LyoKICogRE9TIGludGVycnVwdCAzM2ggaGFuZGxlcgogKgogKiBDb3B5cmlnaHQgMTk5OSBPdmUgS+V2ZW4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCiAqLwoKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIm1pc2NlbXUuaCIKI2luY2x1ZGUgImRvc2V4ZS5oIgojaW5jbHVkZSAidmdhLmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChpbnQpOwoKc3RhdGljIHN0cnVjdAp7CiAgRFdPUkQgeCwgeSwgYnV0OwogIFdPUkQgbGJjb3VudCwgcmJjb3VudCwgcmxhc3R4LCBybGFzdHksIGxsYXN0eCwgbGxhc3R5OwogIEZBUlBST0MxNiBjYWxsYmFjazsKICBXT1JEIGNhbGxtYXNrOwogIFdPUkQgVk1QcmF0aW8sIEhNUHJhdGlvLCBvbGR4LCBvbGR5Owp9IG1vdXNlX2luZm87CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkgICAgRE9TVk1fSW50MzNIYW5kbGVyCiAqCiAqIEhhbmRsZXIgZm9yIGludCAzM2ggKE1TIE1PVVNFKS4KICovCnZvaWQgV0lOQVBJIERPU1ZNX0ludDMzSGFuZGxlciggQ09OVEVYVDg2ICpjb250ZXh0ICkKewogIHN3aXRjaCAoTE9XT1JEKGNvbnRleHQtPkVheCkpIHsKICBjYXNlIDB4MDA6CiAgICBUUkFDRSgiUmVzZXQgbW91c2UgZHJpdmVyIGFuZCByZXF1ZXN0IHN0YXR1c1xuIik7CiAgICBBWF9yZWcoY29udGV4dCkgPSAweEZGRkY7IC8qIGluc3RhbGxlZCAqLwogICAgQlhfcmVnKGNvbnRleHQpID0gMzsgICAgICAvKiAjIG9mIGJ1dHRvbnMgKi8KICAgIG1lbXNldCggJm1vdXNlX2luZm8sIDAsIHNpemVvZihtb3VzZV9pbmZvKSApOwogICAgLyogU2V0IHRoZSBkZWZhdWx0IG1pY2tleS9waXhlbCByYXRpbyAqLwogICAgbW91c2VfaW5mby5ITVByYXRpbyA9IDg7CiAgICBtb3VzZV9pbmZvLlZNUHJhdGlvID0gMTY7CiAgICBicmVhazsKICBjYXNlIDB4MDE6CiAgICBGSVhNRSgiU2hvdyBtb3VzZSBjdXJzb3JcbiIpOwogICAgYnJlYWs7CiAgY2FzZSAweDAyOgogICAgRklYTUUoIkhpZGUgbW91c2UgY3Vyc29yXG4iKTsKICAgIGJyZWFrOwogIGNhc2UgMHgwMzoKICAgIFRSQUNFKCJSZXR1cm4gbW91c2UgcG9zaXRpb24gYW5kIGJ1dHRvbiBzdGF0dXM6ICglbGQsJWxkKSBhbmQgJWxkXG4iLAogICAgICAgICBtb3VzZV9pbmZvLngsIG1vdXNlX2luZm8ueSwgbW91c2VfaW5mby5idXQpOwogICAgQlhfcmVnKGNvbnRleHQpID0gbW91c2VfaW5mby5idXQ7CiAgICBDWF9yZWcoY29udGV4dCkgPSBtb3VzZV9pbmZvLng7CiAgICBEWF9yZWcoY29udGV4dCkgPSBtb3VzZV9pbmZvLnk7CiAgICBicmVhazsKICBjYXNlIDB4MDQ6CiAgICBGSVhNRSgiUG9zaXRpb24gbW91c2UgY3Vyc29yXG4iKTsKICAgIGJyZWFrOwogIGNhc2UgMHgwNToKICAgIFRSQUNFKCJSZXR1cm4gTW91c2UgYnV0dG9uIHByZXNzIEluZm9ybWF0aW9uIGZvciAlcyBtb3VzZSBidXR0b25cbiIsCiAgICAgICAgICBCWF9yZWcoY29udGV4dCkgPyAicmlnaHQiIDogImxlZnQiKTsKICAgIGlmIChCWF9yZWcoY29udGV4dCkpIHsKICAgICAgQlhfcmVnKGNvbnRleHQpID0gbW91c2VfaW5mby5yYmNvdW50OwogICAgICBtb3VzZV9pbmZvLnJiY291bnQgPSAwOwogICAgICBDWF9yZWcoY29udGV4dCkgPSBtb3VzZV9pbmZvLnJsYXN0eDsKICAgICAgRFhfcmVnKGNvbnRleHQpID0gbW91c2VfaW5mby5ybGFzdHk7CiAgICB9IGVsc2UgewogICAgICBCWF9yZWcoY29udGV4dCkgPSBtb3VzZV9pbmZvLmxiY291bnQ7CiAgICAgIG1vdXNlX2luZm8ubGJjb3VudCA9IDA7CiAgICAgIENYX3JlZyhjb250ZXh0KSA9IG1vdXNlX2luZm8ubGxhc3R4OwogICAgICBEWF9yZWcoY29udGV4dCkgPSBtb3VzZV9pbmZvLmxsYXN0eTsKICAgIH0KICAgIEFYX3JlZyhjb250ZXh0KSA9IG1vdXNlX2luZm8uYnV0OwogICAgYnJlYWs7CiAgY2FzZSAweDA3OgogICAgRklYTUUoIkRlZmluZSBob3Jpem9udGFsIG1vdXNlIGN1cnNvciByYW5nZVxuIik7CiAgICBicmVhazsKICBjYXNlIDB4MDg6CiAgICBGSVhNRSgiRGVmaW5lIHZlcnRpY2FsIG1vdXNlIGN1cnNvciByYW5nZVxuIik7CiAgICBicmVhazsKICBjYXNlIDB4MDk6CiAgICBGSVhNRSgiRGVmaW5lIGdyYXBoaWNzIG1vdXNlIGN1cnNvclxuIik7CiAgICBicmVhazsKICBjYXNlIDB4MEE6CiAgICBGSVhNRSgiRGVmaW5lIHRleHQgbW91c2UgY3Vyc29yXG4iKTsKICAgIGJyZWFrOwogIGNhc2UgMHgwQjoKICAgIFRSQUNFKCJSZWFkIE1vdXNlIG1vdGlvbiBjb3VudGVyc1xuIik7CiAgICBDWF9yZWcoY29udGV4dCkgPSAobW91c2VfaW5mby54IC0gbW91c2VfaW5mby5vbGR4KSAqIChtb3VzZV9pbmZvLkhNUHJhdGlvIC8gOCk7CiAgICBEWF9yZWcoY29udGV4dCkgPSAobW91c2VfaW5mby55IC0gbW91c2VfaW5mby5vbGR5KSAqIChtb3VzZV9pbmZvLlZNUHJhdGlvIC8gOCk7CiAgICBtb3VzZV9pbmZvLm9sZHggPSBtb3VzZV9pbmZvLng7CiAgICBtb3VzZV9pbmZvLm9sZHkgPSBtb3VzZV9pbmZvLnk7CiAgICBicmVhazsKICBjYXNlIDB4MEM6CiAgICBUUkFDRSgiRGVmaW5lIG1vdXNlIGludGVycnVwdCBzdWJyb3V0aW5lXG4iKTsKICAgIG1vdXNlX2luZm8uY2FsbG1hc2sgPSBDWF9yZWcoY29udGV4dCk7CiAgICBtb3VzZV9pbmZvLmNhbGxiYWNrID0gKEZBUlBST0MxNilNQUtFU0VHUFRSKGNvbnRleHQtPlNlZ0VzLCBMT1dPUkQoY29udGV4dC0+RWR4KSk7CiAgICBicmVhazsKICBjYXNlIDB4MEY6CiAgICBUUkFDRSgiU2V0IG1pY2tleS9waXhlbCByYXRpb1xuIik7CiAgICBtb3VzZV9pbmZvLkhNUHJhdGlvID0gQ1hfcmVnKGNvbnRleHQpOwogICAgbW91c2VfaW5mby5WTVByYXRpbyA9IERYX3JlZyhjb250ZXh0KTsKICAgIGJyZWFrOwogIGNhc2UgMHgxMDoKICAgIEZJWE1FKCJEZWZpbmUgc2NyZWVuIHJlZ2lvbiBmb3IgdXBkYXRlXG4iKTsKICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICBJTlRfQkFSRihjb250ZXh0LDB4MzMpOwogIH0KfQoKdHlwZWRlZiBzdHJ1Y3QgewogIEZBUlBST0MxNiBwcm9jOwogIFdPUkQgbWFzayxidXQseCx5LG14LG15Owp9IE1DQUxMREFUQTsKCnN0YXRpYyB2b2lkIE1vdXNlUmVsYXkoQ09OVEVYVDg2ICpjb250ZXh0LHZvaWQgKm1kYXRhKQp7CiAgTUNBTExEQVRBICpkYXRhID0gKE1DQUxMREFUQSAqKW1kYXRhOwogIENPTlRFWFQ4NiBjdHggPSAqY29udGV4dDsKCiAgY3R4LkVheCAgID0gZGF0YS0+bWFzazsKICBjdHguRWJ4ICAgPSBkYXRhLT5idXQ7CiAgY3R4LkVjeCAgID0gZGF0YS0+eDsKICBjdHguRWR4ICAgPSBkYXRhLT55OwogIGN0eC5Fc2kgICA9IGRhdGEtPm14OwogIGN0eC5FZGkgICA9IGRhdGEtPm15OwogIGN0eC5TZWdDcyA9IFNFTEVDVE9ST0YoZGF0YS0+cHJvYyk7CiAgY3R4LkVpcCAgID0gT0ZGU0VUT0YoZGF0YS0+cHJvYyk7CiAgZnJlZShkYXRhKTsKICBEUE1JX0NhbGxSTVByb2MoJmN0eCwgTlVMTCwgMCwgMCk7Cn0KCnN0YXRpYyB2b2lkIFF1ZXVlTW91c2VSZWxheShEV09SRCBteCwgRFdPUkQgbXksIFdPUkQgbWFzaykKewogIG1vdXNlX2luZm8ueCA9IG14OwogIG1vdXNlX2luZm8ueSA9IG15OwoKICAvKiBMZWZ0IGJ1dHRvbiBkb3duICovCiAgaWYobWFzayAmIDB4MDIpIHsKICAgIG1vdXNlX2luZm8uYnV0IHw9IDB4MDE7CiAgICBtb3VzZV9pbmZvLmxsYXN0eCA9IG14OwogICAgbW91c2VfaW5mby5sbGFzdHkgPSBteTsKICAgIG1vdXNlX2luZm8ubGJjb3VudCsrOwogIH0KCiAgLyogTGVmdCBidXR0b24gdXAgKi8KICBpZihtYXNrICYgMHgwNCkgewogICAgbW91c2VfaW5mby5idXQgJj0gfjB4MDE7CiAgfQoKICAvKiBSaWdodCBidXR0b24gZG93biAqLwogIGlmKG1hc2sgJiAweDA4KSB7CiAgICBtb3VzZV9pbmZvLmJ1dCB8PSAweDAyOwogICAgbW91c2VfaW5mby5ybGFzdHggPSBteDsKICAgIG1vdXNlX2luZm8ucmxhc3R5ID0gbXk7CiAgICBtb3VzZV9pbmZvLnJiY291bnQrKzsKICB9CgogIC8qIFJpZ2h0IGJ1dHRvbiB1cCAqLwogIGlmKG1hc2sgJiAweDEwKSB7CiAgICBtb3VzZV9pbmZvLmJ1dCAmPSB+MHgwMjsKICB9CgogIC8qIE1pZGRsZSBidXR0b24gZG93biAqLwogIGlmKG1hc2sgJiAweDIwKSB7CiAgICBtb3VzZV9pbmZvLmJ1dCB8PSAweDA0OwogIH0KCiAgLyogTWlkZGxlIGJ1dHRvbiB1cCAqLwogIGlmKG1hc2sgJiAweDQwKSB7CiAgICBtb3VzZV9pbmZvLmJ1dCAmPSB+MHgwNDsKICB9CgogIGlmICgobWFzayAmIG1vdXNlX2luZm8uY2FsbG1hc2spICYmIG1vdXNlX2luZm8uY2FsbGJhY2spIHsKICAgIE1DQUxMREFUQSAqZGF0YSA9IGNhbGxvYygxLHNpemVvZihNQ0FMTERBVEEpKTsKICAgIGRhdGEtPnByb2MgPSBtb3VzZV9pbmZvLmNhbGxiYWNrOwogICAgZGF0YS0+bWFzayA9IG1hc2sgJiBtb3VzZV9pbmZvLmNhbGxtYXNrOwogICAgZGF0YS0+YnV0ID0gbW91c2VfaW5mby5idXQ7CiAgICBkYXRhLT54ID0gbW91c2VfaW5mby54OwogICAgZGF0YS0+eSA9IG1vdXNlX2luZm8ueTsKICAgIERPU1ZNX1F1ZXVlRXZlbnQoLTEsIERPU19QUklPUklUWV9NT1VTRSwgTW91c2VSZWxheSwgZGF0YSk7CiAgfQp9Cgp2b2lkIFdJTkFQSSBET1NWTV9JbnQzM01lc3NhZ2UoVUlOVCBtZXNzYWdlLFdQQVJBTSB3UGFyYW0sTFBBUkFNIGxQYXJhbSkKewogIFdPUkQgbWFzayA9IDA7CiAgdW5zaWduZWQgSGVpZ2h0LCBXaWR0aCwgU1g9MSwgU1k9MTsKCiAgaWYgKCFWR0FfR2V0TW9kZSgmSGVpZ2h0LCZXaWR0aCxOVUxMKSkgewogICAgLyogbWF5IG5lZWQgdG8gZG8gc29tZSBjb29yZGluYXRlIHNjYWxpbmcgKi8KICAgIGlmIChXaWR0aCkgCiAgICAgIFNYID0gNjQwL1dpZHRoOwogICAgaWYgKCFTWCkgU1g9MTsKICB9CgogIHN3aXRjaCAobWVzc2FnZSkgewogIGNhc2UgV01fTU9VU0VNT1ZFOgogICAgbWFzayB8PSAweDAxOwogICAgYnJlYWs7CiAgY2FzZSBXTV9MQlVUVE9ORE9XTjoKICBjYXNlIFdNX0xCVVRUT05EQkxDTEs6CiAgICBtYXNrIHw9IDB4MDI7CiAgICBicmVhazsKICBjYXNlIFdNX0xCVVRUT05VUDoKICAgIG1hc2sgfD0gMHgwNDsKICAgIGJyZWFrOwogIGNhc2UgV01fUkJVVFRPTkRPV046CiAgY2FzZSBXTV9SQlVUVE9OREJMQ0xLOgogICAgbWFzayB8PSAweDA4OwogICAgYnJlYWs7CiAgY2FzZSBXTV9SQlVUVE9OVVA6CiAgICBtYXNrIHw9IDB4MTA7CiAgICBicmVhazsKICBjYXNlIFdNX01CVVRUT05ET1dOOgogIGNhc2UgV01fTUJVVFRPTkRCTENMSzoKICAgIG1hc2sgfD0gMHgyMDsKICAgIGJyZWFrOwogIGNhc2UgV01fTUJVVFRPTlVQOgogICAgbWFzayB8PSAweDQwOwogICAgYnJlYWs7CiAgfQoKICBRdWV1ZU1vdXNlUmVsYXkoTE9XT1JEKGxQYXJhbSkgKiBTWCwKICAgICAgICAgICAgICAgICBISVdPUkQobFBhcmFtKSAqIFNZLAogICAgICAgICAgICAgICAgIG1hc2spOwp9Cgp2b2lkIFdJTkFQSSBET1NWTV9JbnQzM0NvbnNvbGUoTU9VU0VfRVZFTlRfUkVDT1JEICpyZWNvcmQpCnsKICB1bnNpZ25lZCBIZWlnaHQsIFdpZHRoOwogIFdPUkQgbWFzayA9IDA7CiAgQk9PTCBuZXdMZWZ0QnV0dG9uID0gcmVjb3JkLT5kd0J1dHRvblN0YXRlICYgRlJPTV9MRUZUXzFTVF9CVVRUT05fUFJFU1NFRDsKICBCT09MIG9sZExlZnRCdXR0b24gPSBtb3VzZV9pbmZvLmJ1dCAmIDB4MDE7CiAgQk9PTCBuZXdSaWdodEJ1dHRvbiA9IHJlY29yZC0+ZHdCdXR0b25TdGF0ZSAmIFJJR0hUTU9TVF9CVVRUT05fUFJFU1NFRDsKICBCT09MIG9sZFJpZ2h0QnV0dG9uID0gbW91c2VfaW5mby5idXQgJiAweDAyOwogIEJPT0wgbmV3TWlkZGxlQnV0dG9uID0gcmVjb3JkLT5kd0J1dHRvblN0YXRlICYgRlJPTV9MRUZUXzJORF9CVVRUT05fUFJFU1NFRDsKICBCT09MIG9sZE1pZGRsZUJ1dHRvbiA9IG1vdXNlX2luZm8uYnV0ICYgMHgwNDsKCiAgaWYobmV3TGVmdEJ1dHRvbiAmJiAhb2xkTGVmdEJ1dHRvbikKICAgIG1hc2sgfD0gMHgwMjsKICBlbHNlIGlmKCFuZXdMZWZ0QnV0dG9uICYmIG9sZExlZnRCdXR0b24pCiAgICBtYXNrIHw9IDB4MDQ7CgogIGlmKG5ld1JpZ2h0QnV0dG9uICYmICFvbGRSaWdodEJ1dHRvbikKICAgIG1hc2sgfD0gMHgwODsKICBlbHNlIGlmKCFuZXdSaWdodEJ1dHRvbiAmJiBvbGRSaWdodEJ1dHRvbikKICAgIG1hc2sgfD0gMHgxMDsKCiAgaWYobmV3TWlkZGxlQnV0dG9uICYmICFvbGRNaWRkbGVCdXR0b24pCiAgICBtYXNrIHw9IDB4MjA7CiAgZWxzZSBpZighbmV3TWlkZGxlQnV0dG9uICYmIG9sZE1pZGRsZUJ1dHRvbikKICAgIG1hc2sgfD0gMHg0MDsKIAogIFZHQV9HZXRBbHBoYU1vZGUoJldpZHRoLCAmSGVpZ2h0KTsKCiAgUXVldWVNb3VzZVJlbGF5KDY0MCAvIFdpZHRoICogcmVjb3JkLT5kd01vdXNlUG9zaXRpb24uWCwKICAgICAgICAgICAgICAgICAyMDAgLyBIZWlnaHQgKiByZWNvcmQtPmR3TW91c2VQb3NpdGlvbi5ZLAogICAgICAgICAgICAgICAgIG1hc2spOwp9Cg==