LyoKICogUUVNVSBBY2VyIFBpY2EgTWFjaGluZSBzdXBwb3J0CiAqCiAqIENvcHlyaWdodCAoYykgMjAwNyBIZXJ26SBQb3Vzc2luZWF1CiAqCiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKICogaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cwogKiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCiAqIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcwogKiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgogKgogKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbgogKiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1IKICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMCiAqIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSCiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sCiAqIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4KICogVEhFIFNPRlRXQVJFLgogKi8KCiNpbmNsdWRlICJody5oIgojaW5jbHVkZSAibWlwcy5oIgojaW5jbHVkZSAiaXNhLmgiCiNpbmNsdWRlICJwYy5oIgojaW5jbHVkZSAiZmRjLmgiCiNpbmNsdWRlICJzeXNlbXUuaCIKI2luY2x1ZGUgImJvYXJkcy5oIgoKI2lmZGVmIFRBUkdFVF9XT1JEU19CSUdFTkRJQU4KI2RlZmluZSBCSU9TX0ZJTEVOQU1FICJtaXBzX2Jpb3MuYmluIgojZWxzZQojZGVmaW5lIEJJT1NfRklMRU5BTUUgIm1pcHNlbF9iaW9zLmJpbiIKI2VuZGlmCgojaWZkZWYgVEFSR0VUX01JUFM2NAojZGVmaW5lIFBIWVNfVE9fVklSVCh4KSAoKHgpIHwgfjB4N2ZmZmZmZmZVTEwpCiNlbHNlCiNkZWZpbmUgUEhZU19UT19WSVJUKHgpICgoeCkgfCB+MHg3ZmZmZmZmZlUpCiNlbmRpZgoKI2RlZmluZSBWSVJUX1RPX1BIWVNfQURERU5EICgtKChpbnQ2NF90KShpbnQzMl90KTB4ODAwMDAwMDApKQoKI2RlZmluZSBNQVhfSURFX0JVUyAyCiNkZWZpbmUgTUFYX0ZEIDIKCnN0YXRpYyBjb25zdCBpbnQgaWRlX2lvYmFzZVsyXSA9IHsgMHgxZjAsIDB4MTcwIH07CnN0YXRpYyBjb25zdCBpbnQgaWRlX2lvYmFzZTJbMl0gPSB7IDB4M2Y2LCAweDM3NiB9OwpzdGF0aWMgY29uc3QgaW50IGlkZV9pcnFbMl0gPSB7IDE0LCAxNSB9OwoKc3RhdGljIHVpbnQzMl90IHNlcmlhbF9iYXNlW01BWF9TRVJJQUxfUE9SVFNdID0geyAweDgwMDA2MDAwLCAweDgwMDA3MDAwIH07CnN0YXRpYyBpbnQgc2VyaWFsX2lycVtNQVhfU0VSSUFMX1BPUlRTXSA9IHsgOCwgOSB9OwoKZXh0ZXJuIEZJTEUgKmxvZ2ZpbGU7CgpzdGF0aWMgdm9pZCBtYWluX2NwdV9yZXNldCh2b2lkICpvcGFxdWUpCnsKICAgIENQVVN0YXRlICplbnYgPSBvcGFxdWU7CiAgICBjcHVfcmVzZXQoZW52KTsKfQoKc3RhdGljCnZvaWQgbWlwc19waWNhNjFfaW5pdCAoaW50IHJhbV9zaXplLCBpbnQgdmdhX3JhbV9zaXplLAogICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmJvb3RfZGV2aWNlLCBEaXNwbGF5U3RhdGUgKmRzLAogICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmtlcm5lbF9maWxlbmFtZSwgY29uc3QgY2hhciAqa2VybmVsX2NtZGxpbmUsCiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqaW5pdHJkX2ZpbGVuYW1lLCBjb25zdCBjaGFyICpjcHVfbW9kZWwpCnsKICAgIGNoYXIgYnVmWzEwMjRdOwogICAgdW5zaWduZWQgbG9uZyBiaW9zX29mZnNldDsKICAgIGludCBiaW9zX3NpemU7CiAgICBDUFVTdGF0ZSAqZW52OwogICAgaW50IGk7CiAgICBpbnQgYXZhaWxhYmxlX3JhbTsKICAgIHFlbXVfaXJxICppODI1OTsKICAgIGludCBpbmRleDsKICAgIEJsb2NrRHJpdmVyU3RhdGUgKmZkW01BWF9GRF07CgogICAgLyogaW5pdCBDUFVzICovCiAgICBpZiAoY3B1X21vZGVsID09IE5VTEwpIHsKI2lmZGVmIFRBUkdFVF9NSVBTNjQKICAgICAgICBjcHVfbW9kZWwgPSAiUjQwMDAiOwojZWxzZQogICAgICAgIC8qIEZJWE1FOiBBbGwgd3JvbmcsIHRoaXMgbWF5YmUgc2hvdWxkIGJlIFIzMDAwIGZvciB0aGUgb2xkZXIgUElDQXMuICovCiAgICAgICAgY3B1X21vZGVsID0gIjI0S2YiOwojZW5kaWYKICAgIH0KICAgIGVudiA9IGNwdV9pbml0KGNwdV9tb2RlbCk7CiAgICBpZiAoIWVudikgewogICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGZpbmQgQ1BVIGRlZmluaXRpb25cbiIpOwogICAgICAgIGV4aXQoMSk7CiAgICB9CiAgICByZWdpc3Rlcl9zYXZldm0oImNwdSIsIDAsIDMsIGNwdV9zYXZlLCBjcHVfbG9hZCwgZW52KTsKICAgIHFlbXVfcmVnaXN0ZXJfcmVzZXQobWFpbl9jcHVfcmVzZXQsIGVudik7CgogICAgLyogYWxsb2NhdGUgUkFNIChsaW1pdGVkIHRvIDI1NiBNQikgKi8KICAgIGlmIChyYW1fc2l6ZSA8IDI1NiAqIDEwMjQgKiAxMDI0KQogICAgICAgIGF2YWlsYWJsZV9yYW0gPSByYW1fc2l6ZTsKICAgIGVsc2UKICAgICAgICBhdmFpbGFibGVfcmFtID0gMjU2ICogMTAyNCAqIDEwMjQ7CiAgICBjcHVfcmVnaXN0ZXJfcGh5c2ljYWxfbWVtb3J5KDAsIGF2YWlsYWJsZV9yYW0sIElPX01FTV9SQU0pOwoKICAgIC8qIGxvYWQgYSBCSU9TIGltYWdlICovCiAgICBiaW9zX29mZnNldCA9IHJhbV9zaXplICsgdmdhX3JhbV9zaXplOwogICAgaWYgKGJpb3NfbmFtZSA9PSBOVUxMKQogICAgICAgIGJpb3NfbmFtZSA9IEJJT1NfRklMRU5BTUU7CiAgICBzbnByaW50ZihidWYsIHNpemVvZihidWYpLCAiJXMvJXMiLCBiaW9zX2RpciwgYmlvc19uYW1lKTsKICAgIGJpb3Nfc2l6ZSA9IGxvYWRfaW1hZ2UoYnVmLCBwaHlzX3JhbV9iYXNlICsgYmlvc19vZmZzZXQpOwogICAgaWYgKChiaW9zX3NpemUgPD0gMCkgfHwgKGJpb3Nfc2l6ZSA+IEJJT1NfU0laRSkpIHsKICAgICAgICAvKiBmYXRhbCAqLwogICAgICAgIGZwcmludGYoc3RkZXJyLCAicWVtdTogRXJyb3IsIGNvdWxkIG5vdCBsb2FkIE1JUFMgYmlvcyAnJXMnXG4iLAogICAgICAgICAgICAgICAgYnVmKTsKICAgICAgICBleGl0KDEpOwogICAgfQogICAgY3B1X3JlZ2lzdGVyX3BoeXNpY2FsX21lbW9yeSgweDFmYzAwMDAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQklPU19TSVpFLCBiaW9zX29mZnNldCB8IElPX01FTV9ST00pOwoKICAgIC8qIERldmljZSBtYXAKICAgICAqCiAgICAgKiBhZGRyIDB4ZTAwMDQwMDA6IG1jMTQ2ODE4CiAgICAgKiBhZGRyIDB4ZTAwMDUwMDAgaW50ciA2OiBwczIga2V5Ym9hcmQKICAgICAqIGFkZHIgMHhlMDAwNTAwMCBpbnRyIDc6IHBzMiBtb3VzZQogICAgICogYWRkciAweGUwMDA2MDAwIGludHIgODogbnMxNjU1MGEsCiAgICAgKiBhZGRyIDB4ZTAwMDcwMDAgaW50ciA5OiBuczE2NTUwYQogICAgICogaXNhX2lvX2Jhc2UgMHhlMjAwMDAwMCBpc2FfbWVtX2Jhc2UgMHhlMzAwMDAwMAogICAgICovCgogICAgLyogSW5pdCBDUFUgaW50ZXJuYWwgZGV2aWNlcyAqLwogICAgY3B1X21pcHNfaXJxX2luaXRfY3B1KGVudik7CiAgICBjcHVfbWlwc19jbG9ja19pbml0KGVudik7CiAgICBjcHVfbWlwc19pcnFjdHJsX2luaXQoKTsKCiAgICAvKiBSZWdpc3RlciA2NCBLQiBvZiBJU0EgSU8gc3BhY2UgYXQgMHgxMDAwMDAwMCAqLwogICAgaXNhX21taW9faW5pdCgweDEwMDAwMDAwLCAweDAwMDEwMDAwKTsKICAgIGlzYV9tZW1fYmFzZSA9IDB4MTEwMDAwMDA7CgogICAgLyogUEMgc3R5bGUgSVJRIChpODI1OS9pODI1NCkgYW5kIERNQSAoaTgyNTcpICovCiAgICAvKiBUaGUgUElDIGlzIGF0dGFjaGVkIHRvIHRoZSBNSVBTIENQVSBJTlQwIHBpbiAqLwogICAgaTgyNTkgPSBpODI1OV9pbml0KGVudi0+aXJxWzJdKTsKICAgIHJ0Y19tbV9pbml0KDB4ODAwMDQwNzAsIDEsIGk4MjU5WzE0XSk7CiAgICBwaXRfaW5pdCgweDQwLCAwKTsKCiAgICAvKiBLZXlib2FyZCAoaTgwNDIpICovCiAgICBpODA0Ml9tbV9pbml0KGk4MjU5WzZdLCBpODI1OVs3XSwgMHg4MDAwNTA2MCwgMCk7CgogICAgLyogSURFIGNvbnRyb2xsZXIgKi8KCiAgICBpZiAoZHJpdmVfZ2V0X21heF9idXMoSUZfSURFKSA+PSBNQVhfSURFX0JVUykgewogICAgICAgIGZwcmludGYoc3RkZXJyLCAicWVtdTogdG9vIG1hbnkgSURFIGJ1c1xuIik7CiAgICAgICAgZXhpdCgxKTsKICAgIH0KCiAgICBmb3IoaSA9IDA7IGkgPCBNQVhfSURFX0JVUzsgaSsrKSB7CiAgICAgICAgaW50IGhkMCwgaGQxOwogICAgICAgIGhkMCA9IGRyaXZlX2dldF9pbmRleChJRl9JREUsIGksIDApOwogICAgICAgIGhkMSA9IGRyaXZlX2dldF9pbmRleChJRl9JREUsIGksIDEpOwogICAgICAgIGlzYV9pZGVfaW5pdChpZGVfaW9iYXNlW2ldLCBpZGVfaW9iYXNlMltpXSwgaTgyNTlbaWRlX2lycVtpXV0sCiAgICAgICAgICAgICAgICAgICAgIGhkMCA9PSAtMSA/IE5VTEwgOiBkcml2ZXNfdGFibGVbaGQwXS5iZHJ2LAogICAgICAgICAgICAgICAgICAgICBoZDEgPT0gLTEgPyBOVUxMIDogZHJpdmVzX3RhYmxlW2hkMV0uYmRydik7CiAgICB9CgogICAgLyogTmV0d29yayBjb250cm9sbGVyICovCiAgICAvKiBGSVhNRTogbWlzc2luZyBOUyBTT05JQyBEUDgzOTMyICovCgogICAgLyogU0NTSSBhZGFwdGVyICovCiAgICAvKiBGSVhNRTogbWlzc2luZyBOQ1IgNTNDOTQgKi8KCiAgICAvKiBJU0EgZGV2aWNlcyAoZmxvcHB5LCBzZXJpYWwsIHBhcmFsbGVsKSAqLwoKICAgIGZvciAoaSA9IDA7IGkgPCBNQVhfRkQ7IGkrKykgewogICAgICAgIGluZGV4ID0gZHJpdmVfZ2V0X2luZGV4KElGX0ZMT1BQWSwgMCwgaSk7CiAgICAgICAgaWYgKGluZGV4ID09IC0xKQogICAgICAgICAgICBmZFtpXSA9IE5VTEw7CiAgICAgICAgZWxzZQogICAgICAgICAgICBmZFtpXSA9IGRyaXZlc190YWJsZVtpbmRleF0uYmRydjsKICAgIH0KICAgIGZkY3RybF9pbml0KGk4MjU5WzFdLCAxLCAxLCAweDgwMDAzMDAwLCBmZCk7CiAgICBmb3IoaSA9IDA7IGkgPCBNQVhfU0VSSUFMX1BPUlRTOyBpKyspIHsKICAgICAgICBpZiAoc2VyaWFsX2hkc1tpXSkgewogICAgICAgICAgICBzZXJpYWxfbW1faW5pdChzZXJpYWxfYmFzZVtpXSwgMCwgaTgyNTlbc2VyaWFsX2lycVtpXV0sIHNlcmlhbF9oZHNbaV0sIDEpOwogICAgICAgIH0KICAgIH0KICAgIC8qIFBhcmFsbGVsIHBvcnQgKi8KICAgIGlmIChwYXJhbGxlbF9oZHNbMF0pIHBhcmFsbGVsX21tX2luaXQoMHg4MDAwODAwMCwgMCwgaTgyNTlbMV0sIHBhcmFsbGVsX2hkc1swXSk7CgogICAgLyogU291bmQgY2FyZCAqLwogICAgLyogRklYTUU6IG1pc3NpbmcgSmF6eiBzb3VuZCwgSVJRIDE4ICovCgogICAgLyogTEVEIGluZGljYXRvciAqLwogICAgLyogRklYTUU6IG1pc3NpbmcgTEVEIGluZGljYXRvciAqLwoKICAgIC8qIE5WUkFNICovCiAgICBkczEyMjV5X2luaXQoMHg4MDAwOTAwMCwgIm52cmFtIik7CgogICAgLyogVmlkZW8gY2FyZCAqLwogICAgLyogRklYTUU6IFRoaXMgY2FyZCBpcyBub3QgdGhlIHJlYWwgb25lIHdoaWNoIHdhcyBpbiB0aGUgb3JpZ2luYWwgUElDQSwKICAgICAqIGJ1dCBsZXQncyBkbyB3aXRoIHdoYXQgUWVtdSBjdXJyZW5seSBlbXVsYXRlcy4uLiAqLwogICAgaXNhX3ZnYV9tbV9pbml0KGRzLCBwaHlzX3JhbV9iYXNlICsgcmFtX3NpemUsIHJhbV9zaXplLCB2Z2FfcmFtX3NpemUsCiAgICAgICAgICAgICAgICAgICAgMHg0MDAwMDAwMCwgMHg2MDAwMDAwMCwgMCk7CgogICAgLyogTEVEIGluZGljYXRvciAqLwogICAgamF6el9sZWRfaW5pdChkcywgMHg4MDAwZjAwMCk7Cn0KClFFTVVNYWNoaW5lIG1pcHNfcGljYTYxX21hY2hpbmUgPSB7CiAgICAicGljYTYxIiwKICAgICJBY2VyIFBpY2EgNjEiLAogICAgbWlwc19waWNhNjFfaW5pdCwKfTsK