LyoKICogRGVidWdnZXIgc3RhY2sgaGFuZGxpbmcKICoKICogQ29weXJpZ2h0IDE5OTUgQWxleGFuZHJlIEp1bGxpYXJkCiAqIENvcHlyaWdodCAxOTk2IEVyaWMgWW91bmdkYWxlCiAqIENvcHlyaWdodCAxOTk5IE92ZSBL5XZlbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CgojaW5jbHVkZSAiZGVidWdnZXIuaCIKI2luY2x1ZGUgInN0YWNrZnJhbWUuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKCiNpZmRlZiBfX2kzODZfXwovKgogKiBXZSBrZWVwIHRoaXMgaW5mbyBmb3IgZWFjaCBmcmFtZSwgc28gdGhhdCB3ZSBjYW4KICogZmluZCBsb2NhbCB2YXJpYWJsZSBpbmZvcm1hdGlvbiBjb3JyZWN0bHkuCiAqLwpzdHJ1Y3QgYnRfaW5mbwp7CiAgdW5zaWduZWQgaW50CSAgICAgY3M7CiAgdW5zaWduZWQgaW50CSAgICAgZWlwOwogIHVuc2lnbmVkIGludAkgICAgIHNzOwogIHVuc2lnbmVkIGludAkgICAgIGVicDsKICBzdHJ1Y3Qgc3ltYm9sX2luZm8gZnJhbWU7Cn07CgpzdGF0aWMgaW50IG5mcmFtZTsKc3RhdGljIHN0cnVjdCBidF9pbmZvICogZnJhbWVzID0gTlVMTDsKCnR5cGVkZWYgc3RydWN0CnsKICAgIFdPUkQgYnA7CiAgICBXT1JEIGlwOwogICAgV09SRCBjczsKfSBGUkFNRTE2OwoKdHlwZWRlZiBzdHJ1Y3QKewogICAgRFdPUkQgYnA7CiAgICBEV09SRCBpcDsKICAgIFdPUkQgY3M7Cn0gRlJBTUUzMjsKI2VuZGlmCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBERUJVR19JbmZvU3RhY2sKICoKICogRHVtcCB0aGUgdG9wIG9mIHRoZSBzdGFjawogKi8Kdm9pZCBERUJVR19JbmZvU3RhY2sodm9pZCkKewojaWZkZWYgX19pMzg2X18KICAgIERCR19WQUxVRQl2YWx1ZTsKCiAgICB2YWx1ZS50eXBlID0gTlVMTDsKICAgIHZhbHVlLmNvb2tpZSA9IERWX1RBUkdFVDsKICAgIHZhbHVlLmFkZHIuc2VnID0gREVCVUdfY29udGV4dC5TZWdTczsKICAgIHZhbHVlLmFkZHIub2ZmID0gREVCVUdfY29udGV4dC5Fc3A7CgogICAgREVCVUdfUHJpbnRmKCJTdGFjayBkdW1wOlxuIik7CiAgICBzd2l0Y2ggKERFQlVHX0dldFNlbGVjdG9yVHlwZSh2YWx1ZS5hZGRyLnNlZykpCiAgICB7CiAgICBjYXNlIE1PREVfMzI6IC8qIDMyLWJpdCBtb2RlICovCiAgICAgICBERUJVR19FeGFtaW5lTWVtb3J5KCAmdmFsdWUsIDI0LCAneCcgKTsKICAgICAgIGJyZWFrOwogICAgY2FzZSBNT0RFXzE2OiAgLyogMTYtYml0IG1vZGUgKi8KICAgIGNhc2UgTU9ERV9WTTg2OgogICAgICAgIHZhbHVlLmFkZHIub2ZmICY9IDB4ZmZmZjsKICAgICAgICBERUJVR19FeGFtaW5lTWVtb3J5KCAmdmFsdWUsIDI0LCAndycgKTsKCWJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgIERFQlVHX1ByaW50ZigiQmFkIHNlZ21lbnQgKCVsZClcbiIsIHZhbHVlLmFkZHIuc2VnKTsKICAgIH0KICAgIERFQlVHX1ByaW50ZigiXG4iKTsKI2VuZGlmCn0KCiNpZmRlZiBfX2kzODZfXwpzdGF0aWMgdm9pZCBERUJVR19Gb3JjZUZyYW1lKERCR19BRERSICpzdGFjaywgREJHX0FERFIgKmNvZGUsIGludCBmcmFtZW5vLCBlbnVtIGRiZ19tb2RlIG1vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG5vaXN5LCBjb25zdCBjaGFyICpjYXZlYXQpCnsKICAgIGludCB0aGVmcmFtZSA9IG5mcmFtZSsrOwogICAgZnJhbWVzID0gKHN0cnVjdCBidF9pbmZvICopREJHX3JlYWxsb2MoZnJhbWVzLAoJCQkJCSAgIG5mcmFtZSpzaXplb2Yoc3RydWN0IGJ0X2luZm8pKTsKICAgIGlmIChub2lzeSkKICAgICAgREVCVUdfUHJpbnRmKCIlcyVkICIsICh0aGVmcmFtZSA9PSBjdXJyX2ZyYW1lID8gIj0+IiA6ICIgICIpLAogICAgICAgICAgICAgIGZyYW1lbm8pOwogICAgZnJhbWVzW3RoZWZyYW1lXS5jcyA9IGNvZGUtPnNlZzsKICAgIGZyYW1lc1t0aGVmcmFtZV0uZWlwID0gY29kZS0+b2ZmOwogICAgaWYgKG5vaXN5KQogICAgICAgIGZyYW1lc1t0aGVmcmFtZV0uZnJhbWUgPSBERUJVR19QcmludEFkZHJlc3NBbmRBcmdzKCBjb2RlLCBtb2RlLCBzdGFjay0+b2ZmLCBUUlVFICk7CiAgICBlbHNlCiAgICAgIERFQlVHX0ZpbmROZWFyZXN0U3ltYm9sKCBjb2RlLCBUUlVFLAoJCQkgICAgICAgJmZyYW1lc1t0aGVmcmFtZV0uZnJhbWUuc3ltLCBzdGFjay0+b2ZmLAoJCQkgICAgICAgJmZyYW1lc1t0aGVmcmFtZV0uZnJhbWUubGlzdCk7CiAgICBmcmFtZXNbdGhlZnJhbWVdLnNzID0gc3RhY2stPnNlZzsKICAgIGZyYW1lc1t0aGVmcmFtZV0uZWJwID0gc3RhY2stPm9mZjsKICAgIGlmIChub2lzeSkgewogICAgICBERUJVR19QcmludGYoKG1vZGUgIT0gTU9ERV8zMikgPyAiIChicD0lMDRseCVzKVxuIiA6ICIgKGVicD0lMDhseCVzKVxuIiwKICAgICAgICAgICAgICAgICAgIHN0YWNrLT5vZmYsIGNhdmVhdCA/IGNhdmVhdCA6ICIiKTsKICAgIH0KfQoKc3RhdGljIEJPT0wgREVCVUdfRnJhbWUxNihEQkdfVEhSRUFEKiB0aHJlYWQsIERCR19BRERSICphZGRyLCB1bnNpZ25lZCBpbnQgKmNzLCBpbnQgZnJhbWVubywgaW50IG5vaXN5KQp7CiAgICB1bnNpZ25lZCBpbnQJcG9zc2libGVfY3MgPSAwOwogICAgRlJBTUUxNiAJCWZyYW1lOwogICAgdm9pZCoJCXAgPSAodm9pZCopREVCVUdfVG9MaW5lYXIoYWRkcik7CiAgICBEQkdfQUREUgkJY29kZTsKCiAgICBpZiAoIXApIHJldHVybiBGQUxTRTsKCiAgICBpZiAoIURFQlVHX1JFQURfTUVNKHAsICZmcmFtZSwgc2l6ZW9mKGZyYW1lKSkpIHsKICAgICAgICBpZiAobm9pc3kpIERFQlVHX0ludmFsQWRkcihhZGRyKTsKCXJldHVybiBGQUxTRTsKICAgIH0KICAgIGlmICghZnJhbWUuYnApIHJldHVybiBGQUxTRTsKCiAgICBpZiAoZnJhbWUuYnAgJiAxKSAqY3MgPSBmcmFtZS5jczsKICAgIGVsc2UgewogICAgICAgIC8qIG5vdCBleHBsaWNpdGx5IG1hcmtlZCBhcyBmYXIgY2FsbCwKCSAqIGJ1dCBjaGVjayB3aGV0aGVyIGl0IGNvdWxkIGJlIGFueXdheSAqLwogICAgICAgIGlmICgoKGZyYW1lLmNzJjcpPT03KSAmJiAoZnJhbWUuY3MgIT0gKmNzKSkgewoJICAgIExEVF9FTlRSWQlsZTsKCgkgICAgaWYgKEdldFRocmVhZFNlbGVjdG9yRW50cnkoIHRocmVhZC0+aGFuZGxlLCBmcmFtZS5jcywgJmxlKSAmJgoJCShsZS5IaWdoV29yZC5CaXRzLlR5cGUgJiAweDA4KSkgeyAvKiBjb2RlIHNlZ21lbnQgKi8KCSAgICAgICAgLyogaXQgaXMgdmVyeSB1bmNvbW1vbiB0byBwdXNoIGEgY29kZSBzZWdtZW50IGNzIGFzCgkJICogYSBwYXJhbWV0ZXIsIHNvIHRoaXMgc2hvdWxkIHdvcmsgaW4gbW9zdCBjYXNlcyAqLwoJICAgICAgICAqY3MgPSBwb3NzaWJsZV9jcyA9IGZyYW1lLmNzOwoJICAgIH0KCX0KICAgIH0KICAgIGNvZGUuc2VnID0gKmNzOwogICAgY29kZS5vZmYgPSBmcmFtZS5pcDsKICAgIGFkZHItPm9mZiA9IGZyYW1lLmJwICYgfjE7CiAgICBERUJVR19Gb3JjZUZyYW1lKGFkZHIsICZjb2RlLCBmcmFtZW5vLCBNT0RFXzE2LCBub2lzeSwKICAgICAgICAgICAgICAgICAgICAgcG9zc2libGVfY3MgPyAiLCBmYXIgY2FsbCBhc3N1bWVkIiA6IE5VTEwgKTsKICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgQk9PTCBERUJVR19GcmFtZTMyKERCR19BRERSICphZGRyLCB1bnNpZ25lZCBpbnQgKmNzLCBpbnQgZnJhbWVubywgaW50IG5vaXN5KQp7CiAgICBGUkFNRTMyIAkJZnJhbWU7CiAgICB2b2lkKgkJcCA9ICh2b2lkKilERUJVR19Ub0xpbmVhcihhZGRyKTsKICAgIERCR19BRERSCQljb2RlOwogICAgRFdPUkQJCW9sZF9icCA9IGFkZHItPm9mZjsKCiAgICBpZiAoIXApIHJldHVybiBGQUxTRTsKCiAgICBpZiAoIURFQlVHX1JFQURfTUVNKHAsICZmcmFtZSwgc2l6ZW9mKGZyYW1lKSkpIHsKICAgICAgIGlmIChub2lzeSkgREVCVUdfSW52YWxBZGRyKGFkZHIpOwogICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQogICAgaWYgKCFmcmFtZS5pcCkgcmV0dXJuIEZBTFNFOwoKICAgIGNvZGUuc2VnID0gKmNzOwogICAgY29kZS5vZmYgPSBmcmFtZS5pcDsKICAgIGFkZHItPm9mZiA9IGZyYW1lLmJwOwogICAgREVCVUdfRm9yY2VGcmFtZShhZGRyLCAmY29kZSwgZnJhbWVubywgTU9ERV8zMiwgbm9pc3ksIE5VTEwpOwogICAgaWYgKGFkZHItPm9mZiA9PSBvbGRfYnApIHJldHVybiBGQUxTRTsKICAgIHJldHVybiBUUlVFOwp9CiNlbmRpZgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgREVCVUdfQmFja1RyYWNlCiAqCiAqIERpc3BsYXkgYSBzdGFjayBiYWNrLXRyYWNlLgogKi8Kdm9pZCBERUJVR19CYWNrVHJhY2UoRFdPUkQgdGlkLCBCT09MIG5vaXN5KQp7CiNpZmRlZiBfX2kzODYKICAgIERCR19BRERSIAkJYWRkciwgc3dfYWRkciwgY29kZSwgdG1wOwogICAgdW5zaWduZWQgaW50IAlzcywgY3M7CiAgICBpbnQgCQlmcmFtZW5vID0gMCwgaXMxNiwgb2s7CiAgICBEV09SRCAJCW5leHRfc3dpdGNoLCBjdXJfc3dpdGNoLCBwOwogICAgU1RBQ0sxNkZSQU1FICAgICAgIAlmcmFtZTE2OwogICAgU1RBQ0szMkZSQU1FICAgICAgIAlmcmFtZTMyOwogICAgY2hhcgkJY2g7CiAgICBDT05URVhUCQljdHg7CiAgICBEQkdfVEhSRUFEKgkJdGhyZWFkOwoKICAgIGludCAJCWNvcHlfbmZyYW1lID0gMDsKICAgIGludAkJCWNvcHlfY3Vycl9mcmFtZSA9IDA7CiAgICBzdHJ1Y3QgYnRfaW5mbyogCWNvcHlfZnJhbWVzID0gTlVMTDsKCiAgICBpZiAobm9pc3kpIERFQlVHX1ByaW50ZigiQmFja3RyYWNlOlxuIik7CgogICAgaWYgKHRpZCA9PSBERUJVR19DdXJyVGlkKQogICAgewoJIGN0eCA9IERFQlVHX2NvbnRleHQ7CgkgdGhyZWFkID0gREVCVUdfQ3VyclRocmVhZDsKCgkgaWYgKGZyYW1lcykgREJHX2ZyZWUoIGZyYW1lcyApOwoJIC8qIGZyYW1lcyA9IChzdHJ1Y3QgYnRfaW5mbyAqKSBEQkdfYWxsb2MoIHNpemVvZihzdHJ1Y3QgYnRfaW5mbykgKTsgKi8KICAgIH0KICAgIGVsc2UKICAgIHsKCSB0aHJlYWQgPSBERUJVR19HZXRUaHJlYWQoREVCVUdfQ3VyclByb2Nlc3MsIHRpZCk7CgoJIGlmICghdGhyZWFkKQoJIHsKCSAgICAgIERFQlVHX1ByaW50ZigiVW5rbm93biB0aHJlYWQgaWQgKDB4JTA4bHgpIGluIGN1cnJlbnQgcHJvY2Vzc1xuIiwgdGlkKTsKCSAgICAgIHJldHVybjsKCSB9CgkgbWVtc2V0KCZjdHgsIDAsIHNpemVvZihjdHgpKTsKCSBjdHguQ29udGV4dEZsYWdzID0gQ09OVEVYVF9DT05UUk9MIHwgQ09OVEVYVF9TRUdNRU5UUzsKCgkgaWYgKCBTdXNwZW5kVGhyZWFkKCB0aHJlYWQtPmhhbmRsZSApID09IC0xIHx8CgkgICAgICAhR2V0VGhyZWFkQ29udGV4dCggdGhyZWFkLT5oYW5kbGUsICZjdHggKSkKCSB7CgkgICAgICBERUJVR19QcmludGYoIkNhbid0IGdldCBjb250ZXh0IGZvciB0aHJlYWQgaWQgKDB4JTA4bHgpIGluIGN1cnJlbnQgcHJvY2Vzc1xuIiwgdGlkKTsKCSAgICAgIHJldHVybjsKCSB9CgkgLyogbmVlZCB0byBhdm9pZCB0cmFzaGluZyBzdGFjayBmcmFtZSBmb3IgY3VycmVudCB0aHJlYWQgKi8KCSBjb3B5X25mcmFtZSA9IG5mcmFtZTsKCSBjb3B5X2ZyYW1lcyA9IGZyYW1lczsKCSBjb3B5X2N1cnJfZnJhbWUgPSBjdXJyX2ZyYW1lOwoJIGN1cnJfZnJhbWUgPSAwOwogICAgfQoKICAgIG5mcmFtZSA9IDA7CiAgICBmcmFtZXMgPSBOVUxMOwoKICAgIGNzID0gY3R4LlNlZ0NzOwogICAgc3MgPSBjdHguU2VnU3M7CgogICAgaWYgKERFQlVHX0lzU2VsZWN0b3JTeXN0ZW0oc3MpKSBzcyA9IDA7CiAgICBpZiAoREVCVUdfSXNTZWxlY3RvclN5c3RlbShjcykpIGNzID0gMDsKCiAgICAvKiBmaXJzdCBzdGFjayBmcmFtZSBmcm9tIHJlZ2lzdGVycyAqLwogICAgc3dpdGNoIChERUJVR19HZXRTZWxlY3RvclR5cGUoc3MpKQogICAgewogICAgY2FzZSBNT0RFXzMyOgogICAgICAgIGNvZGUuc2VnID0gY3M7CiAgICAgICAgY29kZS5vZmYgPSBjdHguRWlwOwogICAgICAgIGFkZHIuc2VnID0gc3M7CglhZGRyLm9mZiA9IGN0eC5FYnA7CiAgICAgICAgREVCVUdfRm9yY2VGcmFtZSggJmFkZHIsICZjb2RlLCBmcmFtZW5vLCBNT0RFXzMyLCBub2lzeSwgTlVMTCApOwogICAgICAgIGlmICghKGNvZGUuc2VnIHx8IGNvZGUub2ZmKSkgewogICAgICAgICAgICAvKiB0cnlpbmcgdG8gZXhlY3V0ZSBhIG51bGwgcG9pbnRlci4uLiB5dWNrLi4uCiAgICAgICAgICAgICAqIGlmIGl0IHdhcyBhIGNhbGwgdG8gbnVsbCwgdGhlIHJldHVybiBFSVAgc2hvdWxkIGJlCiAgICAgICAgICAgICAqIGF2YWlsYWJsZSBhdCBTUzpFU1AsIHNvIGxldCdzIHRyeSB0byByZXRyaWV2ZSBpdCAqLwogICAgICAgICAgICB0bXAuc2VnID0gc3M7CiAgICAgICAgICAgIHRtcC5vZmYgPSBjdHguRXNwOwogICAgICAgICAgICBpZiAoREVCVUdfUkVBRF9NRU0oKHZvaWQgKilERUJVR19Ub0xpbmVhcigmdG1wKSwgJmNvZGUub2ZmLCBzaXplb2YoY29kZS5vZmYpKSkgewogICAgICAgICAgICAgICAgREVCVUdfRm9yY2VGcmFtZSggJmFkZHIsICZjb2RlLCArK2ZyYW1lbm8sIE1PREVfMzIsIG5vaXN5LCAiLCBudWxsIGNhbGwgYXNzdW1lZCIgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpczE2ID0gRkFMU0U7CglicmVhazsKICAgIGNhc2UgTU9ERV8xNjoKICAgIGNhc2UgTU9ERV9WTTg2OgogICAgICAgIGNvZGUuc2VnID0gY3M7CiAgICAgICAgY29kZS5vZmYgPSBMT1dPUkQoY3R4LkVpcCk7CiAgICAgICAgYWRkci5zZWcgPSBzczsKCWFkZHIub2ZmID0gTE9XT1JEKGN0eC5FYnApOwogICAgICAgIERFQlVHX0ZvcmNlRnJhbWUoICZhZGRyLCAmY29kZSwgZnJhbWVubywgTU9ERV8xNiwgbm9pc3ksIE5VTEwgKTsKICAgICAgICBpczE2ID0gVFJVRTsKCWJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBpZiAobm9pc3kpIERFQlVHX1ByaW50ZigiQmFkIHNlZ21lbnQgJyV4J1xuIiwgc3MpOwoJcmV0dXJuOwogICAgfQoKICAgIC8qIGN1cl9zd2l0Y2ggaG9sZHMgYWRkcmVzcyBvZiBjdXJyX3N0YWNrJ3MgZmllbGQgaW4gVEVCIGluIGRlYnVnZ2VlCiAgICAgKiBhZGRyZXNzIHNwYWNlCiAgICAgKi8KICAgIGN1cl9zd2l0Y2ggPSAoRFdPUkQpdGhyZWFkLT50ZWIgKyBPRkZTRVRfT0YoVEVCLCBjdXJfc3RhY2spOwogICAgaWYgKCFERUJVR19SRUFEX01FTSgodm9pZCopY3VyX3N3aXRjaCwgJm5leHRfc3dpdGNoLCBzaXplb2YobmV4dF9zd2l0Y2gpKSkgewogICAgICAgIGlmIChub2lzeSkgREVCVUdfUHJpbnRmKCJDYW4ndCByZWFkIFRFQjpjdXJfc3RhY2tcbiIpOwoJcmV0dXJuOwogICAgfQoKICAgIGlmIChpczE2KSB7CiAgICAgICAgaWYgKCFERUJVR19SRUFEX01FTSgodm9pZCopbmV4dF9zd2l0Y2gsICZmcmFtZTMyLCBzaXplb2YoU1RBQ0szMkZSQU1FKSkpIHsKCSAgICBpZiAobm9pc3kpIERFQlVHX1ByaW50ZigiQmFkIHN0YWNrIGZyYW1lIDB4JTA4bHhcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1bnNpZ25lZCBsb25nKShTVEFDSzMyRlJBTUUqKW5leHRfc3dpdGNoICk7CgkgICAgcmV0dXJuOwoJfQoJY3VyX3N3aXRjaCA9IChEV09SRClmcmFtZTMyLmZyYW1lMTY7Cglzd19hZGRyLnNlZyA9IFNFTEVDVE9ST0YoY3VyX3N3aXRjaCk7Cglzd19hZGRyLm9mZiA9IE9GRlNFVE9GKGN1cl9zd2l0Y2gpOwogICAgfSBlbHNlIHsKICAgICAgICB0bXAuc2VnID0gU0VMRUNUT1JPRihuZXh0X3N3aXRjaCk7Cgl0bXAub2ZmID0gT0ZGU0VUT0YobmV4dF9zd2l0Y2gpOwoJcCA9IERFQlVHX1RvTGluZWFyKCZ0bXApOwoKCWlmICghREVCVUdfUkVBRF9NRU0oKHZvaWQqKXAsICZmcmFtZTE2LCBzaXplb2YoU1RBQ0sxNkZSQU1FKSkpIHsKCSAgICBpZiAobm9pc3kpIERFQlVHX1ByaW50ZigiQmFkIHN0YWNrIGZyYW1lIDB4JTA4bHhcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1bnNpZ25lZCBsb25nKShTVEFDSzE2RlJBTUUqKXAgKTsKCSAgICByZXR1cm47Cgl9CgljdXJfc3dpdGNoID0gKERXT1JEKWZyYW1lMTYuZnJhbWUzMjsKCXN3X2FkZHIuc2VnID0gc3M7Cglzd19hZGRyLm9mZiA9IGN1cl9zd2l0Y2g7CiAgICB9CiAgICBpZiAoIURFQlVHX1JFQURfTUVNKCh2b2lkKilERUJVR19Ub0xpbmVhcigmc3dfYWRkciksICZjaCwgc2l6ZW9mKGNoKSkpIHsKICAgICAgICBzd19hZGRyLnNlZyA9IChEV09SRCktMTsKCXN3X2FkZHIub2ZmID0gKERXT1JEKS0xOwogICAgfQoKICAgIGZvciAob2sgPSBUUlVFOyBvazspIHsKICAgICAgICBpZiAoKGZyYW1lc1tmcmFtZW5vXS5zcyA9PSBzd19hZGRyLnNlZykgJiYKICAgICAgICAgICAgc3dfYWRkci5vZmYgJiYgKGZyYW1lc1tmcmFtZW5vXS5lYnAgPj0gc3dfYWRkci5vZmYpKQogICAgICAgIHsKCSAgIC8qIDE2PC0+MzIgc3dpdGNoLi4uCgkgICAgKiB5ZXMsIEkga25vdyB0aGlzIGlzIGNvbmZ1c2luZywgaXQgZ2F2ZSBtZSBhIGhlYWRhY2hlIHRvbyAqLwoJICAgaWYgKGlzMTYpIHsKCgkgICAgICAgaWYgKCFERUJVR19SRUFEX01FTSgodm9pZCopbmV4dF9zd2l0Y2gsICZmcmFtZTMyLCBzaXplb2YoU1RBQ0szMkZSQU1FKSkpIHsKCQkgIGlmIChub2lzeSkgREVCVUdfUHJpbnRmKCJCYWQgc3RhY2sgZnJhbWUgMHglMDhseFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVuc2lnbmVkIGxvbmcpKFNUQUNLMzJGUkFNRSopbmV4dF9zd2l0Y2ggKTsKCQkgIHJldHVybjsKCSAgICAgICB9CgoJICAgICAgIGNvZGUuc2VnICA9IDA7CgkgICAgICAgY29kZS5vZmYgID0gZnJhbWUzMi5yZXRhZGRyOwoKCSAgICAgICBjcyA9IDA7CgkgICAgICAgYWRkci5zZWcgPSAwOwoJICAgICAgIGFkZHIub2ZmID0gZnJhbWUzMi5lYnA7CgkgICAgICAgREVCVUdfRm9yY2VGcmFtZSggJmFkZHIsICZjb2RlLCArK2ZyYW1lbm8sIE1PREVfMzIsIG5vaXN5LCBOVUxMICk7CgoJICAgICAgIG5leHRfc3dpdGNoID0gY3VyX3N3aXRjaDsKCSAgICAgICB0bXAuc2VnID0gU0VMRUNUT1JPRihuZXh0X3N3aXRjaCk7CgkgICAgICAgdG1wLm9mZiA9IE9GRlNFVE9GKG5leHRfc3dpdGNoKTsKCSAgICAgICBwID0gREVCVUdfVG9MaW5lYXIoJnRtcCk7CgoJICAgICAgIGlmICghREVCVUdfUkVBRF9NRU0oKHZvaWQqKXAsICZmcmFtZTE2LCBzaXplb2YoU1RBQ0sxNkZSQU1FKSkpIHsKCQkgICBpZiAobm9pc3kpIERFQlVHX1ByaW50ZigiQmFkIHN0YWNrIGZyYW1lIDB4JTA4bHhcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodW5zaWduZWQgbG9uZykoU1RBQ0sxNkZSQU1FKilwICk7CgkJICAgcmV0dXJuOwoJICAgICAgIH0KCSAgICAgICBjdXJfc3dpdGNoID0gKERXT1JEKWZyYW1lMTYuZnJhbWUzMjsKCSAgICAgICBzd19hZGRyLnNlZyA9IDA7CgkgICAgICAgc3dfYWRkci5vZmYgPSBjdXJfc3dpdGNoOwoKCSAgICAgICBpczE2ID0gRkFMU0U7CgkgICB9IGVsc2UgewoJICAgICAgdG1wLnNlZyA9IFNFTEVDVE9ST0YobmV4dF9zd2l0Y2gpOwoJICAgICAgdG1wLm9mZiA9IE9GRlNFVE9GKG5leHRfc3dpdGNoKTsKCSAgICAgIHAgPSBERUJVR19Ub0xpbmVhcigmdG1wKTsKCgkgICAgICBpZiAoIURFQlVHX1JFQURfTUVNKCh2b2lkKilwLCAmZnJhbWUxNiwgc2l6ZW9mKFNUQUNLMTZGUkFNRSkpKSB7CgkJICBpZiAobm9pc3kpIERFQlVHX1ByaW50ZigiQmFkIHN0YWNrIGZyYW1lIDB4JTA4bHhcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1bnNpZ25lZCBsb25nKShTVEFDSzE2RlJBTUUqKXAgKTsKCQkgIHJldHVybjsKCSAgICAgIH0KCgkgICAgICBjb2RlLnNlZyAgPSBmcmFtZTE2LmNzOwoJICAgICAgY29kZS5vZmYgID0gZnJhbWUxNi5pcDsKCgkgICAgICBjcyA9IGZyYW1lMTYuY3M7CgkgICAgICBhZGRyLnNlZyA9IFNFTEVDVE9ST0YobmV4dF9zd2l0Y2gpOwoJICAgICAgYWRkci5vZmYgPSBmcmFtZTE2LmJwOwoJICAgICAgREVCVUdfRm9yY2VGcmFtZSggJmFkZHIsICZjb2RlLCArK2ZyYW1lbm8sIE1PREVfMTYsIG5vaXN5LCBOVUxMICk7CgoJICAgICAgbmV4dF9zd2l0Y2ggPSBjdXJfc3dpdGNoOwoJICAgICAgaWYgKCFERUJVR19SRUFEX01FTSgodm9pZCopbmV4dF9zd2l0Y2gsICZmcmFtZTMyLCBzaXplb2YoU1RBQ0szMkZSQU1FKSkpIHsKCQkgaWYgKG5vaXN5KSBERUJVR19QcmludGYoIkJhZCBzdGFjayBmcmFtZSAweCUwOGx4XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1bnNpZ25lZCBsb25nKShTVEFDSzMyRlJBTUUqKW5leHRfc3dpdGNoICk7CgkJIHJldHVybjsKCSAgICAgIH0KCSAgICAgIGN1cl9zd2l0Y2ggPSAoRFdPUkQpZnJhbWUzMi5mcmFtZTE2OwoJICAgICAgc3dfYWRkci5zZWcgPSBTRUxFQ1RPUk9GKGN1cl9zd2l0Y2gpOwoJICAgICAgc3dfYWRkci5vZmYgPSBPRkZTRVRPRihjdXJfc3dpdGNoKTsKCgkgICAgICBpczE2ID0gVFJVRTsKCSAgIH0KCSAgIGlmICghREVCVUdfUkVBRF9NRU0oKHZvaWQqKURFQlVHX1RvTGluZWFyKCZzd19hZGRyKSwgJmNoLCBzaXplb2YoY2gpKSkgewoJICAgICAgc3dfYWRkci5zZWcgPSAoRFdPUkQpLTE7CgkgICAgICBzd19hZGRyLm9mZiA9IChEV09SRCktMTsKCSAgIH0KCX0gZWxzZSB7CgkgICAgLyogb3JkaW5hcnkgc3RhY2sgZnJhbWUgKi8KCSAgIG9rID0gaXMxNiA/IERFQlVHX0ZyYW1lMTYoIHRocmVhZCwgJmFkZHIsICZjcywgKytmcmFtZW5vLCBub2lzeSkKCSAgICAgIDogREVCVUdfRnJhbWUzMiggJmFkZHIsICZjcywgKytmcmFtZW5vLCBub2lzeSk7Cgl9CiAgICB9CiAgICBpZiAobm9pc3kpIERFQlVHX1ByaW50ZigiXG4iKTsKCiAgICBpZiAodGlkICE9IERFQlVHX0N1cnJUaWQpCiAgICB7CgkgUmVzdW1lVGhyZWFkKCB0aHJlYWQtPmhhbmRsZSApOwoJIC8qIHJlc3RvcmUgc3RhY2sgZnJhbWUgZm9yIGN1cnJlbnQgdGhyZWFkICovCgkgaWYgKGZyYW1lcykgREJHX2ZyZWUoIGZyYW1lcyApOwoJIGZyYW1lcyA9IGNvcHlfZnJhbWVzOwoJIG5mcmFtZSA9IGNvcHlfbmZyYW1lOwoJIGN1cnJfZnJhbWUgPSBjb3B5X2N1cnJfZnJhbWU7CiAgICB9CiNlbmRpZgp9CgppbnQKREVCVUdfU2V0RnJhbWUoaW50IG5ld2ZyYW1lKQp7CiNpZmRlZiBfX2kzODZfXwogIGludAkJcnRuID0gRkFMU0U7CgogIGN1cnJfZnJhbWUgPSBuZXdmcmFtZTsKCiAgaWYoIGN1cnJfZnJhbWUgPj0gbmZyYW1lICkKICAgIHsKICAgICAgY3Vycl9mcmFtZSA9IG5mcmFtZSAtIDE7CiAgICB9CgogIGlmKCBjdXJyX2ZyYW1lIDwgMCApCiAgICB7CiAgICAgIGN1cnJfZnJhbWUgPSAwOwogICAgfQoKICAgaWYoIGZyYW1lcyAmJiBmcmFtZXNbY3Vycl9mcmFtZV0uZnJhbWUubGlzdC5zb3VyY2VmaWxlICE9IE5VTEwgKQogICAgewogICAgICBERUJVR19MaXN0KCZmcmFtZXNbY3Vycl9mcmFtZV0uZnJhbWUubGlzdCwgTlVMTCwgMCk7CiAgICB9CgogIHJ0biA9IFRSVUU7CiAgcmV0dXJuIChydG4pOwojZWxzZSAvKiBfX2kzODZfXyAqLwogIHJldHVybiBGQUxTRTsKI2VuZGlmIC8qIF9faTM4Nl9fICovCn0KCmludApERUJVR19HZXRDdXJyZW50RnJhbWUoc3RydWN0IG5hbWVfaGFzaCAqKiBuYW1lLCB1bnNpZ25lZCBpbnQgKiBlaXAsCgkJICAgICAgdW5zaWduZWQgaW50ICogZWJwKQp7CiNpZmRlZiBfX2kzODZfXwogIC8qCiAgICogSWYgd2UgZG9uJ3QgaGF2ZSBhIHZhbGlkIGJhY2t0cmFjZSwgdGhlbiBqdXN0IHJldHVybi4KICAgKi8KICBpZiggZnJhbWVzID09IE5VTEwgKQogICAgewogICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogIC8qCiAgICogSWYgd2UgZG9uJ3Qga25vdyB3aGF0IHRoZSBjdXJyZW50IGZ1bmN0aW9uIGlzLCB0aGVuIHdlIGFsc28gaGF2ZQogICAqIG5vdGhpbmcgdG8gcmVwb3J0IGhlcmUuCiAgICovCiAgaWYoIGZyYW1lc1tjdXJyX2ZyYW1lXS5mcmFtZS5zeW0gPT0gTlVMTCApCiAgICB7CiAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgKm5hbWUgPSBmcmFtZXNbY3Vycl9mcmFtZV0uZnJhbWUuc3ltOwogICplaXAgPSBmcmFtZXNbY3Vycl9mcmFtZV0uZWlwOwogICplYnAgPSBmcmFtZXNbY3Vycl9mcmFtZV0uZWJwOwoKICByZXR1cm4gVFJVRTsKI2Vsc2UgLyogX19pMzg2X18gKi8KICByZXR1cm4gRkFMU0U7CiNlbmRpZiAvKiBfX2kzODZfXyAqLwp9Cg==