LyoKICogQ29weXJpZ2h0IChjKSBJbnRlbCBDb3JwLiAyMDA3LgogKiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiBJbnRlbCBmdW5kZWQgVHVuZ3N0ZW4gR3JhcGhpY3MgKGh0dHA6Ly93d3cudHVuZ3N0ZW5ncmFwaGljcy5jb20pIHRvCiAqIGRldmVsb3AgdGhpcyBkcml2ZXIuCiAqCiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBWZXJtaWxpb24gUmFuZ2UgZmIgZHJpdmVyLgogKiBUaGUgVmVybWlsaW9uIFJhbmdlIGZiIGRyaXZlciBpcyBmcmVlIHNvZnR3YXJlOwogKiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoZSBWZXJtaWxpb24gUmFuZ2UgZmIgZHJpdmVyIGlzIGRpc3RyaWJ1dGVkCiAqIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogYWxvbmcgd2l0aCB0aGlzIGRyaXZlcjsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQQogKgogKiBBdXRob3JzOgogKiAgIFRob21hcyBIZWxsc3Ry9m0gPHRob21hcy1hdC10dW5nc3RlbmdyYXBoaWNzLWRvdC1jb20+CiAqICAgTWljaGVsIETkbnplciA8bWljaGVsLWF0LXR1bmdzdGVuZ3JhcGhpY3MtZG90LWNvbT4KICogICBBbGFuIEhvdXJpaGFuZSA8YWxhbmgtYXQtdHVuZ3N0ZW5ncmFwaGljcy1kb3QtY29tPgogKi8KCiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgojaW5jbHVkZSA8bGludXgvZXJybm8uaD4KI2luY2x1ZGUgPGxpbnV4L3N0cmluZy5oPgojaW5jbHVkZSA8bGludXgvZGVsYXkuaD4KI2luY2x1ZGUgPGxpbnV4L21tLmg+CiNpbmNsdWRlIDxsaW51eC9mYi5oPgojaW5jbHVkZSA8bGludXgvcGNpLmg+CiNpbmNsdWRlIDxhc20vY2FjaGVmbHVzaC5oPgojaW5jbHVkZSA8YXNtL3RsYmZsdXNoLmg+CiNpbmNsdWRlIDxsaW51eC9tbXpvbmUuaD4KI2luY2x1ZGUgPGFzbS91YWNjZXNzLmg+CgovKiAjZGVmaW5lIFZFUk1JTElPTl9ERUJVRyAqLwoKI2luY2x1ZGUgInZlcm1pbGlvbi5oIgoKI2RlZmluZSBNT0RVTEVfTkFNRSAidm1sZmIiCgojZGVmaW5lIFZNTF9UT0hXKF92YWwsIF93aWR0aCkgKCgoKF92YWwpIDw8IChfd2lkdGgpKSArIDB4N0ZGRiAtIChfdmFsKSkgPj4gMTYpCgpzdGF0aWMgc3RydWN0IG11dGV4IHZtbF9tdXRleDsKc3RhdGljIHN0cnVjdCBsaXN0X2hlYWQgZ2xvYmFsX25vX21vZGU7CnN0YXRpYyBzdHJ1Y3QgbGlzdF9oZWFkIGdsb2JhbF9oYXNfbW9kZTsKc3RhdGljIHN0cnVjdCBmYl9vcHMgdm1sZmJfb3BzOwpzdGF0aWMgc3RydWN0IHZtbF9zeXMgKnN1YnN5cyA9IE5VTEw7CnN0YXRpYyBjaGFyICp2bWxfZGVmYXVsdF9tb2RlID0gIjEwMjR4NzY4QDYwIjsKc3RhdGljIHN0cnVjdCBmYl92aWRlb21vZGUgZGVmYXVsdG1vZGUgPSB7CglOVUxMLCA2MCwgMTAyNCwgNzY4LCAxMjg5NiwgMTQ0LCAyNCwgMjksIDMsIDEzNiwgNiwKCTAsIEZCX1ZNT0RFX05PTklOVEVSTEFDRUQKfTsKCnN0YXRpYyB1MzIgdm1sX21lbV9yZXF1ZXN0ZWQgPSAoMTAgKiAxMDI0ICogMTAyNCk7CnN0YXRpYyB1MzIgdm1sX21lbV9jb250aWcgPSAoNCAqIDEwMjQgKiAxMDI0KTsKc3RhdGljIHUzMiB2bWxfbWVtX21pbiA9ICg0ICogMTAyNCAqIDEwMjQpOwoKc3RhdGljIHUzMiB2bWxfY2xvY2tzW10gPSB7Cgk2NzUwLAoJMTM1MDAsCgkyNzAwMCwKCTI5NzAwLAoJMzcxMjUsCgk1NDAwMCwKCTU5NDAwLAoJNzQyNTAsCgkxMjAwMDAsCgkxNDg1MDAKfTsKCnN0YXRpYyB1MzIgdm1sX251bV9jbG9ja3MgPSBBUlJBWV9TSVpFKHZtbF9jbG9ja3MpOwoKLyoKICogQWxsb2NhdGUgYSBjb250aWd1b3VzIHZyYW0gYXJlYSBhbmQgbWFrZSBpdHMgbGluZWFyIGtlcm5lbCBtYXAKICogdW5jYWNoZWQuCiAqLwoKc3RhdGljIGludCB2bWxmYl9hbGxvY192cmFtX2FyZWEoc3RydWN0IHZyYW1fYXJlYSAqdmEsIHVuc2lnbmVkIG1heF9vcmRlciwKCQkJCSB1bnNpZ25lZCBtaW5fb3JkZXIpCnsKCWdmcF90IGZsYWdzOwoJdW5zaWduZWQgbG9uZyBpOwoJcGdwcm90X3Qgd2NfcGFnZXByb3Q7CgoJd2NfcGFnZXByb3QgPSBQQUdFX0tFUk5FTF9OT0NBQ0hFOwoJbWF4X29yZGVyKys7CglkbyB7CgkJLyoKCQkgKiBSZWFsbHkgdHJ5IGhhcmQgdG8gZ2V0IHRoZSBuZWVkZWQgbWVtb3J5LgoJCSAqIFdlIG5lZWQgbWVtb3J5IGJlbG93IHRoZSBmaXJzdCAzMk1CLCBzbyB3ZQoJCSAqIGFkZCB0aGUgX19HRlBfRE1BIGZsYWcgdGhhdCBndWFyYW50ZWVzIHRoYXQgd2UgYXJlCgkJICogYmVsb3cgdGhlIGZpcnN0IDE2TUIuCgkJICovCgoJCWZsYWdzID0gX19HRlBfRE1BIHwgX19HRlBfSElHSDsKCQl2YS0+bG9naWNhbCA9CgkJCSBfX2dldF9mcmVlX3BhZ2VzKGZsYWdzLCAtLW1heF9vcmRlcik7Cgl9IHdoaWxlICh2YS0+bG9naWNhbCA9PSAwICYmIG1heF9vcmRlciA+IG1pbl9vcmRlcik7CgoJaWYgKCF2YS0+bG9naWNhbCkKCQlyZXR1cm4gLUVOT01FTTsKCgl2YS0+cGh5cyA9IHZpcnRfdG9fcGh5cygodm9pZCAqKXZhLT5sb2dpY2FsKTsKCXZhLT5zaXplID0gUEFHRV9TSVpFIDw8IG1heF9vcmRlcjsKCXZhLT5vcmRlciA9IG1heF9vcmRlcjsKCgkvKgoJICogSXQgc2VlbXMgbGlrZSBfX2dldF9mcmVlX3BhZ2VzIG9ubHkgdXBzIHRoZSB1c2FnZSBjb3VudAoJICogb2YgdGhlIGZpcnN0IHBhZ2UuIFRoaXMgZG9lc24ndCB3b3JrIHdpdGggbm9wYWdlIG1hcHBpbmcsIHNvCgkgKiB1cCB0aGUgdXNhZ2UgY291bnQgb25jZSBtb3JlLgoJICovCgoJbWVtc2V0KCh2b2lkICopdmEtPmxvZ2ljYWwsIDB4MDAsIHZhLT5zaXplKTsKCWZvciAoaSA9IHZhLT5sb2dpY2FsOyBpIDwgdmEtPmxvZ2ljYWwgKyB2YS0+c2l6ZTsgaSArPSBQQUdFX1NJWkUpIHsKCQlnZXRfcGFnZSh2aXJ0X3RvX3BhZ2UoaSkpOwoJfQoKCS8qCgkgKiBDaGFuZ2UgY2FjaGluZyBwb2xpY3kgb2YgdGhlIGxpbmVhciBrZXJuZWwgbWFwIHRvIGF2b2lkCgkgKiBtYXBwaW5nIHR5cGUgY29uZmxpY3RzIHdpdGggdXNlci1zcGFjZSBtYXBwaW5ncy4KCSAqIFRoZSBmaXJzdCBnbG9iYWxfZmx1c2hfdGxiKCkgaXMgcmVhbGx5IG9ubHkgdGhlcmUgdG8gZG8gYSBnbG9iYWwKCSAqIHdiaW52ZCgpLgoJICovCgoJZ2xvYmFsX2ZsdXNoX3RsYigpOwoJY2hhbmdlX3BhZ2VfYXR0cih2aXJ0X3RvX3BhZ2UodmEtPmxvZ2ljYWwpLCB2YS0+c2l6ZSA+PiBQQUdFX1NISUZULAoJCQkgd2NfcGFnZXByb3QpOwoJZ2xvYmFsX2ZsdXNoX3RsYigpOwoKCXByaW50ayhLRVJOX0RFQlVHIE1PRFVMRV9OQU1FCgkgICAgICAgIjogQWxsb2NhdGVkICVsZCBieXRlcyB2cmFtIGFyZWEgYXQgMHglMDhseFxuIiwKCSAgICAgICB2YS0+c2l6ZSwgdmEtPnBoeXMpOwoKCXJldHVybiAwOwp9CgovKgogKiBGcmVlIGEgY29udGlndW91cyB2cmFtIGFyZWEgYW5kIHJlc2V0IGl0cyBsaW5lYXIga2VybmVsIG1hcAogKiBtYXBwaW5nIHR5cGUuCiAqLwoKc3RhdGljIHZvaWQgdm1sZmJfZnJlZV92cmFtX2FyZWEoc3RydWN0IHZyYW1fYXJlYSAqdmEpCnsKCXVuc2lnbmVkIGxvbmcgajsKCglpZiAodmEtPmxvZ2ljYWwpIHsKCgkJLyoKCQkgKiBSZXNldCB0aGUgbGluZWFyIGtlcm5lbCBtYXAgY2FjaGluZyBwb2xpY3kuCgkJICovCgoJCWNoYW5nZV9wYWdlX2F0dHIodmlydF90b19wYWdlKHZhLT5sb2dpY2FsKSwKCQkJCSB2YS0+c2l6ZSA+PiBQQUdFX1NISUZULCBQQUdFX0tFUk5FTCk7CgkJZ2xvYmFsX2ZsdXNoX3RsYigpOwoKCQkvKgoJCSAqIERlY3JlYXNlIHRoZSB1c2FnZSBjb3VudCBvbiB0aGUgcGFnZXMgd2UndmUgdXNlZAoJCSAqIHRvIGNvbXBlbnNhdGUgZm9yIHVwcGluZyB3aGVuIGFsbG9jYXRpbmcuCgkJICovCgoJCWZvciAoaiA9IHZhLT5sb2dpY2FsOyBqIDwgdmEtPmxvZ2ljYWwgKyB2YS0+c2l6ZTsKCQkgICAgIGogKz0gUEFHRV9TSVpFKSB7CgkJCSh2b2lkKXB1dF9wYWdlX3Rlc3R6ZXJvKHZpcnRfdG9fcGFnZShqKSk7CgkJfQoKCQlwcmludGsoS0VSTl9ERUJVRyBNT0RVTEVfTkFNRQoJCSAgICAgICAiOiBGcmVlaW5nICVsZCBieXRlcyB2cmFtIGFyZWEgYXQgMHglMDhseFxuIiwKCQkgICAgICAgdmEtPnNpemUsIHZhLT5waHlzKTsKCQlmcmVlX3BhZ2VzKHZhLT5sb2dpY2FsLCB2YS0+b3JkZXIpOwoKCQl2YS0+bG9naWNhbCA9IDA7Cgl9Cn0KCi8qCiAqIEZyZWUgYWxsb2NhdGVkIHZyYW0uCiAqLwoKc3RhdGljIHZvaWQgdm1sZmJfZnJlZV92cmFtKHN0cnVjdCB2bWxfaW5mbyAqdmluZm8pCnsKCWludCBpOwoKCWZvciAoaSA9IDA7IGkgPCB2aW5mby0+bnVtX2FyZWFzOyArK2kpIHsKCQl2bWxmYl9mcmVlX3ZyYW1fYXJlYSgmdmluZm8tPnZyYW1baV0pOwoJfQoJdmluZm8tPm51bV9hcmVhcyA9IDA7Cn0KCi8qCiAqIEFsbG9jYXRlIHZyYW0uIEN1cnJlbnRseSB3ZSB0cnkgdG8gYWxsb2NhdGUgY29udGlndW91cyBhcmVhcyBmcm9tIHRoZQogKiBfX0dGUF9ETUEgem9uZSBhbmQgcHV6emxlIHRoZW0gdG9nZXRoZXIuIEEgYmV0dGVyIGFwcHJvYWNoIHdvdWxkIGJlIHRvCiAqIGFsbG9jYXRlIG9uZSBjb250aWd1b3VzIGFyZWEgZm9yIHNjYW5vdXQgYW5kIHVzZSBvbmUtcGFnZSBhbGxvY2F0aW9ucyBmb3IKICogb2Zmc2NyZWVuIGFyZWFzLiBUaGlzIHJlcXVpcmVzIHVzZXItc3BhY2UgYW5kIEdQVSB2aXJ0dWFsIG1hcHBpbmdzLgogKi8KCnN0YXRpYyBpbnQgdm1sZmJfYWxsb2NfdnJhbShzdHJ1Y3Qgdm1sX2luZm8gKnZpbmZvLAoJCQkgICAgc2l6ZV90IHJlcXVlc3RlZCwKCQkJICAgIHNpemVfdCBtaW5fdG90YWwsIHNpemVfdCBtaW5fY29udGlnKQp7CglpbnQgaSwgajsKCWludCBvcmRlcjsKCWludCBjb250aWd1b3VzOwoJaW50IGVycjsKCXN0cnVjdCB2cmFtX2FyZWEgKnZhOwoJc3RydWN0IHZyYW1fYXJlYSAqdmEyOwoKCXZpbmZvLT5udW1fYXJlYXMgPSAwOwoJZm9yIChpID0gMDsgaSA8IFZNTF9WUkFNX0FSRUFTOyArK2kpIHsKCQl2YSA9ICZ2aW5mby0+dnJhbVtpXTsKCQlvcmRlciA9IDA7CgoJCXdoaWxlIChyZXF1ZXN0ZWQgPiAoUEFHRV9TSVpFIDw8IG9yZGVyKSAmJiBvcmRlciA8IE1BWF9PUkRFUikKCQkJb3JkZXIrKzsKCgkJZXJyID0gdm1sZmJfYWxsb2NfdnJhbV9hcmVhKHZhLCBvcmRlciwgMCk7CgoJCWlmIChlcnIpCgkJCWJyZWFrOwoKCQlpZiAoaSA9PSAwKSB7CgkJCXZpbmZvLT52cmFtX3N0YXJ0ID0gdmEtPnBoeXM7CgkJCXZpbmZvLT52cmFtX2xvZ2ljYWwgPSAodm9pZCBfX2lvbWVtICopIHZhLT5sb2dpY2FsOwoJCQl2aW5mby0+dnJhbV9jb250aWdfc2l6ZSA9IHZhLT5zaXplOwoJCQl2aW5mby0+bnVtX2FyZWFzID0gMTsKCQl9IGVsc2UgewoJCQljb250aWd1b3VzID0gMDsKCgkJCWZvciAoaiA9IDA7IGogPCBpOyArK2opIHsKCQkJCXZhMiA9ICZ2aW5mby0+dnJhbVtqXTsKCQkJCWlmICh2YS0+cGh5cyArIHZhLT5zaXplID09IHZhMi0+cGh5cyB8fAoJCQkJICAgIHZhMi0+cGh5cyArIHZhMi0+c2l6ZSA9PSB2YS0+cGh5cykgewoJCQkJCWNvbnRpZ3VvdXMgPSAxOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQl9CgoJCQlpZiAoY29udGlndW91cykgewoJCQkJdmluZm8tPm51bV9hcmVhcysrOwoJCQkJaWYgKHZhLT5waHlzIDwgdmluZm8tPnZyYW1fc3RhcnQpIHsKCQkJCQl2aW5mby0+dnJhbV9zdGFydCA9IHZhLT5waHlzOwoJCQkJCXZpbmZvLT52cmFtX2xvZ2ljYWwgPQoJCQkJCQkodm9pZCBfX2lvbWVtICopdmEtPmxvZ2ljYWw7CgkJCQl9CgkJCQl2aW5mby0+dnJhbV9jb250aWdfc2l6ZSArPSB2YS0+c2l6ZTsKCQkJfSBlbHNlIHsKCQkJCXZtbGZiX2ZyZWVfdnJhbV9hcmVhKHZhKTsKCQkJCWJyZWFrOwoJCQl9CgkJfQoKCQlpZiAocmVxdWVzdGVkIDwgdmEtPnNpemUpCgkJCWJyZWFrOwoJCWVsc2UKCQkJcmVxdWVzdGVkIC09IHZhLT5zaXplOwoJfQoKCWlmICh2aW5mby0+dnJhbV9jb250aWdfc2l6ZSA+IG1pbl90b3RhbCAmJgoJICAgIHZpbmZvLT52cmFtX2NvbnRpZ19zaXplID4gbWluX2NvbnRpZykgewoKCQlwcmludGsoS0VSTl9ERUJVRyBNT0RVTEVfTkFNRQoJCSAgICAgICAiOiBDb250aWd1b3VzIHZyYW06ICVsZCBieXRlcyBhdCBwaHlzaWNhbCAweCUwOGx4LlxuIiwKCQkgICAgICAgKHVuc2lnbmVkIGxvbmcpdmluZm8tPnZyYW1fY29udGlnX3NpemUsCgkJICAgICAgICh1bnNpZ25lZCBsb25nKXZpbmZvLT52cmFtX3N0YXJ0KTsKCgkJcmV0dXJuIDA7Cgl9CgoJcHJpbnRrKEtFUk5fRVJSIE1PRFVMRV9OQU1FCgkgICAgICAgIjogQ291bGQgbm90IGFsbG9jYXRlIHJlcXVlc3RlZCBtaW5pbWFsIGFtb3VudCBvZiB2cmFtLlxuIik7CgoJdm1sZmJfZnJlZV92cmFtKHZpbmZvKTsKCglyZXR1cm4gLUVOT01FTTsKfQoKLyoKICogRmluZCB0aGUgR1BVIHRvIHVzZSB3aXRoIG91ciBkaXNwbGF5IGNvbnRyb2xsZXIuCiAqLwoKc3RhdGljIGludCB2bWxmYl9nZXRfZ3B1KHN0cnVjdCB2bWxfcGFyICpwYXIpCnsKCW11dGV4X2xvY2soJnZtbF9tdXRleCk7CgoJcGFyLT5ncHUgPSBwY2lfZ2V0X2RldmljZShQQ0lfVkVORE9SX0lEX0lOVEVMLCBWTUxfREVWSUNFX0dQVSwgTlVMTCk7CgoJaWYgKCFwYXItPmdwdSkgewoJCW11dGV4X3VubG9jaygmdm1sX211dGV4KTsKCQlyZXR1cm4gLUVOT0RFVjsKCX0KCgltdXRleF91bmxvY2soJnZtbF9tdXRleCk7CgoJaWYgKHBjaV9lbmFibGVfZGV2aWNlKHBhci0+Z3B1KSA8IDApCgkJcmV0dXJuIC1FTk9ERVY7CgoJcmV0dXJuIDA7Cn0KCi8qCiAqIEZpbmQgYSBjb250aWd1b3VzIHZyYW0gYXJlYSB0aGF0IGNvbnRhaW5zIGEgZ2l2ZW4gb2Zmc2V0IGZyb20gdnJhbSBzdGFydC4KICovCnN0YXRpYyBpbnQgdm1sZmJfdnJhbV9vZmZzZXQoc3RydWN0IHZtbF9pbmZvICp2aW5mbywgdW5zaWduZWQgbG9uZyBvZmZzZXQpCnsKCXVuc2lnbmVkIGxvbmcgYW9mZnNldDsKCXVuc2lnbmVkIGk7CgoJZm9yIChpID0gMDsgaSA8IHZpbmZvLT5udW1fYXJlYXM7ICsraSkgewoJCWFvZmZzZXQgPSBvZmZzZXQgLSAodmluZm8tPnZyYW1baV0ucGh5cyAtIHZpbmZvLT52cmFtX3N0YXJ0KTsKCgkJaWYgKGFvZmZzZXQgPCB2aW5mby0+dnJhbVtpXS5zaXplKSB7CgkJCXJldHVybiAwOwoJCX0KCX0KCglyZXR1cm4gLUVJTlZBTDsKfQoKLyoKICogUmVtYXAgdGhlIE1NSU8gcmVnaXN0ZXIgc3BhY2VzIG9mIHRoZSBWREMgYW5kIHRoZSBHUFUuCiAqLwoKc3RhdGljIGludCB2bWxmYl9lbmFibGVfbW1pbyhzdHJ1Y3Qgdm1sX3BhciAqcGFyKQp7CglpbnQgZXJyOwoKCXBhci0+dmRjX21lbV9iYXNlID0gcGNpX3Jlc291cmNlX3N0YXJ0KHBhci0+dmRjLCAwKTsKCXBhci0+dmRjX21lbV9zaXplID0gcGNpX3Jlc291cmNlX2xlbihwYXItPnZkYywgMCk7CglpZiAoIXJlcXVlc3RfbWVtX3JlZ2lvbihwYXItPnZkY19tZW1fYmFzZSwgcGFyLT52ZGNfbWVtX3NpemUsICJ2bWxmYiIpKSB7CgkJcHJpbnRrKEtFUk5fRVJSIE1PRFVMRV9OQU1FCgkJICAgICAgICI6IENvdWxkIG5vdCBjbGFpbSBkaXNwbGF5IGNvbnRyb2xsZXIgTU1JTy5cbiIpOwoJCXJldHVybiAtRUJVU1k7Cgl9CglwYXItPnZkY19tZW0gPSBpb3JlbWFwX25vY2FjaGUocGFyLT52ZGNfbWVtX2Jhc2UsIHBhci0+dmRjX21lbV9zaXplKTsKCWlmIChwYXItPnZkY19tZW0gPT0gTlVMTCkgewoJCXByaW50ayhLRVJOX0VSUiBNT0RVTEVfTkFNRQoJCSAgICAgICAiOiBDb3VsZCBub3QgbWFwIGRpc3BsYXkgY29udHJvbGxlciBNTUlPLlxuIik7CgkJZXJyID0gLUVOT01FTTsKCQlnb3RvIG91dF9lcnJfMDsKCX0KCglwYXItPmdwdV9tZW1fYmFzZSA9IHBjaV9yZXNvdXJjZV9zdGFydChwYXItPmdwdSwgMCk7CglwYXItPmdwdV9tZW1fc2l6ZSA9IHBjaV9yZXNvdXJjZV9sZW4ocGFyLT5ncHUsIDApOwoJaWYgKCFyZXF1ZXN0X21lbV9yZWdpb24ocGFyLT5ncHVfbWVtX2Jhc2UsIHBhci0+Z3B1X21lbV9zaXplLCAidm1sZmIiKSkgewoJCXByaW50ayhLRVJOX0VSUiBNT0RVTEVfTkFNRSAiOiBDb3VsZCBub3QgY2xhaW0gR1BVIE1NSU8uXG4iKTsKCQllcnIgPSAtRUJVU1k7CgkJZ290byBvdXRfZXJyXzE7Cgl9CglwYXItPmdwdV9tZW0gPSBpb3JlbWFwX25vY2FjaGUocGFyLT5ncHVfbWVtX2Jhc2UsIHBhci0+Z3B1X21lbV9zaXplKTsKCWlmIChwYXItPmdwdV9tZW0gPT0gTlVMTCkgewoJCXByaW50ayhLRVJOX0VSUiBNT0RVTEVfTkFNRSAiOiBDb3VsZCBub3QgbWFwIEdQVSBNTUlPLlxuIik7CgkJZXJyID0gLUVOT01FTTsKCQlnb3RvIG91dF9lcnJfMjsKCX0KCglyZXR1cm4gMDsKCm91dF9lcnJfMjoKCXJlbGVhc2VfbWVtX3JlZ2lvbihwYXItPmdwdV9tZW1fYmFzZSwgcGFyLT5ncHVfbWVtX3NpemUpOwpvdXRfZXJyXzE6Cglpb3VubWFwKHBhci0+dmRjX21lbSk7Cm91dF9lcnJfMDoKCXJlbGVhc2VfbWVtX3JlZ2lvbihwYXItPnZkY19tZW1fYmFzZSwgcGFyLT52ZGNfbWVtX3NpemUpOwoJcmV0dXJuIGVycjsKfQoKLyoKICogVW5tYXAgdGhlIFZEQyBhbmQgR1BVIHJlZ2lzdGVyIHNwYWNlcy4KICovCgpzdGF0aWMgdm9pZCB2bWxmYl9kaXNhYmxlX21taW8oc3RydWN0IHZtbF9wYXIgKnBhcikKewoJaW91bm1hcChwYXItPmdwdV9tZW0pOwoJcmVsZWFzZV9tZW1fcmVnaW9uKHBhci0+Z3B1X21lbV9iYXNlLCBwYXItPmdwdV9tZW1fc2l6ZSk7Cglpb3VubWFwKHBhci0+dmRjX21lbSk7CglyZWxlYXNlX21lbV9yZWdpb24ocGFyLT52ZGNfbWVtX2Jhc2UsIHBhci0+dmRjX21lbV9zaXplKTsKfQoKLyoKICogUmVsZWFzZSBhbmQgdW5pbml0IHRoZSBWREMgYW5kIEdQVS4KICovCgpzdGF0aWMgdm9pZCB2bWxmYl9yZWxlYXNlX2RldmljZXMoc3RydWN0IHZtbF9wYXIgKnBhcikKewoJaWYgKGF0b21pY19kZWNfYW5kX3Rlc3QoJnBhci0+cmVmY291bnQpKSB7CgkJcGNpX3NldF9kcnZkYXRhKHBhci0+dmRjLCBOVUxMKTsKCQlwY2lfZGlzYWJsZV9kZXZpY2UocGFyLT5ncHUpOwoJCXBjaV9kaXNhYmxlX2RldmljZShwYXItPnZkYyk7Cgl9Cn0KCi8qCiAqIEZyZWUgdXAgYWxsb2NhdGVkIHJlc291cmNlcyBmb3IgYSBkZXZpY2UuCiAqLwoKc3RhdGljIHZvaWQgX19kZXZleGl0IHZtbF9wY2lfcmVtb3ZlKHN0cnVjdCBwY2lfZGV2ICpkZXYpCnsKCXN0cnVjdCBmYl9pbmZvICppbmZvOwoJc3RydWN0IHZtbF9pbmZvICp2aW5mbzsKCXN0cnVjdCB2bWxfcGFyICpwYXI7CgoJaW5mbyA9IHBjaV9nZXRfZHJ2ZGF0YShkZXYpOwoJaWYgKGluZm8pIHsKCQl2aW5mbyA9IGNvbnRhaW5lcl9vZihpbmZvLCBzdHJ1Y3Qgdm1sX2luZm8sIGluZm8pOwoJCXBhciA9IHZpbmZvLT5wYXI7CgkJbXV0ZXhfbG9jaygmdm1sX211dGV4KTsKCQl1bnJlZ2lzdGVyX2ZyYW1lYnVmZmVyKGluZm8pOwoJCWZiX2RlYWxsb2NfY21hcCgmaW5mby0+Y21hcCk7CgkJdm1sZmJfZnJlZV92cmFtKHZpbmZvKTsKCQl2bWxmYl9kaXNhYmxlX21taW8ocGFyKTsKCQl2bWxmYl9yZWxlYXNlX2RldmljZXMocGFyKTsKCQlrZnJlZSh2aW5mbyk7CgkJa2ZyZWUocGFyKTsKCQltdXRleF91bmxvY2soJnZtbF9tdXRleCk7Cgl9Cn0KCnN0YXRpYyB2b2lkIHZtbGZiX3NldF9wcmVmX3BpeGVsX2Zvcm1hdChzdHJ1Y3QgZmJfdmFyX3NjcmVlbmluZm8gKnZhcikKewoJc3dpdGNoICh2YXItPmJpdHNfcGVyX3BpeGVsKSB7CgljYXNlIDE2OgoJCXZhci0+Ymx1ZS5vZmZzZXQgPSAwOwoJCXZhci0+Ymx1ZS5sZW5ndGggPSA1OwoJCXZhci0+Z3JlZW4ub2Zmc2V0ID0gNTsKCQl2YXItPmdyZWVuLmxlbmd0aCA9IDU7CgkJdmFyLT5yZWQub2Zmc2V0ID0gMTA7CgkJdmFyLT5yZWQubGVuZ3RoID0gNTsKCQl2YXItPnRyYW5zcC5vZmZzZXQgPSAxNTsKCQl2YXItPnRyYW5zcC5sZW5ndGggPSAxOwoJCWJyZWFrOwoJY2FzZSAzMjoKCQl2YXItPmJsdWUub2Zmc2V0ID0gMDsKCQl2YXItPmJsdWUubGVuZ3RoID0gODsKCQl2YXItPmdyZWVuLm9mZnNldCA9IDg7CgkJdmFyLT5ncmVlbi5sZW5ndGggPSA4OwoJCXZhci0+cmVkLm9mZnNldCA9IDE2OwoJCXZhci0+cmVkLmxlbmd0aCA9IDg7CgkJdmFyLT50cmFuc3Aub2Zmc2V0ID0gMjQ7CgkJdmFyLT50cmFuc3AubGVuZ3RoID0gMDsKCQlicmVhazsKCWRlZmF1bHQ6CgkJYnJlYWs7Cgl9CgoJdmFyLT5ibHVlLm1zYl9yaWdodCA9IHZhci0+Z3JlZW4ubXNiX3JpZ2h0ID0KCSAgICB2YXItPnJlZC5tc2JfcmlnaHQgPSB2YXItPnRyYW5zcC5tc2JfcmlnaHQgPSAwOwp9CgovKgogKiBEZXZpY2UgaW5pdGlhbGl6YXRpb24uCiAqIFdlIGluaXRpYWxpemUgb25lIHZtbF9wYXIgc3RydWN0IHBlciBkZXZpY2UgYW5kIG9uZSB2bWxfaW5mbwogKiBzdHJ1Y3QgcGVyIHBpcGUuIEN1cnJlbnRseSB3ZSBoYXZlIG9ubHkgb25lIHBpcGUuCiAqLwoKc3RhdGljIGludCBfX2RldmluaXQgdm1sX3BjaV9wcm9iZShzdHJ1Y3QgcGNpX2RldiAqZGV2LAoJCQkJICAgY29uc3Qgc3RydWN0IHBjaV9kZXZpY2VfaWQgKmlkKQp7CglzdHJ1Y3Qgdm1sX2luZm8gKnZpbmZvOwoJc3RydWN0IGZiX2luZm8gKmluZm87CglzdHJ1Y3Qgdm1sX3BhciAqcGFyOwoJaW50IGVyciA9IDA7CgoJcGFyID0ga3phbGxvYyhzaXplb2YoKnBhciksIEdGUF9LRVJORUwpOwoJaWYgKHBhciA9PSBOVUxMKQoJCXJldHVybiAtRU5PTUVNOwoKCXZpbmZvID0ga3phbGxvYyhzaXplb2YoKnZpbmZvKSwgR0ZQX0tFUk5FTCk7CglpZiAodmluZm8gPT0gTlVMTCkgewoJCWVyciA9IC1FTk9NRU07CgkJZ290byBvdXRfZXJyXzA7Cgl9CgoJdmluZm8tPnBhciA9IHBhcjsKCXBhci0+dmRjID0gZGV2OwoJYXRvbWljX3NldCgmcGFyLT5yZWZjb3VudCwgMSk7CgoJc3dpdGNoIChpZC0+ZGV2aWNlKSB7CgljYXNlIFZNTF9ERVZJQ0VfVkRDOgoJCWlmICgoZXJyID0gdm1sZmJfZ2V0X2dwdShwYXIpKSkKCQkJZ290byBvdXRfZXJyXzE7CgkJcGNpX3NldF9kcnZkYXRhKGRldiwgJnZpbmZvLT5pbmZvKTsKCQlicmVhazsKCWRlZmF1bHQ6CgkJZXJyID0gLUVOT0RFVjsKCQlnb3RvIG91dF9lcnJfMTsKCQlicmVhazsKCX0KCglpbmZvID0gJnZpbmZvLT5pbmZvOwoJaW5mby0+ZmxhZ3MgPSBGQklORk9fREVGQVVMVCB8IEZCSU5GT19QQVJUSUFMX1BBTl9PSzsKCgllcnIgPSB2bWxmYl9lbmFibGVfbW1pbyhwYXIpOwoJaWYgKGVycikKCQlnb3RvIG91dF9lcnJfMjsKCgllcnIgPSB2bWxmYl9hbGxvY192cmFtKHZpbmZvLCB2bWxfbWVtX3JlcXVlc3RlZCwKCQkJICAgICAgIHZtbF9tZW1fY29udGlnLCB2bWxfbWVtX21pbik7CglpZiAoZXJyKQoJCWdvdG8gb3V0X2Vycl8zOwoKCXN0cmNweShpbmZvLT5maXguaWQsICJWZXJtaWxpb24gUmFuZ2UiKTsKCWluZm8tPmZpeC5tbWlvX3N0YXJ0ID0gMDsKCWluZm8tPmZpeC5tbWlvX2xlbiA9IDA7CglpbmZvLT5maXguc21lbV9zdGFydCA9IHZpbmZvLT52cmFtX3N0YXJ0OwoJaW5mby0+Zml4LnNtZW1fbGVuID0gdmluZm8tPnZyYW1fY29udGlnX3NpemU7CglpbmZvLT5maXgudHlwZSA9IEZCX1RZUEVfUEFDS0VEX1BJWEVMUzsKCWluZm8tPmZpeC52aXN1YWwgPSBGQl9WSVNVQUxfVFJVRUNPTE9SOwoJaW5mby0+Zml4LnlwYW5zdGVwID0gMTsKCWluZm8tPmZpeC54cGFuc3RlcCA9IDE7CglpbmZvLT5maXgueXdyYXBzdGVwID0gMDsKCWluZm8tPmZpeC5hY2NlbCA9IEZCX0FDQ0VMX05PTkU7CglpbmZvLT5zY3JlZW5fYmFzZSA9IHZpbmZvLT52cmFtX2xvZ2ljYWw7CglpbmZvLT5wc2V1ZG9fcGFsZXR0ZSA9IHZpbmZvLT5wc2V1ZG9fcGFsZXR0ZTsKCWluZm8tPnBhciA9IHBhcjsKCWluZm8tPmZib3BzID0gJnZtbGZiX29wczsKCWluZm8tPmRldmljZSA9ICZkZXYtPmRldjsKCglJTklUX0xJU1RfSEVBRCgmdmluZm8tPmhlYWQpOwoJdmluZm8tPnBpcGVfZGlzYWJsZWQgPSAxOwoJdmluZm8tPmN1cl9ibGFua19tb2RlID0gRkJfQkxBTktfVU5CTEFOSzsKCglpbmZvLT52YXIuZ3JheXNjYWxlID0gMDsKCWluZm8tPnZhci5iaXRzX3Blcl9waXhlbCA9IDE2OwoJdm1sZmJfc2V0X3ByZWZfcGl4ZWxfZm9ybWF0KCZpbmZvLT52YXIpOwoKCWlmICghZmJfZmluZF9tb2RlCgkgICAgKCZpbmZvLT52YXIsIGluZm8sIHZtbF9kZWZhdWx0X21vZGUsIE5VTEwsIDAsICZkZWZhdWx0bW9kZSwgMTYpKSB7CgkJcHJpbnRrKEtFUk5fRVJSIE1PRFVMRV9OQU1FICI6IENvdWxkIG5vdCBmaW5kIGluaXRpYWwgbW9kZVxuIik7Cgl9CgoJaWYgKGZiX2FsbG9jX2NtYXAoJmluZm8tPmNtYXAsIDI1NiwgMSkgPCAwKSB7CgkJZXJyID0gLUVOT01FTTsKCQlnb3RvIG91dF9lcnJfNDsKCX0KCgllcnIgPSByZWdpc3Rlcl9mcmFtZWJ1ZmZlcihpbmZvKTsKCWlmIChlcnIpIHsKCQlwcmludGsoS0VSTl9FUlIgTU9EVUxFX05BTUUgIjogUmVnaXN0ZXIgZnJhbWVidWZmZXIgZXJyb3IuXG4iKTsKCQlnb3RvIG91dF9lcnJfNTsKCX0KCglwcmludGsoIkluaXRpYWxpemVkIHZtbGZiXG4iKTsKCglyZXR1cm4gMDsKCm91dF9lcnJfNToKCWZiX2RlYWxsb2NfY21hcCgmaW5mby0+Y21hcCk7Cm91dF9lcnJfNDoKCXZtbGZiX2ZyZWVfdnJhbSh2aW5mbyk7Cm91dF9lcnJfMzoKCXZtbGZiX2Rpc2FibGVfbW1pbyhwYXIpOwpvdXRfZXJyXzI6Cgl2bWxmYl9yZWxlYXNlX2RldmljZXMocGFyKTsKb3V0X2Vycl8xOgoJa2ZyZWUodmluZm8pOwpvdXRfZXJyXzA6CglrZnJlZShwYXIpOwoJcmV0dXJuIGVycjsKfQoKc3RhdGljIGludCB2bWxmYl9vcGVuKHN0cnVjdCBmYl9pbmZvICppbmZvLCBpbnQgdXNlcikKewoJLyoKCSAqIFNhdmUgcmVnaXN0ZXJzIGhlcmU/CgkgKi8KCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHZtbGZiX3JlbGVhc2Uoc3RydWN0IGZiX2luZm8gKmluZm8sIGludCB1c2VyKQp7CgkvKgoJICogUmVzdG9yZSByZWdpc3RlcnMgaGVyZS4KCSAqLwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHZtbF9uZWFyZXN0X2Nsb2NrKGludCBjbG9jaykKewoKCWludCBpOwoJaW50IGN1cl9pbmRleDsKCWludCBjdXJfZGlmZjsKCWludCBkaWZmOwoKCWN1cl9pbmRleCA9IDA7CgljdXJfZGlmZiA9IGNsb2NrIC0gdm1sX2Nsb2Nrc1swXTsKCWN1cl9kaWZmID0gKGN1cl9kaWZmIDwgMCkgPyAtY3VyX2RpZmYgOiBjdXJfZGlmZjsKCWZvciAoaSA9IDE7IGkgPCB2bWxfbnVtX2Nsb2NrczsgKytpKSB7CgkJZGlmZiA9IGNsb2NrIC0gdm1sX2Nsb2Nrc1tpXTsKCQlkaWZmID0gKGRpZmYgPCAwKSA/IC1kaWZmIDogZGlmZjsKCQlpZiAoZGlmZiA8IGN1cl9kaWZmKSB7CgkJCWN1cl9pbmRleCA9IGk7CgkJCWN1cl9kaWZmID0gZGlmZjsKCQl9Cgl9CglyZXR1cm4gdm1sX2Nsb2Nrc1tjdXJfaW5kZXhdOwp9CgpzdGF0aWMgaW50IHZtbGZiX2NoZWNrX3Zhcl9sb2NrZWQoc3RydWN0IGZiX3Zhcl9zY3JlZW5pbmZvICp2YXIsCgkJCQkgIHN0cnVjdCB2bWxfaW5mbyAqdmluZm8pCnsKCXUzMiBwaXRjaDsKCXU2NCBtZW07CglpbnQgbmVhcmVzdF9jbG9jazsKCWludCBjbG9jazsKCWludCBjbG9ja19kaWZmOwoJc3RydWN0IGZiX3Zhcl9zY3JlZW5pbmZvIHY7CgoJdiA9ICp2YXI7CgljbG9jayA9IFBJQ09TMktIWih2YXItPnBpeGNsb2NrKTsKCglpZiAoc3Vic3lzICYmIHN1YnN5cy0+bmVhcmVzdF9jbG9jaykgewoJCW5lYXJlc3RfY2xvY2sgPSBzdWJzeXMtPm5lYXJlc3RfY2xvY2soc3Vic3lzLCBjbG9jayk7Cgl9IGVsc2UgewoJCW5lYXJlc3RfY2xvY2sgPSB2bWxfbmVhcmVzdF9jbG9jayhjbG9jayk7Cgl9CgoJLyoKCSAqIEFjY2VwdCBhIDIwJSBkaWZmLgoJICovCgoJY2xvY2tfZGlmZiA9IG5lYXJlc3RfY2xvY2sgLSBjbG9jazsKCWNsb2NrX2RpZmYgPSAoY2xvY2tfZGlmZiA8IDApID8gLWNsb2NrX2RpZmYgOiBjbG9ja19kaWZmOwoJaWYgKGNsb2NrX2RpZmYgPiBjbG9jayAvIDUpIHsKI2lmIDAKCQlwcmludGsoS0VSTl9ERUJVRyBNT0RVTEVfTkFNRSAiOiBEaWZmIGZhaWx1cmUuICVkICVkXG4iLGNsb2NrX2RpZmYsY2xvY2spOwojZW5kaWYKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCgl2LnBpeGNsb2NrID0gS0haMlBJQ09TKG5lYXJlc3RfY2xvY2spOwoKCWlmICh2YXItPnhyZXMgPiBWTUxfTUFYX1hSRVMgfHwgdmFyLT55cmVzID4gVk1MX01BWF9ZUkVTKSB7CgkJcHJpbnRrKEtFUk5fREVCVUcgTU9EVUxFX05BTUUgIjogUmVzb2x1dGlvbiBmYWlsdXJlLlxuIik7CgkJcmV0dXJuIC1FSU5WQUw7Cgl9CglpZiAodmFyLT54cmVzX3ZpcnR1YWwgPiBWTUxfTUFYX1hSRVNfVklSVFVBTCkgewoJCXByaW50ayhLRVJOX0RFQlVHIE1PRFVMRV9OQU1FCgkJICAgICAgICI6IFZpcnR1YWwgcmVzb2x1dGlvbiBmYWlsdXJlLlxuIik7CgkJcmV0dXJuIC1FSU5WQUw7Cgl9Cglzd2l0Y2ggKHYuYml0c19wZXJfcGl4ZWwpIHsKCWNhc2UgMCAuLi4gMTY6CgkJdi5iaXRzX3Blcl9waXhlbCA9IDE2OwoJCWJyZWFrOwoJY2FzZSAxNyAuLi4gMzI6CgkJdi5iaXRzX3Blcl9waXhlbCA9IDMyOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlwcmludGsoS0VSTl9ERUJVRyBNT0RVTEVfTkFNRSAiOiBJbnZhbGlkIGJwcDogJWQuXG4iLAoJCSAgICAgICB2YXItPmJpdHNfcGVyX3BpeGVsKTsKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCglwaXRjaCA9IF9fQUxJR05fTUFTSygodmFyLT54cmVzICogdmFyLT5iaXRzX3Blcl9waXhlbCkgPj4gMywgMHgzRik7CgltZW0gPSBwaXRjaCAqIHZhci0+eXJlc192aXJ0dWFsOwoJaWYgKG1lbSA+IHZpbmZvLT52cmFtX2NvbnRpZ19zaXplKSB7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CgoJc3dpdGNoICh2LmJpdHNfcGVyX3BpeGVsKSB7CgljYXNlIDE2OgoJCWlmICh2YXItPmJsdWUub2Zmc2V0ICE9IDAgfHwKCQkgICAgdmFyLT5ibHVlLmxlbmd0aCAhPSA1IHx8CgkJICAgIHZhci0+Z3JlZW4ub2Zmc2V0ICE9IDUgfHwKCQkgICAgdmFyLT5ncmVlbi5sZW5ndGggIT0gNSB8fAoJCSAgICB2YXItPnJlZC5vZmZzZXQgIT0gMTAgfHwKCQkgICAgdmFyLT5yZWQubGVuZ3RoICE9IDUgfHwKCQkgICAgdmFyLT50cmFuc3Aub2Zmc2V0ICE9IDE1IHx8IHZhci0+dHJhbnNwLmxlbmd0aCAhPSAxKSB7CgkJCXZtbGZiX3NldF9wcmVmX3BpeGVsX2Zvcm1hdCgmdik7CgkJfQoJCWJyZWFrOwoJY2FzZSAzMjoKCQlpZiAodmFyLT5ibHVlLm9mZnNldCAhPSAwIHx8CgkJICAgIHZhci0+Ymx1ZS5sZW5ndGggIT0gOCB8fAoJCSAgICB2YXItPmdyZWVuLm9mZnNldCAhPSA4IHx8CgkJICAgIHZhci0+Z3JlZW4ubGVuZ3RoICE9IDggfHwKCQkgICAgdmFyLT5yZWQub2Zmc2V0ICE9IDE2IHx8CgkJICAgIHZhci0+cmVkLmxlbmd0aCAhPSA4IHx8CgkJICAgICh2YXItPnRyYW5zcC5sZW5ndGggIT0gMCAmJiB2YXItPnRyYW5zcC5sZW5ndGggIT0gOCkgfHwKCQkgICAgKHZhci0+dHJhbnNwLmxlbmd0aCA9PSA4ICYmIHZhci0+dHJhbnNwLm9mZnNldCAhPSAyNCkpIHsKCQkJdm1sZmJfc2V0X3ByZWZfcGl4ZWxfZm9ybWF0KCZ2KTsKCQl9CgkJYnJlYWs7CglkZWZhdWx0OgoJCXJldHVybiAtRUlOVkFMOwoJfQoKCSp2YXIgPSB2OwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHZtbGZiX2NoZWNrX3ZhcihzdHJ1Y3QgZmJfdmFyX3NjcmVlbmluZm8gKnZhciwgc3RydWN0IGZiX2luZm8gKmluZm8pCnsKCXN0cnVjdCB2bWxfaW5mbyAqdmluZm8gPSBjb250YWluZXJfb2YoaW5mbywgc3RydWN0IHZtbF9pbmZvLCBpbmZvKTsKCWludCByZXQ7CgoJbXV0ZXhfbG9jaygmdm1sX211dGV4KTsKCXJldCA9IHZtbGZiX2NoZWNrX3Zhcl9sb2NrZWQodmFyLCB2aW5mbyk7CgltdXRleF91bmxvY2soJnZtbF9tdXRleCk7CgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIHZvaWQgdm1sX3dhaXRfdmJsYW5rKHN0cnVjdCB2bWxfaW5mbyAqdmluZm8pCnsKCS8qIFdhaXQgZm9yIHZibGFuay4gRm9yIG5vdywganVzdCB3YWl0IGZvciBhIDUwSHogY3ljbGUgKDIwbXMpKSAqLwoJbWRlbGF5KDIwKTsKfQoKc3RhdGljIHZvaWQgdm1sZmJfZGlzYWJsZV9waXBlKHN0cnVjdCB2bWxfaW5mbyAqdmluZm8pCnsKCXN0cnVjdCB2bWxfcGFyICpwYXIgPSB2aW5mby0+cGFyOwoKCS8qIERpc2FibGUgdGhlIE1EVk8gcGFkICovCglWTUxfV1JJVEUzMihwYXIsIFZNTF9SQ09NUFNUQVQsIDApOwoJd2hpbGUgKCEoVk1MX1JFQUQzMihwYXIsIFZNTF9SQ09NUFNUQVQpICYgVk1MX01EVk9fVkRDX0lfUkNPTVApKSA7CgoJLyogRGlzYWJsZSBkaXNwbGF5IHBsYW5lcyAqLwoJVk1MX1dSSVRFMzIocGFyLCBWTUxfRFNQQ0NOVFIsCgkJICAgIFZNTF9SRUFEMzIocGFyLCBWTUxfRFNQQ0NOVFIpICYgflZNTF9HRlhfRU5BQkxFKTsKCSh2b2lkKVZNTF9SRUFEMzIocGFyLCBWTUxfRFNQQ0NOVFIpOwoJLyogV2FpdCBmb3IgdmJsYW5rIGZvciB0aGUgZGlzYWJsZSB0byB0YWtlIGVmZmVjdCAqLwoJdm1sX3dhaXRfdmJsYW5rKHZpbmZvKTsKCgkvKiBOZXh0LCBkaXNhYmxlIGRpc3BsYXkgcGlwZXMgKi8KCVZNTF9XUklURTMyKHBhciwgVk1MX1BJUEVBQ09ORiwgMCk7Cgkodm9pZClWTUxfUkVBRDMyKHBhciwgVk1MX1BJUEVBQ09ORik7CgoJdmluZm8tPnBpcGVfZGlzYWJsZWQgPSAxOwp9CgojaWZkZWYgVkVSTUlMSU9OX0RFQlVHCnN0YXRpYyB2b2lkIHZtbF9kdW1wX3JlZ3Moc3RydWN0IHZtbF9pbmZvICp2aW5mbykKewoJc3RydWN0IHZtbF9wYXIgKnBhciA9IHZpbmZvLT5wYXI7CgoJcHJpbnRrKEtFUk5fREVCVUcgTU9EVUxFX05BTUUgIjogTW9kZXNldHRpbmcgcmVnaXN0ZXIgZHVtcDpcbiIpOwoJcHJpbnRrKEtFUk5fREVCVUcgTU9EVUxFX05BTUUgIjogXHRIVE9UQUxfQSAgICAgICAgIDogMHglMDh4XG4iLAoJICAgICAgICh1bnNpZ25lZClWTUxfUkVBRDMyKHBhciwgVk1MX0hUT1RBTF9BKSk7CglwcmludGsoS0VSTl9ERUJVRyBNT0RVTEVfTkFNRSAiOiBcdEhCTEFOS19BICAgICAgICAgOiAweCUwOHhcbiIsCgkgICAgICAgKHVuc2lnbmVkKVZNTF9SRUFEMzIocGFyLCBWTUxfSEJMQU5LX0EpKTsKCXByaW50ayhLRVJOX0RFQlVHIE1PRFVMRV9OQU1FICI6IFx0SFNZTkNfQSAgICAgICAgICA6IDB4JTA4eFxuIiwKCSAgICAgICAodW5zaWduZWQpVk1MX1JFQUQzMihwYXIsIFZNTF9IU1lOQ19BKSk7CglwcmludGsoS0VSTl9ERUJVRyBNT0RVTEVfTkFNRSAiOiBcdFZUT1RBTF9BICAgICAgICAgOiAweCUwOHhcbiIsCgkgICAgICAgKHVuc2lnbmVkKVZNTF9SRUFEMzIocGFyLCBWTUxfVlRPVEFMX0EpKTsKCXByaW50ayhLRVJOX0RFQlVHIE1PRFVMRV9OQU1FICI6IFx0VkJMQU5LX0EgICAgICAgICA6IDB4JTA4eFxuIiwKCSAgICAgICAodW5zaWduZWQpVk1MX1JFQUQzMihwYXIsIFZNTF9WQkxBTktfQSkpOwoJcHJpbnRrKEtFUk5fREVCVUcgTU9EVUxFX05BTUUgIjogXHRWU1lOQ19BICAgICAgICAgIDogMHglMDh4XG4iLAoJICAgICAgICh1bnNpZ25lZClWTUxfUkVBRDMyKHBhciwgVk1MX1ZTWU5DX0EpKTsKCXByaW50ayhLRVJOX0RFQlVHIE1PRFVMRV9OQU1FICI6IFx0RFNQQ1NUUklERSAgICAgICA6IDB4JTA4eFxuIiwKCSAgICAgICAodW5zaWduZWQpVk1MX1JFQUQzMihwYXIsIFZNTF9EU1BDU1RSSURFKSk7CglwcmludGsoS0VSTl9ERUJVRyBNT0RVTEVfTkFNRSAiOiBcdERTUENTSVpFICAgICAgICAgOiAweCUwOHhcbiIsCgkgICAgICAgKHVuc2lnbmVkKVZNTF9SRUFEMzIocGFyLCBWTUxfRFNQQ1NJWkUpKTsKCXByaW50ayhLRVJOX0RFQlVHIE1PRFVMRV9OQU1FICI6IFx0RFNQQ1BPUyAgICAgICAgICA6IDB4JTA4eFxuIiwKCSAgICAgICAodW5zaWduZWQpVk1MX1JFQUQzMihwYXIsIFZNTF9EU1BDUE9TKSk7CglwcmludGsoS0VSTl9ERUJVRyBNT0RVTEVfTkFNRSAiOiBcdERTUEFSQiAgICAgICAgICAgOiAweCUwOHhcbiIsCgkgICAgICAgKHVuc2lnbmVkKVZNTF9SRUFEMzIocGFyLCBWTUxfRFNQQVJCKSk7CglwcmludGsoS0VSTl9ERUJVRyBNT0RVTEVfTkFNRSAiOiBcdERTUENBRERSICAgICAgICAgOiAweCUwOHhcbiIsCgkgICAgICAgKHVuc2lnbmVkKVZNTF9SRUFEMzIocGFyLCBWTUxfRFNQQ0FERFIpKTsKCXByaW50ayhLRVJOX0RFQlVHIE1PRFVMRV9OQU1FICI6IFx0QkNMUlBBVF9BICAgICAgICA6IDB4JTA4eFxuIiwKCSAgICAgICAodW5zaWduZWQpVk1MX1JFQUQzMihwYXIsIFZNTF9CQ0xSUEFUX0EpKTsKCXByaW50ayhLRVJOX0RFQlVHIE1PRFVMRV9OQU1FICI6IFx0Q0FOVlNDTFJfQSAgICAgICA6IDB4JTA4eFxuIiwKCSAgICAgICAodW5zaWduZWQpVk1MX1JFQUQzMihwYXIsIFZNTF9DQU5WU0NMUl9BKSk7CglwcmludGsoS0VSTl9ERUJVRyBNT0RVTEVfTkFNRSAiOiBcdFBJUEVBU1JDICAgICAgICAgOiAweCUwOHhcbiIsCgkgICAgICAgKHVuc2lnbmVkKVZNTF9SRUFEMzIocGFyLCBWTUxfUElQRUFTUkMpKTsKCXByaW50ayhLRVJOX0RFQlVHIE1PRFVMRV9OQU1FICI6IFx0UElQRUFDT05GICAgICAgICA6IDB4JTA4eFxuIiwKCSAgICAgICAodW5zaWduZWQpVk1MX1JFQUQzMihwYXIsIFZNTF9QSVBFQUNPTkYpKTsKCXByaW50ayhLRVJOX0RFQlVHIE1PRFVMRV9OQU1FICI6IFx0RFNQQ0NOVFIgICAgICAgICA6IDB4JTA4eFxuIiwKCSAgICAgICAodW5zaWduZWQpVk1MX1JFQUQzMihwYXIsIFZNTF9EU1BDQ05UUikpOwoJcHJpbnRrKEtFUk5fREVCVUcgTU9EVUxFX05BTUUgIjogXHRSQ09NUFNUQVQgICAgICAgIDogMHglMDh4XG4iLAoJICAgICAgICh1bnNpZ25lZClWTUxfUkVBRDMyKHBhciwgVk1MX1JDT01QU1RBVCkpOwoJcHJpbnRrKEtFUk5fREVCVUcgTU9EVUxFX05BTUUgIjogRW5kIG9mIG1vZGVzZXR0aW5nIHJlZ2lzdGVyIGR1bXAuXG4iKTsKfQojZW5kaWYKCnN0YXRpYyBpbnQgdm1sZmJfc2V0X3Bhcl9sb2NrZWQoc3RydWN0IHZtbF9pbmZvICp2aW5mbykKewoJc3RydWN0IHZtbF9wYXIgKnBhciA9IHZpbmZvLT5wYXI7CglzdHJ1Y3QgZmJfaW5mbyAqaW5mbyA9ICZ2aW5mby0+aW5mbzsKCXN0cnVjdCBmYl92YXJfc2NyZWVuaW5mbyAqdmFyID0gJmluZm8tPnZhcjsKCXUzMiBodG90YWwsIGhhY3RpdmUsIGhibGFua19zdGFydCwgaGJsYW5rX2VuZCwgaHN5bmNfc3RhcnQsIGhzeW5jX2VuZDsKCXUzMiB2dG90YWwsIHZhY3RpdmUsIHZibGFua19zdGFydCwgdmJsYW5rX2VuZCwgdnN5bmNfc3RhcnQsIHZzeW5jX2VuZDsKCXUzMiBkc3BjbnRyOwoJaW50IGNsb2NrOwoKCXZpbmZvLT5ieXRlc19wZXJfcGl4ZWwgPSB2YXItPmJpdHNfcGVyX3BpeGVsID4+IDM7Cgl2aW5mby0+c3RyaWRlID0KCSAgICBfX0FMSUdOX01BU0sodmFyLT54cmVzX3ZpcnR1YWwgKiB2aW5mby0+Ynl0ZXNfcGVyX3BpeGVsLCAweDNGKTsKCWluZm8tPmZpeC5saW5lX2xlbmd0aCA9IHZpbmZvLT5zdHJpZGU7CgoJaWYgKCFzdWJzeXMpCgkJcmV0dXJuIDA7CgoJaHRvdGFsID0KCSAgICB2YXItPnhyZXMgKyB2YXItPnJpZ2h0X21hcmdpbiArIHZhci0+aHN5bmNfbGVuICsgdmFyLT5sZWZ0X21hcmdpbjsKCWhhY3RpdmUgPSB2YXItPnhyZXM7CgloYmxhbmtfc3RhcnQgPSB2YXItPnhyZXM7CgloYmxhbmtfZW5kID0gaHRvdGFsOwoJaHN5bmNfc3RhcnQgPSBoYWN0aXZlICsgdmFyLT5yaWdodF9tYXJnaW47Cgloc3luY19lbmQgPSBoc3luY19zdGFydCArIHZhci0+aHN5bmNfbGVuOwoKCXZ0b3RhbCA9CgkgICAgdmFyLT55cmVzICsgdmFyLT5sb3dlcl9tYXJnaW4gKyB2YXItPnZzeW5jX2xlbiArIHZhci0+dXBwZXJfbWFyZ2luOwoJdmFjdGl2ZSA9IHZhci0+eXJlczsKCXZibGFua19zdGFydCA9IHZhci0+eXJlczsKCXZibGFua19lbmQgPSB2dG90YWw7Cgl2c3luY19zdGFydCA9IHZhY3RpdmUgKyB2YXItPmxvd2VyX21hcmdpbjsKCXZzeW5jX2VuZCA9IHZzeW5jX3N0YXJ0ICsgdmFyLT52c3luY19sZW47CgoJZHNwY250ciA9IFZNTF9HRlhfRU5BQkxFIHwgVk1MX0dGWF9HQU1NQUJZUEFTUzsKCWNsb2NrID0gUElDT1MyS0haKHZhci0+cGl4Y2xvY2spOwoKCWlmIChzdWJzeXMtPm5lYXJlc3RfY2xvY2spIHsKCQljbG9jayA9IHN1YnN5cy0+bmVhcmVzdF9jbG9jayhzdWJzeXMsIGNsb2NrKTsKCX0gZWxzZSB7CgkJY2xvY2sgPSB2bWxfbmVhcmVzdF9jbG9jayhjbG9jayk7Cgl9CglwcmludGsoS0VSTl9ERUJVRyBNT0RVTEVfTkFNRQoJICAgICAgICI6IFNldCBtb2RlIEhmcmVxIDogJWQga0h6LCBWZnJlcSA6ICVkIEh6LlxuIiwgY2xvY2sgLyBodG90YWwsCgkgICAgICAgKChjbG9jayAvIGh0b3RhbCkgKiAxMDAwKSAvIHZ0b3RhbCk7CgoJc3dpdGNoICh2YXItPmJpdHNfcGVyX3BpeGVsKSB7CgljYXNlIDE2OgoJCWRzcGNudHIgfD0gVk1MX0dGWF9BUkdCMTU1NTsKCQlicmVhazsKCWNhc2UgMzI6CgkJaWYgKHZhci0+dHJhbnNwLmxlbmd0aCA9PSA4KQoJCQlkc3BjbnRyIHw9IFZNTF9HRlhfQVJHQjg4ODggfCBWTUxfR0ZYX0FMUEhBTVVMVDsKCQllbHNlCgkJCWRzcGNudHIgfD0gVk1MX0dGWF9SR0IwODg4OwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCgl2bWxmYl9kaXNhYmxlX3BpcGUodmluZm8pOwoJbWIoKTsKCglpZiAoc3Vic3lzLT5zZXRfY2xvY2spCgkJc3Vic3lzLT5zZXRfY2xvY2soc3Vic3lzLCBjbG9jayk7CgllbHNlCgkJcmV0dXJuIC1FSU5WQUw7CgoJVk1MX1dSSVRFMzIocGFyLCBWTUxfSFRPVEFMX0EsICgoaHRvdGFsIC0gMSkgPDwgMTYpIHwgKGhhY3RpdmUgLSAxKSk7CglWTUxfV1JJVEUzMihwYXIsIFZNTF9IQkxBTktfQSwKCQkgICAgKChoYmxhbmtfZW5kIC0gMSkgPDwgMTYpIHwgKGhibGFua19zdGFydCAtIDEpKTsKCVZNTF9XUklURTMyKHBhciwgVk1MX0hTWU5DX0EsCgkJICAgICgoaHN5bmNfZW5kIC0gMSkgPDwgMTYpIHwgKGhzeW5jX3N0YXJ0IC0gMSkpOwoJVk1MX1dSSVRFMzIocGFyLCBWTUxfVlRPVEFMX0EsICgodnRvdGFsIC0gMSkgPDwgMTYpIHwgKHZhY3RpdmUgLSAxKSk7CglWTUxfV1JJVEUzMihwYXIsIFZNTF9WQkxBTktfQSwKCQkgICAgKCh2YmxhbmtfZW5kIC0gMSkgPDwgMTYpIHwgKHZibGFua19zdGFydCAtIDEpKTsKCVZNTF9XUklURTMyKHBhciwgVk1MX1ZTWU5DX0EsCgkJICAgICgodnN5bmNfZW5kIC0gMSkgPDwgMTYpIHwgKHZzeW5jX3N0YXJ0IC0gMSkpOwoJVk1MX1dSSVRFMzIocGFyLCBWTUxfRFNQQ1NUUklERSwgdmluZm8tPnN0cmlkZSk7CglWTUxfV1JJVEUzMihwYXIsIFZNTF9EU1BDU0laRSwKCQkgICAgKCh2YXItPnlyZXMgLSAxKSA8PCAxNikgfCAodmFyLT54cmVzIC0gMSkpOwoJVk1MX1dSSVRFMzIocGFyLCBWTUxfRFNQQ1BPUywgMHgwMDAwMDAwMCk7CglWTUxfV1JJVEUzMihwYXIsIFZNTF9EU1BBUkIsIFZNTF9GSUZPX0RFRkFVTFQpOwoJVk1MX1dSSVRFMzIocGFyLCBWTUxfQkNMUlBBVF9BLCAweDAwMDAwMDAwKTsKCVZNTF9XUklURTMyKHBhciwgVk1MX0NBTlZTQ0xSX0EsIDB4MDAwMDAwMDApOwoJVk1MX1dSSVRFMzIocGFyLCBWTUxfUElQRUFTUkMsCgkJICAgICgodmFyLT54cmVzIC0gMSkgPDwgMTYpIHwgKHZhci0+eXJlcyAtIDEpKTsKCgl3bWIoKTsKCVZNTF9XUklURTMyKHBhciwgVk1MX1BJUEVBQ09ORiwgVk1MX1BJUEVfRU5BQkxFKTsKCXdtYigpOwoJVk1MX1dSSVRFMzIocGFyLCBWTUxfRFNQQ0NOVFIsIGRzcGNudHIpOwoJd21iKCk7CglWTUxfV1JJVEUzMihwYXIsIFZNTF9EU1BDQUREUiwgKHUzMikgdmluZm8tPnZyYW1fc3RhcnQgKwoJCSAgICB2YXItPnlvZmZzZXQgKiB2aW5mby0+c3RyaWRlICsKCQkgICAgdmFyLT54b2Zmc2V0ICogdmluZm8tPmJ5dGVzX3Blcl9waXhlbCk7CgoJVk1MX1dSSVRFMzIocGFyLCBWTUxfUkNPTVBTVEFULCBWTUxfTURWT19QQURfRU5BQkxFKTsKCgl3aGlsZSAoIShWTUxfUkVBRDMyKHBhciwgVk1MX1JDT01QU1RBVCkgJgoJCSAoVk1MX01EVk9fVkRDX0lfUkNPTVAgfCBWTUxfTURWT19QQURfRU5BQkxFKSkpIDsKCgl2aW5mby0+cGlwZV9kaXNhYmxlZCA9IDA7CiNpZmRlZiBWRVJNSUxJT05fREVCVUcKCXZtbF9kdW1wX3JlZ3ModmluZm8pOwojZW5kaWYKCglyZXR1cm4gMDsKfQoKc3RhdGljIGludCB2bWxmYl9zZXRfcGFyKHN0cnVjdCBmYl9pbmZvICppbmZvKQp7CglzdHJ1Y3Qgdm1sX2luZm8gKnZpbmZvID0gY29udGFpbmVyX29mKGluZm8sIHN0cnVjdCB2bWxfaW5mbywgaW5mbyk7CglpbnQgcmV0OwoKCW11dGV4X2xvY2soJnZtbF9tdXRleCk7CglsaXN0X2RlbCgmdmluZm8tPmhlYWQpOwoJbGlzdF9hZGQoJnZpbmZvLT5oZWFkLCAoc3Vic3lzKSA/ICZnbG9iYWxfaGFzX21vZGUgOiAmZ2xvYmFsX25vX21vZGUpOwoJcmV0ID0gdm1sZmJfc2V0X3Bhcl9sb2NrZWQodmluZm8pOwoKCW11dGV4X3VubG9jaygmdm1sX211dGV4KTsKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBpbnQgdm1sZmJfYmxhbmtfbG9ja2VkKHN0cnVjdCB2bWxfaW5mbyAqdmluZm8pCnsKCXN0cnVjdCB2bWxfcGFyICpwYXIgPSB2aW5mby0+cGFyOwoJdTMyIGN1ciA9IFZNTF9SRUFEMzIocGFyLCBWTUxfUElQRUFDT05GKTsKCglzd2l0Y2ggKHZpbmZvLT5jdXJfYmxhbmtfbW9kZSkgewoJY2FzZSBGQl9CTEFOS19VTkJMQU5LOgoJCWlmICh2aW5mby0+cGlwZV9kaXNhYmxlZCkgewoJCQl2bWxmYl9zZXRfcGFyX2xvY2tlZCh2aW5mbyk7CgkJfQoJCVZNTF9XUklURTMyKHBhciwgVk1MX1BJUEVBQ09ORiwgY3VyICYgflZNTF9QSVBFX0ZPUkNFX0JPUkRFUik7CgkJKHZvaWQpVk1MX1JFQUQzMihwYXIsIFZNTF9QSVBFQUNPTkYpOwoJCWJyZWFrOwoJY2FzZSBGQl9CTEFOS19OT1JNQUw6CgkJaWYgKHZpbmZvLT5waXBlX2Rpc2FibGVkKSB7CgkJCXZtbGZiX3NldF9wYXJfbG9ja2VkKHZpbmZvKTsKCQl9CgkJVk1MX1dSSVRFMzIocGFyLCBWTUxfUElQRUFDT05GLCBjdXIgfCBWTUxfUElQRV9GT1JDRV9CT1JERVIpOwoJCSh2b2lkKVZNTF9SRUFEMzIocGFyLCBWTUxfUElQRUFDT05GKTsKCQlicmVhazsKCWNhc2UgRkJfQkxBTktfVlNZTkNfU1VTUEVORDoKCWNhc2UgRkJfQkxBTktfSFNZTkNfU1VTUEVORDoKCQlpZiAoIXZpbmZvLT5waXBlX2Rpc2FibGVkKSB7CgkJCXZtbGZiX2Rpc2FibGVfcGlwZSh2aW5mbyk7CgkJfQoJCWJyZWFrOwoJY2FzZSBGQl9CTEFOS19QT1dFUkRPV046CgkJaWYgKCF2aW5mby0+cGlwZV9kaXNhYmxlZCkgewoJCQl2bWxmYl9kaXNhYmxlX3BpcGUodmluZm8pOwoJCX0KCQlicmVhazsKCWRlZmF1bHQ6CgkJcmV0dXJuIC1FSU5WQUw7Cgl9CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgdm1sZmJfYmxhbmsoaW50IGJsYW5rX21vZGUsIHN0cnVjdCBmYl9pbmZvICppbmZvKQp7CglzdHJ1Y3Qgdm1sX2luZm8gKnZpbmZvID0gY29udGFpbmVyX29mKGluZm8sIHN0cnVjdCB2bWxfaW5mbywgaW5mbyk7CglpbnQgcmV0OwoKCW11dGV4X2xvY2soJnZtbF9tdXRleCk7Cgl2aW5mby0+Y3VyX2JsYW5rX21vZGUgPSBibGFua19tb2RlOwoJcmV0ID0gdm1sZmJfYmxhbmtfbG9ja2VkKHZpbmZvKTsKCW11dGV4X3VubG9jaygmdm1sX211dGV4KTsKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBpbnQgdm1sZmJfcGFuX2Rpc3BsYXkoc3RydWN0IGZiX3Zhcl9zY3JlZW5pbmZvICp2YXIsCgkJCSAgICAgc3RydWN0IGZiX2luZm8gKmluZm8pCnsKCXN0cnVjdCB2bWxfaW5mbyAqdmluZm8gPSBjb250YWluZXJfb2YoaW5mbywgc3RydWN0IHZtbF9pbmZvLCBpbmZvKTsKCXN0cnVjdCB2bWxfcGFyICpwYXIgPSB2aW5mby0+cGFyOwoKCW11dGV4X2xvY2soJnZtbF9tdXRleCk7CglWTUxfV1JJVEUzMihwYXIsIFZNTF9EU1BDQUREUiwgKHUzMikgdmluZm8tPnZyYW1fc3RhcnQgKwoJCSAgICB2YXItPnlvZmZzZXQgKiB2aW5mby0+c3RyaWRlICsKCQkgICAgdmFyLT54b2Zmc2V0ICogdmluZm8tPmJ5dGVzX3Blcl9waXhlbCk7Cgkodm9pZClWTUxfUkVBRDMyKHBhciwgVk1MX0RTUENBRERSKTsKCW11dGV4X3VubG9jaygmdm1sX211dGV4KTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIGludCB2bWxmYl9zZXRjb2xyZWcodV9pbnQgcmVnbm8sIHVfaW50IHJlZCwgdV9pbnQgZ3JlZW4sIHVfaW50IGJsdWUsCgkJCSAgIHVfaW50IHRyYW5zcCwgc3RydWN0IGZiX2luZm8gKmluZm8pCnsKCXUzMiB2OwoKCWlmIChyZWdubyA+PSAxNikKCQlyZXR1cm4gLUVJTlZBTDsKCglpZiAoaW5mby0+dmFyLmdyYXlzY2FsZSkgewoJCXJlZCA9IGdyZWVuID0gYmx1ZSA9IChyZWQgKiA3NyArIGdyZWVuICogMTUxICsgYmx1ZSAqIDI4KSA+PiA4OwoJfQoKCWlmIChpbmZvLT5maXgudmlzdWFsICE9IEZCX1ZJU1VBTF9UUlVFQ09MT1IpCgkJcmV0dXJuIC1FSU5WQUw7CgoJcmVkID0gVk1MX1RPSFcocmVkLCBpbmZvLT52YXIucmVkLmxlbmd0aCk7CglibHVlID0gVk1MX1RPSFcoYmx1ZSwgaW5mby0+dmFyLmJsdWUubGVuZ3RoKTsKCWdyZWVuID0gVk1MX1RPSFcoZ3JlZW4sIGluZm8tPnZhci5ncmVlbi5sZW5ndGgpOwoJdHJhbnNwID0gVk1MX1RPSFcodHJhbnNwLCBpbmZvLT52YXIudHJhbnNwLmxlbmd0aCk7CgoJdiA9IChyZWQgPDwgaW5mby0+dmFyLnJlZC5vZmZzZXQpIHwKCSAgICAoZ3JlZW4gPDwgaW5mby0+dmFyLmdyZWVuLm9mZnNldCkgfAoJICAgIChibHVlIDw8IGluZm8tPnZhci5ibHVlLm9mZnNldCkgfAoJICAgICh0cmFuc3AgPDwgaW5mby0+dmFyLnRyYW5zcC5vZmZzZXQpOwoKCXN3aXRjaCAoaW5mby0+dmFyLmJpdHNfcGVyX3BpeGVsKSB7CgljYXNlIDE2OgoJCSgodTMyICopIGluZm8tPnBzZXVkb19wYWxldHRlKVtyZWdub10gPSB2OwoJCWJyZWFrOwoJY2FzZSAyNDoKCWNhc2UgMzI6CgkJKCh1MzIgKikgaW5mby0+cHNldWRvX3BhbGV0dGUpW3JlZ25vXSA9IHY7CgkJYnJlYWs7Cgl9CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCB2bWxmYl9tbWFwKHN0cnVjdCBmYl9pbmZvICppbmZvLCBzdHJ1Y3Qgdm1fYXJlYV9zdHJ1Y3QgKnZtYSkKewoJc3RydWN0IHZtbF9pbmZvICp2aW5mbyA9IGNvbnRhaW5lcl9vZihpbmZvLCBzdHJ1Y3Qgdm1sX2luZm8sIGluZm8pOwoJdW5zaWduZWQgbG9uZyBzaXplID0gdm1hLT52bV9lbmQgLSB2bWEtPnZtX3N0YXJ0OwoJdW5zaWduZWQgbG9uZyBvZmZzZXQgPSB2bWEtPnZtX3Bnb2ZmIDw8IFBBR0VfU0hJRlQ7CglpbnQgcmV0OwoKCWlmICh2bWEtPnZtX3Bnb2ZmID4gKH4wVUwgPj4gUEFHRV9TSElGVCkpCgkJcmV0dXJuIC1FSU5WQUw7CglpZiAob2Zmc2V0ICsgc2l6ZSA+IHZpbmZvLT52cmFtX2NvbnRpZ19zaXplKQoJCXJldHVybiAtRUlOVkFMOwoJcmV0ID0gdm1sZmJfdnJhbV9vZmZzZXQodmluZm8sIG9mZnNldCk7CglpZiAocmV0KQoJCXJldHVybiAtRUlOVkFMOwoJb2Zmc2V0ICs9IHZpbmZvLT52cmFtX3N0YXJ0OwoJcGdwcm90X3ZhbCh2bWEtPnZtX3BhZ2VfcHJvdCkgfD0gX1BBR0VfUENEOwoJcGdwcm90X3ZhbCh2bWEtPnZtX3BhZ2VfcHJvdCkgJj0gfl9QQUdFX1BXVDsKCXZtYS0+dm1fZmxhZ3MgfD0gVk1fUkVTRVJWRUQgfCBWTV9JTzsKCWlmIChyZW1hcF9wZm5fcmFuZ2Uodm1hLCB2bWEtPnZtX3N0YXJ0LCBvZmZzZXQgPj4gUEFHRV9TSElGVCwKCQkJCQkJc2l6ZSwgdm1hLT52bV9wYWdlX3Byb3QpKQoJCXJldHVybiAtRUFHQUlOOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgdm1sZmJfc3luYyhzdHJ1Y3QgZmJfaW5mbyAqaW5mbykKewoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgdm1sZmJfY3Vyc29yKHN0cnVjdCBmYl9pbmZvICppbmZvLCBzdHJ1Y3QgZmJfY3Vyc29yICpjdXJzb3IpCnsKCXJldHVybiAtRUlOVkFMOwkvKiBqdXN0IHRvIGZvcmNlIHNvZnRfY3Vyc29yKCkgY2FsbCAqLwp9CgpzdGF0aWMgc3RydWN0IGZiX29wcyB2bWxmYl9vcHMgPSB7Cgkub3duZXIgPSBUSElTX01PRFVMRSwKCS5mYl9vcGVuID0gdm1sZmJfb3BlbiwKCS5mYl9yZWxlYXNlID0gdm1sZmJfcmVsZWFzZSwKCS5mYl9jaGVja192YXIgPSB2bWxmYl9jaGVja192YXIsCgkuZmJfc2V0X3BhciA9IHZtbGZiX3NldF9wYXIsCgkuZmJfYmxhbmsgPSB2bWxmYl9ibGFuaywKCS5mYl9wYW5fZGlzcGxheSA9IHZtbGZiX3Bhbl9kaXNwbGF5LAoJLmZiX2ZpbGxyZWN0ID0gY2ZiX2ZpbGxyZWN0LAoJLmZiX2NvcHlhcmVhID0gY2ZiX2NvcHlhcmVhLAoJLmZiX2ltYWdlYmxpdCA9IGNmYl9pbWFnZWJsaXQsCgkuZmJfY3Vyc29yID0gdm1sZmJfY3Vyc29yLAoJLmZiX3N5bmMgPSB2bWxmYl9zeW5jLAoJLmZiX21tYXAgPSB2bWxmYl9tbWFwLAoJLmZiX3NldGNvbHJlZyA9IHZtbGZiX3NldGNvbHJlZwp9OwoKc3RhdGljIHN0cnVjdCBwY2lfZGV2aWNlX2lkIHZtbF9pZHNbXSA9IHsKCXtQQ0lfREVWSUNFKFBDSV9WRU5ET1JfSURfSU5URUwsIFZNTF9ERVZJQ0VfVkRDKX0sCgl7MH0KfTsKCnN0YXRpYyBzdHJ1Y3QgcGNpX2RyaXZlciB2bWxmYl9wY2lfZHJpdmVyID0gewoJLm5hbWUgPSAidm1sZmIiLAoJLmlkX3RhYmxlID0gdm1sX2lkcywKCS5wcm9iZSA9IHZtbF9wY2lfcHJvYmUsCgkucmVtb3ZlID0gX19kZXZleGl0X3Aodm1sX3BjaV9yZW1vdmUpCn07CgpzdGF0aWMgdm9pZCBfX2V4aXQgdm1sZmJfY2xlYW51cCh2b2lkKQp7CglwY2lfdW5yZWdpc3Rlcl9kcml2ZXIoJnZtbGZiX3BjaV9kcml2ZXIpOwp9CgpzdGF0aWMgaW50IF9faW5pdCB2bWxmYl9pbml0KHZvaWQpCnsKCiNpZm5kZWYgTU9EVUxFCgljaGFyICpvcHRpb24gPSBOVUxMOwoKCWlmIChmYl9nZXRfb3B0aW9ucyhNT0RVTEVfTkFNRSwgJm9wdGlvbikpCgkJcmV0dXJuIC1FTk9ERVY7CiNlbmRpZgoKCXByaW50ayhLRVJOX0RFQlVHIE1PRFVMRV9OQU1FICI6IGluaXRpYWxpemluZ1xuIik7CgltdXRleF9pbml0KCZ2bWxfbXV0ZXgpOwoJSU5JVF9MSVNUX0hFQUQoJmdsb2JhbF9ub19tb2RlKTsKCUlOSVRfTElTVF9IRUFEKCZnbG9iYWxfaGFzX21vZGUpOwoKCXJldHVybiBwY2lfcmVnaXN0ZXJfZHJpdmVyKCZ2bWxmYl9wY2lfZHJpdmVyKTsKfQoKaW50IHZtbGZiX3JlZ2lzdGVyX3N1YnN5cyhzdHJ1Y3Qgdm1sX3N5cyAqc3lzKQp7CglzdHJ1Y3Qgdm1sX2luZm8gKmVudHJ5OwoJc3RydWN0IGxpc3RfaGVhZCAqbGlzdDsKCXUzMiBzYXZlX2FjdGl2YXRlOwoKCW11dGV4X2xvY2soJnZtbF9tdXRleCk7CglpZiAoc3Vic3lzICE9IE5VTEwpIHsKCQlzdWJzeXMtPnJlc3RvcmUoc3Vic3lzKTsKCX0KCXN1YnN5cyA9IHN5czsKCXN1YnN5cy0+c2F2ZShzdWJzeXMpOwoKCS8qCgkgKiBXZSBuZWVkIHRvIHJlc3RhcnQgbGlzdCB0cmF2ZXJzYWwgZm9yIGVhY2ggaXRlbSwgc2luY2Ugd2UKCSAqIHJlbGVhc2UgdGhlIGxpc3QgbXV0ZXggaW4gdGhlIGxvb3AuCgkgKi8KCglsaXN0ID0gZ2xvYmFsX25vX21vZGUubmV4dDsKCXdoaWxlIChsaXN0ICE9ICZnbG9iYWxfbm9fbW9kZSkgewoJCWxpc3RfZGVsX2luaXQobGlzdCk7CgkJZW50cnkgPSBsaXN0X2VudHJ5KGxpc3QsIHN0cnVjdCB2bWxfaW5mbywgaGVhZCk7CgoJCS8qCgkJICogRmlyc3QsIHRyeSB0aGUgY3VycmVudCBtb2RlIHdoaWNoIG1pZ2h0IG5vdCBiZQoJCSAqIGNvbXBsZXRlbHkgdmFsaWRhdGVkIHdpdGggcmVzcGVjdCB0byB0aGUgcGl4ZWwgY2xvY2suCgkJICovCgoJCWlmICghdm1sZmJfY2hlY2tfdmFyX2xvY2tlZCgmZW50cnktPmluZm8udmFyLCBlbnRyeSkpIHsKCQkJdm1sZmJfc2V0X3Bhcl9sb2NrZWQoZW50cnkpOwoJCQlsaXN0X2FkZF90YWlsKGxpc3QsICZnbG9iYWxfaGFzX21vZGUpOwoJCX0gZWxzZSB7CgoJCQkvKgoJCQkgKiBEaWRuJ3Qgd29yay4gVHJ5IHRvIGZpbmQgYW5vdGhlciBtb2RlLAoJCQkgKiB0aGF0IG1hdGNoZXMgdGhpcyBzdWJzeXMuCgkJCSAqLwoKCQkJbXV0ZXhfdW5sb2NrKCZ2bWxfbXV0ZXgpOwoJCQlzYXZlX2FjdGl2YXRlID0gZW50cnktPmluZm8udmFyLmFjdGl2YXRlOwoJCQllbnRyeS0+aW5mby52YXIuYml0c19wZXJfcGl4ZWwgPSAxNjsKCQkJdm1sZmJfc2V0X3ByZWZfcGl4ZWxfZm9ybWF0KCZlbnRyeS0+aW5mby52YXIpOwoJCQlpZiAoZmJfZmluZF9tb2RlKCZlbnRyeS0+aW5mby52YXIsCgkJCQkJICZlbnRyeS0+aW5mbywKCQkJCQkgdm1sX2RlZmF1bHRfbW9kZSwgTlVMTCwgMCwgTlVMTCwgMTYpKSB7CgkJCQllbnRyeS0+aW5mby52YXIuYWN0aXZhdGUgfD0KCQkJCSAgICBGQl9BQ1RJVkFURV9GT1JDRSB8IEZCX0FDVElWQVRFX05PVzsKCQkJCWZiX3NldF92YXIoJmVudHJ5LT5pbmZvLCAmZW50cnktPmluZm8udmFyKTsKCQkJfSBlbHNlIHsKCQkJCXByaW50ayhLRVJOX0VSUiBNT0RVTEVfTkFNRQoJCQkJICAgICAgICI6IFNvcnJ5LiBubyBtb2RlIGZvdW5kIGZvciB0aGlzIHN1YnN5cy5cbiIpOwoJCQl9CgkJCWVudHJ5LT5pbmZvLnZhci5hY3RpdmF0ZSA9IHNhdmVfYWN0aXZhdGU7CgkJCW11dGV4X2xvY2soJnZtbF9tdXRleCk7CgkJfQoJCXZtbGZiX2JsYW5rX2xvY2tlZChlbnRyeSk7CgkJbGlzdCA9IGdsb2JhbF9ub19tb2RlLm5leHQ7Cgl9CgltdXRleF91bmxvY2soJnZtbF9tdXRleCk7CgoJcHJpbnRrKEtFUk5fREVCVUcgTU9EVUxFX05BTUUgIjogUmVnaXN0ZXJlZCAlcyBzdWJzeXN0ZW0uXG4iLAoJCQkJc3Vic3lzLT5uYW1lID8gc3Vic3lzLT5uYW1lIDogInVua25vd24iKTsKCXJldHVybiAwOwp9CgpFWFBPUlRfU1lNQk9MX0dQTCh2bWxmYl9yZWdpc3Rlcl9zdWJzeXMpOwoKdm9pZCB2bWxmYl91bnJlZ2lzdGVyX3N1YnN5cyhzdHJ1Y3Qgdm1sX3N5cyAqc3lzKQp7CglzdHJ1Y3Qgdm1sX2luZm8gKmVudHJ5LCAqbmV4dDsKCgltdXRleF9sb2NrKCZ2bWxfbXV0ZXgpOwoJaWYgKHN1YnN5cyAhPSBzeXMpIHsKCQltdXRleF91bmxvY2soJnZtbF9tdXRleCk7CgkJcmV0dXJuOwoJfQoJc3Vic3lzLT5yZXN0b3JlKHN1YnN5cyk7CglzdWJzeXMgPSBOVUxMOwoJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGVudHJ5LCBuZXh0LCAmZ2xvYmFsX2hhc19tb2RlLCBoZWFkKSB7CgkJcHJpbnRrKEtFUk5fREVCVUcgTU9EVUxFX05BTUUgIjogc3Vic3lzIGRpc2FibGUgcGlwZVxuIik7CgkJdm1sZmJfZGlzYWJsZV9waXBlKGVudHJ5KTsKCQlsaXN0X2RlbCgmZW50cnktPmhlYWQpOwoJCWxpc3RfYWRkX3RhaWwoJmVudHJ5LT5oZWFkLCAmZ2xvYmFsX25vX21vZGUpOwoJfQoJbXV0ZXhfdW5sb2NrKCZ2bWxfbXV0ZXgpOwp9CgpFWFBPUlRfU1lNQk9MX0dQTCh2bWxmYl91bnJlZ2lzdGVyX3N1YnN5cyk7Cgptb2R1bGVfaW5pdCh2bWxmYl9pbml0KTsKbW9kdWxlX2V4aXQodm1sZmJfY2xlYW51cCk7CgpNT0RVTEVfQVVUSE9SKCJUdW5nc3RlbiBHcmFwaGljcyIpOwpNT0RVTEVfREVTQ1JJUFRJT04oIkluaXRpYWxpemF0aW9uIG9mIHRoZSBWZXJtaWxpb24gZGlzcGxheSBkZXZpY2VzIik7Ck1PRFVMRV9WRVJTSU9OKCIxLjAuMCIpOwpNT0RVTEVfTElDRU5TRSgiR1BMIik7Cg==