LyoKICogIGxpbnV4L2tlcm5lbC9zeXMuYwogKgogKiAgQ29weXJpZ2h0IChDKSAxOTkxLCAxOTkyICBMaW51cyBUb3J2YWxkcwogKi8KCiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L21tLmg+CiNpbmNsdWRlIDxsaW51eC91dHNuYW1lLmg+CiNpbmNsdWRlIDxsaW51eC9tbWFuLmg+CiNpbmNsdWRlIDxsaW51eC9zbXBfbG9jay5oPgojaW5jbHVkZSA8bGludXgvbm90aWZpZXIuaD4KI2luY2x1ZGUgPGxpbnV4L3JlYm9vdC5oPgojaW5jbHVkZSA8bGludXgvcHJjdGwuaD4KI2luY2x1ZGUgPGxpbnV4L2hpZ2h1aWQuaD4KI2luY2x1ZGUgPGxpbnV4L2ZzLmg+CiNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4KI2luY2x1ZGUgPGxpbnV4L2tleGVjLmg+CiNpbmNsdWRlIDxsaW51eC93b3JrcXVldWUuaD4KI2luY2x1ZGUgPGxpbnV4L2NhcGFiaWxpdHkuaD4KI2luY2x1ZGUgPGxpbnV4L2RldmljZS5oPgojaW5jbHVkZSA8bGludXgva2V5Lmg+CiNpbmNsdWRlIDxsaW51eC90aW1lcy5oPgojaW5jbHVkZSA8bGludXgvcG9zaXgtdGltZXJzLmg+CiNpbmNsdWRlIDxsaW51eC9zZWN1cml0eS5oPgojaW5jbHVkZSA8bGludXgvZGNvb2tpZXMuaD4KI2luY2x1ZGUgPGxpbnV4L3N1c3BlbmQuaD4KI2luY2x1ZGUgPGxpbnV4L3R0eS5oPgojaW5jbHVkZSA8bGludXgvc2lnbmFsLmg+CiNpbmNsdWRlIDxsaW51eC9jbl9wcm9jLmg+CiNpbmNsdWRlIDxsaW51eC9nZXRjcHUuaD4KCiNpbmNsdWRlIDxsaW51eC9jb21wYXQuaD4KI2luY2x1ZGUgPGxpbnV4L3N5c2NhbGxzLmg+CiNpbmNsdWRlIDxsaW51eC9rcHJvYmVzLmg+CgojaW5jbHVkZSA8YXNtL3VhY2Nlc3MuaD4KI2luY2x1ZGUgPGFzbS9pby5oPgojaW5jbHVkZSA8YXNtL3VuaXN0ZC5oPgoKI2lmbmRlZiBTRVRfVU5BTElHTl9DVEwKIyBkZWZpbmUgU0VUX1VOQUxJR05fQ1RMKGEsYikJKC1FSU5WQUwpCiNlbmRpZgojaWZuZGVmIEdFVF9VTkFMSUdOX0NUTAojIGRlZmluZSBHRVRfVU5BTElHTl9DVEwoYSxiKQkoLUVJTlZBTCkKI2VuZGlmCiNpZm5kZWYgU0VUX0ZQRU1VX0NUTAojIGRlZmluZSBTRVRfRlBFTVVfQ1RMKGEsYikJKC1FSU5WQUwpCiNlbmRpZgojaWZuZGVmIEdFVF9GUEVNVV9DVEwKIyBkZWZpbmUgR0VUX0ZQRU1VX0NUTChhLGIpCSgtRUlOVkFMKQojZW5kaWYKI2lmbmRlZiBTRVRfRlBFWENfQ1RMCiMgZGVmaW5lIFNFVF9GUEVYQ19DVEwoYSxiKQkoLUVJTlZBTCkKI2VuZGlmCiNpZm5kZWYgR0VUX0ZQRVhDX0NUTAojIGRlZmluZSBHRVRfRlBFWENfQ1RMKGEsYikJKC1FSU5WQUwpCiNlbmRpZgojaWZuZGVmIEdFVF9FTkRJQU4KIyBkZWZpbmUgR0VUX0VORElBTihhLGIpCSgtRUlOVkFMKQojZW5kaWYKI2lmbmRlZiBTRVRfRU5ESUFOCiMgZGVmaW5lIFNFVF9FTkRJQU4oYSxiKQkoLUVJTlZBTCkKI2VuZGlmCgovKgogKiB0aGlzIGlzIHdoZXJlIHRoZSBzeXN0ZW0td2lkZSBvdmVyZmxvdyBVSUQgYW5kIEdJRCBhcmUgZGVmaW5lZCwgZm9yCiAqIGFyY2hpdGVjdHVyZXMgdGhhdCBub3cgaGF2ZSAzMi1iaXQgVUlEL0dJRCBidXQgZGlkbid0IGluIHRoZSBwYXN0CiAqLwoKaW50IG92ZXJmbG93dWlkID0gREVGQVVMVF9PVkVSRkxPV1VJRDsKaW50IG92ZXJmbG93Z2lkID0gREVGQVVMVF9PVkVSRkxPV0dJRDsKCiNpZmRlZiBDT05GSUdfVUlEMTYKRVhQT1JUX1NZTUJPTChvdmVyZmxvd3VpZCk7CkVYUE9SVF9TWU1CT0wob3ZlcmZsb3dnaWQpOwojZW5kaWYKCi8qCiAqIHRoZSBzYW1lIGFzIGFib3ZlLCBidXQgZm9yIGZpbGVzeXN0ZW1zIHdoaWNoIGNhbiBvbmx5IHN0b3JlIGEgMTYtYml0CiAqIFVJRCBhbmQgR0lELiBhcyBzdWNoLCB0aGlzIGlzIG5lZWRlZCBvbiBhbGwgYXJjaGl0ZWN0dXJlcwogKi8KCmludCBmc19vdmVyZmxvd3VpZCA9IERFRkFVTFRfRlNfT1ZFUkZMT1dVSUQ7CmludCBmc19vdmVyZmxvd2dpZCA9IERFRkFVTFRfRlNfT1ZFUkZMT1dVSUQ7CgpFWFBPUlRfU1lNQk9MKGZzX292ZXJmbG93dWlkKTsKRVhQT1JUX1NZTUJPTChmc19vdmVyZmxvd2dpZCk7CgovKgogKiB0aGlzIGluZGljYXRlcyB3aGV0aGVyIHlvdSBjYW4gcmVib290IHdpdGggY3RybC1hbHQtZGVsOiB0aGUgZGVmYXVsdCBpcyB5ZXMKICovCgppbnQgQ19BX0QgPSAxOwpzdHJ1Y3QgcGlkICpjYWRfcGlkOwpFWFBPUlRfU1lNQk9MKGNhZF9waWQpOwoKLyoKICoJTm90aWZpZXIgbGlzdCBmb3Iga2VybmVsIGNvZGUgd2hpY2ggd2FudHMgdG8gYmUgY2FsbGVkCiAqCWF0IHNodXRkb3duLiBUaGlzIGlzIHVzZWQgdG8gc3RvcCBhbnkgaWRsaW5nIERNQSBvcGVyYXRpb25zCiAqCWFuZCB0aGUgbGlrZS4gCiAqLwoKc3RhdGljIEJMT0NLSU5HX05PVElGSUVSX0hFQUQocmVib290X25vdGlmaWVyX2xpc3QpOwoKLyoKICoJTm90aWZpZXIgY2hhaW4gY29yZSByb3V0aW5lcy4gIFRoZSBleHBvcnRlZCByb3V0aW5lcyBiZWxvdwogKglhcmUgbGF5ZXJlZCBvbiB0b3Agb2YgdGhlc2UsIHdpdGggYXBwcm9wcmlhdGUgbG9ja2luZyBhZGRlZC4KICovCgpzdGF0aWMgaW50IG5vdGlmaWVyX2NoYWluX3JlZ2lzdGVyKHN0cnVjdCBub3RpZmllcl9ibG9jayAqKm5sLAoJCXN0cnVjdCBub3RpZmllcl9ibG9jayAqbikKewoJd2hpbGUgKCgqbmwpICE9IE5VTEwpIHsKCQlpZiAobi0+cHJpb3JpdHkgPiAoKm5sKS0+cHJpb3JpdHkpCgkJCWJyZWFrOwoJCW5sID0gJigoKm5sKS0+bmV4dCk7Cgl9CgluLT5uZXh0ID0gKm5sOwoJcmN1X2Fzc2lnbl9wb2ludGVyKCpubCwgbik7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBub3RpZmllcl9jaGFpbl91bnJlZ2lzdGVyKHN0cnVjdCBub3RpZmllcl9ibG9jayAqKm5sLAoJCXN0cnVjdCBub3RpZmllcl9ibG9jayAqbikKewoJd2hpbGUgKCgqbmwpICE9IE5VTEwpIHsKCQlpZiAoKCpubCkgPT0gbikgewoJCQlyY3VfYXNzaWduX3BvaW50ZXIoKm5sLCBuLT5uZXh0KTsKCQkJcmV0dXJuIDA7CgkJfQoJCW5sID0gJigoKm5sKS0+bmV4dCk7Cgl9CglyZXR1cm4gLUVOT0VOVDsKfQoKc3RhdGljIGludCBfX2twcm9iZXMgbm90aWZpZXJfY2FsbF9jaGFpbihzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgKipubCwKCQl1bnNpZ25lZCBsb25nIHZhbCwgdm9pZCAqdikKewoJaW50IHJldCA9IE5PVElGWV9ET05FOwoJc3RydWN0IG5vdGlmaWVyX2Jsb2NrICpuYiwgKm5leHRfbmI7CgoJbmIgPSByY3VfZGVyZWZlcmVuY2UoKm5sKTsKCXdoaWxlIChuYikgewoJCW5leHRfbmIgPSByY3VfZGVyZWZlcmVuY2UobmItPm5leHQpOwoJCXJldCA9IG5iLT5ub3RpZmllcl9jYWxsKG5iLCB2YWwsIHYpOwoJCWlmICgocmV0ICYgTk9USUZZX1NUT1BfTUFTSykgPT0gTk9USUZZX1NUT1BfTUFTSykKCQkJYnJlYWs7CgkJbmIgPSBuZXh0X25iOwoJfQoJcmV0dXJuIHJldDsKfQoKLyoKICoJQXRvbWljIG5vdGlmaWVyIGNoYWluIHJvdXRpbmVzLiAgUmVnaXN0cmF0aW9uIGFuZCB1bnJlZ2lzdHJhdGlvbgogKgl1c2UgYSBzcGlubG9jaywgYW5kIGNhbGxfY2hhaW4gaXMgc3luY2hyb25pemVkIGJ5IFJDVSAobm8gbG9ja3MpLgogKi8KCi8qKgogKglhdG9taWNfbm90aWZpZXJfY2hhaW5fcmVnaXN0ZXIgLSBBZGQgbm90aWZpZXIgdG8gYW4gYXRvbWljIG5vdGlmaWVyIGNoYWluCiAqCUBuaDogUG9pbnRlciB0byBoZWFkIG9mIHRoZSBhdG9taWMgbm90aWZpZXIgY2hhaW4KICoJQG46IE5ldyBlbnRyeSBpbiBub3RpZmllciBjaGFpbgogKgogKglBZGRzIGEgbm90aWZpZXIgdG8gYW4gYXRvbWljIG5vdGlmaWVyIGNoYWluLgogKgogKglDdXJyZW50bHkgYWx3YXlzIHJldHVybnMgemVyby4KICovCgppbnQgYXRvbWljX25vdGlmaWVyX2NoYWluX3JlZ2lzdGVyKHN0cnVjdCBhdG9taWNfbm90aWZpZXJfaGVhZCAqbmgsCgkJc3RydWN0IG5vdGlmaWVyX2Jsb2NrICpuKQp7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoJaW50IHJldDsKCglzcGluX2xvY2tfaXJxc2F2ZSgmbmgtPmxvY2ssIGZsYWdzKTsKCXJldCA9IG5vdGlmaWVyX2NoYWluX3JlZ2lzdGVyKCZuaC0+aGVhZCwgbik7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZuaC0+bG9jaywgZmxhZ3MpOwoJcmV0dXJuIHJldDsKfQoKRVhQT1JUX1NZTUJPTF9HUEwoYXRvbWljX25vdGlmaWVyX2NoYWluX3JlZ2lzdGVyKTsKCi8qKgogKglhdG9taWNfbm90aWZpZXJfY2hhaW5fdW5yZWdpc3RlciAtIFJlbW92ZSBub3RpZmllciBmcm9tIGFuIGF0b21pYyBub3RpZmllciBjaGFpbgogKglAbmg6IFBvaW50ZXIgdG8gaGVhZCBvZiB0aGUgYXRvbWljIG5vdGlmaWVyIGNoYWluCiAqCUBuOiBFbnRyeSB0byByZW1vdmUgZnJvbSBub3RpZmllciBjaGFpbgogKgogKglSZW1vdmVzIGEgbm90aWZpZXIgZnJvbSBhbiBhdG9taWMgbm90aWZpZXIgY2hhaW4uCiAqCiAqCVJldHVybnMgemVybyBvbiBzdWNjZXNzIG9yICUtRU5PRU5UIG9uIGZhaWx1cmUuCiAqLwppbnQgYXRvbWljX25vdGlmaWVyX2NoYWluX3VucmVnaXN0ZXIoc3RydWN0IGF0b21pY19ub3RpZmllcl9oZWFkICpuaCwKCQlzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgKm4pCnsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CglpbnQgcmV0OwoKCXNwaW5fbG9ja19pcnFzYXZlKCZuaC0+bG9jaywgZmxhZ3MpOwoJcmV0ID0gbm90aWZpZXJfY2hhaW5fdW5yZWdpc3RlcigmbmgtPmhlYWQsIG4pOwoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmbmgtPmxvY2ssIGZsYWdzKTsKCXN5bmNocm9uaXplX3JjdSgpOwoJcmV0dXJuIHJldDsKfQoKRVhQT1JUX1NZTUJPTF9HUEwoYXRvbWljX25vdGlmaWVyX2NoYWluX3VucmVnaXN0ZXIpOwoKLyoqCiAqCWF0b21pY19ub3RpZmllcl9jYWxsX2NoYWluIC0gQ2FsbCBmdW5jdGlvbnMgaW4gYW4gYXRvbWljIG5vdGlmaWVyIGNoYWluCiAqCUBuaDogUG9pbnRlciB0byBoZWFkIG9mIHRoZSBhdG9taWMgbm90aWZpZXIgY2hhaW4KICoJQHZhbDogVmFsdWUgcGFzc2VkIHVubW9kaWZpZWQgdG8gbm90aWZpZXIgZnVuY3Rpb24KICoJQHY6IFBvaW50ZXIgcGFzc2VkIHVubW9kaWZpZWQgdG8gbm90aWZpZXIgZnVuY3Rpb24KICoKICoJQ2FsbHMgZWFjaCBmdW5jdGlvbiBpbiBhIG5vdGlmaWVyIGNoYWluIGluIHR1cm4uICBUaGUgZnVuY3Rpb25zCiAqCXJ1biBpbiBhbiBhdG9taWMgY29udGV4dCwgc28gdGhleSBtdXN0IG5vdCBibG9jay4KICoJVGhpcyByb3V0aW5lIHVzZXMgUkNVIHRvIHN5bmNocm9uaXplIHdpdGggY2hhbmdlcyB0byB0aGUgY2hhaW4uCiAqCiAqCUlmIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIG5vdGlmaWVyIGNhbiBiZSBhbmQnZWQKICoJd2l0aCAlTk9USUZZX1NUT1BfTUFTSyB0aGVuIGF0b21pY19ub3RpZmllcl9jYWxsX2NoYWluKCkKICoJd2lsbCByZXR1cm4gaW1tZWRpYXRlbHksIHdpdGggdGhlIHJldHVybiB2YWx1ZSBvZgogKgl0aGUgbm90aWZpZXIgZnVuY3Rpb24gd2hpY2ggaGFsdGVkIGV4ZWN1dGlvbi4KICoJT3RoZXJ3aXNlIHRoZSByZXR1cm4gdmFsdWUgaXMgdGhlIHJldHVybiB2YWx1ZQogKglvZiB0aGUgbGFzdCBub3RpZmllciBmdW5jdGlvbiBjYWxsZWQuCiAqLwogCmludCBfX2twcm9iZXMgYXRvbWljX25vdGlmaWVyX2NhbGxfY2hhaW4oc3RydWN0IGF0b21pY19ub3RpZmllcl9oZWFkICpuaCwKCQl1bnNpZ25lZCBsb25nIHZhbCwgdm9pZCAqdikKewoJaW50IHJldDsKCglyY3VfcmVhZF9sb2NrKCk7CglyZXQgPSBub3RpZmllcl9jYWxsX2NoYWluKCZuaC0+aGVhZCwgdmFsLCB2KTsKCXJjdV9yZWFkX3VubG9jaygpOwoJcmV0dXJuIHJldDsKfQoKRVhQT1JUX1NZTUJPTF9HUEwoYXRvbWljX25vdGlmaWVyX2NhbGxfY2hhaW4pOwoKLyoKICoJQmxvY2tpbmcgbm90aWZpZXIgY2hhaW4gcm91dGluZXMuICBBbGwgYWNjZXNzIHRvIHRoZSBjaGFpbiBpcwogKglzeW5jaHJvbml6ZWQgYnkgYW4gcndzZW0uCiAqLwoKLyoqCiAqCWJsb2NraW5nX25vdGlmaWVyX2NoYWluX3JlZ2lzdGVyIC0gQWRkIG5vdGlmaWVyIHRvIGEgYmxvY2tpbmcgbm90aWZpZXIgY2hhaW4KICoJQG5oOiBQb2ludGVyIHRvIGhlYWQgb2YgdGhlIGJsb2NraW5nIG5vdGlmaWVyIGNoYWluCiAqCUBuOiBOZXcgZW50cnkgaW4gbm90aWZpZXIgY2hhaW4KICoKICoJQWRkcyBhIG5vdGlmaWVyIHRvIGEgYmxvY2tpbmcgbm90aWZpZXIgY2hhaW4uCiAqCU11c3QgYmUgY2FsbGVkIGluIHByb2Nlc3MgY29udGV4dC4KICoKICoJQ3VycmVudGx5IGFsd2F5cyByZXR1cm5zIHplcm8uCiAqLwogCmludCBibG9ja2luZ19ub3RpZmllcl9jaGFpbl9yZWdpc3RlcihzdHJ1Y3QgYmxvY2tpbmdfbm90aWZpZXJfaGVhZCAqbmgsCgkJc3RydWN0IG5vdGlmaWVyX2Jsb2NrICpuKQp7CglpbnQgcmV0OwoKCS8qCgkgKiBUaGlzIGNvZGUgZ2V0cyB1c2VkIGR1cmluZyBib290LXVwLCB3aGVuIHRhc2sgc3dpdGNoaW5nIGlzCgkgKiBub3QgeWV0IHdvcmtpbmcgYW5kIGludGVycnVwdHMgbXVzdCByZW1haW4gZGlzYWJsZWQuICBBdAoJICogc3VjaCB0aW1lcyB3ZSBtdXN0IG5vdCBjYWxsIGRvd25fd3JpdGUoKS4KCSAqLwoJaWYgKHVubGlrZWx5KHN5c3RlbV9zdGF0ZSA9PSBTWVNURU1fQk9PVElORykpCgkJcmV0dXJuIG5vdGlmaWVyX2NoYWluX3JlZ2lzdGVyKCZuaC0+aGVhZCwgbik7CgoJZG93bl93cml0ZSgmbmgtPnJ3c2VtKTsKCXJldCA9IG5vdGlmaWVyX2NoYWluX3JlZ2lzdGVyKCZuaC0+aGVhZCwgbik7Cgl1cF93cml0ZSgmbmgtPnJ3c2VtKTsKCXJldHVybiByZXQ7Cn0KCkVYUE9SVF9TWU1CT0xfR1BMKGJsb2NraW5nX25vdGlmaWVyX2NoYWluX3JlZ2lzdGVyKTsKCi8qKgogKglibG9ja2luZ19ub3RpZmllcl9jaGFpbl91bnJlZ2lzdGVyIC0gUmVtb3ZlIG5vdGlmaWVyIGZyb20gYSBibG9ja2luZyBub3RpZmllciBjaGFpbgogKglAbmg6IFBvaW50ZXIgdG8gaGVhZCBvZiB0aGUgYmxvY2tpbmcgbm90aWZpZXIgY2hhaW4KICoJQG46IEVudHJ5IHRvIHJlbW92ZSBmcm9tIG5vdGlmaWVyIGNoYWluCiAqCiAqCVJlbW92ZXMgYSBub3RpZmllciBmcm9tIGEgYmxvY2tpbmcgbm90aWZpZXIgY2hhaW4uCiAqCU11c3QgYmUgY2FsbGVkIGZyb20gcHJvY2VzcyBjb250ZXh0LgogKgogKglSZXR1cm5zIHplcm8gb24gc3VjY2VzcyBvciAlLUVOT0VOVCBvbiBmYWlsdXJlLgogKi8KaW50IGJsb2NraW5nX25vdGlmaWVyX2NoYWluX3VucmVnaXN0ZXIoc3RydWN0IGJsb2NraW5nX25vdGlmaWVyX2hlYWQgKm5oLAoJCXN0cnVjdCBub3RpZmllcl9ibG9jayAqbikKewoJaW50IHJldDsKCgkvKgoJICogVGhpcyBjb2RlIGdldHMgdXNlZCBkdXJpbmcgYm9vdC11cCwgd2hlbiB0YXNrIHN3aXRjaGluZyBpcwoJICogbm90IHlldCB3b3JraW5nIGFuZCBpbnRlcnJ1cHRzIG11c3QgcmVtYWluIGRpc2FibGVkLiAgQXQKCSAqIHN1Y2ggdGltZXMgd2UgbXVzdCBub3QgY2FsbCBkb3duX3dyaXRlKCkuCgkgKi8KCWlmICh1bmxpa2VseShzeXN0ZW1fc3RhdGUgPT0gU1lTVEVNX0JPT1RJTkcpKQoJCXJldHVybiBub3RpZmllcl9jaGFpbl91bnJlZ2lzdGVyKCZuaC0+aGVhZCwgbik7CgoJZG93bl93cml0ZSgmbmgtPnJ3c2VtKTsKCXJldCA9IG5vdGlmaWVyX2NoYWluX3VucmVnaXN0ZXIoJm5oLT5oZWFkLCBuKTsKCXVwX3dyaXRlKCZuaC0+cndzZW0pOwoJcmV0dXJuIHJldDsKfQoKRVhQT1JUX1NZTUJPTF9HUEwoYmxvY2tpbmdfbm90aWZpZXJfY2hhaW5fdW5yZWdpc3Rlcik7CgovKioKICoJYmxvY2tpbmdfbm90aWZpZXJfY2FsbF9jaGFpbiAtIENhbGwgZnVuY3Rpb25zIGluIGEgYmxvY2tpbmcgbm90aWZpZXIgY2hhaW4KICoJQG5oOiBQb2ludGVyIHRvIGhlYWQgb2YgdGhlIGJsb2NraW5nIG5vdGlmaWVyIGNoYWluCiAqCUB2YWw6IFZhbHVlIHBhc3NlZCB1bm1vZGlmaWVkIHRvIG5vdGlmaWVyIGZ1bmN0aW9uCiAqCUB2OiBQb2ludGVyIHBhc3NlZCB1bm1vZGlmaWVkIHRvIG5vdGlmaWVyIGZ1bmN0aW9uCiAqCiAqCUNhbGxzIGVhY2ggZnVuY3Rpb24gaW4gYSBub3RpZmllciBjaGFpbiBpbiB0dXJuLiAgVGhlIGZ1bmN0aW9ucwogKglydW4gaW4gYSBwcm9jZXNzIGNvbnRleHQsIHNvIHRoZXkgYXJlIGFsbG93ZWQgdG8gYmxvY2suCiAqCiAqCUlmIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIG5vdGlmaWVyIGNhbiBiZSBhbmQnZWQKICoJd2l0aCAlTk9USUZZX1NUT1BfTUFTSyB0aGVuIGJsb2NraW5nX25vdGlmaWVyX2NhbGxfY2hhaW4oKQogKgl3aWxsIHJldHVybiBpbW1lZGlhdGVseSwgd2l0aCB0aGUgcmV0dXJuIHZhbHVlIG9mCiAqCXRoZSBub3RpZmllciBmdW5jdGlvbiB3aGljaCBoYWx0ZWQgZXhlY3V0aW9uLgogKglPdGhlcndpc2UgdGhlIHJldHVybiB2YWx1ZSBpcyB0aGUgcmV0dXJuIHZhbHVlCiAqCW9mIHRoZSBsYXN0IG5vdGlmaWVyIGZ1bmN0aW9uIGNhbGxlZC4KICovCiAKaW50IGJsb2NraW5nX25vdGlmaWVyX2NhbGxfY2hhaW4oc3RydWN0IGJsb2NraW5nX25vdGlmaWVyX2hlYWQgKm5oLAoJCXVuc2lnbmVkIGxvbmcgdmFsLCB2b2lkICp2KQp7CglpbnQgcmV0ID0gTk9USUZZX0RPTkU7CgoJLyoKCSAqIFdlIGNoZWNrIHRoZSBoZWFkIG91dHNpZGUgdGhlIGxvY2ssIGJ1dCBpZiB0aGlzIGFjY2VzcyBpcwoJICogcmFjeSB0aGVuIGl0IGRvZXMgbm90IG1hdHRlciB3aGF0IHRoZSByZXN1bHQgb2YgdGhlIHRlc3QKCSAqIGlzLCB3ZSByZS1jaGVjayB0aGUgbGlzdCBhZnRlciBoYXZpbmcgdGFrZW4gdGhlIGxvY2sgYW55d2F5OgoJICovCglpZiAocmN1X2RlcmVmZXJlbmNlKG5oLT5oZWFkKSkgewoJCWRvd25fcmVhZCgmbmgtPnJ3c2VtKTsKCQlyZXQgPSBub3RpZmllcl9jYWxsX2NoYWluKCZuaC0+aGVhZCwgdmFsLCB2KTsKCQl1cF9yZWFkKCZuaC0+cndzZW0pOwoJfQoJcmV0dXJuIHJldDsKfQoKRVhQT1JUX1NZTUJPTF9HUEwoYmxvY2tpbmdfbm90aWZpZXJfY2FsbF9jaGFpbik7CgovKgogKglSYXcgbm90aWZpZXIgY2hhaW4gcm91dGluZXMuICBUaGVyZSBpcyBubyBwcm90ZWN0aW9uOwogKgl0aGUgY2FsbGVyIG11c3QgcHJvdmlkZSBpdC4gIFVzZSBhdCB5b3VyIG93biByaXNrIQogKi8KCi8qKgogKglyYXdfbm90aWZpZXJfY2hhaW5fcmVnaXN0ZXIgLSBBZGQgbm90aWZpZXIgdG8gYSByYXcgbm90aWZpZXIgY2hhaW4KICoJQG5oOiBQb2ludGVyIHRvIGhlYWQgb2YgdGhlIHJhdyBub3RpZmllciBjaGFpbgogKglAbjogTmV3IGVudHJ5IGluIG5vdGlmaWVyIGNoYWluCiAqCiAqCUFkZHMgYSBub3RpZmllciB0byBhIHJhdyBub3RpZmllciBjaGFpbi4KICoJQWxsIGxvY2tpbmcgbXVzdCBiZSBwcm92aWRlZCBieSB0aGUgY2FsbGVyLgogKgogKglDdXJyZW50bHkgYWx3YXlzIHJldHVybnMgemVyby4KICovCgppbnQgcmF3X25vdGlmaWVyX2NoYWluX3JlZ2lzdGVyKHN0cnVjdCByYXdfbm90aWZpZXJfaGVhZCAqbmgsCgkJc3RydWN0IG5vdGlmaWVyX2Jsb2NrICpuKQp7CglyZXR1cm4gbm90aWZpZXJfY2hhaW5fcmVnaXN0ZXIoJm5oLT5oZWFkLCBuKTsKfQoKRVhQT1JUX1NZTUJPTF9HUEwocmF3X25vdGlmaWVyX2NoYWluX3JlZ2lzdGVyKTsKCi8qKgogKglyYXdfbm90aWZpZXJfY2hhaW5fdW5yZWdpc3RlciAtIFJlbW92ZSBub3RpZmllciBmcm9tIGEgcmF3IG5vdGlmaWVyIGNoYWluCiAqCUBuaDogUG9pbnRlciB0byBoZWFkIG9mIHRoZSByYXcgbm90aWZpZXIgY2hhaW4KICoJQG46IEVudHJ5IHRvIHJlbW92ZSBmcm9tIG5vdGlmaWVyIGNoYWluCiAqCiAqCVJlbW92ZXMgYSBub3RpZmllciBmcm9tIGEgcmF3IG5vdGlmaWVyIGNoYWluLgogKglBbGwgbG9ja2luZyBtdXN0IGJlIHByb3ZpZGVkIGJ5IHRoZSBjYWxsZXIuCiAqCiAqCVJldHVybnMgemVybyBvbiBzdWNjZXNzIG9yICUtRU5PRU5UIG9uIGZhaWx1cmUuCiAqLwppbnQgcmF3X25vdGlmaWVyX2NoYWluX3VucmVnaXN0ZXIoc3RydWN0IHJhd19ub3RpZmllcl9oZWFkICpuaCwKCQlzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgKm4pCnsKCXJldHVybiBub3RpZmllcl9jaGFpbl91bnJlZ2lzdGVyKCZuaC0+aGVhZCwgbik7Cn0KCkVYUE9SVF9TWU1CT0xfR1BMKHJhd19ub3RpZmllcl9jaGFpbl91bnJlZ2lzdGVyKTsKCi8qKgogKglyYXdfbm90aWZpZXJfY2FsbF9jaGFpbiAtIENhbGwgZnVuY3Rpb25zIGluIGEgcmF3IG5vdGlmaWVyIGNoYWluCiAqCUBuaDogUG9pbnRlciB0byBoZWFkIG9mIHRoZSByYXcgbm90aWZpZXIgY2hhaW4KICoJQHZhbDogVmFsdWUgcGFzc2VkIHVubW9kaWZpZWQgdG8gbm90aWZpZXIgZnVuY3Rpb24KICoJQHY6IFBvaW50ZXIgcGFzc2VkIHVubW9kaWZpZWQgdG8gbm90aWZpZXIgZnVuY3Rpb24KICoKICoJQ2FsbHMgZWFjaCBmdW5jdGlvbiBpbiBhIG5vdGlmaWVyIGNoYWluIGluIHR1cm4uICBUaGUgZnVuY3Rpb25zCiAqCXJ1biBpbiBhbiB1bmRlZmluZWQgY29udGV4dC4KICoJQWxsIGxvY2tpbmcgbXVzdCBiZSBwcm92aWRlZCBieSB0aGUgY2FsbGVyLgogKgogKglJZiB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBub3RpZmllciBjYW4gYmUgYW5kJ2VkCiAqCXdpdGggJU5PVElGWV9TVE9QX01BU0sgdGhlbiByYXdfbm90aWZpZXJfY2FsbF9jaGFpbigpCiAqCXdpbGwgcmV0dXJuIGltbWVkaWF0ZWx5LCB3aXRoIHRoZSByZXR1cm4gdmFsdWUgb2YKICoJdGhlIG5vdGlmaWVyIGZ1bmN0aW9uIHdoaWNoIGhhbHRlZCBleGVjdXRpb24uCiAqCU90aGVyd2lzZSB0aGUgcmV0dXJuIHZhbHVlIGlzIHRoZSByZXR1cm4gdmFsdWUKICoJb2YgdGhlIGxhc3Qgbm90aWZpZXIgZnVuY3Rpb24gY2FsbGVkLgogKi8KCmludCByYXdfbm90aWZpZXJfY2FsbF9jaGFpbihzdHJ1Y3QgcmF3X25vdGlmaWVyX2hlYWQgKm5oLAoJCXVuc2lnbmVkIGxvbmcgdmFsLCB2b2lkICp2KQp7CglyZXR1cm4gbm90aWZpZXJfY2FsbF9jaGFpbigmbmgtPmhlYWQsIHZhbCwgdik7Cn0KCkVYUE9SVF9TWU1CT0xfR1BMKHJhd19ub3RpZmllcl9jYWxsX2NoYWluKTsKCi8qCiAqCVNSQ1Ugbm90aWZpZXIgY2hhaW4gcm91dGluZXMuICAgIFJlZ2lzdHJhdGlvbiBhbmQgdW5yZWdpc3RyYXRpb24KICoJdXNlIGEgbXV0ZXgsIGFuZCBjYWxsX2NoYWluIGlzIHN5bmNocm9uaXplZCBieSBTUkNVIChubyBsb2NrcykuCiAqLwoKLyoqCiAqCXNyY3Vfbm90aWZpZXJfY2hhaW5fcmVnaXN0ZXIgLSBBZGQgbm90aWZpZXIgdG8gYW4gU1JDVSBub3RpZmllciBjaGFpbgogKglAbmg6IFBvaW50ZXIgdG8gaGVhZCBvZiB0aGUgU1JDVSBub3RpZmllciBjaGFpbgogKglAbjogTmV3IGVudHJ5IGluIG5vdGlmaWVyIGNoYWluCiAqCiAqCUFkZHMgYSBub3RpZmllciB0byBhbiBTUkNVIG5vdGlmaWVyIGNoYWluLgogKglNdXN0IGJlIGNhbGxlZCBpbiBwcm9jZXNzIGNvbnRleHQuCiAqCiAqCUN1cnJlbnRseSBhbHdheXMgcmV0dXJucyB6ZXJvLgogKi8KCmludCBzcmN1X25vdGlmaWVyX2NoYWluX3JlZ2lzdGVyKHN0cnVjdCBzcmN1X25vdGlmaWVyX2hlYWQgKm5oLAoJCXN0cnVjdCBub3RpZmllcl9ibG9jayAqbikKewoJaW50IHJldDsKCgkvKgoJICogVGhpcyBjb2RlIGdldHMgdXNlZCBkdXJpbmcgYm9vdC11cCwgd2hlbiB0YXNrIHN3aXRjaGluZyBpcwoJICogbm90IHlldCB3b3JraW5nIGFuZCBpbnRlcnJ1cHRzIG11c3QgcmVtYWluIGRpc2FibGVkLiAgQXQKCSAqIHN1Y2ggdGltZXMgd2UgbXVzdCBub3QgY2FsbCBtdXRleF9sb2NrKCkuCgkgKi8KCWlmICh1bmxpa2VseShzeXN0ZW1fc3RhdGUgPT0gU1lTVEVNX0JPT1RJTkcpKQoJCXJldHVybiBub3RpZmllcl9jaGFpbl9yZWdpc3RlcigmbmgtPmhlYWQsIG4pOwoKCW11dGV4X2xvY2soJm5oLT5tdXRleCk7CglyZXQgPSBub3RpZmllcl9jaGFpbl9yZWdpc3RlcigmbmgtPmhlYWQsIG4pOwoJbXV0ZXhfdW5sb2NrKCZuaC0+bXV0ZXgpOwoJcmV0dXJuIHJldDsKfQoKRVhQT1JUX1NZTUJPTF9HUEwoc3JjdV9ub3RpZmllcl9jaGFpbl9yZWdpc3Rlcik7CgovKioKICoJc3JjdV9ub3RpZmllcl9jaGFpbl91bnJlZ2lzdGVyIC0gUmVtb3ZlIG5vdGlmaWVyIGZyb20gYW4gU1JDVSBub3RpZmllciBjaGFpbgogKglAbmg6IFBvaW50ZXIgdG8gaGVhZCBvZiB0aGUgU1JDVSBub3RpZmllciBjaGFpbgogKglAbjogRW50cnkgdG8gcmVtb3ZlIGZyb20gbm90aWZpZXIgY2hhaW4KICoKICoJUmVtb3ZlcyBhIG5vdGlmaWVyIGZyb20gYW4gU1JDVSBub3RpZmllciBjaGFpbi4KICoJTXVzdCBiZSBjYWxsZWQgZnJvbSBwcm9jZXNzIGNvbnRleHQuCiAqCiAqCVJldHVybnMgemVybyBvbiBzdWNjZXNzIG9yICUtRU5PRU5UIG9uIGZhaWx1cmUuCiAqLwppbnQgc3JjdV9ub3RpZmllcl9jaGFpbl91bnJlZ2lzdGVyKHN0cnVjdCBzcmN1X25vdGlmaWVyX2hlYWQgKm5oLAoJCXN0cnVjdCBub3RpZmllcl9ibG9jayAqbikKewoJaW50IHJldDsKCgkvKgoJICogVGhpcyBjb2RlIGdldHMgdXNlZCBkdXJpbmcgYm9vdC11cCwgd2hlbiB0YXNrIHN3aXRjaGluZyBpcwoJICogbm90IHlldCB3b3JraW5nIGFuZCBpbnRlcnJ1cHRzIG11c3QgcmVtYWluIGRpc2FibGVkLiAgQXQKCSAqIHN1Y2ggdGltZXMgd2UgbXVzdCBub3QgY2FsbCBtdXRleF9sb2NrKCkuCgkgKi8KCWlmICh1bmxpa2VseShzeXN0ZW1fc3RhdGUgPT0gU1lTVEVNX0JPT1RJTkcpKQoJCXJldHVybiBub3RpZmllcl9jaGFpbl91bnJlZ2lzdGVyKCZuaC0+aGVhZCwgbik7CgoJbXV0ZXhfbG9jaygmbmgtPm11dGV4KTsKCXJldCA9IG5vdGlmaWVyX2NoYWluX3VucmVnaXN0ZXIoJm5oLT5oZWFkLCBuKTsKCW11dGV4X3VubG9jaygmbmgtPm11dGV4KTsKCXN5bmNocm9uaXplX3NyY3UoJm5oLT5zcmN1KTsKCXJldHVybiByZXQ7Cn0KCkVYUE9SVF9TWU1CT0xfR1BMKHNyY3Vfbm90aWZpZXJfY2hhaW5fdW5yZWdpc3Rlcik7CgovKioKICoJc3JjdV9ub3RpZmllcl9jYWxsX2NoYWluIC0gQ2FsbCBmdW5jdGlvbnMgaW4gYW4gU1JDVSBub3RpZmllciBjaGFpbgogKglAbmg6IFBvaW50ZXIgdG8gaGVhZCBvZiB0aGUgU1JDVSBub3RpZmllciBjaGFpbgogKglAdmFsOiBWYWx1ZSBwYXNzZWQgdW5tb2RpZmllZCB0byBub3RpZmllciBmdW5jdGlvbgogKglAdjogUG9pbnRlciBwYXNzZWQgdW5tb2RpZmllZCB0byBub3RpZmllciBmdW5jdGlvbgogKgogKglDYWxscyBlYWNoIGZ1bmN0aW9uIGluIGEgbm90aWZpZXIgY2hhaW4gaW4gdHVybi4gIFRoZSBmdW5jdGlvbnMKICoJcnVuIGluIGEgcHJvY2VzcyBjb250ZXh0LCBzbyB0aGV5IGFyZSBhbGxvd2VkIHRvIGJsb2NrLgogKgogKglJZiB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBub3RpZmllciBjYW4gYmUgYW5kJ2VkCiAqCXdpdGggJU5PVElGWV9TVE9QX01BU0sgdGhlbiBzcmN1X25vdGlmaWVyX2NhbGxfY2hhaW4oKQogKgl3aWxsIHJldHVybiBpbW1lZGlhdGVseSwgd2l0aCB0aGUgcmV0dXJuIHZhbHVlIG9mCiAqCXRoZSBub3RpZmllciBmdW5jdGlvbiB3aGljaCBoYWx0ZWQgZXhlY3V0aW9uLgogKglPdGhlcndpc2UgdGhlIHJldHVybiB2YWx1ZSBpcyB0aGUgcmV0dXJuIHZhbHVlCiAqCW9mIHRoZSBsYXN0IG5vdGlmaWVyIGZ1bmN0aW9uIGNhbGxlZC4KICovCgppbnQgc3JjdV9ub3RpZmllcl9jYWxsX2NoYWluKHN0cnVjdCBzcmN1X25vdGlmaWVyX2hlYWQgKm5oLAoJCXVuc2lnbmVkIGxvbmcgdmFsLCB2b2lkICp2KQp7CglpbnQgcmV0OwoJaW50IGlkeDsKCglpZHggPSBzcmN1X3JlYWRfbG9jaygmbmgtPnNyY3UpOwoJcmV0ID0gbm90aWZpZXJfY2FsbF9jaGFpbigmbmgtPmhlYWQsIHZhbCwgdik7CglzcmN1X3JlYWRfdW5sb2NrKCZuaC0+c3JjdSwgaWR4KTsKCXJldHVybiByZXQ7Cn0KCkVYUE9SVF9TWU1CT0xfR1BMKHNyY3Vfbm90aWZpZXJfY2FsbF9jaGFpbik7CgovKioKICoJc3JjdV9pbml0X25vdGlmaWVyX2hlYWQgLSBJbml0aWFsaXplIGFuIFNSQ1Ugbm90aWZpZXIgaGVhZAogKglAbmg6IFBvaW50ZXIgdG8gaGVhZCBvZiB0aGUgc3JjdSBub3RpZmllciBjaGFpbgogKgogKglVbmxpa2Ugb3RoZXIgc29ydHMgb2Ygbm90aWZpZXIgaGVhZHMsIFNSQ1Ugbm90aWZpZXIgaGVhZHMgcmVxdWlyZQogKglkeW5hbWljIGluaXRpYWxpemF0aW9uLiAgQmUgc3VyZSB0byBjYWxsIHRoaXMgcm91dGluZSBiZWZvcmUKICoJY2FsbGluZyBhbnkgb2YgdGhlIG90aGVyIFNSQ1Ugbm90aWZpZXIgcm91dGluZXMgZm9yIHRoaXMgaGVhZC4KICoKICoJSWYgYW4gU1JDVSBub3RpZmllciBoZWFkIGlzIGRlYWxsb2NhdGVkLCBpdCBtdXN0IGZpcnN0IGJlIGNsZWFuZWQKICoJdXAgYnkgY2FsbGluZyBzcmN1X2NsZWFudXBfbm90aWZpZXJfaGVhZCgpLiAgT3RoZXJ3aXNlIHRoZSBoZWFkJ3MKICoJcGVyLWNwdSBkYXRhICh1c2VkIGJ5IHRoZSBTUkNVIG1lY2hhbmlzbSkgd2lsbCBsZWFrLgogKi8KCnZvaWQgc3JjdV9pbml0X25vdGlmaWVyX2hlYWQoc3RydWN0IHNyY3Vfbm90aWZpZXJfaGVhZCAqbmgpCnsKCW11dGV4X2luaXQoJm5oLT5tdXRleCk7CglpZiAoaW5pdF9zcmN1X3N0cnVjdCgmbmgtPnNyY3UpIDwgMCkKCQlCVUcoKTsKCW5oLT5oZWFkID0gTlVMTDsKfQoKRVhQT1JUX1NZTUJPTF9HUEwoc3JjdV9pbml0X25vdGlmaWVyX2hlYWQpOwoKLyoqCiAqCXJlZ2lzdGVyX3JlYm9vdF9ub3RpZmllciAtIFJlZ2lzdGVyIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCBhdCByZWJvb3QgdGltZQogKglAbmI6IEluZm8gYWJvdXQgbm90aWZpZXIgZnVuY3Rpb24gdG8gYmUgY2FsbGVkCiAqCiAqCVJlZ2lzdGVycyBhIGZ1bmN0aW9uIHdpdGggdGhlIGxpc3Qgb2YgZnVuY3Rpb25zCiAqCXRvIGJlIGNhbGxlZCBhdCByZWJvb3QgdGltZS4KICoKICoJQ3VycmVudGx5IGFsd2F5cyByZXR1cm5zIHplcm8sIGFzIGJsb2NraW5nX25vdGlmaWVyX2NoYWluX3JlZ2lzdGVyKCkKICoJYWx3YXlzIHJldHVybnMgemVyby4KICovCiAKaW50IHJlZ2lzdGVyX3JlYm9vdF9ub3RpZmllcihzdHJ1Y3Qgbm90aWZpZXJfYmxvY2sgKiBuYikKewoJcmV0dXJuIGJsb2NraW5nX25vdGlmaWVyX2NoYWluX3JlZ2lzdGVyKCZyZWJvb3Rfbm90aWZpZXJfbGlzdCwgbmIpOwp9CgpFWFBPUlRfU1lNQk9MKHJlZ2lzdGVyX3JlYm9vdF9ub3RpZmllcik7CgovKioKICoJdW5yZWdpc3Rlcl9yZWJvb3Rfbm90aWZpZXIgLSBVbnJlZ2lzdGVyIHByZXZpb3VzbHkgcmVnaXN0ZXJlZCByZWJvb3Qgbm90aWZpZXIKICoJQG5iOiBIb29rIHRvIGJlIHVucmVnaXN0ZXJlZAogKgogKglVbnJlZ2lzdGVycyBhIHByZXZpb3VzbHkgcmVnaXN0ZXJlZCByZWJvb3QKICoJbm90aWZpZXIgZnVuY3Rpb24uCiAqCiAqCVJldHVybnMgemVybyBvbiBzdWNjZXNzLCBvciAlLUVOT0VOVCBvbiBmYWlsdXJlLgogKi8KIAppbnQgdW5yZWdpc3Rlcl9yZWJvb3Rfbm90aWZpZXIoc3RydWN0IG5vdGlmaWVyX2Jsb2NrICogbmIpCnsKCXJldHVybiBibG9ja2luZ19ub3RpZmllcl9jaGFpbl91bnJlZ2lzdGVyKCZyZWJvb3Rfbm90aWZpZXJfbGlzdCwgbmIpOwp9CgpFWFBPUlRfU1lNQk9MKHVucmVnaXN0ZXJfcmVib290X25vdGlmaWVyKTsKCnN0YXRpYyBpbnQgc2V0X29uZV9wcmlvKHN0cnVjdCB0YXNrX3N0cnVjdCAqcCwgaW50IG5pY2V2YWwsIGludCBlcnJvcikKewoJaW50IG5vX25pY2U7CgoJaWYgKHAtPnVpZCAhPSBjdXJyZW50LT5ldWlkICYmCgkJcC0+ZXVpZCAhPSBjdXJyZW50LT5ldWlkICYmICFjYXBhYmxlKENBUF9TWVNfTklDRSkpIHsKCQllcnJvciA9IC1FUEVSTTsKCQlnb3RvIG91dDsKCX0KCWlmIChuaWNldmFsIDwgdGFza19uaWNlKHApICYmICFjYW5fbmljZShwLCBuaWNldmFsKSkgewoJCWVycm9yID0gLUVBQ0NFUzsKCQlnb3RvIG91dDsKCX0KCW5vX25pY2UgPSBzZWN1cml0eV90YXNrX3NldG5pY2UocCwgbmljZXZhbCk7CglpZiAobm9fbmljZSkgewoJCWVycm9yID0gbm9fbmljZTsKCQlnb3RvIG91dDsKCX0KCWlmIChlcnJvciA9PSAtRVNSQ0gpCgkJZXJyb3IgPSAwOwoJc2V0X3VzZXJfbmljZShwLCBuaWNldmFsKTsKb3V0OgoJcmV0dXJuIGVycm9yOwp9Cgphc21saW5rYWdlIGxvbmcgc3lzX3NldHByaW9yaXR5KGludCB3aGljaCwgaW50IHdobywgaW50IG5pY2V2YWwpCnsKCXN0cnVjdCB0YXNrX3N0cnVjdCAqZywgKnA7CglzdHJ1Y3QgdXNlcl9zdHJ1Y3QgKnVzZXI7CglpbnQgZXJyb3IgPSAtRUlOVkFMOwoJc3RydWN0IHBpZCAqcGdycDsKCglpZiAod2hpY2ggPiAyIHx8IHdoaWNoIDwgMCkKCQlnb3RvIG91dDsKCgkvKiBub3JtYWxpemU6IGF2b2lkIHNpZ25lZCBkaXZpc2lvbiAocm91bmRpbmcgcHJvYmxlbXMpICovCgllcnJvciA9IC1FU1JDSDsKCWlmIChuaWNldmFsIDwgLTIwKQoJCW5pY2V2YWwgPSAtMjA7CglpZiAobmljZXZhbCA+IDE5KQoJCW5pY2V2YWwgPSAxOTsKCglyZWFkX2xvY2soJnRhc2tsaXN0X2xvY2spOwoJc3dpdGNoICh3aGljaCkgewoJCWNhc2UgUFJJT19QUk9DRVNTOgoJCQlpZiAod2hvKQoJCQkJcCA9IGZpbmRfdGFza19ieV9waWQod2hvKTsKCQkJZWxzZQoJCQkJcCA9IGN1cnJlbnQ7CgkJCWlmIChwKQoJCQkJZXJyb3IgPSBzZXRfb25lX3ByaW8ocCwgbmljZXZhbCwgZXJyb3IpOwoJCQlicmVhazsKCQljYXNlIFBSSU9fUEdSUDoKCQkJaWYgKHdobykKCQkJCXBncnAgPSBmaW5kX3BpZCh3aG8pOwoJCQllbHNlCgkJCQlwZ3JwID0gdGFza19wZ3JwKGN1cnJlbnQpOwoJCQlkb19lYWNoX3BpZF90YXNrKHBncnAsIFBJRFRZUEVfUEdJRCwgcCkgewoJCQkJZXJyb3IgPSBzZXRfb25lX3ByaW8ocCwgbmljZXZhbCwgZXJyb3IpOwoJCQl9IHdoaWxlX2VhY2hfcGlkX3Rhc2socGdycCwgUElEVFlQRV9QR0lELCBwKTsKCQkJYnJlYWs7CgkJY2FzZSBQUklPX1VTRVI6CgkJCXVzZXIgPSBjdXJyZW50LT51c2VyOwoJCQlpZiAoIXdobykKCQkJCXdobyA9IGN1cnJlbnQtPnVpZDsKCQkJZWxzZQoJCQkJaWYgKCh3aG8gIT0gY3VycmVudC0+dWlkKSAmJiAhKHVzZXIgPSBmaW5kX3VzZXIod2hvKSkpCgkJCQkJZ290byBvdXRfdW5sb2NrOwkvKiBObyBwcm9jZXNzZXMgZm9yIHRoaXMgdXNlciAqLwoKCQkJZG9fZWFjaF90aHJlYWQoZywgcCkKCQkJCWlmIChwLT51aWQgPT0gd2hvKQoJCQkJCWVycm9yID0gc2V0X29uZV9wcmlvKHAsIG5pY2V2YWwsIGVycm9yKTsKCQkJd2hpbGVfZWFjaF90aHJlYWQoZywgcCk7CgkJCWlmICh3aG8gIT0gY3VycmVudC0+dWlkKQoJCQkJZnJlZV91aWQodXNlcik7CQkvKiBGb3IgZmluZF91c2VyKCkgKi8KCQkJYnJlYWs7Cgl9Cm91dF91bmxvY2s6CglyZWFkX3VubG9jaygmdGFza2xpc3RfbG9jayk7Cm91dDoKCXJldHVybiBlcnJvcjsKfQoKLyoKICogVWdoLiBUbyBhdm9pZCBuZWdhdGl2ZSByZXR1cm4gdmFsdWVzLCAiZ2V0cHJpb3JpdHkoKSIgd2lsbAogKiBub3QgcmV0dXJuIHRoZSBub3JtYWwgbmljZS12YWx1ZSwgYnV0IGEgbmVnYXRlZCB2YWx1ZSB0aGF0CiAqIGhhcyBiZWVuIG9mZnNldCBieSAyMCAoaWUgaXQgcmV0dXJucyA0MC4uMSBpbnN0ZWFkIG9mIC0yMC4uMTkpCiAqIHRvIHN0YXkgY29tcGF0aWJsZS4KICovCmFzbWxpbmthZ2UgbG9uZyBzeXNfZ2V0cHJpb3JpdHkoaW50IHdoaWNoLCBpbnQgd2hvKQp7CglzdHJ1Y3QgdGFza19zdHJ1Y3QgKmcsICpwOwoJc3RydWN0IHVzZXJfc3RydWN0ICp1c2VyOwoJbG9uZyBuaWNldmFsLCByZXR2YWwgPSAtRVNSQ0g7CglzdHJ1Y3QgcGlkICpwZ3JwOwoKCWlmICh3aGljaCA+IDIgfHwgd2hpY2ggPCAwKQoJCXJldHVybiAtRUlOVkFMOwoKCXJlYWRfbG9jaygmdGFza2xpc3RfbG9jayk7Cglzd2l0Y2ggKHdoaWNoKSB7CgkJY2FzZSBQUklPX1BST0NFU1M6CgkJCWlmICh3aG8pCgkJCQlwID0gZmluZF90YXNrX2J5X3BpZCh3aG8pOwoJCQllbHNlCgkJCQlwID0gY3VycmVudDsKCQkJaWYgKHApIHsKCQkJCW5pY2V2YWwgPSAyMCAtIHRhc2tfbmljZShwKTsKCQkJCWlmIChuaWNldmFsID4gcmV0dmFsKQoJCQkJCXJldHZhbCA9IG5pY2V2YWw7CgkJCX0KCQkJYnJlYWs7CgkJY2FzZSBQUklPX1BHUlA6CgkJCWlmICh3aG8pCgkJCQlwZ3JwID0gZmluZF9waWQod2hvKTsKCQkJZWxzZQoJCQkJcGdycCA9IHRhc2tfcGdycChjdXJyZW50KTsKCQkJZG9fZWFjaF9waWRfdGFzayhwZ3JwLCBQSURUWVBFX1BHSUQsIHApIHsKCQkJCW5pY2V2YWwgPSAyMCAtIHRhc2tfbmljZShwKTsKCQkJCWlmIChuaWNldmFsID4gcmV0dmFsKQoJCQkJCXJldHZhbCA9IG5pY2V2YWw7CgkJCX0gd2hpbGVfZWFjaF9waWRfdGFzayhwZ3JwLCBQSURUWVBFX1BHSUQsIHApOwoJCQlicmVhazsKCQljYXNlIFBSSU9fVVNFUjoKCQkJdXNlciA9IGN1cnJlbnQtPnVzZXI7CgkJCWlmICghd2hvKQoJCQkJd2hvID0gY3VycmVudC0+dWlkOwoJCQllbHNlCgkJCQlpZiAoKHdobyAhPSBjdXJyZW50LT51aWQpICYmICEodXNlciA9IGZpbmRfdXNlcih3aG8pKSkKCQkJCQlnb3RvIG91dF91bmxvY2s7CS8qIE5vIHByb2Nlc3NlcyBmb3IgdGhpcyB1c2VyICovCgoJCQlkb19lYWNoX3RocmVhZChnLCBwKQoJCQkJaWYgKHAtPnVpZCA9PSB3aG8pIHsKCQkJCQluaWNldmFsID0gMjAgLSB0YXNrX25pY2UocCk7CgkJCQkJaWYgKG5pY2V2YWwgPiByZXR2YWwpCgkJCQkJCXJldHZhbCA9IG5pY2V2YWw7CgkJCQl9CgkJCXdoaWxlX2VhY2hfdGhyZWFkKGcsIHApOwoJCQlpZiAod2hvICE9IGN1cnJlbnQtPnVpZCkKCQkJCWZyZWVfdWlkKHVzZXIpOwkJLyogZm9yIGZpbmRfdXNlcigpICovCgkJCWJyZWFrOwoJfQpvdXRfdW5sb2NrOgoJcmVhZF91bmxvY2soJnRhc2tsaXN0X2xvY2spOwoKCXJldHVybiByZXR2YWw7Cn0KCi8qKgogKgllbWVyZ2VuY3lfcmVzdGFydCAtIHJlYm9vdCB0aGUgc3lzdGVtCiAqCiAqCVdpdGhvdXQgc2h1dHRpbmcgZG93biBhbnkgaGFyZHdhcmUgb3IgdGFraW5nIGFueSBsb2NrcwogKglyZWJvb3QgdGhlIHN5c3RlbS4gIFRoaXMgaXMgY2FsbGVkIHdoZW4gd2Uga25vdyB3ZSBhcmUgaW4KICoJdHJvdWJsZSBzbyB0aGlzIGlzIG91ciBiZXN0IGVmZm9ydCB0byByZWJvb3QuICBUaGlzIGlzCiAqCXNhZmUgdG8gY2FsbCBpbiBpbnRlcnJ1cHQgY29udGV4dC4KICovCnZvaWQgZW1lcmdlbmN5X3Jlc3RhcnQodm9pZCkKewoJbWFjaGluZV9lbWVyZ2VuY3lfcmVzdGFydCgpOwp9CkVYUE9SVF9TWU1CT0xfR1BMKGVtZXJnZW5jeV9yZXN0YXJ0KTsKCnN0YXRpYyB2b2lkIGtlcm5lbF9yZXN0YXJ0X3ByZXBhcmUoY2hhciAqY21kKQp7CglibG9ja2luZ19ub3RpZmllcl9jYWxsX2NoYWluKCZyZWJvb3Rfbm90aWZpZXJfbGlzdCwgU1lTX1JFU1RBUlQsIGNtZCk7CglzeXN0ZW1fc3RhdGUgPSBTWVNURU1fUkVTVEFSVDsKCWRldmljZV9zaHV0ZG93bigpOwp9CgovKioKICoJa2VybmVsX3Jlc3RhcnQgLSByZWJvb3QgdGhlIHN5c3RlbQogKglAY21kOiBwb2ludGVyIHRvIGJ1ZmZlciBjb250YWluaW5nIGNvbW1hbmQgdG8gZXhlY3V0ZSBmb3IgcmVzdGFydAogKgkJb3IgJU5VTEwKICoKICoJU2h1dGRvd24gZXZlcnl0aGluZyBhbmQgcGVyZm9ybSBhIGNsZWFuIHJlYm9vdC4KICoJVGhpcyBpcyBub3Qgc2FmZSB0byBjYWxsIGluIGludGVycnVwdCBjb250ZXh0LgogKi8Kdm9pZCBrZXJuZWxfcmVzdGFydChjaGFyICpjbWQpCnsKCWtlcm5lbF9yZXN0YXJ0X3ByZXBhcmUoY21kKTsKCWlmICghY21kKQoJCXByaW50ayhLRVJOX0VNRVJHICJSZXN0YXJ0aW5nIHN5c3RlbS5cbiIpOwoJZWxzZQoJCXByaW50ayhLRVJOX0VNRVJHICJSZXN0YXJ0aW5nIHN5c3RlbSB3aXRoIGNvbW1hbmQgJyVzJy5cbiIsIGNtZCk7CgltYWNoaW5lX3Jlc3RhcnQoY21kKTsKfQpFWFBPUlRfU1lNQk9MX0dQTChrZXJuZWxfcmVzdGFydCk7CgovKioKICoJa2VybmVsX2tleGVjIC0gcmVib290IHRoZSBzeXN0ZW0KICoKICoJTW92ZSBpbnRvIHBsYWNlIGFuZCBzdGFydCBleGVjdXRpbmcgYSBwcmVsb2FkZWQgc3RhbmRhbG9uZQogKglleGVjdXRhYmxlLiAgSWYgbm90aGluZyB3YXMgcHJlbG9hZGVkIHJldHVybiBhbiBlcnJvci4KICovCnN0YXRpYyB2b2lkIGtlcm5lbF9rZXhlYyh2b2lkKQp7CiNpZmRlZiBDT05GSUdfS0VYRUMKCXN0cnVjdCBraW1hZ2UgKmltYWdlOwoJaW1hZ2UgPSB4Y2hnKCZrZXhlY19pbWFnZSwgTlVMTCk7CglpZiAoIWltYWdlKQoJCXJldHVybjsKCWtlcm5lbF9yZXN0YXJ0X3ByZXBhcmUoTlVMTCk7CglwcmludGsoS0VSTl9FTUVSRyAiU3RhcnRpbmcgbmV3IGtlcm5lbFxuIik7CgltYWNoaW5lX3NodXRkb3duKCk7CgltYWNoaW5lX2tleGVjKGltYWdlKTsKI2VuZGlmCn0KCnZvaWQga2VybmVsX3NodXRkb3duX3ByZXBhcmUoZW51bSBzeXN0ZW1fc3RhdGVzIHN0YXRlKQp7CglibG9ja2luZ19ub3RpZmllcl9jYWxsX2NoYWluKCZyZWJvb3Rfbm90aWZpZXJfbGlzdCwKCQkoc3RhdGUgPT0gU1lTVEVNX0hBTFQpP1NZU19IQUxUOlNZU19QT1dFUl9PRkYsIE5VTEwpOwoJc3lzdGVtX3N0YXRlID0gc3RhdGU7CglkZXZpY2Vfc2h1dGRvd24oKTsKfQovKioKICoJa2VybmVsX2hhbHQgLSBoYWx0IHRoZSBzeXN0ZW0KICoKICoJU2h1dGRvd24gZXZlcnl0aGluZyBhbmQgcGVyZm9ybSBhIGNsZWFuIHN5c3RlbSBoYWx0LgogKi8Kdm9pZCBrZXJuZWxfaGFsdCh2b2lkKQp7CglrZXJuZWxfc2h1dGRvd25fcHJlcGFyZShTWVNURU1fSEFMVCk7CglwcmludGsoS0VSTl9FTUVSRyAiU3lzdGVtIGhhbHRlZC5cbiIpOwoJbWFjaGluZV9oYWx0KCk7Cn0KCkVYUE9SVF9TWU1CT0xfR1BMKGtlcm5lbF9oYWx0KTsKCi8qKgogKglrZXJuZWxfcG93ZXJfb2ZmIC0gcG93ZXJfb2ZmIHRoZSBzeXN0ZW0KICoKICoJU2h1dGRvd24gZXZlcnl0aGluZyBhbmQgcGVyZm9ybSBhIGNsZWFuIHN5c3RlbSBwb3dlcl9vZmYuCiAqLwp2b2lkIGtlcm5lbF9wb3dlcl9vZmYodm9pZCkKewoJa2VybmVsX3NodXRkb3duX3ByZXBhcmUoU1lTVEVNX1BPV0VSX09GRik7CglwcmludGsoS0VSTl9FTUVSRyAiUG93ZXIgZG93bi5cbiIpOwoJbWFjaGluZV9wb3dlcl9vZmYoKTsKfQpFWFBPUlRfU1lNQk9MX0dQTChrZXJuZWxfcG93ZXJfb2ZmKTsKLyoKICogUmVib290IHN5c3RlbSBjYWxsOiBmb3Igb2J2aW91cyByZWFzb25zIG9ubHkgcm9vdCBtYXkgY2FsbCBpdCwKICogYW5kIGV2ZW4gcm9vdCBuZWVkcyB0byBzZXQgdXAgc29tZSBtYWdpYyBudW1iZXJzIGluIHRoZSByZWdpc3RlcnMKICogc28gdGhhdCBzb21lIG1pc3Rha2Ugd29uJ3QgbWFrZSB0aGlzIHJlYm9vdCB0aGUgd2hvbGUgbWFjaGluZS4KICogWW91IGNhbiBhbHNvIHNldCB0aGUgbWVhbmluZyBvZiB0aGUgY3RybC1hbHQtZGVsLWtleSBoZXJlLgogKgogKiByZWJvb3QgZG9lc24ndCBzeW5jOiBkbyB0aGF0IHlvdXJzZWxmIGJlZm9yZSBjYWxsaW5nIHRoaXMuCiAqLwphc21saW5rYWdlIGxvbmcgc3lzX3JlYm9vdChpbnQgbWFnaWMxLCBpbnQgbWFnaWMyLCB1bnNpZ25lZCBpbnQgY21kLCB2b2lkIF9fdXNlciAqIGFyZykKewoJY2hhciBidWZmZXJbMjU2XTsKCgkvKiBXZSBvbmx5IHRydXN0IHRoZSBzdXBlcnVzZXIgd2l0aCByZWJvb3RpbmcgdGhlIHN5c3RlbS4gKi8KCWlmICghY2FwYWJsZShDQVBfU1lTX0JPT1QpKQoJCXJldHVybiAtRVBFUk07CgoJLyogRm9yIHNhZmV0eSwgd2UgcmVxdWlyZSAibWFnaWMiIGFyZ3VtZW50cy4gKi8KCWlmIChtYWdpYzEgIT0gTElOVVhfUkVCT09UX01BR0lDMSB8fAoJICAgIChtYWdpYzIgIT0gTElOVVhfUkVCT09UX01BR0lDMiAmJgoJICAgICAgICAgICAgICAgIG1hZ2ljMiAhPSBMSU5VWF9SRUJPT1RfTUFHSUMyQSAmJgoJCQltYWdpYzIgIT0gTElOVVhfUkVCT09UX01BR0lDMkIgJiYKCSAgICAgICAgICAgICAgICBtYWdpYzIgIT0gTElOVVhfUkVCT09UX01BR0lDMkMpKQoJCXJldHVybiAtRUlOVkFMOwoKCS8qIEluc3RlYWQgb2YgdHJ5aW5nIHRvIG1ha2UgdGhlIHBvd2VyX29mZiBjb2RlIGxvb2sgbGlrZQoJICogaGFsdCB3aGVuIHBtX3Bvd2VyX29mZiBpcyBub3Qgc2V0IGRvIGl0IHRoZSBlYXN5IHdheS4KCSAqLwoJaWYgKChjbWQgPT0gTElOVVhfUkVCT09UX0NNRF9QT1dFUl9PRkYpICYmICFwbV9wb3dlcl9vZmYpCgkJY21kID0gTElOVVhfUkVCT09UX0NNRF9IQUxUOwoKCWxvY2tfa2VybmVsKCk7Cglzd2l0Y2ggKGNtZCkgewoJY2FzZSBMSU5VWF9SRUJPT1RfQ01EX1JFU1RBUlQ6CgkJa2VybmVsX3Jlc3RhcnQoTlVMTCk7CgkJYnJlYWs7CgoJY2FzZSBMSU5VWF9SRUJPT1RfQ01EX0NBRF9PTjoKCQlDX0FfRCA9IDE7CgkJYnJlYWs7CgoJY2FzZSBMSU5VWF9SRUJPT1RfQ01EX0NBRF9PRkY6CgkJQ19BX0QgPSAwOwoJCWJyZWFrOwoKCWNhc2UgTElOVVhfUkVCT09UX0NNRF9IQUxUOgoJCWtlcm5lbF9oYWx0KCk7CgkJdW5sb2NrX2tlcm5lbCgpOwoJCWRvX2V4aXQoMCk7CgkJYnJlYWs7CgoJY2FzZSBMSU5VWF9SRUJPT1RfQ01EX1BPV0VSX09GRjoKCQlrZXJuZWxfcG93ZXJfb2ZmKCk7CgkJdW5sb2NrX2tlcm5lbCgpOwoJCWRvX2V4aXQoMCk7CgkJYnJlYWs7CgoJY2FzZSBMSU5VWF9SRUJPT1RfQ01EX1JFU1RBUlQyOgoJCWlmIChzdHJuY3B5X2Zyb21fdXNlcigmYnVmZmVyWzBdLCBhcmcsIHNpemVvZihidWZmZXIpIC0gMSkgPCAwKSB7CgkJCXVubG9ja19rZXJuZWwoKTsKCQkJcmV0dXJuIC1FRkFVTFQ7CgkJfQoJCWJ1ZmZlcltzaXplb2YoYnVmZmVyKSAtIDFdID0gJ1wwJzsKCgkJa2VybmVsX3Jlc3RhcnQoYnVmZmVyKTsKCQlicmVhazsKCgljYXNlIExJTlVYX1JFQk9PVF9DTURfS0VYRUM6CgkJa2VybmVsX2tleGVjKCk7CgkJdW5sb2NrX2tlcm5lbCgpOwoJCXJldHVybiAtRUlOVkFMOwoKI2lmZGVmIENPTkZJR19TT0ZUV0FSRV9TVVNQRU5ECgljYXNlIExJTlVYX1JFQk9PVF9DTURfU1dfU1VTUEVORDoKCQl7CgkJCWludCByZXQgPSBzb2Z0d2FyZV9zdXNwZW5kKCk7CgkJCXVubG9ja19rZXJuZWwoKTsKCQkJcmV0dXJuIHJldDsKCQl9CiNlbmRpZgoKCWRlZmF1bHQ6CgkJdW5sb2NrX2tlcm5lbCgpOwoJCXJldHVybiAtRUlOVkFMOwoJfQoJdW5sb2NrX2tlcm5lbCgpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIGRlZmVycmVkX2NhZChzdHJ1Y3Qgd29ya19zdHJ1Y3QgKmR1bW15KQp7CglrZXJuZWxfcmVzdGFydChOVUxMKTsKfQoKLyoKICogVGhpcyBmdW5jdGlvbiBnZXRzIGNhbGxlZCBieSBjdHJsLWFsdC1kZWwgLSBpZSB0aGUga2V5Ym9hcmQgaW50ZXJydXB0LgogKiBBcyBpdCdzIGNhbGxlZCB3aXRoaW4gYW4gaW50ZXJydXB0LCBpdCBtYXkgTk9UIHN5bmM6IHRoZSBvbmx5IGNob2ljZQogKiBpcyB3aGV0aGVyIHRvIHJlYm9vdCBhdCBvbmNlLCBvciBqdXN0IGlnbm9yZSB0aGUgY3RybC1hbHQtZGVsLgogKi8Kdm9pZCBjdHJsX2FsdF9kZWwodm9pZCkKewoJc3RhdGljIERFQ0xBUkVfV09SSyhjYWRfd29yaywgZGVmZXJyZWRfY2FkKTsKCglpZiAoQ19BX0QpCgkJc2NoZWR1bGVfd29yaygmY2FkX3dvcmspOwoJZWxzZQoJCWtpbGxfY2FkX3BpZChTSUdJTlQsIDEpOwp9CgkKLyoKICogVW5wcml2aWxlZ2VkIHVzZXJzIG1heSBjaGFuZ2UgdGhlIHJlYWwgZ2lkIHRvIHRoZSBlZmZlY3RpdmUgZ2lkCiAqIG9yIHZpY2UgdmVyc2EuICAoQlNELXN0eWxlKQogKgogKiBJZiB5b3Ugc2V0IHRoZSByZWFsIGdpZCBhdCBhbGwsIG9yIHNldCB0aGUgZWZmZWN0aXZlIGdpZCB0byBhIHZhbHVlIG5vdAogKiBlcXVhbCB0byB0aGUgcmVhbCBnaWQsIHRoZW4gdGhlIHNhdmVkIGdpZCBpcyBzZXQgdG8gdGhlIG5ldyBlZmZlY3RpdmUgZ2lkLgogKgogKiBUaGlzIG1ha2VzIGl0IHBvc3NpYmxlIGZvciBhIHNldGdpZCBwcm9ncmFtIHRvIGNvbXBsZXRlbHkgZHJvcCBpdHMKICogcHJpdmlsZWdlcywgd2hpY2ggaXMgb2Z0ZW4gYSB1c2VmdWwgYXNzZXJ0aW9uIHRvIG1ha2Ugd2hlbiB5b3UgYXJlIGRvaW5nCiAqIGEgc2VjdXJpdHkgYXVkaXQgb3ZlciBhIHByb2dyYW0uCiAqCiAqIFRoZSBnZW5lcmFsIGlkZWEgaXMgdGhhdCBhIHByb2dyYW0gd2hpY2ggdXNlcyBqdXN0IHNldHJlZ2lkKCkgd2lsbCBiZQogKiAxMDAlIGNvbXBhdGlibGUgd2l0aCBCU0QuICBBIHByb2dyYW0gd2hpY2ggdXNlcyBqdXN0IHNldGdpZCgpIHdpbGwgYmUKICogMTAwJSBjb21wYXRpYmxlIHdpdGggUE9TSVggd2l0aCBzYXZlZCBJRHMuIAogKgogKiBTTVA6IFRoZXJlIGFyZSBub3QgcmFjZXMsIHRoZSBHSURzIGFyZSBjaGVja2VkIG9ubHkgYnkgZmlsZXN5c3RlbQogKiAgICAgIG9wZXJhdGlvbnMgKGFzIGZhciBhcyBzZW1hbnRpYyBwcmVzZXJ2YXRpb24gaXMgY29uY2VybmVkKS4KICovCmFzbWxpbmthZ2UgbG9uZyBzeXNfc2V0cmVnaWQoZ2lkX3QgcmdpZCwgZ2lkX3QgZWdpZCkKewoJaW50IG9sZF9yZ2lkID0gY3VycmVudC0+Z2lkOwoJaW50IG9sZF9lZ2lkID0gY3VycmVudC0+ZWdpZDsKCWludCBuZXdfcmdpZCA9IG9sZF9yZ2lkOwoJaW50IG5ld19lZ2lkID0gb2xkX2VnaWQ7CglpbnQgcmV0dmFsOwoKCXJldHZhbCA9IHNlY3VyaXR5X3Rhc2tfc2V0Z2lkKHJnaWQsIGVnaWQsIChnaWRfdCktMSwgTFNNX1NFVElEX1JFKTsKCWlmIChyZXR2YWwpCgkJcmV0dXJuIHJldHZhbDsKCglpZiAocmdpZCAhPSAoZ2lkX3QpIC0xKSB7CgkJaWYgKChvbGRfcmdpZCA9PSByZ2lkKSB8fAoJCSAgICAoY3VycmVudC0+ZWdpZD09cmdpZCkgfHwKCQkgICAgY2FwYWJsZShDQVBfU0VUR0lEKSkKCQkJbmV3X3JnaWQgPSByZ2lkOwoJCWVsc2UKCQkJcmV0dXJuIC1FUEVSTTsKCX0KCWlmIChlZ2lkICE9IChnaWRfdCkgLTEpIHsKCQlpZiAoKG9sZF9yZ2lkID09IGVnaWQpIHx8CgkJICAgIChjdXJyZW50LT5lZ2lkID09IGVnaWQpIHx8CgkJICAgIChjdXJyZW50LT5zZ2lkID09IGVnaWQpIHx8CgkJICAgIGNhcGFibGUoQ0FQX1NFVEdJRCkpCgkJCW5ld19lZ2lkID0gZWdpZDsKCQllbHNlCgkJCXJldHVybiAtRVBFUk07Cgl9CglpZiAobmV3X2VnaWQgIT0gb2xkX2VnaWQpIHsKCQljdXJyZW50LT5tbS0+ZHVtcGFibGUgPSBzdWlkX2R1bXBhYmxlOwoJCXNtcF93bWIoKTsKCX0KCWlmIChyZ2lkICE9IChnaWRfdCkgLTEgfHwKCSAgICAoZWdpZCAhPSAoZ2lkX3QpIC0xICYmIGVnaWQgIT0gb2xkX3JnaWQpKQoJCWN1cnJlbnQtPnNnaWQgPSBuZXdfZWdpZDsKCWN1cnJlbnQtPmZzZ2lkID0gbmV3X2VnaWQ7CgljdXJyZW50LT5lZ2lkID0gbmV3X2VnaWQ7CgljdXJyZW50LT5naWQgPSBuZXdfcmdpZDsKCWtleV9mc2dpZF9jaGFuZ2VkKGN1cnJlbnQpOwoJcHJvY19pZF9jb25uZWN0b3IoY3VycmVudCwgUFJPQ19FVkVOVF9HSUQpOwoJcmV0dXJuIDA7Cn0KCi8qCiAqIHNldGdpZCgpIGlzIGltcGxlbWVudGVkIGxpa2UgU3lzViB3LyBTQVZFRF9JRFMgCiAqCiAqIFNNUDogU2FtZSBpbXBsaWNpdCByYWNlcyBhcyBhYm92ZS4KICovCmFzbWxpbmthZ2UgbG9uZyBzeXNfc2V0Z2lkKGdpZF90IGdpZCkKewoJaW50IG9sZF9lZ2lkID0gY3VycmVudC0+ZWdpZDsKCWludCByZXR2YWw7CgoJcmV0dmFsID0gc2VjdXJpdHlfdGFza19zZXRnaWQoZ2lkLCAoZ2lkX3QpLTEsIChnaWRfdCktMSwgTFNNX1NFVElEX0lEKTsKCWlmIChyZXR2YWwpCgkJcmV0dXJuIHJldHZhbDsKCglpZiAoY2FwYWJsZShDQVBfU0VUR0lEKSkgewoJCWlmIChvbGRfZWdpZCAhPSBnaWQpIHsKCQkJY3VycmVudC0+bW0tPmR1bXBhYmxlID0gc3VpZF9kdW1wYWJsZTsKCQkJc21wX3dtYigpOwoJCX0KCQljdXJyZW50LT5naWQgPSBjdXJyZW50LT5lZ2lkID0gY3VycmVudC0+c2dpZCA9IGN1cnJlbnQtPmZzZ2lkID0gZ2lkOwoJfSBlbHNlIGlmICgoZ2lkID09IGN1cnJlbnQtPmdpZCkgfHwgKGdpZCA9PSBjdXJyZW50LT5zZ2lkKSkgewoJCWlmIChvbGRfZWdpZCAhPSBnaWQpIHsKCQkJY3VycmVudC0+bW0tPmR1bXBhYmxlID0gc3VpZF9kdW1wYWJsZTsKCQkJc21wX3dtYigpOwoJCX0KCQljdXJyZW50LT5lZ2lkID0gY3VycmVudC0+ZnNnaWQgPSBnaWQ7Cgl9CgllbHNlCgkJcmV0dXJuIC1FUEVSTTsKCglrZXlfZnNnaWRfY2hhbmdlZChjdXJyZW50KTsKCXByb2NfaWRfY29ubmVjdG9yKGN1cnJlbnQsIFBST0NfRVZFTlRfR0lEKTsKCXJldHVybiAwOwp9CiAgCnN0YXRpYyBpbnQgc2V0X3VzZXIodWlkX3QgbmV3X3J1aWQsIGludCBkdW1wY2xlYXIpCnsKCXN0cnVjdCB1c2VyX3N0cnVjdCAqbmV3X3VzZXI7CgoJbmV3X3VzZXIgPSBhbGxvY191aWQobmV3X3J1aWQpOwoJaWYgKCFuZXdfdXNlcikKCQlyZXR1cm4gLUVBR0FJTjsKCglpZiAoYXRvbWljX3JlYWQoJm5ld191c2VyLT5wcm9jZXNzZXMpID49CgkJCQljdXJyZW50LT5zaWduYWwtPnJsaW1bUkxJTUlUX05QUk9DXS5ybGltX2N1ciAmJgoJCQluZXdfdXNlciAhPSAmcm9vdF91c2VyKSB7CgkJZnJlZV91aWQobmV3X3VzZXIpOwoJCXJldHVybiAtRUFHQUlOOwoJfQoKCXN3aXRjaF91aWQobmV3X3VzZXIpOwoKCWlmIChkdW1wY2xlYXIpIHsKCQljdXJyZW50LT5tbS0+ZHVtcGFibGUgPSBzdWlkX2R1bXBhYmxlOwoJCXNtcF93bWIoKTsKCX0KCWN1cnJlbnQtPnVpZCA9IG5ld19ydWlkOwoJcmV0dXJuIDA7Cn0KCi8qCiAqIFVucHJpdmlsZWdlZCB1c2VycyBtYXkgY2hhbmdlIHRoZSByZWFsIHVpZCB0byB0aGUgZWZmZWN0aXZlIHVpZAogKiBvciB2aWNlIHZlcnNhLiAgKEJTRC1zdHlsZSkKICoKICogSWYgeW91IHNldCB0aGUgcmVhbCB1aWQgYXQgYWxsLCBvciBzZXQgdGhlIGVmZmVjdGl2ZSB1aWQgdG8gYSB2YWx1ZSBub3QKICogZXF1YWwgdG8gdGhlIHJlYWwgdWlkLCB0aGVuIHRoZSBzYXZlZCB1aWQgaXMgc2V0IHRvIHRoZSBuZXcgZWZmZWN0aXZlIHVpZC4KICoKICogVGhpcyBtYWtlcyBpdCBwb3NzaWJsZSBmb3IgYSBzZXR1aWQgcHJvZ3JhbSB0byBjb21wbGV0ZWx5IGRyb3AgaXRzCiAqIHByaXZpbGVnZXMsIHdoaWNoIGlzIG9mdGVuIGEgdXNlZnVsIGFzc2VydGlvbiB0byBtYWtlIHdoZW4geW91IGFyZSBkb2luZwogKiBhIHNlY3VyaXR5IGF1ZGl0IG92ZXIgYSBwcm9ncmFtLgogKgogKiBUaGUgZ2VuZXJhbCBpZGVhIGlzIHRoYXQgYSBwcm9ncmFtIHdoaWNoIHVzZXMganVzdCBzZXRyZXVpZCgpIHdpbGwgYmUKICogMTAwJSBjb21wYXRpYmxlIHdpdGggQlNELiAgQSBwcm9ncmFtIHdoaWNoIHVzZXMganVzdCBzZXR1aWQoKSB3aWxsIGJlCiAqIDEwMCUgY29tcGF0aWJsZSB3aXRoIFBPU0lYIHdpdGggc2F2ZWQgSURzLiAKICovCmFzbWxpbmthZ2UgbG9uZyBzeXNfc2V0cmV1aWQodWlkX3QgcnVpZCwgdWlkX3QgZXVpZCkKewoJaW50IG9sZF9ydWlkLCBvbGRfZXVpZCwgb2xkX3N1aWQsIG5ld19ydWlkLCBuZXdfZXVpZDsKCWludCByZXR2YWw7CgoJcmV0dmFsID0gc2VjdXJpdHlfdGFza19zZXR1aWQocnVpZCwgZXVpZCwgKHVpZF90KS0xLCBMU01fU0VUSURfUkUpOwoJaWYgKHJldHZhbCkKCQlyZXR1cm4gcmV0dmFsOwoKCW5ld19ydWlkID0gb2xkX3J1aWQgPSBjdXJyZW50LT51aWQ7CgluZXdfZXVpZCA9IG9sZF9ldWlkID0gY3VycmVudC0+ZXVpZDsKCW9sZF9zdWlkID0gY3VycmVudC0+c3VpZDsKCglpZiAocnVpZCAhPSAodWlkX3QpIC0xKSB7CgkJbmV3X3J1aWQgPSBydWlkOwoJCWlmICgob2xkX3J1aWQgIT0gcnVpZCkgJiYKCQkgICAgKGN1cnJlbnQtPmV1aWQgIT0gcnVpZCkgJiYKCQkgICAgIWNhcGFibGUoQ0FQX1NFVFVJRCkpCgkJCXJldHVybiAtRVBFUk07Cgl9CgoJaWYgKGV1aWQgIT0gKHVpZF90KSAtMSkgewoJCW5ld19ldWlkID0gZXVpZDsKCQlpZiAoKG9sZF9ydWlkICE9IGV1aWQpICYmCgkJICAgIChjdXJyZW50LT5ldWlkICE9IGV1aWQpICYmCgkJICAgIChjdXJyZW50LT5zdWlkICE9IGV1aWQpICYmCgkJICAgICFjYXBhYmxlKENBUF9TRVRVSUQpKQoJCQlyZXR1cm4gLUVQRVJNOwoJfQoKCWlmIChuZXdfcnVpZCAhPSBvbGRfcnVpZCAmJiBzZXRfdXNlcihuZXdfcnVpZCwgbmV3X2V1aWQgIT0gb2xkX2V1aWQpIDwgMCkKCQlyZXR1cm4gLUVBR0FJTjsKCglpZiAobmV3X2V1aWQgIT0gb2xkX2V1aWQpIHsKCQljdXJyZW50LT5tbS0+ZHVtcGFibGUgPSBzdWlkX2R1bXBhYmxlOwoJCXNtcF93bWIoKTsKCX0KCWN1cnJlbnQtPmZzdWlkID0gY3VycmVudC0+ZXVpZCA9IG5ld19ldWlkOwoJaWYgKHJ1aWQgIT0gKHVpZF90KSAtMSB8fAoJICAgIChldWlkICE9ICh1aWRfdCkgLTEgJiYgZXVpZCAhPSBvbGRfcnVpZCkpCgkJY3VycmVudC0+c3VpZCA9IGN1cnJlbnQtPmV1aWQ7CgljdXJyZW50LT5mc3VpZCA9IGN1cnJlbnQtPmV1aWQ7CgoJa2V5X2ZzdWlkX2NoYW5nZWQoY3VycmVudCk7Cglwcm9jX2lkX2Nvbm5lY3RvcihjdXJyZW50LCBQUk9DX0VWRU5UX1VJRCk7CgoJcmV0dXJuIHNlY3VyaXR5X3Rhc2tfcG9zdF9zZXR1aWQob2xkX3J1aWQsIG9sZF9ldWlkLCBvbGRfc3VpZCwgTFNNX1NFVElEX1JFKTsKfQoKCgkJCi8qCiAqIHNldHVpZCgpIGlzIGltcGxlbWVudGVkIGxpa2UgU3lzViB3aXRoIFNBVkVEX0lEUyAKICogCiAqIE5vdGUgdGhhdCBTQVZFRF9JRCdzIGlzIGRlZmljaWVudCBpbiB0aGF0IGEgc2V0dWlkIHJvb3QgcHJvZ3JhbQogKiBsaWtlIHNlbmRtYWlsLCBmb3IgZXhhbXBsZSwgY2Fubm90IHNldCBpdHMgdWlkIHRvIGJlIGEgbm9ybWFsIAogKiB1c2VyIGFuZCB0aGVuIHN3aXRjaCBiYWNrLCBiZWNhdXNlIGlmIHlvdSdyZSByb290LCBzZXR1aWQoKSBzZXRzCiAqIHRoZSBzYXZlZCB1aWQgdG9vLiAgSWYgeW91IGRvbid0IGxpa2UgdGhpcywgYmxhbWUgdGhlIGJyaWdodCBwZW9wbGUKICogaW4gdGhlIFBPU0lYIGNvbW1pdHRlZSBhbmQvb3IgVVNHLiAgTm90ZSB0aGF0IHRoZSBCU0Qtc3R5bGUgc2V0cmV1aWQoKQogKiB3aWxsIGFsbG93IGEgcm9vdCBwcm9ncmFtIHRvIHRlbXBvcmFyaWx5IGRyb3AgcHJpdmlsZWdlcyBhbmQgYmUgYWJsZSB0bwogKiByZWdhaW4gdGhlbSBieSBzd2FwcGluZyB0aGUgcmVhbCBhbmQgZWZmZWN0aXZlIHVpZC4gIAogKi8KYXNtbGlua2FnZSBsb25nIHN5c19zZXR1aWQodWlkX3QgdWlkKQp7CglpbnQgb2xkX2V1aWQgPSBjdXJyZW50LT5ldWlkOwoJaW50IG9sZF9ydWlkLCBvbGRfc3VpZCwgbmV3X3N1aWQ7CglpbnQgcmV0dmFsOwoKCXJldHZhbCA9IHNlY3VyaXR5X3Rhc2tfc2V0dWlkKHVpZCwgKHVpZF90KS0xLCAodWlkX3QpLTEsIExTTV9TRVRJRF9JRCk7CglpZiAocmV0dmFsKQoJCXJldHVybiByZXR2YWw7CgoJb2xkX3J1aWQgPSBjdXJyZW50LT51aWQ7CglvbGRfc3VpZCA9IGN1cnJlbnQtPnN1aWQ7CgluZXdfc3VpZCA9IG9sZF9zdWlkOwoJCglpZiAoY2FwYWJsZShDQVBfU0VUVUlEKSkgewoJCWlmICh1aWQgIT0gb2xkX3J1aWQgJiYgc2V0X3VzZXIodWlkLCBvbGRfZXVpZCAhPSB1aWQpIDwgMCkKCQkJcmV0dXJuIC1FQUdBSU47CgkJbmV3X3N1aWQgPSB1aWQ7Cgl9IGVsc2UgaWYgKCh1aWQgIT0gY3VycmVudC0+dWlkKSAmJiAodWlkICE9IG5ld19zdWlkKSkKCQlyZXR1cm4gLUVQRVJNOwoKCWlmIChvbGRfZXVpZCAhPSB1aWQpIHsKCQljdXJyZW50LT5tbS0+ZHVtcGFibGUgPSBzdWlkX2R1bXBhYmxlOwoJCXNtcF93bWIoKTsKCX0KCWN1cnJlbnQtPmZzdWlkID0gY3VycmVudC0+ZXVpZCA9IHVpZDsKCWN1cnJlbnQtPnN1aWQgPSBuZXdfc3VpZDsKCglrZXlfZnN1aWRfY2hhbmdlZChjdXJyZW50KTsKCXByb2NfaWRfY29ubmVjdG9yKGN1cnJlbnQsIFBST0NfRVZFTlRfVUlEKTsKCglyZXR1cm4gc2VjdXJpdHlfdGFza19wb3N0X3NldHVpZChvbGRfcnVpZCwgb2xkX2V1aWQsIG9sZF9zdWlkLCBMU01fU0VUSURfSUQpOwp9CgoKLyoKICogVGhpcyBmdW5jdGlvbiBpbXBsZW1lbnRzIGEgZ2VuZXJpYyBhYmlsaXR5IHRvIHVwZGF0ZSBydWlkLCBldWlkLAogKiBhbmQgc3VpZC4gIFRoaXMgYWxsb3dzIHlvdSB0byBpbXBsZW1lbnQgdGhlIDQuNCBjb21wYXRpYmxlIHNldGV1aWQoKS4KICovCmFzbWxpbmthZ2UgbG9uZyBzeXNfc2V0cmVzdWlkKHVpZF90IHJ1aWQsIHVpZF90IGV1aWQsIHVpZF90IHN1aWQpCnsKCWludCBvbGRfcnVpZCA9IGN1cnJlbnQtPnVpZDsKCWludCBvbGRfZXVpZCA9IGN1cnJlbnQtPmV1aWQ7CglpbnQgb2xkX3N1aWQgPSBjdXJyZW50LT5zdWlkOwoJaW50IHJldHZhbDsKCglyZXR2YWwgPSBzZWN1cml0eV90YXNrX3NldHVpZChydWlkLCBldWlkLCBzdWlkLCBMU01fU0VUSURfUkVTKTsKCWlmIChyZXR2YWwpCgkJcmV0dXJuIHJldHZhbDsKCglpZiAoIWNhcGFibGUoQ0FQX1NFVFVJRCkpIHsKCQlpZiAoKHJ1aWQgIT0gKHVpZF90KSAtMSkgJiYgKHJ1aWQgIT0gY3VycmVudC0+dWlkKSAmJgoJCSAgICAocnVpZCAhPSBjdXJyZW50LT5ldWlkKSAmJiAocnVpZCAhPSBjdXJyZW50LT5zdWlkKSkKCQkJcmV0dXJuIC1FUEVSTTsKCQlpZiAoKGV1aWQgIT0gKHVpZF90KSAtMSkgJiYgKGV1aWQgIT0gY3VycmVudC0+dWlkKSAmJgoJCSAgICAoZXVpZCAhPSBjdXJyZW50LT5ldWlkKSAmJiAoZXVpZCAhPSBjdXJyZW50LT5zdWlkKSkKCQkJcmV0dXJuIC1FUEVSTTsKCQlpZiAoKHN1aWQgIT0gKHVpZF90KSAtMSkgJiYgKHN1aWQgIT0gY3VycmVudC0+dWlkKSAmJgoJCSAgICAoc3VpZCAhPSBjdXJyZW50LT5ldWlkKSAmJiAoc3VpZCAhPSBjdXJyZW50LT5zdWlkKSkKCQkJcmV0dXJuIC1FUEVSTTsKCX0KCWlmIChydWlkICE9ICh1aWRfdCkgLTEpIHsKCQlpZiAocnVpZCAhPSBjdXJyZW50LT51aWQgJiYgc2V0X3VzZXIocnVpZCwgZXVpZCAhPSBjdXJyZW50LT5ldWlkKSA8IDApCgkJCXJldHVybiAtRUFHQUlOOwoJfQoJaWYgKGV1aWQgIT0gKHVpZF90KSAtMSkgewoJCWlmIChldWlkICE9IGN1cnJlbnQtPmV1aWQpIHsKCQkJY3VycmVudC0+bW0tPmR1bXBhYmxlID0gc3VpZF9kdW1wYWJsZTsKCQkJc21wX3dtYigpOwoJCX0KCQljdXJyZW50LT5ldWlkID0gZXVpZDsKCX0KCWN1cnJlbnQtPmZzdWlkID0gY3VycmVudC0+ZXVpZDsKCWlmIChzdWlkICE9ICh1aWRfdCkgLTEpCgkJY3VycmVudC0+c3VpZCA9IHN1aWQ7CgoJa2V5X2ZzdWlkX2NoYW5nZWQoY3VycmVudCk7Cglwcm9jX2lkX2Nvbm5lY3RvcihjdXJyZW50LCBQUk9DX0VWRU5UX1VJRCk7CgoJcmV0dXJuIHNlY3VyaXR5X3Rhc2tfcG9zdF9zZXR1aWQob2xkX3J1aWQsIG9sZF9ldWlkLCBvbGRfc3VpZCwgTFNNX1NFVElEX1JFUyk7Cn0KCmFzbWxpbmthZ2UgbG9uZyBzeXNfZ2V0cmVzdWlkKHVpZF90IF9fdXNlciAqcnVpZCwgdWlkX3QgX191c2VyICpldWlkLCB1aWRfdCBfX3VzZXIgKnN1aWQpCnsKCWludCByZXR2YWw7CgoJaWYgKCEocmV0dmFsID0gcHV0X3VzZXIoY3VycmVudC0+dWlkLCBydWlkKSkgJiYKCSAgICAhKHJldHZhbCA9IHB1dF91c2VyKGN1cnJlbnQtPmV1aWQsIGV1aWQpKSkKCQlyZXR2YWwgPSBwdXRfdXNlcihjdXJyZW50LT5zdWlkLCBzdWlkKTsKCglyZXR1cm4gcmV0dmFsOwp9CgovKgogKiBTYW1lIGFzIGFib3ZlLCBidXQgZm9yIHJnaWQsIGVnaWQsIHNnaWQuCiAqLwphc21saW5rYWdlIGxvbmcgc3lzX3NldHJlc2dpZChnaWRfdCByZ2lkLCBnaWRfdCBlZ2lkLCBnaWRfdCBzZ2lkKQp7CglpbnQgcmV0dmFsOwoKCXJldHZhbCA9IHNlY3VyaXR5X3Rhc2tfc2V0Z2lkKHJnaWQsIGVnaWQsIHNnaWQsIExTTV9TRVRJRF9SRVMpOwoJaWYgKHJldHZhbCkKCQlyZXR1cm4gcmV0dmFsOwoKCWlmICghY2FwYWJsZShDQVBfU0VUR0lEKSkgewoJCWlmICgocmdpZCAhPSAoZ2lkX3QpIC0xKSAmJiAocmdpZCAhPSBjdXJyZW50LT5naWQpICYmCgkJICAgIChyZ2lkICE9IGN1cnJlbnQtPmVnaWQpICYmIChyZ2lkICE9IGN1cnJlbnQtPnNnaWQpKQoJCQlyZXR1cm4gLUVQRVJNOwoJCWlmICgoZWdpZCAhPSAoZ2lkX3QpIC0xKSAmJiAoZWdpZCAhPSBjdXJyZW50LT5naWQpICYmCgkJICAgIChlZ2lkICE9IGN1cnJlbnQtPmVnaWQpICYmIChlZ2lkICE9IGN1cnJlbnQtPnNnaWQpKQoJCQlyZXR1cm4gLUVQRVJNOwoJCWlmICgoc2dpZCAhPSAoZ2lkX3QpIC0xKSAmJiAoc2dpZCAhPSBjdXJyZW50LT5naWQpICYmCgkJICAgIChzZ2lkICE9IGN1cnJlbnQtPmVnaWQpICYmIChzZ2lkICE9IGN1cnJlbnQtPnNnaWQpKQoJCQlyZXR1cm4gLUVQRVJNOwoJfQoJaWYgKGVnaWQgIT0gKGdpZF90KSAtMSkgewoJCWlmIChlZ2lkICE9IGN1cnJlbnQtPmVnaWQpIHsKCQkJY3VycmVudC0+bW0tPmR1bXBhYmxlID0gc3VpZF9kdW1wYWJsZTsKCQkJc21wX3dtYigpOwoJCX0KCQljdXJyZW50LT5lZ2lkID0gZWdpZDsKCX0KCWN1cnJlbnQtPmZzZ2lkID0gY3VycmVudC0+ZWdpZDsKCWlmIChyZ2lkICE9IChnaWRfdCkgLTEpCgkJY3VycmVudC0+Z2lkID0gcmdpZDsKCWlmIChzZ2lkICE9IChnaWRfdCkgLTEpCgkJY3VycmVudC0+c2dpZCA9IHNnaWQ7CgoJa2V5X2ZzZ2lkX2NoYW5nZWQoY3VycmVudCk7Cglwcm9jX2lkX2Nvbm5lY3RvcihjdXJyZW50LCBQUk9DX0VWRU5UX0dJRCk7CglyZXR1cm4gMDsKfQoKYXNtbGlua2FnZSBsb25nIHN5c19nZXRyZXNnaWQoZ2lkX3QgX191c2VyICpyZ2lkLCBnaWRfdCBfX3VzZXIgKmVnaWQsIGdpZF90IF9fdXNlciAqc2dpZCkKewoJaW50IHJldHZhbDsKCglpZiAoIShyZXR2YWwgPSBwdXRfdXNlcihjdXJyZW50LT5naWQsIHJnaWQpKSAmJgoJICAgICEocmV0dmFsID0gcHV0X3VzZXIoY3VycmVudC0+ZWdpZCwgZWdpZCkpKQoJCXJldHZhbCA9IHB1dF91c2VyKGN1cnJlbnQtPnNnaWQsIHNnaWQpOwoKCXJldHVybiByZXR2YWw7Cn0KCgovKgogKiAic2V0ZnN1aWQoKSIgc2V0cyB0aGUgZnN1aWQgLSB0aGUgdWlkIHVzZWQgZm9yIGZpbGVzeXN0ZW0gY2hlY2tzLiBUaGlzCiAqIGlzIHVzZWQgZm9yICJhY2Nlc3MoKSIgYW5kIGZvciB0aGUgTkZTIGRhZW1vbiAobGV0dGluZyBuZnNkIHN0YXkgYXQKICogd2hhdGV2ZXIgdWlkIGl0IHdhbnRzIHRvKS4gSXQgbm9ybWFsbHkgc2hhZG93cyAiZXVpZCIsIGV4Y2VwdCB3aGVuCiAqIGV4cGxpY2l0bHkgc2V0IGJ5IHNldGZzdWlkKCkgb3IgZm9yIGFjY2Vzcy4uCiAqLwphc21saW5rYWdlIGxvbmcgc3lzX3NldGZzdWlkKHVpZF90IHVpZCkKewoJaW50IG9sZF9mc3VpZDsKCglvbGRfZnN1aWQgPSBjdXJyZW50LT5mc3VpZDsKCWlmIChzZWN1cml0eV90YXNrX3NldHVpZCh1aWQsICh1aWRfdCktMSwgKHVpZF90KS0xLCBMU01fU0VUSURfRlMpKQoJCXJldHVybiBvbGRfZnN1aWQ7CgoJaWYgKHVpZCA9PSBjdXJyZW50LT51aWQgfHwgdWlkID09IGN1cnJlbnQtPmV1aWQgfHwKCSAgICB1aWQgPT0gY3VycmVudC0+c3VpZCB8fCB1aWQgPT0gY3VycmVudC0+ZnN1aWQgfHwgCgkgICAgY2FwYWJsZShDQVBfU0VUVUlEKSkgewoJCWlmICh1aWQgIT0gb2xkX2ZzdWlkKSB7CgkJCWN1cnJlbnQtPm1tLT5kdW1wYWJsZSA9IHN1aWRfZHVtcGFibGU7CgkJCXNtcF93bWIoKTsKCQl9CgkJY3VycmVudC0+ZnN1aWQgPSB1aWQ7Cgl9CgoJa2V5X2ZzdWlkX2NoYW5nZWQoY3VycmVudCk7Cglwcm9jX2lkX2Nvbm5lY3RvcihjdXJyZW50LCBQUk9DX0VWRU5UX1VJRCk7CgoJc2VjdXJpdHlfdGFza19wb3N0X3NldHVpZChvbGRfZnN1aWQsICh1aWRfdCktMSwgKHVpZF90KS0xLCBMU01fU0VUSURfRlMpOwoKCXJldHVybiBvbGRfZnN1aWQ7Cn0KCi8qCiAqIFNhbW1hIHDlIHN2ZW5za2EuLgogKi8KYXNtbGlua2FnZSBsb25nIHN5c19zZXRmc2dpZChnaWRfdCBnaWQpCnsKCWludCBvbGRfZnNnaWQ7CgoJb2xkX2ZzZ2lkID0gY3VycmVudC0+ZnNnaWQ7CglpZiAoc2VjdXJpdHlfdGFza19zZXRnaWQoZ2lkLCAoZ2lkX3QpLTEsIChnaWRfdCktMSwgTFNNX1NFVElEX0ZTKSkKCQlyZXR1cm4gb2xkX2ZzZ2lkOwoKCWlmIChnaWQgPT0gY3VycmVudC0+Z2lkIHx8IGdpZCA9PSBjdXJyZW50LT5lZ2lkIHx8CgkgICAgZ2lkID09IGN1cnJlbnQtPnNnaWQgfHwgZ2lkID09IGN1cnJlbnQtPmZzZ2lkIHx8IAoJICAgIGNhcGFibGUoQ0FQX1NFVEdJRCkpIHsKCQlpZiAoZ2lkICE9IG9sZF9mc2dpZCkgewoJCQljdXJyZW50LT5tbS0+ZHVtcGFibGUgPSBzdWlkX2R1bXBhYmxlOwoJCQlzbXBfd21iKCk7CgkJfQoJCWN1cnJlbnQtPmZzZ2lkID0gZ2lkOwoJCWtleV9mc2dpZF9jaGFuZ2VkKGN1cnJlbnQpOwoJCXByb2NfaWRfY29ubmVjdG9yKGN1cnJlbnQsIFBST0NfRVZFTlRfR0lEKTsKCX0KCXJldHVybiBvbGRfZnNnaWQ7Cn0KCmFzbWxpbmthZ2UgbG9uZyBzeXNfdGltZXMoc3RydWN0IHRtcyBfX3VzZXIgKiB0YnVmKQp7CgkvKgoJICoJSW4gdGhlIFNNUCB3b3JsZCB3ZSBtaWdodCBqdXN0IGJlIHVubHVja3kgYW5kIGhhdmUgb25lIG9mCgkgKgl0aGUgdGltZXMgaW5jcmVtZW50IGFzIHdlIHVzZSBpdC4gU2luY2UgdGhlIHZhbHVlIGlzIGFuCgkgKglhdG9taWNhbGx5IHNhZmUgdHlwZSB0aGlzIGlzIGp1c3QgZmluZS4gQ29uY2VwdHVhbGx5IGl0cwoJICoJYXMgaWYgdGhlIHN5c2NhbGwgdG9vayBhbiBpbnN0YW50IGxvbmdlciB0byBvY2N1ci4KCSAqLwoJaWYgKHRidWYpIHsKCQlzdHJ1Y3QgdG1zIHRtcDsKCQlzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRzayA9IGN1cnJlbnQ7CgkJc3RydWN0IHRhc2tfc3RydWN0ICp0OwoJCWNwdXRpbWVfdCB1dGltZSwgc3RpbWUsIGN1dGltZSwgY3N0aW1lOwoKCQlzcGluX2xvY2tfaXJxKCZ0c2stPnNpZ2hhbmQtPnNpZ2xvY2spOwoJCXV0aW1lID0gdHNrLT5zaWduYWwtPnV0aW1lOwoJCXN0aW1lID0gdHNrLT5zaWduYWwtPnN0aW1lOwoJCXQgPSB0c2s7CgkJZG8gewoJCQl1dGltZSA9IGNwdXRpbWVfYWRkKHV0aW1lLCB0LT51dGltZSk7CgkJCXN0aW1lID0gY3B1dGltZV9hZGQoc3RpbWUsIHQtPnN0aW1lKTsKCQkJdCA9IG5leHRfdGhyZWFkKHQpOwoJCX0gd2hpbGUgKHQgIT0gdHNrKTsKCgkJY3V0aW1lID0gdHNrLT5zaWduYWwtPmN1dGltZTsKCQljc3RpbWUgPSB0c2stPnNpZ25hbC0+Y3N0aW1lOwoJCXNwaW5fdW5sb2NrX2lycSgmdHNrLT5zaWdoYW5kLT5zaWdsb2NrKTsKCgkJdG1wLnRtc191dGltZSA9IGNwdXRpbWVfdG9fY2xvY2tfdCh1dGltZSk7CgkJdG1wLnRtc19zdGltZSA9IGNwdXRpbWVfdG9fY2xvY2tfdChzdGltZSk7CgkJdG1wLnRtc19jdXRpbWUgPSBjcHV0aW1lX3RvX2Nsb2NrX3QoY3V0aW1lKTsKCQl0bXAudG1zX2NzdGltZSA9IGNwdXRpbWVfdG9fY2xvY2tfdChjc3RpbWUpOwoJCWlmIChjb3B5X3RvX3VzZXIodGJ1ZiwgJnRtcCwgc2l6ZW9mKHN0cnVjdCB0bXMpKSkKCQkJcmV0dXJuIC1FRkFVTFQ7Cgl9CglyZXR1cm4gKGxvbmcpIGppZmZpZXNfNjRfdG9fY2xvY2tfdChnZXRfamlmZmllc182NCgpKTsKfQoKLyoKICogVGhpcyBuZWVkcyBzb21lIGhlYXZ5IGNoZWNraW5nIC4uLgogKiBJIGp1c3QgaGF2ZW4ndCB0aGUgc3RvbWFjaCBmb3IgaXQuIEkgYWxzbyBkb24ndCBmdWxseQogKiB1bmRlcnN0YW5kIHNlc3Npb25zL3BncnAgZXRjLiBMZXQgc29tZWJvZHkgd2hvIGRvZXMgZXhwbGFpbiBpdC4KICoKICogT0ssIEkgdGhpbmsgSSBoYXZlIHRoZSBwcm90ZWN0aW9uIHNlbWFudGljcyByaWdodC4uLi4gdGhpcyBpcyByZWFsbHkKICogb25seSBpbXBvcnRhbnQgb24gYSBtdWx0aS11c2VyIHN5c3RlbSBhbnl3YXksIHRvIG1ha2Ugc3VyZSBvbmUgdXNlcgogKiBjYW4ndCBzZW5kIGEgc2lnbmFsIHRvIGEgcHJvY2VzcyBvd25lZCBieSBhbm90aGVyLiAgLVRZVCwgMTIvMTIvOTEKICoKICogQXVjaC4gSGFkIHRvIGFkZCB0aGUgJ2RpZF9leGVjJyBmbGFnIHRvIGNvbmZvcm0gY29tcGxldGVseSB0byBQT1NJWC4KICogTEJUIDA0LjAzLjk0CiAqLwoKYXNtbGlua2FnZSBsb25nIHN5c19zZXRwZ2lkKHBpZF90IHBpZCwgcGlkX3QgcGdpZCkKewoJc3RydWN0IHRhc2tfc3RydWN0ICpwOwoJc3RydWN0IHRhc2tfc3RydWN0ICpncm91cF9sZWFkZXIgPSBjdXJyZW50LT5ncm91cF9sZWFkZXI7CglpbnQgZXJyID0gLUVJTlZBTDsKCglpZiAoIXBpZCkKCQlwaWQgPSBncm91cF9sZWFkZXItPnBpZDsKCWlmICghcGdpZCkKCQlwZ2lkID0gcGlkOwoJaWYgKHBnaWQgPCAwKQoJCXJldHVybiAtRUlOVkFMOwoKCS8qIEZyb20gdGhpcyBwb2ludCBmb3J3YXJkIHdlIGtlZXAgaG9sZGluZyBvbnRvIHRoZSB0YXNrbGlzdCBsb2NrCgkgKiBzbyB0aGF0IG91ciBwYXJlbnQgZG9lcyBub3QgY2hhbmdlIGZyb20gdW5kZXIgdXMuIC1EYXZlTQoJICovCgl3cml0ZV9sb2NrX2lycSgmdGFza2xpc3RfbG9jayk7CgoJZXJyID0gLUVTUkNIOwoJcCA9IGZpbmRfdGFza19ieV9waWQocGlkKTsKCWlmICghcCkKCQlnb3RvIG91dDsKCgllcnIgPSAtRUlOVkFMOwoJaWYgKCF0aHJlYWRfZ3JvdXBfbGVhZGVyKHApKQoJCWdvdG8gb3V0OwoKCWlmIChwLT5yZWFsX3BhcmVudCA9PSBncm91cF9sZWFkZXIpIHsKCQllcnIgPSAtRVBFUk07CgkJaWYgKHRhc2tfc2Vzc2lvbihwKSAhPSB0YXNrX3Nlc3Npb24oZ3JvdXBfbGVhZGVyKSkKCQkJZ290byBvdXQ7CgkJZXJyID0gLUVBQ0NFUzsKCQlpZiAocC0+ZGlkX2V4ZWMpCgkJCWdvdG8gb3V0OwoJfSBlbHNlIHsKCQllcnIgPSAtRVNSQ0g7CgkJaWYgKHAgIT0gZ3JvdXBfbGVhZGVyKQoJCQlnb3RvIG91dDsKCX0KCgllcnIgPSAtRVBFUk07CglpZiAocC0+c2lnbmFsLT5sZWFkZXIpCgkJZ290byBvdXQ7CgoJaWYgKHBnaWQgIT0gcGlkKSB7CgkJc3RydWN0IHRhc2tfc3RydWN0ICpnID0KCQkJZmluZF90YXNrX2J5X3BpZF90eXBlKFBJRFRZUEVfUEdJRCwgcGdpZCk7CgoJCWlmICghZyB8fCB0YXNrX3Nlc3Npb24oZykgIT0gdGFza19zZXNzaW9uKGdyb3VwX2xlYWRlcikpCgkJCWdvdG8gb3V0OwoJfQoKCWVyciA9IHNlY3VyaXR5X3Rhc2tfc2V0cGdpZChwLCBwZ2lkKTsKCWlmIChlcnIpCgkJZ290byBvdXQ7CgoJaWYgKHByb2Nlc3NfZ3JvdXAocCkgIT0gcGdpZCkgewoJCWRldGFjaF9waWQocCwgUElEVFlQRV9QR0lEKTsKCQlwLT5zaWduYWwtPnBncnAgPSBwZ2lkOwoJCWF0dGFjaF9waWQocCwgUElEVFlQRV9QR0lELCBwZ2lkKTsKCX0KCgllcnIgPSAwOwpvdXQ6CgkvKiBBbGwgcGF0aHMgbGVhZCB0byBoZXJlLCB0aHVzIHdlIGFyZSBzYWZlLiAtRGF2ZU0gKi8KCXdyaXRlX3VubG9ja19pcnEoJnRhc2tsaXN0X2xvY2spOwoJcmV0dXJuIGVycjsKfQoKYXNtbGlua2FnZSBsb25nIHN5c19nZXRwZ2lkKHBpZF90IHBpZCkKewoJaWYgKCFwaWQpCgkJcmV0dXJuIHByb2Nlc3NfZ3JvdXAoY3VycmVudCk7CgllbHNlIHsKCQlpbnQgcmV0dmFsOwoJCXN0cnVjdCB0YXNrX3N0cnVjdCAqcDsKCgkJcmVhZF9sb2NrKCZ0YXNrbGlzdF9sb2NrKTsKCQlwID0gZmluZF90YXNrX2J5X3BpZChwaWQpOwoKCQlyZXR2YWwgPSAtRVNSQ0g7CgkJaWYgKHApIHsKCQkJcmV0dmFsID0gc2VjdXJpdHlfdGFza19nZXRwZ2lkKHApOwoJCQlpZiAoIXJldHZhbCkKCQkJCXJldHZhbCA9IHByb2Nlc3NfZ3JvdXAocCk7CgkJfQoJCXJlYWRfdW5sb2NrKCZ0YXNrbGlzdF9sb2NrKTsKCQlyZXR1cm4gcmV0dmFsOwoJfQp9CgojaWZkZWYgX19BUkNIX1dBTlRfU1lTX0dFVFBHUlAKCmFzbWxpbmthZ2UgbG9uZyBzeXNfZ2V0cGdycCh2b2lkKQp7CgkvKiBTTVAgLSBhc3N1bWluZyB3cml0ZXMgYXJlIHdvcmQgYXRvbWljIHRoaXMgaXMgZmluZSAqLwoJcmV0dXJuIHByb2Nlc3NfZ3JvdXAoY3VycmVudCk7Cn0KCiNlbmRpZgoKYXNtbGlua2FnZSBsb25nIHN5c19nZXRzaWQocGlkX3QgcGlkKQp7CglpZiAoIXBpZCkKCQlyZXR1cm4gcHJvY2Vzc19zZXNzaW9uKGN1cnJlbnQpOwoJZWxzZSB7CgkJaW50IHJldHZhbDsKCQlzdHJ1Y3QgdGFza19zdHJ1Y3QgKnA7CgoJCXJlYWRfbG9jaygmdGFza2xpc3RfbG9jayk7CgkJcCA9IGZpbmRfdGFza19ieV9waWQocGlkKTsKCgkJcmV0dmFsID0gLUVTUkNIOwoJCWlmIChwKSB7CgkJCXJldHZhbCA9IHNlY3VyaXR5X3Rhc2tfZ2V0c2lkKHApOwoJCQlpZiAoIXJldHZhbCkKCQkJCXJldHZhbCA9IHByb2Nlc3Nfc2Vzc2lvbihwKTsKCQl9CgkJcmVhZF91bmxvY2soJnRhc2tsaXN0X2xvY2spOwoJCXJldHVybiByZXR2YWw7Cgl9Cn0KCmFzbWxpbmthZ2UgbG9uZyBzeXNfc2V0c2lkKHZvaWQpCnsKCXN0cnVjdCB0YXNrX3N0cnVjdCAqZ3JvdXBfbGVhZGVyID0gY3VycmVudC0+Z3JvdXBfbGVhZGVyOwoJcGlkX3Qgc2Vzc2lvbjsKCWludCBlcnIgPSAtRVBFUk07CgoJd3JpdGVfbG9ja19pcnEoJnRhc2tsaXN0X2xvY2spOwoKCS8qIEZhaWwgaWYgSSBhbSBhbHJlYWR5IGEgc2Vzc2lvbiBsZWFkZXIgKi8KCWlmIChncm91cF9sZWFkZXItPnNpZ25hbC0+bGVhZGVyKQoJCWdvdG8gb3V0OwoKCXNlc3Npb24gPSBncm91cF9sZWFkZXItPnBpZDsKCS8qIEZhaWwgaWYgYSBwcm9jZXNzIGdyb3VwIGlkIGFscmVhZHkgZXhpc3RzIHRoYXQgZXF1YWxzIHRoZQoJICogcHJvcG9zZWQgc2Vzc2lvbiBpZC4KCSAqCgkgKiBEb24ndCBjaGVjayBpZiBzZXNzaW9uIGlkID09IDEgYmVjYXVzZSBrZXJuZWwgdGhyZWFkcyB1c2UgdGhpcwoJICogc2Vzc2lvbiBpZCBhbmQgc28gdGhlIGNoZWNrIHdpbGwgYWx3YXlzIGZhaWwgYW5kIG1ha2UgaXQgc28KCSAqIGluaXQgY2Fubm90IHN1Y2Nlc3NmdWxseSBjYWxsIHNldHNpZC4KCSAqLwoJaWYgKHNlc3Npb24gPiAxICYmIGZpbmRfdGFza19ieV9waWRfdHlwZShQSURUWVBFX1BHSUQsIHNlc3Npb24pKQoJCWdvdG8gb3V0OwoKCWdyb3VwX2xlYWRlci0+c2lnbmFsLT5sZWFkZXIgPSAxOwoJX19zZXRfc3BlY2lhbF9waWRzKHNlc3Npb24sIHNlc3Npb24pOwoKCXNwaW5fbG9jaygmZ3JvdXBfbGVhZGVyLT5zaWdoYW5kLT5zaWdsb2NrKTsKCWdyb3VwX2xlYWRlci0+c2lnbmFsLT50dHkgPSBOVUxMOwoJc3Bpbl91bmxvY2soJmdyb3VwX2xlYWRlci0+c2lnaGFuZC0+c2lnbG9jayk7CgoJZXJyID0gcHJvY2Vzc19ncm91cChncm91cF9sZWFkZXIpOwpvdXQ6Cgl3cml0ZV91bmxvY2tfaXJxKCZ0YXNrbGlzdF9sb2NrKTsKCXJldHVybiBlcnI7Cn0KCi8qCiAqIFN1cHBsZW1lbnRhcnkgZ3JvdXAgSURzCiAqLwoKLyogaW5pdCB0byAyIC0gb25lIGZvciBpbml0X3Rhc2ssIG9uZSB0byBlbnN1cmUgaXQgaXMgbmV2ZXIgZnJlZWQgKi8Kc3RydWN0IGdyb3VwX2luZm8gaW5pdF9ncm91cHMgPSB7IC51c2FnZSA9IEFUT01JQ19JTklUKDIpIH07CgpzdHJ1Y3QgZ3JvdXBfaW5mbyAqZ3JvdXBzX2FsbG9jKGludCBnaWRzZXRzaXplKQp7CglzdHJ1Y3QgZ3JvdXBfaW5mbyAqZ3JvdXBfaW5mbzsKCWludCBuYmxvY2tzOwoJaW50IGk7CgoJbmJsb2NrcyA9IChnaWRzZXRzaXplICsgTkdST1VQU19QRVJfQkxPQ0sgLSAxKSAvIE5HUk9VUFNfUEVSX0JMT0NLOwoJLyogTWFrZSBzdXJlIHdlIGFsd2F5cyBhbGxvY2F0ZSBhdCBsZWFzdCBvbmUgaW5kaXJlY3QgYmxvY2sgcG9pbnRlciAqLwoJbmJsb2NrcyA9IG5ibG9ja3MgPyA6IDE7Cglncm91cF9pbmZvID0ga21hbGxvYyhzaXplb2YoKmdyb3VwX2luZm8pICsgbmJsb2NrcypzaXplb2YoZ2lkX3QgKiksIEdGUF9VU0VSKTsKCWlmICghZ3JvdXBfaW5mbykKCQlyZXR1cm4gTlVMTDsKCWdyb3VwX2luZm8tPm5ncm91cHMgPSBnaWRzZXRzaXplOwoJZ3JvdXBfaW5mby0+bmJsb2NrcyA9IG5ibG9ja3M7CglhdG9taWNfc2V0KCZncm91cF9pbmZvLT51c2FnZSwgMSk7CgoJaWYgKGdpZHNldHNpemUgPD0gTkdST1VQU19TTUFMTCkKCQlncm91cF9pbmZvLT5ibG9ja3NbMF0gPSBncm91cF9pbmZvLT5zbWFsbF9ibG9jazsKCWVsc2UgewoJCWZvciAoaSA9IDA7IGkgPCBuYmxvY2tzOyBpKyspIHsKCQkJZ2lkX3QgKmI7CgkJCWIgPSAodm9pZCAqKV9fZ2V0X2ZyZWVfcGFnZShHRlBfVVNFUik7CgkJCWlmICghYikKCQkJCWdvdG8gb3V0X3VuZG9fcGFydGlhbF9hbGxvYzsKCQkJZ3JvdXBfaW5mby0+YmxvY2tzW2ldID0gYjsKCQl9Cgl9CglyZXR1cm4gZ3JvdXBfaW5mbzsKCm91dF91bmRvX3BhcnRpYWxfYWxsb2M6Cgl3aGlsZSAoLS1pID49IDApIHsKCQlmcmVlX3BhZ2UoKHVuc2lnbmVkIGxvbmcpZ3JvdXBfaW5mby0+YmxvY2tzW2ldKTsKCX0KCWtmcmVlKGdyb3VwX2luZm8pOwoJcmV0dXJuIE5VTEw7Cn0KCkVYUE9SVF9TWU1CT0woZ3JvdXBzX2FsbG9jKTsKCnZvaWQgZ3JvdXBzX2ZyZWUoc3RydWN0IGdyb3VwX2luZm8gKmdyb3VwX2luZm8pCnsKCWlmIChncm91cF9pbmZvLT5ibG9ja3NbMF0gIT0gZ3JvdXBfaW5mby0+c21hbGxfYmxvY2spIHsKCQlpbnQgaTsKCQlmb3IgKGkgPSAwOyBpIDwgZ3JvdXBfaW5mby0+bmJsb2NrczsgaSsrKQoJCQlmcmVlX3BhZ2UoKHVuc2lnbmVkIGxvbmcpZ3JvdXBfaW5mby0+YmxvY2tzW2ldKTsKCX0KCWtmcmVlKGdyb3VwX2luZm8pOwp9CgpFWFBPUlRfU1lNQk9MKGdyb3Vwc19mcmVlKTsKCi8qIGV4cG9ydCB0aGUgZ3JvdXBfaW5mbyB0byBhIHVzZXItc3BhY2UgYXJyYXkgKi8Kc3RhdGljIGludCBncm91cHNfdG9fdXNlcihnaWRfdCBfX3VzZXIgKmdyb3VwbGlzdCwKICAgIHN0cnVjdCBncm91cF9pbmZvICpncm91cF9pbmZvKQp7CglpbnQgaTsKCWludCBjb3VudCA9IGdyb3VwX2luZm8tPm5ncm91cHM7CgoJZm9yIChpID0gMDsgaSA8IGdyb3VwX2luZm8tPm5ibG9ja3M7IGkrKykgewoJCWludCBjcF9jb3VudCA9IG1pbihOR1JPVVBTX1BFUl9CTE9DSywgY291bnQpOwoJCWludCBvZmYgPSBpICogTkdST1VQU19QRVJfQkxPQ0s7CgkJaW50IGxlbiA9IGNwX2NvdW50ICogc2l6ZW9mKCpncm91cGxpc3QpOwoKCQlpZiAoY29weV90b191c2VyKGdyb3VwbGlzdCtvZmYsIGdyb3VwX2luZm8tPmJsb2Nrc1tpXSwgbGVuKSkKCQkJcmV0dXJuIC1FRkFVTFQ7CgoJCWNvdW50IC09IGNwX2NvdW50OwoJfQoJcmV0dXJuIDA7Cn0KCi8qIGZpbGwgYSBncm91cF9pbmZvIGZyb20gYSB1c2VyLXNwYWNlIGFycmF5IC0gaXQgbXVzdCBiZSBhbGxvY2F0ZWQgYWxyZWFkeSAqLwpzdGF0aWMgaW50IGdyb3Vwc19mcm9tX3VzZXIoc3RydWN0IGdyb3VwX2luZm8gKmdyb3VwX2luZm8sCiAgICBnaWRfdCBfX3VzZXIgKmdyb3VwbGlzdCkKewoJaW50IGk7CglpbnQgY291bnQgPSBncm91cF9pbmZvLT5uZ3JvdXBzOwoKCWZvciAoaSA9IDA7IGkgPCBncm91cF9pbmZvLT5uYmxvY2tzOyBpKyspIHsKCQlpbnQgY3BfY291bnQgPSBtaW4oTkdST1VQU19QRVJfQkxPQ0ssIGNvdW50KTsKCQlpbnQgb2ZmID0gaSAqIE5HUk9VUFNfUEVSX0JMT0NLOwoJCWludCBsZW4gPSBjcF9jb3VudCAqIHNpemVvZigqZ3JvdXBsaXN0KTsKCgkJaWYgKGNvcHlfZnJvbV91c2VyKGdyb3VwX2luZm8tPmJsb2Nrc1tpXSwgZ3JvdXBsaXN0K29mZiwgbGVuKSkKCQkJcmV0dXJuIC1FRkFVTFQ7CgoJCWNvdW50IC09IGNwX2NvdW50OwoJfQoJcmV0dXJuIDA7Cn0KCi8qIGEgc2ltcGxlIFNoZWxsIHNvcnQgKi8Kc3RhdGljIHZvaWQgZ3JvdXBzX3NvcnQoc3RydWN0IGdyb3VwX2luZm8gKmdyb3VwX2luZm8pCnsKCWludCBiYXNlLCBtYXgsIHN0cmlkZTsKCWludCBnaWRzZXRzaXplID0gZ3JvdXBfaW5mby0+bmdyb3VwczsKCglmb3IgKHN0cmlkZSA9IDE7IHN0cmlkZSA8IGdpZHNldHNpemU7IHN0cmlkZSA9IDMgKiBzdHJpZGUgKyAxKQoJCTsgLyogbm90aGluZyAqLwoJc3RyaWRlIC89IDM7CgoJd2hpbGUgKHN0cmlkZSkgewoJCW1heCA9IGdpZHNldHNpemUgLSBzdHJpZGU7CgkJZm9yIChiYXNlID0gMDsgYmFzZSA8IG1heDsgYmFzZSsrKSB7CgkJCWludCBsZWZ0ID0gYmFzZTsKCQkJaW50IHJpZ2h0ID0gbGVmdCArIHN0cmlkZTsKCQkJZ2lkX3QgdG1wID0gR1JPVVBfQVQoZ3JvdXBfaW5mbywgcmlnaHQpOwoKCQkJd2hpbGUgKGxlZnQgPj0gMCAmJiBHUk9VUF9BVChncm91cF9pbmZvLCBsZWZ0KSA+IHRtcCkgewoJCQkJR1JPVVBfQVQoZ3JvdXBfaW5mbywgcmlnaHQpID0KCQkJCSAgICBHUk9VUF9BVChncm91cF9pbmZvLCBsZWZ0KTsKCQkJCXJpZ2h0ID0gbGVmdDsKCQkJCWxlZnQgLT0gc3RyaWRlOwoJCQl9CgkJCUdST1VQX0FUKGdyb3VwX2luZm8sIHJpZ2h0KSA9IHRtcDsKCQl9CgkJc3RyaWRlIC89IDM7Cgl9Cn0KCi8qIGEgc2ltcGxlIGJzZWFyY2ggKi8KaW50IGdyb3Vwc19zZWFyY2goc3RydWN0IGdyb3VwX2luZm8gKmdyb3VwX2luZm8sIGdpZF90IGdycCkKewoJdW5zaWduZWQgaW50IGxlZnQsIHJpZ2h0OwoKCWlmICghZ3JvdXBfaW5mbykKCQlyZXR1cm4gMDsKCglsZWZ0ID0gMDsKCXJpZ2h0ID0gZ3JvdXBfaW5mby0+bmdyb3VwczsKCXdoaWxlIChsZWZ0IDwgcmlnaHQpIHsKCQl1bnNpZ25lZCBpbnQgbWlkID0gKGxlZnQrcmlnaHQpLzI7CgkJaW50IGNtcCA9IGdycCAtIEdST1VQX0FUKGdyb3VwX2luZm8sIG1pZCk7CgkJaWYgKGNtcCA+IDApCgkJCWxlZnQgPSBtaWQgKyAxOwoJCWVsc2UgaWYgKGNtcCA8IDApCgkJCXJpZ2h0ID0gbWlkOwoJCWVsc2UKCQkJcmV0dXJuIDE7Cgl9CglyZXR1cm4gMDsKfQoKLyogdmFsaWRhdGUgYW5kIHNldCBjdXJyZW50LT5ncm91cF9pbmZvICovCmludCBzZXRfY3VycmVudF9ncm91cHMoc3RydWN0IGdyb3VwX2luZm8gKmdyb3VwX2luZm8pCnsKCWludCByZXR2YWw7CglzdHJ1Y3QgZ3JvdXBfaW5mbyAqb2xkX2luZm87CgoJcmV0dmFsID0gc2VjdXJpdHlfdGFza19zZXRncm91cHMoZ3JvdXBfaW5mbyk7CglpZiAocmV0dmFsKQoJCXJldHVybiByZXR2YWw7CgoJZ3JvdXBzX3NvcnQoZ3JvdXBfaW5mbyk7CglnZXRfZ3JvdXBfaW5mbyhncm91cF9pbmZvKTsKCgl0YXNrX2xvY2soY3VycmVudCk7CglvbGRfaW5mbyA9IGN1cnJlbnQtPmdyb3VwX2luZm87CgljdXJyZW50LT5ncm91cF9pbmZvID0gZ3JvdXBfaW5mbzsKCXRhc2tfdW5sb2NrKGN1cnJlbnQpOwoKCXB1dF9ncm91cF9pbmZvKG9sZF9pbmZvKTsKCglyZXR1cm4gMDsKfQoKRVhQT1JUX1NZTUJPTChzZXRfY3VycmVudF9ncm91cHMpOwoKYXNtbGlua2FnZSBsb25nIHN5c19nZXRncm91cHMoaW50IGdpZHNldHNpemUsIGdpZF90IF9fdXNlciAqZ3JvdXBsaXN0KQp7CglpbnQgaSA9IDA7CgoJLyoKCSAqCVNNUDogTm9ib2R5IGVsc2UgY2FuIGNoYW5nZSBvdXIgZ3JvdXBsaXN0LiBUaHVzIHdlIGFyZQoJICoJc2FmZS4KCSAqLwoKCWlmIChnaWRzZXRzaXplIDwgMCkKCQlyZXR1cm4gLUVJTlZBTDsKCgkvKiBubyBuZWVkIHRvIGdyYWIgdGFza19sb2NrIGhlcmU7IGl0IGNhbm5vdCBjaGFuZ2UgKi8KCWkgPSBjdXJyZW50LT5ncm91cF9pbmZvLT5uZ3JvdXBzOwoJaWYgKGdpZHNldHNpemUpIHsKCQlpZiAoaSA+IGdpZHNldHNpemUpIHsKCQkJaSA9IC1FSU5WQUw7CgkJCWdvdG8gb3V0OwoJCX0KCQlpZiAoZ3JvdXBzX3RvX3VzZXIoZ3JvdXBsaXN0LCBjdXJyZW50LT5ncm91cF9pbmZvKSkgewoJCQlpID0gLUVGQVVMVDsKCQkJZ290byBvdXQ7CgkJfQoJfQpvdXQ6CglyZXR1cm4gaTsKfQoKLyoKICoJU01QOiBPdXIgZ3JvdXBzIGFyZSBjb3B5LW9uLXdyaXRlLiBXZSBjYW4gc2V0IHRoZW0gc2FmZWx5CiAqCXdpdGhvdXQgYW5vdGhlciB0YXNrIGludGVyZmVyaW5nLgogKi8KIAphc21saW5rYWdlIGxvbmcgc3lzX3NldGdyb3VwcyhpbnQgZ2lkc2V0c2l6ZSwgZ2lkX3QgX191c2VyICpncm91cGxpc3QpCnsKCXN0cnVjdCBncm91cF9pbmZvICpncm91cF9pbmZvOwoJaW50IHJldHZhbDsKCglpZiAoIWNhcGFibGUoQ0FQX1NFVEdJRCkpCgkJcmV0dXJuIC1FUEVSTTsKCWlmICgodW5zaWduZWQpZ2lkc2V0c2l6ZSA+IE5HUk9VUFNfTUFYKQoJCXJldHVybiAtRUlOVkFMOwoKCWdyb3VwX2luZm8gPSBncm91cHNfYWxsb2MoZ2lkc2V0c2l6ZSk7CglpZiAoIWdyb3VwX2luZm8pCgkJcmV0dXJuIC1FTk9NRU07CglyZXR2YWwgPSBncm91cHNfZnJvbV91c2VyKGdyb3VwX2luZm8sIGdyb3VwbGlzdCk7CglpZiAocmV0dmFsKSB7CgkJcHV0X2dyb3VwX2luZm8oZ3JvdXBfaW5mbyk7CgkJcmV0dXJuIHJldHZhbDsKCX0KCglyZXR2YWwgPSBzZXRfY3VycmVudF9ncm91cHMoZ3JvdXBfaW5mbyk7CglwdXRfZ3JvdXBfaW5mbyhncm91cF9pbmZvKTsKCglyZXR1cm4gcmV0dmFsOwp9CgovKgogKiBDaGVjayB3aGV0aGVyIHdlJ3JlIGZzZ2lkL2VnaWQgb3IgaW4gdGhlIHN1cHBsZW1lbnRhbCBncm91cC4uCiAqLwppbnQgaW5fZ3JvdXBfcChnaWRfdCBncnApCnsKCWludCByZXR2YWwgPSAxOwoJaWYgKGdycCAhPSBjdXJyZW50LT5mc2dpZCkKCQlyZXR2YWwgPSBncm91cHNfc2VhcmNoKGN1cnJlbnQtPmdyb3VwX2luZm8sIGdycCk7CglyZXR1cm4gcmV0dmFsOwp9CgpFWFBPUlRfU1lNQk9MKGluX2dyb3VwX3ApOwoKaW50IGluX2Vncm91cF9wKGdpZF90IGdycCkKewoJaW50IHJldHZhbCA9IDE7CglpZiAoZ3JwICE9IGN1cnJlbnQtPmVnaWQpCgkJcmV0dmFsID0gZ3JvdXBzX3NlYXJjaChjdXJyZW50LT5ncm91cF9pbmZvLCBncnApOwoJcmV0dXJuIHJldHZhbDsKfQoKRVhQT1JUX1NZTUJPTChpbl9lZ3JvdXBfcCk7CgpERUNMQVJFX1JXU0VNKHV0c19zZW0pOwoKRVhQT1JUX1NZTUJPTCh1dHNfc2VtKTsKCmFzbWxpbmthZ2UgbG9uZyBzeXNfbmV3dW5hbWUoc3RydWN0IG5ld191dHNuYW1lIF9fdXNlciAqIG5hbWUpCnsKCWludCBlcnJubyA9IDA7CgoJZG93bl9yZWFkKCZ1dHNfc2VtKTsKCWlmIChjb3B5X3RvX3VzZXIobmFtZSwgdXRzbmFtZSgpLCBzaXplb2YgKm5hbWUpKQoJCWVycm5vID0gLUVGQVVMVDsKCXVwX3JlYWQoJnV0c19zZW0pOwoJcmV0dXJuIGVycm5vOwp9Cgphc21saW5rYWdlIGxvbmcgc3lzX3NldGhvc3RuYW1lKGNoYXIgX191c2VyICpuYW1lLCBpbnQgbGVuKQp7CglpbnQgZXJybm87CgljaGFyIHRtcFtfX05FV19VVFNfTEVOXTsKCglpZiAoIWNhcGFibGUoQ0FQX1NZU19BRE1JTikpCgkJcmV0dXJuIC1FUEVSTTsKCWlmIChsZW4gPCAwIHx8IGxlbiA+IF9fTkVXX1VUU19MRU4pCgkJcmV0dXJuIC1FSU5WQUw7Cglkb3duX3dyaXRlKCZ1dHNfc2VtKTsKCWVycm5vID0gLUVGQVVMVDsKCWlmICghY29weV9mcm9tX3VzZXIodG1wLCBuYW1lLCBsZW4pKSB7CgkJbWVtY3B5KHV0c25hbWUoKS0+bm9kZW5hbWUsIHRtcCwgbGVuKTsKCQl1dHNuYW1lKCktPm5vZGVuYW1lW2xlbl0gPSAwOwoJCWVycm5vID0gMDsKCX0KCXVwX3dyaXRlKCZ1dHNfc2VtKTsKCXJldHVybiBlcnJubzsKfQoKI2lmZGVmIF9fQVJDSF9XQU5UX1NZU19HRVRIT1NUTkFNRQoKYXNtbGlua2FnZSBsb25nIHN5c19nZXRob3N0bmFtZShjaGFyIF9fdXNlciAqbmFtZSwgaW50IGxlbikKewoJaW50IGksIGVycm5vOwoKCWlmIChsZW4gPCAwKQoJCXJldHVybiAtRUlOVkFMOwoJZG93bl9yZWFkKCZ1dHNfc2VtKTsKCWkgPSAxICsgc3RybGVuKHV0c25hbWUoKS0+bm9kZW5hbWUpOwoJaWYgKGkgPiBsZW4pCgkJaSA9IGxlbjsKCWVycm5vID0gMDsKCWlmIChjb3B5X3RvX3VzZXIobmFtZSwgdXRzbmFtZSgpLT5ub2RlbmFtZSwgaSkpCgkJZXJybm8gPSAtRUZBVUxUOwoJdXBfcmVhZCgmdXRzX3NlbSk7CglyZXR1cm4gZXJybm87Cn0KCiNlbmRpZgoKLyoKICogT25seSBzZXRkb21haW5uYW1lOyBnZXRkb21haW5uYW1lIGNhbiBiZSBpbXBsZW1lbnRlZCBieSBjYWxsaW5nCiAqIHVuYW1lKCkKICovCmFzbWxpbmthZ2UgbG9uZyBzeXNfc2V0ZG9tYWlubmFtZShjaGFyIF9fdXNlciAqbmFtZSwgaW50IGxlbikKewoJaW50IGVycm5vOwoJY2hhciB0bXBbX19ORVdfVVRTX0xFTl07CgoJaWYgKCFjYXBhYmxlKENBUF9TWVNfQURNSU4pKQoJCXJldHVybiAtRVBFUk07CglpZiAobGVuIDwgMCB8fCBsZW4gPiBfX05FV19VVFNfTEVOKQoJCXJldHVybiAtRUlOVkFMOwoKCWRvd25fd3JpdGUoJnV0c19zZW0pOwoJZXJybm8gPSAtRUZBVUxUOwoJaWYgKCFjb3B5X2Zyb21fdXNlcih0bXAsIG5hbWUsIGxlbikpIHsKCQltZW1jcHkodXRzbmFtZSgpLT5kb21haW5uYW1lLCB0bXAsIGxlbik7CgkJdXRzbmFtZSgpLT5kb21haW5uYW1lW2xlbl0gPSAwOwoJCWVycm5vID0gMDsKCX0KCXVwX3dyaXRlKCZ1dHNfc2VtKTsKCXJldHVybiBlcnJubzsKfQoKYXNtbGlua2FnZSBsb25nIHN5c19nZXRybGltaXQodW5zaWduZWQgaW50IHJlc291cmNlLCBzdHJ1Y3QgcmxpbWl0IF9fdXNlciAqcmxpbSkKewoJaWYgKHJlc291cmNlID49IFJMSU1fTkxJTUlUUykKCQlyZXR1cm4gLUVJTlZBTDsKCWVsc2UgewoJCXN0cnVjdCBybGltaXQgdmFsdWU7CgkJdGFza19sb2NrKGN1cnJlbnQtPmdyb3VwX2xlYWRlcik7CgkJdmFsdWUgPSBjdXJyZW50LT5zaWduYWwtPnJsaW1bcmVzb3VyY2VdOwoJCXRhc2tfdW5sb2NrKGN1cnJlbnQtPmdyb3VwX2xlYWRlcik7CgkJcmV0dXJuIGNvcHlfdG9fdXNlcihybGltLCAmdmFsdWUsIHNpemVvZigqcmxpbSkpID8gLUVGQVVMVCA6IDA7Cgl9Cn0KCiNpZmRlZiBfX0FSQ0hfV0FOVF9TWVNfT0xEX0dFVFJMSU1JVAoKLyoKICoJQmFjayBjb21wYXRpYmlsaXR5IGZvciBnZXRybGltaXQuIE5lZWRlZCBmb3Igc29tZSBhcHBzLgogKi8KIAphc21saW5rYWdlIGxvbmcgc3lzX29sZF9nZXRybGltaXQodW5zaWduZWQgaW50IHJlc291cmNlLCBzdHJ1Y3QgcmxpbWl0IF9fdXNlciAqcmxpbSkKewoJc3RydWN0IHJsaW1pdCB4OwoJaWYgKHJlc291cmNlID49IFJMSU1fTkxJTUlUUykKCQlyZXR1cm4gLUVJTlZBTDsKCgl0YXNrX2xvY2soY3VycmVudC0+Z3JvdXBfbGVhZGVyKTsKCXggPSBjdXJyZW50LT5zaWduYWwtPnJsaW1bcmVzb3VyY2VdOwoJdGFza191bmxvY2soY3VycmVudC0+Z3JvdXBfbGVhZGVyKTsKCWlmICh4LnJsaW1fY3VyID4gMHg3RkZGRkZGRikKCQl4LnJsaW1fY3VyID0gMHg3RkZGRkZGRjsKCWlmICh4LnJsaW1fbWF4ID4gMHg3RkZGRkZGRikKCQl4LnJsaW1fbWF4ID0gMHg3RkZGRkZGRjsKCXJldHVybiBjb3B5X3RvX3VzZXIocmxpbSwgJngsIHNpemVvZih4KSk/LUVGQVVMVDowOwp9CgojZW5kaWYKCmFzbWxpbmthZ2UgbG9uZyBzeXNfc2V0cmxpbWl0KHVuc2lnbmVkIGludCByZXNvdXJjZSwgc3RydWN0IHJsaW1pdCBfX3VzZXIgKnJsaW0pCnsKCXN0cnVjdCBybGltaXQgbmV3X3JsaW0sICpvbGRfcmxpbTsKCXVuc2lnbmVkIGxvbmcgaXRfcHJvZl9zZWNzOwoJaW50IHJldHZhbDsKCglpZiAocmVzb3VyY2UgPj0gUkxJTV9OTElNSVRTKQoJCXJldHVybiAtRUlOVkFMOwoJaWYgKGNvcHlfZnJvbV91c2VyKCZuZXdfcmxpbSwgcmxpbSwgc2l6ZW9mKCpybGltKSkpCgkJcmV0dXJuIC1FRkFVTFQ7CglpZiAobmV3X3JsaW0ucmxpbV9jdXIgPiBuZXdfcmxpbS5ybGltX21heCkKCQlyZXR1cm4gLUVJTlZBTDsKCW9sZF9ybGltID0gY3VycmVudC0+c2lnbmFsLT5ybGltICsgcmVzb3VyY2U7CglpZiAoKG5ld19ybGltLnJsaW1fbWF4ID4gb2xkX3JsaW0tPnJsaW1fbWF4KSAmJgoJICAgICFjYXBhYmxlKENBUF9TWVNfUkVTT1VSQ0UpKQoJCXJldHVybiAtRVBFUk07CglpZiAocmVzb3VyY2UgPT0gUkxJTUlUX05PRklMRSAmJiBuZXdfcmxpbS5ybGltX21heCA+IE5SX09QRU4pCgkJcmV0dXJuIC1FUEVSTTsKCglyZXR2YWwgPSBzZWN1cml0eV90YXNrX3NldHJsaW1pdChyZXNvdXJjZSwgJm5ld19ybGltKTsKCWlmIChyZXR2YWwpCgkJcmV0dXJuIHJldHZhbDsKCgl0YXNrX2xvY2soY3VycmVudC0+Z3JvdXBfbGVhZGVyKTsKCSpvbGRfcmxpbSA9IG5ld19ybGltOwoJdGFza191bmxvY2soY3VycmVudC0+Z3JvdXBfbGVhZGVyKTsKCglpZiAocmVzb3VyY2UgIT0gUkxJTUlUX0NQVSkKCQlnb3RvIG91dDsKCgkvKgoJICogUkxJTUlUX0NQVSBoYW5kbGluZy4gICBOb3RlIHRoYXQgdGhlIGtlcm5lbCBmYWlscyB0byByZXR1cm4gYW4gZXJyb3IKCSAqIGNvZGUgaWYgaXQgcmVqZWN0ZWQgdGhlIHVzZXIncyBhdHRlbXB0IHRvIHNldCBSTElNSVRfQ1BVLiAgVGhpcyBpcyBhCgkgKiB2ZXJ5IGxvbmctc3RhbmRpbmcgZXJyb3IsIGFuZCBmaXhpbmcgaXQgbm93IHJpc2tzIGJyZWFrYWdlIG9mCgkgKiBhcHBsaWNhdGlvbnMsIHNvIHdlIGxpdmUgd2l0aCBpdAoJICovCglpZiAobmV3X3JsaW0ucmxpbV9jdXIgPT0gUkxJTV9JTkZJTklUWSkKCQlnb3RvIG91dDsKCglpdF9wcm9mX3NlY3MgPSBjcHV0aW1lX3RvX3NlY3MoY3VycmVudC0+c2lnbmFsLT5pdF9wcm9mX2V4cGlyZXMpOwoJaWYgKGl0X3Byb2Zfc2VjcyA9PSAwIHx8IG5ld19ybGltLnJsaW1fY3VyIDw9IGl0X3Byb2Zfc2VjcykgewoJCXVuc2lnbmVkIGxvbmcgcmxpbV9jdXIgPSBuZXdfcmxpbS5ybGltX2N1cjsKCQljcHV0aW1lX3QgY3B1dGltZTsKCgkJaWYgKHJsaW1fY3VyID09IDApIHsKCQkJLyoKCQkJICogVGhlIGNhbGxlciBpcyBhc2tpbmcgZm9yIGFuIGltbWVkaWF0ZSBSTElNSVRfQ1BVCgkJCSAqIGV4cGlyeS4gIEJ1dCB3ZSB1c2UgdGhlIHplcm8gdmFsdWUgdG8gbWVhbiAiaXQgd2FzCgkJCSAqIG5ldmVyIHNldCIuICBTbyBsZXQncyBjaGVhdCBhbmQgbWFrZSBpdCBvbmUgc2Vjb25kCgkJCSAqIGluc3RlYWQKCQkJICovCgkJCXJsaW1fY3VyID0gMTsKCQl9CgkJY3B1dGltZSA9IHNlY3NfdG9fY3B1dGltZShybGltX2N1cik7CgkJcmVhZF9sb2NrKCZ0YXNrbGlzdF9sb2NrKTsKCQlzcGluX2xvY2tfaXJxKCZjdXJyZW50LT5zaWdoYW5kLT5zaWdsb2NrKTsKCQlzZXRfcHJvY2Vzc19jcHVfdGltZXIoY3VycmVudCwgQ1BVQ0xPQ0tfUFJPRiwgJmNwdXRpbWUsIE5VTEwpOwoJCXNwaW5fdW5sb2NrX2lycSgmY3VycmVudC0+c2lnaGFuZC0+c2lnbG9jayk7CgkJcmVhZF91bmxvY2soJnRhc2tsaXN0X2xvY2spOwoJfQpvdXQ6CglyZXR1cm4gMDsKfQoKLyoKICogSXQgd291bGQgbWFrZSBzZW5zZSB0byBwdXQgc3RydWN0IHJ1c2FnZSBpbiB0aGUgdGFza19zdHJ1Y3QsCiAqIGV4Y2VwdCB0aGF0IHdvdWxkIG1ha2UgdGhlIHRhc2tfc3RydWN0IGJlICpyZWFsbHkgYmlnKi4gIEFmdGVyCiAqIHRhc2tfc3RydWN0IGdldHMgbW92ZWQgaW50byBtYWxsb2MnZWQgbWVtb3J5LCBpdCB3b3VsZAogKiBtYWtlIHNlbnNlIHRvIGRvIHRoaXMuICBJdCB3aWxsIG1ha2UgbW92aW5nIHRoZSByZXN0IG9mIHRoZSBpbmZvcm1hdGlvbgogKiBhIGxvdCBzaW1wbGVyISAgKFdoaWNoIHdlJ3JlIG5vdCBkb2luZyByaWdodCBub3cgYmVjYXVzZSB3ZSdyZSBub3QKICogbWVhc3VyaW5nIHRoZW0geWV0KS4KICoKICogV2hlbiBzYW1wbGluZyBtdWx0aXBsZSB0aHJlYWRzIGZvciBSVVNBR0VfU0VMRiwgdW5kZXIgU01QIHdlIG1pZ2h0IGhhdmUKICogcmFjZXMgd2l0aCB0aHJlYWRzIGluY3JlbWVudGluZyB0aGVpciBvd24gY291bnRlcnMuICBCdXQgc2luY2Ugd29yZAogKiByZWFkcyBhcmUgYXRvbWljLCB3ZSBlaXRoZXIgZ2V0IG5ldyB2YWx1ZXMgb3Igb2xkIHZhbHVlcyBhbmQgd2UgZG9uJ3QKICogY2FyZSB3aGljaCBmb3IgdGhlIHN1bXMuICBXZSBhbHdheXMgdGFrZSB0aGUgc2lnbG9jayB0byBwcm90ZWN0IHJlYWRpbmcKICogdGhlIGMqIGZpZWxkcyBmcm9tIHAtPnNpZ25hbCBmcm9tIHJhY2VzIHdpdGggZXhpdC5jIHVwZGF0aW5nIHRob3NlCiAqIGZpZWxkcyB3aGVuIHJlYXBpbmcsIHNvIGEgc2FtcGxlIGVpdGhlciBnZXRzIGFsbCB0aGUgYWRkaXRpb25zIG9mIGEKICogZ2l2ZW4gY2hpbGQgYWZ0ZXIgaXQncyByZWFwZWQsIG9yIG5vbmUgc28gdGhpcyBzYW1wbGUgaXMgYmVmb3JlIHJlYXBpbmcuCiAqCiAqIExvY2tpbmc6CiAqIFdlIG5lZWQgdG8gdGFrZSB0aGUgc2lnbG9jayBmb3IgQ0hJTERFUkVOLCBTRUxGIGFuZCBCT1RICiAqIGZvciAgdGhlIGNhc2VzIGN1cnJlbnQgbXVsdGl0aHJlYWRlZCwgbm9uLWN1cnJlbnQgc2luZ2xlIHRocmVhZGVkCiAqIG5vbi1jdXJyZW50IG11bHRpdGhyZWFkZWQuICBUaHJlYWQgdHJhdmVyc2FsIGlzIG5vdyBzYWZlIHdpdGgKICogdGhlIHNpZ2xvY2sgaGVsZC4KICogU3RyaWN0bHkgc3BlYWtpbmcsIHdlIGRvbm90IG5lZWQgdG8gdGFrZSB0aGUgc2lnbG9jayBpZiB3ZSBhcmUgY3VycmVudCBhbmQKICogc2luZ2xlIHRocmVhZGVkLCAgYXMgbm8gb25lIGVsc2UgY2FuIHRha2Ugb3VyIHNpZ25hbF9zdHJ1Y3QgYXdheSwgbm8gb25lCiAqIGVsc2UgY2FuICByZWFwIHRoZSAgY2hpbGRyZW4gdG8gdXBkYXRlIHNpZ25hbC0+YyogY291bnRlcnMsIGFuZCBubyBvbmUgZWxzZQogKiBjYW4gcmFjZSB3aXRoIHRoZSBzaWduYWwtPiBmaWVsZHMuIElmIHdlIGRvIG5vdCB0YWtlIGFueSBsb2NrLCB0aGUKICogc2lnbmFsLT4gZmllbGRzIGNvdWxkIGJlIHJlYWQgb3V0IG9mIG9yZGVyIHdoaWxlIGFub3RoZXIgdGhyZWFkIHdhcyBqdXN0CiAqIGV4aXRpbmcuIFNvIHdlIHNob3VsZCAgcGxhY2UgYSByZWFkIG1lbW9yeSBiYXJyaWVyIHdoZW4gd2UgYXZvaWQgdGhlIGxvY2suCiAqIE9uIHRoZSB3cml0ZXIgc2lkZSwgIHdyaXRlIG1lbW9yeSBiYXJyaWVyIGlzIGltcGxpZWQgaW4gIF9fZXhpdF9zaWduYWwKICogYXMgX19leGl0X3NpZ25hbCByZWxlYXNlcyAgdGhlIHNpZ2xvY2sgc3BpbmxvY2sgYWZ0ZXIgdXBkYXRpbmcgdGhlIHNpZ25hbC0+CiAqIGZpZWxkcy4gQnV0IHdlIGRvbid0IGRvIHRoaXMgeWV0IHRvIGtlZXAgdGhpbmdzIHNpbXBsZS4KICoKICovCgpzdGF0aWMgdm9pZCBrX2dldHJ1c2FnZShzdHJ1Y3QgdGFza19zdHJ1Y3QgKnAsIGludCB3aG8sIHN0cnVjdCBydXNhZ2UgKnIpCnsKCXN0cnVjdCB0YXNrX3N0cnVjdCAqdDsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgljcHV0aW1lX3QgdXRpbWUsIHN0aW1lOwoKCW1lbXNldCgoY2hhciAqKSByLCAwLCBzaXplb2YgKnIpOwoJdXRpbWUgPSBzdGltZSA9IGNwdXRpbWVfemVybzsKCglyY3VfcmVhZF9sb2NrKCk7CglpZiAoIWxvY2tfdGFza19zaWdoYW5kKHAsICZmbGFncykpIHsKCQlyY3VfcmVhZF91bmxvY2soKTsKCQlyZXR1cm47Cgl9CgoJc3dpdGNoICh3aG8pIHsKCQljYXNlIFJVU0FHRV9CT1RIOgoJCWNhc2UgUlVTQUdFX0NISUxEUkVOOgoJCQl1dGltZSA9IHAtPnNpZ25hbC0+Y3V0aW1lOwoJCQlzdGltZSA9IHAtPnNpZ25hbC0+Y3N0aW1lOwoJCQlyLT5ydV9udmNzdyA9IHAtPnNpZ25hbC0+Y252Y3N3OwoJCQlyLT5ydV9uaXZjc3cgPSBwLT5zaWduYWwtPmNuaXZjc3c7CgkJCXItPnJ1X21pbmZsdCA9IHAtPnNpZ25hbC0+Y21pbl9mbHQ7CgkJCXItPnJ1X21hamZsdCA9IHAtPnNpZ25hbC0+Y21hal9mbHQ7CgoJCQlpZiAod2hvID09IFJVU0FHRV9DSElMRFJFTikKCQkJCWJyZWFrOwoKCQljYXNlIFJVU0FHRV9TRUxGOgoJCQl1dGltZSA9IGNwdXRpbWVfYWRkKHV0aW1lLCBwLT5zaWduYWwtPnV0aW1lKTsKCQkJc3RpbWUgPSBjcHV0aW1lX2FkZChzdGltZSwgcC0+c2lnbmFsLT5zdGltZSk7CgkJCXItPnJ1X252Y3N3ICs9IHAtPnNpZ25hbC0+bnZjc3c7CgkJCXItPnJ1X25pdmNzdyArPSBwLT5zaWduYWwtPm5pdmNzdzsKCQkJci0+cnVfbWluZmx0ICs9IHAtPnNpZ25hbC0+bWluX2ZsdDsKCQkJci0+cnVfbWFqZmx0ICs9IHAtPnNpZ25hbC0+bWFqX2ZsdDsKCQkJdCA9IHA7CgkJCWRvIHsKCQkJCXV0aW1lID0gY3B1dGltZV9hZGQodXRpbWUsIHQtPnV0aW1lKTsKCQkJCXN0aW1lID0gY3B1dGltZV9hZGQoc3RpbWUsIHQtPnN0aW1lKTsKCQkJCXItPnJ1X252Y3N3ICs9IHQtPm52Y3N3OwoJCQkJci0+cnVfbml2Y3N3ICs9IHQtPm5pdmNzdzsKCQkJCXItPnJ1X21pbmZsdCArPSB0LT5taW5fZmx0OwoJCQkJci0+cnVfbWFqZmx0ICs9IHQtPm1hal9mbHQ7CgkJCQl0ID0gbmV4dF90aHJlYWQodCk7CgkJCX0gd2hpbGUgKHQgIT0gcCk7CgkJCWJyZWFrOwoKCQlkZWZhdWx0OgoJCQlCVUcoKTsKCX0KCgl1bmxvY2tfdGFza19zaWdoYW5kKHAsICZmbGFncyk7CglyY3VfcmVhZF91bmxvY2soKTsKCgljcHV0aW1lX3RvX3RpbWV2YWwodXRpbWUsICZyLT5ydV91dGltZSk7CgljcHV0aW1lX3RvX3RpbWV2YWwoc3RpbWUsICZyLT5ydV9zdGltZSk7Cn0KCmludCBnZXRydXNhZ2Uoc3RydWN0IHRhc2tfc3RydWN0ICpwLCBpbnQgd2hvLCBzdHJ1Y3QgcnVzYWdlIF9fdXNlciAqcnUpCnsKCXN0cnVjdCBydXNhZ2UgcjsKCWtfZ2V0cnVzYWdlKHAsIHdobywgJnIpOwoJcmV0dXJuIGNvcHlfdG9fdXNlcihydSwgJnIsIHNpemVvZihyKSkgPyAtRUZBVUxUIDogMDsKfQoKYXNtbGlua2FnZSBsb25nIHN5c19nZXRydXNhZ2UoaW50IHdobywgc3RydWN0IHJ1c2FnZSBfX3VzZXIgKnJ1KQp7CglpZiAod2hvICE9IFJVU0FHRV9TRUxGICYmIHdobyAhPSBSVVNBR0VfQ0hJTERSRU4pCgkJcmV0dXJuIC1FSU5WQUw7CglyZXR1cm4gZ2V0cnVzYWdlKGN1cnJlbnQsIHdobywgcnUpOwp9Cgphc21saW5rYWdlIGxvbmcgc3lzX3VtYXNrKGludCBtYXNrKQp7CgltYXNrID0geGNoZygmY3VycmVudC0+ZnMtPnVtYXNrLCBtYXNrICYgU19JUldYVUdPKTsKCXJldHVybiBtYXNrOwp9CiAgICAKYXNtbGlua2FnZSBsb25nIHN5c19wcmN0bChpbnQgb3B0aW9uLCB1bnNpZ25lZCBsb25nIGFyZzIsIHVuc2lnbmVkIGxvbmcgYXJnMywKCQkJICB1bnNpZ25lZCBsb25nIGFyZzQsIHVuc2lnbmVkIGxvbmcgYXJnNSkKewoJbG9uZyBlcnJvcjsKCgllcnJvciA9IHNlY3VyaXR5X3Rhc2tfcHJjdGwob3B0aW9uLCBhcmcyLCBhcmczLCBhcmc0LCBhcmc1KTsKCWlmIChlcnJvcikKCQlyZXR1cm4gZXJyb3I7CgoJc3dpdGNoIChvcHRpb24pIHsKCQljYXNlIFBSX1NFVF9QREVBVEhTSUc6CgkJCWlmICghdmFsaWRfc2lnbmFsKGFyZzIpKSB7CgkJCQllcnJvciA9IC1FSU5WQUw7CgkJCQlicmVhazsKCQkJfQoJCQljdXJyZW50LT5wZGVhdGhfc2lnbmFsID0gYXJnMjsKCQkJYnJlYWs7CgkJY2FzZSBQUl9HRVRfUERFQVRIU0lHOgoJCQllcnJvciA9IHB1dF91c2VyKGN1cnJlbnQtPnBkZWF0aF9zaWduYWwsIChpbnQgX191c2VyICopYXJnMik7CgkJCWJyZWFrOwoJCWNhc2UgUFJfR0VUX0RVTVBBQkxFOgoJCQllcnJvciA9IGN1cnJlbnQtPm1tLT5kdW1wYWJsZTsKCQkJYnJlYWs7CgkJY2FzZSBQUl9TRVRfRFVNUEFCTEU6CgkJCWlmIChhcmcyIDwgMCB8fCBhcmcyID4gMSkgewoJCQkJZXJyb3IgPSAtRUlOVkFMOwoJCQkJYnJlYWs7CgkJCX0KCQkJY3VycmVudC0+bW0tPmR1bXBhYmxlID0gYXJnMjsKCQkJYnJlYWs7CgoJCWNhc2UgUFJfU0VUX1VOQUxJR046CgkJCWVycm9yID0gU0VUX1VOQUxJR05fQ1RMKGN1cnJlbnQsIGFyZzIpOwoJCQlicmVhazsKCQljYXNlIFBSX0dFVF9VTkFMSUdOOgoJCQllcnJvciA9IEdFVF9VTkFMSUdOX0NUTChjdXJyZW50LCBhcmcyKTsKCQkJYnJlYWs7CgkJY2FzZSBQUl9TRVRfRlBFTVU6CgkJCWVycm9yID0gU0VUX0ZQRU1VX0NUTChjdXJyZW50LCBhcmcyKTsKCQkJYnJlYWs7CgkJY2FzZSBQUl9HRVRfRlBFTVU6CgkJCWVycm9yID0gR0VUX0ZQRU1VX0NUTChjdXJyZW50LCBhcmcyKTsKCQkJYnJlYWs7CgkJY2FzZSBQUl9TRVRfRlBFWEM6CgkJCWVycm9yID0gU0VUX0ZQRVhDX0NUTChjdXJyZW50LCBhcmcyKTsKCQkJYnJlYWs7CgkJY2FzZSBQUl9HRVRfRlBFWEM6CgkJCWVycm9yID0gR0VUX0ZQRVhDX0NUTChjdXJyZW50LCBhcmcyKTsKCQkJYnJlYWs7CgkJY2FzZSBQUl9HRVRfVElNSU5HOgoJCQllcnJvciA9IFBSX1RJTUlOR19TVEFUSVNUSUNBTDsKCQkJYnJlYWs7CgkJY2FzZSBQUl9TRVRfVElNSU5HOgoJCQlpZiAoYXJnMiA9PSBQUl9USU1JTkdfU1RBVElTVElDQUwpCgkJCQllcnJvciA9IDA7CgkJCWVsc2UKCQkJCWVycm9yID0gLUVJTlZBTDsKCQkJYnJlYWs7CgoJCWNhc2UgUFJfR0VUX0tFRVBDQVBTOgoJCQlpZiAoY3VycmVudC0+a2VlcF9jYXBhYmlsaXRpZXMpCgkJCQllcnJvciA9IDE7CgkJCWJyZWFrOwoJCWNhc2UgUFJfU0VUX0tFRVBDQVBTOgoJCQlpZiAoYXJnMiAhPSAwICYmIGFyZzIgIT0gMSkgewoJCQkJZXJyb3IgPSAtRUlOVkFMOwoJCQkJYnJlYWs7CgkJCX0KCQkJY3VycmVudC0+a2VlcF9jYXBhYmlsaXRpZXMgPSBhcmcyOwoJCQlicmVhazsKCQljYXNlIFBSX1NFVF9OQU1FOiB7CgkJCXN0cnVjdCB0YXNrX3N0cnVjdCAqbWUgPSBjdXJyZW50OwoJCQl1bnNpZ25lZCBjaGFyIG5jb21tW3NpemVvZihtZS0+Y29tbSldOwoKCQkJbmNvbW1bc2l6ZW9mKG1lLT5jb21tKS0xXSA9IDA7CgkJCWlmIChzdHJuY3B5X2Zyb21fdXNlcihuY29tbSwgKGNoYXIgX191c2VyICopYXJnMiwKCQkJCQkJc2l6ZW9mKG1lLT5jb21tKS0xKSA8IDApCgkJCQlyZXR1cm4gLUVGQVVMVDsKCQkJc2V0X3Rhc2tfY29tbShtZSwgbmNvbW0pOwoJCQlyZXR1cm4gMDsKCQl9CgkJY2FzZSBQUl9HRVRfTkFNRTogewoJCQlzdHJ1Y3QgdGFza19zdHJ1Y3QgKm1lID0gY3VycmVudDsKCQkJdW5zaWduZWQgY2hhciB0Y29tbVtzaXplb2YobWUtPmNvbW0pXTsKCgkJCWdldF90YXNrX2NvbW0odGNvbW0sIG1lKTsKCQkJaWYgKGNvcHlfdG9fdXNlcigoY2hhciBfX3VzZXIgKilhcmcyLCB0Y29tbSwgc2l6ZW9mKHRjb21tKSkpCgkJCQlyZXR1cm4gLUVGQVVMVDsKCQkJcmV0dXJuIDA7CgkJfQoJCWNhc2UgUFJfR0VUX0VORElBTjoKCQkJZXJyb3IgPSBHRVRfRU5ESUFOKGN1cnJlbnQsIGFyZzIpOwoJCQlicmVhazsKCQljYXNlIFBSX1NFVF9FTkRJQU46CgkJCWVycm9yID0gU0VUX0VORElBTihjdXJyZW50LCBhcmcyKTsKCQkJYnJlYWs7CgoJCWRlZmF1bHQ6CgkJCWVycm9yID0gLUVJTlZBTDsKCQkJYnJlYWs7Cgl9CglyZXR1cm4gZXJyb3I7Cn0KCmFzbWxpbmthZ2UgbG9uZyBzeXNfZ2V0Y3B1KHVuc2lnbmVkIF9fdXNlciAqY3B1cCwgdW5zaWduZWQgX191c2VyICpub2RlcCwKCSAgIAkJICAgc3RydWN0IGdldGNwdV9jYWNoZSBfX3VzZXIgKmNhY2hlKQp7CglpbnQgZXJyID0gMDsKCWludCBjcHUgPSByYXdfc21wX3Byb2Nlc3Nvcl9pZCgpOwoJaWYgKGNwdXApCgkJZXJyIHw9IHB1dF91c2VyKGNwdSwgY3B1cCk7CglpZiAobm9kZXApCgkJZXJyIHw9IHB1dF91c2VyKGNwdV90b19ub2RlKGNwdSksIG5vZGVwKTsKCWlmIChjYWNoZSkgewoJCS8qCgkJICogVGhlIGNhY2hlIGlzIG5vdCBuZWVkZWQgZm9yIHRoaXMgaW1wbGVtZW50YXRpb24sCgkJICogYnV0IG1ha2Ugc3VyZSB1c2VyIHByb2dyYW1zIHBhc3Mgc29tZXRoaW5nCgkJICogdmFsaWQuIHZzeXNjYWxsIGltcGxlbWVudGF0aW9ucyBjYW4gaW5zdGVhZCBtYWtlCgkJICogZ29vZCB1c2Ugb2YgdGhlIGNhY2hlLiBPbmx5IHVzZSB0MCBhbmQgdDEgYmVjYXVzZQoJCSAqIHRoZXNlIGFyZSBhdmFpbGFibGUgaW4gYm90aCAzMmJpdCBhbmQgNjRiaXQgQUJJIChubwoJCSAqIG5lZWQgZm9yIGEgY29tcGF0X2dldGNwdSkuIDMyYml0IGhhcyBlbm91Z2gKCQkgKiBwYWRkaW5nCgkJICovCgkJdW5zaWduZWQgbG9uZyB0MCwgdDE7CgkJZ2V0X3VzZXIodDAsICZjYWNoZS0+YmxvYlswXSk7CgkJZ2V0X3VzZXIodDEsICZjYWNoZS0+YmxvYlsxXSk7CgkJdDArKzsKCQl0MSsrOwoJCXB1dF91c2VyKHQwLCAmY2FjaGUtPmJsb2JbMF0pOwoJCXB1dF91c2VyKHQxLCAmY2FjaGUtPmJsb2JbMV0pOwoJfQoJcmV0dXJuIGVyciA/IC1FRkFVTFQgOiAwOwp9Cg==