LyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwovKiBpMmMtYWxnby1iaXQuYyBpMmMgZHJpdmVyIGFsZ29yaXRobXMgZm9yIGJpdC1zaGlmdCBhZGFwdGVycwkJICAgICAqLwovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCi8qICAgQ29weXJpZ2h0IChDKSAxOTk1LTIwMDAgU2ltb24gRy4gVm9nbAoKICAgIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAgICBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogICAgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKICAgIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCgogICAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAgICBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogICAgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogICAgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KCiAgICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogICAgYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICAgIEZvdW5kYXRpb24sIEluYy4sIDY3NSBNYXNzIEF2ZSwgQ2FtYnJpZGdlLCBNQSAwMjEzOSwgVVNBLgkJICAgICAqLwovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKiBXaXRoIHNvbWUgY2hhbmdlcyBmcm9tIEZyb2RvIExvb2lqYWFyZCA8ZnJvZG9sQGRkcy5ubD4sIEt59nN0aSBN5Gxra2kKICAgPGttYWxra2lAY2MuaHV0LmZpPiBhbmQgSmVhbiBEZWx2YXJlIDxraGFsaUBsaW51eC1mci5vcmc+ICovCgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxsaW51eC9lcnJuby5oPgojaW5jbHVkZSA8bGludXgvc2NoZWQuaD4KI2luY2x1ZGUgPGxpbnV4L2kyYy5oPgojaW5jbHVkZSA8bGludXgvaTJjLWFsZ28tYml0Lmg+CgoKLyogLS0tLS0gZ2xvYmFsIGRlZmluZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KI2RlZmluZSBERUIoeCkgaWYgKGkyY19kZWJ1Zz49MSkgeDsKI2RlZmluZSBERUIyKHgpIGlmIChpMmNfZGVidWc+PTIpIHg7CiNkZWZpbmUgREVCU1RBVCh4KSBpZiAoaTJjX2RlYnVnPj0zKSB4OyAvKiBwcmludCBzZXZlcmFsIHN0YXRpc3RpY2FsIHZhbHVlcyovCiNkZWZpbmUgREVCUFJPVE8oeCkgaWYgKGkyY19kZWJ1Zz49OSkgeyB4OyB9CiAJLyogZGVidWcgdGhlIHByb3RvY29sIGJ5IHNob3dpbmcgdHJhbnNmZXJyZWQgYml0cyAqLwoKCi8qIC0tLS0tIGdsb2JhbCB2YXJpYWJsZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCSovCgovKiBtb2R1bGUgcGFyYW1ldGVyczoKICovCnN0YXRpYyBpbnQgaTJjX2RlYnVnOwpzdGF0aWMgaW50IGJpdF90ZXN0OwkvKiBzZWUgaWYgdGhlIGxpbmUtc2V0dGluZyBmdW5jdGlvbnMgd29yawkqLwoKLyogLS0tIHNldHRpbmcgc3RhdGVzIG9uIHRoZSBidXMgd2l0aCB0aGUgcmlnaHQgdGltaW5nOiAtLS0tLS0tLS0tLS0tLS0JKi8KCiNkZWZpbmUgc2V0c2RhKGFkYXAsdmFsKSBhZGFwLT5zZXRzZGEoYWRhcC0+ZGF0YSwgdmFsKQojZGVmaW5lIHNldHNjbChhZGFwLHZhbCkgYWRhcC0+c2V0c2NsKGFkYXAtPmRhdGEsIHZhbCkKI2RlZmluZSBnZXRzZGEoYWRhcCkgYWRhcC0+Z2V0c2RhKGFkYXAtPmRhdGEpCiNkZWZpbmUgZ2V0c2NsKGFkYXApIGFkYXAtPmdldHNjbChhZGFwLT5kYXRhKQoKc3RhdGljIGlubGluZSB2b2lkIHNkYWxvKHN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCkKewoJc2V0c2RhKGFkYXAsMCk7Cgl1ZGVsYXkoYWRhcC0+dWRlbGF5KTsKfQoKc3RhdGljIGlubGluZSB2b2lkIHNkYWhpKHN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCkKewoJc2V0c2RhKGFkYXAsMSk7Cgl1ZGVsYXkoYWRhcC0+dWRlbGF5KTsKfQoKc3RhdGljIGlubGluZSB2b2lkIHNjbGxvKHN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCkKewoJc2V0c2NsKGFkYXAsMCk7Cgl1ZGVsYXkoYWRhcC0+dWRlbGF5KTsKfQoKLyoKICogUmFpc2Ugc2NsIGxpbmUsIGFuZCBkbyBjaGVja2luZyBmb3IgZGVsYXlzLiBUaGlzIGlzIG5lY2Vzc2FyeSBmb3Igc2xvd2VyCiAqIGRldmljZXMuCiAqLwpzdGF0aWMgaW5saW5lIGludCBzY2xoaShzdHJ1Y3QgaTJjX2FsZ29fYml0X2RhdGEgKmFkYXApCnsKCXVuc2lnbmVkIGxvbmcgc3RhcnQ7CgoJc2V0c2NsKGFkYXAsMSk7CgoJLyogTm90IGFsbCBhZGFwdGVycyBoYXZlIHNjbCBzZW5zZSBsaW5lLi4uICovCglpZiAoYWRhcC0+Z2V0c2NsID09IE5VTEwgKSB7CgkJdWRlbGF5KGFkYXAtPnVkZWxheSk7CgkJcmV0dXJuIDA7Cgl9CgoJc3RhcnQ9amlmZmllczsKCXdoaWxlICghIGdldHNjbChhZGFwKSApIHsJCiAJCS8qIHRoZSBodyBrbm93cyBob3cgdG8gcmVhZCB0aGUgY2xvY2sgbGluZSwKIAkJICogc28gd2Ugd2FpdCB1bnRpbCBpdCBhY3R1YWxseSBnZXRzIGhpZ2guCiAJCSAqIFRoaXMgaXMgc2FmZXIgYXMgc29tZSBjaGlwcyBtYXkgaG9sZCBpdCBsb3cKIAkJICogd2hpbGUgdGhleSBhcmUgcHJvY2Vzc2luZyBkYXRhIGludGVybmFsbHkuIAogCQkgKi8KCQlpZiAodGltZV9hZnRlcl9lcShqaWZmaWVzLCBzdGFydCthZGFwLT50aW1lb3V0KSkgewoJCQlyZXR1cm4gLUVUSU1FRE9VVDsKCQl9CgkJY29uZF9yZXNjaGVkKCk7Cgl9CglERUJTVEFUKHByaW50ayhLRVJOX0RFQlVHICJuZWVkZWQgJWxkIGppZmZpZXNcbiIsIGppZmZpZXMtc3RhcnQpKTsKCXVkZWxheShhZGFwLT51ZGVsYXkpOwoJcmV0dXJuIDA7Cn0gCgoKLyogLS0tIG90aGVyIGF1eGlsaWFyeSBmdW5jdGlvbnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0JKi8Kc3RhdGljIHZvaWQgaTJjX3N0YXJ0KHN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCkgCnsKCS8qIGFzc2VydDogc2NsLCBzZGEgYXJlIGhpZ2ggKi8KCURFQlBST1RPKHByaW50aygiUyAiKSk7CglzZGFsbyhhZGFwKTsKCXNjbGxvKGFkYXApOwp9CgpzdGF0aWMgdm9pZCBpMmNfcmVwc3RhcnQoc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICphZGFwKSAKewoJLyogc2NsLCBzZGEgbWF5IG5vdCBiZSBoaWdoICovCglERUJQUk9UTyhwcmludGsoIiBTciAiKSk7CglzZXRzZGEoYWRhcCwxKTsKCXNjbGhpKGFkYXApOwoJdWRlbGF5KGFkYXAtPnVkZWxheSk7CgkKCXNkYWxvKGFkYXApOwoJc2NsbG8oYWRhcCk7Cn0KCgpzdGF0aWMgdm9pZCBpMmNfc3RvcChzdHJ1Y3QgaTJjX2FsZ29fYml0X2RhdGEgKmFkYXApIAp7CglERUJQUk9UTyhwcmludGsoIlBcbiIpKTsKCS8qIGFzc2VydDogc2NsIGlzIGxvdyAqLwoJc2RhbG8oYWRhcCk7CglzY2xoaShhZGFwKTsgCglzZGFoaShhZGFwKTsKfQoKCgovKiBzZW5kIGEgYnl0ZSB3aXRob3V0IHN0YXJ0IGNvbmQuLCBsb29rIGZvciBhcmJpdHJhdGlvbiwgCiAgIGNoZWNrIGFja24uIGZyb20gc2xhdmUgKi8KLyogcmV0dXJuczoKICogMSBpZiB0aGUgZGV2aWNlIGFja25vd2xlZGdlZAogKiAwIGlmIHRoZSBkZXZpY2UgZGlkIG5vdCBhY2sKICogLUVUSU1FRE9VVCBpZiBhbiBlcnJvciBvY2N1cnJlZCAod2hpbGUgcmFpc2luZyB0aGUgc2NsIGxpbmUpCiAqLwpzdGF0aWMgaW50IGkyY19vdXRiKHN0cnVjdCBpMmNfYWRhcHRlciAqaTJjX2FkYXAsIGNoYXIgYykKewoJaW50IGk7CglpbnQgc2I7CglpbnQgYWNrOwoJc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICphZGFwID0gaTJjX2FkYXAtPmFsZ29fZGF0YTsKCgkvKiBhc3NlcnQ6IHNjbCBpcyBsb3cgKi8KCWZvciAoIGk9NyA7IGk+PTAgOyBpLS0gKSB7CgkJc2IgPSBjICYgKCAxIDw8IGkgKTsKCQlzZXRzZGEoYWRhcCxzYik7CgkJdWRlbGF5KGFkYXAtPnVkZWxheSk7CgkJREVCUFJPVE8ocHJpbnRrKEtFUk5fREVCVUcgIiVkIixzYiE9MCkpOwoJCWlmIChzY2xoaShhZGFwKTwwKSB7IC8qIHRpbWVkIG91dCAqLwoJCQlzZGFoaShhZGFwKTsgLyogd2UgZG9uJ3Qgd2FudCB0byBibG9jayB0aGUgbmV0ICovCgkJCURFQjIocHJpbnRrKEtFUk5fREVCVUcgIiBpMmNfb3V0YjogMHglMDJ4LCB0aW1lb3V0IGF0IGJpdCAjJWRcbiIsIGMmMHhmZiwgaSkpOwoJCQlyZXR1cm4gLUVUSU1FRE9VVDsKCQl9OwoJCS8qIGRvIGFyYml0cmF0aW9uIGhlcmU6IAoJCSAqIGlmICggc2IgJiYgISBnZXRzZGEoYWRhcCkgKSAtPiBvdWNoISBHZXQgb3V0IG9mIGhlcmUuCgkJICovCgkJc2V0c2NsKGFkYXAsIDAgKTsKCQl1ZGVsYXkoYWRhcC0+dWRlbGF5KTsKCX0KCXNkYWhpKGFkYXApOwoJaWYgKHNjbGhpKGFkYXApPDApeyAvKiB0aW1lb3V0ICovCgkgICAgREVCMihwcmludGsoS0VSTl9ERUJVRyAiIGkyY19vdXRiOiAweCUwMngsIHRpbWVvdXQgYXQgYWNrXG4iLCBjJjB4ZmYpKTsKCSAgICByZXR1cm4gLUVUSU1FRE9VVDsKCX07CgkvKiByZWFkIGFjazogU0RBIHNob3VsZCBiZSBwdWxsZWQgZG93biBieSBzbGF2ZSAqLwoJYWNrPWdldHNkYShhZGFwKTsJLyogYWNrOiBzZGEgaXMgcHVsbGVkIGxvdyAtPnN1Y2Nlc3MuCSAqLwoJREVCMihwcmludGsoS0VSTl9ERUJVRyAiIGkyY19vdXRiOiAweCUwMnggLCBnZXRzZGEoKSA9ICVkXG4iLCBjICYgMHhmZiwgYWNrKSk7CgoJREVCUFJPVE8oIHByaW50ayhLRVJOX0RFQlVHICJbJTIuMnhdIixjJjB4ZmYpICk7CglERUJQUk9UTyhpZiAoMD09YWNrKXsgcHJpbnRrKEtFUk5fREVCVUcgIiBBICIpO30gZWxzZSBwcmludGsoS0VSTl9ERUJVRyAiIE5BICIpICk7CglzY2xsbyhhZGFwKTsKCXJldHVybiAwPT1hY2s7CQkvKiByZXR1cm4gMSBpZiBkZXZpY2UgYWNrZWQJICovCgkvKiBhc3NlcnQ6IHNjbCBpcyBsb3cgKHNkYSB1bmRlZikgKi8KfQoKCnN0YXRpYyBpbnQgaTJjX2luYihzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmkyY19hZGFwKSAKewoJLyogcmVhZCBieXRlIHZpYSBpMmMgcG9ydCwgd2l0aG91dCBzdGFydC9zdG9wIHNlcXVlbmNlCSovCgkvKiBhY2tub3dsZWRnZSBpcyBzZW50IGluIGkyY19yZWFkLgkJCSovCglpbnQgaTsKCXVuc2lnbmVkIGNoYXIgaW5kYXRhPTA7CglzdHJ1Y3QgaTJjX2FsZ29fYml0X2RhdGEgKmFkYXAgPSBpMmNfYWRhcC0+YWxnb19kYXRhOwoKCS8qIGFzc2VydDogc2NsIGlzIGxvdyAqLwoJc2RhaGkoYWRhcCk7Cglmb3IgKGk9MDtpPDg7aSsrKSB7CgkJaWYgKHNjbGhpKGFkYXApPDApIHsgLyogdGltZW91dCAqLwoJCQlERUIyKHByaW50ayhLRVJOX0RFQlVHICIgaTJjX2luYjogdGltZW91dCBhdCBiaXQgIyVkXG4iLCA3LWkpKTsKCQkJcmV0dXJuIC1FVElNRURPVVQ7CgkJfTsKCQlpbmRhdGEgKj0gMjsKCQlpZiAoIGdldHNkYShhZGFwKSApIAoJCQlpbmRhdGEgfD0gMHgwMTsKCQlzY2xsbyhhZGFwKTsKCX0KCS8qIGFzc2VydDogc2NsIGlzIGxvdyAqLwoJREVCMihwcmludGsoS0VSTl9ERUJVRyAiaTJjX2luYjogMHglMDJ4XG4iLCBpbmRhdGEgJiAweGZmKSk7CgoJREVCUFJPVE8ocHJpbnRrKEtFUk5fREVCVUcgIiAweCUwMngiLCBpbmRhdGEgJiAweGZmKSk7CglyZXR1cm4gKGludCkgKGluZGF0YSAmIDB4ZmYpOwp9CgovKgogKiBTYW5pdHkgY2hlY2sgZm9yIHRoZSBhZGFwdGVyIGhhcmR3YXJlIC0gY2hlY2sgdGhlIHJlYWN0aW9uIG9mCiAqIHRoZSBidXMgbGluZXMgb25seSBpZiBpdCBzZWVtcyB0byBiZSBpZGxlLgogKi8Kc3RhdGljIGludCB0ZXN0X2J1cyhzdHJ1Y3QgaTJjX2FsZ29fYml0X2RhdGEgKmFkYXAsIGNoYXIqIG5hbWUpIHsKCWludCBzY2wsc2RhOwoKCWlmIChhZGFwLT5nZXRzY2w9PU5VTEwpCgkJcHJpbnRrKEtFUk5fSU5GTyAiaTJjLWFsZ28tYml0Lm86IFRlc3RpbmcgU0RBIG9ubHksICIKCQkJIlNDTCBpcyBub3QgcmVhZGFibGUuXG4iKTsKCglzZGE9Z2V0c2RhKGFkYXApOwoJc2NsPShhZGFwLT5nZXRzY2w9PU5VTEw/MTpnZXRzY2woYWRhcCkpOwoJcHJpbnRrKEtFUk5fREVCVUcgImkyYy1hbGdvLWJpdC5vOiAoMCkgc2NsPSVkLCBzZGE9JWRcbiIsc2NsLHNkYSk7CglpZiAoIXNjbCB8fCAhc2RhICkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgImkyYy1hbGdvLWJpdC5vOiAlcyBzZWVtcyB0byBiZSBidXN5LlxuIiwgbmFtZSk7CgkJZ290byBiYWlsb3V0OwoJfQoKCXNkYWxvKGFkYXApOwoJc2RhPWdldHNkYShhZGFwKTsKCXNjbD0oYWRhcC0+Z2V0c2NsPT1OVUxMPzE6Z2V0c2NsKGFkYXApKTsKCXByaW50ayhLRVJOX0RFQlVHICJpMmMtYWxnby1iaXQubzogKDEpIHNjbD0lZCwgc2RhPSVkXG4iLHNjbCxzZGEpOwoJaWYgKCAwICE9IHNkYSApIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJpMmMtYWxnby1iaXQubzogU0RBIHN0dWNrIGhpZ2ghXG4iKTsKCQlnb3RvIGJhaWxvdXQ7Cgl9CglpZiAoIDAgPT0gc2NsICkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgImkyYy1hbGdvLWJpdC5vOiBTQ0wgdW5leHBlY3RlZCBsb3cgIgoJCQkid2hpbGUgcHVsbGluZyBTREEgbG93IVxuIik7CgkJZ290byBiYWlsb3V0OwoJfQkJCgoJc2RhaGkoYWRhcCk7CglzZGE9Z2V0c2RhKGFkYXApOwoJc2NsPShhZGFwLT5nZXRzY2w9PU5VTEw/MTpnZXRzY2woYWRhcCkpOwoJcHJpbnRrKEtFUk5fREVCVUcgImkyYy1hbGdvLWJpdC5vOiAoMikgc2NsPSVkLCBzZGE9JWRcbiIsc2NsLHNkYSk7CglpZiAoIDAgPT0gc2RhICkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgImkyYy1hbGdvLWJpdC5vOiBTREEgc3R1Y2sgbG93IVxuIik7CgkJZ290byBiYWlsb3V0OwoJfQoJaWYgKCAwID09IHNjbCApIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJpMmMtYWxnby1iaXQubzogU0NMIHVuZXhwZWN0ZWQgbG93ICIKCQkJIndoaWxlIHB1bGxpbmcgU0RBIGhpZ2ghXG4iKTsKCQlnb3RvIGJhaWxvdXQ7Cgl9CgoJc2NsbG8oYWRhcCk7CglzZGE9Z2V0c2RhKGFkYXApOwoJc2NsPShhZGFwLT5nZXRzY2w9PU5VTEw/MDpnZXRzY2woYWRhcCkpOwoJcHJpbnRrKEtFUk5fREVCVUcgImkyYy1hbGdvLWJpdC5vOiAoMykgc2NsPSVkLCBzZGE9JWRcbiIsc2NsLHNkYSk7CglpZiAoIDAgIT0gc2NsICkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgImkyYy1hbGdvLWJpdC5vOiBTQ0wgc3R1Y2sgaGlnaCFcbiIpOwoJCWdvdG8gYmFpbG91dDsKCX0KCWlmICggMCA9PSBzZGEgKSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORyAiaTJjLWFsZ28tYml0Lm86IFNEQSB1bmV4cGVjdGVkIGxvdyAiCgkJCSJ3aGlsZSBwdWxsaW5nIFNDTCBsb3chXG4iKTsKCQlnb3RvIGJhaWxvdXQ7Cgl9CgkKCXNjbGhpKGFkYXApOwoJc2RhPWdldHNkYShhZGFwKTsKCXNjbD0oYWRhcC0+Z2V0c2NsPT1OVUxMPzE6Z2V0c2NsKGFkYXApKTsKCXByaW50ayhLRVJOX0RFQlVHICJpMmMtYWxnby1iaXQubzogKDQpIHNjbD0lZCwgc2RhPSVkXG4iLHNjbCxzZGEpOwoJaWYgKCAwID09IHNjbCApIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJpMmMtYWxnby1iaXQubzogU0NMIHN0dWNrIGxvdyFcbiIpOwoJCWdvdG8gYmFpbG91dDsKCX0KCWlmICggMCA9PSBzZGEgKSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORyAiaTJjLWFsZ28tYml0Lm86IFNEQSB1bmV4cGVjdGVkIGxvdyAiCgkJCSJ3aGlsZSBwdWxsaW5nIFNDTCBoaWdoIVxuIik7CgkJZ290byBiYWlsb3V0OwoJfQoJcHJpbnRrKEtFUk5fSU5GTyAiaTJjLWFsZ28tYml0Lm86ICVzIHBhc3NlZCB0ZXN0LlxuIixuYW1lKTsKCXJldHVybiAwOwpiYWlsb3V0OgoJc2RhaGkoYWRhcCk7CglzY2xoaShhZGFwKTsKCXJldHVybiAtRU5PREVWOwp9CgovKiAtLS0tLSBVdGlsaXR5IGZ1bmN0aW9ucwogKi8KCi8qIHRyeV9hZGRyZXNzIHRyaWVzIHRvIGNvbnRhY3QgYSBjaGlwIGZvciBhIG51bWJlciBvZgogKiB0aW1lcyBiZWZvcmUgaXQgZ2l2ZXMgdXAuCiAqIHJldHVybiB2YWx1ZXM6CiAqIDEgY2hpcCBhbnN3ZXJlZAogKiAwIGNoaXAgZGlkIG5vdCBhbnN3ZXIKICogLXggdHJhbnNtaXNzaW9uIGVycm9yCiAqLwpzdGF0aWMgaW5saW5lIGludCB0cnlfYWRkcmVzcyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmkyY19hZGFwLAoJCSAgICAgICB1bnNpZ25lZCBjaGFyIGFkZHIsIGludCByZXRyaWVzKQp7CglzdHJ1Y3QgaTJjX2FsZ29fYml0X2RhdGEgKmFkYXAgPSBpMmNfYWRhcC0+YWxnb19kYXRhOwoJaW50IGkscmV0ID0gLTE7Cglmb3IgKGk9MDtpPD1yZXRyaWVzO2krKykgewoJCXJldCA9IGkyY19vdXRiKGkyY19hZGFwLGFkZHIpOwoJCWlmIChyZXQ9PTEpCgkJCWJyZWFrOwkvKiBzdWNjZXNzISAqLwoJCWkyY19zdG9wKGFkYXApOwoJCXVkZWxheSg1LyphZGFwLT51ZGVsYXkqLyk7CgkJaWYgKGk9PXJldHJpZXMpICAvKiBubyBzdWNjZXNzICovCgkJCWJyZWFrOwoJCWkyY19zdGFydChhZGFwKTsKCQl1ZGVsYXkoYWRhcC0+dWRlbGF5KTsKCX0KCURFQjIoaWYgKGkpCgkgICAgIHByaW50ayhLRVJOX0RFQlVHICJpMmMtYWxnby1iaXQubzogVXNlZCAlZCB0cmllcyB0byAlcyBjbGllbnQgYXQgMHglMDJ4IDogJXNcbiIsCgkJICAgIGkrMSwgYWRkciAmIDEgPyAicmVhZCIgOiAid3JpdGUiLCBhZGRyPj4xLAoJCSAgICByZXQ9PTEgPyAic3VjY2VzcyIgOiByZXQ9PTAgPyAibm8gYWNrIiA6ICJmYWlsZWQsIHRpbWVvdXQ/IiApCgkgICAgKTsKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBpbnQgc2VuZGJ5dGVzKHN0cnVjdCBpMmNfYWRhcHRlciAqaTJjX2FkYXAsIHN0cnVjdCBpMmNfbXNnICptc2cpCnsKCXN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCA9IGkyY19hZGFwLT5hbGdvX2RhdGE7CgljaGFyIGM7Cgljb25zdCBjaGFyICp0ZW1wID0gbXNnLT5idWY7CglpbnQgY291bnQgPSBtc2ctPmxlbjsKCXVuc2lnbmVkIHNob3J0IG5ha19vayA9IG1zZy0+ZmxhZ3MgJiBJMkNfTV9JR05PUkVfTkFLOyAKCWludCByZXR2YWw7CglpbnQgd3Jjb3VudD0wOwoKCXdoaWxlIChjb3VudCA+IDApIHsKCQljID0gKnRlbXA7CgkJREVCMihkZXZfZGJnKCZpMmNfYWRhcC0+ZGV2LCAic2VuZGJ5dGVzOiB3cml0aW5nICUyLjJYXG4iLCBjJjB4ZmYpKTsKCQlyZXR2YWwgPSBpMmNfb3V0YihpMmNfYWRhcCxjKTsKCQlpZiAoKHJldHZhbD4wKSB8fCAobmFrX29rICYmIChyZXR2YWw9PTApKSkgIHsgLyogb2sgb3IgaWdub3JlZCBOQUsgKi8KCQkJY291bnQtLTsgCgkJCXRlbXArKzsKCQkJd3Jjb3VudCsrOwoJCX0gZWxzZSB7IC8qIGFyYml0cmF0aW9uIG9yIG5vIGFja25vd2xlZGdlICovCgkJCWRldl9lcnIoJmkyY19hZGFwLT5kZXYsICJzZW5kYnl0ZXM6IGVycm9yIC0gYmFpbG91dC5cbiIpOwoJCQlpMmNfc3RvcChhZGFwKTsKCQkJcmV0dXJuIChyZXR2YWw8MCk/IHJldHZhbCA6IC1FRkFVTFQ7CgkJCSAgICAgICAgLyogZ290IGEgYmV0dGVyIG9uZSA/PyAqLwoJCX0KCX0KCXJldHVybiB3cmNvdW50Owp9CgpzdGF0aWMgaW5saW5lIGludCByZWFkYnl0ZXMoc3RydWN0IGkyY19hZGFwdGVyICppMmNfYWRhcCwgc3RydWN0IGkyY19tc2cgKm1zZykKewoJaW50IGludmFsOwoJaW50IHJkY291bnQ9MDsgICAJLyogY291bnRzIGJ5dGVzIHJlYWQgKi8KCXN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCA9IGkyY19hZGFwLT5hbGdvX2RhdGE7CgljaGFyICp0ZW1wID0gbXNnLT5idWY7CglpbnQgY291bnQgPSBtc2ctPmxlbjsKCgl3aGlsZSAoY291bnQgPiAwKSB7CgkJaW52YWwgPSBpMmNfaW5iKGkyY19hZGFwKTsKCQlpZiAoaW52YWw+PTApIHsKCQkJKnRlbXAgPSBpbnZhbDsKCQkJcmRjb3VudCsrOwoJCX0gZWxzZSB7ICAgLyogcmVhZCB0aW1lZCBvdXQgKi8KCQkJcHJpbnRrKEtFUk5fRVJSICJpMmMtYWxnby1iaXQubzogcmVhZGJ5dGVzOiBpMmNfaW5iIHRpbWVkIG91dC5cbiIpOwoJCQlicmVhazsKCQl9CgoJCXRlbXArKzsKCQljb3VudC0tOwoKCQlpZiAobXNnLT5mbGFncyAmIEkyQ19NX05PX1JEX0FDSykKCQkJY29udGludWU7CgoJCWlmICggY291bnQgPiAwICkgewkJLyogc2VuZCBhY2sgKi8KCQkJc2RhbG8oYWRhcCk7CgkJCURFQlBST1RPKHByaW50aygiIEFtICIpKTsKCQl9IGVsc2UgewoJCQlzZGFoaShhZGFwKTsJLyogbmVnLiBhY2sgb24gbGFzdCBieXRlICovCgkJCURFQlBST1RPKHByaW50aygiIE5BbSAiKSk7CgkJfQoJCWlmIChzY2xoaShhZGFwKTwwKSB7CS8qIHRpbWVvdXQgKi8KCQkJc2RhaGkoYWRhcCk7CgkJCXByaW50ayhLRVJOX0VSUiAiaTJjLWFsZ28tYml0Lm86IHJlYWRieXRlczogVGltZW91dCBhdCBhY2tcbiIpOwoJCQlyZXR1cm4gLUVUSU1FRE9VVDsKCQl9OwoJCXNjbGxvKGFkYXApOwoJCXNkYWhpKGFkYXApOwoJfQoJcmV0dXJuIHJkY291bnQ7Cn0KCi8qIGRvQWRkcmVzcyBpbml0aWF0ZXMgdGhlIHRyYW5zZmVyIGJ5IGdlbmVyYXRpbmcgdGhlIHN0YXJ0IGNvbmRpdGlvbiAoaW4KICogdHJ5X2FkZHJlc3MpIGFuZCB0cmFuc21pdHMgdGhlIGFkZHJlc3MgaW4gdGhlIG5lY2Vzc2FyeSBmb3JtYXQgdG8gaGFuZGxlCiAqIHJlYWRzLCB3cml0ZXMgYXMgd2VsbCBhcyAxMGJpdC1hZGRyZXNzZXMuCiAqIHJldHVybnM6CiAqICAwIGV2ZXJ5dGhpbmcgd2VudCBva2F5LCB0aGUgY2hpcCBhY2snZWQsIG9yIElHTk9SRV9OQUsgZmxhZyB3YXMgc2V0CiAqIC14IGFuIGVycm9yIG9jY3VycmVkIChsaWtlOiAtRVJFTU9URUlPIGlmIHRoZSBkZXZpY2UgZGlkIG5vdCBhbnN3ZXIsIG9yCiAqCS1FVElNRURPVVQsIGZvciBleGFtcGxlIGlmIHRoZSBsaW5lcyBhcmUgc3R1Y2suLi4pIAogKi8Kc3RhdGljIGlubGluZSBpbnQgYml0X2RvQWRkcmVzcyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmkyY19hZGFwLCBzdHJ1Y3QgaTJjX21zZyAqbXNnKSAKewoJdW5zaWduZWQgc2hvcnQgZmxhZ3MgPSBtc2ctPmZsYWdzOwoJdW5zaWduZWQgc2hvcnQgbmFrX29rID0gbXNnLT5mbGFncyAmIEkyQ19NX0lHTk9SRV9OQUs7CglzdHJ1Y3QgaTJjX2FsZ29fYml0X2RhdGEgKmFkYXAgPSBpMmNfYWRhcC0+YWxnb19kYXRhOwoKCXVuc2lnbmVkIGNoYXIgYWRkcjsKCWludCByZXQsIHJldHJpZXM7CgoJcmV0cmllcyA9IG5ha19vayA/IDAgOiBpMmNfYWRhcC0+cmV0cmllczsKCQoJaWYgKCAoZmxhZ3MgJiBJMkNfTV9URU4pICApIHsgCgkJLyogYSB0ZW4gYml0IGFkZHJlc3MgKi8KCQlhZGRyID0gMHhmMCB8ICgoIG1zZy0+YWRkciA+PiA3KSAmIDB4MDMpOwoJCURFQjIocHJpbnRrKEtFUk5fREVCVUcgImFkZHIwOiAlZFxuIixhZGRyKSk7CgkJLyogdHJ5IGV4dGVuZGVkIGFkZHJlc3MgY29kZS4uLiovCgkJcmV0ID0gdHJ5X2FkZHJlc3MoaTJjX2FkYXAsIGFkZHIsIHJldHJpZXMpOwoJCWlmICgocmV0ICE9IDEpICYmICFuYWtfb2spICB7CgkJCXByaW50ayhLRVJOX0VSUiAiZGllZCBhdCBleHRlbmRlZCBhZGRyZXNzIGNvZGUuXG4iKTsKCQkJcmV0dXJuIC1FUkVNT1RFSU87CgkJfQoJCS8qIHRoZSByZW1haW5pbmcgOCBiaXQgYWRkcmVzcyAqLwoJCXJldCA9IGkyY19vdXRiKGkyY19hZGFwLG1zZy0+YWRkciAmIDB4N2YpOwoJCWlmICgocmV0ICE9IDEpICYmICFuYWtfb2spIHsKCQkJLyogdGhlIGNoaXAgZGlkIG5vdCBhY2sgLyB4bWlzc2lvbiBlcnJvciBvY2N1cnJlZCAqLwoJCQlwcmludGsoS0VSTl9FUlIgImRpZWQgYXQgMm5kIGFkZHJlc3MgY29kZS5cbiIpOwoJCQlyZXR1cm4gLUVSRU1PVEVJTzsKCQl9CgkJaWYgKCBmbGFncyAmIEkyQ19NX1JEICkgewoJCQlpMmNfcmVwc3RhcnQoYWRhcCk7CgkJCS8qIG9rYXksIG5vdyBzd2l0Y2ggaW50byByZWFkaW5nIG1vZGUgKi8KCQkJYWRkciB8PSAweDAxOwoJCQlyZXQgPSB0cnlfYWRkcmVzcyhpMmNfYWRhcCwgYWRkciwgcmV0cmllcyk7CgkJCWlmICgocmV0IT0xKSAmJiAhbmFrX29rKSB7CgkJCQlwcmludGsoS0VSTl9FUlIgImRpZWQgYXQgZXh0ZW5kZWQgYWRkcmVzcyBjb2RlLlxuIik7CgkJCQlyZXR1cm4gLUVSRU1PVEVJTzsKCQkJfQoJCX0KCX0gZWxzZSB7CQkvKiBub3JtYWwgN2JpdCBhZGRyZXNzCSovCgkJYWRkciA9ICggbXNnLT5hZGRyIDw8IDEgKTsKCQlpZiAoZmxhZ3MgJiBJMkNfTV9SRCApCgkJCWFkZHIgfD0gMTsKCQlpZiAoZmxhZ3MgJiBJMkNfTV9SRVZfRElSX0FERFIgKQoJCQlhZGRyIF49IDE7CgkJcmV0ID0gdHJ5X2FkZHJlc3MoaTJjX2FkYXAsIGFkZHIsIHJldHJpZXMpOwoJCWlmICgocmV0IT0xKSAmJiAhbmFrX29rKQoJCQlyZXR1cm4gLUVSRU1PVEVJTzsKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBiaXRfeGZlcihzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmkyY19hZGFwLAoJCSAgICBzdHJ1Y3QgaTJjX21zZyBtc2dzW10sIGludCBudW0pCnsKCXN0cnVjdCBpMmNfbXNnICpwbXNnOwoJc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICphZGFwID0gaTJjX2FkYXAtPmFsZ29fZGF0YTsKCQoJaW50IGkscmV0OwoJdW5zaWduZWQgc2hvcnQgbmFrX29rOwoKCWkyY19zdGFydChhZGFwKTsKCWZvciAoaT0wO2k8bnVtO2krKykgewoJCXBtc2cgPSAmbXNnc1tpXTsKCQluYWtfb2sgPSBwbXNnLT5mbGFncyAmIEkyQ19NX0lHTk9SRV9OQUs7IAoJCWlmICghKHBtc2ctPmZsYWdzICYgSTJDX01fTk9TVEFSVCkpIHsKCQkJaWYgKGkpIHsKCQkJCWkyY19yZXBzdGFydChhZGFwKTsKCQkJfQoJCQlyZXQgPSBiaXRfZG9BZGRyZXNzKGkyY19hZGFwLCBwbXNnKTsKCQkJaWYgKChyZXQgIT0gMCkgJiYgIW5ha19vaykgewoJCQkgICAgREVCMihwcmludGsoS0VSTl9ERUJVRyAiaTJjLWFsZ28tYml0Lm86IE5BSyBmcm9tIGRldmljZSBhZGRyICUyLjJ4IG1zZyAjJWRcbiIKCQkJCQksbXNnc1tpXS5hZGRyLGkpKTsKCQkJICAgIHJldHVybiAocmV0PDApID8gcmV0IDogLUVSRU1PVEVJTzsKCQkJfQoJCX0KCQlpZiAocG1zZy0+ZmxhZ3MgJiBJMkNfTV9SRCApIHsKCQkJLyogcmVhZCBieXRlcyBpbnRvIGJ1ZmZlciovCgkJCXJldCA9IHJlYWRieXRlcyhpMmNfYWRhcCwgcG1zZyk7CgkJCURFQjIocHJpbnRrKEtFUk5fREVCVUcgImkyYy1hbGdvLWJpdC5vOiByZWFkICVkIGJ5dGVzLlxuIixyZXQpKTsKCQkJaWYgKHJldCA8IHBtc2ctPmxlbiApIHsKCQkJCXJldHVybiAocmV0PDApPyByZXQgOiAtRVJFTU9URUlPOwoJCQl9CgkJfSBlbHNlIHsKCQkJLyogd3JpdGUgYnl0ZXMgZnJvbSBidWZmZXIgKi8KCQkJcmV0ID0gc2VuZGJ5dGVzKGkyY19hZGFwLCBwbXNnKTsKCQkJREVCMihwcmludGsoS0VSTl9ERUJVRyAiaTJjLWFsZ28tYml0Lm86IHdyb3RlICVkIGJ5dGVzLlxuIixyZXQpKTsKCQkJaWYgKHJldCA8IHBtc2ctPmxlbiApIHsKCQkJCXJldHVybiAocmV0PDApID8gcmV0IDogLUVSRU1PVEVJTzsKCQkJfQoJCX0KCX0KCWkyY19zdG9wKGFkYXApOwoJcmV0dXJuIG51bTsKfQoKc3RhdGljIHUzMiBiaXRfZnVuYyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXApCnsKCXJldHVybiBJMkNfRlVOQ19JMkMgfCBJMkNfRlVOQ19TTUJVU19FTVVMIHwgCgkgICAgICAgSTJDX0ZVTkNfMTBCSVRfQUREUiB8IEkyQ19GVU5DX1BST1RPQ09MX01BTkdMSU5HOwp9CgoKLyogLS0tLS1leHBvcnRlZCBhbGdvcml0aG0gZGF0YTogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQkqLwoKc3RhdGljIHN0cnVjdCBpMmNfYWxnb3JpdGhtIGkyY19iaXRfYWxnbyA9IHsKCS5tYXN0ZXJfeGZlcgk9IGJpdF94ZmVyLAoJLmZ1bmN0aW9uYWxpdHkJPSBiaXRfZnVuYywKfTsKCi8qIAogKiByZWdpc3RlcmluZyBmdW5jdGlvbnMgdG8gbG9hZCBhbGdvcml0aG1zIGF0IHJ1bnRpbWUgCiAqLwppbnQgaTJjX2JpdF9hZGRfYnVzKHN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcCkKewoJc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICpiaXRfYWRhcCA9IGFkYXAtPmFsZ29fZGF0YTsKCglpZiAoYml0X3Rlc3QpIHsKCQlpbnQgcmV0ID0gdGVzdF9idXMoYml0X2FkYXAsIGFkYXAtPm5hbWUpOwoJCWlmIChyZXQ8MCkKCQkJcmV0dXJuIC1FTk9ERVY7Cgl9CgoJREVCMihkZXZfZGJnKCZhZGFwLT5kZXYsICJodyByb3V0aW5lcyByZWdpc3RlcmVkLlxuIikpOwoKCS8qIHJlZ2lzdGVyIG5ldyBhZGFwdGVyIHRvIGkyYyBtb2R1bGUuLi4gKi8KCWFkYXAtPmFsZ28gPSAmaTJjX2JpdF9hbGdvOwoKCWFkYXAtPnRpbWVvdXQgPSAxMDA7CS8qIGRlZmF1bHQgdmFsdWVzLCBzaG91bGQJKi8KCWFkYXAtPnJldHJpZXMgPSAzOwkvKiBiZSByZXBsYWNlZCBieSBkZWZpbmVzCSovCgoJcmV0dXJuIGkyY19hZGRfYWRhcHRlcihhZGFwKTsKfQoKCmludCBpMmNfYml0X2RlbF9idXMoc3RydWN0IGkyY19hZGFwdGVyICphZGFwKQp7CglyZXR1cm4gaTJjX2RlbF9hZGFwdGVyKGFkYXApOwp9CgpFWFBPUlRfU1lNQk9MKGkyY19iaXRfYWRkX2J1cyk7CkVYUE9SVF9TWU1CT0woaTJjX2JpdF9kZWxfYnVzKTsKCk1PRFVMRV9BVVRIT1IoIlNpbW9uIEcuIFZvZ2wgPHNpbW9uQHRrLnVuaS1saW56LmFjLmF0PiIpOwpNT0RVTEVfREVTQ1JJUFRJT04oIkkyQy1CdXMgYml0LWJhbmdpbmcgYWxnb3JpdGhtIik7Ck1PRFVMRV9MSUNFTlNFKCJHUEwiKTsKCm1vZHVsZV9wYXJhbShiaXRfdGVzdCwgYm9vbCwgMCk7Cm1vZHVsZV9wYXJhbShpMmNfZGVidWcsIGludCwgU19JUlVHTyB8IFNfSVdVU1IpOwoKTU9EVUxFX1BBUk1fREVTQyhiaXRfdGVzdCwgIlRlc3QgdGhlIGxpbmVzIG9mIHRoZSBidXMgdG8gc2VlIGlmIGl0IGlzIHN0dWNrIik7Ck1PRFVMRV9QQVJNX0RFU0MoaTJjX2RlYnVnLAoJCSAiZGVidWcgbGV2ZWwgLSAwIG9mZjsgMSBub3JtYWw7IDIsMyBtb3JlIHZlcmJvc2U7IDkgYml0LXByb3RvY29sIik7Cg==