LyoKICogbGludXgvYXJjaC9hcm0vb21hcC9kbWEuYwogKgogKiBDb3B5cmlnaHQgKEMpIDIwMDMgTm9raWEgQ29ycG9yYXRpb24KICogQXV0aG9yOiBKdWhhIFlyavZs5CA8anVoYS55cmpvbGFAbm9raWEuY29tPgogKiBETUEgY2hhbm5lbCBsaW5raW5nIGZvciAxNjEwIGJ5IFNhbXVlbCBPcnRpeiA8c2FtdWVsLm9ydGl6QG5va2lhLmNvbT4KICogR3JhcGhpY3MgRE1BIGFuZCBMQ0QgRE1BIGdyYXBoaWNzIHRyYW5mb3JtYXRpb25zCiAqIGJ5IEltcmUgRGVhayA8aW1yZS5kZWFrQG5va2lhLmNvbT4KICogU29tZSBmdW5jdGlvbnMgYmFzZWQgb24gZWFybGllciBkbWEtb21hcC5jIENvcHlyaWdodCAoQykgMjAwMSBSaWRnZVJ1biwgSW5jLgogKgogKiBTdXBwb3J0IGZ1bmN0aW9ucyBmb3IgdGhlIE9NQVAgaW50ZXJuYWwgRE1BIGNoYW5uZWxzLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KICoKICovCgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxsaW51eC9zY2hlZC5oPgojaW5jbHVkZSA8bGludXgvc3BpbmxvY2suaD4KI2luY2x1ZGUgPGxpbnV4L2Vycm5vLmg+CiNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KCiNpbmNsdWRlIDxhc20vc3lzdGVtLmg+CiNpbmNsdWRlIDxhc20vaXJxLmg+CiNpbmNsdWRlIDxhc20vaGFyZHdhcmUuaD4KI2luY2x1ZGUgPGFzbS9kbWEuaD4KI2luY2x1ZGUgPGFzbS9pby5oPgoKI2luY2x1ZGUgPGFzbS9hcmNoL3RjLmg+CgojZGVmaW5lIE9NQVBfRE1BX0FDVElWRQkJMHgwMQoKI2RlZmluZSBPTUFQX0RNQV9DQ1JfRU4JCSgxIDw8IDcpCgojZGVmaW5lIE9NQVBfRlVOQ19NVVhfQVJNX0JBU0UJKDB4ZmZmZTEwMDAgKyAweGVjKQoKc3RhdGljIGludCBlbmFibGVfMTUxMF9tb2RlID0gMDsKCnN0cnVjdCBvbWFwX2RtYV9sY2ggewoJaW50IG5leHRfbGNoOwoJaW50IGRldl9pZDsKCXUxNiBzYXZlZF9jc3I7Cgl1MTYgZW5hYmxlZF9pcnFzOwoJY29uc3QgY2hhciAqZGV2X25hbWU7Cgl2b2lkICgqIGNhbGxiYWNrKShpbnQgbGNoLCB1MTYgY2hfc3RhdHVzLCB2b2lkICpkYXRhKTsKCXZvaWQgKmRhdGE7Cglsb25nIGZsYWdzOwp9OwoKc3RhdGljIGludCBkbWFfY2hhbl9jb3VudDsKCnN0YXRpYyBzcGlubG9ja190IGRtYV9jaGFuX2xvY2s7CnN0YXRpYyBzdHJ1Y3Qgb21hcF9kbWFfbGNoIGRtYV9jaGFuW09NQVBfTE9HSUNBTF9ETUFfQ0hfQ09VTlRdOwoKY29uc3Qgc3RhdGljIHU4IGRtYV9pcnFbT01BUF9MT0dJQ0FMX0RNQV9DSF9DT1VOVF0gPSB7CglJTlRfRE1BX0NIMF82LCBJTlRfRE1BX0NIMV83LCBJTlRfRE1BX0NIMl84LCBJTlRfRE1BX0NIMywKCUlOVF9ETUFfQ0g0LCBJTlRfRE1BX0NINSwgSU5UXzE2MTBfRE1BX0NINiwgSU5UXzE2MTBfRE1BX0NINywKCUlOVF8xNjEwX0RNQV9DSDgsIElOVF8xNjEwX0RNQV9DSDksIElOVF8xNjEwX0RNQV9DSDEwLAoJSU5UXzE2MTBfRE1BX0NIMTEsIElOVF8xNjEwX0RNQV9DSDEyLCBJTlRfMTYxMF9ETUFfQ0gxMywKCUlOVF8xNjEwX0RNQV9DSDE0LCBJTlRfMTYxMF9ETUFfQ0gxNSwgSU5UX0RNQV9MQ0QKfTsKCnN0YXRpYyBpbmxpbmUgaW50IGdldF9nZG1hX2RldihpbnQgcmVxKQp7Cgl1MzIgcmVnID0gT01BUF9GVU5DX01VWF9BUk1fQkFTRSArICgocmVxIC0gMSkgLyA1KSAqIDQ7CglpbnQgc2hpZnQgPSAoKHJlcSAtIDEpICUgNSkgKiA2OwoKCXJldHVybiAoKG9tYXBfcmVhZGwocmVnKSA+PiBzaGlmdCkgJiAweDNmKSArIDE7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBzZXRfZ2RtYV9kZXYoaW50IHJlcSwgaW50IGRldikKewoJdTMyIHJlZyA9IE9NQVBfRlVOQ19NVVhfQVJNX0JBU0UgKyAoKHJlcSAtIDEpIC8gNSkgKiA0OwoJaW50IHNoaWZ0ID0gKChyZXEgLSAxKSAlIDUpICogNjsKCXUzMiBsOwoKCWwgPSBvbWFwX3JlYWRsKHJlZyk7CglsICY9IH4oMHgzZiA8PCBzaGlmdCk7CglsIHw9IChkZXYgLSAxKSA8PCBzaGlmdDsKCW9tYXBfd3JpdGVsKGwsIHJlZyk7Cn0KCnN0YXRpYyB2b2lkIGNsZWFyX2xjaF9yZWdzKGludCBsY2gpCnsKCWludCBpOwoJdTMyIGxjaF9iYXNlID0gT01BUF9ETUFfQkFTRSArIGxjaCAqIDB4NDA7CgoJZm9yIChpID0gMDsgaSA8IDB4MmM7IGkgKz0gMikKCQlvbWFwX3dyaXRldygwLCBsY2hfYmFzZSArIGkpOwp9Cgp2b2lkIG9tYXBfc2V0X2RtYV9wcmlvcml0eShpbnQgZHN0X3BvcnQsIGludCBwcmlvcml0eSkKewoJdW5zaWduZWQgbG9uZyByZWc7Cgl1MzIgbDsKCglzd2l0Y2ggKGRzdF9wb3J0KSB7CgljYXNlIE9NQVBfRE1BX1BPUlRfT0NQX1QxOgkvKiBGRkZFQ0MwMCAqLwoJCXJlZyA9IE9NQVBfVENfT0NQVDFfUFJJT1I7CgkJYnJlYWs7CgljYXNlIE9NQVBfRE1BX1BPUlRfT0NQX1QyOgkvKiBGRkZFQ0NEMCAqLwoJCXJlZyA9IE9NQVBfVENfT0NQVDJfUFJJT1I7CgkJYnJlYWs7CgljYXNlIE9NQVBfRE1BX1BPUlRfRU1JRkY6CS8qIEZGRkVDQzA4ICovCgkJcmVnID0gT01BUF9UQ19FTUlGRl9QUklPUjsKCQlicmVhazsKCWNhc2UgT01BUF9ETUFfUE9SVF9FTUlGUzoJLyogRkZGRUNDMDQgKi8KCQlyZWcgPSBPTUFQX1RDX0VNSUZTX1BSSU9SOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlCVUcoKTsKCQlyZXR1cm47Cgl9CglsID0gb21hcF9yZWFkbChyZWcpOwoJbCAmPSB+KDB4ZiA8PCA4KTsKCWwgfD0gKHByaW9yaXR5ICYgMHhmKSA8PCA4OwoJb21hcF93cml0ZWwobCwgcmVnKTsKfQoKdm9pZCBvbWFwX3NldF9kbWFfdHJhbnNmZXJfcGFyYW1zKGludCBsY2gsIGludCBkYXRhX3R5cGUsIGludCBlbGVtX2NvdW50LAoJCQkJICBpbnQgZnJhbWVfY291bnQsIGludCBzeW5jX21vZGUpCnsKCXUxNiB3OwoKCXcgPSBvbWFwX3JlYWR3KE9NQVBfRE1BX0NTRFAobGNoKSk7Cgl3ICY9IH4weDAzOwoJdyB8PSBkYXRhX3R5cGU7CglvbWFwX3dyaXRldyh3LCBPTUFQX0RNQV9DU0RQKGxjaCkpOwoKCXcgPSBvbWFwX3JlYWR3KE9NQVBfRE1BX0NDUihsY2gpKTsKCXcgJj0gfigxIDw8IDUpOwoJaWYgKHN5bmNfbW9kZSA9PSBPTUFQX0RNQV9TWU5DX0ZSQU1FKQoJCXcgfD0gMSA8PCA1OwoJb21hcF93cml0ZXcodywgT01BUF9ETUFfQ0NSKGxjaCkpOwoKCXcgPSBvbWFwX3JlYWR3KE9NQVBfRE1BX0NDUjIobGNoKSk7Cgl3ICY9IH4oMSA8PCAyKTsKCWlmIChzeW5jX21vZGUgPT0gT01BUF9ETUFfU1lOQ19CTE9DSykKCQl3IHw9IDEgPDwgMjsKCW9tYXBfd3JpdGV3KHcsIE9NQVBfRE1BX0NDUjIobGNoKSk7CgoJb21hcF93cml0ZXcoZWxlbV9jb3VudCwgT01BUF9ETUFfQ0VOKGxjaCkpOwoJb21hcF93cml0ZXcoZnJhbWVfY291bnQsIE9NQVBfRE1BX0NGTihsY2gpKTsKCn0Kdm9pZCBvbWFwX3NldF9kbWFfY29sb3JfbW9kZShpbnQgbGNoLCBlbnVtIG9tYXBfZG1hX2NvbG9yX21vZGUgbW9kZSwgdTMyIGNvbG9yKQp7Cgl1MTYgdzsKCglCVUdfT04ob21hcF9kbWFfaW5fMTUxMF9tb2RlKCkpOwoKCXcgPSBvbWFwX3JlYWR3KE9NQVBfRE1BX0NDUjIobGNoKSkgJiB+MHgwMzsKCXN3aXRjaCAobW9kZSkgewoJY2FzZSBPTUFQX0RNQV9DT05TVEFOVF9GSUxMOgoJCXcgfD0gMHgwMTsKCQlicmVhazsKCWNhc2UgT01BUF9ETUFfVFJBTlNQQVJFTlRfQ09QWToKCQl3IHw9IDB4MDI7CgkJYnJlYWs7CgljYXNlIE9NQVBfRE1BX0NPTE9SX0RJUzoKCQlicmVhazsKCWRlZmF1bHQ6CgkJQlVHKCk7Cgl9CglvbWFwX3dyaXRldyh3LCBPTUFQX0RNQV9DQ1IyKGxjaCkpOwoKCXcgPSBvbWFwX3JlYWR3KE9NQVBfRE1BX0xDSF9DVFJMKGxjaCkpICYgfjB4MGY7CgkvKiBEZWZhdWx0IGlzIGNoYW5uZWwgdHlwZSAyRCAqLwoJaWYgKG1vZGUpIHsKCQlvbWFwX3dyaXRldygodTE2KWNvbG9yLCBPTUFQX0RNQV9DT0xPUl9MKGxjaCkpOwoJCW9tYXBfd3JpdGV3KCh1MTYpKGNvbG9yID4+IDE2KSwgT01BUF9ETUFfQ09MT1JfVShsY2gpKTsKCQl3IHw9IDE7CQkvKiBDaGFubmVsIHR5cGUgRyAqLwoJfQoJb21hcF93cml0ZXcodywgT01BUF9ETUFfTENIX0NUUkwobGNoKSk7Cn0KCgp2b2lkIG9tYXBfc2V0X2RtYV9zcmNfcGFyYW1zKGludCBsY2gsIGludCBzcmNfcG9ydCwgaW50IHNyY19hbW9kZSwKCQkJICAgICB1bnNpZ25lZCBsb25nIHNyY19zdGFydCkKewoJdTE2IHc7CgoJdyA9IG9tYXBfcmVhZHcoT01BUF9ETUFfQ1NEUChsY2gpKTsKCXcgJj0gfigweDFmIDw8IDIpOwoJdyB8PSBzcmNfcG9ydCA8PCAyOwoJb21hcF93cml0ZXcodywgT01BUF9ETUFfQ1NEUChsY2gpKTsKCgl3ID0gb21hcF9yZWFkdyhPTUFQX0RNQV9DQ1IobGNoKSk7Cgl3ICY9IH4oMHgwMyA8PCAxMik7Cgl3IHw9IHNyY19hbW9kZSA8PCAxMjsKCW9tYXBfd3JpdGV3KHcsIE9NQVBfRE1BX0NDUihsY2gpKTsKCglvbWFwX3dyaXRldyhzcmNfc3RhcnQgPj4gMTYsIE9NQVBfRE1BX0NTU0FfVShsY2gpKTsKCW9tYXBfd3JpdGV3KHNyY19zdGFydCwgT01BUF9ETUFfQ1NTQV9MKGxjaCkpOwp9Cgp2b2lkIG9tYXBfc2V0X2RtYV9zcmNfaW5kZXgoaW50IGxjaCwgaW50IGVpZHgsIGludCBmaWR4KQp7CglvbWFwX3dyaXRldyhlaWR4LCBPTUFQX0RNQV9DU0VJKGxjaCkpOwoJb21hcF93cml0ZXcoZmlkeCwgT01BUF9ETUFfQ1NGSShsY2gpKTsKfQoKdm9pZCBvbWFwX3NldF9kbWFfc3JjX2RhdGFfcGFjayhpbnQgbGNoLCBpbnQgZW5hYmxlKQp7Cgl1MTYgdzsKCgl3ID0gb21hcF9yZWFkdyhPTUFQX0RNQV9DU0RQKGxjaCkpICYgfigxIDw8IDYpOwoJdyB8PSBlbmFibGUgPyAoMSA8PCA2KSA6IDA7CglvbWFwX3dyaXRldyh3LCBPTUFQX0RNQV9DU0RQKGxjaCkpOwp9Cgp2b2lkIG9tYXBfc2V0X2RtYV9zcmNfYnVyc3RfbW9kZShpbnQgbGNoLCBlbnVtIG9tYXBfZG1hX2J1cnN0X21vZGUgYnVyc3RfbW9kZSkKewoJdTE2IHc7CgoJdyA9IG9tYXBfcmVhZHcoT01BUF9ETUFfQ1NEUChsY2gpKSAmIH4oMHgwMyA8PCA3KTsKCXN3aXRjaCAoYnVyc3RfbW9kZSkgewoJY2FzZSBPTUFQX0RNQV9EQVRBX0JVUlNUX0RJUzoKCQlicmVhazsKCWNhc2UgT01BUF9ETUFfREFUQV9CVVJTVF80OgoJCXcgfD0gKDB4MDEgPDwgNyk7CgkJYnJlYWs7CgljYXNlIE9NQVBfRE1BX0RBVEFfQlVSU1RfODoKCQkvKiBub3Qgc3VwcG9ydGVkIGJ5IGN1cnJlbnQgaGFyZHdhcmUKCQkgKiB3IHw9ICgweDAzIDw8IDcpOwoJCSAqIGZhbGwgdGhyb3VnaAoJCSAqLwoJZGVmYXVsdDoKCQlCVUcoKTsKCX0KCW9tYXBfd3JpdGV3KHcsIE9NQVBfRE1BX0NTRFAobGNoKSk7Cn0KCnZvaWQgb21hcF9zZXRfZG1hX2Rlc3RfcGFyYW1zKGludCBsY2gsIGludCBkZXN0X3BvcnQsIGludCBkZXN0X2Ftb2RlLAoJCQkgICAgICB1bnNpZ25lZCBsb25nIGRlc3Rfc3RhcnQpCnsKCXUxNiB3OwoKCXcgPSBvbWFwX3JlYWR3KE9NQVBfRE1BX0NTRFAobGNoKSk7Cgl3ICY9IH4oMHgxZiA8PCA5KTsKCXcgfD0gZGVzdF9wb3J0IDw8IDk7CglvbWFwX3dyaXRldyh3LCBPTUFQX0RNQV9DU0RQKGxjaCkpOwoKCXcgPSBvbWFwX3JlYWR3KE9NQVBfRE1BX0NDUihsY2gpKTsKCXcgJj0gfigweDAzIDw8IDE0KTsKCXcgfD0gZGVzdF9hbW9kZSA8PCAxNDsKCW9tYXBfd3JpdGV3KHcsIE9NQVBfRE1BX0NDUihsY2gpKTsKCglvbWFwX3dyaXRldyhkZXN0X3N0YXJ0ID4+IDE2LCBPTUFQX0RNQV9DRFNBX1UobGNoKSk7CglvbWFwX3dyaXRldyhkZXN0X3N0YXJ0LCBPTUFQX0RNQV9DRFNBX0wobGNoKSk7Cn0KCnZvaWQgb21hcF9zZXRfZG1hX2Rlc3RfaW5kZXgoaW50IGxjaCwgaW50IGVpZHgsIGludCBmaWR4KQp7CglvbWFwX3dyaXRldyhlaWR4LCBPTUFQX0RNQV9DREVJKGxjaCkpOwoJb21hcF93cml0ZXcoZmlkeCwgT01BUF9ETUFfQ0RGSShsY2gpKTsKfQoKdm9pZCBvbWFwX3NldF9kbWFfZGVzdF9kYXRhX3BhY2soaW50IGxjaCwgaW50IGVuYWJsZSkKewoJdTE2IHc7CgoJdyA9IG9tYXBfcmVhZHcoT01BUF9ETUFfQ1NEUChsY2gpKSAmIH4oMSA8PCAxMyk7Cgl3IHw9IGVuYWJsZSA/ICgxIDw8IDEzKSA6IDA7CglvbWFwX3dyaXRldyh3LCBPTUFQX0RNQV9DU0RQKGxjaCkpOwp9Cgp2b2lkIG9tYXBfc2V0X2RtYV9kZXN0X2J1cnN0X21vZGUoaW50IGxjaCwgZW51bSBvbWFwX2RtYV9idXJzdF9tb2RlIGJ1cnN0X21vZGUpCnsKCXUxNiB3OwoKCXcgPSBvbWFwX3JlYWR3KE9NQVBfRE1BX0NTRFAobGNoKSkgJiB+KDB4MDMgPDwgMTQpOwoJc3dpdGNoIChidXJzdF9tb2RlKSB7CgljYXNlIE9NQVBfRE1BX0RBVEFfQlVSU1RfRElTOgoJCWJyZWFrOwoJY2FzZSBPTUFQX0RNQV9EQVRBX0JVUlNUXzQ6CgkJdyB8PSAoMHgwMSA8PCAxNCk7CgkJYnJlYWs7CgljYXNlIE9NQVBfRE1BX0RBVEFfQlVSU1RfODoKCQl3IHw9ICgweDAzIDw8IDE0KTsKCQlicmVhazsKCWRlZmF1bHQ6CgkJcHJpbnRrKEtFUk5fRVJSICJJbnZhbGlkIERNQSBidXJzdCBtb2RlXG4iKTsKCQlCVUcoKTsKCQlyZXR1cm47Cgl9CglvbWFwX3dyaXRldyh3LCBPTUFQX0RNQV9DU0RQKGxjaCkpOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgaW5pdF9pbnRyKGludCBsY2gpCnsKCXUxNiB3OwoKCS8qIFJlYWQgQ1NSIHRvIG1ha2Ugc3VyZSBpdCdzIGNsZWFyZWQuICovCgl3ID0gb21hcF9yZWFkdyhPTUFQX0RNQV9DU1IobGNoKSk7CgkvKiBFbmFibGUgc29tZSBuaWNlIGludGVycnVwdHMuICovCglvbWFwX3dyaXRldyhkbWFfY2hhbltsY2hdLmVuYWJsZWRfaXJxcywgT01BUF9ETUFfQ0lDUihsY2gpKTsKCWRtYV9jaGFuW2xjaF0uZmxhZ3MgfD0gT01BUF9ETUFfQUNUSVZFOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgZW5hYmxlX2xuayhpbnQgbGNoKQp7Cgl1MTYgdzsKCgkvKiBDbGVhciB0aGUgU1RPUF9MTksgYml0cyAqLwoJdyA9IG9tYXBfcmVhZHcoT01BUF9ETUFfQ0xOS19DVFJMKGxjaCkpOwoJdyAmPSB+KDEgPDwgMTQpOwoJb21hcF93cml0ZXcodywgT01BUF9ETUFfQ0xOS19DVFJMKGxjaCkpOwoKCS8qIEFuZCBzZXQgdGhlIEVOQUJMRV9MTksgYml0cyAqLwoJaWYgKGRtYV9jaGFuW2xjaF0ubmV4dF9sY2ggIT0gLTEpCgkJb21hcF93cml0ZXcoZG1hX2NoYW5bbGNoXS5uZXh0X2xjaCB8ICgxIDw8IDE1KSwKCQkJICAgIE9NQVBfRE1BX0NMTktfQ1RSTChsY2gpKTsKfQoKc3RhdGljIGlubGluZSB2b2lkIGRpc2FibGVfbG5rKGludCBsY2gpCnsKCXUxNiB3OwoKCS8qIERpc2FibGUgaW50ZXJydXB0cyAqLwoJb21hcF93cml0ZXcoMCwgT01BUF9ETUFfQ0lDUihsY2gpKTsKCgkvKiBTZXQgdGhlIFNUT1BfTE5LIGJpdCAqLwoJdyA9IG9tYXBfcmVhZHcoT01BUF9ETUFfQ0xOS19DVFJMKGxjaCkpOwoJdyB8PSAoMSA8PCAxNCk7Cgl3ID0gb21hcF93cml0ZXcodywgT01BUF9ETUFfQ0xOS19DVFJMKGxjaCkpOwoKCWRtYV9jaGFuW2xjaF0uZmxhZ3MgJj0gfk9NQVBfRE1BX0FDVElWRTsKfQoKdm9pZCBvbWFwX3N0YXJ0X2RtYShpbnQgbGNoKQp7Cgl1MTYgdzsKCglpZiAoIW9tYXBfZG1hX2luXzE1MTBfbW9kZSgpICYmIGRtYV9jaGFuW2xjaF0ubmV4dF9sY2ggIT0gLTEpIHsKCQlpbnQgbmV4dF9sY2gsIGN1cl9sY2g7CgkJY2hhciBkbWFfY2hhbl9saW5rX21hcFtPTUFQX0xPR0lDQUxfRE1BX0NIX0NPVU5UXTsKCgkJZG1hX2NoYW5fbGlua19tYXBbbGNoXSA9IDE7CgkJLyogU2V0IHRoZSBsaW5rIHJlZ2lzdGVyIG9mIHRoZSBmaXJzdCBjaGFubmVsICovCgkJZW5hYmxlX2xuayhsY2gpOwoKCQltZW1zZXQoZG1hX2NoYW5fbGlua19tYXAsIDAsIHNpemVvZihkbWFfY2hhbl9saW5rX21hcCkpOwoJCWN1cl9sY2ggPSBkbWFfY2hhbltsY2hdLm5leHRfbGNoOwoJCWRvIHsKCQkJbmV4dF9sY2ggPSBkbWFfY2hhbltjdXJfbGNoXS5uZXh0X2xjaDsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFRoZSBsb29wIGNhc2U6IHdlJ3ZlIGJlZW4gaGVyZSBhbHJlYWR5ICovCgkJCWlmIChkbWFfY2hhbl9saW5rX21hcFtjdXJfbGNoXSkKCQkJCWJyZWFrOwoJCQkvKiBNYXJrIHRoZSBjdXJyZW50IGNoYW5uZWwgKi8KCQkJZG1hX2NoYW5fbGlua19tYXBbY3VyX2xjaF0gPSAxOwoKCQkJZW5hYmxlX2xuayhjdXJfbGNoKTsKCQkJaW5pdF9pbnRyKGN1cl9sY2gpOwoKCQkJY3VyX2xjaCA9IG5leHRfbGNoOwoJCX0gd2hpbGUgKG5leHRfbGNoICE9IC0xKTsKCX0KCglpbml0X2ludHIobGNoKTsKCgl3ID0gb21hcF9yZWFkdyhPTUFQX0RNQV9DQ1IobGNoKSk7Cgl3IHw9IE9NQVBfRE1BX0NDUl9FTjsKCW9tYXBfd3JpdGV3KHcsIE9NQVBfRE1BX0NDUihsY2gpKTsKCWRtYV9jaGFuW2xjaF0uZmxhZ3MgfD0gT01BUF9ETUFfQUNUSVZFOwp9Cgp2b2lkIG9tYXBfc3RvcF9kbWEoaW50IGxjaCkKewoJdTE2IHc7CgoJaWYgKCFvbWFwX2RtYV9pbl8xNTEwX21vZGUoKSAmJiBkbWFfY2hhbltsY2hdLm5leHRfbGNoICE9IC0xKSB7CgkJaW50IG5leHRfbGNoLCBjdXJfbGNoID0gbGNoOwoJCWNoYXIgZG1hX2NoYW5fbGlua19tYXBbT01BUF9MT0dJQ0FMX0RNQV9DSF9DT1VOVF07CgoJCW1lbXNldChkbWFfY2hhbl9saW5rX21hcCwgMCwgc2l6ZW9mKGRtYV9jaGFuX2xpbmtfbWFwKSk7CgkJZG8gewoJCQkvKiBUaGUgbG9vcCBjYXNlOiB3ZSd2ZSBiZWVuIGhlcmUgYWxyZWFkeSAqLwoJCQlpZiAoZG1hX2NoYW5fbGlua19tYXBbY3VyX2xjaF0pCgkJCQlicmVhazsKCQkJLyogTWFyayB0aGUgY3VycmVudCBjaGFubmVsICovCgkJCWRtYV9jaGFuX2xpbmtfbWFwW2N1cl9sY2hdID0gMTsKCgkJCWRpc2FibGVfbG5rKGN1cl9sY2gpOwoKCQkJbmV4dF9sY2ggPSBkbWFfY2hhbltjdXJfbGNoXS5uZXh0X2xjaDsKCQkJY3VyX2xjaCA9IG5leHRfbGNoOwoJCX0gd2hpbGUgKG5leHRfbGNoICE9IC0xKTsKCgkJcmV0dXJuOwoJfQoJLyogRGlzYWJsZSBhbGwgaW50ZXJydXB0cyBvbiB0aGUgY2hhbm5lbCAqLwoJb21hcF93cml0ZXcoMCwgT01BUF9ETUFfQ0lDUihsY2gpKTsKCgl3ID0gb21hcF9yZWFkdyhPTUFQX0RNQV9DQ1IobGNoKSk7Cgl3ICY9IH5PTUFQX0RNQV9DQ1JfRU47CglvbWFwX3dyaXRldyh3LCBPTUFQX0RNQV9DQ1IobGNoKSk7CglkbWFfY2hhbltsY2hdLmZsYWdzICY9IH5PTUFQX0RNQV9BQ1RJVkU7Cn0KCnZvaWQgb21hcF9lbmFibGVfZG1hX2lycShpbnQgbGNoLCB1MTYgYml0cykKewoJZG1hX2NoYW5bbGNoXS5lbmFibGVkX2lycXMgfD0gYml0czsKfQoKdm9pZCBvbWFwX2Rpc2FibGVfZG1hX2lycShpbnQgbGNoLCB1MTYgYml0cykKewoJZG1hX2NoYW5bbGNoXS5lbmFibGVkX2lycXMgJj0gfmJpdHM7Cn0KCnN0YXRpYyBpbnQgZG1hX2hhbmRsZV9jaChpbnQgY2gpCnsKCXUxNiBjc3I7CgoJaWYgKGVuYWJsZV8xNTEwX21vZGUgJiYgY2ggPj0gNikgewoJCWNzciA9IGRtYV9jaGFuW2NoXS5zYXZlZF9jc3I7CgkJZG1hX2NoYW5bY2hdLnNhdmVkX2NzciA9IDA7Cgl9IGVsc2UKCQljc3IgPSBvbWFwX3JlYWR3KE9NQVBfRE1BX0NTUihjaCkpOwoJaWYgKGVuYWJsZV8xNTEwX21vZGUgJiYgY2ggPD0gMiAmJiAoY3NyID4+IDcpICE9IDApIHsKCQlkbWFfY2hhbltjaCArIDZdLnNhdmVkX2NzciA9IGNzciA+PiA3OwoJCWNzciAmPSAweDdmOwoJfQoJaWYgKCFjc3IpCgkJcmV0dXJuIDA7CglpZiAodW5saWtlbHkoZG1hX2NoYW5bY2hdLmRldl9pZCA9PSAtMSkpIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJTcHVyaW91cyBpbnRlcnJ1cHQgZnJvbSBETUEgY2hhbm5lbCAlZCAoQ1NSICUwNHgpXG4iLAoJCSAgICAgICBjaCwgY3NyKTsKCQlyZXR1cm4gMDsKCX0KCWlmICh1bmxpa2VseShjc3IgJiBPTUFQX0RNQV9UT1VUX0lSUSkpCgkJcHJpbnRrKEtFUk5fV0FSTklORyAiRE1BIHRpbWVvdXQgd2l0aCBkZXZpY2UgJWRcbiIsIGRtYV9jaGFuW2NoXS5kZXZfaWQpOwoJaWYgKHVubGlrZWx5KGNzciAmIE9NQVBfRE1BX0RST1BfSVJRKSkKCQlwcmludGsoS0VSTl9XQVJOSU5HICJETUEgc3luY2hyb25pemF0aW9uIGV2ZW50IGRyb3Agb2NjdXJyZWQgd2l0aCBkZXZpY2UgJWRcbiIsCgkJICAgICAgIGRtYV9jaGFuW2NoXS5kZXZfaWQpOwoJaWYgKGxpa2VseShjc3IgJiBPTUFQX0RNQV9CTE9DS19JUlEpKQoJCWRtYV9jaGFuW2NoXS5mbGFncyAmPSB+T01BUF9ETUFfQUNUSVZFOwoJaWYgKGxpa2VseShkbWFfY2hhbltjaF0uY2FsbGJhY2sgIT0gTlVMTCkpCgkJZG1hX2NoYW5bY2hdLmNhbGxiYWNrKGNoLCBjc3IsIGRtYV9jaGFuW2NoXS5kYXRhKTsKCXJldHVybiAxOwp9CgpzdGF0aWMgaXJxcmV0dXJuX3QgZG1hX2lycV9oYW5kbGVyKGludCBpcnEsIHZvaWQgKmRldl9pZCwgc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKCWludCBjaCA9ICgoaW50KSBkZXZfaWQpIC0gMTsKCWludCBoYW5kbGVkID0gMDsKCglmb3IgKDs7KSB7CgkJaW50IGhhbmRsZWRfbm93ID0gMDsKCgkJaGFuZGxlZF9ub3cgKz0gZG1hX2hhbmRsZV9jaChjaCk7CgkJaWYgKGVuYWJsZV8xNTEwX21vZGUgJiYgZG1hX2NoYW5bY2ggKyA2XS5zYXZlZF9jc3IpCgkJCWhhbmRsZWRfbm93ICs9IGRtYV9oYW5kbGVfY2goY2ggKyA2KTsKCQlpZiAoIWhhbmRsZWRfbm93KQoJCQlicmVhazsKCQloYW5kbGVkICs9IGhhbmRsZWRfbm93OwoJfQoKCXJldHVybiBoYW5kbGVkID8gSVJRX0hBTkRMRUQgOiBJUlFfTk9ORTsKfQoKaW50IG9tYXBfcmVxdWVzdF9kbWEoaW50IGRldl9pZCwgY29uc3QgY2hhciAqZGV2X25hbWUsCgkJICAgICB2b2lkICgqIGNhbGxiYWNrKShpbnQgbGNoLCB1MTYgY2hfc3RhdHVzLCB2b2lkICpkYXRhKSwKCQkgICAgIHZvaWQgKmRhdGEsIGludCAqZG1hX2NoX291dCkKewoJaW50IGNoLCBmcmVlX2NoID0gLTE7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoJc3RydWN0IG9tYXBfZG1hX2xjaCAqY2hhbjsKCglzcGluX2xvY2tfaXJxc2F2ZSgmZG1hX2NoYW5fbG9jaywgZmxhZ3MpOwoJZm9yIChjaCA9IDA7IGNoIDwgZG1hX2NoYW5fY291bnQ7IGNoKyspIHsKCQlpZiAoZnJlZV9jaCA9PSAtMSAmJiBkbWFfY2hhbltjaF0uZGV2X2lkID09IC0xKSB7CgkJCWZyZWVfY2ggPSBjaDsKCQkJaWYgKGRldl9pZCA9PSAwKQoJCQkJYnJlYWs7CgkJfQoJfQoJaWYgKGZyZWVfY2ggPT0gLTEpIHsKCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZkbWFfY2hhbl9sb2NrLCBmbGFncyk7CgkJcmV0dXJuIC1FQlVTWTsKCX0KCWNoYW4gPSBkbWFfY2hhbiArIGZyZWVfY2g7CgljaGFuLT5kZXZfaWQgPSBkZXZfaWQ7CgljbGVhcl9sY2hfcmVncyhmcmVlX2NoKTsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmRtYV9jaGFuX2xvY2ssIGZsYWdzKTsKCgljaGFuLT5kZXZfaWQgPSBkZXZfaWQ7CgljaGFuLT5kZXZfbmFtZSA9IGRldl9uYW1lOwoJY2hhbi0+Y2FsbGJhY2sgPSBjYWxsYmFjazsKCWNoYW4tPmRhdGEgPSBkYXRhOwoJY2hhbi0+ZW5hYmxlZF9pcnFzID0gT01BUF9ETUFfVE9VVF9JUlEgfCBPTUFQX0RNQV9EUk9QX0lSUSB8IE9NQVBfRE1BX0JMT0NLX0lSUTsKCglpZiAoY3B1X2lzX29tYXAxNnh4KCkpIHsKCQkvKiBJZiB0aGUgc3luYyBkZXZpY2UgaXMgc2V0LCBjb25maWd1cmUgaXQgZHluYW1pY2FsbHkuICovCgkJaWYgKGRldl9pZCAhPSAwKSB7CgkJCXNldF9nZG1hX2RldihmcmVlX2NoICsgMSwgZGV2X2lkKTsKCQkJZGV2X2lkID0gZnJlZV9jaCArIDE7CgkJfQoJCS8qIERpc2FibGUgdGhlIDE1MTAgY29tcGF0aWJpbGl0eSBtb2RlIGFuZCBzZXQgdGhlIHN5bmMgZGV2aWNlCgkJICogaWQuICovCgkJb21hcF93cml0ZXcoZGV2X2lkIHwgKDEgPDwgMTApLCBPTUFQX0RNQV9DQ1IoZnJlZV9jaCkpOwoJfSBlbHNlIHsKCQlvbWFwX3dyaXRldyhkZXZfaWQsIE9NQVBfRE1BX0NDUihmcmVlX2NoKSk7Cgl9CgkqZG1hX2NoX291dCA9IGZyZWVfY2g7CgoJcmV0dXJuIDA7Cn0KCnZvaWQgb21hcF9mcmVlX2RtYShpbnQgY2gpCnsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJc3Bpbl9sb2NrX2lycXNhdmUoJmRtYV9jaGFuX2xvY2ssIGZsYWdzKTsKCWlmIChkbWFfY2hhbltjaF0uZGV2X2lkID09IC0xKSB7CgkJcHJpbnRrKCJvbWFwX2RtYTogdHJ5aW5nIHRvIGZyZWUgbm9uYWxsb2NhdGVkIERNQSBjaGFubmVsICVkXG4iLCBjaCk7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmZG1hX2NoYW5fbG9jaywgZmxhZ3MpOwoJCXJldHVybjsKCX0KCWRtYV9jaGFuW2NoXS5kZXZfaWQgPSAtMTsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmRtYV9jaGFuX2xvY2ssIGZsYWdzKTsKCgkvKiBEaXNhYmxlIGFsbCBETUEgaW50ZXJydXB0cyBmb3IgdGhlIGNoYW5uZWwuICovCglvbWFwX3dyaXRldygwLCBPTUFQX0RNQV9DSUNSKGNoKSk7CgkvKiBNYWtlIHN1cmUgdGhlIERNQSB0cmFuc2ZlciBpcyBzdG9wcGVkLiAqLwoJb21hcF93cml0ZXcoMCwgT01BUF9ETUFfQ0NSKGNoKSk7Cn0KCmludCBvbWFwX2RtYV9pbl8xNTEwX21vZGUodm9pZCkKewoJcmV0dXJuIGVuYWJsZV8xNTEwX21vZGU7Cn0KCi8qCiAqIGxjaF9xdWV1ZSBETUEgd2lsbCBzdGFydCByaWdodCBhZnRlciBsY2hfaGVhZCBvbmUgaXMgZmluaXNoZWQuCiAqIEZvciB0aGlzIERNQSBsaW5rIHRvIHN0YXJ0LCB5b3Ugc3RpbGwgbmVlZCB0byBzdGFydCAoc2VlIG9tYXBfc3RhcnRfZG1hKQogKiB0aGUgZmlyc3Qgb25lLiBUaGF0IHdpbGwgZmlyZSB1cCB0aGUgZW50aXJlIHF1ZXVlLgogKi8Kdm9pZCBvbWFwX2RtYV9saW5rX2xjaCAoaW50IGxjaF9oZWFkLCBpbnQgbGNoX3F1ZXVlKQp7CglpZiAob21hcF9kbWFfaW5fMTUxMF9tb2RlKCkpIHsKCQlwcmludGsoS0VSTl9FUlIgIkRNQSBsaW5raW5nIGlzIG5vdCBzdXBwb3J0ZWQgaW4gMTUxMCBtb2RlXG4iKTsKCQlCVUcoKTsKCQlyZXR1cm47Cgl9CgoJaWYgKChkbWFfY2hhbltsY2hfaGVhZF0uZGV2X2lkID09IC0xKSB8fAoJICAgIChkbWFfY2hhbltsY2hfcXVldWVdLmRldl9pZCA9PSAtMSkpIHsKCQlwcmludGsoS0VSTl9FUlIgIm9tYXBfZG1hOiB0cnlpbmcgdG8gbGluayBub24gcmVxdWVzdGVkIGNoYW5uZWxzXG4iKTsKCQlkdW1wX3N0YWNrKCk7Cgl9CgoJZG1hX2NoYW5bbGNoX2hlYWRdLm5leHRfbGNoID0gbGNoX3F1ZXVlOwp9CgovKgogKiBPbmNlIHRoZSBETUEgcXVldWUgaXMgc3RvcHBlZCwgd2UgY2FuIGRlc3Ryb3kgaXQuCiAqLwp2b2lkIG9tYXBfZG1hX3VubGlua19sY2ggKGludCBsY2hfaGVhZCwgaW50IGxjaF9xdWV1ZSkKewoJaWYgKG9tYXBfZG1hX2luXzE1MTBfbW9kZSgpKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJETUEgbGlua2luZyBpcyBub3Qgc3VwcG9ydGVkIGluIDE1MTAgbW9kZVxuIik7CgkJQlVHKCk7CgkJcmV0dXJuOwoJfQoKCWlmIChkbWFfY2hhbltsY2hfaGVhZF0ubmV4dF9sY2ggIT0gbGNoX3F1ZXVlIHx8CgkgICAgZG1hX2NoYW5bbGNoX2hlYWRdLm5leHRfbGNoID09IC0xKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJvbWFwX2RtYTogdHJ5aW5nIHRvIHVubGluayBub24gbGlua2VkIGNoYW5uZWxzXG4iKTsKCQlkdW1wX3N0YWNrKCk7Cgl9CgoKCWlmICgoZG1hX2NoYW5bbGNoX2hlYWRdLmZsYWdzICYgT01BUF9ETUFfQUNUSVZFKSB8fAoJICAgIChkbWFfY2hhbltsY2hfaGVhZF0uZmxhZ3MgJiBPTUFQX0RNQV9BQ1RJVkUpKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJvbWFwX2RtYTogWW91IG5lZWQgdG8gc3RvcCB0aGUgRE1BIGNoYW5uZWxzIGJlZm9yZSB1bmxpbmtpbmdcbiIpOwoJCWR1bXBfc3RhY2soKTsKCX0KCglkbWFfY2hhbltsY2hfaGVhZF0ubmV4dF9sY2ggPSAtMTsKfQoKCnN0YXRpYyBzdHJ1Y3QgbGNkX2RtYV9pbmZvIHsKCXNwaW5sb2NrX3QgbG9jazsKCWludCByZXNlcnZlZDsKCXZvaWQgKCogY2FsbGJhY2spKHUxNiBzdGF0dXMsIHZvaWQgKmRhdGEpOwoJdm9pZCAqY2JfZGF0YTsKCglpbnQgYWN0aXZlOwoJdW5zaWduZWQgbG9uZyBhZGRyLCBzaXplOwoJaW50IHJvdGF0ZSwgZGF0YV90eXBlLCB4cmVzLCB5cmVzOwoJaW50IHZ4cmVzOwoJaW50IG1pcnJvcjsKCWludCB4c2NhbGUsIHlzY2FsZTsKCWludCBleHRfY3RybDsKCWludCBzcmNfcG9ydDsKCWludCBzaW5nbGVfdHJhbnNmZXI7Cn0gbGNkX2RtYTsKCnZvaWQgb21hcF9zZXRfbGNkX2RtYV9iMSh1bnNpZ25lZCBsb25nIGFkZHIsIHUxNiBmYl94cmVzLCB1MTYgZmJfeXJlcywKCQkJIGludCBkYXRhX3R5cGUpCnsKCWxjZF9kbWEuYWRkciA9IGFkZHI7CglsY2RfZG1hLmRhdGFfdHlwZSA9IGRhdGFfdHlwZTsKCWxjZF9kbWEueHJlcyA9IGZiX3hyZXM7CglsY2RfZG1hLnlyZXMgPSBmYl95cmVzOwp9Cgp2b2lkIG9tYXBfc2V0X2xjZF9kbWFfc3JjX3BvcnQoaW50IHBvcnQpCnsKCWxjZF9kbWEuc3JjX3BvcnQgPSBwb3J0Owp9Cgp2b2lkIG9tYXBfc2V0X2xjZF9kbWFfZXh0X2NvbnRyb2xsZXIoaW50IGV4dGVybmFsKQp7CglsY2RfZG1hLmV4dF9jdHJsID0gZXh0ZXJuYWw7Cn0KCnZvaWQgb21hcF9zZXRfbGNkX2RtYV9zaW5nbGVfdHJhbnNmZXIoaW50IHNpbmdsZSkKewoJbGNkX2RtYS5zaW5nbGVfdHJhbnNmZXIgPSBzaW5nbGU7Cn0KCgp2b2lkIG9tYXBfc2V0X2xjZF9kbWFfYjFfcm90YXRpb24oaW50IHJvdGF0ZSkKewoJaWYgKG9tYXBfZG1hX2luXzE1MTBfbW9kZSgpKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJETUEgcm90YXRpb24gaXMgbm90IHN1cHBvcnRlZCBpbiAxNTEwIG1vZGVcbiIpOwoJCUJVRygpOwoJCXJldHVybjsKCX0KCWxjZF9kbWEucm90YXRlID0gcm90YXRlOwp9Cgp2b2lkIG9tYXBfc2V0X2xjZF9kbWFfYjFfbWlycm9yKGludCBtaXJyb3IpCnsKCWlmIChvbWFwX2RtYV9pbl8xNTEwX21vZGUoKSkgewoJCXByaW50ayhLRVJOX0VSUiAiRE1BIG1pcnJvciBpcyBub3Qgc3VwcG9ydGVkIGluIDE1MTAgbW9kZVxuIik7CgkJQlVHKCk7Cgl9CglsY2RfZG1hLm1pcnJvciA9IG1pcnJvcjsKfQoKdm9pZCBvbWFwX3NldF9sY2RfZG1hX2IxX3Z4cmVzKHVuc2lnbmVkIGxvbmcgdnhyZXMpCnsKCWlmIChvbWFwX2RtYV9pbl8xNTEwX21vZGUoKSkgewoJCXByaW50ayhLRVJOX0VSUiAiRE1BIHZpcnR1YWwgcmVzdWxvdGlvbiBpcyBub3Qgc3VwcG9ydGVkICIKCQkJCSJpbiAxNTEwIG1vZGVcbiIpOwoJCUJVRygpOwoJfQoJbGNkX2RtYS52eHJlcyA9IHZ4cmVzOwp9Cgp2b2lkIG9tYXBfc2V0X2xjZF9kbWFfYjFfc2NhbGUodW5zaWduZWQgaW50IHhzY2FsZSwgdW5zaWduZWQgaW50IHlzY2FsZSkKewoJaWYgKG9tYXBfZG1hX2luXzE1MTBfbW9kZSgpKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJETUEgc2NhbGUgaXMgbm90IHN1cHBvcnRlZCBpbiAxNTEwIG1vZGVcbiIpOwoJCUJVRygpOwoJfQoJbGNkX2RtYS54c2NhbGUgPSB4c2NhbGU7CglsY2RfZG1hLnlzY2FsZSA9IHlzY2FsZTsKfQoKc3RhdGljIHZvaWQgc2V0X2IxX3JlZ3Modm9pZCkKewoJdW5zaWduZWQgbG9uZyB0b3AsIGJvdHRvbTsKCWludCBlczsKCXUxNiB3OwoJdW5zaWduZWQgbG9uZyBlbiwgZm47Cglsb25nIGVpLCBmaTsKCXVuc2lnbmVkIGxvbmcgdnhyZXM7Cgl1bnNpZ25lZCBpbnQgeHNjYWxlLCB5c2NhbGU7CgoJc3dpdGNoIChsY2RfZG1hLmRhdGFfdHlwZSkgewoJY2FzZSBPTUFQX0RNQV9EQVRBX1RZUEVfUzg6CgkJZXMgPSAxOwoJCWJyZWFrOwoJY2FzZSBPTUFQX0RNQV9EQVRBX1RZUEVfUzE2OgoJCWVzID0gMjsKCQlicmVhazsKCWNhc2UgT01BUF9ETUFfREFUQV9UWVBFX1MzMjoKCQllcyA9IDQ7CgkJYnJlYWs7CglkZWZhdWx0OgoJCUJVRygpOwoJCXJldHVybjsKCX0KCgl2eHJlcyA9IGxjZF9kbWEudnhyZXMgPyBsY2RfZG1hLnZ4cmVzIDogbGNkX2RtYS54cmVzOwoJeHNjYWxlID0gbGNkX2RtYS54c2NhbGUgPyBsY2RfZG1hLnhzY2FsZSA6IDE7Cgl5c2NhbGUgPSBsY2RfZG1hLnlzY2FsZSA/IGxjZF9kbWEueXNjYWxlIDogMTsKCUJVR19PTih2eHJlcyA8IGxjZF9kbWEueHJlcyk7CiNkZWZpbmUgUElYQUREUih4LHkpIChsY2RfZG1hLmFkZHIgKyAoKHkpICogdnhyZXMgKiB5c2NhbGUgKyAoeCkgKiB4c2NhbGUpICogZXMpCiNkZWZpbmUgUElYU1RFUChzeCwgc3ksIGR4LCBkeSkgKFBJWEFERFIoZHgsIGR5KSAtIFBJWEFERFIoc3gsIHN5KSAtIGVzICsgMSkKCXN3aXRjaCAobGNkX2RtYS5yb3RhdGUpIHsKCWNhc2UgMDoKCQlpZiAoIWxjZF9kbWEubWlycm9yKSB7CgkJCXRvcCA9IFBJWEFERFIoMCwgMCk7CgkJCWJvdHRvbSA9IFBJWEFERFIobGNkX2RtYS54cmVzIC0gMSwgbGNkX2RtYS55cmVzIC0gMSk7CgkJCS8qIDE1MTAgRE1BIHJlcXVpcmVzIHRoZSBib3R0b20gYWRkcmVzcyB0byBiZSAyIG1vcmUKCQkJICogdGhhbiB0aGUgYWN0dWFsIGxhc3QgbWVtb3J5IGFjY2VzcyBsb2NhdGlvbi4gKi8KCQkJaWYgKG9tYXBfZG1hX2luXzE1MTBfbW9kZSgpICYmCgkJCSAgICBsY2RfZG1hLmRhdGFfdHlwZSA9PSBPTUFQX0RNQV9EQVRBX1RZUEVfUzMyKQoJCQkJYm90dG9tICs9IDI7CgkJCWVpID0gUElYU1RFUCgwLCAwLCAxLCAwKTsKCQkJZmkgPSBQSVhTVEVQKGxjZF9kbWEueHJlcyAtIDEsIDAsIDAsIDEpOwoJCX0gZWxzZSB7CgkJCXRvcCA9IFBJWEFERFIobGNkX2RtYS54cmVzIC0gMSwgMCk7CgkJCWJvdHRvbSA9IFBJWEFERFIoMCwgbGNkX2RtYS55cmVzIC0gMSk7CgkJCWVpID0gUElYU1RFUCgxLCAwLCAwLCAwKTsKCQkJZmkgPSBQSVhTVEVQKDAsIDAsIGxjZF9kbWEueHJlcyAtIDEsIDEpOwoJCX0KCQllbiA9IGxjZF9kbWEueHJlczsKCQlmbiA9IGxjZF9kbWEueXJlczsKCQlicmVhazsKCWNhc2UgOTA6CgkJaWYgKCFsY2RfZG1hLm1pcnJvcikgewoJCQl0b3AgPSBQSVhBRERSKDAsIGxjZF9kbWEueXJlcyAtIDEpOwoJCQlib3R0b20gPSBQSVhBRERSKGxjZF9kbWEueHJlcyAtIDEsIDApOwoJCQllaSA9IFBJWFNURVAoMCwgMSwgMCwgMCk7CgkJCWZpID0gUElYU1RFUCgwLCAwLCAxLCBsY2RfZG1hLnlyZXMgLSAxKTsKCQl9IGVsc2UgewoJCQl0b3AgPSBQSVhBRERSKGxjZF9kbWEueHJlcyAtIDEsIGxjZF9kbWEueXJlcyAtIDEpOwoJCQlib3R0b20gPSBQSVhBRERSKDAsIDApOwoJCQllaSA9IFBJWFNURVAoMCwgMSwgMCwgMCk7CgkJCWZpID0gUElYU1RFUCgxLCAwLCAwLCBsY2RfZG1hLnlyZXMgLSAxKTsKCQl9CgkJZW4gPSBsY2RfZG1hLnlyZXM7CgkJZm4gPSBsY2RfZG1hLnhyZXM7CgkJYnJlYWs7CgljYXNlIDE4MDoKCQlpZiAoIWxjZF9kbWEubWlycm9yKSB7CgkJCXRvcCA9IFBJWEFERFIobGNkX2RtYS54cmVzIC0gMSwgbGNkX2RtYS55cmVzIC0gMSk7CgkJCWJvdHRvbSA9IFBJWEFERFIoMCwgMCk7CgkJCWVpID0gUElYU1RFUCgxLCAwLCAwLCAwKTsKCQkJZmkgPSBQSVhTVEVQKDAsIDEsIGxjZF9kbWEueHJlcyAtIDEsIDApOwoJCX0gZWxzZSB7CgkJCXRvcCA9IFBJWEFERFIoMCwgbGNkX2RtYS55cmVzIC0gMSk7CgkJCWJvdHRvbSA9IFBJWEFERFIobGNkX2RtYS54cmVzIC0gMSwgMCk7CgkJCWVpID0gUElYU1RFUCgwLCAwLCAxLCAwKTsKCQkJZmkgPSBQSVhTVEVQKGxjZF9kbWEueHJlcyAtIDEsIDEsIDAsIDApOwoJCX0KCQllbiA9IGxjZF9kbWEueHJlczsKCQlmbiA9IGxjZF9kbWEueXJlczsKCQlicmVhazsKCWNhc2UgMjcwOgoJCWlmICghbGNkX2RtYS5taXJyb3IpIHsKCQkJdG9wID0gUElYQUREUihsY2RfZG1hLnhyZXMgLSAxLCAwKTsKCQkJYm90dG9tID0gUElYQUREUigwLCBsY2RfZG1hLnlyZXMgLSAxKTsKCQkJZWkgPSBQSVhTVEVQKDAsIDAsIDAsIDEpOwoJCQlmaSA9IFBJWFNURVAoMSwgbGNkX2RtYS55cmVzIC0gMSwgMCwgMCk7CgkJfSBlbHNlIHsKCQkJdG9wID0gUElYQUREUigwLCAwKTsKCQkJYm90dG9tID0gUElYQUREUihsY2RfZG1hLnhyZXMgLSAxLCBsY2RfZG1hLnlyZXMgLSAxKTsKCQkJZWkgPSBQSVhTVEVQKDAsIDAsIDAsIDEpOwoJCQlmaSA9IFBJWFNURVAoMCwgbGNkX2RtYS55cmVzIC0gMSwgMSwgMCk7CgkJfQoJCWVuID0gbGNkX2RtYS55cmVzOwoJCWZuID0gbGNkX2RtYS54cmVzOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlCVUcoKTsKCQlyZXR1cm47CS8qIFN1cHJlc3Mgd2FybmluZyBhYm91dCB1bmluaXRpYWxpemVkIHZhcnMgKi8KCX0KCglpZiAob21hcF9kbWFfaW5fMTUxMF9tb2RlKCkpIHsKCQlvbWFwX3dyaXRldyh0b3AgPj4gMTYsIE9NQVAxNTEwX0RNQV9MQ0RfVE9QX0YxX1UpOwoJCW9tYXBfd3JpdGV3KHRvcCwgT01BUDE1MTBfRE1BX0xDRF9UT1BfRjFfTCk7CgkJb21hcF93cml0ZXcoYm90dG9tID4+IDE2LCBPTUFQMTUxMF9ETUFfTENEX0JPVF9GMV9VKTsKCQlvbWFwX3dyaXRldyhib3R0b20sIE9NQVAxNTEwX0RNQV9MQ0RfQk9UX0YxX0wpOwoKCQlyZXR1cm47Cgl9CgoJLyogMTYxMCByZWdzICovCglvbWFwX3dyaXRldyh0b3AgPj4gMTYsIE9NQVAxNjEwX0RNQV9MQ0RfVE9QX0IxX1UpOwoJb21hcF93cml0ZXcodG9wLCBPTUFQMTYxMF9ETUFfTENEX1RPUF9CMV9MKTsKCW9tYXBfd3JpdGV3KGJvdHRvbSA+PiAxNiwgT01BUDE2MTBfRE1BX0xDRF9CT1RfQjFfVSk7CglvbWFwX3dyaXRldyhib3R0b20sIE9NQVAxNjEwX0RNQV9MQ0RfQk9UX0IxX0wpOwoKCW9tYXBfd3JpdGV3KGVuLCBPTUFQMTYxMF9ETUFfTENEX1NSQ19FTl9CMSk7CglvbWFwX3dyaXRldyhmbiwgT01BUDE2MTBfRE1BX0xDRF9TUkNfRk5fQjEpOwoKCXcgPSBvbWFwX3JlYWR3KE9NQVAxNjEwX0RNQV9MQ0RfQ1NEUCk7Cgl3ICY9IH4weDAzOwoJdyB8PSBsY2RfZG1hLmRhdGFfdHlwZTsKCW9tYXBfd3JpdGV3KHcsIE9NQVAxNjEwX0RNQV9MQ0RfQ1NEUCk7CgoJdyA9IG9tYXBfcmVhZHcoT01BUDE2MTBfRE1BX0xDRF9DVFJMKTsKCS8qIEFsd2F5cyBzZXQgdGhlIHNvdXJjZSBwb3J0IGFzIFNEUkFNIGZvciBub3cqLwoJdyAmPSB+KDB4MDMgPDwgNik7CglpZiAobGNkX2RtYS5leHRfY3RybCkKCQl3IHw9IDEgPDwgODsKCWVsc2UKCQl3ICY9IH4oMSA8PCA4KTsKCWlmIChsY2RfZG1hLmNhbGxiYWNrICE9IE5VTEwpCgkJdyB8PSAxIDw8IDE7ICAgICAgICAgICAgLyogQmxvY2sgaW50ZXJydXB0IGVuYWJsZSAqLwoJZWxzZQoJCXcgJj0gfigxIDw8IDEpOwoJb21hcF93cml0ZXcodywgT01BUDE2MTBfRE1BX0xDRF9DVFJMKTsKCglpZiAoIShsY2RfZG1hLnJvdGF0ZSB8fCBsY2RfZG1hLm1pcnJvciB8fAoJICAgICAgbGNkX2RtYS52eHJlcyB8fCBsY2RfZG1hLnhzY2FsZSB8fCBsY2RfZG1hLnlzY2FsZSkpCgkJcmV0dXJuOwoKCXcgPSBvbWFwX3JlYWR3KE9NQVAxNjEwX0RNQV9MQ0RfQ0NSKTsKCS8qIFNldCB0aGUgZG91YmxlLWluZGV4ZWQgYWRkcmVzc2luZyBtb2RlICovCgl3IHw9ICgweDAzIDw8IDEyKTsKCW9tYXBfd3JpdGV3KHcsIE9NQVAxNjEwX0RNQV9MQ0RfQ0NSKTsKCglvbWFwX3dyaXRldyhlaSwgT01BUDE2MTBfRE1BX0xDRF9TUkNfRUlfQjEpOwoJb21hcF93cml0ZXcoZmkgPj4gMTYsIE9NQVAxNjEwX0RNQV9MQ0RfU1JDX0ZJX0IxX1UpOwoJb21hcF93cml0ZXcoZmksIE9NQVAxNjEwX0RNQV9MQ0RfU1JDX0ZJX0IxX0wpOwp9CgpzdGF0aWMgaXJxcmV0dXJuX3QgbGNkX2RtYV9pcnFfaGFuZGxlcihpbnQgaXJxLCB2b2lkICpkZXZfaWQsIHN0cnVjdCBwdF9yZWdzICpyZWdzKQp7Cgl1MTYgdzsKCgl3ID0gb21hcF9yZWFkdyhPTUFQMTYxMF9ETUFfTENEX0NUUkwpOwoJaWYgKHVubGlrZWx5KCEodyAmICgxIDw8IDMpKSkpIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJTcHVyaW91cyBMQ0QgRE1BIElSUVxuIik7CgkJcmV0dXJuIElSUV9OT05FOwoJfQoJLyogQWNrIHRoZSBJUlEgKi8KCXcgfD0gKDEgPDwgMyk7CglvbWFwX3dyaXRldyh3LCBPTUFQMTYxMF9ETUFfTENEX0NUUkwpOwoJbGNkX2RtYS5hY3RpdmUgPSAwOwoJaWYgKGxjZF9kbWEuY2FsbGJhY2sgIT0gTlVMTCkKCQlsY2RfZG1hLmNhbGxiYWNrKHcsIGxjZF9kbWEuY2JfZGF0YSk7CgoJcmV0dXJuIElSUV9IQU5ETEVEOwp9CgppbnQgb21hcF9yZXF1ZXN0X2xjZF9kbWEodm9pZCAoKiBjYWxsYmFjaykodTE2IHN0YXR1cywgdm9pZCAqZGF0YSksCgkJCSB2b2lkICpkYXRhKQp7CglzcGluX2xvY2tfaXJxKCZsY2RfZG1hLmxvY2spOwoJaWYgKGxjZF9kbWEucmVzZXJ2ZWQpIHsKCQlzcGluX3VubG9ja19pcnEoJmxjZF9kbWEubG9jayk7CgkJcHJpbnRrKEtFUk5fRVJSICJMQ0QgRE1BIGNoYW5uZWwgYWxyZWFkeSByZXNlcnZlZFxuIik7CgkJQlVHKCk7CgkJcmV0dXJuIC1FQlVTWTsKCX0KCWxjZF9kbWEucmVzZXJ2ZWQgPSAxOwoJc3Bpbl91bmxvY2tfaXJxKCZsY2RfZG1hLmxvY2spOwoJbGNkX2RtYS5jYWxsYmFjayA9IGNhbGxiYWNrOwoJbGNkX2RtYS5jYl9kYXRhID0gZGF0YTsKCWxjZF9kbWEuYWN0aXZlID0gMDsKCWxjZF9kbWEuc2luZ2xlX3RyYW5zZmVyID0gMDsKCWxjZF9kbWEucm90YXRlID0gMDsKCWxjZF9kbWEudnhyZXMgPSAwOwoJbGNkX2RtYS5taXJyb3IgPSAwOwoJbGNkX2RtYS54c2NhbGUgPSAwOwoJbGNkX2RtYS55c2NhbGUgPSAwOwoJbGNkX2RtYS5leHRfY3RybCA9IDA7CglsY2RfZG1hLnNyY19wb3J0ID0gMDsKCglyZXR1cm4gMDsKfQoKdm9pZCBvbWFwX2ZyZWVfbGNkX2RtYSh2b2lkKQp7CglzcGluX2xvY2soJmxjZF9kbWEubG9jayk7CglpZiAoIWxjZF9kbWEucmVzZXJ2ZWQpIHsKCQlzcGluX3VubG9jaygmbGNkX2RtYS5sb2NrKTsKCQlwcmludGsoS0VSTl9FUlIgIkxDRCBETUEgaXMgbm90IHJlc2VydmVkXG4iKTsKCQlCVUcoKTsKCQlyZXR1cm47Cgl9CglpZiAoIWVuYWJsZV8xNTEwX21vZGUpCgkJb21hcF93cml0ZXcob21hcF9yZWFkdyhPTUFQMTYxMF9ETUFfTENEX0NDUikgJiB+MSwgT01BUDE2MTBfRE1BX0xDRF9DQ1IpOwoJbGNkX2RtYS5yZXNlcnZlZCA9IDA7CglzcGluX3VubG9jaygmbGNkX2RtYS5sb2NrKTsKfQoKdm9pZCBvbWFwX2VuYWJsZV9sY2RfZG1hKHZvaWQpCnsKCXUxNiB3OwoKCS8qIFNldCB0aGUgRW5hYmxlIGJpdCBvbmx5IGlmIGFuIGV4dGVybmFsIGNvbnRyb2xsZXIgaXMKCSAqIGNvbm5lY3RlZC4gT3RoZXJ3aXNlIHRoZSBPTUFQIGludGVybmFsIGNvbnRyb2xsZXIgd2lsbAoJICogc3RhcnQgdGhlIHRyYW5zZmVyIHdoZW4gaXQgZ2V0cyBlbmFibGVkLgoJICovCglpZiAoZW5hYmxlXzE1MTBfbW9kZSB8fCAhbGNkX2RtYS5leHRfY3RybCkKCQlyZXR1cm47Cgl3ID0gb21hcF9yZWFkdyhPTUFQMTYxMF9ETUFfTENEX0NDUik7Cgl3IHw9IDEgPDwgNzsKCW9tYXBfd3JpdGV3KHcsIE9NQVAxNjEwX0RNQV9MQ0RfQ0NSKTsKCWxjZF9kbWEuYWN0aXZlID0gMTsKfQoKdm9pZCBvbWFwX3NldHVwX2xjZF9kbWEodm9pZCkKewoJQlVHX09OKGxjZF9kbWEuYWN0aXZlKTsKCWlmICghZW5hYmxlXzE1MTBfbW9kZSkgewoJCS8qIFNldCBzb21lIHJlYXNvbmFibGUgZGVmYXVsdHMgKi8KCQlvbWFwX3dyaXRldygweDU0NDAsIE9NQVAxNjEwX0RNQV9MQ0RfQ0NSKTsKCQlvbWFwX3dyaXRldygweDkxMDIsIE9NQVAxNjEwX0RNQV9MQ0RfQ1NEUCk7CgkJb21hcF93cml0ZXcoMHgwMDA0LCBPTUFQMTYxMF9ETUFfTENEX0xDSF9DVFJMKTsKCX0KCXNldF9iMV9yZWdzKCk7CglpZiAoIWVuYWJsZV8xNTEwX21vZGUpIHsKCQl1MTYgdzsKCgkJdyA9IG9tYXBfcmVhZHcoT01BUDE2MTBfRE1BX0xDRF9DQ1IpOwoJCS8qIElmIERNQSB3YXMgYWxyZWFkeSBhY3RpdmUgc2V0IHRoZSBlbmRfcHJvZyBiaXQgdG8gaGF2ZQoJCSAqIHRoZSBwcm9ncmFtbWVkIHJlZ2lzdGVyIHNldCBsb2FkZWQgaW50byB0aGUgYWN0aXZlCgkJICogcmVnaXN0ZXIgc2V0LgoJCSAqLwoJCXcgfD0gMSA8PCAxMTsJCS8qIEVuZF9wcm9nICovCgkJaWYgKCFsY2RfZG1hLnNpbmdsZV90cmFuc2ZlcikKCSAgICAgICAgCXcgfD0gKDMgPDwgOCk7CS8qIEF1dG9faW5pdCwgcmVwZWF0ICovCgkJb21hcF93cml0ZXcodywgT01BUDE2MTBfRE1BX0xDRF9DQ1IpOwoJfQp9Cgp2b2lkIG9tYXBfc3RvcF9sY2RfZG1hKHZvaWQpCnsKCWxjZF9kbWEuYWN0aXZlID0gMDsKCWlmICghZW5hYmxlXzE1MTBfbW9kZSAmJiBsY2RfZG1hLmV4dF9jdHJsKQoJCW9tYXBfd3JpdGV3KG9tYXBfcmVhZHcoT01BUDE2MTBfRE1BX0xDRF9DQ1IpICYgfigxIDw8IDcpLAoJCQkgICAgT01BUDE2MTBfRE1BX0xDRF9DQ1IpOwp9CgovKgogKiBDbGVhcnMgYW55IERNQSBzdGF0ZSBzbyB0aGUgRE1BIGVuZ2luZSBpcyByZWFkeSB0byByZXN0YXJ0IHdpdGggbmV3IGJ1ZmZlcnMKICogdGhyb3VnaCBvbWFwX3N0YXJ0X2RtYSgpLiBBbnkgYnVmZmVycyBpbiBmbGlnaHQgYXJlIGRpc2NhcmRlZC4KICovCnZvaWQgb21hcF9jbGVhcl9kbWEoaW50IGxjaCkKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCWludCBzdGF0dXM7CgoJbG9jYWxfaXJxX3NhdmUoZmxhZ3MpOwoJb21hcF93cml0ZXcob21hcF9yZWFkdyhPTUFQX0RNQV9DQ1IobGNoKSkgJiB+T01BUF9ETUFfQ0NSX0VOLAoJCSAgICBPTUFQX0RNQV9DQ1IobGNoKSk7CglzdGF0dXMgPSBPTUFQX0RNQV9DU1IobGNoKTsJLyogY2xlYXIgcGVuZGluZyBpbnRlcnJ1cHRzICovCglsb2NhbF9pcnFfcmVzdG9yZShmbGFncyk7Cn0KCi8qCiAqIFJldHVybnMgY3VycmVudCBwaHlzaWNhbCBzb3VyY2UgYWRkcmVzcyBmb3IgdGhlIGdpdmVuIERNQSBjaGFubmVsLgogKiBJZiB0aGUgY2hhbm5lbCBpcyBydW5uaW5nIHRoZSBjYWxsZXIgbXVzdCBkaXNhYmxlIGludGVycnVwdHMgcHJpb3IgY2FsbGluZwogKiB0aGlzIGZ1bmN0aW9uIGFuZCBwcm9jZXNzIHRoZSByZXR1cm5lZCB2YWx1ZSBiZWZvcmUgcmUtZW5hYmxpbmcgaW50ZXJydXB0IHRvCiAqIHByZXZlbnQgcmFjZXMgd2l0aCB0aGUgaW50ZXJydXB0IGhhbmRsZXIuIE5vdGUgdGhhdCBpbiBjb250aW51b3VzIG1vZGUgdGhlcmUKICogaXMgYSBjaGFuY2UgZm9yIENTU0FfTCByZWdpc3RlciBvdmVyZmxvdyBpbmJldHdlZW4gdGhlIHR3byByZWFkcyByZXN1bHRpbmcKICogaW4gaW5jb3JyZWN0IHJldHVybiB2YWx1ZS4KICovCmRtYV9hZGRyX3Qgb21hcF9nZXRfZG1hX3NyY19wb3MoaW50IGxjaCkKewoJcmV0dXJuIChkbWFfYWRkcl90KSAoT01BUF9ETUFfQ1NTQV9MKGxjaCkgfAoJCQkgICAgIChPTUFQX0RNQV9DU1NBX1UobGNoKSA8PCAxNikpOwp9CgovKgogKiBSZXR1cm5zIGN1cnJlbnQgcGh5c2ljYWwgZGVzdGluYXRpb24gYWRkcmVzcyBmb3IgdGhlIGdpdmVuIERNQSBjaGFubmVsLgogKiBJZiB0aGUgY2hhbm5lbCBpcyBydW5uaW5nIHRoZSBjYWxsZXIgbXVzdCBkaXNhYmxlIGludGVycnVwdHMgcHJpb3IgY2FsbGluZwogKiB0aGlzIGZ1bmN0aW9uIGFuZCBwcm9jZXNzIHRoZSByZXR1cm5lZCB2YWx1ZSBiZWZvcmUgcmUtZW5hYmxpbmcgaW50ZXJydXB0IHRvCiAqIHByZXZlbnQgcmFjZXMgd2l0aCB0aGUgaW50ZXJydXB0IGhhbmRsZXIuIE5vdGUgdGhhdCBpbiBjb250aW51b3VzIG1vZGUgdGhlcmUKICogaXMgYSBjaGFuY2UgZm9yIENEU0FfTCByZWdpc3RlciBvdmVyZmxvdyBpbmJldHdlZW4gdGhlIHR3byByZWFkcyByZXN1bHRpbmcKICogaW4gaW5jb3JyZWN0IHJldHVybiB2YWx1ZS4KICovCmRtYV9hZGRyX3Qgb21hcF9nZXRfZG1hX2RzdF9wb3MoaW50IGxjaCkKewoJcmV0dXJuIChkbWFfYWRkcl90KSAoT01BUF9ETUFfQ0RTQV9MKGxjaCkgfAoJCQkgICAgIChPTUFQX0RNQV9DRFNBX1UobGNoKSA8PCAxNikpOwp9CgpzdGF0aWMgaW50IF9faW5pdCBvbWFwX2luaXRfZG1hKHZvaWQpCnsKCWludCBjaCwgcjsKCglpZiAoY3B1X2lzX29tYXAxNTEwKCkpIHsKCQlwcmludGsoS0VSTl9JTkZPICJETUEgc3VwcG9ydCBmb3IgT01BUDE1MTAgaW5pdGlhbGl6ZWRcbiIpOwoJCWRtYV9jaGFuX2NvdW50ID0gOTsKCQllbmFibGVfMTUxMF9tb2RlID0gMTsKCX0gZWxzZSBpZiAoY3B1X2lzX29tYXAxNnh4KCkgfHwgY3B1X2lzX29tYXA3MzAoKSkgewoJCXByaW50ayhLRVJOX0lORk8gIk9NQVAgRE1BIGhhcmR3YXJlIHZlcnNpb24gJWRcbiIsCgkJICAgICAgIG9tYXBfcmVhZHcoT01BUF9ETUFfSFdfSUQpKTsKCQlwcmludGsoS0VSTl9JTkZPICJETUEgY2FwYWJpbGl0aWVzOiAlMDh4OiUwOHg6JTA0eDolMDR4OiUwNHhcbiIsCgkJICAgICAgIChvbWFwX3JlYWR3KE9NQVBfRE1BX0NBUFNfMF9VKSA8PCAxNikgfCBvbWFwX3JlYWR3KE9NQVBfRE1BX0NBUFNfMF9MKSwKCQkgICAgICAgKG9tYXBfcmVhZHcoT01BUF9ETUFfQ0FQU18xX1UpIDw8IDE2KSB8IG9tYXBfcmVhZHcoT01BUF9ETUFfQ0FQU18xX0wpLAoJCSAgICAgICBvbWFwX3JlYWR3KE9NQVBfRE1BX0NBUFNfMiksIG9tYXBfcmVhZHcoT01BUF9ETUFfQ0FQU18zKSwKCQkgICAgICAgb21hcF9yZWFkdyhPTUFQX0RNQV9DQVBTXzQpKTsKCQlpZiAoIWVuYWJsZV8xNTEwX21vZGUpIHsKCQkJdTE2IHc7CgoJCQkvKiBEaXNhYmxlIE9NQVAgMy4wLzMuMSBjb21wYXRpYmlsaXR5IG1vZGUuICovCgkJCXcgPSBvbWFwX3JlYWR3KE9NQVBfRE1BX0dTQ1IpOwoJCQl3IHw9IDEgPDwgMzsKCQkJb21hcF93cml0ZXcodywgT01BUF9ETUFfR1NDUik7CgkJCWRtYV9jaGFuX2NvdW50ID0gMTY7CgkJfSBlbHNlCgkJCWRtYV9jaGFuX2NvdW50ID0gOTsKCX0gZWxzZSB7CgkJZG1hX2NoYW5fY291bnQgPSAwOwoJCXJldHVybiAwOwoJfQoKCW1lbXNldCgmbGNkX2RtYSwgMCwgc2l6ZW9mKGxjZF9kbWEpKTsKCXNwaW5fbG9ja19pbml0KCZsY2RfZG1hLmxvY2spOwoJc3Bpbl9sb2NrX2luaXQoJmRtYV9jaGFuX2xvY2spOwoJbWVtc2V0KCZkbWFfY2hhbiwgMCwgc2l6ZW9mKGRtYV9jaGFuKSk7CgoJZm9yIChjaCA9IDA7IGNoIDwgZG1hX2NoYW5fY291bnQ7IGNoKyspIHsKCQlkbWFfY2hhbltjaF0uZGV2X2lkID0gLTE7CgkJZG1hX2NoYW5bY2hdLm5leHRfbGNoID0gLTE7CgoJCWlmIChjaCA+PSA2ICYmIGVuYWJsZV8xNTEwX21vZGUpCgkJCWNvbnRpbnVlOwoKCQkvKiByZXF1ZXN0X2lycSgpIGRvZXNuJ3QgbGlrZSBkZXZfaWQgKGllLiBjaCkgYmVpbmcgemVybywKCQkgKiBzbyB3ZSBoYXZlIHRvIGtsdWRnZSBhcm91bmQgdGhpcy4gKi8KCQlyID0gcmVxdWVzdF9pcnEoZG1hX2lycVtjaF0sIGRtYV9pcnFfaGFuZGxlciwgMCwgIkRNQSIsCgkJCQkodm9pZCAqKSAoY2ggKyAxKSk7CgkJaWYgKHIgIT0gMCkgewoJCQlpbnQgaTsKCgkJCXByaW50ayhLRVJOX0VSUiAidW5hYmxlIHRvIHJlcXVlc3QgSVJRICVkIGZvciBETUEgKGVycm9yICVkKVxuIiwKCQkJICAgICAgIGRtYV9pcnFbY2hdLCByKTsKCQkJZm9yIChpID0gMDsgaSA8IGNoOyBpKyspCgkJCQlmcmVlX2lycShkbWFfaXJxW2ldLCAodm9pZCAqKSAoaSArIDEpKTsKCQkJcmV0dXJuIHI7CgkJfQoJfQoJciA9IHJlcXVlc3RfaXJxKElOVF9ETUFfTENELCBsY2RfZG1hX2lycV9oYW5kbGVyLCAwLCAiTENEIERNQSIsIE5VTEwpOwoJaWYgKHIgIT0gMCkgewoJCWludCBpOwoKCQlwcmludGsoS0VSTl9FUlIgInVuYWJsZSB0byByZXF1ZXN0IElSUSBmb3IgTENEIERNQSAoZXJyb3IgJWQpXG4iLCByKTsKCQlmb3IgKGkgPSAwOyBpIDwgZG1hX2NoYW5fY291bnQ7IGkrKykKCQkJZnJlZV9pcnEoZG1hX2lycVtpXSwgKHZvaWQgKikgKGkgKyAxKSk7CgkJcmV0dXJuIHI7Cgl9CglyZXR1cm4gMDsKfQoKYXJjaF9pbml0Y2FsbChvbWFwX2luaXRfZG1hKTsKCgpFWFBPUlRfU1lNQk9MKG9tYXBfZ2V0X2RtYV9zcmNfcG9zKTsKRVhQT1JUX1NZTUJPTChvbWFwX2dldF9kbWFfZHN0X3Bvcyk7CkVYUE9SVF9TWU1CT0wob21hcF9jbGVhcl9kbWEpOwpFWFBPUlRfU1lNQk9MKG9tYXBfc2V0X2RtYV9wcmlvcml0eSk7CkVYUE9SVF9TWU1CT0wob21hcF9yZXF1ZXN0X2RtYSk7CkVYUE9SVF9TWU1CT0wob21hcF9mcmVlX2RtYSk7CkVYUE9SVF9TWU1CT0wob21hcF9zdGFydF9kbWEpOwpFWFBPUlRfU1lNQk9MKG9tYXBfc3RvcF9kbWEpOwpFWFBPUlRfU1lNQk9MKG9tYXBfZW5hYmxlX2RtYV9pcnEpOwpFWFBPUlRfU1lNQk9MKG9tYXBfZGlzYWJsZV9kbWFfaXJxKTsKCkVYUE9SVF9TWU1CT0wob21hcF9zZXRfZG1hX3RyYW5zZmVyX3BhcmFtcyk7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfZG1hX2NvbG9yX21vZGUpOwoKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9kbWFfc3JjX3BhcmFtcyk7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfZG1hX3NyY19pbmRleCk7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfZG1hX3NyY19kYXRhX3BhY2spOwpFWFBPUlRfU1lNQk9MKG9tYXBfc2V0X2RtYV9zcmNfYnVyc3RfbW9kZSk7CgpFWFBPUlRfU1lNQk9MKG9tYXBfc2V0X2RtYV9kZXN0X3BhcmFtcyk7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfZG1hX2Rlc3RfaW5kZXgpOwpFWFBPUlRfU1lNQk9MKG9tYXBfc2V0X2RtYV9kZXN0X2RhdGFfcGFjayk7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfZG1hX2Rlc3RfYnVyc3RfbW9kZSk7CgpFWFBPUlRfU1lNQk9MKG9tYXBfZG1hX2xpbmtfbGNoKTsKRVhQT1JUX1NZTUJPTChvbWFwX2RtYV91bmxpbmtfbGNoKTsKCkVYUE9SVF9TWU1CT0wob21hcF9yZXF1ZXN0X2xjZF9kbWEpOwpFWFBPUlRfU1lNQk9MKG9tYXBfZnJlZV9sY2RfZG1hKTsKRVhQT1JUX1NZTUJPTChvbWFwX2VuYWJsZV9sY2RfZG1hKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldHVwX2xjZF9kbWEpOwpFWFBPUlRfU1lNQk9MKG9tYXBfc3RvcF9sY2RfZG1hKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9sY2RfZG1hX2IxKTsKRVhQT1JUX1NZTUJPTChvbWFwX3NldF9sY2RfZG1hX3NpbmdsZV90cmFuc2Zlcik7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfbGNkX2RtYV9leHRfY29udHJvbGxlcik7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfbGNkX2RtYV9iMV9yb3RhdGlvbik7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfbGNkX2RtYV9iMV92eHJlcyk7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfbGNkX2RtYV9iMV9zY2FsZSk7CkVYUE9SVF9TWU1CT0wob21hcF9zZXRfbGNkX2RtYV9iMV9taXJyb3IpOwoK