LyoKICogTkRBIEFORCBORUVELVRPLUtOT1cgUkVRVUlSRUQKICoKICogQ29weXJpZ2h0IKkgMjAxMy0yMDE4IFN5bmFwdGljcyBJbmNvcnBvcmF0ZWQuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqCiAqIFRoaXMgZmlsZSBjb250YWlucyBpbmZvcm1hdGlvbiB0aGF0IGlzIHByb3ByaWV0YXJ5IHRvIFN5bmFwdGljcwogKiBJbmNvcnBvcmF0ZWQgKCJTeW5hcHRpY3MiKS4gVGhlIGhvbGRlciBvZiB0aGlzIGZpbGUgc2hhbGwgdHJlYXQgYWxsCiAqIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gYXMgY29uZmlkZW50aWFsLCBzaGFsbCB1c2UgdGhlCiAqIGluZm9ybWF0aW9uIG9ubHkgZm9yIGl0cyBpbnRlbmRlZCBwdXJwb3NlLCBhbmQgc2hhbGwgbm90IGR1cGxpY2F0ZSwKICogZGlzY2xvc2UsIG9yIGRpc3NlbWluYXRlIGFueSBvZiB0aGlzIGluZm9ybWF0aW9uIGluIGFueSBtYW5uZXIKICogdW5sZXNzIFN5bmFwdGljcyBoYXMgb3RoZXJ3aXNlIHByb3ZpZGVkIGV4cHJlc3MsIHdyaXR0ZW4KICogcGVybWlzc2lvbi4KICoKICogVXNlIG9mIHRoZSBtYXRlcmlhbHMgbWF5IHJlcXVpcmUgYSBsaWNlbnNlIG9mIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiBmcm9tIGEgdGhpcmQgcGFydHkgb3IgZnJvbSBTeW5hcHRpY3MuIFRoaXMgZmlsZSBjb252ZXlzIG5vIGV4cHJlc3MKICogb3IgaW1wbGllZCBsaWNlbnNlcyB0byBhbnkgaW50ZWxsZWN0dWFsIHByb3BlcnR5IHJpZ2h0cyBiZWxvbmdpbmcKICogdG8gU3luYXB0aWNzLgogKgogKiBJTkZPUk1BVElPTiBDT05UQUlORUQgSU4gVEhJUyBET0NVTUVOVCBJUyBQUk9WSURFRCAiQVMtSVMsIiBBTkQKICogU1lOQVBUSUNTIEVYUFJFU1NMWSBESVNDTEFJTVMgQUxMIEVYUFJFU1MgQU5EIElNUExJRUQgV0FSUkFOVElFUywKICogSU5DTFVESU5HIEFOWSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgogKiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSwgQU5EIEFOWSBXQVJSQU5USUVTIE9GIE5PTi1JTkZSSU5HRU1FTlQgT0YgQU5ZCiAqIElOVEVMTEVDVFVBTCBQUk9QRVJUWSBSSUdIVFMuIElOIE5PIEVWRU5UIFNIQUxMIFNZTkFQVElDUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBQVU5JVElWRSwgT1IKICogQ09OU0VRVUVOVElBTCBEQU1BR0VTIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFCiAqIE9GIFRIRSBJTkZPUk1BVElPTiBDT05UQUlORUQgSU4gVEhJUyBET0NVTUVOVCwgSE9XRVZFUiBDQVVTRUQgQU5ECiAqIEJBU0VEIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwKICogTkVHTElHRU5DRSBPUiBPVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFORCBFVkVOIElGIFNZTkFQVElDUyBXQVMKICogQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuIElGIEEgVFJJQlVOQUwgT0YKICogQ09NUEVURU5UIEpVUklTRElDVElPTiBET0VTIE5PVCBQRVJNSVQgVEhFIERJU0NMQUlNRVIgT0YgRElSRUNUCiAqIERBTUFHRVMgT1IgQU5ZIE9USEVSIERBTUFHRVMsIFNZTkFQVElDUycgVE9UQUwgQ1VNVUxBVElWRSBMSUFCSUxJVFkKICogVE8gQU5ZIFBBUlRZIFNIQUxMIE5PVCBFWENFRUQgT05FIEhVTkRSRUQgVS5TLiBET0xMQVJTLgogKi8KI2luY2x1ZGUgPGlvLmg+CiNpbmNsdWRlICJ1dGlsLmgiCiNpbmNsdWRlICJkZWJ1Zy5oIgojaW5jbHVkZSAiY2hpcF92b2x0YWdlX2luZm8uaCIKI2luY2x1ZGUgInBtaWNfc2VsZWN0LmgiCgojaW5jbHVkZSAibGdwbF9wcmludGYuaCIKI2luY2x1ZGUgInB2X2NvbXAuaCIKCiNkZWZpbmUgVU5VU0VEKHZhcikgZG8geyAodm9pZCkodmFyKTsgfSB3aGlsZSgwKQoKY29uc3QgZHZmc19vcHNfdCAqIGR2ZnNfb3BzID0gTlVMTDsKCnN0YXRpYyBpbnQgZmluZF9kdmZzX2dyb3VwKHN0cnVjdCBmcmVxX2xlYWthZ2VfdGFibGUgKmZsdCwgaW50IHBsbCwgaW50IGxlYWthZ2UpCnsKCXN0cnVjdCBsZWFrYWdlX3RhYmxlICpwID0gTlVMTDsKCgl3aGlsZShmbHQtPmZyZXEgIT0gMCkgewoJCWlmKGZsdC0+ZnJlcSA+PSBwbGwpIHsKCQkJcCA9IGZsdC0+bHQ7CgkJCWlmKHAgPT0gTlVMTCkgewoJCQkJYnJlYWs7CgkJCX0KCQkJd2hpbGUoMSkgewoJCQkJaWYobGVha2FnZSA8PSBwLT5pbmZvKQoJCQkJCWJyZWFrOwoJCQkJcCsrOwoJCQl9CgkJCXJldHVybiBwLT52b2x0OwoJCX0KCQlmbHQrKzsKCX0KCglyZXR1cm4gLTE7Cn0KCgpzdGF0aWMgaW50IGdldF92Y3B1X3ZvbHRfZnJvbV9kdmZzKGludCBjcHVfcGxsLCBpbnQgbGVha2FnZSkKewoJc3RydWN0IGZyZXFfbGVha2FnZV90YWJsZSAqZmx0ID0gZ2V0X3ZjcHVfbGVha2FnZV90YWJsZSgpOwoJaW50IHJldCA9IDA7CgoJaWYoZmx0ID09IE5VTEwpIHsKCQlsZ3BsX3ByaW50ZigiTm8gdmNwdSBQViB0YWJsZSBmb3VuZCEhISFcbiIpOwoJCXJldHVybiAtMTsKCX0KCglyZXQgPSBmaW5kX2R2ZnNfZ3JvdXAoZmx0LCBjcHVfcGxsLCBsZWFrYWdlKTsKCglpZihyZXQgPT0gLTEpCgkJbGdwbF9wcmludGYoIk5vIGxlYWthZ2UgZ3JvdXAgaW4gdmNwdSBQViB0YWJsZSBmb3VuZCEhISFcbiIpOwoKCXJldHVybiByZXQ7Cn0KCiNpZmRlZiBDT1JFX1ZPTFRfVkFMVUUKaW50IGdldF92Y29yZV92b2x0X2Zyb21fZHZmcyhpbnQgZ3B1X3BsbCwgaW50IGxlYWthZ2UpCnsKCXN0cnVjdCBmcmVxX2xlYWthZ2VfdGFibGUgKmZsdCA9IGdldF92Y29yZV9sZWFrYWdlX3RhYmxlKCk7CglpbnQgcmV0ID0gMDsKCglpZihmbHQgPT0gTlVMTCkgewoJCWxncGxfcHJpbnRmKCJObyB2Y29yZSBQViB0YWJsZSBmb3VuZCEhISFcbiIpOwoJCXJldHVybiAtMTsKCX0KCglyZXQgPSBmaW5kX2R2ZnNfZ3JvdXAoZmx0LCBncHVfcGxsLCBsZWFrYWdlKTsKCglpZihyZXQgPT0gLTEpCgkJbGdwbF9wcmludGYoIk5vIGxlYWthZ2UgZ3JvdXAgaW4gdmNvcmUgUFYgdGFibGUgZm91bmQhISEhXG4iKTsKCglyZXR1cm4gcmV0Owp9CiNlbmRpZgoKdm9pZCBnZXRfdmNwdV92aF92bCh1bnNpZ25lZCBpbnQgKm9wcCkKewoJaW50IGxlYWthZ2UgPSAwOwoJaW50IHZvbHQgPSAwOwoJdW5zaWduZWQgaW50IGNvdW50ID0gMDsKCXN0cnVjdCBmcmVxX2xlYWthZ2VfdGFibGUgKmZsdCA9IE5VTEw7CgoJbGVha2FnZSA9IGdldF9sZWFrYWdlX2luZm8oKTsKCWZsdCA9IGdldF92Y3B1X2xlYWthZ2VfdGFibGUoKTsKCglpZihmbHQgPT0gTlVMTCkgewoJCWxncGxfcHJpbnRmKCJObyB2Y3B1IFBWIHRhYmxlIGZvdW5kISEhIVxuIik7CgkJZ290byBlcnJvcjsKCX0KCgkvL3ZsCglpZihmbHQtPmZyZXEgIT0gMCkgewoJCXZvbHQgPSBnZXRfdmNwdV92b2x0X2Zyb21fZHZmcyhmbHQtPmZyZXEsIGxlYWthZ2UpOwoJCWlmKHZvbHQgPiAwKSB7CgkJCW9wcFtjb3VudCsrXSA9IHZvbHQgKiAxMDAwOwoJCQlsZ3BsX3ByaW50ZigidmwgPSAlZFxuIiwgKHZvbHQgKiAxMDAwKSk7CgkJfQoJCWZsdCsrOwoKCQkvL3ZoCgkJaWYoZmx0LT5mcmVxICE9IDApIHsKCQkJdm9sdCA9IGdldF92Y3B1X3ZvbHRfZnJvbV9kdmZzKGZsdC0+ZnJlcSwgbGVha2FnZSk7CgkJCWlmKHZvbHQgPiAwKSB7CgkJCQlvcHBbY291bnQrK10gPSB2b2x0ICogMTAwMDsKCQkJCWxncGxfcHJpbnRmKCJ2aCA9ICVkXG4iLCAodm9sdCAqIDEwMDApKTsKCQkJfQoJCX0KCX0KCglpZihjb3VudCA+IDEpIHsKCQlsZ3BsX3ByaW50ZigiR290ICVkIHZhbHVlIGZvciB2Y3B1IHZsIGFuZCB2aFxuIiwgY291bnQpOwoJCXJldHVybjsKCX0KCmVycm9yOgoJbGdwbF9wcmludGYoIiMjIyMjIyB3cm9uZyB2YWx1ZSBmb3IgdmNwdSB2bCBhbmQgdmghISEhISEhIVxuIik7CglyZXR1cm47Cn0KCiNpZmRlZiBDT1JFX1ZPTFRfVkFMVUUKdm9pZCBnZXRfdmNvcmVfdmhfdmwodW5zaWduZWQgaW50ICpvcHApCnsKCWludCBsZWFrYWdlID0gMDsKCWludCB2b2x0ID0gMDsKCXVuc2lnbmVkIGludCBjb3VudCA9IDA7CglzdHJ1Y3QgZnJlcV9sZWFrYWdlX3RhYmxlICpmbHQgPSBOVUxMOwoKCWxlYWthZ2UgPSBnZXRfbGVha2FnZV9pbmZvKCk7CglmbHQgPSBnZXRfdmNvcmVfbGVha2FnZV90YWJsZSgpOwoKCWlmKE5VTEwgPT0gZmx0KSB7CgkJbGdwbF9wcmludGYoIk5vIHZjb3JlIFBWIHRhYmxlIGZvdW5kISEhIVxuIik7CgkJZ290byBlcnJvcjsKCX0KCgkvL3ZsCglpZigwICE9IGZsdC0+ZnJlcSkgewoJCXZvbHQgPSBnZXRfdmNvcmVfdm9sdF9mcm9tX2R2ZnMoZmx0LT5mcmVxLCBsZWFrYWdlKTsKCQlpZih2b2x0ID4gMCkgewoJCQlvcHBbY291bnQrK10gPSB2b2x0ICogMTAwMDsKCQkJbGdwbF9wcmludGYoInZjb3JlIHZsID0gJWRcbiIsICh2b2x0ICogMTAwMCkpOwoJCX0KCQlmbHQrKzsKCgkJLy92aAoJCWlmKDAgIT0gZmx0LT5mcmVxKSB7CgkJCXZvbHQgPSBnZXRfdmNvcmVfdm9sdF9mcm9tX2R2ZnMoZmx0LT5mcmVxLCBsZWFrYWdlKTsKCQkJaWYodm9sdCA+IDApIHsKCQkJCW9wcFtjb3VudCsrXSA9IHZvbHQgKiAxMDAwOwoJCQkJbGdwbF9wcmludGYoInZjb3JlIHZoID0gJWRcbiIsICh2b2x0ICogMTAwMCkpOwoJCQl9CgkJfQoJfQoKCWlmKGNvdW50ID4gMSkgewoJCWxncGxfcHJpbnRmKCJHb3QgJWQgdmFsdWUgZm9yIHZjb3JlIHZsIGFuZCB2aFxuIiwgY291bnQpOwoJCXJldHVybjsKCX0KCmVycm9yOgoJbGdwbF9wcmludGYoIiMjIyMjIyB3cm9uZyB2YWx1ZSBmb3IgdmNvcmUgdmwgYW5kIHZoISEhISEhISFcbiIpOwoJcmV0dXJuOwp9CiNlbmRpZgoKZXh0ZXJuIGNvbnN0IGR2ZnNfb3BzX3QgbTg4cGc4Nnhfb3BzOwpleHRlcm4gY29uc3QgZHZmc19vcHNfdCBzeTg4MjRiX29wczsKZXh0ZXJuIGNvbnN0IGR2ZnNfb3BzX3QgbmNwNjMzNWRfb3BzOwpleHRlcm4gY29uc3QgZHZmc19vcHNfdCBzeTIwMjc2X29wczsKZXh0ZXJuIGNvbnN0IGR2ZnNfb3BzX3Qgc3kyMDI3OF9vcHM7Cgp2b2lkIHB2X2NvbXAoaW50IGNwdV9wbGwsIGludCBncHVfcGxsKQp7CglpbnQgbGVha2FnZV9pbmZvID0gMDsKICAgIGludCB2b2x0ID0gMCwgZmluYWxfdm9sdCA9IDAsIGRlZmF1bHRfY3B1X3ZvbHQgPSAwOzsKICAgIGludCByZXQgPSAwOwoJdW5zaWduZWQgaW50IHBtaWNfaWQgPSBnZXRfcG1pY19pZCgpOwoKCWlmKE04OFBHODZYID09IHBtaWNfaWQpIHsKCQlsZ3BsX3ByaW50ZigiUE1JQzogTWFydmVsbCA4OFBHODZYIHNlbGVjdGVkIVxuIik7CgkJZHZmc19vcHMgPSAmbTg4cGc4Nnhfb3BzOwoJfQoJZWxzZSBpZihTWTg4MjRCID09IHBtaWNfaWQpIHsKCQlsZ3BsX3ByaW50ZigiUE1JQzogU1k4ODI0QiBzZWxlY3RlZCFcbiIpOwoJCWR2ZnNfb3BzID0gJnN5ODgyNGJfb3BzOwoJfQoJZWxzZSBpZihTWTIwMjc2ID09IHBtaWNfaWQpIHsKCQlsZ3BsX3ByaW50ZigiUE1JQzogU1kyMDI3NiBpcyBzZWxlY3RlZCFcbiIpOwoJCWR2ZnNfb3BzID0gJnN5MjAyNzZfb3BzOwoJfQoJZWxzZSBpZihTWTIwMjc4ID09IHBtaWNfaWQpIHsKCQlsZ3BsX3ByaW50ZigiUE1JQzogU1kyMDI3OCBpcyBzZWxlY3RlZCFcbiIpOwoJCWR2ZnNfb3BzID0gJnN5MjAyNzhfb3BzOwoJfQoJZWxzZSBpZihOQ1A2MzM1RCA9PSBwbWljX2lkKSB7CgkJbGdwbF9wcmludGYoIlBNSUM6IE5DUDYzMzVEIHNlbGVjdGVkIVxuIik7CgkJZHZmc19vcHMgPSAmbmNwNjMzNWRfb3BzOwoJfQoKCWlmKE5VTEwgPT0gZHZmc19vcHMpCgkJbGdwbF9wcmludGYoIldBUk46IHVuc3VwcG9ydGVkIFBNSUMgZm9yIHB2X2NvbXAhXG4iKTsKCglsZWFrYWdlX2luZm8gPSBnZXRfbGVha2FnZV9pbmZvKCk7CgoJaWYoIWxlYWthZ2VfaW5mbykgewoJCWxncGxfcHJpbnRmKCJsZWFrYWdlIGlzIG5vdCBwcmVzZW50ISEhIVxuIik7CgkJcmV0dXJuOwoJfQoJbGdwbF9wcmludGYoImxlYWthZ2UgaW5mbyAlZC5cbiIsIGxlYWthZ2VfaW5mbyk7CgoJLy8gc3RhcnQgdG8gc2V0IHZjcHUKCXZvbHQgPSBnZXRfdmNwdV92b2x0X2Zyb21fZHZmcyhjcHVfcGxsLCBsZWFrYWdlX2luZm8pOwogICAgaWYodm9sdCAhPSAtMSkKICAgICAgICAgICAgZmluYWxfdm9sdCA9IHZvbHQgKiAxMDAwOyAvL2NoYW5nZSB0byB1diB0byBoYW5kbGUgMTIuNW12IGNhc2UKICAgIGVsc2UgewoJCWxncGxfcHJpbnRmKCJGYWlsZWQgdG8gcGFyc2UgdmFsaWQgdmNwdSBmcm9tIG9wcCB0YWJsZSAhXG4iKTsKI2lmZGVmIENPUkVfVk9MVF9WQUxVRQoJCWdvdG8gc2V0X3Zjb3JlOwojZWxzZQoJCVVOVVNFRChncHVfcGxsKTsKCQlyZXR1cm4gOwojZW5kaWYKCX0KCglkZWZhdWx0X2NwdV92b2x0ID0gZHZmc19vcHMtPmdldF92Y3B1X3ZvbHQoKTsKCWlmKGRlZmF1bHRfY3B1X3ZvbHQgPCAwKSB7CgkJbGdwbF9wcmludGYoIkZhaWxlZCB0byBnZXQgY3VycmVudCBWY3B1ISBcbiIpOwoJCXJldHVybiA7Cgl9CgoJdm9sdCA9IGRlZmF1bHRfY3B1X3ZvbHQ7CglpZih2b2x0ID09IGZpbmFsX3ZvbHQpIHsKCQlsZ3BsX3ByaW50ZigiVmNwdSBpcyAlZHVWLCBkZWZhdWx0IHNldHRpbmcgYnkgaGFyZHdhcmUuIFxuIix2b2x0KTsKCX0gZWxzZSB7CgkJcmV0ID0gZHZmc19vcHMtPnNldF92Y3B1X3ZvbHQoZGVmYXVsdF9jcHVfdm9sdCwgZmluYWxfdm9sdCk7CgkJaWYocmV0KQoJCQlsZ3BsX3ByaW50ZigiRmFpbGVkIHRvIHNldCBWY3B1IGZyb20gJWR1diB0byAlZHV2XG4iLCBkZWZhdWx0X2NwdV92b2x0LCBmaW5hbF92b2x0KTsKCQllbHNlCgkJCWxncGxfcHJpbnRmKCJzZXQgVmNwdSBmcm9tICVkdXYgdG8gJWR1dlxuIiwgZGVmYXVsdF9jcHVfdm9sdCwgZmluYWxfdm9sdCk7Cgl9CgojaWZkZWYgQ09SRV9WT0xUX1ZBTFVFCnNldF92Y29yZToKCXsKCWludCBkZWZhdWx0X2NvcmVfdm9sdCA9IDA7CgoJLy8gc3RhcnQgdG8gc2V0IHZjb3JlIGlmIGhhcwoJdm9sdCA9IGdldF92Y29yZV92b2x0X2Zyb21fZHZmcyhncHVfcGxsLCBsZWFrYWdlX2luZm8pOwoJaWYodm9sdCAhPSAtMSkKCQlmaW5hbF92b2x0ID0gdm9sdCAqIDEwMDA7IC8vY2hhbmdlIHRvIHV2IHRvIGhhbmRsZSAxMi41bXYgY2FzZQoJZWxzZSB7CgkJbGdwbF9wcmludGYoIkZhaWxlZCB0byBwYXJzZSB2YWxpZCB2Y29yZSBmcm9tIG9wcCB0YWJsZSAhXG4iKTsKCQlyZXR1cm47Cgl9CgoJZGVmYXVsdF9jb3JlX3ZvbHQgPSBkdmZzX29wcy0+Z2V0X3Zjb3JlX3ZvbHQoKTsKCWlmKGRlZmF1bHRfY29yZV92b2x0IDwgMCkgewoJCWxncGxfcHJpbnRmKCJGYWlsZWQgdG8gZ2V0IGN1cnJlbnQgVmNvcmUhIFxuIik7CgkJcmV0dXJuOwoJfQoJdm9sdCA9IGRlZmF1bHRfY29yZV92b2x0OwoJaWYodm9sdCA9PSBmaW5hbF92b2x0KSB7CgkJbGdwbF9wcmludGYoIlZjb3JlIGlzICVkdVYsIGRlZmF1bHQgc2V0dGluZyBieSBoYXJkd2FyZS4gXG4iLHZvbHQpOwoJfSBlbHNlIHsKCQlyZXQgPSBkdmZzX29wcy0+c2V0X3Zjb3JlX3ZvbHQoZmluYWxfdm9sdCwgZGVmYXVsdF9jb3JlX3ZvbHQpOwoJCWlmKHJldCkgewoJCQlsZ3BsX3ByaW50ZigiRmFpbGVkIHRvIHNldCBWY29yZSBmcm9tICVkdXYgdG8gJWR1dlxuIiwgZGVmYXVsdF9jb3JlX3ZvbHQsIGZpbmFsX3ZvbHQpOwoJCX0gZWxzZSB7CgkJCWxncGxfcHJpbnRmKCJzZXQgVmNvcmUgZnJvbSAlZHV2IHRvICVkdXZcbiIsIGRlZmF1bHRfY3B1X3ZvbHQsIGZpbmFsX3ZvbHQpOwoJCX0KCX0KCX0KI2VuZGlmCglyZXR1cm4gOwp9Cg==