LyoKICogKEMpIENvcHlyaWdodCAyMDAyCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCLCBkYW5pZWxAb21pY3Jvbi5zZQogKgogKiAoQykgQ29weXJpZ2h0IDIwMDIKICogU3lzZ28gUmVhbC1UaW1lIFNvbHV0aW9ucywgR21iSCA8d3d3LmVsaW5vcy5jb20+CiAqIEFsZXggWnVlcGtlIDxhenVAc3lzZ28uZGU+CiAqCiAqIFNlZSBmaWxlIENSRURJVFMgZm9yIGxpc3Qgb2YgcGVvcGxlIHdobyBjb250cmlidXRlZCB0byB0aGlzCiAqIHByb2plY3QuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YKICogdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sCiAqIE1BIDAyMTExLTEzMDcgVVNBCiAqLwoKI2luY2x1ZGUgPGNvbW1vbi5oPgojaW5jbHVkZSA8YXNtL2lvLmg+Cgp1bG9uZyBteWZsdXNoKHZvaWQpOwoKCiNkZWZpbmUgU0M1MjBfTUFYX0ZMQVNIX0JBTktTICAzCiNkZWZpbmUgU0M1MjBfRkxBU0hfQkFOSzBfQkFTRSAweDM4MDAwMDAwICAvKiBCT09UQ1MgKi8KI2RlZmluZSBTQzUyMF9GTEFTSF9CQU5LMV9CQVNFIDB4MzAwMDAwMDAgIC8qIFJPTUNTMCAqLwojZGVmaW5lIFNDNTIwX0ZMQVNIX0JBTksyX0JBU0UgMHgyODAwMDAwMCAgLyogUk9NQ1MxICovCiNkZWZpbmUgU0M1MjBfRkxBU0hfQkFOS1NJWkUgICAweDgwMDAwMDAKCiNkZWZpbmUgQU1EMjlMVjAxNl9TSVpFICAgICAgICAweDIwMDAwMAojZGVmaW5lIEFNRDI5TFYwMTZfU0VDVE9SUyAgICAgMzIKCmZsYXNoX2luZm9fdCAgICBmbGFzaF9pbmZvW1NDNTIwX01BWF9GTEFTSF9CQU5LU107CgojZGVmaW5lIENNRF9SRUFEX0FSUkFZCQkweDAwRjAwMEYwCiNkZWZpbmUgQ01EX1VOTE9DSzEJCTB4MDBBQTAwQUEKI2RlZmluZSBDTURfVU5MT0NLMgkJMHgwMDU1MDA1NQojZGVmaW5lIENNRF9FUkFTRV9TRVRVUAkJMHgwMDgwMDA4MAojZGVmaW5lIENNRF9FUkFTRV9DT05GSVJNCTB4MDAzMDAwMzAKI2RlZmluZSBDTURfUFJPR1JBTQkJMHgwMEEwMDBBMAojZGVmaW5lIENNRF9VTkxPQ0tfQllQQVNTCTB4MDAyMDAwMjAKCgojZGVmaW5lIEJJVF9FUkFTRV9ET05FCQkweDAwODAwMDgwCiNkZWZpbmUgQklUX1JEWV9NQVNLCQkweDAwODAwMDgwCiNkZWZpbmUgQklUX1BST0dSQU1fRVJST1IJMHgwMDIwMDAyMAojZGVmaW5lIEJJVF9USU1FT1VUCQkweDgwMDAwMDAwIC8qIG91ciBmbGFnICovCgojZGVmaW5lIFJFQURZIDEKI2RlZmluZSBFUlIgICAyCiNkZWZpbmUgVE1PICAgNAoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8KCnVsb25nIGZsYXNoX2luaXQodm9pZCkKewoJaW50IGksIGo7Cgl1bG9uZyBzaXplID0gMDsKCglmb3IgKGkgPSAwOyBpIDwgU0M1MjBfTUFYX0ZMQVNIX0JBTktTOyBpKyspIHsKCQl1bG9uZyBmbGFzaGJhc2UgPSAwOwoJCWludCBzZWN0c2l6ZSA9IDA7CgkJaWYgKGk9PTAgfHwgaT09MikgewoJCQkvKiBGaXhNZTogdGhpcyBhc3N1bWVzIHRoYXQgYmFuayAwIGFuZCAyCgkJCSAqIGFyZSBtYXBwZWQgdG8gdGhlIHR3byA4TWIgYmFua3MgKi8KCQkJZmxhc2hfaW5mb1tpXS5mbGFzaF9pZCA9CgkJCQkoQU1EX01BTlVGQUNUICYgRkxBU0hfVkVORE1BU0spIHwKCQkJCShBTURfSURfTFYwMTZCICYgRkxBU0hfVFlQRU1BU0spOwoKCQkJZmxhc2hfaW5mb1tpXS5zaXplID0gQU1EMjlMVjAxNl9TSVpFKjQ7CgkJCWZsYXNoX2luZm9baV0uc2VjdG9yX2NvdW50ID0gQU1EMjlMVjAxNl9TRUNUT1JTOwoJCQlzZWN0c2l6ZSA9IChBTUQyOUxWMDE2X1NJWkUqNCkvQU1EMjlMVjAxNl9TRUNUT1JTOwoJCX0gZWxzZSB7CgkJCS8qIEZpeE1lOiB0aGlzIGFzc3VtZXMgdGhhdCBiYW5rMSBpcyB1bm1hcHBlZAoJCQkgKiAob3IgbWFwcGVkIHRvIHRoZSBzYW1lIGZsYXNoIGJhbmsgYXMgQk9PVENTKSAqLwoJCQlmbGFzaF9pbmZvW2ldLmZsYXNoX2lkID0gMDsKCQkJZmxhc2hfaW5mb1tpXS5zaXplID0gMDsKCQkJZmxhc2hfaW5mb1tpXS5zZWN0b3JfY291bnQgPSAwOwoJCQlzZWN0c2l6ZT0wOwoJCX0KCQltZW1zZXQoZmxhc2hfaW5mb1tpXS5wcm90ZWN0LCAwLCBDT05GSUdfU1lTX01BWF9GTEFTSF9TRUNUKTsKCQlzd2l0Y2ggKGkpIHsKCQljYXNlIDA6CgkJCWZsYXNoYmFzZSA9IFNDNTIwX0ZMQVNIX0JBTkswX0JBU0U7CgkJCWJyZWFrOwoJCWNhc2UgMToKCQkJZmxhc2hiYXNlID0gU0M1MjBfRkxBU0hfQkFOSzFfQkFTRTsKCQkJYnJlYWs7CgkJY2FzZSAyOgoJCQlmbGFzaGJhc2UgPSBTQzUyMF9GTEFTSF9CQU5LMF9CQVNFOwoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQlwYW5pYygiY29uZmlndXJlZCB0b28gbWFueSBmbGFzaCBiYW5rcyFcbiIpOwoJCX0KCgkJZm9yIChqID0gMDsgaiA8IGZsYXNoX2luZm9baV0uc2VjdG9yX2NvdW50OyBqKyspIHsKCQkJZmxhc2hfaW5mb1tpXS5zdGFydFtqXSA9IHNlY3RzaXplOwoJCQlmbGFzaF9pbmZvW2ldLnN0YXJ0W2pdID0gZmxhc2hiYXNlICsgaiAqIHNlY3RzaXplOwoJCX0KCQlzaXplICs9IGZsYXNoX2luZm9baV0uc2l6ZTsKCX0KCgkvKgoJICogUHJvdGVjdCBtb25pdG9yIGFuZCBlbnZpcm9ubWVudCBzZWN0b3JzCgkgKi8KCWZsYXNoX3Byb3RlY3QoRkxBR19QUk9URUNUX1NFVCwKCQkgICAgICBpMzg2Ym9vdF9zdGFydC1TQzUyMF9GTEFTSF9CQU5LMF9CQVNFLAoJCSAgICAgIGkzODZib290X2VuZC1TQzUyMF9GTEFTSF9CQU5LMF9CQVNFLAoJCSAgICAgICZmbGFzaF9pbmZvWzBdKTsKCiNpZmRlZiBDT05GSUdfRU5WX0FERFIKCWZsYXNoX3Byb3RlY3QoRkxBR19QUk9URUNUX1NFVCwKCQkgICAgICBDT05GSUdfRU5WX0FERFIsCgkJICAgICAgQ09ORklHX0VOVl9BRERSICsgQ09ORklHX0VOVl9TSVpFIC0gMSwKCQkgICAgICAmZmxhc2hfaW5mb1swXSk7CiNlbmRpZgoJcmV0dXJuIHNpemU7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICovCnZvaWQgZmxhc2hfcHJpbnRfaW5mbyhmbGFzaF9pbmZvX3QgKmluZm8pCnsKCWludCBpOwoKCXN3aXRjaCAoaW5mby0+Zmxhc2hfaWQgJiBGTEFTSF9WRU5ETUFTSykgewoJY2FzZSAoQU1EX01BTlVGQUNUICYgRkxBU0hfVkVORE1BU0spOgoJCXByaW50ZigiQU1EOiAiKTsKCQlicmVhazsKCWRlZmF1bHQ6CgkJcHJpbnRmKCJVbmtub3duIFZlbmRvciAiKTsKCQlicmVhazsKCX0KCglzd2l0Y2ggKGluZm8tPmZsYXNoX2lkICYgRkxBU0hfVFlQRU1BU0spIHsKCWNhc2UgKEFNRF9JRF9MVjAxNkIgJiBGTEFTSF9UWVBFTUFTSyk6CgkJcHJpbnRmKCI0eCBBbWQyOUxWMDE2QiAoMTZNYml0KVxuIik7CgkJYnJlYWs7CglkZWZhdWx0OgoJCXByaW50ZigiVW5rbm93biBDaGlwIFR5cGVcbiIpOwoJCWdvdG8gZG9uZTsKCQlicmVhazsKCX0KCglwcmludGYoIiAgU2l6ZTogJWxkIE1CIGluICVkIFNlY3RvcnNcbiIsCgkgICAgICAgaW5mby0+c2l6ZSA+PiAyMCwgaW5mby0+c2VjdG9yX2NvdW50KTsKCglwcmludGYoIiAgU2VjdG9yIFN0YXJ0IEFkZHJlc3NlczoiKTsKCWZvciAoaSA9IDA7IGkgPCBpbmZvLT5zZWN0b3JfY291bnQ7IGkrKykgewoJCWlmICgoaSAlIDUpID09IDApIHsKCQkJcHJpbnRmICgiXG4gICAiKTsKCQl9CgkJcHJpbnRmICgiICUwOGxYJXMiLCBpbmZvLT5zdGFydFtpXSwKCQkJaW5mby0+cHJvdGVjdFtpXSA/ICIgKFJPKSIgOiAiICAgICAiKTsKCX0KCXByaW50ZiAoIlxuIik7CgoJZG9uZToKfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8KCmludCBmbGFzaF9lcmFzZShmbGFzaF9pbmZvX3QgKmluZm8sIGludCBzX2ZpcnN0LCBpbnQgc19sYXN0KQp7Cgl1bG9uZyByZXN1bHQ7CglpbnQgaWZsYWcsIHByb3QsIHNlY3Q7CglpbnQgcmMgPSBFUlJfT0s7CglpbnQgY2hpcDEsIGNoaXAyOwoKCS8qIGZpcnN0IGxvb2sgZm9yIHByb3RlY3Rpb24gYml0cyAqLwoKCWlmIChpbmZvLT5mbGFzaF9pZCA9PSBGTEFTSF9VTktOT1dOKSB7CgkJcmV0dXJuIEVSUl9VTktOT1dOX0ZMQVNIX1RZUEU7Cgl9CgoJaWYgKChzX2ZpcnN0IDwgMCkgfHwgKHNfZmlyc3QgPiBzX2xhc3QpKSB7CgkJcmV0dXJuIEVSUl9JTlZBTDsKCX0KCglpZiAoKGluZm8tPmZsYXNoX2lkICYgRkxBU0hfVkVORE1BU0spICE9CgkgICAgKEFNRF9NQU5VRkFDVCAmIEZMQVNIX1ZFTkRNQVNLKSkgewoJCXJldHVybiBFUlJfVU5LTk9XTl9GTEFTSF9WRU5ET1I7Cgl9CgoJcHJvdCA9IDA7Cglmb3IgKHNlY3Q9c19maXJzdDsgc2VjdDw9c19sYXN0OyArK3NlY3QpIHsKCQlpZiAoaW5mby0+cHJvdGVjdFtzZWN0XSkgewoJCQlwcm90Kys7CgkJfQoJfQoJaWYgKHByb3QpIHsKCQlyZXR1cm4gRVJSX1BST1RFQ1RFRDsKCX0KCgkvKgoJICogRGlzYWJsZSBpbnRlcnJ1cHRzIHdoaWNoIG1pZ2h0IGNhdXNlIGEgdGltZW91dAoJICogaGVyZS4gUmVtZW1iZXIgdGhhdCBvdXIgZXhjZXB0aW9uIHZlY3RvcnMgYXJlCgkgKiBhdCBhZGRyZXNzIDAgaW4gdGhlIGZsYXNoLCBhbmQgd2UgZG9uJ3Qgd2FudCBhCgkgKiAodGlja2VyKSBleGNlcHRpb24gdG8gaGFwcGVuIHdoaWxlIHRoZSBmbGFzaAoJICogY2hpcCBpcyBpbiBwcm9ncmFtbWluZyBtb2RlLgoJICovCglpZmxhZyA9IGRpc2FibGVfaW50ZXJydXB0cygpOwoKCS8qIFN0YXJ0IGVyYXNlIG9uIHVucHJvdGVjdGVkIHNlY3RvcnMgKi8KCWZvciAoc2VjdCA9IHNfZmlyc3Q7IHNlY3Q8PXNfbGFzdCAmJiAhY3RybGMoKTsgc2VjdCsrKSB7CgkJcHJpbnRmKCJFcmFzaW5nIHNlY3RvciAlMmQgLi4uICIsIHNlY3QpOwoKCQkvKiBhcm0gc2ltcGxlLCBub24gaW50ZXJydXB0IGRlcGVuZGVudCB0aW1lciAqLwoJCXJlc2V0X3RpbWVyKCk7CgoJCWlmIChpbmZvLT5wcm90ZWN0W3NlY3RdID09IDApIHsKCQkJLyogbm90IHByb3RlY3RlZCAqLwoJCQl1bG9uZyBhZGRyID0gaW5mby0+c3RhcnRbc2VjdF07CgoJCQl3cml0ZWwoQ01EX1VOTE9DSzEsIGFkZHIgKyAxKTsKCQkJd3JpdGVsKENNRF9VTkxPQ0syLCBhZGRyICsgMik7CgkJCXdyaXRlbChDTURfRVJBU0VfU0VUVVAsIGFkZHIgKyAxKTsKCgkJCXdyaXRlbChDTURfVU5MT0NLMSwgYWRkciArIDEpOwoJCQl3cml0ZWwoQ01EX1VOTE9DSzIsIGFkZHIgKyAyKTsKCQkJd3JpdGVsKENNRF9FUkFTRV9DT05GSVJNLCBhZGRyKTsKCgoJCQkvKiB3YWl0IHVudGlsIGZsYXNoIGlzIHJlYWR5ICovCgkJCWNoaXAxID0gY2hpcDIgPSAwOwoKCQkJZG8gewoJCQkJcmVzdWx0ID0gcmVhZGwoYWRkcik7CgoJCQkJLyogY2hlY2sgdGltZW91dCAqLwoJCQkJaWYgKGdldF90aW1lcigwKSA+IENPTkZJR19TWVNfRkxBU0hfRVJBU0VfVE9VVCkgewoJCQkJCXdyaXRlbChDTURfUkVBRF9BUlJBWSwgYWRkciArIDEpOwoJCQkJCWNoaXAxID0gVE1POwoJCQkJCWJyZWFrOwoJCQkJfQoKCQkJCWlmICghY2hpcDEgJiYgKHJlc3VsdCAmIDB4RkZGRikgJiBCSVRfRVJBU0VfRE9ORSkgewoJCQkJCWNoaXAxID0gUkVBRFk7CgkJCQl9CgoJCQkJaWYgKCFjaGlwMSAmJiAocmVzdWx0ICYgMHhGRkZGKSAmIEJJVF9QUk9HUkFNX0VSUk9SKSB7CgkJCQkJY2hpcDEgPSBFUlI7CgkJCQl9CgoJCQkJaWYgKCFjaGlwMiAmJiAocmVzdWx0ID4+IDE2KSAmIEJJVF9FUkFTRV9ET05FKSB7CgkJCQkJY2hpcDIgPSBSRUFEWTsKCQkJCX0KCgkJCQlpZiAoIWNoaXAyICYmIChyZXN1bHQgPj4gMTYpICYgQklUX1BST0dSQU1fRVJST1IpIHsKCQkJCQljaGlwMiA9IEVSUjsKCQkJCX0KCgkJCX0gIHdoaWxlICghY2hpcDEgfHwgIWNoaXAyKTsKCgkJCXdyaXRlbChDTURfUkVBRF9BUlJBWSwgYWRkciArIDEpOwoKCQkJaWYgKGNoaXAxID09IEVSUiB8fCBjaGlwMiA9PSBFUlIpIHsKCQkJCXJjID0gRVJSX1BST0dfRVJST1I7CgkJCQlnb3RvIG91dGFoZXJlOwoJCQl9CgoJCQlpZiAoY2hpcDEgPT0gVE1PKSB7CgkJCQlyYyA9IEVSUl9USU1PVVQ7CgkJCQlnb3RvIG91dGFoZXJlOwoJCQl9CgoJCQlwcmludGYoIm9rLlxuIik7CgkJfSBlbHNlIHsgLyogaXQgd2FzIHByb3RlY3RlZCAqLwoKCQkJcHJpbnRmKCJwcm90ZWN0ZWQhXG4iKTsKCQl9Cgl9CgoJaWYgKGN0cmxjKCkpIHsKCQlwcmludGYoIlVzZXIgSW50ZXJydXB0IVxuIik7Cgl9CgpvdXRhaGVyZToKCS8qIGFsbG93IGZsYXNoIHRvIHNldHRsZSAtIHdhaXQgMTAgbXMgKi8KCXVkZWxheSgxMDAwMCk7CgoJaWYgKGlmbGFnKSB7CgkJZW5hYmxlX2ludGVycnVwdHMoKTsKCX0KCglyZXR1cm4gcmM7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogQ29weSBtZW1vcnkgdG8gZmxhc2gKICovCgp2b2xhdGlsZSBzdGF0aWMgaW50IHdyaXRlX3dvcmQoZmxhc2hfaW5mb190ICppbmZvLCB1bG9uZyBkZXN0LCB1bG9uZyBkYXRhKQp7Cgl1bG9uZyBhZGRyID0gZGVzdDsKCXVsb25nIHJlc3VsdDsKCWludCByYyA9IEVSUl9PSzsKCWludCBpZmxhZzsKCWludCBjaGlwMSwgY2hpcDI7CgoJLyoKCSAqIENoZWNrIGlmIEZsYXNoIGlzIChzdWZmaWNpZW50bHkpIGVyYXNlZAoJICovCglyZXN1bHQgPSByZWFkbChhZGRyKTsKCWlmICgocmVzdWx0ICYgZGF0YSkgIT0gZGF0YSkgewoJCXJldHVybiBFUlJfTk9UX0VSQVNFRDsKCX0KCgkvKgoJICogRGlzYWJsZSBpbnRlcnJ1cHRzIHdoaWNoIG1pZ2h0IGNhdXNlIGEgdGltZW91dAoJICogaGVyZS4gUmVtZW1iZXIgdGhhdCBvdXIgZXhjZXB0aW9uIHZlY3RvcnMgYXJlCgkgKiBhdCBhZGRyZXNzIDAgaW4gdGhlIGZsYXNoLCBhbmQgd2UgZG9uJ3Qgd2FudCBhCgkgKiAodGlja2VyKSBleGNlcHRpb24gdG8gaGFwcGVuIHdoaWxlIHRoZSBmbGFzaAoJICogY2hpcCBpcyBpbiBwcm9ncmFtbWluZyBtb2RlLgoJICovCglpZmxhZyA9IGRpc2FibGVfaW50ZXJydXB0cygpOwoKCXdyaXRlbChDTURfVU5MT0NLMSwgYWRkciArIDEpOwoJd3JpdGVsKENNRF9VTkxPQ0syLCBhZGRyICsgMik7Cgl3cml0ZWwoQ01EX1VOTE9DS19CWVBBU1MsIGFkZHIgKyAxKTsKCXdyaXRlbChhZGRyLCBDTURfUFJPR1JBTSk7Cgl3cml0ZWwoYWRkciwgZGF0YSk7CgoJLyogYXJtIHNpbXBsZSwgbm9uIGludGVycnVwdCBkZXBlbmRlbnQgdGltZXIgKi8KCXJlc2V0X3RpbWVyKCk7CgoJLyogd2FpdCB1bnRpbCBmbGFzaCBpcyByZWFkeSAqLwoJY2hpcDEgPSBjaGlwMiA9IDA7CglkbyB7CgkJcmVzdWx0ID0gcmVhZGwoYWRkcik7CgoJCS8qIGNoZWNrIHRpbWVvdXQgKi8KCQlpZiAoZ2V0X3RpbWVyKDApID4gQ09ORklHX1NZU19GTEFTSF9FUkFTRV9UT1VUKSB7CgkJCWNoaXAxID0gRVJSIHwgVE1POwoJCQlicmVhazsKCQl9CgoJCWlmICghY2hpcDEgJiYgKChyZXN1bHQgJiAweDgwKSA9PSAoZGF0YSAmIDB4ODApKSkgewoJCQljaGlwMSA9IFJFQURZOwoJCX0KCgkJaWYgKCFjaGlwMSAmJiAoKHJlc3VsdCAmIDB4RkZGRikgJiBCSVRfUFJPR1JBTV9FUlJPUikpIHsKCQkJcmVzdWx0ID0gcmVhZGwoYWRkcik7CgoJCQlpZiAoKHJlc3VsdCAmIDB4ODApID09IChkYXRhICYgMHg4MCkpIHsKCQkJCWNoaXAxID0gUkVBRFk7CgkJCX0gZWxzZSB7CgkJCQljaGlwMSA9IEVSUjsKCQkJfQoJCX0KCgkJaWYgKCFjaGlwMiAmJiAoKHJlc3VsdCAmICgweDgwIDw8IDE2KSkgPT0gKGRhdGEgJiAoMHg4MCA8PCAxNikpKSkgewoJCQljaGlwMiA9IFJFQURZOwoJCX0KCgkJaWYgKCFjaGlwMiAmJiAoKHJlc3VsdCA+PiAxNikgJiBCSVRfUFJPR1JBTV9FUlJPUikpIHsKCQkJcmVzdWx0ID0gcmVhZGwoYWRkcik7CgoJCQlpZiAoKHJlc3VsdCAmICgweDgwIDw8IDE2KSkgPT0gKGRhdGEgJiAoMHg4MCA8PCAxNikpKSB7CgkJCQljaGlwMiA9IFJFQURZOwoJCQl9IGVsc2UgewoJCQkJY2hpcDIgPSBFUlI7CgkJCX0KCQl9CgoJfSAgd2hpbGUgKCFjaGlwMSB8fCAhY2hpcDIpOwoKCXdyaXRlbChDTURfUkVBRF9BUlJBWSwgYWRkcik7CgoJaWYgKGNoaXAxID09IEVSUiB8fCBjaGlwMiA9PSBFUlIgfHwgcmVhZGwoYWRkcikgIT0gZGF0YSkgewoJCXJjID0gRVJSX1BST0dfRVJST1I7Cgl9CgoJaWYgKGlmbGFnKSB7CgkJZW5hYmxlX2ludGVycnVwdHMoKTsKCX0KCglyZXR1cm4gcmM7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogQ29weSBtZW1vcnkgdG8gZmxhc2guCiAqLwoKaW50IHdyaXRlX2J1ZmYoZmxhc2hfaW5mb190ICppbmZvLCB1Y2hhciAqc3JjLCB1bG9uZyBhZGRyLCB1bG9uZyBjbnQpCnsKCXVsb25nIGNwLCB3cCwgZGF0YTsKCWludCBsOwoJaW50IGksIHJjOwoKCXdwID0gKGFkZHIgJiB+Myk7CS8qIGdldCBsb3dlciB3b3JkIGFsaWduZWQgYWRkcmVzcyAqLwoKCS8qCgkgKiBoYW5kbGUgdW5hbGlnbmVkIHN0YXJ0IGJ5dGVzCgkgKi8KCWlmICgobCA9IGFkZHIgLSB3cCkgIT0gMCkgewoJCWRhdGEgPSAwOwoJCWZvciAoaT0wLCBjcD13cDsgaTxsOyArK2ksICsrY3ApIHsKCQkJZGF0YSA9IChkYXRhID4+IDgpIHwgKCoodWNoYXIgKiljcCA8PCAyNCk7CgkJfQoJCWZvciAoOyBpPDQgJiYgY250PjA7ICsraSkgewoJCQlkYXRhID0gKGRhdGEgPj4gOCkgfCAoKnNyYysrIDw8IDI0KTsKCQkJLS1jbnQ7CgkJCSsrY3A7CgkJfQoJCWZvciAoOyBjbnQ9PTAgJiYgaTw0OyArK2ksICsrY3ApIHsKCQkJZGF0YSA9IChkYXRhID4+IDgpIHwgKCoodWNoYXIgKiljcCA8PCAyNCk7CgkJfQoKCQlpZiAoKHJjID0gd3JpdGVfd29yZChpbmZvLCB3cCwgZGF0YSkpICE9IDApIHsKCQkJcmV0dXJuIHJjOwoJCX0KCQl3cCArPSA0OwoJfQoKCS8qCgkgKiBoYW5kbGUgd29yZCBhbGlnbmVkIHBhcnQKCSAqLwoJd2hpbGUgKGNudCA+PSA0KSB7CgkJZGF0YSA9ICooKHZ1X2xvbmcqKXNyYyk7CgkJaWYgKChyYyA9IHdyaXRlX3dvcmQoaW5mbywgd3AsIGRhdGEpKSAhPSAwKSB7CgkJCXJldHVybiByYzsKCQl9CgkJc3JjICs9IDQ7CgkJd3AgICs9IDQ7CgkJY250IC09IDQ7Cgl9CgoJaWYgKGNudCA9PSAwKSB7CgkJcmV0dXJuIEVSUl9PSzsKCX0KCgkvKgoJICogaGFuZGxlIHVuYWxpZ25lZCB0YWlsIGJ5dGVzCgkgKi8KCWRhdGEgPSAwOwoJZm9yIChpPTAsIGNwPXdwOyBpPDQgJiYgY250PjA7ICsraSwgKytjcCkgewoJCWRhdGEgPSAoZGF0YSA+PiA4KSB8ICgqc3JjKysgPDwgMjQpOwoJCS0tY250OwoJfQoJZm9yICg7IGk8NDsgKytpLCArK2NwKSB7CgkJZGF0YSA9IChkYXRhID4+IDgpIHwgKCoodWNoYXIgKiljcCA8PCAyNCk7Cgl9CgoJcmV0dXJuIHdyaXRlX3dvcmQoaW5mbywgd3AsIGRhdGEpOwp9Cg==