LyoKICogKEMpIENvcHlyaWdodCAyMDAyCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCLCBkYW5pZWxAb21pY3Jvbi5zZQogKiAKICogU2VlIGZpbGUgQ1JFRElUUyBmb3IgbGlzdCBvZiBwZW9wbGUgd2hvIGNvbnRyaWJ1dGVkIHRvIHRoaXMKICogcHJvamVjdC4KICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZgogKiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwKICogTUEgMDIxMTEtMTMwNyBVU0EKICovCgovKiAKICogTGludXggaTM4NiB6SW1hZ2UgYW5kIGJ6SW1hZ2UgbG9hZGluZwogKiAKICogYmFzZWQgb24gdGhlIHByb2NkdXJlIGRlc2NyaWJlZCBpbiAKICogbGludXgvRG9jdW1lbnRhdGlvbi9pMzg2L2Jvb3QudHh0CiAqLwoKI2luY2x1ZGUgPGNvbW1vbi5oPgojaW5jbHVkZSA8YXNtL2lvLmg+CiNpbmNsdWRlIDxhc20vcHRyYWNlLmg+CiNpbmNsdWRlIDxhc20vemltYWdlLmg+CiNpbmNsdWRlIDxhc20vcmVhbG1vZGUuaD4KI2luY2x1ZGUgPGFzbS9ieXRlb3JkZXIuaD4KCi8qCiAqIE1lbW9yeSBsYXktb3V0OgogKiAKICogcmVsYXRpdmUgdG8gc2V0dXBfYmFzZSAod2hpY2ggaXMgMHg5MDAwMCBjdXJyZW50bHkpCiAqIAogKgkweDAwMDAtMHg3RkZGCVJlYWwgbW9kZSBrZXJuZWwgICAKICoJMHg4MDAwLTB4OEZGRglTdGFjayBhbmQgaGVhcAogKgkweDkwMDAtMHg5MEZGCUtlcm5lbCBjb21tYW5kIGxpbmUKICovCiNkZWZpbmUgREVGQVVMVF9TRVRVUF9CQVNFICAweDkwMDAwCiNkZWZpbmUgQ09NTUFORF9MSU5FX09GRlNFVCAweDkwMDAKI2RlZmluZSBIRUFQX0VORF9PRkZTRVQgICAgIDB4OGUwMAoKI2RlZmluZSBDT01NQU5EX0xJTkVfU0laRSAgIDIwNDgKCnN0YXRpYyB2b2lkIGJ1aWxkX2NvbW1hbmRfbGluZShjaGFyICpjb21tYW5kX2xpbmUsIGludCBhdXRvX2Jvb3QpCnsKCWNoYXIgKmVudl9jb21tYW5kX2xpbmU7CgkKCWNvbW1hbmRfbGluZVswXSA9ICdcMCc7CgkKCWVudl9jb21tYW5kX2xpbmUgPSAgZ2V0ZW52KCJib290YXJncyIpOwoJCgkvKiBzZXQgY29uc29sZT0gYXJndW1lbnQgaWYgd2UgdXNlIGEgc2VyaWFsIGNvbnNvbGUgKi8KCWlmIChOVUxMID09IHN0cnN0cihlbnZfY29tbWFuZF9saW5lLCAiY29uc29sZT0iKSkgewoJCWlmICgwPT1zdHJjbXAoZ2V0ZW52KCJzdGRvdXQiKSwgInNlcmlhbCIpKSB7CgkJCQoJCQkvKiBXZSBzZWVtIHRvIHVzZSBzZXJpYWwgY29uc29sZSAqLwoJCQlzcHJpbnRmKGNvbW1hbmRfbGluZSwgImNvbnNvbGU9dHR5UzAsJXMgIiwgCgkJCQkgZ2V0ZW52KCJiYXVkcmF0ZSIpKTsKCQl9Cgl9CgkKCWlmIChhdXRvX2Jvb3QpIHsKCQlzdHJjYXQoY29tbWFuZF9saW5lLCAiYXV0byAiKTsKCX0KCQkKCWlmIChOVUxMICE9IGVudl9jb21tYW5kX2xpbmUpIHsKCQlzdHJjYXQoY29tbWFuZF9saW5lLCBlbnZfY29tbWFuZF9saW5lKTsKCX0gCgkKCQoJcHJpbnRmKCJLZXJuZWwgY29tbWFuZCBsaW5lOiBcIiVzXCJcbiIsIGNvbW1hbmRfbGluZSk7Cn0KCnZvaWQgKmxvYWRfemltYWdlKGNoYXIgKmltYWdlLCB1bnNpZ25lZCBsb25nIGtlcm5lbF9zaXplLCAKCQkgIHVuc2lnbmVkIGxvbmcgaW5pdHJkX2FkZHIsIHVuc2lnbmVkIGxvbmcgaW5pdHJkX3NpemUsCgkJICBpbnQgYXV0b19ib290KQp7CiAgICAgICAgdm9pZCAqc2V0dXBfYmFzZTsKCWludCBzZXR1cF9zaXplOwoJaW50IGJvb3Rwcm90bzsKCWludCBiaWdfaW1hZ2U7Cgl2b2lkICpsb2FkX2FkZHJlc3M7CgkKCQoJc2V0dXBfYmFzZSA9ICh2b2lkKilERUZBVUxUX1NFVFVQX0JBU0U7CS8qIGJhc2UgYWRkcmVzcyBmb3IgcmVhbC1tb2RlIHNlZ21lbnQgKi8KCQogCWlmIChLRVJORUxfTUFHSUMgIT0gKih1MTYqKShpbWFnZSArIEJPT1RfRkxBR19PRkYpKSB7CgkJcHJpbnRmKCJFcnJvcjogSW52YWxpZCBrZXJuZWwgbWFnaWMgKGZvdW5kIDB4JTA0eCwgZXhwZWN0ZWQgMHhhYTU1KVxuIiwKCQkgICAgICAgKih1MTYqKShpbWFnZSArIEJPT1RfRkxBR19PRkYpKTsKCQlyZXR1cm4gMDsKCX0KCQoJCgkvKiBkZXRlcm1pbmUgYm9vdCBwcm90b2NvbCB2ZXJzaW9uICovCglpZiAoS0VSTkVMX1YyX01BR0lDID09ICoodTMyKikoaW1hZ2UrSEVBREVSX09GRikpIHsKCQlib290cHJvdG8gPSAqKHUxNiopKGltYWdlK1ZFUlNJT05fT0ZGKTsKCX0gZWxzZSB7CgkJLyogVmVyeSBvbGQga2VybmVsICovCgkJYm9vdHByb3RvID0gMHgwMTAwOwoJfQoJCgkvKiBkZXRlcm1pbmUgc2l6ZSBvZiBzZXR1cCAqLwoJaWYgKDAgPT0gKih1OCopKGltYWdlICsgU0VUVVBfU0VDVFNfT0ZGKSkgewoJCXNldHVwX3NpemUgPSA1ICogNTEyOwoJfSBlbHNlIHsKCQlzZXR1cF9zaXplID0gKCoodTgqKShpbWFnZSArIFNFVFVQX1NFQ1RTX09GRikgKyAxKSAqIDUxMjsKCX0KCQoJaWYgKHNldHVwX3NpemUgPiBTRVRVUF9NQVhfU0laRSkgewoJCXByaW50ZigiRXJyb3I6IFNldHVwIGlzIHRvbyBsYXJnZSAoJWQgYnl0ZXMpXG4iLCBzZXR1cF9zaXplKTsKCX0KCQoJLyogRGV0ZXJtaW5lIGltYWdlIHR5cGUgKi8KICAJYmlnX2ltYWdlID0gKGJvb3Rwcm90byA+PSAweDAyMDApICYmICgqKHU4KikoaW1hZ2UgKyBMT0FERkxBR1NfT0ZGKSAmIEJJR19LRVJORUxfRkxBRyk7CgkKCS8qIERlcmVybWluZSBsb2FkIGFkZHJlc3MgKi8KCWxvYWRfYWRkcmVzcyA9ICh2b2lkKikoYmlnX2ltYWdlID8gQlpJTUFHRV9MT0FEX0FERFI6WklNQUdFX0xPQURfQUREUik7CgkJCQoJLyogbG9hZCBzZXR1cCAqLwoJbWVtbW92ZShzZXR1cF9iYXNlLCBpbWFnZSwgc2V0dXBfc2l6ZSk7CgkKCXByaW50ZigiVXNpbmcgYm9vdCBwcm90b2NvbCB2ZXJzaW9uICV4LiUwMnhcbiIsIAoJICAgICAgIChib290cHJvdG8gJiAweGZmMDApID4+IDgsIGJvb3Rwcm90byAmIDB4ZmYpOwoJCgkKCWlmIChib290cHJvdG8gPT0gMHgwMTAwKSB7CQkKCQoJCSoodTE2Kikoc2V0dXBfYmFzZSArIENNRF9MSU5FX01BR0lDX09GRikgPSBDT01NQU5EX0xJTkVfTUFHSUM7CgkJKih1MTYqKShzZXR1cF9iYXNlICsgQ01EX0xJTkVfT0ZGU0VUX09GRikgPSBDT01NQU5EX0xJTkVfT0ZGU0VUOyAKCQkKCQkvKiBBIHZlcnkgb2xkIGtlcm5lbCBNVVNUIGhhdmUgaXRzIHJlYWwtbW9kZSBjb2RlCgkJICogbG9hZGVkIGF0IDB4OTAwMDAgKi8KCQkKCQlpZiAoKHUzMilzZXR1cF9iYXNlICE9IDB4OTAwMDApIHsKCQkJLyogQ29weSB0aGUgcmVhbC1tb2RlIGtlcm5lbCAqLwoJCQltZW1tb3ZlKCh2b2lkKikweDkwMDAwLCBzZXR1cF9iYXNlLCBzZXR1cF9zaXplKTsKCQkJLyogQ29weSB0aGUgY29tbWFuZCBsaW5lICovCgkJCW1lbW1vdmUoKHZvaWQqKTB4OTkwMDAsIHNldHVwX2Jhc2UrQ09NTUFORF9MSU5FX09GRlNFVCwgCgkJCSAgICAgICBDT01NQU5EX0xJTkVfU0laRSk7CgkJCQoJCQlzZXR1cF9iYXNlID0gKHZvaWQqKTB4OTAwMDA7CQkgLyogUmVsb2NhdGVkICovCgkJfQoJCQoJCS8qIEl0IGlzIHJlY29tbWVuZGVkIHRvIGNsZWFyIG1lbW9yeSB1cCB0byB0aGUgMzJLIG1hcmsgKi8KCQltZW1zZXQoKHZvaWQqKTB4OTAwMDAgKyBzZXR1cF9zaXplLCAwLCBTRVRVUF9NQVhfU0laRS1zZXR1cF9zaXplKTsKCX0KCQoJaWYgKGJvb3Rwcm90byA+PSAweDAyMDApIHsKCQkqKHU4Kikoc2V0dXBfYmFzZSArIFRZUEVfT0ZfTE9BREVSX09GRikgPSAweGZmOwoJCXByaW50ZigiTGludXgga2VybmVsIHZlcnNpb24gJXNcbiIsIAoJCSAgICAgICAoY2hhciopKHNldHVwX2Jhc2UgKyBTRVRVUF9TVEFSVF9PRkZTRVQgKyAKCQkJICAgICAgICoodTE2Kikoc2V0dXBfYmFzZSArIFNUQVJUX1NZU19PRkYgKyAyKSkpOwoJCQoJCWlmIChpbml0cmRfYWRkcikgewoJCQlwcmludGYoIkluaXRpYWwgUkFNIGRpc2sgYXQgbGluZWFyIGFkZHJlc3MgMHglMDhseCwgc2l6ZSAlbGQgYnl0ZXNcbiIsCgkJCSAgICAgICBpbml0cmRfYWRkciwgaW5pdHJkX3NpemUpOwoJCQkKCQkJKih1MzIqKShzZXR1cF9iYXNlICsgUkFNRElTS19JTUFHRV9PRkYpID0gaW5pdHJkX2FkZHI7CgkJCSoodTMyKikoc2V0dXBfYmFzZSArIFJBTURJU0tfU0laRV9PRkYpPWluaXRyZF9zaXplOwoJCX0KCX0KCQoJaWYgKGJvb3Rwcm90byA+PSAweDAyMDEpIHsKCQkqKHUxNiopKHNldHVwX2Jhc2UgKyBIRUFQX0VORF9QVFJfT0ZGKSA9IEhFQVBfRU5EX09GRlNFVDsKCQkKCQkvKiBDQU5fVVNFX0hFQVAgKi8KCQkqKHU4Kikoc2V0dXBfYmFzZSArIExPQURGTEFHU19PRkYpID0gCgkJCSoodTgqKShzZXR1cF9iYXNlICsgTE9BREZMQUdTX09GRikgfCBIRUFQX0ZMQUc7Cgl9CgkKCWlmIChib290cHJvdG8gPj0gMHgwMjAyKSB7CgkJKih1MzIqKShzZXR1cF9iYXNlICsgQ01EX0xJTkVfUFRSX09GRikgPSAodTMyKXNldHVwX2Jhc2UgKyBDT01NQU5EX0xJTkVfT0ZGU0VUOwoJfSBlbHNlIGlmIChib290cHJvdG8gPj0gMHgwMjAwKSB7CgkJKih1MTYqKShzZXR1cF9iYXNlICsgQ01EX0xJTkVfTUFHSUNfT0ZGKSA9IENPTU1BTkRfTElORV9NQUdJQzsKCQkqKHUxNiopKHNldHVwX2Jhc2UgKyBDTURfTElORV9PRkZTRVRfT0ZGKSA9IENPTU1BTkRfTElORV9PRkZTRVQ7IAoJCSoodTE2Kikoc2V0dXBfYmFzZSArIFNFVFVQX01PVkVfU0laRV9PRkYpID0gMHg5MTAwOwoJfQoJCgoJCglpZiAoYmlnX2ltYWdlKSB7CgkJaWYgKChrZXJuZWxfc2l6ZSAtIHNldHVwX3NpemUpID4gQlpJTUFHRV9NQVhfU0laRSkgeyAKCQkJcHJpbnRmKCJFcnJvcjogYnpJbWFnZSBrZXJuZWwgdG9vIGJpZyEgKHNpemU6ICVsZCwgbWF4OiAlZClcbiIsCgkJCSAgICAgICBrZXJuZWxfc2l6ZSAtIHNldHVwX3NpemUsIEJaSU1BR0VfTUFYX1NJWkUpOwoJCQlyZXR1cm4gMDsKCQl9CgkJCgl9IGVsc2UgaWYgKChrZXJuZWxfc2l6ZSAtIHNldHVwX3NpemUpID4gWklNQUdFX01BWF9TSVpFKSB7CgkJcHJpbnRmKCJFcnJvcjogekltYWdlIGtlcm5lbCB0b28gYmlnISAoc2l6ZTogJWxkLCBtYXg6ICVkKVxuIiwKCQkgICAgICAga2VybmVsX3NpemUgLSBzZXR1cF9zaXplLCBaSU1BR0VfTUFYX1NJWkUpOwoJCXJldHVybiAwOwoJfQoJCgkvKiBidWlsZCBjb21tYW5kIGxpbmUgYXQgQ09NTUFORF9MSU5FX09GRlNFVCAqLwoJYnVpbGRfY29tbWFuZF9saW5lKHNldHVwX2Jhc2UgKyBDT01NQU5EX0xJTkVfT0ZGU0VULCBhdXRvX2Jvb3QpOwoJCiAgICAgICAgcHJpbnRmKCJMb2FkaW5nICVjekltYWdlIGF0IGFkZHJlc3MgMHglMDh4ICglbGQgYnl0ZXMpXG4iLCBiaWdfaW1hZ2UgPyAnYicgOiAnICcsIAoJICAgICAgICh1MzIpbG9hZF9hZGRyZXNzLCBrZXJuZWxfc2l6ZSAtIHNldHVwX3NpemUpOwoKCSAgICAgICAKCW1lbW1vdmUobG9hZF9hZGRyZXNzLCBpbWFnZSArIHNldHVwX3NpemUsIGtlcm5lbF9zaXplIC0gc2V0dXBfc2l6ZSk7CgkKCS8qIHJlYWR5IGZvciBib290aW5nICovCglyZXR1cm4gc2V0dXBfYmFzZTsKfQoKCnZvaWQgYm9vdF96aW1hZ2Uodm9pZCAqc2V0dXBfYmFzZSkKewoJc3RydWN0IHB0X3JlZ3MgcmVnczsKCQoJbWVtc2V0KCZyZWdzLCAwLCBzaXplb2Yoc3RydWN0IHB0X3JlZ3MpKTsKCXJlZ3MueGRzID0gKHUzMilzZXR1cF9iYXNlID4+IDQ7CglyZWdzLnhzcyA9IDB4OGUwMDsKCXJlZ3MuZXNwID0gMHgyMDA7CglyZWdzLmVmbGFncyA9IDA7CgllbnRlcl9yZWFsbW9kZSgoKHUzMilzZXR1cF9iYXNlK1NFVFVQX1NUQVJUX09GRlNFVCk+PjQsIDAsICZyZWdzLCAmcmVncyk7Cn0KCgppbWFnZV9oZWFkZXJfdCAqZmFrZV96aW1hZ2VfaGVhZGVyKGltYWdlX2hlYWRlcl90ICpoZHIsIHZvaWQgKnB0ciwgaW50IHNpemUpCnsJCgkvKiBUaGVyZSBpcyBubyB3YXkgdG8ga25vdyB0aGUgc2l6ZSBvZiBhIHpJbWFnZSAuLi4gKgoJICogc28gd2UgYXNzdW1lIHRoYXQgMk1CIHdpbGwgYmUgZW5vdWdoIGZvciBub3cgKi8KI2RlZmluZSBaSU1BR0VfU0laRSAweDIwMDAwMAoJCgkvKiBsb2FkIGEgMU1CLCB0aGUgbG9hZGVkIHdpbGwgaGF2ZSB0byBiZSBtb3ZlZCB0byBpdHMgZmluYWwKCSAqIHBvc2l0aW9uIGFnYWluIGxhdGVyLi4uICovCiNkZWZpbmUgWklNQUdFX0xPQUQgMHgxMDAwMDAKCQoJdWxvbmcgY2hlY2tzdW07CgkKIAlpZiAoS0VSTkVMX01BR0lDICE9ICoodTE2KikocHRyICsgQk9PVF9GTEFHX09GRikpIHsKCQkvKiBub3QgYSB6SW1hZ2Ugb3IgYnpJbWFnZSAqLwoJCXJldHVybiBOVUxMOwoJfQoKCWlmICgtMSA9PSBzaXplKSB7CgkJc2l6ZSA9IFpJTUFHRV9TSVpFOwoJfQojaWYgMAkKCWNoZWNrc3VtID0gY3JjMzIgKDAsIHB0ciwgc2l6ZSk7CiNlbHNlCgljaGVja3N1bSA9IDA7CiNlbmRpZgkJCgltZW1zZXQoaGRyLCAwLCBzaXplb2YoaW1hZ2VfaGVhZGVyX3QpKTsKCQoJLyogQnVpbGQgbmV3IGhlYWRlciAqLwoJaGRyLT5paF9tYWdpYyA9IGh0b25sKElIX01BR0lDKTsKCWhkci0+aWhfdGltZSAgPSAwOwoJaGRyLT5paF9zaXplICA9IGh0b25sKHNpemUpOwoJaGRyLT5paF9sb2FkICA9IGh0b25sKFpJTUFHRV9MT0FEKTsKCWhkci0+aWhfZXAgICAgPSAwOwoJaGRyLT5paF9kY3JjICA9IGh0b25sKGNoZWNrc3VtKTsKCWhkci0+aWhfb3MgICAgPSBJSF9PU19MSU5VWDsKCWhkci0+aWhfYXJjaCAgPSBJSF9DUFVfSTM4NjsKCWhkci0+aWhfdHlwZSAgPSBJSF9UWVBFX0tFUk5FTDsKCWhkci0+aWhfY29tcCAgPSBJSF9DT01QX05PTkU7CgoJc3RybmNweSgoY2hhciAqKWhkci0+aWhfbmFtZSwgIihub25lKSIsIElIX05NTEVOKTsKCgljaGVja3N1bSA9IGNyYzMyKDAsKGNvbnN0IGNoYXIgKiloZHIsc2l6ZW9mKGltYWdlX2hlYWRlcl90KSk7CgoJaGRyLT5paF9oY3JjID0gaHRvbmwoY2hlY2tzdW0pOwoJCglyZXR1cm4gaGRyOwp9Cg==