LyoKICogQWdlcmUgU3lzdGVtcyBJbmMuCiAqIDEwLzEwMC8xMDAwIEJhc2UtVCBFdGhlcm5ldCBEcml2ZXIgZm9yIHRoZSBFVDEzMDEgYW5kIEVUMTMxeCBzZXJpZXMgTUFDcwogKgogKiBDb3B5cmlnaHQgqSAyMDA1IEFnZXJlIFN5c3RlbXMgSW5jLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiAgIGh0dHA6Ly93d3cuYWdlcmUuY29tCiAqCiAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqCiAqIGV0MTMxMF9qYWdjb3JlLmMgLSBBbGwgY29kZSBwZXJ0YWluaW5nIHRvIHRoZSBFVDEzMDEvRVQxMzF4J3MgSkFHY29yZQogKgogKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKgogKiBTT0ZUV0FSRSBMSUNFTlNFCiAqCiAqIFRoaXMgc29mdHdhcmUgaXMgcHJvdmlkZWQgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHRlcm1zIGFuZCBjb25kaXRpb25zLAogKiB3aGljaCB5b3Ugc2hvdWxkIHJlYWQgY2FyZWZ1bGx5IGJlZm9yZSB1c2luZyB0aGUgc29mdHdhcmUuICBVc2luZyB0aGlzCiAqIHNvZnR3YXJlIGluZGljYXRlcyB5b3VyIGFjY2VwdGFuY2Ugb2YgdGhlc2UgdGVybXMgYW5kIGNvbmRpdGlvbnMuICBJZiB5b3UgZG8KICogbm90IGFncmVlIHdpdGggdGhlc2UgdGVybXMgYW5kIGNvbmRpdGlvbnMsIGRvIG5vdCB1c2UgdGhlIHNvZnR3YXJlLgogKgogKiBDb3B5cmlnaHQgqSAyMDA1IEFnZXJlIFN5c3RlbXMgSW5jLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBvciBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAogKiBtb2RpZmljYXRpb25zLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6CiAqCiAqIC4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLCB0aGlzCiAqICAgIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBEaXNjbGFpbWVyIGFzIGNvbW1lbnRzIGluIHRoZSBjb2RlIGFzCiAqICAgIHdlbGwgYXMgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQogKiAgICBkaXN0cmlidXRpb24uCiAqCiAqIC4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLAogKiAgICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBEaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uCiAqICAgIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKgogKiAuIE5laXRoZXIgdGhlIG5hbWUgb2YgQWdlcmUgU3lzdGVtcyBJbmMuIG5vciB0aGUgbmFtZXMgb2YgdGhlIGNvbnRyaWJ1dG9ycwogKiAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUKICogICAgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCiAqCiAqIERpc2NsYWltZXIKICoKICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCCTQVMgSVOUIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsCiAqIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBJTkZSSU5HRU1FTlQgQU5EIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YKICogTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gIEFOWQogKiBVU0UsIE1PRElGSUNBVElPTiBPUiBESVNUUklCVVRJT04gT0YgVEhJUyBTT0ZUV0FSRSBJUyBTT0xFTFkgQVQgVEhFIFVTRVJTIE9XTgogKiBSSVNLLiBJTiBOTyBFVkVOVCBTSEFMTCBBR0VSRSBTWVNURU1TIElOQy4gT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZCiAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTCiAqIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsKICogTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5ECiAqIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgQ09OVFJBQ1QsIFNUUklDVAogKiBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVAogKiBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSAogKiBEQU1BR0UuCiAqCiAqLwoKI2luY2x1ZGUgImV0MTMxeF92ZXJzaW9uLmgiCiNpbmNsdWRlICJldDEzMXhfZGVidWcuaCIKI2luY2x1ZGUgImV0MTMxeF9kZWZzLmgiCgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC90eXBlcy5oPgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CgojaW5jbHVkZSA8bGludXgvc2NoZWQuaD4KI2luY2x1ZGUgPGxpbnV4L3B0cmFjZS5oPgojaW5jbHVkZSA8bGludXgvc2xhYi5oPgojaW5jbHVkZSA8bGludXgvY3R5cGUuaD4KI2luY2x1ZGUgPGxpbnV4L3N0cmluZy5oPgojaW5jbHVkZSA8bGludXgvdGltZXIuaD4KI2luY2x1ZGUgPGxpbnV4L2ludGVycnVwdC5oPgojaW5jbHVkZSA8bGludXgvaW4uaD4KI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+CiNpbmNsdWRlIDxhc20vaW8uaD4KI2luY2x1ZGUgPGFzbS9zeXN0ZW0uaD4KI2luY2x1ZGUgPGFzbS9iaXRvcHMuaD4KCiNpbmNsdWRlIDxsaW51eC9uZXRkZXZpY2UuaD4KI2luY2x1ZGUgPGxpbnV4L2V0aGVyZGV2aWNlLmg+CiNpbmNsdWRlIDxsaW51eC9za2J1ZmYuaD4KI2luY2x1ZGUgPGxpbnV4L2lmX2FycC5oPgojaW5jbHVkZSA8bGludXgvaW9wb3J0Lmg+CgojaW5jbHVkZSAiZXQxMzEwX3BoeS5oIgojaW5jbHVkZSAiZXQxMzEwX3BtLmgiCiNpbmNsdWRlICJldDEzMTBfamFnY29yZS5oIgoKI2luY2x1ZGUgImV0MTMxeF9hZGFwdGVyLmgiCiNpbmNsdWRlICJldDEzMXhfaW5pdHBjaS5oIgoKLyogRGF0YSBmb3IgZGVidWdnaW5nIGZhY2lsaXRpZXMgKi8KI2lmZGVmIENPTkZJR19FVDEzMVhfREVCVUcKZXh0ZXJuIGRiZ19pbmZvX3QgKmV0MTMxeF9kYmdpbmZvOwojZW5kaWYgLyogQ09ORklHX0VUMTMxWF9ERUJVRyAqLwoKLyoqCiAqIENvbmZpZ0dsb2JhbFJlZ3MgLSBVc2VkIHRvIGNvbmZpZ3VyZSB0aGUgZ2xvYmFsIHJlZ2lzdGVycyBvbiB0aGUgSkFHQ29yZQogKiBAcEFkcGF0ZXI6IHBvaW50ZXIgdG8gb3VyIGFkYXB0ZXIgc3RydWN0dXJlCiAqLwp2b2lkIENvbmZpZ0dsb2JhbFJlZ3Moc3RydWN0IGV0MTMxeF9hZGFwdGVyICpwQWRhcHRlcikKewoJc3RydWN0IF9HTE9CQUxfdCBfX2lvbWVtICpwR2JsID0gJnBBZGFwdGVyLT5DU1JBZGRyZXNzLT5nbG9iYWw7CgoJREJHX0VOVEVSKGV0MTMxeF9kYmdpbmZvKTsKCglpZiAocEFkYXB0ZXItPlJlZ2lzdHJ5UGh5TG9vcGJrID09IGZhbHNlKSB7CgkJaWYgKHBBZGFwdGVyLT5SZWdpc3RyeUp1bWJvUGFja2V0IDwgMjA0OCkgewoJCQkvKiBUeCAvIFJ4RE1BIGFuZCBUeC9SeCBNQUMgaW50ZXJmYWNlcyBoYXZlIGEgMWsgd29yZAoJCQkgKiBibG9jayBvZiBSQU0gdGhhdCB0aGUgZHJpdmVyIGNhbiBzcGxpdCBiZXR3ZWVuIFR4CgkJCSAqIGFuZCBSeCBhcyBpdCBkZXNpcmVzLiAgT3VyIGRlZmF1bHQgaXMgdG8gc3BsaXQgaXQKCQkJICogNTAvNTA6CgkJCSAqLwoJCQl3cml0ZWwoMCwgJnBHYmwtPnJ4cV9zdGFydF9hZGRyLnZhbHVlKTsKCQkJd3JpdGVsKHBBZGFwdGVyLT5SZWdpc3RyeVJ4TWVtRW5kLAoJCQkgICAgICAgJnBHYmwtPnJ4cV9lbmRfYWRkci52YWx1ZSk7CgkJCXdyaXRlbChwQWRhcHRlci0+UmVnaXN0cnlSeE1lbUVuZCArIDEsCgkJCSAgICAgICAmcEdibC0+dHhxX3N0YXJ0X2FkZHIudmFsdWUpOwoJCQl3cml0ZWwoSU5URVJOQUxfTUVNX1NJWkUgLSAxLAoJCQkgICAgICAgJnBHYmwtPnR4cV9lbmRfYWRkci52YWx1ZSk7CgkJfSBlbHNlIGlmIChwQWRhcHRlci0+UmVnaXN0cnlKdW1ib1BhY2tldCA8IDgxOTIpIHsKCQkJLyogRm9yIGp1bWJvIHBhY2tldHMgPiAyayBidXQgPCA4aywgc3BsaXQgNTAtNTAuICovCgkJCXdyaXRlbCgwLCAmcEdibC0+cnhxX3N0YXJ0X2FkZHIudmFsdWUpOwoJCQl3cml0ZWwoSU5URVJOQUxfTUVNX1JYX09GRlNFVCwKCQkJICAgICAgICZwR2JsLT5yeHFfZW5kX2FkZHIudmFsdWUpOwoJCQl3cml0ZWwoSU5URVJOQUxfTUVNX1JYX09GRlNFVCArIDEsCgkJCSAgICAgICAmcEdibC0+dHhxX3N0YXJ0X2FkZHIudmFsdWUpOwoJCQl3cml0ZWwoSU5URVJOQUxfTUVNX1NJWkUgLSAxLAoJCQkgICAgICAgJnBHYmwtPnR4cV9lbmRfYWRkci52YWx1ZSk7CgkJfSBlbHNlIHsKCQkJLyogOTIxNiBpcyB0aGUgb25seSBwYWNrZXQgc2l6ZSBncmVhdGVyIHRoYW4gOGsgdGhhdAoJCQkgKiBpcyBhdmFpbGFibGUuIFRoZSBUeCBidWZmZXIgaGFzIHRvIGJlIGJpZyBlbm91Z2gKCQkJICogZm9yIG9uZSB3aG9sZSBwYWNrZXQgb24gdGhlIFR4IHNpZGUuIFdlJ2xsIG1ha2UKCQkJICogdGhlIFR4IDk0MDgsIGFuZCBnaXZlIHRoZSByZXN0IHRvIFJ4CgkJCSAqLwoJCQl3cml0ZWwoMHgwMDAwLCAmcEdibC0+cnhxX3N0YXJ0X2FkZHIudmFsdWUpOwoJCQl3cml0ZWwoMHgwMWIzLCAmcEdibC0+cnhxX2VuZF9hZGRyLnZhbHVlKTsKCQkJd3JpdGVsKDB4MDFiNCwgJnBHYmwtPnR4cV9zdGFydF9hZGRyLnZhbHVlKTsKCQkJd3JpdGVsKElOVEVSTkFMX01FTV9TSVpFIC0gMSwKCQkJICAgICAgICZwR2JsLT50eHFfZW5kX2FkZHIudmFsdWUpOwoJCX0KCgkJLyogSW5pdGlhbGl6ZSB0aGUgbG9vcGJhY2sgcmVnaXN0ZXIuIERpc2FibGUgYWxsIGxvb3BiYWNrcy4gKi8KCQl3cml0ZWwoMCwgJnBHYmwtPmxvb3BiYWNrLnZhbHVlKTsKCX0gZWxzZSB7CgkJLyogRm9yIFBIWSBMaW5lIGxvb3BiYWNrLCB0aGUgbWVtb3J5IGlzIGNvbmZpZ3VyZWQgYXMgaWYgVHgKCQkgKiBhbmQgUnggYm90aCBoYXZlIGFsbCB0aGUgbWVtb3J5LiAgVGhpcyBpcyBiZWNhdXNlIHRoZQoJCSAqIFJ4TUFDIHdpbGwgd3JpdGUgZGF0YSBpbnRvIHRoZSBzcGFjZSwgYW5kIHRoZSBUeE1BQyB3aWxsCgkJICogcmVhZCBpdCBvdXQuCgkJICovCgkJd3JpdGVsKDAsICZwR2JsLT5yeHFfc3RhcnRfYWRkci52YWx1ZSk7CgkJd3JpdGVsKElOVEVSTkFMX01FTV9TSVpFIC0gMSwgJnBHYmwtPnJ4cV9lbmRfYWRkci52YWx1ZSk7CgkJd3JpdGVsKDAsICZwR2JsLT50eHFfc3RhcnRfYWRkci52YWx1ZSk7CgkJd3JpdGVsKElOVEVSTkFMX01FTV9TSVpFIC0gMSwgJnBHYmwtPnR4cV9lbmRfYWRkci52YWx1ZSk7CgoJCS8qIEluaXRpYWxpemUgdGhlIGxvb3BiYWNrIHJlZ2lzdGVyIChNQUMgbG9vcGJhY2spLiAqLwoJCXdyaXRlbCgxLCAmcEdibC0+bG9vcGJhY2sudmFsdWUpOwoJfQoKCS8qIE1TSSBSZWdpc3RlciAqLwoJd3JpdGVsKDAsICZwR2JsLT5tc2lfY29uZmlnLnZhbHVlKTsKCgkvKiBCeSBkZWZhdWx0LCBkaXNhYmxlIHRoZSB3YXRjaGRvZyB0aW1lci4gIEl0IHdpbGwgYmUgZW5hYmxlZCB3aGVuCgkgKiBhIHBhY2tldCBpcyBxdWV1ZWQuCgkgKi8KCXdyaXRlbCgwLCAmcEdibC0+d2F0Y2hkb2dfdGltZXIpOwoKCURCR19MRUFWRShldDEzMXhfZGJnaW5mbyk7Cn0KCi8qKgogKiBDb25maWdNTUNSZWdzIC0gVXNlZCB0byBjb25maWd1cmUgdGhlIG1haW4gbWVtb3J5IHJlZ2lzdGVycyBpbiB0aGUgSkFHQ29yZQogKiBAcEFkYXB0ZXI6IHBvaW50ZXIgdG8gb3VyIGFkYXB0ZXIgc3RydWN0dXJlCiAqLwp2b2lkIENvbmZpZ01NQ1JlZ3Moc3RydWN0IGV0MTMxeF9hZGFwdGVyICpwQWRhcHRlcikKewoJTU1DX0NUUkxfdCBtbWNfY3RybCA9IHsgMCB9OwoKCURCR19FTlRFUihldDEzMXhfZGJnaW5mbyk7CgoJLyogQWxsIHdlIG5lZWQgdG8gZG8gaXMgaW5pdGlhbGl6ZSB0aGUgTWVtb3J5IENvbnRyb2wgUmVnaXN0ZXIgKi8KCW1tY19jdHJsLmJpdHMuZm9yY2VfY2UgPSAweDA7CgltbWNfY3RybC5iaXRzLnJ4ZG1hX2Rpc2FibGUgPSAweDA7CgltbWNfY3RybC5iaXRzLnR4ZG1hX2Rpc2FibGUgPSAweDA7CgltbWNfY3RybC5iaXRzLnR4bWFjX2Rpc2FibGUgPSAweDA7CgltbWNfY3RybC5iaXRzLnJ4bWFjX2Rpc2FibGUgPSAweDA7CgltbWNfY3RybC5iaXRzLmFyYl9kaXNhYmxlID0gMHgwOwoJbW1jX2N0cmwuYml0cy5tbWNfZW5hYmxlID0gMHgxOwoKCXdyaXRlbChtbWNfY3RybC52YWx1ZSwgJnBBZGFwdGVyLT5DU1JBZGRyZXNzLT5tbWMubW1jX2N0cmwudmFsdWUpOwoKCURCR19MRUFWRShldDEzMXhfZGJnaW5mbyk7Cn0KCnZvaWQgZXQxMzF4X2VuYWJsZV9pbnRlcnJ1cHRzKHN0cnVjdCBldDEzMXhfYWRhcHRlciAqYWRhcHRlcikKewoJdWludDMyX3QgTWFza1ZhbHVlOwoKCS8qIEVuYWJsZSBhbGwgZ2xvYmFsIGludGVycnVwdHMgKi8KCWlmICgoYWRhcHRlci0+Rmxvd0NvbnRyb2wgPT0gVHhPbmx5KSB8fCAoYWRhcHRlci0+Rmxvd0NvbnRyb2wgPT0gQm90aCkpIHsKCQlNYXNrVmFsdWUgPSBJTlRfTUFTS19FTkFCTEU7Cgl9IGVsc2UgewoJCU1hc2tWYWx1ZSA9IElOVF9NQVNLX0VOQUJMRV9OT19GTE9XOwoJfQoKCWlmIChhZGFwdGVyLT5Ecml2ZXJOb1BoeUFjY2VzcykgewoJCU1hc2tWYWx1ZSB8PSAweDEwMDAwOwoJfQoKCWFkYXB0ZXItPkNhY2hlZE1hc2tWYWx1ZS52YWx1ZSA9IE1hc2tWYWx1ZTsKCXdyaXRlbChNYXNrVmFsdWUsICZhZGFwdGVyLT5DU1JBZGRyZXNzLT5nbG9iYWwuaW50X21hc2sudmFsdWUpOwp9Cgp2b2lkIGV0MTMxeF9kaXNhYmxlX2ludGVycnVwdHMoc3RydWN0IGV0MTMxeF9hZGFwdGVyICogYWRhcHRlcikKewoJLyogRGlzYWJsZSBhbGwgZ2xvYmFsIGludGVycnVwdHMgKi8KCWFkYXB0ZXItPkNhY2hlZE1hc2tWYWx1ZS52YWx1ZSA9IElOVF9NQVNLX0RJU0FCTEU7Cgl3cml0ZWwoSU5UX01BU0tfRElTQUJMRSwgJmFkYXB0ZXItPkNTUkFkZHJlc3MtPmdsb2JhbC5pbnRfbWFzay52YWx1ZSk7Cn0K