LyoKICogQ29weXJpZ2h0IDE5OTUgTWFydGluIHZvbiBMb2V3aXMKICogQ29weXJpZ2h0IDE5OTggSnVzdGluIEJyYWRmb3JkCiAqIENvcHlyaWdodCAxOTk5IEZyYW5jaXMgQmVhdWRldAogKiBDb3B5cmlnaHQgMTk5OSBTeWx2YWluIFN0LUdlcm1haW4KICogQ29weXJpZ2h0IDIwMDIgTWFyY3VzIE1laXNzbmVyCiAqIENvcHlyaWdodCAyMDAzIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzCiAqIENvcHlyaWdodCAyMDA0IE1pa2UgSGVhcm4sIFJvYiBTaGVhcm1hbiwgQ29kZVdlYXZlcnMgSW5jCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpZm5kZWYgX19XSU5FX09MRV9DT01QT0JKX0gKI2RlZmluZSBfX1dJTkVfT0xFX0NPTVBPQkpfSAoKLyogQWxsIHByaXZhdGUgcHJvdG90eXBlIGZ1bmN0aW9ucyB1c2VkIGJ5IE9MRSB3aWxsIGJlIGFkZGVkIHRvIHRoaXMgaGVhZGVyIGZpbGUgKi8KCiNpbmNsdWRlIDxzdGRhcmcuaD4KCiNpbmNsdWRlICJ3aW5lL2xpc3QuaCIKCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgInd0eXBlcy5oIgojaW5jbHVkZSAiZGNvbS5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW50ZXJubC5oIgoKc3RydWN0IGFwYXJ0bWVudDsKdHlwZWRlZiBzdHJ1Y3QgYXBhcnRtZW50IEFQQVJUTUVOVDsKCkRFRklORV9PTEVHVUlEKCBDTFNJRF9EZk1hcnNoYWwsIDB4MDAwMDAzMGIsIDAsIDAgKTsKREVGSU5FX09MRUdVSUQoIENMU0lEX1BTRmFjdG9yeUJ1ZmZlciwgMHgwMDAwMDMyMCwgMCwgMCApOwoKLyogc2lnbmFsIHRvIHN0dWIgbWFuYWdlciB0aGF0IHRoaXMgaXMgYSByZW0gdW5rbm93biBvYmplY3QgKi8KI2RlZmluZSBNU0hMRkxBR1NQX1JFTVVOS05PV04gICAweDgwMDAwMDAwCgovKiBUaHJlYWQtc2FmZXR5IEFubm90YXRpb24gTGVnZW5kOgogKgogKiBSTyAgICAtIFRoZSB2YWx1ZSBpcyByZWFkIG9ubHkuIEl0IG5ldmVyIGNoYW5nZXMgYWZ0ZXIgY3JlYXRpb24sIHNvIG5vCiAqICAgICAgICAgbG9ja2luZyBpcyByZXF1aXJlZC4KICogTE9DSyAgLSBUaGUgdmFsdWUgaXMgd3JpdHRlbiB0byBvbmx5IHVzaW5nIEludGVybG9ja2VkKiBmdW5jdGlvbnMuCiAqIENTICAgIC0gVGhlIHZhbHVlIGlzIHJlYWQgb3Igd3JpdHRlbiB0byBpbnNpZGUgYSBjcml0aWNhbCBzZWN0aW9uLgogKiAgICAgICAgIFRoZSBpZGVudGlmaWVyIGZvbGxvd2luZyAiQ1MiIGlzIHRoZSBzcGVjaWZpYyBjcml0aWNhbCBzZWN0aW9uIHRoYXQKICogICAgICAgICBtdXN0IGJlIHVzZWQuCiAqIE1VVEVYIC0gVGhlIHZhbHVlIGlzIHJlYWQgb3Igd3JpdHRlbiB0byB3aXRoIGEgbXV0ZXggaGVsZC4KICogICAgICAgICBUaGUgaWRlbnRpZmllciBmb2xsb3dpbmcgIk1VVEVYIiBpcyB0aGUgc3BlY2lmaWMgbXV0ZXggdGhhdAogKiAgICAgICAgIG11c3QgYmUgdXNlZC4KICovCgp0eXBlZGVmIGVudW0gaWZzdHViX3N0YXRlCnsKICAgIFNUVUJTVEFURV9OT1JNQUxfTUFSU0hBTEVELAogICAgU1RVQlNUQVRFX05PUk1BTF9VTk1BUlNIQUxFRCwKICAgIFNUVUJTVEFURV9UQUJMRV9XRUFLX01BUlNIQUxFRCwKICAgIFNUVUJTVEFURV9UQUJMRV9XRUFLX1VOTUFSU0hBTEVELAogICAgU1RVQlNUQVRFX1RBQkxFX1NUUk9ORywKfSBTVFVCX1NUQVRFOwoKLyogYW4gaW50ZXJmYWNlIHN0dWIgKi8Kc3RydWN0IGlmc3R1YiAgIAp7CiAgICBzdHJ1Y3QgbGlzdCAgICAgICBlbnRyeTsgICAgICAvKiBlbnRyeSBpbiBzdHViX21hbmFnZXItPmlmc3R1YnMgbGlzdCAoQ1Mgc3R1Yl9tYW5hZ2VyLT5sb2NrKSAqLwogICAgSVJwY1N0dWJCdWZmZXIgICAqc3R1YmJ1ZmZlcjsgLyogUk8gKi8KICAgIElJRCAgICAgICAgICAgICAgIGlpZDsgICAgICAgIC8qIFJPICovCiAgICBJUElEICAgICAgICAgICAgICBpcGlkOyAgICAgICAvKiBSTyAqLwogICAgSVVua25vd24gICAgICAgICAqaWZhY2U7ICAgICAgLyogUk8gKi8KICAgIE1TSExGTEFHUyAgICAgICAgIGZsYWdzOyAgICAgIC8qIHNvIHdlIGNhbiBlbmZvcmNlIHByb2Nlc3MtbG9jYWwgbWFyc2hhbGxpbmcgcnVsZXMgKFJPKSAqLwogICAgSVJwY0NoYW5uZWxCdWZmZXIqY2hhbjsgICAgICAgLyogY2hhbm5lbCBwYXNzZWQgdG8gSVJwY1N0dWJCdWZmZXI6Okludm9rZSAoUk8pICovCn07CgoKLyogc3R1YiBtYW5hZ2VycyBob2xkIHJlZnMgb24gdGhlIG9iamVjdCBhbmQgZWFjaCBpbnRlcmZhY2Ugc3R1YiAqLwpzdHJ1Y3Qgc3R1Yl9tYW5hZ2VyCnsKICAgIHN0cnVjdCBsaXN0ICAgICAgIGVudHJ5OyAgICAgIC8qIGVudHJ5IGluIGFwYXJ0bWVudCBzdHVibWdyIGxpc3QgKENTIGFwdC0+Y3MpICovCiAgICBzdHJ1Y3QgbGlzdCAgICAgICBpZnN0dWJzOyAgICAvKiBsaXN0IG9mIGFjdGl2ZSBpZnN0dWJzIGZvciB0aGUgb2JqZWN0IChDUyBsb2NrKSAqLwogICAgQ1JJVElDQUxfU0VDVElPTiAgbG9jazsKICAgIEFQQVJUTUVOVCAgICAgICAgKmFwdDsgICAgICAgIC8qIG93bmluZyBhcHQgKFJPKSAqLwoKICAgIFVMT05HICAgICAgICAgICAgIGV4dHJlZnM7ICAgIC8qIG51bWJlciBvZiAnZXh0ZXJuYWwnIHJlZmVyZW5jZXMgKENTIGxvY2spICovCiAgICBVTE9ORyAgICAgICAgICAgICByZWZzOyAgICAgICAvKiBpbnRlcm5hbCByZWZlcmVuY2UgY291bnQgKENTIGFwdC0+Y3MpICovCiAgICBVTE9ORyAgICAgICAgICAgICB3ZWFrcmVmczsgICAvKiBudW1iZXIgb2Ygd2VhayByZWZlcmVuY2VzIChDUyBsb2NrKSAqLwogICAgT0lEICAgICAgICAgICAgICAgb2lkOyAgICAgICAgLyogYXBhcnRtZW50LXNjb3BlZCB1bmlxdWUgaWRlbnRpZmllciAoUk8pICovCiAgICBJVW5rbm93biAgICAgICAgICpvYmplY3Q7ICAgICAvKiB0aGUgb2JqZWN0IHdlIGFyZSBtYW5hZ2luZyB0aGUgc3R1YiBmb3IgKFJPKSAqLwogICAgVUxPTkcgICAgICAgICAgICAgbmV4dF9pcGlkOyAgLyogY3VycmVudGx5IHVudXNlZCAoTE9DSykgKi8KICAgIE9YSURfSU5GTyAgICAgICAgIG94aWRfaW5mbzsgIC8qIHN0cmluZyBiaW5kaW5nLCBpcGlkIG9mIHJlbSB1bmtub3duIGFuZCBvdGhlciBpbmZvcm1hdGlvbiAoUk8pICovCgogICAgLyogV2UgbmVlZCB0byBrZWVwIGEgY291bnQgb2YgdGhlIG91dHN0YW5kaW5nIG1hcnNoYWxzLCBzbyB3ZSBjYW4gZW5mb3JjZSB0aGUKICAgICAqIG1hcnNoYWxsaW5nIHJ1bGVzIChpZSwgeW91IGNhbiBvbmx5IHVubWFyc2hhbCBub3JtYWwgbWFyc2hhbHMgb25jZSkuIE5vdGUKICAgICAqIHRoYXQgdGhlc2UgY291bnRzIGRvIE5PVCBpbmNsdWRlIHVubWFyc2hhbGxlZCBpbnRlcmZhY2VzLCBvbmNlIGEgc3RyZWFtIGlzCiAgICAgKiB1bm1hcnNoYWxsZWQgYW5kIGEgcHJveHkgc2V0IHVwLCB0aGlzIGNvdW50IGlzIGRlY3JlbWVudGVkLgogICAgICovCgogICAgVUxPTkcgICAgICAgICAgICAgbm9ybV9yZWZzOyAgLyogcmVmY291bnQgb2Ygbm9ybWFsIG1hcnNoYWxzIChDUyBsb2NrKSAqLwp9OwoKLyogaW1wb3J0ZWQgaW50ZXJmYWNlIHByb3h5ICovCnN0cnVjdCBpZnByb3h5CnsKICBzdHJ1Y3QgbGlzdCBlbnRyeTsgICAgICAgLyogZW50cnkgaW4gcHJveHlfbWFuYWdlciBsaXN0IChDUyBwYXJlbnQtPmNzKSAqLwogIHN0cnVjdCBwcm94eV9tYW5hZ2VyICpwYXJlbnQ7IC8qIG93bmluZyBwcm94eV9tYW5hZ2VyIChSTykgKi8KICBMUFZPSUQgaWZhY2U7ICAgICAgICAgICAgLyogaW50ZXJmYWNlIHBvaW50ZXIgKFJPKSAqLwogIFNURE9CSlJFRiBzdGRvYmpyZWY7ICAgICAvKiBtYXJzaGFsIGRhdGEgdGhhdCByZXByZXNlbnRzIHRoaXMgb2JqZWN0IChSTykgKi8KICBJSUQgaWlkOyAgICAgICAgICAgICAgICAgLyogaW50ZXJmYWNlIElEIChSTykgKi8KICBMUFJQQ1BST1hZQlVGRkVSIHByb3h5OyAgLyogaW50ZXJmYWNlIHByb3h5IChSTykgKi8KICBVTE9ORyByZWZzOyAgICAgICAgICAgICAgLyogaW1wb3J0ZWQgKHB1YmxpYykgcmVmZXJlbmNlcyAoTE9DSykgKi8KICBJUnBjQ2hhbm5lbEJ1ZmZlciAqY2hhbjsgLyogY2hhbm5lbCB0byBvYmplY3QgKENTIHBhcmVudC0+Y3MpICovCn07CgovKiBpbXBvcnRlZCBvYmplY3QgLyBwcm94eSBtYW5hZ2VyICovCnN0cnVjdCBwcm94eV9tYW5hZ2VyCnsKICBjb25zdCBJTXVsdGlRSVZ0YmwgKmxwVnRibDsKICBjb25zdCBJTWFyc2hhbFZ0YmwgKmxwVnRibE1hcnNoYWw7CiAgY29uc3QgSUNsaWVudFNlY3VyaXR5VnRibCAqbHBWdGJsQ2xpU2VjOwogIHN0cnVjdCBhcGFydG1lbnQgKnBhcmVudDsgLyogb3duaW5nIGFwYXJ0bWVudCAoUk8pICovCiAgc3RydWN0IGxpc3QgZW50cnk7ICAgICAgICAvKiBlbnRyeSBpbiBhcGFydG1lbnQgKENTIHBhcmVudC0+Y3MpICovCiAgT1hJRCBveGlkOyAgICAgICAgICAgICAgICAvKiBvYmplY3QgZXhwb3J0ZWQgSUQgKFJPKSAqLwogIE9YSURfSU5GTyBveGlkX2luZm87ICAgICAgLyogc3RyaW5nIGJpbmRpbmcsIGlwaWQgb2YgcmVtIHVua25vd24gYW5kIG90aGVyIGluZm9ybWF0aW9uIChSTykgKi8KICBPSUQgb2lkOyAgICAgICAgICAgICAgICAgIC8qIG9iamVjdCBJRCAoUk8pICovCiAgc3RydWN0IGxpc3QgaW50ZXJmYWNlczsgICAvKiBpbXBvcnRlZCBpbnRlcmZhY2VzIChDUyBjcykgKi8KICBMT05HIHJlZnM7ICAgICAgICAgICAgICAgIC8qIHByb3h5IHJlZmVyZW5jZSBjb3VudCAoTE9DSykgKi8KICBDUklUSUNBTF9TRUNUSU9OIGNzOyAgICAgIC8qIHRocmVhZCBzYWZldHkgZm9yIHRoaXMgb2JqZWN0IGFuZCBjaGlsZHJlbiAqLwogIFVMT05HIHNvcmZsYWdzOyAgICAgICAgICAgLyogU1RET0JKUkVGIGZsYWdzIChSTykgKi8KICBJUmVtVW5rbm93biAqcmVtdW5rOyAgICAgIC8qIHByb3h5IHRvIElSZW1Vbmtub3duIHVzZWQgZm9yIGxpZmVjeWNsZSBtYW5hZ2VtZW50IChDUyBjcykgKi8KICBIQU5ETEUgcmVtb3RpbmdfbXV0ZXg7ICAgIC8qIG11dGV4IHVzZWQgZm9yIHN5bmNocm9uaXppbmcgYWNjZXNzIHRvIElSZW1Vbmtub3duICovCiAgTVNIQ1RYIGRlc3RfY29udGV4dDsgICAgICAvKiBjb250ZXh0IHVzZWQgZm9yIGFjdGl2YXRpbmcgb3B0aW1pc2F0aW9ucyAoTE9DSykgKi8KICB2b2lkICpkZXN0X2NvbnRleHRfZGF0YTsgIC8qIHJlc2VydmVkIGNvbnRleHQgdmFsdWUgKExPQ0spICovCn07CgpzdHJ1Y3QgYXBhcnRtZW50CnsKICBzdHJ1Y3QgbGlzdCBlbnRyeTsKCiAgTE9ORyAgcmVmczsgICAgICAgICAgICAgIC8qIHJlZmNvdW50IG9mIHRoZSBhcGFydG1lbnQgKExPQ0spICovCiAgQk9PTCBtdWx0aV90aHJlYWRlZDsgICAgIC8qIG11bHRpLXRocmVhZGVkIG9yIHNpbmdsZS10aHJlYWRlZCBhcGFydG1lbnQ/IChSTykgKi8KICBEV09SRCB0aWQ7ICAgICAgICAgICAgICAgLyogdGhyZWFkIGlkIChSTykgKi8KICBPWElEIG94aWQ7ICAgICAgICAgICAgICAgLyogb2JqZWN0IGV4cG9ydGVyIElEIChSTykgKi8KICBMT05HIGlwaWRjOyAgICAgICAgICAgICAgLyogaW50ZXJmYWNlIHBvaW50ZXIgSUQgY291bnRlciwgc3RhcnRzIGF0IDEgKExPQ0spICovCiAgQ1JJVElDQUxfU0VDVElPTiBjczsgICAgIC8qIHRocmVhZCBzYWZldHkgKi8KICBzdHJ1Y3QgbGlzdCBwcm94aWVzOyAgICAgLyogaW1wb3J0ZWQgb2JqZWN0cyAoQ1MgY3MpICovCiAgc3RydWN0IGxpc3Qgc3R1Ym1ncnM7ICAgIC8qIHN0dWIgbWFuYWdlcnMgZm9yIGV4cG9ydGVkIG9iamVjdHMgKENTIGNzKSAqLwogIEJPT0wgcmVtdW5rX2V4cG9ydGVkOyAgICAvKiBoYXMgdGhlIElSZW1Vbmtub3duIGludGVyZmFjZSBmb3IgdGhpcyBhcGFydG1lbnQgYmVlbiBjcmVhdGVkIHlldD8gKENTIGNzKSAqLwogIExPTkcgcmVtb3Rpbmdfc3RhcnRlZDsgICAvKiBoYXMgdGhlIFJQQyBzeXN0ZW0gYmVlbiBzdGFydGVkIGZvciB0aGlzIGFwYXJ0bWVudD8gKExPQ0spICovCiAgc3RydWN0IGxpc3QgcHNjbHNpZHM7ICAgIC8qIGxpc3Qgb2YgcmVnaXN0ZXJlZCBQUyBDTFNJRHMgKENTIGNzKSAqLwogIHN0cnVjdCBsaXN0IGxvYWRlZF9kbGxzOyAvKiBsaXN0IG9mIGRsbHMgbG9hZGVkIGJ5IHRoaXMgYXBhcnRtZW50IChDUyBjcykgKi8KICBEV09SRCBob3N0X2FwdF90aWQ7ICAgICAgLyogdGhyZWFkIElEIG9mIGFwYXJ0bWVudCBob3N0aW5nIG9iamVjdHMgb2YgZGlmZmVyaW5nIHRocmVhZGluZyBtb2RlbCAoQ1MgY3MpICovCiAgSFdORCBob3N0X2FwdF9od25kOyAgICAgIC8qIGhhbmRsZSB0byBhcGFydG1lbnQgd2luZG93IG9mIGhvc3QgYXBhcnRtZW50IChDUyBjcykgKi8KCiAgLyogRklYTUU6IE9JRCdzIHNob3VsZCBiZSBnaXZlbiBvdXQgYnkgUlBDU1MgKi8KICBPSUQgb2lkYzsgICAgICAgICAgICAgICAgLyogb2JqZWN0IElEIGNvdW50ZXIsIHN0YXJ0cyBhdCAxLCB6ZXJvIGlzIGludmFsaWQgT0lEIChDUyBjcykgKi8KCiAgLyogU1RBLW9ubHkgZmllbGRzICovCiAgSFdORCB3aW47ICAgICAgICAgICAgICAgIC8qIG1lc3NhZ2Ugd2luZG93IChMT0NLKSAqLwogIExQTUVTU0FHRUZJTFRFUiBmaWx0ZXI7ICAvKiBtZXNzYWdlIGZpbHRlciAoQ1MgY3MpICovCiAgQk9PTCBtYWluOyAgICAgICAgICAgICAgIC8qIGlzIHRoaXMgYSBtYWluLXRocmVhZGVkLWFwYXJ0bWVudD8gKFJPKSAqLwp9OwoKLyogdGhpcyBpcyB3aGF0IGlzIHN0b3JlZCBpbiBURUItPlJlc2VydmVkRm9yT2xlICovCnN0cnVjdCBvbGV0bHMKewogICAgc3RydWN0IGFwYXJ0bWVudCAqYXB0OwogICAgSUVycm9ySW5mbyAgICAgICAqZXJyb3JpbmZvOyAgIC8qIHNlZSBlcnJvcmluZm8uYyAqLwogICAgSVVua25vd24gICAgICAgICAqc3RhdGU7ICAgICAgIC8qIHNlZSBDb1NldFN0YXRlICovCiAgICBEV09SRCAgICAgICAgICAgIGluaXRzOyAgICAgICAgLyogbnVtYmVyIG9mIHRpbWVzIENvSW5pdGlhbGl6ZUV4IGNhbGxlZCAqLwogICAgRFdPUkQgICAgICAgICAgICBvbGVfaW5pdHM7ICAgIC8qIG51bWJlciBvZiB0aW1lcyBPbGVJbml0aWFsaXplIGNhbGxlZCAqLwogICAgR1VJRCAgICAgICAgICAgICBjYXVzYWxpdHlfaWQ7IC8qIHVuaXF1ZSBpZGVudGlmaWVyIGZvciBlYWNoIENPTSBjYWxsICovCiAgICBMT05HICAgICAgICAgICAgIHBlbmRpbmdfY2FsbF9jb3VudF9jbGllbnQ7IC8qIG51bWJlciBvZiBjbGllbnQgY2FsbHMgcGVuZGluZyAqLwogICAgTE9ORyAgICAgICAgICAgICBwZW5kaW5nX2NhbGxfY291bnRfc2VydmVyOyAvKiBudW1iZXIgb2Ygc2VydmVyIGNhbGxzIHBlbmRpbmcgKi8KfTsKCgovKiBHbG9iYWwgSW50ZXJmYWNlIFRhYmxlIEZ1bmN0aW9ucyAqLwoKZXh0ZXJuIHZvaWQqIFN0ZEdsb2JhbEludGVyZmFjZVRhYmxlX0NvbnN0cnVjdCh2b2lkKTsKZXh0ZXJuIEhSRVNVTFQgU3RkR2xvYmFsSW50ZXJmYWNlVGFibGVfR2V0RmFjdG9yeShMUFZPSUQgKnBwdik7CmV4dGVybiB2b2lkKiBTdGRHbG9iYWxJbnRlcmZhY2VUYWJsZUluc3RhbmNlOwoKLyogRklYTUU6IHRoZXNlIHNob3VsZG4ndCBiZSBuZWVkZWQsIGV4Y2VwdCBmb3IgMTYtYml0IGZ1bmN0aW9ucyAqLwpleHRlcm4gSFJFU1VMVCBXSU5FX1N0cmluZ0Zyb21DTFNJRChjb25zdCBDTFNJRCAqaWQsTFBTVFIgaWRzdHIpOwoKSFJFU1VMVCBDT01fT3BlbktleUZvckNMU0lEKFJFRkNMU0lEIGNsc2lkLCBMUENXU1RSIGtleW5hbWUsIFJFR1NBTSBhY2Nlc3MsIEhLRVkgKmtleSk7CkhSRVNVTFQgQ09NX09wZW5LZXlGb3JBcHBJZEZyb21DTFNJRChSRUZDTFNJRCBjbHNpZCwgUkVHU0FNIGFjY2VzcywgSEtFWSAqc3Via2V5KTsKSFJFU1VMVCBNQVJTSEFMX0dldFN0YW5kYXJkTWFyc2hhbENGKExQVk9JRCAqcHB2KTsKSFJFU1VMVCBGVE1hcnNoYWxDRl9DcmVhdGUoUkVGSUlEIHJpaWQsIExQVk9JRCAqcHB2KTsKCi8qIFN0dWIgTWFuYWdlciAqLwoKVUxPTkcgc3R1Yl9tYW5hZ2VyX2ludF9hZGRyZWYoc3RydWN0IHN0dWJfbWFuYWdlciAqVGhpcyk7ClVMT05HIHN0dWJfbWFuYWdlcl9pbnRfcmVsZWFzZShzdHJ1Y3Qgc3R1Yl9tYW5hZ2VyICpUaGlzKTsKc3RydWN0IHN0dWJfbWFuYWdlciAqbmV3X3N0dWJfbWFuYWdlcihBUEFSVE1FTlQgKmFwdCwgSVVua25vd24gKm9iamVjdCk7ClVMT05HIHN0dWJfbWFuYWdlcl9leHRfYWRkcmVmKHN0cnVjdCBzdHViX21hbmFnZXIgKm0sIFVMT05HIHJlZnMsIEJPT0wgdGFibGV3ZWFrKTsKVUxPTkcgc3R1Yl9tYW5hZ2VyX2V4dF9yZWxlYXNlKHN0cnVjdCBzdHViX21hbmFnZXIgKm0sIFVMT05HIHJlZnMsIEJPT0wgdGFibGV3ZWFrLCBCT09MIGxhc3RfdW5sb2NrX3JlbGVhc2VzKTsKc3RydWN0IGlmc3R1YiAqc3R1Yl9tYW5hZ2VyX25ld19pZnN0dWIoc3RydWN0IHN0dWJfbWFuYWdlciAqbSwgSVJwY1N0dWJCdWZmZXIgKnNiLCBJVW5rbm93biAqaXB0ciwgUkVGSUlEIGlpZCwgTVNITEZMQUdTIGZsYWdzKTsKc3RydWN0IGlmc3R1YiAqc3R1Yl9tYW5hZ2VyX2ZpbmRfaWZzdHViKHN0cnVjdCBzdHViX21hbmFnZXIgKm0sIFJFRklJRCBpaWQsIE1TSExGTEFHUyBmbGFncyk7CnN0cnVjdCBzdHViX21hbmFnZXIgKmdldF9zdHViX21hbmFnZXIoQVBBUlRNRU5UICphcHQsIE9JRCBvaWQpOwpzdHJ1Y3Qgc3R1Yl9tYW5hZ2VyICpnZXRfc3R1Yl9tYW5hZ2VyX2Zyb21fb2JqZWN0KEFQQVJUTUVOVCAqYXB0LCB2b2lkICpvYmplY3QpOwpCT09MIHN0dWJfbWFuYWdlcl9ub3RpZnlfdW5tYXJzaGFsKHN0cnVjdCBzdHViX21hbmFnZXIgKm0sIGNvbnN0IElQSUQgKmlwaWQpOwpCT09MIHN0dWJfbWFuYWdlcl9pc190YWJsZV9tYXJzaGFsZWQoc3RydWN0IHN0dWJfbWFuYWdlciAqbSwgY29uc3QgSVBJRCAqaXBpZCk7CnZvaWQgc3R1Yl9tYW5hZ2VyX3JlbGVhc2VfbWFyc2hhbF9kYXRhKHN0cnVjdCBzdHViX21hbmFnZXIgKm0sIFVMT05HIHJlZnMsIGNvbnN0IElQSUQgKmlwaWQsIEJPT0wgdGFibGV3ZWFrKTsKSFJFU1VMVCBpcGlkX3RvX3N0dWJfbWFuYWdlcihjb25zdCBJUElEICppcGlkLCBBUEFSVE1FTlQgKipzdHViX2FwdCwgc3RydWN0IHN0dWJfbWFuYWdlciAqKnN0dWJtZ3JfcmV0KTsKSFJFU1VMVCBpcGlkX2dldF9kaXNwYXRjaF9wYXJhbXMoY29uc3QgSVBJRCAqaXBpZCwgQVBBUlRNRU5UICoqc3R1Yl9hcHQsIElScGNTdHViQnVmZmVyICoqc3R1YiwgSVJwY0NoYW5uZWxCdWZmZXIgKipjaGFuLCBJSUQgKmlpZCwgSVVua25vd24gKippZmFjZSk7CkhSRVNVTFQgc3RhcnRfYXBhcnRtZW50X3JlbW90ZV91bmtub3duKHZvaWQpOwoKSFJFU1VMVCBtYXJzaGFsX29iamVjdChBUEFSVE1FTlQgKmFwdCwgU1RET0JKUkVGICpzdGRvYmpyZWYsIFJFRklJRCByaWlkLCBJVW5rbm93biAqb2JqLCBNU0hMRkxBR1MgbXNobGZsYWdzKTsKCi8qIFJQQyBCYWNrZW5kICovCgpzdHJ1Y3QgZGlzcGF0Y2hfcGFyYW1zOwoKdm9pZCAgICBSUENfU3RhcnRSZW1vdGluZyhzdHJ1Y3QgYXBhcnRtZW50ICphcHQpOwpIUkVTVUxUIFJQQ19DcmVhdGVDbGllbnRDaGFubmVsKGNvbnN0IE9YSUQgKm94aWQsIGNvbnN0IElQSUQgKmlwaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgT1hJRF9JTkZPICpveGlkX2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZGVzdF9jb250ZXh0LCB2b2lkICpkZXN0X2NvbnRleHRfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJUnBjQ2hhbm5lbEJ1ZmZlciAqKmNoYW4pOwpIUkVTVUxUIFJQQ19DcmVhdGVTZXJ2ZXJDaGFubmVsKElScGNDaGFubmVsQnVmZmVyICoqY2hhbik7CnZvaWQgICAgUlBDX0V4ZWN1dGVDYWxsKHN0cnVjdCBkaXNwYXRjaF9wYXJhbXMgKnBhcmFtcyk7CkhSRVNVTFQgUlBDX1JlZ2lzdGVySW50ZXJmYWNlKFJFRklJRCByaWlkKTsKdm9pZCAgICBSUENfVW5yZWdpc3RlckludGVyZmFjZShSRUZJSUQgcmlpZCk7CkhSRVNVTFQgUlBDX1N0YXJ0TG9jYWxTZXJ2ZXIoUkVGQ0xTSUQgY2xzaWQsIElTdHJlYW0gKnN0cmVhbSwgQk9PTCBtdWx0aV91c2UsIHZvaWQgKipyZWdpc3RyYXRpb24pOwp2b2lkICAgIFJQQ19TdG9wTG9jYWxTZXJ2ZXIodm9pZCAqcmVnaXN0cmF0aW9uKTsKSFJFU1VMVCBSUENfR2V0TG9jYWxDbGFzc09iamVjdChSRUZDTFNJRCByY2xzaWQsIFJFRklJRCBpaWQsIExQVk9JRCAqcHB2KTsKSFJFU1VMVCBSUENfUmVnaXN0ZXJDaGFubmVsSG9vayhSRUZHVUlEIHJndWlkLCBJQ2hhbm5lbEhvb2sgKmhvb2spOwp2b2lkICAgIFJQQ19VbnJlZ2lzdGVyQWxsQ2hhbm5lbEhvb2tzKHZvaWQpOwpIUkVTVUxUIFJQQ19SZXNvbHZlT3hpZChPWElEIG94aWQsIE9YSURfSU5GTyAqb3hpZF9pbmZvKTsKCi8qIFRoaXMgZnVuY3Rpb24gaW5pdGlhbGl6ZSB0aGUgUnVubmluZyBPYmplY3QgVGFibGUgKi8KSFJFU1VMVCBXSU5BUEkgUnVubmluZ09iamVjdFRhYmxlSW1wbF9Jbml0aWFsaXplKHZvaWQpOwoKLyogVGhpcyBmdW5jdGlvbiB1bmluaXRpYWxpemUgdGhlIFJ1bm5pbmcgT2JqZWN0IFRhYmxlICovCkhSRVNVTFQgV0lOQVBJIFJ1bm5pbmdPYmplY3RUYWJsZUltcGxfVW5Jbml0aWFsaXplKHZvaWQpOwoKLyogRHJhZyBhbmQgZHJvcCAqLwp2b2lkIE9MRUREX1VuSW5pdGlhbGl6ZSh2b2lkKTsKCi8qIEFwYXJ0bWVudCBGdW5jdGlvbnMgKi8KCkFQQVJUTUVOVCAqYXBhcnRtZW50X2ZpbmRmcm9tb3hpZChPWElEIG94aWQsIEJPT0wgcmVmKTsKQVBBUlRNRU5UICphcGFydG1lbnRfZmluZGZyb210aWQoRFdPUkQgdGlkKTsKRFdPUkQgYXBhcnRtZW50X2FkZHJlZihzdHJ1Y3QgYXBhcnRtZW50ICphcHQpOwpEV09SRCBhcGFydG1lbnRfcmVsZWFzZShzdHJ1Y3QgYXBhcnRtZW50ICphcHQpOwpIUkVTVUxUIGFwYXJ0bWVudF9kaXNjb25uZWN0cHJveGllcyhzdHJ1Y3QgYXBhcnRtZW50ICphcHQpOwp2b2lkIGFwYXJ0bWVudF9kaXNjb25uZWN0b2JqZWN0KHN0cnVjdCBhcGFydG1lbnQgKmFwdCwgdm9pZCAqb2JqZWN0KTsKc3RhdGljIGlubGluZSBIUkVTVUxUIGFwYXJ0bWVudF9nZXRveGlkKGNvbnN0IHN0cnVjdCBhcGFydG1lbnQgKmFwdCwgT1hJRCAqb3hpZCkKewogICAgKm94aWQgPSBhcHQtPm94aWQ7CiAgICByZXR1cm4gU19PSzsKfQpIUkVTVUxUIGFwYXJ0bWVudF9jcmVhdGV3aW5kb3dpZm5lZWRlZChzdHJ1Y3QgYXBhcnRtZW50ICphcHQpOwpIV05EIGFwYXJ0bWVudF9nZXR3aW5kb3coY29uc3Qgc3RydWN0IGFwYXJ0bWVudCAqYXB0KTsKdm9pZCBhcGFydG1lbnRfam9pbm10YSh2b2lkKTsKCgovKiBEQ09NIG1lc3NhZ2VzIHVzZWQgYnkgdGhlIGFwYXJ0bWVudCB3aW5kb3cgKG5vdCBjb21wYXRpYmxlIHdpdGggbmF0aXZlKSAqLwojZGVmaW5lIERNX0VYRUNVVEVSUEMgICAoV01fVVNFUiArIDApIC8qIFdQQVJBTSA9IDAsIExQQVJBTSA9IChzdHJ1Y3QgZGlzcGF0Y2hfcGFyYW1zICopICovCiNkZWZpbmUgRE1fSE9TVE9CSkVDVCAgIChXTV9VU0VSICsgMSkgLyogV1BBUkFNID0gMCwgTFBBUkFNID0gKHN0cnVjdCBob3N0X29iamVjdF9wYXJhbXMgKikgKi8KCi8qCiAqIFBlci10aHJlYWQgdmFsdWVzIGFyZSBzdG9yZWQgaW4gdGhlIFRFQiBvbiBvZmZzZXQgMHhGODAKICovCgovKiB3aWxsIGNyZWF0ZSBpZiBuZWNlc3NhcnkgKi8Kc3RhdGljIGlubGluZSBzdHJ1Y3Qgb2xldGxzICpDT01fQ3VycmVudEluZm8odm9pZCkKewogICAgaWYgKCFOdEN1cnJlbnRUZWIoKS0+UmVzZXJ2ZWRGb3JPbGUpCiAgICAgICAgTnRDdXJyZW50VGViKCktPlJlc2VydmVkRm9yT2xlID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihzdHJ1Y3Qgb2xldGxzKSk7CgogICAgcmV0dXJuIE50Q3VycmVudFRlYigpLT5SZXNlcnZlZEZvck9sZTsKfQoKc3RhdGljIGlubGluZSBBUEFSVE1FTlQqIENPTV9DdXJyZW50QXB0KHZvaWQpCnsgIAogICAgcmV0dXJuIENPTV9DdXJyZW50SW5mbygpLT5hcHQ7Cn0KCnN0YXRpYyBpbmxpbmUgR1VJRCBDT01fQ3VycmVudENhdXNhbGl0eUlkKHZvaWQpCnsKICAgIHN0cnVjdCBvbGV0bHMgKmluZm8gPSBDT01fQ3VycmVudEluZm8oKTsKICAgIGlmICghaW5mbykKICAgICAgICByZXR1cm4gR1VJRF9OVUxMOwogICAgaWYgKElzRXF1YWxHVUlEKCZpbmZvLT5jYXVzYWxpdHlfaWQsICZHVUlEX05VTEwpKQogICAgICAgIENvQ3JlYXRlR3VpZCgmaW5mby0+Y2F1c2FsaXR5X2lkKTsKICAgIHJldHVybiBpbmZvLT5jYXVzYWxpdHlfaWQ7Cn0KCiNkZWZpbmUgSUNPTV9USElTX01VTFRJKGltcGwsZmllbGQsaWZhY2UpIGltcGwqIGNvbnN0IFRoaXM9KGltcGwqKSgoY2hhciopKGlmYWNlKSAtIG9mZnNldG9mKGltcGwsZmllbGQpKQoKLyogaGVscGVycyBmb3IgZGVidWdnaW5nICovCiMgZGVmaW5lIERFQlVHX1NFVF9DUklUU0VDX05BTUUoY3MsIG5hbWUpIChjcyktPkRlYnVnSW5mby0+U3BhcmVbMF0gPSAoRFdPUkRfUFRSKShfX0ZJTEVfXyAiOiAiIG5hbWUpCiMgZGVmaW5lIERFQlVHX0NMRUFSX0NSSVRTRUNfTkFNRShjcykgKGNzKS0+RGVidWdJbmZvLT5TcGFyZVswXSA9IDAKCmV4dGVybiBISU5TVEFOQ0UgT0xFMzJfaEluc3RhbmNlOyAvKiBGSVhNRTogbWFrZSBzdGF0aWMgKi8KCiNkZWZpbmUgQ0hBUlNfSU5fR1VJRCAzOSAvKiBpbmNsdWRpbmcgTlVMTCAqLwoKI2RlZmluZSBXSU5FX0NMU0NUWF9ET05UX0hPU1QgICAweDgwMDAwMDAwCgovKiBFeHBvcnRlZCBub24taW50ZXJmYWNlIERhdGEgQWR2aXNlIEhvbGRlciBmdW5jdGlvbnMgKi8KSFJFU1VMVCBEYXRhQWR2aXNlSG9sZGVyX09uQ29ubmVjdChJRGF0YUFkdmlzZUhvbGRlciAqaWZhY2UsIElEYXRhT2JqZWN0ICpwRGVsZWdhdGUpOwp2b2lkIERhdGFBZHZpc2VIb2xkZXJfT25EaXNjb25uZWN0KElEYXRhQWR2aXNlSG9sZGVyICppZmFjZSk7CgojZW5kaWYgLyogX19XSU5FX09MRV9DT01QT0JKX0ggKi8K