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+ZW5hYmxlZF9pcnFzIHw9IE9NQVAyX0RNQV9NSVNBTElHTkVEX0VSUl9JUlEgfAoJCQlPTUFQMl9ETUFfVFJBTlNfRVJSX0lSUTsKCglpZiAoY3B1X2lzX29tYXAxNnh4KCkpIHsKCQkvKiBJZiB0aGUgc3luYyBkZXZpY2UgaXMgc2V0LCBjb25maWd1cmUgaXQgZHluYW1pY2FsbHkuICovCgkJaWYgKGRldl9pZCAhPSAwKSB7CgkJCXNldF9nZG1hX2RldihmcmVlX2NoICsgMSwgZGV2X2lkKTsKCQkJZGV2X2lkID0gZnJlZV9jaCArIDE7CgkJfQoJCS8qIERpc2FibGUgdGhlIDE1MTAgY29tcGF0aWJpbGl0eSBtb2RlIGFuZCBzZXQgdGhlIHN5bmMgZGV2aWNlCgkJICogaWQuICovCgkJT01BUF9ETUFfQ0NSX1JFRyhmcmVlX2NoKSA9IGRldl9pZCB8ICgxIDw8IDEwKTsKCX0gZWxzZSBpZiAoY3B1X2lzX29tYXA3MzAoKSB8fCBjcHVfaXNfb21hcDE1eHgoKSkgewoJCU9NQVBfRE1BX0NDUl9SRUcoZnJlZV9jaCkgPSBkZXZfaWQ7Cgl9CgoJaWYgKGNwdV9pc19vbWFwMjR4eCgpKSB7CgkJb21hcDJfZW5hYmxlX2lycV9sY2goZnJlZV9jaCk7CgoJCW9tYXBfZW5hYmxlX2NoYW5uZWxfaXJxKGZyZWVfY2gpOwoJCS8qIENsZWFyIHRoZSBDU1IgcmVnaXN0ZXIgYW5kIElSUSBzdGF0dXMgcmVnaXN0ZXIgKi8KCQlPTUFQX0RNQV9DU1JfUkVHKGZyZWVfY2gpID0gT01BUDJfRE1BX0NTUl9DTEVBUl9NQVNLOwoJCW9tYXBfd3JpdGVsKDEgPDwgZnJlZV9jaCwgT01BUF9ETUE0X0lSUVNUQVRVU19MMCk7Cgl9CgoJKmRtYV9jaF9vdXQgPSBmcmVlX2NoOwoKCXJldHVybiAwOwp9Cgp2b2lkIG9tYXBfZnJlZV9kbWEoaW50IGxjaCkKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglzcGluX2xvY2tfaXJxc2F2ZSgmZG1hX2NoYW5fbG9jaywgZmxhZ3MpOwoJaWYgKGRtYV9jaGFuW2xjaF0uZGV2X2lkID09IC0xKSB7CgkJcHJpbnRrKCJvbWFwX2RtYTogdHJ5aW5nIHRvIGZyZWUgbm9uYWxsb2NhdGVkIERNQSBjaGFubmVsICVkXG4iLAoJCSAgICAgICBsY2gpOwoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmRtYV9jaGFuX2xvY2ssIGZsYWdzKTsKCQlyZXR1cm47Cgl9CglkbWFfY2hhbltsY2hdLmRldl9pZCA9IC0xOwoJZG1hX2NoYW5bbGNoXS5uZXh0X2xjaCA9IC0xOwoJZG1hX2NoYW5bbGNoXS5jYWxsYmFjayA9IE5VTEw7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZkbWFfY2hhbl9sb2NrLCBmbGFncyk7CgoJaWYgKGNwdV9jbGFzc19pc19vbWFwMSgpKSB7CgkJLyogRGlzYWJsZSBhbGwgRE1BIGludGVycnVwdHMgZm9yIHRoZSBjaGFubmVsLiAqLwoJCU9NQVBfRE1BX0NJQ1JfUkVHKGxjaCkgPSAwOwoJCS8qIE1ha2Ugc3VyZSB0aGUgRE1BIHRyYW5zZmVyIGlzIHN0b3BwZWQuICovCgkJT01BUF9ETUFfQ0NSX1JFRyhsY2gpID0gMDsKCX0KCglpZiAoY3B1X2lzX29tYXAyNHh4KCkpIHsKCQl1MzIgdmFsOwoJCS8qIERpc2FibGUgaW50ZXJydXB0cyAqLwoJCXZhbCA9IG9tYXBfcmVhZGwoT01BUF9ETUE0X0lSUUVOQUJMRV9MMCk7CgkJdmFsICY9IH4oMSA8PCBsY2gpOwoJCW9tYXBfd3JpdGVsKHZhbCwgT01BUF9ETUE0X0lSUUVOQUJMRV9MMCk7CgoJCS8qIENsZWFyIHRoZSBDU1IgcmVnaXN0ZXIgYW5kIElSUSBzdGF0dXMgcmVnaXN0ZXIgKi8KCQlPTUFQX0RNQV9DU1JfUkVHKGxjaCkgPSBPTUFQMl9ETUFfQ1NSX0NMRUFSX01BU0s7CgkJb21hcF93cml0ZWwoMSA8PCBsY2gsIE9NQVBfRE1BNF9JUlFTVEFUVVNfTDApOwoKCQkvKiBEaXNhYmxlIGFsbCBETUEgaW50ZXJydXB0cyBmb3IgdGhlIGNoYW5uZWwuICovCgkJT01BUF9ETUFfQ0lDUl9SRUcobGNoKSA9IDA7CgoJCS8qIE1ha2Ugc3VyZSB0aGUgRE1BIHRyYW5zZmVyIGlzIHN0b3BwZWQuICovCgkJT01BUF9ETUFfQ0NSX1JFRyhsY2gpID0gMDsKCQlvbWFwX2NsZWFyX2RtYShsY2gpOwoJfQp9CgovKgogKiBDbGVhcnMgYW55IERNQSBzdGF0ZSBzbyB0aGUgRE1BIGVuZ2luZSBpcyByZWFkeSB0byByZXN0YXJ0IHdpdGggbmV3IGJ1ZmZlcnMKICogdGhyb3VnaCBvbWFwX3N0YXJ0X2RtYSgpLiBBbnkgYnVmZmVycyBpbiBmbGlnaHQgYXJlIGRpc2NhcmRlZC4KICovCnZvaWQgb21hcF9jbGVhcl9kbWEoaW50IGxjaCkKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglsb2NhbF9pcnFfc2F2ZShmbGFncyk7CgoJaWYgKGNwdV9jbGFzc19pc19vbWFwMSgpKSB7CgkJaW50IHN0YXR1czsKCQlPTUFQX0RNQV9DQ1JfUkVHKGxjaCkgJj0gfk9NQVBfRE1BX0NDUl9FTjsKCgkJLyogQ2xlYXIgcGVuZGluZyBpbnRlcnJ1cHRzICovCgkJc3RhdHVzID0gT01BUF9ETUFfQ1NSX1JFRyhsY2gpOwoJfQoKCWlmIChjcHVfaXNfb21hcDI0eHgoKSkgewoJCWludCBpOwoJCXUzMiBsY2hfYmFzZSA9IE9NQVAyNFhYX0RNQV9CQVNFICsgbGNoICogMHg2MCArIDB4ODA7CgkJZm9yIChpID0gMDsgaSA8IDB4NDQ7IGkgKz0gNCkKCQkJb21hcF93cml0ZWwoMCwgbGNoX2Jhc2UgKyBpKTsKCX0KCglsb2NhbF9pcnFfcmVzdG9yZShmbGFncyk7Cn0KCnZvaWQgb21hcF9zdGFydF9kbWEoaW50IGxjaCkKewoJaWYgKCFvbWFwX2RtYV9pbl8xNTEwX21vZGUoKSAmJiBkbWFfY2hhbltsY2hdLm5leHRfbGNoICE9IC0xKSB7CgkJaW50IG5leHRfbGNoLCBjdXJfbGNoOwoJCWNoYXIgZG1hX2NoYW5fbGlua19tYXBbT01BUF9MT0dJQ0FMX0RNQV9DSF9DT1VOVF07CgoJCWRtYV9jaGFuX2xpbmtfbWFwW2xjaF0gPSAxOwoJCS8qIFNldCB0aGUgbGluayByZWdpc3RlciBvZiB0aGUgZmlyc3QgY2hhbm5lbCAqLwoJCWVuYWJsZV9sbmsobGNoKTsKCgkJbWVtc2V0KGRtYV9jaGFuX2xpbmtfbWFwLCAwLCBzaXplb2YoZG1hX2NoYW5fbGlua19tYXApKTsKCQljdXJfbGNoID0gZG1hX2NoYW5bbGNoXS5uZXh0X2xjaDsKCQlkbyB7CgkJCW5leHRfbGNoID0gZG1hX2NoYW5bY3VyX2xjaF0ubmV4dF9sY2g7CgoJCQkvKiBUaGUgbG9vcCBjYXNlOiB3ZSd2ZSBiZWVuIGhlcmUgYWxyZWFkeSAqLwoJCQlpZiAoZG1hX2NoYW5fbGlua19tYXBbY3VyX2xjaF0pCgkJCQlicmVhazsKCQkJLyogTWFyayB0aGUgY3VycmVudCBjaGFubmVsICovCgkJCWRtYV9jaGFuX2xpbmtfbWFwW2N1cl9sY2hdID0gMTsKCgkJCWVuYWJsZV9sbmsoY3VyX2xjaCk7CgkJCW9tYXBfZW5hYmxlX2NoYW5uZWxfaXJxKGN1cl9sY2gpOwoKCQkJY3VyX2xjaCA9IG5leHRfbGNoOwoJCX0gd2hpbGUgKG5leHRfbGNoICE9IC0xKTsKCX0gZWxzZSBpZiAoY3B1X2lzX29tYXAyNHh4KCkpIHsKCQkvKiBFcnJhdGE6IE5lZWQgdG8gd3JpdGUgbGNoIGV2ZW4gaWYgbm90IHVzaW5nIGNoYWluaW5nICovCgkJT01BUF9ETUFfQ0xOS19DVFJMX1JFRyhsY2gpID0gbGNoOwoJfQoKCW9tYXBfZW5hYmxlX2NoYW5uZWxfaXJxKGxjaCk7CgoJLyogRXJyYXRhOiBPbiBFUzIuMCBCVUZGRVJJTkcgZGlzYWJsZSBtdXN0IGJlIHNldC4KCSAqIFRoaXMgd2lsbCBhbHdheXMgZmFpbCBvbiBFUzEuMCAqLwoJaWYgKGNwdV9pc19vbWFwMjR4eCgpKSB7CgkJT01BUF9ETUFfQ0NSX1JFRyhsY2gpIHw9IE9NQVBfRE1BX0NDUl9FTjsKCX0KCglPTUFQX0RNQV9DQ1JfUkVHKGxjaCkgfD0gT01BUF9ETUFfQ0NSX0VOOwoKCWRtYV9jaGFuW2xjaF0uZmxhZ3MgfD0gT01BUF9ETUFfQUNUSVZFOwp9Cgp2b2lkIG9tYXBfc3RvcF9kbWEoaW50IGxjaCkKewoJaWYgKCFvbWFwX2RtYV9pbl8xNTEwX21vZGUoKSAmJiBkbWFfY2hhbltsY2hdLm5leHRfbGNoICE9IC0xKSB7CgkJaW50IG5leHRfbGNoLCBjdXJfbGNoID0gbGNoOwoJCWNoYXIgZG1hX2NoYW5fbGlua19tYXBbT01BUF9MT0dJQ0FMX0RNQV9DSF9DT1VOVF07CgoJCW1lbXNldChkbWFfY2hhbl9saW5rX21hcCwgMCwgc2l6ZW9mKGRtYV9jaGFuX2xpbmtfbWFwKSk7CgkJZG8gewoJCQkvKiBUaGUgbG9vcCBjYXNlOiB3ZSd2ZSBiZWVuIGhlcmUgYWxyZWFkeSAqLwoJCQlpZiAoZG1hX2NoYW5fbGlua19tYXBbY3VyX2xjaF0pCgkJCQlicmVhazsKCQkJLyogTWFyayB0aGUgY3VycmVudCBjaGFubmVsICovCgkJCWRtYV9jaGFuX2xpbmtfbWFwW2N1cl9sY2hdID0gMTsKCgkJCWRpc2FibGVfbG5rKGN1cl9sY2gpOwoKCQkJbmV4dF9sY2ggPSBkbWFfY2hhbltjdXJfbGNoXS5uZXh0X2xjaDsKCQkJY3VyX2xjaCA9IG5leHRfbGNoOwoJCX0gd2hpbGUgKG5leHRfbGNoICE9IC0xKTsKCgkJcmV0dXJuOwoJfQoKCS8qIERpc2FibGUgYWxsIGludGVycnVwdHMgb24gdGhlIGNoYW5uZWwgKi8KCWlmIChjcHVfY2xhc3NfaXNfb21hcDEoKSkKCQlPTUFQX0RNQV9DSUNSX1JFRyhsY2gpID0gMDsKCglPTUFQX0RNQV9DQ1JfUkVHKGxjaCkgJj0gfk9NQVBfRE1BX0NDUl9FTjsKCWRtYV9jaGFuW2xjaF0uZmxhZ3MgJj0gfk9NQVBfRE1BX0FDVElWRTsKfQoKLyoKICogQWxsb3dzIGNoYW5naW5nIHRoZSBETUEgY2FsbGJhY2sgZnVuY3Rpb24gb3IgZGF0YS4gVGhpcyBtYXkgYmUgbmVlZGVkIGlmCiAqIHRoZSBkcml2ZXIgc2hhcmVzIGEgc2luZ2xlIERNQSBjaGFubmVsIGZvciBtdWx0aXBsZSBkbWEgdHJpZ2dlcnMuCiAqLwppbnQgb21hcF9zZXRfZG1hX2NhbGxiYWNrKGludCBsY2gsCgkJCSAgdm9pZCAoKiBjYWxsYmFjaykoaW50IGxjaCwgdTE2IGNoX3N0YXR1cywgdm9pZCAqZGF0YSksCgkJCSAgdm9pZCAqZGF0YSkKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglpZiAobGNoIDwgMCkKCQlyZXR1cm4gLUVOT0RFVjsKCglzcGluX2xvY2tfaXJxc2F2ZSgmZG1hX2NoYW5fbG9jaywgZmxhZ3MpOwoJaWYgKGRtYV9jaGFuW2xjaF0uZGV2X2lkID09IC0xKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJETUEgY2FsbGJhY2sgZm9yIG5vdCBzZXQgZm9yIGZyZWUgY2hhbm5lbFxuIik7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmZG1hX2NoYW5fbG9jaywgZmxhZ3MpOwoJCXJldHVybiAtRUlOVkFMOwoJfQoJZG1hX2NoYW5bbGNoXS5jYWxsYmFjayA9IGNhbGxiYWNrOwoJZG1hX2NoYW5bbGNoXS5kYXRhID0gZGF0YTsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmRtYV9jaGFuX2xvY2ssIGZsYWdzKTsKCglyZXR1cm4gMDsKfQoKLyoKICogUmV0dXJucyBjdXJyZW50IHBoeXNpY2FsIHNvdXJjZSBhZGRyZXNzIGZvciB0aGUgZ2l2ZW4gRE1BIGNoYW5uZWwuCiAqIElmIHRoZSBjaGFubmVsIGlzIHJ1bm5pbmcgdGhlIGNhbGxlciBtdXN0IGRpc2FibGUgaW50ZXJydXB0cyBwcmlvciBjYWxsaW5nCiAqIHRoaXMgZnVuY3Rpb24gYW5kIHByb2Nlc3MgdGhlIHJldHVybmVkIHZhbHVlIGJlZm9yZSByZS1lbmFibGluZyBpbnRlcnJ1cHQgdG8KICogcHJldmVudCByYWNlcyB3aXRoIHRoZSBpbnRlcnJ1cHQgaGFuZGxlci4gTm90ZSB0aGF0IGluIGNvbnRpbnVvdXMgbW9kZSB0aGVyZQogKiBpcyBhIGNoYW5jZSBmb3IgQ1NTQV9MIHJlZ2lzdGVyIG92ZXJmbG93IGluYmV0d2VlbiB0aGUgdHdvIHJlYWRzIHJlc3VsdGluZwogKiBpbiBpbmNvcnJlY3QgcmV0dXJuIHZhbHVlLgogKi8KZG1hX2FkZHJfdCBvbWFwX2dldF9kbWFfc3JjX3BvcyhpbnQgbGNoKQp7CglkbWFfYWRkcl90IG9mZnNldCA9IDA7CgoJaWYgKGNwdV9jbGFzc19pc19vbWFwMSgpKQoJCW9mZnNldCA9IChkbWFfYWRkcl90KSAoT01BUDFfRE1BX0NTU0FfTF9SRUcobGNoKSB8CgkJCQkgICAgICAgKE9NQVAxX0RNQV9DU1NBX1VfUkVHKGxjaCkgPDwgMTYpKTsKCglpZiAoY3B1X2lzX29tYXAyNHh4KCkpCgkJb2Zmc2V0ID0gT01BUF9ETUFfQ1NBQ19SRUcobGNoKTsKCglyZXR1cm4gb2Zmc2V0Owp9CgovKgogKiBSZXR1cm5zIGN1cnJlbnQgcGh5c2ljYWwgZGVzdGluYXRpb24gYWRkcmVzcyBmb3IgdGhlIGdpdmVuIERNQSBjaGFubmVsLgogKiBJZiB0aGUgY2hhbm5lbCBpcyBydW5uaW5nIHRoZSBjYWxsZXIgbXVzdCBkaXNhYmxlIGludGVycnVwdHMgcHJpb3IgY2FsbGluZwogKiB0aGlzIGZ1bmN0aW9uIGFuZCBwcm9jZXNzIHRoZSByZXR1cm5lZCB2YWx1ZSBiZWZvcmUgcmUtZW5hYmxpbmcgaW50ZXJydXB0IHRvCiAqIHByZXZlbnQgcmFjZXMgd2l0aCB0aGUgaW50ZXJydXB0IGhhbmRsZXIuIE5vdGUgdGhhdCBpbiBjb250aW51b3VzIG1vZGUgdGhlcmUKICogaXMgYSBjaGFuY2UgZm9yIENEU0FfTCByZWdpc3RlciBvdmVyZmxvdyBpbmJldHdlZW4gdGhlIHR3byByZWFkcyByZXN1bHRpbmcKICogaW4gaW5jb3JyZWN0IHJldHVybiB2YWx1ZS4KICovCmRtYV9hZGRyX3Qgb21hcF9nZXRfZG1hX2RzdF9wb3MoaW50IGxjaCkKewoJZG1hX2FkZHJfdCBvZmZzZXQgPSAwOwoKCWlmIChjcHVfY2xhc3NfaXNfb21hcDEoKSkKCQlvZmZzZXQgPSAoZG1hX2FkZHJfdCkgKE9NQVAxX0RNQV9DRFNBX0xfUkVHKGxjaCkgfAoJCQkJICAgICAgIChPTUFQMV9ETUFfQ0RTQV9VX1JFRyhsY2gpIDw8IDE2KSk7CgoJaWYgKGNwdV9pc19vbWFwMjR4eCgpKQoJCW9mZnNldCA9IE9NQVAyX0RNQV9DRFNBX1JFRyhsY2gpOwoKCXJldHVybiBvZmZzZXQ7Cn0KCi8qCiAqIFJldHVybnMgY3VycmVudCBzb3VyY2UgdHJhbnNmZXIgY291bnRpbmcgZm9yIHRoZSBnaXZlbiBETUEgY2hhbm5lbC4KICogQ2FuIGJlIHVzZWQgdG8gbW9uaXRvciB0aGUgcHJvZ3Jlc3Mgb2YgYSB0cmFuc2ZlciBpbnNpZGUgYSBibG9jay4KICogSXQgbXVzdCBiZSBjYWxsZWQgd2l0aCBkaXNhYmxlZCBpbnRlcnJ1cHRzLgogKi8KaW50IG9tYXBfZ2V0X2RtYV9zcmNfYWRkcl9jb3VudGVyKGludCBsY2gpCnsKCXJldHVybiAoZG1hX2FkZHJfdCkgT01BUF9ETUFfQ1NBQ19SRUcobGNoKTsKfQoKaW50IG9tYXBfZG1hX3J1bm5pbmcodm9pZCkKewoJaW50IGxjaDsKCgkvKiBDaGVjayBpZiBMQ0QgRE1BIGlzIHJ1bm5pbmcgKi8KCWlmIChjcHVfaXNfb21hcDE2eHgoKSkKCQlpZiAob21hcF9yZWFkdyhPTUFQMTYxMF9ETUFfTENEX0NDUikgJiBPTUFQX0RNQV9DQ1JfRU4pCgkJCXJldHVybiAxOwoKCWZvciAobGNoID0gMDsgbGNoIDwgZG1hX2NoYW5fY291bnQ7IGxjaCsrKQoJCWlmIChPTUFQX0RNQV9DQ1JfUkVHKGxjaCkgJiBPTUFQX0RNQV9DQ1JfRU4pCgkJCXJldHVybiAxOwoKCXJldHVybiAwOwp9CgovKgogKiBsY2hfcXVldWUgRE1BIHdpbGwgc3RhcnQgcmlnaHQgYWZ0ZXIgbGNoX2hlYWQgb25lIGlzIGZpbmlzaGVkLgogKiBGb3IgdGhpcyBETUEgbGluayB0byBzdGFydCwgeW91IHN0aWxsIG5lZWQgdG8gc3RhcnQgKHNlZSBvbWFwX3N0YXJ0X2RtYSkKICogdGhlIGZpcnN0IG9uZS4gVGhhdCB3aWxsIGZpcmUgdXAgdGhlIGVudGlyZSBxdWV1ZS4KICovCnZvaWQgb21hcF9kbWFfbGlua19sY2ggKGludCBsY2hfaGVhZCwgaW50IGxjaF9xdWV1ZSkKewoJaWYgKG9tYXBfZG1hX2luXzE1MTBfbW9kZSgpKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJETUEgbGlua2luZyBpcyBub3Qgc3VwcG9ydGVkIGluIDE1MTAgbW9kZVxuIik7CgkJQlVHKCk7CgkJcmV0dXJuOwoJfQoKCWlmICgoZG1hX2NoYW5bbGNoX2hlYWRdLmRldl9pZCA9PSAtMSkgfHwKCSAgICAoZG1hX2NoYW5bbGNoX3F1ZXVlXS5kZXZfaWQgPT0gLTEpKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJvbWFwX2RtYTogdHJ5aW5nIHRvIGxpbmsgIgoJCSAgICAgICAibm9uIHJlcXVlc3RlZCBjaGFubmVsc1xuIik7CgkJZHVtcF9zdGFjaygpOwoJfQoKCWRtYV9jaGFuW2xjaF9oZWFkXS5uZXh0X2xjaCA9IGxjaF9xdWV1ZTsKfQoKLyoKICogT25jZSB0aGUgRE1BIHF1ZXVlIGlzIHN0b3BwZWQsIHdlIGNhbiBkZXN0cm95IGl0LgogKi8Kdm9pZCBvbWFwX2RtYV91bmxpbmtfbGNoIChpbnQgbGNoX2hlYWQsIGludCBsY2hfcXVldWUpCnsKCWlmIChvbWFwX2RtYV9pbl8xNTEwX21vZGUoKSkgewoJCXByaW50ayhLRVJOX0VSUiAiRE1BIGxpbmtpbmcgaXMgbm90IHN1cHBvcnRlZCBpbiAxNTEwIG1vZGVcbiIpOwoJCUJVRygpOwoJCXJldHVybjsKCX0KCglpZiAoZG1hX2NoYW5bbGNoX2hlYWRdLm5leHRfbGNoICE9IGxjaF9xdWV1ZSB8fAoJICAgIGRtYV9jaGFuW2xjaF9oZWFkXS5uZXh0X2xjaCA9PSAtMSkgewoJCXByaW50ayhLRVJOX0VSUiAib21hcF9kbWE6IHRyeWluZyB0byB1bmxpbmsgIgoJCSAgICAgICAibm9uIGxpbmtlZCBjaGFubmVsc1xuIik7CgkJZHVtcF9zdGFjaygpOwoJfQoKCglpZiAoKGRtYV9jaGFuW2xjaF9oZWFkXS5mbGFncyAmIE9NQVBfRE1BX0FDVElWRSkgfHwKCSAgICAoZG1hX2NoYW5bbGNoX2hlYWRdLmZsYWdzICYgT01BUF9ETUFfQUNUSVZFKSkgewoJCXByaW50ayhLRVJOX0VSUiAib21hcF9kbWE6IFlvdSBuZWVkIHRvIHN0b3AgdGhlIERNQSBjaGFubmVscyAiCgkJICAgICAgICJiZWZvcmUgdW5saW5raW5nXG4iKTsKCQlkdW1wX3N0YWNrKCk7Cgl9CgoJZG1hX2NoYW5bbGNoX2hlYWRdLm5leHRfbGNoID0gLTE7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgojaWZkZWYgQ09ORklHX0FSQ0hfT01BUDEKCnN0YXRpYyBpbnQgb21hcDFfZG1hX2hhbmRsZV9jaChpbnQgY2gpCnsKCXUxNiBjc3I7CgoJaWYgKGVuYWJsZV8xNTEwX21vZGUgJiYgY2ggPj0gNikgewoJCWNzciA9IGRtYV9jaGFuW2NoXS5zYXZlZF9jc3I7CgkJZG1hX2NoYW5bY2hdLnNhdmVkX2NzciA9IDA7Cgl9IGVsc2UKCQljc3IgPSBPTUFQX0RNQV9DU1JfUkVHKGNoKTsKCWlmIChlbmFibGVfMTUxMF9tb2RlICYmIGNoIDw9IDIgJiYgKGNzciA+PiA3KSAhPSAwKSB7CgkJZG1hX2NoYW5bY2ggKyA2XS5zYXZlZF9jc3IgPSBjc3IgPj4gNzsKCQljc3IgJj0gMHg3ZjsKCX0KCWlmICgoY3NyICYgMHgzZikgPT0gMCkKCQlyZXR1cm4gMDsKCWlmICh1bmxpa2VseShkbWFfY2hhbltjaF0uZGV2X2lkID09IC0xKSkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgIlNwdXJpb3VzIGludGVycnVwdCBmcm9tIERNQSBjaGFubmVsICIKCQkgICAgICAgIiVkIChDU1IgJTA0eClcbiIsIGNoLCBjc3IpOwoJCXJldHVybiAwOwoJfQoJaWYgKHVubGlrZWx5KGNzciAmIE9NQVAxX0RNQV9UT1VUX0lSUSkpCgkJcHJpbnRrKEtFUk5fV0FSTklORyAiRE1BIHRpbWVvdXQgd2l0aCBkZXZpY2UgJWRcbiIsCgkJICAgICAgIGRtYV9jaGFuW2NoXS5kZXZfaWQpOwoJaWYgKHVubGlrZWx5KGNzciAmIE9NQVBfRE1BX0RST1BfSVJRKSkKCQlwcmludGsoS0VSTl9XQVJOSU5HICJETUEgc3luY2hyb25pemF0aW9uIGV2ZW50IGRyb3Agb2NjdXJyZWQgIgoJCSAgICAgICAid2l0aCBkZXZpY2UgJWRcbiIsIGRtYV9jaGFuW2NoXS5kZXZfaWQpOwoJaWYgKGxpa2VseShjc3IgJiBPTUFQX0RNQV9CTE9DS19JUlEpKQoJCWRtYV9jaGFuW2NoXS5mbGFncyAmPSB+T01BUF9ETUFfQUNUSVZFOwoJaWYgKGxpa2VseShkbWFfY2hhbltjaF0uY2FsbGJhY2sgIT0gTlVMTCkpCgkJZG1hX2NoYW5bY2hdLmNhbGxiYWNrKGNoLCBjc3IsIGRtYV9jaGFuW2NoXS5kYXRhKTsKCXJldHVybiAxOwp9CgpzdGF0aWMgaXJxcmV0dXJuX3Qgb21hcDFfZG1hX2lycV9oYW5kbGVyKGludCBpcnEsIHZvaWQgKmRldl9pZCkKewoJaW50IGNoID0gKChpbnQpIGRldl9pZCkgLSAxOwoJaW50IGhhbmRsZWQgPSAwOwoKCWZvciAoOzspIHsKCQlpbnQgaGFuZGxlZF9ub3cgPSAwOwoKCQloYW5kbGVkX25vdyArPSBvbWFwMV9kbWFfaGFuZGxlX2NoKGNoKTsKCQlpZiAoZW5hYmxlXzE1MTBfbW9kZSAmJiBkbWFfY2hhbltjaCArIDZdLnNhdmVkX2NzcikKCQkJaGFuZGxlZF9ub3cgKz0gb21hcDFfZG1hX2hhbmRsZV9jaChjaCArIDYpOwoJCWlmICghaGFuZGxlZF9ub3cpCgkJCWJyZWFrOwoJCWhhbmRsZWQgKz0gaGFuZGxlZF9ub3c7Cgl9CgoJcmV0dXJuIGhhbmRsZWQgPyBJUlFfSEFORExFRCA6IElSUV9OT05FOwp9CgojZWxzZQojZGVmaW5lIG9tYXAxX2RtYV9pcnFfaGFuZGxlcglOVUxMCiNlbmRpZgoKI2lmZGVmIENPTkZJR19BUkNIX09NQVAyCgpzdGF0aWMgaW50IG9tYXAyX2RtYV9oYW5kbGVfY2goaW50IGNoKQp7Cgl1MzIgc3RhdHVzID0gT01BUF9ETUFfQ1NSX1JFRyhjaCk7CgoJaWYgKCFzdGF0dXMpIHsKCQlpZiAocHJpbnRrX3JhdGVsaW1pdCgpKQoJCQlwcmludGsoS0VSTl9XQVJOSU5HICJTcHVyaW91cyBETUEgSVJRIGZvciBsY2ggJWRcbiIsIGNoKTsKCQlyZXR1cm4gMDsKCX0KCWlmICh1bmxpa2VseShkbWFfY2hhbltjaF0uZGV2X2lkID09IC0xKSkgewoJCWlmIChwcmludGtfcmF0ZWxpbWl0KCkpCgkJCXByaW50ayhLRVJOX1dBUk5JTkcgIklSUSAlMDR4IGZvciBub24tYWxsb2NhdGVkIERNQSIKCQkJCQkiY2hhbm5lbCAlZFxuIiwgc3RhdHVzLCBjaCk7CgkJcmV0dXJuIDA7Cgl9CglpZiAodW5saWtlbHkoc3RhdHVzICYgT01BUF9ETUFfRFJPUF9JUlEpKQoJCXByaW50ayhLRVJOX0lORk8KCQkgICAgICAgIkRNQSBzeW5jaHJvbml6YXRpb24gZXZlbnQgZHJvcCBvY2N1cnJlZCB3aXRoIGRldmljZSAiCgkJICAgICAgICIlZFxuIiwgZG1hX2NoYW5bY2hdLmRldl9pZCk7CglpZiAodW5saWtlbHkoc3RhdHVzICYgT01BUDJfRE1BX1RSQU5TX0VSUl9JUlEpKQoJCXByaW50ayhLRVJOX0lORk8gIkRNQSB0cmFuc2FjdGlvbiBlcnJvciB3aXRoIGRldmljZSAlZFxuIiwKCQkgICAgICAgZG1hX2NoYW5bY2hdLmRldl9pZCk7CglpZiAodW5saWtlbHkoc3RhdHVzICYgT01BUDJfRE1BX1NFQ1VSRV9FUlJfSVJRKSkKCQlwcmludGsoS0VSTl9JTkZPICJETUEgc2VjdXJlIGVycm9yIHdpdGggZGV2aWNlICVkXG4iLAoJCSAgICAgICBkbWFfY2hhbltjaF0uZGV2X2lkKTsKCWlmICh1bmxpa2VseShzdGF0dXMgJiBPTUFQMl9ETUFfTUlTQUxJR05FRF9FUlJfSVJRKSkKCQlwcmludGsoS0VSTl9JTkZPICJETUEgbWlzYWxpZ25lZCBlcnJvciB3aXRoIGRldmljZSAlZFxuIiwKCQkgICAgICAgZG1hX2NoYW5bY2hdLmRldl9pZCk7CgoJT01BUF9ETUFfQ1NSX1JFRyhjaCkgPSBPTUFQMl9ETUFfQ1NSX0NMRUFSX01BU0s7CglvbWFwX3dyaXRlbCgxIDw8IGNoLCBPTUFQX0RNQTRfSVJRU1RBVFVTX0wwKTsKCglpZiAobGlrZWx5KGRtYV9jaGFuW2NoXS5jYWxsYmFjayAhPSBOVUxMKSkKCQlkbWFfY2hhbltjaF0uY2FsbGJhY2soY2gsIHN0YXR1cywgZG1hX2NoYW5bY2hdLmRhdGEpOwoKCXJldHVybiAwOwp9CgovKiBTVEFUVVMgcmVnaXN0ZXIgY291bnQgaXMgZnJvbSAxLTMyIHdoaWxlIG91ciBpcyAwLTMxICovCnN0YXRpYyBpcnFyZXR1cm5fdCBvbWFwMl9kbWFfaXJxX2hhbmRsZXIoaW50IGlycSwgdm9pZCAqZGV2X2lkKQp7Cgl1MzIgdmFsOwoJaW50IGk7CgoJdmFsID0gb21hcF9yZWFkbChPTUFQX0RNQTRfSVJRU1RBVFVTX0wwKTsKCWlmICh2YWwgPT0gMCkgewoJCWlmIChwcmludGtfcmF0ZWxpbWl0KCkpCgkJCXByaW50ayhLRVJOX1dBUk5JTkcgIlNwdXJpb3VzIERNQSBJUlFcbiIpOwoJCXJldHVybiBJUlFfSEFORExFRDsKCX0KCWZvciAoaSA9IDA7IGkgPCBPTUFQX0xPR0lDQUxfRE1BX0NIX0NPVU5UICYmIHZhbCAhPSAwOyBpKyspIHsKCQlpZiAodmFsICYgMSkKCQkJb21hcDJfZG1hX2hhbmRsZV9jaChpKTsKCQl2YWwgPj49IDE7Cgl9CgoJcmV0dXJuIElSUV9IQU5ETEVEOwp9CgpzdGF0aWMgc3RydWN0IGlycWFjdGlvbiBvbWFwMjR4eF9kbWFfaXJxID0gewoJLm5hbWUgPSAiRE1BIiwKCS5oYW5kbGVyID0gb21hcDJfZG1hX2lycV9oYW5kbGVyLAoJLmZsYWdzID0gSVJRRl9ESVNBQkxFRAp9OwoKI2Vsc2UKc3RhdGljIHN0cnVjdCBpcnFhY3Rpb24gb21hcDI0eHhfZG1hX2lycTsKI2VuZGlmCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKc3RhdGljIHN0cnVjdCBsY2RfZG1hX2luZm8gewoJc3BpbmxvY2tfdCBsb2NrOwoJaW50IHJlc2VydmVkOwoJdm9pZCAoKiBjYWxsYmFjaykodTE2IHN0YXR1cywgdm9pZCAqZGF0YSk7Cgl2b2lkICpjYl9kYXRhOwoKCWludCBhY3RpdmU7Cgl1bnNpZ25lZCBsb25nIGFkZHIsIHNpemU7CglpbnQgcm90YXRlLCBkYXRhX3R5cGUsIHhyZXMsIHlyZXM7CglpbnQgdnhyZXM7CglpbnQgbWlycm9yOwoJaW50IHhzY2FsZSwgeXNjYWxlOwoJaW50IGV4dF9jdHJsOwoJaW50IHNyY19wb3J0OwoJaW50IHNpbmdsZV90cmFuc2ZlcjsKfSBsY2RfZG1hOwoKdm9pZCBvbWFwX3NldF9sY2RfZG1hX2IxKHVuc2lnbmVkIGxvbmcgYWRkciwgdTE2IGZiX3hyZXMsIHUxNiBmYl95cmVzLAoJCQkgaW50IGRhdGFfdHlwZSkKewoJbGNkX2RtYS5hZGRyID0gYWRkcjsKCWxjZF9kbWEuZGF0YV90eXBlID0gZGF0YV90eXBlOwoJbGNkX2RtYS54cmVzID0gZmJfeHJlczsKCWxjZF9kbWEueXJlcyA9IGZiX3lyZXM7Cn0KCnZvaWQgb21hcF9zZXRfbGNkX2RtYV9zcmNfcG9ydChpbnQgcG9ydCkKewoJbGNkX2RtYS5zcmNfcG9ydCA9IHBvcnQ7Cn0KCnZvaWQgb21hcF9zZXRfbGNkX2RtYV9leHRfY29udHJvbGxlcihpbnQgZXh0ZXJuYWwpCnsKCWxjZF9kbWEuZXh0X2N0cmwgPSBleHRlcm5hbDsKfQoKdm9pZCBvbWFwX3NldF9sY2RfZG1hX3NpbmdsZV90cmFuc2ZlcihpbnQgc2luZ2xlKQp7CglsY2RfZG1hLnNpbmdsZV90cmFuc2ZlciA9IHNpbmdsZTsKfQoKCnZvaWQgb21hcF9zZXRfbGNkX2RtYV9iMV9yb3RhdGlvbihpbnQgcm90YXRlKQp7CglpZiAob21hcF9kbWFfaW5fMTUxMF9tb2RlKCkpIHsKCQlwcmludGsoS0VSTl9FUlIgIkRNQSByb3RhdGlvbiBpcyBub3Qgc3VwcG9ydGVkIGluIDE1MTAgbW9kZVxuIik7CgkJQlVHKCk7CgkJcmV0dXJuOwoJfQoJbGNkX2RtYS5yb3RhdGUgPSByb3RhdGU7Cn0KCnZvaWQgb21hcF9zZXRfbGNkX2RtYV9iMV9taXJyb3IoaW50IG1pcnJvcikKewoJaWYgKG9tYXBfZG1hX2luXzE1MTBfbW9kZSgpKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJETUEgbWlycm9yIGlzIG5vdCBzdXBwb3J0ZWQgaW4gMTUxMCBtb2RlXG4iKTsKCQlCVUcoKTsKCX0KCWxjZF9kbWEubWlycm9yID0gbWlycm9yOwp9Cgp2b2lkIG9tYXBfc2V0X2xjZF9kbWFfYjFfdnhyZXModW5zaWduZWQgbG9uZyB2eHJlcykKewoJaWYgKG9tYXBfZG1hX2luXzE1MTBfbW9kZSgpKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJETUEgdmlydHVhbCByZXN1bG90aW9uIGlzIG5vdCBzdXBwb3J0ZWQgIgoJCQkJImluIDE1MTAgbW9kZVxuIik7CgkJQlVHKCk7Cgl9CglsY2RfZG1hLnZ4cmVzID0gdnhyZXM7Cn0KCnZvaWQgb21hcF9zZXRfbGNkX2RtYV9iMV9zY2FsZSh1bnNpZ25lZCBpbnQgeHNjYWxlLCB1bnNpZ25lZCBpbnQgeXNjYWxlKQp7CglpZiAob21hcF9kbWFfaW5fMTUxMF9tb2RlKCkpIHsKCQlwcmludGsoS0VSTl9FUlIgIkRNQSBzY2FsZSBpcyBub3Qgc3VwcG9ydGVkIGluIDE1MTAgbW9kZVxuIik7CgkJQlVHKCk7Cgl9CglsY2RfZG1hLnhzY2FsZSA9IHhzY2FsZTsKCWxjZF9kbWEueXNjYWxlID0geXNjYWxlOwp9CgpzdGF0aWMgdm9pZCBzZXRfYjFfcmVncyh2b2lkKQp7Cgl1bnNpZ25lZCBsb25nIHRvcCwgYm90dG9tOwoJaW50IGVzOwoJdTE2IHc7Cgl1bnNpZ25lZCBsb25nIGVuLCBmbjsKCWxvbmcgZWksIGZpOwoJdW5zaWduZWQgbG9uZyB2eHJlczsKCXVuc2lnbmVkIGludCB4c2NhbGUsIHlzY2FsZTsKCglzd2l0Y2ggKGxjZF9kbWEuZGF0YV90eXBlKSB7CgljYXNlIE9NQVBfRE1BX0RBVEFfVFlQRV9TODoKCQllcyA9IDE7CgkJYnJlYWs7CgljYXNlIE9NQVBfRE1BX0RBVEFfVFlQRV9TMTY6CgkJZXMgPSAyOwoJCWJyZWFrOwoJY2FzZSBPTUFQX0RNQV9EQVRBX1RZUEVfUzMyOgoJCWVzID0gNDsKCQlicmVhazsKCWRlZmF1bHQ6CgkJQlVHKCk7CgkJcmV0dXJuOwoJfQoKCXZ4cmVzID0gbGNkX2RtYS52eHJlcyA/IGxjZF9kbWEudnhyZXMgOiBsY2RfZG1hLnhyZXM7Cgl4c2NhbGUgPSBsY2RfZG1hLnhzY2FsZSA/IGxjZF9kbWEueHNjYWxlIDogMTsKCXlzY2FsZSA9IGxjZF9kbWEueXNjYWxlID8gbGNkX2RtYS55c2NhbGUgOiAxOwoJQlVHX09OKHZ4cmVzIDwgbGNkX2RtYS54cmVzKTsKI2RlZmluZSBQSVhBRERSKHgseSkgKGxjZF9kbWEuYWRkciArICgoeSkgKiB2eHJlcyAqIHlzY2FsZSArICh4KSAqIHhzY2FsZSkgKiBlcykKI2RlZmluZSBQSVhTVEVQKHN4LCBzeSwgZHgsIGR5KSAoUElYQUREUihkeCwgZHkpIC0gUElYQUREUihzeCwgc3kpIC0gZXMgKyAxKQoJc3dpdGNoIChsY2RfZG1hLnJvdGF0ZSkgewoJY2FzZSAwOgoJCWlmICghbGNkX2RtYS5taXJyb3IpIHsKCQkJdG9wID0gUElYQUREUigwLCAwKTsKCQkJYm90dG9tID0gUElYQUREUihsY2RfZG1hLnhyZXMgLSAxLCBsY2RfZG1hLnlyZXMgLSAxKTsKCQkJLyogMTUxMCBETUEgcmVxdWlyZXMgdGhlIGJvdHRvbSBhZGRyZXNzIHRvIGJlIDIgbW9yZQoJCQkgKiB0aGFuIHRoZSBhY3R1YWwgbGFzdCBtZW1vcnkgYWNjZXNzIGxvY2F0aW9uLiAqLwoJCQlpZiAob21hcF9kbWFfaW5fMTUxMF9tb2RlKCkgJiYKCQkJICAgIGxjZF9kbWEuZGF0YV90eXBlID09IE9NQVBfRE1BX0RBVEFfVFlQRV9TMzIpCgkJCQlib3R0b20gKz0gMjsKCQkJZWkgPSBQSVhTVEVQKDAsIDAsIDEsIDApOwoJCQlmaSA9IFBJWFNURVAobGNkX2RtYS54cmVzIC0gMSwgMCwgMCwgMSk7CgkJfSBlbHNlIHsKCQkJdG9wID0gUElYQUREUihsY2RfZG1hLnhyZXMgLSAxLCAwKTsKCQkJYm90dG9tID0gUElYQUREUigwLCBsY2RfZG1hLnlyZXMgLSAxKTsKCQkJZWkgPSBQSVhTVEVQKDEsIDAsIDAsIDApOwoJCQlmaSA9IFBJWFNURVAoMCwgMCwgbGNkX2RtYS54cmVzIC0gMSwgMSk7CgkJfQoJCWVuID0gbGNkX2RtYS54cmVzOwoJCWZuID0gbGNkX2RtYS55cmVzOwoJCWJyZWFrOwoJY2FzZSA5MDoKCQlpZiAoIWxjZF9kbWEubWlycm9yKSB7CgkJCXRvcCA9IFBJWEFERFIoMCwgbGNkX2RtYS55cmVzIC0gMSk7CgkJCWJvdHRvbSA9IFBJWEFERFIobGNkX2RtYS54cmVzIC0gMSwgMCk7CgkJCWVpID0gUElYU1RFUCgwLCAxLCAwLCAwKTsKCQkJZmkgPSBQSVhTVEVQKDAsIDAsIDEsIGxjZF9kbWEueXJlcyAtIDEpOwoJCX0gZWxzZSB7CgkJCXRvcCA9IFBJWEFERFIobGNkX2RtYS54cmVzIC0gMSwgbGNkX2RtYS55cmVzIC0gMSk7CgkJCWJvdHRvbSA9IFBJWEFERFIoMCwgMCk7CgkJCWVpID0gUElYU1RFUCgwLCAxLCAwLCAwKTsKCQkJZmkgPSBQSVhTVEVQKDEsIDAsIDAsIGxjZF9kbWEueXJlcyAtIDEpOwoJCX0KCQllbiA9IGxjZF9kbWEueXJlczsKCQlmbiA9IGxjZF9kbWEueHJlczsKCQlicmVhazsKCWNhc2UgMTgwOgoJCWlmICghbGNkX2RtYS5taXJyb3IpIHsKCQkJdG9wID0gUElYQUREUihsY2RfZG1hLnhyZXMgLSAxLCBsY2RfZG1hLnlyZXMgLSAxKTsKCQkJYm90dG9tID0gUElYQUREUigwLCAwKTsKCQkJZWkgPSBQSVhTVEVQKDEsIDAsIDAsIDApOwoJCQlmaSA9IFBJWFNURVAoMCwgMSwgbGNkX2RtYS54cmVzIC0gMSwgMCk7CgkJfSBlbHNlIHsKCQkJdG9wID0gUElYQUREUigwLCBsY2RfZG1hLnlyZXMgLSAxKTsKCQkJYm90dG9tID0gUElYQUREUihsY2RfZG1hLnhyZXMgLSAxLCAwKTsKCQkJZWkgPSBQSVhTVEVQKDAsIDAsIDEsIDApOwoJCQlmaSA9IFBJWFNURVAobGNkX2RtYS54cmVzIC0gMSwgMSwgMCwgMCk7CgkJfQoJCWVuID0gbGNkX2RtYS54cmVzOwoJCWZuID0gbGNkX2RtYS55cmVzOwoJCWJyZWFrOwoJY2FzZSAyNzA6CgkJaWYgKCFsY2RfZG1hLm1pcnJvcikgewoJCQl0b3AgPSBQSVhBRERSKGxjZF9kbWEueHJlcyAtIDEsIDApOwoJCQlib3R0b20gPSBQSVhBRERSKDAsIGxjZF9kbWEueXJlcyAtIDEpOwoJCQllaSA9IFBJWFNURVAoMCwgMCwgMCwgMSk7CgkJCWZpID0gUElYU1RFUCgxLCBsY2RfZG1hLnlyZXMgLSAxLCAwLCAwKTsKCQl9IGVsc2UgewoJCQl0b3AgPSBQSVhBRERSKDAsIDApOwoJCQlib3R0b20gPSBQSVhBRERSKGxjZF9kbWEueHJlcyAtIDEsIGxjZF9kbWEueXJlcyAtIDEpOwoJCQllaSA9IFBJWFNURVAoMCwgMCwgMCwgMSk7CgkJCWZpID0gUElYU1RFUCgwLCBsY2RfZG1hLnlyZXMgLSAxLCAxLCAwKTsKCQl9CgkJZW4gPSBsY2RfZG1hLnlyZXM7CgkJZm4gPSBsY2RfZG1hLnhyZXM7CgkJYnJlYWs7CglkZWZhdWx0OgoJCUJVRygpOwoJCXJldHVybjsJLyogU3VwcHJlc3Mgd2FybmluZyBhYm91dCB1bmluaXRpYWxpemVkIHZhcnMgKi8KCX0KCglpZiAob21hcF9kbWFfaW5fMTUxMF9tb2RlKCkpIHsKCQlvbWFwX3dyaXRldyh0b3AgPj4gMTYsIE9NQVAxNTEwX0RNQV9MQ0RfVE9QX0YxX1UpOwoJCW9tYXBfd3JpdGV3KHRvcCwgT01BUDE1MTBfRE1BX0xDRF9UT1BfRjFfTCk7CgkJb21hcF93cml0ZXcoYm90dG9tID4+IDE2LCBPTUFQMTUxMF9ETUFfTENEX0JPVF9GMV9VKTsKCQlvbWFwX3dyaXRldyhib3R0b20sIE9NQVAxNTEwX0RNQV9MQ0RfQk9UX0YxX0wpOwoKCQlyZXR1cm47Cgl9CgoJLyogMTYxMCByZWdzICovCglvbWFwX3dyaXRldyh0b3AgPj4gMTYsIE9NQVAxNjEwX0RNQV9MQ0RfVE9QX0IxX1UpOwoJb21hcF93cml0ZXcodG9wLCBPTUFQMTYxMF9ETUFfTENEX1RPUF9CMV9MKTsKCW9tYXBfd3JpdGV3KGJvdHRvbSA+PiAxNiwgT01BUDE2MTBfRE1BX0xDRF9CT1RfQjFfVSk7CglvbWFwX3dyaXRldyhib3R0b20sIE9NQVAxNjEwX0RNQV9MQ0RfQk9UX0IxX0wpOwoKCW9tYXBfd3JpdGV3KGVuLCBPTUFQMTYxMF9ETUFfTENEX1NSQ19FTl9CMSk7CglvbWFwX3dyaXRldyhmbiwgT01BUDE2MTBfRE1BX0xDRF9TUkNfRk5fQjEpOwoKCXcgPSBvbWFwX3JlYWR3KE9NQVAxNjEwX0RNQV9MQ0RfQ1NEUCk7Cgl3ICY9IH4weDAzOwoJdyB8PSBsY2RfZG1hLmRhdGFfdHlwZTsKCW9tYXBfd3JpdGV3KHcsIE9NQVAxNjEwX0RNQV9MQ0RfQ1NEUCk7CgoJdyA9IG9tYXBfcmVhZHcoT01BUDE2MTBfRE1BX0xDRF9DVFJMKTsKCS8qIEFsd2F5cyBzZXQgdGhlIHNvdXJjZSBwb3J0IGFzIFNEUkFNIGZvciBub3cqLwoJdyAmPSB+KDB4MDMgPDwgNik7CglpZiAobGNkX2RtYS5jYWxsYmFjayAhPSBOVUxMKQoJCXcgfD0gMSA8PCAxOwkJLyogQmxvY2sgaW50ZXJydXB0IGVuYWJsZSAqLwoJZWxzZQoJCXcgJj0gfigxIDw8IDEpOwoJb21hcF93cml0ZXcodywgT01BUDE2MTBfRE1BX0xDRF9DVFJMKTsKCglpZiAoIShsY2RfZG1hLnJvdGF0ZSB8fCBsY2RfZG1hLm1pcnJvciB8fAoJICAgICAgbGNkX2RtYS52eHJlcyB8fCBsY2RfZG1hLnhzY2FsZSB8fCBsY2RfZG1hLnlzY2FsZSkpCgkJcmV0dXJuOwoKCXcgPSBvbWFwX3JlYWR3KE9NQVAxNjEwX0RNQV9MQ0RfQ0NSKTsKCS8qIFNldCB0aGUgZG91YmxlLWluZGV4ZWQgYWRkcmVzc2luZyBtb2RlICovCgl3IHw9ICgweDAzIDw8IDEyKTsKCW9tYXBfd3JpdGV3KHcsIE9NQVAxNjEwX0RNQV9MQ0RfQ0NSKTsKCglvbWFwX3dyaXRldyhlaSwgT01BUDE2MTBfRE1BX0xDRF9TUkNfRUlfQjEpOwoJb21hcF93cml0ZXcoZmkgPj4gMTYsIE9NQVAxNjEwX0RNQV9MQ0RfU1JDX0ZJX0IxX1UpOwoJb21hcF93cml0ZXcoZmksIE9NQVAxNjEwX0RNQV9MQ0RfU1JDX0ZJX0IxX0wpOwp9CgpzdGF0aWMgaXJxcmV0dXJuX3QgbGNkX2RtYV9pcnFfaGFuZGxlcihpbnQgaXJxLCB2b2lkICpkZXZfaWQpCnsKCXUxNiB3OwoKCXcgPSBvbWFwX3JlYWR3KE9NQVAxNjEwX0RNQV9MQ0RfQ1RSTCk7CglpZiAodW5saWtlbHkoISh3ICYgKDEgPDwgMykpKSkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgIlNwdXJpb3VzIExDRCBETUEgSVJRXG4iKTsKCQlyZXR1cm4gSVJRX05PTkU7Cgl9CgkvKiBBY2sgdGhlIElSUSAqLwoJdyB8PSAoMSA8PCAzKTsKCW9tYXBfd3JpdGV3KHcsIE9NQVAxNjEwX0RNQV9MQ0RfQ1RSTCk7CglsY2RfZG1hLmFjdGl2ZSA9IDA7CglpZiAobGNkX2RtYS5jYWxsYmFjayAhPSBOVUxMKQoJCWxjZF9kbWEuY2FsbGJhY2sodywgbGNkX2RtYS5jYl9kYXRhKTsKCglyZXR1cm4gSVJRX0hBTkRMRUQ7Cn0KCmludCBvbWFwX3JlcXVlc3RfbGNkX2RtYSh2b2lkICgqIGNhbGxiYWNrKSh1MTYgc3RhdHVzLCB2b2lkICpkYXRhKSwKCQkJIHZvaWQgKmRhdGEpCnsKCXNwaW5fbG9ja19pcnEoJmxjZF9kbWEubG9jayk7CglpZiAobGNkX2RtYS5yZXNlcnZlZCkgewoJCXNwaW5fdW5sb2NrX2lycSgmbGNkX2RtYS5sb2NrKTsKCQlwcmludGsoS0VSTl9FUlIgIkxDRCBETUEgY2hhbm5lbCBhbHJlYWR5IHJlc2VydmVkXG4iKTsKCQlCVUcoKTsKCQlyZXR1cm4gLUVCVVNZOwoJfQoJbGNkX2RtYS5yZXNlcnZlZCA9IDE7CglzcGluX3VubG9ja19pcnEoJmxjZF9kbWEubG9jayk7CglsY2RfZG1hLmNhbGxiYWNrID0gY2FsbGJhY2s7CglsY2RfZG1hLmNiX2RhdGEgPSBkYXRhOwoJbGNkX2RtYS5hY3RpdmUgPSAwOwoJbGNkX2RtYS5zaW5nbGVfdHJhbnNmZXIgPSAwOwoJbGNkX2RtYS5yb3RhdGUgPSAwOwoJbGNkX2RtYS52eHJlcyA9IDA7CglsY2RfZG1hLm1pcnJvciA9IDA7CglsY2RfZG1hLnhzY2FsZSA9IDA7CglsY2RfZG1hLnlzY2FsZSA9IDA7CglsY2RfZG1hLmV4dF9jdHJsID0gMDsKCWxjZF9kbWEuc3JjX3BvcnQgPSAwOwoKCXJldHVybiAwOwp9Cgp2b2lkIG9tYXBfZnJlZV9sY2RfZG1hKHZvaWQpCnsKCXNwaW5fbG9jaygmbGNkX2RtYS5sb2NrKTsKCWlmICghbGNkX2RtYS5yZXNlcnZlZCkgewoJCXNwaW5fdW5sb2NrKCZsY2RfZG1hLmxvY2spOwoJCXByaW50ayhLRVJOX0VSUiAiTENEIERNQSBpcyBub3QgcmVzZXJ2ZWRcbiIpOwoJCUJVRygpOwoJCXJldHVybjsKCX0KCWlmICghZW5hYmxlXzE1MTBfbW9kZSkKCQlvbWFwX3dyaXRldyhvbWFwX3JlYWR3KE9NQVAxNjEwX0RNQV9MQ0RfQ0NSKSAmIH4xLAoJCQkgICAgT01BUDE2MTBfRE1BX0xDRF9DQ1IpOwoJbGNkX2RtYS5yZXNlcnZlZCA9IDA7CglzcGluX3VubG9jaygmbGNkX2RtYS5sb2NrKTsKfQoKdm9pZCBvbWFwX2VuYWJsZV9sY2RfZG1hKHZvaWQpCnsKCXUxNiB3OwoKCS8qIFNldCB0aGUgRW5hYmxlIGJpdCBvbmx5IGlmIGFuIGV4dGVybmFsIGNvbnRyb2xsZXIgaXMKCSAqIGNvbm5lY3RlZC4gT3RoZXJ3aXNlIHRoZSBPTUFQIGludGVybmFsIGNvbnRyb2xsZXIgd2lsbAoJICogc3RhcnQgdGhlIHRyYW5zZmVyIHdoZW4gaXQgZ2V0cyBlbmFibGVkLgoJICovCglpZiAoZW5hYmxlXzE1MTBfbW9kZSB8fCAhbGNkX2RtYS5leHRfY3RybCkKCQlyZXR1cm47CgoJdyA9IG9tYXBfcmVhZHcoT01BUDE2MTBfRE1BX0xDRF9DVFJMKTsKCXcgfD0gMSA8PCA4OwoJb21hcF93cml0ZXcodywgT01BUDE2MTBfRE1BX0xDRF9DVFJMKTsKCglsY2RfZG1hLmFjdGl2ZSA9IDE7CgoJdyA9IG9tYXBfcmVhZHcoT01BUDE2MTBfRE1BX0xDRF9DQ1IpOwoJdyB8PSAxIDw8IDc7CglvbWFwX3dyaXRldyh3LCBPTUFQMTYxMF9ETUFfTENEX0NDUik7Cn0KCnZvaWQgb21hcF9zZXR1cF9sY2RfZG1hKHZvaWQpCnsKCUJVR19PTihsY2RfZG1hLmFjdGl2ZSk7CglpZiAoIWVuYWJsZV8xNTEwX21vZGUpIHsKCQkvKiBTZXQgc29tZSByZWFzb25hYmxlIGRlZmF1bHRzICovCgkJb21hcF93cml0ZXcoMHg1NDQwLCBPTUFQMTYxMF9ETUFfTENEX0NDUik7CgkJb21hcF93cml0ZXcoMHg5MTAyLCBPTUFQMTYxMF9ETUFfTENEX0NTRFApOwoJCW9tYXBfd3JpdGV3KDB4MDAwNCwgT01BUDE2MTBfRE1BX0xDRF9MQ0hfQ1RSTCk7Cgl9CglzZXRfYjFfcmVncygpOwoJaWYgKCFlbmFibGVfMTUxMF9tb2RlKSB7CgkJdTE2IHc7CgoJCXcgPSBvbWFwX3JlYWR3KE9NQVAxNjEwX0RNQV9MQ0RfQ0NSKTsKCQkvKiBJZiBETUEgd2FzIGFscmVhZHkgYWN0aXZlIHNldCB0aGUgZW5kX3Byb2cgYml0IHRvIGhhdmUKCQkgKiB0aGUgcHJvZ3JhbW1lZCByZWdpc3RlciBzZXQgbG9hZGVkIGludG8gdGhlIGFjdGl2ZQoJCSAqIHJlZ2lzdGVyIHNldC4KCQkgKi8KCQl3IHw9IDEgPDwgMTE7CQkvKiBFbmRfcHJvZyAqLwoJCWlmICghbGNkX2RtYS5zaW5nbGVfdHJhbnNmZXIpCgkgICAgICAgIAl3IHw9ICgzIDw8IDgpOwkvKiBBdXRvX2luaXQsIHJlcGVhdCAqLwoJCW9tYXBfd3JpdGV3KHcsIE9NQVAxNjEwX0RNQV9MQ0RfQ0NSKTsKCX0KfQoKdm9pZCBvbWFwX3N0b3BfbGNkX2RtYSh2b2lkKQp7Cgl1MTYgdzsKCglsY2RfZG1hLmFjdGl2ZSA9IDA7CglpZiAoZW5hYmxlXzE1MTBfbW9kZSB8fCAhbGNkX2RtYS5leHRfY3RybCkKCQlyZXR1cm47CgoJdyA9IG9tYXBfcmVhZHcoT01BUDE2MTBfRE1BX0xDRF9DQ1IpOwoJdyAmPSB+KDEgPDwgNyk7CglvbWFwX3dyaXRldyh3LCBPTUFQMTYxMF9ETUFfTENEX0NDUik7CgoJdyA9IG9tYXBfcmVhZHcoT01BUDE2MTBfRE1BX0xDRF9DVFJMKTsKCXcgJj0gfigxIDw8IDgpOwoJb21hcF93cml0ZXcodywgT01BUDE2MTBfRE1BX0xDRF9DVFJMKTsKfQoKaW50IG9tYXBfbGNkX2RtYV9leHRfcnVubmluZyh2b2lkKQp7CglyZXR1cm4gbGNkX2RtYS5leHRfY3RybCAmJiBsY2RfZG1hLmFjdGl2ZTsKfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCnN0YXRpYyBpbnQgX19pbml0IG9tYXBfaW5pdF9kbWEodm9pZCkKewoJaW50IGNoLCByOwoKCWlmIChjcHVfaXNfb21hcDE1eHgoKSkgewoJCXByaW50ayhLRVJOX0lORk8gIkRNQSBzdXBwb3J0IGZvciBPTUFQMTV4eCBpbml0aWFsaXplZFxuIik7CgkJZG1hX2NoYW5fY291bnQgPSA5OwoJCWVuYWJsZV8xNTEwX21vZGUgPSAxOwoJfSBlbHNlIGlmIChjcHVfaXNfb21hcDE2eHgoKSB8fCBjcHVfaXNfb21hcDczMCgpKSB7CgkJcHJpbnRrKEtFUk5fSU5GTyAiT01BUCBETUEgaGFyZHdhcmUgdmVyc2lvbiAlZFxuIiwKCQkgICAgICAgb21hcF9yZWFkdyhPTUFQX0RNQV9IV19JRCkpOwoJCXByaW50ayhLRVJOX0lORk8gIkRNQSBjYXBhYmlsaXRpZXM6ICUwOHg6JTA4eDolMDR4OiUwNHg6JTA0eFxuIiwKCQkgICAgICAgKG9tYXBfcmVhZHcoT01BUF9ETUFfQ0FQU18wX1UpIDw8IDE2KSB8CgkJICAgICAgIG9tYXBfcmVhZHcoT01BUF9ETUFfQ0FQU18wX0wpLAoJCSAgICAgICAob21hcF9yZWFkdyhPTUFQX0RNQV9DQVBTXzFfVSkgPDwgMTYpIHwKCQkgICAgICAgb21hcF9yZWFkdyhPTUFQX0RNQV9DQVBTXzFfTCksCgkJICAgICAgIG9tYXBfcmVhZHcoT01BUF9ETUFfQ0FQU18yKSwgb21hcF9yZWFkdyhPTUFQX0RNQV9DQVBTXzMpLAoJCSAgICAgICBvbWFwX3JlYWR3KE9NQVBfRE1BX0NBUFNfNCkpOwoJCWlmICghZW5hYmxlXzE1MTBfbW9kZSkgewoJCQl1MTYgdzsKCgkJCS8qIERpc2FibGUgT01BUCAzLjAvMy4xIGNvbXBhdGliaWxpdHkgbW9kZS4gKi8KCQkJdyA9IG9tYXBfcmVhZHcoT01BUF9ETUFfR1NDUik7CgkJCXcgfD0gMSA8PCAzOwoJCQlvbWFwX3dyaXRldyh3LCBPTUFQX0RNQV9HU0NSKTsKCQkJZG1hX2NoYW5fY291bnQgPSAxNjsKCQl9IGVsc2UKCQkJZG1hX2NoYW5fY291bnQgPSA5OwoJCWlmIChjcHVfaXNfb21hcDE2eHgoKSkgewoJCQl1MTYgdzsKCgkJCS8qIHRoaXMgd291bGQgcHJldmVudCBPTUFQIHNsZWVwICovCgkJCXcgPSBvbWFwX3JlYWR3KE9NQVAxNjEwX0RNQV9MQ0RfQ1RSTCk7CgkJCXcgJj0gfigxIDw8IDgpOwoJCQlvbWFwX3dyaXRldyh3LCBPTUFQMTYxMF9ETUFfTENEX0NUUkwpOwoJCX0KCX0gZWxzZSBpZiAoY3B1X2lzX29tYXAyNHh4KCkpIHsKCQl1OCByZXZpc2lvbiA9IG9tYXBfcmVhZGIoT01BUF9ETUE0X1JFVklTSU9OKTsKCQlwcmludGsoS0VSTl9JTkZPICJPTUFQIERNQSBoYXJkd2FyZSByZXZpc2lvbiAlZC4lZFxuIiwKCQkgICAgICAgcmV2aXNpb24gPj4gNCwgcmV2aXNpb24gJiAweGYpOwoJCWRtYV9jaGFuX2NvdW50ID0gT01BUF9MT0dJQ0FMX0RNQV9DSF9DT1VOVDsKCX0gZWxzZSB7CgkJZG1hX2NoYW5fY291bnQgPSAwOwoJCXJldHVybiAwOwoJfQoKCW1lbXNldCgmbGNkX2RtYSwgMCwgc2l6ZW9mKGxjZF9kbWEpKTsKCXNwaW5fbG9ja19pbml0KCZsY2RfZG1hLmxvY2spOwoJc3Bpbl9sb2NrX2luaXQoJmRtYV9jaGFuX2xvY2spOwoJbWVtc2V0KCZkbWFfY2hhbiwgMCwgc2l6ZW9mKGRtYV9jaGFuKSk7CgoJZm9yIChjaCA9IDA7IGNoIDwgZG1hX2NoYW5fY291bnQ7IGNoKyspIHsKCQlvbWFwX2NsZWFyX2RtYShjaCk7CgkJZG1hX2NoYW5bY2hdLmRldl9pZCA9IC0xOwoJCWRtYV9jaGFuW2NoXS5uZXh0X2xjaCA9IC0xOwoKCQlpZiAoY2ggPj0gNiAmJiBlbmFibGVfMTUxMF9tb2RlKQoJCQljb250aW51ZTsKCgkJaWYgKGNwdV9jbGFzc19pc19vbWFwMSgpKSB7CgkJCS8qIHJlcXVlc3RfaXJxKCkgZG9lc24ndCBsaWtlIGRldl9pZCAoaWUuIGNoKSBiZWluZwoJCQkgKiB6ZXJvLCBzbyB3ZSBoYXZlIHRvIGtsdWRnZSBhcm91bmQgdGhpcy4gKi8KCQkJciA9IHJlcXVlc3RfaXJxKG9tYXAxX2RtYV9pcnFbY2hdLAoJCQkJCW9tYXAxX2RtYV9pcnFfaGFuZGxlciwgMCwgIkRNQSIsCgkJCQkJKHZvaWQgKikgKGNoICsgMSkpOwoJCQlpZiAociAhPSAwKSB7CgkJCQlpbnQgaTsKCgkJCQlwcmludGsoS0VSTl9FUlIgInVuYWJsZSB0byByZXF1ZXN0IElSUSAlZCAiCgkJCQkgICAgICAgImZvciBETUEgKGVycm9yICVkKVxuIiwKCQkJCSAgICAgICBvbWFwMV9kbWFfaXJxW2NoXSwgcik7CgkJCQlmb3IgKGkgPSAwOyBpIDwgY2g7IGkrKykKCQkJCQlmcmVlX2lycShvbWFwMV9kbWFfaXJxW2ldLAoJCQkJCQkgKHZvaWQgKikgKGkgKyAxKSk7CgkJCQlyZXR1cm4gcjsKCQkJfQoJCX0KCX0KCglpZiAoY3B1X2lzX29tYXAyNHh4KCkpCgkJc2V0dXBfaXJxKElOVF8yNFhYX1NETUFfSVJRMCwgJm9tYXAyNHh4X2RtYV9pcnEpOwoKCS8qIEZJWE1FOiBVcGRhdGUgTENEIERNQSB0byB3b3JrIG9uIDI0eHggKi8KCWlmIChjcHVfY2xhc3NfaXNfb21hcDEoKSkgewoJCXIgPSByZXF1ZXN0X2lycShJTlRfRE1BX0xDRCwgbGNkX2RtYV9pcnFfaGFuZGxlciwgMCwKCQkJCSJMQ0QgRE1BIiwgTlVMTCk7CgkJaWYgKHIgIT0gMCkgewoJCQlpbnQgaTsKCgkJCXByaW50ayhLRVJOX0VSUiAidW5hYmxlIHRvIHJlcXVlc3QgSVJRIGZvciBMQ0QgRE1BICIKCQkJICAgICAgICIoZXJyb3IgJWQpXG4iLCByKTsKCQkJZm9yIChpID0gMDsgaSA8IGRtYV9jaGFuX2NvdW50OyBpKyspCgkJCQlmcmVlX2lycShvbWFwMV9kbWFfaXJxW2ldLCAodm9pZCAqKSAoaSArIDEpKTsKCQkJcmV0dXJuIHI7CgkJfQoJfQoKCXJldHVybiAwOwp9CgphcmNoX2luaXRjYWxsKG9tYXBfaW5pdF9kbWEpOwoKRVhQT1JUX1NZTUJPTChvbWFwX2dldF9kbWFfc3JjX3Bvcyk7CkVYUE9SVF9TWU1CT0wob21hcF9nZXRfZG1hX2RzdF9wb3MpOwpFWFBPUlRfU1lNQk9MKG9tYXBfZ2V0X2RtYV9zcmNfYWRkcl9jb3VudGVyKTsKRVhQT1JUX1NZTUJPTChvbWFwX2NsZWFyX2RtYSk7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfZG1hX3ByaW9yaXR5KTsKRVhQT1JUX1NZTUJPTChvbWFwX3JlcXVlc3RfZG1hKTsKRVhQT1JUX1NZTUJPTChvbWFwX2ZyZWVfZG1hKTsKRVhQT1JUX1NZTUJPTChvbWFwX3N0YXJ0X2RtYSk7CkVYUE9SVF9TWU1CT0wob21hcF9zdG9wX2RtYSk7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfZG1hX2NhbGxiYWNrKTsKRVhQT1JUX1NZTUJPTChvbWFwX2VuYWJsZV9kbWFfaXJxKTsKRVhQT1JUX1NZTUJPTChvbWFwX2Rpc2FibGVfZG1hX2lycSk7CgpFWFBPUlRfU1lNQk9MKG9tYXBfc2V0X2RtYV90cmFuc2Zlcl9wYXJhbXMpOwpFWFBPUlRfU1lNQk9MKG9tYXBfc2V0X2RtYV9jb2xvcl9tb2RlKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9kbWFfd3JpdGVfbW9kZSk7CgpFWFBPUlRfU1lNQk9MKG9tYXBfc2V0X2RtYV9zcmNfcGFyYW1zKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9kbWFfc3JjX2luZGV4KTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9kbWFfc3JjX2RhdGFfcGFjayk7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfZG1hX3NyY19idXJzdF9tb2RlKTsKCkVYUE9SVF9TWU1CT0wob21hcF9zZXRfZG1hX2Rlc3RfcGFyYW1zKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9kbWFfZGVzdF9pbmRleCk7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfZG1hX2Rlc3RfZGF0YV9wYWNrKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9kbWFfZGVzdF9idXJzdF9tb2RlKTsKCkVYUE9SVF9TWU1CT0wob21hcF9zZXRfZG1hX3BhcmFtcyk7CgpFWFBPUlRfU1lNQk9MKG9tYXBfZG1hX2xpbmtfbGNoKTsKRVhQT1JUX1NZTUJPTChvbWFwX2RtYV91bmxpbmtfbGNoKTsKCkVYUE9SVF9TWU1CT0wob21hcF9yZXF1ZXN0X2xjZF9kbWEpOwpFWFBPUlRfU1lNQk9MKG9tYXBfZnJlZV9sY2RfZG1hKTsKRVhQT1JUX1NZTUJPTChvbWFwX2VuYWJsZV9sY2RfZG1hKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldHVwX2xjZF9kbWEpOwpFWFBPUlRfU1lNQk9MKG9tYXBfc3RvcF9sY2RfZG1hKTsKRVhQT1JUX1NZTUJPTChvbWFwX2xjZF9kbWFfZXh0X3J1bm5pbmcpOwpFWFBPUlRfU1lNQk9MKG9tYXBfc2V0X2xjZF9kbWFfYjEpOwpFWFBPUlRfU1lNQk9MKG9tYXBfc2V0X2xjZF9kbWFfc2luZ2xlX3RyYW5zZmVyKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9sY2RfZG1hX2V4dF9jb250cm9sbGVyKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9sY2RfZG1hX2IxX3JvdGF0aW9uKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9sY2RfZG1hX2IxX3Z4cmVzKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9sY2RfZG1hX2IxX3NjYWxlKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9sY2RfZG1hX2IxX21pcnJvcik7Cgo=