LyoKICBTaW1wbGUgRGlyZWN0TWVkaWEgTGF5ZXIKICBDb3B5cmlnaHQgKEMpIDE5OTctMjAyMSBTYW0gTGFudGluZ2EgPHNsb3VrZW5AbGlic2RsLm9yZz4KCiAgVGhpcyBzb2Z0d2FyZSBpcyBwcm92aWRlZCAnYXMtaXMnLCB3aXRob3V0IGFueSBleHByZXNzIG9yIGltcGxpZWQKICB3YXJyYW50eS4gIEluIG5vIGV2ZW50IHdpbGwgdGhlIGF1dGhvcnMgYmUgaGVsZCBsaWFibGUgZm9yIGFueSBkYW1hZ2VzCiAgYXJpc2luZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS4KCiAgUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsCiAgaW5jbHVkaW5nIGNvbW1lcmNpYWwgYXBwbGljYXRpb25zLCBhbmQgdG8gYWx0ZXIgaXQgYW5kIHJlZGlzdHJpYnV0ZSBpdAogIGZyZWVseSwgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9uczoKCiAgMS4gVGhlIG9yaWdpbiBvZiB0aGlzIHNvZnR3YXJlIG11c3Qgbm90IGJlIG1pc3JlcHJlc2VudGVkOyB5b3UgbXVzdCBub3QKICAgICBjbGFpbSB0aGF0IHlvdSB3cm90ZSB0aGUgb3JpZ2luYWwgc29mdHdhcmUuIElmIHlvdSB1c2UgdGhpcyBzb2Z0d2FyZQogICAgIGluIGEgcHJvZHVjdCwgYW4gYWNrbm93bGVkZ21lbnQgaW4gdGhlIHByb2R1Y3QgZG9jdW1lbnRhdGlvbiB3b3VsZCBiZQogICAgIGFwcHJlY2lhdGVkIGJ1dCBpcyBub3QgcmVxdWlyZWQuCiAgMi4gQWx0ZXJlZCBzb3VyY2UgdmVyc2lvbnMgbXVzdCBiZSBwbGFpbmx5IG1hcmtlZCBhcyBzdWNoLCBhbmQgbXVzdCBub3QgYmUKICAgICBtaXNyZXByZXNlbnRlZCBhcyBiZWluZyB0aGUgb3JpZ2luYWwgc29mdHdhcmUuCiAgMy4gVGhpcyBub3RpY2UgbWF5IG5vdCBiZSByZW1vdmVkIG9yIGFsdGVyZWQgZnJvbSBhbnkgc291cmNlIGRpc3RyaWJ1dGlvbi4KKi8KI2luY2x1ZGUgIi4uLy4uL1NETF9pbnRlcm5hbC5oIgoKI2lmIFNETF9BVURJT19EUklWRVJfU1VOQVVESU8KCi8qIEFsbG93IGFjY2VzcyB0byBhIHJhdyBtaXhpbmcgYnVmZmVyICovCgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpZmRlZiBfX05FVEJTRF9fCiNpbmNsdWRlIDxzeXMvaW9jdGwuaD4KI2luY2x1ZGUgPHN5cy9hdWRpb2lvLmg+CiNlbmRpZgojaWZkZWYgX19TVlI0CiNpbmNsdWRlIDxzeXMvYXVkaW9pby5oPgojZWxzZQojaW5jbHVkZSA8c3lzL3RpbWUuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojZW5kaWYKI2luY2x1ZGUgPHVuaXN0ZC5oPgoKI2luY2x1ZGUgIlNETF90aW1lci5oIgojaW5jbHVkZSAiU0RMX2F1ZGlvLmgiCiNpbmNsdWRlICIuLi8uLi9jb3JlL3VuaXgvU0RMX3BvbGwuaCIKI2luY2x1ZGUgIi4uL1NETF9hdWRpb19jLmgiCiNpbmNsdWRlICIuLi9TRExfYXVkaW9kZXZfYy5oIgojaW5jbHVkZSAiU0RMX3N1bmF1ZGlvLmgiCgovKiBPcGVuIHRoZSBhdWRpbyBkZXZpY2UgZm9yIHBsYXliYWNrLCBhbmQgZG9uJ3QgYmxvY2sgaWYgYnVzeSAqLwoKI2lmIGRlZmluZWQoQVVESU9fR0VUSU5GTykgJiYgIWRlZmluZWQoQVVESU9fR0VUQlVGSU5GTykKI2RlZmluZSBBVURJT19HRVRCVUZJTkZPIEFVRElPX0dFVElORk8KI2VuZGlmCgovKiBBdWRpbyBkcml2ZXIgZnVuY3Rpb25zICovCnN0YXRpYyBVaW50OCBzbmQyYXUoaW50IHNhbXBsZSk7CgovKiBBdWRpbyBkcml2ZXIgYm9vdHN0cmFwIGZ1bmN0aW9ucyAqLwpzdGF0aWMgdm9pZApTVU5BVURJT19EZXRlY3REZXZpY2VzKHZvaWQpCnsKICAgIFNETF9FbnVtVW5peEF1ZGlvRGV2aWNlcygxLCAoaW50ICgqKShpbnQpKSBOVUxMKTsKfQoKI2lmZGVmIERFQlVHX0FVRElPCnZvaWQKQ2hlY2tVbmRlcmZsb3coX1RISVMpCnsKI2lmZGVmIEFVRElPX0dFVEJVRklORk8KICAgIGF1ZGlvX2luZm9fdCBpbmZvOwogICAgaW50IGxlZnQ7CgogICAgaW9jdGwodGhpcy0+aGlkZGVuLT5hdWRpb19mZCwgQVVESU9fR0VUQlVGSU5GTywgJmluZm8pOwogICAgbGVmdCA9ICh0aGlzLT5oaWRkZW4tPndyaXR0ZW4gLSBpbmZvLnBsYXkuc2FtcGxlcyk7CiAgICBpZiAodGhpcy0+aGlkZGVuLT53cml0dGVuICYmIChsZWZ0ID09IDApKSB7CiAgICAgICAgZnByaW50ZihzdGRlcnIsICJhdWRpbyB1bmRlcmZsb3chXG4iKTsKICAgIH0KI2VuZGlmCn0KI2VuZGlmCgpzdGF0aWMgdm9pZApTVU5BVURJT19XYWl0RGV2aWNlKF9USElTKQp7CiNpZmRlZiBBVURJT19HRVRCVUZJTkZPCiNkZWZpbmUgU0xFRVBfRlVER0UgMTAgICAgICAvKiAxMCBtcyBzY2hlZHVsaW5nIGZ1ZGdlIGZhY3RvciAqLwogICAgYXVkaW9faW5mb190IGluZm87CiAgICBTaW50MzIgbGVmdDsKCiAgICBpb2N0bCh0aGlzLT5oaWRkZW4tPmF1ZGlvX2ZkLCBBVURJT19HRVRCVUZJTkZPLCAmaW5mbyk7CiAgICBsZWZ0ID0gKHRoaXMtPmhpZGRlbi0+d3JpdHRlbiAtIGluZm8ucGxheS5zYW1wbGVzKTsKICAgIGlmIChsZWZ0ID4gdGhpcy0+aGlkZGVuLT5mcmFnc2l6ZSkgewogICAgICAgIFNpbnQzMiBzbGVlcHk7CgogICAgICAgIHNsZWVweSA9ICgobGVmdCAtIHRoaXMtPmhpZGRlbi0+ZnJhZ3NpemUpIC8gdGhpcy0+aGlkZGVuLT5mcmVxdWVuY3kpOwogICAgICAgIHNsZWVweSAtPSBTTEVFUF9GVURHRTsKICAgICAgICBpZiAoc2xlZXB5ID4gMCkgewogICAgICAgICAgICBTRExfRGVsYXkoc2xlZXB5KTsKICAgICAgICB9CiAgICB9CiNlbHNlCiAgICBTRExfSU9SZWFkeSh0aGlzLT5oaWRkZW4tPmF1ZGlvX2ZkLCBTRExfVFJVRSwgLTEpOwojZW5kaWYKfQoKc3RhdGljIHZvaWQKU1VOQVVESU9fUGxheURldmljZShfVEhJUykKewogICAgLyogV3JpdGUgdGhlIGF1ZGlvIGRhdGEgKi8KICAgIGlmICh0aGlzLT5oaWRkZW4tPnVsYXdfb25seSkgewogICAgICAgIC8qIEFzc3VtaW5nIHRoYXQgdGhpcy0+c3BlYy5mcmVxID49IDgwMDAgSHogKi8KICAgICAgICBpbnQgYWNjdW0sIGluY3IsIHBvczsKICAgICAgICBVaW50OCAqYXVidWY7CgogICAgICAgIGFjY3VtID0gMDsKICAgICAgICBpbmNyID0gdGhpcy0+c3BlYy5mcmVxIC8gODsKICAgICAgICBhdWJ1ZiA9IHRoaXMtPmhpZGRlbi0+dWxhd19idWY7CiAgICAgICAgc3dpdGNoICh0aGlzLT5oaWRkZW4tPmF1ZGlvX2ZtdCAmIDB4RkYpIHsKICAgICAgICBjYXNlIDg6CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFVpbnQ4ICpzbmRidWY7CgogICAgICAgICAgICAgICAgc25kYnVmID0gdGhpcy0+aGlkZGVuLT5taXhidWY7CiAgICAgICAgICAgICAgICBmb3IgKHBvcyA9IDA7IHBvcyA8IHRoaXMtPmhpZGRlbi0+ZnJhZ3NpemU7ICsrcG9zKSB7CiAgICAgICAgICAgICAgICAgICAgKmF1YnVmID0gc25kMmF1KCgweDgwIC0gKnNuZGJ1ZikgKiA2NCk7CiAgICAgICAgICAgICAgICAgICAgYWNjdW0gKz0gaW5jcjsKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoYWNjdW0gPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFjY3VtIC09IDEwMDA7CiAgICAgICAgICAgICAgICAgICAgICAgIHNuZGJ1ZiArPSAxOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBhdWJ1ZiArPSAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTY6CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFNpbnQxNiAqc25kYnVmOwoKICAgICAgICAgICAgICAgIHNuZGJ1ZiA9IChTaW50MTYgKikgdGhpcy0+aGlkZGVuLT5taXhidWY7CiAgICAgICAgICAgICAgICBmb3IgKHBvcyA9IDA7IHBvcyA8IHRoaXMtPmhpZGRlbi0+ZnJhZ3NpemU7ICsrcG9zKSB7CiAgICAgICAgICAgICAgICAgICAgKmF1YnVmID0gc25kMmF1KCpzbmRidWYgLyA0KTsKICAgICAgICAgICAgICAgICAgICBhY2N1bSArPSBpbmNyOwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChhY2N1bSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgYWNjdW0gLT0gMTAwMDsKICAgICAgICAgICAgICAgICAgICAgICAgc25kYnVmICs9IDE7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGF1YnVmICs9IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQojaWZkZWYgREVCVUdfQVVESU8KICAgICAgICBDaGVja1VuZGVyZmxvdyh0aGlzKTsKI2VuZGlmCiAgICAgICAgaWYgKHdyaXRlKHRoaXMtPmhpZGRlbi0+YXVkaW9fZmQsIHRoaXMtPmhpZGRlbi0+dWxhd19idWYsCiAgICAgICAgICAgIHRoaXMtPmhpZGRlbi0+ZnJhZ3NpemUpIDwgMCkgewogICAgICAgICAgICAvKiBBc3N1bWUgZmF0YWwgZXJyb3IsIGZvciBub3cgKi8KICAgICAgICAgICAgU0RMX09wZW5lZEF1ZGlvRGV2aWNlRGlzY29ubmVjdGVkKHRoaXMpOwogICAgICAgIH0KICAgICAgICB0aGlzLT5oaWRkZW4tPndyaXR0ZW4gKz0gdGhpcy0+aGlkZGVuLT5mcmFnc2l6ZTsKICAgIH0gZWxzZSB7CiNpZmRlZiBERUJVR19BVURJTwogICAgICAgIENoZWNrVW5kZXJmbG93KHRoaXMpOwojZW5kaWYKICAgICAgICBpZiAod3JpdGUodGhpcy0+aGlkZGVuLT5hdWRpb19mZCwgdGhpcy0+aGlkZGVuLT5taXhidWYsCiAgICAgICAgICAgIHRoaXMtPnNwZWMuc2l6ZSkgPCAwKSB7CiAgICAgICAgICAgIC8qIEFzc3VtZSBmYXRhbCBlcnJvciwgZm9yIG5vdyAqLwogICAgICAgICAgICBTRExfT3BlbmVkQXVkaW9EZXZpY2VEaXNjb25uZWN0ZWQodGhpcyk7CiAgICAgICAgfQogICAgICAgIHRoaXMtPmhpZGRlbi0+d3JpdHRlbiArPSB0aGlzLT5oaWRkZW4tPmZyYWdzaXplOwogICAgfQp9CgpzdGF0aWMgVWludDggKgpTVU5BVURJT19HZXREZXZpY2VCdWYoX1RISVMpCnsKICAgIHJldHVybiAodGhpcy0+aGlkZGVuLT5taXhidWYpOwp9CgpzdGF0aWMgdm9pZApTVU5BVURJT19DbG9zZURldmljZShfVEhJUykKewogICAgU0RMX2ZyZWUodGhpcy0+aGlkZGVuLT51bGF3X2J1Zik7CiAgICBpZiAodGhpcy0+aGlkZGVuLT5hdWRpb19mZCA+PSAwKSB7CiAgICAgICAgY2xvc2UodGhpcy0+aGlkZGVuLT5hdWRpb19mZCk7CiAgICB9CiAgICBTRExfZnJlZSh0aGlzLT5oaWRkZW4tPm1peGJ1Zik7CiAgICBTRExfZnJlZSh0aGlzLT5oaWRkZW4pOwp9CgpzdGF0aWMgaW50ClNVTkFVRElPX09wZW5EZXZpY2UoX1RISVMsIHZvaWQgKmhhbmRsZSwgY29uc3QgY2hhciAqZGV2bmFtZSwgaW50IGlzY2FwdHVyZSkKewojaWZkZWYgQVVESU9fU0VUSU5GTwogICAgaW50IGVuYzsKI2VuZGlmCiAgICBpbnQgZGVzaXJlZF9mcmVxID0gMDsKICAgIGNvbnN0IGludCBmbGFncyA9ICgoaXNjYXB0dXJlKSA/IE9QRU5fRkxBR1NfSU5QVVQgOiBPUEVOX0ZMQUdTX09VVFBVVCk7CiAgICBTRExfQXVkaW9Gb3JtYXQgZm9ybWF0ID0gMDsKICAgIGF1ZGlvX2luZm9fdCBpbmZvOwoKICAgIC8qIFdlIGRvbid0IGNhcmUgd2hhdCB0aGUgZGV2bmFtZSBpcy4uLndlJ2xsIHRyeSB0byBvcGVuIGFueXRoaW5nLiAqLwogICAgLyogIC4uLmJ1dCBkZWZhdWx0IHRvIGZpcnN0IG5hbWUgaW4gdGhlIGxpc3QuLi4gKi8KICAgIGlmIChkZXZuYW1lID09IE5VTEwpIHsKICAgICAgICBkZXZuYW1lID0gU0RMX0dldEF1ZGlvRGV2aWNlTmFtZSgwLCBpc2NhcHR1cmUpOwogICAgICAgIGlmIChkZXZuYW1lID09IE5VTEwpIHsKICAgICAgICAgICAgcmV0dXJuIFNETF9TZXRFcnJvcigiTm8gc3VjaCBhdWRpbyBkZXZpY2UiKTsKICAgICAgICB9CiAgICB9CgogICAgLyogSW5pdGlhbGl6ZSBhbGwgdmFyaWFibGVzIHRoYXQgd2UgY2xlYW4gb24gc2h1dGRvd24gKi8KICAgIHRoaXMtPmhpZGRlbiA9IChzdHJ1Y3QgU0RMX1ByaXZhdGVBdWRpb0RhdGEgKikKICAgICAgICBTRExfbWFsbG9jKChzaXplb2YgKnRoaXMtPmhpZGRlbikpOwogICAgaWYgKHRoaXMtPmhpZGRlbiA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIFNETF9PdXRPZk1lbW9yeSgpOwogICAgfQogICAgU0RMX3plcm9wKHRoaXMtPmhpZGRlbik7CgogICAgLyogT3BlbiB0aGUgYXVkaW8gZGV2aWNlICovCiAgICB0aGlzLT5oaWRkZW4tPmF1ZGlvX2ZkID0gb3BlbihkZXZuYW1lLCBmbGFncywgMCk7CiAgICBpZiAodGhpcy0+aGlkZGVuLT5hdWRpb19mZCA8IDApIHsKICAgICAgICByZXR1cm4gU0RMX1NldEVycm9yKCJDb3VsZG4ndCBvcGVuICVzOiAlcyIsIGRldm5hbWUsIHN0cmVycm9yKGVycm5vKSk7CiAgICB9CgogICAgZGVzaXJlZF9mcmVxID0gdGhpcy0+c3BlYy5mcmVxOwoKICAgIC8qIERldGVybWluZSB0aGUgYXVkaW8gcGFyYW1ldGVycyBmcm9tIHRoZSBBdWRpb1NwZWMgKi8KICAgIHN3aXRjaCAoU0RMX0FVRElPX0JJVFNJWkUodGhpcy0+c3BlYy5mb3JtYXQpKSB7CgogICAgY2FzZSA4OgogICAgICAgIHsgICAgICAgICAgICAgICAgICAgICAgIC8qIFVuc2lnbmVkIDggYml0IGF1ZGlvIGRhdGEgKi8KICAgICAgICAgICAgdGhpcy0+c3BlYy5mb3JtYXQgPSBBVURJT19VODsKI2lmZGVmIEFVRElPX1NFVElORk8KICAgICAgICAgICAgZW5jID0gQVVESU9fRU5DT0RJTkdfTElORUFSODsKI2VuZGlmCiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgMTY6CiAgICAgICAgeyAgICAgICAgICAgICAgICAgICAgICAgLyogU2lnbmVkIDE2IGJpdCBhdWRpbyBkYXRhICovCiAgICAgICAgICAgIHRoaXMtPnNwZWMuZm9ybWF0ID0gQVVESU9fUzE2U1lTOwojaWZkZWYgQVVESU9fU0VUSU5GTwogICAgICAgICAgICBlbmMgPSBBVURJT19FTkNPRElOR19MSU5FQVI7CiNlbmRpZgogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBkZWZhdWx0OgogICAgICAgIHsKICAgICAgICAgICAgLyogISEhIEZJWE1FOiBmYWxsYmFjayB0byBjb252ZXJzaW9uIG9uIHVuc3VwcG9ydGVkIHR5cGVzISAqLwogICAgICAgICAgICByZXR1cm4gU0RMX1NldEVycm9yKCJVbnN1cHBvcnRlZCBhdWRpbyBmb3JtYXQiKTsKICAgICAgICB9CiAgICB9CiAgICB0aGlzLT5oaWRkZW4tPmF1ZGlvX2ZtdCA9IHRoaXMtPnNwZWMuZm9ybWF0OwoKICAgIHRoaXMtPmhpZGRlbi0+dWxhd19vbmx5ID0gMDsgICAgLyogbW9kZXJuIFN1bnMgZG8gc3VwcG9ydCBsaW5lYXIgYXVkaW8gKi8KI2lmZGVmIEFVRElPX1NFVElORk8KICAgIGZvciAoOzspIHsKICAgICAgICBhdWRpb19pbmZvX3QgaW5mbzsKICAgICAgICBBVURJT19JTklUSU5GTygmaW5mbyk7ICAvKiBpbml0IGFsbCBmaWVsZHMgdG8gIm5vIGNoYW5nZSIgKi8KCiAgICAgICAgLyogVHJ5IHRvIHNldCB0aGUgcmVxdWVzdGVkIHNldHRpbmdzICovCiAgICAgICAgaW5mby5wbGF5LnNhbXBsZV9yYXRlID0gdGhpcy0+c3BlYy5mcmVxOwogICAgICAgIGluZm8ucGxheS5jaGFubmVscyA9IHRoaXMtPnNwZWMuY2hhbm5lbHM7CiAgICAgICAgaW5mby5wbGF5LnByZWNpc2lvbiA9IChlbmMgPT0gQVVESU9fRU5DT0RJTkdfVUxBVykKICAgICAgICAgICAgPyA4IDogdGhpcy0+c3BlYy5mb3JtYXQgJiAweGZmOwogICAgICAgIGluZm8ucGxheS5lbmNvZGluZyA9IGVuYzsKICAgICAgICBpZiAoaW9jdGwodGhpcy0+aGlkZGVuLT5hdWRpb19mZCwgQVVESU9fU0VUSU5GTywgJmluZm8pID09IDApIHsKCiAgICAgICAgICAgIC8qIENoZWNrIHRvIGJlIHN1cmUgd2UgZ290IHdoYXQgd2Ugd2FudGVkICovCiAgICAgICAgICAgIGlmIChpb2N0bCh0aGlzLT5oaWRkZW4tPmF1ZGlvX2ZkLCBBVURJT19HRVRJTkZPLCAmaW5mbykgPCAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gU0RMX1NldEVycm9yKCJFcnJvciBnZXR0aW5nIGF1ZGlvIHBhcmFtZXRlcnM6ICVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZXJyb3IoZXJybm8pKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaW5mby5wbGF5LmVuY29kaW5nID09IGVuYwogICAgICAgICAgICAgICAgJiYgaW5mby5wbGF5LnByZWNpc2lvbiA9PSAodGhpcy0+c3BlYy5mb3JtYXQgJiAweGZmKQogICAgICAgICAgICAgICAgJiYgaW5mby5wbGF5LmNoYW5uZWxzID09IHRoaXMtPnNwZWMuY2hhbm5lbHMpIHsKICAgICAgICAgICAgICAgIC8qIFlvdyEgQWxsIHNlZW1zIHRvIGJlIHdlbGwhICovCiAgICAgICAgICAgICAgICB0aGlzLT5zcGVjLmZyZXEgPSBpbmZvLnBsYXkuc2FtcGxlX3JhdGU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgc3dpdGNoIChlbmMpIHsKICAgICAgICBjYXNlIEFVRElPX0VOQ09ESU5HX0xJTkVBUjg6CiAgICAgICAgICAgIC8qIHVuc2lnbmVkIDhiaXQgYXBwYXJlbnRseSBub3Qgc3VwcG9ydGVkIGhlcmUgKi8KICAgICAgICAgICAgZW5jID0gQVVESU9fRU5DT0RJTkdfTElORUFSOwogICAgICAgICAgICB0aGlzLT5zcGVjLmZvcm1hdCA9IEFVRElPX1MxNlNZUzsKICAgICAgICAgICAgYnJlYWs7ICAgICAgICAgICAgICAvKiB0cnkgYWdhaW4gKi8KCiAgICAgICAgY2FzZSBBVURJT19FTkNPRElOR19MSU5FQVI6CiAgICAgICAgICAgIC8qIGxpbmVhciAxNmJpdCBkaWRuJ3Qgd29yayBlaXRoZXIsIHJlc29ydCB0byC1LWxhdyAqLwogICAgICAgICAgICBlbmMgPSBBVURJT19FTkNPRElOR19VTEFXOwogICAgICAgICAgICB0aGlzLT5zcGVjLmNoYW5uZWxzID0gMTsKICAgICAgICAgICAgdGhpcy0+c3BlYy5mcmVxID0gODAwMDsKICAgICAgICAgICAgdGhpcy0+c3BlYy5mb3JtYXQgPSBBVURJT19VODsKICAgICAgICAgICAgdGhpcy0+aGlkZGVuLT51bGF3X29ubHkgPSAxOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgLyogb2ggd2VsbC4uLiAqLwogICAgICAgICAgICByZXR1cm4gU0RMX1NldEVycm9yKCJFcnJvciBzZXR0aW5nIGF1ZGlvIHBhcmFtZXRlcnM6ICVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlcnJvcihlcnJubykpOwogICAgICAgIH0KICAgIH0KI2VuZGlmIC8qIEFVRElPX1NFVElORk8gKi8KICAgIHRoaXMtPmhpZGRlbi0+d3JpdHRlbiA9IDA7CgogICAgLyogV2UgY2FuIGFjdHVhbGx5IGNvbnZlcnQgb24tdGhlLWZseSB0byBVLUxhdyAqLwogICAgaWYgKHRoaXMtPmhpZGRlbi0+dWxhd19vbmx5KSB7CiAgICAgICAgdGhpcy0+c3BlYy5mcmVxID0gZGVzaXJlZF9mcmVxOwogICAgICAgIHRoaXMtPmhpZGRlbi0+ZnJhZ3NpemUgPSAodGhpcy0+c3BlYy5zYW1wbGVzICogMTAwMCkgLwogICAgICAgICAgICAodGhpcy0+c3BlYy5mcmVxIC8gOCk7CiAgICAgICAgdGhpcy0+aGlkZGVuLT5mcmVxdWVuY3kgPSA4OwogICAgICAgIHRoaXMtPmhpZGRlbi0+dWxhd19idWYgPSAoVWludDggKikgU0RMX21hbGxvYyh0aGlzLT5oaWRkZW4tPmZyYWdzaXplKTsKICAgICAgICBpZiAodGhpcy0+aGlkZGVuLT51bGF3X2J1ZiA9PSBOVUxMKSB7CiAgICAgICAgICAgIHJldHVybiBTRExfT3V0T2ZNZW1vcnkoKTsKICAgICAgICB9CiAgICAgICAgdGhpcy0+c3BlYy5jaGFubmVscyA9IDE7CiAgICB9IGVsc2UgewogICAgICAgIHRoaXMtPmhpZGRlbi0+ZnJhZ3NpemUgPSB0aGlzLT5zcGVjLnNhbXBsZXM7CiAgICAgICAgdGhpcy0+aGlkZGVuLT5mcmVxdWVuY3kgPSB0aGlzLT5zcGVjLmZyZXEgLyAxMDAwOwogICAgfQojaWZkZWYgREVCVUdfQVVESU8KICAgIGZwcmludGYoc3RkZXJyLCAiQXVkaW8gZGV2aWNlICVzIFUtTGF3IG9ubHlcbiIsCiAgICAgICAgICAgIHRoaXMtPmhpZGRlbi0+dWxhd19vbmx5ID8gImlzIiA6ICJpcyBub3QiKTsKICAgIGZwcmludGYoc3RkZXJyLCAiZm9ybWF0PTB4JXggY2hhbj0lZCBmcmVxPSVkXG4iLAogICAgICAgICAgICB0aGlzLT5zcGVjLmZvcm1hdCwgdGhpcy0+c3BlYy5jaGFubmVscywgdGhpcy0+c3BlYy5mcmVxKTsKI2VuZGlmCgogICAgLyogVXBkYXRlIHRoZSBmcmFnbWVudCBzaXplIGFzIHNpemUgaW4gYnl0ZXMgKi8KICAgIFNETF9DYWxjdWxhdGVBdWRpb1NwZWMoJnRoaXMtPnNwZWMpOwoKICAgIC8qIEFsbG9jYXRlIG1peGluZyBidWZmZXIgKi8KICAgIHRoaXMtPmhpZGRlbi0+bWl4YnVmID0gKFVpbnQ4ICopIFNETF9tYWxsb2ModGhpcy0+c3BlYy5zaXplKTsKICAgIGlmICh0aGlzLT5oaWRkZW4tPm1peGJ1ZiA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIFNETF9PdXRPZk1lbW9yeSgpOwogICAgfQogICAgU0RMX21lbXNldCh0aGlzLT5oaWRkZW4tPm1peGJ1ZiwgdGhpcy0+c3BlYy5zaWxlbmNlLCB0aGlzLT5zcGVjLnNpemUpOwoKICAgIC8qIFdlJ3JlIHJlYWR5IHRvIHJvY2sgYW5kIHJvbGwuIDotKSAqLwogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIFRoaXMgZnVuY3Rpb24gKHNuZDJhdSgpKSBjb3B5cmlnaHRlZDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qICAgICAgQ29weXJpZ2h0IDE5ODkgYnkgUmljaCBHb3BzdGVpbiBhbmQgSGFycmlzIENvcnBvcmF0aW9uICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSAgICovCi8qICAgICAgYW5kIGl0cyBkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZSBhbmQgd2l0aG91dCBmZWUgaXMgICAgICAgICovCi8qICAgICAgaGVyZWJ5IGdyYW50ZWQsIHByb3ZpZGVkIHRoYXQgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgICAgICAgICovCi8qICAgICAgYXBwZWFycyBpbiBhbGwgY29waWVzIGFuZCB0aGF0IGJvdGggdGhhdCBjb3B5cmlnaHQgbm90aWNlIGFuZCAgICovCi8qICAgICAgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gc3VwcG9ydGluZyBkb2N1bWVudGF0aW9uLCBhbmQgICovCi8qICAgICAgdGhhdCB0aGUgbmFtZSBvZiBSaWNoIEdvcHN0ZWluIGFuZCBIYXJyaXMgQ29ycG9yYXRpb24gbm90IGJlICAgICovCi8qICAgICAgdXNlZCBpbiBhZHZlcnRpc2luZyBvciBwdWJsaWNpdHkgcGVydGFpbmluZyB0byBkaXN0cmlidXRpb24gICAgICovCi8qICAgICAgb2YgdGhlIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMsIHdyaXR0ZW4gcHJpb3IgcGVybWlzc2lvbi4gICAgICovCi8qICAgICAgUmljaCBHb3BzdGVpbiBhbmQgSGFycmlzIENvcnBvcmF0aW9uIG1ha2Ugbm8gcmVwcmVzZW50YXRpb25zICAgICovCi8qICAgICAgYWJvdXQgdGhlIHN1aXRhYmlsaXR5IG9mIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiAgSXQgICAgICovCi8qICAgICAgcHJvdmlkZWQgImFzIGlzIiB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4gICAgICAgICAgICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgVWludDgKc25kMmF1KGludCBzYW1wbGUpCnsKCiAgICBpbnQgbWFzazsKCiAgICBpZiAoc2FtcGxlIDwgMCkgewogICAgICAgIHNhbXBsZSA9IC1zYW1wbGU7CiAgICAgICAgbWFzayA9IDB4N2Y7CiAgICB9IGVsc2UgewogICAgICAgIG1hc2sgPSAweGZmOwogICAgfQoKICAgIGlmIChzYW1wbGUgPCAzMikgewogICAgICAgIHNhbXBsZSA9IDB4RjAgfCAoMTUgLSBzYW1wbGUgLyAyKTsKICAgIH0gZWxzZSBpZiAoc2FtcGxlIDwgOTYpIHsKICAgICAgICBzYW1wbGUgPSAweEUwIHwgKDE1IC0gKHNhbXBsZSAtIDMyKSAvIDQpOwogICAgfSBlbHNlIGlmIChzYW1wbGUgPCAyMjQpIHsKICAgICAgICBzYW1wbGUgPSAweEQwIHwgKDE1IC0gKHNhbXBsZSAtIDk2KSAvIDgpOwogICAgfSBlbHNlIGlmIChzYW1wbGUgPCA0ODApIHsKICAgICAgICBzYW1wbGUgPSAweEMwIHwgKDE1IC0gKHNhbXBsZSAtIDIyNCkgLyAxNik7CiAgICB9IGVsc2UgaWYgKHNhbXBsZSA8IDk5MikgewogICAgICAgIHNhbXBsZSA9IDB4QjAgfCAoMTUgLSAoc2FtcGxlIC0gNDgwKSAvIDMyKTsKICAgIH0gZWxzZSBpZiAoc2FtcGxlIDwgMjAxNikgewogICAgICAgIHNhbXBsZSA9IDB4QTAgfCAoMTUgLSAoc2FtcGxlIC0gOTkyKSAvIDY0KTsKICAgIH0gZWxzZSBpZiAoc2FtcGxlIDwgNDA2NCkgewogICAgICAgIHNhbXBsZSA9IDB4OTAgfCAoMTUgLSAoc2FtcGxlIC0gMjAxNikgLyAxMjgpOwogICAgfSBlbHNlIGlmIChzYW1wbGUgPCA4MTYwKSB7CiAgICAgICAgc2FtcGxlID0gMHg4MCB8ICgxNSAtIChzYW1wbGUgLSA0MDY0KSAvIDI1Nik7CiAgICB9IGVsc2UgewogICAgICAgIHNhbXBsZSA9IDB4ODA7CiAgICB9CiAgICByZXR1cm4gKG1hc2sgJiBzYW1wbGUpOwp9CgpzdGF0aWMgaW50ClNVTkFVRElPX0luaXQoU0RMX0F1ZGlvRHJpdmVySW1wbCAqIGltcGwpCnsKICAgIC8qIFNldCB0aGUgZnVuY3Rpb24gcG9pbnRlcnMgKi8KICAgIGltcGwtPkRldGVjdERldmljZXMgPSBTVU5BVURJT19EZXRlY3REZXZpY2VzOwogICAgaW1wbC0+T3BlbkRldmljZSA9IFNVTkFVRElPX09wZW5EZXZpY2U7CiAgICBpbXBsLT5QbGF5RGV2aWNlID0gU1VOQVVESU9fUGxheURldmljZTsKICAgIGltcGwtPldhaXREZXZpY2UgPSBTVU5BVURJT19XYWl0RGV2aWNlOwogICAgaW1wbC0+R2V0RGV2aWNlQnVmID0gU1VOQVVESU9fR2V0RGV2aWNlQnVmOwogICAgaW1wbC0+Q2xvc2VEZXZpY2UgPSBTVU5BVURJT19DbG9zZURldmljZTsKCiAgICBpbXBsLT5BbGxvd3NBcmJpdHJhcnlEZXZpY2VOYW1lcyA9IDE7CgogICAgcmV0dXJuIDE7IC8qIHRoaXMgYXVkaW8gdGFyZ2V0IGlzIGF2YWlsYWJsZS4gKi8KfQoKQXVkaW9Cb290U3RyYXAgU1VOQVVESU9fYm9vdHN0cmFwID0gewogICAgImF1ZGlvIiwgIlVOSVggL2Rldi9hdWRpbyBpbnRlcmZhY2UiLCBTVU5BVURJT19Jbml0LCAwCn07CgojZW5kaWYgLyogU0RMX0FVRElPX0RSSVZFUl9TVU5BVURJTyAqLwoKLyogdmk6IHNldCB0cz00IHN3PTQgZXhwYW5kdGFiOiAqLwo=