LyoKICogRE9TIFZpcnR1YWwgTWFjaGluZQogKgogKiBDb3B5cmlnaHQgMTk5OCBPdmUgS+V2ZW4KICoKICogVGhpcyBjb2RlIGhhc24ndCBiZWVuIGNvbXBsZXRlbHkgY2xlYW5lZCB1cCB5ZXQuCiAqLwoKI2lmZGVmIGxpbnV4CiAKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxzaWduYWwuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSAid2luZG93cy5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2lubnQuaCIKI2luY2x1ZGUgIm1zZG9zLmgiCiNpbmNsdWRlICJtaXNjZW11LmgiCiNpbmNsdWRlICJkZWJ1Zy5oIgojaW5jbHVkZSAibW9kdWxlLmgiCiNpbmNsdWRlICJ0YXNrLmgiCiNpbmNsdWRlICJsZHQuaCIKI2luY2x1ZGUgImRvc2V4ZS5oIgoKc3RhdGljIHZvaWQgRE9TVk1fRHVtcCggTFBET1NUQVNLIGxwRG9zVGFzaykKewogdW5zaWduZWQgaW9mczsKIEJZVEUqaW5zdDsKIGludCB4OwoKIHN3aXRjaCAoVk04Nl9UWVBFKGxwRG9zVGFzay0+Zm4pKSB7CiAgY2FzZSBWTTg2X1NJR05BTDoKICAgcHJpbnRmKCJUcmFwcGVkIHNpZ25hbFxuIik7IGJyZWFrOwogIGNhc2UgVk04Nl9VTktOT1dOOgogICBwcmludGYoIlRyYXBwZWQgdW5oYW5kbGVkIEdQRlxuIik7IGJyZWFrOwogIGNhc2UgVk04Nl9JTlR4OgogICBwcmludGYoIlRyYXBwZWQgSU5UICUwMnhcbiIsVk04Nl9BUkcobHBEb3NUYXNrLT5mbikpOyBicmVhazsKICBjYXNlIFZNODZfU1RJOgogICBwcmludGYoIlRyYXBwZWQgU1RJXG4iKTsgYnJlYWs7CiAgY2FzZSBWTTg2X1BJQ1JFVFVSTjoKICAgcHJpbnRmKCJUcmFwcGVkIGR1ZSB0byBwZW5kaW5nIFBJQyByZXF1ZXN0XG4iKTsgYnJlYWs7CiAgY2FzZSBWTTg2X1RSQVA6CiAgIHByaW50ZigiVHJhcHBlZCBkZWJ1ZyByZXF1ZXN0XG4iKTsgYnJlYWs7CiB9CiNkZWZpbmUgUkVHUyBscERvc1Rhc2stPlZNODYucmVncwogZnByaW50ZihzdGRlcnIsIkFYPSUwNGxYIENYPSUwNGxYIERYPSUwNGxYIEJYPSUwNGxYXG4iLFJFR1MuZWF4LFJFR1MuZWJ4LFJFR1MuZWN4LFJFR1MuZWR4KTsKIGZwcmludGYoc3RkZXJyLCJTST0lMDRsWCBEST0lMDRsWCBTUD0lMDRsWCBCUD0lMDRsWFxuIixSRUdTLmVzaSxSRUdTLmVkaSxSRUdTLmVzcCxSRUdTLmVicCk7CiBmcHJpbnRmKHN0ZGVyciwiQ1M9JTA0WCBEUz0lMDRYIEVTPSUwNFggU1M9JTA0WFxuIixSRUdTLmNzLFJFR1MuZHMsUkVHUy5lcyxSRUdTLnNzKTsKIGZwcmludGYoc3RkZXJyLCJFSVA9JTA0bFggRUZMQUdTPSUwOGxYXG4iLFJFR1MuZWlwLFJFR1MuZWZsYWdzKTsKCiBpb2ZzPSgoRFdPUkQpUkVHUy5jczw8NCkrUkVHUy5laXA7CiN1bmRlZiBSRUdTCiBpbnN0PShCWVRFKilscERvc1Rhc2stPmltZytpb2ZzOwogcHJpbnRmKCJPcGNvZGVzOiIpOwogZm9yICh4PTA7IHg8ODsgeCsrKSBwcmludGYoIiAlMDJ4IixpbnN0W3hdKTsKIHByaW50ZigiXG4iKTsKCiBleGl0KDApOwp9CgpzdGF0aWMgaW50IERPU1ZNX0ludChpbnQgdmVjdCwgTFBET1NUQVNLIGxwRG9zVGFzaywgUENPTlRFWFQgY29udGV4dCApCnsKIC8qIHdlIHNob3VsZCByZWFsbHkgbWFwIHRvIGlmMTYzMi93cHJvY3Muc3BlYywgYnV0IG5vdCBhbGwKICAgIGludGVycnVwdCBoYW5kbGVycyBhcmUgYWRhcHRlZCB0byBzdXBwb3J0IG91ciBWTSB5ZXQgKi8KIHN3aXRjaCAodmVjdCkgewogIGNhc2UgMHgyMDoKICAgcmV0dXJuIC0xOwogIGNhc2UgMHgyMToKICAgaWYgKEFIX3JlZyhjb250ZXh0KT09MHg0YykgcmV0dXJuIC0xOwogICBET1MzQ2FsbChjb250ZXh0KTsKICAgYnJlYWs7CiAgY2FzZSAweDFhOgogICBJTlRfSW50MWFIYW5kbGVyKGNvbnRleHQpOwogICBicmVhazsKICBjYXNlIDB4MmY6CiAgIElOVF9JbnQyZkhhbmRsZXIoY29udGV4dCk7CiAgIGJyZWFrOwogfQogcmV0dXJuIDA7Cn0KCiNkZWZpbmUgQ1YgQ1AoZWF4LEVheCk7IENQKGVjeCxFY3gpOyBDUChlZHgsRWR4KTsgQ1AoZWJ4LEVieCk7IFwKICAgICAgICAgICBDUChlc2ksRXNpKTsgQ1AoZWRpLEVkaSk7IENQKGVzcCxFc3ApOyBDUChlYnAsRWJwKTsgXAogICAgICAgICAgIENQKGNzLFNlZ0NzKTsgQ1AoZHMsU2VnRHMpOyBDUChlcyxTZWdFcyk7IFwKICAgICAgICAgICBDUChzcyxTZWdTcyk7IENQKGZzLFNlZ0ZzKTsgQ1AoZ3MsU2VnR3MpOyBcCiAgICAgICAgICAgQ1AoZWlwLEVpcCk7IENQKGVmbGFncyxFRmxhZ3MpCgppbnQgRE9TVk1fUHJvY2VzcyggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIENPTlRFWFQgY29udGV4dDsKIGludCByZXQ9MDsKCiNkZWZpbmUgQ1AoeCx5KSBjb250ZXh0LnkgPSBscERvc1Rhc2stPlZNODYucmVncy54CiBDVjsKI3VuZGVmIENQCiAodm9pZCopVjg2QkFTRSgmY29udGV4dCk9bHBEb3NUYXNrLT5pbWc7Cgogc3dpdGNoIChWTTg2X1RZUEUobHBEb3NUYXNrLT5mbikpIHsKICBjYXNlIFZNODZfU0lHTkFMOgogICBwcmludGYoIlRyYXBwZWQgc2lnbmFsXG4iKTsKICAgcmV0PS0xOyBicmVhazsKICBjYXNlIFZNODZfVU5LTk9XTjoKICAgRE9TVk1fRHVtcChscERvc1Rhc2spOwogICBicmVhazsKICBjYXNlIFZNODZfSU5UeDoKICAgVFJBQ0UoaW50LCJET1MgRVhFIGNhbGxzIElOVCAlMDJ4XG4iLFZNODZfQVJHKGxwRG9zVGFzay0+Zm4pKTsKICAgcmV0PURPU1ZNX0ludChWTTg2X0FSRyhscERvc1Rhc2stPmZuKSxscERvc1Rhc2ssJmNvbnRleHQpOyBicmVhazsKICBjYXNlIFZNODZfU1RJOgogICBicmVhazsKICBjYXNlIFZNODZfUElDUkVUVVJOOgogICBwcmludGYoIlRyYXBwZWQgZHVlIHRvIHBlbmRpbmcgUElDIHJlcXVlc3RcbiIpOyBicmVhazsKICBjYXNlIFZNODZfVFJBUDoKICAgcHJpbnRmKCJUcmFwcGVkIGRlYnVnIHJlcXVlc3RcbiIpOyBicmVhazsKICBkZWZhdWx0OgogICBET1NWTV9EdW1wKGxwRG9zVGFzayk7CiB9CgogbHBEb3NUYXNrLT5mbj1WTTg2X0VOVEVSOwojZGVmaW5lIENQKHgseSkgbHBEb3NUYXNrLT5WTTg2LnJlZ3MueCA9IGNvbnRleHQueQogQ1Y7CiN1bmRlZiBDUAogcmV0dXJuIHJldDsKfQoKaW50IERPU1ZNX0VudGVyKCBQQ09OVEVYVCBjb250ZXh0ICkKewogVERCICpwVGFzayA9IChUREIgKilHbG9iYWxMb2NrMTYoIEdldEN1cnJlbnRUYXNrKCkgKTsKIE5FX01PRFVMRSAqcE1vZHVsZSA9IE5FX0dldFB0ciggcFRhc2stPmhNb2R1bGUgKTsKIExQRE9TVEFTSyBscERvc1Rhc2s7CiBpbnQgc3RhdDsKCiBHbG9iYWxVbmxvY2sxNiggR2V0Q3VycmVudFRhc2soKSApOwogaWYgKCFwTW9kdWxlKSB7CiAgRVJSKG1vZHVsZSwiTm8gdGFzayBpcyBjdXJyZW50bHkgYWN0aXZlIVxuIik7CiAgcmV0dXJuIC0xOwogfQogaWYgKCFwTW9kdWxlLT5scERvc1Rhc2spIHsKICAvKiBubyBWTTg2IChkb3Ntb2QpIHRhc2sgaXMgY3VycmVudGx5IHJ1bm5pbmcsIHN0YXJ0IG9uZSAqLwogIGlmICgobHBEb3NUYXNrID0gY2FsbG9jKDEsIHNpemVvZihET1NUQVNLKSkpID09IE5VTEwpCiAgICByZXR1cm4gMDsKICBscERvc1Rhc2stPmltZz1ET1NNRU1fTWVtb3J5QmFzZShwTW9kdWxlLT5zZWxmKTsKICBscERvc1Rhc2stPmhNb2R1bGU9cE1vZHVsZS0+c2VsZjsKICBzdGF0PU1aX0luaXRUYXNrKGxwRG9zVGFzayk7CiAgaWYgKHN0YXQ8MzIpIHsKICAgZnJlZShscERvc1Rhc2spOwogICByZXR1cm4gLTE7CiAgfQogIHBNb2R1bGUtPmxwRG9zVGFzayA9IGxwRG9zVGFzazsKICBwTW9kdWxlLT5kb3NfaW1hZ2UgPSBscERvc1Rhc2stPmltZzsKICAvKiBOb3RlOiB3ZSdyZSBsZWF2aW5nIGl0IHJ1bm5pbmcgYWZ0ZXIgdGhpcywgaW4gY2FzZSB3ZSBuZWVkIGl0IGFnYWluLAogICAgIGFzIHRoaXMgbWluaW1pemVzIHRoZSBvdmVyaGVhZCBvZiBzdGFydGluZyBpdCB1cCBldmVyeSB0aW1lLi4uCiAgICAgaXQgd2lsbCBiZSBraWxsZWQgYXV0b21hdGljYWxseSB3aGVuIHRoZSBjdXJyZW50IHRhc2sgdGVybWluYXRlcyAqLwogfSBlbHNlIGxwRG9zVGFzaz1wTW9kdWxlLT5scERvc1Rhc2s7CgogaWYgKGNvbnRleHQpIHsKI2RlZmluZSBDUCh4LHkpIGxwRG9zVGFzay0+Vk04Ni5yZWdzLnggPSBjb250ZXh0LT55CiAgQ1Y7CiN1bmRlZiBDUAogfQoKIC8qIG1haW4gbG9vcCAqLwogd2hpbGUgKChzdGF0ID0gTVpfUnVuTW9kdWxlKGxwRG9zVGFzaykpID49IDApCiAgaWYgKHN0YXQgPiAwICYmIERPU1ZNX1Byb2Nlc3MobHBEb3NUYXNrKSA8IDApCiAgIGJyZWFrOwoKIGlmIChjb250ZXh0KSB7CiNkZWZpbmUgQ1AoeCx5KSBjb250ZXh0LT55ID0gbHBEb3NUYXNrLT5WTTg2LnJlZ3MueAogIENWOwojdW5kZWYgQ1AKIH0KIHJldHVybiAwOwp9CgojZWxzZSAvKiAhbGludXggKi8KCmludCBET1NWTV9FbnRlciggUENPTlRFWFQgY29udGV4dCApCnsKIEVSUihtb2R1bGUsIkRPUyByZWFsbW9kZSBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgYXJjaGl0ZWN0dXJlIVxuIik7CiByZXR1cm4gLTE7Cn0KCiNlbmRpZiAvKiBsaW51eCAqLwo=