LyogMTk5OS0wMi0yMiBBcmthZGl1c3ogTWm2a2lld2ljeiA8bWlzaWVrQHBsZC5PUkcuUEw+CiAqIC0gYWRkZWQgTmF0aXZlIExhbmd1YWdlIFN1cHBvcnQKICogU3VuIE1hciAyMSAxOTk5IC0gQXJuYWxkbyBDYXJ2YWxobyBkZSBNZWxvIDxhY21lQGNvbmVjdGl2YS5jb20uYnI+CiAqIC0gZml4ZWQgc3RyZXJyKGVycm5vKSBpbiBnZXR0ZXh0IGNhbGxzCiAqLwoKI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxzeXMvdGltZS5oPgojaW5jbHVkZSA8dGltZS5oPgojaW5jbHVkZSA8bW50ZW50Lmg+CiNpbmNsdWRlICJtb3VudF9tbnRlbnQuaCIKI2luY2x1ZGUgImZzdGFiLmgiCiNpbmNsdWRlICJzdW5kcmllcy5oIgojaW5jbHVkZSAieG1hbGxvYy5oIgojaW5jbHVkZSAiZnNwcm9iZS5oIgojaW5jbHVkZSAicGF0aG5hbWVzLmgiCiNpbmNsdWRlICJubHMuaCIKI2luY2x1ZGUgInVzbGVlcC5oIgoKI2RlZmluZSBzdHJlcShzLCB0KQkoc3RyY21wICgocyksICh0KSkgPT0gMCkKCi8qIEluZm9ybWF0aW9uIGFib3V0IG10YWIuIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnN0YXRpYyBpbnQgaGF2ZV9tdGFiX2luZm8gPSAwOwpzdGF0aWMgaW50IHZhcl9tdGFiX2RvZXNfbm90X2V4aXN0ID0gMDsKc3RhdGljIGludCB2YXJfbXRhYl9pc19hX3N5bWxpbmsgPSAwOwoKc3RhdGljIHZvaWQKZ2V0X210YWJfaW5mbyh2b2lkKSB7CglpZiAoIWhhdmVfbXRhYl9pbmZvKSB7CgkJc3RydWN0IHN0YXQgbXRhYl9zdGF0OwoKCQl2YXJfbXRhYl9kb2VzX25vdF9leGlzdCA9IDA7CgkJdmFyX210YWJfaXNfYV9zeW1saW5rID0gMDsKCgkJaWYgKGxzdGF0KF9QQVRIX01PVU5URUQsICZtdGFiX3N0YXQpKQoJCQl2YXJfbXRhYl9kb2VzX25vdF9leGlzdCA9IDE7CgkJZWxzZSBpZiAoU19JU0xOSyhtdGFiX3N0YXQuc3RfbW9kZSkpCgkJCXZhcl9tdGFiX2lzX2Ffc3ltbGluayA9IDE7CgkJaGF2ZV9tdGFiX2luZm8gPSAxOwoJfQp9Cgp2b2lkCnJlc2V0X210YWJfaW5mbyh2b2lkKSB7CiAgICAgICAgaGF2ZV9tdGFiX2luZm8gPSAwOwp9CgppbnQKbXRhYl9kb2VzX25vdF9leGlzdCh2b2lkKSB7CglnZXRfbXRhYl9pbmZvKCk7CglyZXR1cm4gdmFyX210YWJfZG9lc19ub3RfZXhpc3Q7Cn0KCmludAptdGFiX2lzX2Ffc3ltbGluayh2b2lkKSB7CglnZXRfbXRhYl9pbmZvKCk7CglyZXR1cm4gdmFyX210YWJfaXNfYV9zeW1saW5rOwp9CgppbnQKbXRhYl9pc193cml0YWJsZSgpIHsKCWludCBmZDsKCgkvKiBTaG91bGQgd2Ugd3JpdGUgdG8gL2V0Yy9tdGFiIHVwb24gYW4gdXBkYXRlPwoJICAgUHJvYmFibHkgbm90IGlmIGl0IGlzIGEgc3ltbGluayB0byAvcHJvYy9tb3VudHMsIHNpbmNlIHRoYXQKCSAgIHdvdWxkIGNyZWF0ZSBhIGZpbGUgL3Byb2MvbW91bnRzIGluIGNhc2UgdGhlIHByb2MgZmlsZXN5c3RlbQoJICAgaXMgbm90IG1vdW50ZWQuICovCglpZiAobXRhYl9pc19hX3N5bWxpbmsoKSkKCQlyZXR1cm4gMDsKCglmZCA9IG9wZW4oX1BBVEhfTU9VTlRFRCwgT19SRFdSIHwgT19DUkVBVCwgMDY0NCk7CglpZiAoZmQgPj0gMCkgewoJCWNsb3NlKGZkKTsKCQlyZXR1cm4gMTsKCX0gZWxzZQoJCXJldHVybiAwOwp9CgovKiBDb250ZW50cyBvZiBtdGFiIGFuZCBmc3RhYiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKc3RydWN0IG1udGVudGNobiBtb3VudHRhYmxlLCBmc3RhYjsKc3RhdGljIGludCBnb3RfbXRhYiA9IDA7CnN0YXRpYyBpbnQgZ290X2ZzdGFiID0gMDsKCnN0YXRpYyB2b2lkIHJlYWRfbW91bnR0YWJsZSh2b2lkKSwgcmVhZF9mc3RhYih2b2lkKTsKCnN0cnVjdCBtbnRlbnRjaG4gKgptdGFiX2hlYWQoKSB7CglpZiAoIWdvdF9tdGFiKQoJCXJlYWRfbW91bnR0YWJsZSgpOwoJcmV0dXJuICZtb3VudHRhYmxlOwp9CgpzdHJ1Y3QgbW50ZW50Y2huICoKZnN0YWJfaGVhZCgpIHsKCWlmICghZ290X2ZzdGFiKQoJCXJlYWRfZnN0YWIoKTsKCXJldHVybiAmZnN0YWI7Cn0KCnN0YXRpYyB2b2lkCm15X2ZyZWVfbWMoc3RydWN0IG1udGVudGNobiAqbWMpIHsKCWlmIChtYykgewoJCW15X2ZyZWUobWMtPm0ubW50X2ZzbmFtZSk7CgkJbXlfZnJlZShtYy0+bS5tbnRfZGlyKTsKCQlteV9mcmVlKG1jLT5tLm1udF90eXBlKTsKCQlteV9mcmVlKG1jLT5tLm1udF9vcHRzKTsKCQlmcmVlKG1jKTsKCX0KfQoKCnN0YXRpYyB2b2lkCmRpc2NhcmRfbW50ZW50Y2huKHN0cnVjdCBtbnRlbnRjaG4gKm1jMCkgewoJc3RydWN0IG1udGVudGNobiAqbWMsICptYzE7CgoJZm9yIChtYyA9IG1jMC0+bnh0OyBtYyAmJiBtYyAhPSBtYzA7IG1jID0gbWMxKSB7CgkJbWMxID0gbWMtPm54dDsKCQlteV9mcmVlX21jKG1jKTsKCX0KfQoKc3RhdGljIHZvaWQKcmVhZF9tbnRlbnRjaG4obW50RklMRSAqbWZwLCBjb25zdCBjaGFyICpmbmFtLCBzdHJ1Y3QgbW50ZW50Y2huICptYzApIHsKCXN0cnVjdCBtbnRlbnRjaG4gKm1jID0gbWMwOwoJc3RydWN0IG15X21udGVudCAqbW50OwoKCXdoaWxlICgobW50ID0gbXlfZ2V0bW50ZW50KG1mcCkpICE9IE5VTEwpIHsKCQlpZiAoIXN0cmVxKG1udC0+bW50X3R5cGUsIE1OVFRZUEVfSUdOT1JFKSkgewoJCQltYy0+bnh0ID0gKHN0cnVjdCBtbnRlbnRjaG4gKikgeG1hbGxvYyhzaXplb2YoKm1jKSk7CgkJCW1jLT5ueHQtPnByZXYgPSBtYzsKCQkJbWMgPSBtYy0+bnh0OwoJCQltYy0+bSA9ICptbnQ7CgkJCW1jLT5ueHQgPSBtYzA7CgkJfQoJfQoJbWMwLT5wcmV2ID0gbWM7CglpZiAoZmVycm9yKG1mcC0+bW50ZW50X2ZwKSkgewoJCWludCBlcnJzdiA9IGVycm5vOwoJCWVycm9yKF8oIndhcm5pbmc6IGVycm9yIHJlYWRpbmcgJXM6ICVzIiksCgkJICAgICAgZm5hbSwgc3RyZXJyb3IgKGVycnN2KSk7CgkJbWMwLT5ueHQgPSBtYzAtPnByZXYgPSBOVUxMOwoJfQoJbXlfZW5kbW50ZW50KG1mcCk7Cn0KCi8qCiAqIFJlYWQgL2V0Yy9tdGFiLiAgSWYgdGhhdCBmYWlscywgdHJ5IC9wcm9jL21vdW50cy4KICogVGhpcyBwcm9kdWNlcyBhIGxpbmtlZCBsaXN0LiBUaGUgbGlzdCBoZWFkIG1vdW50dGFibGUgaXMgYSBkdW1teS4KICogUmV0dXJuIDAgb24gc3VjY2Vzcy4KICovCnN0YXRpYyB2b2lkCnJlYWRfbW91bnR0YWJsZSgpIHsKCW1udEZJTEUgKm1mcDsKCWNvbnN0IGNoYXIgKmZuYW07CglzdHJ1Y3QgbW50ZW50Y2huICptYyA9ICZtb3VudHRhYmxlOwoKCWdvdF9tdGFiID0gMTsKCW1jLT5ueHQgPSBtYy0+cHJldiA9IE5VTEw7CgoJZm5hbSA9IF9QQVRIX01PVU5URUQ7CgltZnAgPSBteV9zZXRtbnRlbnQgKGZuYW0sICJyIik7CglpZiAobWZwID09IE5VTEwgfHwgbWZwLT5tbnRlbnRfZnAgPT0gTlVMTCkgewoJCWludCBlcnJzdiA9IGVycm5vOwoJCWZuYW0gPSBfUEFUSF9QUk9DX01PVU5UUzsKCQltZnAgPSBteV9zZXRtbnRlbnQgKGZuYW0sICJyIik7CgkJaWYgKG1mcCA9PSBOVUxMIHx8IG1mcC0+bW50ZW50X2ZwID09IE5VTEwpIHsKCQkJZXJyb3IoXygid2FybmluZzogY2FuJ3Qgb3BlbiAlczogJXMiKSwKCQkJICAgICAgX1BBVEhfTU9VTlRFRCwgc3RyZXJyb3IgKGVycnN2KSk7CgkJCXJldHVybjsKCQl9CgkJaWYgKHZlcmJvc2UpCgkJCXByaW50ZiAoXygibW91bnQ6IGNvdWxkIG5vdCBvcGVuICVzIC0gIgoJCQkJICAidXNpbmcgJXMgaW5zdGVhZFxuIiksCgkJCQlfUEFUSF9NT1VOVEVELCBfUEFUSF9QUk9DX01PVU5UUyk7Cgl9CglyZWFkX21udGVudGNobihtZnAsIGZuYW0sIG1jKTsKfQoKc3RhdGljIHZvaWQKcmVhZF9mc3RhYigpIHsKCW1udEZJTEUgKm1mcCA9IE5VTEw7Cgljb25zdCBjaGFyICpmbmFtOwoJc3RydWN0IG1udGVudGNobiAqbWMgPSAmZnN0YWI7CgoJZ290X2ZzdGFiID0gMTsKCW1jLT5ueHQgPSBtYy0+cHJldiA9IE5VTEw7CgoJZm5hbSA9IF9QQVRIX01OVFRBQjsKCW1mcCA9IG15X3NldG1udGVudCAoZm5hbSwgInIiKTsKCWlmIChtZnAgPT0gTlVMTCB8fCBtZnAtPm1udGVudF9mcCA9PSBOVUxMKSB7CgkJaW50IGVycnN2ID0gZXJybm87CgkJZXJyb3IoXygid2FybmluZzogY2FuJ3Qgb3BlbiAlczogJXMiKSwKCQkgICAgICBfUEFUSF9NTlRUQUIsIHN0cmVycm9yIChlcnJzdikpOwoJCXJldHVybjsKCX0KCXJlYWRfbW50ZW50Y2huKG1mcCwgZm5hbSwgbWMpOwp9CgoKLyogR2l2ZW4gdGhlIG5hbWUgTkFNRSwgdHJ5IHRvIGZpbmQgaXQgaW4gbXRhYi4gICovCnN0cnVjdCBtbnRlbnRjaG4gKgpnZXRtbnRmaWxlIChjb25zdCBjaGFyICpuYW1lKSB7CglzdHJ1Y3QgbW50ZW50Y2huICptYywgKm1jMDsKCgltYzAgPSBtdGFiX2hlYWQoKTsKCWZvciAobWMgPSBtYzAtPm54dDsgbWMgJiYgbWMgIT0gbWMwOyBtYyA9IG1jLT5ueHQpCgkJaWYgKHN0cmVxKG1jLT5tLm1udF9kaXIsIG5hbWUpIHx8CgkJICAgIHN0cmVxKG1jLT5tLm1udF9mc25hbWUsIG5hbWUpKQoJCQlyZXR1cm4gbWM7CglyZXR1cm4gTlVMTDsKfQoKLyoKICogR2l2ZW4gdGhlIGRpcmVjdG9yeSBuYW1lIE5BTUUsIGFuZCB0aGUgcGxhY2UgTUNQUkVWIHdlIGZvdW5kIGl0IGxhc3QgdGltZSwKICogdHJ5IHRvIGZpbmQgbW9yZSBvY2N1cnJlbmNlcy4KICovCnN0cnVjdCBtbnRlbnRjaG4gKgpnZXRtbnRkaXJiYWNrd2FyZCAoY29uc3QgY2hhciAqbmFtZSwgc3RydWN0IG1udGVudGNobiAqbWNwcmV2KSB7CglzdHJ1Y3QgbW50ZW50Y2huICptYywgKm1jMDsKCgltYzAgPSBtdGFiX2hlYWQoKTsKCWlmICghbWNwcmV2KQoJCW1jcHJldiA9IG1jMDsKCWZvciAobWMgPSBtY3ByZXYtPnByZXY7IG1jICYmIG1jICE9IG1jMDsgbWMgPSBtYy0+cHJldikKCQlpZiAoc3RyZXEobWMtPm0ubW50X2RpciwgbmFtZSkpCgkJCXJldHVybiBtYzsKCXJldHVybiBOVUxMOwp9CgovKgogKiBHaXZlbiB0aGUgZGV2aWNlIG5hbWUgTkFNRSwgYW5kIHRoZSBwbGFjZSBNQ1BSRVYgd2UgZm91bmQgaXQgbGFzdCB0aW1lLAogKiB0cnkgdG8gZmluZCBtb3JlIG9jY3VycmVuY2VzLgogKi8Kc3RydWN0IG1udGVudGNobiAqCmdldG1udGRldmJhY2t3YXJkIChjb25zdCBjaGFyICpuYW1lLCBzdHJ1Y3QgbW50ZW50Y2huICptY3ByZXYpIHsKCXN0cnVjdCBtbnRlbnRjaG4gKm1jLCAqbWMwOwoKCW1jMCA9IG10YWJfaGVhZCgpOwoJaWYgKCFtY3ByZXYpCgkJbWNwcmV2ID0gbWMwOwoJZm9yIChtYyA9IG1jcHJldi0+cHJldjsgbWMgJiYgbWMgIT0gbWMwOyBtYyA9IG1jLT5wcmV2KQoJCWlmIChzdHJlcShtYy0+bS5tbnRfZnNuYW1lLCBuYW1lKSkKCQkJcmV0dXJuIG1jOwoJcmV0dXJuIE5VTEw7Cn0KCi8qCiAqIEdpdmVuIHRoZSBuYW1lIE5BTUUsIGNoZWNrIHRoYXQgaXQgb2NjdXJzIHByZWNpc2VseSBvbmNlIGFzIGRpciBvciBkZXYuCiAqLwppbnQKaXNfbW91bnRlZF9vbmNlKGNvbnN0IGNoYXIgKm5hbWUpIHsKCXN0cnVjdCBtbnRlbnRjaG4gKm1jLCAqbWMwOwoJaW50IGN0ID0gMDsKCgltYzAgPSBtdGFiX2hlYWQoKTsKCWZvciAobWMgPSBtYzAtPnByZXY7IG1jICYmIG1jICE9IG1jMDsgbWMgPSBtYy0+cHJldikKCQlpZiAoc3RyZXEobWMtPm0ubW50X2RpciwgbmFtZSkgfHwKCQkgICAgc3RyZXEobWMtPm0ubW50X2ZzbmFtZSwgbmFtZSkpCgkJCWN0Kys7CglyZXR1cm4gKGN0ID09IDEpOwp9CgovKiBHaXZlbiB0aGUgbmFtZSBGSUxFLCB0cnkgdG8gZmluZCB0aGUgb3B0aW9uICJsb29wPUZJTEUiIGluIG10YWIuICAqLyAKc3RydWN0IG1udGVudGNobiAqCmdldG1udG9wdGZpbGUgKGNvbnN0IGNoYXIgKmZpbGUpIHsKCXN0cnVjdCBtbnRlbnRjaG4gKm1jLCAqbWMwOwoJY29uc3QgY2hhciAqb3B0cywgKnM7CglpbnQgbDsKCglpZiAoIWZpbGUpCgkJcmV0dXJuIE5VTEw7CgoJbCA9IHN0cmxlbihmaWxlKTsKCgltYzAgPSBtdGFiX2hlYWQoKTsKCWZvciAobWMgPSBtYzAtPm54dDsgbWMgJiYgbWMgIT0gbWMwOyBtYyA9IG1jLT5ueHQpCgkJaWYgKChvcHRzID0gbWMtPm0ubW50X29wdHMpICE9IE5VTEwKCQkgICAgJiYgKHMgPSBzdHJzdHIob3B0cywgImxvb3A9IikpCgkJICAgICYmICFzdHJuY21wKHMrNSwgZmlsZSwgbCkKCQkgICAgJiYgKHMgPT0gb3B0cyB8fCBzWy0xXSA9PSAnLCcpCgkJICAgICYmIChzW2wrNV0gPT0gMCB8fCBzW2wrNV0gPT0gJywnKSkKCQkJcmV0dXJuIG1jOwoJcmV0dXJuIE5VTEw7Cn0KCi8qIGNvbXBhcmVzICJxdW90ZWQiIG9yICdxdW90ZWQnIHdpdGggdW5xdW90ZWQgKi8Kc3RhdGljIGludApzdHJlcV9xdW90ZWQoY29uc3QgY2hhciAqcXVvdGVkLCBjb25zdCBjaGFyICp1bnF1b3RlZCkKewoJaWYgKCpxdW90ZWQgPT0gJyInIHx8ICpxdW90ZWQgPT0gJ1wnJykKCQlyZXR1cm4gIXN0cm5jbXAocXVvdGVkICsgMSwgdW5xdW90ZWQsIHN0cmxlbihxdW90ZWQpIC0gMik7CgoJcmV0dXJuIHN0cmVxKHF1b3RlZCwgdW5xdW90ZWQpOwp9CgpzdGF0aWMgaW50Cmhhc19sYWJlbChjb25zdCBjaGFyICpkZXZpY2UsIGNvbnN0IGNoYXIgKmxhYmVsKSB7Cgljb25zdCBjaGFyICpkZXZsYWJlbDsKCWludCByZXQ7CgoJZGV2bGFiZWwgPSBmc3Byb2JlX2dldF9sYWJlbF9ieV9kZXZuYW1lKGRldmljZSk7CglpZiAoIWRldmxhYmVsKQoJCXJldHVybiAwOwoKCXJldCA9IHN0cmVxX3F1b3RlZChsYWJlbCwgZGV2bGFiZWwpOwoJbXlfZnJlZShkZXZsYWJlbCk7CglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgaW50Cmhhc191dWlkKGNvbnN0IGNoYXIgKmRldmljZSwgY29uc3QgY2hhciAqdXVpZCl7Cgljb25zdCBjaGFyICpkZXZ1dWlkOwoJaW50IHJldDsKCglkZXZ1dWlkID0gZnNwcm9iZV9nZXRfdXVpZF9ieV9kZXZuYW1lKGRldmljZSk7CglpZiAoIWRldnV1aWQpCgkJcmV0dXJuIDA7CgoJcmV0ID0gc3RyZXFfcXVvdGVkKHV1aWQsIGRldnV1aWQpOwoJbXlfZnJlZShkZXZ1dWlkKTsKCXJldHVybiByZXQ7Cn0KCi8qIEZpbmQgdGhlIGVudHJ5IChERVYsRElSKSBpbiBmc3RhYiAtLSBzcGVjIGFuZCBkaXIgbXVzdCBiZSBjYW5vbmljYWxpemVkISAqLwpzdHJ1Y3QgbW50ZW50Y2huICoKZ2V0ZnNfYnlfZGV2ZGlyIChjb25zdCBjaGFyICpkZXYsIGNvbnN0IGNoYXIgKmRpcikgewoJc3RydWN0IG1udGVudGNobiAqbWMsICptYzA7CgoJbWMwID0gZnN0YWJfaGVhZCgpOwoKCWZvciAobWMgPSBtYzAtPm54dDsgbWMgJiYgbWMgIT0gbWMwOyBtYyA9IG1jLT5ueHQpIHsKCQlpbnQgb2sgPSAxOwoKCQkvKiBkaXIgKi8KCQlpZiAoIXN0cmVxKG1jLT5tLm1udF9kaXIsIGRpcikpIHsKCQkJY2hhciAqZHIgPSBjYW5vbmljYWxpemUobWMtPm0ubW50X2Rpcik7CgkJCW9rID0gc3RyZXEoZHIsIGRpcik7CgkJCW15X2ZyZWUoZHIpOwoJCX0KCgkJLyogc3BlYyAqLwoJCWlmIChvayAmJiAhc3RyZXEobWMtPm0ubW50X2ZzbmFtZSwgZGV2KSkgewoJCQljb25zdCBjaGFyICpmcyA9IG1jLT5tLm1udF9mc25hbWU7CgoJCQlpZiAoc3RybmNtcCAoZnMsICJMQUJFTD0iLCA2KSA9PSAwKSB7CgkJCQlvayA9IGhhc19sYWJlbChkZXYsIGZzICsgNik7CgkJCX0gZWxzZSBpZiAoc3RybmNtcCAoZnMsICJVVUlEPSIsIDUpID09IDApIHsKCQkJCW9rID0gaGFzX3V1aWQoZGV2LCBmcyArIDUpOwoJCQl9IGVsc2UgewoJCQkJZnMgPSBjYW5vbmljYWxpemVfc3BlYyhtYy0+bS5tbnRfZnNuYW1lKTsKCQkJCW9rID0gc3RyZXEoZnMsIGRldik7CgkJCQlteV9mcmVlKGZzKTsKCQkJfQoJCX0KCQlpZiAob2spCgkJCXJldHVybiBtYzsKCX0KCglyZXR1cm4gTlVMTDsKfQoKLyogRmluZCB0aGUgZGlyIERJUiBpbiBmc3RhYi4gICovCnN0cnVjdCBtbnRlbnRjaG4gKgpnZXRmc19ieV9kaXIgKGNvbnN0IGNoYXIgKmRpcikgewoJc3RydWN0IG1udGVudGNobiAqbWMsICptYzA7CgljaGFyICpjZGlyOwoKCW1jMCA9IGZzdGFiX2hlYWQoKTsKCWZvciAobWMgPSBtYzAtPm54dDsgbWMgJiYgbWMgIT0gbWMwOyBtYyA9IG1jLT5ueHQpCgkJaWYgKHN0cmVxKG1jLT5tLm1udF9kaXIsIGRpcikpCgkJCXJldHVybiBtYzsKCgljZGlyID0gY2Fub25pY2FsaXplKGRpcik7Cglmb3IgKG1jID0gbWMwLT5ueHQ7IG1jICYmIG1jICE9IG1jMDsgbWMgPSBtYy0+bnh0KSB7CgkJaWYgKHN0cmVxKG1jLT5tLm1udF9kaXIsIGNkaXIpKSB7CgkJCWZyZWUoY2Rpcik7CgkJCXJldHVybiBtYzsKCQl9Cgl9CglmcmVlKGNkaXIpOwoJcmV0dXJuIE5VTEw7Cn0KCi8qIEZpbmQgdGhlIGRldmljZSBTUEVDIGluIGZzdGFiLiAgKi8Kc3RydWN0IG1udGVudGNobiAqCmdldGZzX2J5X3NwZWMgKGNvbnN0IGNoYXIgKnNwZWMpIHsKCWNoYXIgKm5hbWUgPSBOVUxMLCAqdmFsdWUgPSBOVUxMLCAqY3NwZWM7CglzdHJ1Y3QgbW50ZW50Y2huICptYyA9IE5VTEw7CgoJaWYgKCFzcGVjKQoJCXJldHVybiBOVUxMOwoKCWlmIChmc3Byb2JlX3BhcnNlX3NwZWMoc3BlYywgJm5hbWUsICZ2YWx1ZSkgIT0gMCkKCQlyZXR1cm4gTlVMTDsJCQkJLyogcGFyc2UgZXJyb3IgKi8KCglpZiAobmFtZSkgewoJCWlmICghc3RyY21wKG5hbWUsIkxBQkVMIikpCgkJCW1jID0gZ2V0ZnNfYnlfbGFiZWwgKHZhbHVlKTsKCQllbHNlIGlmICghc3RyY21wKG5hbWUsIlVVSUQiKSkKCQkJbWMgPSBnZXRmc19ieV91dWlkICh2YWx1ZSk7CgoJCWZyZWUobmFtZSk7CgkJZnJlZSh2YWx1ZSk7CgkJcmV0dXJuIG1jOwoJfQoKCWNzcGVjID0gY2Fub25pY2FsaXplX3NwZWMoc3BlYyk7CgltYyA9IGdldGZzX2J5X2Rldm5hbWUoY3NwZWMpOwoJZnJlZShjc3BlYyk7CgoJaWYgKCFtYykKCQkvKiBub25jYW5vbmljYWwgbmFtZSAgbGlrZSAvZGV2L2Nkcm9tICovCgkJbWMgPSBnZXRmc19ieV9kZXZuYW1lKHNwZWMpOwoKCXJldHVybiBtYzsKfQoKLyogRmluZCB0aGUgZGV2aWNlIGluIGZzdGFiLiAgKi8Kc3RydWN0IG1udGVudGNobiAqCmdldGZzX2J5X2Rldm5hbWUgKGNvbnN0IGNoYXIgKmRldm5hbWUpIHsKCXN0cnVjdCBtbnRlbnRjaG4gKm1jLCAqbWMwOwoKCW1jMCA9IGZzdGFiX2hlYWQoKTsKCgkvKiBjYW5vbmljYWwgZGV2bmFtZSBpbiBmc3RhYiAqLwoJZm9yIChtYyA9IG1jMC0+bnh0OyBtYyAmJiBtYyAhPSBtYzA7IG1jID0gbWMtPm54dCkKCQlpZiAoc3RyZXEobWMtPm0ubW50X2ZzbmFtZSwgZGV2bmFtZSkpCgkJCXJldHVybiBtYzsKCgkvKiBub25jYW5vbmljYWwgZGV2bmFtZSBpbiBmc3RhYiAqLwoJZm9yIChtYyA9IG1jMC0+bnh0OyBtYyAmJiBtYyAhPSBtYzA7IG1jID0gbWMtPm54dCkgewoJCWNoYXIgKmZzOwoKCQlpZiAoc3RybmNtcChtYy0+bS5tbnRfZnNuYW1lLCAiTEFCRUw9IiwgNikgPT0gMCB8fAoJCQkJc3RybmNtcChtYy0+bS5tbnRfZnNuYW1lLCAiVVVJRD0iLCA1KSA9PSAwKQoJCQljb250aW51ZTsKCgkJZnMgPSBjYW5vbmljYWxpemVfc3BlYyhtYy0+bS5tbnRfZnNuYW1lKTsKCQlpZiAoc3RyZXEoZnMsIGRldm5hbWUpKSB7CgkJCWZyZWUoZnMpOwoJCQlyZXR1cm4gbWM7CgkJfQoJCWZyZWUoZnMpOwoJfQoKCXJldHVybiBOVUxMOwp9CgoKLyogRmluZCB0aGUgdXVpZCBVVUlEIGluIGZzdGFiLiAqLwpzdHJ1Y3QgbW50ZW50Y2huICoKZ2V0ZnNfYnlfdXVpZCAoY29uc3QgY2hhciAqdXVpZCkgewoJc3RydWN0IG1udGVudGNobiAqbWMsICptYzA7CgoJbWMwID0gZnN0YWJfaGVhZCgpOwoJZm9yIChtYyA9IG1jMC0+bnh0OyBtYyAmJiBtYyAhPSBtYzA7IG1jID0gbWMtPm54dCkKCQlpZiAoc3RybmNtcCAobWMtPm0ubW50X2ZzbmFtZSwgIlVVSUQ9IiwgNSkgPT0gMAoJCSAgICAmJiBzdHJlcV9xdW90ZWQobWMtPm0ubW50X2ZzbmFtZSArIDUsIHV1aWQpKQoJCQlyZXR1cm4gbWM7CglyZXR1cm4gTlVMTDsKfQoKLyogRmluZCB0aGUgbGFiZWwgTEFCRUwgaW4gZnN0YWIuICovCnN0cnVjdCBtbnRlbnRjaG4gKgpnZXRmc19ieV9sYWJlbCAoY29uc3QgY2hhciAqbGFiZWwpIHsKCXN0cnVjdCBtbnRlbnRjaG4gKm1jLCAqbWMwOwoKCW1jMCA9IGZzdGFiX2hlYWQoKTsKCWZvciAobWMgPSBtYzAtPm54dDsgbWMgJiYgbWMgIT0gbWMwOyBtYyA9IG1jLT5ueHQpCgkJaWYgKHN0cm5jbXAgKG1jLT5tLm1udF9mc25hbWUsICJMQUJFTD0iLCA2KSA9PSAwCgkJICAgICYmIHN0cmVxX3F1b3RlZChtYy0+bS5tbnRfZnNuYW1lICsgNiwgbGFiZWwpKQoJCQlyZXR1cm4gbWM7CglyZXR1cm4gTlVMTDsKfQoKLyogVXBkYXRpbmcgbXRhYiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCi8qIEZsYWcgZm9yIGFscmVhZHkgZXhpc3RpbmcgbG9jayBmaWxlLiAqLwpzdGF0aWMgaW50IHdlX2NyZWF0ZWRfbG9ja2ZpbGUgPSAwOwpzdGF0aWMgaW50IGxvY2tmaWxlX2ZkID0gLTE7CgovKiBGbGFnIHRvIGluZGljYXRlIHRoYXQgc2lnbmFscyBoYXZlIGJlZW4gc2V0IHVwLiAqLwpzdGF0aWMgaW50IHNpZ25hbHNfaGF2ZV9iZWVuX3NldHVwID0gMDsKCi8qIEVuc3VyZSB0aGF0IHRoZSBsb2NrIGlzIHJlbGVhc2VkIGlmIHdlIGFyZSBpbnRlcnJ1cHRlZC4gICovCmV4dGVybiBjaGFyICpzdHJzaWduYWwoaW50IHNpZyk7CS8qIG5vdCBhbHdheXMgaW4gPHN0cmluZy5oPiAqLwoKc3RhdGljIHZvaWQKaGFuZGxlciAoaW50IHNpZykgewogICAgIGRpZShFWF9VU0VSLCAiJXMiLCBzdHJzaWduYWwoc2lnKSk7Cn0KCnN0YXRpYyB2b2lkCnNldGxrd190aW1lb3V0IChpbnQgc2lnKSB7CiAgICAgLyogbm90aGluZywgZmNudGwgd2lsbCBmYWlsIGFueXdheSAqLwp9CgovKiBSZW1vdmUgbG9jayBmaWxlLiAgKi8Kdm9pZAp1bmxvY2tfbXRhYiAodm9pZCkgewoJaWYgKHdlX2NyZWF0ZWRfbG9ja2ZpbGUpIHsKCQljbG9zZShsb2NrZmlsZV9mZCk7CgkJbG9ja2ZpbGVfZmQgPSAtMTsKCQl1bmxpbmsgKF9QQVRIX01PVU5URURfTE9DSyk7CgkJd2VfY3JlYXRlZF9sb2NrZmlsZSA9IDA7Cgl9Cn0KCi8qIENyZWF0ZSB0aGUgbG9jayBmaWxlLgogICBUaGUgbG9jayBmaWxlIHdpbGwgYmUgcmVtb3ZlZCBpZiB3ZSBjYXRjaCBhIHNpZ25hbCBvciB3aGVuIHdlIGV4aXQuICovCi8qIFRoZSBvbGQgY29kZSBoZXJlIHVzZWQgZmxvY2sgb24gYSBsb2NrIGZpbGUgL2V0Yy9tdGFifiBhbmQgZGVsZXRlZAogICB0aGlzIGxvY2sgZmlsZSBhZnRlcndhcmRzLiBIb3dldmVyLCBhcyByZ29vY2ggcmVtYXJrcywgdGhhdCBoYXMgYQogICByYWNlOiBhIHNlY29uZCBtb3VudCBtYXkgYmUgd2FpdGluZyBvbiB0aGUgbG9jayBhbmQgcHJvY2VlZCBhcwogICBzb29uIGFzIHRoZSBsb2NrIGZpbGUgaXMgZGVsZXRlZCBieSB0aGUgZmlyc3QgbW91bnQsIGFuZCBpbW1lZGlhdGVseQogICBhZnRlcndhcmRzIGEgdGhpcmQgbW91bnQgY29tZXMsIGNyZWF0ZXMgYSBuZXcgL2V0Yy9tdGFifiwgYXBwbGllcwogICBmbG9jayB0byB0aGF0LCBhbmQgYWxzbyBwcm9jZWVkcywgc28gdGhhdCB0aGUgc2Vjb25kIGFuZCB0aGlyZCBtb3VudAogICBub3cgYm90aCBhcmUgc2NyaWJibGluZyBpbiAvZXRjL210YWIuCiAgIFRoZSBuZXcgY29kZSB1c2VzIGEgbGluaygpIGluc3RlYWQgb2YgYSBjcmVhdCgpLCB3aGVyZSB3ZSBwcm9jZWVkCiAgIG9ubHkgaWYgaXQgd2FzIHVzIHRoYXQgY3JlYXRlZCB0aGUgbG9jaywgYW5kIGhlbmNlIHdlIGFsd2F5cyBoYXZlCiAgIHRvIGRlbGV0ZSB0aGUgbG9jayBhZnRlcndhcmRzLiBOb3cgdGhlIHVzZSBvZiBmbG9jaygpIGlzIGluIHByaW5jaXBsZQogICBzdXBlcmZsdW91cywgYnV0IGF2b2lkcyBhbiBhcmJpdHJhcnkgc2xlZXAoKS4gKi8KCi8qIFdoZXJlIGRvZXMgdGhlIGxpbmsgcG9pbnQgdG8/IE9idmlvdXMgY2hvaWNlcyBhcmUgbXRhYiBhbmQgbXRhYn5+LgogICBISkx1IHBvaW50cyBvdXQgdGhhdCB0aGUgbGF0dGVyIGxlYWRzIHRvIHJhY2VzLiBSaWdodCBub3cgd2UgdXNlCiAgIG10YWJ+LjxwaWQ+IGluc3RlYWQuIFVzZSAyMCBhcyB1cHBlciBib3VuZCBmb3IgdGhlIGxlbmd0aCBvZiAlZC4gKi8KI2RlZmluZSBNT1VOVExPQ0tfTElOS1RBUkdFVAkJX1BBVEhfTU9VTlRFRF9MT0NLICIlZCIKI2RlZmluZSBNT1VOVExPQ0tfTElOS1RBUkdFVF9MVEgJKHNpemVvZihfUEFUSF9NT1VOVEVEX0xPQ0spKzIwKQoKLyoKICogVGhlIG9yaWdpbmFsIG1vdW50IGxvY2tpbmcgY29kZSBoYXMgdXNlZCBzbGVlcCgxKSBiZXR3ZWVuIGF0dGVtcHRzIGFuZAogKiBtYXhpbWFsIG51bWJlciBvZiBhdHRlbXBzIGhhcyBiZWVuIDUuCiAqCiAqIFRoZXJlIHdhcyB2ZXJ5IHNtYWxsIG51bWJlciBvZiBhdHRlbXB0cyBhbmQgZXh0cmVtZWx5IGxvbmcgd2FpdGluZyAoMXMpCiAqIHRoYXQgaXMgdXNlbGVzcyBvbiBtYWNoaW5lcyB3aXRoIGxhcmdlIG51bWJlciBvZiBjb25jdXJyZXQgbW91bnQgcHJvY2Vzc2VzLgogKgogKiBOb3cgd2Ugd2FpdCBmZXcgdGhvdXNhbmQgbWljcm9zZWNvbmRzIGJldHdlZW4gYXR0ZW1wdHMgYW5kIHdlIGhhdmUgZ2xvYmFsCiAqIHRpbWUgbGltaXQgKDMwcykgcmF0aGVyIHRoYW4gbGltaXQgZm9yIG51bWJlciBvZiBhdHRlbXB0cy4gVGhlIGFkdmFudGFnZQogKiBpcyB0aGF0IHRoaXMgbWV0aG9kIGFsc28gY291bnRzIHRpbWUgd2hpY2ggd2Ugc3BlbmQgaW4gZmNudGwoRl9TRVRMS1cpIGFuZAogKiBudW1iZXIgb2YgYXR0ZW1wdHMgaXMgbm90IHNvIG11Y2ggcmVzdHJpY3RlZC4KICoKICogLS0ga3pha0ByZWRoYXQuY29tIFsyMDA3LU1hci0yMDA3XQogKi8KCi8qIG1heGltdW0gc2Vjb25kcyBiZXR3ZWVuIGZpcnN0IGFuZCBsYXN0IGF0dGVtcHQgKi8KI2RlZmluZSBNT1VOVExPQ0tfTUFYVElNRQkJMzAKCi8qIHNsZWVwIHRpbWUgKGluIG1pY3Jvc2Vjb25kcywgbWF4PTk5OTk5OSkgYmV0d2VlbiBhdHRlbXB0cyAqLwojZGVmaW5lIE1PVU5UTE9DS19XQUlUVElNRQkJNTAwMAoKdm9pZApsb2NrX210YWIgKHZvaWQpIHsKCWludCBpOwoJc3RydWN0IHRpbWVzcGVjIHdhaXR0aW1lOwoJc3RydWN0IHRpbWV2YWwgbWF4dGltZTsKCWNoYXIgbGlua3RhcmdldGZpbGVbTU9VTlRMT0NLX0xJTktUQVJHRVRfTFRIXTsKCglpZiAoIXNpZ25hbHNfaGF2ZV9iZWVuX3NldHVwKSB7CgkJaW50IHNpZyA9IDA7CgkJc3RydWN0IHNpZ2FjdGlvbiBzYTsKCgkJc2Euc2FfaGFuZGxlciA9IGhhbmRsZXI7CgkJc2Euc2FfZmxhZ3MgPSAwOwoJCXNpZ2ZpbGxzZXQgKCZzYS5zYV9tYXNrKTsKCgkJd2hpbGUgKHNpZ2lzbWVtYmVyICgmc2Euc2FfbWFzaywgKytzaWcpICE9IC0xCgkJICAgICAgICYmIHNpZyAhPSBTSUdDSExEKSB7CgkJCWlmIChzaWcgPT0gU0lHQUxSTSkKCQkJCXNhLnNhX2hhbmRsZXIgPSBzZXRsa3dfdGltZW91dDsKCQkJZWxzZQoJCQkJc2Euc2FfaGFuZGxlciA9IGhhbmRsZXI7CgkJCXNpZ2FjdGlvbiAoc2lnLCAmc2EsIChzdHJ1Y3Qgc2lnYWN0aW9uICopIDApOwoJCX0KCQlzaWduYWxzX2hhdmVfYmVlbl9zZXR1cCA9IDE7Cgl9CgoJc3ByaW50ZihsaW5rdGFyZ2V0ZmlsZSwgTU9VTlRMT0NLX0xJTktUQVJHRVQsIGdldHBpZCAoKSk7CgoJaSA9IG9wZW4gKGxpbmt0YXJnZXRmaWxlLCBPX1dST05MWXxPX0NSRUFULCBTX0lSVVNSfFNfSVdVU1IpOwoJaWYgKGkgPCAwKSB7CgkJaW50IGVycnN2ID0gZXJybm87CgkJLyogbGlua3RhcmdldGZpbGUgZG9lcyBub3QgZXhpc3QgKGFzIGEgZmlsZSkKCQkgICBhbmQgd2UgY2Fubm90IGNyZWF0ZSBpdC4gUmVhZC1vbmx5IGZpbGVzeXN0ZW0/CgkJICAgVG9vIG1hbnkgZmlsZXMgb3BlbiBpbiB0aGUgc3lzdGVtPwoJCSAgIEZpbGVzeXN0ZW0gZnVsbD8gKi8KCQlkaWUgKEVYX0ZJTEVJTywgXygiY2FuJ3QgY3JlYXRlIGxvY2sgZmlsZSAlczogJXMgIgoJCQkJCQkgICIodXNlIC1uIGZsYWcgdG8gb3ZlcnJpZGUpIiksCgkJCSBsaW5rdGFyZ2V0ZmlsZSwgc3RyZXJyb3IgKGVycnN2KSk7Cgl9CgljbG9zZShpKTsKCglnZXR0aW1lb2ZkYXkoJm1heHRpbWUsIE5VTEwpOwoJbWF4dGltZS50dl9zZWMgKz0gTU9VTlRMT0NLX01BWFRJTUU7CgoJd2FpdHRpbWUudHZfc2VjID0gMDsKCXdhaXR0aW1lLnR2X25zZWMgPSAoMTAwMCAqIE1PVU5UTE9DS19XQUlUVElNRSk7CgoJLyogUmVwZWF0IHVudGlsIGl0IHdhcyB1cyB3aG8gbWFkZSB0aGUgbGluayAqLwoJd2hpbGUgKCF3ZV9jcmVhdGVkX2xvY2tmaWxlKSB7CgkJc3RydWN0IHRpbWV2YWwgbm93OwoJCXN0cnVjdCBmbG9jayBmbG9jazsKCQlpbnQgZXJyc3YsIGo7CgoJCWogPSBsaW5rKGxpbmt0YXJnZXRmaWxlLCBfUEFUSF9NT1VOVEVEX0xPQ0spOwoJCWVycnN2ID0gZXJybm87CgoJCWlmIChqID09IDApCgkJCXdlX2NyZWF0ZWRfbG9ja2ZpbGUgPSAxOwoKCQlpZiAoaiA8IDAgJiYgZXJyc3YgIT0gRUVYSVNUKSB7CgkJCSh2b2lkKSB1bmxpbmsobGlua3RhcmdldGZpbGUpOwoJCQlkaWUgKEVYX0ZJTEVJTywgXygiY2FuJ3QgbGluayBsb2NrIGZpbGUgJXM6ICVzICIKCQkJICAgICAiKHVzZSAtbiBmbGFnIHRvIG92ZXJyaWRlKSIpLAoJCQkgICAgIF9QQVRIX01PVU5URURfTE9DSywgc3RyZXJyb3IgKGVycnN2KSk7CgkJfQoKCQlsb2NrZmlsZV9mZCA9IG9wZW4gKF9QQVRIX01PVU5URURfTE9DSywgT19XUk9OTFkpOwoKCQlpZiAobG9ja2ZpbGVfZmQgPCAwKSB7CgkJCS8qIFN0cmFuZ2UuLi4gTWF5YmUgdGhlIGZpbGUgd2FzIGp1c3QgZGVsZXRlZD8gKi8KCQkJaW50IGVycnN2ID0gZXJybm87CgkJCWdldHRpbWVvZmRheSgmbm93LCBOVUxMKTsKCQkJaWYgKGVycm5vID09IEVOT0VOVCAmJiBub3cudHZfc2VjIDwgbWF4dGltZS50dl9zZWMpIHsKCQkJCXdlX2NyZWF0ZWRfbG9ja2ZpbGUgPSAwOwoJCQkJY29udGludWU7CgkJCX0KCQkJKHZvaWQpIHVubGluayhsaW5rdGFyZ2V0ZmlsZSk7CgkJCWRpZSAoRVhfRklMRUlPLCBfKCJjYW4ndCBvcGVuIGxvY2sgZmlsZSAlczogJXMgIgoJCQkgICAgICIodXNlIC1uIGZsYWcgdG8gb3ZlcnJpZGUpIiksCgkJCSAgICAgX1BBVEhfTU9VTlRFRF9MT0NLLCBzdHJlcnJvciAoZXJyc3YpKTsKCQl9CgoJCWZsb2NrLmxfdHlwZSA9IEZfV1JMQ0s7CgkJZmxvY2subF93aGVuY2UgPSBTRUVLX1NFVDsKCQlmbG9jay5sX3N0YXJ0ID0gMDsKCQlmbG9jay5sX2xlbiA9IDA7CgoJCWlmIChqID09IDApIHsKCQkJLyogV2UgbWFkZSB0aGUgbGluay4gTm93IGNsYWltIHRoZSBsb2NrLiAqLwoJCQlpZiAoZmNudGwgKGxvY2tmaWxlX2ZkLCBGX1NFVExLLCAmZmxvY2spID09IC0xKSB7CgkJCQlpZiAodmVyYm9zZSkgewoJCQkJICAgIGludCBlcnJzdiA9IGVycm5vOwoJCQkJICAgIHByaW50ZihfKCJDYW4ndCBsb2NrIGxvY2sgZmlsZSAlczogJXNcbiIpLAoJCQkJCSAgIF9QQVRIX01PVU5URURfTE9DSywgc3RyZXJyb3IgKGVycnN2KSk7CgkJCQl9CgkJCQkvKiBwcm9jZWVkLCBzaW5jZSBpdCB3YXMgdXMgd2hvIGNyZWF0ZWQgdGhlIGxvY2tmaWxlIGFueXdheSAqLwoJCQl9CgkJCSh2b2lkKSB1bmxpbmsobGlua3RhcmdldGZpbGUpOwoJCX0gZWxzZSB7CgkJCS8qIFNvbWVvbmUgZWxzZSBtYWRlIHRoZSBsaW5rLiBXYWl0LiAqLwoJCQlnZXR0aW1lb2ZkYXkoJm5vdywgTlVMTCk7CgkJCWlmIChub3cudHZfc2VjIDwgbWF4dGltZS50dl9zZWMpIHsKCQkJCWFsYXJtKG1heHRpbWUudHZfc2VjIC0gbm93LnR2X3NlYyk7CgkJCQlpZiAoZmNudGwgKGxvY2tmaWxlX2ZkLCBGX1NFVExLVywgJmZsb2NrKSA9PSAtMSkgewoJCQkJCWludCBlcnJzdiA9IGVycm5vOwoJCQkJCSh2b2lkKSB1bmxpbmsobGlua3RhcmdldGZpbGUpOwoJCQkJCWRpZSAoRVhfRklMRUlPLCBfKCJjYW4ndCBsb2NrIGxvY2sgZmlsZSAlczogJXMiKSwKCQkJCQkgICAgIF9QQVRIX01PVU5URURfTE9DSywgKGVycm5vID09IEVJTlRSKSA/CgkJCQkJICAgICBfKCJ0aW1lZCBvdXQiKSA6IHN0cmVycm9yIChlcnJzdikpOwoJCQkJfQoJCQkJYWxhcm0oMCk7CgoJCQkJbmFub3NsZWVwKCZ3YWl0dGltZSwgTlVMTCk7CgkJCX0gZWxzZSB7CgkJCQkodm9pZCkgdW5saW5rKGxpbmt0YXJnZXRmaWxlKTsKCQkJCWRpZSAoRVhfRklMRUlPLCBfKCJDYW5ub3QgY3JlYXRlIGxpbmsgJXNcbiIKCQkJCQkJICAiUGVyaGFwcyB0aGVyZSBpcyBhIHN0YWxlIGxvY2sgZmlsZT9cbiIpLAoJCQkJCSBfUEFUSF9NT1VOVEVEX0xPQ0spOwoJCQl9CgkJCWNsb3NlKGxvY2tmaWxlX2ZkKTsKCQl9Cgl9Cn0KCnN0YXRpYyBjaGFyICoKZ2V0X29wdGlvbihjb25zdCBjaGFyICpvcHRuYW1lLCBjb25zdCBjaGFyICpzcmMsIHNpemVfdCAqbGVuKQp7CgljaGFyICpvcHQsICplbmQ7CglzaXplX3Qgc3o7CgoJaWYgKCFzcmMpCgkJcmV0dXJuIE5VTEw7CgoJb3B0ID0gc3Ryc3RyKHNyYywgb3B0bmFtZSk7CglpZiAoIW9wdCkKCQlyZXR1cm4gTlVMTDsKCgllbmQgPSBzdHJjaHIob3B0LCAnLCcpOwoJc3ogPSBlbmQgPyBlbmQgLSBvcHQgOiBzdHJsZW4ob3B0KTsKCglpZiAobGVuKQoJCSpsZW4gPSBzejsKCglpZiAoKG9wdCA9PSBzcmMgfHwgKihvcHQgLSAxKSA9PSAnLCcpICYmCgkgICAgKCoob3B0ICsgc3opID09ICdcMCcgfHwgKihvcHQgKyBzeikgPT0gJywnKSkKCQlyZXR1cm4gb3B0OwoKCXJldHVybiBOVUxMOwp9CgpzdGF0aWMgaW50CmNweV9vcHRpb24oY29uc3QgY2hhciAqb3B0bmFtZSwgY2hhciAqZGVzdCwgY29uc3QgY2hhciAqc3JjKQp7CgljaGFyICpvcHQ7CglzaXplX3Qgc3o7CgoJb3B0ID0gZ2V0X29wdGlvbihvcHRuYW1lLCBzcmMsICZzeik7CglpZiAoIW9wdCkKCQkvKiB0aGUgb3B0aW9uIGRvZXNuJ3QgZXhpc3QgKi8KCQlyZXR1cm4gMDsKCglpZiAoZ2V0X29wdGlvbihvcHRuYW1lLCBkZXN0LCBOVUxMKSkKCQkvKiB0aGUgb3B0aW9ucyBpcyBhbHJlYWR5IGluIGRlc3QgKi8KCQlyZXR1cm4gMDsKCglpZiAoKmRlc3QpIHsKCQlkZXN0ID0gZGVzdCArIHN0cmxlbihkZXN0KTsKCQkqZGVzdCsrID0gJywnOwkJLyogc2VwYXJhdG9yICovCgl9CgltZW1jcHkoZGVzdCwgb3B0LCBzeik7CS8qIGNvcHkgb3B0aW9uICovCgkqKGRlc3QgKyBzeikgPSAnXDAnOwkvKiB0ZXJtaW5hdG9yICovCgoJcmV0dXJuIDE7Cn0KCi8qIEdlbmVyYXRlcyAoYW5kIGFsbG9jYXRlcykgbmV3IG9wdGlvbnMgZm9yIHJlbW91bnQKICoKICogV2UgY2Fubm90IGJsaW5kbHkgcmVwbGFjZSB0aGUgb2xkIG9wdGlvbnMsIG90aGVyd2lzZSB3ZSB3aWxsIGxvc3Qgc29tZQogKiBpbnRlcm5hbGx5IGdlbmVyYXRlZCBzdHVmZiAoZS5nIGxvb3A9KS4KICovCnN0YXRpYyBjaGFyICoKbWtfcmVtb3VudF9vcHRzKGNvbnN0IGNoYXIgKm9sZCwgY29uc3QgY2hhciAqaW5zdGVhZCkKewoJY2hhciAqbmV3OwoJc2l6ZV90IHN6OwoKCWlmIChvbGQgPT0gTlVMTCAmJiBpbnN0ZWFkID09IE5VTEwpCgkJcmV0dXJuIE5VTEw7CglpZiAoIW9sZCkKCQlyZXR1cm4geHN0cmR1cChpbnN0ZWFkKTsKCgkvKiBtYXggc2l6ZSBvZiBuZXcgb3B0aW9ucyBpczoKCSAqIG9sZCArIG5ldyArICdcMCcgKyBzZXBhcmF0b3IgKGZvciBlYWNoIGNvcGllZCBvcHRpb24pCgkgKi8KCXN6ID0gc3RybGVuKG9sZCkgKyAoaW5zdGVhZCA/IHN0cmxlbihpbnN0ZWFkKSA6IDApICsgMjsKCW5ldyA9IHhtYWxsb2Moc3opOwoJaWYgKGluc3RlYWQgJiYgKmluc3RlYWQpCgkJc3RybmNweShuZXcsIGluc3RlYWQsIHN6KTsKCWVsc2UKCQkqbmV3ID0gJ1wwJzsKCgljcHlfb3B0aW9uKCJsb29wPSIsIG5ldywgb2xkKTsKCglyZXR1cm4gbmV3Owp9CgovKgogKiBVcGRhdGUgdGhlIG10YWIuCiAqICBVc2VkIGJ5IHVtb3VudCB3aXRoIG51bGwgSU5TVEVBRDogcmVtb3ZlIHRoZSBsYXN0IERJUiBlbnRyeS4KICogIFVzZWQgYnkgbW91bnQgdXBvbiBhIHJlbW91bnQ6IHVwZGF0ZSBvcHRpb24gcGFydCwKICogICBhbmQgY29tcGxhaW4gaWYgYSB3cm9uZyBkZXZpY2Ugb3IgdHlwZSB3YXMgZ2l2ZW4uCiAqICAgW05vdGUgdGhhdCBvZnRlbiBhIHJlbW91bnQgd2lsbCBiZSBhIHJ3IHJlbW91bnQgb2YgLwogKiAgICB3aGVyZSB0aGVyZSB3YXMgbm8gZW50cnkgYmVmb3JlLCBhbmQgd2UnbGwgaGF2ZSB0byBiZWxpZXZlCiAqICAgIHRoZSB2YWx1ZXMgZ2l2ZW4gaW4gSU5TVEVBRC5dCiAqLwoKdm9pZAp1cGRhdGVfbXRhYiAoY29uc3QgY2hhciAqZGlyLCBzdHJ1Y3QgbXlfbW50ZW50ICppbnN0ZWFkKSB7CgltbnRGSUxFICptZnAsICptZnRtcDsKCWNvbnN0IGNoYXIgKmZuYW0gPSBfUEFUSF9NT1VOVEVEOwoJc3RydWN0IG1udGVudGNobiBtdGFiaGVhZDsJLyogZHVtbXkgKi8KCXN0cnVjdCBtbnRlbnRjaG4gKm1jLCAqbWMwLCAqYWJzZW50ID0gTlVMTDsKCXN0cnVjdCBzdGF0IHNidWY7CglpbnQgZmQ7CgoJaWYgKG10YWJfZG9lc19ub3RfZXhpc3QoKSB8fCAhbXRhYl9pc193cml0YWJsZSgpKQoJCXJldHVybjsKCglsb2NrX210YWIoKTsKCgkvKiBoYXZpbmcgbG9ja2VkIG10YWIsIHJlYWQgaXQgYWdhaW4gKi8KCW1jMCA9IG1jID0gJm10YWJoZWFkOwoJbWMtPm54dCA9IG1jLT5wcmV2ID0gTlVMTDsKCgltZnAgPSBteV9zZXRtbnRlbnQoZm5hbSwgInIiKTsKCWlmIChtZnAgPT0gTlVMTCB8fCBtZnAtPm1udGVudF9mcCA9PSBOVUxMKSB7CgkJaW50IGVycnN2ID0gZXJybm87CgkJZXJyb3IgKF8oImNhbm5vdCBvcGVuICVzICglcykgLSBtdGFiIG5vdCB1cGRhdGVkIiksCgkJICAgICAgIGZuYW0sIHN0cmVycm9yIChlcnJzdikpOwoJCWdvdG8gbGVhdmU7Cgl9CgoJcmVhZF9tbnRlbnRjaG4obWZwLCBmbmFtLCBtYyk7CgoJLyogZmluZCBsYXN0IG9jY3VycmVuY2Ugb2YgZGlyICovCglmb3IgKG1jID0gbWMwLT5wcmV2OyBtYyAmJiBtYyAhPSBtYzA7IG1jID0gbWMtPnByZXYpCgkJaWYgKHN0cmVxKG1jLT5tLm1udF9kaXIsIGRpcikpCgkJCWJyZWFrOwoJaWYgKG1jICYmIG1jICE9IG1jMCkgewoJCWlmIChpbnN0ZWFkID09IE5VTEwpIHsKCQkJLyogQW4gdW1vdW50IC0gcmVtb3ZlIGVudHJ5ICovCgkJCWlmIChtYyAmJiBtYyAhPSBtYzApIHsKCQkJCW1jLT5wcmV2LT5ueHQgPSBtYy0+bnh0OwoJCQkJbWMtPm54dC0+cHJldiA9IG1jLT5wcmV2OwoJCQkJbXlfZnJlZV9tYyhtYyk7CgkJCX0KCQl9IGVsc2UgaWYgKCFzdHJjbXAobWMtPm0ubW50X2RpciwgaW5zdGVhZC0+bW50X2RpcikpIHsKCQkJLyogQSByZW1vdW50ICovCgkJCWNoYXIgKm9wdHMgPSBta19yZW1vdW50X29wdHMobWMtPm0ubW50X29wdHMsCgkJCQkJaW5zdGVhZC0+bW50X29wdHMpOwoJCQlteV9mcmVlKG1jLT5tLm1udF9vcHRzKTsKCQkJbWMtPm0ubW50X29wdHMgPSBvcHRzOwoJCX0gZWxzZSB7CgkJCS8qIEEgbW92ZSAqLwoJCQlteV9mcmVlKG1jLT5tLm1udF9kaXIpOwoJCQltYy0+bS5tbnRfZGlyID0geHN0cmR1cChpbnN0ZWFkLT5tbnRfZGlyKTsKCQl9Cgl9IGVsc2UgaWYgKGluc3RlYWQpIHsKCQkvKiBub3QgZm91bmQsIGFkZCBhIG5ldyBlbnRyeSAqLwoJCWFic2VudCA9IHhtYWxsb2Moc2l6ZW9mKCphYnNlbnQpKTsKCQlhYnNlbnQtPm0ubW50X2ZzbmFtZSA9IHhzdHJkdXAoaW5zdGVhZC0+bW50X2ZzbmFtZSk7CgkJYWJzZW50LT5tLm1udF9kaXIgPSB4c3RyZHVwKGluc3RlYWQtPm1udF9kaXIpOwoJCWFic2VudC0+bS5tbnRfdHlwZSA9IHhzdHJkdXAoaW5zdGVhZC0+bW50X3R5cGUpOwoJCWFic2VudC0+bS5tbnRfb3B0cyA9IHhzdHJkdXAoaW5zdGVhZC0+bW50X29wdHMpOwoJCWFic2VudC0+bS5tbnRfZnJlcSA9IGluc3RlYWQtPm1udF9mcmVxOwoJCWFic2VudC0+bS5tbnRfcGFzc25vID0gaW5zdGVhZC0+bW50X3Bhc3NubzsKCQlhYnNlbnQtPm54dCA9IG1jMDsKCQlpZiAobWMwLT5wcmV2ICE9IE5VTEwpIHsKCQkJYWJzZW50LT5wcmV2ID0gbWMwLT5wcmV2OwoJCQltYzAtPnByZXYtPm54dCA9IGFic2VudDsKCQl9IGVsc2UgewoJCQlhYnNlbnQtPnByZXYgPSBtYzA7CgkJfQoJCW1jMC0+cHJldiA9IGFic2VudDsKCQlpZiAobWMwLT5ueHQgPT0gTlVMTCkKCQkJbWMwLT5ueHQgPSBhYnNlbnQ7Cgl9CgoJLyogd3JpdGUgY2hhaW4gdG8gbXRlbXAgKi8KCW1mdG1wID0gbXlfc2V0bW50ZW50IChfUEFUSF9NT1VOVEVEX1RNUCwgInciKTsKCWlmIChtZnRtcCA9PSBOVUxMIHx8IG1mdG1wLT5tbnRlbnRfZnAgPT0gTlVMTCkgewoJCWludCBlcnJzdiA9IGVycm5vOwoJCWVycm9yIChfKCJjYW5ub3Qgb3BlbiAlcyAoJXMpIC0gbXRhYiBub3QgdXBkYXRlZCIpLAoJCSAgICAgICBfUEFUSF9NT1VOVEVEX1RNUCwgc3RyZXJyb3IgKGVycnN2KSk7CgkJZGlzY2FyZF9tbnRlbnRjaG4obWMwKTsKCQlnb3RvIGxlYXZlOwoJfQoKCWZvciAobWMgPSBtYzAtPm54dDsgbWMgJiYgbWMgIT0gbWMwOyBtYyA9IG1jLT5ueHQpIHsKCQlpZiAobXlfYWRkbW50ZW50KG1mdG1wLCAmKG1jLT5tKSkgPT0gMSkgewoJCQlpbnQgZXJyc3YgPSBlcnJubzsKCQkJZGllIChFWF9GSUxFSU8sIF8oImVycm9yIHdyaXRpbmcgJXM6ICVzIiksCgkJCSAgICAgX1BBVEhfTU9VTlRFRF9UTVAsIHN0cmVycm9yIChlcnJzdikpOwoJCX0KCX0KCglkaXNjYXJkX21udGVudGNobihtYzApOwoJZmQgPSBmaWxlbm8obWZ0bXAtPm1udGVudF9mcCk7CgoJLyoKCSAqIEl0IHNlZW1zIHRoYXQgYmV0dGVyIGlzIGluY29tcGxldGUgYW5kIGJyb2tlbiAvbW50L210YWIgdGhhdAoJICogL21udC9tdGFiIHRoYXQgaXMgd3JpdGVhYmxlIGZvciBub24tcm9vdCB1c2Vycy4KCSAqCgkgKiBXZSBhbHdheXMgc2tpcCByZW5hbWUoKSB3aGVuIGNob3duKCkgYW5kIGNobW9kKCkgZmFpbGVkLgoJICogLS0ga3phaywgMTEtT2N0LTIwMDcKCSAqLwoKCWlmIChmY2htb2QoZmQsIFNfSVJVU1J8U19JV1VTUnxTX0lSR1JQfFNfSVJPVEgpIDwgMCkgewoJCWludCBlcnJzdiA9IGVycm5vOwoJCWZwcmludGYoc3RkZXJyLCBfKCJlcnJvciBjaGFuZ2luZyBtb2RlIG9mICVzOiAlc1xuIiksCgkJCV9QQVRIX01PVU5URURfVE1QLCBzdHJlcnJvciAoZXJyc3YpKTsKCQlnb3RvIGxlYXZlOwoJfQoKCS8qCgkgKiBJZiBtb3VudCBpcyBzZXR1aWQgYW5kIHNvbWUgbm9uLXJvb3QgdXNlciBtb3VudHMgc3RoLAoJICogdGhlbiBtdGFiLnRtcCBtaWdodCBnZXQgdGhlIGdyb3VwIG9mIHRoaXMgdXNlci4gQ29weSB1aWQvZ2lkCgkgKiBmcm9tIHRoZSBwcmVzZW50IG10YWIgYmVmb3JlIHJlbmFtaW5nLgoJICovCglpZiAoc3RhdChfUEFUSF9NT1VOVEVELCAmc2J1ZikgPT0gMCkgewoJCWlmIChmY2hvd24oZmQsIHNidWYuc3RfdWlkLCBzYnVmLnN0X2dpZCkgPCAwKSB7CgkJCWludCBlcnJzdiA9IGVycm5vOwoJCQlmcHJpbnRmIChzdGRlcnIsIF8oImVycm9yIGNoYW5naW5nIG93bmVyIG9mICVzOiAlc1xuIiksCgkJCQlfUEFUSF9NT1VOVEVEX1RNUCwgc3RyZXJyb3IoZXJyc3YpKTsKCQkJZ290byBsZWF2ZTsKCQl9Cgl9CgoJbXlfZW5kbW50ZW50IChtZnRtcCk7CgoJLyogcmVuYW1lIG10ZW1wIHRvIG10YWIgKi8KCWlmIChyZW5hbWUgKF9QQVRIX01PVU5URURfVE1QLCBfUEFUSF9NT1VOVEVEKSA8IDApIHsKCQlpbnQgZXJyc3YgPSBlcnJubzsKCQlmcHJpbnRmKHN0ZGVyciwgXygiY2FuJ3QgcmVuYW1lICVzIHRvICVzOiAlc1xuIiksCgkJCV9QQVRIX01PVU5URURfVE1QLCBfUEFUSF9NT1VOVEVELCBzdHJlcnJvcihlcnJzdikpOwoJfQoKIGxlYXZlOgoJdW5sb2NrX210YWIoKTsKfQoKCiNpZmRlZiBNQUlOX1RFU1RfTVRBQkxPQ0sKCi8qCiAqIFRoaXMgaXMgbXRhYiBsb2NraW5nIGNvZGUgdGVzdCBmb3I6CiAqCiAqCS0gcGVyZm9ybWFuY2UgKGhvdyBtYW55IGNvbmN1cnJlbnQgcHJvY2Vzc2VzKQogKgogKgktIGxvY2sgcmVsaWFiaWxpdHkgKGlzIHBvc3NpYmxlIHRvIHNlZSBjb3JydXB0ZWQgZGF0YSAgaWYgbW9yZQogKgkgICAgICAgICAgICAgICAgICAgIGNvbmN1cnJlbnQgcHJvY2Vzc2VzIG1vZGlmeSBhIHNhbWUgZmlsZSkKICoKICogIFRoZSB0ZXN0IGlzIHZlcnkgc2ltcGxlIC0tIGl0IHJlYWRzIGEgbnVtYmVyIGZyb20gbG9ja2VkIGZpbGUsIGluY3JlbWVudHMgdGhlCiAqICBudW1iZXIgYW5kIHdyaXRlcyB0aGUgbnVtYmVyIGJhY2sgdG8gdGhlIGZpbGUuCiAqLwovKiBkdW1teSAqLwpjaGFyICpmc3Byb2JlX2dldF9sYWJlbF9ieV9kZXZuYW1lKGNvbnN0IGNoYXIgKnNwZWMpIHsgcmV0dXJuIE5VTEw7IH0KY2hhciAqZnNwcm9iZV9nZXRfdXVpZF9ieV9kZXZuYW1lKGNvbnN0IGNoYXIgKnNwZWMpIHsgcmV0dXJuIE5VTEw7IH0KaW50IGZzcHJvYmVfcGFyc2Vfc3BlYyhjb25zdCBjaGFyICpzcGVjLCBjaGFyICoqbmFtZSwgY2hhciAqKnZhbHVlKSB7IHJldHVybiAwOyB9CnN0cnVjdCBteV9tbnRlbnQgKm15X2dldG1udGVudCAobW50RklMRSAqbWZwKSB7IHJldHVybiBOVUxMOyB9Cm1udEZJTEUgKm15X3NldG1udGVudCAoY29uc3QgY2hhciAqZmlsZSwgY2hhciAqbW9kZSkgeyByZXR1cm4gTlVMTDsgfQp2b2lkIG15X2VuZG1udGVudCAobW50RklMRSAqbWZwKSB7IH0KaW50IG15X2FkZG1udGVudCAobW50RklMRSAqbWZwLCBzdHJ1Y3QgbXlfbW50ZW50ICptbnQpIHsgcmV0dXJuIDA7IH0KCmludAptYWluKGludCBhcmdjLCBjaGFyICoqYXJndikKewoJdGltZV90IHN5bmN0aW1lOwoJY2hhciAqZmlsZW5hbWU7CglpbnQgbmxvb3BzLCBpZCwgaTsKCXBpZF90IHBpZCA9IGdldHBpZCgpOwoJdW5zaWduZWQgaW50IHVzZWNzOwoJc3RydWN0IHRpbWV2YWwgdHY7CglzdHJ1Y3Qgc3RhdCBzdDsKCWxvbmcgbGFzdCA9IDA7CgoJcHJvZ25hbWUgPSBhcmd2WzBdOwoKCWlmIChhcmdjIDwgMykKCQlkaWUoRVhJVF9GQUlMVVJFLAoJCQkidXNhZ2U6ICVzIDxpZD4gPHN5bmN0aW1lPiA8ZmlsZT4gPG5sb29wcz5cbiIsCgkJCXByb2duYW1lKTsKCglpZCA9IGF0b2koYXJndlsxXSk7CglzeW5jdGltZSA9ICh0aW1lX3QpIGF0b2woYXJndlsyXSk7CglmaWxlbmFtZSA9IGFyZ3ZbM107CglubG9vcHMgPSBhdG9pKGFyZ3ZbNF0pOwoKCWlmIChzdGF0KGZpbGVuYW1lLCAmc3QpIDwgLTEpCgkJZGllKEVYSVRfRkFJTFVSRSwgIiVzOiAlc1xuIiwgZmlsZW5hbWUsIHN0cmVycm9yKGVycm5vKSk7CgoJZnByaW50ZihzdGRlcnIsICIlMDVkIChwaWQ9JTA1ZCk6IFNUQVJUXG4iLCBpZCwgcGlkKTsKCglnZXR0aW1lb2ZkYXkoJnR2LCBOVUxMKTsKCWlmIChzeW5jdGltZSAmJiBzeW5jdGltZSAtIHR2LnR2X3NlYyA+IDEpIHsKCQl1c2VjcyA9ICgoc3luY3RpbWUgLSB0di50dl9zZWMpICogMTAwMDAwMFVMKSAtCgkJCQkJKDEwMDAwMDBVTCAtIHR2LnR2X3VzZWMpOwoJCXVzbGVlcCh1c2Vjcyk7Cgl9CgoJZm9yIChpID0gMDsgaSA8IG5sb29wczsgaSsrKSB7CgkJRklMRSAqZjsKCQlsb25nIG51bTsKCQljaGFyIGJ1ZlsyNTZdOwoKCQlsb2NrX210YWIoKTsKCgkJaWYgKCEoZiA9IGZvcGVuKGZpbGVuYW1lLCAiciIpKSkgewoJCQl1bmxvY2tfbXRhYigpOwoJCQlkaWUoRVhJVF9GQUlMVVJFLCAiRVJST1I6ICVkIChwaWQ9JWQsIGxvb3A9JWQpOiAiCgkJCQkJIm9wZW4gZm9yIHJlYWQgZmFpbGVkXG4iLCBpZCwgcGlkLCBpKTsKCQl9CgkJaWYgKCFmZ2V0cyhidWYsIHNpemVvZihidWYpLCBmKSkgewoJCQl1bmxvY2tfbXRhYigpOwoJCQlkaWUoRVhJVF9GQUlMVVJFLCAiRVJST1I6ICVkIChwaWQ9JWQsIGxvb3A9JWQpOiAiCgkJCQkJInJlYWQgZmFpbGVkXG4iLCBpZCwgcGlkLCBpKTsKCQl9CgkJZmNsb3NlKGYpOwoKCQludW0gPSBhdG9sKGJ1ZikgKyAxOwoKCQlpZiAoIShmID0gZm9wZW4oZmlsZW5hbWUsICJ3IikpKSB7CgkJCXVubG9ja19tdGFiKCk7CgkJCWRpZShFWElUX0ZBSUxVUkUsICJFUlJPUjogJWQgKHBpZD0lZCwgbG9vcD0lZCk6ICIKCQkJCQkib3BlbiBmb3Igd3JpdGUgZmFpbGVkXG4iLCBpZCwgcGlkLCBpKTsKCQl9CgkJZnByaW50ZihmLCAiJWxkIiwgbnVtKTsKCQlmY2xvc2UoZik7CgoJCXVubG9ja19tdGFiKCk7CgoJCWdldHRpbWVvZmRheSgmdHYsIE5VTEwpOwoKCQlmcHJpbnRmKHN0ZGVyciwgIiUwMTBsZC4lMDZsZCAlMDRkIChwaWQ9JTA1ZCwgbG9vcD0lMDVkKTogIgoJCQkJIm51bT0lMDlsZCBsYXN0PSUwOWxkXG4iLAoJCQkJdHYudHZfc2VjLCB0di50dl91c2VjLCBpZCwKCQkJCXBpZCwgaSwgbnVtLCBsYXN0KTsKCQlsYXN0ID0gbnVtOwoKCQkvKiBUaGUgbW91bnQgY29tbWFuZCB1c3VhbGx5IGZpbmlzaCBhZnRlciBtdGFiIHVwZGF0ZS4gV2UKCQkgKiBzaW11bGF0ZSB0aGlzIHZpYSBzaG9ydCBzbGVlcCAtLSBpdCdzIGFsc28gZW5vdWdoIHRvIG1ha2UKCQkgKiBjb25jdXJyZW50IHByb2Nlc3NlcyBoYXBweS4KCQkgKi8KCQl1c2xlZXAoNTAwMDApOwoJfQoKCWZwcmludGYoc3RkZXJyLCAiJTA1ZCAocGlkPSUwNWQpOiBET05FXG4iLCBpZCwgcGlkKTsKCglleGl0KEVYSVRfU1VDQ0VTUyk7Cn0KI2VuZGlmCgo=