LyoKICogUUVNVSBGbG9wcHkgZGlzayBlbXVsYXRvciAoSW50ZWwgODIwNzgpCiAqCiAqIENvcHlyaWdodCAoYykgMjAwMywgMjAwNyBKb2NlbHluIE1heWVyCiAqIENvcHlyaWdodCAoYykgMjAwOCBIZXJ26SBQb3Vzc2luZWF1CiAqCiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKICogaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cwogKiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCiAqIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcwogKiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgogKgogKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbgogKiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1IKICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMCiAqIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSCiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sCiAqIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4KICogVEhFIFNPRlRXQVJFLgogKi8KLyoKICogVGhlIGNvbnRyb2xsZXIgaXMgdXNlZCBpbiBTdW40bSBzeXN0ZW1zIGluIGEgc2xpZ2h0bHkgZGlmZmVyZW50CiAqIHdheS4gVGhlcmUgYXJlIGNoYW5nZXMgaW4gRE9SIHJlZ2lzdGVyIGFuZCBETUEgaXMgbm90IGF2YWlsYWJsZS4KICovCgojaW5jbHVkZSAiaHcuaCIKI2luY2x1ZGUgImZkYy5oIgojaW5jbHVkZSAiYmxvY2suaCIKI2luY2x1ZGUgInFlbXUtdGltZXIuaCIKI2luY2x1ZGUgImlzYS5oIgojaW5jbHVkZSAic3lzYnVzLmgiCiNpbmNsdWRlICJxZGV2LWFkZHIuaCIKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogZGVidWcgRmxvcHB5IGRldmljZXMgKi8KLy8jZGVmaW5lIERFQlVHX0ZMT1BQWQoKI2lmZGVmIERFQlVHX0ZMT1BQWQojZGVmaW5lIEZMT1BQWV9EUFJJTlRGKGZtdCwgLi4uKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgZG8geyBwcmludGYoIkZMT1BQWTogIiBmbXQgLCAjIyBfX1ZBX0FSR1NfXyk7IH0gd2hpbGUgKDApCiNlbHNlCiNkZWZpbmUgRkxPUFBZX0RQUklOVEYoZm10LCAuLi4pCiNlbmRpZgoKI2RlZmluZSBGTE9QUFlfRVJST1IoZm10LCAuLi4pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgZG8geyBwcmludGYoIkZMT1BQWSBFUlJPUjogJXM6ICIgZm10LCBfX2Z1bmNfXyAsICMjIF9fVkFfQVJHU19fKTsgfSB3aGlsZSAoMCkKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogRmxvcHB5IGRyaXZlIGVtdWxhdGlvbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwoKI2RlZmluZSBHRVRfQ1VSX0RSVihmZGN0cmwpICgoZmRjdHJsKS0+Y3VyX2RydikKI2RlZmluZSBTRVRfQ1VSX0RSVihmZGN0cmwsIGRyaXZlKSAoKGZkY3RybCktPmN1cl9kcnYgPSAoZHJpdmUpKQoKLyogV2lsbCBhbHdheXMgYmUgYSBmaXhlZCBwYXJhbWV0ZXIgZm9yIHVzICovCiNkZWZpbmUgRkRfU0VDVE9SX0xFTiAgICAgICAgICA1MTIKI2RlZmluZSBGRF9TRUNUT1JfU0MgICAgICAgICAgIDIgICAvKiBTZWN0b3Igc2l6ZSBjb2RlICovCiNkZWZpbmUgRkRfUkVTRVRfU0VOU0VJX0NPVU5UICA0ICAgLyogTnVtYmVyIG9mIHNlbnNlIGludGVycnVwdHMgb24gUkVTRVQgKi8KCi8qIEZsb3BweSBkaXNrIGRyaXZlIGVtdWxhdGlvbiAqLwp0eXBlZGVmIGVudW0gZmRpc2tfdHlwZV90IHsKICAgIEZEUklWRV9ESVNLXzI4OCAgID0gMHgwMSwgLyogMi44OCBNQiBkaXNrICAgICAgICAgICAqLwogICAgRkRSSVZFX0RJU0tfMTQ0ICAgPSAweDAyLCAvKiAxLjQ0IE1CIGRpc2sgICAgICAgICAgICovCiAgICBGRFJJVkVfRElTS183MjAgICA9IDB4MDMsIC8qIDcyMCBrQiBkaXNrICAgICAgICAgICAgKi8KICAgIEZEUklWRV9ESVNLX1VTRVIgID0gMHgwNCwgLyogVXNlciBkZWZpbmVkIGdlb21ldHJ5ICAqLwogICAgRkRSSVZFX0RJU0tfTk9ORSAgPSAweDA1LCAvKiBObyBkaXNrICAgICAgICAgICAgICAgICovCn0gZmRpc2tfdHlwZV90OwoKdHlwZWRlZiBlbnVtIGZkcml2ZV90eXBlX3QgewogICAgRkRSSVZFX0RSVl8xNDQgID0gMHgwMCwgICAvKiAxLjQ0IE1CIDMiNSBkcml2ZSAgICAgICovCiAgICBGRFJJVkVfRFJWXzI4OCAgPSAweDAxLCAgIC8qIDIuODggTUIgMyI1IGRyaXZlICAgICAgKi8KICAgIEZEUklWRV9EUlZfMTIwICA9IDB4MDIsICAgLyogMS4yICBNQiA1IjI1IGRyaXZlICAgICAqLwogICAgRkRSSVZFX0RSVl9OT05FID0gMHgwMywgICAvKiBObyBkcml2ZSBjb25uZWN0ZWQgICAgICovCn0gZmRyaXZlX3R5cGVfdDsKCnR5cGVkZWYgZW51bSBmZGlza19mbGFnc190IHsKICAgIEZESVNLX0RCTF9TSURFUyAgPSAweDAxLAp9IGZkaXNrX2ZsYWdzX3Q7Cgp0eXBlZGVmIHN0cnVjdCBmZHJpdmVfdCB7CiAgICBCbG9ja0RyaXZlclN0YXRlICpiczsKICAgIC8qIERyaXZlIHN0YXR1cyAqLwogICAgZmRyaXZlX3R5cGVfdCBkcml2ZTsKICAgIHVpbnQ4X3QgcGVycGVuZGljdWxhcjsgICAgLyogMi44OCBNQiBhY2Nlc3MgbW9kZSAgICAqLwogICAgLyogUG9zaXRpb24gKi8KICAgIHVpbnQ4X3QgaGVhZDsKICAgIHVpbnQ4X3QgdHJhY2s7CiAgICB1aW50OF90IHNlY3Q7CiAgICAvKiBNZWRpYSAqLwogICAgZmRpc2tfZmxhZ3NfdCBmbGFnczsKICAgIHVpbnQ4X3QgbGFzdF9zZWN0OyAgICAgICAgLyogTmIgc2VjdG9yIHBlciB0cmFjayAgICAqLwogICAgdWludDhfdCBtYXhfdHJhY2s7ICAgICAgICAvKiBOYiBvZiB0cmFja3MgICAgICAgICAgICovCiAgICB1aW50MTZfdCBicHM7ICAgICAgICAgICAgIC8qIEJ5dGVzIHBlciBzZWN0b3IgICAgICAgKi8KICAgIHVpbnQ4X3Qgcm87ICAgICAgICAgICAgICAgLyogSXMgcmVhZC1vbmx5ICAgICAgICAgICAqLwp9IGZkcml2ZV90OwoKc3RhdGljIHZvaWQgZmRfaW5pdCAoZmRyaXZlX3QgKmRydiwgQmxvY2tEcml2ZXJTdGF0ZSAqYnMpCnsKICAgIC8qIERyaXZlICovCiAgICBkcnYtPmJzID0gYnM7CiAgICBkcnYtPmRyaXZlID0gRkRSSVZFX0RSVl9OT05FOwogICAgZHJ2LT5wZXJwZW5kaWN1bGFyID0gMDsKICAgIC8qIERpc2sgKi8KICAgIGRydi0+bGFzdF9zZWN0ID0gMDsKICAgIGRydi0+bWF4X3RyYWNrID0gMDsKfQoKc3RhdGljIGludCBfZmRfc2VjdG9yICh1aW50OF90IGhlYWQsIHVpbnQ4X3QgdHJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgdWludDhfdCBzZWN0LCB1aW50OF90IGxhc3Rfc2VjdCkKewogICAgcmV0dXJuICgoKHRyYWNrICogMikgKyBoZWFkKSAqIGxhc3Rfc2VjdCkgKyBzZWN0IC0gMTsKfQoKLyogUmV0dXJucyBjdXJyZW50IHBvc2l0aW9uLCBpbiBzZWN0b3JzLCBmb3IgZ2l2ZW4gZHJpdmUgKi8Kc3RhdGljIGludCBmZF9zZWN0b3IgKGZkcml2ZV90ICpkcnYpCnsKICAgIHJldHVybiBfZmRfc2VjdG9yKGRydi0+aGVhZCwgZHJ2LT50cmFjaywgZHJ2LT5zZWN0LCBkcnYtPmxhc3Rfc2VjdCk7Cn0KCi8qIFNlZWsgdG8gYSBuZXcgcG9zaXRpb246CiAqIHJldHVybnMgMCBpZiBhbHJlYWR5IG9uIHJpZ2h0IHRyYWNrCiAqIHJldHVybnMgMSBpZiB0cmFjayBjaGFuZ2VkCiAqIHJldHVybnMgMiBpZiB0cmFjayBpcyBpbnZhbGlkCiAqIHJldHVybnMgMyBpZiBzZWN0b3IgaXMgaW52YWxpZAogKiByZXR1cm5zIDQgaWYgc2VlayBpcyBkaXNhYmxlZAogKi8Kc3RhdGljIGludCBmZF9zZWVrIChmZHJpdmVfdCAqZHJ2LCB1aW50OF90IGhlYWQsIHVpbnQ4X3QgdHJhY2ssIHVpbnQ4X3Qgc2VjdCwKICAgICAgICAgICAgICAgICAgICBpbnQgZW5hYmxlX3NlZWspCnsKICAgIHVpbnQzMl90IHNlY3RvcjsKICAgIGludCByZXQ7CgogICAgaWYgKHRyYWNrID4gZHJ2LT5tYXhfdHJhY2sgfHwKICAgICAgICAoaGVhZCAhPSAwICYmIChkcnYtPmZsYWdzICYgRkRJU0tfREJMX1NJREVTKSA9PSAwKSkgewogICAgICAgIEZMT1BQWV9EUFJJTlRGKCJ0cnkgdG8gcmVhZCAlZCAlMDJ4ICUwMnggKG1heD0lZCAlZCAlMDJ4ICUwMngpXG4iLAogICAgICAgICAgICAgICAgICAgICAgIGhlYWQsIHRyYWNrLCBzZWN0LCAxLAogICAgICAgICAgICAgICAgICAgICAgIChkcnYtPmZsYWdzICYgRkRJU0tfREJMX1NJREVTKSA9PSAwID8gMCA6IDEsCiAgICAgICAgICAgICAgICAgICAgICAgZHJ2LT5tYXhfdHJhY2ssIGRydi0+bGFzdF9zZWN0KTsKICAgICAgICByZXR1cm4gMjsKICAgIH0KICAgIGlmIChzZWN0ID4gZHJ2LT5sYXN0X3NlY3QpIHsKICAgICAgICBGTE9QUFlfRFBSSU5URigidHJ5IHRvIHJlYWQgJWQgJTAyeCAlMDJ4IChtYXg9JWQgJWQgJTAyeCAlMDJ4KVxuIiwKICAgICAgICAgICAgICAgICAgICAgICBoZWFkLCB0cmFjaywgc2VjdCwgMSwKICAgICAgICAgICAgICAgICAgICAgICAoZHJ2LT5mbGFncyAmIEZESVNLX0RCTF9TSURFUykgPT0gMCA/IDAgOiAxLAogICAgICAgICAgICAgICAgICAgICAgIGRydi0+bWF4X3RyYWNrLCBkcnYtPmxhc3Rfc2VjdCk7CiAgICAgICAgcmV0dXJuIDM7CiAgICB9CiAgICBzZWN0b3IgPSBfZmRfc2VjdG9yKGhlYWQsIHRyYWNrLCBzZWN0LCBkcnYtPmxhc3Rfc2VjdCk7CiAgICByZXQgPSAwOwogICAgaWYgKHNlY3RvciAhPSBmZF9zZWN0b3IoZHJ2KSkgewojaWYgMAogICAgICAgIGlmICghZW5hYmxlX3NlZWspIHsKICAgICAgICAgICAgRkxPUFBZX0VSUk9SKCJubyBpbXBsaWNpdCBzZWVrICVkICUwMnggJTAyeCAobWF4PSVkICUwMnggJTAyeClcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICBoZWFkLCB0cmFjaywgc2VjdCwgMSwgZHJ2LT5tYXhfdHJhY2ssIGRydi0+bGFzdF9zZWN0KTsKICAgICAgICAgICAgcmV0dXJuIDQ7CiAgICAgICAgfQojZW5kaWYKICAgICAgICBkcnYtPmhlYWQgPSBoZWFkOwogICAgICAgIGlmIChkcnYtPnRyYWNrICE9IHRyYWNrKQogICAgICAgICAgICByZXQgPSAxOwogICAgICAgIGRydi0+dHJhY2sgPSB0cmFjazsKICAgICAgICBkcnYtPnNlY3QgPSBzZWN0OwogICAgfQoKICAgIHJldHVybiByZXQ7Cn0KCi8qIFNldCBkcml2ZSBiYWNrIHRvIHRyYWNrIDAgKi8Kc3RhdGljIHZvaWQgZmRfcmVjYWxpYnJhdGUgKGZkcml2ZV90ICpkcnYpCnsKICAgIEZMT1BQWV9EUFJJTlRGKCJyZWNhbGlicmF0ZVxuIik7CiAgICBkcnYtPmhlYWQgPSAwOwogICAgZHJ2LT50cmFjayA9IDA7CiAgICBkcnYtPnNlY3QgPSAxOwp9CgovKiBSZWNvZ25pemUgZmxvcHB5IGZvcm1hdHMgKi8KdHlwZWRlZiBzdHJ1Y3QgZmRfZm9ybWF0X3QgewogICAgZmRyaXZlX3R5cGVfdCBkcml2ZTsKICAgIGZkaXNrX3R5cGVfdCAgZGlzazsKICAgIHVpbnQ4X3QgbGFzdF9zZWN0OwogICAgdWludDhfdCBtYXhfdHJhY2s7CiAgICB1aW50OF90IG1heF9oZWFkOwogICAgY29uc3QgY2hhciAqc3RyOwp9IGZkX2Zvcm1hdF90OwoKc3RhdGljIGNvbnN0IGZkX2Zvcm1hdF90IGZkX2Zvcm1hdHNbXSA9IHsKICAgIC8qIEZpcnN0IGVudHJ5IGlzIGRlZmF1bHQgZm9ybWF0ICovCiAgICAvKiAxLjQ0IE1CIDMiMS8yIGZsb3BweSBkaXNrcyAqLwogICAgeyBGRFJJVkVfRFJWXzE0NCwgRkRSSVZFX0RJU0tfMTQ0LCAxOCwgODAsIDEsICIxLjQ0IE1CIDNcIjEvMiIsIH0sCiAgICB7IEZEUklWRV9EUlZfMTQ0LCBGRFJJVkVfRElTS18xNDQsIDIwLCA4MCwgMSwgICIxLjYgTUIgM1wiMS8yIiwgfSwKICAgIHsgRkRSSVZFX0RSVl8xNDQsIEZEUklWRV9ESVNLXzE0NCwgMjEsIDgwLCAxLCAiMS42OCBNQiAzXCIxLzIiLCB9LAogICAgeyBGRFJJVkVfRFJWXzE0NCwgRkRSSVZFX0RJU0tfMTQ0LCAyMSwgODIsIDEsICIxLjcyIE1CIDNcIjEvMiIsIH0sCiAgICB7IEZEUklWRV9EUlZfMTQ0LCBGRFJJVkVfRElTS18xNDQsIDIxLCA4MywgMSwgIjEuNzQgTUIgM1wiMS8yIiwgfSwKICAgIHsgRkRSSVZFX0RSVl8xNDQsIEZEUklWRV9ESVNLXzE0NCwgMjIsIDgwLCAxLCAiMS43NiBNQiAzXCIxLzIiLCB9LAogICAgeyBGRFJJVkVfRFJWXzE0NCwgRkRSSVZFX0RJU0tfMTQ0LCAyMywgODAsIDEsICIxLjg0IE1CIDNcIjEvMiIsIH0sCiAgICB7IEZEUklWRV9EUlZfMTQ0LCBGRFJJVkVfRElTS18xNDQsIDI0LCA4MCwgMSwgIjEuOTIgTUIgM1wiMS8yIiwgfSwKICAgIC8qIDIuODggTUIgMyIxLzIgZmxvcHB5IGRpc2tzICovCiAgICB7IEZEUklWRV9EUlZfMjg4LCBGRFJJVkVfRElTS18yODgsIDM2LCA4MCwgMSwgIjIuODggTUIgM1wiMS8yIiwgfSwKICAgIHsgRkRSSVZFX0RSVl8yODgsIEZEUklWRV9ESVNLXzI4OCwgMzksIDgwLCAxLCAiMy4xMiBNQiAzXCIxLzIiLCB9LAogICAgeyBGRFJJVkVfRFJWXzI4OCwgRkRSSVZFX0RJU0tfMjg4LCA0MCwgODAsIDEsICAiMy4yIE1CIDNcIjEvMiIsIH0sCiAgICB7IEZEUklWRV9EUlZfMjg4LCBGRFJJVkVfRElTS18yODgsIDQ0LCA4MCwgMSwgIjMuNTIgTUIgM1wiMS8yIiwgfSwKICAgIHsgRkRSSVZFX0RSVl8yODgsIEZEUklWRV9ESVNLXzI4OCwgNDgsIDgwLCAxLCAiMy44NCBNQiAzXCIxLzIiLCB9LAogICAgLyogNzIwIGtCIDMiMS8yIGZsb3BweSBkaXNrcyAqLwogICAgeyBGRFJJVkVfRFJWXzE0NCwgRkRSSVZFX0RJU0tfNzIwLCAgOSwgODAsIDEsICAiNzIwIGtCIDNcIjEvMiIsIH0sCiAgICB7IEZEUklWRV9EUlZfMTQ0LCBGRFJJVkVfRElTS183MjAsIDEwLCA4MCwgMSwgICI4MDAga0IgM1wiMS8yIiwgfSwKICAgIHsgRkRSSVZFX0RSVl8xNDQsIEZEUklWRV9ESVNLXzcyMCwgMTAsIDgyLCAxLCAgIjgyMCBrQiAzXCIxLzIiLCB9LAogICAgeyBGRFJJVkVfRFJWXzE0NCwgRkRSSVZFX0RJU0tfNzIwLCAxMCwgODMsIDEsICAiODMwIGtCIDNcIjEvMiIsIH0sCiAgICB7IEZEUklWRV9EUlZfMTQ0LCBGRFJJVkVfRElTS183MjAsIDEzLCA4MCwgMSwgIjEuMDQgTUIgM1wiMS8yIiwgfSwKICAgIHsgRkRSSVZFX0RSVl8xNDQsIEZEUklWRV9ESVNLXzcyMCwgMTQsIDgwLCAxLCAiMS4xMiBNQiAzXCIxLzIiLCB9LAogICAgLyogMS4yIE1CIDUiMS80IGZsb3BweSBkaXNrcyAqLwogICAgeyBGRFJJVkVfRFJWXzEyMCwgRkRSSVZFX0RJU0tfMjg4LCAxNSwgODAsIDEsICAiMS4yIGtCIDVcIjEvNCIsIH0sCiAgICB7IEZEUklWRV9EUlZfMTIwLCBGRFJJVkVfRElTS18yODgsIDE4LCA4MCwgMSwgIjEuNDQgTUIgNVwiMS80IiwgfSwKICAgIHsgRkRSSVZFX0RSVl8xMjAsIEZEUklWRV9ESVNLXzI4OCwgMTgsIDgyLCAxLCAiMS40OCBNQiA1XCIxLzQiLCB9LAogICAgeyBGRFJJVkVfRFJWXzEyMCwgRkRSSVZFX0RJU0tfMjg4LCAxOCwgODMsIDEsICIxLjQ5IE1CIDVcIjEvNCIsIH0sCiAgICB7IEZEUklWRV9EUlZfMTIwLCBGRFJJVkVfRElTS18yODgsIDIwLCA4MCwgMSwgICIxLjYgTUIgNVwiMS80IiwgfSwKICAgIC8qIDcyMCBrQiA1IjEvNCBmbG9wcHkgZGlza3MgKi8KICAgIHsgRkRSSVZFX0RSVl8xMjAsIEZEUklWRV9ESVNLXzI4OCwgIDksIDgwLCAxLCAgIjcyMCBrQiA1XCIxLzQiLCB9LAogICAgeyBGRFJJVkVfRFJWXzEyMCwgRkRSSVZFX0RJU0tfMjg4LCAxMSwgODAsIDEsICAiODgwIGtCIDVcIjEvNCIsIH0sCiAgICAvKiAzNjAga0IgNSIxLzQgZmxvcHB5IGRpc2tzICovCiAgICB7IEZEUklWRV9EUlZfMTIwLCBGRFJJVkVfRElTS18yODgsICA5LCA0MCwgMSwgICIzNjAga0IgNVwiMS80IiwgfSwKICAgIHsgRkRSSVZFX0RSVl8xMjAsIEZEUklWRV9ESVNLXzI4OCwgIDksIDQwLCAwLCAgIjE4MCBrQiA1XCIxLzQiLCB9LAogICAgeyBGRFJJVkVfRFJWXzEyMCwgRkRSSVZFX0RJU0tfMjg4LCAxMCwgNDEsIDEsICAiNDEwIGtCIDVcIjEvNCIsIH0sCiAgICB7IEZEUklWRV9EUlZfMTIwLCBGRFJJVkVfRElTS18yODgsIDEwLCA0MiwgMSwgICI0MjAga0IgNVwiMS80IiwgfSwKICAgIC8qIDMyMCBrQiA1IjEvNCBmbG9wcHkgZGlza3MgKi8KICAgIHsgRkRSSVZFX0RSVl8xMjAsIEZEUklWRV9ESVNLXzI4OCwgIDgsIDQwLCAxLCAgIjMyMCBrQiA1XCIxLzQiLCB9LAogICAgeyBGRFJJVkVfRFJWXzEyMCwgRkRSSVZFX0RJU0tfMjg4LCAgOCwgNDAsIDAsICAiMTYwIGtCIDVcIjEvNCIsIH0sCiAgICAvKiAzNjAga0IgbXVzdCBtYXRjaCA1IjEvNCBiZXR0ZXIgdGhhbiAzIjEvMi4uLiAqLwogICAgeyBGRFJJVkVfRFJWXzE0NCwgRkRSSVZFX0RJU0tfNzIwLCAgOSwgODAsIDAsICAiMzYwIGtCIDNcIjEvMiIsIH0sCiAgICAvKiBlbmQgKi8KICAgIHsgRkRSSVZFX0RSVl9OT05FLCBGRFJJVkVfRElTS19OT05FLCAtMSwgLTEsIDAsIE5VTEwsIH0sCn07CgovKiBSZXZhbGlkYXRlIGEgZGlzayBkcml2ZSBhZnRlciBhIGRpc2sgY2hhbmdlICovCnN0YXRpYyB2b2lkIGZkX3JldmFsaWRhdGUgKGZkcml2ZV90ICpkcnYpCnsKICAgIGNvbnN0IGZkX2Zvcm1hdF90ICpwYXJzZTsKICAgIHVpbnQ2NF90IG5iX3NlY3RvcnMsIHNpemU7CiAgICBpbnQgaSwgZmlyc3RfbWF0Y2gsIG1hdGNoOwogICAgaW50IG5iX2hlYWRzLCBtYXhfdHJhY2ssIGxhc3Rfc2VjdCwgcm87CgogICAgRkxPUFBZX0RQUklOVEYoInJldmFsaWRhdGVcbiIpOwogICAgaWYgKGRydi0+YnMgIT0gTlVMTCAmJiBiZHJ2X2lzX2luc2VydGVkKGRydi0+YnMpKSB7CiAgICAgICAgcm8gPSBiZHJ2X2lzX3JlYWRfb25seShkcnYtPmJzKTsKICAgICAgICBiZHJ2X2dldF9nZW9tZXRyeV9oaW50KGRydi0+YnMsICZuYl9oZWFkcywgJm1heF90cmFjaywgJmxhc3Rfc2VjdCk7CiAgICAgICAgaWYgKG5iX2hlYWRzICE9IDAgJiYgbWF4X3RyYWNrICE9IDAgJiYgbGFzdF9zZWN0ICE9IDApIHsKICAgICAgICAgICAgRkxPUFBZX0RQUklOVEYoIlVzZXIgZGVmaW5lZCBkaXNrICglZCAlZCAlZCkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICBuYl9oZWFkcyAtIDEsIG1heF90cmFjaywgbGFzdF9zZWN0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBiZHJ2X2dldF9nZW9tZXRyeShkcnYtPmJzLCAmbmJfc2VjdG9ycyk7CiAgICAgICAgICAgIG1hdGNoID0gLTE7CiAgICAgICAgICAgIGZpcnN0X21hdGNoID0gLTE7CiAgICAgICAgICAgIGZvciAoaSA9IDA7OyBpKyspIHsKICAgICAgICAgICAgICAgIHBhcnNlID0gJmZkX2Zvcm1hdHNbaV07CiAgICAgICAgICAgICAgICBpZiAocGFyc2UtPmRyaXZlID09IEZEUklWRV9EUlZfTk9ORSkKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGlmIChkcnYtPmRyaXZlID09IHBhcnNlLT5kcml2ZSB8fAogICAgICAgICAgICAgICAgICAgIGRydi0+ZHJpdmUgPT0gRkRSSVZFX0RSVl9OT05FKSB7CiAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IChwYXJzZS0+bWF4X2hlYWQgKyAxKSAqIHBhcnNlLT5tYXhfdHJhY2sgKgogICAgICAgICAgICAgICAgICAgICAgICBwYXJzZS0+bGFzdF9zZWN0OwogICAgICAgICAgICAgICAgICAgIGlmIChuYl9zZWN0b3JzID09IHNpemUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2ggPSBpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKGZpcnN0X21hdGNoID09IC0xKQogICAgICAgICAgICAgICAgICAgICAgICBmaXJzdF9tYXRjaCA9IGk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKG1hdGNoID09IC0xKSB7CiAgICAgICAgICAgICAgICBpZiAoZmlyc3RfbWF0Y2ggPT0gLTEpCiAgICAgICAgICAgICAgICAgICAgbWF0Y2ggPSAxOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIG1hdGNoID0gZmlyc3RfbWF0Y2g7CiAgICAgICAgICAgICAgICBwYXJzZSA9ICZmZF9mb3JtYXRzW21hdGNoXTsKICAgICAgICAgICAgfQogICAgICAgICAgICBuYl9oZWFkcyA9IHBhcnNlLT5tYXhfaGVhZCArIDE7CiAgICAgICAgICAgIG1heF90cmFjayA9IHBhcnNlLT5tYXhfdHJhY2s7CiAgICAgICAgICAgIGxhc3Rfc2VjdCA9IHBhcnNlLT5sYXN0X3NlY3Q7CiAgICAgICAgICAgIGRydi0+ZHJpdmUgPSBwYXJzZS0+ZHJpdmU7CiAgICAgICAgICAgIEZMT1BQWV9EUFJJTlRGKCIlcyBmbG9wcHkgZGlzayAoJWQgaCAlZCB0ICVkIHMpICVzXG4iLCBwYXJzZS0+c3RyLAogICAgICAgICAgICAgICAgICAgICAgICAgICBuYl9oZWFkcywgbWF4X3RyYWNrLCBsYXN0X3NlY3QsIHJvID8gInJvIiA6ICJydyIpOwogICAgICAgIH0KICAgICAgICBpZiAobmJfaGVhZHMgPT0gMSkgewogICAgICAgICAgICBkcnYtPmZsYWdzICY9IH5GRElTS19EQkxfU0lERVM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZHJ2LT5mbGFncyB8PSBGRElTS19EQkxfU0lERVM7CiAgICAgICAgfQogICAgICAgIGRydi0+bWF4X3RyYWNrID0gbWF4X3RyYWNrOwogICAgICAgIGRydi0+bGFzdF9zZWN0ID0gbGFzdF9zZWN0OwogICAgICAgIGRydi0+cm8gPSBybzsKICAgIH0gZWxzZSB7CiAgICAgICAgRkxPUFBZX0RQUklOVEYoIk5vIGRpc2sgaW4gZHJpdmVcbiIpOwogICAgICAgIGRydi0+bGFzdF9zZWN0ID0gMDsKICAgICAgICBkcnYtPm1heF90cmFjayA9IDA7CiAgICAgICAgZHJ2LT5mbGFncyAmPSB+RkRJU0tfREJMX1NJREVTOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIEludGVsIDgyMDc4IGZsb3BweSBkaXNrIGNvbnRyb2xsZXIgZW11bGF0aW9uICAgICAgICAgICovCgpzdGF0aWMgdm9pZCBmZGN0cmxfcmVzZXQgKGZkY3RybF90ICpmZGN0cmwsIGludCBkb19pcnEpOwpzdGF0aWMgdm9pZCBmZGN0cmxfcmVzZXRfZmlmbyAoZmRjdHJsX3QgKmZkY3RybCk7CnN0YXRpYyBpbnQgZmRjdHJsX3RyYW5zZmVyX2hhbmRsZXIgKHZvaWQgKm9wYXF1ZSwgaW50IG5jaGFuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZG1hX3BvcywgaW50IGRtYV9sZW4pOwpzdGF0aWMgdm9pZCBmZGN0cmxfcmFpc2VfaXJxIChmZGN0cmxfdCAqZmRjdHJsLCB1aW50OF90IHN0YXR1czApOwoKc3RhdGljIHVpbnQzMl90IGZkY3RybF9yZWFkX3N0YXR1c0EgKGZkY3RybF90ICpmZGN0cmwpOwpzdGF0aWMgdWludDMyX3QgZmRjdHJsX3JlYWRfc3RhdHVzQiAoZmRjdHJsX3QgKmZkY3RybCk7CnN0YXRpYyB1aW50MzJfdCBmZGN0cmxfcmVhZF9kb3IgKGZkY3RybF90ICpmZGN0cmwpOwpzdGF0aWMgdm9pZCBmZGN0cmxfd3JpdGVfZG9yIChmZGN0cmxfdCAqZmRjdHJsLCB1aW50MzJfdCB2YWx1ZSk7CnN0YXRpYyB1aW50MzJfdCBmZGN0cmxfcmVhZF90YXBlIChmZGN0cmxfdCAqZmRjdHJsKTsKc3RhdGljIHZvaWQgZmRjdHJsX3dyaXRlX3RhcGUgKGZkY3RybF90ICpmZGN0cmwsIHVpbnQzMl90IHZhbHVlKTsKc3RhdGljIHVpbnQzMl90IGZkY3RybF9yZWFkX21haW5fc3RhdHVzIChmZGN0cmxfdCAqZmRjdHJsKTsKc3RhdGljIHZvaWQgZmRjdHJsX3dyaXRlX3JhdGUgKGZkY3RybF90ICpmZGN0cmwsIHVpbnQzMl90IHZhbHVlKTsKc3RhdGljIHVpbnQzMl90IGZkY3RybF9yZWFkX2RhdGEgKGZkY3RybF90ICpmZGN0cmwpOwpzdGF0aWMgdm9pZCBmZGN0cmxfd3JpdGVfZGF0YSAoZmRjdHJsX3QgKmZkY3RybCwgdWludDMyX3QgdmFsdWUpOwpzdGF0aWMgdWludDMyX3QgZmRjdHJsX3JlYWRfZGlyIChmZGN0cmxfdCAqZmRjdHJsKTsKCmVudW0gewogICAgRkRfRElSX1dSSVRFICAgPSAwLAogICAgRkRfRElSX1JFQUQgICAgPSAxLAogICAgRkRfRElSX1NDQU5FICAgPSAyLAogICAgRkRfRElSX1NDQU5MICAgPSAzLAogICAgRkRfRElSX1NDQU5IICAgPSA0LAp9OwoKZW51bSB7CiAgICBGRF9TVEFURV9NVUxUSSAgPSAweDAxLAkvKiBtdWx0aSB0cmFjayBmbGFnICovCiAgICBGRF9TVEFURV9GT1JNQVQgPSAweDAyLAkvKiBmb3JtYXQgZmxhZyAqLwogICAgRkRfU1RBVEVfU0VFSyAgID0gMHgwNCwJLyogc2VlayBmbGFnICovCn07CgplbnVtIHsKICAgIEZEX1JFR19TUkEgPSAweDAwLAogICAgRkRfUkVHX1NSQiA9IDB4MDEsCiAgICBGRF9SRUdfRE9SID0gMHgwMiwKICAgIEZEX1JFR19URFIgPSAweDAzLAogICAgRkRfUkVHX01TUiA9IDB4MDQsCiAgICBGRF9SRUdfRFNSID0gMHgwNCwKICAgIEZEX1JFR19GSUZPID0gMHgwNSwKICAgIEZEX1JFR19ESVIgPSAweDA3LAp9OwoKZW51bSB7CiAgICBGRF9DTURfUkVBRF9UUkFDSyA9IDB4MDIsCiAgICBGRF9DTURfU1BFQ0lGWSA9IDB4MDMsCiAgICBGRF9DTURfU0VOU0VfRFJJVkVfU1RBVFVTID0gMHgwNCwKICAgIEZEX0NNRF9XUklURSA9IDB4MDUsCiAgICBGRF9DTURfUkVBRCA9IDB4MDYsCiAgICBGRF9DTURfUkVDQUxJQlJBVEUgPSAweDA3LAogICAgRkRfQ01EX1NFTlNFX0lOVEVSUlVQVF9TVEFUVVMgPSAweDA4LAogICAgRkRfQ01EX1dSSVRFX0RFTEVURUQgPSAweDA5LAogICAgRkRfQ01EX1JFQURfSUQgPSAweDBhLAogICAgRkRfQ01EX1JFQURfREVMRVRFRCA9IDB4MGMsCiAgICBGRF9DTURfRk9STUFUX1RSQUNLID0gMHgwZCwKICAgIEZEX0NNRF9EVU1QUkVHID0gMHgwZSwKICAgIEZEX0NNRF9TRUVLID0gMHgwZiwKICAgIEZEX0NNRF9WRVJTSU9OID0gMHgxMCwKICAgIEZEX0NNRF9TQ0FOX0VRVUFMID0gMHgxMSwKICAgIEZEX0NNRF9QRVJQRU5ESUNVTEFSX01PREUgPSAweDEyLAogICAgRkRfQ01EX0NPTkZJR1VSRSA9IDB4MTMsCiAgICBGRF9DTURfTE9DSyA9IDB4MTQsCiAgICBGRF9DTURfVkVSSUZZID0gMHgxNiwKICAgIEZEX0NNRF9QT1dFUkRPV05fTU9ERSA9IDB4MTcsCiAgICBGRF9DTURfUEFSVF9JRCA9IDB4MTgsCiAgICBGRF9DTURfU0NBTl9MT1dfT1JfRVFVQUwgPSAweDE5LAogICAgRkRfQ01EX1NDQU5fSElHSF9PUl9FUVVBTCA9IDB4MWQsCiAgICBGRF9DTURfU0FWRSA9IDB4MmMsCiAgICBGRF9DTURfT1BUSU9OID0gMHgzMywKICAgIEZEX0NNRF9SRVNUT1JFID0gMHg0YywKICAgIEZEX0NNRF9EUklWRV9TUEVDSUZJQ0FUSU9OX0NPTU1BTkQgPSAweDhlLAogICAgRkRfQ01EX1JFTEFUSVZFX1NFRUtfT1VUID0gMHg4ZiwKICAgIEZEX0NNRF9GT1JNQVRfQU5EX1dSSVRFID0gMHhjZCwKICAgIEZEX0NNRF9SRUxBVElWRV9TRUVLX0lOID0gMHhjZiwKfTsKCmVudW0gewogICAgRkRfQ09ORklHX1BSRVRSSyA9IDB4ZmYsIC8qIFByZS1jb21wZW5zYXRpb24gc2V0IHRvIHRyYWNrIDAgKi8KICAgIEZEX0NPTkZJR19GSUZPVEhSID0gMHgwZiwgLyogRklGTyB0aHJlc2hvbGQgc2V0IHRvIDEgYnl0ZSAqLwogICAgRkRfQ09ORklHX1BPTEwgID0gMHgxMCwgLyogUG9sbCBlbmFibGVkICovCiAgICBGRF9DT05GSUdfRUZJRk8gPSAweDIwLCAvKiBGSUZPIGRpc2FibGVkICovCiAgICBGRF9DT05GSUdfRUlTICAgPSAweDQwLCAvKiBObyBpbXBsaWVkIHNlZWtzICovCn07CgplbnVtIHsKICAgIEZEX1NSMF9FUVBNVCAgICA9IDB4MTAsCiAgICBGRF9TUjBfU0VFSyAgICAgPSAweDIwLAogICAgRkRfU1IwX0FCTlRFUk0gID0gMHg0MCwKICAgIEZEX1NSMF9JTlZDTUQgICA9IDB4ODAsCiAgICBGRF9TUjBfUkRZQ0hHICAgPSAweGMwLAp9OwoKZW51bSB7CiAgICBGRF9TUjFfRUMgICAgICAgPSAweDgwLCAvKiBFbmQgb2YgY3lsaW5kZXIgKi8KfTsKCmVudW0gewogICAgRkRfU1IyX1NOUyAgICAgID0gMHgwNCwgLyogU2NhbiBub3Qgc2F0aXNmaWVkICovCiAgICBGRF9TUjJfU0VIICAgICAgPSAweDA4LCAvKiBTY2FuIGVxdWFsIGhpdCAqLwp9OwoKZW51bSB7CiAgICBGRF9TUkFfRElSICAgICAgPSAweDAxLAogICAgRkRfU1JBX25XUCAgICAgID0gMHgwMiwKICAgIEZEX1NSQV9uSU5EWCAgICA9IDB4MDQsCiAgICBGRF9TUkFfSERTRUwgICAgPSAweDA4LAogICAgRkRfU1JBX25UUkswICAgID0gMHgxMCwKICAgIEZEX1NSQV9TVEVQICAgICA9IDB4MjAsCiAgICBGRF9TUkFfbkRSVjIgICAgPSAweDQwLAogICAgRkRfU1JBX0lOVFBFTkQgID0gMHg4MCwKfTsKCmVudW0gewogICAgRkRfU1JCX01UUjAgICAgID0gMHgwMSwKICAgIEZEX1NSQl9NVFIxICAgICA9IDB4MDIsCiAgICBGRF9TUkJfV0dBVEUgICAgPSAweDA0LAogICAgRkRfU1JCX1JEQVRBICAgID0gMHgwOCwKICAgIEZEX1NSQl9XREFUQSAgICA9IDB4MTAsCiAgICBGRF9TUkJfRFIwICAgICAgPSAweDIwLAp9OwoKZW51bSB7CiNpZiBNQVhfRkQgPT0gNAogICAgRkRfRE9SX1NFTE1BU0sgID0gMHgwMywKI2Vsc2UKICAgIEZEX0RPUl9TRUxNQVNLICA9IDB4MDEsCiNlbmRpZgogICAgRkRfRE9SX25SRVNFVCAgID0gMHgwNCwKICAgIEZEX0RPUl9ETUFFTiAgICA9IDB4MDgsCiAgICBGRF9ET1JfTU9URU4wICAgPSAweDEwLAogICAgRkRfRE9SX01PVEVOMSAgID0gMHgyMCwKICAgIEZEX0RPUl9NT1RFTjIgICA9IDB4NDAsCiAgICBGRF9ET1JfTU9URU4zICAgPSAweDgwLAp9OwoKZW51bSB7CiNpZiBNQVhfRkQgPT0gNAogICAgRkRfVERSX0JPT1RTRUwgID0gMHgwYywKI2Vsc2UKICAgIEZEX1REUl9CT09UU0VMICA9IDB4MDQsCiNlbmRpZgp9OwoKZW51bSB7CiAgICBGRF9EU1JfRFJBVEVNQVNLPSAweDAzLAogICAgRkRfRFNSX1BXUkRPV04gID0gMHg0MCwKICAgIEZEX0RTUl9TV1JFU0VUICA9IDB4ODAsCn07CgplbnVtIHsKICAgIEZEX01TUl9EUlYwQlVTWSA9IDB4MDEsCiAgICBGRF9NU1JfRFJWMUJVU1kgPSAweDAyLAogICAgRkRfTVNSX0RSVjJCVVNZID0gMHgwNCwKICAgIEZEX01TUl9EUlYzQlVTWSA9IDB4MDgsCiAgICBGRF9NU1JfQ01EQlVTWSAgPSAweDEwLAogICAgRkRfTVNSX05PTkRNQSAgID0gMHgyMCwKICAgIEZEX01TUl9ESU8gICAgICA9IDB4NDAsCiAgICBGRF9NU1JfUlFNICAgICAgPSAweDgwLAp9OwoKZW51bSB7CiAgICBGRF9ESVJfRFNLQ0hHICAgPSAweDgwLAp9OwoKI2RlZmluZSBGRF9NVUxUSV9UUkFDSyhzdGF0ZSkgKChzdGF0ZSkgJiBGRF9TVEFURV9NVUxUSSkKI2RlZmluZSBGRF9ESURfU0VFSyhzdGF0ZSkgKChzdGF0ZSkgJiBGRF9TVEFURV9TRUVLKQojZGVmaW5lIEZEX0ZPUk1BVF9DTUQoc3RhdGUpICgoc3RhdGUpICYgRkRfU1RBVEVfRk9STUFUKQoKc3RydWN0IGZkY3RybF90IHsKICAgIC8qIENvbnRyb2xsZXIncyBpZGVudGlmaWNhdGlvbiAqLwogICAgdWludDhfdCB2ZXJzaW9uOwogICAgLyogSFcgKi8KICAgIHFlbXVfaXJxIGlycTsKICAgIGludCBkbWFfY2hhbm47CiAgICAvKiBDb250cm9sbGVyIHN0YXRlICovCiAgICBRRU1VVGltZXIgKnJlc3VsdF90aW1lcjsKICAgIHVpbnQ4X3Qgc3JhOwogICAgdWludDhfdCBzcmI7CiAgICB1aW50OF90IGRvcjsKICAgIHVpbnQ4X3QgdGRyOwogICAgdWludDhfdCBkc3I7CiAgICB1aW50OF90IG1zcjsKICAgIHVpbnQ4X3QgY3VyX2RydjsKICAgIHVpbnQ4X3Qgc3RhdHVzMDsKICAgIHVpbnQ4X3Qgc3RhdHVzMTsKICAgIHVpbnQ4X3Qgc3RhdHVzMjsKICAgIC8qIENvbW1hbmQgRklGTyAqLwogICAgdWludDhfdCAqZmlmbzsKICAgIHVpbnQzMl90IGRhdGFfcG9zOwogICAgdWludDMyX3QgZGF0YV9sZW47CiAgICB1aW50OF90IGRhdGFfc3RhdGU7CiAgICB1aW50OF90IGRhdGFfZGlyOwogICAgdWludDhfdCBlb3Q7IC8qIGxhc3Qgd2FudGVkIHNlY3RvciAqLwogICAgLyogU3RhdGVzIGtlcHQgb25seSB0byBiZSByZXR1cm5lZCBiYWNrICovCiAgICAvKiBUaW1lcnMgc3RhdGUgKi8KICAgIHVpbnQ4X3QgdGltZXIwOwogICAgdWludDhfdCB0aW1lcjE7CiAgICAvKiBwcmVjb21wZW5zYXRpb24gKi8KICAgIHVpbnQ4X3QgcHJlY29tcF90cms7CiAgICB1aW50OF90IGNvbmZpZzsKICAgIHVpbnQ4X3QgbG9jazsKICAgIC8qIFBvd2VyIGRvd24gY29uZmlnIChhbHNvIHdpdGggc3RhdHVzIHJlZ0IgYWNjZXNzIG1vZGUgKi8KICAgIHVpbnQ4X3QgcHdyZDsKICAgIC8qIFN1bjRtIHF1aXJrcz8gKi8KICAgIGludCBzdW40bTsKICAgIC8qIEZsb3BweSBkcml2ZXMgKi8KICAgIGZkcml2ZV90IGRyaXZlc1tNQVhfRkRdOwogICAgaW50IHJlc2V0X3NlbnNlaTsKfTsKCnR5cGVkZWYgc3RydWN0IGZkY3RybF9zeXNidXNfdCB7CiAgICBTeXNCdXNEZXZpY2UgYnVzZGV2OwogICAgc3RydWN0IGZkY3RybF90IHN0YXRlOwp9IGZkY3RybF9zeXNidXNfdDsKCnR5cGVkZWYgc3RydWN0IGZkY3RybF9pc2FidXNfdCB7CiAgICBJU0FEZXZpY2UgYnVzZGV2OwogICAgc3RydWN0IGZkY3RybF90IHN0YXRlOwp9IGZkY3RybF9pc2FidXNfdDsKCnN0YXRpYyB1aW50MzJfdCBmZGN0cmxfcmVhZCAodm9pZCAqb3BhcXVlLCB1aW50MzJfdCByZWcpCnsKICAgIGZkY3RybF90ICpmZGN0cmwgPSBvcGFxdWU7CiAgICB1aW50MzJfdCByZXR2YWw7CgogICAgc3dpdGNoIChyZWcpIHsKICAgIGNhc2UgRkRfUkVHX1NSQToKICAgICAgICByZXR2YWwgPSBmZGN0cmxfcmVhZF9zdGF0dXNBKGZkY3RybCk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEZEX1JFR19TUkI6CiAgICAgICAgcmV0dmFsID0gZmRjdHJsX3JlYWRfc3RhdHVzQihmZGN0cmwpOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBGRF9SRUdfRE9SOgogICAgICAgIHJldHZhbCA9IGZkY3RybF9yZWFkX2RvcihmZGN0cmwpOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBGRF9SRUdfVERSOgogICAgICAgIHJldHZhbCA9IGZkY3RybF9yZWFkX3RhcGUoZmRjdHJsKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgRkRfUkVHX01TUjoKICAgICAgICByZXR2YWwgPSBmZGN0cmxfcmVhZF9tYWluX3N0YXR1cyhmZGN0cmwpOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBGRF9SRUdfRklGTzoKICAgICAgICByZXR2YWwgPSBmZGN0cmxfcmVhZF9kYXRhKGZkY3RybCk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEZEX1JFR19ESVI6CiAgICAgICAgcmV0dmFsID0gZmRjdHJsX3JlYWRfZGlyKGZkY3RybCk7CiAgICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICAgIHJldHZhbCA9ICh1aW50MzJfdCkoLTEpOwogICAgICAgIGJyZWFrOwogICAgfQogICAgRkxPUFBZX0RQUklOVEYoInJlYWQgcmVnJWQ6IDB4JTAyeFxuIiwgcmVnICYgNywgcmV0dmFsKTsKCiAgICByZXR1cm4gcmV0dmFsOwp9CgpzdGF0aWMgdm9pZCBmZGN0cmxfd3JpdGUgKHZvaWQgKm9wYXF1ZSwgdWludDMyX3QgcmVnLCB1aW50MzJfdCB2YWx1ZSkKewogICAgZmRjdHJsX3QgKmZkY3RybCA9IG9wYXF1ZTsKCiAgICBGTE9QUFlfRFBSSU5URigid3JpdGUgcmVnJWQ6IDB4JTAyeFxuIiwgcmVnICYgNywgdmFsdWUpOwoKICAgIHN3aXRjaCAocmVnKSB7CiAgICBjYXNlIEZEX1JFR19ET1I6CiAgICAgICAgZmRjdHJsX3dyaXRlX2RvcihmZGN0cmwsIHZhbHVlKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgRkRfUkVHX1REUjoKICAgICAgICBmZGN0cmxfd3JpdGVfdGFwZShmZGN0cmwsIHZhbHVlKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgRkRfUkVHX0RTUjoKICAgICAgICBmZGN0cmxfd3JpdGVfcmF0ZShmZGN0cmwsIHZhbHVlKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgRkRfUkVHX0ZJRk86CiAgICAgICAgZmRjdHJsX3dyaXRlX2RhdGEoZmRjdHJsLCB2YWx1ZSk7CiAgICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICAgIGJyZWFrOwogICAgfQp9CgpzdGF0aWMgdWludDMyX3QgZmRjdHJsX3JlYWRfcG9ydCAodm9pZCAqb3BhcXVlLCB1aW50MzJfdCByZWcpCnsKICAgIHJldHVybiBmZGN0cmxfcmVhZChvcGFxdWUsIHJlZyAmIDcpOwp9CgpzdGF0aWMgdm9pZCBmZGN0cmxfd3JpdGVfcG9ydCAodm9pZCAqb3BhcXVlLCB1aW50MzJfdCByZWcsIHVpbnQzMl90IHZhbHVlKQp7CiAgICBmZGN0cmxfd3JpdGUob3BhcXVlLCByZWcgJiA3LCB2YWx1ZSk7Cn0KCnN0YXRpYyB1aW50MzJfdCBmZGN0cmxfcmVhZF9tZW0gKHZvaWQgKm9wYXF1ZSwgdGFyZ2V0X3BoeXNfYWRkcl90IHJlZykKewogICAgcmV0dXJuIGZkY3RybF9yZWFkKG9wYXF1ZSwgKHVpbnQzMl90KXJlZyk7Cn0KCnN0YXRpYyB2b2lkIGZkY3RybF93cml0ZV9tZW0gKHZvaWQgKm9wYXF1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0X3BoeXNfYWRkcl90IHJlZywgdWludDMyX3QgdmFsdWUpCnsKICAgIGZkY3RybF93cml0ZShvcGFxdWUsICh1aW50MzJfdClyZWcsIHZhbHVlKTsKfQoKc3RhdGljIENQVVJlYWRNZW1vcnlGdW5jICpmZGN0cmxfbWVtX3JlYWRbM10gPSB7CiAgICBmZGN0cmxfcmVhZF9tZW0sCiAgICBmZGN0cmxfcmVhZF9tZW0sCiAgICBmZGN0cmxfcmVhZF9tZW0sCn07CgpzdGF0aWMgQ1BVV3JpdGVNZW1vcnlGdW5jICpmZGN0cmxfbWVtX3dyaXRlWzNdID0gewogICAgZmRjdHJsX3dyaXRlX21lbSwKICAgIGZkY3RybF93cml0ZV9tZW0sCiAgICBmZGN0cmxfd3JpdGVfbWVtLAp9OwoKc3RhdGljIENQVVJlYWRNZW1vcnlGdW5jICpmZGN0cmxfbWVtX3JlYWRfc3RyaWN0WzNdID0gewogICAgZmRjdHJsX3JlYWRfbWVtLAogICAgTlVMTCwKICAgIE5VTEwsCn07CgpzdGF0aWMgQ1BVV3JpdGVNZW1vcnlGdW5jICpmZGN0cmxfbWVtX3dyaXRlX3N0cmljdFszXSA9IHsKICAgIGZkY3RybF93cml0ZV9tZW0sCiAgICBOVUxMLAogICAgTlVMTCwKfTsKCnN0YXRpYyB2b2lkIGZkX3NhdmUgKFFFTVVGaWxlICpmLCBmZHJpdmVfdCAqZmQpCnsKICAgIHFlbXVfcHV0XzhzKGYsICZmZC0+aGVhZCk7CiAgICBxZW11X3B1dF84cyhmLCAmZmQtPnRyYWNrKTsKICAgIHFlbXVfcHV0XzhzKGYsICZmZC0+c2VjdCk7Cn0KCnN0YXRpYyB2b2lkIGZkY19zYXZlIChRRU1VRmlsZSAqZiwgdm9pZCAqb3BhcXVlKQp7CiAgICBmZGN0cmxfdCAqcyA9IG9wYXF1ZTsKICAgIHVpbnQ4X3QgdG1wOwogICAgaW50IGk7CiAgICB1aW50OF90IGRvciA9IHMtPmRvciB8IEdFVF9DVVJfRFJWKHMpOwoKICAgIC8qIENvbnRyb2xsZXIgc3RhdGUgKi8KICAgIHFlbXVfcHV0XzhzKGYsICZzLT5zcmEpOwogICAgcWVtdV9wdXRfOHMoZiwgJnMtPnNyYik7CiAgICBxZW11X3B1dF84cyhmLCAmZG9yKTsKICAgIHFlbXVfcHV0XzhzKGYsICZzLT50ZHIpOwogICAgcWVtdV9wdXRfOHMoZiwgJnMtPmRzcik7CiAgICBxZW11X3B1dF84cyhmLCAmcy0+bXNyKTsKICAgIHFlbXVfcHV0XzhzKGYsICZzLT5zdGF0dXMwKTsKICAgIHFlbXVfcHV0XzhzKGYsICZzLT5zdGF0dXMxKTsKICAgIHFlbXVfcHV0XzhzKGYsICZzLT5zdGF0dXMyKTsKICAgIC8qIENvbW1hbmQgRklGTyAqLwogICAgcWVtdV9wdXRfYnVmZmVyKGYsIHMtPmZpZm8sIEZEX1NFQ1RPUl9MRU4pOwogICAgcWVtdV9wdXRfYmUzMnMoZiwgJnMtPmRhdGFfcG9zKTsKICAgIHFlbXVfcHV0X2JlMzJzKGYsICZzLT5kYXRhX2xlbik7CiAgICBxZW11X3B1dF84cyhmLCAmcy0+ZGF0YV9zdGF0ZSk7CiAgICBxZW11X3B1dF84cyhmLCAmcy0+ZGF0YV9kaXIpOwogICAgcWVtdV9wdXRfOHMoZiwgJnMtPmVvdCk7CiAgICAvKiBTdGF0ZXMga2VwdCBvbmx5IHRvIGJlIHJldHVybmVkIGJhY2sgKi8KICAgIHFlbXVfcHV0XzhzKGYsICZzLT50aW1lcjApOwogICAgcWVtdV9wdXRfOHMoZiwgJnMtPnRpbWVyMSk7CiAgICBxZW11X3B1dF84cyhmLCAmcy0+cHJlY29tcF90cmspOwogICAgcWVtdV9wdXRfOHMoZiwgJnMtPmNvbmZpZyk7CiAgICBxZW11X3B1dF84cyhmLCAmcy0+bG9jayk7CiAgICBxZW11X3B1dF84cyhmLCAmcy0+cHdyZCk7CgogICAgdG1wID0gTUFYX0ZEOwogICAgcWVtdV9wdXRfOHMoZiwgJnRtcCk7CiAgICBmb3IgKGkgPSAwOyBpIDwgTUFYX0ZEOyBpKyspCiAgICAgICAgZmRfc2F2ZShmLCAmcy0+ZHJpdmVzW2ldKTsKfQoKc3RhdGljIGludCBmZF9sb2FkIChRRU1VRmlsZSAqZiwgZmRyaXZlX3QgKmZkKQp7CiAgICBxZW11X2dldF84cyhmLCAmZmQtPmhlYWQpOwogICAgcWVtdV9nZXRfOHMoZiwgJmZkLT50cmFjayk7CiAgICBxZW11X2dldF84cyhmLCAmZmQtPnNlY3QpOwoKICAgIHJldHVybiAwOwp9CgpzdGF0aWMgaW50IGZkY19sb2FkIChRRU1VRmlsZSAqZiwgdm9pZCAqb3BhcXVlLCBpbnQgdmVyc2lvbl9pZCkKewogICAgZmRjdHJsX3QgKnMgPSBvcGFxdWU7CiAgICBpbnQgaSwgcmV0ID0gMDsKICAgIHVpbnQ4X3QgbjsKCiAgICBpZiAodmVyc2lvbl9pZCAhPSAyKQogICAgICAgIHJldHVybiAtRUlOVkFMOwoKICAgIC8qIENvbnRyb2xsZXIgc3RhdGUgKi8KICAgIHFlbXVfZ2V0XzhzKGYsICZzLT5zcmEpOwogICAgcWVtdV9nZXRfOHMoZiwgJnMtPnNyYik7CiAgICBxZW11X2dldF84cyhmLCAmcy0+ZG9yKTsKICAgIFNFVF9DVVJfRFJWKHMsIHMtPmRvciAmIEZEX0RPUl9TRUxNQVNLKTsKICAgIHMtPmRvciAmPSB+RkRfRE9SX1NFTE1BU0s7CiAgICBxZW11X2dldF84cyhmLCAmcy0+dGRyKTsKICAgIHFlbXVfZ2V0XzhzKGYsICZzLT5kc3IpOwogICAgcWVtdV9nZXRfOHMoZiwgJnMtPm1zcik7CiAgICBxZW11X2dldF84cyhmLCAmcy0+c3RhdHVzMCk7CiAgICBxZW11X2dldF84cyhmLCAmcy0+c3RhdHVzMSk7CiAgICBxZW11X2dldF84cyhmLCAmcy0+c3RhdHVzMik7CiAgICAvKiBDb21tYW5kIEZJRk8gKi8KICAgIHFlbXVfZ2V0X2J1ZmZlcihmLCBzLT5maWZvLCBGRF9TRUNUT1JfTEVOKTsKICAgIHFlbXVfZ2V0X2JlMzJzKGYsICZzLT5kYXRhX3Bvcyk7CiAgICBxZW11X2dldF9iZTMycyhmLCAmcy0+ZGF0YV9sZW4pOwogICAgcWVtdV9nZXRfOHMoZiwgJnMtPmRhdGFfc3RhdGUpOwogICAgcWVtdV9nZXRfOHMoZiwgJnMtPmRhdGFfZGlyKTsKICAgIHFlbXVfZ2V0XzhzKGYsICZzLT5lb3QpOwogICAgLyogU3RhdGVzIGtlcHQgb25seSB0byBiZSByZXR1cm5lZCBiYWNrICovCiAgICBxZW11X2dldF84cyhmLCAmcy0+dGltZXIwKTsKICAgIHFlbXVfZ2V0XzhzKGYsICZzLT50aW1lcjEpOwogICAgcWVtdV9nZXRfOHMoZiwgJnMtPnByZWNvbXBfdHJrKTsKICAgIHFlbXVfZ2V0XzhzKGYsICZzLT5jb25maWcpOwogICAgcWVtdV9nZXRfOHMoZiwgJnMtPmxvY2spOwogICAgcWVtdV9nZXRfOHMoZiwgJnMtPnB3cmQpOwogICAgcWVtdV9nZXRfOHMoZiwgJm4pOwoKICAgIGlmIChuID4gTUFYX0ZEKQogICAgICAgIHJldHVybiAtRUlOVkFMOwoKICAgIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgICByZXQgPSBmZF9sb2FkKGYsICZzLT5kcml2ZXNbaV0pOwogICAgICAgIGlmIChyZXQgIT0gMCkKICAgICAgICAgICAgYnJlYWs7CiAgICB9CgogICAgcmV0dXJuIHJldDsKfQoKc3RhdGljIHZvaWQgZmRjdHJsX2V4dGVybmFsX3Jlc2V0KHZvaWQgKm9wYXF1ZSkKewogICAgZmRjdHJsX3QgKnMgPSBvcGFxdWU7CgogICAgZmRjdHJsX3Jlc2V0KHMsIDApOwp9CgpzdGF0aWMgdm9pZCBmZGN0cmxfaGFuZGxlX3RjKHZvaWQgKm9wYXF1ZSwgaW50IGlycSwgaW50IGxldmVsKQp7CiAgICAvL2ZkY3RybF90ICpzID0gb3BhcXVlOwoKICAgIGlmIChsZXZlbCkgewogICAgICAgIC8vIFhYWAogICAgICAgIEZMT1BQWV9EUFJJTlRGKCJUQyBwdWxzZWRcbiIpOwogICAgfQp9CgovKiBYWFg6IG1heSBjaGFuZ2UgaWYgbW92ZWQgdG8gYmRydiAqLwppbnQgZmRjdHJsX2dldF9kcml2ZV90eXBlKGZkY3RybF90ICpmZGN0cmwsIGludCBkcml2ZV9udW0pCnsKICAgIHJldHVybiBmZGN0cmwtPmRyaXZlc1tkcml2ZV9udW1dLmRyaXZlOwp9CgovKiBDaGFuZ2UgSVJRIHN0YXRlICovCnN0YXRpYyB2b2lkIGZkY3RybF9yZXNldF9pcnEgKGZkY3RybF90ICpmZGN0cmwpCnsKICAgIGlmICghKGZkY3RybC0+c3JhICYgRkRfU1JBX0lOVFBFTkQpKQogICAgICAgIHJldHVybjsKICAgIEZMT1BQWV9EUFJJTlRGKCJSZXNldCBpbnRlcnJ1cHRcbiIpOwogICAgcWVtdV9zZXRfaXJxKGZkY3RybC0+aXJxLCAwKTsKICAgIGZkY3RybC0+c3JhICY9IH5GRF9TUkFfSU5UUEVORDsKfQoKc3RhdGljIHZvaWQgZmRjdHJsX3JhaXNlX2lycSAoZmRjdHJsX3QgKmZkY3RybCwgdWludDhfdCBzdGF0dXMwKQp7CiAgICAvKiBTcGFyYyBtdXRhdGlvbiAqLwogICAgaWYgKGZkY3RybC0+c3VuNG0gJiYgKGZkY3RybC0+bXNyICYgRkRfTVNSX0NNREJVU1kpKSB7CiAgICAgICAgLyogWFhYOiBub3Qgc3VyZSAqLwogICAgICAgIGZkY3RybC0+bXNyICY9IH5GRF9NU1JfQ01EQlVTWTsKICAgICAgICBmZGN0cmwtPm1zciB8PSBGRF9NU1JfUlFNIHwgRkRfTVNSX0RJTzsKICAgICAgICBmZGN0cmwtPnN0YXR1czAgPSBzdGF0dXMwOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGlmICghKGZkY3RybC0+c3JhICYgRkRfU1JBX0lOVFBFTkQpKSB7CiAgICAgICAgcWVtdV9zZXRfaXJxKGZkY3RybC0+aXJxLCAxKTsKICAgICAgICBmZGN0cmwtPnNyYSB8PSBGRF9TUkFfSU5UUEVORDsKICAgIH0KICAgIGZkY3RybC0+cmVzZXRfc2Vuc2VpID0gMDsKICAgIGZkY3RybC0+c3RhdHVzMCA9IHN0YXR1czA7CiAgICBGTE9QUFlfRFBSSU5URigiU2V0IGludGVycnVwdCBzdGF0dXMgdG8gMHglMDJ4XG4iLCBmZGN0cmwtPnN0YXR1czApOwp9CgovKiBSZXNldCBjb250cm9sbGVyICovCnN0YXRpYyB2b2lkIGZkY3RybF9yZXNldCAoZmRjdHJsX3QgKmZkY3RybCwgaW50IGRvX2lycSkKewogICAgaW50IGk7CgogICAgRkxPUFBZX0RQUklOVEYoInJlc2V0IGNvbnRyb2xsZXJcbiIpOwogICAgZmRjdHJsX3Jlc2V0X2lycShmZGN0cmwpOwogICAgLyogSW5pdGlhbGlzZSBjb250cm9sbGVyICovCiAgICBmZGN0cmwtPnNyYSA9IDA7CiAgICBmZGN0cmwtPnNyYiA9IDB4YzA7CiAgICBpZiAoIWZkY3RybC0+ZHJpdmVzWzFdLmJzKQogICAgICAgIGZkY3RybC0+c3JhIHw9IEZEX1NSQV9uRFJWMjsKICAgIGZkY3RybC0+Y3VyX2RydiA9IDA7CiAgICBmZGN0cmwtPmRvciA9IEZEX0RPUl9uUkVTRVQ7CiAgICBmZGN0cmwtPmRvciB8PSAoZmRjdHJsLT5kbWFfY2hhbm4gIT0gLTEpID8gRkRfRE9SX0RNQUVOIDogMDsKICAgIGZkY3RybC0+bXNyID0gRkRfTVNSX1JRTTsKICAgIC8qIEZJRk8gc3RhdGUgKi8KICAgIGZkY3RybC0+ZGF0YV9wb3MgPSAwOwogICAgZmRjdHJsLT5kYXRhX2xlbiA9IDA7CiAgICBmZGN0cmwtPmRhdGFfc3RhdGUgPSAwOwogICAgZmRjdHJsLT5kYXRhX2RpciA9IEZEX0RJUl9XUklURTsKICAgIGZvciAoaSA9IDA7IGkgPCBNQVhfRkQ7IGkrKykKICAgICAgICBmZF9yZWNhbGlicmF0ZSgmZmRjdHJsLT5kcml2ZXNbaV0pOwogICAgZmRjdHJsX3Jlc2V0X2ZpZm8oZmRjdHJsKTsKICAgIGlmIChkb19pcnEpIHsKICAgICAgICBmZGN0cmxfcmFpc2VfaXJxKGZkY3RybCwgRkRfU1IwX1JEWUNIRyk7CiAgICAgICAgZmRjdHJsLT5yZXNldF9zZW5zZWkgPSBGRF9SRVNFVF9TRU5TRUlfQ09VTlQ7CiAgICB9Cn0KCnN0YXRpYyBpbmxpbmUgZmRyaXZlX3QgKmRydjAgKGZkY3RybF90ICpmZGN0cmwpCnsKICAgIHJldHVybiAmZmRjdHJsLT5kcml2ZXNbKGZkY3RybC0+dGRyICYgRkRfVERSX0JPT1RTRUwpID4+IDJdOwp9CgpzdGF0aWMgaW5saW5lIGZkcml2ZV90ICpkcnYxIChmZGN0cmxfdCAqZmRjdHJsKQp7CiAgICBpZiAoKGZkY3RybC0+dGRyICYgRkRfVERSX0JPT1RTRUwpIDwgKDEgPDwgMikpCiAgICAgICAgcmV0dXJuICZmZGN0cmwtPmRyaXZlc1sxXTsKICAgIGVsc2UKICAgICAgICByZXR1cm4gJmZkY3RybC0+ZHJpdmVzWzBdOwp9CgojaWYgTUFYX0ZEID09IDQKc3RhdGljIGlubGluZSBmZHJpdmVfdCAqZHJ2MiAoZmRjdHJsX3QgKmZkY3RybCkKewogICAgaWYgKChmZGN0cmwtPnRkciAmIEZEX1REUl9CT09UU0VMKSA8ICgyIDw8IDIpKQogICAgICAgIHJldHVybiAmZmRjdHJsLT5kcml2ZXNbMl07CiAgICBlbHNlCiAgICAgICAgcmV0dXJuICZmZGN0cmwtPmRyaXZlc1sxXTsKfQoKc3RhdGljIGlubGluZSBmZHJpdmVfdCAqZHJ2MyAoZmRjdHJsX3QgKmZkY3RybCkKewogICAgaWYgKChmZGN0cmwtPnRkciAmIEZEX1REUl9CT09UU0VMKSA8ICgzIDw8IDIpKQogICAgICAgIHJldHVybiAmZmRjdHJsLT5kcml2ZXNbM107CiAgICBlbHNlCiAgICAgICAgcmV0dXJuICZmZGN0cmwtPmRyaXZlc1syXTsKfQojZW5kaWYKCnN0YXRpYyBmZHJpdmVfdCAqZ2V0X2N1cl9kcnYgKGZkY3RybF90ICpmZGN0cmwpCnsKICAgIHN3aXRjaCAoZmRjdHJsLT5jdXJfZHJ2KSB7CiAgICAgICAgY2FzZSAwOiByZXR1cm4gZHJ2MChmZGN0cmwpOwogICAgICAgIGNhc2UgMTogcmV0dXJuIGRydjEoZmRjdHJsKTsKI2lmIE1BWF9GRCA9PSA0CiAgICAgICAgY2FzZSAyOiByZXR1cm4gZHJ2MihmZGN0cmwpOwogICAgICAgIGNhc2UgMzogcmV0dXJuIGRydjMoZmRjdHJsKTsKI2VuZGlmCiAgICAgICAgZGVmYXVsdDogcmV0dXJuIE5VTEw7CiAgICB9Cn0KCi8qIFN0YXR1cyBBIHJlZ2lzdGVyIDogMHgwMCAocmVhZC1vbmx5KSAqLwpzdGF0aWMgdWludDMyX3QgZmRjdHJsX3JlYWRfc3RhdHVzQSAoZmRjdHJsX3QgKmZkY3RybCkKewogICAgdWludDMyX3QgcmV0dmFsID0gZmRjdHJsLT5zcmE7CgogICAgRkxPUFBZX0RQUklOVEYoInN0YXR1cyByZWdpc3RlciBBOiAweCUwMnhcbiIsIHJldHZhbCk7CgogICAgcmV0dXJuIHJldHZhbDsKfQoKLyogU3RhdHVzIEIgcmVnaXN0ZXIgOiAweDAxIChyZWFkLW9ubHkpICovCnN0YXRpYyB1aW50MzJfdCBmZGN0cmxfcmVhZF9zdGF0dXNCIChmZGN0cmxfdCAqZmRjdHJsKQp7CiAgICB1aW50MzJfdCByZXR2YWwgPSBmZGN0cmwtPnNyYjsKCiAgICBGTE9QUFlfRFBSSU5URigic3RhdHVzIHJlZ2lzdGVyIEI6IDB4JTAyeFxuIiwgcmV0dmFsKTsKCiAgICByZXR1cm4gcmV0dmFsOwp9CgovKiBEaWdpdGFsIG91dHB1dCByZWdpc3RlciA6IDB4MDIgKi8Kc3RhdGljIHVpbnQzMl90IGZkY3RybF9yZWFkX2RvciAoZmRjdHJsX3QgKmZkY3RybCkKewogICAgdWludDMyX3QgcmV0dmFsID0gZmRjdHJsLT5kb3I7CgogICAgLyogU2VsZWN0ZWQgZHJpdmUgKi8KICAgIHJldHZhbCB8PSBmZGN0cmwtPmN1cl9kcnY7CiAgICBGTE9QUFlfRFBSSU5URigiZGlnaXRhbCBvdXRwdXQgcmVnaXN0ZXI6IDB4JTAyeFxuIiwgcmV0dmFsKTsKCiAgICByZXR1cm4gcmV0dmFsOwp9CgpzdGF0aWMgdm9pZCBmZGN0cmxfd3JpdGVfZG9yIChmZGN0cmxfdCAqZmRjdHJsLCB1aW50MzJfdCB2YWx1ZSkKewogICAgRkxPUFBZX0RQUklOVEYoImRpZ2l0YWwgb3V0cHV0IHJlZ2lzdGVyIHNldCB0byAweCUwMnhcbiIsIHZhbHVlKTsKCiAgICAvKiBNb3RvcnMgKi8KICAgIGlmICh2YWx1ZSAmIEZEX0RPUl9NT1RFTjApCiAgICAgICAgZmRjdHJsLT5zcmIgfD0gRkRfU1JCX01UUjA7CiAgICBlbHNlCiAgICAgICAgZmRjdHJsLT5zcmIgJj0gfkZEX1NSQl9NVFIwOwogICAgaWYgKHZhbHVlICYgRkRfRE9SX01PVEVOMSkKICAgICAgICBmZGN0cmwtPnNyYiB8PSBGRF9TUkJfTVRSMTsKICAgIGVsc2UKICAgICAgICBmZGN0cmwtPnNyYiAmPSB+RkRfU1JCX01UUjE7CgogICAgLyogRHJpdmUgKi8KICAgIGlmICh2YWx1ZSAmIDEpCiAgICAgICAgZmRjdHJsLT5zcmIgfD0gRkRfU1JCX0RSMDsKICAgIGVsc2UKICAgICAgICBmZGN0cmwtPnNyYiAmPSB+RkRfU1JCX0RSMDsKCiAgICAvKiBSZXNldCAqLwogICAgaWYgKCEodmFsdWUgJiBGRF9ET1JfblJFU0VUKSkgewogICAgICAgIGlmIChmZGN0cmwtPmRvciAmIEZEX0RPUl9uUkVTRVQpIHsKICAgICAgICAgICAgRkxPUFBZX0RQUklOVEYoImNvbnRyb2xsZXIgZW50ZXIgUkVTRVQgc3RhdGVcbiIpOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKCEoZmRjdHJsLT5kb3IgJiBGRF9ET1JfblJFU0VUKSkgewogICAgICAgICAgICBGTE9QUFlfRFBSSU5URigiY29udHJvbGxlciBvdXQgb2YgUkVTRVQgc3RhdGVcbiIpOwogICAgICAgICAgICBmZGN0cmxfcmVzZXQoZmRjdHJsLCAxKTsKICAgICAgICAgICAgZmRjdHJsLT5kc3IgJj0gfkZEX0RTUl9QV1JET1dOOwogICAgICAgIH0KICAgIH0KICAgIC8qIFNlbGVjdGVkIGRyaXZlICovCiAgICBmZGN0cmwtPmN1cl9kcnYgPSB2YWx1ZSAmIEZEX0RPUl9TRUxNQVNLOwoKICAgIGZkY3RybC0+ZG9yID0gdmFsdWU7Cn0KCi8qIFRhcGUgZHJpdmUgcmVnaXN0ZXIgOiAweDAzICovCnN0YXRpYyB1aW50MzJfdCBmZGN0cmxfcmVhZF90YXBlIChmZGN0cmxfdCAqZmRjdHJsKQp7CiAgICB1aW50MzJfdCByZXR2YWwgPSBmZGN0cmwtPnRkcjsKCiAgICBGTE9QUFlfRFBSSU5URigidGFwZSBkcml2ZSByZWdpc3RlcjogMHglMDJ4XG4iLCByZXR2YWwpOwoKICAgIHJldHVybiByZXR2YWw7Cn0KCnN0YXRpYyB2b2lkIGZkY3RybF93cml0ZV90YXBlIChmZGN0cmxfdCAqZmRjdHJsLCB1aW50MzJfdCB2YWx1ZSkKewogICAgLyogUmVzZXQgbW9kZSAqLwogICAgaWYgKCEoZmRjdHJsLT5kb3IgJiBGRF9ET1JfblJFU0VUKSkgewogICAgICAgIEZMT1BQWV9EUFJJTlRGKCJGbG9wcHkgY29udHJvbGxlciBpbiBSRVNFVCBzdGF0ZSAhXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBGTE9QUFlfRFBSSU5URigidGFwZSBkcml2ZSByZWdpc3RlciBzZXQgdG8gMHglMDJ4XG4iLCB2YWx1ZSk7CiAgICAvKiBEaXNrIGJvb3Qgc2VsZWN0aW9uIGluZGljYXRvciAqLwogICAgZmRjdHJsLT50ZHIgPSB2YWx1ZSAmIEZEX1REUl9CT09UU0VMOwogICAgLyogVGFwZSBpbmRpY2F0b3JzOiBuZXZlciBhbGxvdyAqLwp9CgovKiBNYWluIHN0YXR1cyByZWdpc3RlciA6IDB4MDQgKHJlYWQpICovCnN0YXRpYyB1aW50MzJfdCBmZGN0cmxfcmVhZF9tYWluX3N0YXR1cyAoZmRjdHJsX3QgKmZkY3RybCkKewogICAgdWludDMyX3QgcmV0dmFsID0gZmRjdHJsLT5tc3I7CgogICAgZmRjdHJsLT5kc3IgJj0gfkZEX0RTUl9QV1JET1dOOwogICAgZmRjdHJsLT5kb3IgfD0gRkRfRE9SX25SRVNFVDsKCiAgICBGTE9QUFlfRFBSSU5URigibWFpbiBzdGF0dXMgcmVnaXN0ZXI6IDB4JTAyeFxuIiwgcmV0dmFsKTsKCiAgICByZXR1cm4gcmV0dmFsOwp9CgovKiBEYXRhIHNlbGVjdCByYXRlIHJlZ2lzdGVyIDogMHgwNCAod3JpdGUpICovCnN0YXRpYyB2b2lkIGZkY3RybF93cml0ZV9yYXRlIChmZGN0cmxfdCAqZmRjdHJsLCB1aW50MzJfdCB2YWx1ZSkKewogICAgLyogUmVzZXQgbW9kZSAqLwogICAgaWYgKCEoZmRjdHJsLT5kb3IgJiBGRF9ET1JfblJFU0VUKSkgewogICAgICAgIEZMT1BQWV9EUFJJTlRGKCJGbG9wcHkgY29udHJvbGxlciBpbiBSRVNFVCBzdGF0ZSAhXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBGTE9QUFlfRFBSSU5URigic2VsZWN0IHJhdGUgcmVnaXN0ZXIgc2V0IHRvIDB4JTAyeFxuIiwgdmFsdWUpOwogICAgLyogUmVzZXQ6IGF1dG9jbGVhciAqLwogICAgaWYgKHZhbHVlICYgRkRfRFNSX1NXUkVTRVQpIHsKICAgICAgICBmZGN0cmwtPmRvciAmPSB+RkRfRE9SX25SRVNFVDsKICAgICAgICBmZGN0cmxfcmVzZXQoZmRjdHJsLCAxKTsKICAgICAgICBmZGN0cmwtPmRvciB8PSBGRF9ET1JfblJFU0VUOwogICAgfQogICAgaWYgKHZhbHVlICYgRkRfRFNSX1BXUkRPV04pIHsKICAgICAgICBmZGN0cmxfcmVzZXQoZmRjdHJsLCAxKTsKICAgIH0KICAgIGZkY3RybC0+ZHNyID0gdmFsdWU7Cn0KCnN0YXRpYyBpbnQgZmRjdHJsX21lZGlhX2NoYW5nZWQoZmRyaXZlX3QgKmRydikKewogICAgaW50IHJldDsKCiAgICBpZiAoIWRydi0+YnMpCiAgICAgICAgcmV0dXJuIDA7CiAgICByZXQgPSBiZHJ2X21lZGlhX2NoYW5nZWQoZHJ2LT5icyk7CiAgICBpZiAocmV0KSB7CiAgICAgICAgZmRfcmV2YWxpZGF0ZShkcnYpOwogICAgfQogICAgcmV0dXJuIHJldDsKfQoKLyogRGlnaXRhbCBpbnB1dCByZWdpc3RlciA6IDB4MDcgKHJlYWQtb25seSkgKi8Kc3RhdGljIHVpbnQzMl90IGZkY3RybF9yZWFkX2RpciAoZmRjdHJsX3QgKmZkY3RybCkKewogICAgdWludDMyX3QgcmV0dmFsID0gMDsKCiAgICBpZiAoZmRjdHJsX21lZGlhX2NoYW5nZWQoZHJ2MChmZGN0cmwpKQogICAgIHx8IGZkY3RybF9tZWRpYV9jaGFuZ2VkKGRydjEoZmRjdHJsKSkKI2lmIE1BWF9GRCA9PSA0CiAgICAgfHwgZmRjdHJsX21lZGlhX2NoYW5nZWQoZHJ2MihmZGN0cmwpKQogICAgIHx8IGZkY3RybF9tZWRpYV9jaGFuZ2VkKGRydjMoZmRjdHJsKSkKI2VuZGlmCiAgICAgICAgKQogICAgICAgIHJldHZhbCB8PSBGRF9ESVJfRFNLQ0hHOwogICAgaWYgKHJldHZhbCAhPSAwKQogICAgICAgIEZMT1BQWV9EUFJJTlRGKCJGbG9wcHkgZGlnaXRhbCBpbnB1dCByZWdpc3RlcjogMHglMDJ4XG4iLCByZXR2YWwpOwoKICAgIHJldHVybiByZXR2YWw7Cn0KCi8qIEZJRk8gc3RhdGUgY29udHJvbCAqLwpzdGF0aWMgdm9pZCBmZGN0cmxfcmVzZXRfZmlmbyAoZmRjdHJsX3QgKmZkY3RybCkKewogICAgZmRjdHJsLT5kYXRhX2RpciA9IEZEX0RJUl9XUklURTsKICAgIGZkY3RybC0+ZGF0YV9wb3MgPSAwOwogICAgZmRjdHJsLT5tc3IgJj0gfihGRF9NU1JfQ01EQlVTWSB8IEZEX01TUl9ESU8pOwp9CgovKiBTZXQgRklGTyBzdGF0dXMgZm9yIHRoZSBob3N0IHRvIHJlYWQgKi8Kc3RhdGljIHZvaWQgZmRjdHJsX3NldF9maWZvIChmZGN0cmxfdCAqZmRjdHJsLCBpbnQgZmlmb19sZW4sIGludCBkb19pcnEpCnsKICAgIGZkY3RybC0+ZGF0YV9kaXIgPSBGRF9ESVJfUkVBRDsKICAgIGZkY3RybC0+ZGF0YV9sZW4gPSBmaWZvX2xlbjsKICAgIGZkY3RybC0+ZGF0YV9wb3MgPSAwOwogICAgZmRjdHJsLT5tc3IgfD0gRkRfTVNSX0NNREJVU1kgfCBGRF9NU1JfUlFNIHwgRkRfTVNSX0RJTzsKICAgIGlmIChkb19pcnEpCiAgICAgICAgZmRjdHJsX3JhaXNlX2lycShmZGN0cmwsIDB4MDApOwp9CgovKiBTZXQgYW4gZXJyb3I6IHVuaW1wbGVtZW50ZWQvdW5rbm93biBjb21tYW5kICovCnN0YXRpYyB2b2lkIGZkY3RybF91bmltcGxlbWVudGVkIChmZGN0cmxfdCAqZmRjdHJsLCBpbnQgZGlyZWN0aW9uKQp7CiAgICBGTE9QUFlfRVJST1IoInVuaW1wbGVtZW50ZWQgY29tbWFuZCAweCUwMnhcbiIsIGZkY3RybC0+Zmlmb1swXSk7CiAgICBmZGN0cmwtPmZpZm9bMF0gPSBGRF9TUjBfSU5WQ01EOwogICAgZmRjdHJsX3NldF9maWZvKGZkY3RybCwgMSwgMCk7Cn0KCi8qIFNlZWsgdG8gbmV4dCBzZWN0b3IgKi8Kc3RhdGljIGludCBmZGN0cmxfc2Vla190b19uZXh0X3NlY3QgKGZkY3RybF90ICpmZGN0cmwsIGZkcml2ZV90ICpjdXJfZHJ2KQp7CiAgICBGTE9QUFlfRFBSSU5URigic2VlayB0byBuZXh0IHNlY3RvciAoJWQgJTAyeCAlMDJ4ID0+ICVkKVxuIiwKICAgICAgICAgICAgICAgICAgIGN1cl9kcnYtPmhlYWQsIGN1cl9kcnYtPnRyYWNrLCBjdXJfZHJ2LT5zZWN0LAogICAgICAgICAgICAgICAgICAgZmRfc2VjdG9yKGN1cl9kcnYpKTsKICAgIC8qIFhYWDogY3VyX2Rydi0+c2VjdCA+PSBjdXJfZHJ2LT5sYXN0X3NlY3Qgc2hvdWxkIGJlIGFuCiAgICAgICBlcnJvciBpbiBmYWN0ICovCiAgICBpZiAoY3VyX2Rydi0+c2VjdCA+PSBjdXJfZHJ2LT5sYXN0X3NlY3QgfHwKICAgICAgICBjdXJfZHJ2LT5zZWN0ID09IGZkY3RybC0+ZW90KSB7CiAgICAgICAgY3VyX2Rydi0+c2VjdCA9IDE7CiAgICAgICAgaWYgKEZEX01VTFRJX1RSQUNLKGZkY3RybC0+ZGF0YV9zdGF0ZSkpIHsKICAgICAgICAgICAgaWYgKGN1cl9kcnYtPmhlYWQgPT0gMCAmJgogICAgICAgICAgICAgICAgKGN1cl9kcnYtPmZsYWdzICYgRkRJU0tfREJMX1NJREVTKSAhPSAwKSB7CiAgICAgICAgICAgICAgICBjdXJfZHJ2LT5oZWFkID0gMTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGN1cl9kcnYtPmhlYWQgPSAwOwogICAgICAgICAgICAgICAgY3VyX2Rydi0+dHJhY2srKzsKICAgICAgICAgICAgICAgIGlmICgoY3VyX2Rydi0+ZmxhZ3MgJiBGRElTS19EQkxfU0lERVMpID09IDApCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBjdXJfZHJ2LT50cmFjaysrOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICAgICAgRkxPUFBZX0RQUklOVEYoInNlZWsgdG8gbmV4dCB0cmFjayAoJWQgJTAyeCAlMDJ4ID0+ICVkKVxuIiwKICAgICAgICAgICAgICAgICAgICAgICBjdXJfZHJ2LT5oZWFkLCBjdXJfZHJ2LT50cmFjaywKICAgICAgICAgICAgICAgICAgICAgICBjdXJfZHJ2LT5zZWN0LCBmZF9zZWN0b3IoY3VyX2RydikpOwogICAgfSBlbHNlIHsKICAgICAgICBjdXJfZHJ2LT5zZWN0Kys7CiAgICB9CiAgICByZXR1cm4gMTsKfQoKLyogQ2FsbGJhY2sgZm9yIHRyYW5zZmVyIGVuZCAoc3RvcCBvciBhYm9ydCkgKi8Kc3RhdGljIHZvaWQgZmRjdHJsX3N0b3BfdHJhbnNmZXIgKGZkY3RybF90ICpmZGN0cmwsIHVpbnQ4X3Qgc3RhdHVzMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4X3Qgc3RhdHVzMSwgdWludDhfdCBzdGF0dXMyKQp7CiAgICBmZHJpdmVfdCAqY3VyX2RydjsKCiAgICBjdXJfZHJ2ID0gZ2V0X2N1cl9kcnYoZmRjdHJsKTsKICAgIEZMT1BQWV9EUFJJTlRGKCJ0cmFuc2ZlciBzdGF0dXM6ICUwMnggJTAyeCAlMDJ4ICglMDJ4KVxuIiwKICAgICAgICAgICAgICAgICAgIHN0YXR1czAsIHN0YXR1czEsIHN0YXR1czIsCiAgICAgICAgICAgICAgICAgICBzdGF0dXMwIHwgKGN1cl9kcnYtPmhlYWQgPDwgMikgfCBHRVRfQ1VSX0RSVihmZGN0cmwpKTsKICAgIGZkY3RybC0+Zmlmb1swXSA9IHN0YXR1czAgfCAoY3VyX2Rydi0+aGVhZCA8PCAyKSB8IEdFVF9DVVJfRFJWKGZkY3RybCk7CiAgICBmZGN0cmwtPmZpZm9bMV0gPSBzdGF0dXMxOwogICAgZmRjdHJsLT5maWZvWzJdID0gc3RhdHVzMjsKICAgIGZkY3RybC0+Zmlmb1szXSA9IGN1cl9kcnYtPnRyYWNrOwogICAgZmRjdHJsLT5maWZvWzRdID0gY3VyX2Rydi0+aGVhZDsKICAgIGZkY3RybC0+Zmlmb1s1XSA9IGN1cl9kcnYtPnNlY3Q7CiAgICBmZGN0cmwtPmZpZm9bNl0gPSBGRF9TRUNUT1JfU0M7CiAgICBmZGN0cmwtPmRhdGFfZGlyID0gRkRfRElSX1JFQUQ7CiAgICBpZiAoIShmZGN0cmwtPm1zciAmIEZEX01TUl9OT05ETUEpKSB7CiAgICAgICAgRE1BX3JlbGVhc2VfRFJFUShmZGN0cmwtPmRtYV9jaGFubik7CiAgICB9CiAgICBmZGN0cmwtPm1zciB8PSBGRF9NU1JfUlFNIHwgRkRfTVNSX0RJTzsKICAgIGZkY3RybC0+bXNyICY9IH5GRF9NU1JfTk9ORE1BOwogICAgZmRjdHJsX3NldF9maWZvKGZkY3RybCwgNywgMSk7Cn0KCi8qIFByZXBhcmUgYSBkYXRhIHRyYW5zZmVyIChlaXRoZXIgRE1BIG9yIEZJRk8pICovCnN0YXRpYyB2b2lkIGZkY3RybF9zdGFydF90cmFuc2ZlciAoZmRjdHJsX3QgKmZkY3RybCwgaW50IGRpcmVjdGlvbikKewogICAgZmRyaXZlX3QgKmN1cl9kcnY7CiAgICB1aW50OF90IGtoLCBrdCwga3M7CiAgICBpbnQgZGlkX3NlZWsgPSAwOwoKICAgIFNFVF9DVVJfRFJWKGZkY3RybCwgZmRjdHJsLT5maWZvWzFdICYgRkRfRE9SX1NFTE1BU0spOwogICAgY3VyX2RydiA9IGdldF9jdXJfZHJ2KGZkY3RybCk7CiAgICBrdCA9IGZkY3RybC0+Zmlmb1syXTsKICAgIGtoID0gZmRjdHJsLT5maWZvWzNdOwogICAga3MgPSBmZGN0cmwtPmZpZm9bNF07CiAgICBGTE9QUFlfRFBSSU5URigiU3RhcnQgdHJhbnNmZXIgYXQgJWQgJWQgJTAyeCAlMDJ4ICglZClcbiIsCiAgICAgICAgICAgICAgICAgICBHRVRfQ1VSX0RSVihmZGN0cmwpLCBraCwga3QsIGtzLAogICAgICAgICAgICAgICAgICAgX2ZkX3NlY3RvcihraCwga3QsIGtzLCBjdXJfZHJ2LT5sYXN0X3NlY3QpKTsKICAgIHN3aXRjaCAoZmRfc2VlayhjdXJfZHJ2LCBraCwga3QsIGtzLCBmZGN0cmwtPmNvbmZpZyAmIEZEX0NPTkZJR19FSVMpKSB7CiAgICBjYXNlIDI6CiAgICAgICAgLyogc2VjdCB0b28gYmlnICovCiAgICAgICAgZmRjdHJsX3N0b3BfdHJhbnNmZXIoZmRjdHJsLCBGRF9TUjBfQUJOVEVSTSwgMHgwMCwgMHgwMCk7CiAgICAgICAgZmRjdHJsLT5maWZvWzNdID0ga3Q7CiAgICAgICAgZmRjdHJsLT5maWZvWzRdID0ga2g7CiAgICAgICAgZmRjdHJsLT5maWZvWzVdID0ga3M7CiAgICAgICAgcmV0dXJuOwogICAgY2FzZSAzOgogICAgICAgIC8qIHRyYWNrIHRvbyBiaWcgKi8KICAgICAgICBmZGN0cmxfc3RvcF90cmFuc2ZlcihmZGN0cmwsIEZEX1NSMF9BQk5URVJNLCBGRF9TUjFfRUMsIDB4MDApOwogICAgICAgIGZkY3RybC0+Zmlmb1szXSA9IGt0OwogICAgICAgIGZkY3RybC0+Zmlmb1s0XSA9IGtoOwogICAgICAgIGZkY3RybC0+Zmlmb1s1XSA9IGtzOwogICAgICAgIHJldHVybjsKICAgIGNhc2UgNDoKICAgICAgICAvKiBObyBzZWVrIGVuYWJsZWQgKi8KICAgICAgICBmZGN0cmxfc3RvcF90cmFuc2ZlcihmZGN0cmwsIEZEX1NSMF9BQk5URVJNLCAweDAwLCAweDAwKTsKICAgICAgICBmZGN0cmwtPmZpZm9bM10gPSBrdDsKICAgICAgICBmZGN0cmwtPmZpZm9bNF0gPSBraDsKICAgICAgICBmZGN0cmwtPmZpZm9bNV0gPSBrczsKICAgICAgICByZXR1cm47CiAgICBjYXNlIDE6CiAgICAgICAgZGlkX3NlZWsgPSAxOwogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBicmVhazsKICAgIH0KCiAgICAvKiBTZXQgdGhlIEZJRk8gc3RhdGUgKi8KICAgIGZkY3RybC0+ZGF0YV9kaXIgPSBkaXJlY3Rpb247CiAgICBmZGN0cmwtPmRhdGFfcG9zID0gMDsKICAgIGZkY3RybC0+bXNyIHw9IEZEX01TUl9DTURCVVNZOwogICAgaWYgKGZkY3RybC0+Zmlmb1swXSAmIDB4ODApCiAgICAgICAgZmRjdHJsLT5kYXRhX3N0YXRlIHw9IEZEX1NUQVRFX01VTFRJOwogICAgZWxzZQogICAgICAgIGZkY3RybC0+ZGF0YV9zdGF0ZSAmPSB+RkRfU1RBVEVfTVVMVEk7CiAgICBpZiAoZGlkX3NlZWspCiAgICAgICAgZmRjdHJsLT5kYXRhX3N0YXRlIHw9IEZEX1NUQVRFX1NFRUs7CiAgICBlbHNlCiAgICAgICAgZmRjdHJsLT5kYXRhX3N0YXRlICY9IH5GRF9TVEFURV9TRUVLOwogICAgaWYgKGZkY3RybC0+Zmlmb1s1XSA9PSAwMCkgewogICAgICAgIGZkY3RybC0+ZGF0YV9sZW4gPSBmZGN0cmwtPmZpZm9bOF07CiAgICB9IGVsc2UgewogICAgICAgIGludCB0bXA7CiAgICAgICAgZmRjdHJsLT5kYXRhX2xlbiA9IDEyOCA8PCAoZmRjdHJsLT5maWZvWzVdID4gNyA/IDcgOiBmZGN0cmwtPmZpZm9bNV0pOwogICAgICAgIHRtcCA9IChmZGN0cmwtPmZpZm9bNl0gLSBrcyArIDEpOwogICAgICAgIGlmIChmZGN0cmwtPmZpZm9bMF0gJiAweDgwKQogICAgICAgICAgICB0bXAgKz0gZmRjdHJsLT5maWZvWzZdOwogICAgICAgIGZkY3RybC0+ZGF0YV9sZW4gKj0gdG1wOwogICAgfQogICAgZmRjdHJsLT5lb3QgPSBmZGN0cmwtPmZpZm9bNl07CiAgICBpZiAoZmRjdHJsLT5kb3IgJiBGRF9ET1JfRE1BRU4pIHsKICAgICAgICBpbnQgZG1hX21vZGU7CiAgICAgICAgLyogRE1BIHRyYW5zZmVyIGFyZSBlbmFibGVkLiBDaGVjayBpZiBETUEgY2hhbm5lbCBpcyB3ZWxsIHByb2dyYW1tZWQgKi8KICAgICAgICBkbWFfbW9kZSA9IERNQV9nZXRfY2hhbm5lbF9tb2RlKGZkY3RybC0+ZG1hX2NoYW5uKTsKICAgICAgICBkbWFfbW9kZSA9IChkbWFfbW9kZSA+PiAyKSAmIDM7CiAgICAgICAgRkxPUFBZX0RQUklOVEYoImRtYV9tb2RlPSVkIGRpcmVjdGlvbj0lZCAoJWQgLSAlZClcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgZG1hX21vZGUsIGRpcmVjdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAoMTI4IDw8IGZkY3RybC0+Zmlmb1s1XSkgKgogICAgICAgICAgICAgICAgICAgICAgIChjdXJfZHJ2LT5sYXN0X3NlY3QgLSBrcyArIDEpLCBmZGN0cmwtPmRhdGFfbGVuKTsKICAgICAgICBpZiAoKChkaXJlY3Rpb24gPT0gRkRfRElSX1NDQU5FIHx8IGRpcmVjdGlvbiA9PSBGRF9ESVJfU0NBTkwgfHwKICAgICAgICAgICAgICBkaXJlY3Rpb24gPT0gRkRfRElSX1NDQU5IKSAmJiBkbWFfbW9kZSA9PSAwKSB8fAogICAgICAgICAgICAoZGlyZWN0aW9uID09IEZEX0RJUl9XUklURSAmJiBkbWFfbW9kZSA9PSAyKSB8fAogICAgICAgICAgICAoZGlyZWN0aW9uID09IEZEX0RJUl9SRUFEICYmIGRtYV9tb2RlID09IDEpKSB7CiAgICAgICAgICAgIC8qIE5vIGFjY2VzcyBpcyBhbGxvd2VkIHVudGlsIERNQSB0cmFuc2ZlciBoYXMgY29tcGxldGVkICovCiAgICAgICAgICAgIGZkY3RybC0+bXNyICY9IH5GRF9NU1JfUlFNOwogICAgICAgICAgICAvKiBOb3csIHdlIGp1c3QgaGF2ZSB0byB3YWl0IGZvciB0aGUgRE1BIGNvbnRyb2xsZXIgdG8KICAgICAgICAgICAgICogcmVjYWxsIHVzLi4uCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBETUFfaG9sZF9EUkVRKGZkY3RybC0+ZG1hX2NoYW5uKTsKICAgICAgICAgICAgRE1BX3NjaGVkdWxlKGZkY3RybC0+ZG1hX2NoYW5uKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIEZMT1BQWV9FUlJPUigiZG1hX21vZGU9JWQgZGlyZWN0aW9uPSVkXG4iLCBkbWFfbW9kZSwgZGlyZWN0aW9uKTsKICAgICAgICB9CiAgICB9CiAgICBGTE9QUFlfRFBSSU5URigic3RhcnQgbm9uLURNQSB0cmFuc2ZlclxuIik7CiAgICBmZGN0cmwtPm1zciB8PSBGRF9NU1JfTk9ORE1BOwogICAgaWYgKGRpcmVjdGlvbiAhPSBGRF9ESVJfV1JJVEUpCiAgICAgICAgZmRjdHJsLT5tc3IgfD0gRkRfTVNSX0RJTzsKICAgIC8qIElPIGJhc2VkIHRyYW5zZmVyOiBjYWxjdWxhdGUgbGVuICovCiAgICBmZGN0cmxfcmFpc2VfaXJxKGZkY3RybCwgMHgwMCk7CgogICAgcmV0dXJuOwp9CgovKiBQcmVwYXJlIGEgdHJhbnNmZXIgb2YgZGVsZXRlZCBkYXRhICovCnN0YXRpYyB2b2lkIGZkY3RybF9zdGFydF90cmFuc2Zlcl9kZWwgKGZkY3RybF90ICpmZGN0cmwsIGludCBkaXJlY3Rpb24pCnsKICAgIEZMT1BQWV9FUlJPUigiZmRjdHJsX3N0YXJ0X3RyYW5zZmVyX2RlbCgpIHVuaW1wbGVtZW50ZWRcbiIpOwoKICAgIC8qIFdlIGRvbid0IGhhbmRsZSBkZWxldGVkIGRhdGEsCiAgICAgKiBzbyB3ZSBkb24ndCByZXR1cm4gKkFOWVRISU5HKgogICAgICovCiAgICBmZGN0cmxfc3RvcF90cmFuc2ZlcihmZGN0cmwsIEZEX1NSMF9BQk5URVJNIHwgRkRfU1IwX1NFRUssIDB4MDAsIDB4MDApOwp9CgovKiBoYW5kbGVycyBmb3IgRE1BIHRyYW5zZmVycyAqLwpzdGF0aWMgaW50IGZkY3RybF90cmFuc2Zlcl9oYW5kbGVyICh2b2lkICpvcGFxdWUsIGludCBuY2hhbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGRtYV9wb3MsIGludCBkbWFfbGVuKQp7CiAgICBmZGN0cmxfdCAqZmRjdHJsOwogICAgZmRyaXZlX3QgKmN1cl9kcnY7CiAgICBpbnQgbGVuLCBzdGFydF9wb3MsIHJlbF9wb3M7CiAgICB1aW50OF90IHN0YXR1czAgPSAweDAwLCBzdGF0dXMxID0gMHgwMCwgc3RhdHVzMiA9IDB4MDA7CgogICAgZmRjdHJsID0gb3BhcXVlOwogICAgaWYgKGZkY3RybC0+bXNyICYgRkRfTVNSX1JRTSkgewogICAgICAgIEZMT1BQWV9EUFJJTlRGKCJOb3QgaW4gRE1BIHRyYW5zZmVyIG1vZGUgIVxuIik7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICBjdXJfZHJ2ID0gZ2V0X2N1cl9kcnYoZmRjdHJsKTsKICAgIGlmIChmZGN0cmwtPmRhdGFfZGlyID09IEZEX0RJUl9TQ0FORSB8fCBmZGN0cmwtPmRhdGFfZGlyID09IEZEX0RJUl9TQ0FOTCB8fAogICAgICAgIGZkY3RybC0+ZGF0YV9kaXIgPT0gRkRfRElSX1NDQU5IKQogICAgICAgIHN0YXR1czIgPSBGRF9TUjJfU05TOwogICAgaWYgKGRtYV9sZW4gPiBmZGN0cmwtPmRhdGFfbGVuKQogICAgICAgIGRtYV9sZW4gPSBmZGN0cmwtPmRhdGFfbGVuOwogICAgaWYgKGN1cl9kcnYtPmJzID09IE5VTEwpIHsKICAgICAgICBpZiAoZmRjdHJsLT5kYXRhX2RpciA9PSBGRF9ESVJfV1JJVEUpCiAgICAgICAgICAgIGZkY3RybF9zdG9wX3RyYW5zZmVyKGZkY3RybCwgRkRfU1IwX0FCTlRFUk0gfCBGRF9TUjBfU0VFSywgMHgwMCwgMHgwMCk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBmZGN0cmxfc3RvcF90cmFuc2ZlcihmZGN0cmwsIEZEX1NSMF9BQk5URVJNLCAweDAwLCAweDAwKTsKICAgICAgICBsZW4gPSAwOwogICAgICAgIGdvdG8gdHJhbnNmZXJfZXJyb3I7CiAgICB9CiAgICByZWxfcG9zID0gZmRjdHJsLT5kYXRhX3BvcyAlIEZEX1NFQ1RPUl9MRU47CiAgICBmb3IgKHN0YXJ0X3BvcyA9IGZkY3RybC0+ZGF0YV9wb3M7IGZkY3RybC0+ZGF0YV9wb3MgPCBkbWFfbGVuOykgewogICAgICAgIGxlbiA9IGRtYV9sZW4gLSBmZGN0cmwtPmRhdGFfcG9zOwogICAgICAgIGlmIChsZW4gKyByZWxfcG9zID4gRkRfU0VDVE9SX0xFTikKICAgICAgICAgICAgbGVuID0gRkRfU0VDVE9SX0xFTiAtIHJlbF9wb3M7CiAgICAgICAgRkxPUFBZX0RQUklOVEYoImNvcHkgJWQgYnl0ZXMgKCVkICVkICVkKSAlZCBwb3MgJWQgJTAyeCAiCiAgICAgICAgICAgICAgICAgICAgICAgIiglZC0weCUwOHggMHglMDh4KVxuIiwgbGVuLCBkbWFfbGVuLCBmZGN0cmwtPmRhdGFfcG9zLAogICAgICAgICAgICAgICAgICAgICAgIGZkY3RybC0+ZGF0YV9sZW4sIEdFVF9DVVJfRFJWKGZkY3RybCksIGN1cl9kcnYtPmhlYWQsCiAgICAgICAgICAgICAgICAgICAgICAgY3VyX2Rydi0+dHJhY2ssIGN1cl9kcnYtPnNlY3QsIGZkX3NlY3RvcihjdXJfZHJ2KSwKICAgICAgICAgICAgICAgICAgICAgICBmZF9zZWN0b3IoY3VyX2RydikgKiBGRF9TRUNUT1JfTEVOKTsKICAgICAgICBpZiAoZmRjdHJsLT5kYXRhX2RpciAhPSBGRF9ESVJfV1JJVEUgfHwKICAgICAgICAgICAgbGVuIDwgRkRfU0VDVE9SX0xFTiB8fCByZWxfcG9zICE9IDApIHsKICAgICAgICAgICAgLyogUkVBRCAmIFNDQU4gY29tbWFuZHMgYW5kIHJlYWxpZ24gdG8gYSBzZWN0b3IgZm9yIFdSSVRFICovCiAgICAgICAgICAgIGlmIChiZHJ2X3JlYWQoY3VyX2Rydi0+YnMsIGZkX3NlY3RvcihjdXJfZHJ2KSwKICAgICAgICAgICAgICAgICAgICAgICAgICBmZGN0cmwtPmZpZm8sIDEpIDwgMCkgewogICAgICAgICAgICAgICAgRkxPUFBZX0RQUklOVEYoIkZsb3BweTogZXJyb3IgZ2V0dGluZyBzZWN0b3IgJWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmZF9zZWN0b3IoY3VyX2RydikpOwogICAgICAgICAgICAgICAgLyogU3VyZSwgaW1hZ2Ugc2l6ZSBpcyB0b28gc21hbGwuLi4gKi8KICAgICAgICAgICAgICAgIG1lbXNldChmZGN0cmwtPmZpZm8sIDAsIEZEX1NFQ1RPUl9MRU4pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHN3aXRjaCAoZmRjdHJsLT5kYXRhX2RpcikgewogICAgICAgIGNhc2UgRkRfRElSX1JFQUQ6CiAgICAgICAgICAgIC8qIFJFQUQgY29tbWFuZHMgKi8KICAgICAgICAgICAgRE1BX3dyaXRlX21lbW9yeSAobmNoYW4sIGZkY3RybC0+ZmlmbyArIHJlbF9wb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZkY3RybC0+ZGF0YV9wb3MsIGxlbik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgRkRfRElSX1dSSVRFOgogICAgICAgICAgICAvKiBXUklURSBjb21tYW5kcyAqLwogICAgICAgICAgICBETUFfcmVhZF9tZW1vcnkgKG5jaGFuLCBmZGN0cmwtPmZpZm8gKyByZWxfcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZkY3RybC0+ZGF0YV9wb3MsIGxlbik7CiAgICAgICAgICAgIGlmIChiZHJ2X3dyaXRlKGN1cl9kcnYtPmJzLCBmZF9zZWN0b3IoY3VyX2RydiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZkY3RybC0+ZmlmbywgMSkgPCAwKSB7CiAgICAgICAgICAgICAgICBGTE9QUFlfRVJST1IoIndyaXRpbmcgc2VjdG9yICVkXG4iLCBmZF9zZWN0b3IoY3VyX2RydikpOwogICAgICAgICAgICAgICAgZmRjdHJsX3N0b3BfdHJhbnNmZXIoZmRjdHJsLCBGRF9TUjBfQUJOVEVSTSB8IEZEX1NSMF9TRUVLLCAweDAwLCAweDAwKTsKICAgICAgICAgICAgICAgIGdvdG8gdHJhbnNmZXJfZXJyb3I7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgLyogU0NBTiBjb21tYW5kcyAqLwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB1aW50OF90IHRtcGJ1ZltGRF9TRUNUT1JfTEVOXTsKICAgICAgICAgICAgICAgIGludCByZXQ7CiAgICAgICAgICAgICAgICBETUFfcmVhZF9tZW1vcnkgKG5jaGFuLCB0bXBidWYsIGZkY3RybC0+ZGF0YV9wb3MsIGxlbik7CiAgICAgICAgICAgICAgICByZXQgPSBtZW1jbXAodG1wYnVmLCBmZGN0cmwtPmZpZm8gKyByZWxfcG9zLCBsZW4pOwogICAgICAgICAgICAgICAgaWYgKHJldCA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgc3RhdHVzMiA9IEZEX1NSMl9TRUg7CiAgICAgICAgICAgICAgICAgICAgZ290byBlbmRfdHJhbnNmZXI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoKHJldCA8IDAgJiYgZmRjdHJsLT5kYXRhX2RpciA9PSBGRF9ESVJfU0NBTkwpIHx8CiAgICAgICAgICAgICAgICAgICAgKHJldCA+IDAgJiYgZmRjdHJsLT5kYXRhX2RpciA9PSBGRF9ESVJfU0NBTkgpKSB7CiAgICAgICAgICAgICAgICAgICAgc3RhdHVzMiA9IDB4MDA7CiAgICAgICAgICAgICAgICAgICAgZ290byBlbmRfdHJhbnNmZXI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGZkY3RybC0+ZGF0YV9wb3MgKz0gbGVuOwogICAgICAgIHJlbF9wb3MgPSBmZGN0cmwtPmRhdGFfcG9zICUgRkRfU0VDVE9SX0xFTjsKICAgICAgICBpZiAocmVsX3BvcyA9PSAwKSB7CiAgICAgICAgICAgIC8qIFNlZWsgdG8gbmV4dCBzZWN0b3IgKi8KICAgICAgICAgICAgaWYgKCFmZGN0cmxfc2Vla190b19uZXh0X3NlY3QoZmRjdHJsLCBjdXJfZHJ2KSkKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KIGVuZF90cmFuc2ZlcjoKICAgIGxlbiA9IGZkY3RybC0+ZGF0YV9wb3MgLSBzdGFydF9wb3M7CiAgICBGTE9QUFlfRFBSSU5URigiZW5kIHRyYW5zZmVyICVkICVkICVkXG4iLAogICAgICAgICAgICAgICAgICAgZmRjdHJsLT5kYXRhX3BvcywgbGVuLCBmZGN0cmwtPmRhdGFfbGVuKTsKICAgIGlmIChmZGN0cmwtPmRhdGFfZGlyID09IEZEX0RJUl9TQ0FORSB8fAogICAgICAgIGZkY3RybC0+ZGF0YV9kaXIgPT0gRkRfRElSX1NDQU5MIHx8CiAgICAgICAgZmRjdHJsLT5kYXRhX2RpciA9PSBGRF9ESVJfU0NBTkgpCiAgICAgICAgc3RhdHVzMiA9IEZEX1NSMl9TRUg7CiAgICBpZiAoRkRfRElEX1NFRUsoZmRjdHJsLT5kYXRhX3N0YXRlKSkKICAgICAgICBzdGF0dXMwIHw9IEZEX1NSMF9TRUVLOwogICAgZmRjdHJsLT5kYXRhX2xlbiAtPSBsZW47CiAgICBmZGN0cmxfc3RvcF90cmFuc2ZlcihmZGN0cmwsIHN0YXR1czAsIHN0YXR1czEsIHN0YXR1czIpOwogdHJhbnNmZXJfZXJyb3I6CgogICAgcmV0dXJuIGxlbjsKfQoKLyogRGF0YSByZWdpc3RlciA6IDB4MDUgKi8Kc3RhdGljIHVpbnQzMl90IGZkY3RybF9yZWFkX2RhdGEgKGZkY3RybF90ICpmZGN0cmwpCnsKICAgIGZkcml2ZV90ICpjdXJfZHJ2OwogICAgdWludDMyX3QgcmV0dmFsID0gMDsKICAgIGludCBwb3M7CgogICAgY3VyX2RydiA9IGdldF9jdXJfZHJ2KGZkY3RybCk7CiAgICBmZGN0cmwtPmRzciAmPSB+RkRfRFNSX1BXUkRPV047CiAgICBpZiAoIShmZGN0cmwtPm1zciAmIEZEX01TUl9SUU0pIHx8ICEoZmRjdHJsLT5tc3IgJiBGRF9NU1JfRElPKSkgewogICAgICAgIEZMT1BQWV9FUlJPUigiY29udHJvbGxlciBub3QgcmVhZHkgZm9yIHJlYWRpbmdcbiIpOwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgcG9zID0gZmRjdHJsLT5kYXRhX3BvczsKICAgIGlmIChmZGN0cmwtPm1zciAmIEZEX01TUl9OT05ETUEpIHsKICAgICAgICBwb3MgJT0gRkRfU0VDVE9SX0xFTjsKICAgICAgICBpZiAocG9zID09IDApIHsKICAgICAgICAgICAgaWYgKGZkY3RybC0+ZGF0YV9wb3MgIT0gMCkKICAgICAgICAgICAgICAgIGlmICghZmRjdHJsX3NlZWtfdG9fbmV4dF9zZWN0KGZkY3RybCwgY3VyX2RydikpIHsKICAgICAgICAgICAgICAgICAgICBGTE9QUFlfRFBSSU5URigiZXJyb3Igc2Vla2luZyB0byBuZXh0IHNlY3RvciAlZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmZF9zZWN0b3IoY3VyX2RydikpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoYmRydl9yZWFkKGN1cl9kcnYtPmJzLCBmZF9zZWN0b3IoY3VyX2RydiksIGZkY3RybC0+ZmlmbywgMSkgPCAwKSB7CiAgICAgICAgICAgICAgICBGTE9QUFlfRFBSSU5URigiZXJyb3IgZ2V0dGluZyBzZWN0b3IgJWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmZF9zZWN0b3IoY3VyX2RydikpOwogICAgICAgICAgICAgICAgLyogU3VyZSwgaW1hZ2Ugc2l6ZSBpcyB0b28gc21hbGwuLi4gKi8KICAgICAgICAgICAgICAgIG1lbXNldChmZGN0cmwtPmZpZm8sIDAsIEZEX1NFQ1RPUl9MRU4pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgcmV0dmFsID0gZmRjdHJsLT5maWZvW3Bvc107CiAgICBpZiAoKytmZGN0cmwtPmRhdGFfcG9zID09IGZkY3RybC0+ZGF0YV9sZW4pIHsKICAgICAgICBmZGN0cmwtPmRhdGFfcG9zID0gMDsKICAgICAgICAvKiBTd2l0Y2ggZnJvbSB0cmFuc2ZlciBtb2RlIHRvIHN0YXR1cyBtb2RlCiAgICAgICAgICogdGhlbiBmcm9tIHN0YXR1cyBtb2RlIHRvIGNvbW1hbmQgbW9kZQogICAgICAgICAqLwogICAgICAgIGlmIChmZGN0cmwtPm1zciAmIEZEX01TUl9OT05ETUEpIHsKICAgICAgICAgICAgZmRjdHJsX3N0b3BfdHJhbnNmZXIoZmRjdHJsLCBGRF9TUjBfU0VFSywgMHgwMCwgMHgwMCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZmRjdHJsX3Jlc2V0X2ZpZm8oZmRjdHJsKTsKICAgICAgICAgICAgZmRjdHJsX3Jlc2V0X2lycShmZGN0cmwpOwogICAgICAgIH0KICAgIH0KICAgIEZMT1BQWV9EUFJJTlRGKCJkYXRhIHJlZ2lzdGVyOiAweCUwMnhcbiIsIHJldHZhbCk7CgogICAgcmV0dXJuIHJldHZhbDsKfQoKc3RhdGljIHZvaWQgZmRjdHJsX2Zvcm1hdF9zZWN0b3IgKGZkY3RybF90ICpmZGN0cmwpCnsKICAgIGZkcml2ZV90ICpjdXJfZHJ2OwogICAgdWludDhfdCBraCwga3QsIGtzOwoKICAgIFNFVF9DVVJfRFJWKGZkY3RybCwgZmRjdHJsLT5maWZvWzFdICYgRkRfRE9SX1NFTE1BU0spOwogICAgY3VyX2RydiA9IGdldF9jdXJfZHJ2KGZkY3RybCk7CiAgICBrdCA9IGZkY3RybC0+Zmlmb1s2XTsKICAgIGtoID0gZmRjdHJsLT5maWZvWzddOwogICAga3MgPSBmZGN0cmwtPmZpZm9bOF07CiAgICBGTE9QUFlfRFBSSU5URigiZm9ybWF0IHNlY3RvciBhdCAlZCAlZCAlMDJ4ICUwMnggKCVkKVxuIiwKICAgICAgICAgICAgICAgICAgIEdFVF9DVVJfRFJWKGZkY3RybCksIGtoLCBrdCwga3MsCiAgICAgICAgICAgICAgICAgICBfZmRfc2VjdG9yKGtoLCBrdCwga3MsIGN1cl9kcnYtPmxhc3Rfc2VjdCkpOwogICAgc3dpdGNoIChmZF9zZWVrKGN1cl9kcnYsIGtoLCBrdCwga3MsIGZkY3RybC0+Y29uZmlnICYgRkRfQ09ORklHX0VJUykpIHsKICAgIGNhc2UgMjoKICAgICAgICAvKiBzZWN0IHRvbyBiaWcgKi8KICAgICAgICBmZGN0cmxfc3RvcF90cmFuc2ZlcihmZGN0cmwsIEZEX1NSMF9BQk5URVJNLCAweDAwLCAweDAwKTsKICAgICAgICBmZGN0cmwtPmZpZm9bM10gPSBrdDsKICAgICAgICBmZGN0cmwtPmZpZm9bNF0gPSBraDsKICAgICAgICBmZGN0cmwtPmZpZm9bNV0gPSBrczsKICAgICAgICByZXR1cm47CiAgICBjYXNlIDM6CiAgICAgICAgLyogdHJhY2sgdG9vIGJpZyAqLwogICAgICAgIGZkY3RybF9zdG9wX3RyYW5zZmVyKGZkY3RybCwgRkRfU1IwX0FCTlRFUk0sIEZEX1NSMV9FQywgMHgwMCk7CiAgICAgICAgZmRjdHJsLT5maWZvWzNdID0ga3Q7CiAgICAgICAgZmRjdHJsLT5maWZvWzRdID0ga2g7CiAgICAgICAgZmRjdHJsLT5maWZvWzVdID0ga3M7CiAgICAgICAgcmV0dXJuOwogICAgY2FzZSA0OgogICAgICAgIC8qIE5vIHNlZWsgZW5hYmxlZCAqLwogICAgICAgIGZkY3RybF9zdG9wX3RyYW5zZmVyKGZkY3RybCwgRkRfU1IwX0FCTlRFUk0sIDB4MDAsIDB4MDApOwogICAgICAgIGZkY3RybC0+Zmlmb1szXSA9IGt0OwogICAgICAgIGZkY3RybC0+Zmlmb1s0XSA9IGtoOwogICAgICAgIGZkY3RybC0+Zmlmb1s1XSA9IGtzOwogICAgICAgIHJldHVybjsKICAgIGNhc2UgMToKICAgICAgICBmZGN0cmwtPmRhdGFfc3RhdGUgfD0gRkRfU1RBVEVfU0VFSzsKICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgYnJlYWs7CiAgICB9CiAgICBtZW1zZXQoZmRjdHJsLT5maWZvLCAwLCBGRF9TRUNUT1JfTEVOKTsKICAgIGlmIChjdXJfZHJ2LT5icyA9PSBOVUxMIHx8CiAgICAgICAgYmRydl93cml0ZShjdXJfZHJ2LT5icywgZmRfc2VjdG9yKGN1cl9kcnYpLCBmZGN0cmwtPmZpZm8sIDEpIDwgMCkgewogICAgICAgIEZMT1BQWV9FUlJPUigiZm9ybWF0dGluZyBzZWN0b3IgJWRcbiIsIGZkX3NlY3RvcihjdXJfZHJ2KSk7CiAgICAgICAgZmRjdHJsX3N0b3BfdHJhbnNmZXIoZmRjdHJsLCBGRF9TUjBfQUJOVEVSTSB8IEZEX1NSMF9TRUVLLCAweDAwLCAweDAwKTsKICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKGN1cl9kcnYtPnNlY3QgPT0gY3VyX2Rydi0+bGFzdF9zZWN0KSB7CiAgICAgICAgICAgIGZkY3RybC0+ZGF0YV9zdGF0ZSAmPSB+RkRfU1RBVEVfRk9STUFUOwogICAgICAgICAgICAvKiBMYXN0IHNlY3RvciBkb25lICovCiAgICAgICAgICAgIGlmIChGRF9ESURfU0VFSyhmZGN0cmwtPmRhdGFfc3RhdGUpKQogICAgICAgICAgICAgICAgZmRjdHJsX3N0b3BfdHJhbnNmZXIoZmRjdHJsLCBGRF9TUjBfU0VFSywgMHgwMCwgMHgwMCk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGZkY3RybF9zdG9wX3RyYW5zZmVyKGZkY3RybCwgMHgwMCwgMHgwMCwgMHgwMCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyogTW9yZSB0byBkbyAqLwogICAgICAgICAgICBmZGN0cmwtPmRhdGFfcG9zID0gMDsKICAgICAgICAgICAgZmRjdHJsLT5kYXRhX2xlbiA9IDQ7CiAgICAgICAgfQogICAgfQp9CgpzdGF0aWMgdm9pZCBmZGN0cmxfaGFuZGxlX2xvY2sgKGZkY3RybF90ICpmZGN0cmwsIGludCBkaXJlY3Rpb24pCnsKICAgIGZkY3RybC0+bG9jayA9IChmZGN0cmwtPmZpZm9bMF0gJiAweDgwKSA/IDEgOiAwOwogICAgZmRjdHJsLT5maWZvWzBdID0gZmRjdHJsLT5sb2NrIDw8IDQ7CiAgICBmZGN0cmxfc2V0X2ZpZm8oZmRjdHJsLCAxLCBmZGN0cmwtPmxvY2spOwp9CgpzdGF0aWMgdm9pZCBmZGN0cmxfaGFuZGxlX2R1bXByZWcgKGZkY3RybF90ICpmZGN0cmwsIGludCBkaXJlY3Rpb24pCnsKICAgIGZkcml2ZV90ICpjdXJfZHJ2ID0gZ2V0X2N1cl9kcnYoZmRjdHJsKTsKCiAgICAvKiBEcml2ZXMgcG9zaXRpb24gKi8KICAgIGZkY3RybC0+Zmlmb1swXSA9IGRydjAoZmRjdHJsKS0+dHJhY2s7CiAgICBmZGN0cmwtPmZpZm9bMV0gPSBkcnYxKGZkY3RybCktPnRyYWNrOwojaWYgTUFYX0ZEID09IDQKICAgIGZkY3RybC0+Zmlmb1syXSA9IGRydjIoZmRjdHJsKS0+dHJhY2s7CiAgICBmZGN0cmwtPmZpZm9bM10gPSBkcnYzKGZkY3RybCktPnRyYWNrOwojZWxzZQogICAgZmRjdHJsLT5maWZvWzJdID0gMDsKICAgIGZkY3RybC0+Zmlmb1szXSA9IDA7CiNlbmRpZgogICAgLyogdGltZXJzICovCiAgICBmZGN0cmwtPmZpZm9bNF0gPSBmZGN0cmwtPnRpbWVyMDsKICAgIGZkY3RybC0+Zmlmb1s1XSA9IChmZGN0cmwtPnRpbWVyMSA8PCAxKSB8IChmZGN0cmwtPmRvciAmIEZEX0RPUl9ETUFFTiA/IDEgOiAwKTsKICAgIGZkY3RybC0+Zmlmb1s2XSA9IGN1cl9kcnYtPmxhc3Rfc2VjdDsKICAgIGZkY3RybC0+Zmlmb1s3XSA9IChmZGN0cmwtPmxvY2sgPDwgNykgfAogICAgICAgIChjdXJfZHJ2LT5wZXJwZW5kaWN1bGFyIDw8IDIpOwogICAgZmRjdHJsLT5maWZvWzhdID0gZmRjdHJsLT5jb25maWc7CiAgICBmZGN0cmwtPmZpZm9bOV0gPSBmZGN0cmwtPnByZWNvbXBfdHJrOwogICAgZmRjdHJsX3NldF9maWZvKGZkY3RybCwgMTAsIDApOwp9CgpzdGF0aWMgdm9pZCBmZGN0cmxfaGFuZGxlX3ZlcnNpb24gKGZkY3RybF90ICpmZGN0cmwsIGludCBkaXJlY3Rpb24pCnsKICAgIC8qIENvbnRyb2xsZXIncyB2ZXJzaW9uICovCiAgICBmZGN0cmwtPmZpZm9bMF0gPSBmZGN0cmwtPnZlcnNpb247CiAgICBmZGN0cmxfc2V0X2ZpZm8oZmRjdHJsLCAxLCAxKTsKfQoKc3RhdGljIHZvaWQgZmRjdHJsX2hhbmRsZV9wYXJ0aWQgKGZkY3RybF90ICpmZGN0cmwsIGludCBkaXJlY3Rpb24pCnsKICAgIGZkY3RybC0+Zmlmb1swXSA9IDB4NDE7IC8qIFN0ZXBwaW5nIDEgKi8KICAgIGZkY3RybF9zZXRfZmlmbyhmZGN0cmwsIDEsIDApOwp9CgpzdGF0aWMgdm9pZCBmZGN0cmxfaGFuZGxlX3Jlc3RvcmUgKGZkY3RybF90ICpmZGN0cmwsIGludCBkaXJlY3Rpb24pCnsKICAgIGZkcml2ZV90ICpjdXJfZHJ2ID0gZ2V0X2N1cl9kcnYoZmRjdHJsKTsKCiAgICAvKiBEcml2ZXMgcG9zaXRpb24gKi8KICAgIGRydjAoZmRjdHJsKS0+dHJhY2sgPSBmZGN0cmwtPmZpZm9bM107CiAgICBkcnYxKGZkY3RybCktPnRyYWNrID0gZmRjdHJsLT5maWZvWzRdOwojaWYgTUFYX0ZEID09IDQKICAgIGRydjIoZmRjdHJsKS0+dHJhY2sgPSBmZGN0cmwtPmZpZm9bNV07CiAgICBkcnYzKGZkY3RybCktPnRyYWNrID0gZmRjdHJsLT5maWZvWzZdOwojZW5kaWYKICAgIC8qIHRpbWVycyAqLwogICAgZmRjdHJsLT50aW1lcjAgPSBmZGN0cmwtPmZpZm9bN107CiAgICBmZGN0cmwtPnRpbWVyMSA9IGZkY3RybC0+Zmlmb1s4XTsKICAgIGN1cl9kcnYtPmxhc3Rfc2VjdCA9IGZkY3RybC0+Zmlmb1s5XTsKICAgIGZkY3RybC0+bG9jayA9IGZkY3RybC0+Zmlmb1sxMF0gPj4gNzsKICAgIGN1cl9kcnYtPnBlcnBlbmRpY3VsYXIgPSAoZmRjdHJsLT5maWZvWzEwXSA+PiAyKSAmIDB4RjsKICAgIGZkY3RybC0+Y29uZmlnID0gZmRjdHJsLT5maWZvWzExXTsKICAgIGZkY3RybC0+cHJlY29tcF90cmsgPSBmZGN0cmwtPmZpZm9bMTJdOwogICAgZmRjdHJsLT5wd3JkID0gZmRjdHJsLT5maWZvWzEzXTsKICAgIGZkY3RybF9yZXNldF9maWZvKGZkY3RybCk7Cn0KCnN0YXRpYyB2b2lkIGZkY3RybF9oYW5kbGVfc2F2ZSAoZmRjdHJsX3QgKmZkY3RybCwgaW50IGRpcmVjdGlvbikKewogICAgZmRyaXZlX3QgKmN1cl9kcnYgPSBnZXRfY3VyX2RydihmZGN0cmwpOwoKICAgIGZkY3RybC0+Zmlmb1swXSA9IDA7CiAgICBmZGN0cmwtPmZpZm9bMV0gPSAwOwogICAgLyogRHJpdmVzIHBvc2l0aW9uICovCiAgICBmZGN0cmwtPmZpZm9bMl0gPSBkcnYwKGZkY3RybCktPnRyYWNrOwogICAgZmRjdHJsLT5maWZvWzNdID0gZHJ2MShmZGN0cmwpLT50cmFjazsKI2lmIE1BWF9GRCA9PSA0CiAgICBmZGN0cmwtPmZpZm9bNF0gPSBkcnYyKGZkY3RybCktPnRyYWNrOwogICAgZmRjdHJsLT5maWZvWzVdID0gZHJ2MyhmZGN0cmwpLT50cmFjazsKI2Vsc2UKICAgIGZkY3RybC0+Zmlmb1s0XSA9IDA7CiAgICBmZGN0cmwtPmZpZm9bNV0gPSAwOwojZW5kaWYKICAgIC8qIHRpbWVycyAqLwogICAgZmRjdHJsLT5maWZvWzZdID0gZmRjdHJsLT50aW1lcjA7CiAgICBmZGN0cmwtPmZpZm9bN10gPSBmZGN0cmwtPnRpbWVyMTsKICAgIGZkY3RybC0+Zmlmb1s4XSA9IGN1cl9kcnYtPmxhc3Rfc2VjdDsKICAgIGZkY3RybC0+Zmlmb1s5XSA9IChmZGN0cmwtPmxvY2sgPDwgNykgfAogICAgICAgIChjdXJfZHJ2LT5wZXJwZW5kaWN1bGFyIDw8IDIpOwogICAgZmRjdHJsLT5maWZvWzEwXSA9IGZkY3RybC0+Y29uZmlnOwogICAgZmRjdHJsLT5maWZvWzExXSA9IGZkY3RybC0+cHJlY29tcF90cms7CiAgICBmZGN0cmwtPmZpZm9bMTJdID0gZmRjdHJsLT5wd3JkOwogICAgZmRjdHJsLT5maWZvWzEzXSA9IDA7CiAgICBmZGN0cmwtPmZpZm9bMTRdID0gMDsKICAgIGZkY3RybF9zZXRfZmlmbyhmZGN0cmwsIDE1LCAxKTsKfQoKc3RhdGljIHZvaWQgZmRjdHJsX2hhbmRsZV9yZWFkaWQgKGZkY3RybF90ICpmZGN0cmwsIGludCBkaXJlY3Rpb24pCnsKICAgIGZkcml2ZV90ICpjdXJfZHJ2ID0gZ2V0X2N1cl9kcnYoZmRjdHJsKTsKCiAgICAvKiBYWFg6IHNob3VsZCBzZXQgbWFpbiBzdGF0dXMgcmVnaXN0ZXIgdG8gYnVzeSAqLwogICAgY3VyX2Rydi0+aGVhZCA9IChmZGN0cmwtPmZpZm9bMV0gPj4gMikgJiAxOwogICAgcWVtdV9tb2RfdGltZXIoZmRjdHJsLT5yZXN1bHRfdGltZXIsCiAgICAgICAgICAgICAgICAgICBxZW11X2dldF9jbG9jayh2bV9jbG9jaykgKyAodGlja3NfcGVyX3NlYyAvIDUwKSk7Cn0KCnN0YXRpYyB2b2lkIGZkY3RybF9oYW5kbGVfZm9ybWF0X3RyYWNrIChmZGN0cmxfdCAqZmRjdHJsLCBpbnQgZGlyZWN0aW9uKQp7CiAgICBmZHJpdmVfdCAqY3VyX2RydjsKCiAgICBTRVRfQ1VSX0RSVihmZGN0cmwsIGZkY3RybC0+Zmlmb1sxXSAmIEZEX0RPUl9TRUxNQVNLKTsKICAgIGN1cl9kcnYgPSBnZXRfY3VyX2RydihmZGN0cmwpOwogICAgZmRjdHJsLT5kYXRhX3N0YXRlIHw9IEZEX1NUQVRFX0ZPUk1BVDsKICAgIGlmIChmZGN0cmwtPmZpZm9bMF0gJiAweDgwKQogICAgICAgIGZkY3RybC0+ZGF0YV9zdGF0ZSB8PSBGRF9TVEFURV9NVUxUSTsKICAgIGVsc2UKICAgICAgICBmZGN0cmwtPmRhdGFfc3RhdGUgJj0gfkZEX1NUQVRFX01VTFRJOwogICAgZmRjdHJsLT5kYXRhX3N0YXRlICY9IH5GRF9TVEFURV9TRUVLOwogICAgY3VyX2Rydi0+YnBzID0KICAgICAgICBmZGN0cmwtPmZpZm9bMl0gPiA3ID8gMTYzODQgOiAxMjggPDwgZmRjdHJsLT5maWZvWzJdOwojaWYgMAogICAgY3VyX2Rydi0+bGFzdF9zZWN0ID0KICAgICAgICBjdXJfZHJ2LT5mbGFncyAmIEZESVNLX0RCTF9TSURFUyA/IGZkY3RybC0+Zmlmb1szXSA6CiAgICAgICAgZmRjdHJsLT5maWZvWzNdIC8gMjsKI2Vsc2UKICAgIGN1cl9kcnYtPmxhc3Rfc2VjdCA9IGZkY3RybC0+Zmlmb1szXTsKI2VuZGlmCiAgICAvKiBUT0RPOiBpbXBsZW1lbnQgZm9ybWF0IHVzaW5nIERNQSBleHBlY3RlZCBieSB0aGUgQm9jaHMgQklPUwogICAgICogYW5kIExpbnV4IGZkZm9ybWF0IChyZWFkIDMgYnl0ZXMgcGVyIHNlY3RvciB2aWEgRE1BIGFuZCBmaWxsCiAgICAgKiB0aGUgc2VjdG9yIHdpdGggdGhlIHNwZWNpZmllZCBmaWxsIGJ5dGUKICAgICAqLwogICAgZmRjdHJsLT5kYXRhX3N0YXRlICY9IH5GRF9TVEFURV9GT1JNQVQ7CiAgICBmZGN0cmxfc3RvcF90cmFuc2ZlcihmZGN0cmwsIDB4MDAsIDB4MDAsIDB4MDApOwp9CgpzdGF0aWMgdm9pZCBmZGN0cmxfaGFuZGxlX3NwZWNpZnkgKGZkY3RybF90ICpmZGN0cmwsIGludCBkaXJlY3Rpb24pCnsKICAgIGZkY3RybC0+dGltZXIwID0gKGZkY3RybC0+Zmlmb1sxXSA+PiA0KSAmIDB4RjsKICAgIGZkY3RybC0+dGltZXIxID0gZmRjdHJsLT5maWZvWzJdID4+IDE7CiAgICBpZiAoZmRjdHJsLT5maWZvWzJdICYgMSkKICAgICAgICBmZGN0cmwtPmRvciAmPSB+RkRfRE9SX0RNQUVOOwogICAgZWxzZQogICAgICAgIGZkY3RybC0+ZG9yIHw9IEZEX0RPUl9ETUFFTjsKICAgIC8qIE5vIHJlc3VsdCBiYWNrICovCiAgICBmZGN0cmxfcmVzZXRfZmlmbyhmZGN0cmwpOwp9CgpzdGF0aWMgdm9pZCBmZGN0cmxfaGFuZGxlX3NlbnNlX2RyaXZlX3N0YXR1cyAoZmRjdHJsX3QgKmZkY3RybCwgaW50IGRpcmVjdGlvbikKewogICAgZmRyaXZlX3QgKmN1cl9kcnY7CgogICAgU0VUX0NVUl9EUlYoZmRjdHJsLCBmZGN0cmwtPmZpZm9bMV0gJiBGRF9ET1JfU0VMTUFTSyk7CiAgICBjdXJfZHJ2ID0gZ2V0X2N1cl9kcnYoZmRjdHJsKTsKICAgIGN1cl9kcnYtPmhlYWQgPSAoZmRjdHJsLT5maWZvWzFdID4+IDIpICYgMTsKICAgIC8qIDEgQnl0ZSBzdGF0dXMgYmFjayAqLwogICAgZmRjdHJsLT5maWZvWzBdID0gKGN1cl9kcnYtPnJvIDw8IDYpIHwKICAgICAgICAoY3VyX2Rydi0+dHJhY2sgPT0gMCA/IDB4MTAgOiAweDAwKSB8CiAgICAgICAgKGN1cl9kcnYtPmhlYWQgPDwgMikgfAogICAgICAgIEdFVF9DVVJfRFJWKGZkY3RybCkgfAogICAgICAgIDB4Mjg7CiAgICBmZGN0cmxfc2V0X2ZpZm8oZmRjdHJsLCAxLCAwKTsKfQoKc3RhdGljIHZvaWQgZmRjdHJsX2hhbmRsZV9yZWNhbGlicmF0ZSAoZmRjdHJsX3QgKmZkY3RybCwgaW50IGRpcmVjdGlvbikKewogICAgZmRyaXZlX3QgKmN1cl9kcnY7CgogICAgU0VUX0NVUl9EUlYoZmRjdHJsLCBmZGN0cmwtPmZpZm9bMV0gJiBGRF9ET1JfU0VMTUFTSyk7CiAgICBjdXJfZHJ2ID0gZ2V0X2N1cl9kcnYoZmRjdHJsKTsKICAgIGZkX3JlY2FsaWJyYXRlKGN1cl9kcnYpOwogICAgZmRjdHJsX3Jlc2V0X2ZpZm8oZmRjdHJsKTsKICAgIC8qIFJhaXNlIEludGVycnVwdCAqLwogICAgZmRjdHJsX3JhaXNlX2lycShmZGN0cmwsIEZEX1NSMF9TRUVLKTsKfQoKc3RhdGljIHZvaWQgZmRjdHJsX2hhbmRsZV9zZW5zZV9pbnRlcnJ1cHRfc3RhdHVzIChmZGN0cmxfdCAqZmRjdHJsLCBpbnQgZGlyZWN0aW9uKQp7CiAgICBmZHJpdmVfdCAqY3VyX2RydiA9IGdldF9jdXJfZHJ2KGZkY3RybCk7CgogICAgaWYoZmRjdHJsLT5yZXNldF9zZW5zZWkgPiAwKSB7CiAgICAgICAgZmRjdHJsLT5maWZvWzBdID0KICAgICAgICAgICAgRkRfU1IwX1JEWUNIRyArIEZEX1JFU0VUX1NFTlNFSV9DT1VOVCAtIGZkY3RybC0+cmVzZXRfc2Vuc2VpOwogICAgICAgIGZkY3RybC0+cmVzZXRfc2Vuc2VpLS07CiAgICB9IGVsc2UgewogICAgICAgIC8qIFhYWDogc3RhdHVzMCBoYW5kbGluZyBpcyBicm9rZW4gZm9yIHJlYWQvd3JpdGUKICAgICAgICAgICBjb21tYW5kcywgc28gd2UgZG8gdGhpcyBoYWNrLiBJdCBzaG91bGQgYmUgc3VwcHJlc3NlZAogICAgICAgICAgIEFTQVAgKi8KICAgICAgICBmZGN0cmwtPmZpZm9bMF0gPQogICAgICAgICAgICBGRF9TUjBfU0VFSyB8IChjdXJfZHJ2LT5oZWFkIDw8IDIpIHwgR0VUX0NVUl9EUlYoZmRjdHJsKTsKICAgIH0KCiAgICBmZGN0cmwtPmZpZm9bMV0gPSBjdXJfZHJ2LT50cmFjazsKICAgIGZkY3RybF9zZXRfZmlmbyhmZGN0cmwsIDIsIDApOwogICAgZmRjdHJsX3Jlc2V0X2lycShmZGN0cmwpOwogICAgZmRjdHJsLT5zdGF0dXMwID0gRkRfU1IwX1JEWUNIRzsKfQoKc3RhdGljIHZvaWQgZmRjdHJsX2hhbmRsZV9zZWVrIChmZGN0cmxfdCAqZmRjdHJsLCBpbnQgZGlyZWN0aW9uKQp7CiAgICBmZHJpdmVfdCAqY3VyX2RydjsKCiAgICBTRVRfQ1VSX0RSVihmZGN0cmwsIGZkY3RybC0+Zmlmb1sxXSAmIEZEX0RPUl9TRUxNQVNLKTsKICAgIGN1cl9kcnYgPSBnZXRfY3VyX2RydihmZGN0cmwpOwogICAgZmRjdHJsX3Jlc2V0X2ZpZm8oZmRjdHJsKTsKICAgIGlmIChmZGN0cmwtPmZpZm9bMl0gPiBjdXJfZHJ2LT5tYXhfdHJhY2spIHsKICAgICAgICBmZGN0cmxfcmFpc2VfaXJxKGZkY3RybCwgRkRfU1IwX0FCTlRFUk0gfCBGRF9TUjBfU0VFSyk7CiAgICB9IGVsc2UgewogICAgICAgIGN1cl9kcnYtPnRyYWNrID0gZmRjdHJsLT5maWZvWzJdOwogICAgICAgIC8qIFJhaXNlIEludGVycnVwdCAqLwogICAgICAgIGZkY3RybF9yYWlzZV9pcnEoZmRjdHJsLCBGRF9TUjBfU0VFSyk7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIGZkY3RybF9oYW5kbGVfcGVycGVuZGljdWxhcl9tb2RlIChmZGN0cmxfdCAqZmRjdHJsLCBpbnQgZGlyZWN0aW9uKQp7CiAgICBmZHJpdmVfdCAqY3VyX2RydiA9IGdldF9jdXJfZHJ2KGZkY3RybCk7CgogICAgaWYgKGZkY3RybC0+Zmlmb1sxXSAmIDB4ODApCiAgICAgICAgY3VyX2Rydi0+cGVycGVuZGljdWxhciA9IGZkY3RybC0+Zmlmb1sxXSAmIDB4NzsKICAgIC8qIE5vIHJlc3VsdCBiYWNrICovCiAgICBmZGN0cmxfcmVzZXRfZmlmbyhmZGN0cmwpOwp9CgpzdGF0aWMgdm9pZCBmZGN0cmxfaGFuZGxlX2NvbmZpZ3VyZSAoZmRjdHJsX3QgKmZkY3RybCwgaW50IGRpcmVjdGlvbikKewogICAgZmRjdHJsLT5jb25maWcgPSBmZGN0cmwtPmZpZm9bMl07CiAgICBmZGN0cmwtPnByZWNvbXBfdHJrID0gIGZkY3RybC0+Zmlmb1szXTsKICAgIC8qIE5vIHJlc3VsdCBiYWNrICovCiAgICBmZGN0cmxfcmVzZXRfZmlmbyhmZGN0cmwpOwp9CgpzdGF0aWMgdm9pZCBmZGN0cmxfaGFuZGxlX3Bvd2VyZG93bl9tb2RlIChmZGN0cmxfdCAqZmRjdHJsLCBpbnQgZGlyZWN0aW9uKQp7CiAgICBmZGN0cmwtPnB3cmQgPSBmZGN0cmwtPmZpZm9bMV07CiAgICBmZGN0cmwtPmZpZm9bMF0gPSBmZGN0cmwtPmZpZm9bMV07CiAgICBmZGN0cmxfc2V0X2ZpZm8oZmRjdHJsLCAxLCAxKTsKfQoKc3RhdGljIHZvaWQgZmRjdHJsX2hhbmRsZV9vcHRpb24gKGZkY3RybF90ICpmZGN0cmwsIGludCBkaXJlY3Rpb24pCnsKICAgIC8qIE5vIHJlc3VsdCBiYWNrICovCiAgICBmZGN0cmxfcmVzZXRfZmlmbyhmZGN0cmwpOwp9CgpzdGF0aWMgdm9pZCBmZGN0cmxfaGFuZGxlX2RyaXZlX3NwZWNpZmljYXRpb25fY29tbWFuZCAoZmRjdHJsX3QgKmZkY3RybCwgaW50IGRpcmVjdGlvbikKewogICAgZmRyaXZlX3QgKmN1cl9kcnYgPSBnZXRfY3VyX2RydihmZGN0cmwpOwoKICAgIGlmIChmZGN0cmwtPmZpZm9bZmRjdHJsLT5kYXRhX3BvcyAtIDFdICYgMHg4MCkgewogICAgICAgIC8qIENvbW1hbmQgcGFyYW1ldGVycyBkb25lICovCiAgICAgICAgaWYgKGZkY3RybC0+Zmlmb1tmZGN0cmwtPmRhdGFfcG9zIC0gMV0gJiAweDQwKSB7CiAgICAgICAgICAgIGZkY3RybC0+Zmlmb1swXSA9IGZkY3RybC0+Zmlmb1sxXTsKICAgICAgICAgICAgZmRjdHJsLT5maWZvWzJdID0gMDsKICAgICAgICAgICAgZmRjdHJsLT5maWZvWzNdID0gMDsKICAgICAgICAgICAgZmRjdHJsX3NldF9maWZvKGZkY3RybCwgNCwgMSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZmRjdHJsX3Jlc2V0X2ZpZm8oZmRjdHJsKTsKICAgICAgICB9CiAgICB9IGVsc2UgaWYgKGZkY3RybC0+ZGF0YV9sZW4gPiA3KSB7CiAgICAgICAgLyogRVJST1IgKi8KICAgICAgICBmZGN0cmwtPmZpZm9bMF0gPSAweDgwIHwKICAgICAgICAgICAgKGN1cl9kcnYtPmhlYWQgPDwgMikgfCBHRVRfQ1VSX0RSVihmZGN0cmwpOwogICAgICAgIGZkY3RybF9zZXRfZmlmbyhmZGN0cmwsIDEsIDEpOwogICAgfQp9CgpzdGF0aWMgdm9pZCBmZGN0cmxfaGFuZGxlX3JlbGF0aXZlX3NlZWtfb3V0IChmZGN0cmxfdCAqZmRjdHJsLCBpbnQgZGlyZWN0aW9uKQp7CiAgICBmZHJpdmVfdCAqY3VyX2RydjsKCiAgICBTRVRfQ1VSX0RSVihmZGN0cmwsIGZkY3RybC0+Zmlmb1sxXSAmIEZEX0RPUl9TRUxNQVNLKTsKICAgIGN1cl9kcnYgPSBnZXRfY3VyX2RydihmZGN0cmwpOwogICAgaWYgKGZkY3RybC0+Zmlmb1syXSArIGN1cl9kcnYtPnRyYWNrID49IGN1cl9kcnYtPm1heF90cmFjaykgewogICAgICAgIGN1cl9kcnYtPnRyYWNrID0gY3VyX2Rydi0+bWF4X3RyYWNrIC0gMTsKICAgIH0gZWxzZSB7CiAgICAgICAgY3VyX2Rydi0+dHJhY2sgKz0gZmRjdHJsLT5maWZvWzJdOwogICAgfQogICAgZmRjdHJsX3Jlc2V0X2ZpZm8oZmRjdHJsKTsKICAgIC8qIFJhaXNlIEludGVycnVwdCAqLwogICAgZmRjdHJsX3JhaXNlX2lycShmZGN0cmwsIEZEX1NSMF9TRUVLKTsKfQoKc3RhdGljIHZvaWQgZmRjdHJsX2hhbmRsZV9yZWxhdGl2ZV9zZWVrX2luIChmZGN0cmxfdCAqZmRjdHJsLCBpbnQgZGlyZWN0aW9uKQp7CiAgICBmZHJpdmVfdCAqY3VyX2RydjsKCiAgICBTRVRfQ1VSX0RSVihmZGN0cmwsIGZkY3RybC0+Zmlmb1sxXSAmIEZEX0RPUl9TRUxNQVNLKTsKICAgIGN1cl9kcnYgPSBnZXRfY3VyX2RydihmZGN0cmwpOwogICAgaWYgKGZkY3RybC0+Zmlmb1syXSA+IGN1cl9kcnYtPnRyYWNrKSB7CiAgICAgICAgY3VyX2Rydi0+dHJhY2sgPSAwOwogICAgfSBlbHNlIHsKICAgICAgICBjdXJfZHJ2LT50cmFjayAtPSBmZGN0cmwtPmZpZm9bMl07CiAgICB9CiAgICBmZGN0cmxfcmVzZXRfZmlmbyhmZGN0cmwpOwogICAgLyogUmFpc2UgSW50ZXJydXB0ICovCiAgICBmZGN0cmxfcmFpc2VfaXJxKGZkY3RybCwgRkRfU1IwX1NFRUspOwp9CgpzdGF0aWMgY29uc3Qgc3RydWN0IHsKICAgIHVpbnQ4X3QgdmFsdWU7CiAgICB1aW50OF90IG1hc2s7CiAgICBjb25zdCBjaGFyKiBuYW1lOwogICAgaW50IHBhcmFtZXRlcnM7CiAgICB2b2lkICgqaGFuZGxlcikoZmRjdHJsX3QgKmZkY3RybCwgaW50IGRpcmVjdGlvbik7CiAgICBpbnQgZGlyZWN0aW9uOwp9IGhhbmRsZXJzW10gPSB7CiAgICB7IEZEX0NNRF9SRUFELCAweDFmLCAiUkVBRCIsIDgsIGZkY3RybF9zdGFydF90cmFuc2ZlciwgRkRfRElSX1JFQUQgfSwKICAgIHsgRkRfQ01EX1dSSVRFLCAweDNmLCAiV1JJVEUiLCA4LCBmZGN0cmxfc3RhcnRfdHJhbnNmZXIsIEZEX0RJUl9XUklURSB9LAogICAgeyBGRF9DTURfU0VFSywgMHhmZiwgIlNFRUsiLCAyLCBmZGN0cmxfaGFuZGxlX3NlZWsgfSwKICAgIHsgRkRfQ01EX1NFTlNFX0lOVEVSUlVQVF9TVEFUVVMsIDB4ZmYsICJTRU5TRSBJTlRFUlJVUFQgU1RBVFVTIiwgMCwgZmRjdHJsX2hhbmRsZV9zZW5zZV9pbnRlcnJ1cHRfc3RhdHVzIH0sCiAgICB7IEZEX0NNRF9SRUNBTElCUkFURSwgMHhmZiwgIlJFQ0FMSUJSQVRFIiwgMSwgZmRjdHJsX2hhbmRsZV9yZWNhbGlicmF0ZSB9LAogICAgeyBGRF9DTURfRk9STUFUX1RSQUNLLCAweGJmLCAiRk9STUFUIFRSQUNLIiwgNSwgZmRjdHJsX2hhbmRsZV9mb3JtYXRfdHJhY2sgfSwKICAgIHsgRkRfQ01EX1JFQURfVFJBQ0ssIDB4YmYsICJSRUFEIFRSQUNLIiwgOCwgZmRjdHJsX3N0YXJ0X3RyYW5zZmVyLCBGRF9ESVJfUkVBRCB9LAogICAgeyBGRF9DTURfUkVTVE9SRSwgMHhmZiwgIlJFU1RPUkUiLCAxNywgZmRjdHJsX2hhbmRsZV9yZXN0b3JlIH0sIC8qIHBhcnQgb2YgUkVBRCBERUxFVEVEIERBVEEgKi8KICAgIHsgRkRfQ01EX1NBVkUsIDB4ZmYsICJTQVZFIiwgMCwgZmRjdHJsX2hhbmRsZV9zYXZlIH0sIC8qIHBhcnQgb2YgUkVBRCBERUxFVEVEIERBVEEgKi8KICAgIHsgRkRfQ01EX1JFQURfREVMRVRFRCwgMHgxZiwgIlJFQUQgREVMRVRFRCBEQVRBIiwgOCwgZmRjdHJsX3N0YXJ0X3RyYW5zZmVyX2RlbCwgRkRfRElSX1JFQUQgfSwKICAgIHsgRkRfQ01EX1NDQU5fRVFVQUwsIDB4MWYsICJTQ0FOIEVRVUFMIiwgOCwgZmRjdHJsX3N0YXJ0X3RyYW5zZmVyLCBGRF9ESVJfU0NBTkUgfSwKICAgIHsgRkRfQ01EX1ZFUklGWSwgMHgxZiwgIlZFUklGWSIsIDgsIGZkY3RybF91bmltcGxlbWVudGVkIH0sCiAgICB7IEZEX0NNRF9TQ0FOX0xPV19PUl9FUVVBTCwgMHgxZiwgIlNDQU4gTE9XIE9SIEVRVUFMIiwgOCwgZmRjdHJsX3N0YXJ0X3RyYW5zZmVyLCBGRF9ESVJfU0NBTkwgfSwKICAgIHsgRkRfQ01EX1NDQU5fSElHSF9PUl9FUVVBTCwgMHgxZiwgIlNDQU4gSElHSCBPUiBFUVVBTCIsIDgsIGZkY3RybF9zdGFydF90cmFuc2ZlciwgRkRfRElSX1NDQU5IIH0sCiAgICB7IEZEX0NNRF9XUklURV9ERUxFVEVELCAweDNmLCAiV1JJVEUgREVMRVRFRCBEQVRBIiwgOCwgZmRjdHJsX3N0YXJ0X3RyYW5zZmVyX2RlbCwgRkRfRElSX1dSSVRFIH0sCiAgICB7IEZEX0NNRF9SRUFEX0lELCAweGJmLCAiUkVBRCBJRCIsIDEsIGZkY3RybF9oYW5kbGVfcmVhZGlkIH0sCiAgICB7IEZEX0NNRF9TUEVDSUZZLCAweGZmLCAiU1BFQ0lGWSIsIDIsIGZkY3RybF9oYW5kbGVfc3BlY2lmeSB9LAogICAgeyBGRF9DTURfU0VOU0VfRFJJVkVfU1RBVFVTLCAweGZmLCAiU0VOU0UgRFJJVkUgU1RBVFVTIiwgMSwgZmRjdHJsX2hhbmRsZV9zZW5zZV9kcml2ZV9zdGF0dXMgfSwKICAgIHsgRkRfQ01EX1BFUlBFTkRJQ1VMQVJfTU9ERSwgMHhmZiwgIlBFUlBFTkRJQ1VMQVIgTU9ERSIsIDEsIGZkY3RybF9oYW5kbGVfcGVycGVuZGljdWxhcl9tb2RlIH0sCiAgICB7IEZEX0NNRF9DT05GSUdVUkUsIDB4ZmYsICJDT05GSUdVUkUiLCAzLCBmZGN0cmxfaGFuZGxlX2NvbmZpZ3VyZSB9LAogICAgeyBGRF9DTURfUE9XRVJET1dOX01PREUsIDB4ZmYsICJQT1dFUkRPV04gTU9ERSIsIDIsIGZkY3RybF9oYW5kbGVfcG93ZXJkb3duX21vZGUgfSwKICAgIHsgRkRfQ01EX09QVElPTiwgMHhmZiwgIk9QVElPTiIsIDEsIGZkY3RybF9oYW5kbGVfb3B0aW9uIH0sCiAgICB7IEZEX0NNRF9EUklWRV9TUEVDSUZJQ0FUSU9OX0NPTU1BTkQsIDB4ZmYsICJEUklWRSBTUEVDSUZJQ0FUSU9OIENPTU1BTkQiLCA1LCBmZGN0cmxfaGFuZGxlX2RyaXZlX3NwZWNpZmljYXRpb25fY29tbWFuZCB9LAogICAgeyBGRF9DTURfUkVMQVRJVkVfU0VFS19PVVQsIDB4ZmYsICJSRUxBVElWRSBTRUVLIE9VVCIsIDIsIGZkY3RybF9oYW5kbGVfcmVsYXRpdmVfc2Vla19vdXQgfSwKICAgIHsgRkRfQ01EX0ZPUk1BVF9BTkRfV1JJVEUsIDB4ZmYsICJGT1JNQVQgQU5EIFdSSVRFIiwgMTAsIGZkY3RybF91bmltcGxlbWVudGVkIH0sCiAgICB7IEZEX0NNRF9SRUxBVElWRV9TRUVLX0lOLCAweGZmLCAiUkVMQVRJVkUgU0VFSyBJTiIsIDIsIGZkY3RybF9oYW5kbGVfcmVsYXRpdmVfc2Vla19pbiB9LAogICAgeyBGRF9DTURfTE9DSywgMHg3ZiwgIkxPQ0siLCAwLCBmZGN0cmxfaGFuZGxlX2xvY2sgfSwKICAgIHsgRkRfQ01EX0RVTVBSRUcsIDB4ZmYsICJEVU1QUkVHIiwgMCwgZmRjdHJsX2hhbmRsZV9kdW1wcmVnIH0sCiAgICB7IEZEX0NNRF9WRVJTSU9OLCAweGZmLCAiVkVSU0lPTiIsIDAsIGZkY3RybF9oYW5kbGVfdmVyc2lvbiB9LAogICAgeyBGRF9DTURfUEFSVF9JRCwgMHhmZiwgIlBBUlQgSUQiLCAwLCBmZGN0cmxfaGFuZGxlX3BhcnRpZCB9LAogICAgeyBGRF9DTURfV1JJVEUsIDB4MWYsICJXUklURSAoQmVPUykiLCA4LCBmZGN0cmxfc3RhcnRfdHJhbnNmZXIsIEZEX0RJUl9XUklURSB9LCAvKiBub3QgaW4gc3BlY2lmaWNhdGlvbiA7IEJlT1MgNC41IGJ1ZyAqLwogICAgeyAwLCAwLCAidW5rbm93biIsIDAsIGZkY3RybF91bmltcGxlbWVudGVkIH0sIC8qIGRlZmF1bHQgaGFuZGxlciAqLwp9OwovKiBBc3NvY2lhdGUgY29tbWFuZCB0byBhbiBpbmRleCBpbiB0aGUgJ2hhbmRsZXJzJyBhcnJheSAqLwpzdGF0aWMgdWludDhfdCBjb21tYW5kX3RvX2hhbmRsZXJbMjU2XTsKCnN0YXRpYyB2b2lkIGZkY3RybF93cml0ZV9kYXRhIChmZGN0cmxfdCAqZmRjdHJsLCB1aW50MzJfdCB2YWx1ZSkKewogICAgZmRyaXZlX3QgKmN1cl9kcnY7CiAgICBpbnQgcG9zOwoKICAgIC8qIFJlc2V0IG1vZGUgKi8KICAgIGlmICghKGZkY3RybC0+ZG9yICYgRkRfRE9SX25SRVNFVCkpIHsKICAgICAgICBGTE9QUFlfRFBSSU5URigiRmxvcHB5IGNvbnRyb2xsZXIgaW4gUkVTRVQgc3RhdGUgIVxuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKCEoZmRjdHJsLT5tc3IgJiBGRF9NU1JfUlFNKSB8fCAoZmRjdHJsLT5tc3IgJiBGRF9NU1JfRElPKSkgewogICAgICAgIEZMT1BQWV9FUlJPUigiY29udHJvbGxlciBub3QgcmVhZHkgZm9yIHdyaXRpbmdcbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGZkY3RybC0+ZHNyICY9IH5GRF9EU1JfUFdSRE9XTjsKICAgIC8qIElzIGl0IHdyaXRlIGNvbW1hbmQgdGltZSA/ICovCiAgICBpZiAoZmRjdHJsLT5tc3IgJiBGRF9NU1JfTk9ORE1BKSB7CiAgICAgICAgLyogRklGTyBkYXRhIHdyaXRlICovCiAgICAgICAgcG9zID0gZmRjdHJsLT5kYXRhX3BvcysrOwogICAgICAgIHBvcyAlPSBGRF9TRUNUT1JfTEVOOwogICAgICAgIGZkY3RybC0+Zmlmb1twb3NdID0gdmFsdWU7CiAgICAgICAgaWYgKHBvcyA9PSBGRF9TRUNUT1JfTEVOIC0gMSB8fAogICAgICAgICAgICBmZGN0cmwtPmRhdGFfcG9zID09IGZkY3RybC0+ZGF0YV9sZW4pIHsKICAgICAgICAgICAgY3VyX2RydiA9IGdldF9jdXJfZHJ2KGZkY3RybCk7CiAgICAgICAgICAgIGlmIChiZHJ2X3dyaXRlKGN1cl9kcnYtPmJzLCBmZF9zZWN0b3IoY3VyX2RydiksIGZkY3RybC0+ZmlmbywgMSkgPCAwKSB7CiAgICAgICAgICAgICAgICBGTE9QUFlfRVJST1IoIndyaXRpbmcgc2VjdG9yICVkXG4iLCBmZF9zZWN0b3IoY3VyX2RydikpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghZmRjdHJsX3NlZWtfdG9fbmV4dF9zZWN0KGZkY3RybCwgY3VyX2RydikpIHsKICAgICAgICAgICAgICAgIEZMT1BQWV9EUFJJTlRGKCJlcnJvciBzZWVraW5nIHRvIG5leHQgc2VjdG9yICVkXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmRfc2VjdG9yKGN1cl9kcnYpKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKiBTd2l0Y2ggZnJvbSB0cmFuc2ZlciBtb2RlIHRvIHN0YXR1cyBtb2RlCiAgICAgICAgICogdGhlbiBmcm9tIHN0YXR1cyBtb2RlIHRvIGNvbW1hbmQgbW9kZQogICAgICAgICAqLwogICAgICAgIGlmIChmZGN0cmwtPmRhdGFfcG9zID09IGZkY3RybC0+ZGF0YV9sZW4pCiAgICAgICAgICAgIGZkY3RybF9zdG9wX3RyYW5zZmVyKGZkY3RybCwgRkRfU1IwX1NFRUssIDB4MDAsIDB4MDApOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChmZGN0cmwtPmRhdGFfcG9zID09IDApIHsKICAgICAgICAvKiBDb21tYW5kICovCiAgICAgICAgcG9zID0gY29tbWFuZF90b19oYW5kbGVyW3ZhbHVlICYgMHhmZl07CiAgICAgICAgRkxPUFBZX0RQUklOVEYoIiVzIGNvbW1hbmRcbiIsIGhhbmRsZXJzW3Bvc10ubmFtZSk7CiAgICAgICAgZmRjdHJsLT5kYXRhX2xlbiA9IGhhbmRsZXJzW3Bvc10ucGFyYW1ldGVycyArIDE7CiAgICB9CgogICAgRkxPUFBZX0RQUklOVEYoIiVzOiAlMDJ4XG4iLCBfX2Z1bmNfXywgdmFsdWUpOwogICAgZmRjdHJsLT5maWZvW2ZkY3RybC0+ZGF0YV9wb3MrK10gPSB2YWx1ZTsKICAgIGlmIChmZGN0cmwtPmRhdGFfcG9zID09IGZkY3RybC0+ZGF0YV9sZW4pIHsKICAgICAgICAvKiBXZSBub3cgaGF2ZSBhbGwgcGFyYW1ldGVycwogICAgICAgICAqIGFuZCB3aWxsIGJlIGFibGUgdG8gdHJlYXQgdGhlIGNvbW1hbmQKICAgICAgICAgKi8KICAgICAgICBpZiAoZmRjdHJsLT5kYXRhX3N0YXRlICYgRkRfU1RBVEVfRk9STUFUKSB7CiAgICAgICAgICAgIGZkY3RybF9mb3JtYXRfc2VjdG9yKGZkY3RybCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIHBvcyA9IGNvbW1hbmRfdG9faGFuZGxlcltmZGN0cmwtPmZpZm9bMF0gJiAweGZmXTsKICAgICAgICBGTE9QUFlfRFBSSU5URigidHJlYXQgJXMgY29tbWFuZFxuIiwgaGFuZGxlcnNbcG9zXS5uYW1lKTsKICAgICAgICAoKmhhbmRsZXJzW3Bvc10uaGFuZGxlcikoZmRjdHJsLCBoYW5kbGVyc1twb3NdLmRpcmVjdGlvbik7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIGZkY3RybF9yZXN1bHRfdGltZXIodm9pZCAqb3BhcXVlKQp7CiAgICBmZGN0cmxfdCAqZmRjdHJsID0gb3BhcXVlOwogICAgZmRyaXZlX3QgKmN1cl9kcnYgPSBnZXRfY3VyX2RydihmZGN0cmwpOwoKICAgIC8qIFByZXRlbmQgd2UgYXJlIHNwaW5uaW5nLgogICAgICogVGhpcyBpcyBuZWVkZWQgZm9yIENvaGVyZW50LCB3aGljaCB1c2VzIFJFQUQgSUQgdG8gY2hlY2sgZm9yCiAgICAgKiBzZWN0b3IgaW50ZXJsZWF2aW5nLgogICAgICovCiAgICBpZiAoY3VyX2Rydi0+bGFzdF9zZWN0ICE9IDApIHsKICAgICAgICBjdXJfZHJ2LT5zZWN0ID0gKGN1cl9kcnYtPnNlY3QgJSBjdXJfZHJ2LT5sYXN0X3NlY3QpICsgMTsKICAgIH0KICAgIGZkY3RybF9zdG9wX3RyYW5zZmVyKGZkY3RybCwgMHgwMCwgMHgwMCwgMHgwMCk7Cn0KCi8qIEluaXQgZnVuY3Rpb25zICovCnN0YXRpYyB2b2lkIGZkY3RybF9jb25uZWN0X2RyaXZlcyhmZGN0cmxfdCAqZmRjdHJsLCBCbG9ja0RyaXZlclN0YXRlICoqZmRzKQp7CiAgICB1bnNpZ25lZCBpbnQgaTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgTUFYX0ZEOyBpKyspIHsKICAgICAgICBmZF9pbml0KCZmZGN0cmwtPmRyaXZlc1tpXSwgZmRzW2ldKTsKICAgICAgICBmZF9yZXZhbGlkYXRlKCZmZGN0cmwtPmRyaXZlc1tpXSk7CiAgICB9Cn0KCmZkY3RybF90ICpmZGN0cmxfaW5pdCAocWVtdV9pcnEgaXJxLCBpbnQgZG1hX2NoYW5uLCBpbnQgbWVtX21hcHBlZCwKICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRfcGh5c19hZGRyX3QgaW9fYmFzZSwKICAgICAgICAgICAgICAgICAgICAgICBCbG9ja0RyaXZlclN0YXRlICoqZmRzKQp7CiAgICBmZGN0cmxfdCAqZmRjdHJsOwoKICAgIGlmIChtZW1fbWFwcGVkKSB7CiAgICAgICAgRGV2aWNlU3RhdGUgKmRldjsKICAgICAgICBmZGN0cmxfc3lzYnVzX3QgKnN5czsKCiAgICAgICAgZGV2ID0gcWRldl9jcmVhdGUoTlVMTCwgInN5c2J1cy1mZGMiKTsKICAgICAgICBxZGV2X2luaXQoZGV2KTsKICAgICAgICBzeXMgPSBET19VUENBU1QoZmRjdHJsX3N5c2J1c190LCBidXNkZXYucWRldiwgZGV2KTsKICAgICAgICBmZGN0cmwgPSAmc3lzLT5zdGF0ZTsKICAgICAgICBzeXNidXNfY29ubmVjdF9pcnEoJnN5cy0+YnVzZGV2LCAwLCBpcnEpOwogICAgICAgIHN5c2J1c19tbWlvX21hcCgmc3lzLT5idXNkZXYsIDAsIGlvX2Jhc2UpOwogICAgfSBlbHNlIHsKICAgICAgICBJU0FEZXZpY2UgKmRldjsKCiAgICAgICAgZGV2ID0gaXNhX2NyZWF0ZV9zaW1wbGUoImlzYS1mZGMiLCBpb19iYXNlLCAwKTsKICAgICAgICBmZGN0cmwgPSAmKERPX1VQQ0FTVChmZGN0cmxfaXNhYnVzX3QsIGJ1c2RldiwgZGV2KS0+c3RhdGUpOwogICAgICAgIGlzYV9jb25uZWN0X2lycShkZXYsIDAsIGlycSk7CiAgICB9CgogICAgZmRjdHJsLT5kbWFfY2hhbm4gPSBkbWFfY2hhbm47CiAgICBETUFfcmVnaXN0ZXJfY2hhbm5lbChkbWFfY2hhbm4sICZmZGN0cmxfdHJhbnNmZXJfaGFuZGxlciwgZmRjdHJsKTsKCiAgICBmZGN0cmxfY29ubmVjdF9kcml2ZXMoZmRjdHJsLCBmZHMpOwoKICAgIHJldHVybiBmZGN0cmw7Cn0KCmZkY3RybF90ICpzdW40bV9mZGN0cmxfaW5pdCAocWVtdV9pcnEgaXJxLCB0YXJnZXRfcGh5c19hZGRyX3QgaW9fYmFzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCbG9ja0RyaXZlclN0YXRlICoqZmRzLCBxZW11X2lycSAqZmRjX3RjKQp7CiAgICBEZXZpY2VTdGF0ZSAqZGV2OwogICAgZmRjdHJsX3N5c2J1c190ICpzeXM7CiAgICBmZGN0cmxfdCAqZmRjdHJsOwoKICAgIGRldiA9IHFkZXZfY3JlYXRlKE5VTEwsICJTVU5XLGZkdHdvIik7CiAgICBxZGV2X2luaXQoZGV2KTsKICAgIHN5cyA9IERPX1VQQ0FTVChmZGN0cmxfc3lzYnVzX3QsIGJ1c2Rldi5xZGV2LCBkZXYpOwogICAgZmRjdHJsID0gJnN5cy0+c3RhdGU7CiAgICBzeXNidXNfY29ubmVjdF9pcnEoJnN5cy0+YnVzZGV2LCAwLCBpcnEpOwogICAgc3lzYnVzX21taW9fbWFwKCZzeXMtPmJ1c2RldiwgMCwgaW9fYmFzZSk7CiAgICAqZmRjX3RjID0gcWRldl9nZXRfZ3Bpb19pbihkZXYsIDApOwoKICAgIGZkY3RybC0+ZG1hX2NoYW5uID0gLTE7CgogICAgZmRjdHJsX2Nvbm5lY3RfZHJpdmVzKGZkY3RybCwgZmRzKTsKCiAgICByZXR1cm4gZmRjdHJsOwp9CgpzdGF0aWMgdm9pZCBmZGN0cmxfaW5pdF9jb21tb24oZmRjdHJsX3QgKmZkY3RybCkKewogICAgaW50IGksIGo7CiAgICBzdGF0aWMgaW50IGNvbW1hbmRfdGFibGVzX2luaXRlZCA9IDA7CgogICAgLyogRmlsbCAnY29tbWFuZF90b19oYW5kbGVyJyBsb29rdXAgdGFibGUgKi8KICAgIGlmICghY29tbWFuZF90YWJsZXNfaW5pdGVkKSB7CiAgICAgICAgY29tbWFuZF90YWJsZXNfaW5pdGVkID0gMTsKICAgICAgICBmb3IgKGkgPSBBUlJBWV9TSVpFKGhhbmRsZXJzKSAtIDE7IGkgPj0gMDsgaS0tKSB7CiAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCBzaXplb2YoY29tbWFuZF90b19oYW5kbGVyKTsgaisrKSB7CiAgICAgICAgICAgICAgICBpZiAoKGogJiBoYW5kbGVyc1tpXS5tYXNrKSA9PSBoYW5kbGVyc1tpXS52YWx1ZSkgewogICAgICAgICAgICAgICAgICAgIGNvbW1hbmRfdG9faGFuZGxlcltqXSA9IGk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgRkxPUFBZX0RQUklOVEYoImluaXQgY29udHJvbGxlclxuIik7CiAgICBmZGN0cmwtPmZpZm8gPSBxZW11X21lbWFsaWduKDUxMiwgRkRfU0VDVE9SX0xFTik7CiAgICBmZGN0cmwtPnJlc3VsdF90aW1lciA9IHFlbXVfbmV3X3RpbWVyKHZtX2Nsb2NrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmZGN0cmxfcmVzdWx0X3RpbWVyLCBmZGN0cmwpOwoKICAgIGZkY3RybC0+dmVyc2lvbiA9IDB4OTA7IC8qIEludGVsIDgyMDc4IGNvbnRyb2xsZXIgKi8KICAgIGZkY3RybC0+Y29uZmlnID0gRkRfQ09ORklHX0VJUyB8IEZEX0NPTkZJR19FRklGTzsgLyogSW1wbGljaXQgc2VlaywgcG9sbGluZyAmIEZJRk8gZW5hYmxlZCAqLwoKICAgIGZkY3RybF9leHRlcm5hbF9yZXNldChmZGN0cmwpOwogICAgcmVnaXN0ZXJfc2F2ZXZtKCJmZGMiLCAtMSwgMiwgZmRjX3NhdmUsIGZkY19sb2FkLCBmZGN0cmwpOwogICAgcWVtdV9yZWdpc3Rlcl9yZXNldChmZGN0cmxfZXh0ZXJuYWxfcmVzZXQsIGZkY3RybCk7Cn0KCnN0YXRpYyB2b2lkIGlzYWJ1c19mZGNfaW5pdDEoSVNBRGV2aWNlICpkZXYpCnsKICAgIGZkY3RybF9pc2FidXNfdCAqaXNhID0gRE9fVVBDQVNUKGZkY3RybF9pc2FidXNfdCwgYnVzZGV2LCBkZXYpOwogICAgZmRjdHJsX3QgKmZkY3RybCA9ICZpc2EtPnN0YXRlOwoKICAgIHJlZ2lzdGVyX2lvcG9ydF9yZWFkKGlzYS0+YnVzZGV2LmlvYmFzZVswXSArIDB4MDEsIDUsIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAmZmRjdHJsX3JlYWRfcG9ydCwgZmRjdHJsKTsKICAgIHJlZ2lzdGVyX2lvcG9ydF9yZWFkKGlzYS0+YnVzZGV2LmlvYmFzZVswXSArIDB4MDcsIDEsIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAmZmRjdHJsX3JlYWRfcG9ydCwgZmRjdHJsKTsKICAgIHJlZ2lzdGVyX2lvcG9ydF93cml0ZShpc2EtPmJ1c2Rldi5pb2Jhc2VbMF0gKyAweDAxLCA1LCAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICZmZGN0cmxfd3JpdGVfcG9ydCwgZmRjdHJsKTsKICAgIHJlZ2lzdGVyX2lvcG9ydF93cml0ZShpc2EtPmJ1c2Rldi5pb2Jhc2VbMF0gKyAweDA3LCAxLCAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICZmZGN0cmxfd3JpdGVfcG9ydCwgZmRjdHJsKTsKICAgIGlzYV9pbml0X2lycSgmaXNhLT5idXNkZXYsICZmZGN0cmwtPmlycSk7CgogICAgZmRjdHJsX2luaXRfY29tbW9uKGZkY3RybCk7Cn0KCnN0YXRpYyB2b2lkIHN5c2J1c19mZGNfaW5pdDEoU3lzQnVzRGV2aWNlICpkZXYpCnsKICAgIGZkY3RybF90ICpmZGN0cmwgPSAmKEZST01fU1lTQlVTKGZkY3RybF9zeXNidXNfdCwgZGV2KS0+c3RhdGUpOwogICAgaW50IGlvOwoKICAgIGlvID0gY3B1X3JlZ2lzdGVyX2lvX21lbW9yeShmZGN0cmxfbWVtX3JlYWQsIGZkY3RybF9tZW1fd3JpdGUsIGZkY3RybCk7CiAgICBzeXNidXNfaW5pdF9tbWlvKGRldiwgMHgwOCwgaW8pOwogICAgc3lzYnVzX2luaXRfaXJxKGRldiwgJmZkY3RybC0+aXJxKTsKICAgIHFkZXZfaW5pdF9ncGlvX2luKCZkZXYtPnFkZXYsIGZkY3RybF9oYW5kbGVfdGMsIDEpOwoKICAgIGZkY3RybF9pbml0X2NvbW1vbihmZGN0cmwpOwp9CgpzdGF0aWMgdm9pZCBzdW40bV9mZGNfaW5pdDEoU3lzQnVzRGV2aWNlICpkZXYpCnsKICAgIGZkY3RybF90ICpmZGN0cmwgPSAmKEZST01fU1lTQlVTKGZkY3RybF9zeXNidXNfdCwgZGV2KS0+c3RhdGUpOwogICAgaW50IGlvOwoKICAgIGlvID0gY3B1X3JlZ2lzdGVyX2lvX21lbW9yeShmZGN0cmxfbWVtX3JlYWRfc3RyaWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZkY3RybF9tZW1fd3JpdGVfc3RyaWN0LCBmZGN0cmwpOwogICAgc3lzYnVzX2luaXRfbW1pbyhkZXYsIDB4MDgsIGlvKTsKICAgIHN5c2J1c19pbml0X2lycShkZXYsICZmZGN0cmwtPmlycSk7CiAgICBxZGV2X2luaXRfZ3Bpb19pbigmZGV2LT5xZGV2LCBmZGN0cmxfaGFuZGxlX3RjLCAxKTsKCiAgICBmZGN0cmwtPnN1bjRtID0gMTsKICAgIGZkY3RybF9pbml0X2NvbW1vbihmZGN0cmwpOwp9CgpzdGF0aWMgSVNBRGV2aWNlSW5mbyBpc2FfZmRjX2luZm8gPSB7CiAgICAuaW5pdCA9IGlzYWJ1c19mZGNfaW5pdDEsCiAgICAucWRldi5uYW1lICA9ICJpc2EtZmRjIiwKICAgIC5xZGV2LnNpemUgID0gc2l6ZW9mKGZkY3RybF9pc2FidXNfdCksCn07CgpzdGF0aWMgU3lzQnVzRGV2aWNlSW5mbyBzeXNidXNfZmRjX2luZm8gPSB7CiAgICAuaW5pdCA9IHN5c2J1c19mZGNfaW5pdDEsCiAgICAucWRldi5uYW1lICA9ICJzeXNidXMtZmRjIiwKICAgIC5xZGV2LnNpemUgID0gc2l6ZW9mKGZkY3RybF9zeXNidXNfdCksCn07CgpzdGF0aWMgU3lzQnVzRGV2aWNlSW5mbyBzdW40bV9mZGNfaW5mbyA9IHsKICAgIC5pbml0ID0gc3VuNG1fZmRjX2luaXQxLAogICAgLnFkZXYubmFtZSAgPSAiU1VOVyxmZHR3byIsCiAgICAucWRldi5zaXplICA9IHNpemVvZihmZGN0cmxfc3lzYnVzX3QpLAp9OwoKc3RhdGljIHZvaWQgZmRjX3JlZ2lzdGVyX2RldmljZXModm9pZCkKewogICAgaXNhX3FkZXZfcmVnaXN0ZXIoJmlzYV9mZGNfaW5mbyk7CiAgICBzeXNidXNfcmVnaXN0ZXJfd2l0aHByb3AoJnN5c2J1c19mZGNfaW5mbyk7CiAgICBzeXNidXNfcmVnaXN0ZXJfd2l0aHByb3AoJnN1bjRtX2ZkY19pbmZvKTsKfQoKZGV2aWNlX2luaXQoZmRjX3JlZ2lzdGVyX2RldmljZXMpCg==