LyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwovKiBpMmMtYWxnby1wY2YuYyBpMmMgZHJpdmVyIGFsZ29yaXRobXMgZm9yIFBDRjg1ODQgYWRhcHRlcnMJCSAgICAgKi8KLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwovKiAgIENvcHlyaWdodCAoQykgMTk5NS0xOTk3IFNpbW9uIEcuIFZvZ2wKICAgICAgICAgICAgICAgICAgIDE5OTgtMjAwMCBIYW5zIEJlcmdsdW5kCgogICAgVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICAgIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAgICB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgogICAgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KCiAgICBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICAgIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAgICBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAgICBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgoKICAgIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAgICBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogICAgRm91bmRhdGlvbiwgSW5jLiwgNjc1IE1hc3MgQXZlLCBDYW1icmlkZ2UsIE1BIDAyMTM5LCBVU0EuCQkgICAgICovCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCi8qIFdpdGggc29tZSBjaGFuZ2VzIGZyb20gS3n2c3RpIE3kbGtraSA8a21hbGtraUBjYy5odXQuZmk+IGFuZCAKICAgRnJvZG8gTG9vaWphYXJkIDxmcm9kb2xAZGRzLm5sPiAsYW5kIGFsc28gZnJvbSBNYXJ0aW4gQmFpbGV5CiAgIDxtYmFpbGV5QGxpdHRsZWZlZXQtaW5jLmNvbT4gKi8KCi8qIFBhcnRpYWxseSByZXdyaXRlbiBieSBPbGVnIEkuIFZkb3Zpa2luIDx2ZG92aWtpbkBqc2NjLnJ1PiB0byBoYW5kbGUgbXVsdGlwbGUKICAgbWVzc2FnZXMsIHByb3BlciBzdG9wL3JlcHN0YXJ0IHNpZ25hbGluZyBkdXJpbmcgcmVjZWl2ZSwKICAgYWRkZWQgZGV0ZWN0IGNvZGUgKi8KCiNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4KI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvZGVsYXkuaD4KI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KI2luY2x1ZGUgPGxpbnV4L2Vycm5vLmg+CiNpbmNsdWRlIDxsaW51eC9pMmMuaD4KI2luY2x1ZGUgPGxpbnV4L2kyYy1hbGdvLXBjZi5oPgojaW5jbHVkZSAiaTJjLWFsZ28tcGNmLmgiCgoKI2RlZmluZSBERUIyKHgpIGlmIChpMmNfZGVidWc+PTIpIHgKI2RlZmluZSBERUIzKHgpIGlmIChpMmNfZGVidWc+PTMpIHggLyogcHJpbnQgc2V2ZXJhbCBzdGF0aXN0aWNhbCB2YWx1ZXMqLwojZGVmaW5lIERFQlBST1RPKHgpIGlmIChpMmNfZGVidWc+PTkpIHg7CiAJLyogZGVidWcgdGhlIHByb3RvY29sIGJ5IHNob3dpbmcgdHJhbnNmZXJyZWQgYml0cyAqLwojZGVmaW5lIERFRl9USU1FT1VUIDE2CgovKiBtb2R1bGUgcGFyYW1ldGVyczoKICovCnN0YXRpYyBpbnQgaTJjX2RlYnVnOwoKLyogLS0tIHNldHRpbmcgc3RhdGVzIG9uIHRoZSBidXMgd2l0aCB0aGUgcmlnaHQgdGltaW5nOiAtLS0tLS0tLS0tLS0tLS0JKi8KCiNkZWZpbmUgc2V0X3BjZihhZGFwLCBjdGwsIHZhbCkgYWRhcC0+c2V0cGNmKGFkYXAtPmRhdGEsIGN0bCwgdmFsKQojZGVmaW5lIGdldF9wY2YoYWRhcCwgY3RsKSBhZGFwLT5nZXRwY2YoYWRhcC0+ZGF0YSwgY3RsKQojZGVmaW5lIGdldF9vd24oYWRhcCkgYWRhcC0+Z2V0b3duKGFkYXAtPmRhdGEpCiNkZWZpbmUgZ2V0X2Nsb2NrKGFkYXApIGFkYXAtPmdldGNsb2NrKGFkYXAtPmRhdGEpCiNkZWZpbmUgaTJjX291dGIoYWRhcCwgdmFsKSBhZGFwLT5zZXRwY2YoYWRhcC0+ZGF0YSwgMCwgdmFsKQojZGVmaW5lIGkyY19pbmIoYWRhcCkgYWRhcC0+Z2V0cGNmKGFkYXAtPmRhdGEsIDApCgovKiAtLS0gb3RoZXIgYXV4aWxpYXJ5IGZ1bmN0aW9ucyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQkqLwoKc3RhdGljIHZvaWQgaTJjX3N0YXJ0KHN0cnVjdCBpMmNfYWxnb19wY2ZfZGF0YSAqYWRhcCkgCnsKCURFQlBST1RPKHByaW50aygiUyAiKSk7CglzZXRfcGNmKGFkYXAsIDEsIEkyQ19QQ0ZfU1RBUlQpOwp9CgpzdGF0aWMgdm9pZCBpMmNfcmVwc3RhcnQoc3RydWN0IGkyY19hbGdvX3BjZl9kYXRhICphZGFwKSAKewoJREVCUFJPVE8ocHJpbnRrKCIgU3IgIikpOwoJc2V0X3BjZihhZGFwLCAxLCBJMkNfUENGX1JFUFNUQVJUKTsKfQoKCnN0YXRpYyB2b2lkIGkyY19zdG9wKHN0cnVjdCBpMmNfYWxnb19wY2ZfZGF0YSAqYWRhcCkgCnsKCURFQlBST1RPKHByaW50aygiUFxuIikpOwoJc2V0X3BjZihhZGFwLCAxLCBJMkNfUENGX1NUT1ApOwp9CgpzdGF0aWMgaW50IHdhaXRfZm9yX2JiKHN0cnVjdCBpMmNfYWxnb19wY2ZfZGF0YSAqYWRhcCkgewoKCWludCB0aW1lb3V0ID0gREVGX1RJTUVPVVQ7CglpbnQgc3RhdHVzOwoKCXN0YXR1cyA9IGdldF9wY2YoYWRhcCwgMSk7CiNpZm5kZWYgU1RVQl9JMkMKCXdoaWxlICh0aW1lb3V0LS0gJiYgIShzdGF0dXMgJiBJMkNfUENGX0JCKSkgewoJCXVkZWxheSgxMDApOyAvKiB3YWl0IGZvciAxMDAgdXMgKi8KCQlzdGF0dXMgPSBnZXRfcGNmKGFkYXAsIDEpOwoJfQojZW5kaWYKCWlmICh0aW1lb3V0IDw9IDApIHsKCQlwcmludGsoS0VSTl9FUlIgIlRpbWVvdXQgd2FpdGluZyBmb3IgQnVzIEJ1c3lcbiIpOwoJfQoJCglyZXR1cm4gKHRpbWVvdXQ8PTApOwp9CgoKc3RhdGljIGludCB3YWl0X2Zvcl9waW4oc3RydWN0IGkyY19hbGdvX3BjZl9kYXRhICphZGFwLCBpbnQgKnN0YXR1cykgewoKCWludCB0aW1lb3V0ID0gREVGX1RJTUVPVVQ7CgoJKnN0YXR1cyA9IGdldF9wY2YoYWRhcCwgMSk7CiNpZm5kZWYgU1RVQl9JMkMKCXdoaWxlICh0aW1lb3V0LS0gJiYgKCpzdGF0dXMgJiBJMkNfUENGX1BJTikpIHsKCQlhZGFwLT53YWl0Zm9ycGluKCk7CgkJKnN0YXR1cyA9IGdldF9wY2YoYWRhcCwgMSk7Cgl9CglpZiAoKnN0YXR1cyAmIEkyQ19QQ0ZfTEFCKSB7CgkJREVCMihwcmludGsoS0VSTl9JTkZPIAoJCQkiaTJjLWFsZ28tcGNmLm86IGxvc3QgYXJiaXRyYXRpb24gKENTUiAweCUwMngpXG4iLAoJCQkgKnN0YXR1cykpOwoJCS8qIENsZWFudXAgZnJvbSBMQUItLSByZXNldCBhbmQgZW5hYmxlIEVTTy4KCQkgKiBUaGlzIHJlc2V0cyB0aGUgUENGODU4NDsgc2luY2Ugd2UndmUgbG9zdCB0aGUgYnVzLCBubwoJCSAqIGZ1cnRoZXIgYXR0ZW1wdHMgc2hvdWxkIGJlIG1hZGUgYnkgY2FsbGVycyB0byBjbGVhbiB1cCAKCQkgKiAobm8gaTJjX3N0b3AoKSBldGMuKQoJCSAqLwoJCXNldF9wY2YoYWRhcCwgMSwgSTJDX1BDRl9QSU4pOwoJCXNldF9wY2YoYWRhcCwgMSwgSTJDX1BDRl9FU08pOwoJCS8qIFRPRE86IHdlIHNob3VsZCBwYXVzZSBmb3IgYSB0aW1lIHBlcmlvZCBzdWZmaWNpZW50IGZvciBhbnkKCQkgKiBydW5uaW5nIEkyQyB0cmFuc2FjdGlvbiB0byBjb21wbGV0ZS0tIHRoZSBhcmJpdHJhdGlvbgoJCSAqIGxvZ2ljIHdvbid0IHdvcmsgcHJvcGVybHkgdW50aWwgdGhlIG5leHQgU1RBUlQgaXMgc2Vlbi4KCQkgKi8KCQlERUIyKHByaW50ayhLRVJOX0lORk8gCgkJCSJpMmMtYWxnby1wY2YubzogcmVzZXQgTEFCIGNvbmRpdGlvbiAoQ1NSIDB4JTAyeClcbiIsIAoJCQlnZXRfcGNmKGFkYXAsMSkpKTsKCQlyZXR1cm4oLUVJTlRSKTsKCX0KI2VuZGlmCglpZiAodGltZW91dCA8PSAwKQoJCXJldHVybigtMSk7CgllbHNlCgkJcmV0dXJuKDApOwp9CgovKiAKICogVGhpcyBzaG91bGQgcGVyZm9ybSB0aGUgJ1BDRjg1ODQgaW5pdGlhbGl6YXRpb24gc2VxdWVuY2UnIGFzIGRlc2NyaWJlZAogKiBpbiB0aGUgUGhpbGlwcyBJQzEyIGRhdGEgYm9vayAoMTk5NSwgQXVnIDI5KS4KICogVGhlcmUgc2hvdWxkIGJlIGEgMzAgY2xvY2sgY3ljbGUgd2FpdCBhZnRlciByZXNldCwgSSBhc3N1bWUgdGhpcwogKiBoYXMgYmVlbiBmdWxmaWxsZWQuCiAqIFRoZXJlIHNob3VsZCBiZSBhIGRlbGF5IGF0IHRoZSBlbmQgZXF1YWwgdG8gdGhlIGxvbmdlc3QgSTJDIG1lc3NhZ2UKICogdG8gc3luY2hyb25pemUgdGhlIEJCLWJpdCAoaW4gbXVsdGltYXN0ZXIgc3lzdGVtcykuIEhvdyBsb25nIGlzCiAqIHRoaXM/IEkgYXNzdW1lIDEgc2Vjb25kIGlzIGFsd2F5cyBsb25nIGVub3VnaC4KICoKICogdmRvdmlraW46IGFkZGVkIGRldGVjdCBjb2RlIGZvciBQQ0Y4NTg0CiAqLwpzdGF0aWMgaW50IHBjZl9pbml0Xzg1ODQgKHN0cnVjdCBpMmNfYWxnb19wY2ZfZGF0YSAqYWRhcCkKewoJdW5zaWduZWQgY2hhciB0ZW1wOwoKCURFQjMocHJpbnRrKEtFUk5fREVCVUcgImkyYy1hbGdvLXBjZi5vOiBQQ0Ygc3RhdGUgMHglMDJ4XG4iLCBnZXRfcGNmKGFkYXAsIDEpKSk7CgoJLyogUzE9MHg4MDogUzAgc2VsZWN0ZWQsIHNlcmlhbCBpbnRlcmZhY2Ugb2ZmICovCglzZXRfcGNmKGFkYXAsIDEsIEkyQ19QQ0ZfUElOKTsKCS8qIGNoZWNrIHRvIHNlZSBTMSBub3cgdXNlZCBhcyBSL1cgY3RybCAtCgkgICBQQ0Y4NTg0IGRvZXMgdGhhdCB3aGVuIEVTTyBpcyB6ZXJvICovCglpZiAoKCh0ZW1wID0gZ2V0X3BjZihhZGFwLCAxKSkgJiAweDdmKSAhPSAoMCkpIHsKCQlERUIyKHByaW50ayhLRVJOX0VSUiAiaTJjLWFsZ28tcGNmLm86IFBDRiBkZXRlY3Rpb24gZmFpbGVkIC0tIGNhbid0IHNlbGVjdCBTMCAoMHglMDJ4KS5cbiIsIHRlbXApKTsKCQlyZXR1cm4gLUVOWElPOyAvKiBkZWZpbmV0bHkgbm90IFBDRjg1ODQgKi8KCX0KCgkvKiBsb2FkIG93biBhZGRyZXNzIGluIFMwLCBlZmZlY3RpdmUgYWRkcmVzcyBpcyAob3duIDw8IDEpCSovCglpMmNfb3V0YihhZGFwLCBnZXRfb3duKGFkYXApKTsKCS8qIGNoZWNrIGl0J3MgcmVhbGx5IHdyaXR0ZW4gKi8KCWlmICgodGVtcCA9IGkyY19pbmIoYWRhcCkpICE9IGdldF9vd24oYWRhcCkpIHsKCQlERUIyKHByaW50ayhLRVJOX0VSUiAiaTJjLWFsZ28tcGNmLm86IFBDRiBkZXRlY3Rpb24gZmFpbGVkIC0tIGNhbid0IHNldCBTMCAoMHglMDJ4KS5cbiIsIHRlbXApKTsKCQlyZXR1cm4gLUVOWElPOwoJfQoKCS8qIFMxPTB4QTAsIG5leHQgYnl0ZSBpbiBTMgkJCQkJKi8KCXNldF9wY2YoYWRhcCwgMSwgSTJDX1BDRl9QSU4gfCBJMkNfUENGX0VTMSk7CgkvKiBjaGVjayB0byBzZWUgUzIgbm93IHNlbGVjdGVkICovCglpZiAoKCh0ZW1wID0gZ2V0X3BjZihhZGFwLCAxKSkgJiAweDdmKSAhPSBJMkNfUENGX0VTMSkgewoJCURFQjIocHJpbnRrKEtFUk5fRVJSICJpMmMtYWxnby1wY2YubzogUENGIGRldGVjdGlvbiBmYWlsZWQgLS0gY2FuJ3Qgc2VsZWN0IFMyICgweCUwMngpLlxuIiwgdGVtcCkpOwoJCXJldHVybiAtRU5YSU87Cgl9CgoJLyogbG9hZCBjbG9jayByZWdpc3RlciBTMgkJCQkJKi8KCWkyY19vdXRiKGFkYXAsIGdldF9jbG9jayhhZGFwKSk7CgkvKiBjaGVjayBpdCdzIHJlYWxseSB3cml0dGVuLCB0aGUgb25seSA1IGxvd2VzdCBiaXRzIGRvZXMgbWF0dGVyICovCglpZiAoKCh0ZW1wID0gaTJjX2luYihhZGFwKSkgJiAweDFmKSAhPSBnZXRfY2xvY2soYWRhcCkpIHsKCQlERUIyKHByaW50ayhLRVJOX0VSUiAiaTJjLWFsZ28tcGNmLm86IFBDRiBkZXRlY3Rpb24gZmFpbGVkIC0tIGNhbid0IHNldCBTMiAoMHglMDJ4KS5cbiIsIHRlbXApKTsKCQlyZXR1cm4gLUVOWElPOwoJfQoKCS8qIEVuYWJsZSBzZXJpYWwgaW50ZXJmYWNlLCBpZGxlLCBTMCBzZWxlY3RlZAkJCSovCglzZXRfcGNmKGFkYXAsIDEsIEkyQ19QQ0ZfSURMRSk7CgoJLyogY2hlY2sgdG8gc2VlIFBDRiBpcyByZWFsbHkgaWRsZWQgYW5kIHdlIGNhbiBhY2Nlc3Mgc3RhdHVzIHJlZ2lzdGVyICovCglpZiAoKHRlbXAgPSBnZXRfcGNmKGFkYXAsIDEpKSAhPSAoSTJDX1BDRl9QSU4gfCBJMkNfUENGX0JCKSkgewoJCURFQjIocHJpbnRrKEtFUk5fRVJSICJpMmMtYWxnby1wY2YubzogUENGIGRldGVjdGlvbiBmYWlsZWQgLS0gY2FuJ3Qgc2VsZWN0IFMxYCAoMHglMDJ4KS5cbiIsIHRlbXApKTsKCQlyZXR1cm4gLUVOWElPOwoJfQoJCglwcmludGsoS0VSTl9ERUJVRyAiaTJjLWFsZ28tcGNmLm86IGRldGV0ZWQgYW5kIGluaXRpYWxpemVkIFBDRjg1ODQuXG4iKTsKCglyZXR1cm4gMDsKfQoKCi8qIC0tLS0tIFV0aWxpdHkgZnVuY3Rpb25zCiAqLwoKc3RhdGljIGlubGluZSBpbnQgdHJ5X2FkZHJlc3Moc3RydWN0IGkyY19hbGdvX3BjZl9kYXRhICphZGFwLAoJCSAgICAgICB1bnNpZ25lZCBjaGFyIGFkZHIsIGludCByZXRyaWVzKQp7CglpbnQgaSwgc3RhdHVzLCByZXQgPSAtMTsKCWludCB3ZnA7Cglmb3IgKGk9MDtpPHJldHJpZXM7aSsrKSB7CgkJaTJjX291dGIoYWRhcCwgYWRkcik7CgkJaTJjX3N0YXJ0KGFkYXApOwoJCXN0YXR1cyA9IGdldF9wY2YoYWRhcCwgMSk7CgkJaWYgKCh3ZnAgPSB3YWl0X2Zvcl9waW4oYWRhcCwgJnN0YXR1cykpID49IDApIHsKCQkJaWYgKChzdGF0dXMgJiBJMkNfUENGX0xSQikgPT0gMCkgeyAKCQkJCWkyY19zdG9wKGFkYXApOwoJCQkJYnJlYWs7CS8qIHN1Y2Nlc3MhICovCgkJCX0KCQl9CgkJaWYgKHdmcCA9PSAtRUlOVFIpIHsKCQkJLyogYXJiaXRyYXRpb24gbG9zdCAqLwoJCQl1ZGVsYXkoYWRhcC0+dWRlbGF5KTsKCQkJcmV0dXJuIC1FSU5UUjsKCQl9CgkJaTJjX3N0b3AoYWRhcCk7CgkJdWRlbGF5KGFkYXAtPnVkZWxheSk7Cgl9CglERUIyKGlmIChpKSBwcmludGsoS0VSTl9ERUJVRyAiaTJjLWFsZ28tcGNmLm86IG5lZWRlZCAlZCByZXRyaWVzIGZvciAlZFxuIixpLAoJICAgICAgICAgICAgICAgICAgIGFkZHIpKTsKCXJldHVybiByZXQ7Cn0KCgpzdGF0aWMgaW50IHBjZl9zZW5kYnl0ZXMoc3RydWN0IGkyY19hZGFwdGVyICppMmNfYWRhcCwgY29uc3QgY2hhciAqYnVmLAogICAgICAgICAgICAgICAgICAgICAgICAgaW50IGNvdW50LCBpbnQgbGFzdCkKewoJc3RydWN0IGkyY19hbGdvX3BjZl9kYXRhICphZGFwID0gaTJjX2FkYXAtPmFsZ29fZGF0YTsKCWludCB3cmNvdW50LCBzdGF0dXMsIHRpbWVvdXQ7CiAgICAKCWZvciAod3Jjb3VudD0wOyB3cmNvdW50PGNvdW50OyArK3dyY291bnQpIHsKCQlERUIyKGRldl9kYmcoJmkyY19hZGFwLT5kZXYsICJpMmNfd3JpdGU6IHdyaXRpbmcgJTIuMlhcbiIsCgkJCQlidWZbd3Jjb3VudF0mMHhmZikpOwoJCWkyY19vdXRiKGFkYXAsIGJ1Zlt3cmNvdW50XSk7CgkJdGltZW91dCA9IHdhaXRfZm9yX3BpbihhZGFwLCAmc3RhdHVzKTsKCQlpZiAodGltZW91dCkgewoJCQlpZiAodGltZW91dCA9PSAtRUlOVFIpIHsKCQkJCS8qIGFyYml0cmF0aW9uIGxvc3QgKi8KCQkJCXJldHVybiAtRUlOVFI7CgkJCX0KCQkJaTJjX3N0b3AoYWRhcCk7CgkJCWRldl9lcnIoJmkyY19hZGFwLT5kZXYsICJpMmNfd3JpdGU6IGVycm9yIC0gdGltZW91dC5cbiIpOwoJCQlyZXR1cm4gLUVSRU1PVEVJTzsgLyogZ290IGEgYmV0dGVyIG9uZSA/PyAqLwoJCX0KI2lmbmRlZiBTVFVCX0kyQwoJCWlmIChzdGF0dXMgJiBJMkNfUENGX0xSQikgewoJCQlpMmNfc3RvcChhZGFwKTsKCQkJZGV2X2VycigmaTJjX2FkYXAtPmRldiwgImkyY193cml0ZTogZXJyb3IgLSBubyBhY2suXG4iKTsKCQkJcmV0dXJuIC1FUkVNT1RFSU87IC8qIGdvdCBhIGJldHRlciBvbmUgPz8gKi8KCQl9CiNlbmRpZgoJfQoJaWYgKGxhc3QpIHsKCQlpMmNfc3RvcChhZGFwKTsKCX0KCWVsc2UgewoJCWkyY19yZXBzdGFydChhZGFwKTsKCX0KCglyZXR1cm4gKHdyY291bnQpOwp9CgoKc3RhdGljIGludCBwY2ZfcmVhZGJ5dGVzKHN0cnVjdCBpMmNfYWRhcHRlciAqaTJjX2FkYXAsIGNoYXIgKmJ1ZiwKICAgICAgICAgICAgICAgICAgICAgICAgIGludCBjb3VudCwgaW50IGxhc3QpCnsKCWludCBpLCBzdGF0dXM7CglzdHJ1Y3QgaTJjX2FsZ29fcGNmX2RhdGEgKmFkYXAgPSBpMmNfYWRhcC0+YWxnb19kYXRhOwoJaW50IHdmcDsKCgkvKiBpbmNyZW1lbnQgbnVtYmVyIG9mIGJ5dGVzIHRvIHJlYWQgYnkgb25lIC0tIHJlYWQgZHVtbXkgYnl0ZSAqLwoJZm9yIChpID0gMDsgaSA8PSBjb3VudDsgaSsrKSB7CgoJCWlmICgod2ZwID0gd2FpdF9mb3JfcGluKGFkYXAsICZzdGF0dXMpKSkgewoJCQlpZiAod2ZwID09IC1FSU5UUikgewoJCQkJLyogYXJiaXRyYXRpb24gbG9zdCAqLwoJCQkJcmV0dXJuIC1FSU5UUjsKCQkJfQoJCQlpMmNfc3RvcChhZGFwKTsKCQkJZGV2X2VycigmaTJjX2FkYXAtPmRldiwgInBjZl9yZWFkYnl0ZXMgdGltZWQgb3V0LlxuIik7CgkJCXJldHVybiAoLTEpOwoJCX0KCiNpZm5kZWYgU1RVQl9JMkMKCQlpZiAoKHN0YXR1cyAmIEkyQ19QQ0ZfTFJCKSAmJiAoaSAhPSBjb3VudCkpIHsKCQkJaTJjX3N0b3AoYWRhcCk7CgkJCWRldl9lcnIoJmkyY19hZGFwLT5kZXYsICJpMmNfcmVhZDogaTJjX2luYiwgTm8gYWNrLlxuIik7CgkJCXJldHVybiAoLTEpOwoJCX0KI2VuZGlmCgkJCgkJaWYgKGkgPT0gY291bnQgLSAxKSB7CgkJCXNldF9wY2YoYWRhcCwgMSwgSTJDX1BDRl9FU08pOwoJCX0gZWxzZSAKCQlpZiAoaSA9PSBjb3VudCkgewoJCQlpZiAobGFzdCkgewoJCQkJaTJjX3N0b3AoYWRhcCk7CgkJCX0gZWxzZSB7CgkJCQlpMmNfcmVwc3RhcnQoYWRhcCk7CgkJCX0KCQl9OwoKCQlpZiAoaSkgewoJCQlidWZbaSAtIDFdID0gaTJjX2luYihhZGFwKTsKCQl9IGVsc2UgewoJCQlpMmNfaW5iKGFkYXApOyAvKiBkdW1teSByZWFkICovCgkJfQoJfQoKCXJldHVybiAoaSAtIDEpOwp9CgoKc3RhdGljIGlubGluZSBpbnQgcGNmX2RvQWRkcmVzcyhzdHJ1Y3QgaTJjX2FsZ29fcGNmX2RhdGEgKmFkYXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IGkyY19tc2cgKm1zZywgaW50IHJldHJpZXMpIAp7Cgl1bnNpZ25lZCBzaG9ydCBmbGFncyA9IG1zZy0+ZmxhZ3M7Cgl1bnNpZ25lZCBjaGFyIGFkZHI7CglpbnQgcmV0OwoJaWYgKCAoZmxhZ3MgJiBJMkNfTV9URU4pICApIHsgCgkJLyogYSB0ZW4gYml0IGFkZHJlc3MgKi8KCQlhZGRyID0gMHhmMCB8ICgoIG1zZy0+YWRkciA+PiA3KSAmIDB4MDMpOwoJCURFQjIocHJpbnRrKEtFUk5fREVCVUcgImFkZHIwOiAlZFxuIixhZGRyKSk7CgkJLyogdHJ5IGV4dGVuZGVkIGFkZHJlc3MgY29kZS4uLiovCgkJcmV0ID0gdHJ5X2FkZHJlc3MoYWRhcCwgYWRkciwgcmV0cmllcyk7CgkJaWYgKHJldCE9MSkgewoJCQlwcmludGsoS0VSTl9FUlIgImRpZWQgYXQgZXh0ZW5kZWQgYWRkcmVzcyBjb2RlLlxuIik7CgkJCXJldHVybiAtRVJFTU9URUlPOwoJCX0KCQkvKiB0aGUgcmVtYWluaW5nIDggYml0IGFkZHJlc3MgKi8KCQlpMmNfb3V0YihhZGFwLG1zZy0+YWRkciAmIDB4N2YpOwovKiBTdGF0dXMgY2hlY2sgY29tZXMgaGVyZSAqLwoJCWlmIChyZXQgIT0gMSkgewoJCQlwcmludGsoS0VSTl9FUlIgImRpZWQgYXQgMm5kIGFkZHJlc3MgY29kZS5cbiIpOwoJCQlyZXR1cm4gLUVSRU1PVEVJTzsKCQl9CgkJaWYgKCBmbGFncyAmIEkyQ19NX1JEICkgewoJCQlpMmNfcmVwc3RhcnQoYWRhcCk7CgkJCS8qIG9rYXksIG5vdyBzd2l0Y2ggaW50byByZWFkaW5nIG1vZGUgKi8KCQkJYWRkciB8PSAweDAxOwoJCQlyZXQgPSB0cnlfYWRkcmVzcyhhZGFwLCBhZGRyLCByZXRyaWVzKTsKCQkJaWYgKHJldCE9MSkgewoJCQkJcHJpbnRrKEtFUk5fRVJSICJkaWVkIGF0IGV4dGVuZGVkIGFkZHJlc3MgY29kZS5cbiIpOwoJCQkJcmV0dXJuIC1FUkVNT1RFSU87CgkJCX0KCQl9Cgl9IGVsc2UgewkJLyogbm9ybWFsIDdiaXQgYWRkcmVzcwkqLwoJCWFkZHIgPSAoIG1zZy0+YWRkciA8PCAxICk7CgkJaWYgKGZsYWdzICYgSTJDX01fUkQgKQoJCQlhZGRyIHw9IDE7CgkJaWYgKGZsYWdzICYgSTJDX01fUkVWX0RJUl9BRERSICkKCQkJYWRkciBePSAxOwoJCWkyY19vdXRiKGFkYXAsIGFkZHIpOwoJfQoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcGNmX3hmZXIoc3RydWN0IGkyY19hZGFwdGVyICppMmNfYWRhcCwKCQkgICAgc3RydWN0IGkyY19tc2cgKm1zZ3MsIAoJCSAgICBpbnQgbnVtKQp7CglzdHJ1Y3QgaTJjX2FsZ29fcGNmX2RhdGEgKmFkYXAgPSBpMmNfYWRhcC0+YWxnb19kYXRhOwoJc3RydWN0IGkyY19tc2cgKnBtc2c7CglpbnQgaTsKCWludCByZXQ9MCwgdGltZW91dCwgc3RhdHVzOwogICAgCgoJLyogQ2hlY2sgZm9yIGJ1cyBidXN5ICovCgl0aW1lb3V0ID0gd2FpdF9mb3JfYmIoYWRhcCk7CglpZiAodGltZW91dCkgewoJCURFQjIocHJpbnRrKEtFUk5fRVJSICJpMmMtYWxnby1wY2YubzogIgoJCSAgICAgICAgICAgICJUaW1lb3V0IHdhaXRpbmcgZm9yIEJCIGluIHBjZl94ZmVyXG4iKTspCgkJcmV0dXJuIC1FSU87Cgl9CgkKCWZvciAoaSA9IDA7cmV0ID49IDAgJiYgaSA8IG51bTsgaSsrKSB7CgkJcG1zZyA9ICZtc2dzW2ldOwoKCQlERUIyKHByaW50ayhLRVJOX0RFQlVHICJpMmMtYWxnby1wY2YubzogRG9pbmcgJXMgJWQgYnl0ZXMgdG8gMHglMDJ4IC0gJWQgb2YgJWQgbWVzc2FnZXNcbiIsCgkJICAgICBwbXNnLT5mbGFncyAmIEkyQ19NX1JEID8gInJlYWQiIDogIndyaXRlIiwKICAgICAgICAgICAgICAgICAgICAgcG1zZy0+bGVuLCBwbXNnLT5hZGRyLCBpICsgMSwgbnVtKTspCiAgICAKCQlyZXQgPSBwY2ZfZG9BZGRyZXNzKGFkYXAsIHBtc2csIGkyY19hZGFwLT5yZXRyaWVzKTsKCgkJLyogU2VuZCBTVEFSVCAqLwoJCWlmIChpID09IDApIHsKCQkJaTJjX3N0YXJ0KGFkYXApOyAKCQl9CiAgICAKCQkvKiBXYWl0IGZvciBQSU4gKHBlbmRpbmcgaW50ZXJydXB0IE5PVCkgKi8KCQl0aW1lb3V0ID0gd2FpdF9mb3JfcGluKGFkYXAsICZzdGF0dXMpOwoJCWlmICh0aW1lb3V0KSB7CgkJCWlmICh0aW1lb3V0ID09IC1FSU5UUikgewoJCQkJLyogYXJiaXRyYXRpb24gbG9zdCAqLwoJCQkJcmV0dXJuICgtRUlOVFIpOwoJCQl9CgkJCWkyY19zdG9wKGFkYXApOwoJCQlERUIyKHByaW50ayhLRVJOX0VSUiAiaTJjLWFsZ28tcGNmLm86IFRpbWVvdXQgd2FpdGluZyAiCgkJCQkgICAgImZvciBQSU4oMSkgaW4gcGNmX3hmZXJcbiIpOykKCQkJcmV0dXJuICgtRVJFTU9URUlPKTsKCQl9CiAgICAKI2lmbmRlZiBTVFVCX0kyQwoJCS8qIENoZWNrIExSQiAobGFzdCByY3ZkIGJpdCAtIHNsYXZlIGFjaykgKi8KCQlpZiAoc3RhdHVzICYgSTJDX1BDRl9MUkIpIHsKCQkJaTJjX3N0b3AoYWRhcCk7CgkJCURFQjIocHJpbnRrKEtFUk5fRVJSICJpMmMtYWxnby1wY2YubzogTm8gTFJCKDEpIGluIHBjZl94ZmVyXG4iKTspCgkJCXJldHVybiAoLUVSRU1PVEVJTyk7CgkJfQojZW5kaWYKICAgIAoJCURFQjMocHJpbnRrKEtFUk5fREVCVUcgImkyYy1hbGdvLXBjZi5vOiBNc2cgJWQsIGFkZHI9MHgleCwgZmxhZ3M9MHgleCwgbGVuPSVkXG4iLAoJCQkgICAgaSwgbXNnc1tpXS5hZGRyLCBtc2dzW2ldLmZsYWdzLCBtc2dzW2ldLmxlbik7KQogICAgCgkJLyogUmVhZCAqLwoJCWlmIChwbXNnLT5mbGFncyAmIEkyQ19NX1JEKSB7CgkJCS8qIHJlYWQgYnl0ZXMgaW50byBidWZmZXIqLwoJCQlyZXQgPSBwY2ZfcmVhZGJ5dGVzKGkyY19hZGFwLCBwbXNnLT5idWYsIHBtc2ctPmxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaSArIDEgPT0gbnVtKSk7CiAgICAgICAgCgkJCWlmIChyZXQgIT0gcG1zZy0+bGVuKSB7CgkJCQlERUIyKHByaW50ayhLRVJOX0RFQlVHICJpMmMtYWxnby1wY2YubzogZmFpbDogIgoJCQkJCSAgICAib25seSByZWFkICVkIGJ5dGVzLlxuIixyZXQpKTsKCQkJfSBlbHNlIHsKCQkJCURFQjIocHJpbnRrKEtFUk5fREVCVUcgImkyYy1hbGdvLXBjZi5vOiByZWFkICVkIGJ5dGVzLlxuIixyZXQpKTsKCQkJfQoJCX0gZWxzZSB7IC8qIFdyaXRlICovCgkJCXJldCA9IHBjZl9zZW5kYnl0ZXMoaTJjX2FkYXAsIHBtc2ctPmJ1ZiwgcG1zZy0+bGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpICsgMSA9PSBudW0pKTsKICAgICAgICAKCQkJaWYgKHJldCAhPSBwbXNnLT5sZW4pIHsKCQkJCURFQjIocHJpbnRrKEtFUk5fREVCVUcgImkyYy1hbGdvLXBjZi5vOiBmYWlsOiAiCgkJCQkJICAgICJvbmx5IHdyb3RlICVkIGJ5dGVzLlxuIixyZXQpKTsKCQkJfSBlbHNlIHsKCQkJCURFQjIocHJpbnRrKEtFUk5fREVCVUcgImkyYy1hbGdvLXBjZi5vOiB3cm90ZSAlZCBieXRlcy5cbiIscmV0KSk7CgkJCX0KCQl9Cgl9CgoJcmV0dXJuIChpKTsKfQoKc3RhdGljIHUzMiBwY2ZfZnVuYyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXApCnsKCXJldHVybiBJMkNfRlVOQ19JMkMgfCBJMkNfRlVOQ19TTUJVU19FTVVMIHwgCgkgICAgICAgSTJDX0ZVTkNfMTBCSVRfQUREUiB8IEkyQ19GVU5DX1BST1RPQ09MX01BTkdMSU5HOyAKfQoKLyogLS0tLS1leHBvcnRlZCBhbGdvcml0aG0gZGF0YTogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQkqLwoKc3RhdGljIGNvbnN0IHN0cnVjdCBpMmNfYWxnb3JpdGhtIHBjZl9hbGdvID0gewoJLm1hc3Rlcl94ZmVyCT0gcGNmX3hmZXIsCgkuZnVuY3Rpb25hbGl0eQk9IHBjZl9mdW5jLAp9OwoKLyogCiAqIHJlZ2lzdGVyaW5nIGZ1bmN0aW9ucyB0byBsb2FkIGFsZ29yaXRobXMgYXQgcnVudGltZSAKICovCmludCBpMmNfcGNmX2FkZF9idXMoc3RydWN0IGkyY19hZGFwdGVyICphZGFwKQp7CglzdHJ1Y3QgaTJjX2FsZ29fcGNmX2RhdGEgKnBjZl9hZGFwID0gYWRhcC0+YWxnb19kYXRhOwoJaW50IHJ2YWw7CgoJREVCMihkZXZfZGJnKCZhZGFwLT5kZXYsICJodyByb3V0aW5lcyByZWdpc3RlcmVkLlxuIikpOwoKCS8qIHJlZ2lzdGVyIG5ldyBhZGFwdGVyIHRvIGkyYyBtb2R1bGUuLi4gKi8KCWFkYXAtPmFsZ28gPSAmcGNmX2FsZ287CgoJYWRhcC0+dGltZW91dCA9IDEwMDsJCS8qIGRlZmF1bHQgdmFsdWVzLCBzaG91bGQJKi8KCWFkYXAtPnJldHJpZXMgPSAzOwkJLyogYmUgcmVwbGFjZWQgYnkgZGVmaW5lcwkqLwoKCWlmICgocnZhbCA9IHBjZl9pbml0Xzg1ODQocGNmX2FkYXApKSkKCQlyZXR1cm4gcnZhbDsKCglydmFsID0gaTJjX2FkZF9hZGFwdGVyKGFkYXApOwoKCXJldHVybiBydmFsOwp9CgoKaW50IGkyY19wY2ZfZGVsX2J1cyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXApCnsKCXJldHVybiBpMmNfZGVsX2FkYXB0ZXIoYWRhcCk7Cn0KCkVYUE9SVF9TWU1CT0woaTJjX3BjZl9hZGRfYnVzKTsKRVhQT1JUX1NZTUJPTChpMmNfcGNmX2RlbF9idXMpOwoKTU9EVUxFX0FVVEhPUigiSGFucyBCZXJnbHVuZCA8aGJAc3BhY2V0ZWMubm8+Iik7Ck1PRFVMRV9ERVNDUklQVElPTigiSTJDLUJ1cyBQQ0Y4NTg0IGFsZ29yaXRobSIpOwpNT0RVTEVfTElDRU5TRSgiR1BMIik7Cgptb2R1bGVfcGFyYW0oaTJjX2RlYnVnLCBpbnQsIFNfSVJVR08gfCBTX0lXVVNSKTsKTU9EVUxFX1BBUk1fREVTQyhpMmNfZGVidWcsCiAgICAgICAgImRlYnVnIGxldmVsIC0gMCBvZmY7IDEgbm9ybWFsOyAyLDMgbW9yZSB2ZXJib3NlOyA5IHBjZi1wcm90b2NvbCIpOwo=