LyogRnVuY3Rpb25zIHJlbGF0ZWQgdG8gYnVpbGRpbmcgY2xhc3NlcyBhbmQgdGhlaXIgcmVsYXRlZCBvYmplY3RzLgogICBDb3B5cmlnaHQgKEMpIDE5ODcsIDE5OTIsIDE5OTMsIDE5OTQsIDE5OTUsIDE5OTYsIDE5OTcsIDE5OTgsCiAgIDE5OTksIDIwMDAsIDIwMDEsIDIwMDIsIDIwMDMsIDIwMDQsIDIwMDUgIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgSW5jLgogICBDb250cmlidXRlZCBieSBNaWNoYWVsIFRpZW1hbm4gKHRpZW1hbm5AY3lnbnVzLmNvbSkKClRoaXMgZmlsZSBpcyBwYXJ0IG9mIEdDQy4KCkdDQyBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5Cml0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CnRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIsIG9yIChhdCB5b3VyIG9wdGlvbikKYW55IGxhdGVyIHZlcnNpb24uCgpHQ0MgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQpHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgoKWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKYWxvbmcgd2l0aCBHQ0M7IHNlZSB0aGUgZmlsZSBDT1BZSU5HLiAgSWYgbm90LCB3cml0ZSB0bwp0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsCkJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLiAgKi8KCgovKiBIaWdoLWxldmVsIGNsYXNzIGludGVyZmFjZS4gICovCgojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJzeXN0ZW0uaCIKI2luY2x1ZGUgImNvcmV0eXBlcy5oIgojaW5jbHVkZSAidG0uaCIKI2luY2x1ZGUgInRyZWUuaCIKI2luY2x1ZGUgImNwLXRyZWUuaCIKI2luY2x1ZGUgImZsYWdzLmgiCiNpbmNsdWRlICJydGwuaCIKI2luY2x1ZGUgIm91dHB1dC5oIgojaW5jbHVkZSAidG9wbGV2LmgiCiNpbmNsdWRlICJ0YXJnZXQuaCIKI2luY2x1ZGUgImNvbnZlcnQuaCIKLyogQVBQTEUgTE9DQUwgS0VYVCAqLwojaW5jbHVkZSAidHJlZS1pdGVyYXRvci5oIgojaW5jbHVkZSAiY2dyYXBoLmgiCgovKiBUaGUgbnVtYmVyIG9mIG5lc3RlZCBjbGFzc2VzIGJlaW5nIHByb2Nlc3NlZC4gIElmIHdlIGFyZSBub3QgaW4gdGhlCiAgIHNjb3BlIG9mIGFueSBjbGFzcywgdGhpcyBpcyB6ZXJvLiAgKi8KCmludCBjdXJyZW50X2NsYXNzX2RlcHRoOwoKLyogSW4gb3JkZXIgdG8gZGVhbCB3aXRoIG5lc3RlZCBjbGFzc2VzLCB3ZSBrZWVwIGEgc3RhY2sgb2YgY2xhc3Nlcy4KICAgVGhlIHRvcG1vc3QgZW50cnkgaXMgdGhlIGlubmVybW9zdCBjbGFzcywgYW5kIGlzIHRoZSBlbnRyeSBhdCBpbmRleAogICBDVVJSRU5UX0NMQVNTX0RFUFRIICAqLwoKdHlwZWRlZiBzdHJ1Y3QgY2xhc3Nfc3RhY2tfbm9kZSB7CiAgLyogVGhlIG5hbWUgb2YgdGhlIGNsYXNzLiAgKi8KICB0cmVlIG5hbWU7CgogIC8qIFRoZSBfVFlQRSBub2RlIGZvciB0aGUgY2xhc3MuICAqLwogIHRyZWUgdHlwZTsKCiAgLyogVGhlIGFjY2VzcyBzcGVjaWZpZXIgcGVuZGluZyBmb3IgbmV3IGRlY2xhcmF0aW9ucyBpbiB0aGUgc2NvcGUgb2YKICAgICB0aGlzIGNsYXNzLiAgKi8KICB0cmVlIGFjY2VzczsKCiAgLyogSWYgd2VyZSBkZWZpbmluZyBUWVBFLCB0aGUgbmFtZXMgdXNlZCBpbiB0aGlzIGNsYXNzLiAgKi8KICBzcGxheV90cmVlIG5hbWVzX3VzZWQ7Cn0qIGNsYXNzX3N0YWNrX25vZGVfdDsKCnR5cGVkZWYgc3RydWN0IHZ0YmxfaW5pdF9kYXRhX3MKewogIC8qIFRoZSBiYXNlIGZvciB3aGljaCB3ZSdyZSBidWlsZGluZyBpbml0aWFsaXplcnMuICAqLwogIHRyZWUgYmluZm87CiAgLyogVGhlIHR5cGUgb2YgdGhlIG1vc3QtZGVyaXZlZCB0eXBlLiAgKi8KICB0cmVlIGRlcml2ZWQ7CiAgLyogVGhlIGJpbmZvIGZvciB0aGUgZHluYW1pYyB0eXBlLiBUaGlzIHdpbGwgYmUgVFlQRV9CSU5GTyAoZGVyaXZlZCksCiAgICAgdW5sZXNzIGN0b3JfdnRibF9wIGlzIHRydWUuICAqLwogIHRyZWUgcnR0aV9iaW5mbzsKICAvKiBUaGUgbmVnYXRpdmUtaW5kZXggdnRhYmxlIGluaXRpYWxpemVycyBidWlsdCB1cCBzbyBmYXIuICBUaGVzZQogICAgIGFyZSBpbiBvcmRlciBmcm9tIGxlYXN0IG5lZ2F0aXZlIGluZGV4IHRvIG1vc3QgbmVnYXRpdmUgaW5kZXguICAqLwogIHRyZWUgaW5pdHM7CiAgLyogVGhlIGxhc3QgKGkuZS4sIG1vc3QgbmVnYXRpdmUpIGVudHJ5IGluIElOSVRTLiAgKi8KICB0cmVlKiBsYXN0X2luaXQ7CiAgLyogVGhlIGJpbmZvIGZvciB0aGUgdmlydHVhbCBiYXNlIGZvciB3aGljaCB3ZSdyZSBidWlsZGluZwogICAgIHZjYWxsIG9mZnNldCBpbml0aWFsaXplcnMuICAqLwogIHRyZWUgdmJhc2U7CiAgLyogVGhlIGZ1bmN0aW9ucyBpbiB2YmFzZSBmb3Igd2hpY2ggd2UgaGF2ZSBhbHJlYWR5IHByb3ZpZGVkIHZjYWxsCiAgICAgb2Zmc2V0cy4gICovCiAgdmFycmF5X3R5cGUgZm5zOwogIC8qIFRoZSB2dGFibGUgaW5kZXggb2YgdGhlIG5leHQgdmNhbGwgb3IgdmJhc2Ugb2Zmc2V0LiAgKi8KICB0cmVlIGluZGV4OwogIC8qIE5vbnplcm8gaWYgd2UgYXJlIGJ1aWxkaW5nIHRoZSBpbml0aWFsaXplciBmb3IgdGhlIHByaW1hcnkKICAgICB2dGFibGUuICAqLwogIGludCBwcmltYXJ5X3Z0YmxfcDsKICAvKiBOb256ZXJvIGlmIHdlIGFyZSBidWlsZGluZyB0aGUgaW5pdGlhbGl6ZXIgZm9yIGEgY29uc3RydWN0aW9uCiAgICAgdnRhYmxlLiAgKi8KICBpbnQgY3Rvcl92dGJsX3A7CiAgLyogVHJ1ZSB3aGVuIGFkZGluZyB2Y2FsbCBvZmZzZXQgZW50cmllcyB0byB0aGUgdnRhYmxlLiAgRmFsc2Ugd2hlbgogICAgIG1lcmVseSBjb21wdXRpbmcgdGhlIGluZGljZXMuICAqLwogIGJvb2wgZ2VuZXJhdGVfdmNhbGxfZW50cmllczsKfSB2dGJsX2luaXRfZGF0YTsKCi8qIFRoZSB0eXBlIG9mIGEgZnVuY3Rpb24gcGFzc2VkIHRvIHdhbGtfc3Vib2JqZWN0X29mZnNldHMuICAqLwp0eXBlZGVmIGludCAoKnN1Ym9iamVjdF9vZmZzZXRfZm4pICh0cmVlLCB0cmVlLCBzcGxheV90cmVlKTsKCi8qIFRoZSBzdGFjayBpdHNlbGYuICBUaGlzIGlzIGEgZHluYW1pY2FsbHkgcmVzaXplZCBhcnJheS4gIFRoZQogICBudW1iZXIgb2YgZWxlbWVudHMgYWxsb2NhdGVkIGlzIENVUlJFTlRfQ0xBU1NfU1RBQ0tfU0laRS4gICovCnN0YXRpYyBpbnQgY3VycmVudF9jbGFzc19zdGFja19zaXplOwpzdGF0aWMgY2xhc3Nfc3RhY2tfbm9kZV90IGN1cnJlbnRfY2xhc3Nfc3RhY2s7CgovKiBBbiBhcnJheSBvZiBhbGwgbG9jYWwgY2xhc3NlcyBwcmVzZW50IGluIHRoaXMgdHJhbnNsYXRpb24gdW5pdCwgaW4KICAgZGVjbGFyYXRpb24gb3JkZXIuICAqLwp2YXJyYXlfdHlwZSBsb2NhbF9jbGFzc2VzOwoKc3RhdGljIHRyZWUgZ2V0X3ZmaWVsZF9uYW1lICh0cmVlKTsKc3RhdGljIHZvaWQgZmluaXNoX3N0cnVjdF9hbm9uICh0cmVlKTsKc3RhdGljIHRyZWUgZ2V0X3Z0YWJsZV9uYW1lICh0cmVlKTsKc3RhdGljIHRyZWUgZ2V0X2Jhc2VmbmRlY2xzICh0cmVlLCB0cmVlKTsKc3RhdGljIGludCBidWlsZF9wcmltYXJ5X3Z0YWJsZSAodHJlZSwgdHJlZSk7CnN0YXRpYyBpbnQgYnVpbGRfc2Vjb25kYXJ5X3Z0YWJsZSAodHJlZSk7CnN0YXRpYyB2b2lkIGZpbmlzaF92dGJscyAodHJlZSk7CnN0YXRpYyB2b2lkIG1vZGlmeV92dGFibGVfZW50cnkgKHRyZWUsIHRyZWUsIHRyZWUsIHRyZWUsIHRyZWUgKik7CnN0YXRpYyB2b2lkIGZpbmlzaF9zdHJ1Y3RfYml0cyAodHJlZSk7CnN0YXRpYyBpbnQgYWx0ZXJfYWNjZXNzICh0cmVlLCB0cmVlLCB0cmVlKTsKc3RhdGljIHZvaWQgaGFuZGxlX3VzaW5nX2RlY2wgKHRyZWUsIHRyZWUpOwpzdGF0aWMgdHJlZSBkZnNfbW9kaWZ5X3Z0YWJsZXMgKHRyZWUsIHZvaWQgKik7CnN0YXRpYyB0cmVlIG1vZGlmeV9hbGxfdnRhYmxlcyAodHJlZSwgdHJlZSk7CnN0YXRpYyB2b2lkIGRldGVybWluZV9wcmltYXJ5X2Jhc2VzICh0cmVlKTsKc3RhdGljIHZvaWQgZmluaXNoX3N0cnVjdF9tZXRob2RzICh0cmVlKTsKc3RhdGljIHZvaWQgbWF5YmVfd2Fybl9hYm91dF9vdmVybHlfcHJpdmF0ZV9jbGFzcyAodHJlZSk7CnN0YXRpYyBpbnQgbWV0aG9kX25hbWVfY21wIChjb25zdCB2b2lkICosIGNvbnN0IHZvaWQgKik7CnN0YXRpYyBpbnQgcmVzb3J0X21ldGhvZF9uYW1lX2NtcCAoY29uc3Qgdm9pZCAqLCBjb25zdCB2b2lkICopOwpzdGF0aWMgdm9pZCBhZGRfaW1wbGljaXRseV9kZWNsYXJlZF9tZW1iZXJzICh0cmVlLCBpbnQsIGludCk7CnN0YXRpYyB0cmVlIGZpeGVkX3R5cGVfb3JfbnVsbCAodHJlZSwgaW50ICosIGludCAqKTsKc3RhdGljIHRyZWUgcmVzb2x2ZV9hZGRyZXNzX29mX292ZXJsb2FkZWRfZnVuY3Rpb24gKHRyZWUsIHRyZWUsIHRzdWJzdF9mbGFnc190LAoJCQkJCQkgICAgYm9vbCwgdHJlZSk7CnN0YXRpYyB0cmVlIGJ1aWxkX3NpbXBsZV9iYXNlX3BhdGggKHRyZWUgZXhwciwgdHJlZSBiaW5mbyk7CnN0YXRpYyB0cmVlIGJ1aWxkX3Z0YmxfcmVmXzEgKHRyZWUsIHRyZWUpOwpzdGF0aWMgdHJlZSBidWlsZF92dGJsX2luaXRpYWxpemVyICh0cmVlLCB0cmVlLCB0cmVlLCB0cmVlLCBpbnQgKik7CnN0YXRpYyBpbnQgY291bnRfZmllbGRzICh0cmVlKTsKc3RhdGljIGludCBhZGRfZmllbGRzX3RvX3JlY29yZF90eXBlICh0cmVlLCBzdHJ1Y3Qgc29ydGVkX2ZpZWxkc190eXBlKiwgaW50KTsKc3RhdGljIHZvaWQgY2hlY2tfYml0ZmllbGRfZGVjbCAodHJlZSk7CnN0YXRpYyB2b2lkIGNoZWNrX2ZpZWxkX2RlY2wgKHRyZWUsIHRyZWUsIGludCAqLCBpbnQgKiwgaW50ICopOwpzdGF0aWMgdm9pZCBjaGVja19maWVsZF9kZWNscyAodHJlZSwgdHJlZSAqLCBpbnQgKiwgaW50ICopOwpzdGF0aWMgdHJlZSAqYnVpbGRfYmFzZV9maWVsZCAocmVjb3JkX2xheW91dF9pbmZvLCB0cmVlLCBzcGxheV90cmVlLCB0cmVlICopOwpzdGF0aWMgdm9pZCBidWlsZF9iYXNlX2ZpZWxkcyAocmVjb3JkX2xheW91dF9pbmZvLCBzcGxheV90cmVlLCB0cmVlICopOwpzdGF0aWMgdm9pZCBjaGVja19tZXRob2RzICh0cmVlKTsKc3RhdGljIHZvaWQgcmVtb3ZlX3plcm9fd2lkdGhfYml0X2ZpZWxkcyAodHJlZSk7CnN0YXRpYyB2b2lkIGNoZWNrX2Jhc2VzICh0cmVlLCBpbnQgKiwgaW50ICopOwpzdGF0aWMgdm9pZCBjaGVja19iYXNlc19hbmRfbWVtYmVycyAodHJlZSk7CnN0YXRpYyB0cmVlIGNyZWF0ZV92dGFibGVfcHRyICh0cmVlLCB0cmVlICopOwpzdGF0aWMgdm9pZCBpbmNsdWRlX2VtcHR5X2NsYXNzZXMgKHJlY29yZF9sYXlvdXRfaW5mbyk7CnN0YXRpYyB2b2lkIGxheW91dF9jbGFzc190eXBlICh0cmVlLCB0cmVlICopOwpzdGF0aWMgdm9pZCBmaXh1cF9wZW5kaW5nX2lubGluZSAodHJlZSk7CnN0YXRpYyB2b2lkIGZpeHVwX2lubGluZV9tZXRob2RzICh0cmVlKTsKc3RhdGljIHZvaWQgcHJvcGFnYXRlX2JpbmZvX29mZnNldHMgKHRyZWUsIHRyZWUpOwpzdGF0aWMgdm9pZCBsYXlvdXRfdmlydHVhbF9iYXNlcyAocmVjb3JkX2xheW91dF9pbmZvLCBzcGxheV90cmVlKTsKc3RhdGljIHZvaWQgYnVpbGRfdmJhc2Vfb2Zmc2V0X3Z0YmxfZW50cmllcyAodHJlZSwgdnRibF9pbml0X2RhdGEgKik7CnN0YXRpYyB2b2lkIGFkZF92Y2FsbF9vZmZzZXRfdnRibF9lbnRyaWVzX3IgKHRyZWUsIHZ0YmxfaW5pdF9kYXRhICopOwpzdGF0aWMgdm9pZCBhZGRfdmNhbGxfb2Zmc2V0X3Z0YmxfZW50cmllc18xICh0cmVlLCB2dGJsX2luaXRfZGF0YSAqKTsKc3RhdGljIHZvaWQgYnVpbGRfdmNhbGxfb2Zmc2V0X3Z0YmxfZW50cmllcyAodHJlZSwgdnRibF9pbml0X2RhdGEgKik7CnN0YXRpYyB2b2lkIGFkZF92Y2FsbF9vZmZzZXQgKHRyZWUsIHRyZWUsIHZ0YmxfaW5pdF9kYXRhICopOwpzdGF0aWMgdm9pZCBsYXlvdXRfdnRhYmxlX2RlY2wgKHRyZWUsIGludCk7CnN0YXRpYyB0cmVlIGRmc19maW5kX2ZpbmFsX292ZXJyaWRlcl9wcmUgKHRyZWUsIHZvaWQgKik7CnN0YXRpYyB0cmVlIGRmc19maW5kX2ZpbmFsX292ZXJyaWRlcl9wb3N0ICh0cmVlLCB2b2lkICopOwpzdGF0aWMgdHJlZSBmaW5kX2ZpbmFsX292ZXJyaWRlciAodHJlZSwgdHJlZSwgdHJlZSk7CnN0YXRpYyBpbnQgbWFrZV9uZXdfdnRhYmxlICh0cmVlLCB0cmVlKTsKc3RhdGljIGludCBtYXliZV9pbmRlbnRfaGllcmFyY2h5IChGSUxFICosIGludCwgaW50KTsKc3RhdGljIHRyZWUgZHVtcF9jbGFzc19oaWVyYXJjaHlfciAoRklMRSAqLCBpbnQsIHRyZWUsIHRyZWUsIGludCk7CnN0YXRpYyB2b2lkIGR1bXBfY2xhc3NfaGllcmFyY2h5ICh0cmVlKTsKc3RhdGljIHZvaWQgZHVtcF9jbGFzc19oaWVyYXJjaHlfMSAoRklMRSAqLCBpbnQsIHRyZWUpOwpzdGF0aWMgdm9pZCBkdW1wX2FycmF5IChGSUxFICosIHRyZWUpOwpzdGF0aWMgdm9pZCBkdW1wX3Z0YWJsZSAodHJlZSwgdHJlZSwgdHJlZSk7CnN0YXRpYyB2b2lkIGR1bXBfdnR0ICh0cmVlLCB0cmVlKTsKc3RhdGljIHZvaWQgZHVtcF90aHVuayAoRklMRSAqLCBpbnQsIHRyZWUpOwpzdGF0aWMgdHJlZSBidWlsZF92dGFibGUgKHRyZWUsIHRyZWUsIHRyZWUpOwpzdGF0aWMgdm9pZCBpbml0aWFsaXplX3Z0YWJsZSAodHJlZSwgdHJlZSk7CnN0YXRpYyB2b2lkIGxheW91dF9ub25lbXB0eV9iYXNlX29yX2ZpZWxkIChyZWNvcmRfbGF5b3V0X2luZm8sCgkJCQkJICAgdHJlZSwgdHJlZSwgc3BsYXlfdHJlZSk7CnN0YXRpYyB0cmVlIGVuZF9vZl9jbGFzcyAodHJlZSwgaW50KTsKc3RhdGljIGJvb2wgbGF5b3V0X2VtcHR5X2Jhc2UgKHRyZWUsIHRyZWUsIHNwbGF5X3RyZWUpOwpzdGF0aWMgdm9pZCBhY2N1bXVsYXRlX3Z0YmxfaW5pdHMgKHRyZWUsIHRyZWUsIHRyZWUsIHRyZWUsIHRyZWUpOwpzdGF0aWMgdHJlZSBkZnNfYWNjdW11bGF0ZV92dGJsX2luaXRzICh0cmVlLCB0cmVlLCB0cmVlLCB0cmVlLAoJCQkJCSAgICAgICB0cmVlKTsKc3RhdGljIHZvaWQgYnVpbGRfcnR0aV92dGJsX2VudHJpZXMgKHRyZWUsIHZ0YmxfaW5pdF9kYXRhICopOwpzdGF0aWMgdm9pZCBidWlsZF92Y2FsbF9hbmRfdmJhc2VfdnRibF9lbnRyaWVzICh0cmVlLCB2dGJsX2luaXRfZGF0YSAqKTsKc3RhdGljIHZvaWQgY2xvbmVfY29uc3RydWN0b3JzX2FuZF9kZXN0cnVjdG9ycyAodHJlZSk7CnN0YXRpYyB0cmVlIGJ1aWxkX2Nsb25lICh0cmVlLCB0cmVlKTsKc3RhdGljIHZvaWQgdXBkYXRlX3Z0YWJsZV9lbnRyeV9mb3JfZm4gKHRyZWUsIHRyZWUsIHRyZWUsIHRyZWUgKiwgdW5zaWduZWQpOwpzdGF0aWMgdm9pZCBidWlsZF9jdG9yX3Z0YmxfZ3JvdXAgKHRyZWUsIHRyZWUpOwpzdGF0aWMgdm9pZCBidWlsZF92dHQgKHRyZWUpOwpzdGF0aWMgdHJlZSBiaW5mb19jdG9yX3Z0YWJsZSAodHJlZSk7CnN0YXRpYyB0cmVlICpidWlsZF92dHRfaW5pdHMgKHRyZWUsIHRyZWUsIHRyZWUgKiwgdHJlZSAqKTsKc3RhdGljIHRyZWUgZGZzX2J1aWxkX3NlY29uZGFyeV92cHRyX3Z0dF9pbml0cyAodHJlZSwgdm9pZCAqKTsKc3RhdGljIHRyZWUgZGZzX2ZpeHVwX2JpbmZvX3Z0YmxzICh0cmVlLCB2b2lkICopOwpzdGF0aWMgaW50IHJlY29yZF9zdWJvYmplY3Rfb2Zmc2V0ICh0cmVlLCB0cmVlLCBzcGxheV90cmVlKTsKc3RhdGljIGludCBjaGVja19zdWJvYmplY3Rfb2Zmc2V0ICh0cmVlLCB0cmVlLCBzcGxheV90cmVlKTsKc3RhdGljIGludCB3YWxrX3N1Ym9iamVjdF9vZmZzZXRzICh0cmVlLCBzdWJvYmplY3Rfb2Zmc2V0X2ZuLAoJCQkJICAgdHJlZSwgc3BsYXlfdHJlZSwgdHJlZSwgaW50KTsKc3RhdGljIHZvaWQgcmVjb3JkX3N1Ym9iamVjdF9vZmZzZXRzICh0cmVlLCB0cmVlLCBzcGxheV90cmVlLCBpbnQpOwpzdGF0aWMgaW50IGxheW91dF9jb25mbGljdF9wICh0cmVlLCB0cmVlLCBzcGxheV90cmVlLCBpbnQpOwpzdGF0aWMgaW50IHNwbGF5X3RyZWVfY29tcGFyZV9pbnRlZ2VyX2NzdHMgKHNwbGF5X3RyZWVfa2V5IGsxLAoJCQkJCSAgICBzcGxheV90cmVlX2tleSBrMik7CnN0YXRpYyB2b2lkIHdhcm5fYWJvdXRfYW1iaWd1b3VzX2Jhc2VzICh0cmVlKTsKc3RhdGljIGJvb2wgdHlwZV9yZXF1aXJlc19hcnJheV9jb29raWUgKHRyZWUpOwpzdGF0aWMgYm9vbCBjb250YWluc19lbXB0eV9jbGFzc19wICh0cmVlKTsKc3RhdGljIGJvb2wgYmFzZV9kZXJpdmVkX2Zyb20gKHRyZWUsIHRyZWUpOwpzdGF0aWMgaW50IGVtcHR5X2Jhc2VfYXRfbm9uemVyb19vZmZzZXRfcCAodHJlZSwgdHJlZSwgc3BsYXlfdHJlZSk7CnN0YXRpYyB0cmVlIGVuZF9vZl9iYXNlICh0cmVlKTsKc3RhdGljIHRyZWUgZ2V0X3ZjYWxsX2luZGV4ICh0cmVlLCB0cmVlKTsKCi8qIFZhcmlhYmxlcyBzaGFyZWQgYmV0d2VlbiBjbGFzcy5jIGFuZCBjYWxsLmMuICAqLwoKI2lmZGVmIEdBVEhFUl9TVEFUSVNUSUNTCmludCBuX3Z0YWJsZXMgPSAwOwppbnQgbl92dGFibGVfZW50cmllcyA9IDA7CmludCBuX3Z0YWJsZV9zZWFyY2hlcyA9IDA7CmludCBuX3Z0YWJsZV9lbGVtcyA9IDA7CmludCBuX2NvbnZlcnRfaGFyc2huZXNzID0gMDsKaW50IG5fY29tcHV0ZV9jb252ZXJzaW9uX2Nvc3RzID0gMDsKaW50IG5faW5uZXJfZmllbGRzX3NlYXJjaGVkID0gMDsKI2VuZGlmCgovKiBBUFBMRSBMT0NBTCBiZWdpbiBNYWNpbnRvc2ggYWxpZ25tZW50IDIwMDItNS0yNCAtLWZmICAqLwpleHRlcm4gaW50IGRhcndpbl9hbGlnbl9pc19maXJzdF9tZW1iZXJfb2ZfY2xhc3M7Ci8qIEFQUExFIExPQ0FMIGVuZCBNYWNpbnRvc2ggYWxpZ25tZW50IDIwMDItNS0yNCAtLWZmICAqLwoKLyogQ29udmVydCB0byBvciBmcm9tIGEgYmFzZSBzdWJvYmplY3QuICBFWFBSIGlzIGFuIGV4cHJlc3Npb24gb2YgdHlwZQogICBgQScgb3IgYEEqJywgYW4gZXhwcmVzc2lvbiBvZiB0eXBlIGBCJyBvciBgQionIGlzIHJldHVybmVkLiAgVG8KICAgY29udmVydCBBIHRvIGEgYmFzZSBCLCBDT0RFIGlzIFBMVVNfRVhQUiBhbmQgQklORk8gaXMgdGhlIGJpbmZvIGZvcgogICB0aGUgQiBiYXNlIGluc3RhbmNlIHdpdGhpbiBBLiAgVG8gY29udmVydCBiYXNlIEEgdG8gZGVyaXZlZCBCLCBDT0RFCiAgIGlzIE1JTlVTX0VYUFIgYW5kIEJJTkZPIGlzIHRoZSBiaW5mbyBmb3IgdGhlIEEgaW5zdGFuY2Ugd2l0aGluIEIuCiAgIEluIHRoaXMgbGF0dGVyIGNhc2UsIEEgbXVzdCBub3QgYmUgYSBtb3JhbGx5IHZpcnR1YWwgYmFzZSBvZiBCLgogICBOT05OVUxMIGlzIHRydWUgaWYgRVhQUiBpcyBrbm93biB0byBiZSBub24tTlVMTCAodGhpcyBpcyBvbmx5CiAgIG5lZWRlZCB3aGVuIEVYUFIgaXMgb2YgcG9pbnRlciB0eXBlKS4gIENWIHF1YWxpZmllcnMgYXJlIHByZXNlcnZlZAogICBmcm9tIEVYUFIuICAqLwoKdHJlZQpidWlsZF9iYXNlX3BhdGggKGVudW0gdHJlZV9jb2RlIGNvZGUsCiAgICAgICAgICAgICAgICAgdHJlZSBleHByLAogICAgICAgICAgICAgICAgIHRyZWUgYmluZm8sCiAgICAgICAgICAgICAgICAgaW50IG5vbm51bGwpCnsKICB0cmVlIHZfYmluZm8gPSBOVUxMX1RSRUU7CiAgdHJlZSBkX2JpbmZvID0gTlVMTF9UUkVFOwogIHRyZWUgcHJvYmU7CiAgdHJlZSBvZmZzZXQ7CiAgdHJlZSB0YXJnZXRfdHlwZTsKICB0cmVlIG51bGxfdGVzdCA9IE5VTEw7CiAgdHJlZSBwdHJfdGFyZ2V0X3R5cGU7CiAgaW50IGZpeGVkX3R5cGVfcDsKICBpbnQgd2FudF9wb2ludGVyID0gVFJFRV9DT0RFIChUUkVFX1RZUEUgKGV4cHIpKSA9PSBQT0lOVEVSX1RZUEU7CiAgYm9vbCBoYXNfZW1wdHkgPSBmYWxzZTsKICBib29sIHZpcnR1YWxfYWNjZXNzOwoKICBpZiAoZXhwciA9PSBlcnJvcl9tYXJrX25vZGUgfHwgYmluZm8gPT0gZXJyb3JfbWFya19ub2RlIHx8ICFiaW5mbykKICAgIHJldHVybiBlcnJvcl9tYXJrX25vZGU7CgogIGZvciAocHJvYmUgPSBiaW5mbzsgcHJvYmU7IHByb2JlID0gQklORk9fSU5IRVJJVEFOQ0VfQ0hBSU4gKHByb2JlKSkKICAgIHsKICAgICAgZF9iaW5mbyA9IHByb2JlOwogICAgICBpZiAoaXNfZW1wdHlfY2xhc3MgKEJJTkZPX1RZUEUgKHByb2JlKSkpCgloYXNfZW1wdHkgPSB0cnVlOwogICAgICBpZiAoIXZfYmluZm8gJiYgQklORk9fVklSVFVBTF9QIChwcm9iZSkpCgl2X2JpbmZvID0gcHJvYmU7CiAgICB9CgogIHByb2JlID0gVFlQRV9NQUlOX1ZBUklBTlQgKFRSRUVfVFlQRSAoZXhwcikpOwogIGlmICh3YW50X3BvaW50ZXIpCiAgICBwcm9iZSA9IFRZUEVfTUFJTl9WQVJJQU5UIChUUkVFX1RZUEUgKHByb2JlKSk7CgogIGdjY19hc3NlcnQgKChjb2RlID09IE1JTlVTX0VYUFIKCSAgICAgICAmJiBTQU1FX0JJTkZPX1RZUEVfUCAoQklORk9fVFlQRSAoYmluZm8pLCBwcm9iZSkpCgkgICAgICB8fCAoY29kZSA9PSBQTFVTX0VYUFIKCQkgICYmIFNBTUVfQklORk9fVFlQRV9QIChCSU5GT19UWVBFIChkX2JpbmZvKSwgcHJvYmUpKSk7CiAgCiAgaWYgKGJpbmZvID09IGRfYmluZm8pCiAgICAvKiBOb3RoaW5nIHRvIGRvLiAgKi8KICAgIHJldHVybiBleHByOwoKICBpZiAoY29kZSA9PSBNSU5VU19FWFBSICYmIHZfYmluZm8pCiAgICB7CiAgICAgIGVycm9yICgiY2Fubm90IGNvbnZlcnQgZnJvbSBiYXNlICVxVCB0byBkZXJpdmVkIHR5cGUgJXFUIHZpYSB2aXJ0dWFsIGJhc2UgJXFUIiwKCSAgICAgQklORk9fVFlQRSAoYmluZm8pLCBCSU5GT19UWVBFIChkX2JpbmZvKSwgQklORk9fVFlQRSAodl9iaW5mbykpOwogICAgICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwogICAgfQoKICBpZiAoIXdhbnRfcG9pbnRlcikKICAgIC8qIFRoaXMgbXVzdCBoYXBwZW4gYmVmb3JlIHRoZSBjYWxsIHRvIHNhdmVfZXhwci4gICovCiAgICBleHByID0gYnVpbGRfdW5hcnlfb3AgKEFERFJfRVhQUiwgZXhwciwgMCk7CgogIG9mZnNldCA9IEJJTkZPX09GRlNFVCAoYmluZm8pOwogIGZpeGVkX3R5cGVfcCA9IHJlc29sdmVzX3RvX2ZpeGVkX3R5cGVfcCAoZXhwciwgJm5vbm51bGwpOwogIC8qIEFQUExFIExPQ0FMIGJlZ2luIG1haW5saW5lIDIwMDYtMDEtMjIgNDQxNjQ1MiAqLwogIC8qIEdlbmVyYXRlIGEgTk9QX0VYUFIgaW5zdGVhZCBvZiBhIENPTVBPTkVOVF9SRUYgaWYgdGhlIGJhc2UgYW5kIGRlcml2ZWQgY2xhc3NlcyBhcmUgYXQgdGhlIHNhbWUgYWRkcmVzcyAqLwogIHRhcmdldF90eXBlID0gY29kZSA9PSBQTFVTX0VYUFIgPyBCSU5GT19UWVBFIChiaW5mbykgOiBCSU5GT19UWVBFIChkX2JpbmZvKTsKCiAgLyogRG8gd2UgbmVlZCB0byBsb29rIGluIHRoZSB2dGFibGUgZm9yIHRoZSByZWFsIG9mZnNldD8gICovCiAgdmlydHVhbF9hY2Nlc3MgPSAodl9iaW5mbyAmJiBmaXhlZF90eXBlX3AgPD0gMCk7CgogIC8qIERvIHdlIG5lZWQgdG8gY2hlY2sgZm9yIGEgbnVsbCBwb2ludGVyPyAgKi8KICBpZiAod2FudF9wb2ludGVyICYmICFub25udWxsKQogICAgewogICAgICAvKiBJZiB3ZSBrbm93IHRoZSBjb252ZXJzaW9uIHdpbGwgbm90IGFjdHVhbGx5IGNoYW5nZSB0aGUgdmFsdWUKICAgICAgICAgb2YgRVhQUiwgdGhlbiB3ZSBjYW4gYXZvaWQgdGVzdGluZyB0aGUgZXhwcmVzc2lvbiBmb3IgTlVMTC4KICAgICAgICAgV2UgaGF2ZSB0byBhdm9pZCBnZW5lcmF0aW5nIGEgQ09NUE9ORU5UX1JFRiBmb3IgYSBiYXNlIGNsYXNzCiAgICAgICAgIGZpZWxkLCBiZWNhdXNlIG90aGVyIHBhcnRzIG9mIHRoZSBjb21waWxlciBrbm93IHRoYXQgc3VjaAogICAgICAgICBleHByZXNzaW9ucyBhcmUgYWx3YXlzIG5vbi1OVUxMLiDKKi8KICAgICAgaWYgKCF2aXJ0dWFsX2FjY2VzcyAmJiBpbnRlZ2VyX3plcm9wIChvZmZzZXQpKQogICAgICAgIHJldHVybiBidWlsZF9ub3AgKGJ1aWxkX3BvaW50ZXJfdHlwZSAodGFyZ2V0X3R5cGUpLCBleHByKTsKICAgIG51bGxfdGVzdCA9IGVycm9yX21hcmtfbm9kZTsKICAgIH0KICAvKiBBUFBMRSBMT0NBTCBlbmQgbWFpbmxpbmUgMjAwNi0wMS0yMiA0NDE2NDUyICovCgogIC8qIFByb3RlY3QgYWdhaW5zdCBtdWx0aXBsZSBldmFsdWF0aW9uIGlmIG5lY2Vzc2FyeS4gICovCiAgaWYgKFRSRUVfU0lERV9FRkZFQ1RTIChleHByKSAmJiAobnVsbF90ZXN0IHx8IHZpcnR1YWxfYWNjZXNzKSkKICAgIGV4cHIgPSBzYXZlX2V4cHIgKGV4cHIpOwoKICAvKiBOb3cgdGhhdCB3ZSd2ZSBzYXZlZCBleHByLCBidWlsZCB0aGUgcmVhbCBudWxsIHRlc3QuICAqLwogIGlmIChudWxsX3Rlc3QpCiAgICB7CiAgICAgIHRyZWUgemVybyA9IGNwX2NvbnZlcnQgKFRSRUVfVFlQRSAoZXhwciksIGludGVnZXJfemVyb19ub2RlKTsKICAgICAgbnVsbF90ZXN0ID0gZm9sZCAoYnVpbGQyIChORV9FWFBSLCBib29sZWFuX3R5cGVfbm9kZSwKCQkJCWV4cHIsIHplcm8pKTsKICAgIH0KCiAgLyogSWYgdGhpcyBpcyBhIHNpbXBsZSBiYXNlIHJlZmVyZW5jZSwgZXhwcmVzcyBpdCBhcyBhIENPTVBPTkVOVF9SRUYuICAqLwogIGlmIChjb2RlID09IFBMVVNfRVhQUiAmJiAhdmlydHVhbF9hY2Nlc3MKICAgICAgLyogV2UgZG9uJ3QgYnVpbGQgYmFzZSBmaWVsZHMgZm9yIGVtcHR5IGJhc2VzLCBhbmQgdGhleSBhcmVuJ3QgdmVyeQoJIGludGVyZXN0aW5nIHRvIHRoZSBvcHRpbWl6ZXJzIGFueXdheS4gICovCiAgICAgICYmICFoYXNfZW1wdHkpCiAgICB7CiAgICAgIGV4cHIgPSBidWlsZF9pbmRpcmVjdF9yZWYgKGV4cHIsIE5VTEwpOwogICAgICBleHByID0gYnVpbGRfc2ltcGxlX2Jhc2VfcGF0aCAoZXhwciwgYmluZm8pOwogICAgICBpZiAod2FudF9wb2ludGVyKQoJZXhwciA9IGJ1aWxkX2FkZHJlc3MgKGV4cHIpOwogICAgICB0YXJnZXRfdHlwZSA9IFRSRUVfVFlQRSAoZXhwcik7CiAgICAgIGdvdG8gb3V0OwogICAgfQoKICBpZiAodmlydHVhbF9hY2Nlc3MpCiAgICB7CiAgICAgIC8qIEdvaW5nIHZpYSB2aXJ0dWFsIGJhc2UgVl9CSU5GTy4gIFdlIG5lZWQgdGhlIHN0YXRpYyBvZmZzZXQKICAgICAgICAgZnJvbSBWX0JJTkZPIHRvIEJJTkZPLCBhbmQgdGhlIGR5bmFtaWMgb2Zmc2V0IGZyb20gRF9CSU5GTyB0bwogICAgICAgICBWX0JJTkZPLiAgVGhhdCBvZmZzZXQgaXMgYW4gZW50cnkgaW4gRF9CSU5GTydzIHZ0YWJsZS4gICovCiAgICAgIHRyZWUgdl9vZmZzZXQ7CgogICAgICBpZiAoZml4ZWRfdHlwZV9wIDwgMCAmJiBpbl9iYXNlX2luaXRpYWxpemVyKQoJewoJICAvKiBJbiBhIGJhc2UgbWVtYmVyIGluaXRpYWxpemVyLCB3ZSBjYW5ub3QgcmVseSBvbgoJICAgICB0aGUgdnRhYmxlIGJlaW5nIHNldCB1cC4gV2UgaGF2ZSB0byB1c2UgdGhlIHZ0dF9wYXJtLiAgKi8KCSAgdHJlZSBkZXJpdmVkID0gQklORk9fSU5IRVJJVEFOQ0VfQ0hBSU4gKHZfYmluZm8pOwoJICB0cmVlIHQ7CgoJICB0ID0gVFJFRV9UWVBFIChUWVBFX1ZGSUVMRCAoQklORk9fVFlQRSAoZGVyaXZlZCkpKTsKCSAgdCA9IGJ1aWxkX3BvaW50ZXJfdHlwZSAodCk7CgkgIHZfb2Zmc2V0ID0gY29udmVydCAodCwgY3VycmVudF92dHRfcGFybSk7CgkgIHZfb2Zmc2V0ID0gYnVpbGQyIChQTFVTX0VYUFIsIHQsIHZfb2Zmc2V0LAoJCQkgICAgIEJJTkZPX1ZQVFJfSU5ERVggKGRlcml2ZWQpKTsKCSAgdl9vZmZzZXQgPSBidWlsZF9pbmRpcmVjdF9yZWYgKHZfb2Zmc2V0LCBOVUxMKTsKCX0KICAgICAgZWxzZQoJdl9vZmZzZXQgPSBidWlsZF92ZmllbGRfcmVmIChidWlsZF9pbmRpcmVjdF9yZWYgKGV4cHIsIE5VTEwpLAoJCQkJICAgICBUUkVFX1RZUEUgKFRSRUVfVFlQRSAoZXhwcikpKTsKICAgICAgCiAgICAgIHZfb2Zmc2V0ID0gYnVpbGQyIChQTFVTX0VYUFIsIFRSRUVfVFlQRSAodl9vZmZzZXQpLAoJCQkgdl9vZmZzZXQsICBCSU5GT19WUFRSX0ZJRUxEICh2X2JpbmZvKSk7CiAgICAgIHZfb2Zmc2V0ID0gYnVpbGQxIChOT1BfRVhQUiwgCgkJCSBidWlsZF9wb2ludGVyX3R5cGUgKHB0cmRpZmZfdHlwZV9ub2RlKSwKCQkJIHZfb2Zmc2V0KTsKICAgICAgdl9vZmZzZXQgPSBidWlsZF9pbmRpcmVjdF9yZWYgKHZfb2Zmc2V0LCBOVUxMKTsKICAgICAgVFJFRV9DT05TVEFOVCAodl9vZmZzZXQpID0gMTsKICAgICAgVFJFRV9JTlZBUklBTlQgKHZfb2Zmc2V0KSA9IDE7CgogICAgICBvZmZzZXQgPSBjb252ZXJ0X3RvX2ludGVnZXIgKHB0cmRpZmZfdHlwZV9ub2RlLAoJCQkJICAgc2l6ZV9kaWZmb3AgKG9mZnNldCwgCgkJCQkJCUJJTkZPX09GRlNFVCAodl9iaW5mbykpKTsKCiAgICAgIGlmICghaW50ZWdlcl96ZXJvcCAob2Zmc2V0KSkKCXZfb2Zmc2V0ID0gYnVpbGQyIChjb2RlLCBwdHJkaWZmX3R5cGVfbm9kZSwgdl9vZmZzZXQsIG9mZnNldCk7CgogICAgICBpZiAoZml4ZWRfdHlwZV9wIDwgMCkKCS8qIE5lZ2F0aXZlIGZpeGVkX3R5cGVfcCBtZWFucyB0aGlzIGlzIGEgY29uc3RydWN0b3Igb3IgZGVzdHJ1Y3RvcjsKCSAgIHZpcnR1YWwgYmFzZSBsYXlvdXQgaXMgZml4ZWQgaW4gaW4tY2hhcmdlIFtjZF10b3JzLCBidXQgbm90IGluCgkgICBiYXNlIFtjZF10b3JzLiAgKi8KCW9mZnNldCA9IGJ1aWxkMyAoQ09ORF9FWFBSLCBwdHJkaWZmX3R5cGVfbm9kZSwKCQkJIGJ1aWxkMiAoRVFfRVhQUiwgYm9vbGVhbl90eXBlX25vZGUsCgkJCQkgY3VycmVudF9pbl9jaGFyZ2VfcGFybSwgaW50ZWdlcl96ZXJvX25vZGUpLAoJCQkgdl9vZmZzZXQsCgkJCSBCSU5GT19PRkZTRVQgKGJpbmZvKSk7CiAgICAgIGVsc2UKCW9mZnNldCA9IHZfb2Zmc2V0OwogICAgfQoKICAvKiBBUFBMRSBMT0NBTCBiZWdpbiBtYWlubGluZSAyMDA2LTAxLTIyIDQ0MTY0NTIgKi8KICAvKiBHZW5lcmF0ZSBhIE5PUF9FWFBSIGluc3RlYWQgb2YgYSBDT01QT05FTlRfUkVGIGlmIHRoZSBiYXNlIGFuZCBkZXJpdmVkIGNsYXNzZXMgYXJlIGF0IHRoZSBzYW1lIGFkZHJlc3MgKi8KICAvKiBBUFBMRSBMT0NBTCBlbmQgbWFpbmxpbmUgMjAwNi0wMS0yMiA0NDE2NDUyICovCiAgCiAgdGFyZ2V0X3R5cGUgPSBjcF9idWlsZF9xdWFsaWZpZWRfdHlwZQogICAgKHRhcmdldF90eXBlLCBjcF90eXBlX3F1YWxzIChUUkVFX1RZUEUgKFRSRUVfVFlQRSAoZXhwcikpKSk7CiAgcHRyX3RhcmdldF90eXBlID0gYnVpbGRfcG9pbnRlcl90eXBlICh0YXJnZXRfdHlwZSk7CiAgaWYgKHdhbnRfcG9pbnRlcikKICAgIHRhcmdldF90eXBlID0gcHRyX3RhcmdldF90eXBlOwogIAogIGV4cHIgPSBidWlsZDEgKE5PUF9FWFBSLCBwdHJfdGFyZ2V0X3R5cGUsIGV4cHIpOwoKICBpZiAoIWludGVnZXJfemVyb3AgKG9mZnNldCkpCiAgICBleHByID0gYnVpbGQyIChjb2RlLCBwdHJfdGFyZ2V0X3R5cGUsIGV4cHIsIG9mZnNldCk7CiAgZWxzZQogICAgbnVsbF90ZXN0ID0gTlVMTDsKICAKICBpZiAoIXdhbnRfcG9pbnRlcikKICAgIGV4cHIgPSBidWlsZF9pbmRpcmVjdF9yZWYgKGV4cHIsIE5VTEwpOwoKIG91dDoKICBpZiAobnVsbF90ZXN0KQogICAgZXhwciA9IGZvbGQgKGJ1aWxkMyAoQ09ORF9FWFBSLCB0YXJnZXRfdHlwZSwgbnVsbF90ZXN0LCBleHByLAoJCQkgZm9sZCAoYnVpbGQxIChOT1BfRVhQUiwgdGFyZ2V0X3R5cGUsCgkJCQkgICAgICAgaW50ZWdlcl96ZXJvX25vZGUpKSkpOwoKICByZXR1cm4gZXhwcjsKfQoKLyogU3Vicm91dGluZSBvZiBidWlsZF9iYXNlX3BhdGg7IEVYUFIgYW5kIEJJTkZPIGFyZSBhcyBpbiB0aGF0IGZ1bmN0aW9uLgogICBQZXJmb3JtIGEgZGVyaXZlZC10by1iYXNlIGNvbnZlcnNpb24gYnkgcmVjdXJzaXZlbHkgYnVpbGRpbmcgdXAgYQogICBzZXF1ZW5jZSBvZiBDT01QT05FTlRfUkVGcyB0byB0aGUgYXBwcm9wcmlhdGUgYmFzZSBmaWVsZHMuICAqLwoKc3RhdGljIHRyZWUKYnVpbGRfc2ltcGxlX2Jhc2VfcGF0aCAodHJlZSBleHByLCB0cmVlIGJpbmZvKQp7CiAgdHJlZSB0eXBlID0gQklORk9fVFlQRSAoYmluZm8pOwogIHRyZWUgZF9iaW5mbyA9IEJJTkZPX0lOSEVSSVRBTkNFX0NIQUlOIChiaW5mbyk7CiAgdHJlZSBmaWVsZDsKCiAgaWYgKGRfYmluZm8gPT0gTlVMTF9UUkVFKQogICAgewogICAgICB0cmVlIHRlbXA7CiAgICAgIAogICAgICBnY2NfYXNzZXJ0IChUWVBFX01BSU5fVkFSSUFOVCAoVFJFRV9UWVBFIChleHByKSkgPT0gdHlwZSk7CiAgICAgIAogICAgICAvKiBUcmFuc2Zvcm0gYChhLCBiKS54JyBpbnRvIGAoKihhLCAmYikpLngnLCBgKGEgPyBiIDogYykueCcKICAgICAJIGludG8gYCgqKGEgPyAgJmIgOiAmYykpLngnLCBhbmQgc28gb24uICBBIENPTkRfRVhQUiBpcyBvbmx5CiAgICAgCSBhbiBsdmFsdWUgaW4gdGhlIGZyb250ZW5kOyBvbmx5IF9ERUNMcyBhbmQgX1JFRnMgYXJlIGx2YWx1ZXMKICAgICAJIGluIHRoZSBiYWNrZW5kLiAgKi8KICAgICAgdGVtcCA9IHVuYXJ5X2NvbXBsZXhfbHZhbHVlIChBRERSX0VYUFIsIGV4cHIpOwogICAgICBpZiAodGVtcCkKCWV4cHIgPSBidWlsZF9pbmRpcmVjdF9yZWYgKHRlbXAsIE5VTEwpOwoKICAgICAgcmV0dXJuIGV4cHI7CiAgICB9CgogIC8qIFJlY3Vyc2UuICAqLwogIGV4cHIgPSBidWlsZF9zaW1wbGVfYmFzZV9wYXRoIChleHByLCBkX2JpbmZvKTsKCiAgZm9yIChmaWVsZCA9IFRZUEVfRklFTERTIChCSU5GT19UWVBFIChkX2JpbmZvKSk7CiAgICAgICBmaWVsZDsgZmllbGQgPSBUUkVFX0NIQUlOIChmaWVsZCkpCiAgICAvKiBJcyB0aGlzIHRoZSBiYXNlIGZpZWxkIGNyZWF0ZWQgYnkgYnVpbGRfYmFzZV9maWVsZD8gICovCiAgICBpZiAoVFJFRV9DT0RFIChmaWVsZCkgPT0gRklFTERfREVDTAoJJiYgREVDTF9GSUVMRF9JU19CQVNFIChmaWVsZCkKCSYmIFRSRUVfVFlQRSAoZmllbGQpID09IHR5cGUpCiAgICAgIHsKCS8qIFdlIGRvbid0IHVzZSBidWlsZF9jbGFzc19tZW1iZXJfYWNjZXNzX2V4cHIgaGVyZSwgYXMgdGhhdAoJICAgaGFzIHVubmVjZXNzYXJ5IGNoZWNrcywgYW5kIG1vcmUgaW1wb3J0YW50bHkgcmVzdWx0cyBpbgoJICAgcmVjdXJzaXZlIGNhbGxzIHRvIGRmc193YWxrX29uY2UuICAqLwoJaW50IHR5cGVfcXVhbHMgPSBjcF90eXBlX3F1YWxzIChUUkVFX1RZUEUgKGV4cHIpKTsKCglleHByID0gYnVpbGQzIChDT01QT05FTlRfUkVGLAoJCSAgICAgICBjcF9idWlsZF9xdWFsaWZpZWRfdHlwZSAodHlwZSwgdHlwZV9xdWFscyksCgkJICAgICAgIGV4cHIsIGZpZWxkLCBOVUxMX1RSRUUpOwoJZXhwciA9IGZvbGRfaWZfbm90X2luX3RlbXBsYXRlIChleHByKTsKCQoJLyogTWFyayB0aGUgZXhwcmVzc2lvbiBjb25zdCBvciB2b2xhdGlsZSwgYXMgYXBwcm9wcmlhdGUuCgkgICBFdmVuIHRob3VnaCB3ZSd2ZSBkZWFsdCB3aXRoIHRoZSB0eXBlIGFib3ZlLCB3ZSBzdGlsbCBoYXZlCgkgICB0byBtYXJrIHRoZSBleHByZXNzaW9uIGl0c2VsZi4gICovCglpZiAodHlwZV9xdWFscyAmIFRZUEVfUVVBTF9DT05TVCkKCSAgVFJFRV9SRUFET05MWSAoZXhwcikgPSAxOwoJaWYgKHR5cGVfcXVhbHMgJiBUWVBFX1FVQUxfVk9MQVRJTEUpCgkgIFRSRUVfVEhJU19WT0xBVElMRSAoZXhwcikgPSAxOwoJCglyZXR1cm4gZXhwcjsKICAgICAgfQoKICAvKiBEaWRuJ3QgZmluZCB0aGUgYmFzZSBmaWVsZD8hPyAgKi8KICBnY2NfdW5yZWFjaGFibGUgKCk7Cn0KCi8qIENvbnZlcnQgT0JKRUNUIHRvIHRoZSBiYXNlIFRZUEUuICBPQkpFQ1QgaXMgYW4gZXhwcmVzc2lvbiB3aG9zZQogICB0eXBlIGlzIGEgY2xhc3MgdHlwZSBvciBhIHBvaW50ZXIgdG8gYSBjbGFzcyB0eXBlLiAgSW4gdGhlIGZvcm1lcgogICBjYXNlLCBUWVBFIGlzIGFsc28gYSBjbGFzcyB0eXBlOyBpbiB0aGUgbGF0dGVyIGl0IGlzIGFub3RoZXIKICAgcG9pbnRlciB0eXBlLiAgSWYgQ0hFQ0tfQUNDRVNTIGlzIHRydWUsIGFuIGVycm9yIG1lc3NhZ2UgaXMgZW1pdHRlZAogICBpZiBUWVBFIGlzIGluYWNjZXNzaWJsZS4gIElmIE9CSkVDVCBoYXMgcG9pbnRlciB0eXBlLCB0aGUgdmFsdWUgaXMKICAgYXNzdW1lZCB0byBiZSBub24tTlVMTC4gICovCgp0cmVlCmNvbnZlcnRfdG9fYmFzZSAodHJlZSBvYmplY3QsIHRyZWUgdHlwZSwgYm9vbCBjaGVja19hY2Nlc3MsIGJvb2wgbm9ubnVsbCkKewogIHRyZWUgYmluZm87CiAgdHJlZSBvYmplY3RfdHlwZTsKCiAgaWYgKFRZUEVfUFRSX1AgKFRSRUVfVFlQRSAob2JqZWN0KSkpCiAgICB7CiAgICAgIG9iamVjdF90eXBlID0gVFJFRV9UWVBFIChUUkVFX1RZUEUgKG9iamVjdCkpOwogICAgICB0eXBlID0gVFJFRV9UWVBFICh0eXBlKTsKICAgIH0KICBlbHNlCiAgICBvYmplY3RfdHlwZSA9IFRSRUVfVFlQRSAob2JqZWN0KTsKCiAgYmluZm8gPSBsb29rdXBfYmFzZSAob2JqZWN0X3R5cGUsIHR5cGUsCgkJICAgICAgIGNoZWNrX2FjY2VzcyA/IGJhX2NoZWNrIDogYmFfdW5pcXVlLCAKCQkgICAgICAgTlVMTCk7CiAgaWYgKCFiaW5mbyB8fCBiaW5mbyA9PSBlcnJvcl9tYXJrX25vZGUpCiAgICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwoKICByZXR1cm4gYnVpbGRfYmFzZV9wYXRoIChQTFVTX0VYUFIsIG9iamVjdCwgYmluZm8sIG5vbm51bGwpOwp9CgovKiBFWFBSIGlzIGFuIGV4cHJlc3Npb24gd2l0aCB1bnF1YWxpZmllZCBjbGFzcyB0eXBlLiAgQkFTRSBpcyBhIGJhc2UKICAgYmluZm8gb2YgdGhhdCBjbGFzcyB0eXBlLiAgUmV0dXJucyBFWFBSLCBjb252ZXJ0ZWQgdG8gdGhlIEJBU0UKICAgdHlwZS4gIFRoaXMgZnVuY3Rpb24gYXNzdW1lcyB0aGF0IEVYUFIgaXMgdGhlIG1vc3QgZGVyaXZlZCBjbGFzczsKICAgdGhlcmVmb3JlIHZpcnR1YWwgYmFzZXMgY2FuIGJlIGZvdW5kIGF0IHRoZWlyIHN0YXRpYyBvZmZzZXRzLiAgKi8KCnRyZWUKY29udmVydF90b19iYXNlX3N0YXRpY2FsbHkgKHRyZWUgZXhwciwgdHJlZSBiYXNlKQp7CiAgdHJlZSBleHByX3R5cGU7CgogIGV4cHJfdHlwZSA9IFRSRUVfVFlQRSAoZXhwcik7CiAgaWYgKCFTQU1FX0JJTkZPX1RZUEVfUCAoQklORk9fVFlQRSAoYmFzZSksIGV4cHJfdHlwZSkpCiAgICB7CiAgICAgIHRyZWUgcG9pbnRlcl90eXBlOwoKICAgICAgcG9pbnRlcl90eXBlID0gYnVpbGRfcG9pbnRlcl90eXBlIChleHByX3R5cGUpOwogICAgICBleHByID0gYnVpbGRfdW5hcnlfb3AgKEFERFJfRVhQUiwgZXhwciwgLypub2NvbnZlcnQ9Ki8xKTsKICAgICAgaWYgKCFpbnRlZ2VyX3plcm9wIChCSU5GT19PRkZTRVQgKGJhc2UpKSkKCSAgZXhwciA9IGJ1aWxkMiAoUExVU19FWFBSLCBwb2ludGVyX3R5cGUsIGV4cHIsIAoJCQkgYnVpbGRfbm9wIChwb2ludGVyX3R5cGUsIEJJTkZPX09GRlNFVCAoYmFzZSkpKTsKICAgICAgZXhwciA9IGJ1aWxkX25vcCAoYnVpbGRfcG9pbnRlcl90eXBlIChCSU5GT19UWVBFIChiYXNlKSksIGV4cHIpOwogICAgICBleHByID0gYnVpbGQxIChJTkRJUkVDVF9SRUYsIEJJTkZPX1RZUEUgKGJhc2UpLCBleHByKTsKICAgIH0KCiAgcmV0dXJuIGV4cHI7Cn0KCgwKdHJlZQpidWlsZF92ZmllbGRfcmVmICh0cmVlIGRhdHVtLCB0cmVlIHR5cGUpCnsKICB0cmVlIHZmaWVsZCwgdmNvbnRleHQ7CgogIGlmIChkYXR1bSA9PSBlcnJvcl9tYXJrX25vZGUpCiAgICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwoKICAvKiBGaXJzdCwgY29udmVydCB0byB0aGUgcmVxdWVzdGVkIHR5cGUuICAqLwogIGlmICghc2FtZV90eXBlX2lnbm9yaW5nX3RvcF9sZXZlbF9xdWFsaWZpZXJzX3AgKFRSRUVfVFlQRSAoZGF0dW0pLCB0eXBlKSkKICAgIGRhdHVtID0gY29udmVydF90b19iYXNlIChkYXR1bSwgdHlwZSwgLypjaGVja19hY2Nlc3M9Ki9mYWxzZSwKCQkJICAgICAvKm5vbm51bGw9Ki90cnVlKTsKCiAgLyogU2Vjb25kLCB0aGUgcmVxdWVzdGVkIHR5cGUgbWF5IG5vdCBiZSB0aGUgb3duZXIgb2YgaXRzIG93biB2cHRyLgogICAgIElmIG5vdCwgY29udmVydCB0byB0aGUgYmFzZSBjbGFzcyB0aGF0IG93bnMgaXQuICBXZSBjYW5ub3QgdXNlCiAgICAgY29udmVydF90b19iYXNlIGhlcmUsIGJlY2F1c2UgVkNPTlRFWFQgbWF5IGFwcGVhciBtb3JlIHRoYW4gb25jZQogICAgIGluIHRoZSBpbmhlcml0YW5jZSBoaWVyYXJjaHkgb2YgVFlQRSwgYW5kIHRodXMgZGlyZWN0IGNvbnZlcnNpb24KICAgICBiZXR3ZWVuIHRoZSB0eXBlcyBtYXkgYmUgYW1iaWd1b3VzLiAgRm9sbG93aW5nIHRoZSBwYXRoIGJhY2sgdXAKICAgICBvbmUgc3RlcCBhdCBhIHRpbWUgdmlhIHByaW1hcnkgYmFzZXMgYXZvaWRzIHRoZSBwcm9ibGVtLiAgKi8KICB2ZmllbGQgPSBUWVBFX1ZGSUVMRCAodHlwZSk7CiAgdmNvbnRleHQgPSBERUNMX0NPTlRFWFQgKHZmaWVsZCk7CiAgd2hpbGUgKCFzYW1lX3R5cGVfaWdub3JpbmdfdG9wX2xldmVsX3F1YWxpZmllcnNfcCAodmNvbnRleHQsIHR5cGUpKQogICAgewogICAgICBkYXR1bSA9IGJ1aWxkX3NpbXBsZV9iYXNlX3BhdGggKGRhdHVtLCBDTEFTU1RZUEVfUFJJTUFSWV9CSU5GTyAodHlwZSkpOwogICAgICB0eXBlID0gVFJFRV9UWVBFIChkYXR1bSk7CiAgICB9CgogIHJldHVybiBidWlsZDMgKENPTVBPTkVOVF9SRUYsIFRSRUVfVFlQRSAodmZpZWxkKSwgZGF0dW0sIHZmaWVsZCwgTlVMTF9UUkVFKTsKfQoKLyogR2l2ZW4gYW4gb2JqZWN0IElOU1RBTkNFLCByZXR1cm4gYW4gZXhwcmVzc2lvbiB3aGljaCB5aWVsZHMgdGhlCiAgIHZ0YWJsZSBlbGVtZW50IGNvcnJlc3BvbmRpbmcgdG8gSU5ERVguICBUaGVyZSBhcmUgbWFueSBzcGVjaWFsCiAgIGNhc2VzIGZvciBJTlNUQU5DRSB3aGljaCB3ZSB0YWtlIGNhcmUgb2YgaGVyZSwgbWFpbmx5IHRvIGF2b2lkCiAgIGNyZWF0aW5nIGV4dHJhIHRyZWUgbm9kZXMgd2hlbiB3ZSBkb24ndCBoYXZlIHRvLiAgKi8KCnN0YXRpYyB0cmVlCmJ1aWxkX3Z0YmxfcmVmXzEgKHRyZWUgaW5zdGFuY2UsIHRyZWUgaWR4KQp7CiAgdHJlZSBhcmVmOwogIHRyZWUgdnRibCA9IE5VTExfVFJFRTsKCiAgLyogVHJ5IHRvIGZpZ3VyZSBvdXQgd2hhdCBhIHJlZmVyZW5jZSByZWZlcnMgdG8sIGFuZAogICAgIGFjY2VzcyBpdHMgdmlydHVhbCBmdW5jdGlvbiB0YWJsZSBkaXJlY3RseS4gICovCgogIGludCBjZHRvcnAgPSAwOwogIHRyZWUgZml4ZWRfdHlwZSA9IGZpeGVkX3R5cGVfb3JfbnVsbCAoaW5zdGFuY2UsIE5VTEwsICZjZHRvcnApOwoKICB0cmVlIGJhc2V0eXBlID0gbm9uX3JlZmVyZW5jZSAoVFJFRV9UWVBFIChpbnN0YW5jZSkpOwoKICBpZiAoZml4ZWRfdHlwZSAmJiAhY2R0b3JwKQogICAgewogICAgICB0cmVlIGJpbmZvID0gbG9va3VwX2Jhc2UgKGZpeGVkX3R5cGUsIGJhc2V0eXBlLAoJCQkJYmFfdW5pcXVlIHwgYmFfcXVpZXQsIE5VTEwpOwogICAgICBpZiAoYmluZm8pCgl2dGJsID0gdW5zaGFyZV9leHByIChCSU5GT19WVEFCTEUgKGJpbmZvKSk7CiAgICB9CgogIGlmICghdnRibCkKICAgIHZ0YmwgPSBidWlsZF92ZmllbGRfcmVmIChpbnN0YW5jZSwgYmFzZXR5cGUpOwogIAogIGFzc2VtYmxlX2V4dGVybmFsICh2dGJsKTsKCiAgLyogQVBQTEUgTE9DQUwgYmVnaW4gS0VYVCBkb3VibGUgZGVzdHJ1Y3RvciAqLwojaWZkZWYgQURKVVNUX1ZUQUJMRV9JTkRFWAogIEFESlVTVF9WVEFCTEVfSU5ERVggKGlkeCwgdnRibCk7CiNlbmRpZgogIC8qIEFQUExFIExPQ0FMIGVuZCBLRVhUIGRvdWJsZSBkZXN0cnVjdG9yICovCgogIGFyZWYgPSBidWlsZF9hcnJheV9yZWYgKHZ0YmwsIGlkeCk7CiAgVFJFRV9DT05TVEFOVCAoYXJlZikgfD0gVFJFRV9DT05TVEFOVCAodnRibCkgJiYgVFJFRV9DT05TVEFOVCAoaWR4KTsKICBUUkVFX0lOVkFSSUFOVCAoYXJlZikgPSBUUkVFX0NPTlNUQU5UIChhcmVmKTsKCiAgcmV0dXJuIGFyZWY7Cn0KCnRyZWUKYnVpbGRfdnRibF9yZWYgKHRyZWUgaW5zdGFuY2UsIHRyZWUgaWR4KQp7CiAgdHJlZSBhcmVmID0gYnVpbGRfdnRibF9yZWZfMSAoaW5zdGFuY2UsIGlkeCk7CgogIHJldHVybiBhcmVmOwp9CgovKiBHaXZlbiBhIHN0YWJsZSBvYmplY3QgcG9pbnRlciBJTlNUQU5DRV9QVFIsIHJldHVybiBhbiBleHByZXNzaW9uIHdoaWNoCiAgIHlpZWxkcyBhIGZ1bmN0aW9uIHBvaW50ZXIgY29ycmVzcG9uZGluZyB0byB2dGFibGUgZWxlbWVudCBJTkRFWC4gICovCgp0cmVlCmJ1aWxkX3Zmbl9yZWYgKHRyZWUgaW5zdGFuY2VfcHRyLCB0cmVlIGlkeCkKewogIHRyZWUgYXJlZjsKCiAgYXJlZiA9IGJ1aWxkX3Z0YmxfcmVmXzEgKGJ1aWxkX2luZGlyZWN0X3JlZiAoaW5zdGFuY2VfcHRyLCAwKSwgaWR4KTsKCiAgLyogV2hlbiB1c2luZyBmdW5jdGlvbiBkZXNjcmlwdG9ycywgdGhlIGFkZHJlc3Mgb2YgdGhlCiAgICAgdnRhYmxlIGVudHJ5IGlzIHRyZWF0ZWQgYXMgYSBmdW5jdGlvbiBwb2ludGVyLiAgKi8KICBpZiAoVEFSR0VUX1ZUQUJMRV9VU0VTX0RFU0NSSVBUT1JTKQogICAgYXJlZiA9IGJ1aWxkMSAoTk9QX0VYUFIsIFRSRUVfVFlQRSAoYXJlZiksCgkJICAgYnVpbGRfdW5hcnlfb3AgKEFERFJfRVhQUiwgYXJlZiwgLypub2NvbnZlcnQ9Ki8xKSk7CgogIC8qIFJlbWVtYmVyIHRoaXMgYXMgYSBtZXRob2QgcmVmZXJlbmNlLCBmb3IgbGF0ZXIgZGV2aXJ0dWFsaXphdGlvbi4gICovCiAgYXJlZiA9IGJ1aWxkMyAoT0JKX1RZUEVfUkVGLCBUUkVFX1RZUEUgKGFyZWYpLCBhcmVmLCBpbnN0YW5jZV9wdHIsIGlkeCk7CgogIHJldHVybiBhcmVmOwp9CgovKiBBUFBMRSBMT0NBTCBiZWdpbiBLRVhUIGluZGlyZWN0LXZpcnR1YWwtY2FsbHMgLS1zdHMgKi8KLyogR2l2ZW4gYSBWVEJMIGFuZCBhbiBJRFgsIHJldHVybiBhbiBleHByZXNzaW9uIGZvciB0aGUgZnVuY3Rpb24KICAgcG9pbnRlciBsb2NhdGVkIGF0IHRoZSBpbmRpY2F0ZWQgaW5kZXguICBCQVNFVFlQRSBpcyB0aGUgc3RhdGljCiAgIHR5cGUgb2YgdGhlIG9iamVjdCBjb250YWluaW5nIHRoZSB2dGFibGUuICAqLwoKdHJlZQpidWlsZF92Zm5fcmVmX3VzaW5nX3Z0YWJsZSAodHJlZSB2dGJsLCB0cmVlIGlkeCkKewogIHRyZWUgYXJlZjsKCiAgdnRibCA9IHVuc2hhcmVfZXhwciAodnRibCk7CiAgYXNzZW1ibGVfZXh0ZXJuYWwgKHZ0YmwpOwoKICAvKiBBUFBMRSBMT0NBTCBLRVhUIGRvdWJsZSBkZXN0cnVjdG9yICovCiNpZmRlZiBBREpVU1RfVlRBQkxFX0lOREVYCiAgQURKVVNUX1ZUQUJMRV9JTkRFWCAoaWR4LCB2dGJsKTsKI2VuZGlmCgogIGFyZWYgPSBidWlsZF9hcnJheV9yZWYgKHZ0YmwsIGlkeCk7CiAgVFJFRV9DT05TVEFOVCAoYXJlZikgfD0gVFJFRV9DT05TVEFOVCAodnRibCkgJiYgVFJFRV9DT05TVEFOVCAoaWR4KTsKICBUUkVFX0lOVkFSSUFOVCAoYXJlZikgPSBUUkVFX0NPTlNUQU5UIChhcmVmKTsKCiAgcmV0dXJuIGFyZWY7Cn0KLyogQVBQTEUgTE9DQUwgZW5kIEtFWFQgaW5kaXJlY3QtdmlydHVhbC1jYWxscyAtLXN0cyAqLwoKLyogUmV0dXJuIHRoZSBuYW1lIG9mIHRoZSB2aXJ0dWFsIGZ1bmN0aW9uIHRhYmxlIChhcyBhbiBJREVOVElGSUVSX05PREUpCiAgIGZvciB0aGUgZ2l2ZW4gVFlQRS4gICovCgpzdGF0aWMgdHJlZQpnZXRfdnRhYmxlX25hbWUgKHRyZWUgdHlwZSkKewogIHJldHVybiBtYW5nbGVfdnRibF9mb3JfdHlwZSAodHlwZSk7Cn0KCi8qIFJldHVybiBhbiBJREVOVElGSUVSX05PREUgZm9yIHRoZSBuYW1lIG9mIHRoZSB2aXJ0dWFsIHRhYmxlIHRhYmxlCiAgIGZvciBUWVBFLiAgKi8KCnRyZWUKZ2V0X3Z0dF9uYW1lICh0cmVlIHR5cGUpCnsKICByZXR1cm4gbWFuZ2xlX3Z0dF9mb3JfdHlwZSAodHlwZSk7Cn0KCi8qIERFQ0wgaXMgYW4gZW50aXR5IGFzc29jaWF0ZWQgd2l0aCBUWVBFLCBsaWtlIGEgdmlydHVhbCB0YWJsZSBvciBhbgogICBpbXBsaWNpdGx5IGdlbmVyYXRlZCBjb25zdHJ1Y3Rvci4gIERldGVybWluZSB3aGV0aGVyIG9yIG5vdCBERUNMCiAgIHNob3VsZCBoYXZlIGV4dGVybmFsIG9yIGludGVybmFsIGxpbmthZ2UgYXQgdGhlIG9iamVjdCBmaWxlCiAgIGxldmVsLiAgVGhpcyByb3V0aW5lIGRvZXMgbm90IGRlYWwgd2l0aCBDT01EQVQgbGlua2FnZSBhbmQgb3RoZXIKICAgc2ltaWxhciBjb21wbGV4aXRpZXM7IGl0IHNpbXBseSBzZXRzIFRSRUVfUFVCTElDIGlmIGl0IHBvc3NpYmxlIGZvcgogICBlbnRpdGllcyBpbiBvdGhlciB0cmFuc2xhdGlvbiB1bml0cyB0byBjb250YWluIGNvcGllcyBvZiBERUNMLCBpbgogICB0aGUgYWJzdHJhY3QuICAqLwoKdm9pZApzZXRfbGlua2FnZV9hY2NvcmRpbmdfdG9fdHlwZSAodHJlZSB0eXBlLCB0cmVlIGRlY2wpCnsKICAvKiBJZiBUWVBFIGludm9sdmVzIGEgbG9jYWwgY2xhc3MgaW4gYSBmdW5jdGlvbiB3aXRoIGludGVybmFsCiAgICAgbGlua2FnZSwgdGhlbiBERUNMIHNob3VsZCBoYXZlIGludGVybmFsIGxpbmthZ2UgdG9vLiAgT3RoZXIgbG9jYWwKICAgICBjbGFzc2VzIGhhdmUgbm8gbGlua2FnZSAtLSBidXQgaWYgdGhlaXIgY29udGFpbmluZyBmdW5jdGlvbnMKICAgICBoYXZlIGV4dGVybmFsIGxpbmthZ2UsIGl0IG1ha2VzIHNlbnNlIGZvciBERUNMIHRvIGhhdmUgZXh0ZXJuYWwKICAgICBsaW5rYWdlIHRvby4gIFRoYXQgd2lsbCBhbGxvdyB0ZW1wbGF0ZSBkZWZpbml0aW9ucyB0byBiZSBtZXJnZWQsCiAgICAgZm9yIGV4YW1wbGUuICAqLwogIGlmIChub19saW5rYWdlX2NoZWNrICh0eXBlLCAvKnJlbGF4ZWRfcD0qL3RydWUpKQogICAgewogICAgICBUUkVFX1BVQkxJQyAoZGVjbCkgPSAwOwogICAgICBERUNMX0lOVEVSRkFDRV9LTk9XTiAoZGVjbCkgPSAxOwogICAgfQogIGVsc2UKICAgIFRSRUVfUFVCTElDIChkZWNsKSA9IDE7Cn0KCi8qIENyZWF0ZSBhIFZBUl9ERUNMIGZvciBhIHByaW1hcnkgb3Igc2Vjb25kYXJ5IHZ0YWJsZSBmb3IgQ0xBU1NfVFlQRS4KICAgKEZvciBhIHNlY29uZGFyeSB2dGFibGUgZm9yIEItaW4tRCwgQ0xBU1NfVFlQRSBzaG91bGQgYmUgRCwgbm90IEIuKQogICBVc2UgTkFNRSBmb3IgdGhlIG5hbWUgb2YgdGhlIHZ0YWJsZSwgYW5kIFZUQUJMRV9UWVBFIGZvciBpdHMgdHlwZS4gICovCgpzdGF0aWMgdHJlZQpidWlsZF92dGFibGUgKHRyZWUgY2xhc3NfdHlwZSwgdHJlZSBuYW1lLCB0cmVlIHZ0YWJsZV90eXBlKQp7CiAgdHJlZSBkZWNsOwoKICBkZWNsID0gYnVpbGRfbGFuZ19kZWNsIChWQVJfREVDTCwgbmFtZSwgdnRhYmxlX3R5cGUpOwogIC8qIHZ0YWJsZSBuYW1lcyBhcmUgYWxyZWFkeSBtYW5nbGVkOyBnaXZlIHRoZW0gdGhlaXIgREVDTF9BU1NFTUJMRVJfTkFNRQogICAgIG5vdyB0byBhdm9pZCBjb25mdXNpb24gaW4gbWFuZ2xlX2RlY2wuICAqLwogIFNFVF9ERUNMX0FTU0VNQkxFUl9OQU1FIChkZWNsLCBuYW1lKTsKICBERUNMX0NPTlRFWFQgKGRlY2wpID0gY2xhc3NfdHlwZTsKICBERUNMX0FSVElGSUNJQUwgKGRlY2wpID0gMTsKICBUUkVFX1NUQVRJQyAoZGVjbCkgPSAxOwogIFRSRUVfUkVBRE9OTFkgKGRlY2wpID0gMTsKICBERUNMX1ZJUlRVQUxfUCAoZGVjbCkgPSAxOwogIERFQ0xfQUxJR04gKGRlY2wpID0gVEFSR0VUX1ZUQUJMRV9FTlRSWV9BTElHTjsKICBERUNMX1ZUQUJMRV9PUl9WVFRfUCAoZGVjbCkgPSAxOwogIC8qIEF0IG9uZSB0aW1lIHRoZSB2dGFibGUgaW5mbyB3YXMgZ3JhYmJlZCAyIHdvcmRzIGF0IGEgdGltZS4gIFRoaXMKICAgICBmYWlscyBvbiBzcGFyYyB1bmxlc3MgeW91IGhhdmUgOC1ieXRlIGFsaWdubWVudC4gICh0aWVtYW5uKSAqLwogIERFQ0xfQUxJR04gKGRlY2wpID0gTUFYIChUWVBFX0FMSUdOIChkb3VibGVfdHlwZV9ub2RlKSwKCQkJICAgREVDTF9BTElHTiAoZGVjbCkpOwogIHNldF9saW5rYWdlX2FjY29yZGluZ190b190eXBlIChjbGFzc190eXBlLCBkZWNsKTsKICAvKiBUaGUgdnRhYmxlIGhhcyBub3QgYmVlbiBkZWZpbmVkIC0tIHlldC4gICovCiAgREVDTF9FWFRFUk5BTCAoZGVjbCkgPSAxOwogIERFQ0xfTk9UX1JFQUxMWV9FWFRFUk4gKGRlY2wpID0gMTsKCiAgLyogTWFyayB0aGUgVkFSX0RFQ0wgbm9kZSByZXByZXNlbnRpbmcgdGhlIHZ0YWJsZSBpdHNlbGYgYXMgYQogICAgICJncmF0dWl0b3VzIiBvbmUsIHRoZXJlYnkgZm9yY2luZyBkd2FyZm91dC5jIHRvIGlnbm9yZSBpdC4gIEl0CiAgICAgaXMgcmF0aGVyIGltcG9ydGFudCB0aGF0IHN1Y2ggdGhpbmdzIGJlIGlnbm9yZWQgYmVjYXVzZSBhbnkKICAgICBlZmZvcnQgdG8gYWN0dWFsbHkgZ2VuZXJhdGUgRFdBUkYgZm9yIHRoZW0gd2lsbCBydW4gaW50bwogICAgIHRyb3VibGUgd2hlbi9pZiB3ZSBlbmNvdW50ZXIgY29kZSBsaWtlOgogICAgICAgCiAgICAgI3ByYWdtYSBpbnRlcmZhY2UKICAgICBzdHJ1Y3QgUyB7IHZpcnR1YWwgdm9pZCBtZW1iZXIgKCk7IH07CgkgICAKICAgICBiZWNhdXNlIHRoZSBhcnRpZmljaWFsIGRlY2xhcmF0aW9uIG9mIHRoZSB2dGFibGUgaXRzZWxmIChhcwogICAgIG1hbnVmYWN0dXJlZCBieSB0aGUgZysrIGZyb250IGVuZCkgd2lsbCBzYXkgdGhhdCB0aGUgdnRhYmxlIGlzCiAgICAgYSBzdGF0aWMgbWVtYmVyIG9mIGBTJyBidXQgb25seSAqYWZ0ZXIqIHRoZSBkZWJ1ZyBvdXRwdXQgZm9yCiAgICAgdGhlIGRlZmluaXRpb24gb2YgYFMnIGhhcyBhbHJlYWR5IGJlZW4gb3V0cHV0LiAgVGhpcyBjYXVzZXMKICAgICBncmllZiBiZWNhdXNlIHRoZSBEV0FSRiBlbnRyeSBmb3IgdGhlIGRlZmluaXRpb24gb2YgdGhlIHZ0YWJsZQogICAgIHdpbGwgdHJ5IHRvIHJlZmVyIGJhY2sgdG8gYW4gZWFybGllciAqZGVjbGFyYXRpb24qIG9mIHRoZQogICAgIHZ0YWJsZSBhcyBhIHN0YXRpYyBtZW1iZXIgb2YgYFMnIGFuZCB0aGVyZSB3b24ndCBiZSBvbmUuICBXZQogICAgIG1pZ2h0IGJlIGFibGUgdG8gYXJyYW5nZSB0byBoYXZlIHRoZSAidnRhYmxlIHN0YXRpYyBtZW1iZXIiCiAgICAgYXR0YWNoZWQgdG8gdGhlIG1lbWJlciBsaXN0IGZvciBgUycgYmVmb3JlIHRoZSBkZWJ1ZyBpbmZvIGZvcgogICAgIGBTJyBnZXQgd3JpdHRlbiAod2hpY2ggd291bGQgc29sdmUgdGhlIHByb2JsZW0pIGJ1dCB0aGF0IHdvdWxkCiAgICAgcmVxdWlyZSBtb3JlIGludHJ1c2l2ZSBjaGFuZ2VzIHRvIHRoZSBnKysgZnJvbnQgZW5kLiAgKi8KICBERUNMX0lHTk9SRURfUCAoZGVjbCkgPSAxOwoKICByZXR1cm4gZGVjbDsKfQoKLyogR2V0IHRoZSBWQVJfREVDTCBvZiB0aGUgdnRhYmxlIGZvciBUWVBFLiBUWVBFIG5lZWQgbm90IGJlIHBvbHltb3JwaGljLAogICBvciBldmVuIGNvbXBsZXRlLiAgSWYgdGhpcyBkb2VzIG5vdCBleGlzdCwgY3JlYXRlIGl0LiAgSWYgQ09NUExFVEUgaXMKICAgbm9uemVybywgdGhlbiBjb21wbGV0ZSB0aGUgZGVmaW5pdGlvbiBvZiBpdCAtLSB0aGF0IHdpbGwgcmVuZGVyIGl0CiAgIGltcG9zc2libGUgdG8gYWN0dWFsbHkgYnVpbGQgdGhlIHZ0YWJsZSwgYnV0IGlzIHVzZWZ1bCB0byBnZXQgYXQgdGhvc2UKICAgd2hpY2ggYXJlIGtub3duIHRvIGV4aXN0IGluIHRoZSBydW50aW1lLiAgKi8KCnRyZWUgCmdldF92dGFibGVfZGVjbCAodHJlZSB0eXBlLCBpbnQgY29tcGxldGUpCnsKICB0cmVlIGRlY2w7CgogIGlmIChDTEFTU1RZUEVfVlRBQkxFUyAodHlwZSkpCiAgICByZXR1cm4gQ0xBU1NUWVBFX1ZUQUJMRVMgKHR5cGUpOwogIAogIGRlY2wgPSBidWlsZF92dGFibGUgKHR5cGUsIGdldF92dGFibGVfbmFtZSAodHlwZSksIHZ0YmxfdHlwZV9ub2RlKTsKICBDTEFTU1RZUEVfVlRBQkxFUyAodHlwZSkgPSBkZWNsOwoKICBpZiAoY29tcGxldGUpCiAgICB7CiAgICAgIERFQ0xfRVhURVJOQUwgKGRlY2wpID0gMTsKICAgICAgY3BfZmluaXNoX2RlY2wgKGRlY2wsIE5VTExfVFJFRSwgTlVMTF9UUkVFLCAwKTsKICAgIH0KCiAgcmV0dXJuIGRlY2w7Cn0KCi8qIEJ1aWxkIHRoZSBwcmltYXJ5IHZpcnR1YWwgZnVuY3Rpb24gdGFibGUgZm9yIFRZUEUuICBJZiBCSU5GTyBpcwogICBub24tTlVMTCwgYnVpbGQgdGhlIHZ0YWJsZSBzdGFydGluZyB3aXRoIHRoZSBpbml0aWFsIGFwcHJveGltYXRpb24KICAgdGhhdCBpdCBpcyB0aGUgc2FtZSBhcyB0aGUgb25lIHdoaWNoIGlzIHRoZSBoZWFkIG9mIHRoZSBhc3NvY2lhdGlvbgogICBsaXN0LiAgUmV0dXJucyBhIG5vbnplcm8gdmFsdWUgaWYgYSBuZXcgdnRhYmxlIGlzIGFjdHVhbGx5CiAgIGNyZWF0ZWQuICAqLwoKc3RhdGljIGludApidWlsZF9wcmltYXJ5X3Z0YWJsZSAodHJlZSBiaW5mbywgdHJlZSB0eXBlKQp7CiAgdHJlZSBkZWNsOwogIHRyZWUgdmlydHVhbHM7CgogIGRlY2wgPSBnZXRfdnRhYmxlX2RlY2wgKHR5cGUsIC8qY29tcGxldGU9Ki8wKTsKICAKICBpZiAoYmluZm8pCiAgICB7CiAgICAgIGlmIChCSU5GT19ORVdfVlRBQkxFX01BUktFRCAoYmluZm8pKQoJLyogV2UgaGF2ZSBhbHJlYWR5IGNyZWF0ZWQgYSB2dGFibGUgZm9yIHRoaXMgYmFzZSwgc28gdGhlcmUncwoJICAgbm8gbmVlZCB0byBkbyBpdCBhZ2Fpbi4gICovCglyZXR1cm4gMDsKICAgICAgCiAgICAgIHZpcnR1YWxzID0gY29weV9saXN0IChCSU5GT19WSVJUVUFMUyAoYmluZm8pKTsKICAgICAgVFJFRV9UWVBFIChkZWNsKSA9IFRSRUVfVFlQRSAoZ2V0X3Z0YmxfZGVjbF9mb3JfYmluZm8gKGJpbmZvKSk7CiAgICAgIERFQ0xfU0laRSAoZGVjbCkgPSBUWVBFX1NJWkUgKFRSRUVfVFlQRSAoZGVjbCkpOwogICAgICBERUNMX1NJWkVfVU5JVCAoZGVjbCkgPSBUWVBFX1NJWkVfVU5JVCAoVFJFRV9UWVBFIChkZWNsKSk7CiAgICB9CiAgZWxzZQogICAgewogICAgICBnY2NfYXNzZXJ0IChUUkVFX1RZUEUgKGRlY2wpID09IHZ0YmxfdHlwZV9ub2RlKTsKICAgICAgdmlydHVhbHMgPSBOVUxMX1RSRUU7CiAgICB9CgojaWZkZWYgR0FUSEVSX1NUQVRJU1RJQ1MKICBuX3Z0YWJsZXMgKz0gMTsKICBuX3Z0YWJsZV9lbGVtcyArPSBsaXN0X2xlbmd0aCAodmlydHVhbHMpOwojZW5kaWYKCiAgLyogSW5pdGlhbGl6ZSB0aGUgYXNzb2NpYXRpb24gbGlzdCBmb3IgdGhpcyB0eXBlLCBiYXNlZAogICAgIG9uIG91ciBmaXJzdCBhcHByb3hpbWF0aW9uLiAgKi8KICBCSU5GT19WVEFCTEUgKFRZUEVfQklORk8gKHR5cGUpKSA9IGRlY2w7CiAgQklORk9fVklSVFVBTFMgKFRZUEVfQklORk8gKHR5cGUpKSA9IHZpcnR1YWxzOwogIFNFVF9CSU5GT19ORVdfVlRBQkxFX01BUktFRCAoVFlQRV9CSU5GTyAodHlwZSkpOwogIHJldHVybiAxOwp9CgovKiBHaXZlIEJJTkZPIGEgbmV3IHZpcnR1YWwgZnVuY3Rpb24gdGFibGUgd2hpY2ggaXMgaW5pdGlhbGl6ZWQKICAgd2l0aCBhIHNrZWxldG9uLWNvcHkgb2YgaXRzIG9yaWdpbmFsIGluaXRpYWxpemF0aW9uLiAgVGhlIG9ubHkKICAgZW50cnkgdGhhdCBjaGFuZ2VzIGlzIHRoZSBgZGVsdGEnIGVudHJ5LCBzbyB3ZSBjYW4gcmVhbGx5CiAgIHNoYXJlIGEgbG90IG9mIHN0cnVjdHVyZS4KCiAgIEZPUl9UWVBFIGlzIHRoZSBtb3N0IGRlcml2ZWQgdHlwZSB3aGljaCBjYXVzZWQgdGhpcyB0YWJsZSB0bwogICBiZSBuZWVkZWQuCgogICBSZXR1cm5zIG5vbnplcm8gaWYgd2UgaGF2ZW4ndCBtZXQgQklORk8gYmVmb3JlLgoKICAgVGhlIG9yZGVyIGluIHdoaWNoIHZ0YWJsZXMgYXJlIGJ1aWx0IChieSBjYWxsaW5nIHRoaXMgZnVuY3Rpb24pIGZvcgogICBhbiBvYmplY3QgbXVzdCByZW1haW4gdGhlIHNhbWUsIG90aGVyd2lzZSBhIGJpbmFyeSBpbmNvbXBhdGliaWxpdHkKICAgY2FuIHJlc3VsdC4gICovCgpzdGF0aWMgaW50CmJ1aWxkX3NlY29uZGFyeV92dGFibGUgKHRyZWUgYmluZm8pCnsKICBpZiAoQklORk9fTkVXX1ZUQUJMRV9NQVJLRUQgKGJpbmZvKSkKICAgIC8qIFdlIGFscmVhZHkgY3JlYXRlZCBhIHZ0YWJsZSBmb3IgdGhpcyBiYXNlLiAgVGhlcmUncyBubyBuZWVkIHRvCiAgICAgICBkbyBpdCBhZ2Fpbi4gICovCiAgICByZXR1cm4gMDsKCiAgLyogUmVtZW1iZXIgdGhhdCB3ZSd2ZSBjcmVhdGVkIGEgdnRhYmxlIGZvciB0aGlzIEJJTkZPLCBzbyB0aGF0IHdlCiAgICAgZG9uJ3QgdHJ5IHRvIGRvIHNvIGFnYWluLiAgKi8KICBTRVRfQklORk9fTkVXX1ZUQUJMRV9NQVJLRUQgKGJpbmZvKTsKICAKICAvKiBNYWtlIGZyZXNoIHZpcnR1YWwgbGlzdCwgc28gd2UgY2FuIHNtYXNoIGl0IGxhdGVyLiAgKi8KICBCSU5GT19WSVJUVUFMUyAoYmluZm8pID0gY29weV9saXN0IChCSU5GT19WSVJUVUFMUyAoYmluZm8pKTsKCiAgLyogU2Vjb25kYXJ5IHZ0YWJsZXMgYXJlIGxhaWQgb3V0IGFzIHBhcnQgb2YgdGhlIHNhbWUgc3RydWN0dXJlIGFzCiAgICAgdGhlIHByaW1hcnkgdnRhYmxlLiAgKi8KICBCSU5GT19WVEFCTEUgKGJpbmZvKSA9IE5VTExfVFJFRTsKICByZXR1cm4gMTsKfQoKLyogQ3JlYXRlIGEgbmV3IHZ0YWJsZSBmb3IgQklORk8gd2hpY2ggaXMgdGhlIGhpZXJhcmNoeSBkb21pbmF0ZWQgYnkKICAgVC4gUmV0dXJuIG5vbnplcm8gaWYgd2UgYWN0dWFsbHkgY3JlYXRlZCBhIG5ldyB2dGFibGUuICAqLwoKc3RhdGljIGludAptYWtlX25ld192dGFibGUgKHRyZWUgdCwgdHJlZSBiaW5mbykKewogIGlmIChiaW5mbyA9PSBUWVBFX0JJTkZPICh0KSkKICAgIC8qIEluIHRoaXMgY2FzZSwgaXQgaXMgKnR5cGUqJ3MgdnRhYmxlIHdlIGFyZSBtb2RpZnlpbmcuICBXZSBzdGFydAogICAgICAgd2l0aCB0aGUgYXBwcm94aW1hdGlvbiB0aGF0IGl0cyB2dGFibGUgaXMgdGhhdCBvZiB0aGUKICAgICAgIGltbWVkaWF0ZSBiYXNlIGNsYXNzLiAgKi8KICAgIHJldHVybiBidWlsZF9wcmltYXJ5X3Z0YWJsZSAoYmluZm8sIHQpOwogIGVsc2UKICAgIC8qIFRoaXMgaXMgb3VyIHZlcnkgb3duIGNvcHkgb2YgYGJhc2V0eXBlJyB0byBwbGF5IHdpdGguICBMYXRlciwKICAgICAgIHdlIHdpbGwgZmlsbCBpbiBhbGwgdGhlIHZpcnR1YWwgZnVuY3Rpb25zIHRoYXQgb3ZlcnJpZGUgdGhlCiAgICAgICB2aXJ0dWFsIGZ1bmN0aW9ucyBpbiB0aGVzZSBiYXNlIGNsYXNzZXMgd2hpY2ggYXJlIG5vdCBkZWZpbmVkCiAgICAgICBieSB0aGUgY3VycmVudCB0eXBlLiAgKi8KICAgIHJldHVybiBidWlsZF9zZWNvbmRhcnlfdnRhYmxlIChiaW5mbyk7Cn0KCi8qIE1ha2UgKlZJUlRVQUxTLCBhbiBlbnRyeSBvbiB0aGUgQklORk9fVklSVFVBTFMgbGlzdCBmb3IgQklORk8KICAgKHdoaWNoIGlzIGluIHRoZSBoaWVyYXJjaHkgZG9taW5hdGVkIGJ5IFQpIGxpc3QgRk5ERUNMIGFzIGl0cwogICBCVl9GTi4gIERFTFRBIGlzIHRoZSByZXF1aXJlZCBjb25zdGFudCBhZGp1c3RtZW50IGZyb20gdGhlIGB0aGlzJwogICBwb2ludGVyIHdoZXJlIHRoZSB2dGFibGUgZW50cnkgYXBwZWFycyB0byB0aGUgYHRoaXMnIHJlcXVpcmVkIHdoZW4KICAgdGhlIGZ1bmN0aW9uIGlzIGFjdHVhbGx5IGNhbGxlZC4gICovCgpzdGF0aWMgdm9pZAptb2RpZnlfdnRhYmxlX2VudHJ5ICh0cmVlIHQsCiAgICAgICAgICAgICAgICAgICAgIHRyZWUgYmluZm8sIAogICAgICAgICAgICAgICAgICAgICB0cmVlIGZuZGVjbCwgCiAgICAgICAgICAgICAgICAgICAgIHRyZWUgZGVsdGEsIAogICAgICAgICAgICAgICAgICAgICB0cmVlICp2aXJ0dWFscykKewogIHRyZWUgdjsKCiAgdiA9ICp2aXJ0dWFsczsKCiAgaWYgKGZuZGVjbCAhPSBCVl9GTiAodikKICAgICAgfHwgIXRyZWVfaW50X2NzdF9lcXVhbCAoZGVsdGEsIEJWX0RFTFRBICh2KSkpCiAgICB7CiAgICAgIC8qIFdlIG5lZWQgYSBuZXcgdnRhYmxlIGZvciBCSU5GTy4gICovCiAgICAgIGlmIChtYWtlX25ld192dGFibGUgKHQsIGJpbmZvKSkKCXsKCSAgLyogSWYgd2UgcmVhbGx5IGRpZCBtYWtlIGEgbmV3IHZ0YWJsZSwgd2UgYWxzbyBtYWRlIGEgY29weQoJICAgICBvZiB0aGUgQklORk9fVklSVFVBTFMgbGlzdC4gIE5vdywgd2UgaGF2ZSB0byBmaW5kIHRoZQoJICAgICBjb3JyZXNwb25kaW5nIGVudHJ5IGluIHRoYXQgbGlzdC4gICovCgkgICp2aXJ0dWFscyA9IEJJTkZPX1ZJUlRVQUxTIChiaW5mbyk7CgkgIHdoaWxlIChCVl9GTiAoKnZpcnR1YWxzKSAhPSBCVl9GTiAodikpCgkgICAgKnZpcnR1YWxzID0gVFJFRV9DSEFJTiAoKnZpcnR1YWxzKTsKCSAgdiA9ICp2aXJ0dWFsczsKCX0KCiAgICAgIEJWX0RFTFRBICh2KSA9IGRlbHRhOwogICAgICBCVl9WQ0FMTF9JTkRFWCAodikgPSBOVUxMX1RSRUU7CiAgICAgIEJWX0ZOICh2KSA9IGZuZGVjbDsKICAgIH0KfQoKDAovKiBBZGQgbWV0aG9kIE1FVEhPRCB0byBjbGFzcyBUWVBFLiAgKi8KCnZvaWQKYWRkX21ldGhvZCAodHJlZSB0eXBlLCB0cmVlIG1ldGhvZCkKewogIGludCB1c2luZzsKICB1bnNpZ25lZCBzbG90OwogIHRyZWUgb3ZlcmxvYWQ7CiAgYm9vbCB0ZW1wbGF0ZV9jb252X3AgPSBmYWxzZTsKICBib29sIGNvbnZfcDsKICBWRUModHJlZSkgKm1ldGhvZF92ZWM7CiAgYm9vbCBjb21wbGV0ZV9wOwogIGJvb2wgaW5zZXJ0X3AgPSBmYWxzZTsKICB0cmVlIGN1cnJlbnRfZm5zOwoKICBpZiAobWV0aG9kID09IGVycm9yX21hcmtfbm9kZSkKICAgIHJldHVybjsKCiAgY29tcGxldGVfcCA9IENPTVBMRVRFX1RZUEVfUCAodHlwZSk7CiAgdXNpbmcgPSAoREVDTF9DT05URVhUIChtZXRob2QpICE9IHR5cGUpOwogIGNvbnZfcCA9IERFQ0xfQ09OVl9GTl9QIChtZXRob2QpOwogIGlmIChjb252X3ApCiAgICB0ZW1wbGF0ZV9jb252X3AgPSAoVFJFRV9DT0RFIChtZXRob2QpID09IFRFTVBMQVRFX0RFQ0wKCQkgICAgICAgJiYgREVDTF9URU1QTEFURV9DT05WX0ZOX1AgKG1ldGhvZCkpOwoKICBtZXRob2RfdmVjID0gQ0xBU1NUWVBFX01FVEhPRF9WRUMgKHR5cGUpOwogIGlmICghbWV0aG9kX3ZlYykKICAgIHsKICAgICAgLyogTWFrZSBhIG5ldyBtZXRob2QgdmVjdG9yLiAgV2Ugc3RhcnQgd2l0aCA4IGVudHJpZXMuICBXZSBtdXN0CgkgYWxsb2NhdGUgYXQgbGVhc3QgdHdvIChmb3IgY29uc3RydWN0b3JzIGFuZCBkZXN0cnVjdG9ycyksIGFuZAoJIHdlJ3JlIGdvaW5nIHRvIGVuZCB1cCB3aXRoIGFuIGFzc2lnbm1lbnQgb3BlcmF0b3IgYXQgc29tZQoJIHBvaW50IGFzIHdlbGwuICAqLwogICAgICBtZXRob2RfdmVjID0gVkVDX2FsbG9jICh0cmVlLCA4KTsKICAgICAgLyogQ3JlYXRlIHNsb3RzIGZvciBjb25zdHJ1Y3RvcnMgYW5kIGRlc3RydWN0b3JzLiAgKi8KICAgICAgVkVDX3F1aWNrX3B1c2ggKHRyZWUsIG1ldGhvZF92ZWMsIE5VTExfVFJFRSk7CiAgICAgIFZFQ19xdWlja19wdXNoICh0cmVlLCBtZXRob2RfdmVjLCBOVUxMX1RSRUUpOwogICAgICBDTEFTU1RZUEVfTUVUSE9EX1ZFQyAodHlwZSkgPSBtZXRob2RfdmVjOwogICAgfQoKICAvKiBDb25zdHJ1Y3RvcnMgYW5kIGRlc3RydWN0b3JzIGdvIGluIHNwZWNpYWwgc2xvdHMuICAqLwogIGlmIChERUNMX01BWUJFX0lOX0NIQVJHRV9DT05TVFJVQ1RPUl9QIChtZXRob2QpKQogICAgc2xvdCA9IENMQVNTVFlQRV9DT05TVFJVQ1RPUl9TTE9UOwogIGVsc2UgaWYgKERFQ0xfTUFZQkVfSU5fQ0hBUkdFX0RFU1RSVUNUT1JfUCAobWV0aG9kKSkKICAgIHsKICAgICAgc2xvdCA9IENMQVNTVFlQRV9ERVNUUlVDVE9SX1NMT1Q7CiAgICAgIAogICAgICBpZiAoVFlQRV9GT1JfSkFWQSAodHlwZSkpCgl7CgkgIGlmICghREVDTF9BUlRJRklDSUFMIChtZXRob2QpKQoJICAgIGVycm9yICgiSmF2YSBjbGFzcyAlcVQgY2Fubm90IGhhdmUgYSBkZXN0cnVjdG9yIiwgdHlwZSk7CgkgIGVsc2UgaWYgKFRZUEVfSEFTX05PTlRSSVZJQUxfREVTVFJVQ1RPUiAodHlwZSkpCgkgICAgZXJyb3IgKCJKYXZhIGNsYXNzICVxVCBjYW5ub3QgaGF2ZSBhbiBpbXBsaWNpdCBub24tdHJpdmlhbCAiCgkJICAgImRlc3RydWN0b3IiLAoJCSAgIHR5cGUpOwoJfQogICAgfQogIGVsc2UKICAgIHsKICAgICAgdHJlZSBtOwoKICAgICAgaW5zZXJ0X3AgPSB0cnVlOwogICAgICAvKiBTZWUgaWYgd2UgYWxyZWFkeSBoYXZlIGFuIGVudHJ5IHdpdGggdGhpcyBuYW1lLiAgKi8KICAgICAgZm9yIChzbG90ID0gQ0xBU1NUWVBFX0ZJUlNUX0NPTlZFUlNJT05fU0xPVDsgCgkgICBWRUNfaXRlcmF0ZSAodHJlZSwgbWV0aG9kX3ZlYywgc2xvdCwgbSk7CgkgICArK3Nsb3QpCgl7CgkgIG0gPSBPVkxfQ1VSUkVOVCAobSk7CgkgIGlmICh0ZW1wbGF0ZV9jb252X3ApCgkgICAgewoJICAgICAgaWYgKFRSRUVfQ09ERSAobSkgPT0gVEVNUExBVEVfREVDTAoJCSAgJiYgREVDTF9URU1QTEFURV9DT05WX0ZOX1AgKG0pKQoJCWluc2VydF9wID0gZmFsc2U7CgkgICAgICBicmVhazsKCSAgICB9CgkgIGlmIChjb252X3AgJiYgIURFQ0xfQ09OVl9GTl9QIChtKSkKCSAgICBicmVhazsKCSAgaWYgKERFQ0xfTkFNRSAobSkgPT0gREVDTF9OQU1FIChtZXRob2QpKQoJICAgIHsKCSAgICAgIGluc2VydF9wID0gZmFsc2U7CgkgICAgICBicmVhazsKCSAgICB9CgkgIGlmIChjb21wbGV0ZV9wCgkgICAgICAmJiAhREVDTF9DT05WX0ZOX1AgKG0pCgkgICAgICAmJiBERUNMX05BTUUgKG0pID4gREVDTF9OQU1FIChtZXRob2QpKQoJICAgIGJyZWFrOwoJfQogICAgfQogIGN1cnJlbnRfZm5zID0gaW5zZXJ0X3AgPyBOVUxMX1RSRUUgOiBWRUNfaW5kZXggKHRyZWUsIG1ldGhvZF92ZWMsIHNsb3QpOwogIAogIGlmIChwcm9jZXNzaW5nX3RlbXBsYXRlX2RlY2wpCiAgICAvKiBUWVBFIGlzIGEgdGVtcGxhdGUgY2xhc3MuICBEb24ndCBpc3N1ZSBhbnkgZXJyb3JzIG5vdzsgd2FpdAogICAgICAgdW50aWwgaW5zdGFudGlhdGlvbiB0aW1lIHRvIGNvbXBsYWluLiAgKi8KICAgIDsKICBlbHNlCiAgICB7CiAgICAgIHRyZWUgZm5zOwoKICAgICAgLyogQ2hlY2sgdG8gc2VlIGlmIHdlJ3ZlIGFscmVhZHkgZ290IHRoaXMgbWV0aG9kLiAgKi8KICAgICAgZm9yIChmbnMgPSBjdXJyZW50X2ZuczsgZm5zOyBmbnMgPSBPVkxfTkVYVCAoZm5zKSkKCXsKCSAgdHJlZSBmbiA9IE9WTF9DVVJSRU5UIChmbnMpOwoJICAvKiBBUFBMRSBMT0NBTCBiZWdpbiBtYWlubGluZSAyMDA1LTEyLTE5IDQ0MDc5OTUgKi8KCSAgdHJlZSBmbl90eXBlOwoJICB0cmVlIG1ldGhvZF90eXBlOwoJICB0cmVlIHBhcm1zMTsKCSAgdHJlZSBwYXJtczI7CgoJICBpZiAoVFJFRV9DT0RFIChmbikgIT0gVFJFRV9DT0RFIChtZXRob2QpKQoJICAgIGNvbnRpbnVlOwoKCSAgLyogW292ZXIubG9hZF0gTWVtYmVyIGZ1bmN0aW9uIGRlY2xhcmF0aW9ucyB3aXRoIHRoZQoJICAgICBzYW1lIG5hbWUgYW5kIHRoZSBzYW1lIHBhcmFtZXRlciB0eXBlcyBjYW5ub3QgYmUKCSAgICAgb3ZlcmxvYWRlZCBpZiBhbnkgb2YgdGhlbSBpcyBhIHN0YXRpYyBtZW1iZXIKCSAgICAgZnVuY3Rpb24gZGVjbGFyYXRpb24uCgoJICAgICBbbmFtZXNwYWNlLnVkZWNsXSBXaGVuIGEgdXNpbmctZGVjbGFyYXRpb24gYnJpbmdzIG5hbWVzCgkgICAgIGZyb20gYSBiYXNlIGNsYXNzIGludG8gYSBkZXJpdmVkIGNsYXNzIHNjb3BlLCBtZW1iZXIKCSAgICAgZnVuY3Rpb25zIGluIHRoZSBkZXJpdmVkIGNsYXNzIG92ZXJyaWRlIGFuZC9vciBoaWRlIG1lbWJlcgoJICAgICBmdW5jdGlvbnMgd2l0aCB0aGUgc2FtZSBuYW1lIGFuZCBwYXJhbWV0ZXIgdHlwZXMgaW4gYSBiYXNlCgkgICAgIGNsYXNzIChyYXRoZXIgdGhhbiBjb25mbGljdGluZykuICAqLwoJICBmbl90eXBlID0gVFJFRV9UWVBFIChmbik7CgkgIG1ldGhvZF90eXBlID0gVFJFRV9UWVBFIChtZXRob2QpOwoJICBwYXJtczEgPSBUWVBFX0FSR19UWVBFUyAoZm5fdHlwZSk7CgkgIHBhcm1zMiA9IFRZUEVfQVJHX1RZUEVTIChtZXRob2RfdHlwZSk7CgoJICAvKiBDb21wYXJlIHRoZSBxdWFscyBvbiB0aGUgJ3RoaXMnIHBhcm0uICBEb24ndCBjb21wYXJlCgkgICAgIHRoZSB3aG9sZSB0eXBlcywgYXMgdXNlZCBmdW5jdGlvbnMgYXJlIHRyZWF0ZWQgYXMKCSAgICAgY29taW5nIGZyb20gdGhlIHVzaW5nIGNsYXNzIGluIG92ZXJsb2FkIHJlc29sdXRpb24uICAqLwoJICBpZiAoISBERUNMX1NUQVRJQ19GVU5DVElPTl9QIChmbikKCSAgICAgICYmICEgREVDTF9TVEFUSUNfRlVOQ1RJT05fUCAobWV0aG9kKQoJICAgICAgJiYgKFRZUEVfUVVBTFMgKFRSRUVfVFlQRSAoVFJFRV9WQUxVRSAocGFybXMxKSkpCgkJICAhPSBUWVBFX1FVQUxTIChUUkVFX1RZUEUgKFRSRUVfVkFMVUUgKHBhcm1zMikpKSkpCgkgICAgY29udGludWU7CgkgIAoJICAvKiBGb3IgdGVtcGxhdGVzLCB0aGUgdGVtcGxhdGUgcGFybXMgbXVzdCBiZSBpZGVudGljYWwuICAqLwoJICBpZiAoVFJFRV9DT0RFIChmbikgPT0gVEVNUExBVEVfREVDTAoJICAgICAgJiYgKCFzYW1lX3R5cGVfcCAoVFJFRV9UWVBFIChmbl90eXBlKSwKCQkJCVRSRUVfVFlQRSAobWV0aG9kX3R5cGUpKQogICAgICAgICAgICAgICAgICB8fCAhY29tcF90ZW1wbGF0ZV9wYXJtcyAoREVDTF9URU1QTEFURV9QQVJNUyAoZm4pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgREVDTF9URU1QTEFURV9QQVJNUyAobWV0aG9kKSkpKQogICAgICAgICAgIGNvbnRpbnVlOwoJICAKCSAgaWYgKCEgREVDTF9TVEFUSUNfRlVOQ1RJT05fUCAoZm4pKQoJICAgIHBhcm1zMSA9IFRSRUVfQ0hBSU4gKHBhcm1zMSk7CgkgIGlmICghIERFQ0xfU1RBVElDX0ZVTkNUSU9OX1AgKG1ldGhvZCkpCgkgICAgcGFybXMyID0gVFJFRV9DSEFJTiAocGFybXMyKTsKCgkgIGlmIChjb21wcGFybXMgKHBhcm1zMSwgcGFybXMyKQoJICAgICAgJiYgKCFERUNMX0NPTlZfRk5fUCAoZm4pIAoJCSAgfHwgc2FtZV90eXBlX3AgKFRSRUVfVFlQRSAoZm5fdHlwZSksCgkJCQkgIFRSRUVfVFlQRSAobWV0aG9kX3R5cGUpKSkpCgkgIC8qIEFQUExFIExPQ0FMIGVuZCBtYWlubGluZSAyMDA1LTEyLTE5IDQ0MDc5OTUgKi8KCSAgICB7CgkgICAgICBpZiAodXNpbmcgJiYgREVDTF9DT05URVhUIChmbikgPT0gdHlwZSkKCQkvKiBEZWZlciB0byB0aGUgbG9jYWwgZnVuY3Rpb24uICAqLwoJCXJldHVybjsKCSAgICAgIGVsc2UKCQl7CgkJICBjcF9lcnJvcl9hdCAoIiVxI0QgYW5kICVxI0QgY2Fubm90IGJlIG92ZXJsb2FkZWQiLAoJCQkgICAgICAgbWV0aG9kLCBmbik7CgoJCSAgLyogV2UgZG9uJ3QgY2FsbCBkdXBsaWNhdGVfZGVjbHMgaGVyZSB0byBtZXJnZQoJCSAgICAgdGhlIGRlY2xhcmF0aW9ucyBiZWNhdXNlIHRoYXQgd2lsbCBjb25mdXNlCgkJICAgICB0aGluZ3MgaWYgdGhlIG1ldGhvZHMgaGF2ZSBpbmxpbmUKCQkgICAgIGRlZmluaXRpb25zLiAgSW4gcGFydGljdWxhciwgd2Ugd2lsbCBjcmFzaAoJCSAgICAgd2hpbGUgcHJvY2Vzc2luZyB0aGUgZGVmaW5pdGlvbnMuICAqLwoJCSAgcmV0dXJuOwoJCX0KCSAgICB9Cgl9CiAgICB9CgogIC8qIEFkZCB0aGUgbmV3IGJpbmRpbmcuICAqLyAKICBvdmVybG9hZCA9IGJ1aWxkX292ZXJsb2FkIChtZXRob2QsIGN1cnJlbnRfZm5zKTsKICAKICBpZiAoIWNvbnZfcCAmJiBzbG90ID49IENMQVNTVFlQRV9GSVJTVF9DT05WRVJTSU9OX1NMT1QgJiYgIWNvbXBsZXRlX3ApCiAgICBwdXNoX2NsYXNzX2xldmVsX2JpbmRpbmcgKERFQ0xfTkFNRSAobWV0aG9kKSwgb3ZlcmxvYWQpOwoKICBpZiAoaW5zZXJ0X3ApCiAgICB7CiAgICAgIC8qIFdlIG9ubHkgZXhwZWN0IHRvIGFkZCBmZXcgbWV0aG9kcyBpbiB0aGUgQ09NUExFVEVfUCBjYXNlLCBzbwoJIGp1c3QgbWFrZSByb29tIGZvciBvbmUgbW9yZSBtZXRob2QgaW4gdGhhdCBjYXNlLiAgKi8KICAgICAgaWYgKFZFQ19yZXNlcnZlICh0cmVlLCBtZXRob2RfdmVjLCBjb21wbGV0ZV9wID8gMSA6IC0xKSkKCUNMQVNTVFlQRV9NRVRIT0RfVkVDICh0eXBlKSA9IG1ldGhvZF92ZWM7CiAgICAgIGlmIChzbG90ID09IFZFQ19sZW5ndGggKHRyZWUsIG1ldGhvZF92ZWMpKQoJVkVDX3F1aWNrX3B1c2ggKHRyZWUsIG1ldGhvZF92ZWMsIG92ZXJsb2FkKTsKICAgICAgZWxzZQoJVkVDX3F1aWNrX2luc2VydCAodHJlZSwgbWV0aG9kX3ZlYywgc2xvdCwgb3ZlcmxvYWQpOwogICAgfQogIGVsc2UKICAgIC8qIFJlcGxhY2UgdGhlIGN1cnJlbnQgc2xvdC4gICovCiAgICBWRUNfcmVwbGFjZSAodHJlZSwgbWV0aG9kX3ZlYywgc2xvdCwgb3ZlcmxvYWQpOwp9CgovKiBTdWJyb3V0aW5lcyBvZiBmaW5pc2hfc3RydWN0LiAgKi8KCi8qIENoYW5nZSB0aGUgYWNjZXNzIG9mIEZERUNMIHRvIEFDQ0VTUyBpbiBULiAgUmV0dXJuIDEgaWYgY2hhbmdlIHdhcwogICBsZWdpdCwgb3RoZXJ3aXNlIHJldHVybiAwLiAgKi8KCnN0YXRpYyBpbnQKYWx0ZXJfYWNjZXNzICh0cmVlIHQsIHRyZWUgZmRlY2wsIHRyZWUgYWNjZXNzKQp7CiAgdHJlZSBlbGVtOwoKICBpZiAoIURFQ0xfTEFOR19TUEVDSUZJQyAoZmRlY2wpKQogICAgcmV0cm9maXRfbGFuZ19kZWNsIChmZGVjbCk7CgogIGdjY19hc3NlcnQgKCFERUNMX0RJU0NSSU1JTkFUT1JfUCAoZmRlY2wpKTsKCiAgZWxlbSA9IHB1cnBvc2VfbWVtYmVyICh0LCBERUNMX0FDQ0VTUyAoZmRlY2wpKTsKICBpZiAoZWxlbSkKICAgIHsKICAgICAgaWYgKFRSRUVfVkFMVUUgKGVsZW0pICE9IGFjY2VzcykKCXsKCSAgaWYgKFRSRUVfQ09ERSAoVFJFRV9UWVBFIChmZGVjbCkpID09IEZVTkNUSU9OX0RFQ0wpCgkgICAgY3BfZXJyb3JfYXQgKCJjb25mbGljdGluZyBhY2Nlc3Mgc3BlY2lmaWNhdGlvbnMgZm9yIG1ldGhvZCIKICAgICAgICAgICAgICAgICAgICAgICAgICIgJXFELCBpZ25vcmVkIiwgVFJFRV9UWVBFIChmZGVjbCkpOwoJICBlbHNlCgkgICAgZXJyb3IgKCJjb25mbGljdGluZyBhY2Nlc3Mgc3BlY2lmaWNhdGlvbnMgZm9yIGZpZWxkICVxRSwgaWdub3JlZCIsCgkJICAgREVDTF9OQU1FIChmZGVjbCkpOwoJfQogICAgICBlbHNlCgl7CgkgIC8qIFRoZXkncmUgY2hhbmdpbmcgdGhlIGFjY2VzcyB0byB0aGUgc2FtZSB0aGluZyB0aGV5IGNoYW5nZWQKCSAgICAgaXQgdG8gYmVmb3JlLiAgVGhhdCdzIE9LLiAgKi8KCSAgOwoJfQogICAgfQogIGVsc2UKICAgIHsKICAgICAgcGVyZm9ybV9vcl9kZWZlcl9hY2Nlc3NfY2hlY2sgKFRZUEVfQklORk8gKHQpLCBmZGVjbCk7CiAgICAgIERFQ0xfQUNDRVNTIChmZGVjbCkgPSB0cmVlX2NvbnMgKHQsIGFjY2VzcywgREVDTF9BQ0NFU1MgKGZkZWNsKSk7CiAgICAgIHJldHVybiAxOwogICAgfQogIHJldHVybiAwOwp9CgovKiBQcm9jZXNzIHRoZSBVU0lOR19ERUNMLCB3aGljaCBpcyBhIG1lbWJlciBvZiBULiAgKi8KCnN0YXRpYyB2b2lkCmhhbmRsZV91c2luZ19kZWNsICh0cmVlIHVzaW5nX2RlY2wsIHRyZWUgdCkKewogIHRyZWUgY3R5cGUgPSBERUNMX0lOSVRJQUwgKHVzaW5nX2RlY2wpOwogIHRyZWUgbmFtZSA9IERFQ0xfTkFNRSAodXNpbmdfZGVjbCk7CiAgdHJlZSBhY2Nlc3MKICAgID0gVFJFRV9QUklWQVRFICh1c2luZ19kZWNsKSA/IGFjY2Vzc19wcml2YXRlX25vZGUKICAgIDogVFJFRV9QUk9URUNURUQgKHVzaW5nX2RlY2wpID8gYWNjZXNzX3Byb3RlY3RlZF9ub2RlCiAgICA6IGFjY2Vzc19wdWJsaWNfbm9kZTsKICB0cmVlIGZkZWNsLCBiaW5mbzsKICB0cmVlIGZsaXN0ID0gTlVMTF9UUkVFOwogIHRyZWUgb2xkX3ZhbHVlOwoKICBpZiAoY3R5cGUgPT0gZXJyb3JfbWFya19ub2RlKQogICAgcmV0dXJuOwoKICBiaW5mbyA9IGxvb2t1cF9iYXNlICh0LCBjdHlwZSwgYmFfYW55LCBOVUxMKTsKICBpZiAoISBiaW5mbykKICAgIHsKICAgICAgbG9jYXRpb25fdCBzYXZlZF9sb2MgPSBpbnB1dF9sb2NhdGlvbjsKCiAgICAgIGlucHV0X2xvY2F0aW9uID0gREVDTF9TT1VSQ0VfTE9DQVRJT04gKHVzaW5nX2RlY2wpOwogICAgICBlcnJvcl9ub3RfYmFzZV90eXBlIChjdHlwZSwgdCk7CiAgICAgIGlucHV0X2xvY2F0aW9uID0gc2F2ZWRfbG9jOwogICAgICByZXR1cm47CiAgICB9CiAgCiAgaWYgKGNvbnN0cnVjdG9yX25hbWVfcCAobmFtZSwgY3R5cGUpKQogICAgewogICAgICBjcF9lcnJvcl9hdCAoIiVxRCBuYW1lcyBjb25zdHJ1Y3RvciIsIHVzaW5nX2RlY2wpOwogICAgICByZXR1cm47CiAgICB9CiAgaWYgKGNvbnN0cnVjdG9yX25hbWVfcCAobmFtZSwgdCkpCiAgICB7CiAgICAgIGNwX2Vycm9yX2F0ICgiJXFEIGludmFsaWQgaW4gJXFUIiwgdXNpbmdfZGVjbCwgdCk7CiAgICAgIHJldHVybjsKICAgIH0KCiAgZmRlY2wgPSBsb29rdXBfbWVtYmVyIChiaW5mbywgbmFtZSwgMCwgZmFsc2UpOwogIAogIGlmICghZmRlY2wpCiAgICB7CiAgICAgIGNwX2Vycm9yX2F0ICgibm8gbWVtYmVycyBtYXRjaGluZyAlcUQgaW4gJXEjVCIsIHVzaW5nX2RlY2wsIGN0eXBlKTsKICAgICAgcmV0dXJuOwogICAgfQoKICBpZiAoQkFTRUxJTktfUCAoZmRlY2wpKQogICAgLyogSWdub3JlIGJhc2UgdHlwZSB0aGlzIGNhbWUgZnJvbS4gICovCiAgICBmZGVjbCA9IEJBU0VMSU5LX0ZVTkNUSU9OUyAoZmRlY2wpOwoKICBvbGRfdmFsdWUgPSBsb29rdXBfbWVtYmVyICh0LCBuYW1lLCAvKnByb3RlY3Q9Ki8wLCAvKndhbnRfdHlwZT0qL2ZhbHNlKTsKICBpZiAob2xkX3ZhbHVlKQogICAgewogICAgICBpZiAoaXNfb3ZlcmxvYWRlZF9mbiAob2xkX3ZhbHVlKSkKCW9sZF92YWx1ZSA9IE9WTF9DVVJSRU5UIChvbGRfdmFsdWUpOwoKICAgICAgaWYgKERFQ0xfUCAob2xkX3ZhbHVlKSAmJiBERUNMX0NPTlRFWFQgKG9sZF92YWx1ZSkgPT0gdCkKCS8qIE9LICovOwogICAgICBlbHNlCglvbGRfdmFsdWUgPSBOVUxMX1RSRUU7CiAgICB9CgogIGlmIChpc19vdmVybG9hZGVkX2ZuIChmZGVjbCkpCiAgICBmbGlzdCA9IGZkZWNsOwoKICBpZiAoISBvbGRfdmFsdWUpCiAgICA7CiAgZWxzZSBpZiAoaXNfb3ZlcmxvYWRlZF9mbiAob2xkX3ZhbHVlKSkKICAgIHsKICAgICAgaWYgKGZsaXN0KQoJLyogSXQncyBPSyB0byB1c2UgZnVuY3Rpb25zIGZyb20gYSBiYXNlIHdoZW4gdGhlcmUgYXJlIGZ1bmN0aW9ucyB3aXRoCgkgICB0aGUgc2FtZSBuYW1lIGFscmVhZHkgcHJlc2VudCBpbiB0aGUgY3VycmVudCBjbGFzcy4gICovOwogICAgICBlbHNlCgl7CgkgIGNwX2Vycm9yX2F0ICgiJXFEIGludmFsaWQgaW4gJXEjVCIsIHVzaW5nX2RlY2wsIHQpOwoJICBjcF9lcnJvcl9hdCAoIiAgYmVjYXVzZSBvZiBsb2NhbCBtZXRob2QgJXEjRCB3aXRoIHNhbWUgbmFtZSIsCgkJICAgICAgIE9WTF9DVVJSRU5UIChvbGRfdmFsdWUpKTsKCSAgcmV0dXJuOwoJfQogICAgfQogIGVsc2UgaWYgKCFERUNMX0FSVElGSUNJQUwgKG9sZF92YWx1ZSkpCiAgICB7CiAgICAgIGNwX2Vycm9yX2F0ICgiJXFEIGludmFsaWQgaW4gJXEjVCIsIHVzaW5nX2RlY2wsIHQpOwogICAgICBjcF9lcnJvcl9hdCAoIiAgYmVjYXVzZSBvZiBsb2NhbCBtZW1iZXIgJXEjRCB3aXRoIHNhbWUgbmFtZSIsIG9sZF92YWx1ZSk7CiAgICAgIHJldHVybjsKICAgIH0KICAKICAvKiBNYWtlIHR5cGUgVCBzZWUgZmllbGQgZGVjbCBGREVDTCB3aXRoIGFjY2VzcyBBQ0NFU1MuICAqLwogIGlmIChmbGlzdCkKICAgIGZvciAoOyBmbGlzdDsgZmxpc3QgPSBPVkxfTkVYVCAoZmxpc3QpKQogICAgICB7CglhZGRfbWV0aG9kICh0LCBPVkxfQ1VSUkVOVCAoZmxpc3QpKTsKCWFsdGVyX2FjY2VzcyAodCwgT1ZMX0NVUlJFTlQgKGZsaXN0KSwgYWNjZXNzKTsKICAgICAgfQogIGVsc2UKICAgIGFsdGVyX2FjY2VzcyAodCwgZmRlY2wsIGFjY2Vzcyk7Cn0KDAovKiBSdW4gdGhyb3VnaCB0aGUgYmFzZSBjbGFzc2VzIG9mIFQsIHVwZGF0aW5nIENBTlRfSEFWRV9DT05TVF9DVE9SX1AsCiAgIGFuZCBOT19DT05TVF9BU05fUkVGX1AuICBBbHNvIHNldCBmbGFnIGJpdHMgaW4gVCBiYXNlZCBvbgogICBwcm9wZXJ0aWVzIG9mIHRoZSBiYXNlcy4gICovCgpzdGF0aWMgdm9pZApjaGVja19iYXNlcyAodHJlZSB0LAogICAgICAgICAgICAgaW50KiBjYW50X2hhdmVfY29uc3RfY3Rvcl9wLAogICAgICAgICAgICAgaW50KiBub19jb25zdF9hc25fcmVmX3ApCnsKICBpbnQgaTsKICBpbnQgc2Vlbl9ub25fdmlydHVhbF9uZWFybHlfZW1wdHlfYmFzZV9wOwogIHRyZWUgYmFzZV9iaW5mbzsKICB0cmVlIGJpbmZvOwoKICBzZWVuX25vbl92aXJ0dWFsX25lYXJseV9lbXB0eV9iYXNlX3AgPSAwOwoKICBmb3IgKGJpbmZvID0gVFlQRV9CSU5GTyAodCksIGkgPSAwOwogICAgICAgQklORk9fQkFTRV9JVEVSQVRFIChiaW5mbywgaSwgYmFzZV9iaW5mbyk7IGkrKykKICAgIHsKICAgICAgdHJlZSBiYXNldHlwZSA9IFRSRUVfVFlQRSAoYmFzZV9iaW5mbyk7CgogICAgICBnY2NfYXNzZXJ0IChDT01QTEVURV9UWVBFX1AgKGJhc2V0eXBlKSk7CiAgICAgIAogICAgICAvKiBFZmZlY3RpdmUgQysrIHJ1bGUgMTQuICBXZSBvbmx5IG5lZWQgdG8gY2hlY2sgVFlQRV9QT0xZTU9SUEhJQ19QCgkgaGVyZSBiZWNhdXNlIHRoZSBjYXNlIG9mIHZpcnR1YWwgZnVuY3Rpb25zIGJ1dCBub24tdmlydHVhbAoJIGR0b3IgaXMgaGFuZGxlZCBpbiBmaW5pc2hfc3RydWN0XzEuICAqLwogICAgICBpZiAod2Fybl9lY3BwICYmICEgVFlQRV9QT0xZTU9SUEhJQ19QIChiYXNldHlwZSkpCgl3YXJuaW5nICgiYmFzZSBjbGFzcyAlcSNUIGhhcyBhIG5vbi12aXJ0dWFsIGRlc3RydWN0b3IiLCBiYXNldHlwZSk7CgogICAgICAvKiBJZiB0aGUgYmFzZSBjbGFzcyBkb2Vzbid0IGhhdmUgY29weSBjb25zdHJ1Y3RvcnMgb3IKCSBhc3NpZ25tZW50IG9wZXJhdG9ycyB0aGF0IHRha2UgY29uc3QgcmVmZXJlbmNlcywgdGhlbiB0aGUKCSBkZXJpdmVkIGNsYXNzIGNhbm5vdCBoYXZlIHN1Y2ggYSBtZW1iZXIgYXV0b21hdGljYWxseQoJIGdlbmVyYXRlZC4gICovCiAgICAgIGlmICghIFRZUEVfSEFTX0NPTlNUX0lOSVRfUkVGIChiYXNldHlwZSkpCgkqY2FudF9oYXZlX2NvbnN0X2N0b3JfcCA9IDE7CiAgICAgIGlmIChUWVBFX0hBU19BU1NJR05fUkVGIChiYXNldHlwZSkKCSAgJiYgIVRZUEVfSEFTX0NPTlNUX0FTU0lHTl9SRUYgKGJhc2V0eXBlKSkKCSpub19jb25zdF9hc25fcmVmX3AgPSAxOwoKICAgICAgaWYgKEJJTkZPX1ZJUlRVQUxfUCAoYmFzZV9iaW5mbykpCgkvKiBBIHZpcnR1YWwgYmFzZSBkb2VzIG5vdCBlZmZlY3QgbmVhcmx5IGVtcHRpbmVzcy4gICovCgk7CiAgICAgIGVsc2UgaWYgKENMQVNTVFlQRV9ORUFSTFlfRU1QVFlfUCAoYmFzZXR5cGUpKQoJewoJICBpZiAoc2Vlbl9ub25fdmlydHVhbF9uZWFybHlfZW1wdHlfYmFzZV9wKQoJICAgIC8qIEFuZCBpZiB0aGVyZSBpcyBtb3JlIHRoYW4gb25lIG5lYXJseSBlbXB0eSBiYXNlLCB0aGVuIHRoZQoJICAgICAgIGRlcml2ZWQgY2xhc3MgaXMgbm90IG5lYXJseSBlbXB0eSBlaXRoZXIuICAqLwoJICAgIENMQVNTVFlQRV9ORUFSTFlfRU1QVFlfUCAodCkgPSAwOwoJICBlbHNlCgkgICAgLyogUmVtZW1iZXIgd2UndmUgc2VlbiBvbmUuICAqLwoJICAgIHNlZW5fbm9uX3ZpcnR1YWxfbmVhcmx5X2VtcHR5X2Jhc2VfcCA9IDE7Cgl9CiAgICAgIGVsc2UgaWYgKCFpc19lbXB0eV9jbGFzcyAoYmFzZXR5cGUpKQoJLyogSWYgdGhlIGJhc2UgY2xhc3MgaXMgbm90IGVtcHR5IG9yIG5lYXJseSBlbXB0eSwgdGhlbiB0aGlzCgkgICBjbGFzcyBjYW5ub3QgYmUgbmVhcmx5IGVtcHR5LiAgKi8KCUNMQVNTVFlQRV9ORUFSTFlfRU1QVFlfUCAodCkgPSAwOwoKICAgICAgLyogQSBsb3Qgb2YgcHJvcGVydGllcyBmcm9tIHRoZSBiYXNlcyBhbHNvIGFwcGx5IHRvIHRoZSBkZXJpdmVkCgkgY2xhc3MuICAqLwogICAgICBUWVBFX05FRURTX0NPTlNUUlVDVElORyAodCkgfD0gVFlQRV9ORUVEU19DT05TVFJVQ1RJTkcgKGJhc2V0eXBlKTsKICAgICAgVFlQRV9IQVNfTk9OVFJJVklBTF9ERVNUUlVDVE9SICh0KSAKCXw9IFRZUEVfSEFTX05PTlRSSVZJQUxfREVTVFJVQ1RPUiAoYmFzZXR5cGUpOwogICAgICBUWVBFX0hBU19DT01QTEVYX0FTU0lHTl9SRUYgKHQpIAoJfD0gVFlQRV9IQVNfQ09NUExFWF9BU1NJR05fUkVGIChiYXNldHlwZSk7CiAgICAgIFRZUEVfSEFTX0NPTVBMRVhfSU5JVF9SRUYgKHQpIHw9IFRZUEVfSEFTX0NPTVBMRVhfSU5JVF9SRUYgKGJhc2V0eXBlKTsKICAgICAgVFlQRV9QT0xZTU9SUEhJQ19QICh0KSB8PSBUWVBFX1BPTFlNT1JQSElDX1AgKGJhc2V0eXBlKTsKICAgICAgQ0xBU1NUWVBFX0NPTlRBSU5TX0VNUFRZX0NMQVNTX1AgKHQpIAoJfD0gQ0xBU1NUWVBFX0NPTlRBSU5TX0VNUFRZX0NMQVNTX1AgKGJhc2V0eXBlKTsKICAgIH0KfQoKLyogRGV0ZXJtaW5lIGFsbCB0aGUgcHJpbWFyeSBiYXNlcyB3aXRoaW4gVC4gIFNldHMgQklORk9fUFJJTUFSWV9CQVNFX1AgZm9yCiAgIHRob3NlIHRoYXQgYXJlIHByaW1hcmllcy4gIFNldHMgQklORk9fTE9TVF9QUklNQVJZX1AgZm9yIHRob3NlCiAgIHRoYXQgaGF2ZSBoYWQgYSBuZWFybHktZW1wdHkgdmlydHVhbCBwcmltYXJ5IGJhc2Ugc3RvbGVuIGJ5IHNvbWUKICAgb3RoZXIgYmFzZSBpbiB0aGUgaGllcmFyY2h5LiAgRGV0ZXJtaW5lcyBDTEFTU1RZUEVfUFJJTUFSWV9CQVNFIGZvcgogICBULiAgKi8KCnN0YXRpYyB2b2lkCmRldGVybWluZV9wcmltYXJ5X2Jhc2VzICh0cmVlIHQpCnsKICB1bnNpZ25lZCBpOwogIHRyZWUgcHJpbWFyeSA9IE5VTExfVFJFRTsKICB0cmVlIHR5cGVfYmluZm8gPSBUWVBFX0JJTkZPICh0KTsKICB0cmVlIGJhc2VfYmluZm87CgogIC8qIERldGVybWluZSB0aGUgcHJpbWFyeSBiYXNlcyBvZiBvdXIgYmFzZXMuICAqLwogIGZvciAoYmFzZV9iaW5mbyA9IFRSRUVfQ0hBSU4gKHR5cGVfYmluZm8pOyBiYXNlX2JpbmZvOwogICAgICAgYmFzZV9iaW5mbyA9IFRSRUVfQ0hBSU4gKGJhc2VfYmluZm8pKQogICAgewogICAgICB0cmVlIHByaW1hcnkgPSBDTEFTU1RZUEVfUFJJTUFSWV9CSU5GTyAoQklORk9fVFlQRSAoYmFzZV9iaW5mbykpOwoKICAgICAgLyogU2VlIGlmIHdlJ3JlIHRoZSBub24tdmlydHVhbCBwcmltYXJ5IG9mIG91ciBpbmhlcml0YW5jZQoJIGNoYWluLiAgKi8KICAgICAgaWYgKCFCSU5GT19WSVJUVUFMX1AgKGJhc2VfYmluZm8pKQoJewoJICB0cmVlIHBhcmVudCA9IEJJTkZPX0lOSEVSSVRBTkNFX0NIQUlOIChiYXNlX2JpbmZvKTsKCSAgdHJlZSBwYXJlbnRfcHJpbWFyeSA9IENMQVNTVFlQRV9QUklNQVJZX0JJTkZPIChCSU5GT19UWVBFIChwYXJlbnQpKTsKCSAgCgkgIGlmIChwYXJlbnRfcHJpbWFyeQoJICAgICAgJiYgU0FNRV9CSU5GT19UWVBFX1AgKEJJTkZPX1RZUEUgKGJhc2VfYmluZm8pLAoJCQkJICAgIEJJTkZPX1RZUEUgKHBhcmVudF9wcmltYXJ5KSkpCgkgICAgLyogV2UgYXJlIHRoZSBwcmltYXJ5IGJpbmZvLiAgKi8KCSAgICBCSU5GT19QUklNQVJZX1AgKGJhc2VfYmluZm8pID0gMTsKCX0KICAgICAgLyogRGV0ZXJtaW5lIGlmIHdlIGhhdmUgYSB2aXJ0dWFsIHByaW1hcnkgYmFzZSwgYW5kIG1hcmsgaXQgc28uCiAgICAgICAqLwogICAgICBpZiAocHJpbWFyeSAmJiBCSU5GT19WSVJUVUFMX1AgKHByaW1hcnkpKQoJewoJICB0cmVlIHRoaXNfcHJpbWFyeSA9IGNvcGllZF9iaW5mbyAocHJpbWFyeSwgYmFzZV9iaW5mbyk7CgoJICBpZiAoQklORk9fUFJJTUFSWV9QICh0aGlzX3ByaW1hcnkpKQoJICAgIC8qIFNvbWVvbmUgYWxyZWFkeSBjbGFpbWVkIHRoaXMgYmFzZS4gICovCgkgICAgQklORk9fTE9TVF9QUklNQVJZX1AgKGJhc2VfYmluZm8pID0gMTsKCSAgZWxzZQoJICAgIHsKCSAgICAgIHRyZWUgZGVsdGE7CgkgICAgICAKCSAgICAgIEJJTkZPX1BSSU1BUllfUCAodGhpc19wcmltYXJ5KSA9IDE7CgkgICAgICBCSU5GT19JTkhFUklUQU5DRV9DSEFJTiAodGhpc19wcmltYXJ5KSA9IGJhc2VfYmluZm87CgkgICAgICAKCSAgICAgIC8qIEEgdmlydHVhbCBiaW5mbyBtaWdodCBoYXZlIGJlZW4gY29waWVkIGZyb20gd2l0aGluCiAgCSAgICAgICAgIGFub3RoZXIgaGllcmFyY2h5LiBBcyB3ZSdyZSBhYm91dCB0byB1c2UgaXQgYXMgYQogIAkgICAgICAgICBwcmltYXJ5IGJhc2UsIG1ha2Ugc3VyZSB0aGUgb2Zmc2V0cyBtYXRjaC4gICovCgkgICAgICBkZWx0YSA9IHNpemVfZGlmZm9wIChjb252ZXJ0IChzc2l6ZXR5cGUsCgkJCQkJICAgIEJJTkZPX09GRlNFVCAoYmFzZV9iaW5mbykpLAoJCQkJICAgY29udmVydCAoc3NpemV0eXBlLAoJCQkJCSAgICBCSU5GT19PRkZTRVQgKHRoaXNfcHJpbWFyeSkpKTsKCSAgCgkgICAgICBwcm9wYWdhdGVfYmluZm9fb2Zmc2V0cyAodGhpc19wcmltYXJ5LCBkZWx0YSk7CgkgICAgfQoJfQogICAgfQoKICAvKiBGaXJzdCBsb29rIGZvciBhIGR5bmFtaWMgZGlyZWN0IG5vbi12aXJ0dWFsIGJhc2UuICAqLwogIGZvciAoaSA9IDA7IEJJTkZPX0JBU0VfSVRFUkFURSAodHlwZV9iaW5mbywgaSwgYmFzZV9iaW5mbyk7IGkrKykKICAgIHsKICAgICAgdHJlZSBiYXNldHlwZSA9IEJJTkZPX1RZUEUgKGJhc2VfYmluZm8pOwoKICAgICAgaWYgKFRZUEVfQ09OVEFJTlNfVlBUUl9QIChiYXNldHlwZSkgJiYgIUJJTkZPX1ZJUlRVQUxfUCAoYmFzZV9iaW5mbykpCgl7CgkgIHByaW1hcnkgPSBiYXNlX2JpbmZvOwoJICBnb3RvIGZvdW5kOwoJfQogICAgfQoKICAvKiBBICJuZWFybHktZW1wdHkiIHZpcnR1YWwgYmFzZSBjbGFzcyBjYW4gYmUgdGhlIHByaW1hcnkgYmFzZQogICAgIGNsYXNzLCBpZiBubyBub24tdmlydHVhbCBwb2x5bW9ycGhpYyBiYXNlIGNhbiBiZSBmb3VuZC4gIExvb2sgZm9yCiAgICAgYSBuZWFybHktZW1wdHkgdmlydHVhbCBkeW5hbWljIGJhc2UgdGhhdCBpcyBub3QgYWxyZWFkeSBhIHByaW1hcnkKICAgICBiYXNlIG9mIHNvbWV0aGluZyBpbiB0aGUgaGllcmFyY2h5LiAgSWYgdGhlcmUgaXMgbm8gc3VjaCBiYXNlLAogICAgIGp1c3QgcGljayB0aGUgZmlyc3QgbmVhcmx5LWVtcHR5IHZpcnR1YWwgYmFzZS4gICovCgogIGZvciAoYmFzZV9iaW5mbyA9IFRSRUVfQ0hBSU4gKHR5cGVfYmluZm8pOyBiYXNlX2JpbmZvOwogICAgICAgYmFzZV9iaW5mbyA9IFRSRUVfQ0hBSU4gKGJhc2VfYmluZm8pKQogICAgaWYgKEJJTkZPX1ZJUlRVQUxfUCAoYmFzZV9iaW5mbykKCSYmIENMQVNTVFlQRV9ORUFSTFlfRU1QVFlfUCAoQklORk9fVFlQRSAoYmFzZV9iaW5mbykpKQogICAgICB7CglpZiAoIUJJTkZPX1BSSU1BUllfUCAoYmFzZV9iaW5mbykpCgkgIHsKCSAgICAvKiBGb3VuZCBvbmUgdGhhdCBpcyBub3QgcHJpbWFyeS4gICovCgkgICAgcHJpbWFyeSA9IGJhc2VfYmluZm87CgkgICAgZ290byBmb3VuZDsKCSAgfQoJZWxzZSBpZiAoIXByaW1hcnkpCgkgIC8qIFJlbWVtYmVyIHRoZSBmaXJzdCBjYW5kaWRhdGUuICAqLwoJICBwcmltYXJ5ID0gYmFzZV9iaW5mbzsKICAgICAgfQogIAogZm91bmQ6CiAgLyogSWYgd2UndmUgZ290IGEgcHJpbWFyeSBiYXNlLCB1c2UgaXQuICAqLwogIGlmIChwcmltYXJ5KQogICAgewogICAgICB0cmVlIGJhc2V0eXBlID0gQklORk9fVFlQRSAocHJpbWFyeSk7CiAgICAgIAogICAgICBDTEFTU1RZUEVfUFJJTUFSWV9CSU5GTyAodCkgPSBwcmltYXJ5OwogICAgICBpZiAoQklORk9fUFJJTUFSWV9QIChwcmltYXJ5KSkKCS8qIFdlIGFyZSBzdGVhbGluZyBhIHByaW1hcnkgYmFzZS4gICovCglCSU5GT19MT1NUX1BSSU1BUllfUCAoQklORk9fSU5IRVJJVEFOQ0VfQ0hBSU4gKHByaW1hcnkpKSA9IDE7CiAgICAgIEJJTkZPX1BSSU1BUllfUCAocHJpbWFyeSkgPSAxOwogICAgICBpZiAoQklORk9fVklSVFVBTF9QIChwcmltYXJ5KSkKCXsKCSAgdHJlZSBkZWx0YTsKCgkgIEJJTkZPX0lOSEVSSVRBTkNFX0NIQUlOIChwcmltYXJ5KSA9IHR5cGVfYmluZm87CgkgIC8qIEEgdmlydHVhbCBiaW5mbyBtaWdodCBoYXZlIGJlZW4gY29waWVkIGZyb20gd2l0aGluCiAgCSAgICAgYW5vdGhlciBoaWVyYXJjaHkuIEFzIHdlJ3JlIGFib3V0IHRvIHVzZSBpdCBhcyBhIHByaW1hcnkKICAJICAgICBiYXNlLCBtYWtlIHN1cmUgdGhlIG9mZnNldHMgbWF0Y2guICAqLwoJICBkZWx0YSA9IHNpemVfZGlmZm9wIChzc2l6ZV9pbnQgKDApLAoJCQkgICAgICAgY29udmVydCAoc3NpemV0eXBlLCBCSU5GT19PRkZTRVQgKHByaW1hcnkpKSk7CgkgIAoJICBwcm9wYWdhdGVfYmluZm9fb2Zmc2V0cyAocHJpbWFyeSwgZGVsdGEpOwoJfQogICAgICAKICAgICAgcHJpbWFyeSA9IFRZUEVfQklORk8gKGJhc2V0eXBlKTsKICAgICAgCiAgICAgIFRZUEVfVkZJRUxEICh0KSA9IFRZUEVfVkZJRUxEIChiYXNldHlwZSk7CiAgICAgIEJJTkZPX1ZUQUJMRSAodHlwZV9iaW5mbykgPSBCSU5GT19WVEFCTEUgKHByaW1hcnkpOwogICAgICBCSU5GT19WSVJUVUFMUyAodHlwZV9iaW5mbykgPSBCSU5GT19WSVJUVUFMUyAocHJpbWFyeSk7CiAgICB9Cn0KDAovKiBTZXQgbWVtb2l6aW5nIGZpZWxkcyBhbmQgYml0cyBvZiBUIChhbmQgaXRzIHZhcmlhbnRzKSBmb3IgbGF0ZXIKICAgdXNlLiAgKi8KCnN0YXRpYyB2b2lkCmZpbmlzaF9zdHJ1Y3RfYml0cyAodHJlZSB0KQp7CiAgdHJlZSB2YXJpYW50czsKICAKICAvKiBGaXggdXAgdmFyaWFudHMgKGlmIGFueSkuICAqLwogIGZvciAodmFyaWFudHMgPSBUWVBFX05FWFRfVkFSSUFOVCAodCk7CiAgICAgICB2YXJpYW50czsKICAgICAgIHZhcmlhbnRzID0gVFlQRV9ORVhUX1ZBUklBTlQgKHZhcmlhbnRzKSkKICAgIHsKICAgICAgLyogVGhlc2UgZmllbGRzIGFyZSBpbiB0aGUgX1RZUEUgcGFydCBvZiB0aGUgbm9kZSwgbm90IGluCgkgdGhlIFRZUEVfTEFOR19TUEVDSUZJQyBjb21wb25lbnQsIHNvIHRoZXkgYXJlIG5vdCBzaGFyZWQuICAqLwogICAgICBUWVBFX0hBU19DT05TVFJVQ1RPUiAodmFyaWFudHMpID0gVFlQRV9IQVNfQ09OU1RSVUNUT1IgKHQpOwogICAgICBUWVBFX05FRURTX0NPTlNUUlVDVElORyAodmFyaWFudHMpID0gVFlQRV9ORUVEU19DT05TVFJVQ1RJTkcgKHQpOwogICAgICBUWVBFX0hBU19OT05UUklWSUFMX0RFU1RSVUNUT1IgKHZhcmlhbnRzKSAKCT0gVFlQRV9IQVNfTk9OVFJJVklBTF9ERVNUUlVDVE9SICh0KTsKCiAgICAgIFRZUEVfUE9MWU1PUlBISUNfUCAodmFyaWFudHMpID0gVFlQRV9QT0xZTU9SUEhJQ19QICh0KTsKICAgICAgCiAgICAgIFRZUEVfQklORk8gKHZhcmlhbnRzKSA9IFRZUEVfQklORk8gKHQpOwoKICAgICAgLyogQ29weSB3aGF0ZXZlciB0aGVzZSBhcmUgaG9sZGluZyB0b2RheS4gICovCiAgICAgIFRZUEVfVkZJRUxEICh2YXJpYW50cykgPSBUWVBFX1ZGSUVMRCAodCk7CiAgICAgIFRZUEVfTUVUSE9EUyAodmFyaWFudHMpID0gVFlQRV9NRVRIT0RTICh0KTsKICAgICAgVFlQRV9GSUVMRFMgKHZhcmlhbnRzKSA9IFRZUEVfRklFTERTICh0KTsKICAgICAgLyogQVBQTEUgTE9DQUwgYmVnaW4gbWFpbmxpbmUgNDEyMTk2MiAqLwogICAgICAvKiBBUFBMRSBMT0NBTCBlbmQgbWFpbmxpbmUgNDEyMTk2MiAqLwogICAgfQoKICBpZiAoQklORk9fTl9CQVNFX0JJTkZPUyAoVFlQRV9CSU5GTyAodCkpICYmIFRZUEVfUE9MWU1PUlBISUNfUCAodCkpCiAgICAvKiBGb3IgYSBjbGFzcyB3L28gYmFzZWNsYXNzZXMsICdmaW5pc2hfc3RydWN0JyBoYXMgc2V0CiAgICAgICBDTEFTU1RZUEVfUFVSRV9WSVJUVUFMUyBjb3JyZWN0bHkgKGJ5IGRlZmluaXRpb24pLgogICAgICAgU2ltaWxhcmx5IGZvciBhIGNsYXNzIHdob3NlIGJhc2UgY2xhc3NlcyBkbyBub3QgaGF2ZSB2dGFibGVzLgogICAgICAgV2hlbiBuZWl0aGVyIG9mIHRoZXNlIGlzIHRydWUsIHdlIG1pZ2h0IGhhdmUgcmVtb3ZlZCBhYnN0cmFjdAogICAgICAgdmlydHVhbHMgKGJ5IHByb3ZpZGluZyBhIGRlZmluaXRpb24pLCBhZGRlZCBzb21lIChieSBkZWNsYXJpbmcKICAgICAgIG5ldyBvbmVzKSwgb3IgcmVkZWNsYXJlZCBvbmVzIGZyb20gYSBiYXNlIGNsYXNzLiAgV2UgbmVlZCB0bwogICAgICAgcmVjYWxjdWxhdGUgd2hhdCdzIHJlYWxseSBhbiBhYnN0cmFjdCB2aXJ0dWFsIGF0IHRoaXMgcG9pbnQgKGJ5CiAgICAgICBsb29raW5nIGluIHRoZSB2dGFibGVzKS4gICovCiAgICBnZXRfcHVyZV92aXJ0dWFscyAodCk7CiAgCiAgLyogSWYgdGhpcyB0eXBlIGhhcyBhIGNvcHkgY29uc3RydWN0b3Igb3IgYSBkZXN0cnVjdG9yLCBmb3JjZSBpdHMKICAgICBtb2RlIHRvIGJlIEJMS21vZGUsIGFuZCBmb3JjZSBpdHMgVFJFRV9BRERSRVNTQUJMRSBiaXQgdG8gYmUKICAgICBub256ZXJvLiAgVGhpcyB3aWxsIGNhdXNlIGl0IHRvIGJlIHBhc3NlZCBieSBpbnZpc2libGUgcmVmZXJlbmNlCiAgICAgYW5kIHByZXZlbnQgaXQgZnJvbSBiZWluZyByZXR1cm5lZCBpbiBhIHJlZ2lzdGVyLiAgKi8KICBpZiAoISBUWVBFX0hBU19UUklWSUFMX0lOSVRfUkVGICh0KSB8fCBUWVBFX0hBU19OT05UUklWSUFMX0RFU1RSVUNUT1IgKHQpKQogICAgewogICAgICB0cmVlIHZhcmlhbnRzOwogICAgICBERUNMX01PREUgKFRZUEVfTUFJTl9ERUNMICh0KSkgPSBCTEttb2RlOwogICAgICBmb3IgKHZhcmlhbnRzID0gdDsgdmFyaWFudHM7IHZhcmlhbnRzID0gVFlQRV9ORVhUX1ZBUklBTlQgKHZhcmlhbnRzKSkKCXsKCSAgVFlQRV9NT0RFICh2YXJpYW50cykgPSBCTEttb2RlOwoJICBUUkVFX0FERFJFU1NBQkxFICh2YXJpYW50cykgPSAxOwoJfQogICAgfQp9CgovKiBJc3N1ZSB3YXJuaW5ncyBhYm91dCBUIGhhdmluZyBwcml2YXRlIGNvbnN0cnVjdG9ycywgYnV0IG5vIGZyaWVuZHMsCiAgIGFuZCBzbyBmb3J0aC4gIAoKICAgSEFTX05PTlBSSVZBVEVfTUVUSE9EIGlzIG5vbnplcm8gaWYgVCBoYXMgYW55IG5vbi1wcml2YXRlIG1ldGhvZHMgb3IKICAgc3RhdGljIG1lbWJlcnMuICBIQVNfTk9OUFJJVkFURV9TVEFUSUNfRk4gaXMgbm9uemVybyBpZiBUIGhhcyBhbnkKICAgbm9uLXByaXZhdGUgc3RhdGljIG1lbWJlciBmdW5jdGlvbnMuICAqLwoKc3RhdGljIHZvaWQKbWF5YmVfd2Fybl9hYm91dF9vdmVybHlfcHJpdmF0ZV9jbGFzcyAodHJlZSB0KQp7CiAgaW50IGhhc19tZW1iZXJfZm4gPSAwOwogIGludCBoYXNfbm9ucHJpdmF0ZV9tZXRob2QgPSAwOwogIHRyZWUgZm47CgogIGlmICghd2Fybl9jdG9yX2R0b3JfcHJpdmFjeQogICAgICAvKiBJZiB0aGUgY2xhc3MgaGFzIGZyaWVuZHMsIHRob3NlIGVudGl0aWVzIG1pZ2h0IGNyZWF0ZSBhbmQKCSBhY2Nlc3MgaW5zdGFuY2VzLCBzbyB3ZSBzaG91bGQgbm90IHdhcm4uICAqLwogICAgICB8fCAoQ0xBU1NUWVBFX0ZSSUVORF9DTEFTU0VTICh0KQoJICB8fCBERUNMX0ZSSUVORExJU1QgKFRZUEVfTUFJTl9ERUNMICh0KSkpCiAgICAgIC8qIFdlIHdpbGwgaGF2ZSB3YXJuZWQgd2hlbiB0aGUgdGVtcGxhdGUgd2FzIGRlY2xhcmVkOyB0aGVyZSdzCgkgbm8gbmVlZCB0byB3YXJuIG9uIGV2ZXJ5IGluc3RhbnRpYXRpb24uICAqLwogICAgICB8fCBDTEFTU1RZUEVfVEVNUExBVEVfSU5TVEFOVElBVElPTiAodCkpCiAgICAvKiBUaGVyZSdzIG5vIHJlYXNvbiB0byBldmVuIGNvbnNpZGVyIHdhcm5pbmcgYWJvdXQgdGhpcyAKICAgICAgIGNsYXNzLiAgKi8KICAgIHJldHVybjsKICAgIAogIC8qIFdlIG9ubHkgaXNzdWUgb25lIHdhcm5pbmcsIGlmIG1vcmUgdGhhbiBvbmUgYXBwbGllcywgYmVjYXVzZQogICAgIG90aGVyd2lzZSwgb24gY29kZSBsaWtlOgoKICAgICBjbGFzcyBBIHsKICAgICAgIC8vIE9vcHMgLSBmb3Jnb3QgYHB1YmxpYzonCiAgICAgICBBKCk7CiAgICAgICBBKGNvbnN0IEEmKTsKICAgICAgIH5BKCk7CiAgICAgfTsKCiAgICAgd2Ugd2FybiBzZXZlcmFsIHRpbWVzIGFib3V0IGVzc2VudGlhbGx5IHRoZSBzYW1lIHByb2JsZW0uICAqLwoKICAvKiBDaGVjayB0byBzZWUgaWYgYWxsIChub24tY29uc3RydWN0b3IsIG5vbi1kZXN0cnVjdG9yKSBtZW1iZXIKICAgICBmdW5jdGlvbnMgYXJlIHByaXZhdGUuICAoU2luY2UgdGhlcmUgYXJlIG5vIGZyaWVuZHMgb3IKICAgICBub24tcHJpdmF0ZSBzdGF0aWNzLCB3ZSBjYW4ndCBldmVyIGNhbGwgYW55IG9mIHRoZSBwcml2YXRlIG1lbWJlcgogICAgIGZ1bmN0aW9ucy4pICAqLwogIGZvciAoZm4gPSBUWVBFX01FVEhPRFMgKHQpOyBmbjsgZm4gPSBUUkVFX0NIQUlOIChmbikpCiAgICAvKiBXZSdyZSBub3QgaW50ZXJlc3RlZCBpbiBjb21waWxlci1nZW5lcmF0ZWQgbWV0aG9kczsgdGhleSBkb24ndAogICAgICAgcHJvdmlkZSBhbnkgd2F5IHRvIGNhbGwgcHJpdmF0ZSBtZW1iZXJzLiAgKi8KICAgIGlmICghREVDTF9BUlRJRklDSUFMIChmbikpIAogICAgICB7CglpZiAoIVRSRUVfUFJJVkFURSAoZm4pKQoJICB7CgkgICAgaWYgKERFQ0xfU1RBVElDX0ZVTkNUSU9OX1AgKGZuKSkgCgkgICAgICAvKiBBIG5vbi1wcml2YXRlIHN0YXRpYyBtZW1iZXIgZnVuY3Rpb24gaXMganVzdCBsaWtlIGEKCQkgZnJpZW5kOyBpdCBjYW4gY3JlYXRlIGFuZCBpbnZva2UgcHJpdmF0ZSBtZW1iZXIKCQkgZnVuY3Rpb25zLCBhbmQgYmUgYWNjZXNzZWQgd2l0aG91dCBhIGNsYXNzCgkJIGluc3RhbmNlLiAgKi8KCSAgICAgIHJldHVybjsKCQkKCSAgICBoYXNfbm9ucHJpdmF0ZV9tZXRob2QgPSAxOwoJICAgIC8qIEtlZXAgc2VhcmNoaW5nIGZvciBhIHN0YXRpYyBtZW1iZXIgZnVuY3Rpb24uICAqLwoJICB9CgllbHNlIGlmICghREVDTF9DT05TVFJVQ1RPUl9QIChmbikgJiYgIURFQ0xfREVTVFJVQ1RPUl9QIChmbikpCgkgIGhhc19tZW1iZXJfZm4gPSAxOwogICAgICB9IAoKICBpZiAoIWhhc19ub25wcml2YXRlX21ldGhvZCAmJiBoYXNfbWVtYmVyX2ZuKSAKICAgIHsKICAgICAgLyogVGhlcmUgYXJlIG5vIG5vbi1wcml2YXRlIG1ldGhvZHMsIGFuZCB0aGVyZSdzIGF0IGxlYXN0IG9uZQoJIHByaXZhdGUgbWVtYmVyIGZ1bmN0aW9uIHRoYXQgaXNuJ3QgYSBjb25zdHJ1Y3RvciBvcgoJIGRlc3RydWN0b3IuICAoSWYgYWxsIHRoZSBwcml2YXRlIG1lbWJlcnMgYXJlCgkgY29uc3RydWN0b3JzL2Rlc3RydWN0b3JzIHdlIHdhbnQgdG8gdXNlIHRoZSBjb2RlIGJlbG93IHRoYXQKCSBpc3N1ZXMgZXJyb3IgbWVzc2FnZXMgc3BlY2lmaWNhbGx5IHJlZmVycmluZyB0bwoJIGNvbnN0cnVjdG9ycy9kZXN0cnVjdG9ycy4pICAqLwogICAgICB1bnNpZ25lZCBpOwogICAgICB0cmVlIGJpbmZvID0gVFlQRV9CSU5GTyAodCk7CiAgICAgIAogICAgICBmb3IgKGkgPSAwOyBpICE9IEJJTkZPX05fQkFTRV9CSU5GT1MgKGJpbmZvKTsgaSsrKQoJaWYgKEJJTkZPX0JBU0VfQUNDRVNTIChiaW5mbywgaSkgIT0gYWNjZXNzX3ByaXZhdGVfbm9kZSkKCSAgewoJICAgIGhhc19ub25wcml2YXRlX21ldGhvZCA9IDE7CgkgICAgYnJlYWs7CgkgIH0KICAgICAgaWYgKCFoYXNfbm9ucHJpdmF0ZV9tZXRob2QpIAoJewoJICB3YXJuaW5nICgiYWxsIG1lbWJlciBmdW5jdGlvbnMgaW4gY2xhc3MgJXFUIGFyZSBwcml2YXRlIiwgdCk7CgkgIHJldHVybjsKCX0KICAgIH0KCiAgLyogRXZlbiBpZiBzb21lIG9mIHRoZSBtZW1iZXIgZnVuY3Rpb25zIGFyZSBub24tcHJpdmF0ZSwgdGhlIGNsYXNzCiAgICAgd29uJ3QgYmUgdXNlZnVsIGZvciBtdWNoIGlmIGFsbCB0aGUgY29uc3RydWN0b3JzIG9yIGRlc3RydWN0b3JzCiAgICAgYXJlIHByaXZhdGU6IHN1Y2ggYW4gb2JqZWN0IGNhbiBuZXZlciBiZSBjcmVhdGVkIG9yIGRlc3Ryb3llZC4gICovCiAgZm4gPSBDTEFTU1RZUEVfREVTVFJVQ1RPUlMgKHQpOwogIGlmIChmbiAmJiBUUkVFX1BSSVZBVEUgKGZuKSkKICAgIHsKICAgICAgd2FybmluZyAoIiVxI1Qgb25seSBkZWZpbmVzIGEgcHJpdmF0ZSBkZXN0cnVjdG9yIGFuZCBoYXMgbm8gZnJpZW5kcyIsCgkgICAgICAgdCk7CiAgICAgIHJldHVybjsKICAgIH0KCiAgaWYgKFRZUEVfSEFTX0NPTlNUUlVDVE9SICh0KSkKICAgIHsKICAgICAgaW50IG5vbnByaXZhdGVfY3RvciA9IDA7CgkgIAogICAgICAvKiBJZiBhIG5vbi10ZW1wbGF0ZSBjbGFzcyBkb2VzIG5vdCBkZWZpbmUgYSBjb3B5CgkgY29uc3RydWN0b3IsIG9uZSBpcyBkZWZpbmVkIGZvciBpdCwgZW5hYmxpbmcgaXQgdG8gYXZvaWQKCSB0aGlzIHdhcm5pbmcuICBGb3IgYSB0ZW1wbGF0ZSBjbGFzcywgdGhpcyBkb2VzIG5vdAoJIGhhcHBlbiwgYW5kIHNvIHdlIHdvdWxkIG5vcm1hbGx5IGdldCBhIHdhcm5pbmcgb246CgoJICAgdGVtcGxhdGUgPGNsYXNzIFQ+IGNsYXNzIEMgeyBwcml2YXRlOiBDKCk7IH07ICAKCSAgCgkgVG8gYXZvaWQgdGhpcyBhc3ltbWV0cnksIHdlIGNoZWNrIFRZUEVfSEFTX0lOSVRfUkVGLiAgQWxsCgkgY29tcGxldGUgbm9uLXRlbXBsYXRlIG9yIGZ1bGx5IGluc3RhbnRpYXRlZCBjbGFzc2VzIGhhdmUgdGhpcwoJIGZsYWcgc2V0LiAgKi8KICAgICAgaWYgKCFUWVBFX0hBU19JTklUX1JFRiAodCkpCglub25wcml2YXRlX2N0b3IgPSAxOwogICAgICBlbHNlIAoJZm9yIChmbiA9IENMQVNTVFlQRV9DT05TVFJVQ1RPUlMgKHQpOyBmbjsgZm4gPSBPVkxfTkVYVCAoZm4pKSAKCSAgewoJICAgIHRyZWUgY3RvciA9IE9WTF9DVVJSRU5UIChmbik7CgkgICAgLyogSWRlYWxseSwgd2Ugd291bGRuJ3QgY291bnQgY29weSBjb25zdHJ1Y3RvcnMgKG9yLCBpbgoJICAgICAgIGZhY3QsIGFueSBjb25zdHJ1Y3RvciB0aGF0IHRha2VzIGFuIGFyZ3VtZW50IG9mIHRoZQoJICAgICAgIGNsYXNzIHR5cGUgYXMgYSBwYXJhbWV0ZXIpIGJlY2F1c2Ugc3VjaCB0aGluZ3MgY2Fubm90CgkgICAgICAgYmUgdXNlZCB0byBjb25zdHJ1Y3QgYW4gaW5zdGFuY2Ugb2YgdGhlIGNsYXNzIHVubGVzcwoJICAgICAgIHlvdSBhbHJlYWR5IGhhdmUgb25lLiAgQnV0LCBmb3Igbm93IGF0IGxlYXN0LCB3ZSdyZQoJICAgICAgIG1vcmUgZ2VuZXJvdXMuICAqLwoJICAgIGlmICghIFRSRUVfUFJJVkFURSAoY3RvcikpCgkgICAgICB7CgkJbm9ucHJpdmF0ZV9jdG9yID0gMTsKCQlicmVhazsKCSAgICAgIH0KCSAgfQoKICAgICAgaWYgKG5vbnByaXZhdGVfY3RvciA9PSAwKQoJewoJICB3YXJuaW5nICgiJXEjVCBvbmx5IGRlZmluZXMgcHJpdmF0ZSBjb25zdHJ1Y3RvcnMgYW5kIGhhcyBubyBmcmllbmRzIiwKICAgICAgICAgICAgICAgICAgIHQpOwoJICByZXR1cm47Cgl9CiAgICB9Cn0KCnN0YXRpYyBzdHJ1Y3QgewogIGd0X3BvaW50ZXJfb3BlcmF0b3IgbmV3X3ZhbHVlOwogIHZvaWQgKmNvb2tpZTsKfSByZXNvcnRfZGF0YTsKCi8qIENvbXBhcmlzb24gZnVuY3Rpb24gdG8gY29tcGFyZSB0d28gVFlQRV9NRVRIT0RfVkVDIGVudHJpZXMgYnkgbmFtZS4gICovCgpzdGF0aWMgaW50Cm1ldGhvZF9uYW1lX2NtcCAoY29uc3Qgdm9pZCogbTFfcCwgY29uc3Qgdm9pZCogbTJfcCkKewogIGNvbnN0IHRyZWUgKmNvbnN0IG0xID0gbTFfcDsKICBjb25zdCB0cmVlICpjb25zdCBtMiA9IG0yX3A7CiAgCiAgaWYgKCptMSA9PSBOVUxMX1RSRUUgJiYgKm0yID09IE5VTExfVFJFRSkKICAgIHJldHVybiAwOwogIGlmICgqbTEgPT0gTlVMTF9UUkVFKQogICAgcmV0dXJuIC0xOwogIGlmICgqbTIgPT0gTlVMTF9UUkVFKQogICAgcmV0dXJuIDE7CiAgaWYgKERFQ0xfTkFNRSAoT1ZMX0NVUlJFTlQgKCptMSkpIDwgREVDTF9OQU1FIChPVkxfQ1VSUkVOVCAoKm0yKSkpCiAgICByZXR1cm4gLTE7CiAgcmV0dXJuIDE7Cn0KCi8qIFRoaXMgcm91dGluZSBjb21wYXJlcyB0d28gZmllbGRzIGxpa2UgbWV0aG9kX25hbWVfY21wIGJ1dCB1c2luZyB0aGUKICAgcG9pbnRlciBvcGVyYXRvciBpbiByZXNvcnRfZmllbGRfZGVjbF9kYXRhLiAgKi8KCnN0YXRpYyBpbnQKcmVzb3J0X21ldGhvZF9uYW1lX2NtcCAoY29uc3Qgdm9pZCogbTFfcCwgY29uc3Qgdm9pZCogbTJfcCkKewogIGNvbnN0IHRyZWUgKmNvbnN0IG0xID0gbTFfcDsKICBjb25zdCB0cmVlICpjb25zdCBtMiA9IG0yX3A7CiAgaWYgKCptMSA9PSBOVUxMX1RSRUUgJiYgKm0yID09IE5VTExfVFJFRSkKICAgIHJldHVybiAwOwogIGlmICgqbTEgPT0gTlVMTF9UUkVFKQogICAgcmV0dXJuIC0xOwogIGlmICgqbTIgPT0gTlVMTF9UUkVFKQogICAgcmV0dXJuIDE7CiAgewogICAgdHJlZSBkMSA9IERFQ0xfTkFNRSAoT1ZMX0NVUlJFTlQgKCptMSkpOwogICAgdHJlZSBkMiA9IERFQ0xfTkFNRSAoT1ZMX0NVUlJFTlQgKCptMikpOwogICAgcmVzb3J0X2RhdGEubmV3X3ZhbHVlICgmZDEsIHJlc29ydF9kYXRhLmNvb2tpZSk7CiAgICByZXNvcnRfZGF0YS5uZXdfdmFsdWUgKCZkMiwgcmVzb3J0X2RhdGEuY29va2llKTsKICAgIGlmIChkMSA8IGQyKQogICAgICByZXR1cm4gLTE7CiAgfQogIHJldHVybiAxOwp9CgovKiBSZXNvcnQgVFlQRV9NRVRIT0RfVkVDIGJlY2F1c2UgcG9pbnRlcnMgaGF2ZSBiZWVuIHJlb3JkZXJlZC4gICovCgp2b2lkIApyZXNvcnRfdHlwZV9tZXRob2RfdmVjICh2b2lkKiBvYmosCiAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQqIG9yaWdfb2JqIEFUVFJJQlVURV9VTlVTRUQgLAogICAgICAgICAgICAgICAgICAgICAgICBndF9wb2ludGVyX29wZXJhdG9yIG5ld192YWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCogY29va2llKQp7CiAgVkVDKHRyZWUpICptZXRob2RfdmVjID0gKFZFQyh0cmVlKSAqKSBvYmo7CiAgaW50IGxlbiA9IFZFQ19sZW5ndGggKHRyZWUsIG1ldGhvZF92ZWMpOwogIHNpemVfdCBzbG90OwogIHRyZWUgZm47CgogIC8qIFRoZSB0eXBlIGNvbnZlcnNpb24gb3BzIGhhdmUgdG8gbGl2ZSBhdCB0aGUgZnJvbnQgb2YgdGhlIHZlYywgc28gd2UKICAgICBjYW4ndCBzb3J0IHRoZW0uICAqLwogIGZvciAoc2xvdCA9IENMQVNTVFlQRV9GSVJTVF9DT05WRVJTSU9OX1NMT1Q7CiAgICAgICBWRUNfaXRlcmF0ZSAodHJlZSwgbWV0aG9kX3ZlYywgc2xvdCwgZm4pOwogICAgICAgKytzbG90KQogICAgaWYgKCFERUNMX0NPTlZfRk5fUCAoT1ZMX0NVUlJFTlQgKGZuKSkpCiAgICAgIGJyZWFrOwoKICBpZiAobGVuIC0gc2xvdCA+IDEpCiAgICB7CiAgICAgIHJlc29ydF9kYXRhLm5ld192YWx1ZSA9IG5ld192YWx1ZTsKICAgICAgcmVzb3J0X2RhdGEuY29va2llID0gY29va2llOwogICAgICBxc29ydCAoVkVDX2FkZHJlc3MgKHRyZWUsIG1ldGhvZF92ZWMpICsgc2xvdCwgbGVuIC0gc2xvdCwgc2l6ZW9mICh0cmVlKSwKCSAgICAgcmVzb3J0X21ldGhvZF9uYW1lX2NtcCk7CiAgICB9Cn0KCi8qIFdhcm4gYWJvdXQgZHVwbGljYXRlIG1ldGhvZHMgaW4gZm5fZmllbGRzLgoKICAgU29ydCBtZXRob2RzIHRoYXQgYXJlIG5vdCBzcGVjaWFsIChpLmUuLCBjb25zdHJ1Y3RvcnMsIGRlc3RydWN0b3JzLAogICBhbmQgdHlwZSBjb252ZXJzaW9uIG9wZXJhdG9ycykgc28gdGhhdCB3ZSBjYW4gZmluZCB0aGVtIGZhc3RlciBpbgogICBzZWFyY2guICAqLwoKc3RhdGljIHZvaWQKZmluaXNoX3N0cnVjdF9tZXRob2RzICh0cmVlIHQpCnsKICB0cmVlIGZuX2ZpZWxkczsKICBWRUModHJlZSkgKm1ldGhvZF92ZWM7CiAgaW50IHNsb3QsIGxlbjsKCiAgbWV0aG9kX3ZlYyA9IENMQVNTVFlQRV9NRVRIT0RfVkVDICh0KTsKICBpZiAoIW1ldGhvZF92ZWMpCiAgICByZXR1cm47CgogIGxlbiA9IFZFQ19sZW5ndGggKHRyZWUsIG1ldGhvZF92ZWMpOwoKICAvKiBDbGVhciBERUNMX0lOX0FHR1JfUCBmb3IgYWxsIGZ1bmN0aW9ucy4gICovCiAgZm9yIChmbl9maWVsZHMgPSBUWVBFX01FVEhPRFMgKHQpOyBmbl9maWVsZHM7IAogICAgICAgZm5fZmllbGRzID0gVFJFRV9DSEFJTiAoZm5fZmllbGRzKSkKICAgIERFQ0xfSU5fQUdHUl9QIChmbl9maWVsZHMpID0gMDsKCiAgLyogSXNzdWUgd2FybmluZ3MgYWJvdXQgcHJpdmF0ZSBjb25zdHJ1Y3RvcnMgYW5kIHN1Y2guICBJZiB0aGVyZSBhcmUKICAgICBubyBtZXRob2RzLCB0aGVuIHNvbWUgcHVibGljIGRlZmF1bHRzIGFyZSBnZW5lcmF0ZWQuICAqLwogIG1heWJlX3dhcm5fYWJvdXRfb3Zlcmx5X3ByaXZhdGVfY2xhc3MgKHQpOwoKICAvKiBUaGUgdHlwZSBjb252ZXJzaW9uIG9wcyBoYXZlIHRvIGxpdmUgYXQgdGhlIGZyb250IG9mIHRoZSB2ZWMsIHNvIHdlCiAgICAgY2FuJ3Qgc29ydCB0aGVtLiAgKi8KICBmb3IgKHNsb3QgPSBDTEFTU1RZUEVfRklSU1RfQ09OVkVSU0lPTl9TTE9UOwogICAgICAgVkVDX2l0ZXJhdGUgKHRyZWUsIG1ldGhvZF92ZWMsIHNsb3QsIGZuX2ZpZWxkcyk7CiAgICAgICArK3Nsb3QpCiAgICBpZiAoIURFQ0xfQ09OVl9GTl9QIChPVkxfQ1VSUkVOVCAoZm5fZmllbGRzKSkpCiAgICAgIGJyZWFrOwogIGlmIChsZW4gLSBzbG90ID4gMSkKICAgIHFzb3J0IChWRUNfYWRkcmVzcyAodHJlZSwgbWV0aG9kX3ZlYykgKyBzbG90LAoJICAgbGVuLXNsb3QsIHNpemVvZiAodHJlZSksIG1ldGhvZF9uYW1lX2NtcCk7Cn0KCi8qIE1ha2UgQklORk8ncyB2dGFibGUgaGF2ZSBOIGVudHJpZXMsIGluY2x1ZGluZyBSVFRJIGVudHJpZXMsCiAgIHZiYXNlIGFuZCB2Y2FsbCBvZmZzZXRzLCBldGMuICBTZXQgaXRzIHR5cGUgYW5kIGNhbGwgdGhlIGJhY2tlbmQKICAgdG8gbGF5IGl0IG91dC4gICovCgpzdGF0aWMgdm9pZApsYXlvdXRfdnRhYmxlX2RlY2wgKHRyZWUgYmluZm8sIGludCBuKQp7CiAgdHJlZSBhdHlwZTsKICB0cmVlIHZ0YWJsZTsKICAvKiBBUFBMRSBMT0NBTCBiZWdpbiBLRVhUIHRlcm1pbmF0ZWQtdnRhYmxlcyAqLwogIGludCBuX2VudHJpZXM7CgogIG5fZW50cmllcyA9IG47CiAgCiAgLyogRW5sYXJnZSBzdWdnZXN0ZWQgdnRhYmxlIHNpemUgYnkgb25lIGVudHJ5OyBpdCB3aWxsIGJlIGZpbGxlZAogICAgIHdpdGggYSB6ZXJvIHdvcmQuICBEYXJ3aW4ga2VybmVsIGR5bmFtaWMtZHJpdmVyIGxvYWRlciBsb29rcwogICAgIGZvciB0aGlzIHZhbHVlIHRvIGZpbmQgdnRhYmxlIGVuZHMgZm9yIHBhdGNoaW5nLiAgKi8KICBpZiAoVEFSR0VUX0tFWFRBQkkpCiAgICBuX2VudHJpZXMgKz0gMTsKICAvKiBBUFBMRSBMT0NBTCBlbmQgS0VYVCB0ZXJtaW5hdGVkLXZ0YWJsZXMgKi8KCiAgYXR5cGUgPSBidWlsZF9jcGx1c19hcnJheV90eXBlICh2dGFibGVfZW50cnlfdHlwZSwgCgkJCQkgIC8qIEFQUExFIExPQ0FMIEtFWFQgdGVybWluYXRlZC12dGFibGVzICovCgkJCQkgIGJ1aWxkX2luZGV4X3R5cGUgKHNpemVfaW50IChuX2VudHJpZXMgLSAxKSkpOwogIGxheW91dF90eXBlIChhdHlwZSk7CgogIC8qIFdlIG1heSBoYXZlIHRvIGdyb3cgdGhlIHZ0YWJsZS4gICovCiAgdnRhYmxlID0gZ2V0X3Z0YmxfZGVjbF9mb3JfYmluZm8gKGJpbmZvKTsKICBpZiAoIXNhbWVfdHlwZV9wIChUUkVFX1RZUEUgKHZ0YWJsZSksIGF0eXBlKSkKICAgIHsKICAgICAgVFJFRV9UWVBFICh2dGFibGUpID0gYXR5cGU7CiAgICAgIERFQ0xfU0laRSAodnRhYmxlKSA9IERFQ0xfU0laRV9VTklUICh2dGFibGUpID0gTlVMTF9UUkVFOwogICAgICBsYXlvdXRfZGVjbCAodnRhYmxlLCAwKTsKICAgIH0KfQoKLyogVHJ1ZSBpZmYgRk5ERUNMIGFuZCBCQVNFX0ZOREVDTCAoYm90aCBub24tc3RhdGljIG1lbWJlciBmdW5jdGlvbnMpCiAgIGhhdmUgdGhlIHNhbWUgc2lnbmF0dXJlLiAgKi8KCmludApzYW1lX3NpZ25hdHVyZV9wICh0cmVlIGZuZGVjbCwgdHJlZSBiYXNlX2ZuZGVjbCkKewogIC8qIE9uZSBkZXN0cnVjdG9yIG92ZXJyaWRlcyBhbm90aGVyIGlmIHRoZXkgYXJlIHRoZSBzYW1lIGtpbmQgb2YKICAgICBkZXN0cnVjdG9yLiAgKi8KICBpZiAoREVDTF9ERVNUUlVDVE9SX1AgKGJhc2VfZm5kZWNsKSAmJiBERUNMX0RFU1RSVUNUT1JfUCAoZm5kZWNsKQogICAgICAmJiBzcGVjaWFsX2Z1bmN0aW9uX3AgKGJhc2VfZm5kZWNsKSA9PSBzcGVjaWFsX2Z1bmN0aW9uX3AgKGZuZGVjbCkpCiAgICByZXR1cm4gMTsKICAvKiBCdXQgYSBub24tZGVzdHJ1Y3RvciBuZXZlciBvdmVycmlkZXMgYSBkZXN0cnVjdG9yLCBub3IgdmljZQogICAgIHZlcnNhLCBub3IgZG8gZGlmZmVyZW50IGtpbmRzIG9mIGRlc3RydWN0b3JzIG92ZXJyaWRlCiAgICAgb25lLWFub3RoZXIuICBGb3IgZXhhbXBsZSwgYSBjb21wbGV0ZSBvYmplY3QgZGVzdHJ1Y3RvciBkb2VzIG5vdAogICAgIG92ZXJyaWRlIGEgZGVsZXRpbmcgZGVzdHJ1Y3Rvci4gICovCiAgaWYgKERFQ0xfREVTVFJVQ1RPUl9QIChiYXNlX2ZuZGVjbCkgfHwgREVDTF9ERVNUUlVDVE9SX1AgKGZuZGVjbCkpCiAgICByZXR1cm4gMDsKCiAgaWYgKERFQ0xfTkFNRSAoZm5kZWNsKSA9PSBERUNMX05BTUUgKGJhc2VfZm5kZWNsKQogICAgICB8fCAoREVDTF9DT05WX0ZOX1AgKGZuZGVjbCkKCSAgJiYgREVDTF9DT05WX0ZOX1AgKGJhc2VfZm5kZWNsKQoJICAmJiBzYW1lX3R5cGVfcCAoREVDTF9DT05WX0ZOX1RZUEUgKGZuZGVjbCksCgkJCSAgREVDTF9DT05WX0ZOX1RZUEUgKGJhc2VfZm5kZWNsKSkpKQogICAgewogICAgICB0cmVlIHR5cGVzLCBiYXNlX3R5cGVzOwogICAgICB0eXBlcyA9IFRZUEVfQVJHX1RZUEVTIChUUkVFX1RZUEUgKGZuZGVjbCkpOwogICAgICBiYXNlX3R5cGVzID0gVFlQRV9BUkdfVFlQRVMgKFRSRUVfVFlQRSAoYmFzZV9mbmRlY2wpKTsKICAgICAgaWYgKChUWVBFX1FVQUxTIChUUkVFX1RZUEUgKFRSRUVfVkFMVUUgKGJhc2VfdHlwZXMpKSkKCSAgID09IFRZUEVfUVVBTFMgKFRSRUVfVFlQRSAoVFJFRV9WQUxVRSAodHlwZXMpKSkpCgkgICYmIGNvbXBwYXJtcyAoVFJFRV9DSEFJTiAoYmFzZV90eXBlcyksIFRSRUVfQ0hBSU4gKHR5cGVzKSkpCglyZXR1cm4gMTsKICAgIH0KICByZXR1cm4gMDsKfQoKLyogUmV0dXJucyBUUlVFIGlmIERFUklWRUQgaXMgYSBiaW5mbyBjb250YWluaW5nIHRoZSBiaW5mbyBCQVNFIGFzIGEKICAgc3Vib2JqZWN0LiAgKi8KIApzdGF0aWMgYm9vbApiYXNlX2Rlcml2ZWRfZnJvbSAodHJlZSBkZXJpdmVkLCB0cmVlIGJhc2UpCnsKICB0cmVlIHByb2JlOwoKICBmb3IgKHByb2JlID0gYmFzZTsgcHJvYmU7IHByb2JlID0gQklORk9fSU5IRVJJVEFOQ0VfQ0hBSU4gKHByb2JlKSkKICAgIHsKICAgICAgaWYgKHByb2JlID09IGRlcml2ZWQpCglyZXR1cm4gdHJ1ZTsKICAgICAgZWxzZSBpZiAoQklORk9fVklSVFVBTF9QIChwcm9iZSkpCgkvKiBJZiB3ZSBtZWV0IGEgdmlydHVhbCBiYXNlLCB3ZSBjYW4ndCBmb2xsb3cgdGhlIGluaGVyaXRhbmNlCgkgICBhbnkgbW9yZS4gIFNlZSBpZiB0aGUgY29tcGxldGUgdHlwZSBvZiBERVJJVkVEIGNvbnRhaW5zCgkgICBzdWNoIGEgdmlydHVhbCBiYXNlLiAgKi8KCXJldHVybiAoYmluZm9fZm9yX3ZiYXNlIChCSU5GT19UWVBFIChwcm9iZSksIEJJTkZPX1RZUEUgKGRlcml2ZWQpKQoJCSE9IE5VTExfVFJFRSk7CiAgICB9CiAgcmV0dXJuIGZhbHNlOwp9Cgp0eXBlZGVmIHN0cnVjdCBmaW5kX2ZpbmFsX292ZXJyaWRlcl9kYXRhX3MgewogIC8qIFRoZSBmdW5jdGlvbiBmb3Igd2hpY2ggd2UgYXJlIHRyeWluZyB0byBmaW5kIGEgZmluYWwgb3ZlcnJpZGVyLiAgKi8KICB0cmVlIGZuOwogIC8qIFRoZSBiYXNlIGNsYXNzIGluIHdoaWNoIHRoZSBmdW5jdGlvbiB3YXMgZGVjbGFyZWQuICAqLwogIHRyZWUgZGVjbGFyaW5nX2Jhc2U7CiAgLyogVGhlIGNhbmRpZGF0ZSBvdmVycmlkZXJzLiAgKi8KICB0cmVlIGNhbmRpZGF0ZXM7CiAgLyogUGF0aCB0byBtb3N0IGRlcml2ZWQuICAqLwogIFZFQyAodHJlZSkgKnBhdGg7Cn0gZmluZF9maW5hbF9vdmVycmlkZXJfZGF0YTsKCi8qIEFkZCB0aGUgb3ZlcnJpZGVyIGFsb25nIHRoZSBjdXJyZW50IHBhdGggdG8gRkZPRC0+Q0FORElEQVRFUy4KICAgUmV0dXJucyB0cnVlIGlmIGFuIG92ZXJyaWRlciB3YXMgZm91bmQ7IGZhbHNlIG90aGVyd2lzZS4gICovCgpzdGF0aWMgYm9vbApkZnNfZmluZF9maW5hbF9vdmVycmlkZXJfMSAodHJlZSBiaW5mbywgCgkJCSAgICBmaW5kX2ZpbmFsX292ZXJyaWRlcl9kYXRhICpmZm9kLAoJCQkgICAgdW5zaWduZWQgZGVwdGgpCnsKICB0cmVlIG1ldGhvZDsKCiAgLyogSWYgQklORk8gaXMgbm90IHRoZSBtb3N0IGRlcml2ZWQgdHlwZSwgdHJ5IGEgbW9yZSBkZXJpdmVkIGNsYXNzLgogICAgIEEgZGVmaW5pdGlvbiB0aGVyZSB3aWxsIG92ZXJyaWRlciBhIGRlZmluaXRpb24gaGVyZS4gICovCiAgaWYgKGRlcHRoKQogICAgewogICAgICBkZXB0aC0tOwogICAgICBpZiAoZGZzX2ZpbmRfZmluYWxfb3ZlcnJpZGVyXzEKCSAgKFZFQ19pbmRleCAodHJlZSwgZmZvZC0+cGF0aCwgZGVwdGgpLCBmZm9kLCBkZXB0aCkpCglyZXR1cm4gdHJ1ZTsKICAgIH0KCiAgbWV0aG9kID0gbG9va19mb3Jfb3ZlcnJpZGVzX2hlcmUgKEJJTkZPX1RZUEUgKGJpbmZvKSwgZmZvZC0+Zm4pOwogIGlmIChtZXRob2QpCiAgICB7CiAgICAgIHRyZWUgKmNhbmRpZGF0ZSA9ICZmZm9kLT5jYW5kaWRhdGVzOwogICAgICAKICAgICAgLyogUmVtb3ZlIGFueSBjYW5kaWRhdGVzIG92ZXJyaWRkZW4gYnkgdGhpcyBuZXcgZnVuY3Rpb24uICAqLwogICAgICB3aGlsZSAoKmNhbmRpZGF0ZSkKCXsKCSAgLyogSWYgKkNBTkRJREFURSBvdmVycmlkZXMgTUVUSE9ELCB0aGVuIE1FVEhPRAoJICAgICBjYW5ub3Qgb3ZlcnJpZGUgYW55dGhpbmcgZWxzZSBvbiB0aGUgbGlzdC4gICovCgkgIGlmIChiYXNlX2Rlcml2ZWRfZnJvbSAoVFJFRV9WQUxVRSAoKmNhbmRpZGF0ZSksIGJpbmZvKSkKCSAgICByZXR1cm4gdHJ1ZTsKCSAgLyogSWYgTUVUSE9EIG92ZXJyaWRlcyAqQ0FORElEQVRFLCByZW1vdmUgKkNBTkRJREFURS4gICovCgkgIGlmIChiYXNlX2Rlcml2ZWRfZnJvbSAoYmluZm8sIFRSRUVfVkFMVUUgKCpjYW5kaWRhdGUpKSkKCSAgICAqY2FuZGlkYXRlID0gVFJFRV9DSEFJTiAoKmNhbmRpZGF0ZSk7CgkgIGVsc2UKCSAgICBjYW5kaWRhdGUgPSAmVFJFRV9DSEFJTiAoKmNhbmRpZGF0ZSk7Cgl9CiAgICAgIAogICAgICAvKiBBZGQgdGhlIG5ldyBmdW5jdGlvbi4gICovCiAgICAgIGZmb2QtPmNhbmRpZGF0ZXMgPSB0cmVlX2NvbnMgKG1ldGhvZCwgYmluZm8sIGZmb2QtPmNhbmRpZGF0ZXMpOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgcmV0dXJuIGZhbHNlOwp9CgovKiBDYWxsZWQgZnJvbSBmaW5kX2ZpbmFsX292ZXJyaWRlciB2aWEgZGZzX3dhbGsuICAqLwoKc3RhdGljIHRyZWUKZGZzX2ZpbmRfZmluYWxfb3ZlcnJpZGVyX3ByZSAodHJlZSBiaW5mbywgdm9pZCAqZGF0YSkKewogIGZpbmRfZmluYWxfb3ZlcnJpZGVyX2RhdGEgKmZmb2QgPSAoZmluZF9maW5hbF9vdmVycmlkZXJfZGF0YSAqKSBkYXRhOwoKICBpZiAoYmluZm8gPT0gZmZvZC0+ZGVjbGFyaW5nX2Jhc2UpCiAgICBkZnNfZmluZF9maW5hbF9vdmVycmlkZXJfMSAoYmluZm8sIGZmb2QsIFZFQ19sZW5ndGggKHRyZWUsIGZmb2QtPnBhdGgpKTsKICBWRUNfc2FmZV9wdXNoICh0cmVlLCBmZm9kLT5wYXRoLCBiaW5mbyk7CgogIHJldHVybiBOVUxMX1RSRUU7Cn0KCnN0YXRpYyB0cmVlCmRmc19maW5kX2ZpbmFsX292ZXJyaWRlcl9wb3N0ICh0cmVlIGJpbmZvIEFUVFJJQlVURV9VTlVTRUQsIHZvaWQgKmRhdGEpCnsKICBmaW5kX2ZpbmFsX292ZXJyaWRlcl9kYXRhICpmZm9kID0gKGZpbmRfZmluYWxfb3ZlcnJpZGVyX2RhdGEgKikgZGF0YTsKICBWRUNfcG9wICh0cmVlLCBmZm9kLT5wYXRoKTsKCiAgcmV0dXJuIE5VTExfVFJFRTsKfQoKLyogUmV0dXJucyBhIFRSRUVfTElTVCB3aG9zZSBUUkVFX1BVUlBPU0UgaXMgdGhlIGZpbmFsIG92ZXJyaWRlciBmb3IKICAgRk4gYW5kIHdob3NlIFRSRUVfVkFMVUUgaXMgdGhlIGJpbmZvIGZvciB0aGUgYmFzZSB3aGVyZSB0aGUKICAgb3ZlcnJpZGluZyBvY2N1cnMuICBCSU5GTyAoaW4gdGhlIGhpZXJhcmNoeSBkb21pbmF0ZWQgYnkgdGhlIGJpbmZvCiAgIERFUklWRUQpIGlzIHRoZSBiYXNlIG9iamVjdCBpbiB3aGljaCBGTiBpcyBkZWNsYXJlZC4gICovCgpzdGF0aWMgdHJlZQpmaW5kX2ZpbmFsX292ZXJyaWRlciAodHJlZSBkZXJpdmVkLCB0cmVlIGJpbmZvLCB0cmVlIGZuKQp7CiAgZmluZF9maW5hbF9vdmVycmlkZXJfZGF0YSBmZm9kOwoKICAvKiBHZXR0aW5nIHRoaXMgcmlnaHQgaXMgYSBsaXR0bGUgdHJpY2t5LiAgVGhpcyBpcyB2YWxpZDoKCiAgICAgICBzdHJ1Y3QgUyB7IHZpcnR1YWwgdm9pZCBmICgpOyB9OwogICAgICAgc3RydWN0IFQgeyB2aXJ0dWFsIHZvaWQgZiAoKTsgfTsKICAgICAgIHN0cnVjdCBVIDogcHVibGljIFMsIHB1YmxpYyBUIHsgfTsKCiAgICAgZXZlbiB0aG91Z2ggY2FsbGluZyBgZicgaW4gYFUnIGlzIGFtYmlndW91cy4gIEJ1dCwgCgogICAgICAgc3RydWN0IFIgeyB2aXJ0dWFsIHZvaWQgZigpOyB9OwogICAgICAgc3RydWN0IFMgOiB2aXJ0dWFsIHB1YmxpYyBSIHsgdmlydHVhbCB2b2lkIGYgKCk7IH07CiAgICAgICBzdHJ1Y3QgVCA6IHZpcnR1YWwgcHVibGljIFIgeyB2aXJ0dWFsIHZvaWQgZiAoKTsgfTsKICAgICAgIHN0cnVjdCBVIDogcHVibGljIFMsIHB1YmxpYyBUIHsgfTsKCiAgICAgaXMgbm90IC0tIHRoZXJlJ3Mgbm8gd2F5IHRvIGRlY2lkZSB3aGV0aGVyIHRvIHB1dCBgUzo6Zicgb3IKICAgICBgVDo6ZicgaW4gdGhlIHZ0YWJsZSBmb3IgYFInLiAgCiAgICAgCiAgICAgVGhlIHNvbHV0aW9uIGlzIHRvIGxvb2sgYXQgYWxsIHBhdGhzIHRvIEJJTkZPLiAgSWYgd2UgZmluZAogICAgIGRpZmZlcmVudCBvdmVycmlkZXJzIGFsb25nIGFueSB0d28sIHRoZW4gdGhlcmUgaXMgYSBwcm9ibGVtLiAgKi8KICBpZiAoREVDTF9USFVOS19QIChmbikpCiAgICBmbiA9IFRIVU5LX1RBUkdFVCAoZm4pOwoKICAvKiBEZXRlcm1pbmUgdGhlIGRlcHRoIG9mIHRoZSBoaWVyYXJjaHkuICAqLwogIGZmb2QuZm4gPSBmbjsKICBmZm9kLmRlY2xhcmluZ19iYXNlID0gYmluZm87CiAgZmZvZC5jYW5kaWRhdGVzID0gTlVMTF9UUkVFOwogIGZmb2QucGF0aCA9IFZFQ19hbGxvYyAodHJlZSwgMzApOwoKICBkZnNfd2Fsa19hbGwgKGRlcml2ZWQsIGRmc19maW5kX2ZpbmFsX292ZXJyaWRlcl9wcmUsCgkJZGZzX2ZpbmRfZmluYWxfb3ZlcnJpZGVyX3Bvc3QsICZmZm9kKTsKCiAgVkVDX2ZyZWUgKHRyZWUsIGZmb2QucGF0aCk7CiAgCiAgLyogSWYgdGhlcmUgd2FzIG5vIHdpbm5lciwgaXNzdWUgYW4gZXJyb3IgbWVzc2FnZS4gICovCiAgaWYgKCFmZm9kLmNhbmRpZGF0ZXMgfHwgVFJFRV9DSEFJTiAoZmZvZC5jYW5kaWRhdGVzKSkKICAgIHsKICAgICAgZXJyb3IgKCJubyB1bmlxdWUgZmluYWwgb3ZlcnJpZGVyIGZvciAlcUQgaW4gJXFUIiwgZm4sIAoJICAgICBCSU5GT19UWVBFIChkZXJpdmVkKSk7CiAgICAgIHJldHVybiBlcnJvcl9tYXJrX25vZGU7CiAgICB9CgogIHJldHVybiBmZm9kLmNhbmRpZGF0ZXM7Cn0KCi8qIFJldHVybiB0aGUgaW5kZXggb2YgdGhlIHZjYWxsIG9mZnNldCBmb3IgRk4gd2hlbiBUWVBFIGlzIHVzZWQgYXMgYQogICB2aXJ0dWFsIGJhc2UuICAqLwoKc3RhdGljIHRyZWUKZ2V0X3ZjYWxsX2luZGV4ICh0cmVlIGZuLCB0cmVlIHR5cGUpCnsKICBWRUMgKHRyZWVfcGFpcl9zKSAqaW5kaWNlcyA9IENMQVNTVFlQRV9WQ0FMTF9JTkRJQ0VTICh0eXBlKTsKICB0cmVlX3BhaXJfcCBwOwogIHVuc2lnbmVkIGl4OwoKICBmb3IgKGl4ID0gMDsgVkVDX2l0ZXJhdGUgKHRyZWVfcGFpcl9zLCBpbmRpY2VzLCBpeCwgcCk7IGl4KyspCiAgICBpZiAoKERFQ0xfREVTVFJVQ1RPUl9QIChmbikgJiYgREVDTF9ERVNUUlVDVE9SX1AgKHAtPnB1cnBvc2UpKQoJfHwgc2FtZV9zaWduYXR1cmVfcCAoZm4sIHAtPnB1cnBvc2UpKQogICAgICByZXR1cm4gcC0+dmFsdWU7CgogIC8qIFRoZXJlIHNob3VsZCBhbHdheXMgYmUgYW4gYXBwcm9wcmlhdGUgaW5kZXguICAqLwogIGdjY191bnJlYWNoYWJsZSAoKTsKfQoKLyogVXBkYXRlIGFuIGVudHJ5IGluIHRoZSB2dGFibGUgZm9yIEJJTkZPLCB3aGljaCBpcyBpbiB0aGUgaGllcmFyY2h5CiAgIGRvbWluYXRlZCBieSBULiAgRk4gaGFzIGJlZW4gb3ZlcnJpZGRlbiBpbiBCSU5GTzsgVklSVFVBTFMgcG9pbnRzIHRvIHRoZQogICBjb3JyZXNwb25kaW5nIHBvc2l0aW9uIGluIHRoZSBCSU5GT19WSVJUVUFMUyBsaXN0LiAgKi8KCnN0YXRpYyB2b2lkCnVwZGF0ZV92dGFibGVfZW50cnlfZm9yX2ZuICh0cmVlIHQsIHRyZWUgYmluZm8sIHRyZWUgZm4sIHRyZWUqIHZpcnR1YWxzLAoJCQkgICAgdW5zaWduZWQgaXgpCnsKICB0cmVlIGI7CiAgdHJlZSBvdmVycmlkZXI7CiAgdHJlZSBkZWx0YTsKICB0cmVlIHZpcnR1YWxfYmFzZTsKICB0cmVlIGZpcnN0X2RlZm47CiAgdHJlZSBvdmVycmlkZXJfZm4sIG92ZXJyaWRlcl90YXJnZXQ7CiAgdHJlZSB0YXJnZXRfZm4gPSBERUNMX1RIVU5LX1AgKGZuKSA/IFRIVU5LX1RBUkdFVCAoZm4pIDogZm47CiAgdHJlZSBvdmVyX3JldHVybiwgYmFzZV9yZXR1cm47CiAgYm9vbCBsb3N0ID0gZmFsc2U7CgogIC8qIEZpbmQgdGhlIG5lYXJlc3QgcHJpbWFyeSBiYXNlIChwb3NzaWJseSBiaW5mbyBpdHNlbGYpIHdoaWNoIGRlZmluZXMKICAgICB0aGlzIGZ1bmN0aW9uOyB0aGlzIGlzIHRoZSBjbGFzcyB0aGUgY2FsbGVyIHdpbGwgY29udmVydCB0byB3aGVuCiAgICAgY2FsbGluZyBGTiB0aHJvdWdoIEJJTkZPLiAgKi8KICBmb3IgKGIgPSBiaW5mbzsgOyBiID0gZ2V0X3ByaW1hcnlfYmluZm8gKGIpKQogICAgewogICAgICBnY2NfYXNzZXJ0IChiKTsKICAgICAgaWYgKGxvb2tfZm9yX292ZXJyaWRlc19oZXJlIChCSU5GT19UWVBFIChiKSwgdGFyZ2V0X2ZuKSkKCWJyZWFrOwoKICAgICAgLyogVGhlIG5lYXJlc3QgZGVmaW5pdGlvbiBpcyBmcm9tIGEgbG9zdCBwcmltYXJ5LiAgKi8KICAgICAgaWYgKEJJTkZPX0xPU1RfUFJJTUFSWV9QIChiKSkKCWxvc3QgPSB0cnVlOwogICAgfQogIGZpcnN0X2RlZm4gPSBiOwoKICAvKiBGaW5kIHRoZSBmaW5hbCBvdmVycmlkZXIuICAqLwogIG92ZXJyaWRlciA9IGZpbmRfZmluYWxfb3ZlcnJpZGVyIChUWVBFX0JJTkZPICh0KSwgYiwgdGFyZ2V0X2ZuKTsKICBpZiAob3ZlcnJpZGVyID09IGVycm9yX21hcmtfbm9kZSkKICAgIHJldHVybjsKICBvdmVycmlkZXJfdGFyZ2V0ID0gb3ZlcnJpZGVyX2ZuID0gVFJFRV9QVVJQT1NFIChvdmVycmlkZXIpOwogIAogIC8qIENoZWNrIGZvciBhZGp1c3RpbmcgY292YXJpYW50IHJldHVybiB0eXBlcy4gICovCiAgb3Zlcl9yZXR1cm4gPSBUUkVFX1RZUEUgKFRSRUVfVFlQRSAob3ZlcnJpZGVyX3RhcmdldCkpOwogIGJhc2VfcmV0dXJuID0gVFJFRV9UWVBFIChUUkVFX1RZUEUgKHRhcmdldF9mbikpOwogIAogIGlmIChQT0lOVEVSX1RZUEVfUCAob3Zlcl9yZXR1cm4pCiAgICAgICYmIFRSRUVfQ09ERSAob3Zlcl9yZXR1cm4pID09IFRSRUVfQ09ERSAoYmFzZV9yZXR1cm4pCiAgICAgICYmIENMQVNTX1RZUEVfUCAoVFJFRV9UWVBFIChvdmVyX3JldHVybikpCiAgICAgICYmIENMQVNTX1RZUEVfUCAoVFJFRV9UWVBFIChiYXNlX3JldHVybikpKQogICAgewogICAgICAvKiBJZiBGTiBpcyBhIGNvdmFyaWFudCB0aHVuaywgd2UgbXVzdCBmaWd1cmUgb3V0IHRoZSBhZGp1c3RtZW50CiAgICAgICAgIHRvIHRoZSBmaW5hbCBiYXNlIEZOIHdhcyBjb252ZXJ0aW5nIHRvLiBBcyBPVkVSUklERVJfVEFSR0VUIG1pZ2h0CiAgICAgICAgIGFsc28gYmUgY29udmVydGluZyB0byB0aGUgcmV0dXJuIHR5cGUgb2YgRk4sIHdlIGhhdmUgdG8KICAgICAgICAgY29tYmluZSB0aGUgdHdvIGNvbnZlcnNpb25zIGhlcmUuICAqLwogICAgICB0cmVlIGZpeGVkX29mZnNldCwgdmlydHVhbF9vZmZzZXQ7CgogICAgICBvdmVyX3JldHVybiA9IFRSRUVfVFlQRSAob3Zlcl9yZXR1cm4pOwogICAgICBiYXNlX3JldHVybiA9IFRSRUVfVFlQRSAoYmFzZV9yZXR1cm4pOwogICAgICAKICAgICAgaWYgKERFQ0xfVEhVTktfUCAoZm4pKQoJewoJICBnY2NfYXNzZXJ0IChERUNMX1JFU1VMVF9USFVOS19QIChmbikpOwoJICBmaXhlZF9vZmZzZXQgPSBzc2l6ZV9pbnQgKFRIVU5LX0ZJWEVEX09GRlNFVCAoZm4pKTsKCSAgdmlydHVhbF9vZmZzZXQgPSBUSFVOS19WSVJUVUFMX09GRlNFVCAoZm4pOwoJfQogICAgICBlbHNlCglmaXhlZF9vZmZzZXQgPSB2aXJ0dWFsX29mZnNldCA9IE5VTExfVFJFRTsKCiAgICAgIGlmICh2aXJ0dWFsX29mZnNldCkKCS8qIEZpbmQgdGhlIGVxdWl2YWxlbnQgYmluZm8gd2l0aGluIHRoZSByZXR1cm4gdHlwZSBvZiB0aGUKCSAgIG92ZXJyaWRpbmcgZnVuY3Rpb24uIFdlIHdpbGwgd2FudCB0aGUgdmJhc2Ugb2Zmc2V0IGZyb20KCSAgIHRoZXJlLiAgKi8KCXZpcnR1YWxfb2Zmc2V0ID0gYmluZm9fZm9yX3ZiYXNlIChCSU5GT19UWVBFICh2aXJ0dWFsX29mZnNldCksCgkJCQkJICBvdmVyX3JldHVybik7CiAgICAgIGVsc2UgaWYgKCFzYW1lX3R5cGVfaWdub3JpbmdfdG9wX2xldmVsX3F1YWxpZmllcnNfcAoJICAgICAgIChvdmVyX3JldHVybiwgYmFzZV9yZXR1cm4pKQoJewoJICAvKiBUaGVyZSB3YXMgbm8gZXhpc3RpbmcgdmlydHVhbCB0aHVuayAod2hpY2ggdGFrZXMKCSAgICAgcHJlY2VkZW5jZSkuICBTbyBmaW5kIHRoZSBiaW5mbyBvZiB0aGUgYmFzZSBmdW5jdGlvbidzCgkgICAgIHJldHVybiB0eXBlIHdpdGhpbiB0aGUgb3ZlcnJpZGluZyBmdW5jdGlvbidzIHJldHVybiB0eXBlLgoJICAgICBXZSBjYW5ub3QgY2FsbCBsb29rdXAgYmFzZSBoZXJlLCBiZWNhdXNlIHdlJ3JlIGluc2lkZSBhCgkgICAgIGRmc193YWxrLCBhbmQgd2lsbCB0aGVyZWZvcmUgY2xvYmJlciB0aGUgQklORk9fTUFSS0VECgkgICAgIGZsYWdzLiAgRm9ydHVuYXRlbHkgd2Uga25vdyB0aGUgY292YXJpYW5jeSBpcyB2YWxpZCAoaXQKCSAgICAgaGFzIGFscmVhZHkgYmVlbiBjaGVja2VkKSwgc28gd2UgY2FuIGp1c3QgaXRlcmF0ZSBhbG9uZwoJICAgICB0aGUgYmluZm9zLCB3aGljaCBoYXZlIGJlZW4gY2hhaW5lZCBpbiBpbmhlcml0YW5jZSBncmFwaAoJICAgICBvcmRlci4gIE9mIGNvdXJzZSBpdCBpcyBsYW1lIHRoYXQgd2UgaGF2ZSB0byByZXBlYXQgdGhlCgkgICAgIHNlYXJjaCBoZXJlIGFueXdheSAtLSB3ZSBzaG91bGQgcmVhbGx5IGJlIGNhY2hpbmcgcGllY2VzCgkgICAgIG9mIHRoZSB2dGFibGUgYW5kIGF2b2lkaW5nIHRoaXMgcmVwZWF0ZWQgd29yay4gICovCgkgIHRyZWUgdGh1bmtfYmluZm8sIGJhc2VfYmluZm87CgoJICAvKiBGaW5kIHRoZSBiYXNlIGJpbmZvIHdpdGhpbiB0aGUgb3ZlcnJpZGluZyBmdW5jdGlvbidzCgkgICAgIHJldHVybiB0eXBlLiAgV2Ugd2lsbCBhbHdheXMgZmluZCBhIHRodW5rX2JpbmZvLCBleGNlcHQKCSAgICAgd2hlbiB0aGUgY292YXJpYW5jeSBpcyBpbnZhbGlkICh3aGljaCB3ZSB3aWxsIGhhdmUKCSAgICAgYWxyZWFkeSBkaWFnbm9zZWQpLiAgKi8KCSAgZm9yIChiYXNlX2JpbmZvID0gVFlQRV9CSU5GTyAoYmFzZV9yZXR1cm4pLAoJICAgICAgIHRodW5rX2JpbmZvID0gVFlQRV9CSU5GTyAob3Zlcl9yZXR1cm4pOwoJICAgICAgIHRodW5rX2JpbmZvOwoJICAgICAgIHRodW5rX2JpbmZvID0gVFJFRV9DSEFJTiAodGh1bmtfYmluZm8pKQoJICAgIGlmIChTQU1FX0JJTkZPX1RZUEVfUCAoQklORk9fVFlQRSAodGh1bmtfYmluZm8pLAoJCQkJICAgQklORk9fVFlQRSAoYmFzZV9iaW5mbykpKQoJICAgICAgYnJlYWs7CgkgIAoJICAvKiBTZWUgaWYgdmlydHVhbCBpbmhlcml0YW5jZSBpcyBpbnZvbHZlZC4gICovCgkgIGZvciAodmlydHVhbF9vZmZzZXQgPSB0aHVua19iaW5mbzsKCSAgICAgICB2aXJ0dWFsX29mZnNldDsKCSAgICAgICB2aXJ0dWFsX29mZnNldCA9IEJJTkZPX0lOSEVSSVRBTkNFX0NIQUlOICh2aXJ0dWFsX29mZnNldCkpCgkgICAgaWYgKEJJTkZPX1ZJUlRVQUxfUCAodmlydHVhbF9vZmZzZXQpKQoJICAgICAgYnJlYWs7CgkgIAoJICBpZiAodmlydHVhbF9vZmZzZXQKCSAgICAgIHx8ICh0aHVua19iaW5mbyAmJiAhQklORk9fT0ZGU0VUX1pFUk9QICh0aHVua19iaW5mbykpKQoJICAgIHsKCSAgICAgIHRyZWUgb2Zmc2V0ID0gY29udmVydCAoc3NpemV0eXBlLCBCSU5GT19PRkZTRVQgKHRodW5rX2JpbmZvKSk7CgoJICAgICAgaWYgKHZpcnR1YWxfb2Zmc2V0KQoJCXsKCQkgIC8qIFdlIGNvbnZlcnQgdmlhIHZpcnR1YWwgYmFzZS4gIEFkanVzdCB0aGUgZml4ZWQKCQkgICAgIG9mZnNldCB0byBiZSBmcm9tIHRoZXJlLiAgKi8KCQkgIG9mZnNldCA9IHNpemVfZGlmZm9wCgkJICAgIChvZmZzZXQsIGNvbnZlcnQKCQkgICAgIChzc2l6ZXR5cGUsIEJJTkZPX09GRlNFVCAodmlydHVhbF9vZmZzZXQpKSk7CgkJfQoJICAgICAgaWYgKGZpeGVkX29mZnNldCkKCQkvKiBUaGVyZSB3YXMgYW4gZXhpc3RpbmcgZml4ZWQgb2Zmc2V0LCB0aGlzIG11c3QgYmUKCQkgICBmcm9tIHRoZSBiYXNlIGp1c3QgY29udmVydGVkIHRvLCBhbmQgdGhlIGJhc2UgdGhlCgkJICAgRk4gd2FzIHRodW5raW5nIHRvLiAgKi8KCQlmaXhlZF9vZmZzZXQgPSBzaXplX2Jpbm9wIChQTFVTX0VYUFIsIGZpeGVkX29mZnNldCwgb2Zmc2V0KTsKCSAgICAgIGVsc2UKCQlmaXhlZF9vZmZzZXQgPSBvZmZzZXQ7CgkgICAgfQoJfQogICAgICAKICAgICAgaWYgKGZpeGVkX29mZnNldCB8fCB2aXJ0dWFsX29mZnNldCkKCS8qIFJlcGxhY2UgdGhlIG92ZXJyaWRpbmcgZnVuY3Rpb24gd2l0aCBhIGNvdmFyaWFudCB0aHVuay4gIFdlCgkgICB3aWxsIGVtaXQgdGhlIG92ZXJyaWRpbmcgZnVuY3Rpb24gaW4gaXRzIG93biBzbG90IGFzCgkgICB3ZWxsLiAgKi8KCW92ZXJyaWRlcl9mbiA9IG1ha2VfdGh1bmsgKG92ZXJyaWRlcl90YXJnZXQsIC8qdGhpc19hZGp1c3Rpbmc9Ki8wLAoJCQkJICAgZml4ZWRfb2Zmc2V0LCB2aXJ0dWFsX29mZnNldCk7CiAgICB9CiAgZWxzZQogICAgZ2NjX2Fzc2VydCAoIURFQ0xfVEhVTktfUCAoZm4pKTsKICAKICAvKiBBc3N1bWUgdGhhdCB3ZSB3aWxsIHByb2R1Y2UgYSB0aHVuayB0aGF0IGNvbnZlcnQgYWxsIHRoZSB3YXkgdG8KICAgICB0aGUgZmluYWwgb3ZlcnJpZGVyLCBhbmQgbm90IHRvIGFuIGludGVybWVkaWF0ZSB2aXJ0dWFsIGJhc2UuICAqLwogIHZpcnR1YWxfYmFzZSA9IE5VTExfVFJFRTsKCiAgLyogU2VlIGlmIHdlIGNhbiBjb252ZXJ0IHRvIGFuIGludGVybWVkaWF0ZSB2aXJ0dWFsIGJhc2UgZmlyc3QsIGFuZCB0aGVuCiAgICAgdXNlIHRoZSB2Y2FsbCBvZmZzZXQgbG9jYXRlZCB0aGVyZSB0byBmaW5pc2ggdGhlIGNvbnZlcnNpb24uICAqLwogIGZvciAoOyBiOyBiID0gQklORk9fSU5IRVJJVEFOQ0VfQ0hBSU4gKGIpKQogICAgewogICAgICAvKiBJZiB3ZSBmaW5kIHRoZSBmaW5hbCBvdmVycmlkZXIsIHRoZW4gd2UgY2FuIHN0b3AKCSB3YWxraW5nLiAgKi8KICAgICAgaWYgKFNBTUVfQklORk9fVFlQRV9QIChCSU5GT19UWVBFIChiKSwKCQkJICAgICBCSU5GT19UWVBFIChUUkVFX1ZBTFVFIChvdmVycmlkZXIpKSkpCglicmVhazsKCiAgICAgIC8qIElmIHdlIGZpbmQgYSB2aXJ0dWFsIGJhc2UsIGFuZCB3ZSBoYXZlbid0IHlldCBmb3VuZCB0aGUKCSBvdmVycmlkZXIsIHRoZW4gdGhlcmUgaXMgYSB2aXJ0dWFsIGJhc2UgYmV0d2VlbiB0aGUKCSBkZWNsYXJpbmcgYmFzZSAoZmlyc3RfZGVmbikgYW5kIHRoZSBmaW5hbCBvdmVycmlkZXIuICAqLwogICAgICBpZiAoQklORk9fVklSVFVBTF9QIChiKSkKCXsKCSAgdmlydHVhbF9iYXNlID0gYjsKCSAgYnJlYWs7Cgl9CiAgICB9CgogIGlmIChvdmVycmlkZXJfZm4gIT0gb3ZlcnJpZGVyX3RhcmdldCAmJiAhdmlydHVhbF9iYXNlKQogICAgewogICAgICAvKiBUaGUgQUJJIHNwZWNpZmllcyB0aGF0IGEgY292YXJpYW50IHRodW5rIGluY2x1ZGVzIGEgbWFuZ2xpbmcKICAgCSBmb3IgYSB0aGlzIHBvaW50ZXIgYWRqdXN0bWVudC4gIFRoaXMtYWRqdXN0aW5nIHRodW5rcyB0aGF0CiAgIAkgb3ZlcnJpZGUgYSBmdW5jdGlvbiBmcm9tIGEgdmlydHVhbCBiYXNlIGhhdmUgYSB2Y2FsbAogICAJIGFkanVzdG1lbnQuICBXaGVuIHRoZSB2aXJ0dWFsIGJhc2UgaW4gcXVlc3Rpb24gaXMgYSBwcmltYXJ5CiAgIAkgdmlydHVhbCBiYXNlLCB3ZSBrbm93IHRoZSBhZGp1c3RtZW50cyBhcmUgemVybywgKGFuZCBpbiB0aGUKICAgCSBub24tY292YXJpYW50IGNhc2UsIHdlIHdvdWxkIG5vdCB1c2UgdGhlIHRodW5rKS4KICAgCSBVbmZvcnR1bmF0ZWx5IHdlIGRpZG4ndCBub3RpY2UgdGhpcyBjb3VsZCBoYXBwZW4sIHdoZW4KICAgCSBkZXNpZ25pbmcgdGhlIEFCSSBhbmQgc28gbmV2ZXIgbWFuZGF0ZWQgdGhhdCBzdWNoIGEgY292YXJpYW50CiAgIAkgdGh1bmsgc2hvdWxkIGJlIGVtaXR0ZWQuICBCZWNhdXNlIHdlIG11c3QgdXNlIHRoZSBBQkkgbWFuZGF0ZWQKICAgCSBuYW1lLCB3ZSBtdXN0IGNvbnRpbnVlIHNlYXJjaGluZyBmcm9tIHRoZSBiaW5mbyB3aGVyZSB3ZQogICAJIGZvdW5kIHRoZSBtb3N0IHJlY2VudCBkZWZpbml0aW9uIG9mIHRoZSBmdW5jdGlvbiwgdG93YXJkcyB0aGUKICAgCSBwcmltYXJ5IGJpbmZvIHdoaWNoIGZpcnN0IGludHJvZHVjZWQgdGhlIGZ1bmN0aW9uIGludG8gdGhlCiAgIAkgdnRhYmxlLiAgSWYgdGhhdCBlbnRlcnMgYSB2aXJ0dWFsIGJhc2UsIHdlIG11c3QgdXNlIGEgdmNhbGwKICAgCSB0aGlzLWFkanVzdGluZyB0aHVuay4gIEJsZWFoISAqLwogICAgICB0cmVlIHByb2JlID0gZmlyc3RfZGVmbjsKCiAgICAgIHdoaWxlICgocHJvYmUgPSBnZXRfcHJpbWFyeV9iaW5mbyAocHJvYmUpKQoJICAgICAmJiAodW5zaWduZWQpIGxpc3RfbGVuZ3RoIChCSU5GT19WSVJUVUFMUyAocHJvYmUpKSA+IGl4KQoJaWYgKEJJTkZPX1ZJUlRVQUxfUCAocHJvYmUpKQoJICB2aXJ0dWFsX2Jhc2UgPSBwcm9iZTsKICAgICAgCiAgICAgIGlmICh2aXJ0dWFsX2Jhc2UpCgkvKiBFdmVuIGlmIHdlIGZpbmQgYSB2aXJ0dWFsIGJhc2UsIHRoZSBjb3JyZWN0IGRlbHRhIGlzCgkgICBiZXR3ZWVuIHRoZSBvdmVycmlkZXIgYW5kIHRoZSBiaW5mbyB3ZSdyZSBidWlsZGluZyBhIHZ0YWJsZQoJICAgZm9yLiAgKi8KCWdvdG8gdmlydHVhbF9jb3ZhcmlhbnQ7CiAgICB9CiAgCiAgLyogQ29tcHV0ZSB0aGUgY29uc3RhbnQgYWRqdXN0bWVudCB0byB0aGUgYHRoaXMnIHBvaW50ZXIuICBUaGUKICAgICBgdGhpcycgcG9pbnRlciwgd2hlbiB0aGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCwgd2lsbCBwb2ludCBhdCBCSU5GTwogICAgIChvciBvbmUgb2YgaXRzIHByaW1hcnkgYmFzZXMsIHdoaWNoIGFyZSBhdCB0aGUgc2FtZSBvZmZzZXQpLiAgKi8KICBpZiAodmlydHVhbF9iYXNlKQogICAgLyogVGhlIGB0aGlzJyBwb2ludGVyIG5lZWRzIHRvIGJlIGFkanVzdGVkIGZyb20gdGhlIGRlY2xhcmF0aW9uIHRvCiAgICAgICB0aGUgbmVhcmVzdCB2aXJ0dWFsIGJhc2UuICAqLwogICAgZGVsdGEgPSBzaXplX2RpZmZvcCAoY29udmVydCAoc3NpemV0eXBlLCBCSU5GT19PRkZTRVQgKHZpcnR1YWxfYmFzZSkpLAoJCQkgY29udmVydCAoc3NpemV0eXBlLCBCSU5GT19PRkZTRVQgKGZpcnN0X2RlZm4pKSk7CiAgZWxzZSBpZiAobG9zdCkKICAgIC8qIElmIHRoZSBuZWFyZXN0IGRlZmluaXRpb24gaXMgaW4gYSBsb3N0IHByaW1hcnksIHdlIGRvbid0IG5lZWQgYW4KICAgICAgIGVudHJ5IGluIG91ciB2dGFibGUuICBFeGNlcHQgcG9zc2libHkgaW4gYSBjb25zdHJ1Y3RvciB2dGFibGUsCiAgICAgICBpZiB3ZSBoYXBwZW4gdG8gZ2V0IG91ciBwcmltYXJ5IGJhY2suICBJbiB0aGF0IGNhc2UsIHRoZSBvZmZzZXQKICAgICAgIHdpbGwgYmUgemVybywgYXMgaXQgd2lsbCBiZSBhIHByaW1hcnkgYmFzZS4gICovCiAgICBkZWx0YSA9IHNpemVfemVyb19ub2RlOwogIGVsc2UKICAgIC8qIFRoZSBgdGhpcycgcG9pbnRlciBuZWVkcyB0byBiZSBhZGp1c3RlZCBmcm9tIHBvaW50aW5nIHRvCiAgICAgICBCSU5GTyB0byBwb2ludGluZyBhdCB0aGUgYmFzZSB3aGVyZSB0aGUgZmluYWwgb3ZlcnJpZGVyCiAgICAgICBhcHBlYXJzLiAgKi8KICAgIHZpcnR1YWxfY292YXJpYW50OgogICAgZGVsdGEgPSBzaXplX2RpZmZvcCAoY29udmVydCAoc3NpemV0eXBlLAoJCQkJICBCSU5GT19PRkZTRVQgKFRSRUVfVkFMVUUgKG92ZXJyaWRlcikpKSwKCQkJIGNvbnZlcnQgKHNzaXpldHlwZSwgQklORk9fT0ZGU0VUIChiaW5mbykpKTsKCiAgbW9kaWZ5X3Z0YWJsZV9lbnRyeSAodCwgYmluZm8sIG92ZXJyaWRlcl9mbiwgZGVsdGEsIHZpcnR1YWxzKTsKCiAgaWYgKHZpcnR1YWxfYmFzZSkKICAgIEJWX1ZDQUxMX0lOREVYICgqdmlydHVhbHMpIAogICAgICA9IGdldF92Y2FsbF9pbmRleCAob3ZlcnJpZGVyX3RhcmdldCwgQklORk9fVFlQRSAodmlydHVhbF9iYXNlKSk7CiAgZWxzZQogICAgQlZfVkNBTExfSU5ERVggKCp2aXJ0dWFscykgPSBOVUxMX1RSRUU7Cn0KCi8qIENhbGxlZCBmcm9tIG1vZGlmeV9hbGxfdnRhYmxlcyB2aWEgZGZzX3dhbGsuICAqLwoKc3RhdGljIHRyZWUKZGZzX21vZGlmeV92dGFibGVzICh0cmVlIGJpbmZvLCB2b2lkKiBkYXRhKQp7CiAgdHJlZSB0ID0gKHRyZWUpIGRhdGE7CiAgdHJlZSB2aXJ0dWFsczsKICB0cmVlIG9sZF92aXJ0dWFsczsKICB1bnNpZ25lZCBpeDsKCiAgaWYgKCFUWVBFX0NPTlRBSU5TX1ZQVFJfUCAoQklORk9fVFlQRSAoYmluZm8pKSkKICAgIC8qIEEgYmFzZSB3aXRob3V0IGEgdnRhYmxlIG5lZWRzIG5vIG1vZGlmaWNhdGlvbiwgYW5kIGl0cyBiYXNlcwogICAgICAgYXJlIHVuaW50ZXJlc3RpbmcuICAqLwogICAgcmV0dXJuIGRmc19za2lwX2Jhc2VzOwogIAogIGlmIChTQU1FX0JJTkZPX1RZUEVfUCAoQklORk9fVFlQRSAoYmluZm8pLCB0KQogICAgICAmJiAhQ0xBU1NUWVBFX0hBU19QUklNQVJZX0JBU0VfUCAodCkpCiAgICAvKiBEb24ndCBkbyB0aGUgcHJpbWFyeSB2dGFibGUsIGlmIGl0J3MgbmV3LiAgKi8KICAgIHJldHVybiBOVUxMX1RSRUU7CgogIGlmIChCSU5GT19QUklNQVJZX1AgKGJpbmZvKSAmJiAhQklORk9fVklSVFVBTF9QIChiaW5mbykpCiAgICAvKiBUaGVyZSdzIG5vIG5lZWQgdG8gbW9kaWZ5IHRoZSB2dGFibGUgZm9yIGEgbm9uLXZpcnR1YWwgcHJpbWFyeQogICAgICAgYmFzZTsgd2UncmUgbm90IGdvaW5nIHRvIHVzZSB0aGF0IHZ0YWJsZSBhbnlob3cuICBXZSBkbyBzdGlsbAogICAgICAgbmVlZCB0byBkbyB0aGlzIGZvciB2aXJ0dWFsIHByaW1hcnkgYmFzZXMsIGFzIHRoZXkgY291bGQgYmVjb21lCiAgICAgICBub24tcHJpbWFyeSBpbiBhIGNvbnN0cnVjdGlvbiB2dGFibGUuICAqLwogICAgcmV0dXJuIE5VTExfVFJFRTsKCiAgbWFrZV9uZXdfdnRhYmxlICh0LCBiaW5mbyk7CiAgICAgIAogIC8qIE5vdywgZ28gdGhyb3VnaCBlYWNoIG9mIHRoZSB2aXJ0dWFsIGZ1bmN0aW9ucyBpbiB0aGUgdmlydHVhbAogICAgIGZ1bmN0aW9uIHRhYmxlIGZvciBCSU5GTy4gIEZpbmQgdGhlIGZpbmFsIG92ZXJyaWRlciwgYW5kIHVwZGF0ZQogICAgIHRoZSBCSU5GT19WSVJUVUFMUyBsaXN0IGFwcHJvcHJpYXRlbHkuICAqLwogIGZvciAoaXggPSAwLCB2aXJ0dWFscyA9IEJJTkZPX1ZJUlRVQUxTIChiaW5mbyksCgkgb2xkX3ZpcnR1YWxzID0gQklORk9fVklSVFVBTFMgKFRZUEVfQklORk8gKEJJTkZPX1RZUEUgKGJpbmZvKSkpOwogICAgICAgdmlydHVhbHM7CiAgICAgICBpeCsrLCB2aXJ0dWFscyA9IFRSRUVfQ0hBSU4gKHZpcnR1YWxzKSwKCSBvbGRfdmlydHVhbHMgPSBUUkVFX0NIQUlOIChvbGRfdmlydHVhbHMpKQogICAgdXBkYXRlX3Z0YWJsZV9lbnRyeV9mb3JfZm4gKHQsIAoJCQkJYmluZm8sIAoJCQkJQlZfRk4gKG9sZF92aXJ0dWFscyksCgkJCQkmdmlydHVhbHMsIGl4KTsKCiAgcmV0dXJuIE5VTExfVFJFRTsKfQoKLyogVXBkYXRlIGFsbCBvZiB0aGUgcHJpbWFyeSBhbmQgc2Vjb25kYXJ5IHZ0YWJsZXMgZm9yIFQuICBDcmVhdGUgbmV3CiAgIHZ0YWJsZXMgYXMgcmVxdWlyZWQsIGFuZCBpbml0aWFsaXplIHRoZWlyIFJUVEkgaW5mb3JtYXRpb24uICBFYWNoCiAgIG9mIHRoZSBmdW5jdGlvbnMgaW4gVklSVFVBTFMgaXMgZGVjbGFyZWQgaW4gVCBhbmQgbWF5IG92ZXJyaWRlIGEKICAgdmlydHVhbCBmdW5jdGlvbiBmcm9tIGEgYmFzZSBjbGFzczsgZmluZCBhbmQgbW9kaWZ5IHRoZSBhcHByb3ByaWF0ZQogICBlbnRyaWVzIHRvIHBvaW50IHRvIHRoZSBvdmVycmlkaW5nIGZ1bmN0aW9ucy4gIFJldHVybnMgYSBsaXN0LCBpbgogICBkZWNsYXJhdGlvbiBvcmRlciwgb2YgdGhlIHZpcnR1YWwgZnVuY3Rpb25zIHRoYXQgYXJlIGRlY2xhcmVkIGluIFQsCiAgIGJ1dCBkbyBub3QgYXBwZWFyIGluIHRoZSBwcmltYXJ5IGJhc2UgY2xhc3MgdnRhYmxlLCBhbmQgd2hpY2gKICAgc2hvdWxkIHRoZXJlZm9yZSBiZSBhcHBlbmRlZCB0byB0aGUgZW5kIG9mIHRoZSB2dGFibGUgZm9yIFQuICAqLwoKc3RhdGljIHRyZWUKbW9kaWZ5X2FsbF92dGFibGVzICh0cmVlIHQsIHRyZWUgdmlydHVhbHMpCnsKICB0cmVlIGJpbmZvID0gVFlQRV9CSU5GTyAodCk7CiAgdHJlZSAqZm5zcDsKCiAgLyogVXBkYXRlIGFsbCBvZiB0aGUgdnRhYmxlcy4gICovCiAgZGZzX3dhbGtfb25jZSAoYmluZm8sIGRmc19tb2RpZnlfdnRhYmxlcywgTlVMTCwgdCk7CgogIC8qIEFkZCB2aXJ0dWFsIGZ1bmN0aW9ucyBub3QgYWxyZWFkeSBpbiBvdXIgcHJpbWFyeSB2dGFibGUuIFRoZXNlCiAgICAgd2lsbCBiZSBib3RoIHRob3NlIGludHJvZHVjZWQgYnkgdGhpcyBjbGFzcywgYW5kIHRob3NlIG92ZXJyaWRkZW4KICAgICBmcm9tIHNlY29uZGFyeSBiYXNlcy4gIEl0IGRvZXMgbm90IGluY2x1ZGUgdmlydHVhbHMgbWVyZWx5CiAgICAgaW5oZXJpdGVkIGZyb20gc2Vjb25kYXJ5IGJhc2VzLiAgKi8KICBmb3IgKGZuc3AgPSAmdmlydHVhbHM7ICpmbnNwOyApCiAgICB7CiAgICAgIHRyZWUgZm4gPSBUUkVFX1ZBTFVFICgqZm5zcCk7CgogICAgICBpZiAoIXZhbHVlX21lbWJlciAoZm4sIEJJTkZPX1ZJUlRVQUxTIChiaW5mbykpCgkgIHx8IERFQ0xfVklOREVYIChmbikgPT0gZXJyb3JfbWFya19ub2RlKQoJewoJICAvKiBXZSBkb24ndCBuZWVkIHRvIGFkanVzdCB0aGUgYHRoaXMnIHBvaW50ZXIgd2hlbgoJICAgICBjYWxsaW5nIHRoaXMgZnVuY3Rpb24uICAqLwoJICBCVl9ERUxUQSAoKmZuc3ApID0gaW50ZWdlcl96ZXJvX25vZGU7CgkgIEJWX1ZDQUxMX0lOREVYICgqZm5zcCkgPSBOVUxMX1RSRUU7CgoJICAvKiBUaGlzIGlzIGEgZnVuY3Rpb24gbm90IGFscmVhZHkgaW4gb3VyIHZ0YWJsZS4gIEtlZXAgaXQuICAqLwoJICBmbnNwID0gJlRSRUVfQ0hBSU4gKCpmbnNwKTsKCX0KICAgICAgZWxzZQoJLyogV2UndmUgYWxyZWFkeSBnb3QgYW4gZW50cnkgZm9yIHRoaXMgZnVuY3Rpb24uICBTa2lwIGl0LiAgKi8KCSpmbnNwID0gVFJFRV9DSEFJTiAoKmZuc3ApOwogICAgfQoKICByZXR1cm4gdmlydHVhbHM7Cn0KCi8qIEdldCB0aGUgYmFzZSB2aXJ0dWFsIGZ1bmN0aW9uIGRlY2xhcmF0aW9ucyBpbiBUIHRoYXQgaGF2ZSB0aGUKICAgaW5kaWNhdGVkIE5BTUUuICAqLwoKc3RhdGljIHRyZWUKZ2V0X2Jhc2VmbmRlY2xzICh0cmVlIG5hbWUsIHRyZWUgdCkKewogIHRyZWUgbWV0aG9kczsKICB0cmVlIGJhc2VfZm5kZWNscyA9IE5VTExfVFJFRTsKICBpbnQgbl9iYXNlY2xhc3NlcyA9IEJJTkZPX05fQkFTRV9CSU5GT1MgKFRZUEVfQklORk8gKHQpKTsKICBpbnQgaTsKCiAgLyogRmluZCB2aXJ0dWFsIGZ1bmN0aW9ucyBpbiBUIHdpdGggdGhlIGluZGljYXRlZCBOQU1FLiAgKi8KICBpID0gbG9va3VwX2ZuZmllbGRzXzEgKHQsIG5hbWUpOwogIGlmIChpICE9IC0xKQogICAgZm9yIChtZXRob2RzID0gVkVDX2luZGV4ICh0cmVlLCBDTEFTU1RZUEVfTUVUSE9EX1ZFQyAodCksIGkpOwoJIG1ldGhvZHM7CgkgbWV0aG9kcyA9IE9WTF9ORVhUIChtZXRob2RzKSkKICAgICAgewoJdHJlZSBtZXRob2QgPSBPVkxfQ1VSUkVOVCAobWV0aG9kcyk7CgoJaWYgKFRSRUVfQ09ERSAobWV0aG9kKSA9PSBGVU5DVElPTl9ERUNMCgkgICAgJiYgREVDTF9WSU5ERVggKG1ldGhvZCkpCgkgIGJhc2VfZm5kZWNscyA9IHRyZWVfY29ucyAoTlVMTF9UUkVFLCBtZXRob2QsIGJhc2VfZm5kZWNscyk7CiAgICAgIH0KCiAgaWYgKGJhc2VfZm5kZWNscykKICAgIHJldHVybiBiYXNlX2ZuZGVjbHM7CgogIGZvciAoaSA9IDA7IGkgPCBuX2Jhc2VjbGFzc2VzOyBpKyspCiAgICB7CiAgICAgIHRyZWUgYmFzZXR5cGUgPSBCSU5GT19UWVBFIChCSU5GT19CQVNFX0JJTkZPIChUWVBFX0JJTkZPICh0KSwgaSkpOwogICAgICBiYXNlX2ZuZGVjbHMgPSBjaGFpbm9uIChnZXRfYmFzZWZuZGVjbHMgKG5hbWUsIGJhc2V0eXBlKSwKCQkJICAgICAgYmFzZV9mbmRlY2xzKTsKICAgIH0KCiAgcmV0dXJuIGJhc2VfZm5kZWNsczsKfQoKLyogSWYgdGhpcyBkZWNsYXJhdGlvbiBzdXBlcnNlZGVzIHRoZSBkZWNsYXJhdGlvbiBvZgogICBhIG1ldGhvZCBkZWNsYXJlZCB2aXJ0dWFsIGluIHRoZSBiYXNlIGNsYXNzLCB0aGVuCiAgIG1hcmsgdGhpcyBmaWVsZCBhcyBiZWluZyB2aXJ0dWFsIGFzIHdlbGwuICAqLwoKdm9pZApjaGVja19mb3Jfb3ZlcnJpZGUgKHRyZWUgZGVjbCwgdHJlZSBjdHlwZSkKewogIGlmIChUUkVFX0NPREUgKGRlY2wpID09IFRFTVBMQVRFX0RFQ0wpCiAgICAvKiBJbiBbdGVtcC5tZW1dIHdlIGhhdmU6CgogICAgICAgICBBIHNwZWNpYWxpemF0aW9uIG9mIGEgbWVtYmVyIGZ1bmN0aW9uIHRlbXBsYXRlIGRvZXMgbm90CiAgICAgICAgIG92ZXJyaWRlIGEgdmlydHVhbCBmdW5jdGlvbiBmcm9tIGEgYmFzZSBjbGFzcy4gICovCiAgICByZXR1cm47CiAgaWYgKChERUNMX0RFU1RSVUNUT1JfUCAoZGVjbCkKICAgICAgIHx8IElERU5USUZJRVJfVklSVFVBTF9QIChERUNMX05BTUUgKGRlY2wpKQogICAgICAgfHwgREVDTF9DT05WX0ZOX1AgKGRlY2wpKQogICAgICAmJiBsb29rX2Zvcl9vdmVycmlkZXMgKGN0eXBlLCBkZWNsKQogICAgICAmJiAhREVDTF9TVEFUSUNfRlVOQ1RJT05fUCAoZGVjbCkpCiAgICAvKiBTZXQgREVDTF9WSU5ERVggdG8gYSB2YWx1ZSB0aGF0IGlzIG5laXRoZXIgYW4gSU5URUdFUl9DU1Qgbm9yCiAgICAgICB0aGUgZXJyb3JfbWFya19ub2RlIHNvIHRoYXQgd2Uga25vdyBpdCBpcyBhbiBvdmVycmlkaW5nCiAgICAgICBmdW5jdGlvbi4gICovCiAgICBERUNMX1ZJTkRFWCAoZGVjbCkgPSBkZWNsOwoKICBpZiAoREVDTF9WSVJUVUFMX1AgKGRlY2wpKQogICAgewogICAgICBpZiAoIURFQ0xfVklOREVYIChkZWNsKSkKCURFQ0xfVklOREVYIChkZWNsKSA9IGVycm9yX21hcmtfbm9kZTsKICAgICAgSURFTlRJRklFUl9WSVJUVUFMX1AgKERFQ0xfTkFNRSAoZGVjbCkpID0gMTsKICAgIH0KfQoKLyogV2FybiBhYm91dCBoaWRkZW4gdmlydHVhbCBmdW5jdGlvbnMgdGhhdCBhcmUgbm90IG92ZXJyaWRkZW4gaW4gdC4KICAgV2Uga25vdyB0aGF0IGNvbnN0cnVjdG9ycyBhbmQgZGVzdHJ1Y3RvcnMgZG9uJ3QgYXBwbHkuICAqLwoKdm9pZAp3YXJuX2hpZGRlbiAodHJlZSB0KQp7CiAgVkVDKHRyZWUpICptZXRob2RfdmVjID0gQ0xBU1NUWVBFX01FVEhPRF9WRUMgKHQpOwogIHRyZWUgZm5zOwogIHNpemVfdCBpOwoKICAvKiBXZSBnbyB0aHJvdWdoIGVhY2ggc2VwYXJhdGVseSBuYW1lZCB2aXJ0dWFsIGZ1bmN0aW9uLiAgKi8KICBmb3IgKGkgPSBDTEFTU1RZUEVfRklSU1RfQ09OVkVSU0lPTl9TTE9UOyAKICAgICAgIFZFQ19pdGVyYXRlICh0cmVlLCBtZXRob2RfdmVjLCBpLCBmbnMpOwogICAgICAgKytpKQogICAgewogICAgICB0cmVlIGZuOwogICAgICB0cmVlIG5hbWU7CiAgICAgIHRyZWUgZm5kZWNsOwogICAgICB0cmVlIGJhc2VfZm5kZWNsczsKICAgICAgdHJlZSBiYXNlX2JpbmZvOwogICAgICB0cmVlIGJpbmZvOwogICAgICBpbnQgajsKCiAgICAgIC8qIEFsbCBmdW5jdGlvbnMgaW4gdGhpcyBzbG90IGluIHRoZSBDTEFTU1RZUEVfTUVUSE9EX1ZFQyB3aWxsCgkgaGF2ZSB0aGUgc2FtZSBuYW1lLiAgRmlndXJlIG91dCB3aGF0IG5hbWUgdGhhdCBpcy4gICovCiAgICAgIG5hbWUgPSBERUNMX05BTUUgKE9WTF9DVVJSRU5UIChmbnMpKTsKICAgICAgLyogVGhlcmUgYXJlIG5vIHBvc3NpYmx5IGhpZGRlbiBmdW5jdGlvbnMgeWV0LiAgKi8KICAgICAgYmFzZV9mbmRlY2xzID0gTlVMTF9UUkVFOwogICAgICAvKiBJdGVyYXRlIHRocm91Z2ggYWxsIG9mIHRoZSBiYXNlIGNsYXNzZXMgbG9va2luZyBmb3IgcG9zc2libHkKCSBoaWRkZW4gZnVuY3Rpb25zLiAgKi8KICAgICAgZm9yIChiaW5mbyA9IFRZUEVfQklORk8gKHQpLCBqID0gMDsKCSAgIEJJTkZPX0JBU0VfSVRFUkFURSAoYmluZm8sIGosIGJhc2VfYmluZm8pOyBqKyspCgl7CgkgIHRyZWUgYmFzZXR5cGUgPSBCSU5GT19UWVBFIChiYXNlX2JpbmZvKTsKCSAgYmFzZV9mbmRlY2xzID0gY2hhaW5vbiAoZ2V0X2Jhc2VmbmRlY2xzIChuYW1lLCBiYXNldHlwZSksCgkJCQkgIGJhc2VfZm5kZWNscyk7Cgl9CgogICAgICAvKiBJZiB0aGVyZSBhcmUgbm8gZnVuY3Rpb25zIHRvIGhpZGUsIGNvbnRpbnVlLiAgKi8KICAgICAgaWYgKCFiYXNlX2ZuZGVjbHMpCgljb250aW51ZTsKCiAgICAgIC8qIFJlbW92ZSBhbnkgb3ZlcnJpZGRlbiBmdW5jdGlvbnMuICAqLwogICAgICBmb3IgKGZuID0gZm5zOyBmbjsgZm4gPSBPVkxfTkVYVCAoZm4pKQoJewoJICBmbmRlY2wgPSBPVkxfQ1VSUkVOVCAoZm4pOwoJICBpZiAoREVDTF9WSU5ERVggKGZuZGVjbCkpCgkgICAgewoJICAgICAgdHJlZSAqcHJldiA9ICZiYXNlX2ZuZGVjbHM7CgkgICAgICAKCSAgICAgIHdoaWxlICgqcHJldikgCgkJLyogSWYgdGhlIG1ldGhvZCBmcm9tIHRoZSBiYXNlIGNsYXNzIGhhcyB0aGUgc2FtZQoJCSAgIHNpZ25hdHVyZSBhcyB0aGUgbWV0aG9kIGZyb20gdGhlIGRlcml2ZWQgY2xhc3MsIGl0CgkJICAgaGFzIGJlZW4gb3ZlcnJpZGRlbi4gICovCgkJaWYgKHNhbWVfc2lnbmF0dXJlX3AgKGZuZGVjbCwgVFJFRV9WQUxVRSAoKnByZXYpKSkKCQkgICpwcmV2ID0gVFJFRV9DSEFJTiAoKnByZXYpOwoJCWVsc2UKCQkgIHByZXYgPSAmVFJFRV9DSEFJTiAoKnByZXYpOwoJICAgIH0KCX0KCiAgICAgIC8qIE5vdyBnaXZlIGEgd2FybmluZyBmb3IgYWxsIGJhc2UgZnVuY3Rpb25zIHdpdGhvdXQgb3ZlcnJpZGVycywKCSBhcyB0aGV5IGFyZSBoaWRkZW4uICAqLwogICAgICB3aGlsZSAoYmFzZV9mbmRlY2xzKSAKCXsKCSAgLyogSGVyZSB3ZSBrbm93IGl0IGlzIGEgaGlkZXIsIGFuZCBubyBvdmVycmlkZXIgZXhpc3RzLiAgKi8KCSAgY3Bfd2FybmluZ19hdCAoIiVxRCB3YXMgaGlkZGVuIiwgVFJFRV9WQUxVRSAoYmFzZV9mbmRlY2xzKSk7CgkgIGNwX3dhcm5pbmdfYXQgKCIgIGJ5ICVxRCIsIGZucyk7CgkgIGJhc2VfZm5kZWNscyA9IFRSRUVfQ0hBSU4gKGJhc2VfZm5kZWNscyk7Cgl9CiAgICB9Cn0KCi8qIENoZWNrIGZvciB0aGluZ3MgdGhhdCBhcmUgaW52YWxpZC4gIFRoZXJlIGFyZSBwcm9iYWJseSBwbGVudHkgb2Ygb3RoZXIKICAgdGhpbmdzIHdlIHNob3VsZCBjaGVjayBmb3IgYWxzby4gICovCgpzdGF0aWMgdm9pZApmaW5pc2hfc3RydWN0X2Fub24gKHRyZWUgdCkKewogIHRyZWUgZmllbGQ7CgogIGZvciAoZmllbGQgPSBUWVBFX0ZJRUxEUyAodCk7IGZpZWxkOyBmaWVsZCA9IFRSRUVfQ0hBSU4gKGZpZWxkKSkKICAgIHsKICAgICAgaWYgKFRSRUVfU1RBVElDIChmaWVsZCkpCgljb250aW51ZTsKICAgICAgaWYgKFRSRUVfQ09ERSAoZmllbGQpICE9IEZJRUxEX0RFQ0wpCgljb250aW51ZTsKCiAgICAgIGlmIChERUNMX05BTUUgKGZpZWxkKSA9PSBOVUxMX1RSRUUKCSAgJiYgQU5PTl9BR0dSX1RZUEVfUCAoVFJFRV9UWVBFIChmaWVsZCkpKQoJewoJICB0cmVlIGVsdCA9IFRZUEVfRklFTERTIChUUkVFX1RZUEUgKGZpZWxkKSk7CgkgIGZvciAoOyBlbHQ7IGVsdCA9IFRSRUVfQ0hBSU4gKGVsdCkpCgkgICAgewoJICAgICAgLyogV2UncmUgZ2VuZXJhbGx5IG9ubHkgaW50ZXJlc3RlZCBpbiBlbnRpdGllcyB0aGUgdXNlcgoJCSBkZWNsYXJlZCwgYnV0IHdlIGFsc28gZmluZCBuZXN0ZWQgY2xhc3NlcyBieSBub3RpY2luZwoJCSB0aGUgVFlQRV9ERUNMIHRoYXQgd2UgY3JlYXRlIGltcGxpY2l0bHkuICBZb3UncmUKCQkgYWxsb3dlZCB0byBwdXQgb25lIGFub255bW91cyB1bmlvbiBpbnNpZGUgYW5vdGhlciwKCQkgdGhvdWdoLCBzbyB3ZSBleHBsaWNpdGx5IHRvbGVyYXRlIHRoYXQuICBXZSB1c2UKCQkgVFlQRV9BTk9OWU1PVVNfUCByYXRoZXIgdGhhbiBBTk9OX0FHR1JfVFlQRV9QIHNvIHRoYXQKCQkgd2UgYWxzbyBhbGxvdyB1bm5hbWVkIHR5cGVzIHVzZWQgZm9yIGRlZmluaW5nIGZpZWxkcy4gICovCgkgICAgICBpZiAoREVDTF9BUlRJRklDSUFMIChlbHQpIAoJCSAgJiYgKCFERUNMX0lNUExJQ0lUX1RZUEVERUZfUCAoZWx0KQoJCSAgICAgIHx8IFRZUEVfQU5PTllNT1VTX1AgKFRSRUVfVFlQRSAoZWx0KSkpKQoJCWNvbnRpbnVlOwoKCSAgICAgIGlmIChUUkVFX0NPREUgKGVsdCkgIT0gRklFTERfREVDTCkKCQl7CgkJICBjcF9wZWR3YXJuX2F0ICgiJXEjRCBpbnZhbGlkOyBhbiBhbm9ueW1vdXMgdW5pb24gY2FuICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9ubHkgaGF2ZSBub24tc3RhdGljIGRhdGEgbWVtYmVycyIsCgkJCQkgZWx0KTsKCQkgIGNvbnRpbnVlOwoJCX0KCgkgICAgICBpZiAoVFJFRV9QUklWQVRFIChlbHQpKQoJCWNwX3BlZHdhcm5fYXQgKCJwcml2YXRlIG1lbWJlciAlcSNEIGluIGFub255bW91cyB1bmlvbiIsCgkJCSAgICAgICBlbHQpOwoJICAgICAgZWxzZSBpZiAoVFJFRV9QUk9URUNURUQgKGVsdCkpCgkJY3BfcGVkd2Fybl9hdCAoInByb3RlY3RlZCBtZW1iZXIgJXEjRCBpbiBhbm9ueW1vdXMgdW5pb24iLAoJCQkgICAgICAgZWx0KTsKCgkgICAgICBUUkVFX1BSSVZBVEUgKGVsdCkgPSBUUkVFX1BSSVZBVEUgKGZpZWxkKTsKCSAgICAgIFRSRUVfUFJPVEVDVEVEIChlbHQpID0gVFJFRV9QUk9URUNURUQgKGZpZWxkKTsKCSAgICB9Cgl9CiAgICB9Cn0KCi8qIEFkZCBUIHRvIENMQVNTVFlQRV9ERUNMX0xJU1Qgb2YgY3VycmVudF9jbGFzc190eXBlIHdoaWNoCiAgIHdpbGwgYmUgdXNlZCBsYXRlciBkdXJpbmcgY2xhc3MgdGVtcGxhdGUgaW5zdGFudGlhdGlvbi4KICAgV2hlbiBGUklFTkRfUCBpcyB6ZXJvLCBUIGNhbiBiZSBhIHN0YXRpYyBtZW1iZXIgZGF0YSAoVkFSX0RFQ0wpLAogICBhIG5vbi1zdGF0aWMgbWVtYmVyIGRhdGEgKEZJRUxEX0RFQ0wpLCBhIG1lbWJlciBmdW5jdGlvbgogICAoRlVOQ1RJT05fREVDTCksIGEgbmVzdGVkIHR5cGUgKFJFQ09SRF9UWVBFLCBFTlVNX1RZUEUpLCAKICAgYSB0eXBlZGVmIChUWVBFX0RFQ0wpIG9yIGEgbWVtYmVyIGNsYXNzIHRlbXBsYXRlIChURU1QTEFURV9ERUNMKQogICBXaGVuIEZSSUVORF9QIGlzIG5vbnplcm8sIFQgaXMgZWl0aGVyIGEgZnJpZW5kIGNsYXNzCiAgIChSRUNPUkRfVFlQRSwgVEVNUExBVEVfREVDTCkgb3IgYSBmcmllbmQgZnVuY3Rpb24KICAgKEZVTkNUSU9OX0RFQ0wsIFRFTVBMQVRFX0RFQ0wpLiAgKi8KCnZvaWQKbWF5YmVfYWRkX2NsYXNzX3RlbXBsYXRlX2RlY2xfbGlzdCAodHJlZSB0eXBlLCB0cmVlIHQsIGludCBmcmllbmRfcCkKewogIC8qIFNhdmUgc29tZSBtZW1vcnkgYnkgbm90IGNyZWF0aW5nIFRSRUVfTElTVCBpZiBUWVBFIGlzIG5vdCB0ZW1wbGF0ZS4gICovCiAgaWYgKENMQVNTVFlQRV9URU1QTEFURV9JTkZPICh0eXBlKSkKICAgIENMQVNTVFlQRV9ERUNMX0xJU1QgKHR5cGUpCiAgICAgID0gdHJlZV9jb25zIChmcmllbmRfcCA/IE5VTExfVFJFRSA6IHR5cGUsCgkJICAgdCwgQ0xBU1NUWVBFX0RFQ0xfTElTVCAodHlwZSkpOwp9CgovKiBDcmVhdGUgZGVmYXVsdCBjb25zdHJ1Y3RvcnMsIGFzc2lnbm1lbnQgb3BlcmF0b3JzLCBhbmQgc28gZm9ydGggZm9yCiAgIHRoZSB0eXBlIGluZGljYXRlZCBieSBULCBpZiB0aGV5IGFyZSBuZWVkZWQuICBDQU5UX0hBVkVfQ09OU1RfQ1RPUiwKICAgYW5kIENBTlRfSEFWRV9DT05TVF9BU1NJR05NRU5UIGFyZSBub256ZXJvIGlmLCBmb3Igd2hhdGV2ZXIgcmVhc29uLAogICB0aGUgY2xhc3MgY2Fubm90IGhhdmUgYSBkZWZhdWx0IGNvbnN0cnVjdG9yLCBjb3B5IGNvbnN0cnVjdG9yCiAgIHRha2luZyBhIGNvbnN0IHJlZmVyZW5jZSBhcmd1bWVudCwgb3IgYW4gYXNzaWdubWVudCBvcGVyYXRvciB0YWtpbmcKICAgYSBjb25zdCByZWZlcmVuY2UsIHJlc3BlY3RpdmVseS4gICovCgpzdGF0aWMgdm9pZAphZGRfaW1wbGljaXRseV9kZWNsYXJlZF9tZW1iZXJzICh0cmVlIHQsIAoJCQkJIGludCBjYW50X2hhdmVfY29uc3RfY2N0b3IsCgkJCQkgaW50IGNhbnRfaGF2ZV9jb25zdF9hc3NpZ25tZW50KQp7CiAgLyogRGVzdHJ1Y3Rvci4gICovCiAgaWYgKCFDTEFTU1RZUEVfREVTVFJVQ1RPUlMgKHQpKQogICAgewogICAgICAvKiBJbiBnZW5lcmFsLCB3ZSBjcmVhdGUgZGVzdHJ1Y3RvcnMgbGF6aWx5LiAgKi8KICAgICAgQ0xBU1NUWVBFX0xBWllfREVTVFJVQ1RPUiAodCkgPSAxOwogICAgICAvKiBIb3dldmVyLCBpZiB0aGUgaW1wbGljaXQgZGVzdHJ1Y3RvciBpcyBub24tdHJpdmlhbAoJIGRlc3RydWN0b3IsIHdlIHNvbWV0aW1lcyBoYXZlIHRvIGNyZWF0ZSBpdCBhdCB0aGlzIHBvaW50LiAgKi8KICAgICAgaWYgKFRZUEVfSEFTX05PTlRSSVZJQUxfREVTVFJVQ1RPUiAodCkpCgl7CgkgIGJvb2wgbGF6eV9wID0gdHJ1ZTsKCgkgIGlmIChUWVBFX0ZPUl9KQVZBICh0KSkKCSAgICAvKiBJZiB0aGlzIGEgSmF2YSBjbGFzcywgYW55IG5vbi10cml2aWFsIGRlc3RydWN0b3IgaXMKCSAgICAgICBpbnZhbGlkLCBldmVuIGlmIGNvbXBpbGVyLWdlbmVyYXRlZC4gIFRoZXJlZm9yZSwgaWYgdGhlCgkgICAgICAgZGVzdHJ1Y3RvciBpcyBub24tdHJpdmlhbCB3ZSBjcmVhdGUgaXQgbm93LiAgKi8KCSAgICBsYXp5X3AgPSBmYWxzZTsKCSAgZWxzZQoJICAgIHsKCSAgICAgIHRyZWUgYmluZm87CgkgICAgICB0cmVlIGJhc2VfYmluZm87CgkgICAgICBpbnQgaXg7CgoJICAgICAgLyogSWYgdGhlIGltcGxpY2l0IGRlc3RydWN0b3Igd2lsbCBiZSB2aXJ0dWFsLCB0aGVuIHdlIG11c3QKCQkgZ2VuZXJhdGUgaXQgbm93IGJlY2F1c2UgKHVuZm9ydHVuYXRlbHkpIHdlIGRvIG5vdAoJCSBnZW5lcmF0ZSB2aXJ0dWFsIHRhYmxlcyBsYXppbHkuICAqLwoJICAgICAgYmluZm8gPSBUWVBFX0JJTkZPICh0KTsKCSAgICAgIGZvciAoaXggPSAwOyBCSU5GT19CQVNFX0lURVJBVEUgKGJpbmZvLCBpeCwgYmFzZV9iaW5mbyk7IGl4KyspCgkJewoJCSAgdHJlZSBiYXNlX3R5cGU7CgkJICB0cmVlIGR0b3I7CgoJCSAgYmFzZV90eXBlID0gQklORk9fVFlQRSAoYmFzZV9iaW5mbyk7CgkJICBkdG9yID0gQ0xBU1NUWVBFX0RFU1RSVUNUT1JTIChiYXNlX3R5cGUpOwoJCSAgaWYgKGR0b3IgJiYgREVDTF9WSVJUVUFMX1AgKGR0b3IpKQoJCSAgICB7CgkJICAgICAgbGF6eV9wID0gZmFsc2U7CgkJICAgICAgYnJlYWs7CgkJICAgIH0KCQl9CgkgICAgfQoKCSAgLyogSWYgd2UgY2FuJ3QgZ2V0IGF3YXkgd2l0aCBiZWluZyBsYXp5LCBnZW5lcmF0ZSB0aGUgZGVzdHJ1Y3RvcgoJICAgICBub3cuICAqLyAKCSAgaWYgKCFsYXp5X3ApCgkgICAgbGF6aWx5X2RlY2xhcmVfZm4gKHNma19kZXN0cnVjdG9yLCB0KTsKCX0KICAgIH0KCiAgLyogRGVmYXVsdCBjb25zdHJ1Y3Rvci4gICovCiAgaWYgKCEgVFlQRV9IQVNfQ09OU1RSVUNUT1IgKHQpKQogICAgewogICAgICBUWVBFX0hBU19ERUZBVUxUX0NPTlNUUlVDVE9SICh0KSA9IDE7CiAgICAgIENMQVNTVFlQRV9MQVpZX0RFRkFVTFRfQ1RPUiAodCkgPSAxOwogICAgfQoKICAvKiBDb3B5IGNvbnN0cnVjdG9yLiAgKi8KICBpZiAoISBUWVBFX0hBU19JTklUX1JFRiAodCkgJiYgISBUWVBFX0ZPUl9KQVZBICh0KSkKICAgIHsKICAgICAgVFlQRV9IQVNfSU5JVF9SRUYgKHQpID0gMTsKICAgICAgVFlQRV9IQVNfQ09OU1RfSU5JVF9SRUYgKHQpID0gIWNhbnRfaGF2ZV9jb25zdF9jY3RvcjsKICAgICAgQ0xBU1NUWVBFX0xBWllfQ09QWV9DVE9SICh0KSA9IDE7CiAgICAgIFRZUEVfSEFTX0NPTlNUUlVDVE9SICh0KSA9IDE7CiAgICB9CgogIC8qIElmIHRoZXJlIGlzIG5vIGFzc2lnbm1lbnQgb3BlcmF0b3IsIG9uZSB3aWxsIGJlIGNyZWF0ZWQgaWYgYW5kCiAgICAgd2hlbiBpdCBpcyBuZWVkZWQuICBGb3Igbm93LCBqdXN0IHJlY29yZCB3aGV0aGVyIG9yIG5vdCB0aGUgdHlwZQogICAgIG9mIHRoZSBwYXJhbWV0ZXIgdG8gdGhlIGFzc2lnbm1lbnQgb3BlcmF0b3Igd2lsbCBiZSBhIGNvbnN0IG9yCiAgICAgbm9uLWNvbnN0IHJlZmVyZW5jZS4gICovCiAgaWYgKCFUWVBFX0hBU19BU1NJR05fUkVGICh0KSAmJiAhVFlQRV9GT1JfSkFWQSAodCkpCiAgICB7CiAgICAgIFRZUEVfSEFTX0FTU0lHTl9SRUYgKHQpID0gMTsKICAgICAgVFlQRV9IQVNfQ09OU1RfQVNTSUdOX1JFRiAodCkgPSAhY2FudF9oYXZlX2NvbnN0X2Fzc2lnbm1lbnQ7CiAgICAgIENMQVNTVFlQRV9MQVpZX0FTU0lHTk1FTlRfT1AgKHQpID0gMTsKICAgIH0KfQoKLyogU3Vicm91dGluZSBvZiBmaW5pc2hfc3RydWN0XzEuICBSZWN1cnNpdmVseSBjb3VudCB0aGUgbnVtYmVyIG9mIGZpZWxkcwogICBpbiBUWVBFLCBpbmNsdWRpbmcgYW5vbnltb3VzIHVuaW9uIG1lbWJlcnMuICAqLwoKc3RhdGljIGludApjb3VudF9maWVsZHMgKHRyZWUgZmllbGRzKQp7CiAgdHJlZSB4OwogIGludCBuX2ZpZWxkcyA9IDA7CiAgZm9yICh4ID0gZmllbGRzOyB4OyB4ID0gVFJFRV9DSEFJTiAoeCkpCiAgICB7CiAgICAgIGlmIChUUkVFX0NPREUgKHgpID09IEZJRUxEX0RFQ0wgJiYgQU5PTl9BR0dSX1RZUEVfUCAoVFJFRV9UWVBFICh4KSkpCgluX2ZpZWxkcyArPSBjb3VudF9maWVsZHMgKFRZUEVfRklFTERTIChUUkVFX1RZUEUgKHgpKSk7CiAgICAgIGVsc2UKCW5fZmllbGRzICs9IDE7CiAgICB9CiAgcmV0dXJuIG5fZmllbGRzOwp9CgovKiBTdWJyb3V0aW5lIG9mIGZpbmlzaF9zdHJ1Y3RfMS4gIFJlY3Vyc2l2ZWx5IGFkZCBhbGwgdGhlIGZpZWxkcyBpbiB0aGUKICAgVFJFRV9MSVNUIEZJRUxEUyB0byB0aGUgU09SVEVEX0ZJRUxEU19UWVBFIGVsdHMsIHN0YXJ0aW5nIGF0IG9mZnNldCBJRFguICAqLwoKc3RhdGljIGludAphZGRfZmllbGRzX3RvX3JlY29yZF90eXBlICh0cmVlIGZpZWxkcywgc3RydWN0IHNvcnRlZF9maWVsZHNfdHlwZSAqZmllbGRfdmVjLCBpbnQgaWR4KQp7CiAgdHJlZSB4OwogIGZvciAoeCA9IGZpZWxkczsgeDsgeCA9IFRSRUVfQ0hBSU4gKHgpKQogICAgewogICAgICBpZiAoVFJFRV9DT0RFICh4KSA9PSBGSUVMRF9ERUNMICYmIEFOT05fQUdHUl9UWVBFX1AgKFRSRUVfVFlQRSAoeCkpKQoJaWR4ID0gYWRkX2ZpZWxkc190b19yZWNvcmRfdHlwZSAoVFlQRV9GSUVMRFMgKFRSRUVfVFlQRSAoeCkpLCBmaWVsZF92ZWMsIGlkeCk7CiAgICAgIGVsc2UKCWZpZWxkX3ZlYy0+ZWx0c1tpZHgrK10gPSB4OwogICAgfQogIHJldHVybiBpZHg7Cn0KCi8qIEZJRUxEIGlzIGEgYml0LWZpZWxkLiAgV2UgYXJlIGZpbmlzaGluZyB0aGUgcHJvY2Vzc2luZyBmb3IgaXRzCiAgIGVuY2xvc2luZyB0eXBlLiAgSXNzdWUgYW55IGFwcHJvcHJpYXRlIG1lc3NhZ2VzIGFuZCBzZXQgYXBwcm9wcmlhdGUKICAgZmxhZ3MuICAqLwoKc3RhdGljIHZvaWQKY2hlY2tfYml0ZmllbGRfZGVjbCAodHJlZSBmaWVsZCkKewogIHRyZWUgdHlwZSA9IFRSRUVfVFlQRSAoZmllbGQpOwogIHRyZWUgdyA9IE5VTExfVFJFRTsKCiAgLyogRGV0ZWN0IGludmFsaWQgYml0LWZpZWxkIHR5cGUuICAqLwogIGlmIChERUNMX0lOSVRJQUwgKGZpZWxkKQogICAgICAmJiAhIElOVEVHUkFMX1RZUEVfUCAoVFJFRV9UWVBFIChmaWVsZCkpKQogICAgewogICAgICBjcF9lcnJvcl9hdCAoImJpdC1maWVsZCAlcSNEIHdpdGggbm9uLWludGVncmFsIHR5cGUiLCBmaWVsZCk7CiAgICAgIHcgPSBlcnJvcl9tYXJrX25vZGU7CiAgICB9CgogIC8qIERldGVjdCBhbmQgaWdub3JlIG91dCBvZiByYW5nZSBmaWVsZCB3aWR0aC4gICovCiAgaWYgKERFQ0xfSU5JVElBTCAoZmllbGQpKQogICAgewogICAgICB3ID0gREVDTF9JTklUSUFMIChmaWVsZCk7CgogICAgICAvKiBBdm9pZCB0aGUgbm9uX2x2YWx1ZSB3cmFwcGVyIGFkZGVkIGJ5IGZvbGQgZm9yIFBMVVNfRVhQUnMuICAqLwogICAgICBTVFJJUF9OT1BTICh3KTsKCiAgICAgIC8qIGRldGVjdCBpbnZhbGlkIGZpZWxkIHNpemUuICAqLwogICAgICB3ID0gaW50ZWdyYWxfY29uc3RhbnRfdmFsdWUgKHcpOwoKICAgICAgaWYgKFRSRUVfQ09ERSAodykgIT0gSU5URUdFUl9DU1QpCgl7CgkgIGNwX2Vycm9yX2F0ICgiYml0LWZpZWxkICVxRCB3aWR0aCBub3QgYW4gaW50ZWdlciBjb25zdGFudCIsCgkJICAgICAgIGZpZWxkKTsKCSAgdyA9IGVycm9yX21hcmtfbm9kZTsKCX0KICAgICAgZWxzZSBpZiAodHJlZV9pbnRfY3N0X3NnbiAodykgPCAwKQoJewoJICBjcF9lcnJvcl9hdCAoIm5lZ2F0aXZlIHdpZHRoIGluIGJpdC1maWVsZCAlcUQiLCBmaWVsZCk7CgkgIHcgPSBlcnJvcl9tYXJrX25vZGU7Cgl9CiAgICAgIGVsc2UgaWYgKGludGVnZXJfemVyb3AgKHcpICYmIERFQ0xfTkFNRSAoZmllbGQpICE9IDApCgl7CgkgIGNwX2Vycm9yX2F0ICgiemVybyB3aWR0aCBmb3IgYml0LWZpZWxkICVxRCIsIGZpZWxkKTsKCSAgdyA9IGVycm9yX21hcmtfbm9kZTsKCX0KICAgICAgZWxzZSBpZiAoY29tcGFyZV90cmVlX2ludCAodywgVFlQRV9QUkVDSVNJT04gKHR5cGUpKSA+IDAKCSAgICAgICAmJiBUUkVFX0NPREUgKHR5cGUpICE9IEVOVU1FUkFMX1RZUEUKCSAgICAgICAmJiBUUkVFX0NPREUgKHR5cGUpICE9IEJPT0xFQU5fVFlQRSkKCWNwX3dhcm5pbmdfYXQgKCJ3aWR0aCBvZiAlcUQgZXhjZWVkcyBpdHMgdHlwZSIsIGZpZWxkKTsKICAgICAgZWxzZSBpZiAoVFJFRV9DT0RFICh0eXBlKSA9PSBFTlVNRVJBTF9UWVBFCgkgICAgICAgJiYgKDAgPiBjb21wYXJlX3RyZWVfaW50ICh3LAoJCQkJCSBtaW5fcHJlY2lzaW9uIChUWVBFX01JTl9WQUxVRSAodHlwZSksCgkJCQkJCQlUWVBFX1VOU0lHTkVEICh0eXBlKSkpCgkJICAgfHwgIDAgPiBjb21wYXJlX3RyZWVfaW50ICh3LAoJCQkJCSAgICAgbWluX3ByZWNpc2lvbgoJCQkJCSAgICAgKFRZUEVfTUFYX1ZBTFVFICh0eXBlKSwKCQkJCQkgICAgICBUWVBFX1VOU0lHTkVEICh0eXBlKSkpKSkKCWNwX3dhcm5pbmdfYXQgKCIlcUQgaXMgdG9vIHNtYWxsIHRvIGhvbGQgYWxsIHZhbHVlcyBvZiAlcSNUIiwKCQkgICAgICAgZmllbGQsIHR5cGUpOwogICAgfQogIAogIC8qIFJlbW92ZSB0aGUgYml0LWZpZWxkIHdpZHRoIGluZGljYXRvciBzbyB0aGF0IHRoZSByZXN0IG9mIHRoZQogICAgIGNvbXBpbGVyIGRvZXMgbm90IHRyZWF0IHRoYXQgdmFsdWUgYXMgYW4gaW5pdGlhbGl6ZXIuICAqLwogIERFQ0xfSU5JVElBTCAoZmllbGQpID0gTlVMTF9UUkVFOwoKICBpZiAodyAhPSBlcnJvcl9tYXJrX25vZGUpCiAgICB7CiAgICAgIERFQ0xfU0laRSAoZmllbGQpID0gY29udmVydCAoYml0c2l6ZXR5cGUsIHcpOwogICAgICBERUNMX0JJVF9GSUVMRCAoZmllbGQpID0gMTsKICAgIH0KICBlbHNlCiAgICB7CiAgICAgIC8qIE5vbi1iaXQtZmllbGRzIGFyZSBhbGlnbmVkIGZvciB0aGVpciB0eXBlLiAgKi8KICAgICAgREVDTF9CSVRfRklFTEQgKGZpZWxkKSA9IDA7CiAgICAgIENMRUFSX0RFQ0xfQ19CSVRfRklFTEQgKGZpZWxkKTsKICAgIH0KfQoKLyogRklFTEQgaXMgYSBub24gYml0LWZpZWxkLiAgV2UgYXJlIGZpbmlzaGluZyB0aGUgcHJvY2Vzc2luZyBmb3IgaXRzCiAgIGVuY2xvc2luZyB0eXBlIFQuICBJc3N1ZSBhbnkgYXBwcm9wcmlhdGUgbWVzc2FnZXMgYW5kIHNldCBhcHByb3ByaWF0ZQogICBmbGFncy4gICovCgpzdGF0aWMgdm9pZApjaGVja19maWVsZF9kZWNsICh0cmVlIGZpZWxkLAogICAgICAgICAgICAgICAgICB0cmVlIHQsCiAgICAgICAgICAgICAgICAgIGludCogY2FudF9oYXZlX2NvbnN0X2N0b3IsCiAgICAgICAgICAgICAgICAgIGludCogbm9fY29uc3RfYXNuX3JlZiwKCQkgIGludCogYW55X2RlZmF1bHRfbWVtYmVycykKewogIHRyZWUgdHlwZSA9IHN0cmlwX2FycmF5X3R5cGVzIChUUkVFX1RZUEUgKGZpZWxkKSk7CgogIC8qIEFuIGFub255bW91cyB1bmlvbiBjYW5ub3QgY29udGFpbiBhbnkgZmllbGRzIHdoaWNoIHdvdWxkIGNoYW5nZQogICAgIHRoZSBzZXR0aW5ncyBvZiBDQU5UX0hBVkVfQ09OU1RfQ1RPUiBhbmQgZnJpZW5kcy4gICovCiAgaWYgKEFOT05fVU5JT05fVFlQRV9QICh0eXBlKSkKICAgIDsKICAvKiBBbmQsIHdlIGRvbid0IHNldCBUWVBFX0hBU19DT05TVF9JTklUX1JFRiwgZXRjLiwgZm9yIGFub255bW91cwogICAgIHN0cnVjdHMuICBTbywgd2UgcmVjdXJzZSB0aHJvdWdoIHRoZWlyIGZpZWxkcyBoZXJlLiAgKi8KICBlbHNlIGlmIChBTk9OX0FHR1JfVFlQRV9QICh0eXBlKSkKICAgIHsKICAgICAgdHJlZSBmaWVsZHM7CgogICAgICBmb3IgKGZpZWxkcyA9IFRZUEVfRklFTERTICh0eXBlKTsgZmllbGRzOyBmaWVsZHMgPSBUUkVFX0NIQUlOIChmaWVsZHMpKQoJaWYgKFRSRUVfQ09ERSAoZmllbGRzKSA9PSBGSUVMRF9ERUNMICYmICFERUNMX0NfQklUX0ZJRUxEIChmaWVsZCkpCgkgIGNoZWNrX2ZpZWxkX2RlY2wgKGZpZWxkcywgdCwgY2FudF9oYXZlX2NvbnN0X2N0b3IsCgkJCSAgICBub19jb25zdF9hc25fcmVmLCBhbnlfZGVmYXVsdF9tZW1iZXJzKTsKICAgIH0KICAvKiBDaGVjayBtZW1iZXJzIHdpdGggY2xhc3MgdHlwZSBmb3IgY29uc3RydWN0b3JzLCBkZXN0cnVjdG9ycywKICAgICBldGMuICAqLwogIGVsc2UgaWYgKENMQVNTX1RZUEVfUCAodHlwZSkpCiAgICB7CiAgICAgIC8qIE5ldmVyIGxldCBhbnl0aGluZyB3aXRoIHVuaW5oZXJpdGFibGUgdmlydHVhbHMKCSBtYWtlIGl0IHRocm91Z2ggd2l0aG91dCBjb21wbGFpbnQuICAqLwogICAgICBhYnN0cmFjdF92aXJ0dWFsc19lcnJvciAoZmllbGQsIHR5cGUpOwoJCSAgICAgIAogICAgICBpZiAoVFJFRV9DT0RFICh0KSA9PSBVTklPTl9UWVBFKQoJewoJICBpZiAoVFlQRV9ORUVEU19DT05TVFJVQ1RJTkcgKHR5cGUpKQoJICAgIGNwX2Vycm9yX2F0ICgibWVtYmVyICVxI0Qgd2l0aCBjb25zdHJ1Y3RvciBub3QgYWxsb3dlZCBpbiB1bmlvbiIsCgkJCSBmaWVsZCk7CgkgIGlmIChUWVBFX0hBU19OT05UUklWSUFMX0RFU1RSVUNUT1IgKHR5cGUpKQoJICAgIGNwX2Vycm9yX2F0ICgibWVtYmVyICVxI0Qgd2l0aCBkZXN0cnVjdG9yIG5vdCBhbGxvd2VkIGluIHVuaW9uIiwKCQkJIGZpZWxkKTsKCSAgaWYgKFRZUEVfSEFTX0NPTVBMRVhfQVNTSUdOX1JFRiAodHlwZSkpCgkgICAgY3BfZXJyb3JfYXQgKCJtZW1iZXIgJXEjRCB3aXRoIGNvcHkgYXNzaWdubWVudCBvcGVyYXRvciBub3QgYWxsb3dlZCBpbiB1bmlvbiIsCgkJCSBmaWVsZCk7Cgl9CiAgICAgIGVsc2UKCXsKCSAgVFlQRV9ORUVEU19DT05TVFJVQ1RJTkcgKHQpIHw9IFRZUEVfTkVFRFNfQ09OU1RSVUNUSU5HICh0eXBlKTsKCSAgVFlQRV9IQVNfTk9OVFJJVklBTF9ERVNUUlVDVE9SICh0KSAKCSAgICB8PSBUWVBFX0hBU19OT05UUklWSUFMX0RFU1RSVUNUT1IgKHR5cGUpOwoJICBUWVBFX0hBU19DT01QTEVYX0FTU0lHTl9SRUYgKHQpIHw9IFRZUEVfSEFTX0NPTVBMRVhfQVNTSUdOX1JFRiAodHlwZSk7CgkgIFRZUEVfSEFTX0NPTVBMRVhfSU5JVF9SRUYgKHQpIHw9IFRZUEVfSEFTX0NPTVBMRVhfSU5JVF9SRUYgKHR5cGUpOwoJfQoKICAgICAgaWYgKCFUWVBFX0hBU19DT05TVF9JTklUX1JFRiAodHlwZSkpCgkqY2FudF9oYXZlX2NvbnN0X2N0b3IgPSAxOwoKICAgICAgaWYgKCFUWVBFX0hBU19DT05TVF9BU1NJR05fUkVGICh0eXBlKSkKCSpub19jb25zdF9hc25fcmVmID0gMTsKICAgIH0KICBpZiAoREVDTF9JTklUSUFMIChmaWVsZCkgIT0gTlVMTF9UUkVFKQogICAgewogICAgICAvKiBgYnVpbGRfY2xhc3NfaW5pdF9saXN0JyBkb2VzIG5vdCByZWNvZ25pemUKCSBub24tRklFTERfREVDTHMuICAqLwogICAgICBpZiAoVFJFRV9DT0RFICh0KSA9PSBVTklPTl9UWVBFICYmIGFueV9kZWZhdWx0X21lbWJlcnMgIT0gMCkKCWVycm9yICgibXVsdGlwbGUgZmllbGRzIGluIHVuaW9uICVxVCBpbml0aWFsaXplZCIsIHQpOwogICAgICAqYW55X2RlZmF1bHRfbWVtYmVycyA9IDE7CiAgICB9Cn0KCi8qIENoZWNrIHRoZSBkYXRhIG1lbWJlcnMgKGJvdGggc3RhdGljIGFuZCBub24tc3RhdGljKSwgY2xhc3Mtc2NvcGVkCiAgIHR5cGVkZWZzLCBldGMuLCBhcHBlYXJpbmcgaW4gdGhlIGRlY2xhcmF0aW9uIG9mIFQuICBJc3N1ZQogICBhcHByb3ByaWF0ZSBkaWFnbm9zdGljcy4gIFNldHMgQUNDRVNTX0RFQ0xTIHRvIGEgbGlzdCAoaW4KICAgZGVjbGFyYXRpb24gb3JkZXIpIG9mIGFjY2VzcyBkZWNsYXJhdGlvbnM7IGVhY2ggVFJFRV9WQUxVRSBpbiB0aGlzCiAgIGxpc3QgaXMgYSBVU0lOR19ERUNMLgoKICAgSW4gYWRkaXRpb24sIHNldCB0aGUgZm9sbG93aW5nIGZsYWdzOgoKICAgICBFTVBUWV9QCiAgICAgICBUaGUgY2xhc3MgaXMgZW1wdHksIGkuZS4sIGNvbnRhaW5zIG5vIG5vbi1zdGF0aWMgZGF0YSBtZW1iZXJzLgoKICAgICBDQU5UX0hBVkVfQ09OU1RfQ1RPUl9QCiAgICAgICBUaGlzIGNsYXNzIGNhbm5vdCBoYXZlIGFuIGltcGxpY2l0bHkgZ2VuZXJhdGVkIGNvcHkgY29uc3RydWN0b3IKICAgICAgIHRha2luZyBhIGNvbnN0IHJlZmVyZW5jZS4KCiAgICAgQ0FOVF9IQVZFX0NPTlNUX0FTTl9SRUYKICAgICAgIFRoaXMgY2xhc3MgY2Fubm90IGhhdmUgYW4gaW1wbGljaXRseSBnZW5lcmF0ZWQgYXNzaWdubWVudAogICAgICAgb3BlcmF0b3IgdGFraW5nIGEgY29uc3QgcmVmZXJlbmNlLgoKICAgQWxsIG9mIHRoZXNlIGZsYWdzIHNob3VsZCBiZSBpbml0aWFsaXplZCBiZWZvcmUgY2FsbGluZyB0aGlzCiAgIGZ1bmN0aW9uLgoKICAgUmV0dXJucyBhIHBvaW50ZXIgdG8gdGhlIGVuZCBvZiB0aGUgVFlQRV9GSUVMRHMgY2hhaW47IGFkZGl0aW9uYWwKICAgZmllbGRzIGNhbiBiZSBhZGRlZCBieSBhZGRpbmcgdG8gdGhpcyBjaGFpbi4gICovCgpzdGF0aWMgdm9pZApjaGVja19maWVsZF9kZWNscyAodHJlZSB0LCB0cmVlICphY2Nlc3NfZGVjbHMsCgkJICAgaW50ICpjYW50X2hhdmVfY29uc3RfY3Rvcl9wLAoJCSAgIGludCAqbm9fY29uc3RfYXNuX3JlZl9wKQp7CiAgdHJlZSAqZmllbGQ7CiAgdHJlZSAqbmV4dDsKICBib29sIGhhc19wb2ludGVyczsKICBpbnQgYW55X2RlZmF1bHRfbWVtYmVyczsKCiAgLyogQXNzdW1lIHRoZXJlIGFyZSBubyBhY2Nlc3MgZGVjbGFyYXRpb25zLiAgKi8KICAqYWNjZXNzX2RlY2xzID0gTlVMTF9UUkVFOwogIC8qIEFzc3VtZSB0aGlzIGNsYXNzIGhhcyBubyBwb2ludGVyIG1lbWJlcnMuICAqLwogIGhhc19wb2ludGVycyA9IGZhbHNlOwogIC8qIEFzc3VtZSBub25lIG9mIHRoZSBtZW1iZXJzIG9mIHRoaXMgY2xhc3MgaGF2ZSBkZWZhdWx0CiAgICAgaW5pdGlhbGl6YXRpb25zLiAgKi8KICBhbnlfZGVmYXVsdF9tZW1iZXJzID0gMDsKCiAgZm9yIChmaWVsZCA9ICZUWVBFX0ZJRUxEUyAodCk7ICpmaWVsZDsgZmllbGQgPSBuZXh0KQogICAgewogICAgICB0cmVlIHggPSAqZmllbGQ7CiAgICAgIHRyZWUgdHlwZSA9IFRSRUVfVFlQRSAoeCk7CgogICAgICBuZXh0ID0gJlRSRUVfQ0hBSU4gKHgpOwoKICAgICAgaWYgKFRSRUVfQ09ERSAoeCkgPT0gRklFTERfREVDTCkKCXsKCSAgLyogQVBQTEUgTE9DQUwgYmVnaW4gbWFpbmxpbmUgNDEyMTk2MiAqLwogICAgICAgICAgdHlwZSA9IHN0cmlwX2FycmF5X3R5cGVzICh0eXBlKTsKCSAgLyogQVBQTEUgTE9DQUwgZW5kIG1haW5saW5lIDQxMjE5NjIgKi8KCgkgIGlmIChUWVBFX1BBQ0tFRCAodCkpCgkgICAgewoJICAgICAgLyogQVBQTEUgTE9DQUwgYmVnaW4gbWFpbmxpbmUgNDEyMTk2MiAqLwoJICAgICAgaWYgKCFwb2RfdHlwZV9wICh0eXBlKSAmJiAhVFlQRV9QQUNLRUQgKHR5cGUpKQoJCXdhcm5pbmcKCQkgICAoImlnbm9yaW5nIHBhY2tlZCBhdHRyaWJ1dGUgb24gdW5wYWNrZWQgbm9uLVBPRCBmaWVsZCAlcSsjRCIsCgkJICAgeCk7CgkgICAgICBlbHNlIGlmIChUWVBFX0FMSUdOIChUUkVFX1RZUEUgKHgpKSA+IEJJVFNfUEVSX1VOSVQpCgkgICAgICAvKiBBUFBMRSBMT0NBTCBlbmQgbWFpbmxpbmUgNDEyMTk2MiAqLwoJCURFQ0xfUEFDS0VEICh4KSA9IDE7CgkgICAgfQoKCSAgaWYgKERFQ0xfQ19CSVRfRklFTEQgKHgpICYmIGludGVnZXJfemVyb3AgKERFQ0xfSU5JVElBTCAoeCkpKQoJICAgIC8qIFdlIGRvbid0IHRyZWF0IHplcm8td2lkdGggYml0ZmllbGRzIGFzIG1ha2luZyBhIGNsYXNzCgkgICAgICAgbm9uLWVtcHR5LiAgKi8KCSAgICA7CgkgIGVsc2UKCSAgICB7CgkgICAgICAvKiBBUFBMRSBMT0NBTCBiZWdpbiBtYWlubGluZSA0MTIxOTYyICovCgkgICAgICAvKiBBUFBMRSBMT0NBTCBlbmQgbWFpbmxpbmUgNDEyMTk2MiAqLwoJICAgICAgLyogVGhlIGNsYXNzIGlzIG5vbi1lbXB0eS4gICovCgkgICAgICBDTEFTU1RZUEVfRU1QVFlfUCAodCkgPSAwOwoJICAgICAgLyogVGhlIGNsYXNzIGlzIG5vdCBldmVuIG5lYXJseSBlbXB0eS4gICovCgkgICAgICBDTEFTU1RZUEVfTkVBUkxZX0VNUFRZX1AgKHQpID0gMDsKCSAgICAgIC8qIElmIG9uZSBvZiB0aGUgZGF0YSBtZW1iZXJzIGNvbnRhaW5zIGFuIGVtcHR5IGNsYXNzLAoJCSBzbyBkb2VzIFQuICAqLwoJICAgICAgLyogQVBQTEUgTE9DQUwgYmVnaW4gbWFpbmxpbmUgNDEyMTk2MiAqLwoJICAgICAgaWYgKENMQVNTX1RZUEVfUCAodHlwZSkgCgkJICAmJiBDTEFTU1RZUEVfQ09OVEFJTlNfRU1QVFlfQ0xBU1NfUCAodHlwZSkpCgkgICAgICAvKiBBUFBMRSBMT0NBTCBlbmQgbWFpbmxpbmUgNDEyMTk2MiAqLwoJCUNMQVNTVFlQRV9DT05UQUlOU19FTVBUWV9DTEFTU19QICh0KSA9IDE7CgkgICAgfQoJfQoKICAgICAgaWYgKFRSRUVfQ09ERSAoeCkgPT0gVVNJTkdfREVDTCkKCXsKCSAgLyogUHJ1bmUgdGhlIGFjY2VzcyBkZWNsYXJhdGlvbiBmcm9tIHRoZSBsaXN0IG9mIGZpZWxkcy4gICovCgkgICpmaWVsZCA9IFRSRUVfQ0hBSU4gKHgpOwoKCSAgLyogU2F2ZSB0aGUgYWNjZXNzIGRlY2xhcmF0aW9ucyBmb3Igb3VyIGNhbGxlci4gICovCgkgICphY2Nlc3NfZGVjbHMgPSB0cmVlX2NvbnMgKE5VTExfVFJFRSwgeCwgKmFjY2Vzc19kZWNscyk7CgoJICAvKiBTaW5jZSB3ZSd2ZSByZXNldCAqRklFTEQgdGhlcmUncyBubyByZWFzb24gdG8gc2tpcCB0byB0aGUKCSAgICAgbmV4dCBmaWVsZC4gICovCgkgIG5leHQgPSBmaWVsZDsKCSAgY29udGludWU7Cgl9CgogICAgICBpZiAoVFJFRV9DT0RFICh4KSA9PSBUWVBFX0RFQ0wKCSAgfHwgVFJFRV9DT0RFICh4KSA9PSBURU1QTEFURV9ERUNMKQoJY29udGludWU7CgogICAgICAvKiBJZiB3ZSd2ZSBnb3R0ZW4gdGhpcyBmYXIsIGl0J3MgYSBkYXRhIG1lbWJlciwgcG9zc2libHkgc3RhdGljLAoJIG9yIGFuIGVudW1lcmF0b3IuICAqLwogICAgICBERUNMX0NPTlRFWFQgKHgpID0gdDsKCiAgICAgIC8qIFdoZW4gdGhpcyBnb2VzIGludG8gc2NvcGUsIGl0IHdpbGwgYmUgYSBub24tbG9jYWwgcmVmZXJlbmNlLiAgKi8KICAgICAgREVDTF9OT05MT0NBTCAoeCkgPSAxOwoKICAgICAgaWYgKFRSRUVfQ09ERSAodCkgPT0gVU5JT05fVFlQRSkKCXsKCSAgLyogW2NsYXNzLnVuaW9uXQoKCSAgICAgSWYgYSB1bmlvbiBjb250YWlucyBhIHN0YXRpYyBkYXRhIG1lbWJlciwgb3IgYSBtZW1iZXIgb2YKCSAgICAgcmVmZXJlbmNlIHR5cGUsIHRoZSBwcm9ncmFtIGlzIGlsbC1mb3JtZWQuICAqLwoJICBpZiAoVFJFRV9DT0RFICh4KSA9PSBWQVJfREVDTCkKCSAgICB7CgkgICAgICBjcF9lcnJvcl9hdCAoIiVxRCBtYXkgbm90IGJlIHN0YXRpYyBiZWNhdXNlIGl0IGlzIGEgbWVtYmVyIG9mIGEgdW5pb24iLCB4KTsKCSAgICAgIGNvbnRpbnVlOwoJICAgIH0KCSAgaWYgKFRSRUVfQ09ERSAodHlwZSkgPT0gUkVGRVJFTkNFX1RZUEUpCgkgICAgewoJICAgICAgY3BfZXJyb3JfYXQgKCIlcUQgbWF5IG5vdCBoYXZlIHJlZmVyZW5jZSB0eXBlICVxVCBiZWNhdXNlIgogICAgICAgICAgICAgICAgICAgICAgICAgICAiIGl0IGlzIGEgbWVtYmVyIG9mIGEgdW5pb24iLAoJCQkgICB4LCB0eXBlKTsKCSAgICAgIGNvbnRpbnVlOwoJICAgIH0KCX0KCiAgICAgIC8qIGBgQSBsb2NhbCBjbGFzcyBjYW5ub3QgaGF2ZSBzdGF0aWMgZGF0YSBtZW1iZXJzLicnIEFSTSA5LjQgKi8KICAgICAgaWYgKGN1cnJlbnRfZnVuY3Rpb25fZGVjbCAmJiBUUkVFX1NUQVRJQyAoeCkpCgljcF9lcnJvcl9hdCAoImZpZWxkICVxRCBpbiBsb2NhbCBjbGFzcyBjYW5ub3QgYmUgc3RhdGljIiwgeCk7CgogICAgICAvKiBQZXJmb3JtIGVycm9yIGNoZWNraW5nIHRoYXQgZGlkIG5vdCBnZXQgZG9uZSBpbgoJIGdyb2tkZWNsYXJhdG9yLiAgKi8KICAgICAgaWYgKFRSRUVfQ09ERSAodHlwZSkgPT0gRlVOQ1RJT05fVFlQRSkKCXsKCSAgY3BfZXJyb3JfYXQgKCJmaWVsZCAlcUQgaW52YWxpZGx5IGRlY2xhcmVkIGZ1bmN0aW9uIHR5cGUiLCB4KTsKCSAgdHlwZSA9IGJ1aWxkX3BvaW50ZXJfdHlwZSAodHlwZSk7CgkgIFRSRUVfVFlQRSAoeCkgPSB0eXBlOwoJfQogICAgICBlbHNlIGlmIChUUkVFX0NPREUgKHR5cGUpID09IE1FVEhPRF9UWVBFKQoJewoJICBjcF9lcnJvcl9hdCAoImZpZWxkICVxRCBpbnZhbGlkbHkgZGVjbGFyZWQgbWV0aG9kIHR5cGUiLCB4KTsKCSAgdHlwZSA9IGJ1aWxkX3BvaW50ZXJfdHlwZSAodHlwZSk7CgkgIFRSRUVfVFlQRSAoeCkgPSB0eXBlOwoJfQoKICAgICAgaWYgKHR5cGUgPT0gZXJyb3JfbWFya19ub2RlKQoJY29udGludWU7CgkgIAogICAgICBpZiAoVFJFRV9DT0RFICh4KSA9PSBDT05TVF9ERUNMIHx8IFRSRUVfQ09ERSAoeCkgPT0gVkFSX0RFQ0wpCgljb250aW51ZTsKCiAgICAgIC8qIE5vdyBpdCBjYW4gb25seSBiZSBhIEZJRUxEX0RFQ0wuICAqLwoKICAgICAgaWYgKFRSRUVfUFJJVkFURSAoeCkgfHwgVFJFRV9QUk9URUNURUQgKHgpKQoJQ0xBU1NUWVBFX05PTl9BR0dSRUdBVEUgKHQpID0gMTsKCiAgICAgIC8qIElmIHRoaXMgaXMgb2YgcmVmZXJlbmNlIHR5cGUsIGNoZWNrIGlmIGl0IG5lZWRzIGFuIGluaXQuCgkgQWxzbyBkbyBhIGxpdHRsZSBBTlNJIGppZyBpZiBuZWNlc3NhcnkuICAqLwogICAgICBpZiAoVFJFRV9DT0RFICh0eXBlKSA9PSBSRUZFUkVOQ0VfVFlQRSkKIAl7CgkgIENMQVNTVFlQRV9OT05fUE9EX1AgKHQpID0gMTsKCSAgaWYgKERFQ0xfSU5JVElBTCAoeCkgPT0gTlVMTF9UUkVFKQoJICAgIFNFVF9DTEFTU1RZUEVfUkVGX0ZJRUxEU19ORUVEX0lOSVQgKHQsIDEpOwoKCSAgLyogQVJNICQxMi42LjI6IFtBIG1lbWJlciBpbml0aWFsaXplciBsaXN0XSAob3IsIGZvciBhbgoJICAgICBhZ2dyZWdhdGUsIGluaXRpYWxpemF0aW9uIGJ5IGEgYnJhY2UtZW5jbG9zZWQgbGlzdCkgaXMgdGhlCgkgICAgIG9ubHkgd2F5IHRvIGluaXRpYWxpemUgbm9uc3RhdGljIGNvbnN0IGFuZCByZWZlcmVuY2UKCSAgICAgbWVtYmVycy4gICovCgkgIFRZUEVfSEFTX0NPTVBMRVhfQVNTSUdOX1JFRiAodCkgPSAxOwoKCSAgaWYgKCEgVFlQRV9IQVNfQ09OU1RSVUNUT1IgKHQpICYmIENMQVNTVFlQRV9OT05fQUdHUkVHQVRFICh0KQoJICAgICAgJiYgZXh0cmFfd2FybmluZ3MpCiAgICAgICAgICAgIGNwX3dhcm5pbmdfYXQgKCJub24tc3RhdGljIHJlZmVyZW5jZSAlcSNEIGluIGNsYXNzIHdpdGhvdXQgYSBjb25zdHJ1Y3RvciIsIHgpOwoJfQoKICAgICAgdHlwZSA9IHN0cmlwX2FycmF5X3R5cGVzICh0eXBlKTsKCiAgICAgIC8qIFRoaXMgaXMgdXNlZCBieSAtV2VmZmMrKyAoc2VlIGJlbG93KS4gV2FybiBvbmx5IGZvciBwb2ludGVycwoJIHRvIG1lbWJlcnMgd2hpY2ggbWlnaHQgaG9sZCBkeW5hbWljIG1lbW9yeS4gU28gZG8gbm90IHdhcm4KCSBmb3IgcG9pbnRlcnMgdG8gZnVuY3Rpb25zIG9yIHBvaW50ZXJzIHRvIG1lbWJlcnMuICAqLwogICAgICBpZiAoVFlQRV9QVFJfUCAodHlwZSkKCSAgJiYgIVRZUEVfUFRSRk5fUCAodHlwZSkKCSAgJiYgIVRZUEVfUFRSX1RPX01FTUJFUl9QICh0eXBlKSkKCWhhc19wb2ludGVycyA9IHRydWU7CgogICAgICBpZiAoQ0xBU1NfVFlQRV9QICh0eXBlKSkKCXsKCSAgaWYgKENMQVNTVFlQRV9SRUZfRklFTERTX05FRURfSU5JVCAodHlwZSkpCgkgICAgU0VUX0NMQVNTVFlQRV9SRUZfRklFTERTX05FRURfSU5JVCAodCwgMSk7CgkgIGlmIChDTEFTU1RZUEVfUkVBRE9OTFlfRklFTERTX05FRURfSU5JVCAodHlwZSkpCgkgICAgU0VUX0NMQVNTVFlQRV9SRUFET05MWV9GSUVMRFNfTkVFRF9JTklUICh0LCAxKTsKCX0KCiAgICAgIGlmIChERUNMX01VVEFCTEVfUCAoeCkgfHwgVFlQRV9IQVNfTVVUQUJMRV9QICh0eXBlKSkKCUNMQVNTVFlQRV9IQVNfTVVUQUJMRSAodCkgPSAxOwoKICAgICAgaWYgKCEgcG9kX3R5cGVfcCAodHlwZSkpCiAgICAgICAgLyogRFIgMTQ4IG5vdyBhbGxvd3MgcG9pbnRlcnMgdG8gbWVtYmVycyAod2hpY2ggYXJlIFBPRCB0aGVtc2VsdmVzKSwKICAgICAgICAgICB0byBiZSBhbGxvd2VkIGluIFBPRCBzdHJ1Y3RzLiAgKi8KCUNMQVNTVFlQRV9OT05fUE9EX1AgKHQpID0gMTsKCiAgICAgIGlmICghIHplcm9faW5pdF9wICh0eXBlKSkKCUNMQVNTVFlQRV9OT05fWkVST19JTklUX1AgKHQpID0gMTsKCiAgICAgIC8qIElmIGFueSBmaWVsZCBpcyBjb25zdCwgdGhlIHN0cnVjdHVyZSB0eXBlIGlzIHBzZXVkby1jb25zdC4gICovCiAgICAgIGlmIChDUF9UWVBFX0NPTlNUX1AgKHR5cGUpKQoJewoJICBDX1RZUEVfRklFTERTX1JFQURPTkxZICh0KSA9IDE7CgkgIGlmIChERUNMX0lOSVRJQUwgKHgpID09IE5VTExfVFJFRSkKCSAgICBTRVRfQ0xBU1NUWVBFX1JFQURPTkxZX0ZJRUxEU19ORUVEX0lOSVQgKHQsIDEpOwoKCSAgLyogQVJNICQxMi42LjI6IFtBIG1lbWJlciBpbml0aWFsaXplciBsaXN0XSAob3IsIGZvciBhbgoJICAgICBhZ2dyZWdhdGUsIGluaXRpYWxpemF0aW9uIGJ5IGEgYnJhY2UtZW5jbG9zZWQgbGlzdCkgaXMgdGhlCgkgICAgIG9ubHkgd2F5IHRvIGluaXRpYWxpemUgbm9uc3RhdGljIGNvbnN0IGFuZCByZWZlcmVuY2UKCSAgICAgbWVtYmVycy4gICovCgkgIFRZUEVfSEFTX0NPTVBMRVhfQVNTSUdOX1JFRiAodCkgPSAxOwoKCSAgaWYgKCEgVFlQRV9IQVNfQ09OU1RSVUNUT1IgKHQpICYmIENMQVNTVFlQRV9OT05fQUdHUkVHQVRFICh0KQoJICAgICAgJiYgZXh0cmFfd2FybmluZ3MpCiAgICAgICAgICAgIGNwX3dhcm5pbmdfYXQgKCJub24tc3RhdGljIGNvbnN0IG1lbWJlciAlcSNEIGluIGNsYXNzIHdpdGhvdXQgYSBjb25zdHJ1Y3RvciIsIHgpOwoJfQogICAgICAvKiBBIGZpZWxkIHRoYXQgaXMgcHNldWRvLWNvbnN0IG1ha2VzIHRoZSBzdHJ1Y3R1cmUgbGlrZXdpc2UuICAqLwogICAgICBlbHNlIGlmIChDTEFTU19UWVBFX1AgKHR5cGUpKQoJewoJICBDX1RZUEVfRklFTERTX1JFQURPTkxZICh0KSB8PSBDX1RZUEVfRklFTERTX1JFQURPTkxZICh0eXBlKTsKCSAgU0VUX0NMQVNTVFlQRV9SRUFET05MWV9GSUVMRFNfTkVFRF9JTklUICh0LAoJICAgIENMQVNTVFlQRV9SRUFET05MWV9GSUVMRFNfTkVFRF9JTklUICh0KQoJICAgIHwgQ0xBU1NUWVBFX1JFQURPTkxZX0ZJRUxEU19ORUVEX0lOSVQgKHR5cGUpKTsKCX0KCiAgICAgIC8qIENvcmUgaXNzdWUgODA6IEEgbm9uc3RhdGljIGRhdGEgbWVtYmVyIGlzIHJlcXVpcmVkIHRvIGhhdmUgYQoJIGRpZmZlcmVudCBuYW1lIGZyb20gdGhlIGNsYXNzIGlmZiB0aGUgY2xhc3MgaGFzIGEKCSB1c2VyLWRlZmluZWQgY29uc3RydWN0b3IuICAqLwogICAgICBpZiAoY29uc3RydWN0b3JfbmFtZV9wIChERUNMX05BTUUgKHgpLCB0KSAmJiBUWVBFX0hBU19DT05TVFJVQ1RPUiAodCkpCgljcF9wZWR3YXJuX2F0ICgiZmllbGQgJXEjRCB3aXRoIHNhbWUgbmFtZSBhcyBjbGFzcyIsIHgpOwoKICAgICAgLyogV2Ugc2V0IERFQ0xfQ19CSVRfRklFTEQgaW4gZ3Jva2JpdGZpZWxkLgoJIElmIHRoZSB0eXBlIGFuZCB3aWR0aCBhcmUgdmFsaWQsIHdlJ2xsIGFsc28gc2V0IERFQ0xfQklUX0ZJRUxELiAgKi8KICAgICAgaWYgKERFQ0xfQ19CSVRfRklFTEQgKHgpKQoJY2hlY2tfYml0ZmllbGRfZGVjbCAoeCk7CiAgICAgIGVsc2UKCWNoZWNrX2ZpZWxkX2RlY2wgKHgsIHQsCgkJCSAgY2FudF9oYXZlX2NvbnN0X2N0b3JfcCwKCQkJICBub19jb25zdF9hc25fcmVmX3AsCgkJCSAgJmFueV9kZWZhdWx0X21lbWJlcnMpOwogICAgfQoKICAvKiBFZmZlY3RpdmUgQysrIHJ1bGUgMTE6IGlmIGEgY2xhc3MgaGFzIGR5bmFtaWMgbWVtb3J5IGhlbGQgYnkgcG9pbnRlcnMsCiAgICAgaXQgc2hvdWxkIGFsc28gZGVmaW5lIGEgY29weSBjb25zdHJ1Y3RvciBhbmQgYW4gYXNzaWdubWVudCBvcGVyYXRvciB0bwogICAgIGltcGxlbWVudCB0aGUgY29ycmVjdCBjb3B5IHNlbWFudGljIChkZWVwIHZzIHNoYWxsb3csIGV0Yy4pLiBBcyBpdCBpcwogICAgIG5vdCBmZWFzaWJsZSB0byBjaGVjayB3aGV0aGVyIHRoZSBjb25zdHJ1Y3RvcnMgZG8gYWxsb2NhdGUgZHluYW1pYyBtZW1vcnkKICAgICBhbmQgc3RvcmUgaXQgd2l0aGluIG1lbWJlcnMsIHdlIGFwcHJveGltYXRlIHRoZSB3YXJuaW5nIGxpa2UgdGhpczoKCiAgICAgLS0gV2FybiBvbmx5IGlmIHRoZXJlIGFyZSBtZW1iZXJzIHdoaWNoIGFyZSBwb2ludGVycwogICAgIC0tIFdhcm4gb25seSBpZiB0aGVyZSBpcyBhIG5vbi10cml2aWFsIGNvbnN0cnVjdG9yIChvdGhlcndpc2UsCgl0aGVyZSBjYW5ub3QgYmUgbWVtb3J5IGFsbG9jYXRlZCkuCiAgICAgLS0gV2FybiBvbmx5IGlmIHRoZXJlIGlzIGEgbm9uLXRyaXZpYWwgZGVzdHJ1Y3Rvci4gV2UgYXNzdW1lIHRoYXQgdGhlCgl1c2VyIGF0IGxlYXN0IGltcGxlbWVudGVkIHRoZSBjbGVhbnVwIGNvcnJlY3RseSwgYW5kIGEgZGVzdHJ1Y3RvcgoJaXMgbmVlZGVkIHRvIGZyZWUgZHluYW1pYyBtZW1vcnkuCgkKICAgICBUaGlzIHNlZW1zIGVub3VnaCBmb3IgcHJhY3RpY2FsIHB1cnBvc2VzLiAgKi8KICAgIGlmICh3YXJuX2VjcHAKCSYmIGhhc19wb2ludGVycwoJJiYgVFlQRV9IQVNfQ09OU1RSVUNUT1IgKHQpCgkmJiBUWVBFX0hBU19OT05UUklWSUFMX0RFU1RSVUNUT1IgKHQpCgkmJiAhKFRZUEVfSEFTX0lOSVRfUkVGICh0KSAmJiBUWVBFX0hBU19BU1NJR05fUkVGICh0KSkpCiAgICB7CiAgICAgIHdhcm5pbmcgKCIlcSNUIGhhcyBwb2ludGVyIGRhdGEgbWVtYmVycyIsIHQpOwogICAgICAKICAgICAgaWYgKCEgVFlQRV9IQVNfSU5JVF9SRUYgKHQpKQoJewoJICB3YXJuaW5nICgiICBidXQgZG9lcyBub3Qgb3ZlcnJpZGUgJTwlVChjb25zdCAlVCYpJT4iLCB0LCB0KTsKCSAgaWYgKCEgVFlQRV9IQVNfQVNTSUdOX1JFRiAodCkpCgkgICAgd2FybmluZyAoIiAgb3IgJTxvcGVyYXRvcj0oY29uc3QgJVQmKSU+IiwgdCk7Cgl9CiAgICAgIGVsc2UgaWYgKCEgVFlQRV9IQVNfQVNTSUdOX1JFRiAodCkpCgl3YXJuaW5nICgiICBidXQgZG9lcyBub3Qgb3ZlcnJpZGUgJTxvcGVyYXRvcj0oY29uc3QgJVQmKSU+IiwgdCk7CiAgICB9CgoKICAvKiBDaGVjayBhbm9ueW1vdXMgc3RydWN0L2Fub255bW91cyB1bmlvbiBmaWVsZHMuICAqLwogIGZpbmlzaF9zdHJ1Y3RfYW5vbiAodCk7CgogIC8qIFdlJ3ZlIGJ1aWx0IHVwIHRoZSBsaXN0IG9mIGFjY2VzcyBkZWNsYXJhdGlvbnMgaW4gcmV2ZXJzZSBvcmRlci4KICAgICBGaXggdGhhdCBub3cuICAqLwogICphY2Nlc3NfZGVjbHMgPSBucmV2ZXJzZSAoKmFjY2Vzc19kZWNscyk7Cn0KCi8qIElmIFRZUEUgaXMgYW4gZW1wdHkgY2xhc3MgdHlwZSwgcmVjb3JkcyBpdHMgT0ZGU0VUIGluIHRoZSB0YWJsZSBvZgogICBPRkZTRVRTLiAgKi8KCnN0YXRpYyBpbnQKcmVjb3JkX3N1Ym9iamVjdF9vZmZzZXQgKHRyZWUgdHlwZSwgdHJlZSBvZmZzZXQsIHNwbGF5X3RyZWUgb2Zmc2V0cykKewogIHNwbGF5X3RyZWVfbm9kZSBuOwoKICBpZiAoIWlzX2VtcHR5X2NsYXNzICh0eXBlKSkKICAgIHJldHVybiAwOwoKICAvKiBSZWNvcmQgdGhlIGxvY2F0aW9uIG9mIHRoaXMgZW1wdHkgb2JqZWN0IGluIE9GRlNFVFMuICAqLwogIG4gPSBzcGxheV90cmVlX2xvb2t1cCAob2Zmc2V0cywgKHNwbGF5X3RyZWVfa2V5KSBvZmZzZXQpOwogIGlmICghbikKICAgIG4gPSBzcGxheV90cmVlX2luc2VydCAob2Zmc2V0cywgCgkJCSAgIChzcGxheV90cmVlX2tleSkgb2Zmc2V0LAoJCQkgICAoc3BsYXlfdHJlZV92YWx1ZSkgTlVMTF9UUkVFKTsKICBuLT52YWx1ZSA9ICgoc3BsYXlfdHJlZV92YWx1ZSkgCgkgICAgICB0cmVlX2NvbnMgKE5VTExfVFJFRSwKCQkJIHR5cGUsCgkJCSAodHJlZSkgbi0+dmFsdWUpKTsKCiAgcmV0dXJuIDA7Cn0KCi8qIFJldHVybnMgbm9uemVybyBpZiBUWVBFIGlzIGFuIGVtcHR5IGNsYXNzIHR5cGUgYW5kIHRoZXJlIGlzCiAgIGFscmVhZHkgYW4gZW50cnkgaW4gT0ZGU0VUUyBmb3IgdGhlIHNhbWUgVFlQRSBhcyB0aGUgc2FtZSBPRkZTRVQuICAqLwoKc3RhdGljIGludApjaGVja19zdWJvYmplY3Rfb2Zmc2V0ICh0cmVlIHR5cGUsIHRyZWUgb2Zmc2V0LCBzcGxheV90cmVlIG9mZnNldHMpCnsKICBzcGxheV90cmVlX25vZGUgbjsKICB0cmVlIHQ7CgogIGlmICghaXNfZW1wdHlfY2xhc3MgKHR5cGUpKQogICAgcmV0dXJuIDA7CgogIC8qIFJlY29yZCB0aGUgbG9jYXRpb24gb2YgdGhpcyBlbXB0eSBvYmplY3QgaW4gT0ZGU0VUUy4gICovCiAgbiA9IHNwbGF5X3RyZWVfbG9va3VwIChvZmZzZXRzLCAoc3BsYXlfdHJlZV9rZXkpIG9mZnNldCk7CiAgaWYgKCFuKQogICAgcmV0dXJuIDA7CgogIGZvciAodCA9ICh0cmVlKSBuLT52YWx1ZTsgdDsgdCA9IFRSRUVfQ0hBSU4gKHQpKQogICAgaWYgKHNhbWVfdHlwZV9wIChUUkVFX1ZBTFVFICh0KSwgdHlwZSkpCiAgICAgIHJldHVybiAxOwoKICByZXR1cm4gMDsKfQoKLyogV2FsayB0aHJvdWdoIGFsbCB0aGUgc3Vib2JqZWN0cyBvZiBUWVBFIChsb2NhdGVkIGF0IE9GRlNFVCkuICBDYWxsCiAgIEYgZm9yIGV2ZXJ5IHN1Ym9iamVjdCwgcGFzc2luZyBpdCB0aGUgdHlwZSwgb2Zmc2V0LCBhbmQgdGFibGUgb2YKICAgT0ZGU0VUUy4gIElmIFZCQVNFU19QIGlzIG9uZSwgdGhlbiB2aXJ0dWFsIG5vbi1wcmltYXJ5IGJhc2VzIHNob3VsZAogICBiZSB0cmF2ZXJzZWQuCgogICBJZiBNQVhfT0ZGU0VUIGlzIG5vbi1OVUxMLCB0aGVuIHN1Ym9iamVjdHMgd2l0aCBhbiBvZmZzZXQgZ3JlYXRlcgogICB0aGFuIE1BWF9PRkZTRVQgd2lsbCBub3QgYmUgd2Fsa2VkLgoKICAgSWYgRiByZXR1cm5zIGEgbm9uemVybyB2YWx1ZSwgdGhlIHRyYXZlcnNhbCBjZWFzZXMsIGFuZCB0aGF0IHZhbHVlCiAgIGlzIHJldHVybmVkLiAgT3RoZXJ3aXNlLCByZXR1cm5zIHplcm8uICAqLwoKc3RhdGljIGludAp3YWxrX3N1Ym9iamVjdF9vZmZzZXRzICh0cmVlIHR5cGUsIAogICAgICAgICAgICAgICAgICAgICAgICBzdWJvYmplY3Rfb2Zmc2V0X2ZuIGYsIAogICAgICAgICAgICAgICAgICAgICAgICB0cmVlIG9mZnNldCwgCiAgICAgICAgICAgICAgICAgICAgICAgIHNwbGF5X3RyZWUgb2Zmc2V0cywgCiAgICAgICAgICAgICAgICAgICAgICAgIHRyZWUgbWF4X29mZnNldCwgCiAgICAgICAgICAgICAgICAgICAgICAgIGludCB2YmFzZXNfcCkKewogIGludCByID0gMDsKICB0cmVlIHR5cGVfYmluZm8gPSBOVUxMX1RSRUU7CgogIC8qIElmIHRoaXMgT0ZGU0VUIGlzIGJpZ2dlciB0aGFuIHRoZSBNQVhfT0ZGU0VULCB0aGVuIHdlIHNob3VsZAogICAgIHN0b3AuICAqLwogIGlmIChtYXhfb2Zmc2V0ICYmIElOVF9DU1RfTFQgKG1heF9vZmZzZXQsIG9mZnNldCkpCiAgICByZXR1cm4gMDsKCiAgaWYgKCFUWVBFX1AgKHR5cGUpKSAKICAgIHsKICAgICAgaWYgKGFiaV92ZXJzaW9uX2F0X2xlYXN0ICgyKSkKCXR5cGVfYmluZm8gPSB0eXBlOwogICAgICB0eXBlID0gQklORk9fVFlQRSAodHlwZSk7CiAgICB9CgogIGlmIChDTEFTU19UWVBFX1AgKHR5cGUpKQogICAgewogICAgICB0cmVlIGZpZWxkOwogICAgICB0cmVlIGJpbmZvOwogICAgICBpbnQgaTsKCiAgICAgIC8qIEF2b2lkIHJlY3Vyc2luZyBpbnRvIG9iamVjdHMgdGhhdCBhcmUgbm90IGludGVyZXN0aW5nLiAgKi8KICAgICAgaWYgKCFDTEFTU1RZUEVfQ09OVEFJTlNfRU1QVFlfQ0xBU1NfUCAodHlwZSkpCglyZXR1cm4gMDsKCiAgICAgIC8qIFJlY29yZCB0aGUgbG9jYXRpb24gb2YgVFlQRS4gICovCiAgICAgIHIgPSAoKmYpICh0eXBlLCBvZmZzZXQsIG9mZnNldHMpOwogICAgICBpZiAocikKCXJldHVybiByOwoKICAgICAgLyogSXRlcmF0ZSB0aHJvdWdoIHRoZSBkaXJlY3QgYmFzZSBjbGFzc2VzIG9mIFRZUEUuICAqLwogICAgICBpZiAoIXR5cGVfYmluZm8pCgl0eXBlX2JpbmZvID0gVFlQRV9CSU5GTyAodHlwZSk7CiAgICAgIGZvciAoaSA9IDA7IEJJTkZPX0JBU0VfSVRFUkFURSAodHlwZV9iaW5mbywgaSwgYmluZm8pOyBpKyspCgl7CgkgIHRyZWUgYmluZm9fb2Zmc2V0OwoKCSAgaWYgKGFiaV92ZXJzaW9uX2F0X2xlYXN0ICgyKSAKCSAgICAgICYmIEJJTkZPX1ZJUlRVQUxfUCAoYmluZm8pKQoJICAgIGNvbnRpbnVlOwoKCSAgaWYgKCF2YmFzZXNfcCAKCSAgICAgICYmIEJJTkZPX1ZJUlRVQUxfUCAoYmluZm8pIAoJICAgICAgJiYgIUJJTkZPX1BSSU1BUllfUCAoYmluZm8pKQoJICAgIGNvbnRpbnVlOwoKCSAgaWYgKCFhYmlfdmVyc2lvbl9hdF9sZWFzdCAoMikpCgkgICAgYmluZm9fb2Zmc2V0ID0gc2l6ZV9iaW5vcCAoUExVU19FWFBSLAoJCQkJICAgICAgIG9mZnNldCwKCQkJCSAgICAgICBCSU5GT19PRkZTRVQgKGJpbmZvKSk7CgkgIGVsc2UKCSAgICB7CgkgICAgICB0cmVlIG9yaWdfYmluZm87CgkgICAgICAvKiBXZSBjYW5ub3QgcmVseSBvbiBCSU5GT19PRkZTRVQgYmVpbmcgc2V0IGZvciB0aGUgYmFzZQoJCSBjbGFzcyB5ZXQsIGJ1dCB0aGUgb2Zmc2V0cyBmb3IgZGlyZWN0IG5vbi12aXJ0dWFsCgkJIGJhc2VzIGNhbiBiZSBjYWxjdWxhdGVkIGJ5IGdvaW5nIGJhY2sgdG8gdGhlIFRZUEUuICAqLwoJICAgICAgb3JpZ19iaW5mbyA9IEJJTkZPX0JBU0VfQklORk8gKFRZUEVfQklORk8gKHR5cGUpLCBpKTsKCSAgICAgIGJpbmZvX29mZnNldCA9IHNpemVfYmlub3AgKFBMVVNfRVhQUiwJICAgICAgCgkJCQkJIG9mZnNldCwKCQkJCQkgQklORk9fT0ZGU0VUIChvcmlnX2JpbmZvKSk7CgkgICAgfQoKCSAgciA9IHdhbGtfc3Vib2JqZWN0X29mZnNldHMgKGJpbmZvLAoJCQkJICAgICAgZiwKCQkJCSAgICAgIGJpbmZvX29mZnNldCwKCQkJCSAgICAgIG9mZnNldHMsCgkJCQkgICAgICBtYXhfb2Zmc2V0LAoJCQkJICAgICAgKGFiaV92ZXJzaW9uX2F0X2xlYXN0ICgyKSAKCQkJCSAgICAgICA/IC8qdmJhc2VzX3A9Ki8wIDogdmJhc2VzX3ApKTsKCSAgaWYgKHIpCgkgICAgcmV0dXJuIHI7Cgl9CgogICAgICBpZiAoYWJpX3ZlcnNpb25fYXRfbGVhc3QgKDIpICYmIENMQVNTVFlQRV9WQkFTRUNMQVNTRVMgKHR5cGUpKQoJewoJICB1bnNpZ25lZCBpeDsKCSAgVkVDICh0cmVlKSAqdmJhc2VzOwoKCSAgLyogSXRlcmF0ZSB0aHJvdWdoIHRoZSB2aXJ0dWFsIGJhc2UgY2xhc3NlcyBvZiBUWVBFLiAgSW4gRysrCgkgICAgIDMuMiwgd2UgaW5jbHVkZWQgdmlydHVhbCBiYXNlcyBpbiB0aGUgZGlyZWN0IGJhc2UgY2xhc3MKCSAgICAgbG9vcCBhYm92ZSwgd2hpY2ggcmVzdWx0cyBpbiBpbmNvcnJlY3QgcmVzdWx0czsgdGhlCgkgICAgIGNvcnJlY3Qgb2Zmc2V0cyBmb3IgdmlydHVhbCBiYXNlcyBhcmUgb25seSBrbm93biB3aGVuCgkgICAgIHdvcmtpbmcgd2l0aCB0aGUgbW9zdCBkZXJpdmVkIHR5cGUuICAqLwoJICBpZiAodmJhc2VzX3ApCgkgICAgZm9yICh2YmFzZXMgPSBDTEFTU1RZUEVfVkJBU0VDTEFTU0VTICh0eXBlKSwgaXggPSAwOwoJCSBWRUNfaXRlcmF0ZSAodHJlZSwgdmJhc2VzLCBpeCwgYmluZm8pOyBpeCsrKQoJICAgICAgewoJCXIgPSB3YWxrX3N1Ym9iamVjdF9vZmZzZXRzIChiaW5mbywKCQkJCQkgICAgZiwKCQkJCQkgICAgc2l6ZV9iaW5vcCAoUExVU19FWFBSLAoJCQkJCQkJb2Zmc2V0LAoJCQkJCQkJQklORk9fT0ZGU0VUIChiaW5mbykpLAoJCQkJCSAgICBvZmZzZXRzLAoJCQkJCSAgICBtYXhfb2Zmc2V0LAoJCQkJCSAgICAvKnZiYXNlc19wPSovMCk7CgkJaWYgKHIpCgkJICByZXR1cm4gcjsKCSAgICAgIH0KCSAgZWxzZQoJICAgIHsKCSAgICAgIC8qIFdlIHN0aWxsIGhhdmUgdG8gd2FsayB0aGUgcHJpbWFyeSBiYXNlLCBpZiBpdCBpcwoJCSB2aXJ0dWFsLiAgKElmIGl0IGlzIG5vbi12aXJ0dWFsLCB0aGVuIGl0IHdhcyB3YWxrZWQKCQkgYWJvdmUuKSAgKi8KCSAgICAgIHRyZWUgdmJhc2UgPSBnZXRfcHJpbWFyeV9iaW5mbyAodHlwZV9iaW5mbyk7CgkgICAgICAKCSAgICAgIGlmICh2YmFzZSAmJiBCSU5GT19WSVJUVUFMX1AgKHZiYXNlKQoJCSAgJiYgQklORk9fUFJJTUFSWV9QICh2YmFzZSkKCQkgICYmIEJJTkZPX0lOSEVSSVRBTkNFX0NIQUlOICh2YmFzZSkgPT0gdHlwZV9iaW5mbykKCQl7CgkJICByID0gKHdhbGtfc3Vib2JqZWN0X29mZnNldHMgCgkJICAgICAgICh2YmFzZSwgZiwgb2Zmc2V0LAoJCQlvZmZzZXRzLCBtYXhfb2Zmc2V0LCAvKnZiYXNlc19wPSovMCkpOwoJCSAgaWYgKHIpCgkJICAgIHJldHVybiByOwoJCX0KCSAgICB9Cgl9CgogICAgICAvKiBJdGVyYXRlIHRocm91Z2ggdGhlIGZpZWxkcyBvZiBUWVBFLiAgKi8KICAgICAgZm9yIChmaWVsZCA9IFRZUEVfRklFTERTICh0eXBlKTsgZmllbGQ7IGZpZWxkID0gVFJFRV9DSEFJTiAoZmllbGQpKQoJaWYgKFRSRUVfQ09ERSAoZmllbGQpID09IEZJRUxEX0RFQ0wgJiYgIURFQ0xfQVJUSUZJQ0lBTCAoZmllbGQpKQoJICB7CgkgICAgdHJlZSBmaWVsZF9vZmZzZXQ7CgoJICAgIGlmIChhYmlfdmVyc2lvbl9hdF9sZWFzdCAoMikpCgkgICAgICBmaWVsZF9vZmZzZXQgPSBieXRlX3Bvc2l0aW9uIChmaWVsZCk7CgkgICAgZWxzZQoJICAgICAgLyogSW4gRysrIDMuMiwgREVDTF9GSUVMRF9PRkZTRVQgd2FzIHVzZWQuICAqLwoJICAgICAgZmllbGRfb2Zmc2V0ID0gREVDTF9GSUVMRF9PRkZTRVQgKGZpZWxkKTsKCgkgICAgciA9IHdhbGtfc3Vib2JqZWN0X29mZnNldHMgKFRSRUVfVFlQRSAoZmllbGQpLAoJCQkJCWYsCgkJCQkJc2l6ZV9iaW5vcCAoUExVU19FWFBSLAoJCQkJCQkgICAgb2Zmc2V0LAoJCQkJCQkgICAgZmllbGRfb2Zmc2V0KSwKCQkJCQlvZmZzZXRzLAoJCQkJCW1heF9vZmZzZXQsCgkJCQkJLyp2YmFzZXNfcD0qLzEpOwoJICAgIGlmIChyKQoJICAgICAgcmV0dXJuIHI7CgkgIH0KICAgIH0KICBlbHNlIGlmIChUUkVFX0NPREUgKHR5cGUpID09IEFSUkFZX1RZUEUpCiAgICB7CiAgICAgIHRyZWUgZWxlbWVudF90eXBlID0gc3RyaXBfYXJyYXlfdHlwZXMgKHR5cGUpOwogICAgICB0cmVlIGRvbWFpbiA9IFRZUEVfRE9NQUlOICh0eXBlKTsKICAgICAgdHJlZSBpbmRleDsKCiAgICAgIC8qIEF2b2lkIHJlY3Vyc2luZyBpbnRvIG9iamVjdHMgdGhhdCBhcmUgbm90IGludGVyZXN0aW5nLiAgKi8KICAgICAgaWYgKCFDTEFTU19UWVBFX1AgKGVsZW1lbnRfdHlwZSkKCSAgfHwgIUNMQVNTVFlQRV9DT05UQUlOU19FTVBUWV9DTEFTU19QIChlbGVtZW50X3R5cGUpKQoJcmV0dXJuIDA7CgogICAgICAvKiBTdGVwIHRocm91Z2ggZWFjaCBvZiB0aGUgZWxlbWVudHMgaW4gdGhlIGFycmF5LiAgKi8KICAgICAgZm9yIChpbmRleCA9IHNpemVfemVyb19ub2RlOwoJICAgLyogRysrIDMuMiBoYWQgYW4gb2ZmLWJ5LW9uZSBlcnJvciBoZXJlLiAgKi8KCSAgIChhYmlfdmVyc2lvbl9hdF9sZWFzdCAoMikgCgkgICAgPyAhSU5UX0NTVF9MVCAoVFlQRV9NQVhfVkFMVUUgKGRvbWFpbiksIGluZGV4KQoJICAgIDogSU5UX0NTVF9MVCAoaW5kZXgsIFRZUEVfTUFYX1ZBTFVFIChkb21haW4pKSk7CgkgICBpbmRleCA9IHNpemVfYmlub3AgKFBMVVNfRVhQUiwgaW5kZXgsIHNpemVfb25lX25vZGUpKQoJewoJICByID0gd2Fsa19zdWJvYmplY3Rfb2Zmc2V0cyAoVFJFRV9UWVBFICh0eXBlKSwKCQkJCSAgICAgIGYsCgkJCQkgICAgICBvZmZzZXQsCgkJCQkgICAgICBvZmZzZXRzLAoJCQkJICAgICAgbWF4X29mZnNldCwKCQkJCSAgICAgIC8qdmJhc2VzX3A9Ki8xKTsKCSAgaWYgKHIpCgkgICAgcmV0dXJuIHI7CgkgIG9mZnNldCA9IHNpemVfYmlub3AgKFBMVVNfRVhQUiwgb2Zmc2V0LCAKCQkJICAgICAgIFRZUEVfU0laRV9VTklUIChUUkVFX1RZUEUgKHR5cGUpKSk7CgkgIC8qIElmIHRoaXMgbmV3IE9GRlNFVCBpcyBiaWdnZXIgdGhhbiB0aGUgTUFYX09GRlNFVCwgdGhlbgoJICAgICB0aGVyZSdzIG5vIHBvaW50IGluIGl0ZXJhdGluZyB0aHJvdWdoIHRoZSByZW1haW5pbmcKCSAgICAgZWxlbWVudHMgb2YgdGhlIGFycmF5LiAgKi8KCSAgaWYgKG1heF9vZmZzZXQgJiYgSU5UX0NTVF9MVCAobWF4X29mZnNldCwgb2Zmc2V0KSkKCSAgICBicmVhazsKCX0KICAgIH0KCiAgcmV0dXJuIDA7Cn0KCi8qIFJlY29yZCBhbGwgb2YgdGhlIGVtcHR5IHN1Ym9iamVjdHMgb2YgVFlQRSAobG9jYXRlZCBhdCBPRkZTRVQpIGluCiAgIE9GRlNFVFMuICBJZiBWQkFTRVNfUCBpcyBub256ZXJvLCB2aXJ0dWFsIGJhc2VzIG9mIFRZUEUgYXJlCiAgIGV4YW1pbmVkLiAgKi8KCnN0YXRpYyB2b2lkCnJlY29yZF9zdWJvYmplY3Rfb2Zmc2V0cyAodHJlZSB0eXBlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICB0cmVlIG9mZnNldCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgc3BsYXlfdHJlZSBvZmZzZXRzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgdmJhc2VzX3ApCnsKICB3YWxrX3N1Ym9iamVjdF9vZmZzZXRzICh0eXBlLCByZWNvcmRfc3Vib2JqZWN0X29mZnNldCwgb2Zmc2V0LAoJCQkgIG9mZnNldHMsIC8qbWF4X29mZnNldD0qL05VTExfVFJFRSwgdmJhc2VzX3ApOwp9CgovKiBSZXR1cm5zIG5vbnplcm8gaWYgYW55IG9mIHRoZSBlbXB0eSBzdWJvYmplY3RzIG9mIFRZUEUgKGxvY2F0ZWQgYXQKICAgT0ZGU0VUKSBjb25mbGljdCB3aXRoIGVudHJpZXMgaW4gT0ZGU0VUUy4gIElmIFZCQVNFU19QIGlzIG5vbnplcm8sCiAgIHZpcnR1YWwgYmFzZXMgb2YgVFlQRSBhcmUgZXhhbWluZWQuICAqLwoKc3RhdGljIGludApsYXlvdXRfY29uZmxpY3RfcCAodHJlZSB0eXBlLAogICAgICAgICAgICAgICAgICAgdHJlZSBvZmZzZXQsIAogICAgICAgICAgICAgICAgICAgc3BsYXlfdHJlZSBvZmZzZXRzLCAKICAgICAgICAgICAgICAgICAgIGludCB2YmFzZXNfcCkKewogIHNwbGF5X3RyZWVfbm9kZSBtYXhfbm9kZTsKCiAgLyogR2V0IHRoZSBub2RlIGluIE9GRlNFVFMgdGhhdCBpbmRpY2F0ZXMgdGhlIG1heGltdW0gb2Zmc2V0IHdoZXJlCiAgICAgYW4gZW1wdHkgc3Vib2JqZWN0IGlzIGxvY2F0ZWQuICAqLwogIG1heF9ub2RlID0gc3BsYXlfdHJlZV9tYXggKG9mZnNldHMpOwogIC8qIElmIHRoZXJlIGFyZW4ndCBhbnkgZW1wdHkgc3Vib2JqZWN0cywgdGhlbiB0aGVyZSdzIG5vIHBvaW50IGluCiAgICAgcGVyZm9ybWluZyB0aGlzIGNoZWNrLiAgKi8KICBpZiAoIW1heF9ub2RlKQogICAgcmV0dXJuIDA7CgogIHJldHVybiB3YWxrX3N1Ym9iamVjdF9vZmZzZXRzICh0eXBlLCBjaGVja19zdWJvYmplY3Rfb2Zmc2V0LCBvZmZzZXQsCgkJCQkgb2Zmc2V0cywgKHRyZWUpIChtYXhfbm9kZS0+a2V5KSwKCQkJCSB2YmFzZXNfcCk7Cn0KCi8qIERFQ0wgaXMgYSBGSUVMRF9ERUNMIGNvcnJlc3BvbmRpbmcgZWl0aGVyIHRvIGEgYmFzZSBzdWJvYmplY3Qgb2YgYQogICBub24tc3RhdGljIGRhdGEgbWVtYmVyIG9mIHRoZSB0eXBlIGluZGljYXRlZCBieSBSTEkuICBCSU5GTyBpcyB0aGUKICAgYmluZm8gY29ycmVzcG9uZGluZyB0byB0aGUgYmFzZSBzdWJvYmplY3QsIE9GRlNFVFMgbWFwcyBvZmZzZXRzIHRvCiAgIHR5cGVzIGFscmVhZHkgbG9jYXRlZCBhdCB0aG9zZSBvZmZzZXRzLiAgVGhpcyBmdW5jdGlvbiBkZXRlcm1pbmVzCiAgIHRoZSBwb3NpdGlvbiBvZiB0aGUgREVDTC4gICovCgpzdGF0aWMgdm9pZApsYXlvdXRfbm9uZW1wdHlfYmFzZV9vcl9maWVsZCAocmVjb3JkX2xheW91dF9pbmZvIHJsaSwgCgkJCSAgICAgICB0cmVlIGRlY2wsIAoJCQkgICAgICAgdHJlZSBiaW5mbywgCgkJCSAgICAgICBzcGxheV90cmVlIG9mZnNldHMpCnsKICB0cmVlIG9mZnNldCA9IE5VTExfVFJFRTsKICBib29sIGZpZWxkX3A7CiAgdHJlZSB0eXBlOwogIAogIGlmIChiaW5mbykKICAgIHsKICAgICAgLyogRm9yIHRoZSBwdXJwb3NlcyBvZiBkZXRlcm1pbmluZyBsYXlvdXQgY29uZmxpY3RzLCB3ZSB3YW50IHRvCgkgdXNlIHRoZSBjbGFzcyB0eXBlIG9mIEJJTkZPOyBUUkVFX1RZUEUgKERFQ0wpIHdpbGwgYmUgdGhlCgkgQ0xBU1NUWVBFX0FTX0JBU0UgdmVyc2lvbiwgd2hpY2ggZG9lcyBub3QgY29udGFpbiBlbnRyaWVzIGZvcgoJIHplcm8tc2l6ZWQgYmFzZXMuICAqLwogICAgICB0eXBlID0gVFJFRV9UWVBFIChiaW5mbyk7CiAgICAgIGZpZWxkX3AgPSBmYWxzZTsKICAgIH0KICBlbHNlCiAgICB7CiAgICAgIHR5cGUgPSBUUkVFX1RZUEUgKGRlY2wpOwogICAgICBmaWVsZF9wID0gdHJ1ZTsKICAgIH0KCiAgLyogVHJ5IHRvIHBsYWNlIHRoZSBmaWVsZC4gIEl0IG1heSB0YWtlIG1vcmUgdGhhbiBvbmUgdHJ5IGlmIHdlIGhhdmUKICAgICBhIGhhcmQgdGltZSBwbGFjaW5nIHRoZSBmaWVsZCB3aXRob3V0IHB1dHRpbmcgdHdvIG9iamVjdHMgb2YgdGhlCiAgICAgc2FtZSB0eXBlIGF0IHRoZSBzYW1lIGFkZHJlc3MuICAqLwogIHdoaWxlICgxKQogICAgewogICAgICBzdHJ1Y3QgcmVjb3JkX2xheW91dF9pbmZvX3Mgb2xkX3JsaSA9ICpybGk7CgogICAgICAvKiBQbGFjZSB0aGlzIGZpZWxkLiAgKi8KICAgICAgcGxhY2VfZmllbGQgKHJsaSwgZGVjbCk7CiAgICAgIG9mZnNldCA9IGJ5dGVfcG9zaXRpb24gKGRlY2wpOwoKICAgICAgLyogV2UgaGF2ZSB0byBjaGVjayB0byBzZWUgd2hldGhlciBvciBub3QgdGhlcmUgaXMgYWxyZWFkeQoJIHNvbWV0aGluZyBvZiB0aGUgc2FtZSB0eXBlIGF0IHRoZSBvZmZzZXQgd2UncmUgYWJvdXQgdG8gdXNlLgoJIEZvciBleGFtcGxlLCBjb25zaWRlcjoKCSAKCSAgIHN0cnVjdCBTIHt9OwoJICAgc3RydWN0IFQgOiBwdWJsaWMgUyB7IGludCBpOyB9OwoJICAgc3RydWN0IFUgOiBwdWJsaWMgUywgcHVibGljIFQge307CgkgCgkgSGVyZSwgd2UgcHV0IFMgYXQgb2Zmc2V0IHplcm8gaW4gVS4gIFRoZW4sIHdlIGNhbid0IHB1dCBUIGF0Cgkgb2Zmc2V0IHplcm8gLS0gaXRzIFMgY29tcG9uZW50IHdvdWxkIGJlIGF0IHRoZSBzYW1lIGFkZHJlc3MKCSBhcyB0aGUgUyB3ZSBhbHJlYWR5IGFsbG9jYXRlZC4gIFNvLCB3ZSBoYXZlIHRvIHNraXAgYWhlYWQuCgkgU2luY2UgYWxsIGRhdGEgbWVtYmVycywgaW5jbHVkaW5nIHRob3NlIHdob3NlIHR5cGUgaXMgYW4KCSBlbXB0eSBjbGFzcywgaGF2ZSBub256ZXJvIHNpemUsIGFueSBvdmVybGFwIGNhbiBoYXBwZW4gb25seQoJIHdpdGggYSBkaXJlY3Qgb3IgaW5kaXJlY3QgYmFzZS1jbGFzcyAtLSBpdCBjYW4ndCBoYXBwZW4gd2l0aAoJIGEgZGF0YSBtZW1iZXIuICAqLwogICAgICAvKiBJbiBhIHVuaW9uLCBvdmVybGFwIGlzIHBlcm1pdHRlZDsgYWxsIG1lbWJlcnMgYXJlIHBsYWNlZCBhdAoJIG9mZnNldCB6ZXJvLiAgKi8KICAgICAgaWYgKFRSRUVfQ09ERSAocmxpLT50KSA9PSBVTklPTl9UWVBFKQoJYnJlYWs7CiAgICAgIC8qIEcrKyAzLjIgZGlkIG5vdCBjaGVjayBmb3Igb3ZlcmxhcHMgd2hlbiBwbGFjaW5nIGEgbm9uLWVtcHR5CgkgdmlydHVhbCBiYXNlLiAgKi8KICAgICAgaWYgKCFhYmlfdmVyc2lvbl9hdF9sZWFzdCAoMikgJiYgYmluZm8gJiYgQklORk9fVklSVFVBTF9QIChiaW5mbykpCglicmVhazsKICAgICAgaWYgKGxheW91dF9jb25mbGljdF9wIChmaWVsZF9wID8gdHlwZSA6IGJpbmZvLCBvZmZzZXQsIAoJCQkgICAgIG9mZnNldHMsIGZpZWxkX3ApKQoJewoJICAvKiBTdHJpcCBvZmYgdGhlIHNpemUgYWxsb2NhdGVkIHRvIHRoaXMgZmllbGQuICBUaGF0IHB1dHMgdXMKCSAgICAgYXQgdGhlIGZpcnN0IHBsYWNlIHdlIGNvdWxkIGhhdmUgcHV0IHRoZSBmaWVsZCB3aXRoCgkgICAgIHByb3BlciBhbGlnbm1lbnQuICAqLwoJICAqcmxpID0gb2xkX3JsaTsKCgkgIC8qIEJ1bXAgdXAgYnkgdGhlIGFsaWdubWVudCByZXF1aXJlZCBmb3IgdGhlIHR5cGUuICAqLwoJICBybGktPmJpdHBvcwoJICAgID0gc2l6ZV9iaW5vcCAoUExVU19FWFBSLCBybGktPmJpdHBvcywgCgkJCSAgYml0c2l6ZV9pbnQgKGJpbmZvIAoJCQkJICAgICAgID8gQ0xBU1NUWVBFX0FMSUdOICh0eXBlKQoJCQkJICAgICAgIDogVFlQRV9BTElHTiAodHlwZSkpKTsKCSAgbm9ybWFsaXplX3JsaSAocmxpKTsKCX0KICAgICAgZWxzZQoJLyogVGhlcmUgd2FzIG5vIGNvbmZsaWN0LiAgV2UncmUgZG9uZSBsYXlpbmcgb3V0IHRoaXMgZmllbGQuICAqLwoJYnJlYWs7CiAgICB9CgogIC8qIE5vdyB0aGF0IHdlIGtub3cgd2hlcmUgaXQgd2lsbCBiZSBwbGFjZWQsIHVwZGF0ZSBpdHMKICAgICBCSU5GT19PRkZTRVQuICAqLwogIGlmIChiaW5mbyAmJiBDTEFTU19UWVBFX1AgKEJJTkZPX1RZUEUgKGJpbmZvKSkpCiAgICAvKiBJbmRpcmVjdCB2aXJ0dWFsIGJhc2VzIG1heSBoYXZlIGEgbm9uemVybyBCSU5GT19PRkZTRVQgYXQKICAgICAgIHRoaXMgcG9pbnQgYmVjYXVzZSB0aGVpciBCSU5GT19PRkZTRVQgaXMgY29waWVkIGZyb20gYW5vdGhlcgogICAgICAgaGllcmFyY2h5LiAgVGhlcmVmb3JlLCB3ZSBtYXkgbm90IG5lZWQgdG8gYWRkIHRoZSBlbnRpcmUKICAgICAgIE9GRlNFVC4gICovCiAgICBwcm9wYWdhdGVfYmluZm9fb2Zmc2V0cyAoYmluZm8sIAoJCQkgICAgIHNpemVfZGlmZm9wIChjb252ZXJ0IChzc2l6ZXR5cGUsIG9mZnNldCksCgkJCQkJICBjb252ZXJ0IChzc2l6ZXR5cGUsIAoJCQkJCQkgICBCSU5GT19PRkZTRVQgKGJpbmZvKSkpKTsKfQoKLyogUmV0dXJucyB0cnVlIGlmIFRZUEUgaXMgZW1wdHkgYW5kIE9GRlNFVCBpcyBub256ZXJvLiAgKi8KCnN0YXRpYyBpbnQKZW1wdHlfYmFzZV9hdF9ub256ZXJvX29mZnNldF9wICh0cmVlIHR5cGUsCgkJCQl0cmVlIG9mZnNldCwKCQkJCXNwbGF5X3RyZWUgb2Zmc2V0cyBBVFRSSUJVVEVfVU5VU0VEKQp7CiAgcmV0dXJuIGlzX2VtcHR5X2NsYXNzICh0eXBlKSAmJiAhaW50ZWdlcl96ZXJvcCAob2Zmc2V0KTsKfQoKLyogTGF5b3V0IHRoZSBlbXB0eSBiYXNlIEJJTkZPLiAgRU9DIGluZGljYXRlcyB0aGUgYnl0ZSBjdXJyZW50bHkganVzdAogICBwYXN0IHRoZSBlbmQgb2YgdGhlIGNsYXNzLCBhbmQgc2hvdWxkIGJlIGNvcnJlY3RseSBhbGlnbmVkIGZvciBhCiAgIGNsYXNzIG9mIHRoZSB0eXBlIGluZGljYXRlZCBieSBCSU5GTzsgT0ZGU0VUUyBnaXZlcyB0aGUgb2Zmc2V0cyBvZgogICB0aGUgZW1wdHkgYmFzZXMgYWxsb2NhdGVkIHNvIGZhci4gVCBpcyB0aGUgbW9zdCBkZXJpdmVkCiAgIHR5cGUuICBSZXR1cm4gbm9uemVybyBpZmYgd2UgYWRkZWQgaXQgYXQgdGhlIGVuZC4gICovCgpzdGF0aWMgYm9vbApsYXlvdXRfZW1wdHlfYmFzZSAodHJlZSBiaW5mbywgdHJlZSBlb2MsIHNwbGF5X3RyZWUgb2Zmc2V0cykKewogIHRyZWUgYWxpZ25tZW50OwogIHRyZWUgYmFzZXR5cGUgPSBCSU5GT19UWVBFIChiaW5mbyk7CiAgYm9vbCBhdGVuZCA9IGZhbHNlOwoKICAvKiBUaGlzIHJvdXRpbmUgc2hvdWxkIG9ubHkgYmUgdXNlZCBmb3IgZW1wdHkgY2xhc3Nlcy4gICovCiAgZ2NjX2Fzc2VydCAoaXNfZW1wdHlfY2xhc3MgKGJhc2V0eXBlKSk7CiAgYWxpZ25tZW50ID0gc3NpemVfaW50IChDTEFTU1RZUEVfQUxJR05fVU5JVCAoYmFzZXR5cGUpKTsKCiAgaWYgKCFpbnRlZ2VyX3plcm9wIChCSU5GT19PRkZTRVQgKGJpbmZvKSkpCiAgICB7CiAgICAgIGlmIChhYmlfdmVyc2lvbl9hdF9sZWFzdCAoMikpCglwcm9wYWdhdGVfYmluZm9fb2Zmc2V0cwoJICAoYmluZm8sIHNpemVfZGlmZm9wIChzaXplX3plcm9fbm9kZSwgQklORk9fT0ZGU0VUIChiaW5mbykpKTsKICAgICAgZWxzZSBpZiAod2Fybl9hYmkpCgl3YXJuaW5nICgib2Zmc2V0IG9mIGVtcHR5IGJhc2UgJXFUIG1heSBub3QgYmUgQUJJLWNvbXBsaWFudCBhbmQgbWF5IgoJCSAiY2hhbmdlIGluIGEgZnV0dXJlIHZlcnNpb24gb2YgR0NDIiwKCQkgQklORk9fVFlQRSAoYmluZm8pKTsKICAgIH0KICAKICAvKiBUaGlzIGlzIGFuIGVtcHR5IGJhc2UgY2xhc3MuICBXZSBmaXJzdCB0cnkgdG8gcHV0IGl0IGF0IG9mZnNldAogICAgIHplcm8uICAqLwogIGlmIChsYXlvdXRfY29uZmxpY3RfcCAoYmluZm8sCgkJCSBCSU5GT19PRkZTRVQgKGJpbmZvKSwKCQkJIG9mZnNldHMsIAoJCQkgLyp2YmFzZXNfcD0qLzApKQogICAgewogICAgICAvKiBUaGF0IGRpZG4ndCB3b3JrLiAgTm93LCB3ZSBtb3ZlIGZvcndhcmQgZnJvbSB0aGUgbmV4dAoJIGF2YWlsYWJsZSBzcG90IGluIHRoZSBjbGFzcy4gICovCiAgICAgIGF0ZW5kID0gdHJ1ZTsKICAgICAgcHJvcGFnYXRlX2JpbmZvX29mZnNldHMgKGJpbmZvLCBjb252ZXJ0IChzc2l6ZXR5cGUsIGVvYykpOwogICAgICB3aGlsZSAoMSkgCgl7CgkgIGlmICghbGF5b3V0X2NvbmZsaWN0X3AgKGJpbmZvLAoJCQkJICBCSU5GT19PRkZTRVQgKGJpbmZvKSwgCgkJCQkgIG9mZnNldHMsCgkJCQkgIC8qdmJhc2VzX3A9Ki8wKSkKCSAgICAvKiBXZSBmaW5hbGx5IGZvdW5kIGEgc3BvdCB3aGVyZSB0aGVyZSdzIG5vIG92ZXJsYXAuICAqLwoJICAgIGJyZWFrOwoKCSAgLyogVGhlcmUncyBvdmVybGFwIGhlcmUsIHRvby4gIEJ1bXAgYWxvbmcgdG8gdGhlIG5leHQgc3BvdC4gICovCgkgIHByb3BhZ2F0ZV9iaW5mb19vZmZzZXRzIChiaW5mbywgYWxpZ25tZW50KTsKCX0KICAgIH0KICByZXR1cm4gYXRlbmQ7Cn0KCi8qIExheW91dCB0aGUgYmFzZSBnaXZlbiBieSBCSU5GTyBpbiB0aGUgY2xhc3MgaW5kaWNhdGVkIGJ5IFJMSS4KICAgKkJBU0VfQUxJR04gaXMgYSBydW5uaW5nIG1heGltdW0gb2YgdGhlIGFsaWdubWVudHMgb2YKICAgYW55IGJhc2UgY2xhc3MuICBPRkZTRVRTIGdpdmVzIHRoZSBsb2NhdGlvbiBvZiBlbXB0eSBiYXNlCiAgIHN1Ym9iamVjdHMuICBUIGlzIHRoZSBtb3N0IGRlcml2ZWQgdHlwZS4gIFJldHVybiBub256ZXJvIGlmIHRoZSBuZXcKICAgb2JqZWN0IGNhbm5vdCBiZSBuZWFybHktZW1wdHkuICBBIG5ldyBGSUVMRF9ERUNMIGlzIGluc2VydGVkIGF0CiAgICpORVhUX0ZJRUxELCB1bmxlc3MgQklORk8gaXMgZm9yIGFuIGVtcHR5IGJhc2UgY2xhc3MuICAKCiAgIFJldHVybnMgdGhlIGxvY2F0aW9uIGF0IHdoaWNoIHRoZSBuZXh0IGZpZWxkIHNob3VsZCBiZSBpbnNlcnRlZC4gICovCgpzdGF0aWMgdHJlZSAqCmJ1aWxkX2Jhc2VfZmllbGQgKHJlY29yZF9sYXlvdXRfaW5mbyBybGksIHRyZWUgYmluZm8sCgkJICBzcGxheV90cmVlIG9mZnNldHMsIHRyZWUgKm5leHRfZmllbGQpCnsKICB0cmVlIHQgPSBybGktPnQ7CiAgdHJlZSBiYXNldHlwZSA9IEJJTkZPX1RZUEUgKGJpbmZvKTsKCiAgaWYgKCFDT01QTEVURV9UWVBFX1AgKGJhc2V0eXBlKSkKICAgIC8qIFRoaXMgZXJyb3IgaXMgbm93IHJlcG9ydGVkIGluIHhyZWZfdGFnLCB0aHVzIGdpdmluZyBiZXR0ZXIKICAgICAgIGxvY2F0aW9uIGluZm9ybWF0aW9uLiAgKi8KICAgIHJldHVybiBuZXh0X2ZpZWxkOwogIAogIC8qIFBsYWNlIHRoZSBiYXNlIGNsYXNzLiAgKi8KICBpZiAoIWlzX2VtcHR5X2NsYXNzIChiYXNldHlwZSkpCiAgICB7CiAgICAgIHRyZWUgZGVjbDsKCiAgICAgIC8qIFRoZSBjb250YWluaW5nIGNsYXNzIGlzIG5vbi1lbXB0eSBiZWNhdXNlIGl0IGhhcyBhIG5vbi1lbXB0eQoJIGJhc2UgY2xhc3MuICAqLwogICAgICBDTEFTU1RZUEVfRU1QVFlfUCAodCkgPSAwOwogICAgICAKICAgICAgLyogQ3JlYXRlIHRoZSBGSUVMRF9ERUNMLiAgKi8KICAgICAgZGVjbCA9IGJ1aWxkX2RlY2wgKEZJRUxEX0RFQ0wsIE5VTExfVFJFRSwgQ0xBU1NUWVBFX0FTX0JBU0UgKGJhc2V0eXBlKSk7CiAgICAgIERFQ0xfQVJUSUZJQ0lBTCAoZGVjbCkgPSAxOwogICAgICBERUNMX0lHTk9SRURfUCAoZGVjbCkgPSAxOwogICAgICBERUNMX0ZJRUxEX0NPTlRFWFQgKGRlY2wpID0gdDsKICAgICAgREVDTF9TSVpFIChkZWNsKSA9IENMQVNTVFlQRV9TSVpFIChiYXNldHlwZSk7CiAgICAgIERFQ0xfU0laRV9VTklUIChkZWNsKSA9IENMQVNTVFlQRV9TSVpFX1VOSVQgKGJhc2V0eXBlKTsKICAgICAgREVDTF9BTElHTiAoZGVjbCkgPSBDTEFTU1RZUEVfQUxJR04gKGJhc2V0eXBlKTsKICAgICAgREVDTF9VU0VSX0FMSUdOIChkZWNsKSA9IENMQVNTVFlQRV9VU0VSX0FMSUdOIChiYXNldHlwZSk7CiAgICAgIERFQ0xfTU9ERSAoZGVjbCkgPSBUWVBFX01PREUgKGJhc2V0eXBlKTsKICAgICAgREVDTF9GSUVMRF9JU19CQVNFIChkZWNsKSA9IDE7CgogICAgICAvKiBUcnkgdG8gcGxhY2UgdGhlIGZpZWxkLiAgSXQgbWF5IHRha2UgbW9yZSB0aGFuIG9uZSB0cnkgaWYgd2UKCSBoYXZlIGEgaGFyZCB0aW1lIHBsYWNpbmcgdGhlIGZpZWxkIHdpdGhvdXQgcHV0dGluZyB0d28KCSBvYmplY3RzIG9mIHRoZSBzYW1lIHR5cGUgYXQgdGhlIHNhbWUgYWRkcmVzcy4gICovCiAgICAgIGxheW91dF9ub25lbXB0eV9iYXNlX29yX2ZpZWxkIChybGksIGRlY2wsIGJpbmZvLCBvZmZzZXRzKTsKICAgICAgLyogQWRkIHRoZSBuZXcgRklFTERfREVDTCB0byB0aGUgbGlzdCBvZiBmaWVsZHMgZm9yIFQuICAqLwogICAgICBUUkVFX0NIQUlOIChkZWNsKSA9ICpuZXh0X2ZpZWxkOwogICAgICAqbmV4dF9maWVsZCA9IGRlY2w7CiAgICAgIG5leHRfZmllbGQgPSAmVFJFRV9DSEFJTiAoZGVjbCk7CiAgICB9CiAgZWxzZQogICAgewogICAgICB0cmVlIGVvYzsKICAgICAgYm9vbCBhdGVuZDsKCiAgICAgIC8qIE9uIHNvbWUgcGxhdGZvcm1zIChBUk0pLCBldmVuIGVtcHR5IGNsYXNzZXMgd2lsbCBub3QgYmUKCSBieXRlLWFsaWduZWQuICAqLwogICAgICBlb2MgPSByb3VuZF91cCAocmxpX3NpemVfdW5pdF9zb19mYXIgKHJsaSksCgkJICAgICAgQ0xBU1NUWVBFX0FMSUdOX1VOSVQgKGJhc2V0eXBlKSk7CiAgICAgIGF0ZW5kID0gbGF5b3V0X2VtcHR5X2Jhc2UgKGJpbmZvLCBlb2MsIG9mZnNldHMpOwogICAgICAvKiBBIG5lYXJseS1lbXB0eSBjbGFzcyAiaGFzIG5vIHByb3BlciBiYXNlIGNsYXNzIHRoYXQgaXMgZW1wdHksCgkgbm90IG1vcmFsbHkgdmlydHVhbCwgYW5kIGF0IGFuIG9mZnNldCBvdGhlciB0aGFuIHplcm8uIiAgKi8KICAgICAgaWYgKCFCSU5GT19WSVJUVUFMX1AgKGJpbmZvKSAmJiBDTEFTU1RZUEVfTkVBUkxZX0VNUFRZX1AgKHQpKQoJewoJICBpZiAoYXRlbmQpCgkgICAgQ0xBU1NUWVBFX05FQVJMWV9FTVBUWV9QICh0KSA9IDA7CgkgIC8qIFRoZSBjaGVjayBhYm92ZSAodXNlZCBpbiBHKysgMy4yKSBpcyBpbnN1ZmZpY2llbnQgIGJlY2F1c2UKCSAgICAgYW4gZW1wdHkgY2xhc3MgcGxhY2VkIGF0IG9mZnNldCB6ZXJvIG1pZ2h0IGl0c2VsZiBoYXZlIGFuCgkgICAgIGVtcHR5IGJhc2UgYXQgYSBub256ZXJvIG9mZnNldC4gICovCgkgIGVsc2UgaWYgKHdhbGtfc3Vib2JqZWN0X29mZnNldHMgKGJhc2V0eXBlLCAKCQkJCQkgICBlbXB0eV9iYXNlX2F0X25vbnplcm9fb2Zmc2V0X3AsCgkJCQkJICAgc2l6ZV96ZXJvX25vZGUsCgkJCQkJICAgLypvZmZzZXRzPSovTlVMTCwKCQkJCQkgICAvKm1heF9vZmZzZXQ9Ki9OVUxMX1RSRUUsCgkJCQkJICAgLyp2YmFzZXNfcD0qL3RydWUpKQoJICAgIHsKCSAgICAgIGlmIChhYmlfdmVyc2lvbl9hdF9sZWFzdCAoMikpCgkJQ0xBU1NUWVBFX05FQVJMWV9FTVBUWV9QICh0KSA9IDA7CgkgICAgICBlbHNlIGlmICh3YXJuX2FiaSkKCQl3YXJuaW5nICgiY2xhc3MgJXFUIHdpbGwgYmUgY29uc2lkZXJlZCBuZWFybHkgZW1wdHkgaW4gYSAiCgkJCSAiZnV0dXJlIHZlcnNpb24gb2YgR0NDIiwgdCk7CgkgICAgfQoJfQoJCiAgICAgIC8qIFdlIGRvIG5vdCBjcmVhdGUgYSBGSUVMRF9ERUNMIGZvciBlbXB0eSBiYXNlIGNsYXNzZXMgYmVjYXVzZQoJIGl0IG1pZ2h0IG92ZXJsYXAgc29tZSBvdGhlciBmaWVsZC4gIFdlIHdhbnQgdG8gYmUgYWJsZSB0bwoJIGNyZWF0ZSBDT05TVFJVQ1RPUnMgZm9yIHRoZSBjbGFzcyBieSBpdGVyYXRpbmcgb3ZlciB0aGUKCSBGSUVMRF9ERUNMcywgYW5kIHRoZSBiYWNrIGVuZCBkb2VzIG5vdCBoYW5kbGUgb3ZlcmxhcHBpbmcKCSBGSUVMRF9ERUNMcy4gICovCgogICAgICAvKiBBbiBlbXB0eSB2aXJ0dWFsIGJhc2UgY2F1c2VzIGEgY2xhc3MgdG8gYmUgbm9uLWVtcHR5CgkgLS0gYnV0IGluIHRoYXQgY2FzZSB3ZSBkbyBub3QgbmVlZCB0byBjbGVhciBDTEFTU1RZUEVfRU1QVFlfUAoJIGhlcmUgYmVjYXVzZSB0aGF0IHdhcyBhbHJlYWR5IGRvbmUgd2hlbiB0aGUgdmlydHVhbCB0YWJsZQoJIHBvaW50ZXIgd2FzIGNyZWF0ZWQuICAqLwogICAgfQoKICAvKiBSZWNvcmQgdGhlIG9mZnNldHMgb2YgQklORk8gYW5kIGl0cyBiYXNlIHN1Ym9iamVjdHMuICAqLwogIHJlY29yZF9zdWJvYmplY3Rfb2Zmc2V0cyAoYmluZm8sCgkJCSAgICBCSU5GT19PRkZTRVQgKGJpbmZvKSwKCQkJICAgIG9mZnNldHMsIAoJCQkgICAgLyp2YmFzZXNfcD0qLzApOwoKICByZXR1cm4gbmV4dF9maWVsZDsKfQoKLyogTGF5b3V0IGFsbCBvZiB0aGUgbm9uLXZpcnR1YWwgYmFzZSBjbGFzc2VzLiAgUmVjb3JkIGVtcHR5CiAgIHN1Ym9iamVjdHMgaW4gT0ZGU0VUUy4gIFQgaXMgdGhlIG1vc3QgZGVyaXZlZCB0eXBlLiAgUmV0dXJuIG5vbnplcm8KICAgaWYgdGhlIHR5cGUgY2Fubm90IGJlIG5lYXJseSBlbXB0eS4gIFRoZSBmaWVsZHMgY3JlYXRlZAogICBjb3JyZXNwb25kaW5nIHRvIHRoZSBiYXNlIGNsYXNzZXMgd2lsbCBiZSBpbnNlcnRlZCBhdAogICAqTkVYVF9GSUVMRC4gICovCgpzdGF0aWMgdm9pZApidWlsZF9iYXNlX2ZpZWxkcyAocmVjb3JkX2xheW91dF9pbmZvIHJsaSwKCQkgICBzcGxheV90cmVlIG9mZnNldHMsIHRyZWUgKm5leHRfZmllbGQpCnsKICAvKiBDaGFpbiB0byBob2xkIGFsbCB0aGUgbmV3IEZJRUxEX0RFQ0xzIHdoaWNoIHN0YW5kIGluIGZvciBiYXNlIGNsYXNzCiAgICAgc3Vib2JqZWN0cy4gICovCiAgdHJlZSB0ID0gcmxpLT50OwogIGludCBuX2Jhc2VjbGFzc2VzID0gQklORk9fTl9CQVNFX0JJTkZPUyAoVFlQRV9CSU5GTyAodCkpOwogIGludCBpOwoKICAvKiBUaGUgcHJpbWFyeSBiYXNlIGNsYXNzIGlzIGFsd2F5cyBhbGxvY2F0ZWQgZmlyc3QuICAqLwogIGlmIChDTEFTU1RZUEVfSEFTX1BSSU1BUllfQkFTRV9QICh0KSkKICAgIG5leHRfZmllbGQgPSBidWlsZF9iYXNlX2ZpZWxkIChybGksIENMQVNTVFlQRV9QUklNQVJZX0JJTkZPICh0KSwKCQkJCSAgIG9mZnNldHMsIG5leHRfZmllbGQpOwoKICAvKiBOb3cgYWxsb2NhdGUgdGhlIHJlc3Qgb2YgdGhlIGJhc2VzLiAgKi8KICBmb3IgKGkgPSAwOyBpIDwgbl9iYXNlY2xhc3NlczsgKytpKQogICAgewogICAgICB0cmVlIGJhc2VfYmluZm87CgogICAgICBiYXNlX2JpbmZvID0gQklORk9fQkFTRV9CSU5GTyAoVFlQRV9CSU5GTyAodCksIGkpOwoKICAgICAgLyogVGhlIHByaW1hcnkgYmFzZSB3YXMgYWxyZWFkeSBhbGxvY2F0ZWQgYWJvdmUsIHNvIHdlIGRvbid0CgkgbmVlZCB0byBhbGxvY2F0ZSBpdCBhZ2FpbiBoZXJlLiAgKi8KICAgICAgaWYgKGJhc2VfYmluZm8gPT0gQ0xBU1NUWVBFX1BSSU1BUllfQklORk8gKHQpKQoJY29udGludWU7CgogICAgICAvKiBWaXJ0dWFsIGJhc2VzIGFyZSBhZGRlZCBhdCB0aGUgZW5kIChhIHByaW1hcnkgdmlydHVhbCBiYXNlCgkgd2lsbCBoYXZlIGFscmVhZHkgYmVlbiBhZGRlZCkuICAqLwogICAgICBpZiAoQklORk9fVklSVFVBTF9QIChiYXNlX2JpbmZvKSkKCWNvbnRpbnVlOwoKICAgICAgbmV4dF9maWVsZCA9IGJ1aWxkX2Jhc2VfZmllbGQgKHJsaSwgYmFzZV9iaW5mbywKCQkJCSAgICAgb2Zmc2V0cywgbmV4dF9maWVsZCk7CiAgICB9Cn0KCi8qIEdvIHRocm91Z2ggdGhlIFRZUEVfTUVUSE9EUyBvZiBUIGlzc3VpbmcgYW55IGFwcHJvcHJpYXRlCiAgIGRpYWdub3N0aWNzLCBmaWd1cmluZyBvdXQgd2hpY2ggbWV0aG9kcyBvdmVycmlkZSB3aGljaCBvdGhlcgogICBtZXRob2RzLCBhbmQgc28gZm9ydGguICAqLwoKc3RhdGljIHZvaWQKY2hlY2tfbWV0aG9kcyAodHJlZSB0KQp7CiAgdHJlZSB4OwoKICBmb3IgKHggPSBUWVBFX01FVEhPRFMgKHQpOyB4OyB4ID0gVFJFRV9DSEFJTiAoeCkpCiAgICB7CiAgICAgIGNoZWNrX2Zvcl9vdmVycmlkZSAoeCwgdCk7CiAgICAgIGlmIChERUNMX1BVUkVfVklSVFVBTF9QICh4KSAmJiAhIERFQ0xfVklOREVYICh4KSkKCWNwX2Vycm9yX2F0ICgiaW5pdGlhbGl6ZXIgc3BlY2lmaWVkIGZvciBub24tdmlydHVhbCBtZXRob2QgJXFEIiwgeCk7CiAgICAgIC8qIFRoZSBuYW1lIG9mIHRoZSBmaWVsZCBpcyB0aGUgb3JpZ2luYWwgZmllbGQgbmFtZQoJIFNhdmUgdGhpcyBpbiBhdXhpbGlhcnkgZmllbGQgZm9yIGxhdGVyIG92ZXJsb2FkaW5nLiAgKi8KICAgICAgaWYgKERFQ0xfVklOREVYICh4KSkKCXsKCSAgVFlQRV9QT0xZTU9SUEhJQ19QICh0KSA9IDE7CgkgIGlmIChERUNMX1BVUkVfVklSVFVBTF9QICh4KSkKCSAgICBWRUNfc2FmZV9wdXNoICh0cmVlLCBDTEFTU1RZUEVfUFVSRV9WSVJUVUFMUyAodCksIHgpOwoJfQogICAgICAvKiBBbGwgdXNlci1kZWNsYXJlZCBkZXN0cnVjdG9ycyBhcmUgbm9uLXRyaXZpYWwuICAqLwogICAgICBpZiAoREVDTF9ERVNUUlVDVE9SX1AgKHgpKQoJVFlQRV9IQVNfTk9OVFJJVklBTF9ERVNUUlVDVE9SICh0KSA9IDE7CiAgICB9Cn0KCi8qIEZOIGlzIGEgY29uc3RydWN0b3Igb3IgZGVzdHJ1Y3Rvci4gIENsb25lIHRoZSBkZWNsYXJhdGlvbiB0byBjcmVhdGUKICAgYSBzcGVjaWFsaXplZCBpbi1jaGFyZ2Ugb3Igbm90LWluLWNoYXJnZSB2ZXJzaW9uLCBhcyBpbmRpY2F0ZWQgYnkKICAgTkFNRS4gICovCgpzdGF0aWMgdHJlZQpidWlsZF9jbG9uZSAodHJlZSBmbiwgdHJlZSBuYW1lKQp7CiAgdHJlZSBwYXJtczsKICB0cmVlIGNsb25lOwoKICAvKiBDb3B5IHRoZSBmdW5jdGlvbi4gICovCiAgY2xvbmUgPSBjb3B5X2RlY2wgKGZuKTsKICAvKiBSZW1lbWJlciB3aGVyZSB0aGlzIGZ1bmN0aW9uIGNhbWUgZnJvbS4gICovCiAgREVDTF9DTE9ORURfRlVOQ1RJT04gKGNsb25lKSA9IGZuOwogIERFQ0xfQUJTVFJBQ1RfT1JJR0lOIChjbG9uZSkgPSBmbjsKICAvKiBSZXNldCB0aGUgZnVuY3Rpb24gbmFtZS4gICovCiAgREVDTF9OQU1FIChjbG9uZSkgPSBuYW1lOwogIFNFVF9ERUNMX0FTU0VNQkxFUl9OQU1FIChjbG9uZSwgTlVMTF9UUkVFKTsKICAvKiBUaGVyZSdzIG5vIHBlbmRpbmcgaW5saW5lIGRhdGEgZm9yIHRoaXMgZnVuY3Rpb24uICAqLwogIERFQ0xfUEVORElOR19JTkxJTkVfSU5GTyAoY2xvbmUpID0gTlVMTDsKICBERUNMX1BFTkRJTkdfSU5MSU5FX1AgKGNsb25lKSA9IDA7CiAgLyogQW5kIGl0IGhhc24ndCB5ZXQgYmVlbiBkZWZlcnJlZC4gICovCiAgREVDTF9ERUZFUlJFRF9GTiAoY2xvbmUpID0gMDsKCiAgLyogVGhlIGJhc2UtY2xhc3MgZGVzdHJ1Y3RvciBpcyBub3QgdmlydHVhbC4gICovCiAgaWYgKG5hbWUgPT0gYmFzZV9kdG9yX2lkZW50aWZpZXIpCiAgICB7CiAgICAgIERFQ0xfVklSVFVBTF9QIChjbG9uZSkgPSAwOwogICAgICBpZiAoVFJFRV9DT0RFIChjbG9uZSkgIT0gVEVNUExBVEVfREVDTCkKCURFQ0xfVklOREVYIChjbG9uZSkgPSBOVUxMX1RSRUU7CiAgICB9CgogIC8qIElmIHRoZXJlIHdhcyBhbiBpbi1jaGFyZ2UgcGFyYW1ldGVyLCBkcm9wIGl0IGZyb20gdGhlIGZ1bmN0aW9uCiAgICAgdHlwZS4gICovCiAgaWYgKERFQ0xfSEFTX0lOX0NIQVJHRV9QQVJNX1AgKGNsb25lKSkKICAgIHsKICAgICAgdHJlZSBiYXNldHlwZTsKICAgICAgdHJlZSBwYXJtdHlwZXM7CiAgICAgIHRyZWUgZXhjZXB0aW9uczsKCiAgICAgIGV4Y2VwdGlvbnMgPSBUWVBFX1JBSVNFU19FWENFUFRJT05TIChUUkVFX1RZUEUgKGNsb25lKSk7CiAgICAgIGJhc2V0eXBlID0gVFlQRV9NRVRIT0RfQkFTRVRZUEUgKFRSRUVfVFlQRSAoY2xvbmUpKTsKICAgICAgcGFybXR5cGVzID0gVFlQRV9BUkdfVFlQRVMgKFRSRUVfVFlQRSAoY2xvbmUpKTsKICAgICAgLyogU2tpcCB0aGUgYHRoaXMnIHBhcmFtZXRlci4gICovCiAgICAgIHBhcm10eXBlcyA9IFRSRUVfQ0hBSU4gKHBhcm10eXBlcyk7CiAgICAgIC8qIFNraXAgdGhlIGluLWNoYXJnZSBwYXJhbWV0ZXIuICAqLwogICAgICBwYXJtdHlwZXMgPSBUUkVFX0NIQUlOIChwYXJtdHlwZXMpOwogICAgICAvKiBBbmQgdGhlIFZUVCBwYXJtLCBpbiBhIGNvbXBsZXRlIFtjZF10b3IuICAqLwogICAgICBpZiAoREVDTF9IQVNfVlRUX1BBUk1fUCAoZm4pCgkgICYmICEgREVDTF9ORUVEU19WVFRfUEFSTV9QIChjbG9uZSkpCglwYXJtdHlwZXMgPSBUUkVFX0NIQUlOIChwYXJtdHlwZXMpOwogICAgICAgLyogSWYgdGhpcyBpcyBzdWJvYmplY3QgY29uc3RydWN0b3Igb3IgZGVzdHJ1Y3RvciwgYWRkIHRoZSB2dHQKCSBwYXJhbWV0ZXIuICAqLwogICAgICBUUkVFX1RZUEUgKGNsb25lKSAKCT0gYnVpbGRfbWV0aG9kX3R5cGVfZGlyZWN0bHkgKGJhc2V0eXBlLAoJCQkJICAgICAgVFJFRV9UWVBFIChUUkVFX1RZUEUgKGNsb25lKSksCgkJCQkgICAgICBwYXJtdHlwZXMpOwogICAgICBpZiAoZXhjZXB0aW9ucykKCVRSRUVfVFlQRSAoY2xvbmUpID0gYnVpbGRfZXhjZXB0aW9uX3ZhcmlhbnQgKFRSRUVfVFlQRSAoY2xvbmUpLAoJCQkJCQkgICAgIGV4Y2VwdGlvbnMpOwogICAgICBUUkVFX1RZUEUgKGNsb25lKSAKCT0gY3BfYnVpbGRfdHlwZV9hdHRyaWJ1dGVfdmFyaWFudCAoVFJFRV9UWVBFIChjbG9uZSksCgkJCQkJICAgVFlQRV9BVFRSSUJVVEVTIChUUkVFX1RZUEUgKGZuKSkpOwogICAgfQoKICAvKiBDb3B5IHRoZSBmdW5jdGlvbiBwYXJhbWV0ZXJzLiAgQnV0LCBERUNMX0FSR1VNRU5UUyBvbiBhIFRFTVBMQVRFX0RFQ0wKICAgICBhcmVuJ3QgZnVuY3Rpb24gcGFyYW1ldGVyczsgdGhvc2UgYXJlIHRoZSB0ZW1wbGF0ZSBwYXJhbWV0ZXJzLiAgKi8KICBpZiAoVFJFRV9DT0RFIChjbG9uZSkgIT0gVEVNUExBVEVfREVDTCkKICAgIHsKICAgICAgREVDTF9BUkdVTUVOVFMgKGNsb25lKSA9IGNvcHlfbGlzdCAoREVDTF9BUkdVTUVOVFMgKGNsb25lKSk7CiAgICAgIC8qIFJlbW92ZSB0aGUgaW4tY2hhcmdlIHBhcmFtZXRlci4gICovCiAgICAgIGlmIChERUNMX0hBU19JTl9DSEFSR0VfUEFSTV9QIChjbG9uZSkpCgl7CgkgIFRSRUVfQ0hBSU4gKERFQ0xfQVJHVU1FTlRTIChjbG9uZSkpCgkgICAgPSBUUkVFX0NIQUlOIChUUkVFX0NIQUlOIChERUNMX0FSR1VNRU5UUyAoY2xvbmUpKSk7CgkgIERFQ0xfSEFTX0lOX0NIQVJHRV9QQVJNX1AgKGNsb25lKSA9IDA7Cgl9CiAgICAgIC8qIEFuZCB0aGUgVlRUIHBhcm0sIGluIGEgY29tcGxldGUgW2NkXXRvci4gICovCiAgICAgIGlmIChERUNMX0hBU19WVFRfUEFSTV9QIChmbikpCgl7CgkgIGlmIChERUNMX05FRURTX1ZUVF9QQVJNX1AgKGNsb25lKSkKCSAgICBERUNMX0hBU19WVFRfUEFSTV9QIChjbG9uZSkgPSAxOwoJICBlbHNlCgkgICAgewoJICAgICAgVFJFRV9DSEFJTiAoREVDTF9BUkdVTUVOVFMgKGNsb25lKSkKCQk9IFRSRUVfQ0hBSU4gKFRSRUVfQ0hBSU4gKERFQ0xfQVJHVU1FTlRTIChjbG9uZSkpKTsKCSAgICAgIERFQ0xfSEFTX1ZUVF9QQVJNX1AgKGNsb25lKSA9IDA7CgkgICAgfQoJfQoKICAgICAgZm9yIChwYXJtcyA9IERFQ0xfQVJHVU1FTlRTIChjbG9uZSk7IHBhcm1zOyBwYXJtcyA9IFRSRUVfQ0hBSU4gKHBhcm1zKSkKCXsKCSAgREVDTF9DT05URVhUIChwYXJtcykgPSBjbG9uZTsKCSAgY3h4X2R1cF9sYW5nX3NwZWNpZmljX2RlY2wgKHBhcm1zKTsKCX0KICAgIH0KCiAgLyogQ3JlYXRlIHRoZSBSVEwgZm9yIHRoaXMgZnVuY3Rpb24uICAqLwogIC8qIEFQUExFIExPQ0FMIGJlZ2luIExMVk0gKi8KI2lmbmRlZiBFTkFCTEVfTExWTQogIFNFVF9ERUNMX1JUTCAoY2xvbmUsIE5VTExfUlRYKTsKI2Vsc2UKICBTRVRfREVDTF9MTFZNIChjbG9uZSwgMCk7CiNlbmRpZgogIC8qIEFQUExFIExPQ0FMIGVuZCBMTFZNICovCiAgcmVzdF9vZl9kZWNsX2NvbXBpbGF0aW9uIChjbG9uZSwgLyp0b3BfbGV2ZWw9Ki8xLCBhdF9lb2YpOwogIAogIC8qIE1ha2UgaXQgZWFzeSB0byBmaW5kIHRoZSBDTE9ORSBnaXZlbiB0aGUgRk4uICAqLwogIFRSRUVfQ0hBSU4gKGNsb25lKSA9IFRSRUVfQ0hBSU4gKGZuKTsKICBUUkVFX0NIQUlOIChmbikgPSBjbG9uZTsKCiAgLyogSWYgdGhpcyBpcyBhIHRlbXBsYXRlLCBoYW5kbGUgdGhlIERFQ0xfVEVNUExBVEVfUkVTVUxUIGFzIHdlbGwuICAqLwogIGlmIChUUkVFX0NPREUgKGNsb25lKSA9PSBURU1QTEFURV9ERUNMKQogICAgewogICAgICB0cmVlIHJlc3VsdDsKCiAgICAgIERFQ0xfVEVNUExBVEVfUkVTVUxUIChjbG9uZSkgCgk9IGJ1aWxkX2Nsb25lIChERUNMX1RFTVBMQVRFX1JFU1VMVCAoY2xvbmUpLCBuYW1lKTsKICAgICAgcmVzdWx0ID0gREVDTF9URU1QTEFURV9SRVNVTFQgKGNsb25lKTsKICAgICAgREVDTF9URU1QTEFURV9JTkZPIChyZXN1bHQpID0gY29weV9ub2RlIChERUNMX1RFTVBMQVRFX0lORk8gKHJlc3VsdCkpOwogICAgICBERUNMX1RJX1RFTVBMQVRFIChyZXN1bHQpID0gY2xvbmU7CiAgICB9CiAgZWxzZSBpZiAocGNoX2ZpbGUpCiAgICBub3RlX2RlY2xfZm9yX3BjaCAoY2xvbmUpOwoKICByZXR1cm4gY2xvbmU7Cn0KCi8qIFByb2R1Y2UgZGVjbGFyYXRpb25zIGZvciBhbGwgYXBwcm9wcmlhdGUgY2xvbmVzIG9mIEZOLiAgSWYKICAgVVBEQVRFX01FVEhPRF9WRUNfUCBpcyBub256ZXJvLCB0aGUgY2xvbmVzIGFyZSBhZGRlZCB0byB0aGUKICAgQ0xBU1RZUEVfTUVUSE9EX1ZFQyBhcyB3ZWxsLiAgKi8KCnZvaWQKY2xvbmVfZnVuY3Rpb25fZGVjbCAodHJlZSBmbiwgaW50IHVwZGF0ZV9tZXRob2RfdmVjX3ApCnsKICB0cmVlIGNsb25lOwoKICAvKiBBdm9pZCBpbmFwcHJvcHJpYXRlIGNsb25pbmcuICAqLwogIGlmIChUUkVFX0NIQUlOIChmbikKICAgICAgJiYgREVDTF9DTE9ORURfRlVOQ1RJT04gKFRSRUVfQ0hBSU4gKGZuKSkpCiAgICByZXR1cm47CgogIGlmIChERUNMX01BWUJFX0lOX0NIQVJHRV9DT05TVFJVQ1RPUl9QIChmbikpCiAgICB7CiAgICAgIC8qIEZvciBlYWNoIGNvbnN0cnVjdG9yLCB3ZSBuZWVkIHR3byB2YXJpYW50czogYW4gaW4tY2hhcmdlIHZlcnNpb24KCSBhbmQgYSBub3QtaW4tY2hhcmdlIHZlcnNpb24uICAqLwogICAgICBjbG9uZSA9IGJ1aWxkX2Nsb25lIChmbiwgY29tcGxldGVfY3Rvcl9pZGVudGlmaWVyKTsKICAgICAgaWYgKHVwZGF0ZV9tZXRob2RfdmVjX3ApCglhZGRfbWV0aG9kIChERUNMX0NPTlRFWFQgKGNsb25lKSwgY2xvbmUpOwogICAgICBjbG9uZSA9IGJ1aWxkX2Nsb25lIChmbiwgYmFzZV9jdG9yX2lkZW50aWZpZXIpOwogICAgICBpZiAodXBkYXRlX21ldGhvZF92ZWNfcCkKCWFkZF9tZXRob2QgKERFQ0xfQ09OVEVYVCAoY2xvbmUpLCBjbG9uZSk7CiAgICB9CiAgZWxzZQogICAgewogICAgICBnY2NfYXNzZXJ0IChERUNMX01BWUJFX0lOX0NIQVJHRV9ERVNUUlVDVE9SX1AgKGZuKSk7CgogICAgICAvKiBGb3IgZWFjaCBkZXN0cnVjdG9yLCB3ZSBuZWVkIHRocmVlIHZhcmlhbnRzOiBhbiBpbi1jaGFyZ2UKCSB2ZXJzaW9uLCBhIG5vdC1pbi1jaGFyZ2UgdmVyc2lvbiwgYW5kIGFuIGluLWNoYXJnZSBkZWxldGluZwoJIHZlcnNpb24uICBXZSBjbG9uZSB0aGUgZGVsZXRpbmcgdmVyc2lvbiBmaXJzdCBiZWNhdXNlIHRoYXQKCSBtZWFucyBpdCB3aWxsIGdvIHNlY29uZCBvbiB0aGUgVFlQRV9NRVRIT0RTIGxpc3QgLS0gYW5kIHRoYXQKCSBjb3JyZXNwb25kcyB0byB0aGUgY29ycmVjdCBsYXlvdXQgb3JkZXIgaW4gdGhlIHZpcnR1YWwKCSBmdW5jdGlvbiB0YWJsZS4gIAoKICAgICAgICAgRm9yIGEgbm9uLXZpcnR1YWwgZGVzdHJ1Y3Rvciwgd2UgZG8gbm90IGJ1aWxkIGEgZGVsZXRpbmcKCSBkZXN0cnVjdG9yLiAgKi8KICAgICAgaWYgKERFQ0xfVklSVFVBTF9QIChmbikpCgl7CgkgIGNsb25lID0gYnVpbGRfY2xvbmUgKGZuLCBkZWxldGluZ19kdG9yX2lkZW50aWZpZXIpOwoJICBpZiAodXBkYXRlX21ldGhvZF92ZWNfcCkKCSAgICBhZGRfbWV0aG9kIChERUNMX0NPTlRFWFQgKGNsb25lKSwgY2xvbmUpOwoJfQoKICAgICAgLyogQVBQTEUgTE9DQUwgYmVnaW4gS0VYVCBkb3VibGUgZGVzdHJ1Y3RvciAqLwogICAgICAvKiBEb24ndCB1c2UgdGhlIGNvbXBsZXRlIGR0b3IuICAqLwogICAgICBpZiAoISBUQVJHRVRfS0VYVEFCSQoJICB8fCAhIGhhc19hcHBsZV9rZXh0X2NvbXBhdGliaWxpdHlfYXR0cl9wIChERUNMX0NPTlRFWFQgKGZuKSkpCgl7CgkgIGNsb25lID0gYnVpbGRfY2xvbmUgKGZuLCBjb21wbGV0ZV9kdG9yX2lkZW50aWZpZXIpOwoJICBpZiAodXBkYXRlX21ldGhvZF92ZWNfcCkKCSAgICBhZGRfbWV0aG9kIChERUNMX0NPTlRFWFQgKGNsb25lKSwgY2xvbmUpOwoJfQogICAgICAvKiBBUFBMRSBMT0NBTCBlbmQgS0VYVCBkb3VibGUgZGVzdHJ1Y3RvciAqLwoKICAgICAgY2xvbmUgPSBidWlsZF9jbG9uZSAoZm4sIGJhc2VfZHRvcl9pZGVudGlmaWVyKTsKICAgICAgaWYgKHVwZGF0ZV9tZXRob2RfdmVjX3ApCglhZGRfbWV0aG9kIChERUNMX0NPTlRFWFQgKGNsb25lKSwgY2xvbmUpOwogICAgfQoKICAvKiBOb3RlIHRoYXQgdGhpcyBpcyBhbiBhYnN0cmFjdCBmdW5jdGlvbiB0aGF0IGlzIG5ldmVyIGVtaXR0ZWQuICAqLwogIERFQ0xfQUJTVFJBQ1QgKGZuKSA9IDE7Cn0KCi8qIERFQ0wgaXMgYW4gaW4gY2hhcmdlIGNvbnN0cnVjdG9yLCB3aGljaCBpcyBiZWluZyBkZWZpbmVkLiBUaGlzIHdpbGwKICAgaGF2ZSBoYWQgYW4gaW4gY2xhc3MgZGVjbGFyYXRpb24sIGZyb20gd2hlbmNlIGNsb25lcyB3ZXJlCiAgIGRlY2xhcmVkLiBBbiBvdXQtb2YtY2xhc3MgZGVmaW5pdGlvbiBjYW4gc3BlY2lmeSBhZGRpdGlvbmFsIGRlZmF1bHQKICAgYXJndW1lbnRzLiBBcyBpdCBpcyB0aGUgY2xvbmVzIHRoYXQgYXJlIGludm9sdmVkIGluIG92ZXJsb2FkCiAgIHJlc29sdXRpb24sIHdlIG11c3QgcHJvcGFnYXRlIHRoZSBpbmZvcm1hdGlvbiBmcm9tIHRoZSBERUNMIHRvIGl0cwogICBjbG9uZXMuICAqLwoKdm9pZAphZGp1c3RfY2xvbmVfYXJncyAodHJlZSBkZWNsKQp7CiAgdHJlZSBjbG9uZTsKICAKICBmb3IgKGNsb25lID0gVFJFRV9DSEFJTiAoZGVjbCk7IGNsb25lICYmIERFQ0xfQ0xPTkVEX0ZVTkNUSU9OIChjbG9uZSk7CiAgICAgICBjbG9uZSA9IFRSRUVfQ0hBSU4gKGNsb25lKSkKICAgIHsKICAgICAgdHJlZSBvcmlnX2Nsb25lX3Bhcm1zID0gVFlQRV9BUkdfVFlQRVMgKFRSRUVfVFlQRSAoY2xvbmUpKTsKICAgICAgdHJlZSBvcmlnX2RlY2xfcGFybXMgPSBUWVBFX0FSR19UWVBFUyAoVFJFRV9UWVBFIChkZWNsKSk7CiAgICAgIHRyZWUgZGVjbF9wYXJtcywgY2xvbmVfcGFybXM7CgogICAgICBjbG9uZV9wYXJtcyA9IG9yaWdfY2xvbmVfcGFybXM7CiAgICAgIAogICAgICAvKiBTa2lwIHRoZSAndGhpcycgcGFyYW1ldGVyLiAgKi8KICAgICAgb3JpZ19jbG9uZV9wYXJtcyA9IFRSRUVfQ0hBSU4gKG9yaWdfY2xvbmVfcGFybXMpOwogICAgICBvcmlnX2RlY2xfcGFybXMgPSBUUkVFX0NIQUlOIChvcmlnX2RlY2xfcGFybXMpOwoKICAgICAgaWYgKERFQ0xfSEFTX0lOX0NIQVJHRV9QQVJNX1AgKGRlY2wpKQoJb3JpZ19kZWNsX3Bhcm1zID0gVFJFRV9DSEFJTiAob3JpZ19kZWNsX3Bhcm1zKTsKICAgICAgaWYgKERFQ0xfSEFTX1ZUVF9QQVJNX1AgKGRlY2wpKQoJb3JpZ19kZWNsX3Bhcm1zID0gVFJFRV9DSEFJTiAob3JpZ19kZWNsX3Bhcm1zKTsKICAgICAgCiAgICAgIGNsb25lX3Bhcm1zID0gb3JpZ19jbG9uZV9wYXJtczsKICAgICAgaWYgKERFQ0xfSEFTX1ZUVF9QQVJNX1AgKGNsb25lKSkKCWNsb25lX3Bhcm1zID0gVFJFRV9DSEFJTiAoY2xvbmVfcGFybXMpOwogICAgICAKICAgICAgZm9yIChkZWNsX3Bhcm1zID0gb3JpZ19kZWNsX3Bhcm1zOyBkZWNsX3Bhcm1zOwoJICAgZGVjbF9wYXJtcyA9IFRSRUVfQ0hBSU4gKGRlY2xfcGFybXMpLAoJICAgICBjbG9uZV9wYXJtcyA9IFRSRUVfQ0hBSU4gKGNsb25lX3Bhcm1zKSkKCXsKCSAgZ2NjX2Fzc2VydCAoc2FtZV90eXBlX3AgKFRSRUVfVFlQRSAoZGVjbF9wYXJtcyksCgkJCQkgICBUUkVFX1RZUEUgKGNsb25lX3Bhcm1zKSkpOwoJICAKCSAgaWYgKFRSRUVfUFVSUE9TRSAoZGVjbF9wYXJtcykgJiYgIVRSRUVfUFVSUE9TRSAoY2xvbmVfcGFybXMpKQoJICAgIHsKCSAgICAgIC8qIEEgZGVmYXVsdCBwYXJhbWV0ZXIgaGFzIGJlZW4gYWRkZWQuIEFkanVzdCB0aGUKCQkgY2xvbmUncyBwYXJhbWV0ZXJzLiAgKi8KCSAgICAgIHRyZWUgZXhjZXB0aW9ucyA9IFRZUEVfUkFJU0VTX0VYQ0VQVElPTlMgKFRSRUVfVFlQRSAoY2xvbmUpKTsKCSAgICAgIHRyZWUgYmFzZXR5cGUgPSBUWVBFX01FVEhPRF9CQVNFVFlQRSAoVFJFRV9UWVBFIChjbG9uZSkpOwoJICAgICAgdHJlZSB0eXBlOwoKCSAgICAgIGNsb25lX3Bhcm1zID0gb3JpZ19kZWNsX3Bhcm1zOwoKCSAgICAgIGlmIChERUNMX0hBU19WVFRfUEFSTV9QIChjbG9uZSkpCgkJewoJCSAgY2xvbmVfcGFybXMgPSB0cmVlX2NvbnMgKFRSRUVfUFVSUE9TRSAob3JpZ19jbG9uZV9wYXJtcyksCgkJCQkJICAgVFJFRV9WQUxVRSAob3JpZ19jbG9uZV9wYXJtcyksCgkJCQkJICAgY2xvbmVfcGFybXMpOwoJCSAgVFJFRV9UWVBFIChjbG9uZV9wYXJtcykgPSBUUkVFX1RZUEUgKG9yaWdfY2xvbmVfcGFybXMpOwoJCX0KCSAgICAgIHR5cGUgPSBidWlsZF9tZXRob2RfdHlwZV9kaXJlY3RseSAoYmFzZXR5cGUsCgkJCQkJCSBUUkVFX1RZUEUgKFRSRUVfVFlQRSAoY2xvbmUpKSwKCQkJCQkJIGNsb25lX3Bhcm1zKTsKCSAgICAgIGlmIChleGNlcHRpb25zKQoJCXR5cGUgPSBidWlsZF9leGNlcHRpb25fdmFyaWFudCAodHlwZSwgZXhjZXB0aW9ucyk7CgkgICAgICBUUkVFX1RZUEUgKGNsb25lKSA9IHR5cGU7CgkgICAgICAKCSAgICAgIGNsb25lX3Bhcm1zID0gTlVMTF9UUkVFOwoJICAgICAgYnJlYWs7CgkgICAgfQoJfQogICAgICBnY2NfYXNzZXJ0ICghY2xvbmVfcGFybXMpOwogICAgfQp9CgovKiBGb3IgZWFjaCBvZiB0aGUgY29uc3RydWN0b3JzIGFuZCBkZXN0cnVjdG9ycyBpbiBULCBjcmVhdGUgYW4KICAgaW4tY2hhcmdlIGFuZCBub3QtaW4tY2hhcmdlIHZhcmlhbnQuICAqLwoKc3RhdGljIHZvaWQKY2xvbmVfY29uc3RydWN0b3JzX2FuZF9kZXN0cnVjdG9ycyAodHJlZSB0KQp7CiAgdHJlZSBmbnM7CgogIC8qIElmIGZvciBzb21lIHJlYXNvbiB3ZSBkb24ndCBoYXZlIGEgQ0xBU1NUWVBFX01FVEhPRF9WRUMsIHdlIGJhaWwKICAgICBvdXQgbm93LiAgKi8KICBpZiAoIUNMQVNTVFlQRV9NRVRIT0RfVkVDICh0KSkKICAgIHJldHVybjsKCiAgZm9yIChmbnMgPSBDTEFTU1RZUEVfQ09OU1RSVUNUT1JTICh0KTsgZm5zOyBmbnMgPSBPVkxfTkVYVCAoZm5zKSkKICAgIGNsb25lX2Z1bmN0aW9uX2RlY2wgKE9WTF9DVVJSRU5UIChmbnMpLCAvKnVwZGF0ZV9tZXRob2RfdmVjX3A9Ki8xKTsKICBmb3IgKGZucyA9IENMQVNTVFlQRV9ERVNUUlVDVE9SUyAodCk7IGZuczsgZm5zID0gT1ZMX05FWFQgKGZucykpCiAgICBjbG9uZV9mdW5jdGlvbl9kZWNsIChPVkxfQ1VSUkVOVCAoZm5zKSwgLyp1cGRhdGVfbWV0aG9kX3ZlY19wPSovMSk7Cn0KCi8qIFJlbW92ZSBhbGwgemVyby13aWR0aCBiaXQtZmllbGRzIGZyb20gVC4gICovCgpzdGF0aWMgdm9pZApyZW1vdmVfemVyb193aWR0aF9iaXRfZmllbGRzICh0cmVlIHQpCnsKICB0cmVlICpmaWVsZHNwOwoKICBmaWVsZHNwID0gJlRZUEVfRklFTERTICh0KTsgCiAgd2hpbGUgKCpmaWVsZHNwKQogICAgewogICAgICBpZiAoVFJFRV9DT0RFICgqZmllbGRzcCkgPT0gRklFTERfREVDTAoJICAmJiBERUNMX0NfQklUX0ZJRUxEICgqZmllbGRzcCkgCgkgICYmIERFQ0xfSU5JVElBTCAoKmZpZWxkc3ApKQoJKmZpZWxkc3AgPSBUUkVFX0NIQUlOICgqZmllbGRzcCk7CiAgICAgIGVsc2UKCWZpZWxkc3AgPSAmVFJFRV9DSEFJTiAoKmZpZWxkc3ApOwogICAgfQp9CgovKiBSZXR1cm5zIFRSVUUgaWZmIHdlIG5lZWQgYSBjb29raWUgd2hlbiBkeW5hbWljYWxseSBhbGxvY2F0aW5nIGFuCiAgIGFycmF5IHdob3NlIGVsZW1lbnRzIGhhdmUgdGhlIGluZGljYXRlZCBjbGFzcyBUWVBFLiAgKi8KCnN0YXRpYyBib29sCnR5cGVfcmVxdWlyZXNfYXJyYXlfY29va2llICh0cmVlIHR5cGUpCnsKICB0cmVlIGZuczsKICBib29sIGhhc190d29fYXJndW1lbnRfZGVsZXRlX3AgPSBmYWxzZTsKCiAgZ2NjX2Fzc2VydCAoQ0xBU1NfVFlQRV9QICh0eXBlKSk7CgogIC8qIElmIHRoZXJlJ3MgYSBub24tdHJpdmlhbCBkZXN0cnVjdG9yLCB3ZSBuZWVkIGEgY29va2llLiAgSW4gb3JkZXIKICAgICB0byBpdGVyYXRlIHRocm91Z2ggdGhlIGFycmF5IGNhbGxpbmcgdGhlIGRlc3RydWN0b3IgZm9yIGVhY2gKICAgICBlbGVtZW50LCB3ZSdsbCBoYXZlIHRvIGtub3cgaG93IG1hbnkgZWxlbWVudHMgdGhlcmUgYXJlLiAgKi8KICBpZiAoVFlQRV9IQVNfTk9OVFJJVklBTF9ERVNUUlVDVE9SICh0eXBlKSkKICAgIHJldHVybiB0cnVlOwoKICAvKiBJZiB0aGUgdXN1YWwgZGVhbGxvY2F0aW9uIGZ1bmN0aW9uIGlzIGEgdHdvLWFyZ3VtZW50IHdob3NlIHNlY29uZAogICAgIGFyZ3VtZW50IGlzIG9mIHR5cGUgYHNpemVfdCcsIHRoZW4gd2UgaGF2ZSB0byBwYXNzIHRoZSBzaXplIG9mCiAgICAgdGhlIGFycmF5IHRvIHRoZSBkZWFsbG9jYXRpb24gZnVuY3Rpb24sIHNvIHdlIHdpbGwgbmVlZCB0byBzdG9yZQogICAgIGEgY29va2llLiAgKi8KICBmbnMgPSBsb29rdXBfZm5maWVsZHMgKFRZUEVfQklORk8gKHR5cGUpLCAKCQkJIGFuc2lfb3BuYW1lIChWRUNfREVMRVRFX0VYUFIpLAoJCQkgLypwcm90ZWN0PSovMCk7CiAgLyogSWYgdGhlcmUgYXJlIG5vIGBvcGVyYXRvciBbXScgbWVtYmVycywgb3IgdGhlIGxvb2t1cCBpcwogICAgIGFtYmlndW91cywgdGhlbiB3ZSBkb24ndCBuZWVkIGEgY29va2llLiAgKi8KICBpZiAoIWZucyB8fCBmbnMgPT0gZXJyb3JfbWFya19ub2RlKQogICAgcmV0dXJuIGZhbHNlOwogIC8qIExvb3AgdGhyb3VnaCBhbGwgb2YgdGhlIGZ1bmN0aW9ucy4gICovCiAgZm9yIChmbnMgPSBCQVNFTElOS19GVU5DVElPTlMgKGZucyk7IGZuczsgZm5zID0gT1ZMX05FWFQgKGZucykpCiAgICB7CiAgICAgIHRyZWUgZm47CiAgICAgIHRyZWUgc2Vjb25kX3Bhcm07CgogICAgICAvKiBTZWxlY3QgdGhlIGN1cnJlbnQgZnVuY3Rpb24uICAqLwogICAgICBmbiA9IE9WTF9DVVJSRU5UIChmbnMpOwogICAgICAvKiBTZWUgaWYgdGhpcyBmdW5jdGlvbiBpcyBhIG9uZS1hcmd1bWVudCBkZWxldGUgZnVuY3Rpb24uICBJZgoJIGl0IGlzLCB0aGVuIGl0IHdpbGwgYmUgdGhlIHVzdWFsIGRlYWxsb2NhdGlvbiBmdW5jdGlvbi4gICovCiAgICAgIHNlY29uZF9wYXJtID0gVFJFRV9DSEFJTiAoVFlQRV9BUkdfVFlQRVMgKFRSRUVfVFlQRSAoZm4pKSk7CiAgICAgIGlmIChzZWNvbmRfcGFybSA9PSB2b2lkX2xpc3Rfbm9kZSkKCXJldHVybiBmYWxzZTsKICAgICAgLyogT3RoZXJ3aXNlLCBpZiB3ZSBoYXZlIGEgdHdvLWFyZ3VtZW50IGZ1bmN0aW9uIGFuZCB0aGUgc2Vjb25kCgkgYXJndW1lbnQgaXMgYHNpemVfdCcsIGl0IHdpbGwgYmUgdGhlIHVzdWFsIGRlYWxsb2NhdGlvbgoJIGZ1bmN0aW9uIC0tIHVubGVzcyB0aGVyZSBpcyBvbmUtYXJndW1lbnQgZnVuY3Rpb24sIHRvby4gICovCiAgICAgIGlmIChUUkVFX0NIQUlOIChzZWNvbmRfcGFybSkgPT0gdm9pZF9saXN0X25vZGUKCSAgJiYgc2FtZV90eXBlX3AgKFRSRUVfVkFMVUUgKHNlY29uZF9wYXJtKSwgc2l6ZXR5cGUpKQoJaGFzX3R3b19hcmd1bWVudF9kZWxldGVfcCA9IHRydWU7CiAgICB9CgogIHJldHVybiBoYXNfdHdvX2FyZ3VtZW50X2RlbGV0ZV9wOwp9CgovKiBDaGVjayB0aGUgdmFsaWRpdHkgb2YgdGhlIGJhc2VzIGFuZCBtZW1iZXJzIGRlY2xhcmVkIGluIFQuICBBZGQgYW55CiAgIGltcGxpY2l0bHktZ2VuZXJhdGVkIGZ1bmN0aW9ucyAobGlrZSBjb3B5LWNvbnN0cnVjdG9ycyBhbmQKICAgYXNzaWdubWVudCBvcGVyYXRvcnMpLiAgQ29tcHV0ZSB2YXJpb3VzIGZsYWcgYml0cyAobGlrZQogICBDTEFTU1RZUEVfTk9OX1BPRF9UKSBmb3IgVC4gIFRoaXMgcm91dGluZSB3b3JrcyBwdXJlbHkgYXQgdGhlIEMrKwogICBsZXZlbDogaS5lLiwgaW5kZXBlbmRlbnRseSBvZiB0aGUgQUJJIGluIHVzZS4gICovCgpzdGF0aWMgdm9pZApjaGVja19iYXNlc19hbmRfbWVtYmVycyAodHJlZSB0KQp7CiAgLyogTm9uemVybyBpZiB0aGUgaW1wbGljaXRseSBnZW5lcmF0ZWQgY29weSBjb25zdHJ1Y3RvciBzaG91bGQgdGFrZQogICAgIGEgbm9uLWNvbnN0IHJlZmVyZW5jZSBhcmd1bWVudC4gICovCiAgaW50IGNhbnRfaGF2ZV9jb25zdF9jdG9yOwogIC8qIE5vbnplcm8gaWYgdGhlIGltcGxpY2l0bHkgZ2VuZXJhdGVkIGFzc2lnbm1lbnQgb3BlcmF0b3IKICAgICBzaG91bGQgdGFrZSBhIG5vbi1jb25zdCByZWZlcmVuY2UgYXJndW1lbnQuICAqLwogIGludCBub19jb25zdF9hc25fcmVmOwogIHRyZWUgYWNjZXNzX2RlY2xzOwoKICAvKiBCeSBkZWZhdWx0LCB3ZSB1c2UgY29uc3QgcmVmZXJlbmNlIGFyZ3VtZW50cyBhbmQgZ2VuZXJhdGUgZGVmYXVsdAogICAgIGNvbnN0cnVjdG9ycy4gICovCiAgY2FudF9oYXZlX2NvbnN0X2N0b3IgPSAwOwogIG5vX2NvbnN0X2Fzbl9yZWYgPSAwOwoKICAvKiBDaGVjayBhbGwgdGhlIGJhc2UtY2xhc3Nlcy4gICovCiAgY2hlY2tfYmFzZXMgKHQsICZjYW50X2hhdmVfY29uc3RfY3RvciwKCSAgICAgICAmbm9fY29uc3RfYXNuX3JlZik7CgogIC8qIENoZWNrIGFsbCB0aGUgbWV0aG9kIGRlY2xhcmF0aW9ucy4gICovCiAgY2hlY2tfbWV0aG9kcyAodCk7CgogIC8qIENoZWNrIGFsbCB0aGUgZGF0YSBtZW1iZXIgZGVjbGFyYXRpb25zLiAgV2UgY2Fubm90IGNhbGwKICAgICBjaGVja19maWVsZF9kZWNscyB1bnRpbCB3ZSBoYXZlIGNhbGxlZCBjaGVja19iYXNlcyBjaGVja19tZXRob2RzLAogICAgIGFzIGNoZWNrX2ZpZWxkX2RlY2xzIGRlcGVuZHMgb24gVFlQRV9IQVNfTk9OVFJJVklBTF9ERVNUUlVDVE9SCiAgICAgYmVpbmcgc2V0IGFwcHJvcHJpYXRlbHkuICAqLwogIGNoZWNrX2ZpZWxkX2RlY2xzICh0LCAmYWNjZXNzX2RlY2xzLAoJCSAgICAgJmNhbnRfaGF2ZV9jb25zdF9jdG9yLAoJCSAgICAgJm5vX2NvbnN0X2Fzbl9yZWYpOwoKICAvKiBBIG5lYXJseS1lbXB0eSBjbGFzcyBoYXMgdG8gYmUgdnB0ci1jb250YWluaW5nOyBhIG5lYXJseSBlbXB0eQogICAgIGNsYXNzIGNvbnRhaW5zIGp1c3QgYSB2cHRyLiAgKi8KICBpZiAoIVRZUEVfQ09OVEFJTlNfVlBUUl9QICh0KSkKICAgIENMQVNTVFlQRV9ORUFSTFlfRU1QVFlfUCAodCkgPSAwOwoKICAvKiBEbyBzb21lIGJvb2trZWVwaW5nIHRoYXQgd2lsbCBndWlkZSB0aGUgZ2VuZXJhdGlvbiBvZiBpbXBsaWNpdGx5CiAgICAgZGVjbGFyZWQgbWVtYmVyIGZ1bmN0aW9ucy4gICovCiAgVFlQRV9IQVNfQ09NUExFWF9JTklUX1JFRiAodCkKICAgIHw9IChUWVBFX0hBU19JTklUX1JFRiAodCkgfHwgVFlQRV9DT05UQUlOU19WUFRSX1AgKHQpKTsKICBUWVBFX05FRURTX0NPTlNUUlVDVElORyAodCkKICAgIHw9IChUWVBFX0hBU19DT05TVFJVQ1RPUiAodCkgfHwgVFlQRV9DT05UQUlOU19WUFRSX1AgKHQpKTsKICBDTEFTU1RZUEVfTk9OX0FHR1JFR0FURSAodCkKICAgIHw9IChUWVBFX0hBU19DT05TVFJVQ1RPUiAodCkgfHwgVFlQRV9QT0xZTU9SUEhJQ19QICh0KSk7CiAgQ0xBU1NUWVBFX05PTl9QT0RfUCAodCkKICAgIHw9IChDTEFTU1RZUEVfTk9OX0FHR1JFR0FURSAodCkgCgl8fCBUWVBFX0hBU19OT05UUklWSUFMX0RFU1RSVUNUT1IgKHQpCgl8fCBUWVBFX0hBU19BU1NJR05fUkVGICh0KSk7CiAgVFlQRV9IQVNfQ09NUExFWF9BU1NJR05fUkVGICh0KQogICAgfD0gVFlQRV9IQVNfQVNTSUdOX1JFRiAodCkgfHwgVFlQRV9DT05UQUlOU19WUFRSX1AgKHQpOwoKICAvKiBTeW50aGVzaXplIGFueSBuZWVkZWQgbWV0aG9kcy4gICovCiAgYWRkX2ltcGxpY2l0bHlfZGVjbGFyZWRfbWVtYmVycyAodCwKCQkJCSAgIGNhbnRfaGF2ZV9jb25zdF9jdG9yLAoJCQkJICAgbm9fY29uc3RfYXNuX3JlZik7CgogIC8qIENyZWF0ZSB0aGUgaW4tY2hhcmdlIGFuZCBub3QtaW4tY2hhcmdlIHZhcmlhbnRzIG9mIGNvbnN0cnVjdG9ycwogICAgIGFuZCBkZXN0cnVjdG9ycy4gICovCiAgY2xvbmVfY29uc3RydWN0b3JzX2FuZF9kZXN0cnVjdG9ycyAodCk7CgogIC8qIFByb2Nlc3MgdGhlIHVzaW5nLWRlY2xhcmF0aW9ucy4gICovCiAgZm9yICg7IGFjY2Vzc19kZWNsczsgYWNjZXNzX2RlY2xzID0gVFJFRV9DSEFJTiAoYWNjZXNzX2RlY2xzKSkKICAgIGhhbmRsZV91c2luZ19kZWNsIChUUkVFX1ZBTFVFIChhY2Nlc3NfZGVjbHMpLCB0KTsKCiAgLyogQnVpbGQgYW5kIHNvcnQgdGhlIENMQVNTVFlQRV9NRVRIT0RfVkVDLiAgKi8KICBmaW5pc2hfc3RydWN0X21ldGhvZHMgKHQpOwoKICAvKiBGaWd1cmUgb3V0IHdoZXRoZXIgb3Igbm90IHdlIHdpbGwgbmVlZCBhIGNvb2tpZSB3aGVuIGR5bmFtaWNhbGx5CiAgICAgYWxsb2NhdGluZyBhbiBhcnJheSBvZiB0aGlzIHR5cGUuICAqLwogIFRZUEVfTEFOR19TUEVDSUZJQyAodCktPnUuYy52ZWNfbmV3X3VzZXNfY29va2llCiAgICA9IHR5cGVfcmVxdWlyZXNfYXJyYXlfY29va2llICh0KTsKfQoKLyogSWYgVCBuZWVkcyBhIHBvaW50ZXIgdG8gaXRzIHZpcnR1YWwgZnVuY3Rpb24gdGFibGUsIHNldCBUWVBFX1ZGSUVMRAogICBhY2NvcmRpbmdseS4gIElmIGEgbmV3IHZmaWVsZCB3YXMgY3JlYXRlZCAoYmVjYXVzZSBUIGRvZXNuJ3QgaGF2ZSBhCiAgIHByaW1hcnkgYmFzZSBjbGFzcyksIHRoZW4gdGhlIG5ld2x5IGNyZWF0ZWQgZmllbGQgaXMgcmV0dXJuZWQuICBJdAogICBpcyBub3QgYWRkZWQgdG8gdGhlIFRZUEVfRklFTERTIGxpc3Q7IGl0IGlzIHRoZSBjYWxsZXIncwogICByZXNwb25zaWJpbGl0eSB0byBkbyB0aGF0LiAgQWNjdW11bGF0ZSBkZWNsYXJlZCB2aXJ0dWFsIGZ1bmN0aW9ucwogICBvbiBWSVJUVUFMU19QLiAgKi8KCnN0YXRpYyB0cmVlCmNyZWF0ZV92dGFibGVfcHRyICh0cmVlIHQsIHRyZWUqIHZpcnR1YWxzX3ApCnsKICB0cmVlIGZuOwoKICAvKiBDb2xsZWN0IHRoZSB2aXJ0dWFsIGZ1bmN0aW9ucyBkZWNsYXJlZCBpbiBULiAgKi8KICBmb3IgKGZuID0gVFlQRV9NRVRIT0RTICh0KTsgZm47IGZuID0gVFJFRV9DSEFJTiAoZm4pKQogICAgaWYgKERFQ0xfVklOREVYIChmbikgJiYgIURFQ0xfTUFZQkVfSU5fQ0hBUkdFX0RFU1RSVUNUT1JfUCAoZm4pCgkmJiBUUkVFX0NPREUgKERFQ0xfVklOREVYIChmbikpICE9IElOVEVHRVJfQ1NUKQogICAgICB7Cgl0cmVlIG5ld192aXJ0dWFsID0gbWFrZV9ub2RlIChUUkVFX0xJU1QpOwoJCglCVl9GTiAobmV3X3ZpcnR1YWwpID0gZm47CglCVl9ERUxUQSAobmV3X3ZpcnR1YWwpID0gaW50ZWdlcl96ZXJvX25vZGU7CglCVl9WQ0FMTF9JTkRFWCAobmV3X3ZpcnR1YWwpID0gTlVMTF9UUkVFOwoKCVRSRUVfQ0hBSU4gKG5ld192aXJ0dWFsKSA9ICp2aXJ0dWFsc19wOwoJKnZpcnR1YWxzX3AgPSBuZXdfdmlydHVhbDsKICAgICAgfQogIAogIC8qIElmIHdlIGNvdWxkbid0IGZpbmQgYW4gYXBwcm9wcmlhdGUgYmFzZSBjbGFzcywgY3JlYXRlIGEgbmV3IGZpZWxkCiAgICAgaGVyZS4gIEV2ZW4gaWYgdGhlcmUgd2VyZW4ndCBhbnkgbmV3IHZpcnR1YWwgZnVuY3Rpb25zLCB3ZSBtaWdodCBuZWVkIGEKICAgICBuZXcgdmlydHVhbCBmdW5jdGlvbiB0YWJsZSBpZiB3ZSdyZSBzdXBwb3NlZCB0byBpbmNsdWRlIHZwdHJzIGluCiAgICAgYWxsIGNsYXNzZXMgdGhhdCBuZWVkIHRoZW0uICAqLwogIGlmICghVFlQRV9WRklFTEQgKHQpICYmICgqdmlydHVhbHNfcCB8fCBUWVBFX0NPTlRBSU5TX1ZQVFJfUCAodCkpKQogICAgewogICAgICAvKiBXZSBidWlsZCB0aGlzIGRlY2wgd2l0aCB2dGJsX3B0cl90eXBlX25vZGUsIHdoaWNoIGlzIGEKCSBgdnRhYmxlX2VudHJ5X3R5cGUqJy4gIEl0IG1pZ2h0IHNlZW0gbW9yZSBwcmVjaXNlIHRvIHVzZQoJIGB2dGFibGVfZW50cnlfdHlwZSAoKilbTl0nIHdoZXJlIE4gaXMgdGhlIG51bWJlciBvZiB2aXJ0dWFsCgkgZnVuY3Rpb25zLiAgSG93ZXZlciwgdGhhdCB3b3VsZCByZXF1aXJlIHRoZSB2dGFibGUgcG9pbnRlciBpbgoJIGJhc2UgY2xhc3NlcyB0byBoYXZlIGEgZGlmZmVyZW50IHR5cGUgdGhhbiB0aGUgdnRhYmxlIHBvaW50ZXIKCSBpbiBkZXJpdmVkIGNsYXNzZXMuICBXZSBjb3VsZCBtYWtlIHRoYXQgaGFwcGVuLCBidXQgdGhhdAoJIHN0aWxsIHdvdWxkbid0IHNvbHZlIGFsbCB0aGUgcHJvYmxlbXMuICBJbiBwYXJ0aWN1bGFyLCB0aGUKCSB0eXBlLWJhc2VkIGFsaWFzIGFuYWx5c2lzIGNvZGUgd291bGQgZGVjaWRlIHRoYXQgYXNzaWdubWVudHMKCSB0byB0aGUgYmFzZSBjbGFzcyB2dGFibGUgcG9pbnRlciBjYW4ndCBhbGlhcyBhc3NpZ25tZW50cyB0bwoJIHRoZSBkZXJpdmVkIGNsYXNzIHZ0YWJsZSBwb2ludGVyLCBzaW5jZSB0aGV5IGhhdmUgZGlmZmVyZW50CgkgdHlwZXMuICBUaHVzLCBpbiBhIGRlcml2ZWQgY2xhc3MgZGVzdHJ1Y3Rvciwgd2hlcmUgdGhlIGJhc2UKCSBjbGFzcyBjb25zdHJ1Y3RvciB3YXMgaW5saW5lZCwgd2UgY291bGQgZ2VuZXJhdGUgYmFkIGNvZGUgZm9yCgkgc2V0dGluZyB1cCB0aGUgdnRhYmxlIHBvaW50ZXIuICAKCiAgICAgICAgIFRoZXJlZm9yZSwgd2UgdXNlIG9uZSB0eXBlIGZvciBhbGwgdnRhYmxlIHBvaW50ZXJzLiAgV2Ugc3RpbGwKCSB1c2UgYSB0eXBlLWNvcnJlY3QgdHlwZTsgaXQncyBqdXN0IGRvZXNuJ3QgaW5kaWNhdGUgdGhlIGFycmF5CgkgYm91bmRzLiAgVGhhdCdzIGJldHRlciB0aGFuIHVzaW5nIGB2b2lkKicgb3Igc29tZSBzdWNoOyBpdCdzCgkgY2xlYW5lciwgYW5kIGl0IGxldCdzIHRoZSBhbGlhcyBhbmFseXNpcyBjb2RlIGtub3cgdGhhdCB0aGVzZQoJIHN0b3JlcyBjYW5ub3QgYWxpYXMgc3RvcmVzIHRvIHZvaWQqISAgKi8KICAgICAgdHJlZSBmaWVsZDsKCiAgICAgIGZpZWxkID0gYnVpbGRfZGVjbCAoRklFTERfREVDTCwgZ2V0X3ZmaWVsZF9uYW1lICh0KSwgdnRibF9wdHJfdHlwZV9ub2RlKTsKICAgICAgU0VUX0RFQ0xfQVNTRU1CTEVSX05BTUUgKGZpZWxkLCBnZXRfaWRlbnRpZmllciAoVkZJRUxEX0JBU0UpKTsKICAgICAgREVDTF9WSVJUVUFMX1AgKGZpZWxkKSA9IDE7CiAgICAgIERFQ0xfQVJUSUZJQ0lBTCAoZmllbGQpID0gMTsKICAgICAgREVDTF9GSUVMRF9DT05URVhUIChmaWVsZCkgPSB0OwogICAgICBERUNMX0ZDT05URVhUIChmaWVsZCkgPSB0OwogICAgICAKICAgICAgVFlQRV9WRklFTEQgKHQpID0gZmllbGQ7CiAgICAgIAogICAgICAvKiBUaGlzIGNsYXNzIGlzIG5vbi1lbXB0eS4gICovCiAgICAgIENMQVNTVFlQRV9FTVBUWV9QICh0KSA9IDA7CgogICAgICByZXR1cm4gZmllbGQ7CiAgICB9CgogIHJldHVybiBOVUxMX1RSRUU7Cn0KCi8qIEZpeHVwIHRoZSBpbmxpbmUgZnVuY3Rpb24gZ2l2ZW4gYnkgSU5GTyBub3cgdGhhdCB0aGUgY2xhc3MgaXMKICAgY29tcGxldGUuICAqLwoKc3RhdGljIHZvaWQKZml4dXBfcGVuZGluZ19pbmxpbmUgKHRyZWUgZm4pCnsKICBpZiAoREVDTF9QRU5ESU5HX0lOTElORV9JTkZPIChmbikpCiAgICB7CiAgICAgIHRyZWUgYXJncyA9IERFQ0xfQVJHVU1FTlRTIChmbik7CiAgICAgIHdoaWxlIChhcmdzKQoJewoJICBERUNMX0NPTlRFWFQgKGFyZ3MpID0gZm47CgkgIGFyZ3MgPSBUUkVFX0NIQUlOIChhcmdzKTsKCX0KICAgIH0KfQoKLyogRml4dXAgdGhlIGlubGluZSBtZXRob2RzIGFuZCBmcmllbmRzIGluIFRZUEUgbm93IHRoYXQgVFlQRSBpcwogICBjb21wbGV0ZS4gICovCgpzdGF0aWMgdm9pZApmaXh1cF9pbmxpbmVfbWV0aG9kcyAodHJlZSB0eXBlKQp7CiAgdHJlZSBtZXRob2QgPSBUWVBFX01FVEhPRFMgKHR5cGUpOwogIFZFQyAodHJlZSkgKmZyaWVuZHM7CiAgdW5zaWduZWQgaXg7CgogIGlmIChtZXRob2QgJiYgVFJFRV9DT0RFIChtZXRob2QpID09IFRSRUVfVkVDKQogICAgewogICAgICBpZiAoVFJFRV9WRUNfRUxUIChtZXRob2QsIDEpKQoJbWV0aG9kID0gVFJFRV9WRUNfRUxUIChtZXRob2QsIDEpOwogICAgICBlbHNlIGlmIChUUkVFX1ZFQ19FTFQgKG1ldGhvZCwgMCkpCgltZXRob2QgPSBUUkVFX1ZFQ19FTFQgKG1ldGhvZCwgMCk7CiAgICAgIGVsc2UKCW1ldGhvZCA9IFRSRUVfVkVDX0VMVCAobWV0aG9kLCAyKTsKICAgIH0KCiAgLyogRG8gaW5saW5lIG1lbWJlciBmdW5jdGlvbnMuICAqLwogIGZvciAoOyBtZXRob2Q7IG1ldGhvZCA9IFRSRUVfQ0hBSU4gKG1ldGhvZCkpCiAgICBmaXh1cF9wZW5kaW5nX2lubGluZSAobWV0aG9kKTsKCiAgLyogRG8gZnJpZW5kcy4gICovCiAgZm9yIChmcmllbmRzID0gQ0xBU1NUWVBFX0lOTElORV9GUklFTkRTICh0eXBlKSwgaXggPSAwOwogICAgICAgVkVDX2l0ZXJhdGUgKHRyZWUsIGZyaWVuZHMsIGl4LCBtZXRob2QpOyBpeCsrKQogICAgZml4dXBfcGVuZGluZ19pbmxpbmUgKG1ldGhvZCk7CiAgQ0xBU1NUWVBFX0lOTElORV9GUklFTkRTICh0eXBlKSA9IE5VTEw7Cn0KCi8qIEFkZCBPRkZTRVQgdG8gYWxsIGJhc2UgdHlwZXMgb2YgQklORk8gd2hpY2ggaXMgYSBiYXNlIGluIHRoZQogICBoaWVyYXJjaHkgZG9taW5hdGVkIGJ5IFQuCgogICBPRkZTRVQsIHdoaWNoIGlzIGEgdHlwZSBvZmZzZXQsIGlzIG51bWJlciBvZiBieXRlcy4gICovCgpzdGF0aWMgdm9pZApwcm9wYWdhdGVfYmluZm9fb2Zmc2V0cyAodHJlZSBiaW5mbywgdHJlZSBvZmZzZXQpCnsKICBpbnQgaTsKICB0cmVlIHByaW1hcnlfYmluZm87CiAgdHJlZSBiYXNlX2JpbmZvOwoKICAvKiBVcGRhdGUgQklORk8ncyBvZmZzZXQuICAqLwogIEJJTkZPX09GRlNFVCAoYmluZm8pCiAgICA9IGNvbnZlcnQgKHNpemV0eXBlLCAKCSAgICAgICBzaXplX2Jpbm9wIChQTFVTX0VYUFIsCgkJCSAgIGNvbnZlcnQgKHNzaXpldHlwZSwgQklORk9fT0ZGU0VUIChiaW5mbykpLAoJCQkgICBvZmZzZXQpKTsKCiAgLyogRmluZCB0aGUgcHJpbWFyeSBiYXNlIGNsYXNzLiAgKi8KICBwcmltYXJ5X2JpbmZvID0gZ2V0X3ByaW1hcnlfYmluZm8gKGJpbmZvKTsKCiAgaWYgKHByaW1hcnlfYmluZm8gJiYgQklORk9fSU5IRVJJVEFOQ0VfQ0hBSU4gKHByaW1hcnlfYmluZm8pID09IGJpbmZvKQogICAgcHJvcGFnYXRlX2JpbmZvX29mZnNldHMgKHByaW1hcnlfYmluZm8sIG9mZnNldCk7CiAgCiAgLyogU2NhbiBhbGwgb2YgdGhlIGJhc2VzLCBwdXNoaW5nIHRoZSBCSU5GT19PRkZTRVQgYWRqdXN0CiAgICAgZG93bndhcmRzLiAgKi8KICBmb3IgKGkgPSAwOyBCSU5GT19CQVNFX0lURVJBVEUgKGJpbmZvLCBpLCBiYXNlX2JpbmZvKTsgKytpKQogICAgewogICAgICAvKiBEb24ndCBkbyB0aGUgcHJpbWFyeSBiYXNlIHR3aWNlLiAgKi8KICAgICAgaWYgKGJhc2VfYmluZm8gPT0gcHJpbWFyeV9iaW5mbykKCWNvbnRpbnVlOwoKICAgICAgaWYgKEJJTkZPX1ZJUlRVQUxfUCAoYmFzZV9iaW5mbykpCgljb250aW51ZTsKCiAgICAgIHByb3BhZ2F0ZV9iaW5mb19vZmZzZXRzIChiYXNlX2JpbmZvLCBvZmZzZXQpOwogICAgfQp9CgovKiBTZXQgQklORk9fT0ZGU0VUIGZvciBhbGwgb2YgdGhlIHZpcnR1YWwgYmFzZXMgZm9yIFJMSS0+VC4gIFVwZGF0ZQogICBUWVBFX0FMSUdOIGFuZCBUWVBFX1NJWkUgZm9yIFQuICBPRkZTRVRTIGdpdmVzIHRoZSBsb2NhdGlvbiBvZgogICBlbXB0eSBzdWJvYmplY3RzIG9mIFQuICAqLwoKc3RhdGljIHZvaWQKbGF5b3V0X3ZpcnR1YWxfYmFzZXMgKHJlY29yZF9sYXlvdXRfaW5mbyBybGksIHNwbGF5X3RyZWUgb2Zmc2V0cykKewogIHRyZWUgdmJhc2U7CiAgdHJlZSB0ID0gcmxpLT50OwogIGJvb2wgZmlyc3RfdmJhc2UgPSB0cnVlOwogIHRyZWUgKm5leHRfZmllbGQ7CgogIGlmIChCSU5GT19OX0JBU0VfQklORk9TIChUWVBFX0JJTkZPICh0KSkgPT0gMCkKICAgIHJldHVybjsKCiAgaWYgKCFhYmlfdmVyc2lvbl9hdF9sZWFzdCgyKSkKICAgIHsKICAgICAgLyogSW4gRysrIDMuMiwgd2UgaW5jb3JyZWN0bHkgcm91bmRlZCB0aGUgc2l6ZSBiZWZvcmUgbGF5aW5nIG91dAoJIHRoZSB2aXJ0dWFsIGJhc2VzLiAgKi8KICAgICAgZmluaXNoX3JlY29yZF9sYXlvdXQgKHJsaSwgLypmcmVlX3A9Ki9mYWxzZSk7CiNpZmRlZiBTVFJVQ1RVUkVfU0laRV9CT1VOREFSWQogICAgICAvKiBQYWNrZWQgc3RydWN0dXJlcyBkb24ndCBuZWVkIHRvIGhhdmUgbWluaW11bSBzaXplLiAgKi8KICAgICAgaWYgKCEgVFlQRV9QQUNLRUQgKHQpKQoJVFlQRV9BTElHTiAodCkgPSBNQVggKFRZUEVfQUxJR04gKHQpLCAodW5zaWduZWQpIFNUUlVDVFVSRV9TSVpFX0JPVU5EQVJZKTsKI2VuZGlmCiAgICAgIHJsaS0+b2Zmc2V0ID0gVFlQRV9TSVpFX1VOSVQgKHQpOwogICAgICBybGktPmJpdHBvcyA9IGJpdHNpemVfemVyb19ub2RlOwogICAgICBybGktPnJlY29yZF9hbGlnbiA9IFRZUEVfQUxJR04gKHQpOwogICAgfQoKICAvKiBGaW5kIHRoZSBsYXN0IGZpZWxkLiAgVGhlIGFydGlmaWNpYWwgZmllbGRzIGNyZWF0ZWQgZm9yIHZpcnR1YWwKICAgICBiYXNlcyB3aWxsIGdvIGFmdGVyIHRoZSBsYXN0IGV4dGFudCBmaWVsZCB0byBkYXRlLiAgKi8KICBuZXh0X2ZpZWxkID0gJlRZUEVfRklFTERTICh0KTsKICB3aGlsZSAoKm5leHRfZmllbGQpCiAgICBuZXh0X2ZpZWxkID0gJlRSRUVfQ0hBSU4gKCpuZXh0X2ZpZWxkKTsKCiAgLyogR28gdGhyb3VnaCB0aGUgdmlydHVhbCBiYXNlcywgYWxsb2NhdGluZyBzcGFjZSBmb3IgZWFjaCB2aXJ0dWFsCiAgICAgYmFzZSB0aGF0IGlzIG5vdCBhbHJlYWR5IGEgcHJpbWFyeSBiYXNlIGNsYXNzLiAgVGhlc2UgYXJlCiAgICAgYWxsb2NhdGVkIGluIGluaGVyaXRhbmNlIGdyYXBoIG9yZGVyLiAgKi8KICBmb3IgKHZiYXNlID0gVFlQRV9CSU5GTyAodCk7IHZiYXNlOyB2YmFzZSA9IFRSRUVfQ0hBSU4gKHZiYXNlKSkKICAgIHsKICAgICAgaWYgKCFCSU5GT19WSVJUVUFMX1AgKHZiYXNlKSkKCWNvbnRpbnVlOwoKICAgICAgaWYgKCFCSU5GT19QUklNQVJZX1AgKHZiYXNlKSkKCXsKCSAgdHJlZSBiYXNldHlwZSA9IFRSRUVfVFlQRSAodmJhc2UpOwoKCSAgLyogVGhpcyB2aXJ0dWFsIGJhc2UgaXMgbm90IGEgcHJpbWFyeSBiYXNlIG9mIGFueSBjbGFzcyBpbiB0aGUKCSAgICAgaGllcmFyY2h5LCBzbyB3ZSBoYXZlIHRvIGFkZCBzcGFjZSBmb3IgaXQuICAqLwoJICBuZXh0X2ZpZWxkID0gYnVpbGRfYmFzZV9maWVsZCAocmxpLCB2YmFzZSwKCQkJCQkgb2Zmc2V0cywgbmV4dF9maWVsZCk7CgoJICAvKiBJZiB0aGUgZmlyc3QgdmlydHVhbCBiYXNlIG1pZ2h0IGhhdmUgYmVlbiBwbGFjZWQgYXQgYQoJICAgICBsb3dlciBhZGRyZXNzLCBoYWQgd2Ugc3RhcnRlZCBmcm9tIENMQVNTVFlQRV9TSVpFLCByYXRoZXIKCSAgICAgdGhhbiBUWVBFX1NJWkUsIGlzc3VlIGEgd2FybmluZy4gIFRoZXJlIGNhbiBiZSBib3RoIGZhbHNlCgkgICAgIHBvc2l0aXZlcyBhbmQgZmFsc2UgbmVnYXRpdmVzIGZyb20gdGhpcyB3YXJuaW5nIGluIHJhcmUKCSAgICAgY2FzZXM7IHRvIGRlYWwgd2l0aCBhbGwgdGhlIHBvc3NpYmlsaXRpZXMgd291bGQgcHJvYmFibHkKCSAgICAgcmVxdWlyZSBwZXJmb3JtaW5nIGJvdGggbGF5b3V0IGFsZ29yaXRobXMgYW5kIGNvbXBhcmluZwoJICAgICB0aGUgcmVzdWx0cyB3aGljaCBpcyBub3QgcGFydGljdWxhcmx5IHRyYWN0YWJsZS4gICovCgkgIGlmICh3YXJuX2FiaQoJICAgICAgJiYgZmlyc3RfdmJhc2UKCSAgICAgICYmICh0cmVlX2ludF9jc3RfbHQgCgkJICAoc2l6ZV9iaW5vcCAoQ0VJTF9ESVZfRVhQUiwKCQkJICAgICAgIHJvdW5kX3VwIChDTEFTU1RZUEVfU0laRSAodCksCgkJCQkJIENMQVNTVFlQRV9BTElHTiAoYmFzZXR5cGUpKSwKCQkJICAgICAgIGJpdHNpemVfdW5pdF9ub2RlKSwKCQkgICBCSU5GT19PRkZTRVQgKHZiYXNlKSkpKQoJICAgIHdhcm5pbmcgKCJvZmZzZXQgb2YgdmlydHVhbCBiYXNlICVxVCBpcyBub3QgQUJJLWNvbXBsaWFudCBhbmQgIgogICAgICAgICAgICAgICAgICAgICAibWF5IGNoYW5nZSBpbiBhIGZ1dHVyZSB2ZXJzaW9uIG9mIEdDQyIsCgkJICAgICBiYXNldHlwZSk7CgoJICBmaXJzdF92YmFzZSA9IGZhbHNlOwoJfQogICAgfQp9CgovKiBSZXR1cm5zIHRoZSBvZmZzZXQgb2YgdGhlIGJ5dGUganVzdCBwYXN0IHRoZSBlbmQgb2YgdGhlIGJhc2UgY2xhc3MKICAgQklORk8uICAqLwoKc3RhdGljIHRyZWUKZW5kX29mX2Jhc2UgKHRyZWUgYmluZm8pCnsKICB0cmVlIHNpemU7CgogIGlmIChpc19lbXB0eV9jbGFzcyAoQklORk9fVFlQRSAoYmluZm8pKSkKICAgIC8qIEFuIGVtcHR5IGNsYXNzIGhhcyB6ZXJvIENMQVNTVFlQRV9TSVpFX1VOSVQsIGJ1dCB3ZSBuZWVkIHRvCiAgICAgICBhbGxvY2F0ZSBzb21lIHNwYWNlIGZvciBpdC4gSXQgY2Fubm90IGhhdmUgdmlydHVhbCBiYXNlcywgc28KICAgICAgIFRZUEVfU0laRV9VTklUIGlzIGZpbmUuICAqLwogICAgc2l6ZSA9IFRZUEVfU0laRV9VTklUIChCSU5GT19UWVBFIChiaW5mbykpOwogIGVsc2UKICAgIHNpemUgPSBDTEFTU1RZUEVfU0laRV9VTklUIChCSU5GT19UWVBFIChiaW5mbykpOwoKICByZXR1cm4gc2l6ZV9iaW5vcCAoUExVU19FWFBSLCBCSU5GT19PRkZTRVQgKGJpbmZvKSwgc2l6ZSk7Cn0KCi8qIFJldHVybnMgdGhlIG9mZnNldCBvZiB0aGUgYnl0ZSBqdXN0IHBhc3QgdGhlIGVuZCBvZiB0aGUgYmFzZSBjbGFzcwogICB3aXRoIHRoZSBoaWdoZXN0IG9mZnNldCBpbiBULiAgSWYgSU5DTFVERV9WSVJUVUFMU19QIGlzIHplcm8sIHRoZW4KICAgb25seSBub24tdmlydHVhbCBiYXNlcyBhcmUgaW5jbHVkZWQuICAqLwoKc3RhdGljIHRyZWUKZW5kX29mX2NsYXNzICh0cmVlIHQsIGludCBpbmNsdWRlX3ZpcnR1YWxzX3ApCnsKICB0cmVlIHJlc3VsdCA9IHNpemVfemVyb19ub2RlOwogIFZFQyAodHJlZSkgKnZiYXNlczsKICB0cmVlIGJpbmZvOwogIHRyZWUgYmFzZV9iaW5mbzsKICB0cmVlIG9mZnNldDsKICBpbnQgaTsKCiAgZm9yIChiaW5mbyA9IFRZUEVfQklORk8gKHQpLCBpID0gMDsKICAgICAgIEJJTkZPX0JBU0VfSVRFUkFURSAoYmluZm8sIGksIGJhc2VfYmluZm8pOyArK2kpCiAgICB7CiAgICAgIGlmICghaW5jbHVkZV92aXJ0dWFsc19wCgkgICYmIEJJTkZPX1ZJUlRVQUxfUCAoYmFzZV9iaW5mbykKCSAgJiYgKCFCSU5GT19QUklNQVJZX1AgKGJhc2VfYmluZm8pCgkgICAgICB8fCBCSU5GT19JTkhFUklUQU5DRV9DSEFJTiAoYmFzZV9iaW5mbykgIT0gVFlQRV9CSU5GTyAodCkpKQoJY29udGludWU7CgogICAgICBvZmZzZXQgPSBlbmRfb2ZfYmFzZSAoYmFzZV9iaW5mbyk7CiAgICAgIGlmIChJTlRfQ1NUX0xUX1VOU0lHTkVEIChyZXN1bHQsIG9mZnNldCkpCglyZXN1bHQgPSBvZmZzZXQ7CiAgICB9CgogIC8qIEcrKyAzLjIgZGlkIG5vdCBjaGVjayBpbmRpcmVjdCB2aXJ0dWFsIGJhc2VzLiAgKi8KICBpZiAoYWJpX3ZlcnNpb25fYXRfbGVhc3QgKDIpICYmIGluY2x1ZGVfdmlydHVhbHNfcCkKICAgIGZvciAodmJhc2VzID0gQ0xBU1NUWVBFX1ZCQVNFQ0xBU1NFUyAodCksIGkgPSAwOwoJIFZFQ19pdGVyYXRlICh0cmVlLCB2YmFzZXMsIGksIGJhc2VfYmluZm8pOyBpKyspCiAgICAgIHsKCW9mZnNldCA9IGVuZF9vZl9iYXNlIChiYXNlX2JpbmZvKTsKCWlmIChJTlRfQ1NUX0xUX1VOU0lHTkVEIChyZXN1bHQsIG9mZnNldCkpCgkgIHJlc3VsdCA9IG9mZnNldDsKICAgICAgfQoKICByZXR1cm4gcmVzdWx0Owp9CgovKiBXYXJuIGFib3V0IGJhc2VzIG9mIFQgdGhhdCBhcmUgaW5hY2Nlc3NpYmxlIGJlY2F1c2UgdGhleSBhcmUKICAgYW1iaWd1b3VzLiAgRm9yIGV4YW1wbGU6CgogICAgIHN0cnVjdCBTIHt9OwogICAgIHN0cnVjdCBUIDogcHVibGljIFMge307CiAgICAgc3RydWN0IFUgOiBwdWJsaWMgUywgcHVibGljIFQge307CgogICBIZXJlLCBgKFMqKSBuZXcgVScgaXMgbm90IGFsbG93ZWQgYmVjYXVzZSB0aGVyZSBhcmUgdHdvIGBTJwogICBzdWJvYmplY3RzIG9mIFUuICAqLwoKc3RhdGljIHZvaWQKd2Fybl9hYm91dF9hbWJpZ3VvdXNfYmFzZXMgKHRyZWUgdCkKewogIGludCBpOwogIFZFQyAodHJlZSkgKnZiYXNlczsKICB0cmVlIGJhc2V0eXBlOwogIHRyZWUgYmluZm87CiAgdHJlZSBiYXNlX2JpbmZvOwoKICAvKiBJZiB0aGVyZSBhcmUgbm8gcmVwZWF0ZWQgYmFzZXMsIG5vdGhpbmcgY2FuIGJlIGFtYmlndW91cy4gICovCiAgaWYgKCFDTEFTU1RZUEVfUkVQRUFURURfQkFTRV9QICh0KSkKICAgIHJldHVybjsKICAKICAvKiBDaGVjayBkaXJlY3QgYmFzZXMuICAqLwogIGZvciAoYmluZm8gPSBUWVBFX0JJTkZPICh0KSwgaSA9IDA7CiAgICAgICBCSU5GT19CQVNFX0lURVJBVEUgKGJpbmZvLCBpLCBiYXNlX2JpbmZvKTsgKytpKQogICAgewogICAgICBiYXNldHlwZSA9IEJJTkZPX1RZUEUgKGJhc2VfYmluZm8pOwoKICAgICAgaWYgKCFsb29rdXBfYmFzZSAodCwgYmFzZXR5cGUsIGJhX3VuaXF1ZSB8IGJhX3F1aWV0LCBOVUxMKSkKCXdhcm5pbmcgKCJkaXJlY3QgYmFzZSAlcVQgaW5hY2Nlc3NpYmxlIGluICVxVCBkdWUgdG8gYW1iaWd1aXR5IiwKCQkgYmFzZXR5cGUsIHQpOwogICAgfQoKICAvKiBDaGVjayBmb3IgYW1iaWd1b3VzIHZpcnR1YWwgYmFzZXMuICAqLwogIGlmIChleHRyYV93YXJuaW5ncykKICAgIGZvciAodmJhc2VzID0gQ0xBU1NUWVBFX1ZCQVNFQ0xBU1NFUyAodCksIGkgPSAwOwoJIFZFQ19pdGVyYXRlICh0cmVlLCB2YmFzZXMsIGksIGJpbmZvKTsgaSsrKQogICAgICB7CgliYXNldHlwZSA9IEJJTkZPX1RZUEUgKGJpbmZvKTsKCQoJaWYgKCFsb29rdXBfYmFzZSAodCwgYmFzZXR5cGUsIGJhX3VuaXF1ZSB8IGJhX3F1aWV0LCBOVUxMKSkKCSAgd2FybmluZyAoInZpcnR1YWwgYmFzZSAlcVQgaW5hY2Nlc3NpYmxlIGluICVxVCBkdWUgdG8gYW1iaWd1aXR5IiwKCQkgICBiYXNldHlwZSwgdCk7CiAgICAgIH0KfQoKLyogQ29tcGFyZSB0d28gSU5URUdFUl9DU1RzIEsxIGFuZCBLMi4gICovCgpzdGF0aWMgaW50CnNwbGF5X3RyZWVfY29tcGFyZV9pbnRlZ2VyX2NzdHMgKHNwbGF5X3RyZWVfa2V5IGsxLCBzcGxheV90cmVlX2tleSBrMikKewogIHJldHVybiB0cmVlX2ludF9jc3RfY29tcGFyZSAoKHRyZWUpIGsxLCAodHJlZSkgazIpOwp9CgovKiBJbmNyZWFzZSB0aGUgc2l6ZSBpbmRpY2F0ZWQgaW4gUkxJIHRvIGFjY291bnQgZm9yIGVtcHR5IGNsYXNzZXMKICAgdGhhdCBhcmUgIm9mZiB0aGUgZW5kIiBvZiB0aGUgY2xhc3MuICAqLwoKc3RhdGljIHZvaWQKaW5jbHVkZV9lbXB0eV9jbGFzc2VzIChyZWNvcmRfbGF5b3V0X2luZm8gcmxpKQp7CiAgdHJlZSBlb2M7CiAgdHJlZSBybGlfc2l6ZTsKCiAgLyogSXQgbWlnaHQgYmUgdGhlIGNhc2UgdGhhdCB3ZSBncmV3IHRoZSBjbGFzcyB0byBhbGxvY2F0ZSBhCiAgICAgemVyby1zaXplZCBiYXNlIGNsYXNzLiAgVGhhdCB3b24ndCBiZSByZWZsZWN0ZWQgaW4gUkxJLCB5ZXQsCiAgICAgYmVjYXVzZSB3ZSBhcmUgd2lsbGluZyB0byBvdmVybGF5IG11bHRpcGxlIGJhc2VzIGF0IHRoZSBzYW1lCiAgICAgb2Zmc2V0LiAgSG93ZXZlciwgbm93IHdlIG5lZWQgdG8gbWFrZSBzdXJlIHRoYXQgUkxJIGlzIGJpZyBlbm91Z2gKICAgICB0byByZWZsZWN0IHRoZSBlbnRpcmUgY2xhc3MuICAqLwogIGVvYyA9IGVuZF9vZl9jbGFzcyAocmxpLT50LCAKCQkgICAgICBDTEFTU1RZUEVfQVNfQkFTRSAocmxpLT50KSAhPSBOVUxMX1RSRUUpOwogIHJsaV9zaXplID0gcmxpX3NpemVfdW5pdF9zb19mYXIgKHJsaSk7CiAgaWYgKFRSRUVfQ09ERSAocmxpX3NpemUpID09IElOVEVHRVJfQ1NUCiAgICAgICYmIElOVF9DU1RfTFRfVU5TSUdORUQgKHJsaV9zaXplLCBlb2MpKQogICAgewogICAgICBpZiAoIWFiaV92ZXJzaW9uX2F0X2xlYXN0ICgyKSkKCS8qIEluIHZlcnNpb24gMSBvZiB0aGUgQUJJLCB0aGUgc2l6ZSBvZiBhIGNsYXNzIHRoYXQgZW5kcyB3aXRoCgkgICBhIGJpdGZpZWxkIHdhcyBub3Qgcm91bmRlZCB1cCB0byBhIHdob2xlIG11bHRpcGxlIG9mIGEKCSAgIGJ5dGUuICBCZWNhdXNlIHJsaV9zaXplX3VuaXRfc29fZmFyIHJldHVybnMgb25seSB0aGUgbnVtYmVyCgkgICBvZiBmdWxseSBhbGxvY2F0ZWQgYnl0ZXMsIGFueSBleHRyYSBiaXRzIHdlcmUgbm90IGluY2x1ZGVkCgkgICBpbiB0aGUgc2l6ZS4gICovCglybGktPmJpdHBvcyA9IHJvdW5kX2Rvd24gKHJsaS0+Yml0cG9zLCBCSVRTX1BFUl9VTklUKTsKICAgICAgZWxzZQoJLyogVGhlIHNpemUgc2hvdWxkIGhhdmUgYmVlbiByb3VuZGVkIHRvIGEgd2hvbGUgYnl0ZS4gICovCglnY2NfYXNzZXJ0ICh0cmVlX2ludF9jc3RfZXF1YWwKCQkgICAgKHJsaS0+Yml0cG9zLCByb3VuZF9kb3duIChybGktPmJpdHBvcywgQklUU19QRVJfVU5JVCkpKTsKICAgICAgcmxpLT5iaXRwb3MgCgk9IHNpemVfYmlub3AgKFBMVVNfRVhQUiwgCgkJICAgICAgcmxpLT5iaXRwb3MsCgkJICAgICAgc2l6ZV9iaW5vcCAoTVVMVF9FWFBSLAoJCQkJICBjb252ZXJ0IChiaXRzaXpldHlwZSwKCQkJCQkgICBzaXplX2Jpbm9wIChNSU5VU19FWFBSLAoJCQkJCQkgICAgICAgZW9jLCBybGlfc2l6ZSkpLAoJCQkJICBiaXRzaXplX2ludCAoQklUU19QRVJfVU5JVCkpKTsKICAgICAgbm9ybWFsaXplX3JsaSAocmxpKTsKICAgIH0KfQoKLyogQ2FsY3VsYXRlIHRoZSBUWVBFX1NJWkUsIFRZUEVfQUxJR04sIGV0YyBmb3IgVC4gIENhbGN1bGF0ZQogICBCSU5GT19PRkZTRVRzIGZvciBhbGwgb2YgdGhlIGJhc2UtY2xhc3Nlcy4gIFBvc2l0aW9uIHRoZSB2dGFibGUKICAgcG9pbnRlci4gIEFjY3VtdWxhdGUgZGVjbGFyZWQgdmlydHVhbCBmdW5jdGlvbnMgb24gVklSVFVBTFNfUC4gICovCgpzdGF0aWMgdm9pZApsYXlvdXRfY2xhc3NfdHlwZSAodHJlZSB0LCB0cmVlICp2aXJ0dWFsc19wKQp7CiAgdHJlZSBub25fc3RhdGljX2RhdGFfbWVtYmVyczsKICB0cmVlIGZpZWxkOwogIHRyZWUgdnB0cjsKICByZWNvcmRfbGF5b3V0X2luZm8gcmxpOwogIC8qIE1hcHMgb2Zmc2V0cyAocmVwcmVzZW50ZWQgYXMgSU5URUdFUl9DU1RzKSB0byBhIFRSRUVfTElTVCBvZgogICAgIHR5cGVzIHRoYXQgYXBwZWFyIGF0IHRoYXQgb2Zmc2V0LiAgKi8KICBzcGxheV90cmVlIGVtcHR5X2Jhc2Vfb2Zmc2V0czsKICAvKiBUcnVlIGlmIHRoZSBsYXN0IGZpZWxkIGxheWVkIG91dCB3YXMgYSBiaXQtZmllbGQuICAqLwogIGJvb2wgbGFzdF9maWVsZF93YXNfYml0ZmllbGQgPSBmYWxzZTsKICAvKiBUaGUgbG9jYXRpb24gYXQgd2hpY2ggdGhlIG5leHQgZmllbGQgc2hvdWxkIGJlIGluc2VydGVkLiAgKi8KICB0cmVlICpuZXh0X2ZpZWxkOwogIC8qIFQsIGFzIGEgYmFzZSBjbGFzcy4gICovCiAgdHJlZSBiYXNlX3Q7CgogIC8qIEtlZXAgdHJhY2sgb2YgdGhlIGZpcnN0IG5vbi1zdGF0aWMgZGF0YSBtZW1iZXIuICAqLwogIG5vbl9zdGF0aWNfZGF0YV9tZW1iZXJzID0gVFlQRV9GSUVMRFMgKHQpOwoKICAvKiBTdGFydCBsYXlpbmcgb3V0IHRoZSByZWNvcmQuICAqLwogIHJsaSA9IHN0YXJ0X3JlY29yZF9sYXlvdXQgKHQpOwoKICAvKiBNYXJrIGFsbCB0aGUgcHJpbWFyeSBiYXNlcyBpbiB0aGUgaGllcmFyY2h5LiAgKi8KICBkZXRlcm1pbmVfcHJpbWFyeV9iYXNlcyAodCk7CgogIC8qIENyZWF0ZSBhIHBvaW50ZXIgdG8gb3VyIHZpcnR1YWwgZnVuY3Rpb24gdGFibGUuICAqLwogIHZwdHIgPSBjcmVhdGVfdnRhYmxlX3B0ciAodCwgdmlydHVhbHNfcCk7CgogIC8qIFRoZSB2cHRyIGlzIGFsd2F5cyB0aGUgZmlyc3QgdGhpbmcgaW4gdGhlIGNsYXNzLiAgKi8KICBpZiAodnB0cikKICAgIHsKICAgICAgVFJFRV9DSEFJTiAodnB0cikgPSBUWVBFX0ZJRUxEUyAodCk7CiAgICAgIFRZUEVfRklFTERTICh0KSA9IHZwdHI7CiAgICAgIG5leHRfZmllbGQgPSAmVFJFRV9DSEFJTiAodnB0cik7CiAgICAgIHBsYWNlX2ZpZWxkIChybGksIHZwdHIpOwogICAgfQogIGVsc2UKICAgIG5leHRfZmllbGQgPSAmVFlQRV9GSUVMRFMgKHQpOwoKICAvKiBCdWlsZCBGSUVMRF9ERUNMcyBmb3IgYWxsIG9mIHRoZSBub24tdmlydHVhbCBiYXNlLXR5cGVzLiAgKi8KICBlbXB0eV9iYXNlX29mZnNldHMgPSBzcGxheV90cmVlX25ldyAoc3BsYXlfdHJlZV9jb21wYXJlX2ludGVnZXJfY3N0cywgCgkJCQkgICAgICAgTlVMTCwgTlVMTCk7CiAgYnVpbGRfYmFzZV9maWVsZHMgKHJsaSwgZW1wdHlfYmFzZV9vZmZzZXRzLCBuZXh0X2ZpZWxkKTsKICAKICAvKiBBUFBMRSBMT0NBTCBiZWdpbiBNYWNpbnRvc2ggYWxpZ25tZW50IDIwMDItNS0yNCAtLWZmICAqLwogIC8qIFR1cm4gb24gdGhpcyBmbGFnIHVudGlsIHRoZSBmaXJzdCByZWFsIG1lbWJlciBvZiB0aGUgY2xhc3MgaXMKICAgICBsYWlkIG91dC4gIChFbnVtcyBhbmQgc3VjaCB0aGluZ3MgZGVjbGFyZWQgaW4gdGhlIGNsYXNzIGRvIG5vdAogICAgIGNvdW50LikgICovCiAgZGFyd2luX2FsaWduX2lzX2ZpcnN0X21lbWJlcl9vZl9jbGFzcyA9IDE7CSAgCiAgLyogQVBQTEUgTE9DQUwgZW5kIE1hY2ludG9zaCBhbGlnbm1lbnQgMjAwMi01LTI0IC0tZmYgICovCgogIC8qIExheW91dCB0aGUgbm9uLXN0YXRpYyBkYXRhIG1lbWJlcnMuICAqLwogIGZvciAoZmllbGQgPSBub25fc3RhdGljX2RhdGFfbWVtYmVyczsgZmllbGQ7IGZpZWxkID0gVFJFRV9DSEFJTiAoZmllbGQpKQogICAgewogICAgICB0cmVlIHR5cGU7CiAgICAgIHRyZWUgcGFkZGluZzsKCiAgICAgIC8qIFdlIHN0aWxsIHBhc3MgdGhpbmdzIHRoYXQgYXJlbid0IG5vbi1zdGF0aWMgZGF0YSBtZW1iZXJzIHRvCgkgdGhlIGJhY2stZW5kLCBpbiBjYXNlIGl0IHdhbnRzIHRvIGRvIHNvbWV0aGluZyB3aXRoIHRoZW0uICAqLwogICAgICBpZiAoVFJFRV9DT0RFIChmaWVsZCkgIT0gRklFTERfREVDTCkKCXsKCSAgcGxhY2VfZmllbGQgKHJsaSwgZmllbGQpOwoJICAvKiBJZiB0aGUgc3RhdGljIGRhdGEgbWVtYmVyIGhhcyBpbmNvbXBsZXRlIHR5cGUsIGtlZXAgdHJhY2sKCSAgICAgb2YgaXQgc28gdGhhdCBpdCBjYW4gYmUgY29tcGxldGVkIGxhdGVyLiAgKFRoZSBoYW5kbGluZyAKCSAgICAgb2YgcGVuZGluZyBzdGF0aWNzIGluIGZpbmlzaF9yZWNvcmRfbGF5b3V0IGlzCgkgICAgIGluc3VmZmljaWVudDsgY29uc2lkZXI6CgoJICAgICAgIHN0cnVjdCBTMTsKCSAgICAgICBzdHJ1Y3QgUzIgeyBzdGF0aWMgUzEgczE7IH07CgkgICAgICAgCiAgICAgICAgICAgICBBdCB0aGlzIHBvaW50LCBmaW5pc2hfcmVjb3JkX2xheW91dCB3aWxsIGJlIGNhbGxlZCwgYnV0CgkgICAgIFMxIGlzIHN0aWxsIGluY29tcGxldGUuKSAgKi8KCSAgaWYgKFRSRUVfQ09ERSAoZmllbGQpID09IFZBUl9ERUNMKQoJICAgIHsKCSAgICAgIG1heWJlX3JlZ2lzdGVyX2luY29tcGxldGVfdmFyIChmaWVsZCk7CgkgICAgICAvKiBUaGUgdmlzaWJpbGl0eSBvZiBzdGF0aWMgZGF0YSBtZW1iZXJzIGlzIGRldGVybWluZWQKCQkgYXQgdGhlaXIgcG9pbnQgb2YgZGVjbGFyYXRpb24sIG5vdCB0aGVpciBwb2ludCBvZgoJCSBkZWZpbml0aW9uLiAgKi8KCSAgICAgIGRldGVybWluZV92aXNpYmlsaXR5IChmaWVsZCk7CgkgICAgfQoJICBjb250aW51ZTsKCX0KICAgICAgLyogQVBQTEUgTE9DQUwgYmVnaW4gcmFkYXIgNDU5MjUwMyAqLwogICAgICBpZiAoY19kaWFsZWN0X29iamMgKCkpCiAgICAgICAgb2JqY19jaGVja29uX3dlYWtfYXR0cmlidXRlIChmaWVsZCk7CiAgICAgIC8qIEFQUExFIExPQ0FMIGVuZCByYWRhciA0NTkyNTAzICovCgogICAgICB0eXBlID0gVFJFRV9UWVBFIChmaWVsZCk7CiAgICAgIAogICAgICBwYWRkaW5nID0gTlVMTF9UUkVFOwoKICAgICAgLyogSWYgdGhpcyBmaWVsZCBpcyBhIGJpdC1maWVsZCB3aG9zZSB3aWR0aCBpcyBncmVhdGVyIHRoYW4gaXRzCgkgdHlwZSwgdGhlbiB0aGVyZSBhcmUgc29tZSBzcGVjaWFsIHJ1bGVzIGZvciBhbGxvY2F0aW5nCgkgaXQuICAqLwogICAgICBpZiAoREVDTF9DX0JJVF9GSUVMRCAoZmllbGQpCgkgICYmIElOVF9DU1RfTFQgKFRZUEVfU0laRSAodHlwZSksIERFQ0xfU0laRSAoZmllbGQpKSkKCXsKCSAgaW50ZWdlcl90eXBlX2tpbmQgaXRrOwoJICB0cmVlIGludGVnZXJfdHlwZTsKCSAgYm9vbCB3YXNfdW5uYW1lZF9wID0gZmFsc2U7CgkgIC8qIFdlIG11c3QgYWxsb2NhdGUgdGhlIGJpdHMgYXMgaWYgc3VpdGFibHkgYWxpZ25lZCBmb3IgdGhlCgkgICAgIGxvbmdlc3QgaW50ZWdlciB0eXBlIHRoYXQgZml0cyBpbiB0aGlzIG1hbnkgYml0cy4gIHR5cGUKCSAgICAgb2YgdGhlIGZpZWxkLiAgVGhlbiwgd2UgYXJlIHN1cHBvc2VkIHRvIHVzZSB0aGUgbGVmdCBvdmVyCgkgICAgIGJpdHMgYXMgYWRkaXRpb25hbCBwYWRkaW5nLiAgKi8KCSAgZm9yIChpdGsgPSBpdGtfY2hhcjsgaXRrICE9IGl0a19ub25lOyArK2l0aykKCSAgICBpZiAoSU5UX0NTVF9MVCAoREVDTF9TSVpFIChmaWVsZCksIAoJCQkgICAgVFlQRV9TSVpFIChpbnRlZ2VyX3R5cGVzW2l0a10pKSkKCSAgICAgIGJyZWFrOwoKCSAgLyogSVRLIG5vdyBpbmRpY2F0ZXMgYSB0eXBlIHRoYXQgaXMgdG9vIGxhcmdlIGZvciB0aGUKCSAgICAgZmllbGQuICBXZSBoYXZlIHRvIGJhY2sgdXAgYnkgb25lIHRvIGZpbmQgdGhlIGxhcmdlc3QKCSAgICAgdHlwZSB0aGF0IGZpdHMuICAqLwoJICBpbnRlZ2VyX3R5cGUgPSBpbnRlZ2VyX3R5cGVzW2l0ayAtIDFdOwoKCSAgLyogRmlndXJlIG91dCBob3cgbXVjaCBhZGRpdGlvbmFsIHBhZGRpbmcgaXMgcmVxdWlyZWQuICBHQ0MKCSAgICAgMy4yIGFsd2F5cyBjcmVhdGVkIGEgcGFkZGluZyBmaWVsZCwgZXZlbiBpZiBpdCBoYWQgemVybwoJICAgICB3aWR0aC4gICovCgkgIGlmICghYWJpX3ZlcnNpb25fYXRfbGVhc3QgKDIpCgkgICAgICB8fCBJTlRfQ1NUX0xUIChUWVBFX1NJWkUgKGludGVnZXJfdHlwZSksIERFQ0xfU0laRSAoZmllbGQpKSkKCSAgICB7CgkgICAgICBpZiAoYWJpX3ZlcnNpb25fYXRfbGVhc3QgKDIpICYmIFRSRUVfQ09ERSAodCkgPT0gVU5JT05fVFlQRSkKCQkvKiBJbiBhIHVuaW9uLCB0aGUgcGFkZGluZyBmaWVsZCBtdXN0IGhhdmUgdGhlIGZ1bGwgd2lkdGgKCQkgICBvZiB0aGUgYml0LWZpZWxkOyBhbGwgZmllbGRzIHN0YXJ0IGF0IG9mZnNldCB6ZXJvLiAgKi8KCQlwYWRkaW5nID0gREVDTF9TSVpFIChmaWVsZCk7CgkgICAgICBlbHNlCgkJewoJCSAgaWYgKHdhcm5fYWJpICYmIFRSRUVfQ09ERSAodCkgPT0gVU5JT05fVFlQRSkKCQkgICAgd2FybmluZyAoInNpemUgYXNzaWduZWQgdG8gJXFUIG1heSBub3QgYmUgIgoJCQkgICAgICJBQkktY29tcGxpYW50IGFuZCBtYXkgY2hhbmdlIGluIGEgZnV0dXJlICIKCQkJICAgICAidmVyc2lvbiBvZiBHQ0MiLCAKCQkJICAgICB0KTsKCQkgIHBhZGRpbmcgPSBzaXplX2Jpbm9wIChNSU5VU19FWFBSLCBERUNMX1NJWkUgKGZpZWxkKSwKCQkJCQlUWVBFX1NJWkUgKGludGVnZXJfdHlwZSkpOwoJCX0KCSAgICB9CiNpZmRlZiBQQ0NfQklURklFTERfVFlQRV9NQVRURVJTCgkgIC8qIEFuIHVubmFtZWQgYml0ZmllbGQgZG9lcyBub3Qgbm9ybWFsbHkgYWZmZWN0IHRoZQoJICAgICBhbGlnbm1lbnQgb2YgdGhlIGNvbnRhaW5pbmcgY2xhc3Mgb24gYSB0YXJnZXQgd2hlcmUKCSAgICAgUENDX0JJVEZJRUxEX1RZUEVfTUFUVEVSUy4gIEJ1dCwgdGhlIEMrKyBBQkkgZG9lcyBub3QKCSAgICAgbWFrZSBhbnkgZXhjZXB0aW9ucyBmb3IgdW5uYW1lZCBiaXRmaWVsZHMgd2hlbiB0aGUKCSAgICAgYml0ZmllbGRzIGFyZSBsb25nZXIgdGhhbiB0aGVpciB0eXBlcy4gIFRoZXJlZm9yZSwgd2UKCSAgICAgdGVtcG9yYXJpbHkgZ2l2ZSB0aGUgZmllbGQgYSBuYW1lLiAgKi8KCSAgaWYgKFBDQ19CSVRGSUVMRF9UWVBFX01BVFRFUlMgJiYgIURFQ0xfTkFNRSAoZmllbGQpKQoJICAgIHsKCSAgICAgIHdhc191bm5hbWVkX3AgPSB0cnVlOwoJICAgICAgREVDTF9OQU1FIChmaWVsZCkgPSBtYWtlX2Fub25fbmFtZSAoKTsKCSAgICB9CiNlbmRpZgoJICBERUNMX1NJWkUgKGZpZWxkKSA9IFRZUEVfU0laRSAoaW50ZWdlcl90eXBlKTsKCSAgREVDTF9BTElHTiAoZmllbGQpID0gVFlQRV9BTElHTiAoaW50ZWdlcl90eXBlKTsKCSAgREVDTF9VU0VSX0FMSUdOIChmaWVsZCkgPSBUWVBFX1VTRVJfQUxJR04gKGludGVnZXJfdHlwZSk7CgkgIGxheW91dF9ub25lbXB0eV9iYXNlX29yX2ZpZWxkIChybGksIGZpZWxkLCBOVUxMX1RSRUUsCgkJCQkJIGVtcHR5X2Jhc2Vfb2Zmc2V0cyk7CgkgIGlmICh3YXNfdW5uYW1lZF9wKQoJICAgIERFQ0xfTkFNRSAoZmllbGQpID0gTlVMTF9UUkVFOwoJICAvKiBOb3cgdGhhdCBsYXlvdXQgaGFzIGJlZW4gcGVyZm9ybWVkLCBzZXQgdGhlIHNpemUgb2YgdGhlCgkgICAgIGZpZWxkIHRvIHRoZSBzaXplIG9mIGl0cyBkZWNsYXJlZCB0eXBlOyB0aGUgcmVzdCBvZiB0aGUKCSAgICAgZmllbGQgaXMgZWZmZWN0aXZlbHkgaW52aXNpYmxlLiAgKi8KCSAgREVDTF9TSVpFIChmaWVsZCkgPSBUWVBFX1NJWkUgKHR5cGUpOwoJICAvKiBXZSBtdXN0IGFsc28gcmVzZXQgdGhlIERFQ0xfTU9ERSBvZiB0aGUgZmllbGQuICAqLwoJICBpZiAoYWJpX3ZlcnNpb25fYXRfbGVhc3QgKDIpKQoJICAgIERFQ0xfTU9ERSAoZmllbGQpID0gVFlQRV9NT0RFICh0eXBlKTsKCSAgZWxzZSBpZiAod2Fybl9hYmkKCQkgICAmJiBERUNMX01PREUgKGZpZWxkKSAhPSBUWVBFX01PREUgKHR5cGUpKQoJICAgIC8qIFZlcnNpb25zIG9mIEcrKyBiZWZvcmUgRysrIDMuNCBkaWQgbm90IHJlc2V0IHRoZQoJICAgICAgIERFQ0xfTU9ERS4gICovCgkgICAgd2FybmluZyAoInRoZSBvZmZzZXQgb2YgJXFEIG1heSBub3QgYmUgQUJJLWNvbXBsaWFudCBhbmQgbWF5ICIKCQkgICAgICJjaGFuZ2UgaW4gYSBmdXR1cmUgdmVyc2lvbiBvZiBHQ0MiLCBmaWVsZCk7Cgl9CiAgICAgIGVsc2UKCWxheW91dF9ub25lbXB0eV9iYXNlX29yX2ZpZWxkIChybGksIGZpZWxkLCBOVUxMX1RSRUUsCgkJCQkgICAgICAgZW1wdHlfYmFzZV9vZmZzZXRzKTsKCiAgICAgIC8qIEFQUExFIExPQ0FMIGJlZ2luIE1hY2ludG9zaCBhbGlnbm1lbnQgMjAwMi01LTI0IC0tZmYgICovCiAgICAgIC8qIFdoZW4gd2UgcmVhY2ggaGVyZSB3ZSBoYXZlIGxhaWQgb3V0IHRoZSBmaXJzdCByZWFsIG1lbWJlciBvZgogICAgICAgICB0aGUgY2xhc3MuICAqLwogICAgICBkYXJ3aW5fYWxpZ25faXNfZmlyc3RfbWVtYmVyX29mX2NsYXNzID0gMDsJICAKICAgICAgLyogQVBQTEUgTE9DQUwgZW5kIE1hY2ludG9zaCBhbGlnbm1lbnQgMjAwMi01LTI0IC0tZmYgICovCgogICAgICAvKiBSZW1lbWJlciB0aGUgbG9jYXRpb24gb2YgYW55IGVtcHR5IGNsYXNzZXMgaW4gRklFTEQuICAqLwogICAgICBpZiAoYWJpX3ZlcnNpb25fYXRfbGVhc3QgKDIpKQoJcmVjb3JkX3N1Ym9iamVjdF9vZmZzZXRzIChUUkVFX1RZUEUgKGZpZWxkKSwgCgkJCQkgIGJ5dGVfcG9zaXRpb24oZmllbGQpLAoJCQkJICBlbXB0eV9iYXNlX29mZnNldHMsCgkJCQkgIC8qdmJhc2VzX3A9Ki8xKTsKCiAgICAgIC8qIElmIGEgYml0LWZpZWxkIGRvZXMgbm90IGltbWVkaWF0ZWx5IGZvbGxvdyBhbm90aGVyIGJpdC1maWVsZCwKCSBhbmQgeWV0IGl0IHN0YXJ0cyBpbiB0aGUgbWlkZGxlIG9mIGEgYnl0ZSwgd2UgaGF2ZSBmYWlsZWQgdG8KCSBjb21wbHkgd2l0aCB0aGUgQUJJLiAgKi8KICAgICAgaWYgKHdhcm5fYWJpCgkgICYmIERFQ0xfQ19CSVRfRklFTEQgKGZpZWxkKSAKCSAgLyogQVBQTEUgTE9DQUwgYmVnaW4gbWFpbmxpbmUgKi8KCSAgLyogTkI6IFRoZSBUUkVFX05PX1dBUk5JTkcgZmxhZyBnZXRzIHNldCBieSBPYmplY3RpdmUtQyB3aGVuCgkgICAgIGxheWluZyBvdXQgYW4gT2JqZWN0aXZlLUMgY2xhc3MuICBUaGUgT2JqQyBBQkkgZGlmZmVycyBmcm9tCgkgICAgIHRoZSBDKysgQUJJLCBhbmQgc28gd2UgZG8gbm90IHdhbnQgYSB3YXJuaW5nIGhlcmUuICAqLwoJICAmJiAhVFJFRV9OT19XQVJOSU5HIChmaWVsZCkKCSAgLyogQVBQTEUgTE9DQUwgZW5kIG1haW5saW5lICovCgkgICYmICFsYXN0X2ZpZWxkX3dhc19iaXRmaWVsZAoJICAmJiAhaW50ZWdlcl96ZXJvcCAoc2l6ZV9iaW5vcCAoVFJVTkNfTU9EX0VYUFIsCgkJCQkJIERFQ0xfRklFTERfQklUX09GRlNFVCAoZmllbGQpLAoJCQkJCSBiaXRzaXplX3VuaXRfbm9kZSkpKQoJY3Bfd2FybmluZ19hdCAoIm9mZnNldCBvZiAlcUQgaXMgbm90IEFCSS1jb21wbGlhbnQgYW5kIG1heSAiCiAgICAgICAgICAgICAgICAgICAgICAgImNoYW5nZSBpbiBhIGZ1dHVyZSB2ZXJzaW9uIG9mIEdDQyIsIAoJCSAgICAgICBmaWVsZCk7CgogICAgICAvKiBHKysgdXNlZCB0byB1c2UgREVDTF9GSUVMRF9PRkZTRVQgYXMgaWYgaXQgd2VyZSB0aGUgYnl0ZQoJIG9mZnNldCBvZiB0aGUgZmllbGQuICAqLwogICAgICBpZiAod2Fybl9hYmkgCgkgICYmICF0cmVlX2ludF9jc3RfZXF1YWwgKERFQ0xfRklFTERfT0ZGU0VUIChmaWVsZCksCgkJCQkgIGJ5dGVfcG9zaXRpb24gKGZpZWxkKSkKCSAgJiYgY29udGFpbnNfZW1wdHlfY2xhc3NfcCAoVFJFRV9UWVBFIChmaWVsZCkpKQoJY3Bfd2FybmluZ19hdCAoIiVxRCBjb250YWlucyBlbXB0eSBjbGFzc2VzIHdoaWNoIG1heSBjYXVzZSBiYXNlICIKCQkgICAgICAgImNsYXNzZXMgdG8gYmUgcGxhY2VkIGF0IGRpZmZlcmVudCBsb2NhdGlvbnMgaW4gYSAiCgkJICAgICAgICJmdXR1cmUgdmVyc2lvbiBvZiBHQ0MiLAoJCSAgICAgICBmaWVsZCk7CgogICAgICAvKiBJZiB3ZSBuZWVkZWQgYWRkaXRpb25hbCBwYWRkaW5nIGFmdGVyIHRoaXMgZmllbGQsIGFkZCBpdAoJIG5vdy4gICovCiAgICAgIGlmIChwYWRkaW5nKQoJewoJICB0cmVlIHBhZGRpbmdfZmllbGQ7CgoJICBwYWRkaW5nX2ZpZWxkID0gYnVpbGRfZGVjbCAoRklFTERfREVDTCwgCgkJCQkgICAgICBOVUxMX1RSRUUsCgkJCQkgICAgICBjaGFyX3R5cGVfbm9kZSk7IAoJICBERUNMX0JJVF9GSUVMRCAocGFkZGluZ19maWVsZCkgPSAxOwoJICBERUNMX1NJWkUgKHBhZGRpbmdfZmllbGQpID0gcGFkZGluZzsKCSAgREVDTF9DT05URVhUIChwYWRkaW5nX2ZpZWxkKSA9IHQ7CgkgIERFQ0xfQVJUSUZJQ0lBTCAocGFkZGluZ19maWVsZCkgPSAxOwoJICBERUNMX0lHTk9SRURfUCAocGFkZGluZ19maWVsZCkgPSAxOwoJICBsYXlvdXRfbm9uZW1wdHlfYmFzZV9vcl9maWVsZCAocmxpLCBwYWRkaW5nX2ZpZWxkLAoJCQkJCSBOVUxMX1RSRUUsIAoJCQkJCSBlbXB0eV9iYXNlX29mZnNldHMpOwoJfQoKICAgICAgbGFzdF9maWVsZF93YXNfYml0ZmllbGQgPSBERUNMX0NfQklUX0ZJRUxEIChmaWVsZCk7CiAgICB9CgogIC8qIEFQUExFIExPQ0FMIGJlZ2luIE1hY2ludG9zaCBhbGlnbm1lbnQgMjAwMi01LTI0IC0tZmYgICovCiAgLyogTWFrZSBzdXJlIHRoZSBmbGFnIGlzIHR1cm5lZCBvZmYgaW4gY2FzZXMgd2hlcmUgdGhlcmUgd2VyZSBubwogICAgIHJlYWwgbWVtYmVycyBpbiB0aGUgY2xhc3MuICAqLwogIGRhcndpbl9hbGlnbl9pc19maXJzdF9tZW1iZXJfb2ZfY2xhc3MgPSAwOwkgIAoKICAvKiBBUFBMRSBMT0NBTCBlbmQgTWFjaW50b3NoIGFsaWdubWVudCAyMDAyLTUtMjQgLS1mZiAgKi8KICBpZiAoYWJpX3ZlcnNpb25fYXRfbGVhc3QgKDIpICYmICFpbnRlZ2VyX3plcm9wIChybGktPmJpdHBvcykpCiAgICB7CiAgICAgIC8qIE1ha2Ugc3VyZSB0aGF0IHdlIGFyZSBvbiBhIGJ5dGUgYm91bmRhcnkgc28gdGhhdCB0aGUgc2l6ZSBvZgoJIHRoZSBjbGFzcyB3aXRob3V0IHZpcnR1YWwgYmFzZXMgd2lsbCBhbHdheXMgYmUgYSByb3VuZCBudW1iZXIKCSBvZiBieXRlcy4gICovCiAgICAgIHJsaS0+Yml0cG9zID0gcm91bmRfdXAgKHJsaS0+Yml0cG9zLCBCSVRTX1BFUl9VTklUKTsKICAgICAgbm9ybWFsaXplX3JsaSAocmxpKTsKICAgIH0KCiAgLyogRysrIDMuMiBkb2VzIG5vdCBhbGxvdyB2aXJ0dWFsIGJhc2VzIHRvIGJlIG92ZXJsYWlkIHdpdGggdGFpbAogICAgIHBhZGRpbmcuICAqLwogIGlmICghYWJpX3ZlcnNpb25fYXRfbGVhc3QgKDIpKQogICAgaW5jbHVkZV9lbXB0eV9jbGFzc2VzKHJsaSk7CgogIC8qIERlbGV0ZSBhbGwgemVyby13aWR0aCBiaXQtZmllbGRzIGZyb20gdGhlIGxpc3Qgb2YgZmllbGRzLiAgTm93CiAgICAgdGhhdCB0aGUgdHlwZSBpcyBsYWlkIG91dCB0aGV5IGFyZSBubyBsb25nZXIgaW1wb3J0YW50LiAgKi8KICByZW1vdmVfemVyb193aWR0aF9iaXRfZmllbGRzICh0KTsKCiAgLyogQ3JlYXRlIHRoZSB2ZXJzaW9uIG9mIFQgdXNlZCBmb3IgdmlydHVhbCBiYXNlcy4gIFdlIGRvIG5vdCB1c2UKICAgICBtYWtlX2FnZ3JfdHlwZSBmb3IgdGhpcyB2ZXJzaW9uOyB0aGlzIGlzIGFuIGFydGlmaWNpYWwgdHlwZS4gIEZvcgogICAgIGEgUE9EIHR5cGUsIHdlIGp1c3QgcmV1c2UgVC4gICovCiAgaWYgKENMQVNTVFlQRV9OT05fUE9EX1AgKHQpIHx8IENMQVNTVFlQRV9FTVBUWV9QICh0KSkKICAgIHsKICAgICAgYmFzZV90ID0gbWFrZV9ub2RlIChUUkVFX0NPREUgKHQpKTsKICAgICAgCiAgICAgIC8qIFNldCB0aGUgc2l6ZSBhbmQgYWxpZ25tZW50IGZvciB0aGUgbmV3IHR5cGUuICBJbiBHKysgMy4yLCBhbGwKCSBlbXB0eSBjbGFzc2VzIHdlcmUgY29uc2lkZXJlZCB0byBoYXZlIHNpemUgemVybyB3aGVuIHVzZWQgYXMKCSBiYXNlIGNsYXNzZXMuICAqLwogICAgICBpZiAoIWFiaV92ZXJzaW9uX2F0X2xlYXN0ICgyKSAmJiBDTEFTU1RZUEVfRU1QVFlfUCAodCkpCgl7CgkgIFRZUEVfU0laRSAoYmFzZV90KSA9IGJpdHNpemVfemVyb19ub2RlOwoJICBUWVBFX1NJWkVfVU5JVCAoYmFzZV90KSA9IHNpemVfemVyb19ub2RlOwoJICBpZiAod2Fybl9hYmkgJiYgIWludGVnZXJfemVyb3AgKHJsaV9zaXplX3VuaXRfc29fZmFyIChybGkpKSkKCSAgICB3YXJuaW5nICgibGF5b3V0IG9mIGNsYXNzZXMgZGVyaXZlZCBmcm9tIGVtcHR5IGNsYXNzICVxVCAiCgkJICAgICAibWF5IGNoYW5nZSBpbiBhIGZ1dHVyZSB2ZXJzaW9uIG9mIEdDQyIsCgkJICAgICB0KTsKCX0KICAgICAgZWxzZQoJewoJICB0cmVlIGVvYzsKCgkgIC8qIElmIHRoZSBBQkkgdmVyc2lvbiBpcyBub3QgYXQgbGVhc3QgdHdvLCBhbmQgdGhlIGxhc3QKCSAgICAgZmllbGQgd2FzIGEgYml0LWZpZWxkLCBSTEkgbWF5IG5vdCBiZSBvbiBhIGJ5dGUKCSAgICAgYm91bmRhcnkuICBJbiBwYXJ0aWN1bGFyLCBybGlfc2l6ZV91bml0X3NvX2ZhciBtaWdodAoJICAgICBpbmRpY2F0ZSB0aGUgbGFzdCBjb21wbGV0ZSBieXRlLCB3aGlsZSBybGlfc2l6ZV9zb19mYXIKCSAgICAgaW5kaWNhdGVzIHRoZSB0b3RhbCBudW1iZXIgb2YgYml0cyB1c2VkLiAgVGhlcmVmb3JlLAoJICAgICBybGlfc2l6ZV9zb19mYXIsIHJhdGhlciB0aGFuIHJsaV9zaXplX3VuaXRfc29fZmFyLCBpcwoJICAgICB1c2VkIHRvIGNvbXB1dGUgVFlQRV9TSVpFX1VOSVQuICAqLwoJICBlb2MgPSBlbmRfb2ZfY2xhc3MgKHQsIC8qaW5jbHVkZV92aXJ0dWFsc19wPSovMCk7CgkgIFRZUEVfU0laRV9VTklUIChiYXNlX3QpIAoJICAgID0gc2l6ZV9iaW5vcCAoTUFYX0VYUFIsCgkJCSAgY29udmVydCAoc2l6ZXR5cGUsCgkJCQkgICBzaXplX2Jpbm9wIChDRUlMX0RJVl9FWFBSLAoJCQkJCSAgICAgICBybGlfc2l6ZV9zb19mYXIgKHJsaSksCgkJCQkJICAgICAgIGJpdHNpemVfaW50IChCSVRTX1BFUl9VTklUKSkpLAoJCQkgIGVvYyk7CgkgIFRZUEVfU0laRSAoYmFzZV90KSAKCSAgICA9IHNpemVfYmlub3AgKE1BWF9FWFBSLAoJCQkgIHJsaV9zaXplX3NvX2ZhciAocmxpKSwKCQkJICBzaXplX2Jpbm9wIChNVUxUX0VYUFIsCgkJCQkgICAgICBjb252ZXJ0IChiaXRzaXpldHlwZSwgZW9jKSwKCQkJCSAgICAgIGJpdHNpemVfaW50IChCSVRTX1BFUl9VTklUKSkpOwoJfQogICAgICBUWVBFX0FMSUdOIChiYXNlX3QpID0gcmxpLT5yZWNvcmRfYWxpZ247CiAgICAgIFRZUEVfVVNFUl9BTElHTiAoYmFzZV90KSA9IFRZUEVfVVNFUl9BTElHTiAodCk7CgogICAgICAvKiBDb3B5IHRoZSBmaWVsZHMgZnJvbSBULiAgKi8KICAgICAgbmV4dF9maWVsZCA9ICZUWVBFX0ZJRUxEUyAoYmFzZV90KTsKICAgICAgZm9yIChmaWVsZCA9IFRZUEVfRklFTERTICh0KTsgZmllbGQ7IGZpZWxkID0gVFJFRV9DSEFJTiAoZmllbGQpKQoJaWYgKFRSRUVfQ09ERSAoZmllbGQpID09IEZJRUxEX0RFQ0wpCgkgIHsKCSAgICAqbmV4dF9maWVsZCA9IGJ1aWxkX2RlY2wgKEZJRUxEX0RFQ0wsCgkJCQkgICAgICBERUNMX05BTUUgKGZpZWxkKSwgCgkJCQkgICAgICBUUkVFX1RZUEUgKGZpZWxkKSk7CgkgICAgREVDTF9DT05URVhUICgqbmV4dF9maWVsZCkgPSBiYXNlX3Q7CgkgICAgREVDTF9GSUVMRF9PRkZTRVQgKCpuZXh0X2ZpZWxkKSA9IERFQ0xfRklFTERfT0ZGU0VUIChmaWVsZCk7CgkgICAgREVDTF9GSUVMRF9CSVRfT0ZGU0VUICgqbmV4dF9maWVsZCkKCSAgICAgID0gREVDTF9GSUVMRF9CSVRfT0ZGU0VUIChmaWVsZCk7CgkgICAgREVDTF9TSVpFICgqbmV4dF9maWVsZCkgPSBERUNMX1NJWkUgKGZpZWxkKTsKCSAgICBERUNMX01PREUgKCpuZXh0X2ZpZWxkKSA9IERFQ0xfTU9ERSAoZmllbGQpOwoJICAgIG5leHRfZmllbGQgPSAmVFJFRV9DSEFJTiAoKm5leHRfZmllbGQpOwoJICB9CgogICAgICAvKiBSZWNvcmQgdGhlIGJhc2UgdmVyc2lvbiBvZiB0aGUgdHlwZS4gICovCiAgICAgIENMQVNTVFlQRV9BU19CQVNFICh0KSA9IGJhc2VfdDsKICAgICAgVFlQRV9DT05URVhUIChiYXNlX3QpID0gdDsKICAgIH0KICBlbHNlCiAgICBDTEFTU1RZUEVfQVNfQkFTRSAodCkgPSB0OwoKICAvKiBFdmVyeSBlbXB0eSBjbGFzcyBjb250YWlucyBhbiBlbXB0eSBjbGFzcy4gICovCiAgaWYgKENMQVNTVFlQRV9FTVBUWV9QICh0KSkKICAgIENMQVNTVFlQRV9DT05UQUlOU19FTVBUWV9DTEFTU19QICh0KSA9IDE7CgogIC8qIFNldCB0aGUgVFlQRV9ERUNMIGZvciB0aGlzIHR5cGUgdG8gY29udGFpbiB0aGUgcmlnaHQKICAgICB2YWx1ZSBmb3IgREVDTF9PRkZTRVQsIHNvIHRoYXQgd2UgY2FuIHVzZSBpdCBhcyBwYXJ0CiAgICAgb2YgYSBDT01QT05FTlRfUkVGIGZvciBtdWx0aXBsZSBpbmhlcml0YW5jZS4gICovCiAgbGF5b3V0X2RlY2wgKFRZUEVfTUFJTl9ERUNMICh0KSwgMCk7CgogIC8qIE5vdyBmaXggdXAgYW55IHZpcnR1YWwgYmFzZSBjbGFzcyB0eXBlcyB0aGF0IHdlIGxlZnQgbHlpbmcKICAgICBhcm91bmQuICBXZSBtdXN0IGdldCB0aGVzZSBkb25lIGJlZm9yZSB3ZSB0cnkgdG8gbGF5IG91dCB0aGUKICAgICB2aXJ0dWFsIGZ1bmN0aW9uIHRhYmxlLiAgQXMgYSBzaWRlLWVmZmVjdCwgdGhpcyB3aWxsIHJlbW92ZSB0aGUKICAgICBiYXNlIHN1Ym9iamVjdCBmaWVsZHMuICAqLwogIGxheW91dF92aXJ0dWFsX2Jhc2VzIChybGksIGVtcHR5X2Jhc2Vfb2Zmc2V0cyk7CgogIC8qIE1ha2Ugc3VyZSB0aGF0IGVtcHR5IGNsYXNzZXMgYXJlIHJlZmxlY3RlZCBpbiBSTEkgYXQgdGhpcyAKICAgICBwb2ludC4gICovCiAgaW5jbHVkZV9lbXB0eV9jbGFzc2VzKHJsaSk7CgogIC8qIE1ha2Ugc3VyZSBub3QgdG8gY3JlYXRlIGFueSBzdHJ1Y3R1cmVzIHdpdGggemVybyBzaXplLiAgKi8KICBpZiAoaW50ZWdlcl96ZXJvcCAocmxpX3NpemVfdW5pdF9zb19mYXIgKHJsaSkpICYmIENMQVNTVFlQRV9FTVBUWV9QICh0KSkKICAgIHBsYWNlX2ZpZWxkIChybGksIAoJCSBidWlsZF9kZWNsIChGSUVMRF9ERUNMLCBOVUxMX1RSRUUsIGNoYXJfdHlwZV9ub2RlKSk7CgogIC8qIExldCB0aGUgYmFjay1lbmQgbGF5IG91dCB0aGUgdHlwZS4gICovCiAgZmluaXNoX3JlY29yZF9sYXlvdXQgKHJsaSwgLypmcmVlX3A9Ki90cnVlKTsKCiAgLyogV2FybiBhYm91dCBiYXNlcyB0aGF0IGNhbid0IGJlIHRhbGtlZCBhYm91dCBkdWUgdG8gYW1iaWd1aXR5LiAgKi8KICB3YXJuX2Fib3V0X2FtYmlndW91c19iYXNlcyAodCk7CgogIC8qIE5vdyB0aGF0IHdlJ3JlIGRvbmUgd2l0aCBsYXlvdXQsIGdpdmUgdGhlIGJhc2UgZmllbGRzIHRoZSByZWFsIHR5cGVzLiAgKi8KICBmb3IgKGZpZWxkID0gVFlQRV9GSUVMRFMgKHQpOyBmaWVsZDsgZmllbGQgPSBUUkVFX0NIQUlOIChmaWVsZCkpCiAgICBpZiAoREVDTF9BUlRJRklDSUFMIChmaWVsZCkgJiYgSVNfRkFLRV9CQVNFX1RZUEUgKFRSRUVfVFlQRSAoZmllbGQpKSkKICAgICAgVFJFRV9UWVBFIChmaWVsZCkgPSBUWVBFX0NPTlRFWFQgKFRSRUVfVFlQRSAoZmllbGQpKTsKCiAgLyogQ2xlYW4gdXAuICAqLwogIHNwbGF5X3RyZWVfZGVsZXRlIChlbXB0eV9iYXNlX29mZnNldHMpOwp9CgovKiBEZXRlcm1pbmUgdGhlICJrZXkgbWV0aG9kIiBmb3IgdGhlIGNsYXNzIHR5cGUgaW5kaWNhdGVkIGJ5IFRZUEUsCiAgIGFuZCBzZXQgQ0xBU1NUWVBFX0tFWV9NRVRIT0QgYWNjb3JkaW5nbHkuICAqLwoKdm9pZApkZXRlcm1pbmVfa2V5X21ldGhvZCAodHJlZSB0eXBlKQp7CiAgdHJlZSBtZXRob2Q7CgogIGlmIChUWVBFX0ZPUl9KQVZBICh0eXBlKQogICAgICB8fCBwcm9jZXNzaW5nX3RlbXBsYXRlX2RlY2wKICAgICAgfHwgQ0xBU1NUWVBFX1RFTVBMQVRFX0lOU1RBTlRJQVRJT04gKHR5cGUpCiAgICAgIHx8IENMQVNTVFlQRV9JTlRFUkZBQ0VfS05PV04gKHR5cGUpKQogICAgcmV0dXJuOwoKICAvKiBUaGUga2V5IG1ldGhvZCBpcyB0aGUgZmlyc3Qgbm9uLXB1cmUgdmlydHVhbCBmdW5jdGlvbiB0aGF0IGlzIG5vdAogICAgIGlubGluZSBhdCB0aGUgcG9pbnQgb2YgY2xhc3MgZGVmaW5pdGlvbi4gIE9uIHNvbWUgdGFyZ2V0cyB0aGUKICAgICBrZXkgZnVuY3Rpb24gbWF5IG5vdCBiZSBpbmxpbmU7IHRob3NlIHRhcmdldHMgc2hvdWxkIG5vdCBjYWxsCiAgICAgdGhpcyBmdW5jdGlvbiB1bnRpbCB0aGUgZW5kIG9mIHRoZSB0cmFuc2xhdGlvbiB1bml0LiAgKi8KICBmb3IgKG1ldGhvZCA9IFRZUEVfTUVUSE9EUyAodHlwZSk7IG1ldGhvZCAhPSBOVUxMX1RSRUU7CiAgICAgICBtZXRob2QgPSBUUkVFX0NIQUlOIChtZXRob2QpKQogICAgaWYgKERFQ0xfVklOREVYIChtZXRob2QpICE9IE5VTExfVFJFRQoJJiYgISBERUNMX0RFQ0xBUkVEX0lOTElORV9QIChtZXRob2QpCgkmJiAhIERFQ0xfUFVSRV9WSVJUVUFMX1AgKG1ldGhvZCkpCiAgICAgIHsKCUNMQVNTVFlQRV9LRVlfTUVUSE9EICh0eXBlKSA9IG1ldGhvZDsKCWJyZWFrOwogICAgICB9CgogIHJldHVybjsKfQoKLyogUGVyZm9ybSBwcm9jZXNzaW5nIHJlcXVpcmVkIHdoZW4gdGhlIGRlZmluaXRpb24gb2YgVCAoYSBjbGFzcyB0eXBlKQogICBpcyBjb21wbGV0ZS4gICovCgp2b2lkCmZpbmlzaF9zdHJ1Y3RfMSAodHJlZSB0KQp7CiAgdHJlZSB4OwogIC8qIEEgVFJFRV9MSVNULiAgVGhlIFRSRUVfVkFMVUUgb2YgZWFjaCBub2RlIGlzIGEgRlVOQ1RJT05fREVDTC4gICovCiAgdHJlZSB2aXJ0dWFscyA9IE5VTExfVFJFRTsKICBpbnQgbl9maWVsZHMgPSAwOwoKICBpZiAoQ09NUExFVEVfVFlQRV9QICh0KSkKICAgIHsKICAgICAgZ2NjX2Fzc2VydCAoSVNfQUdHUl9UWVBFICh0KSk7CiAgICAgIGVycm9yICgicmVkZWZpbml0aW9uIG9mICVxI1QiLCB0KTsKICAgICAgcG9wY2xhc3MgKCk7CiAgICAgIHJldHVybjsKICAgIH0KCiAgLyogSWYgdGhpcyB0eXBlIHdhcyBwcmV2aW91c2x5IGxhaWQgb3V0IGFzIGEgZm9yd2FyZCByZWZlcmVuY2UsCiAgICAgbWFrZSBzdXJlIHdlIGxheSBpdCBvdXQgYWdhaW4uICAqLwogIFRZUEVfU0laRSAodCkgPSBOVUxMX1RSRUU7CiAgQ0xBU1NUWVBFX1BSSU1BUllfQklORk8gKHQpID0gTlVMTF9UUkVFOwoKICBmaXh1cF9pbmxpbmVfbWV0aG9kcyAodCk7CiAgCiAgLyogTWFrZSBhc3N1bXB0aW9ucyBhYm91dCB0aGUgY2xhc3M7IHdlJ2xsIHJlc2V0IHRoZSBmbGFncyBpZgogICAgIG5lY2Vzc2FyeS4gICovCiAgQ0xBU1NUWVBFX0VNUFRZX1AgKHQpID0gMTsKICBDTEFTU1RZUEVfTkVBUkxZX0VNUFRZX1AgKHQpID0gMTsKICBDTEFTU1RZUEVfQ09OVEFJTlNfRU1QVFlfQ0xBU1NfUCAodCkgPSAwOwoKICAvKiBEbyBlbmQtb2YtY2xhc3Mgc2VtYW50aWMgcHJvY2Vzc2luZzogY2hlY2tpbmcgdGhlIHZhbGlkaXR5IG9mIHRoZQogICAgIGJhc2VzIGFuZCBtZW1iZXJzIGFuZCBhZGQgaW1wbGljaXRseSBnZW5lcmF0ZWQgbWV0aG9kcy4gICovCiAgY2hlY2tfYmFzZXNfYW5kX21lbWJlcnMgKHQpOwoKICAvKiBGaW5kIHRoZSBrZXkgbWV0aG9kLiAgKi8KICBpZiAoVFlQRV9DT05UQUlOU19WUFRSX1AgKHQpKQogICAgewogICAgICAvKiBUaGUgSXRhbml1bSBDKysgQUJJIHBlcm1pdHMgdGhlIGtleSBtZXRob2QgdG8gYmUgY2hvc2VuIHdoZW4KCSB0aGUgY2xhc3MgaXMgZGVmaW5lZCAtLSBldmVuIHRob3VnaCB0aGUga2V5IG1ldGhvZCBzbwoJIHNlbGVjdGVkIG1heSBsYXRlciB0dXJuIG91dCB0byBiZSBhbiBpbmxpbmUgZnVuY3Rpb24uICBPbgoJIHNvbWUgc3lzdGVtcyAoc3VjaCBhcyBBUk0gU3ltYmlhbiBPUykgdGhlIGtleSBtZXRob2QgY2Fubm90CgkgYmUgZGV0ZXJtaW5lZCB1bnRpbCB0aGUgZW5kIG9mIHRoZSB0cmFuc2xhdGlvbiB1bml0LiAgT24gc3VjaAoJIHN5c3RlbXMsIHdlIGxlYXZlIENMQVNTVFlQRV9LRVlfTUVUSE9EIHNldCB0byBOVUxMLCB3aGljaAoJIHdpbGwgY2F1c2UgdGhlIGNsYXNzIHRvIGJlIGFkZGVkIHRvIEtFWUVEX0NMQVNTRVMuICBUaGVuLCBpbgoJIGZpbmlzaF9maWxlIHdlIHdpbGwgZGV0ZXJtaW5lIHRoZSBrZXkgbWV0aG9kLiAgKi8KICAgICAgaWYgKHRhcmdldG0uY3h4LmtleV9tZXRob2RfbWF5X2JlX2lubGluZSAoKSkKCWRldGVybWluZV9rZXlfbWV0aG9kICh0KTsKCiAgICAgIC8qIElmIGEgcG9seW1vcnBoaWMgY2xhc3MgaGFzIG5vIGtleSBtZXRob2QsIHdlIG1heSBlbWl0IHRoZSB2dGFibGUKCSBpbiBldmVyeSB0cmFuc2xhdGlvbiB1bml0IHdoZXJlIHRoZSBjbGFzcyBkZWZpbml0aW9uIGFwcGVhcnMuICAqLwogICAgICBpZiAoQ0xBU1NUWVBFX0tFWV9NRVRIT0QgKHQpID09IE5VTExfVFJFRSkKCWtleWVkX2NsYXNzZXMgPSB0cmVlX2NvbnMgKE5VTExfVFJFRSwgdCwga2V5ZWRfY2xhc3Nlcyk7CiAgICB9CgogIC8qIExheW91dCB0aGUgY2xhc3MgaXRzZWxmLiAgKi8KICBsYXlvdXRfY2xhc3NfdHlwZSAodCwgJnZpcnR1YWxzKTsKICBpZiAoQ0xBU1NUWVBFX0FTX0JBU0UgKHQpICE9IHQpCiAgICAvKiBXZSB1c2UgdGhlIGJhc2UgdHlwZSBmb3IgdHJpdmlhbCBhc3NpZ25tZW50cywgYW5kIGhlbmNlIGl0CiAgICAgICBuZWVkcyBhIG1vZGUuICAqLwogICAgY29tcHV0ZV9yZWNvcmRfbW9kZSAoQ0xBU1NUWVBFX0FTX0JBU0UgKHQpKTsKCiAgdmlydHVhbHMgPSBtb2RpZnlfYWxsX3Z0YWJsZXMgKHQsIG5yZXZlcnNlICh2aXJ0dWFscykpOwoKICAvKiBJZiBuZWNlc3NhcnksIGNyZWF0ZSB0aGUgcHJpbWFyeSB2dGFibGUgZm9yIHRoaXMgY2xhc3MuICAqLwogIGlmICh2aXJ0dWFscyB8fCBUWVBFX0NPTlRBSU5TX1ZQVFJfUCAodCkpCiAgICB7CiAgICAgIC8qIFdlIG11c3QgZW50ZXIgdGhlc2UgdmlydHVhbHMgaW50byB0aGUgdGFibGUuICAqLwogICAgICBpZiAoIUNMQVNTVFlQRV9IQVNfUFJJTUFSWV9CQVNFX1AgKHQpKQoJYnVpbGRfcHJpbWFyeV92dGFibGUgKE5VTExfVFJFRSwgdCk7CiAgICAgIGVsc2UgaWYgKCEgQklORk9fTkVXX1ZUQUJMRV9NQVJLRUQgKFRZUEVfQklORk8gKHQpKSkKCS8qIEhlcmUgd2Uga25vdyBlbm91Z2ggdG8gY2hhbmdlIHRoZSB0eXBlIG9mIG91ciB2aXJ0dWFsCgkgICBmdW5jdGlvbiB0YWJsZSwgYnV0IHdlIHdpbGwgd2FpdCB1bnRpbCBsYXRlciB0aGlzIGZ1bmN0aW9uLiAgKi8KCWJ1aWxkX3ByaW1hcnlfdnRhYmxlIChDTEFTU1RZUEVfUFJJTUFSWV9CSU5GTyAodCksIHQpOwogICAgfQoKICBpZiAoVFlQRV9DT05UQUlOU19WUFRSX1AgKHQpKQogICAgewogICAgICBpbnQgdmluZGV4OwogICAgICB0cmVlIGZuOwoKICAgICAgaWYgKEJJTkZPX1ZUQUJMRSAoVFlQRV9CSU5GTyAodCkpKQoJZ2NjX2Fzc2VydCAoREVDTF9WSVJUVUFMX1AgKEJJTkZPX1ZUQUJMRSAoVFlQRV9CSU5GTyAodCkpKSk7CiAgICAgIGlmICghQ0xBU1NUWVBFX0hBU19QUklNQVJZX0JBU0VfUCAodCkpCglnY2NfYXNzZXJ0IChCSU5GT19WSVJUVUFMUyAoVFlQRV9CSU5GTyAodCkpID09IE5VTExfVFJFRSk7CgogICAgICAvKiBBZGQgZW50cmllcyBmb3IgdmlydHVhbCBmdW5jdGlvbnMgaW50cm9kdWNlZCBieSB0aGlzIGNsYXNzLiAgKi8KICAgICAgQklORk9fVklSVFVBTFMgKFRZUEVfQklORk8gKHQpKQoJPSBjaGFpbm9uIChCSU5GT19WSVJUVUFMUyAoVFlQRV9CSU5GTyAodCkpLCB2aXJ0dWFscyk7CgogICAgICAvKiBTZXQgREVDTF9WSU5ERVggZm9yIGFsbCBmdW5jdGlvbnMgZGVjbGFyZWQgaW4gdGhpcyBjbGFzcy4gICovCiAgICAgIGZvciAodmluZGV4ID0gMCwgZm4gPSBCSU5GT19WSVJUVUFMUyAoVFlQRV9CSU5GTyAodCkpOyAKCSAgIGZuOyAKCSAgIGZuID0gVFJFRV9DSEFJTiAoZm4pLCAKCSAgICAgdmluZGV4ICs9IChUQVJHRVRfVlRBQkxFX1VTRVNfREVTQ1JJUFRPUlMKCQkJPyBUQVJHRVRfVlRBQkxFX1VTRVNfREVTQ1JJUFRPUlMgOiAxKSkKCXsKCSAgdHJlZSBmbmRlY2wgPSBCVl9GTiAoZm4pOwoKCSAgaWYgKERFQ0xfVEhVTktfUCAoZm5kZWNsKSkKCSAgICAvKiBBIHRodW5rLiBXZSBzaG91bGQgbmV2ZXIgYmUgY2FsbGluZyB0aGlzIGVudHJ5IGRpcmVjdGx5CgkgICAgICAgZnJvbSB0aGlzIHZ0YWJsZSAtLSB3ZSdkIHVzZSB0aGUgZW50cnkgZm9yIHRoZSBub24KCSAgICAgICB0aHVuayBiYXNlIGZ1bmN0aW9uLiAgKi8KCSAgICBERUNMX1ZJTkRFWCAoZm5kZWNsKSA9IE5VTExfVFJFRTsKCSAgZWxzZSBpZiAoVFJFRV9DT0RFIChERUNMX1ZJTkRFWCAoZm5kZWNsKSkgIT0gSU5URUdFUl9DU1QpCgkgICAgREVDTF9WSU5ERVggKGZuZGVjbCkgPSBidWlsZF9pbnRfY3N0IChOVUxMX1RSRUUsIHZpbmRleCk7Cgl9CiAgICB9CgogIGZpbmlzaF9zdHJ1Y3RfYml0cyAodCk7CgogIC8qIENvbXBsZXRlIHRoZSBydGwgZm9yIGFueSBzdGF0aWMgbWVtYmVyIG9iamVjdHMgb2YgdGhlIHR5cGUgd2UncmUKICAgICB3b3JraW5nIG9uLiAgKi8KICBmb3IgKHggPSBUWVBFX0ZJRUxEUyAodCk7IHg7IHggPSBUUkVFX0NIQUlOICh4KSkKICAgIGlmIChUUkVFX0NPREUgKHgpID09IFZBUl9ERUNMICYmIFRSRUVfU1RBVElDICh4KQoJJiYgc2FtZV90eXBlX3AgKFRZUEVfTUFJTl9WQVJJQU5UIChUUkVFX1RZUEUgKHgpKSwgdCkpCiAgICAgIERFQ0xfTU9ERSAoeCkgPSBUWVBFX01PREUgKHQpOwoKICAvKiBEb25lIHdpdGggRklFTERTLi4ubm93IGRlY2lkZSB3aGV0aGVyIHRvIHNvcnQgdGhlc2UgZm9yCiAgICAgZmFzdGVyIGxvb2t1cHMgbGF0ZXIuCgogICAgIFdlIHVzZSBhIHNtYWxsIG51bWJlciBiZWNhdXNlIG1vc3Qgc2VhcmNoZXMgZmFpbCAoc3VjY2VlZGluZwogICAgIHVsdGltYXRlbHkgYXMgdGhlIHNlYXJjaCBib3JlcyB0aHJvdWdoIHRoZSBpbmhlcml0YW5jZQogICAgIGhpZXJhcmNoeSksIGFuZCB3ZSB3YW50IHRoaXMgZmFpbHVyZSB0byBvY2N1ciBxdWlja2x5LiAgKi8KCiAgbl9maWVsZHMgPSBjb3VudF9maWVsZHMgKFRZUEVfRklFTERTICh0KSk7CiAgaWYgKG5fZmllbGRzID4gNykKICAgIHsKICAgICAgc3RydWN0IHNvcnRlZF9maWVsZHNfdHlwZSAqZmllbGRfdmVjID0gR0dDX05FV1ZBUgogICAgICAgICAoc3RydWN0IHNvcnRlZF9maWVsZHNfdHlwZSwKICAgICAgICAgIHNpemVvZiAoc3RydWN0IHNvcnRlZF9maWVsZHNfdHlwZSkgKyBuX2ZpZWxkcyAqIHNpemVvZiAodHJlZSkpOwogICAgICBmaWVsZF92ZWMtPmxlbiA9IG5fZmllbGRzOwogICAgICBhZGRfZmllbGRzX3RvX3JlY29yZF90eXBlIChUWVBFX0ZJRUxEUyAodCksIGZpZWxkX3ZlYywgMCk7CiAgICAgIHFzb3J0IChmaWVsZF92ZWMtPmVsdHMsIG5fZmllbGRzLCBzaXplb2YgKHRyZWUpLAoJICAgICBmaWVsZF9kZWNsX2NtcCk7CiAgICAgIGlmICghIERFQ0xfTEFOR19TUEVDSUZJQyAoVFlQRV9NQUlOX0RFQ0wgKHQpKSkKCXJldHJvZml0X2xhbmdfZGVjbCAoVFlQRV9NQUlOX0RFQ0wgKHQpKTsKICAgICAgREVDTF9TT1JURURfRklFTERTIChUWVBFX01BSU5fREVDTCAodCkpID0gZmllbGRfdmVjOwogICAgfQoKICAvKiBNYWtlIHRoZSBydGwgZm9yIGFueSBuZXcgdnRhYmxlcyB3ZSBoYXZlIGNyZWF0ZWQsIGFuZCB1bm1hcmsKICAgICB0aGUgYmFzZSB0eXBlcyB3ZSBtYXJrZWQuICAqLwogIGZpbmlzaF92dGJscyAodCk7CiAgCiAgLyogQnVpbGQgdGhlIFZUVCBmb3IgVC4gICovCiAgYnVpbGRfdnR0ICh0KTsKCiAgLyogVGhpcyB3YXJuaW5nIGRvZXMgbm90IG1ha2Ugc2Vuc2UgZm9yIEphdmEgY2xhc3Nlcywgc2luY2UgdGhleQogICAgIGNhbm5vdCBoYXZlIGRlc3RydWN0b3JzLiAgKi8KICBpZiAoIVRZUEVfRk9SX0pBVkEgKHQpICYmIHdhcm5fbm9udmR0b3IgJiYgVFlQRV9QT0xZTU9SUEhJQ19QICh0KSkKICAgIHsKICAgICAgdHJlZSBkdG9yOwoKICAgICAgZHRvciA9IENMQVNTVFlQRV9ERVNUUlVDVE9SUyAodCk7CiAgICAgIC8qIFdhcm4gb25seSBpZiB0aGUgZHRvciBpcyBub24tcHJpdmF0ZSBvciB0aGUgY2xhc3MgaGFzCgkgZnJpZW5kcy4gICovCiAgICAgIGlmICgvKiBBbiBpbXBsaWNpdGx5IGRlY2xhcmVkIGRlc3RydWN0b3IgaXMgYWx3YXlzIHB1YmxpYy4gIEFuZCwKCSAgICAgaWYgaXQgd2VyZSB2aXJ0dWFsLCB3ZSB3b3VsZCBoYXZlIGNyZWF0ZWQgaXQgYnkgbm93LiAgKi8KCSAgIWR0b3IKCSAgfHwgKCFERUNMX1ZJTkRFWCAoZHRvcikKCSAgICAgICYmICghVFJFRV9QUklWQVRFIChkdG9yKSAKCQkgIHx8IENMQVNTVFlQRV9GUklFTkRfQ0xBU1NFUyAodCkgCgkJICB8fCBERUNMX0ZSSUVORExJU1QgKFRZUEVfTUFJTl9ERUNMICh0KSkpKSkKCXdhcm5pbmcgKCIlcSNUIGhhcyB2aXJ0dWFsIGZ1bmN0aW9ucyBidXQgbm9uLXZpcnR1YWwgZGVzdHJ1Y3RvciIsIAoJCSB0KTsKICAgIH0KCiAgY29tcGxldGVfdmFycyAodCk7CgogIGlmICh3YXJuX292ZXJsb2FkZWRfdmlydHVhbCkKICAgIHdhcm5faGlkZGVuICh0KTsKCiAgbWF5YmVfc3VwcHJlc3NfZGVidWdfaW5mbyAodCk7CgogIGR1bXBfY2xhc3NfaGllcmFyY2h5ICh0KTsKICAKICAvKiBGaW5pc2ggZGVidWdnaW5nIG91dHB1dCBmb3IgdGhpcyB0eXBlLiAgKi8KICAvKiBBUFBMRSBMT0NBTCA0MTY3NzU5ICovCiAgY3Bfc2V0X2RlY2xfaWdub3JlX2ZsYWcgKHQsIDEpOwogIHJlc3Rfb2ZfdHlwZV9jb21waWxhdGlvbiAodCwgISBMT0NBTF9DTEFTU19QICh0KSk7CiAgLyogQVBQTEUgTE9DQUwgNDE2Nzc1OSAqLwogIGNwX3NldF9kZWNsX2lnbm9yZV9mbGFnICh0LCAwKTsKfQoKLyogV2hlbiBUIHdhcyBidWlsdCB1cCwgdGhlIG1lbWJlciBkZWNsYXJhdGlvbnMgd2VyZSBhZGRlZCBpbiByZXZlcnNlCiAgIG9yZGVyLiAgUmVhcnJhbmdlIHRoZW0gdG8gZGVjbGFyYXRpb24gb3JkZXIuICAqLwoKdm9pZAp1bnJldmVyc2VfbWVtYmVyX2RlY2xhcmF0aW9ucyAodHJlZSB0KQp7CiAgdHJlZSBuZXh0OwogIHRyZWUgcHJldjsKICB0cmVlIHg7CgogIC8qIFRoZSBmb2xsb3dpbmcgbGlzdHMgYXJlIGFsbCBpbiByZXZlcnNlIG9yZGVyLiAgUHV0IHRoZW0gaW4KICAgICBkZWNsYXJhdGlvbiBvcmRlciBub3cuICAqLwogIFRZUEVfTUVUSE9EUyAodCkgPSBucmV2ZXJzZSAoVFlQRV9NRVRIT0RTICh0KSk7CiAgQ0xBU1NUWVBFX0RFQ0xfTElTVCAodCkgPSBucmV2ZXJzZSAoQ0xBU1NUWVBFX0RFQ0xfTElTVCAodCkpOwoKICAvKiBBY3R1YWxseSwgZm9yIHRoZSBUWVBFX0ZJRUxEUywgb25seSB0aGUgbm9uIFRZUEVfREVDTHMgYXJlIGluCiAgICAgcmV2ZXJzZSBvcmRlciwgc28gd2UgY2FuJ3QganVzdCB1c2UgbnJldmVyc2UuICAqLwogIHByZXYgPSBOVUxMX1RSRUU7CiAgZm9yICh4ID0gVFlQRV9GSUVMRFMgKHQpOyAKICAgICAgIHggJiYgVFJFRV9DT0RFICh4KSAhPSBUWVBFX0RFQ0w7IAogICAgICAgeCA9IG5leHQpCiAgICB7CiAgICAgIG5leHQgPSBUUkVFX0NIQUlOICh4KTsKICAgICAgVFJFRV9DSEFJTiAoeCkgPSBwcmV2OwogICAgICBwcmV2ID0geDsKICAgIH0KICBpZiAocHJldikKICAgIHsKICAgICAgVFJFRV9DSEFJTiAoVFlQRV9GSUVMRFMgKHQpKSA9IHg7CiAgICAgIGlmIChwcmV2KQoJVFlQRV9GSUVMRFMgKHQpID0gcHJldjsKICAgIH0KfQoKdHJlZQpmaW5pc2hfc3RydWN0ICh0cmVlIHQsIHRyZWUgYXR0cmlidXRlcykKewogIGxvY2F0aW9uX3Qgc2F2ZWRfbG9jID0gaW5wdXRfbG9jYXRpb247CgogIC8qIE5vdyB0aGF0IHdlJ3ZlIGdvdCBhbGwgdGhlIGZpZWxkIGRlY2xhcmF0aW9ucywgcmV2ZXJzZSBldmVyeXRoaW5nCiAgICAgYXMgbmVjZXNzYXJ5LiAgKi8KICB1bnJldmVyc2VfbWVtYmVyX2RlY2xhcmF0aW9ucyAodCk7CgogIGNwbHVzX2RlY2xfYXR0cmlidXRlcyAoJnQsIGF0dHJpYnV0ZXMsIChpbnQpIEFUVFJfRkxBR19UWVBFX0lOX1BMQUNFKTsKCiAgLyogTmFkZ2VyIHRoZSBjdXJyZW50IGxvY2F0aW9uIHNvIHRoYXQgZGlhZ25vc3RpY3MgcG9pbnQgdG8gdGhlIHN0YXJ0IG9mCiAgICAgdGhlIHN0cnVjdCwgbm90IHRoZSBlbmQuICAqLwogIGlucHV0X2xvY2F0aW9uID0gREVDTF9TT1VSQ0VfTE9DQVRJT04gKFRZUEVfTkFNRSAodCkpOwoKICBpZiAocHJvY2Vzc2luZ190ZW1wbGF0ZV9kZWNsKQogICAgewogICAgICB0cmVlIHg7CgogICAgICBmaW5pc2hfc3RydWN0X21ldGhvZHMgKHQpOwogICAgICBUWVBFX1NJWkUgKHQpID0gYml0c2l6ZV96ZXJvX25vZGU7CiAgICAgIFRZUEVfU0laRV9VTklUICh0KSA9IHNpemVfemVyb19ub2RlOwoKICAgICAgLyogV2UgbmVlZCB0byBlbWl0IGFuIGVycm9yIG1lc3NhZ2UgaWYgdGhpcyB0eXBlIHdhcyB1c2VkIGFzIGEgcGFyYW1ldGVyCgkgYW5kIGl0IGlzIGFuIGFic3RyYWN0IHR5cGUsIGV2ZW4gaWYgaXQgaXMgYSB0ZW1wbGF0ZS4gV2UgY29uc3RydWN0CgkgYSBzaW1wbGUgQ0xBU1NUWVBFX1BVUkVfVklSVFVBTFMgbGlzdCB3aXRob3V0IHRha2luZyBiYXNlcyBpbnRvCgkgYWNjb3VudCBhbmQgd2UgY2FsbCBjb21wbGV0ZV92YXJzIHdpdGggdGhpcyB0eXBlLCB3aGljaCB3aWxsIGNoZWNrCgkgdGhlIFBBUk1fREVDTFMuIE5vdGUgdGhhdCB3aGlsZSB0aGUgdHlwZSBpcyBiZWluZyBkZWZpbmVkLAoJIENMQVNTVFlQRV9QVVJFX1ZJUlRVQUxTIGNvbnRhaW5zIHRoZSBsaXN0IG9mIHRoZSBpbmxpbmUgZnJpZW5kcwoJIChzZWUgQ0xBU1NUWVBFX0lOTElORV9GUklFTkRTKSBzbyB3ZSBuZWVkIHRvIGNsZWFyIGl0LiAgKi8KICAgICAgQ0xBU1NUWVBFX1BVUkVfVklSVFVBTFMgKHQpID0gTlVMTDsKICAgICAgZm9yICh4ID0gVFlQRV9NRVRIT0RTICh0KTsgeDsgeCA9IFRSRUVfQ0hBSU4gKHgpKQoJaWYgKERFQ0xfUFVSRV9WSVJUVUFMX1AgKHgpKQoJICBWRUNfc2FmZV9wdXNoICh0cmVlLCBDTEFTU1RZUEVfUFVSRV9WSVJUVUFMUyAodCksIHgpOwogICAgICBjb21wbGV0ZV92YXJzICh0KTsKICAgIH0KICBlbHNlCiAgICBmaW5pc2hfc3RydWN0XzEgKHQpOwoKICBpbnB1dF9sb2NhdGlvbiA9IHNhdmVkX2xvYzsKCiAgVFlQRV9CRUlOR19ERUZJTkVEICh0KSA9IDA7CgogIGlmIChjdXJyZW50X2NsYXNzX3R5cGUpCiAgICBwb3BjbGFzcyAoKTsKICBlbHNlCiAgICBlcnJvciAoInRyeWluZyB0byBmaW5pc2ggc3RydWN0LCBidXQga2lja2VkIG91dCBkdWUgdG8gcHJldmlvdXMgcGFyc2UgZXJyb3JzIik7CgogIGlmIChwcm9jZXNzaW5nX3RlbXBsYXRlX2RlY2wgJiYgYXRfZnVuY3Rpb25fc2NvcGVfcCAoKSkKICAgIGFkZF9zdG10IChidWlsZF9taW4gKFRBR19ERUZOLCB0KSk7CgogIHJldHVybiB0Owp9CgwKLyogUmV0dXJuIHRoZSBkeW5hbWljIHR5cGUgb2YgSU5TVEFOQ0UsIGlmIGtub3duLgogICBVc2VkIHRvIGRldGVybWluZSB3aGV0aGVyIHRoZSB2aXJ0dWFsIGZ1bmN0aW9uIHRhYmxlIGlzIG5lZWRlZAogICBvciBub3QuCgogICAqTk9OTlVMTCBpcyBzZXQgaWZmIElOU1RBTkNFIGNhbiBiZSBrbm93biB0byBiZSBub25udWxsLCByZWdhcmRsZXNzCiAgIG9mIG91ciBrbm93bGVkZ2Ugb2YgaXRzIHR5cGUuICAqTk9OTlVMTCBzaG91bGQgYmUgaW5pdGlhbGl6ZWQKICAgYmVmb3JlIHRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkLiAgKi8KCnN0YXRpYyB0cmVlCmZpeGVkX3R5cGVfb3JfbnVsbCAodHJlZSBpbnN0YW5jZSwgaW50KiBub25udWxsLCBpbnQqIGNkdG9ycCkKewogIHN3aXRjaCAoVFJFRV9DT0RFIChpbnN0YW5jZSkpCiAgICB7CiAgICBjYXNlIElORElSRUNUX1JFRjoKICAgICAgaWYgKFBPSU5URVJfVFlQRV9QIChUUkVFX1RZUEUgKGluc3RhbmNlKSkpCglyZXR1cm4gTlVMTF9UUkVFOwogICAgICBlbHNlCglyZXR1cm4gZml4ZWRfdHlwZV9vcl9udWxsIChUUkVFX09QRVJBTkQgKGluc3RhbmNlLCAwKSwKCQkJCSAgIG5vbm51bGwsIGNkdG9ycCk7CgogICAgY2FzZSBDQUxMX0VYUFI6CiAgICAgIC8qIFRoaXMgaXMgYSBjYWxsIHRvIGEgY29uc3RydWN0b3IsIGhlbmNlIGl0J3MgbmV2ZXIgemVyby4gICovCiAgICAgIGlmIChUUkVFX0hBU19DT05TVFJVQ1RPUiAoaW5zdGFuY2UpKQoJewoJICBpZiAobm9ubnVsbCkKCSAgICAqbm9ubnVsbCA9IDE7CgkgIHJldHVybiBUUkVFX1RZUEUgKGluc3RhbmNlKTsKCX0KICAgICAgcmV0dXJuIE5VTExfVFJFRTsKCiAgICBjYXNlIFNBVkVfRVhQUjoKICAgICAgLyogVGhpcyBpcyBhIGNhbGwgdG8gYSBjb25zdHJ1Y3RvciwgaGVuY2UgaXQncyBuZXZlciB6ZXJvLiAgKi8KICAgICAgaWYgKFRSRUVfSEFTX0NPTlNUUlVDVE9SIChpbnN0YW5jZSkpCgl7CgkgIGlmIChub25udWxsKQoJICAgICpub25udWxsID0gMTsKCSAgcmV0dXJuIFRSRUVfVFlQRSAoaW5zdGFuY2UpOwoJfQogICAgICByZXR1cm4gZml4ZWRfdHlwZV9vcl9udWxsIChUUkVFX09QRVJBTkQgKGluc3RhbmNlLCAwKSwgbm9ubnVsbCwgY2R0b3JwKTsKCiAgICBjYXNlIFBMVVNfRVhQUjoKICAgIGNhc2UgTUlOVVNfRVhQUjoKICAgICAgaWYgKFRSRUVfQ09ERSAoVFJFRV9PUEVSQU5EIChpbnN0YW5jZSwgMCkpID09IEFERFJfRVhQUikKCXJldHVybiBmaXhlZF90eXBlX29yX251bGwgKFRSRUVfT1BFUkFORCAoaW5zdGFuY2UsIDApLCBub25udWxsLCBjZHRvcnApOwogICAgICBpZiAoVFJFRV9DT0RFIChUUkVFX09QRVJBTkQgKGluc3RhbmNlLCAxKSkgPT0gSU5URUdFUl9DU1QpCgkvKiBQcm9wYWdhdGUgbm9ubnVsbC4gICovCglyZXR1cm4gZml4ZWRfdHlwZV9vcl9udWxsIChUUkVFX09QRVJBTkQgKGluc3RhbmNlLCAwKSwgbm9ubnVsbCwgY2R0b3JwKTsKICAgICAgcmV0dXJuIE5VTExfVFJFRTsKCiAgICBjYXNlIE5PUF9FWFBSOgogICAgY2FzZSBDT05WRVJUX0VYUFI6CiAgICAgIHJldHVybiBmaXhlZF90eXBlX29yX251bGwgKFRSRUVfT1BFUkFORCAoaW5zdGFuY2UsIDApLCBub25udWxsLCBjZHRvcnApOwoKICAgIGNhc2UgQUREUl9FWFBSOgogICAgICBpbnN0YW5jZSA9IFRSRUVfT1BFUkFORCAoaW5zdGFuY2UsIDApOwogICAgICBpZiAobm9ubnVsbCkKCXsKCSAgLyogSnVzdCBiZWNhdXNlIHdlIHNlZSBhbiBBRERSX0VYUFIgZG9lc24ndCBtZWFuIHdlJ3JlIGRlYWxpbmcKCSAgICAgd2l0aCBhIHJlYWwgb2JqZWN0IC0tIGdpdmVuICZwLT5mLCBwIGNhbiBzdGlsbCBiZSBudWxsLiAgKi8KCSAgdHJlZSB0ID0gZ2V0X2Jhc2VfYWRkcmVzcyAoaW5zdGFuY2UpOwoJICAvKiA/Pz8gUHJvYmFibHkgc2hvdWxkIGNoZWNrIERFQ0xfV0VBSyBoZXJlLiAgKi8KCSAgaWYgKHQgJiYgREVDTF9QICh0KSkKCSAgICAqbm9ubnVsbCA9IDE7Cgl9CiAgICAgIHJldHVybiBmaXhlZF90eXBlX29yX251bGwgKGluc3RhbmNlLCBub25udWxsLCBjZHRvcnApOwoKICAgIGNhc2UgQ09NUE9ORU5UX1JFRjoKICAgICAgLyogSWYgdGhpcyBjb21wb25lbnQgaXMgcmVhbGx5IGEgYmFzZSBjbGFzcyByZWZlcmVuY2UsIHRoZW4gdGhlIGZpZWxkCgkgaXRzZWxmIGlzbid0IGRlZmluaXRpdmUuICAqLwogICAgICBpZiAoREVDTF9GSUVMRF9JU19CQVNFIChUUkVFX09QRVJBTkQgKGluc3RhbmNlLCAxKSkpCiAgICAgICAgcmV0dXJuIGZpeGVkX3R5cGVfb3JfbnVsbCAoVFJFRV9PUEVSQU5EIChpbnN0YW5jZSwgMCksIG5vbm51bGwsIGNkdG9ycCk7CiAgICAgIHJldHVybiBmaXhlZF90eXBlX29yX251bGwgKFRSRUVfT1BFUkFORCAoaW5zdGFuY2UsIDEpLCBub25udWxsLCBjZHRvcnApOwoKICAgIGNhc2UgVkFSX0RFQ0w6CiAgICBjYXNlIEZJRUxEX0RFQ0w6CiAgICAgIGlmIChUUkVFX0NPREUgKFRSRUVfVFlQRSAoaW5zdGFuY2UpKSA9PSBBUlJBWV9UWVBFCgkgICYmIElTX0FHR1JfVFlQRSAoVFJFRV9UWVBFIChUUkVFX1RZUEUgKGluc3RhbmNlKSkpKQoJewoJICBpZiAobm9ubnVsbCkKCSAgICAqbm9ubnVsbCA9IDE7CgkgIHJldHVybiBUUkVFX1RZUEUgKFRSRUVfVFlQRSAoaW5zdGFuY2UpKTsKCX0KICAgICAgLyogZmFsbCB0aHJvdWdoLi4uICAqLwogICAgY2FzZSBUQVJHRVRfRVhQUjoKICAgIGNhc2UgUEFSTV9ERUNMOgogICAgY2FzZSBSRVNVTFRfREVDTDoKICAgICAgaWYgKElTX0FHR1JfVFlQRSAoVFJFRV9UWVBFIChpbnN0YW5jZSkpKQoJewoJICBpZiAobm9ubnVsbCkKCSAgICAqbm9ubnVsbCA9IDE7CgkgIHJldHVybiBUUkVFX1RZUEUgKGluc3RhbmNlKTsKCX0KICAgICAgZWxzZSBpZiAoaW5zdGFuY2UgPT0gY3VycmVudF9jbGFzc19wdHIpCiAgICAgICAgewogICAgICAgICAgaWYgKG5vbm51bGwpCiAgICAgICAgICAgICpub25udWxsID0gMTsKICAgICAgICAKICAgICAgICAgIC8qIGlmIHdlJ3JlIGluIGEgY3RvciBvciBkdG9yLCB3ZSBrbm93IG91ciB0eXBlLiAgKi8KICAgICAgICAgIGlmIChERUNMX0xBTkdfU1BFQ0lGSUMgKGN1cnJlbnRfZnVuY3Rpb25fZGVjbCkKICAgICAgICAgICAgICAmJiAoREVDTF9DT05TVFJVQ1RPUl9QIChjdXJyZW50X2Z1bmN0aW9uX2RlY2wpCiAgICAgICAgICAgICAgICAgIHx8IERFQ0xfREVTVFJVQ1RPUl9QIChjdXJyZW50X2Z1bmN0aW9uX2RlY2wpKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgIGlmIChjZHRvcnApCiAgICAgICAgICAgICAgICAqY2R0b3JwID0gMTsKICAgICAgICAgICAgICByZXR1cm4gVFJFRV9UWVBFIChUUkVFX1RZUEUgKGluc3RhbmNlKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIGVsc2UgaWYgKFRSRUVfQ09ERSAoVFJFRV9UWVBFIChpbnN0YW5jZSkpID09IFJFRkVSRU5DRV9UWVBFKQogICAgICAgIHsKICAgICAgICAgIC8qIFJlZmVyZW5jZSB2YXJpYWJsZXMgc2hvdWxkIGJlIHJlZmVyZW5jZXMgdG8gb2JqZWN0cy4gICovCiAgICAgICAgICBpZiAobm9ubnVsbCkKCSAgICAqbm9ubnVsbCA9IDE7CgkgIAoJICAvKiBERUNMX1ZBUl9NQVJLRURfUCBpcyB1c2VkIHRvIHByZXZlbnQgcmVjdXJzaW9uOyBhCgkgICAgIHZhcmlhYmxlJ3MgaW5pdGlhbGl6ZXIgbWF5IHJlZmVyIHRvIHRoZSB2YXJpYWJsZQoJICAgICBpdHNlbGYuICAqLwoJICBpZiAoVFJFRV9DT0RFIChpbnN0YW5jZSkgPT0gVkFSX0RFQ0wgCgkgICAgICAmJiBERUNMX0lOSVRJQUwgKGluc3RhbmNlKQoJICAgICAgJiYgIURFQ0xfVkFSX01BUktFRF9QIChpbnN0YW5jZSkpCgkgICAgewoJICAgICAgdHJlZSB0eXBlOwoJICAgICAgREVDTF9WQVJfTUFSS0VEX1AgKGluc3RhbmNlKSA9IDE7CgkgICAgICB0eXBlID0gZml4ZWRfdHlwZV9vcl9udWxsIChERUNMX0lOSVRJQUwgKGluc3RhbmNlKSwKCQkJCQkgbm9ubnVsbCwgY2R0b3JwKTsKCSAgICAgIERFQ0xfVkFSX01BUktFRF9QIChpbnN0YW5jZSkgPSAwOwoJICAgICAgcmV0dXJuIHR5cGU7CgkgICAgfQoJfQogICAgICByZXR1cm4gTlVMTF9UUkVFOwoKICAgIGRlZmF1bHQ6CiAgICAgIHJldHVybiBOVUxMX1RSRUU7CiAgICB9Cn0KCi8qIFJldHVybiBub256ZXJvIGlmIHRoZSBkeW5hbWljIHR5cGUgb2YgSU5TVEFOQ0UgaXMga25vd24sIGFuZAogICBlcXVpdmFsZW50IHRvIHRoZSBzdGF0aWMgdHlwZS4gIFdlIGFsc28gaGFuZGxlIHRoZSBjYXNlIHdoZXJlCiAgIElOU1RBTkNFIGlzIHJlYWxseSBhIHBvaW50ZXIuIFJldHVybiBuZWdhdGl2ZSBpZiB0aGlzIGlzIGEKICAgY3Rvci9kdG9yLiBUaGVyZSB0aGUgZHluYW1pYyB0eXBlIGlzIGtub3duLCBidXQgdGhpcyBtaWdodCBub3QgYmUKICAgdGhlIG1vc3QgZGVyaXZlZCBiYXNlIG9mIHRoZSBvcmlnaW5hbCBvYmplY3QsIGFuZCBoZW5jZSB2aXJ0dWFsCiAgIGJhc2VzIG1heSBub3QgYmUgbGF5ZWQgb3V0IGFjY29yZGluZyB0byB0aGlzIHR5cGUuCgogICBVc2VkIHRvIGRldGVybWluZSB3aGV0aGVyIHRoZSB2aXJ0dWFsIGZ1bmN0aW9uIHRhYmxlIGlzIG5lZWRlZAogICBvciBub3QuCgogICAqTk9OTlVMTCBpcyBzZXQgaWZmIElOU1RBTkNFIGNhbiBiZSBrbm93biB0byBiZSBub25udWxsLCByZWdhcmRsZXNzCiAgIG9mIG91ciBrbm93bGVkZ2Ugb2YgaXRzIHR5cGUuICAqTk9OTlVMTCBzaG91bGQgYmUgaW5pdGlhbGl6ZWQKICAgYmVmb3JlIHRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkLiAgKi8KCmludApyZXNvbHZlc190b19maXhlZF90eXBlX3AgKHRyZWUgaW5zdGFuY2UsIGludCogbm9ubnVsbCkKewogIHRyZWUgdCA9IFRSRUVfVFlQRSAoaW5zdGFuY2UpOwogIGludCBjZHRvcnAgPSAwOwogIAogIHRyZWUgZml4ZWQgPSBmaXhlZF90eXBlX29yX251bGwgKGluc3RhbmNlLCBub25udWxsLCAmY2R0b3JwKTsKICBpZiAoZml4ZWQgPT0gTlVMTF9UUkVFKQogICAgcmV0dXJuIDA7CiAgaWYgKFBPSU5URVJfVFlQRV9QICh0KSkKICAgIHQgPSBUUkVFX1RZUEUgKHQpOwogIGlmICghc2FtZV90eXBlX2lnbm9yaW5nX3RvcF9sZXZlbF9xdWFsaWZpZXJzX3AgKHQsIGZpeGVkKSkKICAgIHJldHVybiAwOwogIHJldHVybiBjZHRvcnAgPyAtMSA6IDE7Cn0KCgwKdm9pZAppbml0X2NsYXNzX3Byb2Nlc3NpbmcgKHZvaWQpCnsKICBjdXJyZW50X2NsYXNzX2RlcHRoID0gMDsKICBjdXJyZW50X2NsYXNzX3N0YWNrX3NpemUgPSAxMDsKICBjdXJyZW50X2NsYXNzX3N0YWNrIAogICAgPSB4bWFsbG9jIChjdXJyZW50X2NsYXNzX3N0YWNrX3NpemUgKiBzaXplb2YgKHN0cnVjdCBjbGFzc19zdGFja19ub2RlKSk7CiAgVkFSUkFZX1RSRUVfSU5JVCAobG9jYWxfY2xhc3NlcywgOCwgImxvY2FsX2NsYXNzZXMiKTsKCiAgcmlkcG9pbnRlcnNbKGludCkgUklEX1BVQkxJQ10gPSBhY2Nlc3NfcHVibGljX25vZGU7CiAgcmlkcG9pbnRlcnNbKGludCkgUklEX1BSSVZBVEVdID0gYWNjZXNzX3ByaXZhdGVfbm9kZTsKICByaWRwb2ludGVyc1soaW50KSBSSURfUFJPVEVDVEVEXSA9IGFjY2Vzc19wcm90ZWN0ZWRfbm9kZTsKfQoKLyogUmVzdG9yZSB0aGUgY2FjaGVkIFBSRVZJT1VTX0NMQVNTX0xFVkVMLiAgKi8KCnN0YXRpYyB2b2lkCnJlc3RvcmVfY2xhc3NfY2FjaGUgKHZvaWQpCnsKICB0cmVlIHR5cGU7CgogIC8qIFdlIGFyZSByZS1lbnRlcmluZyB0aGUgc2FtZSBjbGFzcyB3ZSBqdXN0IGxlZnQsIHNvIHdlIGRvbid0CiAgICAgaGF2ZSB0byBzZWFyY2ggdGhlIHdob2xlIGluaGVyaXRhbmNlIG1hdHJpeCB0byBmaW5kIGFsbCB0aGUKICAgICBkZWNscyB0byBiaW5kIGFnYWluLiAgSW5zdGVhZCwgd2UgaW5zdGFsbCB0aGUgY2FjaGVkCiAgICAgY2xhc3Nfc2hhZG93ZWQgbGlzdCBhbmQgd2FsayB0aHJvdWdoIGl0IGJpbmRpbmcgbmFtZXMuICAqLwogIHB1c2hfYmluZGluZ19sZXZlbCAocHJldmlvdXNfY2xhc3NfbGV2ZWwpOwogIGNsYXNzX2JpbmRpbmdfbGV2ZWwgPSBwcmV2aW91c19jbGFzc19sZXZlbDsKICAvKiBSZXN0b3JlIElERU5USUZJRVJfVFlQRV9WQUxVRS4gICovCiAgZm9yICh0eXBlID0gY2xhc3NfYmluZGluZ19sZXZlbC0+dHlwZV9zaGFkb3dlZDsgCiAgICAgICB0eXBlOyAKICAgICAgIHR5cGUgPSBUUkVFX0NIQUlOICh0eXBlKSkKICAgIFNFVF9JREVOVElGSUVSX1RZUEVfVkFMVUUgKFRSRUVfUFVSUE9TRSAodHlwZSksIFRSRUVfVFlQRSAodHlwZSkpOwp9CgovKiBTZXQgZ2xvYmFsIHZhcmlhYmxlcyBDVVJSRU5UX0NMQVNTX05BTUUgYW5kIENVUlJFTlRfQ0xBU1NfVFlQRSBhcwogICBhcHByb3ByaWF0ZSBmb3IgVFlQRS4KCiAgIFNvIHRoYXQgd2UgbWF5IGF2b2lkIGNhbGxzIHRvIGxvb2t1cF9uYW1lLCB3ZSBjYWNoZSB0aGUgX1RZUEUKICAgbm9kZXMgb2YgbG9jYWwgVFlQRV9ERUNMcyBpbiB0aGUgVFJFRV9UWVBFIGZpZWxkIG9mIHRoZSBuYW1lLgoKICAgRm9yIG11bHRpcGxlIGluaGVyaXRhbmNlLCB3ZSBwZXJmb3JtIGEgdHdvLXBhc3MgZGVwdGgtZmlyc3Qgc2VhcmNoCiAgIG9mIHRoZSB0eXBlIGxhdHRpY2UuICAqLwoKdm9pZApwdXNoY2xhc3MgKHRyZWUgdHlwZSkKewogIHR5cGUgPSBUWVBFX01BSU5fVkFSSUFOVCAodHlwZSk7CgogIC8qIE1ha2Ugc3VyZSB0aGVyZSBpcyBlbm91Z2ggcm9vbSBmb3IgdGhlIG5ldyBlbnRyeSBvbiB0aGUgc3RhY2suICAqLwogIGlmIChjdXJyZW50X2NsYXNzX2RlcHRoICsgMSA+PSBjdXJyZW50X2NsYXNzX3N0YWNrX3NpemUpIAogICAgewogICAgICBjdXJyZW50X2NsYXNzX3N0YWNrX3NpemUgKj0gMjsKICAgICAgY3VycmVudF9jbGFzc19zdGFjawoJPSB4cmVhbGxvYyAoY3VycmVudF9jbGFzc19zdGFjaywKCQkgICAgY3VycmVudF9jbGFzc19zdGFja19zaXplCgkJICAgICogc2l6ZW9mIChzdHJ1Y3QgY2xhc3Nfc3RhY2tfbm9kZSkpOwogICAgfQoKICAvKiBJbnNlcnQgYSBuZXcgZW50cnkgb24gdGhlIGNsYXNzIHN0YWNrLiAgKi8KICBjdXJyZW50X2NsYXNzX3N0YWNrW2N1cnJlbnRfY2xhc3NfZGVwdGhdLm5hbWUgPSBjdXJyZW50X2NsYXNzX25hbWU7CiAgY3VycmVudF9jbGFzc19zdGFja1tjdXJyZW50X2NsYXNzX2RlcHRoXS50eXBlID0gY3VycmVudF9jbGFzc190eXBlOwogIGN1cnJlbnRfY2xhc3Nfc3RhY2tbY3VycmVudF9jbGFzc19kZXB0aF0uYWNjZXNzID0gY3VycmVudF9hY2Nlc3Nfc3BlY2lmaWVyOwogIGN1cnJlbnRfY2xhc3Nfc3RhY2tbY3VycmVudF9jbGFzc19kZXB0aF0ubmFtZXNfdXNlZCA9IDA7CiAgY3VycmVudF9jbGFzc19kZXB0aCsrOwoKICAvKiBOb3cgc2V0IHVwIHRoZSBuZXcgdHlwZS4gICovCiAgY3VycmVudF9jbGFzc19uYW1lID0gVFlQRV9OQU1FICh0eXBlKTsKICBpZiAoVFJFRV9DT0RFIChjdXJyZW50X2NsYXNzX25hbWUpID09IFRZUEVfREVDTCkKICAgIGN1cnJlbnRfY2xhc3NfbmFtZSA9IERFQ0xfTkFNRSAoY3VycmVudF9jbGFzc19uYW1lKTsKICBjdXJyZW50X2NsYXNzX3R5cGUgPSB0eXBlOwoKICAvKiBCeSBkZWZhdWx0LCB0aGluZ3MgaW4gY2xhc3NlcyBhcmUgcHJpdmF0ZSwgd2hpbGUgdGhpbmdzIGluCiAgICAgc3RydWN0dXJlcyBvciB1bmlvbnMgYXJlIHB1YmxpYy4gICovCiAgY3VycmVudF9hY2Nlc3Nfc3BlY2lmaWVyID0gKENMQVNTVFlQRV9ERUNMQVJFRF9DTEFTUyAodHlwZSkgCgkJCSAgICAgID8gYWNjZXNzX3ByaXZhdGVfbm9kZSAKCQkJICAgICAgOiBhY2Nlc3NfcHVibGljX25vZGUpOwoKICBpZiAocHJldmlvdXNfY2xhc3NfbGV2ZWwKICAgICAgJiYgdHlwZSAhPSBwcmV2aW91c19jbGFzc19sZXZlbC0+dGhpc19lbnRpdHkKICAgICAgJiYgY3VycmVudF9jbGFzc19kZXB0aCA9PSAxKQogICAgewogICAgICAvKiBGb3JjaWJseSByZW1vdmUgYW55IG9sZCBjbGFzcyByZW1uYW50cy4gICovCiAgICAgIGludmFsaWRhdGVfY2xhc3NfbG9va3VwX2NhY2hlICgpOwogICAgfQoKICBpZiAoIXByZXZpb3VzX2NsYXNzX2xldmVsIAogICAgICB8fCB0eXBlICE9IHByZXZpb3VzX2NsYXNzX2xldmVsLT50aGlzX2VudGl0eQogICAgICB8fCBjdXJyZW50X2NsYXNzX2RlcHRoID4gMSkKICAgIHB1c2hsZXZlbF9jbGFzcyAoKTsKICBlbHNlCiAgICByZXN0b3JlX2NsYXNzX2NhY2hlICgpOwp9CgovKiBXaGVuIHdlIGV4aXQgYSB0b3BsZXZlbCBjbGFzcyBzY29wZSwgd2Ugc2F2ZSBpdHMgYmluZGluZyBsZXZlbCBzbwogICB0aGF0IHdlIGNhbiByZXN0b3JlIGl0IHF1aWNrbHkuICBIZXJlLCB3ZSd2ZSBlbnRlcmVkIHNvbWUgb3RoZXIKICAgY2xhc3MsIHNvIHdlIG11c3QgaW52YWxpZGF0ZSBvdXIgY2FjaGUuICAqLwoKdm9pZAppbnZhbGlkYXRlX2NsYXNzX2xvb2t1cF9jYWNoZSAodm9pZCkKewogIHByZXZpb3VzX2NsYXNzX2xldmVsID0gTlVMTDsKfQogCi8qIEdldCBvdXQgb2YgdGhlIGN1cnJlbnQgY2xhc3Mgc2NvcGUuIElmIHdlIHdlcmUgaW4gYSBjbGFzcyBzY29wZQogICBwcmV2aW91c2x5LCB0aGF0IGlzIHRoZSBvbmUgcG9wcGVkIHRvLiAgKi8KCnZvaWQKcG9wY2xhc3MgKHZvaWQpCnsKICBwb3BsZXZlbF9jbGFzcyAoKTsKCiAgY3VycmVudF9jbGFzc19kZXB0aC0tOwogIGN1cnJlbnRfY2xhc3NfbmFtZSA9IGN1cnJlbnRfY2xhc3Nfc3RhY2tbY3VycmVudF9jbGFzc19kZXB0aF0ubmFtZTsKICBjdXJyZW50X2NsYXNzX3R5cGUgPSBjdXJyZW50X2NsYXNzX3N0YWNrW2N1cnJlbnRfY2xhc3NfZGVwdGhdLnR5cGU7CiAgY3VycmVudF9hY2Nlc3Nfc3BlY2lmaWVyID0gY3VycmVudF9jbGFzc19zdGFja1tjdXJyZW50X2NsYXNzX2RlcHRoXS5hY2Nlc3M7CiAgaWYgKGN1cnJlbnRfY2xhc3Nfc3RhY2tbY3VycmVudF9jbGFzc19kZXB0aF0ubmFtZXNfdXNlZCkKICAgIHNwbGF5X3RyZWVfZGVsZXRlIChjdXJyZW50X2NsYXNzX3N0YWNrW2N1cnJlbnRfY2xhc3NfZGVwdGhdLm5hbWVzX3VzZWQpOwp9CgovKiBSZXR1cm5zIDEgaWYgY3VycmVudF9jbGFzc190eXBlIGlzIGVpdGhlciBUIG9yIGEgbmVzdGVkIHR5cGUgb2YgVC4KICAgV2Ugc3RhcnQgbG9va2luZyBmcm9tIDEgYmVjYXVzZSBlbnRyeSAwIGlzIGZyb20gZ2xvYmFsIHNjb3BlLCBhbmQgaGFzCiAgIG5vIHR5cGUuICAqLwoKaW50CmN1cnJlbnRseV9vcGVuX2NsYXNzICh0cmVlIHQpCnsKICBpbnQgaTsKICBpZiAoY3VycmVudF9jbGFzc190eXBlICYmIHNhbWVfdHlwZV9wICh0LCBjdXJyZW50X2NsYXNzX3R5cGUpKQogICAgcmV0dXJuIDE7CiAgZm9yIChpID0gMTsgaSA8IGN1cnJlbnRfY2xhc3NfZGVwdGg7ICsraSkKICAgIGlmIChjdXJyZW50X2NsYXNzX3N0YWNrW2ldLnR5cGUKCSYmIHNhbWVfdHlwZV9wIChjdXJyZW50X2NsYXNzX3N0YWNrIFtpXS50eXBlLCB0KSkKICAgICAgcmV0dXJuIDE7CiAgcmV0dXJuIDA7Cn0KCi8qIElmIGVpdGhlciBjdXJyZW50X2NsYXNzX3R5cGUgb3Igb25lIG9mIGl0cyBlbmNsb3NpbmcgY2xhc3NlcyBhcmUgZGVyaXZlZAogICBmcm9tIFQsIHJldHVybiB0aGUgYXBwcm9wcmlhdGUgdHlwZS4gIFVzZWQgdG8gZGV0ZXJtaW5lIGhvdyB3ZSBmb3VuZAogICBzb21ldGhpbmcgdmlhIHVucXVhbGlmaWVkIGxvb2t1cC4gICovCgp0cmVlCmN1cnJlbnRseV9vcGVuX2Rlcml2ZWRfY2xhc3MgKHRyZWUgdCkKewogIGludCBpOwoKICAvKiBUaGUgYmFzZXMgb2YgYSBkZXBlbmRlbnQgdHlwZSBhcmUgdW5rbm93bi4gICovCiAgaWYgKGRlcGVuZGVudF90eXBlX3AgKHQpKQogICAgcmV0dXJuIE5VTExfVFJFRTsKCiAgaWYgKCFjdXJyZW50X2NsYXNzX3R5cGUpCiAgICByZXR1cm4gTlVMTF9UUkVFOwoKICBpZiAoREVSSVZFRF9GUk9NX1AgKHQsIGN1cnJlbnRfY2xhc3NfdHlwZSkpCiAgICByZXR1cm4gY3VycmVudF9jbGFzc190eXBlOwoKICBmb3IgKGkgPSBjdXJyZW50X2NsYXNzX2RlcHRoIC0gMTsgaSA+IDA7IC0taSkKICAgIGlmIChERVJJVkVEX0ZST01fUCAodCwgY3VycmVudF9jbGFzc19zdGFja1tpXS50eXBlKSkKICAgICAgcmV0dXJuIGN1cnJlbnRfY2xhc3Nfc3RhY2tbaV0udHlwZTsKCiAgcmV0dXJuIE5VTExfVFJFRTsKfQoKLyogV2hlbiBlbnRlcmluZyBhIGNsYXNzIHNjb3BlLCBhbGwgZW5jbG9zaW5nIGNsYXNzIHNjb3BlcycgbmFtZXMgd2l0aAogICBzdGF0aWMgbWVhbmluZyAoc3RhdGljIHZhcmlhYmxlcywgc3RhdGljIGZ1bmN0aW9ucywgdHlwZXMgYW5kCiAgIGVudW1lcmF0b3JzKSBoYXZlIHRvIGJlIHZpc2libGUuICBUaGlzIHJlY3Vyc2l2ZSBmdW5jdGlvbiBjYWxscwogICBwdXNoY2xhc3MgZm9yIGFsbCBlbmNsb3NpbmcgY2xhc3MgY29udGV4dHMgdW50aWwgZ2xvYmFsIG9yIGEgbG9jYWwKICAgc2NvcGUgaXMgcmVhY2hlZC4gIFRZUEUgaXMgdGhlIGVuY2xvc2VkIGNsYXNzLiAgKi8KCnZvaWQKcHVzaF9uZXN0ZWRfY2xhc3MgKHRyZWUgdHlwZSkKewogIHRyZWUgY29udGV4dDsKCiAgLyogQSBuYW1lc3BhY2UgbWlnaHQgYmUgcGFzc2VkIGluIGVycm9yIGNhc2VzLCBsaWtlIEE6OkI6Qy4gICovCiAgaWYgKHR5cGUgPT0gTlVMTF9UUkVFIAogICAgICB8fCB0eXBlID09IGVycm9yX21hcmtfbm9kZSAKICAgICAgfHwgVFJFRV9DT0RFICh0eXBlKSA9PSBOQU1FU1BBQ0VfREVDTAogICAgICB8fCAhIElTX0FHR1JfVFlQRSAodHlwZSkKICAgICAgfHwgVFJFRV9DT0RFICh0eXBlKSA9PSBURU1QTEFURV9UWVBFX1BBUk0KICAgICAgfHwgVFJFRV9DT0RFICh0eXBlKSA9PSBCT1VORF9URU1QTEFURV9URU1QTEFURV9QQVJNKQogICAgcmV0dXJuOwogIAogIGNvbnRleHQgPSBERUNMX0NPTlRFWFQgKFRZUEVfTUFJTl9ERUNMICh0eXBlKSk7CgogIGlmIChjb250ZXh0ICYmIENMQVNTX1RZUEVfUCAoY29udGV4dCkpCiAgICBwdXNoX25lc3RlZF9jbGFzcyAoY29udGV4dCk7CiAgcHVzaGNsYXNzICh0eXBlKTsKfQoKLyogVW5kb2VzIGEgcHVzaF9uZXN0ZWRfY2xhc3MgY2FsbC4gICovCgp2b2lkCnBvcF9uZXN0ZWRfY2xhc3MgKHZvaWQpCnsKICB0cmVlIGNvbnRleHQgPSBERUNMX0NPTlRFWFQgKFRZUEVfTUFJTl9ERUNMIChjdXJyZW50X2NsYXNzX3R5cGUpKTsKCiAgcG9wY2xhc3MgKCk7CiAgaWYgKGNvbnRleHQgJiYgQ0xBU1NfVFlQRV9QIChjb250ZXh0KSkKICAgIHBvcF9uZXN0ZWRfY2xhc3MgKCk7Cn0KCi8qIFJldHVybnMgdGhlIG51bWJlciBvZiBleHRlcm4gIkxBTkciIGJsb2NrcyB3ZSBhcmUgbmVzdGVkIHdpdGhpbi4gICovCgppbnQKY3VycmVudF9sYW5nX2RlcHRoICh2b2lkKQp7CiAgcmV0dXJuIFZBUlJBWV9BQ1RJVkVfU0laRSAoY3VycmVudF9sYW5nX2Jhc2UpOwp9CgovKiBTZXQgZ2xvYmFsIHZhcmlhYmxlcyBDVVJSRU5UX0xBTkdfTkFNRSB0byBhcHByb3ByaWF0ZSB2YWx1ZQogICBzbyB0aGF0IGJlaGF2aW9yIG9mIG5hbWUtbWFuZ2xpbmcgbWFjaGluZXJ5IGlzIGNvcnJlY3QuICAqLwoKdm9pZApwdXNoX2xhbmdfY29udGV4dCAodHJlZSBuYW1lKQp7CiAgVkFSUkFZX1BVU0hfVFJFRSAoY3VycmVudF9sYW5nX2Jhc2UsIGN1cnJlbnRfbGFuZ19uYW1lKTsKCiAgaWYgKG5hbWUgPT0gbGFuZ19uYW1lX2NwbHVzcGx1cykKICAgIHsKICAgICAgY3VycmVudF9sYW5nX25hbWUgPSBuYW1lOwogICAgfQogIGVsc2UgaWYgKG5hbWUgPT0gbGFuZ19uYW1lX2phdmEpCiAgICB7CiAgICAgIGN1cnJlbnRfbGFuZ19uYW1lID0gbmFtZTsKICAgICAgLyogREVDTF9JR05PUkVEX1AgaXMgaW5pdGlhbGx5IHNldCBmb3IgdGhlc2UgdHlwZXMsIHRvIGF2b2lkIGNsdXR0ZXIuCgkgKFNlZSByZWNvcmRfYnVpbHRpbl9qYXZhX3R5cGUgaW4gZGVjbC5jLikgIEhvd2V2ZXIsIHRoYXQgY2F1c2VzCgkgaW5jb3JyZWN0IGRlYnVnIGVudHJpZXMgaWYgdGhlc2UgdHlwZXMgYXJlIGFjdHVhbGx5IHVzZWQuCgkgU28gd2UgcmUtZW5hYmxlIGRlYnVnIG91dHB1dCBhZnRlciBleHRlcm4gIkphdmEiLiAgKi8KICAgICAgREVDTF9JR05PUkVEX1AgKFRZUEVfTkFNRSAoamF2YV9ieXRlX3R5cGVfbm9kZSkpID0gMDsKICAgICAgREVDTF9JR05PUkVEX1AgKFRZUEVfTkFNRSAoamF2YV9zaG9ydF90eXBlX25vZGUpKSA9IDA7CiAgICAgIERFQ0xfSUdOT1JFRF9QIChUWVBFX05BTUUgKGphdmFfaW50X3R5cGVfbm9kZSkpID0gMDsKICAgICAgREVDTF9JR05PUkVEX1AgKFRZUEVfTkFNRSAoamF2YV9sb25nX3R5cGVfbm9kZSkpID0gMDsKICAgICAgREVDTF9JR05PUkVEX1AgKFRZUEVfTkFNRSAoamF2YV9mbG9hdF90eXBlX25vZGUpKSA9IDA7CiAgICAgIERFQ0xfSUdOT1JFRF9QIChUWVBFX05BTUUgKGphdmFfZG91YmxlX3R5cGVfbm9kZSkpID0gMDsKICAgICAgREVDTF9JR05PUkVEX1AgKFRZUEVfTkFNRSAoamF2YV9jaGFyX3R5cGVfbm9kZSkpID0gMDsKICAgICAgREVDTF9JR05PUkVEX1AgKFRZUEVfTkFNRSAoamF2YV9ib29sZWFuX3R5cGVfbm9kZSkpID0gMDsKICAgIH0KICBlbHNlIGlmIChuYW1lID09IGxhbmdfbmFtZV9jKQogICAgewogICAgICBjdXJyZW50X2xhbmdfbmFtZSA9IG5hbWU7CiAgICB9CiAgZWxzZQogICAgZXJyb3IgKCJsYW5ndWFnZSBzdHJpbmcgJTxcIiVFXCIlPiBub3QgcmVjb2duaXplZCIsIG5hbWUpOwp9CiAgCi8qIEdldCBvdXQgb2YgdGhlIGN1cnJlbnQgbGFuZ3VhZ2Ugc2NvcGUuICAqLwoKdm9pZApwb3BfbGFuZ19jb250ZXh0ICh2b2lkKQp7CiAgY3VycmVudF9sYW5nX25hbWUgPSBWQVJSQVlfVE9QX1RSRUUgKGN1cnJlbnRfbGFuZ19iYXNlKTsKICBWQVJSQVlfUE9QIChjdXJyZW50X2xhbmdfYmFzZSk7Cn0KDAovKiBUeXBlIGluc3RhbnRpYXRpb24gcm91dGluZXMuICAqLwoKLyogR2l2ZW4gYW4gT1ZFUkxPQUQgYW5kIGEgVEFSR0VUX1RZUEUsIHJldHVybiB0aGUgZnVuY3Rpb24gdGhhdAogICBtYXRjaGVzIHRoZSBUQVJHRVRfVFlQRS4gIElmIHRoZXJlIGlzIG5vIHNhdGlzZmFjdG9yeSBtYXRjaCwgcmV0dXJuCiAgIGVycm9yX21hcmtfbm9kZSwgYW5kIGlzc3VlIGEgZXJyb3IgJiB3YXJuaW5nIG1lc3NhZ2VzIHVuZGVyIGNvbnRyb2wKICAgb2YgRkxBR1MuICBQZXJtaXQgcG9pbnRlcnMgdG8gbWVtYmVyIGZ1bmN0aW9uIGlmIEZMQUdTIHBlcm1pdHMuICBJZgogICBURU1QTEFURV9PTkxZLCB0aGUgbmFtZSBvZiB0aGUgb3ZlcmxvYWRlZCBmdW5jdGlvbiB3YXMgYQogICB0ZW1wbGF0ZS1pZCwgYW5kIEVYUExJQ0lUX1RBUkdTIGFyZSB0aGUgZXhwbGljaXRseSBwcm92aWRlZAogICB0ZW1wbGF0ZSBhcmd1bWVudHMuICAqLwoKc3RhdGljIHRyZWUKcmVzb2x2ZV9hZGRyZXNzX29mX292ZXJsb2FkZWRfZnVuY3Rpb24gKHRyZWUgdGFyZ2V0X3R5cGUsIAoJCQkJCXRyZWUgb3ZlcmxvYWQsCgkJCQkJdHN1YnN0X2ZsYWdzX3QgZmxhZ3MsCgkJCQkJYm9vbCB0ZW1wbGF0ZV9vbmx5LAoJCQkJCXRyZWUgZXhwbGljaXRfdGFyZ3MpCnsKICAvKiBIZXJlJ3Mgd2hhdCB0aGUgc3RhbmRhcmQgc2F5czoKICAgICAKICAgICAgIFtvdmVyLm92ZXJdCgogICAgICAgSWYgdGhlIG5hbWUgaXMgYSBmdW5jdGlvbiB0ZW1wbGF0ZSwgdGVtcGxhdGUgYXJndW1lbnQgZGVkdWN0aW9uCiAgICAgICBpcyBkb25lLCBhbmQgaWYgdGhlIGFyZ3VtZW50IGRlZHVjdGlvbiBzdWNjZWVkcywgdGhlIGRlZHVjZWQKICAgICAgIGFyZ3VtZW50cyBhcmUgdXNlZCB0byBnZW5lcmF0ZSBhIHNpbmdsZSB0ZW1wbGF0ZSBmdW5jdGlvbiwgd2hpY2gKICAgICAgIGlzIGFkZGVkIHRvIHRoZSBzZXQgb2Ygb3ZlcmxvYWRlZCBmdW5jdGlvbnMgY29uc2lkZXJlZC4KCiAgICAgICBOb24tbWVtYmVyIGZ1bmN0aW9ucyBhbmQgc3RhdGljIG1lbWJlciBmdW5jdGlvbnMgbWF0Y2ggdGFyZ2V0cyBvZgogICAgICAgdHlwZSAicG9pbnRlci10by1mdW5jdGlvbiIgb3IgInJlZmVyZW5jZS10by1mdW5jdGlvbi4iICBOb25zdGF0aWMKICAgICAgIG1lbWJlciBmdW5jdGlvbnMgbWF0Y2ggdGFyZ2V0cyBvZiB0eXBlICJwb2ludGVyLXRvLW1lbWJlcgogICAgICAgZnVuY3Rpb247IiB0aGUgZnVuY3Rpb24gdHlwZSBvZiB0aGUgcG9pbnRlciB0byBtZW1iZXIgaXMgdXNlZCB0bwogICAgICAgc2VsZWN0IHRoZSBtZW1iZXIgZnVuY3Rpb24gZnJvbSB0aGUgc2V0IG9mIG92ZXJsb2FkZWQgbWVtYmVyCiAgICAgICBmdW5jdGlvbnMuICBJZiBhIG5vbnN0YXRpYyBtZW1iZXIgZnVuY3Rpb24gaXMgc2VsZWN0ZWQsIHRoZQogICAgICAgcmVmZXJlbmNlIHRvIHRoZSBvdmVybG9hZGVkIGZ1bmN0aW9uIG5hbWUgaXMgcmVxdWlyZWQgdG8gaGF2ZSB0aGUKICAgICAgIGZvcm0gb2YgYSBwb2ludGVyIHRvIG1lbWJlciBhcyBkZXNjcmliZWQgaW4gNS4zLjEuCgogICAgICAgSWYgbW9yZSB0aGFuIG9uZSBmdW5jdGlvbiBpcyBzZWxlY3RlZCwgYW55IHRlbXBsYXRlIGZ1bmN0aW9ucyBpbgogICAgICAgdGhlIHNldCBhcmUgZWxpbWluYXRlZCBpZiB0aGUgc2V0IGFsc28gY29udGFpbnMgYSBub24tdGVtcGxhdGUKICAgICAgIGZ1bmN0aW9uLCBhbmQgYW55IGdpdmVuIHRlbXBsYXRlIGZ1bmN0aW9uIGlzIGVsaW1pbmF0ZWQgaWYgdGhlCiAgICAgICBzZXQgY29udGFpbnMgYSBzZWNvbmQgdGVtcGxhdGUgZnVuY3Rpb24gdGhhdCBpcyBtb3JlIHNwZWNpYWxpemVkCiAgICAgICB0aGFuIHRoZSBmaXJzdCBhY2NvcmRpbmcgdG8gdGhlIHBhcnRpYWwgb3JkZXJpbmcgcnVsZXMgMTQuNS41LjIuCiAgICAgICBBZnRlciBzdWNoIGVsaW1pbmF0aW9ucywgaWYgYW55LCB0aGVyZSBzaGFsbCByZW1haW4gZXhhY3RseSBvbmUKICAgICAgIHNlbGVjdGVkIGZ1bmN0aW9uLiAgKi8KCiAgaW50IGlzX3B0cm1lbSA9IDA7CiAgaW50IGlzX3JlZmVyZW5jZSA9IDA7CiAgLyogV2Ugc3RvcmUgdGhlIG1hdGNoZXMgaW4gYSBUUkVFX0xJU1Qgcm9vdGVkIGhlcmUuICBUaGUgZnVuY3Rpb25zCiAgICAgYXJlIHRoZSBUUkVFX1BVUlBPU0UsIG5vdCB0aGUgVFJFRV9WQUxVRSwgaW4gdGhpcyBsaXN0LCBmb3IgZWFzeQogICAgIGludGVyb3BlcmFiaWxpdHkgd2l0aCBtb3N0X3NwZWNpYWxpemVkX2luc3RhbnRpYXRpb24uICAqLwogIHRyZWUgbWF0Y2hlcyA9IE5VTExfVFJFRTsKICB0cmVlIGZuOwoKICAvKiBCeSB0aGUgdGltZSB3ZSBnZXQgaGVyZSwgd2Ugc2hvdWxkIGJlIHNlZWluZyBvbmx5IHJlYWwKICAgICBwb2ludGVyLXRvLW1lbWJlciB0eXBlcywgbm90IHRoZSBpbnRlcm5hbCBQT0lOVEVSX1RZUEUgdG8KICAgICBNRVRIT0RfVFlQRSByZXByZXNlbnRhdGlvbi4gICovCiAgZ2NjX2Fzc2VydCAoVFJFRV9DT0RFICh0YXJnZXRfdHlwZSkgIT0gUE9JTlRFUl9UWVBFCgkgICAgICB8fCBUUkVFX0NPREUgKFRSRUVfVFlQRSAodGFyZ2V0X3R5cGUpKSAhPSBNRVRIT0RfVFlQRSk7CgogIGdjY19hc3NlcnQgKGlzX292ZXJsb2FkZWRfZm4gKG92ZXJsb2FkKSk7CiAgCiAgLyogQ2hlY2sgdGhhdCB0aGUgVEFSR0VUX1RZUEUgaXMgcmVhc29uYWJsZS4gICovCiAgaWYgKFRZUEVfUFRSRk5fUCAodGFyZ2V0X3R5cGUpKQogICAgLyogVGhpcyBpcyBPSy4gICovOwogIGVsc2UgaWYgKFRZUEVfUFRSTUVNRlVOQ19QICh0YXJnZXRfdHlwZSkpCiAgICAvKiBUaGlzIGlzIE9LLCB0b28uICAqLwogICAgaXNfcHRybWVtID0gMTsKICBlbHNlIGlmIChUUkVFX0NPREUgKHRhcmdldF90eXBlKSA9PSBGVU5DVElPTl9UWVBFKQogICAgewogICAgICAvKiBUaGlzIGlzIE9LLCB0b28uICBUaGlzIGNvbWVzIGZyb20gYSBjb252ZXJzaW9uIHRvIHJlZmVyZW5jZQoJIHR5cGUuICAqLwogICAgICB0YXJnZXRfdHlwZSA9IGJ1aWxkX3JlZmVyZW5jZV90eXBlICh0YXJnZXRfdHlwZSk7CiAgICAgIGlzX3JlZmVyZW5jZSA9IDE7CiAgICB9CiAgZWxzZSAKICAgIHsKICAgICAgaWYgKGZsYWdzICYgdGZfZXJyb3IpCgllcnJvciAoImNhbm5vdCByZXNvbHZlIG92ZXJsb2FkZWQgZnVuY3Rpb24gJXFEIGJhc2VkIG9uIgogICAgICAgICAgICAgICAiIGNvbnZlcnNpb24gdG8gdHlwZSAlcVQiLCAKICAgICAgICAgICAgICAgREVDTF9OQU1FIChPVkxfRlVOQ1RJT04gKG92ZXJsb2FkKSksIHRhcmdldF90eXBlKTsKICAgICAgcmV0dXJuIGVycm9yX21hcmtfbm9kZTsKICAgIH0KICAKICAvKiBJZiB3ZSBjYW4gZmluZCBhIG5vbi10ZW1wbGF0ZSBmdW5jdGlvbiB0aGF0IG1hdGNoZXMsIHdlIGNhbiBqdXN0CiAgICAgdXNlIGl0LiAgVGhlcmUncyBubyBwb2ludCBpbiBnZW5lcmF0aW5nIHRlbXBsYXRlIGluc3RhbnRpYXRpb25zCiAgICAgaWYgd2UncmUganVzdCBnb2luZyB0byB0aHJvdyB0aGVtIG91dCBhbnlob3cuICBCdXQsIG9mIGNvdXJzZSwgd2UKICAgICBjYW4gb25seSBkbyB0aGlzIHdoZW4gd2UgZG9uJ3QgKm5lZWQqIGEgdGVtcGxhdGUgZnVuY3Rpb24uICAqLwogIGlmICghdGVtcGxhdGVfb25seSkKICAgIHsKICAgICAgdHJlZSBmbnM7CgogICAgICBmb3IgKGZucyA9IG92ZXJsb2FkOyBmbnM7IGZucyA9IE9WTF9ORVhUIChmbnMpKQoJewoJICB0cmVlIGZuID0gT1ZMX0NVUlJFTlQgKGZucyk7CgkgIHRyZWUgZm50eXBlOwoKCSAgaWYgKFRSRUVfQ09ERSAoZm4pID09IFRFTVBMQVRFX0RFQ0wpCgkgICAgLyogV2UncmUgbm90IGxvb2tpbmcgZm9yIHRlbXBsYXRlcyBqdXN0IHlldC4gICovCgkgICAgY29udGludWU7CgoJICBpZiAoKFRSRUVfQ09ERSAoVFJFRV9UWVBFIChmbikpID09IE1FVEhPRF9UWVBFKQoJICAgICAgIT0gaXNfcHRybWVtKQoJICAgIC8qIFdlJ3JlIGxvb2tpbmcgZm9yIGEgbm9uLXN0YXRpYyBtZW1iZXIsIGFuZCB0aGlzIGlzbid0CgkgICAgICAgb25lLCBvciB2aWNlIHZlcnNhLiAgKi8KCSAgICBjb250aW51ZTsKCgkgIC8qIElnbm9yZSBhbnRpY2lwYXRlZCBkZWNscyBvZiB1bmRlY2xhcmVkIGJ1aWx0aW5zLiAgKi8KCSAgaWYgKERFQ0xfQU5USUNJUEFURUQgKGZuKSkKCSAgICBjb250aW51ZTsKCgkgIC8qIFNlZSBpZiB0aGVyZSdzIGEgbWF0Y2guICAqLwoJICBmbnR5cGUgPSBUUkVFX1RZUEUgKGZuKTsKCSAgaWYgKGlzX3B0cm1lbSkKCSAgICBmbnR5cGUgPSBidWlsZF9wdHJtZW1mdW5jX3R5cGUgKGJ1aWxkX3BvaW50ZXJfdHlwZSAoZm50eXBlKSk7CgkgIGVsc2UgaWYgKCFpc19yZWZlcmVuY2UpCgkgICAgZm50eXBlID0gYnVpbGRfcG9pbnRlcl90eXBlIChmbnR5cGUpOwoKCSAgLyogQVBQTEUgTE9DQUwgcmFkYXIgNDE4NzkxNiAqLwoJICBpZiAoY2FuX2NvbnZlcnRfYXJnICh0YXJnZXRfdHlwZSwgZm50eXBlLCBmbiwgTE9PS1VQX05PUk1BTCkpCgkgICAgbWF0Y2hlcyA9IHRyZWVfY29ucyAoZm4sIE5VTExfVFJFRSwgbWF0Y2hlcyk7Cgl9CiAgICB9CgogIC8qIE5vdywgaWYgd2UndmUgYWxyZWFkeSBnb3QgYSBtYXRjaCAob3IgbWF0Y2hlcyksIHRoZXJlJ3Mgbm8gbmVlZAogICAgIHRvIHByb2NlZWQgdG8gdGhlIHRlbXBsYXRlIGZ1bmN0aW9ucy4gIEJ1dCwgaWYgd2UgZG9uJ3QgaGF2ZSBhCiAgICAgbWF0Y2ggd2UgbmVlZCB0byBsb29rIGF0IHRoZW0sIHRvby4gICovCiAgaWYgKCFtYXRjaGVzKSAKICAgIHsKICAgICAgdHJlZSB0YXJnZXRfZm5fdHlwZTsKICAgICAgdHJlZSB0YXJnZXRfYXJnX3R5cGVzOwogICAgICB0cmVlIHRhcmdldF9yZXRfdHlwZTsKICAgICAgdHJlZSBmbnM7CgogICAgICBpZiAoaXNfcHRybWVtKQoJdGFyZ2V0X2ZuX3R5cGUKCSAgPSBUUkVFX1RZUEUgKFRZUEVfUFRSTUVNRlVOQ19GTl9UWVBFICh0YXJnZXRfdHlwZSkpOwogICAgICBlbHNlCgl0YXJnZXRfZm5fdHlwZSA9IFRSRUVfVFlQRSAodGFyZ2V0X3R5cGUpOwogICAgICB0YXJnZXRfYXJnX3R5cGVzID0gVFlQRV9BUkdfVFlQRVMgKHRhcmdldF9mbl90eXBlKTsKICAgICAgdGFyZ2V0X3JldF90eXBlID0gVFJFRV9UWVBFICh0YXJnZXRfZm5fdHlwZSk7CgogICAgICAvKiBOZXZlciBkbyB1bmlmaWNhdGlvbiBvbiB0aGUgJ3RoaXMnIHBhcmFtZXRlci4gICovCiAgICAgIGlmIChUUkVFX0NPREUgKHRhcmdldF9mbl90eXBlKSA9PSBNRVRIT0RfVFlQRSkKCXRhcmdldF9hcmdfdHlwZXMgPSBUUkVFX0NIQUlOICh0YXJnZXRfYXJnX3R5cGVzKTsKCSAgCiAgICAgIGZvciAoZm5zID0gb3ZlcmxvYWQ7IGZuczsgZm5zID0gT1ZMX05FWFQgKGZucykpCgl7CgkgIHRyZWUgZm4gPSBPVkxfQ1VSUkVOVCAoZm5zKTsKCSAgdHJlZSBpbnN0YW50aWF0aW9uOwoJICB0cmVlIGluc3RhbnRpYXRpb25fdHlwZTsKCSAgdHJlZSB0YXJnczsKCgkgIGlmIChUUkVFX0NPREUgKGZuKSAhPSBURU1QTEFURV9ERUNMKQoJICAgIC8qIFdlJ3JlIG9ubHkgbG9va2luZyBmb3IgdGVtcGxhdGVzLiAgKi8KCSAgICBjb250aW51ZTsKCgkgIGlmICgoVFJFRV9DT0RFIChUUkVFX1RZUEUgKGZuKSkgPT0gTUVUSE9EX1RZUEUpCgkgICAgICAhPSBpc19wdHJtZW0pCgkgICAgLyogV2UncmUgbm90IGxvb2tpbmcgZm9yIGEgbm9uLXN0YXRpYyBtZW1iZXIsIGFuZCB0aGlzIGlzCgkgICAgICAgb25lLCBvciB2aWNlIHZlcnNhLiAgKi8KCSAgICBjb250aW51ZTsKCgkgIC8qIFRyeSB0byBkbyBhcmd1bWVudCBkZWR1Y3Rpb24uICAqLwoJICB0YXJncyA9IG1ha2VfdHJlZV92ZWMgKERFQ0xfTlRQQVJNUyAoZm4pKTsKCSAgaWYgKGZuX3R5cGVfdW5pZmljYXRpb24gKGZuLCBleHBsaWNpdF90YXJncywgdGFyZ3MsCgkJCQkgICB0YXJnZXRfYXJnX3R5cGVzLCB0YXJnZXRfcmV0X3R5cGUsCgkJCQkgICAvKiBBUFBMRSBMT0NBTCByYWRhciA0MTg3OTE2ICovCgkJCQkgICBERURVQ0VfRVhBQ1QsIC0xLCBMT09LVVBfTk9STUFMKSAhPSAwKQoJICAgIC8qIEFyZ3VtZW50IGRlZHVjdGlvbiBmYWlsZWQuICAqLwoJICAgIGNvbnRpbnVlOwoKCSAgLyogSW5zdGFudGlhdGUgdGhlIHRlbXBsYXRlLiAgKi8KCSAgaW5zdGFudGlhdGlvbiA9IGluc3RhbnRpYXRlX3RlbXBsYXRlIChmbiwgdGFyZ3MsIGZsYWdzKTsKCSAgaWYgKGluc3RhbnRpYXRpb24gPT0gZXJyb3JfbWFya19ub2RlKQoJICAgIC8qIEluc3RhbnRpYXRpb24gZmFpbGVkLiAgKi8KCSAgICBjb250aW51ZTsKCgkgIC8qIFNlZSBpZiB0aGVyZSdzIGEgbWF0Y2guICAqLwoJICBpbnN0YW50aWF0aW9uX3R5cGUgPSBUUkVFX1RZUEUgKGluc3RhbnRpYXRpb24pOwoJICBpZiAoaXNfcHRybWVtKQoJICAgIGluc3RhbnRpYXRpb25fdHlwZSA9IAoJICAgICAgYnVpbGRfcHRybWVtZnVuY190eXBlIChidWlsZF9wb2ludGVyX3R5cGUgKGluc3RhbnRpYXRpb25fdHlwZSkpOwoJICBlbHNlIGlmICghaXNfcmVmZXJlbmNlKQoJICAgIGluc3RhbnRpYXRpb25fdHlwZSA9IGJ1aWxkX3BvaW50ZXJfdHlwZSAoaW5zdGFudGlhdGlvbl90eXBlKTsKCSAgLyogQVBQTEUgTE9DQUwgcmFkYXIgNDE4NzkxNiAqLwoJICBpZiAoY2FuX2NvbnZlcnRfYXJnICh0YXJnZXRfdHlwZSwgaW5zdGFudGlhdGlvbl90eXBlLCBpbnN0YW50aWF0aW9uLCBMT09LVVBfTk9STUFMKSkKCSAgICBtYXRjaGVzID0gdHJlZV9jb25zIChpbnN0YW50aWF0aW9uLCBmbiwgbWF0Y2hlcyk7Cgl9CgogICAgICAvKiBOb3csIHJlbW92ZSBhbGwgYnV0IHRoZSBtb3N0IHNwZWNpYWxpemVkIG9mIHRoZSBtYXRjaGVzLiAgKi8KICAgICAgaWYgKG1hdGNoZXMpCgl7CgkgIHRyZWUgbWF0Y2ggPSBtb3N0X3NwZWNpYWxpemVkX2luc3RhbnRpYXRpb24gKG1hdGNoZXMpOwoKCSAgaWYgKG1hdGNoICE9IGVycm9yX21hcmtfbm9kZSkKCSAgICBtYXRjaGVzID0gdHJlZV9jb25zIChtYXRjaCwgTlVMTF9UUkVFLCBOVUxMX1RSRUUpOwoJfQogICAgfQoKICAvKiBOb3cgd2Ugc2hvdWxkIGhhdmUgZXhhY3RseSBvbmUgZnVuY3Rpb24gaW4gTUFUQ0hFUy4gICovCiAgaWYgKG1hdGNoZXMgPT0gTlVMTF9UUkVFKQogICAgewogICAgICAvKiBUaGVyZSB3ZXJlICpubyogbWF0Y2hlcy4gICovCiAgICAgIGlmIChmbGFncyAmIHRmX2Vycm9yKQoJewogCSAgZXJyb3IgKCJubyBtYXRjaGVzIGNvbnZlcnRpbmcgZnVuY3Rpb24gJXFEIHRvIHR5cGUgJXEjVCIsIAogICAgICAgICAgICAgICAgIERFQ0xfTkFNRSAoT1ZMX0ZVTkNUSU9OIChvdmVybG9hZCkpLAogICAgICAgICAgICAgICAgIHRhcmdldF90eXBlKTsKCgkgIC8qIHByaW50X2NhbmRpZGF0ZXMgZXhwZWN0cyBhIGNoYWluIHdpdGggdGhlIGZ1bmN0aW9ucyBpbgogICAgICAgICAgICAgVFJFRV9WQUxVRSBzbG90cywgc28gd2UgY29ucyBvbmUgdXAgaGVyZSAod2UncmUgbG9zaW5nIGFueXdheSwKICAgICAgICAgICAgIHNvIHdoeSBiZSBjbGV2ZXI/KS4gICovCiAgICAgICAgICBmb3IgKDsgb3ZlcmxvYWQ7IG92ZXJsb2FkID0gT1ZMX05FWFQgKG92ZXJsb2FkKSkKICAgICAgICAgICAgbWF0Y2hlcyA9IHRyZWVfY29ucyAoTlVMTF9UUkVFLCBPVkxfQ1VSUkVOVCAob3ZlcmxvYWQpLAoJCQkJIG1hdGNoZXMpOwogICAgICAgICAgCgkgIHByaW50X2NhbmRpZGF0ZXMgKG1hdGNoZXMpOwoJfQogICAgICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwogICAgfQogIGVsc2UgaWYgKFRSRUVfQ0hBSU4gKG1hdGNoZXMpKQogICAgewogICAgICAvKiBUaGVyZSB3ZXJlIHRvbyBtYW55IG1hdGNoZXMuICAqLwoKICAgICAgaWYgKGZsYWdzICYgdGZfZXJyb3IpCgl7CgkgIHRyZWUgbWF0Y2g7CgogCSAgZXJyb3IgKCJjb252ZXJ0aW5nIG92ZXJsb2FkZWQgZnVuY3Rpb24gJXFEIHRvIHR5cGUgJXEjVCBpcyBhbWJpZ3VvdXMiLCAKCQkgICAgREVDTF9OQU1FIChPVkxfRlVOQ1RJT04gKG92ZXJsb2FkKSksCgkJICAgIHRhcmdldF90eXBlKTsKCgkgIC8qIFNpbmNlIHByaW50X2NhbmRpZGF0ZXMgZXhwZWN0cyB0aGUgZnVuY3Rpb25zIGluIHRoZQoJICAgICBUUkVFX1ZBTFVFIHNsb3QsIHdlIGZsaXAgdGhlbSBoZXJlLiAgKi8KCSAgZm9yIChtYXRjaCA9IG1hdGNoZXM7IG1hdGNoOyBtYXRjaCA9IFRSRUVfQ0hBSU4gKG1hdGNoKSkKCSAgICBUUkVFX1ZBTFVFIChtYXRjaCkgPSBUUkVFX1BVUlBPU0UgKG1hdGNoKTsKCgkgIHByaW50X2NhbmRpZGF0ZXMgKG1hdGNoZXMpOwoJfQogICAgICAKICAgICAgcmV0dXJuIGVycm9yX21hcmtfbm9kZTsKICAgIH0KCiAgLyogR29vZCwgZXhhY3RseSBvbmUgbWF0Y2guICBOb3csIGNvbnZlcnQgaXQgdG8gdGhlIGNvcnJlY3QgdHlwZS4gICovCiAgZm4gPSBUUkVFX1BVUlBPU0UgKG1hdGNoZXMpOwoKICBpZiAoREVDTF9OT05TVEFUSUNfTUVNQkVSX0ZVTkNUSU9OX1AgKGZuKQogICAgICAmJiAhKGZsYWdzICYgdGZfcHRybWVtX29rKSAmJiAhZmxhZ19tc19leHRlbnNpb25zKQogICAgewogICAgICBzdGF0aWMgaW50IGV4cGxhaW5lZDsKICAgICAgCiAgICAgIGlmICghKGZsYWdzICYgdGZfZXJyb3IpKQogICAgICAgIHJldHVybiBlcnJvcl9tYXJrX25vZGU7CgogICAgICBwZWR3YXJuICgiYXNzdW1pbmcgcG9pbnRlciB0byBtZW1iZXIgJXFEIiwgZm4pOwogICAgICBpZiAoIWV4cGxhaW5lZCkKICAgICAgICB7CiAgICAgICAgICBwZWR3YXJuICgiKGEgcG9pbnRlciB0byBtZW1iZXIgY2FuIG9ubHkgYmUgZm9ybWVkIHdpdGggJTwmJUUlPikiLCBmbik7CiAgICAgICAgICBleHBsYWluZWQgPSAxOwogICAgICAgIH0KICAgIH0KCiAgLyogSWYgd2UncmUgZG9pbmcgb3ZlcmxvYWQgcmVzb2x1dGlvbiBwdXJlbHkgZm9yIHRoZSBwdXJwb3NlIG9mCiAgICAgZGV0ZXJtaW5pbmcgY29udmVyc2lvbiBzZXF1ZW5jZXMsIHdlIHNob3VsZCBub3QgY29uc2lkZXIgdGhlCiAgICAgZnVuY3Rpb24gdXNlZC4gIElmIHRoaXMgY29udmVyc2lvbiBzZXF1ZW5jZSBpcyBzZWxlY3RlZCwgdGhlCiAgICAgZnVuY3Rpb24gd2lsbCBiZSBtYXJrZWQgYXMgdXNlZCBhdCB0aGlzIHBvaW50LiAgKi8KICBpZiAoIShmbGFncyAmIHRmX2NvbnYpKQogICAgbWFya191c2VkIChmbik7CgogIGlmIChUWVBFX1BUUkZOX1AgKHRhcmdldF90eXBlKSB8fCBUWVBFX1BUUk1FTUZVTkNfUCAodGFyZ2V0X3R5cGUpKQogICAgcmV0dXJuIGJ1aWxkX3VuYXJ5X29wIChBRERSX0VYUFIsIGZuLCAwKTsKICBlbHNlCiAgICB7CiAgICAgIC8qIFRoZSB0YXJnZXQgbXVzdCBiZSBhIFJFRkVSRU5DRV9UWVBFLiAgQWJvdmUsIGJ1aWxkX3VuYXJ5X29wCgkgd2lsbCBtYXJrIHRoZSBmdW5jdGlvbiBhcyBhZGRyZXNzZWQsIGJ1dCBoZXJlIHdlIG11c3QgZG8gaXQKCSBleHBsaWNpdGx5LiAgKi8KICAgICAgY3h4X21hcmtfYWRkcmVzc2FibGUgKGZuKTsKCiAgICAgIHJldHVybiBmbjsKICAgIH0KfQoKLyogVGhpcyBmdW5jdGlvbiB3aWxsIGluc3RhbnRpYXRlIHRoZSB0eXBlIG9mIHRoZSBleHByZXNzaW9uIGdpdmVuIGluCiAgIFJIUyB0byBtYXRjaCB0aGUgdHlwZSBvZiBMSFNUWVBFLiAgSWYgZXJyb3JzIGV4aXN0LCB0aGVuIHJldHVybgogICBlcnJvcl9tYXJrX25vZGUuIEZMQUdTIGlzIGEgYml0IG1hc2suICBJZiBURl9FUlJPUiBpcyBzZXQsIHRoZW4KICAgd2UgY29tcGxhaW4gb24gZXJyb3JzLiAgSWYgd2UgYXJlIG5vdCBjb21wbGFpbmluZywgbmV2ZXIgbW9kaWZ5IHJocywKICAgYXMgb3ZlcmxvYWQgcmVzb2x1dGlvbiB3YW50cyB0byB0cnkgbWFueSBwb3NzaWJsZSBpbnN0YW50aWF0aW9ucywgaW4KICAgdGhlIGhvcGUgdGhhdCBhdCBsZWFzdCBvbmUgd2lsbCB3b3JrLgogICAKICAgRm9yIG5vbi1yZWN1cnNpdmUgY2FsbHMsIExIU1RZUEUgc2hvdWxkIGJlIGEgZnVuY3Rpb24sIHBvaW50ZXIgdG8KICAgZnVuY3Rpb24sIG9yIGEgcG9pbnRlciB0byBtZW1iZXIgZnVuY3Rpb24uICAqLwoKdHJlZQppbnN0YW50aWF0ZV90eXBlICh0cmVlIGxoc3R5cGUsIHRyZWUgcmhzLCB0c3Vic3RfZmxhZ3NfdCBmbGFncykKewogIHRzdWJzdF9mbGFnc190IGZsYWdzX2luID0gZmxhZ3M7CiAgCiAgZmxhZ3MgJj0gfnRmX3B0cm1lbV9vazsKICAKICBpZiAoVFJFRV9DT0RFIChsaHN0eXBlKSA9PSBVTktOT1dOX1RZUEUpCiAgICB7CiAgICAgIGlmIChmbGFncyAmIHRmX2Vycm9yKQoJZXJyb3IgKCJub3QgZW5vdWdoIHR5cGUgaW5mb3JtYXRpb24iKTsKICAgICAgcmV0dXJuIGVycm9yX21hcmtfbm9kZTsKICAgIH0KCiAgaWYgKFRSRUVfVFlQRSAocmhzKSAhPSBOVUxMX1RSRUUgJiYgISAodHlwZV91bmtub3duX3AgKHJocykpKQogICAgewogICAgICBpZiAoc2FtZV90eXBlX3AgKGxoc3R5cGUsIFRSRUVfVFlQRSAocmhzKSkpCglyZXR1cm4gcmhzOwogICAgICBpZiAoZmxhZ19tc19leHRlbnNpb25zIAoJICAmJiBUWVBFX1BUUk1FTUZVTkNfUCAobGhzdHlwZSkKCSAgJiYgIVRZUEVfUFRSTUVNRlVOQ19QIChUUkVFX1RZUEUgKHJocykpKQoJLyogTWljcm9zb2Z0IGFsbG93cyBgQTo6ZicgdG8gYmUgcmVzb2x2ZWQgdG8gYQoJICAgcG9pbnRlci10by1tZW1iZXIuICAqLwoJOwogICAgICBlbHNlCgl7CgkgIGlmIChmbGFncyAmIHRmX2Vycm9yKQoJICAgIGVycm9yICgiYXJndW1lbnQgb2YgdHlwZSAlcVQgZG9lcyBub3QgbWF0Y2ggJXFUIiwKCQkgICBUUkVFX1RZUEUgKHJocyksIGxoc3R5cGUpOwoJICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwoJfQogICAgfQoKICBpZiAoVFJFRV9DT0RFIChyaHMpID09IEJBU0VMSU5LKQogICAgcmhzID0gQkFTRUxJTktfRlVOQ1RJT05TIChyaHMpOwoKICAvKiBJZiB3ZSBhcmUgaW4gYSB0ZW1wbGF0ZSwgYW5kIGhhdmUgYSBOT05fREVQRU5ERU5UX0VYUFIsIHdlIGNhbm5vdAogICAgIGRlZHVjZSBhbnkgdHlwZSBpbmZvcm1hdGlvbi4gICovCiAgaWYgKFRSRUVfQ09ERSAocmhzKSA9PSBOT05fREVQRU5ERU5UX0VYUFIpCiAgICB7CiAgICAgIGlmIChmbGFncyAmIHRmX2Vycm9yKQoJZXJyb3IgKCJub3QgZW5vdWdoIHR5cGUgaW5mb3JtYXRpb24iKTsKICAgICAgcmV0dXJuIGVycm9yX21hcmtfbm9kZTsKICAgIH0KCiAgLyogV2UgZG9uJ3Qgb3ZlcndyaXRlIHJocyBpZiBpdCBpcyBhbiBvdmVybG9hZGVkIGZ1bmN0aW9uLgogICAgIENvcHlpbmcgaXQgd291bGQgZGVzdHJveSB0aGUgdHJlZSBsaW5rLiAgKi8KICBpZiAoVFJFRV9DT0RFIChyaHMpICE9IE9WRVJMT0FEKQogICAgcmhzID0gY29weV9ub2RlIChyaHMpOwoKICAvKiBUaGlzIHNob3VsZCByZWFsbHkgb25seSBiZSB1c2VkIHdoZW4gYXR0ZW1wdGluZyB0byBkaXN0aW5ndWlzaAogICAgIHdoYXQgc29ydCBvZiBhIHBvaW50ZXIgdG8gZnVuY3Rpb24gd2UgaGF2ZS4gIEZvciBub3csIGFueQogICAgIGFyaXRobWV0aWMgb3BlcmF0aW9uIHdoaWNoIGlzIG5vdCBzdXBwb3J0ZWQgb24gcG9pbnRlcnMKICAgICBpcyByZWplY3RlZCBhcyBhbiBlcnJvci4gICovCgogIHN3aXRjaCAoVFJFRV9DT0RFIChyaHMpKQogICAgewogICAgY2FzZSBUWVBFX0VYUFI6CiAgICBjYXNlIENPTlZFUlRfRVhQUjoKICAgIGNhc2UgU0FWRV9FWFBSOgogICAgY2FzZSBDT05TVFJVQ1RPUjoKICAgICAgZ2NjX3VucmVhY2hhYmxlICgpOwoKICAgIGNhc2UgSU5ESVJFQ1RfUkVGOgogICAgY2FzZSBBUlJBWV9SRUY6CiAgICAgIHsKCXRyZWUgbmV3X3JoczsKCgluZXdfcmhzID0gaW5zdGFudGlhdGVfdHlwZSAoYnVpbGRfcG9pbnRlcl90eXBlIChsaHN0eXBlKSwKCQkJCSAgICBUUkVFX09QRVJBTkQgKHJocywgMCksIGZsYWdzKTsKCWlmIChuZXdfcmhzID09IGVycm9yX21hcmtfbm9kZSkKCSAgcmV0dXJuIGVycm9yX21hcmtfbm9kZTsKCglUUkVFX1RZUEUgKHJocykgPSBsaHN0eXBlOwoJVFJFRV9PUEVSQU5EIChyaHMsIDApID0gbmV3X3JoczsKCXJldHVybiByaHM7CiAgICAgIH0KCiAgICBjYXNlIE5PUF9FWFBSOgogICAgICByaHMgPSBjb3B5X25vZGUgKFRSRUVfT1BFUkFORCAocmhzLCAwKSk7CiAgICAgIFRSRUVfVFlQRSAocmhzKSA9IHVua25vd25fdHlwZV9ub2RlOwogICAgICByZXR1cm4gaW5zdGFudGlhdGVfdHlwZSAobGhzdHlwZSwgcmhzLCBmbGFncyk7CgogICAgY2FzZSBDT01QT05FTlRfUkVGOgogICAgICB7Cgl0cmVlIG1lbWJlciA9IFRSRUVfT1BFUkFORCAocmhzLCAxKTsKCgltZW1iZXIgPSBpbnN0YW50aWF0ZV90eXBlIChsaHN0eXBlLCBtZW1iZXIsIGZsYWdzKTsKCWlmIChtZW1iZXIgIT0gZXJyb3JfbWFya19ub2RlCgkgICAgJiYgVFJFRV9TSURFX0VGRkVDVFMgKFRSRUVfT1BFUkFORCAocmhzLCAwKSkpCgkgIC8qIERvIG5vdCBsb3NlIG9iamVjdCdzIHNpZGUgZWZmZWN0cy4gICovCgkgIHJldHVybiBidWlsZDIgKENPTVBPVU5EX0VYUFIsIFRSRUVfVFlQRSAobWVtYmVyKSwKCQkJIFRSRUVfT1BFUkFORCAocmhzLCAwKSwgbWVtYmVyKTsKCXJldHVybiBtZW1iZXI7CiAgICAgIH0KCiAgICBjYXNlIE9GRlNFVF9SRUY6CiAgICAgIHJocyA9IFRSRUVfT1BFUkFORCAocmhzLCAxKTsKICAgICAgaWYgKEJBU0VMSU5LX1AgKHJocykpCglyZXR1cm4gaW5zdGFudGlhdGVfdHlwZSAobGhzdHlwZSwgQkFTRUxJTktfRlVOQ1RJT05TIChyaHMpLCBmbGFnc19pbik7CgogICAgICAvKiBUaGlzIGNhbiBoYXBwZW4gaWYgd2UgYXJlIGZvcm1pbmcgYSBwb2ludGVyLXRvLW1lbWJlciBmb3IgYQoJIG1lbWJlciB0ZW1wbGF0ZS4gICovCiAgICAgIGdjY19hc3NlcnQgKFRSRUVfQ09ERSAocmhzKSA9PSBURU1QTEFURV9JRF9FWFBSKTsKCiAgICAgIC8qIEZhbGwgdGhyb3VnaC4gICovCgogICAgY2FzZSBURU1QTEFURV9JRF9FWFBSOgogICAgICB7Cgl0cmVlIGZucyA9IFRSRUVfT1BFUkFORCAocmhzLCAwKTsKCXRyZWUgYXJncyA9IFRSRUVfT1BFUkFORCAocmhzLCAxKTsKCglyZXR1cm4KCSAgcmVzb2x2ZV9hZGRyZXNzX29mX292ZXJsb2FkZWRfZnVuY3Rpb24gKGxoc3R5cGUsIGZucywgZmxhZ3NfaW4sCgkJCQkJCSAgLyp0ZW1wbGF0ZV9vbmx5PSovdHJ1ZSwKCQkJCQkJICBhcmdzKTsKICAgICAgfQoKICAgIGNhc2UgT1ZFUkxPQUQ6CiAgICBjYXNlIEZVTkNUSU9OX0RFQ0w6CiAgICAgIHJldHVybiAKCXJlc29sdmVfYWRkcmVzc19vZl9vdmVybG9hZGVkX2Z1bmN0aW9uIChsaHN0eXBlLCByaHMsIGZsYWdzX2luLAoJCQkJCQkvKnRlbXBsYXRlX29ubHk9Ki9mYWxzZSwKCQkJCQkJLypleHBsaWNpdF90YXJncz0qL05VTExfVFJFRSk7CgogICAgY2FzZSBDQUxMX0VYUFI6CiAgICAgIC8qIFRoaXMgaXMgdG9vIGhhcmQgZm9yIG5vdy4gICovCiAgICAgIGdjY191bnJlYWNoYWJsZSAoKTsKCiAgICBjYXNlIFBMVVNfRVhQUjoKICAgIGNhc2UgTUlOVVNfRVhQUjoKICAgIGNhc2UgQ09NUE9VTkRfRVhQUjoKICAgICAgVFJFRV9PUEVSQU5EIChyaHMsIDApCgk9IGluc3RhbnRpYXRlX3R5cGUgKGxoc3R5cGUsIFRSRUVfT1BFUkFORCAocmhzLCAwKSwgZmxhZ3MpOwogICAgICBpZiAoVFJFRV9PUEVSQU5EIChyaHMsIDApID09IGVycm9yX21hcmtfbm9kZSkKCXJldHVybiBlcnJvcl9tYXJrX25vZGU7CiAgICAgIFRSRUVfT1BFUkFORCAocmhzLCAxKQoJPSBpbnN0YW50aWF0ZV90eXBlIChsaHN0eXBlLCBUUkVFX09QRVJBTkQgKHJocywgMSksIGZsYWdzKTsKICAgICAgaWYgKFRSRUVfT1BFUkFORCAocmhzLCAxKSA9PSBlcnJvcl9tYXJrX25vZGUpCglyZXR1cm4gZXJyb3JfbWFya19ub2RlOwoKICAgICAgVFJFRV9UWVBFIChyaHMpID0gbGhzdHlwZTsKICAgICAgcmV0dXJuIHJoczsKCiAgICBjYXNlIE1VTFRfRVhQUjoKICAgIGNhc2UgVFJVTkNfRElWX0VYUFI6CiAgICBjYXNlIEZMT09SX0RJVl9FWFBSOgogICAgY2FzZSBDRUlMX0RJVl9FWFBSOgogICAgY2FzZSBST1VORF9ESVZfRVhQUjoKICAgIGNhc2UgUkRJVl9FWFBSOgogICAgY2FzZSBUUlVOQ19NT0RfRVhQUjoKICAgIGNhc2UgRkxPT1JfTU9EX0VYUFI6CiAgICBjYXNlIENFSUxfTU9EX0VYUFI6CiAgICBjYXNlIFJPVU5EX01PRF9FWFBSOgogICAgY2FzZSBGSVhfUk9VTkRfRVhQUjoKICAgIGNhc2UgRklYX0ZMT09SX0VYUFI6CiAgICBjYXNlIEZJWF9DRUlMX0VYUFI6CiAgICBjYXNlIEZJWF9UUlVOQ19FWFBSOgogICAgY2FzZSBGTE9BVF9FWFBSOgogICAgY2FzZSBORUdBVEVfRVhQUjoKICAgIGNhc2UgQUJTX0VYUFI6CiAgICBjYXNlIE1BWF9FWFBSOgogICAgY2FzZSBNSU5fRVhQUjoKCiAgICBjYXNlIEJJVF9BTkRfRVhQUjoKICAgIGNhc2UgQklUX0lPUl9FWFBSOgogICAgY2FzZSBCSVRfWE9SX0VYUFI6CiAgICBjYXNlIExTSElGVF9FWFBSOgogICAgY2FzZSBSU0hJRlRfRVhQUjoKICAgIGNhc2UgTFJPVEFURV9FWFBSOgogICAgY2FzZSBSUk9UQVRFX0VYUFI6CgogICAgY2FzZSBQUkVJTkNSRU1FTlRfRVhQUjoKICAgIGNhc2UgUFJFREVDUkVNRU5UX0VYUFI6CiAgICBjYXNlIFBPU1RJTkNSRU1FTlRfRVhQUjoKICAgIGNhc2UgUE9TVERFQ1JFTUVOVF9FWFBSOgogICAgICBpZiAoZmxhZ3MgJiB0Zl9lcnJvcikKCWVycm9yICgiaW52YWxpZCBvcGVyYXRpb24gb24gdW5pbnN0YW50aWF0ZWQgdHlwZSIpOwogICAgICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwoKICAgIGNhc2UgVFJVVEhfQU5EX0VYUFI6CiAgICBjYXNlIFRSVVRIX09SX0VYUFI6CiAgICBjYXNlIFRSVVRIX1hPUl9FWFBSOgogICAgY2FzZSBMVF9FWFBSOgogICAgY2FzZSBMRV9FWFBSOgogICAgY2FzZSBHVF9FWFBSOgogICAgY2FzZSBHRV9FWFBSOgogICAgY2FzZSBFUV9FWFBSOgogICAgY2FzZSBORV9FWFBSOgogICAgY2FzZSBUUlVUSF9BTkRJRl9FWFBSOgogICAgY2FzZSBUUlVUSF9PUklGX0VYUFI6CiAgICBjYXNlIFRSVVRIX05PVF9FWFBSOgogICAgICBpZiAoZmxhZ3MgJiB0Zl9lcnJvcikKCWVycm9yICgibm90IGVub3VnaCB0eXBlIGluZm9ybWF0aW9uIik7CiAgICAgIHJldHVybiBlcnJvcl9tYXJrX25vZGU7CgogICAgY2FzZSBDT05EX0VYUFI6CiAgICAgIGlmICh0eXBlX3Vua25vd25fcCAoVFJFRV9PUEVSQU5EIChyaHMsIDApKSkKCXsKCSAgaWYgKGZsYWdzICYgdGZfZXJyb3IpCgkgICAgZXJyb3IgKCJub3QgZW5vdWdoIHR5cGUgaW5mb3JtYXRpb24iKTsKCSAgcmV0dXJuIGVycm9yX21hcmtfbm9kZTsKCX0KICAgICAgVFJFRV9PUEVSQU5EIChyaHMsIDEpCgk9IGluc3RhbnRpYXRlX3R5cGUgKGxoc3R5cGUsIFRSRUVfT1BFUkFORCAocmhzLCAxKSwgZmxhZ3MpOwogICAgICBpZiAoVFJFRV9PUEVSQU5EIChyaHMsIDEpID09IGVycm9yX21hcmtfbm9kZSkKCXJldHVybiBlcnJvcl9tYXJrX25vZGU7CiAgICAgIFRSRUVfT1BFUkFORCAocmhzLCAyKQoJPSBpbnN0YW50aWF0ZV90eXBlIChsaHN0eXBlLCBUUkVFX09QRVJBTkQgKHJocywgMiksIGZsYWdzKTsKICAgICAgaWYgKFRSRUVfT1BFUkFORCAocmhzLCAyKSA9PSBlcnJvcl9tYXJrX25vZGUpCglyZXR1cm4gZXJyb3JfbWFya19ub2RlOwoKICAgICAgVFJFRV9UWVBFIChyaHMpID0gbGhzdHlwZTsKICAgICAgcmV0dXJuIHJoczsKCiAgICBjYXNlIE1PRElGWV9FWFBSOgogICAgICBUUkVFX09QRVJBTkQgKHJocywgMSkKCT0gaW5zdGFudGlhdGVfdHlwZSAobGhzdHlwZSwgVFJFRV9PUEVSQU5EIChyaHMsIDEpLCBmbGFncyk7CiAgICAgIGlmIChUUkVFX09QRVJBTkQgKHJocywgMSkgPT0gZXJyb3JfbWFya19ub2RlKQoJcmV0dXJuIGVycm9yX21hcmtfbm9kZTsKCiAgICAgIFRSRUVfVFlQRSAocmhzKSA9IGxoc3R5cGU7CiAgICAgIHJldHVybiByaHM7CiAgICAgIAogICAgY2FzZSBBRERSX0VYUFI6CiAgICB7CiAgICAgIGlmIChQVFJNRU1fT0tfUCAocmhzKSkKICAgICAgICBmbGFncyB8PSB0Zl9wdHJtZW1fb2s7CiAgICAgIAogICAgICByZXR1cm4gaW5zdGFudGlhdGVfdHlwZSAobGhzdHlwZSwgVFJFRV9PUEVSQU5EIChyaHMsIDApLCBmbGFncyk7CiAgICB9CgogICAgY2FzZSBFUlJPUl9NQVJLOgogICAgICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwoKICAgIGRlZmF1bHQ6CiAgICAgIGdjY191bnJlYWNoYWJsZSAoKTsKICAgIH0KICByZXR1cm4gZXJyb3JfbWFya19ub2RlOwp9CgwKLyogUmV0dXJuIHRoZSBuYW1lIG9mIHRoZSB2aXJ0dWFsIGZ1bmN0aW9uIHBvaW50ZXIgZmllbGQKICAgKGFzIGFuIElERU5USUZJRVJfTk9ERSkgZm9yIHRoZSBnaXZlbiBUWVBFLiAgTm90ZSB0aGF0CiAgIHRoaXMgbWF5IGhhdmUgdG8gbG9vayBiYWNrIHRocm91Z2ggYmFzZSB0eXBlcyB0byBmaW5kIHRoZQogICB1bHRpbWF0ZSBmaWVsZCBuYW1lLiAgKEZvciBzaW5nbGUgaW5oZXJpdGFuY2UsIHRoZXNlIGNvdWxkCiAgIGFsbCBiZSB0aGUgc2FtZSBuYW1lLiAgV2hvIGtub3dzIGZvciBtdWx0aXBsZSBpbmhlcml0YW5jZSkuICAqLwoKc3RhdGljIHRyZWUKZ2V0X3ZmaWVsZF9uYW1lICh0cmVlIHR5cGUpCnsKICB0cmVlIGJpbmZvLCBiYXNlX2JpbmZvOwogIGNoYXIgKmJ1ZjsKCiAgZm9yIChiaW5mbyA9IFRZUEVfQklORk8gKHR5cGUpOwogICAgICAgQklORk9fTl9CQVNFX0JJTkZPUyAoYmluZm8pOwogICAgICAgYmluZm8gPSBiYXNlX2JpbmZvKQogICAgewogICAgICBiYXNlX2JpbmZvID0gQklORk9fQkFTRV9CSU5GTyAoYmluZm8sIDApOwoKICAgICAgaWYgKEJJTkZPX1ZJUlRVQUxfUCAoYmFzZV9iaW5mbykKCSAgfHwgIVRZUEVfQ09OVEFJTlNfVlBUUl9QIChCSU5GT19UWVBFIChiYXNlX2JpbmZvKSkpCglicmVhazsKICAgIH0KICAKICB0eXBlID0gQklORk9fVFlQRSAoYmluZm8pOwogIGJ1ZiA9IGFsbG9jYSAoc2l6ZW9mIChWRklFTERfTkFNRV9GT1JNQVQpICsgVFlQRV9OQU1FX0xFTkdUSCAodHlwZSkgKyAyKTsKICBzcHJpbnRmIChidWYsIFZGSUVMRF9OQU1FX0ZPUk1BVCwKCSAgIElERU5USUZJRVJfUE9JTlRFUiAoY29uc3RydWN0b3JfbmFtZSAodHlwZSkpKTsKICByZXR1cm4gZ2V0X2lkZW50aWZpZXIgKGJ1Zik7Cn0KCnZvaWQKcHJpbnRfY2xhc3Nfc3RhdGlzdGljcyAodm9pZCkKewojaWZkZWYgR0FUSEVSX1NUQVRJU1RJQ1MKICBmcHJpbnRmIChzdGRlcnIsICJjb252ZXJ0X2hhcnNobmVzcyA9ICVkXG4iLCBuX2NvbnZlcnRfaGFyc2huZXNzKTsKICBmcHJpbnRmIChzdGRlcnIsICJjb21wdXRlX2NvbnZlcnNpb25fY29zdHMgPSAlZFxuIiwgbl9jb21wdXRlX2NvbnZlcnNpb25fY29zdHMpOwogIGlmIChuX3Z0YWJsZXMpCiAgICB7CiAgICAgIGZwcmludGYgKHN0ZGVyciwgInZ0YWJsZXMgPSAlZDsgdnRhYmxlIHNlYXJjaGVzID0gJWRcbiIsCgkgICAgICAgbl92dGFibGVzLCBuX3Z0YWJsZV9zZWFyY2hlcyk7CiAgICAgIGZwcmludGYgKHN0ZGVyciwgInZ0YWJsZSBlbnRyaWVzID0gJWQ7IHZ0YWJsZSBlbGVtcyA9ICVkXG4iLAoJICAgICAgIG5fdnRhYmxlX2VudHJpZXMsIG5fdnRhYmxlX2VsZW1zKTsKICAgIH0KI2VuZGlmCn0KCi8qIEJ1aWxkIGEgZHVtbXkgcmVmZXJlbmNlIHRvIG91cnNlbHZlcyBzbyBEZXJpdmVkOjpCYXNlIChhbmQgQTo6QSkgd29ya3MsCiAgIGFjY29yZGluZyB0byBbY2xhc3NdOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGUgY2xhc3MtbmFtZSBpcyBhbHNvIGluc2VydGVkCiAgIGludG8gIHRoZSBzY29wZSBvZiB0aGUgY2xhc3MgaXRzZWxmLiAgRm9yIHB1cnBvc2VzIG9mIGFjY2VzcyBjaGVja2luZywKICAgdGhlIGluc2VydGVkIGNsYXNzIG5hbWUgaXMgdHJlYXRlZCBhcyBpZiBpdCB3ZXJlIGEgcHVibGljIG1lbWJlciBuYW1lLiAgKi8KCnZvaWQKYnVpbGRfc2VsZl9yZWZlcmVuY2UgKHZvaWQpCnsKICB0cmVlIG5hbWUgPSBjb25zdHJ1Y3Rvcl9uYW1lIChjdXJyZW50X2NsYXNzX3R5cGUpOwogIHRyZWUgdmFsdWUgPSBidWlsZF9sYW5nX2RlY2wgKFRZUEVfREVDTCwgbmFtZSwgY3VycmVudF9jbGFzc190eXBlKTsKICB0cmVlIHNhdmVkX2NhczsKCiAgREVDTF9OT05MT0NBTCAodmFsdWUpID0gMTsKICBERUNMX0NPTlRFWFQgKHZhbHVlKSA9IGN1cnJlbnRfY2xhc3NfdHlwZTsKICBERUNMX0FSVElGSUNJQUwgKHZhbHVlKSA9IDE7CiAgU0VUX0RFQ0xfU0VMRl9SRUZFUkVOQ0VfUCAodmFsdWUpOwoKICBpZiAocHJvY2Vzc2luZ190ZW1wbGF0ZV9kZWNsKQogICAgdmFsdWUgPSBwdXNoX3RlbXBsYXRlX2RlY2wgKHZhbHVlKTsKCiAgc2F2ZWRfY2FzID0gY3VycmVudF9hY2Nlc3Nfc3BlY2lmaWVyOwogIGN1cnJlbnRfYWNjZXNzX3NwZWNpZmllciA9IGFjY2Vzc19wdWJsaWNfbm9kZTsKICBmaW5pc2hfbWVtYmVyX2RlY2xhcmF0aW9uICh2YWx1ZSk7CiAgY3VycmVudF9hY2Nlc3Nfc3BlY2lmaWVyID0gc2F2ZWRfY2FzOwp9CgovKiBSZXR1cm5zIDEgaWYgVFlQRSBjb250YWlucyBvbmx5IHBhZGRpbmcgYnl0ZXMuICAqLwoKaW50CmlzX2VtcHR5X2NsYXNzICh0cmVlIHR5cGUpCnsKICBpZiAodHlwZSA9PSBlcnJvcl9tYXJrX25vZGUpCiAgICByZXR1cm4gMDsKCiAgaWYgKCEgSVNfQUdHUl9UWVBFICh0eXBlKSkKICAgIHJldHVybiAwOwoKICAvKiBJbiBHKysgMy4yLCB3aGV0aGVyIG9yIG5vdCBhIGNsYXNzIHdhcyBlbXB0eSB3YXMgZGV0ZXJtaW5lZCBieQogICAgIGxvb2tpbmcgYXQgaXRzIHNpemUuICAqLwogIGlmIChhYmlfdmVyc2lvbl9hdF9sZWFzdCAoMikpCiAgICByZXR1cm4gQ0xBU1NUWVBFX0VNUFRZX1AgKHR5cGUpOwogIGVsc2UKICAgIHJldHVybiBpbnRlZ2VyX3plcm9wIChDTEFTU1RZUEVfU0laRSAodHlwZSkpOwp9CgovKiBSZXR1cm5zIHRydWUgaWYgVFlQRSBjb250YWlucyBhbiBlbXB0eSBjbGFzcy4gICovCgpzdGF0aWMgYm9vbApjb250YWluc19lbXB0eV9jbGFzc19wICh0cmVlIHR5cGUpCnsKICBpZiAoaXNfZW1wdHlfY2xhc3MgKHR5cGUpKQogICAgcmV0dXJuIHRydWU7CiAgaWYgKENMQVNTX1RZUEVfUCAodHlwZSkpCiAgICB7CiAgICAgIHRyZWUgZmllbGQ7CiAgICAgIHRyZWUgYmluZm87CiAgICAgIHRyZWUgYmFzZV9iaW5mbzsKICAgICAgaW50IGk7CgogICAgICBmb3IgKGJpbmZvID0gVFlQRV9CSU5GTyAodHlwZSksIGkgPSAwOwoJICAgQklORk9fQkFTRV9JVEVSQVRFIChiaW5mbywgaSwgYmFzZV9iaW5mbyk7ICsraSkKCWlmIChjb250YWluc19lbXB0eV9jbGFzc19wIChCSU5GT19UWVBFIChiYXNlX2JpbmZvKSkpCgkgIHJldHVybiB0cnVlOwogICAgICBmb3IgKGZpZWxkID0gVFlQRV9GSUVMRFMgKHR5cGUpOyBmaWVsZDsgZmllbGQgPSBUUkVFX0NIQUlOIChmaWVsZCkpCglpZiAoVFJFRV9DT0RFIChmaWVsZCkgPT0gRklFTERfREVDTAoJICAgICYmICFERUNMX0FSVElGSUNJQUwgKGZpZWxkKQoJICAgICYmIGlzX2VtcHR5X2NsYXNzIChUUkVFX1RZUEUgKGZpZWxkKSkpCgkgIHJldHVybiB0cnVlOwogICAgfQogIGVsc2UgaWYgKFRSRUVfQ09ERSAodHlwZSkgPT0gQVJSQVlfVFlQRSkKICAgIHJldHVybiBjb250YWluc19lbXB0eV9jbGFzc19wIChUUkVFX1RZUEUgKHR5cGUpKTsKICByZXR1cm4gZmFsc2U7Cn0KCi8qIE5vdGUgdGhhdCBOQU1FIHdhcyBsb29rZWQgdXAgd2hpbGUgdGhlIGN1cnJlbnQgY2xhc3Mgd2FzIGJlaW5nCiAgIGRlZmluZWQgYW5kIHRoYXQgdGhlIHJlc3VsdCBvZiB0aGF0IGxvb2t1cCB3YXMgREVDTC4gICovCgp2b2lkCm1heWJlX25vdGVfbmFtZV91c2VkX2luX2NsYXNzICh0cmVlIG5hbWUsIHRyZWUgZGVjbCkKewogIHNwbGF5X3RyZWUgbmFtZXNfdXNlZDsKCiAgLyogSWYgd2UncmUgbm90IGRlZmluaW5nIGEgY2xhc3MsIHRoZXJlJ3Mgbm90aGluZyB0byBkby4gICovCiAgaWYgKCEoaW5uZXJtb3N0X3Njb3BlX2tpbmQoKSA9PSBza19jbGFzcwoJJiYgVFlQRV9CRUlOR19ERUZJTkVEIChjdXJyZW50X2NsYXNzX3R5cGUpKSkKICAgIHJldHVybjsKICAKICAvKiBJZiB0aGVyZSdzIGFscmVhZHkgYSBiaW5kaW5nIGZvciB0aGlzIE5BTUUsIHRoZW4gd2UgZG9uJ3QgaGF2ZQogICAgIGFueXRoaW5nIHRvIHdvcnJ5IGFib3V0LiAgKi8KICBpZiAobG9va3VwX21lbWJlciAoY3VycmVudF9jbGFzc190eXBlLCBuYW1lLCAKCQkgICAgIC8qcHJvdGVjdD0qLzAsIC8qd2FudF90eXBlPSovZmFsc2UpKQogICAgcmV0dXJuOwoKICBpZiAoIWN1cnJlbnRfY2xhc3Nfc3RhY2tbY3VycmVudF9jbGFzc19kZXB0aCAtIDFdLm5hbWVzX3VzZWQpCiAgICBjdXJyZW50X2NsYXNzX3N0YWNrW2N1cnJlbnRfY2xhc3NfZGVwdGggLSAxXS5uYW1lc191c2VkCiAgICAgID0gc3BsYXlfdHJlZV9uZXcgKHNwbGF5X3RyZWVfY29tcGFyZV9wb2ludGVycywgMCwgMCk7CiAgbmFtZXNfdXNlZCA9IGN1cnJlbnRfY2xhc3Nfc3RhY2tbY3VycmVudF9jbGFzc19kZXB0aCAtIDFdLm5hbWVzX3VzZWQ7CgogIHNwbGF5X3RyZWVfaW5zZXJ0IChuYW1lc191c2VkLAoJCSAgICAgKHNwbGF5X3RyZWVfa2V5KSBuYW1lLCAKCQkgICAgIChzcGxheV90cmVlX3ZhbHVlKSBkZWNsKTsKfQoKLyogTm90ZSB0aGF0IE5BTUUgd2FzIGRlY2xhcmVkIChhcyBERUNMKSBpbiB0aGUgY3VycmVudCBjbGFzcy4gIENoZWNrCiAgIHRvIHNlZSB0aGF0IHRoZSBkZWNsYXJhdGlvbiBpcyB2YWxpZC4gICovCgp2b2lkCm5vdGVfbmFtZV9kZWNsYXJlZF9pbl9jbGFzcyAodHJlZSBuYW1lLCB0cmVlIGRlY2wpCnsKICBzcGxheV90cmVlIG5hbWVzX3VzZWQ7CiAgc3BsYXlfdHJlZV9ub2RlIG47CgogIC8qIExvb2sgdG8gc2VlIGlmIHdlIGV2ZXIgdXNlZCB0aGlzIG5hbWUuICAqLwogIG5hbWVzX3VzZWQgCiAgICA9IGN1cnJlbnRfY2xhc3Nfc3RhY2tbY3VycmVudF9jbGFzc19kZXB0aCAtIDFdLm5hbWVzX3VzZWQ7CiAgaWYgKCFuYW1lc191c2VkKQogICAgcmV0dXJuOwoKICBuID0gc3BsYXlfdHJlZV9sb29rdXAgKG5hbWVzX3VzZWQsIChzcGxheV90cmVlX2tleSkgbmFtZSk7CiAgaWYgKG4pCiAgICB7CiAgICAgIC8qIFtiYXNpYy5zY29wZS5jbGFzc10KCSAKCSBBIG5hbWUgTiB1c2VkIGluIGEgY2xhc3MgUyBzaGFsbCByZWZlciB0byB0aGUgc2FtZSBkZWNsYXJhdGlvbgoJIGluIGl0cyBjb250ZXh0IGFuZCB3aGVuIHJlLWV2YWx1YXRlZCBpbiB0aGUgY29tcGxldGVkIHNjb3BlIG9mCgkgUy4gICovCiAgICAgIGVycm9yICgiZGVjbGFyYXRpb24gb2YgJXEjRCIsIGRlY2wpOwogICAgICBjcF9lcnJvcl9hdCAoImNoYW5nZXMgbWVhbmluZyBvZiAlcUQgZnJvbSAlcSsjRCIsIAoJCSAgIERFQ0xfTkFNRSAoT1ZMX0NVUlJFTlQgKGRlY2wpKSwKCQkgICAodHJlZSkgbi0+dmFsdWUpOwogICAgfQp9CgovKiBSZXR1cm5zIHRoZSBWQVJfREVDTCBmb3IgdGhlIGNvbXBsZXRlIHZ0YWJsZSBhc3NvY2lhdGVkIHdpdGggQklORk8uCiAgIFNlY29uZGFyeSB2dGFibGVzIGFyZSBtZXJnZWQgd2l0aCBwcmltYXJ5IHZ0YWJsZXM7IHRoaXMgZnVuY3Rpb24KICAgd2lsbCByZXR1cm4gdGhlIFZBUl9ERUNMIGZvciB0aGUgcHJpbWFyeSB2dGFibGUuICAqLwoKdHJlZQpnZXRfdnRibF9kZWNsX2Zvcl9iaW5mbyAodHJlZSBiaW5mbykKewogIHRyZWUgZGVjbDsKCiAgZGVjbCA9IEJJTkZPX1ZUQUJMRSAoYmluZm8pOwogIGlmIChkZWNsICYmIFRSRUVfQ09ERSAoZGVjbCkgPT0gUExVU19FWFBSKQogICAgewogICAgICBnY2NfYXNzZXJ0IChUUkVFX0NPREUgKFRSRUVfT1BFUkFORCAoZGVjbCwgMCkpID09IEFERFJfRVhQUik7CiAgICAgIGRlY2wgPSBUUkVFX09QRVJBTkQgKFRSRUVfT1BFUkFORCAoZGVjbCwgMCksIDApOwogICAgfQogIGlmIChkZWNsKQogICAgZ2NjX2Fzc2VydCAoVFJFRV9DT0RFIChkZWNsKSA9PSBWQVJfREVDTCk7CiAgcmV0dXJuIGRlY2w7Cn0KCgovKiBSZXR1cm5zIHRoZSBiaW5mbyBmb3IgdGhlIHByaW1hcnkgYmFzZSBvZiBCSU5GTy4gIElmIHRoZSByZXN1bHRpbmcKICAgQklORk8gaXMgYSB2aXJ0dWFsIGJhc2UsIGFuZCBpdCBpcyBpbmhlcml0ZWQgZWxzZXdoZXJlIGluIHRoZQogICBoaWVyYXJjaHksIHRoZW4gdGhlIHJldHVybmVkIGJpbmZvIG1pZ2h0IG5vdCBiZSB0aGUgcHJpbWFyeSBiYXNlIG9mCiAgIEJJTkZPIGluIHRoZSBjb21wbGV0ZSBvYmplY3QuICBDaGVjayBCSU5GT19QUklNQVJZX1Agb3IKICAgQklORk9fTE9TVF9QUklNQVJZX1AgdG8gYmUgc3VyZS4gICovCgp0cmVlCmdldF9wcmltYXJ5X2JpbmZvICh0cmVlIGJpbmZvKQp7CiAgdHJlZSBwcmltYXJ5X2Jhc2U7CiAgdHJlZSByZXN1bHQ7CiAgCiAgcHJpbWFyeV9iYXNlID0gQ0xBU1NUWVBFX1BSSU1BUllfQklORk8gKEJJTkZPX1RZUEUgKGJpbmZvKSk7CiAgaWYgKCFwcmltYXJ5X2Jhc2UpCiAgICByZXR1cm4gTlVMTF9UUkVFOwoKICByZXN1bHQgPSBjb3BpZWRfYmluZm8gKHByaW1hcnlfYmFzZSwgYmluZm8pOwogIHJldHVybiByZXN1bHQ7Cn0KCi8qIElmIElOREVOVEVEX1AgaXMgemVybywgaW5kZW50IHRvIElOREVOVC4gUmV0dXJuIG5vbnplcm8uICAqLwoKc3RhdGljIGludAptYXliZV9pbmRlbnRfaGllcmFyY2h5IChGSUxFICogc3RyZWFtLCBpbnQgaW5kZW50LCBpbnQgaW5kZW50ZWRfcCkKewogIGlmICghaW5kZW50ZWRfcCkKICAgIGZwcmludGYgKHN0cmVhbSwgIiUqcyIsIGluZGVudCwgIiIpOwogIHJldHVybiAxOwp9CgovKiBEdW1wIHRoZSBvZmZzZXRzIG9mIGFsbCB0aGUgYmFzZXMgcm9vdGVkIGF0IEJJTkZPIHRvIFNUUkVBTS4KICAgSU5ERU5UIHNob3VsZCBiZSB6ZXJvIHdoZW4gY2FsbGVkIGZyb20gdGhlIHRvcCBsZXZlbDsgaXQgaXMKICAgaW5jcmVtZW50ZWQgcmVjdXJzaXZlbHkuICBJR08gaW5kaWNhdGVzIHRoZSBuZXh0IGV4cGVjdGVkIEJJTkZPIGluCiAgIGluaGVyaXRhbmNlIGdyYXBoIG9yZGVyaW5nLiAgKi8KCnN0YXRpYyB0cmVlCmR1bXBfY2xhc3NfaGllcmFyY2h5X3IgKEZJTEUgKnN0cmVhbSwKICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICB0cmVlIGJpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICB0cmVlIGlnbywKICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGVudCkKewogIGludCBpbmRlbnRlZCA9IDA7CiAgdHJlZSBiYXNlX2JpbmZvOwogIGludCBpOwogIAogIGluZGVudGVkID0gbWF5YmVfaW5kZW50X2hpZXJhcmNoeSAoc3RyZWFtLCBpbmRlbnQsIDApOwogIGZwcmludGYgKHN0cmVhbSwgIiVzICgweCVseCkgIiwKCSAgIHR5cGVfYXNfc3RyaW5nIChCSU5GT19UWVBFIChiaW5mbyksIFRGRl9QTEFJTl9JREVOVElGSUVSKSwKCSAgICh1bnNpZ25lZCBsb25nKSBiaW5mbyk7CiAgaWYgKGJpbmZvICE9IGlnbykKICAgIHsKICAgICAgZnByaW50ZiAoc3RyZWFtLCAiYWx0ZXJuYXRpdmUtcGF0aFxuIik7CiAgICAgIHJldHVybiBpZ287CiAgICB9CiAgaWdvID0gVFJFRV9DSEFJTiAoYmluZm8pOwogIAogIGZwcmludGYgKHN0cmVhbSwgSE9TVF9XSURFX0lOVF9QUklOVF9ERUMsCgkgICB0cmVlX2xvd19jc3QgKEJJTkZPX09GRlNFVCAoYmluZm8pLCAwKSk7CiAgaWYgKGlzX2VtcHR5X2NsYXNzIChCSU5GT19UWVBFIChiaW5mbykpKQogICAgZnByaW50ZiAoc3RyZWFtLCAiIGVtcHR5Iik7CiAgZWxzZSBpZiAoQ0xBU1NUWVBFX05FQVJMWV9FTVBUWV9QIChCSU5GT19UWVBFIChiaW5mbykpKQogICAgZnByaW50ZiAoc3RyZWFtLCAiIG5lYXJseS1lbXB0eSIpOwogIGlmIChCSU5GT19WSVJUVUFMX1AgKGJpbmZvKSkKICAgIGZwcmludGYgKHN0cmVhbSwgIiB2aXJ0dWFsIik7CiAgZnByaW50ZiAoc3RyZWFtLCAiXG4iKTsKCiAgaW5kZW50ZWQgPSAwOwogIGlmIChCSU5GT19QUklNQVJZX1AgKGJpbmZvKSkKICAgIHsKICAgICAgaW5kZW50ZWQgPSBtYXliZV9pbmRlbnRfaGllcmFyY2h5IChzdHJlYW0sIGluZGVudCArIDMsIGluZGVudGVkKTsKICAgICAgZnByaW50ZiAoc3RyZWFtLCAiIHByaW1hcnktZm9yICVzICgweCVseCkiLAoJICAgICAgIHR5cGVfYXNfc3RyaW5nIChCSU5GT19UWVBFIChCSU5GT19JTkhFUklUQU5DRV9DSEFJTiAoYmluZm8pKSwKCQkJICAgICAgIFRGRl9QTEFJTl9JREVOVElGSUVSKSwKCSAgICAgICAodW5zaWduZWQgbG9uZylCSU5GT19JTkhFUklUQU5DRV9DSEFJTiAoYmluZm8pKTsKICAgIH0KICBpZiAoQklORk9fTE9TVF9QUklNQVJZX1AgKGJpbmZvKSkKICAgIHsKICAgICAgaW5kZW50ZWQgPSBtYXliZV9pbmRlbnRfaGllcmFyY2h5IChzdHJlYW0sIGluZGVudCArIDMsIGluZGVudGVkKTsKICAgICAgZnByaW50ZiAoc3RyZWFtLCAiIGxvc3QtcHJpbWFyeSIpOwogICAgfQogIGlmIChpbmRlbnRlZCkKICAgIGZwcmludGYgKHN0cmVhbSwgIlxuIik7CgogIGlmICghKGZsYWdzICYgVERGX1NMSU0pKQogICAgewogICAgICBpbnQgaW5kZW50ZWQgPSAwOwogICAgICAKICAgICAgaWYgKEJJTkZPX1NVQlZUVF9JTkRFWCAoYmluZm8pKQoJewoJICBpbmRlbnRlZCA9IG1heWJlX2luZGVudF9oaWVyYXJjaHkgKHN0cmVhbSwgaW5kZW50ICsgMywgaW5kZW50ZWQpOwoJICBmcHJpbnRmIChzdHJlYW0sICIgc3VidnR0aWR4PSVzIiwKCQkgICBleHByX2FzX3N0cmluZyAoQklORk9fU1VCVlRUX0lOREVYIChiaW5mbyksCgkJCQkgICBURkZfUExBSU5fSURFTlRJRklFUikpOwoJfQogICAgICBpZiAoQklORk9fVlBUUl9JTkRFWCAoYmluZm8pKQoJewoJICBpbmRlbnRlZCA9IG1heWJlX2luZGVudF9oaWVyYXJjaHkgKHN0cmVhbSwgaW5kZW50ICsgMywgaW5kZW50ZWQpOwoJICBmcHJpbnRmIChzdHJlYW0sICIgdnB0cmlkeD0lcyIsCgkJICAgZXhwcl9hc19zdHJpbmcgKEJJTkZPX1ZQVFJfSU5ERVggKGJpbmZvKSwKCQkJCSAgIFRGRl9QTEFJTl9JREVOVElGSUVSKSk7Cgl9CiAgICAgIGlmIChCSU5GT19WUFRSX0ZJRUxEIChiaW5mbykpCgl7CgkgIGluZGVudGVkID0gbWF5YmVfaW5kZW50X2hpZXJhcmNoeSAoc3RyZWFtLCBpbmRlbnQgKyAzLCBpbmRlbnRlZCk7CgkgIGZwcmludGYgKHN0cmVhbSwgIiB2YmFzZW9mZnNldD0lcyIsCgkJICAgZXhwcl9hc19zdHJpbmcgKEJJTkZPX1ZQVFJfRklFTEQgKGJpbmZvKSwKCQkJCSAgIFRGRl9QTEFJTl9JREVOVElGSUVSKSk7Cgl9CiAgICAgIGlmIChCSU5GT19WVEFCTEUgKGJpbmZvKSkKCXsKCSAgaW5kZW50ZWQgPSBtYXliZV9pbmRlbnRfaGllcmFyY2h5IChzdHJlYW0sIGluZGVudCArIDMsIGluZGVudGVkKTsKCSAgZnByaW50ZiAoc3RyZWFtLCAiIHZwdHI9JXMiLAoJCSAgIGV4cHJfYXNfc3RyaW5nIChCSU5GT19WVEFCTEUgKGJpbmZvKSwKCQkJCSAgIFRGRl9QTEFJTl9JREVOVElGSUVSKSk7Cgl9CiAgICAgIAogICAgICBpZiAoaW5kZW50ZWQpCglmcHJpbnRmIChzdHJlYW0sICJcbiIpOwogICAgfQoKICBmb3IgKGkgPSAwOyBCSU5GT19CQVNFX0lURVJBVEUgKGJpbmZvLCBpLCBiYXNlX2JpbmZvKTsgaSsrKQogICAgaWdvID0gZHVtcF9jbGFzc19oaWVyYXJjaHlfciAoc3RyZWFtLCBmbGFncywgYmFzZV9iaW5mbywgaWdvLCBpbmRlbnQgKyAyKTsKICAKICByZXR1cm4gaWdvOwp9CgovKiBEdW1wIHRoZSBCSU5GTyBoaWVyYXJjaHkgZm9yIFQuICAqLwoKc3RhdGljIHZvaWQKZHVtcF9jbGFzc19oaWVyYXJjaHlfMSAoRklMRSAqc3RyZWFtLCBpbnQgZmxhZ3MsIHRyZWUgdCkKewogIGZwcmludGYgKHN0cmVhbSwgIkNsYXNzICVzXG4iLCB0eXBlX2FzX3N0cmluZyAodCwgVEZGX1BMQUlOX0lERU5USUZJRVIpKTsKICBmcHJpbnRmIChzdHJlYW0sICIgICBzaXplPSVsdSBhbGlnbj0lbHVcbiIsCgkgICAodW5zaWduZWQgbG9uZykodHJlZV9sb3dfY3N0IChUWVBFX1NJWkUgKHQpLCAwKSAvIEJJVFNfUEVSX1VOSVQpLAoJICAgKHVuc2lnbmVkIGxvbmcpKFRZUEVfQUxJR04gKHQpIC8gQklUU19QRVJfVU5JVCkpOwogIGZwcmludGYgKHN0cmVhbSwgIiAgIGJhc2Ugc2l6ZT0lbHUgYmFzZSBhbGlnbj0lbHVcbiIsCgkgICAodW5zaWduZWQgbG9uZykodHJlZV9sb3dfY3N0IChUWVBFX1NJWkUgKENMQVNTVFlQRV9BU19CQVNFICh0KSksIDApCgkJCSAgIC8gQklUU19QRVJfVU5JVCksCgkgICAodW5zaWduZWQgbG9uZykoVFlQRV9BTElHTiAoQ0xBU1NUWVBFX0FTX0JBU0UgKHQpKQoJCQkgICAvIEJJVFNfUEVSX1VOSVQpKTsKICBkdW1wX2NsYXNzX2hpZXJhcmNoeV9yIChzdHJlYW0sIGZsYWdzLCBUWVBFX0JJTkZPICh0KSwgVFlQRV9CSU5GTyAodCksIDApOwogIGZwcmludGYgKHN0cmVhbSwgIlxuIik7Cn0KCi8qIERlYnVnIGludGVyZmFjZSB0byBoaWVyYXJjaHkgZHVtcGluZy4gICovCgpleHRlcm4gdm9pZApkZWJ1Z19jbGFzcyAodHJlZSB0KQp7CiAgZHVtcF9jbGFzc19oaWVyYXJjaHlfMSAoc3RkZXJyLCBUREZfU0xJTSwgdCk7Cn0KCnN0YXRpYyB2b2lkCmR1bXBfY2xhc3NfaGllcmFyY2h5ICh0cmVlIHQpCnsKICBpbnQgZmxhZ3M7CiAgRklMRSAqc3RyZWFtID0gZHVtcF9iZWdpbiAoVERJX2NsYXNzLCAmZmxhZ3MpOwoKICBpZiAoc3RyZWFtKQogICAgewogICAgICBkdW1wX2NsYXNzX2hpZXJhcmNoeV8xIChzdHJlYW0sIGZsYWdzLCB0KTsKICAgICAgZHVtcF9lbmQgKFRESV9jbGFzcywgc3RyZWFtKTsKICAgIH0KfQoKc3RhdGljIHZvaWQKZHVtcF9hcnJheSAoRklMRSAqIHN0cmVhbSwgdHJlZSBkZWNsKQp7CiAgdHJlZSBpbml0czsKICBpbnQgaXg7CiAgSE9TVF9XSURFX0lOVCBlbHQ7CiAgdHJlZSBzaXplID0gVFlQRV9NQVhfVkFMVUUgKFRZUEVfRE9NQUlOIChUUkVFX1RZUEUgKGRlY2wpKSk7CgogIGVsdCA9ICh0cmVlX2xvd19jc3QgKFRZUEVfU0laRSAoVFJFRV9UWVBFIChUUkVFX1RZUEUgKGRlY2wpKSksIDApCgkgLyBCSVRTX1BFUl9VTklUKTsKICBmcHJpbnRmIChzdHJlYW0sICIlczoiLCBkZWNsX2FzX3N0cmluZyAoZGVjbCwgVEZGX1BMQUlOX0lERU5USUZJRVIpKTsKICBmcHJpbnRmIChzdHJlYW0sICIgJXMgZW50cmllcyIsCgkgICBleHByX2FzX3N0cmluZyAoc2l6ZV9iaW5vcCAoUExVU19FWFBSLCBzaXplLCBzaXplX29uZV9ub2RlKSwKCQkJICAgVEZGX1BMQUlOX0lERU5USUZJRVIpKTsKICBmcHJpbnRmIChzdHJlYW0sICJcbiIpOwoKICBmb3IgKGl4ID0gMCwgaW5pdHMgPSBDT05TVFJVQ1RPUl9FTFRTIChERUNMX0lOSVRJQUwgKGRlY2wpKTsKICAgICAgIGluaXRzOyBpeCsrLCBpbml0cyA9IFRSRUVfQ0hBSU4gKGluaXRzKSkKICAgIGZwcmludGYgKHN0cmVhbSwgIiUtNGxkICAlc1xuIiwgKGxvbmcpKGl4ICogZWx0KSwKCSAgICAgZXhwcl9hc19zdHJpbmcgKFRSRUVfVkFMVUUgKGluaXRzKSwgVEZGX1BMQUlOX0lERU5USUZJRVIpKTsKfQoKc3RhdGljIHZvaWQKZHVtcF92dGFibGUgKHRyZWUgdCwgdHJlZSBiaW5mbywgdHJlZSB2dGFibGUpCnsKICBpbnQgZmxhZ3M7CiAgRklMRSAqc3RyZWFtID0gZHVtcF9iZWdpbiAoVERJX2NsYXNzLCAmZmxhZ3MpOwoKICBpZiAoIXN0cmVhbSkKICAgIHJldHVybjsKCiAgaWYgKCEoZmxhZ3MgJiBUREZfU0xJTSkpCiAgICB7CiAgICAgIGludCBjdG9yX3Z0YmxfcCA9IFRZUEVfQklORk8gKHQpICE9IGJpbmZvOwogICAgICAKICAgICAgZnByaW50ZiAoc3RyZWFtLCAiJXMgZm9yICVzIiwKCSAgICAgICBjdG9yX3Z0YmxfcCA/ICJDb25zdHJ1Y3Rpb24gdnRhYmxlIiA6ICJWdGFibGUiLAoJICAgICAgIHR5cGVfYXNfc3RyaW5nIChCSU5GT19UWVBFIChiaW5mbyksIFRGRl9QTEFJTl9JREVOVElGSUVSKSk7CiAgICAgIGlmIChjdG9yX3Z0YmxfcCkKCXsKCSAgaWYgKCFCSU5GT19WSVJUVUFMX1AgKGJpbmZvKSkKCSAgICBmcHJpbnRmIChzdHJlYW0sICIgKDB4JWx4IGluc3RhbmNlKSIsICh1bnNpZ25lZCBsb25nKWJpbmZvKTsKCSAgZnByaW50ZiAoc3RyZWFtLCAiIGluICVzIiwgdHlwZV9hc19zdHJpbmcgKHQsIFRGRl9QTEFJTl9JREVOVElGSUVSKSk7Cgl9CiAgICAgIGZwcmludGYgKHN0cmVhbSwgIlxuIik7CiAgICAgIGR1bXBfYXJyYXkgKHN0cmVhbSwgdnRhYmxlKTsKICAgICAgZnByaW50ZiAoc3RyZWFtLCAiXG4iKTsKICAgIH0KICAKICBkdW1wX2VuZCAoVERJX2NsYXNzLCBzdHJlYW0pOwp9CgpzdGF0aWMgdm9pZApkdW1wX3Z0dCAodHJlZSB0LCB0cmVlIHZ0dCkKewogIGludCBmbGFnczsKICBGSUxFICpzdHJlYW0gPSBkdW1wX2JlZ2luIChURElfY2xhc3MsICZmbGFncyk7CgogIGlmICghc3RyZWFtKQogICAgcmV0dXJuOwoKICBpZiAoIShmbGFncyAmIFRERl9TTElNKSkKICAgIHsKICAgICAgZnByaW50ZiAoc3RyZWFtLCAiVlRUIGZvciAlc1xuIiwKCSAgICAgICB0eXBlX2FzX3N0cmluZyAodCwgVEZGX1BMQUlOX0lERU5USUZJRVIpKTsKICAgICAgZHVtcF9hcnJheSAoc3RyZWFtLCB2dHQpOwogICAgICBmcHJpbnRmIChzdHJlYW0sICJcbiIpOwogICAgfQogIAogIGR1bXBfZW5kIChURElfY2xhc3MsIHN0cmVhbSk7Cn0KCi8qIER1bXAgYSBmdW5jdGlvbiBvciB0aHVuayBhbmQgaXRzIHRodW5rZWVzLiAgKi8KCnN0YXRpYyB2b2lkCmR1bXBfdGh1bmsgKEZJTEUgKnN0cmVhbSwgaW50IGluZGVudCwgdHJlZSB0aHVuaykKewogIHN0YXRpYyBjb25zdCBjaGFyIHNwYWNlc1tdID0gIiAgICAgICAgIjsKICB0cmVlIG5hbWUgPSBERUNMX05BTUUgKHRodW5rKTsKICB0cmVlIHRodW5rczsKICAgICAgCiAgZnByaW50ZiAoc3RyZWFtLCAiJS4qcyVwICVzICVzIiwgaW5kZW50LCBzcGFjZXMsCgkgICAodm9pZCAqKXRodW5rLAoJICAgIURFQ0xfVEhVTktfUCAodGh1bmspID8gImZ1bmN0aW9uIgoJICAgOiBERUNMX1RISVNfVEhVTktfUCAodGh1bmspID8gInRoaXMtdGh1bmsiIDogImNvdmFyaWFudC10aHVuayIsCgkgICBuYW1lID8gSURFTlRJRklFUl9QT0lOVEVSIChuYW1lKSA6ICI8dW5zZXQ+Iik7CiAgaWYgKERFQ0xfVEhVTktfUCAodGh1bmspKQogICAgewogICAgICBIT1NUX1dJREVfSU5UIGZpeGVkX2FkanVzdCA9IFRIVU5LX0ZJWEVEX09GRlNFVCAodGh1bmspOwogICAgICB0cmVlIHZpcnR1YWxfYWRqdXN0ID0gVEhVTktfVklSVFVBTF9PRkZTRVQgKHRodW5rKTsKCiAgICAgIGZwcmludGYgKHN0cmVhbSwgIiBmaXhlZD0iIEhPU1RfV0lERV9JTlRfUFJJTlRfREVDLCBmaXhlZF9hZGp1c3QpOwogICAgICBpZiAoIXZpcnR1YWxfYWRqdXN0KQoJLypOT1AqLzsKICAgICAgZWxzZSBpZiAoREVDTF9USElTX1RIVU5LX1AgKHRodW5rKSkKCWZwcmludGYgKHN0cmVhbSwgIiB2Y2FsbD0iICBIT1NUX1dJREVfSU5UX1BSSU5UX0RFQywKCQkgdHJlZV9sb3dfY3N0ICh2aXJ0dWFsX2FkanVzdCwgMCkpOwogICAgICBlbHNlCglmcHJpbnRmIChzdHJlYW0sICIgdmJhc2U9IiBIT1NUX1dJREVfSU5UX1BSSU5UX0RFQyAiKCVzKSIsCgkJIHRyZWVfbG93X2NzdCAoQklORk9fVlBUUl9GSUVMRCAodmlydHVhbF9hZGp1c3QpLCAwKSwKCQkgdHlwZV9hc19zdHJpbmcgKEJJTkZPX1RZUEUgKHZpcnR1YWxfYWRqdXN0KSwgVEZGX1NDT1BFKSk7CiAgICAgIGlmIChUSFVOS19BTElBUyAodGh1bmspKQoJZnByaW50ZiAoc3RyZWFtLCAiIGFsaWFzIHRvICVwIiwgKHZvaWQgKilUSFVOS19BTElBUyAodGh1bmspKTsKICAgIH0KICBmcHJpbnRmIChzdHJlYW0sICJcbiIpOwogIGZvciAodGh1bmtzID0gREVDTF9USFVOS1MgKHRodW5rKTsgdGh1bmtzOyB0aHVua3MgPSBUUkVFX0NIQUlOICh0aHVua3MpKQogICAgZHVtcF90aHVuayAoc3RyZWFtLCBpbmRlbnQgKyAyLCB0aHVua3MpOwp9CgovKiBEdW1wIHRoZSB0aHVua3MgZm9yIEZOLiAgKi8KCmV4dGVybiB2b2lkCmRlYnVnX3RodW5rcyAodHJlZSBmbikKewogIGR1bXBfdGh1bmsgKHN0ZGVyciwgMCwgZm4pOwp9CgovKiBWaXJ0dWFsIGZ1bmN0aW9uIHRhYmxlIGluaXRpYWxpemF0aW9uLiAgKi8KCi8qIENyZWF0ZSBhbGwgdGhlIG5lY2Vzc2FyeSB2dGFibGVzIGZvciBUIGFuZCBpdHMgYmFzZSBjbGFzc2VzLiAgKi8KCnN0YXRpYyB2b2lkCmZpbmlzaF92dGJscyAodHJlZSB0KQp7CiAgdHJlZSBsaXN0OwogIHRyZWUgdmJhc2U7CgogIC8qIFdlIGxheSBvdXQgdGhlIHByaW1hcnkgYW5kIHNlY29uZGFyeSB2dGFibGVzIGluIG9uZSBjb250aWd1b3VzCiAgICAgdnRhYmxlLiAgVGhlIHByaW1hcnkgdnRhYmxlIGlzIGZpcnN0LCBmb2xsb3dlZCBieSB0aGUgbm9uLXZpcnR1YWwKICAgICBzZWNvbmRhcnkgdnRhYmxlcyBpbiBpbmhlcml0YW5jZSBncmFwaCBvcmRlci4gICovCiAgbGlzdCA9IGJ1aWxkX3RyZWVfbGlzdCAoQklORk9fVlRBQkxFIChUWVBFX0JJTkZPICh0KSksIE5VTExfVFJFRSk7CiAgYWNjdW11bGF0ZV92dGJsX2luaXRzIChUWVBFX0JJTkZPICh0KSwgVFlQRV9CSU5GTyAodCksCgkJCSBUWVBFX0JJTkZPICh0KSwgdCwgbGlzdCk7CiAgCiAgLyogVGhlbiBjb21lIHRoZSB2aXJ0dWFsIGJhc2VzLCBhbHNvIGluIGluaGVyaXRhbmNlIGdyYXBoIG9yZGVyLiAgKi8KICBmb3IgKHZiYXNlID0gVFlQRV9CSU5GTyAodCk7IHZiYXNlOyB2YmFzZSA9IFRSRUVfQ0hBSU4gKHZiYXNlKSkKICAgIHsKICAgICAgaWYgKCFCSU5GT19WSVJUVUFMX1AgKHZiYXNlKSkKCWNvbnRpbnVlOwogICAgICBhY2N1bXVsYXRlX3Z0YmxfaW5pdHMgKHZiYXNlLCB2YmFzZSwgVFlQRV9CSU5GTyAodCksIHQsIGxpc3QpOwogICAgfQoKICBpZiAoQklORk9fVlRBQkxFIChUWVBFX0JJTkZPICh0KSkpCiAgICBpbml0aWFsaXplX3Z0YWJsZSAoVFlQRV9CSU5GTyAodCksIFRSRUVfVkFMVUUgKGxpc3QpKTsKfQoKLyogSW5pdGlhbGl6ZSB0aGUgdnRhYmxlIGZvciBCSU5GTyB3aXRoIHRoZSBJTklUUy4gICovCgpzdGF0aWMgdm9pZAppbml0aWFsaXplX3Z0YWJsZSAodHJlZSBiaW5mbywgdHJlZSBpbml0cykKewogIHRyZWUgZGVjbDsKCiAgbGF5b3V0X3Z0YWJsZV9kZWNsIChiaW5mbywgbGlzdF9sZW5ndGggKGluaXRzKSk7CiAgZGVjbCA9IGdldF92dGJsX2RlY2xfZm9yX2JpbmZvIChiaW5mbyk7CiAgaW5pdGlhbGl6ZV9hcnRpZmljaWFsX3ZhciAoZGVjbCwgaW5pdHMpOwogIGR1bXBfdnRhYmxlIChCSU5GT19UWVBFIChiaW5mbyksIGJpbmZvLCBkZWNsKTsKfQoKLyogQnVpbGQgdGhlIFZUVCAodmlydHVhbCB0YWJsZSB0YWJsZSkgZm9yIFQuCiAgIEEgY2xhc3MgcmVxdWlyZXMgYSBWVFQgaWYgaXQgaGFzIHZpcnR1YWwgYmFzZXMuCiAgIAogICBUaGlzIGhvbGRzCiAgIDEgLSBwcmltYXJ5IHZpcnR1YWwgcG9pbnRlciBmb3IgY29tcGxldGUgb2JqZWN0IFQKICAgMiAtIHNlY29uZGFyeSBWVFRzIGZvciBlYWNoIGRpcmVjdCBub24tdmlydHVhbCBiYXNlIG9mIFQgd2hpY2ggcmVxdWlyZXMgYQogICAgICAgVlRUCiAgIDMgLSBzZWNvbmRhcnkgdmlydHVhbCBwb2ludGVycyBmb3IgZWFjaCBkaXJlY3Qgb3IgaW5kaXJlY3QgYmFzZSBvZiBUIHdoaWNoCiAgICAgICBoYXMgdmlydHVhbCBiYXNlcyBvciBpcyByZWFjaGFibGUgdmlhIGEgdmlydHVhbCBwYXRoIGZyb20gVC4KICAgNCAtIHNlY29uZGFyeSBWVFRzIGZvciBlYWNoIGRpcmVjdCBvciBpbmRpcmVjdCB2aXJ0dWFsIGJhc2Ugb2YgVC4KICAgCiAgIFNlY29uZGFyeSBWVFRzIGxvb2sgbGlrZSBjb21wbGV0ZSBvYmplY3QgVlRUcyB3aXRob3V0IHBhcnQgNC4gICovCgpzdGF0aWMgdm9pZApidWlsZF92dHQgKHRyZWUgdCkKewogIHRyZWUgaW5pdHM7CiAgdHJlZSB0eXBlOwogIHRyZWUgdnR0OwogIHRyZWUgaW5kZXg7CgogIC8qIEJ1aWxkIHVwIHRoZSBpbml0aWFsaXplcnMgZm9yIHRoZSBWVFQuICAqLwogIGluaXRzID0gTlVMTF9UUkVFOwogIGluZGV4ID0gc2l6ZV96ZXJvX25vZGU7CiAgYnVpbGRfdnR0X2luaXRzIChUWVBFX0JJTkZPICh0KSwgdCwgJmluaXRzLCAmaW5kZXgpOwoKICAvKiBJZiB3ZSBkaWRuJ3QgbmVlZCBhIFZUVCwgd2UncmUgZG9uZS4gICovCiAgaWYgKCFpbml0cykKICAgIHJldHVybjsKCiAgLyogRmlndXJlIG91dCB0aGUgdHlwZSBvZiB0aGUgVlRULiAgKi8KICB0eXBlID0gYnVpbGRfaW5kZXhfdHlwZSAoc2l6ZV9pbnQgKGxpc3RfbGVuZ3RoIChpbml0cykgLSAxKSk7CiAgdHlwZSA9IGJ1aWxkX2NwbHVzX2FycmF5X3R5cGUgKGNvbnN0X3B0cl90eXBlX25vZGUsIHR5cGUpOwoJCQkJIAogIC8qIE5vdywgYnVpbGQgdGhlIFZUVCBvYmplY3QgaXRzZWxmLiAgKi8KICB2dHQgPSBidWlsZF92dGFibGUgKHQsIGdldF92dHRfbmFtZSAodCksIHR5cGUpOwogIGluaXRpYWxpemVfYXJ0aWZpY2lhbF92YXIgKHZ0dCwgaW5pdHMpOwogIC8qIEFkZCB0aGUgVlRUIHRvIHRoZSB2dGFibGVzIGxpc3QuICAqLwogIFRSRUVfQ0hBSU4gKHZ0dCkgPSBUUkVFX0NIQUlOIChDTEFTU1RZUEVfVlRBQkxFUyAodCkpOwogIFRSRUVfQ0hBSU4gKENMQVNTVFlQRV9WVEFCTEVTICh0KSkgPSB2dHQ7CgogIGR1bXBfdnR0ICh0LCB2dHQpOwp9CgovKiBXaGVuIGJ1aWxkaW5nIGEgc2Vjb25kYXJ5IFZUVCwgQklORk9fVlRBQkxFIGlzIHNldCB0byBhIFRSRUVfTElTVCB3aXRoCiAgIFBVUlBPU0UgdGhlIFJUVElfQklORk8sIFZBTFVFIHRoZSByZWFsIHZ0YWJsZSBwb2ludGVyIGZvciB0aGlzIGJpbmZvLAogICBhbmQgQ0hBSU4gdGhlIHZ0YWJsZSBwb2ludGVyIGZvciB0aGlzIGJpbmZvIGFmdGVyIGNvbnN0cnVjdGlvbiBpcwogICBjb21wbGV0ZS4gIFZBTFVFIGNhbiBhbHNvIGJlIGFub3RoZXIgQklORk8sIGluIHdoaWNoIGNhc2Ugd2UgcmVjdXJzZS4gICovCgpzdGF0aWMgdHJlZQpiaW5mb19jdG9yX3Z0YWJsZSAodHJlZSBiaW5mbykKewogIHRyZWUgdnQ7CgogIHdoaWxlICgxKQogICAgewogICAgICB2dCA9IEJJTkZPX1ZUQUJMRSAoYmluZm8pOwogICAgICBpZiAoVFJFRV9DT0RFICh2dCkgPT0gVFJFRV9MSVNUKQoJdnQgPSBUUkVFX1ZBTFVFICh2dCk7CiAgICAgIGlmIChUUkVFX0NPREUgKHZ0KSA9PSBUUkVFX0JJTkZPKQoJYmluZm8gPSB2dDsKICAgICAgZWxzZQoJYnJlYWs7CiAgICB9CgogIHJldHVybiB2dDsKfQoKLyogRGF0YSBmb3Igc2Vjb25kYXJ5IFZUVCBpbml0aWFsaXphdGlvbi4gICovCnR5cGVkZWYgc3RydWN0IHNlY29uZGFyeV92cHRyX3Z0dF9pbml0X2RhdGFfcwp7CiAgLyogSXMgdGhpcyB0aGUgcHJpbWFyeSBWVFQ/ICovCiAgYm9vbCB0b3BfbGV2ZWxfcDsKCiAgLyogQ3VycmVudCBpbmRleCBpbnRvIHRoZSBWVFQuICAqLwogIHRyZWUgaW5kZXg7CgogIC8qIFRSRUVfTElTVCBvZiBpbml0aWFsaXplcnMgYnVpbHQgdXAuICAqLwogIHRyZWUgaW5pdHM7CgogIC8qIFRoZSB0eXBlIGJlaW5nIGNvbnN0cnVjdGVkIGJ5IHRoaXMgc2Vjb25kYXJ5IFZUVC4gICovCiAgdHJlZSB0eXBlX2JlaW5nX2NvbnN0cnVjdGVkOwp9IHNlY29uZGFyeV92cHRyX3Z0dF9pbml0X2RhdGE7CgovKiBSZWN1cnNpdmVseSBidWlsZCB0aGUgVlRULWluaXRpYWxpemVyIGZvciBCSU5GTyAod2hpY2ggaXMgaW4gdGhlCiAgIGhpZXJhcmNoeSBkb21pbmF0ZWQgYnkgVCkuICBJTklUUyBwb2ludHMgdG8gdGhlIGVuZCBvZiB0aGUgaW5pdGlhbGl6ZXIKICAgbGlzdCB0byBkYXRlLiAgSU5ERVggaXMgdGhlIFZUVCBpbmRleCB3aGVyZSB0aGUgbmV4dCBlbGVtZW50IHdpbGwgYmUKICAgcmVwbGFjZWQuICBJZmYgQklORk8gaXMgdGhlIGJpbmZvIGZvciBULCB0aGlzIGlzIHRoZSB0b3AgbGV2ZWwgVlRUIChpLmUuCiAgIG5vdCBhIHN1YnZ0dCBmb3Igc29tZSBiYXNlIG9mIFQpLiAgV2hlbiB0aGF0IGlzIHNvLCB3ZSBlbWl0IHRoZSBzdWItVlRUcwogICBmb3IgdmlydHVhbCBiYXNlcyBvZiBULiBXaGVuIGl0IGlzIG5vdCBzbywgd2UgYnVpbGQgdGhlIGNvbnN0cnVjdG9yCiAgIHZ0YWJsZXMgZm9yIHRoZSBCSU5GTy1pbi1UIHZhcmlhbnQuICAqLwoKc3RhdGljIHRyZWUgKgpidWlsZF92dHRfaW5pdHMgKHRyZWUgYmluZm8sIHRyZWUgdCwgdHJlZSAqaW5pdHMsIHRyZWUgKmluZGV4KQp7CiAgaW50IGk7CiAgdHJlZSBiOwogIHRyZWUgaW5pdDsKICB0cmVlIHNlY29uZGFyeV92cHRyczsKICBzZWNvbmRhcnlfdnB0cl92dHRfaW5pdF9kYXRhIGRhdGE7CiAgaW50IHRvcF9sZXZlbF9wID0gU0FNRV9CSU5GT19UWVBFX1AgKEJJTkZPX1RZUEUgKGJpbmZvKSwgdCk7CgogIC8qIFdlIG9ubHkgbmVlZCBWVFRzIGZvciBzdWJvYmplY3RzIHdpdGggdmlydHVhbCBiYXNlcy4gICovCiAgaWYgKCFDTEFTU1RZUEVfVkJBU0VDTEFTU0VTIChCSU5GT19UWVBFIChiaW5mbykpKQogICAgcmV0dXJuIGluaXRzOwoKICAvKiBXZSBuZWVkIHRvIHVzZSBhIGNvbnN0cnVjdGlvbiB2dGFibGUgaWYgdGhpcyBpcyBub3QgdGhlIHByaW1hcnkKICAgICBWVFQuICAqLwogIGlmICghdG9wX2xldmVsX3ApCiAgICB7CiAgICAgIGJ1aWxkX2N0b3JfdnRibF9ncm91cCAoYmluZm8sIHQpOwoKICAgICAgLyogUmVjb3JkIHRoZSBvZmZzZXQgaW4gdGhlIFZUVCB3aGVyZSB0aGlzIHN1Yi1WVFQgY2FuIGJlIGZvdW5kLiAgKi8KICAgICAgQklORk9fU1VCVlRUX0lOREVYIChiaW5mbykgPSAqaW5kZXg7CiAgICB9CgogIC8qIEFkZCB0aGUgYWRkcmVzcyBvZiB0aGUgcHJpbWFyeSB2dGFibGUgZm9yIHRoZSBjb21wbGV0ZSBvYmplY3QuICAqLwogIGluaXQgPSBiaW5mb19jdG9yX3Z0YWJsZSAoYmluZm8pOwogICppbml0cyA9IGJ1aWxkX3RyZWVfbGlzdCAoTlVMTF9UUkVFLCBpbml0KTsKICBpbml0cyA9ICZUUkVFX0NIQUlOICgqaW5pdHMpOwogIGlmICh0b3BfbGV2ZWxfcCkKICAgIHsKICAgICAgZ2NjX2Fzc2VydCAoIUJJTkZPX1ZQVFJfSU5ERVggKGJpbmZvKSk7CiAgICAgIEJJTkZPX1ZQVFJfSU5ERVggKGJpbmZvKSA9ICppbmRleDsKICAgIH0KICAqaW5kZXggPSBzaXplX2Jpbm9wIChQTFVTX0VYUFIsICppbmRleCwgVFlQRV9TSVpFX1VOSVQgKHB0cl90eXBlX25vZGUpKTsKCQkgICAgICAgCiAgLyogUmVjdXJzaXZlbHkgYWRkIHRoZSBzZWNvbmRhcnkgVlRUcyBmb3Igbm9uLXZpcnR1YWwgYmFzZXMuICAqLwogIGZvciAoaSA9IDA7IEJJTkZPX0JBU0VfSVRFUkFURSAoYmluZm8sIGksIGIpOyArK2kpCiAgICBpZiAoIUJJTkZPX1ZJUlRVQUxfUCAoYikpCiAgICAgIGluaXRzID0gYnVpbGRfdnR0X2luaXRzIChiLCB0LCBpbml0cywgaW5kZXgpOwogICAgICAKICAvKiBBZGQgc2Vjb25kYXJ5IHZpcnR1YWwgcG9pbnRlcnMgZm9yIGFsbCBzdWJvYmplY3RzIG9mIEJJTkZPIHdpdGgKICAgICBlaXRoZXIgdmlydHVhbCBiYXNlcyBvciByZWFjaGFibGUgYWxvbmcgYSB2aXJ0dWFsIHBhdGgsIGV4Y2VwdAogICAgIHN1Ym9iamVjdHMgdGhhdCBhcmUgbm9uLXZpcnR1YWwgcHJpbWFyeSBiYXNlcy4gICovCiAgZGF0YS50b3BfbGV2ZWxfcCA9IHRvcF9sZXZlbF9wOwogIGRhdGEuaW5kZXggPSAqaW5kZXg7CiAgZGF0YS5pbml0cyA9IE5VTEw7CiAgZGF0YS50eXBlX2JlaW5nX2NvbnN0cnVjdGVkID0gQklORk9fVFlQRSAoYmluZm8pOwogIAogIGRmc193YWxrX29uY2UgKGJpbmZvLCBkZnNfYnVpbGRfc2Vjb25kYXJ5X3ZwdHJfdnR0X2luaXRzLCBOVUxMLCAmZGF0YSk7CgogICppbmRleCA9IGRhdGEuaW5kZXg7CgogIC8qIFRoZSBzZWNvbmRhcnkgdnB0cnMgY29tZSBiYWNrIGluIHJldmVyc2Ugb3JkZXIuICBBZnRlciB3ZSByZXZlcnNlCiAgICAgdGhlbSwgYW5kIGFkZCB0aGUgSU5JVFMsIHRoZSBsYXN0IGluaXQgd2lsbCBiZSB0aGUgZmlyc3QgZWxlbWVudAogICAgIG9mIHRoZSBjaGFpbi4gICovCiAgc2Vjb25kYXJ5X3ZwdHJzID0gZGF0YS5pbml0czsKICBpZiAoc2Vjb25kYXJ5X3ZwdHJzKQogICAgewogICAgICAqaW5pdHMgPSBucmV2ZXJzZSAoc2Vjb25kYXJ5X3ZwdHJzKTsKICAgICAgaW5pdHMgPSAmVFJFRV9DSEFJTiAoc2Vjb25kYXJ5X3ZwdHJzKTsKICAgICAgZ2NjX2Fzc2VydCAoKmluaXRzID09IE5VTExfVFJFRSk7CiAgICB9CgogIGlmICh0b3BfbGV2ZWxfcCkKICAgIC8qIEFkZCB0aGUgc2Vjb25kYXJ5IFZUVHMgZm9yIHZpcnR1YWwgYmFzZXMgaW4gaW5oZXJpdGFuY2UgZ3JhcGgKICAgICAgIG9yZGVyLiAgKi8KICAgIGZvciAoYiA9IFRZUEVfQklORk8gKEJJTkZPX1RZUEUgKGJpbmZvKSk7IGI7IGIgPSBUUkVFX0NIQUlOIChiKSkKICAgICAgewoJaWYgKCFCSU5GT19WSVJUVUFMX1AgKGIpKQoJICBjb250aW51ZTsKCQoJaW5pdHMgPSBidWlsZF92dHRfaW5pdHMgKGIsIHQsIGluaXRzLCBpbmRleCk7CiAgICAgIH0KICBlbHNlCiAgICAvKiBSZW1vdmUgdGhlIGN0b3IgdnRhYmxlcyB3ZSBjcmVhdGVkLiAgKi8KICAgIGRmc193YWxrX2FsbCAoYmluZm8sIGRmc19maXh1cF9iaW5mb192dGJscywgTlVMTCwgYmluZm8pOwoKICByZXR1cm4gaW5pdHM7Cn0KCi8qIENhbGxlZCBmcm9tIGJ1aWxkX3Z0dF9pbml0cyB2aWEgZGZzX3dhbGsuICBCSU5GTyBpcyB0aGUgYmluZm8gZm9yIHRoZSBiYXNlCiAgIGluIG1vc3QgZGVyaXZlZC4gREFUQSBpcyBhIFNFQ09OREFSWV9WUFRSX1ZUVF9JTklUX0RBVEEgc3RydWN0dXJlLiAgKi8KCnN0YXRpYyB0cmVlCmRmc19idWlsZF9zZWNvbmRhcnlfdnB0cl92dHRfaW5pdHMgKHRyZWUgYmluZm8sIHZvaWQgKmRhdGFfKQp7CiAgc2Vjb25kYXJ5X3ZwdHJfdnR0X2luaXRfZGF0YSAqZGF0YSA9IChzZWNvbmRhcnlfdnB0cl92dHRfaW5pdF9kYXRhICopZGF0YV87CgogIC8qIFdlIGRvbid0IGNhcmUgYWJvdXQgYmFzZXMgdGhhdCBkb24ndCBoYXZlIHZ0YWJsZXMuICAqLwogIGlmICghVFlQRV9WRklFTEQgKEJJTkZPX1RZUEUgKGJpbmZvKSkpCiAgICByZXR1cm4gZGZzX3NraXBfYmFzZXM7CgogIC8qIFdlJ3JlIG9ubHkgaW50ZXJlc3RlZCBpbiBwcm9wZXIgc3Vib2JqZWN0cyBvZiB0aGUgdHlwZSBiZWluZwogICAgIGNvbnN0cnVjdGVkLiAgKi8KICBpZiAoU0FNRV9CSU5GT19UWVBFX1AgKEJJTkZPX1RZUEUgKGJpbmZvKSwgZGF0YS0+dHlwZV9iZWluZ19jb25zdHJ1Y3RlZCkpCiAgICByZXR1cm4gTlVMTF9UUkVFOwoKICAvKiBXZSdyZSBvbmx5IGludGVyZXN0ZWQgaW4gYmFzZXMgd2l0aCB2aXJ0dWFsIGJhc2VzIG9yIHJlYWNoYWJsZQogICAgIHZpYSBhIHZpcnR1YWwgcGF0aCBmcm9tIHRoZSB0eXBlIGJlaW5nIGNvbnN0cnVjdGVkLiAgKi8KICBpZiAoIShDTEFTU1RZUEVfVkJBU0VDTEFTU0VTIChCSU5GT19UWVBFIChiaW5mbykpCgl8fCBiaW5mb192aWFfdmlydHVhbCAoYmluZm8sIGRhdGEtPnR5cGVfYmVpbmdfY29uc3RydWN0ZWQpKSkKICAgIHJldHVybiBkZnNfc2tpcF9iYXNlczsKICAKICAvKiBXZSdyZSBub3QgaW50ZXJlc3RlZCBpbiBub24tdmlydHVhbCBwcmltYXJ5IGJhc2VzLiAgKi8KICBpZiAoIUJJTkZPX1ZJUlRVQUxfUCAoYmluZm8pICYmIEJJTkZPX1BSSU1BUllfUCAoYmluZm8pKQogICAgcmV0dXJuIE5VTExfVFJFRTsKICAKICAvKiBSZWNvcmQgdGhlIGluZGV4IHdoZXJlIHRoaXMgc2Vjb25kYXJ5IHZwdHIgY2FuIGJlIGZvdW5kLiAgKi8KICBpZiAoZGF0YS0+dG9wX2xldmVsX3ApCiAgICB7CiAgICAgIGdjY19hc3NlcnQgKCFCSU5GT19WUFRSX0lOREVYIChiaW5mbykpOwogICAgICBCSU5GT19WUFRSX0lOREVYIChiaW5mbykgPSBkYXRhLT5pbmRleDsKCiAgICAgIGlmIChCSU5GT19WSVJUVUFMX1AgKGJpbmZvKSkKCXsKICAgICAgICAgIC8qIEl0J3MgYSBwcmltYXJ5IHZpcnR1YWwgYmFzZSwgYW5kIHRoaXMgaXMgbm90IGEKICAgICAgICAgICAgIGNvbnN0cnVjdGlvbiB2dGFibGUuICBGaW5kIHRoZSBiYXNlIHRoaXMgaXMgcHJpbWFyeSBvZiBpbgogICAgICAgICAgICAgdGhlIGluaGVyaXRhbmNlIGdyYXBoLCBhbmQgdXNlIHRoYXQgYmFzZSdzIHZ0YWJsZQogICAgICAgICAgICAgbm93LiAgKi8KCSAgd2hpbGUgKEJJTkZPX1BSSU1BUllfUCAoYmluZm8pKQoJICAgIGJpbmZvID0gQklORk9fSU5IRVJJVEFOQ0VfQ0hBSU4gKGJpbmZvKTsKCX0KICAgIH0KICAKICAvKiBBZGQgdGhlIGluaXRpYWxpemVyIGZvciB0aGUgc2Vjb25kYXJ5IHZwdHIgaXRzZWxmLiAgKi8KICBkYXRhLT5pbml0cyA9IHRyZWVfY29ucyAoTlVMTF9UUkVFLCBiaW5mb19jdG9yX3Z0YWJsZSAoYmluZm8pLCBkYXRhLT5pbml0cyk7CgogIC8qIEFkdmFuY2UgdGhlIHZ0dCBpbmRleC4gICovCiAgZGF0YS0+aW5kZXggPSBzaXplX2Jpbm9wIChQTFVTX0VYUFIsIGRhdGEtPmluZGV4LAoJCQkgICAgVFlQRV9TSVpFX1VOSVQgKHB0cl90eXBlX25vZGUpKTsKCiAgcmV0dXJuIE5VTExfVFJFRTsKfQoKLyogQ2FsbGVkIGZyb20gYnVpbGRfdnR0X2luaXRzIHZpYSBkZnNfd2Fsay4gQWZ0ZXIgYnVpbGRpbmcKICAgY29uc3RydWN0b3IgdnRhYmxlcyBhbmQgZ2VuZXJhdGluZyB0aGUgc3ViLXZ0dCBmcm9tIHRoZW0sIHdlIG5lZWQKICAgdG8gcmVzdG9yZSB0aGUgQklORk9fVlRBQkxFUyB0aGF0IHdlcmUgc2NyaWJibGVkIG9uLiAgREFUQSBpcyB0aGUKICAgYmluZm8gb2YgdGhlIGJhc2Ugd2hvc2Ugc3ViIHZ0dCB3YXMgZ2VuZXJhdGVkLiAgKi8KCnN0YXRpYyB0cmVlCmRmc19maXh1cF9iaW5mb192dGJscyAodHJlZSBiaW5mbywgdm9pZCogZGF0YSkKewogIHRyZWUgdnRhYmxlID0gQklORk9fVlRBQkxFIChiaW5mbyk7CgogIGlmICghVFlQRV9DT05UQUlOU19WUFRSX1AgKEJJTkZPX1RZUEUgKGJpbmZvKSkpCiAgICAvKiBJZiB0aGlzIGNsYXNzIGhhcyBubyB2dGFibGUsIG5vbmUgb2YgaXRzIGJhc2VzIGRvLiAgKi8KICAgIHJldHVybiBkZnNfc2tpcF9iYXNlczsKICAKICBpZiAoIXZ0YWJsZSkKICAgIC8qIFRoaXMgbWlnaHQgYmUgYSBwcmltYXJ5IGJhc2UsIHNvIGhhdmUgbm8gdnRhYmxlIGluIHRoaXMKICAgICAgIGhpZXJhcmNoeS4gICovCiAgICByZXR1cm4gTlVMTF9UUkVFOwogIAogIC8qIElmIHdlIHNjcmliYmxlZCB0aGUgY29uc3RydWN0aW9uIHZ0YWJsZSB2cHRyIGludG8gQklORk8sIGNsZWFyIGl0CiAgICAgb3V0IG5vdy4gICovCiAgaWYgKFRSRUVfQ09ERSAodnRhYmxlKSA9PSBUUkVFX0xJU1QKICAgICAgJiYgKFRSRUVfUFVSUE9TRSAodnRhYmxlKSA9PSAodHJlZSkgZGF0YSkpCiAgICBCSU5GT19WVEFCTEUgKGJpbmZvKSA9IFRSRUVfQ0hBSU4gKHZ0YWJsZSk7CgogIHJldHVybiBOVUxMX1RSRUU7Cn0KCi8qIEJ1aWxkIHRoZSBjb25zdHJ1Y3Rpb24gdnRhYmxlIGdyb3VwIGZvciBCSU5GTyB3aGljaCBpcyBpbiB0aGUKICAgaGllcmFyY2h5IGRvbWluYXRlZCBieSBULiAgKi8KCnN0YXRpYyB2b2lkCmJ1aWxkX2N0b3JfdnRibF9ncm91cCAodHJlZSBiaW5mbywgdHJlZSB0KQp7CiAgdHJlZSBsaXN0OwogIHRyZWUgdHlwZTsKICB0cmVlIHZ0Ymw7CiAgdHJlZSBpbml0czsKICB0cmVlIGlkOwogIHRyZWUgdmJhc2U7CgogIC8qIFNlZSBpZiB3ZSd2ZSBhbHJlYWR5IGNyZWF0ZWQgdGhpcyBjb25zdHJ1Y3Rpb24gdnRhYmxlIGdyb3VwLiAgKi8KICBpZCA9IG1hbmdsZV9jdG9yX3Z0YmxfZm9yX3R5cGUgKHQsIGJpbmZvKTsKICBpZiAoSURFTlRJRklFUl9HTE9CQUxfVkFMVUUgKGlkKSkKICAgIHJldHVybjsKCiAgZ2NjX2Fzc2VydCAoIVNBTUVfQklORk9fVFlQRV9QIChCSU5GT19UWVBFIChiaW5mbyksIHQpKTsKICAvKiBCdWlsZCBhIHZlcnNpb24gb2YgVlRCTCAod2l0aCB0aGUgd3JvbmcgdHlwZSkgZm9yIHVzZSBpbgogICAgIGNvbnN0cnVjdGluZyB0aGUgYWRkcmVzc2VzIG9mIHNlY29uZGFyeSB2dGFibGVzIGluIHRoZQogICAgIGNvbnN0cnVjdGlvbiB2dGFibGUgZ3JvdXAuICAqLwogIHZ0YmwgPSBidWlsZF92dGFibGUgKHQsIGlkLCBwdHJfdHlwZV9ub2RlKTsKICBERUNMX0NPTlNUUlVDVElPTl9WVEFCTEVfUCAodnRibCkgPSAxOwogIGxpc3QgPSBidWlsZF90cmVlX2xpc3QgKHZ0YmwsIE5VTExfVFJFRSk7CiAgYWNjdW11bGF0ZV92dGJsX2luaXRzIChiaW5mbywgVFlQRV9CSU5GTyAoVFJFRV9UWVBFIChiaW5mbykpLAoJCQkgYmluZm8sIHQsIGxpc3QpOwoKICAvKiBBZGQgdGhlIHZ0YWJsZXMgZm9yIGVhY2ggb2Ygb3VyIHZpcnR1YWwgYmFzZXMgdXNpbmcgdGhlIHZiYXNlIGluIFQKICAgICBiaW5mby4gICovCiAgZm9yICh2YmFzZSA9IFRZUEVfQklORk8gKEJJTkZPX1RZUEUgKGJpbmZvKSk7IAogICAgICAgdmJhc2U7IAogICAgICAgdmJhc2UgPSBUUkVFX0NIQUlOICh2YmFzZSkpCiAgICB7CiAgICAgIHRyZWUgYjsKCiAgICAgIGlmICghQklORk9fVklSVFVBTF9QICh2YmFzZSkpCgljb250aW51ZTsKICAgICAgYiA9IGNvcGllZF9iaW5mbyAodmJhc2UsIGJpbmZvKTsKICAgICAgCiAgICAgIGFjY3VtdWxhdGVfdnRibF9pbml0cyAoYiwgdmJhc2UsIGJpbmZvLCB0LCBsaXN0KTsKICAgIH0KICBpbml0cyA9IFRSRUVfVkFMVUUgKGxpc3QpOwoKICAvKiBGaWd1cmUgb3V0IHRoZSB0eXBlIG9mIHRoZSBjb25zdHJ1Y3Rpb24gdnRhYmxlLiAgKi8KICB0eXBlID0gYnVpbGRfaW5kZXhfdHlwZSAoc2l6ZV9pbnQgKGxpc3RfbGVuZ3RoIChpbml0cykgLSAxKSk7CiAgdHlwZSA9IGJ1aWxkX2NwbHVzX2FycmF5X3R5cGUgKHZ0YWJsZV9lbnRyeV90eXBlLCB0eXBlKTsKICBUUkVFX1RZUEUgKHZ0YmwpID0gdHlwZTsKCiAgLyogSW5pdGlhbGl6ZSB0aGUgY29uc3RydWN0aW9uIHZ0YWJsZS4gICovCiAgQ0xBU1NUWVBFX1ZUQUJMRVMgKHQpID0gY2hhaW5vbiAoQ0xBU1NUWVBFX1ZUQUJMRVMgKHQpLCB2dGJsKTsKICBpbml0aWFsaXplX2FydGlmaWNpYWxfdmFyICh2dGJsLCBpbml0cyk7CiAgZHVtcF92dGFibGUgKHQsIGJpbmZvLCB2dGJsKTsKfQoKLyogQWRkIHRoZSB2dGJsIGluaXRpYWxpemVycyBmb3IgQklORk8gKGFuZCBpdHMgYmFzZXMgb3RoZXIgdGhhbgogICBub24tdmlydHVhbCBwcmltYXJpZXMpIHRvIHRoZSBsaXN0IG9mIElOSVRTLiAgQklORk8gaXMgaW4gdGhlCiAgIGhpZXJhcmNoeSBkb21pbmF0ZWQgYnkgVC4gIFJUVElfQklORk8gaXMgdGhlIGJpbmZvIHdpdGhpbiBUIG9mCiAgIHRoZSBjb25zdHJ1Y3RvciB0aGUgdnRibCBpbml0cyBzaG91bGQgYmUgYWNjdW11bGF0ZWQgZm9yLiAoSWYgdGhpcwogICBpcyB0aGUgY29tcGxldGUgb2JqZWN0IHZ0YmwgdGhlbiBSVFRJX0JJTkZPIHdpbGwgYmUgVFlQRV9CSU5GTyAoVCkuKQogICBPUklHX0JJTkZPIGlzIHRoZSBiaW5mbyBmb3IgdGhpcyBvYmplY3Qgd2l0aGluIEJJTkZPX1RZUEUgKFJUVElfQklORk8pLgogICBCSU5GTyBpcyB0aGUgYWN0aXZlIGJhc2UgZXF1aXZhbGVudCBvZiBPUklHX0JJTkZPIGluIHRoZSBpbmhlcml0YW5jZQogICBncmFwaCBvZiBULiBCb3RoIEJJTkZPIGFuZCBPUklHX0JJTkZPIHdpbGwgaGF2ZSB0aGUgc2FtZSBCSU5GT19UWVBFLAogICBidXQgYXJlIG5vdCBuZWNlc3NhcmlseSB0aGUgc2FtZSBpbiB0ZXJtcyBvZiBsYXlvdXQuICAqLwoKc3RhdGljIHZvaWQKYWNjdW11bGF0ZV92dGJsX2luaXRzICh0cmVlIGJpbmZvLAogICAgICAgICAgICAgICAgICAgICAgIHRyZWUgb3JpZ19iaW5mbywKICAgICAgICAgICAgICAgICAgICAgICB0cmVlIHJ0dGlfYmluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgdHJlZSB0LAogICAgICAgICAgICAgICAgICAgICAgIHRyZWUgaW5pdHMpCnsKICBpbnQgaTsKICB0cmVlIGJhc2VfYmluZm87CiAgaW50IGN0b3JfdnRibF9wID0gIVNBTUVfQklORk9fVFlQRV9QIChCSU5GT19UWVBFIChydHRpX2JpbmZvKSwgdCk7CgogIGdjY19hc3NlcnQgKFNBTUVfQklORk9fVFlQRV9QIChCSU5GT19UWVBFIChiaW5mbyksIEJJTkZPX1RZUEUgKG9yaWdfYmluZm8pKSk7CgogIC8qIElmIGl0IGRvZXNuJ3QgaGF2ZSBhIHZwdHIsIHdlIGRvbid0IGRvIGFueXRoaW5nLiAgKi8KICBpZiAoIVRZUEVfQ09OVEFJTlNfVlBUUl9QIChCSU5GT19UWVBFIChiaW5mbykpKQogICAgcmV0dXJuOwogIAogIC8qIElmIHdlJ3JlIGJ1aWxkaW5nIGEgY29uc3RydWN0aW9uIHZ0YWJsZSwgd2UncmUgbm90IGludGVyZXN0ZWQgaW4KICAgICBzdWJvYmplY3RzIHRoYXQgZG9uJ3QgcmVxdWlyZSBjb25zdHJ1Y3Rpb24gdnRhYmxlcy4gICovCiAgaWYgKGN0b3JfdnRibF9wIAogICAgICAmJiAhQ0xBU1NUWVBFX1ZCQVNFQ0xBU1NFUyAoQklORk9fVFlQRSAoYmluZm8pKQogICAgICAmJiAhYmluZm9fdmlhX3ZpcnR1YWwgKG9yaWdfYmluZm8sIEJJTkZPX1RZUEUgKHJ0dGlfYmluZm8pKSkKICAgIHJldHVybjsKCiAgLyogQnVpbGQgdGhlIGluaXRpYWxpemVycyBmb3IgdGhlIEJJTkZPLWluLVQgdnRhYmxlLiAgKi8KICBUUkVFX1ZBTFVFIChpbml0cykgCiAgICA9IGNoYWlub24gKFRSRUVfVkFMVUUgKGluaXRzKSwKCSAgICAgICBkZnNfYWNjdW11bGF0ZV92dGJsX2luaXRzIChiaW5mbywgb3JpZ19iaW5mbywKCQkJCQkgIHJ0dGlfYmluZm8sIHQsIGluaXRzKSk7CgkJICAgICAgCiAgLyogV2FsayB0aGUgQklORk8gYW5kIGl0cyBiYXNlcy4gIFdlIHdhbGsgaW4gcHJlb3JkZXIgc28gdGhhdCBhcyB3ZQogICAgIGluaXRpYWxpemUgZWFjaCB2dGFibGUgd2UgY2FuIGZpZ3VyZSBvdXQgYXQgd2hhdCBvZmZzZXQgdGhlCiAgICAgc2Vjb25kYXJ5IHZ0YWJsZSBsaWVzIGZyb20gdGhlIHByaW1hcnkgdnRhYmxlLiAgV2UgY2FuJ3QgdXNlCiAgICAgZGZzX3dhbGsgaGVyZSBiZWNhdXNlIHdlIG5lZWQgdG8gaXRlcmF0ZSB0aHJvdWdoIGJhc2VzIG9mIEJJTkZPCiAgICAgYW5kIFJUVElfQklORk8gc2ltdWx0YW5lb3VzbHkuICAqLwogIGZvciAoaSA9IDA7IEJJTkZPX0JBU0VfSVRFUkFURSAoYmluZm8sIGksIGJhc2VfYmluZm8pOyArK2kpCiAgICB7CiAgICAgIC8qIFNraXAgdmlydHVhbCBiYXNlcy4gICovCiAgICAgIGlmIChCSU5GT19WSVJUVUFMX1AgKGJhc2VfYmluZm8pKQoJY29udGludWU7CiAgICAgIGFjY3VtdWxhdGVfdnRibF9pbml0cyAoYmFzZV9iaW5mbywKCQkJICAgICBCSU5GT19CQVNFX0JJTkZPIChvcmlnX2JpbmZvLCBpKSwKCQkJICAgICBydHRpX2JpbmZvLCB0LAoJCQkgICAgIGluaXRzKTsKICAgIH0KfQoKLyogQ2FsbGVkIGZyb20gYWNjdW11bGF0ZV92dGJsX2luaXRzLiAgUmV0dXJucyB0aGUgaW5pdGlhbGl6ZXJzIGZvcgogICB0aGUgQklORk8gdnRhYmxlLiAgKi8KCnN0YXRpYyB0cmVlCmRmc19hY2N1bXVsYXRlX3Z0YmxfaW5pdHMgKHRyZWUgYmluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyZWUgb3JpZ19iaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZSBydHRpX2JpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICB0cmVlIHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyZWUgbCkKewogIHRyZWUgaW5pdHMgPSBOVUxMX1RSRUU7CiAgdHJlZSB2dGJsID0gTlVMTF9UUkVFOwogIGludCBjdG9yX3Z0YmxfcCA9ICFTQU1FX0JJTkZPX1RZUEVfUCAoQklORk9fVFlQRSAocnR0aV9iaW5mbyksIHQpOwoKICBpZiAoY3Rvcl92dGJsX3AKICAgICAgJiYgQklORk9fVklSVFVBTF9QIChvcmlnX2JpbmZvKSAmJiBCSU5GT19QUklNQVJZX1AgKG9yaWdfYmluZm8pKQogICAgewogICAgICAvKiBJbiB0aGUgaGllcmFyY2h5IG9mIEJJTkZPX1RZUEUgKFJUVElfQklORk8pLCB0aGlzIGlzIGEKCSBwcmltYXJ5IHZpcnR1YWwgYmFzZS4gIElmIGl0IGlzIG5vdCB0aGUgc2FtZSBwcmltYXJ5IGluCgkgdGhlIGhpZXJhcmNoeSBvZiBULCB3ZSdsbCBuZWVkIHRvIGdlbmVyYXRlIGEgY3RvciB2dGFibGUKCSBmb3IgaXQsIHRvIHBsYWNlIGF0IGl0cyBsb2NhdGlvbiBpbiBULiAgSWYgaXQgaXMgdGhlIHNhbWUKCSBwcmltYXJ5LCB3ZSBzdGlsbCBuZWVkIGEgVlRUIGVudHJ5IGZvciB0aGUgdnRhYmxlLCBidXQgaXQKCSBzaG91bGQgcG9pbnQgdG8gdGhlIGN0b3IgdnRhYmxlIGZvciB0aGUgYmFzZSBpdCBpcyBhCgkgcHJpbWFyeSBmb3Igd2l0aGluIHRoZSBzdWItaGllcmFyY2h5IG9mIFJUVElfQklORk8uCgkgICAgICAKCSBUaGVyZSBhcmUgdGhyZWUgcG9zc2libGUgY2FzZXM6CgkgICAgICAKCSAxKSBXZSBhcmUgaW4gdGhlIHNhbWUgcGxhY2UuCgkgMikgV2UgYXJlIGEgcHJpbWFyeSBiYXNlIHdpdGhpbiBhIGxvc3QgcHJpbWFyeSB2aXJ0dWFsIGJhc2Ugb2YKCSBSVFRJX0JJTkZPLgoJIDMpIFdlIGFyZSBwcmltYXJ5IHRvIHNvbWV0aGluZyBub3QgYSBiYXNlIG9mIFJUVElfQklORk8uICAqLwoJICAKICAgICAgdHJlZSBiOwogICAgICB0cmVlIGxhc3QgPSBOVUxMX1RSRUU7CgogICAgICAvKiBGaXJzdCwgbG9vayB0aHJvdWdoIHRoZSBiYXNlcyB3ZSBhcmUgcHJpbWFyeSB0byBmb3IgUlRUSV9CSU5GTwoJIG9yIGEgdmlydHVhbCBiYXNlLiAgKi8KICAgICAgYiA9IGJpbmZvOwogICAgICB3aGlsZSAoQklORk9fUFJJTUFSWV9QIChiKSkKCXsKCSAgYiA9IEJJTkZPX0lOSEVSSVRBTkNFX0NIQUlOIChiKTsKCSAgbGFzdCA9IGI7CgkgIGlmIChCSU5GT19WSVJUVUFMX1AgKGIpIHx8IGIgPT0gcnR0aV9iaW5mbykKCSAgICBnb3RvIGZvdW5kOwoJfQogICAgICAvKiBJZiB3ZSBydW4gb3V0IG9mIHByaW1hcnkgbGlua3MsIGtlZXAgbG9va2luZyBkb3duIG91cgoJIGluaGVyaXRhbmNlIGNoYWluOyB3ZSBtaWdodCBiZSBhbiBpbmRpcmVjdCBwcmltYXJ5LiAgKi8KICAgICAgZm9yIChiID0gbGFzdDsgYjsgYiA9IEJJTkZPX0lOSEVSSVRBTkNFX0NIQUlOIChiKSkKCWlmIChCSU5GT19WSVJUVUFMX1AgKGIpIHx8IGIgPT0gcnR0aV9iaW5mbykKCSAgYnJlYWs7CiAgICBmb3VuZDoKICAgICAgCiAgICAgIC8qIElmIHdlIGZvdW5kIFJUVElfQklORk8sIHRoaXMgaXMgY2FzZSAxLiAgSWYgd2UgZm91bmQgYSB2aXJ0dWFsCgkgYmFzZSBCIGFuZCBpdCBpcyBhIGJhc2Ugb2YgUlRUSV9CSU5GTywgdGhpcyBpcyBjYXNlIDIuICBJbgoJIGVpdGhlciBjYXNlLCB3ZSBzaGFyZSBvdXIgdnRhYmxlIHdpdGggTEFTVCwgaS5lLiB0aGUKCSBkZXJpdmVkLW1vc3QgYmFzZSB3aXRoaW4gQiBvZiB3aGljaCB3ZSBhcmUgYSBwcmltYXJ5LiAgKi8KICAgICAgaWYgKGIgPT0gcnR0aV9iaW5mbwoJICB8fCAoYiAmJiBiaW5mb19mb3JfdmJhc2UgKEJJTkZPX1RZUEUgKGIpLCBCSU5GT19UWVBFIChydHRpX2JpbmZvKSkpKQoJLyogSnVzdCBzZXQgb3VyIEJJTkZPX1ZUQUJMRSB0byBwb2ludCB0byBMQVNULCBhcyB3ZSBtYXkgbm90IGhhdmUKCSAgIHNldCBMQVNUJ3MgQklORk9fVlRBQkxFIHlldC4gIFdlJ2xsIGV4dHJhY3QgdGhlIGFjdHVhbCB2cHRyIGluCgkgICBiaW5mb19jdG9yX3Z0YWJsZSBhZnRlciBldmVyeXRoaW5nJ3MgYmVlbiBzZXQgdXAuICAqLwoJdnRibCA9IGxhc3Q7CgogICAgICAvKiBPdGhlcndpc2UsIHRoaXMgaXMgY2FzZSAzIGFuZCB3ZSBnZXQgb3VyIG93bi4gICovCiAgICB9CiAgZWxzZSBpZiAoIUJJTkZPX05FV19WVEFCTEVfTUFSS0VEIChvcmlnX2JpbmZvKSkKICAgIHJldHVybiBpbml0czsKCiAgaWYgKCF2dGJsKQogICAgewogICAgICB0cmVlIGluZGV4OwogICAgICBpbnQgbm9uX2ZuX2VudHJpZXM7CgogICAgICAvKiBDb21wdXRlIHRoZSBpbml0aWFsaXplciBmb3IgdGhpcyB2dGFibGUuICAqLwogICAgICBpbml0cyA9IGJ1aWxkX3Z0YmxfaW5pdGlhbGl6ZXIgKGJpbmZvLCBvcmlnX2JpbmZvLCB0LCBydHRpX2JpbmZvLAoJCQkJICAgICAgJm5vbl9mbl9lbnRyaWVzKTsKCiAgICAgIC8qIEZpZ3VyZSBvdXQgdGhlIHBvc2l0aW9uIHRvIHdoaWNoIHRoZSBWUFRSIHNob3VsZCBwb2ludC4gICovCiAgICAgIHZ0YmwgPSBUUkVFX1BVUlBPU0UgKGwpOwogICAgICB2dGJsID0gYnVpbGQxIChBRERSX0VYUFIsIHZ0YmxfcHRyX3R5cGVfbm9kZSwgdnRibCk7CiAgICAgIGluZGV4ID0gc2l6ZV9iaW5vcCAoUExVU19FWFBSLAoJCQkgIHNpemVfaW50IChub25fZm5fZW50cmllcyksCgkJCSAgc2l6ZV9pbnQgKGxpc3RfbGVuZ3RoIChUUkVFX1ZBTFVFIChsKSkpKTsKICAgICAgaW5kZXggPSBzaXplX2Jpbm9wIChNVUxUX0VYUFIsCgkJCSAgVFlQRV9TSVpFX1VOSVQgKHZ0YWJsZV9lbnRyeV90eXBlKSwKCQkJICBpbmRleCk7CiAgICAgIC8qIEFQUExFIExPQ0FMIGJlZ2luIEtFWFQgZG91YmxlIGRlc3RydWN0b3IgKi8KI2lmZGVmIFZQVFJfSU5JVElBTElaRVJfQURKVVNUTUVOVAogICAgICAvKiBTdWJ0cmFjdCBWUFRSX0lOSVRJQUxJWkVSX0FESlVTVE1FTlQgZnJvbSBJTkRFWC4gICovCiAgICAgIGlmIChUQVJHRVRfS0VYVEFCSSAmJiAhY3Rvcl92dGJsX3AgJiYgISBCSU5GT19QUklNQVJZX1AgKGJpbmZvKQoJICAmJiBUUkVFX0NPREUgKGluZGV4KSA9PSBJTlRFR0VSX0NTVAoJICAmJiBUUkVFX0lOVF9DU1RfTE9XIChpbmRleCkgPj0gVlBUUl9JTklUSUFMSVpFUl9BREpVU1RNRU5UCgkgICYmIFRSRUVfSU5UX0NTVF9ISUdIIChpbmRleCkgPT0gMCkKCWluZGV4ID0gZm9sZCAoYnVpbGQgKE1JTlVTX0VYUFIsCgkJCSAgICAgVFJFRV9UWVBFIChpbmRleCksIGluZGV4LAoJCQkgICAgIHNpemVfaW50IChWUFRSX0lOSVRJQUxJWkVSX0FESlVTVE1FTlQpKSk7CiNlbmRpZgogICAgICAvKiBBUFBMRSBMT0NBTCBlbmQgS0VYVCBkb3VibGUgZGVzdHJ1Y3RvciAqLwoKICAgICAgdnRibCA9IGJ1aWxkMiAoUExVU19FWFBSLCBUUkVFX1RZUEUgKHZ0YmwpLCB2dGJsLCBpbmRleCk7CiAgICB9CgogIGlmIChjdG9yX3Z0YmxfcCkKICAgIC8qIEZvciBhIGNvbnN0cnVjdGlvbiB2dGFibGUsIHdlIGNhbid0IG92ZXJ3cml0ZSBCSU5GT19WVEFCTEUuCiAgICAgICBTbywgd2UgbWFrZSBhIFRSRUVfTElTVC4gIExhdGVyLCBkZnNfZml4dXBfYmluZm9fdnRibHMgd2lsbAogICAgICAgc3RyYWlnaHRlbiB0aGlzIG91dC4gICovCiAgICBCSU5GT19WVEFCTEUgKGJpbmZvKSA9IHRyZWVfY29ucyAocnR0aV9iaW5mbywgdnRibCwgQklORk9fVlRBQkxFIChiaW5mbykpOwogIGVsc2UgaWYgKEJJTkZPX1BSSU1BUllfUCAoYmluZm8pICYmIEJJTkZPX1ZJUlRVQUxfUCAoYmluZm8pKQogICAgaW5pdHMgPSBOVUxMX1RSRUU7CiAgZWxzZQogICAgIC8qIEZvciBhbiBvcmRpbmFyeSB2dGFibGUsIHNldCBCSU5GT19WVEFCTEUuICAqLwogICAgQklORk9fVlRBQkxFIChiaW5mbykgPSB2dGJsOwoKICByZXR1cm4gaW5pdHM7Cn0KCnN0YXRpYyBHVFkoKCkpIHRyZWUgYWJvcnRfZm5kZWNsX2FkZHI7CgovKiBDb25zdHJ1Y3QgdGhlIGluaXRpYWxpemVyIGZvciBCSU5GTydzIHZpcnR1YWwgZnVuY3Rpb24gdGFibGUuICBCSU5GTwogICBpcyBwYXJ0IG9mIHRoZSBoaWVyYXJjaHkgZG9taW5hdGVkIGJ5IFQuICBJZiB3ZSdyZSBidWlsZGluZyBhCiAgIGNvbnN0cnVjdGlvbiB2dGFibGUsIHRoZSBPUklHX0JJTkZPIGlzIHRoZSBiaW5mbyB3ZSBzaG91bGQgdXNlIHRvCiAgIGZpbmQgdGhlIGFjdHVhbCBmdW5jdGlvbiBwb2ludGVycyB0byBwdXQgaW4gdGhlIHZ0YWJsZSAtIGJ1dCB0aGV5CiAgIGNhbiBiZSBvdmVycmlkZGVuIG9uIHRoZSBwYXRoIHRvIG1vc3QtZGVyaXZlZCBpbiB0aGUgZ3JhcGggdGhhdAogICBPUklHX0JJTkZPIGJlbG9uZ3MuICBPdGhlcndpc2UsCiAgIE9SSUdfQklORk8gc2hvdWxkIGJlIHRoZSBzYW1lIGFzIEJJTkZPLiAgVGhlIFJUVElfQklORk8gaXMgdGhlCiAgIEJJTkZPIHRoYXQgc2hvdWxkIGJlIGluZGljYXRlZCBieSB0aGUgUlRUSSBpbmZvcm1hdGlvbiBpbiB0aGUKICAgdnRhYmxlOyBpdCB3aWxsIGJlIGEgYmFzZSBjbGFzcyBvZiBULCByYXRoZXIgdGhhbiBUIGl0c2VsZiwgaWYgd2UKICAgYXJlIGJ1aWxkaW5nIGEgY29uc3RydWN0aW9uIHZ0YWJsZS4KCiAgIFRoZSB2YWx1ZSByZXR1cm5lZCBpcyBhIFRSRUVfTElTVCBzdWl0YWJsZSBmb3Igd3JhcHBpbmcgaW4gYQogICBDT05TVFJVQ1RPUiB0byB1c2UgYXMgdGhlIERFQ0xfSU5JVElBTCBmb3IgYSB2dGFibGUuICBJZgogICBOT05fRk5fRU5UUklFU19QIGlzIG5vdCBOVUxMLCAqTk9OX0ZOX0VOVFJJRVNfUCBpcyBzZXQgdG8gdGhlCiAgIG51bWJlciBvZiBub24tZnVuY3Rpb24gZW50cmllcyBpbiB0aGUgdnRhYmxlLiAgCgogICBJdCBtaWdodCBzZWVtIHRoYXQgdGhpcyBmdW5jdGlvbiBzaG91bGQgbmV2ZXIgYmUgY2FsbGVkIHdpdGggYQogICBCSU5GTyBmb3Igd2hpY2ggQklORk9fUFJJTUFSWV9QIGhvbGRzLCB0aGUgdnRhYmxlIGZvciBzdWNoIGEKICAgYmFzZSBpcyBhbHdheXMgc3Vic3VtZWQgYnkgYSBkZXJpdmVkIGNsYXNzIHZ0YWJsZS4gIEhvd2V2ZXIsIHdoZW4KICAgd2UgYXJlIGJ1aWxkaW5nIGNvbnN0cnVjdGlvbiB2dGFibGVzLCB3ZSBkbyBidWlsZCB2dGFibGVzIGZvcgogICBwcmltYXJ5IGJhc2VzOyB3ZSBuZWVkIHRoZXNlIHdoaWxlIHRoZSBwcmltYXJ5IGJhc2UgaXMgYmVpbmcKICAgY29uc3RydWN0ZWQuICAqLwoKc3RhdGljIHRyZWUKYnVpbGRfdnRibF9pbml0aWFsaXplciAodHJlZSBiaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgdHJlZSBvcmlnX2JpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICB0cmVlIHQsCiAgICAgICAgICAgICAgICAgICAgICAgIHRyZWUgcnR0aV9iaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgaW50KiBub25fZm5fZW50cmllc19wKQp7CiAgdHJlZSB2LCBiOwogIHRyZWUgdmZ1bl9pbml0czsKICB2dGJsX2luaXRfZGF0YSB2aWQ7CiAgdW5zaWduZWQgaXg7CiAgdHJlZSB2YmluZm87CiAgVkVDICh0cmVlKSAqdmJhc2VzOwogIAogIC8qIEluaXRpYWxpemUgVklELiAgKi8KICBtZW1zZXQgKCZ2aWQsIDAsIHNpemVvZiAodmlkKSk7CiAgdmlkLmJpbmZvID0gYmluZm87CiAgdmlkLmRlcml2ZWQgPSB0OwogIHZpZC5ydHRpX2JpbmZvID0gcnR0aV9iaW5mbzsKICB2aWQubGFzdF9pbml0ID0gJnZpZC5pbml0czsKICB2aWQucHJpbWFyeV92dGJsX3AgPSBTQU1FX0JJTkZPX1RZUEVfUCAoQklORk9fVFlQRSAoYmluZm8pLCB0KTsKICB2aWQuY3Rvcl92dGJsX3AgPSAhU0FNRV9CSU5GT19UWVBFX1AgKEJJTkZPX1RZUEUgKHJ0dGlfYmluZm8pLCB0KTsKICB2aWQuZ2VuZXJhdGVfdmNhbGxfZW50cmllcyA9IHRydWU7CiAgLyogVGhlIGZpcnN0IHZiYXNlIG9yIHZjYWxsIG9mZnNldCBpcyBhdCBpbmRleCAtMyBpbiB0aGUgdnRhYmxlLiAgKi8KICB2aWQuaW5kZXggPSBzc2l6ZV9pbnQoLTMgKiBUQVJHRVRfVlRBQkxFX0RBVEFfRU5UUllfRElTVEFOQ0UpOwoKICAvKiBBZGQgZW50cmllcyB0byB0aGUgdnRhYmxlIGZvciBSVFRJLiAgKi8KICBidWlsZF9ydHRpX3Z0YmxfZW50cmllcyAoYmluZm8sICZ2aWQpOwoKICAvKiBDcmVhdGUgYW4gYXJyYXkgZm9yIGtlZXBpbmcgdHJhY2sgb2YgdGhlIGZ1bmN0aW9ucyB3ZSd2ZQogICAgIHByb2Nlc3NlZC4gIFdoZW4gd2Ugc2VlIG11bHRpcGxlIGZ1bmN0aW9ucyB3aXRoIHRoZSBzYW1lCiAgICAgc2lnbmF0dXJlLCB3ZSBzaGFyZSB0aGUgdmNhbGwgb2Zmc2V0cy4gICovCiAgVkFSUkFZX1RSRUVfSU5JVCAodmlkLmZucywgMzIsICJmbnMiKTsKICAvKiBBZGQgdGhlIHZjYWxsIGFuZCB2YmFzZSBvZmZzZXQgZW50cmllcy4gICovCiAgYnVpbGRfdmNhbGxfYW5kX3ZiYXNlX3Z0YmxfZW50cmllcyAoYmluZm8sICZ2aWQpOwogIAogIC8qIENsZWFyIEJJTkZPX1ZUQUJMRV9QQVRIX01BUktFRDsgaXQncyBzZXQgYnkKICAgICBidWlsZF92YmFzZV9vZmZzZXRfdnRibF9lbnRyaWVzLiAgKi8KICBmb3IgKHZiYXNlcyA9IENMQVNTVFlQRV9WQkFTRUNMQVNTRVMgKHQpLCBpeCA9IDA7CiAgICAgICBWRUNfaXRlcmF0ZSAodHJlZSwgdmJhc2VzLCBpeCwgdmJpbmZvKTsgaXgrKykKICAgIEJJTkZPX1ZUQUJMRV9QQVRIX01BUktFRCAodmJpbmZvKSA9IDA7CgogIC8qIElmIHRoZSB0YXJnZXQgcmVxdWlyZXMgcGFkZGluZyBiZXR3ZWVuIGRhdGEgZW50cmllcywgYWRkIHRoYXQgbm93LiAgKi8KICBpZiAoVEFSR0VUX1ZUQUJMRV9EQVRBX0VOVFJZX0RJU1RBTkNFID4gMSkKICAgIHsKICAgICAgdHJlZSBjdXIsICpwcmV2OwoKICAgICAgZm9yIChwcmV2ID0gJnZpZC5pbml0czsgKGN1ciA9ICpwcmV2KTsgcHJldiA9ICZUUkVFX0NIQUlOIChjdXIpKQoJewoJICB0cmVlIGFkZCA9IGN1cjsKCSAgaW50IGk7CgoJICBmb3IgKGkgPSAxOyBpIDwgVEFSR0VUX1ZUQUJMRV9EQVRBX0VOVFJZX0RJU1RBTkNFOyArK2kpCgkgICAgYWRkID0gdHJlZV9jb25zIChOVUxMX1RSRUUsCgkJCSAgICAgYnVpbGQxIChOT1BfRVhQUiwgdnRhYmxlX2VudHJ5X3R5cGUsCgkJCQkgICAgIG51bGxfcG9pbnRlcl9ub2RlKSwKCQkJICAgICBhZGQpOwoJICAqcHJldiA9IGFkZDsKCX0KICAgIH0KCiAgaWYgKG5vbl9mbl9lbnRyaWVzX3ApCiAgICAqbm9uX2ZuX2VudHJpZXNfcCA9IGxpc3RfbGVuZ3RoICh2aWQuaW5pdHMpOwoKICAvKiBHbyB0aHJvdWdoIGFsbCB0aGUgb3JkaW5hcnkgdmlydHVhbCBmdW5jdGlvbnMsIGJ1aWxkaW5nIHVwCiAgICAgaW5pdGlhbGl6ZXJzLiAgKi8KICB2ZnVuX2luaXRzID0gTlVMTF9UUkVFOwogIGZvciAodiA9IEJJTkZPX1ZJUlRVQUxTIChvcmlnX2JpbmZvKTsgdjsgdiA9IFRSRUVfQ0hBSU4gKHYpKQogICAgewogICAgICB0cmVlIGRlbHRhOwogICAgICB0cmVlIHZjYWxsX2luZGV4OwogICAgICB0cmVlIGZuLCBmbl9vcmlnaW5hbDsKICAgICAgdHJlZSBpbml0ID0gTlVMTF9UUkVFOwogICAgICAKICAgICAgZm4gPSBCVl9GTiAodik7CiAgICAgIGZuX29yaWdpbmFsID0gZm47CiAgICAgIGlmIChERUNMX1RIVU5LX1AgKGZuKSkKCXsKCSAgaWYgKCFERUNMX05BTUUgKGZuKSkKCSAgICBmaW5pc2hfdGh1bmsgKGZuKTsKCSAgaWYgKFRIVU5LX0FMSUFTIChmbikpCgkgICAgewoJICAgICAgZm4gPSBUSFVOS19BTElBUyAoZm4pOwoJICAgICAgQlZfRk4gKHYpID0gZm47CgkgICAgfQoJICBmbl9vcmlnaW5hbCA9IFRIVU5LX1RBUkdFVCAoZm4pOwoJfQogICAgICAKICAgICAgLyogSWYgdGhlIG9ubHkgZGVmaW5pdGlvbiBvZiB0aGlzIGZ1bmN0aW9uIHNpZ25hdHVyZSBhbG9uZyBvdXIKCSBwcmltYXJ5IGJhc2UgY2hhaW4gaXMgZnJvbSBhIGxvc3QgcHJpbWFyeSwgdGhpcyB2dGFibGUgc2xvdCB3aWxsCgkgbmV2ZXIgYmUgdXNlZCwgc28ganVzdCB6ZXJvIGl0IG91dC4gIFRoaXMgaXMgaW1wb3J0YW50IHRvIGF2b2lkCgkgcmVxdWlyaW5nIGV4dHJhIHRodW5rcyB3aGljaCBjYW5ub3QgYmUgZ2VuZXJhdGVkIHdpdGggdGhlIGZ1bmN0aW9uLgoKCSBXZSBmaXJzdCBjaGVjayB0aGlzIGluIHVwZGF0ZV92dGFibGVfZW50cnlfZm9yX2ZuLCBzbyB3ZSBoYW5kbGUKCSByZXN0b3JlZCBwcmltYXJ5IGJhc2VzIHByb3Blcmx5OyB3ZSBhbHNvIG5lZWQgdG8gZG8gaXQgaGVyZSBzbyB3ZQoJIHplcm8gb3V0IHVudXNlZCBzbG90cyBpbiBjdG9yIHZ0YWJsZXMsIHJhdGhlciB0aGFuIGZpbGxpbmcgdGhlbWZmCgkgd2l0aCBlcnJvbmVvdXMgdmFsdWVzICh0aG91Z2ggaGFybWxlc3MsIGFwYXJ0IGZyb20gcmVsb2NhdGlvbgoJIGNvc3RzKS4gICovCiAgICAgIGZvciAoYiA9IGJpbmZvOyA7IGIgPSBnZXRfcHJpbWFyeV9iaW5mbyAoYikpCgl7CgkgIC8qIFdlIGZvdW5kIGEgZGVmbiBiZWZvcmUgYSBsb3N0IHByaW1hcnk7IGdvIGFoZWFkIGFzIG5vcm1hbC4gICovCgkgIGlmIChsb29rX2Zvcl9vdmVycmlkZXNfaGVyZSAoQklORk9fVFlQRSAoYiksIGZuX29yaWdpbmFsKSkKCSAgICBicmVhazsKCgkgIC8qIFRoZSBuZWFyZXN0IGRlZmluaXRpb24gaXMgZnJvbSBhIGxvc3QgcHJpbWFyeTsgY2xlYXIgdGhlCgkgICAgIHNsb3QuICAqLwoJICBpZiAoQklORk9fTE9TVF9QUklNQVJZX1AgKGIpKQoJICAgIHsKCSAgICAgIGluaXQgPSBzaXplX3plcm9fbm9kZTsKCSAgICAgIGJyZWFrOwoJICAgIH0KCX0KCiAgICAgIGlmICghIGluaXQpCgl7CgkgIC8qIFB1bGwgdGhlIG9mZnNldCBmb3IgYHRoaXMnLCBhbmQgdGhlIGZ1bmN0aW9uIHRvIGNhbGwsIG91dCBvZgoJICAgICB0aGUgbGlzdC4gICovCgkgIGRlbHRhID0gQlZfREVMVEEgKHYpOwoJICB2Y2FsbF9pbmRleCA9IEJWX1ZDQUxMX0lOREVYICh2KTsKCgkgIGdjY19hc3NlcnQgKFRSRUVfQ09ERSAoZGVsdGEpID09IElOVEVHRVJfQ1NUKTsKCSAgZ2NjX2Fzc2VydCAoVFJFRV9DT0RFIChmbikgPT0gRlVOQ1RJT05fREVDTCk7CgoJICAvKiBZb3UgY2FuJ3QgY2FsbCBhbiBhYnN0cmFjdCB2aXJ0dWFsIGZ1bmN0aW9uOyBpdCdzIGFic3RyYWN0LgoJICAgICBTbywgd2UgcmVwbGFjZSB0aGVzZSBmdW5jdGlvbnMgd2l0aCBfX3B1cmVfdmlydHVhbC4gICovCgkgIGlmIChERUNMX1BVUkVfVklSVFVBTF9QIChmbl9vcmlnaW5hbCkpCgkgICAgewoJICAgICAgZm4gPSBhYm9ydF9mbmRlY2w7CgkgICAgICBpZiAoYWJvcnRfZm5kZWNsX2FkZHIgPT0gTlVMTCkKCQlhYm9ydF9mbmRlY2xfYWRkciA9IGJ1aWxkMSAoQUREUl9FWFBSLCB2ZnVuY19wdHJfdHlwZV9ub2RlLCBmbik7CgkgICAgICBpbml0ID0gYWJvcnRfZm5kZWNsX2FkZHI7CgkgICAgfQoJICBlbHNlCgkgICAgewoJICAgICAgaWYgKCFpbnRlZ2VyX3plcm9wIChkZWx0YSkgfHwgdmNhbGxfaW5kZXgpCgkJewoJCSAgZm4gPSBtYWtlX3RodW5rIChmbiwgLyp0aGlzX2FkanVzdGluZz0qLzEsIGRlbHRhLCB2Y2FsbF9pbmRleCk7CgkJICBpZiAoIURFQ0xfTkFNRSAoZm4pKQoJCSAgICBmaW5pc2hfdGh1bmsgKGZuKTsKCQl9CgkgICAgICAvKiBUYWtlIHRoZSBhZGRyZXNzIG9mIHRoZSBmdW5jdGlvbiwgY29uc2lkZXJpbmcgaXQgdG8gYmUgb2YgYW4KCQkgYXBwcm9wcmlhdGUgZ2VuZXJpYyB0eXBlLiAgKi8KCSAgICAgIGluaXQgPSBidWlsZDEgKEFERFJfRVhQUiwgdmZ1bmNfcHRyX3R5cGVfbm9kZSwgZm4pOwoJICAgIH0KCX0KCiAgICAgIC8qIEFuZCBhZGQgaXQgdG8gdGhlIGNoYWluIG9mIGluaXRpYWxpemVycy4gICovCiAgICAgIGlmIChUQVJHRVRfVlRBQkxFX1VTRVNfREVTQ1JJUFRPUlMpCgl7CgkgIGludCBpOwoJICBpZiAoaW5pdCA9PSBzaXplX3plcm9fbm9kZSkKCSAgICBmb3IgKGkgPSAwOyBpIDwgVEFSR0VUX1ZUQUJMRV9VU0VTX0RFU0NSSVBUT1JTOyArK2kpCgkgICAgICB2ZnVuX2luaXRzID0gdHJlZV9jb25zIChOVUxMX1RSRUUsIGluaXQsIHZmdW5faW5pdHMpOwoJICBlbHNlCgkgICAgZm9yIChpID0gMDsgaSA8IFRBUkdFVF9WVEFCTEVfVVNFU19ERVNDUklQVE9SUzsgKytpKQoJICAgICAgewoJCXRyZWUgZmRlc2MgPSBidWlsZDIgKEZERVNDX0VYUFIsIHZmdW5jX3B0cl90eXBlX25vZGUsCgkJCQkgICAgIFRSRUVfT1BFUkFORCAoaW5pdCwgMCksCgkJCQkgICAgIGJ1aWxkX2ludF9jc3QgKE5VTExfVFJFRSwgaSkpOwoJCVRSRUVfQ09OU1RBTlQgKGZkZXNjKSA9IDE7CgkJVFJFRV9JTlZBUklBTlQgKGZkZXNjKSA9IDE7CgoJCXZmdW5faW5pdHMgPSB0cmVlX2NvbnMgKE5VTExfVFJFRSwgZmRlc2MsIHZmdW5faW5pdHMpOwoJICAgICAgfQoJfQogICAgICBlbHNlCiAgICAgICAgdmZ1bl9pbml0cyA9IHRyZWVfY29ucyAoTlVMTF9UUkVFLCBpbml0LCB2ZnVuX2luaXRzKTsKICAgIH0KCiAgLyogVGhlIGluaXRpYWxpemVycyBmb3IgdmlydHVhbCBmdW5jdGlvbnMgd2VyZSBidWlsdCB1cCBpbiByZXZlcnNlCiAgICAgb3JkZXI7IHN0cmFpZ2h0ZW4gdGhlbSBvdXQgbm93LiAgKi8KICB2ZnVuX2luaXRzID0gbnJldmVyc2UgKHZmdW5faW5pdHMpOwogIAogIC8qIFRoZSBuZWdhdGl2ZSBvZmZzZXQgaW5pdGlhbGl6ZXJzIGFyZSBhbHNvIGluIHJldmVyc2Ugb3JkZXIuICAqLwogIHZpZC5pbml0cyA9IG5yZXZlcnNlICh2aWQuaW5pdHMpOwoKICAvKiBDaGFpbiB0aGUgdHdvIHRvZ2V0aGVyLiAgKi8KICByZXR1cm4gY2hhaW5vbiAodmlkLmluaXRzLCB2ZnVuX2luaXRzKTsKfQoKLyogQWRkcyB0byB2aWQtPmluaXRzIHRoZSBpbml0aWFsaXplcnMgZm9yIHRoZSB2YmFzZSBhbmQgdmNhbGwKICAgb2Zmc2V0cyBpbiBCSU5GTywgd2hpY2ggaXMgaW4gdGhlIGhpZXJhcmNoeSBkb21pbmF0ZWQgYnkgVC4gICovCgpzdGF0aWMgdm9pZApidWlsZF92Y2FsbF9hbmRfdmJhc2VfdnRibF9lbnRyaWVzICh0cmVlIGJpbmZvLCB2dGJsX2luaXRfZGF0YSogdmlkKQp7CiAgdHJlZSBiOwoKICAvKiBJZiB0aGlzIGlzIGEgZGVyaXZlZCBjbGFzcywgd2UgbXVzdCBmaXJzdCBjcmVhdGUgZW50cmllcwogICAgIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHByaW1hcnkgYmFzZSBjbGFzcy4gICovCiAgYiA9IGdldF9wcmltYXJ5X2JpbmZvIChiaW5mbyk7CiAgaWYgKGIpCiAgICBidWlsZF92Y2FsbF9hbmRfdmJhc2VfdnRibF9lbnRyaWVzIChiLCB2aWQpOwoKICAvKiBBZGQgdGhlIHZiYXNlIGVudHJpZXMgZm9yIHRoaXMgYmFzZS4gICovCiAgYnVpbGRfdmJhc2Vfb2Zmc2V0X3Z0YmxfZW50cmllcyAoYmluZm8sIHZpZCk7CiAgLyogQWRkIHRoZSB2Y2FsbCBlbnRyaWVzIGZvciB0aGlzIGJhc2UuICAqLwogIGJ1aWxkX3ZjYWxsX29mZnNldF92dGJsX2VudHJpZXMgKGJpbmZvLCB2aWQpOwp9CgovKiBSZXR1cm5zIHRoZSBpbml0aWFsaXplcnMgZm9yIHRoZSB2YmFzZSBvZmZzZXQgZW50cmllcyBpbiB0aGUgdnRhYmxlCiAgIGZvciBCSU5GTyAod2hpY2ggaXMgcGFydCBvZiB0aGUgY2xhc3MgaGllcmFyY2h5IGRvbWluYXRlZCBieSBUKSwgaW4KICAgcmV2ZXJzZSBvcmRlci4gIFZCQVNFX09GRlNFVF9JTkRFWCBnaXZlcyB0aGUgdnRhYmxlIGluZGV4CiAgIHdoZXJlIHRoZSBuZXh0IHZiYXNlIG9mZnNldCB3aWxsIGdvLiAgKi8KCnN0YXRpYyB2b2lkCmJ1aWxkX3ZiYXNlX29mZnNldF92dGJsX2VudHJpZXMgKHRyZWUgYmluZm8sIHZ0YmxfaW5pdF9kYXRhKiB2aWQpCnsKICB0cmVlIHZiYXNlOwogIHRyZWUgdDsKICB0cmVlIG5vbl9wcmltYXJ5X2JpbmZvOwoKICAvKiBJZiB0aGVyZSBhcmUgbm8gdmlydHVhbCBiYXNlY2xhc3NlcywgdGhlbiB0aGVyZSBpcyBub3RoaW5nIHRvCiAgICAgZG8uICAqLwogIGlmICghQ0xBU1NUWVBFX1ZCQVNFQ0xBU1NFUyAoQklORk9fVFlQRSAoYmluZm8pKSkKICAgIHJldHVybjsKCiAgdCA9IHZpZC0+ZGVyaXZlZDsKICAKICAvKiBXZSBtaWdodCBiZSBhIHByaW1hcnkgYmFzZSBjbGFzcy4gIEdvIHVwIHRoZSBpbmhlcml0YW5jZSBoaWVyYXJjaHkKICAgICB1bnRpbCB3ZSBmaW5kIHRoZSBtb3N0IGRlcml2ZWQgY2xhc3Mgb2Ygd2hpY2ggd2UgYXJlIGEgcHJpbWFyeSBiYXNlOgogICAgIGl0IGlzIHRoZSBvZmZzZXQgb2YgdGhhdCB3aGljaCB3ZSBuZWVkIHRvIHVzZS4gICovCiAgbm9uX3ByaW1hcnlfYmluZm8gPSBiaW5mbzsKICB3aGlsZSAoQklORk9fSU5IRVJJVEFOQ0VfQ0hBSU4gKG5vbl9wcmltYXJ5X2JpbmZvKSkKICAgIHsKICAgICAgdHJlZSBiOwoKICAgICAgLyogSWYgd2UgaGF2ZSByZWFjaGVkIGEgdmlydHVhbCBiYXNlLCB0aGVuIGl0IG11c3QgYmUgYSBwcmltYXJ5CgkgYmFzZSAocG9zc2libHkgbXVsdGktbGV2ZWwpIG9mIHZpZC0+YmluZm8sIG9yIHdlIHdvdWxkbid0CgkgaGF2ZSBjYWxsZWQgYnVpbGRfdmNhbGxfYW5kX3ZiYXNlX3Z0YmxfZW50cmllcyBmb3IgaXQuICBCdXQgaXQKCSBtaWdodCBiZSBhIGxvc3QgcHJpbWFyeSwgc28ganVzdCBza2lwIGRvd24gdG8gdmlkLT5iaW5mby4gICovCiAgICAgIGlmIChCSU5GT19WSVJUVUFMX1AgKG5vbl9wcmltYXJ5X2JpbmZvKSkKCXsKCSAgbm9uX3ByaW1hcnlfYmluZm8gPSB2aWQtPmJpbmZvOwoJICBicmVhazsKCX0KCiAgICAgIGIgPSBCSU5GT19JTkhFUklUQU5DRV9DSEFJTiAobm9uX3ByaW1hcnlfYmluZm8pOwogICAgICBpZiAoZ2V0X3ByaW1hcnlfYmluZm8gKGIpICE9IG5vbl9wcmltYXJ5X2JpbmZvKQoJYnJlYWs7CiAgICAgIG5vbl9wcmltYXJ5X2JpbmZvID0gYjsKICAgIH0KCiAgLyogR28gdGhyb3VnaCB0aGUgdmlydHVhbCBiYXNlcywgYWRkaW5nIHRoZSBvZmZzZXRzLiAgKi8KICBmb3IgKHZiYXNlID0gVFlQRV9CSU5GTyAoQklORk9fVFlQRSAoYmluZm8pKTsKICAgICAgIHZiYXNlOwogICAgICAgdmJhc2UgPSBUUkVFX0NIQUlOICh2YmFzZSkpCiAgICB7CiAgICAgIHRyZWUgYjsKICAgICAgdHJlZSBkZWx0YTsKICAgICAgCiAgICAgIGlmICghQklORk9fVklSVFVBTF9QICh2YmFzZSkpCgljb250aW51ZTsKCiAgICAgIC8qIEZpbmQgdGhlIGluc3RhbmNlIG9mIHRoaXMgdmlydHVhbCBiYXNlIGluIHRoZSBjb21wbGV0ZQoJIG9iamVjdC4gICovCiAgICAgIGIgPSBjb3BpZWRfYmluZm8gKHZiYXNlLCBiaW5mbyk7CgogICAgICAvKiBJZiB3ZSd2ZSBhbHJlYWR5IGdvdCBhbiBvZmZzZXQgZm9yIHRoaXMgdmlydHVhbCBiYXNlLCB3ZQoJIGRvbid0IG5lZWQgYW5vdGhlciBvbmUuICAqLwogICAgICBpZiAoQklORk9fVlRBQkxFX1BBVEhfTUFSS0VEIChiKSkKCWNvbnRpbnVlOwogICAgICBCSU5GT19WVEFCTEVfUEFUSF9NQVJLRUQgKGIpID0gMTsKCiAgICAgIC8qIEZpZ3VyZSBvdXQgd2hlcmUgd2UgY2FuIGZpbmQgdGhpcyB2YmFzZSBvZmZzZXQuICAqLwogICAgICBkZWx0YSA9IHNpemVfYmlub3AgKE1VTFRfRVhQUiwgCgkJCSAgdmlkLT5pbmRleCwKCQkJICBjb252ZXJ0IChzc2l6ZXR5cGUsCgkJCQkgICBUWVBFX1NJWkVfVU5JVCAodnRhYmxlX2VudHJ5X3R5cGUpKSk7CiAgICAgIGlmICh2aWQtPnByaW1hcnlfdnRibF9wKQoJQklORk9fVlBUUl9GSUVMRCAoYikgPSBkZWx0YTsKCiAgICAgIGlmIChiaW5mbyAhPSBUWVBFX0JJTkZPICh0KSkKCS8qIFRoZSB2YmFzZSBvZmZzZXQgaGFkIGJldHRlciBiZSB0aGUgc2FtZS4gICovCglnY2NfYXNzZXJ0ICh0cmVlX2ludF9jc3RfZXF1YWwgKGRlbHRhLCBCSU5GT19WUFRSX0ZJRUxEICh2YmFzZSkpKTsKCiAgICAgIC8qIFRoZSBuZXh0IHZiYXNlIHdpbGwgY29tZSBhdCBhIG1vcmUgbmVnYXRpdmUgb2Zmc2V0LiAgKi8KICAgICAgdmlkLT5pbmRleCA9IHNpemVfYmlub3AgKE1JTlVTX0VYUFIsIHZpZC0+aW5kZXgsCgkJCSAgICAgICBzc2l6ZV9pbnQgKFRBUkdFVF9WVEFCTEVfREFUQV9FTlRSWV9ESVNUQU5DRSkpOwoKICAgICAgLyogVGhlIGluaXRpYWxpemVyIGlzIHRoZSBkZWx0YSBmcm9tIEJJTkZPIHRvIHRoaXMgdmlydHVhbCBiYXNlLgoJIFRoZSB2YmFzZSBvZmZzZXRzIGdvIGluIHJldmVyc2UgaW5oZXJpdGFuY2UtZ3JhcGggb3JkZXIsIGFuZAoJIHdlIGFyZSB3YWxraW5nIGluIGluaGVyaXRhbmNlIGdyYXBoIG9yZGVyIHNvIHRoZXNlIGVuZCB1cCBpbgoJIHRoZSByaWdodCBvcmRlci4gICovCiAgICAgIGRlbHRhID0gc2l6ZV9kaWZmb3AgKEJJTkZPX09GRlNFVCAoYiksIEJJTkZPX09GRlNFVCAobm9uX3ByaW1hcnlfYmluZm8pKTsKICAgICAgCiAgICAgICp2aWQtPmxhc3RfaW5pdCAKCT0gYnVpbGRfdHJlZV9saXN0IChOVUxMX1RSRUUsCgkJCSAgIGZvbGQgKGJ1aWxkMSAoTk9QX0VYUFIsIAoJCQkJCSB2dGFibGVfZW50cnlfdHlwZSwKCQkJCQkgZGVsdGEpKSk7CiAgICAgIHZpZC0+bGFzdF9pbml0ID0gJlRSRUVfQ0hBSU4gKCp2aWQtPmxhc3RfaW5pdCk7CiAgICB9Cn0KCi8qIEFkZHMgdGhlIGluaXRpYWxpemVycyBmb3IgdGhlIHZjYWxsIG9mZnNldCBlbnRyaWVzIGluIHRoZSB2dGFibGUKICAgZm9yIEJJTkZPICh3aGljaCBpcyBwYXJ0IG9mIHRoZSBjbGFzcyBoaWVyYXJjaHkgZG9taW5hdGVkIGJ5IFZJRC0+REVSSVZFRCkKICAgdG8gVklELT5JTklUUy4gICovCgpzdGF0aWMgdm9pZApidWlsZF92Y2FsbF9vZmZzZXRfdnRibF9lbnRyaWVzICh0cmVlIGJpbmZvLCB2dGJsX2luaXRfZGF0YSogdmlkKQp7CiAgLyogV2Ugb25seSBuZWVkIHRoZXNlIGVudHJpZXMgaWYgdGhpcyBiYXNlIGlzIGEgdmlydHVhbCBiYXNlLiAgV2UKICAgICBjb21wdXRlIHRoZSBpbmRpY2VzIC0tIGJ1dCBkbyBub3QgYWRkIHRvIHRoZSB2dGFibGUgLS0gd2hlbgogICAgIGJ1aWxkaW5nIHRoZSBtYWluIHZ0YWJsZSBmb3IgYSBjbGFzcy4gICovCiAgaWYgKEJJTkZPX1ZJUlRVQUxfUCAoYmluZm8pIHx8IGJpbmZvID09IFRZUEVfQklORk8gKHZpZC0+ZGVyaXZlZCkpCiAgICB7CiAgICAgIC8qIFdlIG5lZWQgYSB2Y2FsbCBvZmZzZXQgZm9yIGVhY2ggb2YgdGhlIHZpcnR1YWwgZnVuY3Rpb25zIGluIHRoaXMKCSB2dGFibGUuICBGb3IgZXhhbXBsZToKCgkgICBjbGFzcyBBIHsgdmlydHVhbCB2b2lkIGYgKCk7IH07CgkgICBjbGFzcyBCMSA6IHZpcnR1YWwgcHVibGljIEEgeyB2aXJ0dWFsIHZvaWQgZiAoKTsgfTsKCSAgIGNsYXNzIEIyIDogdmlydHVhbCBwdWJsaWMgQSB7IHZpcnR1YWwgdm9pZCBmICgpOyB9OwoJICAgY2xhc3MgQzogcHVibGljIEIxLCBwdWJsaWMgQjIgeyB2aXJ0dWFsIHZvaWQgZiAoKTsgfTsKCgkgQSBDIG9iamVjdCBoYXMgYSBwcmltYXJ5IGJhc2Ugb2YgQjEsIHdoaWNoIGhhcyBhIHByaW1hcnkgYmFzZSBvZiBBLiAgQQoJIEMgYWxzbyBoYXMgYSBzZWNvbmRhcnkgYmFzZSBvZiBCMiwgd2hpY2ggbm8gbG9uZ2VyIGhhcyBhIHByaW1hcnkgYmFzZQoJIG9mIEEuICBTbyB0aGUgQjItaW4tQyBjb25zdHJ1Y3Rpb24gdnRhYmxlIG5lZWRzIGEgc2Vjb25kYXJ5IHZ0YWJsZSBmb3IKCSBBLCB3aGljaCB3aWxsIGFkanVzdCB0aGUgQSogdG8gYSBCMiogdG8gY2FsbCBmLiAgV2UgaGF2ZSBubyB3YXkgb2YKCSBrbm93aW5nIHdoYXQgKG9yIGV2ZW4gd2hldGhlcikgdGhpcyBvZmZzZXQgd2lsbCBiZSB3aGVuIHdlIGRlZmluZSBCMiwKCSBzbyB3ZSBzdG9yZSB0aGlzICJ2Y2FsbCBvZmZzZXQiIGluIHRoZSBBIHN1Yi12dGFibGUgYW5kIGxvb2sgaXQgdXAgaW4KCSBhICJ2aXJ0dWFsIHRodW5rIiBmb3IgQjI6OmYuCgoJIFdlIG5lZWQgZW50cmllcyBmb3IgYWxsIHRoZSBmdW5jdGlvbnMgaW4gb3VyIHByaW1hcnkgdnRhYmxlIGFuZAoJIGluIG91ciBub24tdmlydHVhbCBiYXNlcycgc2Vjb25kYXJ5IHZ0YWJsZXMuICAqLwogICAgICB2aWQtPnZiYXNlID0gYmluZm87CiAgICAgIC8qIElmIHdlIGFyZSBqdXN0IGNvbXB1dGluZyB0aGUgdmNhbGwgaW5kaWNlcyAtLSBidXQgZG8gbm90IG5lZWQKCSB0aGUgYWN0dWFsIGVudHJpZXMgLS0gbm90IHRoYXQuICAqLwogICAgICBpZiAoIUJJTkZPX1ZJUlRVQUxfUCAoYmluZm8pKQoJdmlkLT5nZW5lcmF0ZV92Y2FsbF9lbnRyaWVzID0gZmFsc2U7CiAgICAgIC8qIE5vdywgd2FsayB0aHJvdWdoIHRoZSBub24tdmlydHVhbCBiYXNlcywgYWRkaW5nIHZjYWxsIG9mZnNldHMuICAqLwogICAgICBhZGRfdmNhbGxfb2Zmc2V0X3Z0YmxfZW50cmllc19yIChiaW5mbywgdmlkKTsKICAgIH0KfQoKLyogQnVpbGQgdmNhbGwgb2Zmc2V0cywgc3RhcnRpbmcgd2l0aCB0aG9zZSBmb3IgQklORk8uICAqLwoKc3RhdGljIHZvaWQKYWRkX3ZjYWxsX29mZnNldF92dGJsX2VudHJpZXNfciAodHJlZSBiaW5mbywgdnRibF9pbml0X2RhdGEqIHZpZCkKewogIGludCBpOwogIHRyZWUgcHJpbWFyeV9iaW5mbzsKICB0cmVlIGJhc2VfYmluZm87CgogIC8qIERvbid0IHdhbGsgaW50byB2aXJ0dWFsIGJhc2VzIC0tIGV4Y2VwdCwgb2YgY291cnNlLCBmb3IgdGhlCiAgICAgdmlydHVhbCBiYXNlIGZvciB3aGljaCB3ZSBhcmUgYnVpbGRpbmcgdmNhbGwgb2Zmc2V0cy4gIEFueQogICAgIHByaW1hcnkgdmlydHVhbCBiYXNlIHdpbGwgaGF2ZSBhbHJlYWR5IGhhZCBpdHMgb2Zmc2V0cyBnZW5lcmF0ZWQKICAgICB0aHJvdWdoIHRoZSByZWN1cnNpb24gaW4gYnVpbGRfdmNhbGxfYW5kX3ZiYXNlX3Z0YmxfZW50cmllcy4gICovCiAgaWYgKEJJTkZPX1ZJUlRVQUxfUCAoYmluZm8pICYmIHZpZC0+dmJhc2UgIT0gYmluZm8pCiAgICByZXR1cm47CiAgCiAgLyogSWYgQklORk8gaGFzIGEgcHJpbWFyeSBiYXNlLCBwcm9jZXNzIGl0IGZpcnN0LiAgKi8KICBwcmltYXJ5X2JpbmZvID0gZ2V0X3ByaW1hcnlfYmluZm8gKGJpbmZvKTsKICBpZiAocHJpbWFyeV9iaW5mbykKICAgIGFkZF92Y2FsbF9vZmZzZXRfdnRibF9lbnRyaWVzX3IgKHByaW1hcnlfYmluZm8sIHZpZCk7CgogIC8qIEFkZCBCSU5GTyBpdHNlbGYgdG8gdGhlIGxpc3QuICAqLwogIGFkZF92Y2FsbF9vZmZzZXRfdnRibF9lbnRyaWVzXzEgKGJpbmZvLCB2aWQpOwoKICAvKiBTY2FuIHRoZSBub24tcHJpbWFyeSBiYXNlcyBvZiBCSU5GTy4gICovCiAgZm9yIChpID0gMDsgQklORk9fQkFTRV9JVEVSQVRFIChiaW5mbywgaSwgYmFzZV9iaW5mbyk7ICsraSkKICAgIGlmIChiYXNlX2JpbmZvICE9IHByaW1hcnlfYmluZm8pCiAgICAgIGFkZF92Y2FsbF9vZmZzZXRfdnRibF9lbnRyaWVzX3IgKGJhc2VfYmluZm8sIHZpZCk7Cn0KCi8qIENhbGxlZCBmcm9tIGJ1aWxkX3ZjYWxsX29mZnNldF92dGJsX2VudHJpZXNfci4gICovCgpzdGF0aWMgdm9pZAphZGRfdmNhbGxfb2Zmc2V0X3Z0YmxfZW50cmllc18xICh0cmVlIGJpbmZvLCB2dGJsX2luaXRfZGF0YSogdmlkKQp7CiAgLyogTWFrZSBlbnRyaWVzIGZvciB0aGUgcmVzdCBvZiB0aGUgdmlydHVhbHMuICAqLwogIGlmIChhYmlfdmVyc2lvbl9hdF9sZWFzdCAoMikpCiAgICB7CiAgICAgIHRyZWUgb3JpZ19mbjsKCiAgICAgIC8qIFRoZSBBQkkgcmVxdWlyZXMgdGhhdCB0aGUgbWV0aG9kcyBiZSBwcm9jZXNzZWQgaW4gZGVjbGFyYXRpb24KCSBvcmRlci4gIEcrKyAzLjIgdXNlZCB0aGUgb3JkZXIgaW4gdGhlIHZ0YWJsZS4gICovCiAgICAgIGZvciAob3JpZ19mbiA9IFRZUEVfTUVUSE9EUyAoQklORk9fVFlQRSAoYmluZm8pKTsKCSAgIG9yaWdfZm47CgkgICBvcmlnX2ZuID0gVFJFRV9DSEFJTiAob3JpZ19mbikpCglpZiAoREVDTF9WSU5ERVggKG9yaWdfZm4pKQoJICBhZGRfdmNhbGxfb2Zmc2V0IChvcmlnX2ZuLCBiaW5mbywgdmlkKTsKICAgIH0KICBlbHNlCiAgICB7CiAgICAgIHRyZWUgZGVyaXZlZF92aXJ0dWFsczsKICAgICAgdHJlZSBiYXNlX3ZpcnR1YWxzOwogICAgICB0cmVlIG9yaWdfdmlydHVhbHM7CiAgICAgIC8qIElmIEJJTkZPIGlzIGEgcHJpbWFyeSBiYXNlLCB0aGUgbW9zdCBkZXJpdmVkIGNsYXNzIHdoaWNoIGhhcwoJIEJJTkZPIGFzIGEgcHJpbWFyeSBiYXNlOyBvdGhlcndpc2UsIGp1c3QgQklORk8uICAqLwogICAgICB0cmVlIG5vbl9wcmltYXJ5X2JpbmZvOwoKICAgICAgLyogV2UgbWlnaHQgYmUgYSBwcmltYXJ5IGJhc2UgY2xhc3MuICBHbyB1cCB0aGUgaW5oZXJpdGFuY2UgaGllcmFyY2h5CgkgdW50aWwgd2UgZmluZCB0aGUgbW9zdCBkZXJpdmVkIGNsYXNzIG9mIHdoaWNoIHdlIGFyZSBhIHByaW1hcnkgYmFzZToKCSBpdCBpcyB0aGUgQklORk9fVklSVFVBTFMgdGhlcmUgdGhhdCB3ZSBuZWVkIHRvIGNvbnNpZGVyLiAgKi8KICAgICAgbm9uX3ByaW1hcnlfYmluZm8gPSBiaW5mbzsKICAgICAgd2hpbGUgKEJJTkZPX0lOSEVSSVRBTkNFX0NIQUlOIChub25fcHJpbWFyeV9iaW5mbykpCgl7CgkgIHRyZWUgYjsKCgkgIC8qIElmIHdlIGhhdmUgcmVhY2hlZCBhIHZpcnR1YWwgYmFzZSwgdGhlbiBpdCBtdXN0IGJlIHZpZC0+dmJhc2UsCgkgICAgIGJlY2F1c2Ugd2UgaWdub3JlIG90aGVyIHZpcnR1YWwgYmFzZXMgaW4KCSAgICAgYWRkX3ZjYWxsX29mZnNldF92dGJsX2VudHJpZXNfci4gIEluIHR1cm4sIGl0IG11c3QgYmUgYSBwcmltYXJ5CgkgICAgIGJhc2UgKHBvc3NpYmx5IG11bHRpLWxldmVsKSBvZiB2aWQtPmJpbmZvLCBvciB3ZSB3b3VsZG4ndAoJICAgICBoYXZlIGNhbGxlZCBidWlsZF92Y2FsbF9hbmRfdmJhc2VfdnRibF9lbnRyaWVzIGZvciBpdC4gIEJ1dCBpdAoJICAgICBtaWdodCBiZSBhIGxvc3QgcHJpbWFyeSwgc28ganVzdCBza2lwIGRvd24gdG8gdmlkLT5iaW5mby4gICovCgkgIGlmIChCSU5GT19WSVJUVUFMX1AgKG5vbl9wcmltYXJ5X2JpbmZvKSkKCSAgICB7CgkgICAgICBnY2NfYXNzZXJ0IChub25fcHJpbWFyeV9iaW5mbyA9PSB2aWQtPnZiYXNlKTsKCSAgICAgIG5vbl9wcmltYXJ5X2JpbmZvID0gdmlkLT5iaW5mbzsKCSAgICAgIGJyZWFrOwoJICAgIH0KCgkgIGIgPSBCSU5GT19JTkhFUklUQU5DRV9DSEFJTiAobm9uX3ByaW1hcnlfYmluZm8pOwoJICBpZiAoZ2V0X3ByaW1hcnlfYmluZm8gKGIpICE9IG5vbl9wcmltYXJ5X2JpbmZvKQoJICAgIGJyZWFrOwoJICBub25fcHJpbWFyeV9iaW5mbyA9IGI7Cgl9CgogICAgICBpZiAodmlkLT5jdG9yX3Z0YmxfcCkKCS8qIEZvciBhIGN0b3IgdnRhYmxlIHdlIG5lZWQgdGhlIGVxdWl2YWxlbnQgYmluZm8gd2l0aGluIHRoZSBoaWVyYXJjaHkKCSAgIHdoZXJlIHJ0dGlfYmluZm8gaXMgdGhlIG1vc3QgZGVyaXZlZCB0eXBlLiAgKi8KCW5vbl9wcmltYXJ5X2JpbmZvCgkgID0gb3JpZ2luYWxfYmluZm8gKG5vbl9wcmltYXJ5X2JpbmZvLCB2aWQtPnJ0dGlfYmluZm8pOwogICAgICAKICAgICAgZm9yIChiYXNlX3ZpcnR1YWxzID0gQklORk9fVklSVFVBTFMgKGJpbmZvKSwKCSAgICAgZGVyaXZlZF92aXJ0dWFscyA9IEJJTkZPX1ZJUlRVQUxTIChub25fcHJpbWFyeV9iaW5mbyksCgkgICAgIG9yaWdfdmlydHVhbHMgPSBCSU5GT19WSVJUVUFMUyAoVFlQRV9CSU5GTyAoQklORk9fVFlQRSAoYmluZm8pKSk7CgkgICBiYXNlX3ZpcnR1YWxzOwoJICAgYmFzZV92aXJ0dWFscyA9IFRSRUVfQ0hBSU4gKGJhc2VfdmlydHVhbHMpLAoJICAgICBkZXJpdmVkX3ZpcnR1YWxzID0gVFJFRV9DSEFJTiAoZGVyaXZlZF92aXJ0dWFscyksCgkgICAgIG9yaWdfdmlydHVhbHMgPSBUUkVFX0NIQUlOIChvcmlnX3ZpcnR1YWxzKSkKCXsKCSAgdHJlZSBvcmlnX2ZuOwoKCSAgLyogRmluZCB0aGUgZGVjbGFyYXRpb24gdGhhdCBvcmlnaW5hbGx5IGNhdXNlZCB0aGlzIGZ1bmN0aW9uIHRvCgkgICAgIGJlIHByZXNlbnQgaW4gQklORk9fVFlQRSAoYmluZm8pLiAgKi8KCSAgb3JpZ19mbiA9IEJWX0ZOIChvcmlnX3ZpcnR1YWxzKTsKCgkgIC8qIFdoZW4gcHJvY2Vzc2luZyBCSU5GTywgd2Ugb25seSB3YW50IHRvIGdlbmVyYXRlIHZjYWxsIHNsb3RzIGZvcgoJICAgICBmdW5jdGlvbiBzbG90cyBpbnRyb2R1Y2VkIGluIEJJTkZPLiAgU28gZG9uJ3QgdHJ5IHRvIGdlbmVyYXRlCgkgICAgIG9uZSBpZiB0aGUgZnVuY3Rpb24gaXNuJ3QgZXZlbiBkZWZpbmVkIGluIEJJTkZPLiAgKi8KCSAgaWYgKCFTQU1FX0JJTkZPX1RZUEVfUCAoQklORk9fVFlQRSAoYmluZm8pLCBERUNMX0NPTlRFWFQgKG9yaWdfZm4pKSkKCSAgICBjb250aW51ZTsKCgkgIGFkZF92Y2FsbF9vZmZzZXQgKG9yaWdfZm4sIGJpbmZvLCB2aWQpOwoJfQogICAgfQp9CgovKiBBZGQgYSB2Y2FsbCBvZmZzZXQgZW50cnkgZm9yIE9SSUdfRk4gdG8gdGhlIHZ0YWJsZS4gICovCgpzdGF0aWMgdm9pZAphZGRfdmNhbGxfb2Zmc2V0ICh0cmVlIG9yaWdfZm4sIHRyZWUgYmluZm8sIHZ0YmxfaW5pdF9kYXRhICp2aWQpCnsKICBzaXplX3QgaTsKICB0cmVlIHZjYWxsX29mZnNldDsKCiAgLyogSWYgdGhlcmUgaXMgYWxyZWFkeSBhbiBlbnRyeSBmb3IgYSBmdW5jdGlvbiB3aXRoIHRoZSBzYW1lCiAgICAgc2lnbmF0dXJlIGFzIEZOLCB0aGVuIHdlIGRvIG5vdCBuZWVkIGEgc2Vjb25kIHZjYWxsIG9mZnNldC4KICAgICBDaGVjayB0aGUgbGlzdCBvZiBmdW5jdGlvbnMgYWxyZWFkeSBwcmVzZW50IGluIHRoZSBkZXJpdmVkCiAgICAgY2xhc3MgdnRhYmxlLiAgKi8KICBmb3IgKGkgPSAwOyBpIDwgVkFSUkFZX0FDVElWRV9TSVpFICh2aWQtPmZucyk7ICsraSkgCiAgICB7CiAgICAgIHRyZWUgZGVyaXZlZF9lbnRyeTsKCiAgICAgIGRlcml2ZWRfZW50cnkgPSBWQVJSQVlfVFJFRSAodmlkLT5mbnMsIGkpOwogICAgICBpZiAoc2FtZV9zaWduYXR1cmVfcCAoZGVyaXZlZF9lbnRyeSwgb3JpZ19mbikKCSAgLyogV2Ugb25seSB1c2Ugb25lIHZjYWxsIG9mZnNldCBmb3IgdmlydHVhbCBkZXN0cnVjdG9ycywKCSAgICAgZXZlbiB0aG91Z2ggdGhlcmUgYXJlIHR3byB2aXJ0dWFsIHRhYmxlIGVudHJpZXMuICAqLwoJICB8fCAoREVDTF9ERVNUUlVDVE9SX1AgKGRlcml2ZWRfZW50cnkpCgkgICAgICAmJiBERUNMX0RFU1RSVUNUT1JfUCAob3JpZ19mbikpKQoJcmV0dXJuOwogICAgfQoKICAvKiBJZiB3ZSBhcmUgYnVpbGRpbmcgdGhlc2UgdmNhbGwgb2Zmc2V0cyBhcyBwYXJ0IG9mIGJ1aWxkaW5nCiAgICAgdGhlIHZ0YWJsZSBmb3IgdGhlIG1vc3QgZGVyaXZlZCBjbGFzcywgcmVtZW1iZXIgdGhlIHZjYWxsCiAgICAgb2Zmc2V0LiAgKi8KICBpZiAodmlkLT5iaW5mbyA9PSBUWVBFX0JJTkZPICh2aWQtPmRlcml2ZWQpKQogICAgewogICAgICB0cmVlX3BhaXJfcCBlbHQgPSBWRUNfc2FmZV9wdXNoICh0cmVlX3BhaXJfcywKCQkJCSAgICAgICBDTEFTU1RZUEVfVkNBTExfSU5ESUNFUyAodmlkLT5kZXJpdmVkKSwKCQkJCSAgICAgICBOVUxMKTsKICAgICAgZWx0LT5wdXJwb3NlID0gb3JpZ19mbjsKICAgICAgZWx0LT52YWx1ZSA9IHZpZC0+aW5kZXg7CiAgICB9CiAgCiAgLyogVGhlIG5leHQgdmNhbGwgb2Zmc2V0IHdpbGwgYmUgZm91bmQgYXQgYSBtb3JlIG5lZ2F0aXZlCiAgICAgb2Zmc2V0LiAgKi8KICB2aWQtPmluZGV4ID0gc2l6ZV9iaW5vcCAoTUlOVVNfRVhQUiwgdmlkLT5pbmRleCwKCQkJICAgc3NpemVfaW50IChUQVJHRVRfVlRBQkxFX0RBVEFfRU5UUllfRElTVEFOQ0UpKTsKCiAgLyogS2VlcCB0cmFjayBvZiB0aGlzIGZ1bmN0aW9uLiAgKi8KICBWQVJSQVlfUFVTSF9UUkVFICh2aWQtPmZucywgb3JpZ19mbik7CgogIGlmICh2aWQtPmdlbmVyYXRlX3ZjYWxsX2VudHJpZXMpCiAgICB7CiAgICAgIHRyZWUgYmFzZTsKICAgICAgdHJlZSBmbjsKCiAgICAgIC8qIEZpbmQgdGhlIG92ZXJyaWRpbmcgZnVuY3Rpb24uICAqLwogICAgICBmbiA9IGZpbmRfZmluYWxfb3ZlcnJpZGVyICh2aWQtPnJ0dGlfYmluZm8sIGJpbmZvLCBvcmlnX2ZuKTsKICAgICAgaWYgKGZuID09IGVycm9yX21hcmtfbm9kZSkKCXZjYWxsX29mZnNldCA9IGJ1aWxkMSAoTk9QX0VYUFIsIHZ0YWJsZV9lbnRyeV90eXBlLAoJCQkgICAgICAgaW50ZWdlcl96ZXJvX25vZGUpOwogICAgICBlbHNlCgl7CgkgIGJhc2UgPSBUUkVFX1ZBTFVFIChmbik7CgoJICAvKiBUaGUgdmJhc2Ugd2UncmUgd29ya2luZyBvbiBpcyBhIHByaW1hcnkgYmFzZSBvZgoJICAgICB2aWQtPmJpbmZvLiAgQnV0IGl0IG1pZ2h0IGJlIGEgbG9zdCBwcmltYXJ5LCBzbyBpdHMKCSAgICAgQklORk9fT0ZGU0VUIG1pZ2h0IGJlIHdyb25nLCBzbyB3ZSBqdXN0IHVzZSB0aGUKCSAgICAgQklORk9fT0ZGU0VUIGZyb20gdmlkLT5iaW5mby4gICovCgkgIHZjYWxsX29mZnNldCA9IHNpemVfZGlmZm9wIChCSU5GT19PRkZTRVQgKGJhc2UpLAoJCQkJICAgICAgQklORk9fT0ZGU0VUICh2aWQtPmJpbmZvKSk7CgkgIHZjYWxsX29mZnNldCA9IGZvbGQgKGJ1aWxkMSAoTk9QX0VYUFIsIHZ0YWJsZV9lbnRyeV90eXBlLAoJCQkJICAgICAgIHZjYWxsX29mZnNldCkpOwoJfQogICAgICAvKiBBZGQgdGhlIGluaXRpYWxpemVyIHRvIHRoZSB2dGFibGUuICAqLwogICAgICAqdmlkLT5sYXN0X2luaXQgPSBidWlsZF90cmVlX2xpc3QgKE5VTExfVFJFRSwgdmNhbGxfb2Zmc2V0KTsKICAgICAgdmlkLT5sYXN0X2luaXQgPSAmVFJFRV9DSEFJTiAoKnZpZC0+bGFzdF9pbml0KTsKICAgIH0KfQoKLyogUmV0dXJuIHZ0YmwgaW5pdGlhbGl6ZXJzIGZvciB0aGUgUlRUSSBlbnRyaWVzIGNvcnJlc3BvbmRpbmcgdG8gdGhlCiAgIEJJTkZPJ3MgdnRhYmxlLiAgVGhlIFJUVEkgZW50cmllcyBzaG91bGQgaW5kaWNhdGUgdGhlIG9iamVjdCBnaXZlbgogICBieSBWSUQtPnJ0dGlfYmluZm8uICAqLwoKc3RhdGljIHZvaWQKYnVpbGRfcnR0aV92dGJsX2VudHJpZXMgKHRyZWUgYmluZm8sIHZ0YmxfaW5pdF9kYXRhKiB2aWQpCnsKICB0cmVlIGI7CiAgdHJlZSB0OwogIHRyZWUgYmFzZXR5cGU7CiAgdHJlZSBvZmZzZXQ7CiAgdHJlZSBkZWNsOwogIHRyZWUgaW5pdDsKCiAgYmFzZXR5cGUgPSBCSU5GT19UWVBFIChiaW5mbyk7CiAgdCA9IEJJTkZPX1RZUEUgKHZpZC0+cnR0aV9iaW5mbyk7CgogIC8qIFRvIGZpbmQgdGhlIGNvbXBsZXRlIG9iamVjdCwgd2Ugd2lsbCBmaXJzdCBjb252ZXJ0IHRvIG91ciBtb3N0CiAgICAgcHJpbWFyeSBiYXNlLCBhbmQgdGhlbiBhZGQgdGhlIG9mZnNldCBpbiB0aGUgdnRibCB0byB0aGF0IHZhbHVlLiAgKi8KICBiID0gYmluZm87CiAgd2hpbGUgKENMQVNTVFlQRV9IQVNfUFJJTUFSWV9CQVNFX1AgKEJJTkZPX1RZUEUgKGIpKQogICAgICAgICAmJiAhQklORk9fTE9TVF9QUklNQVJZX1AgKGIpKQogICAgewogICAgICB0cmVlIHByaW1hcnlfYmFzZTsKCiAgICAgIHByaW1hcnlfYmFzZSA9IGdldF9wcmltYXJ5X2JpbmZvIChiKTsKICAgICAgZ2NjX2Fzc2VydCAoQklORk9fUFJJTUFSWV9QIChwcmltYXJ5X2Jhc2UpCgkJICAmJiBCSU5GT19JTkhFUklUQU5DRV9DSEFJTiAocHJpbWFyeV9iYXNlKSA9PSBiKTsKICAgICAgYiA9IHByaW1hcnlfYmFzZTsKICAgIH0KICBvZmZzZXQgPSBzaXplX2RpZmZvcCAoQklORk9fT0ZGU0VUICh2aWQtPnJ0dGlfYmluZm8pLCBCSU5GT19PRkZTRVQgKGIpKTsKCiAgLyogVGhlIHNlY29uZCBlbnRyeSBpcyB0aGUgYWRkcmVzcyBvZiB0aGUgdHlwZWluZm8gb2JqZWN0LiAgKi8KICBpZiAoZmxhZ19ydHRpKQogICAgZGVjbCA9IGJ1aWxkX2FkZHJlc3MgKGdldF90aW5mb19kZWNsICh0KSk7CiAgZWxzZQogICAgZGVjbCA9IGludGVnZXJfemVyb19ub2RlOwogIAogIC8qIENvbnZlcnQgdGhlIGRlY2xhcmF0aW9uIHRvIGEgdHlwZSB0aGF0IGNhbiBiZSBzdG9yZWQgaW4gdGhlCiAgICAgdnRhYmxlLiAgKi8KICBpbml0ID0gYnVpbGRfbm9wICh2ZnVuY19wdHJfdHlwZV9ub2RlLCBkZWNsKTsKICAqdmlkLT5sYXN0X2luaXQgPSBidWlsZF90cmVlX2xpc3QgKE5VTExfVFJFRSwgaW5pdCk7CiAgdmlkLT5sYXN0X2luaXQgPSAmVFJFRV9DSEFJTiAoKnZpZC0+bGFzdF9pbml0KTsKCiAgLyogQWRkIHRoZSBvZmZzZXQtdG8tdG9wIGVudHJ5LiAgSXQgY29tZXMgZWFybGllciBpbiB0aGUgdnRhYmxlIHRoYW4KICAgICB0aGUgdHlwZWluZm8gZW50cnkuICBDb252ZXJ0IHRoZSBvZmZzZXQgdG8gbG9vayBsaWtlIGEKICAgICBmdW5jdGlvbiBwb2ludGVyLCBzbyB0aGF0IHdlIGNhbiBwdXQgaXQgaW4gdGhlIHZ0YWJsZS4gICovCiAgaW5pdCA9IGJ1aWxkX25vcCAodmZ1bmNfcHRyX3R5cGVfbm9kZSwgb2Zmc2V0KTsKICAqdmlkLT5sYXN0X2luaXQgPSBidWlsZF90cmVlX2xpc3QgKE5VTExfVFJFRSwgaW5pdCk7CiAgdmlkLT5sYXN0X2luaXQgPSAmVFJFRV9DSEFJTiAoKnZpZC0+bGFzdF9pbml0KTsKfQoKLyogRm9sZCBhIE9CSl9UWVBFX1JFRiBleHByZXNzaW9uIHRvIHRoZSBhZGRyZXNzIG9mIGEgZnVuY3Rpb24uCiAgIEtOT1dOX1RZUEUgY2FycmllcyB0aGUgdHJ1ZSB0eXBlIG9mIE9CSl9UWVBFX1JFRl9PQkpFQ1QoUkVGKS4gICovCgp0cmVlCmNwX2ZvbGRfb2JqX3R5cGVfcmVmICh0cmVlIHJlZiwgdHJlZSBrbm93bl90eXBlKQp7CiAgSE9TVF9XSURFX0lOVCBpbmRleCA9IHRyZWVfbG93X2NzdCAoT0JKX1RZUEVfUkVGX1RPS0VOIChyZWYpLCAxKTsKICBIT1NUX1dJREVfSU5UIGkgPSAwOwogIHRyZWUgdiA9IEJJTkZPX1ZJUlRVQUxTIChUWVBFX0JJTkZPIChrbm93bl90eXBlKSk7CiAgdHJlZSBmbmRlY2w7CgogIHdoaWxlIChpICE9IGluZGV4KQogICAgewogICAgICBpICs9IChUQVJHRVRfVlRBQkxFX1VTRVNfREVTQ1JJUFRPUlMKCSAgICA/IFRBUkdFVF9WVEFCTEVfVVNFU19ERVNDUklQVE9SUyA6IDEpOwogICAgICB2ID0gVFJFRV9DSEFJTiAodik7CiAgICB9CgogIGZuZGVjbCA9IEJWX0ZOICh2KTsKCiNpZmRlZiBFTkFCTEVfQ0hFQ0tJTkcKICBnY2NfYXNzZXJ0ICh0cmVlX2ludF9jc3RfZXF1YWwgKE9CSl9UWVBFX1JFRl9UT0tFTiAocmVmKSwKCQkJCSAgREVDTF9WSU5ERVggKGZuZGVjbCkpKTsKI2VuZGlmCgogIGNncmFwaF9ub2RlIChmbmRlY2wpLT5sb2NhbC52dGFibGVfbWV0aG9kID0gdHJ1ZTsKCiAgcmV0dXJuIGJ1aWxkX2FkZHJlc3MgKGZuZGVjbCk7Cn0KCi8qIEFQUExFIExPQ0FMIGJlZ2luIEtFWFQgZG91YmxlIGRlc3RydWN0b3IgKi8KLyogUmV0dXJuIHdoZXRoZXIgQ0xBU1Mgb3IgYW55IG9mIGl0cyBwcmltYXJ5IGFuY2VzdG9ycyBoYXZlIHRoZQogICAiYXBwbGVfa2V4dF9jb21wYXRpYmlsaXR5IiBhdHRyaWJ1dGUsIGluIHdoaWNoIGNhc2UgdGhlCiAgIG5vbi1kZWxldGluZyBkZXN0cnVjdG9yIGlzIG5vdCBlbWl0dGVkLiAgT25seSBzaW5nbGUKICAgaW5oZXJpdGFuY2UgaGVpcmFyY2hpZXMgY2FuIGhhdmUgdGhpcyB0YWcuICAqLwppbnQKaGFzX2FwcGxlX2tleHRfY29tcGF0aWJpbGl0eV9hdHRyX3AgKHRyZWUgY2xhc3MpCnsKICB3aGlsZSAoY2xhc3MgIT0gTlVMTCkKICAgIHsKICAgICAgdHJlZSBiYXNlX2JpbmZvOwoKICAgICAgaWYgKFRSRUVfQ09ERSAoY2xhc3MpID09IEFSUkFZX1RZUEUpCgl7CgkgIGNsYXNzID0gVFJFRV9UWVBFIChjbGFzcyk7CgkgIGNvbnRpbnVlOwoJfQoKICAgICAgaWYgKEJJTkZPX05fQkFTRV9CSU5GT1MgKFRZUEVfQklORk8gKGNsYXNzKSkgPiAxKQoJcmV0dXJuIDA7CgogICAgICBpZiAobG9va3VwX2F0dHJpYnV0ZSAoImFwcGxlX2tleHRfY29tcGF0aWJpbGl0eSIsCgkJCSAgICBUWVBFX0FUVFJJQlVURVMgKGNsYXNzKSkpCglyZXR1cm4gMTsKCiAgICAgIC8qIElmIHRoZXJlIGFyZSBubyBtb3JlIGJhc2UgY2xhc3Nlcywgd2UncmUgZG9uZS4gICovCiAgICAgIGlmIChCSU5GT19OX0JBU0VfQklORk9TIChUWVBFX0JJTkZPIChjbGFzcykpIDwgMSkKCWJyZWFrOwoKICAgICAgYmFzZV9iaW5mbyA9IEJJTkZPX0JBU0VfQklORk8gKFRZUEVfQklORk8gKGNsYXNzKSwgMCk7CiAgICAgIGlmIChiYXNlX2JpbmZvCgkgICYmICEgQklORk9fVklSVFVBTF9QIChiYXNlX2JpbmZvKSkKCWNsYXNzID0gQklORk9fVFlQRSAoYmFzZV9iaW5mbyk7CiAgICAgIGVsc2UKCWJyZWFrOwogICAgfQoKICByZXR1cm4gMDsKfQoKLyogV2FsayB0aHJvdWdoIGEgZnVuY3Rpb24gYm9keSBhbmQgcmV0dXJuIHRydWUgaWYgbm90aGluZyBpbiB0aGVyZQogICB3b3VsZCBjYXVzZSB1cyB0byBnZW5lcmF0ZSBjb2RlLiAgKi8Kc3RhdGljIGludApjb21wb3VuZF9ib2R5X2lzX2VtcHR5X3AgKHRyZWUgdCkKewogIHdoaWxlICh0ICYmIHQgIT0gZXJyb3JfbWFya19ub2RlKQogICAgewogICAgICBlbnVtIHRyZWVfY29kZSB0YyA9IFRSRUVfQ09ERSAodCk7CiAgICAgIGlmICh0YyA9PSBCSU5EX0VYUFIpCgl7CgkgIGlmIChCSU5EX0VYUFJfVkFSUyAodCkgPT0gMAoJICAgICAgJiYgY29tcG91bmRfYm9keV9pc19lbXB0eV9wIChCSU5EX0VYUFJfQk9EWSAodCkpKQoJICAgIHQgPSBUUkVFX0NIQUlOICh0KTsKCSAgZWxzZQoJICAgIHJldHVybiAwOwoJfQogICAgICBlbHNlIGlmICh0YyA9PSBTVEFURU1FTlRfTElTVCkKCXsKCSAgdHJlZV9zdG10X2l0ZXJhdG9yIGl0ZXI7CgoJICBmb3IgKGl0ZXIgPSB0c2lfc3RhcnQgKHQpOyAhdHNpX2VuZF9wIChpdGVyKTsgdHNpX25leHQgKCZpdGVyKSkKCSAgICBpZiAoISBjb21wb3VuZF9ib2R5X2lzX2VtcHR5X3AgKHRzaV9zdG10IChpdGVyKSkpCgkgICAgICByZXR1cm4gMDsKCSAgcmV0dXJuIDE7Cgl9CiAgICAgIGVsc2UKCXJldHVybiAwOwogICAgfQogIC8qIFdlIGhpdCB0aGUgZW5kIG9mIHRoZSBib2R5IGZ1bmN0aW9uIHdpdGhvdXQgc2VlaW5nIGFueXRoaW5nLiAgKi8KICByZXR1cm4gMTsKfQoKLyogVFJVRSBpZiB3ZSBoYXZlIGFuIG9wZXJhdG9yIGRlbGV0ZSB3aGljaCBpcyBlbXB0eSAoaS5lLiwgTk8gQ09ERSEpICAqLwppbnQKaGFzX2VtcHR5X29wZXJhdG9yX2RlbGV0ZV9wICh0cmVlIGNsYXNzKQp7CiAgaWYgKCEgY2xhc3MpCiAgICByZXR1cm4gMDsKCiAgaWYgKEJJTkZPX05fQkFTRV9CSU5GT1MgKFRZUEVfQklORk8gKGNsYXNzKSkgPiAxKQogICAgcmV0dXJuIDA7CgogIGlmIChUWVBFX0dFVFNfREVMRVRFIChjbGFzcykpCiAgICB7CiAgICAgIHRyZWUgZiA9IGxvb2t1cF9mbmZpZWxkcyAoVFlQRV9CSU5GTyAoY2xhc3MpLAoJCQkJYW5zaV9vcG5hbWUgKERFTEVURV9FWFBSKSwgMCk7CgogICAgICBpZiAoZiA9PSBlcnJvcl9tYXJrX25vZGUpCglyZXR1cm4gMDsKCiAgICAgIGlmIChCQVNFTElOS19QIChmKSkKCWYgPSBCQVNFTElOS19GVU5DVElPTlMgKGYpOwoKICAgICAgaWYgKE9WTF9DVVJSRU5UIChmKSkKCXsKCSAgZiA9IE9WTF9DVVJSRU5UIChmKTsKCgkgIC8qIFdlJ3ZlIG92ZXJyaWRkZW4gVFJFRV9TSURFX0VGRkVDVFMgZm9yIEMrKyBvcGVyYXRvciBkZWxldGVzCgkgICAgIHRvIG1lYW4gdGhhdCB0aGUgZnVuY3Rpb24gaXMgZW1wdHkuICAqLwoJICBpZiAoVFJFRV9TSURFX0VGRkVDVFMgKGYpKQoJICAgIHJldHVybiAxOwoKCSAgLyogT3RoZXJ3aXNlLCBpdCBjb3VsZCBiZSBhbiBpbmxpbmUgYnV0IGVtcHR5IGZ1bmN0aW9uLiAgKi8KCSAgaWYgKERFQ0xfU0FWRURfVFJFRSAoZikpCgkgICAgcmV0dXJuIGNvbXBvdW5kX2JvZHlfaXNfZW1wdHlfcCAoREVDTF9TQVZFRF9UUkVFIChmKSk7Cgl9CiAgICB9CgogIHJldHVybiAwOwp9Ci8qIEFQUExFIExPQ0FMIGVuZCBLRVhUIGRvdWJsZSBkZXN0cnVjdG9yICovCgovKiBBUFBMRSBMT0NBTCBiZWdpbiA0MTY3NzU5ICovCi8qIFNldCBERUNMX0lHTk9SRURfUCBmbGFnIGZvciBjdG9ycyBhbmQgZHRvcnMgYXNzb2NpYXRlZCAKICAgd2l0aCBUWVBFIHVzaW5nIFZBTFVFLiAgKi8KCnZvaWQgY3Bfc2V0X2RlY2xfaWdub3JlX2ZsYWcgKHRyZWUgdHlwZSwgaW50IHZhbHVlKQp7CiAgdHJlZSBtOwogIHRyZWUgbWV0aG9kcyA9IFRZUEVfTUVUSE9EUyAodHlwZSk7CgogIGlmICghZmxhZ19saW1pdF9kZWJ1Z19pbmZvKQogICAgcmV0dXJuOwoKICBpZiAobWV0aG9kcyA9PSBOVUxMX1RSRUUpCiAgICByZXR1cm47CgogIGlmIChUUkVFX0NPREUgKG1ldGhvZHMpICE9IFRSRUVfVkVDKQogICAgbSA9IG1ldGhvZHM7CiAgZWxzZSBpZiAoVFJFRV9WRUNfRUxUIChtZXRob2RzLCAwKSAhPSBOVUxMX1RSRUUpCiAgICBtID0gVFJFRV9WRUNfRUxUIChtZXRob2RzLCAwKTsKICBlbHNlCiAgICBtID0gVFJFRV9WRUNfRUxUIChtZXRob2RzLCAxKTsKCiAgZm9yICg7IG07IG0gPSBUUkVFX0NIQUlOIChtKSkKICAgIHsKCiAgICAgIGlmIChERUNMX05BTUUgKG0pID09IGJhc2VfY3Rvcl9pZGVudGlmaWVyCiAgICAgICAgfHwgREVDTF9OQU1FIChtKSA9PSBjb21wbGV0ZV9jdG9yX2lkZW50aWZpZXIKICAgICAgICB8fCBERUNMX05BTUUgKG0pID09IGNvbXBsZXRlX2R0b3JfaWRlbnRpZmllcgogICAgICAgIHx8IERFQ0xfTkFNRSAobSkgPT0gYmFzZV9kdG9yX2lkZW50aWZpZXIKICAgICAgICB8fCBERUNMX05BTUUgKG0pID09IGRlbGV0aW5nX2R0b3JfaWRlbnRpZmllcikKICAgICAgREVDTF9JR05PUkVEX1AgKG0pID0gdmFsdWU7CiAgICB9Cn0KLyogQVBQTEUgTE9DQUwgZW5kIDQxNjc3NTkgKi8KI2luY2x1ZGUgImd0LWNwLWNsYXNzLmgiCg==