LyoKICogRE9TIFZpcnR1YWwgTWFjaGluZQogKgogKiBDb3B5cmlnaHQgMTk5OCBPdmUgS+V2ZW4KICoKICogVGhpcyBjb2RlIGhhc24ndCBiZWVuIGNvbXBsZXRlbHkgY2xlYW5lZCB1cCB5ZXQuCiAqLwoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxzaWduYWwuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3lzL3RpbWUuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL3N0YXQuaD4KCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2lubnQuaCIKI2luY2x1ZGUgInNpZ19jb250ZXh0LmgiCiNpbmNsdWRlICJtc2Rvcy5oIgojaW5jbHVkZSAibWlzY2VtdS5oIgojaW5jbHVkZSAiZGVidWdnZXIuaCIKI2luY2x1ZGUgIm1vZHVsZS5oIgojaW5jbHVkZSAidGFzay5oIgojaW5jbHVkZSAibGR0LmgiCiNpbmNsdWRlICJkb3NleGUuaCIKI2luY2x1ZGUgImRvc21vZC5oIgojaW5jbHVkZSAiZGVidWcuaCIKCiNpZmRlZiBNWl9TVVBQT1JURUQKCiNpbmNsdWRlIDxzeXMvbW1hbi5oPgojaW5jbHVkZSA8c3lzL3ZtODYuaD4KCnN0YXRpYyB2b2lkIERPU1ZNX0R1bXAoIExQRE9TVEFTSyBscERvc1Rhc2ssIGludCBmbiwgaW50IHNpZywKICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IHZtODZwbHVzX3N0cnVjdCpWTTg2ICkKewogdW5zaWduZWQgaW9mczsKIEJZVEUqaW5zdDsKIGludCB4OwoKIHN3aXRjaCAoVk04Nl9UWVBFKGZuKSkgewogIGNhc2UgVk04Nl9TSUdOQUw6CiAgIHByaW50ZigiVHJhcHBlZCBzaWduYWwgJWRcbiIsc2lnKTsgYnJlYWs7CiAgY2FzZSBWTTg2X1VOS05PV046CiAgIHByaW50ZigiVHJhcHBlZCB1bmhhbmRsZWQgR1BGXG4iKTsgYnJlYWs7CiAgY2FzZSBWTTg2X0lOVHg6CiAgIHByaW50ZigiVHJhcHBlZCBJTlQgJTAyeFxuIixWTTg2X0FSRyhmbikpOyBicmVhazsKICBjYXNlIFZNODZfU1RJOgogICBwcmludGYoIlRyYXBwZWQgU1RJXG4iKTsgYnJlYWs7CiAgY2FzZSBWTTg2X1BJQ1JFVFVSTjoKICAgcHJpbnRmKCJUcmFwcGVkIGR1ZSB0byBwZW5kaW5nIFBJQyByZXF1ZXN0XG4iKTsgYnJlYWs7CiAgY2FzZSBWTTg2X1RSQVA6CiAgIHByaW50ZigiVHJhcHBlZCBkZWJ1ZyByZXF1ZXN0XG4iKTsgYnJlYWs7CiAgZGVmYXVsdDoKICAgcHJpbnRmKCJUcmFwcGVkIHVua25vd24gVk04NiB0eXBlICVkIGFyZyAlZFxuIixWTTg2X1RZUEUoZm4pLFZNODZfQVJHKGZuKSk7IGJyZWFrOwogfQojZGVmaW5lIFJFR1MgVk04Ni0+cmVncwogZnByaW50ZihzdGRlcnIsIkFYPSUwNGxYIENYPSUwNGxYIERYPSUwNGxYIEJYPSUwNGxYXG4iLFJFR1MuZWF4LFJFR1MuZWN4LFJFR1MuZWR4LFJFR1MuZWJ4KTsKIGZwcmludGYoc3RkZXJyLCJTST0lMDRsWCBEST0lMDRsWCBTUD0lMDRsWCBCUD0lMDRsWFxuIixSRUdTLmVzaSxSRUdTLmVkaSxSRUdTLmVzcCxSRUdTLmVicCk7CiBmcHJpbnRmKHN0ZGVyciwiQ1M9JTA0WCBEUz0lMDRYIEVTPSUwNFggU1M9JTA0WFxuIixSRUdTLmNzLFJFR1MuZHMsUkVHUy5lcyxSRUdTLnNzKTsKIGZwcmludGYoc3RkZXJyLCJJUD0lMDRsWCBFRkxBR1M9JTA4bFhcbiIsUkVHUy5laXAsUkVHUy5lZmxhZ3MpOwoKIGlvZnM9KChEV09SRClSRUdTLmNzPDw0KStSRUdTLmVpcDsKI3VuZGVmIFJFR1MKIGluc3Q9KEJZVEUqKWxwRG9zVGFzay0+aW1nK2lvZnM7CiBwcmludGYoIk9wY29kZXM6Iik7CiBmb3IgKHg9MDsgeDw4OyB4KyspIHByaW50ZigiICUwMngiLGluc3RbeF0pOwogcHJpbnRmKCJcbiIpOwp9CgpzdGF0aWMgaW50IERPU1ZNX0ludCggaW50IHZlY3QsIFBDT05URVhUIGNvbnRleHQsIExQRE9TVEFTSyBscERvc1Rhc2sgKQp7CiBleHRlcm4gVUlOVDE2IERQTUlfd3JhcF9zZWc7CgogaWYgKHZlY3Q9PTB4MzEpIHsKICBpZiAoQ1NfcmVnKGNvbnRleHQpPT1EUE1JX3dyYXBfc2VnKSB7CiAgIC8qIGV4aXQgZnJvbSByZWFsLW1vZGUgd3JhcHBlciAqLwogICByZXR1cm4gLTE7CiAgfQogIC8qIHdlIGNvdWxkIHByb2JhYmx5IG1vdmUgc29tZSBvdGhlciBkb2RneSBzdHVmZiBoZXJlIHRvbyBmcm9tIGRwbWkuYyAqLwogfQogSU5UX1JlYWxNb2RlSW50ZXJydXB0KHZlY3QsY29udGV4dCk7CiByZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgRE9TVk1fU2ltdWxhdGVJbnQoIGludCB2ZWN0LCBQQ09OVEVYVCBjb250ZXh0LCBMUERPU1RBU0sgbHBEb3NUYXNrICkKewogRkFSUFJPQzE2IGhhbmRsZXI9SU5UX0dldFJNSGFuZGxlcih2ZWN0KTsKIFdPUkQqc3RhY2s9KFdPUkQqKShWODZCQVNFKGNvbnRleHQpKygoKERXT1JEKVNTX3JlZyhjb250ZXh0KSk8PDQpK1NQX3JlZyhjb250ZXh0KSk7CgogKigtLXN0YWNrKT1GTF9yZWcoY29udGV4dCk7CiAqKC0tc3RhY2spPUNTX3JlZyhjb250ZXh0KTsKICooLS1zdGFjayk9SVBfcmVnKGNvbnRleHQpOwogU1BfcmVnKGNvbnRleHQpLT02OwogQ1NfcmVnKGNvbnRleHQpPVNFTEVDVE9ST0YoaGFuZGxlcik7CiBJUF9yZWcoY29udGV4dCk9T0ZGU0VUT0YoaGFuZGxlcik7Cn0KCiNkZWZpbmUgQ1YgQ1AoZWF4LEVBWCk7IENQKGVjeCxFQ1gpOyBDUChlZHgsRURYKTsgQ1AoZWJ4LEVCWCk7IFwKICAgICAgICAgICBDUChlc2ksRVNJKTsgQ1AoZWRpLEVESSk7IENQKGVzcCxFU1ApOyBDUChlYnAsRUJQKTsgXAogICAgICAgICAgIENQKGNzLENTKTsgQ1AoZHMsRFMpOyBDUChlcyxFUyk7IFwKICAgICAgICAgICBDUChzcyxTUyk7IENQKGZzLEZTKTsgQ1AoZ3MsR1MpOyBcCiAgICAgICAgICAgQ1AoZWlwLEVJUCk7IENQKGVmbGFncyxFRkwpCgpzdGF0aWMgaW50IERPU1ZNX1Byb2Nlc3MoIExQRE9TVEFTSyBscERvc1Rhc2ssIGludCBmbiwgaW50IHNpZywKICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3Qgdm04NnBsdXNfc3RydWN0KlZNODYgKQp7CiBTSUdDT05URVhUIHNpZ2NvbnRleHQ7CiBDT05URVhUIGNvbnRleHQ7CiBpbnQgcmV0PTA7CgogaWYgKFZNODZfVFlQRShmbik9PVZNODZfVU5LTk9XTikgewogIC8qIElOU1RSX0VtdWxhdGVJbnN0cnVjdGlvbiBuZWVkcyBhIFNJR0NPTlRFWFQsIG5vdCBhIENPTlRFWFQuLi4gKi8KI2RlZmluZSBDUCh4LHkpIHkjI19zaWcoJnNpZ2NvbnRleHQpID0gVk04Ni0+cmVncy54CiAgQ1Y7CiN1bmRlZiBDUAogIGlmIChmbklOU1RSX0VtdWxhdGVJbnN0cnVjdGlvbikgcmV0PWZuSU5TVFJfRW11bGF0ZUluc3RydWN0aW9uKCZzaWdjb250ZXh0KTsKI2RlZmluZSBDUCh4LHkpIFZNODYtPnJlZ3MueCA9IHkjI19zaWcoJnNpZ2NvbnRleHQpCiAgQ1Y7CiN1bmRlZiBDUAogIGlmIChyZXQpIHJldHVybiAwOwogIHJldD0wOwogfQojZGVmaW5lIENQKHgseSkgeSMjX3JlZygmY29udGV4dCkgPSBWTTg2LT5yZWdzLngKIENWOwojdW5kZWYgQ1AKICh2b2lkKilWODZCQVNFKCZjb250ZXh0KT1scERvc1Rhc2stPmltZzsKCiBzd2l0Y2ggKFZNODZfVFlQRShmbikpIHsKICBjYXNlIFZNODZfU0lHTkFMOgogICBUUkFDRShpbnQsIkRPUyBtb2R1bGUgY2F1Z2h0IHNpZ25hbCAlZFxuIixzaWcpOwogICBpZiAoc2lnPT1TSUdBTFJNKSB7CiAgICBET1NWTV9TaW11bGF0ZUludCg4LCZjb250ZXh0LGxwRG9zVGFzayk7CiAgIH0gZWxzZQogICBpZiAoc2lnPT1TSUdIVVApIHsKICAgIGlmIChjdHhfZGVidWdfY2FsbCkgY3R4X2RlYnVnX2NhbGwoU0lHVFJBUCwmY29udGV4dCk7CiAgIH0gZWxzZQogICBpZiAoKHNpZz09U0lHSUxMKXx8KHNpZz09U0lHU0VHVikpIHsKICAgIGlmIChjdHhfZGVidWdfY2FsbCkgY3R4X2RlYnVnX2NhbGwoU0lHSUxMLCZjb250ZXh0KTsKICAgfSBlbHNlIHsKICAgIERPU1ZNX0R1bXAobHBEb3NUYXNrLGZuLHNpZyxWTTg2KTsKICAgIHJldD0tMTsKICAgfQogICBicmVhazsKICBjYXNlIFZNODZfVU5LTk9XTjogLyogdW5oYW5kbGVkIEdQRiAqLwogICBET1NWTV9EdW1wKGxwRG9zVGFzayxmbixzaWcsVk04Nik7CiAgIGlmIChjdHhfZGVidWdfY2FsbCkgY3R4X2RlYnVnX2NhbGwoU0lHU0VHViwmY29udGV4dCk7IGVsc2UgcmV0PS0xOwogICBicmVhazsKICBjYXNlIFZNODZfSU5UeDoKICAgaWYgKFRSQUNFX09OKHJlbGF5KSkKICAgIERQUklOVEYoIkNhbGwgRE9TIGludCAweCUwMnggKEVBWD0lMDhseCkgcmV0PSUwNGx4OiUwNGx4XG4iLFZNODZfQVJHKGZuKSxjb250ZXh0LkVheCxjb250ZXh0LlNlZ0NzLGNvbnRleHQuRWlwKTsKICAgcmV0PURPU1ZNX0ludChWTTg2X0FSRyhmbiksJmNvbnRleHQsbHBEb3NUYXNrKTsKICAgaWYgKFRSQUNFX09OKHJlbGF5KSkKICAgIERQUklOVEYoIlJldCAgRE9TIGludCAweCUwMnggKEVBWD0lMDhseCkgcmV0PSUwNGx4OiUwNGx4XG4iLFZNODZfQVJHKGZuKSxjb250ZXh0LkVheCxjb250ZXh0LlNlZ0NzLGNvbnRleHQuRWlwKTsKICAgYnJlYWs7CiAgY2FzZSBWTTg2X1NUSToKICAgYnJlYWs7CiAgY2FzZSBWTTg2X1BJQ1JFVFVSTjoKICAgcHJpbnRmKCJUcmFwcGVkIGR1ZSB0byBwZW5kaW5nIFBJQyByZXF1ZXN0XG4iKTsgYnJlYWs7CiAgY2FzZSBWTTg2X1RSQVA6CiAgIGlmIChjdHhfZGVidWdfY2FsbCkgY3R4X2RlYnVnX2NhbGwoU0lHVFJBUCwmY29udGV4dCk7CiAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgIERPU1ZNX0R1bXAobHBEb3NUYXNrLGZuLHNpZyxWTTg2KTsKICAgcmV0PS0xOwogfQoKI2RlZmluZSBDUCh4LHkpIFZNODYtPnJlZ3MueCA9IHkjI19yZWcoJmNvbnRleHQpCiBDVjsKI3VuZGVmIENQCiByZXR1cm4gcmV0Owp9CgppbnQgRE9TVk1fRW50ZXIoIFBDT05URVhUIGNvbnRleHQgKQp7CiBUREIgKnBUYXNrID0gKFREQiAqKUdsb2JhbExvY2sxNiggR2V0Q3VycmVudFRhc2soKSApOwogTkVfTU9EVUxFICpwTW9kdWxlID0gTkVfR2V0UHRyKCBwVGFzay0+aE1vZHVsZSApOwogTFBET1NUQVNLIGxwRG9zVGFzazsKIHN0cnVjdCB2bTg2cGx1c19zdHJ1Y3QgVk04NjsKIGludCBzdGF0LGxlbixzaWc7CiBmZF9zZXQgcmVhZGZkcyxleGNlcHRmZHM7CgogR2xvYmFsVW5sb2NrMTYoIEdldEN1cnJlbnRUYXNrKCkgKTsKIGlmICghcE1vZHVsZSkgewogIEVSUihtb2R1bGUsIk5vIHRhc2sgaXMgY3VycmVudGx5IGFjdGl2ZSFcbiIpOwogIHJldHVybiAtMTsKIH0KIGlmICghKGxwRG9zVGFzaz1wTW9kdWxlLT5scERvc1Rhc2spKSB7CiAgLyogTVpfQ3JlYXRlUHJvY2VzcyBvciBNWl9BbGxvY0RQTUlUYXNrIHNob3VsZCBoYXZlIGJlZW4gY2FsbGVkIGZpcnN0ICovCiAgRVJSKG1vZHVsZSwiZG9zbW9kIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZCEiKTsKICByZXR1cm4gLTE7CiB9CgogaWYgKGNvbnRleHQpIHsKI2RlZmluZSBDUCh4LHkpIFZNODYucmVncy54ID0geSMjX3JlZyhjb250ZXh0KQogIENWOwojdW5kZWYgQ1AKIH0gZWxzZSB7Ci8qIGluaXRpYWwgc2V0dXAgKi8KICAvKiBhbGxvY2F0ZSBzdGFuZGFyZCBET1MgaGFuZGxlcyAqLwogIEZJTEVfSW5pdFByb2Nlc3NEb3NIYW5kbGVzKCk7IAogIC8qIHJlZ2lzdGVycyAqLwogIG1lbXNldCgmVk04NiwwLHNpemVvZihWTTg2KSk7CiAgVk04Ni5yZWdzLmNzPWxwRG9zVGFzay0+aW5pdF9jczsKICBWTTg2LnJlZ3MuZWlwPWxwRG9zVGFzay0+aW5pdF9pcDsKICBWTTg2LnJlZ3Muc3M9bHBEb3NUYXNrLT5pbml0X3NzOwogIFZNODYucmVncy5lc3A9bHBEb3NUYXNrLT5pbml0X3NwOwogIFZNODYucmVncy5kcz1scERvc1Rhc2stPnBzcF9zZWc7CiAgVk04Ni5yZWdzLmVzPWxwRG9zVGFzay0+cHNwX3NlZzsKICAvKiBobW0sIHdoYXQgZWxzZSBkbyB3ZSBuZWVkPyAqLwogfQoKIC8qIG1haW4gZXhjaGFuZ2UgbG9vcCAqLwogZG8gewogIHN0YXQgPSBWTTg2X0VOVEVSOwogIGVycm5vID0gMDsKICAvKiB0cmFuc21pdCBWTTg2IHN0cnVjdHVyZSB0byBkb3Ntb2QgdGFzayAqLwogIGlmICh3cml0ZShscERvc1Rhc2stPndyaXRlX3BpcGUsJnN0YXQsc2l6ZW9mKHN0YXQpKSE9c2l6ZW9mKHN0YXQpKSB7CiAgIEVSUihtb2R1bGUsImRvc21vZCBzeW5jIGxvc3QsIGVycm5vPSVkXG4iLGVycm5vKTsKICAgcmV0dXJuIC0xOwogIH0KICBpZiAod3JpdGUobHBEb3NUYXNrLT53cml0ZV9waXBlLCZWTTg2LHNpemVvZihWTTg2KSkhPXNpemVvZihWTTg2KSkgewogICBFUlIobW9kdWxlLCJkb3Ntb2Qgc3luYyBsb3N0LCBlcnJubz0lZFxuIixlcnJubyk7CiAgIHJldHVybiAtMTsKICB9CiAgLyogd2FpdCBmb3IgcmVzcG9uc2UsIHdpdGggYXN5bmMgZXZlbnRzIGVuYWJsZWQgKi8KICBGRF9aRVJPKCZyZWFkZmRzKTsKICBGRF9aRVJPKCZleGNlcHRmZHMpOwogIFNJR05BTF9NYXNrQXN5bmNFdmVudHMoRkFMU0UpOwogIGRvIHsKICAgRkRfU0VUKGxwRG9zVGFzay0+cmVhZF9waXBlLCZyZWFkZmRzKTsKICAgRkRfU0VUKGxwRG9zVGFzay0+cmVhZF9waXBlLCZleGNlcHRmZHMpOwogICBzZWxlY3QobHBEb3NUYXNrLT5yZWFkX3BpcGUrMSwmcmVhZGZkcyxOVUxMLCZleGNlcHRmZHMsTlVMTCk7CiAgfSB3aGlsZSAoIShGRF9JU1NFVChscERvc1Rhc2stPnJlYWRfcGlwZSwmcmVhZGZkcyl8fAogICAgICAgICAgICAgRkRfSVNTRVQobHBEb3NUYXNrLT5yZWFkX3BpcGUsJmV4Y2VwdGZkcykpKTsKICBTSUdOQUxfTWFza0FzeW5jRXZlbnRzKFRSVUUpOwogIC8qIHJlYWQgcmVzcG9uc2UgKHdpdGggYXN5bmMgZXZlbnRzIGRpc2FibGVkIHRvIGF2b2lkIHNvbWUgc3RyYW5nZSBwcm9ibGVtcykgKi8KICBkbyB7CiAgIGlmICgobGVuPXJlYWQobHBEb3NUYXNrLT5yZWFkX3BpcGUsJnN0YXQsc2l6ZW9mKHN0YXQpKSkhPXNpemVvZihzdGF0KSkgewogICAgaWYgKCgoZXJybm89PUVJTlRSKXx8KGVycm5vPT1FQUdBSU4pKSYmKGxlbjw9MCkpIHsKICAgICBXQVJOKG1vZHVsZSwicmVyZWFkaW5nIGRvc21vZCByZXR1cm4gY29kZSBkdWUgdG8gZXJybm89JWQsIHJlc3VsdD0lZFxuIixlcnJubyxsZW4pOwogICAgIGNvbnRpbnVlOwogICAgfQogICAgRVJSKG1vZHVsZSwiZG9zbW9kIHN5bmMgbG9zdCByZWFkaW5nIHJldHVybiBjb2RlLCBlcnJubz0lZCwgcmVzdWx0PSVkXG4iLGVycm5vLGxlbik7CiAgICByZXR1cm4gLTE7CiAgIH0KICB9IHdoaWxlICgwKTsKICBUUkFDRShtb2R1bGUsImRvc21vZCByZXR1cm4gY29kZT0lZFxuIixzdGF0KTsKICBkbyB7CiAgIGlmICgobGVuPXJlYWQobHBEb3NUYXNrLT5yZWFkX3BpcGUsJlZNODYsc2l6ZW9mKFZNODYpKSkhPXNpemVvZihWTTg2KSkgewogICAgaWYgKCgoZXJybm89PUVJTlRSKXx8KGVycm5vPT1FQUdBSU4pKSYmKGxlbjw9MCkpIHsKICAgICBXQVJOKG1vZHVsZSwicmVyZWFkaW5nIGRvc21vZCBWTTg2IHN0cnVjdHVyZSBkdWUgdG8gZXJybm89JWQsIHJlc3VsdD0lZFxuIixlcnJubyxsZW4pOwogICAgIGNvbnRpbnVlOwogICAgfQogICAgRVJSKG1vZHVsZSwiZG9zbW9kIHN5bmMgbG9zdCByZWFkaW5nIFZNODYgc3RydWN0dXJlLCBlcnJubz0lZCwgcmVzdWx0PSVkXG4iLGVycm5vLGxlbik7CiAgICByZXR1cm4gLTE7CiAgIH0KICB9IHdoaWxlICgwKTsKICBpZiAoKHN0YXQmMHhmZik9PURPU01PRF9TSUdOQUwpIHsKICAgZG8gewogICAgaWYgKChsZW49cmVhZChscERvc1Rhc2stPnJlYWRfcGlwZSwmc2lnLHNpemVvZihzaWcpKSkhPXNpemVvZihzaWcpKSB7CiAgICAgaWYgKCgoZXJybm89PUVJTlRSKXx8KGVycm5vPT1FQUdBSU4pKSYmKGxlbjw9MCkpIHsKICAgICAgV0FSTihtb2R1bGUsInJlcmVhZGluZyBkb3Ntb2Qgc2lnbmFsIGR1ZSB0byBlcnJubz0lZCwgcmVzdWx0PSVkXG4iLGVycm5vLGxlbik7CiAgICAgIGNvbnRpbnVlOwogICAgIH0KICAgICBFUlIobW9kdWxlLCJkb3Ntb2Qgc3luYyBsb3N0IHJlYWRpbmcgc2lnbmFsLCBlcnJubz0lZCwgcmVzdWx0PSVkXG4iLGVycm5vLGxlbik7CiAgICAgcmV0dXJuIC0xOwogICAgfQogICB9IHdoaWxlICgwKTsKICB9IGVsc2Ugc2lnPTA7CiAgLyogZ290IHJlc3BvbnNlICovCiB9IHdoaWxlIChET1NWTV9Qcm9jZXNzKGxwRG9zVGFzayxzdGF0LHNpZywmVk04Nik+PTApOwoKIGlmIChjb250ZXh0KSB7CiNkZWZpbmUgQ1AoeCx5KSB5IyNfcmVnKGNvbnRleHQpID0gVk04Ni5yZWdzLngKICBDVjsKI3VuZGVmIENQCiB9CiByZXR1cm4gMDsKfQoKdm9pZCBET1NWTV9TZXRUaW1lciggdW5zaWduZWQgdGlja3MgKQp7CiBUREIgKnBUYXNrID0gKFREQiAqKUdsb2JhbExvY2sxNiggR2V0Q3VycmVudFRhc2soKSApOwogTkVfTU9EVUxFICpwTW9kdWxlID0gTkVfR2V0UHRyKCBwVGFzay0+aE1vZHVsZSApOwogaW50IHN0YXQ9RE9TTU9EX1NFVF9USU1FUjsKIHN0cnVjdCB0aW1ldmFsIHRpbTsKCiBHbG9iYWxVbmxvY2sxNiggR2V0Q3VycmVudFRhc2soKSApOwogaWYgKHBNb2R1bGUmJnBNb2R1bGUtPmxwRG9zVGFzaykgewogIC8qIHRoZSBQQyBjbG9ja3MgdGlja3MgYXQgMTE5MzE4MCBIeiAqLwogIHRpbS50dl9zZWM9MDsKICB0aW0udHZfdXNlYz0oKHVuc2lnbmVkIGxvbmcgbG9uZyl0aWNrcyoxMDAwMDAwKS8xMTkzMTgwOwogIC8qIHNhbml0eSBjaGVjayAqLwogIGlmICghdGltLnR2X3VzZWMpIHRpbS50dl91c2VjPTE7CgogIGlmICh3cml0ZShwTW9kdWxlLT5scERvc1Rhc2stPndyaXRlX3BpcGUsJnN0YXQsc2l6ZW9mKHN0YXQpKSE9c2l6ZW9mKHN0YXQpKSB7CiAgIEVSUihtb2R1bGUsImRvc21vZCBzeW5jIGxvc3QsIGVycm5vPSVkXG4iLGVycm5vKTsKICAgcmV0dXJuOwogIH0KICBpZiAod3JpdGUocE1vZHVsZS0+bHBEb3NUYXNrLT53cml0ZV9waXBlLCZ0aW0sc2l6ZW9mKHRpbSkpIT1zaXplb2YodGltKSkgewogICBFUlIobW9kdWxlLCJkb3Ntb2Qgc3luYyBsb3N0LCBlcnJubz0lZFxuIixlcnJubyk7CiAgIHJldHVybjsKICB9CiAgLyogdGhlcmUncyBubyByZXR1cm4gKi8KIH0KfQoKdW5zaWduZWQgRE9TVk1fR2V0VGltZXIoIHZvaWQgKQp7CiBUREIgKnBUYXNrID0gKFREQiAqKUdsb2JhbExvY2sxNiggR2V0Q3VycmVudFRhc2soKSApOwogTkVfTU9EVUxFICpwTW9kdWxlID0gTkVfR2V0UHRyKCBwVGFzay0+aE1vZHVsZSApOwogaW50IHN0YXQ9RE9TTU9EX0dFVF9USU1FUjsKIHN0cnVjdCB0aW1ldmFsIHRpbTsKCiBHbG9iYWxVbmxvY2sxNiggR2V0Q3VycmVudFRhc2soKSApOwogaWYgKHBNb2R1bGUmJnBNb2R1bGUtPmxwRG9zVGFzaykgewogIGlmICh3cml0ZShwTW9kdWxlLT5scERvc1Rhc2stPndyaXRlX3BpcGUsJnN0YXQsc2l6ZW9mKHN0YXQpKSE9c2l6ZW9mKHN0YXQpKSB7CiAgIEVSUihtb2R1bGUsImRvc21vZCBzeW5jIGxvc3QsIGVycm5vPSVkXG4iLGVycm5vKTsKICAgcmV0dXJuIDA7CiAgfQogIC8qIHJlYWQgcmVzcG9uc2UgKi8KICBpZiAocmVhZChwTW9kdWxlLT5scERvc1Rhc2stPnJlYWRfcGlwZSwmdGltLHNpemVvZih0aW0pKSE9c2l6ZW9mKHRpbSkpIHsKICAgRVJSKG1vZHVsZSwiZG9zbW9kIHN5bmMgbG9zdCwgZXJybm89JWRcbiIsZXJybm8pOwogICByZXR1cm4gMDsKICB9CiAgcmV0dXJuICgodW5zaWduZWQgbG9uZyBsb25nKXRpbS50dl91c2VjKjExOTMxODApLzEwMDAwMDA7CiB9CiByZXR1cm4gMDsKfQoKdm9pZCBNWl9UaWNrKCBXT1JEIGhhbmRsZSApCnsKIC8qIGZpbmQgdGhlIERPUyB0YXNrIHRoYXQgaGFzIHRoZSByaWdodCBzeXN0ZW1fdGltZXIgaGFuZGxlLi4uICovCiAvKiBzaG91bGQgdXN1YWxseSBiZSB0aGUgY3VycmVudCwgc28gbGV0J3MganVzdCBiZSBsYXp5Li4uICovCiBUREIgKnBUYXNrID0gKFREQiopR2xvYmFsTG9jazE2KCBHZXRDdXJyZW50VGFzaygpICk7CiBORV9NT0RVTEUgKnBNb2R1bGUgPSBwVGFzayA/IE5FX0dldFB0ciggcFRhc2stPmhNb2R1bGUgKSA6IE5VTEw7CiBMUERPU1RBU0sgbHBEb3NUYXNrID0gcE1vZHVsZSA/IHBNb2R1bGUtPmxwRG9zVGFzayA6IE5VTEw7CgogR2xvYmFsVW5sb2NrMTYoIEdldEN1cnJlbnRUYXNrKCkgKTsKIGlmIChscERvc1Rhc2smJihscERvc1Rhc2stPnN5c3RlbV90aW1lcj09aGFuZGxlKSkgewogIC8qIEJJT1MgdGltZXIgdGljayAqLwogICgqKChEV09SRCopKCgoQllURSopKGxwRG9zVGFzay0+aW1nKSkrMHg0NmMpKSkrKzsKIH0KfQoKI2Vsc2UgLyogIU1aX1NVUFBPUlRFRCAqLwoKaW50IERPU1ZNX0VudGVyKCBQQ09OVEVYVCBjb250ZXh0ICkKewogRVJSKG1vZHVsZSwiRE9TIHJlYWxtb2RlIG5vdCBzdXBwb3J0ZWQgb24gdGhpcyBhcmNoaXRlY3R1cmUhXG4iKTsKIHJldHVybiAtMTsKfQoKdm9pZCBNWl9UaWNrKCBXT1JEIGhhbmRsZSApIHt9CnZvaWQgRE9TVk1fU2V0VGltZXIoIHVuc2lnbmVkIHRpY2tzICkge30KdW5zaWduZWQgRE9TVk1fR2V0VGltZXIoIHZvaWQgKSB7IHJldHVybiAwOyB9CgojZW5kaWYK