LyoKICogKEMpIENvcHlyaWdodCAyMDAyCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCIDxkYW5pZWxAb21pY3Jvbi5zZT4uCiAqCiAqIFNlZSBmaWxlIENSRURJVFMgZm9yIGxpc3Qgb2YgcGVvcGxlIHdobyBjb250cmlidXRlZCB0byB0aGlzCiAqIHByb2plY3QuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YKICogdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sCiAqIE1BIDAyMTExLTEzMDcgVVNBCiAqLwoKLyogc3R1ZmYgc3BlY2lmaWMgZm9yIHRoZSBzYzUyMCwKICogYnV0IGlkZXBlbmRlbnQgb2YgaW1wbGVtZW50YXRpb24gKi8KCiNpbmNsdWRlIDxjb21tb24uaD4KI2luY2x1ZGUgPGFzbS9pby5oPgojaW5jbHVkZSA8YXNtL2ljL3NjNTIwLmg+CgpERUNMQVJFX0dMT0JBTF9EQVRBX1BUUjsKCi8qCiAqIHV0aWxpdHkgZnVuY3Rpb25zIGZvciBib2FyZHMgYmFzZWQgb24gdGhlIEFNRCBzYzUyMAogKgogKiB2b2lkIGluaXRfc2M1MjAodm9pZCkKICogdW5zaWduZWQgbG9uZyBpbml0X3NjNTIwX2RyYW0odm9pZCkKICovCgp2b2xhdGlsZSBzYzUyMF9tbWNyX3QgKnNjNTIwX21tY3IgPSAoc2M1MjBfbW1jcl90ICopMHhmZmZlZjAwMDsKCnZvaWQgaW5pdF9zYzUyMCh2b2lkKQp7CgkvKgoJICogU2V0IHRoZSBVQVJUeENUTCByZWdpc3RlciBhdCBpdCdzIHNsb3dlciwKCSAqIGJhdWQgY2xvY2sgZ2l2aW5nIHVzIGEgMS44NDMyIE1IeiByZWZlcmVuY2UKCSAqLwoJd3JpdGViKDB4MDcsICZzYzUyMF9tbWNyLT51YXJ0MWN0bCk7Cgl3cml0ZWIoMHgwNywgJnNjNTIwX21tY3ItPnVhcnQyY3RsKTsKCgkvKiBmaXJzdCBzZXQgdGhlIHRpbWVyIHBpbiBtYXBwaW5nICovCgl3cml0ZWIoMHg3MiwgJnNjNTIwX21tY3ItPmNsa3NlbCk7CS8qIG5vIGNsb2NrIGZyZXF1ZW5jeSBzZWxlY3RlZCwgdXNlIDEuMTg5Mk1IeiAqLwoKCS8qIGVuYWJsZSBQQ0kgYnVzIGFyYml0ZXIgKGNvbmN1cnJlbnQgbW9kZSkgKi8KCXdyaXRlYigweDAyLCAmc2M1MjBfbW1jci0+c3lzYXJiY3RsKTsKCgkvKiBlbmFibGUgZXh0ZXJuYWwgZ3JhbnRzICovCgl3cml0ZWIoMHgxZiwgJnNjNTIwX21tY3ItPnN5c2FyYm1lbmIpOwoKCS8qIGVuYWJsZSBwb3N0ZWQtd3JpdGVzICovCgl3cml0ZWIoMHgwNCwgJnNjNTIwX21tY3ItPmhiY3RsKTsKCglpZiAoQ09ORklHX1NZU19TQzUyMF9ISUdIX1NQRUVEKSB7CgkJLyogc2V0IGl0IHRvIDEzMyBNSHogYW5kIHdyaXRlIGJhY2sgKi8KCQl3cml0ZWIoMHgwMiwgJnNjNTIwX21tY3ItPmNwdWN0bCk7CgkJZ2QtPmNwdV9jbGsgPSAxMzMwMDAwMDA7CgkJcHJpbnRmKCIjIyBDUFUgU3BlZWQgc2V0IHRvIDEzM01IelxuIik7Cgl9IGVsc2UgewoJCS8qIHNldCBpdCB0byAxMDAgTUh6IGFuZCB3cml0ZSBiYWNrICovCgkJd3JpdGViKDB4MDEsICZzYzUyMF9tbWNyLT5jcHVjdGwpOwoJCXByaW50ZigiIyMgQ1BVIFNwZWVkIHNldCB0byAxMDBNSHpcbiIpOwoJCWdkLT5jcHVfY2xrID0gMTAwMDAwMDAwOwoJfQoKCgkvKiB3YWl0IGF0IGxlYXN0IG9uZSBtaWxsaXNlY29uZCAqLwoJYXNtKCJtb3ZsCSQweDIwMDAsICUlZWN4XG4iCgkgICAgIjA6CQlwdXNobCAlJWVjeFxuIgoJICAgICJwb3BsCSUlZWN4XG4iCgkgICAgImxvb3AgMGJcbiI6IDogOiAiZWN4Iik7CgoJLyogdHVybiBvbiB0aGUgU0RSQU0gd3JpdGUgYnVmZmVyICovCgl3cml0ZWIoMHgxMSwgJnNjNTIwX21tY3ItPmRiY3RsKTsKCgkvKiB0dXJuIG9uIHRoZSBjYWNoZSBhbmQgZGlzYWJsZSB3cml0ZSB0aHJvdWdoICovCglhc20oIm1vdmwJJSVjcjAsICUlZWF4XG4iCgkgICAgImFuZGwJJDB4OWZmZmZmZmYsICUlZWF4XG4iCgkgICAgIm1vdmwJJSVlYXgsICUlY3IwXG4iICA6IDogOiAiZWF4Iik7Cn0KCnVuc2lnbmVkIGxvbmcgaW5pdF9zYzUyMF9kcmFtKHZvaWQpCnsKCWJkX3QgKmJkID0gZ2QtPmJkOwoKCXUzMiBkcmFtX3ByZXNlbnQ9MDsKCXUzMiBkcmFtX2N0cmw7CgojaWZkZWYgQ09ORklHX1NZU19TRFJBTV9EUkNUTUNUTAoJLyogdGhlc2UgbWVtb3J5IGNvbnRyb2wgcmVnaXN0ZXJzIGFyZSBzZXQgdXAgaW4gdGhlIGFzc2VtYmVyIHBhcnQsCgkgKiBpbiBzYzUyMF9hc20uUywgZHVyaW5nICdtZW1faW5pdCcuICBJZiB3ZSBtdWNrIHdpdGggdGhlbSBoZXJlLAoJICogYWZ0ZXIgd2UgYXJlIHJ1bm5pbmcgYSBzdGFjayBpbiBSQU0sIHdlIGhhdmUgdHJvdWJsZXMuICBCZXNpZGVzLAoJICogdGhlc2UgcmVmcmVzaCBhbmQgZGVsYXkgdmFsdWVzIGFyZSBiZXR0ZXIgPyBzaW1wbHkgc3BlY2lmaWVkCgkgKiBvdXRyaWdodCBpbiB0aGUgaW5jbHVkZS9jb25maWdzL3tjZmd9IGZpbGUgc2luY2UgdGhlIEhXIGRlc2lnbmVyCgkgKiBzaW1wbHkgZGljdGF0ZXMgaXQuCgkgKi8KI2Vsc2UKCXU4IHRtcDsKCXU4IHZhbDsKCglpbnQgY2FzX3ByZWNoYXJnZV9kZWxheSA9IENPTkZJR19TWVNfU0RSQU1fUFJFQ0hBUkdFX0RFTEFZOwoJaW50IHJlZnJlc2hfcmF0ZSAgICAgICAgPSBDT05GSUdfU1lTX1NEUkFNX1JFRlJFU0hfUkFURTsKCWludCByYXNfY2FzX2RlbGF5ICAgICAgID0gQ09ORklHX1NZU19TRFJBTV9SQVNfQ0FTX0RFTEFZOwoKCS8qIHNldCBTRFJBTSBzcGVlZCBoZXJlICovCgoJcmVmcmVzaF9yYXRlIC89IDc4OwoJaWYgKHJlZnJlc2hfcmF0ZSA8PSAxKSB7CgkJdmFsID0gMDsJLyogNy44dXMgKi8KCX0gZWxzZSBpZiAocmVmcmVzaF9yYXRlID09IDIpIHsKCQl2YWwgPSAxOwkvKiAxNS42dXMgKi8KCX0gZWxzZSBpZiAocmVmcmVzaF9yYXRlID09IDMgfHwgcmVmcmVzaF9yYXRlID09IDQpIHsKCQl2YWwgPSAyOwkvKiAzMS4ydXMgKi8KCX0gZWxzZSB7CgkJdmFsID0gMzsJLyogNjIuNHVzICovCgl9CgoJdG1wID0gKHJlYWRiKCZzYzUyMF9tbWNyLT5kcmNjdGwpICYgMHhjZikgfCAodmFsPDw0KTsKCXdyaXRlYih0bXAsICZzYzUyMF9tbWNyLT5kcmNjdGwpOwoKCXZhbCA9IHJlYWRiKCZzYzUyMF9tbWNyLT5kcmN0bWN0bCkgJiAweGYwOwoKCWlmIChjYXNfcHJlY2hhcmdlX2RlbGF5PT0zKSB7CgkJdmFsIHw9IDB4MDQ7CS8qIDNUICovCgl9IGVsc2UgaWYgKGNhc19wcmVjaGFyZ2VfZGVsYXk9PTQpIHsKCQl2YWwgfD0gMHgwODsJLyogNFQgKi8KCX0gZWxzZSBpZiAoY2FzX3ByZWNoYXJnZV9kZWxheT40KSB7CgkJdmFsIHw9IDB4MGM7Cgl9CgoJaWYgKHJhc19jYXNfZGVsYXkgPiAzKSB7CgkJdmFsIHw9IDI7Cgl9IGVsc2UgewoJCXZhbCB8PSAxOwoJfQoJd3JpdGViKHZhbCwgJmM1MjBfbW1jci0+ZHJjdG1jdGwpOwojZW5kaWYKCgkvKgoJICogV2UgcmVhZC1iYWNrIHRoZSBjb25maWd1cmF0aW9uIG9mIHRoZSBkcmFtCgkgKiBjb250cm9sbGVyIHRoYXQgdGhlIGFzc2VtYmx5IGNvZGUgd3JvdGUKCSAqLwoJZHJhbV9jdHJsID0gcmVhZGwoJnNjNTIwX21tY3ItPmRyY2JlbmRhZHIpOwoKCWJkLT5iaV9kcmFtWzBdLnN0YXJ0ID0gMDsKCWlmIChkcmFtX2N0cmwgJiAweDgwKSB7CgkJLyogYmFuayAwIGVuYWJsZWQgKi8KCQlkcmFtX3ByZXNlbnQgPSBiZC0+YmlfZHJhbVsxXS5zdGFydCA9IChkcmFtX2N0cmwgJiAweDdmKSA8PCAyMjsKCQliZC0+YmlfZHJhbVswXS5zaXplID0gYmQtPmJpX2RyYW1bMV0uc3RhcnQ7Cgl9IGVsc2UgewoJCWJkLT5iaV9kcmFtWzBdLnNpemUgPSAwOwoJCWJkLT5iaV9kcmFtWzFdLnN0YXJ0ID0gYmQtPmJpX2RyYW1bMF0uc3RhcnQ7Cgl9CgoJaWYgKGRyYW1fY3RybCAmIDB4ODAwMCkgewoJCS8qIGJhbmsgMSBlbmFibGVkICovCgkJZHJhbV9wcmVzZW50ID0gYmQtPmJpX2RyYW1bMl0uc3RhcnQgPSAoZHJhbV9jdHJsICYgMHg3ZjAwKSA8PCAxNDsKCQliZC0+YmlfZHJhbVsxXS5zaXplID0gYmQtPmJpX2RyYW1bMl0uc3RhcnQgLSAgYmQtPmJpX2RyYW1bMV0uc3RhcnQ7Cgl9IGVsc2UgewoJCWJkLT5iaV9kcmFtWzFdLnNpemUgPSAwOwoJCWJkLT5iaV9kcmFtWzJdLnN0YXJ0ID0gYmQtPmJpX2RyYW1bMV0uc3RhcnQ7Cgl9CgoJaWYgKGRyYW1fY3RybCAmIDB4ODAwMDAwKSB7CgkJLyogYmFuayAyIGVuYWJsZWQgKi8KCQlkcmFtX3ByZXNlbnQgPSBiZC0+YmlfZHJhbVszXS5zdGFydCA9IChkcmFtX2N0cmwgJiAweDdmMDAwMCkgPDwgNjsKCQliZC0+YmlfZHJhbVsyXS5zaXplID0gYmQtPmJpX2RyYW1bM10uc3RhcnQgLSAgYmQtPmJpX2RyYW1bMl0uc3RhcnQ7Cgl9IGVsc2UgewoJCWJkLT5iaV9kcmFtWzJdLnNpemUgPSAwOwoJCWJkLT5iaV9kcmFtWzNdLnN0YXJ0ID0gYmQtPmJpX2RyYW1bMl0uc3RhcnQ7Cgl9CgoJaWYgKGRyYW1fY3RybCAmIDB4ODAwMDAwMDApIHsKCQkvKiBiYW5rIDMgZW5hYmxlZCAqLwoJCWRyYW1fcHJlc2VudCAgPSAoZHJhbV9jdHJsICYgMHg3ZjAwMDAwMCkgPj4gMjsKCQliZC0+YmlfZHJhbVszXS5zaXplID0gZHJhbV9wcmVzZW50IC0gIGJkLT5iaV9kcmFtWzNdLnN0YXJ0OwoJfSBlbHNlIHsKCQliZC0+YmlfZHJhbVszXS5zaXplID0gMDsKCX0KCWdkLT5yYW1fc2l6ZSA9IGRyYW1fcHJlc2VudDsKCglyZXR1cm4gZHJhbV9wcmVzZW50Owp9CgojaWZkZWYgQ09ORklHX1NZU19TQzUyMF9SRVNFVAp2b2lkIHJlc2V0X2NwdSh1bG9uZyBhZGRyKQp7CglwcmludGYoIlJlc2V0dGluZyB1c2luZyBTQzUyMCBNTUNSXG4iKTsKCS8qIFdyaXRlIGEgJzEnIHRvIHRoZSBTWVNfUlNUIG9mIHRoZSBSRVNDRkcgTU1DUiAqLwoJd3JpdGViKDB4MDEsICZzYzUyMF9tbWNyLT5yZXNjZmcpOwoKCS8qIE5PVFJFQUNIRUQgKi8KfQojZW5kaWYK