LyoKICB0cmUtbWF0Y2gtcGFyYWxsZWwuYyAtIFRSRSBwYXJhbGxlbCByZWdleCBtYXRjaGluZyBlbmdpbmUKCiAgVGhpcyBzb2Z0d2FyZSBpcyByZWxlYXNlZCB1bmRlciBhIEJTRC1zdHlsZSBsaWNlbnNlLgogIFNlZSB0aGUgZmlsZSBMSUNFTlNFIGZvciBkZXRhaWxzIGFuZCBjb3B5cmlnaHQuCgoqLwoKLyoKICBUaGlzIGFsZ29yaXRobSBzZWFyY2hlcyBmb3IgbWF0Y2hlcyBiYXNpY2FsbHkgYnkgcmVhZGluZyBjaGFyYWN0ZXJzCiAgaW4gdGhlIHNlYXJjaGVkIHN0cmluZyBvbmUgYnkgb25lLCBzdGFydGluZyBhdCB0aGUgYmVnaW5uaW5nLgkgQWxsCiAgbWF0Y2hpbmcgcGF0aHMgaW4gdGhlIFRORkEgYXJlIHRyYXZlcnNlZCBpbiBwYXJhbGxlbC4JIFdoZW4gdHdvIG9yCiAgbW9yZSBwYXRocyByZWFjaCB0aGUgc2FtZSBzdGF0ZSwgZXhhY3RseSBvbmUgaXMgY2hvc2VuIGFjY29yZGluZyB0bwogIHRhZyBvcmRlcmluZyBydWxlczsgaWYgcmV0dXJuaW5nIHN1Ym1hdGNoZXMgaXMgbm90IHJlcXVpcmVkIGl0IGRvZXMKICBub3QgbWF0dGVyIHdoaWNoIHBhdGggaXMgY2hvc2VuLgoKICBUaGUgd29yc3QgY2FzZSB0aW1lIHJlcXVpcmVkIGZvciBmaW5kaW5nIHRoZSBsZWZ0bW9zdCBhbmQgbG9uZ2VzdAogIG1hdGNoLCBvciBkZXRlcm1pbmluZyB0aGF0IHRoZXJlIGlzIG5vIG1hdGNoLCBpcyBhbHdheXMgbGluZWFybHkKICBkZXBlbmRlbnQgb24gdGhlIGxlbmd0aCBvZiB0aGUgdGV4dCBiZWluZyBzZWFyY2hlZC4KCiAgVGhpcyBhbGdvcml0aG0gY2Fubm90IGhhbmRsZSBUTkZBcyB3aXRoIGJhY2sgcmVmZXJlbmNpbmcgbm9kZXMuCiAgU2VlIGB0cmUtbWF0Y2gtYmFja3RyYWNrLmMnLgoqLwoKCiNpZmRlZiBIQVZFX0NPTkZJR19ICiNpbmNsdWRlIDxjb25maWcuaD4KI2VuZGlmIC8qIEhBVkVfQ09ORklHX0ggKi8KCiNpZmRlZiBUUkVfVVNFX0FMTE9DQQovKiBBSVggcmVxdWlyZXMgdGhpcyB0byBiZSB0aGUgZmlyc3QgdGhpbmcgaW4gdGhlIGZpbGUuCSAqLwojaWZuZGVmIF9fR05VQ19fCiMgaWYgSEFWRV9BTExPQ0FfSAojICBpbmNsdWRlIDxhbGxvY2EuaD4KIyBlbHNlCiMgIGlmZGVmIF9BSVgKICNwcmFnbWEgYWxsb2NhCiMgIGVsc2UKIyAgIGlmbmRlZiBhbGxvY2EgLyogcHJlZGVmaW5lZCBieSBIUCBjYyArT2xpYmNhbGxzICovCmNoYXIgKmFsbG9jYSAoKTsKIyAgIGVuZGlmCiMgIGVuZGlmCiMgZW5kaWYKI2VuZGlmCiNlbmRpZiAvKiBUUkVfVVNFX0FMTE9DQSAqLwoKLy8gI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2lmZGVmIEhBVkVfV0NIQVJfSAojaW5jbHVkZSA8d2NoYXIuaD4KI2VuZGlmIC8qIEhBVkVfV0NIQVJfSCAqLwojaWZkZWYgSEFWRV9XQ1RZUEVfSAojaW5jbHVkZSA8d2N0eXBlLmg+CiNlbmRpZiAvKiBIQVZFX1dDVFlQRV9IICovCiNpZm5kZWYgVFJFX1dDSEFSCiNpbmNsdWRlIDxjdHlwZS5oPgojZW5kaWYgLyogIVRSRV9XQ0hBUiAqLwojaWZkZWYgSEFWRV9NQUxMT0NfSAojaW5jbHVkZSA8bWFsbG9jLmg+CiNlbmRpZiAvKiBIQVZFX01BTExPQ19IICovCgojaW5jbHVkZSAidHJlLWludGVybmFsLmgiCiNpbmNsdWRlICJ0cmUtbWF0Y2gtdXRpbHMuaCIKI2luY2x1ZGUgInRyZS5oIgojaW5jbHVkZSAieG1hbGxvYy5oIgoKI2RlZmluZSBhc3NlcnQoYSkgUl9hc3NlcnQoYSkKCnR5cGVkZWYgc3RydWN0IHsKICB0cmVfdG5mYV90cmFuc2l0aW9uX3QgKnN0YXRlOwogIGludCAqdGFnczsKfSB0cmVfdG5mYV9yZWFjaF90OwoKdHlwZWRlZiBzdHJ1Y3QgewogIGludCBwb3M7CiAgaW50ICoqdGFnczsKfSB0cmVfcmVhY2hfcG9zX3Q7CgoKI2lmZGVmIFRSRV9ERUJVRwpzdGF0aWMgdm9pZAp0cmVfcHJpbnRfcmVhY2goY29uc3QgdHJlX3RuZmFfdCAqdG5mYSwgdHJlX3RuZmFfcmVhY2hfdCAqcmVhY2gsIGludCBudW1fdGFncykKewogIGludCBpOwoKICB3aGlsZSAocmVhY2gtPnN0YXRlICE9IE5VTEwpCiAgICB7CiAgICAgIERQUklOVCgoIiAlcCIsICh2b2lkICopcmVhY2gtPnN0YXRlKSk7CiAgICAgIGlmIChudW1fdGFncyA+IDApCgl7CgkgIERQUklOVCgoIi8iKSk7CgkgIGZvciAoaSA9IDA7IGkgPCBudW1fdGFnczsgaSsrKQoJICAgIHsKCSAgICAgIERQUklOVCgoIiVkOiVkIiwgaSwgcmVhY2gtPnRhZ3NbaV0pKTsKCSAgICAgIGlmIChpIDwgKG51bV90YWdzLTEpKQoJCURQUklOVCgoIiwiKSk7CgkgICAgfQoJfQogICAgICByZWFjaCsrOwogICAgfQogIERQUklOVCgoIlxuIikpOwoKfQojZW5kaWYgLyogVFJFX0RFQlVHICovCgpyZWdfZXJyY29kZV90CnRyZV90bmZhX3J1bl9wYXJhbGxlbChjb25zdCB0cmVfdG5mYV90ICp0bmZhLCBjb25zdCB2b2lkICpzdHJpbmcsIGludCBsZW4sCgkJICAgICAgdHJlX3N0cl90eXBlX3QgdHlwZSwgaW50ICptYXRjaF90YWdzLCBpbnQgZWZsYWdzLAoJCSAgICAgIGludCAqbWF0Y2hfZW5kX29mcykKewogIC8qIFN0YXRlIHZhcmlhYmxlcyByZXF1aXJlZCBieSBHRVRfTkVYVF9XQ0hBUi4gKi8KICB0cmVfY2hhcl90IHByZXZfYyA9IDAsIG5leHRfYyA9IDA7CiAgY29uc3QgY2hhciAqc3RyX2J5dGUgPSBzdHJpbmc7CiAgaW50IHBvcyA9IC0xOwogIHVuc2lnbmVkIGludCBwb3NfYWRkX25leHQgPSAxOwojaWZkZWYgVFJFX1dDSEFSCiAgY29uc3Qgd2NoYXJfdCAqc3RyX3dpZGUgPSBzdHJpbmc7CiNpZmRlZiBUUkVfTUJTVEFURQogIG1ic3RhdGVfdCBtYnN0YXRlOwojZW5kaWYgLyogVFJFX01CU1RBVEUgKi8KI2VuZGlmIC8qIFRSRV9XQ0hBUiAqLwogIGludCByZWdfbm90Ym9sID0gZWZsYWdzICYgUkVHX05PVEJPTDsKICBpbnQgcmVnX25vdGVvbCA9IGVmbGFncyAmIFJFR19OT1RFT0w7CiAgaW50IHJlZ19uZXdsaW5lID0gdG5mYS0+Y2ZsYWdzICYgUkVHX05FV0xJTkU7CiAgaW50IHN0cl91c2VyX2VuZCA9IDA7CgogIGNoYXIgKmJ1ZjsKICB0cmVfdG5mYV90cmFuc2l0aW9uX3QgKnRyYW5zX2k7CiAgdHJlX3RuZmFfcmVhY2hfdCAqcmVhY2gsICpyZWFjaF9uZXh0LCAqcmVhY2hfaSwgKnJlYWNoX25leHRfaTsKICB0cmVfcmVhY2hfcG9zX3QgKnJlYWNoX3BvczsKICBpbnQgKnRhZ19pOwogIGludCBudW1fdGFncywgaTsKCiAgaW50IG1hdGNoX2VvID0gLTE7CSAgIC8qIGVuZCBvZmZzZXQgb2YgbWF0Y2ggKC0xIGlmIG5vIG1hdGNoIGZvdW5kIHlldCkgKi8KICBpbnQgbmV3X21hdGNoID0gMDsKICBpbnQgKnRtcF90YWdzID0gTlVMTDsKICBpbnQgKnRtcF9pcHRyOwoKI2lmZGVmIFRSRV9NQlNUQVRFCiAgbWVtc2V0KCZtYnN0YXRlLCAnXDAnLCBzaXplb2YobWJzdGF0ZSkpOwojZW5kaWYgLyogVFJFX01CU1RBVEUgKi8KCiAgRFBSSU5UKCgidHJlX3RuZmFfcnVuX3BhcmFsbGVsLCBpbnB1dCB0eXBlICVkXG4iLCB0eXBlKSk7CgogIGlmICghbWF0Y2hfdGFncykKICAgIG51bV90YWdzID0gMDsKICBlbHNlCiAgICBudW1fdGFncyA9IHRuZmEtPm51bV90YWdzOwoKICAvKiBBbGxvY2F0ZSBtZW1vcnkgZm9yIHRlbXBvcmFyeSBkYXRhIHJlcXVpcmVkIGZvciBtYXRjaGluZy4JVGhpcyBuZWVkcyB0bwogICAgIGJlIGRvbmUgZm9yIGV2ZXJ5IG1hdGNoaW5nIG9wZXJhdGlvbiB0byBiZSB0aHJlYWQgc2FmZS4gIFRoaXMgYWxsb2NhdGVzCiAgICAgZXZlcnl0aGluZyBpbiBhIHNpbmdsZSBsYXJnZSBibG9jayBmcm9tIHRoZSBzdGFjayBmcmFtZSB1c2luZyBhbGxvY2EoKQogICAgIG9yIHdpdGggbWFsbG9jKCkgaWYgYWxsb2NhIGlzIHVuYXZhaWxhYmxlLiAqLwogIHsKICAgIGludCB0Ynl0ZXMsIHJieXRlcywgcGJ5dGVzLCB4Ynl0ZXMsIHRvdGFsX2J5dGVzOwogICAgY2hhciAqdG1wX2J1ZjsKICAgIC8qIENvbXB1dGUgdGhlIGxlbmd0aCBvZiB0aGUgYmxvY2sgd2UgbmVlZC4gKi8KICAgIHRieXRlcyA9IHNpemVvZigqdG1wX3RhZ3MpICogbnVtX3RhZ3M7CiAgICByYnl0ZXMgPSBzaXplb2YoKnJlYWNoX25leHQpICogKHRuZmEtPm51bV9zdGF0ZXMgKyAxKTsKICAgIHBieXRlcyA9IHNpemVvZigqcmVhY2hfcG9zKSAqIHRuZmEtPm51bV9zdGF0ZXM7CiAgICB4Ynl0ZXMgPSBzaXplb2YoaW50KSAqIG51bV90YWdzOwogICAgdG90YWxfYnl0ZXMgPQogICAgICAoc2l6ZW9mKGxvbmcpIC0gMSkgKiA0IC8qIGZvciBhbGlnbm1lbnQgcGFkZGluZ3MgKi8KICAgICAgKyAocmJ5dGVzICsgeGJ5dGVzICogdG5mYS0+bnVtX3N0YXRlcykgKiAyICsgdGJ5dGVzICsgcGJ5dGVzOwoKICAgIC8qIEFsbG9jYXRlIHRoZSBtZW1vcnkuICovCiNpZmRlZiBUUkVfVVNFX0FMTE9DQQogICAgYnVmID0gYWxsb2NhKHRvdGFsX2J5dGVzKTsKI2Vsc2UgLyogIVRSRV9VU0VfQUxMT0NBICovCiAgICBidWYgPSB4bWFsbG9jKCh1bnNpZ25lZCl0b3RhbF9ieXRlcyk7CiNlbmRpZiAvKiAhVFJFX1VTRV9BTExPQ0EgKi8KICAgIGlmIChidWYgPT0gTlVMTCkKICAgICAgcmV0dXJuIFJFR19FU1BBQ0U7CiAgICBtZW1zZXQoYnVmLCAwLCAoc2l6ZV90KXRvdGFsX2J5dGVzKTsKCiAgICAvKiBHZXQgdGhlIHZhcmlvdXMgcG9pbnRlcnMgd2l0aGluIHRtcF9idWYgKHByb3Blcmx5IGFsaWduZWQpLiAqLwogICAgdG1wX3RhZ3MgPSAodm9pZCAqKWJ1ZjsKICAgIHRtcF9idWYgPSBidWYgKyB0Ynl0ZXM7CiAgICB0bXBfYnVmICs9IEFMSUdOKHRtcF9idWYsIGxvbmcpOwogICAgcmVhY2hfbmV4dCA9ICh2b2lkICopdG1wX2J1ZjsKICAgIHRtcF9idWYgKz0gcmJ5dGVzOwogICAgdG1wX2J1ZiArPSBBTElHTih0bXBfYnVmLCBsb25nKTsKICAgIHJlYWNoID0gKHZvaWQgKil0bXBfYnVmOwogICAgdG1wX2J1ZiArPSByYnl0ZXM7CiAgICB0bXBfYnVmICs9IEFMSUdOKHRtcF9idWYsIGxvbmcpOwogICAgcmVhY2hfcG9zID0gKHZvaWQgKil0bXBfYnVmOwogICAgdG1wX2J1ZiArPSBwYnl0ZXM7CiAgICB0bXBfYnVmICs9IEFMSUdOKHRtcF9idWYsIGxvbmcpOwogICAgZm9yIChpID0gMDsgaSA8IHRuZmEtPm51bV9zdGF0ZXM7IGkrKykKICAgICAgewoJcmVhY2hbaV0udGFncyA9ICh2b2lkICopdG1wX2J1ZjsKCXRtcF9idWYgKz0geGJ5dGVzOwoJcmVhY2hfbmV4dFtpXS50YWdzID0gKHZvaWQgKil0bXBfYnVmOwoJdG1wX2J1ZiArPSB4Ynl0ZXM7CiAgICAgIH0KICB9CgogIGZvciAoaSA9IDA7IGkgPCB0bmZhLT5udW1fc3RhdGVzOyBpKyspCiAgICByZWFjaF9wb3NbaV0ucG9zID0gLTE7CgogIC8qIElmIG9ubHkgb25lIGNoYXJhY3RlciBjYW4gc3RhcnQgYSBtYXRjaCwgZmluZCBpdCBmaXJzdC4gKi8KICBpZiAodG5mYS0+Zmlyc3RfY2hhciA+PSAwICYmIHR5cGUgPT0gU1RSX0JZVEUgJiYgc3RyX2J5dGUpCiAgICB7CiAgICAgIGNvbnN0IGNoYXIgKm9yaWdfc3RyID0gc3RyX2J5dGU7CiAgICAgIGludCBmaXJzdCA9IHRuZmEtPmZpcnN0X2NoYXI7CgogICAgICBpZiAobGVuID49IDApCglzdHJfYnl0ZSA9IG1lbWNocihvcmlnX3N0ciwgZmlyc3QsIChzaXplX3QpbGVuKTsKICAgICAgZWxzZQoJc3RyX2J5dGUgPSBzdHJjaHIob3JpZ19zdHIsIGZpcnN0KTsKICAgICAgaWYgKHN0cl9ieXRlID09IE5VTEwpCgl7CiNpZm5kZWYgVFJFX1VTRV9BTExPQ0EKCSAgaWYgKGJ1ZikKCSAgICB4ZnJlZShidWYpOwojZW5kaWYgLyogIVRSRV9VU0VfQUxMT0NBICovCgkgIHJldHVybiBSRUdfTk9NQVRDSDsKCX0KICAgICAgRFBSSU5UKCgic2tpcHBlZCAlbHUgY2hhcnNcbiIsICh1bnNpZ25lZCBsb25nKShzdHJfYnl0ZSAtIG9yaWdfc3RyKSkpOwogICAgICBpZiAoc3RyX2J5dGUgPj0gb3JpZ19zdHIgKyAxKQoJcHJldl9jID0gKHVuc2lnbmVkIGNoYXIpKihzdHJfYnl0ZSAtIDEpOwogICAgICBuZXh0X2MgPSAodW5zaWduZWQgY2hhcikqc3RyX2J5dGU7CiAgICAgIHBvcyA9IChpbnQpKHN0cl9ieXRlIC0gb3JpZ19zdHIpOwogICAgICBpZiAobGVuIDwgMCB8fCBwb3MgPCBsZW4pCglzdHJfYnl0ZSsrOwogICAgfQogIGVsc2UKICAgIHsKICAgICAgR0VUX05FWFRfV0NIQVIoKTsKICAgICAgcG9zID0gMDsKICAgIH0KCiNpZiAwCiAgLyogU2tpcCBvdmVyIGNoYXJhY3RlcnMgdGhhdCBjYW5ub3QgcG9zc2libHkgYmUgdGhlIGZpcnN0IGNoYXJhY3RlcgogICAgIG9mIGEgbWF0Y2guICovCiAgaWYgKHRuZmEtPmZpcnN0cG9zX2NoYXJzICE9IE5VTEwpCiAgICB7CiAgICAgIGNoYXIgKmNoYXJzID0gdG5mYS0+Zmlyc3Rwb3NfY2hhcnM7CgogICAgICBpZiAobGVuIDwgMCkKCXsKCSAgY29uc3QgY2hhciAqb3JpZ19zdHIgPSBzdHJfYnl0ZTsKCSAgLyogWFhYIC0gdXNlIHN0cnBicmsoKSBhbmQgd2NzcGJyaygpIGJlY2F1c2UgdGhleSBtaWdodCBiZQoJICAgICBvcHRpbWl6ZWQgZm9yIHRoZSB0YXJnZXQgYXJjaGl0ZWN0dXJlLiAgVHJ5IGFsc28gc3RyY3NwbigpCgkgICAgIGFuZCB3Y3Njc3BuKCkgYW5kIGNvbXBhcmUgdGhlIHNwZWVkcy4gKi8KCSAgd2hpbGUgKG5leHRfYyAhPSBMJ1wwJyAmJiAhY2hhcnNbbmV4dF9jXSkKCSAgICB7CgkgICAgICBuZXh0X2MgPSAqc3RyX2J5dGUrKzsKCSAgICB9CgkgIHByZXZfYyA9ICooc3RyX2J5dGUgLSAyKTsKCSAgcG9zICs9IHN0cl9ieXRlIC0gb3JpZ19zdHI7CgkgIERQUklOVCgoInNraXBwZWQgJWQgY2hhcnNcbiIsIHN0cl9ieXRlIC0gb3JpZ19zdHIpKTsKCX0KICAgICAgZWxzZQoJewoJICB3aGlsZSAocG9zIDw9IGxlbiAmJiAhY2hhcnNbbmV4dF9jXSkKCSAgICB7CgkgICAgICBwcmV2X2MgPSBuZXh0X2M7CgkgICAgICBuZXh0X2MgPSAodW5zaWduZWQgY2hhcikoKnN0cl9ieXRlKyspOwoJICAgICAgcG9zKys7CgkgICAgfQoJfQogICAgfQojZW5kaWYKCiAgRFBSSU5UKCgibGVuZ3RoOiAlZFxuIiwgbGVuKSk7CiAgRFBSSU5UKCgicG9zOmNoci9jb2RlIHwgc3RhdGVzIGFuZCB0YWdzXG4iKSk7CiAgRFBSSU5UKCgiLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiIpKTsKCiAgcmVhY2hfbmV4dF9pID0gcmVhY2hfbmV4dDsKICB3aGlsZSAoLypDT05TVENPTkQqLyh2b2lkKTEsMSkKICAgIHsKICAgICAgLyogSWYgbm8gbWF0Y2ggZm91bmQgeWV0LCBhZGQgdGhlIGluaXRpYWwgc3RhdGVzIHRvIGByZWFjaF9uZXh0Jy4gKi8KICAgICAgaWYgKG1hdGNoX2VvIDwgMCkKCXsKCSAgRFBSSU5UKCgiIGluaXQgPiIpKTsKCSAgdHJhbnNfaSA9IHRuZmEtPmluaXRpYWw7CgkgIHdoaWxlICh0cmFuc19pLT5zdGF0ZSAhPSBOVUxMKQoJICAgIHsKCSAgICAgIGlmIChyZWFjaF9wb3NbdHJhbnNfaS0+c3RhdGVfaWRdLnBvcyA8IHBvcykKCQl7CgkJICBpZiAodHJhbnNfaS0+YXNzZXJ0aW9ucwoJCSAgICAgICYmIENIRUNLX0FTU0VSVElPTlModHJhbnNfaS0+YXNzZXJ0aW9ucykpCgkJICAgIHsKCQkgICAgICBEUFJJTlQoKCJhc3NlcnRpb24gZmFpbGVkXG4iKSk7CgkJICAgICAgdHJhbnNfaSsrOwoJCSAgICAgIGNvbnRpbnVlOwoJCSAgICB9CgoJCSAgRFBSSU5UKCgiICVwIiwgKHZvaWQgKil0cmFuc19pLT5zdGF0ZSkpOwoJCSAgcmVhY2hfbmV4dF9pLT5zdGF0ZSA9IHRyYW5zX2ktPnN0YXRlOwoJCSAgZm9yIChpID0gMDsgaSA8IG51bV90YWdzOyBpKyspCgkJICAgIHJlYWNoX25leHRfaS0+dGFnc1tpXSA9IC0xOwoJCSAgdGFnX2kgPSB0cmFuc19pLT50YWdzOwoJCSAgaWYgKHRhZ19pKQoJCSAgICB3aGlsZSAoKnRhZ19pID49IDApCgkJICAgICAgewoJCQlpZiAoKnRhZ19pIDwgbnVtX3RhZ3MpCgkJCSAgcmVhY2hfbmV4dF9pLT50YWdzWyp0YWdfaV0gPSBwb3M7CgkJCXRhZ19pKys7CgkJICAgICAgfQoJCSAgaWYgKHJlYWNoX25leHRfaS0+c3RhdGUgPT0gdG5mYS0+ZmluYWwpCgkJICAgIHsKCQkgICAgICBEUFJJTlQoKCIJIGZvdW5kIGVtcHR5IG1hdGNoXG4iKSk7CgkJICAgICAgbWF0Y2hfZW8gPSBwb3M7CgkJICAgICAgbmV3X21hdGNoID0gMTsKCQkgICAgICBmb3IgKGkgPSAwOyBpIDwgbnVtX3RhZ3M7IGkrKykKCQkJbWF0Y2hfdGFnc1tpXSA9IHJlYWNoX25leHRfaS0+dGFnc1tpXTsKCQkgICAgfQoJCSAgcmVhY2hfcG9zW3RyYW5zX2ktPnN0YXRlX2lkXS5wb3MgPSBwb3M7CgkJICByZWFjaF9wb3NbdHJhbnNfaS0+c3RhdGVfaWRdLnRhZ3MgPSAmcmVhY2hfbmV4dF9pLT50YWdzOwoJCSAgcmVhY2hfbmV4dF9pKys7CgkJfQoJICAgICAgdHJhbnNfaSsrOwoJICAgIH0KCSAgRFBSSU5UKCgiXG4iKSk7CgkgIHJlYWNoX25leHRfaS0+c3RhdGUgPSBOVUxMOwoJfQogICAgICBlbHNlCgl7CgkgIGlmIChudW1fdGFncyA9PSAwIHx8IHJlYWNoX25leHRfaSA9PSByZWFjaF9uZXh0KQoJICAgIC8qoFdlIGhhdmUgZm91bmQgYSBtYXRjaC4gKi8KCSAgICBicmVhazsKCX0KCiAgICAgIC8qIENoZWNrIGZvciBlbmQgb2Ygc3RyaW5nLiAqLwogICAgICBpZiAobGVuIDwgMCkKCXsKCSAgaWYgKHR5cGUgPT0gU1RSX1VTRVIpCgkgICAgewoJICAgICAgaWYgKHN0cl91c2VyX2VuZCkKCQlicmVhazsKCSAgICB9CgkgIGVsc2UgaWYgKG5leHRfYyA9PSBMJ1wwJykKCSAgICBicmVhazsKCX0KICAgICAgZWxzZQoJewoJICBpZiAocG9zID49IGxlbikKCSAgICBicmVhazsKCX0KCiAgICAgIEdFVF9ORVhUX1dDSEFSKCk7CgojaWZkZWYgVFJFX0RFQlVHCiAgICAgIERQUklOVCgoIiUzZDolMmxjLyUwNWQgfCIsIHBvcyAtIDEsICh0cmVfY2ludF90KXByZXZfYywgKGludClwcmV2X2MpKTsKICAgICAgdHJlX3ByaW50X3JlYWNoKHRuZmEsIHJlYWNoX25leHQsIG51bV90YWdzKTsKICAgICAgRFBSSU5UKCgiJTNkOiUybGMvJTA1ZCB8IiwgcG9zLCAodHJlX2NpbnRfdCluZXh0X2MsIChpbnQpbmV4dF9jKSk7CiAgICAgIHRyZV9wcmludF9yZWFjaCh0bmZhLCByZWFjaF9uZXh0LCBudW1fdGFncyk7CiNlbmRpZiAvKiBUUkVfREVCVUcgKi8KCiAgICAgIC8qIFN3YXAgYHJlYWNoJyBhbmQgYHJlYWNoX25leHQnLiAqLwogICAgICByZWFjaF9pID0gcmVhY2g7CiAgICAgIHJlYWNoID0gcmVhY2hfbmV4dDsKICAgICAgcmVhY2hfbmV4dCA9IHJlYWNoX2k7CgogICAgICAvKiBGb3IgZWFjaCBzdGF0ZSBpbiBgcmVhY2gnLCB3ZWVkIG91dCBzdGF0ZXMgdGhhdCBkb24ndCBmdWxmaWxsIHRoZQoJIG1pbmltYWwgbWF0Y2hpbmcgY29uZGl0aW9ucy4gKi8KICAgICAgaWYgKHRuZmEtPm51bV9taW5pbWFscyAmJiBuZXdfbWF0Y2gpCgl7CgkgIG5ld19tYXRjaCA9IDA7CgkgIHJlYWNoX25leHRfaSA9IHJlYWNoX25leHQ7CgkgIGZvciAocmVhY2hfaSA9IHJlYWNoOyByZWFjaF9pLT5zdGF0ZTsgcmVhY2hfaSsrKQoJICAgIHsKCSAgICAgIGludCBza2lwID0gMDsKCSAgICAgIGZvciAoaSA9IDA7IHRuZmEtPm1pbmltYWxfdGFnc1tpXSA+PSAwOyBpICs9IDIpCgkJewoJCSAgaW50IGVuZCA9IHRuZmEtPm1pbmltYWxfdGFnc1tpXTsKCQkgIGludCBzdGFydCA9IHRuZmEtPm1pbmltYWxfdGFnc1tpICsgMV07CgkJICBEUFJJTlQoKCIgIE1pbmltYWwgc3RhcnQgJWQsIGVuZCAlZFxuIiwgc3RhcnQsIGVuZCkpOwoJCSAgaWYgKGVuZCA+PSBudW1fdGFncykKCQkgICAgewoJCSAgICAgIERQUklOVCgoIgkgVGhyb3dpbmcgJXAgb3V0LlxuIiwgcmVhY2hfaS0+c3RhdGUpKTsKCQkgICAgICBza2lwID0gMTsKCQkgICAgICBicmVhazsKCQkgICAgfQoJCSAgZWxzZSBpZiAocmVhY2hfaS0+dGFnc1tzdGFydF0gPT0gbWF0Y2hfdGFnc1tzdGFydF0KCQkJICAgJiYgcmVhY2hfaS0+dGFnc1tlbmRdIDwgbWF0Y2hfdGFnc1tlbmRdKQoJCSAgICB7CgkJICAgICAgRFBSSU5UKCgiCSBUaHJvd2luZyAlcCBvdXQgYmVjYXVzZSB0JWQgPCAlZFxuIiwKCQkJICAgICAgcmVhY2hfaS0+c3RhdGUsIGVuZCwgbWF0Y2hfdGFnc1tlbmRdKSk7CgkJICAgICAgc2tpcCA9IDE7CgkJICAgICAgYnJlYWs7CgkJICAgIH0KCQl9CgkgICAgICBpZiAoIXNraXApCgkJewoJCSAgcmVhY2hfbmV4dF9pLT5zdGF0ZSA9IHJlYWNoX2ktPnN0YXRlOwoJCSAgdG1wX2lwdHIgPSByZWFjaF9uZXh0X2ktPnRhZ3M7CgkJICByZWFjaF9uZXh0X2ktPnRhZ3MgPSByZWFjaF9pLT50YWdzOwoJCSAgcmVhY2hfaS0+dGFncyA9IHRtcF9pcHRyOwoJCSAgcmVhY2hfbmV4dF9pKys7CgkJfQoJICAgIH0KCSAgcmVhY2hfbmV4dF9pLT5zdGF0ZSA9IE5VTEw7CgoJICAvKiBTd2FwIGByZWFjaCcgYW5kIGByZWFjaF9uZXh0Jy4gKi8KCSAgcmVhY2hfaSA9IHJlYWNoOwoJICByZWFjaCA9IHJlYWNoX25leHQ7CgkgIHJlYWNoX25leHQgPSByZWFjaF9pOwoJfQoKICAgICAgLyogRm9yIGVhY2ggc3RhdGUgaW4gYHJlYWNoJyBzZWUgaWYgdGhlcmUgaXMgYSB0cmFuc2l0aW9uIGxlYXZpbmcgd2l0aAoJIHRoZSBjdXJyZW50IGlucHV0IHN5bWJvbCB0byBhIHN0YXRlIG5vdCB5ZXQgaW4gYHJlYWNoX25leHQnLCBhbmQKCSBhZGQgdGhlIGRlc3RpbmF0aW9uIHN0YXRlcyB0byBgcmVhY2hfbmV4dCcuICovCiAgICAgIHJlYWNoX25leHRfaSA9IHJlYWNoX25leHQ7CiAgICAgIGZvciAocmVhY2hfaSA9IHJlYWNoOyByZWFjaF9pLT5zdGF0ZTsgcmVhY2hfaSsrKQoJewoJICBmb3IgKHRyYW5zX2kgPSByZWFjaF9pLT5zdGF0ZTsgdHJhbnNfaS0+c3RhdGU7IHRyYW5zX2krKykKCSAgICB7CgkgICAgICAvKiBEb2VzIHRoaXMgdHJhbnNpdGlvbiBtYXRjaCB0aGUgaW5wdXQgc3ltYm9sPyAqLwoJICAgICAgaWYgKHRyYW5zX2ktPmNvZGVfbWluIDw9ICh0cmVfY2ludF90KXByZXZfYyAmJgoJCSAgdHJhbnNfaS0+Y29kZV9tYXggPj0gKHRyZV9jaW50X3QpcHJldl9jKQoJCXsKCQkgIGlmICh0cmFuc19pLT5hc3NlcnRpb25zCgkJICAgICAgJiYgKENIRUNLX0FTU0VSVElPTlModHJhbnNfaS0+YXNzZXJ0aW9ucykKCQkJICB8fCBDSEVDS19DSEFSX0NMQVNTRVModHJhbnNfaSwgdG5mYSwgZWZsYWdzKSkpCgkJICAgIHsKCQkgICAgICBEUFJJTlQoKCJhc3NlcnRpb24gZmFpbGVkXG4iKSk7CgkJICAgICAgY29udGludWU7CgkJICAgIH0KCgkJICAvKiBDb21wdXRlIHRoZSB0YWdzIGFmdGVyIHRoaXMgdHJhbnNpdGlvbi4gKi8KCQkgIGZvciAoaSA9IDA7IGkgPCBudW1fdGFnczsgaSsrKQoJCSAgICB0bXBfdGFnc1tpXSA9IHJlYWNoX2ktPnRhZ3NbaV07CgkJICB0YWdfaSA9IHRyYW5zX2ktPnRhZ3M7CgkJICBpZiAodGFnX2kgIT0gTlVMTCkKCQkgICAgd2hpbGUgKCp0YWdfaSA+PSAwKQoJCSAgICAgIHsKCQkJaWYgKCp0YWdfaSA8IG51bV90YWdzKQoJCQkgIHRtcF90YWdzWyp0YWdfaV0gPSBwb3M7CgkJCXRhZ19pKys7CgkJICAgICAgfQoKCQkgIGlmIChyZWFjaF9wb3NbdHJhbnNfaS0+c3RhdGVfaWRdLnBvcyA8IHBvcykKCQkgICAgewoJCSAgICAgIC8qIEZvdW5kIGFuIHVudmlzaXRlZCBub2RlLiAqLwoJCSAgICAgIHJlYWNoX25leHRfaS0+c3RhdGUgPSB0cmFuc19pLT5zdGF0ZTsKCQkgICAgICB0bXBfaXB0ciA9IHJlYWNoX25leHRfaS0+dGFnczsKCQkgICAgICByZWFjaF9uZXh0X2ktPnRhZ3MgPSB0bXBfdGFnczsKCQkgICAgICB0bXBfdGFncyA9IHRtcF9pcHRyOwoJCSAgICAgIHJlYWNoX3Bvc1t0cmFuc19pLT5zdGF0ZV9pZF0ucG9zID0gcG9zOwoJCSAgICAgIHJlYWNoX3Bvc1t0cmFuc19pLT5zdGF0ZV9pZF0udGFncyA9ICZyZWFjaF9uZXh0X2ktPnRhZ3M7CgoJCSAgICAgIGlmIChyZWFjaF9uZXh0X2ktPnN0YXRlID09IHRuZmEtPmZpbmFsCgkJCSAgJiYgKG1hdGNoX2VvID09IC0xCgkJCSAgICAgIHx8IChudW1fdGFncyA+IDAKCQkJCSAgJiYgcmVhY2hfbmV4dF9pLT50YWdzWzBdIDw9IG1hdGNoX3RhZ3NbMF0pKSkKCQkJewoJCQkgIERQUklOVCgoIiAgZm91bmQgbWF0Y2ggJXBcbiIsIHRyYW5zX2ktPnN0YXRlKSk7CgkJCSAgbWF0Y2hfZW8gPSBwb3M7CgkJCSAgbmV3X21hdGNoID0gMTsKCQkJICBmb3IgKGkgPSAwOyBpIDwgbnVtX3RhZ3M7IGkrKykKCQkJICAgIG1hdGNoX3RhZ3NbaV0gPSByZWFjaF9uZXh0X2ktPnRhZ3NbaV07CgkJCX0KCQkgICAgICByZWFjaF9uZXh0X2krKzsKCgkJICAgIH0KCQkgIGVsc2UKCQkgICAgewoJCSAgICAgIGFzc2VydChyZWFjaF9wb3NbdHJhbnNfaS0+c3RhdGVfaWRdLnBvcyA9PSBwb3MpOwoJCSAgICAgIC8qIEFub3RoZXIgcGF0aCBoYXMgYWxzbyByZWFjaGVkIHRoaXMgc3RhdGUuICBXZSBjaG9vc2UKCQkJIHRoZSB3aW5uZXIgYnkgZXhhbWluaW5nIHRoZSB0YWcgdmFsdWVzIGZvciBib3RoCgkJCSBwYXRocy4gKi8KCQkgICAgICBpZiAodHJlX3RhZ19vcmRlcihudW1fdGFncywgdG5mYS0+dGFnX2RpcmVjdGlvbnMsCgkJCQkJdG1wX3RhZ3MsCgkJCQkJKnJlYWNoX3Bvc1t0cmFuc19pLT5zdGF0ZV9pZF0udGFncykpCgkJCXsKCQkJICAvKiBUaGUgbmV3IHBhdGggd2lucy4gKi8KCQkJICB0bXBfaXB0ciA9ICpyZWFjaF9wb3NbdHJhbnNfaS0+c3RhdGVfaWRdLnRhZ3M7CgkJCSAgKnJlYWNoX3Bvc1t0cmFuc19pLT5zdGF0ZV9pZF0udGFncyA9IHRtcF90YWdzOwoJCQkgIGlmICh0cmFuc19pLT5zdGF0ZSA9PSB0bmZhLT5maW5hbCkKCQkJICAgIHsKCQkJICAgICAgRFBSSU5UKCgiCSBmb3VuZCBiZXR0ZXIgbWF0Y2hcbiIpKTsKCQkJICAgICAgbWF0Y2hfZW8gPSBwb3M7CgkJCSAgICAgIG5ld19tYXRjaCA9IDE7CgkJCSAgICAgIGZvciAoaSA9IDA7IGkgPCBudW1fdGFnczsgaSsrKQoJCQkJbWF0Y2hfdGFnc1tpXSA9IHRtcF90YWdzW2ldOwoJCQkgICAgfQoJCQkgIHRtcF90YWdzID0gdG1wX2lwdHI7CgkJCX0KCQkgICAgfQoJCX0KCSAgICB9Cgl9CiAgICAgIHJlYWNoX25leHRfaS0+c3RhdGUgPSBOVUxMOwogICAgfQoKICBEUFJJTlQoKCJtYXRjaCBlbmQgb2Zmc2V0ID0gJWRcbiIsIG1hdGNoX2VvKSk7CgojaWZuZGVmIFRSRV9VU0VfQUxMT0NBCiAgaWYgKGJ1ZikKICAgIHhmcmVlKGJ1Zik7CiNlbmRpZiAvKiAhVFJFX1VTRV9BTExPQ0EgKi8KCiAgKm1hdGNoX2VuZF9vZnMgPSBtYXRjaF9lbzsKICByZXR1cm4gbWF0Y2hfZW8gPj0gMCA/IFJFR19PSyA6IFJFR19OT01BVENIOwp9CgovKiBFT0YgKi8K