LyoKICogbGludXgvYXJjaC9hcm0vbWFjaC1vbWFwMS9pcnEuYwogKgogKiBJbnRlcnJ1cHQgaGFuZGxlciBmb3IgYWxsIE9NQVAgYm9hcmRzCiAqCiAqIENvcHlyaWdodCAoQykgMjAwNCBOb2tpYSBDb3Jwb3JhdGlvbgogKiBXcml0dGVuIGJ5IFRvbnkgTGluZGdyZW4gPHRvbnlAYXRvbWlkZS5jb20+CiAqIE1ham9yIGNsZWFudXBzIGJ5IEp1aGEgWXJq9mzkIDxqdWhhLnlyam9sYUBub2tpYS5jb20+CiAqCiAqIENvbXBsZXRlbHkgcmUtd3JpdHRlbiB0byBzdXBwb3J0IHZhcmlvdXMgT01BUCBjaGlwcyB3aXRoIGJhbmsgc3BlY2lmaWMKICogaW50ZXJydXB0IGhhbmRsZXJzLgogKgogKiBTb21lIHNuaXBwZXRzIG9mIHRoZSBjb2RlIHRha2VuIGZyb20gdGhlIG9sZGVyIE9NQVAgaW50ZXJydXB0IGhhbmRsZXIKICogQ29weXJpZ2h0IChDKSAyMDAxIFJpZGdlUnVuLCBJbmMuIEdyZWcgTG9ubm9uIDxnbG9ubm9uQHJpZGdlcnVuLmNvbT4KICoKICogR1BJTyBpbnRlcnJ1cHQgaGFuZGxlciBtb3ZlZCB0byBncGlvLmMgYnkgSnVoYSBZcmpvbGEKICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlCiAqIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIKICogb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBgYEFTIElTJycgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQKICogV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YKICogTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4KICogTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULAogKiBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQKICogTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YKICogVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTgogKiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAogKiAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YKICogVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFsb25nCiAqIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlICB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBJbmMuLAogKiA2NzUgTWFzcyBBdmUsIENhbWJyaWRnZSwgTUEgMDIxMzksIFVTQS4KICovCgojaW5jbHVkZSA8bGludXgvY29uZmlnLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L3NjaGVkLmg+CiNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KI2luY2x1ZGUgPGxpbnV4L3B0cmFjZS5oPgoKI2luY2x1ZGUgPGFzbS9oYXJkd2FyZS5oPgojaW5jbHVkZSA8YXNtL2lycS5oPgojaW5jbHVkZSA8YXNtL21hY2gvaXJxLmg+CiNpbmNsdWRlIDxhc20vYXJjaC9ncGlvLmg+CgojaW5jbHVkZSA8YXNtL2lvLmg+CgojZGVmaW5lIElSUV9CQU5LKGlycSkgKChpcnEpID4+IDUpCiNkZWZpbmUgSVJRX0JJVChpcnEpICAoKGlycSkgJiAweDFmKQoKc3RydWN0IG9tYXBfaXJxX2JhbmsgewoJdW5zaWduZWQgbG9uZyBiYXNlX3JlZzsKCXVuc2lnbmVkIGxvbmcgdHJpZ2dlcl9tYXA7Cgl1bnNpZ25lZCBsb25nIHdha2VfZW5hYmxlOwp9OwoKc3RhdGljIHVuc2lnbmVkIGludCBpcnFfYmFua19jb3VudCA9IDA7CnN0YXRpYyBzdHJ1Y3Qgb21hcF9pcnFfYmFuayAqaXJxX2JhbmtzOwoKc3RhdGljIGlubGluZSB1bnNpZ25lZCBpbnQgaXJxX2JhbmtfcmVhZGwoaW50IGJhbmssIGludCBvZmZzZXQpCnsKCXJldHVybiBvbWFwX3JlYWRsKGlycV9iYW5rc1tiYW5rXS5iYXNlX3JlZyArIG9mZnNldCk7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBpcnFfYmFua193cml0ZWwodW5zaWduZWQgbG9uZyB2YWx1ZSwgaW50IGJhbmssIGludCBvZmZzZXQpCnsKCW9tYXBfd3JpdGVsKHZhbHVlLCBpcnFfYmFua3NbYmFua10uYmFzZV9yZWcgKyBvZmZzZXQpOwp9CgpzdGF0aWMgdm9pZCBvbWFwX2Fja19pcnEodW5zaWduZWQgaW50IGlycSkKewoJaWYgKGlycSA+IDMxKQoJCW9tYXBfd3JpdGVsKDB4MSwgT01BUF9JSDJfQkFTRSArIElSUV9DT05UUk9MX1JFR19PRkZTRVQpOwoKCW9tYXBfd3JpdGVsKDB4MSwgT01BUF9JSDFfQkFTRSArIElSUV9DT05UUk9MX1JFR19PRkZTRVQpOwp9CgpzdGF0aWMgdm9pZCBvbWFwX21hc2tfaXJxKHVuc2lnbmVkIGludCBpcnEpCnsKCWludCBiYW5rID0gSVJRX0JBTksoaXJxKTsKCXUzMiBsOwoKCWwgPSBvbWFwX3JlYWRsKGlycV9iYW5rc1tiYW5rXS5iYXNlX3JlZyArIElSUV9NSVJfUkVHX09GRlNFVCk7CglsIHw9IDEgPDwgSVJRX0JJVChpcnEpOwoJb21hcF93cml0ZWwobCwgaXJxX2JhbmtzW2JhbmtdLmJhc2VfcmVnICsgSVJRX01JUl9SRUdfT0ZGU0VUKTsKfQoKc3RhdGljIHZvaWQgb21hcF91bm1hc2tfaXJxKHVuc2lnbmVkIGludCBpcnEpCnsKCWludCBiYW5rID0gSVJRX0JBTksoaXJxKTsKCXUzMiBsOwoKCWwgPSBvbWFwX3JlYWRsKGlycV9iYW5rc1tiYW5rXS5iYXNlX3JlZyArIElSUV9NSVJfUkVHX09GRlNFVCk7CglsICY9IH4oMSA8PCBJUlFfQklUKGlycSkpOwoJb21hcF93cml0ZWwobCwgaXJxX2JhbmtzW2JhbmtdLmJhc2VfcmVnICsgSVJRX01JUl9SRUdfT0ZGU0VUKTsKfQoKc3RhdGljIHZvaWQgb21hcF9tYXNrX2Fja19pcnEodW5zaWduZWQgaW50IGlycSkKewoJb21hcF9tYXNrX2lycShpcnEpOwoJb21hcF9hY2tfaXJxKGlycSk7Cn0KCnN0YXRpYyBpbnQgb21hcF93YWtlX2lycSh1bnNpZ25lZCBpbnQgaXJxLCB1bnNpZ25lZCBpbnQgZW5hYmxlKQp7CglpbnQgYmFuayA9IElSUV9CQU5LKGlycSk7CgoJaWYgKGVuYWJsZSkKCQlpcnFfYmFua3NbYmFua10ud2FrZV9lbmFibGUgfD0gSVJRX0JJVChpcnEpOwoJZWxzZQoJCWlycV9iYW5rc1tiYW5rXS53YWtlX2VuYWJsZSAmPSB+SVJRX0JJVChpcnEpOwoKCXJldHVybiAwOwp9CgoKLyoKICogQWxsb3dzIHR1bmluZyB0aGUgSVJRIHR5cGUgYW5kIHByaW9yaXR5CiAqCiAqIE5PVEU6IFRoZXJlIGlzIGN1cnJlbnRseSBubyBPTUFQIGZpcSBoYW5kbGVyIGZvciBMaW51eC4gUmVhZCB0aGUKICoJIG1haWxpbmcgbGlzdCB0aHJlYWRzIG9uIEZJUSBoYW5kbGVycyBpZiB5b3UgYXJlIHBsYW5uaW5nIHRvCiAqCSBhZGQgYSBGSVEgaGFuZGxlciBmb3IgT01BUC4KICovCnN0YXRpYyB2b2lkIG9tYXBfaXJxX3NldF9jZmcoaW50IGlycSwgaW50IGZpcSwgaW50IHByaW9yaXR5LCBpbnQgdHJpZ2dlcikKewoJc2lnbmVkIGludCBiYW5rOwoJdW5zaWduZWQgbG9uZyB2YWwsIG9mZnNldDsKCgliYW5rID0gSVJRX0JBTksoaXJxKTsKCS8qIEZJUSBpcyBvbmx5IGF2YWlsYWJsZSBvbiBiYW5rIDAgaW50ZXJydXB0cyAqLwoJZmlxID0gYmFuayA/IDAgOiAoZmlxICYgMHgxKTsKCXZhbCA9IGZpcSB8ICgocHJpb3JpdHkgJiAweDFmKSA8PCAyKSB8ICgodHJpZ2dlciAmIDB4MSkgPDwgMSk7CglvZmZzZXQgPSBJUlFfSUxSMF9SRUdfT0ZGU0VUICsgSVJRX0JJVChpcnEpICogMHg0OwoJaXJxX2Jhbmtfd3JpdGVsKHZhbCwgYmFuaywgb2Zmc2V0KTsKfQoKI2lmZGVmIENPTkZJR19BUkNIX09NQVA3MzAKc3RhdGljIHN0cnVjdCBvbWFwX2lycV9iYW5rIG9tYXA3MzBfaXJxX2JhbmtzW10gPSB7Cgl7IC5iYXNlX3JlZyA9IE9NQVBfSUgxX0JBU0UsIAkJLnRyaWdnZXJfbWFwID0gMHhiM2Y4ZTIyZiB9LAoJeyAuYmFzZV9yZWcgPSBPTUFQX0lIMl9CQVNFLCAJCS50cmlnZ2VyX21hcCA9IDB4ZmRiOWMxZjIgfSwKCXsgLmJhc2VfcmVnID0gT01BUF9JSDJfQkFTRSArIDB4MTAwLAkudHJpZ2dlcl9tYXAgPSAweDgwMDA0MGYzIH0sCn07CiNlbmRpZgoKI2lmZGVmIENPTkZJR19BUkNIX09NQVAxNTEwCnN0YXRpYyBzdHJ1Y3Qgb21hcF9pcnFfYmFuayBvbWFwMTUxMF9pcnFfYmFua3NbXSA9IHsKCXsgLmJhc2VfcmVnID0gT01BUF9JSDFfQkFTRSwgCQkudHJpZ2dlcl9tYXAgPSAweGIzZmViZmZmIH0sCgl7IC5iYXNlX3JlZyA9IE9NQVBfSUgyX0JBU0UsIAkJLnRyaWdnZXJfbWFwID0gMHhmZmJmZmZlZCB9LAp9OwojZW5kaWYKCiNpZiBkZWZpbmVkKENPTkZJR19BUkNIX09NQVAxNlhYKQoKc3RhdGljIHN0cnVjdCBvbWFwX2lycV9iYW5rIG9tYXAxNjEwX2lycV9iYW5rc1tdID0gewoJeyAuYmFzZV9yZWcgPSBPTUFQX0lIMV9CQVNFLCAJCS50cmlnZ2VyX21hcCA9IDB4YjNmZWZlOGYgfSwKCXsgLmJhc2VfcmVnID0gT01BUF9JSDJfQkFTRSwgCQkudHJpZ2dlcl9tYXAgPSAweGZkYjdjMWZkIH0sCgl7IC5iYXNlX3JlZyA9IE9NQVBfSUgyX0JBU0UgKyAweDEwMCwJLnRyaWdnZXJfbWFwID0gMHhmZmZmYjdmZiB9LAoJeyAuYmFzZV9yZWcgPSBPTUFQX0lIMl9CQVNFICsgMHgyMDAsCS50cmlnZ2VyX21hcCA9IDB4ZmZmZmZmZmYgfSwKfTsKI2VuZGlmCgpzdGF0aWMgc3RydWN0IGlycWNoaXAgb21hcF9pcnFfY2hpcCA9IHsKCS5hY2sJCT0gb21hcF9tYXNrX2Fja19pcnEsCgkubWFzawkJPSBvbWFwX21hc2tfaXJxLAoJLnVubWFzawkJPSBvbWFwX3VubWFza19pcnEsCgkuc2V0X3dha2UJPSBvbWFwX3dha2VfaXJxLAp9OwoKdm9pZCBfX2luaXQgb21hcF9pbml0X2lycSh2b2lkKQp7CglpbnQgaSwgajsKCiNpZmRlZiBDT05GSUdfQVJDSF9PTUFQNzMwCglpZiAoY3B1X2lzX29tYXA3MzAoKSkgewoJCWlycV9iYW5rcyA9IG9tYXA3MzBfaXJxX2JhbmtzOwoJCWlycV9iYW5rX2NvdW50ID0gQVJSQVlfU0laRShvbWFwNzMwX2lycV9iYW5rcyk7Cgl9CiNlbmRpZgojaWZkZWYgQ09ORklHX0FSQ0hfT01BUDE1MTAKCWlmIChjcHVfaXNfb21hcDE1MTAoKSkgewoJCWlycV9iYW5rcyA9IG9tYXAxNTEwX2lycV9iYW5rczsKCQlpcnFfYmFua19jb3VudCA9IEFSUkFZX1NJWkUob21hcDE1MTBfaXJxX2JhbmtzKTsKCX0KI2VuZGlmCiNpZiBkZWZpbmVkKENPTkZJR19BUkNIX09NQVAxNlhYKQoJaWYgKGNwdV9pc19vbWFwMTZ4eCgpKSB7CgkJaXJxX2JhbmtzID0gb21hcDE2MTBfaXJxX2JhbmtzOwoJCWlycV9iYW5rX2NvdW50ID0gQVJSQVlfU0laRShvbWFwMTYxMF9pcnFfYmFua3MpOwoJfQojZW5kaWYKCXByaW50aygiVG90YWwgb2YgJWkgaW50ZXJydXB0cyBpbiAlaSBpbnRlcnJ1cHQgYmFua3NcbiIsCgkgICAgICAgaXJxX2JhbmtfY291bnQgKiAzMiwgaXJxX2JhbmtfY291bnQpOwoKCS8qIE1hc2sgYW5kIGNsZWFyIGFsbCBpbnRlcnJ1cHRzICovCglmb3IgKGkgPSAwOyBpIDwgaXJxX2JhbmtfY291bnQ7IGkrKykgewoJCWlycV9iYW5rX3dyaXRlbCh+MHgwLCBpLCBJUlFfTUlSX1JFR19PRkZTRVQpOwoJCWlycV9iYW5rX3dyaXRlbCgweDAsIGksIElSUV9JVFJfUkVHX09GRlNFVCk7Cgl9CgoJLyogQ2xlYXIgYW55IHBlbmRpbmcgaW50ZXJydXB0cyAqLwoJaXJxX2Jhbmtfd3JpdGVsKDB4MDMsIDAsIElSUV9DT05UUk9MX1JFR19PRkZTRVQpOwoJaXJxX2Jhbmtfd3JpdGVsKDB4MDMsIDEsIElSUV9DT05UUk9MX1JFR19PRkZTRVQpOwoKCS8qIEVuYWJsZSBpbnRlcnJ1cHRzIGluIGdsb2JhbCBtYXNrICovCglpZiAoY3B1X2lzX29tYXA3MzAoKSkgewoJCWlycV9iYW5rX3dyaXRlbCgweDAsIDAsIElSUV9HTVJfUkVHX09GRlNFVCk7Cgl9CgoJLyogSW5zdGFsbCB0aGUgaW50ZXJydXB0IGhhbmRsZXJzIGZvciBlYWNoIGJhbmsgKi8KCWZvciAoaSA9IDA7IGkgPCBpcnFfYmFua19jb3VudDsgaSsrKSB7CgkJZm9yIChqID0gaSAqIDMyOyBqIDwgKGkgKyAxKSAqIDMyOyBqKyspIHsKCQkJaW50IGlycV90cmlnZ2VyOwoKCQkJaXJxX3RyaWdnZXIgPSBpcnFfYmFua3NbaV0udHJpZ2dlcl9tYXAgPj4gSVJRX0JJVChqKTsKCQkJb21hcF9pcnFfc2V0X2NmZyhqLCAwLCAwLCBpcnFfdHJpZ2dlcik7CgoJCQlzZXRfaXJxX2NoaXAoaiwgJm9tYXBfaXJxX2NoaXApOwoJCQlzZXRfaXJxX2hhbmRsZXIoaiwgZG9fbGV2ZWxfSVJRKTsKCQkJc2V0X2lycV9mbGFncyhqLCBJUlFGX1ZBTElEKTsKCQl9Cgl9CgoJLyogVW5tYXNrIGxldmVsIDIgaGFuZGxlciAqLwoJaWYgKGNwdV9pc19vbWFwNzMwKCkpIHsKCQlvbWFwX3VubWFza19pcnEoSU5UXzczMF9JSDJfSVJRKTsKCX0gZWxzZSB7CgkJb21hcF91bm1hc2tfaXJxKElOVF9JSDJfSVJRKTsKCX0KfQo=