LyoKICogbGludXgvYXJjaC9hcm0vbWFjaC1vbWFwMS9pcnEuYwogKgogKiBJbnRlcnJ1cHQgaGFuZGxlciBmb3IgYWxsIE9NQVAgYm9hcmRzCiAqCiAqIENvcHlyaWdodCAoQykgMjAwNCBOb2tpYSBDb3Jwb3JhdGlvbgogKiBXcml0dGVuIGJ5IFRvbnkgTGluZGdyZW4gPHRvbnlAYXRvbWlkZS5jb20+CiAqIE1ham9yIGNsZWFudXBzIGJ5IEp1aGEgWXJq9mzkIDxqdWhhLnlyam9sYUBub2tpYS5jb20+CiAqCiAqIENvbXBsZXRlbHkgcmUtd3JpdHRlbiB0byBzdXBwb3J0IHZhcmlvdXMgT01BUCBjaGlwcyB3aXRoIGJhbmsgc3BlY2lmaWMKICogaW50ZXJydXB0IGhhbmRsZXJzLgogKgogKiBTb21lIHNuaXBwZXRzIG9mIHRoZSBjb2RlIHRha2VuIGZyb20gdGhlIG9sZGVyIE9NQVAgaW50ZXJydXB0IGhhbmRsZXIKICogQ29weXJpZ2h0IChDKSAyMDAxIFJpZGdlUnVuLCBJbmMuIEdyZWcgTG9ubm9uIDxnbG9ubm9uQHJpZGdlcnVuLmNvbT4KICoKICogR1BJTyBpbnRlcnJ1cHQgaGFuZGxlciBtb3ZlZCB0byBncGlvLmMgYnkgSnVoYSBZcmpvbGEKICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlCiAqIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIKICogb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQKICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YKICogTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4KICogTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULAogKiBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQKICogTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTgogKiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAogKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YKICogVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFsb25nCiAqIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlICB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBJbmMuLAogKiA2NzUgTWFzcyBBdmUsIENhbWJyaWRnZSwgTUEgMDIxMzksIFVTQS4KICovCgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC9zY2hlZC5oPgojaW5jbHVkZSA8bGludXgvaW50ZXJydXB0Lmg+CiNpbmNsdWRlIDxsaW51eC9wdHJhY2UuaD4KCiNpbmNsdWRlIDxhc20vaGFyZHdhcmUuaD4KI2luY2x1ZGUgPGFzbS9pcnEuaD4KI2luY2x1ZGUgPGFzbS9tYWNoL2lycS5oPgojaW5jbHVkZSA8YXNtL2FyY2gvZ3Bpby5oPgojaW5jbHVkZSA8YXNtL2FyY2gvY3B1Lmg+CgojaW5jbHVkZSA8YXNtL2lvLmg+CgojZGVmaW5lIElSUV9CQU5LKGlycSkgKChpcnEpID4+IDUpCiNkZWZpbmUgSVJRX0JJVChpcnEpICAoKGlycSkgJiAweDFmKQoKc3RydWN0IG9tYXBfaXJxX2JhbmsgewoJdW5zaWduZWQgbG9uZyBiYXNlX3JlZzsKCXVuc2lnbmVkIGxvbmcgdHJpZ2dlcl9tYXA7Cgl1bnNpZ25lZCBsb25nIHdha2VfZW5hYmxlOwp9OwoKc3RhdGljIHVuc2lnbmVkIGludCBpcnFfYmFua19jb3VudDsKc3RhdGljIHN0cnVjdCBvbWFwX2lycV9iYW5rICppcnFfYmFua3M7CgpzdGF0aWMgaW5saW5lIHVuc2lnbmVkIGludCBpcnFfYmFua19yZWFkbChpbnQgYmFuaywgaW50IG9mZnNldCkKewoJcmV0dXJuIG9tYXBfcmVhZGwoaXJxX2JhbmtzW2JhbmtdLmJhc2VfcmVnICsgb2Zmc2V0KTsKfQoKc3RhdGljIGlubGluZSB2b2lkIGlycV9iYW5rX3dyaXRlbCh1bnNpZ25lZCBsb25nIHZhbHVlLCBpbnQgYmFuaywgaW50IG9mZnNldCkKewoJb21hcF93cml0ZWwodmFsdWUsIGlycV9iYW5rc1tiYW5rXS5iYXNlX3JlZyArIG9mZnNldCk7Cn0KCnN0YXRpYyB2b2lkIG9tYXBfYWNrX2lycSh1bnNpZ25lZCBpbnQgaXJxKQp7CglpZiAoaXJxID4gMzEpCgkJb21hcF93cml0ZWwoMHgxLCBPTUFQX0lIMl9CQVNFICsgSVJRX0NPTlRST0xfUkVHX09GRlNFVCk7CgoJb21hcF93cml0ZWwoMHgxLCBPTUFQX0lIMV9CQVNFICsgSVJRX0NPTlRST0xfUkVHX09GRlNFVCk7Cn0KCnN0YXRpYyB2b2lkIG9tYXBfbWFza19pcnEodW5zaWduZWQgaW50IGlycSkKewoJaW50IGJhbmsgPSBJUlFfQkFOSyhpcnEpOwoJdTMyIGw7CgoJbCA9IG9tYXBfcmVhZGwoaXJxX2JhbmtzW2JhbmtdLmJhc2VfcmVnICsgSVJRX01JUl9SRUdfT0ZGU0VUKTsKCWwgfD0gMSA8PCBJUlFfQklUKGlycSk7CglvbWFwX3dyaXRlbChsLCBpcnFfYmFua3NbYmFua10uYmFzZV9yZWcgKyBJUlFfTUlSX1JFR19PRkZTRVQpOwp9CgpzdGF0aWMgdm9pZCBvbWFwX3VubWFza19pcnEodW5zaWduZWQgaW50IGlycSkKewoJaW50IGJhbmsgPSBJUlFfQkFOSyhpcnEpOwoJdTMyIGw7CgoJbCA9IG9tYXBfcmVhZGwoaXJxX2JhbmtzW2JhbmtdLmJhc2VfcmVnICsgSVJRX01JUl9SRUdfT0ZGU0VUKTsKCWwgJj0gfigxIDw8IElSUV9CSVQoaXJxKSk7CglvbWFwX3dyaXRlbChsLCBpcnFfYmFua3NbYmFua10uYmFzZV9yZWcgKyBJUlFfTUlSX1JFR19PRkZTRVQpOwp9CgpzdGF0aWMgdm9pZCBvbWFwX21hc2tfYWNrX2lycSh1bnNpZ25lZCBpbnQgaXJxKQp7CglvbWFwX21hc2tfaXJxKGlycSk7CglvbWFwX2Fja19pcnEoaXJxKTsKfQoKc3RhdGljIGludCBvbWFwX3dha2VfaXJxKHVuc2lnbmVkIGludCBpcnEsIHVuc2lnbmVkIGludCBlbmFibGUpCnsKCWludCBiYW5rID0gSVJRX0JBTksoaXJxKTsKCglpZiAoZW5hYmxlKQoJCWlycV9iYW5rc1tiYW5rXS53YWtlX2VuYWJsZSB8PSBJUlFfQklUKGlycSk7CgllbHNlCgkJaXJxX2JhbmtzW2JhbmtdLndha2VfZW5hYmxlICY9IH5JUlFfQklUKGlycSk7CgoJcmV0dXJuIDA7Cn0KCgovKgogKiBBbGxvd3MgdHVuaW5nIHRoZSBJUlEgdHlwZSBhbmQgcHJpb3JpdHkKICoKICogTk9URTogVGhlcmUgaXMgY3VycmVudGx5IG5vIE9NQVAgZmlxIGhhbmRsZXIgZm9yIExpbnV4LiBSZWFkIHRoZQogKgkgbWFpbGluZyBsaXN0IHRocmVhZHMgb24gRklRIGhhbmRsZXJzIGlmIHlvdSBhcmUgcGxhbm5pbmcgdG8KICoJIGFkZCBhIEZJUSBoYW5kbGVyIGZvciBPTUFQLgogKi8Kc3RhdGljIHZvaWQgb21hcF9pcnFfc2V0X2NmZyhpbnQgaXJxLCBpbnQgZmlxLCBpbnQgcHJpb3JpdHksIGludCB0cmlnZ2VyKQp7CglzaWduZWQgaW50IGJhbms7Cgl1bnNpZ25lZCBsb25nIHZhbCwgb2Zmc2V0OwoKCWJhbmsgPSBJUlFfQkFOSyhpcnEpOwoJLyogRklRIGlzIG9ubHkgYXZhaWxhYmxlIG9uIGJhbmsgMCBpbnRlcnJ1cHRzICovCglmaXEgPSBiYW5rID8gMCA6IChmaXEgJiAweDEpOwoJdmFsID0gZmlxIHwgKChwcmlvcml0eSAmIDB4MWYpIDw8IDIpIHwgKCh0cmlnZ2VyICYgMHgxKSA8PCAxKTsKCW9mZnNldCA9IElSUV9JTFIwX1JFR19PRkZTRVQgKyBJUlFfQklUKGlycSkgKiAweDQ7CglpcnFfYmFua193cml0ZWwodmFsLCBiYW5rLCBvZmZzZXQpOwp9CgojaWZkZWYgQ09ORklHX0FSQ0hfT01BUDczMApzdGF0aWMgc3RydWN0IG9tYXBfaXJxX2Jhbmsgb21hcDczMF9pcnFfYmFua3NbXSA9IHsKCXsgLmJhc2VfcmVnID0gT01BUF9JSDFfQkFTRSwJCS50cmlnZ2VyX21hcCA9IDB4YjNmOGUyMmYgfSwKCXsgLmJhc2VfcmVnID0gT01BUF9JSDJfQkFTRSwJCS50cmlnZ2VyX21hcCA9IDB4ZmRiOWMxZjIgfSwKCXsgLmJhc2VfcmVnID0gT01BUF9JSDJfQkFTRSArIDB4MTAwLAkudHJpZ2dlcl9tYXAgPSAweDgwMDA0MGYzIH0sCn07CiNlbmRpZgoKI2lmZGVmIENPTkZJR19BUkNIX09NQVAxNVhYCnN0YXRpYyBzdHJ1Y3Qgb21hcF9pcnFfYmFuayBvbWFwMTUxMF9pcnFfYmFua3NbXSA9IHsKCXsgLmJhc2VfcmVnID0gT01BUF9JSDFfQkFTRSwJCS50cmlnZ2VyX21hcCA9IDB4YjNmZWJmZmYgfSwKCXsgLmJhc2VfcmVnID0gT01BUF9JSDJfQkFTRSwJCS50cmlnZ2VyX21hcCA9IDB4ZmZiZmZmZWQgfSwKfTsKc3RhdGljIHN0cnVjdCBvbWFwX2lycV9iYW5rIG9tYXAzMTBfaXJxX2JhbmtzW10gPSB7Cgl7IC5iYXNlX3JlZyA9IE9NQVBfSUgxX0JBU0UsCQkudHJpZ2dlcl9tYXAgPSAweGIzZmFlZmMzIH0sCgl7IC5iYXNlX3JlZyA9IE9NQVBfSUgyX0JBU0UsCQkudHJpZ2dlcl9tYXAgPSAweDY1YjNjMDYxIH0sCn07CiNlbmRpZgoKI2lmIGRlZmluZWQoQ09ORklHX0FSQ0hfT01BUDE2WFgpCgpzdGF0aWMgc3RydWN0IG9tYXBfaXJxX2Jhbmsgb21hcDE2MTBfaXJxX2JhbmtzW10gPSB7Cgl7IC5iYXNlX3JlZyA9IE9NQVBfSUgxX0JBU0UsCQkudHJpZ2dlcl9tYXAgPSAweGIzZmVmZThmIH0sCgl7IC5iYXNlX3JlZyA9IE9NQVBfSUgyX0JBU0UsCQkudHJpZ2dlcl9tYXAgPSAweGZkYjdjMWZkIH0sCgl7IC5iYXNlX3JlZyA9IE9NQVBfSUgyX0JBU0UgKyAweDEwMCwJLnRyaWdnZXJfbWFwID0gMHhmZmZmYjdmZiB9LAoJeyAuYmFzZV9yZWcgPSBPTUFQX0lIMl9CQVNFICsgMHgyMDAsCS50cmlnZ2VyX21hcCA9IDB4ZmZmZmZmZmYgfSwKfTsKI2VuZGlmCgpzdGF0aWMgc3RydWN0IGlycV9jaGlwIG9tYXBfaXJxX2NoaXAgPSB7CgkubmFtZQkJPSAiTVBVIiwKCS5hY2sJCT0gb21hcF9tYXNrX2Fja19pcnEsCgkubWFzawkJPSBvbWFwX21hc2tfaXJxLAoJLnVubWFzawkJPSBvbWFwX3VubWFza19pcnEsCgkuc2V0X3dha2UJPSBvbWFwX3dha2VfaXJxLAp9OwoKdm9pZCBfX2luaXQgb21hcF9pbml0X2lycSh2b2lkKQp7CglpbnQgaSwgajsKCiNpZmRlZiBDT05GSUdfQVJDSF9PTUFQNzMwCglpZiAoY3B1X2lzX29tYXA3MzAoKSkgewoJCWlycV9iYW5rcyA9IG9tYXA3MzBfaXJxX2JhbmtzOwoJCWlycV9iYW5rX2NvdW50ID0gQVJSQVlfU0laRShvbWFwNzMwX2lycV9iYW5rcyk7Cgl9CiNlbmRpZgojaWZkZWYgQ09ORklHX0FSQ0hfT01BUDE1WFgKCWlmIChjcHVfaXNfb21hcDE1MTAoKSkgewoJCWlycV9iYW5rcyA9IG9tYXAxNTEwX2lycV9iYW5rczsKCQlpcnFfYmFua19jb3VudCA9IEFSUkFZX1NJWkUob21hcDE1MTBfaXJxX2JhbmtzKTsKCX0KCWlmIChjcHVfaXNfb21hcDMxMCgpKSB7CgkJaXJxX2JhbmtzID0gb21hcDMxMF9pcnFfYmFua3M7CgkJaXJxX2JhbmtfY291bnQgPSBBUlJBWV9TSVpFKG9tYXAzMTBfaXJxX2JhbmtzKTsKCX0KI2VuZGlmCiNpZiBkZWZpbmVkKENPTkZJR19BUkNIX09NQVAxNlhYKQoJaWYgKGNwdV9pc19vbWFwMTZ4eCgpKSB7CgkJaXJxX2JhbmtzID0gb21hcDE2MTBfaXJxX2JhbmtzOwoJCWlycV9iYW5rX2NvdW50ID0gQVJSQVlfU0laRShvbWFwMTYxMF9pcnFfYmFua3MpOwoJfQojZW5kaWYKCXByaW50aygiVG90YWwgb2YgJWkgaW50ZXJydXB0cyBpbiAlaSBpbnRlcnJ1cHQgYmFua3NcbiIsCgkgICAgICAgaXJxX2JhbmtfY291bnQgKiAzMiwgaXJxX2JhbmtfY291bnQpOwoKCS8qIE1hc2sgYW5kIGNsZWFyIGFsbCBpbnRlcnJ1cHRzICovCglmb3IgKGkgPSAwOyBpIDwgaXJxX2JhbmtfY291bnQ7IGkrKykgewoJCWlycV9iYW5rX3dyaXRlbCh+MHgwLCBpLCBJUlFfTUlSX1JFR19PRkZTRVQpOwoJCWlycV9iYW5rX3dyaXRlbCgweDAsIGksIElSUV9JVFJfUkVHX09GRlNFVCk7Cgl9CgoJLyogQ2xlYXIgYW55IHBlbmRpbmcgaW50ZXJydXB0cyAqLwoJaXJxX2Jhbmtfd3JpdGVsKDB4MDMsIDAsIElSUV9DT05UUk9MX1JFR19PRkZTRVQpOwoJaXJxX2Jhbmtfd3JpdGVsKDB4MDMsIDEsIElSUV9DT05UUk9MX1JFR19PRkZTRVQpOwoKCS8qIEVuYWJsZSBpbnRlcnJ1cHRzIGluIGdsb2JhbCBtYXNrICovCglpZiAoY3B1X2lzX29tYXA3MzAoKSkgewoJCWlycV9iYW5rX3dyaXRlbCgweDAsIDAsIElSUV9HTVJfUkVHX09GRlNFVCk7Cgl9CgoJLyogSW5zdGFsbCB0aGUgaW50ZXJydXB0IGhhbmRsZXJzIGZvciBlYWNoIGJhbmsgKi8KCWZvciAoaSA9IDA7IGkgPCBpcnFfYmFua19jb3VudDsgaSsrKSB7CgkJZm9yIChqID0gaSAqIDMyOyBqIDwgKGkgKyAxKSAqIDMyOyBqKyspIHsKCQkJaW50IGlycV90cmlnZ2VyOwoKCQkJaXJxX3RyaWdnZXIgPSBpcnFfYmFua3NbaV0udHJpZ2dlcl9tYXAgPj4gSVJRX0JJVChqKTsKCQkJb21hcF9pcnFfc2V0X2NmZyhqLCAwLCAwLCBpcnFfdHJpZ2dlcik7CgoJCQlzZXRfaXJxX2NoaXAoaiwgJm9tYXBfaXJxX2NoaXApOwoJCQlzZXRfaXJxX2hhbmRsZXIoaiwgaGFuZGxlX2xldmVsX2lycSk7CgkJCXNldF9pcnFfZmxhZ3MoaiwgSVJRRl9WQUxJRCk7CgkJfQoJfQoKCS8qIFVubWFzayBsZXZlbCAyIGhhbmRsZXIgKi8KCglpZiAoY3B1X2lzX29tYXA3MzAoKSkKCQlvbWFwX3VubWFza19pcnEoSU5UXzczMF9JSDJfSVJRKTsKCWVsc2UgaWYgKGNwdV9pc19vbWFwMTUxMCgpKQoJCW9tYXBfdW5tYXNrX2lycShJTlRfMTUxMF9JSDJfSVJRKTsKCWVsc2UgaWYgKGNwdV9pc19vbWFwMTZ4eCgpKQoJCW9tYXBfdW5tYXNrX2lycShJTlRfMTYxMF9JSDJfSVJRKTsKfQo=