LyogQ29weXJpZ2h0IChjKSAyMDEzLTIwMTQsIFRoZSBMaW51eCBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQogKiBtZXQ6CiAqICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICogICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQogKiAgICAgICBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZwogKiAgICAgICBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQKICogICAgICAgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKiAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIFRoZSBMaW51eCBGb3VuZGF0aW9uIG5vciB0aGUgbmFtZXMgb2YgaXRzCiAqICAgICAgIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZAogKiAgICAgICBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCiAqCiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRAogKiBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRgogKiBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT04tSU5GUklOR0VNRU5UCiAqIEFSRSBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVCBPV05FUiBPUiBDT05UUklCVVRPUlMKICogQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUgogKiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRgogKiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IKICogQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksCiAqIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFCiAqIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4KICogSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCiAqLwoKI2luY2x1ZGUgPGFyY2gvb3BzLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPGtlcm5lbC90aHJlYWQuaD4KI2luY2x1ZGUgPGRlYnVnLmg+CiNpbmNsdWRlIDxlcnIuaD4KI2luY2x1ZGUgPHJlZy5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxtYWxsb2MuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8dWZzX2h3Lmg+CiNpbmNsdWRlIDx1dHAuaD4KI2luY2x1ZGUgPHVmcy5oPgojaW5jbHVkZSA8cGxhdGZvcm0vaW9tYXAuaD4KI2luY2x1ZGUgPHBsYXRmb3JtL2Nsb2NrLmg+CiNpbmNsdWRlIDxwbGF0Zm9ybS90aW1lci5oPgojaW5jbHVkZSA8YXJjaC9vcHMuaD4KI2luY2x1ZGUgPGVuZGlhbi5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KCnZvaWQgdXRwX3Byb2Nlc3NfcmVxX2NvbXBsZXRpb24oc3RydWN0IHVmc19yZXFfaXJxX3R5cGUgKmlycSkKewoJc3RydWN0IHVmc19yZXFfbm9kZSAqcmVxOwoJc3RydWN0IGxpc3Rfbm9kZSAgICAqcHJldjsKCXVpbnQzMl90ICAgICAgICAgICAgdmFsOwoKCS8qIE1ha2Ugc3VyZSB3ZSBoYXZlIG1vcmUgbm9kZXMgdGhhbiBqdXN0IHRoZSBoZWFkIGluIHRoZSBsaXN0LiAqLwoJaWYgKGxpc3RfbmV4dChpcnEtPmxpc3QsIGlycS0+bGlzdCkgPT0gTlVMTCkKCXsKCQlkcHJpbnRmKENSSVRJQ0FMLCAiJXM6JWQgVVRSRC8gVVRNUkQgcHJvY2Vzc2VkIHNpZ25hbGxlZCBhbmQgdGhlIHdhaXQgcXVldWUgaXMgZW1wdHlcbiIsIF9fZnVuY19fLCBfX0xJTkVfXyk7CgkJQVNTRVJUKDApOwoJfQoKCS8qIFJlYWQgdGhlIGRvb3IgYmVsbCByZWdpc3Rlci4gKi8KCXZhbCA9IHJlYWRsKGlycS0+ZG9vcl9iZWxsX3JlZyk7CgoJbGlzdF9mb3JfZXZlcnlfZW50cnkoaXJxLT5saXN0LCByZXEsIHN0cnVjdCB1ZnNfcmVxX25vZGUsIGxpc3Rfbm9kZSkKCXsKCQlpZiAoIShyZXEtPmRvb3JfYmVsbF9iaXQgJiB2YWwpKQoJCXsKCQkJLyogVHJhbnNhY3Rpb24gaXMgY29tcGxldGU6IEVpdGhlciB0cmFuc2FjdGlvbiBjb21wbGV0ZWQgaW4gYSBub3JtYWwgd2F5LgoJCQkgKiBEZWxldGUgYW5kIFNpZ25hbCBhbGwgcmVxdWVzdHMgdGhhdCBoYXZlIGNvbXBsZXRlZC4KCQkJICovCgkJCXByZXYgPSByZXEtPmxpc3Rfbm9kZS5wcmV2OwoJCQkvKiBUT0RPOiBtb3ZlIGRlbGV0ZSB0byB0aGUgY2FsbGVyIGZ1bmN0aW9uLiAqLwoJCQlsaXN0X2RlbGV0ZSgmKHJlcS0+bGlzdF9ub2RlKSk7CgoJCQlpZiAoZXZlbnRfc2lnbmFsKHJlcS0+ZXZlbnQsIGZhbHNlKSkKCQkJewoJCQkJZHByaW50ZihDUklUSUNBTCwgIiVzOiVkIEV2ZW50IHNpZ25hbCBmYWlsZWQuXG4iLF9fZnVuY19fLCBfX0xJTkVfXyk7CgkJCQlBU1NFUlQoMCk7CgoJCQl9CgkJCXJlcSA9IGNvbnRhaW5lcm9mKHByZXYsIHN0cnVjdCB1ZnNfcmVxX25vZGUsIGxpc3Rfbm9kZSk7CgkJfQoJfQoKCXJldHVybjsKfQoKLyogQWx3YXlzIGNhbGxlZCB3aXRoaW4gY3JpdGljYWwgc2VjdGlvbjogdXRyZF9iaXRtYXBfbXV0ZXgvIHV0bXJkX2JpdG1hcF9tdXRleC4gKi8Kc3RhdGljIHVpbnQzMl90IHV0cF9nZXRfZG9vcl9iZWxsX2JpdCh1aW50MzJfdCByZWcsIHVpbnQzMl90ICpyZWdfYml0bWFwLCB1aW50MzJfdCAqYml0X251bSkKewoJdWludDMyX3QgdmFsID0gMDsKCXVpbnQzMl90IGRvb3JiZWxsX2JpdF92YWw7Cgl1aW50MzJfdCBmb3VuZCA9IDA7CgoJKmJpdF9udW0gPSAwOwoKCXZhbCA9IHJlYWRsKHJlZykgfCAqcmVnX2JpdG1hcDsKCWRvb3JiZWxsX2JpdF92YWwgPSAxOwoKCS8qIEZpbmQgYW4gZW1wdHkgc2xvdC4gKi8KCWRvCgl7CgkJKCpiaXRfbnVtKSsrOwoKCQlpZiAoIShkb29yYmVsbF9iaXRfdmFsICYgdmFsKSkKCQl7CgkJCWZvdW5kID0gMTsKCQkJKnJlZ19iaXRtYXAgfD0gZG9vcmJlbGxfYml0X3ZhbDsKCQkJYnJlYWs7CgkJfQoJCWRvb3JiZWxsX2JpdF92YWwgPDw9IDE7Cgl9d2hpbGUgKGRvb3JiZWxsX2JpdF92YWwgPD0gKHVpbnQzMl90KSAoMSA8PCAzMSkpOwoKCWlmICghZm91bmQpCgl7CgkJZG9vcmJlbGxfYml0X3ZhbCA9IDA7CgkJZHByaW50ZihDUklUSUNBTCwgIiVzOiVkIFVuYWJsZSB0byBmaW5kIGEgZnJlZSBzbG90IGZvciB0cmFuc2FjdGlvbi5cbiIsX19mdW5jX18sIF9fTElORV9fKTsKCX0KCglyZXR1cm4gZG9vcmJlbGxfYml0X3ZhbDsKfQoKc3RhdGljIHZvaWQgdXRwX3JpbmdfZG9vcl9iZWxsKHVpbnQzMl90IHJlZywgdWludDMyX3QgZG9vcmJlbGxfYml0KQp7Cgl3cml0ZWwoZG9vcmJlbGxfYml0LCByZWcpOwp9CgpzdGF0aWMgaW50IHV0cF91dHJkX3Byb2Nlc3NfdGltZW91dF9yZXEoc3RydWN0IHVmc19kZXYgKmRldiwKCQkJCQkJCQkgc3RydWN0IHV0cF91dHJkX3JlcV9idWlsZF90eXBlICp1dHJkX3JlcSwKCQkJCQkJCQkgc3RydWN0IHVmc19yZXFfbm9kZSAqcmVxKQp7Cglzd2l0Y2ggKHV0cmRfcmVxLT5yZXFfdXBpdS0+dHJhbnNfdHlwZSkKCXsKCQljYXNlIFVQSVVfVFlQRV9OT1BfT1VUOgoJCQkJCQkJICAgIHdyaXRlbCh+cmVxLT5kb29yX2JlbGxfYml0LCBVRlNfVVRSTENMUihkZXYtPmJhc2UpKTsKCQkJCQkJCQlyZXR1cm4gLVVGU19SRVRSWTsKCQlkZWZhdWx0OgoJCQkJCQkJCS8qIFRPRE8gOiBBZGQgdWZzIGhjaSBzdyByZXNldC4qLwoJCQkJCQkJCUFTU0VSVCgwKTsKCQkJCQkJCQlyZXR1cm4gLVVGU19GQUlMVVJFOwoJfQp9CgpzdGF0aWMgaW50IHV0cF9yZW1vdmVfZnJvbV9iaXRtYXAoc3RydWN0IHV0cF9iaXRtYXBfYWNjZXNzX3R5cGUgKnJlcSkKewoKCWlmIChtdXRleF9hY3F1aXJlKHJlcS0+bXV0eCkpCgl7CgkJcmV0dXJuIC1VRlNfRkFJTFVSRTsKCX0KCgkqKHJlcS0+Yml0bWFwKSAmPSB+cmVxLT5kb29yX2JlbGxfYml0OwoKCWlmIChtdXRleF9yZWxlYXNlKHJlcS0+bXV0eCkpCgl7CgkJcmV0dXJuIC1VRlNfRkFJTFVSRTsKCX0KCglyZXR1cm4gVUZTX1NVQ0NFU1M7Cn0KCnN0YXRpYyB2b2lkIHV0cF9lbnF1ZXVlX3V0cmRfZmlsbF9kZXNjKHN0cnVjdCB1dHBfdHJhbnNfcmVxX2Rlc2MgKmRlc2MsIHN0cnVjdCB1dHBfdXRyZF9yZXFfYnVpbGRfdHlwZSAqdXRyZF9yZXEpCnsKCS8qIEZpbGwgdHJhbnNmZXIgZGVzYy4gKi8KCW1lbXNldChkZXNjLCAwLCBVUElVX0hEUl9MRU4pOwoJZGVzYy0+Y21kX3R5cGVfZGRfaXJxID0gVVRQX1JFUV9CVUlMRF9DTURfRERfSVJRX0ZJRUxEKHV0cmRfcmVxLT5jbWRfdHlwZSwgdXRyZF9yZXEtPmRkLCB1dHJkX3JlcS0+aXJxKTsKCWRlc2MtPm92ZXJhbGxfY21kX3N0YXR1cyA9IHV0cmRfcmVxLT5vY3M7CgkvKiBCaXRzIDAgLSA2IGFyZSByZXNlcnZlZCBpbiBjbWRfZGVzY19iYXNlX2FkZHJbMF0gZmllbGQuICovCglkZXNjLT5jbWRfZGVzY19iYXNlX2FkZHJbMF0gPSAoKHVpbnQzMl90KSB1dHJkX3JlcS0+cmVxX3VwaXUpICYgMHhDMDsKCWRlc2MtPmNtZF9kZXNjX2Jhc2VfYWRkclsxXSA9ICgodWludDMyX3QpIHV0cmRfcmVxLT5yZXFfdXBpdSA+PiA4KSAmIDB4RkY7CglkZXNjLT5jbWRfZGVzY19iYXNlX2FkZHJbMl0gPSAoKHVpbnQzMl90KSB1dHJkX3JlcS0+cmVxX3VwaXUgPj4gMTYpICYgMHhGRjsKCWRlc2MtPmNtZF9kZXNjX2Jhc2VfYWRkclszXSA9ICgodWludDMyX3QpIHV0cmRfcmVxLT5yZXFfdXBpdSA+PiAyNCkgJiAweEZGOwoJZGVzYy0+cmVzcF91cGl1X29mZnNldCA9IFJPVU5EVVAodXRyZF9yZXEtPnJlcV91cGl1X2xlbiwgVVBJVV9IRFJfTEVOKSAvIDQ7CglkZXNjLT5yZXNwX3VwaXVfbGVuID0gdXRyZF9yZXEtPnJlc3BfdXBpdV9sZW47CgoJaWYgKHV0cmRfcmVxLT5kZCAhPSBVVFJEX05PX0RBVEFfVFJBTlNGRVIpCgl7CgkJLyogRGF0YSB0cmFuc2ZlciBjb21tYW5kLgoJCSAqIEZpbGwgaW4gUFJEVCBkYXRhLgoJCSAqLwoJCWRlc2MtPnByZHRfb2Zmc2V0ID0gdXRyZF9yZXEtPnByZHRfb2Zmc2V0IC8gNDsKCQlkZXNjLT5wcmR0X2xlbiAgICA9IHV0cmRfcmVxLT5wcmR0X2xlbjsKCX0KCgkvKiBGbHVzaCBVVFJEIHRvIG1lbW9yeS4gKi8KCWNhY2hlX2NsZWFuX2ludmFsaWRhdGVfdW5hbGlnbmVkX3N0YXJ0X2FkZHIoKGFkZHJfdClkZXNjLCBzaXplb2Yoc3RydWN0IHV0cF90cmFuc19yZXFfZGVzYykpOwp9CgpzdGF0aWMgc3RydWN0IHV0cF90cmFuc19yZXFfZGVzYyogdXRwX2dldF9kZXNjX3Nsb3RfYWRkcihzdHJ1Y3QgdWZzX2RldiAqZGV2LCBzdHJ1Y3QgdXRwX3V0cmRfcmVxX2J1aWxkX3R5cGUgKnV0cmRfcmVxLCB1aW50MzJfdCAqZG9vcl9iZWxsX3ZhbCkKewoJc3RydWN0IHV0cF90cmFuc19yZXFfZGVzYyAqZGVzYyA9IE5VTEw7Cgl1aW50MzJfdCAgICAgICAgICAgICAgICAgIGRvb3JfYmVsbF9zbG90OwoKCWlmIChtdXRleF9hY3F1aXJlKCYoZGV2LT51dHJkX2RhdGEuYml0bWFwX211dGV4KSkpCgl7CgkJZ290byB1dHBfZ2V0X2Rlc2Nfc2xvdF9hZGRyX2VycjsKCX0KCgkqZG9vcl9iZWxsX3ZhbCA9IHV0cF9nZXRfZG9vcl9iZWxsX2JpdChVRlNfVVRSTERCUihkZXYtPmJhc2UpLCAmZGV2LT51dHJkX2RhdGEuYml0bWFwLCAmZG9vcl9iZWxsX3Nsb3QpOwoJaWYgKCEoKmRvb3JfYmVsbF92YWwpKQoJewoJCWdvdG8gdXRwX2dldF9kZXNjX3Nsb3RfYWRkcl9lcnI7Cgl9CgoJaWYgKG11dGV4X3JlbGVhc2UoJihkZXYtPnV0cmRfZGF0YS5iaXRtYXBfbXV0ZXgpKSkKCXsKCQlnb3RvIHV0cF9nZXRfZGVzY19zbG90X2FkZHJfZXJyOwoJfQoKCWRlc2MgPSAoc3RydWN0IHV0cF90cmFuc19yZXFfZGVzYyAqKSAoKGFkZHJfdClkZXYtPnV0cmRfZGF0YS5saXN0X2Jhc2VfYWRkciArIChkb29yX2JlbGxfc2xvdCAtIDEpICogc2l6ZW9mKHN0cnVjdCB1dHBfdHJhbnNfcmVxX2Rlc2MpKTsKCnV0cF9nZXRfZGVzY19zbG90X2FkZHJfZXJyOgoJcmV0dXJuIGRlc2M7Cn0KCmludCB1dHBfcG9sbF91dHJkX2NvbXBsZXRlKHN0cnVjdCB1ZnNfZGV2ICpkZXYpCnsKCWludCByZXQgPSBFUlJPUjsKCXN0cnVjdCB1ZnNfcmVxX2lycV90eXBlIGlycTsKCXVpbnQzMl90IHZhbCwgYmFzZSwgcmV0cnkgPSAwOwoJYmFzZSA9IGRldi0+YmFzZTsKCXZhbCA9IHJlYWRsKFVGU19JUyhiYXNlKSk7CglpcnEuaXJxX2hhbmRsZWQgPSAwOwoJLyogV2FpdCB0aWxsIHRoZSBkZXNjIGhhcyBiZWVuIHByb2Nlc3NlZC4gKi8KCXdoaWxlKCgodmFsICYgVUZTX0lTX1VUUkNTKSA9PSAwKSAmJiAoKHZhbCAmIFVGU19JU19VVE1SQ1MpID09IDApKQoJewoJCXZhbCA9IHJlYWRsKFVGU19JUyhiYXNlKSk7CgkJcmV0cnkrKzsKCQl1ZGVsYXkoMSk7CgkJaWYocmV0cnkgPT0gVVRQX01BWF9DT01NQU5EX1JFVFJZKQoJCXsKCQkJZHByaW50ZihDUklUSUNBTCwgIiVzOiVkIFVUUCBjb21tYW5kIG5ldmVyIGNvbXBsZXRlZC5cbiIsIF9fZnVuY19fLCBfX0xJTkVfXyk7CgkJCXJldHVybiBFUlJfVElNRURfT1VUOwoJCX0KI2lmZGVmIERFQlVHX1VGUwoJCWRwcmludGYoSU5GTywgIldhaXRpbmcgZm9yIFVUUkNTL1VSTVJDUyBDb21wbGV0aW9uLi4uXG4iKTsKI2VuZGlmCgl9CglpZiAocmVhZGwoVUZTX0lTKGJhc2UpKSAmIFVGU19JU19VVFJDUykKCXsKCQl2YWwgPSByZWFkbChVRlNfSVMoYmFzZSkpICYgVUZTX0lTX1VUUkNTOwoJCXdyaXRlbChVRlNfSVNfVVRSQ1MsIFVGU19JUyhiYXNlKSk7CgkJaXJxLmlycV9oYW5kbGVkID0gVUZTX0lTX1VUUkNTOwoJCWlycS5saXN0ID0gJihkZXYtPnV0cmRfZGF0YS5saXN0X2hlYWQubGlzdF9ub2RlKTsKCQlpcnEuZG9vcl9iZWxsX3JlZyA9IFVGU19VVFJMREJSKGJhc2UpOwoJCXV0cF9wcm9jZXNzX3JlcV9jb21wbGV0aW9uKCZpcnEpOwoJCXJldCA9IElOVF9OT19SRVNDSEVEVUxFOwoJfQoJZWxzZSBpZiAocmVhZGwoVUZTX0lTKGJhc2UpKSAmIChVRlNfSVNfVVRNUkNTKSkKCXsKCQl2YWwgPSByZWFkbChVRlNfSVMoYmFzZSkpICYgVUZTX0lTX1VUTVJDUzsKCQl3cml0ZWwoVUZTX0lTX1VUTVJDUywgVUZTX0lTKGJhc2UpKTsKCQlpcnEuaXJxX2hhbmRsZWQgPSBVRlNfSVNfVVRNUkNTOwoJCWlycS5saXN0ID0gJihkZXYtPnV0bXJkX2RhdGEubGlzdF9oZWFkLmxpc3Rfbm9kZSk7CgkJdXRwX3Byb2Nlc3NfcmVxX2NvbXBsZXRpb24oJmlycSk7CgkJcmV0ID0gSU5UX05PX1JFU0NIRURVTEU7Cgl9CglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgaW50IHV0cF9lbnF1ZXVlX3V0cmQoc3RydWN0IHVmc19kZXYgKmRldiwgc3RydWN0IHV0cF91dHJkX3JlcV9idWlsZF90eXBlICp1dHJkX3JlcSkKewoJaW50ICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0OwoJc3RydWN0IHV0cF90cmFuc19yZXFfZGVzYyAgICAgKmRlc2M7CglldmVudF90ICAgICAgICAgICAgICAgICAgICAgICB1dHJkX2V2dDsKCXN0cnVjdCB1ZnNfcmVxX25vZGUgICAgICAgICAgICpyZXE7Cgl1aW50MzJfdCAgICAgICAgICAgICAgICAgICAgICBkb29yX2JlbGxfYml0X3ZhbDsKCXN0cnVjdCB1dHBfYml0bWFwX2FjY2Vzc190eXBlIGJpdG1hcF9yZXE7CgoJcmV0ID0gVUZTX1NVQ0NFU1M7CglyZXEgPSAoc3RydWN0IHVmc19yZXFfbm9kZSAqKW1hbGxvYyhzaXplb2Yoc3RydWN0IHVmc19yZXFfbm9kZSkpOwoKCWV2ZW50X2luaXQoJnV0cmRfZXZ0LCBmYWxzZSwgRVZFTlRfRkxBR19BVVRPVU5TSUdOQUwpOwoKCWRlc2MgPSB1dHBfZ2V0X2Rlc2Nfc2xvdF9hZGRyKGRldiwgdXRyZF9yZXEsICZkb29yX2JlbGxfYml0X3ZhbCk7CglpZiAoIWRlc2MpCgl7CgkJcmV0ID0gVUZTX0ZBSUxVUkU7CgkJZ290byB1dHBfZW5xdWV1ZV91dHJkX2VycjsKCX0KCgkvKiBDaGVjayByZWdpc3RlciBVVFJMUlNSIGFuZCBtYWtlIHN1cmUgaXQgaXMgcmVhZCCRMZIgYmVmb3JlIGNvbnRpbnVpbmcuICovCglpZiAoIXJlYWRsKFVGU19VVFJMUlNSKGRldi0+YmFzZSkpKQoJewoJCXJldCA9IC1VRlNfRkFJTFVSRTsKCQlnb3RvIHV0cF9lbnF1ZXVlX3V0cmRfZXJyOwoJfQoKCXV0cF9lbnF1ZXVlX3V0cmRfZmlsbF9kZXNjKGRlc2MsIHV0cmRfcmVxKTsKCglyZXEtPmRvb3JfYmVsbF9iaXQgPSBkb29yX2JlbGxfYml0X3ZhbDsKCXJlcS0+ZXZlbnQgICAgICAgICA9ICZ1dHJkX2V2dDsKCgkvKiBFbnF1ZXVlIHRoZSByZXEgaW4gdGhlIGRldmljZSB1dHJkIGxpc3QuICovCglsaXN0X2FkZF9oZWFkKCYoZGV2LT51dHJkX2RhdGEubGlzdF9oZWFkLmxpc3Rfbm9kZSksICYocmVxLT5saXN0X25vZGUpKTsKCglkc2IoKTsKCiNpZmRlZiBERUJVR19VRlMKCS8vIHByaW50IElTIGJlZm9yZSB3cml0ZQoJdWZzX2R1bXBfaXNfcmVnaXN0ZXIoZGV2KTsKI2VuZGlmCgoJdXRwX3JpbmdfZG9vcl9iZWxsKFVGU19VVFJMREJSKGRldi0+YmFzZSksIGRvb3JfYmVsbF9iaXRfdmFsKTsKCglkc2IoKTsKCiNpZmRlZiBERUJVR19VRlMKCS8vIHByaW50IElTIGFmdGVyIHdyaXRlCgl1ZnNfZHVtcF9pc19yZWdpc3RlcihkZXYpOwojZW5kaWYKCXJldCA9IHV0cF9wb2xsX3V0cmRfY29tcGxldGUoZGV2KTsKCglpZiAocmV0ID09IEVSUl9USU1FRF9PVVQpCgl7CgkJLyogVHJhbnNhY3Rpb24gbm90IGNvbXBsZXRlZCBldmVuIGFmdGVyIHRpbWVvdXQgbXMuICovCgkJZHByaW50ZihDUklUSUNBTCwgIiVzOiVkIFRyYW5zYWN0aW9uIHRpbWVvdXQgYWZ0ZXIgcG9sbGluZyAlZCB0aW1lc1xuIixfX2Z1bmNfXywgX19MSU5FX18sIFVUUF9NQVhfQ09NTUFORF9SRVRSWSk7CgkJcmV0ID0gdXRwX3V0cmRfcHJvY2Vzc190aW1lb3V0X3JlcShkZXYsIHV0cmRfcmVxLCByZXEpOwoJCWdvdG8gdXRwX2VucXVldWVfdXRyZF9lcnI7Cgl9CgllbHNlCgl7CgkJLyogUmVzZXQgcmV0IGJlZm9yZSByZXR1cm5pbmcuICovCgkJcmV0ID0gVUZTX1NVQ0NFU1M7CgoJCS8qIEZvcmNlIHJlYWQgVVRSRCBmcm9tIG1lbW9yeS4gKi8KCQlkc2IoKTsKCQljYWNoZV9jbGVhbl9pbnZhbGlkYXRlX3VuYWxpZ25lZF9zdGFydF9hZGRyKChhZGRyX3QpIGRlc2MsIHNpemVvZihzdHJ1Y3QgdWZzX3JlcV9ub2RlKSk7CgoJCS8qIENoZWNrIHRoZSByZXNwb25zZS4gKi8KCQlpZiAoZGVzYy0+b3ZlcmFsbF9jbWRfc3RhdHVzICE9IFVUUkRfT0NTX1NVQ0NFU1MpCgkJewoJCQlkcHJpbnRmKENSSVRJQ0FMLCAiJXM6JWQgQ29tbWFuZCBmYWlsZWQuIGNvbW1hbmQgdHlwZSA9ICV4XG4iLCBfX2Z1bmNfXywgX19MSU5FX18sIHV0cmRfcmVxLT5jbWRfdHlwZSk7CgkJCXJldCA9IC1VRlNfRkFJTFVSRTsKCQkJZ290byB1dHBfZW5xdWV1ZV91dHJkX2VycjsKCQl9Cgl9CgoJLyogU2lnbmFsIHNsb3QgYXMgZnJlZS4gKi8KCWJpdG1hcF9yZXEuYml0bWFwICAgICAgICA9ICZkZXYtPnV0cmRfZGF0YS5iaXRtYXA7CgliaXRtYXBfcmVxLmRvb3JfYmVsbF9iaXQgPSByZXEtPmRvb3JfYmVsbF9iaXQ7CgliaXRtYXBfcmVxLm11dHggICAgICAgICAgPSAmKGRldi0+dXRyZF9kYXRhLmJpdG1hcF9tdXRleCk7CgoJcmV0ID0gdXRwX3JlbW92ZV9mcm9tX2JpdG1hcCgmYml0bWFwX3JlcSk7CglpZiAocmV0KQoJCWdvdG8gdXRwX2VucXVldWVfdXRyZF9lcnI7Cgp1dHBfZW5xdWV1ZV91dHJkX2VycjoKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBpbnQgdXRwX2dldF9wcmR0X2xlbih1aW50MzJfdCBkYXRhX2xlbiwgdWludDMyX3QgKm51bV9wcmR0KQp7CgkvKiBDYWxjdWxhdGUgdGhlIHByZHQgZW50cmllcyByZXF1aXJlZC4gKi8KCSpudW1fcHJkdCA9IFJPVU5EVVAoZGF0YV9sZW4sIFVUUF9NQVhfUFJEX0RBVEFfQllURV9DTlQpOwoJKm51bV9wcmR0ID4+PSBVVFBfTUFYX1BSRF9EQVRBX0JZVEVfQ05UX0JZVEVfU0hJRlQ7CgoJaWYgKCpudW1fcHJkdCA+IFVUUF9NQVhfUFJEX1RBQkxFX0VOVFJJRVMpCgl7CgkJZHByaW50ZihDUklUSUNBTCwgIiVzOiVkIERhdGEgbGVuZ3RoIGV4Y2VlZHMgZm9yIGEgc2luZ2xlIHVwaXUgdHJhbnNmZXIuXG4iLCBfX2Z1bmNfXyxfX0xJTkVfXyk7CgkJcmV0dXJuIC1VRlNfRkFJTFVSRTsKCX0KCglyZXR1cm4gVUZTX1NVQ0NFU1M7Cn0KCnN0YXRpYyBpbnQgdXRwX2ZpbGxfcmVxX3VwaXUoc3RydWN0IHVmc19kZXYgKmRldiwgc3RydWN0IHVwaXVfcmVxX2J1aWxkX3R5cGUgKnVwaXVfZGF0YSwgc3RydWN0IHVwaXVfZ2VuX2hkciAqcmVxX3VwaXUpCnsKCW1lbXNldChyZXFfdXBpdSwgMCwgVVBJVV9IRFJfTEVOKTsKCglpZiAodXBpdV9kYXRhLT50cmFuc190eXBlID09IFVQSVVfVFlQRV9RVUVSWV9SRVEpCgl7CgkJLyogRmlsbCBpbiBxdWVyeSBzcGVjaWZpYyBmaWVsZHMuICovCgkJaWYgKHV0cF9idWlsZF9xdWVyeV9yZXFfdXBpdSgoc3RydWN0IHVwaXVfdHJhbnNfbWdtdF9xdWVyeV9oZHIgKikgcmVxX3VwaXUsIHVwaXVfZGF0YSkpCgkJewoJCQlyZXR1cm4gLVVGU19GQUlMVVJFOwoJCX0KCX0KCgkvKiBJZiBhIGRhdGEgdHJhbnNmZXIgY21kLCBjaGVjayB0aGUgYWxpZ25tZW50IGFuZCBsZW5ndGggb2YgdGhlIGJ1ZmZlci4gKi8KCWlmICh1cGl1X2RhdGEtPmV4cGVjdGVkX2RhdGFfbGVuKQoJewoJCWlmICh1cGl1X2RhdGEtPmRhdGFfYnVmZmVyX2FkZHIgJiAweDMpCgkJewoJCQlkcHJpbnRmKENSSVRJQ0FMLCAiJXM6JWQgQWxpZ25tZW50IGFuZCBsZW5ndGggY2hlY2sgZmFpbGVkIGZvciBkYXRhIHRyYW5mZXIgY29tbWFuZC5cbiIsIF9fZnVuY19fLCBfX0xJTkVfXyk7CgkJCXJldHVybiAtVUZTX0ZBSUxVUkU7CgkJfQoJfQoKCXJlcV91cGl1LT5iYXNpY19oZHIudHJhbnNfdHlwZSAgICA9IHVwaXVfZGF0YS0+dHJhbnNfdHlwZTsKCXJlcV91cGl1LT5iYXNpY19oZHIuZmxhZ3MgICAgICAgICA9IHVwaXVfZGF0YS0+ZmxhZ3M7CglyZXFfdXBpdS0+YmFzaWNfaGRyLmNtZF9zZXRfdHlwZSAgPSB1cGl1X2RhdGEtPmNtZF9zZXRfdHlwZTsKCXJlcV91cGl1LT5iYXNpY19oZHIuZGF0YV9zZWdfbGVuICA9IHVwaXVfZGF0YS0+ZGF0YV9zZWdfbGVuOwoJcmVxX3VwaXUtPmJhc2ljX2hkci5sdW4gICAgICAgICAgID0gdXBpdV9kYXRhLT5sdW47CglyZXFfdXBpdS0+YmFzaWNfaGRyLnRvdGFsX2Voc19sZW4gPSB1cGl1X2RhdGEtPmVoc19sZW47CglyZXFfdXBpdS0+YmFzaWNfaGRyLnRhc2tfdGFnICAgICAgPSBhdG9taWNfYWRkKChpbnQgKikgJihkZXYtPnV0cmRfZGF0YS50YXNrX2lkKSwgMSk7CglpZiAodXBpdV9kYXRhLT5jZGIpCgkJbWVtY3B5KCYocmVxX3VwaXUtPnRyYW5zX3NwZWNpZmljX2ZpZWxkc1s0XSksICh2b2lkICopIHVwaXVfZGF0YS0+Y2RiLCAxNik7CgkvKiBJZiBjb21tYW5kIHVwaXUsIGZpbGwgaW4gZGF0YSBsZW5ndGguICovCglpZiAocmVxX3VwaXUtPmJhc2ljX2hkci50cmFuc190eXBlID09IFVQSVVfVFlQRV9DT01NQU5EKQoJCSgoc3RydWN0IHVwaXVfY21kX2hkciAqKXJlcV91cGl1KS0+ZGF0YV9leHBlY3RlZF9sZW4gPSBCRTMyKHVwaXVfZGF0YS0+ZXhwZWN0ZWRfZGF0YV9sZW4pOwoKCXJldHVybiBVRlNfU1VDQ0VTUzsKCn0KCnN0YXRpYyB2b2lkIHV0cF9maWxsX3V0cmRfcHJvcGVydGllcyhzdHJ1Y3QgdXBpdV9yZXFfYnVpbGRfdHlwZSAqdXBpdV9kYXRhLAoJCQkJCQkJCQkgc3RydWN0IHV0cF91dHJkX3JlcV9idWlsZF90eXBlICp1dHJkLAoJCQkJCQkJCQkgc3RydWN0IHV0cmRfY21kX2Rlc2MgKmNtZF9kZXNjKQp7Cgl1dHJkLT5jbWRfdHlwZSAgICAgID0gdXBpdV9kYXRhLT5jbWRfdHlwZTsKCXV0cmQtPmRkICAgICAgICAgICAgPSB1cGl1X2RhdGEtPmRkOwoJdXRyZC0+aXJxICAgICAgICAgICA9IFVUUkRfSVJRX0NNRDsKCXV0cmQtPnByZHRfb2Zmc2V0ICAgPSBVUElVX0hEUl9MRU4gKyBjbWRfZGVzYy0+cmVzcF91cGl1X2xlbjsKCXV0cmQtPnByZHRfbGVuICAgICAgPSBjbWRfZGVzYy0+bnVtX3ByZHQ7Cgl1dHJkLT5yZXFfdXBpdSAgICAgID0gKHN0cnVjdCB1cGl1X2Jhc2ljX2hkciAqKSBjbWRfZGVzYy0+cmVxX3VwaXU7Cgl1dHJkLT5yZXFfdXBpdV9sZW4gID0gVVBJVV9IRFJfTEVOOwoJdXRyZC0+cmVzcF91cGl1X2xlbiA9IGNtZF9kZXNjLT5yZXNwX3VwaXVfbGVuOwoJdXRyZC0+b2NzICAgICAgICAgICA9IDB4RjsKCXV0cmQtPnRpbWVvdXQgICAgICAgPSB1cGl1X2RhdGEtPnRpbWVvdXRfbXNlY3M7Cn0KCnN0YXRpYyB2b2lkIHV0cF9maWxsX3ByZHRfZW50cmllcyhzdHJ1Y3QgdXBpdV9yZXFfYnVpbGRfdHlwZSAqdXBpdV9kYXRhLCBzdHJ1Y3QgdXRwX3ByZHRfZW50cnkgKnByZHRfZW50cnkpCnsKCXVpbnQ2NF90IGJ1ZjsKCXVpbnQ2NF90IGJ5dGVzX3JlbWFpbmluZzsKCXVpbnQzMl90IHByZF9kYmM7CgoJYnVmICAgICAgICAgICAgICAgID0gdXBpdV9kYXRhLT5kYXRhX2J1ZmZlcl9hZGRyOwoJYnl0ZXNfcmVtYWluaW5nICAgID0gdXBpdV9kYXRhLT5leHBlY3RlZF9kYXRhX2xlbjsKCgl3aGlsZSAoYnl0ZXNfcmVtYWluaW5nKQoJewoJCXByZHRfZW50cnktPmRhdGFfYmFzZV9hZGRyICAgPSBidWY7CgkJcHJkdF9lbnRyeS0+ZGF0YV91cHBlcl9hZGRyICA9IGJ1ZiA+PiAzMjsKCQlwcmRfZGJjICAgICAgICAgICAgICAgICAgICAgID0gTUlOKFVUUF9NQVhfUFJEX0RBVEFfQllURV9DTlQsIGJ5dGVzX3JlbWFpbmluZykgLSAxOwoJCXByZHRfZW50cnktPmRhdGFfYnl0ZV9jbnQgICAgPSBwcmRfZGJjOwoJCWlmIChieXRlc19yZW1haW5pbmcgPD0gVVRQX01BWF9QUkRfREFUQV9CWVRFX0NOVCkKCQkJYnJlYWs7CgkJYnVmICAgICAgICAgICAgICs9IFVUUF9NQVhfUFJEX0RBVEFfQllURV9DTlQ7CgkJYnl0ZXNfcmVtYWluaW5nIC09IFVUUF9NQVhfUFJEX0RBVEFfQllURV9DTlQ7CgkJcHJkdF9lbnRyeSsrOwoJfQoKfQoKaW50IHV0cF9lbnF1ZXVlX3VwaXUoc3RydWN0IHVmc19kZXYgKmRldiwgc3RydWN0IHVwaXVfcmVxX2J1aWxkX3R5cGUgKnVwaXVfZGF0YSkKewoJc3RydWN0IHVwaXVfZ2VuX2hkciAgICAgICAgICAgICpyZXFfdXBpdTsKCXN0cnVjdCB1dHBfdXRyZF9yZXFfYnVpbGRfdHlwZSB1dHJkOwoJdWludDMyX3QgICAgICAgICAgICAgICAgICAgICAgIG51bV9wcmR0OwoJc3RydWN0IHV0cF9wcmR0X2VudHJ5ICAgICAgICAgICpwcmR0X2VudHJ5OwoJaW50ICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldCA9IFVGU19TVUNDRVNTOwoJdWludDMyX3QgICAgICAgICAgICAgICAgICAgICAgIHJlc3BfbGVuOwoJdWludDMyX3QgICAgICAgICAgICAgICAgICAgICAgIGNtZF9kZXNjX2xlbjsKCXN0cnVjdCB1dHJkX2NtZF9kZXNjICAgICAgICAgICBjbWRfZGVzYzsKCgkvKiBSb3VuZCB1cCByZXNwX3VwaXVfbGVuIHRvIGEgRFdPUkQgYm91bmRhcnkuCgkgKiBBbHNvLCBtYWtlIHN1cmUgaXQgaXMgb2YgbWluIHJlcXVpcmVkIGxlbmd0aC4KCSAqLwoJcmVzcF9sZW4gPSBST1VORFVQKHVwaXVfZGF0YS0+cmVzcF9kYXRhX2xlbiwgNCkgKyBVUElVX0hEUl9MRU47CgoJaWYgKHV0cF9nZXRfcHJkdF9sZW4odXBpdV9kYXRhLT5leHBlY3RlZF9kYXRhX2xlbiwgJm51bV9wcmR0KSkKCQlyZXR1cm4gLVVGU19GQUlMVVJFOwoKCS8qIENhbGN1bGF0ZSB0aGUgbGVuZ3RoLiAqLwoJY21kX2Rlc2NfbGVuID0gVVBJVV9IRFJfTEVOICsgcmVzcF9sZW4gKyBudW1fcHJkdCAqIHNpemVvZihzdHJ1Y3QgdXRwX3ByZHRfZW50cnkpOwoKCS8qIEFsbG9jYXRlIG1lbW9yeSBmb3IgVVRQIENvbW1hbmQgRGVzY3JpcHRvci4gKi8KCXJlcV91cGl1ID0gKHN0cnVjdCB1cGl1X2dlbl9oZHIqKSBtZW1hbGlnbigoc2l6ZV90ICkgbGNtKENBQ0hFX0xJTkUsIFVUUF9DTURfREVTQ19CQVNFX0FMSUdOTUVOVF9TSVpFKSwgUk9VTkRVUChjbWRfZGVzY19sZW4sIENBQ0hFX0xJTkUpKTsKCWlmICghcmVxX3VwaXUpCgl7CgkJZHByaW50ZihDUklUSUNBTCwgIiVzOiVkIFVuYWJsZSB0byBhbGxvY2F0ZSByZXF1ZXN0IHVwaXVcbiIsX19mdW5jX18sIF9fTElORV9fKTsKCQlyZXR1cm4gLVVGU19GQUlMVVJFOwoJfQoKCS8qIEZpbGwgcmVxIHVwaXUuICovCglyZXQgPSB1dHBfZmlsbF9yZXFfdXBpdShkZXYsIHVwaXVfZGF0YSwgcmVxX3VwaXUpOwoJaWYgKHJldCkKCXsKCQlnb3RvIHV0cF9lbnF1ZXVlX3VwaXVfZXJyOwoJfQoKCS8qIEZpbGwgVVRSRCBwcm9wZXJ0aWVzLiAqLwoJY21kX2Rlc2MubnVtX3ByZHQgICAgICA9IG51bV9wcmR0OwoJY21kX2Rlc2MucmVxX3VwaXUgICAgICA9IHJlcV91cGl1OwoJY21kX2Rlc2MucmVzcF91cGl1X2xlbiA9IHJlc3BfbGVuOwoJdXRwX2ZpbGxfdXRyZF9wcm9wZXJ0aWVzKHVwaXVfZGF0YSwgJnV0cmQsICZjbWRfZGVzYyk7CgoJcHJkdF9lbnRyeSAgICAgICAgID0gKHN0cnVjdCB1dHBfcHJkdF9lbnRyeSAqKSAoKHVpbnQzMl90KSByZXFfdXBpdSArIFVQSVVfSERSX0xFTiArIHJlc3BfbGVuKTsKCgkvKiBGaWxsIFBSRFQgZW50cmllcy4gKi8KCWlmIChudW1fcHJkdCkKCXV0cF9maWxsX3ByZHRfZW50cmllcyh1cGl1X2RhdGEsIHByZHRfZW50cnkpOwoKCS8qIEZsdXNoIHJlcV91cGl1ICovCglkc2IoKTsKCWFyY2hfY2xlYW5faW52YWxpZGF0ZV9jYWNoZV9yYW5nZSgoYWRkcl90KSByZXFfdXBpdSwgY21kX2Rlc2NfbGVuKTsKCgkvKiBDaGVjayB0aGUgcmVzcG9uc2UuICovCglyZXQgPSB1dHBfZW5xdWV1ZV91dHJkKGRldiwgJnV0cmQpOwoJaWYgKHJldCkKCXsKCQlkcHJpbnRmKENSSVRJQ0FMLCAiJXM6JWQgQ29tbWFuZCBmYWlsZWQuIGNvbW1hbmQgPSAleFxuIiwgX19mdW5jX18sIF9fTElORV9fLCByZXFfdXBpdS0+YmFzaWNfaGRyLnRyYW5zX3R5cGUpOwoJCWdvdG8gdXRwX2VucXVldWVfdXBpdV9lcnI7Cgl9CgoJLyogVVBJVSBwcm9jZXNzZWQuIEludmFsaWRhdGUgY2FjaGUgdG8gdXBkYXRlIHJlc3AuICovCglhcmNoX2ludmFsaWRhdGVfY2FjaGVfcmFuZ2UoKGFkZHJfdCkgcmVxX3VwaXUsIGNtZF9kZXNjX2xlbik7CgoJLyogU2F2ZSB0aGUgcmVzcG9uc2UuICovCgltZW1jcHkodXBpdV9kYXRhLT5yZXNwX3B0ciwgKHZvaWQgKikgKCh1aW50MzJfdClyZXFfdXBpdSArIFVQSVVfSERSX0xFTiksIHVwaXVfZGF0YS0+cmVzcF9sZW4pOwoJbWVtY3B5KCh2b2lkICopIHVwaXVfZGF0YS0+cmVzcF9kYXRhX3B0ciwgKHZvaWQgKikgKCh1aW50MzJfdClyZXFfdXBpdSArIDIgKiBVUElVX0hEUl9MRU4pLCB1cGl1X2RhdGEtPnJlc3BfZGF0YV9sZW4pOwoKdXRwX2VucXVldWVfdXBpdV9lcnI6CglmcmVlKHJlcV91cGl1KTsKCXJldHVybiByZXQ7Cn0K