LyoKICogIFRDUCBNSUIgZ3JvdXAgVGFibGUgaW1wbGVtZW50YXRpb24gLSB0Y3BUYWJsZS5jCiAqCiAqLwoKLyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IKkgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtY29uZmlnLmg+CiNpbmNsdWRlICJtaWJJSV9jb21tb24uaCIKCiNpZiBIQVZFX05FVElORVRfVENQX0gKI2luY2x1ZGUgPG5ldGluZXQvdGNwLmg+CiNlbmRpZgojaWYgSEFWRV9ORVRJTkVUX1RDUF9USU1FUl9ICiNpbmNsdWRlIDxuZXRpbmV0L3RjcF90aW1lci5oPgojZW5kaWYKI2lmIEhBVkVfTkVUSU5FVF9UQ1BJUF9ICiNpbmNsdWRlIDxuZXRpbmV0L3RjcGlwLmg+CiNlbmRpZgojaWYgSEFWRV9ORVRJTkVUX1RDUF9WQVJfSAojaW5jbHVkZSA8bmV0aW5ldC90Y3BfdmFyLmg+CiNlbmRpZgojaWYgSEFWRV9ORVRMSU5LX05FVExJTktfSAojaW5jbHVkZSA8bmV0bGluay9uZXRsaW5rLmg+CiNpbmNsdWRlIDxuZXRsaW5rL21zZy5oPgojaW5jbHVkZSA8bGludXgvaW5ldF9kaWFnLmg+CiNlbmRpZgoKI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWluY2x1ZGVzLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9uZXQtc25tcC1hZ2VudC1pbmNsdWRlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvYXV0b19ubGlzdC5oPgoKI2luY2x1ZGUgInRjcC5oIgojaW5jbHVkZSAidGNwVGFibGUuaCIKCiNpZmRlZiBocHV4MTEKI2RlZmluZQlUQ1BUQUJMRV9FTlRSWV9UWVBFCW1pYl90Y3BDb25uRW50IAojZGVmaW5lCVRDUFRBQkxFX1NUQVRFCQlTdGF0ZSAKI2RlZmluZQlUQ1BUQUJMRV9MT0NBTEFERFJFU1MJTG9jYWxBZGRyZXNzIAojZGVmaW5lCVRDUFRBQkxFX0xPQ0FMUE9SVAlMb2NhbFBvcnQgCiNkZWZpbmUJVENQVEFCTEVfUkVNT1RFQUREUkVTUwlSZW1BZGRyZXNzIAojZGVmaW5lCVRDUFRBQkxFX1JFTU9URVBPUlQJUmVtUG9ydCAKI2RlZmluZQlUQ1BUQUJMRV9JU19UQUJMRQojZWxzZQoKI2lmZGVmIHNvbGFyaXMyCnR5cGVkZWYgc3RydWN0IG5ldHNubXBfdGNwQ29ubkVudHJ5X3MgbmV0c25tcF90Y3BDb25uRW50cnk7CnN0cnVjdCBuZXRzbm1wX3RjcENvbm5FbnRyeV9zIHsKICAgIG1pYjJfdGNwQ29ubkVudHJ5X3QgICBlbnRyeTsKICAgIG5ldHNubXBfdGNwQ29ubkVudHJ5ICppbnBfbmV4dDsKfTsKI2RlZmluZQlUQ1BUQUJMRV9FTlRSWV9UWVBFCW5ldHNubXBfdGNwQ29ubkVudHJ5CiNkZWZpbmUJVENQVEFCTEVfU1RBVEUJCWVudHJ5LnRjcENvbm5TdGF0ZSAKI2RlZmluZQlUQ1BUQUJMRV9MT0NBTEFERFJFU1MJZW50cnkudGNwQ29ubkxvY2FsQWRkcmVzcyAKI2RlZmluZQlUQ1BUQUJMRV9MT0NBTFBPUlQJZW50cnkudGNwQ29ubkxvY2FsUG9ydCAKI2RlZmluZQlUQ1BUQUJMRV9SRU1PVEVBRERSRVNTCWVudHJ5LnRjcENvbm5SZW1BZGRyZXNzIAojZGVmaW5lCVRDUFRBQkxFX1JFTU9URVBPUlQJZW50cnkudGNwQ29ublJlbVBvcnQgCiNkZWZpbmUJVENQVEFCTEVfSVNfTElOS0VEX0xJU1QKI2Vsc2UKCiNpZmRlZiBIQVZFX0lQSExQQVBJX0gKI2luY2x1ZGUgPGlwaGxwYXBpLmg+CiNkZWZpbmUJVENQVEFCTEVfRU5UUllfVFlQRQlNSUJfVENQUk9XCiNkZWZpbmUJVENQVEFCTEVfU1RBVEUJCWR3U3RhdGUgCiNkZWZpbmUJVENQVEFCTEVfTE9DQUxBRERSRVNTCWR3TG9jYWxBZGRyCiNkZWZpbmUJVENQVEFCTEVfTE9DQUxQT1JUCWR3TG9jYWxQb3J0IAojZGVmaW5lCVRDUFRBQkxFX1JFTU9URUFERFJFU1MJZHdSZW1vdGVBZGRyIAojZGVmaW5lCVRDUFRBQkxFX1JFTU9URVBPUlQJZHdSZW1vdGVQb3J0IAojZGVmaW5lCVRDUFRBQkxFX0lTX1RBQkxFCiNlbHNlCgojaWZkZWYgbGludXgKI2RlZmluZQlUQ1BUQUJMRV9FTlRSWV9UWVBFCXN0cnVjdCBpbnBjYiAKI2RlZmluZQlUQ1BUQUJMRV9TVEFURQkJaW5wX3N0YXRlIAojZGVmaW5lCVRDUFRBQkxFX0xPQ0FMQUREUkVTUwlpbnBfbGFkZHIuc19hZGRyIAojZGVmaW5lCVRDUFRBQkxFX0xPQ0FMUE9SVAlpbnBfbHBvcnQKI2RlZmluZQlUQ1BUQUJMRV9SRU1PVEVBRERSRVNTCWlucF9mYWRkci5zX2FkZHIgCiNkZWZpbmUJVENQVEFCTEVfUkVNT1RFUE9SVAlpbnBfZnBvcnQKI2RlZmluZQlUQ1BUQUJMRV9JU19MSU5LRURfTElTVAoKI2Vsc2UJCQkvKiBldmVyeXRoaW5nIGVsc2UgKi8KCnR5cGVkZWYgc3RydWN0IG5ldHNubXBfaW5wY2JfcyBuZXRzbm1wX2lucGNiOwpzdHJ1Y3QgbmV0c25tcF9pbnBjYl9zIHsKICAgIHN0cnVjdCBpbnBjYiAgICBwY2I7CiAgICBpbnQgICAgICAgICAgICAgc3RhdGU7CiAgICBuZXRzbm1wX2lucGNiICAqaW5wX25leHQ7Cn07CiN1bmRlZiBJTlBfTkVYVF9TWU1CT0wKI2RlZmluZSBJTlBfTkVYVF9TWU1CT0wJCWlucF9uZXh0CiNkZWZpbmUJVENQVEFCTEVfRU5UUllfVFlQRQluZXRzbm1wX2lucGNiIAojZGVmaW5lCVRDUFRBQkxFX1NUQVRFCQlzdGF0ZSAKI2RlZmluZQlUQ1BUQUJMRV9MT0NBTEFERFJFU1MJcGNiLmlucF9sYWRkci5zX2FkZHIgCiNkZWZpbmUJVENQVEFCTEVfTE9DQUxQT1JUCXBjYi5pbnBfbHBvcnQKI2RlZmluZQlUQ1BUQUJMRV9SRU1PVEVBRERSRVNTCXBjYi5pbnBfZmFkZHIuc19hZGRyIAojZGVmaW5lCVRDUFRBQkxFX1JFTU9URVBPUlQJcGNiLmlucF9mcG9ydAojZGVmaW5lCVRDUFRBQkxFX0lTX0xJTktFRF9MSVNUCgojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGxpbnV4ICovCiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogV0lOMzIgY3lnd2luICovCiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc29sYXJpczIgKi8KI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBocHV4MTEgKi8KCgkJCQkvKiBIZWFkIG9mIGxpbmtlZCBsaXN0LCBvciByb290IG9mIHRhYmxlICovClRDUFRBQkxFX0VOVFJZX1RZUEUJKnRjcF9oZWFkICA9IE5VTEw7CmludCAgICAgICAgICAgICAgICAgICAgICB0Y3Bfc2l6ZSAgPSAwOwkvKiBPbmx5IHVzZWQgZm9yIHRhYmxlLWJhc2VkIHN5c3RlbXMgKi8KaW50ICAgICAgICAgICAgICAgICAgICAgIHRjcF9lc3RhYiA9IDA7CgoKCS8qCgkgKgoJICogSW5pdGlhbGl6YXRpb24gYW5kIGhhbmRsZXIgcm91dGluZXMgYXJlIGNvbW1vbiB0byBhbGwgYXJjaGl0ZWN0dXJlcwoJICoKCSAqLwojaWZuZGVmIE1JQl9TVEFUU19DQUNIRV9USU1FT1VUCiNkZWZpbmUgTUlCX1NUQVRTX0NBQ0hFX1RJTUVPVVQJNQojZW5kaWYKI2lmbmRlZiBUQ1BfU1RBVFNfQ0FDSEVfVElNRU9VVAojZGVmaW5lIFRDUF9TVEFUU19DQUNIRV9USU1FT1VUCU1JQl9TVEFUU19DQUNIRV9USU1FT1VUCiNlbmRpZgoKI2lmIGRlZmluZWQoVENQX1BPUlRTX0lOX0hPU1RfT1JERVIpICYmIFRDUF9QT1JUU19JTl9IT1NUX09SREVSCiNkZWZpbmUgVENQX1BPUlRfVE9fSE9TVF9PUkRFUih4KSB4CiNlbHNlCiNkZWZpbmUgVENQX1BPUlRfVE9fSE9TVF9PUkRFUih4KSBudG9ocyh4KQojZW5kaWYKCnZvaWQKaW5pdF90Y3BUYWJsZSh2b2lkKQp7CiAgICBjb25zdCBvaWQgdGNwVGFibGVfb2lkW10gPSB7IFNOTVBfT0lEX01JQjIsIDYsIDEzIH07CgogICAgbmV0c25tcF90YWJsZV9yZWdpc3RyYXRpb25faW5mbyAqdGFibGVfaW5mbzsKICAgIG5ldHNubXBfaXRlcmF0b3JfaW5mbyAgICAgICAgICAgKmlpbmZvOwogICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAgICAqcmVnaW5mbzsKICAgIGludCByYzsKCiAgICBERUJVR01TR1RMKCgibWliSUkvdGNwVGFibGUiLCAiSW5pdGlhbGlzaW5nIFRDUCBUYWJsZVxuIikpOwogICAgLyoKICAgICAqIENyZWF0ZSB0aGUgdGFibGUgZGF0YSBzdHJ1Y3R1cmUsIGFuZCBkZWZpbmUgdGhlIGluZGV4aW5nLi4uLgogICAgICovCiAgICB0YWJsZV9pbmZvID0gU05NUF9NQUxMT0NfVFlQRURFRihuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvKTsKICAgIGlmICghdGFibGVfaW5mbykgewogICAgICAgIHJldHVybjsKICAgIH0KICAgIG5ldHNubXBfdGFibGVfaGVscGVyX2FkZF9pbmRleGVzKHRhYmxlX2luZm8sIEFTTl9JUEFERFJFU1MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fSU5URUdFUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9JUEFERFJFU1MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fSU5URUdFUiwgMCk7CiAgICB0YWJsZV9pbmZvLT5taW5fY29sdW1uID0gVENQQ09OTlNUQVRFOwogICAgdGFibGVfaW5mby0+bWF4X2NvbHVtbiA9IFRDUENPTk5SRU1PVEVQT1JUOwoKCiAgICAvKgogICAgICogLi4uLiBhbmQgaXRlcmF0aW9uIGluZm9ybWF0aW9uIC4uLi4KICAgICAqLwogICAgaWluZm8gICAgICA9IFNOTVBfTUFMTE9DX1RZUEVERUYobmV0c25tcF9pdGVyYXRvcl9pbmZvKTsKICAgIGlmICghaWluZm8pIHsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpaW5mby0+Z2V0X2ZpcnN0X2RhdGFfcG9pbnQgPSB0Y3BUYWJsZV9maXJzdF9lbnRyeTsKICAgIGlpbmZvLT5nZXRfbmV4dF9kYXRhX3BvaW50ICA9IHRjcFRhYmxlX25leHRfZW50cnk7CiAgICBpaW5mby0+dGFibGVfcmVnaW5mbyAgICAgICAgPSB0YWJsZV9pbmZvOwojaWYgZGVmaW5lZCAoV0lOMzIpIHx8IGRlZmluZWQgKGN5Z3dpbikKICAgIGlpbmZvLT5mbGFncyAgICAgICAgICAgICAgIHw9IE5FVFNOTVBfSVRFUkFUT1JfRkxBR19TT1JURUQ7CiNlbmRpZiAvKiBXSU4zMiB8fCBjeWd3aW4gKi8KCgogICAgLyoKICAgICAqIC4uLi4gYW5kIHJlZ2lzdGVyIHRoZSB0YWJsZSB3aXRoIHRoZSBhZ2VudC4KICAgICAqLwogICAgcmVnaW5mbyA9IG5ldHNubXBfY3JlYXRlX2hhbmRsZXJfcmVnaXN0cmF0aW9uKCJ0Y3BUYWJsZSIsCiAgICAgICAgICAgIHRjcFRhYmxlX2hhbmRsZXIsCiAgICAgICAgICAgIHRjcFRhYmxlX29pZCwgT0lEX0xFTkdUSCh0Y3BUYWJsZV9vaWQpLAogICAgICAgICAgICBIQU5ETEVSX0NBTl9ST05MWSksCiAgICByYyA9IG5ldHNubXBfcmVnaXN0ZXJfdGFibGVfaXRlcmF0b3IocmVnaW5mbywgaWluZm8pOwogICAgaWYgKHJjICE9IFNOTVBFUlJfU1VDQ0VTUykKICAgICAgICByZXR1cm47CgogICAgLyoKICAgICAqIC4uLi4gd2l0aCBhIGxvY2FsIGNhY2hlCiAgICAgKiAgICAoZXhjZXB0IGZvciBTb2xhcmlzLCB3aGljaCB1c2VzIGEgZGlmZmVyZW50IGFwcHJvYWNoKQogICAgICovCiAgICBuZXRzbm1wX2luamVjdF9oYW5kbGVyKCByZWdpbmZvLAoJCSAgICBuZXRzbm1wX2dldF9jYWNoZV9oYW5kbGVyKFRDUF9TVEFUU19DQUNIRV9USU1FT1VULAoJCQkgICAJCXRjcFRhYmxlX2xvYWQsIHRjcFRhYmxlX2ZyZWUsCgkJCQkJdGNwVGFibGVfb2lkLCBPSURfTEVOR1RIKHRjcFRhYmxlX29pZCkpKTsKfQoKCgppbnQKdGNwVGFibGVfaGFuZGxlcihuZXRzbm1wX21pYl9oYW5kbGVyICAgICAgICAgICpoYW5kbGVyLAogICAgICAgICAgICAgICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gICAqcmVxaW5mbywKICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAgICAgICAgICpyZXF1ZXN0cykKewogICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gICpyZXF1ZXN0OwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICpyZXF1ZXN0dmI7CiAgICBuZXRzbm1wX3RhYmxlX3JlcXVlc3RfaW5mbyAqdGFibGVfaW5mbzsKICAgIFRDUFRBQkxFX0VOVFJZX1RZUEUJICAqZW50cnk7CiAgICBvaWQgICAgICBzdWJpZDsKICAgIGxvbmcgICAgIHBvcnQ7CiAgICBsb25nICAgICBzdGF0ZTsKCiAgICBERUJVR01TR1RMKCgibWliSUkvdGNwVGFibGUiLCAiSGFuZGxlciAtIG1vZGUgJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgc2VfZmluZF9sYWJlbF9pbl9zbGlzdCgiYWdlbnRfbW9kZSIsIHJlcWluZm8tPm1vZGUpKSk7CiAgICBzd2l0Y2ggKHJlcWluZm8tPm1vZGUpIHsKICAgIGNhc2UgTU9ERV9HRVQ6CiAgICAgICAgZm9yIChyZXF1ZXN0PXJlcXVlc3RzOyByZXF1ZXN0OyByZXF1ZXN0PXJlcXVlc3QtPm5leHQpIHsKICAgICAgICAgICAgcmVxdWVzdHZiID0gcmVxdWVzdC0+cmVxdWVzdHZiOwogICAgICAgICAgICBERUJVR01TR1RMKCggIm1pYklJL3RjcFRhYmxlIiwgIm9pZDogIikpOwogICAgICAgICAgICBERUJVR01TR09JRCgoIm1pYklJL3RjcFRhYmxlIiwgcmVxdWVzdHZiLT5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdHZiLT5uYW1lX2xlbmd0aCkpOwogICAgICAgICAgICBERUJVR01TRygoICAgIm1pYklJL3RjcFRhYmxlIiwgIlxuIikpOwoKICAgICAgICAgICAgZW50cnkgPSAoVENQVEFCTEVfRU5UUllfVFlQRSAqKW5ldHNubXBfZXh0cmFjdF9pdGVyYXRvcl9jb250ZXh0KHJlcXVlc3QpOwogICAgICAgICAgICBpZiAoIWVudHJ5KQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIHRhYmxlX2luZm8gPSBuZXRzbm1wX2V4dHJhY3RfdGFibGVfaW5mbyhyZXF1ZXN0KTsKICAgICAgICAgICAgc3ViaWQgICAgICA9IHRhYmxlX2luZm8tPmNvbG51bTsKCiAgICAgICAgICAgIHN3aXRjaCAoc3ViaWQpIHsKICAgICAgICAgICAgY2FzZSBUQ1BDT05OU1RBVEU6CiAgICAgICAgICAgICAgICBzdGF0ZSA9IGVudHJ5LT5UQ1BUQUJMRV9TVEFURTsKCSAgICAgICAgc25tcF9zZXRfdmFyX3R5cGVkX3ZhbHVlKHJlcXVlc3R2YiwgQVNOX0lOVEVHRVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikmc3RhdGUsIHNpemVvZihzdGF0ZSkpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgVENQQ09OTkxPQ0FMQUREUkVTUzoKI2lmIGRlZmluZWQob3NmNSkgJiYgZGVmaW5lZChJTjZfRVhUUkFDVF9WNEFERFIpCgkgICAgICAgIHNubXBfc2V0X3Zhcl90eXBlZF92YWx1ZShyZXF1ZXN0dmIsIEFTTl9JUEFERFJFU1MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIqKUlONl9FWFRSQUNUX1Y0QUREUigmZW50cnktPnBjYi5pbnBfbGFkZHIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihJTjZfRVhUUkFDVF9WNEFERFIoJmVudHJ5LT5wY2IuaW5wX2xhZGRyKSkpOwojZWxzZQoJICAgICAgICBzbm1wX3NldF92YXJfdHlwZWRfdmFsdWUocmVxdWVzdHZiLCBBU05fSVBBRERSRVNTLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyICopJmVudHJ5LT5UQ1BUQUJMRV9MT0NBTEFERFJFU1MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoZW50cnktPlRDUFRBQkxFX0xPQ0FMQUREUkVTUykpOwojZW5kaWYKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFRDUENPTk5MT0NBTFBPUlQ6CiAgICAgICAgICAgICAgICBwb3J0ID0gVENQX1BPUlRfVE9fSE9TVF9PUkRFUigodV9zaG9ydCllbnRyeS0+VENQVEFCTEVfTE9DQUxQT1JUKTsKCSAgICAgICAgc25tcF9zZXRfdmFyX3R5cGVkX3ZhbHVlKHJlcXVlc3R2YiwgQVNOX0lOVEVHRVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikmcG9ydCwgc2l6ZW9mKHBvcnQpKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFRDUENPTk5SRU1PVEVBRERSRVNTOgojaWYgZGVmaW5lZChvc2Y1KSAmJiBkZWZpbmVkKElONl9FWFRSQUNUX1Y0QUREUikKCSAgICAgICAgc25tcF9zZXRfdmFyX3R5cGVkX3ZhbHVlKHJlcXVlc3R2YiwgQVNOX0lQQUREUkVTUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhciopSU42X0VYVFJBQ1RfVjRBRERSKCZlbnRyeS0+cGNiLmlucF9sYWRkciksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKElONl9FWFRSQUNUX1Y0QUREUigmZW50cnktPnBjYi5pbnBfbGFkZHIpKSk7CiNlbHNlCgkgICAgICAgIHNubXBfc2V0X3Zhcl90eXBlZF92YWx1ZShyZXF1ZXN0dmIsIEFTTl9JUEFERFJFU1MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikmZW50cnktPlRDUFRBQkxFX1JFTU9URUFERFJFU1MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoZW50cnktPlRDUFRBQkxFX1JFTU9URUFERFJFU1MpKTsKI2VuZGlmCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBUQ1BDT05OUkVNT1RFUE9SVDoKICAgICAgICAgICAgICAgIHBvcnQgPSBUQ1BfUE9SVF9UT19IT1NUX09SREVSKCh1X3Nob3J0KWVudHJ5LT5UQ1BUQUJMRV9SRU1PVEVQT1JUKTsKCSAgICAgICAgc25tcF9zZXRfdmFyX3R5cGVkX3ZhbHVlKHJlcXVlc3R2YiwgQVNOX0lOVEVHRVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikmcG9ydCwgc2l6ZW9mKHBvcnQpKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgIH0KCX0KICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfR0VUTkVYVDoKICAgIGNhc2UgTU9ERV9HRVRCVUxLOgogICAgY2FzZSBNT0RFX1NFVF9SRVNFUlZFMToKICAgIGNhc2UgTU9ERV9TRVRfUkVTRVJWRTI6CiAgICBjYXNlIE1PREVfU0VUX0FDVElPTjoKICAgIGNhc2UgTU9ERV9TRVRfQ09NTUlUOgogICAgY2FzZSBNT0RFX1NFVF9GUkVFOgogICAgY2FzZSBNT0RFX1NFVF9VTkRPOgogICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLCAibWliSUkvdGNwVGFibGU6IFVuc3VwcG9ydGVkIG1vZGUgKCVkKVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcWluZm8tPm1vZGUpOwogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywgIm1pYklJL3RjcFRhYmxlOiBVbnJlY29nbmlzZWQgbW9kZSAoJWQpXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxaW5mby0+bW9kZSk7CiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7Cn0KCmludApUQ1BfQ291bnRfQ29ubmVjdGlvbnMoIHZvaWQgKSB7CiAgICB0Y3BUYWJsZV9sb2FkKE5VTEwsIE5VTEwpOwogICAgcmV0dXJuIHRjcF9lc3RhYjsKfQoKCS8qCgkgKiBUd28gZm9ybXMgb2YgaXRlcmF0aW9uIGhvb2sgcm91dGluZXM6CgkgKiAgICBPbmUgZm9yIHdoZW4gdGhlIFRDUCB0YWJsZSBpcyBzdG9yZWQgYXMgYSB0YWJsZQoJICogICAgT25lIGZvciB3aGVuIHRoZSBUQ1AgdGFibGUgaXMgc3RvcmVkIGFzIGEgbGlua2VkIGxpc3QKCSAqCgkgKiBBbHNvIGFwcGxpZXMgdG8gdGhlIGNhY2hlLWhhbmRsZXIgZnJlZSByb3V0aW5lCgkgKi8KCiNpZmRlZglUQ1BUQUJMRV9JU19UQUJMRQpuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKgp0Y3BUYWJsZV9maXJzdF9lbnRyeSh2b2lkICoqbG9vcF9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICB2b2lkICoqZGF0YV9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKmluZGV4LAogICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2l0ZXJhdG9yX2luZm8gKmRhdGEpCnsKICAgIC8qCiAgICAgKiBYWFggLSBIb3cgY2FuIHdlIHRlbGwgaWYgdGhlIGNhY2hlIGlzIHZhbGlkPwogICAgICogICAgICAgTm8gYWNjZXNzIHRvICdyZXFpbmZvJwogICAgICovCiAgICBpZiAodGNwX3NpemUgPT0gMCkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICAvKgogICAgICogUG9pbnQgdG8gdGhlIGZpcnN0IGVudHJ5LCBhbmQgdXNlIHRoZQogICAgICogJ25leHRfZW50cnknIGhvb2sgdG8gcmV0cmlldmUgdGhpcyByb3cKICAgICAqLwogICAgKmxvb3BfY29udGV4dCA9IDA7CiAgICByZXR1cm4gdGNwVGFibGVfbmV4dF9lbnRyeSggbG9vcF9jb250ZXh0LCBkYXRhX2NvbnRleHQsIGluZGV4LCBkYXRhICk7Cn0KCm5ldHNubXBfdmFyaWFibGVfbGlzdCAqCnRjcFRhYmxlX25leHRfZW50cnkoIHZvaWQgKipsb29wX2NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgIHZvaWQgKipkYXRhX2NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfaXRlcmF0b3JfaW5mbyAqZGF0YSkKewogICAgaW50IGkgPSAoaW50KSpsb29wX2NvbnRleHQ7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKmlkeDsKICAgIGxvbmcgcG9ydDsKCiAgICBpZiAodGNwX3NpemUgPCBpKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIC8qCiAgICAgKiBTZXQgdXAgdGhlIGluZGV4aW5nIGZvciB0aGUgc3BlY2lmaWVkIHJvdy4uLgogICAgICovCiAgICBpZHggPSBpbmRleDsKI2lmIGRlZmluZWQgKFdJTjMyKSB8fCBkZWZpbmVkIChjeWd3aW4pCiAgICBwb3J0ID0gbnRvaGwoKHVfbG9uZyl0Y3BfaGVhZFtpXS5UQ1BUQUJMRV9MT0NBTEFERFJFU1MpOwogICAgc25tcF9zZXRfdmFyX3ZhbHVlKGlkeCwgKHVfY2hhciAqKSZwb3J0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZih0Y3BfaGVhZFtpXS5UQ1BUQUJMRV9MT0NBTEFERFJFU1MpKTsKI2Vsc2UKICAgIHNubXBfc2V0X3Zhcl92YWx1ZShpZHgsICh1X2NoYXIgKikmdGNwX2hlYWRbaV0uVENQVEFCTEVfTE9DQUxBRERSRVNTLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZih0Y3BfaGVhZFtpXS5UQ1BUQUJMRV9MT0NBTEFERFJFU1MpKTsKI2VuZGlmCgogICAgcG9ydCA9IFRDUF9QT1JUX1RPX0hPU1RfT1JERVIoKHVfc2hvcnQpdGNwX2hlYWRbaV0uVENQVEFCTEVfTE9DQUxQT1JUKTsKICAgIGlkeCA9IGlkeC0+bmV4dF92YXJpYWJsZTsKICAgIHNubXBfc2V0X3Zhcl92YWx1ZShpZHgsICh1X2NoYXIqKSZwb3J0LCBzaXplb2YocG9ydCkpOwoKICAgIGlkeCA9IGlkeC0+bmV4dF92YXJpYWJsZTsKI2lmIGRlZmluZWQgKFdJTjMyKSB8fCBkZWZpbmVkIChjeWd3aW4pCiAgICBwb3J0ID0gbnRvaGwoKHVfbG9uZyl0Y3BfaGVhZFtpXS5UQ1BUQUJMRV9SRU1PVEVBRERSRVNTKTsKICAgIHNubXBfc2V0X3Zhcl92YWx1ZShpZHgsICh1X2NoYXIgKikmcG9ydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YodGNwX2hlYWRbaV0uVENQVEFCTEVfUkVNT1RFQUREUkVTUykpOwojZWxzZQogICAgc25tcF9zZXRfdmFyX3ZhbHVlKGlkeCwgKHVfY2hhciAqKSZ0Y3BfaGVhZFtpXS5UQ1BUQUJMRV9SRU1PVEVBRERSRVNTLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZih0Y3BfaGVhZFtpXS5UQ1BUQUJMRV9SRU1PVEVBRERSRVNTKSk7CiNlbmRpZgoKICAgIHBvcnQgPSBUQ1BfUE9SVF9UT19IT1NUX09SREVSKCh1X3Nob3J0KXRjcF9oZWFkW2ldLlRDUFRBQkxFX1JFTU9URVBPUlQpOwogICAgaWR4ID0gaWR4LT5uZXh0X3ZhcmlhYmxlOwogICAgc25tcF9zZXRfdmFyX3ZhbHVlKGlkeCwgKHVfY2hhciopJnBvcnQsIHNpemVvZihwb3J0KSk7CgogICAgLyoKICAgICAqIC4uLiByZXR1cm4gdGhlIGRhdGEgc3RydWN0dXJlIGZvciB0aGlzIHJvdywKICAgICAqIGFuZCB1cGRhdGUgdGhlIGxvb3AgY29udGV4dCByZWFkeSBmb3IgdGhlIG5leHQgb25lLgogICAgICovCiAgICAqZGF0YV9jb250ZXh0ID0gKHZvaWQqKSZ0Y3BfaGVhZFtpXTsKICAgICpsb29wX2NvbnRleHQgPSAodm9pZCopKytpOwoKICAgIHJldHVybiBpbmRleDsKfQoKdm9pZAp0Y3BUYWJsZV9mcmVlKG5ldHNubXBfY2FjaGUgKmNhY2hlLCB2b2lkICptYWdpYykKewojaWYgZGVmaW5lZCAoV0lOMzIpIHx8IGRlZmluZWQgKGN5Z3dpbikKICAgIGlmICh0Y3BfaGVhZCkgewoJCS8qIHRoZSBhbGxvY2F0ZWQgc3RydWN0dXJlIGlzIGEgY291bnQgZm9sbG93ZWQgYnkgdGFibGUgZW50cmllcyAqLwoJCWZyZWUoKGNoYXIgKikodGNwX2hlYWQpIC0gc2l6ZW9mKERXT1JEKSk7Cgl9CiNlbHNlCglpZiAodGNwX2hlYWQpCiAgICAgICAgZnJlZSh0Y3BfaGVhZCk7CiNlbmRpZgogICAgdGNwX2hlYWQgID0gTlVMTDsKICAgIHRjcF9zaXplICA9IDA7CiAgICB0Y3BfZXN0YWIgPSAwOwp9CiNlbHNlCiNpZmRlZiBUQ1BUQUJMRV9JU19MSU5LRURfTElTVApuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKgp0Y3BUYWJsZV9maXJzdF9lbnRyeSh2b2lkICoqbG9vcF9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICB2b2lkICoqZGF0YV9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKmluZGV4LAogICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2l0ZXJhdG9yX2luZm8gKmRhdGEpCnsKICAgIC8qCiAgICAgKiBYWFggLSBIb3cgY2FuIHdlIHRlbGwgaWYgdGhlIGNhY2hlIGlzIHZhbGlkPwogICAgICogICAgICAgTm8gYWNjZXNzIHRvICdyZXFpbmZvJwogICAgICovCiAgICBpZiAodGNwX2hlYWQgPT0gTlVMTCkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICAvKgogICAgICogUG9pbnQgdG8gdGhlIGZpcnN0IGVudHJ5LCBhbmQgdXNlIHRoZQogICAgICogJ25leHRfZW50cnknIGhvb2sgdG8gcmV0cmlldmUgdGhpcyByb3cKICAgICAqLwogICAgKmxvb3BfY29udGV4dCA9ICh2b2lkKil0Y3BfaGVhZDsKICAgIHJldHVybiB0Y3BUYWJsZV9uZXh0X2VudHJ5KCBsb29wX2NvbnRleHQsIGRhdGFfY29udGV4dCwgaW5kZXgsIGRhdGEgKTsKfQoKbmV0c25tcF92YXJpYWJsZV9saXN0ICoKdGNwVGFibGVfbmV4dF9lbnRyeSggdm9pZCAqKmxvb3BfY29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgdm9pZCAqKmRhdGFfY29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICppbmRleCwKICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9pdGVyYXRvcl9pbmZvICpkYXRhKQp7CiAgICBUQ1BUQUJMRV9FTlRSWV9UWVBFCSAqZW50cnkgPSAoVENQVEFCTEVfRU5UUllfVFlQRSAqKSpsb29wX2NvbnRleHQ7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKmlkeDsKICAgIGxvbmcgYWRkciwgcG9ydDsKCiAgICBpZiAoIWVudHJ5KQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIC8qCiAgICAgKiBTZXQgdXAgdGhlIGluZGV4aW5nIGZvciB0aGUgc3BlY2lmaWVkIHJvdy4uLgogICAgICovCiAgICBpZHggPSBpbmRleDsKI2lmIGRlZmluZWQob3NmNSkgJiYgZGVmaW5lZChJTjZfRVhUUkFDVF9WNEFERFIpCiAgICBhZGRyID0gbnRvaGwoSU42X0VYVFJBQ1RfVjRBRERSKCZlbnRyeS0+cGNiLmlucF9sYWRkcikpOwojZWxzZQogICAgYWRkciA9IG50b2hsKGVudHJ5LT5UQ1BUQUJMRV9MT0NBTEFERFJFU1MpOwojZW5kaWYKICAgIHNubXBfc2V0X3Zhcl92YWx1ZShpZHgsICh1X2NoYXIgKikmYWRkciwgc2l6ZW9mKGFkZHIpKTsKCiAgICBwb3J0ID0gVENQX1BPUlRfVE9fSE9TVF9PUkRFUihlbnRyeS0+VENQVEFCTEVfTE9DQUxQT1JUKTsKICAgIGlkeCA9IGlkeC0+bmV4dF92YXJpYWJsZTsKICAgIHNubXBfc2V0X3Zhcl92YWx1ZShpZHgsICh1X2NoYXIqKSZwb3J0LCBzaXplb2YocG9ydCkpOwoKICAgIGlkeCA9IGlkeC0+bmV4dF92YXJpYWJsZTsKI2lmIGRlZmluZWQob3NmNSkgJiYgZGVmaW5lZChJTjZfRVhUUkFDVF9WNEFERFIpCiAgICBhZGRyID0gbnRvaGwoSU42X0VYVFJBQ1RfVjRBRERSKCZlbnRyeS0+cGNiLmlucF9mYWRkcikpOwojZWxzZQogICAgYWRkciA9IG50b2hsKGVudHJ5LT5UQ1BUQUJMRV9SRU1PVEVBRERSRVNTKTsKI2VuZGlmCiAgICBzbm1wX3NldF92YXJfdmFsdWUoaWR4LCAodV9jaGFyICopJmFkZHIsIHNpemVvZihhZGRyKSk7CgogICAgcG9ydCA9IFRDUF9QT1JUX1RPX0hPU1RfT1JERVIoZW50cnktPlRDUFRBQkxFX1JFTU9URVBPUlQpOwogICAgaWR4ID0gaWR4LT5uZXh0X3ZhcmlhYmxlOwogICAgc25tcF9zZXRfdmFyX3ZhbHVlKGlkeCwgKHVfY2hhciopJnBvcnQsIHNpemVvZihwb3J0KSk7CgogICAgLyoKICAgICAqIC4uLiByZXR1cm4gdGhlIGRhdGEgc3RydWN0dXJlIGZvciB0aGlzIHJvdywKICAgICAqIGFuZCB1cGRhdGUgdGhlIGxvb3AgY29udGV4dCByZWFkeSBmb3IgdGhlIG5leHQgb25lLgogICAgICovCiAgICAqZGF0YV9jb250ZXh0ID0gKHZvaWQqKWVudHJ5OwogICAgKmxvb3BfY29udGV4dCA9ICh2b2lkKillbnRyeS0+SU5QX05FWFRfU1lNQk9MOwogICAgcmV0dXJuIGluZGV4Owp9Cgp2b2lkCnRjcFRhYmxlX2ZyZWUobmV0c25tcF9jYWNoZSAqY2FjaGUsIHZvaWQgKm1hZ2ljKQp7CiAgICBUQ1BUQUJMRV9FTlRSWV9UWVBFICpwOwogICAgd2hpbGUgKHRjcF9oZWFkKSB7CiAgICAgICAgcCA9IHRjcF9oZWFkOwogICAgICAgIHRjcF9oZWFkID0gdGNwX2hlYWQtPklOUF9ORVhUX1NZTUJPTDsKICAgICAgICBmcmVlKHApOwogICAgfQoKICAgIHRjcF9oZWFkICA9IE5VTEw7CiAgICB0Y3Bfc2l6ZSAgPSAwOwogICAgdGNwX2VzdGFiID0gMDsKfQojZW5kaWYJCS8qIFRDUFRBQkxFX0lTX0xJTktFRF9MSVNUICovCiNlbmRpZgkJLyogVENQVEFCTEVfSVNfVEFCTEUgKi8KCgoJLyoKCSAqCgkgKiBUaGUgY2FjaGUtaGFuZGxlciBsb2FkaW5nIHJvdXRpbmUgaXMgdGhlIG1haW4KCSAqICAgIHBsYWNlIGZvciBhcmNoaXRlY3R1cmUtc3BlY2lmaWMgY29kZQoJICoKCSAqIExvYWQgaW50byBlaXRoZXIgYSB0YWJsZSBzdHJ1Y3R1cmUsIG9yIGEgbGlua2VkIGxpc3QKCSAqICAgIGRlcGVuZGluZyBvbiB0aGUgc3lzdGVtIGFyY2hpdGVjdHVyZQoJICovCgoKI2lmZGVmIGhwdXgxMQppbnQKdGNwVGFibGVfbG9hZChuZXRzbm1wX2NhY2hlICpjYWNoZSwgdm9pZCAqdm1hZ2ljKQp7CiAgICBpbnQgICAgICAgICAgICAgZmQ7CiAgICBzdHJ1Y3Qgbm1wYXJtcyAgcDsKICAgIGludCAgICAgICAgICAgICB2YWwgPSAwOwogICAgdW5zaWduZWQgaW50ICAgIHVsZW47CiAgICBpbnQgICAgICAgICAgICAgcmV0OwogICAgaW50ICAgICAgICAgICAgIGk7CgogICAgdGNwVGFibGVfZnJlZShOVUxMLCBOVUxMKTsKCiAgICBpZiAoKGZkID0gb3Blbl9taWIoIi9kZXYvaXAiLCBPX1JET05MWSwgMCwgTk1fQVNZTkNfT0ZGKSkgPj0gMCkgewogICAgICAgIHAub2JqaWQgPSBJRF90Y3BDb25uTnVtRW50OwogICAgICAgIHAuYnVmZmVyID0gKHZvaWQgKikgJnZhbDsKICAgICAgICB1bGVuID0gc2l6ZW9mKGludCk7CiAgICAgICAgcC5sZW4gPSAmdWxlbjsKICAgICAgICBpZiAoKHJldCA9IGdldF9taWJfaW5mbyhmZCwgJnApKSA9PSAwKQogICAgICAgICAgICB0Y3Bfc2l6ZSA9IHZhbDsKCiAgICAgICAgaWYgKHRjcF9zaXplID4gMCkgewogICAgICAgICAgICB1bGVuID0gKHVuc2lnbmVkKSB0Y3Bfc2l6ZSAqc2l6ZW9mKG1pYl90Y3BDb25uRW50KTsKICAgICAgICAgICAgdGNwX2hlYWQgPSAobWliX3RjcENvbm5FbnQgKikgbWFsbG9jKHVsZW4pOwogICAgICAgICAgICBwLm9iamlkID0gSURfdGNwQ29ublRhYmxlOwogICAgICAgICAgICBwLmJ1ZmZlciA9ICh2b2lkICopIHRjcF9oZWFkOwogICAgICAgICAgICBwLmxlbiA9ICZ1bGVuOwogICAgICAgICAgICBpZiAoKHJldCA9IGdldF9taWJfaW5mbyhmZCwgJnApKSA8IDApIHsKICAgICAgICAgICAgICAgIHRjcF9zaXplID0gMDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgY2xvc2VfbWliKGZkKTsKICAgIH0KCiAgICAvKgogICAgICogQ291bnQgdGhlIG51bWJlciBvZiBlc3RhYmxpc2hlZCBjb25uZWN0aW9ucwogICAgICogUHJvYmFibHkgbm90IGFjdHVhbGx5IG5lY2Vzc2FyeSBmb3IgSFAtVVgKICAgICAqLwogICAgZm9yIChpID0gMDsgaSA8IHRjcF9zaXplOyBpKyspIHsKICAgICAgICBpZiAodGNwX2hlYWRbaV0uU3RhdGUgPT0gNSAvKiBlc3RhYmxpc2hlZCAqLyB8fAogICAgICAgICAgICB0Y3BfaGVhZFtpXS5TdGF0ZSA9PSA4IC8qICBjbG9zZVdhaXQgICovICkKICAgICAgICAgICAgdGNwX2VzdGFiKys7CiAgICB9CgogICAgaWYgKHRjcF9zaXplID4gMCkgewogICAgICAgIERFQlVHTVNHVEwoKCJtaWJJSS90Y3BUYWJsZSIsICJMb2FkZWQgVENQIFRhYmxlIChocHV4MTEpXG4iKSk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICBERUJVR01TR1RMKCgibWliSUkvdGNwVGFibGUiLCAiRmFpbGVkIHRvIGxvYWQgVENQIFRhYmxlIChocHV4MTEpXG4iKSk7CiAgICByZXR1cm4gLTE7Cn0KI2Vsc2UgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBocHV4MTEgKi8KCiNpZmRlZiBsaW51eAoKLyogIHNlZSA8bmV0aW5ldC90Y3AuaD4gKi8KI2RlZmluZSBUQ1BfQUxMICgoMSA8PCAoVENQX0NMT1NJTkcgKyAxKSkgLSAxKQoKY29uc3Qgc3RhdGljIGludCBsaW51eF9zdGF0ZXNbMTJdID0geyAxLCA1LCAzLCA0LCA2LCA3LCAxMSwgMSwgOCwgOSwgMiwgMTAgfTsKCiNpZiBIQVZFX05FVExJTktfTkVUTElOS19ICgojaWYgIWRlZmluZWQoSEFWRV9MSUJOTDMpCi8qIGxpYm5sMyBBUEkgaW1wbGVtZW50ZWQgb24gdG9wIG9mIHRoZSBsaWJubDEgQVBJICovCgojZGVmaW5lIG5sX3NvY2sgbmxfaGFuZGxlCgpzdGF0aWMgY29uc3QgY2hhciAqbmxfZ2V0ZXJyb3JfY29tcGF0KGludCBlKQp7CiAgICByZXR1cm4gbmxfZ2V0ZXJyb3IoKTsKfQoKI2RlZmluZSBubF9nZXRlcnJvcihlKSBubF9nZXRlcnJvcl9jb21wYXQoZSkKCnN0YXRpYyBzdHJ1Y3QgbmxfaGFuZGxlICpubF9zb2NrZXRfYWxsb2Modm9pZCkKewogICAgcmV0dXJuIG5sX2hhbmRsZV9hbGxvYygpOwp9CgpzdGF0aWMgdm9pZCBubF9zb2NrZXRfZnJlZShzdHJ1Y3QgbmxfaGFuZGxlICpucykKewogICAgbmxfaGFuZGxlX2Rlc3Ryb3kobnMpOwp9CiNlbmRpZiAvKiBIQVZFX0xJQk5MMyAqLwoKc3RhdGljIGludAp0Y3BUYWJsZV9sb2FkX25ldGxpbmsodm9pZCkKewoJLyogVE9ETzogcGVyaGFwcyB1c2UgcGVybWFuZW50IG5sIHNvY2tldCA/ICovCglzdHJ1Y3Qgbmxfc29jayAqbmwgPSBubF9zb2NrZXRfYWxsb2MoKTsKCXN0cnVjdCBpbmV0X2RpYWdfcmVxIHJlcSA9IHsKCQkuaWRpYWdfZmFtaWx5ID0gQUZfSU5FVCwKCQkuaWRpYWdfc3RhdGVzID0gVENQX0FMTCwKCX07CgoJc3RydWN0IG5sX21zZyAqbm07CgoJc3RydWN0IHNvY2thZGRyX25sIHBlZXI7Cgl1bnNpZ25lZCBjaGFyICpidWYgPSBOVUxMOwoJaW50IHJ1bm5pbmcgPSAxLCBsZW4sIGVycjsKCglpZiAobmwgPT0gTlVMTCkgewoJCURFQlVHTVNHVEwoKCJtaWJJSS90Y3BUYWJsZSIsICJGYWlsZWQgdG8gYWxsb2NhdGUgbmV0bGluayBoYW5kbGVcbiIpKTsKCQlzbm1wX2xvZyhMT0dfRVJSLCAic25tcGQ6IEZhaWxlZCB0byBhbGxvY2F0ZSBuZXRsaW5rIGhhbmRsZVxuIik7CgkJcmV0dXJuIC0xOwoJfQoKCWVyciA9IG5sX2Nvbm5lY3QobmwsIE5FVExJTktfSU5FVF9ESUFHKTsKCWlmIChlcnIgPCAwKSB7CgkJREVCVUdNU0dUTCgoIm1pYklJL3RjcFRhYmxlIiwgIkZhaWxlZCB0byBjb25uZWN0IHRvIG5ldGxpbms6ICVzXG4iLCBubF9nZXRlcnJvcihlcnIpKSk7CgkJc25tcF9sb2coTE9HX0VSUiwgInNubXBkOiBDb3VsZG4ndCBjb25uZWN0IHRvIG5ldGxpbms6ICVzXG4iLCBubF9nZXRlcnJvcihlcnIpKTsKCQlubF9zb2NrZXRfZnJlZShubCk7CgkJcmV0dXJuIC0xOwoJfQoKCW5tID0gbmxtc2dfYWxsb2Nfc2ltcGxlKFRDUERJQUdfR0VUU09DSywgTkxNX0ZfUk9PVHxOTE1fRl9NQVRDSHxOTE1fRl9SRVFVRVNUKTsKCW5sbXNnX2FwcGVuZChubSwgJnJlcSwgc2l6ZW9mKHN0cnVjdCBpbmV0X2RpYWdfcmVxKSwgMCk7CgoJZXJyID0gbmxfc2VuZF9hdXRvX2NvbXBsZXRlKG5sLCBubSk7CglpZiAoZXJyIDwgMCkgewoJCURFQlVHTVNHVEwoKCJtaWJJSS90Y3BUYWJsZSIsICJubF9zZW5kX2F1dG9jb21wbGV0ZSgpOiAlc1xuIiwgbmxfZ2V0ZXJyb3IoZXJyKSkpOwoJCXNubXBfbG9nKExPR19FUlIsICJzbm1wZDogbmxfc2VuZF9hdXRvY29tcGxldGUoKTogJXNcbiIsIG5sX2dldGVycm9yKGVycikpOwoJCW5sX3NvY2tldF9mcmVlKG5sKTsKCQlyZXR1cm4gLTE7Cgl9CglubG1zZ19mcmVlKG5tKTsKCgl3aGlsZSAocnVubmluZykgewoJCXN0cnVjdCBubG1zZ2hkciAqaDsKCQlpZiAoKGxlbiA9IG5sX3JlY3YobmwsICZwZWVyLCAmYnVmLCBOVUxMKSkgPD0gMCkgewoJCQlERUJVR01TR1RMKCgibWliSUkvdGNwVGFibGUiLCAibmxfcmVjdigpOiAlc1xuIiwgbmxfZ2V0ZXJyb3IobGVuKSkpOwoJCQlzbm1wX2xvZyhMT0dfRVJSLCAic25tcGQ6IG5sX3JlY3YoKTogJXNcbiIsIG5sX2dldGVycm9yKGxlbikpOwoJCQlubF9zb2NrZXRfZnJlZShubCk7CgkJCXJldHVybiAtMTsKCQl9CgoJCWggPSAoc3RydWN0IG5sbXNnaGRyKilidWY7CgoJCXdoaWxlIChubG1zZ19vayhoLCBsZW4pKSB7CgkJCXN0cnVjdCBpbmV0X2RpYWdfbXNnICpyID0gbmxtc2dfZGF0YShoKTsKCQkJc3RydWN0IGlucGNiICAgIHBjYiwgKm5uZXc7CgoJCQlpZiAoaC0+bmxtc2dfdHlwZSA9PSBOTE1TR19ET05FKSB7CgkJCQlydW5uaW5nID0gMDsKCQkJCWJyZWFrOwoJCQl9CgoJCQlyID0gbmxtc2dfZGF0YShoKTsKCgkJCWlmIChyLT5pZGlhZ19mYW1pbHkgIT0gQUZfSU5FVCkgewoJCQkJaCA9IG5sbXNnX25leHQoaCwgJmxlbik7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJbWVtY3B5KCZwY2IuaW5wX2xhZGRyLnNfYWRkciwgci0+aWQuaWRpYWdfc3JjLCByLT5pZGlhZ19mYW1pbHkgPT0gQUZfSU5FVCA/IDQgOiA2KTsKCQkJbWVtY3B5KCZwY2IuaW5wX2ZhZGRyLnNfYWRkciwgci0+aWQuaWRpYWdfZHN0LCByLT5pZGlhZ19mYW1pbHkgPT0gQUZfSU5FVCA/IDQgOiA2KTsKCgkJCXBjYi5pbnBfbHBvcnQgPSByLT5pZC5pZGlhZ19zcG9ydDsKCQkJcGNiLmlucF9mcG9ydCA9IHItPmlkLmlkaWFnX2Rwb3J0OwoKCQkJcGNiLmlucF9zdGF0ZSA9IChyLT5pZGlhZ19zdGF0ZSAmIDB4ZikgPCAxMiA/IGxpbnV4X3N0YXRlc1tyLT5pZGlhZ19zdGF0ZSAmIDB4Zl0gOiAyOwoJCQlpZiAocGNiLmlucF9zdGF0ZSA9PSA1IC8qIGVzdGFibGlzaGVkICovIHx8CgkJCQlwY2IuaW5wX3N0YXRlID09IDggLyogIGNsb3NlV2FpdCAgKi8gKQoJCQkJdGNwX2VzdGFiKys7CgkJCXBjYi51aWQgPSByLT5pZGlhZ191aWQ7CgoJCQlubmV3ID0gU05NUF9NQUxMT0NfVFlQRURFRihzdHJ1Y3QgaW5wY2IpOwoJCQlpZiAobm5ldyA9PSBOVUxMKSB7CgkJCQlydW5uaW5nID0gMDsKCQkJCS8qICBYWFggcmVwb3J0IG1hbGxvYyBlcnJvciBhbmQgcmV0dXJuIC0xPyAqLwoJCQkJYnJlYWs7CgkJCX0KCQkJbWVtY3B5KG5uZXcsICZwY2IsIHNpemVvZihzdHJ1Y3QgaW5wY2IpKTsKCQkJbm5ldy0+aW5wX25leHQgPSB0Y3BfaGVhZDsKCQkJdGNwX2hlYWQgICAgICAgPSBubmV3OwoKCQkJaCA9IG5sbXNnX25leHQoaCwgJmxlbik7CgkJfQoJCWZyZWUoYnVmKTsKCX0KCglubF9zb2NrZXRfZnJlZShubCk7CgoJaWYgKHRjcF9oZWFkKSB7CgkJREVCVUdNU0dUTCgoIm1pYklJL3RjcFRhYmxlIiwgIkxvYWRlZCBUQ1AgVGFibGUgdXNpbmcgbmV0bGlua1xuIikpOwoJCXJldHVybiAwOwoJfQoJREVCVUdNU0dUTCgoIm1pYklJL3RjcFRhYmxlIiwgIkZhaWxlZCB0byBsb2FkIFRDUCBUYWJsZSAobmV0bGluaylcbiIpKTsKCXJldHVybiAtMTsKfQojZW5kaWYKCmludAp0Y3BUYWJsZV9sb2FkKG5ldHNubXBfY2FjaGUgKmNhY2hlLCB2b2lkICp2bWFnaWMpCnsKICAgIEZJTEUgICAgICAgICAgICppbjsKICAgIGNoYXIgICAgICAgICAgICBsaW5lWzI1Nl07CgogICAgdGNwVGFibGVfZnJlZShjYWNoZSwgTlVMTCk7CgojaWYgSEFWRV9ORVRMSU5LX05FVExJTktfSAoJaWYgKHRjcFRhYmxlX2xvYWRfbmV0bGluaygpID09IDApIHsKCQlyZXR1cm4gMDsKCX0KI2VuZGlmCgogICAgaWYgKCEoaW4gPSBmb3BlbigiL3Byb2MvbmV0L3RjcCIsICJyIikpKSB7CiAgICAgICAgREVCVUdNU0dUTCgoIm1pYklJL3RjcFRhYmxlIiwgIkZhaWxlZCB0byBsb2FkIFRDUCBUYWJsZSAobGludXgxKVxuIikpOwogICAgICAgIE5FVFNOTVBfTE9HT05DRSgoTE9HX0VSUiwgInNubXBkOiBjYW5ub3Qgb3BlbiAvcHJvYy9uZXQvdGNwIC4uLlxuIikpOwogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICAvKgogICAgICogc2NhbiBwcm9jLWZpbGUgYW5kIGJ1aWxkIHVwIGEgbGlua2VkIGxpc3QgCiAgICAgKiBUaGlzIHdpbGwgYWN0dWFsbHkgYmUgYnVpbHQgdXAgaW4gcmV2ZXJzZSwKICAgICAqICAgYnV0IHNpbmNlIHRoZSBlbnRyaWVzIGFyZSB1bnNvcnRlZCwgdGhhdCBkb2Vzbid0IG1hdHRlci4KICAgICAqLwogICAgd2hpbGUgKGxpbmUgPT0gZmdldHMobGluZSwgc2l6ZW9mKGxpbmUpLCBpbikpIHsKICAgICAgICBzdHJ1Y3QgaW5wY2IgICAgcGNiLCAqbm5ldzsKICAgICAgICB1bnNpZ25lZCBpbnQgICAgbHAsIGZwOwogICAgICAgIGludCAgICAgICAgICAgICBzdGF0ZSwgdWlkOwoKICAgICAgICBpZiAoNiAhPSBzc2NhbmYobGluZSwKICAgICAgICAgICAgICAgICAgICAgICAgIiUqZDogJXg6JXggJXg6JXggJXggJSpYOiUqWCAlKlg6JSpYICUqWCAlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICZwY2IuaW5wX2xhZGRyLnNfYWRkciwgJmxwLAogICAgICAgICAgICAgICAgICAgICAgICAmcGNiLmlucF9mYWRkci5zX2FkZHIsICZmcCwgJnN0YXRlLCAmdWlkKSkKICAgICAgICAgICAgY29udGludWU7CgogICAgICAgIHBjYi5pbnBfbHBvcnQgPSBodG9ucygodW5zaWduZWQgc2hvcnQpIGxwKTsKICAgICAgICBwY2IuaW5wX2Zwb3J0ID0gaHRvbnMoKHVuc2lnbmVkIHNob3J0KSBmcCk7CgogICAgICAgIHBjYi5pbnBfc3RhdGUgPSAoc3RhdGUgJiAweGYpIDwgMTIgPyBsaW51eF9zdGF0ZXNbc3RhdGUgJiAweGZdIDogMjsKICAgICAgICBpZiAocGNiLmlucF9zdGF0ZSA9PSA1IC8qIGVzdGFibGlzaGVkICovIHx8CiAgICAgICAgICAgIHBjYi5pbnBfc3RhdGUgPT0gOCAvKiAgY2xvc2VXYWl0ICAqLyApCiAgICAgICAgICAgIHRjcF9lc3RhYisrOwogICAgICAgIHBjYi51aWQgPSB1aWQ7CgogICAgICAgIG5uZXcgPSBTTk1QX01BTExPQ19UWVBFREVGKHN0cnVjdCBpbnBjYik7CiAgICAgICAgaWYgKG5uZXcgPT0gTlVMTCkKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgbWVtY3B5KG5uZXcsICZwY2IsIHNpemVvZihzdHJ1Y3QgaW5wY2IpKTsKICAgICAgICBubmV3LT5pbnBfbmV4dCA9IHRjcF9oZWFkOwogICAgICAgIHRjcF9oZWFkICAgICAgID0gbm5ldzsKICAgIH0KCiAgICBmY2xvc2UoaW4pOwoKICAgIERFQlVHTVNHVEwoKCJtaWJJSS90Y3BUYWJsZSIsICJMb2FkZWQgVENQIFRhYmxlIChsaW51eClcbiIpKTsKICAgIHJldHVybiAwOwp9CiNlbHNlICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbGludXggKi8KCiNpZmRlZiBzb2xhcmlzMgpzdGF0aWMgaW50ClRDUF9DbXAodm9pZCAqYWRkciwgdm9pZCAqZXApCnsKICAgIGlmIChtZW1jbXAoKG1pYjJfdGNwQ29ubkVudHJ5X3QgKikgZXAsIChtaWIyX3RjcENvbm5FbnRyeV90ICopIGFkZHIsCiAgICAgICAgICAgICAgIHNpemVvZihtaWIyX3RjcENvbm5FbnRyeV90KSkgPT0gMCkKICAgICAgICByZXR1cm4gKDApOwogICAgZWxzZQogICAgICAgIHJldHVybiAoMSk7Cn0KCmludAp0Y3BUYWJsZV9sb2FkKG5ldHNubXBfY2FjaGUgKmNhY2hlLCB2b2lkICp2bWFnaWMpCnsKICAgIG1pYjJfdGNwQ29ubkVudHJ5X3QgICBlbnRyeTsKICAgIG5ldHNubXBfdGNwQ29ubkVudHJ5ICpubmV3OwogICAgbmV0c25tcF90Y3BDb25uRW50cnkgKnByZXZfZW50cnkgPSBOVUxMOwoKICAgIHRjcFRhYmxlX2ZyZWUoTlVMTCwgTlVMTCk7CgogICAgaWYgKGdldE1pYnN0YXQoTUlCX1RDUF9DT05OLCAmZW50cnksIHNpemVvZihtaWIyX3RjcENvbm5FbnRyeV90KSwKICAgICAgICAgICAgICAgICAgIEdFVF9GSVJTVCwgJlRDUF9DbXAsICZlbnRyeSkgIT0gMCkgewogICAgICAgIERFQlVHTVNHVEwoKCJtaWJJSS90Y3BUYWJsZSIsICJGYWlsZWQgdG8gbG9hZCBUQ1AgVGFibGUgKHNvbGFyaXMpXG4iKSk7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQoKICAgIHdoaWxlICgxKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBCdWlsZCB1cCBhIGxpbmtlZCBsaXN0IGNvcHkgb2YgdGhlIGdldE1pYnN0YXQgcmVzdWx0cwogICAgICAgICAqIE5vdGUgdGhhdCBzaW5jZSBnZXRNaWJzdGF0IHJldHVybnMgcm93cyBpbiBzb3J0ZWQgb3JkZXIsCiAgICAgICAgICogICAgd2UgbmVlZCB0byByZXRhaW4gdGhpcyBvcmRlciB3aGlsZSBidWlsZGluZyB0aGUgbGlzdAogICAgICAgICAqICAgIHNvIG5ldyBlbnRyaWVzIGFyZSBhZGRlZCBvbnRvIHRoZSBlbmQgb2YgdGhlIGxpc3QuCiAgICAgICAgICogTm90ZSAyOiBhdCBsZWFzdCBTb2xhcmlzIDgtMTAgZG8gbm90IHJldHVybiByb3dzIGluCiAgICAgICAgICogICAgc29ydGVkIG9yZGVyIGFueW1vcmUKICAgICAgICAgKi8KICAgICAgICBubmV3ID0gU05NUF9NQUxMT0NfVFlQRURFRihuZXRzbm1wX3RjcENvbm5FbnRyeSk7CiAgICAgICAgaWYgKG5uZXcgPT0gTlVMTCkKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgbWVtY3B5KCYobm5ldy0+ZW50cnkpLCAmZW50cnksIHNpemVvZihtaWIyX3RjcENvbm5FbnRyeV90KSk7CiAgICAgICAgaWYgKCFwcmV2X2VudHJ5KQogICAgICAgICAgICB0Y3BfaGVhZCA9IG5uZXc7CiAgICAgICAgZWxzZQogICAgICAgICAgICBwcmV2X2VudHJ5LT5pbnBfbmV4dCA9IG5uZXc7CiAgICAgICAgcHJldl9lbnRyeSA9IG5uZXc7CgogICAgICAgIGlmIChnZXRNaWJzdGF0KE1JQl9UQ1BfQ09OTiwgJmVudHJ5LCBzaXplb2YobWliMl90Y3BDb25uRW50cnlfdCksCiAgICAgICAgICAgICAgICAgICAgICAgR0VUX05FWFQsICZUQ1BfQ21wLCAmZW50cnkpICE9IDApCgkgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKHRjcF9oZWFkKSB7CiAgICAgICAgREVCVUdNU0dUTCgoIm1pYklJL3RjcFRhYmxlIiwgIkxvYWRlZCBUQ1AgVGFibGUgKHNvbGFyaXMpXG4iKSk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICBERUJVR01TR1RMKCgibWliSUkvdGNwVGFibGUiLCAiRmFpbGVkIHRvIGxvYWQgVENQIFRhYmxlIChzb2xhcmlzKVxuIikpOwogICAgcmV0dXJuIC0xOwp9CiNlbHNlICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc29sYXJpczIgKi8KCiNpZiBkZWZpbmVkIChXSU4zMikgfHwgZGVmaW5lZCAoY3lnd2luKQppbnQKdGNwVGFibGVfbG9hZChuZXRzbm1wX2NhY2hlICpjYWNoZSwgdm9pZCAqdm1hZ2ljKQp7CiAgICBQTUlCX1RDUFRBQkxFIHBUY3BUYWJsZSA9IE5VTEw7CiAgICBEV09SRCAgICAgICAgIGR3QWN0dWFsU2l6ZSA9IDA7CiAgICBEV09SRCAgICAgICAgIHN0YXR1cyA9IE5PX0VSUk9SOwoKICAgIC8qCiAgICAgKiBxdWVyeSBmb3IgdGhlIGJ1ZmZlciBzaXplIG5lZWRlZCAKICAgICAqLwogICAgc3RhdHVzID0gR2V0VGNwVGFibGUocFRjcFRhYmxlLCAmZHdBY3R1YWxTaXplLCBUUlVFKTsKICAgIGlmIChzdGF0dXMgPT0gRVJST1JfSU5TVUZGSUNJRU5UX0JVRkZFUikgewogICAgICAgIHBUY3BUYWJsZSA9IChQTUlCX1RDUFRBQkxFKSBtYWxsb2MoZHdBY3R1YWxTaXplKTsKICAgICAgICBpZiAocFRjcFRhYmxlICE9IE5VTEwpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogR2V0IHRoZSBzb3J0ZWQgVENQIHRhYmxlIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc3RhdHVzID0gR2V0VGNwVGFibGUocFRjcFRhYmxlLCAmZHdBY3R1YWxTaXplLCBUUlVFKTsKICAgICAgICB9CiAgICB9CgogICAgaWYgKHN0YXR1cyA9PSBOT19FUlJPUikgewogICAgICAgIGludCAgICAgICAgICAgaTsKCiAgICAgICAgREVCVUdNU0dUTCgoIm1pYklJL3RjcFRhYmxlIiwgIkxvYWRlZCBUQ1AgVGFibGUgKFdJTjMyKVxuIikpOwogICAgICAgIHRjcF9zaXplID0gcFRjcFRhYmxlLT5kd051bUVudHJpZXMgLTE7ICAvKiBlbnRyaWVzIGFyZSBjb3VudGVkIHN0YXJ0aW5nIHdpdGggMCAqLwogICAgICAgIHRjcF9oZWFkID0gcFRjcFRhYmxlLT50YWJsZTsKCgkvKgoJICogQ291bnQgdGhlIG51bWJlciBvZiBlc3RhYmxpc2hlZCBjb25uZWN0aW9ucwoJICogUHJvYmFibHkgbm90IGFjdHVhbGx5IG5lY2Vzc2FyeSBmb3IgV2luZG93cwoJICovCglmb3IgKGkgPSAwOyBpIDwgdGNwX3NpemU7IGkrKykgewoJCWlmICh0Y3BfaGVhZFtpXS5kd1N0YXRlID09IDUgLyogZXN0YWJsaXNoZWQgKi8gfHwKCQkJdGNwX2hlYWRbaV0uZHdTdGF0ZSA9PSA4IC8qICBjbG9zZVdhaXQgICovICkKCQkJdGNwX2VzdGFiKys7Cgl9CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgREVCVUdNU0dUTCgoIm1pYklJL3RjcFRhYmxlIiwgIkZhaWxlZCB0byBsb2FkIFRDUCBUYWJsZSAod2luMzIpXG4iKSk7CglpZiAocFRjcFRhYmxlKQoJCWZyZWUocFRjcFRhYmxlKTsKICAgIHJldHVybiAtMTsKfQojZWxzZSAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIFdJTjMyIGN5Z3dpbiAqLwoKI2lmIChkZWZpbmVkKE5FVFNOTVBfQ0FOX1VTRV9TWVNDVEwpICYmIGRlZmluZWQoVENQQ1RMX1BDQkxJU1QpKQoKI2lmIGRlZmluZWQoZnJlZWJzZDQpIHx8IGRlZmluZWQoZGFyd2luKQogICAgI2RlZmluZSBOU19FTEVNIHN0cnVjdCB4dGNwY2IKI2Vsc2UKICAgICNkZWZpbmUgTlNfRUxFTSBzdHJ1Y3QgeGlucGNiCiNlbmRpZgoKaW50CnRjcFRhYmxlX2xvYWQobmV0c25tcF9jYWNoZSAqY2FjaGUsIHZvaWQgKnZtYWdpYykKewogICAgc2l6ZV90ICAgbGVuOwogICAgaW50ICAgICAgc25hbWVbXSA9IHsgQ1RMX05FVCwgUEZfSU5FVCwgSVBQUk9UT19UQ1AsIFRDUENUTF9QQ0JMSVNUIH07CiAgICBjaGFyICAgICAqdGNwY2JfYnVmID0gTlVMTDsKI2lmIGRlZmluZWQoZHJhZ29uZmx5KQogICAgc3RydWN0IHhpbnBjYiAgKnhpZyA9IE5VTEw7CiAgICBpbnQgICAgICBTdGF0ZU1hcFtdID0geyAxLCAxLCAyLCAzLCA0LCA1LCA4LCA2LCAxMCwgOSwgNywgMTEgfTsKI2Vsc2UKICAgIHN0cnVjdCB4aW5wZ2VuICp4aWcgPSBOVUxMOwogICAgaW50ICAgICAgU3RhdGVNYXBbXSA9IHsgMSwgMiwgMywgNCwgNSwgOCwgNiwgMTAsIDksIDcsIDExIH07CiNlbmRpZgogICAgbmV0c25tcF9pbnBjYiAgKm5uZXc7CgogICAgdGNwVGFibGVfZnJlZShOVUxMLCBOVUxMKTsKCiAgICAvKgogICAgICogIFJlYWQgaW4gdGhlIGJ1ZmZlciBjb250YWluaW5nIHRoZSBUQ1AgdGFibGUgZGF0YQogICAgICovCiAgICBsZW4gPSAwOwogICAgaWYgKHN5c2N0bChzbmFtZSwgNCwgMCwgJmxlbiwgMCwgMCkgPCAwIHx8CiAgICAgICAodGNwY2JfYnVmID0gbWFsbG9jKGxlbikpID09IE5VTEwpCiAgICAgICAgcmV0dXJuIC0xOwogICAgaWYgKHN5c2N0bChzbmFtZSwgNCwgdGNwY2JfYnVmLCAmbGVuLCAwLCAwKSA8IDApIHsKICAgICAgICBmcmVlKHRjcGNiX2J1Zik7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQoKICAgIC8qCiAgICAgKiAgVW5waWNrIHRoaXMgaW50byB0aGUgY29uc3RpdHVlbnQgJ3hpbnBnZW4nIHN0cnVjdHVyZXMsIGFuZCBleHRyYWN0CiAgICAgKiAgICAgdGhlICdpbnBjYicgZWxlbWVudHMgaW50byBhIGxpbmtlZCBsaXN0IChidWlsdCBpbiByZXZlcnNlKQogICAgICovCiNpZiBkZWZpbmVkKGRyYWdvbmZseSkKICAgIHhpZyA9IChzdHJ1Y3QgeGlucGNiICAqKSB0Y3BjYl9idWY7CiNlbHNlCiAgICB4aWcgPSAoc3RydWN0IHhpbnBnZW4gKikgdGNwY2JfYnVmOwogICAgeGlnID0gKHN0cnVjdCB4aW5wZ2VuICopICgoY2hhciAqKSB4aWcgKyB4aWctPnhpZ19sZW4pOwojZW5kaWYKCiNpZiBkZWZpbmVkKGRyYWdvbmZseSkKICAgIHdoaWxlICh4aWcgJiYgKChjaGFyICopeGlnICsgeGlnLT54aV9sZW4gPCB0Y3BjYl9idWYgKyBsZW4pKQojZWxzZQogICAgd2hpbGUgKHhpZyAmJiAoeGlnLT54aWdfbGVuID4gc2l6ZW9mKHN0cnVjdCB4aW5wZ2VuKSkpCiNlbmRpZgogICAgewogICAgICAgIG5uZXcgPSBTTk1QX01BTExPQ19UWVBFREVGKG5ldHNubXBfaW5wY2IpOwogICAgICAgIGlmICghbm5ldykKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgbm5ldy0+c3RhdGUgPSBTdGF0ZU1hcFsoKE5TX0VMRU0gKikgeGlnKS0+eHRfdHAudF9zdGF0ZV07CiAgICAgICAgaWYgKG5uZXctPnN0YXRlID09IDUgLyogZXN0YWJsaXNoZWQgKi8gfHwKICAgICAgICAgICAgbm5ldy0+c3RhdGUgPT0gOCAvKiAgY2xvc2VXYWl0ICAqLyApCiAgICAgICAgICAgIHRjcF9lc3RhYisrOwogICAgICAgIG1lbWNweSgmKG5uZXctPnBjYiksICYoKChOU19FTEVNICopIHhpZyktPnh0X2lucCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihzdHJ1Y3QgaW5wY2IpKTsKCglpZiAobm5ldy0+cGNiLmlucF92ZmxhZyAmIElOUF9JUFY2KQoJICAgIGZyZWUobm5ldyk7CgllbHNlIHsKCSAgICBubmV3LT5pbnBfbmV4dCA9IHRjcF9oZWFkOwoJICAgIHRjcF9oZWFkICAgPSBubmV3OwoJfQojaWYgZGVmaW5lZChkcmFnb25mbHkpCiAgICAgICAgeGlnID0gKHN0cnVjdCB4aW5wY2IgICopICgoY2hhciAqKSB4aWcgKyB4aWctPnhpX2xlbik7CiNlbHNlCiAgICAgICAgeGlnID0gKHN0cnVjdCB4aW5wZ2VuICopICgoY2hhciAqKSB4aWcgKyB4aWctPnhpZ19sZW4pOwojZW5kaWYKICAgIH0KCiAgICBmcmVlKHRjcGNiX2J1Zik7CiAgICBpZiAodGNwX2hlYWQpIHsKICAgICAgICBERUJVR01TR1RMKCgibWliSUkvdGNwVGFibGUiLCAiTG9hZGVkIFRDUCBUYWJsZSAoc3lzY3RsKVxuIikpOwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgREVCVUdNU0dUTCgoIm1pYklJL3RjcFRhYmxlIiwgIkZhaWxlZCB0byBsb2FkIFRDUCBUYWJsZSAoc3lzY3RsKVxuIikpOwogICAgcmV0dXJuIC0xOwp9CiN1bmRlZiBOU19FTEVNCgojZWxzZQkJLyogKGRlZmluZWQoTkVUU05NUF9DQU5fVVNFX1NZU0NUTCkgJiYgZGVmaW5lZChUQ1BDVExfUENCTElTVCkpICovCiNpZmRlZiBQQ0JfVEFCTEUKaW50CnRjcFRhYmxlX2xvYWQobmV0c25tcF9jYWNoZSAqY2FjaGUsIHZvaWQgKnZtYWdpYykKewogICAgc3RydWN0IGlucGNidGFibGUgdGFibGU7CiAgICBzdHJ1Y3QgaW5wY2IgICAqZW50cnk7CiAgICBzdHJ1Y3QgdGNwY2IgICAgdGNwY2I7CiAgICBuZXRzbm1wX2lucGNiICAqbm5ldzsKICAgIGludCAgICAgIFN0YXRlTWFwW10gPSB7IDEsIDIsIDMsIDQsIDUsIDgsIDYsIDEwLCA5LCA3LCAxMSB9OwoKICAgIHRjcFRhYmxlX2ZyZWUoTlVMTCwgTlVMTCk7CgogICAgaWYgKCFhdXRvX25saXN0KFRDUF9TWU1CT0wsIChjaGFyICopICZ0YWJsZSwgc2l6ZW9mKHRhYmxlKSkpIHsKICAgICAgICBERUJVR01TR1RMKCgibWliSUkvdGNwVGFibGUiLCAiRmFpbGVkIHRvIHJlYWQgaW5wY2J0YWJsZVxuIikpOwogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICAvKgogICAgICogIFNldCB1cCBhIGxpbmtlZCBsaXN0CiAgICAgKi8KICAgIGVudHJ5ICA9IHRhYmxlLmlucHRfcXVldWUuY3FoX2ZpcnN0OwogICAgd2hpbGUgKGVudHJ5KSB7CiAgIAogICAgICAgIG5uZXcgPSBTTk1QX01BTExPQ19UWVBFREVGKG5ldHNubXBfaW5wY2IpOwogICAgICAgIGlmICghbm5ldykKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgaWYgKCFORVRTTk1QX0tMT09LVVAoZW50cnksIChjaGFyICopJihubmV3LT5wY2IpLCBzaXplb2Yoc3RydWN0IGlucGNiKSkpIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoIm1pYklJL3RjcFRhYmxlOlRjcFRhYmxlX2xvYWQiLCAia2xvb2t1cCBmYWlsZWRcbiIpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBpZiAoIU5FVFNOTVBfS0xPT0tVUChubmV3LT5wY2IuaW5wX3BwY2IsIChjaGFyICopJnRjcGNiLCBzaXplb2Yoc3RydWN0IHRjcGNiKSkpIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoIm1pYklJL3RjcFRhYmxlOlRjcFRhYmxlX2xvYWQiLCAia2xvb2t1cCBmYWlsZWRcbiIpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoJbm5ldy0+c3RhdGUgPSBTdGF0ZU1hcFt0Y3BjYi50X3N0YXRlXTsKICAgICAgICBpZiAobm5ldy0+c3RhdGUgPT0gNSAvKiBlc3RhYmxpc2hlZCAqLyB8fAogICAgICAgICAgICBubmV3LT5zdGF0ZSA9PSA4IC8qICBjbG9zZVdhaXQgICovICkKICAgICAgICAgICAgdGNwX2VzdGFiKys7CgogICAgICAgIGVudHJ5ICAgICAgPSBubmV3LT5JTlBfTkVYVF9TWU1CT0w7CS8qIE5leHQga2VybmVsIGVudHJ5ICovCglubmV3LT5pbnBfbmV4dCA9IHRjcF9oZWFkOwoJdGNwX2hlYWQgICA9IG5uZXc7CgogICAgICAgIGlmIChlbnRyeSA9PSB0YWJsZS5pbnB0X3F1ZXVlLmNxaF9maXJzdCkKICAgICAgICAgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKHRjcF9oZWFkKSB7CiAgICAgICAgREVCVUdNU0dUTCgoIm1pYklJL3RjcFRhYmxlIiwgIkxvYWRlZCBUQ1AgVGFibGUgKHBjYl90YWJsZSlcbiIpKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIERFQlVHTVNHVEwoKCJtaWJJSS90Y3BUYWJsZSIsICJGYWlsZWQgdG8gbG9hZCBUQ1AgVGFibGUgKHBjYl90YWJsZSlcbiIpKTsKICAgIHJldHVybiAtMTsKfQoKI2Vsc2UJCQkJLyogUENCX1RBQkxFICovCiNpZmRlZiBUQ1BfU1lNQk9MCmludAp0Y3BUYWJsZV9sb2FkKG5ldHNubXBfY2FjaGUgKmNhY2hlLCB2b2lkICp2bWFnaWMpCnsKICAgIHN0cnVjdCBpbnBjYiAgIHRjcF9pbnBjYjsKICAgIHN0cnVjdCB0Y3BjYiAgIHRjcGNiOwogICAgbmV0c25tcF9pbnBjYiAgKm5uZXc7CiAgICBzdHJ1Y3QgaW5wY2IgICAqZW50cnk7CiNpZmRlZiBocHV4CiAgICBpbnQgICAgICBTdGF0ZU1hcFtdID0geyAxLCAyLCAzLCAtMSwgNCwgNSwgOCwgNiwgMTAsIDksIDcsIDExIH07CiNlbHNlCiAgICBpbnQgICAgICBTdGF0ZU1hcFtdID0geyAxLCAyLCAzLCAgICAgNCwgNSwgOCwgNiwgMTAsIDksIDcsIDExIH07CiNlbmRpZgoKICAgIHRjcFRhYmxlX2ZyZWUoTlVMTCwgTlVMTCk7CgogICAgaWYgKCFhdXRvX25saXN0KFRDUF9TWU1CT0wsIChjaGFyICopICZ0Y3BfaW5wY2IsIHNpemVvZih0Y3BfaW5wY2IpKSkgewogICAgICAgIERFQlVHTVNHVEwoKCJtaWJJSS90Y3BUYWJsZSIsICJGYWlsZWQgdG8gcmVhZCB0Y3Bfc3ltYm9sXG4iKSk7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQoKICAgIC8qCiAgICAgKiAgU2V0IHVwIGEgbGlua2VkIGxpc3QKICAgICAqLwogICAgZW50cnkgID0gdGNwX2lucGNiLklOUF9ORVhUX1NZTUJPTDsKICAgIHdoaWxlIChlbnRyeSkgewogICAKICAgICAgICBubmV3ID0gU05NUF9NQUxMT0NfVFlQRURFRihuZXRzbm1wX2lucGNiKTsKICAgICAgICBpZiAoIW5uZXcpCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGlmICghTkVUU05NUF9LTE9PS1VQKGVudHJ5LCAoY2hhciAqKSYobm5ldy0+cGNiKSwgc2l6ZW9mKHN0cnVjdCBpbnBjYikpKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJtaWJJSS90Y3BUYWJsZTp0Y3BUYWJsZV9sb2FkIiwgImtsb29rdXAgZmFpbGVkXG4iKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBpZiAoIU5FVFNOTVBfS0xPT0tVUChubmV3LT5wY2IuaW5wX3BwY2IsIChjaGFyICopJnRjcGNiLCBzaXplb2Yoc3RydWN0IHRjcGNiKSkpIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoIm1pYklJL3RjcFRhYmxlOnRjcFRhYmxlX2xvYWQiLCAia2xvb2t1cCBmYWlsZWRcbiIpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoJbm5ldy0+c3RhdGUgICAgPSBTdGF0ZU1hcFt0Y3BjYi50X3N0YXRlXTsKICAgICAgICBpZiAobm5ldy0+c3RhdGUgPT0gNSAvKiBlc3RhYmxpc2hlZCAqLyB8fAogICAgICAgICAgICBubmV3LT5zdGF0ZSA9PSA4IC8qICBjbG9zZVdhaXQgICovICkKICAgICAgICAgICAgdGNwX2VzdGFiKys7CgogICAgICAgIGVudHJ5ICAgICAgICAgID0gbm5ldy0+cGNiLklOUF9ORVhUX1NZTUJPTDsJLyogTmV4dCBrZXJuZWwgZW50cnkgKi8KCW5uZXctPmlucF9uZXh0ID0gdGNwX2hlYWQ7Cgl0Y3BfaGVhZCAgICAgICA9IG5uZXc7CgogICAgICAgIGlmIChlbnRyeSA9PSB0Y3BfaW5wY2IuSU5QX05FWFRfU1lNQk9MKQogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICBpZiAodGNwX2hlYWQpIHsKICAgICAgICBERUJVR01TR1RMKCgibWliSUkvdGNwVGFibGUiLCAiTG9hZGVkIFRDUCBUYWJsZSAodGNwX3N5bWJvbClcbiIpKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIERFQlVHTVNHVEwoKCJtaWJJSS90Y3BUYWJsZSIsICJGYWlsZWQgdG8gbG9hZCBUQ1AgVGFibGUgKHRjcF9zeW1ib2wpXG4iKSk7CiAgICByZXR1cm4gLTE7Cn0KCiNlbHNlCQkJCS8qIFVEQl9TWU1CT0wgKi8KaW50CnRjcFRhYmxlX2xvYWQobmV0c25tcF9jYWNoZSAqY2FjaGUsIHZvaWQgKnZtYWdpYykKewogICAgREVCVUdNU0dUTCgoIm1pYklJL3RjcFRhYmxlIiwgIkxvYWRpbmcgVENQIFRhYmxlIG5vdCBpbXBsZW1lbnRlZFxuIikpOwogICAgcmV0dXJuIC0xOwp9CiNlbmRpZgkJCQkvKiBVREJfU1lNQk9MICovCiNlbmRpZgkJCQkvKiBQQ0JfVEFCTEUgKi8KI2VuZGlmCQkvKiAoZGVmaW5lZChORVRTTk1QX0NBTl9VU0VfU1lTQ1RMKSAmJiBkZWZpbmVkKFRDUENUTF9QQ0JMSVNUKSkgKi8KI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBXSU4zMiBjeWd3aW4gKi8KI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBsaW51eCAqLwojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHNvbGFyaXMyICovCiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogaHB1eDExICovCg==