LyoKICogUUVNVSBNYWx0YSBib2FyZCBzdXBwb3J0CiAqCiAqIENvcHlyaWdodCAoYykgMjAwNyBIZXJ26SBQb3Vzc2luZWF1CiAqCiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKICogaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cwogKiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCiAqIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcwogKiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgogKgogKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbgogKiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1IKICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMCiAqIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSCiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sCiAqIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4KICogVEhFIFNPRlRXQVJFLgogKi8KCiNpbmNsdWRlICJ2bC5oIgoKI2lmZGVmIFRBUkdFVF9XT1JEU19CSUdFTkRJQU4KI2RlZmluZSBCSU9TX0ZJTEVOQU1FICJtaXBzX2Jpb3MuYmluIgojZWxzZQojZGVmaW5lIEJJT1NfRklMRU5BTUUgIm1pcHNlbF9iaW9zLmJpbiIKI2VuZGlmCgojaWZkZWYgVEFSR0VUX01JUFM2NAojZGVmaW5lIFBIWVNfVE9fVklSVCh4KSAoKHgpIHwgfjB4N2ZmZmZmZmZVTEwpCiNlbHNlCiNkZWZpbmUgUEhZU19UT19WSVJUKHgpICgoeCkgfCB+MHg3ZmZmZmZmZlUpCiNlbmRpZgoKI2RlZmluZSBWSVJUX1RPX1BIWVNfQURERU5EICgtKChpbnQ2NF90KShpbnQzMl90KTB4ODAwMDAwMDApKQoKc3RhdGljIGNvbnN0IGludCBpZGVfaW9iYXNlWzJdID0geyAweDFmMCwgMHgxNzAgfTsKc3RhdGljIGNvbnN0IGludCBpZGVfaW9iYXNlMlsyXSA9IHsgMHgzZjYsIDB4Mzc2IH07CnN0YXRpYyBjb25zdCBpbnQgaWRlX2lycVsyXSA9IHsgMTQsIDE1IH07CgpzdGF0aWMgdWludDMyX3Qgc2VyaWFsX2Jhc2VbTUFYX1NFUklBTF9QT1JUU10gPSB7IDB4ODAwMDYwMDAsIDB4ODAwMDcwMDAgfTsKc3RhdGljIGludCBzZXJpYWxfaXJxW01BWF9TRVJJQUxfUE9SVFNdID0geyA4LCA5IH07CgpleHRlcm4gRklMRSAqbG9nZmlsZTsKCnN0YXRpYyB2b2lkIG1haW5fY3B1X3Jlc2V0KHZvaWQgKm9wYXF1ZSkKewogICAgQ1BVU3RhdGUgKmVudiA9IG9wYXF1ZTsKICAgIGNwdV9yZXNldChlbnYpOwp9CgpzdGF0aWMKdm9pZCBtaXBzX3BpY2E2MV9pbml0IChpbnQgcmFtX3NpemUsIGludCB2Z2FfcmFtX3NpemUsIGludCBib290X2RldmljZSwKICAgICAgICAgICAgICAgICAgICBEaXNwbGF5U3RhdGUgKmRzLCBjb25zdCBjaGFyICoqZmRfZmlsZW5hbWUsIGludCBzbmFwc2hvdCwKICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICprZXJuZWxfZmlsZW5hbWUsIGNvbnN0IGNoYXIgKmtlcm5lbF9jbWRsaW5lLAogICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmluaXRyZF9maWxlbmFtZSwgY29uc3QgY2hhciAqY3B1X21vZGVsKQp7CiAgICBjaGFyIGJ1ZlsxMDI0XTsKICAgIHVuc2lnbmVkIGxvbmcgYmlvc19vZmZzZXQ7CiAgICBpbnQgYmlvc19zaXplOwogICAgQ1BVU3RhdGUgKmVudjsKICAgIGludCBpOwogICAgbWlwc19kZWZfdCAqZGVmOwogICAgaW50IGF2YWlsYWJsZV9yYW07CiAgICBxZW11X2lycSAqaTgyNTk7CgogICAgLyogaW5pdCBDUFVzICovCiAgICBpZiAoY3B1X21vZGVsID09IE5VTEwpIHsKI2lmZGVmIFRBUkdFVF9NSVBTNjQKICAgICAgICBjcHVfbW9kZWwgPSAiUjQwMDAiOwojZWxzZQogICAgICAgIC8qIEZJWE1FOiBBbGwgd3JvbmcsIHRoaXMgbWF5YmUgc2hvdWxkIGJlIFIzMDAwIGZvciB0aGUgb2xkZXIgUElDQXMuICovCiAgICAgICAgY3B1X21vZGVsID0gIjI0S2YiOwojZW5kaWYKICAgIH0KICAgIGlmIChtaXBzX2ZpbmRfYnlfbmFtZShjcHVfbW9kZWwsICZkZWYpICE9IDApCiAgICAgICAgZGVmID0gTlVMTDsKICAgIGVudiA9IGNwdV9pbml0KCk7CiAgICBjcHVfbWlwc19yZWdpc3RlcihlbnYsIGRlZik7CiAgICByZWdpc3Rlcl9zYXZldm0oImNwdSIsIDAsIDMsIGNwdV9zYXZlLCBjcHVfbG9hZCwgZW52KTsKICAgIHFlbXVfcmVnaXN0ZXJfcmVzZXQobWFpbl9jcHVfcmVzZXQsIGVudik7CgogICAgLyogYWxsb2NhdGUgUkFNIChsaW1pdGVkIHRvIDI1NiBNQikgKi8KICAgIGlmIChyYW1fc2l6ZSA8IDI1NiAqIDEwMjQgKiAxMDI0KQogICAgICAgIGF2YWlsYWJsZV9yYW0gPSByYW1fc2l6ZTsKICAgIGVsc2UKICAgICAgICBhdmFpbGFibGVfcmFtID0gMjU2ICogMTAyNCAqIDEwMjQ7CiAgICBjcHVfcmVnaXN0ZXJfcGh5c2ljYWxfbWVtb3J5KDAsIGF2YWlsYWJsZV9yYW0sIElPX01FTV9SQU0pOwoKICAgIC8qIGxvYWQgYSBCSU9TIGltYWdlICovCiAgICBiaW9zX29mZnNldCA9IHJhbV9zaXplICsgdmdhX3JhbV9zaXplOwogICAgc25wcmludGYoYnVmLCBzaXplb2YoYnVmKSwgIiVzLyVzIiwgYmlvc19kaXIsIEJJT1NfRklMRU5BTUUpOwogICAgYmlvc19zaXplID0gbG9hZF9pbWFnZShidWYsIHBoeXNfcmFtX2Jhc2UgKyBiaW9zX29mZnNldCk7CiAgICBpZiAoKGJpb3Nfc2l6ZSA8PSAwKSB8fCAoYmlvc19zaXplID4gQklPU19TSVpFKSkgewogICAgICAgIC8qIGZhdGFsICovCiAgICAgICAgZnByaW50ZihzdGRlcnIsICJxZW11OiBFcnJvciwgY291bGQgbm90IGxvYWQgTUlQUyBiaW9zICclcydcbiIsCiAgICAgICAgICAgICAgICBidWYpOwogICAgICAgIGV4aXQoMSk7CiAgICB9CiAgICBjcHVfcmVnaXN0ZXJfcGh5c2ljYWxfbWVtb3J5KDB4MWZjMDAwMDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCSU9TX1NJWkUsIGJpb3Nfb2Zmc2V0IHwgSU9fTUVNX1JPTSk7CgogICAgLyogRGV2aWNlIG1hcAogICAgICoKICAgICAqIGFkZHIgMHhlMDAwNDAwMDogbWMxNDY4MTgKICAgICAqIGFkZHIgMHhlMDAwNTAwMCBpbnRyIDY6IHBzMiBrZXlib2FyZAogICAgICogYWRkciAweGUwMDA1MDAwIGludHIgNzogcHMyIG1vdXNlCiAgICAgKiBhZGRyIDB4ZTAwMDYwMDAgaW50ciA4OiBuczE2NTUwYSwKICAgICAqIGFkZHIgMHhlMDAwNzAwMCBpbnRyIDk6IG5zMTY1NTBhCiAgICAgKiBpc2FfaW9fYmFzZSAweGUyMDAwMDAwIGlzYV9tZW1fYmFzZSAweGUzMDAwMDAwCiAgICAgKi8KCiAgICAvKiBJbml0IENQVSBpbnRlcm5hbCBkZXZpY2VzICovCiAgICBjcHVfbWlwc19pcnFfaW5pdF9jcHUoZW52KTsKICAgIGNwdV9taXBzX2Nsb2NrX2luaXQoZW52KTsKICAgIGNwdV9taXBzX2lycWN0cmxfaW5pdCgpOwoKICAgIC8qIFJlZ2lzdGVyIDY0IEtCIG9mIElTQSBJTyBzcGFjZSBhdCAweDEwMDAwMDAwICovCiAgICBpc2FfbW1pb19pbml0KDB4MTAwMDAwMDAsIDB4MDAwMTAwMDApOwogICAgaXNhX21lbV9iYXNlID0gMHgxMTAwMDAwMDsKCiAgICAvKiBQQyBzdHlsZSBJUlEgKGk4MjU5L2k4MjU0KSBhbmQgRE1BIChpODI1NykgKi8KICAgIC8qIFRoZSBQSUMgaXMgYXR0YWNoZWQgdG8gdGhlIE1JUFMgQ1BVIElOVDAgcGluICovCiAgICBpODI1OSA9IGk4MjU5X2luaXQoZW52LT5pcnFbMl0pOwogICAgcnRjX21tX2luaXQoMHg4MDAwNDA3MCwgMSwgaTgyNTlbMTRdKTsKICAgIHBpdF9pbml0KDB4NDAsIDApOwoKICAgIC8qIEtleWJvYXJkIChpODA0MikgKi8KICAgIGk4MDQyX21tX2luaXQoaTgyNTlbNl0sIGk4MjU5WzddLCAweDgwMDA1MDYwLCAwKTsKCiAgICAvKiBJREUgY29udHJvbGxlciAqLwogICAgZm9yKGkgPSAwOyBpIDwgMjsgaSsrKQogICAgICAgIGlzYV9pZGVfaW5pdChpZGVfaW9iYXNlW2ldLCBpZGVfaW9iYXNlMltpXSwgaTgyNTlbaWRlX2lycVtpXV0sCiAgICAgICAgICAgICAgICAgICAgIGJzX3RhYmxlWzIgKiBpXSwgYnNfdGFibGVbMiAqIGkgKyAxXSk7CgogICAgLyogTmV0d29yayBjb250cm9sbGVyICovCiAgICAvKiBGSVhNRTogbWlzc2luZyBOUyBTT05JQyBEUDgzOTMyICovCgogICAgLyogU0NTSSBhZGFwdGVyICovCiAgICAvKiBGSVhNRTogbWlzc2luZyBOQ1IgNTNDOTQgKi8KCiAgICAvKiBJU0EgZGV2aWNlcyAoZmxvcHB5LCBzZXJpYWwsIHBhcmFsbGVsKSAqLwogICAgZmRjdHJsX2luaXQoaTgyNTlbMV0sIDEsIDEsIDB4ODAwMDMwMDAsIGZkX3RhYmxlKTsKICAgIGZvcihpID0gMDsgaSA8IE1BWF9TRVJJQUxfUE9SVFM7IGkrKykgewogICAgICAgIGlmIChzZXJpYWxfaGRzW2ldKSB7CiAgICAgICAgICAgIHNlcmlhbF9tbV9pbml0KHNlcmlhbF9iYXNlW2ldLCAwLCBpODI1OVtzZXJpYWxfaXJxW2ldXSwgc2VyaWFsX2hkc1tpXSwgMSk7CiAgICAgICAgfQogICAgfQogICAgZm9yIChpID0gMDsgaSA8IE1BWF9QQVJBTExFTF9QT1JUUzsgaSsrKSB7CiAgICAgICAgaWYgKHBhcmFsbGVsX2hkc1tpXSkgewogICAgICAgICAgICAvKiBGSVhNRTogbWVtb3J5IG1hcHBlZCEgcGFyYWxsZWxfaW5pdCgweDgwMDA4MDAwLCBpODI1OVsxN10sIHBhcmFsbGVsX2hkc1tpXSk7ICovCiAgICAgICAgfQogICAgfQoKICAgIC8qIFNvdW5kIGNhcmQgKi8KICAgIC8qIEZJWE1FOiBtaXNzaW5nIEphenogc291bmQsIElSUSAxOCAqLwoKICAgIC8qIExFRCBpbmRpY2F0b3IgKi8KICAgIC8qIEZJWE1FOiBtaXNzaW5nIExFRCBpbmRpY2F0b3IgKi8KCiAgICAvKiBOVlJBTSAqLwogICAgZHMxMjI1eV9pbml0KDB4ODAwMDkwMDAsICJudnJhbSIpOwoKICAgIC8qIFZpZGVvIGNhcmQgKi8KICAgIC8qIEZJWE1FOiBUaGlzIGNhcmQgaXMgbm90IHRoZSByZWFsIG9uZSB3aGljaCB3YXMgaW4gdGhlIG9yaWdpbmFsIFBJQ0EsCiAgICAgKiBidXQgbGV0J3MgZG8gd2l0aCB3aGF0IFFlbXUgY3VycmVubHkgZW11bGF0ZXMuLi4gKi8KICAgIGlzYV92Z2FfbW1faW5pdChkcywgcGh5c19yYW1fYmFzZSArIHJhbV9zaXplLCByYW1fc2l6ZSwgdmdhX3JhbV9zaXplLAogICAgICAgICAgICAgICAgICAgIDB4NDAwMDAwMDAsIDB4NjAwMDAwMDAsIDApOwp9CgpRRU1VTWFjaGluZSBtaXBzX3BpY2E2MV9tYWNoaW5lID0gewogICAgInBpY2E2MSIsCiAgICAiQWNlciBQaWNhIDYxIiwKICAgIG1pcHNfcGljYTYxX2luaXQsCn07Cg==