In CAPSTONE_DIET builds, getRegisterName() returns NULL because the
register-name string table is compiled out. Every other AArch64 printer
helper feeds that NULL into SStream_concat0(), which is a no-op on NULL
under CAPSTONE_DIET. printMatrixTileVector is the outlier: it calls
strlen(RegName) + 1 directly to size a scratch buffer, so a NULL
result causes SIGSEGV inside strlen().
Early-return after AArch64_add_cs_detail_1() when RegName is NULL, so
detail-mode users still get the operand recorded.
Repro on a diet aarch64 build:
static const unsigned char code[] = { 0xc0, 0xc0, 0xc0, 0xc0 };
cs_disasm(handle, code, sizeof(code), 0, 0, &insn); /* SIGSEGV */
Fixescapstone-engine/capstone#3014
Co-authored-by: Amit Sides <amit-sides@users.noreply.github.com>
* Fix OOB read in SH module.
Reported by @pant0m in GHSA-5q63-4654-94v6.
* Add several bound checking asserts to SH disassembler.
* Fix macro formatting for readability.
* Add asserts in case of opening failure to detect them.
MRS Xt, NZCV reads (and MSR NZCV, Xt writes) the same flags every
flag-setting instruction implicitly defines, but the generated
implicit register lists cannot express it: MRS/MSR are single generic
instructions whose system register is an immediate operand, so LLVM's
static Uses/Defs do not depend on it. The semantic link is already
half-modeled: AArch64_check_updates_flags() sets update_flags for
MSR NZCV, yet neither direction surfaces in the detail register lists
or cs_regs_access().
Add the aliased NZCV register to the implicit lists when MRS reads or
MSR writes it. The 128-bit pair forms MRRS/MSRR are deliberately
excluded: NZCV is not a valid 128-bit system register, so those
encodings are UNDEFINED rather than flag accesses (an exhaustive
2^32-word cross-check against an external NZCV-liveness model caught
exactly this over-match in an earlier revision of the patch).
Add detail tests covering both directions, a TPIDR_EL0 control case,
and exact-match register lists for MRRS/MSRR.
The Xtensa disassembler enabled the ESP32-S3 SIMD/AI (ee.*) and HiFi3 ops for
every target because the subtarget feature gates were stubbed to return true
(Xtensa_getFeatureBits and hasDensity/hasESP32S3Ops/hasHIFI3). As a result, on a
non-ESP32-S3 Xtensa config any instruction with op0=0xE/0xF was matched as a
4-byte ee.* op, so a base-ISA byte stream desynced.
Make Xtensa_getFeatureBits map the mode to a feature set (mirroring the SystemZ
precedent), thread MI->csh->mode into the three has*Ops gates, and add an opt-in
CS_MODE_XTENSA_ESP32S3. Base/esp32/esp32s2/esp8266 no longer emit ESP32-S3 ops;
CS_MODE_XTENSA_ESP32S3 preserves them. Concrete instance of issue #1992.
The saved auto-sync patch hashes are updated so the fix survives the next LLVM
re-sync. Adds tests/MC/Xtensa/esp32s3.s.yaml.
Co-authored-by: Denys Melnyk <denys@com2cloud.com>
Add CS_OPT_SYNTAX_AARCH64_EXPLICIT_WIDE_IMM to print shifted
MOVN and MOVZ instructions in their explicit forms instead of using
the equivalent MOV aliases.
Keep the existing LLVM-compatible alias output as the default, and
retain MOV aliases for unshifted instructions when the option is
enabled.
Expose the option through cstool and the Python bindings, and add
regression tests for MOVN, MOVZ, 32-bit and 64-bit forms.
Fixes#2890
Signed-off-by: Amaan Mujawar <amaansmujawar@gmail.com>
* Don't build cstool arch specific details printing, if not requested.
* Add workflow for cstool builds with a single arch.
* Print only options in cstool help for enabled archs.
* Add ColdFire EMAC_B dual-acc MAC support
* Fix M68K reserved EA decoding in Capstone
---------
Co-authored-by: Rot127 <45763064+Rot127@users.noreply.github.com>
All the enum names were prefixed with `Alpha` instead of `ALPHA`.
That happened because of an old Auto-Sync bug.
Sadly, I just recognized that Alpha was generated with it.
No idea why it got through in the PR in the first place.
I really would like that to have fixed before Beta.
And while it is super annoying for everyone to fix,
it is better to do as early as possible.
A simple command to replace all these occurrences in your code base is:
```
find . -type f -regex ".*\.\(c\|h\)$" -exec sed -i -E "s|Alpha_([A-Z0-9_]+)|ALPHA_\1|g" {} +
```
Please excuse the inconvenience!
* Alpha: fix integer register class decoding order
GPRC[] is LLVM's register allocation order, not the architectural
register number order. Using it to map hardware register fields 0-31
scrambled r9-r29 (e.g. field 9 → \$16, field 23 → \$9).
Alpha_R0 through Alpha_R31 are contiguous in the enum (33-64), so
Alpha_R0 + RegNo gives the correct architectural mapping directly.
Update existing tests that encoded the wrong register names, and add
new MC tests covering the previously scrambled r9-r29 range.
* Alpha: fix BR/BSR to accept any Ra register
The LLVM decoder table constrained BR to Ra=31 and BSR to Ra=26,
rejecting all other encodings as illegal. The Alpha ISA defines Ra
as the return address destination for BSR (any writable register
is valid) and as an unused hint field for BR (any register field
is legal in existing binaries).
Remove both CheckField constraints by zeroing the skip bytes to a
no-op, and change the decode format from 25 (disp-only) to 27
(Ra + disp21) so the Ra operand is visible to callers.
Override BR/BSR in the instruction printer, since the generated
AsmWriter hardcodes "\$31" for BR and ignores Ra entirely for BSR.
Update the placeholder BSR test (which had a malformed expected
string) and add new tests for BR/BSR with non-default Ra values.
Refs: https://github.com/capstone-engine/capstone/issues/2582
* Alpha: fix CALL_PAL to decode full 26-bit function code
The LLVM decoder mapped opcode 0x00 to COND_BRANCH_I (format 0),
which tried to interpret bits[20:0] as a register number. This
failed for any PAL function code > 31 (e.g. 0x83 gentrap, 0x1020b).
Add decode format 31 that extracts bits[25:0] as a single immediate,
switch opcode 0x00 to use it, map COND_BRANCH_I to the new public
Alpha_INS_CALL_PAL, and override the printer to emit "call_pal <imm>".
* Alpha: fix JMP/JSR to accept any Ra, Rb, and hint
The LLVM decoder required JMP to have Ra=31 and hint=0, and JSR to
have specific Ra/Rb pairs (26/27 or 23/27) with hint=0. Real-world
code uses arbitrary combinations: JMP with Ra!=31 to save return
addresses, JSR with Ra=26 and Rb!=27, or non-zero hint fields for
branch prediction.
Remove all Ra, Rb, and hint constraints for JMP and JSR. Switch both
from decode format 17 (Rb only) and 14 (no operands) to format 18
(Ra + Rb + hint14). Add printer override to emit the three-operand
form: "jmp/jsr \$ra,(\$rb),hint".
Closes: https://github.com/capstone-engine/capstone/issues/2582
* Alpha: fix TRAPB/EXCB/MB/WMB to decode with any Ra/Rb field
The LLVM assembler emits these barrier instructions with Ra=Rb=31,
but the decoder required Ra=Rb=0 (bits[25:16]=0), causing all
canonical encodings to fail.
Remove the CheckField constraint so any Ra/Rb combination is accepted.
The instructions carry no register operands in their decode format,
so the field values do not affect the output.
Closes: https://github.com/capstone-engine/capstone/issues/2795
* Alpha: add missing test coverage for s4addq and cvt FP variants
s4addq (register and literal forms), cvttq/svc, cvtts/sui, cvtqs/sui,
and cvtqt/sui had no MC tests despite being reachable instructions.
* Alpha: fix RET/RC/RS to decode with any register fields
RET (opcode 0x1a, bits[15:14]=10) shares identical operation semantics
with JMP/JSR/JSR_COROUTINE — all four differ only in branch-prediction
hints. The decoder incorrectly required Ra=31, Rb=26, hint=1 exactly;
any other encoding failed to decode.
RC and RS (opcode 0x18) have an unused Rb field. The decoder checked
Rb==0 (R0), but convention is to set unused fields to R31 (=31), so
any real-world encoding produced by a compiler would fail to decode.
Remove the restrictive CheckField constraints on RET, RC, and RS.
Update RETDAG's operand table to carry Ra+Rb+hint (format 18), and
add a ret printer in Alpha_LLVM_printInstruction matching the existing
jmp/jsr handling.
Tests added: ret $0,($1),3 (non-canonical RET); rc/rs $1 with Rb=R31.
Detection of writebacks was only partially implemented:
- MCInst_handleWriteback() was not called, so tied_op_idx was not filled
- map_get_op_access() in RISCV_add_cs_detail_0() queried tied_op_idx
unnecessarily, because all elements were -1 (initialization value)