LyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwovKiBpMmMtZWxla3Rvci5jIGkyYy1odyBhY2Nlc3MgZm9yIFBDRjg1ODQgc3R5bGUgaXNhIGJ1cyBhZGFwdGVzICAgICAgICAgICAgICovCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KLyogICBDb3B5cmlnaHQgKEMpIDE5OTUtOTcgU2ltb24gRy4gVm9nbAogICAgICAgICAgICAgICAgICAgMTk5OC05OSBIYW5zIEJlcmdsdW5kCgogICAgVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICAgIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAgICB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgogICAgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KCiAgICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICAgIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAgICBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAgICBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgoKICAgIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAgICBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogICAgRm91bmRhdGlvbiwgSW5jLiwgNjc1IE1hc3MgQXZlLCBDYW1icmlkZ2UsIE1BIDAyMTM5LCBVU0EuCQkgICAgICovCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCi8qIFdpdGggc29tZSBjaGFuZ2VzIGZyb20gS3n2c3RpIE3kbGtraSA8a21hbGtraUBjYy5odXQuZmk+IGFuZCBldmVuCiAgIEZyb2RvIExvb2lqYWFyZCA8ZnJvZG9sQGRkcy5ubD4gKi8KCi8qIFBhcnRpYWx5IHJld3JpdGVuIGJ5IE9sZWcgSS4gVmRvdmlraW4gZm9yIG1tYXBwZWQgc3VwcG9ydCBvZiAKICAgZm9yIEFscGhhIFByb2Nlc3NvciBJbmMuIFVQLTIwMDAoKykgYm9hcmRzICovCgojaW5jbHVkZSA8bGludXgvY29uZmlnLmg+CiNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4KI2luY2x1ZGUgPGxpbnV4L2lvcG9ydC5oPgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvc2xhYi5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvaW50ZXJydXB0Lmg+CiNpbmNsdWRlIDxsaW51eC9wY2kuaD4KI2luY2x1ZGUgPGxpbnV4L3dhaXQuaD4KCiNpbmNsdWRlIDxsaW51eC9pMmMuaD4KI2luY2x1ZGUgPGxpbnV4L2kyYy1hbGdvLXBjZi5oPgoKI2luY2x1ZGUgPGFzbS9pby5oPgojaW5jbHVkZSA8YXNtL2lycS5oPgoKI2luY2x1ZGUgIi4uL2FsZ29zL2kyYy1hbGdvLXBjZi5oIgoKI2RlZmluZSBERUZBVUxUX0JBU0UgMHgzMzAKCnN0YXRpYyBpbnQgYmFzZTsKc3RhdGljIGludCBpcnE7CnN0YXRpYyBpbnQgY2xvY2sgID0gMHgxYzsKc3RhdGljIGludCBvd24gICAgPSAweDU1OwpzdGF0aWMgaW50IG1tYXBwZWQ7CgovKiB2ZG92aWtpbjogcmVtb3ZlZCBzdGF0aWMgc3RydWN0IGkyY19wY2ZfaXNhIGdwaTsgY29kZSAtIAogIHRoaXMgbW9kdWxlIGluIHJlYWwgc3VwcG9ydHMgb25seSBvbmUgZGV2aWNlLCBkdWUgdG8gbWlzc2luZyBhcmd1bWVudHMKICBpbiBzb21lIGZ1bmN0aW9ucywgY2FsbGVkIGZyb20gdGhlIGFsZ28tcGNmIG1vZHVsZS4gU29tZXRpbWVzIGl0J3MKICBuZWVkIHRvIGJlIHJld3JpdGVuIC0gYnV0IGZvciBub3cganVzdCByZW1vdmUgdGhpcyBmb3Igc2ltcGxlciByZWFkaW5nICovCgpzdGF0aWMgd2FpdF9xdWV1ZV9oZWFkX3QgcGNmX3dhaXQ7CnN0YXRpYyBpbnQgcGNmX3BlbmRpbmc7CnN0YXRpYyBzcGlubG9ja190IGxvY2s7CgovKiAtLS0tLSBsb2NhbCBmdW5jdGlvbnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQkqLwoKc3RhdGljIHZvaWQgcGNmX2lzYV9zZXRieXRlKHZvaWQgKmRhdGEsIGludCBjdGwsIGludCB2YWwpCnsKCWludCBhZGRyZXNzID0gY3RsID8gKGJhc2UgKyAxKSA6IGJhc2U7CgoJLyogZW5hYmxlIGlycSBpZiBhbnkgc3BlY2lmaWVkIGZvciBzZXJpYWwgb3BlcmF0aW9uICovCglpZiAoY3RsICYmIGlycSAmJiAodmFsICYgSTJDX1BDRl9FU08pKSB7CgkJdmFsIHw9IEkyQ19QQ0ZfRU5JOwoJfQoKCXByX2RlYnVnKCJpMmMtZWxla3RvcjogV3JpdGUgMHglWCAweCUwMlhcbiIsIGFkZHJlc3MsIHZhbCAmIDI1NSk7CgoJc3dpdGNoIChtbWFwcGVkKSB7CgljYXNlIDA6IC8qIHJlZ3VsYXIgSS9PICovCgkJb3V0Yih2YWwsIGFkZHJlc3MpOwoJCWJyZWFrOwoJY2FzZSAyOiAvKiBkb3VibGUgbWFwcGVkIEkvTyBuZWVkZWQgZm9yIFVQMjAwMCBib2FyZCwKICAgICAgICAgICAgICAgICAgIEkgZG9uJ3Qga25vdyB3aHkgdGhpcy4uLiAqLwoJCXdyaXRlYih2YWwsICh2b2lkICopYWRkcmVzcyk7CgkJLyogZmFsbCAqLwoJY2FzZSAxOiAvKiBtZW1vcnkgbWFwcGVkIEkvTyAqLwoJCXdyaXRlYih2YWwsICh2b2lkICopYWRkcmVzcyk7CgkJYnJlYWs7Cgl9Cn0KCnN0YXRpYyBpbnQgcGNmX2lzYV9nZXRieXRlKHZvaWQgKmRhdGEsIGludCBjdGwpCnsKCWludCBhZGRyZXNzID0gY3RsID8gKGJhc2UgKyAxKSA6IGJhc2U7CglpbnQgdmFsID0gbW1hcHBlZCA/IHJlYWRiKCh2b2lkICopYWRkcmVzcykgOiBpbmIoYWRkcmVzcyk7CgoJcHJfZGVidWcoImkyYy1lbGVrdG9yOiBSZWFkIDB4JVggMHglMDJYXG4iLCBhZGRyZXNzLCB2YWwpOwoKCXJldHVybiAodmFsKTsKfQoKc3RhdGljIGludCBwY2ZfaXNhX2dldG93bih2b2lkICpkYXRhKQp7CglyZXR1cm4gKG93bik7Cn0KCgpzdGF0aWMgaW50IHBjZl9pc2FfZ2V0Y2xvY2sodm9pZCAqZGF0YSkKewoJcmV0dXJuIChjbG9jayk7Cn0KCnN0YXRpYyB2b2lkIHBjZl9pc2Ffd2FpdGZvcnBpbih2b2lkKSB7CgoJaW50IHRpbWVvdXQgPSAyOwoJbG9uZyBmbGFnczsKCglpZiAoaXJxID4gMCkgewoJCXNwaW5fbG9ja19pcnFzYXZlKCZsb2NrLCBmbGFncyk7CgkJaWYgKHBjZl9wZW5kaW5nID09IDApIHsKCQkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmbG9jaywgZmxhZ3MpOwoJCQlpZiAoaW50ZXJydXB0aWJsZV9zbGVlcF9vbl90aW1lb3V0KCZwY2Zfd2FpdCwKCQkJCQkJCQl0aW1lb3V0KkhaKSkgewoJCQkJc3Bpbl9sb2NrX2lycXNhdmUoJmxvY2ssIGZsYWdzKTsKCQkJCWlmIChwY2ZfcGVuZGluZyA9PSAxKSB7CgkJCQkJcGNmX3BlbmRpbmcgPSAwOwoJCQkJfQoJCQkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmbG9jaywgZmxhZ3MpOwoJCQl9CgkJfSBlbHNlIHsKCQkJcGNmX3BlbmRpbmcgPSAwOwoJCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZsb2NrLCBmbGFncyk7CgkJfQoJfSBlbHNlIHsKCQl1ZGVsYXkoMTAwKTsKCX0KfQoKCnN0YXRpYyBpcnFyZXR1cm5fdCBwY2ZfaXNhX2hhbmRsZXIoaW50IHRoaXNfaXJxLCB2b2lkICpkZXZfaWQsIHN0cnVjdCBwdF9yZWdzICpyZWdzKSB7CglzcGluX2xvY2soJmxvY2spOwoJcGNmX3BlbmRpbmcgPSAxOwoJc3Bpbl91bmxvY2soJmxvY2spOwoJd2FrZV91cF9pbnRlcnJ1cHRpYmxlKCZwY2Zfd2FpdCk7CglyZXR1cm4gSVJRX0hBTkRMRUQ7Cn0KCgpzdGF0aWMgaW50IHBjZl9pc2FfaW5pdCh2b2lkKQp7CglzcGluX2xvY2tfaW5pdCgmbG9jayk7CglpZiAoIW1tYXBwZWQpIHsKCQlpZiAoIXJlcXVlc3RfcmVnaW9uKGJhc2UsIDIsICJpMmMgKGlzYSBidXMgYWRhcHRlcikiKSkgewoJCQlwcmludGsoS0VSTl9FUlIKCQkJICAgICAgICJpMmMtZWxla3RvcjogcmVxdWVzdGVkIEkvTyByZWdpb24gKDB4JVg6MikgIgoJCQkgICAgICAgImlzIGluIHVzZS5cbiIsIGJhc2UpOwoJCQlyZXR1cm4gLUVOT0RFVjsKCQl9Cgl9CglpZiAoaXJxID4gMCkgewoJCWlmIChyZXF1ZXN0X2lycShpcnEsIHBjZl9pc2FfaGFuZGxlciwgMCwgIlBDRjg1ODQiLCBOVUxMKSA8IDApIHsKCQkJcHJpbnRrKEtFUk5fRVJSICJpMmMtZWxla3RvcjogUmVxdWVzdCBpcnElZCBmYWlsZWRcbiIsIGlycSk7CgkJCWlycSA9IDA7CgkJfSBlbHNlCgkJCWVuYWJsZV9pcnEoaXJxKTsKCX0KCXJldHVybiAwOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogRW5jYXBzdWxhdGUgdGhlIGFib3ZlIGZ1bmN0aW9ucyBpbiB0aGUgY29ycmVjdCBvcGVyYXRpb25zIHN0cnVjdHVyZS4KICogVGhpcyBpcyBvbmx5IGRvbmUgd2hlbiBtb3JlIHRoYW4gb25lIGhhcmR3YXJlIGFkYXB0ZXIgaXMgc3VwcG9ydGVkLgogKi8Kc3RhdGljIHN0cnVjdCBpMmNfYWxnb19wY2ZfZGF0YSBwY2ZfaXNhX2RhdGEgPSB7Cgkuc2V0cGNmCSAgICA9IHBjZl9pc2Ffc2V0Ynl0ZSwKCS5nZXRwY2YJICAgID0gcGNmX2lzYV9nZXRieXRlLAoJLmdldG93bgkgICAgPSBwY2ZfaXNhX2dldG93biwKCS5nZXRjbG9jayAgID0gcGNmX2lzYV9nZXRjbG9jaywKCS53YWl0Zm9ycGluID0gcGNmX2lzYV93YWl0Zm9ycGluLAoJLnVkZWxheQkgICAgPSAxMCwKCS5tZGVsYXkJICAgID0gMTAsCgkudGltZW91dCAgICA9IDEwMCwKfTsKCnN0YXRpYyBzdHJ1Y3QgaTJjX2FkYXB0ZXIgcGNmX2lzYV9vcHMgPSB7Cgkub3duZXIJCT0gVEhJU19NT0RVTEUsCgkuaWQJCT0gSTJDX0hXX1BfRUxFSywKCS5hbGdvX2RhdGEJPSAmcGNmX2lzYV9kYXRhLAoJLm5hbWUJCT0gIlBDRjg1ODQgSVNBIGFkYXB0ZXIiLAp9OwoKc3RhdGljIGludCBfX2luaXQgaTJjX3BjZmlzYV9pbml0KHZvaWQpIAp7CiNpZmRlZiBfX2FscGhhX18KCS8qIGNoZWNrIHRvIHNlZSB3ZSBoYXZlIG1lbW9yeSBtYXBwZWQgUENGODU4NCBjb25uZWN0ZWQgdG8gdGhlIAoJQ3lwcmVzcyBjeTgyYzY5MyBQQ0ktSVNBIGJyaWRnZSBhcyBvbiBVUDIwMDAgYm9hcmQgKi8KCWlmIChiYXNlID09IDApIHsKCQlzdHJ1Y3QgcGNpX2RldiAqY3k2OTNfZGV2OwoJCQoJCWN5NjkzX2RldiA9IHBjaV9nZXRfZGV2aWNlKFBDSV9WRU5ET1JfSURfQ09OVEFRLCAKCQkJCQkgICBQQ0lfREVWSUNFX0lEX0NPTlRBUV84MkM2OTMsIE5VTEwpOwoJCWlmIChjeTY5M19kZXYpIHsKCQkJY2hhciBjb25maWc7CgkJCS8qIHllYXAsIHdlJ3ZlIGZvdW5kIGN5cHJlc3MsIGxldCdzIGNoZWNrIGNvbmZpZyAqLwoJCQlpZiAoIXBjaV9yZWFkX2NvbmZpZ19ieXRlKGN5NjkzX2RldiwgMHg0NywgJmNvbmZpZykpIHsKCQkJCQoJCQkJcHJfZGVidWcoImkyYy1lbGVrdG9yOiBmb3VuZCBjeTgyYzY5MywgY29uZmlnIHJlZ2lzdGVyIDB4NDcgPSAweCUwMnguXG4iLCBjb25maWcpOwoKCQkJCS8qIFVQMjAwMCBib2FyZCBoYXMgdGhpcyByZWdpc3RlciBzZXQgdG8gMHhlMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidXQgdGhlIG1vc3Qgc2lnbmlmaWNhbnQgYml0IGFzIHNlZW1zIGNhbiBiZSAKCQkJCSAgIHJlc2V0IGR1cmluZyB0aGUgcHJvcGVyIGluaXRpYWxpc2F0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VxdWVuY2UgaWYgZ3V5cyBmcm9tIEFQSSBkZWNpZGVzIHRvIGRvIHRoYXQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc28sIHdlIGNhbiBldmVuIGVuYWJsZSBUc3VuYW1pIFBjaGlwCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93IGZvciB0aGUgdXBwZXIgMSBHYikgKi8KCgkJCQkvKiBzbyBqdXN0IGNoZWNrIGZvciBST01DUyBhdCAweGUwMDAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJPTUNTIGVuYWJsZWQgZm9yIHdyaXRlcwoJCQkJICAgYW5kIGV4dGVybmFsIFhEIEJ1cyBidWZmZXIgaW4gdXNlLiAqLwoJCQkJaWYgKChjb25maWcgJiAweDdmKSA9PSAweDYxKSB7CgkJCQkJLyogc2VlbXMgdG8gYmUgVVAyMDAwIGxpa2UgYm9hcmQgKi8KCQkJCQliYXNlID0gMHhlMDAwMDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIEkgZG9uJ3Qga25vdyB3aHkgd2UgbmVlZCB0bwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGUgdHdpY2UgKi8KCQkJCQltbWFwcGVkID0gMjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIFVQMjAwMCBkcml2ZXMgSVNBIHdpdGgKCQkJCQkgICA4LjI1IE1IeiAoUENJLzQpIGNsb2NrCgkJCQkJICAgKHRoaXMgY2FuIGJlIHJlYWQgZnJvbSBjeXByZXNzKSAqLwoJCQkJCWNsb2NrID0gSTJDX1BDRl9DTEsgfCBJMkNfUENGX1RSTlM5MDsKCQkJCQlwcmludGsoS0VSTl9JTkZPICJpMmMtZWxla3RvcjogZm91bmQgQVBJIFVQMjAwMCBsaWtlIGJvYXJkLCB3aWxsIHByb2JlIFBDRjg1ODQgbGF0ZXIuXG4iKTsKCQkJCX0KCQkJfQoJCQlwY2lfZGV2X3B1dChjeTY5M19kZXYpOwoJCX0KCX0KI2VuZGlmCgoJLyogc2FuaXR5IGNoZWNrcyBmb3IgbW1hcHBlZCBJL08gKi8KCWlmIChtbWFwcGVkICYmIGJhc2UgPCAweGM4MDAwKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJpMmMtZWxla3RvcjogaW5jb3JyZWN0IGJhc2UgYWRkcmVzcyAoMHglMFgpIHNwZWNpZmllZCBmb3IgbW1hcHBlZCBJL08uXG4iLCBiYXNlKTsKCQlyZXR1cm4gLUVOT0RFVjsKCX0KCglwcmludGsoS0VSTl9JTkZPICJpMmMtZWxla3RvcjogaTJjIHBjZjg1ODQtaXNhIGFkYXB0ZXIgZHJpdmVyXG4iKTsKCglpZiAoYmFzZSA9PSAwKSB7CgkJYmFzZSA9IERFRkFVTFRfQkFTRTsKCX0KCglpbml0X3dhaXRxdWV1ZV9oZWFkKCZwY2Zfd2FpdCk7CglpZiAocGNmX2lzYV9pbml0KCkpCgkJcmV0dXJuIC1FTk9ERVY7CglpZiAoaTJjX3BjZl9hZGRfYnVzKCZwY2ZfaXNhX29wcykgPCAwKQoJCWdvdG8gZmFpbDsKCQoJcHJpbnRrKEtFUk5fRVJSICJpMmMtZWxla3RvcjogZm91bmQgZGV2aWNlIGF0ICUjeC5cbiIsIGJhc2UpOwoKCXJldHVybiAwOwoKIGZhaWw6CglpZiAoaXJxID4gMCkgewoJCWRpc2FibGVfaXJxKGlycSk7CgkJZnJlZV9pcnEoaXJxLCBOVUxMKTsKCX0KCglpZiAoIW1tYXBwZWQpCgkJcmVsZWFzZV9yZWdpb24oYmFzZSAsIDIpOwoJcmV0dXJuIC1FTk9ERVY7Cn0KCnN0YXRpYyB2b2lkIGkyY19wY2Zpc2FfZXhpdCh2b2lkKQp7CglpMmNfcGNmX2RlbF9idXMoJnBjZl9pc2Ffb3BzKTsKCglpZiAoaXJxID4gMCkgewoJCWRpc2FibGVfaXJxKGlycSk7CgkJZnJlZV9pcnEoaXJxLCBOVUxMKTsKCX0KCglpZiAoIW1tYXBwZWQpCgkJcmVsZWFzZV9yZWdpb24oYmFzZSAsIDIpOwp9CgpNT0RVTEVfQVVUSE9SKCJIYW5zIEJlcmdsdW5kIDxoYkBzcGFjZXRlYy5ubz4iKTsKTU9EVUxFX0RFU0NSSVBUSU9OKCJJMkMtQnVzIGFkYXB0ZXIgcm91dGluZXMgZm9yIFBDRjg1ODQgSVNBIGJ1cyBhZGFwdGVyIik7Ck1PRFVMRV9MSUNFTlNFKCJHUEwiKTsKCm1vZHVsZV9wYXJhbShiYXNlLCBpbnQsIDApOwptb2R1bGVfcGFyYW0oaXJxLCBpbnQsIDApOwptb2R1bGVfcGFyYW0oY2xvY2ssIGludCwgMCk7Cm1vZHVsZV9wYXJhbShvd24sIGludCwgMCk7Cm1vZHVsZV9wYXJhbShtbWFwcGVkLCBpbnQsIDApOwoKbW9kdWxlX2luaXQoaTJjX3BjZmlzYV9pbml0KTsKbW9kdWxlX2V4aXQoaTJjX3BjZmlzYV9leGl0KTsK