LyogMTk5OS0wMi0yMiBBcmthZGl1c3ogTWm2a2lld2ljeiA8bWlzaWVrQHBsZC5PUkcuUEw+CiAqIC0gYWRkZWQgTmF0aXZlIExhbmd1YWdlIFN1cHBvcnQKICogU3VuIE1hciAyMSAxOTk5IC0gQXJuYWxkbyBDYXJ2YWxobyBkZSBNZWxvIDxhY21lQGNvbmVjdGl2YS5jb20uYnI+CiAqIC0gZml4ZWQgc3RyZXJyKGVycm5vKSBpbiBnZXR0ZXh0IGNhbGxzCiAqCiAqIDIwMDYtMDYtMDggQW1pdCBHdWQgPGFndWRAcmVkaGF0LmNvbT4KICogLSBNb3ZlZCBjb2RlIHRvIG5mcy11dGlscy9zdXBwb3J0L25mcyBmcm9tIHV0aWwtbGludXgvbW91bnQuCiAqLwoKI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSA8bW50ZW50Lmg+CgojaW5jbHVkZSAiZnN0YWIuaCIKI2luY2x1ZGUgInhjb21tb24uaCIKI2luY2x1ZGUgIm5mc19tbnRlbnQuaCIKI2luY2x1ZGUgIm5mc19wYXRocy5oIgojaW5jbHVkZSAibmxzLmgiCgojZGVmaW5lIExPQ0tfVElNRU9VVAkxMAojZGVmaW5lIHN0cmVxKHMsIHQpCShzdHJjbXAgKChzKSwgKHQpKSA9PSAwKQojZGVmaW5lIFBST0NfTU9VTlRTCQkiL3Byb2MvbW91bnRzIgoKZXh0ZXJuIGNoYXIgKnByb2duYW1lOwpleHRlcm4gaW50IHZlcmJvc2U7CgovKiBJbmZvcm1hdGlvbiBhYm91dCBtdGFiLiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpzdGF0aWMgaW50IGhhdmVfbXRhYl9pbmZvID0gMDsKc3RhdGljIGludCB2YXJfbXRhYl9kb2VzX25vdF9leGlzdCA9IDA7CnN0YXRpYyBpbnQgdmFyX210YWJfaXNfYV9zeW1saW5rID0gMDsKCnN0YXRpYyB2b2lkCmdldF9tdGFiX2luZm8odm9pZCkgewoJc3RydWN0IHN0YXQgbXRhYl9zdGF0OwoKCWlmICghaGF2ZV9tdGFiX2luZm8pIHsKCQlpZiAobHN0YXQoTU9VTlRFRCwgJm10YWJfc3RhdCkpCgkJCXZhcl9tdGFiX2RvZXNfbm90X2V4aXN0ID0gMTsKCQllbHNlIGlmIChTX0lTTE5LKG10YWJfc3RhdC5zdF9tb2RlKSkKCQkJdmFyX210YWJfaXNfYV9zeW1saW5rID0gMTsKCQloYXZlX210YWJfaW5mbyA9IDE7Cgl9Cn0KCnZvaWQKcmVzZXRfbXRhYl9pbmZvKHZvaWQpIHsKICAgICAgICBoYXZlX210YWJfaW5mbyA9IDA7Cn0KCmludAptdGFiX2RvZXNfbm90X2V4aXN0KHZvaWQpIHsKCWdldF9tdGFiX2luZm8oKTsKCXJldHVybiB2YXJfbXRhYl9kb2VzX25vdF9leGlzdDsKfQoKc3RhdGljIGludAptdGFiX2lzX2Ffc3ltbGluayh2b2lkKSB7CiAgICAgICAgZ2V0X210YWJfaW5mbygpOwogICAgICAgIHJldHVybiB2YXJfbXRhYl9pc19hX3N5bWxpbms7Cn0KCmludAptdGFiX2lzX3dyaXRhYmxlKCkgewoJaW50IGZkOwoKCS8qIFNob3VsZCB3ZSB3cml0ZSB0byAvZXRjL210YWIgdXBvbiBhbiB1cGRhdGU/CgkgICBQcm9iYWJseSBub3QgaWYgaXQgaXMgYSBzeW1saW5rIHRvIC9wcm9jL21vdW50cywgc2luY2UgdGhhdAoJICAgd291bGQgY3JlYXRlIGEgZmlsZSAvcHJvYy9tb3VudHMgaW4gY2FzZSB0aGUgcHJvYyBmaWxlc3lzdGVtCgkgICBpcyBub3QgbW91bnRlZC4gKi8KCWlmIChtdGFiX2lzX2Ffc3ltbGluaygpKQoJCXJldHVybiAwOwoKCWZkID0gb3BlbihNT1VOVEVELCBPX1JEV1IgfCBPX0NSRUFULCAwNjQ0KTsKCWlmIChmZCA+PSAwKSB7CgkJY2xvc2UoZmQpOwoJCXJldHVybiAxOwoJfSBlbHNlCgkJcmV0dXJuIDA7Cn0KCi8qIENvbnRlbnRzIG9mIG10YWIgYW5kIGZzdGFiIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgpzdHJ1Y3QgbW50ZW50Y2huIG1vdW50dGFibGU7CnN0YXRpYyBpbnQgZ290X210YWIgPSAwOwpzdHJ1Y3QgbW50ZW50Y2huIGZzdGFiOwpzdGF0aWMgaW50IGdvdF9mc3RhYiA9IDA7CgpzdGF0aWMgdm9pZCByZWFkX21vdW50dGFibGUodm9pZCk7CnN0YXRpYyB2b2lkIHJlYWRfZnN0YWIodm9pZCk7CgpzdGF0aWMgc3RydWN0IG1udGVudGNobiAqCm10YWJfaGVhZCh2b2lkKQp7CglpZiAoIWdvdF9tdGFiKQoJCXJlYWRfbW91bnR0YWJsZSgpOwoJcmV0dXJuICZtb3VudHRhYmxlOwp9CgpzdGF0aWMgc3RydWN0IG1udGVudGNobiAqCmZzdGFiX2hlYWQodm9pZCkKewoJaWYgKCFnb3RfZnN0YWIpCgkJcmVhZF9mc3RhYigpOwoJcmV0dXJuICZmc3RhYjsKfQoKI2lmIDAKc3RhdGljIHZvaWQKbXlfZnJlZShjb25zdCB2b2lkICpzKSB7CglpZiAocykKCQlmcmVlKCh2b2lkICopIHMpOwp9CgpzdGF0aWMgdm9pZApkaXNjYXJkX21udGVudGNobihzdHJ1Y3QgbW50ZW50Y2huICptYzApIHsKCXN0cnVjdCBtbnRlbnRjaG4gKm1jLCAqbWMxOwoKCWZvciAobWMgPSBtYzAtPm54dDsgbWMgJiYgbWMgIT0gbWMwOyBtYyA9IG1jMSkgewoJCW1jMSA9IG1jLT5ueHQ7CgkJbXlfZnJlZShtYy0+bS5tbnRfZnNuYW1lKTsKCQlteV9mcmVlKG1jLT5tLm1udF9kaXIpOwoJCW15X2ZyZWUobWMtPm0ubW50X3R5cGUpOwoJCW15X2ZyZWUobWMtPm0ubW50X29wdHMpOwoJCWZyZWUobWMpOwoJfQp9CiNlbmRpZgoKc3RhdGljIHZvaWQKcmVhZF9tbnRlbnRjaG4obW50RklMRSAqbWZwLCBjb25zdCBjaGFyICpmbmFtLCBzdHJ1Y3QgbW50ZW50Y2huICptYzApIHsKCXN0cnVjdCBtbnRlbnRjaG4gKm1jID0gbWMwOwoJc3RydWN0IG1udGVudCAqbW50OwoKCXdoaWxlICgobW50ID0gbmZzX2dldG1udGVudChtZnApKSAhPSBOVUxMKSB7CgkJaWYgKCFzdHJlcShtbnQtPm1udF90eXBlLCBNTlRUWVBFX0lHTk9SRSkpIHsKCQkJbWMtPm54dCA9IChzdHJ1Y3QgbW50ZW50Y2huICopIHhtYWxsb2Moc2l6ZW9mKCptYykpOwoJCQltYy0+bnh0LT5wcmV2ID0gbWM7CgkJCW1jID0gbWMtPm54dDsKCQkJbWMtPm0gPSAqbW50OwoJCQltYy0+bnh0ID0gbWMwOwoJCX0KCX0KCW1jMC0+cHJldiA9IG1jOwoJaWYgKGZlcnJvcihtZnAtPm1udGVudF9mcCkpIHsKCQlpbnQgZXJyc3YgPSBlcnJubzsKCQluZnNfZXJyb3IoXygid2FybmluZzogZXJyb3IgcmVhZGluZyAlczogJXMiKSwKCQkgICAgICBmbmFtLCBzdHJlcnJvciAoZXJyc3YpKTsKCQltYzAtPm54dCA9IG1jMC0+cHJldiA9IE5VTEw7Cgl9CgluZnNfZW5kbW50ZW50KG1mcCk7Cn0KCi8qCiAqIFJlYWQgL2V0Yy9tdGFiLiAgSWYgdGhhdCBmYWlscywgdHJ5IC9wcm9jL21vdW50cy4KICogVGhpcyBwcm9kdWNlcyBhIGxpbmtlZCBsaXN0LiBUaGUgbGlzdCBoZWFkIG1vdW50dGFibGUgaXMgYSBkdW1teS4KICogUmV0dXJuIDAgb24gc3VjY2Vzcy4KICovCnN0YXRpYyB2b2lkCnJlYWRfbW91bnR0YWJsZSgpIHsKICAgICAgICBtbnRGSUxFICptZnA7CiAgICAgICAgY29uc3QgY2hhciAqZm5hbTsKICAgICAgICBzdHJ1Y3QgbW50ZW50Y2huICptYyA9ICZtb3VudHRhYmxlOwoKICAgICAgICBnb3RfbXRhYiA9IDE7CiAgICAgICAgbWMtPm54dCA9IG1jLT5wcmV2ID0gTlVMTDsKCiAgICAgICAgZm5hbSA9IE1PVU5URUQ7CiAgICAgICAgbWZwID0gbmZzX3NldG1udGVudCAoZm5hbSwgInIiKTsKICAgICAgICBpZiAobWZwID09IE5VTEwgfHwgbWZwLT5tbnRlbnRfZnAgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgaW50IGVycnN2ID0gZXJybm87CiAgICAgICAgICAgICAgICBmbmFtID0gUFJPQ19NT1VOVFM7CiAgICAgICAgICAgICAgICBtZnAgPSBuZnNfc2V0bW50ZW50IChmbmFtLCAiciIpOwogICAgICAgICAgICAgICAgaWYgKG1mcCA9PSBOVUxMIHx8IG1mcC0+bW50ZW50X2ZwID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbmZzX2Vycm9yKF8oIndhcm5pbmc6IGNhbid0IG9wZW4gJXM6ICVzIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1PVU5URUQsIHN0cmVycm9yIChlcnJzdikpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAodmVyYm9zZSkKICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRmKF8oIiVzOiBjb3VsZCBub3Qgb3BlbiAlczsgdXNpbmcgJXMgaW5zdGVhZFxuIiksCgkJCQlwcm9nbmFtZSwgTU9VTlRFRCwgUFJPQ19NT1VOVFMpOwogICAgICAgIH0KICAgICAgICByZWFkX21udGVudGNobihtZnAsIGZuYW0sIG1jKTsKfQoKc3RhdGljIHZvaWQKcmVhZF9mc3RhYigpCnsKCW1udEZJTEUgKm1mcCA9IE5VTEw7Cgljb25zdCBjaGFyICpmbmFtOwoJc3RydWN0IG1udGVudGNobiAqbWMgPSAmZnN0YWI7CgoJZ290X2ZzdGFiID0gMTsKCW1jLT5ueHQgPSBtYy0+cHJldiA9IE5VTEw7CgoJZm5hbSA9IF9QQVRIX0ZTVEFCOwoJbWZwID0gbmZzX3NldG1udGVudCAoZm5hbSwgInIiKTsKCWlmIChtZnAgPT0gTlVMTCB8fCBtZnAtPm1udGVudF9mcCA9PSBOVUxMKSB7CgkJaW50IGVycnN2ID0gZXJybm87CgkJbmZzX2Vycm9yKF8oIndhcm5pbmc6IGNhbid0IG9wZW4gJXM6ICVzIiksCgkJCSAgX1BBVEhfRlNUQUIsIHN0cmVycm9yIChlcnJzdikpOwoJCXJldHVybjsKCX0KCXJlYWRfbW50ZW50Y2huKG1mcCwgZm5hbSwgbWMpOwp9CgovKgogKiBHaXZlbiB0aGUgZGlyZWN0b3J5IG5hbWUgTkFNRSwgYW5kIHRoZSBwbGFjZSBNQ1BSRVYgd2UgZm91bmQgaXQgbGFzdCB0aW1lLAogKiB0cnkgdG8gZmluZCBtb3JlIG9jY3VycmVuY2VzLgogKi8gCnN0cnVjdCBtbnRlbnRjaG4gKgpnZXRtbnRkaXJiYWNrd2FyZCAoY29uc3QgY2hhciAqbmFtZSwgc3RydWN0IG1udGVudGNobiAqbWNwcmV2KSB7CglzdHJ1Y3QgbW50ZW50Y2huICptYywgKm1jMDsKCgltYzAgPSBtdGFiX2hlYWQoKTsKCWlmICghbWNwcmV2KQoJCW1jcHJldiA9IG1jMDsKCWZvciAobWMgPSBtY3ByZXYtPnByZXY7IG1jICYmIG1jICE9IG1jMDsgbWMgPSBtYy0+cHJldikKCQlpZiAoc3RyZXEobWMtPm0ubW50X2RpciwgbmFtZSkpCgkJCXJldHVybiBtYzsKCXJldHVybiBOVUxMOwp9CgovKgogKiBHaXZlbiB0aGUgZGV2aWNlIG5hbWUgTkFNRSwgYW5kIHRoZSBwbGFjZSBNQ1BSRVYgd2UgZm91bmQgaXQgbGFzdCB0aW1lLAogKiB0cnkgdG8gZmluZCBtb3JlIG9jY3VycmVuY2VzLgogKi8gCnN0cnVjdCBtbnRlbnRjaG4gKgpnZXRtbnRkZXZiYWNrd2FyZCAoY29uc3QgY2hhciAqbmFtZSwgc3RydWN0IG1udGVudGNobiAqbWNwcmV2KSB7CglzdHJ1Y3QgbW50ZW50Y2huICptYywgKm1jMDsKCgltYzAgPSBtdGFiX2hlYWQoKTsKCWlmICghbWNwcmV2KQoJCW1jcHJldiA9IG1jMDsKCWZvciAobWMgPSBtY3ByZXYtPnByZXY7IG1jICYmIG1jICE9IG1jMDsgbWMgPSBtYy0+cHJldikKCQlpZiAoc3RyZXEobWMtPm0ubW50X2ZzbmFtZSwgbmFtZSkpCgkJCXJldHVybiBtYzsKCXJldHVybiBOVUxMOwp9CgovKiBGaW5kIHRoZSBkaXIgRklMRSBpbiBmc3RhYi4gICovCnN0cnVjdCBtbnRlbnRjaG4gKgpnZXRmc2ZpbGUgKGNvbnN0IGNoYXIgKmZpbGUpCnsKCXN0cnVjdCBtbnRlbnRjaG4gKm1jLCAqbWMwOwoKCW1jMCA9IGZzdGFiX2hlYWQoKTsKCWZvciAobWMgPSBtYzAtPm54dDsgbWMgJiYgbWMgIT0gbWMwOyBtYyA9IG1jLT5ueHQpCgkJaWYgKHN0cmVxKG1jLT5tLm1udF9kaXIsIGZpbGUpKQoJCQlyZXR1cm4gbWM7CglyZXR1cm4gTlVMTDsKfQoKLyogRmluZCB0aGUgZGV2aWNlIFNQRUMgaW4gZnN0YWIuICAqLwpzdHJ1Y3QgbW50ZW50Y2huICoKZ2V0ZnNzcGVjIChjb25zdCBjaGFyICpzcGVjKQp7CglzdHJ1Y3QgbW50ZW50Y2huICptYywgKm1jMDsKCgltYzAgPSBmc3RhYl9oZWFkKCk7Cglmb3IgKG1jID0gbWMwLT5ueHQ7IG1jICYmIG1jICE9IG1jMDsgbWMgPSBtYy0+bnh0KQoJCWlmIChzdHJlcShtYy0+bS5tbnRfZnNuYW1lLCBzcGVjKSkKCQkJcmV0dXJuIG1jOwoJcmV0dXJuIE5VTEw7Cn0KCi8qIFVwZGF0aW5nIG10YWIgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgovKiBGbGFnIGZvciBhbHJlYWR5IGV4aXN0aW5nIGxvY2sgZmlsZS4gKi8Kc3RhdGljIGludCB3ZV9jcmVhdGVkX2xvY2tmaWxlID0gMDsKc3RhdGljIGludCBsb2NrZmlsZV9mZCA9IC0xOwoKLyogRmxhZyB0byBpbmRpY2F0ZSB0aGF0IHNpZ25hbHMgaGF2ZSBiZWVuIHNldCB1cC4gKi8Kc3RhdGljIGludCBzaWduYWxzX2hhdmVfYmVlbl9zZXR1cCA9IDA7CgovKiBFbnN1cmUgdGhhdCB0aGUgbG9jayBpcyByZWxlYXNlZCBpZiB3ZSBhcmUgaW50ZXJydXB0ZWQuICAqLwpleHRlcm4gY2hhciAqc3Ryc2lnbmFsKGludCBzaWcpOwkvKiBub3QgYWx3YXlzIGluIDxzdHJpbmcuaD4gKi8KCnN0YXRpYyB2b2lkCmhhbmRsZXIgKGludCBzaWcpIHsKICAgICBkaWUoRVhfVVNFUiwgIiVzIiwgc3Ryc2lnbmFsKHNpZykpOwp9CgpzdGF0aWMgdm9pZApzZXRsa3dfdGltZW91dCAoX19hdHRyaWJ1dGVfXygodW51c2VkKSkgaW50IHNpZykgewogICAgIC8qIG5vdGhpbmcsIGZjbnRsIHdpbGwgZmFpbCBhbnl3YXkgKi8KfQoKLyogUmVtb3ZlIGxvY2sgZmlsZS4gICovCnZvaWQKdW5sb2NrX210YWIgKHZvaWQpIHsKCWlmICh3ZV9jcmVhdGVkX2xvY2tmaWxlKSB7CgkJY2xvc2UobG9ja2ZpbGVfZmQpOwoJCWxvY2tmaWxlX2ZkID0gLTE7CgkJdW5saW5rIChNT1VOVEVEX0xPQ0spOwoJCXdlX2NyZWF0ZWRfbG9ja2ZpbGUgPSAwOwoJfQp9CgovKiBDcmVhdGUgdGhlIGxvY2sgZmlsZS4KICAgVGhlIGxvY2sgZmlsZSB3aWxsIGJlIHJlbW92ZWQgaWYgd2UgY2F0Y2ggYSBzaWduYWwgb3Igd2hlbiB3ZSBleGl0LiAqLwovKiBUaGUgb2xkIGNvZGUgaGVyZSB1c2VkIGZsb2NrIG9uIGEgbG9jayBmaWxlIC9ldGMvbXRhYn4gYW5kIGRlbGV0ZWQKICAgdGhpcyBsb2NrIGZpbGUgYWZ0ZXJ3YXJkcy4gSG93ZXZlciwgYXMgcmdvb2NoIHJlbWFya3MsIHRoYXQgaGFzIGEKICAgcmFjZTogYSBzZWNvbmQgbW91bnQgbWF5IGJlIHdhaXRpbmcgb24gdGhlIGxvY2sgYW5kIHByb2NlZWQgYXMKICAgc29vbiBhcyB0aGUgbG9jayBmaWxlIGlzIGRlbGV0ZWQgYnkgdGhlIGZpcnN0IG1vdW50LCBhbmQgaW1tZWRpYXRlbHkKICAgYWZ0ZXJ3YXJkcyBhIHRoaXJkIG1vdW50IGNvbWVzLCBjcmVhdGVzIGEgbmV3IC9ldGMvbXRhYn4sIGFwcGxpZXMKICAgZmxvY2sgdG8gdGhhdCwgYW5kIGFsc28gcHJvY2VlZHMsIHNvIHRoYXQgdGhlIHNlY29uZCBhbmQgdGhpcmQgbW91bnQKICAgbm93IGJvdGggYXJlIHNjcmliYmxpbmcgaW4gL2V0Yy9tdGFiLgogICBUaGUgbmV3IGNvZGUgdXNlcyBhIGxpbmsoKSBpbnN0ZWFkIG9mIGEgY3JlYXQoKSwgd2hlcmUgd2UgcHJvY2VlZAogICBvbmx5IGlmIGl0IHdhcyB1cyB0aGF0IGNyZWF0ZWQgdGhlIGxvY2ssIGFuZCBoZW5jZSB3ZSBhbHdheXMgaGF2ZQogICB0byBkZWxldGUgdGhlIGxvY2sgYWZ0ZXJ3YXJkcy4gTm93IHRoZSB1c2Ugb2YgZmxvY2soKSBpcyBpbiBwcmluY2lwbGUKICAgc3VwZXJmbHVvdXMsIGJ1dCBhdm9pZHMgYW4gYXJiaXRyYXJ5IHNsZWVwKCkuICovCgovKiBXaGVyZSBkb2VzIHRoZSBsaW5rIHBvaW50IHRvPyBPYnZpb3VzIGNob2ljZXMgYXJlIG10YWIgYW5kIG10YWJ+fi4KICAgSEpMdSBwb2ludHMgb3V0IHRoYXQgdGhlIGxhdHRlciBsZWFkcyB0byByYWNlcy4gUmlnaHQgbm93IHdlIHVzZQogICBtdGFifi48cGlkPiBpbnN0ZWFkLiBVc2UgMjAgYXMgdXBwZXIgYm91bmQgZm9yIHRoZSBsZW5ndGggb2YgJWQuICovCiNkZWZpbmUgTU9VTlRMT0NLX0xJTktUQVJHRVQJCU1PVU5URURfTE9DSyAiJWQiCiNkZWZpbmUgTU9VTlRMT0NLX0xJTktUQVJHRVRfTFRICShzaXplb2YoTU9VTlRFRF9MT0NLKSsyMCkKCnZvaWQKbG9ja19tdGFiICh2b2lkKSB7CglpbnQgdHJpZXMgPSAxMDAwMDAsIGk7CgljaGFyIGxpbmt0YXJnZXRmaWxlW01PVU5UTE9DS19MSU5LVEFSR0VUX0xUSF07CgoJYXRfZGllID0gdW5sb2NrX210YWI7CgoJaWYgKCFzaWduYWxzX2hhdmVfYmVlbl9zZXR1cCkgewoJCWludCBzaWcgPSAwOwoJCXN0cnVjdCBzaWdhY3Rpb24gc2E7CgoJCXNhLnNhX2hhbmRsZXIgPSBoYW5kbGVyOwoJCXNhLnNhX2ZsYWdzID0gMDsKCQlzaWdmaWxsc2V0ICgmc2Euc2FfbWFzayk7CiAgCgkJd2hpbGUgKHNpZ2lzbWVtYmVyICgmc2Euc2FfbWFzaywgKytzaWcpICE9IC0xCgkJICAgICAgICYmIHNpZyAhPSBTSUdDSExEKSB7CgkJCWlmIChzaWcgPT0gU0lHQUxSTSkKCQkJCXNhLnNhX2hhbmRsZXIgPSBzZXRsa3dfdGltZW91dDsKCQkJZWxzZQoJCQkJc2Euc2FfaGFuZGxlciA9IGhhbmRsZXI7CgkJCXNpZ2FjdGlvbiAoc2lnLCAmc2EsIChzdHJ1Y3Qgc2lnYWN0aW9uICopIDApOwoJCX0KCQlzaWduYWxzX2hhdmVfYmVlbl9zZXR1cCA9IDE7Cgl9CgoJc3ByaW50ZihsaW5rdGFyZ2V0ZmlsZSwgTU9VTlRMT0NLX0xJTktUQVJHRVQsIGdldHBpZCAoKSk7CgoJaSA9IG9wZW4gKGxpbmt0YXJnZXRmaWxlLCBPX1dST05MWXxPX0NSRUFULCAwKTsKCWlmIChpIDwgMCkgewoJCWludCBlcnJzdiA9IGVycm5vOwoJCS8qIGxpbmt0YXJnZXRmaWxlIGRvZXMgbm90IGV4aXN0IChhcyBhIGZpbGUpCgkJICAgYW5kIHdlIGNhbm5vdCBjcmVhdGUgaXQuIFJlYWQtb25seSBmaWxlc3lzdGVtPwoJCSAgIFRvbyBtYW55IGZpbGVzIG9wZW4gaW4gdGhlIHN5c3RlbT8KCQkgICBGaWxlc3lzdGVtIGZ1bGw/ICovCgkJZGllIChFWF9GSUxFSU8sIF8oImNhbid0IGNyZWF0ZSBsb2NrIGZpbGUgJXM6ICVzICIKCQkJCQkJICAiKHVzZSAtbiBmbGFnIHRvIG92ZXJyaWRlKSIpLAoJCQkgbGlua3RhcmdldGZpbGUsIHN0cmVycm9yIChlcnJzdikpOwoJfQoJY2xvc2UoaSk7CgkKCS8qIFJlcGVhdCB1bnRpbCBpdCB3YXMgdXMgd2hvIG1hZGUgdGhlIGxpbmsgKi8KCXdoaWxlICghd2VfY3JlYXRlZF9sb2NrZmlsZSkgewoJCXN0cnVjdCBmbG9jayBmbG9jazsKCQlpbnQgZXJyc3YsIGo7CgoJCWogPSBsaW5rKGxpbmt0YXJnZXRmaWxlLCBNT1VOVEVEX0xPQ0spOwoJCWVycnN2ID0gZXJybm87CgoJCWlmIChqID09IDApCgkJCXdlX2NyZWF0ZWRfbG9ja2ZpbGUgPSAxOwoKCQlpZiAoaiA8IDAgJiYgZXJyc3YgIT0gRUVYSVNUKSB7CgkJCSh2b2lkKSB1bmxpbmsobGlua3RhcmdldGZpbGUpOwoJCQlkaWUgKEVYX0ZJTEVJTywgXygiY2FuJ3QgbGluayBsb2NrIGZpbGUgJXM6ICVzICIKCQkJICAgICAiKHVzZSAtbiBmbGFnIHRvIG92ZXJyaWRlKSIpLAoJCQkgICAgIE1PVU5URURfTE9DSywgc3RyZXJyb3IgKGVycnN2KSk7CgkJfQoKCQlsb2NrZmlsZV9mZCA9IG9wZW4gKE1PVU5URURfTE9DSywgT19XUk9OTFkpOwoKCQlpZiAobG9ja2ZpbGVfZmQgPCAwKSB7CgkJCWludCBlcnJzdiA9IGVycm5vOwoJCQkvKiBTdHJhbmdlLi4uIE1heWJlIHRoZSBmaWxlIHdhcyBqdXN0IGRlbGV0ZWQ/ICovCgkJCWlmIChlcnJubyA9PSBFTk9FTlQgJiYgdHJpZXMtLSA+IDApIHsKCQkJCWlmICh0cmllcyAlIDIwMCA9PSAwKQoJCQkJCXVzbGVlcCgzMCk7CgkJCQljb250aW51ZTsKCQkJfQoJCQkodm9pZCkgdW5saW5rKGxpbmt0YXJnZXRmaWxlKTsKCQkJZGllIChFWF9GSUxFSU8sIF8oImNhbid0IG9wZW4gbG9jayBmaWxlICVzOiAlcyAiCgkJCSAgICAgIih1c2UgLW4gZmxhZyB0byBvdmVycmlkZSkiKSwKCQkJICAgICBNT1VOVEVEX0xPQ0ssIHN0cmVycm9yIChlcnJzdikpOwoJCX0KCgkJZmxvY2subF90eXBlID0gRl9XUkxDSzsKCQlmbG9jay5sX3doZW5jZSA9IFNFRUtfU0VUOwoJCWZsb2NrLmxfc3RhcnQgPSAwOwoJCWZsb2NrLmxfbGVuID0gMDsKCgkJaWYgKGogPT0gMCkgewoJCQkvKiBXZSBtYWRlIHRoZSBsaW5rLiBOb3cgY2xhaW0gdGhlIGxvY2suICovCgkJCWlmIChmY250bCAobG9ja2ZpbGVfZmQsIEZfU0VUTEssICZmbG9jaykgPT0gLTEpIHsKCQkJCWlmICh2ZXJib3NlKSB7CgkJCQkgICAgaW50IGVycnN2ID0gZXJybm87CgkJCQkgICAgbmZzX2Vycm9yKF8oIiVzOiBDYW4ndCBsb2NrIGxvY2sgZmlsZSAiCgkJCQkJCSIlczogJXMiKSwgcHJvZ25hbWUsCgkJCQkJICAgCU1PVU5URURfTE9DSywKCQkJCQkJc3RyZXJyb3IgKGVycnN2KSk7CgkJCQl9CgkJCQkvKiBwcm9jZWVkIGFueXdheSAqLwoJCQl9CgkJCSh2b2lkKSB1bmxpbmsobGlua3RhcmdldGZpbGUpOwoJCX0gZWxzZSB7CgkJCXN0YXRpYyBpbnQgdHJpZXMgPSAwOwoKCQkJLyogU29tZW9uZSBlbHNlIG1hZGUgdGhlIGxpbmsuIFdhaXQuICovCgkJCWFsYXJtKExPQ0tfVElNRU9VVCk7CgkJCWlmIChmY250bCAobG9ja2ZpbGVfZmQsIEZfU0VUTEtXLCAmZmxvY2spID09IC0xKSB7CgkJCQlpbnQgZXJyc3YgPSBlcnJubzsKCQkJCSh2b2lkKSB1bmxpbmsobGlua3RhcmdldGZpbGUpOwoJCQkJZGllIChFWF9GSUxFSU8sIF8oImNhbid0IGxvY2sgbG9jayBmaWxlICVzOiAlcyIpLAoJCQkJICAgICBNT1VOVEVEX0xPQ0ssIChlcnJubyA9PSBFSU5UUikgPwoJCQkJICAgICBfKCJ0aW1lZCBvdXQiKSA6IHN0cmVycm9yIChlcnJzdikpOwoJCQl9CgkJCWFsYXJtKDApOwoJCQkvKiBMaW1pdCB0aGUgbnVtYmVyIG9mIGl0ZXJhdGlvbnMgLSBtYXliZSB0aGVyZQoJCQkgICBzdGlsbCBpcyBzb21lIG9sZCAvZXRjL210YWJ+ICovCgkJCSsrdHJpZXM7CgkJCWlmICh0cmllcyAlIDIwMCA9PSAwKQoJCQkgICB1c2xlZXAoMzApOwoJCQlpZiAodHJpZXMgPiAxMDAwMDApIHsKCQkJCSh2b2lkKSB1bmxpbmsobGlua3RhcmdldGZpbGUpOwoJCQkJY2xvc2UobG9ja2ZpbGVfZmQpOwoJCQkJZGllIChFWF9GSUxFSU8sIF8oIkNhbm5vdCBjcmVhdGUgbGluayAlc1xuIgoJCQkJCQkgICJQZXJoYXBzIHRoZXJlIGlzIGEgc3RhbGUgbG9jayBmaWxlP1xuIiksCgkJCQkJIE1PVU5URURfTE9DSyk7CiAJCQl9CgkJCWNsb3NlKGxvY2tmaWxlX2ZkKTsKCQl9Cgl9Cn0KCi8qCiAqIFVwZGF0ZSB0aGUgbXRhYi4KICogIFVzZWQgYnkgdW1vdW50IHdpdGggbnVsbCBJTlNURUFEOiByZW1vdmUgdGhlIGxhc3QgRElSIGVudHJ5LgogKiAgVXNlZCBieSBtb3VudCB1cG9uIGEgcmVtb3VudDogdXBkYXRlIG9wdGlvbiBwYXJ0LAogKiAgIGFuZCBjb21wbGFpbiBpZiBhIHdyb25nIGRldmljZSBvciB0eXBlIHdhcyBnaXZlbi4KICogICBbTm90ZSB0aGF0IG9mdGVuIGEgcmVtb3VudCB3aWxsIGJlIGEgcncgcmVtb3VudCBvZiAvCiAqICAgIHdoZXJlIHRoZXJlIHdhcyBubyBlbnRyeSBiZWZvcmUsIGFuZCB3ZSdsbCBoYXZlIHRvIGJlbGlldmUKICogICAgdGhlIHZhbHVlcyBnaXZlbiBpbiBJTlNURUFELl0KICovCgp2b2lkCnVwZGF0ZV9tdGFiIChjb25zdCBjaGFyICpkaXIsIHN0cnVjdCBtbnRlbnQgKmluc3RlYWQpCnsKCW1udEZJTEUgKm1mcCwgKm1mdG1wOwoJY29uc3QgY2hhciAqZm5hbSA9IE1PVU5URUQ7CglzdHJ1Y3QgbW50ZW50Y2huIG10YWJoZWFkOwkvKiBkdW1teSAqLwoJc3RydWN0IG1udGVudGNobiAqbWMsICptYzAsICphYnNlbnQgPSBOVUxMOwoKCWlmIChtdGFiX2RvZXNfbm90X2V4aXN0KCkgfHwgIW10YWJfaXNfd3JpdGFibGUoKSkKCQlyZXR1cm47CgoJbG9ja19tdGFiKCk7CgoJLyogaGF2aW5nIGxvY2tlZCBtdGFiLCByZWFkIGl0IGFnYWluICovCgltYzAgPSBtYyA9ICZtdGFiaGVhZDsKCW1jLT5ueHQgPSBtYy0+cHJldiA9IE5VTEw7CgoJbWZwID0gbmZzX3NldG1udGVudChmbmFtLCAiciIpOwoJaWYgKG1mcCA9PSBOVUxMIHx8IG1mcC0+bW50ZW50X2ZwID09IE5VTEwpIHsKCQlpbnQgZXJyc3YgPSBlcnJubzsKCQluZnNfZXJyb3IgKF8oImNhbm5vdCBvcGVuICVzICglcykgLSBtdGFiIG5vdCB1cGRhdGVkIiksCgkJICAgICAgIGZuYW0sIHN0cmVycm9yIChlcnJzdikpOwoJCWdvdG8gbGVhdmU7Cgl9CgoJcmVhZF9tbnRlbnRjaG4obWZwLCBmbmFtLCBtYyk7CgoJLyogZmluZCBsYXN0IG9jY3VycmVuY2Ugb2YgZGlyICovCglmb3IgKG1jID0gbWMwLT5wcmV2OyBtYyAmJiBtYyAhPSBtYzA7IG1jID0gbWMtPnByZXYpCgkJaWYgKHN0cmVxKG1jLT5tLm1udF9kaXIsIGRpcikpCgkJCWJyZWFrOwoJaWYgKG1jICYmIG1jICE9IG1jMCkgewoJCWlmIChpbnN0ZWFkID09IE5VTEwpIHsKCQkJLyogQW4gdW1vdW50IC0gcmVtb3ZlIGVudHJ5ICovCgkJCWlmIChtYyAmJiBtYyAhPSBtYzApIHsKCQkJCW1jLT5wcmV2LT5ueHQgPSBtYy0+bnh0OwoJCQkJbWMtPm54dC0+cHJldiA9IG1jLT5wcmV2OwoJCQkJZnJlZShtYyk7CgkJCX0KCQl9IGVsc2UgewoJCQkvKiBBIHJlbW91bnQgKi8KCQkJbWMtPm0ubW50X29wdHMgPSBpbnN0ZWFkLT5tbnRfb3B0czsKCQl9Cgl9IGVsc2UgaWYgKGluc3RlYWQpIHsKCQkvKiBub3QgZm91bmQsIGFkZCBhIG5ldyBlbnRyeSAqLwoJCWFic2VudCA9IHhtYWxsb2Moc2l6ZW9mKCphYnNlbnQpKTsKCQlhYnNlbnQtPm0gPSAqaW5zdGVhZDsKCQlhYnNlbnQtPm54dCA9IG1jMDsKCQlhYnNlbnQtPnByZXYgPSBtYzAtPnByZXY7CgkJbWMwLT5wcmV2ID0gYWJzZW50OwoJCWlmIChtYzAtPm54dCA9PSBOVUxMKQoJCQltYzAtPm54dCA9IGFic2VudDsKCX0KCgkvKiB3cml0ZSBjaGFpbiB0byBtdGVtcCAqLwoJbWZ0bXAgPSBuZnNfc2V0bW50ZW50IChNT1VOVEVEX1RFTVAsICJ3Iik7CglpZiAobWZ0bXAgPT0gTlVMTCB8fCBtZnRtcC0+bW50ZW50X2ZwID09IE5VTEwpIHsKCQlpbnQgZXJyc3YgPSBlcnJubzsKCQluZnNfZXJyb3IgKF8oImNhbm5vdCBvcGVuICVzICglcykgLSBtdGFiIG5vdCB1cGRhdGVkIiksCgkJICAgICAgIE1PVU5URURfVEVNUCwgc3RyZXJyb3IgKGVycnN2KSk7CgkJZ290byBsZWF2ZTsKCX0KCglmb3IgKG1jID0gbWMwLT5ueHQ7IG1jICYmIG1jICE9IG1jMDsgbWMgPSBtYy0+bnh0KSB7CgkJaWYgKG5mc19hZGRtbnRlbnQobWZ0bXAsICYobWMtPm0pKSA9PSAxKSB7CgkJCWludCBlcnJzdiA9IGVycm5vOwoJCQlkaWUgKEVYX0ZJTEVJTywgXygiZXJyb3Igd3JpdGluZyAlczogJXMiKSwKCQkJICAgICBNT1VOVEVEX1RFTVAsIHN0cmVycm9yIChlcnJzdikpOwoJCX0KCX0KCiNpZiAwCgkvKiB0aGUgY2hhaW4gbWlnaHQgaGF2ZSBzdHJpbmdzIGNvcGllZCBmcm9tICdpbnN0ZWFkJywKCSAqIHNvIHdlIGNhbm5vdCBzYWZlbHkgZnJlZSBpdC4KCSAqIEFuZCB0aGVyZSBpcyBubyBuZWVkIGFueXdheSBiZWNhdXNlIHdlIGFyZSBnb2luZyB0byBleGl0CgkgKiBzaG9ydGx5LiAgU28ganVzdCBkb24ndCBjYWxsIGRpc2NhcmRfbW50ZW50Y2huLi4uLgoJICovCglkaXNjYXJkX21udGVudGNobihtYzApOwojZW5kaWYKCWlmIChmY2htb2QgKGZpbGVubyAobWZ0bXAtPm1udGVudF9mcCksCgkJICAgIFNfSVJVU1J8U19JV1VTUnxTX0lSR1JQfFNfSVJPVEgpIDwgMCkgewoJCWludCBlcnJzdiA9IGVycm5vOwoJCW5mc19lcnJvcihfKCIlczogZXJyb3IgY2hhbmdpbmcgbW9kZSBvZiAlczogJXMiKSwKCQkJCXByb2duYW1lLCBNT1VOVEVEX1RFTVAsIHN0cmVycm9yIChlcnJzdikpOwoJfQoJbmZzX2VuZG1udGVudCAobWZ0bXApOwoKCXsgLyoKCSAgICogSWYgbW91bnQgaXMgc2V0dWlkIGFuZCBzb21lIG5vbi1yb290IHVzZXIgbW91bnRzIHN0aCwKCSAgICogdGhlbiBtdGFiLnRtcCBtaWdodCBnZXQgdGhlIGdyb3VwIG9mIHRoaXMgdXNlci4gQ29weSB1aWQvZ2lkCgkgICAqIGZyb20gdGhlIHByZXNlbnQgbXRhYiBiZWZvcmUgcmVuYW1pbmcuCgkgICAqLwoJICAgIHN0cnVjdCBzdGF0IHNidWY7CgkgICAgaWYgKHN0YXQgKE1PVU5URUQsICZzYnVmKSA9PSAwKSB7CgkJCWlmIChjaG93biAoTU9VTlRFRF9URU1QLCBzYnVmLnN0X3VpZCwgc2J1Zi5zdF9naWQpIDwgMCkgewoJCQkJbmZzX2Vycm9yKF8oIiVzOiBlcnJvciBjaGFuZ2luZyBvd25lciBvZiAlczogJXMiKSwKCQkJCQlwcm9nbmFtZSwgTU9VTlRFRF9URU1QLCBzdHJlcnJvciAoZXJybm8pKTsKCQkJfQoJCX0KCX0KCgkvKiByZW5hbWUgbXRlbXAgdG8gbXRhYiAqLwoJaWYgKHJlbmFtZSAoTU9VTlRFRF9URU1QLCBNT1VOVEVEKSA8IDApIHsKCQlpbnQgZXJyc3YgPSBlcnJubzsKCQluZnNfZXJyb3IoXygiJXM6IGNhbid0IHJlbmFtZSAlcyB0byAlczogJXNcbiIpLAoJCQkJcHJvZ25hbWUsIE1PVU5URURfVEVNUCwgTU9VTlRFRCwKCQkJCXN0cmVycm9yKGVycnN2KSk7Cgl9CgogbGVhdmU6Cgl1bmxvY2tfbXRhYigpOwp9Cg==