LyoKICogIGxpbnV4L2tlcm5lbC9zeXMuYwogKgogKiAgQ29weXJpZ2h0IChDKSAxOTkxLCAxOTkyICBMaW51cyBUb3J2YWxkcwogKi8KCiNpbmNsdWRlIDxsaW51eC9jb25maWcuaD4KI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvbW0uaD4KI2luY2x1ZGUgPGxpbnV4L3V0c25hbWUuaD4KI2luY2x1ZGUgPGxpbnV4L21tYW4uaD4KI2luY2x1ZGUgPGxpbnV4L3NtcF9sb2NrLmg+CiNpbmNsdWRlIDxsaW51eC9ub3RpZmllci5oPgojaW5jbHVkZSA8bGludXgvcmVib290Lmg+CiNpbmNsdWRlIDxsaW51eC9wcmN0bC5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvaGlnaHVpZC5oPgojaW5jbHVkZSA8bGludXgvZnMuaD4KI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgojaW5jbHVkZSA8bGludXgva2V4ZWMuaD4KI2luY2x1ZGUgPGxpbnV4L3dvcmtxdWV1ZS5oPgojaW5jbHVkZSA8bGludXgvZGV2aWNlLmg+CiNpbmNsdWRlIDxsaW51eC9rZXkuaD4KI2luY2x1ZGUgPGxpbnV4L3RpbWVzLmg+CiNpbmNsdWRlIDxsaW51eC9wb3NpeC10aW1lcnMuaD4KI2luY2x1ZGUgPGxpbnV4L3NlY3VyaXR5Lmg+CiNpbmNsdWRlIDxsaW51eC9kY29va2llcy5oPgojaW5jbHVkZSA8bGludXgvc3VzcGVuZC5oPgojaW5jbHVkZSA8bGludXgvdHR5Lmg+CiNpbmNsdWRlIDxsaW51eC9zaWduYWwuaD4KCiNpbmNsdWRlIDxsaW51eC9jb21wYXQuaD4KI2luY2x1ZGUgPGxpbnV4L3N5c2NhbGxzLmg+CgojaW5jbHVkZSA8YXNtL3VhY2Nlc3MuaD4KI2luY2x1ZGUgPGFzbS9pby5oPgojaW5jbHVkZSA8YXNtL3VuaXN0ZC5oPgoKI2lmbmRlZiBTRVRfVU5BTElHTl9DVEwKIyBkZWZpbmUgU0VUX1VOQUxJR05fQ1RMKGEsYikJKC1FSU5WQUwpCiNlbmRpZgojaWZuZGVmIEdFVF9VTkFMSUdOX0NUTAojIGRlZmluZSBHRVRfVU5BTElHTl9DVEwoYSxiKQkoLUVJTlZBTCkKI2VuZGlmCiNpZm5kZWYgU0VUX0ZQRU1VX0NUTAojIGRlZmluZSBTRVRfRlBFTVVfQ1RMKGEsYikJKC1FSU5WQUwpCiNlbmRpZgojaWZuZGVmIEdFVF9GUEVNVV9DVEwKIyBkZWZpbmUgR0VUX0ZQRU1VX0NUTChhLGIpCSgtRUlOVkFMKQojZW5kaWYKI2lmbmRlZiBTRVRfRlBFWENfQ1RMCiMgZGVmaW5lIFNFVF9GUEVYQ19DVEwoYSxiKQkoLUVJTlZBTCkKI2VuZGlmCiNpZm5kZWYgR0VUX0ZQRVhDX0NUTAojIGRlZmluZSBHRVRfRlBFWENfQ1RMKGEsYikJKC1FSU5WQUwpCiNlbmRpZgoKLyoKICogdGhpcyBpcyB3aGVyZSB0aGUgc3lzdGVtLXdpZGUgb3ZlcmZsb3cgVUlEIGFuZCBHSUQgYXJlIGRlZmluZWQsIGZvcgogKiBhcmNoaXRlY3R1cmVzIHRoYXQgbm93IGhhdmUgMzItYml0IFVJRC9HSUQgYnV0IGRpZG4ndCBpbiB0aGUgcGFzdAogKi8KCmludCBvdmVyZmxvd3VpZCA9IERFRkFVTFRfT1ZFUkZMT1dVSUQ7CmludCBvdmVyZmxvd2dpZCA9IERFRkFVTFRfT1ZFUkZMT1dHSUQ7CgojaWZkZWYgQ09ORklHX1VJRDE2CkVYUE9SVF9TWU1CT0wob3ZlcmZsb3d1aWQpOwpFWFBPUlRfU1lNQk9MKG92ZXJmbG93Z2lkKTsKI2VuZGlmCgovKgogKiB0aGUgc2FtZSBhcyBhYm92ZSwgYnV0IGZvciBmaWxlc3lzdGVtcyB3aGljaCBjYW4gb25seSBzdG9yZSBhIDE2LWJpdAogKiBVSUQgYW5kIEdJRC4gYXMgc3VjaCwgdGhpcyBpcyBuZWVkZWQgb24gYWxsIGFyY2hpdGVjdHVyZXMKICovCgppbnQgZnNfb3ZlcmZsb3d1aWQgPSBERUZBVUxUX0ZTX09WRVJGTE9XVUlEOwppbnQgZnNfb3ZlcmZsb3dnaWQgPSBERUZBVUxUX0ZTX09WRVJGTE9XVUlEOwoKRVhQT1JUX1NZTUJPTChmc19vdmVyZmxvd3VpZCk7CkVYUE9SVF9TWU1CT0woZnNfb3ZlcmZsb3dnaWQpOwoKLyoKICogdGhpcyBpbmRpY2F0ZXMgd2hldGhlciB5b3UgY2FuIHJlYm9vdCB3aXRoIGN0cmwtYWx0LWRlbDogdGhlIGRlZmF1bHQgaXMgeWVzCiAqLwoKaW50IENfQV9EID0gMTsKaW50IGNhZF9waWQgPSAxOwoKLyoKICoJTm90aWZpZXIgbGlzdCBmb3Iga2VybmVsIGNvZGUgd2hpY2ggd2FudHMgdG8gYmUgY2FsbGVkCiAqCWF0IHNodXRkb3duLiBUaGlzIGlzIHVzZWQgdG8gc3RvcCBhbnkgaWRsaW5nIERNQSBvcGVyYXRpb25zCiAqCWFuZCB0aGUgbGlrZS4gCiAqLwoKc3RhdGljIHN0cnVjdCBub3RpZmllcl9ibG9jayAqcmVib290X25vdGlmaWVyX2xpc3Q7CnN0YXRpYyBERUZJTkVfUldMT0NLKG5vdGlmaWVyX2xvY2spOwoKLyoqCiAqCW5vdGlmaWVyX2NoYWluX3JlZ2lzdGVyCS0gQWRkIG5vdGlmaWVyIHRvIGEgbm90aWZpZXIgY2hhaW4KICoJQGxpc3Q6IFBvaW50ZXIgdG8gcm9vdCBsaXN0IHBvaW50ZXIKICoJQG46IE5ldyBlbnRyeSBpbiBub3RpZmllciBjaGFpbgogKgogKglBZGRzIGEgbm90aWZpZXIgdG8gYSBub3RpZmllciBjaGFpbi4KICoKICoJQ3VycmVudGx5IGFsd2F5cyByZXR1cm5zIHplcm8uCiAqLwogCmludCBub3RpZmllcl9jaGFpbl9yZWdpc3RlcihzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgKipsaXN0LCBzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgKm4pCnsKCXdyaXRlX2xvY2soJm5vdGlmaWVyX2xvY2spOwoJd2hpbGUoKmxpc3QpCgl7CgkJaWYobi0+cHJpb3JpdHkgPiAoKmxpc3QpLT5wcmlvcml0eSkKCQkJYnJlYWs7CgkJbGlzdD0gJigoKmxpc3QpLT5uZXh0KTsKCX0KCW4tPm5leHQgPSAqbGlzdDsKCSpsaXN0PW47Cgl3cml0ZV91bmxvY2soJm5vdGlmaWVyX2xvY2spOwoJcmV0dXJuIDA7Cn0KCkVYUE9SVF9TWU1CT0wobm90aWZpZXJfY2hhaW5fcmVnaXN0ZXIpOwoKLyoqCiAqCW5vdGlmaWVyX2NoYWluX3VucmVnaXN0ZXIgLSBSZW1vdmUgbm90aWZpZXIgZnJvbSBhIG5vdGlmaWVyIGNoYWluCiAqCUBubDogUG9pbnRlciB0byByb290IGxpc3QgcG9pbnRlcgogKglAbjogTmV3IGVudHJ5IGluIG5vdGlmaWVyIGNoYWluCiAqCiAqCVJlbW92ZXMgYSBub3RpZmllciBmcm9tIGEgbm90aWZpZXIgY2hhaW4uCiAqCiAqCVJldHVybnMgemVybyBvbiBzdWNjZXNzLCBvciAlLUVOT0VOVCBvbiBmYWlsdXJlLgogKi8KIAppbnQgbm90aWZpZXJfY2hhaW5fdW5yZWdpc3RlcihzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgKipubCwgc3RydWN0IG5vdGlmaWVyX2Jsb2NrICpuKQp7Cgl3cml0ZV9sb2NrKCZub3RpZmllcl9sb2NrKTsKCXdoaWxlKCgqbmwpIT1OVUxMKQoJewoJCWlmKCgqbmwpPT1uKQoJCXsKCQkJKm5sPW4tPm5leHQ7CgkJCXdyaXRlX3VubG9jaygmbm90aWZpZXJfbG9jayk7CgkJCXJldHVybiAwOwoJCX0KCQlubD0mKCgqbmwpLT5uZXh0KTsKCX0KCXdyaXRlX3VubG9jaygmbm90aWZpZXJfbG9jayk7CglyZXR1cm4gLUVOT0VOVDsKfQoKRVhQT1JUX1NZTUJPTChub3RpZmllcl9jaGFpbl91bnJlZ2lzdGVyKTsKCi8qKgogKglub3RpZmllcl9jYWxsX2NoYWluIC0gQ2FsbCBmdW5jdGlvbnMgaW4gYSBub3RpZmllciBjaGFpbgogKglAbjogUG9pbnRlciB0byByb290IHBvaW50ZXIgb2Ygbm90aWZpZXIgY2hhaW4KICoJQHZhbDogVmFsdWUgcGFzc2VkIHVubW9kaWZpZWQgdG8gbm90aWZpZXIgZnVuY3Rpb24KICoJQHY6IFBvaW50ZXIgcGFzc2VkIHVubW9kaWZpZWQgdG8gbm90aWZpZXIgZnVuY3Rpb24KICoKICoJQ2FsbHMgZWFjaCBmdW5jdGlvbiBpbiBhIG5vdGlmaWVyIGNoYWluIGluIHR1cm4uCiAqCiAqCUlmIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIG5vdGlmaWVyIGNhbiBiZSBhbmQnZAogKgl3aXRoICVOT1RJRllfU1RPUF9NQVNLLCB0aGVuIG5vdGlmaWVyX2NhbGxfY2hhaW4KICoJd2lsbCByZXR1cm4gaW1tZWRpYXRlbHksIHdpdGggdGhlIHJldHVybiB2YWx1ZSBvZgogKgl0aGUgbm90aWZpZXIgZnVuY3Rpb24gd2hpY2ggaGFsdGVkIGV4ZWN1dGlvbi4KICoJT3RoZXJ3aXNlLCB0aGUgcmV0dXJuIHZhbHVlIGlzIHRoZSByZXR1cm4gdmFsdWUKICoJb2YgdGhlIGxhc3Qgbm90aWZpZXIgZnVuY3Rpb24gY2FsbGVkLgogKi8KIAppbnQgbm90aWZpZXJfY2FsbF9jaGFpbihzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgKipuLCB1bnNpZ25lZCBsb25nIHZhbCwgdm9pZCAqdikKewoJaW50IHJldD1OT1RJRllfRE9ORTsKCXN0cnVjdCBub3RpZmllcl9ibG9jayAqbmIgPSAqbjsKCgl3aGlsZShuYikKCXsKCQlyZXQ9bmItPm5vdGlmaWVyX2NhbGwobmIsdmFsLHYpOwoJCWlmKHJldCZOT1RJRllfU1RPUF9NQVNLKQoJCXsKCQkJcmV0dXJuIHJldDsKCQl9CgkJbmI9bmItPm5leHQ7Cgl9CglyZXR1cm4gcmV0Owp9CgpFWFBPUlRfU1lNQk9MKG5vdGlmaWVyX2NhbGxfY2hhaW4pOwoKLyoqCiAqCXJlZ2lzdGVyX3JlYm9vdF9ub3RpZmllciAtIFJlZ2lzdGVyIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCBhdCByZWJvb3QgdGltZQogKglAbmI6IEluZm8gYWJvdXQgbm90aWZpZXIgZnVuY3Rpb24gdG8gYmUgY2FsbGVkCiAqCiAqCVJlZ2lzdGVycyBhIGZ1bmN0aW9uIHdpdGggdGhlIGxpc3Qgb2YgZnVuY3Rpb25zCiAqCXRvIGJlIGNhbGxlZCBhdCByZWJvb3QgdGltZS4KICoKICoJQ3VycmVudGx5IGFsd2F5cyByZXR1cm5zIHplcm8sIGFzIG5vdGlmaWVyX2NoYWluX3JlZ2lzdGVyCiAqCWFsd2F5cyByZXR1cm5zIHplcm8uCiAqLwogCmludCByZWdpc3Rlcl9yZWJvb3Rfbm90aWZpZXIoc3RydWN0IG5vdGlmaWVyX2Jsb2NrICogbmIpCnsKCXJldHVybiBub3RpZmllcl9jaGFpbl9yZWdpc3RlcigmcmVib290X25vdGlmaWVyX2xpc3QsIG5iKTsKfQoKRVhQT1JUX1NZTUJPTChyZWdpc3Rlcl9yZWJvb3Rfbm90aWZpZXIpOwoKLyoqCiAqCXVucmVnaXN0ZXJfcmVib290X25vdGlmaWVyIC0gVW5yZWdpc3RlciBwcmV2aW91c2x5IHJlZ2lzdGVyZWQgcmVib290IG5vdGlmaWVyCiAqCUBuYjogSG9vayB0byBiZSB1bnJlZ2lzdGVyZWQKICoKICoJVW5yZWdpc3RlcnMgYSBwcmV2aW91c2x5IHJlZ2lzdGVyZWQgcmVib290CiAqCW5vdGlmaWVyIGZ1bmN0aW9uLgogKgogKglSZXR1cm5zIHplcm8gb24gc3VjY2Vzcywgb3IgJS1FTk9FTlQgb24gZmFpbHVyZS4KICovCiAKaW50IHVucmVnaXN0ZXJfcmVib290X25vdGlmaWVyKHN0cnVjdCBub3RpZmllcl9ibG9jayAqIG5iKQp7CglyZXR1cm4gbm90aWZpZXJfY2hhaW5fdW5yZWdpc3RlcigmcmVib290X25vdGlmaWVyX2xpc3QsIG5iKTsKfQoKRVhQT1JUX1NZTUJPTCh1bnJlZ2lzdGVyX3JlYm9vdF9ub3RpZmllcik7CgpzdGF0aWMgaW50IHNldF9vbmVfcHJpbyhzdHJ1Y3QgdGFza19zdHJ1Y3QgKnAsIGludCBuaWNldmFsLCBpbnQgZXJyb3IpCnsKCWludCBub19uaWNlOwoKCWlmIChwLT51aWQgIT0gY3VycmVudC0+ZXVpZCAmJgoJCXAtPmV1aWQgIT0gY3VycmVudC0+ZXVpZCAmJiAhY2FwYWJsZShDQVBfU1lTX05JQ0UpKSB7CgkJZXJyb3IgPSAtRVBFUk07CgkJZ290byBvdXQ7Cgl9CglpZiAobmljZXZhbCA8IHRhc2tfbmljZShwKSAmJiAhY2FuX25pY2UocCwgbmljZXZhbCkpIHsKCQllcnJvciA9IC1FQUNDRVM7CgkJZ290byBvdXQ7Cgl9Cglub19uaWNlID0gc2VjdXJpdHlfdGFza19zZXRuaWNlKHAsIG5pY2V2YWwpOwoJaWYgKG5vX25pY2UpIHsKCQllcnJvciA9IG5vX25pY2U7CgkJZ290byBvdXQ7Cgl9CglpZiAoZXJyb3IgPT0gLUVTUkNIKQoJCWVycm9yID0gMDsKCXNldF91c2VyX25pY2UocCwgbmljZXZhbCk7Cm91dDoKCXJldHVybiBlcnJvcjsKfQoKYXNtbGlua2FnZSBsb25nIHN5c19zZXRwcmlvcml0eShpbnQgd2hpY2gsIGludCB3aG8sIGludCBuaWNldmFsKQp7CglzdHJ1Y3QgdGFza19zdHJ1Y3QgKmcsICpwOwoJc3RydWN0IHVzZXJfc3RydWN0ICp1c2VyOwoJaW50IGVycm9yID0gLUVJTlZBTDsKCglpZiAod2hpY2ggPiAyIHx8IHdoaWNoIDwgMCkKCQlnb3RvIG91dDsKCgkvKiBub3JtYWxpemU6IGF2b2lkIHNpZ25lZCBkaXZpc2lvbiAocm91bmRpbmcgcHJvYmxlbXMpICovCgllcnJvciA9IC1FU1JDSDsKCWlmIChuaWNldmFsIDwgLTIwKQoJCW5pY2V2YWwgPSAtMjA7CglpZiAobmljZXZhbCA+IDE5KQoJCW5pY2V2YWwgPSAxOTsKCglyZWFkX2xvY2soJnRhc2tsaXN0X2xvY2spOwoJc3dpdGNoICh3aGljaCkgewoJCWNhc2UgUFJJT19QUk9DRVNTOgoJCQlpZiAoIXdobykKCQkJCXdobyA9IGN1cnJlbnQtPnBpZDsKCQkJcCA9IGZpbmRfdGFza19ieV9waWQod2hvKTsKCQkJaWYgKHApCgkJCQllcnJvciA9IHNldF9vbmVfcHJpbyhwLCBuaWNldmFsLCBlcnJvcik7CgkJCWJyZWFrOwoJCWNhc2UgUFJJT19QR1JQOgoJCQlpZiAoIXdobykKCQkJCXdobyA9IHByb2Nlc3NfZ3JvdXAoY3VycmVudCk7CgkJCWRvX2VhY2hfdGFza19waWQod2hvLCBQSURUWVBFX1BHSUQsIHApIHsKCQkJCWVycm9yID0gc2V0X29uZV9wcmlvKHAsIG5pY2V2YWwsIGVycm9yKTsKCQkJfSB3aGlsZV9lYWNoX3Rhc2tfcGlkKHdobywgUElEVFlQRV9QR0lELCBwKTsKCQkJYnJlYWs7CgkJY2FzZSBQUklPX1VTRVI6CgkJCXVzZXIgPSBjdXJyZW50LT51c2VyOwoJCQlpZiAoIXdobykKCQkJCXdobyA9IGN1cnJlbnQtPnVpZDsKCQkJZWxzZQoJCQkJaWYgKCh3aG8gIT0gY3VycmVudC0+dWlkKSAmJiAhKHVzZXIgPSBmaW5kX3VzZXIod2hvKSkpCgkJCQkJZ290byBvdXRfdW5sb2NrOwkvKiBObyBwcm9jZXNzZXMgZm9yIHRoaXMgdXNlciAqLwoKCQkJZG9fZWFjaF90aHJlYWQoZywgcCkKCQkJCWlmIChwLT51aWQgPT0gd2hvKQoJCQkJCWVycm9yID0gc2V0X29uZV9wcmlvKHAsIG5pY2V2YWwsIGVycm9yKTsKCQkJd2hpbGVfZWFjaF90aHJlYWQoZywgcCk7CgkJCWlmICh3aG8gIT0gY3VycmVudC0+dWlkKQoJCQkJZnJlZV91aWQodXNlcik7CQkvKiBGb3IgZmluZF91c2VyKCkgKi8KCQkJYnJlYWs7Cgl9Cm91dF91bmxvY2s6CglyZWFkX3VubG9jaygmdGFza2xpc3RfbG9jayk7Cm91dDoKCXJldHVybiBlcnJvcjsKfQoKLyoKICogVWdoLiBUbyBhdm9pZCBuZWdhdGl2ZSByZXR1cm4gdmFsdWVzLCAiZ2V0cHJpb3JpdHkoKSIgd2lsbAogKiBub3QgcmV0dXJuIHRoZSBub3JtYWwgbmljZS12YWx1ZSwgYnV0IGEgbmVnYXRlZCB2YWx1ZSB0aGF0CiAqIGhhcyBiZWVuIG9mZnNldCBieSAyMCAoaWUgaXQgcmV0dXJucyA0MC4uMSBpbnN0ZWFkIG9mIC0yMC4uMTkpCiAqIHRvIHN0YXkgY29tcGF0aWJsZS4KICovCmFzbWxpbmthZ2UgbG9uZyBzeXNfZ2V0cHJpb3JpdHkoaW50IHdoaWNoLCBpbnQgd2hvKQp7CglzdHJ1Y3QgdGFza19zdHJ1Y3QgKmcsICpwOwoJc3RydWN0IHVzZXJfc3RydWN0ICp1c2VyOwoJbG9uZyBuaWNldmFsLCByZXR2YWwgPSAtRVNSQ0g7CgoJaWYgKHdoaWNoID4gMiB8fCB3aGljaCA8IDApCgkJcmV0dXJuIC1FSU5WQUw7CgoJcmVhZF9sb2NrKCZ0YXNrbGlzdF9sb2NrKTsKCXN3aXRjaCAod2hpY2gpIHsKCQljYXNlIFBSSU9fUFJPQ0VTUzoKCQkJaWYgKCF3aG8pCgkJCQl3aG8gPSBjdXJyZW50LT5waWQ7CgkJCXAgPSBmaW5kX3Rhc2tfYnlfcGlkKHdobyk7CgkJCWlmIChwKSB7CgkJCQluaWNldmFsID0gMjAgLSB0YXNrX25pY2UocCk7CgkJCQlpZiAobmljZXZhbCA+IHJldHZhbCkKCQkJCQlyZXR2YWwgPSBuaWNldmFsOwoJCQl9CgkJCWJyZWFrOwoJCWNhc2UgUFJJT19QR1JQOgoJCQlpZiAoIXdobykKCQkJCXdobyA9IHByb2Nlc3NfZ3JvdXAoY3VycmVudCk7CgkJCWRvX2VhY2hfdGFza19waWQod2hvLCBQSURUWVBFX1BHSUQsIHApIHsKCQkJCW5pY2V2YWwgPSAyMCAtIHRhc2tfbmljZShwKTsKCQkJCWlmIChuaWNldmFsID4gcmV0dmFsKQoJCQkJCXJldHZhbCA9IG5pY2V2YWw7CgkJCX0gd2hpbGVfZWFjaF90YXNrX3BpZCh3aG8sIFBJRFRZUEVfUEdJRCwgcCk7CgkJCWJyZWFrOwoJCWNhc2UgUFJJT19VU0VSOgoJCQl1c2VyID0gY3VycmVudC0+dXNlcjsKCQkJaWYgKCF3aG8pCgkJCQl3aG8gPSBjdXJyZW50LT51aWQ7CgkJCWVsc2UKCQkJCWlmICgod2hvICE9IGN1cnJlbnQtPnVpZCkgJiYgISh1c2VyID0gZmluZF91c2VyKHdobykpKQoJCQkJCWdvdG8gb3V0X3VubG9jazsJLyogTm8gcHJvY2Vzc2VzIGZvciB0aGlzIHVzZXIgKi8KCgkJCWRvX2VhY2hfdGhyZWFkKGcsIHApCgkJCQlpZiAocC0+dWlkID09IHdobykgewoJCQkJCW5pY2V2YWwgPSAyMCAtIHRhc2tfbmljZShwKTsKCQkJCQlpZiAobmljZXZhbCA+IHJldHZhbCkKCQkJCQkJcmV0dmFsID0gbmljZXZhbDsKCQkJCX0KCQkJd2hpbGVfZWFjaF90aHJlYWQoZywgcCk7CgkJCWlmICh3aG8gIT0gY3VycmVudC0+dWlkKQoJCQkJZnJlZV91aWQodXNlcik7CQkvKiBmb3IgZmluZF91c2VyKCkgKi8KCQkJYnJlYWs7Cgl9Cm91dF91bmxvY2s6CglyZWFkX3VubG9jaygmdGFza2xpc3RfbG9jayk7CgoJcmV0dXJuIHJldHZhbDsKfQoKCi8qCiAqIFJlYm9vdCBzeXN0ZW0gY2FsbDogZm9yIG9idmlvdXMgcmVhc29ucyBvbmx5IHJvb3QgbWF5IGNhbGwgaXQsCiAqIGFuZCBldmVuIHJvb3QgbmVlZHMgdG8gc2V0IHVwIHNvbWUgbWFnaWMgbnVtYmVycyBpbiB0aGUgcmVnaXN0ZXJzCiAqIHNvIHRoYXQgc29tZSBtaXN0YWtlIHdvbid0IG1ha2UgdGhpcyByZWJvb3QgdGhlIHdob2xlIG1hY2hpbmUuCiAqIFlvdSBjYW4gYWxzbyBzZXQgdGhlIG1lYW5pbmcgb2YgdGhlIGN0cmwtYWx0LWRlbC1rZXkgaGVyZS4KICoKICogcmVib290IGRvZXNuJ3Qgc3luYzogZG8gdGhhdCB5b3Vyc2VsZiBiZWZvcmUgY2FsbGluZyB0aGlzLgogKi8KYXNtbGlua2FnZSBsb25nIHN5c19yZWJvb3QoaW50IG1hZ2ljMSwgaW50IG1hZ2ljMiwgdW5zaWduZWQgaW50IGNtZCwgdm9pZCBfX3VzZXIgKiBhcmcpCnsKCWNoYXIgYnVmZmVyWzI1Nl07CgoJLyogV2Ugb25seSB0cnVzdCB0aGUgc3VwZXJ1c2VyIHdpdGggcmVib290aW5nIHRoZSBzeXN0ZW0uICovCglpZiAoIWNhcGFibGUoQ0FQX1NZU19CT09UKSkKCQlyZXR1cm4gLUVQRVJNOwoKCS8qIEZvciBzYWZldHksIHdlIHJlcXVpcmUgIm1hZ2ljIiBhcmd1bWVudHMuICovCglpZiAobWFnaWMxICE9IExJTlVYX1JFQk9PVF9NQUdJQzEgfHwKCSAgICAobWFnaWMyICE9IExJTlVYX1JFQk9PVF9NQUdJQzIgJiYKCSAgICAgICAgICAgICAgICBtYWdpYzIgIT0gTElOVVhfUkVCT09UX01BR0lDMkEgJiYKCQkJbWFnaWMyICE9IExJTlVYX1JFQk9PVF9NQUdJQzJCICYmCgkgICAgICAgICAgICAgICAgbWFnaWMyICE9IExJTlVYX1JFQk9PVF9NQUdJQzJDKSkKCQlyZXR1cm4gLUVJTlZBTDsKCglsb2NrX2tlcm5lbCgpOwoJc3dpdGNoIChjbWQpIHsKCWNhc2UgTElOVVhfUkVCT09UX0NNRF9SRVNUQVJUOgoJCW5vdGlmaWVyX2NhbGxfY2hhaW4oJnJlYm9vdF9ub3RpZmllcl9saXN0LCBTWVNfUkVTVEFSVCwgTlVMTCk7CgkJc3lzdGVtX3N0YXRlID0gU1lTVEVNX1JFU1RBUlQ7CgkJZGV2aWNlX3NodXRkb3duKCk7CgkJcHJpbnRrKEtFUk5fRU1FUkcgIlJlc3RhcnRpbmcgc3lzdGVtLlxuIik7CgkJbWFjaGluZV9yZXN0YXJ0KE5VTEwpOwoJCWJyZWFrOwoKCWNhc2UgTElOVVhfUkVCT09UX0NNRF9DQURfT046CgkJQ19BX0QgPSAxOwoJCWJyZWFrOwoKCWNhc2UgTElOVVhfUkVCT09UX0NNRF9DQURfT0ZGOgoJCUNfQV9EID0gMDsKCQlicmVhazsKCgljYXNlIExJTlVYX1JFQk9PVF9DTURfSEFMVDoKCQlub3RpZmllcl9jYWxsX2NoYWluKCZyZWJvb3Rfbm90aWZpZXJfbGlzdCwgU1lTX0hBTFQsIE5VTEwpOwoJCXN5c3RlbV9zdGF0ZSA9IFNZU1RFTV9IQUxUOwoJCWRldmljZV9zdXNwZW5kKFBNU0dfU1VTUEVORCk7CgkJZGV2aWNlX3NodXRkb3duKCk7CgkJcHJpbnRrKEtFUk5fRU1FUkcgIlN5c3RlbSBoYWx0ZWQuXG4iKTsKCQltYWNoaW5lX2hhbHQoKTsKCQl1bmxvY2tfa2VybmVsKCk7CgkJZG9fZXhpdCgwKTsKCQlicmVhazsKCgljYXNlIExJTlVYX1JFQk9PVF9DTURfUE9XRVJfT0ZGOgoJCW5vdGlmaWVyX2NhbGxfY2hhaW4oJnJlYm9vdF9ub3RpZmllcl9saXN0LCBTWVNfUE9XRVJfT0ZGLCBOVUxMKTsKCQlzeXN0ZW1fc3RhdGUgPSBTWVNURU1fUE9XRVJfT0ZGOwoJCWRldmljZV9zdXNwZW5kKFBNU0dfU1VTUEVORCk7CgkJZGV2aWNlX3NodXRkb3duKCk7CgkJcHJpbnRrKEtFUk5fRU1FUkcgIlBvd2VyIGRvd24uXG4iKTsKCQltYWNoaW5lX3Bvd2VyX29mZigpOwoJCXVubG9ja19rZXJuZWwoKTsKCQlkb19leGl0KDApOwoJCWJyZWFrOwoKCWNhc2UgTElOVVhfUkVCT09UX0NNRF9SRVNUQVJUMjoKCQlpZiAoc3RybmNweV9mcm9tX3VzZXIoJmJ1ZmZlclswXSwgYXJnLCBzaXplb2YoYnVmZmVyKSAtIDEpIDwgMCkgewoJCQl1bmxvY2tfa2VybmVsKCk7CgkJCXJldHVybiAtRUZBVUxUOwoJCX0KCQlidWZmZXJbc2l6ZW9mKGJ1ZmZlcikgLSAxXSA9ICdcMCc7CgoJCW5vdGlmaWVyX2NhbGxfY2hhaW4oJnJlYm9vdF9ub3RpZmllcl9saXN0LCBTWVNfUkVTVEFSVCwgYnVmZmVyKTsKCQlzeXN0ZW1fc3RhdGUgPSBTWVNURU1fUkVTVEFSVDsKCQlkZXZpY2Vfc3VzcGVuZChQTVNHX0ZSRUVaRSk7CgkJZGV2aWNlX3NodXRkb3duKCk7CgkJcHJpbnRrKEtFUk5fRU1FUkcgIlJlc3RhcnRpbmcgc3lzdGVtIHdpdGggY29tbWFuZCAnJXMnLlxuIiwgYnVmZmVyKTsKCQltYWNoaW5lX3Jlc3RhcnQoYnVmZmVyKTsKCQlicmVhazsKCiNpZmRlZiBDT05GSUdfS0VYRUMKCWNhc2UgTElOVVhfUkVCT09UX0NNRF9LRVhFQzoKCXsKCQlzdHJ1Y3Qga2ltYWdlICppbWFnZTsKCQlpbWFnZSA9IHhjaGcoJmtleGVjX2ltYWdlLCAwKTsKCQlpZiAoIWltYWdlKSB7CgkJCXVubG9ja19rZXJuZWwoKTsKCQkJcmV0dXJuIC1FSU5WQUw7CgkJfQoJCW5vdGlmaWVyX2NhbGxfY2hhaW4oJnJlYm9vdF9ub3RpZmllcl9saXN0LCBTWVNfUkVTVEFSVCwgTlVMTCk7CgkJc3lzdGVtX3N0YXRlID0gU1lTVEVNX1JFU1RBUlQ7CgkJZGV2aWNlX3NodXRkb3duKCk7CgkJcHJpbnRrKEtFUk5fRU1FUkcgIlN0YXJ0aW5nIG5ldyBrZXJuZWxcbiIpOwoJCW1hY2hpbmVfc2h1dGRvd24oKTsKCQltYWNoaW5lX2tleGVjKGltYWdlKTsKCQlicmVhazsKCX0KI2VuZGlmCiNpZmRlZiBDT05GSUdfU09GVFdBUkVfU1VTUEVORAoJY2FzZSBMSU5VWF9SRUJPT1RfQ01EX1NXX1NVU1BFTkQ6CgkJewoJCQlpbnQgcmV0ID0gc29mdHdhcmVfc3VzcGVuZCgpOwoJCQl1bmxvY2tfa2VybmVsKCk7CgkJCXJldHVybiByZXQ7CgkJfQojZW5kaWYKCglkZWZhdWx0OgoJCXVubG9ja19rZXJuZWwoKTsKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCXVubG9ja19rZXJuZWwoKTsKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBkZWZlcnJlZF9jYWQodm9pZCAqZHVtbXkpCnsKCW5vdGlmaWVyX2NhbGxfY2hhaW4oJnJlYm9vdF9ub3RpZmllcl9saXN0LCBTWVNfUkVTVEFSVCwgTlVMTCk7CgltYWNoaW5lX3Jlc3RhcnQoTlVMTCk7Cn0KCi8qCiAqIFRoaXMgZnVuY3Rpb24gZ2V0cyBjYWxsZWQgYnkgY3RybC1hbHQtZGVsIC0gaWUgdGhlIGtleWJvYXJkIGludGVycnVwdC4KICogQXMgaXQncyBjYWxsZWQgd2l0aGluIGFuIGludGVycnVwdCwgaXQgbWF5IE5PVCBzeW5jOiB0aGUgb25seSBjaG9pY2UKICogaXMgd2hldGhlciB0byByZWJvb3QgYXQgb25jZSwgb3IganVzdCBpZ25vcmUgdGhlIGN0cmwtYWx0LWRlbC4KICovCnZvaWQgY3RybF9hbHRfZGVsKHZvaWQpCnsKCXN0YXRpYyBERUNMQVJFX1dPUksoY2FkX3dvcmssIGRlZmVycmVkX2NhZCwgTlVMTCk7CgoJaWYgKENfQV9EKQoJCXNjaGVkdWxlX3dvcmsoJmNhZF93b3JrKTsKCWVsc2UKCQlraWxsX3Byb2MoY2FkX3BpZCwgU0lHSU5ULCAxKTsKfQoJCgovKgogKiBVbnByaXZpbGVnZWQgdXNlcnMgbWF5IGNoYW5nZSB0aGUgcmVhbCBnaWQgdG8gdGhlIGVmZmVjdGl2ZSBnaWQKICogb3IgdmljZSB2ZXJzYS4gIChCU0Qtc3R5bGUpCiAqCiAqIElmIHlvdSBzZXQgdGhlIHJlYWwgZ2lkIGF0IGFsbCwgb3Igc2V0IHRoZSBlZmZlY3RpdmUgZ2lkIHRvIGEgdmFsdWUgbm90CiAqIGVxdWFsIHRvIHRoZSByZWFsIGdpZCwgdGhlbiB0aGUgc2F2ZWQgZ2lkIGlzIHNldCB0byB0aGUgbmV3IGVmZmVjdGl2ZSBnaWQuCiAqCiAqIFRoaXMgbWFrZXMgaXQgcG9zc2libGUgZm9yIGEgc2V0Z2lkIHByb2dyYW0gdG8gY29tcGxldGVseSBkcm9wIGl0cwogKiBwcml2aWxlZ2VzLCB3aGljaCBpcyBvZnRlbiBhIHVzZWZ1bCBhc3NlcnRpb24gdG8gbWFrZSB3aGVuIHlvdSBhcmUgZG9pbmcKICogYSBzZWN1cml0eSBhdWRpdCBvdmVyIGEgcHJvZ3JhbS4KICoKICogVGhlIGdlbmVyYWwgaWRlYSBpcyB0aGF0IGEgcHJvZ3JhbSB3aGljaCB1c2VzIGp1c3Qgc2V0cmVnaWQoKSB3aWxsIGJlCiAqIDEwMCUgY29tcGF0aWJsZSB3aXRoIEJTRC4gIEEgcHJvZ3JhbSB3aGljaCB1c2VzIGp1c3Qgc2V0Z2lkKCkgd2lsbCBiZQogKiAxMDAlIGNvbXBhdGlibGUgd2l0aCBQT1NJWCB3aXRoIHNhdmVkIElEcy4gCiAqCiAqIFNNUDogVGhlcmUgYXJlIG5vdCByYWNlcywgdGhlIEdJRHMgYXJlIGNoZWNrZWQgb25seSBieSBmaWxlc3lzdGVtCiAqICAgICAgb3BlcmF0aW9ucyAoYXMgZmFyIGFzIHNlbWFudGljIHByZXNlcnZhdGlvbiBpcyBjb25jZXJuZWQpLgogKi8KYXNtbGlua2FnZSBsb25nIHN5c19zZXRyZWdpZChnaWRfdCByZ2lkLCBnaWRfdCBlZ2lkKQp7CglpbnQgb2xkX3JnaWQgPSBjdXJyZW50LT5naWQ7CglpbnQgb2xkX2VnaWQgPSBjdXJyZW50LT5lZ2lkOwoJaW50IG5ld19yZ2lkID0gb2xkX3JnaWQ7CglpbnQgbmV3X2VnaWQgPSBvbGRfZWdpZDsKCWludCByZXR2YWw7CgoJcmV0dmFsID0gc2VjdXJpdHlfdGFza19zZXRnaWQocmdpZCwgZWdpZCwgKGdpZF90KS0xLCBMU01fU0VUSURfUkUpOwoJaWYgKHJldHZhbCkKCQlyZXR1cm4gcmV0dmFsOwoKCWlmIChyZ2lkICE9IChnaWRfdCkgLTEpIHsKCQlpZiAoKG9sZF9yZ2lkID09IHJnaWQpIHx8CgkJICAgIChjdXJyZW50LT5lZ2lkPT1yZ2lkKSB8fAoJCSAgICBjYXBhYmxlKENBUF9TRVRHSUQpKQoJCQluZXdfcmdpZCA9IHJnaWQ7CgkJZWxzZQoJCQlyZXR1cm4gLUVQRVJNOwoJfQoJaWYgKGVnaWQgIT0gKGdpZF90KSAtMSkgewoJCWlmICgob2xkX3JnaWQgPT0gZWdpZCkgfHwKCQkgICAgKGN1cnJlbnQtPmVnaWQgPT0gZWdpZCkgfHwKCQkgICAgKGN1cnJlbnQtPnNnaWQgPT0gZWdpZCkgfHwKCQkgICAgY2FwYWJsZShDQVBfU0VUR0lEKSkKCQkJbmV3X2VnaWQgPSBlZ2lkOwoJCWVsc2UgewoJCQlyZXR1cm4gLUVQRVJNOwoJCX0KCX0KCWlmIChuZXdfZWdpZCAhPSBvbGRfZWdpZCkKCXsKCQljdXJyZW50LT5tbS0+ZHVtcGFibGUgPSBzdWlkX2R1bXBhYmxlOwoJCXNtcF93bWIoKTsKCX0KCWlmIChyZ2lkICE9IChnaWRfdCkgLTEgfHwKCSAgICAoZWdpZCAhPSAoZ2lkX3QpIC0xICYmIGVnaWQgIT0gb2xkX3JnaWQpKQoJCWN1cnJlbnQtPnNnaWQgPSBuZXdfZWdpZDsKCWN1cnJlbnQtPmZzZ2lkID0gbmV3X2VnaWQ7CgljdXJyZW50LT5lZ2lkID0gbmV3X2VnaWQ7CgljdXJyZW50LT5naWQgPSBuZXdfcmdpZDsKCWtleV9mc2dpZF9jaGFuZ2VkKGN1cnJlbnQpOwoJcmV0dXJuIDA7Cn0KCi8qCiAqIHNldGdpZCgpIGlzIGltcGxlbWVudGVkIGxpa2UgU3lzViB3LyBTQVZFRF9JRFMgCiAqCiAqIFNNUDogU2FtZSBpbXBsaWNpdCByYWNlcyBhcyBhYm92ZS4KICovCmFzbWxpbmthZ2UgbG9uZyBzeXNfc2V0Z2lkKGdpZF90IGdpZCkKewoJaW50IG9sZF9lZ2lkID0gY3VycmVudC0+ZWdpZDsKCWludCByZXR2YWw7CgoJcmV0dmFsID0gc2VjdXJpdHlfdGFza19zZXRnaWQoZ2lkLCAoZ2lkX3QpLTEsIChnaWRfdCktMSwgTFNNX1NFVElEX0lEKTsKCWlmIChyZXR2YWwpCgkJcmV0dXJuIHJldHZhbDsKCglpZiAoY2FwYWJsZShDQVBfU0VUR0lEKSkKCXsKCQlpZihvbGRfZWdpZCAhPSBnaWQpCgkJewoJCQljdXJyZW50LT5tbS0+ZHVtcGFibGUgPSBzdWlkX2R1bXBhYmxlOwoJCQlzbXBfd21iKCk7CgkJfQoJCWN1cnJlbnQtPmdpZCA9IGN1cnJlbnQtPmVnaWQgPSBjdXJyZW50LT5zZ2lkID0gY3VycmVudC0+ZnNnaWQgPSBnaWQ7Cgl9CgllbHNlIGlmICgoZ2lkID09IGN1cnJlbnQtPmdpZCkgfHwgKGdpZCA9PSBjdXJyZW50LT5zZ2lkKSkKCXsKCQlpZihvbGRfZWdpZCAhPSBnaWQpCgkJewoJCQljdXJyZW50LT5tbS0+ZHVtcGFibGUgPSBzdWlkX2R1bXBhYmxlOwoJCQlzbXBfd21iKCk7CgkJfQoJCWN1cnJlbnQtPmVnaWQgPSBjdXJyZW50LT5mc2dpZCA9IGdpZDsKCX0KCWVsc2UKCQlyZXR1cm4gLUVQRVJNOwoKCWtleV9mc2dpZF9jaGFuZ2VkKGN1cnJlbnQpOwoJcmV0dXJuIDA7Cn0KICAKc3RhdGljIGludCBzZXRfdXNlcih1aWRfdCBuZXdfcnVpZCwgaW50IGR1bXBjbGVhcikKewoJc3RydWN0IHVzZXJfc3RydWN0ICpuZXdfdXNlcjsKCgluZXdfdXNlciA9IGFsbG9jX3VpZChuZXdfcnVpZCk7CglpZiAoIW5ld191c2VyKQoJCXJldHVybiAtRUFHQUlOOwoKCWlmIChhdG9taWNfcmVhZCgmbmV3X3VzZXItPnByb2Nlc3NlcykgPj0KCQkJCWN1cnJlbnQtPnNpZ25hbC0+cmxpbVtSTElNSVRfTlBST0NdLnJsaW1fY3VyICYmCgkJCW5ld191c2VyICE9ICZyb290X3VzZXIpIHsKCQlmcmVlX3VpZChuZXdfdXNlcik7CgkJcmV0dXJuIC1FQUdBSU47Cgl9CgoJc3dpdGNoX3VpZChuZXdfdXNlcik7CgoJaWYoZHVtcGNsZWFyKQoJewoJCWN1cnJlbnQtPm1tLT5kdW1wYWJsZSA9IHN1aWRfZHVtcGFibGU7CgkJc21wX3dtYigpOwoJfQoJY3VycmVudC0+dWlkID0gbmV3X3J1aWQ7CglyZXR1cm4gMDsKfQoKLyoKICogVW5wcml2aWxlZ2VkIHVzZXJzIG1heSBjaGFuZ2UgdGhlIHJlYWwgdWlkIHRvIHRoZSBlZmZlY3RpdmUgdWlkCiAqIG9yIHZpY2UgdmVyc2EuICAoQlNELXN0eWxlKQogKgogKiBJZiB5b3Ugc2V0IHRoZSByZWFsIHVpZCBhdCBhbGwsIG9yIHNldCB0aGUgZWZmZWN0aXZlIHVpZCB0byBhIHZhbHVlIG5vdAogKiBlcXVhbCB0byB0aGUgcmVhbCB1aWQsIHRoZW4gdGhlIHNhdmVkIHVpZCBpcyBzZXQgdG8gdGhlIG5ldyBlZmZlY3RpdmUgdWlkLgogKgogKiBUaGlzIG1ha2VzIGl0IHBvc3NpYmxlIGZvciBhIHNldHVpZCBwcm9ncmFtIHRvIGNvbXBsZXRlbHkgZHJvcCBpdHMKICogcHJpdmlsZWdlcywgd2hpY2ggaXMgb2Z0ZW4gYSB1c2VmdWwgYXNzZXJ0aW9uIHRvIG1ha2Ugd2hlbiB5b3UgYXJlIGRvaW5nCiAqIGEgc2VjdXJpdHkgYXVkaXQgb3ZlciBhIHByb2dyYW0uCiAqCiAqIFRoZSBnZW5lcmFsIGlkZWEgaXMgdGhhdCBhIHByb2dyYW0gd2hpY2ggdXNlcyBqdXN0IHNldHJldWlkKCkgd2lsbCBiZQogKiAxMDAlIGNvbXBhdGlibGUgd2l0aCBCU0QuICBBIHByb2dyYW0gd2hpY2ggdXNlcyBqdXN0IHNldHVpZCgpIHdpbGwgYmUKICogMTAwJSBjb21wYXRpYmxlIHdpdGggUE9TSVggd2l0aCBzYXZlZCBJRHMuIAogKi8KYXNtbGlua2FnZSBsb25nIHN5c19zZXRyZXVpZCh1aWRfdCBydWlkLCB1aWRfdCBldWlkKQp7CglpbnQgb2xkX3J1aWQsIG9sZF9ldWlkLCBvbGRfc3VpZCwgbmV3X3J1aWQsIG5ld19ldWlkOwoJaW50IHJldHZhbDsKCglyZXR2YWwgPSBzZWN1cml0eV90YXNrX3NldHVpZChydWlkLCBldWlkLCAodWlkX3QpLTEsIExTTV9TRVRJRF9SRSk7CglpZiAocmV0dmFsKQoJCXJldHVybiByZXR2YWw7CgoJbmV3X3J1aWQgPSBvbGRfcnVpZCA9IGN1cnJlbnQtPnVpZDsKCW5ld19ldWlkID0gb2xkX2V1aWQgPSBjdXJyZW50LT5ldWlkOwoJb2xkX3N1aWQgPSBjdXJyZW50LT5zdWlkOwoKCWlmIChydWlkICE9ICh1aWRfdCkgLTEpIHsKCQluZXdfcnVpZCA9IHJ1aWQ7CgkJaWYgKChvbGRfcnVpZCAhPSBydWlkKSAmJgoJCSAgICAoY3VycmVudC0+ZXVpZCAhPSBydWlkKSAmJgoJCSAgICAhY2FwYWJsZShDQVBfU0VUVUlEKSkKCQkJcmV0dXJuIC1FUEVSTTsKCX0KCglpZiAoZXVpZCAhPSAodWlkX3QpIC0xKSB7CgkJbmV3X2V1aWQgPSBldWlkOwoJCWlmICgob2xkX3J1aWQgIT0gZXVpZCkgJiYKCQkgICAgKGN1cnJlbnQtPmV1aWQgIT0gZXVpZCkgJiYKCQkgICAgKGN1cnJlbnQtPnN1aWQgIT0gZXVpZCkgJiYKCQkgICAgIWNhcGFibGUoQ0FQX1NFVFVJRCkpCgkJCXJldHVybiAtRVBFUk07Cgl9CgoJaWYgKG5ld19ydWlkICE9IG9sZF9ydWlkICYmIHNldF91c2VyKG5ld19ydWlkLCBuZXdfZXVpZCAhPSBvbGRfZXVpZCkgPCAwKQoJCXJldHVybiAtRUFHQUlOOwoKCWlmIChuZXdfZXVpZCAhPSBvbGRfZXVpZCkKCXsKCQljdXJyZW50LT5tbS0+ZHVtcGFibGUgPSBzdWlkX2R1bXBhYmxlOwoJCXNtcF93bWIoKTsKCX0KCWN1cnJlbnQtPmZzdWlkID0gY3VycmVudC0+ZXVpZCA9IG5ld19ldWlkOwoJaWYgKHJ1aWQgIT0gKHVpZF90KSAtMSB8fAoJICAgIChldWlkICE9ICh1aWRfdCkgLTEgJiYgZXVpZCAhPSBvbGRfcnVpZCkpCgkJY3VycmVudC0+c3VpZCA9IGN1cnJlbnQtPmV1aWQ7CgljdXJyZW50LT5mc3VpZCA9IGN1cnJlbnQtPmV1aWQ7CgoJa2V5X2ZzdWlkX2NoYW5nZWQoY3VycmVudCk7CgoJcmV0dXJuIHNlY3VyaXR5X3Rhc2tfcG9zdF9zZXR1aWQob2xkX3J1aWQsIG9sZF9ldWlkLCBvbGRfc3VpZCwgTFNNX1NFVElEX1JFKTsKfQoKCgkJCi8qCiAqIHNldHVpZCgpIGlzIGltcGxlbWVudGVkIGxpa2UgU3lzViB3aXRoIFNBVkVEX0lEUyAKICogCiAqIE5vdGUgdGhhdCBTQVZFRF9JRCdzIGlzIGRlZmljaWVudCBpbiB0aGF0IGEgc2V0dWlkIHJvb3QgcHJvZ3JhbQogKiBsaWtlIHNlbmRtYWlsLCBmb3IgZXhhbXBsZSwgY2Fubm90IHNldCBpdHMgdWlkIHRvIGJlIGEgbm9ybWFsIAogKiB1c2VyIGFuZCB0aGVuIHN3aXRjaCBiYWNrLCBiZWNhdXNlIGlmIHlvdSdyZSByb290LCBzZXR1aWQoKSBzZXRzCiAqIHRoZSBzYXZlZCB1aWQgdG9vLiAgSWYgeW91IGRvbid0IGxpa2UgdGhpcywgYmxhbWUgdGhlIGJyaWdodCBwZW9wbGUKICogaW4gdGhlIFBPU0lYIGNvbW1pdHRlZSBhbmQvb3IgVVNHLiAgTm90ZSB0aGF0IHRoZSBCU0Qtc3R5bGUgc2V0cmV1aWQoKQogKiB3aWxsIGFsbG93IGEgcm9vdCBwcm9ncmFtIHRvIHRlbXBvcmFyaWx5IGRyb3AgcHJpdmlsZWdlcyBhbmQgYmUgYWJsZSB0bwogKiByZWdhaW4gdGhlbSBieSBzd2FwcGluZyB0aGUgcmVhbCBhbmQgZWZmZWN0aXZlIHVpZC4gIAogKi8KYXNtbGlua2FnZSBsb25nIHN5c19zZXR1aWQodWlkX3QgdWlkKQp7CglpbnQgb2xkX2V1aWQgPSBjdXJyZW50LT5ldWlkOwoJaW50IG9sZF9ydWlkLCBvbGRfc3VpZCwgbmV3X3J1aWQsIG5ld19zdWlkOwoJaW50IHJldHZhbDsKCglyZXR2YWwgPSBzZWN1cml0eV90YXNrX3NldHVpZCh1aWQsICh1aWRfdCktMSwgKHVpZF90KS0xLCBMU01fU0VUSURfSUQpOwoJaWYgKHJldHZhbCkKCQlyZXR1cm4gcmV0dmFsOwoKCW9sZF9ydWlkID0gbmV3X3J1aWQgPSBjdXJyZW50LT51aWQ7CglvbGRfc3VpZCA9IGN1cnJlbnQtPnN1aWQ7CgluZXdfc3VpZCA9IG9sZF9zdWlkOwoJCglpZiAoY2FwYWJsZShDQVBfU0VUVUlEKSkgewoJCWlmICh1aWQgIT0gb2xkX3J1aWQgJiYgc2V0X3VzZXIodWlkLCBvbGRfZXVpZCAhPSB1aWQpIDwgMCkKCQkJcmV0dXJuIC1FQUdBSU47CgkJbmV3X3N1aWQgPSB1aWQ7Cgl9IGVsc2UgaWYgKCh1aWQgIT0gY3VycmVudC0+dWlkKSAmJiAodWlkICE9IG5ld19zdWlkKSkKCQlyZXR1cm4gLUVQRVJNOwoKCWlmIChvbGRfZXVpZCAhPSB1aWQpCgl7CgkJY3VycmVudC0+bW0tPmR1bXBhYmxlID0gc3VpZF9kdW1wYWJsZTsKCQlzbXBfd21iKCk7Cgl9CgljdXJyZW50LT5mc3VpZCA9IGN1cnJlbnQtPmV1aWQgPSB1aWQ7CgljdXJyZW50LT5zdWlkID0gbmV3X3N1aWQ7CgoJa2V5X2ZzdWlkX2NoYW5nZWQoY3VycmVudCk7CgoJcmV0dXJuIHNlY3VyaXR5X3Rhc2tfcG9zdF9zZXR1aWQob2xkX3J1aWQsIG9sZF9ldWlkLCBvbGRfc3VpZCwgTFNNX1NFVElEX0lEKTsKfQoKCi8qCiAqIFRoaXMgZnVuY3Rpb24gaW1wbGVtZW50cyBhIGdlbmVyaWMgYWJpbGl0eSB0byB1cGRhdGUgcnVpZCwgZXVpZCwKICogYW5kIHN1aWQuICBUaGlzIGFsbG93cyB5b3UgdG8gaW1wbGVtZW50IHRoZSA0LjQgY29tcGF0aWJsZSBzZXRldWlkKCkuCiAqLwphc21saW5rYWdlIGxvbmcgc3lzX3NldHJlc3VpZCh1aWRfdCBydWlkLCB1aWRfdCBldWlkLCB1aWRfdCBzdWlkKQp7CglpbnQgb2xkX3J1aWQgPSBjdXJyZW50LT51aWQ7CglpbnQgb2xkX2V1aWQgPSBjdXJyZW50LT5ldWlkOwoJaW50IG9sZF9zdWlkID0gY3VycmVudC0+c3VpZDsKCWludCByZXR2YWw7CgoJcmV0dmFsID0gc2VjdXJpdHlfdGFza19zZXR1aWQocnVpZCwgZXVpZCwgc3VpZCwgTFNNX1NFVElEX1JFUyk7CglpZiAocmV0dmFsKQoJCXJldHVybiByZXR2YWw7CgoJaWYgKCFjYXBhYmxlKENBUF9TRVRVSUQpKSB7CgkJaWYgKChydWlkICE9ICh1aWRfdCkgLTEpICYmIChydWlkICE9IGN1cnJlbnQtPnVpZCkgJiYKCQkgICAgKHJ1aWQgIT0gY3VycmVudC0+ZXVpZCkgJiYgKHJ1aWQgIT0gY3VycmVudC0+c3VpZCkpCgkJCXJldHVybiAtRVBFUk07CgkJaWYgKChldWlkICE9ICh1aWRfdCkgLTEpICYmIChldWlkICE9IGN1cnJlbnQtPnVpZCkgJiYKCQkgICAgKGV1aWQgIT0gY3VycmVudC0+ZXVpZCkgJiYgKGV1aWQgIT0gY3VycmVudC0+c3VpZCkpCgkJCXJldHVybiAtRVBFUk07CgkJaWYgKChzdWlkICE9ICh1aWRfdCkgLTEpICYmIChzdWlkICE9IGN1cnJlbnQtPnVpZCkgJiYKCQkgICAgKHN1aWQgIT0gY3VycmVudC0+ZXVpZCkgJiYgKHN1aWQgIT0gY3VycmVudC0+c3VpZCkpCgkJCXJldHVybiAtRVBFUk07Cgl9CglpZiAocnVpZCAhPSAodWlkX3QpIC0xKSB7CgkJaWYgKHJ1aWQgIT0gY3VycmVudC0+dWlkICYmIHNldF91c2VyKHJ1aWQsIGV1aWQgIT0gY3VycmVudC0+ZXVpZCkgPCAwKQoJCQlyZXR1cm4gLUVBR0FJTjsKCX0KCWlmIChldWlkICE9ICh1aWRfdCkgLTEpIHsKCQlpZiAoZXVpZCAhPSBjdXJyZW50LT5ldWlkKQoJCXsKCQkJY3VycmVudC0+bW0tPmR1bXBhYmxlID0gc3VpZF9kdW1wYWJsZTsKCQkJc21wX3dtYigpOwoJCX0KCQljdXJyZW50LT5ldWlkID0gZXVpZDsKCX0KCWN1cnJlbnQtPmZzdWlkID0gY3VycmVudC0+ZXVpZDsKCWlmIChzdWlkICE9ICh1aWRfdCkgLTEpCgkJY3VycmVudC0+c3VpZCA9IHN1aWQ7CgoJa2V5X2ZzdWlkX2NoYW5nZWQoY3VycmVudCk7CgoJcmV0dXJuIHNlY3VyaXR5X3Rhc2tfcG9zdF9zZXR1aWQob2xkX3J1aWQsIG9sZF9ldWlkLCBvbGRfc3VpZCwgTFNNX1NFVElEX1JFUyk7Cn0KCmFzbWxpbmthZ2UgbG9uZyBzeXNfZ2V0cmVzdWlkKHVpZF90IF9fdXNlciAqcnVpZCwgdWlkX3QgX191c2VyICpldWlkLCB1aWRfdCBfX3VzZXIgKnN1aWQpCnsKCWludCByZXR2YWw7CgoJaWYgKCEocmV0dmFsID0gcHV0X3VzZXIoY3VycmVudC0+dWlkLCBydWlkKSkgJiYKCSAgICAhKHJldHZhbCA9IHB1dF91c2VyKGN1cnJlbnQtPmV1aWQsIGV1aWQpKSkKCQlyZXR2YWwgPSBwdXRfdXNlcihjdXJyZW50LT5zdWlkLCBzdWlkKTsKCglyZXR1cm4gcmV0dmFsOwp9CgovKgogKiBTYW1lIGFzIGFib3ZlLCBidXQgZm9yIHJnaWQsIGVnaWQsIHNnaWQuCiAqLwphc21saW5rYWdlIGxvbmcgc3lzX3NldHJlc2dpZChnaWRfdCByZ2lkLCBnaWRfdCBlZ2lkLCBnaWRfdCBzZ2lkKQp7CglpbnQgcmV0dmFsOwoKCXJldHZhbCA9IHNlY3VyaXR5X3Rhc2tfc2V0Z2lkKHJnaWQsIGVnaWQsIHNnaWQsIExTTV9TRVRJRF9SRVMpOwoJaWYgKHJldHZhbCkKCQlyZXR1cm4gcmV0dmFsOwoKCWlmICghY2FwYWJsZShDQVBfU0VUR0lEKSkgewoJCWlmICgocmdpZCAhPSAoZ2lkX3QpIC0xKSAmJiAocmdpZCAhPSBjdXJyZW50LT5naWQpICYmCgkJICAgIChyZ2lkICE9IGN1cnJlbnQtPmVnaWQpICYmIChyZ2lkICE9IGN1cnJlbnQtPnNnaWQpKQoJCQlyZXR1cm4gLUVQRVJNOwoJCWlmICgoZWdpZCAhPSAoZ2lkX3QpIC0xKSAmJiAoZWdpZCAhPSBjdXJyZW50LT5naWQpICYmCgkJICAgIChlZ2lkICE9IGN1cnJlbnQtPmVnaWQpICYmIChlZ2lkICE9IGN1cnJlbnQtPnNnaWQpKQoJCQlyZXR1cm4gLUVQRVJNOwoJCWlmICgoc2dpZCAhPSAoZ2lkX3QpIC0xKSAmJiAoc2dpZCAhPSBjdXJyZW50LT5naWQpICYmCgkJICAgIChzZ2lkICE9IGN1cnJlbnQtPmVnaWQpICYmIChzZ2lkICE9IGN1cnJlbnQtPnNnaWQpKQoJCQlyZXR1cm4gLUVQRVJNOwoJfQoJaWYgKGVnaWQgIT0gKGdpZF90KSAtMSkgewoJCWlmIChlZ2lkICE9IGN1cnJlbnQtPmVnaWQpCgkJewoJCQljdXJyZW50LT5tbS0+ZHVtcGFibGUgPSBzdWlkX2R1bXBhYmxlOwoJCQlzbXBfd21iKCk7CgkJfQoJCWN1cnJlbnQtPmVnaWQgPSBlZ2lkOwoJfQoJY3VycmVudC0+ZnNnaWQgPSBjdXJyZW50LT5lZ2lkOwoJaWYgKHJnaWQgIT0gKGdpZF90KSAtMSkKCQljdXJyZW50LT5naWQgPSByZ2lkOwoJaWYgKHNnaWQgIT0gKGdpZF90KSAtMSkKCQljdXJyZW50LT5zZ2lkID0gc2dpZDsKCglrZXlfZnNnaWRfY2hhbmdlZChjdXJyZW50KTsKCXJldHVybiAwOwp9Cgphc21saW5rYWdlIGxvbmcgc3lzX2dldHJlc2dpZChnaWRfdCBfX3VzZXIgKnJnaWQsIGdpZF90IF9fdXNlciAqZWdpZCwgZ2lkX3QgX191c2VyICpzZ2lkKQp7CglpbnQgcmV0dmFsOwoKCWlmICghKHJldHZhbCA9IHB1dF91c2VyKGN1cnJlbnQtPmdpZCwgcmdpZCkpICYmCgkgICAgIShyZXR2YWwgPSBwdXRfdXNlcihjdXJyZW50LT5lZ2lkLCBlZ2lkKSkpCgkJcmV0dmFsID0gcHV0X3VzZXIoY3VycmVudC0+c2dpZCwgc2dpZCk7CgoJcmV0dXJuIHJldHZhbDsKfQoKCi8qCiAqICJzZXRmc3VpZCgpIiBzZXRzIHRoZSBmc3VpZCAtIHRoZSB1aWQgdXNlZCBmb3IgZmlsZXN5c3RlbSBjaGVja3MuIFRoaXMKICogaXMgdXNlZCBmb3IgImFjY2VzcygpIiBhbmQgZm9yIHRoZSBORlMgZGFlbW9uIChsZXR0aW5nIG5mc2Qgc3RheSBhdAogKiB3aGF0ZXZlciB1aWQgaXQgd2FudHMgdG8pLiBJdCBub3JtYWxseSBzaGFkb3dzICJldWlkIiwgZXhjZXB0IHdoZW4KICogZXhwbGljaXRseSBzZXQgYnkgc2V0ZnN1aWQoKSBvciBmb3IgYWNjZXNzLi4KICovCmFzbWxpbmthZ2UgbG9uZyBzeXNfc2V0ZnN1aWQodWlkX3QgdWlkKQp7CglpbnQgb2xkX2ZzdWlkOwoKCW9sZF9mc3VpZCA9IGN1cnJlbnQtPmZzdWlkOwoJaWYgKHNlY3VyaXR5X3Rhc2tfc2V0dWlkKHVpZCwgKHVpZF90KS0xLCAodWlkX3QpLTEsIExTTV9TRVRJRF9GUykpCgkJcmV0dXJuIG9sZF9mc3VpZDsKCglpZiAodWlkID09IGN1cnJlbnQtPnVpZCB8fCB1aWQgPT0gY3VycmVudC0+ZXVpZCB8fAoJICAgIHVpZCA9PSBjdXJyZW50LT5zdWlkIHx8IHVpZCA9PSBjdXJyZW50LT5mc3VpZCB8fCAKCSAgICBjYXBhYmxlKENBUF9TRVRVSUQpKQoJewoJCWlmICh1aWQgIT0gb2xkX2ZzdWlkKQoJCXsKCQkJY3VycmVudC0+bW0tPmR1bXBhYmxlID0gc3VpZF9kdW1wYWJsZTsKCQkJc21wX3dtYigpOwoJCX0KCQljdXJyZW50LT5mc3VpZCA9IHVpZDsKCX0KCglrZXlfZnN1aWRfY2hhbmdlZChjdXJyZW50KTsKCglzZWN1cml0eV90YXNrX3Bvc3Rfc2V0dWlkKG9sZF9mc3VpZCwgKHVpZF90KS0xLCAodWlkX3QpLTEsIExTTV9TRVRJRF9GUyk7CgoJcmV0dXJuIG9sZF9mc3VpZDsKfQoKLyoKICogU2FtbWEgcOUgc3ZlbnNrYS4uCiAqLwphc21saW5rYWdlIGxvbmcgc3lzX3NldGZzZ2lkKGdpZF90IGdpZCkKewoJaW50IG9sZF9mc2dpZDsKCglvbGRfZnNnaWQgPSBjdXJyZW50LT5mc2dpZDsKCWlmIChzZWN1cml0eV90YXNrX3NldGdpZChnaWQsIChnaWRfdCktMSwgKGdpZF90KS0xLCBMU01fU0VUSURfRlMpKQoJCXJldHVybiBvbGRfZnNnaWQ7CgoJaWYgKGdpZCA9PSBjdXJyZW50LT5naWQgfHwgZ2lkID09IGN1cnJlbnQtPmVnaWQgfHwKCSAgICBnaWQgPT0gY3VycmVudC0+c2dpZCB8fCBnaWQgPT0gY3VycmVudC0+ZnNnaWQgfHwgCgkgICAgY2FwYWJsZShDQVBfU0VUR0lEKSkKCXsKCQlpZiAoZ2lkICE9IG9sZF9mc2dpZCkKCQl7CgkJCWN1cnJlbnQtPm1tLT5kdW1wYWJsZSA9IHN1aWRfZHVtcGFibGU7CgkJCXNtcF93bWIoKTsKCQl9CgkJY3VycmVudC0+ZnNnaWQgPSBnaWQ7CgkJa2V5X2ZzZ2lkX2NoYW5nZWQoY3VycmVudCk7Cgl9CglyZXR1cm4gb2xkX2ZzZ2lkOwp9Cgphc21saW5rYWdlIGxvbmcgc3lzX3RpbWVzKHN0cnVjdCB0bXMgX191c2VyICogdGJ1ZikKewoJLyoKCSAqCUluIHRoZSBTTVAgd29ybGQgd2UgbWlnaHQganVzdCBiZSB1bmx1Y2t5IGFuZCBoYXZlIG9uZSBvZgoJICoJdGhlIHRpbWVzIGluY3JlbWVudCBhcyB3ZSB1c2UgaXQuIFNpbmNlIHRoZSB2YWx1ZSBpcyBhbgoJICoJYXRvbWljYWxseSBzYWZlIHR5cGUgdGhpcyBpcyBqdXN0IGZpbmUuIENvbmNlcHR1YWxseSBpdHMKCSAqCWFzIGlmIHRoZSBzeXNjYWxsIHRvb2sgYW4gaW5zdGFudCBsb25nZXIgdG8gb2NjdXIuCgkgKi8KCWlmICh0YnVmKSB7CgkJc3RydWN0IHRtcyB0bXA7CgkJY3B1dGltZV90IHV0aW1lLCBzdGltZSwgY3V0aW1lLCBjc3RpbWU7CgojaWZkZWYgQ09ORklHX1NNUAoJCWlmICh0aHJlYWRfZ3JvdXBfZW1wdHkoY3VycmVudCkpIHsKCQkJLyoKCQkJICogU2luZ2xlIHRocmVhZCBjYXNlIHdpdGhvdXQgdGhlIHVzZSBvZiBhbnkgbG9ja3MuCgkJCSAqCgkJCSAqIFdlIG1heSByYWNlIHdpdGggcmVsZWFzZV90YXNrIGlmIHR3byB0aHJlYWRzIGFyZQoJCQkgKiBleGVjdXRpbmcuIEhvd2V2ZXIsIHJlbGVhc2UgdGFzayBmaXJzdCBhZGRzIHVwIHRoZQoJCQkgKiBjb3VudGVycyAoX19leGl0X3NpZ25hbCkgYmVmb3JlICByZW1vdmluZyB0aGUgdGFzawoJCQkgKiBmcm9tIHRoZSBwcm9jZXNzIHRhc2tsaXN0IChfX3VuaGFzaF9wcm9jZXNzKS4KCQkJICogX19leGl0X3NpZ25hbCBhbHNvIGFjcXVpcmVzIGFuZCByZWxlYXNlcyB0aGUKCQkJICogc2lnbG9jayB3aGljaCByZXN1bHRzIGluIHRoZSBwcm9wZXIgbWVtb3J5IG9yZGVyaW5nCgkJCSAqIHNvIHRoYXQgdGhlIGxpc3QgbW9kaWZpY2F0aW9ucyBhcmUgYWx3YXlzIHZpc2libGUKCQkJICogYWZ0ZXIgdGhlIGNvdW50ZXJzIGhhdmUgYmVlbiB1cGRhdGVkLgoJCQkgKgoJCQkgKiBJZiB0aGUgY291bnRlcnMgaGF2ZSBiZWVuIHVwZGF0ZWQgYnkgdGhlIHNlY29uZCB0aHJlYWQKCQkJICogYnV0IHRoZSB0aHJlYWQgaGFzIG5vdCB5ZXQgYmVlbiByZW1vdmVkIGZyb20gdGhlIGxpc3QKCQkJICogdGhlbiB0aGUgb3RoZXIgYnJhbmNoIHdpbGwgYmUgZXhlY3V0aW5nIHdoaWNoIHdpbGwKCQkJICogYmxvY2sgb24gdGFza2xpc3RfbG9jayB1bnRpbCB0aGUgZXhpdCBoYW5kbGluZyBvZiB0aGUKCQkJICogb3RoZXIgdGFzayBpcyBmaW5pc2hlZC4KCQkJICoKCQkJICogVGhpcyBhbHNvIGltcGxpZXMgdGhhdCB0aGUgc2lnaGFuZC0+c2lnbG9jayBjYW5ub3QKCQkJICogYmUgaGVsZCBieSBhbm90aGVyIHByb2Nlc3Nvci4gU28gd2UgY2FuIGFsc28KCQkJICogc2tpcCBhY3F1aXJpbmcgdGhhdCBsb2NrLgoJCQkgKi8KCQkJdXRpbWUgPSBjcHV0aW1lX2FkZChjdXJyZW50LT5zaWduYWwtPnV0aW1lLCBjdXJyZW50LT51dGltZSk7CgkJCXN0aW1lID0gY3B1dGltZV9hZGQoY3VycmVudC0+c2lnbmFsLT51dGltZSwgY3VycmVudC0+c3RpbWUpOwoJCQljdXRpbWUgPSBjdXJyZW50LT5zaWduYWwtPmN1dGltZTsKCQkJY3N0aW1lID0gY3VycmVudC0+c2lnbmFsLT5jc3RpbWU7CgkJfSBlbHNlCiNlbmRpZgoJCXsKCgkJCS8qIFByb2Nlc3Mgd2l0aCBtdWx0aXBsZSB0aHJlYWRzICovCgkJCXN0cnVjdCB0YXNrX3N0cnVjdCAqdHNrID0gY3VycmVudDsKCQkJc3RydWN0IHRhc2tfc3RydWN0ICp0OwoKCQkJcmVhZF9sb2NrKCZ0YXNrbGlzdF9sb2NrKTsKCQkJdXRpbWUgPSB0c2stPnNpZ25hbC0+dXRpbWU7CgkJCXN0aW1lID0gdHNrLT5zaWduYWwtPnN0aW1lOwoJCQl0ID0gdHNrOwoJCQlkbyB7CgkJCQl1dGltZSA9IGNwdXRpbWVfYWRkKHV0aW1lLCB0LT51dGltZSk7CgkJCQlzdGltZSA9IGNwdXRpbWVfYWRkKHN0aW1lLCB0LT5zdGltZSk7CgkJCQl0ID0gbmV4dF90aHJlYWQodCk7CgkJCX0gd2hpbGUgKHQgIT0gdHNrKTsKCgkJCS8qCgkJCSAqIFdoaWxlIHdlIGhhdmUgdGFza2xpc3RfbG9jayByZWFkLWxvY2tlZCwgbm8gZHlpbmcgdGhyZWFkCgkJCSAqIGNhbiBiZSB1cGRhdGluZyBjdXJyZW50LT5zaWduYWwtPlt1c110aW1lLiAgSW5zdGVhZCwKCQkJICogd2UgZ290IHRoZWlyIGNvdW50cyBpbmNsdWRlZCBpbiB0aGUgbGl2ZSB0aHJlYWQgbG9vcC4KCQkJICogSG93ZXZlciwgYW5vdGhlciB0aHJlYWQgY2FuIGNvbWUgaW4gcmlnaHQgbm93IGFuZAoJCQkgKiBkbyBhIHdhaXQgY2FsbCB0aGF0IHVwZGF0ZXMgY3VycmVudC0+c2lnbmFsLT5jW3VzXXRpbWUuCgkJCSAqIFRvIG1ha2Ugc3VyZSB3ZSBhbHdheXMgc2VlIHRoYXQgcGFpciB1cGRhdGVkIGF0b21pY2FsbHksCgkJCSAqIHdlIHRha2UgdGhlIHNpZ2xvY2sgYXJvdW5kIGZldGNoaW5nIHRoZW0uCgkJCSAqLwoJCQlzcGluX2xvY2tfaXJxKCZ0c2stPnNpZ2hhbmQtPnNpZ2xvY2spOwoJCQljdXRpbWUgPSB0c2stPnNpZ25hbC0+Y3V0aW1lOwoJCQljc3RpbWUgPSB0c2stPnNpZ25hbC0+Y3N0aW1lOwoJCQlzcGluX3VubG9ja19pcnEoJnRzay0+c2lnaGFuZC0+c2lnbG9jayk7CgkJCXJlYWRfdW5sb2NrKCZ0YXNrbGlzdF9sb2NrKTsKCQl9CgkJdG1wLnRtc191dGltZSA9IGNwdXRpbWVfdG9fY2xvY2tfdCh1dGltZSk7CgkJdG1wLnRtc19zdGltZSA9IGNwdXRpbWVfdG9fY2xvY2tfdChzdGltZSk7CgkJdG1wLnRtc19jdXRpbWUgPSBjcHV0aW1lX3RvX2Nsb2NrX3QoY3V0aW1lKTsKCQl0bXAudG1zX2NzdGltZSA9IGNwdXRpbWVfdG9fY2xvY2tfdChjc3RpbWUpOwoJCWlmIChjb3B5X3RvX3VzZXIodGJ1ZiwgJnRtcCwgc2l6ZW9mKHN0cnVjdCB0bXMpKSkKCQkJcmV0dXJuIC1FRkFVTFQ7Cgl9CglyZXR1cm4gKGxvbmcpIGppZmZpZXNfNjRfdG9fY2xvY2tfdChnZXRfamlmZmllc182NCgpKTsKfQoKLyoKICogVGhpcyBuZWVkcyBzb21lIGhlYXZ5IGNoZWNraW5nIC4uLgogKiBJIGp1c3QgaGF2ZW4ndCB0aGUgc3RvbWFjaCBmb3IgaXQuIEkgYWxzbyBkb24ndCBmdWxseQogKiB1bmRlcnN0YW5kIHNlc3Npb25zL3BncnAgZXRjLiBMZXQgc29tZWJvZHkgd2hvIGRvZXMgZXhwbGFpbiBpdC4KICoKICogT0ssIEkgdGhpbmsgSSBoYXZlIHRoZSBwcm90ZWN0aW9uIHNlbWFudGljcyByaWdodC4uLi4gdGhpcyBpcyByZWFsbHkKICogb25seSBpbXBvcnRhbnQgb24gYSBtdWx0aS11c2VyIHN5c3RlbSBhbnl3YXksIHRvIG1ha2Ugc3VyZSBvbmUgdXNlcgogKiBjYW4ndCBzZW5kIGEgc2lnbmFsIHRvIGEgcHJvY2VzcyBvd25lZCBieSBhbm90aGVyLiAgLVRZVCwgMTIvMTIvOTEKICoKICogQXVjaC4gSGFkIHRvIGFkZCB0aGUgJ2RpZF9leGVjJyBmbGFnIHRvIGNvbmZvcm0gY29tcGxldGVseSB0byBQT1NJWC4KICogTEJUIDA0LjAzLjk0CiAqLwoKYXNtbGlua2FnZSBsb25nIHN5c19zZXRwZ2lkKHBpZF90IHBpZCwgcGlkX3QgcGdpZCkKewoJc3RydWN0IHRhc2tfc3RydWN0ICpwOwoJaW50IGVyciA9IC1FSU5WQUw7CgoJaWYgKCFwaWQpCgkJcGlkID0gY3VycmVudC0+cGlkOwoJaWYgKCFwZ2lkKQoJCXBnaWQgPSBwaWQ7CglpZiAocGdpZCA8IDApCgkJcmV0dXJuIC1FSU5WQUw7CgoJLyogRnJvbSB0aGlzIHBvaW50IGZvcndhcmQgd2Uga2VlcCBob2xkaW5nIG9udG8gdGhlIHRhc2tsaXN0IGxvY2sKCSAqIHNvIHRoYXQgb3VyIHBhcmVudCBkb2VzIG5vdCBjaGFuZ2UgZnJvbSB1bmRlciB1cy4gLURhdmVNCgkgKi8KCXdyaXRlX2xvY2tfaXJxKCZ0YXNrbGlzdF9sb2NrKTsKCgllcnIgPSAtRVNSQ0g7CglwID0gZmluZF90YXNrX2J5X3BpZChwaWQpOwoJaWYgKCFwKQoJCWdvdG8gb3V0OwoKCWVyciA9IC1FSU5WQUw7CglpZiAoIXRocmVhZF9ncm91cF9sZWFkZXIocCkpCgkJZ290byBvdXQ7CgoJaWYgKHAtPnBhcmVudCA9PSBjdXJyZW50IHx8IHAtPnJlYWxfcGFyZW50ID09IGN1cnJlbnQpIHsKCQllcnIgPSAtRVBFUk07CgkJaWYgKHAtPnNpZ25hbC0+c2Vzc2lvbiAhPSBjdXJyZW50LT5zaWduYWwtPnNlc3Npb24pCgkJCWdvdG8gb3V0OwoJCWVyciA9IC1FQUNDRVM7CgkJaWYgKHAtPmRpZF9leGVjKQoJCQlnb3RvIG91dDsKCX0gZWxzZSB7CgkJZXJyID0gLUVTUkNIOwoJCWlmIChwICE9IGN1cnJlbnQpCgkJCWdvdG8gb3V0OwoJfQoKCWVyciA9IC1FUEVSTTsKCWlmIChwLT5zaWduYWwtPmxlYWRlcikKCQlnb3RvIG91dDsKCglpZiAocGdpZCAhPSBwaWQpIHsKCQlzdHJ1Y3QgdGFza19zdHJ1Y3QgKnA7CgoJCWRvX2VhY2hfdGFza19waWQocGdpZCwgUElEVFlQRV9QR0lELCBwKSB7CgkJCWlmIChwLT5zaWduYWwtPnNlc3Npb24gPT0gY3VycmVudC0+c2lnbmFsLT5zZXNzaW9uKQoJCQkJZ290byBva19wZ2lkOwoJCX0gd2hpbGVfZWFjaF90YXNrX3BpZChwZ2lkLCBQSURUWVBFX1BHSUQsIHApOwoJCWdvdG8gb3V0OwoJfQoKb2tfcGdpZDoKCWVyciA9IHNlY3VyaXR5X3Rhc2tfc2V0cGdpZChwLCBwZ2lkKTsKCWlmIChlcnIpCgkJZ290byBvdXQ7CgoJaWYgKHByb2Nlc3NfZ3JvdXAocCkgIT0gcGdpZCkgewoJCWRldGFjaF9waWQocCwgUElEVFlQRV9QR0lEKTsKCQlwLT5zaWduYWwtPnBncnAgPSBwZ2lkOwoJCWF0dGFjaF9waWQocCwgUElEVFlQRV9QR0lELCBwZ2lkKTsKCX0KCgllcnIgPSAwOwpvdXQ6CgkvKiBBbGwgcGF0aHMgbGVhZCB0byBoZXJlLCB0aHVzIHdlIGFyZSBzYWZlLiAtRGF2ZU0gKi8KCXdyaXRlX3VubG9ja19pcnEoJnRhc2tsaXN0X2xvY2spOwoJcmV0dXJuIGVycjsKfQoKYXNtbGlua2FnZSBsb25nIHN5c19nZXRwZ2lkKHBpZF90IHBpZCkKewoJaWYgKCFwaWQpIHsKCQlyZXR1cm4gcHJvY2Vzc19ncm91cChjdXJyZW50KTsKCX0gZWxzZSB7CgkJaW50IHJldHZhbDsKCQlzdHJ1Y3QgdGFza19zdHJ1Y3QgKnA7CgoJCXJlYWRfbG9jaygmdGFza2xpc3RfbG9jayk7CgkJcCA9IGZpbmRfdGFza19ieV9waWQocGlkKTsKCgkJcmV0dmFsID0gLUVTUkNIOwoJCWlmIChwKSB7CgkJCXJldHZhbCA9IHNlY3VyaXR5X3Rhc2tfZ2V0cGdpZChwKTsKCQkJaWYgKCFyZXR2YWwpCgkJCQlyZXR2YWwgPSBwcm9jZXNzX2dyb3VwKHApOwoJCX0KCQlyZWFkX3VubG9jaygmdGFza2xpc3RfbG9jayk7CgkJcmV0dXJuIHJldHZhbDsKCX0KfQoKI2lmZGVmIF9fQVJDSF9XQU5UX1NZU19HRVRQR1JQCgphc21saW5rYWdlIGxvbmcgc3lzX2dldHBncnAodm9pZCkKewoJLyogU01QIC0gYXNzdW1pbmcgd3JpdGVzIGFyZSB3b3JkIGF0b21pYyB0aGlzIGlzIGZpbmUgKi8KCXJldHVybiBwcm9jZXNzX2dyb3VwKGN1cnJlbnQpOwp9CgojZW5kaWYKCmFzbWxpbmthZ2UgbG9uZyBzeXNfZ2V0c2lkKHBpZF90IHBpZCkKewoJaWYgKCFwaWQpIHsKCQlyZXR1cm4gY3VycmVudC0+c2lnbmFsLT5zZXNzaW9uOwoJfSBlbHNlIHsKCQlpbnQgcmV0dmFsOwoJCXN0cnVjdCB0YXNrX3N0cnVjdCAqcDsKCgkJcmVhZF9sb2NrKCZ0YXNrbGlzdF9sb2NrKTsKCQlwID0gZmluZF90YXNrX2J5X3BpZChwaWQpOwoKCQlyZXR2YWwgPSAtRVNSQ0g7CgkJaWYocCkgewoJCQlyZXR2YWwgPSBzZWN1cml0eV90YXNrX2dldHNpZChwKTsKCQkJaWYgKCFyZXR2YWwpCgkJCQlyZXR2YWwgPSBwLT5zaWduYWwtPnNlc3Npb247CgkJfQoJCXJlYWRfdW5sb2NrKCZ0YXNrbGlzdF9sb2NrKTsKCQlyZXR1cm4gcmV0dmFsOwoJfQp9Cgphc21saW5rYWdlIGxvbmcgc3lzX3NldHNpZCh2b2lkKQp7CglzdHJ1Y3QgcGlkICpwaWQ7CglpbnQgZXJyID0gLUVQRVJNOwoKCWlmICghdGhyZWFkX2dyb3VwX2xlYWRlcihjdXJyZW50KSkKCQlyZXR1cm4gLUVJTlZBTDsKCglkb3duKCZ0dHlfc2VtKTsKCXdyaXRlX2xvY2tfaXJxKCZ0YXNrbGlzdF9sb2NrKTsKCglwaWQgPSBmaW5kX3BpZChQSURUWVBFX1BHSUQsIGN1cnJlbnQtPnBpZCk7CglpZiAocGlkKQoJCWdvdG8gb3V0OwoKCWN1cnJlbnQtPnNpZ25hbC0+bGVhZGVyID0gMTsKCV9fc2V0X3NwZWNpYWxfcGlkcyhjdXJyZW50LT5waWQsIGN1cnJlbnQtPnBpZCk7CgljdXJyZW50LT5zaWduYWwtPnR0eSA9IE5VTEw7CgljdXJyZW50LT5zaWduYWwtPnR0eV9vbGRfcGdycCA9IDA7CgllcnIgPSBwcm9jZXNzX2dyb3VwKGN1cnJlbnQpOwpvdXQ6Cgl3cml0ZV91bmxvY2tfaXJxKCZ0YXNrbGlzdF9sb2NrKTsKCXVwKCZ0dHlfc2VtKTsKCXJldHVybiBlcnI7Cn0KCi8qCiAqIFN1cHBsZW1lbnRhcnkgZ3JvdXAgSURzCiAqLwoKLyogaW5pdCB0byAyIC0gb25lIGZvciBpbml0X3Rhc2ssIG9uZSB0byBlbnN1cmUgaXQgaXMgbmV2ZXIgZnJlZWQgKi8Kc3RydWN0IGdyb3VwX2luZm8gaW5pdF9ncm91cHMgPSB7IC51c2FnZSA9IEFUT01JQ19JTklUKDIpIH07CgpzdHJ1Y3QgZ3JvdXBfaW5mbyAqZ3JvdXBzX2FsbG9jKGludCBnaWRzZXRzaXplKQp7CglzdHJ1Y3QgZ3JvdXBfaW5mbyAqZ3JvdXBfaW5mbzsKCWludCBuYmxvY2tzOwoJaW50IGk7CgoJbmJsb2NrcyA9IChnaWRzZXRzaXplICsgTkdST1VQU19QRVJfQkxPQ0sgLSAxKSAvIE5HUk9VUFNfUEVSX0JMT0NLOwoJLyogTWFrZSBzdXJlIHdlIGFsd2F5cyBhbGxvY2F0ZSBhdCBsZWFzdCBvbmUgaW5kaXJlY3QgYmxvY2sgcG9pbnRlciAqLwoJbmJsb2NrcyA9IG5ibG9ja3MgPyA6IDE7Cglncm91cF9pbmZvID0ga21hbGxvYyhzaXplb2YoKmdyb3VwX2luZm8pICsgbmJsb2NrcypzaXplb2YoZ2lkX3QgKiksIEdGUF9VU0VSKTsKCWlmICghZ3JvdXBfaW5mbykKCQlyZXR1cm4gTlVMTDsKCWdyb3VwX2luZm8tPm5ncm91cHMgPSBnaWRzZXRzaXplOwoJZ3JvdXBfaW5mby0+bmJsb2NrcyA9IG5ibG9ja3M7CglhdG9taWNfc2V0KCZncm91cF9pbmZvLT51c2FnZSwgMSk7CgoJaWYgKGdpZHNldHNpemUgPD0gTkdST1VQU19TTUFMTCkgewoJCWdyb3VwX2luZm8tPmJsb2Nrc1swXSA9IGdyb3VwX2luZm8tPnNtYWxsX2Jsb2NrOwoJfSBlbHNlIHsKCQlmb3IgKGkgPSAwOyBpIDwgbmJsb2NrczsgaSsrKSB7CgkJCWdpZF90ICpiOwoJCQliID0gKHZvaWQgKilfX2dldF9mcmVlX3BhZ2UoR0ZQX1VTRVIpOwoJCQlpZiAoIWIpCgkJCQlnb3RvIG91dF91bmRvX3BhcnRpYWxfYWxsb2M7CgkJCWdyb3VwX2luZm8tPmJsb2Nrc1tpXSA9IGI7CgkJfQoJfQoJcmV0dXJuIGdyb3VwX2luZm87CgpvdXRfdW5kb19wYXJ0aWFsX2FsbG9jOgoJd2hpbGUgKC0taSA+PSAwKSB7CgkJZnJlZV9wYWdlKCh1bnNpZ25lZCBsb25nKWdyb3VwX2luZm8tPmJsb2Nrc1tpXSk7Cgl9CglrZnJlZShncm91cF9pbmZvKTsKCXJldHVybiBOVUxMOwp9CgpFWFBPUlRfU1lNQk9MKGdyb3Vwc19hbGxvYyk7Cgp2b2lkIGdyb3Vwc19mcmVlKHN0cnVjdCBncm91cF9pbmZvICpncm91cF9pbmZvKQp7CglpZiAoZ3JvdXBfaW5mby0+YmxvY2tzWzBdICE9IGdyb3VwX2luZm8tPnNtYWxsX2Jsb2NrKSB7CgkJaW50IGk7CgkJZm9yIChpID0gMDsgaSA8IGdyb3VwX2luZm8tPm5ibG9ja3M7IGkrKykKCQkJZnJlZV9wYWdlKCh1bnNpZ25lZCBsb25nKWdyb3VwX2luZm8tPmJsb2Nrc1tpXSk7Cgl9CglrZnJlZShncm91cF9pbmZvKTsKfQoKRVhQT1JUX1NZTUJPTChncm91cHNfZnJlZSk7CgovKiBleHBvcnQgdGhlIGdyb3VwX2luZm8gdG8gYSB1c2VyLXNwYWNlIGFycmF5ICovCnN0YXRpYyBpbnQgZ3JvdXBzX3RvX3VzZXIoZ2lkX3QgX191c2VyICpncm91cGxpc3QsCiAgICBzdHJ1Y3QgZ3JvdXBfaW5mbyAqZ3JvdXBfaW5mbykKewoJaW50IGk7CglpbnQgY291bnQgPSBncm91cF9pbmZvLT5uZ3JvdXBzOwoKCWZvciAoaSA9IDA7IGkgPCBncm91cF9pbmZvLT5uYmxvY2tzOyBpKyspIHsKCQlpbnQgY3BfY291bnQgPSBtaW4oTkdST1VQU19QRVJfQkxPQ0ssIGNvdW50KTsKCQlpbnQgb2ZmID0gaSAqIE5HUk9VUFNfUEVSX0JMT0NLOwoJCWludCBsZW4gPSBjcF9jb3VudCAqIHNpemVvZigqZ3JvdXBsaXN0KTsKCgkJaWYgKGNvcHlfdG9fdXNlcihncm91cGxpc3Qrb2ZmLCBncm91cF9pbmZvLT5ibG9ja3NbaV0sIGxlbikpCgkJCXJldHVybiAtRUZBVUxUOwoKCQljb3VudCAtPSBjcF9jb3VudDsKCX0KCXJldHVybiAwOwp9CgovKiBmaWxsIGEgZ3JvdXBfaW5mbyBmcm9tIGEgdXNlci1zcGFjZSBhcnJheSAtIGl0IG11c3QgYmUgYWxsb2NhdGVkIGFscmVhZHkgKi8Kc3RhdGljIGludCBncm91cHNfZnJvbV91c2VyKHN0cnVjdCBncm91cF9pbmZvICpncm91cF9pbmZvLAogICAgZ2lkX3QgX191c2VyICpncm91cGxpc3QpCiB7CglpbnQgaTsKCWludCBjb3VudCA9IGdyb3VwX2luZm8tPm5ncm91cHM7CgoJZm9yIChpID0gMDsgaSA8IGdyb3VwX2luZm8tPm5ibG9ja3M7IGkrKykgewoJCWludCBjcF9jb3VudCA9IG1pbihOR1JPVVBTX1BFUl9CTE9DSywgY291bnQpOwoJCWludCBvZmYgPSBpICogTkdST1VQU19QRVJfQkxPQ0s7CgkJaW50IGxlbiA9IGNwX2NvdW50ICogc2l6ZW9mKCpncm91cGxpc3QpOwoKCQlpZiAoY29weV9mcm9tX3VzZXIoZ3JvdXBfaW5mby0+YmxvY2tzW2ldLCBncm91cGxpc3Qrb2ZmLCBsZW4pKQoJCQlyZXR1cm4gLUVGQVVMVDsKCgkJY291bnQgLT0gY3BfY291bnQ7Cgl9CglyZXR1cm4gMDsKfQoKLyogYSBzaW1wbGUgU2hlbGwgc29ydCAqLwpzdGF0aWMgdm9pZCBncm91cHNfc29ydChzdHJ1Y3QgZ3JvdXBfaW5mbyAqZ3JvdXBfaW5mbykKewoJaW50IGJhc2UsIG1heCwgc3RyaWRlOwoJaW50IGdpZHNldHNpemUgPSBncm91cF9pbmZvLT5uZ3JvdXBzOwoKCWZvciAoc3RyaWRlID0gMTsgc3RyaWRlIDwgZ2lkc2V0c2l6ZTsgc3RyaWRlID0gMyAqIHN0cmlkZSArIDEpCgkJOyAvKiBub3RoaW5nICovCglzdHJpZGUgLz0gMzsKCgl3aGlsZSAoc3RyaWRlKSB7CgkJbWF4ID0gZ2lkc2V0c2l6ZSAtIHN0cmlkZTsKCQlmb3IgKGJhc2UgPSAwOyBiYXNlIDwgbWF4OyBiYXNlKyspIHsKCQkJaW50IGxlZnQgPSBiYXNlOwoJCQlpbnQgcmlnaHQgPSBsZWZ0ICsgc3RyaWRlOwoJCQlnaWRfdCB0bXAgPSBHUk9VUF9BVChncm91cF9pbmZvLCByaWdodCk7CgoJCQl3aGlsZSAobGVmdCA+PSAwICYmIEdST1VQX0FUKGdyb3VwX2luZm8sIGxlZnQpID4gdG1wKSB7CgkJCQlHUk9VUF9BVChncm91cF9pbmZvLCByaWdodCkgPQoJCQkJICAgIEdST1VQX0FUKGdyb3VwX2luZm8sIGxlZnQpOwoJCQkJcmlnaHQgPSBsZWZ0OwoJCQkJbGVmdCAtPSBzdHJpZGU7CgkJCX0KCQkJR1JPVVBfQVQoZ3JvdXBfaW5mbywgcmlnaHQpID0gdG1wOwoJCX0KCQlzdHJpZGUgLz0gMzsKCX0KfQoKLyogYSBzaW1wbGUgYnNlYXJjaCAqLwppbnQgZ3JvdXBzX3NlYXJjaChzdHJ1Y3QgZ3JvdXBfaW5mbyAqZ3JvdXBfaW5mbywgZ2lkX3QgZ3JwKQp7CglpbnQgbGVmdCwgcmlnaHQ7CgoJaWYgKCFncm91cF9pbmZvKQoJCXJldHVybiAwOwoKCWxlZnQgPSAwOwoJcmlnaHQgPSBncm91cF9pbmZvLT5uZ3JvdXBzOwoJd2hpbGUgKGxlZnQgPCByaWdodCkgewoJCWludCBtaWQgPSAobGVmdCtyaWdodCkvMjsKCQlpbnQgY21wID0gZ3JwIC0gR1JPVVBfQVQoZ3JvdXBfaW5mbywgbWlkKTsKCQlpZiAoY21wID4gMCkKCQkJbGVmdCA9IG1pZCArIDE7CgkJZWxzZSBpZiAoY21wIDwgMCkKCQkJcmlnaHQgPSBtaWQ7CgkJZWxzZQoJCQlyZXR1cm4gMTsKCX0KCXJldHVybiAwOwp9CgovKiB2YWxpZGF0ZSBhbmQgc2V0IGN1cnJlbnQtPmdyb3VwX2luZm8gKi8KaW50IHNldF9jdXJyZW50X2dyb3VwcyhzdHJ1Y3QgZ3JvdXBfaW5mbyAqZ3JvdXBfaW5mbykKewoJaW50IHJldHZhbDsKCXN0cnVjdCBncm91cF9pbmZvICpvbGRfaW5mbzsKCglyZXR2YWwgPSBzZWN1cml0eV90YXNrX3NldGdyb3Vwcyhncm91cF9pbmZvKTsKCWlmIChyZXR2YWwpCgkJcmV0dXJuIHJldHZhbDsKCglncm91cHNfc29ydChncm91cF9pbmZvKTsKCWdldF9ncm91cF9pbmZvKGdyb3VwX2luZm8pOwoKCXRhc2tfbG9jayhjdXJyZW50KTsKCW9sZF9pbmZvID0gY3VycmVudC0+Z3JvdXBfaW5mbzsKCWN1cnJlbnQtPmdyb3VwX2luZm8gPSBncm91cF9pbmZvOwoJdGFza191bmxvY2soY3VycmVudCk7CgoJcHV0X2dyb3VwX2luZm8ob2xkX2luZm8pOwoKCXJldHVybiAwOwp9CgpFWFBPUlRfU1lNQk9MKHNldF9jdXJyZW50X2dyb3Vwcyk7Cgphc21saW5rYWdlIGxvbmcgc3lzX2dldGdyb3VwcyhpbnQgZ2lkc2V0c2l6ZSwgZ2lkX3QgX191c2VyICpncm91cGxpc3QpCnsKCWludCBpID0gMDsKCgkvKgoJICoJU01QOiBOb2JvZHkgZWxzZSBjYW4gY2hhbmdlIG91ciBncm91cGxpc3QuIFRodXMgd2UgYXJlCgkgKglzYWZlLgoJICovCgoJaWYgKGdpZHNldHNpemUgPCAwKQoJCXJldHVybiAtRUlOVkFMOwoKCS8qIG5vIG5lZWQgdG8gZ3JhYiB0YXNrX2xvY2sgaGVyZTsgaXQgY2Fubm90IGNoYW5nZSAqLwoJZ2V0X2dyb3VwX2luZm8oY3VycmVudC0+Z3JvdXBfaW5mbyk7CglpID0gY3VycmVudC0+Z3JvdXBfaW5mby0+bmdyb3VwczsKCWlmIChnaWRzZXRzaXplKSB7CgkJaWYgKGkgPiBnaWRzZXRzaXplKSB7CgkJCWkgPSAtRUlOVkFMOwoJCQlnb3RvIG91dDsKCQl9CgkJaWYgKGdyb3Vwc190b191c2VyKGdyb3VwbGlzdCwgY3VycmVudC0+Z3JvdXBfaW5mbykpIHsKCQkJaSA9IC1FRkFVTFQ7CgkJCWdvdG8gb3V0OwoJCX0KCX0Kb3V0OgoJcHV0X2dyb3VwX2luZm8oY3VycmVudC0+Z3JvdXBfaW5mbyk7CglyZXR1cm4gaTsKfQoKLyoKICoJU01QOiBPdXIgZ3JvdXBzIGFyZSBjb3B5LW9uLXdyaXRlLiBXZSBjYW4gc2V0IHRoZW0gc2FmZWx5CiAqCXdpdGhvdXQgYW5vdGhlciB0YXNrIGludGVyZmVyaW5nLgogKi8KIAphc21saW5rYWdlIGxvbmcgc3lzX3NldGdyb3VwcyhpbnQgZ2lkc2V0c2l6ZSwgZ2lkX3QgX191c2VyICpncm91cGxpc3QpCnsKCXN0cnVjdCBncm91cF9pbmZvICpncm91cF9pbmZvOwoJaW50IHJldHZhbDsKCglpZiAoIWNhcGFibGUoQ0FQX1NFVEdJRCkpCgkJcmV0dXJuIC1FUEVSTTsKCWlmICgodW5zaWduZWQpZ2lkc2V0c2l6ZSA+IE5HUk9VUFNfTUFYKQoJCXJldHVybiAtRUlOVkFMOwoKCWdyb3VwX2luZm8gPSBncm91cHNfYWxsb2MoZ2lkc2V0c2l6ZSk7CglpZiAoIWdyb3VwX2luZm8pCgkJcmV0dXJuIC1FTk9NRU07CglyZXR2YWwgPSBncm91cHNfZnJvbV91c2VyKGdyb3VwX2luZm8sIGdyb3VwbGlzdCk7CglpZiAocmV0dmFsKSB7CgkJcHV0X2dyb3VwX2luZm8oZ3JvdXBfaW5mbyk7CgkJcmV0dXJuIHJldHZhbDsKCX0KCglyZXR2YWwgPSBzZXRfY3VycmVudF9ncm91cHMoZ3JvdXBfaW5mbyk7CglwdXRfZ3JvdXBfaW5mbyhncm91cF9pbmZvKTsKCglyZXR1cm4gcmV0dmFsOwp9CgovKgogKiBDaGVjayB3aGV0aGVyIHdlJ3JlIGZzZ2lkL2VnaWQgb3IgaW4gdGhlIHN1cHBsZW1lbnRhbCBncm91cC4uCiAqLwppbnQgaW5fZ3JvdXBfcChnaWRfdCBncnApCnsKCWludCByZXR2YWwgPSAxOwoJaWYgKGdycCAhPSBjdXJyZW50LT5mc2dpZCkgewoJCWdldF9ncm91cF9pbmZvKGN1cnJlbnQtPmdyb3VwX2luZm8pOwoJCXJldHZhbCA9IGdyb3Vwc19zZWFyY2goY3VycmVudC0+Z3JvdXBfaW5mbywgZ3JwKTsKCQlwdXRfZ3JvdXBfaW5mbyhjdXJyZW50LT5ncm91cF9pbmZvKTsKCX0KCXJldHVybiByZXR2YWw7Cn0KCkVYUE9SVF9TWU1CT0woaW5fZ3JvdXBfcCk7CgppbnQgaW5fZWdyb3VwX3AoZ2lkX3QgZ3JwKQp7CglpbnQgcmV0dmFsID0gMTsKCWlmIChncnAgIT0gY3VycmVudC0+ZWdpZCkgewoJCWdldF9ncm91cF9pbmZvKGN1cnJlbnQtPmdyb3VwX2luZm8pOwoJCXJldHZhbCA9IGdyb3Vwc19zZWFyY2goY3VycmVudC0+Z3JvdXBfaW5mbywgZ3JwKTsKCQlwdXRfZ3JvdXBfaW5mbyhjdXJyZW50LT5ncm91cF9pbmZvKTsKCX0KCXJldHVybiByZXR2YWw7Cn0KCkVYUE9SVF9TWU1CT0woaW5fZWdyb3VwX3ApOwoKREVDTEFSRV9SV1NFTSh1dHNfc2VtKTsKCkVYUE9SVF9TWU1CT0wodXRzX3NlbSk7Cgphc21saW5rYWdlIGxvbmcgc3lzX25ld3VuYW1lKHN0cnVjdCBuZXdfdXRzbmFtZSBfX3VzZXIgKiBuYW1lKQp7CglpbnQgZXJybm8gPSAwOwoKCWRvd25fcmVhZCgmdXRzX3NlbSk7CglpZiAoY29weV90b191c2VyKG5hbWUsJnN5c3RlbV91dHNuYW1lLHNpemVvZiAqbmFtZSkpCgkJZXJybm8gPSAtRUZBVUxUOwoJdXBfcmVhZCgmdXRzX3NlbSk7CglyZXR1cm4gZXJybm87Cn0KCmFzbWxpbmthZ2UgbG9uZyBzeXNfc2V0aG9zdG5hbWUoY2hhciBfX3VzZXIgKm5hbWUsIGludCBsZW4pCnsKCWludCBlcnJubzsKCWNoYXIgdG1wW19fTkVXX1VUU19MRU5dOwoKCWlmICghY2FwYWJsZShDQVBfU1lTX0FETUlOKSkKCQlyZXR1cm4gLUVQRVJNOwoJaWYgKGxlbiA8IDAgfHwgbGVuID4gX19ORVdfVVRTX0xFTikKCQlyZXR1cm4gLUVJTlZBTDsKCWRvd25fd3JpdGUoJnV0c19zZW0pOwoJZXJybm8gPSAtRUZBVUxUOwoJaWYgKCFjb3B5X2Zyb21fdXNlcih0bXAsIG5hbWUsIGxlbikpIHsKCQltZW1jcHkoc3lzdGVtX3V0c25hbWUubm9kZW5hbWUsIHRtcCwgbGVuKTsKCQlzeXN0ZW1fdXRzbmFtZS5ub2RlbmFtZVtsZW5dID0gMDsKCQllcnJubyA9IDA7Cgl9Cgl1cF93cml0ZSgmdXRzX3NlbSk7CglyZXR1cm4gZXJybm87Cn0KCiNpZmRlZiBfX0FSQ0hfV0FOVF9TWVNfR0VUSE9TVE5BTUUKCmFzbWxpbmthZ2UgbG9uZyBzeXNfZ2V0aG9zdG5hbWUoY2hhciBfX3VzZXIgKm5hbWUsIGludCBsZW4pCnsKCWludCBpLCBlcnJubzsKCglpZiAobGVuIDwgMCkKCQlyZXR1cm4gLUVJTlZBTDsKCWRvd25fcmVhZCgmdXRzX3NlbSk7CglpID0gMSArIHN0cmxlbihzeXN0ZW1fdXRzbmFtZS5ub2RlbmFtZSk7CglpZiAoaSA+IGxlbikKCQlpID0gbGVuOwoJZXJybm8gPSAwOwoJaWYgKGNvcHlfdG9fdXNlcihuYW1lLCBzeXN0ZW1fdXRzbmFtZS5ub2RlbmFtZSwgaSkpCgkJZXJybm8gPSAtRUZBVUxUOwoJdXBfcmVhZCgmdXRzX3NlbSk7CglyZXR1cm4gZXJybm87Cn0KCiNlbmRpZgoKLyoKICogT25seSBzZXRkb21haW5uYW1lOyBnZXRkb21haW5uYW1lIGNhbiBiZSBpbXBsZW1lbnRlZCBieSBjYWxsaW5nCiAqIHVuYW1lKCkKICovCmFzbWxpbmthZ2UgbG9uZyBzeXNfc2V0ZG9tYWlubmFtZShjaGFyIF9fdXNlciAqbmFtZSwgaW50IGxlbikKewoJaW50IGVycm5vOwoJY2hhciB0bXBbX19ORVdfVVRTX0xFTl07CgoJaWYgKCFjYXBhYmxlKENBUF9TWVNfQURNSU4pKQoJCXJldHVybiAtRVBFUk07CglpZiAobGVuIDwgMCB8fCBsZW4gPiBfX05FV19VVFNfTEVOKQoJCXJldHVybiAtRUlOVkFMOwoKCWRvd25fd3JpdGUoJnV0c19zZW0pOwoJZXJybm8gPSAtRUZBVUxUOwoJaWYgKCFjb3B5X2Zyb21fdXNlcih0bXAsIG5hbWUsIGxlbikpIHsKCQltZW1jcHkoc3lzdGVtX3V0c25hbWUuZG9tYWlubmFtZSwgdG1wLCBsZW4pOwoJCXN5c3RlbV91dHNuYW1lLmRvbWFpbm5hbWVbbGVuXSA9IDA7CgkJZXJybm8gPSAwOwoJfQoJdXBfd3JpdGUoJnV0c19zZW0pOwoJcmV0dXJuIGVycm5vOwp9Cgphc21saW5rYWdlIGxvbmcgc3lzX2dldHJsaW1pdCh1bnNpZ25lZCBpbnQgcmVzb3VyY2UsIHN0cnVjdCBybGltaXQgX191c2VyICpybGltKQp7CglpZiAocmVzb3VyY2UgPj0gUkxJTV9OTElNSVRTKQoJCXJldHVybiAtRUlOVkFMOwoJZWxzZSB7CgkJc3RydWN0IHJsaW1pdCB2YWx1ZTsKCQl0YXNrX2xvY2soY3VycmVudC0+Z3JvdXBfbGVhZGVyKTsKCQl2YWx1ZSA9IGN1cnJlbnQtPnNpZ25hbC0+cmxpbVtyZXNvdXJjZV07CgkJdGFza191bmxvY2soY3VycmVudC0+Z3JvdXBfbGVhZGVyKTsKCQlyZXR1cm4gY29weV90b191c2VyKHJsaW0sICZ2YWx1ZSwgc2l6ZW9mKCpybGltKSkgPyAtRUZBVUxUIDogMDsKCX0KfQoKI2lmZGVmIF9fQVJDSF9XQU5UX1NZU19PTERfR0VUUkxJTUlUCgovKgogKglCYWNrIGNvbXBhdGliaWxpdHkgZm9yIGdldHJsaW1pdC4gTmVlZGVkIGZvciBzb21lIGFwcHMuCiAqLwogCmFzbWxpbmthZ2UgbG9uZyBzeXNfb2xkX2dldHJsaW1pdCh1bnNpZ25lZCBpbnQgcmVzb3VyY2UsIHN0cnVjdCBybGltaXQgX191c2VyICpybGltKQp7CglzdHJ1Y3QgcmxpbWl0IHg7CglpZiAocmVzb3VyY2UgPj0gUkxJTV9OTElNSVRTKQoJCXJldHVybiAtRUlOVkFMOwoKCXRhc2tfbG9jayhjdXJyZW50LT5ncm91cF9sZWFkZXIpOwoJeCA9IGN1cnJlbnQtPnNpZ25hbC0+cmxpbVtyZXNvdXJjZV07Cgl0YXNrX3VubG9jayhjdXJyZW50LT5ncm91cF9sZWFkZXIpOwoJaWYoeC5ybGltX2N1ciA+IDB4N0ZGRkZGRkYpCgkJeC5ybGltX2N1ciA9IDB4N0ZGRkZGRkY7CglpZih4LnJsaW1fbWF4ID4gMHg3RkZGRkZGRikKCQl4LnJsaW1fbWF4ID0gMHg3RkZGRkZGRjsKCXJldHVybiBjb3B5X3RvX3VzZXIocmxpbSwgJngsIHNpemVvZih4KSk/LUVGQVVMVDowOwp9CgojZW5kaWYKCmFzbWxpbmthZ2UgbG9uZyBzeXNfc2V0cmxpbWl0KHVuc2lnbmVkIGludCByZXNvdXJjZSwgc3RydWN0IHJsaW1pdCBfX3VzZXIgKnJsaW0pCnsKCXN0cnVjdCBybGltaXQgbmV3X3JsaW0sICpvbGRfcmxpbTsKCWludCByZXR2YWw7CgoJaWYgKHJlc291cmNlID49IFJMSU1fTkxJTUlUUykKCQlyZXR1cm4gLUVJTlZBTDsKCWlmKGNvcHlfZnJvbV91c2VyKCZuZXdfcmxpbSwgcmxpbSwgc2l6ZW9mKCpybGltKSkpCgkJcmV0dXJuIC1FRkFVTFQ7CiAgICAgICBpZiAobmV3X3JsaW0ucmxpbV9jdXIgPiBuZXdfcmxpbS5ybGltX21heCkKICAgICAgICAgICAgICAgcmV0dXJuIC1FSU5WQUw7CglvbGRfcmxpbSA9IGN1cnJlbnQtPnNpZ25hbC0+cmxpbSArIHJlc291cmNlOwoJaWYgKChuZXdfcmxpbS5ybGltX21heCA+IG9sZF9ybGltLT5ybGltX21heCkgJiYKCSAgICAhY2FwYWJsZShDQVBfU1lTX1JFU09VUkNFKSkKCQlyZXR1cm4gLUVQRVJNOwoJaWYgKHJlc291cmNlID09IFJMSU1JVF9OT0ZJTEUgJiYgbmV3X3JsaW0ucmxpbV9tYXggPiBOUl9PUEVOKQoJCQlyZXR1cm4gLUVQRVJNOwoKCXJldHZhbCA9IHNlY3VyaXR5X3Rhc2tfc2V0cmxpbWl0KHJlc291cmNlLCAmbmV3X3JsaW0pOwoJaWYgKHJldHZhbCkKCQlyZXR1cm4gcmV0dmFsOwoKCXRhc2tfbG9jayhjdXJyZW50LT5ncm91cF9sZWFkZXIpOwoJKm9sZF9ybGltID0gbmV3X3JsaW07Cgl0YXNrX3VubG9jayhjdXJyZW50LT5ncm91cF9sZWFkZXIpOwoKCWlmIChyZXNvdXJjZSA9PSBSTElNSVRfQ1BVICYmIG5ld19ybGltLnJsaW1fY3VyICE9IFJMSU1fSU5GSU5JVFkgJiYKCSAgICAoY3B1dGltZV9lcShjdXJyZW50LT5zaWduYWwtPml0X3Byb2ZfZXhwaXJlcywgY3B1dGltZV96ZXJvKSB8fAoJICAgICBuZXdfcmxpbS5ybGltX2N1ciA8PSBjcHV0aW1lX3RvX3NlY3MoCgkJICAgICBjdXJyZW50LT5zaWduYWwtPml0X3Byb2ZfZXhwaXJlcykpKSB7CgkJY3B1dGltZV90IGNwdXRpbWUgPSBzZWNzX3RvX2NwdXRpbWUobmV3X3JsaW0ucmxpbV9jdXIpOwoJCXJlYWRfbG9jaygmdGFza2xpc3RfbG9jayk7CgkJc3Bpbl9sb2NrX2lycSgmY3VycmVudC0+c2lnaGFuZC0+c2lnbG9jayk7CgkJc2V0X3Byb2Nlc3NfY3B1X3RpbWVyKGN1cnJlbnQsIENQVUNMT0NLX1BST0YsCgkJCQkgICAgICAmY3B1dGltZSwgTlVMTCk7CgkJc3Bpbl91bmxvY2tfaXJxKCZjdXJyZW50LT5zaWdoYW5kLT5zaWdsb2NrKTsKCQlyZWFkX3VubG9jaygmdGFza2xpc3RfbG9jayk7Cgl9CgoJcmV0dXJuIDA7Cn0KCi8qCiAqIEl0IHdvdWxkIG1ha2Ugc2Vuc2UgdG8gcHV0IHN0cnVjdCBydXNhZ2UgaW4gdGhlIHRhc2tfc3RydWN0LAogKiBleGNlcHQgdGhhdCB3b3VsZCBtYWtlIHRoZSB0YXNrX3N0cnVjdCBiZSAqcmVhbGx5IGJpZyouICBBZnRlcgogKiB0YXNrX3N0cnVjdCBnZXRzIG1vdmVkIGludG8gbWFsbG9jJ2VkIG1lbW9yeSwgaXQgd291bGQKICogbWFrZSBzZW5zZSB0byBkbyB0aGlzLiAgSXQgd2lsbCBtYWtlIG1vdmluZyB0aGUgcmVzdCBvZiB0aGUgaW5mb3JtYXRpb24KICogYSBsb3Qgc2ltcGxlciEgIChXaGljaCB3ZSdyZSBub3QgZG9pbmcgcmlnaHQgbm93IGJlY2F1c2Ugd2UncmUgbm90CiAqIG1lYXN1cmluZyB0aGVtIHlldCkuCiAqCiAqIFRoaXMgZXhwZWN0cyB0byBiZSBjYWxsZWQgd2l0aCB0YXNrbGlzdF9sb2NrIHJlYWQtbG9ja2VkIG9yIGJldHRlciwKICogYW5kIHRoZSBzaWdsb2NrIG5vdCBsb2NrZWQuICBJdCBtYXkgbW9tZW50YXJpbHkgdGFrZSB0aGUgc2lnbG9jay4KICoKICogV2hlbiBzYW1wbGluZyBtdWx0aXBsZSB0aHJlYWRzIGZvciBSVVNBR0VfU0VMRiwgdW5kZXIgU01QIHdlIG1pZ2h0IGhhdmUKICogcmFjZXMgd2l0aCB0aHJlYWRzIGluY3JlbWVudGluZyB0aGVpciBvd24gY291bnRlcnMuICBCdXQgc2luY2Ugd29yZAogKiByZWFkcyBhcmUgYXRvbWljLCB3ZSBlaXRoZXIgZ2V0IG5ldyB2YWx1ZXMgb3Igb2xkIHZhbHVlcyBhbmQgd2UgZG9uJ3QKICogY2FyZSB3aGljaCBmb3IgdGhlIHN1bXMuICBXZSBhbHdheXMgdGFrZSB0aGUgc2lnbG9jayB0byBwcm90ZWN0IHJlYWRpbmcKICogdGhlIGMqIGZpZWxkcyBmcm9tIHAtPnNpZ25hbCBmcm9tIHJhY2VzIHdpdGggZXhpdC5jIHVwZGF0aW5nIHRob3NlCiAqIGZpZWxkcyB3aGVuIHJlYXBpbmcsIHNvIGEgc2FtcGxlIGVpdGhlciBnZXRzIGFsbCB0aGUgYWRkaXRpb25zIG9mIGEKICogZ2l2ZW4gY2hpbGQgYWZ0ZXIgaXQncyByZWFwZWQsIG9yIG5vbmUgc28gdGhpcyBzYW1wbGUgaXMgYmVmb3JlIHJlYXBpbmcuCiAqLwoKc3RhdGljIHZvaWQga19nZXRydXNhZ2Uoc3RydWN0IHRhc2tfc3RydWN0ICpwLCBpbnQgd2hvLCBzdHJ1Y3QgcnVzYWdlICpyKQp7CglzdHJ1Y3QgdGFza19zdHJ1Y3QgKnQ7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoJY3B1dGltZV90IHV0aW1lLCBzdGltZTsKCgltZW1zZXQoKGNoYXIgKikgciwgMCwgc2l6ZW9mICpyKTsKCglpZiAodW5saWtlbHkoIXAtPnNpZ25hbCkpCgkJcmV0dXJuOwoKCXN3aXRjaCAod2hvKSB7CgkJY2FzZSBSVVNBR0VfQ0hJTERSRU46CgkJCXNwaW5fbG9ja19pcnFzYXZlKCZwLT5zaWdoYW5kLT5zaWdsb2NrLCBmbGFncyk7CgkJCXV0aW1lID0gcC0+c2lnbmFsLT5jdXRpbWU7CgkJCXN0aW1lID0gcC0+c2lnbmFsLT5jc3RpbWU7CgkJCXItPnJ1X252Y3N3ID0gcC0+c2lnbmFsLT5jbnZjc3c7CgkJCXItPnJ1X25pdmNzdyA9IHAtPnNpZ25hbC0+Y25pdmNzdzsKCQkJci0+cnVfbWluZmx0ID0gcC0+c2lnbmFsLT5jbWluX2ZsdDsKCQkJci0+cnVfbWFqZmx0ID0gcC0+c2lnbmFsLT5jbWFqX2ZsdDsKCQkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmcC0+c2lnaGFuZC0+c2lnbG9jaywgZmxhZ3MpOwoJCQljcHV0aW1lX3RvX3RpbWV2YWwodXRpbWUsICZyLT5ydV91dGltZSk7CgkJCWNwdXRpbWVfdG9fdGltZXZhbChzdGltZSwgJnItPnJ1X3N0aW1lKTsKCQkJYnJlYWs7CgkJY2FzZSBSVVNBR0VfU0VMRjoKCQkJc3Bpbl9sb2NrX2lycXNhdmUoJnAtPnNpZ2hhbmQtPnNpZ2xvY2ssIGZsYWdzKTsKCQkJdXRpbWUgPSBzdGltZSA9IGNwdXRpbWVfemVybzsKCQkJZ290byBzdW1fZ3JvdXA7CgkJY2FzZSBSVVNBR0VfQk9USDoKCQkJc3Bpbl9sb2NrX2lycXNhdmUoJnAtPnNpZ2hhbmQtPnNpZ2xvY2ssIGZsYWdzKTsKCQkJdXRpbWUgPSBwLT5zaWduYWwtPmN1dGltZTsKCQkJc3RpbWUgPSBwLT5zaWduYWwtPmNzdGltZTsKCQkJci0+cnVfbnZjc3cgPSBwLT5zaWduYWwtPmNudmNzdzsKCQkJci0+cnVfbml2Y3N3ID0gcC0+c2lnbmFsLT5jbml2Y3N3OwoJCQlyLT5ydV9taW5mbHQgPSBwLT5zaWduYWwtPmNtaW5fZmx0OwoJCQlyLT5ydV9tYWpmbHQgPSBwLT5zaWduYWwtPmNtYWpfZmx0OwoJCXN1bV9ncm91cDoKCQkJdXRpbWUgPSBjcHV0aW1lX2FkZCh1dGltZSwgcC0+c2lnbmFsLT51dGltZSk7CgkJCXN0aW1lID0gY3B1dGltZV9hZGQoc3RpbWUsIHAtPnNpZ25hbC0+c3RpbWUpOwoJCQlyLT5ydV9udmNzdyArPSBwLT5zaWduYWwtPm52Y3N3OwoJCQlyLT5ydV9uaXZjc3cgKz0gcC0+c2lnbmFsLT5uaXZjc3c7CgkJCXItPnJ1X21pbmZsdCArPSBwLT5zaWduYWwtPm1pbl9mbHQ7CgkJCXItPnJ1X21hamZsdCArPSBwLT5zaWduYWwtPm1hal9mbHQ7CgkJCXQgPSBwOwoJCQlkbyB7CgkJCQl1dGltZSA9IGNwdXRpbWVfYWRkKHV0aW1lLCB0LT51dGltZSk7CgkJCQlzdGltZSA9IGNwdXRpbWVfYWRkKHN0aW1lLCB0LT5zdGltZSk7CgkJCQlyLT5ydV9udmNzdyArPSB0LT5udmNzdzsKCQkJCXItPnJ1X25pdmNzdyArPSB0LT5uaXZjc3c7CgkJCQlyLT5ydV9taW5mbHQgKz0gdC0+bWluX2ZsdDsKCQkJCXItPnJ1X21hamZsdCArPSB0LT5tYWpfZmx0OwoJCQkJdCA9IG5leHRfdGhyZWFkKHQpOwoJCQl9IHdoaWxlICh0ICE9IHApOwoJCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZwLT5zaWdoYW5kLT5zaWdsb2NrLCBmbGFncyk7CgkJCWNwdXRpbWVfdG9fdGltZXZhbCh1dGltZSwgJnItPnJ1X3V0aW1lKTsKCQkJY3B1dGltZV90b190aW1ldmFsKHN0aW1lLCAmci0+cnVfc3RpbWUpOwoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQlCVUcoKTsKCX0KfQoKaW50IGdldHJ1c2FnZShzdHJ1Y3QgdGFza19zdHJ1Y3QgKnAsIGludCB3aG8sIHN0cnVjdCBydXNhZ2UgX191c2VyICpydSkKewoJc3RydWN0IHJ1c2FnZSByOwoJcmVhZF9sb2NrKCZ0YXNrbGlzdF9sb2NrKTsKCWtfZ2V0cnVzYWdlKHAsIHdobywgJnIpOwoJcmVhZF91bmxvY2soJnRhc2tsaXN0X2xvY2spOwoJcmV0dXJuIGNvcHlfdG9fdXNlcihydSwgJnIsIHNpemVvZihyKSkgPyAtRUZBVUxUIDogMDsKfQoKYXNtbGlua2FnZSBsb25nIHN5c19nZXRydXNhZ2UoaW50IHdobywgc3RydWN0IHJ1c2FnZSBfX3VzZXIgKnJ1KQp7CglpZiAod2hvICE9IFJVU0FHRV9TRUxGICYmIHdobyAhPSBSVVNBR0VfQ0hJTERSRU4pCgkJcmV0dXJuIC1FSU5WQUw7CglyZXR1cm4gZ2V0cnVzYWdlKGN1cnJlbnQsIHdobywgcnUpOwp9Cgphc21saW5rYWdlIGxvbmcgc3lzX3VtYXNrKGludCBtYXNrKQp7CgltYXNrID0geGNoZygmY3VycmVudC0+ZnMtPnVtYXNrLCBtYXNrICYgU19JUldYVUdPKTsKCXJldHVybiBtYXNrOwp9CiAgICAKYXNtbGlua2FnZSBsb25nIHN5c19wcmN0bChpbnQgb3B0aW9uLCB1bnNpZ25lZCBsb25nIGFyZzIsIHVuc2lnbmVkIGxvbmcgYXJnMywKCQkJICB1bnNpZ25lZCBsb25nIGFyZzQsIHVuc2lnbmVkIGxvbmcgYXJnNSkKewoJbG9uZyBlcnJvcjsKCWludCBzaWc7CgoJZXJyb3IgPSBzZWN1cml0eV90YXNrX3ByY3RsKG9wdGlvbiwgYXJnMiwgYXJnMywgYXJnNCwgYXJnNSk7CglpZiAoZXJyb3IpCgkJcmV0dXJuIGVycm9yOwoKCXN3aXRjaCAob3B0aW9uKSB7CgkJY2FzZSBQUl9TRVRfUERFQVRIU0lHOgoJCQlzaWcgPSBhcmcyOwoJCQlpZiAoIXZhbGlkX3NpZ25hbChzaWcpKSB7CgkJCQllcnJvciA9IC1FSU5WQUw7CgkJCQlicmVhazsKCQkJfQoJCQljdXJyZW50LT5wZGVhdGhfc2lnbmFsID0gc2lnOwoJCQlicmVhazsKCQljYXNlIFBSX0dFVF9QREVBVEhTSUc6CgkJCWVycm9yID0gcHV0X3VzZXIoY3VycmVudC0+cGRlYXRoX3NpZ25hbCwgKGludCBfX3VzZXIgKilhcmcyKTsKCQkJYnJlYWs7CgkJY2FzZSBQUl9HRVRfRFVNUEFCTEU6CgkJCWlmIChjdXJyZW50LT5tbS0+ZHVtcGFibGUpCgkJCQllcnJvciA9IDE7CgkJCWJyZWFrOwoJCWNhc2UgUFJfU0VUX0RVTVBBQkxFOgoJCQlpZiAoYXJnMiA8IDAgfHwgYXJnMiA+IDIpIHsKCQkJCWVycm9yID0gLUVJTlZBTDsKCQkJCWJyZWFrOwoJCQl9CgkJCWN1cnJlbnQtPm1tLT5kdW1wYWJsZSA9IGFyZzI7CgkJCWJyZWFrOwoKCQljYXNlIFBSX1NFVF9VTkFMSUdOOgoJCQllcnJvciA9IFNFVF9VTkFMSUdOX0NUTChjdXJyZW50LCBhcmcyKTsKCQkJYnJlYWs7CgkJY2FzZSBQUl9HRVRfVU5BTElHTjoKCQkJZXJyb3IgPSBHRVRfVU5BTElHTl9DVEwoY3VycmVudCwgYXJnMik7CgkJCWJyZWFrOwoJCWNhc2UgUFJfU0VUX0ZQRU1VOgoJCQllcnJvciA9IFNFVF9GUEVNVV9DVEwoY3VycmVudCwgYXJnMik7CgkJCWJyZWFrOwoJCWNhc2UgUFJfR0VUX0ZQRU1VOgoJCQllcnJvciA9IEdFVF9GUEVNVV9DVEwoY3VycmVudCwgYXJnMik7CgkJCWJyZWFrOwoJCWNhc2UgUFJfU0VUX0ZQRVhDOgoJCQllcnJvciA9IFNFVF9GUEVYQ19DVEwoY3VycmVudCwgYXJnMik7CgkJCWJyZWFrOwoJCWNhc2UgUFJfR0VUX0ZQRVhDOgoJCQllcnJvciA9IEdFVF9GUEVYQ19DVEwoY3VycmVudCwgYXJnMik7CgkJCWJyZWFrOwoJCWNhc2UgUFJfR0VUX1RJTUlORzoKCQkJZXJyb3IgPSBQUl9USU1JTkdfU1RBVElTVElDQUw7CgkJCWJyZWFrOwoJCWNhc2UgUFJfU0VUX1RJTUlORzoKCQkJaWYgKGFyZzIgPT0gUFJfVElNSU5HX1NUQVRJU1RJQ0FMKQoJCQkJZXJyb3IgPSAwOwoJCQllbHNlCgkJCQllcnJvciA9IC1FSU5WQUw7CgkJCWJyZWFrOwoKCQljYXNlIFBSX0dFVF9LRUVQQ0FQUzoKCQkJaWYgKGN1cnJlbnQtPmtlZXBfY2FwYWJpbGl0aWVzKQoJCQkJZXJyb3IgPSAxOwoJCQlicmVhazsKCQljYXNlIFBSX1NFVF9LRUVQQ0FQUzoKCQkJaWYgKGFyZzIgIT0gMCAmJiBhcmcyICE9IDEpIHsKCQkJCWVycm9yID0gLUVJTlZBTDsKCQkJCWJyZWFrOwoJCQl9CgkJCWN1cnJlbnQtPmtlZXBfY2FwYWJpbGl0aWVzID0gYXJnMjsKCQkJYnJlYWs7CgkJY2FzZSBQUl9TRVRfTkFNRTogewoJCQlzdHJ1Y3QgdGFza19zdHJ1Y3QgKm1lID0gY3VycmVudDsKCQkJdW5zaWduZWQgY2hhciBuY29tbVtzaXplb2YobWUtPmNvbW0pXTsKCgkJCW5jb21tW3NpemVvZihtZS0+Y29tbSktMV0gPSAwOwoJCQlpZiAoc3RybmNweV9mcm9tX3VzZXIobmNvbW0sIChjaGFyIF9fdXNlciAqKWFyZzIsCgkJCQkJCXNpemVvZihtZS0+Y29tbSktMSkgPCAwKQoJCQkJcmV0dXJuIC1FRkFVTFQ7CgkJCXNldF90YXNrX2NvbW0obWUsIG5jb21tKTsKCQkJcmV0dXJuIDA7CgkJfQoJCWNhc2UgUFJfR0VUX05BTUU6IHsKCQkJc3RydWN0IHRhc2tfc3RydWN0ICptZSA9IGN1cnJlbnQ7CgkJCXVuc2lnbmVkIGNoYXIgdGNvbW1bc2l6ZW9mKG1lLT5jb21tKV07CgoJCQlnZXRfdGFza19jb21tKHRjb21tLCBtZSk7CgkJCWlmIChjb3B5X3RvX3VzZXIoKGNoYXIgX191c2VyICopYXJnMiwgdGNvbW0sIHNpemVvZih0Y29tbSkpKQoJCQkJcmV0dXJuIC1FRkFVTFQ7CgkJCXJldHVybiAwOwoJCX0KCQlkZWZhdWx0OgoJCQllcnJvciA9IC1FSU5WQUw7CgkJCWJyZWFrOwoJfQoJcmV0dXJuIGVycm9yOwp9Cg==