LyoKICogRE9TIFZpcnR1YWwgTWFjaGluZQogKgogKiBDb3B5cmlnaHQgMTk5OCBPdmUgS+V2ZW4KICoKICogVGhpcyBjb2RlIGhhc24ndCBiZWVuIGNvbXBsZXRlbHkgY2xlYW5lZCB1cCB5ZXQuCiAqLwoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxzaWduYWwuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSAid2luZG93cy5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2lubnQuaCIKI2luY2x1ZGUgIm1zZG9zLmgiCiNpbmNsdWRlICJtaXNjZW11LmgiCiNpbmNsdWRlICJkZWJ1Zy5oIgojaW5jbHVkZSAibW9kdWxlLmgiCiNpbmNsdWRlICJ0YXNrLmgiCiNpbmNsdWRlICJsZHQuaCIKI2luY2x1ZGUgImRvc2V4ZS5oIgoKI2lmZGVmIE1aX1NVUFBPUlRFRAoKc3RhdGljIHZvaWQgRE9TVk1fRHVtcCggTFBET1NUQVNLIGxwRG9zVGFzaykKewogdW5zaWduZWQgaW9mczsKIEJZVEUqaW5zdDsKIGludCB4OwoKIHN3aXRjaCAoVk04Nl9UWVBFKGxwRG9zVGFzay0+Zm4pKSB7CiAgY2FzZSBWTTg2X1NJR05BTDoKICAgcHJpbnRmKCJUcmFwcGVkIHNpZ25hbFxuIik7IGJyZWFrOwogIGNhc2UgVk04Nl9VTktOT1dOOgogICBwcmludGYoIlRyYXBwZWQgdW5oYW5kbGVkIEdQRlxuIik7IGJyZWFrOwogIGNhc2UgVk04Nl9JTlR4OgogICBwcmludGYoIlRyYXBwZWQgSU5UICUwMnhcbiIsVk04Nl9BUkcobHBEb3NUYXNrLT5mbikpOyBicmVhazsKICBjYXNlIFZNODZfU1RJOgogICBwcmludGYoIlRyYXBwZWQgU1RJXG4iKTsgYnJlYWs7CiAgY2FzZSBWTTg2X1BJQ1JFVFVSTjoKICAgcHJpbnRmKCJUcmFwcGVkIGR1ZSB0byBwZW5kaW5nIFBJQyByZXF1ZXN0XG4iKTsgYnJlYWs7CiAgY2FzZSBWTTg2X1RSQVA6CiAgIHByaW50ZigiVHJhcHBlZCBkZWJ1ZyByZXF1ZXN0XG4iKTsgYnJlYWs7CiB9CiNkZWZpbmUgUkVHUyBscERvc1Rhc2stPlZNODYucmVncwogZnByaW50ZihzdGRlcnIsIkFYPSUwNGxYIENYPSUwNGxYIERYPSUwNGxYIEJYPSUwNGxYXG4iLFJFR1MuZWF4LFJFR1MuZWJ4LFJFR1MuZWN4LFJFR1MuZWR4KTsKIGZwcmludGYoc3RkZXJyLCJTST0lMDRsWCBEST0lMDRsWCBTUD0lMDRsWCBCUD0lMDRsWFxuIixSRUdTLmVzaSxSRUdTLmVkaSxSRUdTLmVzcCxSRUdTLmVicCk7CiBmcHJpbnRmKHN0ZGVyciwiQ1M9JTA0WCBEUz0lMDRYIEVTPSUwNFggU1M9JTA0WFxuIixSRUdTLmNzLFJFR1MuZHMsUkVHUy5lcyxSRUdTLnNzKTsKIGZwcmludGYoc3RkZXJyLCJFSVA9JTA0bFggRUZMQUdTPSUwOGxYXG4iLFJFR1MuZWlwLFJFR1MuZWZsYWdzKTsKCiBpb2ZzPSgoRFdPUkQpUkVHUy5jczw8NCkrUkVHUy5laXA7CiN1bmRlZiBSRUdTCiBpbnN0PShCWVRFKilscERvc1Rhc2stPmltZytpb2ZzOwogcHJpbnRmKCJPcGNvZGVzOiIpOwogZm9yICh4PTA7IHg8ODsgeCsrKSBwcmludGYoIiAlMDJ4IixpbnN0W3hdKTsKIHByaW50ZigiXG4iKTsKCiBleGl0KDApOwp9CgpzdGF0aWMgaW50IERPU1ZNX0ludChpbnQgdmVjdCwgUENPTlRFWFQgY29udGV4dCApCnsKIC8qIG1vdmVkIHRvIElOVF9SZWFsTW9kZUludGVycnVwdCBpbiBtc2Rvcy9pbnRlcnJ1cHRzLmMgKi8KIElOVF9SZWFsTW9kZUludGVycnVwdCh2ZWN0LGNvbnRleHQpOwogcmV0dXJuIDA7Cn0KCiNkZWZpbmUgQ1YgQ1AoZWF4LEVheCk7IENQKGVjeCxFY3gpOyBDUChlZHgsRWR4KTsgQ1AoZWJ4LEVieCk7IFwKICAgICAgICAgICBDUChlc2ksRXNpKTsgQ1AoZWRpLEVkaSk7IENQKGVzcCxFc3ApOyBDUChlYnAsRWJwKTsgXAogICAgICAgICAgIENQKGNzLFNlZ0NzKTsgQ1AoZHMsU2VnRHMpOyBDUChlcyxTZWdFcyk7IFwKICAgICAgICAgICBDUChzcyxTZWdTcyk7IENQKGZzLFNlZ0ZzKTsgQ1AoZ3MsU2VnR3MpOyBcCiAgICAgICAgICAgQ1AoZWlwLEVpcCk7IENQKGVmbGFncyxFRmxhZ3MpCgppbnQgRE9TVk1fUHJvY2VzcyggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIENPTlRFWFQgY29udGV4dDsKIGludCByZXQ9MDsKCiNkZWZpbmUgQ1AoeCx5KSBjb250ZXh0LnkgPSBscERvc1Rhc2stPlZNODYucmVncy54CiBDVjsKI3VuZGVmIENQCiAodm9pZCopVjg2QkFTRSgmY29udGV4dCk9bHBEb3NUYXNrLT5pbWc7Cgogc3dpdGNoIChWTTg2X1RZUEUobHBEb3NUYXNrLT5mbikpIHsKICBjYXNlIFZNODZfU0lHTkFMOgogICBwcmludGYoIlRyYXBwZWQgc2lnbmFsXG4iKTsKICAgcmV0PS0xOyBicmVhazsKICBjYXNlIFZNODZfVU5LTk9XTjogLyogdW5oYW5kbGVkIEdQRiAqLwogICBET1NWTV9EdW1wKGxwRG9zVGFzayk7CiAgIGN0eF9kZWJ1ZyhTSUdTRUdWLCZjb250ZXh0KTsKICAgYnJlYWs7CiAgY2FzZSBWTTg2X0lOVHg6CiAgIFRSQUNFKGludCwiRE9TIEVYRSBjYWxscyBJTlQgJTAyeCB3aXRoIEFYPSUwNGx4XG4iLFZNODZfQVJHKGxwRG9zVGFzay0+Zm4pLGNvbnRleHQuRWF4KTsKICAgcmV0PURPU1ZNX0ludChWTTg2X0FSRyhscERvc1Rhc2stPmZuKSwmY29udGV4dCk7IGJyZWFrOwogIGNhc2UgVk04Nl9TVEk6CiAgIGJyZWFrOwogIGNhc2UgVk04Nl9QSUNSRVRVUk46CiAgIHByaW50ZigiVHJhcHBlZCBkdWUgdG8gcGVuZGluZyBQSUMgcmVxdWVzdFxuIik7IGJyZWFrOwogIGNhc2UgVk04Nl9UUkFQOgogICBjdHhfZGVidWcoU0lHVFJBUCwmY29udGV4dCk7CiAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgIERPU1ZNX0R1bXAobHBEb3NUYXNrKTsKIH0KCiBscERvc1Rhc2stPmZuPVZNODZfRU5URVI7CiNkZWZpbmUgQ1AoeCx5KSBscERvc1Rhc2stPlZNODYucmVncy54ID0gY29udGV4dC55CiBDVjsKI3VuZGVmIENQCiByZXR1cm4gcmV0Owp9CgppbnQgRE9TVk1fRW50ZXIoIFBDT05URVhUIGNvbnRleHQgKQp7CiBUREIgKnBUYXNrID0gKFREQiAqKUdsb2JhbExvY2sxNiggR2V0Q3VycmVudFRhc2soKSApOwogTkVfTU9EVUxFICpwTW9kdWxlID0gTkVfR2V0UHRyKCBwVGFzay0+aE1vZHVsZSApOwogTFBET1NUQVNLIGxwRG9zVGFzazsKIGludCBzdGF0OwoKIEdsb2JhbFVubG9jazE2KCBHZXRDdXJyZW50VGFzaygpICk7CiBpZiAoIXBNb2R1bGUpIHsKICBFUlIobW9kdWxlLCJObyB0YXNrIGlzIGN1cnJlbnRseSBhY3RpdmUhXG4iKTsKICByZXR1cm4gLTE7CiB9CiBpZiAoIXBNb2R1bGUtPmxwRG9zVGFzaykgewogIC8qIG5vIFZNODYgKGRvc21vZCkgdGFzayBpcyBjdXJyZW50bHkgcnVubmluZywgc3RhcnQgb25lICovCiAgaWYgKChscERvc1Rhc2sgPSBjYWxsb2MoMSwgc2l6ZW9mKERPU1RBU0spKSkgPT0gTlVMTCkKICAgIHJldHVybiAwOwogIGxwRG9zVGFzay0+aE1vZHVsZT1wTW9kdWxlLT5zZWxmOwogIHN0YXQ9TVpfSW5pdE1lbW9yeShscERvc1Rhc2sscE1vZHVsZSk7CiAgaWYgKHN0YXQ+PTMyKSBzdGF0PU1aX0luaXRUYXNrKGxwRG9zVGFzayk7CiAgaWYgKHN0YXQ8MzIpIHsKICAgZnJlZShscERvc1Rhc2spOwogICByZXR1cm4gLTE7CiAgfQogIHBNb2R1bGUtPmxwRG9zVGFzayA9IGxwRG9zVGFzazsKICBwTW9kdWxlLT5kb3NfaW1hZ2UgPSBscERvc1Rhc2stPmltZzsKICAvKiBOb3RlOiB3ZSdyZSBsZWF2aW5nIGl0IHJ1bm5pbmcgYWZ0ZXIgdGhpcywgaW4gY2FzZSB3ZSBuZWVkIGl0IGFnYWluLAogICAgIGFzIHRoaXMgbWluaW1pemVzIHRoZSBvdmVyaGVhZCBvZiBzdGFydGluZyBpdCB1cCBldmVyeSB0aW1lLi4uCiAgICAgaXQgd2lsbCBiZSBraWxsZWQgYXV0b21hdGljYWxseSB3aGVuIHRoZSBjdXJyZW50IHRhc2sgdGVybWluYXRlcyAqLwogfSBlbHNlIGxwRG9zVGFzaz1wTW9kdWxlLT5scERvc1Rhc2s7CgogaWYgKGNvbnRleHQpIHsKI2RlZmluZSBDUCh4LHkpIGxwRG9zVGFzay0+Vk04Ni5yZWdzLnggPSBjb250ZXh0LT55CiAgQ1Y7CiN1bmRlZiBDUAogfQoKIC8qIG1haW4gbG9vcCAqLwogd2hpbGUgKChzdGF0ID0gTVpfUnVuTW9kdWxlKGxwRG9zVGFzaykpID49IDApCiAgaWYgKHN0YXQgPiAwICYmIERPU1ZNX1Byb2Nlc3MobHBEb3NUYXNrKSA8IDApCiAgIGJyZWFrOwoKIGlmIChjb250ZXh0KSB7CiNkZWZpbmUgQ1AoeCx5KSBjb250ZXh0LT55ID0gbHBEb3NUYXNrLT5WTTg2LnJlZ3MueAogIENWOwojdW5kZWYgQ1AKIH0KIHJldHVybiAwOwp9CgojZWxzZSAvKiAhTVpfU1VQUE9SVEVEICovCgppbnQgRE9TVk1fRW50ZXIoIFBDT05URVhUIGNvbnRleHQgKQp7CiBFUlIobW9kdWxlLCJET1MgcmVhbG1vZGUgbm90IHN1cHBvcnRlZCBvbiB0aGlzIGFyY2hpdGVjdHVyZSFcbiIpOwogcmV0dXJuIC0xOwp9CgojZW5kaWYK