LyogMTk5OS0wMi0yMiBBcmthZGl1c3ogTWm2a2lld2ljeiA8bWlzaWVrQHBsZC5PUkcuUEw+CiAqIC0gYWRkZWQgTmF0aXZlIExhbmd1YWdlIFN1cHBvcnQKICogU3VuIE1hciAyMSAxOTk5IC0gQXJuYWxkbyBDYXJ2YWxobyBkZSBNZWxvIDxhY21lQGNvbmVjdGl2YS5jb20uYnI+CiAqIC0gZml4ZWQgc3RyZXJyKGVycm5vKSBpbiBnZXR0ZXh0IGNhbGxzCiAqCiAqIDIwMDYtMDYtMDggQW1pdCBHdWQgPGFndWRAcmVkaGF0LmNvbT4KICogLSBNb3ZlZCBjb2RlIHRvIG5mcy11dGlscy9zdXBwb3J0L25mcyBmcm9tIHV0aWwtbGludXgvbW91bnQuCiAqLwoKI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSA8bW50ZW50Lmg+CgojaW5jbHVkZSAiZnN0YWIuaCIKI2luY2x1ZGUgInhjb21tb24uaCIKI2luY2x1ZGUgIm5mc19tbnRlbnQuaCIKI2luY2x1ZGUgIm5mc19wYXRocy5oIgojaW5jbHVkZSAibmxzLmgiCgojZGVmaW5lIExPQ0tfVElNRU9VVAkxMAojZGVmaW5lIHN0cmVxKHMsIHQpCShzdHJjbXAgKChzKSwgKHQpKSA9PSAwKQojZGVmaW5lIFBST0NfTU9VTlRTCQkiL3Byb2MvbW91bnRzIgoKZXh0ZXJuIGludCB2ZXJib3NlOwoKLyogSW5mb3JtYXRpb24gYWJvdXQgbXRhYi4gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kc3RhdGljIGludCBoYXZlX210YWJfaW5mbyA9IDA7CnN0YXRpYyBpbnQgdmFyX210YWJfZG9lc19ub3RfZXhpc3QgPSAwOwpzdGF0aWMgaW50IHZhcl9tdGFiX2lzX2Ffc3ltbGluayA9IDA7CgpzdGF0aWMgdm9pZApnZXRfbXRhYl9pbmZvKHZvaWQpIHsKCXN0cnVjdCBzdGF0IG10YWJfc3RhdDsKCglpZiAoIWhhdmVfbXRhYl9pbmZvKSB7CgkJaWYgKGxzdGF0KE1PVU5URUQsICZtdGFiX3N0YXQpKQoJCQl2YXJfbXRhYl9kb2VzX25vdF9leGlzdCA9IDE7CgkJZWxzZSBpZiAoU19JU0xOSyhtdGFiX3N0YXQuc3RfbW9kZSkpCgkJCXZhcl9tdGFiX2lzX2Ffc3ltbGluayA9IDE7CgkJaGF2ZV9tdGFiX2luZm8gPSAxOwoJfQp9CgppbnQKbXRhYl9kb2VzX25vdF9leGlzdCh2b2lkKSB7CglnZXRfbXRhYl9pbmZvKCk7CglyZXR1cm4gdmFyX210YWJfZG9lc19ub3RfZXhpc3Q7Cn0KCnN0YXRpYyBpbnQKbXRhYl9pc19hX3N5bWxpbmsodm9pZCkgewogICAgICAgIGdldF9tdGFiX2luZm8oKTsKICAgICAgICByZXR1cm4gdmFyX210YWJfaXNfYV9zeW1saW5rOwp9CgppbnQKbXRhYl9pc193cml0YWJsZSgpIHsKCWludCBmZDsKCgkvKiBTaG91bGQgd2Ugd3JpdGUgdG8gL2V0Yy9tdGFiIHVwb24gYW4gdXBkYXRlPwoJICAgUHJvYmFibHkgbm90IGlmIGl0IGlzIGEgc3ltbGluayB0byAvcHJvYy9tb3VudHMsIHNpbmNlIHRoYXQKCSAgIHdvdWxkIGNyZWF0ZSBhIGZpbGUgL3Byb2MvbW91bnRzIGluIGNhc2UgdGhlIHByb2MgZmlsZXN5c3RlbQoJICAgaXMgbm90IG1vdW50ZWQuICovCglpZiAobXRhYl9pc19hX3N5bWxpbmsoKSkKCQlyZXR1cm4gMDsKCglmZCA9IG9wZW4oTU9VTlRFRCwgT19SRFdSIHwgT19DUkVBVCwgMDY0NCk7CglpZiAoZmQgPj0gMCkgewoJCWNsb3NlKGZkKTsKCQlyZXR1cm4gMTsKCX0gZWxzZQoJCXJldHVybiAwOwp9CgovKiBDb250ZW50cyBvZiBtdGFiIGFuZCBmc3RhYiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKc3RydWN0IG1udGVudGNobiBtb3VudHRhYmxlOwpzdGF0aWMgaW50IGdvdF9tdGFiID0gMDsKc3RydWN0IG1udGVudGNobiBmc3RhYjsKc3RhdGljIGludCBnb3RfZnN0YWIgPSAwOwoKc3RhdGljIHZvaWQgcmVhZF9tb3VudHRhYmxlKHZvaWQpOwpzdGF0aWMgdm9pZCByZWFkX2ZzdGFiKHZvaWQpOwoKc3RhdGljIHN0cnVjdCBtbnRlbnRjaG4gKgptdGFiX2hlYWQodm9pZCkgewoJaWYgKCFnb3RfbXRhYikKCQlyZWFkX21vdW50dGFibGUoKTsKCXJldHVybiAmbW91bnR0YWJsZTsKfQoKc3RhdGljIHN0cnVjdCBtbnRlbnRjaG4gKgpmc3RhYl9oZWFkKHZvaWQpCnsKCWlmICghZ290X2ZzdGFiKQoJCXJlYWRfZnN0YWIoKTsKCXJldHVybiAmZnN0YWI7Cn0KCiNpZiAwCnN0YXRpYyB2b2lkCm15X2ZyZWUoY29uc3Qgdm9pZCAqcykgewoJaWYgKHMpCgkJZnJlZSgodm9pZCAqKSBzKTsKfQoKc3RhdGljIHZvaWQKZGlzY2FyZF9tbnRlbnRjaG4oc3RydWN0IG1udGVudGNobiAqbWMwKSB7CglzdHJ1Y3QgbW50ZW50Y2huICptYywgKm1jMTsKCglmb3IgKG1jID0gbWMwLT5ueHQ7IG1jICYmIG1jICE9IG1jMDsgbWMgPSBtYzEpIHsKCQltYzEgPSBtYy0+bnh0OwoJCW15X2ZyZWUobWMtPm0ubW50X2ZzbmFtZSk7CgkJbXlfZnJlZShtYy0+bS5tbnRfZGlyKTsKCQlteV9mcmVlKG1jLT5tLm1udF90eXBlKTsKCQlteV9mcmVlKG1jLT5tLm1udF9vcHRzKTsKCQlmcmVlKG1jKTsKCX0KfQojZW5kaWYKCnN0YXRpYyB2b2lkCnJlYWRfbW50ZW50Y2huKG1udEZJTEUgKm1mcCwgY29uc3QgY2hhciAqZm5hbSwgc3RydWN0IG1udGVudGNobiAqbWMwKSB7CglzdHJ1Y3QgbW50ZW50Y2huICptYyA9IG1jMDsKCXN0cnVjdCBtbnRlbnQgKm1udDsKCgl3aGlsZSAoKG1udCA9IG5mc19nZXRtbnRlbnQobWZwKSkgIT0gTlVMTCkgewoJCWlmICghc3RyZXEobW50LT5tbnRfdHlwZSwgTU5UVFlQRV9JR05PUkUpKSB7CgkJCW1jLT5ueHQgPSAoc3RydWN0IG1udGVudGNobiAqKSB4bWFsbG9jKHNpemVvZigqbWMpKTsKCQkJbWMtPm54dC0+cHJldiA9IG1jOwoJCQltYyA9IG1jLT5ueHQ7CgkJCW1jLT5tID0gKm1udDsKCQkJbWMtPm54dCA9IG1jMDsKCQl9Cgl9CgltYzAtPnByZXYgPSBtYzsKCWlmIChmZXJyb3IobWZwLT5tbnRlbnRfZnApKSB7CgkJaW50IGVycnN2ID0gZXJybm87CgkJbmZzX2Vycm9yKF8oIndhcm5pbmc6IGVycm9yIHJlYWRpbmcgJXM6ICVzIiksCgkJICAgICAgZm5hbSwgc3RyZXJyb3IgKGVycnN2KSk7CgkJbWMwLT5ueHQgPSBtYzAtPnByZXYgPSBOVUxMOwoJfQoJbmZzX2VuZG1udGVudChtZnApOwp9CgovKgogKiBSZWFkIC9ldGMvbXRhYi4gIElmIHRoYXQgZmFpbHMsIHRyeSAvcHJvYy9tb3VudHMuCiAqIFRoaXMgcHJvZHVjZXMgYSBsaW5rZWQgbGlzdC4gVGhlIGxpc3QgaGVhZCBtb3VudHRhYmxlIGlzIGEgZHVtbXkuCiAqIFJldHVybiAwIG9uIHN1Y2Nlc3MuCiAqLwpzdGF0aWMgdm9pZApyZWFkX21vdW50dGFibGUoKSB7CiAgICAgICAgbW50RklMRSAqbWZwOwogICAgICAgIGNvbnN0IGNoYXIgKmZuYW07CiAgICAgICAgc3RydWN0IG1udGVudGNobiAqbWMgPSAmbW91bnR0YWJsZTsKCiAgICAgICAgZ290X210YWIgPSAxOwogICAgICAgIG1jLT5ueHQgPSBtYy0+cHJldiA9IE5VTEw7CgogICAgICAgIGZuYW0gPSBNT1VOVEVEOwogICAgICAgIG1mcCA9IG5mc19zZXRtbnRlbnQgKGZuYW0sICJyIik7CiAgICAgICAgaWYgKG1mcCA9PSBOVUxMIHx8IG1mcC0+bW50ZW50X2ZwID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIGludCBlcnJzdiA9IGVycm5vOwogICAgICAgICAgICAgICAgZm5hbSA9IFBST0NfTU9VTlRTOwogICAgICAgICAgICAgICAgbWZwID0gbmZzX3NldG1udGVudCAoZm5hbSwgInIiKTsKICAgICAgICAgICAgICAgIGlmIChtZnAgPT0gTlVMTCB8fCBtZnAtPm1udGVudF9mcCA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5mc19lcnJvcihfKCJ3YXJuaW5nOiBjYW4ndCBvcGVuICVzOiAlcyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNT1VOVEVELCBzdHJlcnJvciAoZXJyc3YpKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHZlcmJvc2UpCiAgICAgICAgICAgICAgICAgICAgICAgIHByaW50ZiAoXygibW91bnQ6IGNvdWxkIG5vdCBvcGVuICVzIC0gIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInVzaW5nICVzIGluc3RlYWRcbiIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1PVU5URUQsIFBST0NfTU9VTlRTKTsKICAgICAgICB9CiAgICAgICAgcmVhZF9tbnRlbnRjaG4obWZwLCBmbmFtLCBtYyk7Cn0KCnN0YXRpYyB2b2lkCnJlYWRfZnN0YWIoKQp7CgltbnRGSUxFICptZnAgPSBOVUxMOwoJY29uc3QgY2hhciAqZm5hbTsKCXN0cnVjdCBtbnRlbnRjaG4gKm1jID0gJmZzdGFiOwoKCWdvdF9mc3RhYiA9IDE7CgltYy0+bnh0ID0gbWMtPnByZXYgPSBOVUxMOwoKCWZuYW0gPSBfUEFUSF9GU1RBQjsKCW1mcCA9IG5mc19zZXRtbnRlbnQgKGZuYW0sICJyIik7CglpZiAobWZwID09IE5VTEwgfHwgbWZwLT5tbnRlbnRfZnAgPT0gTlVMTCkgewoJCWludCBlcnJzdiA9IGVycm5vOwoJCW5mc19lcnJvcihfKCJ3YXJuaW5nOiBjYW4ndCBvcGVuICVzOiAlcyIpLAoJCQkgIF9QQVRIX0ZTVEFCLCBzdHJlcnJvciAoZXJyc3YpKTsKCQlyZXR1cm47Cgl9CglyZWFkX21udGVudGNobihtZnAsIGZuYW0sIG1jKTsKfQoKLyoKICogR2l2ZW4gdGhlIGRpcmVjdG9yeSBuYW1lIE5BTUUsIGFuZCB0aGUgcGxhY2UgTUNQUkVWIHdlIGZvdW5kIGl0IGxhc3QgdGltZSwKICogdHJ5IHRvIGZpbmQgbW9yZSBvY2N1cnJlbmNlcy4KICovIApzdHJ1Y3QgbW50ZW50Y2huICoKZ2V0bW50ZGlyYmFja3dhcmQgKGNvbnN0IGNoYXIgKm5hbWUsIHN0cnVjdCBtbnRlbnRjaG4gKm1jcHJldikgewoJc3RydWN0IG1udGVudGNobiAqbWMsICptYzA7CgoJbWMwID0gbXRhYl9oZWFkKCk7CglpZiAoIW1jcHJldikKCQltY3ByZXYgPSBtYzA7Cglmb3IgKG1jID0gbWNwcmV2LT5wcmV2OyBtYyAmJiBtYyAhPSBtYzA7IG1jID0gbWMtPnByZXYpCgkJaWYgKHN0cmVxKG1jLT5tLm1udF9kaXIsIG5hbWUpKQoJCQlyZXR1cm4gbWM7CglyZXR1cm4gTlVMTDsKfQoKLyoKICogR2l2ZW4gdGhlIGRldmljZSBuYW1lIE5BTUUsIGFuZCB0aGUgcGxhY2UgTUNQUkVWIHdlIGZvdW5kIGl0IGxhc3QgdGltZSwKICogdHJ5IHRvIGZpbmQgbW9yZSBvY2N1cnJlbmNlcy4KICovIApzdHJ1Y3QgbW50ZW50Y2huICoKZ2V0bW50ZGV2YmFja3dhcmQgKGNvbnN0IGNoYXIgKm5hbWUsIHN0cnVjdCBtbnRlbnRjaG4gKm1jcHJldikgewoJc3RydWN0IG1udGVudGNobiAqbWMsICptYzA7CgoJbWMwID0gbXRhYl9oZWFkKCk7CglpZiAoIW1jcHJldikKCQltY3ByZXYgPSBtYzA7Cglmb3IgKG1jID0gbWNwcmV2LT5wcmV2OyBtYyAmJiBtYyAhPSBtYzA7IG1jID0gbWMtPnByZXYpCgkJaWYgKHN0cmVxKG1jLT5tLm1udF9mc25hbWUsIG5hbWUpKQoJCQlyZXR1cm4gbWM7CglyZXR1cm4gTlVMTDsKfQoKLyogRmluZCB0aGUgZGlyIEZJTEUgaW4gZnN0YWIuICAqLwpzdHJ1Y3QgbW50ZW50Y2huICoKZ2V0ZnNmaWxlIChjb25zdCBjaGFyICpmaWxlKQp7CglzdHJ1Y3QgbW50ZW50Y2huICptYywgKm1jMDsKCgltYzAgPSBmc3RhYl9oZWFkKCk7Cglmb3IgKG1jID0gbWMwLT5ueHQ7IG1jICYmIG1jICE9IG1jMDsgbWMgPSBtYy0+bnh0KQoJCWlmIChzdHJlcShtYy0+bS5tbnRfZGlyLCBmaWxlKSkKCQkJcmV0dXJuIG1jOwoJcmV0dXJuIE5VTEw7Cn0KCi8qIEZpbmQgdGhlIGRldmljZSBTUEVDIGluIGZzdGFiLiAgKi8Kc3RydWN0IG1udGVudGNobiAqCmdldGZzc3BlYyAoY29uc3QgY2hhciAqc3BlYykKewoJc3RydWN0IG1udGVudGNobiAqbWMsICptYzA7CgoJbWMwID0gZnN0YWJfaGVhZCgpOwoJZm9yIChtYyA9IG1jMC0+bnh0OyBtYyAmJiBtYyAhPSBtYzA7IG1jID0gbWMtPm54dCkKCQlpZiAoc3RyZXEobWMtPm0ubW50X2ZzbmFtZSwgc3BlYykpCgkJCXJldHVybiBtYzsKCXJldHVybiBOVUxMOwp9CgovKiBVcGRhdGluZyBtdGFiIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKLyogRmxhZyBmb3IgYWxyZWFkeSBleGlzdGluZyBsb2NrIGZpbGUuICovCnN0YXRpYyBpbnQgd2VfY3JlYXRlZF9sb2NrZmlsZSA9IDA7CnN0YXRpYyBpbnQgbG9ja2ZpbGVfZmQgPSAtMTsKCi8qIEZsYWcgdG8gaW5kaWNhdGUgdGhhdCBzaWduYWxzIGhhdmUgYmVlbiBzZXQgdXAuICovCnN0YXRpYyBpbnQgc2lnbmFsc19oYXZlX2JlZW5fc2V0dXAgPSAwOwoKLyogRW5zdXJlIHRoYXQgdGhlIGxvY2sgaXMgcmVsZWFzZWQgaWYgd2UgYXJlIGludGVycnVwdGVkLiAgKi8KZXh0ZXJuIGNoYXIgKnN0cnNpZ25hbChpbnQgc2lnKTsJLyogbm90IGFsd2F5cyBpbiA8c3RyaW5nLmg+ICovCgpzdGF0aWMgdm9pZApoYW5kbGVyIChpbnQgc2lnKSB7CiAgICAgZGllKEVYX1VTRVIsICIlcyIsIHN0cnNpZ25hbChzaWcpKTsKfQoKc3RhdGljIHZvaWQKc2V0bGt3X3RpbWVvdXQgKGludCBzaWcpIHsKICAgICAvKiBub3RoaW5nLCBmY250bCB3aWxsIGZhaWwgYW55d2F5ICovCn0KCi8qIFJlbW92ZSBsb2NrIGZpbGUuICAqLwp2b2lkCnVubG9ja19tdGFiICh2b2lkKSB7CglpZiAod2VfY3JlYXRlZF9sb2NrZmlsZSkgewoJCWNsb3NlKGxvY2tmaWxlX2ZkKTsKCQlsb2NrZmlsZV9mZCA9IC0xOwoJCXVubGluayAoTU9VTlRFRF9MT0NLKTsKCQl3ZV9jcmVhdGVkX2xvY2tmaWxlID0gMDsKCX0KfQoKLyogQ3JlYXRlIHRoZSBsb2NrIGZpbGUuCiAgIFRoZSBsb2NrIGZpbGUgd2lsbCBiZSByZW1vdmVkIGlmIHdlIGNhdGNoIGEgc2lnbmFsIG9yIHdoZW4gd2UgZXhpdC4gKi8KLyogVGhlIG9sZCBjb2RlIGhlcmUgdXNlZCBmbG9jayBvbiBhIGxvY2sgZmlsZSAvZXRjL210YWJ+IGFuZCBkZWxldGVkCiAgIHRoaXMgbG9jayBmaWxlIGFmdGVyd2FyZHMuIEhvd2V2ZXIsIGFzIHJnb29jaCByZW1hcmtzLCB0aGF0IGhhcyBhCiAgIHJhY2U6IGEgc2Vjb25kIG1vdW50IG1heSBiZSB3YWl0aW5nIG9uIHRoZSBsb2NrIGFuZCBwcm9jZWVkIGFzCiAgIHNvb24gYXMgdGhlIGxvY2sgZmlsZSBpcyBkZWxldGVkIGJ5IHRoZSBmaXJzdCBtb3VudCwgYW5kIGltbWVkaWF0ZWx5CiAgIGFmdGVyd2FyZHMgYSB0aGlyZCBtb3VudCBjb21lcywgY3JlYXRlcyBhIG5ldyAvZXRjL210YWJ+LCBhcHBsaWVzCiAgIGZsb2NrIHRvIHRoYXQsIGFuZCBhbHNvIHByb2NlZWRzLCBzbyB0aGF0IHRoZSBzZWNvbmQgYW5kIHRoaXJkIG1vdW50CiAgIG5vdyBib3RoIGFyZSBzY3JpYmJsaW5nIGluIC9ldGMvbXRhYi4KICAgVGhlIG5ldyBjb2RlIHVzZXMgYSBsaW5rKCkgaW5zdGVhZCBvZiBhIGNyZWF0KCksIHdoZXJlIHdlIHByb2NlZWQKICAgb25seSBpZiBpdCB3YXMgdXMgdGhhdCBjcmVhdGVkIHRoZSBsb2NrLCBhbmQgaGVuY2Ugd2UgYWx3YXlzIGhhdmUKICAgdG8gZGVsZXRlIHRoZSBsb2NrIGFmdGVyd2FyZHMuIE5vdyB0aGUgdXNlIG9mIGZsb2NrKCkgaXMgaW4gcHJpbmNpcGxlCiAgIHN1cGVyZmx1b3VzLCBidXQgYXZvaWRzIGFuIGFyYml0cmFyeSBzbGVlcCgpLiAqLwoKLyogV2hlcmUgZG9lcyB0aGUgbGluayBwb2ludCB0bz8gT2J2aW91cyBjaG9pY2VzIGFyZSBtdGFiIGFuZCBtdGFifn4uCiAgIEhKTHUgcG9pbnRzIG91dCB0aGF0IHRoZSBsYXR0ZXIgbGVhZHMgdG8gcmFjZXMuIFJpZ2h0IG5vdyB3ZSB1c2UKICAgbXRhYn4uPHBpZD4gaW5zdGVhZC4gVXNlIDIwIGFzIHVwcGVyIGJvdW5kIGZvciB0aGUgbGVuZ3RoIG9mICVkLiAqLwojZGVmaW5lIE1PVU5UTE9DS19MSU5LVEFSR0VUCQlNT1VOVEVEX0xPQ0sgIiVkIgojZGVmaW5lIE1PVU5UTE9DS19MSU5LVEFSR0VUX0xUSAkoc2l6ZW9mKE1PVU5URURfTE9DSykrMjApCgp2b2lkCmxvY2tfbXRhYiAodm9pZCkgewoJaW50IHRyaWVzID0gMTAwMDAwLCBpOwoJY2hhciBsaW5rdGFyZ2V0ZmlsZVtNT1VOVExPQ0tfTElOS1RBUkdFVF9MVEhdOwoKCWF0X2RpZSA9IHVubG9ja19tdGFiOwoKCWlmICghc2lnbmFsc19oYXZlX2JlZW5fc2V0dXApIHsKCQlpbnQgc2lnID0gMDsKCQlzdHJ1Y3Qgc2lnYWN0aW9uIHNhOwoKCQlzYS5zYV9oYW5kbGVyID0gaGFuZGxlcjsKCQlzYS5zYV9mbGFncyA9IDA7CgkJc2lnZmlsbHNldCAoJnNhLnNhX21hc2spOwogIAoJCXdoaWxlIChzaWdpc21lbWJlciAoJnNhLnNhX21hc2ssICsrc2lnKSAhPSAtMQoJCSAgICAgICAmJiBzaWcgIT0gU0lHQ0hMRCkgewoJCQlpZiAoc2lnID09IFNJR0FMUk0pCgkJCQlzYS5zYV9oYW5kbGVyID0gc2V0bGt3X3RpbWVvdXQ7CgkJCWVsc2UKCQkJCXNhLnNhX2hhbmRsZXIgPSBoYW5kbGVyOwoJCQlzaWdhY3Rpb24gKHNpZywgJnNhLCAoc3RydWN0IHNpZ2FjdGlvbiAqKSAwKTsKCQl9CgkJc2lnbmFsc19oYXZlX2JlZW5fc2V0dXAgPSAxOwoJfQoKCXNwcmludGYobGlua3RhcmdldGZpbGUsIE1PVU5UTE9DS19MSU5LVEFSR0VULCBnZXRwaWQgKCkpOwoKCWkgPSBvcGVuIChsaW5rdGFyZ2V0ZmlsZSwgT19XUk9OTFl8T19DUkVBVCwgMCk7CglpZiAoaSA8IDApIHsKCQlpbnQgZXJyc3YgPSBlcnJubzsKCQkvKiBsaW5rdGFyZ2V0ZmlsZSBkb2VzIG5vdCBleGlzdCAoYXMgYSBmaWxlKQoJCSAgIGFuZCB3ZSBjYW5ub3QgY3JlYXRlIGl0LiBSZWFkLW9ubHkgZmlsZXN5c3RlbT8KCQkgICBUb28gbWFueSBmaWxlcyBvcGVuIGluIHRoZSBzeXN0ZW0/CgkJICAgRmlsZXN5c3RlbSBmdWxsPyAqLwoJCWRpZSAoRVhfRklMRUlPLCBfKCJjYW4ndCBjcmVhdGUgbG9jayBmaWxlICVzOiAlcyAiCgkJCQkJCSAgIih1c2UgLW4gZmxhZyB0byBvdmVycmlkZSkiKSwKCQkJIGxpbmt0YXJnZXRmaWxlLCBzdHJlcnJvciAoZXJyc3YpKTsKCX0KCWNsb3NlKGkpOwoJCgkvKiBSZXBlYXQgdW50aWwgaXQgd2FzIHVzIHdobyBtYWRlIHRoZSBsaW5rICovCgl3aGlsZSAoIXdlX2NyZWF0ZWRfbG9ja2ZpbGUpIHsKCQlzdHJ1Y3QgZmxvY2sgZmxvY2s7CgkJaW50IGVycnN2LCBqOwoKCQlqID0gbGluayhsaW5rdGFyZ2V0ZmlsZSwgTU9VTlRFRF9MT0NLKTsKCQllcnJzdiA9IGVycm5vOwoKCQlpZiAoaiA9PSAwKQoJCQl3ZV9jcmVhdGVkX2xvY2tmaWxlID0gMTsKCgkJaWYgKGogPCAwICYmIGVycnN2ICE9IEVFWElTVCkgewoJCQkodm9pZCkgdW5saW5rKGxpbmt0YXJnZXRmaWxlKTsKCQkJZGllIChFWF9GSUxFSU8sIF8oImNhbid0IGxpbmsgbG9jayBmaWxlICVzOiAlcyAiCgkJCSAgICAgIih1c2UgLW4gZmxhZyB0byBvdmVycmlkZSkiKSwKCQkJICAgICBNT1VOVEVEX0xPQ0ssIHN0cmVycm9yIChlcnJzdikpOwoJCX0KCgkJbG9ja2ZpbGVfZmQgPSBvcGVuIChNT1VOVEVEX0xPQ0ssIE9fV1JPTkxZKTsKCgkJaWYgKGxvY2tmaWxlX2ZkIDwgMCkgewoJCQlpbnQgZXJyc3YgPSBlcnJubzsKCQkJLyogU3RyYW5nZS4uLiBNYXliZSB0aGUgZmlsZSB3YXMganVzdCBkZWxldGVkPyAqLwoJCQlpZiAoZXJybm8gPT0gRU5PRU5UICYmIHRyaWVzLS0gPiAwKSB7CgkJCQlpZiAodHJpZXMgJSAyMDAgPT0gMCkKCQkJCQl1c2xlZXAoMzApOwoJCQkJY29udGludWU7CgkJCX0KCQkJKHZvaWQpIHVubGluayhsaW5rdGFyZ2V0ZmlsZSk7CgkJCWRpZSAoRVhfRklMRUlPLCBfKCJjYW4ndCBvcGVuIGxvY2sgZmlsZSAlczogJXMgIgoJCQkgICAgICIodXNlIC1uIGZsYWcgdG8gb3ZlcnJpZGUpIiksCgkJCSAgICAgTU9VTlRFRF9MT0NLLCBzdHJlcnJvciAoZXJyc3YpKTsKCQl9CgoJCWZsb2NrLmxfdHlwZSA9IEZfV1JMQ0s7CgkJZmxvY2subF93aGVuY2UgPSBTRUVLX1NFVDsKCQlmbG9jay5sX3N0YXJ0ID0gMDsKCQlmbG9jay5sX2xlbiA9IDA7CgoJCWlmIChqID09IDApIHsKCQkJLyogV2UgbWFkZSB0aGUgbGluay4gTm93IGNsYWltIHRoZSBsb2NrLiAqLwoJCQlpZiAoZmNudGwgKGxvY2tmaWxlX2ZkLCBGX1NFVExLLCAmZmxvY2spID09IC0xKSB7CgkJCQlpZiAodmVyYm9zZSkgewoJCQkJICAgIGludCBlcnJzdiA9IGVycm5vOwoJCQkJICAgIHByaW50ZihfKCJDYW4ndCBsb2NrIGxvY2sgZmlsZSAlczogJXNcbiIpLAoJCQkJCSAgIE1PVU5URURfTE9DSywgc3RyZXJyb3IgKGVycnN2KSk7CgkJCQl9CgkJCQkvKiBwcm9jZWVkIGFueXdheSAqLwoJCQl9CgkJCSh2b2lkKSB1bmxpbmsobGlua3RhcmdldGZpbGUpOwoJCX0gZWxzZSB7CgkJCXN0YXRpYyBpbnQgdHJpZXMgPSAwOwoKCQkJLyogU29tZW9uZSBlbHNlIG1hZGUgdGhlIGxpbmsuIFdhaXQuICovCgkJCWFsYXJtKExPQ0tfVElNRU9VVCk7CgkJCWlmIChmY250bCAobG9ja2ZpbGVfZmQsIEZfU0VUTEtXLCAmZmxvY2spID09IC0xKSB7CgkJCQlpbnQgZXJyc3YgPSBlcnJubzsKCQkJCSh2b2lkKSB1bmxpbmsobGlua3RhcmdldGZpbGUpOwoJCQkJZGllIChFWF9GSUxFSU8sIF8oImNhbid0IGxvY2sgbG9jayBmaWxlICVzOiAlcyIpLAoJCQkJICAgICBNT1VOVEVEX0xPQ0ssIChlcnJubyA9PSBFSU5UUikgPwoJCQkJICAgICBfKCJ0aW1lZCBvdXQiKSA6IHN0cmVycm9yIChlcnJzdikpOwoJCQl9CgkJCWFsYXJtKDApOwoJCQkvKiBMaW1pdCB0aGUgbnVtYmVyIG9mIGl0ZXJhdGlvbnMgLSBtYXliZSB0aGVyZQoJCQkgICBzdGlsbCBpcyBzb21lIG9sZCAvZXRjL210YWJ+ICovCgkJCSsrdHJpZXM7CgkJCWlmICh0cmllcyAlIDIwMCA9PSAwKQoJCQkgICB1c2xlZXAoMzApOwoJCQlpZiAodHJpZXMgPiAxMDAwMDApIHsKCQkJCSh2b2lkKSB1bmxpbmsobGlua3RhcmdldGZpbGUpOwoJCQkJY2xvc2UobG9ja2ZpbGVfZmQpOwoJCQkJZGllIChFWF9GSUxFSU8sIF8oIkNhbm5vdCBjcmVhdGUgbGluayAlc1xuIgoJCQkJCQkgICJQZXJoYXBzIHRoZXJlIGlzIGEgc3RhbGUgbG9jayBmaWxlP1xuIiksCgkJCQkJIE1PVU5URURfTE9DSyk7CiAJCQl9CgkJCWNsb3NlKGxvY2tmaWxlX2ZkKTsKCQl9Cgl9Cn0KCi8qCiAqIFVwZGF0ZSB0aGUgbXRhYi4KICogIFVzZWQgYnkgdW1vdW50IHdpdGggbnVsbCBJTlNURUFEOiByZW1vdmUgdGhlIGxhc3QgRElSIGVudHJ5LgogKiAgVXNlZCBieSBtb3VudCB1cG9uIGEgcmVtb3VudDogdXBkYXRlIG9wdGlvbiBwYXJ0LAogKiAgIGFuZCBjb21wbGFpbiBpZiBhIHdyb25nIGRldmljZSBvciB0eXBlIHdhcyBnaXZlbi4KICogICBbTm90ZSB0aGF0IG9mdGVuIGEgcmVtb3VudCB3aWxsIGJlIGEgcncgcmVtb3VudCBvZiAvCiAqICAgIHdoZXJlIHRoZXJlIHdhcyBubyBlbnRyeSBiZWZvcmUsIGFuZCB3ZSdsbCBoYXZlIHRvIGJlbGlldmUKICogICAgdGhlIHZhbHVlcyBnaXZlbiBpbiBJTlNURUFELl0KICovCgp2b2lkCnVwZGF0ZV9tdGFiIChjb25zdCBjaGFyICpkaXIsIHN0cnVjdCBtbnRlbnQgKmluc3RlYWQpCnsKCW1udEZJTEUgKm1mcCwgKm1mdG1wOwoJY29uc3QgY2hhciAqZm5hbSA9IE1PVU5URUQ7CglzdHJ1Y3QgbW50ZW50Y2huIG10YWJoZWFkOwkvKiBkdW1teSAqLwoJc3RydWN0IG1udGVudGNobiAqbWMsICptYzAsICphYnNlbnQgPSBOVUxMOwoKCWlmIChtdGFiX2RvZXNfbm90X2V4aXN0KCkgfHwgIW10YWJfaXNfd3JpdGFibGUoKSkKCQlyZXR1cm47CgoJbG9ja19tdGFiKCk7CgoJLyogaGF2aW5nIGxvY2tlZCBtdGFiLCByZWFkIGl0IGFnYWluICovCgltYzAgPSBtYyA9ICZtdGFiaGVhZDsKCW1jLT5ueHQgPSBtYy0+cHJldiA9IE5VTEw7CgoJbWZwID0gbmZzX3NldG1udGVudChmbmFtLCAiciIpOwoJaWYgKG1mcCA9PSBOVUxMIHx8IG1mcC0+bW50ZW50X2ZwID09IE5VTEwpIHsKCQlpbnQgZXJyc3YgPSBlcnJubzsKCQluZnNfZXJyb3IgKF8oImNhbm5vdCBvcGVuICVzICglcykgLSBtdGFiIG5vdCB1cGRhdGVkIiksCgkJICAgICAgIGZuYW0sIHN0cmVycm9yIChlcnJzdikpOwoJCWdvdG8gbGVhdmU7Cgl9CgoJcmVhZF9tbnRlbnRjaG4obWZwLCBmbmFtLCBtYyk7CgoJLyogZmluZCBsYXN0IG9jY3VycmVuY2Ugb2YgZGlyICovCglmb3IgKG1jID0gbWMwLT5wcmV2OyBtYyAmJiBtYyAhPSBtYzA7IG1jID0gbWMtPnByZXYpCgkJaWYgKHN0cmVxKG1jLT5tLm1udF9kaXIsIGRpcikpCgkJCWJyZWFrOwoJaWYgKG1jICYmIG1jICE9IG1jMCkgewoJCWlmIChpbnN0ZWFkID09IE5VTEwpIHsKCQkJLyogQW4gdW1vdW50IC0gcmVtb3ZlIGVudHJ5ICovCgkJCWlmIChtYyAmJiBtYyAhPSBtYzApIHsKCQkJCW1jLT5wcmV2LT5ueHQgPSBtYy0+bnh0OwoJCQkJbWMtPm54dC0+cHJldiA9IG1jLT5wcmV2OwoJCQkJZnJlZShtYyk7CgkJCX0KCQl9IGVsc2UgewoJCQkvKiBBIHJlbW91bnQgKi8KCQkJbWMtPm0ubW50X29wdHMgPSBpbnN0ZWFkLT5tbnRfb3B0czsKCQl9Cgl9IGVsc2UgaWYgKGluc3RlYWQpIHsKCQkvKiBub3QgZm91bmQsIGFkZCBhIG5ldyBlbnRyeSAqLwoJCWFic2VudCA9IHhtYWxsb2Moc2l6ZW9mKCphYnNlbnQpKTsKCQlhYnNlbnQtPm0gPSAqaW5zdGVhZDsKCQlhYnNlbnQtPm54dCA9IG1jMDsKCQlhYnNlbnQtPnByZXYgPSBtYzAtPnByZXY7CgkJbWMwLT5wcmV2ID0gYWJzZW50OwoJCWlmIChtYzAtPm54dCA9PSBOVUxMKQoJCQltYzAtPm54dCA9IGFic2VudDsKCX0KCgkvKiB3cml0ZSBjaGFpbiB0byBtdGVtcCAqLwoJbWZ0bXAgPSBuZnNfc2V0bW50ZW50IChNT1VOVEVEX1RFTVAsICJ3Iik7CglpZiAobWZ0bXAgPT0gTlVMTCB8fCBtZnRtcC0+bW50ZW50X2ZwID09IE5VTEwpIHsKCQlpbnQgZXJyc3YgPSBlcnJubzsKCQluZnNfZXJyb3IgKF8oImNhbm5vdCBvcGVuICVzICglcykgLSBtdGFiIG5vdCB1cGRhdGVkIiksCgkJICAgICAgIE1PVU5URURfVEVNUCwgc3RyZXJyb3IgKGVycnN2KSk7CgkJZ290byBsZWF2ZTsKCX0KCglmb3IgKG1jID0gbWMwLT5ueHQ7IG1jICYmIG1jICE9IG1jMDsgbWMgPSBtYy0+bnh0KSB7CgkJaWYgKG5mc19hZGRtbnRlbnQobWZ0bXAsICYobWMtPm0pKSA9PSAxKSB7CgkJCWludCBlcnJzdiA9IGVycm5vOwoJCQlkaWUgKEVYX0ZJTEVJTywgXygiZXJyb3Igd3JpdGluZyAlczogJXMiKSwKCQkJICAgICBNT1VOVEVEX1RFTVAsIHN0cmVycm9yIChlcnJzdikpOwoJCX0KCX0KCiNpZiAwCgkvKiB0aGUgY2hhaW4gbWlnaHQgaGF2ZSBzdHJpbmdzIGNvcGllZCBmcm9tICdpbnN0ZWFkJywKCSAqIHNvIHdlIGNhbm5vdCBzYWZlbHkgZnJlZSBpdC4KCSAqIEFuZCB0aGVyZSBpcyBubyBuZWVkIGFueXdheSBiZWNhdXNlIHdlIGFyZSBnb2luZyB0byBleGl0CgkgKiBzaG9ydGx5LiAgU28ganVzdCBkb24ndCBjYWxsIGRpc2NhcmRfbW50ZW50Y2huLi4uLgoJICovCglkaXNjYXJkX21udGVudGNobihtYzApOwojZW5kaWYKCWlmIChmY2htb2QgKGZpbGVubyAobWZ0bXAtPm1udGVudF9mcCksCgkJICAgIFNfSVJVU1J8U19JV1VTUnxTX0lSR1JQfFNfSVJPVEgpIDwgMCkgewoJCWludCBlcnJzdiA9IGVycm5vOwoJCWZwcmludGYoc3RkZXJyLCBfKCJlcnJvciBjaGFuZ2luZyBtb2RlIG9mICVzOiAlc1xuIiksCgkJCU1PVU5URURfVEVNUCwgc3RyZXJyb3IgKGVycnN2KSk7Cgl9CgluZnNfZW5kbW50ZW50IChtZnRtcCk7CgoJeyAvKgoJICAgKiBJZiBtb3VudCBpcyBzZXR1aWQgYW5kIHNvbWUgbm9uLXJvb3QgdXNlciBtb3VudHMgc3RoLAoJICAgKiB0aGVuIG10YWIudG1wIG1pZ2h0IGdldCB0aGUgZ3JvdXAgb2YgdGhpcyB1c2VyLiBDb3B5IHVpZC9naWQKCSAgICogZnJvbSB0aGUgcHJlc2VudCBtdGFiIGJlZm9yZSByZW5hbWluZy4KCSAgICovCgkgICAgc3RydWN0IHN0YXQgc2J1ZjsKCSAgICBpZiAoc3RhdCAoTU9VTlRFRCwgJnNidWYpID09IDApCgkJY2hvd24gKE1PVU5URURfVEVNUCwgc2J1Zi5zdF91aWQsIHNidWYuc3RfZ2lkKTsKCX0KCgkvKiByZW5hbWUgbXRlbXAgdG8gbXRhYiAqLwoJaWYgKHJlbmFtZSAoTU9VTlRFRF9URU1QLCBNT1VOVEVEKSA8IDApIHsKCQlpbnQgZXJyc3YgPSBlcnJubzsKCQlmcHJpbnRmKHN0ZGVyciwgXygiY2FuJ3QgcmVuYW1lICVzIHRvICVzOiAlc1xuIiksCgkJCU1PVU5URURfVEVNUCwgTU9VTlRFRCwgc3RyZXJyb3IoZXJyc3YpKTsKCX0KCiBsZWF2ZToKCXVubG9ja19tdGFiKCk7Cn0K