LyogUmV0dXJuIGRpZSBhdCBnaXZlbiBvZmZzZXQuCiAgIENvcHlyaWdodCAoQykgMjAwMCwgMjAwMiBSZWQgSGF0LCBJbmMuCiAgIFdyaXR0ZW4gYnkgVWxyaWNoIERyZXBwZXIgPGRyZXBwZXJAcmVkaGF0LmNvbT4sIDIwMDAuCgogICBUaGlzIHByb2dyYW0gaXMgT3BlbiBTb3VyY2Ugc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogICBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBPcGVuIFNvZnR3YXJlIExpY2Vuc2UgdmVyc2lvbiAxLjAgYXMKICAgcHVibGlzaGVkIGJ5IHRoZSBPcGVuIFNvdXJjZSBJbml0aWF0aXZlLgoKICAgWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgT3BlbiBTb2Z0d2FyZSBMaWNlbnNlIGFsb25nCiAgIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgT3BlbiBTb2Z0d2FyZQogICBMaWNlbnNlIHZlcnNpb24gMS4wIGZyb20gaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9vc2wucGhwIG9yCiAgIGJ5IHdyaXRpbmcgdGhlIE9wZW4gU291cmNlIEluaXRpYXRpdmUgYy9vIExhd3JlbmNlIFJvc2VuLCBFc3EuLAogICAzMDAxIEtpbmcgUmFuY2ggUm9hZCwgVWtpYWgsIENBIDk1NDgyLiAgICovCgojaWZkZWYgSEFWRV9DT05GSUdfSAojIGluY2x1ZGUgPGNvbmZpZy5oPgojZW5kaWYKCiNpbmNsdWRlIDxkd2FyZi5oPgojaW5jbHVkZSA8c3RkbGliLmg+CgojaW5jbHVkZSA8bGliZHdhcmZQLmg+CgoKLyogWFhYIFRoaXMgZnVuY3Rpb24gd2lsbCBoYXZlIHRvIGJlIG9wdGltaXplZC4gIFRoZSBzZWFyY2ggaXMgdG9vIGxpbmVhcgogICB0byBiZSBwZXJmb3JtZWQgdG9vIG9mdGVuIC0+IE8obrIpLiAgKi8Kc3RhdGljIER3YXJmX0NVX0luZm8KZmluZF9jdSAoRHdhcmZfRGVidWcgZGJnLCBEd2FyZl9PZmYgb2Zmc2V0LCBEd2FyZl9FcnJvciAqZXJyb3IpCnsKICBEd2FyZl9DVV9JbmZvIGN1OwogIER3YXJmX1dvcmQgY3Vfb2Zmc2V0OwoKICAvKiBTZWFyY2ggaW4gdGhlIENVcyBhbHJlYWR5IGtub3duLiAgKi8KICBmb3IgKGN1ID0gZGJnLT5jdV9saXN0OyBjdSAhPSBOVUxMOyBjdSA9IGN1LT5uZXh0KQogICAgaWYgKGN1LT5vZmZzZXQgPD0gb2Zmc2V0CgkmJiBjdS0+b2Zmc2V0ICsgMiAqIGN1LT5vZmZzZXRfc2l6ZSAtIDQgKyBjdS0+bGVuZ3RoID4gb2Zmc2V0KQogICAgICByZXR1cm4gY3U7CgogIC8qIFRoZSBDVSBpcyBub3QgeWV0IGxvYWRlZC4gIERvIHRoaXMgbm93LiAgKi8KICBpZiAoZGJnLT5jdV9saXN0X3RhaWwgPT0gTlVMTCkKICAgIGN1X29mZnNldCA9IDA7CiAgZWxzZQogICAgY3Vfb2Zmc2V0ID0gKGRiZy0+Y3VfbGlzdF90YWlsLT5vZmZzZXQKCQkgKyAyICogZGJnLT5jdV9saXN0X3RhaWwtPm9mZnNldF9zaXplIC0gNAoJCSArIGRiZy0+Y3VfbGlzdF90YWlsLT5sZW5ndGgpOwoKICB3aGlsZSAoMSkKICAgIHsKICAgICAgLyogR2V0IG5leHQgQ1UgYW5kIGFkZCBpdCB0byB0aGUgZW5kIG9mIHRoZSBsaXN0LiAgKi8KICAgICAgaWYgKF9fbGliZHdhcmZfZ2V0X2N1X2F0X29mZnNldCAoZGJnLCBjdV9vZmZzZXQsICZjdSwgZXJyb3IpCgkgICE9IERXX0RMVl9PSykKCXJldHVybiBOVUxMOwoKICAgICAgLyogT2Zmc2V0IG9mIG5leHQgQ1UuICAqLwogICAgICBjdV9vZmZzZXQgKz0gMiAqIGN1LT5vZmZzZXRfc2l6ZSAtIDQgKyBjdS0+bGVuZ3RoOwoKICAgICAgLyogSWYgdGhpcyB0aGUgQ1Ugd2UgYXJlIGxvb2tpbmcgZm9yPyAgKi8KICAgICAgaWYgKG9mZnNldCA8IGN1X29mZnNldCkKCXJldHVybiBjdTsKICAgIH0KfQoKCmludApkd2FyZl9vZmZkaWUgKGRiZywgb2Zmc2V0LCByZXR1cm5fZGllLCBlcnJvcikKICAgICBEd2FyZl9EZWJ1ZyBkYmc7CiAgICAgRHdhcmZfT2ZmIG9mZnNldDsKICAgICBEd2FyZl9EaWUgKnJldHVybl9kaWU7CiAgICAgRHdhcmZfRXJyb3IgKmVycm9yOwp7CiAgRHdhcmZfQ1VfSW5mbyBjdTsKICBEd2FyZl9EaWUgbmV3X2RpZTsKICBEd2FyZl9TbWFsbCAqZGllX2FkZHI7CiAgRHdhcmZfV29yZCB1MTI4OwoKICBpZiAob2Zmc2V0ID49IGRiZy0+c2VjdGlvbnNbSURYX2RlYnVnX2luZm9dLnNpemUpCiAgICB7CiAgICAgIC8qIENvbXBsZXRlbHkgb3V0IG9mIGJvdW5kcy4gICovCiAgICAgIF9fbGliZHdhcmZfZXJyb3IgKGRiZywgZXJyb3IsIERXX0VfSU5WQUxJRF9PRkZTRVQpOwogICAgICByZXR1cm4gRFdfRExWX0VSUk9SOwogICAgfQoKICAvKiBGaW5kIHRoZSBjb21waWxlIHVuaXQgdGhpcyBhZGRyZXNzIGJlbG9uZ3MgdG8uICAqLwogIGN1ID0gZmluZF9jdSAoZGJnLCBvZmZzZXQsIGVycm9yKTsKICBpZiAoY3UgPT0gTlVMTCkKICAgIHJldHVybiBEV19ETFZfRVJST1I7CgogIC8qIENyZWF0YSBhIG5ldyBkaWUuICAqLwogIG5ld19kaWUgPSAoRHdhcmZfRGllKSBtYWxsb2MgKHNpemVvZiAoc3RydWN0IER3YXJmX0RpZV9zKSk7CiAgaWYgKG5ld19kaWUgPT0gTlVMTCkKICAgIHsKICAgICAgX19saWJkd2FyZl9lcnJvciAoZGJnLCBlcnJvciwgRFdfRV9OT01FTSk7CiAgICAgIHJldHVybiBEV19ETFZfRVJST1I7CiAgICB9CgojaWZkZWYgRFdBUkZfREVCVUcKICBuZXdfZGllLT5tZW10YWcgPSBEV19ETEFfRElFOwojZW5kaWYKCiAgLyogUmVtZW1iZXIgdGhlIGFkZHJlc3MuICAqLwogIGRpZV9hZGRyID0gKER3YXJmX1NtYWxsICopIGRiZy0+c2VjdGlvbnNbSURYX2RlYnVnX2luZm9dLmFkZHIgKyBvZmZzZXQ7CiAgbmV3X2RpZS0+YWRkciA9IGRpZV9hZGRyOwoKICAvKiBBbmQgdGhlIGNvbXBpbGUgdW5pdC4gICovCiAgbmV3X2RpZS0+Y3UgPSBjdTsKCiAgLyogNy41LjIgIERlYnVnZ2luZyBJbmZvcm1hdGlvbiBFbnRyeQoKICAgICBFYWNoIGRlYnVnZ2luZyBpbmZvcm1hdGlvbiBlbnRyeSBiZWdpbnMgd2l0aCBhbiB1bnNpZ25lZCBMRUIxMjgKICAgICBudW1iZXIgY29udGFpbmluZyB0aGUgYWJicmV2aWF0aW9uIGNvZGUgZm9yIHRoZSBlbnRyeS4gICovCiAgZ2V0X3VsZWIxMjggKHUxMjgsIGRpZV9hZGRyKTsKCiAgLyogRmluZCB0aGUgYWJicmV2aWF0aW9uLiAgKi8KICBuZXdfZGllLT5hYmJyZXYgPSBfX2xpYmR3YXJmX2dldF9hYmJyZXYgKGRiZywgY3UsIHUxMjgsIGVycm9yKTsKICBpZiAobmV3X2RpZS0+YWJicmV2ID09IE5VTEwpCiAgICB7CiAgICAgIGZyZWUgKG5ld19kaWUpOwogICAgICByZXR1cm4gRFdfRExWX0VSUk9SOwogICAgfQoKICAqcmV0dXJuX2RpZSA9IG5ld19kaWU7CiAgcmV0dXJuIERXX0RMVl9PSzsKfQo=