LyoKICogKEMpIENvcHlyaWdodCAyMDAyCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCIDxkYW5pZWxAb21pY3Jvbi5zZT4uCiAqCiAqIFNlZSBmaWxlIENSRURJVFMgZm9yIGxpc3Qgb2YgcGVvcGxlIHdobyBjb250cmlidXRlZCB0byB0aGlzCiAqIHByb2plY3QuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YKICogdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sCiAqIE1BIDAyMTExLTEzMDcgVVNBCiAqLwoKLyogc3R1ZmYgc3BlY2lmaWMgZm9yIHRoZSBzYzUyMCwKICogYnV0IGlkZXBlbmRlbnQgb2YgaW1wbGVtZW50YXRpb24gKi8KCiNpbmNsdWRlIDxjb21tb24uaD4KI2luY2x1ZGUgPGFzbS9pby5oPgojaW5jbHVkZSA8YXNtL2ljL3NjNTIwLmg+CgpERUNMQVJFX0dMT0JBTF9EQVRBX1BUUjsKCi8qCiAqIHV0aWxpdHkgZnVuY3Rpb25zIGZvciBib2FyZHMgYmFzZWQgb24gdGhlIEFNRCBzYzUyMAogKgogKiB2b2lkIHdyaXRlX21tY3JfYnl0ZSh1MTYgbW1jciwgdTggZGF0YSkKICogdm9pZCB3cml0ZV9tbWNyX3dvcmQodTE2IG1tY3IsIHUxNiBkYXRhKQogKiB2b2lkIHdyaXRlX21tY3JfbG9uZyh1MTYgbW1jciwgdTMyIGRhdGEpCiAqCiAqIHU4ICAgcmVhZF9tbWNyX2J5dGUodTE2IG1tY3IpCiAqIHUxNiAgcmVhZF9tbWNyX3dvcmQodTE2IG1tY3IpCiAqIHUzMiAgcmVhZF9tbWNyX2xvbmcodTE2IG1tY3IpCiAqCiAqIHZvaWQgaW5pdF9zYzUyMCh2b2lkKQogKiB1bnNpZ25lZCBsb25nIGluaXRfc2M1MjBfZHJhbSh2b2lkKQogKi8KCnN0YXRpYyB1MzIgbW1jcl9iYXNlPSAweGZmZmVmMDAwOwoKdm9pZCB3cml0ZV9tbWNyX2J5dGUodTE2IG1tY3IsIHU4IGRhdGEpCnsKCXdyaXRlYihkYXRhLCBtbWNyK21tY3JfYmFzZSk7Cn0KCnZvaWQgd3JpdGVfbW1jcl93b3JkKHUxNiBtbWNyLCB1MTYgZGF0YSkKewoJd3JpdGV3KGRhdGEsIG1tY3IrbW1jcl9iYXNlKTsKfQoKdm9pZCB3cml0ZV9tbWNyX2xvbmcodTE2IG1tY3IsIHUzMiBkYXRhKQp7Cgl3cml0ZWwoZGF0YSwgbW1jcittbWNyX2Jhc2UpOwp9Cgp1OCByZWFkX21tY3JfYnl0ZSh1MTYgbW1jcikKewoJcmV0dXJuIHJlYWRiKG1tY3IrbW1jcl9iYXNlKTsKfQoKdTE2IHJlYWRfbW1jcl93b3JkKHUxNiBtbWNyKQp7CglyZXR1cm4gcmVhZHcobW1jcittbWNyX2Jhc2UpOwp9Cgp1MzIgcmVhZF9tbWNyX2xvbmcodTE2IG1tY3IpCnsKCXJldHVybiByZWFkbChtbWNyK21tY3JfYmFzZSk7Cn0KCgp2b2lkIGluaXRfc2M1MjAodm9pZCkKewoJLyogU2V0IHRoZSBVQVJUeENUTCByZWdpc3RlciBhdCBpdCdzIHNsb3dlciwKCSAqIGJhdWQgY2xvY2sgZ2l2aW5nIHVzIGEgMS44NDMyIE1IeiByZWZlcmVuY2UKCSAqLwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX1VBUlQxQ1RMLCA3KTsKCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9VQVJUMkNUTCwgNyk7CgoJLyogZmlyc3Qgc2V0IHRoZSB0aW1lciBwaW4gbWFwcGluZyAqLwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX0NMS1NFTCwgMHg3Mik7CS8qIG5vIGNsb2NrIGZyZXF1ZW5jeSBzZWxlY3RlZCwgdXNlIDEuMTg5Mk1IeiAqLwoKCS8qIGVuYWJsZSBQQ0kgYnVzIGFyYml0cmVyICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfU1lTQVJCQ1RMLDB4MDIpOyAgLyogZW5hYmxlIGNvbmN1cnJlbnQgbW9kZSAqLwoKCXdyaXRlX21tY3Jfd29yZChTQzUyMF9TWVNBUkJNRU5CLDB4MWYpOyAvKiBlbmFibGUgZXh0ZXJuYWwgZ3JhbnRzICovCgl3cml0ZV9tbWNyX3dvcmQoU0M1MjBfSEJDVEwsMHgwNCk7ICAgICAgLyogZW5hYmxlIHBvc3RlZC13cml0ZXMgKi8KCgoJaWYgKENPTkZJR19TWVNfU0M1MjBfSElHSF9TUEVFRCkgewoJCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9DUFVDVEwsIDB4Mik7CS8qIHNldCBpdCB0byAxMzMgTUh6IGFuZCB3cml0ZSBiYWNrICovCgkJZ2QtPmNwdV9jbGsgPSAxMzMwMDAwMDA7CgkJcHJpbnRmKCIjIyBDUFUgU3BlZWQgc2V0IHRvIDEzM01IelxuIik7Cgl9IGVsc2UgewoJCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9DUFVDVEwsIDEpOwkvKiBzZXQgQ1BVIHRvIDEwMCBNSHogYW5kIHdyaXRlIGJhY2sgY2FjaGUgKi8KCQlwcmludGYoIiMjIENQVSBTcGVlZCBzZXQgdG8gMTAwTUh6XG4iKTsKCQlnZC0+Y3B1X2NsayA9IDEwMDAwMDAwMDsKCX0KCgoJLyogd2FpdCBhdCBsZWFzdCBvbmUgbWlsbGlzZWNvbmQgKi8KCWFzbSgibW92bAkkMHgyMDAwLCUlZWN4XG4iCgkgICAgIndhaXRfbG9vcDoJcHVzaGwgJSVlY3hcbiIKCSAgICAicG9wbAklJWVjeFxuIgoJICAgICJsb29wIHdhaXRfbG9vcFxuIjogOiA6ICJlY3giKTsKCgkvKiB0dXJuIG9uIHRoZSBTRFJBTSB3cml0ZSBidWZmZXIgKi8KCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9EQkNUTCwgMHgxMSk7CgoJLyogdHVybiBvbiB0aGUgY2FjaGUgYW5kIGRpc2FibGUgd3JpdGUgdGhyb3VnaCAqLwoJYXNtKCJtb3ZsCSUlY3IwLCAlJWVheFxuIgoJICAgICJhbmRsCSQweDlmZmZmZmZmLCAlJWVheFxuIgoJICAgICJtb3ZsCSUlZWF4LCAlJWNyMFxuIiAgOiA6IDogImVheCIpOwp9Cgp1bnNpZ25lZCBsb25nIGluaXRfc2M1MjBfZHJhbSh2b2lkKQp7CgliZF90ICpiZCA9IGdkLT5iZDsKCgl1MzIgZHJhbV9wcmVzZW50PTA7Cgl1MzIgZHJhbV9jdHJsOwojaWZkZWYgQ09ORklHX1NZU19TRFJBTV9EUkNUTUNUTAoJLyogdGhlc2UgbWVtb3J5IGNvbnRyb2wgcmVnaXN0ZXJzIGFyZSBzZXQgdXAgaW4gdGhlIGFzc2VtYmVyIHBhcnQsCgkgKiBpbiBzYzUyMF9hc20uUywgZHVyaW5nICdtZW1faW5pdCcuICBJZiB3ZSBtdWNrIHdpdGggdGhlbSBoZXJlLAoJICogYWZ0ZXIgd2UgYXJlIHJ1bm5pbmcgYSBzdGFjayBpbiBSQU0sIHdlIGhhdmUgdHJvdWJsZXMuICBCZXNpZGVzLAoJICogdGhlc2UgcmVmcmVzaCBhbmQgZGVsYXkgdmFsdWVzIGFyZSBiZXR0ZXIgPyBzaW1wbHkgc3BlY2lmaWVkCgkgKiBvdXRyaWdodCBpbiB0aGUgaW5jbHVkZS9jb25maWdzL3tjZmd9IGZpbGUgc2luY2UgdGhlIEhXIGRlc2lnbmVyCgkgKiBzaW1wbHkgZGljdGF0ZXMgaXQuCgkgKi8KI2Vsc2UKCWludCB2YWw7CgoJaW50IGNhc19wcmVjaGFyZ2VfZGVsYXkgPSBDT05GSUdfU1lTX1NEUkFNX1BSRUNIQVJHRV9ERUxBWTsKCWludCByZWZyZXNoX3JhdGUgICAgICAgID0gQ09ORklHX1NZU19TRFJBTV9SRUZSRVNIX1JBVEU7CglpbnQgcmFzX2Nhc19kZWxheSAgICAgICA9IENPTkZJR19TWVNfU0RSQU1fUkFTX0NBU19ERUxBWTsKCgkvKiBzZXQgU0RSQU0gc3BlZWQgaGVyZSAqLwoKCXJlZnJlc2hfcmF0ZS89Nzg7CglpZiAocmVmcmVzaF9yYXRlPD0xKSB7CgkJdmFsID0gMDsgIC8qIDcuOHVzICovCgl9IGVsc2UgaWYgKHJlZnJlc2hfcmF0ZT09MikgewoJCXZhbCA9IDE7ICAvKiAxNS42dXMgKi8KCX0gZWxzZSBpZiAocmVmcmVzaF9yYXRlPT0zIHx8IHJlZnJlc2hfcmF0ZT09NCkgewoJCXZhbCA9IDI7ICAvKiAzMS4ydXMgKi8KCX0gZWxzZSB7CgkJdmFsID0gMzsgIC8qIDYyLjR1cyAqLwoJfQoKCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9EUkNDVEwsIChyZWFkX21tY3JfYnl0ZShTQzUyMF9EUkNDVEwpICYgMHhjZikgfCAodmFsPDw0KSk7CgoJdmFsID0gcmVhZF9tbWNyX2J5dGUoU0M1MjBfRFJDVE1DVEwpOwoJdmFsICY9IDB4ZjA7CgoJaWYgKGNhc19wcmVjaGFyZ2VfZGVsYXk9PTMpIHsKCQl2YWwgfD0gMHgwNDsgICAvKiAzVCAqLwoJfSBlbHNlIGlmIChjYXNfcHJlY2hhcmdlX2RlbGF5PT00KSB7CgkJdmFsIHw9IDB4MDg7ICAgLyogNFQgKi8KCX0gZWxzZSBpZiAoY2FzX3ByZWNoYXJnZV9kZWxheT40KSB7CgkJdmFsIHw9IDB4MGM7Cgl9CgoJaWYgKHJhc19jYXNfZGVsYXkgPiAzKSB7CgkJdmFsIHw9IDI7Cgl9IGVsc2UgewoJCXZhbCB8PSAxOwoJfQoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX0RSQ1RNQ1RMLCB2YWwpOwojZW5kaWYKCgkvKiBXZSByZWFkLWJhY2sgdGhlIGNvbmZpZ3VyYXRpb24gb2YgdGhlIGRyYW0KCSAqIGNvbnRyb2xsZXIgdGhhdCB0aGUgYXNzZW1ibHkgY29kZSB3cm90ZSAqLwoJZHJhbV9jdHJsID0gcmVhZF9tbWNyX2xvbmcoU0M1MjBfRFJDQkVOREFEUik7CgoJYmQtPmJpX2RyYW1bMF0uc3RhcnQgPSAwOwoJaWYgKGRyYW1fY3RybCAmIDB4ODApIHsKCQkvKiBiYW5rIDAgZW5hYmxlZCAqLwoJCWRyYW1fcHJlc2VudCA9IGJkLT5iaV9kcmFtWzFdLnN0YXJ0ID0gKGRyYW1fY3RybCAmIDB4N2YpIDw8IDIyOwoJCWJkLT5iaV9kcmFtWzBdLnNpemUgPSBiZC0+YmlfZHJhbVsxXS5zdGFydDsKCgl9IGVsc2UgewoJCWJkLT5iaV9kcmFtWzBdLnNpemUgPSAwOwoJCWJkLT5iaV9kcmFtWzFdLnN0YXJ0ID0gYmQtPmJpX2RyYW1bMF0uc3RhcnQ7Cgl9CgoJaWYgKGRyYW1fY3RybCAmIDB4ODAwMCkgewoJCS8qIGJhbmsgMSBlbmFibGVkICovCgkJZHJhbV9wcmVzZW50ID0gYmQtPmJpX2RyYW1bMl0uc3RhcnQgPSAoZHJhbV9jdHJsICYgMHg3ZjAwKSA8PCAxNDsKCQliZC0+YmlfZHJhbVsxXS5zaXplID0gYmQtPmJpX2RyYW1bMl0uc3RhcnQgLSAgYmQtPmJpX2RyYW1bMV0uc3RhcnQ7Cgl9IGVsc2UgewoJCWJkLT5iaV9kcmFtWzFdLnNpemUgPSAwOwoJCWJkLT5iaV9kcmFtWzJdLnN0YXJ0ID0gYmQtPmJpX2RyYW1bMV0uc3RhcnQ7Cgl9CgoJaWYgKGRyYW1fY3RybCAmIDB4ODAwMDAwKSB7CgkJLyogYmFuayAyIGVuYWJsZWQgKi8KCQlkcmFtX3ByZXNlbnQgPSBiZC0+YmlfZHJhbVszXS5zdGFydCA9IChkcmFtX2N0cmwgJiAweDdmMDAwMCkgPDwgNjsKCQliZC0+YmlfZHJhbVsyXS5zaXplID0gYmQtPmJpX2RyYW1bM10uc3RhcnQgLSAgYmQtPmJpX2RyYW1bMl0uc3RhcnQ7Cgl9IGVsc2UgewoJCWJkLT5iaV9kcmFtWzJdLnNpemUgPSAwOwoJCWJkLT5iaV9kcmFtWzNdLnN0YXJ0ID0gYmQtPmJpX2RyYW1bMl0uc3RhcnQ7Cgl9CgoJaWYgKGRyYW1fY3RybCAmIDB4ODAwMDAwMDApIHsKCQkvKiBiYW5rIDMgZW5hYmxlZCAqLwoJCWRyYW1fcHJlc2VudCAgPSAoZHJhbV9jdHJsICYgMHg3ZjAwMDAwMCkgPj4gMjsKCQliZC0+YmlfZHJhbVszXS5zaXplID0gZHJhbV9wcmVzZW50IC0gIGJkLT5iaV9kcmFtWzNdLnN0YXJ0OwoJfSBlbHNlIHsKCQliZC0+YmlfZHJhbVszXS5zaXplID0gMDsKCX0KCgojaWYgMAoJcHJpbnRmKCJDb25maWd1cmVkICVkIGJ5dGVzIG9mIGRyYW1cbiIsIGRyYW1fcHJlc2VudCk7CiNlbmRpZgoJZ2QtPnJhbV9zaXplID0gZHJhbV9wcmVzZW50OwoKCXJldHVybiBkcmFtX3ByZXNlbnQ7Cn0KCiNpZmRlZiBDT05GSUdfU1lTX1NDNTIwX1JFU0VUCnZvaWQgcmVzZXRfY3B1KHVsb25nIGFkZHIpCnsKCXByaW50ZigiUmVzZXR0aW5nIHVzaW5nIFNDNTIwIE1NQ1JcbiIpOwoJLyogV3JpdGUgYSAnMScgdG8gdGhlIFNZU19SU1Qgb2YgdGhlIFJFU0NGRyBNTUNSICovCgl3cml0ZV9tbWNyX3dvcmQoU0M1MjBfUkVTQ0ZHLCAweDAwMDEpOwoKCS8qIE5PVFJFQUNIRUQgKi8KfQojZW5kaWYK