LyoKICogKEMpIENvcHlyaWdodCAyMDAyCiAqIERhbmllbCBFbmdzdHL2bSwgT21pY3JvbiBDZXRpIEFCLCA8ZGFuaWVsQG9taWNyb24uc2U+CiAqCiAqIFNlZSBmaWxlIENSRURJVFMgZm9yIGxpc3Qgb2YgcGVvcGxlIHdobyBjb250cmlidXRlZCB0byB0aGlzCiAqIHByb2plY3QuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YKICogdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sCiAqIE1BIDAyMTExLTEzMDcgVVNBCiAqLwoKLyoKICogTGludXggeDg2IHpJbWFnZSBhbmQgYnpJbWFnZSBsb2FkaW5nCiAqCiAqIGJhc2VkIG9uIHRoZSBwcm9jZHVyZSBkZXNjcmliZWQgaW4KICogbGludXgvRG9jdW1lbnRhdGlvbi9pMzg2L2Jvb3QudHh0CiAqLwoKI2luY2x1ZGUgPGNvbW1vbi5oPgojaW5jbHVkZSA8YXNtL2lvLmg+CiNpbmNsdWRlIDxhc20vcHRyYWNlLmg+CiNpbmNsdWRlIDxhc20vemltYWdlLmg+CiNpbmNsdWRlIDxhc20vcmVhbG1vZGUuaD4KI2luY2x1ZGUgPGFzbS9ieXRlb3JkZXIuaD4KI2luY2x1ZGUgPGFzbS9ib290cGFyYW0uaD4KI2luY2x1ZGUgPGFzbS9pYy9zYzUyMC5oPgoKLyoKICogTWVtb3J5IGxheS1vdXQ6CiAqCiAqIHJlbGF0aXZlIHRvIHNldHVwX2Jhc2UgKHdoaWNoIGlzIDB4OTAwMDAgY3VycmVudGx5KQogKgogKgkweDAwMDAtMHg3RkZGCVJlYWwgbW9kZSBrZXJuZWwKICoJMHg4MDAwLTB4OEZGRglTdGFjayBhbmQgaGVhcAogKgkweDkwMDAtMHg5MEZGCUtlcm5lbCBjb21tYW5kIGxpbmUKICovCiNkZWZpbmUgREVGQVVMVF9TRVRVUF9CQVNFICAweDkwMDAwCiNkZWZpbmUgQ09NTUFORF9MSU5FX09GRlNFVCAweDkwMDAKI2RlZmluZSBIRUFQX0VORF9PRkZTRVQgICAgIDB4OGUwMAoKI2RlZmluZSBDT01NQU5EX0xJTkVfU0laRSAgIDIwNDgKCnN0YXRpYyB2b2lkIGJ1aWxkX2NvbW1hbmRfbGluZShjaGFyICpjb21tYW5kX2xpbmUsIGludCBhdXRvX2Jvb3QpCnsKCWNoYXIgKmVudl9jb21tYW5kX2xpbmU7CgoJY29tbWFuZF9saW5lWzBdID0gJ1wwJzsKCgllbnZfY29tbWFuZF9saW5lID0gIGdldGVudigiYm9vdGFyZ3MiKTsKCgkvKiBzZXQgY29uc29sZT0gYXJndW1lbnQgaWYgd2UgdXNlIGEgc2VyaWFsIGNvbnNvbGUgKi8KCWlmIChOVUxMID09IHN0cnN0cihlbnZfY29tbWFuZF9saW5lLCAiY29uc29sZT0iKSkgewoJCWlmICgwPT1zdHJjbXAoZ2V0ZW52KCJzdGRvdXQiKSwgInNlcmlhbCIpKSB7CgoJCQkvKiBXZSBzZWVtIHRvIHVzZSBzZXJpYWwgY29uc29sZSAqLwoJCQlzcHJpbnRmKGNvbW1hbmRfbGluZSwgImNvbnNvbGU9dHR5UzAsJXMgIiwKCQkJCSBnZXRlbnYoImJhdWRyYXRlIikpOwoJCX0KCX0KCglpZiAoYXV0b19ib290KSB7CgkJc3RyY2F0KGNvbW1hbmRfbGluZSwgImF1dG8gIik7Cgl9CgoJaWYgKE5VTEwgIT0gZW52X2NvbW1hbmRfbGluZSkgewoJCXN0cmNhdChjb21tYW5kX2xpbmUsIGVudl9jb21tYW5kX2xpbmUpOwoJfQoKCglwcmludGYoIktlcm5lbCBjb21tYW5kIGxpbmU6IFwiJXNcIlxuIiwgY29tbWFuZF9saW5lKTsKfQoKdm9pZCAqbG9hZF96aW1hZ2UoY2hhciAqaW1hZ2UsIHVuc2lnbmVkIGxvbmcga2VybmVsX3NpemUsCgkJICB1bnNpZ25lZCBsb25nIGluaXRyZF9hZGRyLCB1bnNpZ25lZCBsb25nIGluaXRyZF9zaXplLAoJCSAgaW50IGF1dG9fYm9vdCkKewoJdm9pZCAqc2V0dXBfYmFzZTsKCWludCBzZXR1cF9zaXplOwoJaW50IGJvb3Rwcm90bzsKCWludCBiaWdfaW1hZ2U7Cgl2b2lkICpsb2FkX2FkZHJlc3M7CgoJc3RydWN0IHNldHVwX2hlYWRlciAqaGRyID0gKHN0cnVjdCBzZXR1cF9oZWFkZXIgKikoaW1hZ2UgKyBTRVRVUF9TRUNUU19PRkYpOwoKCXNldHVwX2Jhc2UgPSAodm9pZCopREVGQVVMVF9TRVRVUF9CQVNFOwkvKiBiYXNlIGFkZHJlc3MgZm9yIHJlYWwtbW9kZSBzZWdtZW50ICovCgoJaWYgKEtFUk5FTF9NQUdJQyAhPSBoZHItPmJvb3RfZmxhZykgewoJCXByaW50ZigiRXJyb3I6IEludmFsaWQgQm9vdCBGbGFnIChmb3VuZCAweCUwNHgsIGV4cGVjdGVkIDB4JTA0eClcbiIsCgkJCQloZHItPmJvb3RfZmxhZywgS0VSTkVMX01BR0lDKTsKCQlyZXR1cm4gMDsKCX0gZWxzZSB7CgkJcHJpbnRmKCJWYWxpZCBCb290IEZsYWdcbiIpOwoJfQoKCS8qIGRldGVybWluZSBib290IHByb3RvY29sIHZlcnNpb24gKi8KCWlmIChLRVJORUxfVjJfTUFHSUMgPT0gaGRyLT5oZWFkZXIpIHsKCQlwcmludGYoIk1hZ2ljIHNpZ25hdHVyZSBmb3VuZFxuIik7CgoJCWJvb3Rwcm90byA9IGhkci0+dmVyc2lvbjsKCX0gZWxzZSB7CgkJLyogVmVyeSBvbGQga2VybmVsICovCgkJcHJpbnRmKCJNYWdpYyBzaWduYXR1cmUgbm90IGZvdW5kXG4iKTsKCQlib290cHJvdG8gPSAweDAxMDA7Cgl9CgoJLyogZGV0ZXJtaW5lIHNpemUgb2Ygc2V0dXAgKi8KCWlmICgwID09IGhkci0+c2V0dXBfc2VjdHMpIHsKCQlwcmludGYoIlNldHVwIFNlY3RvcnMgPSAwIChkZWZhdWx0aW5nIHRvIDQpXG4iKTsKCQlzZXR1cF9zaXplID0gNSAqIDUxMjsKCX0gZWxzZSB7CgkJc2V0dXBfc2l6ZSA9IChoZHItPnNldHVwX3NlY3RzICsgMSkgKiA1MTI7Cgl9CgoJcHJpbnRmKCJTZXR1cCBTaXplID0gMHglOC44bHhcbiIsICh1bG9uZylzZXR1cF9zaXplKTsKCglpZiAoc2V0dXBfc2l6ZSA+IFNFVFVQX01BWF9TSVpFKSB7CgkJcHJpbnRmKCJFcnJvcjogU2V0dXAgaXMgdG9vIGxhcmdlICglZCBieXRlcylcbiIsIHNldHVwX3NpemUpOwoJfQoKCS8qIERldGVybWluZSBpbWFnZSB0eXBlICovCgliaWdfaW1hZ2UgPSAoYm9vdHByb3RvID49IDB4MDIwMCkgJiYgKGhkci0+bG9hZGZsYWdzICYgQklHX0tFUk5FTF9GTEFHKTsKCgkvKiBEZXRlcm1pbmUgbG9hZCBhZGRyZXNzICovCglsb2FkX2FkZHJlc3MgPSAodm9pZCopKGJpZ19pbWFnZSA/IEJaSU1BR0VfTE9BRF9BRERSIDogWklNQUdFX0xPQURfQUREUik7CgoJLyogbG9hZCBzZXR1cCAqLwoJcHJpbnRmKCJNb3ZpbmcgUmVhbC1Nb2RlIENvZGUgdG8gMHglOC44bHggKCVkIGJ5dGVzKVxuIiwgKHVsb25nKXNldHVwX2Jhc2UsIHNldHVwX3NpemUpOwoJbWVtbW92ZShzZXR1cF9iYXNlLCBpbWFnZSwgc2V0dXBfc2l6ZSk7CgoJcHJpbnRmKCJVc2luZyBib290IHByb3RvY29sIHZlcnNpb24gJXguJTAyeFxuIiwKCSAgICAgICAoYm9vdHByb3RvICYgMHhmZjAwKSA+PiA4LCBib290cHJvdG8gJiAweGZmKTsKCglpZiAoYm9vdHByb3RvID09IDB4MDEwMCkgewoKCQkqKHUxNiopKHNldHVwX2Jhc2UgKyBDTURfTElORV9NQUdJQ19PRkYpID0gQ09NTUFORF9MSU5FX01BR0lDOwoJCSoodTE2Kikoc2V0dXBfYmFzZSArIENNRF9MSU5FX09GRlNFVF9PRkYpID0gQ09NTUFORF9MSU5FX09GRlNFVDsKCgkJLyogQSB2ZXJ5IG9sZCBrZXJuZWwgTVVTVCBoYXZlIGl0cyByZWFsLW1vZGUgY29kZQoJCSAqIGxvYWRlZCBhdCAweDkwMDAwICovCgoJCWlmICgodTMyKXNldHVwX2Jhc2UgIT0gMHg5MDAwMCkgewoJCQkvKiBDb3B5IHRoZSByZWFsLW1vZGUga2VybmVsICovCgkJCW1lbW1vdmUoKHZvaWQqKTB4OTAwMDAsIHNldHVwX2Jhc2UsIHNldHVwX3NpemUpOwoJCQkvKiBDb3B5IHRoZSBjb21tYW5kIGxpbmUgKi8KCQkJbWVtbW92ZSgodm9pZCopMHg5OTAwMCwgc2V0dXBfYmFzZStDT01NQU5EX0xJTkVfT0ZGU0VULAoJCQkgICAgICAgQ09NTUFORF9MSU5FX1NJWkUpOwoKCQkJc2V0dXBfYmFzZSA9ICh2b2lkKikweDkwMDAwOwkJIC8qIFJlbG9jYXRlZCAqLwoJCX0KCgkJLyogSXQgaXMgcmVjb21tZW5kZWQgdG8gY2xlYXIgbWVtb3J5IHVwIHRvIHRoZSAzMksgbWFyayAqLwoJCW1lbXNldCgodm9pZCopMHg5MDAwMCArIHNldHVwX3NpemUsIDAsIFNFVFVQX01BWF9TSVpFLXNldHVwX3NpemUpOwoJfQoKCS8qIFdlIGFyZSBub3cgc2V0dGluZyB1cCB0aGUgcmVhbC1tb2RlIHZlcnNpb24gb2YgdGhlIGhlYWRlciAqLwoJaGRyID0gKHN0cnVjdCBzZXR1cF9oZWFkZXIgKikoc2V0dXBfYmFzZSArIFNFVFVQX1NFQ1RTX09GRik7CgoJaWYgKGJvb3Rwcm90byA+PSAweDAyMDApIHsKCQloZHItPnR5cGVfb2ZfbG9hZGVyID0gODsKCgkJaWYgKGhkci0+c2V0dXBfc2VjdHMgPj0gMTUpCgkJCXByaW50ZigiTGludXgga2VybmVsIHZlcnNpb24gJXNcbiIsIChjaGFyICopCgkJCQkJKHNldHVwX2Jhc2UgKyAoaGRyLT5rZXJuZWxfdmVyc2lvbiArIDB4MjAwKSkpOwoJCWVsc2UKCQkJcHJpbnRmKCJTZXR1cCBTZWN0b3JzIDwgMTUgLSBDYW5ub3QgcHJpbnQga2VybmVsIHZlcnNpb24uXG4iKTsKCgkJaWYgKGluaXRyZF9hZGRyKSB7CgkJCXByaW50ZigiSW5pdGlhbCBSQU0gZGlzayBhdCBsaW5lYXIgYWRkcmVzcyAweCUwOGx4LCBzaXplICVsZCBieXRlc1xuIiwKCQkJICAgICAgIGluaXRyZF9hZGRyLCBpbml0cmRfc2l6ZSk7CgoJCQloZHItPnJhbWRpc2tfaW1hZ2UgPSBpbml0cmRfYWRkcjsKCQkJaGRyLT5yYW1kaXNrX3NpemUgPSBpbml0cmRfc2l6ZTsKCQl9Cgl9CgoJaWYgKGJvb3Rwcm90byA+PSAweDAyMDEpIHsKCQloZHItPmhlYXBfZW5kX3B0ciA9IEhFQVBfRU5EX09GRlNFVDsKCQloZHItPmxvYWRmbGFncyB8PSBIRUFQX0ZMQUc7Cgl9CgoJaWYgKGJvb3Rwcm90byA+PSAweDAyMDIpIHsKCQloZHItPmNtZF9saW5lX3B0ciA9ICh1MzIpc2V0dXBfYmFzZSArIENPTU1BTkRfTElORV9PRkZTRVQ7Cgl9IGVsc2UgaWYgKGJvb3Rwcm90byA+PSAweDAyMDApIHsKCgkJKih1MTYqKShzZXR1cF9iYXNlICsgQ01EX0xJTkVfTUFHSUNfT0ZGKSA9IENPTU1BTkRfTElORV9NQUdJQzsKCQkqKHUxNiopKHNldHVwX2Jhc2UgKyBDTURfTElORV9PRkZTRVRfT0ZGKSA9IENPTU1BTkRfTElORV9PRkZTRVQ7CgoJCWhkci0+c2V0dXBfbW92ZV9zaXplID0gMHg5MTAwOwoJfQoKCWlmIChib290cHJvdG8gPj0gMHgwMjA0KQoJCWtlcm5lbF9zaXplID0gaGRyLT5zeXNzaXplICogMTY7CgllbHNlCgkJa2VybmVsX3NpemUgLT0gc2V0dXBfc2l6ZTsKCgoJaWYgKGJpZ19pbWFnZSkgewoJCWlmICgoa2VybmVsX3NpemUpID4gQlpJTUFHRV9NQVhfU0laRSkgewoJCQlwcmludGYoIkVycm9yOiBiekltYWdlIGtlcm5lbCB0b28gYmlnISAoc2l6ZTogJWxkLCBtYXg6ICVkKVxuIiwKCQkJICAgICAgIGtlcm5lbF9zaXplLCBCWklNQUdFX01BWF9TSVpFKTsKCQkJcmV0dXJuIDA7CgkJfQoKCX0gZWxzZSBpZiAoKGtlcm5lbF9zaXplKSA+IFpJTUFHRV9NQVhfU0laRSkgewoJCXByaW50ZigiRXJyb3I6IHpJbWFnZSBrZXJuZWwgdG9vIGJpZyEgKHNpemU6ICVsZCwgbWF4OiAlZClcbiIsCgkJICAgICAgIGtlcm5lbF9zaXplLCBaSU1BR0VfTUFYX1NJWkUpOwoJCXJldHVybiAwOwoJfQoKCS8qIGJ1aWxkIGNvbW1hbmQgbGluZSBhdCBDT01NQU5EX0xJTkVfT0ZGU0VUICovCglidWlsZF9jb21tYW5kX2xpbmUoc2V0dXBfYmFzZSArIENPTU1BTkRfTElORV9PRkZTRVQsIGF1dG9fYm9vdCk7CgoJcHJpbnRmKCJMb2FkaW5nICVjekltYWdlIGF0IGFkZHJlc3MgMHglMDh4ICglbGQgYnl0ZXMpXG4iLCBiaWdfaW1hZ2UgPyAnYicgOiAnICcsCgkgICAgICAgKHUzMilsb2FkX2FkZHJlc3MsIGtlcm5lbF9zaXplKTsKCgoJbWVtbW92ZShsb2FkX2FkZHJlc3MsIGltYWdlICsgc2V0dXBfc2l6ZSwga2VybmVsX3NpemUpOwoKCS8qIHJlYWR5IGZvciBib290aW5nICovCglyZXR1cm4gc2V0dXBfYmFzZTsKfQoKdm9pZCBib290X3ppbWFnZSh2b2lkICpzZXR1cF9iYXNlKQp7CglzdHJ1Y3QgcHRfcmVncyByZWdzOwoKCW1lbXNldCgmcmVncywgMCwgc2l6ZW9mKHN0cnVjdCBwdF9yZWdzKSk7CglyZWdzLnhkcyA9ICh1MzIpc2V0dXBfYmFzZSA+PiA0OwoJcmVncy54ZXMgPSByZWdzLnhkczsKCXJlZ3MueHNzID0gcmVncy54ZHM7CglyZWdzLmVzcCA9IDB4OTAwMDsKCXJlZ3MuZWZsYWdzID0gMDsKCWVudGVyX3JlYWxtb2RlKCgodTMyKXNldHVwX2Jhc2UrU0VUVVBfU1RBUlRfT0ZGU0VUKT4+NCwgMCwgJnJlZ3MsICZyZWdzKTsKfQoKaW50IGRvX3pib290IChjbWRfdGJsX3QgKmNtZHRwLCBpbnQgZmxhZywgaW50IGFyZ2MsIGNoYXIgKiBjb25zdCBhcmd2W10pCnsKCXZvaWQgKmJhc2VfcHRyOwoJdm9pZCAqYnpJbWFnZV9hZGRyID0gTlVMTDsKCWNoYXIgKnM7Cgl1bG9uZyBiekltYWdlX3NpemUgPSAwOwoKCWRpc2FibGVfaW50ZXJydXB0cygpOwoKCS8qIFNldHVwIGJvYXJkIGZvciBtYXhpbXVtIFBDL0FUIENvbXBhdGliaWxpdHkgKi8KCXNldHVwX3BjYXRfY29tcGF0aWJpbGl0eSgpOwoKCWlmIChhcmdjID49IDIpCgkJLyogYXJndlsxXSBob2xkcyB0aGUgYWRkcmVzcyBvZiB0aGUgYnpJbWFnZSAqLwoJCXMgPSBhcmd2WzFdOwoJZWxzZQoJCXMgPSBnZXRlbnYoImZpbGVhZGRyIik7CgoJaWYgKHMpCgkJYnpJbWFnZV9hZGRyID0gKHZvaWQgKilzaW1wbGVfc3RydG91bChzLCBOVUxMLCAxNik7CgoJaWYgKGFyZ2MgPj0gMykKCQkvKiBhcmd2WzJdIGhvbGRzIHRoZSBzaXplIG9mIHRoZSBiekltYWdlICovCgkJYnpJbWFnZV9zaXplID0gc2ltcGxlX3N0cnRvdWwoYXJndlsyXSwgTlVMTCwgMTYpOwoKCS8qIExldHMgbG9vayBmb3IqLwoJYmFzZV9wdHIgPSBsb2FkX3ppbWFnZSAoYnpJbWFnZV9hZGRyLCBiekltYWdlX3NpemUsIDAsIDAsIDApOwoKCWlmIChOVUxMID09IGJhc2VfcHRyKSB7CgkJcHJpbnRmICgiIyMgS2VybmVsIGxvYWRpbmcgZmFpbGVkIC4uLlxuIik7Cgl9IGVsc2UgewoJCXByaW50ZiAoIiMjIFRyYW5zZmVycmluZyBjb250cm9sIHRvIExpbnV4IChhdCBhZGRyZXNzICUwOHgpIC4uLlxuIiwKCQkJKHUzMiliYXNlX3B0cik7CgoJCS8qIHdlIGFzc3VtZSB0aGF0IHRoZSBrZXJuZWwgaXMgaW4gcGxhY2UgKi8KCQlwcmludGYoIlxuU3RhcnRpbmcga2VybmVsIC4uLlxuXG4iKTsKCgkJYm9vdF96aW1hZ2UoYmFzZV9wdHIpOwoJCS8qIGRvZXMgbm90IHJldHVybiAqLwoJfQoKCXJldHVybiAtMTsKfQoKVV9CT09UX0NNRCgKCXpib290LCAyLCAwLAlkb196Ym9vdCwKCSJCb290IGJ6SW1hZ2UiLAoJIiIKKTsK