LyoKICogRE9TIFZpcnR1YWwgTWFjaGluZQogKgogKiBDb3B5cmlnaHQgMTk5OCBPdmUgS+V2ZW4KICoKICogVGhpcyBjb2RlIGhhc24ndCBiZWVuIGNvbXBsZXRlbHkgY2xlYW5lZCB1cCB5ZXQuCiAqLwoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxzaWduYWwuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSAid2luZG93cy5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2lubnQuaCIKI2luY2x1ZGUgIm1zZG9zLmgiCiNpbmNsdWRlICJtaXNjZW11LmgiCiNpbmNsdWRlICJkZWJ1Z2dlci5oIgojaW5jbHVkZSAiZGVidWcuaCIKI2luY2x1ZGUgIm1vZHVsZS5oIgojaW5jbHVkZSAidGFzay5oIgojaW5jbHVkZSAibGR0LmgiCiNpbmNsdWRlICJkb3NleGUuaCIKCnZvaWQgKCpjdHhfZGVidWdfY2FsbCkoaW50IHNpZyxDT05URVhUKmN0eCk9TlVMTDsKCiNpZmRlZiBNWl9TVVBQT1JURUQKCiNpbmNsdWRlIDxzeXMvbW1hbi5oPgojaW5jbHVkZSA8c3lzL3ZtODYuaD4KCnN0YXRpYyB2b2lkIERPU1ZNX0R1bXAoIExQRE9TVEFTSyBscERvc1Rhc2ssIGludCBmbiwKICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IHZtODZwbHVzX3N0cnVjdCpWTTg2ICkKewogdW5zaWduZWQgaW9mczsKIEJZVEUqaW5zdDsKIGludCB4OwoKIHN3aXRjaCAoVk04Nl9UWVBFKGZuKSkgewogIGNhc2UgVk04Nl9TSUdOQUw6CiAgIHByaW50ZigiVHJhcHBlZCBzaWduYWxcbiIpOyBicmVhazsKICBjYXNlIFZNODZfVU5LTk9XTjoKICAgcHJpbnRmKCJUcmFwcGVkIHVuaGFuZGxlZCBHUEZcbiIpOyBicmVhazsKICBjYXNlIFZNODZfSU5UeDoKICAgcHJpbnRmKCJUcmFwcGVkIElOVCAlMDJ4XG4iLFZNODZfQVJHKGZuKSk7IGJyZWFrOwogIGNhc2UgVk04Nl9TVEk6CiAgIHByaW50ZigiVHJhcHBlZCBTVElcbiIpOyBicmVhazsKICBjYXNlIFZNODZfUElDUkVUVVJOOgogICBwcmludGYoIlRyYXBwZWQgZHVlIHRvIHBlbmRpbmcgUElDIHJlcXVlc3RcbiIpOyBicmVhazsKICBjYXNlIFZNODZfVFJBUDoKICAgcHJpbnRmKCJUcmFwcGVkIGRlYnVnIHJlcXVlc3RcbiIpOyBicmVhazsKIH0KI2RlZmluZSBSRUdTIFZNODYtPnJlZ3MKIGZwcmludGYoc3RkZXJyLCJBWD0lMDRsWCBDWD0lMDRsWCBEWD0lMDRsWCBCWD0lMDRsWFxuIixSRUdTLmVheCxSRUdTLmVieCxSRUdTLmVjeCxSRUdTLmVkeCk7CiBmcHJpbnRmKHN0ZGVyciwiU0k9JTA0bFggREk9JTA0bFggU1A9JTA0bFggQlA9JTA0bFhcbiIsUkVHUy5lc2ksUkVHUy5lZGksUkVHUy5lc3AsUkVHUy5lYnApOwogZnByaW50ZihzdGRlcnIsIkNTPSUwNFggRFM9JTA0WCBFUz0lMDRYIFNTPSUwNFhcbiIsUkVHUy5jcyxSRUdTLmRzLFJFR1MuZXMsUkVHUy5zcyk7CiBmcHJpbnRmKHN0ZGVyciwiRUlQPSUwNGxYIEVGTEFHUz0lMDhsWFxuIixSRUdTLmVpcCxSRUdTLmVmbGFncyk7CgogaW9mcz0oKERXT1JEKVJFR1MuY3M8PDQpK1JFR1MuZWlwOwojdW5kZWYgUkVHUwogaW5zdD0oQllURSopbHBEb3NUYXNrLT5pbWcraW9mczsKIHByaW50ZigiT3Bjb2RlczoiKTsKIGZvciAoeD0wOyB4PDg7IHgrKykgcHJpbnRmKCIgJTAyeCIsaW5zdFt4XSk7CiBwcmludGYoIlxuIik7CgogZXhpdCgwKTsKfQoKc3RhdGljIGludCBET1NWTV9JbnQoIGludCB2ZWN0LCBQQ09OVEVYVCBjb250ZXh0LCBMUERPU1RBU0sgbHBEb3NUYXNrICkKewogaWYgKHZlY3Q9PTB4MzEpIHsKICBpZiAoQ1NfcmVnKGNvbnRleHQpPT1scERvc1Rhc2stPmRwbWlfc2VsKSB7CiAgIGlmIChJUF9yZWcoY29udGV4dCk+PWxwRG9zVGFzay0+d3JhcF9vZnMpIHsKICAgIC8qIGV4aXQgZnJvbSByZWFsLW1vZGUgd3JhcHBlciAqLwogICAgcmV0dXJuIC0xOwogICB9CiAgfQogIC8qIHdlIGNvdWxkIHByb2JhYmx5IG1vdmUgc29tZSBvdGhlciBkb2RneSBzdHVmZiBoZXJlIHRvbyBmcm9tIGRwbWkuYyAqLwogfQogSU5UX1JlYWxNb2RlSW50ZXJydXB0KHZlY3QsY29udGV4dCk7CiByZXR1cm4gMDsKfQoKI2RlZmluZSBDViBDUChlYXgsRWF4KTsgQ1AoZWN4LEVjeCk7IENQKGVkeCxFZHgpOyBDUChlYngsRWJ4KTsgXAogICAgICAgICAgIENQKGVzaSxFc2kpOyBDUChlZGksRWRpKTsgQ1AoZXNwLEVzcCk7IENQKGVicCxFYnApOyBcCiAgICAgICAgICAgQ1AoY3MsU2VnQ3MpOyBDUChkcyxTZWdEcyk7IENQKGVzLFNlZ0VzKTsgXAogICAgICAgICAgIENQKHNzLFNlZ1NzKTsgQ1AoZnMsU2VnRnMpOyBDUChncyxTZWdHcyk7IFwKICAgICAgICAgICBDUChlaXAsRWlwKTsgQ1AoZWZsYWdzLEVGbGFncykKCnN0YXRpYyBpbnQgRE9TVk1fUHJvY2VzcyggTFBET1NUQVNLIGxwRG9zVGFzaywgaW50IGZuLAogICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCB2bTg2cGx1c19zdHJ1Y3QqVk04NiApCnsKIENPTlRFWFQgY29udGV4dDsKIGludCByZXQ9MDsKCiNkZWZpbmUgQ1AoeCx5KSBjb250ZXh0LnkgPSBWTTg2LT5yZWdzLngKIENWOwojdW5kZWYgQ1AKICh2b2lkKilWODZCQVNFKCZjb250ZXh0KT1scERvc1Rhc2stPmltZzsKCiBzd2l0Y2ggKFZNODZfVFlQRShmbikpIHsKICBjYXNlIFZNODZfU0lHTkFMOgogICBwcmludGYoIlRyYXBwZWQgc2lnbmFsXG4iKTsKICAgcmV0PS0xOyBicmVhazsKICBjYXNlIFZNODZfVU5LTk9XTjogLyogdW5oYW5kbGVkIEdQRiAqLwogICBET1NWTV9EdW1wKGxwRG9zVGFzayxmbixWTTg2KTsKICAgaWYgKGN0eF9kZWJ1Z19jYWxsKSBjdHhfZGVidWdfY2FsbChTSUdTRUdWLCZjb250ZXh0KTsgZWxzZSByZXQ9LTE7CiAgIGJyZWFrOwogIGNhc2UgVk04Nl9JTlR4OgogICBUUkFDRShpbnQsIkRPUyBFWEUgY2FsbHMgSU5UICUwMnggd2l0aCBBWD0lMDRseFxuIixWTTg2X0FSRyhmbiksY29udGV4dC5FYXgpOwogICByZXQ9RE9TVk1fSW50KFZNODZfQVJHKGZuKSwmY29udGV4dCxscERvc1Rhc2spOyBicmVhazsKICBjYXNlIFZNODZfU1RJOgogICBicmVhazsKICBjYXNlIFZNODZfUElDUkVUVVJOOgogICBwcmludGYoIlRyYXBwZWQgZHVlIHRvIHBlbmRpbmcgUElDIHJlcXVlc3RcbiIpOyBicmVhazsKICBjYXNlIFZNODZfVFJBUDoKICAgaWYgKGN0eF9kZWJ1Z19jYWxsKSBjdHhfZGVidWdfY2FsbChTSUdUUkFQLCZjb250ZXh0KTsKICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgRE9TVk1fRHVtcChscERvc1Rhc2ssZm4sVk04Nik7CiB9CgojZGVmaW5lIENQKHgseSkgVk04Ni0+cmVncy54ID0gY29udGV4dC55CiBDVjsKI3VuZGVmIENQCiByZXR1cm4gcmV0Owp9CgppbnQgRE9TVk1fRW50ZXIoIFBDT05URVhUIGNvbnRleHQgKQp7CiBUREIgKnBUYXNrID0gKFREQiAqKUdsb2JhbExvY2sxNiggR2V0Q3VycmVudFRhc2soKSApOwogTkVfTU9EVUxFICpwTW9kdWxlID0gTkVfR2V0UHRyKCBwVGFzay0+aE1vZHVsZSApOwogTFBET1NUQVNLIGxwRG9zVGFzazsKIHN0cnVjdCB2bTg2cGx1c19zdHJ1Y3QgVk04NjsKIGludCBzdGF0OwoKIEdsb2JhbFVubG9jazE2KCBHZXRDdXJyZW50VGFzaygpICk7CiBpZiAoIXBNb2R1bGUpIHsKICBFUlIobW9kdWxlLCJObyB0YXNrIGlzIGN1cnJlbnRseSBhY3RpdmUhXG4iKTsKICByZXR1cm4gLTE7CiB9CiBpZiAoIXBNb2R1bGUtPmxwRG9zVGFzaykgewogIC8qIG5vIFZNODYgKGRvc21vZCkgdGFzayBpcyBjdXJyZW50bHkgcnVubmluZywgc3RhcnQgb25lICovCiAgaWYgKChscERvc1Rhc2sgPSBjYWxsb2MoMSwgc2l6ZW9mKERPU1RBU0spKSkgPT0gTlVMTCkKICAgIHJldHVybiAwOwogIGxwRG9zVGFzay0+aE1vZHVsZT1wTW9kdWxlLT5zZWxmOwogIHN0YXQ9TVpfSW5pdE1lbW9yeShscERvc1Rhc2sscE1vZHVsZSk7CiAgaWYgKHN0YXQ+PTMyKSBzdGF0PU1aX0luaXRUYXNrKGxwRG9zVGFzayk7CiAgaWYgKHN0YXQ8MzIpIHsKICAgZnJlZShscERvc1Rhc2spOwogICByZXR1cm4gLTE7CiAgfQogIHBNb2R1bGUtPmxwRG9zVGFzayA9IGxwRG9zVGFzazsKICBwTW9kdWxlLT5kb3NfaW1hZ2UgPSBscERvc1Rhc2stPmltZzsKICAvKiBOb3RlOiB3ZSdyZSBsZWF2aW5nIGl0IHJ1bm5pbmcgYWZ0ZXIgdGhpcywgaW4gY2FzZSB3ZSBuZWVkIGl0IGFnYWluLAogICAgIGFzIHRoaXMgbWluaW1pemVzIHRoZSBvdmVyaGVhZCBvZiBzdGFydGluZyBpdCB1cCBldmVyeSB0aW1lLi4uCiAgICAgaXQgd2lsbCBiZSBraWxsZWQgYXV0b21hdGljYWxseSB3aGVuIHRoZSBjdXJyZW50IHRhc2sgdGVybWluYXRlcyAqLwogfSBlbHNlIGxwRG9zVGFzaz1wTW9kdWxlLT5scERvc1Rhc2s7CgogaWYgKGNvbnRleHQpIHsKI2RlZmluZSBDUCh4LHkpIFZNODYucmVncy54ID0gY29udGV4dC0+eQogIENWOwojdW5kZWYgQ1AKIH0gZWxzZSB7Ci8qIGluaXRpYWwgc2V0dXAgKi8KICBtZW1zZXQoJlZNODYsMCxzaXplb2YoVk04NikpOwogIFZNODYucmVncy5jcz1scERvc1Rhc2stPmluaXRfY3M7CiAgVk04Ni5yZWdzLmVpcD1scERvc1Rhc2stPmluaXRfaXA7CiAgVk04Ni5yZWdzLnNzPWxwRG9zVGFzay0+aW5pdF9zczsKICBWTTg2LnJlZ3MuZXNwPWxwRG9zVGFzay0+aW5pdF9zcDsKICBWTTg2LnJlZ3MuZHM9bHBEb3NUYXNrLT5wc3Bfc2VnOwogIFZNODYucmVncy5lcz1scERvc1Rhc2stPnBzcF9zZWc7CiAgLyogaG1tLCB3aGF0IGVsc2UgZG8gd2UgbmVlZD8gKi8KIH0KCiAvKiBtYWluIGV4Y2hhbmdlIGxvb3AgKi8KIHN0YXQgPSBWTTg2X0VOVEVSOwogZG8gewogIC8qIHRyYW5zbWl0IFZNODYgc3RydWN0dXJlIHRvIGRvc21vZCB0YXNrICovCiAgaWYgKHdyaXRlKGxwRG9zVGFzay0+d3JpdGVfcGlwZSwmc3RhdCxzaXplb2Yoc3RhdCkpIT1zaXplb2Yoc3RhdCkpCiAgIHJldHVybiAtMTsKICBpZiAod3JpdGUobHBEb3NUYXNrLT53cml0ZV9waXBlLCZWTTg2LHNpemVvZihWTTg2KSkhPXNpemVvZihWTTg2KSkKICAgcmV0dXJuIC0xOwogIC8qIHdhaXQgZm9yIHJlc3BvbnNlICovCiAgZG8gewogICBpZiAocmVhZChscERvc1Rhc2stPnJlYWRfcGlwZSwmc3RhdCxzaXplb2Yoc3RhdCkpIT1zaXplb2Yoc3RhdCkpIHsKICAgIGlmICgoZXJybm89PUVJTlRSKXx8KGVycm5vPT1FQUdBSU4pKSBjb250aW51ZTsKICAgIHJldHVybiAtMTsKICAgfQogIH0gd2hpbGUgKDApOwogIGRvIHsKICAgaWYgKHJlYWQobHBEb3NUYXNrLT5yZWFkX3BpcGUsJlZNODYsc2l6ZW9mKFZNODYpKSE9c2l6ZW9mKFZNODYpKSB7CiAgICBpZiAoKGVycm5vPT1FSU5UUil8fChlcnJubz09RUFHQUlOKSkgY29udGludWU7CiAgICByZXR1cm4gLTE7CiAgIH0KICB9IHdoaWxlICgwKTsKICAvKiBnb3QgcmVzcG9uc2UgKi8KIH0gd2hpbGUgKERPU1ZNX1Byb2Nlc3MobHBEb3NUYXNrLHN0YXQsJlZNODYpPj0wKTsKCiBpZiAoY29udGV4dCkgewojZGVmaW5lIENQKHgseSkgY29udGV4dC0+eSA9IFZNODYucmVncy54CiAgQ1Y7CiN1bmRlZiBDUAogfQogcmV0dXJuIDA7Cn0KCiNlbHNlIC8qICFNWl9TVVBQT1JURUQgKi8KCmludCBET1NWTV9FbnRlciggUENPTlRFWFQgY29udGV4dCApCnsKIEVSUihtb2R1bGUsIkRPUyByZWFsbW9kZSBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgYXJjaGl0ZWN0dXJlIVxuIik7CiByZXR1cm4gLTE7Cn0KCiNlbmRpZgo=