LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGNvZGUgaGFzbid0IGJlZW4gY29tcGxldGVseSBjbGVhbmVkIHVwIHlldC4KICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHNpZ25hbC5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxzeXMvdGltZS5oPgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIm1vZHVsZS5oIgojaW5jbHVkZSAibmVleGUuaCIKI2luY2x1ZGUgInRhc2suaCIKI2luY2x1ZGUgInNlbGVjdG9ycy5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAibGR0LmgiCiNpbmNsdWRlICJwcm9jZXNzLmgiCiNpbmNsdWRlICJtaXNjZW11LmgiCiNpbmNsdWRlICJkZWJ1Z3Rvb2xzLmgiCiNpbmNsdWRlICJkb3NleGUuaCIKI2luY2x1ZGUgImRvc21vZC5oIgojaW5jbHVkZSAib3B0aW9ucy5oIgojaW5jbHVkZSAidmdhLmgiCgpERUZBVUxUX0RFQlVHX0NIQU5ORUwobW9kdWxlKTsKCiNpZmRlZiBNWl9TVVBQT1JURUQKCiNpZmRlZiBIQVZFX1NZU19NTUFOX0gKIyBpbmNsdWRlIDxzeXMvbW1hbi5oPgojZW5kaWYKCi8qIGRlZmluZSB0aGlzIHRvIHRyeSBtYXBwaW5nIHRocm91Z2ggL3Byb2MvcGlkL21lbSBpbnN0ZWFkIG9mIGEgdGVtcCBmaWxlLAogICBidXQgTGludXMgZG9lc24ndCBsaWtlIG1tYXBwaW5nIC9wcm9jL3BpZC9tZW0sIHNvIGl0IGRvZXNuJ3Qgd29yayBmb3IgbWUgKi8KI3VuZGVmIE1aX01BUFNFTEYKCiNkZWZpbmUgQklPU19EQVRBX1NFR01FTlQgMHg0MAojZGVmaW5lIFNUQVJUX09GRlNFVCAwCiNkZWZpbmUgUFNQX1NJWkUgMHgxMAoKI2RlZmluZSBTRUcxNihwdHIsc2VnKSAoKExQVk9JRCkoKEJZVEUqKXB0cisoKERXT1JEKShzZWcpPDw0KSkpCiNkZWZpbmUgU0VHUFRSMTYocHRyLHNlZ3B0cikgKChMUFZPSUQpKChCWVRFKilwdHIrKChEV09SRClTRUxFQ1RPUk9GKHNlZ3B0cik8PDQpK09GRlNFVE9GKHNlZ3B0cikpKQoKc3RhdGljIExQRE9TVEFTSyBkb3NfY3VycmVudDsKCnN0YXRpYyB2b2lkIE1aX0xhdW5jaCh2b2lkKTsKCnN0YXRpYyB2b2lkIE1aX0NyZWF0ZVBTUCggTFBWT0lEIGxwUFNQLCBXT1JEIGVudiApCnsKIFBEQjE2KnBzcD1scFBTUDsKCiBwc3AtPmludDIwPTB4MjBDRDsgLyogaW50IDIwICovCiAvKiBzb21lIHByb2dyYW1zIHVzZSB0aGlzIHRvIGNhbGN1bGF0ZSBob3cgbXVjaCBtZW1vcnkgdGhleSBuZWVkICovCiBwc3AtPm5leHRQYXJhZ3JhcGg9MHg5RkZGOwogcHNwLT5lbnZpcm9ubWVudD1lbnY7CiAvKiBGSVhNRTogbW9yZSBQU1Agc3R1ZmYgKi8KfQoKc3RhdGljIHZvaWQgTVpfRmlsbFBTUCggTFBWT0lEIGxwUFNQLCBMUENTVFIgY21kbGluZSApCnsKIFBEQjE2KnBzcD1scFBTUDsKIGNvbnN0IGNoYXIqY21kPWNtZGxpbmU/c3RyY2hyKGNtZGxpbmUsJyAnKTpOVUxMOwoKIC8qIGNvcHkgcGFyYW1ldGVycyAqLwogaWYgKGNtZCkgewojaWYgMAogIC8qIGNvbW1hbmQuY29tIGRvZXNuJ3QgZG8gdGhpcyAqLwogIHdoaWxlICgqY21kID09ICcgJykgY21kKys7CiNlbmRpZgogIHBzcC0+Y21kTGluZVswXT1zdHJsZW4oY21kKTsKICBzdHJjcHkocHNwLT5jbWRMaW5lKzEsY21kKTsKICBwc3AtPmNtZExpbmVbcHNwLT5jbWRMaW5lWzBdKzFdPSdccic7CiB9IGVsc2UgcHNwLT5jbWRMaW5lWzFdPSdccic7CiAvKiBGSVhNRTogbW9yZSBQU1Agc3R1ZmYgKi8KfQoKLyogZGVmYXVsdCBJTlQgMDggaGFuZGxlcjogaW5jcmVhc2VzIHRpbWVyIHRpY2sgY291bnRlciBidXQgbm90IG11Y2ggbW9yZSAqLwpzdGF0aWMgY2hhciBpbnQwOFtdPXsKIDB4Q0QsMHgxQywgICAgICAgICAgIC8qIGludCAkMHgxYyAqLwogMHg1MCwgICAgICAgICAgICAgICAgLyogcHVzaHcgJWF4ICovCiAweDFFLCAgICAgICAgICAgICAgICAvKiBwdXNodyAlZHMgKi8KIDB4QjgsMHg0MCwweDAwLCAgICAgIC8qIG1vdncgJDB4NDAsJWF4ICovCiAweDhFLDB4RDgsICAgICAgICAgICAvKiBtb3Z3ICVheCwlZHMgKi8KI2lmIDAKIDB4ODMsMHgwNiwweDZDLDB4MDAsMHgwMSwgLyogYWRkdyAkMSwoMHg2YykgKi8KIDB4ODMsMHgxNiwweDZFLDB4MDAsMHgwMCwgLyogYWRjdyAkMCwoMHg2ZSkgKi8KI2Vsc2UKIDB4NjYsMHhGRiwweDA2LDB4NkMsMHgwMCwgLyogaW5jbCAoMHg2YykgKi8KI2VuZGlmCiAweEIwLDB4MjAsICAgICAgICAgICAvKiBtb3ZiICQweDIwLCVhbCAqLwogMHhFNiwweDIwLCAgICAgICAgICAgLyogb3V0YiAlYWwsJDB4MjAgKi8KIDB4MUYsICAgICAgICAgICAgICAgIC8qIHBvcHcgJWF4ICovCiAweDU4LCAgICAgICAgICAgICAgICAvKiBwb3B3ICVheCAqLwogMHhDRiAgICAgICAgICAgICAgICAgLyogaXJldCAqLwp9OwoKc3RhdGljIHZvaWQgTVpfSW5pdEhhbmRsZXJzKCBMUERPU1RBU0sgbHBEb3NUYXNrICkKewogV09SRCBzZWc7CiBMUEJZVEUgc3RhcnQ9RE9TTUVNX0dldEJsb2NrKHNpemVvZihpbnQwOCksJnNlZyk7CiBtZW1jcHkoc3RhcnQsaW50MDgsc2l6ZW9mKGludDA4KSk7Ci8qIElOVCAwODogcG9pbnQgaXQgYXQgb3VyIHRpY2staW5jcmVtZW50aW5nIGhhbmRsZXIgKi8KICgoU0VHUFRSKikobHBEb3NUYXNrLT5pbWcpKVsweDA4XT1QVFJfU0VHX09GRl9UT19TRUdQVFIoc2VnLDApOwovKiBJTlQgMUM6IGp1c3QgcG9pbnQgaXQgdG8gSVJFVCwgd2UgZG9uJ3Qgd2FudCB0byBoYW5kbGUgaXQgb3Vyc2VsdmVzICovCiAoKFNFR1BUUiopKGxwRG9zVGFzay0+aW1nKSlbMHgxQ109UFRSX1NFR19PRkZfVE9fU0VHUFRSKHNlZyxzaXplb2YoaW50MDgpLTEpOwp9CgpzdGF0aWMgY2hhciBlbnRlcl94bXNbXT17Ci8qIFhNUyBob29rYWJsZSBlbnRyeSBwb2ludCAqLwogMHhFQiwweDAzLCAgICAgICAgICAgLyogam1wIGVudHJ5ICovCiAweDkwLDB4OTAsMHg5MCwgICAgICAvKiBub3A7bm9wO25vcCAqLwogICAgICAgICAgICAgICAgICAgICAgLyogZW50cnk6ICovCi8qIHJlYWwgZW50cnkgcG9pbnQgKi8KLyogZm9yIHNpbXBsaWNpdHksIHdlJ2xsIGp1c3QgdXNlIHRoZSBzYW1lIGhvb2sgYXMgRFBNSSBiZWxvdyAqLwogMHhDRCwweDMxLCAgICAgICAgICAgLyogaW50ICQweDMxICovCiAweENCICAgICAgICAgICAgICAgICAvKiBscmV0ICovCn07CgpzdGF0aWMgdm9pZCBNWl9Jbml0WE1TKCBMUERPU1RBU0sgbHBEb3NUYXNrICkKewogTFBCWVRFIHN0YXJ0PURPU01FTV9HZXRCbG9jayhzaXplb2YoZW50ZXJfeG1zKSwmKGxwRG9zVGFzay0+eG1zX3NlZykpOwogbWVtY3B5KHN0YXJ0LGVudGVyX3htcyxzaXplb2YoZW50ZXJfeG1zKSk7Cn0KCnN0YXRpYyBjaGFyIGVudGVyX3BtW109ewogMHg1MCwgICAgICAgICAgICAgICAgLyogcHVzaHcgJWF4ICovCiAweDUyLCAgICAgICAgICAgICAgICAvKiBwdXNodyAlZHggKi8KIDB4NTUsICAgICAgICAgICAgICAgIC8qIHB1c2h3ICVicCAqLwogMHg4OSwweEU1LCAgICAgICAgICAgLyogbW92dyAlc3AsJWJwICovCi8qIGdldCByZXR1cm4gQ1MgKi8KIDB4OEIsMHg1NiwweDA4LCAgICAgIC8qIG1vdncgOCglYnApLCVkeCAqLwovKiBqdXN0IGNhbGwgaW50IDMxIGhlcmUgdG8gZ2V0IGludG8gcHJvdGVjdGVkIG1vZGUuLi4gKi8KLyogaXQnbGwgY2hlY2sgd2hldGhlciBpdCB3YXMgY2FsbGVkIGZyb20gZHBtaV9zZWcuLi4gKi8KIDB4Q0QsMHgzMSwgICAgICAgICAgIC8qIGludCAkMHgzMSAqLwovKiB3ZSBhcmUgbm93IGluIHRoZSBjb250ZXh0IG9mIGEgMTYtYml0IHJlbGF5IGNhbGwgKi8KLyogbmVlZCB0byBmaXh1cCBvdXIgc3RhY2s7CiAqIDE2LWJpdCByZWxheSByZXR1cm4gYWRkcmVzcyB3aWxsIGJlIGxvc3QsIGJ1dCB3ZSB3b24ndCB3b3JyeSBxdWl0ZSB5ZXQgKi8KIDB4OEUsMHhEMCwgICAgICAgICAgIC8qIG1vdncgJWF4LCVzcyAqLwogMHg2NiwweDBGLDB4QjcsMHhFNSwgLyogbW92endsICVicCwlZXNwICovCi8qIHNldCByZXR1cm4gQ1MgKi8KIDB4ODksMHg1NiwweDA4LCAgICAgIC8qIG1vdncgJWR4LDgoJWJwKSAqLwogMHg1RCwgICAgICAgICAgICAgICAgLyogcG9wdyAlYnAgKi8KIDB4NUEsICAgICAgICAgICAgICAgIC8qIHBvcHcgJWR4ICovCiAweDU4LCAgICAgICAgICAgICAgICAvKiBwb3B3ICVheCAqLwogMHhDQiAgICAgICAgICAgICAgICAgLyogbHJldCAqLwp9OwoKc3RhdGljIHZvaWQgTVpfSW5pdERQTUkoIExQRE9TVEFTSyBscERvc1Rhc2sgKQp7CiB1bnNpZ25lZCBzaXplPXNpemVvZihlbnRlcl9wbSk7CiBMUEJZVEUgc3RhcnQ9RE9TTUVNX0dldEJsb2NrKHNpemUsJihscERvc1Rhc2stPmRwbWlfc2VnKSk7CiAKIGxwRG9zVGFzay0+ZHBtaV9zZWwgPSBTRUxFQ1RPUl9BbGxvY0Jsb2NrKCBzdGFydCwgc2l6ZSwgU0VHTUVOVF9DT0RFLCBGQUxTRSwgRkFMU0UgKTsKCiBtZW1jcHkoc3RhcnQsZW50ZXJfcG0sc2l6ZW9mKGVudGVyX3BtKSk7Cn0KCnN0YXRpYyBXT1JEIE1aX0luaXRFbnZpcm9ubWVudCggTFBET1NUQVNLIGxwRG9zVGFzaywgTFBDU1RSIGVudiwgTFBDU1RSIG5hbWUgKQp7CiB1bnNpZ25lZCBzej0wOwogV09SRCBzZWc7CiBMUFNUUiBlbnZibGs7CgogaWYgKGVudikgewogIC8qIGdldCBzaXplIG9mIGVudmlyb25tZW50IGJsb2NrICovCiAgd2hpbGUgKGVudltzeisrXSkgc3orPXN0cmxlbihlbnYrc3opKzE7CiB9IGVsc2Ugc3orKzsKIC8qIGFsbG9jYXRlIGl0ICovCiBlbnZibGs9RE9TTUVNX0dldEJsb2NrKHN6K3NpemVvZihXT1JEKStzdHJsZW4obmFtZSkrMSwmc2VnKTsKIC8qIGZpbGwgaXQgKi8KIGlmIChlbnYpIHsKICBtZW1jcHkoZW52YmxrLGVudixzeik7CiB9IGVsc2UgZW52YmxrWzBdPTA7CiAvKiBET1MgMy54OiB0aGUgYmxvY2sgY29udGFpbnMgMSBhZGRpdGlvbmFsIHN0cmluZyAqLwogKihXT1JEKikoZW52YmxrK3N6KT0xOwogLyogYmVpbmcgdGhlIHByb2dyYW0gbmFtZSBpdHNlbGYgKi8KIHN0cmNweShlbnZibGsrc3orc2l6ZW9mKFdPUkQpLG5hbWUpOwogcmV0dXJuIHNlZzsKfQoKc3RhdGljIEJPT0wgTVpfSW5pdE1lbW9yeSggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIGlmIChscERvc1Rhc2stPmltZykgcmV0dXJuIFRSVUU7IC8qIGFscmVhZHkgYWxsb2NhdGVkICovCgogLyogYWxsb2NhdGUgMU1CKzY0SyBzaGFyZWQgbWVtb3J5ICovCiBscERvc1Rhc2stPmltZ19vZnM9U1RBUlRfT0ZGU0VUOwojaWZkZWYgTVpfTUFQU0VMRgogbHBEb3NUYXNrLT5pbWc9VmlydHVhbEFsbG9jKE5VTEwsMHgxMTAwMDAsTUVNX0NPTU1JVCxQQUdFX1JFQURXUklURSk7CiAvKiBtYWtlIHN1cmUgbW1hcCBhY2NlcHRzIGl0ICovCiAoKGNoYXIqKWxwRG9zVGFzay0+aW1nKVsweDEwRkZGRl09MDsKI2Vsc2UKIHRtcG5hbShscERvc1Rhc2stPm1tX25hbWUpOwovKiBzdHJjcHkobHBEb3NUYXNrLT5tbV9uYW1lLCIvdG1wL215ZG9zaW1hZ2UiKTsgKi8KIGxwRG9zVGFzay0+bW1fZmQ9b3BlbihscERvc1Rhc2stPm1tX25hbWUsT19SRFdSfE9fQ1JFQVQgLyogfE9fVFJVTkMgKi8sU19JUlVTUnxTX0lXVVNSKTsKIGlmIChscERvc1Rhc2stPm1tX2ZkPDApIEVSUigiZmlsZSAlcyBjb3VsZCBub3QgYmUgb3BlbmVkXG4iLGxwRG9zVGFzay0+bW1fbmFtZSk7CiAvKiBleHBhbmQgZmlsZSB0byAxTUIrNjRLICovCiBmdHJ1bmNhdGUobHBEb3NUYXNrLT5tbV9mZCwweDExMDAwMCk7CiAvKiBtYXAgaXQgaW4gKi8KIGxwRG9zVGFzay0+aW1nPW1tYXAoTlVMTCwweDExMDAwMC1TVEFSVF9PRkZTRVQsUFJPVF9SRUFEfFBST1RfV1JJVEUsTUFQX1NIQVJFRCxscERvc1Rhc2stPm1tX2ZkLDApOwojZW5kaWYKIGlmIChscERvc1Rhc2stPmltZz09KExQVk9JRCktMSkgewogIEVSUigiY291bGQgbm90IG1hcCBzaGFyZWQgbWVtb3J5LCBlcnJvcj0lc1xuIixzdHJlcnJvcihlcnJubykpOwogIHJldHVybiBGQUxTRTsKIH0KIFRSQUNFKCJET1MgVk04NiBpbWFnZSBtYXBwZWQgYXQgJTA4bHhcbiIsKERXT1JEKWxwRG9zVGFzay0+aW1nKTsKCiAvKiBpbml0aWFsaXplIHRoZSBtZW1vcnkgKi8KIFRSQUNFKCJJbml0aWFsaXppbmcgRE9TIG1lbW9yeSBzdHJ1Y3R1cmVzXG4iKTsKIERPU01FTV9Jbml0KFRSVUUpOwogTVpfSW5pdEhhbmRsZXJzKGxwRG9zVGFzayk7CiBNWl9Jbml0WE1TKGxwRG9zVGFzayk7CiBNWl9Jbml0RFBNSShscERvc1Rhc2spOwogcmV0dXJuIFRSVUU7Cn0KCkJPT0wgTVpfTG9hZEltYWdlKCBITU9EVUxFIG1vZHVsZSwgSEFORExFIGhGaWxlLCBMUENTVFIgZmlsZW5hbWUgKQp7CiAgTFBET1NUQVNLIGxwRG9zVGFzayA9IGRvc19jdXJyZW50OwogIElNQUdFX05UX0hFQURFUlMgKndpbl9oZHIgPSBQRV9IRUFERVIobW9kdWxlKTsKICBJTUFHRV9ET1NfSEVBREVSIG16X2hlYWRlcjsKICBEV09SRCBpbWFnZV9zdGFydCxpbWFnZV9zaXplLG1pbl9zaXplLG1heF9zaXplLGF2YWlsOwogIEJZVEUqcHNwX3N0YXJ0LCpsb2FkX3N0YXJ0OwogIGludCB4LCBvbGRfY29tPTAsIGFsbG9jPTA7CiAgU0VHUFRSIHJlbG9jOwogIFdPUkQgZW52X3NlZzsKICBEV09SRCBsZW47CgogIHdpbl9oZHItPk9wdGlvbmFsSGVhZGVyLlN1YnN5c3RlbSA9IElNQUdFX1NVQlNZU1RFTV9XSU5ET1dTX0NVSTsKICB3aW5faGRyLT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50ID0gKExQQllURSlNWl9MYXVuY2ggLSAoTFBCWVRFKW1vZHVsZTsKCiAgaWYgKCFscERvc1Rhc2spIHsKICAgIGFsbG9jPTE7CiAgICBscERvc1Rhc2sgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKERPU1RBU0spKTsKICAgIGxwRG9zVGFzay0+bW1fZmQgPSAtMTsKICAgIGRvc19jdXJyZW50ID0gbHBEb3NUYXNrOwogIH0KCiBTZXRGaWxlUG9pbnRlcihoRmlsZSwwLE5VTEwsRklMRV9CRUdJTik7CiBpZiAoICAgIVJlYWRGaWxlKGhGaWxlLCZtel9oZWFkZXIsc2l6ZW9mKG16X2hlYWRlciksJmxlbixOVUxMKQogICAgIHx8IGxlbiAhPSBzaXplb2YobXpfaGVhZGVyKSAKICAgICB8fCBtel9oZWFkZXIuZV9tYWdpYyAhPSBJTUFHRV9ET1NfU0lHTkFUVVJFKSB7CiAgb2xkX2NvbT0xOyAvKiBhc3N1bWUgLkNPTSBmaWxlICovCiAgaW1hZ2Vfc3RhcnQ9MDsKICBpbWFnZV9zaXplPUdldEZpbGVTaXplKGhGaWxlLE5VTEwpOwogIG1pbl9zaXplPTB4MTAwMDA7IG1heF9zaXplPTB4MTAwMDAwOwogIG16X2hlYWRlci5lX2NybGM9MDsKICBtel9oZWFkZXIuZV9zcz0wOyBtel9oZWFkZXIuZV9zcD0weEZGRkU7CiAgbXpfaGVhZGVyLmVfY3M9MDsgbXpfaGVhZGVyLmVfaXA9MHgxMDA7CiB9IGVsc2UgewogIC8qIGNhbGN1bGF0ZSBsb2FkIHNpemUgKi8KICBpbWFnZV9zdGFydD1tel9oZWFkZXIuZV9jcGFyaGRyPDw0OwogIGltYWdlX3NpemU9bXpfaGVhZGVyLmVfY3A8PDk7IC8qIHBhZ2VzIGFyZSA1MTIgYnl0ZXMgKi8KICBpZiAoKG16X2hlYWRlci5lX2NibHAhPTApJiYobXpfaGVhZGVyLmVfY2JscCE9NCkpIGltYWdlX3NpemUtPTUxMi1tel9oZWFkZXIuZV9jYmxwOwogIGltYWdlX3NpemUtPWltYWdlX3N0YXJ0OwogIG1pbl9zaXplPWltYWdlX3NpemUrKChEV09SRCltel9oZWFkZXIuZV9taW5hbGxvYzw8NCkrKFBTUF9TSVpFPDw0KTsKICBtYXhfc2l6ZT1pbWFnZV9zaXplKygoRFdPUkQpbXpfaGVhZGVyLmVfbWF4YWxsb2M8PDQpKyhQU1BfU0laRTw8NCk7CiB9CgogTVpfSW5pdE1lbW9yeShscERvc1Rhc2spOwoKIC8qIGFsbG9jYXRlIGVudmlyb25tZW50IGJsb2NrICovCiBlbnZfc2VnPU1aX0luaXRFbnZpcm9ubWVudChscERvc1Rhc2ssR2V0RW52aXJvbm1lbnRTdHJpbmdzQSgpLGZpbGVuYW1lKTsKCiAvKiBhbGxvY2F0ZSBtZW1vcnkgZm9yIHRoZSBleGVjdXRhYmxlICovCiBUUkFDRSgiQWxsb2NhdGluZyBET1MgbWVtb3J5IChtaW49JWxkLCBtYXg9JWxkKVxuIixtaW5fc2l6ZSxtYXhfc2l6ZSk7CiBhdmFpbD1ET1NNRU1fQXZhaWxhYmxlKCk7CiBpZiAoYXZhaWw8bWluX3NpemUpIHsKICBFUlIoImluc3VmZmljaWVudCBET1MgbWVtb3J5XG4iKTsKICBTZXRMYXN0RXJyb3IoRVJST1JfTk9UX0VOT1VHSF9NRU1PUlkpOwogIGdvdG8gbG9hZF9lcnJvcjsKIH0KIGlmIChhdmFpbD5tYXhfc2l6ZSkgYXZhaWw9bWF4X3NpemU7CiBwc3Bfc3RhcnQ9RE9TTUVNX0dldEJsb2NrKGF2YWlsLCZscERvc1Rhc2stPnBzcF9zZWcpOwogaWYgKCFwc3Bfc3RhcnQpIHsKICBFUlIoImVycm9yIGFsbG9jYXRpbmcgRE9TIG1lbW9yeVxuIik7CiAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZKTsKICBnb3RvIGxvYWRfZXJyb3I7CiB9CiBscERvc1Rhc2stPmxvYWRfc2VnPWxwRG9zVGFzay0+cHNwX3NlZysob2xkX2NvbT8wOlBTUF9TSVpFKTsKIGxvYWRfc3RhcnQ9cHNwX3N0YXJ0KyhQU1BfU0laRTw8NCk7CiBNWl9DcmVhdGVQU1AocHNwX3N0YXJ0LCBlbnZfc2VnKTsKCiAvKiBsb2FkIGV4ZWN1dGFibGUgaW1hZ2UgKi8KIFRSQUNFKCJsb2FkaW5nIERPUyAlcyBpbWFnZSwgJTA4bHggYnl0ZXNcbiIsb2xkX2NvbT8iQ09NIjoiRVhFIixpbWFnZV9zaXplKTsKIFNldEZpbGVQb2ludGVyKGhGaWxlLGltYWdlX3N0YXJ0LE5VTEwsRklMRV9CRUdJTik7CiBpZiAoIVJlYWRGaWxlKGhGaWxlLGxvYWRfc3RhcnQsaW1hZ2Vfc2l6ZSwmbGVuLE5VTEwpIHx8IGxlbiAhPSBpbWFnZV9zaXplKSB7CiAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogIGdvdG8gbG9hZF9lcnJvcjsKIH0KCiBpZiAobXpfaGVhZGVyLmVfY3JsYykgewogIC8qIGxvYWQgcmVsb2NhdGlvbiB0YWJsZSAqLwogIFRSQUNFKCJsb2FkaW5nIERPUyBFWEUgcmVsb2NhdGlvbiB0YWJsZSwgJWQgZW50cmllc1xuIixtel9oZWFkZXIuZV9jcmxjKTsKICAvKiBGSVhNRTogaXMgdGhpcyB0b28gc2xvdyB3aXRob3V0IHJlYWQgYnVmZmVyaW5nPyAqLwogIFNldEZpbGVQb2ludGVyKGhGaWxlLG16X2hlYWRlci5lX2xmYXJsYyxOVUxMLEZJTEVfQkVHSU4pOwogIGZvciAoeD0wOyB4PG16X2hlYWRlci5lX2NybGM7IHgrKykgewogICBpZiAoIVJlYWRGaWxlKGhGaWxlLCZyZWxvYyxzaXplb2YocmVsb2MpLCZsZW4sTlVMTCkgfHwgbGVuICE9IHNpemVvZihyZWxvYykpIHsKICAgIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKICAgIGdvdG8gbG9hZF9lcnJvcjsKICAgfQogICAqKFdPUkQqKVNFR1BUUjE2KGxvYWRfc3RhcnQscmVsb2MpKz1scERvc1Rhc2stPmxvYWRfc2VnOwogIH0KIH0KCiBscERvc1Rhc2stPmluaXRfY3M9bHBEb3NUYXNrLT5sb2FkX3NlZyttel9oZWFkZXIuZV9jczsKIGxwRG9zVGFzay0+aW5pdF9pcD1tel9oZWFkZXIuZV9pcDsKIGxwRG9zVGFzay0+aW5pdF9zcz1scERvc1Rhc2stPmxvYWRfc2VnK216X2hlYWRlci5lX3NzOwogbHBEb3NUYXNrLT5pbml0X3NwPW16X2hlYWRlci5lX3NwOwoKICBUUkFDRSgiZW50cnkgcG9pbnQ6ICUwNHg6JTA0eFxuIixscERvc1Rhc2stPmluaXRfY3MsbHBEb3NUYXNrLT5pbml0X2lwKTsKCiAgaWYgKCFNWl9Jbml0VGFzayhscERvc1Rhc2spKSB7CiAgICBNWl9LaWxsVGFzayhscERvc1Rhc2spOwogICAgU2V0TGFzdEVycm9yKEVSUk9SX0dFTl9GQUlMVVJFKTsKICAgIHJldHVybiBGQUxTRTsKICB9CgogIHJldHVybiBUUlVFOwoKbG9hZF9lcnJvcjoKICBpZiAoYWxsb2MpIHsKICAgIGRvc19jdXJyZW50ID0gTlVMTDsKICAgIGlmIChscERvc1Rhc2stPm1tX25hbWVbMF0hPTApIHsKICAgICAgaWYgKGxwRG9zVGFzay0+aW1nIT1OVUxMKSBtdW5tYXAobHBEb3NUYXNrLT5pbWcsMHgxMTAwMDAtU1RBUlRfT0ZGU0VUKTsKICAgICAgaWYgKGxwRG9zVGFzay0+bW1fZmQ+PTApIGNsb3NlKGxwRG9zVGFzay0+bW1fZmQpOwogICAgICB1bmxpbmsobHBEb3NUYXNrLT5tbV9uYW1lKTsKICAgIH0gZWxzZQogICAgICBpZiAobHBEb3NUYXNrLT5pbWchPU5VTEwpIFZpcnR1YWxGcmVlKGxwRG9zVGFzay0+aW1nLDB4MTEwMDAwLE1FTV9SRUxFQVNFKTsKICB9CgogIHJldHVybiBGQUxTRTsKfQoKTFBET1NUQVNLIE1aX0FsbG9jRFBNSVRhc2soIHZvaWQgKQp7CiAgTFBET1NUQVNLIGxwRG9zVGFzayA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoRE9TVEFTSykpOwoKICBpZiAobHBEb3NUYXNrKSB7CiAgICBscERvc1Rhc2stPm1tX2ZkID0gLTE7CiAgICBkb3NfY3VycmVudCA9IGxwRG9zVGFzazsKICAgIE1aX0luaXRNZW1vcnkobHBEb3NUYXNrKTsKICB9CiAgcmV0dXJuIGxwRG9zVGFzazsKfQoKc3RhdGljIHZvaWQgTVpfSW5pdFRpbWVyKCBMUERPU1RBU0sgbHBEb3NUYXNrLCBpbnQgdmVyICkKewogaWYgKHZlcjwxKSB7CiAgLyogY2FuJ3QgbWFrZSB0aW1lciB0aWNrcyAqLwogfSBlbHNlIHsKICBpbnQgZnVuYzsKICBzdHJ1Y3QgdGltZXZhbCB0aW07CgogIC8qIHN0YXJ0IGRvc21vZCB0aW1lciBhdCA1NW1zICgxOC4ySHopICovCiAgZnVuYz1ET1NNT0RfU0VUX1RJTUVSOwogIHRpbS50dl9zZWM9MDsgdGltLnR2X3VzZWM9NTQ5MjU7CiAgd3JpdGUobHBEb3NUYXNrLT53cml0ZV9waXBlLCZmdW5jLHNpemVvZihmdW5jKSk7CiAgd3JpdGUobHBEb3NUYXNrLT53cml0ZV9waXBlLCZ0aW0sc2l6ZW9mKHRpbSkpOwogfQp9CgpCT09MIE1aX0luaXRUYXNrKCBMUERPU1RBU0sgbHBEb3NUYXNrICkKewogIGludCB3cml0ZV9mZFsyXSx4X2ZkOwogIHBpZF90IGNoaWxkOwogIGNoYXIgKmZuYW1lLCpmYXJnLGFyZ1sxNl0sZnByb2NbNjRdLHBhdGhbMjU2XSwqZnBhdGg7CgogIGlmICghbHBEb3NUYXNrKSByZXR1cm4gRkFMU0U7CiAgLyogY3JlYXRlIHBpcGVzICovCiAgaWYgKCFDcmVhdGVQaXBlKCYobHBEb3NUYXNrLT5oUmVhZFBpcGUpLCYobHBEb3NUYXNrLT5oWFBpcGUpLE5VTEwsMCkpIHJldHVybiBGQUxTRTsKICBpZiAocGlwZSh3cml0ZV9mZCk8MCkgewogICAgQ2xvc2VIYW5kbGUobHBEb3NUYXNrLT5oUmVhZFBpcGUpOwogICAgQ2xvc2VIYW5kbGUobHBEb3NUYXNrLT5oWFBpcGUpOwogICAgcmV0dXJuIEZBTFNFOwogIH0KCiAgbHBEb3NUYXNrLT5yZWFkX3BpcGUgPSBGSUxFX0dldFVuaXhIYW5kbGUoIGxwRG9zVGFzay0+aFJlYWRQaXBlLCBHRU5FUklDX1JFQUQgKTsKICB4X2ZkID0gRklMRV9HZXRVbml4SGFuZGxlKCBscERvc1Rhc2stPmhYUGlwZSwgR0VORVJJQ19XUklURSApOwoKICBUUkFDRSgid2luMzIgcGlwZTogcmVhZD0lZCwgd3JpdGU9JWQsIHVuaXggcGlwZTogcmVhZD0lZCwgd3JpdGU9JWRcbiIsCgkgICAgICAgbHBEb3NUYXNrLT5oUmVhZFBpcGUsbHBEb3NUYXNrLT5oWFBpcGUsbHBEb3NUYXNrLT5yZWFkX3BpcGUseF9mZCk7CiAgVFJBQ0UoIm91dGJvdW5kIHVuaXggcGlwZTogcmVhZD0lZCwgd3JpdGU9JWQsIHBpZD0lZFxuIix3cml0ZV9mZFswXSx3cml0ZV9mZFsxXSxnZXRwaWQoKSk7CgogIGxwRG9zVGFzay0+d3JpdGVfcGlwZT13cml0ZV9mZFsxXTsKCiAgbHBEb3NUYXNrLT5oQ29uSW5wdXQ9R2V0U3RkSGFuZGxlKFNURF9JTlBVVF9IQU5ETEUpOwogIGxwRG9zVGFzay0+aENvbk91dHB1dD1HZXRTdGRIYW5kbGUoU1REX09VVFBVVF9IQU5ETEUpOwoKICAvKiBpZiB3ZSBoYXZlIGEgbWFwcGluZyBmaWxlLCB1c2UgaXQgKi8KICBmbmFtZT1scERvc1Rhc2stPm1tX25hbWU7IGZhcmc9TlVMTDsKICBpZiAoIWZuYW1lWzBdKSB7CiAgICAvKiBvdGhlcndpc2UsIG1hcCBvdXIgb3duIG1lbW9yeSBpbWFnZSAqLwogICAgc3ByaW50ZihmcHJvYywiL3Byb2MvJWQvbWVtIixnZXRwaWQoKSk7CiAgICBzcHJpbnRmKGFyZywiJWxkIiwodW5zaWduZWQgbG9uZylscERvc1Rhc2stPmltZyk7CiAgICBmbmFtZT1mcHJvYzsgZmFyZz1hcmc7CiAgfQoKICBUUkFDRSgiTG9hZGluZyBET1MgVk0gc3VwcG9ydCBtb2R1bGVcbiIpOwogIGlmICgoY2hpbGQ9Zm9yaygpKTwwKSB7CiAgICBjbG9zZSh3cml0ZV9mZFswXSk7CiAgICBjbG9zZShscERvc1Rhc2stPnJlYWRfcGlwZSk7CiAgICBjbG9zZShscERvc1Rhc2stPndyaXRlX3BpcGUpOwogICAgY2xvc2UoeF9mZCk7CiAgICBDbG9zZUhhbmRsZShscERvc1Rhc2stPmhSZWFkUGlwZSk7CiAgICBDbG9zZUhhbmRsZShscERvc1Rhc2stPmhYUGlwZSk7CiAgICByZXR1cm4gRkFMU0U7CiAgfQogaWYgKGNoaWxkIT0wKSB7CiAgLyogcGFyZW50IHByb2Nlc3MgKi8KICBpbnQgcmV0OwoKICBjbG9zZSh3cml0ZV9mZFswXSk7CiAgY2xvc2UoeF9mZCk7CiAgbHBEb3NUYXNrLT50YXNrPWNoaWxkOwogIC8qIHdhaXQgZm9yIGNoaWxkIHByb2Nlc3MgdG8gc2lnbmFsIHJlYWRpbmVzcyAqLwogIHdoaWxlICgxKSB7CiAgICBpZiAocmVhZChscERvc1Rhc2stPnJlYWRfcGlwZSwmcmV0LHNpemVvZihyZXQpKT09c2l6ZW9mKHJldCkpIGJyZWFrOwogICAgaWYgKChlcnJubz09RUlOVFIpfHwoZXJybm89PUVBR0FJTikpIGNvbnRpbnVlOwogICAgLyogZmFpbHVyZSAqLwogICAgRVJSKCJkb3Ntb2QgaGFzIGZhaWxlZCB0byBpbml0aWFsaXplXG4iKTsKICAgIGlmIChscERvc1Rhc2stPm1tX25hbWVbMF0hPTApIHVubGluayhscERvc1Rhc2stPm1tX25hbWUpOwogICAgcmV0dXJuIEZBTFNFOwogIH0KICAvKiB0aGUgY2hpbGQgaGFzIG5vdyBtbWFwZWQgdGhlIHRlbXAgZmlsZSwgaXQncyBub3cgc2FmZSB0byB1bmxpbmsuCiAgICogZG8gaXQgaGVyZSB0byBhdm9pZCBsZWF2aW5nIGEgbWVzcyBpbiAvdG1wIGlmL3doZW4gV2luZSBjcmFzaGVzLi4uICovCiAgaWYgKGxwRG9zVGFzay0+bW1fbmFtZVswXSE9MCkgdW5saW5rKGxwRG9zVGFzay0+bW1fbmFtZSk7CiAgLyogc3RhcnQgc2ltdWxhdGVkIHN5c3RlbSB0aW1lciAqLwogIE1aX0luaXRUaW1lcihscERvc1Rhc2sscmV0KTsKICBpZiAocmV0PDIpIHsKICAgIEVSUigiZG9zbW9kIHZlcnNpb24gdG9vIG9sZCEgUGxlYXNlIGluc3RhbGwgbmV3ZXIgZG9zbW9kIHByb3Blcmx5XG4iKTsKICAgIEVSUigiSWYgeW91IGRvbid0LCB0aGUgbmV3IGRvc21vZCBldmVudCBoYW5kbGluZyBzeXN0ZW0gd2lsbCBub3Qgd29ya1xuIik7CiAgfQogIC8qIGFsbCBzeXN0ZW1zIGFyZSBub3cgZ28gKi8KIH0gZWxzZSB7CiAgLyogY2hpbGQgcHJvY2VzcyAqLwogIGNsb3NlKGxwRG9zVGFzay0+cmVhZF9waXBlKTsKICBjbG9zZShscERvc1Rhc2stPndyaXRlX3BpcGUpOwogIC8qIHB1dCBvdXIgcGlwZXMgc29tZXdoZXJlIGRvc21vZCBjYW4gZmluZCB0aGVtICovCiAgZHVwMih3cml0ZV9mZFswXSwwKTsgLyogc3RkaW4gKi8KICBkdXAyKHhfZmQsMSk7ICAgICAgICAvKiBzdGRvdXQgKi8KICAvKiBub3cgbG9hZCBkb3Ntb2QgKi8KICAvKiBjaGVjayBhcmd2WzBdLWRlcml2ZWQgcGF0aHMgZmlyc3QsIHNpbmNlIHRoZSBuZXdlc3QgZG9zbW9kIGlzIG1vc3QgbGlrZWx5IHRoZXJlCiAgICogKGF0IGxlYXN0IGl0IHdhcyBvbmNlIGZvciBBbmRyZWFzIE1vaHIsIHNvIEkgZGVjaWRlZCB0byBtYWtlIGl0IGVhc2llciBmb3IgaGltKSAqLwogIGZwYXRoPXN0cnJjaHIoc3RyY3B5KHBhdGgsZnVsbF9hcmd2MCksJy8nKTsKICBpZiAoZnBhdGgpIHsKICAgc3RyY3B5KGZwYXRoLCIvZG9zbW9kIik7CiAgIGV4ZWNsKHBhdGgsZm5hbWUsZmFyZyxOVUxMKTsKICAgc3RyY3B5KGZwYXRoLCIvbG9hZGVyL2Rvcy9kb3Ntb2QiKTsKICAgZXhlY2wocGF0aCxmbmFtZSxmYXJnLE5VTEwpOwogIH0KICAvKiBva2F5LCBpdCB3YXNuJ3QgdGhlcmUsIHRyeSBpbiB0aGUgcGF0aCAqLwogIGV4ZWNscCgiZG9zbW9kIixmbmFtZSxmYXJnLE5VTEwpOwogIC8qIGxhc3QgZGVzcGVyYXRlIGF0dGVtcHRzOiBjdXJyZW50IGRpcmVjdG9yeSAqLwogIGV4ZWNsKCJkb3Ntb2QiLGZuYW1lLGZhcmcsTlVMTCk7CiAgLyogYW5kLCBqdXN0IGZvciBjb21wbGV0ZW5lc3MuLi4gKi8KICBleGVjbCgibG9hZGVyL2Rvcy9kb3Ntb2QiLGZuYW1lLGZhcmcsTlVMTCk7CiAgLyogaWYgZmFpbHVyZSwgZXhpdCAqLwogIEVSUigiRmFpbGVkIHRvIHNwYXduIGRvc21vZCwgZXJyb3I9JXNcbiIsc3RyZXJyb3IoZXJybm8pKTsKICBleGl0KDEpOwogfQogcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyB2b2lkIE1aX0xhdW5jaCh2b2lkKQp7CiAgTFBET1NUQVNLIGxwRG9zVGFzayA9IE1aX0N1cnJlbnQoKTsKICBCWVRFICpwc3Bfc3RhcnQgPSAoQllURSopbHBEb3NUYXNrLT5pbWcgKyAoKERXT1JEKWxwRG9zVGFzay0+cHNwX3NlZyA8PCA0KTsKCiAgTVpfRmlsbFBTUChwc3Bfc3RhcnQsIEdldENvbW1hbmRMaW5lQSgpKTsKCiAgRE9TVk1fRW50ZXIoTlVMTCk7Cn0KCnZvaWQgTVpfS2lsbFRhc2soIExQRE9TVEFTSyBscERvc1Rhc2sgKQp7CiAgRE9TRVZFTlQgKmV2ZW50LCpwX2V2ZW50OwogIERPU1NZU1RFTSAqc3lzLCpwX3N5czsKCiAgVFJBQ0UoImtpbGxpbmcgRE9TIHRhc2tcbiIpOwogIFZHQV9DbGVhbigpOwogIGlmIChscERvc1Rhc2stPm1tX25hbWVbMF0hPTApIHsKICAgIG11bm1hcChscERvc1Rhc2stPmltZywweDExMDAwMC1TVEFSVF9PRkZTRVQpOwogICAgY2xvc2UobHBEb3NUYXNrLT5tbV9mZCk7CiAgfSBlbHNlIFZpcnR1YWxGcmVlKGxwRG9zVGFzay0+aW1nLDB4MTEwMDAwLE1FTV9SRUxFQVNFKTsKICBjbG9zZShscERvc1Rhc2stPnJlYWRfcGlwZSk7CiAgY2xvc2UobHBEb3NUYXNrLT53cml0ZV9waXBlKTsKICBDbG9zZUhhbmRsZShscERvc1Rhc2stPmhSZWFkUGlwZSk7CiAgQ2xvc2VIYW5kbGUobHBEb3NUYXNrLT5oWFBpcGUpOwogIGtpbGwobHBEb3NUYXNrLT50YXNrLFNJR1RFUk0pOwovKiBmcmVlIG1lbW9yeSBhbGxvY2F0ZWQgZm9yIGV2ZW50cyBhbmQgc3lzdGVtcyAqLwojZGVmaW5lIERGUkVFKHZhcixwdmFyLHN2YXIpIFwKICB2YXIgPSBscERvc1Rhc2stPnN2YXI7IFwKICB3aGlsZSAodmFyKSB7IFwKICAgIGlmICh2YXItPmRhdGEpIGZyZWUodmFyLT5kYXRhKTsgXAogICAgcHZhciA9IHZhci0+bmV4dDsgZnJlZSh2YXIpOyB2YXIgPSBwdmFyOyBcCiAgfQoKICBERlJFRShldmVudCxwX2V2ZW50LHBlbmRpbmcpCiAgREZSRUUoZXZlbnQscF9ldmVudCxjdXJyZW50KQogIERGUkVFKHN5cyxwX3N5cyxzeXMpCgojdW5kZWYgREZSRUUKCiNpZiAwCiAgLyogRklYTUU6IHRoaXMgc2VlbXMgdG8gY3Jhc2ggKi8KICBpZiAobHBEb3NUYXNrLT5kcG1pX3NlbCkKICAgIFNFTEVDVE9SX0ZyZWVCbG9jayhscERvc1Rhc2stPmRwbWlfc2VsLCAxKTsKI2VuZGlmCn0KCkxQRE9TVEFTSyBNWl9DdXJyZW50KCB2b2lkICkKewogIHJldHVybiBkb3NfY3VycmVudDsKfQoKI2Vsc2UgLyogIU1aX1NVUFBPUlRFRCAqLwoKQk9PTCBNWl9Mb2FkSW1hZ2UoIEhNT0RVTEUgbW9kdWxlLCBIQU5ETEUgaEZpbGUsIExQQ1NUUiBmaWxlbmFtZSApCnsKIFdBUk4oIkRPUyBleGVjdXRhYmxlcyBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgYXJjaGl0ZWN0dXJlXG4iKTsKIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKIHJldHVybiBGQUxTRTsKfQoKTFBET1NUQVNLIE1aX0N1cnJlbnQoIHZvaWQgKQp7CiAgcmV0dXJuIE5VTEw7Cn0KCiNlbmRpZgo=