LyoKICogbGludXgvYXJjaC9hcm0vcGxhdC1vbWFwL2RtYS5jCiAqCiAqIENvcHlyaWdodCAoQykgMjAwMyBOb2tpYSBDb3Jwb3JhdGlvbgogKiBBdXRob3I6IEp1aGEgWXJq9mzkIDxqdWhhLnlyam9sYUBub2tpYS5jb20+CiAqIERNQSBjaGFubmVsIGxpbmtpbmcgZm9yIDE2MTAgYnkgU2FtdWVsIE9ydGl6IDxzYW11ZWwub3J0aXpAbm9raWEuY29tPgogKiBHcmFwaGljcyBETUEgYW5kIExDRCBETUEgZ3JhcGhpY3MgdHJhbmZvcm1hdGlvbnMKICogYnkgSW1yZSBEZWFrIDxpbXJlLmRlYWtAbm9raWEuY29tPgogKiBPTUFQMiBzdXBwb3J0IENvcHlyaWdodCAoQykgMjAwNC0yMDA1IFRleGFzIEluc3RydW1lbnRzLCBJbmMuCiAqIE1lcmdlZCB0byBzdXBwb3J0IGJvdGggT01BUDEgYW5kIE9NQVAyIGJ5IFRvbnkgTGluZGdyZW4gPHRvbnlAYXRvbWlkZS5jb20+CiAqIFNvbWUgZnVuY3Rpb25zIGJhc2VkIG9uIGVhcmxpZXIgZG1hLW9tYXAuYyBDb3B5cmlnaHQgKEMpIDIwMDEgUmlkZ2VSdW4sIEluYy4KICoKICogU3VwcG9ydCBmdW5jdGlvbnMgZm9yIHRoZSBPTUFQIGludGVybmFsIERNQSBjaGFubmVscy4KICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCiAqCiAqLwoKI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvc2NoZWQuaD4KI2luY2x1ZGUgPGxpbnV4L3NwaW5sb2NrLmg+CiNpbmNsdWRlIDxsaW51eC9lcnJuby5oPgojaW5jbHVkZSA8bGludXgvaW50ZXJydXB0Lmg+CiNpbmNsdWRlIDxsaW51eC9pcnEuaD4KCiNpbmNsdWRlIDxhc20vc3lzdGVtLmg+CiNpbmNsdWRlIDxhc20vaGFyZHdhcmUuaD4KI2luY2x1ZGUgPGFzbS9kbWEuaD4KI2luY2x1ZGUgPGFzbS9pby5oPgoKI2luY2x1ZGUgPGFzbS9hcmNoL3RjLmg+CgojZGVmaW5lIERFQlVHX1BSSU5UUwojdW5kZWYgREVCVUdfUFJJTlRTCiNpZmRlZiBERUJVR19QUklOVFMKI2RlZmluZSBkZWJ1Z19wcmludGsoeCkgcHJpbnRrIHgKI2Vsc2UKI2RlZmluZQlkZWJ1Z19wcmludGsoeCkKI2VuZGlmCgojZGVmaW5lIE9NQVBfRE1BX0FDVElWRQkJMHgwMQojZGVmaW5lIE9NQVBfRE1BX0NDUl9FTgkJKDEgPDwgNykKI2RlZmluZSBPTUFQMl9ETUFfQ1NSX0NMRUFSX01BU0sJMHhmZmUKCiNkZWZpbmUgT01BUF9GVU5DX01VWF9BUk1fQkFTRQkoMHhmZmZlMTAwMCArIDB4ZWMpCgpzdGF0aWMgaW50IGVuYWJsZV8xNTEwX21vZGUgPSAwOwoKc3RydWN0IG9tYXBfZG1hX2xjaCB7CglpbnQgbmV4dF9sY2g7CglpbnQgZGV2X2lkOwoJdTE2IHNhdmVkX2NzcjsKCXUxNiBlbmFibGVkX2lycXM7Cgljb25zdCBjaGFyICpkZXZfbmFtZTsKCXZvaWQgKCogY2FsbGJhY2spKGludCBsY2gsIHUxNiBjaF9zdGF0dXMsIHZvaWQgKmRhdGEpOwoJdm9pZCAqZGF0YTsKCWxvbmcgZmxhZ3M7Cn07CgpzdGF0aWMgaW50IGRtYV9jaGFuX2NvdW50OwoKc3RhdGljIHNwaW5sb2NrX3QgZG1hX2NoYW5fbG9jazsKc3RhdGljIHN0cnVjdCBvbWFwX2RtYV9sY2ggZG1hX2NoYW5bT01BUF9MT0dJQ0FMX0RNQV9DSF9DT1VOVF07CgpzdGF0aWMgY29uc3QgdTggb21hcDFfZG1hX2lycVtPTUFQX0xPR0lDQUxfRE1BX0NIX0NPVU5UXSA9IHsKCUlOVF9ETUFfQ0gwXzYsIElOVF9ETUFfQ0gxXzcsIElOVF9ETUFfQ0gyXzgsIElOVF9ETUFfQ0gzLAoJSU5UX0RNQV9DSDQsIElOVF9ETUFfQ0g1LCBJTlRfMTYxMF9ETUFfQ0g2LCBJTlRfMTYxMF9ETUFfQ0g3LAoJSU5UXzE2MTBfRE1BX0NIOCwgSU5UXzE2MTBfRE1BX0NIOSwgSU5UXzE2MTBfRE1BX0NIMTAsCglJTlRfMTYxMF9ETUFfQ0gxMSwgSU5UXzE2MTBfRE1BX0NIMTIsIElOVF8xNjEwX0RNQV9DSDEzLAoJSU5UXzE2MTBfRE1BX0NIMTQsIElOVF8xNjEwX0RNQV9DSDE1LCBJTlRfRE1BX0xDRAp9OwoKI2RlZmluZSBSRVZJU0lUXzI0WFgoKQkJcHJpbnRrKEtFUk5fRVJSICJGSVhNRTogbm8gJXMgb24gMjR4eFxuIiwgXAoJCQkJCQlfX0ZVTkNUSU9OX18pOwoKI2lmZGVmIENPTkZJR19BUkNIX09NQVAxNVhYCi8qIFJldHVybnMgMSBpZiB0aGUgRE1BIG1vZHVsZSBpcyBpbiBPTUFQMTUxMC1jb21wYXRpYmxlIG1vZGUsIDAgb3RoZXJ3aXNlICovCmludCBvbWFwX2RtYV9pbl8xNTEwX21vZGUodm9pZCkKewoJcmV0dXJuIGVuYWJsZV8xNTEwX21vZGU7Cn0KI2Vsc2UKI2RlZmluZSBvbWFwX2RtYV9pbl8xNTEwX21vZGUoKQkJMAojZW5kaWYKCiNpZmRlZiBDT05GSUdfQVJDSF9PTUFQMQpzdGF0aWMgaW5saW5lIGludCBnZXRfZ2RtYV9kZXYoaW50IHJlcSkKewoJdTMyIHJlZyA9IE9NQVBfRlVOQ19NVVhfQVJNX0JBU0UgKyAoKHJlcSAtIDEpIC8gNSkgKiA0OwoJaW50IHNoaWZ0ID0gKChyZXEgLSAxKSAlIDUpICogNjsKCglyZXR1cm4gKChvbWFwX3JlYWRsKHJlZykgPj4gc2hpZnQpICYgMHgzZikgKyAxOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgc2V0X2dkbWFfZGV2KGludCByZXEsIGludCBkZXYpCnsKCXUzMiByZWcgPSBPTUFQX0ZVTkNfTVVYX0FSTV9CQVNFICsgKChyZXEgLSAxKSAvIDUpICogNDsKCWludCBzaGlmdCA9ICgocmVxIC0gMSkgJSA1KSAqIDY7Cgl1MzIgbDsKCglsID0gb21hcF9yZWFkbChyZWcpOwoJbCAmPSB+KDB4M2YgPDwgc2hpZnQpOwoJbCB8PSAoZGV2IC0gMSkgPDwgc2hpZnQ7CglvbWFwX3dyaXRlbChsLCByZWcpOwp9CiNlbHNlCiNkZWZpbmUgc2V0X2dkbWFfZGV2KHJlcSwgZGV2KQlkbyB7fSB3aGlsZSAoMCkKI2VuZGlmCgpzdGF0aWMgdm9pZCBjbGVhcl9sY2hfcmVncyhpbnQgbGNoKQp7CglpbnQgaTsKCXUzMiBsY2hfYmFzZSA9IE9NQVBfRE1BX0JBU0UgKyBsY2ggKiAweDQwOwoKCWZvciAoaSA9IDA7IGkgPCAweDJjOyBpICs9IDIpCgkJb21hcF93cml0ZXcoMCwgbGNoX2Jhc2UgKyBpKTsKfQoKdm9pZCBvbWFwX3NldF9kbWFfcHJpb3JpdHkoaW50IGxjaCwgaW50IGRzdF9wb3J0LCBpbnQgcHJpb3JpdHkpCnsKCXVuc2lnbmVkIGxvbmcgcmVnOwoJdTMyIGw7CgoJaWYgKGNwdV9jbGFzc19pc19vbWFwMSgpKSB7CgkJc3dpdGNoIChkc3RfcG9ydCkgewoJCWNhc2UgT01BUF9ETUFfUE9SVF9PQ1BfVDE6CS8qIEZGRkVDQzAwICovCgkJCXJlZyA9IE9NQVBfVENfT0NQVDFfUFJJT1I7CgkJCWJyZWFrOwoJCWNhc2UgT01BUF9ETUFfUE9SVF9PQ1BfVDI6CS8qIEZGRkVDQ0QwICovCgkJCXJlZyA9IE9NQVBfVENfT0NQVDJfUFJJT1I7CgkJCWJyZWFrOwoJCWNhc2UgT01BUF9ETUFfUE9SVF9FTUlGRjoJLyogRkZGRUNDMDggKi8KCQkJcmVnID0gT01BUF9UQ19FTUlGRl9QUklPUjsKCQkJYnJlYWs7CgkJY2FzZSBPTUFQX0RNQV9QT1JUX0VNSUZTOgkvKiBGRkZFQ0MwNCAqLwoJCQlyZWcgPSBPTUFQX1RDX0VNSUZTX1BSSU9SOwoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQlCVUcoKTsKCQkJcmV0dXJuOwoJCX0KCQlsID0gb21hcF9yZWFkbChyZWcpOwoJCWwgJj0gfigweGYgPDwgOCk7CgkJbCB8PSAocHJpb3JpdHkgJiAweGYpIDw8IDg7CgkJb21hcF93cml0ZWwobCwgcmVnKTsKCX0KCglpZiAoY3B1X2lzX29tYXAyNHh4KCkpIHsKCQlpZiAocHJpb3JpdHkpCgkJCU9NQVBfRE1BX0NDUl9SRUcobGNoKSB8PSAoMSA8PCA2KTsKCQllbHNlCgkJCU9NQVBfRE1BX0NDUl9SRUcobGNoKSAmPSB+KDEgPDwgNik7Cgl9Cn0KCnZvaWQgb21hcF9zZXRfZG1hX3RyYW5zZmVyX3BhcmFtcyhpbnQgbGNoLCBpbnQgZGF0YV90eXBlLCBpbnQgZWxlbV9jb3VudCwKCQkJCSAgaW50IGZyYW1lX2NvdW50LCBpbnQgc3luY19tb2RlLAoJCQkJICBpbnQgZG1hX3RyaWdnZXIsIGludCBzcmNfb3JfZHN0X3N5bmNoKQp7CglPTUFQX0RNQV9DU0RQX1JFRyhsY2gpICY9IH4weDAzOwoJT01BUF9ETUFfQ1NEUF9SRUcobGNoKSB8PSBkYXRhX3R5cGU7CgoJaWYgKGNwdV9jbGFzc19pc19vbWFwMSgpKSB7CgkJT01BUF9ETUFfQ0NSX1JFRyhsY2gpICY9IH4oMSA8PCA1KTsKCQlpZiAoc3luY19tb2RlID09IE9NQVBfRE1BX1NZTkNfRlJBTUUpCgkJCU9NQVBfRE1BX0NDUl9SRUcobGNoKSB8PSAxIDw8IDU7CgoJCU9NQVAxX0RNQV9DQ1IyX1JFRyhsY2gpICY9IH4oMSA8PCAyKTsKCQlpZiAoc3luY19tb2RlID09IE9NQVBfRE1BX1NZTkNfQkxPQ0spCgkJCU9NQVAxX0RNQV9DQ1IyX1JFRyhsY2gpIHw9IDEgPDwgMjsKCX0KCglpZiAoY3B1X2lzX29tYXAyNHh4KCkgJiYgZG1hX3RyaWdnZXIpIHsKCQl1MzIgdmFsID0gT01BUF9ETUFfQ0NSX1JFRyhsY2gpOwoKCQl2YWwgJj0gfigzIDw8IDE5KTsKCQlpZiAoZG1hX3RyaWdnZXIgPiA2MykKCQkJdmFsIHw9IDEgPDwgMjA7CgkJaWYgKGRtYV90cmlnZ2VyID4gMzEpCgkJCXZhbCB8PSAxIDw8IDE5OwoKCQl2YWwgJj0gfigweDFmKTsKCQl2YWwgfD0gKGRtYV90cmlnZ2VyICYgMHgxZik7CgoJCWlmIChzeW5jX21vZGUgJiBPTUFQX0RNQV9TWU5DX0ZSQU1FKQoJCQl2YWwgfD0gMSA8PCA1OwoJCWVsc2UKCQkJdmFsICY9IH4oMSA8PCA1KTsKCgkJaWYgKHN5bmNfbW9kZSAmIE9NQVBfRE1BX1NZTkNfQkxPQ0spCgkJCXZhbCB8PSAxIDw8IDE4OwoJCWVsc2UKCQkJdmFsICY9IH4oMSA8PCAxOCk7CgoJCWlmIChzcmNfb3JfZHN0X3N5bmNoKQoJCQl2YWwgfD0gMSA8PCAyNDsJCS8qIHNvdXJjZSBzeW5jaCAqLwoJCWVsc2UKCQkJdmFsICY9IH4oMSA8PCAyNCk7CS8qIGRlc3Qgc3luY2ggKi8KCgkJT01BUF9ETUFfQ0NSX1JFRyhsY2gpID0gdmFsOwoJfQoKCU9NQVBfRE1BX0NFTl9SRUcobGNoKSA9IGVsZW1fY291bnQ7CglPTUFQX0RNQV9DRk5fUkVHKGxjaCkgPSBmcmFtZV9jb3VudDsKfQoKdm9pZCBvbWFwX3NldF9kbWFfY29sb3JfbW9kZShpbnQgbGNoLCBlbnVtIG9tYXBfZG1hX2NvbG9yX21vZGUgbW9kZSwgdTMyIGNvbG9yKQp7Cgl1MTYgdzsKCglCVUdfT04ob21hcF9kbWFfaW5fMTUxMF9tb2RlKCkpOwoKCWlmIChjcHVfaXNfb21hcDI0eHgoKSkgewoJCVJFVklTSVRfMjRYWCgpOwoJCXJldHVybjsKCX0KCgl3ID0gT01BUDFfRE1BX0NDUjJfUkVHKGxjaCkgJiB+MHgwMzsKCXN3aXRjaCAobW9kZSkgewoJY2FzZSBPTUFQX0RNQV9DT05TVEFOVF9GSUxMOgoJCXcgfD0gMHgwMTsKCQlicmVhazsKCWNhc2UgT01BUF9ETUFfVFJBTlNQQVJFTlRfQ09QWToKCQl3IHw9IDB4MDI7CgkJYnJlYWs7CgljYXNlIE9NQVBfRE1BX0NPTE9SX0RJUzoKCQlicmVhazsKCWRlZmF1bHQ6CgkJQlVHKCk7Cgl9CglPTUFQMV9ETUFfQ0NSMl9SRUcobGNoKSA9IHc7CgoJdyA9IE9NQVAxX0RNQV9MQ0hfQ1RSTF9SRUcobGNoKSAmIH4weDBmOwoJLyogRGVmYXVsdCBpcyBjaGFubmVsIHR5cGUgMkQgKi8KCWlmIChtb2RlKSB7CgkJT01BUDFfRE1BX0NPTE9SX0xfUkVHKGxjaCkgPSAodTE2KWNvbG9yOwoJCU9NQVAxX0RNQV9DT0xPUl9VX1JFRyhsY2gpID0gKHUxNikoY29sb3IgPj4gMTYpOwoJCXcgfD0gMTsJCS8qIENoYW5uZWwgdHlwZSBHICovCgl9CglPTUFQMV9ETUFfTENIX0NUUkxfUkVHKGxjaCkgPSB3Owp9Cgp2b2lkIG9tYXBfc2V0X2RtYV93cml0ZV9tb2RlKGludCBsY2gsIGVudW0gb21hcF9kbWFfd3JpdGVfbW9kZSBtb2RlKQp7CglpZiAoY3B1X2lzX29tYXAyNHh4KCkpIHsKCQlPTUFQX0RNQV9DU0RQX1JFRyhsY2gpICY9IH4oMHgzIDw8IDE2KTsKCQlPTUFQX0RNQV9DU0RQX1JFRyhsY2gpIHw9IChtb2RlIDw8IDE2KTsKCX0KfQoKLyogTm90ZSB0aGF0IHNyY19wb3J0IGlzIG9ubHkgZm9yIG9tYXAxICovCnZvaWQgb21hcF9zZXRfZG1hX3NyY19wYXJhbXMoaW50IGxjaCwgaW50IHNyY19wb3J0LCBpbnQgc3JjX2Ftb2RlLAoJCQkgICAgIHVuc2lnbmVkIGxvbmcgc3JjX3N0YXJ0LAoJCQkgICAgIGludCBzcmNfZWksIGludCBzcmNfZmkpCnsKCWlmIChjcHVfY2xhc3NfaXNfb21hcDEoKSkgewoJCU9NQVBfRE1BX0NTRFBfUkVHKGxjaCkgJj0gfigweDFmIDw8IDIpOwoJCU9NQVBfRE1BX0NTRFBfUkVHKGxjaCkgfD0gc3JjX3BvcnQgPDwgMjsKCX0KCglPTUFQX0RNQV9DQ1JfUkVHKGxjaCkgJj0gfigweDAzIDw8IDEyKTsKCU9NQVBfRE1BX0NDUl9SRUcobGNoKSB8PSBzcmNfYW1vZGUgPDwgMTI7CgoJaWYgKGNwdV9jbGFzc19pc19vbWFwMSgpKSB7CgkJT01BUDFfRE1BX0NTU0FfVV9SRUcobGNoKSA9IHNyY19zdGFydCA+PiAxNjsKCQlPTUFQMV9ETUFfQ1NTQV9MX1JFRyhsY2gpID0gc3JjX3N0YXJ0OwoJfQoKCWlmIChjcHVfaXNfb21hcDI0eHgoKSkKCQlPTUFQMl9ETUFfQ1NTQV9SRUcobGNoKSA9IHNyY19zdGFydDsKCglPTUFQX0RNQV9DU0VJX1JFRyhsY2gpID0gc3JjX2VpOwoJT01BUF9ETUFfQ1NGSV9SRUcobGNoKSA9IHNyY19maTsKfQoKdm9pZCBvbWFwX3NldF9kbWFfcGFyYW1zKGludCBsY2gsIHN0cnVjdCBvbWFwX2RtYV9jaGFubmVsX3BhcmFtcyAqIHBhcmFtcykKewoJb21hcF9zZXRfZG1hX3RyYW5zZmVyX3BhcmFtcyhsY2gsIHBhcmFtcy0+ZGF0YV90eXBlLAoJCQkJICAgICBwYXJhbXMtPmVsZW1fY291bnQsIHBhcmFtcy0+ZnJhbWVfY291bnQsCgkJCQkgICAgIHBhcmFtcy0+c3luY19tb2RlLCBwYXJhbXMtPnRyaWdnZXIsCgkJCQkgICAgIHBhcmFtcy0+c3JjX29yX2RzdF9zeW5jaCk7CglvbWFwX3NldF9kbWFfc3JjX3BhcmFtcyhsY2gsIHBhcmFtcy0+c3JjX3BvcnQsCgkJCQlwYXJhbXMtPnNyY19hbW9kZSwgcGFyYW1zLT5zcmNfc3RhcnQsCgkJCQlwYXJhbXMtPnNyY19laSwgcGFyYW1zLT5zcmNfZmkpOwoKCW9tYXBfc2V0X2RtYV9kZXN0X3BhcmFtcyhsY2gsIHBhcmFtcy0+ZHN0X3BvcnQsCgkJCQkgcGFyYW1zLT5kc3RfYW1vZGUsIHBhcmFtcy0+ZHN0X3N0YXJ0LAoJCQkJIHBhcmFtcy0+ZHN0X2VpLCBwYXJhbXMtPmRzdF9maSk7Cn0KCnZvaWQgb21hcF9zZXRfZG1hX3NyY19pbmRleChpbnQgbGNoLCBpbnQgZWlkeCwgaW50IGZpZHgpCnsKCWlmIChjcHVfaXNfb21hcDI0eHgoKSkgewoJCVJFVklTSVRfMjRYWCgpOwoJCXJldHVybjsKCX0KCU9NQVBfRE1BX0NTRUlfUkVHKGxjaCkgPSBlaWR4OwoJT01BUF9ETUFfQ1NGSV9SRUcobGNoKSA9IGZpZHg7Cn0KCnZvaWQgb21hcF9zZXRfZG1hX3NyY19kYXRhX3BhY2soaW50IGxjaCwgaW50IGVuYWJsZSkKewoJT01BUF9ETUFfQ1NEUF9SRUcobGNoKSAmPSB+KDEgPDwgNik7CglpZiAoZW5hYmxlKQoJCU9NQVBfRE1BX0NTRFBfUkVHKGxjaCkgfD0gKDEgPDwgNik7Cn0KCnZvaWQgb21hcF9zZXRfZG1hX3NyY19idXJzdF9tb2RlKGludCBsY2gsIGVudW0gb21hcF9kbWFfYnVyc3RfbW9kZSBidXJzdF9tb2RlKQp7Cgl1bnNpZ25lZCBpbnQgYnVyc3QgPSAwOwoJT01BUF9ETUFfQ1NEUF9SRUcobGNoKSAmPSB+KDB4MDMgPDwgNyk7CgoJc3dpdGNoIChidXJzdF9tb2RlKSB7CgljYXNlIE9NQVBfRE1BX0RBVEFfQlVSU1RfRElTOgoJCWJyZWFrOwoJY2FzZSBPTUFQX0RNQV9EQVRBX0JVUlNUXzQ6CgkJaWYgKGNwdV9pc19vbWFwMjR4eCgpKQoJCQlidXJzdCA9IDB4MTsKCQllbHNlCgkJCWJ1cnN0ID0gMHgyOwoJCWJyZWFrOwoJY2FzZSBPTUFQX0RNQV9EQVRBX0JVUlNUXzg6CgkJaWYgKGNwdV9pc19vbWFwMjR4eCgpKSB7CgkJCWJ1cnN0ID0gMHgyOwoJCQlicmVhazsKCQl9CgkJLyogbm90IHN1cHBvcnRlZCBieSBjdXJyZW50IGhhcmR3YXJlIG9uIE9NQVAxCgkJICogdyB8PSAoMHgwMyA8PCA3KTsKCQkgKiBmYWxsIHRocm91Z2gKCQkgKi8KCWNhc2UgT01BUF9ETUFfREFUQV9CVVJTVF8xNjoKCQlpZiAoY3B1X2lzX29tYXAyNHh4KCkpIHsKCQkJYnVyc3QgPSAweDM7CgkJCWJyZWFrOwoJCX0KCQkvKiBPTUFQMSBkb24ndCBzdXBwb3J0IGJ1cnN0IDE2CgkJICogZmFsbCB0aHJvdWdoCgkJICovCglkZWZhdWx0OgoJCUJVRygpOwoJfQoJT01BUF9ETUFfQ1NEUF9SRUcobGNoKSB8PSAoYnVyc3QgPDwgNyk7Cn0KCi8qIE5vdGUgdGhhdCBkZXN0X3BvcnQgaXMgb25seSBmb3IgT01BUDEgKi8Kdm9pZCBvbWFwX3NldF9kbWFfZGVzdF9wYXJhbXMoaW50IGxjaCwgaW50IGRlc3RfcG9ydCwgaW50IGRlc3RfYW1vZGUsCgkJCSAgICAgIHVuc2lnbmVkIGxvbmcgZGVzdF9zdGFydCwKCQkJICAgICAgaW50IGRzdF9laSwgaW50IGRzdF9maSkKewoJaWYgKGNwdV9jbGFzc19pc19vbWFwMSgpKSB7CgkJT01BUF9ETUFfQ1NEUF9SRUcobGNoKSAmPSB+KDB4MWYgPDwgOSk7CgkJT01BUF9ETUFfQ1NEUF9SRUcobGNoKSB8PSBkZXN0X3BvcnQgPDwgOTsKCX0KCglPTUFQX0RNQV9DQ1JfUkVHKGxjaCkgJj0gfigweDAzIDw8IDE0KTsKCU9NQVBfRE1BX0NDUl9SRUcobGNoKSB8PSBkZXN0X2Ftb2RlIDw8IDE0OwoKCWlmIChjcHVfY2xhc3NfaXNfb21hcDEoKSkgewoJCU9NQVAxX0RNQV9DRFNBX1VfUkVHKGxjaCkgPSBkZXN0X3N0YXJ0ID4+IDE2OwoJCU9NQVAxX0RNQV9DRFNBX0xfUkVHKGxjaCkgPSBkZXN0X3N0YXJ0OwoJfQoKCWlmIChjcHVfaXNfb21hcDI0eHgoKSkKCQlPTUFQMl9ETUFfQ0RTQV9SRUcobGNoKSA9IGRlc3Rfc3RhcnQ7CgoJT01BUF9ETUFfQ0RFSV9SRUcobGNoKSA9IGRzdF9laTsKCU9NQVBfRE1BX0NERklfUkVHKGxjaCkgPSBkc3RfZmk7Cn0KCnZvaWQgb21hcF9zZXRfZG1hX2Rlc3RfaW5kZXgoaW50IGxjaCwgaW50IGVpZHgsIGludCBmaWR4KQp7CglpZiAoY3B1X2lzX29tYXAyNHh4KCkpIHsKCQlSRVZJU0lUXzI0WFgoKTsKCQlyZXR1cm47Cgl9CglPTUFQX0RNQV9DREVJX1JFRyhsY2gpID0gZWlkeDsKCU9NQVBfRE1BX0NERklfUkVHKGxjaCkgPSBmaWR4Owp9Cgp2b2lkIG9tYXBfc2V0X2RtYV9kZXN0X2RhdGFfcGFjayhpbnQgbGNoLCBpbnQgZW5hYmxlKQp7CglPTUFQX0RNQV9DU0RQX1JFRyhsY2gpICY9IH4oMSA8PCAxMyk7CglpZiAoZW5hYmxlKQoJCU9NQVBfRE1BX0NTRFBfUkVHKGxjaCkgfD0gMSA8PCAxMzsKfQoKdm9pZCBvbWFwX3NldF9kbWFfZGVzdF9idXJzdF9tb2RlKGludCBsY2gsIGVudW0gb21hcF9kbWFfYnVyc3RfbW9kZSBidXJzdF9tb2RlKQp7Cgl1bnNpZ25lZCBpbnQgYnVyc3QgPSAwOwoJT01BUF9ETUFfQ1NEUF9SRUcobGNoKSAmPSB+KDB4MDMgPDwgMTQpOwoKCXN3aXRjaCAoYnVyc3RfbW9kZSkgewoJY2FzZSBPTUFQX0RNQV9EQVRBX0JVUlNUX0RJUzoKCQlicmVhazsKCWNhc2UgT01BUF9ETUFfREFUQV9CVVJTVF80OgoJCWlmIChjcHVfaXNfb21hcDI0eHgoKSkKCQkJYnVyc3QgPSAweDE7CgkJZWxzZQoJCQlidXJzdCA9IDB4MjsKCQlicmVhazsKCWNhc2UgT01BUF9ETUFfREFUQV9CVVJTVF84OgoJCWlmIChjcHVfaXNfb21hcDI0eHgoKSkKCQkJYnVyc3QgPSAweDI7CgkJZWxzZQoJCQlidXJzdCA9IDB4MzsKCQlicmVhazsKCWNhc2UgT01BUF9ETUFfREFUQV9CVVJTVF8xNjoKCQlpZiAoY3B1X2lzX29tYXAyNHh4KCkpIHsKCQkJYnVyc3QgPSAweDM7CgkJCWJyZWFrOwoJCX0KCQkvKiBPTUFQMSBkb24ndCBzdXBwb3J0IGJ1cnN0IDE2CgkJICogZmFsbCB0aHJvdWdoCgkJICovCglkZWZhdWx0OgoJCXByaW50ayhLRVJOX0VSUiAiSW52YWxpZCBETUEgYnVyc3QgbW9kZVxuIik7CgkJQlVHKCk7CgkJcmV0dXJuOwoJfQoJT01BUF9ETUFfQ1NEUF9SRUcobGNoKSB8PSAoYnVyc3QgPDwgMTQpOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgb21hcF9lbmFibGVfY2hhbm5lbF9pcnEoaW50IGxjaCkKewoJdTMyIHN0YXR1czsKCgkvKiBDbGVhciBDU1IgKi8KCWlmIChjcHVfY2xhc3NfaXNfb21hcDEoKSkKCQlzdGF0dXMgPSBPTUFQX0RNQV9DU1JfUkVHKGxjaCk7CgllbHNlIGlmIChjcHVfaXNfb21hcDI0eHgoKSkKCQlPTUFQX0RNQV9DU1JfUkVHKGxjaCkgPSBPTUFQMl9ETUFfQ1NSX0NMRUFSX01BU0s7CgoJLyogRW5hYmxlIHNvbWUgbmljZSBpbnRlcnJ1cHRzLiAqLwoJT01BUF9ETUFfQ0lDUl9SRUcobGNoKSA9IGRtYV9jaGFuW2xjaF0uZW5hYmxlZF9pcnFzOwoKCWRtYV9jaGFuW2xjaF0uZmxhZ3MgfD0gT01BUF9ETUFfQUNUSVZFOwp9CgpzdGF0aWMgdm9pZCBvbWFwX2Rpc2FibGVfY2hhbm5lbF9pcnEoaW50IGxjaCkKewoJaWYgKGNwdV9pc19vbWFwMjR4eCgpKQoJCU9NQVBfRE1BX0NJQ1JfUkVHKGxjaCkgPSAwOwp9Cgp2b2lkIG9tYXBfZW5hYmxlX2RtYV9pcnEoaW50IGxjaCwgdTE2IGJpdHMpCnsKCWRtYV9jaGFuW2xjaF0uZW5hYmxlZF9pcnFzIHw9IGJpdHM7Cn0KCnZvaWQgb21hcF9kaXNhYmxlX2RtYV9pcnEoaW50IGxjaCwgdTE2IGJpdHMpCnsKCWRtYV9jaGFuW2xjaF0uZW5hYmxlZF9pcnFzICY9IH5iaXRzOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgZW5hYmxlX2xuayhpbnQgbGNoKQp7CglpZiAoY3B1X2NsYXNzX2lzX29tYXAxKCkpCgkJT01BUF9ETUFfQ0xOS19DVFJMX1JFRyhsY2gpICY9IH4oMSA8PCAxNCk7CgoJLyogU2V0IHRoZSBFTkFCTEVfTE5LIGJpdHMgKi8KCWlmIChkbWFfY2hhbltsY2hdLm5leHRfbGNoICE9IC0xKQoJCU9NQVBfRE1BX0NMTktfQ1RSTF9SRUcobGNoKSA9CgkJCWRtYV9jaGFuW2xjaF0ubmV4dF9sY2ggfCAoMSA8PCAxNSk7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBkaXNhYmxlX2xuayhpbnQgbGNoKQp7CgkvKiBEaXNhYmxlIGludGVycnVwdHMgKi8KCWlmIChjcHVfY2xhc3NfaXNfb21hcDEoKSkgewoJCU9NQVBfRE1BX0NJQ1JfUkVHKGxjaCkgPSAwOwoJCS8qIFNldCB0aGUgU1RPUF9MTksgYml0ICovCgkJT01BUF9ETUFfQ0xOS19DVFJMX1JFRyhsY2gpIHw9IDEgPDwgMTQ7Cgl9CgoJaWYgKGNwdV9pc19vbWFwMjR4eCgpKSB7CgkJb21hcF9kaXNhYmxlX2NoYW5uZWxfaXJxKGxjaCk7CgkJLyogQ2xlYXIgdGhlIEVOQUJMRV9MTksgYml0ICovCgkJT01BUF9ETUFfQ0xOS19DVFJMX1JFRyhsY2gpICY9IH4oMSA8PCAxNSk7Cgl9CgoJZG1hX2NoYW5bbGNoXS5mbGFncyAmPSB+T01BUF9ETUFfQUNUSVZFOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgb21hcDJfZW5hYmxlX2lycV9sY2goaW50IGxjaCkKewoJdTMyIHZhbDsKCglpZiAoIWNwdV9pc19vbWFwMjR4eCgpKQoJCXJldHVybjsKCgl2YWwgPSBvbWFwX3JlYWRsKE9NQVBfRE1BNF9JUlFFTkFCTEVfTDApOwoJdmFsIHw9IDEgPDwgbGNoOwoJb21hcF93cml0ZWwodmFsLCBPTUFQX0RNQTRfSVJRRU5BQkxFX0wwKTsKfQoKaW50IG9tYXBfcmVxdWVzdF9kbWEoaW50IGRldl9pZCwgY29uc3QgY2hhciAqZGV2X25hbWUsCgkJICAgICB2b2lkICgqIGNhbGxiYWNrKShpbnQgbGNoLCB1MTYgY2hfc3RhdHVzLCB2b2lkICpkYXRhKSwKCQkgICAgIHZvaWQgKmRhdGEsIGludCAqZG1hX2NoX291dCkKewoJaW50IGNoLCBmcmVlX2NoID0gLTE7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoJc3RydWN0IG9tYXBfZG1hX2xjaCAqY2hhbjsKCglzcGluX2xvY2tfaXJxc2F2ZSgmZG1hX2NoYW5fbG9jaywgZmxhZ3MpOwoJZm9yIChjaCA9IDA7IGNoIDwgZG1hX2NoYW5fY291bnQ7IGNoKyspIHsKCQlpZiAoZnJlZV9jaCA9PSAtMSAmJiBkbWFfY2hhbltjaF0uZGV2X2lkID09IC0xKSB7CgkJCWZyZWVfY2ggPSBjaDsKCQkJaWYgKGRldl9pZCA9PSAwKQoJCQkJYnJlYWs7CgkJfQoJfQoJaWYgKGZyZWVfY2ggPT0gLTEpIHsKCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZkbWFfY2hhbl9sb2NrLCBmbGFncyk7CgkJcmV0dXJuIC1FQlVTWTsKCX0KCWNoYW4gPSBkbWFfY2hhbiArIGZyZWVfY2g7CgljaGFuLT5kZXZfaWQgPSBkZXZfaWQ7CgoJaWYgKGNwdV9jbGFzc19pc19vbWFwMSgpKQoJCWNsZWFyX2xjaF9yZWdzKGZyZWVfY2gpOwoKCWlmIChjcHVfaXNfb21hcDI0eHgoKSkKCQlvbWFwX2NsZWFyX2RtYShmcmVlX2NoKTsKCglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZkbWFfY2hhbl9sb2NrLCBmbGFncyk7CgoJY2hhbi0+ZGV2X25hbWUgPSBkZXZfbmFtZTsKCWNoYW4tPmNhbGxiYWNrID0gY2FsbGJhY2s7CgljaGFuLT5kYXRhID0gZGF0YTsKCWNoYW4tPmVuYWJsZWRfaXJxcyA9IE9NQVBfRE1BX0RST1BfSVJRIHwgT01BUF9ETUFfQkxPQ0tfSVJROwoKCWlmIChjcHVfY2xhc3NfaXNfb21hcDEoKSkKCQljaGFuLT5lbmFibGVkX2lycXMgfD0gT01BUDFfRE1BX1RPVVRfSVJROwoJZWxzZSBpZiAoY3B1X2lzX29tYXAyNHh4KCkpCgkJY2hhbi0+ZW5hYmxlZF9pcnFzIHw9IE9NQVAyX0RNQV9NSVNBTElHTkVEX0VSUl9JUlEgfAoJCQlPTUFQMl9ETUFfVFJBTlNfRVJSX0lSUTsKCglpZiAoY3B1X2lzX29tYXAxNnh4KCkpIHsKCQkvKiBJZiB0aGUgc3luYyBkZXZpY2UgaXMgc2V0LCBjb25maWd1cmUgaXQgZHluYW1pY2FsbHkuICovCgkJaWYgKGRldl9pZCAhPSAwKSB7CgkJCXNldF9nZG1hX2RldihmcmVlX2NoICsgMSwgZGV2X2lkKTsKCQkJZGV2X2lkID0gZnJlZV9jaCArIDE7CgkJfQoJCS8qIERpc2FibGUgdGhlIDE1MTAgY29tcGF0aWJpbGl0eSBtb2RlIGFuZCBzZXQgdGhlIHN5bmMgZGV2aWNlCgkJICogaWQuICovCgkJT01BUF9ETUFfQ0NSX1JFRyhmcmVlX2NoKSA9IGRldl9pZCB8ICgxIDw8IDEwKTsKCX0gZWxzZSBpZiAoY3B1X2lzX29tYXA3MzAoKSB8fCBjcHVfaXNfb21hcDE1eHgoKSkgewoJCU9NQVBfRE1BX0NDUl9SRUcoZnJlZV9jaCkgPSBkZXZfaWQ7Cgl9CgoJaWYgKGNwdV9pc19vbWFwMjR4eCgpKSB7CgkJb21hcDJfZW5hYmxlX2lycV9sY2goZnJlZV9jaCk7CgoJCW9tYXBfZW5hYmxlX2NoYW5uZWxfaXJxKGZyZWVfY2gpOwoJCS8qIENsZWFyIHRoZSBDU1IgcmVnaXN0ZXIgYW5kIElSUSBzdGF0dXMgcmVnaXN0ZXIgKi8KCQlPTUFQX0RNQV9DU1JfUkVHKGZyZWVfY2gpID0gT01BUDJfRE1BX0NTUl9DTEVBUl9NQVNLOwoJCW9tYXBfd3JpdGVsKDEgPDwgZnJlZV9jaCwgT01BUF9ETUE0X0lSUVNUQVRVU19MMCk7Cgl9CgoJKmRtYV9jaF9vdXQgPSBmcmVlX2NoOwoKCXJldHVybiAwOwp9Cgp2b2lkIG9tYXBfZnJlZV9kbWEoaW50IGxjaCkKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglzcGluX2xvY2tfaXJxc2F2ZSgmZG1hX2NoYW5fbG9jaywgZmxhZ3MpOwoJaWYgKGRtYV9jaGFuW2xjaF0uZGV2X2lkID09IC0xKSB7CgkJcHJpbnRrKCJvbWFwX2RtYTogdHJ5aW5nIHRvIGZyZWUgbm9uYWxsb2NhdGVkIERNQSBjaGFubmVsICVkXG4iLAoJCSAgICAgICBsY2gpOwoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmRtYV9jaGFuX2xvY2ssIGZsYWdzKTsKCQlyZXR1cm47Cgl9CglkbWFfY2hhbltsY2hdLmRldl9pZCA9IC0xOwoJZG1hX2NoYW5bbGNoXS5uZXh0X2xjaCA9IC0xOwoJZG1hX2NoYW5bbGNoXS5jYWxsYmFjayA9IE5VTEw7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZkbWFfY2hhbl9sb2NrLCBmbGFncyk7CgoJaWYgKGNwdV9jbGFzc19pc19vbWFwMSgpKSB7CgkJLyogRGlzYWJsZSBhbGwgRE1BIGludGVycnVwdHMgZm9yIHRoZSBjaGFubmVsLiAqLwoJCU9NQVBfRE1BX0NJQ1JfUkVHKGxjaCkgPSAwOwoJCS8qIE1ha2Ugc3VyZSB0aGUgRE1BIHRyYW5zZmVyIGlzIHN0b3BwZWQuICovCgkJT01BUF9ETUFfQ0NSX1JFRyhsY2gpID0gMDsKCX0KCglpZiAoY3B1X2lzX29tYXAyNHh4KCkpIHsKCQl1MzIgdmFsOwoJCS8qIERpc2FibGUgaW50ZXJydXB0cyAqLwoJCXZhbCA9IG9tYXBfcmVhZGwoT01BUF9ETUE0X0lSUUVOQUJMRV9MMCk7CgkJdmFsICY9IH4oMSA8PCBsY2gpOwoJCW9tYXBfd3JpdGVsKHZhbCwgT01BUF9ETUE0X0lSUUVOQUJMRV9MMCk7CgoJCS8qIENsZWFyIHRoZSBDU1IgcmVnaXN0ZXIgYW5kIElSUSBzdGF0dXMgcmVnaXN0ZXIgKi8KCQlPTUFQX0RNQV9DU1JfUkVHKGxjaCkgPSBPTUFQMl9ETUFfQ1NSX0NMRUFSX01BU0s7CgkJb21hcF93cml0ZWwoMSA8PCBsY2gsIE9NQVBfRE1BNF9JUlFTVEFUVVNfTDApOwoKCQkvKiBEaXNhYmxlIGFsbCBETUEgaW50ZXJydXB0cyBmb3IgdGhlIGNoYW5uZWwuICovCgkJT01BUF9ETUFfQ0lDUl9SRUcobGNoKSA9IDA7CgoJCS8qIE1ha2Ugc3VyZSB0aGUgRE1BIHRyYW5zZmVyIGlzIHN0b3BwZWQuICovCgkJT01BUF9ETUFfQ0NSX1JFRyhsY2gpID0gMDsKCQlvbWFwX2NsZWFyX2RtYShsY2gpOwoJfQp9CgovKgogKiBDbGVhcnMgYW55IERNQSBzdGF0ZSBzbyB0aGUgRE1BIGVuZ2luZSBpcyByZWFkeSB0byByZXN0YXJ0IHdpdGggbmV3IGJ1ZmZlcnMKICogdGhyb3VnaCBvbWFwX3N0YXJ0X2RtYSgpLiBBbnkgYnVmZmVycyBpbiBmbGlnaHQgYXJlIGRpc2NhcmRlZC4KICovCnZvaWQgb21hcF9jbGVhcl9kbWEoaW50IGxjaCkKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglsb2NhbF9pcnFfc2F2ZShmbGFncyk7CgoJaWYgKGNwdV9jbGFzc19pc19vbWFwMSgpKSB7CgkJaW50IHN0YXR1czsKCQlPTUFQX0RNQV9DQ1JfUkVHKGxjaCkgJj0gfk9NQVBfRE1BX0NDUl9FTjsKCgkJLyogQ2xlYXIgcGVuZGluZyBpbnRlcnJ1cHRzICovCgkJc3RhdHVzID0gT01BUF9ETUFfQ1NSX1JFRyhsY2gpOwoJfQoKCWlmIChjcHVfaXNfb21hcDI0eHgoKSkgewoJCWludCBpOwoJCXUzMiBsY2hfYmFzZSA9IE9NQVAyNFhYX0RNQV9CQVNFICsgbGNoICogMHg2MCArIDB4ODA7CgkJZm9yIChpID0gMDsgaSA8IDB4NDQ7IGkgKz0gNCkKCQkJb21hcF93cml0ZWwoMCwgbGNoX2Jhc2UgKyBpKTsKCX0KCglsb2NhbF9pcnFfcmVzdG9yZShmbGFncyk7Cn0KCnZvaWQgb21hcF9zdGFydF9kbWEoaW50IGxjaCkKewoJaWYgKCFvbWFwX2RtYV9pbl8xNTEwX21vZGUoKSAmJiBkbWFfY2hhbltsY2hdLm5leHRfbGNoICE9IC0xKSB7CgkJaW50IG5leHRfbGNoLCBjdXJfbGNoOwoJCWNoYXIgZG1hX2NoYW5fbGlua19tYXBbT01BUF9MT0dJQ0FMX0RNQV9DSF9DT1VOVF07CgoJCWRtYV9jaGFuX2xpbmtfbWFwW2xjaF0gPSAxOwoJCS8qIFNldCB0aGUgbGluayByZWdpc3RlciBvZiB0aGUgZmlyc3QgY2hhbm5lbCAqLwoJCWVuYWJsZV9sbmsobGNoKTsKCgkJbWVtc2V0KGRtYV9jaGFuX2xpbmtfbWFwLCAwLCBzaXplb2YoZG1hX2NoYW5fbGlua19tYXApKTsKCQljdXJfbGNoID0gZG1hX2NoYW5bbGNoXS5uZXh0X2xjaDsKCQlkbyB7CgkJCW5leHRfbGNoID0gZG1hX2NoYW5bY3VyX2xjaF0ubmV4dF9sY2g7CgoJCQkvKiBUaGUgbG9vcCBjYXNlOiB3ZSd2ZSBiZWVuIGhlcmUgYWxyZWFkeSAqLwoJCQlpZiAoZG1hX2NoYW5fbGlua19tYXBbY3VyX2xjaF0pCgkJCQlicmVhazsKCQkJLyogTWFyayB0aGUgY3VycmVudCBjaGFubmVsICovCgkJCWRtYV9jaGFuX2xpbmtfbWFwW2N1cl9sY2hdID0gMTsKCgkJCWVuYWJsZV9sbmsoY3VyX2xjaCk7CgkJCW9tYXBfZW5hYmxlX2NoYW5uZWxfaXJxKGN1cl9sY2gpOwoKCQkJY3VyX2xjaCA9IG5leHRfbGNoOwoJCX0gd2hpbGUgKG5leHRfbGNoICE9IC0xKTsKCX0gZWxzZSBpZiAoY3B1X2lzX29tYXAyNHh4KCkpIHsKCQkvKiBFcnJhdGE6IE5lZWQgdG8gd3JpdGUgbGNoIGV2ZW4gaWYgbm90IHVzaW5nIGNoYWluaW5nICovCgkJT01BUF9ETUFfQ0xOS19DVFJMX1JFRyhsY2gpID0gbGNoOwoJfQoKCW9tYXBfZW5hYmxlX2NoYW5uZWxfaXJxKGxjaCk7CgoJLyogRXJyYXRhOiBPbiBFUzIuMCBCVUZGRVJJTkcgZGlzYWJsZSBtdXN0IGJlIHNldC4KCSAqIFRoaXMgd2lsbCBhbHdheXMgZmFpbCBvbiBFUzEuMCAqLwoJaWYgKGNwdV9pc19vbWFwMjR4eCgpKSB7CgkJT01BUF9ETUFfQ0NSX1JFRyhsY2gpIHw9IE9NQVBfRE1BX0NDUl9FTjsKCX0KCglPTUFQX0RNQV9DQ1JfUkVHKGxjaCkgfD0gT01BUF9ETUFfQ0NSX0VOOwoKCWRtYV9jaGFuW2xjaF0uZmxhZ3MgfD0gT01BUF9ETUFfQUNUSVZFOwp9Cgp2b2lkIG9tYXBfc3RvcF9kbWEoaW50IGxjaCkKewoJaWYgKCFvbWFwX2RtYV9pbl8xNTEwX21vZGUoKSAmJiBkbWFfY2hhbltsY2hdLm5leHRfbGNoICE9IC0xKSB7CgkJaW50IG5leHRfbGNoLCBjdXJfbGNoID0gbGNoOwoJCWNoYXIgZG1hX2NoYW5fbGlua19tYXBbT01BUF9MT0dJQ0FMX0RNQV9DSF9DT1VOVF07CgoJCW1lbXNldChkbWFfY2hhbl9saW5rX21hcCwgMCwgc2l6ZW9mKGRtYV9jaGFuX2xpbmtfbWFwKSk7CgkJZG8gewoJCQkvKiBUaGUgbG9vcCBjYXNlOiB3ZSd2ZSBiZWVuIGhlcmUgYWxyZWFkeSAqLwoJCQlpZiAoZG1hX2NoYW5fbGlua19tYXBbY3VyX2xjaF0pCgkJCQlicmVhazsKCQkJLyogTWFyayB0aGUgY3VycmVudCBjaGFubmVsICovCgkJCWRtYV9jaGFuX2xpbmtfbWFwW2N1cl9sY2hdID0gMTsKCgkJCWRpc2FibGVfbG5rKGN1cl9sY2gpOwoKCQkJbmV4dF9sY2ggPSBkbWFfY2hhbltjdXJfbGNoXS5uZXh0X2xjaDsKCQkJY3VyX2xjaCA9IG5leHRfbGNoOwoJCX0gd2hpbGUgKG5leHRfbGNoICE9IC0xKTsKCgkJcmV0dXJuOwoJfQoKCS8qIERpc2FibGUgYWxsIGludGVycnVwdHMgb24gdGhlIGNoYW5uZWwgKi8KCWlmIChjcHVfY2xhc3NfaXNfb21hcDEoKSkKCQlPTUFQX0RNQV9DSUNSX1JFRyhsY2gpID0gMDsKCglPTUFQX0RNQV9DQ1JfUkVHKGxjaCkgJj0gfk9NQVBfRE1BX0NDUl9FTjsKCWRtYV9jaGFuW2xjaF0uZmxhZ3MgJj0gfk9NQVBfRE1BX0FDVElWRTsKfQoKLyoKICogQWxsb3dzIGNoYW5naW5nIHRoZSBETUEgY2FsbGJhY2sgZnVuY3Rpb24gb3IgZGF0YS4gVGhpcyBtYXkgYmUgbmVlZGVkIGlmCiAqIHRoZSBkcml2ZXIgc2hhcmVzIGEgc2luZ2xlIERNQSBjaGFubmVsIGZvciBtdWx0aXBsZSBkbWEgdHJpZ2dlcnMuCiAqLwppbnQgb21hcF9zZXRfZG1hX2NhbGxiYWNrKGludCBsY2gsCgkJCSAgdm9pZCAoKiBjYWxsYmFjaykoaW50IGxjaCwgdTE2IGNoX3N0YXR1cywgdm9pZCAqZGF0YSksCgkJCSAgdm9pZCAqZGF0YSkKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglpZiAobGNoIDwgMCkKCQlyZXR1cm4gLUVOT0RFVjsKCglzcGluX2xvY2tfaXJxc2F2ZSgmZG1hX2NoYW5fbG9jaywgZmxhZ3MpOwoJaWYgKGRtYV9jaGFuW2xjaF0uZGV2X2lkID09IC0xKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJETUEgY2FsbGJhY2sgZm9yIG5vdCBzZXQgZm9yIGZyZWUgY2hhbm5lbFxuIik7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmZG1hX2NoYW5fbG9jaywgZmxhZ3MpOwoJCXJldHVybiAtRUlOVkFMOwoJfQoJZG1hX2NoYW5bbGNoXS5jYWxsYmFjayA9IGNhbGxiYWNrOwoJZG1hX2NoYW5bbGNoXS5kYXRhID0gZGF0YTsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmRtYV9jaGFuX2xvY2ssIGZsYWdzKTsKCglyZXR1cm4gMDsKfQoKLyoKICogUmV0dXJucyBjdXJyZW50IHBoeXNpY2FsIHNvdXJjZSBhZGRyZXNzIGZvciB0aGUgZ2l2ZW4gRE1BIGNoYW5uZWwuCiAqIElmIHRoZSBjaGFubmVsIGlzIHJ1bm5pbmcgdGhlIGNhbGxlciBtdXN0IGRpc2FibGUgaW50ZXJydXB0cyBwcmlvciBjYWxsaW5nCiAqIHRoaXMgZnVuY3Rpb24gYW5kIHByb2Nlc3MgdGhlIHJldHVybmVkIHZhbHVlIGJlZm9yZSByZS1lbmFibGluZyBpbnRlcnJ1cHQgdG8KICogcHJldmVudCByYWNlcyB3aXRoIHRoZSBpbnRlcnJ1cHQgaGFuZGxlci4gTm90ZSB0aGF0IGluIGNvbnRpbnVvdXMgbW9kZSB0aGVyZQogKiBpcyBhIGNoYW5jZSBmb3IgQ1NTQV9MIHJlZ2lzdGVyIG92ZXJmbG93IGluYmV0d2VlbiB0aGUgdHdvIHJlYWRzIHJlc3VsdGluZwogKiBpbiBpbmNvcnJlY3QgcmV0dXJuIHZhbHVlLgogKi8KZG1hX2FkZHJfdCBvbWFwX2dldF9kbWFfc3JjX3BvcyhpbnQgbGNoKQp7CglkbWFfYWRkcl90IG9mZnNldDsKCglpZiAoY3B1X2NsYXNzX2lzX29tYXAxKCkpCgkJb2Zmc2V0ID0gKGRtYV9hZGRyX3QpIChPTUFQMV9ETUFfQ1NTQV9MX1JFRyhsY2gpIHwKCQkJCSAgICAgICAoT01BUDFfRE1BX0NTU0FfVV9SRUcobGNoKSA8PCAxNikpOwoKCWlmIChjcHVfaXNfb21hcDI0eHgoKSkKCQlvZmZzZXQgPSBPTUFQX0RNQV9DU0FDX1JFRyhsY2gpOwoKCXJldHVybiBvZmZzZXQ7Cn0KCi8qCiAqIFJldHVybnMgY3VycmVudCBwaHlzaWNhbCBkZXN0aW5hdGlvbiBhZGRyZXNzIGZvciB0aGUgZ2l2ZW4gRE1BIGNoYW5uZWwuCiAqIElmIHRoZSBjaGFubmVsIGlzIHJ1bm5pbmcgdGhlIGNhbGxlciBtdXN0IGRpc2FibGUgaW50ZXJydXB0cyBwcmlvciBjYWxsaW5nCiAqIHRoaXMgZnVuY3Rpb24gYW5kIHByb2Nlc3MgdGhlIHJldHVybmVkIHZhbHVlIGJlZm9yZSByZS1lbmFibGluZyBpbnRlcnJ1cHQgdG8KICogcHJldmVudCByYWNlcyB3aXRoIHRoZSBpbnRlcnJ1cHQgaGFuZGxlci4gTm90ZSB0aGF0IGluIGNvbnRpbnVvdXMgbW9kZSB0aGVyZQogKiBpcyBhIGNoYW5jZSBmb3IgQ0RTQV9MIHJlZ2lzdGVyIG92ZXJmbG93IGluYmV0d2VlbiB0aGUgdHdvIHJlYWRzIHJlc3VsdGluZwogKiBpbiBpbmNvcnJlY3QgcmV0dXJuIHZhbHVlLgogKi8KZG1hX2FkZHJfdCBvbWFwX2dldF9kbWFfZHN0X3BvcyhpbnQgbGNoKQp7CglkbWFfYWRkcl90IG9mZnNldDsKCglpZiAoY3B1X2NsYXNzX2lzX29tYXAxKCkpCgkJb2Zmc2V0ID0gKGRtYV9hZGRyX3QpIChPTUFQMV9ETUFfQ0RTQV9MX1JFRyhsY2gpIHwKCQkJCSAgICAgICAoT01BUDFfRE1BX0NEU0FfVV9SRUcobGNoKSA8PCAxNikpOwoKCWlmIChjcHVfaXNfb21hcDI0eHgoKSkKCQlvZmZzZXQgPSBPTUFQMl9ETUFfQ0RTQV9SRUcobGNoKTsKCglyZXR1cm4gb2Zmc2V0Owp9CgovKgogKiBSZXR1cm5zIGN1cnJlbnQgc291cmNlIHRyYW5zZmVyIGNvdW50aW5nIGZvciB0aGUgZ2l2ZW4gRE1BIGNoYW5uZWwuCiAqIENhbiBiZSB1c2VkIHRvIG1vbml0b3IgdGhlIHByb2dyZXNzIG9mIGEgdHJhbnNmZXIgaW5zaWRlIGEgYmxvY2suCiAqIEl0IG11c3QgYmUgY2FsbGVkIHdpdGggZGlzYWJsZWQgaW50ZXJydXB0cy4KICovCmludCBvbWFwX2dldF9kbWFfc3JjX2FkZHJfY291bnRlcihpbnQgbGNoKQp7CglyZXR1cm4gKGRtYV9hZGRyX3QpIE9NQVBfRE1BX0NTQUNfUkVHKGxjaCk7Cn0KCmludCBvbWFwX2RtYV9ydW5uaW5nKHZvaWQpCnsKCWludCBsY2g7CgoJLyogQ2hlY2sgaWYgTENEIERNQSBpcyBydW5uaW5nICovCglpZiAoY3B1X2lzX29tYXAxNnh4KCkpCgkJaWYgKG9tYXBfcmVhZHcoT01BUDE2MTBfRE1BX0xDRF9DQ1IpICYgT01BUF9ETUFfQ0NSX0VOKQoJCQlyZXR1cm4gMTsKCglmb3IgKGxjaCA9IDA7IGxjaCA8IGRtYV9jaGFuX2NvdW50OyBsY2grKykKCQlpZiAoT01BUF9ETUFfQ0NSX1JFRyhsY2gpICYgT01BUF9ETUFfQ0NSX0VOKQoJCQlyZXR1cm4gMTsKCglyZXR1cm4gMDsKfQoKLyoKICogbGNoX3F1ZXVlIERNQSB3aWxsIHN0YXJ0IHJpZ2h0IGFmdGVyIGxjaF9oZWFkIG9uZSBpcyBmaW5pc2hlZC4KICogRm9yIHRoaXMgRE1BIGxpbmsgdG8gc3RhcnQsIHlvdSBzdGlsbCBuZWVkIHRvIHN0YXJ0IChzZWUgb21hcF9zdGFydF9kbWEpCiAqIHRoZSBmaXJzdCBvbmUuIFRoYXQgd2lsbCBmaXJlIHVwIHRoZSBlbnRpcmUgcXVldWUuCiAqLwp2b2lkIG9tYXBfZG1hX2xpbmtfbGNoIChpbnQgbGNoX2hlYWQsIGludCBsY2hfcXVldWUpCnsKCWlmIChvbWFwX2RtYV9pbl8xNTEwX21vZGUoKSkgewoJCXByaW50ayhLRVJOX0VSUiAiRE1BIGxpbmtpbmcgaXMgbm90IHN1cHBvcnRlZCBpbiAxNTEwIG1vZGVcbiIpOwoJCUJVRygpOwoJCXJldHVybjsKCX0KCglpZiAoKGRtYV9jaGFuW2xjaF9oZWFkXS5kZXZfaWQgPT0gLTEpIHx8CgkgICAgKGRtYV9jaGFuW2xjaF9xdWV1ZV0uZGV2X2lkID09IC0xKSkgewoJCXByaW50ayhLRVJOX0VSUiAib21hcF9kbWE6IHRyeWluZyB0byBsaW5rICIKCQkgICAgICAgIm5vbiByZXF1ZXN0ZWQgY2hhbm5lbHNcbiIpOwoJCWR1bXBfc3RhY2soKTsKCX0KCglkbWFfY2hhbltsY2hfaGVhZF0ubmV4dF9sY2ggPSBsY2hfcXVldWU7Cn0KCi8qCiAqIE9uY2UgdGhlIERNQSBxdWV1ZSBpcyBzdG9wcGVkLCB3ZSBjYW4gZGVzdHJveSBpdC4KICovCnZvaWQgb21hcF9kbWFfdW5saW5rX2xjaCAoaW50IGxjaF9oZWFkLCBpbnQgbGNoX3F1ZXVlKQp7CglpZiAob21hcF9kbWFfaW5fMTUxMF9tb2RlKCkpIHsKCQlwcmludGsoS0VSTl9FUlIgIkRNQSBsaW5raW5nIGlzIG5vdCBzdXBwb3J0ZWQgaW4gMTUxMCBtb2RlXG4iKTsKCQlCVUcoKTsKCQlyZXR1cm47Cgl9CgoJaWYgKGRtYV9jaGFuW2xjaF9oZWFkXS5uZXh0X2xjaCAhPSBsY2hfcXVldWUgfHwKCSAgICBkbWFfY2hhbltsY2hfaGVhZF0ubmV4dF9sY2ggPT0gLTEpIHsKCQlwcmludGsoS0VSTl9FUlIgIm9tYXBfZG1hOiB0cnlpbmcgdG8gdW5saW5rICIKCQkgICAgICAgIm5vbiBsaW5rZWQgY2hhbm5lbHNcbiIpOwoJCWR1bXBfc3RhY2soKTsKCX0KCgoJaWYgKChkbWFfY2hhbltsY2hfaGVhZF0uZmxhZ3MgJiBPTUFQX0RNQV9BQ1RJVkUpIHx8CgkgICAgKGRtYV9jaGFuW2xjaF9oZWFkXS5mbGFncyAmIE9NQVBfRE1BX0FDVElWRSkpIHsKCQlwcmludGsoS0VSTl9FUlIgIm9tYXBfZG1hOiBZb3UgbmVlZCB0byBzdG9wIHRoZSBETUEgY2hhbm5lbHMgIgoJCSAgICAgICAiYmVmb3JlIHVubGlua2luZ1xuIik7CgkJZHVtcF9zdGFjaygpOwoJfQoKCWRtYV9jaGFuW2xjaF9oZWFkXS5uZXh0X2xjaCA9IC0xOwp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKI2lmZGVmIENPTkZJR19BUkNIX09NQVAxCgpzdGF0aWMgaW50IG9tYXAxX2RtYV9oYW5kbGVfY2goaW50IGNoKQp7Cgl1MTYgY3NyOwoKCWlmIChlbmFibGVfMTUxMF9tb2RlICYmIGNoID49IDYpIHsKCQljc3IgPSBkbWFfY2hhbltjaF0uc2F2ZWRfY3NyOwoJCWRtYV9jaGFuW2NoXS5zYXZlZF9jc3IgPSAwOwoJfSBlbHNlCgkJY3NyID0gT01BUF9ETUFfQ1NSX1JFRyhjaCk7CglpZiAoZW5hYmxlXzE1MTBfbW9kZSAmJiBjaCA8PSAyICYmIChjc3IgPj4gNykgIT0gMCkgewoJCWRtYV9jaGFuW2NoICsgNl0uc2F2ZWRfY3NyID0gY3NyID4+IDc7CgkJY3NyICY9IDB4N2Y7Cgl9CglpZiAoKGNzciAmIDB4M2YpID09IDApCgkJcmV0dXJuIDA7CglpZiAodW5saWtlbHkoZG1hX2NoYW5bY2hdLmRldl9pZCA9PSAtMSkpIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJTcHVyaW91cyBpbnRlcnJ1cHQgZnJvbSBETUEgY2hhbm5lbCAiCgkJICAgICAgICIlZCAoQ1NSICUwNHgpXG4iLCBjaCwgY3NyKTsKCQlyZXR1cm4gMDsKCX0KCWlmICh1bmxpa2VseShjc3IgJiBPTUFQMV9ETUFfVE9VVF9JUlEpKQoJCXByaW50ayhLRVJOX1dBUk5JTkcgIkRNQSB0aW1lb3V0IHdpdGggZGV2aWNlICVkXG4iLAoJCSAgICAgICBkbWFfY2hhbltjaF0uZGV2X2lkKTsKCWlmICh1bmxpa2VseShjc3IgJiBPTUFQX0RNQV9EUk9QX0lSUSkpCgkJcHJpbnRrKEtFUk5fV0FSTklORyAiRE1BIHN5bmNocm9uaXphdGlvbiBldmVudCBkcm9wIG9jY3VycmVkICIKCQkgICAgICAgIndpdGggZGV2aWNlICVkXG4iLCBkbWFfY2hhbltjaF0uZGV2X2lkKTsKCWlmIChsaWtlbHkoY3NyICYgT01BUF9ETUFfQkxPQ0tfSVJRKSkKCQlkbWFfY2hhbltjaF0uZmxhZ3MgJj0gfk9NQVBfRE1BX0FDVElWRTsKCWlmIChsaWtlbHkoZG1hX2NoYW5bY2hdLmNhbGxiYWNrICE9IE5VTEwpKQoJCWRtYV9jaGFuW2NoXS5jYWxsYmFjayhjaCwgY3NyLCBkbWFfY2hhbltjaF0uZGF0YSk7CglyZXR1cm4gMTsKfQoKc3RhdGljIGlycXJldHVybl90IG9tYXAxX2RtYV9pcnFfaGFuZGxlcihpbnQgaXJxLCB2b2lkICpkZXZfaWQpCnsKCWludCBjaCA9ICgoaW50KSBkZXZfaWQpIC0gMTsKCWludCBoYW5kbGVkID0gMDsKCglmb3IgKDs7KSB7CgkJaW50IGhhbmRsZWRfbm93ID0gMDsKCgkJaGFuZGxlZF9ub3cgKz0gb21hcDFfZG1hX2hhbmRsZV9jaChjaCk7CgkJaWYgKGVuYWJsZV8xNTEwX21vZGUgJiYgZG1hX2NoYW5bY2ggKyA2XS5zYXZlZF9jc3IpCgkJCWhhbmRsZWRfbm93ICs9IG9tYXAxX2RtYV9oYW5kbGVfY2goY2ggKyA2KTsKCQlpZiAoIWhhbmRsZWRfbm93KQoJCQlicmVhazsKCQloYW5kbGVkICs9IGhhbmRsZWRfbm93OwoJfQoKCXJldHVybiBoYW5kbGVkID8gSVJRX0hBTkRMRUQgOiBJUlFfTk9ORTsKfQoKI2Vsc2UKI2RlZmluZSBvbWFwMV9kbWFfaXJxX2hhbmRsZXIJTlVMTAojZW5kaWYKCiNpZmRlZiBDT05GSUdfQVJDSF9PTUFQMgoKc3RhdGljIGludCBvbWFwMl9kbWFfaGFuZGxlX2NoKGludCBjaCkKewoJdTMyIHN0YXR1cyA9IE9NQVBfRE1BX0NTUl9SRUcoY2gpOwoKCWlmICghc3RhdHVzKSB7CgkJaWYgKHByaW50a19yYXRlbGltaXQoKSkKCQkJcHJpbnRrKEtFUk5fV0FSTklORyAiU3B1cmlvdXMgRE1BIElSUSBmb3IgbGNoICVkXG4iLCBjaCk7CgkJcmV0dXJuIDA7Cgl9CglpZiAodW5saWtlbHkoZG1hX2NoYW5bY2hdLmRldl9pZCA9PSAtMSkpIHsKCQlpZiAocHJpbnRrX3JhdGVsaW1pdCgpKQoJCQlwcmludGsoS0VSTl9XQVJOSU5HICJJUlEgJTA0eCBmb3Igbm9uLWFsbG9jYXRlZCBETUEiCgkJCQkJImNoYW5uZWwgJWRcbiIsIHN0YXR1cywgY2gpOwoJCXJldHVybiAwOwoJfQoJaWYgKHVubGlrZWx5KHN0YXR1cyAmIE9NQVBfRE1BX0RST1BfSVJRKSkKCQlwcmludGsoS0VSTl9JTkZPCgkJICAgICAgICJETUEgc3luY2hyb25pemF0aW9uIGV2ZW50IGRyb3Agb2NjdXJyZWQgd2l0aCBkZXZpY2UgIgoJCSAgICAgICAiJWRcbiIsIGRtYV9jaGFuW2NoXS5kZXZfaWQpOwoJaWYgKHVubGlrZWx5KHN0YXR1cyAmIE9NQVAyX0RNQV9UUkFOU19FUlJfSVJRKSkKCQlwcmludGsoS0VSTl9JTkZPICJETUEgdHJhbnNhY3Rpb24gZXJyb3Igd2l0aCBkZXZpY2UgJWRcbiIsCgkJICAgICAgIGRtYV9jaGFuW2NoXS5kZXZfaWQpOwoJaWYgKHVubGlrZWx5KHN0YXR1cyAmIE9NQVAyX0RNQV9TRUNVUkVfRVJSX0lSUSkpCgkJcHJpbnRrKEtFUk5fSU5GTyAiRE1BIHNlY3VyZSBlcnJvciB3aXRoIGRldmljZSAlZFxuIiwKCQkgICAgICAgZG1hX2NoYW5bY2hdLmRldl9pZCk7CglpZiAodW5saWtlbHkoc3RhdHVzICYgT01BUDJfRE1BX01JU0FMSUdORURfRVJSX0lSUSkpCgkJcHJpbnRrKEtFUk5fSU5GTyAiRE1BIG1pc2FsaWduZWQgZXJyb3Igd2l0aCBkZXZpY2UgJWRcbiIsCgkJICAgICAgIGRtYV9jaGFuW2NoXS5kZXZfaWQpOwoKCU9NQVBfRE1BX0NTUl9SRUcoY2gpID0gT01BUDJfRE1BX0NTUl9DTEVBUl9NQVNLOwoJb21hcF93cml0ZWwoMSA8PCBjaCwgT01BUF9ETUE0X0lSUVNUQVRVU19MMCk7CgoJaWYgKGxpa2VseShkbWFfY2hhbltjaF0uY2FsbGJhY2sgIT0gTlVMTCkpCgkJZG1hX2NoYW5bY2hdLmNhbGxiYWNrKGNoLCBzdGF0dXMsIGRtYV9jaGFuW2NoXS5kYXRhKTsKCglyZXR1cm4gMDsKfQoKLyogU1RBVFVTIHJlZ2lzdGVyIGNvdW50IGlzIGZyb20gMS0zMiB3aGlsZSBvdXIgaXMgMC0zMSAqLwpzdGF0aWMgaXJxcmV0dXJuX3Qgb21hcDJfZG1hX2lycV9oYW5kbGVyKGludCBpcnEsIHZvaWQgKmRldl9pZCkKewoJdTMyIHZhbDsKCWludCBpOwoKCXZhbCA9IG9tYXBfcmVhZGwoT01BUF9ETUE0X0lSUVNUQVRVU19MMCk7CglpZiAodmFsID09IDApIHsKCQlpZiAocHJpbnRrX3JhdGVsaW1pdCgpKQoJCQlwcmludGsoS0VSTl9XQVJOSU5HICJTcHVyaW91cyBETUEgSVJRXG4iKTsKCQlyZXR1cm4gSVJRX0hBTkRMRUQ7Cgl9Cglmb3IgKGkgPSAwOyBpIDwgT01BUF9MT0dJQ0FMX0RNQV9DSF9DT1VOVCAmJiB2YWwgIT0gMDsgaSsrKSB7CgkJaWYgKHZhbCAmIDEpCgkJCW9tYXAyX2RtYV9oYW5kbGVfY2goaSk7CgkJdmFsID4+PSAxOwoJfQoKCXJldHVybiBJUlFfSEFORExFRDsKfQoKc3RhdGljIHN0cnVjdCBpcnFhY3Rpb24gb21hcDI0eHhfZG1hX2lycSA9IHsKCS5uYW1lID0gIkRNQSIsCgkuaGFuZGxlciA9IG9tYXAyX2RtYV9pcnFfaGFuZGxlciwKCS5mbGFncyA9IElSUUZfRElTQUJMRUQKfTsKCiNlbHNlCnN0YXRpYyBzdHJ1Y3QgaXJxYWN0aW9uIG9tYXAyNHh4X2RtYV9pcnE7CiNlbmRpZgoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCnN0YXRpYyBzdHJ1Y3QgbGNkX2RtYV9pbmZvIHsKCXNwaW5sb2NrX3QgbG9jazsKCWludCByZXNlcnZlZDsKCXZvaWQgKCogY2FsbGJhY2spKHUxNiBzdGF0dXMsIHZvaWQgKmRhdGEpOwoJdm9pZCAqY2JfZGF0YTsKCglpbnQgYWN0aXZlOwoJdW5zaWduZWQgbG9uZyBhZGRyLCBzaXplOwoJaW50IHJvdGF0ZSwgZGF0YV90eXBlLCB4cmVzLCB5cmVzOwoJaW50IHZ4cmVzOwoJaW50IG1pcnJvcjsKCWludCB4c2NhbGUsIHlzY2FsZTsKCWludCBleHRfY3RybDsKCWludCBzcmNfcG9ydDsKCWludCBzaW5nbGVfdHJhbnNmZXI7Cn0gbGNkX2RtYTsKCnZvaWQgb21hcF9zZXRfbGNkX2RtYV9iMSh1bnNpZ25lZCBsb25nIGFkZHIsIHUxNiBmYl94cmVzLCB1MTYgZmJfeXJlcywKCQkJIGludCBkYXRhX3R5cGUpCnsKCWxjZF9kbWEuYWRkciA9IGFkZHI7CglsY2RfZG1hLmRhdGFfdHlwZSA9IGRhdGFfdHlwZTsKCWxjZF9kbWEueHJlcyA9IGZiX3hyZXM7CglsY2RfZG1hLnlyZXMgPSBmYl95cmVzOwp9Cgp2b2lkIG9tYXBfc2V0X2xjZF9kbWFfc3JjX3BvcnQoaW50IHBvcnQpCnsKCWxjZF9kbWEuc3JjX3BvcnQgPSBwb3J0Owp9Cgp2b2lkIG9tYXBfc2V0X2xjZF9kbWFfZXh0X2NvbnRyb2xsZXIoaW50IGV4dGVybmFsKQp7CglsY2RfZG1hLmV4dF9jdHJsID0gZXh0ZXJuYWw7Cn0KCnZvaWQgb21hcF9zZXRfbGNkX2RtYV9zaW5nbGVfdHJhbnNmZXIoaW50IHNpbmdsZSkKewoJbGNkX2RtYS5zaW5nbGVfdHJhbnNmZXIgPSBzaW5nbGU7Cn0KCgp2b2lkIG9tYXBfc2V0X2xjZF9kbWFfYjFfcm90YXRpb24oaW50IHJvdGF0ZSkKewoJaWYgKG9tYXBfZG1hX2luXzE1MTBfbW9kZSgpKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJETUEgcm90YXRpb24gaXMgbm90IHN1cHBvcnRlZCBpbiAxNTEwIG1vZGVcbiIpOwoJCUJVRygpOwoJCXJldHVybjsKCX0KCWxjZF9kbWEucm90YXRlID0gcm90YXRlOwp9Cgp2b2lkIG9tYXBfc2V0X2xjZF9kbWFfYjFfbWlycm9yKGludCBtaXJyb3IpCnsKCWlmIChvbWFwX2RtYV9pbl8xNTEwX21vZGUoKSkgewoJCXByaW50ayhLRVJOX0VSUiAiRE1BIG1pcnJvciBpcyBub3Qgc3VwcG9ydGVkIGluIDE1MTAgbW9kZVxuIik7CgkJQlVHKCk7Cgl9CglsY2RfZG1hLm1pcnJvciA9IG1pcnJvcjsKfQoKdm9pZCBvbWFwX3NldF9sY2RfZG1hX2IxX3Z4cmVzKHVuc2lnbmVkIGxvbmcgdnhyZXMpCnsKCWlmIChvbWFwX2RtYV9pbl8xNTEwX21vZGUoKSkgewoJCXByaW50ayhLRVJOX0VSUiAiRE1BIHZpcnR1YWwgcmVzdWxvdGlvbiBpcyBub3Qgc3VwcG9ydGVkICIKCQkJCSJpbiAxNTEwIG1vZGVcbiIpOwoJCUJVRygpOwoJfQoJbGNkX2RtYS52eHJlcyA9IHZ4cmVzOwp9Cgp2b2lkIG9tYXBfc2V0X2xjZF9kbWFfYjFfc2NhbGUodW5zaWduZWQgaW50IHhzY2FsZSwgdW5zaWduZWQgaW50IHlzY2FsZSkKewoJaWYgKG9tYXBfZG1hX2luXzE1MTBfbW9kZSgpKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJETUEgc2NhbGUgaXMgbm90IHN1cHBvcnRlZCBpbiAxNTEwIG1vZGVcbiIpOwoJCUJVRygpOwoJfQoJbGNkX2RtYS54c2NhbGUgPSB4c2NhbGU7CglsY2RfZG1hLnlzY2FsZSA9IHlzY2FsZTsKfQoKc3RhdGljIHZvaWQgc2V0X2IxX3JlZ3Modm9pZCkKewoJdW5zaWduZWQgbG9uZyB0b3AsIGJvdHRvbTsKCWludCBlczsKCXUxNiB3OwoJdW5zaWduZWQgbG9uZyBlbiwgZm47Cglsb25nIGVpLCBmaTsKCXVuc2lnbmVkIGxvbmcgdnhyZXM7Cgl1bnNpZ25lZCBpbnQgeHNjYWxlLCB5c2NhbGU7CgoJc3dpdGNoIChsY2RfZG1hLmRhdGFfdHlwZSkgewoJY2FzZSBPTUFQX0RNQV9EQVRBX1RZUEVfUzg6CgkJZXMgPSAxOwoJCWJyZWFrOwoJY2FzZSBPTUFQX0RNQV9EQVRBX1RZUEVfUzE2OgoJCWVzID0gMjsKCQlicmVhazsKCWNhc2UgT01BUF9ETUFfREFUQV9UWVBFX1MzMjoKCQllcyA9IDQ7CgkJYnJlYWs7CglkZWZhdWx0OgoJCUJVRygpOwoJCXJldHVybjsKCX0KCgl2eHJlcyA9IGxjZF9kbWEudnhyZXMgPyBsY2RfZG1hLnZ4cmVzIDogbGNkX2RtYS54cmVzOwoJeHNjYWxlID0gbGNkX2RtYS54c2NhbGUgPyBsY2RfZG1hLnhzY2FsZSA6IDE7Cgl5c2NhbGUgPSBsY2RfZG1hLnlzY2FsZSA/IGxjZF9kbWEueXNjYWxlIDogMTsKCUJVR19PTih2eHJlcyA8IGxjZF9kbWEueHJlcyk7CiNkZWZpbmUgUElYQUREUih4LHkpIChsY2RfZG1hLmFkZHIgKyAoKHkpICogdnhyZXMgKiB5c2NhbGUgKyAoeCkgKiB4c2NhbGUpICogZXMpCiNkZWZpbmUgUElYU1RFUChzeCwgc3ksIGR4LCBkeSkgKFBJWEFERFIoZHgsIGR5KSAtIFBJWEFERFIoc3gsIHN5KSAtIGVzICsgMSkKCXN3aXRjaCAobGNkX2RtYS5yb3RhdGUpIHsKCWNhc2UgMDoKCQlpZiAoIWxjZF9kbWEubWlycm9yKSB7CgkJCXRvcCA9IFBJWEFERFIoMCwgMCk7CgkJCWJvdHRvbSA9IFBJWEFERFIobGNkX2RtYS54cmVzIC0gMSwgbGNkX2RtYS55cmVzIC0gMSk7CgkJCS8qIDE1MTAgRE1BIHJlcXVpcmVzIHRoZSBib3R0b20gYWRkcmVzcyB0byBiZSAyIG1vcmUKCQkJICogdGhhbiB0aGUgYWN0dWFsIGxhc3QgbWVtb3J5IGFjY2VzcyBsb2NhdGlvbi4gKi8KCQkJaWYgKG9tYXBfZG1hX2luXzE1MTBfbW9kZSgpICYmCgkJCSAgICBsY2RfZG1hLmRhdGFfdHlwZSA9PSBPTUFQX0RNQV9EQVRBX1RZUEVfUzMyKQoJCQkJYm90dG9tICs9IDI7CgkJCWVpID0gUElYU1RFUCgwLCAwLCAxLCAwKTsKCQkJZmkgPSBQSVhTVEVQKGxjZF9kbWEueHJlcyAtIDEsIDAsIDAsIDEpOwoJCX0gZWxzZSB7CgkJCXRvcCA9IFBJWEFERFIobGNkX2RtYS54cmVzIC0gMSwgMCk7CgkJCWJvdHRvbSA9IFBJWEFERFIoMCwgbGNkX2RtYS55cmVzIC0gMSk7CgkJCWVpID0gUElYU1RFUCgxLCAwLCAwLCAwKTsKCQkJZmkgPSBQSVhTVEVQKDAsIDAsIGxjZF9kbWEueHJlcyAtIDEsIDEpOwoJCX0KCQllbiA9IGxjZF9kbWEueHJlczsKCQlmbiA9IGxjZF9kbWEueXJlczsKCQlicmVhazsKCWNhc2UgOTA6CgkJaWYgKCFsY2RfZG1hLm1pcnJvcikgewoJCQl0b3AgPSBQSVhBRERSKDAsIGxjZF9kbWEueXJlcyAtIDEpOwoJCQlib3R0b20gPSBQSVhBRERSKGxjZF9kbWEueHJlcyAtIDEsIDApOwoJCQllaSA9IFBJWFNURVAoMCwgMSwgMCwgMCk7CgkJCWZpID0gUElYU1RFUCgwLCAwLCAxLCBsY2RfZG1hLnlyZXMgLSAxKTsKCQl9IGVsc2UgewoJCQl0b3AgPSBQSVhBRERSKGxjZF9kbWEueHJlcyAtIDEsIGxjZF9kbWEueXJlcyAtIDEpOwoJCQlib3R0b20gPSBQSVhBRERSKDAsIDApOwoJCQllaSA9IFBJWFNURVAoMCwgMSwgMCwgMCk7CgkJCWZpID0gUElYU1RFUCgxLCAwLCAwLCBsY2RfZG1hLnlyZXMgLSAxKTsKCQl9CgkJZW4gPSBsY2RfZG1hLnlyZXM7CgkJZm4gPSBsY2RfZG1hLnhyZXM7CgkJYnJlYWs7CgljYXNlIDE4MDoKCQlpZiAoIWxjZF9kbWEubWlycm9yKSB7CgkJCXRvcCA9IFBJWEFERFIobGNkX2RtYS54cmVzIC0gMSwgbGNkX2RtYS55cmVzIC0gMSk7CgkJCWJvdHRvbSA9IFBJWEFERFIoMCwgMCk7CgkJCWVpID0gUElYU1RFUCgxLCAwLCAwLCAwKTsKCQkJZmkgPSBQSVhTVEVQKDAsIDEsIGxjZF9kbWEueHJlcyAtIDEsIDApOwoJCX0gZWxzZSB7CgkJCXRvcCA9IFBJWEFERFIoMCwgbGNkX2RtYS55cmVzIC0gMSk7CgkJCWJvdHRvbSA9IFBJWEFERFIobGNkX2RtYS54cmVzIC0gMSwgMCk7CgkJCWVpID0gUElYU1RFUCgwLCAwLCAxLCAwKTsKCQkJZmkgPSBQSVhTVEVQKGxjZF9kbWEueHJlcyAtIDEsIDEsIDAsIDApOwoJCX0KCQllbiA9IGxjZF9kbWEueHJlczsKCQlmbiA9IGxjZF9kbWEueXJlczsKCQlicmVhazsKCWNhc2UgMjcwOgoJCWlmICghbGNkX2RtYS5taXJyb3IpIHsKCQkJdG9wID0gUElYQUREUihsY2RfZG1hLnhyZXMgLSAxLCAwKTsKCQkJYm90dG9tID0gUElYQUREUigwLCBsY2RfZG1hLnlyZXMgLSAxKTsKCQkJZWkgPSBQSVhTVEVQKDAsIDAsIDAsIDEpOwoJCQlmaSA9IFBJWFNURVAoMSwgbGNkX2RtYS55cmVzIC0gMSwgMCwgMCk7CgkJfSBlbHNlIHsKCQkJdG9wID0gUElYQUREUigwLCAwKTsKCQkJYm90dG9tID0gUElYQUREUihsY2RfZG1hLnhyZXMgLSAxLCBsY2RfZG1hLnlyZXMgLSAxKTsKCQkJZWkgPSBQSVhTVEVQKDAsIDAsIDAsIDEpOwoJCQlmaSA9IFBJWFNURVAoMCwgbGNkX2RtYS55cmVzIC0gMSwgMSwgMCk7CgkJfQoJCWVuID0gbGNkX2RtYS55cmVzOwoJCWZuID0gbGNkX2RtYS54cmVzOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlCVUcoKTsKCQlyZXR1cm47CS8qIFN1cHJlc3Mgd2FybmluZyBhYm91dCB1bmluaXRpYWxpemVkIHZhcnMgKi8KCX0KCglpZiAob21hcF9kbWFfaW5fMTUxMF9tb2RlKCkpIHsKCQlvbWFwX3dyaXRldyh0b3AgPj4gMTYsIE9NQVAxNTEwX0RNQV9MQ0RfVE9QX0YxX1UpOwoJCW9tYXBfd3JpdGV3KHRvcCwgT01BUDE1MTBfRE1BX0xDRF9UT1BfRjFfTCk7CgkJb21hcF93cml0ZXcoYm90dG9tID4+IDE2LCBPTUFQMTUxMF9ETUFfTENEX0JPVF9GMV9VKTsKCQlvbWFwX3dyaXRldyhib3R0b20sIE9NQVAxNTEwX0RNQV9MQ0RfQk9UX0YxX0wpOwoKCQlyZXR1cm47Cgl9CgoJLyogMTYxMCByZWdzICovCglvbWFwX3dyaXRldyh0b3AgPj4gMTYsIE9NQVAxNjEwX0RNQV9MQ0RfVE9QX0IxX1UpOwoJb21hcF93cml0ZXcodG9wLCBPTUFQMTYxMF9ETUFfTENEX1RPUF9CMV9MKTsKCW9tYXBfd3JpdGV3KGJvdHRvbSA+PiAxNiwgT01BUDE2MTBfRE1BX0xDRF9CT1RfQjFfVSk7CglvbWFwX3dyaXRldyhib3R0b20sIE9NQVAxNjEwX0RNQV9MQ0RfQk9UX0IxX0wpOwoKCW9tYXBfd3JpdGV3KGVuLCBPTUFQMTYxMF9ETUFfTENEX1NSQ19FTl9CMSk7CglvbWFwX3dyaXRldyhmbiwgT01BUDE2MTBfRE1BX0xDRF9TUkNfRk5fQjEpOwoKCXcgPSBvbWFwX3JlYWR3KE9NQVAxNjEwX0RNQV9MQ0RfQ1NEUCk7Cgl3ICY9IH4weDAzOwoJdyB8PSBsY2RfZG1hLmRhdGFfdHlwZTsKCW9tYXBfd3JpdGV3KHcsIE9NQVAxNjEwX0RNQV9MQ0RfQ1NEUCk7CgoJdyA9IG9tYXBfcmVhZHcoT01BUDE2MTBfRE1BX0xDRF9DVFJMKTsKCS8qIEFsd2F5cyBzZXQgdGhlIHNvdXJjZSBwb3J0IGFzIFNEUkFNIGZvciBub3cqLwoJdyAmPSB+KDB4MDMgPDwgNik7CglpZiAobGNkX2RtYS5jYWxsYmFjayAhPSBOVUxMKQoJCXcgfD0gMSA8PCAxOwkJLyogQmxvY2sgaW50ZXJydXB0IGVuYWJsZSAqLwoJZWxzZQoJCXcgJj0gfigxIDw8IDEpOwoJb21hcF93cml0ZXcodywgT01BUDE2MTBfRE1BX0xDRF9DVFJMKTsKCglpZiAoIShsY2RfZG1hLnJvdGF0ZSB8fCBsY2RfZG1hLm1pcnJvciB8fAoJICAgICAgbGNkX2RtYS52eHJlcyB8fCBsY2RfZG1hLnhzY2FsZSB8fCBsY2RfZG1hLnlzY2FsZSkpCgkJcmV0dXJuOwoKCXcgPSBvbWFwX3JlYWR3KE9NQVAxNjEwX0RNQV9MQ0RfQ0NSKTsKCS8qIFNldCB0aGUgZG91YmxlLWluZGV4ZWQgYWRkcmVzc2luZyBtb2RlICovCgl3IHw9ICgweDAzIDw8IDEyKTsKCW9tYXBfd3JpdGV3KHcsIE9NQVAxNjEwX0RNQV9MQ0RfQ0NSKTsKCglvbWFwX3dyaXRldyhlaSwgT01BUDE2MTBfRE1BX0xDRF9TUkNfRUlfQjEpOwoJb21hcF93cml0ZXcoZmkgPj4gMTYsIE9NQVAxNjEwX0RNQV9MQ0RfU1JDX0ZJX0IxX1UpOwoJb21hcF93cml0ZXcoZmksIE9NQVAxNjEwX0RNQV9MQ0RfU1JDX0ZJX0IxX0wpOwp9CgpzdGF0aWMgaXJxcmV0dXJuX3QgbGNkX2RtYV9pcnFfaGFuZGxlcihpbnQgaXJxLCB2b2lkICpkZXZfaWQpCnsKCXUxNiB3OwoKCXcgPSBvbWFwX3JlYWR3KE9NQVAxNjEwX0RNQV9MQ0RfQ1RSTCk7CglpZiAodW5saWtlbHkoISh3ICYgKDEgPDwgMykpKSkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgIlNwdXJpb3VzIExDRCBETUEgSVJRXG4iKTsKCQlyZXR1cm4gSVJRX05PTkU7Cgl9CgkvKiBBY2sgdGhlIElSUSAqLwoJdyB8PSAoMSA8PCAzKTsKCW9tYXBfd3JpdGV3KHcsIE9NQVAxNjEwX0RNQV9MQ0RfQ1RSTCk7CglsY2RfZG1hLmFjdGl2ZSA9IDA7CglpZiAobGNkX2RtYS5jYWxsYmFjayAhPSBOVUxMKQoJCWxjZF9kbWEuY2FsbGJhY2sodywgbGNkX2RtYS5jYl9kYXRhKTsKCglyZXR1cm4gSVJRX0hBTkRMRUQ7Cn0KCmludCBvbWFwX3JlcXVlc3RfbGNkX2RtYSh2b2lkICgqIGNhbGxiYWNrKSh1MTYgc3RhdHVzLCB2b2lkICpkYXRhKSwKCQkJIHZvaWQgKmRhdGEpCnsKCXNwaW5fbG9ja19pcnEoJmxjZF9kbWEubG9jayk7CglpZiAobGNkX2RtYS5yZXNlcnZlZCkgewoJCXNwaW5fdW5sb2NrX2lycSgmbGNkX2RtYS5sb2NrKTsKCQlwcmludGsoS0VSTl9FUlIgIkxDRCBETUEgY2hhbm5lbCBhbHJlYWR5IHJlc2VydmVkXG4iKTsKCQlCVUcoKTsKCQlyZXR1cm4gLUVCVVNZOwoJfQoJbGNkX2RtYS5yZXNlcnZlZCA9IDE7CglzcGluX3VubG9ja19pcnEoJmxjZF9kbWEubG9jayk7CglsY2RfZG1hLmNhbGxiYWNrID0gY2FsbGJhY2s7CglsY2RfZG1hLmNiX2RhdGEgPSBkYXRhOwoJbGNkX2RtYS5hY3RpdmUgPSAwOwoJbGNkX2RtYS5zaW5nbGVfdHJhbnNmZXIgPSAwOwoJbGNkX2RtYS5yb3RhdGUgPSAwOwoJbGNkX2RtYS52eHJlcyA9IDA7CglsY2RfZG1hLm1pcnJvciA9IDA7CglsY2RfZG1hLnhzY2FsZSA9IDA7CglsY2RfZG1hLnlzY2FsZSA9IDA7CglsY2RfZG1hLmV4dF9jdHJsID0gMDsKCWxjZF9kbWEuc3JjX3BvcnQgPSAwOwoKCXJldHVybiAwOwp9Cgp2b2lkIG9tYXBfZnJlZV9sY2RfZG1hKHZvaWQpCnsKCXNwaW5fbG9jaygmbGNkX2RtYS5sb2NrKTsKCWlmICghbGNkX2RtYS5yZXNlcnZlZCkgewoJCXNwaW5fdW5sb2NrKCZsY2RfZG1hLmxvY2spOwoJCXByaW50ayhLRVJOX0VSUiAiTENEIERNQSBpcyBub3QgcmVzZXJ2ZWRcbiIpOwoJCUJVRygpOwoJCXJldHVybjsKCX0KCWlmICghZW5hYmxlXzE1MTBfbW9kZSkKCQlvbWFwX3dyaXRldyhvbWFwX3JlYWR3KE9NQVAxNjEwX0RNQV9MQ0RfQ0NSKSAmIH4xLAoJCQkgICAgT01BUDE2MTBfRE1BX0xDRF9DQ1IpOwoJbGNkX2RtYS5yZXNlcnZlZCA9IDA7CglzcGluX3VubG9jaygmbGNkX2RtYS5sb2NrKTsKfQoKdm9pZCBvbWFwX2VuYWJsZV9sY2RfZG1hKHZvaWQpCnsKCXUxNiB3OwoKCS8qIFNldCB0aGUgRW5hYmxlIGJpdCBvbmx5IGlmIGFuIGV4dGVybmFsIGNvbnRyb2xsZXIgaXMKCSAqIGNvbm5lY3RlZC4gT3RoZXJ3aXNlIHRoZSBPTUFQIGludGVybmFsIGNvbnRyb2xsZXIgd2lsbAoJICogc3RhcnQgdGhlIHRyYW5zZmVyIHdoZW4gaXQgZ2V0cyBlbmFibGVkLgoJICovCglpZiAoZW5hYmxlXzE1MTBfbW9kZSB8fCAhbGNkX2RtYS5leHRfY3RybCkKCQlyZXR1cm47CgoJdyA9IG9tYXBfcmVhZHcoT01BUDE2MTBfRE1BX0xDRF9DVFJMKTsKCXcgfD0gMSA8PCA4OwoJb21hcF93cml0ZXcodywgT01BUDE2MTBfRE1BX0xDRF9DVFJMKTsKCglsY2RfZG1hLmFjdGl2ZSA9IDE7CgoJdyA9IG9tYXBfcmVhZHcoT01BUDE2MTBfRE1BX0xDRF9DQ1IpOwoJdyB8PSAxIDw8IDc7CglvbWFwX3dyaXRldyh3LCBPTUFQMTYxMF9ETUFfTENEX0NDUik7Cn0KCnZvaWQgb21hcF9zZXR1cF9sY2RfZG1hKHZvaWQpCnsKCUJVR19PTihsY2RfZG1hLmFjdGl2ZSk7CglpZiAoIWVuYWJsZV8xNTEwX21vZGUpIHsKCQkvKiBTZXQgc29tZSByZWFzb25hYmxlIGRlZmF1bHRzICovCgkJb21hcF93cml0ZXcoMHg1NDQwLCBPTUFQMTYxMF9ETUFfTENEX0NDUik7CgkJb21hcF93cml0ZXcoMHg5MTAyLCBPTUFQMTYxMF9ETUFfTENEX0NTRFApOwoJCW9tYXBfd3JpdGV3KDB4MDAwNCwgT01BUDE2MTBfRE1BX0xDRF9MQ0hfQ1RSTCk7Cgl9CglzZXRfYjFfcmVncygpOwoJaWYgKCFlbmFibGVfMTUxMF9tb2RlKSB7CgkJdTE2IHc7CgoJCXcgPSBvbWFwX3JlYWR3KE9NQVAxNjEwX0RNQV9MQ0RfQ0NSKTsKCQkvKiBJZiBETUEgd2FzIGFscmVhZHkgYWN0aXZlIHNldCB0aGUgZW5kX3Byb2cgYml0IHRvIGhhdmUKCQkgKiB0aGUgcHJvZ3JhbW1lZCByZWdpc3RlciBzZXQgbG9hZGVkIGludG8gdGhlIGFjdGl2ZQoJCSAqIHJlZ2lzdGVyIHNldC4KCQkgKi8KCQl3IHw9IDEgPDwgMTE7CQkvKiBFbmRfcHJvZyAqLwoJCWlmICghbGNkX2RtYS5zaW5nbGVfdHJhbnNmZXIpCgkgICAgICAgIAl3IHw9ICgzIDw8IDgpOwkvKiBBdXRvX2luaXQsIHJlcGVhdCAqLwoJCW9tYXBfd3JpdGV3KHcsIE9NQVAxNjEwX0RNQV9MQ0RfQ0NSKTsKCX0KfQoKdm9pZCBvbWFwX3N0b3BfbGNkX2RtYSh2b2lkKQp7Cgl1MTYgdzsKCglsY2RfZG1hLmFjdGl2ZSA9IDA7CglpZiAoZW5hYmxlXzE1MTBfbW9kZSB8fCAhbGNkX2RtYS5leHRfY3RybCkKCQlyZXR1cm47CgoJdyA9IG9tYXBfcmVhZHcoT01BUDE2MTBfRE1BX0xDRF9DQ1IpOwoJdyAmPSB+KDEgPDwgNyk7CglvbWFwX3dyaXRldyh3LCBPTUFQMTYxMF9ETUFfTENEX0NDUik7CgoJdyA9IG9tYXBfcmVhZHcoT01BUDE2MTBfRE1BX0xDRF9DVFJMKTsKCXcgJj0gfigxIDw8IDgpOwoJb21hcF93cml0ZXcodywgT01BUDE2MTBfRE1BX0xDRF9DVFJMKTsKfQoKaW50IG9tYXBfbGNkX2RtYV9leHRfcnVubmluZyh2b2lkKQp7CglyZXR1cm4gbGNkX2RtYS5leHRfY3RybCAmJiBsY2RfZG1hLmFjdGl2ZTsKfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCnN0YXRpYyBpbnQgX19pbml0IG9tYXBfaW5pdF9kbWEodm9pZCkKewoJaW50IGNoLCByOwoKCWlmIChjcHVfaXNfb21hcDE1eHgoKSkgewoJCXByaW50ayhLRVJOX0lORk8gIkRNQSBzdXBwb3J0IGZvciBPTUFQMTV4eCBpbml0aWFsaXplZFxuIik7CgkJZG1hX2NoYW5fY291bnQgPSA5OwoJCWVuYWJsZV8xNTEwX21vZGUgPSAxOwoJfSBlbHNlIGlmIChjcHVfaXNfb21hcDE2eHgoKSB8fCBjcHVfaXNfb21hcDczMCgpKSB7CgkJcHJpbnRrKEtFUk5fSU5GTyAiT01BUCBETUEgaGFyZHdhcmUgdmVyc2lvbiAlZFxuIiwKCQkgICAgICAgb21hcF9yZWFkdyhPTUFQX0RNQV9IV19JRCkpOwoJCXByaW50ayhLRVJOX0lORk8gIkRNQSBjYXBhYmlsaXRpZXM6ICUwOHg6JTA4eDolMDR4OiUwNHg6JTA0eFxuIiwKCQkgICAgICAgKG9tYXBfcmVhZHcoT01BUF9ETUFfQ0FQU18wX1UpIDw8IDE2KSB8CgkJICAgICAgIG9tYXBfcmVhZHcoT01BUF9ETUFfQ0FQU18wX0wpLAoJCSAgICAgICAob21hcF9yZWFkdyhPTUFQX0RNQV9DQVBTXzFfVSkgPDwgMTYpIHwKCQkgICAgICAgb21hcF9yZWFkdyhPTUFQX0RNQV9DQVBTXzFfTCksCgkJICAgICAgIG9tYXBfcmVhZHcoT01BUF9ETUFfQ0FQU18yKSwgb21hcF9yZWFkdyhPTUFQX0RNQV9DQVBTXzMpLAoJCSAgICAgICBvbWFwX3JlYWR3KE9NQVBfRE1BX0NBUFNfNCkpOwoJCWlmICghZW5hYmxlXzE1MTBfbW9kZSkgewoJCQl1MTYgdzsKCgkJCS8qIERpc2FibGUgT01BUCAzLjAvMy4xIGNvbXBhdGliaWxpdHkgbW9kZS4gKi8KCQkJdyA9IG9tYXBfcmVhZHcoT01BUF9ETUFfR1NDUik7CgkJCXcgfD0gMSA8PCAzOwoJCQlvbWFwX3dyaXRldyh3LCBPTUFQX0RNQV9HU0NSKTsKCQkJZG1hX2NoYW5fY291bnQgPSAxNjsKCQl9IGVsc2UKCQkJZG1hX2NoYW5fY291bnQgPSA5OwoJCWlmIChjcHVfaXNfb21hcDE2eHgoKSkgewoJCQl1MTYgdzsKCgkJCS8qIHRoaXMgd291bGQgcHJldmVudCBPTUFQIHNsZWVwICovCgkJCXcgPSBvbWFwX3JlYWR3KE9NQVAxNjEwX0RNQV9MQ0RfQ1RSTCk7CgkJCXcgJj0gfigxIDw8IDgpOwoJCQlvbWFwX3dyaXRldyh3LCBPTUFQMTYxMF9ETUFfTENEX0NUUkwpOwoJCX0KCX0gZWxzZSBpZiAoY3B1X2lzX29tYXAyNHh4KCkpIHsKCQl1OCByZXZpc2lvbiA9IG9tYXBfcmVhZGIoT01BUF9ETUE0X1JFVklTSU9OKTsKCQlwcmludGsoS0VSTl9JTkZPICJPTUFQIERNQSBoYXJkd2FyZSByZXZpc2lvbiAlZC4lZFxuIiwKCQkgICAgICAgcmV2aXNpb24gPj4gNCwgcmV2aXNpb24gJiAweGYpOwoJCWRtYV9jaGFuX2NvdW50ID0gT01BUF9MT0dJQ0FMX0RNQV9DSF9DT1VOVDsKCX0gZWxzZSB7CgkJZG1hX2NoYW5fY291bnQgPSAwOwoJCXJldHVybiAwOwoJfQoKCW1lbXNldCgmbGNkX2RtYSwgMCwgc2l6ZW9mKGxjZF9kbWEpKTsKCXNwaW5fbG9ja19pbml0KCZsY2RfZG1hLmxvY2spOwoJc3Bpbl9sb2NrX2luaXQoJmRtYV9jaGFuX2xvY2spOwoJbWVtc2V0KCZkbWFfY2hhbiwgMCwgc2l6ZW9mKGRtYV9jaGFuKSk7CgoJZm9yIChjaCA9IDA7IGNoIDwgZG1hX2NoYW5fY291bnQ7IGNoKyspIHsKCQlvbWFwX2NsZWFyX2RtYShjaCk7CgkJZG1hX2NoYW5bY2hdLmRldl9pZCA9IC0xOwoJCWRtYV9jaGFuW2NoXS5uZXh0X2xjaCA9IC0xOwoKCQlpZiAoY2ggPj0gNiAmJiBlbmFibGVfMTUxMF9tb2RlKQoJCQljb250aW51ZTsKCgkJaWYgKGNwdV9jbGFzc19pc19vbWFwMSgpKSB7CgkJCS8qIHJlcXVlc3RfaXJxKCkgZG9lc24ndCBsaWtlIGRldl9pZCAoaWUuIGNoKSBiZWluZwoJCQkgKiB6ZXJvLCBzbyB3ZSBoYXZlIHRvIGtsdWRnZSBhcm91bmQgdGhpcy4gKi8KCQkJciA9IHJlcXVlc3RfaXJxKG9tYXAxX2RtYV9pcnFbY2hdLAoJCQkJCW9tYXAxX2RtYV9pcnFfaGFuZGxlciwgMCwgIkRNQSIsCgkJCQkJKHZvaWQgKikgKGNoICsgMSkpOwoJCQlpZiAociAhPSAwKSB7CgkJCQlpbnQgaTsKCgkJCQlwcmludGsoS0VSTl9FUlIgInVuYWJsZSB0byByZXF1ZXN0IElSUSAlZCAiCgkJCQkgICAgICAgImZvciBETUEgKGVycm9yICVkKVxuIiwKCQkJCSAgICAgICBvbWFwMV9kbWFfaXJxW2NoXSwgcik7CgkJCQlmb3IgKGkgPSAwOyBpIDwgY2g7IGkrKykKCQkJCQlmcmVlX2lycShvbWFwMV9kbWFfaXJxW2ldLAoJCQkJCQkgKHZvaWQgKikgKGkgKyAxKSk7CgkJCQlyZXR1cm4gcjsKCQkJfQoJCX0KCX0KCglpZiAoY3B1X2lzX29tYXAyNHh4KCkpCgkJc2V0dXBfaXJxKElOVF8yNFhYX1NETUFfSVJRMCwgJm9tYXAyNHh4X2RtYV9pcnEpOwoKCS8qIEZJWE1FOiBVcGRhdGUgTENEIERNQSB0byB3b3JrIG9uIDI0eHggKi8KCWlmIChjcHVfY2xhc3NfaXNfb21hcDEoKSkgewoJCXIgPSByZXF1ZXN0X2lycShJTlRfRE1BX0xDRCwgbGNkX2RtYV9pcnFfaGFuZGxlciwgMCwKCQkJCSJMQ0QgRE1BIiwgTlVMTCk7CgkJaWYgKHIgIT0gMCkgewoJCQlpbnQgaTsKCgkJCXByaW50ayhLRVJOX0VSUiAidW5hYmxlIHRvIHJlcXVlc3QgSVJRIGZvciBMQ0QgRE1BICIKCQkJICAgICAgICIoZXJyb3IgJWQpXG4iLCByKTsKCQkJZm9yIChpID0gMDsgaSA8IGRtYV9jaGFuX2NvdW50OyBpKyspCgkJCQlmcmVlX2lycShvbWFwMV9kbWFfaXJxW2ldLCAodm9pZCAqKSAoaSArIDEpKTsKCQkJcmV0dXJuIHI7CgkJfQoJfQoKCXJldHVybiAwOwp9CgphcmNoX2luaXRjYWxsKG9tYXBfaW5pdF9kbWEpOwoKRVhQT1JUX1NZTUJPTChvbWFwX2dldF9kbWFfc3JjX3Bvcyk7CkVYUE9SVF9TWU1CT0wob21hcF9nZXRfZG1hX2RzdF9wb3MpOwpFWFBPUlRfU1lNQk9MKG9tYXBfZ2V0X2RtYV9zcmNfYWRkcl9jb3VudGVyKTsKRVhQT1JUX1NZTUJPTChvbWFwX2NsZWFyX2RtYSk7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfZG1hX3ByaW9yaXR5KTsKRVhQT1JUX1NZTUJPTChvbWFwX3JlcXVlc3RfZG1hKTsKRVhQT1JUX1NZTUJPTChvbWFwX2ZyZWVfZG1hKTsKRVhQT1JUX1NZTUJPTChvbWFwX3N0YXJ0X2RtYSk7CkVYUE9SVF9TWU1CT0wob21hcF9zdG9wX2RtYSk7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfZG1hX2NhbGxiYWNrKTsKRVhQT1JUX1NZTUJPTChvbWFwX2VuYWJsZV9kbWFfaXJxKTsKRVhQT1JUX1NZTUJPTChvbWFwX2Rpc2FibGVfZG1hX2lycSk7CgpFWFBPUlRfU1lNQk9MKG9tYXBfc2V0X2RtYV90cmFuc2Zlcl9wYXJhbXMpOwpFWFBPUlRfU1lNQk9MKG9tYXBfc2V0X2RtYV9jb2xvcl9tb2RlKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9kbWFfd3JpdGVfbW9kZSk7CgpFWFBPUlRfU1lNQk9MKG9tYXBfc2V0X2RtYV9zcmNfcGFyYW1zKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9kbWFfc3JjX2luZGV4KTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9kbWFfc3JjX2RhdGFfcGFjayk7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfZG1hX3NyY19idXJzdF9tb2RlKTsKCkVYUE9SVF9TWU1CT0wob21hcF9zZXRfZG1hX2Rlc3RfcGFyYW1zKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9kbWFfZGVzdF9pbmRleCk7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfZG1hX2Rlc3RfZGF0YV9wYWNrKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9kbWFfZGVzdF9idXJzdF9tb2RlKTsKCkVYUE9SVF9TWU1CT0wob21hcF9zZXRfZG1hX3BhcmFtcyk7CgpFWFBPUlRfU1lNQk9MKG9tYXBfZG1hX2xpbmtfbGNoKTsKRVhQT1JUX1NZTUJPTChvbWFwX2RtYV91bmxpbmtfbGNoKTsKCkVYUE9SVF9TWU1CT0wob21hcF9yZXF1ZXN0X2xjZF9kbWEpOwpFWFBPUlRfU1lNQk9MKG9tYXBfZnJlZV9sY2RfZG1hKTsKRVhQT1JUX1NZTUJPTChvbWFwX2VuYWJsZV9sY2RfZG1hKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldHVwX2xjZF9kbWEpOwpFWFBPUlRfU1lNQk9MKG9tYXBfc3RvcF9sY2RfZG1hKTsKRVhQT1JUX1NZTUJPTChvbWFwX2xjZF9kbWFfZXh0X3J1bm5pbmcpOwpFWFBPUlRfU1lNQk9MKG9tYXBfc2V0X2xjZF9kbWFfYjEpOwpFWFBPUlRfU1lNQk9MKG9tYXBfc2V0X2xjZF9kbWFfc2luZ2xlX3RyYW5zZmVyKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9sY2RfZG1hX2V4dF9jb250cm9sbGVyKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9sY2RfZG1hX2IxX3JvdGF0aW9uKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9sY2RfZG1hX2IxX3Z4cmVzKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9sY2RfZG1hX2IxX3NjYWxlKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9sY2RfZG1hX2IxX21pcnJvcik7Cgo=