LyoKICogbGludXgvYXJjaC9hcm0vcGxhdC1vbWFwL2RtYS5jCiAqCiAqIENvcHlyaWdodCAoQykgMjAwMyBOb2tpYSBDb3Jwb3JhdGlvbgogKiBBdXRob3I6IEp1aGEgWXJq9mzkIDxqdWhhLnlyam9sYUBub2tpYS5jb20+CiAqIERNQSBjaGFubmVsIGxpbmtpbmcgZm9yIDE2MTAgYnkgU2FtdWVsIE9ydGl6IDxzYW11ZWwub3J0aXpAbm9raWEuY29tPgogKiBHcmFwaGljcyBETUEgYW5kIExDRCBETUEgZ3JhcGhpY3MgdHJhbmZvcm1hdGlvbnMKICogYnkgSW1yZSBEZWFrIDxpbXJlLmRlYWtAbm9raWEuY29tPgogKiBPTUFQMiBzdXBwb3J0IENvcHlyaWdodCAoQykgMjAwNC0yMDA1IFRleGFzIEluc3RydW1lbnRzLCBJbmMuCiAqIE1lcmdlZCB0byBzdXBwb3J0IGJvdGggT01BUDEgYW5kIE9NQVAyIGJ5IFRvbnkgTGluZGdyZW4gPHRvbnlAYXRvbWlkZS5jb20+CiAqIFNvbWUgZnVuY3Rpb25zIGJhc2VkIG9uIGVhcmxpZXIgZG1hLW9tYXAuYyBDb3B5cmlnaHQgKEMpIDIwMDEgUmlkZ2VSdW4sIEluYy4KICoKICogU3VwcG9ydCBmdW5jdGlvbnMgZm9yIHRoZSBPTUFQIGludGVybmFsIERNQSBjaGFubmVscy4KICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCiAqCiAqLwoKI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvc2NoZWQuaD4KI2luY2x1ZGUgPGxpbnV4L3NwaW5sb2NrLmg+CiNpbmNsdWRlIDxsaW51eC9lcnJuby5oPgojaW5jbHVkZSA8bGludXgvaW50ZXJydXB0Lmg+CgojaW5jbHVkZSA8YXNtL3N5c3RlbS5oPgojaW5jbHVkZSA8YXNtL2lycS5oPgojaW5jbHVkZSA8YXNtL2hhcmR3YXJlLmg+CiNpbmNsdWRlIDxhc20vZG1hLmg+CiNpbmNsdWRlIDxhc20vaW8uaD4KCiNpbmNsdWRlIDxhc20vYXJjaC90Yy5oPgoKI2RlZmluZSBERUJVR19QUklOVFMKI3VuZGVmIERFQlVHX1BSSU5UUwojaWZkZWYgREVCVUdfUFJJTlRTCiNkZWZpbmUgZGVidWdfcHJpbnRrKHgpIHByaW50ayB4CiNlbHNlCiNkZWZpbmUJZGVidWdfcHJpbnRrKHgpCiNlbmRpZgoKI2RlZmluZSBPTUFQX0RNQV9BQ1RJVkUJCTB4MDEKI2RlZmluZSBPTUFQX0RNQV9DQ1JfRU4JCSgxIDw8IDcpCgojZGVmaW5lIE9NQVBfRlVOQ19NVVhfQVJNX0JBU0UJKDB4ZmZmZTEwMDAgKyAweGVjKQoKc3RhdGljIGludCBlbmFibGVfMTUxMF9tb2RlID0gMDsKCnN0cnVjdCBvbWFwX2RtYV9sY2ggewoJaW50IG5leHRfbGNoOwoJaW50IGRldl9pZDsKCXUxNiBzYXZlZF9jc3I7Cgl1MTYgZW5hYmxlZF9pcnFzOwoJY29uc3QgY2hhciAqZGV2X25hbWU7Cgl2b2lkICgqIGNhbGxiYWNrKShpbnQgbGNoLCB1MTYgY2hfc3RhdHVzLCB2b2lkICpkYXRhKTsKCXZvaWQgKmRhdGE7Cglsb25nIGZsYWdzOwp9OwoKc3RhdGljIGludCBkbWFfY2hhbl9jb3VudDsKCnN0YXRpYyBzcGlubG9ja190IGRtYV9jaGFuX2xvY2s7CnN0YXRpYyBzdHJ1Y3Qgb21hcF9kbWFfbGNoIGRtYV9jaGFuW09NQVBfTE9HSUNBTF9ETUFfQ0hfQ09VTlRdOwoKc3RhdGljIGNvbnN0IHU4IG9tYXAxX2RtYV9pcnFbT01BUF9MT0dJQ0FMX0RNQV9DSF9DT1VOVF0gPSB7CglJTlRfRE1BX0NIMF82LCBJTlRfRE1BX0NIMV83LCBJTlRfRE1BX0NIMl84LCBJTlRfRE1BX0NIMywKCUlOVF9ETUFfQ0g0LCBJTlRfRE1BX0NINSwgSU5UXzE2MTBfRE1BX0NINiwgSU5UXzE2MTBfRE1BX0NINywKCUlOVF8xNjEwX0RNQV9DSDgsIElOVF8xNjEwX0RNQV9DSDksIElOVF8xNjEwX0RNQV9DSDEwLAoJSU5UXzE2MTBfRE1BX0NIMTEsIElOVF8xNjEwX0RNQV9DSDEyLCBJTlRfMTYxMF9ETUFfQ0gxMywKCUlOVF8xNjEwX0RNQV9DSDE0LCBJTlRfMTYxMF9ETUFfQ0gxNSwgSU5UX0RNQV9MQ0QKfTsKCiNkZWZpbmUgUkVWSVNJVF8yNFhYKCkJCXByaW50ayhLRVJOX0VSUiAiRklYTUU6IG5vICVzIG9uIDI0eHhcbiIsIFwKCQkJCQkJX19GVU5DVElPTl9fKTsKCiNpZmRlZiBDT05GSUdfQVJDSF9PTUFQMTVYWAovKiBSZXR1cm5zIDEgaWYgdGhlIERNQSBtb2R1bGUgaXMgaW4gT01BUDE1MTAtY29tcGF0aWJsZSBtb2RlLCAwIG90aGVyd2lzZSAqLwppbnQgb21hcF9kbWFfaW5fMTUxMF9tb2RlKHZvaWQpCnsKCXJldHVybiBlbmFibGVfMTUxMF9tb2RlOwp9CiNlbHNlCiNkZWZpbmUgb21hcF9kbWFfaW5fMTUxMF9tb2RlKCkJCTAKI2VuZGlmCgojaWZkZWYgQ09ORklHX0FSQ0hfT01BUDEKc3RhdGljIGlubGluZSBpbnQgZ2V0X2dkbWFfZGV2KGludCByZXEpCnsKCXUzMiByZWcgPSBPTUFQX0ZVTkNfTVVYX0FSTV9CQVNFICsgKChyZXEgLSAxKSAvIDUpICogNDsKCWludCBzaGlmdCA9ICgocmVxIC0gMSkgJSA1KSAqIDY7CgoJcmV0dXJuICgob21hcF9yZWFkbChyZWcpID4+IHNoaWZ0KSAmIDB4M2YpICsgMTsKfQoKc3RhdGljIGlubGluZSB2b2lkIHNldF9nZG1hX2RldihpbnQgcmVxLCBpbnQgZGV2KQp7Cgl1MzIgcmVnID0gT01BUF9GVU5DX01VWF9BUk1fQkFTRSArICgocmVxIC0gMSkgLyA1KSAqIDQ7CglpbnQgc2hpZnQgPSAoKHJlcSAtIDEpICUgNSkgKiA2OwoJdTMyIGw7CgoJbCA9IG9tYXBfcmVhZGwocmVnKTsKCWwgJj0gfigweDNmIDw8IHNoaWZ0KTsKCWwgfD0gKGRldiAtIDEpIDw8IHNoaWZ0OwoJb21hcF93cml0ZWwobCwgcmVnKTsKfQojZWxzZQojZGVmaW5lIHNldF9nZG1hX2RldihyZXEsIGRldikJZG8ge30gd2hpbGUgKDApCiNlbmRpZgoKc3RhdGljIHZvaWQgY2xlYXJfbGNoX3JlZ3MoaW50IGxjaCkKewoJaW50IGk7Cgl1MzIgbGNoX2Jhc2UgPSBPTUFQX0RNQV9CQVNFICsgbGNoICogMHg0MDsKCglmb3IgKGkgPSAwOyBpIDwgMHgyYzsgaSArPSAyKQoJCW9tYXBfd3JpdGV3KDAsIGxjaF9iYXNlICsgaSk7Cn0KCnZvaWQgb21hcF9zZXRfZG1hX3ByaW9yaXR5KGludCBkc3RfcG9ydCwgaW50IHByaW9yaXR5KQp7Cgl1bnNpZ25lZCBsb25nIHJlZzsKCXUzMiBsOwoKCXN3aXRjaCAoZHN0X3BvcnQpIHsKCWNhc2UgT01BUF9ETUFfUE9SVF9PQ1BfVDE6CS8qIEZGRkVDQzAwICovCgkJcmVnID0gT01BUF9UQ19PQ1BUMV9QUklPUjsKCQlicmVhazsKCWNhc2UgT01BUF9ETUFfUE9SVF9PQ1BfVDI6CS8qIEZGRkVDQ0QwICovCgkJcmVnID0gT01BUF9UQ19PQ1BUMl9QUklPUjsKCQlicmVhazsKCWNhc2UgT01BUF9ETUFfUE9SVF9FTUlGRjoJLyogRkZGRUNDMDggKi8KCQlyZWcgPSBPTUFQX1RDX0VNSUZGX1BSSU9SOwoJCWJyZWFrOwoJY2FzZSBPTUFQX0RNQV9QT1JUX0VNSUZTOgkvKiBGRkZFQ0MwNCAqLwoJCXJlZyA9IE9NQVBfVENfRU1JRlNfUFJJT1I7CgkJYnJlYWs7CglkZWZhdWx0OgoJCUJVRygpOwoJCXJldHVybjsKCX0KCWwgPSBvbWFwX3JlYWRsKHJlZyk7CglsICY9IH4oMHhmIDw8IDgpOwoJbCB8PSAocHJpb3JpdHkgJiAweGYpIDw8IDg7CglvbWFwX3dyaXRlbChsLCByZWcpOwp9Cgp2b2lkIG9tYXBfc2V0X2RtYV90cmFuc2Zlcl9wYXJhbXMoaW50IGxjaCwgaW50IGRhdGFfdHlwZSwgaW50IGVsZW1fY291bnQsCgkJCQkgIGludCBmcmFtZV9jb3VudCwgaW50IHN5bmNfbW9kZSwKCQkJCSAgaW50IGRtYV90cmlnZ2VyLCBpbnQgc3JjX29yX2RzdF9zeW5jaCkKewoJT01BUF9ETUFfQ1NEUF9SRUcobGNoKSAmPSB+MHgwMzsKCU9NQVBfRE1BX0NTRFBfUkVHKGxjaCkgfD0gZGF0YV90eXBlOwoKCWlmIChjcHVfY2xhc3NfaXNfb21hcDEoKSkgewoJCU9NQVBfRE1BX0NDUl9SRUcobGNoKSAmPSB+KDEgPDwgNSk7CgkJaWYgKHN5bmNfbW9kZSA9PSBPTUFQX0RNQV9TWU5DX0ZSQU1FKQoJCQlPTUFQX0RNQV9DQ1JfUkVHKGxjaCkgfD0gMSA8PCA1OwoKCQlPTUFQMV9ETUFfQ0NSMl9SRUcobGNoKSAmPSB+KDEgPDwgMik7CgkJaWYgKHN5bmNfbW9kZSA9PSBPTUFQX0RNQV9TWU5DX0JMT0NLKQoJCQlPTUFQMV9ETUFfQ0NSMl9SRUcobGNoKSB8PSAxIDw8IDI7Cgl9CgoJaWYgKGNwdV9pc19vbWFwMjR4eCgpICYmIGRtYV90cmlnZ2VyKSB7CgkJdTMyIHZhbCA9IE9NQVBfRE1BX0NDUl9SRUcobGNoKTsKCgkJaWYgKGRtYV90cmlnZ2VyID4gNjMpCgkJCXZhbCB8PSAxIDw8IDIwOwoJCWlmIChkbWFfdHJpZ2dlciA+IDMxKQoJCQl2YWwgfD0gMSA8PCAxOTsKCgkJdmFsIHw9IChkbWFfdHJpZ2dlciAmIDB4MWYpOwoKCQlpZiAoc3luY19tb2RlICYgT01BUF9ETUFfU1lOQ19GUkFNRSkKCQkJdmFsIHw9IDEgPDwgNTsKCgkJaWYgKHN5bmNfbW9kZSAmIE9NQVBfRE1BX1NZTkNfQkxPQ0spCgkJCXZhbCB8PSAxIDw8IDE4OwoKCQlpZiAoc3JjX29yX2RzdF9zeW5jaCkKCQkJdmFsIHw9IDEgPDwgMjQ7CQkvKiBzb3VyY2Ugc3luY2ggKi8KCQllbHNlCgkJCXZhbCAmPSB+KDEgPDwgMjQpOwkvKiBkZXN0IHN5bmNoICovCgoJCU9NQVBfRE1BX0NDUl9SRUcobGNoKSA9IHZhbDsKCX0KCglPTUFQX0RNQV9DRU5fUkVHKGxjaCkgPSBlbGVtX2NvdW50OwoJT01BUF9ETUFfQ0ZOX1JFRyhsY2gpID0gZnJhbWVfY291bnQ7Cn0KCnZvaWQgb21hcF9zZXRfZG1hX2NvbG9yX21vZGUoaW50IGxjaCwgZW51bSBvbWFwX2RtYV9jb2xvcl9tb2RlIG1vZGUsIHUzMiBjb2xvcikKewoJdTE2IHc7CgoJQlVHX09OKG9tYXBfZG1hX2luXzE1MTBfbW9kZSgpKTsKCglpZiAoY3B1X2lzX29tYXAyNHh4KCkpIHsKCQlSRVZJU0lUXzI0WFgoKTsKCQlyZXR1cm47Cgl9CgoJdyA9IE9NQVAxX0RNQV9DQ1IyX1JFRyhsY2gpICYgfjB4MDM7Cglzd2l0Y2ggKG1vZGUpIHsKCWNhc2UgT01BUF9ETUFfQ09OU1RBTlRfRklMTDoKCQl3IHw9IDB4MDE7CgkJYnJlYWs7CgljYXNlIE9NQVBfRE1BX1RSQU5TUEFSRU5UX0NPUFk6CgkJdyB8PSAweDAyOwoJCWJyZWFrOwoJY2FzZSBPTUFQX0RNQV9DT0xPUl9ESVM6CgkJYnJlYWs7CglkZWZhdWx0OgoJCUJVRygpOwoJfQoJT01BUDFfRE1BX0NDUjJfUkVHKGxjaCkgPSB3OwoKCXcgPSBPTUFQMV9ETUFfTENIX0NUUkxfUkVHKGxjaCkgJiB+MHgwZjsKCS8qIERlZmF1bHQgaXMgY2hhbm5lbCB0eXBlIDJEICovCglpZiAobW9kZSkgewoJCU9NQVAxX0RNQV9DT0xPUl9MX1JFRyhsY2gpID0gKHUxNiljb2xvcjsKCQlPTUFQMV9ETUFfQ09MT1JfVV9SRUcobGNoKSA9ICh1MTYpKGNvbG9yID4+IDE2KTsKCQl3IHw9IDE7CQkvKiBDaGFubmVsIHR5cGUgRyAqLwoJfQoJT01BUDFfRE1BX0xDSF9DVFJMX1JFRyhsY2gpID0gdzsKfQoKLyogTm90ZSB0aGF0IHNyY19wb3J0IGlzIG9ubHkgZm9yIG9tYXAxICovCnZvaWQgb21hcF9zZXRfZG1hX3NyY19wYXJhbXMoaW50IGxjaCwgaW50IHNyY19wb3J0LCBpbnQgc3JjX2Ftb2RlLAoJCQkgICAgIHVuc2lnbmVkIGxvbmcgc3JjX3N0YXJ0LAoJCQkgICAgIGludCBzcmNfZWksIGludCBzcmNfZmkpCnsKCWlmIChjcHVfY2xhc3NfaXNfb21hcDEoKSkgewoJCU9NQVBfRE1BX0NTRFBfUkVHKGxjaCkgJj0gfigweDFmIDw8IDIpOwoJCU9NQVBfRE1BX0NTRFBfUkVHKGxjaCkgfD0gc3JjX3BvcnQgPDwgMjsKCX0KCglPTUFQX0RNQV9DQ1JfUkVHKGxjaCkgJj0gfigweDAzIDw8IDEyKTsKCU9NQVBfRE1BX0NDUl9SRUcobGNoKSB8PSBzcmNfYW1vZGUgPDwgMTI7CgoJaWYgKGNwdV9jbGFzc19pc19vbWFwMSgpKSB7CgkJT01BUDFfRE1BX0NTU0FfVV9SRUcobGNoKSA9IHNyY19zdGFydCA+PiAxNjsKCQlPTUFQMV9ETUFfQ1NTQV9MX1JFRyhsY2gpID0gc3JjX3N0YXJ0OwoJfQoKCWlmIChjcHVfaXNfb21hcDI0eHgoKSkKCQlPTUFQMl9ETUFfQ1NTQV9SRUcobGNoKSA9IHNyY19zdGFydDsKCglPTUFQX0RNQV9DU0VJX1JFRyhsY2gpID0gc3JjX2VpOwoJT01BUF9ETUFfQ1NGSV9SRUcobGNoKSA9IHNyY19maTsKfQoKdm9pZCBvbWFwX3NldF9kbWFfcGFyYW1zKGludCBsY2gsIHN0cnVjdCBvbWFwX2RtYV9jaGFubmVsX3BhcmFtcyAqIHBhcmFtcykKewoJb21hcF9zZXRfZG1hX3RyYW5zZmVyX3BhcmFtcyhsY2gsIHBhcmFtcy0+ZGF0YV90eXBlLAoJCQkJICAgICBwYXJhbXMtPmVsZW1fY291bnQsIHBhcmFtcy0+ZnJhbWVfY291bnQsCgkJCQkgICAgIHBhcmFtcy0+c3luY19tb2RlLCBwYXJhbXMtPnRyaWdnZXIsCgkJCQkgICAgIHBhcmFtcy0+c3JjX29yX2RzdF9zeW5jaCk7CglvbWFwX3NldF9kbWFfc3JjX3BhcmFtcyhsY2gsIHBhcmFtcy0+c3JjX3BvcnQsCgkJCQlwYXJhbXMtPnNyY19hbW9kZSwgcGFyYW1zLT5zcmNfc3RhcnQsCgkJCQlwYXJhbXMtPnNyY19laSwgcGFyYW1zLT5zcmNfZmkpOwoKCW9tYXBfc2V0X2RtYV9kZXN0X3BhcmFtcyhsY2gsIHBhcmFtcy0+ZHN0X3BvcnQsCgkJCQkgcGFyYW1zLT5kc3RfYW1vZGUsIHBhcmFtcy0+ZHN0X3N0YXJ0LAoJCQkJIHBhcmFtcy0+ZHN0X2VpLCBwYXJhbXMtPmRzdF9maSk7Cn0KCnZvaWQgb21hcF9zZXRfZG1hX3NyY19pbmRleChpbnQgbGNoLCBpbnQgZWlkeCwgaW50IGZpZHgpCnsKCWlmIChjcHVfaXNfb21hcDI0eHgoKSkgewoJCVJFVklTSVRfMjRYWCgpOwoJCXJldHVybjsKCX0KCU9NQVBfRE1BX0NTRUlfUkVHKGxjaCkgPSBlaWR4OwoJT01BUF9ETUFfQ1NGSV9SRUcobGNoKSA9IGZpZHg7Cn0KCnZvaWQgb21hcF9zZXRfZG1hX3NyY19kYXRhX3BhY2soaW50IGxjaCwgaW50IGVuYWJsZSkKewoJT01BUF9ETUFfQ1NEUF9SRUcobGNoKSAmPSB+KDEgPDwgNik7CglpZiAoZW5hYmxlKQoJCU9NQVBfRE1BX0NTRFBfUkVHKGxjaCkgfD0gKDEgPDwgNik7Cn0KCnZvaWQgb21hcF9zZXRfZG1hX3NyY19idXJzdF9tb2RlKGludCBsY2gsIGVudW0gb21hcF9kbWFfYnVyc3RfbW9kZSBidXJzdF9tb2RlKQp7CglPTUFQX0RNQV9DU0RQX1JFRyhsY2gpICY9IH4oMHgwMyA8PCA3KTsKCglzd2l0Y2ggKGJ1cnN0X21vZGUpIHsKCWNhc2UgT01BUF9ETUFfREFUQV9CVVJTVF9ESVM6CgkJYnJlYWs7CgljYXNlIE9NQVBfRE1BX0RBVEFfQlVSU1RfNDoKCQlPTUFQX0RNQV9DU0RQX1JFRyhsY2gpIHw9ICgweDAyIDw8IDcpOwoJCWJyZWFrOwoJY2FzZSBPTUFQX0RNQV9EQVRBX0JVUlNUXzg6CgkJLyogbm90IHN1cHBvcnRlZCBieSBjdXJyZW50IGhhcmR3YXJlCgkJICogdyB8PSAoMHgwMyA8PCA3KTsKCQkgKiBmYWxsIHRocm91Z2gKCQkgKi8KCWRlZmF1bHQ6CgkJQlVHKCk7Cgl9Cn0KCi8qIE5vdGUgdGhhdCBkZXN0X3BvcnQgaXMgb25seSBmb3IgT01BUDEgKi8Kdm9pZCBvbWFwX3NldF9kbWFfZGVzdF9wYXJhbXMoaW50IGxjaCwgaW50IGRlc3RfcG9ydCwgaW50IGRlc3RfYW1vZGUsCgkJCSAgICAgIHVuc2lnbmVkIGxvbmcgZGVzdF9zdGFydCwKCQkJICAgICAgaW50IGRzdF9laSwgaW50IGRzdF9maSkKewoJaWYgKGNwdV9jbGFzc19pc19vbWFwMSgpKSB7CgkJT01BUF9ETUFfQ1NEUF9SRUcobGNoKSAmPSB+KDB4MWYgPDwgOSk7CgkJT01BUF9ETUFfQ1NEUF9SRUcobGNoKSB8PSBkZXN0X3BvcnQgPDwgOTsKCX0KCglPTUFQX0RNQV9DQ1JfUkVHKGxjaCkgJj0gfigweDAzIDw8IDE0KTsKCU9NQVBfRE1BX0NDUl9SRUcobGNoKSB8PSBkZXN0X2Ftb2RlIDw8IDE0OwoKCWlmIChjcHVfY2xhc3NfaXNfb21hcDEoKSkgewoJCU9NQVAxX0RNQV9DRFNBX1VfUkVHKGxjaCkgPSBkZXN0X3N0YXJ0ID4+IDE2OwoJCU9NQVAxX0RNQV9DRFNBX0xfUkVHKGxjaCkgPSBkZXN0X3N0YXJ0OwoJfQoKCWlmIChjcHVfaXNfb21hcDI0eHgoKSkKCQlPTUFQMl9ETUFfQ0RTQV9SRUcobGNoKSA9IGRlc3Rfc3RhcnQ7CgoJT01BUF9ETUFfQ0RFSV9SRUcobGNoKSA9IGRzdF9laTsKCU9NQVBfRE1BX0NERklfUkVHKGxjaCkgPSBkc3RfZmk7Cn0KCnZvaWQgb21hcF9zZXRfZG1hX2Rlc3RfaW5kZXgoaW50IGxjaCwgaW50IGVpZHgsIGludCBmaWR4KQp7CglpZiAoY3B1X2lzX29tYXAyNHh4KCkpIHsKCQlSRVZJU0lUXzI0WFgoKTsKCQlyZXR1cm47Cgl9CglPTUFQX0RNQV9DREVJX1JFRyhsY2gpID0gZWlkeDsKCU9NQVBfRE1BX0NERklfUkVHKGxjaCkgPSBmaWR4Owp9Cgp2b2lkIG9tYXBfc2V0X2RtYV9kZXN0X2RhdGFfcGFjayhpbnQgbGNoLCBpbnQgZW5hYmxlKQp7CglPTUFQX0RNQV9DU0RQX1JFRyhsY2gpICY9IH4oMSA8PCAxMyk7CglpZiAoZW5hYmxlKQoJCU9NQVBfRE1BX0NTRFBfUkVHKGxjaCkgfD0gMSA8PCAxMzsKfQoKdm9pZCBvbWFwX3NldF9kbWFfZGVzdF9idXJzdF9tb2RlKGludCBsY2gsIGVudW0gb21hcF9kbWFfYnVyc3RfbW9kZSBidXJzdF9tb2RlKQp7CglPTUFQX0RNQV9DU0RQX1JFRyhsY2gpICY9IH4oMHgwMyA8PCAxNCk7CgoJc3dpdGNoIChidXJzdF9tb2RlKSB7CgljYXNlIE9NQVBfRE1BX0RBVEFfQlVSU1RfRElTOgoJCWJyZWFrOwoJY2FzZSBPTUFQX0RNQV9EQVRBX0JVUlNUXzQ6CgkJT01BUF9ETUFfQ1NEUF9SRUcobGNoKSB8PSAoMHgwMiA8PCAxNCk7CgkJYnJlYWs7CgljYXNlIE9NQVBfRE1BX0RBVEFfQlVSU1RfODoKCQlPTUFQX0RNQV9DU0RQX1JFRyhsY2gpIHw9ICgweDAzIDw8IDE0KTsKCQlicmVhazsKCWRlZmF1bHQ6CgkJcHJpbnRrKEtFUk5fRVJSICJJbnZhbGlkIERNQSBidXJzdCBtb2RlXG4iKTsKCQlCVUcoKTsKCQlyZXR1cm47Cgl9Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBvbWFwX2VuYWJsZV9jaGFubmVsX2lycShpbnQgbGNoKQp7Cgl1MzIgc3RhdHVzOwoKCS8qIFJlYWQgQ1NSIHRvIG1ha2Ugc3VyZSBpdCdzIGNsZWFyZWQuICovCglzdGF0dXMgPSBPTUFQX0RNQV9DU1JfUkVHKGxjaCk7CgoJLyogRW5hYmxlIHNvbWUgbmljZSBpbnRlcnJ1cHRzLiAqLwoJT01BUF9ETUFfQ0lDUl9SRUcobGNoKSA9IGRtYV9jaGFuW2xjaF0uZW5hYmxlZF9pcnFzOwoKCWRtYV9jaGFuW2xjaF0uZmxhZ3MgfD0gT01BUF9ETUFfQUNUSVZFOwp9CgpzdGF0aWMgdm9pZCBvbWFwX2Rpc2FibGVfY2hhbm5lbF9pcnEoaW50IGxjaCkKewoJaWYgKGNwdV9pc19vbWFwMjR4eCgpKQoJCU9NQVBfRE1BX0NJQ1JfUkVHKGxjaCkgPSAwOwp9Cgp2b2lkIG9tYXBfZW5hYmxlX2RtYV9pcnEoaW50IGxjaCwgdTE2IGJpdHMpCnsKCWRtYV9jaGFuW2xjaF0uZW5hYmxlZF9pcnFzIHw9IGJpdHM7Cn0KCnZvaWQgb21hcF9kaXNhYmxlX2RtYV9pcnEoaW50IGxjaCwgdTE2IGJpdHMpCnsKCWRtYV9jaGFuW2xjaF0uZW5hYmxlZF9pcnFzICY9IH5iaXRzOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgZW5hYmxlX2xuayhpbnQgbGNoKQp7CglpZiAoY3B1X2NsYXNzX2lzX29tYXAxKCkpCgkJT01BUF9ETUFfQ0xOS19DVFJMX1JFRyhsY2gpICY9IH4oMSA8PCAxNCk7CgoJLyogU2V0IHRoZSBFTkFCTEVfTE5LIGJpdHMgKi8KCWlmIChkbWFfY2hhbltsY2hdLm5leHRfbGNoICE9IC0xKQoJCU9NQVBfRE1BX0NMTktfQ1RSTF9SRUcobGNoKSA9CgkJCWRtYV9jaGFuW2xjaF0ubmV4dF9sY2ggfCAoMSA8PCAxNSk7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBkaXNhYmxlX2xuayhpbnQgbGNoKQp7CgkvKiBEaXNhYmxlIGludGVycnVwdHMgKi8KCWlmIChjcHVfY2xhc3NfaXNfb21hcDEoKSkgewoJCU9NQVBfRE1BX0NJQ1JfUkVHKGxjaCkgPSAwOwoJCS8qIFNldCB0aGUgU1RPUF9MTksgYml0ICovCgkJT01BUF9ETUFfQ0xOS19DVFJMX1JFRyhsY2gpIHw9IDEgPDwgMTQ7Cgl9CgoJaWYgKGNwdV9pc19vbWFwMjR4eCgpKSB7CgkJb21hcF9kaXNhYmxlX2NoYW5uZWxfaXJxKGxjaCk7CgkJLyogQ2xlYXIgdGhlIEVOQUJMRV9MTksgYml0ICovCgkJT01BUF9ETUFfQ0xOS19DVFJMX1JFRyhsY2gpICY9IH4oMSA8PCAxNSk7Cgl9CgoJZG1hX2NoYW5bbGNoXS5mbGFncyAmPSB+T01BUF9ETUFfQUNUSVZFOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgb21hcDJfZW5hYmxlX2lycV9sY2goaW50IGxjaCkKewoJdTMyIHZhbDsKCglpZiAoIWNwdV9pc19vbWFwMjR4eCgpKQoJCXJldHVybjsKCgl2YWwgPSBvbWFwX3JlYWRsKE9NQVBfRE1BNF9JUlFFTkFCTEVfTDApOwoJdmFsIHw9IDEgPDwgbGNoOwoJb21hcF93cml0ZWwodmFsLCBPTUFQX0RNQTRfSVJRRU5BQkxFX0wwKTsKfQoKaW50IG9tYXBfcmVxdWVzdF9kbWEoaW50IGRldl9pZCwgY29uc3QgY2hhciAqZGV2X25hbWUsCgkJICAgICB2b2lkICgqIGNhbGxiYWNrKShpbnQgbGNoLCB1MTYgY2hfc3RhdHVzLCB2b2lkICpkYXRhKSwKCQkgICAgIHZvaWQgKmRhdGEsIGludCAqZG1hX2NoX291dCkKewoJaW50IGNoLCBmcmVlX2NoID0gLTE7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoJc3RydWN0IG9tYXBfZG1hX2xjaCAqY2hhbjsKCglzcGluX2xvY2tfaXJxc2F2ZSgmZG1hX2NoYW5fbG9jaywgZmxhZ3MpOwoJZm9yIChjaCA9IDA7IGNoIDwgZG1hX2NoYW5fY291bnQ7IGNoKyspIHsKCQlpZiAoZnJlZV9jaCA9PSAtMSAmJiBkbWFfY2hhbltjaF0uZGV2X2lkID09IC0xKSB7CgkJCWZyZWVfY2ggPSBjaDsKCQkJaWYgKGRldl9pZCA9PSAwKQoJCQkJYnJlYWs7CgkJfQoJfQoJaWYgKGZyZWVfY2ggPT0gLTEpIHsKCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZkbWFfY2hhbl9sb2NrLCBmbGFncyk7CgkJcmV0dXJuIC1FQlVTWTsKCX0KCWNoYW4gPSBkbWFfY2hhbiArIGZyZWVfY2g7CgljaGFuLT5kZXZfaWQgPSBkZXZfaWQ7CgoJaWYgKGNwdV9jbGFzc19pc19vbWFwMSgpKQoJCWNsZWFyX2xjaF9yZWdzKGZyZWVfY2gpOwoKCWlmIChjcHVfaXNfb21hcDI0eHgoKSkKCQlvbWFwX2NsZWFyX2RtYShmcmVlX2NoKTsKCglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZkbWFfY2hhbl9sb2NrLCBmbGFncyk7CgoJY2hhbi0+ZGV2X25hbWUgPSBkZXZfbmFtZTsKCWNoYW4tPmNhbGxiYWNrID0gY2FsbGJhY2s7CgljaGFuLT5kYXRhID0gZGF0YTsKCWNoYW4tPmVuYWJsZWRfaXJxcyA9IE9NQVBfRE1BX1RPVVRfSVJRIHwgT01BUF9ETUFfRFJPUF9JUlEgfAoJCQkJT01BUF9ETUFfQkxPQ0tfSVJROwoKCWlmIChjcHVfaXNfb21hcDI0eHgoKSkKCQljaGFuLT5lbmFibGVkX2lycXMgfD0gT01BUDJfRE1BX1RSQU5TX0VSUl9JUlE7CgoJaWYgKGNwdV9pc19vbWFwMTZ4eCgpKSB7CgkJLyogSWYgdGhlIHN5bmMgZGV2aWNlIGlzIHNldCwgY29uZmlndXJlIGl0IGR5bmFtaWNhbGx5LiAqLwoJCWlmIChkZXZfaWQgIT0gMCkgewoJCQlzZXRfZ2RtYV9kZXYoZnJlZV9jaCArIDEsIGRldl9pZCk7CgkJCWRldl9pZCA9IGZyZWVfY2ggKyAxOwoJCX0KCQkvKiBEaXNhYmxlIHRoZSAxNTEwIGNvbXBhdGliaWxpdHkgbW9kZSBhbmQgc2V0IHRoZSBzeW5jIGRldmljZQoJCSAqIGlkLiAqLwoJCU9NQVBfRE1BX0NDUl9SRUcoZnJlZV9jaCkgPSBkZXZfaWQgfCAoMSA8PCAxMCk7Cgl9IGVsc2UgaWYgKGNwdV9pc19vbWFwNzMwKCkgfHwgY3B1X2lzX29tYXAxNXh4KCkpIHsKCQlPTUFQX0RNQV9DQ1JfUkVHKGZyZWVfY2gpID0gZGV2X2lkOwoJfQoKCWlmIChjcHVfaXNfb21hcDI0eHgoKSkgewoJCW9tYXAyX2VuYWJsZV9pcnFfbGNoKGZyZWVfY2gpOwoKCQlvbWFwX2VuYWJsZV9jaGFubmVsX2lycShmcmVlX2NoKTsKCQkvKiBDbGVhciB0aGUgQ1NSIHJlZ2lzdGVyIGFuZCBJUlEgc3RhdHVzIHJlZ2lzdGVyICovCgkJT01BUF9ETUFfQ1NSX1JFRyhmcmVlX2NoKSA9IDB4MDsKCQlvbWFwX3dyaXRlbCh+MHgwLCBPTUFQX0RNQTRfSVJRU1RBVFVTX0wwKTsKCX0KCgkqZG1hX2NoX291dCA9IGZyZWVfY2g7CgoJcmV0dXJuIDA7Cn0KCnZvaWQgb21hcF9mcmVlX2RtYShpbnQgbGNoKQp7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCXNwaW5fbG9ja19pcnFzYXZlKCZkbWFfY2hhbl9sb2NrLCBmbGFncyk7CglpZiAoZG1hX2NoYW5bbGNoXS5kZXZfaWQgPT0gLTEpIHsKCQlwcmludGsoIm9tYXBfZG1hOiB0cnlpbmcgdG8gZnJlZSBub25hbGxvY2F0ZWQgRE1BIGNoYW5uZWwgJWRcbiIsCgkJICAgICAgIGxjaCk7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmZG1hX2NoYW5fbG9jaywgZmxhZ3MpOwoJCXJldHVybjsKCX0KCWRtYV9jaGFuW2xjaF0uZGV2X2lkID0gLTE7CglkbWFfY2hhbltsY2hdLm5leHRfbGNoID0gLTE7CglkbWFfY2hhbltsY2hdLmNhbGxiYWNrID0gTlVMTDsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmRtYV9jaGFuX2xvY2ssIGZsYWdzKTsKCglpZiAoY3B1X2NsYXNzX2lzX29tYXAxKCkpIHsKCQkvKiBEaXNhYmxlIGFsbCBETUEgaW50ZXJydXB0cyBmb3IgdGhlIGNoYW5uZWwuICovCgkJT01BUF9ETUFfQ0lDUl9SRUcobGNoKSA9IDA7CgkJLyogTWFrZSBzdXJlIHRoZSBETUEgdHJhbnNmZXIgaXMgc3RvcHBlZC4gKi8KCQlPTUFQX0RNQV9DQ1JfUkVHKGxjaCkgPSAwOwoJfQoKCWlmIChjcHVfaXNfb21hcDI0eHgoKSkgewoJCXUzMiB2YWw7CgkJLyogRGlzYWJsZSBpbnRlcnJ1cHRzICovCgkJdmFsID0gb21hcF9yZWFkbChPTUFQX0RNQTRfSVJRRU5BQkxFX0wwKTsKCQl2YWwgJj0gfigxIDw8IGxjaCk7CgkJb21hcF93cml0ZWwodmFsLCBPTUFQX0RNQTRfSVJRRU5BQkxFX0wwKTsKCgkJLyogQ2xlYXIgdGhlIENTUiByZWdpc3RlciBhbmQgSVJRIHN0YXR1cyByZWdpc3RlciAqLwoJCU9NQVBfRE1BX0NTUl9SRUcobGNoKSA9IDB4MDsKCgkJdmFsID0gb21hcF9yZWFkbChPTUFQX0RNQTRfSVJRU1RBVFVTX0wwKTsKCQl2YWwgfD0gMSA8PCBsY2g7CgkJb21hcF93cml0ZWwodmFsLCBPTUFQX0RNQTRfSVJRU1RBVFVTX0wwKTsKCgkJLyogRGlzYWJsZSBhbGwgRE1BIGludGVycnVwdHMgZm9yIHRoZSBjaGFubmVsLiAqLwoJCU9NQVBfRE1BX0NJQ1JfUkVHKGxjaCkgPSAwOwoKCQkvKiBNYWtlIHN1cmUgdGhlIERNQSB0cmFuc2ZlciBpcyBzdG9wcGVkLiAqLwoJCU9NQVBfRE1BX0NDUl9SRUcobGNoKSA9IDA7CgkJb21hcF9jbGVhcl9kbWEobGNoKTsKCX0KfQoKLyoKICogQ2xlYXJzIGFueSBETUEgc3RhdGUgc28gdGhlIERNQSBlbmdpbmUgaXMgcmVhZHkgdG8gcmVzdGFydCB3aXRoIG5ldyBidWZmZXJzCiAqIHRocm91Z2ggb21hcF9zdGFydF9kbWEoKS4gQW55IGJ1ZmZlcnMgaW4gZmxpZ2h0IGFyZSBkaXNjYXJkZWQuCiAqLwp2b2lkIG9tYXBfY2xlYXJfZG1hKGludCBsY2gpCnsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJbG9jYWxfaXJxX3NhdmUoZmxhZ3MpOwoKCWlmIChjcHVfY2xhc3NfaXNfb21hcDEoKSkgewoJCWludCBzdGF0dXM7CgkJT01BUF9ETUFfQ0NSX1JFRyhsY2gpICY9IH5PTUFQX0RNQV9DQ1JfRU47CgoJCS8qIENsZWFyIHBlbmRpbmcgaW50ZXJydXB0cyAqLwoJCXN0YXR1cyA9IE9NQVBfRE1BX0NTUl9SRUcobGNoKTsKCX0KCglpZiAoY3B1X2lzX29tYXAyNHh4KCkpIHsKCQlpbnQgaTsKCQl1MzIgbGNoX2Jhc2UgPSBPTUFQMjRYWF9ETUFfQkFTRSArIGxjaCAqIDB4NjAgKyAweDgwOwoJCWZvciAoaSA9IDA7IGkgPCAweDQ0OyBpICs9IDQpCgkJCW9tYXBfd3JpdGVsKDAsIGxjaF9iYXNlICsgaSk7Cgl9CgoJbG9jYWxfaXJxX3Jlc3RvcmUoZmxhZ3MpOwp9Cgp2b2lkIG9tYXBfc3RhcnRfZG1hKGludCBsY2gpCnsKCWlmICghb21hcF9kbWFfaW5fMTUxMF9tb2RlKCkgJiYgZG1hX2NoYW5bbGNoXS5uZXh0X2xjaCAhPSAtMSkgewoJCWludCBuZXh0X2xjaCwgY3VyX2xjaDsKCQljaGFyIGRtYV9jaGFuX2xpbmtfbWFwW09NQVBfTE9HSUNBTF9ETUFfQ0hfQ09VTlRdOwoKCQlkbWFfY2hhbl9saW5rX21hcFtsY2hdID0gMTsKCQkvKiBTZXQgdGhlIGxpbmsgcmVnaXN0ZXIgb2YgdGhlIGZpcnN0IGNoYW5uZWwgKi8KCQllbmFibGVfbG5rKGxjaCk7CgoJCW1lbXNldChkbWFfY2hhbl9saW5rX21hcCwgMCwgc2l6ZW9mKGRtYV9jaGFuX2xpbmtfbWFwKSk7CgkJY3VyX2xjaCA9IGRtYV9jaGFuW2xjaF0ubmV4dF9sY2g7CgkJZG8gewoJCQluZXh0X2xjaCA9IGRtYV9jaGFuW2N1cl9sY2hdLm5leHRfbGNoOwoKCQkJLyogVGhlIGxvb3AgY2FzZTogd2UndmUgYmVlbiBoZXJlIGFscmVhZHkgKi8KCQkJaWYgKGRtYV9jaGFuX2xpbmtfbWFwW2N1cl9sY2hdKQoJCQkJYnJlYWs7CgkJCS8qIE1hcmsgdGhlIGN1cnJlbnQgY2hhbm5lbCAqLwoJCQlkbWFfY2hhbl9saW5rX21hcFtjdXJfbGNoXSA9IDE7CgoJCQllbmFibGVfbG5rKGN1cl9sY2gpOwoJCQlvbWFwX2VuYWJsZV9jaGFubmVsX2lycShjdXJfbGNoKTsKCgkJCWN1cl9sY2ggPSBuZXh0X2xjaDsKCQl9IHdoaWxlIChuZXh0X2xjaCAhPSAtMSk7Cgl9IGVsc2UgaWYgKGNwdV9pc19vbWFwMjR4eCgpKSB7CgkJLyogRXJyYXRhOiBOZWVkIHRvIHdyaXRlIGxjaCBldmVuIGlmIG5vdCB1c2luZyBjaGFpbmluZyAqLwoJCU9NQVBfRE1BX0NMTktfQ1RSTF9SRUcobGNoKSA9IGxjaDsKCX0KCglvbWFwX2VuYWJsZV9jaGFubmVsX2lycShsY2gpOwoKCS8qIEVycmF0YTogT24gRVMyLjAgQlVGRkVSSU5HIGRpc2FibGUgbXVzdCBiZSBzZXQuCgkgKiBUaGlzIHdpbGwgYWx3YXlzIGZhaWwgb24gRVMxLjAgKi8KCWlmIChjcHVfaXNfb21hcDI0eHgoKSkgewoJCU9NQVBfRE1BX0NDUl9SRUcobGNoKSB8PSBPTUFQX0RNQV9DQ1JfRU47Cgl9CgoJT01BUF9ETUFfQ0NSX1JFRyhsY2gpIHw9IE9NQVBfRE1BX0NDUl9FTjsKCglkbWFfY2hhbltsY2hdLmZsYWdzIHw9IE9NQVBfRE1BX0FDVElWRTsKfQoKdm9pZCBvbWFwX3N0b3BfZG1hKGludCBsY2gpCnsKCWlmICghb21hcF9kbWFfaW5fMTUxMF9tb2RlKCkgJiYgZG1hX2NoYW5bbGNoXS5uZXh0X2xjaCAhPSAtMSkgewoJCWludCBuZXh0X2xjaCwgY3VyX2xjaCA9IGxjaDsKCQljaGFyIGRtYV9jaGFuX2xpbmtfbWFwW09NQVBfTE9HSUNBTF9ETUFfQ0hfQ09VTlRdOwoKCQltZW1zZXQoZG1hX2NoYW5fbGlua19tYXAsIDAsIHNpemVvZihkbWFfY2hhbl9saW5rX21hcCkpOwoJCWRvIHsKCQkJLyogVGhlIGxvb3AgY2FzZTogd2UndmUgYmVlbiBoZXJlIGFscmVhZHkgKi8KCQkJaWYgKGRtYV9jaGFuX2xpbmtfbWFwW2N1cl9sY2hdKQoJCQkJYnJlYWs7CgkJCS8qIE1hcmsgdGhlIGN1cnJlbnQgY2hhbm5lbCAqLwoJCQlkbWFfY2hhbl9saW5rX21hcFtjdXJfbGNoXSA9IDE7CgoJCQlkaXNhYmxlX2xuayhjdXJfbGNoKTsKCgkJCW5leHRfbGNoID0gZG1hX2NoYW5bY3VyX2xjaF0ubmV4dF9sY2g7CgkJCWN1cl9sY2ggPSBuZXh0X2xjaDsKCQl9IHdoaWxlIChuZXh0X2xjaCAhPSAtMSk7CgoJCXJldHVybjsKCX0KCgkvKiBEaXNhYmxlIGFsbCBpbnRlcnJ1cHRzIG9uIHRoZSBjaGFubmVsICovCglpZiAoY3B1X2NsYXNzX2lzX29tYXAxKCkpCgkJT01BUF9ETUFfQ0lDUl9SRUcobGNoKSA9IDA7CgoJT01BUF9ETUFfQ0NSX1JFRyhsY2gpICY9IH5PTUFQX0RNQV9DQ1JfRU47CglkbWFfY2hhbltsY2hdLmZsYWdzICY9IH5PTUFQX0RNQV9BQ1RJVkU7Cn0KCi8qCiAqIFJldHVybnMgY3VycmVudCBwaHlzaWNhbCBzb3VyY2UgYWRkcmVzcyBmb3IgdGhlIGdpdmVuIERNQSBjaGFubmVsLgogKiBJZiB0aGUgY2hhbm5lbCBpcyBydW5uaW5nIHRoZSBjYWxsZXIgbXVzdCBkaXNhYmxlIGludGVycnVwdHMgcHJpb3IgY2FsbGluZwogKiB0aGlzIGZ1bmN0aW9uIGFuZCBwcm9jZXNzIHRoZSByZXR1cm5lZCB2YWx1ZSBiZWZvcmUgcmUtZW5hYmxpbmcgaW50ZXJydXB0IHRvCiAqIHByZXZlbnQgcmFjZXMgd2l0aCB0aGUgaW50ZXJydXB0IGhhbmRsZXIuIE5vdGUgdGhhdCBpbiBjb250aW51b3VzIG1vZGUgdGhlcmUKICogaXMgYSBjaGFuY2UgZm9yIENTU0FfTCByZWdpc3RlciBvdmVyZmxvdyBpbmJldHdlZW4gdGhlIHR3byByZWFkcyByZXN1bHRpbmcKICogaW4gaW5jb3JyZWN0IHJldHVybiB2YWx1ZS4KICovCmRtYV9hZGRyX3Qgb21hcF9nZXRfZG1hX3NyY19wb3MoaW50IGxjaCkKewoJZG1hX2FkZHJfdCBvZmZzZXQ7CgoJaWYgKGNwdV9jbGFzc19pc19vbWFwMSgpKQoJCW9mZnNldCA9IChkbWFfYWRkcl90KSAoT01BUDFfRE1BX0NTU0FfTF9SRUcobGNoKSB8CgkJCQkgICAgICAgKE9NQVAxX0RNQV9DU1NBX1VfUkVHKGxjaCkgPDwgMTYpKTsKCglpZiAoY3B1X2lzX29tYXAyNHh4KCkpCgkJb2Zmc2V0ID0gT01BUF9ETUFfQ1NBQ19SRUcobGNoKTsKCglyZXR1cm4gb2Zmc2V0Owp9CgovKgogKiBSZXR1cm5zIGN1cnJlbnQgcGh5c2ljYWwgZGVzdGluYXRpb24gYWRkcmVzcyBmb3IgdGhlIGdpdmVuIERNQSBjaGFubmVsLgogKiBJZiB0aGUgY2hhbm5lbCBpcyBydW5uaW5nIHRoZSBjYWxsZXIgbXVzdCBkaXNhYmxlIGludGVycnVwdHMgcHJpb3IgY2FsbGluZwogKiB0aGlzIGZ1bmN0aW9uIGFuZCBwcm9jZXNzIHRoZSByZXR1cm5lZCB2YWx1ZSBiZWZvcmUgcmUtZW5hYmxpbmcgaW50ZXJydXB0IHRvCiAqIHByZXZlbnQgcmFjZXMgd2l0aCB0aGUgaW50ZXJydXB0IGhhbmRsZXIuIE5vdGUgdGhhdCBpbiBjb250aW51b3VzIG1vZGUgdGhlcmUKICogaXMgYSBjaGFuY2UgZm9yIENEU0FfTCByZWdpc3RlciBvdmVyZmxvdyBpbmJldHdlZW4gdGhlIHR3byByZWFkcyByZXN1bHRpbmcKICogaW4gaW5jb3JyZWN0IHJldHVybiB2YWx1ZS4KICovCmRtYV9hZGRyX3Qgb21hcF9nZXRfZG1hX2RzdF9wb3MoaW50IGxjaCkKewoJZG1hX2FkZHJfdCBvZmZzZXQ7CgoJaWYgKGNwdV9jbGFzc19pc19vbWFwMSgpKQoJCW9mZnNldCA9IChkbWFfYWRkcl90KSAoT01BUDFfRE1BX0NEU0FfTF9SRUcobGNoKSB8CgkJCQkgICAgICAgKE9NQVAxX0RNQV9DRFNBX1VfUkVHKGxjaCkgPDwgMTYpKTsKCglpZiAoY3B1X2lzX29tYXAyNHh4KCkpCgkJb2Zmc2V0ID0gT01BUDJfRE1BX0NEU0FfUkVHKGxjaCk7CgoJcmV0dXJuIG9mZnNldDsKfQoKLyoKICogUmV0dXJucyBjdXJyZW50IHNvdXJjZSB0cmFuc2ZlciBjb3VudGluZyBmb3IgdGhlIGdpdmVuIERNQSBjaGFubmVsLgogKiBDYW4gYmUgdXNlZCB0byBtb25pdG9yIHRoZSBwcm9ncmVzcyBvZiBhIHRyYW5zZmVyIGluc2lkZSBhIGJsb2NrLgogKiBJdCBtdXN0IGJlIGNhbGxlZCB3aXRoIGRpc2FibGVkIGludGVycnVwdHMuCiAqLwppbnQgb21hcF9nZXRfZG1hX3NyY19hZGRyX2NvdW50ZXIoaW50IGxjaCkKewoJcmV0dXJuIChkbWFfYWRkcl90KSBPTUFQX0RNQV9DU0FDX1JFRyhsY2gpOwp9CgppbnQgb21hcF9kbWFfcnVubmluZyh2b2lkKQp7CglpbnQgbGNoOwoKCS8qIENoZWNrIGlmIExDRCBETUEgaXMgcnVubmluZyAqLwoJaWYgKGNwdV9pc19vbWFwMTZ4eCgpKQoJCWlmIChvbWFwX3JlYWR3KE9NQVAxNjEwX0RNQV9MQ0RfQ0NSKSAmIE9NQVBfRE1BX0NDUl9FTikKCQkJcmV0dXJuIDE7CgoJZm9yIChsY2ggPSAwOyBsY2ggPCBkbWFfY2hhbl9jb3VudDsgbGNoKyspCgkJaWYgKE9NQVBfRE1BX0NDUl9SRUcobGNoKSAmIE9NQVBfRE1BX0NDUl9FTikKCQkJcmV0dXJuIDE7CgoJcmV0dXJuIDA7Cn0KCi8qCiAqIGxjaF9xdWV1ZSBETUEgd2lsbCBzdGFydCByaWdodCBhZnRlciBsY2hfaGVhZCBvbmUgaXMgZmluaXNoZWQuCiAqIEZvciB0aGlzIERNQSBsaW5rIHRvIHN0YXJ0LCB5b3Ugc3RpbGwgbmVlZCB0byBzdGFydCAoc2VlIG9tYXBfc3RhcnRfZG1hKQogKiB0aGUgZmlyc3Qgb25lLiBUaGF0IHdpbGwgZmlyZSB1cCB0aGUgZW50aXJlIHF1ZXVlLgogKi8Kdm9pZCBvbWFwX2RtYV9saW5rX2xjaCAoaW50IGxjaF9oZWFkLCBpbnQgbGNoX3F1ZXVlKQp7CglpZiAob21hcF9kbWFfaW5fMTUxMF9tb2RlKCkpIHsKCQlwcmludGsoS0VSTl9FUlIgIkRNQSBsaW5raW5nIGlzIG5vdCBzdXBwb3J0ZWQgaW4gMTUxMCBtb2RlXG4iKTsKCQlCVUcoKTsKCQlyZXR1cm47Cgl9CgoJaWYgKChkbWFfY2hhbltsY2hfaGVhZF0uZGV2X2lkID09IC0xKSB8fAoJICAgIChkbWFfY2hhbltsY2hfcXVldWVdLmRldl9pZCA9PSAtMSkpIHsKCQlwcmludGsoS0VSTl9FUlIgIm9tYXBfZG1hOiB0cnlpbmcgdG8gbGluayAiCgkJICAgICAgICJub24gcmVxdWVzdGVkIGNoYW5uZWxzXG4iKTsKCQlkdW1wX3N0YWNrKCk7Cgl9CgoJZG1hX2NoYW5bbGNoX2hlYWRdLm5leHRfbGNoID0gbGNoX3F1ZXVlOwp9CgovKgogKiBPbmNlIHRoZSBETUEgcXVldWUgaXMgc3RvcHBlZCwgd2UgY2FuIGRlc3Ryb3kgaXQuCiAqLwp2b2lkIG9tYXBfZG1hX3VubGlua19sY2ggKGludCBsY2hfaGVhZCwgaW50IGxjaF9xdWV1ZSkKewoJaWYgKG9tYXBfZG1hX2luXzE1MTBfbW9kZSgpKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJETUEgbGlua2luZyBpcyBub3Qgc3VwcG9ydGVkIGluIDE1MTAgbW9kZVxuIik7CgkJQlVHKCk7CgkJcmV0dXJuOwoJfQoKCWlmIChkbWFfY2hhbltsY2hfaGVhZF0ubmV4dF9sY2ggIT0gbGNoX3F1ZXVlIHx8CgkgICAgZG1hX2NoYW5bbGNoX2hlYWRdLm5leHRfbGNoID09IC0xKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJvbWFwX2RtYTogdHJ5aW5nIHRvIHVubGluayAiCgkJICAgICAgICJub24gbGlua2VkIGNoYW5uZWxzXG4iKTsKCQlkdW1wX3N0YWNrKCk7Cgl9CgoKCWlmICgoZG1hX2NoYW5bbGNoX2hlYWRdLmZsYWdzICYgT01BUF9ETUFfQUNUSVZFKSB8fAoJICAgIChkbWFfY2hhbltsY2hfaGVhZF0uZmxhZ3MgJiBPTUFQX0RNQV9BQ1RJVkUpKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJvbWFwX2RtYTogWW91IG5lZWQgdG8gc3RvcCB0aGUgRE1BIGNoYW5uZWxzICIKCQkgICAgICAgImJlZm9yZSB1bmxpbmtpbmdcbiIpOwoJCWR1bXBfc3RhY2soKTsKCX0KCglkbWFfY2hhbltsY2hfaGVhZF0ubmV4dF9sY2ggPSAtMTsKfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCiNpZmRlZiBDT05GSUdfQVJDSF9PTUFQMQoKc3RhdGljIGludCBvbWFwMV9kbWFfaGFuZGxlX2NoKGludCBjaCkKewoJdTE2IGNzcjsKCglpZiAoZW5hYmxlXzE1MTBfbW9kZSAmJiBjaCA+PSA2KSB7CgkJY3NyID0gZG1hX2NoYW5bY2hdLnNhdmVkX2NzcjsKCQlkbWFfY2hhbltjaF0uc2F2ZWRfY3NyID0gMDsKCX0gZWxzZQoJCWNzciA9IE9NQVBfRE1BX0NTUl9SRUcoY2gpOwoJaWYgKGVuYWJsZV8xNTEwX21vZGUgJiYgY2ggPD0gMiAmJiAoY3NyID4+IDcpICE9IDApIHsKCQlkbWFfY2hhbltjaCArIDZdLnNhdmVkX2NzciA9IGNzciA+PiA3OwoJCWNzciAmPSAweDdmOwoJfQoJaWYgKChjc3IgJiAweDNmKSA9PSAwKQoJCXJldHVybiAwOwoJaWYgKHVubGlrZWx5KGRtYV9jaGFuW2NoXS5kZXZfaWQgPT0gLTEpKSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORyAiU3B1cmlvdXMgaW50ZXJydXB0IGZyb20gRE1BIGNoYW5uZWwgIgoJCSAgICAgICAiJWQgKENTUiAlMDR4KVxuIiwgY2gsIGNzcik7CgkJcmV0dXJuIDA7Cgl9CglpZiAodW5saWtlbHkoY3NyICYgT01BUF9ETUFfVE9VVF9JUlEpKQoJCXByaW50ayhLRVJOX1dBUk5JTkcgIkRNQSB0aW1lb3V0IHdpdGggZGV2aWNlICVkXG4iLAoJCSAgICAgICBkbWFfY2hhbltjaF0uZGV2X2lkKTsKCWlmICh1bmxpa2VseShjc3IgJiBPTUFQX0RNQV9EUk9QX0lSUSkpCgkJcHJpbnRrKEtFUk5fV0FSTklORyAiRE1BIHN5bmNocm9uaXphdGlvbiBldmVudCBkcm9wIG9jY3VycmVkICIKCQkgICAgICAgIndpdGggZGV2aWNlICVkXG4iLCBkbWFfY2hhbltjaF0uZGV2X2lkKTsKCWlmIChsaWtlbHkoY3NyICYgT01BUF9ETUFfQkxPQ0tfSVJRKSkKCQlkbWFfY2hhbltjaF0uZmxhZ3MgJj0gfk9NQVBfRE1BX0FDVElWRTsKCWlmIChsaWtlbHkoZG1hX2NoYW5bY2hdLmNhbGxiYWNrICE9IE5VTEwpKQoJCWRtYV9jaGFuW2NoXS5jYWxsYmFjayhjaCwgY3NyLCBkbWFfY2hhbltjaF0uZGF0YSk7CglyZXR1cm4gMTsKfQoKc3RhdGljIGlycXJldHVybl90IG9tYXAxX2RtYV9pcnFfaGFuZGxlcihpbnQgaXJxLCB2b2lkICpkZXZfaWQsCgkJCQkJIHN0cnVjdCBwdF9yZWdzICpyZWdzKQp7CglpbnQgY2ggPSAoKGludCkgZGV2X2lkKSAtIDE7CglpbnQgaGFuZGxlZCA9IDA7CgoJZm9yICg7OykgewoJCWludCBoYW5kbGVkX25vdyA9IDA7CgoJCWhhbmRsZWRfbm93ICs9IG9tYXAxX2RtYV9oYW5kbGVfY2goY2gpOwoJCWlmIChlbmFibGVfMTUxMF9tb2RlICYmIGRtYV9jaGFuW2NoICsgNl0uc2F2ZWRfY3NyKQoJCQloYW5kbGVkX25vdyArPSBvbWFwMV9kbWFfaGFuZGxlX2NoKGNoICsgNik7CgkJaWYgKCFoYW5kbGVkX25vdykKCQkJYnJlYWs7CgkJaGFuZGxlZCArPSBoYW5kbGVkX25vdzsKCX0KCglyZXR1cm4gaGFuZGxlZCA/IElSUV9IQU5ETEVEIDogSVJRX05PTkU7Cn0KCiNlbHNlCiNkZWZpbmUgb21hcDFfZG1hX2lycV9oYW5kbGVyCU5VTEwKI2VuZGlmCgojaWZkZWYgQ09ORklHX0FSQ0hfT01BUDIKCnN0YXRpYyBpbnQgb21hcDJfZG1hX2hhbmRsZV9jaChpbnQgY2gpCnsKCXUzMiBzdGF0dXMgPSBPTUFQX0RNQV9DU1JfUkVHKGNoKTsKCXUzMiB2YWw7CgoJaWYgKCFzdGF0dXMpCgkJcmV0dXJuIDA7CglpZiAodW5saWtlbHkoZG1hX2NoYW5bY2hdLmRldl9pZCA9PSAtMSkpCgkJcmV0dXJuIDA7CgkvKiBSRVZJU0lUOiBBY2NvcmRpbmcgdG8gMjR4eCBUUk0sIHRoZXJlJ3Mgbm8gVE9VVF9JRSAqLwoJaWYgKHVubGlrZWx5KHN0YXR1cyAmIE9NQVBfRE1BX1RPVVRfSVJRKSkKCQlwcmludGsoS0VSTl9JTkZPICJETUEgdGltZW91dCB3aXRoIGRldmljZSAlZFxuIiwKCQkgICAgICAgZG1hX2NoYW5bY2hdLmRldl9pZCk7CglpZiAodW5saWtlbHkoc3RhdHVzICYgT01BUF9ETUFfRFJPUF9JUlEpKQoJCXByaW50ayhLRVJOX0lORk8KCQkgICAgICAgIkRNQSBzeW5jaHJvbml6YXRpb24gZXZlbnQgZHJvcCBvY2N1cnJlZCB3aXRoIGRldmljZSAiCgkJICAgICAgICIlZFxuIiwgZG1hX2NoYW5bY2hdLmRldl9pZCk7CgoJaWYgKHVubGlrZWx5KHN0YXR1cyAmIE9NQVAyX0RNQV9UUkFOU19FUlJfSVJRKSkKCQlwcmludGsoS0VSTl9JTkZPICJETUEgdHJhbnNhY3Rpb24gZXJyb3Igd2l0aCBkZXZpY2UgJWRcbiIsCgkJICAgICAgIGRtYV9jaGFuW2NoXS5kZXZfaWQpOwoKCU9NQVBfRE1BX0NTUl9SRUcoY2gpID0gMHgyMDsKCgl2YWwgPSBvbWFwX3JlYWRsKE9NQVBfRE1BNF9JUlFTVEFUVVNfTDApOwoJLyogY2ggaW4gdGhpcyBmdW5jdGlvbiBpcyBmcm9tIDAtMzEgd2hpbGUgaW4gcmVnaXN0ZXIgaXQgaXMgMS0zMiAqLwoJdmFsID0gMSA8PCAoY2gpOwoJb21hcF93cml0ZWwodmFsLCBPTUFQX0RNQTRfSVJRU1RBVFVTX0wwKTsKCglpZiAobGlrZWx5KGRtYV9jaGFuW2NoXS5jYWxsYmFjayAhPSBOVUxMKSkKCQlkbWFfY2hhbltjaF0uY2FsbGJhY2soY2gsIHN0YXR1cywgZG1hX2NoYW5bY2hdLmRhdGEpOwoKCXJldHVybiAwOwp9CgovKiBTVEFUVVMgcmVnaXN0ZXIgY291bnQgaXMgZnJvbSAxLTMyIHdoaWxlIG91ciBpcyAwLTMxICovCnN0YXRpYyBpcnFyZXR1cm5fdCBvbWFwMl9kbWFfaXJxX2hhbmRsZXIoaW50IGlycSwgdm9pZCAqZGV2X2lkLAoJCQkJCSBzdHJ1Y3QgcHRfcmVncyAqcmVncykKewoJdTMyIHZhbDsKCWludCBpOwoKCXZhbCA9IG9tYXBfcmVhZGwoT01BUF9ETUE0X0lSUVNUQVRVU19MMCk7CgoJZm9yIChpID0gMTsgaSA8PSBPTUFQX0xPR0lDQUxfRE1BX0NIX0NPVU5UOyBpKyspIHsKCQlpbnQgYWN0aXZlID0gdmFsICYgKDEgPDwgKGkgLSAxKSk7CgkJaWYgKGFjdGl2ZSkKCQkJb21hcDJfZG1hX2hhbmRsZV9jaChpIC0gMSk7Cgl9CgoJcmV0dXJuIElSUV9IQU5ETEVEOwp9CgpzdGF0aWMgc3RydWN0IGlycWFjdGlvbiBvbWFwMjR4eF9kbWFfaXJxID0gewoJLm5hbWUgPSAiRE1BIiwKCS5oYW5kbGVyID0gb21hcDJfZG1hX2lycV9oYW5kbGVyLAoJLmZsYWdzID0gU0FfSU5URVJSVVBUCn07CgojZWxzZQpzdGF0aWMgc3RydWN0IGlycWFjdGlvbiBvbWFwMjR4eF9kbWFfaXJxOwojZW5kaWYKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgpzdGF0aWMgc3RydWN0IGxjZF9kbWFfaW5mbyB7CglzcGlubG9ja190IGxvY2s7CglpbnQgcmVzZXJ2ZWQ7Cgl2b2lkICgqIGNhbGxiYWNrKSh1MTYgc3RhdHVzLCB2b2lkICpkYXRhKTsKCXZvaWQgKmNiX2RhdGE7CgoJaW50IGFjdGl2ZTsKCXVuc2lnbmVkIGxvbmcgYWRkciwgc2l6ZTsKCWludCByb3RhdGUsIGRhdGFfdHlwZSwgeHJlcywgeXJlczsKCWludCB2eHJlczsKCWludCBtaXJyb3I7CglpbnQgeHNjYWxlLCB5c2NhbGU7CglpbnQgZXh0X2N0cmw7CglpbnQgc3JjX3BvcnQ7CglpbnQgc2luZ2xlX3RyYW5zZmVyOwp9IGxjZF9kbWE7Cgp2b2lkIG9tYXBfc2V0X2xjZF9kbWFfYjEodW5zaWduZWQgbG9uZyBhZGRyLCB1MTYgZmJfeHJlcywgdTE2IGZiX3lyZXMsCgkJCSBpbnQgZGF0YV90eXBlKQp7CglsY2RfZG1hLmFkZHIgPSBhZGRyOwoJbGNkX2RtYS5kYXRhX3R5cGUgPSBkYXRhX3R5cGU7CglsY2RfZG1hLnhyZXMgPSBmYl94cmVzOwoJbGNkX2RtYS55cmVzID0gZmJfeXJlczsKfQoKdm9pZCBvbWFwX3NldF9sY2RfZG1hX3NyY19wb3J0KGludCBwb3J0KQp7CglsY2RfZG1hLnNyY19wb3J0ID0gcG9ydDsKfQoKdm9pZCBvbWFwX3NldF9sY2RfZG1hX2V4dF9jb250cm9sbGVyKGludCBleHRlcm5hbCkKewoJbGNkX2RtYS5leHRfY3RybCA9IGV4dGVybmFsOwp9Cgp2b2lkIG9tYXBfc2V0X2xjZF9kbWFfc2luZ2xlX3RyYW5zZmVyKGludCBzaW5nbGUpCnsKCWxjZF9kbWEuc2luZ2xlX3RyYW5zZmVyID0gc2luZ2xlOwp9CgoKdm9pZCBvbWFwX3NldF9sY2RfZG1hX2IxX3JvdGF0aW9uKGludCByb3RhdGUpCnsKCWlmIChvbWFwX2RtYV9pbl8xNTEwX21vZGUoKSkgewoJCXByaW50ayhLRVJOX0VSUiAiRE1BIHJvdGF0aW9uIGlzIG5vdCBzdXBwb3J0ZWQgaW4gMTUxMCBtb2RlXG4iKTsKCQlCVUcoKTsKCQlyZXR1cm47Cgl9CglsY2RfZG1hLnJvdGF0ZSA9IHJvdGF0ZTsKfQoKdm9pZCBvbWFwX3NldF9sY2RfZG1hX2IxX21pcnJvcihpbnQgbWlycm9yKQp7CglpZiAob21hcF9kbWFfaW5fMTUxMF9tb2RlKCkpIHsKCQlwcmludGsoS0VSTl9FUlIgIkRNQSBtaXJyb3IgaXMgbm90IHN1cHBvcnRlZCBpbiAxNTEwIG1vZGVcbiIpOwoJCUJVRygpOwoJfQoJbGNkX2RtYS5taXJyb3IgPSBtaXJyb3I7Cn0KCnZvaWQgb21hcF9zZXRfbGNkX2RtYV9iMV92eHJlcyh1bnNpZ25lZCBsb25nIHZ4cmVzKQp7CglpZiAob21hcF9kbWFfaW5fMTUxMF9tb2RlKCkpIHsKCQlwcmludGsoS0VSTl9FUlIgIkRNQSB2aXJ0dWFsIHJlc3Vsb3Rpb24gaXMgbm90IHN1cHBvcnRlZCAiCgkJCQkiaW4gMTUxMCBtb2RlXG4iKTsKCQlCVUcoKTsKCX0KCWxjZF9kbWEudnhyZXMgPSB2eHJlczsKfQoKdm9pZCBvbWFwX3NldF9sY2RfZG1hX2IxX3NjYWxlKHVuc2lnbmVkIGludCB4c2NhbGUsIHVuc2lnbmVkIGludCB5c2NhbGUpCnsKCWlmIChvbWFwX2RtYV9pbl8xNTEwX21vZGUoKSkgewoJCXByaW50ayhLRVJOX0VSUiAiRE1BIHNjYWxlIGlzIG5vdCBzdXBwb3J0ZWQgaW4gMTUxMCBtb2RlXG4iKTsKCQlCVUcoKTsKCX0KCWxjZF9kbWEueHNjYWxlID0geHNjYWxlOwoJbGNkX2RtYS55c2NhbGUgPSB5c2NhbGU7Cn0KCnN0YXRpYyB2b2lkIHNldF9iMV9yZWdzKHZvaWQpCnsKCXVuc2lnbmVkIGxvbmcgdG9wLCBib3R0b207CglpbnQgZXM7Cgl1MTYgdzsKCXVuc2lnbmVkIGxvbmcgZW4sIGZuOwoJbG9uZyBlaSwgZmk7Cgl1bnNpZ25lZCBsb25nIHZ4cmVzOwoJdW5zaWduZWQgaW50IHhzY2FsZSwgeXNjYWxlOwoKCXN3aXRjaCAobGNkX2RtYS5kYXRhX3R5cGUpIHsKCWNhc2UgT01BUF9ETUFfREFUQV9UWVBFX1M4OgoJCWVzID0gMTsKCQlicmVhazsKCWNhc2UgT01BUF9ETUFfREFUQV9UWVBFX1MxNjoKCQllcyA9IDI7CgkJYnJlYWs7CgljYXNlIE9NQVBfRE1BX0RBVEFfVFlQRV9TMzI6CgkJZXMgPSA0OwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlCVUcoKTsKCQlyZXR1cm47Cgl9CgoJdnhyZXMgPSBsY2RfZG1hLnZ4cmVzID8gbGNkX2RtYS52eHJlcyA6IGxjZF9kbWEueHJlczsKCXhzY2FsZSA9IGxjZF9kbWEueHNjYWxlID8gbGNkX2RtYS54c2NhbGUgOiAxOwoJeXNjYWxlID0gbGNkX2RtYS55c2NhbGUgPyBsY2RfZG1hLnlzY2FsZSA6IDE7CglCVUdfT04odnhyZXMgPCBsY2RfZG1hLnhyZXMpOwojZGVmaW5lIFBJWEFERFIoeCx5KSAobGNkX2RtYS5hZGRyICsgKCh5KSAqIHZ4cmVzICogeXNjYWxlICsgKHgpICogeHNjYWxlKSAqIGVzKQojZGVmaW5lIFBJWFNURVAoc3gsIHN5LCBkeCwgZHkpIChQSVhBRERSKGR4LCBkeSkgLSBQSVhBRERSKHN4LCBzeSkgLSBlcyArIDEpCglzd2l0Y2ggKGxjZF9kbWEucm90YXRlKSB7CgljYXNlIDA6CgkJaWYgKCFsY2RfZG1hLm1pcnJvcikgewoJCQl0b3AgPSBQSVhBRERSKDAsIDApOwoJCQlib3R0b20gPSBQSVhBRERSKGxjZF9kbWEueHJlcyAtIDEsIGxjZF9kbWEueXJlcyAtIDEpOwoJCQkvKiAxNTEwIERNQSByZXF1aXJlcyB0aGUgYm90dG9tIGFkZHJlc3MgdG8gYmUgMiBtb3JlCgkJCSAqIHRoYW4gdGhlIGFjdHVhbCBsYXN0IG1lbW9yeSBhY2Nlc3MgbG9jYXRpb24uICovCgkJCWlmIChvbWFwX2RtYV9pbl8xNTEwX21vZGUoKSAmJgoJCQkgICAgbGNkX2RtYS5kYXRhX3R5cGUgPT0gT01BUF9ETUFfREFUQV9UWVBFX1MzMikKCQkJCWJvdHRvbSArPSAyOwoJCQllaSA9IFBJWFNURVAoMCwgMCwgMSwgMCk7CgkJCWZpID0gUElYU1RFUChsY2RfZG1hLnhyZXMgLSAxLCAwLCAwLCAxKTsKCQl9IGVsc2UgewoJCQl0b3AgPSBQSVhBRERSKGxjZF9kbWEueHJlcyAtIDEsIDApOwoJCQlib3R0b20gPSBQSVhBRERSKDAsIGxjZF9kbWEueXJlcyAtIDEpOwoJCQllaSA9IFBJWFNURVAoMSwgMCwgMCwgMCk7CgkJCWZpID0gUElYU1RFUCgwLCAwLCBsY2RfZG1hLnhyZXMgLSAxLCAxKTsKCQl9CgkJZW4gPSBsY2RfZG1hLnhyZXM7CgkJZm4gPSBsY2RfZG1hLnlyZXM7CgkJYnJlYWs7CgljYXNlIDkwOgoJCWlmICghbGNkX2RtYS5taXJyb3IpIHsKCQkJdG9wID0gUElYQUREUigwLCBsY2RfZG1hLnlyZXMgLSAxKTsKCQkJYm90dG9tID0gUElYQUREUihsY2RfZG1hLnhyZXMgLSAxLCAwKTsKCQkJZWkgPSBQSVhTVEVQKDAsIDEsIDAsIDApOwoJCQlmaSA9IFBJWFNURVAoMCwgMCwgMSwgbGNkX2RtYS55cmVzIC0gMSk7CgkJfSBlbHNlIHsKCQkJdG9wID0gUElYQUREUihsY2RfZG1hLnhyZXMgLSAxLCBsY2RfZG1hLnlyZXMgLSAxKTsKCQkJYm90dG9tID0gUElYQUREUigwLCAwKTsKCQkJZWkgPSBQSVhTVEVQKDAsIDEsIDAsIDApOwoJCQlmaSA9IFBJWFNURVAoMSwgMCwgMCwgbGNkX2RtYS55cmVzIC0gMSk7CgkJfQoJCWVuID0gbGNkX2RtYS55cmVzOwoJCWZuID0gbGNkX2RtYS54cmVzOwoJCWJyZWFrOwoJY2FzZSAxODA6CgkJaWYgKCFsY2RfZG1hLm1pcnJvcikgewoJCQl0b3AgPSBQSVhBRERSKGxjZF9kbWEueHJlcyAtIDEsIGxjZF9kbWEueXJlcyAtIDEpOwoJCQlib3R0b20gPSBQSVhBRERSKDAsIDApOwoJCQllaSA9IFBJWFNURVAoMSwgMCwgMCwgMCk7CgkJCWZpID0gUElYU1RFUCgwLCAxLCBsY2RfZG1hLnhyZXMgLSAxLCAwKTsKCQl9IGVsc2UgewoJCQl0b3AgPSBQSVhBRERSKDAsIGxjZF9kbWEueXJlcyAtIDEpOwoJCQlib3R0b20gPSBQSVhBRERSKGxjZF9kbWEueHJlcyAtIDEsIDApOwoJCQllaSA9IFBJWFNURVAoMCwgMCwgMSwgMCk7CgkJCWZpID0gUElYU1RFUChsY2RfZG1hLnhyZXMgLSAxLCAxLCAwLCAwKTsKCQl9CgkJZW4gPSBsY2RfZG1hLnhyZXM7CgkJZm4gPSBsY2RfZG1hLnlyZXM7CgkJYnJlYWs7CgljYXNlIDI3MDoKCQlpZiAoIWxjZF9kbWEubWlycm9yKSB7CgkJCXRvcCA9IFBJWEFERFIobGNkX2RtYS54cmVzIC0gMSwgMCk7CgkJCWJvdHRvbSA9IFBJWEFERFIoMCwgbGNkX2RtYS55cmVzIC0gMSk7CgkJCWVpID0gUElYU1RFUCgwLCAwLCAwLCAxKTsKCQkJZmkgPSBQSVhTVEVQKDEsIGxjZF9kbWEueXJlcyAtIDEsIDAsIDApOwoJCX0gZWxzZSB7CgkJCXRvcCA9IFBJWEFERFIoMCwgMCk7CgkJCWJvdHRvbSA9IFBJWEFERFIobGNkX2RtYS54cmVzIC0gMSwgbGNkX2RtYS55cmVzIC0gMSk7CgkJCWVpID0gUElYU1RFUCgwLCAwLCAwLCAxKTsKCQkJZmkgPSBQSVhTVEVQKDAsIGxjZF9kbWEueXJlcyAtIDEsIDEsIDApOwoJCX0KCQllbiA9IGxjZF9kbWEueXJlczsKCQlmbiA9IGxjZF9kbWEueHJlczsKCQlicmVhazsKCWRlZmF1bHQ6CgkJQlVHKCk7CgkJcmV0dXJuOwkvKiBTdXByZXNzIHdhcm5pbmcgYWJvdXQgdW5pbml0aWFsaXplZCB2YXJzICovCgl9CgoJaWYgKG9tYXBfZG1hX2luXzE1MTBfbW9kZSgpKSB7CgkJb21hcF93cml0ZXcodG9wID4+IDE2LCBPTUFQMTUxMF9ETUFfTENEX1RPUF9GMV9VKTsKCQlvbWFwX3dyaXRldyh0b3AsIE9NQVAxNTEwX0RNQV9MQ0RfVE9QX0YxX0wpOwoJCW9tYXBfd3JpdGV3KGJvdHRvbSA+PiAxNiwgT01BUDE1MTBfRE1BX0xDRF9CT1RfRjFfVSk7CgkJb21hcF93cml0ZXcoYm90dG9tLCBPTUFQMTUxMF9ETUFfTENEX0JPVF9GMV9MKTsKCgkJcmV0dXJuOwoJfQoKCS8qIDE2MTAgcmVncyAqLwoJb21hcF93cml0ZXcodG9wID4+IDE2LCBPTUFQMTYxMF9ETUFfTENEX1RPUF9CMV9VKTsKCW9tYXBfd3JpdGV3KHRvcCwgT01BUDE2MTBfRE1BX0xDRF9UT1BfQjFfTCk7CglvbWFwX3dyaXRldyhib3R0b20gPj4gMTYsIE9NQVAxNjEwX0RNQV9MQ0RfQk9UX0IxX1UpOwoJb21hcF93cml0ZXcoYm90dG9tLCBPTUFQMTYxMF9ETUFfTENEX0JPVF9CMV9MKTsKCglvbWFwX3dyaXRldyhlbiwgT01BUDE2MTBfRE1BX0xDRF9TUkNfRU5fQjEpOwoJb21hcF93cml0ZXcoZm4sIE9NQVAxNjEwX0RNQV9MQ0RfU1JDX0ZOX0IxKTsKCgl3ID0gb21hcF9yZWFkdyhPTUFQMTYxMF9ETUFfTENEX0NTRFApOwoJdyAmPSB+MHgwMzsKCXcgfD0gbGNkX2RtYS5kYXRhX3R5cGU7CglvbWFwX3dyaXRldyh3LCBPTUFQMTYxMF9ETUFfTENEX0NTRFApOwoKCXcgPSBvbWFwX3JlYWR3KE9NQVAxNjEwX0RNQV9MQ0RfQ1RSTCk7CgkvKiBBbHdheXMgc2V0IHRoZSBzb3VyY2UgcG9ydCBhcyBTRFJBTSBmb3Igbm93Ki8KCXcgJj0gfigweDAzIDw8IDYpOwoJaWYgKGxjZF9kbWEuY2FsbGJhY2sgIT0gTlVMTCkKCQl3IHw9IDEgPDwgMTsJCS8qIEJsb2NrIGludGVycnVwdCBlbmFibGUgKi8KCWVsc2UKCQl3ICY9IH4oMSA8PCAxKTsKCW9tYXBfd3JpdGV3KHcsIE9NQVAxNjEwX0RNQV9MQ0RfQ1RSTCk7CgoJaWYgKCEobGNkX2RtYS5yb3RhdGUgfHwgbGNkX2RtYS5taXJyb3IgfHwKCSAgICAgIGxjZF9kbWEudnhyZXMgfHwgbGNkX2RtYS54c2NhbGUgfHwgbGNkX2RtYS55c2NhbGUpKQoJCXJldHVybjsKCgl3ID0gb21hcF9yZWFkdyhPTUFQMTYxMF9ETUFfTENEX0NDUik7CgkvKiBTZXQgdGhlIGRvdWJsZS1pbmRleGVkIGFkZHJlc3NpbmcgbW9kZSAqLwoJdyB8PSAoMHgwMyA8PCAxMik7CglvbWFwX3dyaXRldyh3LCBPTUFQMTYxMF9ETUFfTENEX0NDUik7CgoJb21hcF93cml0ZXcoZWksIE9NQVAxNjEwX0RNQV9MQ0RfU1JDX0VJX0IxKTsKCW9tYXBfd3JpdGV3KGZpID4+IDE2LCBPTUFQMTYxMF9ETUFfTENEX1NSQ19GSV9CMV9VKTsKCW9tYXBfd3JpdGV3KGZpLCBPTUFQMTYxMF9ETUFfTENEX1NSQ19GSV9CMV9MKTsKfQoKc3RhdGljIGlycXJldHVybl90IGxjZF9kbWFfaXJxX2hhbmRsZXIoaW50IGlycSwgdm9pZCAqZGV2X2lkLAoJCQkJICAgICAgIHN0cnVjdCBwdF9yZWdzICpyZWdzKQp7Cgl1MTYgdzsKCgl3ID0gb21hcF9yZWFkdyhPTUFQMTYxMF9ETUFfTENEX0NUUkwpOwoJaWYgKHVubGlrZWx5KCEodyAmICgxIDw8IDMpKSkpIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJTcHVyaW91cyBMQ0QgRE1BIElSUVxuIik7CgkJcmV0dXJuIElSUV9OT05FOwoJfQoJLyogQWNrIHRoZSBJUlEgKi8KCXcgfD0gKDEgPDwgMyk7CglvbWFwX3dyaXRldyh3LCBPTUFQMTYxMF9ETUFfTENEX0NUUkwpOwoJbGNkX2RtYS5hY3RpdmUgPSAwOwoJaWYgKGxjZF9kbWEuY2FsbGJhY2sgIT0gTlVMTCkKCQlsY2RfZG1hLmNhbGxiYWNrKHcsIGxjZF9kbWEuY2JfZGF0YSk7CgoJcmV0dXJuIElSUV9IQU5ETEVEOwp9CgppbnQgb21hcF9yZXF1ZXN0X2xjZF9kbWEodm9pZCAoKiBjYWxsYmFjaykodTE2IHN0YXR1cywgdm9pZCAqZGF0YSksCgkJCSB2b2lkICpkYXRhKQp7CglzcGluX2xvY2tfaXJxKCZsY2RfZG1hLmxvY2spOwoJaWYgKGxjZF9kbWEucmVzZXJ2ZWQpIHsKCQlzcGluX3VubG9ja19pcnEoJmxjZF9kbWEubG9jayk7CgkJcHJpbnRrKEtFUk5fRVJSICJMQ0QgRE1BIGNoYW5uZWwgYWxyZWFkeSByZXNlcnZlZFxuIik7CgkJQlVHKCk7CgkJcmV0dXJuIC1FQlVTWTsKCX0KCWxjZF9kbWEucmVzZXJ2ZWQgPSAxOwoJc3Bpbl91bmxvY2tfaXJxKCZsY2RfZG1hLmxvY2spOwoJbGNkX2RtYS5jYWxsYmFjayA9IGNhbGxiYWNrOwoJbGNkX2RtYS5jYl9kYXRhID0gZGF0YTsKCWxjZF9kbWEuYWN0aXZlID0gMDsKCWxjZF9kbWEuc2luZ2xlX3RyYW5zZmVyID0gMDsKCWxjZF9kbWEucm90YXRlID0gMDsKCWxjZF9kbWEudnhyZXMgPSAwOwoJbGNkX2RtYS5taXJyb3IgPSAwOwoJbGNkX2RtYS54c2NhbGUgPSAwOwoJbGNkX2RtYS55c2NhbGUgPSAwOwoJbGNkX2RtYS5leHRfY3RybCA9IDA7CglsY2RfZG1hLnNyY19wb3J0ID0gMDsKCglyZXR1cm4gMDsKfQoKdm9pZCBvbWFwX2ZyZWVfbGNkX2RtYSh2b2lkKQp7CglzcGluX2xvY2soJmxjZF9kbWEubG9jayk7CglpZiAoIWxjZF9kbWEucmVzZXJ2ZWQpIHsKCQlzcGluX3VubG9jaygmbGNkX2RtYS5sb2NrKTsKCQlwcmludGsoS0VSTl9FUlIgIkxDRCBETUEgaXMgbm90IHJlc2VydmVkXG4iKTsKCQlCVUcoKTsKCQlyZXR1cm47Cgl9CglpZiAoIWVuYWJsZV8xNTEwX21vZGUpCgkJb21hcF93cml0ZXcob21hcF9yZWFkdyhPTUFQMTYxMF9ETUFfTENEX0NDUikgJiB+MSwKCQkJICAgIE9NQVAxNjEwX0RNQV9MQ0RfQ0NSKTsKCWxjZF9kbWEucmVzZXJ2ZWQgPSAwOwoJc3Bpbl91bmxvY2soJmxjZF9kbWEubG9jayk7Cn0KCnZvaWQgb21hcF9lbmFibGVfbGNkX2RtYSh2b2lkKQp7Cgl1MTYgdzsKCgkvKiBTZXQgdGhlIEVuYWJsZSBiaXQgb25seSBpZiBhbiBleHRlcm5hbCBjb250cm9sbGVyIGlzCgkgKiBjb25uZWN0ZWQuIE90aGVyd2lzZSB0aGUgT01BUCBpbnRlcm5hbCBjb250cm9sbGVyIHdpbGwKCSAqIHN0YXJ0IHRoZSB0cmFuc2ZlciB3aGVuIGl0IGdldHMgZW5hYmxlZC4KCSAqLwoJaWYgKGVuYWJsZV8xNTEwX21vZGUgfHwgIWxjZF9kbWEuZXh0X2N0cmwpCgkJcmV0dXJuOwoKCXcgPSBvbWFwX3JlYWR3KE9NQVAxNjEwX0RNQV9MQ0RfQ1RSTCk7Cgl3IHw9IDEgPDwgODsKCW9tYXBfd3JpdGV3KHcsIE9NQVAxNjEwX0RNQV9MQ0RfQ1RSTCk7CgoJbGNkX2RtYS5hY3RpdmUgPSAxOwoKCXcgPSBvbWFwX3JlYWR3KE9NQVAxNjEwX0RNQV9MQ0RfQ0NSKTsKCXcgfD0gMSA8PCA3OwoJb21hcF93cml0ZXcodywgT01BUDE2MTBfRE1BX0xDRF9DQ1IpOwp9Cgp2b2lkIG9tYXBfc2V0dXBfbGNkX2RtYSh2b2lkKQp7CglCVUdfT04obGNkX2RtYS5hY3RpdmUpOwoJaWYgKCFlbmFibGVfMTUxMF9tb2RlKSB7CgkJLyogU2V0IHNvbWUgcmVhc29uYWJsZSBkZWZhdWx0cyAqLwoJCW9tYXBfd3JpdGV3KDB4NTQ0MCwgT01BUDE2MTBfRE1BX0xDRF9DQ1IpOwoJCW9tYXBfd3JpdGV3KDB4OTEwMiwgT01BUDE2MTBfRE1BX0xDRF9DU0RQKTsKCQlvbWFwX3dyaXRldygweDAwMDQsIE9NQVAxNjEwX0RNQV9MQ0RfTENIX0NUUkwpOwoJfQoJc2V0X2IxX3JlZ3MoKTsKCWlmICghZW5hYmxlXzE1MTBfbW9kZSkgewoJCXUxNiB3OwoKCQl3ID0gb21hcF9yZWFkdyhPTUFQMTYxMF9ETUFfTENEX0NDUik7CgkJLyogSWYgRE1BIHdhcyBhbHJlYWR5IGFjdGl2ZSBzZXQgdGhlIGVuZF9wcm9nIGJpdCB0byBoYXZlCgkJICogdGhlIHByb2dyYW1tZWQgcmVnaXN0ZXIgc2V0IGxvYWRlZCBpbnRvIHRoZSBhY3RpdmUKCQkgKiByZWdpc3RlciBzZXQuCgkJICovCgkJdyB8PSAxIDw8IDExOwkJLyogRW5kX3Byb2cgKi8KCQlpZiAoIWxjZF9kbWEuc2luZ2xlX3RyYW5zZmVyKQoJICAgICAgICAJdyB8PSAoMyA8PCA4KTsJLyogQXV0b19pbml0LCByZXBlYXQgKi8KCQlvbWFwX3dyaXRldyh3LCBPTUFQMTYxMF9ETUFfTENEX0NDUik7Cgl9Cn0KCnZvaWQgb21hcF9zdG9wX2xjZF9kbWEodm9pZCkKewoJdTE2IHc7CgoJbGNkX2RtYS5hY3RpdmUgPSAwOwoJaWYgKGVuYWJsZV8xNTEwX21vZGUgfHwgIWxjZF9kbWEuZXh0X2N0cmwpCgkJcmV0dXJuOwoKCXcgPSBvbWFwX3JlYWR3KE9NQVAxNjEwX0RNQV9MQ0RfQ0NSKTsKCXcgJj0gfigxIDw8IDcpOwoJb21hcF93cml0ZXcodywgT01BUDE2MTBfRE1BX0xDRF9DQ1IpOwoKCXcgPSBvbWFwX3JlYWR3KE9NQVAxNjEwX0RNQV9MQ0RfQ1RSTCk7Cgl3ICY9IH4oMSA8PCA4KTsKCW9tYXBfd3JpdGV3KHcsIE9NQVAxNjEwX0RNQV9MQ0RfQ1RSTCk7Cn0KCmludCBvbWFwX2xjZF9kbWFfZXh0X3J1bm5pbmcodm9pZCkKewoJcmV0dXJuIGxjZF9kbWEuZXh0X2N0cmwgJiYgbGNkX2RtYS5hY3RpdmU7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgpzdGF0aWMgaW50IF9faW5pdCBvbWFwX2luaXRfZG1hKHZvaWQpCnsKCWludCBjaCwgcjsKCglpZiAoY3B1X2lzX29tYXAxNXh4KCkpIHsKCQlwcmludGsoS0VSTl9JTkZPICJETUEgc3VwcG9ydCBmb3IgT01BUDE1eHggaW5pdGlhbGl6ZWRcbiIpOwoJCWRtYV9jaGFuX2NvdW50ID0gOTsKCQllbmFibGVfMTUxMF9tb2RlID0gMTsKCX0gZWxzZSBpZiAoY3B1X2lzX29tYXAxNnh4KCkgfHwgY3B1X2lzX29tYXA3MzAoKSkgewoJCXByaW50ayhLRVJOX0lORk8gIk9NQVAgRE1BIGhhcmR3YXJlIHZlcnNpb24gJWRcbiIsCgkJICAgICAgIG9tYXBfcmVhZHcoT01BUF9ETUFfSFdfSUQpKTsKCQlwcmludGsoS0VSTl9JTkZPICJETUEgY2FwYWJpbGl0aWVzOiAlMDh4OiUwOHg6JTA0eDolMDR4OiUwNHhcbiIsCgkJICAgICAgIChvbWFwX3JlYWR3KE9NQVBfRE1BX0NBUFNfMF9VKSA8PCAxNikgfAoJCSAgICAgICBvbWFwX3JlYWR3KE9NQVBfRE1BX0NBUFNfMF9MKSwKCQkgICAgICAgKG9tYXBfcmVhZHcoT01BUF9ETUFfQ0FQU18xX1UpIDw8IDE2KSB8CgkJICAgICAgIG9tYXBfcmVhZHcoT01BUF9ETUFfQ0FQU18xX0wpLAoJCSAgICAgICBvbWFwX3JlYWR3KE9NQVBfRE1BX0NBUFNfMiksIG9tYXBfcmVhZHcoT01BUF9ETUFfQ0FQU18zKSwKCQkgICAgICAgb21hcF9yZWFkdyhPTUFQX0RNQV9DQVBTXzQpKTsKCQlpZiAoIWVuYWJsZV8xNTEwX21vZGUpIHsKCQkJdTE2IHc7CgoJCQkvKiBEaXNhYmxlIE9NQVAgMy4wLzMuMSBjb21wYXRpYmlsaXR5IG1vZGUuICovCgkJCXcgPSBvbWFwX3JlYWR3KE9NQVBfRE1BX0dTQ1IpOwoJCQl3IHw9IDEgPDwgMzsKCQkJb21hcF93cml0ZXcodywgT01BUF9ETUFfR1NDUik7CgkJCWRtYV9jaGFuX2NvdW50ID0gMTY7CgkJfSBlbHNlCgkJCWRtYV9jaGFuX2NvdW50ID0gOTsKCX0gZWxzZSBpZiAoY3B1X2lzX29tYXAyNHh4KCkpIHsKCQl1OCByZXZpc2lvbiA9IG9tYXBfcmVhZGIoT01BUF9ETUE0X1JFVklTSU9OKTsKCQlwcmludGsoS0VSTl9JTkZPICJPTUFQIERNQSBoYXJkd2FyZSByZXZpc2lvbiAlZC4lZFxuIiwKCQkgICAgICAgcmV2aXNpb24gPj4gNCwgcmV2aXNpb24gJiAweGYpOwoJCWRtYV9jaGFuX2NvdW50ID0gT01BUF9MT0dJQ0FMX0RNQV9DSF9DT1VOVDsKCX0gZWxzZSB7CgkJZG1hX2NoYW5fY291bnQgPSAwOwoJCXJldHVybiAwOwoJfQoKCW1lbXNldCgmbGNkX2RtYSwgMCwgc2l6ZW9mKGxjZF9kbWEpKTsKCXNwaW5fbG9ja19pbml0KCZsY2RfZG1hLmxvY2spOwoJc3Bpbl9sb2NrX2luaXQoJmRtYV9jaGFuX2xvY2spOwoJbWVtc2V0KCZkbWFfY2hhbiwgMCwgc2l6ZW9mKGRtYV9jaGFuKSk7CgoJZm9yIChjaCA9IDA7IGNoIDwgZG1hX2NoYW5fY291bnQ7IGNoKyspIHsKCQlvbWFwX2NsZWFyX2RtYShjaCk7CgkJZG1hX2NoYW5bY2hdLmRldl9pZCA9IC0xOwoJCWRtYV9jaGFuW2NoXS5uZXh0X2xjaCA9IC0xOwoKCQlpZiAoY2ggPj0gNiAmJiBlbmFibGVfMTUxMF9tb2RlKQoJCQljb250aW51ZTsKCgkJaWYgKGNwdV9jbGFzc19pc19vbWFwMSgpKSB7CgkJCS8qIHJlcXVlc3RfaXJxKCkgZG9lc24ndCBsaWtlIGRldl9pZCAoaWUuIGNoKSBiZWluZwoJCQkgKiB6ZXJvLCBzbyB3ZSBoYXZlIHRvIGtsdWRnZSBhcm91bmQgdGhpcy4gKi8KCQkJciA9IHJlcXVlc3RfaXJxKG9tYXAxX2RtYV9pcnFbY2hdLAoJCQkJCW9tYXAxX2RtYV9pcnFfaGFuZGxlciwgMCwgIkRNQSIsCgkJCQkJKHZvaWQgKikgKGNoICsgMSkpOwoJCQlpZiAociAhPSAwKSB7CgkJCQlpbnQgaTsKCgkJCQlwcmludGsoS0VSTl9FUlIgInVuYWJsZSB0byByZXF1ZXN0IElSUSAlZCAiCgkJCQkgICAgICAgImZvciBETUEgKGVycm9yICVkKVxuIiwKCQkJCSAgICAgICBvbWFwMV9kbWFfaXJxW2NoXSwgcik7CgkJCQlmb3IgKGkgPSAwOyBpIDwgY2g7IGkrKykKCQkJCQlmcmVlX2lycShvbWFwMV9kbWFfaXJxW2ldLAoJCQkJCQkgKHZvaWQgKikgKGkgKyAxKSk7CgkJCQlyZXR1cm4gcjsKCQkJfQoJCX0KCX0KCglpZiAoY3B1X2lzX29tYXAyNHh4KCkpCgkJc2V0dXBfaXJxKElOVF8yNFhYX1NETUFfSVJRMCwgJm9tYXAyNHh4X2RtYV9pcnEpOwoKCS8qIEZJWE1FOiBVcGRhdGUgTENEIERNQSB0byB3b3JrIG9uIDI0eHggKi8KCWlmIChjcHVfY2xhc3NfaXNfb21hcDEoKSkgewoJCXIgPSByZXF1ZXN0X2lycShJTlRfRE1BX0xDRCwgbGNkX2RtYV9pcnFfaGFuZGxlciwgMCwKCQkJCSJMQ0QgRE1BIiwgTlVMTCk7CgkJaWYgKHIgIT0gMCkgewoJCQlpbnQgaTsKCgkJCXByaW50ayhLRVJOX0VSUiAidW5hYmxlIHRvIHJlcXVlc3QgSVJRIGZvciBMQ0QgRE1BICIKCQkJICAgICAgICIoZXJyb3IgJWQpXG4iLCByKTsKCQkJZm9yIChpID0gMDsgaSA8IGRtYV9jaGFuX2NvdW50OyBpKyspCgkJCQlmcmVlX2lycShvbWFwMV9kbWFfaXJxW2ldLCAodm9pZCAqKSAoaSArIDEpKTsKCQkJcmV0dXJuIHI7CgkJfQoJfQoKCXJldHVybiAwOwp9CgphcmNoX2luaXRjYWxsKG9tYXBfaW5pdF9kbWEpOwoKRVhQT1JUX1NZTUJPTChvbWFwX2dldF9kbWFfc3JjX3Bvcyk7CkVYUE9SVF9TWU1CT0wob21hcF9nZXRfZG1hX2RzdF9wb3MpOwpFWFBPUlRfU1lNQk9MKG9tYXBfZ2V0X2RtYV9zcmNfYWRkcl9jb3VudGVyKTsKRVhQT1JUX1NZTUJPTChvbWFwX2NsZWFyX2RtYSk7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfZG1hX3ByaW9yaXR5KTsKRVhQT1JUX1NZTUJPTChvbWFwX3JlcXVlc3RfZG1hKTsKRVhQT1JUX1NZTUJPTChvbWFwX2ZyZWVfZG1hKTsKRVhQT1JUX1NZTUJPTChvbWFwX3N0YXJ0X2RtYSk7CkVYUE9SVF9TWU1CT0wob21hcF9zdG9wX2RtYSk7CkVYUE9SVF9TWU1CT0wob21hcF9lbmFibGVfZG1hX2lycSk7CkVYUE9SVF9TWU1CT0wob21hcF9kaXNhYmxlX2RtYV9pcnEpOwoKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9kbWFfdHJhbnNmZXJfcGFyYW1zKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9kbWFfY29sb3JfbW9kZSk7CgpFWFBPUlRfU1lNQk9MKG9tYXBfc2V0X2RtYV9zcmNfcGFyYW1zKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9kbWFfc3JjX2luZGV4KTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9kbWFfc3JjX2RhdGFfcGFjayk7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfZG1hX3NyY19idXJzdF9tb2RlKTsKCkVYUE9SVF9TWU1CT0wob21hcF9zZXRfZG1hX2Rlc3RfcGFyYW1zKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9kbWFfZGVzdF9pbmRleCk7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfZG1hX2Rlc3RfZGF0YV9wYWNrKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9kbWFfZGVzdF9idXJzdF9tb2RlKTsKCkVYUE9SVF9TWU1CT0wob21hcF9zZXRfZG1hX3BhcmFtcyk7CgpFWFBPUlRfU1lNQk9MKG9tYXBfZG1hX2xpbmtfbGNoKTsKRVhQT1JUX1NZTUJPTChvbWFwX2RtYV91bmxpbmtfbGNoKTsKCkVYUE9SVF9TWU1CT0wob21hcF9yZXF1ZXN0X2xjZF9kbWEpOwpFWFBPUlRfU1lNQk9MKG9tYXBfZnJlZV9sY2RfZG1hKTsKRVhQT1JUX1NZTUJPTChvbWFwX2VuYWJsZV9sY2RfZG1hKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldHVwX2xjZF9kbWEpOwpFWFBPUlRfU1lNQk9MKG9tYXBfc3RvcF9sY2RfZG1hKTsKRVhQT1JUX1NZTUJPTChvbWFwX2xjZF9kbWFfZXh0X3J1bm5pbmcpOwpFWFBPUlRfU1lNQk9MKG9tYXBfc2V0X2xjZF9kbWFfYjEpOwpFWFBPUlRfU1lNQk9MKG9tYXBfc2V0X2xjZF9kbWFfc2luZ2xlX3RyYW5zZmVyKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9sY2RfZG1hX2V4dF9jb250cm9sbGVyKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9sY2RfZG1hX2IxX3JvdGF0aW9uKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9sY2RfZG1hX2IxX3Z4cmVzKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9sY2RfZG1hX2IxX3NjYWxlKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9sY2RfZG1hX2IxX21pcnJvcik7Cgo=