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+ZW5hYmxlZF9pcnFzIHw9IE9NQVAyX0RNQV9NSVNBTElHTkVEX0VSUl9JUlEgfAoJCQlPTUFQMl9ETUFfVFJBTlNfRVJSX0lSUTsKCglpZiAoY3B1X2lzX29tYXAxNnh4KCkpIHsKCQkvKiBJZiB0aGUgc3luYyBkZXZpY2UgaXMgc2V0LCBjb25maWd1cmUgaXQgZHluYW1pY2FsbHkuICovCgkJaWYgKGRldl9pZCAhPSAwKSB7CgkJCXNldF9nZG1hX2RldihmcmVlX2NoICsgMSwgZGV2X2lkKTsKCQkJZGV2X2lkID0gZnJlZV9jaCArIDE7CgkJfQoJCS8qIERpc2FibGUgdGhlIDE1MTAgY29tcGF0aWJpbGl0eSBtb2RlIGFuZCBzZXQgdGhlIHN5bmMgZGV2aWNlCgkJICogaWQuICovCgkJT01BUF9ETUFfQ0NSX1JFRyhmcmVlX2NoKSA9IGRldl9pZCB8ICgxIDw8IDEwKTsKCX0gZWxzZSBpZiAoY3B1X2lzX29tYXA3MzAoKSB8fCBjcHVfaXNfb21hcDE1eHgoKSkgewoJCU9NQVBfRE1BX0NDUl9SRUcoZnJlZV9jaCkgPSBkZXZfaWQ7Cgl9CgoJaWYgKGNwdV9pc19vbWFwMjR4eCgpKSB7CgkJb21hcDJfZW5hYmxlX2lycV9sY2goZnJlZV9jaCk7CgoJCW9tYXBfZW5hYmxlX2NoYW5uZWxfaXJxKGZyZWVfY2gpOwoJCS8qIENsZWFyIHRoZSBDU1IgcmVnaXN0ZXIgYW5kIElSUSBzdGF0dXMgcmVnaXN0ZXIgKi8KCQlPTUFQX0RNQV9DU1JfUkVHKGZyZWVfY2gpID0gT01BUDJfRE1BX0NTUl9DTEVBUl9NQVNLOwoJCW9tYXBfd3JpdGVsKH4weDAsIE9NQVBfRE1BNF9JUlFTVEFUVVNfTDApOwoJfQoKCSpkbWFfY2hfb3V0ID0gZnJlZV9jaDsKCglyZXR1cm4gMDsKfQoKdm9pZCBvbWFwX2ZyZWVfZG1hKGludCBsY2gpCnsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJc3Bpbl9sb2NrX2lycXNhdmUoJmRtYV9jaGFuX2xvY2ssIGZsYWdzKTsKCWlmIChkbWFfY2hhbltsY2hdLmRldl9pZCA9PSAtMSkgewoJCXByaW50aygib21hcF9kbWE6IHRyeWluZyB0byBmcmVlIG5vbmFsbG9jYXRlZCBETUEgY2hhbm5lbCAlZFxuIiwKCQkgICAgICAgbGNoKTsKCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZkbWFfY2hhbl9sb2NrLCBmbGFncyk7CgkJcmV0dXJuOwoJfQoJZG1hX2NoYW5bbGNoXS5kZXZfaWQgPSAtMTsKCWRtYV9jaGFuW2xjaF0ubmV4dF9sY2ggPSAtMTsKCWRtYV9jaGFuW2xjaF0uY2FsbGJhY2sgPSBOVUxMOwoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmZG1hX2NoYW5fbG9jaywgZmxhZ3MpOwoKCWlmIChjcHVfY2xhc3NfaXNfb21hcDEoKSkgewoJCS8qIERpc2FibGUgYWxsIERNQSBpbnRlcnJ1cHRzIGZvciB0aGUgY2hhbm5lbC4gKi8KCQlPTUFQX0RNQV9DSUNSX1JFRyhsY2gpID0gMDsKCQkvKiBNYWtlIHN1cmUgdGhlIERNQSB0cmFuc2ZlciBpcyBzdG9wcGVkLiAqLwoJCU9NQVBfRE1BX0NDUl9SRUcobGNoKSA9IDA7Cgl9CgoJaWYgKGNwdV9pc19vbWFwMjR4eCgpKSB7CgkJdTMyIHZhbDsKCQkvKiBEaXNhYmxlIGludGVycnVwdHMgKi8KCQl2YWwgPSBvbWFwX3JlYWRsKE9NQVBfRE1BNF9JUlFFTkFCTEVfTDApOwoJCXZhbCAmPSB+KDEgPDwgbGNoKTsKCQlvbWFwX3dyaXRlbCh2YWwsIE9NQVBfRE1BNF9JUlFFTkFCTEVfTDApOwoKCQkvKiBDbGVhciB0aGUgQ1NSIHJlZ2lzdGVyIGFuZCBJUlEgc3RhdHVzIHJlZ2lzdGVyICovCgkJT01BUF9ETUFfQ1NSX1JFRyhsY2gpID0gT01BUDJfRE1BX0NTUl9DTEVBUl9NQVNLOwoKCQl2YWwgPSBvbWFwX3JlYWRsKE9NQVBfRE1BNF9JUlFTVEFUVVNfTDApOwoJCXZhbCB8PSAxIDw8IGxjaDsKCQlvbWFwX3dyaXRlbCh2YWwsIE9NQVBfRE1BNF9JUlFTVEFUVVNfTDApOwoKCQkvKiBEaXNhYmxlIGFsbCBETUEgaW50ZXJydXB0cyBmb3IgdGhlIGNoYW5uZWwuICovCgkJT01BUF9ETUFfQ0lDUl9SRUcobGNoKSA9IDA7CgoJCS8qIE1ha2Ugc3VyZSB0aGUgRE1BIHRyYW5zZmVyIGlzIHN0b3BwZWQuICovCgkJT01BUF9ETUFfQ0NSX1JFRyhsY2gpID0gMDsKCQlvbWFwX2NsZWFyX2RtYShsY2gpOwoJfQp9CgovKgogKiBDbGVhcnMgYW55IERNQSBzdGF0ZSBzbyB0aGUgRE1BIGVuZ2luZSBpcyByZWFkeSB0byByZXN0YXJ0IHdpdGggbmV3IGJ1ZmZlcnMKICogdGhyb3VnaCBvbWFwX3N0YXJ0X2RtYSgpLiBBbnkgYnVmZmVycyBpbiBmbGlnaHQgYXJlIGRpc2NhcmRlZC4KICovCnZvaWQgb21hcF9jbGVhcl9kbWEoaW50IGxjaCkKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglsb2NhbF9pcnFfc2F2ZShmbGFncyk7CgoJaWYgKGNwdV9jbGFzc19pc19vbWFwMSgpKSB7CgkJaW50IHN0YXR1czsKCQlPTUFQX0RNQV9DQ1JfUkVHKGxjaCkgJj0gfk9NQVBfRE1BX0NDUl9FTjsKCgkJLyogQ2xlYXIgcGVuZGluZyBpbnRlcnJ1cHRzICovCgkJc3RhdHVzID0gT01BUF9ETUFfQ1NSX1JFRyhsY2gpOwoJfQoKCWlmIChjcHVfaXNfb21hcDI0eHgoKSkgewoJCWludCBpOwoJCXUzMiBsY2hfYmFzZSA9IE9NQVAyNFhYX0RNQV9CQVNFICsgbGNoICogMHg2MCArIDB4ODA7CgkJZm9yIChpID0gMDsgaSA8IDB4NDQ7IGkgKz0gNCkKCQkJb21hcF93cml0ZWwoMCwgbGNoX2Jhc2UgKyBpKTsKCX0KCglsb2NhbF9pcnFfcmVzdG9yZShmbGFncyk7Cn0KCnZvaWQgb21hcF9zdGFydF9kbWEoaW50IGxjaCkKewoJaWYgKCFvbWFwX2RtYV9pbl8xNTEwX21vZGUoKSAmJiBkbWFfY2hhbltsY2hdLm5leHRfbGNoICE9IC0xKSB7CgkJaW50IG5leHRfbGNoLCBjdXJfbGNoOwoJCWNoYXIgZG1hX2NoYW5fbGlua19tYXBbT01BUF9MT0dJQ0FMX0RNQV9DSF9DT1VOVF07CgoJCWRtYV9jaGFuX2xpbmtfbWFwW2xjaF0gPSAxOwoJCS8qIFNldCB0aGUgbGluayByZWdpc3RlciBvZiB0aGUgZmlyc3QgY2hhbm5lbCAqLwoJCWVuYWJsZV9sbmsobGNoKTsKCgkJbWVtc2V0KGRtYV9jaGFuX2xpbmtfbWFwLCAwLCBzaXplb2YoZG1hX2NoYW5fbGlua19tYXApKTsKCQljdXJfbGNoID0gZG1hX2NoYW5bbGNoXS5uZXh0X2xjaDsKCQlkbyB7CgkJCW5leHRfbGNoID0gZG1hX2NoYW5bY3VyX2xjaF0ubmV4dF9sY2g7CgoJCQkvKiBUaGUgbG9vcCBjYXNlOiB3ZSd2ZSBiZWVuIGhlcmUgYWxyZWFkeSAqLwoJCQlpZiAoZG1hX2NoYW5fbGlua19tYXBbY3VyX2xjaF0pCgkJCQlicmVhazsKCQkJLyogTWFyayB0aGUgY3VycmVudCBjaGFubmVsICovCgkJCWRtYV9jaGFuX2xpbmtfbWFwW2N1cl9sY2hdID0gMTsKCgkJCWVuYWJsZV9sbmsoY3VyX2xjaCk7CgkJCW9tYXBfZW5hYmxlX2NoYW5uZWxfaXJxKGN1cl9sY2gpOwoKCQkJY3VyX2xjaCA9IG5leHRfbGNoOwoJCX0gd2hpbGUgKG5leHRfbGNoICE9IC0xKTsKCX0gZWxzZSBpZiAoY3B1X2lzX29tYXAyNHh4KCkpIHsKCQkvKiBFcnJhdGE6IE5lZWQgdG8gd3JpdGUgbGNoIGV2ZW4gaWYgbm90IHVzaW5nIGNoYWluaW5nICovCgkJT01BUF9ETUFfQ0xOS19DVFJMX1JFRyhsY2gpID0gbGNoOwoJfQoKCW9tYXBfZW5hYmxlX2NoYW5uZWxfaXJxKGxjaCk7CgoJLyogRXJyYXRhOiBPbiBFUzIuMCBCVUZGRVJJTkcgZGlzYWJsZSBtdXN0IGJlIHNldC4KCSAqIFRoaXMgd2lsbCBhbHdheXMgZmFpbCBvbiBFUzEuMCAqLwoJaWYgKGNwdV9pc19vbWFwMjR4eCgpKSB7CgkJT01BUF9ETUFfQ0NSX1JFRyhsY2gpIHw9IE9NQVBfRE1BX0NDUl9FTjsKCX0KCglPTUFQX0RNQV9DQ1JfUkVHKGxjaCkgfD0gT01BUF9ETUFfQ0NSX0VOOwoKCWRtYV9jaGFuW2xjaF0uZmxhZ3MgfD0gT01BUF9ETUFfQUNUSVZFOwp9Cgp2b2lkIG9tYXBfc3RvcF9kbWEoaW50IGxjaCkKewoJaWYgKCFvbWFwX2RtYV9pbl8xNTEwX21vZGUoKSAmJiBkbWFfY2hhbltsY2hdLm5leHRfbGNoICE9IC0xKSB7CgkJaW50IG5leHRfbGNoLCBjdXJfbGNoID0gbGNoOwoJCWNoYXIgZG1hX2NoYW5fbGlua19tYXBbT01BUF9MT0dJQ0FMX0RNQV9DSF9DT1VOVF07CgoJCW1lbXNldChkbWFfY2hhbl9saW5rX21hcCwgMCwgc2l6ZW9mKGRtYV9jaGFuX2xpbmtfbWFwKSk7CgkJZG8gewoJCQkvKiBUaGUgbG9vcCBjYXNlOiB3ZSd2ZSBiZWVuIGhlcmUgYWxyZWFkeSAqLwoJCQlpZiAoZG1hX2NoYW5fbGlua19tYXBbY3VyX2xjaF0pCgkJCQlicmVhazsKCQkJLyogTWFyayB0aGUgY3VycmVudCBjaGFubmVsICovCgkJCWRtYV9jaGFuX2xpbmtfbWFwW2N1cl9sY2hdID0gMTsKCgkJCWRpc2FibGVfbG5rKGN1cl9sY2gpOwoKCQkJbmV4dF9sY2ggPSBkbWFfY2hhbltjdXJfbGNoXS5uZXh0X2xjaDsKCQkJY3VyX2xjaCA9IG5leHRfbGNoOwoJCX0gd2hpbGUgKG5leHRfbGNoICE9IC0xKTsKCgkJcmV0dXJuOwoJfQoKCS8qIERpc2FibGUgYWxsIGludGVycnVwdHMgb24gdGhlIGNoYW5uZWwgKi8KCWlmIChjcHVfY2xhc3NfaXNfb21hcDEoKSkKCQlPTUFQX0RNQV9DSUNSX1JFRyhsY2gpID0gMDsKCglPTUFQX0RNQV9DQ1JfUkVHKGxjaCkgJj0gfk9NQVBfRE1BX0NDUl9FTjsKCWRtYV9jaGFuW2xjaF0uZmxhZ3MgJj0gfk9NQVBfRE1BX0FDVElWRTsKfQoKLyoKICogQWxsb3dzIGNoYW5naW5nIHRoZSBETUEgY2FsbGJhY2sgZnVuY3Rpb24gb3IgZGF0YS4gVGhpcyBtYXkgYmUgbmVlZGVkIGlmCiAqIHRoZSBkcml2ZXIgc2hhcmVzIGEgc2luZ2xlIERNQSBjaGFubmVsIGZvciBtdWx0aXBsZSBkbWEgdHJpZ2dlcnMuCiAqLwppbnQgb21hcF9zZXRfZG1hX2NhbGxiYWNrKGludCBsY2gsCgkJCSAgdm9pZCAoKiBjYWxsYmFjaykoaW50IGxjaCwgdTE2IGNoX3N0YXR1cywgdm9pZCAqZGF0YSksCgkJCSAgdm9pZCAqZGF0YSkKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglpZiAobGNoIDwgMCkKCQlyZXR1cm4gLUVOT0RFVjsKCglzcGluX2xvY2tfaXJxc2F2ZSgmZG1hX2NoYW5fbG9jaywgZmxhZ3MpOwoJaWYgKGRtYV9jaGFuW2xjaF0uZGV2X2lkID09IC0xKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJETUEgY2FsbGJhY2sgZm9yIG5vdCBzZXQgZm9yIGZyZWUgY2hhbm5lbFxuIik7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmZG1hX2NoYW5fbG9jaywgZmxhZ3MpOwoJCXJldHVybiAtRUlOVkFMOwoJfQoJZG1hX2NoYW5bbGNoXS5jYWxsYmFjayA9IGNhbGxiYWNrOwoJZG1hX2NoYW5bbGNoXS5kYXRhID0gZGF0YTsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmRtYV9jaGFuX2xvY2ssIGZsYWdzKTsKCglyZXR1cm4gMDsKfQoKLyoKICogUmV0dXJucyBjdXJyZW50IHBoeXNpY2FsIHNvdXJjZSBhZGRyZXNzIGZvciB0aGUgZ2l2ZW4gRE1BIGNoYW5uZWwuCiAqIElmIHRoZSBjaGFubmVsIGlzIHJ1bm5pbmcgdGhlIGNhbGxlciBtdXN0IGRpc2FibGUgaW50ZXJydXB0cyBwcmlvciBjYWxsaW5nCiAqIHRoaXMgZnVuY3Rpb24gYW5kIHByb2Nlc3MgdGhlIHJldHVybmVkIHZhbHVlIGJlZm9yZSByZS1lbmFibGluZyBpbnRlcnJ1cHQgdG8KICogcHJldmVudCByYWNlcyB3aXRoIHRoZSBpbnRlcnJ1cHQgaGFuZGxlci4gTm90ZSB0aGF0IGluIGNvbnRpbnVvdXMgbW9kZSB0aGVyZQogKiBpcyBhIGNoYW5jZSBmb3IgQ1NTQV9MIHJlZ2lzdGVyIG92ZXJmbG93IGluYmV0d2VlbiB0aGUgdHdvIHJlYWRzIHJlc3VsdGluZwogKiBpbiBpbmNvcnJlY3QgcmV0dXJuIHZhbHVlLgogKi8KZG1hX2FkZHJfdCBvbWFwX2dldF9kbWFfc3JjX3BvcyhpbnQgbGNoKQp7CglkbWFfYWRkcl90IG9mZnNldDsKCglpZiAoY3B1X2NsYXNzX2lzX29tYXAxKCkpCgkJb2Zmc2V0ID0gKGRtYV9hZGRyX3QpIChPTUFQMV9ETUFfQ1NTQV9MX1JFRyhsY2gpIHwKCQkJCSAgICAgICAoT01BUDFfRE1BX0NTU0FfVV9SRUcobGNoKSA8PCAxNikpOwoKCWlmIChjcHVfaXNfb21hcDI0eHgoKSkKCQlvZmZzZXQgPSBPTUFQX0RNQV9DU0FDX1JFRyhsY2gpOwoKCXJldHVybiBvZmZzZXQ7Cn0KCi8qCiAqIFJldHVybnMgY3VycmVudCBwaHlzaWNhbCBkZXN0aW5hdGlvbiBhZGRyZXNzIGZvciB0aGUgZ2l2ZW4gRE1BIGNoYW5uZWwuCiAqIElmIHRoZSBjaGFubmVsIGlzIHJ1bm5pbmcgdGhlIGNhbGxlciBtdXN0IGRpc2FibGUgaW50ZXJydXB0cyBwcmlvciBjYWxsaW5nCiAqIHRoaXMgZnVuY3Rpb24gYW5kIHByb2Nlc3MgdGhlIHJldHVybmVkIHZhbHVlIGJlZm9yZSByZS1lbmFibGluZyBpbnRlcnJ1cHQgdG8KICogcHJldmVudCByYWNlcyB3aXRoIHRoZSBpbnRlcnJ1cHQgaGFuZGxlci4gTm90ZSB0aGF0IGluIGNvbnRpbnVvdXMgbW9kZSB0aGVyZQogKiBpcyBhIGNoYW5jZSBmb3IgQ0RTQV9MIHJlZ2lzdGVyIG92ZXJmbG93IGluYmV0d2VlbiB0aGUgdHdvIHJlYWRzIHJlc3VsdGluZwogKiBpbiBpbmNvcnJlY3QgcmV0dXJuIHZhbHVlLgogKi8KZG1hX2FkZHJfdCBvbWFwX2dldF9kbWFfZHN0X3BvcyhpbnQgbGNoKQp7CglkbWFfYWRkcl90IG9mZnNldDsKCglpZiAoY3B1X2NsYXNzX2lzX29tYXAxKCkpCgkJb2Zmc2V0ID0gKGRtYV9hZGRyX3QpIChPTUFQMV9ETUFfQ0RTQV9MX1JFRyhsY2gpIHwKCQkJCSAgICAgICAoT01BUDFfRE1BX0NEU0FfVV9SRUcobGNoKSA8PCAxNikpOwoKCWlmIChjcHVfaXNfb21hcDI0eHgoKSkKCQlvZmZzZXQgPSBPTUFQMl9ETUFfQ0RTQV9SRUcobGNoKTsKCglyZXR1cm4gb2Zmc2V0Owp9CgovKgogKiBSZXR1cm5zIGN1cnJlbnQgc291cmNlIHRyYW5zZmVyIGNvdW50aW5nIGZvciB0aGUgZ2l2ZW4gRE1BIGNoYW5uZWwuCiAqIENhbiBiZSB1c2VkIHRvIG1vbml0b3IgdGhlIHByb2dyZXNzIG9mIGEgdHJhbnNmZXIgaW5zaWRlIGEgYmxvY2suCiAqIEl0IG11c3QgYmUgY2FsbGVkIHdpdGggZGlzYWJsZWQgaW50ZXJydXB0cy4KICovCmludCBvbWFwX2dldF9kbWFfc3JjX2FkZHJfY291bnRlcihpbnQgbGNoKQp7CglyZXR1cm4gKGRtYV9hZGRyX3QpIE9NQVBfRE1BX0NTQUNfUkVHKGxjaCk7Cn0KCmludCBvbWFwX2RtYV9ydW5uaW5nKHZvaWQpCnsKCWludCBsY2g7CgoJLyogQ2hlY2sgaWYgTENEIERNQSBpcyBydW5uaW5nICovCglpZiAoY3B1X2lzX29tYXAxNnh4KCkpCgkJaWYgKG9tYXBfcmVhZHcoT01BUDE2MTBfRE1BX0xDRF9DQ1IpICYgT01BUF9ETUFfQ0NSX0VOKQoJCQlyZXR1cm4gMTsKCglmb3IgKGxjaCA9IDA7IGxjaCA8IGRtYV9jaGFuX2NvdW50OyBsY2grKykKCQlpZiAoT01BUF9ETUFfQ0NSX1JFRyhsY2gpICYgT01BUF9ETUFfQ0NSX0VOKQoJCQlyZXR1cm4gMTsKCglyZXR1cm4gMDsKfQoKLyoKICogbGNoX3F1ZXVlIERNQSB3aWxsIHN0YXJ0IHJpZ2h0IGFmdGVyIGxjaF9oZWFkIG9uZSBpcyBmaW5pc2hlZC4KICogRm9yIHRoaXMgRE1BIGxpbmsgdG8gc3RhcnQsIHlvdSBzdGlsbCBuZWVkIHRvIHN0YXJ0IChzZWUgb21hcF9zdGFydF9kbWEpCiAqIHRoZSBmaXJzdCBvbmUuIFRoYXQgd2lsbCBmaXJlIHVwIHRoZSBlbnRpcmUgcXVldWUuCiAqLwp2b2lkIG9tYXBfZG1hX2xpbmtfbGNoIChpbnQgbGNoX2hlYWQsIGludCBsY2hfcXVldWUpCnsKCWlmIChvbWFwX2RtYV9pbl8xNTEwX21vZGUoKSkgewoJCXByaW50ayhLRVJOX0VSUiAiRE1BIGxpbmtpbmcgaXMgbm90IHN1cHBvcnRlZCBpbiAxNTEwIG1vZGVcbiIpOwoJCUJVRygpOwoJCXJldHVybjsKCX0KCglpZiAoKGRtYV9jaGFuW2xjaF9oZWFkXS5kZXZfaWQgPT0gLTEpIHx8CgkgICAgKGRtYV9jaGFuW2xjaF9xdWV1ZV0uZGV2X2lkID09IC0xKSkgewoJCXByaW50ayhLRVJOX0VSUiAib21hcF9kbWE6IHRyeWluZyB0byBsaW5rICIKCQkgICAgICAgIm5vbiByZXF1ZXN0ZWQgY2hhbm5lbHNcbiIpOwoJCWR1bXBfc3RhY2soKTsKCX0KCglkbWFfY2hhbltsY2hfaGVhZF0ubmV4dF9sY2ggPSBsY2hfcXVldWU7Cn0KCi8qCiAqIE9uY2UgdGhlIERNQSBxdWV1ZSBpcyBzdG9wcGVkLCB3ZSBjYW4gZGVzdHJveSBpdC4KICovCnZvaWQgb21hcF9kbWFfdW5saW5rX2xjaCAoaW50IGxjaF9oZWFkLCBpbnQgbGNoX3F1ZXVlKQp7CglpZiAob21hcF9kbWFfaW5fMTUxMF9tb2RlKCkpIHsKCQlwcmludGsoS0VSTl9FUlIgIkRNQSBsaW5raW5nIGlzIG5vdCBzdXBwb3J0ZWQgaW4gMTUxMCBtb2RlXG4iKTsKCQlCVUcoKTsKCQlyZXR1cm47Cgl9CgoJaWYgKGRtYV9jaGFuW2xjaF9oZWFkXS5uZXh0X2xjaCAhPSBsY2hfcXVldWUgfHwKCSAgICBkbWFfY2hhbltsY2hfaGVhZF0ubmV4dF9sY2ggPT0gLTEpIHsKCQlwcmludGsoS0VSTl9FUlIgIm9tYXBfZG1hOiB0cnlpbmcgdG8gdW5saW5rICIKCQkgICAgICAgIm5vbiBsaW5rZWQgY2hhbm5lbHNcbiIpOwoJCWR1bXBfc3RhY2soKTsKCX0KCgoJaWYgKChkbWFfY2hhbltsY2hfaGVhZF0uZmxhZ3MgJiBPTUFQX0RNQV9BQ1RJVkUpIHx8CgkgICAgKGRtYV9jaGFuW2xjaF9oZWFkXS5mbGFncyAmIE9NQVBfRE1BX0FDVElWRSkpIHsKCQlwcmludGsoS0VSTl9FUlIgIm9tYXBfZG1hOiBZb3UgbmVlZCB0byBzdG9wIHRoZSBETUEgY2hhbm5lbHMgIgoJCSAgICAgICAiYmVmb3JlIHVubGlua2luZ1xuIik7CgkJZHVtcF9zdGFjaygpOwoJfQoKCWRtYV9jaGFuW2xjaF9oZWFkXS5uZXh0X2xjaCA9IC0xOwp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKI2lmZGVmIENPTkZJR19BUkNIX09NQVAxCgpzdGF0aWMgaW50IG9tYXAxX2RtYV9oYW5kbGVfY2goaW50IGNoKQp7Cgl1MTYgY3NyOwoKCWlmIChlbmFibGVfMTUxMF9tb2RlICYmIGNoID49IDYpIHsKCQljc3IgPSBkbWFfY2hhbltjaF0uc2F2ZWRfY3NyOwoJCWRtYV9jaGFuW2NoXS5zYXZlZF9jc3IgPSAwOwoJfSBlbHNlCgkJY3NyID0gT01BUF9ETUFfQ1NSX1JFRyhjaCk7CglpZiAoZW5hYmxlXzE1MTBfbW9kZSAmJiBjaCA8PSAyICYmIChjc3IgPj4gNykgIT0gMCkgewoJCWRtYV9jaGFuW2NoICsgNl0uc2F2ZWRfY3NyID0gY3NyID4+IDc7CgkJY3NyICY9IDB4N2Y7Cgl9CglpZiAoKGNzciAmIDB4M2YpID09IDApCgkJcmV0dXJuIDA7CglpZiAodW5saWtlbHkoZG1hX2NoYW5bY2hdLmRldl9pZCA9PSAtMSkpIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJTcHVyaW91cyBpbnRlcnJ1cHQgZnJvbSBETUEgY2hhbm5lbCAiCgkJICAgICAgICIlZCAoQ1NSICUwNHgpXG4iLCBjaCwgY3NyKTsKCQlyZXR1cm4gMDsKCX0KCWlmICh1bmxpa2VseShjc3IgJiBPTUFQMV9ETUFfVE9VVF9JUlEpKQoJCXByaW50ayhLRVJOX1dBUk5JTkcgIkRNQSB0aW1lb3V0IHdpdGggZGV2aWNlICVkXG4iLAoJCSAgICAgICBkbWFfY2hhbltjaF0uZGV2X2lkKTsKCWlmICh1bmxpa2VseShjc3IgJiBPTUFQX0RNQV9EUk9QX0lSUSkpCgkJcHJpbnRrKEtFUk5fV0FSTklORyAiRE1BIHN5bmNocm9uaXphdGlvbiBldmVudCBkcm9wIG9jY3VycmVkICIKCQkgICAgICAgIndpdGggZGV2aWNlICVkXG4iLCBkbWFfY2hhbltjaF0uZGV2X2lkKTsKCWlmIChsaWtlbHkoY3NyICYgT01BUF9ETUFfQkxPQ0tfSVJRKSkKCQlkbWFfY2hhbltjaF0uZmxhZ3MgJj0gfk9NQVBfRE1BX0FDVElWRTsKCWlmIChsaWtlbHkoZG1hX2NoYW5bY2hdLmNhbGxiYWNrICE9IE5VTEwpKQoJCWRtYV9jaGFuW2NoXS5jYWxsYmFjayhjaCwgY3NyLCBkbWFfY2hhbltjaF0uZGF0YSk7CglyZXR1cm4gMTsKfQoKc3RhdGljIGlycXJldHVybl90IG9tYXAxX2RtYV9pcnFfaGFuZGxlcihpbnQgaXJxLCB2b2lkICpkZXZfaWQpCnsKCWludCBjaCA9ICgoaW50KSBkZXZfaWQpIC0gMTsKCWludCBoYW5kbGVkID0gMDsKCglmb3IgKDs7KSB7CgkJaW50IGhhbmRsZWRfbm93ID0gMDsKCgkJaGFuZGxlZF9ub3cgKz0gb21hcDFfZG1hX2hhbmRsZV9jaChjaCk7CgkJaWYgKGVuYWJsZV8xNTEwX21vZGUgJiYgZG1hX2NoYW5bY2ggKyA2XS5zYXZlZF9jc3IpCgkJCWhhbmRsZWRfbm93ICs9IG9tYXAxX2RtYV9oYW5kbGVfY2goY2ggKyA2KTsKCQlpZiAoIWhhbmRsZWRfbm93KQoJCQlicmVhazsKCQloYW5kbGVkICs9IGhhbmRsZWRfbm93OwoJfQoKCXJldHVybiBoYW5kbGVkID8gSVJRX0hBTkRMRUQgOiBJUlFfTk9ORTsKfQoKI2Vsc2UKI2RlZmluZSBvbWFwMV9kbWFfaXJxX2hhbmRsZXIJTlVMTAojZW5kaWYKCiNpZmRlZiBDT05GSUdfQVJDSF9PTUFQMgoKc3RhdGljIGludCBvbWFwMl9kbWFfaGFuZGxlX2NoKGludCBjaCkKewoJdTMyIHN0YXR1cyA9IE9NQVBfRE1BX0NTUl9SRUcoY2gpOwoJdTMyIHZhbDsKCglpZiAoIXN0YXR1cykKCQlyZXR1cm4gMDsKCWlmICh1bmxpa2VseShkbWFfY2hhbltjaF0uZGV2X2lkID09IC0xKSkKCQlyZXR1cm4gMDsKCWlmICh1bmxpa2VseShzdGF0dXMgJiBPTUFQX0RNQV9EUk9QX0lSUSkpCgkJcHJpbnRrKEtFUk5fSU5GTwoJCSAgICAgICAiRE1BIHN5bmNocm9uaXphdGlvbiBldmVudCBkcm9wIG9jY3VycmVkIHdpdGggZGV2aWNlICIKCQkgICAgICAgIiVkXG4iLCBkbWFfY2hhbltjaF0uZGV2X2lkKTsKCWlmICh1bmxpa2VseShzdGF0dXMgJiBPTUFQMl9ETUFfVFJBTlNfRVJSX0lSUSkpCgkJcHJpbnRrKEtFUk5fSU5GTyAiRE1BIHRyYW5zYWN0aW9uIGVycm9yIHdpdGggZGV2aWNlICVkXG4iLAoJCSAgICAgICBkbWFfY2hhbltjaF0uZGV2X2lkKTsKCWlmICh1bmxpa2VseShzdGF0dXMgJiBPTUFQMl9ETUFfU0VDVVJFX0VSUl9JUlEpKQoJCXByaW50ayhLRVJOX0lORk8gIkRNQSBzZWN1cmUgZXJyb3Igd2l0aCBkZXZpY2UgJWRcbiIsCgkJICAgICAgIGRtYV9jaGFuW2NoXS5kZXZfaWQpOwoJaWYgKHVubGlrZWx5KHN0YXR1cyAmIE9NQVAyX0RNQV9NSVNBTElHTkVEX0VSUl9JUlEpKQoJCXByaW50ayhLRVJOX0lORk8gIkRNQSBtaXNhbGlnbmVkIGVycm9yIHdpdGggZGV2aWNlICVkXG4iLAoJCSAgICAgICBkbWFfY2hhbltjaF0uZGV2X2lkKTsKCglPTUFQX0RNQV9DU1JfUkVHKGNoKSA9IE9NQVAyX0RNQV9DU1JfQ0xFQVJfTUFTSzsKCgl2YWwgPSBvbWFwX3JlYWRsKE9NQVBfRE1BNF9JUlFTVEFUVVNfTDApOwoJLyogY2ggaW4gdGhpcyBmdW5jdGlvbiBpcyBmcm9tIDAtMzEgd2hpbGUgaW4gcmVnaXN0ZXIgaXQgaXMgMS0zMiAqLwoJdmFsID0gMSA8PCAoY2gpOwoJb21hcF93cml0ZWwodmFsLCBPTUFQX0RNQTRfSVJRU1RBVFVTX0wwKTsKCglpZiAobGlrZWx5KGRtYV9jaGFuW2NoXS5jYWxsYmFjayAhPSBOVUxMKSkKCQlkbWFfY2hhbltjaF0uY2FsbGJhY2soY2gsIHN0YXR1cywgZG1hX2NoYW5bY2hdLmRhdGEpOwoKCXJldHVybiAwOwp9CgovKiBTVEFUVVMgcmVnaXN0ZXIgY291bnQgaXMgZnJvbSAxLTMyIHdoaWxlIG91ciBpcyAwLTMxICovCnN0YXRpYyBpcnFyZXR1cm5fdCBvbWFwMl9kbWFfaXJxX2hhbmRsZXIoaW50IGlycSwgdm9pZCAqZGV2X2lkKQp7Cgl1MzIgdmFsOwoJaW50IGk7CgoJdmFsID0gb21hcF9yZWFkbChPTUFQX0RNQTRfSVJRU1RBVFVTX0wwKTsKCglmb3IgKGkgPSAxOyBpIDw9IE9NQVBfTE9HSUNBTF9ETUFfQ0hfQ09VTlQ7IGkrKykgewoJCWludCBhY3RpdmUgPSB2YWwgJiAoMSA8PCAoaSAtIDEpKTsKCQlpZiAoYWN0aXZlKQoJCQlvbWFwMl9kbWFfaGFuZGxlX2NoKGkgLSAxKTsKCX0KCglyZXR1cm4gSVJRX0hBTkRMRUQ7Cn0KCnN0YXRpYyBzdHJ1Y3QgaXJxYWN0aW9uIG9tYXAyNHh4X2RtYV9pcnEgPSB7CgkubmFtZSA9ICJETUEiLAoJLmhhbmRsZXIgPSBvbWFwMl9kbWFfaXJxX2hhbmRsZXIsCgkuZmxhZ3MgPSBJUlFGX0RJU0FCTEVECn07CgojZWxzZQpzdGF0aWMgc3RydWN0IGlycWFjdGlvbiBvbWFwMjR4eF9kbWFfaXJxOwojZW5kaWYKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgpzdGF0aWMgc3RydWN0IGxjZF9kbWFfaW5mbyB7CglzcGlubG9ja190IGxvY2s7CglpbnQgcmVzZXJ2ZWQ7Cgl2b2lkICgqIGNhbGxiYWNrKSh1MTYgc3RhdHVzLCB2b2lkICpkYXRhKTsKCXZvaWQgKmNiX2RhdGE7CgoJaW50IGFjdGl2ZTsKCXVuc2lnbmVkIGxvbmcgYWRkciwgc2l6ZTsKCWludCByb3RhdGUsIGRhdGFfdHlwZSwgeHJlcywgeXJlczsKCWludCB2eHJlczsKCWludCBtaXJyb3I7CglpbnQgeHNjYWxlLCB5c2NhbGU7CglpbnQgZXh0X2N0cmw7CglpbnQgc3JjX3BvcnQ7CglpbnQgc2luZ2xlX3RyYW5zZmVyOwp9IGxjZF9kbWE7Cgp2b2lkIG9tYXBfc2V0X2xjZF9kbWFfYjEodW5zaWduZWQgbG9uZyBhZGRyLCB1MTYgZmJfeHJlcywgdTE2IGZiX3lyZXMsCgkJCSBpbnQgZGF0YV90eXBlKQp7CglsY2RfZG1hLmFkZHIgPSBhZGRyOwoJbGNkX2RtYS5kYXRhX3R5cGUgPSBkYXRhX3R5cGU7CglsY2RfZG1hLnhyZXMgPSBmYl94cmVzOwoJbGNkX2RtYS55cmVzID0gZmJfeXJlczsKfQoKdm9pZCBvbWFwX3NldF9sY2RfZG1hX3NyY19wb3J0KGludCBwb3J0KQp7CglsY2RfZG1hLnNyY19wb3J0ID0gcG9ydDsKfQoKdm9pZCBvbWFwX3NldF9sY2RfZG1hX2V4dF9jb250cm9sbGVyKGludCBleHRlcm5hbCkKewoJbGNkX2RtYS5leHRfY3RybCA9IGV4dGVybmFsOwp9Cgp2b2lkIG9tYXBfc2V0X2xjZF9kbWFfc2luZ2xlX3RyYW5zZmVyKGludCBzaW5nbGUpCnsKCWxjZF9kbWEuc2luZ2xlX3RyYW5zZmVyID0gc2luZ2xlOwp9CgoKdm9pZCBvbWFwX3NldF9sY2RfZG1hX2IxX3JvdGF0aW9uKGludCByb3RhdGUpCnsKCWlmIChvbWFwX2RtYV9pbl8xNTEwX21vZGUoKSkgewoJCXByaW50ayhLRVJOX0VSUiAiRE1BIHJvdGF0aW9uIGlzIG5vdCBzdXBwb3J0ZWQgaW4gMTUxMCBtb2RlXG4iKTsKCQlCVUcoKTsKCQlyZXR1cm47Cgl9CglsY2RfZG1hLnJvdGF0ZSA9IHJvdGF0ZTsKfQoKdm9pZCBvbWFwX3NldF9sY2RfZG1hX2IxX21pcnJvcihpbnQgbWlycm9yKQp7CglpZiAob21hcF9kbWFfaW5fMTUxMF9tb2RlKCkpIHsKCQlwcmludGsoS0VSTl9FUlIgIkRNQSBtaXJyb3IgaXMgbm90IHN1cHBvcnRlZCBpbiAxNTEwIG1vZGVcbiIpOwoJCUJVRygpOwoJfQoJbGNkX2RtYS5taXJyb3IgPSBtaXJyb3I7Cn0KCnZvaWQgb21hcF9zZXRfbGNkX2RtYV9iMV92eHJlcyh1bnNpZ25lZCBsb25nIHZ4cmVzKQp7CglpZiAob21hcF9kbWFfaW5fMTUxMF9tb2RlKCkpIHsKCQlwcmludGsoS0VSTl9FUlIgIkRNQSB2aXJ0dWFsIHJlc3Vsb3Rpb24gaXMgbm90IHN1cHBvcnRlZCAiCgkJCQkiaW4gMTUxMCBtb2RlXG4iKTsKCQlCVUcoKTsKCX0KCWxjZF9kbWEudnhyZXMgPSB2eHJlczsKfQoKdm9pZCBvbWFwX3NldF9sY2RfZG1hX2IxX3NjYWxlKHVuc2lnbmVkIGludCB4c2NhbGUsIHVuc2lnbmVkIGludCB5c2NhbGUpCnsKCWlmIChvbWFwX2RtYV9pbl8xNTEwX21vZGUoKSkgewoJCXByaW50ayhLRVJOX0VSUiAiRE1BIHNjYWxlIGlzIG5vdCBzdXBwb3J0ZWQgaW4gMTUxMCBtb2RlXG4iKTsKCQlCVUcoKTsKCX0KCWxjZF9kbWEueHNjYWxlID0geHNjYWxlOwoJbGNkX2RtYS55c2NhbGUgPSB5c2NhbGU7Cn0KCnN0YXRpYyB2b2lkIHNldF9iMV9yZWdzKHZvaWQpCnsKCXVuc2lnbmVkIGxvbmcgdG9wLCBib3R0b207CglpbnQgZXM7Cgl1MTYgdzsKCXVuc2lnbmVkIGxvbmcgZW4sIGZuOwoJbG9uZyBlaSwgZmk7Cgl1bnNpZ25lZCBsb25nIHZ4cmVzOwoJdW5zaWduZWQgaW50IHhzY2FsZSwgeXNjYWxlOwoKCXN3aXRjaCAobGNkX2RtYS5kYXRhX3R5cGUpIHsKCWNhc2UgT01BUF9ETUFfREFUQV9UWVBFX1M4OgoJCWVzID0gMTsKCQlicmVhazsKCWNhc2UgT01BUF9ETUFfREFUQV9UWVBFX1MxNjoKCQllcyA9IDI7CgkJYnJlYWs7CgljYXNlIE9NQVBfRE1BX0RBVEFfVFlQRV9TMzI6CgkJZXMgPSA0OwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlCVUcoKTsKCQlyZXR1cm47Cgl9CgoJdnhyZXMgPSBsY2RfZG1hLnZ4cmVzID8gbGNkX2RtYS52eHJlcyA6IGxjZF9kbWEueHJlczsKCXhzY2FsZSA9IGxjZF9kbWEueHNjYWxlID8gbGNkX2RtYS54c2NhbGUgOiAxOwoJeXNjYWxlID0gbGNkX2RtYS55c2NhbGUgPyBsY2RfZG1hLnlzY2FsZSA6IDE7CglCVUdfT04odnhyZXMgPCBsY2RfZG1hLnhyZXMpOwojZGVmaW5lIFBJWEFERFIoeCx5KSAobGNkX2RtYS5hZGRyICsgKCh5KSAqIHZ4cmVzICogeXNjYWxlICsgKHgpICogeHNjYWxlKSAqIGVzKQojZGVmaW5lIFBJWFNURVAoc3gsIHN5LCBkeCwgZHkpIChQSVhBRERSKGR4LCBkeSkgLSBQSVhBRERSKHN4LCBzeSkgLSBlcyArIDEpCglzd2l0Y2ggKGxjZF9kbWEucm90YXRlKSB7CgljYXNlIDA6CgkJaWYgKCFsY2RfZG1hLm1pcnJvcikgewoJCQl0b3AgPSBQSVhBRERSKDAsIDApOwoJCQlib3R0b20gPSBQSVhBRERSKGxjZF9kbWEueHJlcyAtIDEsIGxjZF9kbWEueXJlcyAtIDEpOwoJCQkvKiAxNTEwIERNQSByZXF1aXJlcyB0aGUgYm90dG9tIGFkZHJlc3MgdG8gYmUgMiBtb3JlCgkJCSAqIHRoYW4gdGhlIGFjdHVhbCBsYXN0IG1lbW9yeSBhY2Nlc3MgbG9jYXRpb24uICovCgkJCWlmIChvbWFwX2RtYV9pbl8xNTEwX21vZGUoKSAmJgoJCQkgICAgbGNkX2RtYS5kYXRhX3R5cGUgPT0gT01BUF9ETUFfREFUQV9UWVBFX1MzMikKCQkJCWJvdHRvbSArPSAyOwoJCQllaSA9IFBJWFNURVAoMCwgMCwgMSwgMCk7CgkJCWZpID0gUElYU1RFUChsY2RfZG1hLnhyZXMgLSAxLCAwLCAwLCAxKTsKCQl9IGVsc2UgewoJCQl0b3AgPSBQSVhBRERSKGxjZF9kbWEueHJlcyAtIDEsIDApOwoJCQlib3R0b20gPSBQSVhBRERSKDAsIGxjZF9kbWEueXJlcyAtIDEpOwoJCQllaSA9IFBJWFNURVAoMSwgMCwgMCwgMCk7CgkJCWZpID0gUElYU1RFUCgwLCAwLCBsY2RfZG1hLnhyZXMgLSAxLCAxKTsKCQl9CgkJZW4gPSBsY2RfZG1hLnhyZXM7CgkJZm4gPSBsY2RfZG1hLnlyZXM7CgkJYnJlYWs7CgljYXNlIDkwOgoJCWlmICghbGNkX2RtYS5taXJyb3IpIHsKCQkJdG9wID0gUElYQUREUigwLCBsY2RfZG1hLnlyZXMgLSAxKTsKCQkJYm90dG9tID0gUElYQUREUihsY2RfZG1hLnhyZXMgLSAxLCAwKTsKCQkJZWkgPSBQSVhTVEVQKDAsIDEsIDAsIDApOwoJCQlmaSA9IFBJWFNURVAoMCwgMCwgMSwgbGNkX2RtYS55cmVzIC0gMSk7CgkJfSBlbHNlIHsKCQkJdG9wID0gUElYQUREUihsY2RfZG1hLnhyZXMgLSAxLCBsY2RfZG1hLnlyZXMgLSAxKTsKCQkJYm90dG9tID0gUElYQUREUigwLCAwKTsKCQkJZWkgPSBQSVhTVEVQKDAsIDEsIDAsIDApOwoJCQlmaSA9IFBJWFNURVAoMSwgMCwgMCwgbGNkX2RtYS55cmVzIC0gMSk7CgkJfQoJCWVuID0gbGNkX2RtYS55cmVzOwoJCWZuID0gbGNkX2RtYS54cmVzOwoJCWJyZWFrOwoJY2FzZSAxODA6CgkJaWYgKCFsY2RfZG1hLm1pcnJvcikgewoJCQl0b3AgPSBQSVhBRERSKGxjZF9kbWEueHJlcyAtIDEsIGxjZF9kbWEueXJlcyAtIDEpOwoJCQlib3R0b20gPSBQSVhBRERSKDAsIDApOwoJCQllaSA9IFBJWFNURVAoMSwgMCwgMCwgMCk7CgkJCWZpID0gUElYU1RFUCgwLCAxLCBsY2RfZG1hLnhyZXMgLSAxLCAwKTsKCQl9IGVsc2UgewoJCQl0b3AgPSBQSVhBRERSKDAsIGxjZF9kbWEueXJlcyAtIDEpOwoJCQlib3R0b20gPSBQSVhBRERSKGxjZF9kbWEueHJlcyAtIDEsIDApOwoJCQllaSA9IFBJWFNURVAoMCwgMCwgMSwgMCk7CgkJCWZpID0gUElYU1RFUChsY2RfZG1hLnhyZXMgLSAxLCAxLCAwLCAwKTsKCQl9CgkJZW4gPSBsY2RfZG1hLnhyZXM7CgkJZm4gPSBsY2RfZG1hLnlyZXM7CgkJYnJlYWs7CgljYXNlIDI3MDoKCQlpZiAoIWxjZF9kbWEubWlycm9yKSB7CgkJCXRvcCA9IFBJWEFERFIobGNkX2RtYS54cmVzIC0gMSwgMCk7CgkJCWJvdHRvbSA9IFBJWEFERFIoMCwgbGNkX2RtYS55cmVzIC0gMSk7CgkJCWVpID0gUElYU1RFUCgwLCAwLCAwLCAxKTsKCQkJZmkgPSBQSVhTVEVQKDEsIGxjZF9kbWEueXJlcyAtIDEsIDAsIDApOwoJCX0gZWxzZSB7CgkJCXRvcCA9IFBJWEFERFIoMCwgMCk7CgkJCWJvdHRvbSA9IFBJWEFERFIobGNkX2RtYS54cmVzIC0gMSwgbGNkX2RtYS55cmVzIC0gMSk7CgkJCWVpID0gUElYU1RFUCgwLCAwLCAwLCAxKTsKCQkJZmkgPSBQSVhTVEVQKDAsIGxjZF9kbWEueXJlcyAtIDEsIDEsIDApOwoJCX0KCQllbiA9IGxjZF9kbWEueXJlczsKCQlmbiA9IGxjZF9kbWEueHJlczsKCQlicmVhazsKCWRlZmF1bHQ6CgkJQlVHKCk7CgkJcmV0dXJuOwkvKiBTdXByZXNzIHdhcm5pbmcgYWJvdXQgdW5pbml0aWFsaXplZCB2YXJzICovCgl9CgoJaWYgKG9tYXBfZG1hX2luXzE1MTBfbW9kZSgpKSB7CgkJb21hcF93cml0ZXcodG9wID4+IDE2LCBPTUFQMTUxMF9ETUFfTENEX1RPUF9GMV9VKTsKCQlvbWFwX3dyaXRldyh0b3AsIE9NQVAxNTEwX0RNQV9MQ0RfVE9QX0YxX0wpOwoJCW9tYXBfd3JpdGV3KGJvdHRvbSA+PiAxNiwgT01BUDE1MTBfRE1BX0xDRF9CT1RfRjFfVSk7CgkJb21hcF93cml0ZXcoYm90dG9tLCBPTUFQMTUxMF9ETUFfTENEX0JPVF9GMV9MKTsKCgkJcmV0dXJuOwoJfQoKCS8qIDE2MTAgcmVncyAqLwoJb21hcF93cml0ZXcodG9wID4+IDE2LCBPTUFQMTYxMF9ETUFfTENEX1RPUF9CMV9VKTsKCW9tYXBfd3JpdGV3KHRvcCwgT01BUDE2MTBfRE1BX0xDRF9UT1BfQjFfTCk7CglvbWFwX3dyaXRldyhib3R0b20gPj4gMTYsIE9NQVAxNjEwX0RNQV9MQ0RfQk9UX0IxX1UpOwoJb21hcF93cml0ZXcoYm90dG9tLCBPTUFQMTYxMF9ETUFfTENEX0JPVF9CMV9MKTsKCglvbWFwX3dyaXRldyhlbiwgT01BUDE2MTBfRE1BX0xDRF9TUkNfRU5fQjEpOwoJb21hcF93cml0ZXcoZm4sIE9NQVAxNjEwX0RNQV9MQ0RfU1JDX0ZOX0IxKTsKCgl3ID0gb21hcF9yZWFkdyhPTUFQMTYxMF9ETUFfTENEX0NTRFApOwoJdyAmPSB+MHgwMzsKCXcgfD0gbGNkX2RtYS5kYXRhX3R5cGU7CglvbWFwX3dyaXRldyh3LCBPTUFQMTYxMF9ETUFfTENEX0NTRFApOwoKCXcgPSBvbWFwX3JlYWR3KE9NQVAxNjEwX0RNQV9MQ0RfQ1RSTCk7CgkvKiBBbHdheXMgc2V0IHRoZSBzb3VyY2UgcG9ydCBhcyBTRFJBTSBmb3Igbm93Ki8KCXcgJj0gfigweDAzIDw8IDYpOwoJaWYgKGxjZF9kbWEuY2FsbGJhY2sgIT0gTlVMTCkKCQl3IHw9IDEgPDwgMTsJCS8qIEJsb2NrIGludGVycnVwdCBlbmFibGUgKi8KCWVsc2UKCQl3ICY9IH4oMSA8PCAxKTsKCW9tYXBfd3JpdGV3KHcsIE9NQVAxNjEwX0RNQV9MQ0RfQ1RSTCk7CgoJaWYgKCEobGNkX2RtYS5yb3RhdGUgfHwgbGNkX2RtYS5taXJyb3IgfHwKCSAgICAgIGxjZF9kbWEudnhyZXMgfHwgbGNkX2RtYS54c2NhbGUgfHwgbGNkX2RtYS55c2NhbGUpKQoJCXJldHVybjsKCgl3ID0gb21hcF9yZWFkdyhPTUFQMTYxMF9ETUFfTENEX0NDUik7CgkvKiBTZXQgdGhlIGRvdWJsZS1pbmRleGVkIGFkZHJlc3NpbmcgbW9kZSAqLwoJdyB8PSAoMHgwMyA8PCAxMik7CglvbWFwX3dyaXRldyh3LCBPTUFQMTYxMF9ETUFfTENEX0NDUik7CgoJb21hcF93cml0ZXcoZWksIE9NQVAxNjEwX0RNQV9MQ0RfU1JDX0VJX0IxKTsKCW9tYXBfd3JpdGV3KGZpID4+IDE2LCBPTUFQMTYxMF9ETUFfTENEX1NSQ19GSV9CMV9VKTsKCW9tYXBfd3JpdGV3KGZpLCBPTUFQMTYxMF9ETUFfTENEX1NSQ19GSV9CMV9MKTsKfQoKc3RhdGljIGlycXJldHVybl90IGxjZF9kbWFfaXJxX2hhbmRsZXIoaW50IGlycSwgdm9pZCAqZGV2X2lkKQp7Cgl1MTYgdzsKCgl3ID0gb21hcF9yZWFkdyhPTUFQMTYxMF9ETUFfTENEX0NUUkwpOwoJaWYgKHVubGlrZWx5KCEodyAmICgxIDw8IDMpKSkpIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJTcHVyaW91cyBMQ0QgRE1BIElSUVxuIik7CgkJcmV0dXJuIElSUV9OT05FOwoJfQoJLyogQWNrIHRoZSBJUlEgKi8KCXcgfD0gKDEgPDwgMyk7CglvbWFwX3dyaXRldyh3LCBPTUFQMTYxMF9ETUFfTENEX0NUUkwpOwoJbGNkX2RtYS5hY3RpdmUgPSAwOwoJaWYgKGxjZF9kbWEuY2FsbGJhY2sgIT0gTlVMTCkKCQlsY2RfZG1hLmNhbGxiYWNrKHcsIGxjZF9kbWEuY2JfZGF0YSk7CgoJcmV0dXJuIElSUV9IQU5ETEVEOwp9CgppbnQgb21hcF9yZXF1ZXN0X2xjZF9kbWEodm9pZCAoKiBjYWxsYmFjaykodTE2IHN0YXR1cywgdm9pZCAqZGF0YSksCgkJCSB2b2lkICpkYXRhKQp7CglzcGluX2xvY2tfaXJxKCZsY2RfZG1hLmxvY2spOwoJaWYgKGxjZF9kbWEucmVzZXJ2ZWQpIHsKCQlzcGluX3VubG9ja19pcnEoJmxjZF9kbWEubG9jayk7CgkJcHJpbnRrKEtFUk5fRVJSICJMQ0QgRE1BIGNoYW5uZWwgYWxyZWFkeSByZXNlcnZlZFxuIik7CgkJQlVHKCk7CgkJcmV0dXJuIC1FQlVTWTsKCX0KCWxjZF9kbWEucmVzZXJ2ZWQgPSAxOwoJc3Bpbl91bmxvY2tfaXJxKCZsY2RfZG1hLmxvY2spOwoJbGNkX2RtYS5jYWxsYmFjayA9IGNhbGxiYWNrOwoJbGNkX2RtYS5jYl9kYXRhID0gZGF0YTsKCWxjZF9kbWEuYWN0aXZlID0gMDsKCWxjZF9kbWEuc2luZ2xlX3RyYW5zZmVyID0gMDsKCWxjZF9kbWEucm90YXRlID0gMDsKCWxjZF9kbWEudnhyZXMgPSAwOwoJbGNkX2RtYS5taXJyb3IgPSAwOwoJbGNkX2RtYS54c2NhbGUgPSAwOwoJbGNkX2RtYS55c2NhbGUgPSAwOwoJbGNkX2RtYS5leHRfY3RybCA9IDA7CglsY2RfZG1hLnNyY19wb3J0ID0gMDsKCglyZXR1cm4gMDsKfQoKdm9pZCBvbWFwX2ZyZWVfbGNkX2RtYSh2b2lkKQp7CglzcGluX2xvY2soJmxjZF9kbWEubG9jayk7CglpZiAoIWxjZF9kbWEucmVzZXJ2ZWQpIHsKCQlzcGluX3VubG9jaygmbGNkX2RtYS5sb2NrKTsKCQlwcmludGsoS0VSTl9FUlIgIkxDRCBETUEgaXMgbm90IHJlc2VydmVkXG4iKTsKCQlCVUcoKTsKCQlyZXR1cm47Cgl9CglpZiAoIWVuYWJsZV8xNTEwX21vZGUpCgkJb21hcF93cml0ZXcob21hcF9yZWFkdyhPTUFQMTYxMF9ETUFfTENEX0NDUikgJiB+MSwKCQkJICAgIE9NQVAxNjEwX0RNQV9MQ0RfQ0NSKTsKCWxjZF9kbWEucmVzZXJ2ZWQgPSAwOwoJc3Bpbl91bmxvY2soJmxjZF9kbWEubG9jayk7Cn0KCnZvaWQgb21hcF9lbmFibGVfbGNkX2RtYSh2b2lkKQp7Cgl1MTYgdzsKCgkvKiBTZXQgdGhlIEVuYWJsZSBiaXQgb25seSBpZiBhbiBleHRlcm5hbCBjb250cm9sbGVyIGlzCgkgKiBjb25uZWN0ZWQuIE90aGVyd2lzZSB0aGUgT01BUCBpbnRlcm5hbCBjb250cm9sbGVyIHdpbGwKCSAqIHN0YXJ0IHRoZSB0cmFuc2ZlciB3aGVuIGl0IGdldHMgZW5hYmxlZC4KCSAqLwoJaWYgKGVuYWJsZV8xNTEwX21vZGUgfHwgIWxjZF9kbWEuZXh0X2N0cmwpCgkJcmV0dXJuOwoKCXcgPSBvbWFwX3JlYWR3KE9NQVAxNjEwX0RNQV9MQ0RfQ1RSTCk7Cgl3IHw9IDEgPDwgODsKCW9tYXBfd3JpdGV3KHcsIE9NQVAxNjEwX0RNQV9MQ0RfQ1RSTCk7CgoJbGNkX2RtYS5hY3RpdmUgPSAxOwoKCXcgPSBvbWFwX3JlYWR3KE9NQVAxNjEwX0RNQV9MQ0RfQ0NSKTsKCXcgfD0gMSA8PCA3OwoJb21hcF93cml0ZXcodywgT01BUDE2MTBfRE1BX0xDRF9DQ1IpOwp9Cgp2b2lkIG9tYXBfc2V0dXBfbGNkX2RtYSh2b2lkKQp7CglCVUdfT04obGNkX2RtYS5hY3RpdmUpOwoJaWYgKCFlbmFibGVfMTUxMF9tb2RlKSB7CgkJLyogU2V0IHNvbWUgcmVhc29uYWJsZSBkZWZhdWx0cyAqLwoJCW9tYXBfd3JpdGV3KDB4NTQ0MCwgT01BUDE2MTBfRE1BX0xDRF9DQ1IpOwoJCW9tYXBfd3JpdGV3KDB4OTEwMiwgT01BUDE2MTBfRE1BX0xDRF9DU0RQKTsKCQlvbWFwX3dyaXRldygweDAwMDQsIE9NQVAxNjEwX0RNQV9MQ0RfTENIX0NUUkwpOwoJfQoJc2V0X2IxX3JlZ3MoKTsKCWlmICghZW5hYmxlXzE1MTBfbW9kZSkgewoJCXUxNiB3OwoKCQl3ID0gb21hcF9yZWFkdyhPTUFQMTYxMF9ETUFfTENEX0NDUik7CgkJLyogSWYgRE1BIHdhcyBhbHJlYWR5IGFjdGl2ZSBzZXQgdGhlIGVuZF9wcm9nIGJpdCB0byBoYXZlCgkJICogdGhlIHByb2dyYW1tZWQgcmVnaXN0ZXIgc2V0IGxvYWRlZCBpbnRvIHRoZSBhY3RpdmUKCQkgKiByZWdpc3RlciBzZXQuCgkJICovCgkJdyB8PSAxIDw8IDExOwkJLyogRW5kX3Byb2cgKi8KCQlpZiAoIWxjZF9kbWEuc2luZ2xlX3RyYW5zZmVyKQoJICAgICAgICAJdyB8PSAoMyA8PCA4KTsJLyogQXV0b19pbml0LCByZXBlYXQgKi8KCQlvbWFwX3dyaXRldyh3LCBPTUFQMTYxMF9ETUFfTENEX0NDUik7Cgl9Cn0KCnZvaWQgb21hcF9zdG9wX2xjZF9kbWEodm9pZCkKewoJdTE2IHc7CgoJbGNkX2RtYS5hY3RpdmUgPSAwOwoJaWYgKGVuYWJsZV8xNTEwX21vZGUgfHwgIWxjZF9kbWEuZXh0X2N0cmwpCgkJcmV0dXJuOwoKCXcgPSBvbWFwX3JlYWR3KE9NQVAxNjEwX0RNQV9MQ0RfQ0NSKTsKCXcgJj0gfigxIDw8IDcpOwoJb21hcF93cml0ZXcodywgT01BUDE2MTBfRE1BX0xDRF9DQ1IpOwoKCXcgPSBvbWFwX3JlYWR3KE9NQVAxNjEwX0RNQV9MQ0RfQ1RSTCk7Cgl3ICY9IH4oMSA8PCA4KTsKCW9tYXBfd3JpdGV3KHcsIE9NQVAxNjEwX0RNQV9MQ0RfQ1RSTCk7Cn0KCmludCBvbWFwX2xjZF9kbWFfZXh0X3J1bm5pbmcodm9pZCkKewoJcmV0dXJuIGxjZF9kbWEuZXh0X2N0cmwgJiYgbGNkX2RtYS5hY3RpdmU7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgpzdGF0aWMgaW50IF9faW5pdCBvbWFwX2luaXRfZG1hKHZvaWQpCnsKCWludCBjaCwgcjsKCglpZiAoY3B1X2lzX29tYXAxNXh4KCkpIHsKCQlwcmludGsoS0VSTl9JTkZPICJETUEgc3VwcG9ydCBmb3IgT01BUDE1eHggaW5pdGlhbGl6ZWRcbiIpOwoJCWRtYV9jaGFuX2NvdW50ID0gOTsKCQllbmFibGVfMTUxMF9tb2RlID0gMTsKCX0gZWxzZSBpZiAoY3B1X2lzX29tYXAxNnh4KCkgfHwgY3B1X2lzX29tYXA3MzAoKSkgewoJCXByaW50ayhLRVJOX0lORk8gIk9NQVAgRE1BIGhhcmR3YXJlIHZlcnNpb24gJWRcbiIsCgkJICAgICAgIG9tYXBfcmVhZHcoT01BUF9ETUFfSFdfSUQpKTsKCQlwcmludGsoS0VSTl9JTkZPICJETUEgY2FwYWJpbGl0aWVzOiAlMDh4OiUwOHg6JTA0eDolMDR4OiUwNHhcbiIsCgkJICAgICAgIChvbWFwX3JlYWR3KE9NQVBfRE1BX0NBUFNfMF9VKSA8PCAxNikgfAoJCSAgICAgICBvbWFwX3JlYWR3KE9NQVBfRE1BX0NBUFNfMF9MKSwKCQkgICAgICAgKG9tYXBfcmVhZHcoT01BUF9ETUFfQ0FQU18xX1UpIDw8IDE2KSB8CgkJICAgICAgIG9tYXBfcmVhZHcoT01BUF9ETUFfQ0FQU18xX0wpLAoJCSAgICAgICBvbWFwX3JlYWR3KE9NQVBfRE1BX0NBUFNfMiksIG9tYXBfcmVhZHcoT01BUF9ETUFfQ0FQU18zKSwKCQkgICAgICAgb21hcF9yZWFkdyhPTUFQX0RNQV9DQVBTXzQpKTsKCQlpZiAoIWVuYWJsZV8xNTEwX21vZGUpIHsKCQkJdTE2IHc7CgoJCQkvKiBEaXNhYmxlIE9NQVAgMy4wLzMuMSBjb21wYXRpYmlsaXR5IG1vZGUuICovCgkJCXcgPSBvbWFwX3JlYWR3KE9NQVBfRE1BX0dTQ1IpOwoJCQl3IHw9IDEgPDwgMzsKCQkJb21hcF93cml0ZXcodywgT01BUF9ETUFfR1NDUik7CgkJCWRtYV9jaGFuX2NvdW50ID0gMTY7CgkJfSBlbHNlCgkJCWRtYV9jaGFuX2NvdW50ID0gOTsKCQlpZiAoY3B1X2lzX29tYXAxNnh4KCkpIHsKCQkJdTE2IHc7CgoJCQkvKiB0aGlzIHdvdWxkIHByZXZlbnQgT01BUCBzbGVlcCAqLwoJCQl3ID0gb21hcF9yZWFkdyhPTUFQMTYxMF9ETUFfTENEX0NUUkwpOwoJCQl3ICY9IH4oMSA8PCA4KTsKCQkJb21hcF93cml0ZXcodywgT01BUDE2MTBfRE1BX0xDRF9DVFJMKTsKCQl9Cgl9IGVsc2UgaWYgKGNwdV9pc19vbWFwMjR4eCgpKSB7CgkJdTggcmV2aXNpb24gPSBvbWFwX3JlYWRiKE9NQVBfRE1BNF9SRVZJU0lPTik7CgkJcHJpbnRrKEtFUk5fSU5GTyAiT01BUCBETUEgaGFyZHdhcmUgcmV2aXNpb24gJWQuJWRcbiIsCgkJICAgICAgIHJldmlzaW9uID4+IDQsIHJldmlzaW9uICYgMHhmKTsKCQlkbWFfY2hhbl9jb3VudCA9IE9NQVBfTE9HSUNBTF9ETUFfQ0hfQ09VTlQ7Cgl9IGVsc2UgewoJCWRtYV9jaGFuX2NvdW50ID0gMDsKCQlyZXR1cm4gMDsKCX0KCgltZW1zZXQoJmxjZF9kbWEsIDAsIHNpemVvZihsY2RfZG1hKSk7CglzcGluX2xvY2tfaW5pdCgmbGNkX2RtYS5sb2NrKTsKCXNwaW5fbG9ja19pbml0KCZkbWFfY2hhbl9sb2NrKTsKCW1lbXNldCgmZG1hX2NoYW4sIDAsIHNpemVvZihkbWFfY2hhbikpOwoKCWZvciAoY2ggPSAwOyBjaCA8IGRtYV9jaGFuX2NvdW50OyBjaCsrKSB7CgkJb21hcF9jbGVhcl9kbWEoY2gpOwoJCWRtYV9jaGFuW2NoXS5kZXZfaWQgPSAtMTsKCQlkbWFfY2hhbltjaF0ubmV4dF9sY2ggPSAtMTsKCgkJaWYgKGNoID49IDYgJiYgZW5hYmxlXzE1MTBfbW9kZSkKCQkJY29udGludWU7CgoJCWlmIChjcHVfY2xhc3NfaXNfb21hcDEoKSkgewoJCQkvKiByZXF1ZXN0X2lycSgpIGRvZXNuJ3QgbGlrZSBkZXZfaWQgKGllLiBjaCkgYmVpbmcKCQkJICogemVybywgc28gd2UgaGF2ZSB0byBrbHVkZ2UgYXJvdW5kIHRoaXMuICovCgkJCXIgPSByZXF1ZXN0X2lycShvbWFwMV9kbWFfaXJxW2NoXSwKCQkJCQlvbWFwMV9kbWFfaXJxX2hhbmRsZXIsIDAsICJETUEiLAoJCQkJCSh2b2lkICopIChjaCArIDEpKTsKCQkJaWYgKHIgIT0gMCkgewoJCQkJaW50IGk7CgoJCQkJcHJpbnRrKEtFUk5fRVJSICJ1bmFibGUgdG8gcmVxdWVzdCBJUlEgJWQgIgoJCQkJICAgICAgICJmb3IgRE1BIChlcnJvciAlZClcbiIsCgkJCQkgICAgICAgb21hcDFfZG1hX2lycVtjaF0sIHIpOwoJCQkJZm9yIChpID0gMDsgaSA8IGNoOyBpKyspCgkJCQkJZnJlZV9pcnEob21hcDFfZG1hX2lycVtpXSwKCQkJCQkJICh2b2lkICopIChpICsgMSkpOwoJCQkJcmV0dXJuIHI7CgkJCX0KCQl9Cgl9CgoJaWYgKGNwdV9pc19vbWFwMjR4eCgpKQoJCXNldHVwX2lycShJTlRfMjRYWF9TRE1BX0lSUTAsICZvbWFwMjR4eF9kbWFfaXJxKTsKCgkvKiBGSVhNRTogVXBkYXRlIExDRCBETUEgdG8gd29yayBvbiAyNHh4ICovCglpZiAoY3B1X2NsYXNzX2lzX29tYXAxKCkpIHsKCQlyID0gcmVxdWVzdF9pcnEoSU5UX0RNQV9MQ0QsIGxjZF9kbWFfaXJxX2hhbmRsZXIsIDAsCgkJCQkiTENEIERNQSIsIE5VTEwpOwoJCWlmIChyICE9IDApIHsKCQkJaW50IGk7CgoJCQlwcmludGsoS0VSTl9FUlIgInVuYWJsZSB0byByZXF1ZXN0IElSUSBmb3IgTENEIERNQSAiCgkJCSAgICAgICAiKGVycm9yICVkKVxuIiwgcik7CgkJCWZvciAoaSA9IDA7IGkgPCBkbWFfY2hhbl9jb3VudDsgaSsrKQoJCQkJZnJlZV9pcnEob21hcDFfZG1hX2lycVtpXSwgKHZvaWQgKikgKGkgKyAxKSk7CgkJCXJldHVybiByOwoJCX0KCX0KCglyZXR1cm4gMDsKfQoKYXJjaF9pbml0Y2FsbChvbWFwX2luaXRfZG1hKTsKCkVYUE9SVF9TWU1CT0wob21hcF9nZXRfZG1hX3NyY19wb3MpOwpFWFBPUlRfU1lNQk9MKG9tYXBfZ2V0X2RtYV9kc3RfcG9zKTsKRVhQT1JUX1NZTUJPTChvbWFwX2dldF9kbWFfc3JjX2FkZHJfY291bnRlcik7CkVYUE9SVF9TWU1CT0wob21hcF9jbGVhcl9kbWEpOwpFWFBPUlRfU1lNQk9MKG9tYXBfc2V0X2RtYV9wcmlvcml0eSk7CkVYUE9SVF9TWU1CT0wob21hcF9yZXF1ZXN0X2RtYSk7CkVYUE9SVF9TWU1CT0wob21hcF9mcmVlX2RtYSk7CkVYUE9SVF9TWU1CT0wob21hcF9zdGFydF9kbWEpOwpFWFBPUlRfU1lNQk9MKG9tYXBfc3RvcF9kbWEpOwpFWFBPUlRfU1lNQk9MKG9tYXBfc2V0X2RtYV9jYWxsYmFjayk7CkVYUE9SVF9TWU1CT0wob21hcF9lbmFibGVfZG1hX2lycSk7CkVYUE9SVF9TWU1CT0wob21hcF9kaXNhYmxlX2RtYV9pcnEpOwoKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9kbWFfdHJhbnNmZXJfcGFyYW1zKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9kbWFfY29sb3JfbW9kZSk7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfZG1hX3dyaXRlX21vZGUpOwoKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9kbWFfc3JjX3BhcmFtcyk7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfZG1hX3NyY19pbmRleCk7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfZG1hX3NyY19kYXRhX3BhY2spOwpFWFBPUlRfU1lNQk9MKG9tYXBfc2V0X2RtYV9zcmNfYnVyc3RfbW9kZSk7CgpFWFBPUlRfU1lNQk9MKG9tYXBfc2V0X2RtYV9kZXN0X3BhcmFtcyk7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfZG1hX2Rlc3RfaW5kZXgpOwpFWFBPUlRfU1lNQk9MKG9tYXBfc2V0X2RtYV9kZXN0X2RhdGFfcGFjayk7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfZG1hX2Rlc3RfYnVyc3RfbW9kZSk7CgpFWFBPUlRfU1lNQk9MKG9tYXBfc2V0X2RtYV9wYXJhbXMpOwoKRVhQT1JUX1NZTUJPTChvbWFwX2RtYV9saW5rX2xjaCk7CkVYUE9SVF9TWU1CT0wob21hcF9kbWFfdW5saW5rX2xjaCk7CgpFWFBPUlRfU1lNQk9MKG9tYXBfcmVxdWVzdF9sY2RfZG1hKTsKRVhQT1JUX1NZTUJPTChvbWFwX2ZyZWVfbGNkX2RtYSk7CkVYUE9SVF9TWU1CT0wob21hcF9lbmFibGVfbGNkX2RtYSk7CkVYUE9SVF9TWU1CT0wob21hcF9zZXR1cF9sY2RfZG1hKTsKRVhQT1JUX1NZTUJPTChvbWFwX3N0b3BfbGNkX2RtYSk7CkVYUE9SVF9TWU1CT0wob21hcF9sY2RfZG1hX2V4dF9ydW5uaW5nKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9sY2RfZG1hX2IxKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9sY2RfZG1hX3NpbmdsZV90cmFuc2Zlcik7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfbGNkX2RtYV9leHRfY29udHJvbGxlcik7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfbGNkX2RtYV9iMV9yb3RhdGlvbik7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfbGNkX2RtYV9iMV92eHJlcyk7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfbGNkX2RtYV9iMV9zY2FsZSk7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfbGNkX2RtYV9iMV9taXJyb3IpOwoK