LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgICAKICogRmlsZW5hbWU6ICAgICAgaXJ0dHktc2lyLmMKICogVmVyc2lvbjogICAgICAgMi4wCiAqIERlc2NyaXB0aW9uOiAgIElyREEgbGluZSBkaXNjaXBsaW5lIGltcGxlbWVudGF0aW9uCiAqIFN0YXR1czogICAgICAgIEV4cGVyaW1lbnRhbC4KICogQXV0aG9yOiAgICAgICAgRGFnIEJyYXR0bGkgPGRhZ2JAY3MudWl0Lm5vPgogKiBDcmVhdGVkIGF0OiAgICBUdWUgRGVjICA5IDIxOjE4OjM4IDE5OTcKICogTW9kaWZpZWQgYXQ6ICAgU3VuIE9jdCAyNyAyMjoxMzozMCAyMDAyCiAqIE1vZGlmaWVkIGJ5OiAgIE1hcnRpbiBEaWVobCA8bWFkQG1kaWVobC5kZT4KICogU291cmNlczogICAgICAgc2xpcC5jIGJ5IExhdXJlbmNlIEN1bGhhbmUsICAgPGxvekBob2xtZXMuZGVtb24uY28udWs+CiAqICAgICAgICAgICAgICAgICAgICAgICAgICBGcmVkIE4uIHZhbiBLZW1wZW4sIDx3YWx0amVAdXdhbHQubmwubXVnbmV0Lm9yZz4KICogCiAqICAgICBDb3B5cmlnaHQgKGMpIDE5OTgtMjAwMCBEYWcgQnJhdHRsaSwKICogICAgIENvcHlyaWdodCAoYykgMjAwMiBNYXJ0aW4gRGllaGwsCiAqICAgICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiAgICAgIAogKiAgICAgVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciAKICogICAgIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIAogKiAgICAgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgCiAqICAgICB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICogIAogKiAgICAgTmVpdGhlciBEYWcgQnJhdHRsaSBub3IgVW5pdmVyc2l0eSBvZiBUcm9tc/ggYWRtaXQgbGlhYmlsaXR5IG5vcgogKiAgICAgcHJvdmlkZSB3YXJyYW50eSBmb3IgYW55IG9mIHRoaXMgc29mdHdhcmUuIFRoaXMgbWF0ZXJpYWwgaXMgCiAqICAgICBwcm92aWRlZCAiQVMtSVMiIGFuZCBhdCBubyBjaGFyZ2UuCiAqICAgICAKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLyAgICAKCiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgojaW5jbHVkZSA8bGludXgvdHR5Lmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxhc20vdWFjY2Vzcy5oPgojaW5jbHVkZSA8bGludXgvc21wX2xvY2suaD4KI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+CiNpbmNsdWRlIDxsaW51eC9tdXRleC5oPgoKI2luY2x1ZGUgPG5ldC9pcmRhL2lyZGEuaD4KI2luY2x1ZGUgPG5ldC9pcmRhL2lyZGFfZGV2aWNlLmg+CgojaW5jbHVkZSAic2lyLWRldi5oIgojaW5jbHVkZSAiaXJ0dHktc2lyLmgiCgpzdGF0aWMgaW50IHFvc19tdHRfYml0cyA9IDB4MDM7ICAgICAgLyogNSBtcyBvciBtb3JlICovCgptb2R1bGVfcGFyYW0ocW9zX210dF9iaXRzLCBpbnQsIDApOwpNT0RVTEVfUEFSTV9ERVNDKHFvc19tdHRfYml0cywgIk1pbmltdW0gVHVybiBUaW1lIik7CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKiBkZXZpY2UgY29uZmlndXJhdGlvbiBjYWxsYmFja3MgYWx3YXlzIGludm9rZWQgd2l0aCBpcmRhLXRocmVhZCBjb250ZXh0ICovCgovKiBmaW5kIG91dCwgaG93IG1hbnkgY2hhcnMgd2UgaGF2ZSBpbiBidWZmZXJzIGJlbG93IHVzCiAqIHRoaXMgaXMgYWxsb3dlZCB0byBsaWUsIGkuZS4gcmV0dXJuIGxlc3MgY2hhcnMgdGhhbiB3ZQogKiBhY3R1YWxseSBoYXZlLiBUaGUgcmV0dXJuZWQgdmFsdWUgaXMgdXNlZCB0byBkZXRlcm1pbmUKICogaG93IGxvbmcgdGhlIGlyZGF0aHJlYWQgc2hvdWxkIHdhaXQgYmVmb3JlIGRvaW5nIHRoZQogKiByZWFsIGJsb2NraW5nIHdhaXRfdW50aWxfc2VudCgpCiAqLwoKc3RhdGljIGludCBpcnR0eV9jaGFyc19pbl9idWZmZXIoc3RydWN0IHNpcl9kZXYgKmRldikKewoJc3RydWN0IHNpcnR0eV9jYiAqcHJpdiA9IGRldi0+cHJpdjsKCglJUkRBX0FTU0VSVChwcml2ICE9IE5VTEwsIHJldHVybiAtMTspOwoJSVJEQV9BU1NFUlQocHJpdi0+bWFnaWMgPT0gSVJUVFlfTUFHSUMsIHJldHVybiAtMTspOwoKCXJldHVybiBwcml2LT50dHktPmRyaXZlci0+Y2hhcnNfaW5fYnVmZmVyKHByaXYtPnR0eSk7Cn0KCi8qIFdhaXQgKHNsZWVwKSB1bnRpbCB1bmRlcmxheWluZyBoYXJkd2FyZSBmaW5pc2hlZCB0cmFuc21pc3Npb24KICogaS5lLiBoYXJkd2FyZSBidWZmZXJzIGFyZSBkcmFpbmVkCiAqIHRoaXMgbXVzdCBibG9jayBhbmQgbm90IHJldHVybiBiZWZvcmUgYWxsIGNoYXJhY3RlcnMgYXJlIHJlYWxseSBzZW50CiAqCiAqIElmIHRoZSB0dHkgc2l0cyBvbiB0b3Agb2YgYSAxNjU1MEEtbGlrZSB1YXJ0LCB0aGVyZSBhcmUgdHlwaWNhbGx5CiAqIHVwIHRvIDE2IGJ5dGVzIGluIHRoZSBmaWZvIC0gZi5lLiA5NjAwIGJwcyA4TjEgbmVlZHMgMTYuNyBtc2VjCiAqCiAqIFdpdGggdXNic2VyaWFsIHRoZSB1YXJ0LWZpZm8gaXMgYmFzaWNhbGx5IHJlcGxhY2VkIGJ5IHRoZSBjb252ZXJ0ZXIncwogKiBvdXRnb2luZyBlbmRwb2ludCBidWZmZXIsIHdoaWNoIGNhbiB1c3VhbGx5IGhvbGQgNjQgYnl0ZXMgKGF0IGxlYXN0KS4KICogV2l0aCBwbDIzMDMgaXQgYXBwZWFycyB3ZSBhcmUgc2FmZSB3aXRoIDYwbXNlYyBoZXJlLgogKgogKiBJIHJlYWxseSB3aXNoIGFsbCBzZXJpYWwgZHJpdmVycyB3b3VsZCBwcm92aWRlCiAqIGNvcnJlY3QgaW1wbGVtZW50YXRpb24gb2Ygd2FpdF91bnRpbF9zZW50KCkKICovCgojZGVmaW5lIFVTQlNFUklBTF9UWF9ET05FX0RFTEFZCTYwCgpzdGF0aWMgdm9pZCBpcnR0eV93YWl0X3VudGlsX3NlbnQoc3RydWN0IHNpcl9kZXYgKmRldikKewoJc3RydWN0IHNpcnR0eV9jYiAqcHJpdiA9IGRldi0+cHJpdjsKCXN0cnVjdCB0dHlfc3RydWN0ICp0dHk7CgoJSVJEQV9BU1NFUlQocHJpdiAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHByaXYtPm1hZ2ljID09IElSVFRZX01BR0lDLCByZXR1cm47KTsKCgl0dHkgPSBwcml2LT50dHk7CglpZiAodHR5LT5kcml2ZXItPndhaXRfdW50aWxfc2VudCkgewoJCWxvY2tfa2VybmVsKCk7CgkJdHR5LT5kcml2ZXItPndhaXRfdW50aWxfc2VudCh0dHksIG1zZWNzX3RvX2ppZmZpZXMoMTAwKSk7CgkJdW5sb2NrX2tlcm5lbCgpOwoJfQoJZWxzZSB7CgkJbXNsZWVwKFVTQlNFUklBTF9UWF9ET05FX0RFTEFZKTsKCX0KfQoKLyogCiAqICBGdW5jdGlvbiBpcnR0eV9jaGFuZ2Vfc3BlZWQgKGRldiwgc3BlZWQpCiAqCiAqICAgIENoYW5nZSB0aGUgc3BlZWQgb2YgdGhlIHNlcmlhbCBwb3J0LgogKgogKiBUaGlzIG1heSBzbGVlcCBpbiBzZXRfdGVybWlvcyAodXNic2VyaWFsIGRyaXZlciBmLmUuKSBhbmQgbXVzdAogKiBub3QgYmUgY2FsbGVkIGZyb20gaW50ZXJydXB0L3RpbWVyL3Rhc2tsZXQgdGhlcmVmb3JlLgogKiBBbGwgc3VjaCBpbnZvY2F0aW9ucyBhcmUgZGVmZXJyZWQgdG8ga0lyREFkIG5vdyBzbyB3ZSBjYW4gc2xlZXAgdGhlcmUuCiAqLwoKc3RhdGljIGludCBpcnR0eV9jaGFuZ2Vfc3BlZWQoc3RydWN0IHNpcl9kZXYgKmRldiwgdW5zaWduZWQgc3BlZWQpCnsKCXN0cnVjdCBzaXJ0dHlfY2IgKnByaXYgPSBkZXYtPnByaXY7CglzdHJ1Y3QgdHR5X3N0cnVjdCAqdHR5OwogICAgICAgIHN0cnVjdCB0ZXJtaW9zIG9sZF90ZXJtaW9zOwoJaW50IGNmbGFnOwoKCUlSREFfQVNTRVJUKHByaXYgIT0gTlVMTCwgcmV0dXJuIC0xOyk7CglJUkRBX0FTU0VSVChwcml2LT5tYWdpYyA9PSBJUlRUWV9NQUdJQywgcmV0dXJuIC0xOyk7CgoJdHR5ID0gcHJpdi0+dHR5OwoKCWxvY2tfa2VybmVsKCk7CglvbGRfdGVybWlvcyA9ICoodHR5LT50ZXJtaW9zKTsKCWNmbGFnID0gdHR5LT50ZXJtaW9zLT5jX2NmbGFnOwoKCWNmbGFnICY9IH5DQkFVRDsKCglJUkRBX0RFQlVHKDIsICIlcygpLCBTZXR0aW5nIHNwZWVkIHRvICVkXG4iLCBfX0ZVTkNUSU9OX18sIHNwZWVkKTsKCglzd2l0Y2ggKHNwZWVkKSB7CgljYXNlIDEyMDA6CgkJY2ZsYWcgfD0gQjEyMDA7CgkJYnJlYWs7CgljYXNlIDI0MDA6CgkJY2ZsYWcgfD0gQjI0MDA7CgkJYnJlYWs7CgljYXNlIDQ4MDA6CgkJY2ZsYWcgfD0gQjQ4MDA7CgkJYnJlYWs7CgljYXNlIDE5MjAwOgoJCWNmbGFnIHw9IEIxOTIwMDsKCQlicmVhazsKCWNhc2UgMzg0MDA6CgkJY2ZsYWcgfD0gQjM4NDAwOwoJCWJyZWFrOwoJY2FzZSA1NzYwMDoKCQljZmxhZyB8PSBCNTc2MDA7CgkJYnJlYWs7CgljYXNlIDExNTIwMDoKCQljZmxhZyB8PSBCMTE1MjAwOwoJCWJyZWFrOwoJY2FzZSA5NjAwOgoJZGVmYXVsdDoKCQljZmxhZyB8PSBCOTYwMDsKCQlicmVhazsKCX0JCgoJdHR5LT50ZXJtaW9zLT5jX2NmbGFnID0gY2ZsYWc7CglpZiAodHR5LT5kcml2ZXItPnNldF90ZXJtaW9zKQoJCXR0eS0+ZHJpdmVyLT5zZXRfdGVybWlvcyh0dHksICZvbGRfdGVybWlvcyk7Cgl1bmxvY2tfa2VybmVsKCk7CgoJcHJpdi0+aW8uc3BlZWQgPSBzcGVlZDsKCglyZXR1cm4gMDsKfQoKLyoKICogRnVuY3Rpb24gaXJ0dHlfc2V0X2R0cl9ydHMgKGRldiwgZHRyLCBydHMpCiAqCiAqICAgIFRoaXMgZnVuY3Rpb24gY2FuIGJlIHVzZWQgYnkgZG9uZ2xlcyBldGMuIHRvIHNldCBvciByZXNldCB0aGUgc3RhdHVzCiAqICAgIG9mIHRoZSBkdHIgYW5kIHJ0cyBsaW5lcwogKi8KCnN0YXRpYyBpbnQgaXJ0dHlfc2V0X2R0cl9ydHMoc3RydWN0IHNpcl9kZXYgKmRldiwgaW50IGR0ciwgaW50IHJ0cykKewoJc3RydWN0IHNpcnR0eV9jYiAqcHJpdiA9IGRldi0+cHJpdjsKCWludCBzZXQgPSAwOwoJaW50IGNsZWFyID0gMDsKCglJUkRBX0FTU0VSVChwcml2ICE9IE5VTEwsIHJldHVybiAtMTspOwoJSVJEQV9BU1NFUlQocHJpdi0+bWFnaWMgPT0gSVJUVFlfTUFHSUMsIHJldHVybiAtMTspOwoKCWlmIChydHMpCgkJc2V0IHw9IFRJT0NNX1JUUzsKCWVsc2UKCQljbGVhciB8PSBUSU9DTV9SVFM7CglpZiAoZHRyKQoJCXNldCB8PSBUSU9DTV9EVFI7CgllbHNlCgkJY2xlYXIgfD0gVElPQ01fRFRSOwoKCS8qCgkgKiBXZSBjYW4ndCB1c2UgaW9jdGwoKSBiZWNhdXNlIGl0IGV4cGVjdHMgYSBub24tbnVsbCBmaWxlIHN0cnVjdHVyZSwKCSAqIGFuZCB3ZSBkb24ndCBoYXZlIHRoYXQgaGVyZS4KCSAqIFRoaXMgZnVuY3Rpb24gaXMgbm90IHlldCBkZWZpbmVkIGZvciBhbGwgdHR5IGRyaXZlciwgc28KCSAqIGxldCdzIGJlIGNhcmVmdWwuLi4gSmVhbiBJSQoJICovCglJUkRBX0FTU0VSVChwcml2LT50dHktPmRyaXZlci0+dGlvY21zZXQgIT0gTlVMTCwgcmV0dXJuIC0xOyk7Cglwcml2LT50dHktPmRyaXZlci0+dGlvY21zZXQocHJpdi0+dHR5LCBOVUxMLCBzZXQsIGNsZWFyKTsKCglyZXR1cm4gMDsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKLyogY2FsbGVkIGZyb20gc2lyX2RldiB3aGVuIHRoZXJlIGlzIG1vcmUgZGF0YSB0byBzZW5kCiAqIGNvbnRleHQgaXMgZWl0aGVyIG5ldGRldi0+aGFyZF94bWl0IG9yIHNvbWUgdHJhbnNtaXQtY29tcGxldGlvbiBiaAogKiBpLmUuIHdlIGFyZSB1bmRlciBzcGlubG9jayBoZXJlIGFuZCBtdXN0IG5vdCBzbGVlcC4KICovCgpzdGF0aWMgaW50IGlydHR5X2RvX3dyaXRlKHN0cnVjdCBzaXJfZGV2ICpkZXYsIGNvbnN0IHVuc2lnbmVkIGNoYXIgKnB0ciwgc2l6ZV90IGxlbikKewoJc3RydWN0IHNpcnR0eV9jYiAqcHJpdiA9IGRldi0+cHJpdjsKCXN0cnVjdCB0dHlfc3RydWN0ICp0dHk7CglpbnQgd3JpdGVsZW47CgoJSVJEQV9BU1NFUlQocHJpdiAhPSBOVUxMLCByZXR1cm4gLTE7KTsKCUlSREFfQVNTRVJUKHByaXYtPm1hZ2ljID09IElSVFRZX01BR0lDLCByZXR1cm4gLTE7KTsKCgl0dHkgPSBwcml2LT50dHk7CglpZiAoIXR0eS0+ZHJpdmVyLT53cml0ZSkKCQlyZXR1cm4gMDsKCXR0eS0+ZmxhZ3MgfD0gKDEgPDwgVFRZX0RPX1dSSVRFX1dBS0VVUCk7CglpZiAodHR5LT5kcml2ZXItPndyaXRlX3Jvb20pIHsKCQl3cml0ZWxlbiA9IHR0eS0+ZHJpdmVyLT53cml0ZV9yb29tKHR0eSk7CgkJaWYgKHdyaXRlbGVuID4gbGVuKQoJCQl3cml0ZWxlbiA9IGxlbjsKCX0KCWVsc2UKCQl3cml0ZWxlbiA9IGxlbjsKCXJldHVybiB0dHktPmRyaXZlci0+d3JpdGUodHR5LCBwdHIsIHdyaXRlbGVuKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKLyogaXJkYSBsaW5lIGRpc2NpcGxpbmUgY2FsbGJhY2tzICovCgovKiAKICogIEZ1bmN0aW9uIGlydHR5X3JlY2VpdmVfYnVmKCB0dHksIGNwLCBjb3VudCkKICoKICogICAgSGFuZGxlIHRoZSAncmVjZWl2ZXIgZGF0YSByZWFkeScgaW50ZXJydXB0LiAgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQKICogICAgYnkgdGhlICd0dHlfaW8nIG1vZHVsZSBpbiB0aGUga2VybmVsIHdoZW4gYSBibG9jayBvZiBJckRBIGRhdGEgaGFzCiAqICAgIGJlZW4gcmVjZWl2ZWQsIHdoaWNoIGNhbiBub3cgYmUgZGVjYXBzdWxhdGVkIGFuZCBkZWxpdmVyZWQgZm9yCiAqICAgIGZ1cnRoZXIgcHJvY2Vzc2luZyAKICoKICogY2FsbGluZyBjb250ZXh0IGRlcGVuZHMgb24gdW5kZXJseWluZyBkcml2ZXIgYW5kIHR0eS0+bG93X2xhdGVuY3khCiAqIGZvciBleGFtcGxlIChsb3dfbGF0ZW5jeTogMSAvIDApOgogKiBzZXJpYWwuYzoJdWFydC1pbnRlcnJ1cHQgLyBzb2Z0aW50CiAqIHVzYnNlcmlhbDoJdXJiLWNvbXBsZXRlLWludGVycnVwdCAvIHNvZnRpbnQKICovCgpzdGF0aWMgdm9pZCBpcnR0eV9yZWNlaXZlX2J1ZihzdHJ1Y3QgdHR5X3N0cnVjdCAqdHR5LCBjb25zdCB1bnNpZ25lZCBjaGFyICpjcCwKCQkJICAgICAgY2hhciAqZnAsIGludCBjb3VudCkgCnsKCXN0cnVjdCBzaXJfZGV2ICpkZXY7CglzdHJ1Y3Qgc2lydHR5X2NiICpwcml2ID0gdHR5LT5kaXNjX2RhdGE7CglpbnQJaTsKCglJUkRBX0FTU0VSVChwcml2ICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQocHJpdi0+bWFnaWMgPT0gSVJUVFlfTUFHSUMsIHJldHVybjspOwoKCWlmICh1bmxpa2VseShjb3VudD09MCkpCQkvKiB5ZXMsIHRoaXMgaGFwcGVucyAqLwoJCXJldHVybjsKCglkZXYgPSBwcml2LT5kZXY7CglpZiAoIWRldikgewoJCUlSREFfV0FSTklORygiJXMoKSwgbm90IHJlYWR5IHlldCFcbiIsIF9fRlVOQ1RJT05fXyk7CgkJcmV0dXJuOwoJfQoKCWZvciAoaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7CgkJLyogCgkJICogIENoYXJhY3RlcnMgcmVjZWl2ZWQgd2l0aCBhIHBhcml0eSBlcnJvciwgZXRjPwoJCSAqLwogCQlpZiAoZnAgJiYgKmZwKyspIHsgCgkJCUlSREFfREVCVUcoMCwgIkZyYW1pbmcgb3IgcGFyaXR5IGVycm9yIVxuIik7CgkJCXNpcmRldl9yZWNlaXZlKGRldiwgTlVMTCwgMCk7CS8qIG5vdGlmeSBzaXJfZGV2ICh1cGRhdGluZyBzdGF0cykgKi8KCQkJcmV0dXJuOwogCQl9Cgl9CgoJc2lyZGV2X3JlY2VpdmUoZGV2LCBjcCwgY291bnQpOwp9CgovKgogKiBGdW5jdGlvbiBpcnR0eV93cml0ZV93YWtldXAgKHR0eSkKICoKICogICAgQ2FsbGVkIGJ5IHRoZSBkcml2ZXIgd2hlbiB0aGVyZSdzIHJvb20gZm9yIG1vcmUgZGF0YS4gIElmIHdlIGhhdmUKICogICAgbW9yZSBwYWNrZXRzIHRvIHNlbmQsIHdlIHNlbmQgdGhlbSBoZXJlLgogKgogKi8Kc3RhdGljIHZvaWQgaXJ0dHlfd3JpdGVfd2FrZXVwKHN0cnVjdCB0dHlfc3RydWN0ICp0dHkpIAp7CglzdHJ1Y3Qgc2lydHR5X2NiICpwcml2ID0gdHR5LT5kaXNjX2RhdGE7CgoJSVJEQV9BU1NFUlQocHJpdiAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHByaXYtPm1hZ2ljID09IElSVFRZX01BR0lDLCByZXR1cm47KTsKCgl0dHktPmZsYWdzICY9IH4oMSA8PCBUVFlfRE9fV1JJVEVfV0FLRVVQKTsKCglpZiAocHJpdi0+ZGV2KQoJCXNpcmRldl93cml0ZV9jb21wbGV0ZShwcml2LT5kZXYpOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKgogKiBGdW5jdGlvbiBpcnR0eV9zdG9wX3JlY2VpdmVyICh0dHksIHN0b3ApCiAqCiAqLwoKc3RhdGljIGlubGluZSB2b2lkIGlydHR5X3N0b3BfcmVjZWl2ZXIoc3RydWN0IHR0eV9zdHJ1Y3QgKnR0eSwgaW50IHN0b3ApCnsKCXN0cnVjdCB0ZXJtaW9zIG9sZF90ZXJtaW9zOwoJaW50IGNmbGFnOwoKCWxvY2tfa2VybmVsKCk7CglvbGRfdGVybWlvcyA9ICoodHR5LT50ZXJtaW9zKTsKCWNmbGFnID0gdHR5LT50ZXJtaW9zLT5jX2NmbGFnOwoJCglpZiAoc3RvcCkKCQljZmxhZyAmPSB+Q1JFQUQ7CgllbHNlCgkJY2ZsYWcgfD0gQ1JFQUQ7CgoJdHR5LT50ZXJtaW9zLT5jX2NmbGFnID0gY2ZsYWc7CglpZiAodHR5LT5kcml2ZXItPnNldF90ZXJtaW9zKQoJCXR0eS0+ZHJpdmVyLT5zZXRfdGVybWlvcyh0dHksICZvbGRfdGVybWlvcyk7Cgl1bmxvY2tfa2VybmVsKCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qIHNlcmlhbGl6ZSBsZGlzYyBvcGVuL2Nsb3NlIHdpdGggc2lyX2RldiAqLwpzdGF0aWMgREVGSU5FX01VVEVYKGlydHR5X211dGV4KTsKCi8qIG5vdGlmaWVyIGZyb20gc2lyX2RldiB3aGVuIGlyZGElIGRldmljZSBnZXRzIG9wZW5lZCAoaWZ1cCkgKi8KCnN0YXRpYyBpbnQgaXJ0dHlfc3RhcnRfZGV2KHN0cnVjdCBzaXJfZGV2ICpkZXYpCnsKCXN0cnVjdCBzaXJ0dHlfY2IgKnByaXY7CglzdHJ1Y3QgdHR5X3N0cnVjdCAqdHR5OwoKCS8qIHNlcmlhbGl6ZSB3aXRoIGxkaXNjIG9wZW4vY2xvc2UgKi8KCW11dGV4X2xvY2soJmlydHR5X211dGV4KTsKCglwcml2ID0gZGV2LT5wcml2OwoJaWYgKHVubGlrZWx5KCFwcml2IHx8IHByaXYtPm1hZ2ljIT1JUlRUWV9NQUdJQykpIHsKCQltdXRleF91bmxvY2soJmlydHR5X211dGV4KTsKCQlyZXR1cm4gLUVTVEFMRTsKCX0KCgl0dHkgPSBwcml2LT50dHk7CgoJaWYgKHR0eS0+ZHJpdmVyLT5zdGFydCkKCQl0dHktPmRyaXZlci0+c3RhcnQodHR5KTsKCS8qIE1ha2Ugc3VyZSB3ZSBjYW4gcmVjZWl2ZSBtb3JlIGRhdGEgKi8KCWlydHR5X3N0b3BfcmVjZWl2ZXIodHR5LCBGQUxTRSk7CgoJbXV0ZXhfdW5sb2NrKCZpcnR0eV9tdXRleCk7CglyZXR1cm4gMDsKfQoKLyogbm90aWZpZXIgZnJvbSBzaXJfZGV2IHdoZW4gaXJkYSUgZGV2aWNlIGdldHMgY2xvc2VkIChpZmRvd24pICovCgpzdGF0aWMgaW50IGlydHR5X3N0b3BfZGV2KHN0cnVjdCBzaXJfZGV2ICpkZXYpCnsKCXN0cnVjdCBzaXJ0dHlfY2IgKnByaXY7CglzdHJ1Y3QgdHR5X3N0cnVjdCAqdHR5OwoKCS8qIHNlcmlhbGl6ZSB3aXRoIGxkaXNjIG9wZW4vY2xvc2UgKi8KCW11dGV4X2xvY2soJmlydHR5X211dGV4KTsKCglwcml2ID0gZGV2LT5wcml2OwoJaWYgKHVubGlrZWx5KCFwcml2IHx8IHByaXYtPm1hZ2ljIT1JUlRUWV9NQUdJQykpIHsKCQltdXRleF91bmxvY2soJmlydHR5X211dGV4KTsKCQlyZXR1cm4gLUVTVEFMRTsKCX0KCgl0dHkgPSBwcml2LT50dHk7CgoJLyogTWFrZSBzdXJlIHdlIGRvbid0IHJlY2VpdmUgbW9yZSBkYXRhICovCglpcnR0eV9zdG9wX3JlY2VpdmVyKHR0eSwgVFJVRSk7CglpZiAodHR5LT5kcml2ZXItPnN0b3ApCgkJdHR5LT5kcml2ZXItPnN0b3AodHR5KTsKCgltdXRleF91bmxvY2soJmlydHR5X211dGV4KTsKCglyZXR1cm4gMDsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKc3RhdGljIHN0cnVjdCBzaXJfZHJpdmVyIHNpcl90dHlfZHJ2ID0gewoJLm93bmVyCQkJPSBUSElTX01PRFVMRSwKCS5kcml2ZXJfbmFtZQkJPSAic2lyX3R0eSIsCgkuc3RhcnRfZGV2CQk9IGlydHR5X3N0YXJ0X2RldiwKCS5zdG9wX2RldgkJPSBpcnR0eV9zdG9wX2RldiwKCS5kb193cml0ZQkJPSBpcnR0eV9kb193cml0ZSwKCS5jaGFyc19pbl9idWZmZXIJPSBpcnR0eV9jaGFyc19pbl9idWZmZXIsCgkud2FpdF91bnRpbF9zZW50CT0gaXJ0dHlfd2FpdF91bnRpbF9zZW50LAoJLnNldF9zcGVlZAkJPSBpcnR0eV9jaGFuZ2Vfc3BlZWQsCgkuc2V0X2R0cl9ydHMJCT0gaXJ0dHlfc2V0X2R0cl9ydHMsCn07CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKgogKiBGdW5jdGlvbiBpcnR0eV9pb2N0bCAodHR5LCBmaWxlLCBjbWQsIGFyZykKICoKICogICAgIFRoZSBTd2lzcyBhcm15IGtuaWZlIG9mIHN5c3RlbSBjYWxscyA6LSkKICoKICovCnN0YXRpYyBpbnQgaXJ0dHlfaW9jdGwoc3RydWN0IHR0eV9zdHJ1Y3QgKnR0eSwgc3RydWN0IGZpbGUgKmZpbGUsIHVuc2lnbmVkIGludCBjbWQsIHVuc2lnbmVkIGxvbmcgYXJnKQp7CglzdHJ1Y3QgaXJ0dHlfaW5mbyB7IGNoYXIgbmFtZVs2XTsgfSBpbmZvOwoJc3RydWN0IHNpcl9kZXYgKmRldjsKCXN0cnVjdCBzaXJ0dHlfY2IgKnByaXYgPSB0dHktPmRpc2NfZGF0YTsKCWludCBlcnIgPSAwOwoKCUlSREFfQVNTRVJUKHByaXYgIT0gTlVMTCwgcmV0dXJuIC1FTk9ERVY7KTsKCUlSREFfQVNTRVJUKHByaXYtPm1hZ2ljID09IElSVFRZX01BR0lDLCByZXR1cm4gLUVCQURSOyk7CgoJSVJEQV9ERUJVRygzLCAiJXMoY21kPTB4JVgpXG4iLCBfX0ZVTkNUSU9OX18sIGNtZCk7CgoJZGV2ID0gcHJpdi0+ZGV2OwoJSVJEQV9BU1NFUlQoZGV2ICE9IE5VTEwsIHJldHVybiAtMTspOwoKCXN3aXRjaCAoY21kKSB7CgljYXNlIFRDR0VUUzoKCWNhc2UgVENHRVRBOgoJCWVyciA9IG5fdHR5X2lvY3RsKHR0eSwgZmlsZSwgY21kLCBhcmcpOwoJCWJyZWFrOwoKCWNhc2UgSVJUVFlfSU9DVERPTkdMRToKCQkvKiB0aGlzIGNhbGwgYmxvY2tzIGZvciBjb21wbGV0aW9uICovCgkJZXJyID0gc2lyZGV2X3NldF9kb25nbGUoZGV2LCAoSVJEQV9ET05HTEUpIGFyZyk7CgkJYnJlYWs7CgoJY2FzZSBJUlRUWV9JT0NHRVQ6CgkJSVJEQV9BU1NFUlQoZGV2LT5uZXRkZXYgIT0gTlVMTCwgcmV0dXJuIC0xOyk7CgoJCW1lbXNldCgmaW5mbywgMCwgc2l6ZW9mKGluZm8pKTsgCgkJc3RybmNweShpbmZvLm5hbWUsIGRldi0+bmV0ZGV2LT5uYW1lLCBzaXplb2YoaW5mby5uYW1lKS0xKTsKCgkJaWYgKGNvcHlfdG9fdXNlcigodm9pZCBfX3VzZXIgKilhcmcsICZpbmZvLCBzaXplb2YoaW5mbykpKQoJCQllcnIgPSAtRUZBVUxUOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQllcnIgPSAtRU5PSU9DVExDTUQ7CgkJYnJlYWs7Cgl9CglyZXR1cm4gZXJyOwp9CgoKLyogCiAqICBGdW5jdGlvbiBpcnR0eV9vcGVuKHR0eSkKICoKICogICAgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYnkgdGhlIFRUWSBtb2R1bGUgd2hlbiB0aGUgSXJEQSBsaW5lCiAqICAgIGRpc2NpcGxpbmUgaXMgY2FsbGVkIGZvci4gIEJlY2F1c2Ugd2UgYXJlIHN1cmUgdGhlIHR0eSBsaW5lIGV4aXN0cywKICogICAgd2Ugb25seSBoYXZlIHRvIGxpbmsgaXQgdG8gYSBmcmVlIElyREEgY2hhbm5lbC4gIAogKi8Kc3RhdGljIGludCBpcnR0eV9vcGVuKHN0cnVjdCB0dHlfc3RydWN0ICp0dHkpIAp7CglzdHJ1Y3Qgc2lyX2RldiAqZGV2OwoJc3RydWN0IHNpcnR0eV9jYiAqcHJpdjsKCWludCByZXQgPSAwOwoKCS8qIE1vZHVsZSBzdHVmZiBoYW5kbGVkIHZpYSBpcmRhX2xkaXNjLm93bmVyIC0gSmVhbiBJSSAqLwoKCS8qIEZpcnN0IG1ha2Ugc3VyZSB3ZSdyZSBub3QgYWxyZWFkeSBjb25uZWN0ZWQuICovCglpZiAodHR5LT5kaXNjX2RhdGEgIT0gTlVMTCkgewoJCXByaXYgPSB0dHktPmRpc2NfZGF0YTsKCQlpZiAocHJpdiAmJiBwcml2LT5tYWdpYyA9PSBJUlRUWV9NQUdJQykgewoJCQlyZXQgPSAtRUVYSVNUOwoJCQlnb3RvIG91dDsKCQl9CgkJdHR5LT5kaXNjX2RhdGEgPSBOVUxMOwkJLyogIyMjICovCgl9CgoJLyogc3RvcCB0aGUgdW5kZXJseWluZyAgZHJpdmVyICovCglpcnR0eV9zdG9wX3JlY2VpdmVyKHR0eSwgVFJVRSk7CglpZiAodHR5LT5kcml2ZXItPnN0b3ApCgkJdHR5LT5kcml2ZXItPnN0b3AodHR5KTsKCglpZiAodHR5LT5kcml2ZXItPmZsdXNoX2J1ZmZlcikKCQl0dHktPmRyaXZlci0+Zmx1c2hfYnVmZmVyKHR0eSk7CgkKCS8qIGFwcGx5IG10dCBvdmVycmlkZSAqLwoJc2lyX3R0eV9kcnYucW9zX210dF9iaXRzID0gcW9zX210dF9iaXRzOwoKCS8qIGdldCBhIHNpciBkZXZpY2UgaW5zdGFuY2UgZm9yIHRoaXMgZHJpdmVyICovCglkZXYgPSBzaXJkZXZfZ2V0X2luc3RhbmNlKCZzaXJfdHR5X2RydiwgdHR5LT5uYW1lKTsKCWlmICghZGV2KSB7CgkJcmV0ID0gLUVOT0RFVjsKCQlnb3RvIG91dDsKCX0KCgkvKiBhbGxvY2F0ZSBwcml2YXRlIGRldmljZSBpbmZvIGJsb2NrICovCglwcml2ID0ga21hbGxvYyhzaXplb2YoKnByaXYpLCBHRlBfS0VSTkVMKTsKCWlmICghcHJpdikKCQlnb3RvIG91dF9wdXQ7CgltZW1zZXQocHJpdiwgMCwgc2l6ZW9mKCpwcml2KSk7CgoJcHJpdi0+bWFnaWMgPSBJUlRUWV9NQUdJQzsKCXByaXYtPnR0eSA9IHR0eTsKCXByaXYtPmRldiA9IGRldjsKCgkvKiBzZXJpYWxpemUgd2l0aCBzdGFydF9kZXYgLSBpbiBjYXNlIHdlIHdlcmUgcmFjaW5nIHdpdGggaWZ1cCAqLwoJbXV0ZXhfbG9jaygmaXJ0dHlfbXV0ZXgpOwoKCWRldi0+cHJpdiA9IHByaXY7Cgl0dHktPmRpc2NfZGF0YSA9IHByaXY7Cgl0dHktPnJlY2VpdmVfcm9vbSA9IDY1NTM2OwoKCW11dGV4X3VubG9jaygmaXJ0dHlfbXV0ZXgpOwoKCUlSREFfREVCVUcoMCwgIiVzIC0gJXM6IGlyZGEgbGluZSBkaXNjaXBsaW5lIG9wZW5lZFxuIiwgX19GVU5DVElPTl9fLCB0dHktPm5hbWUpOwoKCXJldHVybiAwOwoKb3V0X3B1dDoKCXNpcmRldl9wdXRfaW5zdGFuY2UoZGV2KTsKb3V0OgoJcmV0dXJuIHJldDsKfQoKLyogCiAqICBGdW5jdGlvbiBpcnR0eV9jbG9zZSAodHR5KQogKgogKiAgICBDbG9zZSBkb3duIGEgSXJEQSBjaGFubmVsLiBUaGlzIG1lYW5zIGZsdXNoaW5nIG91dCBhbnkgcGVuZGluZyBxdWV1ZXMsCiAqICAgIGFuZCB0aGVuIHJlc3RvcmluZyB0aGUgVFRZIGxpbmUgZGlzY2lwbGluZSB0byB3aGF0IGl0IHdhcyBiZWZvcmUgaXQgZ290CiAqICAgIGhvb2tlZCB0byBJckRBICh3aGljaCB1c3VhbGx5IGlzIFRUWSBhZ2FpbikuICAKICovCnN0YXRpYyB2b2lkIGlydHR5X2Nsb3NlKHN0cnVjdCB0dHlfc3RydWN0ICp0dHkpIAp7CglzdHJ1Y3Qgc2lydHR5X2NiICpwcml2ID0gdHR5LT5kaXNjX2RhdGE7CgoJSVJEQV9BU1NFUlQocHJpdiAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHByaXYtPm1hZ2ljID09IElSVFRZX01BR0lDLCByZXR1cm47KTsKCgkvKiBIbSwgd2l0aCBhIGRvbmdsZSBhdHRhY2hlZCB0aGUgZG9uZ2xlIGRyaXZlciB3YW50cwoJICogdG8gY2xvc2UgdGhlIGRvbmdsZSAtIHdoaWNoIHJlcXVpcmVzIHRoZSB1c2Ugb2YKCSAqIHNvbWUgdHR5IHdyaXRlIGFuZC9vciB0ZXJtaW9zIG9yIGlvY3RsIG9wZXJhdGlvbnMuCgkgKiBBcmUgd2UgYWxsb3dlZCB0byBjYWxsIHRob3NlIHdoZW4gYWxyZWFkeSByZXF1ZXN0ZWQKCSAqIHRvIHNodXRkb3duIHRoZSBsZGlzYz8KCSAqIElmIG5vdCwgd2Ugc2hvdWxkIHNvbWVob3cgbWFyayB0aGUgZGV2IGJlaW5nIHN0YWxlZC4KCSAqIFF1ZXN0aW9uIHJlbWFpbnMsIGhvdyB0byBjbG9zZSB0aGUgZG9uZ2xlIGluIHRoaXMgY2FzZS4uLgoJICogRm9yIG5vdyBsZXQncyBhc3N1bWUgd2UgYXJlIGdyYW50ZWQgdG8gaXNzdWUgdHR5IGRyaXZlciBjYWxscwoJICogdW50aWwgd2UgcmV0dXJuIGhlcmUgZnJvbSB0aGUgbGRpc2MgY2xvc2UuIEknbSBqdXN0IHdvbmRlcmluZwoJICogaG93IHRoaXMgYmVoYXZlcyB3aXRoIGhvdHBsdWdnYWJsZSBzZXJpYWwgaGFyZHdhcmUgbGlrZQoJICogcnMyMzItcGNtY2lhIGNhcmQgb3IgdXNiLXNlcmlhbC4uLgoJICoKCSAqIHByaXYtPnR0eSA9IE5VTEw/OwoJICovCgoJLyogd2UgYXJlIGRlYWQgbm93ICovCgl0dHktPmRpc2NfZGF0YSA9IE5VTEw7CgoJc2lyZGV2X3B1dF9pbnN0YW5jZShwcml2LT5kZXYpOwoKCS8qIFN0b3AgdHR5ICovCglpcnR0eV9zdG9wX3JlY2VpdmVyKHR0eSwgVFJVRSk7Cgl0dHktPmZsYWdzICY9IH4oMSA8PCBUVFlfRE9fV1JJVEVfV0FLRVVQKTsKCWlmICh0dHktPmRyaXZlci0+c3RvcCkKCQl0dHktPmRyaXZlci0+c3RvcCh0dHkpOwoKCWtmcmVlKHByaXYpOwoKCUlSREFfREVCVUcoMCwgIiVzIC0gJXM6IGlyZGEgbGluZSBkaXNjaXBsaW5lIGNsb3NlZFxuIiwgX19GVU5DVElPTl9fLCB0dHktPm5hbWUpOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpzdGF0aWMgc3RydWN0IHR0eV9sZGlzYyBpcmRhX2xkaXNjID0gewoJLm1hZ2ljCQk9IFRUWV9MRElTQ19NQUdJQywKIAkubmFtZQkJPSAiaXJkYSIsCgkuZmxhZ3MJCT0gMCwKCS5vcGVuCQk9IGlydHR5X29wZW4sCgkuY2xvc2UJCT0gaXJ0dHlfY2xvc2UsCgkucmVhZAkJPSBOVUxMLAoJLndyaXRlCQk9IE5VTEwsCgkuaW9jdGwJCT0gaXJ0dHlfaW9jdGwsCiAJLnBvbGwJCT0gTlVMTCwKCS5yZWNlaXZlX2J1Zgk9IGlydHR5X3JlY2VpdmVfYnVmLAoJLndyaXRlX3dha2V1cAk9IGlydHR5X3dyaXRlX3dha2V1cCwKCS5vd25lcgkJPSBUSElTX01PRFVMRSwKfTsKCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCnN0YXRpYyBpbnQgX19pbml0IGlydHR5X3Npcl9pbml0KHZvaWQpCnsKCWludCBlcnI7CgoJaWYgKChlcnIgPSB0dHlfcmVnaXN0ZXJfbGRpc2MoTl9JUkRBLCAmaXJkYV9sZGlzYykpICE9IDApCgkJSVJEQV9FUlJPUigiSXJEQTogY2FuJ3QgcmVnaXN0ZXIgbGluZSBkaXNjaXBsaW5lIChlcnIgPSAlZClcbiIsCgkJCSAgIGVycik7CglyZXR1cm4gZXJyOwp9CgpzdGF0aWMgdm9pZCBfX2V4aXQgaXJ0dHlfc2lyX2NsZWFudXAodm9pZCkgCnsKCWludCBlcnI7CgoJaWYgKChlcnIgPSB0dHlfdW5yZWdpc3Rlcl9sZGlzYyhOX0lSREEpKSkgewoJCUlSREFfRVJST1IoIiVzKCksIGNhbid0IHVucmVnaXN0ZXIgbGluZSBkaXNjaXBsaW5lIChlcnIgPSAlZClcbiIsCgkJCSAgIF9fRlVOQ1RJT05fXywgZXJyKTsKCX0KfQoKbW9kdWxlX2luaXQoaXJ0dHlfc2lyX2luaXQpOwptb2R1bGVfZXhpdChpcnR0eV9zaXJfY2xlYW51cCk7CgpNT0RVTEVfQVVUSE9SKCJEYWcgQnJhdHRsaSA8ZGFnYkBjcy51aXQubm8+Iik7Ck1PRFVMRV9ERVNDUklQVElPTigiSXJEQSBUVFkgZGV2aWNlIGRyaXZlciIpOwpNT0RVTEVfQUxJQVNfTERJU0MoTl9JUkRBKTsKTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwoK