LyoKICogIEFnZW50WCBtYXN0ZXIgYWdlbnQKICovCi8qIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvcHlyaWdodChzKS4gIFNlZQogKiB0aGUgTmV0LVNOTVAncyBDT1BZSU5HIGZpbGUgZm9yIG1vcmUgZGV0YWlscyBhbmQgb3RoZXIgY29weXJpZ2h0cwogKiB0aGF0IG1heSBhcHBseToKICovCi8qCiAqIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgY29weXJpZ2h0ZWQgYnk6CiAqIENvcHlyaWdodCCpIDIwMDMgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBVc2UgaXMgc3ViamVjdCB0byBsaWNlbnNlIHRlcm1zIHNwZWNpZmllZCBpbiB0aGUgQ09QWUlORyBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhlIE5ldC1TTk1QIHBhY2thZ2UuCiAqLwoKCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KI2lmIEhBVkVfSU9fSAojaW5jbHVkZSA8aW8uaD4KI2VuZGlmCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaWZkZWYgSEFWRV9TVERMSUJfSAojaW5jbHVkZSA8c3RkbGliLmg+CiNlbmRpZgojaWYgSEFWRV9TVFJJTkdfSAojaW5jbHVkZSA8c3RyaW5nLmg+CiNlbHNlCiNpbmNsdWRlIDxzdHJpbmdzLmg+CiNlbmRpZgojaWYgSEFWRV9ORVRJTkVUX0lOX0gKI2luY2x1ZGUgPG5ldGluZXQvaW4uaD4KI2VuZGlmCiNpZiBIQVZFX1dJTlNPQ0tfSAojaW5jbHVkZSA8d2luc29jay5oPgojZW5kaWYKI2lmIEhBVkVfU1lTX1NPQ0tFVF9ICiNpbmNsdWRlIDxzeXMvc29ja2V0Lmg+CiNlbmRpZgojaW5jbHVkZSA8ZXJybm8uaD4KCiNpZiBIQVZFX1VOSVNURF9ICiNpbmNsdWRlIDx1bmlzdGQuaD4KI2VuZGlmCiNpZmRlZiBIQVZFX1NZU19TVEFUX0gKI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNlbmRpZgoKI2RlZmluZSBTTk1QX05FRURfUkVRVUVTVF9MSVNUCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1pbmNsdWRlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvbmV0LXNubXAtYWdlbnQtaW5jbHVkZXMuaD4KI2luY2x1ZGUgInNubXBkLmgiCiNpbmNsdWRlICJhZ2VudHgvcHJvdG9jb2wuaCIKI2luY2x1ZGUgImFnZW50eC9tYXN0ZXJfYWRtaW4uaCIKCnZvaWQKcmVhbF9pbml0X21hc3Rlcih2b2lkKQp7CiAgICBuZXRzbm1wX3Nlc3Npb24gc2VzcywgKnNlc3Npb24gPSBOVUxMOwogICAgY2hhciAqYWdlbnR4X3NvY2tldHM7CiAgICBjaGFyICpjcDE7CgojaWZkZWYgTkVUU05NUF9UUkFOU1BPUlRfVU5JWF9ET01BSU4KICAgIGludCBhZ2VudHhfZGlyX3Blcm07CiAgICBpbnQgYWdlbnR4X3NvY2tfcGVybTsKICAgIGludCBhZ2VudHhfc29ja191c2VyOwogICAgaW50IGFnZW50eF9zb2NrX2dyb3VwOwojZW5kaWYKCiAgICBpZiAobmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0FQUExJQ0FUSU9OX0lELCBORVRTTk1QX0RTX0FHRU5UX1JPTEUpICE9IE1BU1RFUl9BR0VOVCkKICAgICAgICByZXR1cm47CgogICAgaWYgKG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0FQUExJQ0FUSU9OX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0FHRU5UX1hfU09DS0VUKSkgewogICAgICAgYWdlbnR4X3NvY2tldHMgPSBzdHJkdXAobmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfQVBQTElDQVRJT05fSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19BR0VOVF9YX1NPQ0tFVCkpOwojaWZkZWYgTkVUU05NUF9BR0VOVFhfRE9NX1NPQ0tfT05MWQogICAgICAgaWYgKGFnZW50eF9zb2NrZXRzWzBdICE9ICcvJykgewogICAgICAgICAgIC8qIHVuaXg6L3BhdGggKi8KICAgICAgICAgICBpZiAoYWdlbnR4X3NvY2tldHNbNV0gIT0gJy8nKSB7CiAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsCiAgICAgICAgICAgICAgICAgICAgIkVycm9yOiAlcyB0cmFuc3BvcnQgaXMgbm90IHN1cHBvcnRlZCwgZGlzYWJsaW5nIGFnZW50eC9tYXN0ZXIuXG4iLCBhZ2VudHhfc29ja2V0cyk7CiAgICAgICAgICAgICAgIFNOTVBfRlJFRShhZ2VudHhfc29ja2V0cyk7CiAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICB9CiAgICAgICB9CiNlbmRpZgogICAgfSBlbHNlIHsKICAgICAgICBhZ2VudHhfc29ja2V0cyA9IHN0cmR1cCgiIik7CiAgICB9CgoKICAgIERFQlVHTVNHVEwoKCJhZ2VudHgvbWFzdGVyIiwgImluaXRpYWxpemluZy4uLlxuIikpOwogICAgc25tcF9zZXNzX2luaXQoJnNlc3MpOwogICAgc2Vzcy52ZXJzaW9uID0gQUdFTlRYX1ZFUlNJT05fMTsKICAgIHNlc3MuZmxhZ3MgfD0gU05NUF9GTEFHU19TVFJFQU1fU09DS0VUOwogICAgc2Vzcy50aW1lb3V0ID0gbmV0c25tcF9kc19nZXRfaW50KE5FVFNOTVBfRFNfQVBQTElDQVRJT05fSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19BR0VOVF9BR0VOVFhfVElNRU9VVCk7CiAgICBzZXNzLnJldHJpZXMgPSBuZXRzbm1wX2RzX2dldF9pbnQoTkVUU05NUF9EU19BUFBMSUNBVElPTl9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0FHRU5UX0FHRU5UWF9SRVRSSUVTKTsKICAgIGNwMSA9IGFnZW50eF9zb2NrZXRzOwogICAgd2hpbGUgKGNwMSkgewogICAgICAgIG5ldHNubXBfdHJhbnNwb3J0ICp0OwogICAgICAgIC8qCiAgICAgICAgICogIElmIHRoZSBBZ2VudFggc29ja2V0IHN0cmluZyBjb250YWlucyBtdWx0aXBsZSBkZXNjcmlwdG9ycywKICAgICAgICAgKiAgdGhlbiBwaWNrIHRoaXMgYXBhcnQgYW5kIGhhbmRsZSB0aGVtIG9uZSBieSBvbmUuCiAgICAgICAgICoKICAgICAgICAgKi8KICAgICAgICBzZXNzLnBlZXJuYW1lID0gY3AxOwogICAgICAgIGNwMSA9IHN0cmNocihzZXNzLnBlZXJuYW1lLCAnLCcpOwogICAgICAgIGlmIChjcDEgIT0gTlVMTCkgewogICAgICAgICAgICAqY3AxKysgPSAnXDAnOwoJfQogICAgCiAgICAgICAgaWYgKHNlc3MucGVlcm5hbWVbMF0gPT0gJy8nKSB7CiNpZmRlZiBORVRTTk1QX1RSQU5TUE9SVF9VTklYX0RPTUFJTgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiAgSWYgdGhpcyBpcyBhIFVuaXggcGF0aG5hbWUsCiAgICAgICAgICAgICAqICB0cnkgYW5kIGNyZWF0ZSB0aGUgZGlyZWN0b3J5IGZpcnN0LgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgYWdlbnR4X2Rpcl9wZXJtID0gbmV0c25tcF9kc19nZXRfaW50KE5FVFNOTVBfRFNfQVBQTElDQVRJT05fSUQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19BR0VOVF9YX0RJUl9QRVJNKTsKICAgICAgICAgICAgaWYgKGFnZW50eF9kaXJfcGVybSA9PSAwKQogICAgICAgICAgICAgICAgYWdlbnR4X2Rpcl9wZXJtID0gTkVUU05NUF9BR0VOVF9ESVJFQ1RPUllfTU9ERTsKICAgICAgICAgICAgaWYgKG1rZGlyaGllcihzZXNzLnBlZXJuYW1lLCAobW9kZV90KWFnZW50eF9kaXJfcGVybSwgMSkpIHsKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsCiAgICAgICAgICAgICAgICAgICAgICAgICAiRmFpbGVkIHRvIGNyZWF0ZSB0aGUgZGlyZWN0b3J5IGZvciB0aGUgYWdlbnRYIHNvY2tldDogJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzLnBlZXJuYW1lKTsKICAgICAgICAgICAgfQojZWxzZQogICAgICAgICAgICBuZXRzbm1wX3Nlc3NfbG9nX2Vycm9yKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ1bml4IGRvbWFpbiBzdXBwb3J0IG5vdCBhdmFpbGFibGVcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnNlc3MpOwojZW5kaWYKICAgICAgICB9CiAgICAKICAgICAgICAvKgogICAgICAgICAqICBPdGhlcndpc2UsIGxldCAnc25tcF9vcGVuJyBpbnRlcnByZXQgdGhlIHN0cmluZy4KICAgICAgICAgKi8KICAgICAgICBzZXNzLmxvY2FsX3BvcnQgPSBBR0VOVFhfUE9SVDsgICAgICAvKiBJbmRpY2F0ZSBzZXJ2ZXIgJiBzZXQgZGVmYXVsdCBwb3J0ICovCiAgICAgICAgc2Vzcy5yZW1vdGVfcG9ydCA9IDA7CiAgICAgICAgc2Vzcy5jYWxsYmFjayA9IGhhbmRsZV9tYXN0ZXJfYWdlbnR4X3BhY2tldDsKICAgICAgICBlcnJubyA9IDA7CiAgICAgICAgdCA9IG5ldHNubXBfdHJhbnNwb3J0X29wZW5fc2VydmVyKCJhZ2VudHgiLCBzZXNzLnBlZXJuYW1lKTsKICAgICAgICBpZiAodCA9PSBOVUxMICYmIGVycm5vID09IEVBRERSSU5VU0UpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogQ291bGQgYmUgYSBsZWZ0LW92ZXIgc29ja2V0IChub3cgZGVsZXRlZCkKICAgICAgICAgICAgICogVHJ5IGFnYWluCiAgICAgICAgICAgICAqLwogICAgICAgICAgICB0ID0gbmV0c25tcF90cmFuc3BvcnRfb3Blbl9zZXJ2ZXIoImFnZW50eCIsIHNlc3MucGVlcm5hbWUpOwogICAgICAgIH0KICAgICAgICBpZiAodCA9PSBOVUxMKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGRpYWdub3NlIHNubXBfb3BlbiBlcnJvcnMgd2l0aCB0aGUgaW5wdXQgbmV0c25tcF9zZXNzaW9uCiAgICAgICAgICAgICAqIHBvaW50ZXIuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBjaGFyIGJ1ZlsxMDI0XTsKICAgICAgICAgICAgaWYgKCFuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfQVBQTElDQVRJT05fSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0FHRU5UX05PX1JPT1RfQUNDRVNTKSkgewogICAgICAgICAgICAgICAgc25wcmludGYoYnVmLCBzaXplb2YoYnVmKSwKICAgICAgICAgICAgICAgICAgICAgICAgICJFcnJvcjogQ291bGRuJ3Qgb3BlbiBhIG1hc3RlciBhZ2VudHggc29ja2V0IHRvICIKICAgICAgICAgICAgICAgICAgICAgICAgICJsaXN0ZW4gb24gKCVzKSIsIHNlc3MucGVlcm5hbWUpOwogICAgICAgICAgICAgICAgc25tcF9zZXNzX3BlcnJvcihidWYsICZzZXNzKTsKICAgICAgICAgICAgICAgIGV4aXQoMSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzbnByaW50ZihidWYsIHNpemVvZihidWYpLAogICAgICAgICAgICAgICAgICAgICAgICAgIldhcm5pbmc6IENvdWxkbid0IG9wZW4gYSBtYXN0ZXIgYWdlbnR4IHNvY2tldCB0byAiCiAgICAgICAgICAgICAgICAgICAgICAgICAibGlzdGVuIG9uICglcykiLCBzZXNzLnBlZXJuYW1lKTsKICAgICAgICAgICAgICAgIG5ldHNubXBfc2Vzc19sb2dfZXJyb3IoTE9HX1dBUk5JTkcsIGJ1ZiwgJnNlc3MpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKI2lmZGVmIE5FVFNOTVBfVFJBTlNQT1JUX1VOSVhfRE9NQUlOCiAgICAgICAgICAgIGlmICh0LT5kb21haW4gPT0gbmV0c25tcF9Vbml4RG9tYWluICYmIHQtPmxvY2FsICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIGNoYXIgbmFtZVtzaXplb2Yoc3RydWN0IHNvY2thZGRyX3VuKSArIDFdOwogICAgICAgICAgICAgICAgbWVtY3B5KG5hbWUsIHQtPmxvY2FsLCB0LT5sb2NhbF9sZW5ndGgpOwogICAgICAgICAgICAgICAgbmFtZVt0LT5sb2NhbF9sZW5ndGhdID0gJ1wwJzsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBBcHBseSBhbnkgc2V0dGluZ3MgdG8gdGhlIG93bmVyc2hpcC9wZXJtaXNzaW9ucyBvZiB0aGUKICAgICAgICAgICAgICAgICAqIEFnZW50WCBzb2NrZXQKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgYWdlbnR4X3NvY2tfcGVybSA9CiAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9kc19nZXRfaW50KE5FVFNOTVBfRFNfQVBQTElDQVRJT05fSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfQUdFTlRfWF9TT0NLX1BFUk0pOwogICAgICAgICAgICAgICAgYWdlbnR4X3NvY2tfdXNlciA9CiAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9kc19nZXRfaW50KE5FVFNOTVBfRFNfQVBQTElDQVRJT05fSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfQUdFTlRfWF9TT0NLX1VTRVIpOwogICAgICAgICAgICAgICAgYWdlbnR4X3NvY2tfZ3JvdXAgPQogICAgICAgICAgICAgICAgICAgIG5ldHNubXBfZHNfZ2V0X2ludChORVRTTk1QX0RTX0FQUExJQ0FUSU9OX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0FHRU5UX1hfU09DS19HUk9VUCk7CgogICAgICAgICAgICAgICAgaWYgKGFnZW50eF9zb2NrX3Blcm0gIT0gMCkKICAgICAgICAgICAgICAgICAgICBjaG1vZChuYW1lLCBhZ2VudHhfc29ja19wZXJtKTsKCiAgICAgICAgICAgICAgICBpZiAoYWdlbnR4X3NvY2tfdXNlciB8fCBhZ2VudHhfc29ja19ncm91cCkgewogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogSWYgZWl0aGVyIG9mIHVzZXIgb3IgZ3JvdXAgaGF2ZW4ndCBiZWVuIHNldCwKICAgICAgICAgICAgICAgICAgICAgKiAgdGhlbiBsZWF2ZSB0aGVtIHVuY2hhbmdlZC4KICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBpZiAoYWdlbnR4X3NvY2tfdXNlciA9PSAwICkKICAgICAgICAgICAgICAgICAgICAgICAgYWdlbnR4X3NvY2tfdXNlciA9IC0xOwogICAgICAgICAgICAgICAgICAgIGlmIChhZ2VudHhfc29ja19ncm91cCA9PSAwICkKICAgICAgICAgICAgICAgICAgICAgICAgYWdlbnR4X3NvY2tfZ3JvdXAgPSAtMTsKICAgICAgICAgICAgICAgICAgICBjaG93bihuYW1lLCBhZ2VudHhfc29ja191c2VyLCBhZ2VudHhfc29ja19ncm91cCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KI2VuZGlmCiAgICAgICAgICAgIHNlc3Npb24gPQogICAgICAgICAgICAgICAgc25tcF9hZGRfZnVsbCgmc2VzcywgdCwgTlVMTCwgYWdlbnR4X3BhcnNlLCBOVUxMLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZ2VudHhfcmVhbGxvY19idWlsZCwgYWdlbnR4X2NoZWNrX3BhY2tldCwgTlVMTCk7CiAgICAgICAgfQogICAgICAgIGlmIChzZXNzaW9uID09IE5VTEwpIHsKICAgICAgICAgICAgbmV0c25tcF90cmFuc3BvcnRfZnJlZSh0KTsKICAgICAgICB9CiAgICB9CgogICAgU05NUF9GUkVFKGFnZW50eF9zb2NrZXRzKTsKICAgIERFQlVHTVNHVEwoKCJhZ2VudHgvbWFzdGVyIiwgImluaXRpYWxpemluZy4uLiAgIERPTkVcbiIpKTsKfQoKICAgICAgICAvKgogICAgICAgICAqIEhhbmRsZSB0aGUgcmVzcG9uc2UgZnJvbSBhbiBBZ2VudFggc3ViYWdlbnQsCiAgICAgICAgICogICBtZXJnaW5nIHRoZSBhbnN3ZXJzIGJhY2sgaW50byB0aGUgb3JpZ2luYWwgcXVlcnkKICAgICAgICAgKi8KaW50CmFnZW50eF9nb3RfcmVzcG9uc2UoaW50IG9wZXJhdGlvbiwKICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3Nlc3Npb24gKiBzZXNzaW9uLAogICAgICAgICAgICAgICAgICAgIGludCByZXFpZCwgbmV0c25tcF9wZHUgKnBkdSwgdm9pZCAqbWFnaWMpCnsKICAgIG5ldHNubXBfZGVsZWdhdGVkX2NhY2hlICpjYWNoZSA9IChuZXRzbm1wX2RlbGVnYXRlZF9jYWNoZSAqKSBtYWdpYzsKICAgIGludCAgICAgICAgICAgICBpLCByZXQ7CiAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdHMsICpyZXF1ZXN0OwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2YXI7CiAgICBuZXRzbm1wX3Nlc3Npb24gKmF4X3Nlc3Npb247CgogICAgY2FjaGUgPSBuZXRzbm1wX2hhbmRsZXJfY2hlY2tfY2FjaGUoY2FjaGUpOwogICAgaWYgKCFjYWNoZSkgewogICAgICAgIERFQlVHTVNHVEwoKCJhZ2VudHgvbWFzdGVyIiwgInJlc3BvbnNlIHRvbyBsYXRlIG9uIHNlc3Npb24gJTA4cFxuIiwKICAgICAgICAgICAgICAgICAgICBzZXNzaW9uKSk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICByZXF1ZXN0cyA9IGNhY2hlLT5yZXF1ZXN0czsKCiAgICBzd2l0Y2ggKG9wZXJhdGlvbikgewogICAgY2FzZSBORVRTTk1QX0NBTExCQUNLX09QX1RJTUVEX09VVDp7CiAgICAgICAgICAgIHZvaWQgICAgICAgICAgICpzID0gc25tcF9zZXNzX3BvaW50ZXIoc2Vzc2lvbik7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJhZ2VudHgvbWFzdGVyIiwgInRpbWVvdXQgb24gc2Vzc2lvbiAlMDhwXG4iLAogICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uKSk7CgogICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfbWFya19yZXF1ZXN0c19hc19kZWxlZ2F0ZWQocmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFUVVFU1RfSVNfTk9UX0RFTEVHQVRFRCk7CiAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IoY2FjaGUtPnJlcWluZm8sIHJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIFhYWFdXVzogc2hvdWxkIGJlIGluZGV4PTAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX0VSUl9HRU5FUlIpOwoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogVGhpcyBpcyBhIGJpdCBzbGVkZ2VoYW1tZXIgYmVjYXVzZSB0aGUgb3RoZXIgc2Vzc2lvbnMgb24gdGhpcwogICAgICAgICAgICAgKiB0cmFuc3BvcnQgbWF5IGJlIG9rYXkgKGUuZy4gc29tZSB0aHJlYWQgaW4gdGhlIHN1YmFnZW50IGhhcwogICAgICAgICAgICAgKiB3ZWRnZWQsIGJ1dCB0aGUgb3RoZXJzIGFyZSBhbHJpZ2h0KS4gIE9UT0ggdGhlIG92ZXJ3aGVsbWluZwogICAgICAgICAgICAgKiBwcm9iYWJpbGl0eSBpcyB0aGF0IHRoZSB3aG9sZSBhZ2VudCBoYXMgZGllZCBzb21laG93LiAgCiAgICAgICAgICAgICAqLwoKICAgICAgICAgICAgaWYgKHMgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgbmV0c25tcF90cmFuc3BvcnQgKnQgPSBzbm1wX3Nlc3NfdHJhbnNwb3J0KHMpOwogICAgICAgICAgICAgICAgY2xvc2VfYWdlbnR4X3Nlc3Npb24oc2Vzc2lvbiwgLTEpOwoKICAgICAgICAgICAgICAgIGlmICh0ICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgiYWdlbnR4L21hc3RlciIsICJjbG9zZSB0cmFuc3BvcnRcbiIpKTsKICAgICAgICAgICAgICAgICAgICB0LT5mX2Nsb3NlKHQpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgiYWdlbnR4L21hc3RlciIsICJOVUxMIHRyYW5zcG9ydD8/XG4iKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgiYWdlbnR4L21hc3RlciIsICJOVUxMIHNlc3NfcG9pbnRlcj8/XG4iKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYXhfc2Vzc2lvbiA9IChuZXRzbm1wX3Nlc3Npb24gKikgY2FjaGUtPmxvY2FsaW5mbzsKICAgICAgICAgICAgbmV0c25tcF9mcmVlX2FnZW50X3NubXBfc2Vzc2lvbl9ieV9zZXNzaW9uKGF4X3Nlc3Npb24sIE5VTEwpOwogICAgICAgICAgICBuZXRzbm1wX2ZyZWVfZGVsZWdhdGVkX2NhY2hlKGNhY2hlKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgIGNhc2UgTkVUU05NUF9DQUxMQkFDS19PUF9ESVNDT05ORUNUOgogICAgY2FzZSBORVRTTk1QX0NBTExCQUNLX09QX1NFTkRfRkFJTEVEOgogICAgICAgIGlmIChvcGVyYXRpb24gPT0gTkVUU05NUF9DQUxMQkFDS19PUF9ESVNDT05ORUNUKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJhZ2VudHgvbWFzdGVyIiwgImRpc2Nvbm5lY3Qgb24gc2Vzc2lvbiAlMDhwXG4iLAogICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoImFnZW50eC9tYXN0ZXIiLCAic2VuZCBmYWlsZWQgb24gc2Vzc2lvbiAlMDhwXG4iLAogICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uKSk7CiAgICAgICAgfQogICAgICAgIGNsb3NlX2FnZW50eF9zZXNzaW9uKHNlc3Npb24sIC0xKTsKICAgICAgICBuZXRzbm1wX2hhbmRsZXJfbWFya19yZXF1ZXN0c19hc19kZWxlZ2F0ZWQocmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFUVVFU1RfSVNfTk9UX0RFTEVHQVRFRCk7CiAgICAgICAgbmV0c25tcF9zZXRfcmVxdWVzdF9lcnJvcihjYWNoZS0+cmVxaW5mbywgcmVxdWVzdHMsICAgICAvKiBYWFhXV1c6IHNob3VsZCBiZSBpbmRleD0wICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX0VSUl9HRU5FUlIpOwogICAgICAgIG5ldHNubXBfZnJlZV9kZWxlZ2F0ZWRfY2FjaGUoY2FjaGUpOwogICAgICAgIHJldHVybiAwOwoKICAgIGNhc2UgTkVUU05NUF9DQUxMQkFDS19PUF9SRUNFSVZFRF9NRVNTQUdFOgogICAgICAgIC8qCiAgICAgICAgICogVGhpcyBzZXNzaW9uIGlzIGFsaXZlIAogICAgICAgICAqLwogICAgICAgIENMRUFSX1NOTVBfU1RSSUtFX0ZMQUdTKHNlc3Npb24tPmZsYWdzKTsKICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIlVua25vd24gb3BlcmF0aW9uICVkIGluIGFnZW50eF9nb3RfcmVzcG9uc2VcbiIsCiAgICAgICAgICAgICAgICAgb3BlcmF0aW9uKTsKICAgICAgICBuZXRzbm1wX2ZyZWVfZGVsZWdhdGVkX2NhY2hlKGNhY2hlKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBERUJVR01TR1RMKCgiYWdlbnR4L21hc3RlciIsICJnb3QgcmVzcG9uc2UgZXJyc3RhdD0lZCwgKHJlcT0weCV4LHRyYW5zPSIKICAgICAgICAgICAgICAgICIweCV4LHNlc3M9MHgleClcbiIsCiAgICAgICAgICAgICAgICBwZHUtPmVycnN0YXQscGR1LT5yZXFpZCxwZHUtPnRyYW5zaWQsIHBkdS0+c2Vzc2lkKSk7CgogICAgaWYgKHBkdS0+ZXJyc3RhdCAhPSBBR0VOVFhfRVJSX05PRVJST1IpIHsKICAgICAgICAvKiBbUkZDIDI0NzEgLSA3LjIuNS4yLl0KICAgICAgICAgKgogICAgICAgICAqICAgMSkgRm9yIGFueSByZWNlaXZlZCBBZ2VudFggcmVzcG9uc2UgUERVLCBpZiByZXMuZXJyb3IgaXMKICAgICAgICAgKiAgICAgIG5vdCBgbm9FcnJvcicsIHRoZSBTTk1QIHJlc3BvbnNlIFBEVSdzIGVycm9yIGNvZGUgaXMKICAgICAgICAgKiAgICAgIHNldCB0byB0aGlzIHZhbHVlLiAgSWYgcmVzLmVycm9yIGNvbnRhaW5zIGFuIEFnZW50WAogICAgICAgICAqICAgICAgc3BlY2lmaWMgdmFsdWUgKGUuZy4gIGBwYXJzZUVycm9yJyksIHRoZSBTTk1QIHJlc3BvbnNlCiAgICAgICAgICogICAgICBQRFUncyBlcnJvciBjb2RlIGlzIHNldCB0byBhIHZhbHVlIG9mIGdlbkVyciBpbnN0ZWFkLgogICAgICAgICAqICAgICAgQWxzbywgdGhlIFNOTVAgcmVzcG9uc2UgUERVJ3MgZXJyb3IgaW5kZXggaXMgc2V0IHRvCiAgICAgICAgICogICAgICB0aGUgaW5kZXggb2YgdGhlIHZhcmlhYmxlIGJpbmRpbmcgY29ycmVzcG9uZGluZyB0byB0aGUKICAgICAgICAgKiAgICAgIGZhaWxlZCBWYXJCaW5kIGluIHRoZSBzdWJhZ2VudCdzIEFnZW50WCByZXNwb25zZSBQRFUuCiAgICAgICAgICoKICAgICAgICAgKiAgICAgIEFsbCBvdGhlciBBZ2VudFggcmVzcG9uc2UgUERVcyByZWNlaXZlZCBkdWUgdG8KICAgICAgICAgKiAgICAgIHByb2Nlc3NpbmcgdGhpcyBTTk1QIHJlcXVlc3QgYXJlIGlnbm9yZWQuICBQcm9jZXNzaW5nCiAgICAgICAgICogICAgICBpcyBjb21wbGV0ZTsgdGhlIFNOTVAgUmVzcG9uc2UgUERVIGlzIHJlYWR5IHRvIGJlIHNlbnQKICAgICAgICAgKiAgICAgIChzZWUgc2VjdGlvbiA3LjIuNiwgIlNlbmRpbmcgdGhlIFNOTVAgUmVzcG9uc2UtUERVIikuCiAgICAgICAgICovCiAgICAgICAgaW50IGVycjsKCiAgICAgICAgREVCVUdNU0dUTCgoImFnZW50eC9tYXN0ZXIiLAogICAgICAgICAgICAgICAgICAgICJhZ2VudHhfZ290X3Jlc3BvbnNlKCkgZXJyb3IgYnJhbmNoXG4iKSk7CgogICAgICAgIHN3aXRjaCAocGR1LT5lcnJzdGF0KSB7CiAgICAgICAgY2FzZSBBR0VOVFhfRVJSX1BBUlNFX0ZBSUxFRDoKICAgICAgICBjYXNlIEFHRU5UWF9FUlJfUkVRVUVTVF9ERU5JRUQ6CiAgICAgICAgY2FzZSBBR0VOVFhfRVJSX1BST0NFU1NJTkdfRVJST1I6CiAgICAgICAgICAgIGVyciA9IFNOTVBfRVJSX0dFTkVSUjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgZXJyID0gcGR1LT5lcnJzdGF0OwogICAgICAgIH0KCiAgICAgICAgcmV0ID0gMDsKICAgICAgICBmb3IgKHJlcXVlc3QgPSByZXF1ZXN0cywgaSA9IDE7IHJlcXVlc3Q7CiAgICAgICAgICAgICByZXF1ZXN0ID0gcmVxdWVzdC0+bmV4dCwgaSsrKSB7CiAgICAgICAgICAgIGlmIChpID09IHBkdS0+ZXJyaW5kZXgpIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBNYXJrIHRoaXMgdmFyYmluZCBhcyB0aGUgb25lIGdlbmVyYXRpbmcgdGhlIGVycm9yLgogICAgICAgICAgICAgICAgICogTm90ZSB0aGF0IHRoZSBBZ2VudFggZXJyaW5kZXggbWF5IG5vdCBtYXRjaCB0aGUKICAgICAgICAgICAgICAgICAqIHBvc2l0aW9uIGluIHRoZSBvcmlnaW5hbCBTTk1QIFBEVSAocmVxdWVzdC0+aW5kZXgpCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IoY2FjaGUtPnJlcWluZm8sIHJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycik7CiAgICAgICAgICAgICAgICByZXQgPSAxOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlcXVlc3QtPmRlbGVnYXRlZCA9IFJFUVVFU1RfSVNfTk9UX0RFTEVHQVRFRDsKICAgICAgICB9CiAgICAgICAgaWYgKCFyZXQpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogYWNrLCB1bmtub3duLCBtYXJrIHRoZSBmaXJzdCBvbmUKICAgICAgICAgICAgICovCiAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IoY2FjaGUtPnJlcWluZm8sIHJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRVJSX0dFTkVSUik7CiAgICAgICAgfQogICAgICAgIG5ldHNubXBfZnJlZV9kZWxlZ2F0ZWRfY2FjaGUoY2FjaGUpOwogICAgICAgIERFQlVHTVNHVEwoKCJhZ2VudHgvbWFzdGVyIiwgImVuZCBlcnJvciBicmFuY2hcbiIpKTsKICAgICAgICByZXR1cm4gMTsKICAgIH0gZWxzZSBpZiAoY2FjaGUtPnJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVQgfHwKICAgICAgICAgICAgICAgY2FjaGUtPnJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVRORVhUIHx8CiAgICAgICAgICAgICAgIGNhY2hlLT5yZXFpbmZvLT5tb2RlID09IE1PREVfR0VUQlVMSykgewogICAgICAgIC8qCiAgICAgICAgICogUmVwbGFjZSB2YXJiaW5kcyBmb3IgZGF0YSByZXF1ZXN0IHR5cGVzLCBidXQgbm90IFNFVHMuICAKICAgICAgICAgKi8KICAgICAgICBERUJVR01TR1RMKCgiYWdlbnR4L21hc3RlciIsCiAgICAgICAgICAgICAgICAgICAgImFnZW50eF9nb3RfcmVzcG9uc2UoKSBiZWdpbm5pbmcuLi5cbiIpKTsKICAgICAgICBmb3IgKHZhciA9IHBkdS0+dmFyaWFibGVzLCByZXF1ZXN0ID0gcmVxdWVzdHM7IHJlcXVlc3QgJiYgdmFyOwogICAgICAgICAgICAgcmVxdWVzdCA9IHJlcXVlc3QtPm5leHQsIHZhciA9IHZhci0+bmV4dF92YXJpYWJsZSkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBPdGhlcndpc2UsIHByb2Nlc3Mgc3VjY2Vzc2Z1bCByZXF1ZXN0cwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgREVCVUdNU0dUTCgoImFnZW50eC9tYXN0ZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAiICBoYW5kbGVfYWdlbnR4X3Jlc3BvbnNlOiBwcm9jZXNzaW5nOiAiKSk7CiAgICAgICAgICAgIERFQlVHTVNHT0lEKCgiYWdlbnR4L21hc3RlciIsIHZhci0+bmFtZSwgdmFyLT5uYW1lX2xlbmd0aCkpOwogICAgICAgICAgICBERUJVR01TRygoImFnZW50eC9tYXN0ZXIiLCAiXG4iKSk7CiAgICAgICAgICAgIGlmIChuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfQVBQTElDQVRJT05fSUQsIE5FVFNOTVBfRFNfQUdFTlRfVkVSQk9TRSkpIHsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwgIiAgICA+PiAiKSk7CiAgICAgICAgICAgICAgICBERUJVR01TR1ZBUigoInNubXBfYWdlbnQiLCB2YXIpKTsKICAgICAgICAgICAgICAgIERFQlVHTVNHKCgic25tcF9hZ2VudCIsICJcbiIpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogdXBkYXRlIHRoZSBvaWQgaW4gdGhlIG9yaWdpbmFsIHJlcXVlc3QgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAodmFyLT50eXBlICE9IFNOTVBfRU5ET0ZNSUJWSUVXKSB7CiAgICAgICAgICAgICAgICBzbm1wX3NldF92YXJfdHlwZWRfdmFsdWUocmVxdWVzdC0+cmVxdWVzdHZiLCB2YXItPnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyLT52YWwuc3RyaW5nLCB2YXItPnZhbF9sZW4pOwogICAgICAgICAgICAgICAgc25tcF9zZXRfdmFyX29iamlkKHJlcXVlc3QtPnJlcXVlc3R2YiwgdmFyLT5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhci0+bmFtZV9sZW5ndGgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlcXVlc3QtPmRlbGVnYXRlZCA9IFJFUVVFU1RfSVNfTk9UX0RFTEVHQVRFRDsKICAgICAgICB9CgogICAgICAgIGlmIChyZXF1ZXN0IHx8IHZhcikgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBhY2ssIHRoaXMgaXMgYmFkLiAgVGhlICMgb2YgdmFyYmluZHMgZG9uJ3QgbWF0Y2ggYW5kCiAgICAgICAgICAgICAqIHRoZXJlIGlzIG5vIHdheSB0byBmaXggdGhlIHByb2JsZW0gCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLAogICAgICAgICAgICAgICAgICAgICAicmVzcG9uc2UgdG8gYWdlbnR4IHJlcXVlc3QgaWxsZWdhbC4gIGJhaWxpbmcgb3V0LlxuIik7CiAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IoY2FjaGUtPnJlcWluZm8sIHJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRVJSX0dFTkVSUik7CiAgICAgICAgfQoKICAgICAgICBpZiAoY2FjaGUtPnJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVRCVUxLKQogICAgICAgICAgICBuZXRzbm1wX2J1bGtfdG9fbmV4dF9maXhfcmVxdWVzdHMocmVxdWVzdHMpOwogICAgfSBlbHNlIHsKICAgICAgICAvKgogICAgICAgICAqIG1hcmsgc2V0IHJlcXVlc3RzIGFzIGhhbmRsZWQgCiAgICAgICAgICovCiAgICAgICAgZm9yIChyZXF1ZXN0ID0gcmVxdWVzdHM7IHJlcXVlc3Q7IHJlcXVlc3QgPSByZXF1ZXN0LT5uZXh0KSB7CiAgICAgICAgICAgIHJlcXVlc3QtPmRlbGVnYXRlZCA9IFJFUVVFU1RfSVNfTk9UX0RFTEVHQVRFRDsKICAgICAgICB9CiAgICB9CiAgICBERUJVR01TR1RMKCgiYWdlbnR4L21hc3RlciIsCiAgICAgICAgICAgICAgICAiaGFuZGxlX2FnZW50eF9yZXNwb25zZSgpIGZpbmlzaGluZy4uLlxuIikpOwogICAgbmV0c25tcF9mcmVlX2RlbGVnYXRlZF9jYWNoZShjYWNoZSk7CiAgICByZXR1cm4gMTsKfQoKLyoKICoKICogQWdlbnRYIFN0YXRlIGRpYWdyYW0uICBbbW9kZV0gPSBpbnRlcm5hbCBtb2RlIGl0J3MgbWFwcGVkIGZyb206CiAqCiAqIFRFU1RTRVQgLXN1Y2Nlc3MtPiBDT01NSVQgLXN1Y2Nlc3MtPiBDTEVBTlVQCiAqIFtSRVNFUlZFMV0gICAgICAgICBbQUNUSU9OXSAgICAgICAgICBbQ09NTUlUXQogKiAgICB8ICAgICAgICAgICAgICAgICB8CiAqICAgIHwgICAgICAgICAgICAgICAgIFwtLWZhaWx1cmUtPiBVTkRPCiAqICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbVU5ET10KICogICAgfAogKiAgICAgLS1mYWlsdXJlLT4gQ0xFQU5VUAogKiAgICAgICAgICAgICAgICAgW0ZSRUVdCiAqLwppbnQKYWdlbnR4X21hc3Rlcl9oYW5kbGVyKG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdHMpCnsKICAgIG5ldHNubXBfc2Vzc2lvbiAqYXhfc2Vzc2lvbiA9IChuZXRzbm1wX3Nlc3Npb24gKikgaGFuZGxlci0+bXl2b2lkOwogICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3QgPSByZXF1ZXN0czsKICAgIG5ldHNubXBfcGR1ICAgICpwZHU7CiAgICB2b2lkICAgICAgICAgICAqY2JfZGF0YTsKICAgIGludCAgICAgICAgICAgICByZXN1bHQ7CgogICAgREVCVUdNU0dUTCgoImFnZW50eC9tYXN0ZXIiLAogICAgICAgICAgICAgICAgImFnZW50eCBtYXN0ZXIgaGFuZGxlciBzdGFydGluZywgbW9kZSA9IDB4JTAyeFxuIiwKICAgICAgICAgICAgICAgIHJlcWluZm8tPm1vZGUpKTsKCiAgICBpZiAoIWF4X3Nlc3Npb24pIHsKICAgICAgICBuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKHJlcWluZm8sIHJlcXVlc3RzLCBTTk1QX0VSUl9HRU5FUlIpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwogICAgfSAgICAgICAgCgogICAgLyoKICAgICAqIGJ1aWxkIGEgbmV3IHBkdSBiYXNlZCBvbiB0aGUgcGR1IHR5cGUgY29taW5nIGluIAogICAgICovCiAgICBzd2l0Y2ggKHJlcWluZm8tPm1vZGUpIHsKICAgIGNhc2UgTU9ERV9HRVQ6CiAgICAgICAgcGR1ID0gc25tcF9wZHVfY3JlYXRlKEFHRU5UWF9NU0dfR0VUKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfR0VUTkVYVDoKICAgICAgICBwZHUgPSBzbm1wX3BkdV9jcmVhdGUoQUdFTlRYX01TR19HRVRORVhUKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfR0VUQlVMSzogICAgICAgICAvKiBXV1dYWFggKi8KICAgICAgICBwZHUgPSBzbm1wX3BkdV9jcmVhdGUoQUdFTlRYX01TR19HRVRORVhUKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfU0VUX1JFU0VSVkUxOgogICAgICAgIHBkdSA9IHNubXBfcGR1X2NyZWF0ZShBR0VOVFhfTVNHX1RFU1RTRVQpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTU9ERV9TRVRfUkVTRVJWRTI6CiAgICAgICAgLyoKICAgICAgICAgKiBkb24ndCBkbyBhbnl0aGluZyBoZXJlIGZvciBBZ2VudFguICBBc3N1bWUgYWxsIGlzIGZpbmUKICAgICAgICAgKiBhbmQgZ28gb24gc2luY2UgQWdlbnRYIG9ubHkgaGFzIG9uZSB0ZXN0IHBoYXNlLiAKICAgICAgICAgKi8KICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKCiAgICBjYXNlIE1PREVfU0VUX0FDVElPTjoKICAgICAgICBwZHUgPSBzbm1wX3BkdV9jcmVhdGUoQUdFTlRYX01TR19DT01NSVRTRVQpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTU9ERV9TRVRfVU5ETzoKICAgICAgICBwZHUgPSBzbm1wX3BkdV9jcmVhdGUoQUdFTlRYX01TR19VTkRPU0VUKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfU0VUX0NPTU1JVDoKICAgIGNhc2UgTU9ERV9TRVRfRlJFRToKICAgICAgICBwZHUgPSBzbm1wX3BkdV9jcmVhdGUoQUdFTlRYX01TR19DTEVBTlVQU0VUKTsKICAgICAgICBicmVhazsKCiAgICBkZWZhdWx0OgogICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICJ1bnN1cHBvcnRlZCBtb2RlIGZvciBhZ2VudHgvbWFzdGVyIGNhbGxlZFxuIik7CiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7CiAgICB9CgogICAgaWYgKCFwZHUpIHsKICAgICAgICBuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKHJlcWluZm8sIHJlcXVlc3RzLCBTTk1QX0VSUl9HRU5FUlIpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwogICAgfQoKICAgIHBkdS0+dmVyc2lvbiA9IEFHRU5UWF9WRVJTSU9OXzE7CiAgICBwZHUtPnJlcWlkID0gc25tcF9nZXRfbmV4dF90cmFuc2lkKCk7CiAgICBwZHUtPnRyYW5zaWQgPSByZXFpbmZvLT5hc3AtPnBkdS0+dHJhbnNpZDsKICAgIHBkdS0+c2Vzc2lkID0gYXhfc2Vzc2lvbi0+c3Vic2Vzc2lvbi0+c2Vzc2lkOwogICAgaWYgKHJlZ2luZm8tPmNvbnRleHROYW1lKSB7CiAgICAgICAgcGR1LT5jb21tdW5pdHkgPSAodV9jaGFyICopIHN0cmR1cChyZWdpbmZvLT5jb250ZXh0TmFtZSk7CiAgICAgICAgcGR1LT5jb21tdW5pdHlfbGVuID0gc3RybGVuKHJlZ2luZm8tPmNvbnRleHROYW1lKTsKICAgICAgICBwZHUtPmZsYWdzIHw9IEFHRU5UWF9NU0dfRkxBR19OT05fREVGQVVMVF9DT05URVhUOwogICAgfQogICAgaWYgKGF4X3Nlc3Npb24tPnN1YnNlc3Npb24tPmZsYWdzICYgQUdFTlRYX01TR19GTEFHX05FVFdPUktfQllURV9PUkRFUikKICAgICAgICBwZHUtPmZsYWdzIHw9IEFHRU5UWF9NU0dfRkxBR19ORVRXT1JLX0JZVEVfT1JERVI7CgogICAgd2hpbGUgKHJlcXVlc3QpIHsKCiAgICAgICAgc2l6ZV90IG5sZW4gPSByZXF1ZXN0LT5yZXF1ZXN0dmItPm5hbWVfbGVuZ3RoOwogICAgICAgIG9pZCAgICpucHRyID0gcmVxdWVzdC0+cmVxdWVzdHZiLT5uYW1lOwogICAgICAgIAogICAgICAgIERFQlVHTVNHVEwoKCJhZ2VudHgvbWFzdGVyIiwicmVxdWVzdCBmb3IgdmFyaWFibGUgKCIpKTsKICAgICAgICBERUJVR01TR09JRCgoImFnZW50eC9tYXN0ZXIiLCBucHRyLCBubGVuKSk7CiAgICAgICAgREVCVUdNU0coKCJhZ2VudHgvbWFzdGVyIiwgIilcbiIpKTsKICAgICAgICAKICAgICAgICAvKgogICAgICAgICAqIGxvb3AgdGhyb3VnaCBhbGwgdGhlIHJlcXVlc3RzIGFuZCBjcmVhdGUgYWdlbnR4IG9uZXMgb3V0IG9mIHRoZW0gCiAgICAgICAgICovCgogICAgICAgIGlmIChyZXFpbmZvLT5tb2RlID09IE1PREVfR0VUTkVYVCB8fCByZXFpbmZvLT5tb2RlID09IE1PREVfR0VUQlVMSykgewoKICAgICAgICAgICAgaWYgKHNubXBfb2lkX2NvbXBhcmUobnB0ciwgbmxlbiwgcmVxdWVzdC0+c3VidHJlZS0+c3RhcnRfYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+c3VidHJlZS0+c3RhcnRfbGVuKSA8IDApIHsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJhZ2VudHgvbWFzdGVyIiwiaW5leGFjdCByZXF1ZXN0IHByZWNlZWRpbmcgcmVnaW9uICgiKSk7CiAgICAgICAgICAgICAgICBERUJVR01TR09JRCgoImFnZW50eC9tYXN0ZXIiLCByZXF1ZXN0LT5zdWJ0cmVlLT5zdGFydF9hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPnN1YnRyZWUtPnN0YXJ0X2xlbikpOwogICAgICAgICAgICAgICAgREVCVUdNU0coKCJhZ2VudHgvbWFzdGVyIiwgIilcbiIpKTsKICAgICAgICAgICAgICAgIG5wdHIgPSByZXF1ZXN0LT5zdWJ0cmVlLT5zdGFydF9hOwogICAgICAgICAgICAgICAgbmxlbiA9IHJlcXVlc3QtPnN1YnRyZWUtPnN0YXJ0X2xlbjsKICAgICAgICAgICAgICAgIHJlcXVlc3QtPmluY2x1c2l2ZSA9IDE7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChyZXF1ZXN0LT5pbmNsdXNpdmUpIHsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJhZ2VudHgvbWFzdGVyIiwgIklOQ0xVU0lWRSB2YXJiaW5kICIpKTsKICAgICAgICAgICAgICAgIERFQlVHTVNHT0lEKCgiYWdlbnR4L21hc3RlciIsIG5wdHIsIG5sZW4pKTsKICAgICAgICAgICAgICAgIERFQlVHTVNHKCgiYWdlbnR4L21hc3RlciIsICIgc2NvcGVkIHRvICIpKTsKICAgICAgICAgICAgICAgIERFQlVHTVNHT0lEKCgiYWdlbnR4L21hc3RlciIsIHJlcXVlc3QtPnJhbmdlX2VuZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5yYW5nZV9lbmRfbGVuKSk7CiAgICAgICAgICAgICAgICBERUJVR01TRygoImFnZW50eC9tYXN0ZXIiLCAiXG4iKSk7CiAgICAgICAgICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCBucHRyLCBubGVuLCBBU05fUFJJVl9JTkNMX1JBTkdFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikgcmVxdWVzdC0+cmFuZ2VfZW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJhbmdlX2VuZF9sZW4gKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihvaWQpKTsKICAgICAgICAgICAgICAgIHJlcXVlc3QtPmluY2x1c2l2ZSA9IDA7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgiYWdlbnR4L21hc3RlciIsICJFWENMVVNJVkUgdmFyYmluZCAiKSk7CiAgICAgICAgICAgICAgICBERUJVR01TR09JRCgoImFnZW50eC9tYXN0ZXIiLCBucHRyLCBubGVuKSk7CiAgICAgICAgICAgICAgICBERUJVR01TRygoImFnZW50eC9tYXN0ZXIiLCAiIHNjb3BlZCB0byAiKSk7CiAgICAgICAgICAgICAgICBERUJVR01TR09JRCgoImFnZW50eC9tYXN0ZXIiLCByZXF1ZXN0LT5yYW5nZV9lbmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cmFuZ2VfZW5kX2xlbikpOwogICAgICAgICAgICAgICAgREVCVUdNU0coKCJhZ2VudHgvbWFzdGVyIiwgIlxuIikpOwogICAgICAgICAgICAgICAgc25tcF9wZHVfYWRkX3ZhcmlhYmxlKHBkdSwgbnB0ciwgbmxlbiwgQVNOX1BSSVZfRVhDTF9SQU5HRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyICopIHJlcXVlc3QtPnJhbmdlX2VuZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5yYW5nZV9lbmRfbGVuICoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2Yob2lkKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCByZXF1ZXN0LT5yZXF1ZXN0dmItPm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5yZXF1ZXN0dmItPm5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cmVxdWVzdHZiLT50eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cmVxdWVzdHZiLT52YWwuc3RyaW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cmVxdWVzdHZiLT52YWxfbGVuKTsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogbWFyayB0aGUgcmVxdWVzdCBhcyBkZWxheWVkIAogICAgICAgICAqLwogICAgICAgIGlmIChwZHUtPmNvbW1hbmQgIT0gQUdFTlRYX01TR19DTEVBTlVQU0VUKQogICAgICAgICAgICByZXF1ZXN0LT5kZWxlZ2F0ZWQgPSBSRVFVRVNUX0lTX0RFTEVHQVRFRDsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHJlcXVlc3QtPmRlbGVnYXRlZCA9IFJFUVVFU1RfSVNfTk9UX0RFTEVHQVRFRDsKCiAgICAgICAgLyoKICAgICAgICAgKiBuZXh0Li4uIAogICAgICAgICAqLwogICAgICAgIHJlcXVlc3QgPSByZXF1ZXN0LT5uZXh0OwogICAgfQoKICAgIC8qCiAgICAgKiBXaGVuIHRoZSBtYXN0ZXIgc2VuZHMgYSBDbGVhbnVwU2V0IFBEVSwgaXQgd2lsbCBuZXZlciBnZXQgYSByZXNwb25zZQogICAgICogYmFjayBmcm9tIHRoZSBzdWJhZ2VudC4gU28gd2Ugc2hvdWxkbid0IGFsbG9jYXRlIHRoZQogICAgICogbmV0c25tcF9kZWxlZ2F0ZWRfY2FjaGUgc3RydWN0dXJlIGluIHRoaXMgY2FzZS4KICAgICAqLwogICAgaWYgKHBkdS0+Y29tbWFuZCAhPSBBR0VOVFhfTVNHX0NMRUFOVVBTRVQpCiAgICAgICAgY2JfZGF0YSA9IG5ldHNubXBfY3JlYXRlX2RlbGVnYXRlZF9jYWNoZShoYW5kbGVyLCByZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxaW5mbywgcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCAqKSBheF9zZXNzaW9uKTsKICAgIGVsc2UKICAgICAgICBjYl9kYXRhID0gTlVMTDsKCiAgICAvKgogICAgICogc2VuZCB0aGUgcmVxdWVzdHMgb3V0LgogICAgICovCiAgICBERUJVR01TR1RMKCgiYWdlbnR4IiwgInNlbmRpbmcgcGR1IChyZXE9MHgleCx0cmFucz0weCV4LHNlc3M9MHgleClcbiIsCiAgICAgICAgICAgICAgICBwZHUtPnJlcWlkLHBkdS0+dHJhbnNpZCwgcGR1LT5zZXNzaWQpKTsKICAgIHJlc3VsdCA9IHNubXBfYXN5bmNfc2VuZChheF9zZXNzaW9uLCBwZHUsIGFnZW50eF9nb3RfcmVzcG9uc2UsIGNiX2RhdGEpOwoKICAgIGlmIChyZXN1bHQgPT0gMCApIHsKICAgICAgICBzbm1wX2ZyZWVfcGR1KCBwZHUgKTsKICAgIH0KCiAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKfQo=