LyoKICogKEMpIENvcHlyaWdodCAyMDAyLCAyMDAzCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCLCBkYW5pZWxAb21pY3Jvbi5zZQogKgogKiAoQykgQ29weXJpZ2h0IDIwMDIKICogU3lzZ28gUmVhbC1UaW1lIFNvbHV0aW9ucywgR21iSCA8d3d3LmVsaW5vcy5jb20+CiAqIEFsZXggWnVlcGtlIDxhenVAc3lzZ28uZGU+CiAqCiAqIFNlZSBmaWxlIENSRURJVFMgZm9yIGxpc3Qgb2YgcGVvcGxlIHdobyBjb250cmlidXRlZCB0byB0aGlzCiAqIHByb2plY3QuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YKICogdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sCiAqIE1BIDAyMTExLTEzMDcgVVNBCiAqLwoKI2luY2x1ZGUgPGNvbW1vbi5oPgojaW5jbHVkZSA8YXNtL2lvLmg+CiNpbmNsdWRlIDxwY2kuaD4KI2luY2x1ZGUgPGFzbS9pYy9zYzUyMC5oPgoKI2RlZmluZSBQUk9CRV9CVUZGRVJfU0laRSAxMDI0CnN0YXRpYyB1bnNpZ25lZCBjaGFyIGJ1ZmZlcltQUk9CRV9CVUZGRVJfU0laRV07CgojZGVmaW5lIFNDNTIwX01BWF9GTEFTSF9CQU5LUyAgMwojZGVmaW5lIFNDNTIwX0ZMQVNIX0JBTkswX0JBU0UgMHgzODAwMDAwMCAgLyogQk9PVENTICovCiNkZWZpbmUgU0M1MjBfRkxBU0hfQkFOSzFfQkFTRSAweDMwMDAwMDAwICAvKiBST01DUzAgKi8KI2RlZmluZSBTQzUyMF9GTEFTSF9CQU5LMl9CQVNFIDB4MjgwMDAwMDAgIC8qIFJPTUNTMSAqLwojZGVmaW5lIFNDNTIwX0ZMQVNIX0JBTktTSVpFICAgMHg4MDAwMDAwCgojZGVmaW5lIEFNRDI5TFYwMTZCX1NJWkUgICAgICAgIDB4MjAwMDAwCiNkZWZpbmUgQU1EMjlMVjAxNkJfU0VDVE9SUyAgICAgMzIKCmZsYXNoX2luZm9fdCAgICBmbGFzaF9pbmZvW1NDNTIwX01BWF9GTEFTSF9CQU5LU107CgojZGVmaW5lIFJFQURZIDEKI2RlZmluZSBFUlIgICAyCiNkZWZpbmUgVE1PICAgNAoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8KCgpzdGF0aWMgdTMyIF9wcm9iZV9mbGFzaCh1MzIgYWRkciwgdTMyIGJ3LCBpbnQgaWwpCnsKCXUzMiByZXN1bHQ9MDsKCgkvKiBGaXJzdCBkbyBhbiB1bmxvY2sgY3ljbGUgZm9yIHRoZSBiZW5lZml0IG9mCgkgKiBkZXZpY2VzIHRoYXQgbmVlZCBpdCAqLwoKCXN3aXRjaCAoYncpIHsKCgljYXNlIDE6CgkJKih2b2xhdGlsZSB1OCopKGFkZHIrMHg1NTU1KSA9IDB4YWE7CgkJKih2b2xhdGlsZSB1OCopKGFkZHIrMHgyYWFhKSA9IDB4NTU7CgkJKih2b2xhdGlsZSB1OCopKGFkZHIrMHg1NTU1KSA9IDB4OTA7CgoJCS8qIFJlYWQgdmVuZG9yICovCgkJcmVzdWx0ID0gKih2b2xhdGlsZSB1OCopYWRkcjsKCQlyZXN1bHQgPDw9IDE2OwoKCQkvKiBSZWFkIGRldmljZSAqLwoJCXJlc3VsdCB8PSAqKHZvbGF0aWxlIHU4KikoYWRkcisyKTsKCgkJLyogUmV0dXJuIGRldmljZSB0byBkYXRhIG1vZGUgKi8KCQkqKHZvbGF0aWxlIHU4KilhZGRyID0gMHhmZjsKCQkqKHZvbGF0aWxlIHU4KikoYWRkcisweDU1NTUpLCAweGYwOwoJCWJyZWFrOwoKCWNhc2UgMjoKCQkqKHZvbGF0aWxlIHUxNiopKGFkZHIrMHhhYWFhKSA9IDB4YWFhYTsKCQkqKHZvbGF0aWxlIHUxNiopKGFkZHIrMHg1NTU0KSA9IDB4NTU1NTsKCgkJLyogSXNzdWUgaWRlbnRpZmljYXRpb24gY29tbWFuZCAqLwoJCWlmIChpbCA9PSAyKSB7CgkJCSoodm9sYXRpbGUgdTE2KikoYWRkcisweGFhYWEpID0gMHg5MDkwOwoKCQkJLyogUmVhZCB2ZW5kb3IgKi8KCQkJcmVzdWx0ID0gKih2b2xhdGlsZSB1OCopYWRkcjsKCQkJcmVzdWx0IDw8PSAxNjsKCgkJCS8qIFJlYWQgZGV2aWNlICovCgkJCXJlc3VsdCB8PSAqKHZvbGF0aWxlIHU4KikoYWRkcisyKTsKCgkJCS8qIFJldHVybiBkZXZpY2UgdG8gZGF0YSBtb2RlICovCgkJCSoodm9sYXRpbGUgdTE2KilhZGRyID0gIDB4ZmZmZjsKCQkJKih2b2xhdGlsZSB1MTYqKShhZGRyKzB4YWFhYSksIDB4ZjBmMDsKCgkJfSBlbHNlIHsKCQkJKih2b2xhdGlsZSB1OCopKGFkZHIrMHhhYWFhKSA9IDB4OTA7CgkJCS8qIFJlYWQgdmVuZG9yICovCgkJCXJlc3VsdCA9ICoodm9sYXRpbGUgdTE2KilhZGRyOwoJCQlyZXN1bHQgPDw9IDE2OwoKCQkJLyogUmVhZCBkZXZpY2UgKi8KCQkJcmVzdWx0IHw9ICoodm9sYXRpbGUgdTE2KikoYWRkcisyKTsKCgkJCS8qIFJldHVybiBkZXZpY2UgdG8gZGF0YSBtb2RlICovCgkJCSoodm9sYXRpbGUgdTgqKWFkZHIgPSAweGZmOwoJCQkqKHZvbGF0aWxlIHU4KikoYWRkcisweGFhYWEpLCAweGYwOwoJCX0KCgkJYnJlYWs7CgoJIGNhc2UgNDoKCQkqKHZvbGF0aWxlIHUzMiopKGFkZHIrMHg1NTU0KSA9IDB4YWFhYWFhYWE7CgkJKih2b2xhdGlsZSB1MzIqKShhZGRyKzB4YWFhOCkgPSAweDU1NTU1NTU1OwoKCQlzd2l0Y2ggKGlsKSB7CgkJY2FzZSAxOgoJCQkvKiBJc3N1ZSBpZGVudGlmaWNhdGlvbiBjb21tYW5kICovCgkJCSoodm9sYXRpbGUgdTgqKShhZGRyKzB4NTU1NCkgPSAweDkwOwoKCQkJLyogUmVhZCB2ZW5kb3IgKi8KCQkJcmVzdWx0ID0gKih2b2xhdGlsZSB1MTYqKWFkZHI7CgkJCXJlc3VsdCA8PD0gMTY7CgoJCQkvKiBSZWFkIGRldmljZSAqLwoJCQlyZXN1bHQgfD0gKih2b2xhdGlsZSB1MTYqKShhZGRyKzQpOwoKCQkJLyogUmV0dXJuIGRldmljZSB0byBkYXRhIG1vZGUgKi8KCQkJKih2b2xhdGlsZSB1OCopYWRkciA9ICAweGZmOwoJCQkqKHZvbGF0aWxlIHU4KikoYWRkcisweDU1NTQpLCAweGYwOwoJCQlicmVhazsKCgkJY2FzZSAyOgoJCQkvKiBJc3N1ZSBpZGVudGlmaWNhdGlvbiBjb21tYW5kICovCgkJCSoodm9sYXRpbGUgdTMyKikoYWRkciArIDB4NTU1NCkgPSAweDAwOTAwMDkwOwoKCQkJLyogUmVhZCB2ZW5kb3IgKi8KCQkJcmVzdWx0ID0gKih2b2xhdGlsZSB1MTYqKWFkZHI7CgkJCXJlc3VsdCA8PD0gMTY7CgoJCQkvKiBSZWFkIGRldmljZSAqLwoJCQlyZXN1bHQgfD0gKih2b2xhdGlsZSB1MTYqKShhZGRyKzQpOwoKCQkJLyogUmV0dXJuIGRldmljZSB0byBkYXRhIG1vZGUgKi8KCQkJKih2b2xhdGlsZSB1MzIqKWFkZHIgPSAgMHgwMGZmMDBmZjsKCQkJKih2b2xhdGlsZSB1MzIqKShhZGRyKzB4NTU1NCksIDB4MDBmMDAwZjA7CgkJCWJyZWFrOwoKCQljYXNlIDQ6CgkJCS8qIElzc3VlIGlkZW50aWZpY2F0aW9uIGNvbW1hbmQgKi8KCQkJKih2b2xhdGlsZSB1MzIqKShhZGRyKzB4NTU1NCkgPSAweDkwOTA5MDkwOwoKCQkJLyogUmVhZCB2ZW5kb3IgKi8KCQkJcmVzdWx0ID0gKih2b2xhdGlsZSB1OCopYWRkcjsKCQkJcmVzdWx0IDw8PSAxNjsKCgkJCS8qIFJlYWQgZGV2aWNlICovCgkJCXJlc3VsdCB8PSAqKHZvbGF0aWxlIHU4KikoYWRkcis0KTsKCgkJCS8qIFJldHVybiBkZXZpY2UgdG8gZGF0YSBtb2RlICovCgkJCSoodm9sYXRpbGUgdTMyKilhZGRyID0gIDB4ZmZmZmZmZmY7CgkJCSoodm9sYXRpbGUgdTMyKikoYWRkcisweDU1NTQpLCAweGYwZjBmMGYwOwoJCQlicmVhazsKCQl9CgkJYnJlYWs7Cgl9CgoKCXJldHVybiByZXN1bHQ7Cn0KCmV4dGVybiBpbnQgX3Byb2JlX2ZsYXNoX2VuZDsKYXNtICgiX3Byb2JlX2ZsYXNoX2VuZDpcbiIKICAgICAiLmxvbmcgMFxuIik7CgpzdGF0aWMgaW50IGlkZW50aWZ5X2ZsYXNoKHVuc2lnbmVkIGFkZHJlc3MsIGludCB3aWR0aCkKewoJaW50IGlzOwoJaW50IGRldmljZTsKCWludCB2ZW5kb3I7CglpbnQgc2l6ZTsKCXVuc2lnbmVkIHJlczsKCgl1MzIgKCpfcHJvYmVfZmxhc2hfcHRyKSh1MzIgYSwgdTMyIGJ3LCBpbnQgaWwpOwoKCXNpemUgPSAodW5zaWduZWQpJl9wcm9iZV9mbGFzaF9lbmQgLSAodW5zaWduZWQpX3Byb2JlX2ZsYXNoOwoKCWlmIChzaXplID4gUFJPQkVfQlVGRkVSX1NJWkUpIHsKCQlwcmludGYoIl9wcm9iZV9mbGFzaCgpIHJvdXRpbmUgdG9vIGxhcmdlICglZCkgJXAgLSAlcFxuIiwKCQkgICAgICAgc2l6ZSwgJl9wcm9iZV9mbGFzaF9lbmQsIF9wcm9iZV9mbGFzaCk7CgkJcmV0dXJuIDA7Cgl9CgoJbWVtY3B5KGJ1ZmZlciwgX3Byb2JlX2ZsYXNoLCBzaXplKTsKCV9wcm9iZV9mbGFzaF9wdHIgPSAodm9pZCopYnVmZmVyOwoKCWlzID0gZGlzYWJsZV9pbnRlcnJ1cHRzKCk7CglyZXMgPSBfcHJvYmVfZmxhc2hfcHRyKGFkZHJlc3MsIHdpZHRoLCAxKTsKCWlmIChpcykgewoJCWVuYWJsZV9pbnRlcnJ1cHRzKCk7Cgl9CgoKCXZlbmRvciA9IHJlcyA+PiAxNjsKCWRldmljZSA9IHJlcyAmIDB4ZmZmZjsKCgoJcmV0dXJuIHJlczsKfQoKdWxvbmcgZmxhc2hfaW5pdCh2b2lkKQp7CglpbnQgaSwgajsKCXVsb25nIHNpemUgPSAwOwoKCWZvciAoaSA9IDA7IGkgPCBTQzUyMF9NQVhfRkxBU0hfQkFOS1M7IGkrKykgewoJCXVuc2lnbmVkIGlkOwoJCXVsb25nIGZsYXNoYmFzZSA9IDA7CgkJaW50IHNlY3RzaXplID0gMDsKCgkJbWVtc2V0KGZsYXNoX2luZm9baV0ucHJvdGVjdCwgMCwgQ0ZHX01BWF9GTEFTSF9TRUNUKTsKCQlzd2l0Y2ggKGkpIHsKCQljYXNlIDA6CgkJCWZsYXNoYmFzZSA9IFNDNTIwX0ZMQVNIX0JBTkswX0JBU0U7CgkJCWJyZWFrOwoJCWNhc2UgMToKCQkJZmxhc2hiYXNlID0gU0M1MjBfRkxBU0hfQkFOSzFfQkFTRTsKCQkJYnJlYWs7CgkJY2FzZSAyOgoJCQlmbGFzaGJhc2UgPSBTQzUyMF9GTEFTSF9CQU5LMl9CQVNFOwoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQlwYW5pYygiY29uZmlndXJlZCB0b28gbWFueSBmbGFzaCBiYW5rcyFcbiIpOwoJCX0KCgkJaWQgPSBpZGVudGlmeV9mbGFzaChmbGFzaGJhc2UsIDQpOwoJCXN3aXRjaCAoaWQgJiAweDAwZmYwMGZmKSB7CgkJY2FzZSAweDAwMDEwMGM4OgoJCQkvKiAyOUxWMDE2Qi8yOUxWMDE3QiAqLwoJCQlmbGFzaF9pbmZvW2ldLmZsYXNoX2lkID0KCQkJCShBTURfTUFOVUZBQ1QgJiBGTEFTSF9WRU5ETUFTSykgfAoJCQkJKEFNRF9JRF9MVjAxNkIgJiBGTEFTSF9UWVBFTUFTSyk7CgoJCQlmbGFzaF9pbmZvW2ldLnNpemUgPSBBTUQyOUxWMDE2Ql9TSVpFKjQ7CgkJCWZsYXNoX2luZm9baV0uc2VjdG9yX2NvdW50ID0gQU1EMjlMVjAxNkJfU0VDVE9SUzsKCQkJc2VjdHNpemUgPSAoQU1EMjlMVjAxNkJfU0laRSo0KS9BTUQyOUxWMDE2Ql9TRUNUT1JTOwoJCQlwcmludGYoIkJhbmsgJWQ6IDQgeCBBTUQgMjlMVjAxN0JcbiIsIGkpOwoJCQlicmVhazsKCgoJCWRlZmF1bHQ6CgkJCXByaW50ZigiQmFuayAlZCBoYXZlIHVua25vd24gZmxhc2ggJTA4eFxuIiwgaSwgaWQpOwoJCQlmbGFzaF9pbmZvW2ldLmZsYXNoX2lkID0gRkxBU0hfVU5LTk9XTjsKCQkJY29udGludWU7CgkJfQoKCQlmb3IgKGogPSAwOyBqIDwgZmxhc2hfaW5mb1tpXS5zZWN0b3JfY291bnQ7IGorKykgewoJCQlmbGFzaF9pbmZvW2ldLnN0YXJ0W2pdID0gZmxhc2hiYXNlICsgaiAqIHNlY3RzaXplOwoJCX0KCQlzaXplICs9IGZsYXNoX2luZm9baV0uc2l6ZTsKCgkJZmxhc2hfcHJvdGVjdChGTEFHX1BST1RFQ1RfQ0xFQVIsCgkJCSAgICAgIGZsYXNoX2luZm9baV0uc3RhcnRbMF0sCgkJCSAgICAgICBmbGFzaF9pbmZvW2ldLnN0YXJ0WzBdICsgZmxhc2hfaW5mb1tpXS5zaXplIC0gMSwKCQkJICAgICAgJmZsYXNoX2luZm9baV0pOwoJfQoKCS8qCgkgKiBQcm90ZWN0IG1vbml0b3IgYW5kIGVudmlyb25tZW50IHNlY3RvcnMKCSAqLwoJZmxhc2hfcHJvdGVjdChGTEFHX1BST1RFQ1RfU0VULAoJCSAgICAgIGkzODZib290X3N0YXJ0LAoJCSAgICAgIGkzODZib290X2VuZCwKCQkgICAgICAmZmxhc2hfaW5mb1swXSk7CiNpZmRlZiBDRkdfRU5WX0FERFIKCWZsYXNoX3Byb3RlY3QoRkxBR19QUk9URUNUX1NFVCwKCQkgICAgICBDRkdfRU5WX0FERFIsCgkJICAgICAgQ0ZHX0VOVl9BRERSICsgQ0ZHX0VOVl9TSVpFIC0gMSwKCQkgICAgICAmZmxhc2hfaW5mb1swXSk7CiNlbmRpZgoJcmV0dXJuIHNpemU7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICovCnZvaWQgZmxhc2hfcHJpbnRfaW5mbyhmbGFzaF9pbmZvX3QgKmluZm8pCnsKCWludCBpOwoKCXN3aXRjaCAoaW5mby0+Zmxhc2hfaWQgJiBGTEFTSF9WRU5ETUFTSykgewoKCWNhc2UgKEFNRF9NQU5VRkFDVCAmIEZMQVNIX1ZFTkRNQVNLKToKCQlwcmludGYoIkFNRDogICAiKTsKCQlzd2l0Y2ggKGluZm8tPmZsYXNoX2lkICYgRkxBU0hfVFlQRU1BU0spIHsKCQljYXNlIChBTURfSURfTFYwMTZCICYgRkxBU0hfVFlQRU1BU0spOgoJCQlwcmludGYoIjR4IEFNRDI5TFYwMTdCICg0eDE2TWJpdClcbiIpOwoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQlwcmludGYoIlVua25vd24gQ2hpcCBUeXBlXG4iKTsKCQkJZ290byBkb25lOwoJCQlicmVhazsKCQl9CgoJCWJyZWFrOwoJZGVmYXVsdDoKCQlwcmludGYoIlVua25vd24gVmVuZG9yICIpOwoJCWJyZWFrOwoJfQoKCglwcmludGYoIiAgU2l6ZTogJWxkIE1CIGluICVkIFNlY3RvcnNcbiIsCgkgICAgICAgaW5mby0+c2l6ZSA+PiAyMCwgaW5mby0+c2VjdG9yX2NvdW50KTsKCglwcmludGYoIiAgU2VjdG9yIFN0YXJ0IEFkZHJlc3NlczoiKTsKCWZvciAoaSA9IDA7IGkgPCBpbmZvLT5zZWN0b3JfY291bnQ7IGkrKykgewoJCWlmICgoaSAlIDUpID09IDApIHsKCQkJcHJpbnRmICgiXG4gICAiKTsKCQl9CgkJcHJpbnRmICgiICUwOGxYJXMiLCBpbmZvLT5zdGFydFtpXSwKCQkJaW5mby0+cHJvdGVjdFtpXSA/ICIgKFJPKSIgOiAiICAgICAiKTsKCX0KCXByaW50ZiAoIlxuIik7Cgpkb25lOgk7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICovCgovKiB0aGlzIG5lZWRzIHRvIGJlIGlubGluZWQsIHRoZSBTV1RNUk1NSUxMSSByZWdpc3RlciBpcyByZXNldCBieSBlYWNoIHJlYWQgKi8KI2RlZmluZSBfX3VkZWxheShkZWxheSkgXAp7CVwKCXVuc2lnbmVkIG1pY3JvOyBcCgl1bnNpZ25lZCBtaWxsaT0wOyBcCglcCgltaWNybyA9ICoodm9sYXRpbGUgdTE2KikoMHhmZmZlZjAwMCtTQzUyMF9TV1RNUk1JTExJKTsgXAoJIFwKCWZvciAoOzspIHsgXAoJCVwKCQltaWxsaSArPSAqKHZvbGF0aWxlIHUxNiopKDB4ZmZmZWYwMDArU0M1MjBfU1dUTVJNSUxMSSk7IFwKCQltaWNybyA9ICoodm9sYXRpbGUgdTE2KikoMHhmZmZlZjAwMCtTQzUyMF9TV1RNUk1JQ1JPKTsgXAoJCVwKCQlpZiAoKGRlbGF5KSA8PSAobWljcm8gKyAobWlsbGkgKiAxMDAwKSkpIHsgXAoJCQlicmVhazsgXAoJCX0gXAoJfSBcCn0gd2hpbGUgKDApCgpzdGF0aWMgdTMyIF9hbWRfZXJhc2VfZmxhc2godTMyIGFkZHIsIHUzMiBzZWN0b3IpCnsKCXVuc2lnbmVkIGVsYXBzZWQ7CgoJLyogSXNzdWUgZXJhc2UgKi8KCSoodm9sYXRpbGUgdTMyKikoYWRkciArIDB4NTU1NCkgPSAweEFBQUFBQUFBOwoJKih2b2xhdGlsZSB1MzIqKShhZGRyICsgMHhhYWE4KSA9IDB4NTU1NTU1NTU7CgkqKHZvbGF0aWxlIHUzMiopKGFkZHIgKyAweDU1NTQpID0gMHg4MDgwODA4MDsKCS8qIEFuZCBvbmUgdW5sb2NrICovCgkqKHZvbGF0aWxlIHUzMiopKGFkZHIgKyAweDU1NTQpID0gMHhBQUFBQUFBQTsKCSoodm9sYXRpbGUgdTMyKikoYWRkciArIDB4YWFhOCkgPSAweDU1NTU1NTU1OwoJLyogU2VjdG9yIGVyYXNlIGNvbW1hbmQgY29tZXMgbGFzdCAqLwoJKih2b2xhdGlsZSB1MzIqKShhZGRyICsgc2VjdG9yKSA9IDB4MzAzMDMwMzA7CgoJZWxhcHNlZCA9ICoodm9sYXRpbGUgdTE2KikoMHhmZmZlZjAwMCtTQzUyMF9TV1RNUk1JTExJKTsgLyogZHVtbXkgcmVhZCAqLwoJZWxhcHNlZCA9IDA7CglfX3VkZWxheSg1MCk7Cgl3aGlsZSAoKCgqKHZvbGF0aWxlIHUzMiopKGFkZHIgKyBzZWN0b3IpKSAmIDB4ODA4MDgwODApICE9IDB4ODA4MDgwODApIHsKCgkJZWxhcHNlZCArPSAqKHZvbGF0aWxlIHUxNiopKDB4ZmZmZWYwMDArU0M1MjBfU1dUTVJNSUxMSSk7CgkJaWYgKGVsYXBzZWQgPiAoKENGR19GTEFTSF9FUkFTRV9UT1VUL0NGR19IWikgKiAxMDAwKSkgewoJCQkqKHZvbGF0aWxlIHUzMiopKGFkZHIpID0gMHhmMGYwZjBmMDsKCQkJcmV0dXJuIDE7CgkJfQoJfQoKCSoodm9sYXRpbGUgdTMyKikoYWRkcikgPSAweGYwZjBmMGYwOwoKCXJldHVybiAwOwp9CgpleHRlcm4gaW50IF9hbWRfZXJhc2VfZmxhc2hfZW5kOwphc20gKCJfYW1kX2VyYXNlX2ZsYXNoX2VuZDpcbiIKICAgICAiLmxvbmcgMFxuIik7CgppbnQgZmxhc2hfZXJhc2UoZmxhc2hfaW5mb190ICppbmZvLCBpbnQgc19maXJzdCwgaW50IHNfbGFzdCkKewoJdTMyICgqX2VyYXNlX2ZsYXNoX3B0cikodTMyIGEsIHUzMiBzbyk7CglpbnQgcHJvdDsKCWludCBzZWN0OwoJdW5zaWduZWQgc2l6ZTsKCglpZiAoKHNfZmlyc3QgPCAwKSB8fCAoc19maXJzdCA+IHNfbGFzdCkpIHsKCQlpZiAoaW5mby0+Zmxhc2hfaWQgPT0gRkxBU0hfVU5LTk9XTikgewoJCQlwcmludGYoIi0gbWlzc2luZ1xuIik7CgkJfSBlbHNlIHsKCQkJcHJpbnRmKCItIG5vIHNlY3RvcnMgdG8gZXJhc2VcbiIpOwoJCX0KCQlyZXR1cm4gMTsKCX0KCglpZiAoKGluZm8tPmZsYXNoX2lkICYgRkxBU0hfVkVORE1BU0spID09IChBTURfTUFOVUZBQ1QgJiBGTEFTSF9WRU5ETUFTSykpIHsKCQlzaXplID0gKHVuc2lnbmVkKSZfYW1kX2VyYXNlX2ZsYXNoX2VuZCAtICh1bnNpZ25lZClfYW1kX2VyYXNlX2ZsYXNoOwoKCQlpZiAoc2l6ZSA+IFBST0JFX0JVRkZFUl9TSVpFKSB7CgkJCXByaW50ZigiX2FtZF9lcmFzZV9mbGFzaCgpIHJvdXRpbmUgdG9vIGxhcmdlICglZCkgJXAgLSAlcFxuIiwKCQkJICAgICAgIHNpemUsICZfYW1kX2VyYXNlX2ZsYXNoX2VuZCwgX2FtZF9lcmFzZV9mbGFzaCk7CgkJCXJldHVybiAwOwoJCX0KCgkJbWVtY3B5KGJ1ZmZlciwgX2FtZF9lcmFzZV9mbGFzaCwgc2l6ZSk7CgkJX2VyYXNlX2ZsYXNoX3B0ciA9ICh2b2lkKilidWZmZXI7CgoJfSAgZWxzZSB7CgkJcHJpbnRmICgiQ2FuJ3QgZXJhc2UgdW5rbm93biBmbGFzaCB0eXBlIC0gYWJvcnRlZFxuIik7CgkJcmV0dXJuIDE7Cgl9CgoJcHJvdCA9IDA7Cglmb3IgKHNlY3Q9c19maXJzdDsgc2VjdDw9c19sYXN0OyArK3NlY3QpIHsKCQlpZiAoaW5mby0+cHJvdGVjdFtzZWN0XSkgewoJCQlwcm90Kys7CgkJfQoJfQoKCWlmIChwcm90KSB7CgkJcHJpbnRmICgiLSBXYXJuaW5nOiAlZCBwcm90ZWN0ZWQgc2VjdG9ycyB3aWxsIG5vdCBiZSBlcmFzZWQhXG4iLCBwcm90KTsKCX0gZWxzZSB7CgkJcHJpbnRmICgiXG4iKTsKCX0KCgoJLyogU3RhcnQgZXJhc2Ugb24gdW5wcm90ZWN0ZWQgc2VjdG9ycyAqLwoJZm9yIChzZWN0ID0gc19maXJzdDsgc2VjdDw9c19sYXN0OyBzZWN0KyspIHsKCgkJaWYgKGluZm8tPnByb3RlY3Rbc2VjdF0gPT0gMCkgeyAvKiBub3QgcHJvdGVjdGVkICovCgkJCWludCByZXM7CgkJCWludCBmbGFnOwoKCQkJLyogRGlzYWJsZSBpbnRlcnJ1cHRzIHdoaWNoIG1pZ2h0IGNhdXNlIGEgdGltZW91dCBoZXJlICovCgkJCWZsYWcgPSBkaXNhYmxlX2ludGVycnVwdHMoKTsKCgkJCXJlcyA9IF9lcmFzZV9mbGFzaF9wdHIoaW5mby0+c3RhcnRbMF0sIGluZm8tPnN0YXJ0W3NlY3RdLWluZm8tPnN0YXJ0WzBdKTsKCgkJCS8qIHJlLWVuYWJsZSBpbnRlcnJ1cHRzIGlmIG5lY2Vzc2FyeSAqLwoJCQlpZiAoZmxhZykgewoJCQkJZW5hYmxlX2ludGVycnVwdHMoKTsKCQkJfQoKCgkJCWlmIChyZXMpIHsKCQkJCXByaW50ZigiRXJhc2UgdGltZWQgb3V0LCBzZWN0b3IgJWRcbiIsIHNlY3QpOwoJCQkJcmV0dXJuIHJlczsKCQkJfQoKCQkJcHV0YygnLicpOwoJCX0KCX0KCgoJcmV0dXJuIDA7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogV3JpdGUgYSB3b3JkIHRvIEZsYXNoLCByZXR1cm5zOgogKiAwIC0gT0sKICogMSAtIHdyaXRlIHRpbWVvdXQKICogMiAtIEZsYXNoIG5vdCBlcmFzZWQKICovCnN0YXRpYyBpbnQgX2FtZF93cml0ZV93b3JkKHVuc2lnbmVkIHN0YXJ0LCB1bnNpZ25lZCBkZXN0LCB1bnNpZ25lZCBkYXRhKQp7Cgl2b2xhdGlsZSB1MzIgKmFkZHIyID0gKHUzMiopc3RhcnQ7Cgl2b2xhdGlsZSB1MzIgKmRlc3QyID0gKHUzMiopZGVzdDsKCXZvbGF0aWxlIHUzMiAqZGF0YTIgPSAodTMyKikmZGF0YTsKCXVuc2lnbmVkIGVsYXBzZWQ7CgoJLyogQ2hlY2sgaWYgRmxhc2ggaXMgKHN1ZmZpY2llbnRseSkgZXJhc2VkICovCglpZiAoKCooKHZvbGF0aWxlIHUzMiopZGVzdCkgJiAodTMyKWRhdGEpICE9ICh1MzIpZGF0YSkgewoJCXJldHVybiAyOwoJfQoKCWFkZHIyWzB4NTU1NF0gPSAweEFBQUFBQUFBOwoJYWRkcjJbMHhhYWE4XSA9IDB4NTU1NTU1NTU7CglhZGRyMlsweDU1NTRdID0gMHhBMEEwQTBBMDsKCglkZXN0MlswXSA9IGRhdGE7CgoJZWxhcHNlZCA9ICoodm9sYXRpbGUgdTE2KikoMHhmZmZlZjAwMCtTQzUyMF9TV1RNUk1JTExJKTsgLyogZHVtbXkgcmVhZCAqLwoJZWxhcHNlZCA9IDA7CgoJLyogZGF0YSBwb2xsaW5nIGZvciBENyAqLwoJd2hpbGUgKChkZXN0MlswXSAmIDB4ODA4MDgwODApICE9IChkYXRhMlswXSAmIDB4ODA4MDgwODApKSB7CgkJZWxhcHNlZCArPSAqKHZvbGF0aWxlIHUxNiopKDB4ZmZmZWYwMDArU0M1MjBfU1dUTVJNSUxMSSk7CgkJaWYgKGVsYXBzZWQgPiAoKENGR19GTEFTSF9XUklURV9UT1VUL0NGR19IWikgKiAxMDAwKSkgewoJCQlhZGRyMlswXSA9IDB4ZjBmMGYwZjA7CgkJCXJldHVybiAxOwoJCX0KCX0KCgoJYWRkcjJbMF0gPSAweGYwZjBmMGYwOwoKCXJldHVybiAwOwp9CgpleHRlcm4gaW50IF9hbWRfd3JpdGVfd29yZF9lbmQ7CmFzbSAoIl9hbWRfd3JpdGVfd29yZF9lbmQ6XG4iCiAgICAgIi5sb25nIDBcbiIpOwoKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogQ29weSBtZW1vcnkgdG8gZmxhc2gsIHJldHVybnM6CiAqIDAgLSBPSwogKiAxIC0gd3JpdGUgdGltZW91dAogKiAyIC0gRmxhc2ggbm90IGVyYXNlZAogKiAzIC0gVW5zdXBwb3J0ZWQgZmxhc2ggdHlwZQogKi8KCmludCB3cml0ZV9idWZmKGZsYXNoX2luZm9fdCAqaW5mbywgdWNoYXIgKnNyYywgdWxvbmcgYWRkciwgdWxvbmcgY250KQp7Cgl1bG9uZyBjcCwgd3AsIGRhdGE7CglpbnQgaSwgbCwgcmM7CglpbnQgZmxhZzsKCXUzMiAoKl93cml0ZV93b3JkX3B0cikodW5zaWduZWQgc3RhcnQsIHVuc2lnbmVkIGRlc3QsIHVuc2lnbmVkIGRhdGEpOwoJdW5zaWduZWQgc2l6ZTsKCglpZiAoKGluZm8tPmZsYXNoX2lkICYgRkxBU0hfVkVORE1BU0spID09IChBTURfTUFOVUZBQ1QgJiBGTEFTSF9WRU5ETUFTSykpIHsKCQlzaXplID0gKHVuc2lnbmVkKSZfYW1kX3dyaXRlX3dvcmRfZW5kIC0gKHVuc2lnbmVkKV9hbWRfd3JpdGVfd29yZDsKCgkJaWYgKHNpemUgPiBQUk9CRV9CVUZGRVJfU0laRSkgewoJCQlwcmludGYoIl9hbWRfd3JpdGVfd29yZCgpIHJvdXRpbmUgdG9vIGxhcmdlICglZCkgJXAgLSAlcFxuIiwKCQkJICAgICAgIHNpemUsICZfYW1kX3dyaXRlX3dvcmRfZW5kLCBfYW1kX3dyaXRlX3dvcmQpOwoJCQlyZXR1cm4gMDsKCQl9CgoJCW1lbWNweShidWZmZXIsIF9hbWRfd3JpdGVfd29yZCwgc2l6ZSk7CgkJX3dyaXRlX3dvcmRfcHRyID0gKHZvaWQqKWJ1ZmZlcjsKCgl9IGVsc2UgewoJCXByaW50ZiAoIkNhbid0IHByb2dyYW0gdW5rbm93biBmbGFzaCB0eXBlIC0gYWJvcnRlZFxuIik7CgkJcmV0dXJuIDM7Cgl9CgoKCXdwID0gKGFkZHIgJiB+Myk7CS8qIGdldCBsb3dlciB3b3JkIGFsaWduZWQgYWRkcmVzcyAqLwoKCgkvKgoJICogaGFuZGxlIHVuYWxpZ25lZCBzdGFydCBieXRlcwoJICovCglpZiAoKGwgPSBhZGRyIC0gd3ApICE9IDApIHsKCQlkYXRhID0gMDsKCQlmb3IgKGk9MCwgY3A9d3A7IGk8bDsgKytpLCArK2NwKSB7CgkJCWRhdGEgfD0gKCoodWNoYXIgKiljcCkgPDwgKDgqaSk7CgkJfQoJCWZvciAoOyBpPDQgJiYgY250PjA7ICsraSkgewoJCQlkYXRhIHw9ICpzcmMrKyA8PCAoOCppKTsKCQkJLS1jbnQ7CgkJCSsrY3A7CgkJfQoJCWZvciAoOyBjbnQ9PTAgJiYgaTw0OyArK2ksICsrY3ApIHsKCQkJZGF0YSB8PSAoKih1Y2hhciAqKWNwKSAgPDwgKDgqaSk7CgkJfQoKCQkvKiBEaXNhYmxlIGludGVycnVwdHMgd2hpY2ggbWlnaHQgY2F1c2UgYSB0aW1lb3V0IGhlcmUgKi8KCQlmbGFnID0gZGlzYWJsZV9pbnRlcnJ1cHRzKCk7CgoJCXJjID0gX3dyaXRlX3dvcmRfcHRyKGluZm8tPnN0YXJ0WzBdLCB3cCwgZGF0YSk7CgoJCS8qIHJlLWVuYWJsZSBpbnRlcnJ1cHRzIGlmIG5lY2Vzc2FyeSAqLwoJCWlmIChmbGFnKSB7CgkJCWVuYWJsZV9pbnRlcnJ1cHRzKCk7CgkJfQoJCWlmIChyYyAhPSAwKSB7CgkJCXJldHVybiByYzsKCQl9CgkJd3AgKz0gNDsKCX0KCgkvKgoJICogaGFuZGxlIHdvcmQgYWxpZ25lZCBwYXJ0CgkgKi8KCXdoaWxlIChjbnQgPj0gNCkgewoJCWRhdGEgPSAwOwoKCQlmb3IgKGk9MDsgaTw0OyArK2kpIHsKCQkJZGF0YSB8PSAqc3JjKysgPDwgKDgqaSk7CgkJfQoKCQkvKiBEaXNhYmxlIGludGVycnVwdHMgd2hpY2ggbWlnaHQgY2F1c2UgYSB0aW1lb3V0IGhlcmUgKi8KCQlmbGFnID0gZGlzYWJsZV9pbnRlcnJ1cHRzKCk7CgoJCXJjID0gX3dyaXRlX3dvcmRfcHRyKGluZm8tPnN0YXJ0WzBdLCB3cCwgZGF0YSk7CgoJCS8qIHJlLWVuYWJsZSBpbnRlcnJ1cHRzIGlmIG5lY2Vzc2FyeSAqLwoJCWlmIChmbGFnKSB7CgkJCWVuYWJsZV9pbnRlcnJ1cHRzKCk7CgkJfQoJCWlmIChyYyAhPSAwKSB7CgkJCXJldHVybiByYzsKCQl9CgkJd3AgICs9IDQ7CgkJY250IC09IDQ7Cgl9CgoJaWYgKGNudCA9PSAwKSB7CgkJcmV0dXJuIDA7Cgl9CgoJLyoKCSAqIGhhbmRsZSB1bmFsaWduZWQgdGFpbCBieXRlcwoJICovCglkYXRhID0gMDsKCWZvciAoaT0wLCBjcD13cDsgaTw0ICYmIGNudD4wOyArK2ksICsrY3ApIHsKCQlkYXRhIHw9ICpzcmMrKyA8PCAoOCppKTsKCQktLWNudDsKCX0KCglmb3IgKDsgaTw0OyArK2ksICsrY3ApIHsKCQlkYXRhIHw9ICgqKHVjaGFyICopY3ApIDw8ICg4KmkpOwoJfQoKCS8qIERpc2FibGUgaW50ZXJydXB0cyB3aGljaCBtaWdodCBjYXVzZSBhIHRpbWVvdXQgaGVyZSAqLwoJZmxhZyA9IGRpc2FibGVfaW50ZXJydXB0cygpOwoKCXJjID0gX3dyaXRlX3dvcmRfcHRyKGluZm8tPnN0YXJ0WzBdLCB3cCwgZGF0YSk7CgoJLyogcmUtZW5hYmxlIGludGVycnVwdHMgaWYgbmVjZXNzYXJ5ICovCglpZiAoZmxhZykgewoJCWVuYWJsZV9pbnRlcnJ1cHRzKCk7Cgl9CgoJcmV0dXJuIHJjOwoKfQo=