LyoKICogZmF0LmMKICoKICogUi9PIChWKUZBVCAxMi8xNi8zMiBmaWxlc3lzdGVtIGltcGxlbWVudGF0aW9uIGJ5IE1hcmN1cyBTdW5kYmVyZwogKgogKiAyMDAyLTA3LTI4IC0gcmpvbmVzQG5leHVzLXRlY2gubmV0IC0gcG9ydGVkIHRvIHBwY2Jvb3QgdjEuMS42CiAqIDIwMDMtMDMtMTAgLSBraGFycmlzQG5leHVzLXRlY2gubmV0IC0gcG9ydGVkIHRvIHVib290CiAqCiAqIFNlZSBmaWxlIENSRURJVFMgZm9yIGxpc3Qgb2YgcGVvcGxlIHdobyBjb250cmlidXRlZCB0byB0aGlzCiAqIHByb2plY3QuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YKICogdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sCiAqIE1BIDAyMTExLTEzMDcgVVNBCiAqLwoKI2luY2x1ZGUgPGNvbW1vbi5oPgojaW5jbHVkZSA8Y29uZmlnLmg+CiNpbmNsdWRlIDxmYXQuaD4KI2luY2x1ZGUgPGFzbS9ieXRlb3JkZXIuaD4KI2luY2x1ZGUgPHBhcnQuaD4KCiNpZiAoQ09ORklHX0NPTU1BTkRTICYgQ0ZHX0NNRF9GQVQpCgovKgogKiBDb252ZXJ0IGEgc3RyaW5nIHRvIGxvd2VyY2FzZS4KICovCnN0YXRpYyB2b2lkCmRvd25jYXNlKGNoYXIgKnN0cikKewoJd2hpbGUgKCpzdHIgIT0gJ1wwJykgewoJCVRPTE9XRVIoKnN0cik7CgkJc3RyKys7Cgl9Cn0KCnN0YXRpYyAgYmxvY2tfZGV2X2Rlc2NfdCAqY3VyX2RldiA9IE5VTEw7CnN0YXRpYyB1bnNpZ25lZCBsb25nIHBhcnRfb2Zmc2V0ID0gMDsKc3RhdGljIGludCBjdXJfcGFydCA9IDE7CgojZGVmaW5lIERPU19QQVJUX1RCTF9PRkZTRVQJMHgxYmUKI2RlZmluZSBET1NfUEFSVF9NQUdJQ19PRkZTRVQJMHgxZmUKI2RlZmluZSBET1NfRlNfVFlQRV9PRkZTRVQJMHgzNgoKaW50IGRpc2tfcmVhZCAoX191MzIgc3RhcnRibG9jaywgX191MzIgZ2V0c2l6ZSwgX191OCAqIGJ1ZnB0cikKewoJc3RhcnRibG9jayArPSBwYXJ0X29mZnNldDsKCWlmIChjdXJfZGV2ID09IE5VTEwpCgkJcmV0dXJuIC0xOwoJaWYgKGN1cl9kZXYtPmJsb2NrX3JlYWQpIHsKCQlyZXR1cm4gY3VyX2Rldi0+YmxvY2tfcmVhZCAoY3VyX2Rldi0+ZGV2LCBzdGFydGJsb2NrLCBnZXRzaXplLCAodW5zaWduZWQgbG9uZyAqKWJ1ZnB0cik7Cgl9CglyZXR1cm4gLTE7Cn0KCgppbnQKZmF0X3JlZ2lzdGVyX2RldmljZShibG9ja19kZXZfZGVzY190ICpkZXZfZGVzYywgaW50IHBhcnRfbm8pCnsKCXVuc2lnbmVkIGNoYXIgYnVmZmVyW1NFQ1RPUl9TSVpFXTsKCglpZiAoIWRldl9kZXNjLT5ibG9ja19yZWFkKQoJCXJldHVybiAtMTsKCWN1cl9kZXY9ZGV2X2Rlc2M7CgkvKiBjaGVjayBpZiB3ZSBoYXZlIGEgTUJSIChvbiBmbG9wcGllcyB3ZSBoYXZlIG9ubHkgYSBQQlIpICovCglpZiAoZGV2X2Rlc2MtPmJsb2NrX3JlYWQgKGRldl9kZXNjLT5kZXYsIDAsIDEsICh1bG9uZyAqKSBidWZmZXIpICE9IDEpIHsKCQlwcmludGYgKCIqKiBDYW4ndCByZWFkIGZyb20gZGV2aWNlICVkICoqXG4iLCBkZXZfZGVzYy0+ZGV2KTsKCQlyZXR1cm4gLTE7Cgl9CglpZiAoYnVmZmVyW0RPU19QQVJUX01BR0lDX09GRlNFVF0gIT0gMHg1NSB8fAoJCWJ1ZmZlcltET1NfUEFSVF9NQUdJQ19PRkZTRVQgKyAxXSAhPSAweGFhKSB7CgkJLyogbm8gc2lnbmF0dXJlIGZvdW5kICovCgkJcmV0dXJuIC0xOwoJfQoJaWYoIXN0cm5jbXAoJmJ1ZmZlcltET1NfRlNfVFlQRV9PRkZTRVRdLCJGQVQiLDMpKSB7CgkJLyogb2ssIHdlIGFzc3VtZSB3ZSBhcmUgb24gYSBQQlIgb25seSAqLwoJCWN1cl9wYXJ0ID0gMTsKCQlwYXJ0X29mZnNldD0wOwoJfQoJZWxzZSB7CiNpZiAoQ09ORklHX0NPTU1BTkRTICYgQ0ZHX0NNRF9JREUpIHx8IChDT05GSUdfQ09NTUFORFMgJiBDRkdfQ01EX1NDU0kpIHx8IFwKICAgIChDT05GSUdfQ09NTUFORFMgJiBDRkdfQ01EX1VTQikgfHwgZGVmaW5lZChDT05GSUdfU1lTVEVNQUNFKQoJCWRpc2tfcGFydGl0aW9uX3QgaW5mbzsKCQlpZighZ2V0X3BhcnRpdGlvbl9pbmZvKGRldl9kZXNjLCBwYXJ0X25vLCAmaW5mbykpIHsKCQkJcGFydF9vZmZzZXQgPSBpbmZvLnN0YXJ0OwoJCQljdXJfcGFydCA9IHBhcnRfbm87CgkJfQoJCWVsc2UgewoJCQlwcmludGYgKCIqKiBQYXJ0aXRpb24gJWQgbm90IHZhbGlkIG9uIGRldmljZSAlZCAqKlxuIixwYXJ0X25vLGRldl9kZXNjLT5kZXYpOwoJCQlyZXR1cm4gLTE7CgkJfQojZWxzZQoJCS8qIEZJWE1FIHdlIG5lZWQgdG8gZGV0ZXJtaW5lIHRoZSBzdGFydCBibG9jayBvZiB0aGUKCQkgKiBwYXJ0aXRpb24gd2hlcmUgdGhlIERPUyBGUyByZXNpZGVzLiBUaGlzIGNhbiBiZSBkb25lCgkJICogYnkgdXNpbmcgdGhlIGdldF9wYXJ0aXRpb25faW5mbyByb3V0aW5lLiBGb3IgdGhpcwoJCSAqIHB1cnBvc2UgdGhlIGxpYnBhcnQgbXVzdCBiZSBpbmNsdWRlZC4KCQkgKi8KCQlwYXJ0X29mZnNldD0zMjsKCQljdXJfcGFydCA9IDE7CiNlbmRpZgoJfQoJcmV0dXJuIDA7Cn0KCgovKgogKiBHZXQgdGhlIGZpcnN0IG9jY3VyZW5jZSBvZiBhIGRpcmVjdG9yeSBkZWxpbWl0ZXIgKCcvJyBvciAnXCcpIGluIGEgc3RyaW5nLgogKiBSZXR1cm4gaW5kZXggaW50byBzdHJpbmcgaWYgZm91bmQsIC0xIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKZGlyZGVsaW0oY2hhciAqc3RyKQp7CgljaGFyICpzdGFydCA9IHN0cjsKCgl3aGlsZSAoKnN0ciAhPSAnXDAnKSB7CgkJaWYgKElTRElSREVMSU0oKnN0cikpIHJldHVybiBzdHIgLSBzdGFydDsKCQlzdHIrKzsKCX0KCXJldHVybiAtMTsKfQoKCi8qCiAqIE1hdGNoIHZvbHVtZV9pbmZvIGZzX3R5cGUgc3RyaW5ncy4KICogUmV0dXJuIDAgb24gbWF0Y2gsIC0xIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKY29tcGFyZV9zaWduKGNoYXIgKnN0cjEsIGNoYXIgKnN0cjIpCnsKCWNoYXIgKmVuZCA9IHN0cjErU0lHTkxFTjsKCgl3aGlsZSAoc3RyMSAhPSBlbmQpIHsKCQlpZiAoKnN0cjEgIT0gKnN0cjIpIHsKCQkJcmV0dXJuIC0xOwoJCX0KCQlzdHIxKys7CgkJc3RyMisrOwoJfQoKCXJldHVybiAwOwp9CgoKLyoKICogRXh0cmFjdCB6ZXJvIHRlcm1pbmF0ZWQgc2hvcnQgbmFtZSBmcm9tIGEgZGlyZWN0b3J5IGVudHJ5LgogKi8Kc3RhdGljIHZvaWQgZ2V0X25hbWUgKGRpcl9lbnRyeSAqZGlyZW50LCBjaGFyICpzX25hbWUpCnsKCWNoYXIgKnB0cjsKCgltZW1jcHkgKHNfbmFtZSwgZGlyZW50LT5uYW1lLCA4KTsKCXNfbmFtZVs4XSA9ICdcMCc7CglwdHIgPSBzX25hbWU7Cgl3aGlsZSAoKnB0ciAmJiAqcHRyICE9ICcgJykKCQlwdHIrKzsKCWlmIChkaXJlbnQtPmV4dFswXSAmJiBkaXJlbnQtPmV4dFswXSAhPSAnICcpIHsKCQkqcHRyID0gJy4nOwoJCXB0cisrOwoJCW1lbWNweSAocHRyLCBkaXJlbnQtPmV4dCwgMyk7CgkJcHRyWzNdID0gJ1wwJzsKCQl3aGlsZSAoKnB0ciAmJiAqcHRyICE9ICcgJykKCQkJcHRyKys7Cgl9CgkqcHRyID0gJ1wwJzsKCWlmICgqc19uYW1lID09IERFTEVURURfRkxBRykKCQkqc19uYW1lID0gJ1wwJzsKCWVsc2UgaWYgKCpzX25hbWUgPT0gYVJJTkcpCgkJKnNfbmFtZSA9ICflJzsKCWRvd25jYXNlIChzX25hbWUpOwp9CgovKgogKiBHZXQgdGhlIGVudHJ5IGF0IGluZGV4ICdlbnRyeScgaW4gYSBGQVQgKDEyLzE2LzMyKSB0YWJsZS4KICogT24gZmFpbHVyZSAweDAwIGlzIHJldHVybmVkLgogKi8Kc3RhdGljIF9fdTMyCmdldF9mYXRlbnQoZnNkYXRhICpteWRhdGEsIF9fdTMyIGVudHJ5KQp7CglfX3UzMiBidWZudW07CglfX3UzMiBvZmZzZXQ7CglfX3UzMiByZXQgPSAweDAwOwoKCXN3aXRjaCAobXlkYXRhLT5mYXRzaXplKSB7CgljYXNlIDMyOgoJCWJ1Zm51bSA9IGVudHJ5IC8gRkFUMzJCVUZTSVpFOwoJCW9mZnNldCA9IGVudHJ5IC0gYnVmbnVtICogRkFUMzJCVUZTSVpFOwoJCWJyZWFrOwoJY2FzZSAxNjoKCQlidWZudW0gPSBlbnRyeSAvIEZBVDE2QlVGU0laRTsKCQlvZmZzZXQgPSBlbnRyeSAtIGJ1Zm51bSAqIEZBVDE2QlVGU0laRTsKCQlicmVhazsKCWNhc2UgMTI6CgkJYnVmbnVtID0gZW50cnkgLyBGQVQxMkJVRlNJWkU7CgkJb2Zmc2V0ID0gZW50cnkgLSBidWZudW0gKiBGQVQxMkJVRlNJWkU7CgkJYnJlYWs7CgoJZGVmYXVsdDoKCQkvKiBVbnN1cHBvcnRlZCBGQVQgc2l6ZSAqLwoJCXJldHVybiByZXQ7Cgl9CgoJLyogUmVhZCBhIG5ldyBibG9jayBvZiBGQVQgZW50cmllcyBpbnRvIHRoZSBjYWNoZS4gKi8KCWlmIChidWZudW0gIT0gbXlkYXRhLT5mYXRidWZudW0pIHsKCQlpbnQgZ2V0c2l6ZSA9IEZBVEJVRlNJWkUvRlNfQkxPQ0tfU0laRTsKCQlfX3U4ICpidWZwdHIgPSBteWRhdGEtPmZhdGJ1ZjsKCQlfX3UzMiBmYXRsZW5ndGggPSBteWRhdGEtPmZhdGxlbmd0aDsKCQlfX3UzMiBzdGFydGJsb2NrID0gYnVmbnVtICogRkFUQlVGQkxPQ0tTOwoKCQlmYXRsZW5ndGggKj0gU0VDVE9SX1NJWkU7CS8qIFdlIHdhbnQgaXQgaW4gYnl0ZXMgbm93ICovCgkJc3RhcnRibG9jayArPSBteWRhdGEtPmZhdF9zZWN0OwkvKiBPZmZzZXQgZnJvbSBzdGFydCBvZiBkaXNrICovCgoJCWlmIChnZXRzaXplID4gZmF0bGVuZ3RoKSBnZXRzaXplID0gZmF0bGVuZ3RoOwoJCWlmIChkaXNrX3JlYWQoc3RhcnRibG9jaywgZ2V0c2l6ZSwgYnVmcHRyKSA8IDApIHsKCQkJRkFUX0RQUklOVCgiRXJyb3IgcmVhZGluZyBGQVQgYmxvY2tzXG4iKTsKCQkJcmV0dXJuIHJldDsKCQl9CgkJbXlkYXRhLT5mYXRidWZudW0gPSBidWZudW07Cgl9CgoJLyogR2V0IHRoZSBhY3R1YWwgZW50cnkgZnJvbSB0aGUgdGFibGUgKi8KCXN3aXRjaCAobXlkYXRhLT5mYXRzaXplKSB7CgljYXNlIDMyOgoJCXJldCA9IEZBVDJDUFUzMigoKF9fdTMyKilteWRhdGEtPmZhdGJ1Zilbb2Zmc2V0XSk7CgkJYnJlYWs7CgljYXNlIDE2OgoJCXJldCA9IEZBVDJDUFUxNigoKF9fdTE2KilteWRhdGEtPmZhdGJ1Zilbb2Zmc2V0XSk7CgkJYnJlYWs7CgljYXNlIDEyOiB7CgkJX191MzIgb2ZmMTYgPSAob2Zmc2V0KjMpLzQ7CgkJX191MTYgdmFsMSwgdmFsMjsKCgkJc3dpdGNoIChvZmZzZXQgJiAweDMpIHsKCQljYXNlIDA6CgkJCXJldCA9IEZBVDJDUFUxNigoKF9fdTE2KilteWRhdGEtPmZhdGJ1Zilbb2ZmMTZdKTsKCQkJcmV0ICY9IDB4ZmZmOwoJCQlicmVhazsKCQljYXNlIDE6CgkJCXZhbDEgPSBGQVQyQ1BVMTYoKChfX3UxNiopbXlkYXRhLT5mYXRidWYpW29mZjE2XSk7CgkJCXZhbDEgJj0gMHhmMDAwOwoJCQl2YWwyID0gRkFUMkNQVTE2KCgoX191MTYqKW15ZGF0YS0+ZmF0YnVmKVtvZmYxNisxXSk7CgkJCXZhbDIgJj0gMHgwMGZmOwoJCQlyZXQgPSAodmFsMiA8PCA0KSB8ICh2YWwxID4+IDEyKTsKCQkJYnJlYWs7CgkJY2FzZSAyOgoJCQl2YWwxID0gRkFUMkNQVTE2KCgoX191MTYqKW15ZGF0YS0+ZmF0YnVmKVtvZmYxNl0pOwoJCQl2YWwxICY9IDB4ZmYwMDsKCQkJdmFsMiA9IEZBVDJDUFUxNigoKF9fdTE2KilteWRhdGEtPmZhdGJ1Zilbb2ZmMTYrMV0pOwoJCQl2YWwyICY9IDB4MDAwZjsKCQkJcmV0ID0gKHZhbDIgPDwgOCkgfCAodmFsMSA+PiA4KTsKCQkJYnJlYWs7CgkJY2FzZSAzOgoJCQlyZXQgPSBGQVQyQ1BVMTYoKChfX3UxNiopbXlkYXRhLT5mYXRidWYpW29mZjE2XSk7OwoJCQlyZXQgPSAocmV0ICYgMHhmZmYwKSA+PiA0OwoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQlicmVhazsKCQl9Cgl9CglicmVhazsKCX0KCUZBVF9EUFJJTlQoInJldDogJWQsIG9mZnNldDogJWRcbiIsIHJldCwgb2Zmc2V0KTsKCglyZXR1cm4gcmV0Owp9CgoKLyoKICogUmVhZCBhdCBtb3N0ICdzaXplJyBieXRlcyBmcm9tIHRoZSBzcGVjaWZpZWQgY2x1c3RlciBpbnRvICdidWZmZXInLgogKiBSZXR1cm4gMCBvbiBzdWNjZXNzLCAtMSBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CmdldF9jbHVzdGVyKGZzZGF0YSAqbXlkYXRhLCBfX3UzMiBjbHVzdG51bSwgX191OCAqYnVmZmVyLCB1bnNpZ25lZCBsb25nIHNpemUpCnsKCWludCBpZHggPSAwOwoJX191MzIgc3RhcnRzZWN0OwoKCWlmIChjbHVzdG51bSA+IDApIHsKCQlzdGFydHNlY3QgPSBteWRhdGEtPmRhdGFfYmVnaW4gKyBjbHVzdG51bSpteWRhdGEtPmNsdXN0X3NpemU7Cgl9IGVsc2UgewoJCXN0YXJ0c2VjdCA9IG15ZGF0YS0+cm9vdGRpcl9zZWN0OwoJfQoKCUZBVF9EUFJJTlQoImdjIC0gY2x1c3RudW06ICVkLCBzdGFydHNlY3Q6ICVkXG4iLCBjbHVzdG51bSwgc3RhcnRzZWN0KTsKCWlmIChkaXNrX3JlYWQoc3RhcnRzZWN0LCBzaXplL0ZTX0JMT0NLX1NJWkUgLCBidWZmZXIpIDwgMCkgewoJCUZBVF9EUFJJTlQoIkVycm9yIHJlYWRpbmcgZGF0YVxuIik7CgkJcmV0dXJuIC0xOwoJfQoJaWYoc2l6ZSAlIEZTX0JMT0NLX1NJWkUpIHsKCQlfX3U4IHRtcGJ1ZltGU19CTE9DS19TSVpFXTsKCQlpZHg9IHNpemUvRlNfQkxPQ0tfU0laRTsKCQlpZiAoZGlza19yZWFkKHN0YXJ0c2VjdCArIGlkeCwgMSwgdG1wYnVmKSA8IDApIHsKCQkJRkFUX0RQUklOVCgiRXJyb3IgcmVhZGluZyBkYXRhXG4iKTsKCQkJcmV0dXJuIC0xOwoJCX0KCQlidWZmZXIgKz0gaWR4KkZTX0JMT0NLX1NJWkU7CgoJCW1lbWNweShidWZmZXIsIHRtcGJ1Ziwgc2l6ZSAlIEZTX0JMT0NLX1NJWkUpOwoJCXJldHVybiAwOwoJfQoKCXJldHVybiAwOwp9CgoKLyoKICogUmVhZCBhdCBtb3N0ICdtYXhzaXplJyBieXRlcyBmcm9tIHRoZSBmaWxlIGFzc29jaWF0ZWQgd2l0aCAnZGVudHB0cicKICogaW50byAnYnVmZmVyJy4KICogUmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVhZCBvciAtMSBvbiBmYXRhbCBlcnJvcnMuCiAqLwpzdGF0aWMgbG9uZwpnZXRfY29udGVudHMoZnNkYXRhICpteWRhdGEsIGRpcl9lbnRyeSAqZGVudHB0ciwgX191OCAqYnVmZmVyLAoJICAgICB1bnNpZ25lZCBsb25nIG1heHNpemUpCnsKCXVuc2lnbmVkIGxvbmcgZmlsZXNpemUgPSBGQVQyQ1BVMzIoZGVudHB0ci0+c2l6ZSksIGdvdHNpemUgPSAwOwoJdW5zaWduZWQgaW50IGJ5dGVzcGVyY2x1c3QgPSBteWRhdGEtPmNsdXN0X3NpemUgKiBTRUNUT1JfU0laRTsKCV9fdTMyIGN1cmNsdXN0ID0gU1RBUlQoZGVudHB0cik7CglfX3UzMiBlbmRjbHVzdCwgbmV3Y2x1c3Q7Cgl1bnNpZ25lZCBsb25nIGFjdHNpemU7CgoJRkFUX0RQUklOVCgiRmlsZXNpemU6ICVsZCBieXRlc1xuIiwgZmlsZXNpemUpOwoKCWlmIChtYXhzaXplID4gMCAmJiBmaWxlc2l6ZSA+IG1heHNpemUpIGZpbGVzaXplID0gbWF4c2l6ZTsKCglGQVRfRFBSSU5UKCJSZWFkaW5nOiAlbGQgYnl0ZXNcbiIsIGZpbGVzaXplKTsKCglhY3RzaXplPWJ5dGVzcGVyY2x1c3Q7CgllbmRjbHVzdD1jdXJjbHVzdDsKCWRvIHsKCQkvKiBzZWFyY2ggZm9yIGNvbnNlY3V0aXZlIGNsdXN0ZXJzICovCgkJd2hpbGUoYWN0c2l6ZSA8IGZpbGVzaXplKSB7CgkJCW5ld2NsdXN0ID0gZ2V0X2ZhdGVudChteWRhdGEsIGVuZGNsdXN0KTsKCQkJaWYoKG5ld2NsdXN0IC0xKSE9ZW5kY2x1c3QpCgkJCQlnb3RvIGdldGl0OwoJCQlpZiAobmV3Y2x1c3QgPD0gMHgwMDAxIHx8IG5ld2NsdXN0ID49IDB4ZmZmMCkgewoJCQkJRkFUX0RQUklOVCgiY3VyY2x1c3Q6IDB4JXhcbiIsIG5ld2NsdXN0KTsKCQkJCUZBVF9EUFJJTlQoIkludmFsaWQgRkFUIGVudHJ5XG4iKTsKCQkJCXJldHVybiBnb3RzaXplOwoJCQl9CgkJCWVuZGNsdXN0PW5ld2NsdXN0OwoJCQlhY3RzaXplKz0gYnl0ZXNwZXJjbHVzdDsKCQl9CgkJLyogYWN0c2l6ZSA+PSBmaWxlIHNpemUgKi8KCQlhY3RzaXplIC09IGJ5dGVzcGVyY2x1c3Q7CgkJLyogZ2V0IHJlbWFpbmluZyBjbHVzdGVycyAqLwoJCWlmIChnZXRfY2x1c3RlcihteWRhdGEsIGN1cmNsdXN0LCBidWZmZXIsIChpbnQpYWN0c2l6ZSkgIT0gMCkgewoJCQlGQVRfRVJST1IoIkVycm9yIHJlYWRpbmcgY2x1c3RlclxuIik7CgkJCXJldHVybiAtMTsKCQl9CgkJLyogZ2V0IHJlbWFpbmluZyBieXRlcyAqLwoJCWdvdHNpemUgKz0gKGludClhY3RzaXplOwoJCWZpbGVzaXplIC09IGFjdHNpemU7CgkJYnVmZmVyICs9IGFjdHNpemU7CgkJYWN0c2l6ZT0gZmlsZXNpemU7CgkJaWYgKGdldF9jbHVzdGVyKG15ZGF0YSwgZW5kY2x1c3QsIGJ1ZmZlciwgKGludClhY3RzaXplKSAhPSAwKSB7CgkJCUZBVF9FUlJPUigiRXJyb3IgcmVhZGluZyBjbHVzdGVyXG4iKTsKCQkJcmV0dXJuIC0xOwoJCX0KCQlnb3RzaXplKz1hY3RzaXplOwoJCXJldHVybiBnb3RzaXplOwpnZXRpdDoKCQlpZiAoZ2V0X2NsdXN0ZXIobXlkYXRhLCBjdXJjbHVzdCwgYnVmZmVyLCAoaW50KWFjdHNpemUpICE9IDApIHsKCQkJRkFUX0VSUk9SKCJFcnJvciByZWFkaW5nIGNsdXN0ZXJcbiIpOwoJCQlyZXR1cm4gLTE7CgkJfQoJCWdvdHNpemUgKz0gKGludClhY3RzaXplOwoJCWZpbGVzaXplIC09IGFjdHNpemU7CgkJYnVmZmVyICs9IGFjdHNpemU7CgkJY3VyY2x1c3QgPSBnZXRfZmF0ZW50KG15ZGF0YSwgZW5kY2x1c3QpOwoJCWlmIChjdXJjbHVzdCA8PSAweDAwMDEgfHwgY3VyY2x1c3QgPj0gMHhmZmYwKSB7CgkJCUZBVF9EUFJJTlQoImN1cmNsdXN0OiAweCV4XG4iLCBjdXJjbHVzdCk7CgkJCUZBVF9FUlJPUigiSW52YWxpZCBGQVQgZW50cnlcbiIpOwoJCQlyZXR1cm4gZ290c2l6ZTsKCQl9CgkJYWN0c2l6ZT1ieXRlc3BlcmNsdXN0OwoJCWVuZGNsdXN0PWN1cmNsdXN0OwoJfSB3aGlsZSAoMSk7Cn0KCgojaWZkZWYgQ09ORklHX1NVUFBPUlRfVkZBVAovKgogKiBFeHRyYWN0IHRoZSBmaWxlIG5hbWUgaW5mb3JtYXRpb24gZnJvbSAnc2xvdHB0cicgaW50byAnbF9uYW1lJywKICogc3RhcnRpbmcgYXQgbF9uYW1lWyppZHhdLgogKiBSZXR1cm4gMSBpZiB0ZXJtaW5hdG9yICh6ZXJvIGJ5dGUpIGlzIGZvdW5kLCAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKc2xvdDJzdHIoZGlyX3Nsb3QgKnNsb3RwdHIsIGNoYXIgKmxfbmFtZSwgaW50ICppZHgpCnsKCWludCBqOwoKCWZvciAoaiA9IDA7IGogPD0gODsgaiArPSAyKSB7CgkJbF9uYW1lWyppZHhdID0gc2xvdHB0ci0+bmFtZTBfNFtqXTsKCQlpZiAobF9uYW1lWyppZHhdID09IDB4MDApIHJldHVybiAxOwoJCSgqaWR4KSsrOwoJfQoJZm9yIChqID0gMDsgaiA8PSAxMDsgaiArPSAyKSB7CgkJbF9uYW1lWyppZHhdID0gc2xvdHB0ci0+bmFtZTVfMTBbal07CgkJaWYgKGxfbmFtZVsqaWR4XSA9PSAweDAwKSByZXR1cm4gMTsKCQkoKmlkeCkrKzsKCX0KCWZvciAoaiA9IDA7IGogPD0gMjsgaiArPSAyKSB7CgkJbF9uYW1lWyppZHhdID0gc2xvdHB0ci0+bmFtZTExXzEyW2pdOwoJCWlmIChsX25hbWVbKmlkeF0gPT0gMHgwMCkgcmV0dXJuIDE7CgkJKCppZHgpKys7Cgl9CgoJcmV0dXJuIDA7Cn0KCgovKgogKiBFeHRyYWN0IHRoZSBmdWxsIGxvbmcgZmlsZW5hbWUgc3RhcnRpbmcgYXQgJ3JldGRlbnQnICh3aGljaCBpcyByZWFsbHkKICogYSBzbG90KSBpbnRvICdsX25hbWUnLiBJZiBzdWNjZXNzZnVsIGFsc28gY29weSB0aGUgcmVhbCBkaXJlY3RvcnkgZW50cnkKICogaW50byAncmV0ZGVudCcKICogUmV0dXJuIDAgb24gc3VjY2VzcywgLTEgb3RoZXJ3aXNlLgogKi8KX191OAkgZ2V0X3ZmYXRuYW1lX2Jsb2NrW01BWF9DTFVTVFNJWkVdOwpzdGF0aWMgaW50CmdldF92ZmF0bmFtZShmc2RhdGEgKm15ZGF0YSwgaW50IGN1cmNsdXN0LCBfX3U4ICpjbHVzdGVyLAoJICAgICBkaXJfZW50cnkgKnJldGRlbnQsIGNoYXIgKmxfbmFtZSkKewoJZGlyX2VudHJ5ICpyZWFsZGVudDsKCWRpcl9zbG90ICAqc2xvdHB0ciA9IChkaXJfc2xvdCopIHJldGRlbnQ7CglfX3U4CSAgKm5leHRjbHVzdCA9IGNsdXN0ZXIgKyBteWRhdGEtPmNsdXN0X3NpemUgKiBTRUNUT1JfU0laRTsKCV9fdTgJICAgY291bnRlciA9IChzbG90cHRyLT5pZCAmIH5MQVNUX0xPTkdfRU5UUllfTUFTSykgJiAweGZmOwoJaW50IGlkeCA9IDA7CgoJd2hpbGUgKChfX3U4KilzbG90cHRyIDwgbmV4dGNsdXN0KSB7CgkJaWYgKGNvdW50ZXIgPT0gMCkgYnJlYWs7CgkJaWYgKCgoc2xvdHB0ci0+aWQgJiB+TEFTVF9MT05HX0VOVFJZX01BU0spICYgMHhmZikgIT0gY291bnRlcikKCQkJcmV0dXJuIC0xOwoJCXNsb3RwdHIrKzsKCQljb3VudGVyLS07Cgl9CgoJaWYgKChfX3U4KilzbG90cHRyID49IG5leHRjbHVzdCkgewoJCWRpcl9zbG90ICpzbG90cHRyMjsKCgkJc2xvdHB0ci0tOwoJCWN1cmNsdXN0ID0gZ2V0X2ZhdGVudChteWRhdGEsIGN1cmNsdXN0KTsKCQlpZiAoY3VyY2x1c3QgPD0gMHgwMDAxIHx8IGN1cmNsdXN0ID49IDB4ZmZmMCkgewoJCQlGQVRfRFBSSU5UKCJjdXJjbHVzdDogMHgleFxuIiwgY3VyY2x1c3QpOwoJCQlGQVRfRVJST1IoIkludmFsaWQgRkFUIGVudHJ5XG4iKTsKCQkJcmV0dXJuIC0xOwoJCX0KCQlpZiAoZ2V0X2NsdXN0ZXIobXlkYXRhLCBjdXJjbHVzdCwgZ2V0X3ZmYXRuYW1lX2Jsb2NrLAoJCQkJbXlkYXRhLT5jbHVzdF9zaXplICogU0VDVE9SX1NJWkUpICE9IDApIHsKCQkJRkFUX0RQUklOVCgiRXJyb3I6IHJlYWRpbmcgZGlyZWN0b3J5IGJsb2NrXG4iKTsKCQkJcmV0dXJuIC0xOwoJCX0KCQlzbG90cHRyMiA9IChkaXJfc2xvdCopIGdldF92ZmF0bmFtZV9ibG9jazsKCQl3aGlsZSAoc2xvdHB0cjItPmlkID4gMHgwMSkgewoJCQlzbG90cHRyMisrOwoJCX0KCQkvKiBTYXZlIHRoZSByZWFsIGRpcmVjdG9yeSBlbnRyeSAqLwoJCXJlYWxkZW50ID0gKGRpcl9lbnRyeSopc2xvdHB0cjIgKyAxOwoJCXdoaWxlICgoX191OCopc2xvdHB0cjIgPj0gZ2V0X3ZmYXRuYW1lX2Jsb2NrKSB7CgkJCXNsb3Qyc3RyKHNsb3RwdHIyLCBsX25hbWUsICZpZHgpOwoJCQlzbG90cHRyMi0tOwoJCX0KCX0gZWxzZSB7CgkJLyogU2F2ZSB0aGUgcmVhbCBkaXJlY3RvcnkgZW50cnkgKi8KCQlyZWFsZGVudCA9IChkaXJfZW50cnkqKXNsb3RwdHI7Cgl9CgoJZG8gewoJCXNsb3RwdHItLTsKCQlpZiAoc2xvdDJzdHIoc2xvdHB0ciwgbF9uYW1lLCAmaWR4KSkgYnJlYWs7Cgl9IHdoaWxlICghKHNsb3RwdHItPmlkICYgTEFTVF9MT05HX0VOVFJZX01BU0spKTsKCglsX25hbWVbaWR4XSA9ICdcMCc7CglpZiAoKmxfbmFtZSA9PSBERUxFVEVEX0ZMQUcpICpsX25hbWUgPSAnXDAnOwoJZWxzZSBpZiAoKmxfbmFtZSA9PSBhUklORykgKmxfbmFtZSA9ICflJzsKCWRvd25jYXNlKGxfbmFtZSk7CgoJLyogUmV0dXJuIHRoZSByZWFsIGRpcmVjdG9yeSBlbnRyeSAqLwoJbWVtY3B5KHJldGRlbnQsIHJlYWxkZW50LCBzaXplb2YoZGlyX2VudHJ5KSk7CgoJcmV0dXJuIDA7Cn0KCgovKiBDYWxjdWxhdGUgc2hvcnQgbmFtZSBjaGVja3N1bSAqLwpzdGF0aWMgX191OApta2Nrc3VtKGNvbnN0IGNoYXIgKnN0cikKewoJaW50IGk7CglfX3U4IHJldCA9IDA7CgoJZm9yIChpID0gMDsgaSA8IDExOyBpKyspIHsKCQlyZXQgPSAoKChyZXQmMSk8PDcpfCgocmV0JjB4ZmUpPj4xKSkgKyBzdHJbaV07Cgl9CgoJcmV0dXJuIHJldDsKfQojZW5kaWYKCgovKgogKiBHZXQgdGhlIGRpcmVjdG9yeSBlbnRyeSBhc3NvY2lhdGVkIHdpdGggJ2ZpbGVuYW1lJyBmcm9tIHRoZSBkaXJlY3RvcnkKICogc3RhcnRpbmcgYXQgJ3N0YXJ0c2VjdCcKICovCl9fdTggZ2V0X2RlbnRmcm9tZGlyX2Jsb2NrW01BWF9DTFVTVFNJWkVdOwpzdGF0aWMgZGlyX2VudHJ5ICpnZXRfZGVudGZyb21kaXIgKGZzZGF0YSAqIG15ZGF0YSwgaW50IHN0YXJ0c2VjdCwKCQkJCSAgIGNoYXIgKmZpbGVuYW1lLCBkaXJfZW50cnkgKiByZXRkZW50LAoJCQkJICAgaW50IGRvbHMpCnsKICAgIF9fdTE2IHByZXZja3N1bSA9IDB4ZmZmZjsKICAgIF9fdTMyIGN1cmNsdXN0ID0gU1RBUlQgKHJldGRlbnQpOwogICAgaW50IGZpbGVzID0gMCwgZGlycyA9IDA7CgogICAgRkFUX0RQUklOVCAoImdldF9kZW50ZnJvbWRpcjogJXNcbiIsIGZpbGVuYW1lKTsKICAgIHdoaWxlICgxKSB7CglkaXJfZW50cnkgKmRlbnRwdHI7CglpbnQgaTsKCglpZiAoZ2V0X2NsdXN0ZXIgKG15ZGF0YSwgY3VyY2x1c3QsIGdldF9kZW50ZnJvbWRpcl9ibG9jaywKCQkgbXlkYXRhLT5jbHVzdF9zaXplICogU0VDVE9SX1NJWkUpICE9IDApIHsKCSAgICBGQVRfRFBSSU5UICgiRXJyb3I6IHJlYWRpbmcgZGlyZWN0b3J5IGJsb2NrXG4iKTsKCSAgICByZXR1cm4gTlVMTDsKCX0KCWRlbnRwdHIgPSAoZGlyX2VudHJ5ICopIGdldF9kZW50ZnJvbWRpcl9ibG9jazsKCWZvciAoaSA9IDA7IGkgPCBESVJFTlRTUEVSQ0xVU1Q7IGkrKykgewoJICAgIGNoYXIgc19uYW1lWzE0XSwgbF9uYW1lWzI1Nl07CgoJICAgIGxfbmFtZVswXSA9ICdcMCc7CgkgICAgaWYgKGRlbnRwdHItPm5hbWVbMF0gPT0gREVMRVRFRF9GTEFHKSB7CgkJICAgIGRlbnRwdHIrKzsKCQkgICAgY29udGludWU7CgkgICAgfQoJICAgIGlmICgoZGVudHB0ci0+YXR0ciAmIEFUVFJfVk9MVU1FKSkgewojaWZkZWYgQ09ORklHX1NVUFBPUlRfVkZBVAoJCWlmICgoZGVudHB0ci0+YXR0ciAmIEFUVFJfVkZBVCkgJiYKCQkgICAgKGRlbnRwdHItPm5hbWVbMF0gJiBMQVNUX0xPTkdfRU5UUllfTUFTSykpIHsKCQkgICAgcHJldmNrc3VtID0gKChkaXJfc2xvdCAqKSBkZW50cHRyKQoJCQkgICAgLT5hbGlhc19jaGVja3N1bTsKCQkgICAgZ2V0X3ZmYXRuYW1lIChteWRhdGEsIGN1cmNsdXN0LCBnZXRfZGVudGZyb21kaXJfYmxvY2ssCgkJCQkgIGRlbnRwdHIsIGxfbmFtZSk7CgkJICAgIGlmIChkb2xzKSB7CgkJCWludCBpc2RpciA9IChkZW50cHRyLT5hdHRyICYgQVRUUl9ESVIpOwoJCQljaGFyIGRpcmM7CgkJCWludCBkb2l0ID0gMDsKCgkJCWlmIChpc2RpcikgewoJCQkgICAgZGlycysrOwoJCQkgICAgZGlyYyA9ICcvJzsKCQkJICAgIGRvaXQgPSAxOwoJCQl9IGVsc2UgewoJCQkgICAgZGlyYyA9ICcgJzsKCQkJICAgIGlmIChsX25hbWVbMF0gIT0gMCkgewoJCQkJZmlsZXMrKzsKCQkJCWRvaXQgPSAxOwoJCQkgICAgfQoJCQl9CgkJCWlmIChkb2l0KSB7CgkJCSAgICBpZiAoZGlyYyA9PSAnICcpIHsKCQkJCXByaW50ZiAoIiAlOGxkICAgJXMlY1xuIiwKCQkJCQkobG9uZykgRkFUMkNQVTMyIChkZW50cHRyLT5zaXplKSwKCQkJCQlsX25hbWUsIGRpcmMpOwoJCQkgICAgfSBlbHNlIHsKCQkJCXByaW50ZiAoIiAgICAgICAgICAgICVzJWNcbiIsIGxfbmFtZSwgZGlyYyk7CgkJCSAgICB9CgkJCX0KCQkJZGVudHB0cisrOwoJCQljb250aW51ZTsKCQkgICAgfQoJCSAgICBGQVRfRFBSSU5UICgidmZhdG5hbWU6IHwlc3xcbiIsIGxfbmFtZSk7CgkJfSBlbHNlCiNlbmRpZgoJCXsKCQkgICAgLyogVm9sdW1lIGxhYmVsIG9yIFZGQVQgZW50cnkgKi8KCQkgICAgZGVudHB0cisrOwoJCSAgICBjb250aW51ZTsKCQl9CgkgICAgfQoJICAgIGlmIChkZW50cHRyLT5uYW1lWzBdID09IDApIHsKCQlpZiAoZG9scykgewoJCSAgICBwcmludGYgKCJcbiVkIGZpbGUocyksICVkIGRpcihzKVxuXG4iLCBmaWxlcywgZGlycyk7CgkJfQoJCUZBVF9EUFJJTlQgKCJEZW50bmFtZSA9PSBOVUxMIC0gJWRcbiIsIGkpOwoJCXJldHVybiBOVUxMOwoJICAgIH0KI2lmZGVmIENPTkZJR19TVVBQT1JUX1ZGQVQKCSAgICBpZiAoZG9scyAmJiBta2Nrc3VtIChkZW50cHRyLT5uYW1lKSA9PSBwcmV2Y2tzdW0pIHsKCQlkZW50cHRyKys7CgkJY29udGludWU7CgkgICAgfQojZW5kaWYKCSAgICBnZXRfbmFtZSAoZGVudHB0ciwgc19uYW1lKTsKCSAgICBpZiAoZG9scykgewoJCWludCBpc2RpciA9IChkZW50cHRyLT5hdHRyICYgQVRUUl9ESVIpOwoJCWNoYXIgZGlyYzsKCQlpbnQgZG9pdCA9IDA7CgoJCWlmIChpc2RpcikgewoJCSAgICBkaXJzKys7CgkJICAgIGRpcmMgPSAnLyc7CgkJICAgIGRvaXQgPSAxOwoJCX0gZWxzZSB7CgkJICAgIGRpcmMgPSAnICc7CgkJICAgIGlmIChzX25hbWVbMF0gIT0gMCkgewoJCQlmaWxlcysrOwoJCQlkb2l0ID0gMTsKCQkgICAgfQoJCX0KCQlpZiAoZG9pdCkgewoJCSAgICBpZiAoZGlyYyA9PSAnICcpIHsKCQkJcHJpbnRmICgiICU4bGQgICAlcyVjXG4iLAoJCQkJKGxvbmcpIEZBVDJDUFUzMiAoZGVudHB0ci0+c2l6ZSksIHNfbmFtZSwKCQkJCWRpcmMpOwoJCSAgICB9IGVsc2UgewoJCQlwcmludGYgKCIgICAgICAgICAgICAlcyVjXG4iLCBzX25hbWUsIGRpcmMpOwoJCSAgICB9CgkJfQoJCWRlbnRwdHIrKzsKCQljb250aW51ZTsKCSAgICB9CgkgICAgaWYgKHN0cmNtcCAoZmlsZW5hbWUsIHNfbmFtZSkgJiYgc3RyY21wIChmaWxlbmFtZSwgbF9uYW1lKSkgewoJCUZBVF9EUFJJTlQgKCJNaXNtYXRjaDogfCVzfCVzfFxuIiwgc19uYW1lLCBsX25hbWUpOwoJCWRlbnRwdHIrKzsKCQljb250aW51ZTsKCSAgICB9CgkgICAgbWVtY3B5IChyZXRkZW50LCBkZW50cHRyLCBzaXplb2YgKGRpcl9lbnRyeSkpOwoKCSAgICBGQVRfRFBSSU5UICgiRGVudE5hbWU6ICVzIiwgc19uYW1lKTsKCSAgICBGQVRfRFBSSU5UICgiLCBzdGFydDogMHgleCIsIFNUQVJUIChkZW50cHRyKSk7CgkgICAgRkFUX0RQUklOVCAoIiwgc2l6ZTogIDB4JXggJXNcbiIsCgkJCUZBVDJDUFUzMiAoZGVudHB0ci0+c2l6ZSksCgkJCShkZW50cHRyLT5hdHRyICYgQVRUUl9ESVIpID8gIihESVIpIiA6ICIiKTsKCgkgICAgcmV0dXJuIHJldGRlbnQ7Cgl9CgljdXJjbHVzdCA9IGdldF9mYXRlbnQgKG15ZGF0YSwgY3VyY2x1c3QpOwoJaWYgKGN1cmNsdXN0IDw9IDB4MDAwMSB8fCBjdXJjbHVzdCA+PSAweGZmZjApIHsKCSAgICBGQVRfRFBSSU5UICgiY3VyY2x1c3Q6IDB4JXhcbiIsIGN1cmNsdXN0KTsKCSAgICBGQVRfRVJST1IgKCJJbnZhbGlkIEZBVCBlbnRyeVxuIik7CgkgICAgcmV0dXJuIE5VTEw7Cgl9CiAgICB9CgogICAgcmV0dXJuIE5VTEw7Cn0KCgovKgogKiBSZWFkIGJvb3Qgc2VjdG9yIGFuZCB2b2x1bWUgaW5mbyBmcm9tIGEgRkFUIGZpbGVzeXN0ZW0KICovCnN0YXRpYyBpbnQKcmVhZF9ib290c2VjdGFuZHZpKGJvb3Rfc2VjdG9yICpicywgdm9sdW1lX2luZm8gKnZvbGluZm8sIGludCAqZmF0c2l6ZSkKewoJX191OCBibG9ja1tGU19CTE9DS19TSVpFXTsKCXZvbHVtZV9pbmZvICp2aXN0YXJ0OwoKCWlmIChkaXNrX3JlYWQoMCwgMSwgYmxvY2spIDwgMCkgewoJCUZBVF9EUFJJTlQoIkVycm9yOiByZWFkaW5nIGJsb2NrXG4iKTsKCQlyZXR1cm4gLTE7Cgl9CgoJbWVtY3B5KGJzLCBibG9jaywgc2l6ZW9mKGJvb3Rfc2VjdG9yKSk7Cglicy0+cmVzZXJ2ZWQJPSBGQVQyQ1BVMTYoYnMtPnJlc2VydmVkKTsKCWJzLT5mYXRfbGVuZ3RoCT0gRkFUMkNQVTE2KGJzLT5mYXRfbGVuZ3RoKTsKCWJzLT5zZWNzX3RyYWNrCT0gRkFUMkNQVTE2KGJzLT5zZWNzX3RyYWNrKTsKCWJzLT5oZWFkcwk9IEZBVDJDUFUxNihicy0+aGVhZHMpOwojaWYgMCAvKiBVTlVTRUQgKi8KCWJzLT5oaWRkZW4JPSBGQVQyQ1BVMzIoYnMtPmhpZGRlbik7CiNlbmRpZgoJYnMtPnRvdGFsX3NlY3QJPSBGQVQyQ1BVMzIoYnMtPnRvdGFsX3NlY3QpOwoKCS8qIEZBVDMyIGVudHJpZXMgKi8KCWlmIChicy0+ZmF0X2xlbmd0aCA9PSAwKSB7CgkJLyogQXNzdW1lIEZBVDMyICovCgkJYnMtPmZhdDMyX2xlbmd0aCA9IEZBVDJDUFUzMihicy0+ZmF0MzJfbGVuZ3RoKTsKCQlicy0+ZmxhZ3MJID0gRkFUMkNQVTE2KGJzLT5mbGFncyk7CgkJYnMtPnJvb3RfY2x1c3RlciA9IEZBVDJDUFUzMihicy0+cm9vdF9jbHVzdGVyKTsKCQlicy0+aW5mb19zZWN0b3IgID0gRkFUMkNQVTE2KGJzLT5pbmZvX3NlY3Rvcik7CgkJYnMtPmJhY2t1cF9ib290ICA9IEZBVDJDUFUxNihicy0+YmFja3VwX2Jvb3QpOwoJCXZpc3RhcnQgPSAodm9sdW1lX2luZm8qKSAoYmxvY2sgKyBzaXplb2YoYm9vdF9zZWN0b3IpKTsKCQkqZmF0c2l6ZSA9IDMyOwoJfSBlbHNlIHsKCQl2aXN0YXJ0ID0gKHZvbHVtZV9pbmZvKikgJihicy0+ZmF0MzJfbGVuZ3RoKTsKCQkqZmF0c2l6ZSA9IDA7Cgl9CgltZW1jcHkodm9saW5mbywgdmlzdGFydCwgc2l6ZW9mKHZvbHVtZV9pbmZvKSk7CgoJLyogVGVybWluYXRlIGZzX3R5cGUgc3RyaW5nLiBXcml0aW5nIHBhc3QgdGhlIGVuZCBvZiB2aXN0YXJ0CgkgICBpcyBvayAtIGl0J3MganVzdCB0aGUgYnVmZmVyLiAqLwoJdmlzdGFydC0+ZnNfdHlwZVs4XSA9ICdcMCc7CgoJaWYgKCpmYXRzaXplID09IDMyKSB7CgkJaWYgKGNvbXBhcmVfc2lnbihGQVQzMl9TSUdOLCB2aXN0YXJ0LT5mc190eXBlKSA9PSAwKSB7CgkJCXJldHVybiAwOwoJCX0KCX0gZWxzZSB7CgkJaWYgKGNvbXBhcmVfc2lnbihGQVQxMl9TSUdOLCB2aXN0YXJ0LT5mc190eXBlKSA9PSAwKSB7CgkJCSpmYXRzaXplID0gMTI7CgkJCXJldHVybiAwOwoJCX0KCQlpZiAoY29tcGFyZV9zaWduKEZBVDE2X1NJR04sIHZpc3RhcnQtPmZzX3R5cGUpID09IDApIHsKCQkJKmZhdHNpemUgPSAxNjsKCQkJcmV0dXJuIDA7CgkJfQoJfQoKCUZBVF9EUFJJTlQoIkVycm9yOiBicm9rZW4gZnNfdHlwZSBzaWduXG4iKTsKCXJldHVybiAtMTsKfQoKCl9fdTggZG9fZmF0X3JlYWRfYmxvY2tbTUFYX0NMVVNUU0laRV07ICAvKiBCbG9jayBidWZmZXIgKi8KbG9uZwpkb19mYXRfcmVhZCAoY29uc3QgY2hhciAqZmlsZW5hbWUsIHZvaWQgKmJ1ZmZlciwgdW5zaWduZWQgbG9uZyBtYXhzaXplLAoJICAgICBpbnQgZG9scykKewogICAgY2hhciBmbmFtZWNvcHlbMjA0OF07CiAgICBib290X3NlY3RvciBiczsKICAgIHZvbHVtZV9pbmZvIHZvbGluZm87CiAgICBmc2RhdGEgZGF0YWJsb2NrOwogICAgZnNkYXRhICpteWRhdGEgPSAmZGF0YWJsb2NrOwogICAgZGlyX2VudHJ5ICpkZW50cHRyOwogICAgX191MTYgcHJldmNrc3VtID0gMHhmZmZmOwogICAgY2hhciAqc3VibmFtZSA9ICIiOwogICAgaW50IHJvb3RkaXJfc2l6ZSwgY3Vyc2VjdDsKICAgIGludCBpZHgsIGlzZGlyID0gMDsKICAgIGludCBmaWxlcyA9IDAsIGRpcnMgPSAwOwogICAgbG9uZyByZXQgPSAwOwogICAgaW50IGZpcnN0dGltZTsKCiAgICBpZiAocmVhZF9ib290c2VjdGFuZHZpICgmYnMsICZ2b2xpbmZvLCAmbXlkYXRhLT5mYXRzaXplKSkgewoJRkFUX0RQUklOVCAoIkVycm9yOiByZWFkaW5nIGJvb3Qgc2VjdG9yXG4iKTsKCXJldHVybiAtMTsKICAgIH0KICAgIGlmIChteWRhdGEtPmZhdHNpemUgPT0gMzIpIHsKCW15ZGF0YS0+ZmF0bGVuZ3RoID0gYnMuZmF0MzJfbGVuZ3RoOwogICAgfSBlbHNlIHsKCW15ZGF0YS0+ZmF0bGVuZ3RoID0gYnMuZmF0X2xlbmd0aDsKICAgIH0KICAgIG15ZGF0YS0+ZmF0X3NlY3QgPSBicy5yZXNlcnZlZDsKICAgIGN1cnNlY3QgPSBteWRhdGEtPnJvb3RkaXJfc2VjdAoJICAgID0gbXlkYXRhLT5mYXRfc2VjdCArIG15ZGF0YS0+ZmF0bGVuZ3RoICogYnMuZmF0czsKICAgIG15ZGF0YS0+Y2x1c3Rfc2l6ZSA9IGJzLmNsdXN0ZXJfc2l6ZTsKICAgIGlmIChteWRhdGEtPmZhdHNpemUgPT0gMzIpIHsKCXJvb3RkaXJfc2l6ZSA9IG15ZGF0YS0+Y2x1c3Rfc2l6ZTsKCW15ZGF0YS0+ZGF0YV9iZWdpbiA9IG15ZGF0YS0+cm9vdGRpcl9zZWN0ICAgLyogKyByb290ZGlyX3NpemUgKi8KCQktIChteWRhdGEtPmNsdXN0X3NpemUgKiAyKTsKICAgIH0gZWxzZSB7Cglyb290ZGlyX3NpemUgPSAoKGJzLmRpcl9lbnRyaWVzWzFdICogKGludCkgMjU2ICsgYnMuZGlyX2VudHJpZXNbMF0pCgkJCSogc2l6ZW9mIChkaXJfZW50cnkpKSAvIFNFQ1RPUl9TSVpFOwoJbXlkYXRhLT5kYXRhX2JlZ2luID0gbXlkYXRhLT5yb290ZGlyX3NlY3QgKyByb290ZGlyX3NpemUKCQktIChteWRhdGEtPmNsdXN0X3NpemUgKiAyKTsKICAgIH0KICAgIG15ZGF0YS0+ZmF0YnVmbnVtID0gLTE7CgogICAgRkFUX0RQUklOVCAoIkZBVCVkLCBmYXRsZW5ndGg6ICVkXG4iLCBteWRhdGEtPmZhdHNpemUsCgkJbXlkYXRhLT5mYXRsZW5ndGgpOwogICAgRkFUX0RQUklOVCAoIlJvb3RkaXIgYmVnaW5zIGF0IHNlY3RvcjogJWQsIG9mZnNldDogJXgsIHNpemU6ICVkXG4iCgkJIkRhdGEgYmVnaW5zIGF0OiAlZFxuIiwKCQlteWRhdGEtPnJvb3RkaXJfc2VjdCwgbXlkYXRhLT5yb290ZGlyX3NlY3QgKiBTRUNUT1JfU0laRSwKCQlyb290ZGlyX3NpemUsIG15ZGF0YS0+ZGF0YV9iZWdpbik7CiAgICBGQVRfRFBSSU5UICgiQ2x1c3RlciBzaXplOiAlZFxuIiwgbXlkYXRhLT5jbHVzdF9zaXplKTsKCiAgICAvKiAiY3dkIiBpcyBhbHdheXMgdGhlIHJvb3QuLi4gKi8KICAgIHdoaWxlIChJU0RJUkRFTElNICgqZmlsZW5hbWUpKQoJZmlsZW5hbWUrKzsKICAgIC8qIE1ha2UgYSBjb3B5IG9mIHRoZSBmaWxlbmFtZSBhbmQgY29udmVydCBpdCB0byBsb3dlcmNhc2UgKi8KICAgIHN0cmNweSAoZm5hbWVjb3B5LCBmaWxlbmFtZSk7CiAgICBkb3duY2FzZSAoZm5hbWVjb3B5KTsKICAgIGlmICgqZm5hbWVjb3B5ID09ICdcMCcpIHsKCWlmICghZG9scykKCSAgICByZXR1cm4gLTE7Cglkb2xzID0gTFNfUk9PVDsKICAgIH0gZWxzZSBpZiAoKGlkeCA9IGRpcmRlbGltIChmbmFtZWNvcHkpKSA+PSAwKSB7Cglpc2RpciA9IDE7CglmbmFtZWNvcHlbaWR4XSA9ICdcMCc7CglzdWJuYW1lID0gZm5hbWVjb3B5ICsgaWR4ICsgMTsKCS8qIEhhbmRsZSBtdWx0aXBsZSBkZWxpbWl0ZXJzICovCgl3aGlsZSAoSVNESVJERUxJTSAoKnN1Ym5hbWUpKQoJICAgIHN1Ym5hbWUrKzsKICAgIH0gZWxzZSBpZiAoZG9scykgewoJaXNkaXIgPSAxOwogICAgfQoKICAgIHdoaWxlICgxKSB7CglpbnQgaTsKCglpZiAoZGlza19yZWFkIChjdXJzZWN0LCBteWRhdGEtPmNsdXN0X3NpemUsIGRvX2ZhdF9yZWFkX2Jsb2NrKSA8IDApIHsKCSAgICBGQVRfRFBSSU5UICgiRXJyb3I6IHJlYWRpbmcgcm9vdGRpciBibG9ja1xuIik7CgkgICAgcmV0dXJuIC0xOwoJfQoJZGVudHB0ciA9IChkaXJfZW50cnkgKikgZG9fZmF0X3JlYWRfYmxvY2s7Cglmb3IgKGkgPSAwOyBpIDwgRElSRU5UU1BFUkJMT0NLOyBpKyspIHsKCSAgICBjaGFyIHNfbmFtZVsxNF0sIGxfbmFtZVsyNTZdOwoKCSAgICBsX25hbWVbMF0gPSAnXDAnOwoJICAgIGlmICgoZGVudHB0ci0+YXR0ciAmIEFUVFJfVk9MVU1FKSkgewojaWZkZWYgQ09ORklHX1NVUFBPUlRfVkZBVAoJCWlmICgoZGVudHB0ci0+YXR0ciAmIEFUVFJfVkZBVCkgJiYKCQkgICAgKGRlbnRwdHItPm5hbWVbMF0gJiBMQVNUX0xPTkdfRU5UUllfTUFTSykpIHsKCQkgICAgcHJldmNrc3VtID0gKChkaXJfc2xvdCAqKSBkZW50cHRyKS0+YWxpYXNfY2hlY2tzdW07CgkJICAgIGdldF92ZmF0bmFtZSAobXlkYXRhLCAwLCBkb19mYXRfcmVhZF9ibG9jaywgZGVudHB0ciwgbF9uYW1lKTsKCQkgICAgaWYgKGRvbHMgPT0gTFNfUk9PVCkgewoJCQlpbnQgaXNkaXIgPSAoZGVudHB0ci0+YXR0ciAmIEFUVFJfRElSKTsKCQkJY2hhciBkaXJjOwoJCQlpbnQgZG9pdCA9IDA7CgoJCQlpZiAoaXNkaXIpIHsKCQkJICAgIGRpcnMrKzsKCQkJICAgIGRpcmMgPSAnLyc7CgkJCSAgICBkb2l0ID0gMTsKCQkJfSBlbHNlIHsKCQkJICAgIGRpcmMgPSAnICc7CgkJCSAgICBpZiAobF9uYW1lWzBdICE9IDApIHsKCQkJCWZpbGVzKys7CgkJCQlkb2l0ID0gMTsKCQkJICAgIH0KCQkJfQoJCQlpZiAoZG9pdCkgewoJCQkgICAgaWYgKGRpcmMgPT0gJyAnKSB7CgkJCQlwcmludGYgKCIgJThsZCAgICVzJWNcbiIsCgkJCQkJKGxvbmcpIEZBVDJDUFUzMiAoZGVudHB0ci0+c2l6ZSksCgkJCQkJbF9uYW1lLCBkaXJjKTsKCQkJICAgIH0gZWxzZSB7CgkJCQlwcmludGYgKCIgICAgICAgICAgICAlcyVjXG4iLCBsX25hbWUsIGRpcmMpOwoJCQkgICAgfQoJCQl9CgkJCWRlbnRwdHIrKzsKCQkJY29udGludWU7CgkJICAgIH0KCQkgICAgRkFUX0RQUklOVCAoIlJvb3R2ZmF0bmFtZTogfCVzfFxuIiwgbF9uYW1lKTsKCQl9IGVsc2UKI2VuZGlmCgkJewoJCSAgICAvKiBWb2x1bWUgbGFiZWwgb3IgVkZBVCBlbnRyeSAqLwoJCSAgICBkZW50cHRyKys7CgkJICAgIGNvbnRpbnVlOwoJCX0KCSAgICB9IGVsc2UgaWYgKGRlbnRwdHItPm5hbWVbMF0gPT0gMCkgewoJCUZBVF9EUFJJTlQgKCJSb290RGVudG5hbWUgPT0gTlVMTCAtICVkXG4iLCBpKTsKCQlpZiAoZG9scyA9PSBMU19ST09UKSB7CgkJICAgIHByaW50ZiAoIlxuJWQgZmlsZShzKSwgJWQgZGlyKHMpXG5cbiIsIGZpbGVzLCBkaXJzKTsKCQkgICAgcmV0dXJuIDA7CgkJfQoJCXJldHVybiAtMTsKCSAgICB9CiNpZmRlZiBDT05GSUdfU1VQUE9SVF9WRkFUCgkgICAgZWxzZSBpZiAoZG9scyA9PSBMU19ST09UCgkJICAgICAmJiBta2Nrc3VtIChkZW50cHRyLT5uYW1lKSA9PSBwcmV2Y2tzdW0pIHsKCQlkZW50cHRyKys7CgkJY29udGludWU7CgkgICAgfQojZW5kaWYKCSAgICBnZXRfbmFtZSAoZGVudHB0ciwgc19uYW1lKTsKCSAgICBpZiAoZG9scyA9PSBMU19ST09UKSB7CgkJaW50IGlzZGlyID0gKGRlbnRwdHItPmF0dHIgJiBBVFRSX0RJUik7CgkJY2hhciBkaXJjOwoJCWludCBkb2l0ID0gMDsKCgkJaWYgKGlzZGlyKSB7CgkJICAgIGRpcmMgPSAnLyc7CgkJICAgIGlmIChzX25hbWVbMF0gIT0gMCkgewoJCQlkaXJzKys7CgkJCWRvaXQgPSAxOwoJCSAgICB9CgkJfSBlbHNlIHsKCQkgICAgZGlyYyA9ICcgJzsKCQkgICAgaWYgKHNfbmFtZVswXSAhPSAwKSB7CgkJCWZpbGVzKys7CgkJCWRvaXQgPSAxOwoJCSAgICB9CgkJfQoJCWlmIChkb2l0KSB7CgkJICAgIGlmIChkaXJjID09ICcgJykgewoJCQlwcmludGYgKCIgJThsZCAgICVzJWNcbiIsCgkJCQkobG9uZykgRkFUMkNQVTMyIChkZW50cHRyLT5zaXplKSwgc19uYW1lLAoJCQkJZGlyYyk7CgkJICAgIH0gZWxzZSB7CgkJCXByaW50ZiAoIiAgICAgICAgICAgICVzJWNcbiIsIHNfbmFtZSwgZGlyYyk7CgkJICAgIH0KCQl9CgkJZGVudHB0cisrOwoJCWNvbnRpbnVlOwoJICAgIH0KCSAgICBpZiAoc3RyY21wIChmbmFtZWNvcHksIHNfbmFtZSkgJiYgc3RyY21wIChmbmFtZWNvcHksIGxfbmFtZSkpIHsKCQlGQVRfRFBSSU5UICgiUm9vdE1pc21hdGNoOiB8JXN8JXN8XG4iLCBzX25hbWUsIGxfbmFtZSk7CgkJZGVudHB0cisrOwoJCWNvbnRpbnVlOwoJICAgIH0KCSAgICBpZiAoaXNkaXIgJiYgIShkZW50cHRyLT5hdHRyICYgQVRUUl9ESVIpKQoJCXJldHVybiAtMTsKCgkgICAgRkFUX0RQUklOVCAoIlJvb3ROYW1lOiAlcyIsIHNfbmFtZSk7CgkgICAgRkFUX0RQUklOVCAoIiwgc3RhcnQ6IDB4JXgiLCBTVEFSVCAoZGVudHB0cikpOwoJICAgIEZBVF9EUFJJTlQgKCIsIHNpemU6ICAweCV4ICVzXG4iLAoJCQlGQVQyQ1BVMzIgKGRlbnRwdHItPnNpemUpLCBpc2RpciA/ICIoRElSKSIgOiAiIik7CgoJICAgIGdvdG8gcm9vdGRpcl9kb25lOyAgLyogV2UgZ290IGEgbWF0Y2ggKi8KCX0KCWN1cnNlY3QrKzsKICAgIH0KICByb290ZGlyX2RvbmU6CgogICAgZmlyc3R0aW1lID0gMTsKICAgIHdoaWxlIChpc2RpcikgewoJaW50IHN0YXJ0c2VjdCA9IG15ZGF0YS0+ZGF0YV9iZWdpbgoJCSsgU1RBUlQgKGRlbnRwdHIpICogbXlkYXRhLT5jbHVzdF9zaXplOwoJZGlyX2VudHJ5IGRlbnQ7CgljaGFyICpuZXh0bmFtZSA9IE5VTEw7CgoJZGVudCA9ICpkZW50cHRyOwoJZGVudHB0ciA9ICZkZW50OwoKCWlkeCA9IGRpcmRlbGltIChzdWJuYW1lKTsKCWlmIChpZHggPj0gMCkgewoJICAgIHN1Ym5hbWVbaWR4XSA9ICdcMCc7CgkgICAgbmV4dG5hbWUgPSBzdWJuYW1lICsgaWR4ICsgMTsKCSAgICAvKiBIYW5kbGUgbXVsdGlwbGUgZGVsaW1pdGVycyAqLwoJICAgIHdoaWxlIChJU0RJUkRFTElNICgqbmV4dG5hbWUpKQoJCW5leHRuYW1lKys7CgkgICAgaWYgKGRvbHMgJiYgKm5leHRuYW1lID09ICdcMCcpCgkJZmlyc3R0aW1lID0gMDsKCX0gZWxzZSB7CgkgICAgaWYgKGRvbHMgJiYgZmlyc3R0aW1lKSB7CgkJZmlyc3R0aW1lID0gMDsKCSAgICB9IGVsc2UgewoJCWlzZGlyID0gMDsKCSAgICB9Cgl9CgoJaWYgKGdldF9kZW50ZnJvbWRpciAobXlkYXRhLCBzdGFydHNlY3QsIHN1Ym5hbWUsIGRlbnRwdHIsCgkJCSAgICAgaXNkaXIgPyAwIDogZG9scykgPT0gTlVMTCkgewoJICAgIGlmIChkb2xzICYmICFpc2RpcikKCQlyZXR1cm4gMDsKCSAgICByZXR1cm4gLTE7Cgl9CgoJaWYgKGlkeCA+PSAwKSB7CgkgICAgaWYgKCEoZGVudHB0ci0+YXR0ciAmIEFUVFJfRElSKSkKCQlyZXR1cm4gLTE7CgkgICAgc3VibmFtZSA9IG5leHRuYW1lOwoJfQogICAgfQogICAgcmV0ID0gZ2V0X2NvbnRlbnRzIChteWRhdGEsIGRlbnRwdHIsIGJ1ZmZlciwgbWF4c2l6ZSk7CiAgICBGQVRfRFBSSU5UICgiU2l6ZTogJWQsIGdvdDogJWxkXG4iLCBGQVQyQ1BVMzIgKGRlbnRwdHItPnNpemUpLCByZXQpOwoKICAgIHJldHVybiByZXQ7Cn0KCgppbnQKZmlsZV9mYXRfZGV0ZWN0ZnModm9pZCkKewoJYm9vdF9zZWN0b3IJYnM7Cgl2b2x1bWVfaW5mbwl2b2xpbmZvOwoJaW50CQlmYXRzaXplOwoJY2hhcgl2b2xfbGFiZWxbMTJdOwoKCWlmKGN1cl9kZXY9PU5VTEwpIHsKCQlwcmludGYoIk5vIGN1cnJlbnQgZGV2aWNlXG4iKTsKCQlyZXR1cm4gMTsKCX0KI2lmIChDT05GSUdfQ09NTUFORFMgJiBDRkdfQ01EX0lERSkgfHwgKENPTkZJR19DT01NQU5EUyAmIENGR19DTURfU0NTSSkgfHwgXAogICAgKENPTkZJR19DT01NQU5EUyAmIENGR19DTURfVVNCKSB8fCAoQ09ORklHX01NQykKCXByaW50ZigiSW50ZXJmYWNlOiAgIik7Cglzd2l0Y2goY3VyX2Rldi0+aWZfdHlwZSkgewoJCWNhc2UgSUZfVFlQRV9JREUgOglwcmludGYoIklERSIpOyBicmVhazsKCQljYXNlIElGX1RZUEVfU0NTSSA6CXByaW50ZigiU0NTSSIpOyBicmVhazsKCQljYXNlIElGX1RZUEVfQVRBUEkgOglwcmludGYoIkFUQVBJIik7IGJyZWFrOwoJCWNhc2UgSUZfVFlQRV9VU0IgOglwcmludGYoIlVTQiIpOyBicmVhazsKCQljYXNlIElGX1RZUEVfRE9DIDoJcHJpbnRmKCJET0MiKTsgYnJlYWs7CgkJY2FzZSBJRl9UWVBFX01NQyA6CXByaW50ZigiTU1DIik7IGJyZWFrOwoJCWRlZmF1bHQgOgkJcHJpbnRmKCJVbmtub3duIik7Cgl9CglwcmludGYoIlxuICBEZXZpY2UgJWQ6ICIsY3VyX2Rldi0+ZGV2KTsKCWRldl9wcmludChjdXJfZGV2KTsKI2VuZGlmCglpZihyZWFkX2Jvb3RzZWN0YW5kdmkoJmJzLCAmdm9saW5mbywgJmZhdHNpemUpKSB7CgkJcHJpbnRmKCJcbk5vIHZhbGlkIEZBVCBmcyBmb3VuZFxuIik7CgkJcmV0dXJuIDE7Cgl9CgltZW1jcHkgKHZvbF9sYWJlbCwgdm9saW5mby52b2x1bWVfbGFiZWwsIDExKTsKCXZvbF9sYWJlbFsxMV0gPSAnXDAnOwoJdm9saW5mby5mc190eXBlWzVdPSdcMCc7CglwcmludGYoIlBhcnRpdGlvbiAlZDogRmlsZXN5c3RlbTogJXMgXCIlc1wiXG4iLGN1cl9wYXJ0LHZvbGluZm8uZnNfdHlwZSx2b2xfbGFiZWwpOwoJcmV0dXJuIDA7Cn0KCgppbnQKZmlsZV9mYXRfbHMoY29uc3QgY2hhciAqZGlyKQp7CglyZXR1cm4gZG9fZmF0X3JlYWQoZGlyLCBOVUxMLCAwLCBMU19ZRVMpOwp9CgoKbG9uZwpmaWxlX2ZhdF9yZWFkKGNvbnN0IGNoYXIgKmZpbGVuYW1lLCB2b2lkICpidWZmZXIsIHVuc2lnbmVkIGxvbmcgbWF4c2l6ZSkKewoJcHJpbnRmKCJyZWFkaW5nICVzXG4iLGZpbGVuYW1lKTsKCXJldHVybiBkb19mYXRfcmVhZChmaWxlbmFtZSwgYnVmZmVyLCBtYXhzaXplLCBMU19OTyk7Cn0KCiNlbmRpZiAvKiAjaWYgKENPTkZJR19DT01NQU5EUyAmIENGR19DTURfRkFUKSAqLwo=