LyoKICogRGVidWdnZXIgc3RhY2sgaGFuZGxpbmcKICoKICogQ29weXJpZ2h0IDE5OTUgQWxleGFuZHJlIEp1bGxpYXJkCiAqIENvcHlyaWdodCAxOTk2IEVyaWMgWW91bmdkYWxlCiAqIENvcHlyaWdodCAxOTk5IE92ZSBL5XZlbgogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKCiNpbmNsdWRlIDxzdGRsaWIuaD4KCiNpbmNsdWRlICJkZWJ1Z2dlci5oIgojaW5jbHVkZSAic3RhY2tmcmFtZS5oIgojaW5jbHVkZSAid2luYmFzZS5oIgoKI2lmZGVmIF9faTM4Nl9fCi8qCiAqIFdlIGtlZXAgdGhpcyBpbmZvIGZvciBlYWNoIGZyYW1lLCBzbyB0aGF0IHdlIGNhbgogKiBmaW5kIGxvY2FsIHZhcmlhYmxlIGluZm9ybWF0aW9uIGNvcnJlY3RseS4KICovCnN0cnVjdCBidF9pbmZvCnsKICB1bnNpZ25lZCBpbnQJICAgICBjczsKICB1bnNpZ25lZCBpbnQJICAgICBlaXA7CiAgdW5zaWduZWQgaW50CSAgICAgc3M7CiAgdW5zaWduZWQgaW50CSAgICAgZWJwOwogIHN0cnVjdCBzeW1ib2xfaW5mbyBmcmFtZTsKfTsKCnN0YXRpYyBpbnQgbmZyYW1lOwpzdGF0aWMgc3RydWN0IGJ0X2luZm8gKiBmcmFtZXMgPSBOVUxMOwoKdHlwZWRlZiBzdHJ1Y3QKewogICAgV09SRCBicDsKICAgIFdPUkQgaXA7CiAgICBXT1JEIGNzOwp9IEZSQU1FMTY7Cgp0eXBlZGVmIHN0cnVjdAp7CiAgICBEV09SRCBicDsKICAgIERXT1JEIGlwOwogICAgV09SRCBjczsKfSBGUkFNRTMyOwojZW5kaWYKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIERFQlVHX0luZm9TdGFjawogKgogKiBEdW1wIHRoZSB0b3Agb2YgdGhlIHN0YWNrCiAqLwp2b2lkIERFQlVHX0luZm9TdGFjayh2b2lkKQp7CiNpZmRlZiBfX2kzODZfXwogICAgREJHX1ZBTFVFCXZhbHVlOwogICAgCiAgICB2YWx1ZS50eXBlID0gTlVMTDsKICAgIHZhbHVlLmNvb2tpZSA9IERWX1RBUkdFVDsKICAgIHZhbHVlLmFkZHIuc2VnID0gREVCVUdfY29udGV4dC5TZWdTczsKICAgIHZhbHVlLmFkZHIub2ZmID0gREVCVUdfY29udGV4dC5Fc3A7CgogICAgREVCVUdfUHJpbnRmKERCR19DSE5fTUVTRywiU3RhY2sgZHVtcDpcbiIpOwogICAgc3dpdGNoIChERUJVR19HZXRTZWxlY3RvclR5cGUodmFsdWUuYWRkci5zZWcpKQogICAgewogICAgY2FzZSBNT0RFXzMyOiAvKiAzMi1iaXQgbW9kZSAqLwogICAgICAgREVCVUdfRXhhbWluZU1lbW9yeSggJnZhbHVlLCAyNCwgJ3gnICk7CiAgICAgICBicmVhazsKICAgIGNhc2UgTU9ERV8xNjogIC8qIDE2LWJpdCBtb2RlICovCiAgICBjYXNlIE1PREVfVk04NjoKICAgICAgICB2YWx1ZS5hZGRyLm9mZiAmPSAweGZmZmY7CiAgICAgICAgREVCVUdfRXhhbWluZU1lbW9yeSggJnZhbHVlLCAyNCwgJ3cnICk7CglicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICBERUJVR19QcmludGYoREJHX0NITl9NRVNHLCAiQmFkIHNlZ21lbnQgKCVsZClcbiIsIHZhbHVlLmFkZHIuc2VnKTsKICAgIH0KICAgIERFQlVHX1ByaW50ZihEQkdfQ0hOX01FU0csIlxuIik7CiNlbmRpZgp9CgojaWZkZWYgX19pMzg2X18Kc3RhdGljIHZvaWQgREVCVUdfRm9yY2VGcmFtZShEQkdfQUREUiAqc3RhY2ssIERCR19BRERSICpjb2RlLCBpbnQgZnJhbWVubywgZW51bSBkYmdfbW9kZSBtb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBub2lzeSwgY29uc3QgY2hhciAqY2F2ZWF0KQp7CiAgICBpbnQgdGhlZnJhbWUgPSBuZnJhbWUrKzsKICAgIGZyYW1lcyA9IChzdHJ1Y3QgYnRfaW5mbyAqKURCR19yZWFsbG9jKGZyYW1lcywKCQkJCQkgICBuZnJhbWUqc2l6ZW9mKHN0cnVjdCBidF9pbmZvKSk7CiAgICBpZiAobm9pc3kpCiAgICAgIERFQlVHX1ByaW50ZihEQkdfQ0hOX01FU0csIiVzJWQgIiwgKHRoZWZyYW1lID09IGN1cnJfZnJhbWUgPyAiPT4iIDogIiAgIiksCiAgICAgICAgICAgICAgZnJhbWVubyk7CiAgICBmcmFtZXNbdGhlZnJhbWVdLmNzID0gY29kZS0+c2VnOwogICAgZnJhbWVzW3RoZWZyYW1lXS5laXAgPSBjb2RlLT5vZmY7CiAgICBpZiAobm9pc3kpCiAgICAgICAgZnJhbWVzW3RoZWZyYW1lXS5mcmFtZSA9IERFQlVHX1ByaW50QWRkcmVzc0FuZEFyZ3MoIGNvZGUsIG1vZGUsIHN0YWNrLT5vZmYsIFRSVUUgKTsKICAgIGVsc2UKICAgICAgREVCVUdfRmluZE5lYXJlc3RTeW1ib2woIGNvZGUsIFRSVUUsIAoJCQkgICAgICAgJmZyYW1lc1t0aGVmcmFtZV0uZnJhbWUuc3ltLCBzdGFjay0+b2ZmLCAKCQkJICAgICAgICZmcmFtZXNbdGhlZnJhbWVdLmZyYW1lLmxpc3QpOwogICAgZnJhbWVzW3RoZWZyYW1lXS5zcyA9IHN0YWNrLT5zZWc7CiAgICBmcmFtZXNbdGhlZnJhbWVdLmVicCA9IHN0YWNrLT5vZmY7CiAgICBpZiAobm9pc3kpIHsKICAgICAgREVCVUdfUHJpbnRmKCBEQkdfQ0hOX01FU0csIChtb2RlICE9IE1PREVfMzIpID8gIiAoYnA9JTA0bHglcylcbiIgOiAiIChlYnA9JTA4bHglcylcbiIsCiAgICAgICAgICAgICAgICAgICAgc3RhY2stPm9mZiwgY2F2ZWF0P2NhdmVhdDoiIiApOwogICAgfQp9CgpzdGF0aWMgQk9PTCBERUJVR19GcmFtZTE2KERCR19USFJFQUQqIHRocmVhZCwgREJHX0FERFIgKmFkZHIsIHVuc2lnbmVkIGludCAqY3MsIGludCBmcmFtZW5vLCBpbnQgbm9pc3kpCnsKICAgIHVuc2lnbmVkIGludAlwb3NzaWJsZV9jcyA9IDA7CiAgICBGUkFNRTE2IAkJZnJhbWU7CiAgICB2b2lkKgkJcCA9ICh2b2lkKilERUJVR19Ub0xpbmVhcihhZGRyKTsKICAgIERCR19BRERSCQljb2RlOwogICAgCiAgICBpZiAoIXApIHJldHVybiBGQUxTRTsKICAgIAogICAgaWYgKCFERUJVR19SRUFEX01FTShwLCAmZnJhbWUsIHNpemVvZihmcmFtZSkpKSB7CiAgICAgICAgaWYgKG5vaXN5KSBERUJVR19JbnZhbEFkZHIoYWRkcik7CglyZXR1cm4gRkFMU0U7CiAgICB9CiAgICBpZiAoIWZyYW1lLmJwKSByZXR1cm4gRkFMU0U7CgogICAgaWYgKGZyYW1lLmJwICYgMSkgKmNzID0gZnJhbWUuY3M7CiAgICBlbHNlIHsKICAgICAgICAvKiBub3QgZXhwbGljaXRseSBtYXJrZWQgYXMgZmFyIGNhbGwsCgkgKiBidXQgY2hlY2sgd2hldGhlciBpdCBjb3VsZCBiZSBhbnl3YXkgKi8KICAgICAgICBpZiAoKChmcmFtZS5jcyY3KT09NykgJiYgKGZyYW1lLmNzICE9ICpjcykpIHsKCSAgICBMRFRfRU5UUlkJbGU7CgkgCgkgICAgaWYgKEdldFRocmVhZFNlbGVjdG9yRW50cnkoIHRocmVhZC0+aGFuZGxlLCBmcmFtZS5jcywgJmxlKSAmJgoJCShsZS5IaWdoV29yZC5CaXRzLlR5cGUgJiAweDA4KSkgeyAvKiBjb2RlIHNlZ21lbnQgKi8KCSAgICAgICAgLyogaXQgaXMgdmVyeSB1bmNvbW1vbiB0byBwdXNoIGEgY29kZSBzZWdtZW50IGNzIGFzCgkJICogYSBwYXJhbWV0ZXIsIHNvIHRoaXMgc2hvdWxkIHdvcmsgaW4gbW9zdCBjYXNlcyAqLwoJICAgICAgICAqY3MgPSBwb3NzaWJsZV9jcyA9IGZyYW1lLmNzOwoJICAgIH0KCX0KICAgIH0KICAgIGNvZGUuc2VnID0gKmNzOwogICAgY29kZS5vZmYgPSBmcmFtZS5pcDsKICAgIGFkZHItPm9mZiA9IGZyYW1lLmJwICYgfjE7CiAgICBERUJVR19Gb3JjZUZyYW1lKGFkZHIsICZjb2RlLCBmcmFtZW5vLCBNT0RFXzE2LCBub2lzeSwKICAgICAgICAgICAgICAgICAgICAgcG9zc2libGVfY3MgPyAiLCBmYXIgY2FsbCBhc3N1bWVkIiA6IE5VTEwgKTsKICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgQk9PTCBERUJVR19GcmFtZTMyKERCR19BRERSICphZGRyLCB1bnNpZ25lZCBpbnQgKmNzLCBpbnQgZnJhbWVubywgaW50IG5vaXN5KQp7CiAgICBGUkFNRTMyIAkJZnJhbWU7CiAgICB2b2lkKgkJcCA9ICh2b2lkKilERUJVR19Ub0xpbmVhcihhZGRyKTsKICAgIERCR19BRERSCQljb2RlOwogICAgRFdPUkQJCW9sZF9icCA9IGFkZHItPm9mZjsKICAgIAogICAgaWYgKCFwKSByZXR1cm4gRkFMU0U7CiAgICAKICAgIGlmICghREVCVUdfUkVBRF9NRU0ocCwgJmZyYW1lLCBzaXplb2YoZnJhbWUpKSkgewogICAgICAgaWYgKG5vaXN5KSBERUJVR19JbnZhbEFkZHIoYWRkcik7CiAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CiAgICBpZiAoIWZyYW1lLmlwKSByZXR1cm4gRkFMU0U7CgogICAgY29kZS5zZWcgPSAqY3M7CiAgICBjb2RlLm9mZiA9IGZyYW1lLmlwOwogICAgYWRkci0+b2ZmID0gZnJhbWUuYnA7CiAgICBERUJVR19Gb3JjZUZyYW1lKGFkZHIsICZjb2RlLCBmcmFtZW5vLCBNT0RFXzMyLCBub2lzeSwgTlVMTCk7CiAgICBpZiAoYWRkci0+b2ZmID09IG9sZF9icCkgcmV0dXJuIEZBTFNFOwogICAgcmV0dXJuIFRSVUU7Cn0KI2VuZGlmCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBERUJVR19CYWNrVHJhY2UKICoKICogRGlzcGxheSBhIHN0YWNrIGJhY2stdHJhY2UuCiAqLwp2b2lkIERFQlVHX0JhY2tUcmFjZShEV09SRCB0aWQsIEJPT0wgbm9pc3kpCnsKI2lmZGVmIF9faTM4NgogICAgREJHX0FERFIgCQlhZGRyLCBzd19hZGRyLCBjb2RlLCB0bXA7CiAgICB1bnNpZ25lZCBpbnQgCXNzLCBjczsKICAgIGludCAJCWZyYW1lbm8gPSAwLCBpczE2LCBvazsKICAgIERXT1JEIAkJbmV4dF9zd2l0Y2gsIGN1cl9zd2l0Y2gsIHA7CiAgICBTVEFDSzE2RlJBTUUgICAgICAgCWZyYW1lMTY7CiAgICBTVEFDSzMyRlJBTUUgICAgICAgCWZyYW1lMzI7CiAgICBjaGFyCQljaDsKICAgIENPTlRFWFQJCWN0eDsKICAgIERCR19USFJFQUQqCQl0aHJlYWQ7CgogICAgaW50IAkJY29weV9uZnJhbWUgPSAwOwogICAgaW50CQkJY29weV9jdXJyX2ZyYW1lID0gMDsKICAgIHN0cnVjdCBidF9pbmZvKiAJY29weV9mcmFtZXMgPSBOVUxMOwogICAgCiAgICBpZiAobm9pc3kpIERFQlVHX1ByaW50ZiggREJHX0NITl9NRVNHLCAiQmFja3RyYWNlOlxuIiApOwoKICAgIGlmICh0aWQgPT0gREVCVUdfQ3VyclRpZCkKICAgIHsKCSBjdHggPSBERUJVR19jb250ZXh0OwoJIHRocmVhZCA9IERFQlVHX0N1cnJUaHJlYWQ7CgoJIGlmIChmcmFtZXMpIERCR19mcmVlKCBmcmFtZXMgKTsKCSAvKiBmcmFtZXMgPSAoc3RydWN0IGJ0X2luZm8gKikgREJHX2FsbG9jKCBzaXplb2Yoc3RydWN0IGJ0X2luZm8pICk7ICovCiAgICB9CiAgICBlbHNlCiAgICB7CgkgdGhyZWFkID0gREVCVUdfR2V0VGhyZWFkKERFQlVHX0N1cnJQcm9jZXNzLCB0aWQpOwoKCSBpZiAoIXRocmVhZCkKCSB7CgkgICAgICBERUJVR19QcmludGYoIERCR19DSE5fTUVTRywgIlVua25vd24gdGhyZWFkIGlkICgweCUwOGx4KSBpbiBjdXJyZW50IHByb2Nlc3NcbiIsIHRpZCk7CgkgICAgICByZXR1cm47CgkgfQoJIG1lbXNldCgmY3R4LCAwLCBzaXplb2YoY3R4KSk7CgkgY3R4LkNvbnRleHRGbGFncyA9IENPTlRFWFRfQ09OVFJPTCB8IENPTlRFWFRfU0VHTUVOVFM7CgoJIGlmICggU3VzcGVuZFRocmVhZCggdGhyZWFkLT5oYW5kbGUgKSA9PSAtMSB8fAoJICAgICAgIUdldFRocmVhZENvbnRleHQoIHRocmVhZC0+aGFuZGxlLCAmY3R4ICkpCgkgewoJICAgICAgREVCVUdfUHJpbnRmKCBEQkdfQ0hOX01FU0csICJDYW4ndCBnZXQgY29udGV4dCBmb3IgdGhyZWFkIGlkICgweCUwOGx4KSBpbiBjdXJyZW50IHByb2Nlc3NcbiIsIHRpZCk7CgkgICAgICByZXR1cm47CgkgfQoJIC8qIG5lZWQgdG8gYXZvaWQgdHJhc2hpbmcgc3RhY2sgZnJhbWUgZm9yIGN1cnJlbnQgdGhyZWFkICovCgkgY29weV9uZnJhbWUgPSBuZnJhbWU7CgkgY29weV9mcmFtZXMgPSBmcmFtZXM7CgkgY29weV9jdXJyX2ZyYW1lID0gY3Vycl9mcmFtZTsKCSBjdXJyX2ZyYW1lID0gMDsKICAgIH0KCiAgICBuZnJhbWUgPSAwOwogICAgZnJhbWVzID0gTlVMTDsKCiAgICBjcyA9IGN0eC5TZWdDczsKICAgIHNzID0gY3R4LlNlZ1NzOwoKICAgIGlmIChERUJVR19Jc1NlbGVjdG9yU3lzdGVtKHNzKSkgc3MgPSAwOwogICAgaWYgKERFQlVHX0lzU2VsZWN0b3JTeXN0ZW0oY3MpKSBjcyA9IDA7CgogICAgLyogZmlyc3Qgc3RhY2sgZnJhbWUgZnJvbSByZWdpc3RlcnMgKi8KICAgIHN3aXRjaCAoREVCVUdfR2V0U2VsZWN0b3JUeXBlKHNzKSkKICAgIHsKICAgIGNhc2UgTU9ERV8zMjoKICAgICAgICBjb2RlLnNlZyA9IGNzOwogICAgICAgIGNvZGUub2ZmID0gY3R4LkVpcDsKICAgICAgICBhZGRyLnNlZyA9IHNzOwoJYWRkci5vZmYgPSBjdHguRWJwOwogICAgICAgIERFQlVHX0ZvcmNlRnJhbWUoICZhZGRyLCAmY29kZSwgZnJhbWVubywgTU9ERV8zMiwgbm9pc3ksIE5VTEwgKTsKICAgICAgICBpZiAoIShjb2RlLnNlZyB8fCBjb2RlLm9mZikpIHsKICAgICAgICAgICAgLyogdHJ5aW5nIHRvIGV4ZWN1dGUgYSBudWxsIHBvaW50ZXIuLi4geXVjay4uLgogICAgICAgICAgICAgKiBpZiBpdCB3YXMgYSBjYWxsIHRvIG51bGwsIHRoZSByZXR1cm4gRUlQIHNob3VsZCBiZQogICAgICAgICAgICAgKiBhdmFpbGFibGUgYXQgU1M6RVNQLCBzbyBsZXQncyB0cnkgdG8gcmV0cmlldmUgaXQgKi8KICAgICAgICAgICAgdG1wLnNlZyA9IHNzOwogICAgICAgICAgICB0bXAub2ZmID0gY3R4LkVzcDsKICAgICAgICAgICAgaWYgKERFQlVHX1JFQURfTUVNKCh2b2lkICopREVCVUdfVG9MaW5lYXIoJnRtcCksICZjb2RlLm9mZiwgc2l6ZW9mKGNvZGUub2ZmKSkpIHsKICAgICAgICAgICAgICAgIERFQlVHX0ZvcmNlRnJhbWUoICZhZGRyLCAmY29kZSwgKytmcmFtZW5vLCBNT0RFXzMyLCBub2lzeSwgIiwgbnVsbCBjYWxsIGFzc3VtZWQiICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaXMxNiA9IEZBTFNFOwoJYnJlYWs7CiAgICBjYXNlIE1PREVfMTY6CiAgICBjYXNlIE1PREVfVk04NjoKICAgICAgICBjb2RlLnNlZyA9IGNzOwogICAgICAgIGNvZGUub2ZmID0gTE9XT1JEKGN0eC5FaXApOwogICAgICAgIGFkZHIuc2VnID0gc3M7CglhZGRyLm9mZiA9IExPV09SRChjdHguRWJwKTsKICAgICAgICBERUJVR19Gb3JjZUZyYW1lKCAmYWRkciwgJmNvZGUsIGZyYW1lbm8sIE1PREVfMTYsIG5vaXN5LCBOVUxMICk7CiAgICAgICAgaXMxNiA9IFRSVUU7CglicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgaWYgKG5vaXN5KSBERUJVR19QcmludGYoIERCR19DSE5fTUVTRywgIkJhZCBzZWdtZW50ICcleCdcbiIsIHNzKTsKCXJldHVybjsKICAgIH0KCiAgICAvKiBjdXJfc3dpdGNoIGhvbGRzIGFkZHJlc3Mgb2YgY3Vycl9zdGFjaydzIGZpZWxkIGluIFRFQiBpbiBkZWJ1Z2dlZSAKICAgICAqIGFkZHJlc3Mgc3BhY2UgCiAgICAgKi8KICAgIGN1cl9zd2l0Y2ggPSAoRFdPUkQpdGhyZWFkLT50ZWIgKyBPRkZTRVRfT0YoVEVCLCBjdXJfc3RhY2spOwogICAgaWYgKCFERUJVR19SRUFEX01FTSgodm9pZCopY3VyX3N3aXRjaCwgJm5leHRfc3dpdGNoLCBzaXplb2YobmV4dF9zd2l0Y2gpKSkgewogICAgICAgIGlmIChub2lzeSkgREVCVUdfUHJpbnRmKCBEQkdfQ0hOX01FU0csICJDYW4ndCByZWFkIFRFQjpjdXJfc3RhY2tcbiIpOwoJcmV0dXJuOwogICAgfQoKICAgIGlmIChpczE2KSB7CiAgICAgICAgaWYgKCFERUJVR19SRUFEX01FTSgodm9pZCopbmV4dF9zd2l0Y2gsICZmcmFtZTMyLCBzaXplb2YoU1RBQ0szMkZSQU1FKSkpIHsKCSAgICBpZiAobm9pc3kpIERFQlVHX1ByaW50ZiggREJHX0NITl9NRVNHLCAiQmFkIHN0YWNrIGZyYW1lIDB4JTA4bHhcbiIsIAoJCQkJICAgICAodW5zaWduZWQgbG9uZykoU1RBQ0szMkZSQU1FKiluZXh0X3N3aXRjaCApOwoJICAgIHJldHVybjsKCX0KCWN1cl9zd2l0Y2ggPSAoRFdPUkQpZnJhbWUzMi5mcmFtZTE2OwoJc3dfYWRkci5zZWcgPSBTRUxFQ1RPUk9GKGN1cl9zd2l0Y2gpOwoJc3dfYWRkci5vZmYgPSBPRkZTRVRPRihjdXJfc3dpdGNoKTsKICAgIH0gZWxzZSB7CiAgICAgICAgdG1wLnNlZyA9IFNFTEVDVE9ST0YobmV4dF9zd2l0Y2gpOwoJdG1wLm9mZiA9IE9GRlNFVE9GKG5leHRfc3dpdGNoKTsKCXAgPSBERUJVR19Ub0xpbmVhcigmdG1wKTsKCQoJaWYgKCFERUJVR19SRUFEX01FTSgodm9pZCopcCwgJmZyYW1lMTYsIHNpemVvZihTVEFDSzE2RlJBTUUpKSkgewoJICAgIGlmIChub2lzeSkgREVCVUdfUHJpbnRmKCBEQkdfQ0hOX01FU0csICJCYWQgc3RhY2sgZnJhbWUgMHglMDhseFxuIiwgCgkJCQkgICAgICh1bnNpZ25lZCBsb25nKShTVEFDSzE2RlJBTUUqKXAgKTsKCSAgICByZXR1cm47Cgl9CgljdXJfc3dpdGNoID0gKERXT1JEKWZyYW1lMTYuZnJhbWUzMjsKCXN3X2FkZHIuc2VnID0gc3M7Cglzd19hZGRyLm9mZiA9IGN1cl9zd2l0Y2g7CiAgICB9CiAgICBpZiAoIURFQlVHX1JFQURfTUVNKCh2b2lkKilERUJVR19Ub0xpbmVhcigmc3dfYWRkciksICZjaCwgc2l6ZW9mKGNoKSkpIHsKICAgICAgICBzd19hZGRyLnNlZyA9IChEV09SRCktMTsKCXN3X2FkZHIub2ZmID0gKERXT1JEKS0xOwogICAgfQogICAgCiAgICBmb3IgKG9rID0gVFJVRTsgb2s7KSB7CiAgICAgICAgaWYgKChmcmFtZXNbZnJhbWVub10uc3MgPT0gc3dfYWRkci5zZWcpICYmCiAgICAgICAgICAgIHN3X2FkZHIub2ZmICYmIChmcmFtZXNbZnJhbWVub10uZWJwID49IHN3X2FkZHIub2ZmKSkKICAgICAgICB7CgkgICAvKiAxNjwtPjMyIHN3aXRjaC4uLgoJICAgICogeWVzLCBJIGtub3cgdGhpcyBpcyBjb25mdXNpbmcsIGl0IGdhdmUgbWUgYSBoZWFkYWNoZSB0b28gKi8KCSAgIGlmIChpczE2KSB7CgkgICAgICAKCSAgICAgICBpZiAoIURFQlVHX1JFQURfTUVNKCh2b2lkKiluZXh0X3N3aXRjaCwgJmZyYW1lMzIsIHNpemVvZihTVEFDSzMyRlJBTUUpKSkgewoJCSAgaWYgKG5vaXN5KSBERUJVR19QcmludGYoIERCR19DSE5fTUVTRywgIkJhZCBzdGFjayBmcmFtZSAweCUwOGx4XG4iLCAKCQkJCQkgICAodW5zaWduZWQgbG9uZykoU1RBQ0szMkZSQU1FKiluZXh0X3N3aXRjaCApOwoJCSAgcmV0dXJuOwoJICAgICAgIH0KCgkgICAgICAgY29kZS5zZWcgID0gMDsKCSAgICAgICBjb2RlLm9mZiAgPSBmcmFtZTMyLnJldGFkZHI7CgkgICAgICAgCgkgICAgICAgY3MgPSAwOwoJICAgICAgIGFkZHIuc2VnID0gMDsKCSAgICAgICBhZGRyLm9mZiA9IGZyYW1lMzIuZWJwOwoJICAgICAgIERFQlVHX0ZvcmNlRnJhbWUoICZhZGRyLCAmY29kZSwgKytmcmFtZW5vLCBNT0RFXzMyLCBub2lzeSwgTlVMTCApOwoJICAgICAgIAoJICAgICAgIG5leHRfc3dpdGNoID0gY3VyX3N3aXRjaDsKCSAgICAgICB0bXAuc2VnID0gU0VMRUNUT1JPRihuZXh0X3N3aXRjaCk7CgkgICAgICAgdG1wLm9mZiA9IE9GRlNFVE9GKG5leHRfc3dpdGNoKTsKCSAgICAgICBwID0gREVCVUdfVG9MaW5lYXIoJnRtcCk7CgkgICAgICAgCgkgICAgICAgaWYgKCFERUJVR19SRUFEX01FTSgodm9pZCopcCwgJmZyYW1lMTYsIHNpemVvZihTVEFDSzE2RlJBTUUpKSkgewoJCSAgIGlmIChub2lzeSkgREVCVUdfUHJpbnRmKCBEQkdfQ0hOX01FU0csICJCYWQgc3RhY2sgZnJhbWUgMHglMDhseFxuIiwgCgkJCQkJICAgICh1bnNpZ25lZCBsb25nKShTVEFDSzE2RlJBTUUqKXAgKTsKCQkgICByZXR1cm47CgkgICAgICAgfQoJICAgICAgIGN1cl9zd2l0Y2ggPSAoRFdPUkQpZnJhbWUxNi5mcmFtZTMyOwoJICAgICAgIHN3X2FkZHIuc2VnID0gMDsKCSAgICAgICBzd19hZGRyLm9mZiA9IGN1cl9zd2l0Y2g7CgkgICAgICAgCgkgICAgICAgaXMxNiA9IEZBTFNFOwoJICAgfSBlbHNlIHsKCSAgICAgIHRtcC5zZWcgPSBTRUxFQ1RPUk9GKG5leHRfc3dpdGNoKTsKCSAgICAgIHRtcC5vZmYgPSBPRkZTRVRPRihuZXh0X3N3aXRjaCk7CgkgICAgICBwID0gREVCVUdfVG9MaW5lYXIoJnRtcCk7CgkgICAgICAKCSAgICAgIGlmICghREVCVUdfUkVBRF9NRU0oKHZvaWQqKXAsICZmcmFtZTE2LCBzaXplb2YoU1RBQ0sxNkZSQU1FKSkpIHsKCQkgIGlmIChub2lzeSkgREVCVUdfUHJpbnRmKCBEQkdfQ0hOX01FU0csICJCYWQgc3RhY2sgZnJhbWUgMHglMDhseFxuIiwKCQkJCQkgICAodW5zaWduZWQgbG9uZykoU1RBQ0sxNkZSQU1FKilwICk7CgkJICByZXR1cm47CgkgICAgICB9CgkgICAgICAKCSAgICAgIGNvZGUuc2VnICA9IGZyYW1lMTYuY3M7CgkgICAgICBjb2RlLm9mZiAgPSBmcmFtZTE2LmlwOwoJICAgICAgCgkgICAgICBjcyA9IGZyYW1lMTYuY3M7CgkgICAgICBhZGRyLnNlZyA9IFNFTEVDVE9ST0YobmV4dF9zd2l0Y2gpOwoJICAgICAgYWRkci5vZmYgPSBmcmFtZTE2LmJwOwoJICAgICAgREVCVUdfRm9yY2VGcmFtZSggJmFkZHIsICZjb2RlLCArK2ZyYW1lbm8sIE1PREVfMTYsIG5vaXN5LCBOVUxMICk7CgkgICAgICAKCSAgICAgIG5leHRfc3dpdGNoID0gY3VyX3N3aXRjaDsKCSAgICAgIGlmICghREVCVUdfUkVBRF9NRU0oKHZvaWQqKW5leHRfc3dpdGNoLCAmZnJhbWUzMiwgc2l6ZW9mKFNUQUNLMzJGUkFNRSkpKSB7CgkJIGlmIChub2lzeSkgREVCVUdfUHJpbnRmKCBEQkdfQ0hOX01FU0csICJCYWQgc3RhY2sgZnJhbWUgMHglMDhseFxuIiwgCgkJCQkJICAodW5zaWduZWQgbG9uZykoU1RBQ0szMkZSQU1FKiluZXh0X3N3aXRjaCApOwoJCSByZXR1cm47CgkgICAgICB9CgkgICAgICBjdXJfc3dpdGNoID0gKERXT1JEKWZyYW1lMzIuZnJhbWUxNjsKCSAgICAgIHN3X2FkZHIuc2VnID0gU0VMRUNUT1JPRihjdXJfc3dpdGNoKTsKCSAgICAgIHN3X2FkZHIub2ZmID0gT0ZGU0VUT0YoY3VyX3N3aXRjaCk7CgkgICAgICAKCSAgICAgIGlzMTYgPSBUUlVFOwoJICAgfQoJICAgaWYgKCFERUJVR19SRUFEX01FTSgodm9pZCopREVCVUdfVG9MaW5lYXIoJnN3X2FkZHIpLCAmY2gsIHNpemVvZihjaCkpKSB7CgkgICAgICBzd19hZGRyLnNlZyA9IChEV09SRCktMTsKCSAgICAgIHN3X2FkZHIub2ZmID0gKERXT1JEKS0xOwoJICAgfQoJfSBlbHNlIHsKCSAgICAvKiBvcmRpbmFyeSBzdGFjayBmcmFtZSAqLwoJICAgb2sgPSBpczE2ID8gREVCVUdfRnJhbWUxNiggdGhyZWFkLCAmYWRkciwgJmNzLCArK2ZyYW1lbm8sIG5vaXN5KQoJICAgICAgOiBERUJVR19GcmFtZTMyKCAmYWRkciwgJmNzLCArK2ZyYW1lbm8sIG5vaXN5KTsKCX0KICAgIH0KICAgIGlmIChub2lzeSkgREVCVUdfUHJpbnRmKCBEQkdfQ0hOX01FU0csICJcbiIgKTsKCiAgICBpZiAodGlkICE9IERFQlVHX0N1cnJUaWQpCiAgICB7CgkgUmVzdW1lVGhyZWFkKCB0aHJlYWQtPmhhbmRsZSApOwoJIC8qIHJlc3RvcmUgc3RhY2sgZnJhbWUgZm9yIGN1cnJlbnQgdGhyZWFkICovCgkgaWYgKGZyYW1lcykgREJHX2ZyZWUoIGZyYW1lcyApOwoJIGZyYW1lcyA9IGNvcHlfZnJhbWVzOwoJIG5mcmFtZSA9IGNvcHlfbmZyYW1lOwoJIGN1cnJfZnJhbWUgPSBjb3B5X2N1cnJfZnJhbWU7CiAgICB9CiNlbmRpZgp9CgppbnQKREVCVUdfU2V0RnJhbWUoaW50IG5ld2ZyYW1lKQp7CiNpZmRlZiBfX2kzODZfXwogIGludAkJcnRuID0gRkFMU0U7CgogIGN1cnJfZnJhbWUgPSBuZXdmcmFtZTsKCiAgaWYoIGN1cnJfZnJhbWUgPj0gbmZyYW1lICkKICAgIHsKICAgICAgY3Vycl9mcmFtZSA9IG5mcmFtZSAtIDE7CiAgICB9CgogIGlmKCBjdXJyX2ZyYW1lIDwgMCApCiAgICB7CiAgICAgIGN1cnJfZnJhbWUgPSAwOwogICAgfQoKICAgaWYoIGZyYW1lcyAmJiBmcmFtZXNbY3Vycl9mcmFtZV0uZnJhbWUubGlzdC5zb3VyY2VmaWxlICE9IE5VTEwgKQogICAgewogICAgICBERUJVR19MaXN0KCZmcmFtZXNbY3Vycl9mcmFtZV0uZnJhbWUubGlzdCwgTlVMTCwgMCk7CiAgICB9CgogIHJ0biA9IFRSVUU7CiAgcmV0dXJuIChydG4pOwojZWxzZSAvKiBfX2kzODZfXyAqLwogIHJldHVybiBGQUxTRTsKI2VuZGlmIC8qIF9faTM4Nl9fICovCn0KCmludApERUJVR19HZXRDdXJyZW50RnJhbWUoc3RydWN0IG5hbWVfaGFzaCAqKiBuYW1lLCB1bnNpZ25lZCBpbnQgKiBlaXAsCgkJICAgICAgdW5zaWduZWQgaW50ICogZWJwKQp7CiNpZmRlZiBfX2kzODZfXwogIC8qCiAgICogSWYgd2UgZG9uJ3QgaGF2ZSBhIHZhbGlkIGJhY2t0cmFjZSwgdGhlbiBqdXN0IHJldHVybi4KICAgKi8KICBpZiggZnJhbWVzID09IE5VTEwgKQogICAgewogICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogIC8qCiAgICogSWYgd2UgZG9uJ3Qga25vdyB3aGF0IHRoZSBjdXJyZW50IGZ1bmN0aW9uIGlzLCB0aGVuIHdlIGFsc28gaGF2ZQogICAqIG5vdGhpbmcgdG8gcmVwb3J0IGhlcmUuCiAgICovCiAgaWYoIGZyYW1lc1tjdXJyX2ZyYW1lXS5mcmFtZS5zeW0gPT0gTlVMTCApCiAgICB7CiAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgKm5hbWUgPSBmcmFtZXNbY3Vycl9mcmFtZV0uZnJhbWUuc3ltOwogICplaXAgPSBmcmFtZXNbY3Vycl9mcmFtZV0uZWlwOwogICplYnAgPSBmcmFtZXNbY3Vycl9mcmFtZV0uZWJwOwoKICByZXR1cm4gVFJVRTsKI2Vsc2UgLyogX19pMzg2X18gKi8KICByZXR1cm4gRkFMU0U7CiNlbmRpZiAvKiBfX2kzODZfXyAqLwp9Cgo=