LyoKICogKEMpIENvcHlyaWdodCAyMDAyCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCIDxkYW5pZWxAb21pY3Jvbi5zZT4uCiAqCiAqIFNlZSBmaWxlIENSRURJVFMgZm9yIGxpc3Qgb2YgcGVvcGxlIHdobyBjb250cmlidXRlZCB0byB0aGlzCiAqIHByb2plY3QuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YKICogdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sCiAqIE1BIDAyMTExLTEzMDcgVVNBCiAqLwoKLyogc3R1ZmYgc3BlY2lmaWMgZm9yIHRoZSBzYzUyMCwKICogYnV0IGlkZXBlbmRlbnQgb2YgaW1wbGVtZW50YXRpb24gKi8KCiNpbmNsdWRlIDxjb25maWcuaD4KCiNpZmRlZiBDT05GSUdfU0M1MjAKCiNpbmNsdWRlIDxjb21tb24uaD4KI2luY2x1ZGUgPGNvbmZpZy5oPgojaW5jbHVkZSA8cGNpLmg+CiNpZmRlZiBDT05GSUdfU0M1MjBfU1NJCiNpbmNsdWRlIDxhc20vaWMvc3NpLmg+CiNlbmRpZgojaW5jbHVkZSA8YXNtL2lvLmg+CiNpbmNsdWRlIDxhc20vcGNpLmg+CiNpbmNsdWRlIDxhc20vaWMvc2M1MjAuaD4KCkRFQ0xBUkVfR0xPQkFMX0RBVEFfUFRSOwoKLyoKICogdXRpbGl0eSBmdW5jdGlvbnMgZm9yIGJvYXJkcyBiYXNlZCBvbiB0aGUgQU1EIHNjNTIwCiAqCiAqIHZvaWQgd3JpdGVfbW1jcl9ieXRlKHUxNiBtbWNyLCB1OCBkYXRhKQogKiB2b2lkIHdyaXRlX21tY3Jfd29yZCh1MTYgbW1jciwgdTE2IGRhdGEpCiAqIHZvaWQgd3JpdGVfbW1jcl9sb25nKHUxNiBtbWNyLCB1MzIgZGF0YSkKICoKICogdTggICByZWFkX21tY3JfYnl0ZSh1MTYgbW1jcikKICogdTE2ICByZWFkX21tY3Jfd29yZCh1MTYgbW1jcikKICogdTMyICByZWFkX21tY3JfbG9uZyh1MTYgbW1jcikKICoKICogdm9pZCBpbml0X3NjNTIwKHZvaWQpCiAqIHVuc2lnbmVkIGxvbmcgaW5pdF9zYzUyMF9kcmFtKHZvaWQpCiAqIHZvaWQgcGNpX3NjNTIwX2luaXQoc3RydWN0IHBjaV9jb250cm9sbGVyICpob3NlKQogKgogKiB2b2lkIHJlc2V0X3RpbWVyKHZvaWQpCiAqIHVsb25nIGdldF90aW1lcih1bG9uZyBiYXNlKQogKiB2b2lkIHNldF90aW1lcih1bG9uZyB0KQogKiB2b2lkIHVkZWxheSh1bnNpZ25lZCBsb25nIHVzZWMpCiAqCiAqLwoKc3RhdGljIHUzMiBtbWNyX2Jhc2U9IDB4ZmZmZWYwMDA7Cgp2b2lkIHdyaXRlX21tY3JfYnl0ZSh1MTYgbW1jciwgdTggZGF0YSkKewoJd3JpdGViKGRhdGEsIG1tY3IrbW1jcl9iYXNlKTsKfQoKdm9pZCB3cml0ZV9tbWNyX3dvcmQodTE2IG1tY3IsIHUxNiBkYXRhKQp7Cgl3cml0ZXcoZGF0YSwgbW1jcittbWNyX2Jhc2UpOwp9Cgp2b2lkIHdyaXRlX21tY3JfbG9uZyh1MTYgbW1jciwgdTMyIGRhdGEpCnsKCXdyaXRlbChkYXRhLCBtbWNyK21tY3JfYmFzZSk7Cn0KCnU4IHJlYWRfbW1jcl9ieXRlKHUxNiBtbWNyKQp7CglyZXR1cm4gcmVhZGIobW1jcittbWNyX2Jhc2UpOwp9Cgp1MTYgcmVhZF9tbWNyX3dvcmQodTE2IG1tY3IpCnsKCXJldHVybiByZWFkdyhtbWNyK21tY3JfYmFzZSk7Cn0KCnUzMiByZWFkX21tY3JfbG9uZyh1MTYgbW1jcikKewoJcmV0dXJuIHJlYWRsKG1tY3IrbW1jcl9iYXNlKTsKfQoKCnZvaWQgaW5pdF9zYzUyMCh2b2lkKQp7CgkvKiBTZXQgdGhlIFVBUlR4Q1RMIHJlZ2lzdGVyIGF0IGl0J3Mgc2xvd2VyLAoJICogYmF1ZCBjbG9jayBnaXZpbmcgdXMgYSAxLjg0MzIgTUh6IHJlZmVyZW5jZQoJICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfVUFSVDFDVEwsIDcpOwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX1VBUlQyQ1RMLCA3KTsKCgkvKiBmaXJzdCBzZXQgdGhlIHRpbWVyIHBpbiBtYXBwaW5nICovCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfQ0xLU0VMLCAweDcyKTsJLyogbm8gY2xvY2sgZnJlcXVlbmN5IHNlbGVjdGVkLCB1c2UgMS4xODkyTUh6ICovCgoJLyogZW5hYmxlIFBDSSBidXMgYXJiaXRyZXIgKi8KCXdyaXRlX21tY3JfYnl0ZShTQzUyMF9TWVNBUkJDVEwsMHgwMik7ICAvKiBlbmFibGUgY29uY3VycmVudCBtb2RlICovCgoJd3JpdGVfbW1jcl93b3JkKFNDNTIwX1NZU0FSQk1FTkIsMHgxZik7IC8qIGVuYWJsZSBleHRlcm5hbCBncmFudHMgKi8KCXdyaXRlX21tY3Jfd29yZChTQzUyMF9IQkNUTCwweDA0KTsgICAgICAvKiBlbmFibGUgcG9zdGVkLXdyaXRlcyAqLwoKCglpZiAoQ09ORklHX1NZU19TQzUyMF9ISUdIX1NQRUVEKSB7CgkJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX0NQVUNUTCwgMHgyKTsJLyogc2V0IGl0IHRvIDEzMyBNSHogYW5kIHdyaXRlIGJhY2sgKi8KCQlnZC0+Y3B1X2NsayA9IDEzMzAwMDAwMDsKCQlwcmludGYoIiMjIENQVSBTcGVlZCBzZXQgdG8gMTMzTUh6XG4iKTsKCX0gZWxzZSB7CgkJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX0NQVUNUTCwgMSk7CS8qIHNldCBDUFUgdG8gMTAwIE1IeiBhbmQgd3JpdGUgYmFjayBjYWNoZSAqLwoJCXByaW50ZigiIyMgQ1BVIFNwZWVkIHNldCB0byAxMDBNSHpcbiIpOwoJCWdkLT5jcHVfY2xrID0gMTAwMDAwMDAwOwoJfQoKCgkvKiB3YWl0IGF0IGxlYXN0IG9uZSBtaWxsaXNlY29uZCAqLwoJYXNtKCJtb3ZsCSQweDIwMDAsJSVlY3hcbiIKCSAgICAid2FpdF9sb29wOglwdXNobCAlJWVjeFxuIgoJICAgICJwb3BsCSUlZWN4XG4iCgkgICAgImxvb3Agd2FpdF9sb29wXG4iOiA6IDogImVjeCIpOwoKCS8qIHR1cm4gb24gdGhlIFNEUkFNIHdyaXRlIGJ1ZmZlciAqLwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX0RCQ1RMLCAweDExKTsKCgkvKiB0dXJuIG9uIHRoZSBjYWNoZSBhbmQgZGlzYWJsZSB3cml0ZSB0aHJvdWdoICovCglhc20oIm1vdmwJJSVjcjAsICUlZWF4XG4iCgkgICAgImFuZGwJJDB4OWZmZmZmZmYsICUlZWF4XG4iCgkgICAgIm1vdmwJJSVlYXgsICUlY3IwXG4iICA6IDogOiAiZWF4Iik7Cn0KCnVuc2lnbmVkIGxvbmcgaW5pdF9zYzUyMF9kcmFtKHZvaWQpCnsKCWJkX3QgKmJkID0gZ2QtPmJkOwoKCXUzMiBkcmFtX3ByZXNlbnQ9MDsKCXUzMiBkcmFtX2N0cmw7CiNpZmRlZiBDT05GSUdfU1lTX1NEUkFNX0RSQ1RNQ1RMCgkvKiB0aGVzZSBtZW1vcnkgY29udHJvbCByZWdpc3RlcnMgYXJlIHNldCB1cCBpbiB0aGUgYXNzZW1iZXIgcGFydCwKCSAqIGluIHNjNTIwX2FzbS5TLCBkdXJpbmcgJ21lbV9pbml0Jy4gIElmIHdlIG11Y2sgd2l0aCB0aGVtIGhlcmUsCgkgKiBhZnRlciB3ZSBhcmUgcnVubmluZyBhIHN0YWNrIGluIFJBTSwgd2UgaGF2ZSB0cm91Ymxlcy4gIEJlc2lkZXMsCgkgKiB0aGVzZSByZWZyZXNoIGFuZCBkZWxheSB2YWx1ZXMgYXJlIGJldHRlciA/IHNpbXBseSBzcGVjaWZpZWQKCSAqIG91dHJpZ2h0IGluIHRoZSBpbmNsdWRlL2NvbmZpZ3Mve2NmZ30gZmlsZSBzaW5jZSB0aGUgSFcgZGVzaWduZXIKCSAqIHNpbXBseSBkaWN0YXRlcyBpdC4KCSAqLwojZWxzZQoJaW50IHZhbDsKCglpbnQgY2FzX3ByZWNoYXJnZV9kZWxheSA9IENPTkZJR19TWVNfU0RSQU1fUFJFQ0hBUkdFX0RFTEFZOwoJaW50IHJlZnJlc2hfcmF0ZSAgICAgICAgPSBDT05GSUdfU1lTX1NEUkFNX1JFRlJFU0hfUkFURTsKCWludCByYXNfY2FzX2RlbGF5ICAgICAgID0gQ09ORklHX1NZU19TRFJBTV9SQVNfQ0FTX0RFTEFZOwoKCS8qIHNldCBTRFJBTSBzcGVlZCBoZXJlICovCgoJcmVmcmVzaF9yYXRlLz03ODsKCWlmIChyZWZyZXNoX3JhdGU8PTEpIHsKCQl2YWwgPSAwOyAgLyogNy44dXMgKi8KCX0gZWxzZSBpZiAocmVmcmVzaF9yYXRlPT0yKSB7CgkJdmFsID0gMTsgIC8qIDE1LjZ1cyAqLwoJfSBlbHNlIGlmIChyZWZyZXNoX3JhdGU9PTMgfHwgcmVmcmVzaF9yYXRlPT00KSB7CgkJdmFsID0gMjsgIC8qIDMxLjJ1cyAqLwoJfSBlbHNlIHsKCQl2YWwgPSAzOyAgLyogNjIuNHVzICovCgl9CgoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX0RSQ0NUTCwgKHJlYWRfbW1jcl9ieXRlKFNDNTIwX0RSQ0NUTCkgJiAweGNmKSB8ICh2YWw8PDQpKTsKCgl2YWwgPSByZWFkX21tY3JfYnl0ZShTQzUyMF9EUkNUTUNUTCk7Cgl2YWwgJj0gMHhmMDsKCglpZiAoY2FzX3ByZWNoYXJnZV9kZWxheT09MykgewoJCXZhbCB8PSAweDA0OyAgIC8qIDNUICovCgl9IGVsc2UgaWYgKGNhc19wcmVjaGFyZ2VfZGVsYXk9PTQpIHsKCQl2YWwgfD0gMHgwODsgICAvKiA0VCAqLwoJfSBlbHNlIGlmIChjYXNfcHJlY2hhcmdlX2RlbGF5PjQpIHsKCQl2YWwgfD0gMHgwYzsKCX0KCglpZiAocmFzX2Nhc19kZWxheSA+IDMpIHsKCQl2YWwgfD0gMjsKCX0gZWxzZSB7CgkJdmFsIHw9IDE7Cgl9Cgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfRFJDVE1DVEwsIHZhbCk7CiNlbmRpZgoKCS8qIFdlIHJlYWQtYmFjayB0aGUgY29uZmlndXJhdGlvbiBvZiB0aGUgZHJhbQoJICogY29udHJvbGxlciB0aGF0IHRoZSBhc3NlbWJseSBjb2RlIHdyb3RlICovCglkcmFtX2N0cmwgPSByZWFkX21tY3JfbG9uZyhTQzUyMF9EUkNCRU5EQURSKTsKCgliZC0+YmlfZHJhbVswXS5zdGFydCA9IDA7CglpZiAoZHJhbV9jdHJsICYgMHg4MCkgewoJCS8qIGJhbmsgMCBlbmFibGVkICovCgkJZHJhbV9wcmVzZW50ID0gYmQtPmJpX2RyYW1bMV0uc3RhcnQgPSAoZHJhbV9jdHJsICYgMHg3ZikgPDwgMjI7CgkJYmQtPmJpX2RyYW1bMF0uc2l6ZSA9IGJkLT5iaV9kcmFtWzFdLnN0YXJ0OwoKCX0gZWxzZSB7CgkJYmQtPmJpX2RyYW1bMF0uc2l6ZSA9IDA7CgkJYmQtPmJpX2RyYW1bMV0uc3RhcnQgPSBiZC0+YmlfZHJhbVswXS5zdGFydDsKCX0KCglpZiAoZHJhbV9jdHJsICYgMHg4MDAwKSB7CgkJLyogYmFuayAxIGVuYWJsZWQgKi8KCQlkcmFtX3ByZXNlbnQgPSBiZC0+YmlfZHJhbVsyXS5zdGFydCA9IChkcmFtX2N0cmwgJiAweDdmMDApIDw8IDE0OwoJCWJkLT5iaV9kcmFtWzFdLnNpemUgPSBiZC0+YmlfZHJhbVsyXS5zdGFydCAtICBiZC0+YmlfZHJhbVsxXS5zdGFydDsKCX0gZWxzZSB7CgkJYmQtPmJpX2RyYW1bMV0uc2l6ZSA9IDA7CgkJYmQtPmJpX2RyYW1bMl0uc3RhcnQgPSBiZC0+YmlfZHJhbVsxXS5zdGFydDsKCX0KCglpZiAoZHJhbV9jdHJsICYgMHg4MDAwMDApIHsKCQkvKiBiYW5rIDIgZW5hYmxlZCAqLwoJCWRyYW1fcHJlc2VudCA9IGJkLT5iaV9kcmFtWzNdLnN0YXJ0ID0gKGRyYW1fY3RybCAmIDB4N2YwMDAwKSA8PCA2OwoJCWJkLT5iaV9kcmFtWzJdLnNpemUgPSBiZC0+YmlfZHJhbVszXS5zdGFydCAtICBiZC0+YmlfZHJhbVsyXS5zdGFydDsKCX0gZWxzZSB7CgkJYmQtPmJpX2RyYW1bMl0uc2l6ZSA9IDA7CgkJYmQtPmJpX2RyYW1bM10uc3RhcnQgPSBiZC0+YmlfZHJhbVsyXS5zdGFydDsKCX0KCglpZiAoZHJhbV9jdHJsICYgMHg4MDAwMDAwMCkgewoJCS8qIGJhbmsgMyBlbmFibGVkICovCgkJZHJhbV9wcmVzZW50ICA9IChkcmFtX2N0cmwgJiAweDdmMDAwMDAwKSA+PiAyOwoJCWJkLT5iaV9kcmFtWzNdLnNpemUgPSBkcmFtX3ByZXNlbnQgLSAgYmQtPmJpX2RyYW1bM10uc3RhcnQ7Cgl9IGVsc2UgewoJCWJkLT5iaV9kcmFtWzNdLnNpemUgPSAwOwoJfQoKCiNpZiAwCglwcmludGYoIkNvbmZpZ3VyZWQgJWQgYnl0ZXMgb2YgZHJhbVxuIiwgZHJhbV9wcmVzZW50KTsKI2VuZGlmCglnZC0+cmFtX3NpemUgPSBkcmFtX3ByZXNlbnQ7CgoJcmV0dXJuIGRyYW1fcHJlc2VudDsKfQoKCiNpZmRlZiBDT05GSUdfUENJCgoKc3RhdGljIHN0cnVjdCB7Cgl1OCBwcmlvcml0eTsKCXUxNiBsZXZlbF9yZWc7Cgl1OCBsZXZlbF9iaXQ7Cn0gc2M1MjBfaXJxW10gPSB7Cgl7IFNDNTIwX0lSUTAsICBTQzUyMF9NUElDTU9ERSwgIDB4MDEgfSwKCXsgU0M1MjBfSVJRMSwgIFNDNTIwX01QSUNNT0RFLCAgMHgwMiB9LAoJeyBTQzUyMF9JUlEyLCAgU0M1MjBfU0wxUElDTU9ERSwgMHgwMiB9LAoJeyBTQzUyMF9JUlEzLCAgU0M1MjBfTVBJQ01PREUsICAweDA4IH0sCgl7IFNDNTIwX0lSUTQsICBTQzUyMF9NUElDTU9ERSwgIDB4MTAgfSwKCXsgU0M1MjBfSVJRNSwgIFNDNTIwX01QSUNNT0RFLCAgMHgyMCB9LAoJeyBTQzUyMF9JUlE2LCAgU0M1MjBfTVBJQ01PREUsICAweDQwIH0sCgl7IFNDNTIwX0lSUTcsICBTQzUyMF9NUElDTU9ERSwgIDB4ODAgfSwKCgl7IFNDNTIwX0lSUTgsICBTQzUyMF9TTDFQSUNNT0RFLCAweDAxIH0sCgl7IFNDNTIwX0lSUTksICBTQzUyMF9TTDFQSUNNT0RFLCAweDAyIH0sCgl7IFNDNTIwX0lSUTEwLCBTQzUyMF9TTDFQSUNNT0RFLCAweDA0IH0sCgl7IFNDNTIwX0lSUTExLCBTQzUyMF9TTDFQSUNNT0RFLCAweDA4IH0sCgl7IFNDNTIwX0lSUTEyLCBTQzUyMF9TTDFQSUNNT0RFLCAweDEwIH0sCgl7IFNDNTIwX0lSUTEzLCBTQzUyMF9TTDFQSUNNT0RFLCAweDIwIH0sCgl7IFNDNTIwX0lSUTE0LCBTQzUyMF9TTDFQSUNNT0RFLCAweDQwIH0sCgl7IFNDNTIwX0lSUTE1LCBTQzUyMF9TTDFQSUNNT0RFLCAweDgwIH0KfTsKCgovKiBUaGUgaW50ZXJydXB0IHVzZWQgZm9yIFBDSSBJTlRBLUlOVEQgICovCmludCBzYzUyMF9wY2lfaW50c1sxNV0gPSB7CgktMSwgLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsCgkJLTEsIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEKfTsKCi8qIHV0aWxpdHkgZnVuY3Rpb24gdG8gY29uZmlndXJlIGEgcGNpIGludGVycnVwdCAqLwppbnQgcGNpX3NjNTIwX3NldF9pcnEoaW50IHBjaV9waW4sIGludCBpcnEpCnsKCWludCBpOwoKIyBpZiAxCglwcmludGYoInNldF9pcnEoKTogbWFwIElOVCVjIHRvIElSUSVkXG4iLCBwY2lfcGluICsgJ0EnLCBpcnEpOwojZW5kaWYKCWlmIChpcnEgPCAwIHx8IGlycSA+IDE1KSB7CgkJcmV0dXJuIC0xOyAvKiBpbGxlZ2FsIGlycSAqLwoJfQoKCWlmIChwY2lfcGluIDwgMCB8fCBwY2lfcGluID4gMTUpIHsKCQlyZXR1cm4gLTE7IC8qIGlsbGVnYWwgcGNpIGludCBwaW4gKi8KCX0KCgkvKiBmaXJzdCBkaXNhYmxlIGFueSBub24tcGNpIGludGVycnVwdCBzb3VyY2UgdGhhdCB1c2UKCSAqIHRoaXMgbGV2ZWwgKi8KCWZvciAoaT1TQzUyMF9HUFRNUjBNQVA7aTw9U0M1MjBfR1AxMElNQVA7aSsrKSB7CgkJaWYgKGk+PVNDNTIwX1BDSUlOVEFNQVAmJmk8PVNDNTIwX1BDSUlOVERNQVApIHsKCQkJY29udGludWU7CgkJfQoJCWlmIChyZWFkX21tY3JfYnl0ZShpKSA9PSBzYzUyMF9pcnFbaXJxXS5wcmlvcml0eSkgewoJCQl3cml0ZV9tbWNyX2J5dGUoaSwgU0M1MjBfSVJRX0RJU0FCTEVEKTsKCQl9Cgl9CgoJLyogU2V0IHRoZSB0cmlnZ2VyIHRvIGxldmVsICovCgl3cml0ZV9tbWNyX2J5dGUoc2M1MjBfaXJxW2lycV0ubGV2ZWxfcmVnLAoJCQlyZWFkX21tY3JfYnl0ZShzYzUyMF9pcnFbaXJxXS5sZXZlbF9yZWcpIHwgc2M1MjBfaXJxW2lycV0ubGV2ZWxfYml0KTsKCgoJaWYgKHBjaV9waW4gPCA0KSB7CgkJLyogUENJIElOVEEtSU5URCAqLwoJCS8qIHJvdXRlIHRoZSBpbnRlcnJ1cHQgKi8KCQl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfUENJSU5UQU1BUCArIHBjaV9waW4sIHNjNTIwX2lycVtpcnFdLnByaW9yaXR5KTsKCgoJfSBlbHNlIHsKCQkvKiBHUElSUTAtR1BJUlExMCB1c2VkIGZvciBhZGRpdGlvbmFsIFBDSSBJTlRTICovCgkJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX0dQMElNQVAgKyBwY2lfcGluIC0gNCwgc2M1MjBfaXJxW2lycV0ucHJpb3JpdHkpOwoKCQkvKiBhbHNvIHNldCB0aGUgcG9sYXJpdHkgaW4gdGhpcyBjYXNlICovCgkJd3JpdGVfbW1jcl93b3JkKFNDNTIwX0lOVFBJTlBPTCwKCQkJCXJlYWRfbW1jcl93b3JkKFNDNTIwX0lOVFBJTlBPTCkgfCAoMSA8PCAocGNpX3Bpbi00KSkpOwoKCX0KCgkvKiByZWdpc3RlciB0aGUgcGluICovCglzYzUyMF9wY2lfaW50c1twY2lfcGluXSA9IGlycTsKCgoJcmV0dXJuIDA7IC8qIE9LICovCn0KCnZvaWQgcGNpX3NjNTIwX2luaXQoc3RydWN0IHBjaV9jb250cm9sbGVyICpob3NlKQp7Cglob3NlLT5maXJzdF9idXNubyA9IDA7Cglob3NlLT5sYXN0X2J1c25vID0gMHhmZjsKCgkvKiBTeXN0ZW0gbWVtb3J5IHNwYWNlICovCglwY2lfc2V0X3JlZ2lvbihob3NlLT5yZWdpb25zICsgMCwKCQkgICAgICAgU0M1MjBfUENJX01FTU9SWV9CVVMsCgkJICAgICAgIFNDNTIwX1BDSV9NRU1PUllfUEhZUywKCQkgICAgICAgU0M1MjBfUENJX01FTU9SWV9TSVpFLAoJCSAgICAgICBQQ0lfUkVHSU9OX01FTSB8IFBDSV9SRUdJT05fTUVNT1JZKTsKCgkvKiBQQ0kgbWVtb3J5IHNwYWNlICovCglwY2lfc2V0X3JlZ2lvbihob3NlLT5yZWdpb25zICsgMSwKCQkgICAgICAgU0M1MjBfUENJX01FTV9CVVMsCgkJICAgICAgIFNDNTIwX1BDSV9NRU1fUEhZUywKCQkgICAgICAgU0M1MjBfUENJX01FTV9TSVpFLAoJCSAgICAgICBQQ0lfUkVHSU9OX01FTSk7CgoJLyogSVNBL1BDSSBtZW1vcnkgc3BhY2UgKi8KCXBjaV9zZXRfcmVnaW9uKGhvc2UtPnJlZ2lvbnMgKyAyLAoJCSAgICAgICBTQzUyMF9JU0FfTUVNX0JVUywKCQkgICAgICAgU0M1MjBfSVNBX01FTV9QSFlTLAoJCSAgICAgICBTQzUyMF9JU0FfTUVNX1NJWkUsCgkJICAgICAgIFBDSV9SRUdJT05fTUVNKTsKCgkvKiBQQ0kgSS9PIHNwYWNlICovCglwY2lfc2V0X3JlZ2lvbihob3NlLT5yZWdpb25zICsgMywKCQkgICAgICAgU0M1MjBfUENJX0lPX0JVUywKCQkgICAgICAgU0M1MjBfUENJX0lPX1BIWVMsCgkJICAgICAgIFNDNTIwX1BDSV9JT19TSVpFLAoJCSAgICAgICBQQ0lfUkVHSU9OX0lPKTsKCgkvKiBJU0EvUENJIEkvTyBzcGFjZSAqLwoJcGNpX3NldF9yZWdpb24oaG9zZS0+cmVnaW9ucyArIDQsCgkJICAgICAgIFNDNTIwX0lTQV9JT19CVVMsCgkJICAgICAgIFNDNTIwX0lTQV9JT19QSFlTLAoJCSAgICAgICBTQzUyMF9JU0FfSU9fU0laRSwKCQkgICAgICAgUENJX1JFR0lPTl9JTyk7CgoJaG9zZS0+cmVnaW9uX2NvdW50ID0gNTsKCglwY2lfc2V0dXBfdHlwZTEoaG9zZSwKCQkJU0M1MjBfUkVHX0FERFIsCgkJCVNDNTIwX1JFR19EQVRBKTsKCglwY2lfcmVnaXN0ZXJfaG9zZShob3NlKTsKCglob3NlLT5sYXN0X2J1c25vID0gcGNpX2hvc2Vfc2Nhbihob3NlKTsKCgkvKiBlbmFibGUgdGFyZ2V0IG1lbW9yeSBhY2Nlc2VzIG9uIGhvc3QgYnJpZ2UgKi8KCXBjaV93cml0ZV9jb25maWdfd29yZCgwLCBQQ0lfQ09NTUFORCwKCQkJICAgICAgUENJX0NPTU1BTkRfTUVNT1JZIHwgUENJX0NPTU1BTkRfTUFTVEVSKTsKCn0KCgojZW5kaWYKCiNpZmRlZiBDT05GSUdfU1lTX1RJTUVSX1NDNTIwCgoKdm9pZCByZXNldF90aW1lcih2b2lkKQp7Cgl3cml0ZV9tbWNyX3dvcmQoU0M1MjBfR1BUTVIwQ05ULCAwKTsKCXdyaXRlX21tY3Jfd29yZChTQzUyMF9HUFRNUjBDVEwsIDB4NjAwMSk7Cgp9Cgp1bG9uZyBnZXRfdGltZXIodWxvbmcgYmFzZSkKewoJLyogZml4bWU6IDMwIG9yIDMzICovCglyZXR1cm4JcmVhZF9tbWNyX3dvcmQoU0M1MjBfR1BUTVIwQ05UKSAvIDMzOwp9Cgp2b2lkIHNldF90aW1lcih1bG9uZyB0KQp7CgkvKiBGaXhNZTogdXNlIHR3byBjYXNjYWRlIGNvdXBsZWQgdGltZXJzICovCgl3cml0ZV9tbWNyX3dvcmQoU0M1MjBfR1BUTVIwQ1RMLCAweDQwMDEpOwoJd3JpdGVfbW1jcl93b3JkKFNDNTIwX0dQVE1SMENOVCwgdCozMyk7Cgl3cml0ZV9tbWNyX3dvcmQoU0M1MjBfR1BUTVIwQ1RMLCAweDYwMDEpOwp9CgoKdm9pZCB1ZGVsYXkodW5zaWduZWQgbG9uZyB1c2VjKQp7CglpbnQgbT0wOwoJbG9uZyB1OwoKCXJlYWRfbW1jcl93b3JkKFNDNTIwX1NXVE1STUlMTEkpOwoJcmVhZF9tbWNyX3dvcmQoU0M1MjBfU1dUTVJNSUNSTyk7CgojaWYgMAoJLyogZG8gbm90IGVuYWJsZSB0aGlzIGxpbmUsIHVkZWxheSBpcyB1c2VkIGluIHRoZSBzZXJpYWwgZHJpdmVyIC0+IHJlY3Vyc2lvbiAqLwoJcHJpbnRmKCJ1ZGVsYXk6ICVsZCBtLnUgJWQuJWQgIHRtLnR1ICVkLiVkXG4iLCB1c2VjLCBtLCB1LCB0bSwgdHUpOwojZW5kaWYKCXdoaWxlICgxKSB7CgoJCW0gKz0gcmVhZF9tbWNyX3dvcmQoU0M1MjBfU1dUTVJNSUxMSSk7CgkJdSA9IHJlYWRfbW1jcl93b3JkKFNDNTIwX1NXVE1STUlDUk8pICsgKG0gKiAxMDAwKTsKCgkJaWYgKHVzZWMgPD0gdSkgewoJCQlicmVhazsKCQl9Cgl9Cn0KCiNlbmRpZgoKaW50IHNzaV9zZXRfaW50ZXJmYWNlKGludCBmcmVxLCBpbnQgbHNiX2ZpcnN0LCBpbnQgaW52X2Nsb2NrLCBpbnQgaW52X3BoYXNlKQp7Cgl1OCB0ZW1wPTA7CgoJaWYgKGZyZXEgPj0gODE5MikgewoJCXRlbXAgfD0gQ1RMX0NMS19TRUxfNDsKCX0gZWxzZSBpZiAoZnJlcSA+PSA0MDk2KSB7CgkJdGVtcCB8PSBDVExfQ0xLX1NFTF84OwoJfSBlbHNlIGlmIChmcmVxID49IDIwNDgpIHsKCQl0ZW1wIHw9IENUTF9DTEtfU0VMXzE2OwoJfSBlbHNlIGlmIChmcmVxID49IDEwMjQpIHsKCQl0ZW1wIHw9IENUTF9DTEtfU0VMXzMyOwoJfSBlbHNlIGlmIChmcmVxID49IDUxMikgewoJCXRlbXAgfD0gQ1RMX0NMS19TRUxfNjQ7Cgl9IGVsc2UgaWYgKGZyZXEgPj0gMjU2KSB7CgkJdGVtcCB8PSBDVExfQ0xLX1NFTF8xMjg7Cgl9IGVsc2UgaWYgKGZyZXEgPj0gMTI4KSB7CgkJdGVtcCB8PSBDVExfQ0xLX1NFTF8yNTY7Cgl9IGVsc2UgewoJCXRlbXAgfD0gQ1RMX0NMS19TRUxfNTEyOwoJfQoKCWlmICghbHNiX2ZpcnN0KSB7CgkJdGVtcCB8PSBNU0JGX0VOQjsKCX0KCglpZiAoaW52X2Nsb2NrKSB7CgkJdGVtcCB8PSBDTEtfSU5WX0VOQjsKCX0KCglpZiAoaW52X3BoYXNlKSB7CgkJdGVtcCB8PSBQSFNfSU5WX0VOQjsKCX0KCgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfU1NJQ1RMLCB0ZW1wKTsKCglyZXR1cm4gMDsKfQoKdTggc3NpX3R4cnhfYnl0ZSh1OCBkYXRhKQp7Cgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfU1NJWE1JVCwgZGF0YSk7Cgl3aGlsZSAoKHJlYWRfbW1jcl9ieXRlKFNDNTIwX1NTSVNUQSkpICYgU1NJU1RBX0JTWSk7Cgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfU1NJQ01ELCBTU0lDTURfQ01EX1NFTF9YTUlUUkNWKTsKCXdoaWxlICgocmVhZF9tbWNyX2J5dGUoU0M1MjBfU1NJU1RBKSkgJiBTU0lTVEFfQlNZKTsKCXJldHVybiByZWFkX21tY3JfYnl0ZShTQzUyMF9TU0lSQ1YpOwp9CgoKdm9pZCBzc2lfdHhfYnl0ZSh1OCBkYXRhKQp7Cgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfU1NJWE1JVCwgZGF0YSk7Cgl3aGlsZSAoKHJlYWRfbW1jcl9ieXRlKFNDNTIwX1NTSVNUQSkpICYgU1NJU1RBX0JTWSk7Cgl3cml0ZV9tbWNyX2J5dGUoU0M1MjBfU1NJQ01ELCBTU0lDTURfQ01EX1NFTF9YTUlUKTsKfQoKdTggc3NpX3J4X2J5dGUodm9pZCkKewoJd2hpbGUgKChyZWFkX21tY3JfYnl0ZShTQzUyMF9TU0lTVEEpKSAmIFNTSVNUQV9CU1kpOwoJd3JpdGVfbW1jcl9ieXRlKFNDNTIwX1NTSUNNRCwgU1NJQ01EX0NNRF9TRUxfUkNWKTsKCXdoaWxlICgocmVhZF9tbWNyX2J5dGUoU0M1MjBfU1NJU1RBKSkgJiBTU0lTVEFfQlNZKTsKCXJldHVybiByZWFkX21tY3JfYnl0ZShTQzUyMF9TU0lSQ1YpOwp9CgojZW5kaWYgLyogQ09ORklHX1NDNTIwICovCg==