LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGNvZGUgaGFzbid0IGJlZW4gY29tcGxldGVseSBjbGVhbmVkIHVwIHlldC4KICovCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHNpZ25hbC5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxzeXMvdGltZS5oPgojaW5jbHVkZSAid2luZG93cy5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAibW9kdWxlLmgiCiNpbmNsdWRlICJ0YXNrLmgiCiNpbmNsdWRlICJzZWxlY3RvcnMuaCIKI2luY2x1ZGUgImZpbGUuaCIKI2luY2x1ZGUgImxkdC5oIgojaW5jbHVkZSAicHJvY2Vzcy5oIgojaW5jbHVkZSAibWlzY2VtdS5oIgojaW5jbHVkZSAiZGVidWcuaCIKI2luY2x1ZGUgImRvc2V4ZS5oIgojaW5jbHVkZSAiZG9zbW9kLmgiCiNpbmNsdWRlICJvcHRpb25zLmgiCgojaWZkZWYgTVpfU1VQUE9SVEVECgojaW5jbHVkZSA8c3lzL21tYW4uaD4KCi8qIGRlZmluZSB0aGlzIHRvIHRyeSBtYXBwaW5nIHRocm91Z2ggL3Byb2MvcGlkL21lbSBpbnN0ZWFkIG9mIGEgdGVtcCBmaWxlLAogICBidXQgTGludXMgZG9lc24ndCBsaWtlIG1tYXBwaW5nIC9wcm9jL3BpZC9tZW0sIHNvIGl0IGRvZXNuJ3Qgd29yayBmb3IgbWUgKi8KI3VuZGVmIE1aX01BUFNFTEYKCiNkZWZpbmUgQklPU19EQVRBX1NFR01FTlQgMHg0MAojZGVmaW5lIFNUQVJUX09GRlNFVCAwCiNkZWZpbmUgUFNQX1NJWkUgMHgxMAoKI2RlZmluZSBTRUcxNihwdHIsc2VnKSAoKExQVk9JRCkoKEJZVEUqKXB0cisoKERXT1JEKShzZWcpPDw0KSkpCiNkZWZpbmUgU0VHUFRSMTYocHRyLHNlZ3B0cikgKChMUFZPSUQpKChCWVRFKilwdHIrKChEV09SRClTRUxFQ1RPUk9GKHNlZ3B0cik8PDQpK09GRlNFVE9GKHNlZ3B0cikpKQoKZXh0ZXJuIFdPUkQgV0lOQVBJIFNZU1RFTV9LaWxsU3lzdGVtVGltZXIoIFdPUkQgdGltZXIgKTsKCnN0YXRpYyB2b2lkIE1aX0luaXRQU1AoIExQVk9JRCBscFBTUCwgTFBDU1RSIGNtZGxpbmUsIFdPUkQgZW52ICkKewogUERCKnBzcD1scFBTUDsKIGNvbnN0IGNoYXIqY21kPWNtZGxpbmU/c3RyY2hyKGNtZGxpbmUsJyAnKTpOVUxMOwoKIHBzcC0+aW50MjA9MHgyMENEOyAvKiBpbnQgMjAgKi8KIC8qIHNvbWUgcHJvZ3JhbXMgdXNlIHRoaXMgdG8gY2FsY3VsYXRlIGhvdyBtdWNoIG1lbW9yeSB0aGV5IG5lZWQgKi8KIHBzcC0+bmV4dFBhcmFncmFwaD0weDlGRkY7CiBwc3AtPmVudmlyb25tZW50PWVudjsKIC8qIGNvcHkgcGFyYW1ldGVycyAqLwogaWYgKGNtZCkgewojaWYgMAogIC8qIGNvbW1hbmQuY29tIGRvZXNuJ3QgZG8gdGhpcyAqLwogIHdoaWxlICgqY21kID09ICcgJykgY21kKys7CiNlbmRpZgogIHBzcC0+Y21kTGluZVswXT1zdHJsZW4oY21kKTsKICBzdHJjcHkocHNwLT5jbWRMaW5lKzEsY21kKTsKICBwc3AtPmNtZExpbmVbcHNwLT5jbWRMaW5lWzBdKzFdPSdccic7CiB9IGVsc2UgcHNwLT5jbWRMaW5lWzFdPSdccic7CiAvKiBGSVhNRTogaW50ZWdyYXRlIHRoZSBtZW1vcnkgc3R1ZmYgZnJvbSBXaW5lIChtc2Rvcy9kb3NtZW0uYykgKi8KIC8qIEZJWE1FOiBpbnRlZ3JhdGUgdGhlIFBEQiBzdHVmZiBmcm9tIFdpbmUgKGxvYWRlci90YXNrLmMpICovCn0KCi8qIGRlZmF1bHQgSU5UIDA4IGhhbmRsZXI6IGluY3JlYXNlcyB0aW1lciB0aWNrIGNvdW50ZXIgYnV0IG5vdCBtdWNoIG1vcmUgKi8Kc3RhdGljIGNoYXIgaW50MDhbXT17CiAweENELDB4MUMsICAgICAgICAgICAvKiBpbnQgJDB4MWMgKi8KIDB4NTAsICAgICAgICAgICAgICAgIC8qIHB1c2h3ICVheCAqLwogMHgxRSwgICAgICAgICAgICAgICAgLyogcHVzaHcgJWRzICovCiAweEI4LDB4NDAsMHgwMCwgICAgICAvKiBtb3Z3ICQweDQwLCVheCAqLwogMHg4RSwweEQ4LCAgICAgICAgICAgLyogbW92dyAlYXgsJWRzICovCiNpZiAwCiAweDgzLDB4MDYsMHg2QywweDAwLDB4MDEsIC8qIGFkZHcgJDEsKDB4NmMpICovCiAweDgzLDB4MTYsMHg2RSwweDAwLDB4MDAsIC8qIGFkY3cgJDAsKDB4NmUpICovCiNlbHNlCiAweDY2LDB4RkYsMHgwNiwweDZDLDB4MDAsIC8qIGluY2wgKDB4NmMpICovCiNlbmRpZgogMHhCMCwweDIwLCAgICAgICAgICAgLyogbW92YiAkMHgyMCwlYWwgKi8KIDB4RTYsMHgyMCwgICAgICAgICAgIC8qIG91dGIgJWFsLCQweDIwICovCiAweDFGLCAgICAgICAgICAgICAgICAvKiBwb3B3ICVheCAqLwogMHg1OCwgICAgICAgICAgICAgICAgLyogcG9wdyAlYXggKi8KIDB4Q0YgICAgICAgICAgICAgICAgIC8qIGlyZXQgKi8KfTsKCnN0YXRpYyB2b2lkIE1aX0luaXRIYW5kbGVycyggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIFdPUkQgc2VnOwogTFBCWVRFIHN0YXJ0PURPU01FTV9HZXRCbG9jayhscERvc1Rhc2stPmhNb2R1bGUsc2l6ZW9mKGludDA4KSwmc2VnKTsKIG1lbWNweShzdGFydCxpbnQwOCxzaXplb2YoaW50MDgpKTsKLyogSU5UIDA4OiBwb2ludCBpdCBhdCBvdXIgdGljay1pbmNyZW1lbnRpbmcgaGFuZGxlciAqLwogKChTRUdQVFIqKShscERvc1Rhc2stPmltZykpWzB4MDhdPVBUUl9TRUdfT0ZGX1RPX1NFR1BUUihzZWcsMCk7Ci8qIElOVCAxQzoganVzdCBwb2ludCBpdCB0byBJUkVULCB3ZSBkb24ndCB3YW50IHRvIGhhbmRsZSBpdCBvdXJzZWx2ZXMgKi8KICgoU0VHUFRSKikobHBEb3NUYXNrLT5pbWcpKVsweDFDXT1QVFJfU0VHX09GRl9UT19TRUdQVFIoc2VnLHNpemVvZihpbnQwOCktMSk7Cn0KCnN0YXRpYyBjaGFyIGVudGVyX3htc1tdPXsKLyogWE1TIGhvb2thYmxlIGVudHJ5IHBvaW50ICovCiAweEVCLDB4MDMsICAgICAgICAgICAvKiBqbXAgZW50cnkgKi8KIDB4OTAsMHg5MCwweDkwLCAgICAgIC8qIG5vcDtub3A7bm9wICovCiAgICAgICAgICAgICAgICAgICAgICAvKiBlbnRyeTogKi8KLyogcmVhbCBlbnRyeSBwb2ludCAqLwovKiBmb3Igc2ltcGxpY2l0eSwgd2UnbGwganVzdCB1c2UgdGhlIHNhbWUgaG9vayBhcyBEUE1JIGJlbG93ICovCiAweENELDB4MzEsICAgICAgICAgICAvKiBpbnQgJDB4MzEgKi8KIDB4Q0IgICAgICAgICAgICAgICAgIC8qIGxyZXQgKi8KfTsKCnN0YXRpYyB2b2lkIE1aX0luaXRYTVMoIExQRE9TVEFTSyBscERvc1Rhc2sgKQp7CiBMUEJZVEUgc3RhcnQ9RE9TTUVNX0dldEJsb2NrKGxwRG9zVGFzay0+aE1vZHVsZSxzaXplb2YoZW50ZXJfeG1zKSwmKGxwRG9zVGFzay0+eG1zX3NlZykpOwogbWVtY3B5KHN0YXJ0LGVudGVyX3htcyxzaXplb2YoZW50ZXJfeG1zKSk7Cn0KCnN0YXRpYyBjaGFyIGVudGVyX3BtW109ewogMHg1MCwgICAgICAgICAgICAgICAgLyogcHVzaHcgJWF4ICovCiAweDUyLCAgICAgICAgICAgICAgICAvKiBwdXNodyAlZHggKi8KIDB4NTUsICAgICAgICAgICAgICAgIC8qIHB1c2h3ICVicCAqLwogMHg4OSwweEU1LCAgICAgICAgICAgLyogbW92dyAlc3AsJWJwICovCi8qIGdldCByZXR1cm4gQ1MgKi8KIDB4OEIsMHg1NiwweDA4LCAgICAgIC8qIG1vdncgOCglYnApLCVkeCAqLwovKiBqdXN0IGNhbGwgaW50IDMxIGhlcmUgdG8gZ2V0IGludG8gcHJvdGVjdGVkIG1vZGUuLi4gKi8KLyogaXQnbGwgY2hlY2sgd2hldGhlciBpdCB3YXMgY2FsbGVkIGZyb20gZHBtaV9zZWcuLi4gKi8KIDB4Q0QsMHgzMSwgICAgICAgICAgIC8qIGludCAkMHgzMSAqLwovKiB3ZSBhcmUgbm93IGluIHRoZSBjb250ZXh0IG9mIGEgMTYtYml0IHJlbGF5IGNhbGwgKi8KLyogbmVlZCB0byBmaXh1cCBvdXIgc3RhY2s7CiAqIDE2LWJpdCByZWxheSByZXR1cm4gYWRkcmVzcyB3aWxsIGJlIGxvc3QsIGJ1dCB3ZSB3b24ndCB3b3JyeSBxdWl0ZSB5ZXQgKi8KIDB4OEUsMHhEMCwgICAgICAgICAgIC8qIG1vdncgJWF4LCVzcyAqLwogMHg2NiwweDBGLDB4QjcsMHhFNSwgLyogbW92endsICVicCwlZXNwICovCi8qIHNldCByZXR1cm4gQ1MgKi8KIDB4ODksMHg1NiwweDA4LCAgICAgIC8qIG1vdncgJWR4LDgoJWJwKSAqLwogMHg1RCwgICAgICAgICAgICAgICAgLyogcG9wdyAlYnAgKi8KIDB4NUEsICAgICAgICAgICAgICAgIC8qIHBvcHcgJWR4ICovCiAweDU4LCAgICAgICAgICAgICAgICAvKiBwb3B3ICVheCAqLwogMHhDQiAgICAgICAgICAgICAgICAgLyogbHJldCAqLwp9OwoKc3RhdGljIHZvaWQgTVpfSW5pdERQTUkoIExQRE9TVEFTSyBscERvc1Rhc2sgKQp7CiB1bnNpZ25lZCBzaXplPXNpemVvZihlbnRlcl9wbSk7CiBMUEJZVEUgc3RhcnQ9RE9TTUVNX0dldEJsb2NrKGxwRG9zVGFzay0+aE1vZHVsZSxzaXplLCYobHBEb3NUYXNrLT5kcG1pX3NlZykpOwogCiBscERvc1Rhc2stPmRwbWlfc2VsID0gU0VMRUNUT1JfQWxsb2NCbG9jayggc3RhcnQsIHNpemUsIFNFR01FTlRfQ09ERSwgRkFMU0UsIEZBTFNFICk7CgogbWVtY3B5KHN0YXJ0LGVudGVyX3BtLHNpemVvZihlbnRlcl9wbSkpOwp9CgpzdGF0aWMgV09SRCBNWl9Jbml0RW52aXJvbm1lbnQoIExQRE9TVEFTSyBscERvc1Rhc2ssIExQQ1NUUiBlbnYsIExQQ1NUUiBuYW1lICkKewogdW5zaWduZWQgc3o9MDsKIFdPUkQgc2VnOwogTFBTVFIgZW52YmxrOwoKIGlmIChlbnYpIHsKICAvKiBnZXQgc2l6ZSBvZiBlbnZpcm9ubWVudCBibG9jayAqLwogIHdoaWxlIChlbnZbc3orK10pIHN6Kz1zdHJsZW4oZW52K3N6KSsxOwogfSBlbHNlIHN6Kys7CiAvKiBhbGxvY2F0ZSBpdCAqLwogZW52YmxrPURPU01FTV9HZXRCbG9jayhscERvc1Rhc2stPmhNb2R1bGUsc3orc2l6ZW9mKFdPUkQpK3N0cmxlbihuYW1lKSsxLCZzZWcpOwogLyogZmlsbCBpdCAqLwogaWYgKGVudikgewogIG1lbWNweShlbnZibGssZW52LHN6KTsKIH0gZWxzZSBlbnZibGtbMF09MDsKIC8qIERPUyAzLng6IHRoZSBibG9jayBjb250YWlucyAxIGFkZGl0aW9uYWwgc3RyaW5nICovCiAqKFdPUkQqKShlbnZibGsrc3opPTE7CiAvKiBiZWluZyB0aGUgcHJvZ3JhbSBuYW1lIGl0c2VsZiAqLwogc3RyY3B5KGVudmJsaytzeitzaXplb2YoV09SRCksbmFtZSk7CiByZXR1cm4gc2VnOwp9CgppbnQgTVpfSW5pdE1lbW9yeSggTFBET1NUQVNLIGxwRG9zVGFzaywgTkVfTU9EVUxFICpwTW9kdWxlICkKewogaW50IHg7CgogaWYgKGxwRG9zVGFzay0+aW1nX29mcykgcmV0dXJuIDMyOyAvKiBhbHJlYWR5IGFsbG9jYXRlZCAqLwoKIC8qIGFsbG9jYXRlIDFNQis2NEsgc2hhcmVkIG1lbW9yeSAqLwogbHBEb3NUYXNrLT5pbWdfb2ZzPVNUQVJUX09GRlNFVDsKI2lmZGVmIE1aX01BUFNFTEYKIGxwRG9zVGFzay0+aW1nPVZpcnR1YWxBbGxvYyhOVUxMLDB4MTEwMDAwLE1FTV9DT01NSVQsUEFHRV9SRUFEV1JJVEUpOwogLyogbWFrZSBzdXJlIG1tYXAgYWNjZXB0cyBpdCAqLwogKChjaGFyKilscERvc1Rhc2stPmltZylbMHgxMEZGRkZdPTA7CiNlbHNlCiB0bXBuYW0obHBEb3NUYXNrLT5tbV9uYW1lKTsKLyogc3RyY3B5KGxwRG9zVGFzay0+bW1fbmFtZSwiL3RtcC9teWRvc2ltYWdlIik7ICovCiBscERvc1Rhc2stPm1tX2ZkPW9wZW4obHBEb3NUYXNrLT5tbV9uYW1lLE9fUkRXUnxPX0NSRUFUIC8qIHxPX1RSVU5DICovLFNfSVJVU1J8U19JV1VTUik7CiBpZiAobHBEb3NUYXNrLT5tbV9mZDwwKSBFUlIobW9kdWxlLCJmaWxlICVzIGNvdWxkIG5vdCBiZSBvcGVuZWRcbiIsbHBEb3NUYXNrLT5tbV9uYW1lKTsKIC8qIGV4cGFuZCBmaWxlIHRvIDFNQis2NEsgKi8KIGxzZWVrKGxwRG9zVGFzay0+bW1fZmQsMHgxMTAwMDAtMSxTRUVLX1NFVCk7CiB4PTA7IHdyaXRlKGxwRG9zVGFzay0+bW1fZmQsJngsMSk7CiAvKiBtYXAgaXQgaW4gKi8KIGxwRG9zVGFzay0+aW1nPW1tYXAoTlVMTCwweDExMDAwMC1TVEFSVF9PRkZTRVQsUFJPVF9SRUFEfFBST1RfV1JJVEUsTUFQX1NIQVJFRCxscERvc1Rhc2stPm1tX2ZkLDApOwojZW5kaWYKIGlmIChscERvc1Rhc2stPmltZz09KExQVk9JRCktMSkgewogIEVSUihtb2R1bGUsImNvdWxkIG5vdCBtYXAgc2hhcmVkIG1lbW9yeSwgZXJyb3I9JXNcbiIsc3RyZXJyb3IoZXJybm8pKTsKICByZXR1cm4gMDsKIH0KIFRSQUNFKG1vZHVsZSwiRE9TIFZNODYgaW1hZ2UgbWFwcGVkIGF0ICUwOGx4XG4iLChEV09SRClscERvc1Rhc2stPmltZyk7CiBwTW9kdWxlLT5kb3NfaW1hZ2U9bHBEb3NUYXNrLT5pbWc7CgogLyogaW5pdGlhbGl6ZSB0aGUgbWVtb3J5ICovCiBUUkFDRShtb2R1bGUsIkluaXRpYWxpemluZyBET1MgbWVtb3J5IHN0cnVjdHVyZXNcbiIpOwogRE9TTUVNX0luaXQobHBEb3NUYXNrLT5oTW9kdWxlKTsKIE1aX0luaXRIYW5kbGVycyhscERvc1Rhc2spOwogTVpfSW5pdFhNUyhscERvc1Rhc2spOwogTVpfSW5pdERQTUkobHBEb3NUYXNrKTsKIHJldHVybiBscERvc1Rhc2stPmhNb2R1bGU7Cn0KCnN0YXRpYyBpbnQgTVpfTG9hZEltYWdlKCBIRklMRTE2IGhGaWxlLCBMUENTVFIgbmFtZSwgTFBDU1RSIGNtZGxpbmUsCiAgICAgICAgICAgICAgICAgICAgICAgICBMUENTVFIgZW52LCBMUERPU1RBU0sgbHBEb3NUYXNrLCBORV9NT0RVTEUgKnBNb2R1bGUgKQp7CiBJTUFHRV9ET1NfSEVBREVSIG16X2hlYWRlcjsKIERXT1JEIGltYWdlX3N0YXJ0LGltYWdlX3NpemUsbWluX3NpemUsbWF4X3NpemUsYXZhaWw7CiBCWVRFKnBzcF9zdGFydCwqbG9hZF9zdGFydDsKIGludCB4LG9sZF9jb209MDsKIFNFR1BUUiByZWxvYzsKIFdPUkQgZW52X3NlZzsKCiBpZiAoKF9ocmVhZDE2KGhGaWxlLCZtel9oZWFkZXIsc2l6ZW9mKG16X2hlYWRlcikpICE9IHNpemVvZihtel9oZWFkZXIpKSB8fAogICAgIChtel9oZWFkZXIuZV9tYWdpYyAhPSBJTUFHRV9ET1NfU0lHTkFUVVJFKSkgewojaWYgMAogICAgIHJldHVybiAxMTsgLyogaW52YWxpZCBleGUgKi8KI2VuZGlmCiAgb2xkX2NvbT0xOyAvKiBhc3N1bWUgLkNPTSBmaWxlICovCiAgaW1hZ2Vfc3RhcnQ9MDsKICBpbWFnZV9zaXplPUdldEZpbGVTaXplKEhGSUxFMTZfVE9fSEZJTEUzMihoRmlsZSksTlVMTCk7CiAgbWluX3NpemU9MHgxMDAwMDsgbWF4X3NpemU9MHgxMDAwMDA7CiAgbXpfaGVhZGVyLmVfY3JsYz0wOwogIG16X2hlYWRlci5lX3NzPTA7IG16X2hlYWRlci5lX3NwPTB4RkZGRTsKICBtel9oZWFkZXIuZV9jcz0wOyBtel9oZWFkZXIuZV9pcD0weDEwMDsKIH0gZWxzZSB7CiAgLyogY2FsY3VsYXRlIGxvYWQgc2l6ZSAqLwogIGltYWdlX3N0YXJ0PW16X2hlYWRlci5lX2NwYXJoZHI8PDQ7CiAgaW1hZ2Vfc2l6ZT1tel9oZWFkZXIuZV9jcDw8OTsgLyogcGFnZXMgYXJlIDUxMiBieXRlcyAqLwogIGlmICgobXpfaGVhZGVyLmVfY2JscCE9MCkmJihtel9oZWFkZXIuZV9jYmxwIT00KSkgaW1hZ2Vfc2l6ZS09NTEyLW16X2hlYWRlci5lX2NibHA7CiAgaW1hZ2Vfc2l6ZS09aW1hZ2Vfc3RhcnQ7CiAgbWluX3NpemU9aW1hZ2Vfc2l6ZSsoKERXT1JEKW16X2hlYWRlci5lX21pbmFsbG9jPDw0KSsoUFNQX1NJWkU8PDQpOwogIG1heF9zaXplPWltYWdlX3NpemUrKChEV09SRCltel9oZWFkZXIuZV9tYXhhbGxvYzw8NCkrKFBTUF9TSVpFPDw0KTsKIH0KCiBNWl9Jbml0TWVtb3J5KGxwRG9zVGFzayxwTW9kdWxlKTsKCiAvKiBhbGxvY2F0ZSBlbnZpcm9ubWVudCBibG9jayAqLwogZW52X3NlZz1NWl9Jbml0RW52aXJvbm1lbnQobHBEb3NUYXNrLGVudixuYW1lKTsKCiAvKiBhbGxvY2F0ZSBtZW1vcnkgZm9yIHRoZSBleGVjdXRhYmxlICovCiBUUkFDRShtb2R1bGUsIkFsbG9jYXRpbmcgRE9TIG1lbW9yeSAobWluPSVsZCwgbWF4PSVsZClcbiIsbWluX3NpemUsbWF4X3NpemUpOwogYXZhaWw9RE9TTUVNX0F2YWlsYWJsZShscERvc1Rhc2stPmhNb2R1bGUpOwogaWYgKGF2YWlsPG1pbl9zaXplKSB7CiAgRVJSKG1vZHVsZSwgImluc3VmZmljaWVudCBET1MgbWVtb3J5XG4iKTsKICByZXR1cm4gMDsKIH0KIGlmIChhdmFpbD5tYXhfc2l6ZSkgYXZhaWw9bWF4X3NpemU7CiBwc3Bfc3RhcnQ9RE9TTUVNX0dldEJsb2NrKGxwRG9zVGFzay0+aE1vZHVsZSxhdmFpbCwmbHBEb3NUYXNrLT5wc3Bfc2VnKTsKIGlmICghcHNwX3N0YXJ0KSB7CiAgRVJSKG1vZHVsZSwgImVycm9yIGFsbG9jYXRpbmcgRE9TIG1lbW9yeVxuIik7CiAgcmV0dXJuIDA7CiB9CiBscERvc1Rhc2stPmxvYWRfc2VnPWxwRG9zVGFzay0+cHNwX3NlZysob2xkX2NvbT8wOlBTUF9TSVpFKTsKIGxvYWRfc3RhcnQ9cHNwX3N0YXJ0KyhQU1BfU0laRTw8NCk7CiBNWl9Jbml0UFNQKHBzcF9zdGFydCwgY21kbGluZSwgZW52X3NlZyk7CgogLyogbG9hZCBleGVjdXRhYmxlIGltYWdlICovCiBUUkFDRShtb2R1bGUsImxvYWRpbmcgRE9TICVzIGltYWdlLCAlMDhseCBieXRlc1xuIixvbGRfY29tPyJDT00iOiJFWEUiLGltYWdlX3NpemUpOwogX2xsc2VlazE2KGhGaWxlLGltYWdlX3N0YXJ0LEZJTEVfQkVHSU4pOwogaWYgKChfaHJlYWQxNihoRmlsZSxsb2FkX3N0YXJ0LGltYWdlX3NpemUpKSAhPSBpbWFnZV9zaXplKQogIHJldHVybiAxMTsgLyogaW52YWxpZCBleGUgKi8KCiBpZiAobXpfaGVhZGVyLmVfY3JsYykgewogIC8qIGxvYWQgcmVsb2NhdGlvbiB0YWJsZSAqLwogIFRSQUNFKG1vZHVsZSwibG9hZGluZyBET1MgRVhFIHJlbG9jYXRpb24gdGFibGUsICVkIGVudHJpZXNcbiIsbXpfaGVhZGVyLmVfY3JsYyk7CiAgLyogRklYTUU6IGlzIHRoaXMgdG9vIHNsb3cgd2l0aG91dCByZWFkIGJ1ZmZlcmluZz8gKi8KICBfbGxzZWVrMTYoaEZpbGUsbXpfaGVhZGVyLmVfbGZhcmxjLEZJTEVfQkVHSU4pOwogIGZvciAoeD0wOyB4PG16X2hlYWRlci5lX2NybGM7IHgrKykgewogICBpZiAoX2xyZWFkMTYoaEZpbGUsJnJlbG9jLHNpemVvZihyZWxvYykpICE9IHNpemVvZihyZWxvYykpCiAgICByZXR1cm4gMTE7IC8qIGludmFsaWQgZXhlICovCiAgICooV09SRCopU0VHUFRSMTYobG9hZF9zdGFydCxyZWxvYykrPWxwRG9zVGFzay0+bG9hZF9zZWc7CiAgfQogfQoKIGxwRG9zVGFzay0+aW5pdF9jcz1scERvc1Rhc2stPmxvYWRfc2VnK216X2hlYWRlci5lX2NzOwogbHBEb3NUYXNrLT5pbml0X2lwPW16X2hlYWRlci5lX2lwOwogbHBEb3NUYXNrLT5pbml0X3NzPWxwRG9zVGFzay0+bG9hZF9zZWcrbXpfaGVhZGVyLmVfc3M7CiBscERvc1Rhc2stPmluaXRfc3A9bXpfaGVhZGVyLmVfc3A7CgogVFJBQ0UobW9kdWxlLCJlbnRyeSBwb2ludDogJTA0eDolMDR4XG4iLGxwRG9zVGFzay0+aW5pdF9jcyxscERvc1Rhc2stPmluaXRfaXApOwoKIHJldHVybiBscERvc1Rhc2stPmhNb2R1bGU7Cn0KCkxQRE9TVEFTSyBNWl9BbGxvY0RQTUlUYXNrKCBITU9EVUxFMTYgaE1vZHVsZSApCnsKIExQRE9TVEFTSyBscERvc1Rhc2sgPSBjYWxsb2MoMSwgc2l6ZW9mKERPU1RBU0spKTsKIE5FX01PRFVMRSAqcE1vZHVsZTsKCiBpZiAobHBEb3NUYXNrKSB7CiAgbHBEb3NUYXNrLT5oTW9kdWxlID0gaE1vZHVsZTsKCiAgcE1vZHVsZSA9IChORV9NT0RVTEUgKilHbG9iYWxMb2NrMTYoaE1vZHVsZSk7CiAgcE1vZHVsZS0+bHBEb3NUYXNrID0gbHBEb3NUYXNrOwogCiAgbHBEb3NUYXNrLT5pbWc9TlVMTDsgbHBEb3NUYXNrLT5tbV9uYW1lWzBdPTA7IGxwRG9zVGFzay0+bW1fZmQ9LTE7CgogIE1aX0luaXRNZW1vcnkobHBEb3NUYXNrLCBwTW9kdWxlKTsKCiAgR2xvYmFsVW5sb2NrMTYoaE1vZHVsZSk7CiB9CiByZXR1cm4gbHBEb3NUYXNrOwp9CgpzdGF0aWMgdm9pZCBNWl9Jbml0VGltZXIoIExQRE9TVEFTSyBscERvc1Rhc2ssIGludCB2ZXIgKQp7CiBpZiAodmVyPDEpIHsKI2lmIDAKICAvKiBzdGFydCBzaW11bGF0ZWQgc3lzdGVtIDU1SHogdGltZXIgKi8KICBscERvc1Rhc2stPnN5c3RlbV90aW1lciA9IENyZWF0ZVN5c3RlbVRpbWVyKCA1NSwgTVpfVGljayApOwogIFRSQUNFKG1vZHVsZSwiY3JlYXRlZCA1NUh6IHRpbWVyIHRpY2ssIGhhbmRsZT0lZFxuIixscERvc1Rhc2stPnN5c3RlbV90aW1lcik7CiNlbmRpZgogfSBlbHNlIHsKICBpbnQgZnVuYzsKICBzdHJ1Y3QgdGltZXZhbCB0aW07CgogIC8qIHN0YXJ0IGRvc21vZCB0aW1lciBhdCA1NUh6ICovCiAgZnVuYz1ET1NNT0RfU0VUX1RJTUVSOwogIHRpbS50dl9zZWM9MDsgdGltLnR2X3VzZWM9NTQ5MjU7CiAgd3JpdGUobHBEb3NUYXNrLT53cml0ZV9waXBlLCZmdW5jLHNpemVvZihmdW5jKSk7CiAgd3JpdGUobHBEb3NUYXNrLT53cml0ZV9waXBlLCZ0aW0sc2l6ZW9mKHRpbSkpOwogfQp9CgppbnQgTVpfSW5pdFRhc2soIExQRE9TVEFTSyBscERvc1Rhc2sgKQp7CiBpbnQgcmVhZF9mZFsyXSx3cml0ZV9mZFsyXTsKIHBpZF90IGNoaWxkOwogY2hhciAqZm5hbWUsKmZhcmcsYXJnWzE2XSxmcHJvY1s2NF0scGF0aFsyNTZdLCpmcGF0aDsKCiBpZiAoIWxwRG9zVGFzaykgcmV0dXJuIDA7CiAvKiBjcmVhdGUgcmVhZCBwaXBlICovCiBpZiAocGlwZShyZWFkX2ZkKTwwKSByZXR1cm4gMDsKIGlmIChwaXBlKHdyaXRlX2ZkKTwwKSB7CiAgY2xvc2UocmVhZF9mZFswXSk7IGNsb3NlKHJlYWRfZmRbMV0pOyByZXR1cm4gMDsKIH0KIGxwRG9zVGFzay0+cmVhZF9waXBlPXJlYWRfZmRbMF07CiBscERvc1Rhc2stPndyaXRlX3BpcGU9d3JpdGVfZmRbMV07CiAvKiBpZiB3ZSBoYXZlIGEgbWFwcGluZyBmaWxlLCB1c2UgaXQgKi8KIGZuYW1lPWxwRG9zVGFzay0+bW1fbmFtZTsgZmFyZz1OVUxMOwogaWYgKCFmbmFtZVswXSkgewogIC8qIG90aGVyd2lzZSwgbWFwIG91ciBvd24gbWVtb3J5IGltYWdlICovCiAgc3ByaW50ZihmcHJvYywiL3Byb2MvJWQvbWVtIixnZXRwaWQoKSk7CiAgc3ByaW50ZihhcmcsIiVsZCIsKHVuc2lnbmVkIGxvbmcpbHBEb3NUYXNrLT5pbWcpOwogIGZuYW1lPWZwcm9jOyBmYXJnPWFyZzsKIH0KCiBUUkFDRShtb2R1bGUsIkxvYWRpbmcgRE9TIFZNIHN1cHBvcnQgbW9kdWxlIChobW9kdWxlPSUwNHgpXG4iLGxwRG9zVGFzay0+aE1vZHVsZSk7CiBpZiAoKGNoaWxkPWZvcmsoKSk8MCkgewogIGNsb3NlKHdyaXRlX2ZkWzBdKTsgY2xvc2Uod3JpdGVfZmRbMV0pOwogIGNsb3NlKHJlYWRfZmRbMF0pOyBjbG9zZShyZWFkX2ZkWzFdKTsgcmV0dXJuIDA7CiB9CiBpZiAoY2hpbGQhPTApIHsKICAvKiBwYXJlbnQgcHJvY2VzcyAqLwogIGludCByZXQ7CgogIGNsb3NlKHJlYWRfZmRbMV0pOyBjbG9zZSh3cml0ZV9mZFswXSk7CiAgbHBEb3NUYXNrLT50YXNrPWNoaWxkOwogIC8qIHdhaXQgZm9yIGNoaWxkIHByb2Nlc3MgdG8gc2lnbmFsIHJlYWRpbmVzcyAqLwogIGRvIHsKICAgaWYgKHJlYWQobHBEb3NUYXNrLT5yZWFkX3BpcGUsJnJldCxzaXplb2YocmV0KSkhPXNpemVvZihyZXQpKSB7CiAgICBpZiAoKGVycm5vPT1FSU5UUil8fChlcnJubz09RUFHQUlOKSkgY29udGludWU7CiAgICAvKiBmYWlsdXJlICovCiAgICBFUlIobW9kdWxlLCJkb3Ntb2QgaGFzIGZhaWxlZCB0byBpbml0aWFsaXplXG4iKTsKICAgIGlmIChscERvc1Rhc2stPm1tX25hbWVbMF0hPTApIHVubGluayhscERvc1Rhc2stPm1tX25hbWUpOwogICAgcmV0dXJuIDA7CiAgIH0KICB9IHdoaWxlICgwKTsKICAvKiB0aGUgY2hpbGQgaGFzIG5vdyBtbWFwZWQgdGhlIHRlbXAgZmlsZSwgaXQncyBub3cgc2FmZSB0byB1bmxpbmsuCiAgICogZG8gaXQgaGVyZSB0byBhdm9pZCBsZWF2aW5nIGEgbWVzcyBpbiAvdG1wIGlmL3doZW4gV2luZSBjcmFzaGVzLi4uICovCiAgaWYgKGxwRG9zVGFzay0+bW1fbmFtZVswXSE9MCkgdW5saW5rKGxwRG9zVGFzay0+bW1fbmFtZSk7CiAgLyogc3RhcnQgc2ltdWxhdGVkIHN5c3RlbSB0aW1lciAqLwogIE1aX0luaXRUaW1lcihscERvc1Rhc2sscmV0KTsKICAvKiBhbGwgc3lzdGVtcyBhcmUgbm93IGdvICovCiB9IGVsc2UgewogIC8qIGNoaWxkIHByb2Nlc3MgKi8KICBjbG9zZShyZWFkX2ZkWzBdKTsgY2xvc2Uod3JpdGVfZmRbMV0pOwogIC8qIHB1dCBvdXIgcGlwZXMgc29tZXdoZXJlIGRvc21vZCBjYW4gZmluZCB0aGVtICovCiAgZHVwMih3cml0ZV9mZFswXSwwKTsgICAgICAvKiBzdGRpbiAqLwogIGR1cDIocmVhZF9mZFsxXSwxKTsgICAgICAgLyogc3Rkb3V0ICovCiAgLyogZW5hYmxlIHNpZ25hbHMgKi8KICBTSUdOQUxfTWFza0FzeW5jRXZlbnRzKEZBTFNFKTsKICAvKiBub3cgbG9hZCBkb3Ntb2QgKi8KICBleGVjbHAoImRvc21vZCIsZm5hbWUsZmFyZyxOVUxMKTsKICBleGVjbCgiZG9zbW9kIixmbmFtZSxmYXJnLE5VTEwpOwogIC8qIGhtbSwgdGhleSBkaWRuJ3QgaW5zdGFsbCBwcm9wZXJseSAqLwogIGV4ZWNsKCJsb2FkZXIvZG9zL2Rvc21vZCIsZm5hbWUsZmFyZyxOVUxMKTsKICAvKiBsYXN0IHJlc29ydCwgdHJ5IHRvIGZpbmQgaXQgdGhyb3VnaCBhcmd2WzBdICovCiAgZnBhdGg9c3RycmNocihzdHJjcHkocGF0aCxPcHRpb25zLmFyZ3YwKSwnLycpOwogIGlmIChmcGF0aCkgewogICBzdHJjcHkoZnBhdGgsIi9sb2FkZXIvZG9zL2Rvc21vZCIpOwogICBleGVjbChwYXRoLGZuYW1lLGZhcmcsTlVMTCk7CiAgfQogIC8qIGlmIGZhaWx1cmUsIGV4aXQgKi8KICBFUlIobW9kdWxlLCJGYWlsZWQgdG8gc3Bhd24gZG9zbW9kLCBlcnJvcj0lc1xuIixzdHJlcnJvcihlcnJubykpOwogIGV4aXQoMSk7CiB9CiByZXR1cm4gbHBEb3NUYXNrLT5oTW9kdWxlOwp9CgpISU5TVEFOQ0UxNiBNWl9DcmVhdGVQcm9jZXNzKCBMUENTVFIgbmFtZSwgTFBDU1RSIGNtZGxpbmUsIExQQ1NUUiBlbnYsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNUQVJUVVBJTkZPMzJBIHN0YXJ0dXAsIExQUFJPQ0VTU19JTkZPUk1BVElPTiBpbmZvICkKewogTFBET1NUQVNLIGxwRG9zVGFzayA9IE5VTEw7IC8qIGtlZXAgZ2NjIGZyb20gY29tcGxhaW5pbmcgKi8KIEhNT0RVTEUxNiBoTW9kdWxlOwogSElOU1RBTkNFMTYgaEluc3RhbmNlOwogUERCMzIgKnBkYiA9IFBST0NFU1NfQ3VycmVudCgpOwogVERCICpwVGFzayA9IChUREIqKUdsb2JhbExvY2sxNiggR2V0Q3VycmVudFRhc2soKSApOwogTkVfTU9EVUxFICpwTW9kdWxlID0gcFRhc2sgPyBORV9HZXRQdHIoIHBUYXNrLT5oTW9kdWxlICkgOiBOVUxMOwogSEZJTEUxNiBoRmlsZTsKIE9GU1RSVUNUIG9mczsKIGludCBlcnIsIGFsbG9jID0gIShwTW9kdWxlICYmIHBNb2R1bGUtPmRvc19pbWFnZSk7CgogR2xvYmFsVW5sb2NrMTYoIEdldEN1cnJlbnRUYXNrKCkgKTsKCiBpZiAoYWxsb2MgJiYgKGxwRG9zVGFzayA9IGNhbGxvYygxLCBzaXplb2YoRE9TVEFTSykpKSA9PSBOVUxMKQogIHJldHVybiAwOwoKIGlmICgoaEZpbGUgPSBPcGVuRmlsZTE2KCBuYW1lLCAmb2ZzLCBPRl9SRUFEICkpID09IEhGSUxFX0VSUk9SMTYpCiAgcmV0dXJuIDI7IC8qIEZpbGUgbm90IGZvdW5kICovCgogaWYgKCghZW52KSYmcGRiKSBlbnYgPSBwZGItPmVudl9kYi0+ZW52aXJvbjsKIGlmIChhbGxvYykgewogIGlmICgoaE1vZHVsZSA9IE1PRFVMRV9DcmVhdGVEdW1teU1vZHVsZSgmb2ZzKSkgPCAzMikKICAgcmV0dXJuIGhNb2R1bGU7CgogIGxwRG9zVGFzay0+aE1vZHVsZSA9IGhNb2R1bGU7CgogIHBNb2R1bGUgPSAoTkVfTU9EVUxFICopR2xvYmFsTG9jazE2KGhNb2R1bGUpOwogIHBNb2R1bGUtPmxwRG9zVGFzayA9IGxwRG9zVGFzazsKIAogIGxwRG9zVGFzay0+aW1nPU5VTEw7IGxwRG9zVGFzay0+bW1fbmFtZVswXT0wOyBscERvc1Rhc2stPm1tX2ZkPS0xOwogfSBlbHNlIGxwRG9zVGFzaz1wTW9kdWxlLT5scERvc1Rhc2s7CiBlcnIgPSBNWl9Mb2FkSW1hZ2UoIGhGaWxlLCBuYW1lLCBjbWRsaW5lLCBlbnYsIGxwRG9zVGFzaywgcE1vZHVsZSApOwogX2xjbG9zZTE2KGhGaWxlKTsKIGlmIChhbGxvYykgewogIHBNb2R1bGUtPmRvc19pbWFnZSA9IGxwRG9zVGFzay0+aW1nOwogIGlmIChlcnI8MzIpIHsKICAgaWYgKGxwRG9zVGFzay0+bW1fbmFtZVswXSE9MCkgewogICAgaWYgKGxwRG9zVGFzay0+aW1nIT1OVUxMKSBtdW5tYXAobHBEb3NUYXNrLT5pbWcsMHgxMTAwMDAtU1RBUlRfT0ZGU0VUKTsKICAgIGlmIChscERvc1Rhc2stPm1tX2ZkPj0wKSBjbG9zZShscERvc1Rhc2stPm1tX2ZkKTsKICAgIHVubGluayhscERvc1Rhc2stPm1tX25hbWUpOwogICB9IGVsc2UKICAgIGlmIChscERvc1Rhc2stPmltZyE9TlVMTCkgVmlydHVhbEZyZWUobHBEb3NUYXNrLT5pbWcsMHgxMTAwMDAsTUVNX1JFTEVBU0UpOwogICByZXR1cm4gZXJyOwogIH0KICBlcnIgPSBNWl9Jbml0VGFzayggbHBEb3NUYXNrICk7CiAgaWYgKGVycjwzMikgewogICBNWl9LaWxsTW9kdWxlKCBscERvc1Rhc2sgKTsKICAgLyogRklYTUU6IGNsZWFudXAgaE1vZHVsZSAqLwogICByZXR1cm4gZXJyOwogIH0KCiAgaEluc3RhbmNlID0gTkVfQ3JlYXRlSW5zdGFuY2UocE1vZHVsZSwgTlVMTCwgKGNtZGxpbmUgPT0gTlVMTCkpOwogIFBST0NFU1NfQ3JlYXRlKCBwTW9kdWxlLCBjbWRsaW5lLCBlbnYsIGhJbnN0YW5jZSwgMCwgc3RhcnR1cCwgaW5mbyApOwogIHJldHVybiBoSW5zdGFuY2U7CiB9IGVsc2UgewogIHJldHVybiAoZXJyPDMyKSA/IGVyciA6IHBUYXNrLT5oSW5zdGFuY2U7CiB9Cn0KCnZvaWQgTVpfS2lsbE1vZHVsZSggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIFRSQUNFKG1vZHVsZSwia2lsbGluZyBET1MgdGFza1xuIik7CiNpZiAwCiBTWVNURU1fS2lsbFN5c3RlbVRpbWVyKGxwRG9zVGFzay0+c3lzdGVtX3RpbWVyKTsKI2VuZGlmCiBpZiAobHBEb3NUYXNrLT5tbV9uYW1lWzBdIT0wKSB7CiAgbXVubWFwKGxwRG9zVGFzay0+aW1nLDB4MTEwMDAwLVNUQVJUX09GRlNFVCk7CiAgY2xvc2UobHBEb3NUYXNrLT5tbV9mZCk7CiB9IGVsc2UgVmlydHVhbEZyZWUobHBEb3NUYXNrLT5pbWcsMHgxMTAwMDAsTUVNX1JFTEVBU0UpOwogY2xvc2UobHBEb3NUYXNrLT5yZWFkX3BpcGUpOwogY2xvc2UobHBEb3NUYXNrLT53cml0ZV9waXBlKTsKIGtpbGwobHBEb3NUYXNrLT50YXNrLFNJR1RFUk0pOwojaWYgMAogLyogRklYTUU6IHRoaXMgc2VlbXMgdG8gY3Jhc2ggKi8KIGlmIChscERvc1Rhc2stPmRwbWlfc2VsKQogIFVuTWFwTFMoUFRSX1NFR19PRkZfVE9fU0VHUFRSKGxwRG9zVGFzay0+ZHBtaV9zZWwsMCkpOwojZW5kaWYKfQoKI2Vsc2UgLyogIU1aX1NVUFBPUlRFRCAqLwoKSElOU1RBTkNFMTYgTVpfQ3JlYXRlUHJvY2VzcyggTFBDU1RSIG5hbWUsIExQQ1NUUiBjbWRsaW5lLCBMUENTVFIgZW52LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTVEFSVFVQSU5GTzMyQSBzdGFydHVwLCBMUFBST0NFU1NfSU5GT1JNQVRJT04gaW5mbyApCnsKIFdBUk4obW9kdWxlLCJET1MgZXhlY3V0YWJsZXMgbm90IHN1cHBvcnRlZCBvbiB0aGlzIGFyY2hpdGVjdHVyZVxuIik7CiByZXR1cm4gKEhNT0RVTEUxNikxMTsgIC8qIGludmFsaWQgZXhlICovCn0KCiNlbmRpZgo=