From 2cfca35e2fd2818d07b435e7ef551a723ffbf237 Mon Sep 17 00:00:00 2001 From: Rot127 <45763064+Rot127@users.noreply.github.com> Date: Fri, 25 Oct 2024 13:38:33 +0000 Subject: [PATCH] Add CC and VAS compatibility macros (#2525) --- docs/cs_v6_release_guide.md | 7 ++- include/capstone/arm.h | 20 +++++++++ include/capstone/arm64.h | 34 +++++++++++++++ suite/auto-sync/src/autosync/HeaderPatcher.py | 43 +++++++++++++++++++ .../src/test_arm64_compatibility_header.c | 7 +++ 5 files changed, 109 insertions(+), 2 deletions(-) diff --git a/docs/cs_v6_release_guide.md b/docs/cs_v6_release_guide.md index 0ade9c75b..6f470eedc 100644 --- a/docs/cs_v6_release_guide.md +++ b/docs/cs_v6_release_guide.md @@ -304,7 +304,7 @@ Such an instruction is ill-defined in LLVM and should be fixed upstream. | Keyword | Change | Justification | |---------|--------|---------------| -| `ARMCC_*` | `ARMCC_EQ == 0` but `ARMCC_INVALID != 0` | They match the LLVM enum. Better for LLVM compatibility and code generation. | +| `ARMCC_*` | `ARMCC_EQ == 0` but `ARMCC_INVALID != 0` | They match the LLVM enum. Better for LLVM compatibility and code generation. Check the compatibility option below. | | `ARM_CC` | `ARM_CC` → `ARMCC` and value change | They match the same LLVM enum. Better for LLVM compatibility and code generation. | | Post-index | Post-index memory access has the disponent now set in the `MEMORY` operand! No longer as separated `reg`/`imm` operand. | The CS memory operand had a field which was there for disponents. Not having it set, for post-index operands was inconsistent. | | Sign `mem.disp` | `mem.disp` is now always positive and the `subtracted` flag indicates if it should be subtracted. | It was inconsistent before. | @@ -358,7 +358,7 @@ Such an instruction is ill-defined in LLVM and should be fixed upstream. | SYSZ -> SystemZ | `SYSZ` was everywhere renamed to `SystemZ` to match the LLVM naming. | See below | | `SYSTEMZ_CC_*` | `SYSTEMZ_CC_O = 0` and `SYSTEMZ_CC_INVALID != 0` | They match the same LLVM values. Better for LLVM compatibility and code generation. | -### Notes about AArch64 and SystemZ renaming +### Notes about AArch64, SystemZ and ARM renaming `ARM64` was everywhere renamed to `AArch64`. And `SYSZ` to `SYSTEMZ`. This is a necessity to ensure that the update scripts stay reasonably simple. Capstone was very inconsistent with the naming before (sometimes `AArch64` sometimes `ARM64`. Sometimes `SYSZ` sometimes `SYSTEMZ`). @@ -375,9 +375,12 @@ _Compatibility header_ If you want to use the compatibility header and stick with the `ARM64`/`SYSZ` naming, you can define `CAPSTONE_AARCH64_COMPAT_HEADER` and `CAPSTONE_SYSTEMZ_COMPAT_HEADER` before including `capstone.h`. +**Note**: The `CAPSTONE_ARM_COMPAT_HEADER` will only define macros for the `ARM_CC -> ARMCC` and `arm_cc -> ARMCC_CondCodes` renaming. + ```c #define CAPSTONE_SYSTEMZ_COMPAT_HEADER #define CAPSTONE_AARCH64_COMPAT_HEADER +#define CAPSTONE_ARM_COMPAT_HEADER #include // Your code... diff --git a/include/capstone/arm.h b/include/capstone/arm.h index 3e03e4f70..c9d3d6091 100644 --- a/include/capstone/arm.h +++ b/include/capstone/arm.h @@ -1706,6 +1706,26 @@ typedef enum arm_insn_group { ARM_GRP_ENDING, } arm_insn_group; +#ifdef CAPSTONE_ARM_COMPAT_HEADER +#define arm_cc ARMCC_CondCodes +#define ARM_CC_EQ ARMCC_EQ +#define ARM_CC_NE ARMCC_NE +#define ARM_CC_HS ARMCC_HS +#define ARM_CC_LO ARMCC_LO +#define ARM_CC_MI ARMCC_MI +#define ARM_CC_PL ARMCC_PL +#define ARM_CC_VS ARMCC_VS +#define ARM_CC_VC ARMCC_VC +#define ARM_CC_HI ARMCC_HI +#define ARM_CC_LS ARMCC_LS +#define ARM_CC_GE ARMCC_GE +#define ARM_CC_LT ARMCC_LT +#define ARM_CC_GT ARMCC_GT +#define ARM_CC_LE ARMCC_LE +#define ARM_CC_AL ARMCC_AL +#define ARM_CC_INVALID ARMCC_Invalid +#endif + #ifdef __cplusplus } #endif diff --git a/include/capstone/arm64.h b/include/capstone/arm64.h index 6aea91e1e..96045bf5d 100644 --- a/include/capstone/arm64.h +++ b/include/capstone/arm64.h @@ -4576,3 +4576,37 @@ typedef enum { #endif #endif + +#define arm64_cc AArch64CC_CondCode +#define ARM64_CC_EQ AArch64CC_EQ +#define ARM64_CC_NE AArch64CC_NE +#define ARM64_CC_HS AArch64CC_HS +#define ARM64_CC_LO AArch64CC_LO +#define ARM64_CC_MI AArch64CC_MI +#define ARM64_CC_PL AArch64CC_PL +#define ARM64_CC_VS AArch64CC_VS +#define ARM64_CC_VC AArch64CC_VC +#define ARM64_CC_HI AArch64CC_HI +#define ARM64_CC_LS AArch64CC_LS +#define ARM64_CC_GE AArch64CC_GE +#define ARM64_CC_LT AArch64CC_LT +#define ARM64_CC_GT AArch64CC_GT +#define ARM64_CC_LE AArch64CC_LE +#define ARM64_CC_AL AArch64CC_AL +#define ARM64_CC_INVALID AArch64CC_Invalid +#define ARM64_VAS_INVALID AARCH64LAYOUT_VL_INVALID +#define ARM64_VAS_16B AARCH64LAYOUT_VL_16B +#define ARM64_VAS_8B AARCH64LAYOUT_VL_8B +#define ARM64_VAS_4B AARCH64LAYOUT_VL_4B +#define ARM64_VAS_1B AARCH64LAYOUT_VL_1B +#define ARM64_VAS_8H AARCH64LAYOUT_VL_8H +#define ARM64_VAS_4H AARCH64LAYOUT_VL_4H +#define ARM64_VAS_2H AARCH64LAYOUT_VL_2H +#define ARM64_VAS_1H AARCH64LAYOUT_VL_1H +#define ARM64_VAS_4S AARCH64LAYOUT_VL_4S +#define ARM64_VAS_2S AARCH64LAYOUT_VL_2S +#define ARM64_VAS_1S AARCH64LAYOUT_VL_1S +#define ARM64_VAS_2D AARCH64LAYOUT_VL_2D +#define ARM64_VAS_1D AARCH64LAYOUT_VL_1D +#define ARM64_VAS_1Q AARCH64LAYOUT_VL_1Q +#define arm64_vas AArch64Layout_VectorLayout diff --git a/suite/auto-sync/src/autosync/HeaderPatcher.py b/suite/auto-sync/src/autosync/HeaderPatcher.py index 2f7444261..1a84891fe 100755 --- a/suite/auto-sync/src/autosync/HeaderPatcher.py +++ b/suite/auto-sync/src/autosync/HeaderPatcher.py @@ -9,6 +9,43 @@ import re from pathlib import Path +AARCH64_CC_MACROS = [ + "\n", + "#define arm64_cc AArch64CC_CondCode\n", + "#define ARM64_CC_EQ AArch64CC_EQ\n", + "#define ARM64_CC_NE AArch64CC_NE\n", + "#define ARM64_CC_HS AArch64CC_HS\n", + "#define ARM64_CC_LO AArch64CC_LO\n", + "#define ARM64_CC_MI AArch64CC_MI\n", + "#define ARM64_CC_PL AArch64CC_PL\n", + "#define ARM64_CC_VS AArch64CC_VS\n", + "#define ARM64_CC_VC AArch64CC_VC\n", + "#define ARM64_CC_HI AArch64CC_HI\n", + "#define ARM64_CC_LS AArch64CC_LS\n", + "#define ARM64_CC_GE AArch64CC_GE\n", + "#define ARM64_CC_LT AArch64CC_LT\n", + "#define ARM64_CC_GT AArch64CC_GT\n", + "#define ARM64_CC_LE AArch64CC_LE\n", + "#define ARM64_CC_AL AArch64CC_AL\n", + "#define ARM64_CC_INVALID AArch64CC_Invalid\n", + "#define ARM64_VAS_INVALID AARCH64LAYOUT_VL_INVALID\n", + "#define ARM64_VAS_16B AARCH64LAYOUT_VL_16B\n", + "#define ARM64_VAS_8B AARCH64LAYOUT_VL_8B\n", + "#define ARM64_VAS_4B AARCH64LAYOUT_VL_4B\n", + "#define ARM64_VAS_1B AARCH64LAYOUT_VL_1B\n", + "#define ARM64_VAS_8H AARCH64LAYOUT_VL_8H\n", + "#define ARM64_VAS_4H AARCH64LAYOUT_VL_4H\n", + "#define ARM64_VAS_2H AARCH64LAYOUT_VL_2H\n", + "#define ARM64_VAS_1H AARCH64LAYOUT_VL_1H\n", + "#define ARM64_VAS_4S AARCH64LAYOUT_VL_4S\n", + "#define ARM64_VAS_2S AARCH64LAYOUT_VL_2S\n", + "#define ARM64_VAS_1S AARCH64LAYOUT_VL_1S\n", + "#define ARM64_VAS_2D AARCH64LAYOUT_VL_2D\n", + "#define ARM64_VAS_1D AARCH64LAYOUT_VL_1D\n", + "#define ARM64_VAS_1Q AARCH64LAYOUT_VL_1Q\n", + "#define arm64_vas AArch64Layout_VectorLayout\n", +] + def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser( @@ -259,6 +296,10 @@ class CompatHeaderBuilder: output.append(line) return output + def add_cc_macros(self, v6_lines: list[str]) -> list[str]: + v6_lines += AARCH64_CC_MACROS + return v6_lines + def generate_v5_compat_header(self) -> bool: """ Translates the aarch64.h header into the arm64.h header and renames all aarch64 occurrences. @@ -275,6 +316,8 @@ class CompatHeaderBuilder: patched = self.replace_v6_prefix(patched) patched = self.replace_include_guards(patched) patched = self.inject_v6_header(patched) + if self.v6_lower == "aarch64": + patched = self.add_cc_macros(patched) with open(self.v5, "w+") as f: f.writelines(patched) diff --git a/tests/integration/compat_header/src/test_arm64_compatibility_header.c b/tests/integration/compat_header/src/test_arm64_compatibility_header.c index 8dcf86605..95d77719b 100644 --- a/tests/integration/compat_header/src/test_arm64_compatibility_header.c +++ b/tests/integration/compat_header/src/test_arm64_compatibility_header.c @@ -4,6 +4,7 @@ #include #include +#define CAPSTONE_ARM_COMPAT_HEADER #define CAPSTONE_AARCH64_COMPAT_HEADER #include @@ -55,6 +56,12 @@ int arm64(void) fprintf(stderr, "Immediate wrong.\n"); goto err; } + arm64_cc test_cc64 = insn[0].detail->arm64.cc + ARM64_CC_GE; + arm_cc test_cc = insn[0].detail->arm.cc + ARM_CC_LE; + printf("test_cc64 = %" PRId32 " test_cc = %" PRId32 "\n", test_cc64, test_cc); + + arm64_vas test_vas = insn[0].detail->arm64.operands[0].vas + ARM64_VAS_16B; + printf("test_vas = %" PRId32 "\n", test_vas); cs_free(insn, count); cs_close(&handle);