From 382b217a91a871eb9d0c138ab08de2985b8411bb Mon Sep 17 00:00:00 2001 From: Rot127 Date: Fri, 25 Oct 2024 07:25:01 -0500 Subject: [PATCH] Add CC compatibility macros --- docs/cs_v6_release_guide.md | 7 +++-- include/capstone/arm.h | 20 ++++++++++++++ include/capstone/arm64.h | 18 +++++++++++++ suite/auto-sync/src/autosync/HeaderPatcher.py | 26 +++++++++++++++++++ .../src/test_arm64_compatibility_header.c | 4 +++ 5 files changed, 73 insertions(+), 2 deletions(-) diff --git a/docs/cs_v6_release_guide.md b/docs/cs_v6_release_guide.md index 0ade9c75b0..6f470eedc2 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 3e03e4f706..c9d3d60910 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 6aea91e1e2..aae606dec1 100644 --- a/include/capstone/arm64.h +++ b/include/capstone/arm64.h @@ -4576,3 +4576,21 @@ 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 diff --git a/suite/auto-sync/src/autosync/HeaderPatcher.py b/suite/auto-sync/src/autosync/HeaderPatcher.py index 2f7444261f..ce816bd527 100755 --- a/suite/auto-sync/src/autosync/HeaderPatcher.py +++ b/suite/auto-sync/src/autosync/HeaderPatcher.py @@ -9,6 +9,27 @@ 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", +] + def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser( @@ -259,6 +280,10 @@ def inject_v6_header(self, v6_lines: list[str]) -> list[str]: 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 +300,7 @@ def generate_v5_compat_header(self) -> bool: patched = self.replace_v6_prefix(patched) patched = self.replace_include_guards(patched) patched = self.inject_v6_header(patched) + 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 8dcf866050..b8417232f0 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,9 @@ 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); cs_free(insn, count); cs_close(&handle);