LyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICoKICogaTJjLXBhcnBvcnQuYyBJMkMgYnVzIG92ZXIgcGFyYWxsZWwgcG9ydCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICoKICAgQ29weXJpZ2h0IChDKSAyMDAzLTIwMDQgSmVhbiBEZWx2YXJlIDxraGFsaUBsaW51eC1mci5vcmc+CiAgIAogICBCYXNlZCBvbiBvbGRlciBpMmMtcGhpbGlwcy1wYXIuYyBkcml2ZXIKICAgQ29weXJpZ2h0IChDKSAxOTk1LTIwMDAgU2ltb24gRy4gVm9nbAogICBXaXRoIHNvbWUgY2hhbmdlcyBmcm9tOgogICBGcm9kbyBMb29pamFhcmQgPGZyb2RvbEBkZHMubmw+CiAgIEt59nN0aSBN5Gxra2kgPGttYWxra2lAY2MuaHV0LmZpPgogICAKICAgVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICAgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKICAgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKICAgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KCiAgIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogICBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogICBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAgIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCgogICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogICBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogICBGb3VuZGF0aW9uLCBJbmMuLCA2NzUgTWFzcyBBdmUsIENhbWJyaWRnZSwgTUEgMDIxMzksIFVTQS4KICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgojaW5jbHVkZSA8bGludXgvY29uZmlnLmg+CiNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4KI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvcGFycG9ydC5oPgojaW5jbHVkZSA8bGludXgvaTJjLmg+CiNpbmNsdWRlIDxsaW51eC9pMmMtYWxnby1iaXQuaD4KI2luY2x1ZGUgImkyYy1wYXJwb3J0LmgiCgovKiAtLS0tLSBEZXZpY2UgbGlzdCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCnN0cnVjdCBpMmNfcGFyIHsKCXN0cnVjdCBwYXJkZXZpY2UgKnBkZXY7CglzdHJ1Y3QgaTJjX2FkYXB0ZXIgYWRhcHRlcjsKCXN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSBhbGdvX2RhdGE7CglzdHJ1Y3QgaTJjX3BhciAqbmV4dDsKfTsKCnN0YXRpYyBzdHJ1Y3QgaTJjX3BhciAqYWRhcHRlcl9saXN0OwoKLyogLS0tLS0gTG93LWxldmVsIHBhcmFsbGVsIHBvcnQgYWNjZXNzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpzdGF0aWMgdm9pZCBwb3J0X3dyaXRlX2RhdGEoc3RydWN0IHBhcnBvcnQgKnAsIHVuc2lnbmVkIGNoYXIgZCkKewoJcGFycG9ydF93cml0ZV9kYXRhKHAsIGQpOwp9CgpzdGF0aWMgdm9pZCBwb3J0X3dyaXRlX2NvbnRyb2woc3RydWN0IHBhcnBvcnQgKnAsIHVuc2lnbmVkIGNoYXIgZCkKewoJcGFycG9ydF93cml0ZV9jb250cm9sKHAsIGQpOwp9CgpzdGF0aWMgdW5zaWduZWQgY2hhciBwb3J0X3JlYWRfZGF0YShzdHJ1Y3QgcGFycG9ydCAqcCkKewoJcmV0dXJuIHBhcnBvcnRfcmVhZF9kYXRhKHApOwp9CgpzdGF0aWMgdW5zaWduZWQgY2hhciBwb3J0X3JlYWRfc3RhdHVzKHN0cnVjdCBwYXJwb3J0ICpwKQp7CglyZXR1cm4gcGFycG9ydF9yZWFkX3N0YXR1cyhwKTsKfQoKc3RhdGljIHVuc2lnbmVkIGNoYXIgcG9ydF9yZWFkX2NvbnRyb2woc3RydWN0IHBhcnBvcnQgKnApCnsKCXJldHVybiBwYXJwb3J0X3JlYWRfY29udHJvbChwKTsKfQoKc3RhdGljIHZvaWQgKCpwb3J0X3dyaXRlW10pKHN0cnVjdCBwYXJwb3J0ICosIHVuc2lnbmVkIGNoYXIpID0gewoJcG9ydF93cml0ZV9kYXRhLAoJTlVMTCwKCXBvcnRfd3JpdGVfY29udHJvbCwKfTsKCnN0YXRpYyB1bnNpZ25lZCBjaGFyICgqcG9ydF9yZWFkW10pKHN0cnVjdCBwYXJwb3J0ICopID0gewoJcG9ydF9yZWFkX2RhdGEsCglwb3J0X3JlYWRfc3RhdHVzLAoJcG9ydF9yZWFkX2NvbnRyb2wsCn07CgovKiAtLS0tLSBVbmlmaWVkIGxpbmUgb3BlcmF0aW9uIGZ1bmN0aW9ucyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCnN0YXRpYyBpbmxpbmUgdm9pZCBsaW5lX3NldChzdHJ1Y3QgcGFycG9ydCAqZGF0YSwgaW50IHN0YXRlLAoJY29uc3Qgc3RydWN0IGxpbmVvcCAqb3ApCnsKCXU4IG9sZHZhbCA9IHBvcnRfcmVhZFtvcC0+cG9ydF0oZGF0YSk7CgoJLyogVG91Y2ggb25seSB0aGUgYml0KHMpIG5lZWRlZCAqLwoJaWYgKChvcC0+aW52ZXJ0ZWQgJiYgIXN0YXRlKSB8fCAoIW9wLT5pbnZlcnRlZCAmJiBzdGF0ZSkpCgkJcG9ydF93cml0ZVtvcC0+cG9ydF0oZGF0YSwgb2xkdmFsIHwgb3AtPnZhbCk7CgllbHNlCgkJcG9ydF93cml0ZVtvcC0+cG9ydF0oZGF0YSwgb2xkdmFsICYgfm9wLT52YWwpOwp9CgpzdGF0aWMgaW5saW5lIGludCBsaW5lX2dldChzdHJ1Y3QgcGFycG9ydCAqZGF0YSwKCWNvbnN0IHN0cnVjdCBsaW5lb3AgKm9wKQp7Cgl1OCBvbGR2YWwgPSBwb3J0X3JlYWRbb3AtPnBvcnRdKGRhdGEpOwoKCXJldHVybiAoKG9wLT5pbnZlcnRlZCAmJiAob2xkdmFsICYgb3AtPnZhbCkgIT0gb3AtPnZhbCkKCSAgICB8fCAoIW9wLT5pbnZlcnRlZCAmJiAob2xkdmFsICYgb3AtPnZhbCkgPT0gb3AtPnZhbCkpOwp9CgovKiAtLS0tLSBJMkMgYWxnb3JpdGhtIGNhbGwtYmFjayBmdW5jdGlvbnMgYW5kIHN0cnVjdHVyZXMgLS0tLS0tLS0tLS0tLS0tLS0gKi8KCnN0YXRpYyB2b2lkIHBhcnBvcnRfc2V0c2NsKHZvaWQgKmRhdGEsIGludCBzdGF0ZSkKewoJbGluZV9zZXQoKHN0cnVjdCBwYXJwb3J0ICopIGRhdGEsIHN0YXRlLCAmYWRhcHRlcl9wYXJtW3R5cGVdLnNldHNjbCk7Cn0KCnN0YXRpYyB2b2lkIHBhcnBvcnRfc2V0c2RhKHZvaWQgKmRhdGEsIGludCBzdGF0ZSkKewoJbGluZV9zZXQoKHN0cnVjdCBwYXJwb3J0ICopIGRhdGEsIHN0YXRlLCAmYWRhcHRlcl9wYXJtW3R5cGVdLnNldHNkYSk7Cn0KCnN0YXRpYyBpbnQgcGFycG9ydF9nZXRzY2wodm9pZCAqZGF0YSkKewoJcmV0dXJuIGxpbmVfZ2V0KChzdHJ1Y3QgcGFycG9ydCAqKSBkYXRhLCAmYWRhcHRlcl9wYXJtW3R5cGVdLmdldHNjbCk7Cn0KCnN0YXRpYyBpbnQgcGFycG9ydF9nZXRzZGEodm9pZCAqZGF0YSkKewoJcmV0dXJuIGxpbmVfZ2V0KChzdHJ1Y3QgcGFycG9ydCAqKSBkYXRhLCAmYWRhcHRlcl9wYXJtW3R5cGVdLmdldHNkYSk7Cn0KCi8qIEVuY2Fwc3VsYXRlIHRoZSBmdW5jdGlvbnMgYWJvdmUgaW4gdGhlIGNvcnJlY3Qgc3RydWN0dXJlLgogICBOb3RlIHRoYXQgdGhpcyBpcyBvbmx5IGEgdGVtcGxhdGUsIGZyb20gd2hpY2ggdGhlIHJlYWwgc3RydWN0dXJlcyBhcmUKICAgY29waWVkLiBUaGUgYXR0YWNoaW5nIGNvZGUgd2lsbCBzZXQgZ2V0c2NsIHRvIE5VTEwgZm9yIGFkYXB0ZXJzIHRoYXQKICAgY2Fubm90IHJlYWQgU0NMIGJhY2ssIGFuZCB3aWxsIGFsc28gbWFrZSB0aGUgdGhlIGRhdGEgZmllbGQgcG9pbnQgdG8KICAgdGhlIHBhcmFsbGVsIHBvcnQgc3RydWN0dXJlLiAqLwpzdGF0aWMgc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhIHBhcnBvcnRfYWxnb19kYXRhID0gewoJLnNldHNkYQkJPSBwYXJwb3J0X3NldHNkYSwKCS5zZXRzY2wJCT0gcGFycG9ydF9zZXRzY2wsCgkuZ2V0c2RhCQk9IHBhcnBvcnRfZ2V0c2RhLAoJLmdldHNjbAkJPSBwYXJwb3J0X2dldHNjbCwKCS51ZGVsYXkJCT0gNjAsCgkubWRlbGF5CQk9IDYwLAoJLnRpbWVvdXQJPSBIWiwKfTsgCgovKiAtLS0tLSBJMmMgYW5kIHBhcmFsbGVsIHBvcnQgY2FsbC1iYWNrIGZ1bmN0aW9ucyBhbmQgc3RydWN0dXJlcyAtLS0tLS0tLS0gKi8KCnN0YXRpYyBzdHJ1Y3QgaTJjX2FkYXB0ZXIgcGFycG9ydF9hZGFwdGVyID0gewoJLm93bmVyCQk9IFRISVNfTU9EVUxFLAoJLmNsYXNzCQk9IEkyQ19DTEFTU19IV01PTiwKCS5pZAkJPSBJMkNfSFdfQl9MUCwKCS5uYW1lCQk9ICJQYXJhbGxlbCBwb3J0IGFkYXB0ZXIiLAp9OwoKc3RhdGljIHZvaWQgaTJjX3BhcnBvcnRfYXR0YWNoIChzdHJ1Y3QgcGFycG9ydCAqcG9ydCkKewoJc3RydWN0IGkyY19wYXIgKmFkYXB0ZXI7CgkKCWFkYXB0ZXIgPSBrbWFsbG9jKHNpemVvZihzdHJ1Y3QgaTJjX3BhciksIEdGUF9LRVJORUwpOwoJaWYgKGFkYXB0ZXIgPT0gTlVMTCkgewoJCXByaW50ayhLRVJOX0VSUiAiaTJjLXBhcnBvcnQ6IEZhaWxlZCB0byBrbWFsbG9jXG4iKTsKCQlyZXR1cm47Cgl9CgltZW1zZXQoYWRhcHRlciwgMHgwMCwgc2l6ZW9mKHN0cnVjdCBpMmNfcGFyKSk7CgoJcHJfZGVidWcoImkyYy1wYXJwb3J0OiBhdHRhY2hpbmcgdG8gJXNcbiIsIHBvcnQtPm5hbWUpOwoJYWRhcHRlci0+cGRldiA9IHBhcnBvcnRfcmVnaXN0ZXJfZGV2aWNlKHBvcnQsICJpMmMtcGFycG9ydCIsCgkJTlVMTCwgTlVMTCwgTlVMTCwgUEFSUE9SVF9GTEFHX0VYQ0wsIE5VTEwpOwoJaWYgKCFhZGFwdGVyLT5wZGV2KSB7CgkJcHJpbnRrKEtFUk5fRVJSICJpMmMtcGFycG9ydDogVW5hYmxlIHRvIHJlZ2lzdGVyIHdpdGggcGFycG9ydFxuIik7CgkJZ290byBFUlJPUjA7Cgl9CgoJLyogRmlsbCB0aGUgcmVzdCBvZiB0aGUgc3RydWN0dXJlICovCglhZGFwdGVyLT5hZGFwdGVyID0gcGFycG9ydF9hZGFwdGVyOwoJYWRhcHRlci0+YWxnb19kYXRhID0gcGFycG9ydF9hbGdvX2RhdGE7CglpZiAoIWFkYXB0ZXJfcGFybVt0eXBlXS5nZXRzY2wudmFsKQoJCWFkYXB0ZXItPmFsZ29fZGF0YS5nZXRzY2wgPSBOVUxMOwoJYWRhcHRlci0+YWxnb19kYXRhLmRhdGEgPSBwb3J0OwoJYWRhcHRlci0+YWRhcHRlci5hbGdvX2RhdGEgPSAmYWRhcHRlci0+YWxnb19kYXRhOwoKCWlmIChwYXJwb3J0X2NsYWltX29yX2Jsb2NrKGFkYXB0ZXItPnBkZXYpIDwgMCkgewoJCXByaW50ayhLRVJOX0VSUiAiaTJjLXBhcnBvcnQ6IENvdWxkIG5vdCBjbGFpbSBwYXJhbGxlbCBwb3J0XG4iKTsKCQlnb3RvIEVSUk9SMTsKCX0KCgkvKiBSZXNldCBoYXJkd2FyZSB0byBhIHNhbmUgc3RhdGUgKFNDTCBhbmQgU0RBIGhpZ2gpICovCglwYXJwb3J0X3NldHNkYShwb3J0LCAxKTsKCXBhcnBvcnRfc2V0c2NsKHBvcnQsIDEpOwoJLyogT3RoZXIgaW5pdCBpZiBuZWVkZWQgKHBvd2VyIG9uLi4uKSAqLwoJaWYgKGFkYXB0ZXJfcGFybVt0eXBlXS5pbml0LnZhbCkKCQlsaW5lX3NldChwb3J0LCAxLCAmYWRhcHRlcl9wYXJtW3R5cGVdLmluaXQpOwoKCXBhcnBvcnRfcmVsZWFzZShhZGFwdGVyLT5wZGV2KTsKCglpZiAoaTJjX2JpdF9hZGRfYnVzKCZhZGFwdGVyLT5hZGFwdGVyKSA8IDApIHsKCQlwcmludGsoS0VSTl9FUlIgImkyYy1wYXJwb3J0OiBVbmFibGUgdG8gcmVnaXN0ZXIgd2l0aCBJMkNcbiIpOwoJCWdvdG8gRVJST1IxOwoJfQoKCS8qIEFkZCB0aGUgbmV3IGFkYXB0ZXIgdG8gdGhlIGxpc3QgKi8KCWFkYXB0ZXItPm5leHQgPSBhZGFwdGVyX2xpc3Q7CglhZGFwdGVyX2xpc3QgPSBhZGFwdGVyOwogICAgICAgIHJldHVybjsKCkVSUk9SMToKCXBhcnBvcnRfdW5yZWdpc3Rlcl9kZXZpY2UoYWRhcHRlci0+cGRldik7CkVSUk9SMDoKCWtmcmVlKGFkYXB0ZXIpOwp9CgpzdGF0aWMgdm9pZCBpMmNfcGFycG9ydF9kZXRhY2ggKHN0cnVjdCBwYXJwb3J0ICpwb3J0KQp7CglzdHJ1Y3QgaTJjX3BhciAqYWRhcHRlciwgKnByZXY7CgoJLyogV2FsayB0aGUgbGlzdCAqLwoJZm9yIChwcmV2ID0gTlVMTCwgYWRhcHRlciA9IGFkYXB0ZXJfbGlzdDsgYWRhcHRlcjsKCSAgICAgcHJldiA9IGFkYXB0ZXIsIGFkYXB0ZXIgPSBhZGFwdGVyLT5uZXh0KSB7CgkJaWYgKGFkYXB0ZXItPnBkZXYtPnBvcnQgPT0gcG9ydCkgewoJCQkvKiBVbi1pbml0IGlmIG5lZWRlZCAocG93ZXIgb2ZmLi4uKSAqLwoJCQlpZiAoYWRhcHRlcl9wYXJtW3R5cGVdLmluaXQudmFsKQoJCQkJbGluZV9zZXQocG9ydCwgMCwgJmFkYXB0ZXJfcGFybVt0eXBlXS5pbml0KTsKCQkJCQoJCQlpMmNfYml0X2RlbF9idXMoJmFkYXB0ZXItPmFkYXB0ZXIpOwoJCQlwYXJwb3J0X3VucmVnaXN0ZXJfZGV2aWNlKGFkYXB0ZXItPnBkZXYpOwoJCQlpZiAocHJldikKCQkJCXByZXYtPm5leHQgPSBhZGFwdGVyLT5uZXh0OwoJCQllbHNlCgkJCQlhZGFwdGVyX2xpc3QgPSBhZGFwdGVyLT5uZXh0OwoJCQlrZnJlZShhZGFwdGVyKTsKCQkJcmV0dXJuOwoJCX0KCX0KfQoKc3RhdGljIHN0cnVjdCBwYXJwb3J0X2RyaXZlciBpMmNfZHJpdmVyID0gewoJLm5hbWUJPSAiaTJjLXBhcnBvcnQiLAoJLmF0dGFjaAk9IGkyY19wYXJwb3J0X2F0dGFjaCwKCS5kZXRhY2gJPSBpMmNfcGFycG9ydF9kZXRhY2gsCn07CgovKiAtLS0tLSBNb2R1bGUgbG9hZGluZywgdW5sb2FkaW5nIGFuZCBpbmZvcm1hdGlvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCnN0YXRpYyBpbnQgX19pbml0IGkyY19wYXJwb3J0X2luaXQodm9pZCkKewoJaW50IHR5cGVfY291bnQ7CgoJdHlwZV9jb3VudCA9IHNpemVvZihhZGFwdGVyX3Bhcm0pL3NpemVvZihzdHJ1Y3QgYWRhcHRlcl9wYXJtKTsKCWlmICh0eXBlIDwgMCB8fCB0eXBlID49IHR5cGVfY291bnQpIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJpMmMtcGFycG9ydDogaW52YWxpZCB0eXBlICglZClcbiIsIHR5cGUpOwoJCXR5cGUgPSAwOwoJfQoJCglyZXR1cm4gcGFycG9ydF9yZWdpc3Rlcl9kcml2ZXIoJmkyY19kcml2ZXIpOwp9CgpzdGF0aWMgdm9pZCBfX2V4aXQgaTJjX3BhcnBvcnRfZXhpdCh2b2lkKQp7CglwYXJwb3J0X3VucmVnaXN0ZXJfZHJpdmVyKCZpMmNfZHJpdmVyKTsKfQoKTU9EVUxFX0FVVEhPUigiSmVhbiBEZWx2YXJlIDxraGFsaUBsaW51eC1mci5vcmc+Iik7Ck1PRFVMRV9ERVNDUklQVElPTigiSTJDIGJ1cyBvdmVyIHBhcmFsbGVsIHBvcnQiKTsKTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwoKbW9kdWxlX2luaXQoaTJjX3BhcnBvcnRfaW5pdCk7Cm1vZHVsZV9leGl0KGkyY19wYXJwb3J0X2V4aXQpOwo=