LyogJFhGcmVlODYkICovIC8qIC0qLSBtb2RlOiBjOyBjLWJhc2ljLW9mZnNldDogMyAtKi0gKi8KLyoKICogTWVzYSAzLUQgZ3JhcGhpY3MgbGlicmFyeQogKiBWZXJzaW9uOiAgMy41CiAqCiAqIENvcHlyaWdodCAoQykgMTk5OS0yMDAxICBCcmlhbiBQYXVsICAgQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICoKICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEKICogY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwKICogdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbgogKiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwKICogYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlCiAqIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CiAqCiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkCiAqIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgogKgogKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUwogKiBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gIElOIE5PIEVWRU5UIFNIQUxMCiAqIEJSSUFOIFBBVUwgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOCiAqIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOCiAqIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuCiAqCiAqIE9yaWdpbmFsIGF1dGhvcnM6CiAqICAgIEtlaXRoIFdoaXR3ZWxsIDxrZWl0aHdAdmFsaW51eC5jb20+CiAqCiAqIEFkYXB0ZWQgdG8gTWFjaDY0IGJ5OgogKiAgICBKb3PpIEZvbnNlY2EgPGpfcl9mb25zZWNhQHlhaG9vLmNvLnVrPgogKi8KCiNpbmNsdWRlICJtYXRoL21fdHJhbnNsYXRlLmgiCgojaWZuZGVmIExPQ0FMVkFSUwojZGVmaW5lIExPQ0FMVkFSUwojZW5kaWYKCnZvaWQgVEFHKHRyYW5zbGF0ZV92ZXJ0ZXgpKEdMY29udGV4dCAqY3R4LAoJCQkgICBjb25zdCBWRVJURVggKnNyYywKCQkJICAgU1d2ZXJ0ZXggKmRzdCkKewogICBMT0NBTFZBUlMKICAgR0x1aW50IGZvcm1hdCA9IEdFVF9WRVJURVhfRk9STUFUKCk7CiAgIFVOVklFV1BPUlRfVkFSUzsKICAgQ0FSRDMyICpwID0gKENBUkQzMiAqKXNyYyArIDEwIC0gbW1lc2EtPnZlcnRleF9zaXplOwoKICAgZHN0LT5hdHRyaWJbRlJBR19BVFRSSUJfV1BPU11bM10gPSAxLjA7CiAgIAogICBzd2l0Y2ggKCBmb3JtYXQgKSB7CiAgICAgIGNhc2UgVEVYMV9WRVJURVhfRk9STUFUOgojaWZkZWYgTUFDSDY0X1BSRU1VTFRfVEVYQ09PUkRTCgkgewoJICAgIGZsb2F0IHJodyA9IDEuMCAvIExFMzJfSU5fRkxPQVQoIHAgKyAyICk7CgkgICAgCgkgICAgZHN0LT5hdHRyaWJbRlJBR19BVFRSSUJfVEVYMV1bMF0gPSByaHcqTEUzMl9JTl9GTE9BVCggcCsrICk7CgkgICAgZHN0LT5hdHRyaWJbRlJBR19BVFRSSUJfVEVYMV1bMV0gPSByaHcqTEUzMl9JTl9GTE9BVCggcCsrICk7CgkgfQojZWxzZQoJIGRzdC0+YXR0cmliW0ZSQUdfQVRUUklCX1RFWDFdWzBdID0gTEUzMl9JTl9GTE9BVCggcCsrICk7CgkgZHN0LT5hdHRyaWJbRlJBR19BVFRSSUJfVEVYMV1bMV0gPSBMRTMyX0lOX0ZMT0FUKCBwKysgKTsKI2VuZGlmCgkgZHN0LT5hdHRyaWJbRlJBR19BVFRSSUJfVEVYMV1bM10gPSAxLjA7CgkgcCsrOwoKICAgICAgY2FzZSBURVgwX1ZFUlRFWF9GT1JNQVQ6CiNpZmRlZiBNQUNINjRfUFJFTVVMVF9URVhDT09SRFMKCSB7CgkgICAgZmxvYXQgcmh3ID0gMS4wIC8gTEUzMl9JTl9GTE9BVCggcCArIDIgKTsKCSAgICAKCSAgICBkc3QtPmF0dHJpYltGUkFHX0FUVFJJQl9URVgwXVswXSA9IHJodypMRTMyX0lOX0ZMT0FUKCBwKysgKTsKCSAgICBkc3QtPmF0dHJpYltGUkFHX0FUVFJJQl9URVgwXVsxXSA9IHJodypMRTMyX0lOX0ZMT0FUKCBwKysgKTsKCSB9CiNlbHNlCgkgZHN0LT5hdHRyaWJbRlJBR19BVFRSSUJfVEVYMF1bMF0gPSBMRTMyX0lOX0ZMT0FUKCBwKysgKTsKCSBkc3QtPmF0dHJpYltGUkFHX0FUVFJJQl9URVgwXVsxXSA9IExFMzJfSU5fRkxPQVQoIHArKyApOwojZW5kaWYKCSBkc3QtPmF0dHJpYltGUkFHX0FUVFJJQl9URVgwXVszXSA9IDEuMDsKCSBkc3QtPmF0dHJpYltGUkFHX0FUVFJJQl9XUE9TXVszXSA9IExFMzJfSU5fRkxPQVQoIHArKyApOwoJCiAgICAgIGNhc2UgTk9URVhfVkVSVEVYX0ZPUk1BVDoKCSBkc3QtPmF0dHJpYltGUkFHX0FUVFJJQl9DT0wxXVsyXSA9IFVCWVRFX1RPX0ZMT0FUKCgoR0x1Ynl0ZSAqKXApWzBdKTsKCSBkc3QtPmF0dHJpYltGUkFHX0FUVFJJQl9DT0wxXVsxXSA9IFVCWVRFX1RPX0ZMT0FUKCgoR0x1Ynl0ZSAqKXApWzFdKTsKCSBkc3QtPmF0dHJpYltGUkFHX0FUVFJJQl9DT0wxXVswXSA9IFVCWVRFX1RPX0ZMT0FUKCgoR0x1Ynl0ZSAqKXApWzJdKTsKCSBkc3QtPmF0dHJpYltGUkFHX0FUVFJJQl9GT0dDXVswXSA9ICgoR0x1Ynl0ZSAqKXApWzNdOyAvKlhYWCBpbnQtPmZsb2F0PyovCgkgcCsrOwoKICAgICAgY2FzZSBUSU5ZX1ZFUlRFWF9GT1JNQVQ6CgkgZHN0LT5hdHRyaWJbRlJBR19BVFRSSUJfV1BPU11bMl0gPSBVTlZJRVdQT1JUX1ooIExFMzJfSU4oIHArKyApICk7CgoJIGRzdC0+Y29sb3JbMl0gPSAoKEdMdWJ5dGUgKilwKVswXTsKCSBkc3QtPmNvbG9yWzFdID0gKChHTHVieXRlICopcClbMV07CgkgZHN0LT5jb2xvclswXSA9ICgoR0x1Ynl0ZSAqKXApWzJdOwoJIGRzdC0+Y29sb3JbM10gPSAoKEdMdWJ5dGUgKilwKVszXTsKCSBwKys7CgkgCgkgewoJICAgIEdMdWludCB4eSA9IExFMzJfSU4oIHAgKTsKCSAgICAKCSAgICBkc3QtPmF0dHJpYltGUkFHX0FUVFJJQl9XUE9TXVswXSA9IFVOVklFV1BPUlRfWCggKEdMZmxvYXQpKEdMc2hvcnQpKCB4eSA+PiAxNiApICk7CgkgICAgZHN0LT5hdHRyaWJbRlJBR19BVFRSSUJfV1BPU11bMV0gPSBVTlZJRVdQT1JUX1koIChHTGZsb2F0KShHTHNob3J0KSggeHkgJiAweGZmZmYgKSApOwoJIH0KICAgfQoKICAgYXNzZXJ0KCBwICsgMSAtIChDQVJEMzIgKilzcmMgPT0gMTAgKTsKCSAKICAgZHN0LT5wb2ludFNpemUgPSBjdHgtPlBvaW50LlNpemU7Cn0KCgoKdm9pZCBUQUcocHJpbnRfdmVydGV4KSggR0xjb250ZXh0ICpjdHgsIGNvbnN0IFZFUlRFWCAqdiApCnsKICAgTE9DQUxWQVJTCiAgIEdMdWludCBmb3JtYXQgPSBHRVRfVkVSVEVYX0ZPUk1BVCgpOwogICBDQVJEMzIgKnAgPSAoQ0FSRDMyICopdiArIDEwIC0gbW1lc2EtPnZlcnRleF9zaXplOwogICAKICAgc3dpdGNoICggZm9ybWF0ICkgewogICAgICBjYXNlIFRFWDFfVkVSVEVYX0ZPUk1BVDoKCSB7CgkgICAgR0xmbG9hdCB1LCB2LCB3OwojaWZkZWYgTUFDSDY0X1BSRU1VTFRfVEVYQ09PUkRTCgkgICAgZmxvYXQgcmh3ID0gMS4wIC8gTEUzMl9JTl9GTE9BVCggcCArIDIgKTsKCSAgICAKCSAgICB1ID0gcmh3KkxFMzJfSU5fRkxPQVQoIHArKyApOwoJICAgIHYgPSByaHcqTEUzMl9JTl9GTE9BVCggcCsrICk7CiNlbHNlCgkgICAgdSA9IExFMzJfSU5fRkxPQVQoIHArKyApOwoJICAgIHYgPSBMRTMyX0lOX0ZMT0FUKCBwKysgKTsKI2VuZGlmCgkgICAgdyA9IExFMzJfSU5fRkxPQVQoIHArKyApOwoJICAgIGZwcmludGYoIHN0ZGVyciwgInUxICVmIHYxICVmIHcxICVmXG4iLCB1LCB2LCB3ICk7CgkgfQoKICAgICAgY2FzZSBURVgwX1ZFUlRFWF9GT1JNQVQ6CgkgewoJICAgIEdMZmxvYXQgdSwgdiwgdzsKI2lmZGVmIE1BQ0g2NF9QUkVNVUxUX1RFWENPT1JEUwoJICAgIGZsb2F0IHJodyA9IDEuMCAvIExFMzJfSU5fRkxPQVQoIHAgKyAyICk7CgkgICAgCgkgICAgdSA9IHJodypMRTMyX0lOX0ZMT0FUKCBwKysgKTsKCSAgICB2ID0gcmh3KkxFMzJfSU5fRkxPQVQoIHArKyApOwojZWxzZQoJICAgIHUgPSBMRTMyX0lOX0ZMT0FUKCBwKysgKTsKCSAgICB2ID0gTEUzMl9JTl9GTE9BVCggcCsrICk7CiNlbmRpZgoJICAgIHcgPSBMRTMyX0lOX0ZMT0FUKCBwKysgKTsKCSAgICBmcHJpbnRmKCBzdGRlcnIsICJ1MCAlZiB2MCAlZiB3MCAlZlxuIiwgdSwgdiwgdyApOwoJIH0KCQogICAgICBjYXNlIE5PVEVYX1ZFUlRFWF9GT1JNQVQ6CgkgewoJICAgIEdMdWJ5dGUgciwgZywgYiwgYTsKCSAgICAKCSAgICBiID0gKChHTHVieXRlICopcClbMF07CgkgICAgZyA9ICgoR0x1Ynl0ZSAqKXApWzFdOwoJICAgIHIgPSAoKEdMdWJ5dGUgKilwKVsyXTsKCSAgICBhID0gKChHTHVieXRlICopcClbM107CgkgICAgcCsrOwoJICAgIGZwcmludGYoc3RkZXJyLCAic3BlYzogciAlZCBnICVkIGIgJWQgYSAlZFxuIiwgciwgZywgYiwgYSk7CgkgfQoKICAgICAgY2FzZSBUSU5ZX1ZFUlRFWF9GT1JNQVQ6CgkgewoJICAgIEdMdWludCB4eTsKCSAgICBHTGZsb2F0IHgsIHksIHo7CgkgICAgR0x1Ynl0ZSByLCBnLCBiLCBhOwoJICAgIAoJICAgIHogPSBMRTMyX0lOKCBwKysgKSAvIDY1NTM2LjA7CgoJICAgIGIgPSAoKEdMdWJ5dGUgKilwKVswXTsKCSAgICBnID0gKChHTHVieXRlICopcClbMV07CgkgICAgciA9ICgoR0x1Ynl0ZSAqKXApWzJdOwoJICAgIGEgPSAoKEdMdWJ5dGUgKilwKVszXTsKCSAgICBwKys7CgkgICAgeHkgPSBMRTMyX0lOKCBwICk7CgkgICAgeCA9IChHTGZsb2F0KShHTHNob3J0KSggeHkgPj4gMTYgKSAvIDQuMDsKCSAgICB5ID0gKEdMZmxvYXQpKEdMc2hvcnQpKCB4eSAmIDB4ZmZmZiApIC8gNC4wOwoJICAgIAoJICAgIGZwcmludGYoc3RkZXJyLCAieCAlZiB5ICVmIHogJWZcbiIsIHgsIHksIHopOwoJICAgIGZwcmludGYoc3RkZXJyLCAiciAlZCBnICVkIGIgJWQgYSAlZFxuIiwgciwgZywgYiwgYSk7CgkgfQogICB9CiAgIAogICBhc3NlcnQoIHAgKyAxIC0gKENBUkQzMiAqKXYgPT0gMTAgKTsJIAoKICAgZnByaW50ZihzdGRlcnIsICJcbiIpOwp9CgovKiBJbnRlcnBvbGF0ZSB0aGUgZWxlbWVudHMgb2YgdGhlIFZCIG5vdCBpbmNsdWRlZCBpbiB0eXBpY2FsIGhhcmR3YXJlCiAqIHZlcnRpY2VzLiAgCiAqCiAqIE5PVEU6IEFsbCB0aGVzZSBhcnJheXMgYXJlIGd1YXJlbnRlZWQgYnkgdG5sIHRvIGJlIHdyaXRlYWJsZSBhbmQKICogaGF2ZSBnb29kIHN0cmlkZS4KICovCiNpZm5kZWYgSU5URVJQX1FVQUxJRklFUiAKI2RlZmluZSBJTlRFUlBfUVVBTElGSUVSIHN0YXRpYwojZW5kaWYKCiNkZWZpbmUgR0VUX0NPTE9SKHB0ciwgaWR4KSAoKHB0ciktPmRhdGFbaWR4XSkKCgpJTlRFUlBfUVVBTElGSUVSIHZvaWQgVEFHKGludGVycF9leHRyYXMpKCBHTGNvbnRleHQgKmN0eCwKCQkJCQkgIEdMZmxvYXQgdCwKCQkJCQkgIEdMdWludCBkc3QsIEdMdWludCBvdXQsIEdMdWludCBpbiwKCQkJCQkgIEdMYm9vbGVhbiBmb3JjZV9ib3VuZGFyeSApCnsKICAgTE9DQUxWQVJTCiAgIHN0cnVjdCB2ZXJ0ZXhfYnVmZmVyICpWQiA9ICZUTkxfQ09OVEVYVChjdHgpLT52YjsKCiAgIGlmIChWQi0+Q29sb3JQdHJbMV0pIHsKICAgICAgYXNzZXJ0KFZCLT5Db2xvclB0clsxXS0+c3RyaWRlID09IDQgKiBzaXplb2YoR0xmbG9hdCkpOwogICAgICAKICAgICAgSU5URVJQXzRGKCB0LAoJCSAgICBHRVRfQ09MT1IoVkItPkNvbG9yUHRyWzFdLCBkc3QpLAoJCSAgICBHRVRfQ09MT1IoVkItPkNvbG9yUHRyWzFdLCBvdXQpLAoJCSAgICBHRVRfQ09MT1IoVkItPkNvbG9yUHRyWzFdLCBpbikgKTsKCiAgICAgIGlmIChWQi0+U2Vjb25kYXJ5Q29sb3JQdHJbMV0pIHsKCSBJTlRFUlBfM0YoIHQsCgkJICAgICAgIEdFVF9DT0xPUihWQi0+U2Vjb25kYXJ5Q29sb3JQdHJbMV0sIGRzdCksCgkJICAgICAgIEdFVF9DT0xPUihWQi0+U2Vjb25kYXJ5Q29sb3JQdHJbMV0sIG91dCksCgkJICAgICAgIEdFVF9DT0xPUihWQi0+U2Vjb25kYXJ5Q29sb3JQdHJbMV0sIGluKSApOwogICAgICB9CiAgIH0KCiAgIGlmIChWQi0+RWRnZUZsYWcpIHsKICAgICAgVkItPkVkZ2VGbGFnW2RzdF0gPSBWQi0+RWRnZUZsYWdbb3V0XSB8fCBmb3JjZV9ib3VuZGFyeTsKICAgfQoKICAgSU5URVJQX1ZFUlRFWChjdHgsIHQsIGRzdCwgb3V0LCBpbiwgZm9yY2VfYm91bmRhcnkpOwp9CgpJTlRFUlBfUVVBTElGSUVSIHZvaWQgVEFHKGNvcHlfcHZfZXh0cmFzKSggR0xjb250ZXh0ICpjdHgsIAoJCQkJCSAgIEdMdWludCBkc3QsIEdMdWludCBzcmMgKQp7CiAgIExPQ0FMVkFSUwogICAgICBzdHJ1Y3QgdmVydGV4X2J1ZmZlciAqVkIgPSAmVE5MX0NPTlRFWFQoY3R4KS0+dmI7CgogICBpZiAoVkItPkNvbG9yUHRyWzFdKSB7CiAgICAgIENPUFlfNEZWKCBHRVRfQ09MT1IoVkItPkNvbG9yUHRyWzFdLCBkc3QpLCAKCQlHRVRfQ09MT1IoVkItPkNvbG9yUHRyWzFdLCBzcmMpICk7CgogICAgICBpZiAoVkItPlNlY29uZGFyeUNvbG9yUHRyWzFdKSB7CgkgQ09QWV80RlYoIEdFVF9DT0xPUihWQi0+U2Vjb25kYXJ5Q29sb3JQdHJbMV0sIGRzdCksIAoJCSAgIEdFVF9DT0xPUihWQi0+U2Vjb25kYXJ5Q29sb3JQdHJbMV0sIHNyYykgKTsKICAgICAgfQogICB9CgogICBDT1BZX1BWX1ZFUlRFWChjdHgsIGRzdCwgc3JjKTsKfQoKCiN1bmRlZiBJTlRFUlBfUVVBTElGSUVSCiN1bmRlZiBHRVRfQ09MT1IKCiN1bmRlZiBJTkQKI3VuZGVmIFRBRwo=