LyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwovKiBpMmMtYWxnby1iaXQuYyBpMmMgZHJpdmVyIGFsZ29yaXRobXMgZm9yIGJpdC1zaGlmdCBhZGFwdGVycwkJICAgICAqLwovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCi8qICAgQ29weXJpZ2h0IChDKSAxOTk1LTIwMDAgU2ltb24gRy4gVm9nbAoKICAgIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAgICBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogICAgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKICAgIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCgogICAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAgICBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogICAgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogICAgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KCiAgICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogICAgYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICAgIEZvdW5kYXRpb24sIEluYy4sIDY3NSBNYXNzIEF2ZSwgQ2FtYnJpZGdlLCBNQSAwMjEzOSwgVVNBLgkJICAgICAqLwovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKiBXaXRoIHNvbWUgY2hhbmdlcyBmcm9tIEZyb2RvIExvb2lqYWFyZCA8ZnJvZG9sQGRkcy5ubD4sIEt59nN0aSBN5Gxra2kKICAgPGttYWxra2lAY2MuaHV0LmZpPiBhbmQgSmVhbiBEZWx2YXJlIDxraGFsaUBsaW51eC1mci5vcmc+ICovCgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxsaW51eC9lcnJuby5oPgojaW5jbHVkZSA8bGludXgvc2NoZWQuaD4KI2luY2x1ZGUgPGxpbnV4L2kyYy5oPgojaW5jbHVkZSA8bGludXgvaTJjLWFsZ28tYml0Lmg+CgoKLyogLS0tLS0gZ2xvYmFsIGRlZmluZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KI2RlZmluZSBERUIoeCkgaWYgKGkyY19kZWJ1Zz49MSkgeDsKI2RlZmluZSBERUIyKHgpIGlmIChpMmNfZGVidWc+PTIpIHg7CiNkZWZpbmUgREVCU1RBVCh4KSBpZiAoaTJjX2RlYnVnPj0zKSB4OyAvKiBwcmludCBzZXZlcmFsIHN0YXRpc3RpY2FsIHZhbHVlcyovCiNkZWZpbmUgREVCUFJPVE8oeCkgaWYgKGkyY19kZWJ1Zz49OSkgeyB4OyB9CiAJLyogZGVidWcgdGhlIHByb3RvY29sIGJ5IHNob3dpbmcgdHJhbnNmZXJyZWQgYml0cyAqLwoKCi8qIC0tLS0tIGdsb2JhbCB2YXJpYWJsZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCSovCgovKiBtb2R1bGUgcGFyYW1ldGVyczoKICovCnN0YXRpYyBpbnQgaTJjX2RlYnVnOwpzdGF0aWMgaW50IGJpdF90ZXN0OwkvKiBzZWUgaWYgdGhlIGxpbmUtc2V0dGluZyBmdW5jdGlvbnMgd29yawkqLwoKLyogLS0tIHNldHRpbmcgc3RhdGVzIG9uIHRoZSBidXMgd2l0aCB0aGUgcmlnaHQgdGltaW5nOiAtLS0tLS0tLS0tLS0tLS0JKi8KCiNkZWZpbmUgc2V0c2RhKGFkYXAsdmFsKSBhZGFwLT5zZXRzZGEoYWRhcC0+ZGF0YSwgdmFsKQojZGVmaW5lIHNldHNjbChhZGFwLHZhbCkgYWRhcC0+c2V0c2NsKGFkYXAtPmRhdGEsIHZhbCkKI2RlZmluZSBnZXRzZGEoYWRhcCkgYWRhcC0+Z2V0c2RhKGFkYXAtPmRhdGEpCiNkZWZpbmUgZ2V0c2NsKGFkYXApIGFkYXAtPmdldHNjbChhZGFwLT5kYXRhKQoKc3RhdGljIGlubGluZSB2b2lkIHNkYWxvKHN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCkKewoJc2V0c2RhKGFkYXAsMCk7Cgl1ZGVsYXkoYWRhcC0+dWRlbGF5KTsKfQoKc3RhdGljIGlubGluZSB2b2lkIHNkYWhpKHN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCkKewoJc2V0c2RhKGFkYXAsMSk7Cgl1ZGVsYXkoYWRhcC0+dWRlbGF5KTsKfQoKc3RhdGljIGlubGluZSB2b2lkIHNjbGxvKHN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCkKewoJc2V0c2NsKGFkYXAsMCk7Cgl1ZGVsYXkoYWRhcC0+dWRlbGF5KTsKfQoKLyoKICogUmFpc2Ugc2NsIGxpbmUsIGFuZCBkbyBjaGVja2luZyBmb3IgZGVsYXlzLiBUaGlzIGlzIG5lY2Vzc2FyeSBmb3Igc2xvd2VyCiAqIGRldmljZXMuCiAqLwpzdGF0aWMgaW50IHNjbGhpKHN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCkKewoJdW5zaWduZWQgbG9uZyBzdGFydDsKCglzZXRzY2woYWRhcCwxKTsKCgkvKiBOb3QgYWxsIGFkYXB0ZXJzIGhhdmUgc2NsIHNlbnNlIGxpbmUuLi4gKi8KCWlmICghYWRhcC0+Z2V0c2NsKQoJCWdvdG8gZG9uZTsKCglzdGFydD1qaWZmaWVzOwoJd2hpbGUgKCEgZ2V0c2NsKGFkYXApICkgewkKIAkJLyogdGhlIGh3IGtub3dzIGhvdyB0byByZWFkIHRoZSBjbG9jayBsaW5lLAogCQkgKiBzbyB3ZSB3YWl0IHVudGlsIGl0IGFjdHVhbGx5IGdldHMgaGlnaC4KIAkJICogVGhpcyBpcyBzYWZlciBhcyBzb21lIGNoaXBzIG1heSBob2xkIGl0IGxvdwogCQkgKiB3aGlsZSB0aGV5IGFyZSBwcm9jZXNzaW5nIGRhdGEgaW50ZXJuYWxseS4gCiAJCSAqLwoJCWlmICh0aW1lX2FmdGVyX2VxKGppZmZpZXMsIHN0YXJ0K2FkYXAtPnRpbWVvdXQpKSB7CgkJCXJldHVybiAtRVRJTUVET1VUOwoJCX0KCQljb25kX3Jlc2NoZWQoKTsKCX0KCURFQlNUQVQocHJpbnRrKEtFUk5fREVCVUcgIm5lZWRlZCAlbGQgamlmZmllc1xuIiwgamlmZmllcy1zdGFydCkpOwoKZG9uZToKCXVkZWxheShhZGFwLT51ZGVsYXkpOwoJcmV0dXJuIDA7Cn0gCgoKLyogLS0tIG90aGVyIGF1eGlsaWFyeSBmdW5jdGlvbnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0JKi8Kc3RhdGljIHZvaWQgaTJjX3N0YXJ0KHN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCkgCnsKCS8qIGFzc2VydDogc2NsLCBzZGEgYXJlIGhpZ2ggKi8KCURFQlBST1RPKHByaW50aygiUyAiKSk7CglzZGFsbyhhZGFwKTsKCXNjbGxvKGFkYXApOwp9CgpzdGF0aWMgdm9pZCBpMmNfcmVwc3RhcnQoc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICphZGFwKSAKewoJLyogc2NsLCBzZGEgbWF5IG5vdCBiZSBoaWdoICovCglERUJQUk9UTyhwcmludGsoIiBTciAiKSk7CglzZXRzZGEoYWRhcCwxKTsKCXNjbGhpKGFkYXApOwoJCglzZGFsbyhhZGFwKTsKCXNjbGxvKGFkYXApOwp9CgoKc3RhdGljIHZvaWQgaTJjX3N0b3Aoc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICphZGFwKSAKewoJREVCUFJPVE8ocHJpbnRrKCJQXG4iKSk7CgkvKiBhc3NlcnQ6IHNjbCBpcyBsb3cgKi8KCXNkYWxvKGFkYXApOwoJc2NsaGkoYWRhcCk7IAoJc2RhaGkoYWRhcCk7Cn0KCgoKLyogc2VuZCBhIGJ5dGUgd2l0aG91dCBzdGFydCBjb25kLiwgbG9vayBmb3IgYXJiaXRyYXRpb24sIAogICBjaGVjayBhY2tuLiBmcm9tIHNsYXZlICovCi8qIHJldHVybnM6CiAqIDEgaWYgdGhlIGRldmljZSBhY2tub3dsZWRnZWQKICogMCBpZiB0aGUgZGV2aWNlIGRpZCBub3QgYWNrCiAqIC1FVElNRURPVVQgaWYgYW4gZXJyb3Igb2NjdXJyZWQgKHdoaWxlIHJhaXNpbmcgdGhlIHNjbCBsaW5lKQogKi8Kc3RhdGljIGludCBpMmNfb3V0YihzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmkyY19hZGFwLCBjaGFyIGMpCnsKCWludCBpOwoJaW50IHNiOwoJaW50IGFjazsKCXN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCA9IGkyY19hZGFwLT5hbGdvX2RhdGE7CgoJLyogYXNzZXJ0OiBzY2wgaXMgbG93ICovCglmb3IgKCBpPTcgOyBpPj0wIDsgaS0tICkgewoJCXNiID0gYyAmICggMSA8PCBpICk7CgkJc2V0c2RhKGFkYXAsc2IpOwoJCXVkZWxheShhZGFwLT51ZGVsYXkpOwoJCURFQlBST1RPKHByaW50ayhLRVJOX0RFQlVHICIlZCIsc2IhPTApKTsKCQlpZiAoc2NsaGkoYWRhcCk8MCkgeyAvKiB0aW1lZCBvdXQgKi8KCQkJc2RhaGkoYWRhcCk7IC8qIHdlIGRvbid0IHdhbnQgdG8gYmxvY2sgdGhlIG5ldCAqLwoJCQlERUIyKHByaW50ayhLRVJOX0RFQlVHICIgaTJjX291dGI6IDB4JTAyeCwgdGltZW91dCBhdCBiaXQgIyVkXG4iLCBjJjB4ZmYsIGkpKTsKCQkJcmV0dXJuIC1FVElNRURPVVQ7CgkJfTsKCQkvKiBkbyBhcmJpdHJhdGlvbiBoZXJlOiAKCQkgKiBpZiAoIHNiICYmICEgZ2V0c2RhKGFkYXApICkgLT4gb3VjaCEgR2V0IG91dCBvZiBoZXJlLgoJCSAqLwoJCXNldHNjbChhZGFwLCAwICk7CgkJdWRlbGF5KGFkYXAtPnVkZWxheSk7Cgl9CglzZGFoaShhZGFwKTsKCWlmIChzY2xoaShhZGFwKTwwKXsgLyogdGltZW91dCAqLwoJICAgIERFQjIocHJpbnRrKEtFUk5fREVCVUcgIiBpMmNfb3V0YjogMHglMDJ4LCB0aW1lb3V0IGF0IGFja1xuIiwgYyYweGZmKSk7CgkgICAgcmV0dXJuIC1FVElNRURPVVQ7Cgl9OwoJLyogcmVhZCBhY2s6IFNEQSBzaG91bGQgYmUgcHVsbGVkIGRvd24gYnkgc2xhdmUgKi8KCWFjaz1nZXRzZGEoYWRhcCk7CS8qIGFjazogc2RhIGlzIHB1bGxlZCBsb3cgLT5zdWNjZXNzLgkgKi8KCURFQjIocHJpbnRrKEtFUk5fREVCVUcgIiBpMmNfb3V0YjogMHglMDJ4ICwgZ2V0c2RhKCkgPSAlZFxuIiwgYyAmIDB4ZmYsIGFjaykpOwoKCURFQlBST1RPKCBwcmludGsoS0VSTl9ERUJVRyAiWyUyLjJ4XSIsYyYweGZmKSApOwoJREVCUFJPVE8oaWYgKDA9PWFjayl7IHByaW50ayhLRVJOX0RFQlVHICIgQSAiKTt9IGVsc2UgcHJpbnRrKEtFUk5fREVCVUcgIiBOQSAiKSApOwoJc2NsbG8oYWRhcCk7CglyZXR1cm4gMD09YWNrOwkJLyogcmV0dXJuIDEgaWYgZGV2aWNlIGFja2VkCSAqLwoJLyogYXNzZXJ0OiBzY2wgaXMgbG93IChzZGEgdW5kZWYpICovCn0KCgpzdGF0aWMgaW50IGkyY19pbmIoc3RydWN0IGkyY19hZGFwdGVyICppMmNfYWRhcCkgCnsKCS8qIHJlYWQgYnl0ZSB2aWEgaTJjIHBvcnQsIHdpdGhvdXQgc3RhcnQvc3RvcCBzZXF1ZW5jZQkqLwoJLyogYWNrbm93bGVkZ2UgaXMgc2VudCBpbiBpMmNfcmVhZC4JCQkqLwoJaW50IGk7Cgl1bnNpZ25lZCBjaGFyIGluZGF0YT0wOwoJc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICphZGFwID0gaTJjX2FkYXAtPmFsZ29fZGF0YTsKCgkvKiBhc3NlcnQ6IHNjbCBpcyBsb3cgKi8KCXNkYWhpKGFkYXApOwoJZm9yIChpPTA7aTw4O2krKykgewoJCWlmIChzY2xoaShhZGFwKTwwKSB7IC8qIHRpbWVvdXQgKi8KCQkJREVCMihwcmludGsoS0VSTl9ERUJVRyAiIGkyY19pbmI6IHRpbWVvdXQgYXQgYml0ICMlZFxuIiwgNy1pKSk7CgkJCXJldHVybiAtRVRJTUVET1VUOwoJCX07CgkJaW5kYXRhICo9IDI7CgkJaWYgKCBnZXRzZGEoYWRhcCkgKSAKCQkJaW5kYXRhIHw9IDB4MDE7CgkJc2NsbG8oYWRhcCk7Cgl9CgkvKiBhc3NlcnQ6IHNjbCBpcyBsb3cgKi8KCURFQjIocHJpbnRrKEtFUk5fREVCVUcgImkyY19pbmI6IDB4JTAyeFxuIiwgaW5kYXRhICYgMHhmZikpOwoKCURFQlBST1RPKHByaW50ayhLRVJOX0RFQlVHICIgMHglMDJ4IiwgaW5kYXRhICYgMHhmZikpOwoJcmV0dXJuIChpbnQpIChpbmRhdGEgJiAweGZmKTsKfQoKLyoKICogU2FuaXR5IGNoZWNrIGZvciB0aGUgYWRhcHRlciBoYXJkd2FyZSAtIGNoZWNrIHRoZSByZWFjdGlvbiBvZgogKiB0aGUgYnVzIGxpbmVzIG9ubHkgaWYgaXQgc2VlbXMgdG8gYmUgaWRsZS4KICovCnN0YXRpYyBpbnQgdGVzdF9idXMoc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICphZGFwLCBjaGFyKiBuYW1lKSB7CglpbnQgc2NsLHNkYTsKCglpZiAoYWRhcC0+Z2V0c2NsPT1OVUxMKQoJCXByaW50ayhLRVJOX0lORk8gImkyYy1hbGdvLWJpdC5vOiBUZXN0aW5nIFNEQSBvbmx5LCAiCgkJCSJTQ0wgaXMgbm90IHJlYWRhYmxlLlxuIik7CgoJc2RhPWdldHNkYShhZGFwKTsKCXNjbD0oYWRhcC0+Z2V0c2NsPT1OVUxMPzE6Z2V0c2NsKGFkYXApKTsKCXByaW50ayhLRVJOX0RFQlVHICJpMmMtYWxnby1iaXQubzogKDApIHNjbD0lZCwgc2RhPSVkXG4iLHNjbCxzZGEpOwoJaWYgKCFzY2wgfHwgIXNkYSApIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJpMmMtYWxnby1iaXQubzogJXMgc2VlbXMgdG8gYmUgYnVzeS5cbiIsIG5hbWUpOwoJCWdvdG8gYmFpbG91dDsKCX0KCglzZGFsbyhhZGFwKTsKCXNkYT1nZXRzZGEoYWRhcCk7CglzY2w9KGFkYXAtPmdldHNjbD09TlVMTD8xOmdldHNjbChhZGFwKSk7CglwcmludGsoS0VSTl9ERUJVRyAiaTJjLWFsZ28tYml0Lm86ICgxKSBzY2w9JWQsIHNkYT0lZFxuIixzY2wsc2RhKTsKCWlmICggMCAhPSBzZGEgKSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORyAiaTJjLWFsZ28tYml0Lm86IFNEQSBzdHVjayBoaWdoIVxuIik7CgkJZ290byBiYWlsb3V0OwoJfQoJaWYgKCAwID09IHNjbCApIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJpMmMtYWxnby1iaXQubzogU0NMIHVuZXhwZWN0ZWQgbG93ICIKCQkJIndoaWxlIHB1bGxpbmcgU0RBIGxvdyFcbiIpOwoJCWdvdG8gYmFpbG91dDsKCX0JCQoKCXNkYWhpKGFkYXApOwoJc2RhPWdldHNkYShhZGFwKTsKCXNjbD0oYWRhcC0+Z2V0c2NsPT1OVUxMPzE6Z2V0c2NsKGFkYXApKTsKCXByaW50ayhLRVJOX0RFQlVHICJpMmMtYWxnby1iaXQubzogKDIpIHNjbD0lZCwgc2RhPSVkXG4iLHNjbCxzZGEpOwoJaWYgKCAwID09IHNkYSApIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJpMmMtYWxnby1iaXQubzogU0RBIHN0dWNrIGxvdyFcbiIpOwoJCWdvdG8gYmFpbG91dDsKCX0KCWlmICggMCA9PSBzY2wgKSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORyAiaTJjLWFsZ28tYml0Lm86IFNDTCB1bmV4cGVjdGVkIGxvdyAiCgkJCSJ3aGlsZSBwdWxsaW5nIFNEQSBoaWdoIVxuIik7CgkJZ290byBiYWlsb3V0OwoJfQoKCXNjbGxvKGFkYXApOwoJc2RhPWdldHNkYShhZGFwKTsKCXNjbD0oYWRhcC0+Z2V0c2NsPT1OVUxMPzA6Z2V0c2NsKGFkYXApKTsKCXByaW50ayhLRVJOX0RFQlVHICJpMmMtYWxnby1iaXQubzogKDMpIHNjbD0lZCwgc2RhPSVkXG4iLHNjbCxzZGEpOwoJaWYgKCAwICE9IHNjbCApIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJpMmMtYWxnby1iaXQubzogU0NMIHN0dWNrIGhpZ2ghXG4iKTsKCQlnb3RvIGJhaWxvdXQ7Cgl9CglpZiAoIDAgPT0gc2RhICkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgImkyYy1hbGdvLWJpdC5vOiBTREEgdW5leHBlY3RlZCBsb3cgIgoJCQkid2hpbGUgcHVsbGluZyBTQ0wgbG93IVxuIik7CgkJZ290byBiYWlsb3V0OwoJfQoJCglzY2xoaShhZGFwKTsKCXNkYT1nZXRzZGEoYWRhcCk7CglzY2w9KGFkYXAtPmdldHNjbD09TlVMTD8xOmdldHNjbChhZGFwKSk7CglwcmludGsoS0VSTl9ERUJVRyAiaTJjLWFsZ28tYml0Lm86ICg0KSBzY2w9JWQsIHNkYT0lZFxuIixzY2wsc2RhKTsKCWlmICggMCA9PSBzY2wgKSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORyAiaTJjLWFsZ28tYml0Lm86IFNDTCBzdHVjayBsb3chXG4iKTsKCQlnb3RvIGJhaWxvdXQ7Cgl9CglpZiAoIDAgPT0gc2RhICkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgImkyYy1hbGdvLWJpdC5vOiBTREEgdW5leHBlY3RlZCBsb3cgIgoJCQkid2hpbGUgcHVsbGluZyBTQ0wgaGlnaCFcbiIpOwoJCWdvdG8gYmFpbG91dDsKCX0KCXByaW50ayhLRVJOX0lORk8gImkyYy1hbGdvLWJpdC5vOiAlcyBwYXNzZWQgdGVzdC5cbiIsbmFtZSk7CglyZXR1cm4gMDsKYmFpbG91dDoKCXNkYWhpKGFkYXApOwoJc2NsaGkoYWRhcCk7CglyZXR1cm4gLUVOT0RFVjsKfQoKLyogLS0tLS0gVXRpbGl0eSBmdW5jdGlvbnMKICovCgovKiB0cnlfYWRkcmVzcyB0cmllcyB0byBjb250YWN0IGEgY2hpcCBmb3IgYSBudW1iZXIgb2YKICogdGltZXMgYmVmb3JlIGl0IGdpdmVzIHVwLgogKiByZXR1cm4gdmFsdWVzOgogKiAxIGNoaXAgYW5zd2VyZWQKICogMCBjaGlwIGRpZCBub3QgYW5zd2VyCiAqIC14IHRyYW5zbWlzc2lvbiBlcnJvcgogKi8Kc3RhdGljIGludCB0cnlfYWRkcmVzcyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmkyY19hZGFwLAoJCSAgICAgICB1bnNpZ25lZCBjaGFyIGFkZHIsIGludCByZXRyaWVzKQp7CglzdHJ1Y3QgaTJjX2FsZ29fYml0X2RhdGEgKmFkYXAgPSBpMmNfYWRhcC0+YWxnb19kYXRhOwoJaW50IGkscmV0ID0gLTE7Cglmb3IgKGk9MDtpPD1yZXRyaWVzO2krKykgewoJCXJldCA9IGkyY19vdXRiKGkyY19hZGFwLGFkZHIpOwoJCWlmIChyZXQgPT0gMSB8fCBpID09IHJldHJpZXMpCgkJCWJyZWFrOwoJCWkyY19zdG9wKGFkYXApOwoJCXVkZWxheSg1LyphZGFwLT51ZGVsYXkqLyk7CgkJaTJjX3N0YXJ0KGFkYXApOwoJCXVkZWxheShhZGFwLT51ZGVsYXkpOwoJfQoJREVCMihpZiAoaSkKCSAgICAgcHJpbnRrKEtFUk5fREVCVUcgImkyYy1hbGdvLWJpdC5vOiBVc2VkICVkIHRyaWVzIHRvICVzIGNsaWVudCBhdCAweCUwMnggOiAlc1xuIiwKCQkgICAgaSsxLCBhZGRyICYgMSA/ICJyZWFkIiA6ICJ3cml0ZSIsIGFkZHI+PjEsCgkJICAgIHJldD09MSA/ICJzdWNjZXNzIiA6IHJldD09MCA/ICJubyBhY2siIDogImZhaWxlZCwgdGltZW91dD8iICkKCSAgICApOwoJcmV0dXJuIHJldDsKfQoKc3RhdGljIGludCBzZW5kYnl0ZXMoc3RydWN0IGkyY19hZGFwdGVyICppMmNfYWRhcCwgc3RydWN0IGkyY19tc2cgKm1zZykKewoJY2hhciBjOwoJY29uc3QgY2hhciAqdGVtcCA9IG1zZy0+YnVmOwoJaW50IGNvdW50ID0gbXNnLT5sZW47Cgl1bnNpZ25lZCBzaG9ydCBuYWtfb2sgPSBtc2ctPmZsYWdzICYgSTJDX01fSUdOT1JFX05BSzsgCglpbnQgcmV0dmFsOwoJaW50IHdyY291bnQ9MDsKCgl3aGlsZSAoY291bnQgPiAwKSB7CgkJYyA9ICp0ZW1wOwoJCURFQjIoZGV2X2RiZygmaTJjX2FkYXAtPmRldiwgInNlbmRieXRlczogd3JpdGluZyAlMi4yWFxuIiwgYyYweGZmKSk7CgkJcmV0dmFsID0gaTJjX291dGIoaTJjX2FkYXAsYyk7CgkJaWYgKChyZXR2YWw+MCkgfHwgKG5ha19vayAmJiAocmV0dmFsPT0wKSkpICB7IC8qIG9rIG9yIGlnbm9yZWQgTkFLICovCgkJCWNvdW50LS07IAoJCQl0ZW1wKys7CgkJCXdyY291bnQrKzsKCQl9IGVsc2UgeyAvKiBhcmJpdHJhdGlvbiBvciBubyBhY2tub3dsZWRnZSAqLwoJCQlkZXZfZXJyKCZpMmNfYWRhcC0+ZGV2LCAic2VuZGJ5dGVzOiBlcnJvciAtIGJhaWxvdXQuXG4iKTsKCQkJcmV0dXJuIChyZXR2YWw8MCk/IHJldHZhbCA6IC1FRkFVTFQ7CgkJCSAgICAgICAgLyogZ290IGEgYmV0dGVyIG9uZSA/PyAqLwoJCX0KCX0KCXJldHVybiB3cmNvdW50Owp9CgpzdGF0aWMgaW50IHJlYWRieXRlcyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmkyY19hZGFwLCBzdHJ1Y3QgaTJjX21zZyAqbXNnKQp7CglpbnQgaW52YWw7CglpbnQgcmRjb3VudD0wOyAgIAkvKiBjb3VudHMgYnl0ZXMgcmVhZCAqLwoJc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICphZGFwID0gaTJjX2FkYXAtPmFsZ29fZGF0YTsKCWNoYXIgKnRlbXAgPSBtc2ctPmJ1ZjsKCWludCBjb3VudCA9IG1zZy0+bGVuOwoKCXdoaWxlIChjb3VudCA+IDApIHsKCQlpbnZhbCA9IGkyY19pbmIoaTJjX2FkYXApOwoJCWlmIChpbnZhbD49MCkgewoJCQkqdGVtcCA9IGludmFsOwoJCQlyZGNvdW50Kys7CgkJfSBlbHNlIHsgICAvKiByZWFkIHRpbWVkIG91dCAqLwoJCQlwcmludGsoS0VSTl9FUlIgImkyYy1hbGdvLWJpdC5vOiByZWFkYnl0ZXM6IGkyY19pbmIgdGltZWQgb3V0LlxuIik7CgkJCWJyZWFrOwoJCX0KCgkJdGVtcCsrOwoJCWNvdW50LS07CgoJCWlmIChtc2ctPmZsYWdzICYgSTJDX01fTk9fUkRfQUNLKQoJCQljb250aW51ZTsKCgkJaWYgKCBjb3VudCA+IDAgKSB7CQkvKiBzZW5kIGFjayAqLwoJCQlzZGFsbyhhZGFwKTsKCQkJREVCUFJPVE8ocHJpbnRrKCIgQW0gIikpOwoJCX0gZWxzZSB7CgkJCXNkYWhpKGFkYXApOwkvKiBuZWcuIGFjayBvbiBsYXN0IGJ5dGUgKi8KCQkJREVCUFJPVE8ocHJpbnRrKCIgTkFtICIpKTsKCQl9CgkJaWYgKHNjbGhpKGFkYXApPDApIHsJLyogdGltZW91dCAqLwoJCQlzZGFoaShhZGFwKTsKCQkJcHJpbnRrKEtFUk5fRVJSICJpMmMtYWxnby1iaXQubzogcmVhZGJ5dGVzOiBUaW1lb3V0IGF0IGFja1xuIik7CgkJCXJldHVybiAtRVRJTUVET1VUOwoJCX07CgkJc2NsbG8oYWRhcCk7CgkJc2RhaGkoYWRhcCk7CgoJCS8qIFNvbWUgU01CdXMgdHJhbnNhY3Rpb25zIHJlcXVpcmUgdGhhdCB3ZSByZWNlaXZlIHRoZQoJCSAgIHRyYW5zYWN0aW9uIGxlbmd0aCBhcyB0aGUgZmlyc3QgcmVhZCBieXRlLiAqLwoJCWlmIChyZGNvdW50ID09IDEgJiYgKG1zZy0+ZmxhZ3MgJiBJMkNfTV9SRUNWX0xFTikpIHsKCQkJaWYgKGludmFsIDw9IDAgfHwgaW52YWwgPiBJMkNfU01CVVNfQkxPQ0tfTUFYKSB7CgkJCQlwcmludGsoS0VSTl9FUlIgImkyYy1hbGdvLWJpdDogcmVhZGJ5dGVzOiAiCgkJCQkgICAgICAgImludmFsaWQgYmxvY2sgbGVuZ3RoICglZClcbiIsIGludmFsKTsKCQkJCXJldHVybiAtRVJFTU9URUlPOwoJCQl9CgkJCS8qIFRoZSBvcmlnaW5hbCBjb3VudCB2YWx1ZSBhY2NvdW50cyBmb3IgdGhlIGV4dHJhCgkJCSAgIGJ5dGVzLCB0aGF0IGlzLCBlaXRoZXIgMSBmb3IgYSByZWd1bGFyIHRyYW5zYWN0aW9uLAoJCQkgICBvciAyIGZvciBhIFBFQyB0cmFuc2FjdGlvbi4gKi8KCQkJY291bnQgKz0gaW52YWw7CgkJCW1zZy0+bGVuICs9IGludmFsOwoJCX0KCX0KCXJldHVybiByZGNvdW50Owp9CgovKiBkb0FkZHJlc3MgaW5pdGlhdGVzIHRoZSB0cmFuc2ZlciBieSBnZW5lcmF0aW5nIHRoZSBzdGFydCBjb25kaXRpb24gKGluCiAqIHRyeV9hZGRyZXNzKSBhbmQgdHJhbnNtaXRzIHRoZSBhZGRyZXNzIGluIHRoZSBuZWNlc3NhcnkgZm9ybWF0IHRvIGhhbmRsZQogKiByZWFkcywgd3JpdGVzIGFzIHdlbGwgYXMgMTBiaXQtYWRkcmVzc2VzLgogKiByZXR1cm5zOgogKiAgMCBldmVyeXRoaW5nIHdlbnQgb2theSwgdGhlIGNoaXAgYWNrJ2VkLCBvciBJR05PUkVfTkFLIGZsYWcgd2FzIHNldAogKiAteCBhbiBlcnJvciBvY2N1cnJlZCAobGlrZTogLUVSRU1PVEVJTyBpZiB0aGUgZGV2aWNlIGRpZCBub3QgYW5zd2VyLCBvcgogKgktRVRJTUVET1VULCBmb3IgZXhhbXBsZSBpZiB0aGUgbGluZXMgYXJlIHN0dWNrLi4uKSAKICovCnN0YXRpYyBpbnQgYml0X2RvQWRkcmVzcyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmkyY19hZGFwLCBzdHJ1Y3QgaTJjX21zZyAqbXNnKQp7Cgl1bnNpZ25lZCBzaG9ydCBmbGFncyA9IG1zZy0+ZmxhZ3M7Cgl1bnNpZ25lZCBzaG9ydCBuYWtfb2sgPSBtc2ctPmZsYWdzICYgSTJDX01fSUdOT1JFX05BSzsKCXN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCA9IGkyY19hZGFwLT5hbGdvX2RhdGE7CgoJdW5zaWduZWQgY2hhciBhZGRyOwoJaW50IHJldCwgcmV0cmllczsKCglyZXRyaWVzID0gbmFrX29rID8gMCA6IGkyY19hZGFwLT5yZXRyaWVzOwoJCglpZiAoIChmbGFncyAmIEkyQ19NX1RFTikgICkgeyAKCQkvKiBhIHRlbiBiaXQgYWRkcmVzcyAqLwoJCWFkZHIgPSAweGYwIHwgKCggbXNnLT5hZGRyID4+IDcpICYgMHgwMyk7CgkJREVCMihwcmludGsoS0VSTl9ERUJVRyAiYWRkcjA6ICVkXG4iLGFkZHIpKTsKCQkvKiB0cnkgZXh0ZW5kZWQgYWRkcmVzcyBjb2RlLi4uKi8KCQlyZXQgPSB0cnlfYWRkcmVzcyhpMmNfYWRhcCwgYWRkciwgcmV0cmllcyk7CgkJaWYgKChyZXQgIT0gMSkgJiYgIW5ha19vaykgIHsKCQkJcHJpbnRrKEtFUk5fRVJSICJkaWVkIGF0IGV4dGVuZGVkIGFkZHJlc3MgY29kZS5cbiIpOwoJCQlyZXR1cm4gLUVSRU1PVEVJTzsKCQl9CgkJLyogdGhlIHJlbWFpbmluZyA4IGJpdCBhZGRyZXNzICovCgkJcmV0ID0gaTJjX291dGIoaTJjX2FkYXAsbXNnLT5hZGRyICYgMHg3Zik7CgkJaWYgKChyZXQgIT0gMSkgJiYgIW5ha19vaykgewoJCQkvKiB0aGUgY2hpcCBkaWQgbm90IGFjayAvIHhtaXNzaW9uIGVycm9yIG9jY3VycmVkICovCgkJCXByaW50ayhLRVJOX0VSUiAiZGllZCBhdCAybmQgYWRkcmVzcyBjb2RlLlxuIik7CgkJCXJldHVybiAtRVJFTU9URUlPOwoJCX0KCQlpZiAoIGZsYWdzICYgSTJDX01fUkQgKSB7CgkJCWkyY19yZXBzdGFydChhZGFwKTsKCQkJLyogb2theSwgbm93IHN3aXRjaCBpbnRvIHJlYWRpbmcgbW9kZSAqLwoJCQlhZGRyIHw9IDB4MDE7CgkJCXJldCA9IHRyeV9hZGRyZXNzKGkyY19hZGFwLCBhZGRyLCByZXRyaWVzKTsKCQkJaWYgKChyZXQhPTEpICYmICFuYWtfb2spIHsKCQkJCXByaW50ayhLRVJOX0VSUiAiZGllZCBhdCBleHRlbmRlZCBhZGRyZXNzIGNvZGUuXG4iKTsKCQkJCXJldHVybiAtRVJFTU9URUlPOwoJCQl9CgkJfQoJfSBlbHNlIHsJCS8qIG5vcm1hbCA3Yml0IGFkZHJlc3MJKi8KCQlhZGRyID0gKCBtc2ctPmFkZHIgPDwgMSApOwoJCWlmIChmbGFncyAmIEkyQ19NX1JEICkKCQkJYWRkciB8PSAxOwoJCWlmIChmbGFncyAmIEkyQ19NX1JFVl9ESVJfQUREUiApCgkJCWFkZHIgXj0gMTsKCQlyZXQgPSB0cnlfYWRkcmVzcyhpMmNfYWRhcCwgYWRkciwgcmV0cmllcyk7CgkJaWYgKChyZXQhPTEpICYmICFuYWtfb2spCgkJCXJldHVybiAtRVJFTU9URUlPOwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IGJpdF94ZmVyKHN0cnVjdCBpMmNfYWRhcHRlciAqaTJjX2FkYXAsCgkJICAgIHN0cnVjdCBpMmNfbXNnIG1zZ3NbXSwgaW50IG51bSkKewoJc3RydWN0IGkyY19tc2cgKnBtc2c7CglzdHJ1Y3QgaTJjX2FsZ29fYml0X2RhdGEgKmFkYXAgPSBpMmNfYWRhcC0+YWxnb19kYXRhOwoJCglpbnQgaSxyZXQ7Cgl1bnNpZ25lZCBzaG9ydCBuYWtfb2s7CgoJaTJjX3N0YXJ0KGFkYXApOwoJZm9yIChpPTA7aTxudW07aSsrKSB7CgkJcG1zZyA9ICZtc2dzW2ldOwoJCW5ha19vayA9IHBtc2ctPmZsYWdzICYgSTJDX01fSUdOT1JFX05BSzsgCgkJaWYgKCEocG1zZy0+ZmxhZ3MgJiBJMkNfTV9OT1NUQVJUKSkgewoJCQlpZiAoaSkgewoJCQkJaTJjX3JlcHN0YXJ0KGFkYXApOwoJCQl9CgkJCXJldCA9IGJpdF9kb0FkZHJlc3MoaTJjX2FkYXAsIHBtc2cpOwoJCQlpZiAoKHJldCAhPSAwKSAmJiAhbmFrX29rKSB7CgkJCSAgICBERUIyKHByaW50ayhLRVJOX0RFQlVHICJpMmMtYWxnby1iaXQubzogTkFLIGZyb20gZGV2aWNlIGFkZHIgJTIuMnggbXNnICMlZFxuIgoJCQkJCSxtc2dzW2ldLmFkZHIsaSkpOwoJCQkJZ290byBiYWlsb3V0OwoJCQl9CgkJfQoJCWlmIChwbXNnLT5mbGFncyAmIEkyQ19NX1JEICkgewoJCQkvKiByZWFkIGJ5dGVzIGludG8gYnVmZmVyKi8KCQkJcmV0ID0gcmVhZGJ5dGVzKGkyY19hZGFwLCBwbXNnKTsKCQkJREVCMihwcmludGsoS0VSTl9ERUJVRyAiaTJjLWFsZ28tYml0Lm86IHJlYWQgJWQgYnl0ZXMuXG4iLHJldCkpOwoJCQlpZiAocmV0IDwgcG1zZy0+bGVuKSB7CgkJCQlpZiAocmV0ID49IDApCgkJCQkJcmV0ID0gLUVSRU1PVEVJTzsKCQkJCWdvdG8gYmFpbG91dDsKCQkJfQoJCX0gZWxzZSB7CgkJCS8qIHdyaXRlIGJ5dGVzIGZyb20gYnVmZmVyICovCgkJCXJldCA9IHNlbmRieXRlcyhpMmNfYWRhcCwgcG1zZyk7CgkJCURFQjIocHJpbnRrKEtFUk5fREVCVUcgImkyYy1hbGdvLWJpdC5vOiB3cm90ZSAlZCBieXRlcy5cbiIscmV0KSk7CgkJCWlmIChyZXQgPCBwbXNnLT5sZW4pIHsKCQkJCWlmIChyZXQgPj0gMCkKCQkJCQlyZXQgPSAtRVJFTU9URUlPOwoJCQkJZ290byBiYWlsb3V0OwoJCQl9CgkJfQoJfQoJcmV0ID0gaTsKCmJhaWxvdXQ6CglpMmNfc3RvcChhZGFwKTsKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyB1MzIgYml0X2Z1bmMoc3RydWN0IGkyY19hZGFwdGVyICphZGFwKQp7CglyZXR1cm4gSTJDX0ZVTkNfSTJDIHwgSTJDX0ZVTkNfU01CVVNfRU1VTCB8IAoJICAgICAgIEkyQ19GVU5DX1NNQlVTX1JFQURfQkxPQ0tfREFUQSB8CgkgICAgICAgSTJDX0ZVTkNfU01CVVNfQkxPQ0tfUFJPQ19DQUxMIHwKCSAgICAgICBJMkNfRlVOQ18xMEJJVF9BRERSIHwgSTJDX0ZVTkNfUFJPVE9DT0xfTUFOR0xJTkc7Cn0KCgovKiAtLS0tLWV4cG9ydGVkIGFsZ29yaXRobSBkYXRhOiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCSovCgpzdGF0aWMgY29uc3Qgc3RydWN0IGkyY19hbGdvcml0aG0gaTJjX2JpdF9hbGdvID0gewoJLm1hc3Rlcl94ZmVyCT0gYml0X3hmZXIsCgkuZnVuY3Rpb25hbGl0eQk9IGJpdF9mdW5jLAp9OwoKLyogCiAqIHJlZ2lzdGVyaW5nIGZ1bmN0aW9ucyB0byBsb2FkIGFsZ29yaXRobXMgYXQgcnVudGltZSAKICovCnN0YXRpYyBpbnQgaTJjX2JpdF9wcmVwYXJlX2J1cyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXApCnsKCXN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYml0X2FkYXAgPSBhZGFwLT5hbGdvX2RhdGE7CgoJaWYgKGJpdF90ZXN0KSB7CgkJaW50IHJldCA9IHRlc3RfYnVzKGJpdF9hZGFwLCBhZGFwLT5uYW1lKTsKCQlpZiAocmV0PDApCgkJCXJldHVybiAtRU5PREVWOwoJfQoKCURFQjIoZGV2X2RiZygmYWRhcC0+ZGV2LCAiaHcgcm91dGluZXMgcmVnaXN0ZXJlZC5cbiIpKTsKCgkvKiByZWdpc3RlciBuZXcgYWRhcHRlciB0byBpMmMgbW9kdWxlLi4uICovCglhZGFwLT5hbGdvID0gJmkyY19iaXRfYWxnbzsKCglhZGFwLT50aW1lb3V0ID0gMTAwOwkvKiBkZWZhdWx0IHZhbHVlcywgc2hvdWxkCSovCglhZGFwLT5yZXRyaWVzID0gMzsJLyogYmUgcmVwbGFjZWQgYnkgZGVmaW5lcwkqLwoKCXJldHVybiAwOwp9CgppbnQgaTJjX2JpdF9hZGRfYnVzKHN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcCkKewoJaW50IGVycjsKCgllcnIgPSBpMmNfYml0X3ByZXBhcmVfYnVzKGFkYXApOwoJaWYgKGVycikKCQlyZXR1cm4gZXJyOwoKCXJldHVybiBpMmNfYWRkX2FkYXB0ZXIoYWRhcCk7Cn0KRVhQT1JUX1NZTUJPTChpMmNfYml0X2FkZF9idXMpOwoKaW50IGkyY19iaXRfYWRkX251bWJlcmVkX2J1cyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXApCnsKCWludCBlcnI7CgoJZXJyID0gaTJjX2JpdF9wcmVwYXJlX2J1cyhhZGFwKTsKCWlmIChlcnIpCgkJcmV0dXJuIGVycjsKCglyZXR1cm4gaTJjX2FkZF9udW1iZXJlZF9hZGFwdGVyKGFkYXApOwp9CkVYUE9SVF9TWU1CT0woaTJjX2JpdF9hZGRfbnVtYmVyZWRfYnVzKTsKCk1PRFVMRV9BVVRIT1IoIlNpbW9uIEcuIFZvZ2wgPHNpbW9uQHRrLnVuaS1saW56LmFjLmF0PiIpOwpNT0RVTEVfREVTQ1JJUFRJT04oIkkyQy1CdXMgYml0LWJhbmdpbmcgYWxnb3JpdGhtIik7Ck1PRFVMRV9MSUNFTlNFKCJHUEwiKTsKCm1vZHVsZV9wYXJhbShiaXRfdGVzdCwgYm9vbCwgMCk7Cm1vZHVsZV9wYXJhbShpMmNfZGVidWcsIGludCwgU19JUlVHTyB8IFNfSVdVU1IpOwoKTU9EVUxFX1BBUk1fREVTQyhiaXRfdGVzdCwgIlRlc3QgdGhlIGxpbmVzIG9mIHRoZSBidXMgdG8gc2VlIGlmIGl0IGlzIHN0dWNrIik7Ck1PRFVMRV9QQVJNX0RFU0MoaTJjX2RlYnVnLAoJCSAiZGVidWcgbGV2ZWwgLSAwIG9mZjsgMSBub3JtYWw7IDIsMyBtb3JlIHZlcmJvc2U7IDkgYml0LXByb3RvY29sIik7Cg==