LyoKICogIGxpbnV4L2tlcm5lbC9zeXMuYwogKgogKiAgQ29weXJpZ2h0IChDKSAxOTkxLCAxOTkyICBMaW51cyBUb3J2YWxkcwogKi8KCiNpbmNsdWRlIDxsaW51eC9jb25maWcuaD4KI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvbW0uaD4KI2luY2x1ZGUgPGxpbnV4L3V0c25hbWUuaD4KI2luY2x1ZGUgPGxpbnV4L21tYW4uaD4KI2luY2x1ZGUgPGxpbnV4L3NtcF9sb2NrLmg+CiNpbmNsdWRlIDxsaW51eC9ub3RpZmllci5oPgojaW5jbHVkZSA8bGludXgvcmVib290Lmg+CiNpbmNsdWRlIDxsaW51eC9wcmN0bC5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvaGlnaHVpZC5oPgojaW5jbHVkZSA8bGludXgvZnMuaD4KI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgojaW5jbHVkZSA8bGludXgva2V4ZWMuaD4KI2luY2x1ZGUgPGxpbnV4L3dvcmtxdWV1ZS5oPgojaW5jbHVkZSA8bGludXgvY2FwYWJpbGl0eS5oPgojaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+CiNpbmNsdWRlIDxsaW51eC9rZXkuaD4KI2luY2x1ZGUgPGxpbnV4L3RpbWVzLmg+CiNpbmNsdWRlIDxsaW51eC9wb3NpeC10aW1lcnMuaD4KI2luY2x1ZGUgPGxpbnV4L3NlY3VyaXR5Lmg+CiNpbmNsdWRlIDxsaW51eC9kY29va2llcy5oPgojaW5jbHVkZSA8bGludXgvc3VzcGVuZC5oPgojaW5jbHVkZSA8bGludXgvdHR5Lmg+CiNpbmNsdWRlIDxsaW51eC9zaWduYWwuaD4KI2luY2x1ZGUgPGxpbnV4L2NuX3Byb2MuaD4KCiNpbmNsdWRlIDxsaW51eC9jb21wYXQuaD4KI2luY2x1ZGUgPGxpbnV4L3N5c2NhbGxzLmg+CiNpbmNsdWRlIDxsaW51eC9rcHJvYmVzLmg+CgojaW5jbHVkZSA8YXNtL3VhY2Nlc3MuaD4KI2luY2x1ZGUgPGFzbS9pby5oPgojaW5jbHVkZSA8YXNtL3VuaXN0ZC5oPgoKI2lmbmRlZiBTRVRfVU5BTElHTl9DVEwKIyBkZWZpbmUgU0VUX1VOQUxJR05fQ1RMKGEsYikJKC1FSU5WQUwpCiNlbmRpZgojaWZuZGVmIEdFVF9VTkFMSUdOX0NUTAojIGRlZmluZSBHRVRfVU5BTElHTl9DVEwoYSxiKQkoLUVJTlZBTCkKI2VuZGlmCiNpZm5kZWYgU0VUX0ZQRU1VX0NUTAojIGRlZmluZSBTRVRfRlBFTVVfQ1RMKGEsYikJKC1FSU5WQUwpCiNlbmRpZgojaWZuZGVmIEdFVF9GUEVNVV9DVEwKIyBkZWZpbmUgR0VUX0ZQRU1VX0NUTChhLGIpCSgtRUlOVkFMKQojZW5kaWYKI2lmbmRlZiBTRVRfRlBFWENfQ1RMCiMgZGVmaW5lIFNFVF9GUEVYQ19DVEwoYSxiKQkoLUVJTlZBTCkKI2VuZGlmCiNpZm5kZWYgR0VUX0ZQRVhDX0NUTAojIGRlZmluZSBHRVRfRlBFWENfQ1RMKGEsYikJKC1FSU5WQUwpCiNlbmRpZgoKLyoKICogdGhpcyBpcyB3aGVyZSB0aGUgc3lzdGVtLXdpZGUgb3ZlcmZsb3cgVUlEIGFuZCBHSUQgYXJlIGRlZmluZWQsIGZvcgogKiBhcmNoaXRlY3R1cmVzIHRoYXQgbm93IGhhdmUgMzItYml0IFVJRC9HSUQgYnV0IGRpZG4ndCBpbiB0aGUgcGFzdAogKi8KCmludCBvdmVyZmxvd3VpZCA9IERFRkFVTFRfT1ZFUkZMT1dVSUQ7CmludCBvdmVyZmxvd2dpZCA9IERFRkFVTFRfT1ZFUkZMT1dHSUQ7CgojaWZkZWYgQ09ORklHX1VJRDE2CkVYUE9SVF9TWU1CT0wob3ZlcmZsb3d1aWQpOwpFWFBPUlRfU1lNQk9MKG92ZXJmbG93Z2lkKTsKI2VuZGlmCgovKgogKiB0aGUgc2FtZSBhcyBhYm92ZSwgYnV0IGZvciBmaWxlc3lzdGVtcyB3aGljaCBjYW4gb25seSBzdG9yZSBhIDE2LWJpdAogKiBVSUQgYW5kIEdJRC4gYXMgc3VjaCwgdGhpcyBpcyBuZWVkZWQgb24gYWxsIGFyY2hpdGVjdHVyZXMKICovCgppbnQgZnNfb3ZlcmZsb3d1aWQgPSBERUZBVUxUX0ZTX09WRVJGTE9XVUlEOwppbnQgZnNfb3ZlcmZsb3dnaWQgPSBERUZBVUxUX0ZTX09WRVJGTE9XVUlEOwoKRVhQT1JUX1NZTUJPTChmc19vdmVyZmxvd3VpZCk7CkVYUE9SVF9TWU1CT0woZnNfb3ZlcmZsb3dnaWQpOwoKLyoKICogdGhpcyBpbmRpY2F0ZXMgd2hldGhlciB5b3UgY2FuIHJlYm9vdCB3aXRoIGN0cmwtYWx0LWRlbDogdGhlIGRlZmF1bHQgaXMgeWVzCiAqLwoKaW50IENfQV9EID0gMTsKaW50IGNhZF9waWQgPSAxOwoKLyoKICoJTm90aWZpZXIgbGlzdCBmb3Iga2VybmVsIGNvZGUgd2hpY2ggd2FudHMgdG8gYmUgY2FsbGVkCiAqCWF0IHNodXRkb3duLiBUaGlzIGlzIHVzZWQgdG8gc3RvcCBhbnkgaWRsaW5nIERNQSBvcGVyYXRpb25zCiAqCWFuZCB0aGUgbGlrZS4gCiAqLwoKc3RhdGljIHN0cnVjdCBub3RpZmllcl9ibG9jayAqcmVib290X25vdGlmaWVyX2xpc3Q7CnN0YXRpYyBERUZJTkVfUldMT0NLKG5vdGlmaWVyX2xvY2spOwoKLyoqCiAqCW5vdGlmaWVyX2NoYWluX3JlZ2lzdGVyCS0gQWRkIG5vdGlmaWVyIHRvIGEgbm90aWZpZXIgY2hhaW4KICoJQGxpc3Q6IFBvaW50ZXIgdG8gcm9vdCBsaXN0IHBvaW50ZXIKICoJQG46IE5ldyBlbnRyeSBpbiBub3RpZmllciBjaGFpbgogKgogKglBZGRzIGEgbm90aWZpZXIgdG8gYSBub3RpZmllciBjaGFpbi4KICoKICoJQ3VycmVudGx5IGFsd2F5cyByZXR1cm5zIHplcm8uCiAqLwogCmludCBub3RpZmllcl9jaGFpbl9yZWdpc3RlcihzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgKipsaXN0LCBzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgKm4pCnsKCXdyaXRlX2xvY2soJm5vdGlmaWVyX2xvY2spOwoJd2hpbGUoKmxpc3QpCgl7CgkJaWYobi0+cHJpb3JpdHkgPiAoKmxpc3QpLT5wcmlvcml0eSkKCQkJYnJlYWs7CgkJbGlzdD0gJigoKmxpc3QpLT5uZXh0KTsKCX0KCW4tPm5leHQgPSAqbGlzdDsKCSpsaXN0PW47Cgl3cml0ZV91bmxvY2soJm5vdGlmaWVyX2xvY2spOwoJcmV0dXJuIDA7Cn0KCkVYUE9SVF9TWU1CT0wobm90aWZpZXJfY2hhaW5fcmVnaXN0ZXIpOwoKLyoqCiAqCW5vdGlmaWVyX2NoYWluX3VucmVnaXN0ZXIgLSBSZW1vdmUgbm90aWZpZXIgZnJvbSBhIG5vdGlmaWVyIGNoYWluCiAqCUBubDogUG9pbnRlciB0byByb290IGxpc3QgcG9pbnRlcgogKglAbjogTmV3IGVudHJ5IGluIG5vdGlmaWVyIGNoYWluCiAqCiAqCVJlbW92ZXMgYSBub3RpZmllciBmcm9tIGEgbm90aWZpZXIgY2hhaW4uCiAqCiAqCVJldHVybnMgemVybyBvbiBzdWNjZXNzLCBvciAlLUVOT0VOVCBvbiBmYWlsdXJlLgogKi8KIAppbnQgbm90aWZpZXJfY2hhaW5fdW5yZWdpc3RlcihzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgKipubCwgc3RydWN0IG5vdGlmaWVyX2Jsb2NrICpuKQp7Cgl3cml0ZV9sb2NrKCZub3RpZmllcl9sb2NrKTsKCXdoaWxlKCgqbmwpIT1OVUxMKQoJewoJCWlmKCgqbmwpPT1uKQoJCXsKCQkJKm5sPW4tPm5leHQ7CgkJCXdyaXRlX3VubG9jaygmbm90aWZpZXJfbG9jayk7CgkJCXJldHVybiAwOwoJCX0KCQlubD0mKCgqbmwpLT5uZXh0KTsKCX0KCXdyaXRlX3VubG9jaygmbm90aWZpZXJfbG9jayk7CglyZXR1cm4gLUVOT0VOVDsKfQoKRVhQT1JUX1NZTUJPTChub3RpZmllcl9jaGFpbl91bnJlZ2lzdGVyKTsKCi8qKgogKglub3RpZmllcl9jYWxsX2NoYWluIC0gQ2FsbCBmdW5jdGlvbnMgaW4gYSBub3RpZmllciBjaGFpbgogKglAbjogUG9pbnRlciB0byByb290IHBvaW50ZXIgb2Ygbm90aWZpZXIgY2hhaW4KICoJQHZhbDogVmFsdWUgcGFzc2VkIHVubW9kaWZpZWQgdG8gbm90aWZpZXIgZnVuY3Rpb24KICoJQHY6IFBvaW50ZXIgcGFzc2VkIHVubW9kaWZpZWQgdG8gbm90aWZpZXIgZnVuY3Rpb24KICoKICoJQ2FsbHMgZWFjaCBmdW5jdGlvbiBpbiBhIG5vdGlmaWVyIGNoYWluIGluIHR1cm4uCiAqCiAqCUlmIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIG5vdGlmaWVyIGNhbiBiZSBhbmQnZAogKgl3aXRoICVOT1RJRllfU1RPUF9NQVNLLCB0aGVuIG5vdGlmaWVyX2NhbGxfY2hhaW4KICoJd2lsbCByZXR1cm4gaW1tZWRpYXRlbHksIHdpdGggdGhlIHJldHVybiB2YWx1ZSBvZgogKgl0aGUgbm90aWZpZXIgZnVuY3Rpb24gd2hpY2ggaGFsdGVkIGV4ZWN1dGlvbi4KICoJT3RoZXJ3aXNlLCB0aGUgcmV0dXJuIHZhbHVlIGlzIHRoZSByZXR1cm4gdmFsdWUKICoJb2YgdGhlIGxhc3Qgbm90aWZpZXIgZnVuY3Rpb24gY2FsbGVkLgogKi8KIAppbnQgX19rcHJvYmVzIG5vdGlmaWVyX2NhbGxfY2hhaW4oc3RydWN0IG5vdGlmaWVyX2Jsb2NrICoqbiwgdW5zaWduZWQgbG9uZyB2YWwsIHZvaWQgKnYpCnsKCWludCByZXQ9Tk9USUZZX0RPTkU7CglzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgKm5iID0gKm47CgoJd2hpbGUobmIpCgl7CgkJcmV0PW5iLT5ub3RpZmllcl9jYWxsKG5iLHZhbCx2KTsKCQlpZihyZXQmTk9USUZZX1NUT1BfTUFTSykKCQl7CgkJCXJldHVybiByZXQ7CgkJfQoJCW5iPW5iLT5uZXh0OwoJfQoJcmV0dXJuIHJldDsKfQoKRVhQT1JUX1NZTUJPTChub3RpZmllcl9jYWxsX2NoYWluKTsKCi8qKgogKglyZWdpc3Rlcl9yZWJvb3Rfbm90aWZpZXIgLSBSZWdpc3RlciBmdW5jdGlvbiB0byBiZSBjYWxsZWQgYXQgcmVib290IHRpbWUKICoJQG5iOiBJbmZvIGFib3V0IG5vdGlmaWVyIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZAogKgogKglSZWdpc3RlcnMgYSBmdW5jdGlvbiB3aXRoIHRoZSBsaXN0IG9mIGZ1bmN0aW9ucwogKgl0byBiZSBjYWxsZWQgYXQgcmVib290IHRpbWUuCiAqCiAqCUN1cnJlbnRseSBhbHdheXMgcmV0dXJucyB6ZXJvLCBhcyBub3RpZmllcl9jaGFpbl9yZWdpc3RlcgogKglhbHdheXMgcmV0dXJucyB6ZXJvLgogKi8KIAppbnQgcmVnaXN0ZXJfcmVib290X25vdGlmaWVyKHN0cnVjdCBub3RpZmllcl9ibG9jayAqIG5iKQp7CglyZXR1cm4gbm90aWZpZXJfY2hhaW5fcmVnaXN0ZXIoJnJlYm9vdF9ub3RpZmllcl9saXN0LCBuYik7Cn0KCkVYUE9SVF9TWU1CT0wocmVnaXN0ZXJfcmVib290X25vdGlmaWVyKTsKCi8qKgogKgl1bnJlZ2lzdGVyX3JlYm9vdF9ub3RpZmllciAtIFVucmVnaXN0ZXIgcHJldmlvdXNseSByZWdpc3RlcmVkIHJlYm9vdCBub3RpZmllcgogKglAbmI6IEhvb2sgdG8gYmUgdW5yZWdpc3RlcmVkCiAqCiAqCVVucmVnaXN0ZXJzIGEgcHJldmlvdXNseSByZWdpc3RlcmVkIHJlYm9vdAogKglub3RpZmllciBmdW5jdGlvbi4KICoKICoJUmV0dXJucyB6ZXJvIG9uIHN1Y2Nlc3MsIG9yICUtRU5PRU5UIG9uIGZhaWx1cmUuCiAqLwogCmludCB1bnJlZ2lzdGVyX3JlYm9vdF9ub3RpZmllcihzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgKiBuYikKewoJcmV0dXJuIG5vdGlmaWVyX2NoYWluX3VucmVnaXN0ZXIoJnJlYm9vdF9ub3RpZmllcl9saXN0LCBuYik7Cn0KCkVYUE9SVF9TWU1CT0wodW5yZWdpc3Rlcl9yZWJvb3Rfbm90aWZpZXIpOwoKc3RhdGljIGludCBzZXRfb25lX3ByaW8oc3RydWN0IHRhc2tfc3RydWN0ICpwLCBpbnQgbmljZXZhbCwgaW50IGVycm9yKQp7CglpbnQgbm9fbmljZTsKCglpZiAocC0+dWlkICE9IGN1cnJlbnQtPmV1aWQgJiYKCQlwLT5ldWlkICE9IGN1cnJlbnQtPmV1aWQgJiYgIWNhcGFibGUoQ0FQX1NZU19OSUNFKSkgewoJCWVycm9yID0gLUVQRVJNOwoJCWdvdG8gb3V0OwoJfQoJaWYgKG5pY2V2YWwgPCB0YXNrX25pY2UocCkgJiYgIWNhbl9uaWNlKHAsIG5pY2V2YWwpKSB7CgkJZXJyb3IgPSAtRUFDQ0VTOwoJCWdvdG8gb3V0OwoJfQoJbm9fbmljZSA9IHNlY3VyaXR5X3Rhc2tfc2V0bmljZShwLCBuaWNldmFsKTsKCWlmIChub19uaWNlKSB7CgkJZXJyb3IgPSBub19uaWNlOwoJCWdvdG8gb3V0OwoJfQoJaWYgKGVycm9yID09IC1FU1JDSCkKCQllcnJvciA9IDA7CglzZXRfdXNlcl9uaWNlKHAsIG5pY2V2YWwpOwpvdXQ6CglyZXR1cm4gZXJyb3I7Cn0KCmFzbWxpbmthZ2UgbG9uZyBzeXNfc2V0cHJpb3JpdHkoaW50IHdoaWNoLCBpbnQgd2hvLCBpbnQgbmljZXZhbCkKewoJc3RydWN0IHRhc2tfc3RydWN0ICpnLCAqcDsKCXN0cnVjdCB1c2VyX3N0cnVjdCAqdXNlcjsKCWludCBlcnJvciA9IC1FSU5WQUw7CgoJaWYgKHdoaWNoID4gMiB8fCB3aGljaCA8IDApCgkJZ290byBvdXQ7CgoJLyogbm9ybWFsaXplOiBhdm9pZCBzaWduZWQgZGl2aXNpb24gKHJvdW5kaW5nIHByb2JsZW1zKSAqLwoJZXJyb3IgPSAtRVNSQ0g7CglpZiAobmljZXZhbCA8IC0yMCkKCQluaWNldmFsID0gLTIwOwoJaWYgKG5pY2V2YWwgPiAxOSkKCQluaWNldmFsID0gMTk7CgoJcmVhZF9sb2NrKCZ0YXNrbGlzdF9sb2NrKTsKCXN3aXRjaCAod2hpY2gpIHsKCQljYXNlIFBSSU9fUFJPQ0VTUzoKCQkJaWYgKCF3aG8pCgkJCQl3aG8gPSBjdXJyZW50LT5waWQ7CgkJCXAgPSBmaW5kX3Rhc2tfYnlfcGlkKHdobyk7CgkJCWlmIChwKQoJCQkJZXJyb3IgPSBzZXRfb25lX3ByaW8ocCwgbmljZXZhbCwgZXJyb3IpOwoJCQlicmVhazsKCQljYXNlIFBSSU9fUEdSUDoKCQkJaWYgKCF3aG8pCgkJCQl3aG8gPSBwcm9jZXNzX2dyb3VwKGN1cnJlbnQpOwoJCQlkb19lYWNoX3Rhc2tfcGlkKHdobywgUElEVFlQRV9QR0lELCBwKSB7CgkJCQllcnJvciA9IHNldF9vbmVfcHJpbyhwLCBuaWNldmFsLCBlcnJvcik7CgkJCX0gd2hpbGVfZWFjaF90YXNrX3BpZCh3aG8sIFBJRFRZUEVfUEdJRCwgcCk7CgkJCWJyZWFrOwoJCWNhc2UgUFJJT19VU0VSOgoJCQl1c2VyID0gY3VycmVudC0+dXNlcjsKCQkJaWYgKCF3aG8pCgkJCQl3aG8gPSBjdXJyZW50LT51aWQ7CgkJCWVsc2UKCQkJCWlmICgod2hvICE9IGN1cnJlbnQtPnVpZCkgJiYgISh1c2VyID0gZmluZF91c2VyKHdobykpKQoJCQkJCWdvdG8gb3V0X3VubG9jazsJLyogTm8gcHJvY2Vzc2VzIGZvciB0aGlzIHVzZXIgKi8KCgkJCWRvX2VhY2hfdGhyZWFkKGcsIHApCgkJCQlpZiAocC0+dWlkID09IHdobykKCQkJCQllcnJvciA9IHNldF9vbmVfcHJpbyhwLCBuaWNldmFsLCBlcnJvcik7CgkJCXdoaWxlX2VhY2hfdGhyZWFkKGcsIHApOwoJCQlpZiAod2hvICE9IGN1cnJlbnQtPnVpZCkKCQkJCWZyZWVfdWlkKHVzZXIpOwkJLyogRm9yIGZpbmRfdXNlcigpICovCgkJCWJyZWFrOwoJfQpvdXRfdW5sb2NrOgoJcmVhZF91bmxvY2soJnRhc2tsaXN0X2xvY2spOwpvdXQ6CglyZXR1cm4gZXJyb3I7Cn0KCi8qCiAqIFVnaC4gVG8gYXZvaWQgbmVnYXRpdmUgcmV0dXJuIHZhbHVlcywgImdldHByaW9yaXR5KCkiIHdpbGwKICogbm90IHJldHVybiB0aGUgbm9ybWFsIG5pY2UtdmFsdWUsIGJ1dCBhIG5lZ2F0ZWQgdmFsdWUgdGhhdAogKiBoYXMgYmVlbiBvZmZzZXQgYnkgMjAgKGllIGl0IHJldHVybnMgNDAuLjEgaW5zdGVhZCBvZiAtMjAuLjE5KQogKiB0byBzdGF5IGNvbXBhdGlibGUuCiAqLwphc21saW5rYWdlIGxvbmcgc3lzX2dldHByaW9yaXR5KGludCB3aGljaCwgaW50IHdobykKewoJc3RydWN0IHRhc2tfc3RydWN0ICpnLCAqcDsKCXN0cnVjdCB1c2VyX3N0cnVjdCAqdXNlcjsKCWxvbmcgbmljZXZhbCwgcmV0dmFsID0gLUVTUkNIOwoKCWlmICh3aGljaCA+IDIgfHwgd2hpY2ggPCAwKQoJCXJldHVybiAtRUlOVkFMOwoKCXJlYWRfbG9jaygmdGFza2xpc3RfbG9jayk7Cglzd2l0Y2ggKHdoaWNoKSB7CgkJY2FzZSBQUklPX1BST0NFU1M6CgkJCWlmICghd2hvKQoJCQkJd2hvID0gY3VycmVudC0+cGlkOwoJCQlwID0gZmluZF90YXNrX2J5X3BpZCh3aG8pOwoJCQlpZiAocCkgewoJCQkJbmljZXZhbCA9IDIwIC0gdGFza19uaWNlKHApOwoJCQkJaWYgKG5pY2V2YWwgPiByZXR2YWwpCgkJCQkJcmV0dmFsID0gbmljZXZhbDsKCQkJfQoJCQlicmVhazsKCQljYXNlIFBSSU9fUEdSUDoKCQkJaWYgKCF3aG8pCgkJCQl3aG8gPSBwcm9jZXNzX2dyb3VwKGN1cnJlbnQpOwoJCQlkb19lYWNoX3Rhc2tfcGlkKHdobywgUElEVFlQRV9QR0lELCBwKSB7CgkJCQluaWNldmFsID0gMjAgLSB0YXNrX25pY2UocCk7CgkJCQlpZiAobmljZXZhbCA+IHJldHZhbCkKCQkJCQlyZXR2YWwgPSBuaWNldmFsOwoJCQl9IHdoaWxlX2VhY2hfdGFza19waWQod2hvLCBQSURUWVBFX1BHSUQsIHApOwoJCQlicmVhazsKCQljYXNlIFBSSU9fVVNFUjoKCQkJdXNlciA9IGN1cnJlbnQtPnVzZXI7CgkJCWlmICghd2hvKQoJCQkJd2hvID0gY3VycmVudC0+dWlkOwoJCQllbHNlCgkJCQlpZiAoKHdobyAhPSBjdXJyZW50LT51aWQpICYmICEodXNlciA9IGZpbmRfdXNlcih3aG8pKSkKCQkJCQlnb3RvIG91dF91bmxvY2s7CS8qIE5vIHByb2Nlc3NlcyBmb3IgdGhpcyB1c2VyICovCgoJCQlkb19lYWNoX3RocmVhZChnLCBwKQoJCQkJaWYgKHAtPnVpZCA9PSB3aG8pIHsKCQkJCQluaWNldmFsID0gMjAgLSB0YXNrX25pY2UocCk7CgkJCQkJaWYgKG5pY2V2YWwgPiByZXR2YWwpCgkJCQkJCXJldHZhbCA9IG5pY2V2YWw7CgkJCQl9CgkJCXdoaWxlX2VhY2hfdGhyZWFkKGcsIHApOwoJCQlpZiAod2hvICE9IGN1cnJlbnQtPnVpZCkKCQkJCWZyZWVfdWlkKHVzZXIpOwkJLyogZm9yIGZpbmRfdXNlcigpICovCgkJCWJyZWFrOwoJfQpvdXRfdW5sb2NrOgoJcmVhZF91bmxvY2soJnRhc2tsaXN0X2xvY2spOwoKCXJldHVybiByZXR2YWw7Cn0KCi8qKgogKgllbWVyZ2VuY3lfcmVzdGFydCAtIHJlYm9vdCB0aGUgc3lzdGVtCiAqCiAqCVdpdGhvdXQgc2h1dHRpbmcgZG93biBhbnkgaGFyZHdhcmUgb3IgdGFraW5nIGFueSBsb2NrcwogKglyZWJvb3QgdGhlIHN5c3RlbS4gIFRoaXMgaXMgY2FsbGVkIHdoZW4gd2Uga25vdyB3ZSBhcmUgaW4KICoJdHJvdWJsZSBzbyB0aGlzIGlzIG91ciBiZXN0IGVmZm9ydCB0byByZWJvb3QuICBUaGlzIGlzCiAqCXNhZmUgdG8gY2FsbCBpbiBpbnRlcnJ1cHQgY29udGV4dC4KICovCnZvaWQgZW1lcmdlbmN5X3Jlc3RhcnQodm9pZCkKewoJbWFjaGluZV9lbWVyZ2VuY3lfcmVzdGFydCgpOwp9CkVYUE9SVF9TWU1CT0xfR1BMKGVtZXJnZW5jeV9yZXN0YXJ0KTsKCnZvaWQga2VybmVsX3Jlc3RhcnRfcHJlcGFyZShjaGFyICpjbWQpCnsKCW5vdGlmaWVyX2NhbGxfY2hhaW4oJnJlYm9vdF9ub3RpZmllcl9saXN0LCBTWVNfUkVTVEFSVCwgY21kKTsKCXN5c3RlbV9zdGF0ZSA9IFNZU1RFTV9SRVNUQVJUOwoJZGV2aWNlX3NodXRkb3duKCk7Cn0KCi8qKgogKglrZXJuZWxfcmVzdGFydCAtIHJlYm9vdCB0aGUgc3lzdGVtCiAqCUBjbWQ6IHBvaW50ZXIgdG8gYnVmZmVyIGNvbnRhaW5pbmcgY29tbWFuZCB0byBleGVjdXRlIGZvciByZXN0YXJ0CiAqCQlvciAlTlVMTAogKgogKglTaHV0ZG93biBldmVyeXRoaW5nIGFuZCBwZXJmb3JtIGEgY2xlYW4gcmVib290LgogKglUaGlzIGlzIG5vdCBzYWZlIHRvIGNhbGwgaW4gaW50ZXJydXB0IGNvbnRleHQuCiAqLwp2b2lkIGtlcm5lbF9yZXN0YXJ0KGNoYXIgKmNtZCkKewoJa2VybmVsX3Jlc3RhcnRfcHJlcGFyZShjbWQpOwoJaWYgKCFjbWQpIHsKCQlwcmludGsoS0VSTl9FTUVSRyAiUmVzdGFydGluZyBzeXN0ZW0uXG4iKTsKCX0gZWxzZSB7CgkJcHJpbnRrKEtFUk5fRU1FUkcgIlJlc3RhcnRpbmcgc3lzdGVtIHdpdGggY29tbWFuZCAnJXMnLlxuIiwgY21kKTsKCX0KCXByaW50aygiLlxuIik7CgltYWNoaW5lX3Jlc3RhcnQoY21kKTsKfQpFWFBPUlRfU1lNQk9MX0dQTChrZXJuZWxfcmVzdGFydCk7CgovKioKICoJa2VybmVsX2tleGVjIC0gcmVib290IHRoZSBzeXN0ZW0KICoKICoJTW92ZSBpbnRvIHBsYWNlIGFuZCBzdGFydCBleGVjdXRpbmcgYSBwcmVsb2FkZWQgc3RhbmRhbG9uZQogKglleGVjdXRhYmxlLiAgSWYgbm90aGluZyB3YXMgcHJlbG9hZGVkIHJldHVybiBhbiBlcnJvci4KICovCnZvaWQga2VybmVsX2tleGVjKHZvaWQpCnsKI2lmZGVmIENPTkZJR19LRVhFQwoJc3RydWN0IGtpbWFnZSAqaW1hZ2U7CglpbWFnZSA9IHhjaGcoJmtleGVjX2ltYWdlLCBOVUxMKTsKCWlmICghaW1hZ2UpIHsKCQlyZXR1cm47Cgl9CglrZXJuZWxfcmVzdGFydF9wcmVwYXJlKE5VTEwpOwoJcHJpbnRrKEtFUk5fRU1FUkcgIlN0YXJ0aW5nIG5ldyBrZXJuZWxcbiIpOwoJbWFjaGluZV9zaHV0ZG93bigpOwoJbWFjaGluZV9rZXhlYyhpbWFnZSk7CiNlbmRpZgp9CkVYUE9SVF9TWU1CT0xfR1BMKGtlcm5lbF9rZXhlYyk7Cgp2b2lkIGtlcm5lbF9zaHV0ZG93bl9wcmVwYXJlKGVudW0gc3lzdGVtX3N0YXRlcyBzdGF0ZSkKewoJbm90aWZpZXJfY2FsbF9jaGFpbigmcmVib290X25vdGlmaWVyX2xpc3QsCgkJKHN0YXRlID09IFNZU1RFTV9IQUxUKT9TWVNfSEFMVDpTWVNfUE9XRVJfT0ZGLCBOVUxMKTsKCXN5c3RlbV9zdGF0ZSA9IHN0YXRlOwoJZGV2aWNlX3NodXRkb3duKCk7Cn0KLyoqCiAqCWtlcm5lbF9oYWx0IC0gaGFsdCB0aGUgc3lzdGVtCiAqCiAqCVNodXRkb3duIGV2ZXJ5dGhpbmcgYW5kIHBlcmZvcm0gYSBjbGVhbiBzeXN0ZW0gaGFsdC4KICovCnZvaWQga2VybmVsX2hhbHQodm9pZCkKewoJa2VybmVsX3NodXRkb3duX3ByZXBhcmUoU1lTVEVNX0hBTFQpOwoJcHJpbnRrKEtFUk5fRU1FUkcgIlN5c3RlbSBoYWx0ZWQuXG4iKTsKCW1hY2hpbmVfaGFsdCgpOwp9CgpFWFBPUlRfU1lNQk9MX0dQTChrZXJuZWxfaGFsdCk7CgovKioKICoJa2VybmVsX3Bvd2VyX29mZiAtIHBvd2VyX29mZiB0aGUgc3lzdGVtCiAqCiAqCVNodXRkb3duIGV2ZXJ5dGhpbmcgYW5kIHBlcmZvcm0gYSBjbGVhbiBzeXN0ZW0gcG93ZXJfb2ZmLgogKi8Kdm9pZCBrZXJuZWxfcG93ZXJfb2ZmKHZvaWQpCnsKCWtlcm5lbF9zaHV0ZG93bl9wcmVwYXJlKFNZU1RFTV9QT1dFUl9PRkYpOwoJcHJpbnRrKEtFUk5fRU1FUkcgIlBvd2VyIGRvd24uXG4iKTsKCW1hY2hpbmVfcG93ZXJfb2ZmKCk7Cn0KRVhQT1JUX1NZTUJPTF9HUEwoa2VybmVsX3Bvd2VyX29mZik7Ci8qCiAqIFJlYm9vdCBzeXN0ZW0gY2FsbDogZm9yIG9idmlvdXMgcmVhc29ucyBvbmx5IHJvb3QgbWF5IGNhbGwgaXQsCiAqIGFuZCBldmVuIHJvb3QgbmVlZHMgdG8gc2V0IHVwIHNvbWUgbWFnaWMgbnVtYmVycyBpbiB0aGUgcmVnaXN0ZXJzCiAqIHNvIHRoYXQgc29tZSBtaXN0YWtlIHdvbid0IG1ha2UgdGhpcyByZWJvb3QgdGhlIHdob2xlIG1hY2hpbmUuCiAqIFlvdSBjYW4gYWxzbyBzZXQgdGhlIG1lYW5pbmcgb2YgdGhlIGN0cmwtYWx0LWRlbC1rZXkgaGVyZS4KICoKICogcmVib290IGRvZXNuJ3Qgc3luYzogZG8gdGhhdCB5b3Vyc2VsZiBiZWZvcmUgY2FsbGluZyB0aGlzLgogKi8KYXNtbGlua2FnZSBsb25nIHN5c19yZWJvb3QoaW50IG1hZ2ljMSwgaW50IG1hZ2ljMiwgdW5zaWduZWQgaW50IGNtZCwgdm9pZCBfX3VzZXIgKiBhcmcpCnsKCWNoYXIgYnVmZmVyWzI1Nl07CgoJLyogV2Ugb25seSB0cnVzdCB0aGUgc3VwZXJ1c2VyIHdpdGggcmVib290aW5nIHRoZSBzeXN0ZW0uICovCglpZiAoIWNhcGFibGUoQ0FQX1NZU19CT09UKSkKCQlyZXR1cm4gLUVQRVJNOwoKCS8qIEZvciBzYWZldHksIHdlIHJlcXVpcmUgIm1hZ2ljIiBhcmd1bWVudHMuICovCglpZiAobWFnaWMxICE9IExJTlVYX1JFQk9PVF9NQUdJQzEgfHwKCSAgICAobWFnaWMyICE9IExJTlVYX1JFQk9PVF9NQUdJQzIgJiYKCSAgICAgICAgICAgICAgICBtYWdpYzIgIT0gTElOVVhfUkVCT09UX01BR0lDMkEgJiYKCQkJbWFnaWMyICE9IExJTlVYX1JFQk9PVF9NQUdJQzJCICYmCgkgICAgICAgICAgICAgICAgbWFnaWMyICE9IExJTlVYX1JFQk9PVF9NQUdJQzJDKSkKCQlyZXR1cm4gLUVJTlZBTDsKCgkvKiBJbnN0ZWFkIG9mIHRyeWluZyB0byBtYWtlIHRoZSBwb3dlcl9vZmYgY29kZSBsb29rIGxpa2UKCSAqIGhhbHQgd2hlbiBwbV9wb3dlcl9vZmYgaXMgbm90IHNldCBkbyBpdCB0aGUgZWFzeSB3YXkuCgkgKi8KCWlmICgoY21kID09IExJTlVYX1JFQk9PVF9DTURfUE9XRVJfT0ZGKSAmJiAhcG1fcG93ZXJfb2ZmKQoJCWNtZCA9IExJTlVYX1JFQk9PVF9DTURfSEFMVDsKCglsb2NrX2tlcm5lbCgpOwoJc3dpdGNoIChjbWQpIHsKCWNhc2UgTElOVVhfUkVCT09UX0NNRF9SRVNUQVJUOgoJCWtlcm5lbF9yZXN0YXJ0KE5VTEwpOwoJCWJyZWFrOwoKCWNhc2UgTElOVVhfUkVCT09UX0NNRF9DQURfT046CgkJQ19BX0QgPSAxOwoJCWJyZWFrOwoKCWNhc2UgTElOVVhfUkVCT09UX0NNRF9DQURfT0ZGOgoJCUNfQV9EID0gMDsKCQlicmVhazsKCgljYXNlIExJTlVYX1JFQk9PVF9DTURfSEFMVDoKCQlrZXJuZWxfaGFsdCgpOwoJCXVubG9ja19rZXJuZWwoKTsKCQlkb19leGl0KDApOwoJCWJyZWFrOwoKCWNhc2UgTElOVVhfUkVCT09UX0NNRF9QT1dFUl9PRkY6CgkJa2VybmVsX3Bvd2VyX29mZigpOwoJCXVubG9ja19rZXJuZWwoKTsKCQlkb19leGl0KDApOwoJCWJyZWFrOwoKCWNhc2UgTElOVVhfUkVCT09UX0NNRF9SRVNUQVJUMjoKCQlpZiAoc3RybmNweV9mcm9tX3VzZXIoJmJ1ZmZlclswXSwgYXJnLCBzaXplb2YoYnVmZmVyKSAtIDEpIDwgMCkgewoJCQl1bmxvY2tfa2VybmVsKCk7CgkJCXJldHVybiAtRUZBVUxUOwoJCX0KCQlidWZmZXJbc2l6ZW9mKGJ1ZmZlcikgLSAxXSA9ICdcMCc7CgoJCWtlcm5lbF9yZXN0YXJ0KGJ1ZmZlcik7CgkJYnJlYWs7CgoJY2FzZSBMSU5VWF9SRUJPT1RfQ01EX0tFWEVDOgoJCWtlcm5lbF9rZXhlYygpOwoJCXVubG9ja19rZXJuZWwoKTsKCQlyZXR1cm4gLUVJTlZBTDsKCiNpZmRlZiBDT05GSUdfU09GVFdBUkVfU1VTUEVORAoJY2FzZSBMSU5VWF9SRUJPT1RfQ01EX1NXX1NVU1BFTkQ6CgkJewoJCQlpbnQgcmV0ID0gc29mdHdhcmVfc3VzcGVuZCgpOwoJCQl1bmxvY2tfa2VybmVsKCk7CgkJCXJldHVybiByZXQ7CgkJfQojZW5kaWYKCglkZWZhdWx0OgoJCXVubG9ja19rZXJuZWwoKTsKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCXVubG9ja19rZXJuZWwoKTsKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBkZWZlcnJlZF9jYWQodm9pZCAqZHVtbXkpCnsKCWtlcm5lbF9yZXN0YXJ0KE5VTEwpOwp9CgovKgogKiBUaGlzIGZ1bmN0aW9uIGdldHMgY2FsbGVkIGJ5IGN0cmwtYWx0LWRlbCAtIGllIHRoZSBrZXlib2FyZCBpbnRlcnJ1cHQuCiAqIEFzIGl0J3MgY2FsbGVkIHdpdGhpbiBhbiBpbnRlcnJ1cHQsIGl0IG1heSBOT1Qgc3luYzogdGhlIG9ubHkgY2hvaWNlCiAqIGlzIHdoZXRoZXIgdG8gcmVib290IGF0IG9uY2UsIG9yIGp1c3QgaWdub3JlIHRoZSBjdHJsLWFsdC1kZWwuCiAqLwp2b2lkIGN0cmxfYWx0X2RlbCh2b2lkKQp7CglzdGF0aWMgREVDTEFSRV9XT1JLKGNhZF93b3JrLCBkZWZlcnJlZF9jYWQsIE5VTEwpOwoKCWlmIChDX0FfRCkKCQlzY2hlZHVsZV93b3JrKCZjYWRfd29yayk7CgllbHNlCgkJa2lsbF9wcm9jKGNhZF9waWQsIFNJR0lOVCwgMSk7Cn0KCQoKLyoKICogVW5wcml2aWxlZ2VkIHVzZXJzIG1heSBjaGFuZ2UgdGhlIHJlYWwgZ2lkIHRvIHRoZSBlZmZlY3RpdmUgZ2lkCiAqIG9yIHZpY2UgdmVyc2EuICAoQlNELXN0eWxlKQogKgogKiBJZiB5b3Ugc2V0IHRoZSByZWFsIGdpZCBhdCBhbGwsIG9yIHNldCB0aGUgZWZmZWN0aXZlIGdpZCB0byBhIHZhbHVlIG5vdAogKiBlcXVhbCB0byB0aGUgcmVhbCBnaWQsIHRoZW4gdGhlIHNhdmVkIGdpZCBpcyBzZXQgdG8gdGhlIG5ldyBlZmZlY3RpdmUgZ2lkLgogKgogKiBUaGlzIG1ha2VzIGl0IHBvc3NpYmxlIGZvciBhIHNldGdpZCBwcm9ncmFtIHRvIGNvbXBsZXRlbHkgZHJvcCBpdHMKICogcHJpdmlsZWdlcywgd2hpY2ggaXMgb2Z0ZW4gYSB1c2VmdWwgYXNzZXJ0aW9uIHRvIG1ha2Ugd2hlbiB5b3UgYXJlIGRvaW5nCiAqIGEgc2VjdXJpdHkgYXVkaXQgb3ZlciBhIHByb2dyYW0uCiAqCiAqIFRoZSBnZW5lcmFsIGlkZWEgaXMgdGhhdCBhIHByb2dyYW0gd2hpY2ggdXNlcyBqdXN0IHNldHJlZ2lkKCkgd2lsbCBiZQogKiAxMDAlIGNvbXBhdGlibGUgd2l0aCBCU0QuICBBIHByb2dyYW0gd2hpY2ggdXNlcyBqdXN0IHNldGdpZCgpIHdpbGwgYmUKICogMTAwJSBjb21wYXRpYmxlIHdpdGggUE9TSVggd2l0aCBzYXZlZCBJRHMuIAogKgogKiBTTVA6IFRoZXJlIGFyZSBub3QgcmFjZXMsIHRoZSBHSURzIGFyZSBjaGVja2VkIG9ubHkgYnkgZmlsZXN5c3RlbQogKiAgICAgIG9wZXJhdGlvbnMgKGFzIGZhciBhcyBzZW1hbnRpYyBwcmVzZXJ2YXRpb24gaXMgY29uY2VybmVkKS4KICovCmFzbWxpbmthZ2UgbG9uZyBzeXNfc2V0cmVnaWQoZ2lkX3QgcmdpZCwgZ2lkX3QgZWdpZCkKewoJaW50IG9sZF9yZ2lkID0gY3VycmVudC0+Z2lkOwoJaW50IG9sZF9lZ2lkID0gY3VycmVudC0+ZWdpZDsKCWludCBuZXdfcmdpZCA9IG9sZF9yZ2lkOwoJaW50IG5ld19lZ2lkID0gb2xkX2VnaWQ7CglpbnQgcmV0dmFsOwoKCXJldHZhbCA9IHNlY3VyaXR5X3Rhc2tfc2V0Z2lkKHJnaWQsIGVnaWQsIChnaWRfdCktMSwgTFNNX1NFVElEX1JFKTsKCWlmIChyZXR2YWwpCgkJcmV0dXJuIHJldHZhbDsKCglpZiAocmdpZCAhPSAoZ2lkX3QpIC0xKSB7CgkJaWYgKChvbGRfcmdpZCA9PSByZ2lkKSB8fAoJCSAgICAoY3VycmVudC0+ZWdpZD09cmdpZCkgfHwKCQkgICAgY2FwYWJsZShDQVBfU0VUR0lEKSkKCQkJbmV3X3JnaWQgPSByZ2lkOwoJCWVsc2UKCQkJcmV0dXJuIC1FUEVSTTsKCX0KCWlmIChlZ2lkICE9IChnaWRfdCkgLTEpIHsKCQlpZiAoKG9sZF9yZ2lkID09IGVnaWQpIHx8CgkJICAgIChjdXJyZW50LT5lZ2lkID09IGVnaWQpIHx8CgkJICAgIChjdXJyZW50LT5zZ2lkID09IGVnaWQpIHx8CgkJICAgIGNhcGFibGUoQ0FQX1NFVEdJRCkpCgkJCW5ld19lZ2lkID0gZWdpZDsKCQllbHNlIHsKCQkJcmV0dXJuIC1FUEVSTTsKCQl9Cgl9CglpZiAobmV3X2VnaWQgIT0gb2xkX2VnaWQpCgl7CgkJY3VycmVudC0+bW0tPmR1bXBhYmxlID0gc3VpZF9kdW1wYWJsZTsKCQlzbXBfd21iKCk7Cgl9CglpZiAocmdpZCAhPSAoZ2lkX3QpIC0xIHx8CgkgICAgKGVnaWQgIT0gKGdpZF90KSAtMSAmJiBlZ2lkICE9IG9sZF9yZ2lkKSkKCQljdXJyZW50LT5zZ2lkID0gbmV3X2VnaWQ7CgljdXJyZW50LT5mc2dpZCA9IG5ld19lZ2lkOwoJY3VycmVudC0+ZWdpZCA9IG5ld19lZ2lkOwoJY3VycmVudC0+Z2lkID0gbmV3X3JnaWQ7CglrZXlfZnNnaWRfY2hhbmdlZChjdXJyZW50KTsKCXByb2NfaWRfY29ubmVjdG9yKGN1cnJlbnQsIFBST0NfRVZFTlRfR0lEKTsKCXJldHVybiAwOwp9CgovKgogKiBzZXRnaWQoKSBpcyBpbXBsZW1lbnRlZCBsaWtlIFN5c1Ygdy8gU0FWRURfSURTIAogKgogKiBTTVA6IFNhbWUgaW1wbGljaXQgcmFjZXMgYXMgYWJvdmUuCiAqLwphc21saW5rYWdlIGxvbmcgc3lzX3NldGdpZChnaWRfdCBnaWQpCnsKCWludCBvbGRfZWdpZCA9IGN1cnJlbnQtPmVnaWQ7CglpbnQgcmV0dmFsOwoKCXJldHZhbCA9IHNlY3VyaXR5X3Rhc2tfc2V0Z2lkKGdpZCwgKGdpZF90KS0xLCAoZ2lkX3QpLTEsIExTTV9TRVRJRF9JRCk7CglpZiAocmV0dmFsKQoJCXJldHVybiByZXR2YWw7CgoJaWYgKGNhcGFibGUoQ0FQX1NFVEdJRCkpCgl7CgkJaWYob2xkX2VnaWQgIT0gZ2lkKQoJCXsKCQkJY3VycmVudC0+bW0tPmR1bXBhYmxlID0gc3VpZF9kdW1wYWJsZTsKCQkJc21wX3dtYigpOwoJCX0KCQljdXJyZW50LT5naWQgPSBjdXJyZW50LT5lZ2lkID0gY3VycmVudC0+c2dpZCA9IGN1cnJlbnQtPmZzZ2lkID0gZ2lkOwoJfQoJZWxzZSBpZiAoKGdpZCA9PSBjdXJyZW50LT5naWQpIHx8IChnaWQgPT0gY3VycmVudC0+c2dpZCkpCgl7CgkJaWYob2xkX2VnaWQgIT0gZ2lkKQoJCXsKCQkJY3VycmVudC0+bW0tPmR1bXBhYmxlID0gc3VpZF9kdW1wYWJsZTsKCQkJc21wX3dtYigpOwoJCX0KCQljdXJyZW50LT5lZ2lkID0gY3VycmVudC0+ZnNnaWQgPSBnaWQ7Cgl9CgllbHNlCgkJcmV0dXJuIC1FUEVSTTsKCglrZXlfZnNnaWRfY2hhbmdlZChjdXJyZW50KTsKCXByb2NfaWRfY29ubmVjdG9yKGN1cnJlbnQsIFBST0NfRVZFTlRfR0lEKTsKCXJldHVybiAwOwp9CiAgCnN0YXRpYyBpbnQgc2V0X3VzZXIodWlkX3QgbmV3X3J1aWQsIGludCBkdW1wY2xlYXIpCnsKCXN0cnVjdCB1c2VyX3N0cnVjdCAqbmV3X3VzZXI7CgoJbmV3X3VzZXIgPSBhbGxvY191aWQobmV3X3J1aWQpOwoJaWYgKCFuZXdfdXNlcikKCQlyZXR1cm4gLUVBR0FJTjsKCglpZiAoYXRvbWljX3JlYWQoJm5ld191c2VyLT5wcm9jZXNzZXMpID49CgkJCQljdXJyZW50LT5zaWduYWwtPnJsaW1bUkxJTUlUX05QUk9DXS5ybGltX2N1ciAmJgoJCQluZXdfdXNlciAhPSAmcm9vdF91c2VyKSB7CgkJZnJlZV91aWQobmV3X3VzZXIpOwoJCXJldHVybiAtRUFHQUlOOwoJfQoKCXN3aXRjaF91aWQobmV3X3VzZXIpOwoKCWlmKGR1bXBjbGVhcikKCXsKCQljdXJyZW50LT5tbS0+ZHVtcGFibGUgPSBzdWlkX2R1bXBhYmxlOwoJCXNtcF93bWIoKTsKCX0KCWN1cnJlbnQtPnVpZCA9IG5ld19ydWlkOwoJcmV0dXJuIDA7Cn0KCi8qCiAqIFVucHJpdmlsZWdlZCB1c2VycyBtYXkgY2hhbmdlIHRoZSByZWFsIHVpZCB0byB0aGUgZWZmZWN0aXZlIHVpZAogKiBvciB2aWNlIHZlcnNhLiAgKEJTRC1zdHlsZSkKICoKICogSWYgeW91IHNldCB0aGUgcmVhbCB1aWQgYXQgYWxsLCBvciBzZXQgdGhlIGVmZmVjdGl2ZSB1aWQgdG8gYSB2YWx1ZSBub3QKICogZXF1YWwgdG8gdGhlIHJlYWwgdWlkLCB0aGVuIHRoZSBzYXZlZCB1aWQgaXMgc2V0IHRvIHRoZSBuZXcgZWZmZWN0aXZlIHVpZC4KICoKICogVGhpcyBtYWtlcyBpdCBwb3NzaWJsZSBmb3IgYSBzZXR1aWQgcHJvZ3JhbSB0byBjb21wbGV0ZWx5IGRyb3AgaXRzCiAqIHByaXZpbGVnZXMsIHdoaWNoIGlzIG9mdGVuIGEgdXNlZnVsIGFzc2VydGlvbiB0byBtYWtlIHdoZW4geW91IGFyZSBkb2luZwogKiBhIHNlY3VyaXR5IGF1ZGl0IG92ZXIgYSBwcm9ncmFtLgogKgogKiBUaGUgZ2VuZXJhbCBpZGVhIGlzIHRoYXQgYSBwcm9ncmFtIHdoaWNoIHVzZXMganVzdCBzZXRyZXVpZCgpIHdpbGwgYmUKICogMTAwJSBjb21wYXRpYmxlIHdpdGggQlNELiAgQSBwcm9ncmFtIHdoaWNoIHVzZXMganVzdCBzZXR1aWQoKSB3aWxsIGJlCiAqIDEwMCUgY29tcGF0aWJsZSB3aXRoIFBPU0lYIHdpdGggc2F2ZWQgSURzLiAKICovCmFzbWxpbmthZ2UgbG9uZyBzeXNfc2V0cmV1aWQodWlkX3QgcnVpZCwgdWlkX3QgZXVpZCkKewoJaW50IG9sZF9ydWlkLCBvbGRfZXVpZCwgb2xkX3N1aWQsIG5ld19ydWlkLCBuZXdfZXVpZDsKCWludCByZXR2YWw7CgoJcmV0dmFsID0gc2VjdXJpdHlfdGFza19zZXR1aWQocnVpZCwgZXVpZCwgKHVpZF90KS0xLCBMU01fU0VUSURfUkUpOwoJaWYgKHJldHZhbCkKCQlyZXR1cm4gcmV0dmFsOwoKCW5ld19ydWlkID0gb2xkX3J1aWQgPSBjdXJyZW50LT51aWQ7CgluZXdfZXVpZCA9IG9sZF9ldWlkID0gY3VycmVudC0+ZXVpZDsKCW9sZF9zdWlkID0gY3VycmVudC0+c3VpZDsKCglpZiAocnVpZCAhPSAodWlkX3QpIC0xKSB7CgkJbmV3X3J1aWQgPSBydWlkOwoJCWlmICgob2xkX3J1aWQgIT0gcnVpZCkgJiYKCQkgICAgKGN1cnJlbnQtPmV1aWQgIT0gcnVpZCkgJiYKCQkgICAgIWNhcGFibGUoQ0FQX1NFVFVJRCkpCgkJCXJldHVybiAtRVBFUk07Cgl9CgoJaWYgKGV1aWQgIT0gKHVpZF90KSAtMSkgewoJCW5ld19ldWlkID0gZXVpZDsKCQlpZiAoKG9sZF9ydWlkICE9IGV1aWQpICYmCgkJICAgIChjdXJyZW50LT5ldWlkICE9IGV1aWQpICYmCgkJICAgIChjdXJyZW50LT5zdWlkICE9IGV1aWQpICYmCgkJICAgICFjYXBhYmxlKENBUF9TRVRVSUQpKQoJCQlyZXR1cm4gLUVQRVJNOwoJfQoKCWlmIChuZXdfcnVpZCAhPSBvbGRfcnVpZCAmJiBzZXRfdXNlcihuZXdfcnVpZCwgbmV3X2V1aWQgIT0gb2xkX2V1aWQpIDwgMCkKCQlyZXR1cm4gLUVBR0FJTjsKCglpZiAobmV3X2V1aWQgIT0gb2xkX2V1aWQpCgl7CgkJY3VycmVudC0+bW0tPmR1bXBhYmxlID0gc3VpZF9kdW1wYWJsZTsKCQlzbXBfd21iKCk7Cgl9CgljdXJyZW50LT5mc3VpZCA9IGN1cnJlbnQtPmV1aWQgPSBuZXdfZXVpZDsKCWlmIChydWlkICE9ICh1aWRfdCkgLTEgfHwKCSAgICAoZXVpZCAhPSAodWlkX3QpIC0xICYmIGV1aWQgIT0gb2xkX3J1aWQpKQoJCWN1cnJlbnQtPnN1aWQgPSBjdXJyZW50LT5ldWlkOwoJY3VycmVudC0+ZnN1aWQgPSBjdXJyZW50LT5ldWlkOwoKCWtleV9mc3VpZF9jaGFuZ2VkKGN1cnJlbnQpOwoJcHJvY19pZF9jb25uZWN0b3IoY3VycmVudCwgUFJPQ19FVkVOVF9VSUQpOwoKCXJldHVybiBzZWN1cml0eV90YXNrX3Bvc3Rfc2V0dWlkKG9sZF9ydWlkLCBvbGRfZXVpZCwgb2xkX3N1aWQsIExTTV9TRVRJRF9SRSk7Cn0KCgoJCQovKgogKiBzZXR1aWQoKSBpcyBpbXBsZW1lbnRlZCBsaWtlIFN5c1Ygd2l0aCBTQVZFRF9JRFMgCiAqIAogKiBOb3RlIHRoYXQgU0FWRURfSUQncyBpcyBkZWZpY2llbnQgaW4gdGhhdCBhIHNldHVpZCByb290IHByb2dyYW0KICogbGlrZSBzZW5kbWFpbCwgZm9yIGV4YW1wbGUsIGNhbm5vdCBzZXQgaXRzIHVpZCB0byBiZSBhIG5vcm1hbCAKICogdXNlciBhbmQgdGhlbiBzd2l0Y2ggYmFjaywgYmVjYXVzZSBpZiB5b3UncmUgcm9vdCwgc2V0dWlkKCkgc2V0cwogKiB0aGUgc2F2ZWQgdWlkIHRvby4gIElmIHlvdSBkb24ndCBsaWtlIHRoaXMsIGJsYW1lIHRoZSBicmlnaHQgcGVvcGxlCiAqIGluIHRoZSBQT1NJWCBjb21taXR0ZWUgYW5kL29yIFVTRy4gIE5vdGUgdGhhdCB0aGUgQlNELXN0eWxlIHNldHJldWlkKCkKICogd2lsbCBhbGxvdyBhIHJvb3QgcHJvZ3JhbSB0byB0ZW1wb3JhcmlseSBkcm9wIHByaXZpbGVnZXMgYW5kIGJlIGFibGUgdG8KICogcmVnYWluIHRoZW0gYnkgc3dhcHBpbmcgdGhlIHJlYWwgYW5kIGVmZmVjdGl2ZSB1aWQuICAKICovCmFzbWxpbmthZ2UgbG9uZyBzeXNfc2V0dWlkKHVpZF90IHVpZCkKewoJaW50IG9sZF9ldWlkID0gY3VycmVudC0+ZXVpZDsKCWludCBvbGRfcnVpZCwgb2xkX3N1aWQsIG5ld19ydWlkLCBuZXdfc3VpZDsKCWludCByZXR2YWw7CgoJcmV0dmFsID0gc2VjdXJpdHlfdGFza19zZXR1aWQodWlkLCAodWlkX3QpLTEsICh1aWRfdCktMSwgTFNNX1NFVElEX0lEKTsKCWlmIChyZXR2YWwpCgkJcmV0dXJuIHJldHZhbDsKCglvbGRfcnVpZCA9IG5ld19ydWlkID0gY3VycmVudC0+dWlkOwoJb2xkX3N1aWQgPSBjdXJyZW50LT5zdWlkOwoJbmV3X3N1aWQgPSBvbGRfc3VpZDsKCQoJaWYgKGNhcGFibGUoQ0FQX1NFVFVJRCkpIHsKCQlpZiAodWlkICE9IG9sZF9ydWlkICYmIHNldF91c2VyKHVpZCwgb2xkX2V1aWQgIT0gdWlkKSA8IDApCgkJCXJldHVybiAtRUFHQUlOOwoJCW5ld19zdWlkID0gdWlkOwoJfSBlbHNlIGlmICgodWlkICE9IGN1cnJlbnQtPnVpZCkgJiYgKHVpZCAhPSBuZXdfc3VpZCkpCgkJcmV0dXJuIC1FUEVSTTsKCglpZiAob2xkX2V1aWQgIT0gdWlkKQoJewoJCWN1cnJlbnQtPm1tLT5kdW1wYWJsZSA9IHN1aWRfZHVtcGFibGU7CgkJc21wX3dtYigpOwoJfQoJY3VycmVudC0+ZnN1aWQgPSBjdXJyZW50LT5ldWlkID0gdWlkOwoJY3VycmVudC0+c3VpZCA9IG5ld19zdWlkOwoKCWtleV9mc3VpZF9jaGFuZ2VkKGN1cnJlbnQpOwoJcHJvY19pZF9jb25uZWN0b3IoY3VycmVudCwgUFJPQ19FVkVOVF9VSUQpOwoKCXJldHVybiBzZWN1cml0eV90YXNrX3Bvc3Rfc2V0dWlkKG9sZF9ydWlkLCBvbGRfZXVpZCwgb2xkX3N1aWQsIExTTV9TRVRJRF9JRCk7Cn0KCgovKgogKiBUaGlzIGZ1bmN0aW9uIGltcGxlbWVudHMgYSBnZW5lcmljIGFiaWxpdHkgdG8gdXBkYXRlIHJ1aWQsIGV1aWQsCiAqIGFuZCBzdWlkLiAgVGhpcyBhbGxvd3MgeW91IHRvIGltcGxlbWVudCB0aGUgNC40IGNvbXBhdGlibGUgc2V0ZXVpZCgpLgogKi8KYXNtbGlua2FnZSBsb25nIHN5c19zZXRyZXN1aWQodWlkX3QgcnVpZCwgdWlkX3QgZXVpZCwgdWlkX3Qgc3VpZCkKewoJaW50IG9sZF9ydWlkID0gY3VycmVudC0+dWlkOwoJaW50IG9sZF9ldWlkID0gY3VycmVudC0+ZXVpZDsKCWludCBvbGRfc3VpZCA9IGN1cnJlbnQtPnN1aWQ7CglpbnQgcmV0dmFsOwoKCXJldHZhbCA9IHNlY3VyaXR5X3Rhc2tfc2V0dWlkKHJ1aWQsIGV1aWQsIHN1aWQsIExTTV9TRVRJRF9SRVMpOwoJaWYgKHJldHZhbCkKCQlyZXR1cm4gcmV0dmFsOwoKCWlmICghY2FwYWJsZShDQVBfU0VUVUlEKSkgewoJCWlmICgocnVpZCAhPSAodWlkX3QpIC0xKSAmJiAocnVpZCAhPSBjdXJyZW50LT51aWQpICYmCgkJICAgIChydWlkICE9IGN1cnJlbnQtPmV1aWQpICYmIChydWlkICE9IGN1cnJlbnQtPnN1aWQpKQoJCQlyZXR1cm4gLUVQRVJNOwoJCWlmICgoZXVpZCAhPSAodWlkX3QpIC0xKSAmJiAoZXVpZCAhPSBjdXJyZW50LT51aWQpICYmCgkJICAgIChldWlkICE9IGN1cnJlbnQtPmV1aWQpICYmIChldWlkICE9IGN1cnJlbnQtPnN1aWQpKQoJCQlyZXR1cm4gLUVQRVJNOwoJCWlmICgoc3VpZCAhPSAodWlkX3QpIC0xKSAmJiAoc3VpZCAhPSBjdXJyZW50LT51aWQpICYmCgkJICAgIChzdWlkICE9IGN1cnJlbnQtPmV1aWQpICYmIChzdWlkICE9IGN1cnJlbnQtPnN1aWQpKQoJCQlyZXR1cm4gLUVQRVJNOwoJfQoJaWYgKHJ1aWQgIT0gKHVpZF90KSAtMSkgewoJCWlmIChydWlkICE9IGN1cnJlbnQtPnVpZCAmJiBzZXRfdXNlcihydWlkLCBldWlkICE9IGN1cnJlbnQtPmV1aWQpIDwgMCkKCQkJcmV0dXJuIC1FQUdBSU47Cgl9CglpZiAoZXVpZCAhPSAodWlkX3QpIC0xKSB7CgkJaWYgKGV1aWQgIT0gY3VycmVudC0+ZXVpZCkKCQl7CgkJCWN1cnJlbnQtPm1tLT5kdW1wYWJsZSA9IHN1aWRfZHVtcGFibGU7CgkJCXNtcF93bWIoKTsKCQl9CgkJY3VycmVudC0+ZXVpZCA9IGV1aWQ7Cgl9CgljdXJyZW50LT5mc3VpZCA9IGN1cnJlbnQtPmV1aWQ7CglpZiAoc3VpZCAhPSAodWlkX3QpIC0xKQoJCWN1cnJlbnQtPnN1aWQgPSBzdWlkOwoKCWtleV9mc3VpZF9jaGFuZ2VkKGN1cnJlbnQpOwoJcHJvY19pZF9jb25uZWN0b3IoY3VycmVudCwgUFJPQ19FVkVOVF9VSUQpOwoKCXJldHVybiBzZWN1cml0eV90YXNrX3Bvc3Rfc2V0dWlkKG9sZF9ydWlkLCBvbGRfZXVpZCwgb2xkX3N1aWQsIExTTV9TRVRJRF9SRVMpOwp9Cgphc21saW5rYWdlIGxvbmcgc3lzX2dldHJlc3VpZCh1aWRfdCBfX3VzZXIgKnJ1aWQsIHVpZF90IF9fdXNlciAqZXVpZCwgdWlkX3QgX191c2VyICpzdWlkKQp7CglpbnQgcmV0dmFsOwoKCWlmICghKHJldHZhbCA9IHB1dF91c2VyKGN1cnJlbnQtPnVpZCwgcnVpZCkpICYmCgkgICAgIShyZXR2YWwgPSBwdXRfdXNlcihjdXJyZW50LT5ldWlkLCBldWlkKSkpCgkJcmV0dmFsID0gcHV0X3VzZXIoY3VycmVudC0+c3VpZCwgc3VpZCk7CgoJcmV0dXJuIHJldHZhbDsKfQoKLyoKICogU2FtZSBhcyBhYm92ZSwgYnV0IGZvciByZ2lkLCBlZ2lkLCBzZ2lkLgogKi8KYXNtbGlua2FnZSBsb25nIHN5c19zZXRyZXNnaWQoZ2lkX3QgcmdpZCwgZ2lkX3QgZWdpZCwgZ2lkX3Qgc2dpZCkKewoJaW50IHJldHZhbDsKCglyZXR2YWwgPSBzZWN1cml0eV90YXNrX3NldGdpZChyZ2lkLCBlZ2lkLCBzZ2lkLCBMU01fU0VUSURfUkVTKTsKCWlmIChyZXR2YWwpCgkJcmV0dXJuIHJldHZhbDsKCglpZiAoIWNhcGFibGUoQ0FQX1NFVEdJRCkpIHsKCQlpZiAoKHJnaWQgIT0gKGdpZF90KSAtMSkgJiYgKHJnaWQgIT0gY3VycmVudC0+Z2lkKSAmJgoJCSAgICAocmdpZCAhPSBjdXJyZW50LT5lZ2lkKSAmJiAocmdpZCAhPSBjdXJyZW50LT5zZ2lkKSkKCQkJcmV0dXJuIC1FUEVSTTsKCQlpZiAoKGVnaWQgIT0gKGdpZF90KSAtMSkgJiYgKGVnaWQgIT0gY3VycmVudC0+Z2lkKSAmJgoJCSAgICAoZWdpZCAhPSBjdXJyZW50LT5lZ2lkKSAmJiAoZWdpZCAhPSBjdXJyZW50LT5zZ2lkKSkKCQkJcmV0dXJuIC1FUEVSTTsKCQlpZiAoKHNnaWQgIT0gKGdpZF90KSAtMSkgJiYgKHNnaWQgIT0gY3VycmVudC0+Z2lkKSAmJgoJCSAgICAoc2dpZCAhPSBjdXJyZW50LT5lZ2lkKSAmJiAoc2dpZCAhPSBjdXJyZW50LT5zZ2lkKSkKCQkJcmV0dXJuIC1FUEVSTTsKCX0KCWlmIChlZ2lkICE9IChnaWRfdCkgLTEpIHsKCQlpZiAoZWdpZCAhPSBjdXJyZW50LT5lZ2lkKQoJCXsKCQkJY3VycmVudC0+bW0tPmR1bXBhYmxlID0gc3VpZF9kdW1wYWJsZTsKCQkJc21wX3dtYigpOwoJCX0KCQljdXJyZW50LT5lZ2lkID0gZWdpZDsKCX0KCWN1cnJlbnQtPmZzZ2lkID0gY3VycmVudC0+ZWdpZDsKCWlmIChyZ2lkICE9IChnaWRfdCkgLTEpCgkJY3VycmVudC0+Z2lkID0gcmdpZDsKCWlmIChzZ2lkICE9IChnaWRfdCkgLTEpCgkJY3VycmVudC0+c2dpZCA9IHNnaWQ7CgoJa2V5X2ZzZ2lkX2NoYW5nZWQoY3VycmVudCk7Cglwcm9jX2lkX2Nvbm5lY3RvcihjdXJyZW50LCBQUk9DX0VWRU5UX0dJRCk7CglyZXR1cm4gMDsKfQoKYXNtbGlua2FnZSBsb25nIHN5c19nZXRyZXNnaWQoZ2lkX3QgX191c2VyICpyZ2lkLCBnaWRfdCBfX3VzZXIgKmVnaWQsIGdpZF90IF9fdXNlciAqc2dpZCkKewoJaW50IHJldHZhbDsKCglpZiAoIShyZXR2YWwgPSBwdXRfdXNlcihjdXJyZW50LT5naWQsIHJnaWQpKSAmJgoJICAgICEocmV0dmFsID0gcHV0X3VzZXIoY3VycmVudC0+ZWdpZCwgZWdpZCkpKQoJCXJldHZhbCA9IHB1dF91c2VyKGN1cnJlbnQtPnNnaWQsIHNnaWQpOwoKCXJldHVybiByZXR2YWw7Cn0KCgovKgogKiAic2V0ZnN1aWQoKSIgc2V0cyB0aGUgZnN1aWQgLSB0aGUgdWlkIHVzZWQgZm9yIGZpbGVzeXN0ZW0gY2hlY2tzLiBUaGlzCiAqIGlzIHVzZWQgZm9yICJhY2Nlc3MoKSIgYW5kIGZvciB0aGUgTkZTIGRhZW1vbiAobGV0dGluZyBuZnNkIHN0YXkgYXQKICogd2hhdGV2ZXIgdWlkIGl0IHdhbnRzIHRvKS4gSXQgbm9ybWFsbHkgc2hhZG93cyAiZXVpZCIsIGV4Y2VwdCB3aGVuCiAqIGV4cGxpY2l0bHkgc2V0IGJ5IHNldGZzdWlkKCkgb3IgZm9yIGFjY2Vzcy4uCiAqLwphc21saW5rYWdlIGxvbmcgc3lzX3NldGZzdWlkKHVpZF90IHVpZCkKewoJaW50IG9sZF9mc3VpZDsKCglvbGRfZnN1aWQgPSBjdXJyZW50LT5mc3VpZDsKCWlmIChzZWN1cml0eV90YXNrX3NldHVpZCh1aWQsICh1aWRfdCktMSwgKHVpZF90KS0xLCBMU01fU0VUSURfRlMpKQoJCXJldHVybiBvbGRfZnN1aWQ7CgoJaWYgKHVpZCA9PSBjdXJyZW50LT51aWQgfHwgdWlkID09IGN1cnJlbnQtPmV1aWQgfHwKCSAgICB1aWQgPT0gY3VycmVudC0+c3VpZCB8fCB1aWQgPT0gY3VycmVudC0+ZnN1aWQgfHwgCgkgICAgY2FwYWJsZShDQVBfU0VUVUlEKSkKCXsKCQlpZiAodWlkICE9IG9sZF9mc3VpZCkKCQl7CgkJCWN1cnJlbnQtPm1tLT5kdW1wYWJsZSA9IHN1aWRfZHVtcGFibGU7CgkJCXNtcF93bWIoKTsKCQl9CgkJY3VycmVudC0+ZnN1aWQgPSB1aWQ7Cgl9CgoJa2V5X2ZzdWlkX2NoYW5nZWQoY3VycmVudCk7Cglwcm9jX2lkX2Nvbm5lY3RvcihjdXJyZW50LCBQUk9DX0VWRU5UX1VJRCk7CgoJc2VjdXJpdHlfdGFza19wb3N0X3NldHVpZChvbGRfZnN1aWQsICh1aWRfdCktMSwgKHVpZF90KS0xLCBMU01fU0VUSURfRlMpOwoKCXJldHVybiBvbGRfZnN1aWQ7Cn0KCi8qCiAqIFNhbW1hIHDlIHN2ZW5za2EuLgogKi8KYXNtbGlua2FnZSBsb25nIHN5c19zZXRmc2dpZChnaWRfdCBnaWQpCnsKCWludCBvbGRfZnNnaWQ7CgoJb2xkX2ZzZ2lkID0gY3VycmVudC0+ZnNnaWQ7CglpZiAoc2VjdXJpdHlfdGFza19zZXRnaWQoZ2lkLCAoZ2lkX3QpLTEsIChnaWRfdCktMSwgTFNNX1NFVElEX0ZTKSkKCQlyZXR1cm4gb2xkX2ZzZ2lkOwoKCWlmIChnaWQgPT0gY3VycmVudC0+Z2lkIHx8IGdpZCA9PSBjdXJyZW50LT5lZ2lkIHx8CgkgICAgZ2lkID09IGN1cnJlbnQtPnNnaWQgfHwgZ2lkID09IGN1cnJlbnQtPmZzZ2lkIHx8IAoJICAgIGNhcGFibGUoQ0FQX1NFVEdJRCkpCgl7CgkJaWYgKGdpZCAhPSBvbGRfZnNnaWQpCgkJewoJCQljdXJyZW50LT5tbS0+ZHVtcGFibGUgPSBzdWlkX2R1bXBhYmxlOwoJCQlzbXBfd21iKCk7CgkJfQoJCWN1cnJlbnQtPmZzZ2lkID0gZ2lkOwoJCWtleV9mc2dpZF9jaGFuZ2VkKGN1cnJlbnQpOwoJCXByb2NfaWRfY29ubmVjdG9yKGN1cnJlbnQsIFBST0NfRVZFTlRfR0lEKTsKCX0KCXJldHVybiBvbGRfZnNnaWQ7Cn0KCmFzbWxpbmthZ2UgbG9uZyBzeXNfdGltZXMoc3RydWN0IHRtcyBfX3VzZXIgKiB0YnVmKQp7CgkvKgoJICoJSW4gdGhlIFNNUCB3b3JsZCB3ZSBtaWdodCBqdXN0IGJlIHVubHVja3kgYW5kIGhhdmUgb25lIG9mCgkgKgl0aGUgdGltZXMgaW5jcmVtZW50IGFzIHdlIHVzZSBpdC4gU2luY2UgdGhlIHZhbHVlIGlzIGFuCgkgKglhdG9taWNhbGx5IHNhZmUgdHlwZSB0aGlzIGlzIGp1c3QgZmluZS4gQ29uY2VwdHVhbGx5IGl0cwoJICoJYXMgaWYgdGhlIHN5c2NhbGwgdG9vayBhbiBpbnN0YW50IGxvbmdlciB0byBvY2N1ci4KCSAqLwoJaWYgKHRidWYpIHsKCQlzdHJ1Y3QgdG1zIHRtcDsKCQljcHV0aW1lX3QgdXRpbWUsIHN0aW1lLCBjdXRpbWUsIGNzdGltZTsKCiNpZmRlZiBDT05GSUdfU01QCgkJaWYgKHRocmVhZF9ncm91cF9lbXB0eShjdXJyZW50KSkgewoJCQkvKgoJCQkgKiBTaW5nbGUgdGhyZWFkIGNhc2Ugd2l0aG91dCB0aGUgdXNlIG9mIGFueSBsb2Nrcy4KCQkJICoKCQkJICogV2UgbWF5IHJhY2Ugd2l0aCByZWxlYXNlX3Rhc2sgaWYgdHdvIHRocmVhZHMgYXJlCgkJCSAqIGV4ZWN1dGluZy4gSG93ZXZlciwgcmVsZWFzZSB0YXNrIGZpcnN0IGFkZHMgdXAgdGhlCgkJCSAqIGNvdW50ZXJzIChfX2V4aXRfc2lnbmFsKSBiZWZvcmUgIHJlbW92aW5nIHRoZSB0YXNrCgkJCSAqIGZyb20gdGhlIHByb2Nlc3MgdGFza2xpc3QgKF9fdW5oYXNoX3Byb2Nlc3MpLgoJCQkgKiBfX2V4aXRfc2lnbmFsIGFsc28gYWNxdWlyZXMgYW5kIHJlbGVhc2VzIHRoZQoJCQkgKiBzaWdsb2NrIHdoaWNoIHJlc3VsdHMgaW4gdGhlIHByb3BlciBtZW1vcnkgb3JkZXJpbmcKCQkJICogc28gdGhhdCB0aGUgbGlzdCBtb2RpZmljYXRpb25zIGFyZSBhbHdheXMgdmlzaWJsZQoJCQkgKiBhZnRlciB0aGUgY291bnRlcnMgaGF2ZSBiZWVuIHVwZGF0ZWQuCgkJCSAqCgkJCSAqIElmIHRoZSBjb3VudGVycyBoYXZlIGJlZW4gdXBkYXRlZCBieSB0aGUgc2Vjb25kIHRocmVhZAoJCQkgKiBidXQgdGhlIHRocmVhZCBoYXMgbm90IHlldCBiZWVuIHJlbW92ZWQgZnJvbSB0aGUgbGlzdAoJCQkgKiB0aGVuIHRoZSBvdGhlciBicmFuY2ggd2lsbCBiZSBleGVjdXRpbmcgd2hpY2ggd2lsbAoJCQkgKiBibG9jayBvbiB0YXNrbGlzdF9sb2NrIHVudGlsIHRoZSBleGl0IGhhbmRsaW5nIG9mIHRoZQoJCQkgKiBvdGhlciB0YXNrIGlzIGZpbmlzaGVkLgoJCQkgKgoJCQkgKiBUaGlzIGFsc28gaW1wbGllcyB0aGF0IHRoZSBzaWdoYW5kLT5zaWdsb2NrIGNhbm5vdAoJCQkgKiBiZSBoZWxkIGJ5IGFub3RoZXIgcHJvY2Vzc29yLiBTbyB3ZSBjYW4gYWxzbwoJCQkgKiBza2lwIGFjcXVpcmluZyB0aGF0IGxvY2suCgkJCSAqLwoJCQl1dGltZSA9IGNwdXRpbWVfYWRkKGN1cnJlbnQtPnNpZ25hbC0+dXRpbWUsIGN1cnJlbnQtPnV0aW1lKTsKCQkJc3RpbWUgPSBjcHV0aW1lX2FkZChjdXJyZW50LT5zaWduYWwtPnV0aW1lLCBjdXJyZW50LT5zdGltZSk7CgkJCWN1dGltZSA9IGN1cnJlbnQtPnNpZ25hbC0+Y3V0aW1lOwoJCQljc3RpbWUgPSBjdXJyZW50LT5zaWduYWwtPmNzdGltZTsKCQl9IGVsc2UKI2VuZGlmCgkJewoKCQkJLyogUHJvY2VzcyB3aXRoIG11bHRpcGxlIHRocmVhZHMgKi8KCQkJc3RydWN0IHRhc2tfc3RydWN0ICp0c2sgPSBjdXJyZW50OwoJCQlzdHJ1Y3QgdGFza19zdHJ1Y3QgKnQ7CgoJCQlyZWFkX2xvY2soJnRhc2tsaXN0X2xvY2spOwoJCQl1dGltZSA9IHRzay0+c2lnbmFsLT51dGltZTsKCQkJc3RpbWUgPSB0c2stPnNpZ25hbC0+c3RpbWU7CgkJCXQgPSB0c2s7CgkJCWRvIHsKCQkJCXV0aW1lID0gY3B1dGltZV9hZGQodXRpbWUsIHQtPnV0aW1lKTsKCQkJCXN0aW1lID0gY3B1dGltZV9hZGQoc3RpbWUsIHQtPnN0aW1lKTsKCQkJCXQgPSBuZXh0X3RocmVhZCh0KTsKCQkJfSB3aGlsZSAodCAhPSB0c2spOwoKCQkJLyoKCQkJICogV2hpbGUgd2UgaGF2ZSB0YXNrbGlzdF9sb2NrIHJlYWQtbG9ja2VkLCBubyBkeWluZyB0aHJlYWQKCQkJICogY2FuIGJlIHVwZGF0aW5nIGN1cnJlbnQtPnNpZ25hbC0+W3VzXXRpbWUuICBJbnN0ZWFkLAoJCQkgKiB3ZSBnb3QgdGhlaXIgY291bnRzIGluY2x1ZGVkIGluIHRoZSBsaXZlIHRocmVhZCBsb29wLgoJCQkgKiBIb3dldmVyLCBhbm90aGVyIHRocmVhZCBjYW4gY29tZSBpbiByaWdodCBub3cgYW5kCgkJCSAqIGRvIGEgd2FpdCBjYWxsIHRoYXQgdXBkYXRlcyBjdXJyZW50LT5zaWduYWwtPmNbdXNddGltZS4KCQkJICogVG8gbWFrZSBzdXJlIHdlIGFsd2F5cyBzZWUgdGhhdCBwYWlyIHVwZGF0ZWQgYXRvbWljYWxseSwKCQkJICogd2UgdGFrZSB0aGUgc2lnbG9jayBhcm91bmQgZmV0Y2hpbmcgdGhlbS4KCQkJICovCgkJCXNwaW5fbG9ja19pcnEoJnRzay0+c2lnaGFuZC0+c2lnbG9jayk7CgkJCWN1dGltZSA9IHRzay0+c2lnbmFsLT5jdXRpbWU7CgkJCWNzdGltZSA9IHRzay0+c2lnbmFsLT5jc3RpbWU7CgkJCXNwaW5fdW5sb2NrX2lycSgmdHNrLT5zaWdoYW5kLT5zaWdsb2NrKTsKCQkJcmVhZF91bmxvY2soJnRhc2tsaXN0X2xvY2spOwoJCX0KCQl0bXAudG1zX3V0aW1lID0gY3B1dGltZV90b19jbG9ja190KHV0aW1lKTsKCQl0bXAudG1zX3N0aW1lID0gY3B1dGltZV90b19jbG9ja190KHN0aW1lKTsKCQl0bXAudG1zX2N1dGltZSA9IGNwdXRpbWVfdG9fY2xvY2tfdChjdXRpbWUpOwoJCXRtcC50bXNfY3N0aW1lID0gY3B1dGltZV90b19jbG9ja190KGNzdGltZSk7CgkJaWYgKGNvcHlfdG9fdXNlcih0YnVmLCAmdG1wLCBzaXplb2Yoc3RydWN0IHRtcykpKQoJCQlyZXR1cm4gLUVGQVVMVDsKCX0KCXJldHVybiAobG9uZykgamlmZmllc182NF90b19jbG9ja190KGdldF9qaWZmaWVzXzY0KCkpOwp9CgovKgogKiBUaGlzIG5lZWRzIHNvbWUgaGVhdnkgY2hlY2tpbmcgLi4uCiAqIEkganVzdCBoYXZlbid0IHRoZSBzdG9tYWNoIGZvciBpdC4gSSBhbHNvIGRvbid0IGZ1bGx5CiAqIHVuZGVyc3RhbmQgc2Vzc2lvbnMvcGdycCBldGMuIExldCBzb21lYm9keSB3aG8gZG9lcyBleHBsYWluIGl0LgogKgogKiBPSywgSSB0aGluayBJIGhhdmUgdGhlIHByb3RlY3Rpb24gc2VtYW50aWNzIHJpZ2h0Li4uLiB0aGlzIGlzIHJlYWxseQogKiBvbmx5IGltcG9ydGFudCBvbiBhIG11bHRpLXVzZXIgc3lzdGVtIGFueXdheSwgdG8gbWFrZSBzdXJlIG9uZSB1c2VyCiAqIGNhbid0IHNlbmQgYSBzaWduYWwgdG8gYSBwcm9jZXNzIG93bmVkIGJ5IGFub3RoZXIuICAtVFlULCAxMi8xMi85MQogKgogKiBBdWNoLiBIYWQgdG8gYWRkIHRoZSAnZGlkX2V4ZWMnIGZsYWcgdG8gY29uZm9ybSBjb21wbGV0ZWx5IHRvIFBPU0lYLgogKiBMQlQgMDQuMDMuOTQKICovCgphc21saW5rYWdlIGxvbmcgc3lzX3NldHBnaWQocGlkX3QgcGlkLCBwaWRfdCBwZ2lkKQp7CglzdHJ1Y3QgdGFza19zdHJ1Y3QgKnA7CglzdHJ1Y3QgdGFza19zdHJ1Y3QgKmdyb3VwX2xlYWRlciA9IGN1cnJlbnQtPmdyb3VwX2xlYWRlcjsKCWludCBlcnIgPSAtRUlOVkFMOwoKCWlmICghcGlkKQoJCXBpZCA9IGdyb3VwX2xlYWRlci0+cGlkOwoJaWYgKCFwZ2lkKQoJCXBnaWQgPSBwaWQ7CglpZiAocGdpZCA8IDApCgkJcmV0dXJuIC1FSU5WQUw7CgoJLyogRnJvbSB0aGlzIHBvaW50IGZvcndhcmQgd2Uga2VlcCBob2xkaW5nIG9udG8gdGhlIHRhc2tsaXN0IGxvY2sKCSAqIHNvIHRoYXQgb3VyIHBhcmVudCBkb2VzIG5vdCBjaGFuZ2UgZnJvbSB1bmRlciB1cy4gLURhdmVNCgkgKi8KCXdyaXRlX2xvY2tfaXJxKCZ0YXNrbGlzdF9sb2NrKTsKCgllcnIgPSAtRVNSQ0g7CglwID0gZmluZF90YXNrX2J5X3BpZChwaWQpOwoJaWYgKCFwKQoJCWdvdG8gb3V0OwoKCWVyciA9IC1FSU5WQUw7CglpZiAoIXRocmVhZF9ncm91cF9sZWFkZXIocCkpCgkJZ290byBvdXQ7CgoJaWYgKHAtPnJlYWxfcGFyZW50ID09IGdyb3VwX2xlYWRlcikgewoJCWVyciA9IC1FUEVSTTsKCQlpZiAocC0+c2lnbmFsLT5zZXNzaW9uICE9IGdyb3VwX2xlYWRlci0+c2lnbmFsLT5zZXNzaW9uKQoJCQlnb3RvIG91dDsKCQllcnIgPSAtRUFDQ0VTOwoJCWlmIChwLT5kaWRfZXhlYykKCQkJZ290byBvdXQ7Cgl9IGVsc2UgewoJCWVyciA9IC1FU1JDSDsKCQlpZiAocCAhPSBncm91cF9sZWFkZXIpCgkJCWdvdG8gb3V0OwoJfQoKCWVyciA9IC1FUEVSTTsKCWlmIChwLT5zaWduYWwtPmxlYWRlcikKCQlnb3RvIG91dDsKCglpZiAocGdpZCAhPSBwaWQpIHsKCQlzdHJ1Y3QgdGFza19zdHJ1Y3QgKnA7CgoJCWRvX2VhY2hfdGFza19waWQocGdpZCwgUElEVFlQRV9QR0lELCBwKSB7CgkJCWlmIChwLT5zaWduYWwtPnNlc3Npb24gPT0gZ3JvdXBfbGVhZGVyLT5zaWduYWwtPnNlc3Npb24pCgkJCQlnb3RvIG9rX3BnaWQ7CgkJfSB3aGlsZV9lYWNoX3Rhc2tfcGlkKHBnaWQsIFBJRFRZUEVfUEdJRCwgcCk7CgkJZ290byBvdXQ7Cgl9Cgpva19wZ2lkOgoJZXJyID0gc2VjdXJpdHlfdGFza19zZXRwZ2lkKHAsIHBnaWQpOwoJaWYgKGVycikKCQlnb3RvIG91dDsKCglpZiAocHJvY2Vzc19ncm91cChwKSAhPSBwZ2lkKSB7CgkJZGV0YWNoX3BpZChwLCBQSURUWVBFX1BHSUQpOwoJCXAtPnNpZ25hbC0+cGdycCA9IHBnaWQ7CgkJYXR0YWNoX3BpZChwLCBQSURUWVBFX1BHSUQsIHBnaWQpOwoJfQoKCWVyciA9IDA7Cm91dDoKCS8qIEFsbCBwYXRocyBsZWFkIHRvIGhlcmUsIHRodXMgd2UgYXJlIHNhZmUuIC1EYXZlTSAqLwoJd3JpdGVfdW5sb2NrX2lycSgmdGFza2xpc3RfbG9jayk7CglyZXR1cm4gZXJyOwp9Cgphc21saW5rYWdlIGxvbmcgc3lzX2dldHBnaWQocGlkX3QgcGlkKQp7CglpZiAoIXBpZCkgewoJCXJldHVybiBwcm9jZXNzX2dyb3VwKGN1cnJlbnQpOwoJfSBlbHNlIHsKCQlpbnQgcmV0dmFsOwoJCXN0cnVjdCB0YXNrX3N0cnVjdCAqcDsKCgkJcmVhZF9sb2NrKCZ0YXNrbGlzdF9sb2NrKTsKCQlwID0gZmluZF90YXNrX2J5X3BpZChwaWQpOwoKCQlyZXR2YWwgPSAtRVNSQ0g7CgkJaWYgKHApIHsKCQkJcmV0dmFsID0gc2VjdXJpdHlfdGFza19nZXRwZ2lkKHApOwoJCQlpZiAoIXJldHZhbCkKCQkJCXJldHZhbCA9IHByb2Nlc3NfZ3JvdXAocCk7CgkJfQoJCXJlYWRfdW5sb2NrKCZ0YXNrbGlzdF9sb2NrKTsKCQlyZXR1cm4gcmV0dmFsOwoJfQp9CgojaWZkZWYgX19BUkNIX1dBTlRfU1lTX0dFVFBHUlAKCmFzbWxpbmthZ2UgbG9uZyBzeXNfZ2V0cGdycCh2b2lkKQp7CgkvKiBTTVAgLSBhc3N1bWluZyB3cml0ZXMgYXJlIHdvcmQgYXRvbWljIHRoaXMgaXMgZmluZSAqLwoJcmV0dXJuIHByb2Nlc3NfZ3JvdXAoY3VycmVudCk7Cn0KCiNlbmRpZgoKYXNtbGlua2FnZSBsb25nIHN5c19nZXRzaWQocGlkX3QgcGlkKQp7CglpZiAoIXBpZCkgewoJCXJldHVybiBjdXJyZW50LT5zaWduYWwtPnNlc3Npb247Cgl9IGVsc2UgewoJCWludCByZXR2YWw7CgkJc3RydWN0IHRhc2tfc3RydWN0ICpwOwoKCQlyZWFkX2xvY2soJnRhc2tsaXN0X2xvY2spOwoJCXAgPSBmaW5kX3Rhc2tfYnlfcGlkKHBpZCk7CgoJCXJldHZhbCA9IC1FU1JDSDsKCQlpZihwKSB7CgkJCXJldHZhbCA9IHNlY3VyaXR5X3Rhc2tfZ2V0c2lkKHApOwoJCQlpZiAoIXJldHZhbCkKCQkJCXJldHZhbCA9IHAtPnNpZ25hbC0+c2Vzc2lvbjsKCQl9CgkJcmVhZF91bmxvY2soJnRhc2tsaXN0X2xvY2spOwoJCXJldHVybiByZXR2YWw7Cgl9Cn0KCmFzbWxpbmthZ2UgbG9uZyBzeXNfc2V0c2lkKHZvaWQpCnsKCXN0cnVjdCB0YXNrX3N0cnVjdCAqZ3JvdXBfbGVhZGVyID0gY3VycmVudC0+Z3JvdXBfbGVhZGVyOwoJc3RydWN0IHBpZCAqcGlkOwoJaW50IGVyciA9IC1FUEVSTTsKCgltdXRleF9sb2NrKCZ0dHlfbXV0ZXgpOwoJd3JpdGVfbG9ja19pcnEoJnRhc2tsaXN0X2xvY2spOwoKCXBpZCA9IGZpbmRfcGlkKFBJRFRZUEVfUEdJRCwgZ3JvdXBfbGVhZGVyLT5waWQpOwoJaWYgKHBpZCkKCQlnb3RvIG91dDsKCglncm91cF9sZWFkZXItPnNpZ25hbC0+bGVhZGVyID0gMTsKCV9fc2V0X3NwZWNpYWxfcGlkcyhncm91cF9sZWFkZXItPnBpZCwgZ3JvdXBfbGVhZGVyLT5waWQpOwoJZ3JvdXBfbGVhZGVyLT5zaWduYWwtPnR0eSA9IE5VTEw7Cglncm91cF9sZWFkZXItPnNpZ25hbC0+dHR5X29sZF9wZ3JwID0gMDsKCWVyciA9IHByb2Nlc3NfZ3JvdXAoZ3JvdXBfbGVhZGVyKTsKb3V0OgoJd3JpdGVfdW5sb2NrX2lycSgmdGFza2xpc3RfbG9jayk7CgltdXRleF91bmxvY2soJnR0eV9tdXRleCk7CglyZXR1cm4gZXJyOwp9CgovKgogKiBTdXBwbGVtZW50YXJ5IGdyb3VwIElEcwogKi8KCi8qIGluaXQgdG8gMiAtIG9uZSBmb3IgaW5pdF90YXNrLCBvbmUgdG8gZW5zdXJlIGl0IGlzIG5ldmVyIGZyZWVkICovCnN0cnVjdCBncm91cF9pbmZvIGluaXRfZ3JvdXBzID0geyAudXNhZ2UgPSBBVE9NSUNfSU5JVCgyKSB9OwoKc3RydWN0IGdyb3VwX2luZm8gKmdyb3Vwc19hbGxvYyhpbnQgZ2lkc2V0c2l6ZSkKewoJc3RydWN0IGdyb3VwX2luZm8gKmdyb3VwX2luZm87CglpbnQgbmJsb2NrczsKCWludCBpOwoKCW5ibG9ja3MgPSAoZ2lkc2V0c2l6ZSArIE5HUk9VUFNfUEVSX0JMT0NLIC0gMSkgLyBOR1JPVVBTX1BFUl9CTE9DSzsKCS8qIE1ha2Ugc3VyZSB3ZSBhbHdheXMgYWxsb2NhdGUgYXQgbGVhc3Qgb25lIGluZGlyZWN0IGJsb2NrIHBvaW50ZXIgKi8KCW5ibG9ja3MgPSBuYmxvY2tzID8gOiAxOwoJZ3JvdXBfaW5mbyA9IGttYWxsb2Moc2l6ZW9mKCpncm91cF9pbmZvKSArIG5ibG9ja3Mqc2l6ZW9mKGdpZF90ICopLCBHRlBfVVNFUik7CglpZiAoIWdyb3VwX2luZm8pCgkJcmV0dXJuIE5VTEw7Cglncm91cF9pbmZvLT5uZ3JvdXBzID0gZ2lkc2V0c2l6ZTsKCWdyb3VwX2luZm8tPm5ibG9ja3MgPSBuYmxvY2tzOwoJYXRvbWljX3NldCgmZ3JvdXBfaW5mby0+dXNhZ2UsIDEpOwoKCWlmIChnaWRzZXRzaXplIDw9IE5HUk9VUFNfU01BTEwpIHsKCQlncm91cF9pbmZvLT5ibG9ja3NbMF0gPSBncm91cF9pbmZvLT5zbWFsbF9ibG9jazsKCX0gZWxzZSB7CgkJZm9yIChpID0gMDsgaSA8IG5ibG9ja3M7IGkrKykgewoJCQlnaWRfdCAqYjsKCQkJYiA9ICh2b2lkICopX19nZXRfZnJlZV9wYWdlKEdGUF9VU0VSKTsKCQkJaWYgKCFiKQoJCQkJZ290byBvdXRfdW5kb19wYXJ0aWFsX2FsbG9jOwoJCQlncm91cF9pbmZvLT5ibG9ja3NbaV0gPSBiOwoJCX0KCX0KCXJldHVybiBncm91cF9pbmZvOwoKb3V0X3VuZG9fcGFydGlhbF9hbGxvYzoKCXdoaWxlICgtLWkgPj0gMCkgewoJCWZyZWVfcGFnZSgodW5zaWduZWQgbG9uZylncm91cF9pbmZvLT5ibG9ja3NbaV0pOwoJfQoJa2ZyZWUoZ3JvdXBfaW5mbyk7CglyZXR1cm4gTlVMTDsKfQoKRVhQT1JUX1NZTUJPTChncm91cHNfYWxsb2MpOwoKdm9pZCBncm91cHNfZnJlZShzdHJ1Y3QgZ3JvdXBfaW5mbyAqZ3JvdXBfaW5mbykKewoJaWYgKGdyb3VwX2luZm8tPmJsb2Nrc1swXSAhPSBncm91cF9pbmZvLT5zbWFsbF9ibG9jaykgewoJCWludCBpOwoJCWZvciAoaSA9IDA7IGkgPCBncm91cF9pbmZvLT5uYmxvY2tzOyBpKyspCgkJCWZyZWVfcGFnZSgodW5zaWduZWQgbG9uZylncm91cF9pbmZvLT5ibG9ja3NbaV0pOwoJfQoJa2ZyZWUoZ3JvdXBfaW5mbyk7Cn0KCkVYUE9SVF9TWU1CT0woZ3JvdXBzX2ZyZWUpOwoKLyogZXhwb3J0IHRoZSBncm91cF9pbmZvIHRvIGEgdXNlci1zcGFjZSBhcnJheSAqLwpzdGF0aWMgaW50IGdyb3Vwc190b191c2VyKGdpZF90IF9fdXNlciAqZ3JvdXBsaXN0LAogICAgc3RydWN0IGdyb3VwX2luZm8gKmdyb3VwX2luZm8pCnsKCWludCBpOwoJaW50IGNvdW50ID0gZ3JvdXBfaW5mby0+bmdyb3VwczsKCglmb3IgKGkgPSAwOyBpIDwgZ3JvdXBfaW5mby0+bmJsb2NrczsgaSsrKSB7CgkJaW50IGNwX2NvdW50ID0gbWluKE5HUk9VUFNfUEVSX0JMT0NLLCBjb3VudCk7CgkJaW50IG9mZiA9IGkgKiBOR1JPVVBTX1BFUl9CTE9DSzsKCQlpbnQgbGVuID0gY3BfY291bnQgKiBzaXplb2YoKmdyb3VwbGlzdCk7CgoJCWlmIChjb3B5X3RvX3VzZXIoZ3JvdXBsaXN0K29mZiwgZ3JvdXBfaW5mby0+YmxvY2tzW2ldLCBsZW4pKQoJCQlyZXR1cm4gLUVGQVVMVDsKCgkJY291bnQgLT0gY3BfY291bnQ7Cgl9CglyZXR1cm4gMDsKfQoKLyogZmlsbCBhIGdyb3VwX2luZm8gZnJvbSBhIHVzZXItc3BhY2UgYXJyYXkgLSBpdCBtdXN0IGJlIGFsbG9jYXRlZCBhbHJlYWR5ICovCnN0YXRpYyBpbnQgZ3JvdXBzX2Zyb21fdXNlcihzdHJ1Y3QgZ3JvdXBfaW5mbyAqZ3JvdXBfaW5mbywKICAgIGdpZF90IF9fdXNlciAqZ3JvdXBsaXN0KQogewoJaW50IGk7CglpbnQgY291bnQgPSBncm91cF9pbmZvLT5uZ3JvdXBzOwoKCWZvciAoaSA9IDA7IGkgPCBncm91cF9pbmZvLT5uYmxvY2tzOyBpKyspIHsKCQlpbnQgY3BfY291bnQgPSBtaW4oTkdST1VQU19QRVJfQkxPQ0ssIGNvdW50KTsKCQlpbnQgb2ZmID0gaSAqIE5HUk9VUFNfUEVSX0JMT0NLOwoJCWludCBsZW4gPSBjcF9jb3VudCAqIHNpemVvZigqZ3JvdXBsaXN0KTsKCgkJaWYgKGNvcHlfZnJvbV91c2VyKGdyb3VwX2luZm8tPmJsb2Nrc1tpXSwgZ3JvdXBsaXN0K29mZiwgbGVuKSkKCQkJcmV0dXJuIC1FRkFVTFQ7CgoJCWNvdW50IC09IGNwX2NvdW50OwoJfQoJcmV0dXJuIDA7Cn0KCi8qIGEgc2ltcGxlIFNoZWxsIHNvcnQgKi8Kc3RhdGljIHZvaWQgZ3JvdXBzX3NvcnQoc3RydWN0IGdyb3VwX2luZm8gKmdyb3VwX2luZm8pCnsKCWludCBiYXNlLCBtYXgsIHN0cmlkZTsKCWludCBnaWRzZXRzaXplID0gZ3JvdXBfaW5mby0+bmdyb3VwczsKCglmb3IgKHN0cmlkZSA9IDE7IHN0cmlkZSA8IGdpZHNldHNpemU7IHN0cmlkZSA9IDMgKiBzdHJpZGUgKyAxKQoJCTsgLyogbm90aGluZyAqLwoJc3RyaWRlIC89IDM7CgoJd2hpbGUgKHN0cmlkZSkgewoJCW1heCA9IGdpZHNldHNpemUgLSBzdHJpZGU7CgkJZm9yIChiYXNlID0gMDsgYmFzZSA8IG1heDsgYmFzZSsrKSB7CgkJCWludCBsZWZ0ID0gYmFzZTsKCQkJaW50IHJpZ2h0ID0gbGVmdCArIHN0cmlkZTsKCQkJZ2lkX3QgdG1wID0gR1JPVVBfQVQoZ3JvdXBfaW5mbywgcmlnaHQpOwoKCQkJd2hpbGUgKGxlZnQgPj0gMCAmJiBHUk9VUF9BVChncm91cF9pbmZvLCBsZWZ0KSA+IHRtcCkgewoJCQkJR1JPVVBfQVQoZ3JvdXBfaW5mbywgcmlnaHQpID0KCQkJCSAgICBHUk9VUF9BVChncm91cF9pbmZvLCBsZWZ0KTsKCQkJCXJpZ2h0ID0gbGVmdDsKCQkJCWxlZnQgLT0gc3RyaWRlOwoJCQl9CgkJCUdST1VQX0FUKGdyb3VwX2luZm8sIHJpZ2h0KSA9IHRtcDsKCQl9CgkJc3RyaWRlIC89IDM7Cgl9Cn0KCi8qIGEgc2ltcGxlIGJzZWFyY2ggKi8KaW50IGdyb3Vwc19zZWFyY2goc3RydWN0IGdyb3VwX2luZm8gKmdyb3VwX2luZm8sIGdpZF90IGdycCkKewoJdW5zaWduZWQgaW50IGxlZnQsIHJpZ2h0OwoKCWlmICghZ3JvdXBfaW5mbykKCQlyZXR1cm4gMDsKCglsZWZ0ID0gMDsKCXJpZ2h0ID0gZ3JvdXBfaW5mby0+bmdyb3VwczsKCXdoaWxlIChsZWZ0IDwgcmlnaHQpIHsKCQl1bnNpZ25lZCBpbnQgbWlkID0gKGxlZnQrcmlnaHQpLzI7CgkJaW50IGNtcCA9IGdycCAtIEdST1VQX0FUKGdyb3VwX2luZm8sIG1pZCk7CgkJaWYgKGNtcCA+IDApCgkJCWxlZnQgPSBtaWQgKyAxOwoJCWVsc2UgaWYgKGNtcCA8IDApCgkJCXJpZ2h0ID0gbWlkOwoJCWVsc2UKCQkJcmV0dXJuIDE7Cgl9CglyZXR1cm4gMDsKfQoKLyogdmFsaWRhdGUgYW5kIHNldCBjdXJyZW50LT5ncm91cF9pbmZvICovCmludCBzZXRfY3VycmVudF9ncm91cHMoc3RydWN0IGdyb3VwX2luZm8gKmdyb3VwX2luZm8pCnsKCWludCByZXR2YWw7CglzdHJ1Y3QgZ3JvdXBfaW5mbyAqb2xkX2luZm87CgoJcmV0dmFsID0gc2VjdXJpdHlfdGFza19zZXRncm91cHMoZ3JvdXBfaW5mbyk7CglpZiAocmV0dmFsKQoJCXJldHVybiByZXR2YWw7CgoJZ3JvdXBzX3NvcnQoZ3JvdXBfaW5mbyk7CglnZXRfZ3JvdXBfaW5mbyhncm91cF9pbmZvKTsKCgl0YXNrX2xvY2soY3VycmVudCk7CglvbGRfaW5mbyA9IGN1cnJlbnQtPmdyb3VwX2luZm87CgljdXJyZW50LT5ncm91cF9pbmZvID0gZ3JvdXBfaW5mbzsKCXRhc2tfdW5sb2NrKGN1cnJlbnQpOwoKCXB1dF9ncm91cF9pbmZvKG9sZF9pbmZvKTsKCglyZXR1cm4gMDsKfQoKRVhQT1JUX1NZTUJPTChzZXRfY3VycmVudF9ncm91cHMpOwoKYXNtbGlua2FnZSBsb25nIHN5c19nZXRncm91cHMoaW50IGdpZHNldHNpemUsIGdpZF90IF9fdXNlciAqZ3JvdXBsaXN0KQp7CglpbnQgaSA9IDA7CgoJLyoKCSAqCVNNUDogTm9ib2R5IGVsc2UgY2FuIGNoYW5nZSBvdXIgZ3JvdXBsaXN0LiBUaHVzIHdlIGFyZQoJICoJc2FmZS4KCSAqLwoKCWlmIChnaWRzZXRzaXplIDwgMCkKCQlyZXR1cm4gLUVJTlZBTDsKCgkvKiBubyBuZWVkIHRvIGdyYWIgdGFza19sb2NrIGhlcmU7IGl0IGNhbm5vdCBjaGFuZ2UgKi8KCWkgPSBjdXJyZW50LT5ncm91cF9pbmZvLT5uZ3JvdXBzOwoJaWYgKGdpZHNldHNpemUpIHsKCQlpZiAoaSA+IGdpZHNldHNpemUpIHsKCQkJaSA9IC1FSU5WQUw7CgkJCWdvdG8gb3V0OwoJCX0KCQlpZiAoZ3JvdXBzX3RvX3VzZXIoZ3JvdXBsaXN0LCBjdXJyZW50LT5ncm91cF9pbmZvKSkgewoJCQlpID0gLUVGQVVMVDsKCQkJZ290byBvdXQ7CgkJfQoJfQpvdXQ6CglyZXR1cm4gaTsKfQoKLyoKICoJU01QOiBPdXIgZ3JvdXBzIGFyZSBjb3B5LW9uLXdyaXRlLiBXZSBjYW4gc2V0IHRoZW0gc2FmZWx5CiAqCXdpdGhvdXQgYW5vdGhlciB0YXNrIGludGVyZmVyaW5nLgogKi8KIAphc21saW5rYWdlIGxvbmcgc3lzX3NldGdyb3VwcyhpbnQgZ2lkc2V0c2l6ZSwgZ2lkX3QgX191c2VyICpncm91cGxpc3QpCnsKCXN0cnVjdCBncm91cF9pbmZvICpncm91cF9pbmZvOwoJaW50IHJldHZhbDsKCglpZiAoIWNhcGFibGUoQ0FQX1NFVEdJRCkpCgkJcmV0dXJuIC1FUEVSTTsKCWlmICgodW5zaWduZWQpZ2lkc2V0c2l6ZSA+IE5HUk9VUFNfTUFYKQoJCXJldHVybiAtRUlOVkFMOwoKCWdyb3VwX2luZm8gPSBncm91cHNfYWxsb2MoZ2lkc2V0c2l6ZSk7CglpZiAoIWdyb3VwX2luZm8pCgkJcmV0dXJuIC1FTk9NRU07CglyZXR2YWwgPSBncm91cHNfZnJvbV91c2VyKGdyb3VwX2luZm8sIGdyb3VwbGlzdCk7CglpZiAocmV0dmFsKSB7CgkJcHV0X2dyb3VwX2luZm8oZ3JvdXBfaW5mbyk7CgkJcmV0dXJuIHJldHZhbDsKCX0KCglyZXR2YWwgPSBzZXRfY3VycmVudF9ncm91cHMoZ3JvdXBfaW5mbyk7CglwdXRfZ3JvdXBfaW5mbyhncm91cF9pbmZvKTsKCglyZXR1cm4gcmV0dmFsOwp9CgovKgogKiBDaGVjayB3aGV0aGVyIHdlJ3JlIGZzZ2lkL2VnaWQgb3IgaW4gdGhlIHN1cHBsZW1lbnRhbCBncm91cC4uCiAqLwppbnQgaW5fZ3JvdXBfcChnaWRfdCBncnApCnsKCWludCByZXR2YWwgPSAxOwoJaWYgKGdycCAhPSBjdXJyZW50LT5mc2dpZCkgewoJCXJldHZhbCA9IGdyb3Vwc19zZWFyY2goY3VycmVudC0+Z3JvdXBfaW5mbywgZ3JwKTsKCX0KCXJldHVybiByZXR2YWw7Cn0KCkVYUE9SVF9TWU1CT0woaW5fZ3JvdXBfcCk7CgppbnQgaW5fZWdyb3VwX3AoZ2lkX3QgZ3JwKQp7CglpbnQgcmV0dmFsID0gMTsKCWlmIChncnAgIT0gY3VycmVudC0+ZWdpZCkgewoJCXJldHZhbCA9IGdyb3Vwc19zZWFyY2goY3VycmVudC0+Z3JvdXBfaW5mbywgZ3JwKTsKCX0KCXJldHVybiByZXR2YWw7Cn0KCkVYUE9SVF9TWU1CT0woaW5fZWdyb3VwX3ApOwoKREVDTEFSRV9SV1NFTSh1dHNfc2VtKTsKCkVYUE9SVF9TWU1CT0wodXRzX3NlbSk7Cgphc21saW5rYWdlIGxvbmcgc3lzX25ld3VuYW1lKHN0cnVjdCBuZXdfdXRzbmFtZSBfX3VzZXIgKiBuYW1lKQp7CglpbnQgZXJybm8gPSAwOwoKCWRvd25fcmVhZCgmdXRzX3NlbSk7CglpZiAoY29weV90b191c2VyKG5hbWUsJnN5c3RlbV91dHNuYW1lLHNpemVvZiAqbmFtZSkpCgkJZXJybm8gPSAtRUZBVUxUOwoJdXBfcmVhZCgmdXRzX3NlbSk7CglyZXR1cm4gZXJybm87Cn0KCmFzbWxpbmthZ2UgbG9uZyBzeXNfc2V0aG9zdG5hbWUoY2hhciBfX3VzZXIgKm5hbWUsIGludCBsZW4pCnsKCWludCBlcnJubzsKCWNoYXIgdG1wW19fTkVXX1VUU19MRU5dOwoKCWlmICghY2FwYWJsZShDQVBfU1lTX0FETUlOKSkKCQlyZXR1cm4gLUVQRVJNOwoJaWYgKGxlbiA8IDAgfHwgbGVuID4gX19ORVdfVVRTX0xFTikKCQlyZXR1cm4gLUVJTlZBTDsKCWRvd25fd3JpdGUoJnV0c19zZW0pOwoJZXJybm8gPSAtRUZBVUxUOwoJaWYgKCFjb3B5X2Zyb21fdXNlcih0bXAsIG5hbWUsIGxlbikpIHsKCQltZW1jcHkoc3lzdGVtX3V0c25hbWUubm9kZW5hbWUsIHRtcCwgbGVuKTsKCQlzeXN0ZW1fdXRzbmFtZS5ub2RlbmFtZVtsZW5dID0gMDsKCQllcnJubyA9IDA7Cgl9Cgl1cF93cml0ZSgmdXRzX3NlbSk7CglyZXR1cm4gZXJybm87Cn0KCiNpZmRlZiBfX0FSQ0hfV0FOVF9TWVNfR0VUSE9TVE5BTUUKCmFzbWxpbmthZ2UgbG9uZyBzeXNfZ2V0aG9zdG5hbWUoY2hhciBfX3VzZXIgKm5hbWUsIGludCBsZW4pCnsKCWludCBpLCBlcnJubzsKCglpZiAobGVuIDwgMCkKCQlyZXR1cm4gLUVJTlZBTDsKCWRvd25fcmVhZCgmdXRzX3NlbSk7CglpID0gMSArIHN0cmxlbihzeXN0ZW1fdXRzbmFtZS5ub2RlbmFtZSk7CglpZiAoaSA+IGxlbikKCQlpID0gbGVuOwoJZXJybm8gPSAwOwoJaWYgKGNvcHlfdG9fdXNlcihuYW1lLCBzeXN0ZW1fdXRzbmFtZS5ub2RlbmFtZSwgaSkpCgkJZXJybm8gPSAtRUZBVUxUOwoJdXBfcmVhZCgmdXRzX3NlbSk7CglyZXR1cm4gZXJybm87Cn0KCiNlbmRpZgoKLyoKICogT25seSBzZXRkb21haW5uYW1lOyBnZXRkb21haW5uYW1lIGNhbiBiZSBpbXBsZW1lbnRlZCBieSBjYWxsaW5nCiAqIHVuYW1lKCkKICovCmFzbWxpbmthZ2UgbG9uZyBzeXNfc2V0ZG9tYWlubmFtZShjaGFyIF9fdXNlciAqbmFtZSwgaW50IGxlbikKewoJaW50IGVycm5vOwoJY2hhciB0bXBbX19ORVdfVVRTX0xFTl07CgoJaWYgKCFjYXBhYmxlKENBUF9TWVNfQURNSU4pKQoJCXJldHVybiAtRVBFUk07CglpZiAobGVuIDwgMCB8fCBsZW4gPiBfX05FV19VVFNfTEVOKQoJCXJldHVybiAtRUlOVkFMOwoKCWRvd25fd3JpdGUoJnV0c19zZW0pOwoJZXJybm8gPSAtRUZBVUxUOwoJaWYgKCFjb3B5X2Zyb21fdXNlcih0bXAsIG5hbWUsIGxlbikpIHsKCQltZW1jcHkoc3lzdGVtX3V0c25hbWUuZG9tYWlubmFtZSwgdG1wLCBsZW4pOwoJCXN5c3RlbV91dHNuYW1lLmRvbWFpbm5hbWVbbGVuXSA9IDA7CgkJZXJybm8gPSAwOwoJfQoJdXBfd3JpdGUoJnV0c19zZW0pOwoJcmV0dXJuIGVycm5vOwp9Cgphc21saW5rYWdlIGxvbmcgc3lzX2dldHJsaW1pdCh1bnNpZ25lZCBpbnQgcmVzb3VyY2UsIHN0cnVjdCBybGltaXQgX191c2VyICpybGltKQp7CglpZiAocmVzb3VyY2UgPj0gUkxJTV9OTElNSVRTKQoJCXJldHVybiAtRUlOVkFMOwoJZWxzZSB7CgkJc3RydWN0IHJsaW1pdCB2YWx1ZTsKCQl0YXNrX2xvY2soY3VycmVudC0+Z3JvdXBfbGVhZGVyKTsKCQl2YWx1ZSA9IGN1cnJlbnQtPnNpZ25hbC0+cmxpbVtyZXNvdXJjZV07CgkJdGFza191bmxvY2soY3VycmVudC0+Z3JvdXBfbGVhZGVyKTsKCQlyZXR1cm4gY29weV90b191c2VyKHJsaW0sICZ2YWx1ZSwgc2l6ZW9mKCpybGltKSkgPyAtRUZBVUxUIDogMDsKCX0KfQoKI2lmZGVmIF9fQVJDSF9XQU5UX1NZU19PTERfR0VUUkxJTUlUCgovKgogKglCYWNrIGNvbXBhdGliaWxpdHkgZm9yIGdldHJsaW1pdC4gTmVlZGVkIGZvciBzb21lIGFwcHMuCiAqLwogCmFzbWxpbmthZ2UgbG9uZyBzeXNfb2xkX2dldHJsaW1pdCh1bnNpZ25lZCBpbnQgcmVzb3VyY2UsIHN0cnVjdCBybGltaXQgX191c2VyICpybGltKQp7CglzdHJ1Y3QgcmxpbWl0IHg7CglpZiAocmVzb3VyY2UgPj0gUkxJTV9OTElNSVRTKQoJCXJldHVybiAtRUlOVkFMOwoKCXRhc2tfbG9jayhjdXJyZW50LT5ncm91cF9sZWFkZXIpOwoJeCA9IGN1cnJlbnQtPnNpZ25hbC0+cmxpbVtyZXNvdXJjZV07Cgl0YXNrX3VubG9jayhjdXJyZW50LT5ncm91cF9sZWFkZXIpOwoJaWYoeC5ybGltX2N1ciA+IDB4N0ZGRkZGRkYpCgkJeC5ybGltX2N1ciA9IDB4N0ZGRkZGRkY7CglpZih4LnJsaW1fbWF4ID4gMHg3RkZGRkZGRikKCQl4LnJsaW1fbWF4ID0gMHg3RkZGRkZGRjsKCXJldHVybiBjb3B5X3RvX3VzZXIocmxpbSwgJngsIHNpemVvZih4KSk/LUVGQVVMVDowOwp9CgojZW5kaWYKCmFzbWxpbmthZ2UgbG9uZyBzeXNfc2V0cmxpbWl0KHVuc2lnbmVkIGludCByZXNvdXJjZSwgc3RydWN0IHJsaW1pdCBfX3VzZXIgKnJsaW0pCnsKCXN0cnVjdCBybGltaXQgbmV3X3JsaW0sICpvbGRfcmxpbTsKCXVuc2lnbmVkIGxvbmcgaXRfcHJvZl9zZWNzOwoJaW50IHJldHZhbDsKCglpZiAocmVzb3VyY2UgPj0gUkxJTV9OTElNSVRTKQoJCXJldHVybiAtRUlOVkFMOwoJaWYgKGNvcHlfZnJvbV91c2VyKCZuZXdfcmxpbSwgcmxpbSwgc2l6ZW9mKCpybGltKSkpCgkJcmV0dXJuIC1FRkFVTFQ7CglpZiAobmV3X3JsaW0ucmxpbV9jdXIgPiBuZXdfcmxpbS5ybGltX21heCkKCQlyZXR1cm4gLUVJTlZBTDsKCW9sZF9ybGltID0gY3VycmVudC0+c2lnbmFsLT5ybGltICsgcmVzb3VyY2U7CglpZiAoKG5ld19ybGltLnJsaW1fbWF4ID4gb2xkX3JsaW0tPnJsaW1fbWF4KSAmJgoJICAgICFjYXBhYmxlKENBUF9TWVNfUkVTT1VSQ0UpKQoJCXJldHVybiAtRVBFUk07CglpZiAocmVzb3VyY2UgPT0gUkxJTUlUX05PRklMRSAmJiBuZXdfcmxpbS5ybGltX21heCA+IE5SX09QRU4pCgkJcmV0dXJuIC1FUEVSTTsKCglyZXR2YWwgPSBzZWN1cml0eV90YXNrX3NldHJsaW1pdChyZXNvdXJjZSwgJm5ld19ybGltKTsKCWlmIChyZXR2YWwpCgkJcmV0dXJuIHJldHZhbDsKCgl0YXNrX2xvY2soY3VycmVudC0+Z3JvdXBfbGVhZGVyKTsKCSpvbGRfcmxpbSA9IG5ld19ybGltOwoJdGFza191bmxvY2soY3VycmVudC0+Z3JvdXBfbGVhZGVyKTsKCglpZiAocmVzb3VyY2UgIT0gUkxJTUlUX0NQVSkKCQlnb3RvIG91dDsKCgkvKgoJICogUkxJTUlUX0NQVSBoYW5kbGluZy4gICBOb3RlIHRoYXQgdGhlIGtlcm5lbCBmYWlscyB0byByZXR1cm4gYW4gZXJyb3IKCSAqIGNvZGUgaWYgaXQgcmVqZWN0ZWQgdGhlIHVzZXIncyBhdHRlbXB0IHRvIHNldCBSTElNSVRfQ1BVLiAgVGhpcyBpcyBhCgkgKiB2ZXJ5IGxvbmctc3RhbmRpbmcgZXJyb3IsIGFuZCBmaXhpbmcgaXQgbm93IHJpc2tzIGJyZWFrYWdlIG9mCgkgKiBhcHBsaWNhdGlvbnMsIHNvIHdlIGxpdmUgd2l0aCBpdAoJICovCglpZiAobmV3X3JsaW0ucmxpbV9jdXIgPT0gUkxJTV9JTkZJTklUWSkKCQlnb3RvIG91dDsKCglpdF9wcm9mX3NlY3MgPSBjcHV0aW1lX3RvX3NlY3MoY3VycmVudC0+c2lnbmFsLT5pdF9wcm9mX2V4cGlyZXMpOwoJaWYgKGl0X3Byb2Zfc2VjcyA9PSAwIHx8IG5ld19ybGltLnJsaW1fY3VyIDw9IGl0X3Byb2Zfc2VjcykgewoJCXVuc2lnbmVkIGxvbmcgcmxpbV9jdXIgPSBuZXdfcmxpbS5ybGltX2N1cjsKCQljcHV0aW1lX3QgY3B1dGltZTsKCgkJaWYgKHJsaW1fY3VyID09IDApIHsKCQkJLyoKCQkJICogVGhlIGNhbGxlciBpcyBhc2tpbmcgZm9yIGFuIGltbWVkaWF0ZSBSTElNSVRfQ1BVCgkJCSAqIGV4cGlyeS4gIEJ1dCB3ZSB1c2UgdGhlIHplcm8gdmFsdWUgdG8gbWVhbiAiaXQgd2FzCgkJCSAqIG5ldmVyIHNldCIuICBTbyBsZXQncyBjaGVhdCBhbmQgbWFrZSBpdCBvbmUgc2Vjb25kCgkJCSAqIGluc3RlYWQKCQkJICovCgkJCXJsaW1fY3VyID0gMTsKCQl9CgkJY3B1dGltZSA9IHNlY3NfdG9fY3B1dGltZShybGltX2N1cik7CgkJcmVhZF9sb2NrKCZ0YXNrbGlzdF9sb2NrKTsKCQlzcGluX2xvY2tfaXJxKCZjdXJyZW50LT5zaWdoYW5kLT5zaWdsb2NrKTsKCQlzZXRfcHJvY2Vzc19jcHVfdGltZXIoY3VycmVudCwgQ1BVQ0xPQ0tfUFJPRiwgJmNwdXRpbWUsIE5VTEwpOwoJCXNwaW5fdW5sb2NrX2lycSgmY3VycmVudC0+c2lnaGFuZC0+c2lnbG9jayk7CgkJcmVhZF91bmxvY2soJnRhc2tsaXN0X2xvY2spOwoJfQpvdXQ6CglyZXR1cm4gMDsKfQoKLyoKICogSXQgd291bGQgbWFrZSBzZW5zZSB0byBwdXQgc3RydWN0IHJ1c2FnZSBpbiB0aGUgdGFza19zdHJ1Y3QsCiAqIGV4Y2VwdCB0aGF0IHdvdWxkIG1ha2UgdGhlIHRhc2tfc3RydWN0IGJlICpyZWFsbHkgYmlnKi4gIEFmdGVyCiAqIHRhc2tfc3RydWN0IGdldHMgbW92ZWQgaW50byBtYWxsb2MnZWQgbWVtb3J5LCBpdCB3b3VsZAogKiBtYWtlIHNlbnNlIHRvIGRvIHRoaXMuICBJdCB3aWxsIG1ha2UgbW92aW5nIHRoZSByZXN0IG9mIHRoZSBpbmZvcm1hdGlvbgogKiBhIGxvdCBzaW1wbGVyISAgKFdoaWNoIHdlJ3JlIG5vdCBkb2luZyByaWdodCBub3cgYmVjYXVzZSB3ZSdyZSBub3QKICogbWVhc3VyaW5nIHRoZW0geWV0KS4KICoKICogV2hlbiBzYW1wbGluZyBtdWx0aXBsZSB0aHJlYWRzIGZvciBSVVNBR0VfU0VMRiwgdW5kZXIgU01QIHdlIG1pZ2h0IGhhdmUKICogcmFjZXMgd2l0aCB0aHJlYWRzIGluY3JlbWVudGluZyB0aGVpciBvd24gY291bnRlcnMuICBCdXQgc2luY2Ugd29yZAogKiByZWFkcyBhcmUgYXRvbWljLCB3ZSBlaXRoZXIgZ2V0IG5ldyB2YWx1ZXMgb3Igb2xkIHZhbHVlcyBhbmQgd2UgZG9uJ3QKICogY2FyZSB3aGljaCBmb3IgdGhlIHN1bXMuICBXZSBhbHdheXMgdGFrZSB0aGUgc2lnbG9jayB0byBwcm90ZWN0IHJlYWRpbmcKICogdGhlIGMqIGZpZWxkcyBmcm9tIHAtPnNpZ25hbCBmcm9tIHJhY2VzIHdpdGggZXhpdC5jIHVwZGF0aW5nIHRob3NlCiAqIGZpZWxkcyB3aGVuIHJlYXBpbmcsIHNvIGEgc2FtcGxlIGVpdGhlciBnZXRzIGFsbCB0aGUgYWRkaXRpb25zIG9mIGEKICogZ2l2ZW4gY2hpbGQgYWZ0ZXIgaXQncyByZWFwZWQsIG9yIG5vbmUgc28gdGhpcyBzYW1wbGUgaXMgYmVmb3JlIHJlYXBpbmcuCiAqCiAqIHRhc2tsaXN0X2xvY2sgbG9ja2luZyBvcHRpbWlzYXRpb246CiAqIElmIHdlIGFyZSBjdXJyZW50IGFuZCBzaW5nbGUgdGhyZWFkZWQsIHdlIGRvIG5vdCBuZWVkIHRvIHRha2UgdGhlIHRhc2tsaXN0CiAqIGxvY2sgb3IgdGhlIHNpZ2xvY2suICBObyBvbmUgZWxzZSBjYW4gdGFrZSBvdXIgc2lnbmFsX3N0cnVjdCBhd2F5LAogKiBubyBvbmUgZWxzZSBjYW4gcmVhcCB0aGUgY2hpbGRyZW4gdG8gdXBkYXRlIHNpZ25hbC0+YyogY291bnRlcnMsIGFuZAogKiBubyBvbmUgZWxzZSBjYW4gcmFjZSB3aXRoIHRoZSBzaWduYWwtPiBmaWVsZHMuCiAqIElmIHdlIGRvIG5vdCB0YWtlIHRoZSB0YXNrbGlzdF9sb2NrLCB0aGUgc2lnbmFsLT4gZmllbGRzIGNvdWxkIGJlIHJlYWQKICogb3V0IG9mIG9yZGVyIHdoaWxlIGFub3RoZXIgdGhyZWFkIHdhcyBqdXN0IGV4aXRpbmcuIFNvIHdlIHBsYWNlIGEKICogcmVhZCBtZW1vcnkgYmFycmllciB3aGVuIHdlIGF2b2lkIHRoZSBsb2NrLiAgT24gdGhlIHdyaXRlciBzaWRlLAogKiB3cml0ZSBtZW1vcnkgYmFycmllciBpcyBpbXBsaWVkIGluICBfX2V4aXRfc2lnbmFsIGFzIF9fZXhpdF9zaWduYWwgcmVsZWFzZXMKICogdGhlIHNpZ2xvY2sgc3BpbmxvY2sgYWZ0ZXIgdXBkYXRpbmcgdGhlIHNpZ25hbC0+IGZpZWxkcy4KICoKICogV2UgZG9uJ3QgcmVhbGx5IG5lZWQgdGhlIHNpZ2xvY2sgd2hlbiB3ZSBhY2Nlc3MgdGhlIG5vbiBjKiBmaWVsZHMKICogb2YgdGhlIHNpZ25hbF9zdHJ1Y3QgKGZvciBSVVNBR0VfU0VMRikgZXZlbiBpbiBtdWx0aXRocmVhZGVkCiAqIGNhc2UsIHNpbmNlIHdlIHRha2UgdGhlIHRhc2tsaXN0IGxvY2sgZm9yIHJlYWQgYW5kIHRoZSBub24gYyogc2lnbmFsLT4KICogZmllbGRzIGFyZSB1cGRhdGVkIG9ubHkgaW4gX19leGl0X3NpZ25hbCwgd2hpY2ggaXMgY2FsbGVkIHdpdGgKICogdGFza2xpc3RfbG9jayB0YWtlbiBmb3Igd3JpdGUsIGhlbmNlIHRoZXNlIHR3byB0aHJlYWRzIGNhbm5vdCBleGVjdXRlCiAqIGNvbmN1cnJlbnRseS4KICoKICovCgpzdGF0aWMgdm9pZCBrX2dldHJ1c2FnZShzdHJ1Y3QgdGFza19zdHJ1Y3QgKnAsIGludCB3aG8sIHN0cnVjdCBydXNhZ2UgKnIpCnsKCXN0cnVjdCB0YXNrX3N0cnVjdCAqdDsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgljcHV0aW1lX3QgdXRpbWUsIHN0aW1lOwoJaW50IG5lZWRfbG9jayA9IDA7CgoJbWVtc2V0KChjaGFyICopIHIsIDAsIHNpemVvZiAqcik7Cgl1dGltZSA9IHN0aW1lID0gY3B1dGltZV96ZXJvOwoKCWlmIChwICE9IGN1cnJlbnQgfHwgIXRocmVhZF9ncm91cF9lbXB0eShwKSkKCQluZWVkX2xvY2sgPSAxOwoKCWlmIChuZWVkX2xvY2spIHsKCQlyZWFkX2xvY2soJnRhc2tsaXN0X2xvY2spOwoJCWlmICh1bmxpa2VseSghcC0+c2lnbmFsKSkgewoJCQlyZWFkX3VubG9jaygmdGFza2xpc3RfbG9jayk7CgkJCXJldHVybjsKCQl9Cgl9IGVsc2UKCQkvKiBTZWUgbG9ja2luZyBjb21tZW50cyBhYm92ZSAqLwoJCXNtcF9ybWIoKTsKCglzd2l0Y2ggKHdobykgewoJCWNhc2UgUlVTQUdFX0JPVEg6CgkJY2FzZSBSVVNBR0VfQ0hJTERSRU46CgkJCXNwaW5fbG9ja19pcnFzYXZlKCZwLT5zaWdoYW5kLT5zaWdsb2NrLCBmbGFncyk7CgkJCXV0aW1lID0gcC0+c2lnbmFsLT5jdXRpbWU7CgkJCXN0aW1lID0gcC0+c2lnbmFsLT5jc3RpbWU7CgkJCXItPnJ1X252Y3N3ID0gcC0+c2lnbmFsLT5jbnZjc3c7CgkJCXItPnJ1X25pdmNzdyA9IHAtPnNpZ25hbC0+Y25pdmNzdzsKCQkJci0+cnVfbWluZmx0ID0gcC0+c2lnbmFsLT5jbWluX2ZsdDsKCQkJci0+cnVfbWFqZmx0ID0gcC0+c2lnbmFsLT5jbWFqX2ZsdDsKCQkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmcC0+c2lnaGFuZC0+c2lnbG9jaywgZmxhZ3MpOwoKCQkJaWYgKHdobyA9PSBSVVNBR0VfQ0hJTERSRU4pCgkJCQlicmVhazsKCgkJY2FzZSBSVVNBR0VfU0VMRjoKCQkJdXRpbWUgPSBjcHV0aW1lX2FkZCh1dGltZSwgcC0+c2lnbmFsLT51dGltZSk7CgkJCXN0aW1lID0gY3B1dGltZV9hZGQoc3RpbWUsIHAtPnNpZ25hbC0+c3RpbWUpOwoJCQlyLT5ydV9udmNzdyArPSBwLT5zaWduYWwtPm52Y3N3OwoJCQlyLT5ydV9uaXZjc3cgKz0gcC0+c2lnbmFsLT5uaXZjc3c7CgkJCXItPnJ1X21pbmZsdCArPSBwLT5zaWduYWwtPm1pbl9mbHQ7CgkJCXItPnJ1X21hamZsdCArPSBwLT5zaWduYWwtPm1hal9mbHQ7CgkJCXQgPSBwOwoJCQlkbyB7CgkJCQl1dGltZSA9IGNwdXRpbWVfYWRkKHV0aW1lLCB0LT51dGltZSk7CgkJCQlzdGltZSA9IGNwdXRpbWVfYWRkKHN0aW1lLCB0LT5zdGltZSk7CgkJCQlyLT5ydV9udmNzdyArPSB0LT5udmNzdzsKCQkJCXItPnJ1X25pdmNzdyArPSB0LT5uaXZjc3c7CgkJCQlyLT5ydV9taW5mbHQgKz0gdC0+bWluX2ZsdDsKCQkJCXItPnJ1X21hamZsdCArPSB0LT5tYWpfZmx0OwoJCQkJdCA9IG5leHRfdGhyZWFkKHQpOwoJCQl9IHdoaWxlICh0ICE9IHApOwoJCQlicmVhazsKCgkJZGVmYXVsdDoKCQkJQlVHKCk7Cgl9CgoJaWYgKG5lZWRfbG9jaykKCQlyZWFkX3VubG9jaygmdGFza2xpc3RfbG9jayk7CgljcHV0aW1lX3RvX3RpbWV2YWwodXRpbWUsICZyLT5ydV91dGltZSk7CgljcHV0aW1lX3RvX3RpbWV2YWwoc3RpbWUsICZyLT5ydV9zdGltZSk7Cn0KCmludCBnZXRydXNhZ2Uoc3RydWN0IHRhc2tfc3RydWN0ICpwLCBpbnQgd2hvLCBzdHJ1Y3QgcnVzYWdlIF9fdXNlciAqcnUpCnsKCXN0cnVjdCBydXNhZ2UgcjsKCWtfZ2V0cnVzYWdlKHAsIHdobywgJnIpOwoJcmV0dXJuIGNvcHlfdG9fdXNlcihydSwgJnIsIHNpemVvZihyKSkgPyAtRUZBVUxUIDogMDsKfQoKYXNtbGlua2FnZSBsb25nIHN5c19nZXRydXNhZ2UoaW50IHdobywgc3RydWN0IHJ1c2FnZSBfX3VzZXIgKnJ1KQp7CglpZiAod2hvICE9IFJVU0FHRV9TRUxGICYmIHdobyAhPSBSVVNBR0VfQ0hJTERSRU4pCgkJcmV0dXJuIC1FSU5WQUw7CglyZXR1cm4gZ2V0cnVzYWdlKGN1cnJlbnQsIHdobywgcnUpOwp9Cgphc21saW5rYWdlIGxvbmcgc3lzX3VtYXNrKGludCBtYXNrKQp7CgltYXNrID0geGNoZygmY3VycmVudC0+ZnMtPnVtYXNrLCBtYXNrICYgU19JUldYVUdPKTsKCXJldHVybiBtYXNrOwp9CiAgICAKYXNtbGlua2FnZSBsb25nIHN5c19wcmN0bChpbnQgb3B0aW9uLCB1bnNpZ25lZCBsb25nIGFyZzIsIHVuc2lnbmVkIGxvbmcgYXJnMywKCQkJICB1bnNpZ25lZCBsb25nIGFyZzQsIHVuc2lnbmVkIGxvbmcgYXJnNSkKewoJbG9uZyBlcnJvcjsKCgllcnJvciA9IHNlY3VyaXR5X3Rhc2tfcHJjdGwob3B0aW9uLCBhcmcyLCBhcmczLCBhcmc0LCBhcmc1KTsKCWlmIChlcnJvcikKCQlyZXR1cm4gZXJyb3I7CgoJc3dpdGNoIChvcHRpb24pIHsKCQljYXNlIFBSX1NFVF9QREVBVEhTSUc6CgkJCWlmICghdmFsaWRfc2lnbmFsKGFyZzIpKSB7CgkJCQllcnJvciA9IC1FSU5WQUw7CgkJCQlicmVhazsKCQkJfQoJCQljdXJyZW50LT5wZGVhdGhfc2lnbmFsID0gYXJnMjsKCQkJYnJlYWs7CgkJY2FzZSBQUl9HRVRfUERFQVRIU0lHOgoJCQllcnJvciA9IHB1dF91c2VyKGN1cnJlbnQtPnBkZWF0aF9zaWduYWwsIChpbnQgX191c2VyICopYXJnMik7CgkJCWJyZWFrOwoJCWNhc2UgUFJfR0VUX0RVTVBBQkxFOgoJCQllcnJvciA9IGN1cnJlbnQtPm1tLT5kdW1wYWJsZTsKCQkJYnJlYWs7CgkJY2FzZSBQUl9TRVRfRFVNUEFCTEU6CgkJCWlmIChhcmcyIDwgMCB8fCBhcmcyID4gMikgewoJCQkJZXJyb3IgPSAtRUlOVkFMOwoJCQkJYnJlYWs7CgkJCX0KCQkJY3VycmVudC0+bW0tPmR1bXBhYmxlID0gYXJnMjsKCQkJYnJlYWs7CgoJCWNhc2UgUFJfU0VUX1VOQUxJR046CgkJCWVycm9yID0gU0VUX1VOQUxJR05fQ1RMKGN1cnJlbnQsIGFyZzIpOwoJCQlicmVhazsKCQljYXNlIFBSX0dFVF9VTkFMSUdOOgoJCQllcnJvciA9IEdFVF9VTkFMSUdOX0NUTChjdXJyZW50LCBhcmcyKTsKCQkJYnJlYWs7CgkJY2FzZSBQUl9TRVRfRlBFTVU6CgkJCWVycm9yID0gU0VUX0ZQRU1VX0NUTChjdXJyZW50LCBhcmcyKTsKCQkJYnJlYWs7CgkJY2FzZSBQUl9HRVRfRlBFTVU6CgkJCWVycm9yID0gR0VUX0ZQRU1VX0NUTChjdXJyZW50LCBhcmcyKTsKCQkJYnJlYWs7CgkJY2FzZSBQUl9TRVRfRlBFWEM6CgkJCWVycm9yID0gU0VUX0ZQRVhDX0NUTChjdXJyZW50LCBhcmcyKTsKCQkJYnJlYWs7CgkJY2FzZSBQUl9HRVRfRlBFWEM6CgkJCWVycm9yID0gR0VUX0ZQRVhDX0NUTChjdXJyZW50LCBhcmcyKTsKCQkJYnJlYWs7CgkJY2FzZSBQUl9HRVRfVElNSU5HOgoJCQllcnJvciA9IFBSX1RJTUlOR19TVEFUSVNUSUNBTDsKCQkJYnJlYWs7CgkJY2FzZSBQUl9TRVRfVElNSU5HOgoJCQlpZiAoYXJnMiA9PSBQUl9USU1JTkdfU1RBVElTVElDQUwpCgkJCQllcnJvciA9IDA7CgkJCWVsc2UKCQkJCWVycm9yID0gLUVJTlZBTDsKCQkJYnJlYWs7CgoJCWNhc2UgUFJfR0VUX0tFRVBDQVBTOgoJCQlpZiAoY3VycmVudC0+a2VlcF9jYXBhYmlsaXRpZXMpCgkJCQllcnJvciA9IDE7CgkJCWJyZWFrOwoJCWNhc2UgUFJfU0VUX0tFRVBDQVBTOgoJCQlpZiAoYXJnMiAhPSAwICYmIGFyZzIgIT0gMSkgewoJCQkJZXJyb3IgPSAtRUlOVkFMOwoJCQkJYnJlYWs7CgkJCX0KCQkJY3VycmVudC0+a2VlcF9jYXBhYmlsaXRpZXMgPSBhcmcyOwoJCQlicmVhazsKCQljYXNlIFBSX1NFVF9OQU1FOiB7CgkJCXN0cnVjdCB0YXNrX3N0cnVjdCAqbWUgPSBjdXJyZW50OwoJCQl1bnNpZ25lZCBjaGFyIG5jb21tW3NpemVvZihtZS0+Y29tbSldOwoKCQkJbmNvbW1bc2l6ZW9mKG1lLT5jb21tKS0xXSA9IDA7CgkJCWlmIChzdHJuY3B5X2Zyb21fdXNlcihuY29tbSwgKGNoYXIgX191c2VyICopYXJnMiwKCQkJCQkJc2l6ZW9mKG1lLT5jb21tKS0xKSA8IDApCgkJCQlyZXR1cm4gLUVGQVVMVDsKCQkJc2V0X3Rhc2tfY29tbShtZSwgbmNvbW0pOwoJCQlyZXR1cm4gMDsKCQl9CgkJY2FzZSBQUl9HRVRfTkFNRTogewoJCQlzdHJ1Y3QgdGFza19zdHJ1Y3QgKm1lID0gY3VycmVudDsKCQkJdW5zaWduZWQgY2hhciB0Y29tbVtzaXplb2YobWUtPmNvbW0pXTsKCgkJCWdldF90YXNrX2NvbW0odGNvbW0sIG1lKTsKCQkJaWYgKGNvcHlfdG9fdXNlcigoY2hhciBfX3VzZXIgKilhcmcyLCB0Y29tbSwgc2l6ZW9mKHRjb21tKSkpCgkJCQlyZXR1cm4gLUVGQVVMVDsKCQkJcmV0dXJuIDA7CgkJfQoJCWRlZmF1bHQ6CgkJCWVycm9yID0gLUVJTlZBTDsKCQkJYnJlYWs7Cgl9CglyZXR1cm4gZXJyb3I7Cn0K