LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgICAKICogRmlsZW5hbWU6ICAgICAgaXJ0dHktc2lyLmMKICogVmVyc2lvbjogICAgICAgMi4wCiAqIERlc2NyaXB0aW9uOiAgIElyREEgbGluZSBkaXNjaXBsaW5lIGltcGxlbWVudGF0aW9uCiAqIFN0YXR1czogICAgICAgIEV4cGVyaW1lbnRhbC4KICogQXV0aG9yOiAgICAgICAgRGFnIEJyYXR0bGkgPGRhZ2JAY3MudWl0Lm5vPgogKiBDcmVhdGVkIGF0OiAgICBUdWUgRGVjICA5IDIxOjE4OjM4IDE5OTcKICogTW9kaWZpZWQgYXQ6ICAgU3VuIE9jdCAyNyAyMjoxMzozMCAyMDAyCiAqIE1vZGlmaWVkIGJ5OiAgIE1hcnRpbiBEaWVobCA8bWFkQG1kaWVobC5kZT4KICogU291cmNlczogICAgICAgc2xpcC5jIGJ5IExhdXJlbmNlIEN1bGhhbmUsICAgPGxvekBob2xtZXMuZGVtb24uY28udWs+CiAqICAgICAgICAgICAgICAgICAgICAgICAgICBGcmVkIE4uIHZhbiBLZW1wZW4sIDx3YWx0amVAdXdhbHQubmwubXVnbmV0Lm9yZz4KICogCiAqICAgICBDb3B5cmlnaHQgKGMpIDE5OTgtMjAwMCBEYWcgQnJhdHRsaSwKICogICAgIENvcHlyaWdodCAoYykgMjAwMiBNYXJ0aW4gRGllaGwsCiAqICAgICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiAgICAgIAogKiAgICAgVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciAKICogICAgIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIAogKiAgICAgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgCiAqICAgICB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICogIAogKiAgICAgTmVpdGhlciBEYWcgQnJhdHRsaSBub3IgVW5pdmVyc2l0eSBvZiBUcm9tc/ggYWRtaXQgbGlhYmlsaXR5IG5vcgogKiAgICAgcHJvdmlkZSB3YXJyYW50eSBmb3IgYW55IG9mIHRoaXMgc29mdHdhcmUuIFRoaXMgbWF0ZXJpYWwgaXMgCiAqICAgICBwcm92aWRlZCAiQVMtSVMiIGFuZCBhdCBubyBjaGFyZ2UuCiAqICAgICAKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLyAgICAKCiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgojaW5jbHVkZSA8bGludXgvdHR5Lmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxhc20vdWFjY2Vzcy5oPgojaW5jbHVkZSA8bGludXgvc21wX2xvY2suaD4KI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+CiNpbmNsdWRlIDxsaW51eC9tdXRleC5oPgoKI2luY2x1ZGUgPG5ldC9pcmRhL2lyZGEuaD4KI2luY2x1ZGUgPG5ldC9pcmRhL2lyZGFfZGV2aWNlLmg+CgojaW5jbHVkZSAic2lyLWRldi5oIgojaW5jbHVkZSAiaXJ0dHktc2lyLmgiCgpzdGF0aWMgaW50IHFvc19tdHRfYml0cyA9IDB4MDM7ICAgICAgLyogNSBtcyBvciBtb3JlICovCgptb2R1bGVfcGFyYW0ocW9zX210dF9iaXRzLCBpbnQsIDApOwpNT0RVTEVfUEFSTV9ERVNDKHFvc19tdHRfYml0cywgIk1pbmltdW0gVHVybiBUaW1lIik7CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKiBkZXZpY2UgY29uZmlndXJhdGlvbiBjYWxsYmFja3MgYWx3YXlzIGludm9rZWQgd2l0aCBpcmRhLXRocmVhZCBjb250ZXh0ICovCgovKiBmaW5kIG91dCwgaG93IG1hbnkgY2hhcnMgd2UgaGF2ZSBpbiBidWZmZXJzIGJlbG93IHVzCiAqIHRoaXMgaXMgYWxsb3dlZCB0byBsaWUsIGkuZS4gcmV0dXJuIGxlc3MgY2hhcnMgdGhhbiB3ZQogKiBhY3R1YWxseSBoYXZlLiBUaGUgcmV0dXJuZWQgdmFsdWUgaXMgdXNlZCB0byBkZXRlcm1pbmUKICogaG93IGxvbmcgdGhlIGlyZGF0aHJlYWQgc2hvdWxkIHdhaXQgYmVmb3JlIGRvaW5nIHRoZQogKiByZWFsIGJsb2NraW5nIHdhaXRfdW50aWxfc2VudCgpCiAqLwoKc3RhdGljIGludCBpcnR0eV9jaGFyc19pbl9idWZmZXIoc3RydWN0IHNpcl9kZXYgKmRldikKewoJc3RydWN0IHNpcnR0eV9jYiAqcHJpdiA9IGRldi0+cHJpdjsKCglJUkRBX0FTU0VSVChwcml2ICE9IE5VTEwsIHJldHVybiAtMTspOwoJSVJEQV9BU1NFUlQocHJpdi0+bWFnaWMgPT0gSVJUVFlfTUFHSUMsIHJldHVybiAtMTspOwoKCXJldHVybiBwcml2LT50dHktPmRyaXZlci0+Y2hhcnNfaW5fYnVmZmVyKHByaXYtPnR0eSk7Cn0KCi8qIFdhaXQgKHNsZWVwKSB1bnRpbCB1bmRlcmxheWluZyBoYXJkd2FyZSBmaW5pc2hlZCB0cmFuc21pc3Npb24KICogaS5lLiBoYXJkd2FyZSBidWZmZXJzIGFyZSBkcmFpbmVkCiAqIHRoaXMgbXVzdCBibG9jayBhbmQgbm90IHJldHVybiBiZWZvcmUgYWxsIGNoYXJhY3RlcnMgYXJlIHJlYWxseSBzZW50CiAqCiAqIElmIHRoZSB0dHkgc2l0cyBvbiB0b3Agb2YgYSAxNjU1MEEtbGlrZSB1YXJ0LCB0aGVyZSBhcmUgdHlwaWNhbGx5CiAqIHVwIHRvIDE2IGJ5dGVzIGluIHRoZSBmaWZvIC0gZi5lLiA5NjAwIGJwcyA4TjEgbmVlZHMgMTYuNyBtc2VjCiAqCiAqIFdpdGggdXNic2VyaWFsIHRoZSB1YXJ0LWZpZm8gaXMgYmFzaWNhbGx5IHJlcGxhY2VkIGJ5IHRoZSBjb252ZXJ0ZXIncwogKiBvdXRnb2luZyBlbmRwb2ludCBidWZmZXIsIHdoaWNoIGNhbiB1c3VhbGx5IGhvbGQgNjQgYnl0ZXMgKGF0IGxlYXN0KS4KICogV2l0aCBwbDIzMDMgaXQgYXBwZWFycyB3ZSBhcmUgc2FmZSB3aXRoIDYwbXNlYyBoZXJlLgogKgogKiBJIHJlYWxseSB3aXNoIGFsbCBzZXJpYWwgZHJpdmVycyB3b3VsZCBwcm92aWRlCiAqIGNvcnJlY3QgaW1wbGVtZW50YXRpb24gb2Ygd2FpdF91bnRpbF9zZW50KCkKICovCgojZGVmaW5lIFVTQlNFUklBTF9UWF9ET05FX0RFTEFZCTYwCgpzdGF0aWMgdm9pZCBpcnR0eV93YWl0X3VudGlsX3NlbnQoc3RydWN0IHNpcl9kZXYgKmRldikKewoJc3RydWN0IHNpcnR0eV9jYiAqcHJpdiA9IGRldi0+cHJpdjsKCXN0cnVjdCB0dHlfc3RydWN0ICp0dHk7CgoJSVJEQV9BU1NFUlQocHJpdiAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHByaXYtPm1hZ2ljID09IElSVFRZX01BR0lDLCByZXR1cm47KTsKCgl0dHkgPSBwcml2LT50dHk7CglpZiAodHR5LT5kcml2ZXItPndhaXRfdW50aWxfc2VudCkgewoJCWxvY2tfa2VybmVsKCk7CgkJdHR5LT5kcml2ZXItPndhaXRfdW50aWxfc2VudCh0dHksIG1zZWNzX3RvX2ppZmZpZXMoMTAwKSk7CgkJdW5sb2NrX2tlcm5lbCgpOwoJfQoJZWxzZSB7CgkJbXNsZWVwKFVTQlNFUklBTF9UWF9ET05FX0RFTEFZKTsKCX0KfQoKLyogCiAqICBGdW5jdGlvbiBpcnR0eV9jaGFuZ2Vfc3BlZWQgKGRldiwgc3BlZWQpCiAqCiAqICAgIENoYW5nZSB0aGUgc3BlZWQgb2YgdGhlIHNlcmlhbCBwb3J0LgogKgogKiBUaGlzIG1heSBzbGVlcCBpbiBzZXRfdGVybWlvcyAodXNic2VyaWFsIGRyaXZlciBmLmUuKSBhbmQgbXVzdAogKiBub3QgYmUgY2FsbGVkIGZyb20gaW50ZXJydXB0L3RpbWVyL3Rhc2tsZXQgdGhlcmVmb3JlLgogKiBBbGwgc3VjaCBpbnZvY2F0aW9ucyBhcmUgZGVmZXJyZWQgdG8ga0lyREFkIG5vdyBzbyB3ZSBjYW4gc2xlZXAgdGhlcmUuCiAqLwoKc3RhdGljIGludCBpcnR0eV9jaGFuZ2Vfc3BlZWQoc3RydWN0IHNpcl9kZXYgKmRldiwgdW5zaWduZWQgc3BlZWQpCnsKCXN0cnVjdCBzaXJ0dHlfY2IgKnByaXYgPSBkZXYtPnByaXY7CglzdHJ1Y3QgdHR5X3N0cnVjdCAqdHR5OwogICAgICAgIHN0cnVjdCBrdGVybWlvcyBvbGRfdGVybWlvczsKCWludCBjZmxhZzsKCglJUkRBX0FTU0VSVChwcml2ICE9IE5VTEwsIHJldHVybiAtMTspOwoJSVJEQV9BU1NFUlQocHJpdi0+bWFnaWMgPT0gSVJUVFlfTUFHSUMsIHJldHVybiAtMTspOwoKCXR0eSA9IHByaXYtPnR0eTsKCglsb2NrX2tlcm5lbCgpOwoJb2xkX3Rlcm1pb3MgPSAqKHR0eS0+dGVybWlvcyk7CgljZmxhZyA9IHR0eS0+dGVybWlvcy0+Y19jZmxhZzsKCgljZmxhZyAmPSB+Q0JBVUQ7CgoJSVJEQV9ERUJVRygyLCAiJXMoKSwgU2V0dGluZyBzcGVlZCB0byAlZFxuIiwgX19GVU5DVElPTl9fLCBzcGVlZCk7CgoJc3dpdGNoIChzcGVlZCkgewoJY2FzZSAxMjAwOgoJCWNmbGFnIHw9IEIxMjAwOwoJCWJyZWFrOwoJY2FzZSAyNDAwOgoJCWNmbGFnIHw9IEIyNDAwOwoJCWJyZWFrOwoJY2FzZSA0ODAwOgoJCWNmbGFnIHw9IEI0ODAwOwoJCWJyZWFrOwoJY2FzZSAxOTIwMDoKCQljZmxhZyB8PSBCMTkyMDA7CgkJYnJlYWs7CgljYXNlIDM4NDAwOgoJCWNmbGFnIHw9IEIzODQwMDsKCQlicmVhazsKCWNhc2UgNTc2MDA6CgkJY2ZsYWcgfD0gQjU3NjAwOwoJCWJyZWFrOwoJY2FzZSAxMTUyMDA6CgkJY2ZsYWcgfD0gQjExNTIwMDsKCQlicmVhazsKCWNhc2UgOTYwMDoKCWRlZmF1bHQ6CgkJY2ZsYWcgfD0gQjk2MDA7CgkJYnJlYWs7Cgl9CQoKCXR0eS0+dGVybWlvcy0+Y19jZmxhZyA9IGNmbGFnOwoJaWYgKHR0eS0+ZHJpdmVyLT5zZXRfdGVybWlvcykKCQl0dHktPmRyaXZlci0+c2V0X3Rlcm1pb3ModHR5LCAmb2xkX3Rlcm1pb3MpOwoJdW5sb2NrX2tlcm5lbCgpOwoKCXByaXYtPmlvLnNwZWVkID0gc3BlZWQ7CgoJcmV0dXJuIDA7Cn0KCi8qCiAqIEZ1bmN0aW9uIGlydHR5X3NldF9kdHJfcnRzIChkZXYsIGR0ciwgcnRzKQogKgogKiAgICBUaGlzIGZ1bmN0aW9uIGNhbiBiZSB1c2VkIGJ5IGRvbmdsZXMgZXRjLiB0byBzZXQgb3IgcmVzZXQgdGhlIHN0YXR1cwogKiAgICBvZiB0aGUgZHRyIGFuZCBydHMgbGluZXMKICovCgpzdGF0aWMgaW50IGlydHR5X3NldF9kdHJfcnRzKHN0cnVjdCBzaXJfZGV2ICpkZXYsIGludCBkdHIsIGludCBydHMpCnsKCXN0cnVjdCBzaXJ0dHlfY2IgKnByaXYgPSBkZXYtPnByaXY7CglpbnQgc2V0ID0gMDsKCWludCBjbGVhciA9IDA7CgoJSVJEQV9BU1NFUlQocHJpdiAhPSBOVUxMLCByZXR1cm4gLTE7KTsKCUlSREFfQVNTRVJUKHByaXYtPm1hZ2ljID09IElSVFRZX01BR0lDLCByZXR1cm4gLTE7KTsKCglpZiAocnRzKQoJCXNldCB8PSBUSU9DTV9SVFM7CgllbHNlCgkJY2xlYXIgfD0gVElPQ01fUlRTOwoJaWYgKGR0cikKCQlzZXQgfD0gVElPQ01fRFRSOwoJZWxzZQoJCWNsZWFyIHw9IFRJT0NNX0RUUjsKCgkvKgoJICogV2UgY2FuJ3QgdXNlIGlvY3RsKCkgYmVjYXVzZSBpdCBleHBlY3RzIGEgbm9uLW51bGwgZmlsZSBzdHJ1Y3R1cmUsCgkgKiBhbmQgd2UgZG9uJ3QgaGF2ZSB0aGF0IGhlcmUuCgkgKiBUaGlzIGZ1bmN0aW9uIGlzIG5vdCB5ZXQgZGVmaW5lZCBmb3IgYWxsIHR0eSBkcml2ZXIsIHNvCgkgKiBsZXQncyBiZSBjYXJlZnVsLi4uIEplYW4gSUkKCSAqLwoJSVJEQV9BU1NFUlQocHJpdi0+dHR5LT5kcml2ZXItPnRpb2Ntc2V0ICE9IE5VTEwsIHJldHVybiAtMTspOwoJcHJpdi0+dHR5LT5kcml2ZXItPnRpb2Ntc2V0KHByaXYtPnR0eSwgTlVMTCwgc2V0LCBjbGVhcik7CgoJcmV0dXJuIDA7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCi8qIGNhbGxlZCBmcm9tIHNpcl9kZXYgd2hlbiB0aGVyZSBpcyBtb3JlIGRhdGEgdG8gc2VuZAogKiBjb250ZXh0IGlzIGVpdGhlciBuZXRkZXYtPmhhcmRfeG1pdCBvciBzb21lIHRyYW5zbWl0LWNvbXBsZXRpb24gYmgKICogaS5lLiB3ZSBhcmUgdW5kZXIgc3BpbmxvY2sgaGVyZSBhbmQgbXVzdCBub3Qgc2xlZXAuCiAqLwoKc3RhdGljIGludCBpcnR0eV9kb193cml0ZShzdHJ1Y3Qgc2lyX2RldiAqZGV2LCBjb25zdCB1bnNpZ25lZCBjaGFyICpwdHIsIHNpemVfdCBsZW4pCnsKCXN0cnVjdCBzaXJ0dHlfY2IgKnByaXYgPSBkZXYtPnByaXY7CglzdHJ1Y3QgdHR5X3N0cnVjdCAqdHR5OwoJaW50IHdyaXRlbGVuOwoKCUlSREFfQVNTRVJUKHByaXYgIT0gTlVMTCwgcmV0dXJuIC0xOyk7CglJUkRBX0FTU0VSVChwcml2LT5tYWdpYyA9PSBJUlRUWV9NQUdJQywgcmV0dXJuIC0xOyk7CgoJdHR5ID0gcHJpdi0+dHR5OwoJaWYgKCF0dHktPmRyaXZlci0+d3JpdGUpCgkJcmV0dXJuIDA7Cgl0dHktPmZsYWdzIHw9ICgxIDw8IFRUWV9ET19XUklURV9XQUtFVVApOwoJaWYgKHR0eS0+ZHJpdmVyLT53cml0ZV9yb29tKSB7CgkJd3JpdGVsZW4gPSB0dHktPmRyaXZlci0+d3JpdGVfcm9vbSh0dHkpOwoJCWlmICh3cml0ZWxlbiA+IGxlbikKCQkJd3JpdGVsZW4gPSBsZW47Cgl9CgllbHNlCgkJd3JpdGVsZW4gPSBsZW47CglyZXR1cm4gdHR5LT5kcml2ZXItPndyaXRlKHR0eSwgcHRyLCB3cml0ZWxlbik7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCi8qIGlyZGEgbGluZSBkaXNjaXBsaW5lIGNhbGxiYWNrcyAqLwoKLyogCiAqICBGdW5jdGlvbiBpcnR0eV9yZWNlaXZlX2J1ZiggdHR5LCBjcCwgY291bnQpCiAqCiAqICAgIEhhbmRsZSB0aGUgJ3JlY2VpdmVyIGRhdGEgcmVhZHknIGludGVycnVwdC4gIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkCiAqICAgIGJ5IHRoZSAndHR5X2lvJyBtb2R1bGUgaW4gdGhlIGtlcm5lbCB3aGVuIGEgYmxvY2sgb2YgSXJEQSBkYXRhIGhhcwogKiAgICBiZWVuIHJlY2VpdmVkLCB3aGljaCBjYW4gbm93IGJlIGRlY2Fwc3VsYXRlZCBhbmQgZGVsaXZlcmVkIGZvcgogKiAgICBmdXJ0aGVyIHByb2Nlc3NpbmcgCiAqCiAqIGNhbGxpbmcgY29udGV4dCBkZXBlbmRzIG9uIHVuZGVybHlpbmcgZHJpdmVyIGFuZCB0dHktPmxvd19sYXRlbmN5IQogKiBmb3IgZXhhbXBsZSAobG93X2xhdGVuY3k6IDEgLyAwKToKICogc2VyaWFsLmM6CXVhcnQtaW50ZXJydXB0IC8gc29mdGludAogKiB1c2JzZXJpYWw6CXVyYi1jb21wbGV0ZS1pbnRlcnJ1cHQgLyBzb2Z0aW50CiAqLwoKc3RhdGljIHZvaWQgaXJ0dHlfcmVjZWl2ZV9idWYoc3RydWN0IHR0eV9zdHJ1Y3QgKnR0eSwgY29uc3QgdW5zaWduZWQgY2hhciAqY3AsCgkJCSAgICAgIGNoYXIgKmZwLCBpbnQgY291bnQpIAp7CglzdHJ1Y3Qgc2lyX2RldiAqZGV2OwoJc3RydWN0IHNpcnR0eV9jYiAqcHJpdiA9IHR0eS0+ZGlzY19kYXRhOwoJaW50CWk7CgoJSVJEQV9BU1NFUlQocHJpdiAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHByaXYtPm1hZ2ljID09IElSVFRZX01BR0lDLCByZXR1cm47KTsKCglpZiAodW5saWtlbHkoY291bnQ9PTApKQkJLyogeWVzLCB0aGlzIGhhcHBlbnMgKi8KCQlyZXR1cm47CgoJZGV2ID0gcHJpdi0+ZGV2OwoJaWYgKCFkZXYpIHsKCQlJUkRBX1dBUk5JTkcoIiVzKCksIG5vdCByZWFkeSB5ZXQhXG4iLCBfX0ZVTkNUSU9OX18pOwoJCXJldHVybjsKCX0KCglmb3IgKGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewoJCS8qIAoJCSAqICBDaGFyYWN0ZXJzIHJlY2VpdmVkIHdpdGggYSBwYXJpdHkgZXJyb3IsIGV0Yz8KCQkgKi8KIAkJaWYgKGZwICYmICpmcCsrKSB7IAoJCQlJUkRBX0RFQlVHKDAsICJGcmFtaW5nIG9yIHBhcml0eSBlcnJvciFcbiIpOwoJCQlzaXJkZXZfcmVjZWl2ZShkZXYsIE5VTEwsIDApOwkvKiBub3RpZnkgc2lyX2RldiAodXBkYXRpbmcgc3RhdHMpICovCgkJCXJldHVybjsKIAkJfQoJfQoKCXNpcmRldl9yZWNlaXZlKGRldiwgY3AsIGNvdW50KTsKfQoKLyoKICogRnVuY3Rpb24gaXJ0dHlfd3JpdGVfd2FrZXVwICh0dHkpCiAqCiAqICAgIENhbGxlZCBieSB0aGUgZHJpdmVyIHdoZW4gdGhlcmUncyByb29tIGZvciBtb3JlIGRhdGEuICBJZiB3ZSBoYXZlCiAqICAgIG1vcmUgcGFja2V0cyB0byBzZW5kLCB3ZSBzZW5kIHRoZW0gaGVyZS4KICoKICovCnN0YXRpYyB2b2lkIGlydHR5X3dyaXRlX3dha2V1cChzdHJ1Y3QgdHR5X3N0cnVjdCAqdHR5KSAKewoJc3RydWN0IHNpcnR0eV9jYiAqcHJpdiA9IHR0eS0+ZGlzY19kYXRhOwoKCUlSREFfQVNTRVJUKHByaXYgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChwcml2LT5tYWdpYyA9PSBJUlRUWV9NQUdJQywgcmV0dXJuOyk7CgoJdHR5LT5mbGFncyAmPSB+KDEgPDwgVFRZX0RPX1dSSVRFX1dBS0VVUCk7CgoJaWYgKHByaXYtPmRldikKCQlzaXJkZXZfd3JpdGVfY29tcGxldGUocHJpdi0+ZGV2KTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKLyoKICogRnVuY3Rpb24gaXJ0dHlfc3RvcF9yZWNlaXZlciAodHR5LCBzdG9wKQogKgogKi8KCnN0YXRpYyBpbmxpbmUgdm9pZCBpcnR0eV9zdG9wX3JlY2VpdmVyKHN0cnVjdCB0dHlfc3RydWN0ICp0dHksIGludCBzdG9wKQp7CglzdHJ1Y3Qga3Rlcm1pb3Mgb2xkX3Rlcm1pb3M7CglpbnQgY2ZsYWc7CgoJbG9ja19rZXJuZWwoKTsKCW9sZF90ZXJtaW9zID0gKih0dHktPnRlcm1pb3MpOwoJY2ZsYWcgPSB0dHktPnRlcm1pb3MtPmNfY2ZsYWc7CgkKCWlmIChzdG9wKQoJCWNmbGFnICY9IH5DUkVBRDsKCWVsc2UKCQljZmxhZyB8PSBDUkVBRDsKCgl0dHktPnRlcm1pb3MtPmNfY2ZsYWcgPSBjZmxhZzsKCWlmICh0dHktPmRyaXZlci0+c2V0X3Rlcm1pb3MpCgkJdHR5LT5kcml2ZXItPnNldF90ZXJtaW9zKHR0eSwgJm9sZF90ZXJtaW9zKTsKCXVubG9ja19rZXJuZWwoKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyogc2VyaWFsaXplIGxkaXNjIG9wZW4vY2xvc2Ugd2l0aCBzaXJfZGV2ICovCnN0YXRpYyBERUZJTkVfTVVURVgoaXJ0dHlfbXV0ZXgpOwoKLyogbm90aWZpZXIgZnJvbSBzaXJfZGV2IHdoZW4gaXJkYSUgZGV2aWNlIGdldHMgb3BlbmVkIChpZnVwKSAqLwoKc3RhdGljIGludCBpcnR0eV9zdGFydF9kZXYoc3RydWN0IHNpcl9kZXYgKmRldikKewoJc3RydWN0IHNpcnR0eV9jYiAqcHJpdjsKCXN0cnVjdCB0dHlfc3RydWN0ICp0dHk7CgoJLyogc2VyaWFsaXplIHdpdGggbGRpc2Mgb3Blbi9jbG9zZSAqLwoJbXV0ZXhfbG9jaygmaXJ0dHlfbXV0ZXgpOwoKCXByaXYgPSBkZXYtPnByaXY7CglpZiAodW5saWtlbHkoIXByaXYgfHwgcHJpdi0+bWFnaWMhPUlSVFRZX01BR0lDKSkgewoJCW11dGV4X3VubG9jaygmaXJ0dHlfbXV0ZXgpOwoJCXJldHVybiAtRVNUQUxFOwoJfQoKCXR0eSA9IHByaXYtPnR0eTsKCglpZiAodHR5LT5kcml2ZXItPnN0YXJ0KQoJCXR0eS0+ZHJpdmVyLT5zdGFydCh0dHkpOwoJLyogTWFrZSBzdXJlIHdlIGNhbiByZWNlaXZlIG1vcmUgZGF0YSAqLwoJaXJ0dHlfc3RvcF9yZWNlaXZlcih0dHksIEZBTFNFKTsKCgltdXRleF91bmxvY2soJmlydHR5X211dGV4KTsKCXJldHVybiAwOwp9CgovKiBub3RpZmllciBmcm9tIHNpcl9kZXYgd2hlbiBpcmRhJSBkZXZpY2UgZ2V0cyBjbG9zZWQgKGlmZG93bikgKi8KCnN0YXRpYyBpbnQgaXJ0dHlfc3RvcF9kZXYoc3RydWN0IHNpcl9kZXYgKmRldikKewoJc3RydWN0IHNpcnR0eV9jYiAqcHJpdjsKCXN0cnVjdCB0dHlfc3RydWN0ICp0dHk7CgoJLyogc2VyaWFsaXplIHdpdGggbGRpc2Mgb3Blbi9jbG9zZSAqLwoJbXV0ZXhfbG9jaygmaXJ0dHlfbXV0ZXgpOwoKCXByaXYgPSBkZXYtPnByaXY7CglpZiAodW5saWtlbHkoIXByaXYgfHwgcHJpdi0+bWFnaWMhPUlSVFRZX01BR0lDKSkgewoJCW11dGV4X3VubG9jaygmaXJ0dHlfbXV0ZXgpOwoJCXJldHVybiAtRVNUQUxFOwoJfQoKCXR0eSA9IHByaXYtPnR0eTsKCgkvKiBNYWtlIHN1cmUgd2UgZG9uJ3QgcmVjZWl2ZSBtb3JlIGRhdGEgKi8KCWlydHR5X3N0b3BfcmVjZWl2ZXIodHR5LCBUUlVFKTsKCWlmICh0dHktPmRyaXZlci0+c3RvcCkKCQl0dHktPmRyaXZlci0+c3RvcCh0dHkpOwoKCW11dGV4X3VubG9jaygmaXJ0dHlfbXV0ZXgpOwoKCXJldHVybiAwOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpzdGF0aWMgc3RydWN0IHNpcl9kcml2ZXIgc2lyX3R0eV9kcnYgPSB7Cgkub3duZXIJCQk9IFRISVNfTU9EVUxFLAoJLmRyaXZlcl9uYW1lCQk9ICJzaXJfdHR5IiwKCS5zdGFydF9kZXYJCT0gaXJ0dHlfc3RhcnRfZGV2LAoJLnN0b3BfZGV2CQk9IGlydHR5X3N0b3BfZGV2LAoJLmRvX3dyaXRlCQk9IGlydHR5X2RvX3dyaXRlLAoJLmNoYXJzX2luX2J1ZmZlcgk9IGlydHR5X2NoYXJzX2luX2J1ZmZlciwKCS53YWl0X3VudGlsX3NlbnQJPSBpcnR0eV93YWl0X3VudGlsX3NlbnQsCgkuc2V0X3NwZWVkCQk9IGlydHR5X2NoYW5nZV9zcGVlZCwKCS5zZXRfZHRyX3J0cwkJPSBpcnR0eV9zZXRfZHRyX3J0cywKfTsKCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCi8qCiAqIEZ1bmN0aW9uIGlydHR5X2lvY3RsICh0dHksIGZpbGUsIGNtZCwgYXJnKQogKgogKiAgICAgVGhlIFN3aXNzIGFybXkga25pZmUgb2Ygc3lzdGVtIGNhbGxzIDotKQogKgogKi8Kc3RhdGljIGludCBpcnR0eV9pb2N0bChzdHJ1Y3QgdHR5X3N0cnVjdCAqdHR5LCBzdHJ1Y3QgZmlsZSAqZmlsZSwgdW5zaWduZWQgaW50IGNtZCwgdW5zaWduZWQgbG9uZyBhcmcpCnsKCXN0cnVjdCBpcnR0eV9pbmZvIHsgY2hhciBuYW1lWzZdOyB9IGluZm87CglzdHJ1Y3Qgc2lyX2RldiAqZGV2OwoJc3RydWN0IHNpcnR0eV9jYiAqcHJpdiA9IHR0eS0+ZGlzY19kYXRhOwoJaW50IGVyciA9IDA7CgoJSVJEQV9BU1NFUlQocHJpdiAhPSBOVUxMLCByZXR1cm4gLUVOT0RFVjspOwoJSVJEQV9BU1NFUlQocHJpdi0+bWFnaWMgPT0gSVJUVFlfTUFHSUMsIHJldHVybiAtRUJBRFI7KTsKCglJUkRBX0RFQlVHKDMsICIlcyhjbWQ9MHglWClcbiIsIF9fRlVOQ1RJT05fXywgY21kKTsKCglkZXYgPSBwcml2LT5kZXY7CglJUkRBX0FTU0VSVChkZXYgIT0gTlVMTCwgcmV0dXJuIC0xOyk7CgoJc3dpdGNoIChjbWQpIHsKCWNhc2UgVENHRVRTOgoJY2FzZSBUQ0dFVEE6CgkJZXJyID0gbl90dHlfaW9jdGwodHR5LCBmaWxlLCBjbWQsIGFyZyk7CgkJYnJlYWs7CgoJY2FzZSBJUlRUWV9JT0NURE9OR0xFOgoJCS8qIHRoaXMgY2FsbCBibG9ja3MgZm9yIGNvbXBsZXRpb24gKi8KCQllcnIgPSBzaXJkZXZfc2V0X2RvbmdsZShkZXYsIChJUkRBX0RPTkdMRSkgYXJnKTsKCQlicmVhazsKCgljYXNlIElSVFRZX0lPQ0dFVDoKCQlJUkRBX0FTU0VSVChkZXYtPm5ldGRldiAhPSBOVUxMLCByZXR1cm4gLTE7KTsKCgkJbWVtc2V0KCZpbmZvLCAwLCBzaXplb2YoaW5mbykpOyAKCQlzdHJuY3B5KGluZm8ubmFtZSwgZGV2LT5uZXRkZXYtPm5hbWUsIHNpemVvZihpbmZvLm5hbWUpLTEpOwoKCQlpZiAoY29weV90b191c2VyKCh2b2lkIF9fdXNlciAqKWFyZywgJmluZm8sIHNpemVvZihpbmZvKSkpCgkJCWVyciA9IC1FRkFVTFQ7CgkJYnJlYWs7CglkZWZhdWx0OgoJCWVyciA9IC1FTk9JT0NUTENNRDsKCQlicmVhazsKCX0KCXJldHVybiBlcnI7Cn0KCgovKiAKICogIEZ1bmN0aW9uIGlydHR5X29wZW4odHR5KQogKgogKiAgICBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBieSB0aGUgVFRZIG1vZHVsZSB3aGVuIHRoZSBJckRBIGxpbmUKICogICAgZGlzY2lwbGluZSBpcyBjYWxsZWQgZm9yLiAgQmVjYXVzZSB3ZSBhcmUgc3VyZSB0aGUgdHR5IGxpbmUgZXhpc3RzLAogKiAgICB3ZSBvbmx5IGhhdmUgdG8gbGluayBpdCB0byBhIGZyZWUgSXJEQSBjaGFubmVsLiAgCiAqLwpzdGF0aWMgaW50IGlydHR5X29wZW4oc3RydWN0IHR0eV9zdHJ1Y3QgKnR0eSkgCnsKCXN0cnVjdCBzaXJfZGV2ICpkZXY7CglzdHJ1Y3Qgc2lydHR5X2NiICpwcml2OwoJaW50IHJldCA9IDA7CgoJLyogTW9kdWxlIHN0dWZmIGhhbmRsZWQgdmlhIGlyZGFfbGRpc2Mub3duZXIgLSBKZWFuIElJICovCgoJLyogRmlyc3QgbWFrZSBzdXJlIHdlJ3JlIG5vdCBhbHJlYWR5IGNvbm5lY3RlZC4gKi8KCWlmICh0dHktPmRpc2NfZGF0YSAhPSBOVUxMKSB7CgkJcHJpdiA9IHR0eS0+ZGlzY19kYXRhOwoJCWlmIChwcml2ICYmIHByaXYtPm1hZ2ljID09IElSVFRZX01BR0lDKSB7CgkJCXJldCA9IC1FRVhJU1Q7CgkJCWdvdG8gb3V0OwoJCX0KCQl0dHktPmRpc2NfZGF0YSA9IE5VTEw7CQkvKiAjIyMgKi8KCX0KCgkvKiBzdG9wIHRoZSB1bmRlcmx5aW5nICBkcml2ZXIgKi8KCWlydHR5X3N0b3BfcmVjZWl2ZXIodHR5LCBUUlVFKTsKCWlmICh0dHktPmRyaXZlci0+c3RvcCkKCQl0dHktPmRyaXZlci0+c3RvcCh0dHkpOwoKCWlmICh0dHktPmRyaXZlci0+Zmx1c2hfYnVmZmVyKQoJCXR0eS0+ZHJpdmVyLT5mbHVzaF9idWZmZXIodHR5KTsKCQoJLyogYXBwbHkgbXR0IG92ZXJyaWRlICovCglzaXJfdHR5X2Rydi5xb3NfbXR0X2JpdHMgPSBxb3NfbXR0X2JpdHM7CgoJLyogZ2V0IGEgc2lyIGRldmljZSBpbnN0YW5jZSBmb3IgdGhpcyBkcml2ZXIgKi8KCWRldiA9IHNpcmRldl9nZXRfaW5zdGFuY2UoJnNpcl90dHlfZHJ2LCB0dHktPm5hbWUpOwoJaWYgKCFkZXYpIHsKCQlyZXQgPSAtRU5PREVWOwoJCWdvdG8gb3V0OwoJfQoKCS8qIGFsbG9jYXRlIHByaXZhdGUgZGV2aWNlIGluZm8gYmxvY2sgKi8KCXByaXYgPSBrbWFsbG9jKHNpemVvZigqcHJpdiksIEdGUF9LRVJORUwpOwoJaWYgKCFwcml2KQoJCWdvdG8gb3V0X3B1dDsKCW1lbXNldChwcml2LCAwLCBzaXplb2YoKnByaXYpKTsKCglwcml2LT5tYWdpYyA9IElSVFRZX01BR0lDOwoJcHJpdi0+dHR5ID0gdHR5OwoJcHJpdi0+ZGV2ID0gZGV2OwoKCS8qIHNlcmlhbGl6ZSB3aXRoIHN0YXJ0X2RldiAtIGluIGNhc2Ugd2Ugd2VyZSByYWNpbmcgd2l0aCBpZnVwICovCgltdXRleF9sb2NrKCZpcnR0eV9tdXRleCk7CgoJZGV2LT5wcml2ID0gcHJpdjsKCXR0eS0+ZGlzY19kYXRhID0gcHJpdjsKCXR0eS0+cmVjZWl2ZV9yb29tID0gNjU1MzY7CgoJbXV0ZXhfdW5sb2NrKCZpcnR0eV9tdXRleCk7CgoJSVJEQV9ERUJVRygwLCAiJXMgLSAlczogaXJkYSBsaW5lIGRpc2NpcGxpbmUgb3BlbmVkXG4iLCBfX0ZVTkNUSU9OX18sIHR0eS0+bmFtZSk7CgoJcmV0dXJuIDA7CgpvdXRfcHV0OgoJc2lyZGV2X3B1dF9pbnN0YW5jZShkZXYpOwpvdXQ6CglyZXR1cm4gcmV0Owp9CgovKiAKICogIEZ1bmN0aW9uIGlydHR5X2Nsb3NlICh0dHkpCiAqCiAqICAgIENsb3NlIGRvd24gYSBJckRBIGNoYW5uZWwuIFRoaXMgbWVhbnMgZmx1c2hpbmcgb3V0IGFueSBwZW5kaW5nIHF1ZXVlcywKICogICAgYW5kIHRoZW4gcmVzdG9yaW5nIHRoZSBUVFkgbGluZSBkaXNjaXBsaW5lIHRvIHdoYXQgaXQgd2FzIGJlZm9yZSBpdCBnb3QKICogICAgaG9va2VkIHRvIElyREEgKHdoaWNoIHVzdWFsbHkgaXMgVFRZIGFnYWluKS4gIAogKi8Kc3RhdGljIHZvaWQgaXJ0dHlfY2xvc2Uoc3RydWN0IHR0eV9zdHJ1Y3QgKnR0eSkgCnsKCXN0cnVjdCBzaXJ0dHlfY2IgKnByaXYgPSB0dHktPmRpc2NfZGF0YTsKCglJUkRBX0FTU0VSVChwcml2ICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQocHJpdi0+bWFnaWMgPT0gSVJUVFlfTUFHSUMsIHJldHVybjspOwoKCS8qIEhtLCB3aXRoIGEgZG9uZ2xlIGF0dGFjaGVkIHRoZSBkb25nbGUgZHJpdmVyIHdhbnRzCgkgKiB0byBjbG9zZSB0aGUgZG9uZ2xlIC0gd2hpY2ggcmVxdWlyZXMgdGhlIHVzZSBvZgoJICogc29tZSB0dHkgd3JpdGUgYW5kL29yIHRlcm1pb3Mgb3IgaW9jdGwgb3BlcmF0aW9ucy4KCSAqIEFyZSB3ZSBhbGxvd2VkIHRvIGNhbGwgdGhvc2Ugd2hlbiBhbHJlYWR5IHJlcXVlc3RlZAoJICogdG8gc2h1dGRvd24gdGhlIGxkaXNjPwoJICogSWYgbm90LCB3ZSBzaG91bGQgc29tZWhvdyBtYXJrIHRoZSBkZXYgYmVpbmcgc3RhbGVkLgoJICogUXVlc3Rpb24gcmVtYWlucywgaG93IHRvIGNsb3NlIHRoZSBkb25nbGUgaW4gdGhpcyBjYXNlLi4uCgkgKiBGb3Igbm93IGxldCdzIGFzc3VtZSB3ZSBhcmUgZ3JhbnRlZCB0byBpc3N1ZSB0dHkgZHJpdmVyIGNhbGxzCgkgKiB1bnRpbCB3ZSByZXR1cm4gaGVyZSBmcm9tIHRoZSBsZGlzYyBjbG9zZS4gSSdtIGp1c3Qgd29uZGVyaW5nCgkgKiBob3cgdGhpcyBiZWhhdmVzIHdpdGggaG90cGx1Z2dhYmxlIHNlcmlhbCBoYXJkd2FyZSBsaWtlCgkgKiByczIzMi1wY21jaWEgY2FyZCBvciB1c2Itc2VyaWFsLi4uCgkgKgoJICogcHJpdi0+dHR5ID0gTlVMTD87CgkgKi8KCgkvKiB3ZSBhcmUgZGVhZCBub3cgKi8KCXR0eS0+ZGlzY19kYXRhID0gTlVMTDsKCglzaXJkZXZfcHV0X2luc3RhbmNlKHByaXYtPmRldik7CgoJLyogU3RvcCB0dHkgKi8KCWlydHR5X3N0b3BfcmVjZWl2ZXIodHR5LCBUUlVFKTsKCXR0eS0+ZmxhZ3MgJj0gfigxIDw8IFRUWV9ET19XUklURV9XQUtFVVApOwoJaWYgKHR0eS0+ZHJpdmVyLT5zdG9wKQoJCXR0eS0+ZHJpdmVyLT5zdG9wKHR0eSk7CgoJa2ZyZWUocHJpdik7CgoJSVJEQV9ERUJVRygwLCAiJXMgLSAlczogaXJkYSBsaW5lIGRpc2NpcGxpbmUgY2xvc2VkXG4iLCBfX0ZVTkNUSU9OX18sIHR0eS0+bmFtZSk7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCnN0YXRpYyBzdHJ1Y3QgdHR5X2xkaXNjIGlyZGFfbGRpc2MgPSB7CgkubWFnaWMJCT0gVFRZX0xESVNDX01BR0lDLAogCS5uYW1lCQk9ICJpcmRhIiwKCS5mbGFncwkJPSAwLAoJLm9wZW4JCT0gaXJ0dHlfb3BlbiwKCS5jbG9zZQkJPSBpcnR0eV9jbG9zZSwKCS5yZWFkCQk9IE5VTEwsCgkud3JpdGUJCT0gTlVMTCwKCS5pb2N0bAkJPSBpcnR0eV9pb2N0bCwKIAkucG9sbAkJPSBOVUxMLAoJLnJlY2VpdmVfYnVmCT0gaXJ0dHlfcmVjZWl2ZV9idWYsCgkud3JpdGVfd2FrZXVwCT0gaXJ0dHlfd3JpdGVfd2FrZXVwLAoJLm93bmVyCQk9IFRISVNfTU9EVUxFLAp9OwoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKc3RhdGljIGludCBfX2luaXQgaXJ0dHlfc2lyX2luaXQodm9pZCkKewoJaW50IGVycjsKCglpZiAoKGVyciA9IHR0eV9yZWdpc3Rlcl9sZGlzYyhOX0lSREEsICZpcmRhX2xkaXNjKSkgIT0gMCkKCQlJUkRBX0VSUk9SKCJJckRBOiBjYW4ndCByZWdpc3RlciBsaW5lIGRpc2NpcGxpbmUgKGVyciA9ICVkKVxuIiwKCQkJICAgZXJyKTsKCXJldHVybiBlcnI7Cn0KCnN0YXRpYyB2b2lkIF9fZXhpdCBpcnR0eV9zaXJfY2xlYW51cCh2b2lkKSAKewoJaW50IGVycjsKCglpZiAoKGVyciA9IHR0eV91bnJlZ2lzdGVyX2xkaXNjKE5fSVJEQSkpKSB7CgkJSVJEQV9FUlJPUigiJXMoKSwgY2FuJ3QgdW5yZWdpc3RlciBsaW5lIGRpc2NpcGxpbmUgKGVyciA9ICVkKVxuIiwKCQkJICAgX19GVU5DVElPTl9fLCBlcnIpOwoJfQp9Cgptb2R1bGVfaW5pdChpcnR0eV9zaXJfaW5pdCk7Cm1vZHVsZV9leGl0KGlydHR5X3Npcl9jbGVhbnVwKTsKCk1PRFVMRV9BVVRIT1IoIkRhZyBCcmF0dGxpIDxkYWdiQGNzLnVpdC5ubz4iKTsKTU9EVUxFX0RFU0NSSVBUSU9OKCJJckRBIFRUWSBkZXZpY2UgZHJpdmVyIik7Ck1PRFVMRV9BTElBU19MRElTQyhOX0lSREEpOwpNT0RVTEVfTElDRU5TRSgiR1BMIik7Cgo=