LyoKICogQ29weXJpZ2h0IDE5OTUgTWFydGluIHZvbiBMb2V3aXMKICogQ29weXJpZ2h0IDE5OTggSnVzdGluIEJyYWRmb3JkCiAqIENvcHlyaWdodCAxOTk5IEZyYW5jaXMgQmVhdWRldAogKiBDb3B5cmlnaHQgMTk5OSBTeWx2YWluIFN0LUdlcm1haW4KICogQ29weXJpZ2h0IDIwMDIgTWFyY3VzIE1laXNzbmVyCiAqIENvcHlyaWdodCAyMDAzIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNpZm5kZWYgX19XSU5FX09MRV9DT01QT0JKX0gKI2RlZmluZSBfX1dJTkVfT0xFX0NPTVBPQkpfSAoKLyogQWxsIHByaXZhdGUgcHJvdG90eXBlIGZ1bmN0aW9ucyB1c2VkIGJ5IE9MRSB3aWxsIGJlIGFkZGVkIHRvIHRoaXMgaGVhZGVyIGZpbGUgKi8KCiNpbmNsdWRlICJ3dHlwZXMuaCIKI2luY2x1ZGUgImRjb20uaCIKI2luY2x1ZGUgInRocmVhZC5oIgoKLyogZXhwb3J0ZWQgaW50ZXJmYWNlICovCnR5cGVkZWYgc3RydWN0IHRhZ1hJRiB7CiAgc3RydWN0IHRhZ1hJRiAqbmV4dDsKICBMUFZPSUQgaWZhY2U7ICAgICAgICAgICAgLyogaW50ZXJmYWNlIHBvaW50ZXIgKi8KICBJSUQgaWlkOyAgICAgICAgICAgICAgICAgLyogaW50ZXJmYWNlIElEICovCiAgSVBJRCBpcGlkOyAgICAgICAgICAgICAgIC8qIGV4cG9ydGVkIGludGVyZmFjZSBJRCAqLwogIExQUlBDU1RVQkJVRkZFUiBzdHViOyAgICAvKiBpbnRlcmZhY2Ugc3R1YiAqLwogIERXT1JEIHJlZnM7ICAgICAgICAgICAgICAvKiBleHRlcm5hbCByZWZlcmVuY2UgY291bnQgKi8KICBIUkVTVUxUIGhyZXM7ICAgICAgICAgICAgLyogcmVzdWx0IG9mIHN0dWIgY3JlYXRpb24gYXR0ZW1wdCAqLwp9IFhJRjsKCi8qIGV4cG9ydGVkIG9iamVjdCAqLwp0eXBlZGVmIHN0cnVjdCB0YWdYT0JKRUNUIHsKICBJQ09NX1ZUQUJMRShJUnBjU3R1YkJ1ZmZlcikgKmxwVnRibDsKICBzdHJ1Y3QgdGFnQVBBUlRNRU5UICpwYXJlbnQ7CiAgc3RydWN0IHRhZ1hPQkpFQ1QgKm5leHQ7CiAgTFBVTktOT1dOIG9iajsgICAgICAgICAgIC8qIG9iamVjdCBpZGVudGl0eSAoSVVua25vd24pICovCiAgT0lEIG9pZDsgICAgICAgICAgICAgICAgIC8qIG9iamVjdCBJRCAqLwogIERXT1JEIGlmYzsgICAgICAgICAgICAgICAvKiBpbnRlcmZhY2UgSUQgY291bnRlciAqLwogIFhJRiAqaWZhY2VzOyAgICAgICAgICAgICAvKiBleHBvcnRlZCBpbnRlcmZhY2VzICovCiAgRFdPUkQgcmVmczsgICAgICAgICAgICAgIC8qIGV4dGVybmFsIHJlZmVyZW5jZSBjb3VudCAqLwp9IFhPQkpFQ1Q7CgovKiBpbXBvcnRlZCBpbnRlcmZhY2UgKi8KdHlwZWRlZiBzdHJ1Y3QgdGFnSUlGIHsKICBzdHJ1Y3QgdGFnSUlGICpuZXh0OwogIExQVk9JRCBpZmFjZTsgICAgICAgICAgICAvKiBpbnRlcmZhY2UgcG9pbnRlciAqLwogIElJRCBpaWQ7ICAgICAgICAgICAgICAgICAvKiBpbnRlcmZhY2UgSUQgKi8KICBJUElEIGlwaWQ7ICAgICAgICAgICAgICAgLyogaW1wb3J0ZWQgaW50ZXJmYWNlIElEICovCiAgTFBSUENQUk9YWUJVRkZFUiBwcm94eTsgIC8qIGludGVyZmFjZSBwcm94eSAqLwogIERXT1JEIHJlZnM7ICAgICAgICAgICAgICAvKiBpbXBvcnRlZCAocHVibGljKSByZWZlcmVuY2VzICovCiAgSFJFU1VMVCBocmVzOyAgICAgICAgICAgIC8qIHJlc3VsdCBvZiBwcm94eSBjcmVhdGlvbiBhdHRlbXB0ICovCn0gSUlGOwoKLyogaW1wb3J0ZWQgb2JqZWN0ICovCnR5cGVkZWYgc3RydWN0IHRhZ0lPQkpFQ1QgewogIElDT01fVlRBQkxFKElSZW1Vbmtub3duKSAqbHBWdGJsOwogIHN0cnVjdCB0YWdBUEFSVE1FTlQgKnBhcmVudDsKICBzdHJ1Y3QgdGFnSU9CSkVDVCAqbmV4dDsKICBMUFJQQ0NIQU5ORUxCVUZGRVIgY2hhbjsgLyogY2hhbm5lbCB0byBvYmplY3QgKi8KICBPWElEIG94aWQ7ICAgICAgICAgICAgICAgLyogb2JqZWN0IGV4cG9ydGVkIElEICovCiAgT0lEIG9pZDsgICAgICAgICAgICAgICAgIC8qIG9iamVjdCBJRCAqLwogIElQSUQgaXBpZDsgICAgICAgICAgICAgICAvKiBmaXJzdCBpbXBvcnRlZCBpbnRlcmZhY2UgSUQgKi8KICBJSUYgKmlmYWNlczsgICAgICAgICAgICAgLyogaW1wb3J0ZWQgaW50ZXJmYWNlcyAqLwogIERXT1JEIHJlZnM7ICAgICAgICAgICAgICAvKiBwcm94eSByZWZlcmVuY2UgY291bnQgKi8KfSBJT0JKRUNUOwoKLyogYXBhcnRtZW50ICovCnR5cGVkZWYgc3RydWN0IHRhZ0FQQVJUTUVOVCB7CiAgc3RydWN0IHRhZ0FQQVJUTUVOVCAqbmV4dCwgKnByZXYsICpwYXJlbnQ7CiAgRFdPUkQgbW9kZWw7ICAgICAgICAgICAgIC8qIHRocmVhZGluZyBtb2RlbCAqLwogIERXT1JEIGluaXRzOyAgICAgICAgICAgICAvKiBDb0luaXRpYWxpemUgY291bnQgKi8KICBEV09SRCB0aWQ7ICAgICAgICAgICAgICAgLyogdGhyZWFkIGlkICovCiAgSEFORExFIHRocmVhZDsgICAgICAgICAgIC8qIHRocmVhZCBoYW5kbGUgKi8KICBPWElEIG94aWQ7ICAgICAgICAgICAgICAgLyogb2JqZWN0IGV4cG9ydGVyIElEICovCiAgT0lEIG9pZGM7ICAgICAgICAgICAgICAgIC8qIG9iamVjdCBJRCBjb3VudGVyICovCiAgSFdORCB3aW47ICAgICAgICAgICAgICAgIC8qIG1lc3NhZ2Ugd2luZG93ICovCiAgQ1JJVElDQUxfU0VDVElPTiBjczsgICAgIC8qIHRocmVhZCBzYWZldHkgKi8KICBMUE1FU1NBR0VGSUxURVIgZmlsdGVyOyAgLyogbWVzc2FnZSBmaWx0ZXIgKi8KICBYT0JKRUNUICpvYmpzOyAgICAgICAgICAgLyogZXhwb3J0ZWQgb2JqZWN0cyAqLwogIElPQkpFQ1QgKnByb3hpZXM7ICAgICAgICAvKiBpbXBvcnRlZCBvYmplY3RzICovCiAgTFBWT0lEIEVycm9ySW5mbzsgICAgICAgIC8qIHRocmVhZCBlcnJvciBpbmZvICovCn0gQVBBUlRNRU5UOwoKZXh0ZXJuIEFQQVJUTUVOVCBNVEEsICphcHRzOwoKZXh0ZXJuIHZvaWQqIFN0ZEdsb2JhbEludGVyZmFjZVRhYmxlX0NvbnN0cnVjdCgpOwpleHRlcm4gdm9pZCAgU3RkR2xvYmFsSW50ZXJmYWNlVGFibGVfRGVzdHJveSh2b2lkKiBzZWxmKTsKZXh0ZXJuIEhSRVNVTFQgU3RkR2xvYmFsSW50ZXJmYWNlVGFibGVfR2V0RmFjdG9yeShMUFZPSUQgKnBwdik7CgpleHRlcm4gSFJFU1VMVCBXSU5FX1N0cmluZ0Zyb21DTFNJRChjb25zdCBDTFNJRCAqaWQsTFBTVFIgaWRzdHIpOwpleHRlcm4gSFJFU1VMVCBjcmVhdGVfbWFyc2hhbGxlZF9wcm94eShSRUZDTFNJRCByY2xzaWQsIFJFRklJRCBpaWQsIExQVk9JRCAqcHB2KTsKCmV4dGVybiB2b2lkKiBTdGRHbG9iYWxJbnRlcmZhY2VUYWJsZUluc3RhbmNlOwoKaW5saW5lIHN0YXRpYyBIUkVTVUxUCmdldF9mYWNidWZfZm9yX2lpZChSRUZJSUQgcmlpZCxJUFNGYWN0b3J5QnVmZmVyICoqZmFjYnVmKSB7CiAgICBIUkVTVUxUICAgICAgIGhyZXM7CiAgICBDTFNJRCAgICAgICAgIHB4Y2xzaWQ7CgogICAgaWYgKChocmVzID0gQ29HZXRQU0Nsc2lkKHJpaWQsJnB4Y2xzaWQpKSkKCXJldHVybiBocmVzOwogICAgcmV0dXJuIENvR2V0Q2xhc3NPYmplY3QoJnB4Y2xzaWQsQ0xTQ1RYX0lOUFJPQ19TRVJWRVIsTlVMTCwmSUlEX0lQU0ZhY3RvcnlCdWZmZXIsKExQVk9JRCopZmFjYnVmKTsKfQoKI2RlZmluZSBQSVBFUFJFRiAiXFxcXC5cXHBpcGVcXCIKI2RlZmluZSBPTEVTVFVCTUdSIFBJUEVQUkVGIldJTkVfT0xFX1N0dWJNZ3IiCi8qIFN0YW5kYXJkIE1hcnNoYWxsaW5nIGRlZmluaXRpb25zICovCnR5cGVkZWYgc3RydWN0IF93aW5lX21hcnNoYWxfaWQgewogICAgRFdPUkQJcHJvY2Vzc2lkOwogICAgRFdPUkQJb2JqZWN0aWQ7CS8qIHVuaXF1ZSB2YWx1ZSBjb3JyZXNwLiBJVW5rbm93biBvZiBvYmplY3QgKi8KICAgIElJRAkJaWlkOwp9IHdpbmVfbWFyc2hhbF9pZDsKCmlubGluZSBzdGF0aWMgQk9PTApNQVJTSEFMX0NvbXBhcmVfTWlkcyh3aW5lX21hcnNoYWxfaWQgKm1pZDEsd2luZV9tYXJzaGFsX2lkICptaWQyKSB7CiAgICByZXR1cm4KCShtaWQxLT5wcm9jZXNzaWQgPT0gbWlkMi0+cHJvY2Vzc2lkKQkmJgoJKG1pZDEtPm9iamVjdGlkID09IG1pZDItPm9iamVjdGlkKQkmJgoJSXNFcXVhbElJRCgmKG1pZDEtPmlpZCksJihtaWQyLT5paWQpKQogICAgOwp9CgovKiBjb21wYXJlIHdpdGhvdXQgaW50ZXJmYWNlIGNvbXBhcmUgKi8KaW5saW5lIHN0YXRpYyBCT09MCk1BUlNIQUxfQ29tcGFyZV9NaWRzX05vSW50ZXJmYWNlKHdpbmVfbWFyc2hhbF9pZCAqbWlkMSwgd2luZV9tYXJzaGFsX2lkICptaWQyKSB7CiAgICByZXR1cm4KCShtaWQxLT5wcm9jZXNzaWQgPT0gbWlkMi0+cHJvY2Vzc2lkKQkmJgoJKG1pZDEtPm9iamVjdGlkID09IG1pZDItPm9iamVjdGlkKQogICAgOwp9CgpIUkVTVUxUIE1BUlNIQUxfRmluZF9TdHViX0J1ZmZlcih3aW5lX21hcnNoYWxfaWQgKm1pZCxJUnBjU3R1YkJ1ZmZlciAqKnN0dWIpOwpIUkVTVUxUIE1BUlNIQUxfRmluZF9TdHViX1NlcnZlcih3aW5lX21hcnNoYWxfaWQgKm1pZCxMUFVOS05PV04gKnB1bmspOwpIUkVTVUxUIE1BUlNIQUxfUmVnaXN0ZXJfU3R1Yih3aW5lX21hcnNoYWxfaWQgKm1pZCxMUFVOS05PV04gcHVuaywgSVJwY1N0dWJCdWZmZXIgKnN0dWIpOwoKSFJFU1VMVCBNQVJTSEFMX0dldFN0YW5kYXJkTWFyc2hhbENGKExQVk9JRCAqcHB2KTsKCnR5cGVkZWYgc3RydWN0IF93aW5lX21hcnNoYWxfZGF0YSB7CiAgICBEV09SRAlkd0Rlc3RDb250ZXh0OwogICAgRFdPUkQJbXNobGZsYWdzOwp9IHdpbmVfbWFyc2hhbF9kYXRhOwoKCiNkZWZpbmUgUkVRVFlQRV9SRVFVRVNUCQkwCnR5cGVkZWYgc3RydWN0IF93aW5lX3JwY19yZXF1ZXN0X2hlYWRlciB7CiAgICBEV09SRAkJcmVxaWQ7CiAgICB3aW5lX21hcnNoYWxfaWQJbWlkOwogICAgRFdPUkQJCWlNZXRob2Q7CiAgICBEV09SRAkJY2JCdWZmZXI7Cn0gd2luZV9ycGNfcmVxdWVzdF9oZWFkZXI7CgojZGVmaW5lIFJFUVRZUEVfUkVTUE9OU0UJMQp0eXBlZGVmIHN0cnVjdCBfd2luZV9ycGNfcmVzcG9uc2VfaGVhZGVyIHsKICAgIERXT1JECQlyZXFpZDsKICAgIERXT1JECQljYkJ1ZmZlcjsKICAgIERXT1JECQlyZXR2YWw7Cn0gd2luZV9ycGNfcmVzcG9uc2VfaGVhZGVyOwoKI2RlZmluZSBSRVFTVEFURV9TVEFSVAkJCTAKI2RlZmluZSBSRVFTVEFURV9SRVFfUVVFVUVECQkxCiNkZWZpbmUgUkVRU1RBVEVfUkVRX1dBSVRJTkdfRk9SX1JFUExZCTIKI2RlZmluZSBSRVFTVEFURV9SRVFfR09UCQkzCiNkZWZpbmUgUkVRU1RBVEVfSU5WT0tJTkcJCTQKI2RlZmluZSBSRVFTVEFURV9SRVNQX1FVRVVFRAkJNQojZGVmaW5lIFJFUVNUQVRFX1JFU1BfR09UCQk2CiNkZWZpbmUgUkVRU1RBVEVfRE9ORQkJCTYKCnZvaWQgU1RVQk1HUl9TdGFydCgpOwoKZXh0ZXJuIEhSRVNVTFQgUElQRV9HZXROZXdQaXBlQnVmKHdpbmVfbWFyc2hhbF9pZCAqbWlkLCBJUnBjQ2hhbm5lbEJ1ZmZlciAqKnBpcGVidWYpOwoKLyogVGhpcyBmdW5jdGlvbiBpbml0aWFsaXplIHRoZSBSdW5uaW5nIE9iamVjdCBUYWJsZSAqLwpIUkVTVUxUIFdJTkFQSSBSdW5uaW5nT2JqZWN0VGFibGVJbXBsX0luaXRpYWxpemUoKTsKCi8qIFRoaXMgZnVuY3Rpb24gdW5pbml0aWFsaXplIHRoZSBSdW5uaW5nIE9iamVjdCBUYWJsZSAqLwpIUkVTVUxUIFdJTkFQSSBSdW5uaW5nT2JqZWN0VGFibGVJbXBsX1VuSW5pdGlhbGl6ZSgpOwoKLyogVGhpcyBmdW5jdGlvbiBkZWNvbXBvc2VzIGEgU3RyaW5nIHBhdGggdG8gYSBTdHJpbmcgVGFibGUgY29udGFpbmluZyBhbGwgdGhlIGVsZW1lbnRzICgiXCIgb3IgInN1YkRpcmVjdG9yeSIgb3IgIkRpcmVjdG9yeSIgb3IgIkZpbGVOYW1lIikgb2YgdGhlIHBhdGggKi8KaW50IFdJTkFQSSBGaWxlTW9uaWtlckltcGxfRGVjb21wb3NlUGF0aChMUENPTEVTVFIgc3RyLCBMUE9MRVNUUioqIHN0cmluZ1RhYmxlKTsKCkhSRVNVTFQgV0lOQVBJIF9fQ0xTSURGcm9tU3RyaW5nQShMUENTVFIgaWRzdHIsIENMU0lEICppZCk7CgovKgogKiBQZXItdGhyZWFkIHZhbHVlcyBhcmUgc3RvcmVkIGluIHRoZSBURUIgb24gb2Zmc2V0IDB4RjgwLAogKiBzZWUgaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL21zai8xMDk5L2J1Z3NsYXllci9idWdzbGF5ZXIxMDk5Lmh0bQogKi8Kc3RhdGljIGlubGluZSBBUEFSVE1FTlQqIENPTV9DdXJyZW50SW5mbyh2b2lkKSBXSU5FX1VOVVNFRDsKc3RhdGljIGlubGluZSBBUEFSVE1FTlQqIENPTV9DdXJyZW50SW5mbyh2b2lkKQp7CiAgQVBBUlRNRU5UKiBhcHQgPSBOdEN1cnJlbnRUZWIoKS0+RXJyb3JJbmZvOwogIHJldHVybiBhcHQ7Cn0Kc3RhdGljIGlubGluZSBBUEFSVE1FTlQqIENPTV9DdXJyZW50QXB0KHZvaWQpIFdJTkVfVU5VU0VEOwpzdGF0aWMgaW5saW5lIEFQQVJUTUVOVCogQ09NX0N1cnJlbnRBcHQodm9pZCkKewogIEFQQVJUTUVOVCogYXB0ID0gQ09NX0N1cnJlbnRJbmZvKCk7CiAgaWYgKGFwdCAmJiBhcHQtPnBhcmVudCkgYXB0ID0gYXB0LT5wYXJlbnQ7CiAgcmV0dXJuIGFwdDsKfQoKLyogY29tcG9iai5jICovCkhXTkQgQ09NX0dldEFwYXJ0bWVudFdpbihPWElEIG94aWQpOwoKI2VuZGlmIC8qIF9fV0lORV9PTEVfQ09NUE9CSl9IICovCg==