LyoKICogdGFibGVfaXRlcmF0b3IuYyAKICovCi8qIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvcHlyaWdodChzKS4gIFNlZQogKiB0aGUgTmV0LVNOTVAncyBDT1BZSU5HIGZpbGUgZm9yIG1vcmUgZGV0YWlscyBhbmQgb3RoZXIgY29weXJpZ2h0cwogKiB0aGF0IG1heSBhcHBseToKICovCi8qCiAqIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgY29weXJpZ2h0ZWQgYnk6CiAqIENvcHlyaWdodCCpIDIwMDMgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBVc2UgaXMgc3ViamVjdCB0byBsaWNlbnNlIHRlcm1zIHNwZWNpZmllZCBpbiB0aGUgQ09QWUlORyBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhlIE5ldC1TTk1QIHBhY2thZ2UuCiAqLwoKLyoqIEBkZWZncm91cCB0YWJsZV9pdGVyYXRvciB0YWJsZV9pdGVyYXRvcgogKiAgVGhlIHRhYmxlIGl0ZXJhdG9yIGhlbHBlciBpcyBkZXNpZ25lZCB0byBzaW1wbGlmeSB0aGUgdGFzayBvZiB3cml0aW5nIGEgdGFibGUgaGFuZGxlciBmb3IgdGhlIG5ldC1zbm1wIGFnZW50IHdoZW4gdGhlIGRhdGEgYmVpbmcgYWNjZXNzZWQgaXMgbm90IGluIGFuIG9pZCBzb3J0ZWQgZm9ybSBhbmQgbXVzdCBiZSBhY2Nlc3NlZCBleHRlcm5hbGx5LgogKiAgQGluZ3JvdXAgdGFibGUKICAgIEZ1bmN0aW9uYWxseSwgaXQgaXMgYSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIHRoZSBtb3JlCiAgICBnZW5lcmljIHRhYmxlIGhlbHBlciBidXQgZWFzaWVzIHRoZSBidXJkZW4gb2YgR0VUTkVYVCBwcm9jZXNzaW5nIGJ5CiAgICBtYW51YWxseSBsb29waW5nIHRocm91Z2ggYWxsIHRoZSBkYXRhIGluZGV4ZXMgcmV0cmlldmVkIHRocm91Z2gKICAgIGZ1bmN0aW9uIGNhbGxzIHdoaWNoIHNob3VsZCBiZSBzdXBwbGllZCBieSB0aGUgbW9kdWxlIHRoYXQgd2lzaGVzCiAgICBoZWxwLiAgVGhlIG1vZHVsZSB0aGUgdGFibGVfaXRlcmF0b3IgaGVscHMgc2hvdWxkLCBhZnRlcndhcmRzLAogICAgbmV2ZXIgYmUgY2FsbGVkIGZvciB0aGUgY2FzZSBvZiAiTU9ERV9HRVRORVhUIiBhbmQgb25seSBmb3IgdGhlIEdFVAogICAgYW5kIFNFVCByZWxhdGVkIG1vZGVzIGluc3RlYWQuCiAKICAgIFRoZSBmdW5kYW1lbnRhbCBub3Rpb24gYmV0d2VlbiB0aGUgdGFibGUgaXRlcmF0b3IgaXMgdGhhdCBpdAogICAgYWxsb3dzIHlvdXIgY29kZSB0byBpdGVyYXRlIG92ZXIgZWFjaCAicm93IiB3aXRoaW4geW91ciBkYXRhCiAgICBzdG9yYWdlIG1lY2hhbmlzbSwgd2l0aG91dCByZXF1aXJpbmcgdGhhdCBpdCBiZSBzb3J0ZWQgaW4gYQogICAgU05NUC1pbmRleC1jb21wbGlhbnQgbWFubmVyLiAgVGhyb3VnaCB0aGUgZ2V0X2ZpcnN0X2RhdGFfcG9pbnQgYW5kCiAgICBnZXRfbmV4dF9kYXRhX3BvaW50IGhvb2tzLCB0aGUgdGFibGVfaXRlcmF0b3IgaGVscGVyIHdpbGwKICAgIHJlcGVhdGVkbHkgY2FsbCB5b3VyIGhvb2tzIHRvIGZpbmQgdGhlICJwcm9wZXIiIHJvdyBvZiBkYXRhIHRoYXQKICAgIG5lZWRzIHByb2Nlc3NpbmcuICBUaGUgZm9sbG93aW5nIGNvbmNlcHRzIGFyZSBpbXBvcnRhbnQ6CgogICAgICAtIEEgbG9vcCBjb250ZXh0IGlzIGEgcG9pbnRlciB3aGljaCBpbmRpY2F0ZXMgd2hlcmUgaW4gdGhlCiAgICAgICAgY3VycmVudCBwcm9jZXNzaW5nIG9mIGEgc2V0IG9mIHJvd3MgeW91IGN1cnJlbnRseSBhcmUuICBBbGxvd3MKCXRoZSBnZXRfKl9kYXRhX3BvaW50IHJvdXRpbmVzIHRvIG1vdmUgZnJvbSBvbmUgcm93IHRvIHRoZSBuZXh0LAoJb25jZSB0aGUgaXRlcmF0b3IgaGFuZGxlciBoYXMgaWRlbnRpZmllZCB0aGUgYXBwcm9wcmlhdGUgcm93IGZvcgoJdGhpcyByZXF1ZXN0LCB0aGUgam9iIG9mIHRoZSBsb29wIGNvbnRleHQgaXMgZG9uZS4gIFRoZQogICAgICAgIG1vc3Qgc2ltcGxlIGV4YW1wbGUgd291bGQgYmUgYSBwb2ludGVyIHRvIGFuIGludGVnZXIgd2hpY2gKICAgICAgICBzaW1wbHkgY291bnRzIHJvd3MgZnJvbSAxIHRvIFguICBNb3JlIGNvbW1vbmx5LCBpdCBtaWdodCBiZSBhCiAgICAgICAgcG9pbnRlciB0byBhIGxpbmtlZCBsaXN0IG5vZGUsIG9yIHNvbWVvdGhlciBpbnRlcm5hbCBvcgogICAgICAgIGV4dGVybmFsIHJlZmVyZW5jZSB0byBhIGRhdGEgc2V0IChmaWxlIHNlZWsgdmFsdWUsIGFycmF5CiAgICAgICAgcG9pbnRlciwgLi4uKS4gIElmIGFsbG9jYXRlZCBkdXJpbmcgaXRlcmF0aW9uLCBlaXRoZXIgdGhlCiAgICAgICAgZnJlZV9sb29wX2NvbnRleHRfYXRfZW5kIChwcmVmZXJhYmx5KSBvciB0aGUgZnJlZV9sb29wX2NvbnRleHQKICAgICAgICBwb2ludGVycyBzaG91bGQgYmUgc2V0LgoKICAgICAgLSBBIGRhdGEgY29udGV4dCBpcyBzb21ldGhpbmcgdGhhdCB5b3VyIGhhbmRsZXIgY29kZSBjYW4gdXNlCiAgICAgICAgaW4gb3JkZXIgdG8gcmV0cmlldmUgdGhlIHJlc3Qgb2YgdGhlIGRhdGEgZm9yIHRoZSBuZWVkZWQKICAgICAgICByb3cuICBUaGlzIGRhdGEgY2FuIGJlIGFjY2Vzc2VkIGluIHlvdXIgaGFuZGxlciB2aWEKCW5ldHNubXBfZXh0cmFjdF9pdGVyYXRvcl9jb250ZXh0IGFwaSB3aXRoIHRoZSBuZXRzbm1wX3JlcXVlc3RfaW5mbwoJc3RydWN0dXJlIHRoYXQncyBwYXNzZWQgaW4uCglUaGUgaW1wb3J0YW50IGRpZmZlcmVuY2UgYmV0d2VlbiBhIGxvb3AgY29udGV4dCBhbmQgYQogICAgICAgIGRhdGEgY29udGV4dCBpcyB0aGF0IG11bHRpcGxlIGRhdGEgY29udGV4dHMgY2FuIGJlIGtlcHQgYnkgdGhlCiAgICAgICAgdGFibGVfaXRlcmF0b3IgaGVscGVyLCB3aGVyZSBhcyBvbmx5IG9uZSBsb29wIGNvbnRleHQgd2lsbAogICAgICAgIGV2ZXIgYmUgaGVsZCBieSB0aGUgdGFibGVfaXRlcmF0b3IgaGVscGVyLiAgSWYgYWxsb2NhdGVkCiAgICAgICAgZHVyaW5nIGl0ZXJhdGlvbiB0aGUgZnJlZV9kYXRhX2NvbnRleHQgcG9pbnRlciBzaG91bGQgYmUgc2V0CiAgICAgICAgdG8gYW4gYXBwcm9wcmlhdGUgZnVuY3Rpb24uCiAKICAgIFRoZSB0YWJsZSBpdGVyYXRvciBvcGVyYXRlcyBpbiBhIHNlcmllcyBvZiBzdGVwcyB0aGF0IGNhbGwgeW91cgogICAgY29kZSBob29rcyBmcm9tIHlvdXIgbmV0c25tcF9pdGVyYXRvcl9pbmZvIHJlZ2lzdHJhdGlvbiBwb2ludGVyLgogCiAgICAgIC0gdGhlIGdldF9maXJzdF9kYXRhX3BvaW50IGhvb2sgaXMgY2FsbGVkIGF0IHRoZSBiZWdpbm5pbmcgb2YKICAgICAgICBwcm9jZXNzaW5nLiAgSXQgc2hvdWxkIHNldCB0aGUgdmFyaWFibGUgbGlzdCB0byBhIGxpc3Qgb2YKICAgICAgICBpbmRleGVzIGZvciB0aGUgZ2l2ZW4gdGFibGUuICBJdCBzaG91bGQgYWxzbyBzZXQgdGhlCiAgICAgICAgbG9vcF9jb250ZXh0IGFuZCBtYXliZSBhIGRhdGFfY29udGV4dCB3aGljaCB5b3Ugd2lsbCBnZXQgYQogICAgICAgIHBvaW50ZXIgYmFjayB0byB3aGVuIGl0IG5lZWRzIHRvIGNhbGwgeW91ciBjb2RlIHRvIHJldHJpZXZlCiAgICAgICAgYWN0dWFsIGRhdGEgbGF0ZXIuICBUaGUgbGlzdCBvZiBpbmRleGVzIHNob3VsZCBiZSByZXR1cm5lZAogICAgICAgIGFmdGVyIGJlaW5nIHVwZGF0ZS4KCiAgICAgIC0gdGhlIGdldF9uZXh0X2RhdGFfcG9pbnQgaG9vayBpcyB0aGVuIGNhbGxlZCByZXBlYXRlZGx5IGFuZCBpcwogICAgICAgIHBhc3NlZCB0aGUgbG9vcCBjb250ZXh0IGFuZCB0aGUgZGF0YSBjb250ZXh0IGZvciBpdCB0byB1cGRhdGUuCiAgICAgICAgVGhlIGluZGV4ZXMsIGxvb3AgY29udGV4dCBhbmQgZGF0YSBjb250ZXh0IHNob3VsZCBhbGwgYmUKICAgICAgICB1cGRhdGVkIGlmIG1vcmUgZGF0YSBpcyBhdmFpbGFibGUsIG90aGVyd2lzZSB0aGV5IHNob3VsZCBiZQogICAgICAgIGxlZnQgYWxvbmUgYW5kIGEgTlVMTCBzaG91bGQgYmUgcmV0dXJuZWQuICBJZGVhbGx5LCBpdCBzaG91bGQKICAgICAgICB1cGRhdGUgdGhlIGxvb3AgY29udGV4dCB3aXRob3V0IHRoZSBuZWVkIHRvIHJlYWxsb2NhdGUgaXQuICBJZgogICAgICAgIHJlYWxsb2NhdGlvbiBpcyBuZWNlc3NhcnkgZm9yIGV2ZXJ5IGl0ZXJhdGl2ZSBzdGVwLCB0aGVuIHRoZQogICAgICAgIGZyZWVfbG9vcF9jb250ZXh0IGZ1bmN0aW9uIHBvaW50ZXIgc2hvdWxkIGJlIHNldC4gIElmIG5vdCwKICAgICAgICB0aGVuIHRoZSBmcmVlX2xvb3BfY29udGV4dF9hdF9lbmQgcG9pbnRlciBzaG91bGQgYmUgc2V0LCB3aGljaAogICAgICAgIGlzIG1vcmUgZWZmaWNpZW50IHNpbmNlIGEgbWFsbG9jL2ZyZWUgd2lsbCBvbmx5IGJlIHBlcmZvcm1lZAogICAgICAgIG9uY2UgZm9yIGV2ZXJ5IGl0ZXJhdGlvbi4KICoKICogIEB7CiAqLwoKI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWNvbmZpZy5oPgoKI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWZlYXR1cmVzLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1pbmNsdWRlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvbmV0LXNubXAtYWdlbnQtaW5jbHVkZXMuaD4KCiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC90YWJsZV9pdGVyYXRvci5oPgoKI2lmIEhBVkVfU1RSSU5HX0gKI2luY2x1ZGUgPHN0cmluZy5oPgojZWxzZQojaW5jbHVkZSA8c3RyaW5ncy5oPgojZW5kaWYKCiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC90YWJsZS5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvc2VyaWFsaXplLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9zdGFzaF9jYWNoZS5oPgoKbmV0c25tcF9mZWF0dXJlX2NoaWxkX29mKHRhYmxlX2l0ZXJhdG9yX2FsbCwgbWliX2hlbHBlcnMpCgpuZXRzbm1wX2ZlYXR1cmVfY2hpbGRfb2YodGFibGVfaXRlcmF0b3JfaW5zZXJ0X2NvbnRleHQsIHRhYmxlX2l0ZXJhdG9yX2FsbCkKbmV0c25tcF9mZWF0dXJlX2NoaWxkX29mKHRhYmxlX2l0ZXJhdG9yX2NyZWF0ZV90YWJsZSwgdGFibGVfaXRlcmF0b3JfYWxsKQpuZXRzbm1wX2ZlYXR1cmVfY2hpbGRfb2YodGFibGVfaXRlcmF0b3Jfcm93X2ZpcnN0LCB0YWJsZV9pdGVyYXRvcl9hbGwpCm5ldHNubXBfZmVhdHVyZV9jaGlsZF9vZih0YWJsZV9pdGVyYXRvcl9yb3dfY291bnQsIHRhYmxlX2l0ZXJhdG9yX2FsbCkKCiNpZmRlZiBORVRTTk1QX0ZFQVRVUkVfUkVRVUlSRV9TVEFTSF9DQUNIRQpuZXRzbm1wX2ZlYXR1cmVfcmVxdWlyZShkYXRhX2xpc3RfZ2V0X2xpc3Rfbm9kZSkKbmV0c25tcF9mZWF0dXJlX3JlcXVpcmUob2lkX3N0YXNoX2FkZF9kYXRhKQojZW5kaWYgLyogTkVUU05NUF9GRUFUVVJFX1JFUVVJUkVfU1RBU0hfQ0FDSEUgKi8KCi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICoKICogSXRlcmF0b3IgQVBJOiBUYWJsZSBtYWludGVuYW5jZQogKgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovCgogICAgLyoKICAgICAqIEl0ZXJhdG9yLWJhc2VkIHRhYmxlcyBhcmUgdHlwaWNhbGx5IG1haW50YWluZWQgYnkgZXh0ZXJuYWwKICAgICAqICBjb2RlLCBhbmQgdGhpcyBoZWxwZXIgaXMgcmVhbGx5IG9ubHkgY29uY2VybmVkIHdpdGgKICAgICAqICBtYXBwaW5nIGJldHdlZW4gYSB3YWxrIHRocm91Z2ggdGhpcyBsb2NhbCByZXByZXNlbnRhdGlvbiwKICAgICAqICBhbmQgdGhlIHJlcXVpcmVtZW50cyBvZiBTTk1QIHRhYmxlIG9yZGVyaW5nLgogICAgICogSG93ZXZlciwgdGhlcmUncyBhIGNhc2UgdG8gYmUgbWFkZSBmb3IgY29uc2lkZXJpbmcgdGhlCiAgICAgKiAgaXRlcmF0b3IgaW5mbyBzdHJ1Y3R1cmUgYXMgZW5jYXBzdWxhdGluZyB0aGUgdGFibGUsIHNvCiAgICAgKiAgaXQncyBwcm9iYWJseSB3b3J0aCBkZWZpbmluZyB0aGUgdGFibGUgY3JlYXRpb24vZGVsZXRpb24KICAgICAqICByb3V0aW5lcyBmcm9tIHRoZSBnZW5lcmljIEFQSS4KICAgICAqCiAgICAgKiBUaW1lIHdpbGwgc2hvdyB3aGV0aGVyIHRoaXMgaXMgYSBzZW5zaWJsZSBhcHByb2FjaCBvciBub3QuCiAgICAgKi8KI2lmbmRlZiBORVRTTk1QX0ZFQVRVUkVfUkVNT1ZFX1RBQkxFX0lURVJBVE9SX0NSRUFURV9UQUJMRQpuZXRzbm1wX2l0ZXJhdG9yX2luZm8gKgpuZXRzbm1wX2l0ZXJhdG9yX2NyZWF0ZV90YWJsZSggTmV0c25tcF9GaXJzdF9EYXRhX1BvaW50ICpmaXJzdERQLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmV0c25tcF9OZXh0X0RhdGFfUG9pbnQgICpuZXh0RFAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZXRzbm1wX0ZpcnN0X0RhdGFfUG9pbnQgKmdldGlkeCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAgICAqaW5kZXhlcykKewogICAgbmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbyA9CiAgICAgICAgU05NUF9NQUxMT0NfVFlQRURFRihuZXRzbm1wX2l0ZXJhdG9yX2luZm8pOwoKICAgIGlmICggIWlpbmZvICkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICBpZiAoIGluZGV4ZXMgKQogICAgICAgIGlpbmZvLT5pbmRleGVzID0gc25tcF9jbG9uZV92YXJiaW5kKGluZGV4ZXMpOwogICAgaWluZm8tPmdldF9maXJzdF9kYXRhX3BvaW50ID0gZmlyc3REUDsKICAgIGlpbmZvLT5nZXRfbmV4dF9kYXRhX3BvaW50ICA9IG5leHREUDsKICAgIGlpbmZvLT5nZXRfcm93X2luZGV4ZXMgICAgICA9IGdldGlkeDsKCiAgICByZXR1cm4gaWluZm87Cn0KI2VuZGlmIC8qIE5FVFNOTVBfRkVBVFVSRV9SRU1PVkVfVEFCTEVfSVRFUkFUT1JfQ1JFQVRFX1RBQkxFICovCgovKiogRnJlZSB0aGUgbWVtb3J5IHRoYXQgd2FzIGFsbG9jYXRlZCBmb3IgYSB0YWJsZSBpdGVyYXRvci4gKi8Kdm9pZApuZXRzbm1wX2l0ZXJhdG9yX2RlbGV0ZV90YWJsZSggbmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbyApCnsKICAgIGlmICghaWluZm8pCiAgICAgICAgcmV0dXJuOwoKICAgIGlmIChpaW5mby0+aW5kZXhlcykgewogICAgICAgIHNubXBfZnJlZV92YXJiaW5kKCBpaW5mby0+aW5kZXhlcyApOwogICAgICAgIGlpbmZvLT5pbmRleGVzID0gTlVMTDsKICAgIH0KICAgIG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm9fZnJlZShpaW5mby0+dGFibGVfcmVnaW5mbyk7CiAgICBTTk1QX0ZSRUUoIGlpbmZvICk7Cn0KCiAgICAvKgogICAgICogVGhlIHJlc3Qgb2YgdGhlIHRhYmxlIG1haW50ZW5hbmNlIHNlY3Rpb24gb2YgdGhlCiAgICAgKiAgIGdlbmVyaWMgdGFibGUgQVBJIGlzIE5vdCBBcHBsaWNhYmxlIHRvIHRoaXMgaGVscGVyLgogICAgICoKICAgICAqIFRoZSBjb250ZW50cyBvZiBhIGl0ZXJhdG9yLWJhc2VkIHRhYmxlIHdpbGwgYmUKICAgICAqICBtYWludGFpbmVkIGJ5IHRoZSB0YWJsZS1zcGVjaWZpYyBtb2R1bGUgaXRzZWxmLgogICAgICovCgovKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqCiAqIEl0ZXJhdG9yIEFQSTogTUlCIG1haW50ZW5hbmNlCiAqCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi8KCnN0YXRpYyBuZXRzbm1wX2l0ZXJhdG9yX2luZm8gKgpuZXRzbm1wX2l0ZXJhdG9yX3JlZihuZXRzbm1wX2l0ZXJhdG9yX2luZm8gKmlpbmZvKQp7CiAgICBpaW5mby0+cmVmY250Kys7CiAgICByZXR1cm4gaWluZm87Cn0KCnN0YXRpYyB2b2lkCm5ldHNubXBfaXRlcmF0b3JfZGVyZWYobmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbykKewogICAgaWYgKC0taWluZm8tPnJlZmNudCA9PSAwKQogICAgICAgIG5ldHNubXBfaXRlcmF0b3JfZGVsZXRlX3RhYmxlKGlpbmZvKTsKfQoKdm9pZCBuZXRzbm1wX2hhbmRsZXJfb3duc19pdGVyYXRvcl9pbmZvKG5ldHNubXBfbWliX2hhbmRsZXIgKmgpCnsKICAgIG5ldHNubXBfYXNzZXJ0KGgpOwogICAgbmV0c25tcF9hc3NlcnQoaC0+bXl2b2lkKTsKICAgICgobmV0c25tcF9pdGVyYXRvcl9pbmZvICopKGgtPm15dm9pZCkpLT5yZWZjbnQrKzsKICAgIGgtPmRhdGFfY2xvbmUgPSAodm9pZCAqKCopKHZvaWQgKikpbmV0c25tcF9pdGVyYXRvcl9yZWY7CiAgICBoLT5kYXRhX2ZyZWUgID0gKHZvaWQoKikodm9pZCAqKSluZXRzbm1wX2l0ZXJhdG9yX2RlcmVmOwp9CgovKioKICogUmV0dXJucyBhIG5ldHNubXBfbWliX2hhbmRsZXIgb2JqZWN0IGZvciB0aGUgdGFibGVfaXRlcmF0b3IgaGVscGVyLgogKgogKiBUaGUgY2FsbGVyIHJlbWFpbnMgdGhlIG93bmVyIG9mIHRoZSBpdGVyYXRvciBpbmZvcm1hdGlvbiBvYmplY3QgaWYKICogdGhlIGZsYWcgTkVUU05NUF9IQU5ETEVSX09XTlNfSUlORk8gaGFzIG5vdCBiZWVuIHNldCwgYW5kIHRoZSBjcmVhdGVkCiAqIGhhbmRsZXIgYmVjb21lcyB0aGUgb3duZXIgb2YgdGhlIGl0ZXJhdG9yIGluZm9ybWF0aW9uIGlmIHRoZSBmbGFnCiAqIE5FVFNOTVBfSEFORExFUl9PV05TX0lJTkZPIGhhcyBiZWVuIHNldC4KICovCm5ldHNubXBfbWliX2hhbmRsZXIgKgpuZXRzbm1wX2dldF90YWJsZV9pdGVyYXRvcl9oYW5kbGVyKG5ldHNubXBfaXRlcmF0b3JfaW5mbyAqaWluZm8pCnsKICAgIG5ldHNubXBfbWliX2hhbmRsZXIgKm1lOwoKICAgIGlmICghaWluZm8pCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgbWUgPQogICAgICAgIG5ldHNubXBfY3JlYXRlX2hhbmRsZXIoVEFCTEVfSVRFUkFUT1JfTkFNRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdGFibGVfaXRlcmF0b3JfaGVscGVyX2hhbmRsZXIpOwoKICAgIGlmICghbWUpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgbWUtPm15dm9pZCA9IGlpbmZvOwogICAgaWYgKGlpbmZvLT5mbGFncyAmIE5FVFNOTVBfSEFORExFUl9PV05TX0lJTkZPKQogICAgICAgIG5ldHNubXBfaGFuZGxlcl9vd25zX2l0ZXJhdG9yX2luZm8obWUpOwogICAgcmV0dXJuIG1lOwp9CgovKiogCiAqIENyZWF0ZXMgYW5kIHJlZ2lzdGVycyBhIHRhYmxlIGl0ZXJhdG9yIGhlbHBlciBoYW5kbGVyIGNhbGxpbmcgCiAqIG5ldHNubXBfY3JlYXRlX2hhbmRsZXIgd2l0aCBhIGhhbmRsZXIgbmFtZSBzZXQgdG8gVEFCTEVfSVRFUkFUT1JfTkFNRSAKICogYW5kIGFjY2VzcyBtZXRob2QsIG5ldHNubXBfdGFibGVfaXRlcmF0b3JfaGVscGVyX2hhbmRsZXIuCiAqCiAqIElmIE5PVF9TRVJJQUxJWkVEIGlzIG5vdCBkZWZpbmVkIHRoZSBmdW5jdGlvbiBpbmplY3RzIHRoZSBzZXJpYWxpemUKICogaGFuZGxlciBpbnRvIHRoZSBjYWxsaW5nIGNoYWluIHByaW9yIHRvIGNhbGxpbmcgbmV0c25tcF9yZWdpc3Rlcl90YWJsZS4KICoKICogQHBhcmFtIHJlZ2luZm8gaXMgYSBwb2ludGVyIHRvIGEgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiBzdHJ1Y3QKICoKICogQHBhcmFtIGlpbmZvIEEgcG9pbnRlciB0byBhIG5ldHNubXBfaXRlcmF0b3JfaW5mbyBzdHJ1Y3QuIElmIHRoZSBmbGFnCiAqIE5FVFNOTVBfSEFORExFUl9PV05TX0lJTkZPIGlzIG5vdCBzZXQgaW4gaWluZm8tPmZsYWdzLCB0aGUgY2FsbGVyIHJlbWFpbnMKICogdGhlIG93bmVyIG9mIHRoaXMgc3RydWN0dXJlLiBBbmQgaWYgdGhlIGZsYWcgTkVUU05NUF9IQU5ETEVSX09XTlNfSUlORk8gaXMKICogc2V0IGluIGlpbmZvLT5mbGFncywgb3duZXJzaGlwIG9mIHRoaXMgZGF0YSBzdHJ1Y3R1cmUgaXMgcGFzc2VkIHRvIHRoZQogKiBoYW5kbGVyLgogKgogKiBAcmV0dXJuIE1JQl9SRUdJU1RFUkVEX09LIGlzIHJldHVybmVkIGlmIHRoZSByZWdpc3RyYXRpb24gd2FzIGEgc3VjY2Vzcy4KICoJRmFpbHVyZXMgYXJlIE1JQl9SRUdJU1RSQVRJT05fRkFJTEVELCBNSUJfRFVQTElDQVRFX1JFR0lTVFJBVElPTi4KICoJSWYgaWluZm8gaXMgTlVMTCwgU05NUEVSUl9HRU5FUlIgaXMgcmV0dXJuZWQuCiAqCiAqLwppbnQKbmV0c25tcF9yZWdpc3Rlcl90YWJsZV9pdGVyYXRvcihuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfaXRlcmF0b3JfaW5mbyAqaWluZm8pCnsKI2lmbmRlZiBORVRTTk1QX0ZFQVRVUkVfUkVNT1ZFX1NUQVNIX0NBQ0hFCiAgICByZWdpbmZvLT5tb2RlcyB8PSBIQU5ETEVSX0NBTl9TVEFTSDsKI2VuZGlmICAvKiBORVRTTk1QX0ZFQVRVUkVfUkVNT1ZFX1NUQVNIX0NBQ0hFICovCiAgICBuZXRzbm1wX2luamVjdF9oYW5kbGVyKHJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfZ2V0X3RhYmxlX2l0ZXJhdG9yX2hhbmRsZXIoaWluZm8pKTsKICAgIGlmICghaWluZm8pCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgaWYgKCFpaW5mby0+aW5kZXhlcyAmJiBpaW5mby0+dGFibGVfcmVnaW5mbyAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICBpaW5mby0+dGFibGVfcmVnaW5mby0+aW5kZXhlcyApCiAgICAgICAgaWluZm8tPmluZGV4ZXMgPSBzbm1wX2Nsb25lX3ZhcmJpbmQoIGlpbmZvLT50YWJsZV9yZWdpbmZvLT5pbmRleGVzICk7CgogICAgcmV0dXJuIG5ldHNubXBfcmVnaXN0ZXJfdGFibGUocmVnaW5mbywgaWluZm8tPnRhYmxlX3JlZ2luZm8pOwp9CgovKiogZXh0cmFjdHMgdGhlIHRhYmxlX2l0ZXJhdG9yIHNwZWNpZmljIGRhdGEgZnJvbSBhIHJlcXVlc3QuCiAqIFRoaXMgZnVuY3Rpb24gZXh0cmFjdHMgdGhlIHRhYmxlIGl0ZXJhdG9yIHNwZWNpZmljIGRhdGEgZnJvbSBhIAogKiBuZXRzbm1wX3JlcXVlc3RfaW5mbyBvYmplY3QuICBDYWxscyBuZXRzbm1wX3JlcXVlc3RfZ2V0X2xpc3RfZGF0YQogKiB3aXRoIHJlcXVlc3QtPnBhcmVudF9kYXRhIHNldCB3aXRoIGRhdGEgZnJvbSBhIHJlcXVlc3QgdGhhdCB3YXMgYWRkZWQgCiAqIHByZXZpb3VzbHkgYnkgYSBtb2R1bGUgYW5kIFRBQkxFX0lURVJBVE9SX05BTUUgaGFuZGxlciBuYW1lLgogKgogKiBAcGFyYW0gcmVxdWVzdCB0aGUgbmV0c25tcCByZXF1ZXN0IGluZm8gc3RydWN0dXJlCiAqCiAqIEByZXR1cm4gYSB2b2lkIHBvaW50ZXIocmVxdWVzdC0+cGFyZW50X2RhdGEtPmRhdGEpLCBvdGhlcndpc2UgTlVMTCBpcwogKiAgICAgICAgIHJldHVybmVkIGlmIHJlcXVlc3QgaXMgTlVMTCBvciByZXF1ZXN0LT5wYXJlbnRfZGF0YSBpcyBOVUxMIG9yCiAqICAgICAgICAgcmVxdWVzdC0+cGFyZW50X2RhdGEgb2JqZWN0IGlzIG5vdCBmb3VuZC50aGUgbmV0CiAqCiAqLwpORVRTTk1QX0lOTElORSB2b2lkICAgICoKbmV0c25tcF9leHRyYWN0X2l0ZXJhdG9yX2NvbnRleHQobmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3QpCnsKICAgIHJldHVybiBuZXRzbm1wX3JlcXVlc3RfZ2V0X2xpc3RfZGF0YShyZXF1ZXN0LCBUQUJMRV9JVEVSQVRPUl9OQU1FKTsKfQoKI2lmbmRlZiBORVRTTk1QX0ZFQVRVUkVfUkVNT1ZFX1RBQkxFX0lURVJBVE9SX0lOU0VSVF9DT05URVhUCi8qKiBpbnNlcnRzIHRhYmxlX2l0ZXJhdG9yIHNwZWNpZmljIGRhdGEgZm9yIGEgbmV3bHkKICogIGNyZWF0ZWQgcm93IGludG8gYSByZXF1ZXN0ICovCk5FVFNOTVBfSU5MSU5FIHZvaWQKbmV0c25tcF9pbnNlcnRfaXRlcmF0b3JfY29udGV4dChuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdCwgdm9pZCAqZGF0YSkKewogICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gICAgICAgKnJlcTsKICAgIG5ldHNubXBfdGFibGVfcmVxdWVzdF9pbmZvICp0YWJsZV9pbmZvID0gTlVMTDsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAgICAgICp0aGlzX2luZGV4ID0gTlVMTDsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAgICAgICp0aGF0X2luZGV4ID0gTlVMTDsKICAgIG9pZCAgICAgIGJhc2Vfb2lkW10gPSB7MCwgMH07CS8qIE1ha2Ugc3VyZSBpbmRleCBPSURzIGFyZSBsZWdhbCEgKi8KICAgIG9pZCAgICAgIHRoaXNfb2lkW01BWF9PSURfTEVOXTsKICAgIG9pZCAgICAgIHRoYXRfb2lkW01BWF9PSURfTEVOXTsKICAgIHNpemVfdCAgIHRoaXNfb2lkX2xlbiwgdGhhdF9vaWRfbGVuOwoKICAgIGlmICghcmVxdWVzdCkKICAgICAgICByZXR1cm47CgogICAgLyoKICAgICAqIFdlJ2xsIGFkZCB0aGUgbmV3IHJvdyBpbmZvcm1hdGlvbiB0byBhbnkgcmVxdWVzdAogICAgICogc3RydWN0dXJlIHdpdGggdGhlIHNhbWUgaW5kZXggdmFsdWVzIGFzIHRoZSByZXF1ZXN0CiAgICAgKiBwYXNzZWQgaW4gKHdoaWNoIGluY2x1ZGVzIHRoYXQgb25lISkuCiAgICAgKgogICAgICogU28gY29uc3RydWN0IGFuIE9JRCBiYXNlZCBvbiB0aGVzZSBpbmRleCB2YWx1ZXMuCiAgICAgKi8KCiAgICB0YWJsZV9pbmZvID0gbmV0c25tcF9leHRyYWN0X3RhYmxlX2luZm8ocmVxdWVzdCk7CiAgICB0aGlzX2luZGV4ID0gdGFibGVfaW5mby0+aW5kZXhlczsKICAgIGJ1aWxkX29pZF9ub2FsbG9jKHRoaXNfb2lkLCBNQVhfT0lEX0xFTiwgJnRoaXNfb2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgIGJhc2Vfb2lkLCAyLCB0aGlzX2luZGV4KTsKCiAgICAvKgogICAgICogV2UgbmVlZCB0byBsb29rIHRocm91Z2ggdGhlIHdob2xlIG9mIHRoZSByZXF1ZXN0IGxpc3QKICAgICAqIChhcyByZWNlaXZlZCBieSB0aGUgY3VycmVudCBoYW5kbGVyKSwgYXMgdGhlcmUncyBubwogICAgICogZ3VhcmFudGVlIHRoYXQgdGhpcyByb3V0aW5lIHdpbGwgYmUgY2FsbGVkIGJ5IHRoZSBmaXJzdAogICAgICogdmFyYmluZCB0aGF0IHJlZmVycyB0byB0aGlzIHJvdy4KICAgICAqICAgSW4gcGFydGljdWxhciwgYSBSb3dTdGF0dXMgY29udHJvbGxlZCByb3cgY3JlYXRpb24KICAgICAqIG1heSBlYXNpbHkgb2NjdXIgbGF0ZXIgaW4gdGhlIHZhcmlhYmxlIGxpc3QuCiAgICAgKgogICAgICogU28gZmlyc3QsIHdlIHJld2luZCB0byB0aGUgaGVhZCBvZiB0aGUgbGlzdC4uLi4KICAgICAqLwogICAgZm9yIChyZXE9cmVxdWVzdDsgcmVxLT5wcmV2OyByZXE9cmVxLT5wcmV2KQogICAgICAgIDsKCiAgICAvKgogICAgICogLi4uIGFuZCB0aGVuIHN0YXJ0IGxvb2tpbmcgZm9yIG1hdGNoaW5nIGluZGV4ZXMKICAgICAqIChieSBjb25zdHJ1Y3RpbmcgT0lEcyBmcm9tIHRoZXNlIGluZGV4IHZhbHVlcykKICAgICAqLwogICAgZm9yICg7IHJlcTsgcmVxPXJlcS0+bmV4dCkgewogICAgICAgIHRhYmxlX2luZm8gPSBuZXRzbm1wX2V4dHJhY3RfdGFibGVfaW5mbyhyZXEpOwogICAgICAgIHRoYXRfaW5kZXggPSB0YWJsZV9pbmZvLT5pbmRleGVzOwogICAgICAgIGJ1aWxkX29pZF9ub2FsbG9jKHRoYXRfb2lkLCBNQVhfT0lEX0xFTiwgJnRoYXRfb2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlX29pZCwgMiwgdGhhdF9pbmRleCk7CiAgICAgIAogICAgICAgIC8qCiAgICAgICAgICogVGhpcyByZXF1ZXN0IGhhcyB0aGUgc2FtZSBpbmRleCB2YWx1ZXMsCiAgICAgICAgICogc28gYWRkIHRoZSBuZXdseS1jcmVhdGVkIHJvdyBpbmZvcm1hdGlvbi4KICAgICAgICAgKi8KICAgICAgICBpZiAoc25tcF9vaWRfY29tcGFyZSh0aGlzX29pZCwgdGhpc19vaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXRfb2lkLCB0aGF0X29pZF9sZW4pID09IDApIHsKICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2FkZF9saXN0X2RhdGEocmVxLAogICAgICAgICAgICAgICAgbmV0c25tcF9jcmVhdGVfZGF0YV9saXN0KFRBQkxFX0lURVJBVE9SX05BTUUsIGRhdGEsIE5VTEwpKTsKICAgICAgICB9CiAgICB9Cn0KI2VuZGlmIC8qIE5FVFNOTVBfRkVBVFVSRV9SRU1PVkVfVEFCTEVfSVRFUkFUT1JfSU5TRVJUX0NPTlRFWFQgKi8KCiNkZWZpbmUgVElfUkVRVUVTVF9DQUNIRSAidGlfY2FjaGUiCgp0eXBlZGVmIHN0cnVjdCB0aV9jYWNoZV9pbmZvX3MgewogICBvaWQgYmVzdF9tYXRjaFtNQVhfT0lEX0xFTl07CiAgIHNpemVfdCBiZXN0X21hdGNoX2xlbjsKICAgdm9pZCAqZGF0YV9jb250ZXh0OwogICBOZXRzbm1wX0ZyZWVfRGF0YV9Db250ZXh0ICpmcmVlX2NvbnRleHQ7CiAgIG5ldHNubXBfaXRlcmF0b3JfaW5mbyAqaWluZm87CiAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqcmVzdWx0czsKfSB0aV9jYWNoZV9pbmZvOwoKc3RhdGljIHZvaWQKbmV0c25tcF9mcmVlX3RpX2NhY2hlKHZvaWQgKml0KSB7CiAgICB0aV9jYWNoZV9pbmZvICpiZWVyID0gKHRpX2NhY2hlX2luZm8qKWl0OwogICAgaWYgKCFpdCkgcmV0dXJuOwogICAgaWYgKGJlZXItPmRhdGFfY29udGV4dCAmJiBiZWVyLT5mcmVlX2NvbnRleHQpIHsKICAgICAgICAgICAgKGJlZXItPmZyZWVfY29udGV4dCkoYmVlci0+ZGF0YV9jb250ZXh0LCBiZWVyLT5paW5mbyk7CiAgICB9CiAgICBpZiAoYmVlci0+cmVzdWx0cykgewogICAgICAgIHNubXBfZnJlZV92YXJiaW5kKGJlZXItPnJlc3VsdHMpOwogICAgfQogICAgZnJlZShiZWVyKTsKfQoKLyogY2FjaGVzIGluZm9ybWF0aW9uIChpbiB0aGUgcmVxdWVzdCkgd2UnbGwgbmVlZCBhdCBhIGxhdGVyIHBvaW50IGluIHRpbWUgKi8Kc3RhdGljIHRpX2NhY2hlX2luZm8gKgpuZXRzbm1wX2l0ZXJhdG9yX3JlbWVtYmVyKG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgIG9pZCAqb2lkX3RvX3NhdmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IG9pZF90b19zYXZlX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpjYWxsYmFja19kYXRhX2NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqY2FsbGJhY2tfbG9vcF9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfaXRlcmF0b3JfaW5mbyAqaWluZm8pCnsKICAgIHRpX2NhY2hlX2luZm8gKnRpX2luZm87CgogICAgaWYgKCFyZXF1ZXN0IHx8ICFvaWRfdG9fc2F2ZSB8fCBvaWRfdG9fc2F2ZV9sZW4gPiBNQVhfT0lEX0xFTikKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICAvKiBleHRyYWN0IGV4aXN0aW5nIGNhY2hlZCBzdGF0ZSAqLwogICAgdGlfaW5mbyA9ICh0aV9jYWNoZV9pbmZvKiluZXRzbm1wX3JlcXVlc3RfZ2V0X2xpc3RfZGF0YShyZXF1ZXN0LCBUSV9SRVFVRVNUX0NBQ0hFKTsKCiAgICAvKiBubyBleGlzdGluZyBjYWNoZWQgc3RhdGUuICBtYWtlIGEgbmV3IG9uZS4gKi8KICAgIGlmICghdGlfaW5mbykgewogICAgICAgIHRpX2luZm8gPSBTTk1QX01BTExPQ19UWVBFREVGKHRpX2NhY2hlX2luZm8pOwogICAgICAgIGlmICh0aV9pbmZvID09IE5VTEwpCiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIG5ldHNubXBfcmVxdWVzdF9hZGRfbGlzdF9kYXRhKHJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9jcmVhdGVfZGF0YV9saXN0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFRJX1JFUVVFU1RfQ0FDSEUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpX2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfZnJlZV90aV9jYWNoZSkpOwogICAgfQoKICAgIC8qIGZyZWUgZXhpc3RpbmcgY2FjaGUgYmVmb3JlIHJlcGxhY2luZyAqLwogICAgaWYgKHRpX2luZm8tPmRhdGFfY29udGV4dCAmJiB0aV9pbmZvLT5mcmVlX2NvbnRleHQpCiAgICAgICAgKHRpX2luZm8tPmZyZWVfY29udGV4dCkodGlfaW5mby0+ZGF0YV9jb250ZXh0LCBpaW5mbyk7CgogICAgLyogbWF5YmUgZ2VuZXJhdGUgaXQgZnJvbSB0aGUgbG9vcCBjb250ZXh0PyAqLwogICAgaWYgKGlpbmZvLT5tYWtlX2RhdGFfY29udGV4dCAmJiAhY2FsbGJhY2tfZGF0YV9jb250ZXh0KSB7CiAgICAgICAgY2FsbGJhY2tfZGF0YV9jb250ZXh0ID0KICAgICAgICAgICAgKGlpbmZvLT5tYWtlX2RhdGFfY29udGV4dCkoY2FsbGJhY2tfbG9vcF9jb250ZXh0LCBpaW5mbyk7CgogICAgfQoKICAgIC8qIHNhdmUgZGF0YSBhcyByZXF1ZXN0ZWQgKi8KICAgIHRpX2luZm8tPmRhdGFfY29udGV4dCA9IGNhbGxiYWNrX2RhdGFfY29udGV4dDsKICAgIHRpX2luZm8tPmZyZWVfY29udGV4dCA9IGlpbmZvLT5mcmVlX2RhdGFfY29udGV4dDsKICAgIHRpX2luZm8tPmJlc3RfbWF0Y2hfbGVuID0gb2lkX3RvX3NhdmVfbGVuOwogICAgdGlfaW5mby0+aWluZm8gPSBpaW5mbzsKICAgIGlmIChvaWRfdG9fc2F2ZV9sZW4pCiAgICAgICAgbWVtY3B5KHRpX2luZm8tPmJlc3RfbWF0Y2gsIG9pZF90b19zYXZlLCBvaWRfdG9fc2F2ZV9sZW4gKiBzaXplb2Yob2lkKSk7CgogICAgcmV0dXJuIHRpX2luZm87Cn0gICAgCgojZGVmaW5lIFRBQkxFX0lURVJBVE9SX05PVEFHQUlOIDI1NQovKiBpbXBsZW1lbnRzIHRoZSB0YWJsZV9pdGVyYXRvciBoZWxwZXIgKi8KaW50Cm5ldHNubXBfdGFibGVfaXRlcmF0b3JfaGVscGVyX2hhbmRsZXIobmV0c25tcF9taWJfaGFuZGxlciAqaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0cykKewogICAgbmV0c25tcF90YWJsZV9yZWdpc3RyYXRpb25faW5mbyAqdGJsX2luZm87CiAgICBuZXRzbm1wX3RhYmxlX3JlcXVlc3RfaW5mbyAqdGFibGVfaW5mbyA9IE5VTEw7CiAgICBvaWQgICAgICAgICAgICAgY29sb2lkW01BWF9PSURfTEVOXTsKICAgIHNpemVfdCAgICAgICAgICBjb2xvaWRfbGVuOwogICAgaW50ICAgICAgICAgICAgIHJldCA9IFNOTVBfRVJSX05PRVJST1I7CiAgICBzdGF0aWMgb2lkICAgICAgbXluYW1lW01BWF9PSURfTEVOXTsKICAgIHNpemVfdCAgICAgICAgICBteW5hbWVfbGVuOwogICAgaW50ICAgICAgICAgICAgIG9sZG1vZGUgPSAwOwogICAgbmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbzsKICAgIGludCBub3Rkb25lOwogICAgaW50IGhpbnRvayA9IDA7CiAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdCwgKnJlcXRtcCA9IE5VTEw7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKmluZGV4X3NlYXJjaCA9IE5VTEw7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKmZyZWVfdGhpc19pbmRleF9zZWFyY2ggPSBOVUxMOwogICAgdm9pZCAgICAgICAgICAgKmNhbGxiYWNrX2xvb3BfY29udGV4dCA9IE5VTEwsICpsYXN0X2xvb3BfY29udGV4dDsKICAgIHZvaWQgICAgICAgICAgICpjYWxsYmFja19kYXRhX2NvbnRleHQgPSBOVUxMOwogICAgdGlfY2FjaGVfaW5mbyAgKnRpX2luZm8gPSBOVUxMOwogICAgaW50ICAgICAgICAgICAgIHJlcXVlc3RfY291bnQgPSAwOwojaWZuZGVmIE5FVFNOTVBfRkVBVFVSRV9SRU1PVkVfU1RBU0hfQ0FDSEUKICAgIG5ldHNubXBfb2lkX3N0YXNoX25vZGUgKipjaW5mbyA9IE5VTEw7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKm9sZF9pbmRleGVzID0gTlVMTCwgKnZiOwogICAgbmV0c25tcF90YWJsZV9yZWdpc3RyYXRpb25faW5mbyAqdGFibGVfcmVnX2luZm8gPSBOVUxMOwogICAgaW50IGk7CiAgICBuZXRzbm1wX2RhdGFfbGlzdCAgICAqbGRhdGEgPSBOVUxMOwojZW5kaWYgLyogTkVUU05NUF9GRUFUVVJFX1JFTU9WRV9TVEFTSF9DQUNIRSAqLwoKICAgIGlpbmZvID0gKG5ldHNubXBfaXRlcmF0b3JfaW5mbyAqKSBoYW5kbGVyLT5teXZvaWQ7CiAgICBpZiAoIWlpbmZvIHx8ICFyZWdpbmZvIHx8ICFyZXFpbmZvKQogICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CgogICAgdGJsX2luZm8gPSBpaW5mby0+dGFibGVfcmVnaW5mbzsKCiAgICAvKgogICAgICogY29weSBpbiB0aGUgdGFibGUgcmVnaXN0cmF0aW9uIG9pZCBmb3IgbGF0ZXIgdXNlIAogICAgICovCiAgICBjb2xvaWRfbGVuID0gcmVnaW5mby0+cm9vdG9pZF9sZW4gKyAyOwogICAgbWVtY3B5KGNvbG9pZCwgcmVnaW5mby0+cm9vdG9pZCwgcmVnaW5mby0+cm9vdG9pZF9sZW4gKiBzaXplb2Yob2lkKSk7CiAgICBjb2xvaWRbcmVnaW5mby0+cm9vdG9pZF9sZW5dID0gMTsgICAvKiB0YWJsZS5lbnRyeSBub2RlICovCgogICAgLyoKICAgICAqIGlsbGVnYWxseSBnb3QgaGVyZSBpZiB0aGVzZSBmdW5jdGlvbnMgYXJlbid0IGRlZmluZWQgCiAgICAgKi8KICAgIGlmIChpaW5mby0+Z2V0X2ZpcnN0X2RhdGFfcG9pbnQgPT0gTlVMTCB8fAogICAgICAgIGlpbmZvLT5nZXRfbmV4dF9kYXRhX3BvaW50ID09IE5VTEwpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLAogICAgICAgICAgICAgICAgICJ0YWJsZV9pdGVyYXRvciBoZWxwZXIgY2FsbGVkIHdpdGhvdXQgZGF0YSBhY2Nlc3NvciBmdW5jdGlvbnNcbiIpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICB9CgogICAgLyogcHJlbGltaW5hcnkgYW5hbHlzaXMgKi8KICAgIHN3aXRjaCAocmVxaW5mby0+bW9kZSkgewojaWZuZGVmIE5FVFNOTVBfRkVBVFVSRV9SRU1PVkVfU1RBU0hfQ0FDSEUKICAgIGNhc2UgTU9ERV9HRVRfU1RBU0g6CiAgICAgICAgY2luZm8gPSBuZXRzbm1wX2V4dHJhY3Rfc3Rhc2hfY2FjaGUocmVxaW5mbyk7CiAgICAgICAgdGFibGVfcmVnX2luZm8gPSBuZXRzbm1wX2ZpbmRfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8ocmVnaW5mbyk7CgogICAgICAgIC8qIFhYWDogbW92ZSB0aGlzIG1hbGxvYyB0byBzdGFzaF9jYWNoZSBoYW5kbGVyPyAqLwogICAgICAgIHJlcXRtcCA9IFNOTVBfTUFMTE9DX1RZUEVERUYobmV0c25tcF9yZXF1ZXN0X2luZm8pOwogICAgICAgIGlmIChyZXF0bXAgPT0gTlVMTCkKICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0dFTkVSUjsKICAgICAgICByZXF0bXAtPnN1YnRyZWUgPSByZXF1ZXN0cy0+c3VidHJlZTsKICAgICAgICB0YWJsZV9pbmZvID0gbmV0c25tcF9leHRyYWN0X3RhYmxlX2luZm8ocmVxdWVzdHMpOwogICAgICAgIG5ldHNubXBfcmVxdWVzdF9hZGRfbGlzdF9kYXRhKHJlcXRtcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2NyZWF0ZV9kYXRhX2xpc3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoVEFCTEVfSEFORExFUl9OQU1FLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCAqKSB0YWJsZV9pbmZvLCBOVUxMKSk7CgogICAgICAgIC8qIHJlbWVtYmVyIHRoZSBpbmRleGVzIHRoYXQgd2VyZSBvcmlnaW5hbGx5IHBhcnNlZC4gKi8KICAgICAgICBvbGRfaW5kZXhlcyA9IHRhYmxlX2luZm8tPmluZGV4ZXM7CiAgICAgICAgYnJlYWs7CiNlbmRpZiAvKiBORVRTTk1QX0ZFQVRVUkVfUkVNT1ZFX1NUQVNIX0NBQ0hFICovCgogICAgY2FzZSBNT0RFX0dFVE5FWFQ6CiAgICAgICAgZm9yKHJlcXVlc3QgPSByZXF1ZXN0cyA7IHJlcXVlc3Q7IHJlcXVlc3QgPSByZXF1ZXN0LT5uZXh0KSB7CiAgICAgICAgICAgIGlmIChyZXF1ZXN0LT5wcm9jZXNzZWQpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgdGFibGVfaW5mbyA9IG5ldHNubXBfZXh0cmFjdF90YWJsZV9pbmZvKHJlcXVlc3QpOwogICAgICAgICAgICBpZiAodGFibGVfaW5mbyA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogQ2xlYW51cCAKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaWYgKGZyZWVfdGhpc19pbmRleF9zZWFyY2gpCiAgICAgICAgICAgICAgICAgICAgc25tcF9mcmVlX3ZhcmJpbmQoZnJlZV90aGlzX2luZGV4X3NlYXJjaCk7CiAgICAgICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfR0VORVJSOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICh0YWJsZV9pbmZvLT5jb2xudW0gPCB0YmxfaW5mby0+bWluX2NvbHVtbiAtIDEpIHsKICAgICAgICAgICAgICAgIC8qIFhYWDogb3B0aW1pemUgYmV0dGVyIHRoYW4gdGhpcyAqLwogICAgICAgICAgICAgICAgLyogZm9yIG5vdywganVzdCBpbmNyZWFzZSB0byBjb2xudW0tMSAqLwogICAgICAgICAgICAgICAgLyogd2UgbmVlZCB0byBqdW1wIHRvIHRoZSBsb3dlc3QgcmVzdWx0IG9mIHRoZSBtaW5fY29sdW1uCiAgICAgICAgICAgICAgICAgICBhbmQgdGFrZSBpdCwgY29tcGFyaW5nIHRvIG5vdGhpbmcgZnJvbSB0aGUgcmVxdWVzdCAqLwogICAgICAgICAgICAgICAgdGFibGVfaW5mby0+Y29sbnVtID0gdGJsX2luZm8tPm1pbl9jb2x1bW4gLSAxOwogICAgICAgICAgICB9IGVsc2UgaWYgKHRhYmxlX2luZm8tPmNvbG51bSA+IHRibF9pbmZvLT5tYXhfY29sdW1uKSB7CiAgICAgICAgICAgICAgICByZXF1ZXN0LT5wcm9jZXNzZWQgPSBUQUJMRV9JVEVSQVRPUl9OT1RBR0FJTjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGlfaW5mbyA9ICh0aV9jYWNoZV9pbmZvKikKICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9nZXRfbGlzdF9kYXRhKHJlcXVlc3QsIFRJX1JFUVVFU1RfQ0FDSEUpOwogICAgICAgICAgICBpZiAoIXRpX2luZm8pIHsKICAgICAgICAgICAgICAgIHRpX2luZm8gPSBTTk1QX01BTExPQ19UWVBFREVGKHRpX2NhY2hlX2luZm8pOwogICAgICAgICAgICAgICAgaWYgKHRpX2luZm8gPT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogQ2xlYW51cCAKICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBpZiAoZnJlZV90aGlzX2luZGV4X3NlYXJjaCkKICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9mcmVlX3ZhcmJpbmQoZnJlZV90aGlzX2luZGV4X3NlYXJjaCk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0dFTkVSUjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9hZGRfbGlzdF9kYXRhKHJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2NyZWF0ZV9kYXRhX2xpc3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChUSV9SRVFVRVNUX0NBQ0hFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpX2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9mcmVlX3RpX2NhY2hlKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIFhYWDogaWYgbm8gdmFsaWQgcmVxdWVzdHMsIGRvbid0IGV2ZW4gbG9vcCBiZWxvdyAqLwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIH0KCiAgICAvKgogICAgICogY29sbGVjdCBhbGwgaW5mb3JtYXRpb24gZm9yIGVhY2ggbmVlZGVkIHJvdwogICAgICovCiAgICBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVCB8fAogICAgICAgIHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVRORVhUIHx8CiAgICAgICAgcmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVF9TVEFTSAojaWZuZGVmIE5FVFNOTVBfTk9fV1JJVEVfU1VQUE9SVAogICAgICAgIHx8IHJlcWluZm8tPm1vZGUgPT0gTU9ERV9TRVRfUkVTRVJWRTEKI2VuZGlmIC8qIE5FVFNOTVBfTk9fV1JJVEVfU1VQUE9SVCAqLwogICAgICAgICkgewogICAgICAgIC8qCiAgICAgICAgICogQ291bnQgdGhlIG51bWJlciBvZiByZXF1ZXN0IGluIHRoZSBsaXN0LAogICAgICAgICAqICAgc28gdGhhdCB3ZSdsbCBrbm93IHdoZW4gd2UncmUgZmluaXNoZWQKICAgICAgICAgKi8KICAgICAgICBmb3IocmVxdWVzdCA9IHJlcXVlc3RzIDsgcmVxdWVzdDsgcmVxdWVzdCA9IHJlcXVlc3QtPm5leHQpCiAgICAgICAgICBpZiAoIXJlcXVlc3QtPnByb2Nlc3NlZCkKICAgICAgICAgICAgcmVxdWVzdF9jb3VudCsrOwogICAgICAgIG5vdGRvbmUgPSAxOwogICAgICAgIGhpbnRvayA9IDE7CiAgICAgICAgd2hpbGUobm90ZG9uZSkgewogICAgICAgICAgICBub3Rkb25lID0gMDsKCiAgICAgICAgICAgIC8qIGZpbmQgZmlyc3QgZGF0YSBwb2ludCAqLwogICAgICAgICAgICBpZiAoIWluZGV4X3NlYXJjaCkgewogICAgICAgICAgICAgICAgaWYgKGZyZWVfdGhpc19pbmRleF9zZWFyY2gpIHsKICAgICAgICAgICAgICAgICAgICAvKiBwcmV2aW91c2x5IGRvbmUgKi8KICAgICAgICAgICAgICAgICAgICBpbmRleF9zZWFyY2ggPSBmcmVlX3RoaXNfaW5kZXhfc2VhcmNoOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBmb3IocmVxdWVzdD1yZXF1ZXN0cyA7IHJlcXVlc3Q7IHJlcXVlc3Q9cmVxdWVzdC0+bmV4dCkgewogICAgICAgICAgICAgICAgICAgICAgICB0YWJsZV9pbmZvID0gbmV0c25tcF9leHRyYWN0X3RhYmxlX2luZm8ocmVxdWVzdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YWJsZV9pbmZvKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICghdGFibGVfaW5mbykgewogICAgICAgICAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm5vIHZhbGlkIHJlcXVlc3RzIGZvciBpdGVyYXRvciB0YWJsZSAlc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnaW5mby0+aGFuZGxlck5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2ZyZWVfcmVxdWVzdF9kYXRhX3NldHMocmVxdG1wKTsKICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9GUkVFKHJlcXRtcCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpbmRleF9zZWFyY2ggPSBzbm1wX2Nsb25lX3ZhcmJpbmQodGFibGVfaW5mby0+aW5kZXhlcyk7CiAgICAgICAgICAgICAgICAgICAgZnJlZV90aGlzX2luZGV4X3NlYXJjaCA9IGluZGV4X3NlYXJjaDsKCiAgICAgICAgICAgICAgICAgICAgLyogc2V0dXAsIG1hbGxvYyBzZWFyY2ggZGF0YTogKi8KICAgICAgICAgICAgICAgICAgICBpZiAoIWluZGV4X3NlYXJjaCkgewogICAgICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAgICAgKiBobW1tLi4uLiAgaW52YWxpZCB0YWJsZT8gCiAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImludmFsaWQgaW5kZXggbGlzdCBvciBmYWlsZWQgbWFsbG9jIGZvciB0YWJsZSAlc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnaW5mby0+aGFuZGxlck5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2ZyZWVfcmVxdWVzdF9kYXRhX3NldHMocmVxdG1wKTsKICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9GUkVFKHJlcXRtcCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogaWYgc29ydGVkLCBwYXNzIGluIGEgaGludCAqLwogICAgICAgICAgICBpZiAoaGludG9rICYmIChpaW5mby0+ZmxhZ3MgJiBORVRTTk1QX0lURVJBVE9SX0ZMQUdfU09SVEVEKSkgewogICAgICAgICAgICAgICAgY2FsbGJhY2tfbG9vcF9jb250ZXh0ID0gdGFibGVfaW5mbzsKICAgICAgICAgICAgfQogICAgICAgICAgICBpbmRleF9zZWFyY2ggPQogICAgICAgICAgICAgICAgKGlpbmZvLT5nZXRfZmlyc3RfZGF0YV9wb2ludCkgKCZjYWxsYmFja19sb29wX2NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmNhbGxiYWNrX2RhdGFfY29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleF9zZWFyY2gsIGlpbmZvKTsKCiAgICAgICAgICAgIC8qIGxvb3Agb3ZlciBlYWNoIGRhdGEgcG9pbnQgKi8KICAgICAgICAgICAgd2hpbGUoaW5kZXhfc2VhcmNoKSB7CgogICAgICAgICAgICAgICAgLyogcmVtZW1iZXIgdG8gZnJlZSB0aGlzIGxhdGVyICovCiAgICAgICAgICAgICAgICBmcmVlX3RoaXNfaW5kZXhfc2VhcmNoID0gaW5kZXhfc2VhcmNoOwogICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8qIGNvbXBhcmUgYWdhaW5zdCBlYWNoIHJlcXVlc3QqLwogICAgICAgICAgICAgICAgZm9yKHJlcXVlc3QgPSByZXF1ZXN0cyA7IHJlcXVlc3Q7IHJlcXVlc3QgPSByZXF1ZXN0LT5uZXh0KSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJlcXVlc3QtPnByb2Nlc3NlZCkKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CgogICAgICAgICAgICAgICAgICAgIC8qIFhYWDogc3RvcmUgaW4gYW4gYXJyYXkgZm9yIGZhc3RlciByZXRyaWV2YWwgKi8KICAgICAgICAgICAgICAgICAgICB0YWJsZV9pbmZvID0gbmV0c25tcF9leHRyYWN0X3RhYmxlX2luZm8ocmVxdWVzdCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRhYmxlX2luZm8gPT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAgICAgKiBDbGVhbnVwIAogICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZyZWVfdGhpc19pbmRleF9zZWFyY2gpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbm1wX2ZyZWVfdmFyYmluZChmcmVlX3RoaXNfaW5kZXhfc2VhcmNoKTsKICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9mcmVlX3JlcXVlc3RfZGF0YV9zZXRzKHJlcXRtcCk7CiAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRlJFRShyZXF0bXApOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfR0VORVJSOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjb2xvaWRbcmVnaW5mby0+cm9vdG9pZF9sZW4gKyAxXSA9IHRhYmxlX2luZm8tPmNvbG51bTsKCiAgICAgICAgICAgICAgICAgICAgdGlfaW5mbyA9ICh0aV9jYWNoZV9pbmZvKikKICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2dldF9saXN0X2RhdGEocmVxdWVzdCwgVElfUkVRVUVTVF9DQUNIRSk7CgogICAgICAgICAgICAgICAgICAgIHN3aXRjaChyZXFpbmZvLT5tb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBNT0RFX0dFVDoKI2lmbmRlZiBORVRTTk1QX05PX1dSSVRFX1NVUFBPUlQKICAgICAgICAgICAgICAgICAgICBjYXNlIE1PREVfU0VUX1JFU0VSVkUxOgojZW5kaWYgLyogTkVUU05NUF9OT19XUklURV9TVVBQT1JUICovCiAgICAgICAgICAgICAgICAgICAgICAgIC8qIGxvb2tpbmcgZm9yIGV4YWN0IG1hdGNoZXMgKi8KICAgICAgICAgICAgICAgICAgICAgICAgYnVpbGRfb2lkX25vYWxsb2MobXluYW1lLCBNQVhfT0lEX0xFTiwgJm15bmFtZV9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9pZCwgY29sb2lkX2xlbiwgaW5kZXhfc2VhcmNoKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNubXBfb2lkX2NvbXBhcmUobXluYW1lLCBteW5hbWVfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5yZXF1ZXN0dmItPm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJlcXVlc3R2Yi0+bmFtZV9sZW5ndGgpID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICoga2VlcCB0aGlzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuZXRzbm1wX2l0ZXJhdG9yX3JlbWVtYmVyKHJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBteW5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBteW5hbWVfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tfZGF0YV9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tfbG9vcF9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWluZm8pID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIENsZWFudXAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZyZWVfdGhpc19pbmRleF9zZWFyY2gpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNubXBfZnJlZV92YXJiaW5kCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZnJlZV90aGlzX2luZGV4X3NlYXJjaCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9mcmVlX3JlcXVlc3RfZGF0YV9zZXRzKHJlcXRtcCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9GUkVFKHJlcXRtcCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0dFTkVSUjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RfY291bnQtLTsgICAvKiBPbmUgbGVzcyB0byBsb29rIGZvciAqLwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlpbmZvLT5mcmVlX2RhdGFfY29udGV4dCAmJiBjYWxsYmFja19kYXRhX2NvbnRleHQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaWluZm8tPmZyZWVfZGF0YV9jb250ZXh0KShjYWxsYmFja19kYXRhX2NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWluZm8pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKI2lmbmRlZiBORVRTTk1QX0ZFQVRVUkVfUkVNT1ZFX1NUQVNIX0NBQ0hFCiAgICAgICAgICAgICAgICAgICAgY2FzZSBNT0RFX0dFVF9TVEFTSDoKICAgICAgICAgICAgICAgICAgICAgICAgLyogY29sbGVjdCBkYXRhIGZvciBlYWNoIGNvbHVtbiBmb3IgZXZlcnkgcm93ICovCiAgICAgICAgICAgICAgICAgICAgICAgIGJ1aWxkX29pZF9ub2FsbG9jKG15bmFtZSwgTUFYX09JRF9MRU4sICZteW5hbWVfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvaWQsIGNvbG9pZF9sZW4sIGluZGV4X3NlYXJjaCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlcWluZm8tPm1vZGUgPSBNT0RFX0dFVDsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcXRtcCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxkYXRhID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2dldF9saXN0X25vZGUocmVxdG1wLT5wYXJlbnRfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVEFCTEVfSVRFUkFUT1JfTkFNRSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbGRhdGEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9hZGRfbGlzdF9kYXRhKHJlcXRtcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX2RhdGFfbGlzdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFRBQkxFX0lURVJBVE9SX05BTUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tfZGF0YV9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG1heSBoYXZlIGNoYW5nZWQgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxkYXRhLT5kYXRhID0gY2FsbGJhY2tfZGF0YV9jb250ZXh0OwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICB0YWJsZV9pbmZvLT5pbmRleGVzID0gaW5kZXhfc2VhcmNoOwogICAgICAgICAgICAgICAgICAgICAgICBmb3IoaSA9IHRhYmxlX3JlZ19pbmZvLT5taW5fY29sdW1uOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA8PSAoaW50KXRhYmxlX3JlZ19pbmZvLT5tYXhfY29sdW1uOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG15bmFtZVtyZWdpbmZvLT5yb290b2lkX2xlbiArIDFdID0gaTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlX2luZm8tPmNvbG51bSA9IGk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YiA9IHJlcXRtcC0+cmVxdWVzdHZiID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX01BTExPQ19UWVBFREVGKG5ldHNubXBfdmFyaWFibGVfbGlzdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodmIgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogQ2xlYW51cCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZnJlZV90aGlzX2luZGV4X3NlYXJjaCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9mcmVlX3ZhcmJpbmQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmcmVlX3RoaXNfaW5kZXhfc2VhcmNoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfR0VORVJSOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmItPnR5cGUgPSBBU05fTlVMTDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNubXBfc2V0X3Zhcl9vYmppZCh2YiwgbXluYW1lLCBteW5hbWVfbGVuKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfY2FsbF9uZXh0X2hhbmRsZXIoaGFuZGxlciwgcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxaW5mbywgcmVxdG1wKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXRtcC0+cmVxdWVzdHZiID0gTlVMTDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXRtcC0+cHJvY2Vzc2VkID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2Yi0+dHlwZSAhPSBBU05fTlVMTCkgeyAvKiBYWFgsIG5vdCBhbGwgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX29pZF9zdGFzaF9hZGRfZGF0YShjaW5mbywgbXluYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG15bmFtZV9sZW4sIHZiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9mcmVlX3Zhcih2Yik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgcmVxaW5mby0+bW9kZSA9IE1PREVfR0VUX1NUQVNIOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKI2VuZGlmICAvKiBORVRTTk1QX0ZFQVRVUkVfUkVNT1ZFX1NUQVNIX0NBQ0hFICovCgogICAgICAgICAgICAgICAgICAgIGNhc2UgTU9ERV9HRVRORVhUOgogICAgICAgICAgICAgICAgICAgICAgICAvKiBsb29raW5nIGZvciAibmV4dCIgbWF0Y2hlcyAqLwogICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV0c25tcF9jaGVja19nZXRuZXh0X3JlcGx5CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVxdWVzdCwgY29sb2lkLCBjb2xvaWRfbGVuLCBpbmRleF9zZWFyY2gsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnRpX2luZm8tPnJlc3VsdHMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV0c25tcF9pdGVyYXRvcl9yZW1lbWJlcihyZXF1ZXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGlfaW5mby0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzLT5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGlfaW5mby0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzLT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tfZGF0YV9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tfbG9vcF9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWluZm8pID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIENsZWFudXAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZyZWVfdGhpc19pbmRleF9zZWFyY2gpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNubXBfZnJlZV92YXJiaW5kCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZnJlZV90aGlzX2luZGV4X3NlYXJjaCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0dFTkVSUjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiAgSWYgd2UndmUgYmVlbiB0b2xkIHRoYXQgdGhlIHJvd3MgYXJlIHNvcnRlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqICAgdGhlbiB0aGUgZmlyc3QgdmFsaWQgb25lIHdlIGZpbmQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqICAgbXVzdCBiZSB0aGUgcmlnaHQgb25lLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaWluZm8tPmZsYWdzICYgTkVUU05NUF9JVEVSQVRPUl9GTEFHX1NPUlRFRCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0X2NvdW50LS07CiAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlpbmZvLT5mcmVlX2RhdGFfY29udGV4dCAmJiBjYWxsYmFja19kYXRhX2NvbnRleHQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaWluZm8tPmZyZWVfZGF0YV9jb250ZXh0KShjYWxsYmFja19kYXRhX2NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWluZm8pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKI2lmbmRlZiBORVRTTk1QX05PX1dSSVRFX1NVUFBPUlQKICAgICAgICAgICAgICAgICAgICBjYXNlIE1PREVfU0VUX1JFU0VSVkUyOgogICAgICAgICAgICAgICAgICAgIGNhc2UgTU9ERV9TRVRfRlJFRToKICAgICAgICAgICAgICAgICAgICBjYXNlIE1PREVfU0VUX1VORE86CiAgICAgICAgICAgICAgICAgICAgY2FzZSBNT0RFX1NFVF9DT01NSVQ6CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIG5lZWRlZCBwcm9jZXNzaW5nIGFscmVhZHkgZG9uZSBpbiBSRVNFUlZFMSAqLwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKI2VuZGlmIC8qIE5FVFNOTVBfTk9fV1JJVEVfU1VQUE9SVCAqLwoKICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFibGVfaXRlcmF0b3IgY2FsbGVkIHdpdGggdW5zdXBwb3J0ZWQgbW9kZVxuIik7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOyAgLyogWFhYIHJldHVybiAqLwogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8qIElzIHRoZXJlIGFueSBwb2ludCBpbiBjYXJyeWluZyBvbj8gKi8KICAgICAgICAgICAgICAgIGlmICghcmVxdWVzdF9jb3VudCkKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIC8qIGdldCB0aGUgbmV4dCBzZWFyY2ggcG9zc2liaWxpdHkgKi8KICAgICAgICAgICAgICAgIGxhc3RfbG9vcF9jb250ZXh0ID0gY2FsbGJhY2tfbG9vcF9jb250ZXh0OwogICAgICAgICAgICAgICAgaW5kZXhfc2VhcmNoID0KICAgICAgICAgICAgICAgICAgICAoaWluZm8tPmdldF9uZXh0X2RhdGFfcG9pbnQpICgmY2FsbGJhY2tfbG9vcF9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjYWxsYmFja19kYXRhX2NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXhfc2VhcmNoLCBpaW5mbyk7CiAgICAgICAgICAgICAgICBpZiAoaWluZm8tPmZyZWVfbG9vcF9jb250ZXh0ICYmIGxhc3RfbG9vcF9jb250ZXh0ICYmCiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tfZGF0YV9jb250ZXh0ICE9IGxhc3RfbG9vcF9jb250ZXh0KSB7CiAgICAgICAgICAgICAgICAgICAgKGlpbmZvLT5mcmVlX2xvb3BfY29udGV4dCkgKGxhc3RfbG9vcF9jb250ZXh0LCBpaW5mbyk7CiAgICAgICAgICAgICAgICAgICAgbGFzdF9sb29wX2NvbnRleHQgPSBOVUxMOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBmcmVlIGxvb3AgY29udGV4dCBiZWZvcmUgZ29pbmcgb24gKi8KICAgICAgICAgICAgaWYgKGNhbGxiYWNrX2xvb3BfY29udGV4dCAmJiBpaW5mby0+ZnJlZV9sb29wX2NvbnRleHRfYXRfZW5kKSB7CiAgICAgICAgICAgICAgICAoaWluZm8tPmZyZWVfbG9vcF9jb250ZXh0X2F0X2VuZCkgKGNhbGxiYWNrX2xvb3BfY29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWluZm8pOwogICAgICAgICAgICAgICAgY2FsbGJhY2tfbG9vcF9jb250ZXh0ID0gTlVMTDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogZGVjaWRlIHdoaWNoIChHRVRORVhUKSByZXF1ZXN0cyBhcmUgbm90IHlldCBmaWxsZWQgKi8KICAgICAgICAgICAgaWYgKHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVRORVhUKSB7CiAgICAgICAgICAgICAgICBmb3IocmVxdWVzdCA9IHJlcXVlc3RzIDsgcmVxdWVzdDsgcmVxdWVzdCA9IHJlcXVlc3QtPm5leHQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAocmVxdWVzdC0+cHJvY2Vzc2VkKQogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB0aV9pbmZvID0gKHRpX2NhY2hlX2luZm8qKQogICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfZ2V0X2xpc3RfZGF0YShyZXF1ZXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUSV9SRVFVRVNUX0NBQ0hFKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIXRpX2luZm8tPnJlc3VsdHMpIHsKICAgICAgICAgICAgICAgICAgICAgIGludCBuYzsKICAgICAgICAgICAgICAgICAgICAgICAgdGFibGVfaW5mbyA9IG5ldHNubXBfZXh0cmFjdF90YWJsZV9pbmZvKHJlcXVlc3QpOwogICAgICAgICAgICAgICAgICAgICAgICBuYyA9IG5ldHNubXBfdGFibGVfbmV4dF9jb2x1bW4odGFibGVfaW5mbyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgwID09IG5jKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvaWRbcmVnaW5mby0+cm9vdG9pZF9sZW4rMV0gPSB0YWJsZV9pbmZvLT5jb2xudW0rMTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNubXBfc2V0X3Zhcl9vYmppZChyZXF1ZXN0LT5yZXF1ZXN0dmIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb2lkLCByZWdpbmZvLT5yb290b2lkX2xlbisyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPnByb2Nlc3NlZCA9IFRBQkxFX0lURVJBVE9SX05PVEFHQUlOOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgdGFibGVfaW5mby0+Y29sbnVtID0gbmM7CiAgICAgICAgICAgICAgICAgICAgICAgICAgaGludG9rID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgICBub3Rkb25lID0gMTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVCB8fAogICAgICAgIHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVRORVhUCiNpZm5kZWYgTkVUU05NUF9OT19XUklURV9TVVBQT1JUCiAgICAgICAgfHwgcmVxaW5mby0+bW9kZSA9PSBNT0RFX1NFVF9SRVNFUlZFMQojZW5kaWYgLyogTkVUU05NUF9OT19XUklURV9TVVBQT1JUICovCiAgICAgICAgKSB7CiAgICAgICAgLyogcGVyIHJlcXVlc3QgbGFzdCBtaW51dGUgcHJvY2Vzc2luZyAqLwogICAgICAgIGZvcihyZXF1ZXN0ID0gcmVxdWVzdHMgOyByZXF1ZXN0OyByZXF1ZXN0ID0gcmVxdWVzdC0+bmV4dCkgewogICAgICAgICAgICBpZiAocmVxdWVzdC0+cHJvY2Vzc2VkKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIHRpX2luZm8gPSAodGlfY2FjaGVfaW5mbyopCiAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfZ2V0X2xpc3RfZGF0YShyZXF1ZXN0LCBUSV9SRVFVRVNUX0NBQ0hFKTsKICAgICAgICAgICAgdGFibGVfaW5mbyA9CiAgICAgICAgICAgICAgICBuZXRzbm1wX2V4dHJhY3RfdGFibGVfaW5mbyhyZXF1ZXN0KTsKCiAgICAgICAgICAgIGlmICghdGlfaW5mbykKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIAogICAgICAgICAgICBzd2l0Y2gocmVxaW5mby0+bW9kZSkgewoKICAgICAgICAgICAgY2FzZSBNT0RFX0dFVE5FWFQ6CiAgICAgICAgICAgICAgICBpZiAodGlfaW5mby0+YmVzdF9tYXRjaF9sZW4pCiAgICAgICAgICAgICAgICAgICAgc25tcF9zZXRfdmFyX29iamlkKHJlcXVlc3QtPnJlcXVlc3R2YiwgdGlfaW5mby0+YmVzdF9tYXRjaCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGlfaW5mby0+YmVzdF9tYXRjaF9sZW4pOwogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgY29sb2lkW3JlZ2luZm8tPnJvb3RvaWRfbGVuKzFdID0gCiAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdGFibGVfbmV4dF9jb2x1bW4odGFibGVfaW5mbyk7CiAgICAgICAgICAgICAgICAgICAgaWYgKDAgPT0gY29sb2lkW3JlZ2luZm8tPnJvb3RvaWRfbGVuKzFdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIG91dCBvZiByYW5nZS4gKi8KICAgICAgICAgICAgICAgICAgICAgICAgY29sb2lkW3JlZ2luZm8tPnJvb3RvaWRfbGVuKzFdID0gdGJsX2luZm8tPm1heF9jb2x1bW4gKyAxOwogICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5wcm9jZXNzZWQgPSBUQUJMRV9JVEVSQVRPUl9OT1RBR0FJTjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgc25tcF9zZXRfdmFyX29iamlkKHJlcXVlc3QtPnJlcXVlc3R2YiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb2lkLCByZWdpbmZvLT5yb290b2lkX2xlbisyKTsKICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5wcm9jZXNzZWQgPSAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgc25tcF9mcmVlX3ZhcmJpbmQodGFibGVfaW5mby0+aW5kZXhlcyk7CiAgICAgICAgICAgICAgICB0YWJsZV9pbmZvLT5pbmRleGVzID0gc25tcF9jbG9uZV92YXJiaW5kKHRpX2luZm8tPnJlc3VsdHMpOwogICAgICAgICAgICAgICAgLyogRkFMTCBUSFJPVUdIICovCgogICAgICAgICAgICBjYXNlIE1PREVfR0VUOgojaWZuZGVmIE5FVFNOTVBfTk9fV1JJVEVfU1VQUE9SVAogICAgICAgICAgICBjYXNlIE1PREVfU0VUX1JFU0VSVkUxOgojZW5kaWYgLyogTkVUU05NUF9OT19XUklURV9TVVBQT1JUICovCiAgICAgICAgICAgICAgICBpZiAodGlfaW5mby0+ZGF0YV9jb250ZXh0KQogICAgICAgICAgICAgICAgICAgIC8qIHdlIGRvbid0IGFkZCBhIGZyZWUgcG9pbnRlciwgc2luY2UgaXQncyBpbiB0aGUKICAgICAgICAgICAgICAgICAgICAgICBUSV9SRVFVRVNUX0NBQ0hFIGluc3RlYWQgKi8KICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfYWRkX2xpc3RfZGF0YShyZXF1ZXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX2RhdGFfbGlzdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChUQUJMRV9JVEVSQVRPUl9OQU1FLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aV9pbmZvLT5kYXRhX2NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAvKiB3ZSBjaGFuZ2UgYWxsIEdFVE5FWFQgb3BlcmF0aW9ucyBpbnRvIEdFVCBvcGVyYXRpb25zLgogICAgICAgICAgIHdoeT8gYmVjYXVzZSB3ZSdyZSBqdXN0IHNvIG5pY2UgdG8gdGhlIGxvd2VyIGxldmVscy4KICAgICAgICAgICBtYXliZSBzb21lZGF5IHRoZXknbGwgcGF5IHVzIGZvciBpdC4gIGRvdWJ0ZnVsIHRob3VnaC4gKi8KICAgICAgICBvbGRtb2RlID0gcmVxaW5mby0+bW9kZTsKICAgICAgICBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVE5FWFQpIHsKICAgICAgICAgICAgcmVxaW5mby0+bW9kZSA9IE1PREVfR0VUOwogICAgICAgIH0KI2lmbmRlZiBORVRTTk1QX0ZFQVRVUkVfUkVNT1ZFX1NUQVNIX0NBQ0hFCiAgICB9IGVsc2UgaWYgKHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVRfU1RBU0gpIHsKICAgICAgICBuZXRzbm1wX2ZyZWVfcmVxdWVzdF9kYXRhX3NldHMocmVxdG1wKTsKICAgICAgICBTTk1QX0ZSRUUocmVxdG1wKTsKICAgICAgICB0YWJsZV9pbmZvLT5pbmRleGVzID0gb2xkX2luZGV4ZXM7CiNlbmRpZiAgLyogTkVUU05NUF9GRUFUVVJFX1JFTU9WRV9TVEFTSF9DQUNIRSAqLwogICAgfQoKCiAgICAvKiBGaW5hbGx5LCB3ZSBnZXQgdG8gY2FsbCB0aGUgbmV4dCBoYW5kbGVyIGJlbG93IHVzLiAgQm95LCB3YXNuJ3QKICAgICAgIGFsbCB0aGF0IHNpbXBsZT8gIFRoZXkgYmV0dGVyIGJlIGdsYWQgdGhleSBkb24ndCBoYXZlIHRvIGRvIGl0ISAqLwogICAgaWYgKHJlcWluZm8tPm1vZGUgIT0gTU9ERV9HRVRfU1RBU0gpIHsKICAgICAgICBERUJVR01TR1RMKCgidGFibGVfaXRlcmF0b3IiLCAiY2FsbCBzdWJoYW5kbGVyIGZvciBtb2RlOiAlc1xuIiwKICAgICAgICAgICAgICAgICAgICBzZV9maW5kX2xhYmVsX2luX3NsaXN0KCJhZ2VudF9tb2RlIiwgb2xkbW9kZSkpKTsKICAgICAgICByZXQgPQogICAgICAgICAgICBuZXRzbm1wX2NhbGxfbmV4dF9oYW5kbGVyKGhhbmRsZXIsIHJlZ2luZm8sIHJlcWluZm8sIHJlcXVlc3RzKTsKICAgIH0KCiAgICAvKiByZXZlcnNlIHRoZSBwcmV2aW91c2x5IHNhdmVkIG1vZGUgaWYgd2Ugd2VyZSBhIGdldG5leHQgKi8KICAgIGlmIChvbGRtb2RlID09IE1PREVfR0VUTkVYVCkgewogICAgICAgIHJlcWluZm8tPm1vZGUgPSBvbGRtb2RlOwogICAgfQoKICAgIC8qIGNsZWFudXAgKi8KICAgIGlmIChmcmVlX3RoaXNfaW5kZXhfc2VhcmNoKQogICAgICAgIHNubXBfZnJlZV92YXJiaW5kKGZyZWVfdGhpc19pbmRleF9zZWFyY2gpOwoKICAgIHJldHVybiByZXQ7Cn0KCi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICoKICogSXRlcmF0b3IgQVBJOiBSb3cgb3BlcmF0aW9ucwogKgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovCgojaWZuZGVmIE5FVFNOTVBfRkVBVFVSRV9SRU1PVkVfVEFCTEVfSVRFUkFUT1JfUk9XX0ZJUlNUCnZvaWQgKgpuZXRzbm1wX2l0ZXJhdG9yX3Jvd19maXJzdCggbmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbyApIHsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdnAxLCAqdnAyOwogICAgdm9pZCAqY3R4MSwgKmN0eDI7CgogICAgaWYgKCFpaW5mbykKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICB2cDEgPSBzbm1wX2Nsb25lX3ZhcmJpbmQoaWluZm8tPmluZGV4ZXMpOwogICAgdnAyID0gaWluZm8tPmdldF9maXJzdF9kYXRhX3BvaW50KCAmY3R4MSwgJmN0eDIsIHZwMSwgaWluZm8gKTsKCiAgICBpZiAoIXZwMikKICAgICAgICBjdHgyID0gTlVMTDsKCiAgICAvKiBmcmVlIGxvb3AgY29udGV4dCA/PyAqLwogICAgc25tcF9mcmVlX3ZhcmJpbmQoIHZwMSApOwogICAgcmV0dXJuIGN0eDI7ICAvKiBvciAqY3R4MiA/PyAqLwp9CiNlbmRpZiAvKiBORVRTTk1QX0ZFQVRVUkVfUkVNT1ZFX1RBQkxFX0lURVJBVE9SX1JPV19GSVJTVCAqLwoKdm9pZCAqCm5ldHNubXBfaXRlcmF0b3Jfcm93X2dldCggbmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbywgdm9pZCAqcm93ICkKewogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2cDEsICp2cDI7CiAgICB2b2lkICpjdHgxLCAqY3R4MjsKCiAgICBpZiAoIWlpbmZvIHx8ICFyb3cpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgICAgIC8qCiAgICAgICAgICogVGhpcyByb3V0aW5lIHJlbGllcyBvbiBiZWluZyBhYmxlIHRvCiAgICAgICAgICogICBkZXRlcm1pbmUgdGhlIGluZGV4ZXMgZm9yIGEgZ2l2ZW4gcm93LiAgCiAgICAgICAgICovCiAgICBpZiAoIWlpbmZvLT5nZXRfcm93X2luZGV4ZXMpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgdnAxICA9IHNubXBfY2xvbmVfdmFyYmluZChpaW5mby0+aW5kZXhlcyk7CiAgICBjdHgxID0gcm93OyAgIC8qIFByb2JhYmx5IG9ubHkgbmVlZCBvbmUgb2YgdGhlc2UgLi4uICovCiAgICBjdHgyID0gcm93OwogICAgdnAyICA9IGlpbmZvLT5nZXRfcm93X2luZGV4ZXMoICZjdHgxLCAmY3R4MiwgdnAxLCBpaW5mbyApOwoKICAgIGN0eDIgPSBOVUxMOwogICAgaWYgKHZwMikgewogICAgICAgIGN0eDIgPSBuZXRzbm1wX2l0ZXJhdG9yX3Jvd19nZXRfYnlpZHgoIGlpbmZvLCB2cDIgKTsKICAgIH0KICAgIHNubXBfZnJlZV92YXJiaW5kKCB2cDEgKTsKICAgIHJldHVybiBjdHgyOwp9Cgp2b2lkICoKbmV0c25tcF9pdGVyYXRvcl9yb3dfbmV4dCggbmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbywgdm9pZCAqcm93ICkKewogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2cDEsICp2cDI7CiAgICB2b2lkICpjdHgxLCAqY3R4MjsKCiAgICBpZiAoIWlpbmZvIHx8ICFyb3cpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgICAgIC8qCiAgICAgICAgICogVGhpcyByb3V0aW5lIHJlbGllcyBvbiBiZWluZyBhYmxlIHRvCiAgICAgICAgICogICBkZXRlcm1pbmUgdGhlIGluZGV4ZXMgZm9yIGEgZ2l2ZW4gcm93LiAgCiAgICAgICAgICovCiAgICBpZiAoIWlpbmZvLT5nZXRfcm93X2luZGV4ZXMpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgdnAxICA9IHNubXBfY2xvbmVfdmFyYmluZChpaW5mby0+aW5kZXhlcyk7CiAgICBjdHgxID0gcm93OyAgIC8qIFByb2JhYmx5IG9ubHkgbmVlZCBvbmUgb2YgdGhlc2UgLi4uICovCiAgICBjdHgyID0gcm93OwogICAgdnAyICA9IGlpbmZvLT5nZXRfcm93X2luZGV4ZXMoICZjdHgxLCAmY3R4MiwgdnAxLCBpaW5mbyApOwoKICAgIGN0eDIgPSBOVUxMOwogICAgaWYgKHZwMikgewogICAgICAgIGN0eDIgPSBuZXRzbm1wX2l0ZXJhdG9yX3Jvd19uZXh0X2J5aWR4KCBpaW5mbywgdnAyICk7CiAgICB9CiAgICBzbm1wX2ZyZWVfdmFyYmluZCggdnAxICk7CiAgICByZXR1cm4gY3R4MjsKfQoKdm9pZCAqCm5ldHNubXBfaXRlcmF0b3Jfcm93X2dldF9ieWlkeCggIG5ldHNubXBfaXRlcmF0b3JfaW5mbyAqaWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqaW5kZXhlcyApCnsKICAgIG9pZCAgICBkdW1teVtdID0gezAsMH07ICAgLyogS2VlcCAnYnVpbGRfb2lkJyBoYXBweSAqLwogICAgb2lkICAgIGluc3RhbmNlW01BWF9PSURfTEVOXTsKICAgIHNpemVfdCBsZW4gPSAgICBNQVhfT0lEX0xFTjsKCiAgICBpZiAoIWlpbmZvIHx8ICFpbmRleGVzKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIGJ1aWxkX29pZF9ub2FsbG9jKGluc3RhbmNlLCBNQVhfT0lEX0xFTiwgJmxlbiwKICAgICAgICAgICAgICAgICAgICAgIGR1bW15LCAyLCBpbmRleGVzKTsKICAgIHJldHVybiBuZXRzbm1wX2l0ZXJhdG9yX3Jvd19nZXRfYnlvaWQoIGlpbmZvLCBpbnN0YW5jZSsyLCBsZW4tMiApOwp9Cgp2b2lkICoKbmV0c25tcF9pdGVyYXRvcl9yb3dfbmV4dF9ieWlkeCggbmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICppbmRleGVzICkKewogICAgb2lkICAgIGR1bW15W10gPSB7MCwwfTsKICAgIG9pZCAgICBpbnN0YW5jZVtNQVhfT0lEX0xFTl07CiAgICBzaXplX3QgbGVuID0gICAgTUFYX09JRF9MRU47CgogICAgaWYgKCFpaW5mbyB8fCAhaW5kZXhlcykKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICBidWlsZF9vaWRfbm9hbGxvYyhpbnN0YW5jZSwgTUFYX09JRF9MRU4sICZsZW4sCiAgICAgICAgICAgICAgICAgICAgICBkdW1teSwgMiwgaW5kZXhlcyk7CiAgICByZXR1cm4gbmV0c25tcF9pdGVyYXRvcl9yb3dfbmV4dF9ieW9pZCggaWluZm8sIGluc3RhbmNlKzIsIGxlbi0yICk7Cn0KCnZvaWQgKgpuZXRzbm1wX2l0ZXJhdG9yX3Jvd19nZXRfYnlvaWQoICBuZXRzbm1wX2l0ZXJhdG9yX2luZm8gKmlpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvaWQgKmluc3RhbmNlLCBzaXplX3QgbGVuICkKewogICAgb2lkICAgIGR1bW15W10gPSB7MCwwfTsKICAgIG9pZCAgICB0aGlzX2luc3RbIE1BWF9PSURfTEVOXTsKICAgIHNpemVfdCB0aGlzX2xlbjsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdnAxLCAqdnAyOwogICAgdm9pZCAqY3R4MSwgKmN0eDI7CiAgICBpbnQgICBuOwoKICAgIGlmICghaWluZm8gfHwgIWlpbmZvLT5nZXRfZmlyc3RfZGF0YV9wb2ludAogICAgICAgICAgICAgICB8fCAhaWluZm8tPmdldF9uZXh0X2RhdGFfcG9pbnQgKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIGlmICggIWluc3RhbmNlIHx8ICFsZW4gKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIHZwMSA9IHNubXBfY2xvbmVfdmFyYmluZChpaW5mby0+aW5kZXhlcyk7CiAgICB2cDIgPSBpaW5mby0+Z2V0X2ZpcnN0X2RhdGFfcG9pbnQoICZjdHgxLCAmY3R4MiwgdnAxLCBpaW5mbyApOwogICAgREVCVUdNU0dUTCgoInRhYmxlOml0ZXJhdG9yOmdldCIsICJmaXJzdCBEUDogJXAgJXAgJXBcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eDEsIGN0eDIsIHZwMikpOwoKICAgIC8qIFhYWCAtIGZyZWUgY29udGV4dCA/ICovCiAgICAKICAgIHdoaWxlICggdnAyICkgewogICAgICAgIHRoaXNfbGVuID0gTUFYX09JRF9MRU47CiAgICAgICAgYnVpbGRfb2lkX25vYWxsb2ModGhpc19pbnN0LCBNQVhfT0lEX0xFTiwgJnRoaXNfbGVuLCBkdW1teSwgMiwgdnAyKTsKICAgICAgICBuID0gc25tcF9vaWRfY29tcGFyZSggaW5zdGFuY2UsIGxlbiwgdGhpc19pbnN0KzIsIHRoaXNfbGVuLTIgKTsKICAgICAgICBpZiAoIG4gPT0gMCApCiAgICAgICAgICAgIGJyZWFrOyAgLyogRm91bmQgbWF0Y2hpbmcgcm93ICovCgogICAgICAgIGlmICgoIG4gPiAwKSAmJgogICAgICAgICAgICAoaWluZm8tPmZsYWdzICYgTkVUU05NUF9JVEVSQVRPUl9GTEFHX1NPUlRFRCkpIHsKICAgICAgICAgICAgdnAyID0gTlVMTDsgIC8qIFJvdyBub3QgcHJlc2VudCAqLwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdnAyID0gaWluZm8tPmdldF9uZXh0X2RhdGFfcG9pbnQoICZjdHgxLCAmY3R4MiwgdnAyLCBpaW5mbyApOwogICAgICAgIERFQlVHTVNHVEwoKCJ0YWJsZTppdGVyYXRvcjpnZXQiLCAibmV4dCBEUDogJXAgJXAgJXBcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHgxLCBjdHgyLCB2cDIpKTsKICAgICAgICAvKiBYWFggLSBmcmVlIGNvbnRleHQgPyAqLwogICAgfQogICAgICAgICAgIAogICAgLyogWFhYIC0gZmluYWwgZnJlZSBjb250ZXh0ID8gKi8KICAgIHNubXBfZnJlZV92YXJiaW5kKCB2cDEgKTsKCiAgICByZXR1cm4gKCB2cDIgPyBjdHgyIDogTlVMTCApOwp9Cgp2b2lkICoKbmV0c25tcF9pdGVyYXRvcl9yb3dfbmV4dF9ieW9pZCggbmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2lkICppbnN0YW5jZSwgc2l6ZV90IGxlbiApCnsKICAgIG9pZCAgICBkdW1teVtdID0gezAsMH07CiAgICBvaWQgICAgdGhpc19pbnN0WyBNQVhfT0lEX0xFTl07CiAgICBzaXplX3QgdGhpc19sZW47CiAgICBvaWQgICAgYmVzdF9pbnN0WyBNQVhfT0lEX0xFTl07CiAgICBzaXplX3QgYmVzdF9sZW4gPSAwOwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2cDEsICp2cDI7CiAgICB2b2lkICpjdHgxLCAqY3R4MjsKICAgIGludCAgIG47CgogICAgaWYgKCFpaW5mbyB8fCAhaWluZm8tPmdldF9maXJzdF9kYXRhX3BvaW50CiAgICAgICAgICAgICAgIHx8ICFpaW5mby0+Z2V0X25leHRfZGF0YV9wb2ludCApCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgdnAxID0gc25tcF9jbG9uZV92YXJiaW5kKGlpbmZvLT5pbmRleGVzKTsKICAgIHZwMiA9IGlpbmZvLT5nZXRfZmlyc3RfZGF0YV9wb2ludCggJmN0eDEsICZjdHgyLCB2cDEsIGlpbmZvICk7CiAgICBERUJVR01TR1RMKCgidGFibGU6aXRlcmF0b3I6Z2V0IiwgImZpcnN0IERQOiAlcCAlcCAlcFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4MSwgY3R4MiwgdnAyKSk7CgogICAgaWYgKCAhaW5zdGFuY2UgfHwgIWxlbiApIHsKICAgICAgICBzbm1wX2ZyZWVfdmFyYmluZCggdnAxICk7CiAgICAgICAgcmV0dXJuICggdnAyID8gY3R4MiA6IE5VTEwgKTsgICAvKiBGaXJzdCBlbnRyeSAqLwogICAgfQoKICAgIC8qIFhYWCAtIGZyZWUgY29udGV4dCA/ICovCiAgICAKICAgIHdoaWxlICggdnAyICkgewogICAgICAgIHRoaXNfbGVuID0gTUFYX09JRF9MRU47CiAgICAgICAgYnVpbGRfb2lkX25vYWxsb2ModGhpc19pbnN0LCBNQVhfT0lEX0xFTiwgJnRoaXNfbGVuLCBkdW1teSwgMiwgdnAyKTsKICAgICAgICBuID0gc25tcF9vaWRfY29tcGFyZSggaW5zdGFuY2UsIGxlbiwgdGhpc19pbnN0KzIsIHRoaXNfbGVuLTIgKTsKCiAgICAgICAgLyoKICAgICAgICAgKiBMb29rIGZvciB0aGUgYmVzdC1maXQgY2FuZGlkYXRlIGZvciB0aGUgbmV4dCByb3cKICAgICAgICAgKiAgIChiZWFyaW5nIGluIG1pbmQgdGhlIHJvd3MgbWF5IG5vdCBiZSBvcmRlcmVkICJjb3JyZWN0bHkiKQogICAgICAgICAqLwogICAgICAgIGlmICggbiA+IDAgKSB7CiAgICAgICAgICAgIGlmICggYmVzdF9sZW4gPT0gMCApIHsKICAgICAgICAgICAgICAgIG1lbWNweSggYmVzdF9pbnN0LCB0aGlzX2luc3QsIHNpemVvZiggdGhpc19pbnN0ICkpOwogICAgICAgICAgICAgICAgYmVzdF9sZW4gPSB0aGlzX2xlbjsKICAgICAgICAgICAgICAgIGlmIChpaW5mby0+ZmxhZ3MgJiBORVRTTk1QX0lURVJBVE9SX0ZMQUdfU09SVEVEKQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbiA9IHNubXBfb2lkX2NvbXBhcmUoIGJlc3RfaW5zdCwgYmVzdF9sZW4sIHRoaXNfaW5zdCwgdGhpc19sZW4gKTsKICAgICAgICAgICAgICAgIGlmICggbiA8IDAgKSB7CiAgICAgICAgICAgICAgICAgICAgbWVtY3B5KCBiZXN0X2luc3QsIHRoaXNfaW5zdCwgc2l6ZW9mKCB0aGlzX2luc3QgKSk7CiAgICAgICAgICAgICAgICAgICAgYmVzdF9sZW4gPSB0aGlzX2xlbjsKICAgICAgICAgICAgICAgICAgICBpZiAoaWluZm8tPmZsYWdzICYgTkVUU05NUF9JVEVSQVRPUl9GTEFHX1NPUlRFRCkKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdnAyID0gaWluZm8tPmdldF9uZXh0X2RhdGFfcG9pbnQoICZjdHgxLCAmY3R4MiwgdnAyLCBpaW5mbyApOwogICAgICAgIERFQlVHTVNHVEwoKCJ0YWJsZTppdGVyYXRvcjpnZXQiLCAibmV4dCBEUDogJXAgJXAgJXBcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHgxLCBjdHgyLCB2cDIpKTsKICAgICAgICAvKiBYWFggLSBmcmVlIGNvbnRleHQgPyAqLwogICAgfQogICAgICAgICAgIAogICAgLyogWFhYIC0gZmluYWwgZnJlZSBjb250ZXh0ID8gKi8KICAgIHNubXBfZnJlZV92YXJiaW5kKCB2cDEgKTsKCiAgICByZXR1cm4gKCB2cDIgPyBjdHgyIDogTlVMTCApOwp9CgojaWZuZGVmIE5FVFNOTVBfRkVBVFVSRV9SRU1PVkVfVEFCTEVfSVRFUkFUT1JfUk9XX0NPVU5UCmludApuZXRzbm1wX2l0ZXJhdG9yX3Jvd19jb3VudCggbmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbyApCnsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdnAxLCAqdnAyOwogICAgdm9pZCAqY3R4MSwgKmN0eDI7CiAgICBpbnQgICBpPTA7CgogICAgaWYgKCFpaW5mbyB8fCAhaWluZm8tPmdldF9maXJzdF9kYXRhX3BvaW50CiAgICAgICAgICAgICAgIHx8ICFpaW5mby0+Z2V0X25leHRfZGF0YV9wb2ludCApCiAgICAgICAgcmV0dXJuIDA7CgogICAgdnAxID0gc25tcF9jbG9uZV92YXJiaW5kKGlpbmZvLT5pbmRleGVzKTsKICAgIHZwMiA9IGlpbmZvLT5nZXRfZmlyc3RfZGF0YV9wb2ludCggJmN0eDEsICZjdHgyLCB2cDEsIGlpbmZvICk7CiAgICBpZiAoIXZwMikgewogICAgICAgIHNubXBfZnJlZV92YXJiaW5kKCB2cDEgKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIAogICAgREVCVUdNU0dUTCgoInRhYmxlOml0ZXJhdG9yOmNvdW50IiwgImZpcnN0IERQOiAlcCAlcCAlcFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHgxLCBjdHgyLCB2cDIpKTsKCiAgICAvKiBYWFggLSBmcmVlIGNvbnRleHQgPyAqLwoKICAgIHdoaWxlICh2cDIpIHsKICAgICAgICBpKys7CiAgICAgICAgdnAyID0gaWluZm8tPmdldF9uZXh0X2RhdGFfcG9pbnQoICZjdHgxLCAmY3R4MiwgdnAyLCBpaW5mbyApOwogICAgICAgIERFQlVHTVNHVEwoKCJ0YWJsZTppdGVyYXRvcjpjb3VudCIsICJuZXh0IERQOiAlcCAlcCAlcCAoJWQpXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHgxLCBjdHgyLCB2cDIsIGkpKTsKICAgICAgICAvKiBYWFggLSBmcmVlIGNvbnRleHQgPyAqLwogICAgfQogICAgICAgICAgIAogICAgLyogWFhYIC0gZmluYWwgZnJlZSBjb250ZXh0ID8gKi8KICAgIHNubXBfZnJlZV92YXJiaW5kKCB2cDEgKTsKICAgIHJldHVybiBpOwp9CiNlbmRpZiAvKiBORVRTTk1QX0ZFQVRVUkVfUkVNT1ZFX1RBQkxFX0lURVJBVE9SX1JPV19DT1VOVCAqLwoKCi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICoKICogSXRlcmF0b3IgQVBJOiBJbmRleCBvcGVyYXRpb25zCiAqCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi8KCgovKiogQH0gKi8K