LyoKICogT01BUDIgUmVtb3RlIEZyYW1lIEJ1ZmZlciBJbnRlcmZhY2Ugc3VwcG9ydAogKgogKiBDb3B5cmlnaHQgKEMpIDIwMDUgTm9raWEgQ29ycG9yYXRpb24KICogQXV0aG9yOiBKdWhhIFlyavZs5CA8anVoYS55cmpvbGFAbm9raWEuY29tPgogKgkgICBJbXJlIERlYWsgPGltcmUuZGVha0Bub2tpYS5jb20+CiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZQogKiBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyCiAqIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQKICogV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFsb25nCiAqIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIEluYy4sCiAqIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNywgVVNBLgogKi8KI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvZGVsYXkuaD4KI2luY2x1ZGUgPGxpbnV4L2kyYy5oPgojaW5jbHVkZSA8bGludXgvZXJyLmg+CiNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KI2luY2x1ZGUgPGxpbnV4L2Nsay5oPgojaW5jbHVkZSA8bGludXgvaW8uaD4KCiNpbmNsdWRlIDxtYWNoL29tYXBmYi5oPgoKI2luY2x1ZGUgImRpc3BjLmgiCgovKiBUbyB3b3JrIGFyb3VuZCBhbiBSRkJJIHRyYW5zZmVyIHJhdGUgbGltaXRhdGlvbiAqLwojZGVmaW5lIE9NQVBfUkZCSV9SQVRFX0xJTUlUCTEKCiNkZWZpbmUgUkZCSV9CQVNFCQkweDQ4MDUwODAwCiNkZWZpbmUgUkZCSV9SRVZJU0lPTgkJMHgwMDAwCiNkZWZpbmUgUkZCSV9TWVNDT05GSUcJCTB4MDAxMAojZGVmaW5lIFJGQklfU1lTU1RBVFVTCQkweDAwMTQKI2RlZmluZSBSRkJJX0NPTlRST0wJCTB4MDA0MAojZGVmaW5lIFJGQklfUElYRUxfQ05UCQkweDAwNDQKI2RlZmluZSBSRkJJX0xJTkVfTlVNQkVSCTB4MDA0OAojZGVmaW5lIFJGQklfQ01ECQkweDAwNGMKI2RlZmluZSBSRkJJX1BBUkFNCQkweDAwNTAKI2RlZmluZSBSRkJJX0RBVEEJCTB4MDA1NAojZGVmaW5lIFJGQklfUkVBRAkJMHgwMDU4CiNkZWZpbmUgUkZCSV9TVEFUVVMJCTB4MDA1YwojZGVmaW5lIFJGQklfQ09ORklHMAkJMHgwMDYwCiNkZWZpbmUgUkZCSV9PTk9GRl9USU1FMAkweDAwNjQKI2RlZmluZSBSRkJJX0NZQ0xFX1RJTUUwCTB4MDA2OAojZGVmaW5lIFJGQklfREFUQV9DWUNMRTFfMAkweDAwNmMKI2RlZmluZSBSRkJJX0RBVEFfQ1lDTEUyXzAJMHgwMDcwCiNkZWZpbmUgUkZCSV9EQVRBX0NZQ0xFM18wCTB4MDA3NAojZGVmaW5lIFJGQklfVlNZTkNfV0lEVEgJMHgwMDkwCiNkZWZpbmUgUkZCSV9IU1lOQ19XSURUSAkweDAwOTQKCiNkZWZpbmUgRElTUENfQkFTRQkJMHg0ODA1MDQwMAojZGVmaW5lIERJU1BDX0NPTlRST0wJCTB4MDA0MAoKc3RhdGljIHN0cnVjdCB7Cgl2b2lkIF9faW9tZW0JKmJhc2U7Cgl2b2lkCQkoKmxjZGNfY2FsbGJhY2spKHZvaWQgKmRhdGEpOwoJdm9pZAkJKmxjZGNfY2FsbGJhY2tfZGF0YTsKCXVuc2lnbmVkIGxvbmcJbDRfa2h6OwoJaW50CQliaXRzX3Blcl9jeWNsZTsKCXN0cnVjdCBvbWFwZmJfZGV2aWNlICpmYmRldjsKCXN0cnVjdCBjbGsJKmRzc19pY2s7CglzdHJ1Y3QgY2xrCSpkc3MxX2ZjazsKCXVuc2lnbmVkCXRlYXJzeW5jX3Bpbl9jbnQ7Cgl1bnNpZ25lZAl0ZWFyc3luY19tb2RlOwp9IHJmYmk7CgpzdGF0aWMgaW5saW5lIHZvaWQgcmZiaV93cml0ZV9yZWcoaW50IGlkeCwgdTMyIHZhbCkKewoJX19yYXdfd3JpdGVsKHZhbCwgcmZiaS5iYXNlICsgaWR4KTsKfQoKc3RhdGljIGlubGluZSB1MzIgcmZiaV9yZWFkX3JlZyhpbnQgaWR4KQp7CglyZXR1cm4gX19yYXdfcmVhZGwocmZiaS5iYXNlICsgaWR4KTsKfQoKc3RhdGljIGludCByZmJpX2dldF9jbG9ja3Modm9pZCkKewoJcmZiaS5kc3NfaWNrID0gY2xrX2dldChyZmJpLmZiZGV2LT5kZXYsICJpY2siKTsKCWlmIChJU19FUlIocmZiaS5kc3NfaWNrKSkgewoJCWRldl9lcnIocmZiaS5mYmRldi0+ZGV2LCAiY2FuJ3QgZ2V0IGlja1xuIik7CgkJcmV0dXJuIFBUUl9FUlIocmZiaS5kc3NfaWNrKTsKCX0KCglyZmJpLmRzczFfZmNrID0gY2xrX2dldChyZmJpLmZiZGV2LT5kZXYsICJkc3MxX2ZjayIpOwoJaWYgKElTX0VSUihyZmJpLmRzczFfZmNrKSkgewoJCWRldl9lcnIocmZiaS5mYmRldi0+ZGV2LCAiY2FuJ3QgZ2V0IGRzczFfZmNrXG4iKTsKCQljbGtfcHV0KHJmYmkuZHNzX2ljayk7CgkJcmV0dXJuIFBUUl9FUlIocmZiaS5kc3MxX2Zjayk7Cgl9CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHJmYmlfcHV0X2Nsb2Nrcyh2b2lkKQp7CgljbGtfcHV0KHJmYmkuZHNzMV9mY2spOwoJY2xrX3B1dChyZmJpLmRzc19pY2spOwp9CgpzdGF0aWMgdm9pZCByZmJpX2VuYWJsZV9jbG9ja3MoaW50IGVuYWJsZSkKewoJaWYgKGVuYWJsZSkgewoJCWNsa19lbmFibGUocmZiaS5kc3NfaWNrKTsKCQljbGtfZW5hYmxlKHJmYmkuZHNzMV9mY2spOwoJfSBlbHNlIHsKCQljbGtfZGlzYWJsZShyZmJpLmRzczFfZmNrKTsKCQljbGtfZGlzYWJsZShyZmJpLmRzc19pY2spOwoJfQp9CgoKI2lmZGVmIFZFUkJPU0UKc3RhdGljIHZvaWQgcmZiaV9wcmludF90aW1pbmdzKHZvaWQpCnsKCXUzMiBsOwoJdTMyIHRpbWU7CgoJbCA9IHJmYmlfcmVhZF9yZWcoUkZCSV9DT05GSUcwKTsKCXRpbWUgPSAxMDAwMDAwMDAwIC8gcmZiaS5sNF9raHo7CglpZiAobCAmICgxIDw8IDQpKQoJCXRpbWUgKj0gMjsKCglkZXZfZGJnKHJmYmkuZmJkZXYtPmRldiwgIlRpY2sgdGltZSAldSBwc1xuIiwgdGltZSk7CglsID0gcmZiaV9yZWFkX3JlZyhSRkJJX09OT0ZGX1RJTUUwKTsKCWRldl9kYmcocmZiaS5mYmRldi0+ZGV2LAoJCSJDU09OVElNRSAlZCwgQ1NPRkZUSU1FICVkLCBXRU9OVElNRSAlZCwgV0VPRkZUSU1FICVkLCAiCgkJIlJFT05USU1FICVkLCBSRU9GRlRJTUUgJWRcbiIsCgkJbCAmIDB4MGYsIChsID4+IDQpICYgMHgzZiwgKGwgPj4gMTApICYgMHgwZiwgKGwgPj4gMTQpICYgMHgzZiwKCQkobCA+PiAyMCkgJiAweDBmLCAobCA+PiAyNCkgJiAweDNmKTsKCglsID0gcmZiaV9yZWFkX3JlZyhSRkJJX0NZQ0xFX1RJTUUwKTsKCWRldl9kYmcocmZiaS5mYmRldi0+ZGV2LAoJCSJXRUNZQ0xFVElNRSAlZCwgUkVDWUNMRVRJTUUgJWQsIENTUFVMU0VXSURUSCAlZCwgIgoJCSJBQ0NFU1NUSU1FICVkXG4iLAoJCShsICYgMHgzZiksIChsID4+IDYpICYgMHgzZiwgKGwgPj4gMTIpICYgMHgzZiwKCQkobCA+PiAyMikgJiAweDNmKTsKfQojZWxzZQpzdGF0aWMgdm9pZCByZmJpX3ByaW50X3RpbWluZ3Modm9pZCkge30KI2VuZGlmCgpzdGF0aWMgdm9pZCByZmJpX3NldF90aW1pbmdzKGNvbnN0IHN0cnVjdCBleHRpZl90aW1pbmdzICp0KQp7Cgl1MzIgbDsKCglCVUdfT04oIXQtPmNvbnZlcnRlZCk7CgoJcmZiaV9lbmFibGVfY2xvY2tzKDEpOwoJcmZiaV93cml0ZV9yZWcoUkZCSV9PTk9GRl9USU1FMCwgdC0+dGltWzBdKTsKCXJmYmlfd3JpdGVfcmVnKFJGQklfQ1lDTEVfVElNRTAsIHQtPnRpbVsxXSk7CgoJbCA9IHJmYmlfcmVhZF9yZWcoUkZCSV9DT05GSUcwKTsKCWwgJj0gfigxIDw8IDQpOwoJbCB8PSAodC0+dGltWzJdID8gMSA6IDApIDw8IDQ7CglyZmJpX3dyaXRlX3JlZyhSRkJJX0NPTkZJRzAsIGwpOwoKCXJmYmlfcHJpbnRfdGltaW5ncygpOwoJcmZiaV9lbmFibGVfY2xvY2tzKDApOwp9CgpzdGF0aWMgdm9pZCByZmJpX2dldF9jbGtfaW5mbyh1MzIgKmNsa19wZXJpb2QsIHUzMiAqbWF4X2Nsa19kaXYpCnsKCSpjbGtfcGVyaW9kID0gMTAwMDAwMDAwMCAvIHJmYmkubDRfa2h6OwoJKm1heF9jbGtfZGl2ID0gMjsKfQoKc3RhdGljIGludCBwc190b19yZmJpX3RpY2tzKGludCB0aW1lLCBpbnQgZGl2KQp7Cgl1bnNpZ25lZCBsb25nIHRpY2tfcHM7CglpbnQgcmV0OwoKCS8qIENhbGN1bGF0ZSBpbiBwaWNvc2VjcyB0byB5aWVsZCBtb3JlIGV4YWN0IHJlc3VsdHMgKi8KCXRpY2tfcHMgPSAxMDAwMDAwMDAwIC8gKHJmYmkubDRfa2h6KSAqIGRpdjsKCglyZXQgPSAodGltZSArIHRpY2tfcHMgLSAxKSAvIHRpY2tfcHM7CgoJcmV0dXJuIHJldDsKfQoKI2lmZGVmIE9NQVBfUkZCSV9SQVRFX0xJTUlUCnN0YXRpYyB1bnNpZ25lZCBsb25nIHJmYmlfZ2V0X21heF90eF9yYXRlKHZvaWQpCnsKCXVuc2lnbmVkIGxvbmcJbDRfcmF0ZSwgZHNzMV9yYXRlOwoJaW50CQltaW5fbDRfdGlja3MgPSAwOwoJaW50CQlpOwoKCS8qIEFjY29yZGluZyB0byBUSSB0aGlzIGNhbid0IGJlIGNhbGN1bGF0ZWQgc28gbWFrZSB0aGUKCSAqIGFkanVzdG1lbnRzIGZvciBhIGNvdXBsZSBvZiBrbm93biBmcmVxdWVuY2llcyBhbmQgd2FybiBmb3IKCSAqIG90aGVycy4KCSAqLwoJc3RhdGljIGNvbnN0IHN0cnVjdCB7CgkJdW5zaWduZWQgbG9uZyBsNF9jbGs7CQkvKiBIWiAqLwoJCXVuc2lnbmVkIGxvbmcgZHNzMV9jbGs7CQkvKiBIWiAqLwoJCXVuc2lnbmVkIGxvbmcgbWluX2w0X3RpY2tzOwoJfSBmdGFiW10gPSB7CgkJeyA1NSwJMTMyLAk3LCB9LAkJLyogNy44NiBNUGl4L3MgKi8KCQl7IDExMCwJMTEwLAkxMiwgfSwJCS8qIDkuMTYgTVBpeC9zICovCgkJeyAxMTAsCTEzMiwJMTAsIH0sCQkvKiAxMSAgIE1waXgvcyAqLwoJCXsgMTIwLAkxMjAsCTEwLCB9LAkJLyogMTIgICBNcGl4L3MgKi8KCQl7IDEzMywJMTMzLAkxMCwgfSwJCS8qIDEzLjMgTXBpeC9zICovCgl9OwoKCWw0X3JhdGUgPSByZmJpLmw0X2toeiAvIDEwMDA7Cglkc3MxX3JhdGUgPSBjbGtfZ2V0X3JhdGUocmZiaS5kc3MxX2ZjaykgLyAxMDAwMDAwOwoKCWZvciAoaSA9IDA7IGkgPCBBUlJBWV9TSVpFKGZ0YWIpOyBpKyspIHsKCQkvKiBVc2UgYSB3aW5kb3cgaW5zdGVhZCBvZiBhbiBleGFjdCBtYXRjaCwgdG8gYWNjb3VudAoJCSAqIGZvciBkaWZmZXJlbnQgRFBMTCBtdWx0aXBsaWVyIC8gZGl2aWRlciBwYWlycy4KCQkgKi8KCQlpZiAoYWJzKGZ0YWJbaV0ubDRfY2xrIC0gbDRfcmF0ZSkgPCAzICYmCgkJICAgIGFicyhmdGFiW2ldLmRzczFfY2xrIC0gZHNzMV9yYXRlKSA8IDMpIHsKCQkJbWluX2w0X3RpY2tzID0gZnRhYltpXS5taW5fbDRfdGlja3M7CgkJCWJyZWFrOwoJCX0KCX0KCWlmIChpID09IEFSUkFZX1NJWkUoZnRhYikpIHsKCQkvKiBDYW4ndCBiZSBzdXJlLCByZXR1cm4gYW55d2F5IHRoZSBtYXhpbXVtIG5vdAoJCSAqIHJhdGUtbGltaXRlZC4gVGhpcyBtaWdodCBjYXVzZSBhIHByb2JsZW0gb25seSBmb3IgdGhlCgkJICogdGVhcmluZyBzeW5jaHJvbmlzYXRpb24uCgkJICovCgkJZGV2X2VycihyZmJpLmZiZGV2LT5kZXYsCgkJCSJjYW4ndCBkZXRlcm1pbmUgbWF4aW11bSBSRkJJIHRyYW5zZmVyIHJhdGVcbiIpOwoJCXJldHVybiByZmJpLmw0X2toeiAqIDEwMDA7Cgl9CglyZXR1cm4gcmZiaS5sNF9raHogKiAxMDAwIC8gbWluX2w0X3RpY2tzOwp9CiNlbHNlCnN0YXRpYyBpbnQgcmZiaV9nZXRfbWF4X3R4X3JhdGUodm9pZCkKewoJcmV0dXJuIHJmYmkubDRfa2h6ICogMTAwMDsKfQojZW5kaWYKCgpzdGF0aWMgaW50IHJmYmlfY29udmVydF90aW1pbmdzKHN0cnVjdCBleHRpZl90aW1pbmdzICp0KQp7Cgl1MzIgbDsKCWludCByZW9uLCByZW9mZiwgd2Vvbiwgd2VvZmYsIGNzb24sIGNzb2ZmLCBjc19wdWxzZTsKCWludCBhY3RpbSwgcmVjeWMsIHdlY3ljOwoJaW50IGRpdiA9IHQtPmNsa19kaXY7CgoJaWYgKGRpdiA8PSAwIHx8IGRpdiA+IDIpCgkJcmV0dXJuIC0xOwoKCS8qIE1ha2Ugc3VyZSB0aGF0IGFmdGVyIGNvbnZlcnNpb24gaXQgc3RpbGwgaG9sZHMgdGhhdDoKCSAqIHdlb2ZmID4gd2VvbiwgcmVvZmYgPiByZW9uLCByZWN5YyA+PSByZW9mZiwgd2VjeWMgPj0gd2VvZmYsCgkgKiBjc29mZiA+IGNzb24sIGNzb2ZmID49IG1heCh3ZW9mZiwgcmVvZmYpLCBhY3RpbSA+IHJlb24KCSAqLwoJd2VvbiA9IHBzX3RvX3JmYmlfdGlja3ModC0+d2Vfb25fdGltZSwgZGl2KTsKCXdlb2ZmID0gcHNfdG9fcmZiaV90aWNrcyh0LT53ZV9vZmZfdGltZSwgZGl2KTsKCWlmICh3ZW9mZiA8PSB3ZW9uKQoJCXdlb2ZmID0gd2VvbiArIDE7CglpZiAod2VvbiA+IDB4MGYpCgkJcmV0dXJuIC0xOwoJaWYgKHdlb2ZmID4gMHgzZikKCQlyZXR1cm4gLTE7CgoJcmVvbiA9IHBzX3RvX3JmYmlfdGlja3ModC0+cmVfb25fdGltZSwgZGl2KTsKCXJlb2ZmID0gcHNfdG9fcmZiaV90aWNrcyh0LT5yZV9vZmZfdGltZSwgZGl2KTsKCWlmIChyZW9mZiA8PSByZW9uKQoJCXJlb2ZmID0gcmVvbiArIDE7CglpZiAocmVvbiA+IDB4MGYpCgkJcmV0dXJuIC0xOwoJaWYgKHJlb2ZmID4gMHgzZikKCQlyZXR1cm4gLTE7CgoJY3NvbiA9IHBzX3RvX3JmYmlfdGlja3ModC0+Y3Nfb25fdGltZSwgZGl2KTsKCWNzb2ZmID0gcHNfdG9fcmZiaV90aWNrcyh0LT5jc19vZmZfdGltZSwgZGl2KTsKCWlmIChjc29mZiA8PSBjc29uKQoJCWNzb2ZmID0gY3NvbiArIDE7CglpZiAoY3NvZmYgPCBtYXgod2VvZmYsIHJlb2ZmKSkKCQljc29mZiA9IG1heCh3ZW9mZiwgcmVvZmYpOwoJaWYgKGNzb24gPiAweDBmKQoJCXJldHVybiAtMTsKCWlmIChjc29mZiA+IDB4M2YpCgkJcmV0dXJuIC0xOwoKCWwgPSAgY3NvbjsKCWwgfD0gY3NvZmYgPDwgNDsKCWwgfD0gd2VvbiAgPDwgMTA7CglsIHw9IHdlb2ZmIDw8IDE0OwoJbCB8PSByZW9uICA8PCAyMDsKCWwgfD0gcmVvZmYgPDwgMjQ7CgoJdC0+dGltWzBdID0gbDsKCglhY3RpbSA9IHBzX3RvX3JmYmlfdGlja3ModC0+YWNjZXNzX3RpbWUsIGRpdik7CglpZiAoYWN0aW0gPD0gcmVvbikKCQlhY3RpbSA9IHJlb24gKyAxOwoJaWYgKGFjdGltID4gMHgzZikKCQlyZXR1cm4gLTE7CgoJd2VjeWMgPSBwc190b19yZmJpX3RpY2tzKHQtPndlX2N5Y2xlX3RpbWUsIGRpdik7CglpZiAod2VjeWMgPCB3ZW9mZikKCQl3ZWN5YyA9IHdlb2ZmOwoJaWYgKHdlY3ljID4gMHgzZikKCQlyZXR1cm4gLTE7CgoJcmVjeWMgPSBwc190b19yZmJpX3RpY2tzKHQtPnJlX2N5Y2xlX3RpbWUsIGRpdik7CglpZiAocmVjeWMgPCByZW9mZikKCQlyZWN5YyA9IHJlb2ZmOwoJaWYgKHJlY3ljID4gMHgzZikKCQlyZXR1cm4gLTE7CgoJY3NfcHVsc2UgPSBwc190b19yZmJpX3RpY2tzKHQtPmNzX3B1bHNlX3dpZHRoLCBkaXYpOwoJaWYgKGNzX3B1bHNlID4gMHgzZikKCQlyZXR1cm4gLTE7CgoJbCA9ICB3ZWN5YzsKCWwgfD0gcmVjeWMgICAgPDwgNjsKCWwgfD0gY3NfcHVsc2UgPDwgMTI7CglsIHw9IGFjdGltICAgIDw8IDIyOwoKCXQtPnRpbVsxXSA9IGw7CgoJdC0+dGltWzJdID0gZGl2IC0gMTsKCgl0LT5jb252ZXJ0ZWQgPSAxOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHJmYmlfc2V0dXBfdGVhcnN5bmModW5zaWduZWQgcGluX2NudCwKCQkJICAgICAgIHVuc2lnbmVkIGhzX3B1bHNlX3RpbWUsIHVuc2lnbmVkIHZzX3B1bHNlX3RpbWUsCgkJCSAgICAgICBpbnQgaHNfcG9sX2ludiwgaW50IHZzX3BvbF9pbnYsIGludCBleHRpZl9kaXYpCnsKCWludCBocywgdnM7CglpbnQgbWluOwoJdTMyIGw7CgoJaWYgKHBpbl9jbnQgIT0gMSAmJiBwaW5fY250ICE9IDIpCgkJcmV0dXJuIC1FSU5WQUw7CgoJaHMgPSBwc190b19yZmJpX3RpY2tzKGhzX3B1bHNlX3RpbWUsIDEpOwoJdnMgPSBwc190b19yZmJpX3RpY2tzKHZzX3B1bHNlX3RpbWUsIDEpOwoJaWYgKGhzIDwgMikKCQlyZXR1cm4gLUVET007CglpZiAocGluX2NudCA9PSAyKQoJCW1pbiA9IDI7CgllbHNlCgkJbWluID0gNDsKCWlmICh2cyA8IG1pbikKCQlyZXR1cm4gLUVET007CglpZiAodnMgPT0gaHMpCgkJcmV0dXJuIC1FSU5WQUw7CglyZmJpLnRlYXJzeW5jX3Bpbl9jbnQgPSBwaW5fY250OwoJZGV2X2RiZyhyZmJpLmZiZGV2LT5kZXYsCgkJInNldHVwX3RlYXJzeW5jOiBwaW5zICVkIGhzICVkIHZzICVkIGhzX2ludiAlZCB2c19pbnYgJWRcbiIsCgkJcGluX2NudCwgaHMsIHZzLCBoc19wb2xfaW52LCB2c19wb2xfaW52KTsKCglyZmJpX2VuYWJsZV9jbG9ja3MoMSk7CglyZmJpX3dyaXRlX3JlZyhSRkJJX0hTWU5DX1dJRFRILCBocyk7CglyZmJpX3dyaXRlX3JlZyhSRkJJX1ZTWU5DX1dJRFRILCB2cyk7CgoJbCA9IHJmYmlfcmVhZF9yZWcoUkZCSV9DT05GSUcwKTsKCWlmIChoc19wb2xfaW52KQoJCWwgJj0gfigxIDw8IDIxKTsKCWVsc2UKCQlsIHw9IDEgPDwgMjE7CglpZiAodnNfcG9sX2ludikKCQlsICY9IH4oMSA8PCAyMCk7CgllbHNlCgkJbCB8PSAxIDw8IDIwOwoJcmZiaV9lbmFibGVfY2xvY2tzKDApOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHJmYmlfZW5hYmxlX3RlYXJzeW5jKGludCBlbmFibGUsIHVuc2lnbmVkIGxpbmUpCnsKCXUzMiBsOwoKCWRldl9kYmcocmZiaS5mYmRldi0+ZGV2LCAidGVhcnN5bmMgJWQgbGluZSAlZCBtb2RlICVkXG4iLAoJCWVuYWJsZSwgbGluZSwgcmZiaS50ZWFyc3luY19tb2RlKTsKCWlmIChsaW5lID4gKDEgPDwgMTEpIC0gMSkKCQlyZXR1cm4gLUVJTlZBTDsKCglyZmJpX2VuYWJsZV9jbG9ja3MoMSk7CglsID0gcmZiaV9yZWFkX3JlZyhSRkJJX0NPTkZJRzApOwoJbCAmPSB+KDB4MyA8PCAyKTsKCWlmIChlbmFibGUpIHsKCQlyZmJpLnRlYXJzeW5jX21vZGUgPSByZmJpLnRlYXJzeW5jX3Bpbl9jbnQ7CgkJbCB8PSByZmJpLnRlYXJzeW5jX21vZGUgPDwgMjsKCX0gZWxzZQoJCXJmYmkudGVhcnN5bmNfbW9kZSA9IDA7CglyZmJpX3dyaXRlX3JlZyhSRkJJX0NPTkZJRzAsIGwpOwoJcmZiaV93cml0ZV9yZWcoUkZCSV9MSU5FX05VTUJFUiwgbGluZSk7CglyZmJpX2VuYWJsZV9jbG9ja3MoMCk7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHJmYmlfd3JpdGVfY29tbWFuZChjb25zdCB2b2lkICpidWYsIHVuc2lnbmVkIGludCBsZW4pCnsKCXJmYmlfZW5hYmxlX2Nsb2NrcygxKTsKCWlmIChyZmJpLmJpdHNfcGVyX2N5Y2xlID09IDE2KSB7CgkJY29uc3QgdTE2ICp3ID0gYnVmOwoJCUJVR19PTihsZW4gJiAxKTsKCQlmb3IgKDsgbGVuOyBsZW4gLT0gMikKCQkJcmZiaV93cml0ZV9yZWcoUkZCSV9DTUQsICp3KyspOwoJfSBlbHNlIHsKCQljb25zdCB1OCAqYiA9IGJ1ZjsKCQlCVUdfT04ocmZiaS5iaXRzX3Blcl9jeWNsZSAhPSA4KTsKCQlmb3IgKDsgbGVuOyBsZW4tLSkKCQkJcmZiaV93cml0ZV9yZWcoUkZCSV9DTUQsICpiKyspOwoJfQoJcmZiaV9lbmFibGVfY2xvY2tzKDApOwp9CgpzdGF0aWMgdm9pZCByZmJpX3JlYWRfZGF0YSh2b2lkICpidWYsIHVuc2lnbmVkIGludCBsZW4pCnsKCXJmYmlfZW5hYmxlX2Nsb2NrcygxKTsKCWlmIChyZmJpLmJpdHNfcGVyX2N5Y2xlID09IDE2KSB7CgkJdTE2ICp3ID0gYnVmOwoJCUJVR19PTihsZW4gJiB+MSk7CgkJZm9yICg7IGxlbjsgbGVuIC09IDIpIHsKCQkJcmZiaV93cml0ZV9yZWcoUkZCSV9SRUFELCAwKTsKCQkJKncrKyA9IHJmYmlfcmVhZF9yZWcoUkZCSV9SRUFEKTsKCQl9Cgl9IGVsc2UgewoJCXU4ICpiID0gYnVmOwoJCUJVR19PTihyZmJpLmJpdHNfcGVyX2N5Y2xlICE9IDgpOwoJCWZvciAoOyBsZW47IGxlbi0tKSB7CgkJCXJmYmlfd3JpdGVfcmVnKFJGQklfUkVBRCwgMCk7CgkJCSpiKysgPSByZmJpX3JlYWRfcmVnKFJGQklfUkVBRCk7CgkJfQoJfQoJcmZiaV9lbmFibGVfY2xvY2tzKDApOwp9CgpzdGF0aWMgdm9pZCByZmJpX3dyaXRlX2RhdGEoY29uc3Qgdm9pZCAqYnVmLCB1bnNpZ25lZCBpbnQgbGVuKQp7CglyZmJpX2VuYWJsZV9jbG9ja3MoMSk7CglpZiAocmZiaS5iaXRzX3Blcl9jeWNsZSA9PSAxNikgewoJCWNvbnN0IHUxNiAqdyA9IGJ1ZjsKCQlCVUdfT04obGVuICYgMSk7CgkJZm9yICg7IGxlbjsgbGVuIC09IDIpCgkJCXJmYmlfd3JpdGVfcmVnKFJGQklfUEFSQU0sICp3KyspOwoJfSBlbHNlIHsKCQljb25zdCB1OCAqYiA9IGJ1ZjsKCQlCVUdfT04ocmZiaS5iaXRzX3Blcl9jeWNsZSAhPSA4KTsKCQlmb3IgKDsgbGVuOyBsZW4tLSkKCQkJcmZiaV93cml0ZV9yZWcoUkZCSV9QQVJBTSwgKmIrKyk7Cgl9CglyZmJpX2VuYWJsZV9jbG9ja3MoMCk7Cn0KCnN0YXRpYyB2b2lkIHJmYmlfdHJhbnNmZXJfYXJlYShpbnQgd2lkdGgsIGludCBoZWlnaHQsCgkJCQl2b2lkIChjYWxsYmFjaykodm9pZCAqIGRhdGEpLCB2b2lkICpkYXRhKQp7Cgl1MzIgdzsKCglCVUdfT04oY2FsbGJhY2sgPT0gTlVMTCk7CgoJcmZiaV9lbmFibGVfY2xvY2tzKDEpOwoJb21hcF9kaXNwY19zZXRfbGNkX3NpemUod2lkdGgsIGhlaWdodCk7CgoJcmZiaS5sY2RjX2NhbGxiYWNrID0gY2FsbGJhY2s7CglyZmJpLmxjZGNfY2FsbGJhY2tfZGF0YSA9IGRhdGE7CgoJcmZiaV93cml0ZV9yZWcoUkZCSV9QSVhFTF9DTlQsIHdpZHRoICogaGVpZ2h0KTsKCgl3ID0gcmZiaV9yZWFkX3JlZyhSRkJJX0NPTlRST0wpOwoJdyB8PSAxOwkJCQkvKiBlbmFibGUgKi8KCWlmICghcmZiaS50ZWFyc3luY19tb2RlKQoJCXcgfD0gMSA8PCA0OwkJLyogaW50ZXJuYWwgdHJpZ2dlciwgcmVzZXQgYnkgSFcgKi8KCXJmYmlfd3JpdGVfcmVnKFJGQklfQ09OVFJPTCwgdyk7CgoJb21hcF9kaXNwY19lbmFibGVfbGNkX291dCgxKTsKfQoKc3RhdGljIGlubGluZSB2b2lkIF9zdG9wX3RyYW5zZmVyKHZvaWQpCnsKCXUzMiB3OwoKCXcgPSByZmJpX3JlYWRfcmVnKFJGQklfQ09OVFJPTCk7CglyZmJpX3dyaXRlX3JlZyhSRkJJX0NPTlRST0wsIHcgJiB+KDEgPDwgMCkpOwoJcmZiaV9lbmFibGVfY2xvY2tzKDApOwp9CgpzdGF0aWMgdm9pZCByZmJpX2RtYV9jYWxsYmFjayh2b2lkICpkYXRhKQp7Cglfc3RvcF90cmFuc2ZlcigpOwoJcmZiaS5sY2RjX2NhbGxiYWNrKHJmYmkubGNkY19jYWxsYmFja19kYXRhKTsKfQoKc3RhdGljIHZvaWQgcmZiaV9zZXRfYml0c19wZXJfY3ljbGUoaW50IGJwYykKewoJdTMyIGw7CgoJcmZiaV9lbmFibGVfY2xvY2tzKDEpOwoJbCA9IHJmYmlfcmVhZF9yZWcoUkZCSV9DT05GSUcwKTsKCWwgJj0gfigweDAzIDw8IDApOwoKCXN3aXRjaCAoYnBjKSB7CgljYXNlIDg6CgkJYnJlYWs7CgljYXNlIDE2OgoJCWwgfD0gMzsKCQlicmVhazsKCWRlZmF1bHQ6CgkJQlVHKCk7Cgl9CglyZmJpX3dyaXRlX3JlZyhSRkJJX0NPTkZJRzAsIGwpOwoJcmZiaS5iaXRzX3Blcl9jeWNsZSA9IGJwYzsKCXJmYmlfZW5hYmxlX2Nsb2NrcygwKTsKfQoKc3RhdGljIGludCByZmJpX2luaXQoc3RydWN0IG9tYXBmYl9kZXZpY2UgKmZiZGV2KQp7Cgl1MzIgbDsKCWludCByOwoKCXJmYmkuZmJkZXYgPSBmYmRldjsKCXJmYmkuYmFzZSA9IGlvcmVtYXAoUkZCSV9CQVNFLCBTWl8xSyk7CglpZiAoIXJmYmkuYmFzZSkgewoJCWRldl9lcnIoZmJkZXYtPmRldiwgImNhbid0IGlvcmVtYXAgUkZCSVxuIik7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CgoJaWYgKChyID0gcmZiaV9nZXRfY2xvY2tzKCkpIDwgMCkKCQlyZXR1cm4gcjsKCXJmYmlfZW5hYmxlX2Nsb2NrcygxKTsKCglyZmJpLmw0X2toeiA9IGNsa19nZXRfcmF0ZShyZmJpLmRzc19pY2spIC8gMTAwMDsKCgkvKiBSZXNldCAqLwoJcmZiaV93cml0ZV9yZWcoUkZCSV9TWVNDT05GSUcsIDEgPDwgMSk7Cgl3aGlsZSAoIShyZmJpX3JlYWRfcmVnKFJGQklfU1lTU1RBVFVTKSAmICgxIDw8IDApKSk7CgoJbCA9IHJmYmlfcmVhZF9yZWcoUkZCSV9TWVNDT05GSUcpOwoJLyogRW5hYmxlIGF1dG9pZGxlIGFuZCBzbWFydC1pZGxlICovCglsIHw9ICgxIDw8IDApIHwgKDIgPDwgMyk7CglyZmJpX3dyaXRlX3JlZyhSRkJJX1NZU0NPTkZJRywgbCk7CgoJLyogMTYtYml0IGludGVyZmFjZSwgSVRFIHRyaWdnZXIgbW9kZSwgMTYtYml0IGRhdGEgKi8KCWwgPSAoMHgwMyA8PCAwKSB8ICgweDAwIDw8IDIpIHwgKDB4MDEgPDwgNSkgfCAoMHgwMiA8PCA3KTsKCWwgfD0gKDAgPDwgOSkgfCAoMSA8PCAyMCkgfCAoMSA8PCAyMSk7CglyZmJpX3dyaXRlX3JlZyhSRkJJX0NPTkZJRzAsIGwpOwoKCXJmYmlfd3JpdGVfcmVnKFJGQklfREFUQV9DWUNMRTFfMCwgMHgwMDAwMDAxMCk7CgoJbCA9IHJmYmlfcmVhZF9yZWcoUkZCSV9DT05UUk9MKTsKCS8qIFNlbGVjdCBDUzAsIGNsZWFyIGJ5cGFzcyBtb2RlICovCglsID0gKDB4MDEgPDwgMik7CglyZmJpX3dyaXRlX3JlZyhSRkJJX0NPTlRST0wsIGwpOwoKCWlmICgociA9IG9tYXBfZGlzcGNfcmVxdWVzdF9pcnEocmZiaV9kbWFfY2FsbGJhY2ssIE5VTEwpKSA8IDApIHsKCQlkZXZfZXJyKGZiZGV2LT5kZXYsICJjYW4ndCBnZXQgRElTUEMgaXJxXG4iKTsKCQlyZmJpX2VuYWJsZV9jbG9ja3MoMCk7CgkJcmV0dXJuIHI7Cgl9CgoJbCA9IHJmYmlfcmVhZF9yZWcoUkZCSV9SRVZJU0lPTik7Cglwcl9pbmZvKCJvbWFwZmI6IFJGQkkgdmVyc2lvbiAlZC4lZCBpbml0aWFsaXplZFxuIiwKCQkobCA+PiA0KSAmIDB4MGYsIGwgJiAweDBmKTsKCglyZmJpX2VuYWJsZV9jbG9ja3MoMCk7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIHJmYmlfY2xlYW51cCh2b2lkKQp7CglvbWFwX2Rpc3BjX2ZyZWVfaXJxKCk7CglyZmJpX3B1dF9jbG9ja3MoKTsKCWlvdW5tYXAocmZiaS5iYXNlKTsKfQoKY29uc3Qgc3RydWN0IGxjZF9jdHJsX2V4dGlmIG9tYXAyX2V4dF9pZiA9IHsKCS5pbml0CQkJPSByZmJpX2luaXQsCgkuY2xlYW51cAkJPSByZmJpX2NsZWFudXAsCgkuZ2V0X2Nsa19pbmZvCQk9IHJmYmlfZ2V0X2Nsa19pbmZvLAoJLmdldF9tYXhfdHhfcmF0ZQk9IHJmYmlfZ2V0X21heF90eF9yYXRlLAoJLnNldF9iaXRzX3Blcl9jeWNsZQk9IHJmYmlfc2V0X2JpdHNfcGVyX2N5Y2xlLAoJLmNvbnZlcnRfdGltaW5ncwk9IHJmYmlfY29udmVydF90aW1pbmdzLAoJLnNldF90aW1pbmdzCQk9IHJmYmlfc2V0X3RpbWluZ3MsCgkud3JpdGVfY29tbWFuZAkJPSByZmJpX3dyaXRlX2NvbW1hbmQsCgkucmVhZF9kYXRhCQk9IHJmYmlfcmVhZF9kYXRhLAoJLndyaXRlX2RhdGEJCT0gcmZiaV93cml0ZV9kYXRhLAoJLnRyYW5zZmVyX2FyZWEJCT0gcmZiaV90cmFuc2Zlcl9hcmVhLAoJLnNldHVwX3RlYXJzeW5jCQk9IHJmYmlfc2V0dXBfdGVhcnN5bmMsCgkuZW5hYmxlX3RlYXJzeW5jCT0gcmZiaV9lbmFibGVfdGVhcnN5bmMsCgoJLm1heF90cmFuc21pdF9zaXplCT0gKHUzMikgfjAsCn07Cgo=