LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGNvZGUgaGFzbid0IGJlZW4gY29tcGxldGVseSBjbGVhbmVkIHVwIHlldC4KICovCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHNpZ25hbC5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxzeXMvdGltZS5oPgojaW5jbHVkZSAid2luZG93cy5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAibW9kdWxlLmgiCiNpbmNsdWRlICJ0YXNrLmgiCiNpbmNsdWRlICJzZWxlY3RvcnMuaCIKI2luY2x1ZGUgImZpbGUuaCIKI2luY2x1ZGUgImxkdC5oIgojaW5jbHVkZSAicHJvY2Vzcy5oIgojaW5jbHVkZSAibWlzY2VtdS5oIgojaW5jbHVkZSAiZGVidWcuaCIKI2luY2x1ZGUgImRvc2V4ZS5oIgojaW5jbHVkZSAiZG9zbW9kLmgiCiNpbmNsdWRlICJvcHRpb25zLmgiCgojaWZkZWYgTVpfU1VQUE9SVEVECgojaW5jbHVkZSA8c3lzL21tYW4uaD4KCi8qIGRlZmluZSB0aGlzIHRvIHRyeSBtYXBwaW5nIHRocm91Z2ggL3Byb2MvcGlkL21lbSBpbnN0ZWFkIG9mIGEgdGVtcCBmaWxlLAogICBidXQgTGludXMgZG9lc24ndCBsaWtlIG1tYXBwaW5nIC9wcm9jL3BpZC9tZW0sIHNvIGl0IGRvZXNuJ3Qgd29yayBmb3IgbWUgKi8KI3VuZGVmIE1aX01BUFNFTEYKCiNkZWZpbmUgQklPU19EQVRBX1NFR01FTlQgMHg0MAojZGVmaW5lIFNUQVJUX09GRlNFVCAwCiNkZWZpbmUgUFNQX1NJWkUgMHgxMAoKI2RlZmluZSBTRUcxNihwdHIsc2VnKSAoKExQVk9JRCkoKEJZVEUqKXB0cisoKERXT1JEKShzZWcpPDw0KSkpCiNkZWZpbmUgU0VHUFRSMTYocHRyLHNlZ3B0cikgKChMUFZPSUQpKChCWVRFKilwdHIrKChEV09SRClTRUxFQ1RPUk9GKHNlZ3B0cik8PDQpK09GRlNFVE9GKHNlZ3B0cikpKQoKc3RhdGljIHZvaWQgTVpfSW5pdFBTUCggTFBWT0lEIGxwUFNQLCBMUENTVFIgY21kbGluZSwgV09SRCBlbnYgKQp7CiBQREIqcHNwPWxwUFNQOwogY29uc3QgY2hhcipjbWQ9Y21kbGluZT9zdHJjaHIoY21kbGluZSwnICcpOk5VTEw7CgogcHNwLT5pbnQyMD0weDIwQ0Q7IC8qIGludCAyMCAqLwogLyogc29tZSBwcm9ncmFtcyB1c2UgdGhpcyB0byBjYWxjdWxhdGUgaG93IG11Y2ggbWVtb3J5IHRoZXkgbmVlZCAqLwogcHNwLT5uZXh0UGFyYWdyYXBoPTB4OUZGRjsKIHBzcC0+ZW52aXJvbm1lbnQ9ZW52OwogLyogY29weSBwYXJhbWV0ZXJzICovCiBpZiAoY21kKSB7CiNpZiAwCiAgLyogY29tbWFuZC5jb20gZG9lc24ndCBkbyB0aGlzICovCiAgd2hpbGUgKCpjbWQgPT0gJyAnKSBjbWQrKzsKI2VuZGlmCiAgcHNwLT5jbWRMaW5lWzBdPXN0cmxlbihjbWQpOwogIHN0cmNweShwc3AtPmNtZExpbmUrMSxjbWQpOwogIHBzcC0+Y21kTGluZVtwc3AtPmNtZExpbmVbMF0rMV09J1xyJzsKIH0gZWxzZSBwc3AtPmNtZExpbmVbMV09J1xyJzsKIC8qIEZJWE1FOiBpbnRlZ3JhdGUgdGhlIG1lbW9yeSBzdHVmZiBmcm9tIFdpbmUgKG1zZG9zL2Rvc21lbS5jKSAqLwogLyogRklYTUU6IGludGVncmF0ZSB0aGUgUERCIHN0dWZmIGZyb20gV2luZSAobG9hZGVyL3Rhc2suYykgKi8KfQoKLyogZGVmYXVsdCBJTlQgMDggaGFuZGxlcjogaW5jcmVhc2VzIHRpbWVyIHRpY2sgY291bnRlciBidXQgbm90IG11Y2ggbW9yZSAqLwpzdGF0aWMgY2hhciBpbnQwOFtdPXsKIDB4Q0QsMHgxQywgICAgICAgICAgIC8qIGludCAkMHgxYyAqLwogMHg1MCwgICAgICAgICAgICAgICAgLyogcHVzaHcgJWF4ICovCiAweDFFLCAgICAgICAgICAgICAgICAvKiBwdXNodyAlZHMgKi8KIDB4QjgsMHg0MCwweDAwLCAgICAgIC8qIG1vdncgJDB4NDAsJWF4ICovCiAweDhFLDB4RDgsICAgICAgICAgICAvKiBtb3Z3ICVheCwlZHMgKi8KI2lmIDAKIDB4ODMsMHgwNiwweDZDLDB4MDAsMHgwMSwgLyogYWRkdyAkMSwoMHg2YykgKi8KIDB4ODMsMHgxNiwweDZFLDB4MDAsMHgwMCwgLyogYWRjdyAkMCwoMHg2ZSkgKi8KI2Vsc2UKIDB4NjYsMHhGRiwweDA2LDB4NkMsMHgwMCwgLyogaW5jbCAoMHg2YykgKi8KI2VuZGlmCiAweEIwLDB4MjAsICAgICAgICAgICAvKiBtb3ZiICQweDIwLCVhbCAqLwogMHhFNiwweDIwLCAgICAgICAgICAgLyogb3V0YiAlYWwsJDB4MjAgKi8KIDB4MUYsICAgICAgICAgICAgICAgIC8qIHBvcHcgJWF4ICovCiAweDU4LCAgICAgICAgICAgICAgICAvKiBwb3B3ICVheCAqLwogMHhDRiAgICAgICAgICAgICAgICAgLyogaXJldCAqLwp9OwoKc3RhdGljIHZvaWQgTVpfSW5pdEhhbmRsZXJzKCBMUERPU1RBU0sgbHBEb3NUYXNrICkKewogV09SRCBzZWc7CiBMUEJZVEUgc3RhcnQ9RE9TTUVNX0dldEJsb2NrKGxwRG9zVGFzay0+aE1vZHVsZSxzaXplb2YoaW50MDgpLCZzZWcpOwogbWVtY3B5KHN0YXJ0LGludDA4LHNpemVvZihpbnQwOCkpOwovKiBJTlQgMDg6IHBvaW50IGl0IGF0IG91ciB0aWNrLWluY3JlbWVudGluZyBoYW5kbGVyICovCiAoKFNFR1BUUiopKGxwRG9zVGFzay0+aW1nKSlbMHgwOF09UFRSX1NFR19PRkZfVE9fU0VHUFRSKHNlZywwKTsKLyogSU5UIDFDOiBqdXN0IHBvaW50IGl0IHRvIElSRVQsIHdlIGRvbid0IHdhbnQgdG8gaGFuZGxlIGl0IG91cnNlbHZlcyAqLwogKChTRUdQVFIqKShscERvc1Rhc2stPmltZykpWzB4MUNdPVBUUl9TRUdfT0ZGX1RPX1NFR1BUUihzZWcsc2l6ZW9mKGludDA4KS0xKTsKfQoKc3RhdGljIGNoYXIgZW50ZXJfeG1zW109ewovKiBYTVMgaG9va2FibGUgZW50cnkgcG9pbnQgKi8KIDB4RUIsMHgwMywgICAgICAgICAgIC8qIGptcCBlbnRyeSAqLwogMHg5MCwweDkwLDB4OTAsICAgICAgLyogbm9wO25vcDtub3AgKi8KICAgICAgICAgICAgICAgICAgICAgIC8qIGVudHJ5OiAqLwovKiByZWFsIGVudHJ5IHBvaW50ICovCi8qIGZvciBzaW1wbGljaXR5LCB3ZSdsbCBqdXN0IHVzZSB0aGUgc2FtZSBob29rIGFzIERQTUkgYmVsb3cgKi8KIDB4Q0QsMHgzMSwgICAgICAgICAgIC8qIGludCAkMHgzMSAqLwogMHhDQiAgICAgICAgICAgICAgICAgLyogbHJldCAqLwp9OwoKc3RhdGljIHZvaWQgTVpfSW5pdFhNUyggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIExQQllURSBzdGFydD1ET1NNRU1fR2V0QmxvY2sobHBEb3NUYXNrLT5oTW9kdWxlLHNpemVvZihlbnRlcl94bXMpLCYobHBEb3NUYXNrLT54bXNfc2VnKSk7CiBtZW1jcHkoc3RhcnQsZW50ZXJfeG1zLHNpemVvZihlbnRlcl94bXMpKTsKfQoKc3RhdGljIGNoYXIgZW50ZXJfcG1bXT17CiAweDUwLCAgICAgICAgICAgICAgICAvKiBwdXNodyAlYXggKi8KIDB4NTIsICAgICAgICAgICAgICAgIC8qIHB1c2h3ICVkeCAqLwogMHg1NSwgICAgICAgICAgICAgICAgLyogcHVzaHcgJWJwICovCiAweDg5LDB4RTUsICAgICAgICAgICAvKiBtb3Z3ICVzcCwlYnAgKi8KLyogZ2V0IHJldHVybiBDUyAqLwogMHg4QiwweDU2LDB4MDgsICAgICAgLyogbW92dyA4KCVicCksJWR4ICovCi8qIGp1c3QgY2FsbCBpbnQgMzEgaGVyZSB0byBnZXQgaW50byBwcm90ZWN0ZWQgbW9kZS4uLiAqLwovKiBpdCdsbCBjaGVjayB3aGV0aGVyIGl0IHdhcyBjYWxsZWQgZnJvbSBkcG1pX3NlZy4uLiAqLwogMHhDRCwweDMxLCAgICAgICAgICAgLyogaW50ICQweDMxICovCi8qIHdlIGFyZSBub3cgaW4gdGhlIGNvbnRleHQgb2YgYSAxNi1iaXQgcmVsYXkgY2FsbCAqLwovKiBuZWVkIHRvIGZpeHVwIG91ciBzdGFjazsKICogMTYtYml0IHJlbGF5IHJldHVybiBhZGRyZXNzIHdpbGwgYmUgbG9zdCwgYnV0IHdlIHdvbid0IHdvcnJ5IHF1aXRlIHlldCAqLwogMHg4RSwweEQwLCAgICAgICAgICAgLyogbW92dyAlYXgsJXNzICovCiAweDY2LDB4MEYsMHhCNywweEU1LCAvKiBtb3Z6d2wgJWJwLCVlc3AgKi8KLyogc2V0IHJldHVybiBDUyAqLwogMHg4OSwweDU2LDB4MDgsICAgICAgLyogbW92dyAlZHgsOCglYnApICovCiAweDVELCAgICAgICAgICAgICAgICAvKiBwb3B3ICVicCAqLwogMHg1QSwgICAgICAgICAgICAgICAgLyogcG9wdyAlZHggKi8KIDB4NTgsICAgICAgICAgICAgICAgIC8qIHBvcHcgJWF4ICovCiAweENCICAgICAgICAgICAgICAgICAvKiBscmV0ICovCn07CgpzdGF0aWMgdm9pZCBNWl9Jbml0RFBNSSggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIHVuc2lnbmVkIHNpemU9c2l6ZW9mKGVudGVyX3BtKTsKIExQQllURSBzdGFydD1ET1NNRU1fR2V0QmxvY2sobHBEb3NUYXNrLT5oTW9kdWxlLHNpemUsJihscERvc1Rhc2stPmRwbWlfc2VnKSk7CiAKIGxwRG9zVGFzay0+ZHBtaV9zZWwgPSBTRUxFQ1RPUl9BbGxvY0Jsb2NrKCBzdGFydCwgc2l6ZSwgU0VHTUVOVF9DT0RFLCBGQUxTRSwgRkFMU0UgKTsKCiBtZW1jcHkoc3RhcnQsZW50ZXJfcG0sc2l6ZW9mKGVudGVyX3BtKSk7Cn0KCnN0YXRpYyBXT1JEIE1aX0luaXRFbnZpcm9ubWVudCggTFBET1NUQVNLIGxwRG9zVGFzaywgTFBDU1RSIGVudiwgTFBDU1RSIG5hbWUgKQp7CiB1bnNpZ25lZCBzej0wOwogV09SRCBzZWc7CiBMUFNUUiBlbnZibGs7CgogaWYgKGVudikgewogIC8qIGdldCBzaXplIG9mIGVudmlyb25tZW50IGJsb2NrICovCiAgd2hpbGUgKGVudltzeisrXSkgc3orPXN0cmxlbihlbnYrc3opKzE7CiB9IGVsc2Ugc3orKzsKIC8qIGFsbG9jYXRlIGl0ICovCiBlbnZibGs9RE9TTUVNX0dldEJsb2NrKGxwRG9zVGFzay0+aE1vZHVsZSxzeitzaXplb2YoV09SRCkrc3RybGVuKG5hbWUpKzEsJnNlZyk7CiAvKiBmaWxsIGl0ICovCiBpZiAoZW52KSB7CiAgbWVtY3B5KGVudmJsayxlbnYsc3opOwogfSBlbHNlIGVudmJsa1swXT0wOwogLyogRE9TIDMueDogdGhlIGJsb2NrIGNvbnRhaW5zIDEgYWRkaXRpb25hbCBzdHJpbmcgKi8KICooV09SRCopKGVudmJsaytzeik9MTsKIC8qIGJlaW5nIHRoZSBwcm9ncmFtIG5hbWUgaXRzZWxmICovCiBzdHJjcHkoZW52YmxrK3N6K3NpemVvZihXT1JEKSxuYW1lKTsKIHJldHVybiBzZWc7Cn0KCmludCBNWl9Jbml0TWVtb3J5KCBMUERPU1RBU0sgbHBEb3NUYXNrLCBORV9NT0RVTEUgKnBNb2R1bGUgKQp7CiBpbnQgeDsKCiBpZiAobHBEb3NUYXNrLT5pbWdfb2ZzKSByZXR1cm4gMzI7IC8qIGFscmVhZHkgYWxsb2NhdGVkICovCgogLyogYWxsb2NhdGUgMU1CKzY0SyBzaGFyZWQgbWVtb3J5ICovCiBscERvc1Rhc2stPmltZ19vZnM9U1RBUlRfT0ZGU0VUOwojaWZkZWYgTVpfTUFQU0VMRgogbHBEb3NUYXNrLT5pbWc9VmlydHVhbEFsbG9jKE5VTEwsMHgxMTAwMDAsTUVNX0NPTU1JVCxQQUdFX1JFQURXUklURSk7CiAvKiBtYWtlIHN1cmUgbW1hcCBhY2NlcHRzIGl0ICovCiAoKGNoYXIqKWxwRG9zVGFzay0+aW1nKVsweDEwRkZGRl09MDsKI2Vsc2UKIHRtcG5hbShscERvc1Rhc2stPm1tX25hbWUpOwovKiBzdHJjcHkobHBEb3NUYXNrLT5tbV9uYW1lLCIvdG1wL215ZG9zaW1hZ2UiKTsgKi8KIGxwRG9zVGFzay0+bW1fZmQ9b3BlbihscERvc1Rhc2stPm1tX25hbWUsT19SRFdSfE9fQ1JFQVQgLyogfE9fVFJVTkMgKi8sU19JUlVTUnxTX0lXVVNSKTsKIGlmIChscERvc1Rhc2stPm1tX2ZkPDApIEVSUihtb2R1bGUsImZpbGUgJXMgY291bGQgbm90IGJlIG9wZW5lZFxuIixscERvc1Rhc2stPm1tX25hbWUpOwogLyogZXhwYW5kIGZpbGUgdG8gMU1CKzY0SyAqLwogbHNlZWsobHBEb3NUYXNrLT5tbV9mZCwweDExMDAwMC0xLFNFRUtfU0VUKTsKIHg9MDsgd3JpdGUobHBEb3NUYXNrLT5tbV9mZCwmeCwxKTsKIC8qIG1hcCBpdCBpbiAqLwogbHBEb3NUYXNrLT5pbWc9bW1hcChOVUxMLDB4MTEwMDAwLVNUQVJUX09GRlNFVCxQUk9UX1JFQUR8UFJPVF9XUklURSxNQVBfU0hBUkVELGxwRG9zVGFzay0+bW1fZmQsMCk7CiNlbmRpZgogaWYgKGxwRG9zVGFzay0+aW1nPT0oTFBWT0lEKS0xKSB7CiAgRVJSKG1vZHVsZSwiY291bGQgbm90IG1hcCBzaGFyZWQgbWVtb3J5LCBlcnJvcj0lc1xuIixzdHJlcnJvcihlcnJubykpOwogIHJldHVybiAwOwogfQogVFJBQ0UobW9kdWxlLCJET1MgVk04NiBpbWFnZSBtYXBwZWQgYXQgJTA4bHhcbiIsKERXT1JEKWxwRG9zVGFzay0+aW1nKTsKIHBNb2R1bGUtPmRvc19pbWFnZT1scERvc1Rhc2stPmltZzsKCiAvKiBpbml0aWFsaXplIHRoZSBtZW1vcnkgKi8KIFRSQUNFKG1vZHVsZSwiSW5pdGlhbGl6aW5nIERPUyBtZW1vcnkgc3RydWN0dXJlc1xuIik7CiBET1NNRU1fSW5pdChscERvc1Rhc2stPmhNb2R1bGUpOwogTVpfSW5pdEhhbmRsZXJzKGxwRG9zVGFzayk7CiBNWl9Jbml0WE1TKGxwRG9zVGFzayk7CiBNWl9Jbml0RFBNSShscERvc1Rhc2spOwogcmV0dXJuIGxwRG9zVGFzay0+aE1vZHVsZTsKfQoKc3RhdGljIGludCBNWl9Mb2FkSW1hZ2UoIEhGSUxFMTYgaEZpbGUsIExQQ1NUUiBuYW1lLCBMUENTVFIgY21kbGluZSwKICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBlbnYsIExQRE9TVEFTSyBscERvc1Rhc2ssIE5FX01PRFVMRSAqcE1vZHVsZSApCnsKIElNQUdFX0RPU19IRUFERVIgbXpfaGVhZGVyOwogRFdPUkQgaW1hZ2Vfc3RhcnQsaW1hZ2Vfc2l6ZSxtaW5fc2l6ZSxtYXhfc2l6ZSxhdmFpbDsKIEJZVEUqcHNwX3N0YXJ0LCpsb2FkX3N0YXJ0OwogaW50IHgsb2xkX2NvbT0wOwogU0VHUFRSIHJlbG9jOwogV09SRCBlbnZfc2VnOwoKIGlmICgoX2hyZWFkMTYoaEZpbGUsJm16X2hlYWRlcixzaXplb2YobXpfaGVhZGVyKSkgIT0gc2l6ZW9mKG16X2hlYWRlcikpIHx8CiAgICAgKG16X2hlYWRlci5lX21hZ2ljICE9IElNQUdFX0RPU19TSUdOQVRVUkUpKSB7CiNpZiAwCiAgICAgcmV0dXJuIDExOyAvKiBpbnZhbGlkIGV4ZSAqLwojZW5kaWYKICBvbGRfY29tPTE7IC8qIGFzc3VtZSAuQ09NIGZpbGUgKi8KICBpbWFnZV9zdGFydD0wOwogIGltYWdlX3NpemU9R2V0RmlsZVNpemUoRklMRV9HZXRIYW5kbGUzMihoRmlsZSksTlVMTCk7CiAgbWluX3NpemU9MHgxMDAwMDsgbWF4X3NpemU9MHgxMDAwMDA7CiAgbXpfaGVhZGVyLmVfY3JsYz0wOwogIG16X2hlYWRlci5lX3NzPTA7IG16X2hlYWRlci5lX3NwPTB4RkZGRTsKICBtel9oZWFkZXIuZV9jcz0wOyBtel9oZWFkZXIuZV9pcD0weDEwMDsKIH0gZWxzZSB7CiAgLyogY2FsY3VsYXRlIGxvYWQgc2l6ZSAqLwogIGltYWdlX3N0YXJ0PW16X2hlYWRlci5lX2NwYXJoZHI8PDQ7CiAgaW1hZ2Vfc2l6ZT1tel9oZWFkZXIuZV9jcDw8OTsgLyogcGFnZXMgYXJlIDUxMiBieXRlcyAqLwogIGlmICgobXpfaGVhZGVyLmVfY2JscCE9MCkmJihtel9oZWFkZXIuZV9jYmxwIT00KSkgaW1hZ2Vfc2l6ZS09NTEyLW16X2hlYWRlci5lX2NibHA7CiAgaW1hZ2Vfc2l6ZS09aW1hZ2Vfc3RhcnQ7CiAgbWluX3NpemU9aW1hZ2Vfc2l6ZSsoKERXT1JEKW16X2hlYWRlci5lX21pbmFsbG9jPDw0KSsoUFNQX1NJWkU8PDQpOwogIG1heF9zaXplPWltYWdlX3NpemUrKChEV09SRCltel9oZWFkZXIuZV9tYXhhbGxvYzw8NCkrKFBTUF9TSVpFPDw0KTsKIH0KCiBNWl9Jbml0TWVtb3J5KGxwRG9zVGFzayxwTW9kdWxlKTsKCiAvKiBhbGxvY2F0ZSBlbnZpcm9ubWVudCBibG9jayAqLwogZW52X3NlZz1NWl9Jbml0RW52aXJvbm1lbnQobHBEb3NUYXNrLGVudixuYW1lKTsKCiAvKiBhbGxvY2F0ZSBtZW1vcnkgZm9yIHRoZSBleGVjdXRhYmxlICovCiBUUkFDRShtb2R1bGUsIkFsbG9jYXRpbmcgRE9TIG1lbW9yeSAobWluPSVsZCwgbWF4PSVsZClcbiIsbWluX3NpemUsbWF4X3NpemUpOwogYXZhaWw9RE9TTUVNX0F2YWlsYWJsZShscERvc1Rhc2stPmhNb2R1bGUpOwogaWYgKGF2YWlsPG1pbl9zaXplKSB7CiAgRVJSKG1vZHVsZSwgImluc3VmZmljaWVudCBET1MgbWVtb3J5XG4iKTsKICByZXR1cm4gMDsKIH0KIGlmIChhdmFpbD5tYXhfc2l6ZSkgYXZhaWw9bWF4X3NpemU7CiBwc3Bfc3RhcnQ9RE9TTUVNX0dldEJsb2NrKGxwRG9zVGFzay0+aE1vZHVsZSxhdmFpbCwmbHBEb3NUYXNrLT5wc3Bfc2VnKTsKIGlmICghcHNwX3N0YXJ0KSB7CiAgRVJSKG1vZHVsZSwgImVycm9yIGFsbG9jYXRpbmcgRE9TIG1lbW9yeVxuIik7CiAgcmV0dXJuIDA7CiB9CiBscERvc1Rhc2stPmxvYWRfc2VnPWxwRG9zVGFzay0+cHNwX3NlZysob2xkX2NvbT8wOlBTUF9TSVpFKTsKIGxvYWRfc3RhcnQ9cHNwX3N0YXJ0KyhQU1BfU0laRTw8NCk7CiBNWl9Jbml0UFNQKHBzcF9zdGFydCwgY21kbGluZSwgZW52X3NlZyk7CgogLyogbG9hZCBleGVjdXRhYmxlIGltYWdlICovCiBUUkFDRShtb2R1bGUsImxvYWRpbmcgRE9TICVzIGltYWdlLCAlMDhseCBieXRlc1xuIixvbGRfY29tPyJDT00iOiJFWEUiLGltYWdlX3NpemUpOwogX2xsc2VlazE2KGhGaWxlLGltYWdlX3N0YXJ0LEZJTEVfQkVHSU4pOwogaWYgKChfaHJlYWQxNihoRmlsZSxsb2FkX3N0YXJ0LGltYWdlX3NpemUpKSAhPSBpbWFnZV9zaXplKQogIHJldHVybiAxMTsgLyogaW52YWxpZCBleGUgKi8KCiBpZiAobXpfaGVhZGVyLmVfY3JsYykgewogIC8qIGxvYWQgcmVsb2NhdGlvbiB0YWJsZSAqLwogIFRSQUNFKG1vZHVsZSwibG9hZGluZyBET1MgRVhFIHJlbG9jYXRpb24gdGFibGUsICVkIGVudHJpZXNcbiIsbXpfaGVhZGVyLmVfY3JsYyk7CiAgLyogRklYTUU6IGlzIHRoaXMgdG9vIHNsb3cgd2l0aG91dCByZWFkIGJ1ZmZlcmluZz8gKi8KICBfbGxzZWVrMTYoaEZpbGUsbXpfaGVhZGVyLmVfbGZhcmxjLEZJTEVfQkVHSU4pOwogIGZvciAoeD0wOyB4PG16X2hlYWRlci5lX2NybGM7IHgrKykgewogICBpZiAoX2xyZWFkMTYoaEZpbGUsJnJlbG9jLHNpemVvZihyZWxvYykpICE9IHNpemVvZihyZWxvYykpCiAgICByZXR1cm4gMTE7IC8qIGludmFsaWQgZXhlICovCiAgICooV09SRCopU0VHUFRSMTYobG9hZF9zdGFydCxyZWxvYykrPWxwRG9zVGFzay0+bG9hZF9zZWc7CiAgfQogfQoKIGxwRG9zVGFzay0+aW5pdF9jcz1scERvc1Rhc2stPmxvYWRfc2VnK216X2hlYWRlci5lX2NzOwogbHBEb3NUYXNrLT5pbml0X2lwPW16X2hlYWRlci5lX2lwOwogbHBEb3NUYXNrLT5pbml0X3NzPWxwRG9zVGFzay0+bG9hZF9zZWcrbXpfaGVhZGVyLmVfc3M7CiBscERvc1Rhc2stPmluaXRfc3A9bXpfaGVhZGVyLmVfc3A7CgogVFJBQ0UobW9kdWxlLCJlbnRyeSBwb2ludDogJTA0eDolMDR4XG4iLGxwRG9zVGFzay0+aW5pdF9jcyxscERvc1Rhc2stPmluaXRfaXApOwoKIHJldHVybiBscERvc1Rhc2stPmhNb2R1bGU7Cn0KCkxQRE9TVEFTSyBNWl9BbGxvY0RQTUlUYXNrKCBITU9EVUxFMTYgaE1vZHVsZSApCnsKIExQRE9TVEFTSyBscERvc1Rhc2sgPSBjYWxsb2MoMSwgc2l6ZW9mKERPU1RBU0spKTsKIE5FX01PRFVMRSAqcE1vZHVsZTsKCiBpZiAobHBEb3NUYXNrKSB7CiAgbHBEb3NUYXNrLT5oTW9kdWxlID0gaE1vZHVsZTsKCiAgcE1vZHVsZSA9IChORV9NT0RVTEUgKilHbG9iYWxMb2NrMTYoaE1vZHVsZSk7CiAgcE1vZHVsZS0+bHBEb3NUYXNrID0gbHBEb3NUYXNrOwogCiAgbHBEb3NUYXNrLT5pbWc9TlVMTDsgbHBEb3NUYXNrLT5tbV9uYW1lWzBdPTA7IGxwRG9zVGFzay0+bW1fZmQ9LTE7CgogIE1aX0luaXRNZW1vcnkobHBEb3NUYXNrLCBwTW9kdWxlKTsKCiAgR2xvYmFsVW5sb2NrMTYoaE1vZHVsZSk7CiB9CiByZXR1cm4gbHBEb3NUYXNrOwp9CgpzdGF0aWMgdm9pZCBNWl9Jbml0VGltZXIoIExQRE9TVEFTSyBscERvc1Rhc2ssIGludCB2ZXIgKQp7CiBpZiAodmVyPDEpIHsKI2lmIDAKICAvKiBzdGFydCBzaW11bGF0ZWQgc3lzdGVtIDU1SHogdGltZXIgKi8KICBscERvc1Rhc2stPnN5c3RlbV90aW1lciA9IENyZWF0ZVN5c3RlbVRpbWVyKCA1NSwgTVpfVGljayApOwogIFRSQUNFKG1vZHVsZSwiY3JlYXRlZCA1NUh6IHRpbWVyIHRpY2ssIGhhbmRsZT0lZFxuIixscERvc1Rhc2stPnN5c3RlbV90aW1lcik7CiNlbmRpZgogfSBlbHNlIHsKICBpbnQgZnVuYzsKICBzdHJ1Y3QgdGltZXZhbCB0aW07CgogIC8qIHN0YXJ0IGRvc21vZCB0aW1lciBhdCA1NUh6ICovCiAgZnVuYz1ET1NNT0RfU0VUX1RJTUVSOwogIHRpbS50dl9zZWM9MDsgdGltLnR2X3VzZWM9NTQ5MjU7CiAgd3JpdGUobHBEb3NUYXNrLT53cml0ZV9waXBlLCZmdW5jLHNpemVvZihmdW5jKSk7CiAgd3JpdGUobHBEb3NUYXNrLT53cml0ZV9waXBlLCZ0aW0sc2l6ZW9mKHRpbSkpOwogfQp9CgppbnQgTVpfSW5pdFRhc2soIExQRE9TVEFTSyBscERvc1Rhc2sgKQp7CiBpbnQgcmVhZF9mZFsyXSx3cml0ZV9mZFsyXTsKIHBpZF90IGNoaWxkOwogY2hhciAqZm5hbWUsKmZhcmcsYXJnWzE2XSxmcHJvY1s2NF0scGF0aFsyNTZdLCpmcGF0aDsKCiBpZiAoIWxwRG9zVGFzaykgcmV0dXJuIDA7CiAvKiBjcmVhdGUgcmVhZCBwaXBlICovCiBpZiAocGlwZShyZWFkX2ZkKTwwKSByZXR1cm4gMDsKIGlmIChwaXBlKHdyaXRlX2ZkKTwwKSB7CiAgY2xvc2UocmVhZF9mZFswXSk7IGNsb3NlKHJlYWRfZmRbMV0pOyByZXR1cm4gMDsKIH0KIGxwRG9zVGFzay0+cmVhZF9waXBlPXJlYWRfZmRbMF07CiBscERvc1Rhc2stPndyaXRlX3BpcGU9d3JpdGVfZmRbMV07CiAvKiBpZiB3ZSBoYXZlIGEgbWFwcGluZyBmaWxlLCB1c2UgaXQgKi8KIGZuYW1lPWxwRG9zVGFzay0+bW1fbmFtZTsgZmFyZz1OVUxMOwogaWYgKCFmbmFtZVswXSkgewogIC8qIG90aGVyd2lzZSwgbWFwIG91ciBvd24gbWVtb3J5IGltYWdlICovCiAgc3ByaW50ZihmcHJvYywiL3Byb2MvJWQvbWVtIixnZXRwaWQoKSk7CiAgc3ByaW50ZihhcmcsIiVsZCIsKHVuc2lnbmVkIGxvbmcpbHBEb3NUYXNrLT5pbWcpOwogIGZuYW1lPWZwcm9jOyBmYXJnPWFyZzsKIH0KCiBUUkFDRShtb2R1bGUsIkxvYWRpbmcgRE9TIFZNIHN1cHBvcnQgbW9kdWxlIChobW9kdWxlPSUwNHgpXG4iLGxwRG9zVGFzay0+aE1vZHVsZSk7CiBpZiAoKGNoaWxkPWZvcmsoKSk8MCkgewogIGNsb3NlKHdyaXRlX2ZkWzBdKTsgY2xvc2Uod3JpdGVfZmRbMV0pOwogIGNsb3NlKHJlYWRfZmRbMF0pOyBjbG9zZShyZWFkX2ZkWzFdKTsgcmV0dXJuIDA7CiB9CiBpZiAoY2hpbGQhPTApIHsKICAvKiBwYXJlbnQgcHJvY2VzcyAqLwogIGludCByZXQ7CgogIGNsb3NlKHJlYWRfZmRbMV0pOyBjbG9zZSh3cml0ZV9mZFswXSk7CiAgbHBEb3NUYXNrLT50YXNrPWNoaWxkOwogIC8qIHdhaXQgZm9yIGNoaWxkIHByb2Nlc3MgdG8gc2lnbmFsIHJlYWRpbmVzcyAqLwogIGRvIHsKICAgaWYgKHJlYWQobHBEb3NUYXNrLT5yZWFkX3BpcGUsJnJldCxzaXplb2YocmV0KSkhPXNpemVvZihyZXQpKSB7CiAgICBpZiAoKGVycm5vPT1FSU5UUil8fChlcnJubz09RUFHQUlOKSkgY29udGludWU7CiAgICAvKiBmYWlsdXJlICovCiAgICBFUlIobW9kdWxlLCJkb3Ntb2QgaGFzIGZhaWxlZCB0byBpbml0aWFsaXplXG4iKTsKICAgIGlmIChscERvc1Rhc2stPm1tX25hbWVbMF0hPTApIHVubGluayhscERvc1Rhc2stPm1tX25hbWUpOwogICAgcmV0dXJuIDA7CiAgIH0KICB9IHdoaWxlICgwKTsKICAvKiB0aGUgY2hpbGQgaGFzIG5vdyBtbWFwZWQgdGhlIHRlbXAgZmlsZSwgaXQncyBub3cgc2FmZSB0byB1bmxpbmsuCiAgICogZG8gaXQgaGVyZSB0byBhdm9pZCBsZWF2aW5nIGEgbWVzcyBpbiAvdG1wIGlmL3doZW4gV2luZSBjcmFzaGVzLi4uICovCiAgaWYgKGxwRG9zVGFzay0+bW1fbmFtZVswXSE9MCkgdW5saW5rKGxwRG9zVGFzay0+bW1fbmFtZSk7CiAgLyogc3RhcnQgc2ltdWxhdGVkIHN5c3RlbSB0aW1lciAqLwogIE1aX0luaXRUaW1lcihscERvc1Rhc2sscmV0KTsKICAvKiBhbGwgc3lzdGVtcyBhcmUgbm93IGdvICovCiB9IGVsc2UgewogIC8qIGNoaWxkIHByb2Nlc3MgKi8KICBjbG9zZShyZWFkX2ZkWzBdKTsgY2xvc2Uod3JpdGVfZmRbMV0pOwogIC8qIHB1dCBvdXIgcGlwZXMgc29tZXdoZXJlIGRvc21vZCBjYW4gZmluZCB0aGVtICovCiAgZHVwMih3cml0ZV9mZFswXSwwKTsgICAgICAvKiBzdGRpbiAqLwogIGR1cDIocmVhZF9mZFsxXSwxKTsgICAgICAgLyogc3Rkb3V0ICovCiAgLyogZW5hYmxlIHNpZ25hbHMgKi8KICBTSUdOQUxfTWFza0FzeW5jRXZlbnRzKEZBTFNFKTsKICAvKiBub3cgbG9hZCBkb3Ntb2QgKi8KICBleGVjbHAoImRvc21vZCIsZm5hbWUsZmFyZyxOVUxMKTsKICBleGVjbCgiZG9zbW9kIixmbmFtZSxmYXJnLE5VTEwpOwogIC8qIGhtbSwgdGhleSBkaWRuJ3QgaW5zdGFsbCBwcm9wZXJseSAqLwogIGV4ZWNsKCJsb2FkZXIvZG9zL2Rvc21vZCIsZm5hbWUsZmFyZyxOVUxMKTsKICAvKiBsYXN0IHJlc29ydCwgdHJ5IHRvIGZpbmQgaXQgdGhyb3VnaCBhcmd2WzBdICovCiAgZnBhdGg9c3RycmNocihzdHJjcHkocGF0aCxPcHRpb25zLmFyZ3YwKSwnLycpOwogIGlmIChmcGF0aCkgewogICBzdHJjcHkoZnBhdGgsIi9sb2FkZXIvZG9zL2Rvc21vZCIpOwogICBleGVjbChwYXRoLGZuYW1lLGZhcmcsTlVMTCk7CiAgfQogIC8qIGlmIGZhaWx1cmUsIGV4aXQgKi8KICBFUlIobW9kdWxlLCJGYWlsZWQgdG8gc3Bhd24gZG9zbW9kLCBlcnJvcj0lc1xuIixzdHJlcnJvcihlcnJubykpOwogIGV4aXQoMSk7CiB9CiByZXR1cm4gbHBEb3NUYXNrLT5oTW9kdWxlOwp9CgpISU5TVEFOQ0UxNiBNWl9DcmVhdGVQcm9jZXNzKCBMUENTVFIgbmFtZSwgTFBDU1RSIGNtZGxpbmUsIExQQ1NUUiBlbnYsIEJPT0wzMiBpbmhlcml0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNUQVJUVVBJTkZPMzJBIHN0YXJ0dXAsIExQUFJPQ0VTU19JTkZPUk1BVElPTiBpbmZvICkKewogTFBET1NUQVNLIGxwRG9zVGFzayA9IE5VTEw7IC8qIGtlZXAgZ2NjIGZyb20gY29tcGxhaW5pbmcgKi8KIEhNT0RVTEUxNiBoTW9kdWxlOwogSElOU1RBTkNFMTYgaEluc3RhbmNlOwogUERCMzIgKnBkYiA9IFBST0NFU1NfQ3VycmVudCgpOwogVERCICpwVGFzayA9IChUREIqKUdsb2JhbExvY2sxNiggR2V0Q3VycmVudFRhc2soKSApOwogTkVfTU9EVUxFICpwTW9kdWxlID0gcFRhc2sgPyBORV9HZXRQdHIoIHBUYXNrLT5oTW9kdWxlICkgOiBOVUxMOwogSEZJTEUxNiBoRmlsZTsKIE9GU1RSVUNUIG9mczsKIGludCBlcnIsIGFsbG9jID0gIShwTW9kdWxlICYmIHBNb2R1bGUtPmRvc19pbWFnZSk7CgogR2xvYmFsVW5sb2NrMTYoIEdldEN1cnJlbnRUYXNrKCkgKTsKCiBpZiAoYWxsb2MgJiYgKGxwRG9zVGFzayA9IGNhbGxvYygxLCBzaXplb2YoRE9TVEFTSykpKSA9PSBOVUxMKQogIHJldHVybiAwOwoKIGlmICgoaEZpbGUgPSBPcGVuRmlsZTE2KCBuYW1lLCAmb2ZzLCBPRl9SRUFEICkpID09IEhGSUxFX0VSUk9SMTYpCiAgcmV0dXJuIDI7IC8qIEZpbGUgbm90IGZvdW5kICovCgogaWYgKCghZW52KSYmcGRiKSBlbnYgPSBwZGItPmVudl9kYi0+ZW52aXJvbjsKIGlmIChhbGxvYykgewogIGlmICgoaE1vZHVsZSA9IE1PRFVMRV9DcmVhdGVEdW1teU1vZHVsZSgmb2ZzLCBOVUxMKSkgPCAzMikKICAgcmV0dXJuIGhNb2R1bGU7CgogIGxwRG9zVGFzay0+aE1vZHVsZSA9IGhNb2R1bGU7CgogIHBNb2R1bGUgPSAoTkVfTU9EVUxFICopR2xvYmFsTG9jazE2KGhNb2R1bGUpOwogIHBNb2R1bGUtPmxwRG9zVGFzayA9IGxwRG9zVGFzazsKIAogIGxwRG9zVGFzay0+aW1nPU5VTEw7IGxwRG9zVGFzay0+bW1fbmFtZVswXT0wOyBscERvc1Rhc2stPm1tX2ZkPS0xOwogfSBlbHNlIGxwRG9zVGFzaz1wTW9kdWxlLT5scERvc1Rhc2s7CiBlcnIgPSBNWl9Mb2FkSW1hZ2UoIGhGaWxlLCBuYW1lLCBjbWRsaW5lLCBlbnYsIGxwRG9zVGFzaywgcE1vZHVsZSApOwogX2xjbG9zZTE2KGhGaWxlKTsKIGlmIChhbGxvYykgewogIHBNb2R1bGUtPmRvc19pbWFnZSA9IGxwRG9zVGFzay0+aW1nOwogIGlmIChlcnI8MzIpIHsKICAgaWYgKGxwRG9zVGFzay0+bW1fbmFtZVswXSE9MCkgewogICAgaWYgKGxwRG9zVGFzay0+aW1nIT1OVUxMKSBtdW5tYXAobHBEb3NUYXNrLT5pbWcsMHgxMTAwMDAtU1RBUlRfT0ZGU0VUKTsKICAgIGlmIChscERvc1Rhc2stPm1tX2ZkPj0wKSBjbG9zZShscERvc1Rhc2stPm1tX2ZkKTsKICAgIHVubGluayhscERvc1Rhc2stPm1tX25hbWUpOwogICB9IGVsc2UKICAgIGlmIChscERvc1Rhc2stPmltZyE9TlVMTCkgVmlydHVhbEZyZWUobHBEb3NUYXNrLT5pbWcsMHgxMTAwMDAsTUVNX1JFTEVBU0UpOwogICByZXR1cm4gZXJyOwogIH0KICBlcnIgPSBNWl9Jbml0VGFzayggbHBEb3NUYXNrICk7CiAgaWYgKGVycjwzMikgewogICBNWl9LaWxsTW9kdWxlKCBscERvc1Rhc2sgKTsKICAgLyogRklYTUU6IGNsZWFudXAgaE1vZHVsZSAqLwogICByZXR1cm4gZXJyOwogIH0KCiAgaEluc3RhbmNlID0gTkVfQ3JlYXRlSW5zdGFuY2UocE1vZHVsZSwgTlVMTCwgKGNtZGxpbmUgPT0gTlVMTCkpOwogIFBST0NFU1NfQ3JlYXRlKCBwTW9kdWxlLCBjbWRsaW5lLCBlbnYsIGhJbnN0YW5jZSwgMCwgaW5oZXJpdCwgc3RhcnR1cCwgaW5mbyApOwogIHJldHVybiBoSW5zdGFuY2U7CiB9IGVsc2UgewogIHJldHVybiAoZXJyPDMyKSA/IGVyciA6IHBUYXNrLT5oSW5zdGFuY2U7CiB9Cn0KCnZvaWQgTVpfS2lsbE1vZHVsZSggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIFRSQUNFKG1vZHVsZSwia2lsbGluZyBET1MgdGFza1xuIik7CiNpZiAwCiBTWVNURU1fS2lsbFN5c3RlbVRpbWVyKGxwRG9zVGFzay0+c3lzdGVtX3RpbWVyKTsKI2VuZGlmCiBpZiAobHBEb3NUYXNrLT5tbV9uYW1lWzBdIT0wKSB7CiAgbXVubWFwKGxwRG9zVGFzay0+aW1nLDB4MTEwMDAwLVNUQVJUX09GRlNFVCk7CiAgY2xvc2UobHBEb3NUYXNrLT5tbV9mZCk7CiB9IGVsc2UgVmlydHVhbEZyZWUobHBEb3NUYXNrLT5pbWcsMHgxMTAwMDAsTUVNX1JFTEVBU0UpOwogY2xvc2UobHBEb3NUYXNrLT5yZWFkX3BpcGUpOwogY2xvc2UobHBEb3NUYXNrLT53cml0ZV9waXBlKTsKIGtpbGwobHBEb3NUYXNrLT50YXNrLFNJR1RFUk0pOwojaWYgMAogLyogRklYTUU6IHRoaXMgc2VlbXMgdG8gY3Jhc2ggKi8KIGlmIChscERvc1Rhc2stPmRwbWlfc2VsKQogIFVuTWFwTFMoUFRSX1NFR19PRkZfVE9fU0VHUFRSKGxwRG9zVGFzay0+ZHBtaV9zZWwsMCkpOwojZW5kaWYKfQoKI2Vsc2UgLyogIU1aX1NVUFBPUlRFRCAqLwoKSElOU1RBTkNFMTYgTVpfQ3JlYXRlUHJvY2VzcyggTFBDU1RSIG5hbWUsIExQQ1NUUiBjbWRsaW5lLCBMUENTVFIgZW52LCBCT09MMzIgaW5oZXJpdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTVEFSVFVQSU5GTzMyQSBzdGFydHVwLCBMUFBST0NFU1NfSU5GT1JNQVRJT04gaW5mbyApCnsKIFdBUk4obW9kdWxlLCJET1MgZXhlY3V0YWJsZXMgbm90IHN1cHBvcnRlZCBvbiB0aGlzIGFyY2hpdGVjdHVyZVxuIik7CiByZXR1cm4gKEhNT0RVTEUxNikxMTsgIC8qIGludmFsaWQgZXhlICovCn0KCiNlbmRpZgo=