LyoKICogRGVidWdnZXIgc3RhY2sgaGFuZGxpbmcKICoKICogQ29weXJpZ2h0IDE5OTUgQWxleGFuZHJlIEp1bGxpYXJkCiAqIENvcHlyaWdodCAxOTk2IEVyaWMgWW91bmdkYWxlCiAqIENvcHlyaWdodCAxOTk5IE92ZSBL5XZlbgogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKCiNpbmNsdWRlIDxzdGRsaWIuaD4KCiNpbmNsdWRlICJkZWJ1Z2dlci5oIgojaW5jbHVkZSAic3RhY2tmcmFtZS5oIgojaW5jbHVkZSAid2luYmFzZS5oIgoKI2lmZGVmIF9faTM4Nl9fCi8qCiAqIFdlIGtlZXAgdGhpcyBpbmZvIGZvciBlYWNoIGZyYW1lLCBzbyB0aGF0IHdlIGNhbgogKiBmaW5kIGxvY2FsIHZhcmlhYmxlIGluZm9ybWF0aW9uIGNvcnJlY3RseS4KICovCnN0cnVjdCBidF9pbmZvCnsKICB1bnNpZ25lZCBpbnQJICAgICBjczsKICB1bnNpZ25lZCBpbnQJICAgICBlaXA7CiAgdW5zaWduZWQgaW50CSAgICAgc3M7CiAgdW5zaWduZWQgaW50CSAgICAgZWJwOwogIHN0cnVjdCBzeW1ib2xfaW5mbyBmcmFtZTsKfTsKCnN0YXRpYyBpbnQgbmZyYW1lOwpzdGF0aWMgc3RydWN0IGJ0X2luZm8gKiBmcmFtZXMgPSBOVUxMOwppbnQgY3Vycl9mcmFtZTsKCnR5cGVkZWYgc3RydWN0CnsKICAgIFdPUkQgYnA7CiAgICBXT1JEIGlwOwogICAgV09SRCBjczsKfSBGUkFNRTE2OwoKdHlwZWRlZiBzdHJ1Y3QKewogICAgRFdPUkQgYnA7CiAgICBEV09SRCBpcDsKICAgIFdPUkQgY3M7Cn0gRlJBTUUzMjsKI2VuZGlmCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBERUJVR19JbmZvU3RhY2sKICoKICogRHVtcCB0aGUgdG9wIG9mIHRoZSBzdGFjawogKi8Kdm9pZCBERUJVR19JbmZvU3RhY2sodm9pZCkKewojaWZkZWYgX19pMzg2X18KICAgIERCR19WQUxVRQl2YWx1ZTsKICAgIAogICAgdmFsdWUudHlwZSA9IE5VTEw7CiAgICB2YWx1ZS5jb29raWUgPSBEVl9UQVJHRVQ7CiAgICB2YWx1ZS5hZGRyLnNlZyA9IERFQlVHX2NvbnRleHQuU2VnU3M7CiAgICB2YWx1ZS5hZGRyLm9mZiA9IERFQlVHX2NvbnRleHQuRXNwOwoKICAgIERFQlVHX1ByaW50ZihEQkdfQ0hOX01FU0csIlN0YWNrIGR1bXA6XG4iKTsKICAgIHN3aXRjaCAoREVCVUdfR2V0U2VsZWN0b3JUeXBlKHZhbHVlLmFkZHIuc2VnKSkgewogICAgY2FzZSAzMjogLyogMzItYml0IG1vZGUgKi8KICAgICAgIERFQlVHX0V4YW1pbmVNZW1vcnkoICZ2YWx1ZSwgMjQsICd4JyApOwogICAgICAgYnJlYWs7CiAgICBjYXNlIDE2OiAgLyogMTYtYml0IG1vZGUgKi8KICAgICAgICB2YWx1ZS5hZGRyLm9mZiAmPSAweGZmZmY7CiAgICAgICAgREVCVUdfRXhhbWluZU1lbW9yeSggJnZhbHVlLCAyNCwgJ3cnICk7CglicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICBERUJVR19QcmludGYoREJHX0NITl9NRVNHLCAiQmFkIHNlZ21lbnQgKCVsZClcbiIsIHZhbHVlLmFkZHIuc2VnKTsKICAgIH0KICAgIERFQlVHX1ByaW50ZihEQkdfQ0hOX01FU0csIlxuIik7CiNlbmRpZgp9CgojaWZkZWYgX19pMzg2X18Kc3RhdGljIHZvaWQgREVCVUdfRm9yY2VGcmFtZShEQkdfQUREUiAqc3RhY2ssIERCR19BRERSICpjb2RlLCBpbnQgZnJhbWVubywgaW50IGJpdHMsIGludCBub2lzeSkKewogICAgaW50IHRoZWZyYW1lID0gbmZyYW1lKys7CiAgICBmcmFtZXMgPSAoc3RydWN0IGJ0X2luZm8gKilEQkdfcmVhbGxvYyhmcmFtZXMsCgkJCQkJICAgbmZyYW1lKnNpemVvZihzdHJ1Y3QgYnRfaW5mbykpOwogICAgaWYgKG5vaXN5KQogICAgICBERUJVR19QcmludGYoREJHX0NITl9NRVNHLCIlcyVkICIsICh0aGVmcmFtZSA9PSBjdXJyX2ZyYW1lID8gIj0+IiA6ICIgICIpLAogICAgICAgICAgICAgIGZyYW1lbm8pOwogICAgZnJhbWVzW3RoZWZyYW1lXS5jcyA9IGNvZGUtPnNlZzsKICAgIGZyYW1lc1t0aGVmcmFtZV0uZWlwID0gY29kZS0+b2ZmOwogICAgaWYgKG5vaXN5KQogICAgICBmcmFtZXNbdGhlZnJhbWVdLmZyYW1lID0gREVCVUdfUHJpbnRBZGRyZXNzQW5kQXJncyggY29kZSwgYml0cywgCgkJCQkJCQkgIHN0YWNrLT5vZmYsIFRSVUUgKTsKICAgIGVsc2UKICAgICAgREVCVUdfRmluZE5lYXJlc3RTeW1ib2woIGNvZGUsIFRSVUUsIAoJCQkgICAgICAgJmZyYW1lc1t0aGVmcmFtZV0uZnJhbWUuc3ltLCBzdGFjay0+b2ZmLCAKCQkJICAgICAgICZmcmFtZXNbdGhlZnJhbWVdLmZyYW1lLmxpc3QpOwogICAgZnJhbWVzW3RoZWZyYW1lXS5zcyA9IHN0YWNrLT5zZWc7CiAgICBmcmFtZXNbdGhlZnJhbWVdLmVicCA9IHN0YWNrLT5vZmY7CiAgICBpZiAobm9pc3kpIHsKICAgICAgREVCVUdfUHJpbnRmKCBEQkdfQ0hOX01FU0csIChiaXRzID09IDE2KSA/ICIgKGJwPSUwNGx4KVxuIiA6ICIgKGVicD0lMDhseClcbiIsIHN0YWNrLT5vZmYgKTsKICAgIH0KfQoKc3RhdGljIEJPT0wgREVCVUdfRnJhbWUxNihEQkdfQUREUiAqYWRkciwgdW5zaWduZWQgaW50ICpjcywgaW50IGZyYW1lbm8sIGludCBub2lzeSkKewogICAgdW5zaWduZWQgaW50CXNzID0gYWRkci0+c2VnLCBwb3NzaWJsZV9jcyA9IDA7CiAgICBGUkFNRTE2IAkJZnJhbWU7CiAgICBpbnQgCQl0aGVmcmFtZSA9IG5mcmFtZTsKICAgIHZvaWQqCQlwID0gKHZvaWQqKURFQlVHX1RvTGluZWFyKGFkZHIpOwogICAgCiAgICBpZiAoIXApIHJldHVybiBGQUxTRTsKICAgIAogICAgaWYgKCFERUJVR19SRUFEX01FTShwLCAmZnJhbWUsIHNpemVvZihmcmFtZSkpKSB7CiAgICAgICAgaWYgKG5vaXN5KSBERUJVR19JbnZhbEFkZHIoYWRkcik7CglyZXR1cm4gRkFMU0U7CiAgICB9CiAgICBpZiAoIWZyYW1lLmJwKSByZXR1cm4gRkFMU0U7CiAgICBuZnJhbWUrKzsKICAgIGZyYW1lcyA9IChzdHJ1Y3QgYnRfaW5mbyAqKURCR19yZWFsbG9jKGZyYW1lcywKCQkJCQkgICBuZnJhbWUqc2l6ZW9mKHN0cnVjdCBidF9pbmZvKSk7CiAgICBpZiAobm9pc3kpCiAgICAgICAgREVCVUdfUHJpbnRmKERCR19DSE5fTUVTRywiJXMlZCAiLCAodGhlZnJhbWUgPT0gY3Vycl9mcmFtZSA/ICI9PiIgOiAiICAiKSwKCQkgICAgIGZyYW1lbm8pOwogICAgaWYgKGZyYW1lLmJwICYgMSkgKmNzID0gZnJhbWUuY3M7CiAgICBlbHNlIHsKICAgICAgICAvKiBub3QgZXhwbGljaXRseSBtYXJrZWQgYXMgZmFyIGNhbGwsCgkgKiBidXQgY2hlY2sgd2hldGhlciBpdCBjb3VsZCBiZSBhbnl3YXkgKi8KICAgICAgICBpZiAoKChmcmFtZS5jcyY3KT09NykgJiYgKGZyYW1lLmNzICE9ICpjcykpIHsKCSAgICBMRFRfRU5UUlkJbGU7CgkgCgkgICAgaWYgKEdldFRocmVhZFNlbGVjdG9yRW50cnkoIERFQlVHX0N1cnJUaHJlYWQtPmhhbmRsZSwgZnJhbWUuY3MsICZsZSkgJiYKCQkobGUuSGlnaFdvcmQuQml0cy5UeXBlICYgMHgwOCkpIHsgLyogY29kZSBzZWdtZW50ICovCgkgICAgICAgIC8qIGl0IGlzIHZlcnkgdW5jb21tb24gdG8gcHVzaCBhIGNvZGUgc2VnbWVudCBjcyBhcwoJCSAqIGEgcGFyYW1ldGVyLCBzbyB0aGlzIHNob3VsZCB3b3JrIGluIG1vc3QgY2FzZXMgKi8KCSAgICAgICAgKmNzID0gcG9zc2libGVfY3MgPSBmcmFtZS5jczsKCSAgICB9Cgl9CiAgICB9CiAgICBmcmFtZXNbdGhlZnJhbWVdLmNzID0gYWRkci0+c2VnID0gKmNzOwogICAgZnJhbWVzW3RoZWZyYW1lXS5laXAgPSBhZGRyLT5vZmYgPSBmcmFtZS5pcDsKICAgIGlmIChub2lzeSkKICAgICAgICBmcmFtZXNbdGhlZnJhbWVdLmZyYW1lID0gREVCVUdfUHJpbnRBZGRyZXNzQW5kQXJncyggYWRkciwgMTYsIAoJCQkJCQkJICAgIGZyYW1lLmJwLCBUUlVFICk7CiAgICBlbHNlCiAgICAgICAgREVCVUdfRmluZE5lYXJlc3RTeW1ib2woIGFkZHIsIFRSVUUsIAoJCQkJICZmcmFtZXNbdGhlZnJhbWVdLmZyYW1lLnN5bSwgZnJhbWUuYnAsIAoJCQkJICZmcmFtZXNbdGhlZnJhbWVdLmZyYW1lLmxpc3QpOwogICAgZnJhbWVzW3RoZWZyYW1lXS5zcyA9IGFkZHItPnNlZyA9IHNzOwogICAgZnJhbWVzW3RoZWZyYW1lXS5lYnAgPSBhZGRyLT5vZmYgPSBmcmFtZS5icCAmIH4xOwogICAgaWYgKG5vaXN5KSB7CiAgICAgICAgREVCVUdfUHJpbnRmKCBEQkdfQ0hOX01FU0csICIgKGJwPSUwNGx4IiwgYWRkci0+b2ZmICk7CiAgICAgICAgaWYgKHBvc3NpYmxlX2NzKSB7CgkgICAgREVCVUdfUHJpbnRmKCBEQkdfQ0hOX01FU0csICIsIGZhciBjYWxsIGFzc3VtZWQiICk7Cgl9CglERUJVR19QcmludGYoIERCR19DSE5fTUVTRywgIilcbiIgKTsKICAgIH0KICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgQk9PTCBERUJVR19GcmFtZTMyKERCR19BRERSICphZGRyLCB1bnNpZ25lZCBpbnQgKmNzLCBpbnQgZnJhbWVubywgaW50IG5vaXN5KQp7CiAgICB1bnNpZ25lZCBpbnQgCXNzID0gYWRkci0+c2VnOwogICAgRlJBTUUzMiAJCWZyYW1lOwogICAgaW50IAkJdGhlZnJhbWUgPSBuZnJhbWU7CiAgICB2b2lkKgkJcCA9ICh2b2lkKilERUJVR19Ub0xpbmVhcihhZGRyKTsKICAgIAogICAgaWYgKCFwKSByZXR1cm4gRkFMU0U7CiAgICAKICAgIGlmICghREVCVUdfUkVBRF9NRU0ocCwgJmZyYW1lLCBzaXplb2YoZnJhbWUpKSkgewogICAgICAgaWYgKG5vaXN5KSBERUJVR19JbnZhbEFkZHIoYWRkcik7CiAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CiAgICBpZiAoIWZyYW1lLmlwKSByZXR1cm4gRkFMU0U7CiAgICAKICAgIG5mcmFtZSsrOwogICAgZnJhbWVzID0gKHN0cnVjdCBidF9pbmZvICopREJHX3JlYWxsb2MoZnJhbWVzLAoJCQkJCSAgIG5mcmFtZSpzaXplb2Yoc3RydWN0IGJ0X2luZm8pKTsKICAgIGlmIChub2lzeSkKICAgICAgIERFQlVHX1ByaW50ZihEQkdfQ0hOX01FU0csIiVzJWQgIiwgKHRoZWZyYW1lID09IGN1cnJfZnJhbWUgPyAiPT4iIDogIiAgIiksCgkJICAgIGZyYW1lbm8pOwogICAgZnJhbWVzW3RoZWZyYW1lXS5jcyA9IGFkZHItPnNlZyA9ICpjczsKICAgIGZyYW1lc1t0aGVmcmFtZV0uZWlwID0gYWRkci0+b2ZmID0gZnJhbWUuaXA7CiAgICBpZiAobm9pc3kpCiAgICAgICAgZnJhbWVzW3RoZWZyYW1lXS5mcmFtZSA9IERFQlVHX1ByaW50QWRkcmVzc0FuZEFyZ3MoIGFkZHIsIDMyLCAKCQkJCQkJCSAgICBmcmFtZS5icCwgVFJVRSApOwogICAgZWxzZQogICAgICAgIERFQlVHX0ZpbmROZWFyZXN0U3ltYm9sKCBhZGRyLCBUUlVFLCAKCQkJCSAmZnJhbWVzW3RoZWZyYW1lXS5mcmFtZS5zeW0sIGZyYW1lLmJwLCAKCQkJCSAmZnJhbWVzW3RoZWZyYW1lXS5mcmFtZS5saXN0KTsKICAgIGlmIChub2lzeSkgREVCVUdfUHJpbnRmKCBEQkdfQ0hOX01FU0csICIgKGVicD0lMDhseClcbiIsIGZyYW1lLmJwICk7CiAgICBmcmFtZXNbdGhlZnJhbWVdLnNzID0gYWRkci0+c2VnID0gc3M7CiAgICBmcmFtZXNbdGhlZnJhbWVdLmVicCA9IGZyYW1lLmJwOwogICAgaWYgKGFkZHItPm9mZiA9PSBmcmFtZS5icCkgcmV0dXJuIEZBTFNFOwogICAgYWRkci0+b2ZmID0gZnJhbWUuYnA7CiAgICByZXR1cm4gVFJVRTsKfQojZW5kaWYKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIERFQlVHX0JhY2tUcmFjZQogKgogKiBEaXNwbGF5IGEgc3RhY2sgYmFjay10cmFjZS4KICovCnZvaWQgREVCVUdfQmFja1RyYWNlKEJPT0wgbm9pc3kpCnsKI2lmZGVmIF9faTM4NgogICAgREJHX0FERFIgCQlhZGRyLCBzd19hZGRyLCBjb2RlLCB0bXA7CiAgICB1bnNpZ25lZCBpbnQgCXNzID0gREVCVUdfY29udGV4dC5TZWdTczsKICAgIHVuc2lnbmVkIGludAljcyA9IERFQlVHX2NvbnRleHQuU2VnQ3M7CiAgICBpbnQgCQlmcmFtZW5vID0gMCwgaXMxNiwgb2s7CiAgICBEV09SRCAJCW5leHRfc3dpdGNoLCBjdXJfc3dpdGNoLCBwOwogICAgU1RBQ0sxNkZSQU1FICAgICAgIAlmcmFtZTE2OwogICAgU1RBQ0szMkZSQU1FICAgICAgIAlmcmFtZTMyOwogICAgY2hhcgkJY2g7CgogICAgaWYgKG5vaXN5KSBERUJVR19QcmludGYoIERCR19DSE5fTUVTRywgIkJhY2t0cmFjZTpcbiIgKTsKCiAgICBuZnJhbWUgPSAxOwogICAgaWYgKGZyYW1lcykgREJHX2ZyZWUoIGZyYW1lcyApOwogICAgZnJhbWVzID0gKHN0cnVjdCBidF9pbmZvICopIERCR19hbGxvYyggc2l6ZW9mKHN0cnVjdCBidF9pbmZvKSApOwogICAgaWYgKG5vaXN5KQogICAgICAgIERFQlVHX1ByaW50ZihEQkdfQ0hOX01FU0csIiVzJWQgIiwoY3Vycl9mcmFtZSA9PSAwID8gIj0+IiA6ICIgICIpLCBmcmFtZW5vKTsKCiAgICBpZiAoREVCVUdfSXNTZWxlY3RvclN5c3RlbShzcykpIHNzID0gMDsKICAgIGlmIChERUJVR19Jc1NlbGVjdG9yU3lzdGVtKGNzKSkgY3MgPSAwOwoKICAgIC8qIGZpcnN0IHN0YWNrIGZyYW1lIGZyb20gcmVnaXN0ZXJzICovCiAgICBzd2l0Y2ggKERFQlVHX0dldFNlbGVjdG9yVHlwZShzcykpCiAgICB7CiAgICBjYXNlIDMyOgogICAgICAgIGZyYW1lc1swXS5jcyA9IGFkZHIuc2VnID0gY3M7CiAgICAgICAgZnJhbWVzWzBdLmVpcCA9IGFkZHIub2ZmID0gREVCVUdfY29udGV4dC5FaXA7CiAgICAgICAgaWYgKG5vaXN5KQogICAgICAgICAgICBmcmFtZXNbMF0uZnJhbWUgPSBERUJVR19QcmludEFkZHJlc3MoICZhZGRyLCAzMiwgVFJVRSApOwogICAgICAgIGVsc2UKCSAgICBERUJVR19GaW5kTmVhcmVzdFN5bWJvbCggJmFkZHIsIFRSVUUsICZmcmFtZXNbMF0uZnJhbWUuc3ltLCAwLCAKCQkJCSAgICAgJmZyYW1lc1swXS5mcmFtZS5saXN0KTsKICAgICAgICBmcmFtZXNbMF0uc3MgPSBhZGRyLnNlZyA9IHNzOwoJZnJhbWVzWzBdLmVicCA9IGFkZHIub2ZmID0gREVCVUdfY29udGV4dC5FYnA7CiAgICAgICAgaWYgKG5vaXN5KSBERUJVR19QcmludGYoIERCR19DSE5fTUVTRywgIiAoZWJwPSUwOHgpXG4iLCBmcmFtZXNbMF0uZWJwICk7CiAgICAgICAgaXMxNiA9IEZBTFNFOwoJYnJlYWs7CiAgICBjYXNlIDE2OgogICAgICAgIGZyYW1lc1swXS5jcyA9IGFkZHIuc2VnID0gY3M7CiAgICAgICAgZnJhbWVzWzBdLmVpcCA9IGFkZHIub2ZmID0gTE9XT1JEKERFQlVHX2NvbnRleHQuRWlwKTsKICAgICAgICBpZiAobm9pc3kpCgkgICAgZnJhbWVzWzBdLmZyYW1lID0gREVCVUdfUHJpbnRBZGRyZXNzKCAmYWRkciwgMTYsIFRSVUUgKTsKICAgICAgICBlbHNlCgkgICAgREVCVUdfRmluZE5lYXJlc3RTeW1ib2woICZhZGRyLCBUUlVFLCAmZnJhbWVzWzBdLmZyYW1lLnN5bSwgMCwgCgkJCQkgICAgICZmcmFtZXNbMF0uZnJhbWUubGlzdCk7CiAgICAgICAgZnJhbWVzWzBdLnNzID0gYWRkci5zZWcgPSBzczsKCWZyYW1lc1swXS5lYnAgPSBhZGRyLm9mZiA9IExPV09SRChERUJVR19jb250ZXh0LkVicCk7CiAgICAgICAgaWYgKG5vaXN5KSBERUJVR19QcmludGYoIERCR19DSE5fTUVTRywgIiAoYnA9JTA0eClcbiIsIGZyYW1lc1swXS5lYnAgKTsKICAgICAgICBpczE2ID0gVFJVRTsKCWJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBpZiAobm9pc3kpIERFQlVHX1ByaW50ZiggREJHX0NITl9NRVNHLCAiQmFkIHNlZ21lbnQgJyV1J1xuIiwgc3MpOwoJcmV0dXJuOwogICAgfQoKICAgIC8qIGN1cl9zd2l0Y2ggaG9sZHMgYWRkcmVzcyBvZiBjdXJyX3N0YWNrJ3MgZmllbGQgaW4gVEVCIGluIGRlYnVnZ2VlIAogICAgICogYWRkcmVzcyBzcGFjZSAKICAgICAqLwogICAgY3VyX3N3aXRjaCA9IChEV09SRClERUJVR19DdXJyVGhyZWFkLT50ZWIgKyBPRkZTRVRfT0YoVEVCLCBjdXJfc3RhY2spOwogICAgaWYgKCFERUJVR19SRUFEX01FTSgodm9pZCopY3VyX3N3aXRjaCwgJm5leHRfc3dpdGNoLCBzaXplb2YobmV4dF9zd2l0Y2gpKSkgewogICAgICAgIGlmIChub2lzeSkgREVCVUdfUHJpbnRmKCBEQkdfQ0hOX01FU0csICJDYW4ndCByZWFkIFRFQjpjdXJfc3RhY2tcbiIpOwoJcmV0dXJuOwogICAgfQoKICAgIGlmIChpczE2KSB7CiAgICAgICAgaWYgKCFERUJVR19SRUFEX01FTSgodm9pZCopbmV4dF9zd2l0Y2gsICZmcmFtZTMyLCBzaXplb2YoU1RBQ0szMkZSQU1FKSkpIHsKCSAgICBpZiAobm9pc3kpIERFQlVHX1ByaW50ZiggREJHX0NITl9NRVNHLCAiQmFkIHN0YWNrIGZyYW1lIDB4JTA4bHhcbiIsIAoJCQkJICAgICAodW5zaWduZWQgbG9uZykoU1RBQ0szMkZSQU1FKiluZXh0X3N3aXRjaCApOwoJICAgIHJldHVybjsKCX0KCWN1cl9zd2l0Y2ggPSAoRFdPUkQpZnJhbWUzMi5mcmFtZTE2OwoJc3dfYWRkci5zZWcgPSBTRUxFQ1RPUk9GKGN1cl9zd2l0Y2gpOwoJc3dfYWRkci5vZmYgPSBPRkZTRVRPRihjdXJfc3dpdGNoKTsKICAgIH0gZWxzZSB7CiAgICAgICAgdG1wLnNlZyA9IFNFTEVDVE9ST0YobmV4dF9zd2l0Y2gpOwoJdG1wLm9mZiA9IE9GRlNFVE9GKG5leHRfc3dpdGNoKTsKCXAgPSBERUJVR19Ub0xpbmVhcigmdG1wKTsKCQoJaWYgKCFERUJVR19SRUFEX01FTSgodm9pZCopcCwgJmZyYW1lMTYsIHNpemVvZihTVEFDSzE2RlJBTUUpKSkgewoJICAgIGlmIChub2lzeSkgREVCVUdfUHJpbnRmKCBEQkdfQ0hOX01FU0csICJCYWQgc3RhY2sgZnJhbWUgMHglMDhseFxuIiwgCgkJCQkgICAgICh1bnNpZ25lZCBsb25nKShTVEFDSzE2RlJBTUUqKXAgKTsKCSAgICByZXR1cm47Cgl9CgljdXJfc3dpdGNoID0gKERXT1JEKWZyYW1lMTYuZnJhbWUzMjsKCXN3X2FkZHIuc2VnID0gc3M7Cglzd19hZGRyLm9mZiA9IGN1cl9zd2l0Y2g7CiAgICB9CiAgICBpZiAoIURFQlVHX1JFQURfTUVNKCh2b2lkKilERUJVR19Ub0xpbmVhcigmc3dfYWRkciksICZjaCwgc2l6ZW9mKGNoKSkpIHsKICAgICAgICBzd19hZGRyLnNlZyA9IChEV09SRCktMTsKCXN3X2FkZHIub2ZmID0gKERXT1JEKS0xOwogICAgfQogICAgCiAgICBmb3IgKG9rID0gVFJVRTsgb2s7KSB7CiAgICAgICAgaWYgKChmcmFtZXNbZnJhbWVub10uc3MgPT0gc3dfYWRkci5zZWcpICYmCgkgICAgKGZyYW1lc1tmcmFtZW5vXS5lYnAgPj0gc3dfYWRkci5vZmYpKSB7CgkgICAvKiAxNjwtPjMyIHN3aXRjaC4uLgoJICAgICogeWVzLCBJIGtub3cgdGhpcyBpcyBjb25mdXNpbmcsIGl0IGdhdmUgbWUgYSBoZWFkYWNoZSB0b28gKi8KCSAgIGlmIChpczE2KSB7CgkgICAgICAKCSAgICAgICBpZiAoIURFQlVHX1JFQURfTUVNKCh2b2lkKiluZXh0X3N3aXRjaCwgJmZyYW1lMzIsIHNpemVvZihTVEFDSzMyRlJBTUUpKSkgewoJCSAgaWYgKG5vaXN5KSBERUJVR19QcmludGYoIERCR19DSE5fTUVTRywgIkJhZCBzdGFjayBmcmFtZSAweCUwOGx4XG4iLCAKCQkJCQkgICAodW5zaWduZWQgbG9uZykoU1RBQ0szMkZSQU1FKiluZXh0X3N3aXRjaCApOwoJCSAgcmV0dXJuOwoJICAgICAgIH0KCgkgICAgICAgY29kZS5zZWcgID0gMDsKCSAgICAgICBjb2RlLm9mZiAgPSBmcmFtZTMyLnJldGFkZHI7CgkgICAgICAgCgkgICAgICAgY3MgPSAwOwoJICAgICAgIGFkZHIuc2VnID0gMDsKCSAgICAgICBhZGRyLm9mZiA9IGZyYW1lMzIuZWJwOwoJICAgICAgIERFQlVHX0ZvcmNlRnJhbWUoICZhZGRyLCAmY29kZSwgKytmcmFtZW5vLCAzMiwgbm9pc3kgKTsKCSAgICAgICAKCSAgICAgICBuZXh0X3N3aXRjaCA9IGN1cl9zd2l0Y2g7CgkgICAgICAgdG1wLnNlZyA9IFNFTEVDVE9ST0YobmV4dF9zd2l0Y2gpOwoJICAgICAgIHRtcC5vZmYgPSBPRkZTRVRPRihuZXh0X3N3aXRjaCk7CgkgICAgICAgcCA9IERFQlVHX1RvTGluZWFyKCZ0bXApOwoJICAgICAgIAoJICAgICAgIGlmICghREVCVUdfUkVBRF9NRU0oKHZvaWQqKXAsICZmcmFtZTE2LCBzaXplb2YoU1RBQ0sxNkZSQU1FKSkpIHsKCQkgICBpZiAobm9pc3kpIERFQlVHX1ByaW50ZiggREJHX0NITl9NRVNHLCAiQmFkIHN0YWNrIGZyYW1lIDB4JTA4bHhcbiIsIAoJCQkJCSAgICAodW5zaWduZWQgbG9uZykoU1RBQ0sxNkZSQU1FKilwICk7CgkJICAgcmV0dXJuOwoJICAgICAgIH0KCSAgICAgICBjdXJfc3dpdGNoID0gKERXT1JEKWZyYW1lMTYuZnJhbWUzMjsKCSAgICAgICBzd19hZGRyLnNlZyA9IDA7CgkgICAgICAgc3dfYWRkci5vZmYgPSBjdXJfc3dpdGNoOwoJICAgICAgIAoJICAgICAgIGlzMTYgPSBGQUxTRTsKCSAgIH0gZWxzZSB7CgkgICAgICB0bXAuc2VnID0gU0VMRUNUT1JPRihuZXh0X3N3aXRjaCk7CgkgICAgICB0bXAub2ZmID0gT0ZGU0VUT0YobmV4dF9zd2l0Y2gpOwoJICAgICAgcCA9IERFQlVHX1RvTGluZWFyKCZ0bXApOwoJICAgICAgCgkgICAgICBpZiAoIURFQlVHX1JFQURfTUVNKCh2b2lkKilwLCAmZnJhbWUxNiwgc2l6ZW9mKFNUQUNLMTZGUkFNRSkpKSB7CgkJICBpZiAobm9pc3kpIERFQlVHX1ByaW50ZiggREJHX0NITl9NRVNHLCAiQmFkIHN0YWNrIGZyYW1lIDB4JTA4bHhcbiIsCgkJCQkJICAgKHVuc2lnbmVkIGxvbmcpKFNUQUNLMTZGUkFNRSopcCApOwoJCSAgcmV0dXJuOwoJICAgICAgfQoJICAgICAgCgkgICAgICBjb2RlLnNlZyAgPSBmcmFtZTE2LmNzOwoJICAgICAgY29kZS5vZmYgID0gZnJhbWUxNi5pcDsKCSAgICAgIAoJICAgICAgY3MgPSBmcmFtZTE2LmNzOwoJICAgICAgYWRkci5zZWcgPSBTRUxFQ1RPUk9GKG5leHRfc3dpdGNoKTsKCSAgICAgIGFkZHIub2ZmID0gZnJhbWUxNi5icDsKCSAgICAgIERFQlVHX0ZvcmNlRnJhbWUoICZhZGRyLCAmY29kZSwgKytmcmFtZW5vLCAxNiwgbm9pc3kgKTsKCSAgICAgIAoJICAgICAgbmV4dF9zd2l0Y2ggPSBjdXJfc3dpdGNoOwoJICAgICAgaWYgKCFERUJVR19SRUFEX01FTSgodm9pZCopbmV4dF9zd2l0Y2gsICZmcmFtZTMyLCBzaXplb2YoU1RBQ0szMkZSQU1FKSkpIHsKCQkgaWYgKG5vaXN5KSBERUJVR19QcmludGYoIERCR19DSE5fTUVTRywgIkJhZCBzdGFjayBmcmFtZSAweCUwOGx4XG4iLCAKCQkJCQkgICh1bnNpZ25lZCBsb25nKShTVEFDSzMyRlJBTUUqKW5leHRfc3dpdGNoICk7CgkJIHJldHVybjsKCSAgICAgIH0KCSAgICAgIGN1cl9zd2l0Y2ggPSAoRFdPUkQpZnJhbWUzMi5mcmFtZTE2OwoJICAgICAgc3dfYWRkci5zZWcgPSBTRUxFQ1RPUk9GKGN1cl9zd2l0Y2gpOwoJICAgICAgc3dfYWRkci5vZmYgPSBPRkZTRVRPRihjdXJfc3dpdGNoKTsKCSAgICAgIAoJICAgICAgaXMxNiA9IFRSVUU7CgkgICB9CgkgICBpZiAoIURFQlVHX1JFQURfTUVNKCh2b2lkKilERUJVR19Ub0xpbmVhcigmc3dfYWRkciksICZjaCwgc2l6ZW9mKGNoKSkpIHsKCSAgICAgIHN3X2FkZHIuc2VnID0gKERXT1JEKS0xOwoJICAgICAgc3dfYWRkci5vZmYgPSAoRFdPUkQpLTE7CgkgICB9Cgl9IGVsc2UgewoJICAgIC8qIG9yZGluYXJ5IHN0YWNrIGZyYW1lICovCgkgICBvayA9IGlzMTYgPyBERUJVR19GcmFtZTE2KCAmYWRkciwgJmNzLCArK2ZyYW1lbm8sIG5vaXN5KQoJICAgICAgOiBERUJVR19GcmFtZTMyKCAmYWRkciwgJmNzLCArK2ZyYW1lbm8sIG5vaXN5KTsKCX0KICAgIH0KICAgIGlmIChub2lzeSkgREVCVUdfUHJpbnRmKCBEQkdfQ0hOX01FU0csICJcbiIgKTsKI2VuZGlmCn0KCmludApERUJVR19TZXRGcmFtZShpbnQgbmV3ZnJhbWUpCnsKI2lmZGVmIF9faTM4Nl9fCiAgaW50CQlydG4gPSBGQUxTRTsKCiAgY3Vycl9mcmFtZSA9IG5ld2ZyYW1lOwoKICBpZiggY3Vycl9mcmFtZSA+PSBuZnJhbWUgKQogICAgewogICAgICBjdXJyX2ZyYW1lID0gbmZyYW1lIC0gMTsKICAgIH0KCiAgaWYoIGN1cnJfZnJhbWUgPCAwICkKICAgIHsKICAgICAgY3Vycl9mcmFtZSA9IDA7CiAgICB9CgogICBpZiggZnJhbWVzICYmIGZyYW1lc1tjdXJyX2ZyYW1lXS5mcmFtZS5saXN0LnNvdXJjZWZpbGUgIT0gTlVMTCApCiAgICB7CiAgICAgIERFQlVHX0xpc3QoJmZyYW1lc1tjdXJyX2ZyYW1lXS5mcmFtZS5saXN0LCBOVUxMLCAwKTsKICAgIH0KCiAgcnRuID0gVFJVRTsKICByZXR1cm4gKHJ0bik7CiNlbHNlIC8qIF9faTM4Nl9fICovCiAgcmV0dXJuIEZBTFNFOwojZW5kaWYgLyogX19pMzg2X18gKi8KfQoKaW50CkRFQlVHX0dldEN1cnJlbnRGcmFtZShzdHJ1Y3QgbmFtZV9oYXNoICoqIG5hbWUsIHVuc2lnbmVkIGludCAqIGVpcCwKCQkgICAgICB1bnNpZ25lZCBpbnQgKiBlYnApCnsKI2lmZGVmIF9faTM4Nl9fCiAgLyoKICAgKiBJZiB3ZSBkb24ndCBoYXZlIGEgdmFsaWQgYmFja3RyYWNlLCB0aGVuIGp1c3QgcmV0dXJuLgogICAqLwogIGlmKCBmcmFtZXMgPT0gTlVMTCApCiAgICB7CiAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgLyoKICAgKiBJZiB3ZSBkb24ndCBrbm93IHdoYXQgdGhlIGN1cnJlbnQgZnVuY3Rpb24gaXMsIHRoZW4gd2UgYWxzbyBoYXZlCiAgICogbm90aGluZyB0byByZXBvcnQgaGVyZS4KICAgKi8KICBpZiggZnJhbWVzW2N1cnJfZnJhbWVdLmZyYW1lLnN5bSA9PSBOVUxMICkKICAgIHsKICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAqbmFtZSA9IGZyYW1lc1tjdXJyX2ZyYW1lXS5mcmFtZS5zeW07CiAgKmVpcCA9IGZyYW1lc1tjdXJyX2ZyYW1lXS5laXA7CiAgKmVicCA9IGZyYW1lc1tjdXJyX2ZyYW1lXS5lYnA7CgogIHJldHVybiBUUlVFOwojZWxzZSAvKiBfX2kzODZfXyAqLwogIHJldHVybiBGQUxTRTsKI2VuZGlmIC8qIF9faTM4Nl9fICovCn0KCg==