LyoKICogKEMpIENvcHlyaWdodCAyMDAyLCAyMDAzCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCLCBkYW5pZWxAb21pY3Jvbi5zZQogKgogKiAoQykgQ29weXJpZ2h0IDIwMDIKICogU3lzZ28gUmVhbC1UaW1lIFNvbHV0aW9ucywgR21iSCA8d3d3LmVsaW5vcy5jb20+CiAqIEFsZXggWnVlcGtlIDxhenVAc3lzZ28uZGU+CiAqCiAqIFNlZSBmaWxlIENSRURJVFMgZm9yIGxpc3Qgb2YgcGVvcGxlIHdobyBjb250cmlidXRlZCB0byB0aGlzCiAqIHByb2plY3QuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YKICogdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sCiAqIE1BIDAyMTExLTEzMDcgVVNBCiAqLwoKI2luY2x1ZGUgPGNvbW1vbi5oPgojaW5jbHVkZSA8YXNtL2lvLmg+CiNpbmNsdWRlIDxwY2kuaD4KI2luY2x1ZGUgPGFzbS9pYy9zYzUyMC5oPgoKI2RlZmluZSBQUk9CRV9CVUZGRVJfU0laRSAxMDI0CnN0YXRpYyB1bnNpZ25lZCBjaGFyIGJ1ZmZlcltQUk9CRV9CVUZGRVJfU0laRV07CgojZGVmaW5lIFNDNTIwX01BWF9GTEFTSF9CQU5LUyAgMwojZGVmaW5lIFNDNTIwX0ZMQVNIX0JBTkswX0JBU0UgMHgzODAwMDAwMCAgLyogQk9PVENTICovCiNkZWZpbmUgU0M1MjBfRkxBU0hfQkFOSzFfQkFTRSAweDMwMDAwMDAwICAvKiBST01DUzAgKi8KI2RlZmluZSBTQzUyMF9GTEFTSF9CQU5LMl9CQVNFIDB4MjgwMDAwMDAgIC8qIFJPTUNTMSAqLwojZGVmaW5lIFNDNTIwX0ZMQVNIX0JBTktTSVpFICAgMHg4MDAwMDAwCgojZGVmaW5lIEFNRDI5TFYwMTZCX1NJWkUgICAgICAgIDB4MjAwMDAwCiNkZWZpbmUgQU1EMjlMVjAxNkJfU0VDVE9SUyAgICAgMzIKCmZsYXNoX2luZm9fdCAgICBmbGFzaF9pbmZvW1NDNTIwX01BWF9GTEFTSF9CQU5LU107CgojZGVmaW5lIFJFQURZIDEKI2RlZmluZSBFUlIgICAyCiNkZWZpbmUgVE1PICAgNAoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8KCgpzdGF0aWMgdTMyIF9wcm9iZV9mbGFzaCh1MzIgYWRkciwgdTMyIGJ3LCBpbnQgaWwpCnsKCXUzMiByZXN1bHQ9MDsKCgkvKiBGaXJzdCBkbyBhbiB1bmxvY2sgY3ljbGUgZm9yIHRoZSBiZW5lZml0IG9mCgkgKiBkZXZpY2VzIHRoYXQgbmVlZCBpdCAqLwoKCXN3aXRjaCAoYncpIHsKCgljYXNlIDE6CgkJKih2b2xhdGlsZSB1OCopKGFkZHIrMHg1NTU1KSA9IDB4YWE7CgkJKih2b2xhdGlsZSB1OCopKGFkZHIrMHgyYWFhKSA9IDB4NTU7CgkJKih2b2xhdGlsZSB1OCopKGFkZHIrMHg1NTU1KSA9IDB4OTA7CgoJCS8qIFJlYWQgdmVuZG9yICovCgkJcmVzdWx0ID0gKih2b2xhdGlsZSB1OCopYWRkcjsKCQlyZXN1bHQgPDw9IDE2OwoKCQkvKiBSZWFkIGRldmljZSAqLwoJCXJlc3VsdCB8PSAqKHZvbGF0aWxlIHU4KikoYWRkcisyKTsKCgkJLyogUmV0dXJuIGRldmljZSB0byBkYXRhIG1vZGUgKi8KCQkqKHZvbGF0aWxlIHU4KilhZGRyID0gMHhmZjsKCQkqKHZvbGF0aWxlIHU4KikoYWRkcisweDU1NTUpLCAweGYwOwoJCWJyZWFrOwoKCWNhc2UgMjoKCQkqKHZvbGF0aWxlIHUxNiopKGFkZHIrMHhhYWFhKSA9IDB4YWFhYTsKCQkqKHZvbGF0aWxlIHUxNiopKGFkZHIrMHg1NTU0KSA9IDB4NTU1NTsKCgkJLyogSXNzdWUgaWRlbnRpZmljYXRpb24gY29tbWFuZCAqLwoJCWlmIChpbCA9PSAyKSB7CgkJCSoodm9sYXRpbGUgdTE2KikoYWRkcisweGFhYWEpID0gMHg5MDkwOwoKCQkJLyogUmVhZCB2ZW5kb3IgKi8KCQkJcmVzdWx0ID0gKih2b2xhdGlsZSB1OCopYWRkcjsKCQkJcmVzdWx0IDw8PSAxNjsKCgkJCS8qIFJlYWQgZGV2aWNlICovCgkJCXJlc3VsdCB8PSAqKHZvbGF0aWxlIHU4KikoYWRkcisyKTsKCgkJCS8qIFJldHVybiBkZXZpY2UgdG8gZGF0YSBtb2RlICovCgkJCSoodm9sYXRpbGUgdTE2KilhZGRyID0gIDB4ZmZmZjsKCQkJKih2b2xhdGlsZSB1MTYqKShhZGRyKzB4YWFhYSksIDB4ZjBmMDsKCgkJfSBlbHNlIHsKCQkJKih2b2xhdGlsZSB1OCopKGFkZHIrMHhhYWFhKSA9IDB4OTA7CgkJCS8qIFJlYWQgdmVuZG9yICovCgkJCXJlc3VsdCA9ICoodm9sYXRpbGUgdTE2KilhZGRyOwoJCQlyZXN1bHQgPDw9IDE2OwoKCQkJLyogUmVhZCBkZXZpY2UgKi8KCQkJcmVzdWx0IHw9ICoodm9sYXRpbGUgdTE2KikoYWRkcisyKTsKCgkJCS8qIFJldHVybiBkZXZpY2UgdG8gZGF0YSBtb2RlICovCgkJCSoodm9sYXRpbGUgdTgqKWFkZHIgPSAweGZmOwoJCQkqKHZvbGF0aWxlIHU4KikoYWRkcisweGFhYWEpLCAweGYwOwoJCX0KCgkJYnJlYWs7CgoJIGNhc2UgNDoKCQkqKHZvbGF0aWxlIHUzMiopKGFkZHIrMHg1NTU0KSA9IDB4YWFhYWFhYWE7CgkJKih2b2xhdGlsZSB1MzIqKShhZGRyKzB4YWFhOCkgPSAweDU1NTU1NTU1OwoKCQlzd2l0Y2ggKGlsKSB7CgkJY2FzZSAxOgoJCQkvKiBJc3N1ZSBpZGVudGlmaWNhdGlvbiBjb21tYW5kICovCgkJCSoodm9sYXRpbGUgdTgqKShhZGRyKzB4NTU1NCkgPSAweDkwOwoKCQkJLyogUmVhZCB2ZW5kb3IgKi8KCQkJcmVzdWx0ID0gKih2b2xhdGlsZSB1MTYqKWFkZHI7CgkJCXJlc3VsdCA8PD0gMTY7CgoJCQkvKiBSZWFkIGRldmljZSAqLwoJCQlyZXN1bHQgfD0gKih2b2xhdGlsZSB1MTYqKShhZGRyKzQpOwoKCQkJLyogUmV0dXJuIGRldmljZSB0byBkYXRhIG1vZGUgKi8KCQkJKih2b2xhdGlsZSB1OCopYWRkciA9ICAweGZmOwoJCQkqKHZvbGF0aWxlIHU4KikoYWRkcisweDU1NTQpLCAweGYwOwoJCQlicmVhazsKCgkJY2FzZSAyOgoJCQkvKiBJc3N1ZSBpZGVudGlmaWNhdGlvbiBjb21tYW5kICovCgkJCSoodm9sYXRpbGUgdTMyKikoYWRkciArIDB4NTU1NCkgPSAweDAwOTAwMDkwOwoKCQkJLyogUmVhZCB2ZW5kb3IgKi8KCQkJcmVzdWx0ID0gKih2b2xhdGlsZSB1MTYqKWFkZHI7CgkJCXJlc3VsdCA8PD0gMTY7CgoJCQkvKiBSZWFkIGRldmljZSAqLwoJCQlyZXN1bHQgfD0gKih2b2xhdGlsZSB1MTYqKShhZGRyKzQpOwoKCQkJLyogUmV0dXJuIGRldmljZSB0byBkYXRhIG1vZGUgKi8KCQkJKih2b2xhdGlsZSB1MzIqKWFkZHIgPSAgMHgwMGZmMDBmZjsKCQkJKih2b2xhdGlsZSB1MzIqKShhZGRyKzB4NTU1NCksIDB4MDBmMDAwZjA7CgkJCWJyZWFrOwoKCQljYXNlIDQ6CgkJCS8qIElzc3VlIGlkZW50aWZpY2F0aW9uIGNvbW1hbmQgKi8KCQkJKih2b2xhdGlsZSB1MzIqKShhZGRyKzB4NTU1NCkgPSAweDkwOTA5MDkwOwoKCQkJLyogUmVhZCB2ZW5kb3IgKi8KCQkJcmVzdWx0ID0gKih2b2xhdGlsZSB1OCopYWRkcjsKCQkJcmVzdWx0IDw8PSAxNjsKCgkJCS8qIFJlYWQgZGV2aWNlICovCgkJCXJlc3VsdCB8PSAqKHZvbGF0aWxlIHU4KikoYWRkcis0KTsKCgkJCS8qIFJldHVybiBkZXZpY2UgdG8gZGF0YSBtb2RlICovCgkJCSoodm9sYXRpbGUgdTMyKilhZGRyID0gIDB4ZmZmZmZmZmY7CgkJCSoodm9sYXRpbGUgdTMyKikoYWRkcisweDU1NTQpLCAweGYwZjBmMGYwOwoJCQlicmVhazsKCQl9CgkJYnJlYWs7Cgl9CgoKCXJldHVybiByZXN1bHQ7Cn0KCmV4dGVybiBpbnQgX3Byb2JlX2ZsYXNoX2VuZDsKYXNtICgiX3Byb2JlX2ZsYXNoX2VuZDpcbiIKICAgICAiLmxvbmcgMFxuIik7CgpzdGF0aWMgaW50IGlkZW50aWZ5X2ZsYXNoKHVuc2lnbmVkIGFkZHJlc3MsIGludCB3aWR0aCkKewoJaW50IGlzOwoJaW50IGRldmljZTsKCWludCB2ZW5kb3I7CglpbnQgc2l6ZTsKCXVuc2lnbmVkIHJlczsKCgl1MzIgKCpfcHJvYmVfZmxhc2hfcHRyKSh1MzIgYSwgdTMyIGJ3LCBpbnQgaWwpOwoKCXNpemUgPSAodW5zaWduZWQpJl9wcm9iZV9mbGFzaF9lbmQgLSAodW5zaWduZWQpX3Byb2JlX2ZsYXNoOwoKCWlmIChzaXplID4gUFJPQkVfQlVGRkVSX1NJWkUpIHsKCQlwcmludGYoIl9wcm9iZV9mbGFzaCgpIHJvdXRpbmUgdG9vIGxhcmdlICglZCkgJXAgLSAlcFxuIiwKCQkgICAgICAgc2l6ZSwgJl9wcm9iZV9mbGFzaF9lbmQsIF9wcm9iZV9mbGFzaCk7CgkJcmV0dXJuIDA7Cgl9CgoJbWVtY3B5KGJ1ZmZlciwgX3Byb2JlX2ZsYXNoLCBzaXplKTsKCV9wcm9iZV9mbGFzaF9wdHIgPSAodm9pZCopYnVmZmVyOwoKCWlzID0gZGlzYWJsZV9pbnRlcnJ1cHRzKCk7CglyZXMgPSBfcHJvYmVfZmxhc2hfcHRyKGFkZHJlc3MsIHdpZHRoLCAxKTsKCWlmIChpcykgewoJCWVuYWJsZV9pbnRlcnJ1cHRzKCk7Cgl9CgoKCXZlbmRvciA9IHJlcyA+PiAxNjsKCWRldmljZSA9IHJlcyAmIDB4ZmZmZjsKCgoJcmV0dXJuIHJlczsKfQoKdWxvbmcgZmxhc2hfaW5pdCh2b2lkKQp7CglpbnQgaSwgajsKCXVsb25nIHNpemUgPSAwOwoKCWZvciAoaSA9IDA7IGkgPCBTQzUyMF9NQVhfRkxBU0hfQkFOS1M7IGkrKykgewoJCXVuc2lnbmVkIGlkOwoJCXVsb25nIGZsYXNoYmFzZSA9IDA7CgkJaW50IHNlY3RzaXplID0gMDsKCgkJbWVtc2V0KGZsYXNoX2luZm9baV0ucHJvdGVjdCwgMCwgQ09ORklHX1NZU19NQVhfRkxBU0hfU0VDVCk7CgkJc3dpdGNoIChpKSB7CgkJY2FzZSAwOgoJCQlmbGFzaGJhc2UgPSBTQzUyMF9GTEFTSF9CQU5LMF9CQVNFOwoJCQlicmVhazsKCQljYXNlIDE6CgkJCWZsYXNoYmFzZSA9IFNDNTIwX0ZMQVNIX0JBTksxX0JBU0U7CgkJCWJyZWFrOwoJCWNhc2UgMjoKCQkJZmxhc2hiYXNlID0gU0M1MjBfRkxBU0hfQkFOSzJfQkFTRTsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJcGFuaWMoImNvbmZpZ3VyZWQgdG9vIG1hbnkgZmxhc2ggYmFua3MhXG4iKTsKCQl9CgoJCWlkID0gaWRlbnRpZnlfZmxhc2goZmxhc2hiYXNlLCA0KTsKCQlzd2l0Y2ggKGlkICYgMHgwMGZmMDBmZikgewoJCWNhc2UgMHgwMDAxMDBjODoKCQkJLyogMjlMVjAxNkIvMjlMVjAxN0IgKi8KCQkJZmxhc2hfaW5mb1tpXS5mbGFzaF9pZCA9CgkJCQkoQU1EX01BTlVGQUNUICYgRkxBU0hfVkVORE1BU0spIHwKCQkJCShBTURfSURfTFYwMTZCICYgRkxBU0hfVFlQRU1BU0spOwoKCQkJZmxhc2hfaW5mb1tpXS5zaXplID0gQU1EMjlMVjAxNkJfU0laRSo0OwoJCQlmbGFzaF9pbmZvW2ldLnNlY3Rvcl9jb3VudCA9IEFNRDI5TFYwMTZCX1NFQ1RPUlM7CgkJCXNlY3RzaXplID0gKEFNRDI5TFYwMTZCX1NJWkUqNCkvQU1EMjlMVjAxNkJfU0VDVE9SUzsKCQkJcHJpbnRmKCJCYW5rICVkOiA0IHggQU1EIDI5TFYwMTdCXG4iLCBpKTsKCQkJYnJlYWs7CgoKCQlkZWZhdWx0OgoJCQlwcmludGYoIkJhbmsgJWQgaGF2ZSB1bmtub3duIGZsYXNoICUwOHhcbiIsIGksIGlkKTsKCQkJZmxhc2hfaW5mb1tpXS5mbGFzaF9pZCA9IEZMQVNIX1VOS05PV047CgkJCWNvbnRpbnVlOwoJCX0KCgkJZm9yIChqID0gMDsgaiA8IGZsYXNoX2luZm9baV0uc2VjdG9yX2NvdW50OyBqKyspIHsKCQkJZmxhc2hfaW5mb1tpXS5zdGFydFtqXSA9IGZsYXNoYmFzZSArIGogKiBzZWN0c2l6ZTsKCQl9CgkJc2l6ZSArPSBmbGFzaF9pbmZvW2ldLnNpemU7CgoJCWZsYXNoX3Byb3RlY3QoRkxBR19QUk9URUNUX0NMRUFSLAoJCQkgICAgICBmbGFzaF9pbmZvW2ldLnN0YXJ0WzBdLAoJCQkgICAgICAgZmxhc2hfaW5mb1tpXS5zdGFydFswXSArIGZsYXNoX2luZm9baV0uc2l6ZSAtIDEsCgkJCSAgICAgICZmbGFzaF9pbmZvW2ldKTsKCX0KCgkvKgoJICogUHJvdGVjdCBtb25pdG9yIGFuZCBlbnZpcm9ubWVudCBzZWN0b3JzCgkgKi8KCWZsYXNoX3Byb3RlY3QoRkxBR19QUk9URUNUX1NFVCwKCQkgICAgICBpMzg2Ym9vdF9zdGFydCwKCQkgICAgICBpMzg2Ym9vdF9lbmQsCgkJICAgICAgJmZsYXNoX2luZm9bMF0pOwojaWZkZWYgQ09ORklHX0VOVl9BRERSCglmbGFzaF9wcm90ZWN0KEZMQUdfUFJPVEVDVF9TRVQsCgkJICAgICAgQ09ORklHX0VOVl9BRERSLAoJCSAgICAgIENPTkZJR19FTlZfQUREUiArIENPTkZJR19FTlZfU0laRSAtIDEsCgkJICAgICAgJmZsYXNoX2luZm9bMF0pOwojZW5kaWYKCXJldHVybiBzaXplOwp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqLwp2b2lkIGZsYXNoX3ByaW50X2luZm8oZmxhc2hfaW5mb190ICppbmZvKQp7CglpbnQgaTsKCglzd2l0Y2ggKGluZm8tPmZsYXNoX2lkICYgRkxBU0hfVkVORE1BU0spIHsKCgljYXNlIChBTURfTUFOVUZBQ1QgJiBGTEFTSF9WRU5ETUFTSyk6CgkJcHJpbnRmKCJBTUQ6ICAgIik7CgkJc3dpdGNoIChpbmZvLT5mbGFzaF9pZCAmIEZMQVNIX1RZUEVNQVNLKSB7CgkJY2FzZSAoQU1EX0lEX0xWMDE2QiAmIEZMQVNIX1RZUEVNQVNLKToKCQkJcHJpbnRmKCI0eCBBTUQyOUxWMDE3QiAoNHgxNk1iaXQpXG4iKTsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJcHJpbnRmKCJVbmtub3duIENoaXAgVHlwZVxuIik7CgkJCWdvdG8gZG9uZTsKCQkJYnJlYWs7CgkJfQoKCQlicmVhazsKCWRlZmF1bHQ6CgkJcHJpbnRmKCJVbmtub3duIFZlbmRvciAiKTsKCQlicmVhazsKCX0KCgoJcHJpbnRmKCIgIFNpemU6ICVsZCBNQiBpbiAlZCBTZWN0b3JzXG4iLAoJICAgICAgIGluZm8tPnNpemUgPj4gMjAsIGluZm8tPnNlY3Rvcl9jb3VudCk7CgoJcHJpbnRmKCIgIFNlY3RvciBTdGFydCBBZGRyZXNzZXM6Iik7Cglmb3IgKGkgPSAwOyBpIDwgaW5mby0+c2VjdG9yX2NvdW50OyBpKyspIHsKCQlpZiAoKGkgJSA1KSA9PSAwKSB7CgkJCXByaW50ZiAoIlxuICAgIik7CgkJfQoJCXByaW50ZiAoIiAlMDhsWCVzIiwgaW5mby0+c3RhcnRbaV0sCgkJCWluZm8tPnByb3RlY3RbaV0gPyAiIChSTykiIDogIiAgICAgIik7Cgl9CglwcmludGYgKCJcbiIpOwoKZG9uZToJOwp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqLwoKLyogdGhpcyBuZWVkcyB0byBiZSBpbmxpbmVkLCB0aGUgU1dUTVJNTUlMTEkgcmVnaXN0ZXIgaXMgcmVzZXQgYnkgZWFjaCByZWFkICovCiNkZWZpbmUgX191ZGVsYXkoZGVsYXkpIFwKewlcCgl1bnNpZ25lZCBtaWNybzsgXAoJdW5zaWduZWQgbWlsbGk9MDsgXAoJXAoJbWljcm8gPSAqKHZvbGF0aWxlIHUxNiopKDB4ZmZmZWYwMDArU0M1MjBfU1dUTVJNSUxMSSk7IFwKCSBcCglmb3IgKDs7KSB7IFwKCQlcCgkJbWlsbGkgKz0gKih2b2xhdGlsZSB1MTYqKSgweGZmZmVmMDAwK1NDNTIwX1NXVE1STUlMTEkpOyBcCgkJbWljcm8gPSAqKHZvbGF0aWxlIHUxNiopKDB4ZmZmZWYwMDArU0M1MjBfU1dUTVJNSUNSTyk7IFwKCQlcCgkJaWYgKChkZWxheSkgPD0gKG1pY3JvICsgKG1pbGxpICogMTAwMCkpKSB7IFwKCQkJYnJlYWs7IFwKCQl9IFwKCX0gXAp9IHdoaWxlICgwKQoKc3RhdGljIHUzMiBfYW1kX2VyYXNlX2ZsYXNoKHUzMiBhZGRyLCB1MzIgc2VjdG9yKQp7Cgl1bnNpZ25lZCBlbGFwc2VkOwoKCS8qIElzc3VlIGVyYXNlICovCgkqKHZvbGF0aWxlIHUzMiopKGFkZHIgKyAweDU1NTQpID0gMHhBQUFBQUFBQTsKCSoodm9sYXRpbGUgdTMyKikoYWRkciArIDB4YWFhOCkgPSAweDU1NTU1NTU1OwoJKih2b2xhdGlsZSB1MzIqKShhZGRyICsgMHg1NTU0KSA9IDB4ODA4MDgwODA7CgkvKiBBbmQgb25lIHVubG9jayAqLwoJKih2b2xhdGlsZSB1MzIqKShhZGRyICsgMHg1NTU0KSA9IDB4QUFBQUFBQUE7CgkqKHZvbGF0aWxlIHUzMiopKGFkZHIgKyAweGFhYTgpID0gMHg1NTU1NTU1NTsKCS8qIFNlY3RvciBlcmFzZSBjb21tYW5kIGNvbWVzIGxhc3QgKi8KCSoodm9sYXRpbGUgdTMyKikoYWRkciArIHNlY3RvcikgPSAweDMwMzAzMDMwOwoKCWVsYXBzZWQgPSAqKHZvbGF0aWxlIHUxNiopKDB4ZmZmZWYwMDArU0M1MjBfU1dUTVJNSUxMSSk7IC8qIGR1bW15IHJlYWQgKi8KCWVsYXBzZWQgPSAwOwoJX191ZGVsYXkoNTApOwoJd2hpbGUgKCgoKih2b2xhdGlsZSB1MzIqKShhZGRyICsgc2VjdG9yKSkgJiAweDgwODA4MDgwKSAhPSAweDgwODA4MDgwKSB7CgoJCWVsYXBzZWQgKz0gKih2b2xhdGlsZSB1MTYqKSgweGZmZmVmMDAwK1NDNTIwX1NXVE1STUlMTEkpOwoJCWlmIChlbGFwc2VkID4gKChDT05GSUdfU1lTX0ZMQVNIX0VSQVNFX1RPVVQvQ09ORklHX1NZU19IWikgKiAxMDAwKSkgewoJCQkqKHZvbGF0aWxlIHUzMiopKGFkZHIpID0gMHhmMGYwZjBmMDsKCQkJcmV0dXJuIDE7CgkJfQoJfQoKCSoodm9sYXRpbGUgdTMyKikoYWRkcikgPSAweGYwZjBmMGYwOwoKCXJldHVybiAwOwp9CgpleHRlcm4gaW50IF9hbWRfZXJhc2VfZmxhc2hfZW5kOwphc20gKCJfYW1kX2VyYXNlX2ZsYXNoX2VuZDpcbiIKICAgICAiLmxvbmcgMFxuIik7CgppbnQgZmxhc2hfZXJhc2UoZmxhc2hfaW5mb190ICppbmZvLCBpbnQgc19maXJzdCwgaW50IHNfbGFzdCkKewoJdTMyICgqX2VyYXNlX2ZsYXNoX3B0cikodTMyIGEsIHUzMiBzbyk7CglpbnQgcHJvdDsKCWludCBzZWN0OwoJdW5zaWduZWQgc2l6ZTsKCglpZiAoKHNfZmlyc3QgPCAwKSB8fCAoc19maXJzdCA+IHNfbGFzdCkpIHsKCQlpZiAoaW5mby0+Zmxhc2hfaWQgPT0gRkxBU0hfVU5LTk9XTikgewoJCQlwcmludGYoIi0gbWlzc2luZ1xuIik7CgkJfSBlbHNlIHsKCQkJcHJpbnRmKCItIG5vIHNlY3RvcnMgdG8gZXJhc2VcbiIpOwoJCX0KCQlyZXR1cm4gMTsKCX0KCglpZiAoKGluZm8tPmZsYXNoX2lkICYgRkxBU0hfVkVORE1BU0spID09IChBTURfTUFOVUZBQ1QgJiBGTEFTSF9WRU5ETUFTSykpIHsKCQlzaXplID0gKHVuc2lnbmVkKSZfYW1kX2VyYXNlX2ZsYXNoX2VuZCAtICh1bnNpZ25lZClfYW1kX2VyYXNlX2ZsYXNoOwoKCQlpZiAoc2l6ZSA+IFBST0JFX0JVRkZFUl9TSVpFKSB7CgkJCXByaW50ZigiX2FtZF9lcmFzZV9mbGFzaCgpIHJvdXRpbmUgdG9vIGxhcmdlICglZCkgJXAgLSAlcFxuIiwKCQkJICAgICAgIHNpemUsICZfYW1kX2VyYXNlX2ZsYXNoX2VuZCwgX2FtZF9lcmFzZV9mbGFzaCk7CgkJCXJldHVybiAwOwoJCX0KCgkJbWVtY3B5KGJ1ZmZlciwgX2FtZF9lcmFzZV9mbGFzaCwgc2l6ZSk7CgkJX2VyYXNlX2ZsYXNoX3B0ciA9ICh2b2lkKilidWZmZXI7CgoJfSAgZWxzZSB7CgkJcHJpbnRmICgiQ2FuJ3QgZXJhc2UgdW5rbm93biBmbGFzaCB0eXBlIC0gYWJvcnRlZFxuIik7CgkJcmV0dXJuIDE7Cgl9CgoJcHJvdCA9IDA7Cglmb3IgKHNlY3Q9c19maXJzdDsgc2VjdDw9c19sYXN0OyArK3NlY3QpIHsKCQlpZiAoaW5mby0+cHJvdGVjdFtzZWN0XSkgewoJCQlwcm90Kys7CgkJfQoJfQoKCWlmIChwcm90KSB7CgkJcHJpbnRmICgiLSBXYXJuaW5nOiAlZCBwcm90ZWN0ZWQgc2VjdG9ycyB3aWxsIG5vdCBiZSBlcmFzZWQhXG4iLCBwcm90KTsKCX0gZWxzZSB7CgkJcHJpbnRmICgiXG4iKTsKCX0KCgoJLyogU3RhcnQgZXJhc2Ugb24gdW5wcm90ZWN0ZWQgc2VjdG9ycyAqLwoJZm9yIChzZWN0ID0gc19maXJzdDsgc2VjdDw9c19sYXN0OyBzZWN0KyspIHsKCgkJaWYgKGluZm8tPnByb3RlY3Rbc2VjdF0gPT0gMCkgeyAvKiBub3QgcHJvdGVjdGVkICovCgkJCWludCByZXM7CgkJCWludCBmbGFnOwoKCQkJLyogRGlzYWJsZSBpbnRlcnJ1cHRzIHdoaWNoIG1pZ2h0IGNhdXNlIGEgdGltZW91dCBoZXJlICovCgkJCWZsYWcgPSBkaXNhYmxlX2ludGVycnVwdHMoKTsKCgkJCXJlcyA9IF9lcmFzZV9mbGFzaF9wdHIoaW5mby0+c3RhcnRbMF0sIGluZm8tPnN0YXJ0W3NlY3RdLWluZm8tPnN0YXJ0WzBdKTsKCgkJCS8qIHJlLWVuYWJsZSBpbnRlcnJ1cHRzIGlmIG5lY2Vzc2FyeSAqLwoJCQlpZiAoZmxhZykgewoJCQkJZW5hYmxlX2ludGVycnVwdHMoKTsKCQkJfQoKCgkJCWlmIChyZXMpIHsKCQkJCXByaW50ZigiRXJhc2UgdGltZWQgb3V0LCBzZWN0b3IgJWRcbiIsIHNlY3QpOwoJCQkJcmV0dXJuIHJlczsKCQkJfQoKCQkJcHV0YygnLicpOwoJCX0KCX0KCgoJcmV0dXJuIDA7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogV3JpdGUgYSB3b3JkIHRvIEZsYXNoLCByZXR1cm5zOgogKiAwIC0gT0sKICogMSAtIHdyaXRlIHRpbWVvdXQKICogMiAtIEZsYXNoIG5vdCBlcmFzZWQKICovCnN0YXRpYyBpbnQgX2FtZF93cml0ZV93b3JkKHVuc2lnbmVkIHN0YXJ0LCB1bnNpZ25lZCBkZXN0LCB1bnNpZ25lZCBkYXRhKQp7Cgl2b2xhdGlsZSB1MzIgKmFkZHIyID0gKHUzMiopc3RhcnQ7Cgl2b2xhdGlsZSB1MzIgKmRlc3QyID0gKHUzMiopZGVzdDsKCXZvbGF0aWxlIHUzMiAqZGF0YTIgPSAodTMyKikmZGF0YTsKCXVuc2lnbmVkIGVsYXBzZWQ7CgoJLyogQ2hlY2sgaWYgRmxhc2ggaXMgKHN1ZmZpY2llbnRseSkgZXJhc2VkICovCglpZiAoKCooKHZvbGF0aWxlIHUzMiopZGVzdCkgJiAodTMyKWRhdGEpICE9ICh1MzIpZGF0YSkgewoJCXJldHVybiAyOwoJfQoKCWFkZHIyWzB4NTU1NF0gPSAweEFBQUFBQUFBOwoJYWRkcjJbMHhhYWE4XSA9IDB4NTU1NTU1NTU7CglhZGRyMlsweDU1NTRdID0gMHhBMEEwQTBBMDsKCglkZXN0MlswXSA9IGRhdGE7CgoJZWxhcHNlZCA9ICoodm9sYXRpbGUgdTE2KikoMHhmZmZlZjAwMCtTQzUyMF9TV1RNUk1JTExJKTsgLyogZHVtbXkgcmVhZCAqLwoJZWxhcHNlZCA9IDA7CgoJLyogZGF0YSBwb2xsaW5nIGZvciBENyAqLwoJd2hpbGUgKChkZXN0MlswXSAmIDB4ODA4MDgwODApICE9IChkYXRhMlswXSAmIDB4ODA4MDgwODApKSB7CgkJZWxhcHNlZCArPSAqKHZvbGF0aWxlIHUxNiopKDB4ZmZmZWYwMDArU0M1MjBfU1dUTVJNSUxMSSk7CgkJaWYgKGVsYXBzZWQgPiAoKENPTkZJR19TWVNfRkxBU0hfV1JJVEVfVE9VVC9DT05GSUdfU1lTX0haKSAqIDEwMDApKSB7CgkJCWFkZHIyWzBdID0gMHhmMGYwZjBmMDsKCQkJcmV0dXJuIDE7CgkJfQoJfQoKCglhZGRyMlswXSA9IDB4ZjBmMGYwZjA7CgoJcmV0dXJuIDA7Cn0KCmV4dGVybiBpbnQgX2FtZF93cml0ZV93b3JkX2VuZDsKYXNtICgiX2FtZF93cml0ZV93b3JkX2VuZDpcbiIKICAgICAiLmxvbmcgMFxuIik7CgoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiBDb3B5IG1lbW9yeSB0byBmbGFzaCwgcmV0dXJuczoKICogMCAtIE9LCiAqIDEgLSB3cml0ZSB0aW1lb3V0CiAqIDIgLSBGbGFzaCBub3QgZXJhc2VkCiAqIDMgLSBVbnN1cHBvcnRlZCBmbGFzaCB0eXBlCiAqLwoKaW50IHdyaXRlX2J1ZmYoZmxhc2hfaW5mb190ICppbmZvLCB1Y2hhciAqc3JjLCB1bG9uZyBhZGRyLCB1bG9uZyBjbnQpCnsKCXVsb25nIGNwLCB3cCwgZGF0YTsKCWludCBpLCBsLCByYzsKCWludCBmbGFnOwoJdTMyICgqX3dyaXRlX3dvcmRfcHRyKSh1bnNpZ25lZCBzdGFydCwgdW5zaWduZWQgZGVzdCwgdW5zaWduZWQgZGF0YSk7Cgl1bnNpZ25lZCBzaXplOwoKCWlmICgoaW5mby0+Zmxhc2hfaWQgJiBGTEFTSF9WRU5ETUFTSykgPT0gKEFNRF9NQU5VRkFDVCAmIEZMQVNIX1ZFTkRNQVNLKSkgewoJCXNpemUgPSAodW5zaWduZWQpJl9hbWRfd3JpdGVfd29yZF9lbmQgLSAodW5zaWduZWQpX2FtZF93cml0ZV93b3JkOwoKCQlpZiAoc2l6ZSA+IFBST0JFX0JVRkZFUl9TSVpFKSB7CgkJCXByaW50ZigiX2FtZF93cml0ZV93b3JkKCkgcm91dGluZSB0b28gbGFyZ2UgKCVkKSAlcCAtICVwXG4iLAoJCQkgICAgICAgc2l6ZSwgJl9hbWRfd3JpdGVfd29yZF9lbmQsIF9hbWRfd3JpdGVfd29yZCk7CgkJCXJldHVybiAwOwoJCX0KCgkJbWVtY3B5KGJ1ZmZlciwgX2FtZF93cml0ZV93b3JkLCBzaXplKTsKCQlfd3JpdGVfd29yZF9wdHIgPSAodm9pZCopYnVmZmVyOwoKCX0gZWxzZSB7CgkJcHJpbnRmICgiQ2FuJ3QgcHJvZ3JhbSB1bmtub3duIGZsYXNoIHR5cGUgLSBhYm9ydGVkXG4iKTsKCQlyZXR1cm4gMzsKCX0KCgoJd3AgPSAoYWRkciAmIH4zKTsJLyogZ2V0IGxvd2VyIHdvcmQgYWxpZ25lZCBhZGRyZXNzICovCgoKCS8qCgkgKiBoYW5kbGUgdW5hbGlnbmVkIHN0YXJ0IGJ5dGVzCgkgKi8KCWlmICgobCA9IGFkZHIgLSB3cCkgIT0gMCkgewoJCWRhdGEgPSAwOwoJCWZvciAoaT0wLCBjcD13cDsgaTxsOyArK2ksICsrY3ApIHsKCQkJZGF0YSB8PSAoKih1Y2hhciAqKWNwKSA8PCAoOCppKTsKCQl9CgkJZm9yICg7IGk8NCAmJiBjbnQ+MDsgKytpKSB7CgkJCWRhdGEgfD0gKnNyYysrIDw8ICg4KmkpOwoJCQktLWNudDsKCQkJKytjcDsKCQl9CgkJZm9yICg7IGNudD09MCAmJiBpPDQ7ICsraSwgKytjcCkgewoJCQlkYXRhIHw9ICgqKHVjaGFyICopY3ApICA8PCAoOCppKTsKCQl9CgoJCS8qIERpc2FibGUgaW50ZXJydXB0cyB3aGljaCBtaWdodCBjYXVzZSBhIHRpbWVvdXQgaGVyZSAqLwoJCWZsYWcgPSBkaXNhYmxlX2ludGVycnVwdHMoKTsKCgkJcmMgPSBfd3JpdGVfd29yZF9wdHIoaW5mby0+c3RhcnRbMF0sIHdwLCBkYXRhKTsKCgkJLyogcmUtZW5hYmxlIGludGVycnVwdHMgaWYgbmVjZXNzYXJ5ICovCgkJaWYgKGZsYWcpIHsKCQkJZW5hYmxlX2ludGVycnVwdHMoKTsKCQl9CgkJaWYgKHJjICE9IDApIHsKCQkJcmV0dXJuIHJjOwoJCX0KCQl3cCArPSA0OwoJfQoKCS8qCgkgKiBoYW5kbGUgd29yZCBhbGlnbmVkIHBhcnQKCSAqLwoJd2hpbGUgKGNudCA+PSA0KSB7CgkJZGF0YSA9IDA7CgoJCWZvciAoaT0wOyBpPDQ7ICsraSkgewoJCQlkYXRhIHw9ICpzcmMrKyA8PCAoOCppKTsKCQl9CgoJCS8qIERpc2FibGUgaW50ZXJydXB0cyB3aGljaCBtaWdodCBjYXVzZSBhIHRpbWVvdXQgaGVyZSAqLwoJCWZsYWcgPSBkaXNhYmxlX2ludGVycnVwdHMoKTsKCgkJcmMgPSBfd3JpdGVfd29yZF9wdHIoaW5mby0+c3RhcnRbMF0sIHdwLCBkYXRhKTsKCgkJLyogcmUtZW5hYmxlIGludGVycnVwdHMgaWYgbmVjZXNzYXJ5ICovCgkJaWYgKGZsYWcpIHsKCQkJZW5hYmxlX2ludGVycnVwdHMoKTsKCQl9CgkJaWYgKHJjICE9IDApIHsKCQkJcmV0dXJuIHJjOwoJCX0KCQl3cCAgKz0gNDsKCQljbnQgLT0gNDsKCX0KCglpZiAoY250ID09IDApIHsKCQlyZXR1cm4gMDsKCX0KCgkvKgoJICogaGFuZGxlIHVuYWxpZ25lZCB0YWlsIGJ5dGVzCgkgKi8KCWRhdGEgPSAwOwoJZm9yIChpPTAsIGNwPXdwOyBpPDQgJiYgY250PjA7ICsraSwgKytjcCkgewoJCWRhdGEgfD0gKnNyYysrIDw8ICg4KmkpOwoJCS0tY250OwoJfQoKCWZvciAoOyBpPDQ7ICsraSwgKytjcCkgewoJCWRhdGEgfD0gKCoodWNoYXIgKiljcCkgPDwgKDgqaSk7Cgl9CgoJLyogRGlzYWJsZSBpbnRlcnJ1cHRzIHdoaWNoIG1pZ2h0IGNhdXNlIGEgdGltZW91dCBoZXJlICovCglmbGFnID0gZGlzYWJsZV9pbnRlcnJ1cHRzKCk7CgoJcmMgPSBfd3JpdGVfd29yZF9wdHIoaW5mby0+c3RhcnRbMF0sIHdwLCBkYXRhKTsKCgkvKiByZS1lbmFibGUgaW50ZXJydXB0cyBpZiBuZWNlc3NhcnkgKi8KCWlmIChmbGFnKSB7CgkJZW5hYmxlX2ludGVycnVwdHMoKTsKCX0KCglyZXR1cm4gcmM7Cgp9Cg==