mirror of
https://github.com/capstone-engine/capstone
synced 2026-08-11 16:26:07 -04:00
RISC-V: Add v5 compatibility behaviour for CS_MODE_RISCVC/RISCV_C (#2996)
Co-authored-by: Rot127 <45763064+Rot127@users.noreply.github.com>
This commit is contained in:
parent
54fcf14f05
commit
032f79993d
10 changed files with 95 additions and 7 deletions
5
.github/workflows/CITest.yml
vendored
5
.github/workflows/CITest.yml
vendored
|
|
@ -202,10 +202,13 @@ jobs:
|
|||
clang-format-20 --version
|
||||
cp ./include/capstone/arm64.h arm64_compat_current.h
|
||||
cp ./include/capstone/systemz_compatibility.h systemz_compat_current.h
|
||||
cp ./include/capstone/riscv.h riscv_current.h
|
||||
./suite/auto-sync/src/autosync/HeaderPatcher.py -C ./.clang-format -c --v6 ./include/capstone/aarch64.h --v5 ./include/capstone/arm64.h
|
||||
./suite/auto-sync/src/autosync/HeaderPatcher.py -C ./.clang-format -c --v6 ./include/capstone/systemz.h --v5 ./include/capstone/systemz_compatibility.h
|
||||
./suite/auto-sync/src/autosync/HeaderPatcher.py --riscv-compat --header ./include/capstone/riscv.h
|
||||
diff ./include/capstone/arm64.h arm64_compat_current.h &&
|
||||
diff ./include/capstone/systemz_compatibility.h systemz_compat_current.h
|
||||
diff ./include/capstone/systemz_compatibility.h systemz_compat_current.h &&
|
||||
diff ./include/capstone/riscv.h riscv_current.h
|
||||
|
||||
Windows:
|
||||
runs-on: ${{ matrix.config.os }}
|
||||
|
|
|
|||
|
|
@ -123,6 +123,7 @@ __all__ = [
|
|||
"CS_MODE_RISCV32",
|
||||
"CS_MODE_RISCV64",
|
||||
"CS_MODE_RISCV_C",
|
||||
"CS_MODE_RISCVC",
|
||||
"CS_MODE_RISCV_FD",
|
||||
"CS_MODE_RISCV_F",
|
||||
"CS_MODE_RISCV_D",
|
||||
|
|
@ -471,6 +472,7 @@ CS_MODE_BPF_EXTENDED = 1 << 0 # Extended BPF mode
|
|||
CS_MODE_RISCV32 = 1 << 0 # RISCV32 mode
|
||||
CS_MODE_RISCV64 = 1 << 1 # RISCV64 mode
|
||||
CS_MODE_RISCV_C = 1 << 2 # RISCV compressed instructure mode
|
||||
CS_MODE_RISCVC = CS_MODE_RISCV_C
|
||||
CS_MODE_RISCV_FD = 1 << 3
|
||||
CS_MODE_RISCV_F = CS_MODE_RISCV_FD
|
||||
CS_MODE_RISCV_D = CS_MODE_RISCV_FD
|
||||
|
|
|
|||
|
|
@ -55,6 +55,12 @@ def test_compatibility():
|
|||
print("systemz.SYSTEMZ_INS_LG = %d" % capstone.systemz.SYSTEMZ_INS_LG)
|
||||
assert capstone.systemz.SYSZ_INS_LG == capstone.systemz.SYSTEMZ_INS_LG
|
||||
|
||||
# Test RISC-V compressed-mode compatibility constant
|
||||
print("CS_MODE_RISCVC = %d" % CS_MODE_RISCVC)
|
||||
print("CS_MODE_RISCV_C = %d" % CS_MODE_RISCV_C)
|
||||
assert CS_MODE_RISCVC == CS_MODE_RISCV_C
|
||||
assert "CS_MODE_RISCVC" in capstone.__all__
|
||||
|
||||
# Test ARM_CC_ constants
|
||||
print("arm.ARM_CC_MI = %d" % capstone.arm.ARM_CC_MI)
|
||||
print("arm.ARMCC_MI = %d" % capstone.arm.ARMCC_MI)
|
||||
|
|
|
|||
|
|
@ -489,7 +489,7 @@ Such an instruction is ill-defined in LLVM and should be fixed upstream.
|
|||
| `M68K_OP_MEM` storage | Memory operands now store base registers in `m68k_op_mem.base_reg` and absolute addresses in `m68k_op_mem.address`; `op->reg` and `op->imm` are only used for register and immediate operands. | Keeps memory-addressing details in `m68k_op_mem` consistently. |
|
||||
|
||||
|
||||
### Notes about AArch64, SystemZ and ARM renaming
|
||||
### Notes about AArch64, SystemZ, ARM and RISC-V 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`).
|
||||
|
|
@ -499,19 +499,21 @@ Because this would completely break maintaining Capstone `v6` and `pre-v6` in a
|
|||
|
||||
1. `arm64.h` is a compatibility header now, which merely maps every member to the one in the `aarch64.h` header. Defining `CAPSTONE_AARCH64_COMPAT_HEADER` before including `capstone.h` will include the headers in the right order.
|
||||
2. The `systemz.h` header includes the `systemz_compatibility.h` header if `CAPSTONE_SYSTEMZ_COMPAT_HEADER` is defined.
|
||||
3. Defining `CAPSTONE_RISCV_COMPAT_HEADER` before including `capstone.h` exposes the legacy RISC-V compressed-mode constant `CS_MODE_RISCVC` as an alias of `CS_MODE_RISCV_C`.
|
||||
|
||||
We will continue to maintain both headers.
|
||||
We will continue to maintain both compatibility headers, `arm64.h` and `systemz_compatibility.h`.
|
||||
|
||||
_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`.
|
||||
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`. For the legacy RISC-V compressed-mode spelling (`CS_MODE_RISCVC`), define `CAPSTONE_RISCV_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.
|
||||
**Note**: The `CAPSTONE_ARM_COMPAT_HEADER` will only define macros for the `ARM_CC -> ARMCC` and `arm_cc -> ARMCC_CondCodes` renaming. The `CAPSTONE_RISCV_COMPAT_HEADER` only defines `CS_MODE_RISCVC` for the `CS_MODE_RISCVC -> CS_MODE_RISCV_C` renaming.
|
||||
|
||||
```c
|
||||
#define CAPSTONE_SYSTEMZ_COMPAT_HEADER
|
||||
#define CAPSTONE_AARCH64_COMPAT_HEADER
|
||||
#define CAPSTONE_ARM_COMPAT_HEADER
|
||||
#define CAPSTONE_RISCV_COMPAT_HEADER
|
||||
#include <capstone/capstone.h>
|
||||
|
||||
// Your code...
|
||||
|
|
|
|||
|
|
@ -2878,6 +2878,14 @@ typedef enum riscv_insn_group {
|
|||
RISCV_GRP_ENDING,
|
||||
} riscv_insn_group;
|
||||
|
||||
// generated content <RISCVCompat> begin
|
||||
// clang-format off
|
||||
#ifdef CAPSTONE_RISCV_COMPAT_HEADER
|
||||
#define CS_MODE_RISCVC CS_MODE_RISCV_C
|
||||
#endif
|
||||
// clang-format on
|
||||
// generated content <RISCVCompat> end
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -128,6 +128,8 @@ class ASUpdater:
|
|||
arch="systemz",
|
||||
)
|
||||
builder.generate_v5_compat_header()
|
||||
elif self.arch == "RISCV":
|
||||
HeaderPatcher.patch_riscv_compat_macros(main_header)
|
||||
return patched
|
||||
|
||||
def copy_files(self, path: Path, dest: Path) -> None:
|
||||
|
|
|
|||
|
|
@ -10,6 +10,12 @@ import subprocess as sp
|
|||
|
||||
from pathlib import Path
|
||||
|
||||
RISCV_COMPAT_MACROS = [
|
||||
"#ifdef CAPSTONE_RISCV_COMPAT_HEADER\n",
|
||||
"#define CS_MODE_RISCVC CS_MODE_RISCV_C\n",
|
||||
"#endif\n",
|
||||
]
|
||||
|
||||
AARCH64_CC_MACROS = [
|
||||
"\n",
|
||||
"#define arm64_cc AArch64CC_CondCode\n",
|
||||
|
|
@ -68,6 +74,12 @@ def parse_args() -> argparse.Namespace:
|
|||
parser.add_argument(
|
||||
"-p", dest="patch", help="Patch inc file into header", action="store_true"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--riscv-compat",
|
||||
dest="riscv_compat",
|
||||
help="Patch the RISC-V compatibility macros into the RISC-V header",
|
||||
action="store_true",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-C",
|
||||
dest="clang_format",
|
||||
|
|
@ -160,6 +172,35 @@ class HeaderPatcher:
|
|||
log.info(f"Patched {self.inc.name} into {self.header.name}")
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def patch_riscv_compat_macros(header: Path) -> bool:
|
||||
if not (header.exists() or header.is_file()):
|
||||
error_exit(f"header file {header.name} does not exist.")
|
||||
|
||||
with open(header) as f:
|
||||
header_content = f.read()
|
||||
|
||||
regex = (
|
||||
r"\n// generated content <RISCVCompat> begin.*(\n)"
|
||||
r"(.*\n)*"
|
||||
r"// generated content <RISCVCompat> end.*(\n)"
|
||||
)
|
||||
new_content = (
|
||||
"\n// generated content <RISCVCompat> begin\n"
|
||||
+ "// clang-format off\n"
|
||||
+ "".join(RISCV_COMPAT_MACROS)
|
||||
+ "// clang-format on\n"
|
||||
+ "// generated content <RISCVCompat> end\n"
|
||||
)
|
||||
if not re.search(regex, header_content):
|
||||
error_exit(f"Could not find RISCVCompat marker in {header.name}.")
|
||||
header_content = re.sub(regex, new_content, header_content)
|
||||
|
||||
with open(header, "w") as f:
|
||||
f.write(header_content)
|
||||
log.info(f"Patched RISC-V compatibility macros into {header.name}")
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def file_in_main_header(header: Path, filename: str) -> bool:
|
||||
with open(header) as f:
|
||||
|
|
@ -347,8 +388,8 @@ class CompatHeaderBuilder:
|
|||
|
||||
if __name__ == "__main__":
|
||||
args = parse_args()
|
||||
if (not args.patch and not args.compat) or (args.patch and args.compat):
|
||||
print("You need to specify either -c or -p")
|
||||
if [args.patch, args.compat, args.riscv_compat].count(True) != 1:
|
||||
print("You need to specify exactly one of -c, -p, or --riscv-compat")
|
||||
exit(1)
|
||||
if args.compat and not (args.v6 and args.v5):
|
||||
print("Generating the v5 compatibility header requires --v5 and --v6")
|
||||
|
|
@ -356,6 +397,13 @@ if __name__ == "__main__":
|
|||
if args.patch and not (args.inc and args.header):
|
||||
print("Patching headers requires --inc and --header")
|
||||
exit(1)
|
||||
if args.riscv_compat and not args.header:
|
||||
print("Patching RISC-V compatibility macros requires --header")
|
||||
exit(1)
|
||||
|
||||
if args.riscv_compat:
|
||||
HeaderPatcher.patch_riscv_compat_macros(args.header)
|
||||
exit(0)
|
||||
|
||||
if args.patch:
|
||||
patcher = HeaderPatcher(args.header, args.inc)
|
||||
|
|
|
|||
|
|
@ -3,3 +3,4 @@
|
|||
|
||||
int arm64(void);
|
||||
int sysz(void);
|
||||
int riscv(void);
|
||||
|
|
|
|||
|
|
@ -14,4 +14,8 @@ int main()
|
|||
printf("Failed the sysz compatibility header test.\n");
|
||||
return -1;
|
||||
}
|
||||
if (riscv() != 0) {
|
||||
printf("Failed the riscv compatibility header test.\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
// SPDX-FileCopyrightText: 2026 moste00 <ubermenchun@gmail.com>
|
||||
// SPDX-License-Identifier: BSD-3.0-Clause
|
||||
|
||||
#define CAPSTONE_RISCV_COMPAT_HEADER
|
||||
#include <capstone/capstone.h>
|
||||
|
||||
int riscv(void)
|
||||
{
|
||||
return CS_MODE_RISCVC == CS_MODE_RISCV_C ? 0 : -1;
|
||||
}
|
||||
|
||||
#undef CAPSTONE_RISCV_COMPAT_HEADER
|
||||
Loading…
Add table
Add a link
Reference in a new issue