LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgICAKICogRmlsZW5hbWU6ICAgICAgaXJsYW5fY2xpZW50LmMKICogVmVyc2lvbjogICAgICAgMC45CiAqIERlc2NyaXB0aW9uOiAgIElyREEgTEFOIEFjY2VzcyBQcm90b2NvbCAoSXJMQU4pIENsaWVudAogKiBTdGF0dXM6ICAgICAgICBFeHBlcmltZW50YWwuCiAqIEF1dGhvcjogICAgICAgIERhZyBCcmF0dGxpIDxkYWdiQGNzLnVpdC5ubz4KICogQ3JlYXRlZCBhdDogICAgU3VuIEF1ZyAzMSAyMDoxNDozNyAxOTk3CiAqIE1vZGlmaWVkIGF0OiAgIFR1ZSBEZWMgMTQgMTU6NDc6MDIgMTk5OQogKiBNb2RpZmllZCBieTogICBEYWcgQnJhdHRsaSA8ZGFnYkBjcy51aXQubm8+CiAqIFNvdXJjZXM6ICAgICAgIHNrZWxldG9uLmMgYnkgRG9uYWxkIEJlY2tlciA8YmVja2VyQENFU0RJUy5nc2ZjLm5hc2EuZ292PgogKiAgICAgICAgICAgICAgICBzbGlwLmMgYnkgTGF1cmVuY2UgQ3VsaGFuZSwgPGxvekBob2xtZXMuZGVtb24uY28udWs+CiAqICAgICAgICAgICAgICAgICAgICAgICAgICBGcmVkIE4uIHZhbiBLZW1wZW4sIDx3YWx0amVAdXdhbHQubmwubXVnbmV0Lm9yZz4KICogCiAqICAgICBDb3B5cmlnaHQgKGMpIDE5OTgtMTk5OSBEYWcgQnJhdHRsaSA8ZGFnYkBjcy51aXQubm8+LCAKICogICAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqICAgICAKICogICAgIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgCiAqICAgICBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyAKICogICAgIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIAogKiAgICAgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqICAgICBOZWl0aGVyIERhZyBCcmF0dGxpIG5vciBVbml2ZXJzaXR5IG9mIFRyb21z+CBhZG1pdCBsaWFiaWxpdHkgbm9yCiAqICAgICBwcm92aWRlIHdhcnJhbnR5IGZvciBhbnkgb2YgdGhpcyBzb2Z0d2FyZS4gVGhpcyBtYXRlcmlhbCBpcyAKICogICAgIHByb3ZpZGVkICJBUy1JUyIgYW5kIGF0IG5vIGNoYXJnZS4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgojaW5jbHVkZSA8bGludXgvc3RyaW5nLmg+CiNpbmNsdWRlIDxsaW51eC9lcnJuby5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvbmV0ZGV2aWNlLmg+CiNpbmNsdWRlIDxsaW51eC9ldGhlcmRldmljZS5oPgojaW5jbHVkZSA8bGludXgvaWZfYXJwLmg+CiNpbmNsdWRlIDxsaW51eC9iaXRvcHMuaD4KI2luY2x1ZGUgPG5ldC9hcnAuaD4KCiNpbmNsdWRlIDxhc20vc3lzdGVtLmg+CiNpbmNsdWRlIDxhc20vYnl0ZW9yZGVyLmg+CgojaW5jbHVkZSA8bmV0L2lyZGEvaXJkYS5oPgojaW5jbHVkZSA8bmV0L2lyZGEvaXJ0dHAuaD4KI2luY2x1ZGUgPG5ldC9pcmRhL2lybG1wLmg+CiNpbmNsdWRlIDxuZXQvaXJkYS9pcmlhc19vYmplY3QuaD4KI2luY2x1ZGUgPG5ldC9pcmRhL2lyaWFwLmg+CiNpbmNsdWRlIDxuZXQvaXJkYS90aW1lci5oPgoKI2luY2x1ZGUgPG5ldC9pcmRhL2lybGFuX2NvbW1vbi5oPgojaW5jbHVkZSA8bmV0L2lyZGEvaXJsYW5fZXZlbnQuaD4KI2luY2x1ZGUgPG5ldC9pcmRhL2lybGFuX2V0aC5oPgojaW5jbHVkZSA8bmV0L2lyZGEvaXJsYW5fcHJvdmlkZXIuaD4KI2luY2x1ZGUgPG5ldC9pcmRhL2lybGFuX2NsaWVudC5oPgoKI3VuZGVmIENPTkZJR19JUkxBTl9HUkFUVUlUT1VTX0FSUAoKc3RhdGljIHZvaWQgaXJsYW5fY2xpZW50X2N0cmxfZGlzY29ubmVjdF9pbmRpY2F0aW9uKHZvaWQgKmluc3RhbmNlLCB2b2lkICpzYXAsIAoJCQkJCQkgICAgTE1fUkVBU09OIHJlYXNvbiwgCgkJCQkJCSAgICBzdHJ1Y3Qgc2tfYnVmZiAqKTsKc3RhdGljIGludCBpcmxhbl9jbGllbnRfY3RybF9kYXRhX2luZGljYXRpb24odm9pZCAqaW5zdGFuY2UsIHZvaWQgKnNhcCwgCgkJCQkJICAgICBzdHJ1Y3Qgc2tfYnVmZiAqc2tiKTsKc3RhdGljIHZvaWQgaXJsYW5fY2xpZW50X2N0cmxfY29ubmVjdF9jb25maXJtKHZvaWQgKmluc3RhbmNlLCB2b2lkICpzYXAsIAoJCQkJCSAgICAgIHN0cnVjdCBxb3NfaW5mbyAqcW9zLCAKCQkJCQkgICAgICBfX3UzMiBtYXhfc2R1X3NpemUsCgkJCQkJICAgICAgX191OCBtYXhfaGVhZGVyX3NpemUsCgkJCQkJICAgICAgc3RydWN0IHNrX2J1ZmYgKik7CnN0YXRpYyB2b2lkIGlybGFuX2NoZWNrX3Jlc3BvbnNlX3BhcmFtKHN0cnVjdCBpcmxhbl9jYiAqc2VsZiwgY2hhciAqcGFyYW0sIAoJCQkJICAgICAgIGNoYXIgKnZhbHVlLCBpbnQgdmFsX2xlbik7CnN0YXRpYyB2b2lkIGlybGFuX2NsaWVudF9vcGVuX2N0cmxfdHNhcChzdHJ1Y3QgaXJsYW5fY2IgKnNlbGYpOwoKc3RhdGljIHZvaWQgaXJsYW5fY2xpZW50X2tpY2tfdGltZXJfZXhwaXJlZCh2b2lkICpkYXRhKQp7CglzdHJ1Y3QgaXJsYW5fY2IgKnNlbGYgPSAoc3RydWN0IGlybGFuX2NiICopIGRhdGE7CgkKCUlSREFfREVCVUcoMiwgIiVzKClcbiIsIF9fRlVOQ1RJT05fXyApOwoKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBJUkxBTl9NQUdJQywgcmV0dXJuOyk7CgkKCS8qICAKCSAqIElmIHdlIGFyZSBpbiBwZWVyIG1vZGUsIHRoZSBjbGllbnQgbWF5IG5vdCBoYXZlIGdvdCB0aGUgZGlzY292ZXJ5CgkgKiBpbmRpY2F0aW9uIGl0IG5lZWRzIHRvIG1ha2UgcHJvZ3Jlc3MuIElmIHRoZSBjbGllbnQgaXMgc3RpbGwgaW4gCgkgKiBJRExFIHN0YXRlLCB3ZSBtdXN0IGtpY2sgaXQgdG8sIGJ1dCBvbmx5IGlmIHRoZSBwcm92aWRlciBpcyBub3QgSURMRQogCSAqLwoJaWYgKChzZWxmLT5wcm92aWRlci5hY2Nlc3NfdHlwZSA9PSBBQ0NFU1NfUEVFUikgJiYgCgkgICAgKHNlbGYtPmNsaWVudC5zdGF0ZSA9PSBJUkxBTl9JRExFKSAmJgoJICAgIChzZWxmLT5wcm92aWRlci5zdGF0ZSAhPSBJUkxBTl9JRExFKSkgewoJCWlybGFuX2NsaWVudF93YWtldXAoc2VsZiwgc2VsZi0+c2FkZHIsIHNlbGYtPmRhZGRyKTsKCX0KfQoKc3RhdGljIHZvaWQgaXJsYW5fY2xpZW50X3N0YXJ0X2tpY2tfdGltZXIoc3RydWN0IGlybGFuX2NiICpzZWxmLCBpbnQgdGltZW91dCkKewoJSVJEQV9ERUJVRyg0LCAiJXMoKVxuIiwgX19GVU5DVElPTl9fICk7CgkKCWlyZGFfc3RhcnRfdGltZXIoJnNlbGYtPmNsaWVudC5raWNrX3RpbWVyLCB0aW1lb3V0LCAodm9pZCAqKSBzZWxmLCAKCQkJIGlybGFuX2NsaWVudF9raWNrX3RpbWVyX2V4cGlyZWQpOwp9CgovKgogKiBGdW5jdGlvbiBpcmxhbl9jbGllbnRfd2FrZXVwIChzZWxmLCBzYWRkciwgZGFkZHIpCiAqCiAqICAgIFdha2UgdXAgY2xpZW50CiAqCiAqLwp2b2lkIGlybGFuX2NsaWVudF93YWtldXAoc3RydWN0IGlybGFuX2NiICpzZWxmLCBfX3UzMiBzYWRkciwgX191MzIgZGFkZHIpCnsKCUlSREFfREVCVUcoMSwgIiVzKClcbiIsIF9fRlVOQ1RJT05fXyApOwoKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBJUkxBTl9NQUdJQywgcmV0dXJuOyk7CgoJLyogCgkgKiBDaGVjayBpZiB3ZSBhcmUgYWxyZWFkeSBhd2FrZSwgb3IgaWYgd2UgYXJlIGEgcHJvdmlkZXIgaW4gZGlyZWN0CgkgKiBtb2RlIChpbiB0aGF0IGNhc2Ugd2UgbXVzdCBsZWF2ZSB0aGUgY2xpZW50IGlkbGUKCSAqLwoJaWYgKChzZWxmLT5jbGllbnQuc3RhdGUgIT0gSVJMQU5fSURMRSkgfHwgCgkgICAgKHNlbGYtPnByb3ZpZGVyLmFjY2Vzc190eXBlID09IEFDQ0VTU19ESVJFQ1QpKQoJewoJCQlJUkRBX0RFQlVHKDAsICIlcygpLCBhbHJlYWR5IGF3YWtlIVxuIiwgX19GVU5DVElPTl9fICk7CgkJCXJldHVybjsKCX0KCgkvKiBBZGRyZXNzZXMgbWF5IGhhdmUgY2hhbmdlZCEgKi8KCXNlbGYtPnNhZGRyID0gc2FkZHI7CglzZWxmLT5kYWRkciA9IGRhZGRyOwoKCWlmIChzZWxmLT5kaXNjb25uZWN0X3JlYXNvbiA9PSBMTV9VU0VSX1JFUVVFU1QpIHsKCQkJSVJEQV9ERUJVRygwLCAiJXMoKSwgc3RpbGwgc3RvcHBlZCBieSB1c2VyXG4iLCBfX0ZVTkNUSU9OX18gKTsKCQkJcmV0dXJuOwoJfQoKCS8qIE9wZW4gVFNBUHMgKi8KCWlybGFuX2NsaWVudF9vcGVuX2N0cmxfdHNhcChzZWxmKTsKCWlybGFuX29wZW5fZGF0YV90c2FwKHNlbGYpOwoKCWlybGFuX2RvX2NsaWVudF9ldmVudChzZWxmLCBJUkxBTl9ESVNDT1ZFUllfSU5ESUNBVElPTiwgTlVMTCk7CgkKCS8qIFN0YXJ0IGtpY2sgdGltZXIgKi8KCWlybGFuX2NsaWVudF9zdGFydF9raWNrX3RpbWVyKHNlbGYsIDIqSFopOwp9CgovKgogKiBGdW5jdGlvbiBpcmxhbl9kaXNjb3ZlcnlfaW5kaWNhdGlvbiAoZGFkZHIpCiAqCiAqICAgIFJlbW90ZSBkZXZpY2Ugd2l0aCBJckxBTiBzZXJ2ZXIgc3VwcG9ydCBkaXNjb3ZlcmVkCiAqCiAqLwp2b2lkIGlybGFuX2NsaWVudF9kaXNjb3ZlcnlfaW5kaWNhdGlvbihkaXNjaW5mb190ICpkaXNjb3ZlcnksCgkJCQkgICAgICAgRElTQ09WRVJZX01PREUgbW9kZSwKCQkJCSAgICAgICB2b2lkICpwcml2KSAKewoJc3RydWN0IGlybGFuX2NiICpzZWxmOwoJX191MzIgc2FkZHIsIGRhZGRyOwoJCglJUkRBX0RFQlVHKDEsICIlcygpXG4iLCBfX0ZVTkNUSU9OX18gKTsKCglJUkRBX0FTU0VSVChkaXNjb3ZlcnkgIT0gTlVMTCwgcmV0dXJuOyk7CgoJLyoKCSAqIEkgZGlkbid0IGNoZWNrIGl0LCBidXQgSSBiZXQgdGhhdCBJckxBTiBzdWZmZXIgZnJvbSB0aGUgc2FtZQoJICogZGVmaWNpZW5jeSBhcyBJckNvbW0gYW5kIGRvZXNuJ3QgaGFuZGxlIHR3byBpbnN0YW5jZXMKCSAqIHNpbXVsdGFuZW91c2x5IGNvbm5lY3RpbmcgdG8gZWFjaCBvdGhlci4KCSAqIFNhbWUgd29ya2Fyb3VuZCwgZHJvcCBwYXNzaXZlIGRpc2NvdmVyaWVzLgoJICogSmVhbiBJSSAqLwoJaWYobW9kZSA9PSBESVNDT1ZFUllfUEFTU0lWRSkKCQlyZXR1cm47CgoJc2FkZHIgPSBkaXNjb3ZlcnktPnNhZGRyOwoJZGFkZHIgPSBkaXNjb3ZlcnktPmRhZGRyOwoKCS8qIEZpbmQgaW5zdGFuY2UgKi8KCXJjdV9yZWFkX2xvY2soKTsKCXNlbGYgPSBpcmxhbl9nZXRfYW55KCk7CglpZiAoc2VsZikgewoJCUlSREFfQVNTRVJUKHNlbGYtPm1hZ2ljID09IElSTEFOX01BR0lDLCByZXR1cm47KTsKCgkJSVJEQV9ERUJVRygxLCAiJXMoKSwgRm91bmQgaW5zdGFuY2UgKCUwOHgpIVxuIiwgX19GVU5DVElPTl9fICwKCQkgICAgICBkYWRkcik7CgkJCgkJaXJsYW5fY2xpZW50X3dha2V1cChzZWxmLCBzYWRkciwgZGFkZHIpOwoJfQoJcmN1X3JlYWRfdW5sb2NrKCk7Cn0KCQovKgogKiBGdW5jdGlvbiBpcmxhbl9jbGllbnRfZGF0YV9pbmRpY2F0aW9uIChoYW5kbGUsIHNrYikKICoKICogICAgVGhpcyBmdW5jdGlvbiBnZXRzIHRoZSBkYXRhIHRoYXQgaXMgcmVjZWl2ZWQgb24gdGhlIGNvbnRyb2wgY2hhbm5lbAogKgogKi8Kc3RhdGljIGludCBpcmxhbl9jbGllbnRfY3RybF9kYXRhX2luZGljYXRpb24odm9pZCAqaW5zdGFuY2UsIHZvaWQgKnNhcCwgCgkJCQkJICAgICBzdHJ1Y3Qgc2tfYnVmZiAqc2tiKQp7CglzdHJ1Y3QgaXJsYW5fY2IgKnNlbGY7CgkKCUlSREFfREVCVUcoMiwgIiVzKClcbiIsIF9fRlVOQ1RJT05fXyApOwoJCglzZWxmID0gKHN0cnVjdCBpcmxhbl9jYiAqKSBpbnN0YW5jZTsKCQoJSVJEQV9BU1NFUlQoc2VsZiAhPSBOVUxMLCByZXR1cm4gLTE7KTsKCUlSREFfQVNTRVJUKHNlbGYtPm1hZ2ljID09IElSTEFOX01BR0lDLCByZXR1cm4gLTE7KTsKCUlSREFfQVNTRVJUKHNrYiAhPSBOVUxMLCByZXR1cm4gLTE7KTsKCQoJaXJsYW5fZG9fY2xpZW50X2V2ZW50KHNlbGYsIElSTEFOX0RBVEFfSU5ESUNBVElPTiwgc2tiKTsgCgoJLyogUmVhZHkgZm9yIGEgbmV3IGNvbW1hbmQgKi8JCglJUkRBX0RFQlVHKDIsICIlcygpLCBjbGVhcmluZyB0eF9idXN5XG4iLCBfX0ZVTkNUSU9OX18gKTsKCXNlbGYtPmNsaWVudC50eF9idXN5ID0gRkFMU0U7CgoJLyogQ2hlY2sgaWYgd2UgaGF2ZSBzb21lIHF1ZXVlZCBjb21tYW5kcyB3YWl0aW5nIHRvIGJlIHNlbnQgKi8KCWlybGFuX3J1bl9jdHJsX3R4X3F1ZXVlKHNlbGYpOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBpcmxhbl9jbGllbnRfY3RybF9kaXNjb25uZWN0X2luZGljYXRpb24odm9pZCAqaW5zdGFuY2UsIHZvaWQgKnNhcCwgCgkJCQkJCSAgICBMTV9SRUFTT04gcmVhc29uLCAKCQkJCQkJICAgIHN0cnVjdCBza19idWZmICp1c2VyZGF0YSkgCnsKCXN0cnVjdCBpcmxhbl9jYiAqc2VsZjsKCXN0cnVjdCB0c2FwX2NiICp0c2FwOwoJc3RydWN0IHNrX2J1ZmYgKnNrYjsKCglJUkRBX0RFQlVHKDQsICIlcygpLCByZWFzb249JWRcbiIsIF9fRlVOQ1RJT05fXyAsIHJlYXNvbik7CgkKCXNlbGYgPSAoc3RydWN0IGlybGFuX2NiICopIGluc3RhbmNlOwoJdHNhcCA9IChzdHJ1Y3QgdHNhcF9jYiAqKSBzYXA7CgoJSVJEQV9BU1NFUlQoc2VsZiAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHNlbGYtPm1hZ2ljID09IElSTEFOX01BR0lDLCByZXR1cm47KTsJCglJUkRBX0FTU0VSVCh0c2FwICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQodHNhcC0+bWFnaWMgPT0gVFRQX1RTQVBfTUFHSUMsIHJldHVybjspOwoJCglJUkRBX0FTU0VSVCh0c2FwID09IHNlbGYtPmNsaWVudC50c2FwX2N0cmwsIHJldHVybjspOwoKICAgICAgIAkvKiBSZW1vdmUgZnJhbWVzIHF1ZXVlZCBvbiB0aGUgY29udHJvbCBjaGFubmVsICovCgl3aGlsZSAoKHNrYiA9IHNrYl9kZXF1ZXVlKCZzZWxmLT5jbGllbnQudHhxKSkgIT0gTlVMTCkgewoJCWRldl9rZnJlZV9za2Ioc2tiKTsKCX0KCXNlbGYtPmNsaWVudC50eF9idXN5ID0gRkFMU0U7CgoJaXJsYW5fZG9fY2xpZW50X2V2ZW50KHNlbGYsIElSTEFOX0xNUF9ESVNDT05ORUNULCBOVUxMKTsKfQoKLyoKICogRnVuY3Rpb24gaXJsYW5fY2xpZW50X29wZW5fdHNhcHMgKHNlbGYpCiAqCiAqICAgIEluaXRpYWxpemUgY2FsbGJhY2tzIGFuZCBvcGVuIElyVFRQIFRTQVBzCiAqCiAqLwpzdGF0aWMgdm9pZCBpcmxhbl9jbGllbnRfb3Blbl9jdHJsX3RzYXAoc3RydWN0IGlybGFuX2NiICpzZWxmKQp7CglzdHJ1Y3QgdHNhcF9jYiAqdHNhcDsKCW5vdGlmeV90IG5vdGlmeTsKCglJUkRBX0RFQlVHKDQsICIlcygpXG4iLCBfX0ZVTkNUSU9OX18gKTsKCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gSVJMQU5fTUFHSUMsIHJldHVybjspOwoKCS8qIENoZWNrIGlmIGFscmVhZHkgb3BlbiAqLwoJaWYgKHNlbGYtPmNsaWVudC50c2FwX2N0cmwpCgkJcmV0dXJuOwoKCWlyZGFfbm90aWZ5X2luaXQoJm5vdGlmeSk7CgoJLyogU2V0IHVwIGNhbGxiYWNrcyAqLwoJbm90aWZ5LmRhdGFfaW5kaWNhdGlvbiAgICAgICA9IGlybGFuX2NsaWVudF9jdHJsX2RhdGFfaW5kaWNhdGlvbjsKCW5vdGlmeS5jb25uZWN0X2NvbmZpcm0gICAgICAgPSBpcmxhbl9jbGllbnRfY3RybF9jb25uZWN0X2NvbmZpcm07Cglub3RpZnkuZGlzY29ubmVjdF9pbmRpY2F0aW9uID0gaXJsYW5fY2xpZW50X2N0cmxfZGlzY29ubmVjdF9pbmRpY2F0aW9uOwoJbm90aWZ5Lmluc3RhbmNlID0gc2VsZjsKCXN0cmxjcHkobm90aWZ5Lm5hbWUsICJJckxBTiBjdHJsIChjKSIsIHNpemVvZihub3RpZnkubmFtZSkpOwoJCgl0c2FwID0gaXJ0dHBfb3Blbl90c2FwKExTQVBfQU5ZLCBERUZBVUxUX0lOSVRJQUxfQ1JFRElULCAmbm90aWZ5KTsKCWlmICghdHNhcCkgewoJCUlSREFfREVCVUcoMiwgIiVzKCksIEdvdCBubyB0c2FwIVxuIiwgX19GVU5DVElPTl9fICk7CgkJcmV0dXJuOwoJfQoJc2VsZi0+Y2xpZW50LnRzYXBfY3RybCA9IHRzYXA7Cn0KCi8qCiAqIEZ1bmN0aW9uIGlybGFuX2NsaWVudF9jb25uZWN0X2NvbmZpcm0gKGhhbmRsZSwgc2tiKQogKgogKiAgICBDb25uZWN0aW9uIHRvIHBlZXIgSXJMQU4gbGF5ZSBjb25maXJtZWQKICoKICovCnN0YXRpYyB2b2lkIGlybGFuX2NsaWVudF9jdHJsX2Nvbm5lY3RfY29uZmlybSh2b2lkICppbnN0YW5jZSwgdm9pZCAqc2FwLCAKCQkJCQkgICAgICBzdHJ1Y3QgcW9zX2luZm8gKnFvcywgCgkJCQkJICAgICAgX191MzIgbWF4X3NkdV9zaXplLAoJCQkJCSAgICAgIF9fdTggbWF4X2hlYWRlcl9zaXplLAoJCQkJCSAgICAgIHN0cnVjdCBza19idWZmICpza2IpIAp7CglzdHJ1Y3QgaXJsYW5fY2IgKnNlbGY7CgoJSVJEQV9ERUJVRyg0LCAiJXMoKVxuIiwgX19GVU5DVElPTl9fICk7CgoJc2VsZiA9IChzdHJ1Y3QgaXJsYW5fY2IgKikgaW5zdGFuY2U7CgoJSVJEQV9BU1NFUlQoc2VsZiAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHNlbGYtPm1hZ2ljID09IElSTEFOX01BR0lDLCByZXR1cm47KTsKCglzZWxmLT5jbGllbnQubWF4X3NkdV9zaXplID0gbWF4X3NkdV9zaXplOwoJc2VsZi0+Y2xpZW50Lm1heF9oZWFkZXJfc2l6ZSA9IG1heF9oZWFkZXJfc2l6ZTsKCgkvKiBUT0RPOiB3ZSBjb3VsZCBzZXQgdGhlIE1UVSBkZXBlbmRpbmcgb24gdGhlIG1heF9zZHVfc2l6ZSAqLwoKCWlybGFuX2RvX2NsaWVudF9ldmVudChzZWxmLCBJUkxBTl9DT05ORUNUX0NPTVBMRVRFLCBOVUxMKTsKfQoKLyoKICogRnVuY3Rpb24gcHJpbnRfcmV0X2NvZGUgKGNvZGUpCiAqCiAqICAgIFByaW50IHJldHVybiBjb2RlIG9mIHJlcXVlc3QgdG8gcGVlciBJckxBTiBsYXllci4KICoKICovCnN0YXRpYyB2b2lkIHByaW50X3JldF9jb2RlKF9fdTggY29kZSkgCnsKCXN3aXRjaChjb2RlKSB7CgljYXNlIDA6CgkJcHJpbnRrKEtFUk5fSU5GTyAiU3VjY2Vzc1xuIik7CgkJYnJlYWs7CgljYXNlIDE6CgkJSVJEQV9XQVJOSU5HKCJJckxBTjogSW5zdWZmaWNpZW50IHJlc291cmNlc1xuIik7CgkJYnJlYWs7CgljYXNlIDI6CgkJSVJEQV9XQVJOSU5HKCJJckxBTjogSW52YWxpZCBjb21tYW5kIGZvcm1hdFxuIik7CgkJYnJlYWs7CgljYXNlIDM6CgkJSVJEQV9XQVJOSU5HKCJJckxBTjogQ29tbWFuZCBub3Qgc3VwcG9ydGVkXG4iKTsKCQlicmVhazsKCWNhc2UgNDoKCQlJUkRBX1dBUk5JTkcoIklyTEFOOiBQYXJhbWV0ZXIgbm90IHN1cHBvcnRlZFxuIik7CgkJYnJlYWs7CgljYXNlIDU6CgkJSVJEQV9XQVJOSU5HKCJJckxBTjogVmFsdWUgbm90IHN1cHBvcnRlZFxuIik7CgkJYnJlYWs7CgljYXNlIDY6CgkJSVJEQV9XQVJOSU5HKCJJckxBTjogTm90IG9wZW5cbiIpOwoJCWJyZWFrOwoJY2FzZSA3OgoJCUlSREFfV0FSTklORygiSXJMQU46IEF1dGhlbnRpY2F0aW9uIHJlcXVpcmVkXG4iKTsKCQlicmVhazsKCWNhc2UgODoKCQlJUkRBX1dBUk5JTkcoIklyTEFOOiBJbnZhbGlkIHBhc3N3b3JkXG4iKTsKCQlicmVhazsKCWNhc2UgOToKCQlJUkRBX1dBUk5JTkcoIklyTEFOOiBQcm90b2NvbCBlcnJvclxuIik7CgkJYnJlYWs7CgljYXNlIDI1NToKCQlJUkRBX1dBUk5JTkcoIklyTEFOOiBBc3luY2hyb25vdXMgc3RhdHVzXG4iKTsKCQlicmVhazsKCX0KfQoKLyoKICogRnVuY3Rpb24gaXJsYW5fY2xpZW50X3BhcnNlX3Jlc3BvbnNlIChzZWxmLCBza2IpCiAqCiAqICAgIEV4dHJhY3QgYWxsIHBhcmFtZXRlcnMgZnJvbSByZWNlaXZlZCBidWZmZXIsIHRoZW4gZmVlZCB0aGVtIHRvIAogKiAgICBjaGVja19wYXJhbXMgZm9yIHBhcnNpbmcKICovCnZvaWQgaXJsYW5fY2xpZW50X3BhcnNlX3Jlc3BvbnNlKHN0cnVjdCBpcmxhbl9jYiAqc2VsZiwgc3RydWN0IHNrX2J1ZmYgKnNrYikKewoJX191OCAqZnJhbWU7CglfX3U4ICpwdHI7CglpbnQgY291bnQ7CglpbnQgcmV0OwoJX191MTYgdmFsX2xlbjsKCWludCBpOwogICAgICAgIGNoYXIgKm5hbWU7CiAgICAgICAgY2hhciAqdmFsdWU7CgoJSVJEQV9BU1NFUlQoc2tiICE9IE5VTEwsIHJldHVybjspOwkKCQoJSVJEQV9ERUJVRyg0LCAiJXMoKSBza2ItPmxlbj0lZFxuIiwgX19GVU5DVElPTl9fICwgKGludCkgc2tiLT5sZW4pOwoJCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gSVJMQU5fTUFHSUMsIHJldHVybjspOwoJCglpZiAoIXNrYikgewoJCUlSREFfRVJST1IoIiVzKCksIEdvdCBOVUxMIHNrYiFcbiIsIF9fRlVOQ1RJT05fXyk7CgkJcmV0dXJuOwoJfQoJZnJhbWUgPSBza2ItPmRhdGE7CgkKCS8qIAoJICogIENoZWNrIHJldHVybiBjb2RlIGFuZCBwcmludCBpdCBpZiBub3Qgc3VjY2VzcyAKCSAqLwoJaWYgKGZyYW1lWzBdKSB7CgkJcHJpbnRfcmV0X2NvZGUoZnJhbWVbMF0pOwoJCXJldHVybjsKCX0KCQoJbmFtZSA9IGttYWxsb2MoMjU1LCBHRlBfQVRPTUlDKTsKCWlmICghbmFtZSkKCQlyZXR1cm47Cgl2YWx1ZSA9IGttYWxsb2MoMTAxNiwgR0ZQX0FUT01JQyk7CglpZiAoIXZhbHVlKSB7CgkJa2ZyZWUobmFtZSk7CgkJcmV0dXJuOwoJfQoKCS8qIEhvdyBtYW55IHBhcmFtZXRlcnM/ICovCgljb3VudCA9IGZyYW1lWzFdOwoKCUlSREFfREVCVUcoNCwgIiVzKCksIGdvdCAlZCBwYXJhbWV0ZXJzXG4iLCBfX0ZVTkNUSU9OX18gLCBjb3VudCk7CgkKCXB0ciA9IGZyYW1lKzI7CgoJLyogRm9yIGFsbCBwYXJhbWV0ZXJzICovCiAJZm9yIChpPTA7IGk8Y291bnQ7aSsrKSB7CgkJcmV0ID0gaXJsYW5fZXh0cmFjdF9wYXJhbShwdHIsIG5hbWUsIHZhbHVlLCAmdmFsX2xlbik7CgkJaWYgKHJldCA8IDApIHsKCQkJSVJEQV9ERUJVRygyLCAiJXMoKSwgSXJMQU4sIEVycm9yIVxuIiwgX19GVU5DVElPTl9fICk7CgkJCWJyZWFrOwoJCX0KCQlwdHIgKz0gcmV0OwoJCWlybGFuX2NoZWNrX3Jlc3BvbnNlX3BhcmFtKHNlbGYsIG5hbWUsIHZhbHVlLCB2YWxfbGVuKTsKIAl9CgkvKiBDbGVhbnVwICovCglrZnJlZShuYW1lKTsKCWtmcmVlKHZhbHVlKTsKfQoKLyoKICogRnVuY3Rpb24gaXJsYW5fY2hlY2tfcmVzcG9uc2VfcGFyYW0gKHNlbGYsIHBhcmFtLCB2YWx1ZSwgdmFsX2xlbikKICoKICogICAgIENoZWNrIHdoaWNoIHBhcmFtZXRlciBpcyByZWNlaXZlZCBhbmQgdXBkYXRlIGxvY2FsIHZhcmlhYmxlcwogKgogKi8Kc3RhdGljIHZvaWQgaXJsYW5fY2hlY2tfcmVzcG9uc2VfcGFyYW0oc3RydWN0IGlybGFuX2NiICpzZWxmLCBjaGFyICpwYXJhbSwgCgkJCQkgICAgICAgY2hhciAqdmFsdWUsIGludCB2YWxfbGVuKSAKewoJX191MTYgdG1wX2NwdTsgLyogVGVtcG9yYXJ5IHZhbHVlIGluIGhvc3Qgb3JkZXIgKi8KCV9fdTggKmJ5dGVzOwoJaW50IGk7CgoJSVJEQV9ERUJVRyg0LCAiJXMoKSwgcGFybT0lc1xuIiwgX19GVU5DVElPTl9fICwgcGFyYW0pOwoKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBJUkxBTl9NQUdJQywgcmV0dXJuOyk7CgoJLyogTWVkaWEgdHlwZSAqLwoJaWYgKHN0cmNtcChwYXJhbSwgIk1FRElBIikgPT0gMCkgewoJCWlmIChzdHJjbXAodmFsdWUsICI4MDIuMyIpID09IDApCgkJCXNlbGYtPm1lZGlhID0gTUVESUFfODAyXzM7CgkJZWxzZQoJCQlzZWxmLT5tZWRpYSA9IE1FRElBXzgwMl81OwoJCXJldHVybjsKCX0KCWlmIChzdHJjbXAocGFyYW0sICJGSUxURVJfVFlQRSIpID09IDApIHsKCQlpZiAoc3RyY21wKHZhbHVlLCAiRElSRUNURUQiKSA9PSAwKQoJCQlzZWxmLT5jbGllbnQuZmlsdGVyX3R5cGUgfD0gSVJMQU5fRElSRUNURUQ7CgkJZWxzZSBpZiAoc3RyY21wKHZhbHVlLCAiRlVOQ1RJT05BTCIpID09IDApCgkJCXNlbGYtPmNsaWVudC5maWx0ZXJfdHlwZSB8PSBJUkxBTl9GVU5DVElPTkFMOwoJCWVsc2UgaWYgKHN0cmNtcCh2YWx1ZSwgIkdST1VQIikgPT0gMCkKCQkJc2VsZi0+Y2xpZW50LmZpbHRlcl90eXBlIHw9IElSTEFOX0dST1VQOwoJCWVsc2UgaWYgKHN0cmNtcCh2YWx1ZSwgIk1BQ19GUkFNRSIpID09IDApCgkJCXNlbGYtPmNsaWVudC5maWx0ZXJfdHlwZSB8PSBJUkxBTl9NQUNfRlJBTUU7CgkJZWxzZSBpZiAoc3RyY21wKHZhbHVlLCAiTVVMVElDQVNUIikgPT0gMCkKCQkJc2VsZi0+Y2xpZW50LmZpbHRlcl90eXBlIHw9IElSTEFOX01VTFRJQ0FTVDsKCQllbHNlIGlmIChzdHJjbXAodmFsdWUsICJCUk9BRENBU1QiKSA9PSAwKQoJCQlzZWxmLT5jbGllbnQuZmlsdGVyX3R5cGUgfD0gSVJMQU5fQlJPQURDQVNUOwoJCWVsc2UgaWYgKHN0cmNtcCh2YWx1ZSwgIklQWF9TT0NLRVQiKSA9PSAwKQoJCQlzZWxmLT5jbGllbnQuZmlsdGVyX3R5cGUgfD0gSVJMQU5fSVBYX1NPQ0tFVDsKCQkKCX0KCWlmIChzdHJjbXAocGFyYW0sICJBQ0NFU1NfVFlQRSIpID09IDApIHsKCQlpZiAoc3RyY21wKHZhbHVlLCAiRElSRUNUIikgPT0gMCkKCQkJc2VsZi0+Y2xpZW50LmFjY2Vzc190eXBlID0gQUNDRVNTX0RJUkVDVDsKCQllbHNlIGlmIChzdHJjbXAodmFsdWUsICJQRUVSIikgPT0gMCkKCQkJc2VsZi0+Y2xpZW50LmFjY2Vzc190eXBlID0gQUNDRVNTX1BFRVI7CgkJZWxzZSBpZiAoc3RyY21wKHZhbHVlLCAiSE9TVEVEIikgPT0gMCkKCQkJc2VsZi0+Y2xpZW50LmFjY2Vzc190eXBlID0gQUNDRVNTX0hPU1RFRDsKCQllbHNlIHsKCQkJSVJEQV9ERUJVRygyLCAiJXMoKSwgdW5rbm93biBhY2Nlc3MgdHlwZSFcbiIsIF9fRlVOQ1RJT05fXyApOwoJCX0KCX0KCS8qIElSTEFOIHZlcnNpb24gKi8KCWlmIChzdHJjbXAocGFyYW0sICJJUkxBTl9WRVIiKSA9PSAwKSB7CgkJSVJEQV9ERUJVRyg0LCAiSXJMQU4gdmVyc2lvbiAlZC4lZFxuIiwgKF9fdTgpIHZhbHVlWzBdLCAKCQkgICAgICAoX191OCkgdmFsdWVbMV0pOwoKCQlzZWxmLT52ZXJzaW9uWzBdID0gdmFsdWVbMF07CgkJc2VsZi0+dmVyc2lvblsxXSA9IHZhbHVlWzFdOwoJCXJldHVybjsKCX0KCS8qIFdoaWNoIHJlbW90ZSBUU0FQIHRvIHVzZSBmb3IgZGF0YSBjaGFubmVsICovCglpZiAoc3RyY21wKHBhcmFtLCAiREFUQV9DSEFOIikgPT0gMCkgewoJCXNlbGYtPmR0c2FwX3NlbF9kYXRhID0gdmFsdWVbMF07CgkJSVJEQV9ERUJVRyg0LCAiRGF0YSBUU0FQID0gJTAyeFxuIiwgc2VsZi0+ZHRzYXBfc2VsX2RhdGEpOwoJCXJldHVybjsKCX0KCWlmIChzdHJjbXAocGFyYW0sICJDT05fQVJCIikgPT0gMCkgewoJCW1lbWNweSgmdG1wX2NwdSwgdmFsdWUsIDIpOyAvKiBBbGlnbiB2YWx1ZSAqLwoJCWxlMTZfdG9fY3B1cygmdG1wX2NwdSk7ICAgICAvKiBDb252ZXJ0IHRvIGhvc3Qgb3JkZXIgKi8KCQlzZWxmLT5jbGllbnQucmVjdl9hcmJfdmFsID0gdG1wX2NwdTsKCQlJUkRBX0RFQlVHKDIsICIlcygpLCByZWNlaXZlIGFyYiB2YWw9JWRcbiIsIF9fRlVOQ1RJT05fXyAsIAoJCQkgICBzZWxmLT5jbGllbnQucmVjdl9hcmJfdmFsKTsKCX0KCWlmIChzdHJjbXAocGFyYW0sICJNQVhfRlJBTUUiKSA9PSAwKSB7CgkJbWVtY3B5KCZ0bXBfY3B1LCB2YWx1ZSwgMik7IC8qIEFsaWduIHZhbHVlICovCgkJbGUxNl90b19jcHVzKCZ0bXBfY3B1KTsgICAgIC8qIENvbnZlcnQgdG8gaG9zdCBvcmRlciAqLwoJCXNlbGYtPmNsaWVudC5tYXhfZnJhbWUgPSB0bXBfY3B1OwoJCUlSREFfREVCVUcoNCwgIiVzKCksIG1heCBmcmFtZT0lZFxuIiwgX19GVU5DVElPTl9fICwgCgkJCSAgIHNlbGYtPmNsaWVudC5tYXhfZnJhbWUpOwoJfQoJIAoJLyogUkVDT05ORUNUX0tFWSwgaW4gY2FzZSB0aGUgbGluayBnb2VzIGRvd24hICovCglpZiAoc3RyY21wKHBhcmFtLCAiUkVDT05ORUNUX0tFWSIpID09IDApIHsKCQlJUkRBX0RFQlVHKDQsICJHb3QgcmVjb25uZWN0IGtleTogIik7CgkJLyogZm9yIChpID0gMDsgaSA8IHZhbF9sZW47IGkrKykgKi8KLyogCQkJcHJpbnRrKCIlMDJ4IiwgdmFsdWVbaV0pOyAqLwoJCW1lbWNweShzZWxmLT5jbGllbnQucmVjb25uZWN0X2tleSwgdmFsdWUsIHZhbF9sZW4pOwoJCXNlbGYtPmNsaWVudC5rZXlfbGVuID0gdmFsX2xlbjsKCQlJUkRBX0RFQlVHKDQsICJcbiIpOwoJfQoJLyogRklMVEVSX0VOVFJZLCBoYXZlIHdlIGdvdCBhbiBldGhlcm5ldCBhZGRyZXNzPyAqLwoJaWYgKHN0cmNtcChwYXJhbSwgIkZJTFRFUl9FTlRSWSIpID09IDApIHsKCQlieXRlcyA9IHZhbHVlOwoJCUlSREFfREVCVUcoNCwgIkV0aGVybmV0IGFkZHJlc3MgPSAlMDJ4OiUwMng6JTAyeDolMDJ4OiUwMng6JTAyeFxuIiwKCQkgICAgICBieXRlc1swXSwgYnl0ZXNbMV0sIGJ5dGVzWzJdLCBieXRlc1szXSwgYnl0ZXNbNF0sIAoJCSAgICAgIGJ5dGVzWzVdKTsKCQlmb3IgKGkgPSAwOyBpIDwgNjsgaSsrKSAKCQkJc2VsZi0+ZGV2LT5kZXZfYWRkcltpXSA9IGJ5dGVzW2ldOwoJfQp9CgovKgogKiBGdW5jdGlvbiBpcmxhbl9jbGllbnRfZ2V0X3ZhbHVlX2NvbmZpcm0gKG9ial9pZCwgdmFsdWUpCiAqCiAqICAgIEdvdCByZXN1bHRzIGZyb20gcmVtb3RlIExNLUlBUwogKgogKi8Kdm9pZCBpcmxhbl9jbGllbnRfZ2V0X3ZhbHVlX2NvbmZpcm0oaW50IHJlc3VsdCwgX191MTYgb2JqX2lkLCAKCQkJCSAgICBzdHJ1Y3QgaWFzX3ZhbHVlICp2YWx1ZSwgdm9pZCAqcHJpdikgCnsKCXN0cnVjdCBpcmxhbl9jYiAqc2VsZjsKCQoJSVJEQV9ERUJVRyg0LCAiJXMoKVxuIiwgX19GVU5DVElPTl9fICk7CgoJSVJEQV9BU1NFUlQocHJpdiAhPSBOVUxMLCByZXR1cm47KTsKCglzZWxmID0gKHN0cnVjdCBpcmxhbl9jYiAqKSBwcml2OwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gSVJMQU5fTUFHSUMsIHJldHVybjspOwoKCS8qIFdlIHByb2JhYmx5IGRvbid0IG5lZWQgdG8gbWFrZSBhbnkgbW9yZSBxdWVyaWVzICovCglpcmlhcF9jbG9zZShzZWxmLT5jbGllbnQuaXJpYXApOwoJc2VsZi0+Y2xpZW50LmlyaWFwID0gTlVMTDsKCgkvKiBDaGVjayBpZiByZXF1ZXN0IHN1Y2NlZWRlZCAqLwoJaWYgKHJlc3VsdCAhPSBJQVNfU1VDQ0VTUykgewoJCUlSREFfREVCVUcoMiwgIiVzKCksIGdvdCBOVUxMIHZhbHVlIVxuIiwgX19GVU5DVElPTl9fICk7CgkJaXJsYW5fZG9fY2xpZW50X2V2ZW50KHNlbGYsIElSTEFOX0lBU19QUk9WSURFUl9OT1RfQVZBSUwsIAoJCQkJICAgICAgTlVMTCk7CgkJcmV0dXJuOwoJfQoKCXN3aXRjaCAodmFsdWUtPnR5cGUpIHsKCWNhc2UgSUFTX0lOVEVHRVI6CgkJc2VsZi0+ZHRzYXBfc2VsX2N0cmwgPSB2YWx1ZS0+dC5pbnRlZ2VyOwoKCQlpZiAodmFsdWUtPnQuaW50ZWdlciAhPSAtMSkgewoJCQlpcmxhbl9kb19jbGllbnRfZXZlbnQoc2VsZiwgSVJMQU5fSUFTX1BST1ZJREVSX0FWQUlMLAoJCQkJCSAgICAgIE5VTEwpOwoJCQlyZXR1cm47CgkJfQoJCWlyaWFzX2RlbGV0ZV92YWx1ZSh2YWx1ZSk7CgkJYnJlYWs7CglkZWZhdWx0OgoJCUlSREFfREVCVUcoMiwgIiVzKCksIHVua25vd24gdHlwZSFcbiIsIF9fRlVOQ1RJT05fXyApOwoJCWJyZWFrOwoJfQoJaXJsYW5fZG9fY2xpZW50X2V2ZW50KHNlbGYsIElSTEFOX0lBU19QUk9WSURFUl9OT1RfQVZBSUwsIE5VTEwpOwp9Cg==