LyoKICogQUlYNC81IGNwdSBzdGF0aXN0aWNzIG1vZHVsZSBmb3IgbmV0LXNubXAKICoKICogVmVyc2lvbiAwLjEgLSBJbml0aWFsIHJlbGVhc2UgLSAwNS9KdW4vMjAwMwogKgogKiBEZXJpdmVkIGZyb20gdm1zdGF0X3NvbGFyaXMyLmMKICogVXNpbmcgbGlicGVyZnN0YXQgZm9yIHN0YXRpc3RpY3MgKFJlZGJvb2sgU0cyNC02MDM5KQogKgogKiBQb3J0ZWQgdG8gQUlYIGJ5IE1pY2hhZWwgS3VrYXQgPG1pY2hhZWwua3VrYXRAdG8uY29tPgogKiBUaGlua2luZyBPYmplY3RzIFNvZnR3YXJlIEdtYkgKICogTGlsaWVudGhhbHN0cmHfZSAyCiAqIDcwODI1IFN0dXR0Z2FydC1Lb3JudGFsCiAqIGh0dHA6Ly93d3cudG8uY29tLwogKgogKiBUaGFua3MgZ28gdG8gSm9jaGVuIEttaWV0c2NoIGZvciB0aGUgc29sYXJpczIgc3VwcG9ydCBhbmQKICogdG8gRGFpbWxlckNocnlzbGVyIEFHIFN0dXR0Z2FydCBmb3IgbWFraW5nIHRoaXMgcG9ydCBwb3NzaWJsZQogKi8KCi8qCiAqIFRvIG1ha2UgbGludCBza2lwIHRoZSBkZWJ1ZyBjb2RlIGFuZCBzdG9wIGNvbXBsYWluaW5nIAogKi8KI2lmZGVmIF9fbGludAojZGVmaW5lIE5FVFNOTVBfTk9fREVCVUdHSU5HIDEKI2VuZGlmCgovKgogKiBJbmNsdWRlcyBzdGFydCBoZXJlIAogKi8KCi8qCiAqIFN0YW5kYXJkIGluY2x1ZGVzIAogKi8KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy90aW1lLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KCi8qCiAqIGxpYnBlcmZzdGF0IHN0cnVjdHMgCiAqLwojaW5jbHVkZSA8bGlicGVyZnN0YXQuaD4KCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWluY2x1ZGVzLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9uZXQtc25tcC1hZ2VudC1pbmNsdWRlcy5oPgoKI2luY2x1ZGUgIm1pYmRlZnMuaCIKI2luY2x1ZGUgInV0aWxfZnVuY3MuaCIKCi8qCiAqIEhlYWRlciBmaWxlIGZvciB0aGlzIG1vZHVsZSAKICovCiNpbmNsdWRlICJ2bXN0YXQuaCIKI2luY2x1ZGUgInZtc3RhdF9haXg0LmgiCgovKgogKiBJbmNsdWRlcyBlbmQgaGVyZSAKICovCgoKLyoKICogR2xvYmFsIHN0cnVjdHVyZXMgc3RhcnQgaGVyZSAKICovCgovKgogKiBBIHN0cnVjdHVyZSB0byBzYXZlIGRhdGEgZ2F0aGVyZWQgZnJvbSB0aGUgbGlicGVyZnN0YXQuCiAqLwpzdHJ1Y3QgY3B1X3N0YXRfc25hcHNob3QgewoJdW5zaWduZWQgbG9uZyBsb25nIGNzc190aW1lOwoJdW5zaWduZWQgaW50CSAgIGNzc19jcHVzOwoJdW5zaWduZWQgbG9uZyBsb25nIGNzc19zd2FwaW47Cgl1bnNpZ25lZCBsb25nIGxvbmcgY3NzX3N3YXBvdXQ7Cgl1bnNpZ25lZCBsb25nIGxvbmcgY3NzX2Jsb2Nrc19yZWFkOwoJdW5zaWduZWQgbG9uZyBsb25nIGNzc19ibG9ja3Nfd3JpdGU7Cgl1bnNpZ25lZCBsb25nIGxvbmcgY3NzX2ludGVycnVwdHM7Cgl1bnNpZ25lZCBsb25nIGxvbmcgY3NzX2NvbnRleHRfc3c7Cgl1bnNpZ25lZCBsb25nIGxvbmcgY3NzX2NwdVtDUFVfU1RBVEVTXTsKfTsKCi8qCiAqIEdsb2JhbCBzdHJ1Y3R1cmVzIGVuZCBoZXJlIAogKi8KCgovKgogKiBHbG9iYWwgdmFyaWFibGVzIHN0YXJ0IGhlcmUgCiAqLwoKLyoKICogVmFyaWFibGVzIGZvciB0aGUgY2FsY3VsYXRlZCB2YWx1ZXMsIGZpbGxlZCBpbiB1cGRhdGVfc3RhdHMJCiAqIE5lZWQgdG8gYmUgZ2xvYmFsIHNpbmNlIHdlIG5lZWQgdGhlbSBpbiBtb3JlIHRoYW4gb25lIGZ1bmN0aW9uIAogKi8Kc3RhdGljIHVsb25nCXN3YXBpbjsKc3RhdGljIHVsb25nCXN3YXBvdXQ7CnN0YXRpYyB1bG9uZwlibG9ja3NfcmVhZDsKc3RhdGljIHVsb25nCWJsb2Nrc193cml0ZTsKc3RhdGljIHVsb25nCWludGVycnVwdHM7CnN0YXRpYyB1bG9uZwljb250ZXh0X3N3OwoKLyoKICogU2luY2UgTUlCIHdhbnRzIENQVV9TWVNURU0sIHdoaWNoIGlzIENQVV9LRVJORUwgKyBDUFVfV0FJVCAKICovCnN0YXRpYyBsb25nCSBjcHVfcGVyY1tDUFVfU1RBVEVTXTsKCi8qCiAqIEhvdyBtYW55IHNuYXBzaG90cyB3ZSBoYXZlIGFscmVhZHkgdGFrZW4sIG5lZWRlZCBmb3IgdGhlIGZpcnN0IAogKiBQT0xMX0lOVEVSVkFMICogUE9MTF9WQUxVRVMgc2Vjb25kcyBvZiBhZ2VudCBydW5uaW5nIAogKi8Kc3RhdGljIHVuc2lnbmVkIGludCBudW1iZXJfb2Zfc25hcHNob3RzOwoKLyoKICogVGhlIHBsYWNlIHRvIHN0b3JlIHRoZSBzbmFwc2hvdHMgb2Ygc3lzdGVtIGRhdGEgaW4gCiAqLwpzdGF0aWMgc3RydWN0IGNwdV9zdGF0X3NuYXBzaG90IHNuYXBzaG90W1BPTExfVkFMVUVTICsgMV07CgovKgogKiBBbmQgb25lIGZvciB0aGUgcmF3IGNvdW50ZXJzLCB3aGljaCB3ZSBmaWxsIHdoZW4gdGhlIHJhdyB2YWx1ZXMgYXJlIAogKiByZXF1ZXN0ZWQsIGFzIG9wcG9zZWQgdG8gdGhlIGFic29sdXRlIHZhbHVlcywgd2hpY2ggYXJlIHRha2VuIGV2ZXJ5IAogKiBQT0xMX0lOVEVSVkFMIHNlY29uZHMgYW5kIGNhbGN1bGF0ZWQgb3ZlciBQT0xMX0lOVEVSVkFMICogUE9MTF9WQUxVRVMgdGltZSAKICovCnN0YXRpYyBzdHJ1Y3QgY3B1X3N0YXRfc25hcHNob3QgcmF3X3ZhbHVlczsKCi8qCiAqIEdsb2JhbCB2YXJpYWJsZXMgZW5kIGhlcmUgCiAqLwoKCi8qCiAqIEZ1bmN0aW9ucyBzdGFydCBoZXJlIAogKi8KCi8qCiAqIEZ1bmN0aW9uIHByb3RvdHlwZSAKICovCnN0YXRpYyB2b2lkCXVwZGF0ZV9zdGF0cyh1bnNpZ25lZCBpbnQgcmVnaXN0cmF0aW9uTnVtYmVyLCB2b2lkICpjbGllbnRhcmcpOwpzdGF0aWMgaW50CXRha2Vfc25hcHNob3Qoc3RydWN0IGNwdV9zdGF0X3NuYXBzaG90ICpjc3MpOwoKLyoKICogaW5pdF92bXN0YXRfYWl4NCBzdGFydHMgaGVyZSAKICogSW5pdCBmdW5jdGlvbiBmb3IgdGhpcyBtb2R1bGUsIGZyb20gcHJvdG90eXBlIAogKiBEZWZpbmVzIHZhcmlhYmxlcyBoYW5kbGVkIGJ5IHRoaXMgbW9kdWxlLCBkZWZpbmVzIHJvb3QgT0lEIGZvciAKICogdGhpcyBtb2R1bGUgYW5kIHJlZ2lzdGVycyBpdCB3aXRoIHRoZSBhZ2VudCAKICovCgpGaW5kVmFyTWV0aG9kIHZhcl9leHRlbnNpYmxlX3Ztc3RhdDsKCnZvaWQKaW5pdF92bXN0YXRfYWl4NCh2b2lkKQp7CgoJLyoKCSAqIFdoaWNoIHZhcmlhYmxlcyBkbyB3ZSBzZXJ2aWNlID8gCgkgKi8KCXN0cnVjdCB2YXJpYWJsZTIgZXh0ZW5zaWJsZV92bXN0YXRfdmFyaWFibGVzW10gPSB7CgkJe01JQklOREVYLCBBU05fSU5URUdFUiwgUk9OTFksIHZhcl9leHRlbnNpYmxlX3Ztc3RhdCwgMSwKCQkge01JQklOREVYfX0sCgkJe0VSUk9STkFNRSwgQVNOX09DVEVUX1NUUiwgUk9OTFksIHZhcl9leHRlbnNpYmxlX3Ztc3RhdCwgMSwKCQkge0VSUk9STkFNRX19LAoJCXtTV0FQSU4sIEFTTl9JTlRFR0VSLCBST05MWSwgdmFyX2V4dGVuc2libGVfdm1zdGF0LCAxLCB7U1dBUElOfX0sCgkJe1NXQVBPVVQsIEFTTl9JTlRFR0VSLCBST05MWSwgdmFyX2V4dGVuc2libGVfdm1zdGF0LCAxLCB7U1dBUE9VVH19LAoJCXtJT1NFTlQsIEFTTl9JTlRFR0VSLCBST05MWSwgdmFyX2V4dGVuc2libGVfdm1zdGF0LCAxLCB7SU9TRU5UfX0sCgkJe0lPUkVDRUlWRSwgQVNOX0lOVEVHRVIsIFJPTkxZLCB2YXJfZXh0ZW5zaWJsZV92bXN0YXQsIDEsCgkJIHtJT1JFQ0VJVkV9fSwKCQl7U1lTSU5URVJSVVBUUywgQVNOX0lOVEVHRVIsIFJPTkxZLCB2YXJfZXh0ZW5zaWJsZV92bXN0YXQsIDEsCgkJIHtTWVNJTlRFUlJVUFRTfX0sCgkJe1NZU0NPTlRFWFQsIEFTTl9JTlRFR0VSLCBST05MWSwgdmFyX2V4dGVuc2libGVfdm1zdGF0LCAxLAoJCSB7U1lTQ09OVEVYVH19LAoJCXtDUFVVU0VSLCBBU05fSU5URUdFUiwgUk9OTFksIHZhcl9leHRlbnNpYmxlX3Ztc3RhdCwgMSwge0NQVVVTRVJ9fSwKCQl7Q1BVU1lTVEVNLCBBU05fSU5URUdFUiwgUk9OTFksIHZhcl9leHRlbnNpYmxlX3Ztc3RhdCwgMSwKCQkge0NQVVNZU1RFTX19LAoJCXtDUFVJRExFLCBBU05fSU5URUdFUiwgUk9OTFksIHZhcl9leHRlbnNpYmxlX3Ztc3RhdCwgMSwge0NQVUlETEV9fSwKCQl7Q1BVUkFXVVNFUiwgQVNOX0NPVU5URVIsIFJPTkxZLCB2YXJfZXh0ZW5zaWJsZV92bXN0YXQsIDEsCgkJIHtDUFVSQVdVU0VSfX0sCgkJe0NQVVJBV1NZU1RFTSwgQVNOX0NPVU5URVIsIFJPTkxZLCB2YXJfZXh0ZW5zaWJsZV92bXN0YXQsIDEsCgkJIHtDUFVSQVdTWVNURU19fSwKCQl7Q1BVUkFXSURMRSwgQVNOX0NPVU5URVIsIFJPTkxZLCB2YXJfZXh0ZW5zaWJsZV92bXN0YXQsIDEsCgkJIHtDUFVSQVdJRExFfX0sCgkJe0NQVVJBV1dBSVQsIEFTTl9DT1VOVEVSLCBST05MWSwgdmFyX2V4dGVuc2libGVfdm1zdGF0LCAxLAoJCSB7Q1BVUkFXV0FJVH19LAoJCXtDUFVSQVdLRVJORUwsIEFTTl9DT1VOVEVSLCBST05MWSwgdmFyX2V4dGVuc2libGVfdm1zdGF0LCAxLAoJCSB7Q1BVUkFXS0VSTkVMfX0sCgkJe0lPUkFXU0VOVCwgQVNOX0NPVU5URVIsIFJPTkxZLCB2YXJfZXh0ZW5zaWJsZV92bXN0YXQsIDEsCgkJIHtJT1JBV1NFTlR9fSwKCQl7SU9SQVdSRUNFSVZFLCBBU05fQ09VTlRFUiwgUk9OTFksIHZhcl9leHRlbnNpYmxlX3Ztc3RhdCwgMSwKCQkge0lPUkFXUkVDRUlWRX19LAoJCXtTWVNSQVdJTlRFUlJVUFRTLCBBU05fQ09VTlRFUiwgUk9OTFksIHZhcl9leHRlbnNpYmxlX3Ztc3RhdCwgMSwKCQkge1NZU1JBV0lOVEVSUlVQVFN9fSwKCQl7U1lTUkFXQ09OVEVYVCwgQVNOX0NPVU5URVIsIFJPTkxZLCB2YXJfZXh0ZW5zaWJsZV92bXN0YXQsIDEsCgkJIHtTWVNSQVdDT05URVhUfX0sCgkJLyoKCQkgKiBGdXR1cmUgdXNlOiAKCQkgKiB7RVJST1JGTEFHLCBBU05fSU5URUdFUiwgUk9OTFksIHZhcl9leHRlbnNpYmxlX3Ztc3RhdCwgMSwge0VSUk9SRkxBRyB9fSwKCQkgKiB7RVJST1JNU0csIEFTTl9PQ1RFVF9TVFIsIFJPTkxZLCB2YXJfZXh0ZW5zaWJsZV92bXN0YXQsIDEsIHtFUlJPUk1TRyB9fQoJCSAqLwoJfTsKCgkvKgoJICogRGVmaW5lIHRoZSBPSUQgcG9pbnRlciB0byB0aGUgdG9wIG9mIHRoZSBtaWIgdHJlZSB0aGF0IHdlJ3JlIAoJICogcmVnaXN0ZXJpbmcgdW5kZXJuZWF0aCAKCSAqLwoJb2lkCQkJIHZtc3RhdF92YXJpYWJsZXNfb2lkW10gPSB7IE5FVFNOTVBfVUNEQVZJU19NSUIsIDExIH07CgoJLyoKCSAqIHJlZ2lzdGVyIG91cnNlbHZlcyB3aXRoIHRoZSBhZ2VudCB0byBoYW5kbGUgb3VyIG1pYiB0cmVlIAoJICogTElOVEVEIFRydXN0IG1lLCBJIGtub3cgd2hhdCBJJ20gZG9pbmcgCgkgKi8KCVJFR0lTVEVSX01JQigidWNkLXNubXAvdm1zdGF0IiwgZXh0ZW5zaWJsZV92bXN0YXRfdmFyaWFibGVzLCB2YXJpYWJsZTIsCgkJCQkgdm1zdGF0X3ZhcmlhYmxlc19vaWQpOwoKCS8qCgkgKiBTdGFydCB3aXRoIHNvbWUgdXNlZnVsIGRhdGEgCgkgKi8KCXVwZGF0ZV9zdGF0cygwLCBOVUxMKTsKCgkvKgoJICogdXBkYXRlX3N0YXRzIGlzIHJ1biBldmVyeSBQT0xMX0lOVEVSVkFMIHNlY29uZHMgdXNpbmcgdGhpcyByb3V0aW5lIAoJICogKHNlZSAnbWFuIHNubXBfYWxhcm0nKSAKCSAqIFRoaXMgaXMgb25seSBleGVjdXRlZCBvbmNlIHRvIGdldCBzb21lIHVzZWZ1bCBkYXRhIGluIHRoZSBiZWdpbm5pbmcgCgkgKi8KCWlmIChzbm1wX2FsYXJtX3JlZ2lzdGVyKDUsIE5VTEwsIHVwZGF0ZV9zdGF0cywgTlVMTCkgPT0gMCkgewoJCXNubXBfbG9nKExPR19XQVJOSU5HLAoJCQkJICJ2bXN0YXRfYWl4NCAoaW5pdCk6IHNubXBfYWxhcm1fcmVnaXN0ZXIgZmFpbGVkLlxuIik7Cgl9CgkvKgoJICogVGhpcyBpcyB0aGUgb25lIHRoYXQgcnVucyB1cGRhdGVfc3RhdHMgZXZlcnkgUE9MTF9JTlRFUlZBTCBzZWNvbmRzIAoJICovCglpZiAoc25tcF9hbGFybV9yZWdpc3RlcihQT0xMX0lOVEVSVkFMLCBTQV9SRVBFQVQsIHVwZGF0ZV9zdGF0cywgTlVMTCkKCQk9PSAwKSB7CgkJc25tcF9sb2coTE9HX0VSUiwKCQkJCSAidm1zdGF0X2FpeDQgKGluaXQpOiBzbm1wX2FsYXJtX3JlZ2lzdGVyIGZhaWxlZCwgY2Fubm90IHNlcnZpY2UgcmVxdWVzdHMuXG4iKTsKCX0KCn0JLyogaW5pdF92bXN0YXRfYWl4NCBlbmRzIGhlcmUgKi8KCi8qCiAqIERhdGEgY29sbGVjdGlvbiBmdW5jdGlvbiB0YWtlX3NuYXBzaG90IHN0YXJ0cyBoZXJlIAogKiBHZXQgZGF0YSBmcm9tIGtlcm5lbCBhbmQgc2F2ZSBpbnRvIHRoZSBzbmFwc2hvdCBzdHJ1dGNzIAogKiBBcmd1bWVudCBpcyB0aGUgc25hcHNob3Qgc3RydWN0IHRvIHNhdmUgdG8uIEdsb2JhbCBhbnl3YXksIGJ1dCBsb29rcyBuaWNlciAKICovCnN0YXRpYyBpbnQKdGFrZV9zbmFwc2hvdChzdHJ1Y3QgY3B1X3N0YXRfc25hcHNob3QgKmNzcykKewoJLyoKCSAqIFZhcmlhYmxlcyBzdGFydCBoZXJlIAoJICovCgoJLyoKCSAqIEhpZ2ggcmVzb2x1dGlvbiB0aW1lIGNvdW50ZXIgCgkgKi8KCXN0cnVjdCB0aW1ldmFsCQl0cDsKCXVuc2lnbmVkIGxvbmcgbG9uZwljdXJyZW50X3RpbWU7CgoJLyoKCSAqIHNlZSBsaWJwZXJmc3RhdC5oLCBob2xkcyBDUFUvbWVtb3J5IGRhdGEgCgkgKi8KCXBlcmZzdGF0X2NwdV90b3RhbF90CWNzOwoJcGVyZnN0YXRfbWVtb3J5X3RvdGFsX3QJbXM7CgoJLyoKCSAqIFRoZSB1c3VhbCBzdHVmZiB0byBjb3VudCBvbiwgZXJyLCBieSAKCSAqLwoJaW50CQkJaTsKCgkvKgoJICogVmFyaWFibGVzIGVuZCBoZXJlIAoJICovCgoJLyoKCSAqIEZ1bmN0aW9uIHN0YXJ0cyBoZXJlIAoJICovCgoJLyoKCSAqIEdldCB0aW1lIAoJICovCglnZXR0aW1lb2ZkYXkoJnRwLCAoc3RydWN0IHRpbWV6b25lICopTlVMTCk7CgljdXJyZW50X3RpbWUgPSB0cC50dl9zZWMgKiAodW5zaWduZWQgbG9uZyBsb25nKTEwMDAwMDAgKyB0cC50dl91c2VjOwoKCS8qCgkgKiBJZiB3ZSBoYXZlIGp1c3QgZ290dGVuIHRoZSBkYXRhLCByZXR1cm4gdGhlIHZhbHVlcyBmcm9tIGxhc3QgcnVuIChza2lwIGlmLWNsYXVzZSkgCgkgKiBUaGlzIGhhcHBlbnMgb24gYSBzbm1wd2FsayByZXF1ZXN0LiAgTm8gbmVlZCB0byByZWFkIHRoZSBwZXJmc3RhdCBhZ2FpbiAKCSAqIGlmIHdlIGp1c3QgZGlkIGl0IGxlc3MgdGhhbiAyIHNlY29uZHMgYWdvIAoJICogSnVtcHMgaW50byBpZi1jbGF1c2UgZWl0aGVyIHdoZW4gc25hcHNob3QgaXMgZW1wdHkgb3Igd2hlbiB0b28gb2xkIAoJICovCgoJaWYgKChjc3MtPmNzc190aW1lID09IDApCgkJfHwgKGN1cnJlbnRfdGltZSA+IGNzcy0+Y3NzX3RpbWUgKyAyMDAwMDAwKSkgewoJCS8qCgkJICogTWFrZSBzdXJlIHdlIGNsZWFuIHVwIGJlZm9yZSB3ZSBwdXQgbmV3IGRhdGEgaW50byBzbmFwc2hvdCAKCQkgKi8KCQltZW1zZXQoY3NzLCAwLCBzaXplb2YgKmNzcyk7CgoJCS8qCgkJICogVXBkYXRlIHRpbWVyIAoJCSAqLwoJCWNzcy0+Y3NzX3RpbWUgPSBjdXJyZW50X3RpbWU7CgoJCWlmKChwZXJmc3RhdF9jcHVfdG90YWwoKHBlcmZzdGF0X2lkX3QgKilOVUxMLCAmY3MsIHNpemVvZihwZXJmc3RhdF9jcHVfdG90YWxfdCksIDEpID4gMCkgJiYKCQkJKHBlcmZzdGF0X21lbW9yeV90b3RhbCgocGVyZnN0YXRfaWRfdCAqKU5VTEwsICZtcywgc2l6ZW9mKHBlcmZzdGF0X21lbW9yeV90b3RhbF90KSwgMSkgPiAwKSkgewoJCQljc3MtPmNzc19jcHVzID0gY3MubmNwdXM7CgkJCWNzcy0+Y3NzX3N3YXBpbiA9IG1zLnBnc3BpbnM7CgkJCWNzcy0+Y3NzX3N3YXBvdXQgPSBtcy5wZ3Nwb3V0czsKCQkJY3NzLT5jc3NfYmxvY2tzX3JlYWQgPSBjcy5zeXNyZWFkOwoJCQljc3MtPmNzc19ibG9ja3Nfd3JpdGUgPSBjcy5zeXN3cml0ZTsKCQkJY3NzLT5jc3NfaW50ZXJydXB0cyA9IGNzLmRldmludHJzICsgY3Muc29mdGludHJzOwoJCQljc3MtPmNzc19jb250ZXh0X3N3ID0gY3MucHN3aXRjaDsKCQkJY3NzLT5jc3NfY3B1W0NQVV9VU0VSXSA9IGNzLnVzZXI7CgkJCWNzcy0+Y3NzX2NwdVtDUFVfU1lTVEVNXSA9IGNzLnN5czsKCQkJY3NzLT5jc3NfY3B1W0NQVV9JRExFXSA9IGNzLmlkbGU7CgkJCWNzcy0+Y3NzX2NwdVtDUFVfV0FJVF0gPSBjcy53YWl0OwoJCX0KCX0KCgkvKgoJICogQWxsIGVuZ2luZXMgcnVubmluZyBhdCB3YXJwIHNwZWVkLCBubyBwcm9ibGVtcyAoaWYgdGhlcmUgYXJlIGFueSBlbmdpbmVzLCB0aGF0IGlzKSAKCSAqLwoJcmV0dXJuIChjcy5uY3B1cyA+IDAgPyAwIDogLTEpOwp9CS8qIHRha2Vfc25hcHNob3QgZW5kcyBoZXJlICovCgovKgogKiBUaGlzIGdldHMgY2FsbGVkIGV2ZXJ5IFBPTExfSU5URVJWQUwgc2Vjb25kcyB0byB1cGRhdGUgdGhlIHNuYXBzaG90cy4KICogSXQgdGFrZXMgYSBuZXcgc25hcHNob3QgYW5kIGRyb3BzIHRoZSBvbGRlc3Qgb25lLiAgVGhpcyB3YXkgd2UgbW92ZQogKiB0aGUgdGltZSB3aW5kb3cgc28gd2UgYWx3YXlzIHRha2UgdGhlIHZhbHVlcyBvdmVyIAogKiBQT0xMX0lOVEVSVkFMICogUE9MTF9WQUxVRVMgc2Vjb25kcyBhbmQgdXBkYXRlIHRoZSBkYXRhIHVzZWQgZXZlcnkKICogUE9MTF9JTlRFUlZBTCBzZWNvbmRzIAogKiBUaGUgYWxhcm0gdGltZXIgaXMgaW4gdGhlIGluaXQgZnVuY3Rpb24gb2YgdGhpcyBtb2R1bGUgKHNubXBfYWxhcm1fcmVnaXN0ZXIpIAogKi8KLyoKICogQVJHU1VTRUQwIAogKi8Kc3RhdGljIHZvaWQKdXBkYXRlX3N0YXRzKHVuc2lnbmVkIGludCByZWdpc3RyYXRpb25OdW1iZXIsIHZvaWQgKmNsaWVudGFyZykKewoJLyoKCSAqIFRoZSB0aW1lIGJldHdlZW4gdGhlIHNhbXBsZXMgd2UgY29tcGFyZSAKCSAqLwoJdW5zaWduZWQgbG9uZyBsb25nIHRpbWVfZGlmZjsKCgkvKgoJICogRWFzaWVyIHRvIHVzZSB0aGVzZSB0aGFuIHRoZSBzbmFwc2hvdHMsIHNob3J0IGhhbmQgcG9pbnRlcnMgCgkgKi8KCXN0cnVjdCBjcHVfc3RhdF9zbmFwc2hvdCAqY3NzX29sZCwgKmNzc19uZXc7CgoJLyoKCSAqIFRoZSB1c3VhbCBzdHVmZiB0byBjb3VudCBvbiwgZXJyLCBieSAKCSAqLwoJaW50CQkJIGk7CgoJLyoKCSAqIFRoZSBzdW0gb2YgdGhlIENQVSB0aWNrcyB0aGF0IGhhdmUgcGFzc2VkIG9uIHRoZSBkaWZmZXJlbnQgQ1BVIHN0YXRlcywgc28gd2UgY2FuIGNhbGN1bGF0ZSAKCSAqIHRoZSBwZXJjZW50YWdlcyBvZiBlYWNoIHN0YXRlIAoJICovCgl1bnNpZ25lZCBsb25nIGxvbmcgY3B1X3N1bSA9IDA7CgoJREVCVUdNU0dUTCgoInVjZC1zbm1wL3Ztc3RhdF9haXg0LmM6dXBkYXRlX3N0YXRzIiwKCQkJCSJ1cGRhdGluZyBzdGF0c1xuIikpOwoKCS8qCgkgKiBUYWtlIHRoZSBjdXJyZW50IHNuYXBzaG90IAoJICovCglpZiAodGFrZV9zbmFwc2hvdCgmc25hcHNob3RbMF0pID09IC0xKSB7CgkJc25tcF9sb2coTE9HX1dBUk5JTkcsCgkJCQkgInZtc3RhdF9haXg0ICh1cGRhdGVfc3RhdHMpOiBTb21ldGhpbmcgd2VudCB3cm9uZyB3aXRoIHRha2Vfc25hcHNob3QuXG4iKTsKCQlyZXR1cm47Cgl9CgoJLyoKCSAqIERvIHdlIGhhdmUgc29tZSBkYXRhIHdlIGNhbiB1c2UgPyAgQW4gaXNzdWUgcmlnaHQgYWZ0ZXIgdGhlIHN0YXJ0IG9mIHRoZSBhZ2VudCAKCSAqLwoJaWYgKG51bWJlcl9vZl9zbmFwc2hvdHMgPiAwKSB7CgkJLyoKCQkgKiBIdWgsIHRoZSBudW1iZXIgb2YgQ1BVcyBjaGFuZ2VkIGR1cmluZyBydW4gdGltZS4gIFRoYXQgaXMgaW5kZWVkIHMudGguIHdvcnRoIG5vdGluZywgd2UgCgkJICogb3V0cHV0IGEgaHVtb3JvdXMgKG1vcmUgb3IgbGVzcykgc3lzbG9nIG1lc3NhZ2UgYW5kIG5lZWQgdG8gcmV0YWtlIHRoZSBzbmFwc2hvdHMgCgkJICovCgkJaWYgKHNuYXBzaG90WzBdLmNzc19jcHVzICE9IHNuYXBzaG90WzFdLmNzc19jcHVzKSB7CgkJCWlmIChzbmFwc2hvdFswXS5jc3NfY3B1cyA+IHNuYXBzaG90WzFdLmNzc19jcHVzKSB7CgkJCQlzbm1wX2xvZyhMT0dfTk9USUNFLAoJCQkJCQkgInZtc3RhdF9haXg0ICh1cGRhdGVfc3RhdHMpOiBDb29sICEgTnVtYmVyIG9mIENQVXMgaW5jcmVhc2VkLCBtdXN0IGJlIGhvdC1wbHVnZ2FibGUuXG4iKTsKCQkJfSBlbHNlIHsKCQkJCXNubXBfbG9nKExPR19OT1RJQ0UsCgkJCQkJCSAidm1zdGF0X2FpeDQgKHVwZGF0ZV9zdGF0cyk6IExvc3QgYXQgbGVhc3Qgb25lIENQVSwgUklQLlxuIik7CgkJCX0KCQkJLyoKCQkJICogTWFrZSBhbGwgc25hcHNob3RzIGJ1dCB0aGUgY3VycmVudCBvbmUgaW52YWxpZCAKCQkJICovCgkJCW51bWJlcl9vZl9zbmFwc2hvdHMgPSAxOwoJCQkvKgoJCQkgKiBNb3ZlIHRoZSBjdXJyZW50IG9uZSBpbiB0aGUgImZpcnN0IiBbMV0gc2xvdCAKCQkJICovCgkJCW1lbW1vdmUoJnNuYXBzaG90WzFdLCAmc25hcHNob3RbMF0sIHNpemVvZiBzbmFwc2hvdFswXSk7CgkJCS8qCgkJCSAqIEVyYXNlIHRoZSBjdXJyZW50IG9uZSAKCQkJICovCgkJCW1lbXNldCgmc25hcHNob3RbMF0sIDAsIHNpemVvZiBzbmFwc2hvdFswXSk7CgkJCS8qCgkJCSAqIFRyeSB0byBnZXQgYSBuZXcgc25hcHNob3QgaW4gZml2ZSBzZWNvbmRzIHNvIHdlIGNhbiByZXR1cm4gcy50aC4gdXNlZnVsIAoJCQkgKi8KCQkJaWYgKHNubXBfYWxhcm1fcmVnaXN0ZXIoNSwgTlVMTCwgdXBkYXRlX3N0YXRzLCBOVUxMKSA9PSAwKSB7CgkJCQlzbm1wX2xvZyhMT0dfV0FSTklORywKCQkJCQkJICJ2bXN0YXRfYWl4NCAodXBkYXRlX3N0YXRzKTogc25tcF9hbGFybV9yZWdpc3RlciBmYWlsZWQuXG4iKTsKCQkJfQoJCQlyZXR1cm47CgkJfQoKCQkvKgoJCSAqIFNob3J0IGhhbmQgcG9pbnRlcnMgCgkJICovCgkJY3NzX25ldyA9ICZzbmFwc2hvdFswXTsKCQljc3Nfb2xkID0gJnNuYXBzaG90W251bWJlcl9vZl9zbmFwc2hvdHNdOwoKCQkvKgoJCSAqIEhvdyBtdWNoIHRpbWUgaGFzIHBhc3NlZCBiZXR3ZWVuIHRoZSBzbmFwc2hvdHMgd2UgZ2V0IHRoZSB2YWx1ZXMgZnJvbSA/IAoJCSAqLwoJCXRpbWVfZGlmZiA9CgkJCShzbmFwc2hvdFswXS5jc3NfdGltZSAtCgkJCSBzbmFwc2hvdFtudW1iZXJfb2Zfc25hcHNob3RzXS5jc3NfdGltZSkgLyAxMDAwOwoKCQlERUJVR01TR1RMKCgidWNkLXNubXAvdm1zdGF0X2FpeDQuYzp1cGRhdGVfc3RhdHMiLAoJCQkJCSJ0aW1lX2RpZmY6ICVsbGRcbiIsIHRpbWVfZGlmZikpOwoKCQkvKgoJCSAqIHN3YXBpbiBhbmQgc3dhcG91dCBhcmUgaW4gcGFnZXMsIE1JQiB3YW50cyBrQi9zLHNvIHdlIGp1c3QgbmVlZCB0byBnZXQga0IgYW5kIHNlY29uZHMgCgkJICogRm9yIHRoZSBvdGhlcnMgd2UgbmVlZCB0byBnZXQgdmFsdWUgcGVyIHNlY29uZCAKCQkgKiBnZXRwYWdlc2l6ZSgpIHJldHVybnMgcGFnZXNpemUgaW4gYnl0ZXMgCgkJICovCgkJLyoKCQkgKiBMSU5URUQgY2FzdCBuZWVkZWQsIHJlYWxseSAKCQkgKi8KCQlzd2FwaW4gPQoJCQkodWludF90KSAoKGNzc19uZXctPmNzc19zd2FwaW4gLSBjc3Nfb2xkLT5jc3Nfc3dhcGluKSAqCgkJCQkJICBnZXRwYWdlc2l6ZSgpIC8gMTAyNCAvIHRpbWVfZGlmZik7CgkJLyoKCQkgKiBMSU5URUQgY2FzdCBuZWVkZWQsIHJlYWxseSAKCQkgKi8KCQlzd2Fwb3V0ID0KCQkJKHVpbnRfdCkgKChjc3NfbmV3LT5jc3Nfc3dhcG91dCAtIGNzc19vbGQtPmNzc19zd2Fwb3V0KSAqCgkJCQkJICBnZXRwYWdlc2l6ZSgpIC8gMTAyNCAvIHRpbWVfZGlmZik7CgkJLyoKCQkgKiBMSU5URUQgY2FzdCBuZWVkZWQsIHJlYWxseSAKCQkgKi8KCQlibG9ja3NfcmVhZCA9CgkJCSh1aW50X3QpICgoY3NzX25ldy0+Y3NzX2Jsb2Nrc19yZWFkIC0gY3NzX29sZC0+Y3NzX2Jsb2Nrc19yZWFkKSAvCgkJCQkJICB0aW1lX2RpZmYpOwoJCS8qCgkJICogTElOVEVEIGNhc3QgbmVlZGVkLCByZWFsbHkgCgkJICovCgkJYmxvY2tzX3dyaXRlID0KCQkJKHVpbnRfdCkgKChjc3NfbmV3LT5jc3NfYmxvY2tzX3dyaXRlIC0gY3NzX29sZC0+Y3NzX2Jsb2Nrc193cml0ZSkgLwoJCQkJCSAgdGltZV9kaWZmKTsKCQkvKgoJCSAqIExJTlRFRCBjYXN0IG5lZWRlZCwgcmVhbGx5IAoJCSAqLwoJCWludGVycnVwdHMgPQoJCQkodWludF90KSAoKGNzc19uZXctPmNzc19pbnRlcnJ1cHRzIC0gY3NzX29sZC0+Y3NzX2ludGVycnVwdHMpIC8KCQkJCQkgIHRpbWVfZGlmZik7CgkJLyoKCQkgKiBMSU5URUQgY2FzdCBuZWVkZWQsIHJlYWxseSAKCQkgKi8KCQljb250ZXh0X3N3ID0KCQkJKHVpbnRfdCkgKChjc3NfbmV3LT5jc3NfY29udGV4dF9zdyAtIGNzc19vbGQtPmNzc19jb250ZXh0X3N3KSAvCgkJCQkJICB0aW1lX2RpZmYpOwoKCQkvKgoJCSAqIExvb3AgdGhydSBhbGwgdGhlIENQVV9TVEFURVMgYW5kIGdldCB0aGUgZGlmZmVyZW5jZXMgCgkJICovCgkJZm9yIChpID0gMDsgaSA8IENQVV9TVEFURVM7IGkrKykgewoJCQljcHVfc3VtICs9IChjc3NfbmV3LT5jc3NfY3B1W2ldIC0gY3NzX29sZC0+Y3NzX2NwdVtpXSk7CgkJfQoKCQkvKgoJCSAqIE5vdyBjYWxjdWxhdGUgdGhlIGFic29sdXRlIHBlcmNlbnRhZ2UgdmFsdWVzIAoJCSAqIExvb2tzIHNvbWV3aGF0IGNvbXBsaWNhdGVkIHNvbWV0aW1lcyBidXQgdHJpZXMgdG8gZ2V0IGFyb3VuZCB1c2luZyBmbG9hdHMgdG8gaW5jcmVhc2Ugc3BlZWQgCgkJICovCgkJZm9yIChpID0gMDsgaSA8IENQVV9TVEFURVM7IGkrKykgewoJCQkvKgoJCQkgKiBTaW5jZSB3ZSBkb24ndCByZXR1cm4gZnJhY3Rpb25zIHdlIHVzZSArIDAuNSB0byBnZXQgYmV0d2VlbiA5OSBhbmQgMTAxIHBlcmNlbnQgYWRkaW5nIHRoZSB2YWx1ZXMgCgkJCSAqIHRvZ2V0aGVyLCBvdGhlcndpc2Ugd2Ugd291bGQgZ2V0IGxlc3MgdGhhbiAxMDAgbW9zdCBvZiB0aGUgdGltZSAKCQkJICovCgkJCS8qCgkJCSAqIExJTlRFRCBoYXMgdG8gYmUgJ2xvbmcnIAoJCQkgKi8KCQkJY3B1X3BlcmNbaV0gPQoJCQkJKGxvbmcpICgoKGNzc19uZXctPmNzc19jcHVbaV0gLSBjc3Nfb2xkLT5jc3NfY3B1W2ldKSAqIDEwMCArCgkJCQkJCSAoY3B1X3N1bSAvIDIpKSAvIGNwdV9zdW0pOwoJCX0KCQkvKiAic3lzdGVtIiBpcyAia2VybmVsIiwgd2UgaGF2ZSB0byBhZGQgIndhaXQiIHRvIGdldCB0aGUgY29ycmVjdCB2YWx1ZSAqLwoJCWNwdV9wZXJjW0NQVV9TWVNURU1dICs9IGNwdV9wZXJjW0NQVV9XQUlUXTsKCX0KCgkvKgoJICogTWFrZSB0aGUgY3VycmVudCBvbmUgdGhlIGZpcnN0IG9uZSBhbmQgbW92ZSB0aGUgd2hvbGUgdGhpbmcgb25lIHBsYWNlIGRvd24gCgkgKi8KCW1lbW1vdmUoJnNuYXBzaG90WzFdLCAmc25hcHNob3RbMF0sCgkJCShzaXplX3QpICgoKGNoYXIgKikgJnNuYXBzaG90W1BPTExfVkFMVUVTXSkgLQoJCQkJCSAgKChjaGFyICopICZzbmFwc2hvdFswXSkpKTsKCgkvKgoJICogRXJhc2UgdGhlIGN1cnJlbnQgb25lIAoJICovCgltZW1zZXQoJnNuYXBzaG90WzBdLCAwLCBzaXplb2Ygc25hcHNob3RbMF0pOwoKCS8qCgkgKiBPbmx5IGltcG9ydGFudCBvbiBzdGFydCB1cCwgd2Uga2VlcCB0cmFjayBvZiBob3cgbWFueSBzbmFwc2hvdHMgd2UgaGF2ZSB0YWtlbiBzbyBmYXIgCgkgKi8KCWlmIChudW1iZXJfb2Zfc25hcHNob3RzIDwgUE9MTF9WQUxVRVMpIHsKCQludW1iZXJfb2Zfc25hcHNob3RzKys7Cgl9Cn0JCQkJCQkJICAgLyogdXBkYXRlX3N0YXRzIGVuZHMgaGVyZSAqLwoKLyoKICogKnZhcl9leHRlbnNpYmxlX3Ztc3RhdCBzdGFydHMgaGVyZSAKICogVGhlIGd1dHMgb2YgdGhlIG1vZHVsZSwgdGhpcyByb3V0aW5lIGdldHMgY2FsbGVkIHRvIHNlcnZpY2UgYSByZXF1ZXN0IAogKi8KdW5zaWduZWQgY2hhciAqCnZhcl9leHRlbnNpYmxlX3Ztc3RhdChzdHJ1Y3QgdmFyaWFibGUgKnZwLAoJCQkJCSAgb2lkICogbmFtZSwKCQkJCQkgIHNpemVfdCAqIGxlbmd0aCwKCQkJCQkgIGludCBleGFjdCwKCQkJCQkgIHNpemVfdCAqIHZhcl9sZW4sIFdyaXRlTWV0aG9kICoqIHdyaXRlX21ldGhvZCkKewoJLyoKCSAqIE5lZWRlZCBmb3IgcmV0dXJuaW5nIHRoZSB2YWx1ZXMgCgkgKi8KCXN0YXRpYyBsb25nCSBsb25nX3JldDsKCXN0YXRpYyBjaGFyCSBlcnJtc2dbMzAwXTsKCgkvKgoJICogc2V0IHRvIDAgYXMgZGVmYXVsdCAKCSAqLwoJbG9uZ19yZXQgPSAwOwoKCS8qCgkgKiBnZW5lcmljIGNoZWNrIHdoZXRoZXIgdGhlIG9wdGlvbnMgcGFzc2VkIG1ha2Ugc2Vuc2UgYW5kIHdoZXRoZXIgdGhlIAoJICovCgkvKgoJICogcmlnaHQgdmFyaWFibGUgaXMgcmVxdWVzdGVkIAoJICovCglpZiAoaGVhZGVyX2dlbmVyaWModnAsIG5hbWUsIGxlbmd0aCwgZXhhY3QsIHZhcl9sZW4sIHdyaXRlX21ldGhvZCkgIT0KCQlNQVRDSF9TVUNDRUVERUQpIHsKCQlyZXR1cm4gKE5VTEwpOwoJfQoKCS8qCgkgKiBUaGUgZnVuY3Rpb24gdGhhdCBhY3R1YWxseSByZXR1cm5zIHMudGguIAoJICovCglzd2l0Y2ggKHZwLT5tYWdpYykgewoJY2FzZSBNSUJJTkRFWDoKCQlsb25nX3JldCA9IDE7CgkJcmV0dXJuICgodV9jaGFyICopICgmbG9uZ19yZXQpKTsKCWNhc2UgRVJST1JOQU1FOgkJCS8qIGR1bW15IG5hbWUgKi8KCQlzcHJpbnRmKGVycm1zZywgInN5c3RlbVN0YXRzIik7CgkJKnZhcl9sZW4gPSBzdHJsZW4oZXJybXNnKTsKCQlyZXR1cm4gKCh1X2NoYXIgKikgKGVycm1zZykpOwoJY2FzZSBTV0FQSU46CgkJcmV0dXJuICgodV9jaGFyICopICgmc3dhcGluKSk7CgljYXNlIFNXQVBPVVQ6CgkJcmV0dXJuICgodV9jaGFyICopICgmc3dhcG91dCkpOwoJY2FzZSBJT1NFTlQ6CgkJcmV0dXJuICgodV9jaGFyICopICgmYmxvY2tzX3dyaXRlKSk7CgljYXNlIElPUkVDRUlWRToKCQlyZXR1cm4gKCh1X2NoYXIgKikgKCZibG9ja3NfcmVhZCkpOwoJY2FzZSBTWVNJTlRFUlJVUFRTOgoJCXJldHVybiAoKHVfY2hhciAqKSAoJmludGVycnVwdHMpKTsKCWNhc2UgU1lTQ09OVEVYVDoKCQlyZXR1cm4gKCh1X2NoYXIgKikgKCZjb250ZXh0X3N3KSk7CgljYXNlIENQVVVTRVI6CgkJcmV0dXJuICgodV9jaGFyICopICgmY3B1X3BlcmNbQ1BVX1VTRVJdKSk7CgljYXNlIENQVVNZU1RFTToKCQlyZXR1cm4gKCh1X2NoYXIgKikgKCZjcHVfcGVyY1tDUFVfU1lTVEVNXSkpOwoJY2FzZSBDUFVJRExFOgoJCXJldHVybiAoKHVfY2hhciAqKSAoJmNwdV9wZXJjW0NQVV9JRExFXSkpOwoJY2FzZSBDUFVSQVdVU0VSOgoJCXRha2Vfc25hcHNob3QoJnJhd192YWx1ZXMpOwoJCS8qCgkJICogTElOVEVEIGhhcyB0byBiZSAnbG9uZycgCgkJICovCgkJbG9uZ19yZXQgPQoJCQkobG9uZykgKHJhd192YWx1ZXMuY3NzX2NwdVtDUFVfVVNFUl0gLyByYXdfdmFsdWVzLmNzc19jcHVzKTsKCQlyZXR1cm4gKCh1X2NoYXIgKikgKCZsb25nX3JldCkpOwoJCS8qCgkJICogV2UgYXJlIG1pc3NpbmcgQ1BVUkFXTklDRSwgQUlYIGRvZXMgbm90IGFjY291bnQgZm9yIHRoaXMgaW4gdGhlIGtlcm5lbCBzbyB0aGlzIE9JRCBjYW4gbm90IAoJCSAqIGJlIHJldHVybmVkLiAgQWxzbywgdGhlc2UgdmFsdWVzIHdpbGwgcm9sbCBvdmVyIHNvb25lciBvciBsYXRlciBhbmQgdGhlbiByZXR1cm4gaW5hY2N1cmF0ZSBkYXRhIAoJCSAqIGJ1dCB0aGUgTUlCIHdhbnRzIEludGVnZXIzMiBzbyB3ZSBjYW5ub3QgcHV0IGEgY291bnRlciBoZXJlIAoJCSAqIChIYXMgYmVlbiBjaGFuZ2VkIHRvIENvdW50ZXIzMiBpbiB0aGUgbGF0ZXN0IE1JQiB2ZXJzaW9uISkgCgkJICovCgljYXNlIENQVVJBV1NZU1RFTToKCQl0YWtlX3NuYXBzaG90KCZyYXdfdmFsdWVzKTsKCQkvKgoJCSAqIExJTlRFRCBoYXMgdG8gYmUgJ2xvbmcnIAoJCSAqLwoJCWxvbmdfcmV0ID0KCQkJKGxvbmcpICgocmF3X3ZhbHVlcy5jc3NfY3B1W0NQVV9TWVNURU1dICsKCQkJCQkgcmF3X3ZhbHVlcy5jc3NfY3B1W0NQVV9XQUlUXSkgLyByYXdfdmFsdWVzLmNzc19jcHVzKTsKCQlyZXR1cm4gKCh1X2NoYXIgKikgKCZsb25nX3JldCkpOwoJY2FzZSBDUFVSQVdJRExFOgoJCXRha2Vfc25hcHNob3QoJnJhd192YWx1ZXMpOwoJCS8qCgkJICogTElOVEVEIGhhcyB0byBiZSAnbG9uZycgCgkJICovCgkJbG9uZ19yZXQgPQoJCQkobG9uZykgKHJhd192YWx1ZXMuY3NzX2NwdVtDUFVfSURMRV0gLyByYXdfdmFsdWVzLmNzc19jcHVzKTsKCQlyZXR1cm4gKCh1X2NoYXIgKikgKCZsb25nX3JldCkpOwoJY2FzZSBDUFVSQVdXQUlUOgoJCXRha2Vfc25hcHNob3QoJnJhd192YWx1ZXMpOwoJCS8qCgkJICogTElOVEVEIGhhcyB0byBiZSAnbG9uZycgCgkJICovCgkJbG9uZ19yZXQgPQoJCQkobG9uZykgKHJhd192YWx1ZXMuY3NzX2NwdVtDUFVfV0FJVF0gLyByYXdfdmFsdWVzLmNzc19jcHVzKTsKCQlyZXR1cm4gKCh1X2NoYXIgKikgKCZsb25nX3JldCkpOwoJY2FzZSBDUFVSQVdLRVJORUw6CgkJdGFrZV9zbmFwc2hvdCgmcmF3X3ZhbHVlcyk7CgkJLyoKCQkgKiBMSU5URUQgaGFzIHRvIGJlICdsb25nJyAKCQkgKi8KCQlsb25nX3JldCA9CgkJCShsb25nKSAocmF3X3ZhbHVlcy5jc3NfY3B1W0NQVV9TWVNURU1dIC8gcmF3X3ZhbHVlcy5jc3NfY3B1cyk7CgkJcmV0dXJuICgodV9jaGFyICopICgmbG9uZ19yZXQpKTsKCWNhc2UgSU9SQVdTRU5UOgoJCWxvbmdfcmV0ID0gKGxvbmcpIChyYXdfdmFsdWVzLmNzc19ibG9ja3Nfd3JpdGUpOwoJCXJldHVybiAoKHVfY2hhciAqKSAoJmxvbmdfcmV0KSk7CgljYXNlIElPUkFXUkVDRUlWRToKCQlsb25nX3JldCA9IChsb25nKSAocmF3X3ZhbHVlcy5jc3NfYmxvY2tzX3JlYWQpOwoJCXJldHVybiAoKHVfY2hhciAqKSAoJmxvbmdfcmV0KSk7CgljYXNlIFNZU1JBV0lOVEVSUlVQVFM6CgkJbG9uZ19yZXQgPSAobG9uZykgKHJhd192YWx1ZXMuY3NzX2ludGVycnVwdHMpOwoJCXJldHVybiAoKHVfY2hhciAqKSAoJmxvbmdfcmV0KSk7CgljYXNlIFNZU1JBV0NPTlRFWFQ6CgkJbG9uZ19yZXQgPSAobG9uZykgKHJhd192YWx1ZXMuY3NzX2NvbnRleHRfc3cpOwoJCXJldHVybiAoKHVfY2hhciAqKSAoJmxvbmdfcmV0KSk7CgoJCS8qCgkJICogcmVzZXJ2ZWQgZm9yIGZ1dHVyZSB1c2UgCgkJICovCgkJLyoKCQkgKiBjYXNlIEVSUk9SRkxBRzoKCQkgKiByZXR1cm4oKHVfY2hhciAqKSAoJmxvbmdfcmV0KSk7CgkJICogY2FzZSBFUlJPUk1TRzoKCQkgKiByZXR1cm4oKHVfY2hhciAqKSAoJmxvbmdfcmV0KSk7CgkJICovCglkZWZhdWx0OgoJCXNubXBfbG9nKExPR19FUlIsCgkJCQkgInZtc3RhdF9haXg0OiBFcnJvciBpbiByZXF1ZXN0LCBubyBtYXRjaCBmb3VuZC5cbiIpOwoJfQoJcmV0dXJuIChOVUxMKTsKfQkJCQkJCQkgICAvKiAqdmFyX2V4dGVuc2libGVfdm1zdGF0IGVuZHMgaGVyZSAqLwoKLyoKICogRnVuY3Rpb25zIGVuZCBoZXJlIAogKi8KCi8qCiAqIFByb2dyYW0gZW5kcyBoZXJlIAogKi8K