LyoKICogaThrLmMgLS0gTGludXggZHJpdmVyIGZvciBhY2Nlc3NpbmcgdGhlIFNNTSBCSU9TIG9uIERlbGwgbGFwdG9wcy4KICoJICAgIFNlZSBodHRwOi8vd3d3LmRlYmlhbi5vcmcvfmR6L2k4ay8gZm9yIG1vcmUgaW5mb3JtYXRpb24KICoJICAgIGFuZCBmb3IgbGF0ZXN0IHZlcnNpb24gb2YgdGhpcyBkcml2ZXIuCiAqCiAqIENvcHlyaWdodCAoQykgMjAwMSAgTWFzc2ltbyBEYWwgWm90dG8gPGR6QGRlYmlhbi5vcmc+CiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZQogKiBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55CiAqIGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQKICogV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqLwoKI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvdHlwZXMuaD4KI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KI2luY2x1ZGUgPGxpbnV4L3Byb2NfZnMuaD4KI2luY2x1ZGUgPGxpbnV4L2FwbV9iaW9zLmg+CiNpbmNsdWRlIDxhc20vdWFjY2Vzcy5oPgojaW5jbHVkZSA8YXNtL2lvLmg+CgojaW5jbHVkZSA8bGludXgvaThrLmg+CgojZGVmaW5lIEk4S19WRVJTSU9OCQkiMS4xMyAxNC8wNS8yMDAyIgoKI2RlZmluZSBJOEtfU01NX0ZOX1NUQVRVUwkweDAwMjUKI2RlZmluZSBJOEtfU01NX1BPV0VSX1NUQVRVUwkweDAwNjkKI2RlZmluZSBJOEtfU01NX1NFVF9GQU4JCTB4MDFhMwojZGVmaW5lIEk4S19TTU1fR0VUX0ZBTgkJMHgwMGEzCiNkZWZpbmUgSThLX1NNTV9HRVRfU1BFRUQJMHgwMmEzCiNkZWZpbmUgSThLX1NNTV9HRVRfVEVNUAkweDEwYTMKI2RlZmluZSBJOEtfU01NX0dFVF9ERUxMX1NJRwkweGZmYTMKI2RlZmluZSBJOEtfU01NX0JJT1NfVkVSU0lPTgkweDAwYTYKCiNkZWZpbmUgSThLX0ZBTl9NVUxUCQkzMAojZGVmaW5lIEk4S19NQVhfVEVNUAkJMTI3CgojZGVmaW5lIEk4S19GTl9OT05FCQkweDAwCiNkZWZpbmUgSThLX0ZOX1VQCQkweDAxCiNkZWZpbmUgSThLX0ZOX0RPV04JCTB4MDIKI2RlZmluZSBJOEtfRk5fTVVURQkJMHgwNAojZGVmaW5lIEk4S19GTl9NQVNLCQkweDA3CiNkZWZpbmUgSThLX0ZOX1NISUZUCQk4CgojZGVmaW5lIEk4S19QT1dFUl9BQwkJMHgwNQojZGVmaW5lIEk4S19QT1dFUl9CQVRURVJZCTB4MDEKCiNkZWZpbmUgSThLX1RFTVBFUkFUVVJFX0JVRwkxCgojZGVmaW5lIERFTExfU0lHTkFUVVJFCQkiRGVsbCBDb21wdXRlciIKCnN0YXRpYyBjaGFyICpzdXBwb3J0ZWRfbW9kZWxzW10gPSB7CgkiSW5zcGlyb24iLAoJIkxhdGl0dWRlIiwKCU5VTEwKfTsKCnN0YXRpYyBjaGFyIHN5c3RlbV92ZW5kb3JbNDhdID0gIj8iOwpzdGF0aWMgY2hhciBwcm9kdWN0X25hbWVbNDhdID0gIj8iOwpzdGF0aWMgY2hhciBiaW9zX3ZlcnNpb25bNF0gPSAiPyI7CnN0YXRpYyBjaGFyIHNlcmlhbF9udW1iZXJbMTZdID0gIj8iOwoKTU9EVUxFX0FVVEhPUigiTWFzc2ltbyBEYWwgWm90dG8gKGR6QGRlYmlhbi5vcmcpIik7Ck1PRFVMRV9ERVNDUklQVElPTigiRHJpdmVyIGZvciBhY2Nlc3NpbmcgU01NIEJJT1Mgb24gRGVsbCBsYXB0b3BzIik7Ck1PRFVMRV9MSUNFTlNFKCJHUEwiKTsKCnN0YXRpYyBpbnQgZm9yY2U7Cm1vZHVsZV9wYXJhbShmb3JjZSwgYm9vbCwgMCk7Ck1PRFVMRV9QQVJNX0RFU0MoZm9yY2UsICJGb3JjZSBsb2FkaW5nIHdpdGhvdXQgY2hlY2tpbmcgZm9yIHN1cHBvcnRlZCBtb2RlbHMiKTsKCnN0YXRpYyBpbnQgcmVzdHJpY3RlZDsKbW9kdWxlX3BhcmFtKHJlc3RyaWN0ZWQsIGJvb2wsIDApOwpNT0RVTEVfUEFSTV9ERVNDKHJlc3RyaWN0ZWQsICJBbGxvdyBmYW4gY29udHJvbCBpZiBTWVNfQURNSU4gY2FwYWJpbGl0eSBzZXQiKTsKCnN0YXRpYyBpbnQgcG93ZXJfc3RhdHVzOwptb2R1bGVfcGFyYW0ocG93ZXJfc3RhdHVzLCBib29sLCAwNjAwKTsKTU9EVUxFX1BBUk1fREVTQyhwb3dlcl9zdGF0dXMsICJSZXBvcnQgcG93ZXIgc3RhdHVzIGluIC9wcm9jL2k4ayIpOwoKc3RhdGljIHNzaXplX3QgaThrX3JlYWQoc3RydWN0IGZpbGUgKiwgY2hhciBfX3VzZXIgKiwgc2l6ZV90LCBsb2ZmX3QgKik7CnN0YXRpYyBpbnQgaThrX2lvY3RsKHN0cnVjdCBpbm9kZSAqLCBzdHJ1Y3QgZmlsZSAqLCB1bnNpZ25lZCBpbnQsCgkJICAgICB1bnNpZ25lZCBsb25nKTsKCnN0YXRpYyBzdHJ1Y3QgZmlsZV9vcGVyYXRpb25zIGk4a19mb3BzID0gewoJLnJlYWQgPSBpOGtfcmVhZCwKCS5pb2N0bCA9IGk4a19pb2N0bCwKfTsKCnR5cGVkZWYgc3RydWN0IHsKCXVuc2lnbmVkIGludCBlYXg7Cgl1bnNpZ25lZCBpbnQgZWJ4IF9fYXR0cmlidXRlX18gKChwYWNrZWQpKTsKCXVuc2lnbmVkIGludCBlY3ggX19hdHRyaWJ1dGVfXyAoKHBhY2tlZCkpOwoJdW5zaWduZWQgaW50IGVkeCBfX2F0dHJpYnV0ZV9fICgocGFja2VkKSk7Cgl1bnNpZ25lZCBpbnQgZXNpIF9fYXR0cmlidXRlX18gKChwYWNrZWQpKTsKCXVuc2lnbmVkIGludCBlZGkgX19hdHRyaWJ1dGVfXyAoKHBhY2tlZCkpOwp9IFNNTVJlZ2lzdGVyczsKCnR5cGVkZWYgc3RydWN0IHsKCXU4IHR5cGU7Cgl1OCBsZW5ndGg7Cgl1MTYgaGFuZGxlOwp9IERNSUhlYWRlcjsKCi8qCiAqIENhbGwgdGhlIFN5c3RlbSBNYW5hZ2VtZW50IE1vZGUgQklPUy4gQ29kZSBwcm92aWRlZCBieSBKb25hdGhhbiBCdXp6YXJkLgogKi8Kc3RhdGljIGludCBpOGtfc21tKFNNTVJlZ2lzdGVycyAqIHJlZ3MpCnsKCWludCByYzsKCWludCBlYXggPSByZWdzLT5lYXg7CgoJYXNtKCJwdXNobCAlJWVheFxuXHQiCgkgICAgIm1vdmwgMCglJWVheCksJSVlZHhcblx0IgoJICAgICJwdXNoICUlZWR4XG5cdCIKCSAgICAibW92bCA0KCUlZWF4KSwlJWVieFxuXHQiCgkgICAgIm1vdmwgOCglJWVheCksJSVlY3hcblx0IgoJICAgICJtb3ZsIDEyKCUlZWF4KSwlJWVkeFxuXHQiCgkgICAgIm1vdmwgMTYoJSVlYXgpLCUlZXNpXG5cdCIKCSAgICAibW92bCAyMCglJWVheCksJSVlZGlcblx0IgoJICAgICJwb3BsICUlZWF4XG5cdCIKCSAgICAib3V0ICUlYWwsJDB4YjJcblx0IgoJICAgICJvdXQgJSVhbCwkMHg4NFxuXHQiCgkgICAgInhjaGdsICUlZWF4LCglJWVzcClcblx0IgoJICAgICJtb3ZsICUlZWJ4LDQoJSVlYXgpXG5cdCIKCSAgICAibW92bCAlJWVjeCw4KCUlZWF4KVxuXHQiCgkgICAgIm1vdmwgJSVlZHgsMTIoJSVlYXgpXG5cdCIKCSAgICAibW92bCAlJWVzaSwxNiglJWVheClcblx0IgoJICAgICJtb3ZsICUlZWRpLDIwKCUlZWF4KVxuXHQiCgkgICAgInBvcGwgJSVlZHhcblx0IgoJICAgICJtb3ZsICUlZWR4LDAoJSVlYXgpXG5cdCIKCSAgICAibGFoZlxuXHQiCgkgICAgInNocmwgJDgsJSVlYXhcblx0IgoJICAgICJhbmRsICQxLCUlZWF4XG4iOiI9YSIocmMpCgkgICAgOiAgICAiYSIocmVncykKCSAgICA6ICAgICIlZWJ4IiwgIiVlY3giLCAiJWVkeCIsICIlZXNpIiwgIiVlZGkiLCAibWVtb3J5Iik7CgoJaWYgKChyYyAhPSAwKSB8fCAoKHJlZ3MtPmVheCAmIDB4ZmZmZikgPT0gMHhmZmZmKSB8fCAocmVncy0+ZWF4ID09IGVheCkpIHsKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCglyZXR1cm4gMDsKfQoKLyoKICogUmVhZCB0aGUgYmlvcyB2ZXJzaW9uLiBSZXR1cm4gdGhlIHZlcnNpb24gYXMgYW4gaW50ZWdlciBjb3JyZXNwb25kaW5nCiAqIHRvIHRoZSBhc2NpaSB2YWx1ZSwgZm9yIGV4YW1wbGUgIkExNyIgaXMgcmV0dXJuZWQgYXMgMHgwMDQxMzEzNy4KICovCnN0YXRpYyBpbnQgaThrX2dldF9iaW9zX3ZlcnNpb24odm9pZCkKewoJU01NUmVnaXN0ZXJzIHJlZ3MgPSB7IDAsIDAsIDAsIDAsIDAsIDAgfTsKCWludCByYzsKCglyZWdzLmVheCA9IEk4S19TTU1fQklPU19WRVJTSU9OOwoJaWYgKChyYyA9IGk4a19zbW0oJnJlZ3MpKSA8IDApIHsKCQlyZXR1cm4gcmM7Cgl9CgoJcmV0dXJuIHJlZ3MuZWF4Owp9CgovKgogKiBSZWFkIHRoZSBtYWNoaW5lIGlkLgogKi8Kc3RhdGljIGludCBpOGtfZ2V0X3NlcmlhbF9udW1iZXIodW5zaWduZWQgY2hhciAqYnVmZikKewoJc3RybGNweShidWZmLCBzZXJpYWxfbnVtYmVyLCBzaXplb2Yoc2VyaWFsX251bWJlcikpOwoJcmV0dXJuIDA7Cn0KCi8qCiAqIFJlYWQgdGhlIEZuIGtleSBzdGF0dXMuCiAqLwpzdGF0aWMgaW50IGk4a19nZXRfZm5fc3RhdHVzKHZvaWQpCnsKCVNNTVJlZ2lzdGVycyByZWdzID0geyAwLCAwLCAwLCAwLCAwLCAwIH07CglpbnQgcmM7CgoJcmVncy5lYXggPSBJOEtfU01NX0ZOX1NUQVRVUzsKCWlmICgocmMgPSBpOGtfc21tKCZyZWdzKSkgPCAwKSB7CgkJcmV0dXJuIHJjOwoJfQoKCXN3aXRjaCAoKHJlZ3MuZWF4ID4+IEk4S19GTl9TSElGVCkgJiBJOEtfRk5fTUFTSykgewoJY2FzZSBJOEtfRk5fVVA6CgkJcmV0dXJuIEk4S19WT0xfVVA7CgljYXNlIEk4S19GTl9ET1dOOgoJCXJldHVybiBJOEtfVk9MX0RPV047CgljYXNlIEk4S19GTl9NVVRFOgoJCXJldHVybiBJOEtfVk9MX01VVEU7CglkZWZhdWx0OgoJCXJldHVybiAwOwoJfQp9CgovKgogKiBSZWFkIHRoZSBwb3dlciBzdGF0dXMuCiAqLwpzdGF0aWMgaW50IGk4a19nZXRfcG93ZXJfc3RhdHVzKHZvaWQpCnsKCVNNTVJlZ2lzdGVycyByZWdzID0geyAwLCAwLCAwLCAwLCAwLCAwIH07CglpbnQgcmM7CgoJcmVncy5lYXggPSBJOEtfU01NX1BPV0VSX1NUQVRVUzsKCWlmICgocmMgPSBpOGtfc21tKCZyZWdzKSkgPCAwKSB7CgkJcmV0dXJuIHJjOwoJfQoKCXN3aXRjaCAocmVncy5lYXggJiAweGZmKSB7CgljYXNlIEk4S19QT1dFUl9BQzoKCQlyZXR1cm4gSThLX0FDOwoJZGVmYXVsdDoKCQlyZXR1cm4gSThLX0JBVFRFUlk7Cgl9Cn0KCi8qCiAqIFJlYWQgdGhlIGZhbiBzdGF0dXMuCiAqLwpzdGF0aWMgaW50IGk4a19nZXRfZmFuX3N0YXR1cyhpbnQgZmFuKQp7CglTTU1SZWdpc3RlcnMgcmVncyA9IHsgMCwgMCwgMCwgMCwgMCwgMCB9OwoJaW50IHJjOwoKCXJlZ3MuZWF4ID0gSThLX1NNTV9HRVRfRkFOOwoJcmVncy5lYnggPSBmYW4gJiAweGZmOwoJaWYgKChyYyA9IGk4a19zbW0oJnJlZ3MpKSA8IDApIHsKCQlyZXR1cm4gcmM7Cgl9CgoJcmV0dXJuIChyZWdzLmVheCAmIDB4ZmYpOwp9CgovKgogKiBSZWFkIHRoZSBmYW4gc3BlZWQgaW4gUlBNLgogKi8Kc3RhdGljIGludCBpOGtfZ2V0X2Zhbl9zcGVlZChpbnQgZmFuKQp7CglTTU1SZWdpc3RlcnMgcmVncyA9IHsgMCwgMCwgMCwgMCwgMCwgMCB9OwoJaW50IHJjOwoKCXJlZ3MuZWF4ID0gSThLX1NNTV9HRVRfU1BFRUQ7CglyZWdzLmVieCA9IGZhbiAmIDB4ZmY7CglpZiAoKHJjID0gaThrX3NtbSgmcmVncykpIDwgMCkgewoJCXJldHVybiByYzsKCX0KCglyZXR1cm4gKHJlZ3MuZWF4ICYgMHhmZmZmKSAqIEk4S19GQU5fTVVMVDsKfQoKLyoKICogU2V0IHRoZSBmYW4gc3BlZWQgKG9mZiwgbG93LCBoaWdoKS4gUmV0dXJucyB0aGUgbmV3IGZhbiBzdGF0dXMuCiAqLwpzdGF0aWMgaW50IGk4a19zZXRfZmFuKGludCBmYW4sIGludCBzcGVlZCkKewoJU01NUmVnaXN0ZXJzIHJlZ3MgPSB7IDAsIDAsIDAsIDAsIDAsIDAgfTsKCWludCByYzsKCglzcGVlZCA9IChzcGVlZCA8IDApID8gMCA6ICgoc3BlZWQgPiBJOEtfRkFOX01BWCkgPyBJOEtfRkFOX01BWCA6IHNwZWVkKTsKCglyZWdzLmVheCA9IEk4S19TTU1fU0VUX0ZBTjsKCXJlZ3MuZWJ4ID0gKGZhbiAmIDB4ZmYpIHwgKHNwZWVkIDw8IDgpOwoJaWYgKChyYyA9IGk4a19zbW0oJnJlZ3MpKSA8IDApIHsKCQlyZXR1cm4gcmM7Cgl9CgoJcmV0dXJuIChpOGtfZ2V0X2Zhbl9zdGF0dXMoZmFuKSk7Cn0KCi8qCiAqIFJlYWQgdGhlIGNwdSB0ZW1wZXJhdHVyZS4KICovCnN0YXRpYyBpbnQgaThrX2dldF9jcHVfdGVtcCh2b2lkKQp7CglTTU1SZWdpc3RlcnMgcmVncyA9IHsgMCwgMCwgMCwgMCwgMCwgMCB9OwoJaW50IHJjOwoJaW50IHRlbXA7CgojaWZkZWYgSThLX1RFTVBFUkFUVVJFX0JVRwoJc3RhdGljIGludCBwcmV2ID0gMDsKI2VuZGlmCgoJcmVncy5lYXggPSBJOEtfU01NX0dFVF9URU1QOwoJaWYgKChyYyA9IGk4a19zbW0oJnJlZ3MpKSA8IDApIHsKCQlyZXR1cm4gcmM7Cgl9Cgl0ZW1wID0gcmVncy5lYXggJiAweGZmOwoKI2lmZGVmIEk4S19URU1QRVJBVFVSRV9CVUcKCS8qCgkgKiBTb21ldGltZXMgdGhlIHRlbXBlcmF0dXJlIHNlbnNvciByZXR1cm5zIDB4OTksIHdoaWNoIGlzIG91dCBvZiByYW5nZS4KCSAqIEluIHRoaXMgY2FzZSB3ZSByZXR1cm4gKG9uY2UpIHRoZSBwcmV2aW91cyBjYWNoZWQgdmFsdWUuIEZvciBleGFtcGxlOgoJICMgMTAwMzY1NTEzNyAwMDAwMDA1OCAwMDAwNWE0YgoJICMgMTAwMzY1NTEzOCAwMDAwMDA5OSAwMDAwM2E4MCA8LS0tIDB4OTkgPSAxNTMgZGVncmVlcwoJICMgMTAwMzY1NTEzOSAwMDAwMDA1NCAwMDAwNWM1MgoJICovCglpZiAodGVtcCA+IEk4S19NQVhfVEVNUCkgewoJCXRlbXAgPSBwcmV2OwoJCXByZXYgPSBJOEtfTUFYX1RFTVA7Cgl9IGVsc2UgewoJCXByZXYgPSB0ZW1wOwoJfQojZW5kaWYKCglyZXR1cm4gdGVtcDsKfQoKc3RhdGljIGludCBpOGtfZ2V0X2RlbGxfc2lnbmF0dXJlKHZvaWQpCnsKCVNNTVJlZ2lzdGVycyByZWdzID0geyAwLCAwLCAwLCAwLCAwLCAwIH07CglpbnQgcmM7CgoJcmVncy5lYXggPSBJOEtfU01NX0dFVF9ERUxMX1NJRzsKCWlmICgocmMgPSBpOGtfc21tKCZyZWdzKSkgPCAwKSB7CgkJcmV0dXJuIHJjOwoJfQoKCWlmICgocmVncy5lYXggPT0gMTE0NTY1MTUyNykgJiYgKHJlZ3MuZWR4ID09IDExNDUzOTIyMDQpKSB7CgkJcmV0dXJuIDA7Cgl9IGVsc2UgewoJCXJldHVybiAtMTsKCX0KfQoKc3RhdGljIGludCBpOGtfaW9jdGwoc3RydWN0IGlub2RlICppcCwgc3RydWN0IGZpbGUgKmZwLCB1bnNpZ25lZCBpbnQgY21kLAoJCSAgICAgdW5zaWduZWQgbG9uZyBhcmcpCnsKCWludCB2YWw7CglpbnQgc3BlZWQ7Cgl1bnNpZ25lZCBjaGFyIGJ1ZmZbMTZdOwoJaW50IF9fdXNlciAqYXJncCA9IChpbnQgX191c2VyICopYXJnOwoKCWlmICghYXJncCkKCQlyZXR1cm4gLUVJTlZBTDsKCglzd2l0Y2ggKGNtZCkgewoJY2FzZSBJOEtfQklPU19WRVJTSU9OOgoJCXZhbCA9IGk4a19nZXRfYmlvc192ZXJzaW9uKCk7CgkJYnJlYWs7CgoJY2FzZSBJOEtfTUFDSElORV9JRDoKCQltZW1zZXQoYnVmZiwgMCwgMTYpOwoJCXZhbCA9IGk4a19nZXRfc2VyaWFsX251bWJlcihidWZmKTsKCQlicmVhazsKCgljYXNlIEk4S19GTl9TVEFUVVM6CgkJdmFsID0gaThrX2dldF9mbl9zdGF0dXMoKTsKCQlicmVhazsKCgljYXNlIEk4S19QT1dFUl9TVEFUVVM6CgkJdmFsID0gaThrX2dldF9wb3dlcl9zdGF0dXMoKTsKCQlicmVhazsKCgljYXNlIEk4S19HRVRfVEVNUDoKCQl2YWwgPSBpOGtfZ2V0X2NwdV90ZW1wKCk7CgkJYnJlYWs7CgoJY2FzZSBJOEtfR0VUX1NQRUVEOgoJCWlmIChjb3B5X2Zyb21fdXNlcigmdmFsLCBhcmdwLCBzaXplb2YoaW50KSkpIHsKCQkJcmV0dXJuIC1FRkFVTFQ7CgkJfQoJCXZhbCA9IGk4a19nZXRfZmFuX3NwZWVkKHZhbCk7CgkJYnJlYWs7CgoJY2FzZSBJOEtfR0VUX0ZBTjoKCQlpZiAoY29weV9mcm9tX3VzZXIoJnZhbCwgYXJncCwgc2l6ZW9mKGludCkpKSB7CgkJCXJldHVybiAtRUZBVUxUOwoJCX0KCQl2YWwgPSBpOGtfZ2V0X2Zhbl9zdGF0dXModmFsKTsKCQlicmVhazsKCgljYXNlIEk4S19TRVRfRkFOOgoJCWlmIChyZXN0cmljdGVkICYmICFjYXBhYmxlKENBUF9TWVNfQURNSU4pKSB7CgkJCXJldHVybiAtRVBFUk07CgkJfQoJCWlmIChjb3B5X2Zyb21fdXNlcigmdmFsLCBhcmdwLCBzaXplb2YoaW50KSkpIHsKCQkJcmV0dXJuIC1FRkFVTFQ7CgkJfQoJCWlmIChjb3B5X2Zyb21fdXNlcigmc3BlZWQsIGFyZ3AgKyAxLCBzaXplb2YoaW50KSkpIHsKCQkJcmV0dXJuIC1FRkFVTFQ7CgkJfQoJCXZhbCA9IGk4a19zZXRfZmFuKHZhbCwgc3BlZWQpOwoJCWJyZWFrOwoKCWRlZmF1bHQ6CgkJcmV0dXJuIC1FSU5WQUw7Cgl9CgoJaWYgKHZhbCA8IDApIHsKCQlyZXR1cm4gdmFsOwoJfQoKCXN3aXRjaCAoY21kKSB7CgljYXNlIEk4S19CSU9TX1ZFUlNJT046CgkJaWYgKGNvcHlfdG9fdXNlcihhcmdwLCAmdmFsLCA0KSkgewoJCQlyZXR1cm4gLUVGQVVMVDsKCQl9CgkJYnJlYWs7CgljYXNlIEk4S19NQUNISU5FX0lEOgoJCWlmIChjb3B5X3RvX3VzZXIoYXJncCwgYnVmZiwgMTYpKSB7CgkJCXJldHVybiAtRUZBVUxUOwoJCX0KCQlicmVhazsKCWRlZmF1bHQ6CgkJaWYgKGNvcHlfdG9fdXNlcihhcmdwLCAmdmFsLCBzaXplb2YoaW50KSkpIHsKCQkJcmV0dXJuIC1FRkFVTFQ7CgkJfQoJCWJyZWFrOwoJfQoKCXJldHVybiAwOwp9CgovKgogKiBQcmludCB0aGUgaW5mb3JtYXRpb24gZm9yIC9wcm9jL2k4ay4KICovCnN0YXRpYyBpbnQgaThrX2dldF9pbmZvKGNoYXIgKmJ1ZmZlciwgY2hhciAqKnN0YXJ0LCBvZmZfdCBmcG9zLCBpbnQgbGVuZ3RoKQp7CglpbnQgbiwgZm5fa2V5LCBjcHVfdGVtcCwgYWNfcG93ZXI7CglpbnQgbGVmdF9mYW4sIHJpZ2h0X2ZhbiwgbGVmdF9zcGVlZCwgcmlnaHRfc3BlZWQ7CgoJY3B1X3RlbXAJPSBpOGtfZ2V0X2NwdV90ZW1wKCk7CQkJLyogMTExMDAgtXMgKi8KCWxlZnRfZmFuCT0gaThrX2dldF9mYW5fc3RhdHVzKEk4S19GQU5fTEVGVCk7CS8qICAgNTgwILVzICovCglyaWdodF9mYW4JPSBpOGtfZ2V0X2Zhbl9zdGF0dXMoSThLX0ZBTl9SSUdIVCk7CS8qICAgNTgwILVzICovCglsZWZ0X3NwZWVkCT0gaThrX2dldF9mYW5fc3BlZWQoSThLX0ZBTl9MRUZUKTsJLyogICA1ODAgtXMgKi8KCXJpZ2h0X3NwZWVkCT0gaThrX2dldF9mYW5fc3BlZWQoSThLX0ZBTl9SSUdIVCk7CS8qICAgNTgwILVzICovCglmbl9rZXkJCT0gaThrX2dldF9mbl9zdGF0dXMoKTsJCQkvKiAgIDc1MCC1cyAqLwoJaWYgKHBvd2VyX3N0YXR1cykgewoJCWFjX3Bvd2VyID0gaThrX2dldF9wb3dlcl9zdGF0dXMoKTsJCS8qIDE0NzAwILVzICovCgl9IGVsc2UgewoJCWFjX3Bvd2VyID0gLTE7Cgl9CgoJLyoKCSAqIEluZm86CgkgKgoJICogMSkgIEZvcm1hdCB2ZXJzaW9uICh0aGlzIHdpbGwgY2hhbmdlIGlmIGZvcm1hdCBjaGFuZ2VzKQoJICogMikgIEJJT1MgdmVyc2lvbgoJICogMykgIEJJT1MgbWFjaGluZSBJRAoJICogNCkgIENwdSB0ZW1wZXJhdHVyZQoJICogNSkgIExlZnQgZmFuIHN0YXR1cwoJICogNikgIFJpZ2h0IGZhbiBzdGF0dXMKCSAqIDcpICBMZWZ0IGZhbiBzcGVlZAoJICogOCkgIFJpZ2h0IGZhbiBzcGVlZAoJICogOSkgIEFDIHBvd2VyCgkgKiAxMCkgRm4gS2V5IHN0YXR1cwoJICovCgluID0gc3ByaW50ZihidWZmZXIsICIlcyAlcyAlcyAlZCAlZCAlZCAlZCAlZCAlZCAlZFxuIiwKCQkgICAgSThLX1BST0NfRk1ULAoJCSAgICBiaW9zX3ZlcnNpb24sCgkJICAgIHNlcmlhbF9udW1iZXIsCgkJICAgIGNwdV90ZW1wLAoJCSAgICBsZWZ0X2ZhbiwKCQkgICAgcmlnaHRfZmFuLCBsZWZ0X3NwZWVkLCByaWdodF9zcGVlZCwgYWNfcG93ZXIsIGZuX2tleSk7CgoJcmV0dXJuIG47Cn0KCnN0YXRpYyBzc2l6ZV90IGk4a19yZWFkKHN0cnVjdCBmaWxlICpmLCBjaGFyIF9fdXNlciAqIGJ1ZmZlciwgc2l6ZV90IGxlbiwKCQkJbG9mZl90ICogZnBvcykKewoJaW50IG47CgljaGFyIGluZm9bMTI4XTsKCgluID0gaThrX2dldF9pbmZvKGluZm8sIE5VTEwsIDAsIDEyOCk7CglpZiAobiA8PSAwKSB7CgkJcmV0dXJuIG47Cgl9CgoJaWYgKCpmcG9zID49IG4pIHsKCQlyZXR1cm4gMDsKCX0KCglpZiAoKCpmcG9zICsgbGVuKSA+PSBuKSB7CgkJbGVuID0gbiAtICpmcG9zOwoJfQoKCWlmIChjb3B5X3RvX3VzZXIoYnVmZmVyLCBpbmZvLCBsZW4pICE9IDApIHsKCQlyZXR1cm4gLUVGQVVMVDsKCX0KCgkqZnBvcyArPSBsZW47CglyZXR1cm4gbGVuOwp9CgpzdGF0aWMgY2hhciAqX19pbml0IHN0cmluZ190cmltKGNoYXIgKnMsIGludCBzaXplKQp7CglpbnQgbGVuOwoJY2hhciAqcDsKCglpZiAoKGxlbiA9IHN0cmxlbihzKSkgPiBzaXplKSB7CgkJbGVuID0gc2l6ZTsKCX0KCglmb3IgKHAgPSBzICsgbGVuIC0gMTsgbGVuICYmICgqcCA9PSAnICcpOyBsZW4tLSwgcC0tKSB7CgkJKnAgPSAnXDAnOwoJfQoKCXJldHVybiBzOwp9CgovKiBETUkgY29kZSwgc3RvbGVuIGZyb20gYXJjaC9pMzg2L2tlcm5lbC9kbWlfc2Nhbi5jICovCgovKgogKiB8PC0tIGRtaS0+bGVuZ3RoIC0tPnwKICogfCAgICAgICAgICAgICAgICAgICB8CiAqIHxkbWkgaGVhZGVyICAgIHM9TiAgfCBzdHJpbmcxLFwwLCAuLi4sIHN0cmluZ04sXDAsIC4uLiwgXDAKICogICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgfAogKiAgICAgICAgICAgICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCiAqLwpzdGF0aWMgY2hhciAqX19pbml0IGRtaV9zdHJpbmcoRE1JSGVhZGVyICogZG1pLCB1OCBzKQp7Cgl1OCAqcDsKCglpZiAoIXMpIHsKCQlyZXR1cm4gIiI7Cgl9CglzLS07CgoJcCA9ICh1OCAqKSBkbWkgKyBkbWktPmxlbmd0aDsKCXdoaWxlIChzID4gMCkgewoJCXAgKz0gc3RybGVuKHApOwoJCXArKzsKCQlzLS07Cgl9CgoJcmV0dXJuIHA7Cn0KCnN0YXRpYyB2b2lkIF9faW5pdCBkbWlfZGVjb2RlKERNSUhlYWRlciAqIGRtaSkKewoJdTggKmRhdGEgPSAodTggKikgZG1pOwoJY2hhciAqcDsKCiNpZmRlZiBJOEtfREVCVUcKCWludCBpOwoJcHJpbnRrKCIlMDh4ICIsIChpbnQpZGF0YSk7Cglmb3IgKGkgPSAwOyBpIDwgZGF0YVsxXSAmJiBpIDwgNjQ7IGkrKykgewoJCXByaW50aygiJTAyeCAiLCBkYXRhW2ldKTsKCX0KCXByaW50aygiXG4iKTsKI2VuZGlmCgoJc3dpdGNoIChkbWktPnR5cGUpIHsKCWNhc2UgMDoJCS8qIEJJT1MgSW5mb3JtYXRpb24gKi8KCQlwID0gZG1pX3N0cmluZyhkbWksIGRhdGFbNV0pOwoJCWlmICgqcCkgewoJCQlzdHJsY3B5KGJpb3NfdmVyc2lvbiwgcCwgc2l6ZW9mKGJpb3NfdmVyc2lvbikpOwoJCQlzdHJpbmdfdHJpbShiaW9zX3ZlcnNpb24sIHNpemVvZihiaW9zX3ZlcnNpb24pKTsKCQl9CgkJYnJlYWs7CgljYXNlIDE6CQkvKiBTeXN0ZW0gSW5mb3JtYXRpb24gKi8KCQlwID0gZG1pX3N0cmluZyhkbWksIGRhdGFbNF0pOwoJCWlmICgqcCkgewoJCQlzdHJsY3B5KHN5c3RlbV92ZW5kb3IsIHAsIHNpemVvZihzeXN0ZW1fdmVuZG9yKSk7CgkJCXN0cmluZ190cmltKHN5c3RlbV92ZW5kb3IsIHNpemVvZihzeXN0ZW1fdmVuZG9yKSk7CgkJfQoJCXAgPSBkbWlfc3RyaW5nKGRtaSwgZGF0YVs1XSk7CgkJaWYgKCpwKSB7CgkJCXN0cmxjcHkocHJvZHVjdF9uYW1lLCBwLCBzaXplb2YocHJvZHVjdF9uYW1lKSk7CgkJCXN0cmluZ190cmltKHByb2R1Y3RfbmFtZSwgc2l6ZW9mKHByb2R1Y3RfbmFtZSkpOwoJCX0KCQlwID0gZG1pX3N0cmluZyhkbWksIGRhdGFbN10pOwoJCWlmICgqcCkgewoJCQlzdHJsY3B5KHNlcmlhbF9udW1iZXIsIHAsIHNpemVvZihzZXJpYWxfbnVtYmVyKSk7CgkJCXN0cmluZ190cmltKHNlcmlhbF9udW1iZXIsIHNpemVvZihzZXJpYWxfbnVtYmVyKSk7CgkJfQoJCWJyZWFrOwoJfQp9CgpzdGF0aWMgaW50IF9faW5pdCBkbWlfdGFibGUodTMyIGJhc2UsIGludCBsZW4sIGludCBudW0sCgkJCSAgICB2b2lkICgqZm4pIChETUlIZWFkZXIgKikpCnsKCXU4ICpidWY7Cgl1OCAqZGF0YTsKCURNSUhlYWRlciAqZG1pOwoJaW50IGkgPSAxOwoKCWJ1ZiA9IGlvcmVtYXAoYmFzZSwgbGVuKTsKCWlmIChidWYgPT0gTlVMTCkgewoJCXJldHVybiAtMTsKCX0KCWRhdGEgPSBidWY7CgoJLyoKCSAqIFN0b3Agd2hlbiB3ZSBzZWUgYWwgdGhlIGl0ZW1zIHRoZSB0YWJsZSBjbGFpbWVkIHRvIGhhdmUKCSAqIG9yIHdlIHJ1biBvZmYgdGhlIGVuZCBvZiB0aGUgdGFibGUgKGFsc28gaGFwcGVucykKCSAqLwoJd2hpbGUgKChpIDwgbnVtKSAmJiAoKGRhdGEgLSBidWYpIDwgbGVuKSkgewoJCWRtaSA9IChETUlIZWFkZXIgKikgZGF0YTsKCQkvKgoJCSAqIEF2b2lkIG1pc3BhcnNpbmcgY3J1ZCBpZiB0aGUgbGVuZ3RoIG9mIHRoZSBsYXN0CgkJICogcmVjb3JkIGlzIGNyYXAKCQkgKi8KCQlpZiAoKGRhdGEgLSBidWYgKyBkbWktPmxlbmd0aCkgPj0gbGVuKSB7CgkJCWJyZWFrOwoJCX0KCQlmbihkbWkpOwoJCWRhdGEgKz0gZG1pLT5sZW5ndGg7CgkJLyoKCQkgKiBEb24ndCBnbyBvZmYgdGhlIGVuZCBvZiB0aGUgZGF0YSBpZiB0aGVyZSBpcwoJCSAqIHN0dWZmIGxvb2tpbmcgbGlrZSBzdHJpbmcgZmlsbCBwYXN0IHRoZSBlbmQKCQkgKi8KCQl3aGlsZSAoKChkYXRhIC0gYnVmKSA8IGxlbikgJiYgKCpkYXRhIHx8IGRhdGFbMV0pKSB7CgkJCWRhdGErKzsKCQl9CgkJZGF0YSArPSAyOwoJCWkrKzsKCX0KCWlvdW5tYXAoYnVmKTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBfX2luaXQgZG1pX2l0ZXJhdGUodm9pZCAoKmRlY29kZSkgKERNSUhlYWRlciAqKSkKewoJdW5zaWduZWQgY2hhciBidWZbMjBdOwoJdm9pZCBfX2lvbWVtICpwID0gaW9yZW1hcCgweGUwMDAwLCAweDIwMDAwKSwgKnE7CgoJaWYgKCFwKQoJCXJldHVybiAtMTsKCglmb3IgKHEgPSBwOyBxIDwgcCArIDB4MjAwMDA7IHEgKz0gMTYpIHsKCQltZW1jcHlfZnJvbWlvKGJ1ZiwgcSwgMjApOwoJCWlmIChtZW1jbXAoYnVmLCAiX0RNSV8iLCA1KSA9PSAwKSB7CgkJCXUxNiBudW0gID0gYnVmWzEzXSA8PCA4IHwgYnVmWzEyXTsKCQkJdTE2IGxlbiAgPSBidWZbN10gPDwgOCB8IGJ1Zls2XTsKCQkJdTMyIGJhc2UgPSBidWZbMTFdIDw8IDI0IHwgYnVmWzEwXSA8PCAxNiB8IGJ1Zls5XSA8PCA4IHwgYnVmWzhdOwojaWZkZWYgSThLX0RFQlVHCgkJCXByaW50ayhLRVJOX0lORk8gIkRNSSAlZC4lZCBwcmVzZW50LlxuIiwKCQkJICAgICAgIGJ1ZlsxNF0gPj4gNCwgYnVmWzE0XSAmIDB4MEYpOwoJCQlwcmludGsoS0VSTl9JTkZPICIlZCBzdHJ1Y3R1cmVzIG9jY3VweWluZyAlZCBieXRlcy5cbiIsCgkJCSAgICAgICBidWZbMTNdIDw8IDggfCBidWZbMTJdLCBidWZbN10gPDwgOCB8IGJ1Zls2XSk7CgkJCXByaW50ayhLRVJOX0lORk8gIkRNSSB0YWJsZSBhdCAweCUwOFguXG4iLAoJCQkgICAgICAgYnVmWzExXSA8PCAyNCB8IGJ1ZlsxMF0gPDwgMTYgfCBidWZbOV0gPDwgOCB8CgkJCSAgICAgICBidWZbOF0pOwojZW5kaWYKCQkJaWYgKGRtaV90YWJsZShiYXNlLCBsZW4sIG51bSwgZGVjb2RlKSA9PSAwKSB7CgkJCQlpb3VubWFwKHApOwoJCQkJcmV0dXJuIDA7CgkJCX0KCQl9Cgl9Cglpb3VubWFwKHApOwoJcmV0dXJuIC0xOwp9CgovKiBlbmQgb2YgRE1JIGNvZGUgKi8KCi8qCiAqIEdldCBETUkgaW5mb3JtYXRpb24uCiAqLwpzdGF0aWMgaW50IF9faW5pdCBpOGtfZG1pX3Byb2JlKHZvaWQpCnsKCWNoYXIgKipwOwoKCWlmIChkbWlfaXRlcmF0ZShkbWlfZGVjb2RlKSAhPSAwKSB7CgkJcHJpbnRrKEtFUk5fSU5GTyAiaThrOiB1bmFibGUgdG8gZ2V0IERNSSBpbmZvcm1hdGlvblxuIik7CgkJcmV0dXJuIC1FTk9ERVY7Cgl9CgoJaWYgKHN0cm5jbXAoc3lzdGVtX3ZlbmRvciwgREVMTF9TSUdOQVRVUkUsIHN0cmxlbihERUxMX1NJR05BVFVSRSkpICE9IDApIHsKCQlwcmludGsoS0VSTl9JTkZPICJpOGs6IG5vdCBydW5uaW5nIG9uIGEgRGVsbCBzeXN0ZW1cbiIpOwoJCXJldHVybiAtRU5PREVWOwoJfQoKCWZvciAocCA9IHN1cHBvcnRlZF9tb2RlbHM7OyBwKyspIHsKCQlpZiAoISpwKSB7CgkJCXByaW50ayhLRVJOX0lORk8gImk4azogdW5zdXBwb3J0ZWQgbW9kZWw6ICVzXG4iLAoJCQkgICAgICAgcHJvZHVjdF9uYW1lKTsKCQkJcmV0dXJuIC1FTk9ERVY7CgkJfQoJCWlmIChzdHJuY21wKHByb2R1Y3RfbmFtZSwgKnAsIHN0cmxlbigqcCkpID09IDApIHsKCQkJYnJlYWs7CgkJfQoJfQoKCXJldHVybiAwOwp9CgovKgogKiBQcm9iZSBmb3IgdGhlIHByZXNlbmNlIG9mIGEgc3VwcG9ydGVkIGxhcHRvcC4KICovCnN0YXRpYyBpbnQgX19pbml0IGk4a19wcm9iZSh2b2lkKQp7CgljaGFyIGJ1ZmZbNF07CglpbnQgdmVyc2lvbjsKCWludCBzbW1fZm91bmQgPSAwOwoKCS8qCgkgKiBHZXQgRE1JIGluZm9ybWF0aW9uCgkgKi8KCWlmIChpOGtfZG1pX3Byb2JlKCkgIT0gMCkgewoJCXByaW50ayhLRVJOX0lORk8gImk4azogdmVuZG9yPSVzLCBtb2RlbD0lcywgdmVyc2lvbj0lc1xuIiwKCQkgICAgICAgc3lzdGVtX3ZlbmRvciwgcHJvZHVjdF9uYW1lLCBiaW9zX3ZlcnNpb24pOwoJfQoKCS8qCgkgKiBHZXQgU01NIERlbGwgc2lnbmF0dXJlCgkgKi8KCWlmIChpOGtfZ2V0X2RlbGxfc2lnbmF0dXJlKCkgIT0gMCkgewoJCXByaW50ayhLRVJOX0lORk8gImk4azogdW5hYmxlIHRvIGdldCBTTU0gRGVsbCBzaWduYXR1cmVcbiIpOwoJfSBlbHNlIHsKCQlzbW1fZm91bmQgPSAxOwoJfQoKCS8qCgkgKiBHZXQgU01NIEJJT1MgdmVyc2lvbi4KCSAqLwoJdmVyc2lvbiA9IGk4a19nZXRfYmlvc192ZXJzaW9uKCk7CglpZiAodmVyc2lvbiA8PSAwKSB7CgkJcHJpbnRrKEtFUk5fSU5GTyAiaThrOiB1bmFibGUgdG8gZ2V0IFNNTSBCSU9TIHZlcnNpb25cbiIpOwoJfSBlbHNlIHsKCQlzbW1fZm91bmQgPSAxOwoJCWJ1ZmZbMF0gPSAodmVyc2lvbiA+PiAxNikgJiAweGZmOwoJCWJ1ZmZbMV0gPSAodmVyc2lvbiA+PiA4KSAmIDB4ZmY7CgkJYnVmZlsyXSA9ICh2ZXJzaW9uKSAmIDB4ZmY7CgkJYnVmZlszXSA9ICdcMCc7CgkJLyoKCQkgKiBJZiBETUkgQklPUyB2ZXJzaW9uIGlzIHVua25vd24gdXNlIFNNTSBCSU9TIHZlcnNpb24uCgkJICovCgkJaWYgKGJpb3NfdmVyc2lvblswXSA9PSAnPycpIHsKCQkJc3RyY3B5KGJpb3NfdmVyc2lvbiwgYnVmZik7CgkJfQoJCS8qCgkJICogQ2hlY2sgaWYgdGhlIHR3byB2ZXJzaW9ucyBtYXRjaC4KCQkgKi8KCQlpZiAoc3RybmNtcChidWZmLCBiaW9zX3ZlcnNpb24sIHNpemVvZihiaW9zX3ZlcnNpb24pKSAhPSAwKSB7CgkJCXByaW50ayhLRVJOX0lORk8KCQkJICAgICAgICJpOGs6IEJJT1MgdmVyc2lvbiBtaXNtYXRjaDogJXMgIT0gJXNcbiIsIGJ1ZmYsCgkJCSAgICAgICBiaW9zX3ZlcnNpb24pOwoJCX0KCX0KCglpZiAoIXNtbV9mb3VuZCAmJiAhZm9yY2UpIHsKCQlyZXR1cm4gLUVOT0RFVjsKCX0KCglyZXR1cm4gMDsKfQoKI2lmZGVmIE1PRFVMRQpzdGF0aWMKI2VuZGlmCmludCBfX2luaXQgaThrX2luaXQodm9pZCkKewoJc3RydWN0IHByb2NfZGlyX2VudHJ5ICpwcm9jX2k4azsKCgkvKiBBcmUgd2UgcnVubmluZyBvbiBhbiBzdXBwb3J0ZWQgbGFwdG9wPyAqLwoJaWYgKGk4a19wcm9iZSgpICE9IDApIHsKCQlyZXR1cm4gLUVOT0RFVjsKCX0KCgkvKiBSZWdpc3RlciB0aGUgcHJvYyBlbnRyeSAqLwoJcHJvY19pOGsgPSBjcmVhdGVfcHJvY19pbmZvX2VudHJ5KCJpOGsiLCAwLCBOVUxMLCBpOGtfZ2V0X2luZm8pOwoJaWYgKCFwcm9jX2k4aykgewoJCXJldHVybiAtRU5PRU5UOwoJfQoJcHJvY19pOGstPnByb2NfZm9wcyA9ICZpOGtfZm9wczsKCXByb2NfaThrLT5vd25lciA9IFRISVNfTU9EVUxFOwoKCXByaW50ayhLRVJOX0lORk8KCSAgICAgICAiRGVsbCBsYXB0b3AgU01NIGRyaXZlciB2JXMgTWFzc2ltbyBEYWwgWm90dG8gKGR6QGRlYmlhbi5vcmcpXG4iLAoJICAgICAgIEk4S19WRVJTSU9OKTsKCglyZXR1cm4gMDsKfQoKI2lmZGVmIE1PRFVMRQppbnQgaW5pdF9tb2R1bGUodm9pZCkKewoJcmV0dXJuIGk4a19pbml0KCk7Cn0KCnZvaWQgY2xlYW51cF9tb2R1bGUodm9pZCkKewoJLyogUmVtb3ZlIHRoZSBwcm9jIGVudHJ5ICovCglyZW1vdmVfcHJvY19lbnRyeSgiaThrIiwgTlVMTCk7CgoJcHJpbnRrKEtFUk5fSU5GTyAiaThrOiBtb2R1bGUgdW5sb2FkZWRcbiIpOwp9CiNlbmRpZgoKLyogZW5kIG9mIGZpbGUgKi8K