LyoKICogKEMpIENvcHlyaWdodCAyMDAzCiAqIERhdmlkIE38bGxlciBFTFNPRlQgQUcgU3dpdHplcmxhbmQuIGQubXVlbGxlckBlbHNvZnQuY2gKICoKICogU2VlIGZpbGUgQ1JFRElUUyBmb3IgbGlzdCBvZiBwZW9wbGUgd2hvIGNvbnRyaWJ1dGVkIHRvIHRoaXMKICogcHJvamVjdC4KICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcwogKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZgogKiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwKICogTUEgMDIxMTEtMTMwNyBVU0EKICovCgovKgogKiBEYXRlICYgVGltZSBzdXBwb3J0IGZvciB0aGUgYnVpbHQtaW4gU2Ftc3VuZyBTM0MyNFgwIFJUQwogKi8KCiNpbmNsdWRlIDxjb21tb24uaD4KI2luY2x1ZGUgPGNvbW1hbmQuaD4KCiNpZiAoZGVmaW5lZChDT05GSUdfQ01EX0RBVEUpKQoKI2luY2x1ZGUgPGFzbS9hcmNoL3MzYzI0eDBfY3B1Lmg+CgojaW5jbHVkZSA8cnRjLmg+CiNpbmNsdWRlIDxhc20vaW8uaD4KCi8qI2RlZmluZQlERUJVRyovCgp0eXBlZGVmIGVudW0gewoJUlRDX0VOQUJMRSwKCVJUQ19ESVNBQkxFCn0gUlRDX0FDQ0VTUzsKCgpzdGF0aWMgaW5saW5lIHZvaWQgU2V0UlRDX0FjY2VzcyhSVENfQUNDRVNTIGEpCnsKCXN0cnVjdCBzM2MyNHgwX3J0YyAqcnRjID0gczNjMjR4MF9nZXRfYmFzZV9ydGMoKTsKCglzd2l0Y2ggKGEpIHsKCWNhc2UgUlRDX0VOQUJMRToKCQl3cml0ZWIocmVhZGIoJnJ0Yy0+cnRjY29uKSB8IDB4MDEsICZydGMtPnJ0Y2Nvbik7CgkJYnJlYWs7CgoJY2FzZSBSVENfRElTQUJMRToKCQl3cml0ZWIocmVhZGIoJnJ0Yy0+cnRjY29uKSAmIH4weDAxLCAmcnRjLT5ydGNjb24pOwoJCWJyZWFrOwoJfQp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgppbnQgcnRjX2dldChzdHJ1Y3QgcnRjX3RpbWUgKnRtcCkKewoJc3RydWN0IHMzYzI0eDBfcnRjICpydGMgPSBzM2MyNHgwX2dldF9iYXNlX3J0YygpOwoJdWNoYXIgc2VjLCBtaW4sIGhvdXIsIG1kYXksIHdkYXksIG1vbiwgeWVhcjsKCXVjaGFyIGFfc2VjLCBhX21pbiwgYV9ob3VyLCBhX2RhdGUsIGFfbW9uLCBhX3llYXIsIGFfYXJtZWQ7CgoJLyogZW5hYmxlIGFjY2VzcyB0byBSVEMgcmVnaXN0ZXJzICovCglTZXRSVENfQWNjZXNzKFJUQ19FTkFCTEUpOwoKCS8qIHJlYWQgUlRDIHJlZ2lzdGVycyAqLwoJZG8gewoJCXNlYyAgPSByZWFkYigmcnRjLT5iY2RzZWMpOwoJCW1pbiAgPSByZWFkYigmcnRjLT5iY2RtaW4pOwoJCWhvdXIgPSByZWFkYigmcnRjLT5iY2Rob3VyKTsKCQltZGF5ID0gcmVhZGIoJnJ0Yy0+YmNkZGF0ZSk7CgkJd2RheSA9IHJlYWRiKCZydGMtPmJjZGRheSk7CgkJbW9uICA9IHJlYWRiKCZydGMtPmJjZG1vbik7CgkJeWVhciA9IHJlYWRiKCZydGMtPmJjZHllYXIpOwoJfSB3aGlsZSAoc2VjICE9IHJlYWRiKCZydGMtPmJjZHNlYykpOwoKCS8qIHJlYWQgQUxBUk0gcmVnaXN0ZXJzICovCglhX3NlYyAgID0gcmVhZGIoJnJ0Yy0+YWxtc2VjKTsKCWFfbWluICAgPSByZWFkYigmcnRjLT5hbG1taW4pOwoJYV9ob3VyICA9IHJlYWRiKCZydGMtPmFsbWhvdXIpOwoJYV9kYXRlICA9IHJlYWRiKCZydGMtPmFsbWRhdGUpOwoJYV9tb24gICA9IHJlYWRiKCZydGMtPmFsbW1vbik7CglhX3llYXIgID0gcmVhZGIoJnJ0Yy0+YWxteWVhcik7CglhX2FybWVkID0gcmVhZGIoJnJ0Yy0+cnRjYWxtKTsKCgkvKiBkaXNhYmxlIGFjY2VzcyB0byBSVEMgcmVnaXN0ZXJzICovCglTZXRSVENfQWNjZXNzKFJUQ19ESVNBQkxFKTsKCiNpZmRlZiBSVENfREVCVUcKCXByaW50ZigiR2V0IFJUQyB5ZWFyOiAlMDJ4IG1vbi9jZW50OiAlMDJ4IG1kYXk6ICUwMnggd2RheTogJTAyeCAiCgkgICAgICAgImhyOiAlMDJ4IG1pbjogJTAyeCBzZWM6ICUwMnhcbiIsCgkgICAgICAgeWVhciwgbW9uLCBtZGF5LCB3ZGF5LCBob3VyLCBtaW4sIHNlYyk7CglwcmludGYoIkFsYXJtczogJTAyeDogeWVhcjogJTAyeCBtb250aDogJTAyeCBkYXRlOiAlMDJ4IGhvdXI6ICIKCSAgICAgICAiJTAyeCBtaW46ICUwMnggc2VjOiAlMDJ4XG4iLAoJICAgICAgIGFfYXJtZWQsIGFfeWVhciwgYV9tb24sIGFfZGF0ZSwgYV9ob3VyLCBhX21pbiwgYV9zZWMpOwojZW5kaWYKCgl0bXAtPnRtX3NlYyAgPSBiY2QyYmluKHNlYyAmIDB4N0YpOwoJdG1wLT50bV9taW4gID0gYmNkMmJpbihtaW4gJiAweDdGKTsKCXRtcC0+dG1faG91ciA9IGJjZDJiaW4oaG91ciAmIDB4M0YpOwoJdG1wLT50bV9tZGF5ID0gYmNkMmJpbihtZGF5ICYgMHgzRik7Cgl0bXAtPnRtX21vbiAgPSBiY2QyYmluKG1vbiAmIDB4MUYpOwoJdG1wLT50bV95ZWFyID0gYmNkMmJpbih5ZWFyKTsKCXRtcC0+dG1fd2RheSA9IGJjZDJiaW4od2RheSAmIDB4MDcpOwoJaWYgKHRtcC0+dG1feWVhciA8IDcwKQoJCXRtcC0+dG1feWVhciArPSAyMDAwOwoJZWxzZQoJCXRtcC0+dG1feWVhciArPSAxOTAwOwoJdG1wLT50bV95ZGF5ICA9IDA7Cgl0bXAtPnRtX2lzZHN0ID0gMDsKI2lmZGVmIFJUQ19ERUJVRwoJcHJpbnRmKCJHZXQgREFURTogJTRkLSUwMmQtJTAyZCAod2RheT0lZCkgIFRJTUU6ICUyZDolMDJkOiUwMmRcbiIsCgkgICAgICAgdG1wLT50bV95ZWFyLCB0bXAtPnRtX21vbiwgdG1wLT50bV9tZGF5LCB0bXAtPnRtX3dkYXksCgkgICAgICAgdG1wLT50bV9ob3VyLCB0bXAtPnRtX21pbiwgdG1wLT50bV9zZWMpOwojZW5kaWYKCglyZXR1cm4gMDsKfQoKaW50IHJ0Y19zZXQoc3RydWN0IHJ0Y190aW1lICp0bXApCnsKCXN0cnVjdCBzM2MyNHgwX3J0YyAqcnRjID0gczNjMjR4MF9nZXRfYmFzZV9ydGMoKTsKCXVjaGFyIHNlYywgbWluLCBob3VyLCBtZGF5LCB3ZGF5LCBtb24sIHllYXI7CgojaWZkZWYgUlRDX0RFQlVHCglwcmludGYoIlNldCBEQVRFOiAlNGQtJTAyZC0lMDJkICh3ZGF5PSVkKSAgVElNRTogJTJkOiUwMmQ6JTAyZFxuIiwKCSAgICAgICB0bXAtPnRtX3llYXIsIHRtcC0+dG1fbW9uLCB0bXAtPnRtX21kYXksIHRtcC0+dG1fd2RheSwKCSAgICAgICB0bXAtPnRtX2hvdXIsIHRtcC0+dG1fbWluLCB0bXAtPnRtX3NlYyk7CiNlbmRpZgoJeWVhciA9IGJpbjJiY2QodG1wLT50bV95ZWFyICUgMTAwKTsKCW1vbiAgPSBiaW4yYmNkKHRtcC0+dG1fbW9uKTsKCXdkYXkgPSBiaW4yYmNkKHRtcC0+dG1fd2RheSk7CgltZGF5ID0gYmluMmJjZCh0bXAtPnRtX21kYXkpOwoJaG91ciA9IGJpbjJiY2QodG1wLT50bV9ob3VyKTsKCW1pbiAgPSBiaW4yYmNkKHRtcC0+dG1fbWluKTsKCXNlYyAgPSBiaW4yYmNkKHRtcC0+dG1fc2VjKTsKCgkvKiBlbmFibGUgYWNjZXNzIHRvIFJUQyByZWdpc3RlcnMgKi8KCVNldFJUQ19BY2Nlc3MoUlRDX0VOQUJMRSk7CgoJLyogd3JpdGUgUlRDIHJlZ2lzdGVycyAqLwoJd3JpdGViKHNlYywgJnJ0Yy0+YmNkc2VjKTsKCXdyaXRlYihtaW4sICZydGMtPmJjZG1pbik7Cgl3cml0ZWIoaG91ciwgJnJ0Yy0+YmNkaG91cik7Cgl3cml0ZWIobWRheSwgJnJ0Yy0+YmNkZGF0ZSk7Cgl3cml0ZWIod2RheSwgJnJ0Yy0+YmNkZGF5KTsKCXdyaXRlYihtb24sICZydGMtPmJjZG1vbik7Cgl3cml0ZWIoeWVhciwgJnJ0Yy0+YmNkeWVhcik7CgoJLyogZGlzYWJsZSBhY2Nlc3MgdG8gUlRDIHJlZ2lzdGVycyAqLwoJU2V0UlRDX0FjY2VzcyhSVENfRElTQUJMRSk7CgoJcmV0dXJuIDA7Cn0KCnZvaWQgcnRjX3Jlc2V0KHZvaWQpCnsKCXN0cnVjdCBzM2MyNHgwX3J0YyAqcnRjID0gczNjMjR4MF9nZXRfYmFzZV9ydGMoKTsKCgl3cml0ZWIoKHJlYWRiKCZydGMtPnJ0Y2NvbikgJiB+MHgwNikgfCAweDA4LCAmcnRjLT5ydGNjb24pOwoJd3JpdGViKHJlYWRiKCZydGMtPnJ0Y2NvbikgJiB+KDB4MDggfCAweDAxKSwgJnJ0Yy0+cnRjY29uKTsKfQoKI2VuZGlmCg==