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/PyAqLwoJCX0KI2lmIDAKCQkvKiBmcm9tIGFzbS9kZWxheS5oICovCgkJX19kZWxheShhZGFwLT5tZGVsYXkgKiAobG9vcHNfcGVyX3NlYyAvIDEwMDApICk7CiNlbmRpZgoJfQoJcmV0dXJuIHdyY291bnQ7Cn0KCnN0YXRpYyBpbmxpbmUgaW50IHJlYWRieXRlcyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmkyY19hZGFwLCBzdHJ1Y3QgaTJjX21zZyAqbXNnKQp7CglpbnQgaW52YWw7CglpbnQgcmRjb3VudD0wOyAgIAkvKiBjb3VudHMgYnl0ZXMgcmVhZCAqLwoJc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICphZGFwID0gaTJjX2FkYXAtPmFsZ29fZGF0YTsKCWNoYXIgKnRlbXAgPSBtc2ctPmJ1ZjsKCWludCBjb3VudCA9IG1zZy0+bGVuOwoKCXdoaWxlIChjb3VudCA+IDApIHsKCQlpbnZhbCA9IGkyY19pbmIoaTJjX2FkYXApOwovKnByaW50aygiJSMwMnggIixpbnZhbCk7IGlmICggISAoY291bnQgJSAxNikgKSBwcmludGsoIlxuIik7ICovCgkJaWYgKGludmFsPj0wKSB7CgkJCSp0ZW1wID0gaW52YWw7CgkJCXJkY291bnQrKzsKCQl9IGVsc2UgeyAgIC8qIHJlYWQgdGltZWQgb3V0ICovCgkJCXByaW50ayhLRVJOX0VSUiAiaTJjLWFsZ28tYml0Lm86IHJlYWRieXRlczogaTJjX2luYiB0aW1lZCBvdXQuXG4iKTsKCQkJYnJlYWs7CgkJfQoKCQl0ZW1wKys7CgkJY291bnQtLTsKCgkJaWYgKG1zZy0+ZmxhZ3MgJiBJMkNfTV9OT19SRF9BQ0spCgkJCWNvbnRpbnVlOwoKCQlpZiAoIGNvdW50ID4gMCApIHsJCS8qIHNlbmQgYWNrICovCgkJCXNkYWxvKGFkYXApOwoJCQlERUJQUk9UTyhwcmludGsoIiBBbSAiKSk7CgkJfSBlbHNlIHsKCQkJc2RhaGkoYWRhcCk7CS8qIG5lZy4gYWNrIG9uIGxhc3QgYnl0ZSAqLwoJCQlERUJQUk9UTyhwcmludGsoIiBOQW0gIikpOwoJCX0KCQlpZiAoc2NsaGkoYWRhcCk8MCkgewkvKiB0aW1lb3V0ICovCgkJCXNkYWhpKGFkYXApOwoJCQlwcmludGsoS0VSTl9FUlIgImkyYy1hbGdvLWJpdC5vOiByZWFkYnl0ZXM6IFRpbWVvdXQgYXQgYWNrXG4iKTsKCQkJcmV0dXJuIC1FVElNRURPVVQ7CgkJfTsKCQlzY2xsbyhhZGFwKTsKCQlzZGFoaShhZGFwKTsKCX0KCXJldHVybiByZGNvdW50Owp9CgovKiBkb0FkZHJlc3MgaW5pdGlhdGVzIHRoZSB0cmFuc2ZlciBieSBnZW5lcmF0aW5nIHRoZSBzdGFydCBjb25kaXRpb24gKGluCiAqIHRyeV9hZGRyZXNzKSBhbmQgdHJhbnNtaXRzIHRoZSBhZGRyZXNzIGluIHRoZSBuZWNlc3NhcnkgZm9ybWF0IHRvIGhhbmRsZQogKiByZWFkcywgd3JpdGVzIGFzIHdlbGwgYXMgMTBiaXQtYWRkcmVzc2VzLgogKiByZXR1cm5zOgogKiAgMCBldmVyeXRoaW5nIHdlbnQgb2theSwgdGhlIGNoaXAgYWNrJ2VkLCBvciBJR05PUkVfTkFLIGZsYWcgd2FzIHNldAogKiAteCBhbiBlcnJvciBvY2N1cnJlZCAobGlrZTogLUVSRU1PVEVJTyBpZiB0aGUgZGV2aWNlIGRpZCBub3QgYW5zd2VyLCBvcgogKgktRVRJTUVET1VULCBmb3IgZXhhbXBsZSBpZiB0aGUgbGluZXMgYXJlIHN0dWNrLi4uKSAKICovCnN0YXRpYyBpbmxpbmUgaW50IGJpdF9kb0FkZHJlc3Moc3RydWN0IGkyY19hZGFwdGVyICppMmNfYWRhcCwgc3RydWN0IGkyY19tc2cgKm1zZykgCnsKCXVuc2lnbmVkIHNob3J0IGZsYWdzID0gbXNnLT5mbGFnczsKCXVuc2lnbmVkIHNob3J0IG5ha19vayA9IG1zZy0+ZmxhZ3MgJiBJMkNfTV9JR05PUkVfTkFLOwoJc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICphZGFwID0gaTJjX2FkYXAtPmFsZ29fZGF0YTsKCgl1bnNpZ25lZCBjaGFyIGFkZHI7CglpbnQgcmV0LCByZXRyaWVzOwoKCXJldHJpZXMgPSBuYWtfb2sgPyAwIDogaTJjX2FkYXAtPnJldHJpZXM7CgkKCWlmICggKGZsYWdzICYgSTJDX01fVEVOKSAgKSB7IAoJCS8qIGEgdGVuIGJpdCBhZGRyZXNzICovCgkJYWRkciA9IDB4ZjAgfCAoKCBtc2ctPmFkZHIgPj4gNykgJiAweDAzKTsKCQlERUIyKHByaW50ayhLRVJOX0RFQlVHICJhZGRyMDogJWRcbiIsYWRkcikpOwoJCS8qIHRyeSBleHRlbmRlZCBhZGRyZXNzIGNvZGUuLi4qLwoJCXJldCA9IHRyeV9hZGRyZXNzKGkyY19hZGFwLCBhZGRyLCByZXRyaWVzKTsKCQlpZiAoKHJldCAhPSAxKSAmJiAhbmFrX29rKSAgewoJCQlwcmludGsoS0VSTl9FUlIgImRpZWQgYXQgZXh0ZW5kZWQgYWRkcmVzcyBjb2RlLlxuIik7CgkJCXJldHVybiAtRVJFTU9URUlPOwoJCX0KCQkvKiB0aGUgcmVtYWluaW5nIDggYml0IGFkZHJlc3MgKi8KCQlyZXQgPSBpMmNfb3V0YihpMmNfYWRhcCxtc2ctPmFkZHIgJiAweDdmKTsKCQlpZiAoKHJldCAhPSAxKSAmJiAhbmFrX29rKSB7CgkJCS8qIHRoZSBjaGlwIGRpZCBub3QgYWNrIC8geG1pc3Npb24gZXJyb3Igb2NjdXJyZWQgKi8KCQkJcHJpbnRrKEtFUk5fRVJSICJkaWVkIGF0IDJuZCBhZGRyZXNzIGNvZGUuXG4iKTsKCQkJcmV0dXJuIC1FUkVNT1RFSU87CgkJfQoJCWlmICggZmxhZ3MgJiBJMkNfTV9SRCApIHsKCQkJaTJjX3JlcHN0YXJ0KGFkYXApOwoJCQkvKiBva2F5LCBub3cgc3dpdGNoIGludG8gcmVhZGluZyBtb2RlICovCgkJCWFkZHIgfD0gMHgwMTsKCQkJcmV0ID0gdHJ5X2FkZHJlc3MoaTJjX2FkYXAsIGFkZHIsIHJldHJpZXMpOwoJCQlpZiAoKHJldCE9MSkgJiYgIW5ha19vaykgewoJCQkJcHJpbnRrKEtFUk5fRVJSICJkaWVkIGF0IGV4dGVuZGVkIGFkZHJlc3MgY29kZS5cbiIpOwoJCQkJcmV0dXJuIC1FUkVNT1RFSU87CgkJCX0KCQl9Cgl9IGVsc2UgewkJLyogbm9ybWFsIDdiaXQgYWRkcmVzcwkqLwoJCWFkZHIgPSAoIG1zZy0+YWRkciA8PCAxICk7CgkJaWYgKGZsYWdzICYgSTJDX01fUkQgKQoJCQlhZGRyIHw9IDE7CgkJaWYgKGZsYWdzICYgSTJDX01fUkVWX0RJUl9BRERSICkKCQkJYWRkciBePSAxOwoJCXJldCA9IHRyeV9hZGRyZXNzKGkyY19hZGFwLCBhZGRyLCByZXRyaWVzKTsKCQlpZiAoKHJldCE9MSkgJiYgIW5ha19vaykKCQkJcmV0dXJuIC1FUkVNT1RFSU87Cgl9CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgYml0X3hmZXIoc3RydWN0IGkyY19hZGFwdGVyICppMmNfYWRhcCwKCQkgICAgc3RydWN0IGkyY19tc2cgbXNnc1tdLCBpbnQgbnVtKQp7CglzdHJ1Y3QgaTJjX21zZyAqcG1zZzsKCXN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCA9IGkyY19hZGFwLT5hbGdvX2RhdGE7CgkKCWludCBpLHJldDsKCXVuc2lnbmVkIHNob3J0IG5ha19vazsKCglpMmNfc3RhcnQoYWRhcCk7Cglmb3IgKGk9MDtpPG51bTtpKyspIHsKCQlwbXNnID0gJm1zZ3NbaV07CgkJbmFrX29rID0gcG1zZy0+ZmxhZ3MgJiBJMkNfTV9JR05PUkVfTkFLOyAKCQlpZiAoIShwbXNnLT5mbGFncyAmIEkyQ19NX05PU1RBUlQpKSB7CgkJCWlmIChpKSB7CgkJCQlpMmNfcmVwc3RhcnQoYWRhcCk7CgkJCX0KCQkJcmV0ID0gYml0X2RvQWRkcmVzcyhpMmNfYWRhcCwgcG1zZyk7CgkJCWlmICgocmV0ICE9IDApICYmICFuYWtfb2spIHsKCQkJICAgIERFQjIocHJpbnRrKEtFUk5fREVCVUcgImkyYy1hbGdvLWJpdC5vOiBOQUsgZnJvbSBkZXZpY2UgYWRkciAlMi4yeCBtc2cgIyVkXG4iCgkJCQkJLG1zZ3NbaV0uYWRkcixpKSk7CgkJCSAgICByZXR1cm4gKHJldDwwKSA/IHJldCA6IC1FUkVNT1RFSU87CgkJCX0KCQl9CgkJaWYgKHBtc2ctPmZsYWdzICYgSTJDX01fUkQgKSB7CgkJCS8qIHJlYWQgYnl0ZXMgaW50byBidWZmZXIqLwoJCQlyZXQgPSByZWFkYnl0ZXMoaTJjX2FkYXAsIHBtc2cpOwoJCQlERUIyKHByaW50ayhLRVJOX0RFQlVHICJpMmMtYWxnby1iaXQubzogcmVhZCAlZCBieXRlcy5cbiIscmV0KSk7CgkJCWlmIChyZXQgPCBwbXNnLT5sZW4gKSB7CgkJCQlyZXR1cm4gKHJldDwwKT8gcmV0IDogLUVSRU1PVEVJTzsKCQkJfQoJCX0gZWxzZSB7CgkJCS8qIHdyaXRlIGJ5dGVzIGZyb20gYnVmZmVyICovCgkJCXJldCA9IHNlbmRieXRlcyhpMmNfYWRhcCwgcG1zZyk7CgkJCURFQjIocHJpbnRrKEtFUk5fREVCVUcgImkyYy1hbGdvLWJpdC5vOiB3cm90ZSAlZCBieXRlcy5cbiIscmV0KSk7CgkJCWlmIChyZXQgPCBwbXNnLT5sZW4gKSB7CgkJCQlyZXR1cm4gKHJldDwwKSA/IHJldCA6IC1FUkVNT1RFSU87CgkJCX0KCQl9Cgl9CglpMmNfc3RvcChhZGFwKTsKCXJldHVybiBudW07Cn0KCnN0YXRpYyB1MzIgYml0X2Z1bmMoc3RydWN0IGkyY19hZGFwdGVyICphZGFwKQp7CglyZXR1cm4gSTJDX0ZVTkNfSTJDIHwgSTJDX0ZVTkNfU01CVVNfRU1VTCB8IAoJICAgICAgIEkyQ19GVU5DXzEwQklUX0FERFIgfCBJMkNfRlVOQ19QUk9UT0NPTF9NQU5HTElORzsKfQoKCi8qIC0tLS0tZXhwb3J0ZWQgYWxnb3JpdGhtIGRhdGE6IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0JKi8KCnN0YXRpYyBzdHJ1Y3QgaTJjX2FsZ29yaXRobSBpMmNfYml0X2FsZ28gPSB7CgkubmFtZQkJPSAiQml0LXNoaWZ0IGFsZ29yaXRobSIsCgkuaWQJCT0gSTJDX0FMR09fQklULAoJLm1hc3Rlcl94ZmVyCT0gYml0X3hmZXIsCgkuZnVuY3Rpb25hbGl0eQk9IGJpdF9mdW5jLAp9OwoKLyogCiAqIHJlZ2lzdGVyaW5nIGZ1bmN0aW9ucyB0byBsb2FkIGFsZ29yaXRobXMgYXQgcnVudGltZSAKICovCmludCBpMmNfYml0X2FkZF9idXMoc3RydWN0IGkyY19hZGFwdGVyICphZGFwKQp7CglzdHJ1Y3QgaTJjX2FsZ29fYml0X2RhdGEgKmJpdF9hZGFwID0gYWRhcC0+YWxnb19kYXRhOwoKCWlmIChiaXRfdGVzdCkgewoJCWludCByZXQgPSB0ZXN0X2J1cyhiaXRfYWRhcCwgYWRhcC0+bmFtZSk7CgkJaWYgKHJldDwwKQoJCQlyZXR1cm4gLUVOT0RFVjsKCX0KCglERUIyKGRldl9kYmcoJmFkYXAtPmRldiwgImh3IHJvdXRpbmVzIHJlZ2lzdGVyZWQuXG4iKSk7CgoJLyogcmVnaXN0ZXIgbmV3IGFkYXB0ZXIgdG8gaTJjIG1vZHVsZS4uLiAqLwoKCWFkYXAtPmlkIHw9IGkyY19iaXRfYWxnby5pZDsKCWFkYXAtPmFsZ28gPSAmaTJjX2JpdF9hbGdvOwoKCWFkYXAtPnRpbWVvdXQgPSAxMDA7CS8qIGRlZmF1bHQgdmFsdWVzLCBzaG91bGQJKi8KCWFkYXAtPnJldHJpZXMgPSAzOwkvKiBiZSByZXBsYWNlZCBieSBkZWZpbmVzCSovCgoJaTJjX2FkZF9hZGFwdGVyKGFkYXApOwoJcmV0dXJuIDA7Cn0KCgppbnQgaTJjX2JpdF9kZWxfYnVzKHN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcCkKewoJcmV0dXJuIGkyY19kZWxfYWRhcHRlcihhZGFwKTsKfQoKRVhQT1JUX1NZTUJPTChpMmNfYml0X2FkZF9idXMpOwpFWFBPUlRfU1lNQk9MKGkyY19iaXRfZGVsX2J1cyk7CgpNT0RVTEVfQVVUSE9SKCJTaW1vbiBHLiBWb2dsIDxzaW1vbkB0ay51bmktbGluei5hYy5hdD4iKTsKTU9EVUxFX0RFU0NSSVBUSU9OKCJJMkMtQnVzIGJpdC1iYW5naW5nIGFsZ29yaXRobSIpOwpNT0RVTEVfTElDRU5TRSgiR1BMIik7Cgptb2R1bGVfcGFyYW0oYml0X3Rlc3QsIGJvb2wsIDApOwptb2R1bGVfcGFyYW0oaTJjX2RlYnVnLCBpbnQsIFNfSVJVR08gfCBTX0lXVVNSKTsKCk1PRFVMRV9QQVJNX0RFU0MoYml0X3Rlc3QsICJUZXN0IHRoZSBsaW5lcyBvZiB0aGUgYnVzIHRvIHNlZSBpZiBpdCBpcyBzdHVjayIpOwpNT0RVTEVfUEFSTV9ERVNDKGkyY19kZWJ1ZywKCQkgImRlYnVnIGxldmVsIC0gMCBvZmY7IDEgbm9ybWFsOyAyLDMgbW9yZSB2ZXJib3NlOyA5IGJpdC1wcm90b2NvbCIpOwo=