100 Commits
Author SHA1 Message Date
Anton Kochkov f52a6681ce librz/arch/tms320: decode the TMS320C28x FPU, TMU and FINTDIV instructions 2026-10-11 01:50:45 +08:00
Anton Kochkov fa093d4201 librz/arch/tms320: give the C28x and VCU instructions real analysis types 2026-10-11 01:50:45 +08:00
Anton Kochkov 9e95f9957a librz/arch/tms320: decode the TMS320C28x VCU instructions 2026-10-11 01:50:45 +08:00
Anton Kochkov b81023155b librz/arch/tms320: RzIL uplifting for the TMS320C28x core 2026-10-11 01:50:45 +08:00
Anton Kochkov eab103feb7 librz/arch/tms320: native TMS320C28x support 2026-10-11 01:50:45 +08:00
Anton Kochkov 2d03595fc2 librz/arch/tms320: read and write C6000 words through rz_read/write_ble 2026-10-11 01:50:45 +08:00
Anton Kochkov b7ea008625 librz/arch/tms320: correct and expand the C6000 notes in the README 2026-10-11 01:50:45 +08:00
Anton Kochkov 00720d0fd2 analysis: mask only the analysed instruction in rz_core_analysis_bytes() 2026-09-28 23:58:34 +08:00
Anton Kochkov b52fdf807a test/bench: benchmark rz_core_analysis_bytes() 2026-09-28 23:58:34 +08:00
Anton Kochkov e00813631c librz/arch/dwarf: use per-cpu DWARF register numbering for tms320 2026-09-18 01:32:00 +08:00
Anton Kochkov b5b3a8fdb3 librz/arch/tms320: bound the C6000 packet slot count 2026-09-18 01:32:00 +08:00
Anton Kochkov 92ee3147ea librz/arch/tms320: half-word scale C6000 BNOP in a compact packet 2026-09-17 23:08:15 +08:00
Anton Kochkov b1c5f7163b librz/arch/tms320: recognise a C6000 fetch-packet header by position 2026-09-17 23:08:15 +08:00
Anton Kochkov 7b99656a56 librz/arch/tms320: report the C6000 fetch packet through archinfo 2026-09-17 23:08:15 +08:00
Anton Kochkov 5082af3230 arch/tms320: model C6000 execute packets and branch delay slots 2026-09-08 10:50:05 +08:00
Anton Kochkov 627597652c arch/tms320: define the C6000 (c6x) EABI calling convention 2026-09-08 10:50:05 +08:00
Anton Kochkov 743d25b12a arch/tms320: list C6000 (c6x) instruction mnemonics 2026-09-08 10:50:05 +08:00
Anton Kochkov e2673beaf0 arch/tms320: retire the C64x Capstone fallback 2026-09-08 10:50:05 +08:00
Anton Kochkov f7b01c8eea arch/tms320: RzIL uplifting for the TMS320C6000 (c6x) scalar core 2026-09-08 10:50:05 +08:00
Anton Kochkov fb4f5072d1 arch/tms320: native TMS320C6000 (c6x) disassembler and analysis 2026-09-08 10:50:05 +08:00
Anton Kochkov 1b7476c11d bin/elf: convert and patch TMS320C6000 (c6x) ELF relocations
The values follow SPRAB89 Table 13-5 -- S+A for the absolute forms, S+A-P
for the PC-relative branches, S+A-B against the static base for the
base-relative ones -- and Table 13-6 gives, per type, the container to edit
and the field's offset and width inside it. That is the whole encoding, so
the field layouts are a table here too rather than a case each.

PC-relative branches measure from the fetch packet the branch sits in, not
from the instruction, so the place is rounded down to a 32-byte boundary
before the difference is taken.
2026-09-08 01:55:32 +08:00
Anton Kochkov 0fc2365b57 bin/coff: apply TMS320C6000 (c6x) relocations 2026-09-08 01:55:32 +08:00
Anton Kochkov 58e1b45063 il: add bit-reversal, per-byte popcount and bit interleaving routines 2026-09-07 00:21:17 +08:00
Anton Kochkov 414fa1af4f librz/util: fix pointer passing to Windows API 2026-09-06 23:33:31 +08:00
Anton Kochkov 31ee6b6d78 ci: update AppVeyor from VS2022 to VS2026 2026-09-06 23:33:31 +08:00
Anton Kochkov 79ba30fc2d Document how to build the API documentation 2026-09-06 10:23:06 +08:00
Anton Kochkov 2354c84211 Add a CI job building the API documentation 2026-09-06 10:23:06 +08:00
Anton Kochkov add6e50f29 Add a doc target building the documentation with a modern theme 2026-09-06 10:23:06 +08:00
Anton Kochkov 98df84934a Fix the broken Doxygen documentation blocks 2026-09-06 10:23:06 +08:00
Anton Kochkov ca2f24aebb Rewrite the Doxygen configuration to only carry non-defaults 2026-09-06 10:23:06 +08:00
Anton Kochkov 38c3bed6c9 librz/arch/tms320/c5x: classify BSAR as a right shift in analysis
BSAR (Barrel Shift ACC Right) was grouped with the left-shift ops and
reported RZ_ANALYSIS_OP_TYPE_SHL. It shifts the accumulator right (1..16
bits, sign-extended under SXM), so it belongs with the SHR group next to
RORB/SFRB. The decode (shift code + 1) was already correct and continues
to match the reference disassembler bit-for-bit.
2026-08-17 01:53:33 +08:00
Anton Kochkov ad462e7ede librz/arch/tms320: add TMS320C5x RzIL lifter
Lift the TMS320C5x instruction set to RzIL. Shared-semantics
instructions reuse the C2x lifter (the C5x-only forms that are a renamed
C2x op, such as the delayed branches, map onto their non-delayed
equivalents); the C5x-only core instructions (the ACCB accumulator-buffer
loads and logical ops, the swap, the zero-accumulator forms, the control
bits and the store-long-immediate) are lifted directly. Instructions with
effects the per-instruction RzIL cannot model cleanly (conditional
control transfers, block moves, parallel-logic, memory-mapped register
access, the MAC fetch forms) are decoded and analysed but left without
IL. Wired into the analysis plugin's il_config under cpu "c5x", with the
C5x register bindings (ACCB and the C5x-specific registers). The asm
tests assert the lifted RzIL, with execution tests covering the IL VM.
2026-08-17 01:53:33 +08:00
Anton Kochkov 79bec39195 librz/arch/tms320: add TMS320C2x RzIL lifter
Lift the TMS320C2x instruction set to RzIL: the 32-bit accumulator and
product paths, the auxiliary-register file with all indirect addressing
modes, the status bits (carry, overflow, OVM saturation, SXM sign
extension, product-mode shifts, TC), and the load/store, multiply,
accumulate, shift, logical and control-flow instructions. Wired into the
analysis plugin's il_config under cpu "c2x". The asm tests now assert the
lifted RzIL for every instruction, with execution tests covering the IL
VM end to end.
2026-08-17 01:53:33 +08:00
Anton Kochkov 148b54a9fc librz/arch/tms320: add TMS320C5x disassembler and analysis
Add the real TMS320C5x (C50/C51/C53) object encoding. The C5x is
source-compatible with the C2x but encodes instructions differently, so
it cannot reuse the C2x decode table: a dedicated C5x decode front-end
fills the shared C55 instruction representation, carrying the C2x ids for
shared-semantics instructions (so the common consumers apply unchanged)
and new C5x-only ids for the C5x additions (ACCB ops, parallel-logic,
memory-mapped register access, conditional execute/call/return, block
moves, ...). Wired into the tms320 asm and analysis plugins under cpu
"c5x", with the C5x mnemonic and op-type tables and register profile.
Includes disassembly and opcode classification tests.
2026-08-17 01:53:33 +08:00
Anton Kochkov 7b36a031ca librz/arch/tms320: add TMS320C2x disassembler and analysis
Add support for the legacy TMS320C2x (C25-class) fixed-point DSP family
to the shared C55 decode-IR engine: the C2x opcode table, operand
extractors, mnemonic and op-type tables, and the register profile, wired
into the tms320 asm and analysis plugins under cpu "c2x". The decoder
fills the shared C55 instruction representation so the common formatter
and analysis filler apply unchanged. Includes disassembly and opcode
classification tests, plus a COFF-loading test exercising the new bin
autodetect.
2026-08-17 01:53:33 +08:00
Anton Kochkov 68471f8736 librz/bin: autodetect legacy TMS320C1x/C2x/C5x COFF objects
The legacy TMS320 fixed-point families ship as 16-bit big-endian COFF
objects whose magic and machine identifiers were not recognised by the
COFF loader. Teach the COFF format backend and the bin plugin to detect
and load them so the new tms320 c2x/c5x analysis can operate on real
object files.
2026-08-17 01:53:33 +08:00
Anton Kochkov fee84c7f5c librz/bin/coff: scale addresses on word-addressed TI targets
The C54x and C28x address 16-bit words, so their loadable section sizes
and every address in the file count words. Rizin's address space is
byte-based, so reading those unscaled mapped only half of each loadable
section and placed every symbol at half its true offset: _main in the
c54x emulateme object landed mid-instruction instead of on its prologue.

Scale section VAs, loadable section sizes and symbol addresses by the
target's address unit. Debug sections are byte streams even on these
targets and keep a scale of one, matching the loadable mask already used
for mapping. The C55x addresses program memory by byte and is left
alone; the ids were checked against the objects in rizin-testbins by
comparing each section's declared size against its extent in the file.

Branch and call targets on the C54x count program words too, and reached
analysis and RzIL unscaled. That went unnoticed while the sections were
half-mapped: the emulateme RzIL test ran from a mid-instruction address
whose decode happened to lift, so it pinned values produced by garbage.
Scale those as well and drive the test the way its C55x sibling does,
decrypting seckrit with the real key.

With the sections fully mapped, analysis now finds every routine the
c54x fixtures declare, so the function counts change.
2026-08-17 01:53:33 +08:00
Anton Kochkov f5bb3a9a41 rz-util: skip the expression parser for bare integer literals 2026-07-26 00:00:50 +08:00
Anton Kochkov 78b903c5f7 rz-debug: stop reporting an error per instruction for unprofiled registers
rz_debug_trace_ins_after() runs for every instruction while a debug session
records, and logged an error whenever the disassembler named a register
that is not in the debug register profile. x86-64 has no zmm or k entries,
so on a CPU where glibc selects the EVEX string routines every vector
instruction produced a line on stderr. In a `dc` under `dts+`, which single
-steps, that is one line per executed instruction; rz-test buffers all of
it, and the write cost alone can push a test over its timeout.

Demote it to a debug message and name the instruction address, so the same
information is available when it is wanted without being paid for on every
step.
2026-07-26 00:00:50 +08:00
Anton Kochkov fdd99cf452 rz-debug: record memory writes wider than 32 bytes
rz_debug_trace_ins_before() dropped any memory write larger than 32 bytes
because rz_debug_trace_ins_after() read it into a fixed 32-byte stack
buffer. The write was then missing from the session, so stepping or
continuing back over it restored stale memory without saying so.

On x86-64 this fires on ordinary code: the glibc PLT and IFUNC resolvers
save vector state with XSAVE, which is a 576 byte write for the legacy
region plus header and more once AVX-512 state is enabled. Size the buffer
to the access instead, cap it at 4096 bytes, and warn with the address when
something exceeds that so the gap in the recording is visible.
2026-07-26 00:00:50 +08:00
Anton Kochkov a41fc7f197 Install missing rz_num_expressions.h header 2026-07-24 10:36:25 +02:00
Anton Kochkov 0d362aab25 test: do not pin a libm pow() result to full precision
% 2**4.5 asserted both the %.17g rendering and the exact bit pattern of
pow(2.0, 4.5). The exact value is 22.62741699796952078...; glibc and the
UCRT return the correctly rounded 0x4036a09e667f3bcd, while FreeBSD and
NetBSD return 0x4036a09e667f3bcc, one ULP low. msun's pow is documented as
under one ULP, not correctly rounded, so the test asserted bit-exact libm
behaviour for a transcendental and could not pass everywhere.

Filter the output down to the rounded line, which every implementation
within one ULP agrees on. The full float/scifmt/hex table stays covered by
the tests whose results are exactly representable.
2026-07-24 10:36:25 +02:00
Anton Kochkov 842cde6138 rz-debug: terminate the map start token on NetBSD, OpenBSD and DragonFly
rz_debug_native_map_get() splits a "<start>-<end>" region by copying the
tail into region2, but never terminated region at the '-'. That was
harmless while rz_num_get() stopped at the first character it could not
read; it no longer does, so the start token is now evaluated as a whole
expression:

    0x7fc8124c4000-7fc81278d000  ->  syntax error, 0
    0x400000-0405000             ->  0x3df600, the end read as C octal

Every map then gets a wrong start address. linux_map_get() was fixed when
the parser changed; these three copies were missed. kfbsd.c reads the two
bounds as separate sscanf fields and is unaffected, as is the FreeBSD
map_get, which does not parse text at all.
2026-07-24 10:36:25 +02:00
Anton Kochkov 689bafb7a4 Rewrite the RzNum parser and calculator on tree-sitter (#4326)
Replace the hand-written parser in calc.c with a tree-sitter grammar
(subprojects/rizin-math-parser) and a typed evaluator. The old parser
could only ever produce a ut64 and folded anything it failed to read to
0, which left callers unable to tell a failed expression from one that
evaluated to zero.

Expressions now evaluate to an RzNumValue, a tagged union over ut64,
double, RzBitVector, arbitrary-precision integer and arbitrary-precision
decimal, carrying an RzNumError rather than signalling failure as 0.
Literals keep the width they were written with (5u8, 0xffu128, any width
from 1 to 65536), results that outgrow 64 bits promote to a big number on
their own, and a parse error, division by zero or unresolved identifier
reaches the caller.

rz_num_math() is deprecated. rz_num_math_ut64() keeps its exact behaviour
for callers that want a ut64, and rz_num_math_value() exposes the typed
result. rz_core_math() adds the RzCore-backed form used by the % command,
with rz_core_math_ut64() deprecated alongside it. rz-ax routes through the
typed API, so it prints values at full precision, reports errors on stderr
and exits non-zero. rz_il_lift_num() converts an expression to an
RzILOpPure, so a numeric argument can be lifted instead of pre-evaluated.

Legacy input still works: trailing base suffixes (101b, 35o, 212t), the
trailing-'h' hex form and the k/m/g scale suffixes are all accepted and
warn once, pointing at the 0b/0o/0t prefixes. doc/math.md documents the
language and doc/math-il-lift.md the lift; the grammar, the evaluator,
rz-ax and the % command are covered by unit and db tests.
2026-07-24 02:57:27 +08:00
Anton Kochkov cc06c1dedb Use Muon for the TinyCC build job (#3345) 2026-07-22 01:23:21 +08:00
Anton Kochkov d8413d7fca Bump version to v1.0.0 2026-06-21 15:54:28 +04:00
Anton Kochkov 83749dfbed subprojects: update zlib to 1.3.2 2026-06-21 05:16:57 +08:00
Anton Kochkov c5344d3c8a subprojects: update xz to 5.8.3 2026-06-21 05:16:57 +08:00
Anton Kochkov b9e20477fb subprojects/rizin-grammar-c: update to tree-sitter-0.26.9 2026-06-21 01:09:02 +08:00
Anton Kochkov 06840d1e6e Regenerate shell parser 2026-06-21 01:09:02 +08:00
Anton Kochkov 401efa2af4 subprojects: update tree-sitter to v0.26.9 2026-06-21 01:09:02 +08:00
Anton Kochkov 9ff9a48c4a arch/tms320: extend C55x/C55x+ RzIL coverage (returns, addressing, sub-register and bit ops)
Builds on the shared decode-IR engine to lift a broad set of common C55x and
C55x+ (Ryujin) instruction forms that were previously left without RzIL,
deriving the exact semantics from the TI C55x+ references (SWPU104 / SWPU086).

Control flow and addressing:
  - ret / reti / retcc: return address read from the top of stack, SP popped by
    two words, control transferred to it (retcc guarded by its predicate).
  - 24-bit XAR correctness on C55x+ (XAR0-15, XSP, XSSP, XDP, XCDP) in the
    register table, the IL-VM profile and the pointer-arithmetic width, enabling
    the 24-bit amov address immediate; classic C55x keeps its 23-bit file.
  - long constant-index and 16-bit-absolute addressing modes, memory-to-memory
    copy, shifted memory loads (uns()/signed, immediate shift), and the
    memory-mapped-register moves mov reg,mmap(@reg) / mov mmap(@reg),reg.
  - push/pop of accumulator sub-register halves and dbl(xarN) pointer pairs.

Arithmetic, logical, shift and bit operations:
  - sub-register add/sub on a 16-bit accumulator slice, for the immediate and
    register forms: a .L destination updates [15:0], a .H destination updates
    [39:16] sign-extended through the guard (SWPU104 1.5.1).
  - bitwise and/or/xor with a 16-bit source (half or AR/T) into a full
    accumulator, zero-extending the operands to 40 bits (SWPU104 6.6.1); the
    memory-source bitwise forms into full and half destinations; and the
    shift-ALU forms <op> ACx.<sub> << #S6, ACy.<sub> on the 16-bit slice.
  - memory-source add (including a 16-bit half addend and the reverse-subtract
    sub ACx.<sub>, Smem, ACy.<sub>), the 32-bit dbl(Lmem) add/sub forms
    (ACy = ACx +/- dbl(Lmem) and the reversed ACy = dbl(Lmem) - ACx), and the
    memory-destination immediate RMW add/sub #k, Smem.
  - register bit ops bclr / bset / bnot @#k, ACx[.h/.l] / ARx: clear, set or
    toggle bit k of the register, the bit number taken relative to the
    addressed sub-register (a .h operand targets bit k+16, the guard k+32).
  - bitwise not ACx.<sub>/ARx into an accumulator half or a 16-bit register
    (not ACx.l, ARy), the half-register and short (0x7b #1/#-1) sftl/sfts
    including register-count shifts, and btst @#k, ACx.l/.h, TCy.

This also corrects an op_type-fallback mis-lift: on C55x+ several non-move
instructions (round, sat/satr, the mant/nexp helper) and the bit-field
extract/expand bfxtr/bfxpa were typed as a move and so were lifted as a plain
register copy. round and sat/satr now carry their lops and reach the existing
rounding / saturation handlers (matching C55x); mant/nexp, bfxtr/bfxpa, the
operand-less sat and the register-indexed memory bit ops (bclr/bset/bnot Baddr)
are marked decode-only (no modelled data effect) so the fallback can no longer
guess at them.

Also fixes a FIRSADD/FIRSSUB lifting bug: the Cmem operand was not converted
from AR to XAR before emitting its pointer post-modify, so a post-modified Cmem
(e.g. firssub *ar3-, *ar5-, *ar6-, ...) produced an invalid 16-bit-vs-24-bit
subtract that failed IL validation; Cmem is now widened like Xmem/Ymem.

The multiply/MAC family stays unlifted by design, as do the flag-predicate
retcc forms (whose condition register field is not represented by the decoder)
and the software-interrupt intr (which would need the interrupt-vector base);
the correct-or-NULL contract test asserts a representative deferred form.

The disassembler tests for both variants are extended with the expected IL for
every form that lifts -- previously the optional IL field was omitted on many
lines whose lift already existed, leaving the lifting unchecked -- so the asm
suite now validates RzIL for all lifted C55x / C55x+ instructions, not just a
subset.

Measured on a 5 MB C55x+ firmware image (16k-instruction sample) RzIL coverage
rises from 82% to 99.4% of decoded instructions, the remaining tail being the
multiply/MAC family and the deferred forms above.
2026-06-15 23:31:05 +08:00
Anton Kochkov 4b2ea610df arch/tms320: rewrite C55x and C55x+ on a shared decode-IR engine
Replace the per-variant, table/token-driven disassembly and lifting for the
TMS320C55x and C55x+ DSPs with a single shared decode-IR layer, c55_ir, that
both variants drive through a C55ArchDesc descriptor. The shared engine
table-walks an instruction (c55_decode), formats it (c55_format), fills the
analysis op (c55_fill_analysis), and lifts to RzIL (c55_lift) arch-agnostically,
with the opcode tables, register files, operand extractors, and op-type/lift
mappings supplied per variant (c55x and c55x_plus).

Both test corpora decode and lift entirely through the shared engine: forcing
the shared-only decode path and, separately, the shared-only lift path each pass
the full suite -- 1288 tests including the three RzIL VM emulation tests, whose
decrypt loops execute every instruction through the shared IL. The legacy
decoder and lifter are retained only as a fallback for a complex long-tail (the
parallel dual-MAC group, dual-memory addsub/subadd, the absolute-k24 and dbl
multi-operand loads/stores, and the bit-field forms); the shared path is used
when it can decode an instruction and control falls through otherwise, so
behaviour is preserved at every step.

Several forms are extended beyond the old engine: the full C55x+ register file
(ac0-31, ar/xar0-15, CPU-gated in the profile and IL VM) so extended-register
forms lift where the legacy lifter bound only the low eight; pc-relative and
compare-and-branch control transfer; the bcc flag predicate; and the
single-data-memory bitwise and address-arithmetic forms (and/or #k16,Smem and
register-mode amar Smem,xar) decoded cleanly with RzIL rather than inherited from
the legacy tables.
2026-06-15 23:31:05 +08:00
Anton Kochkov ab201a3843 arch/tms320: TMS320C55x+ analysis & RzIL (PR #6434) + extended lifter coverage
Squash of rizinorg/rizin PR #6434 ("improve TMS320C55x+ analysis and RzIL")
rebased onto dev, with the PR head's doubled c55plus_il.c (every symbol defined
twice, failing to compile) de-duplicated to a single clean copy.

Substantially extends the C55x/C55x+ RzIL lifter over the existing structured-
operand helpers: mov/copy (immediate, register, memory load/store, half-register
read-modify-write), the full addressing-mode set with post-modify side effects,
control and system-register moves, 40-bit accumulator ALU with shifted sources,
16-bit and dual-memory add/sub, the ST0_55 status-flag model (cmp/cmpand/rol/ror,
named-bit bset/bclr), a documented psh/pop stack model, address-unit amov/aadd/
asub and amar, and bcc/callcc control transfer. The multiply/MAC family and satr
are lifted with explicit, documented integer-mode approximations (not verified
DSP semantics); irreducibly multi-output primitives (bit counts, Viterbi, FIR,
distance) are left correct-or-NULL. The register file covers ac0-7 and xar, found
by validating on real Motorola Wrigley C55x+ firmware whose prologues save 40-bit
accumulators as dbl(acN)+acN.g pairs.

Adds RzIL-VM emulation tests (including the C55x and C55x+ _decrypt emulateme
binaries), per-instruction IL assertions, and ~95% instruction-class disassembly
coverage per corpus; pins little-endian in the VM tests for big-endian hosts; and
regenerates the analysis expectations against current dev.
2026-06-15 23:31:05 +08:00
Anton Kochkov f89e09f6bc bin/coff: honor load addresses for TI linked (F_EXEC) executables
For a fully linked TI COFF executable the section s_vaddr fields hold the real
load addresses (e.g. .text at 0x100, vectors high) rather than a packed
sequential layout. Map sections at s_vaddr for F_EXEC objects (keeping the
sequential 16-aligned fallback only for relocatable objects), treat a defined
symbol's n_value as an already-absolute address instead of re-basing it onto the
section VA, and give non-loadable sections (DWARF/debug, build attributes,
.pinit) no loadable vaddr so their code-valued debug entries no longer split
instructions mid-stream or shadow the real low-addressed loadable sections. The
formats/coff test expectations are updated accordingly.
2026-06-15 23:31:05 +08:00
Anton Kochkov a2454fec15 librz/arch/vax: add new LGPL DEC VAX-11 disassembler and analysis plugin
Add a new LGPL-3.0 VAX-11 architecture plugin that replaces the removed
binutils-derived GPL one. It is written from scratch from the documented
VAX operand-specifier encoding and does not reuse any GPL code.
2026-06-13 18:58:55 +08:00
Anton Kochkov 423104df4a arch/vax: remove the GPL binutils-derived VAX plugin
Drop the old GPL-licensed VAX disassembler (vax_gnu), which was derived
from GNU binutils and gated behind the use_gpl build option. It is being
replaced by a new, clean-room LGPL implementation in a following commit.

Removed:
  - librz/arch/isa_gnu/vax/vax-dis.c
  - librz/arch/isa_gnu/vax/vax.h
  - librz/arch/p_gnu/arch_vax.c
  - librz/arch/p_gnu/asm/asm_vax_gnu.c
  - librz/arch/p_gnu/analysis/analysis_vax_gnu.c

and their entries from the use_gpl plugin/source lists in
librz/arch/meson.build.
2026-06-13 18:58:55 +08:00
Anton Kochkov f2f4543a26 type: add tk commands to list and manage typeclasses (#3381)
Expose the typeclasses of types through the new `tk` commands:

- `tk <type>` shows the typeclass of a type;
- `tkl` lists the available typeclasses, while `tkll` (verbose), `tklt`
  (table) and `tklj` (JSON) additionally list the types belonging to each
  typeclass;
- `tks <type> <typeclass>` sets the typeclass of a type.

A new rz_base_type_set_typeclass() API backs the `tks` command. Since a
typedef without its own typeclass inherits the one of the type it points
to, setting the typeclass of an atomic type is automatically reflected on
the typedefs resolving to it.

The `tk` help also explains what typeclasses are and lists the available
ones.

Closes #3371
2026-06-02 13:43:11 +08:00
Anton Kochkov 36a593e360 librz/type: add tr command to rename a type and its references (#4016)
Introduce rz_type_db_rename_base_type() and expose it through the new
`tr` command to rename a base type. In addition to renaming the type
itself, every reference to it is updated so the analysis state stays
consistent after the rename:

- other base types and function types (callables) that use the type,
  including self-references such as a linked-list struct that contains a
  pointer to itself;
- the `pf` formats that mention the type, both the format stored under
  the type's own name and the "(name)" references inside other stored
  formats;
- the types of analysis global variables (as reported by `avg`), the
  function signatures (return type and arguments) and the function local
  variables.

The whole update is orchestrated by rz_core_types_rename(), and the
recursive RzType reference renamer is exposed as
rz_type_rename_references() so it can be reused for type usages that live
outside the type database.

Closes #1078
2026-06-01 05:04:05 +08:00
Anton Kochkov e91c636f00 test/unit: cover rz_core_graph_* per-type API entry points
The existing integration tests only reached the per-type graph
builders through the rz_core_graph() dispatcher. Add tests that call
rz_core_graph_callgraph/datarefs/coderefs/importxrefs directly and
assert they agree with the dispatcher, plus coverage for the
rz_core_graph_to_dot_str()/rz_core_graph_to_sdb_str() serializers.

Completes the work on rizinorg/rizin#992.
2026-05-29 00:22:08 +08:00
Anton Kochkov 0cdeb0df2a Add colors, Unicode and RzIL to the visual bit editor
The visual bit editor (V d 1 / V b1) ignored the active color theme,
scr.utf8 and cfg.bigendian, always showed ESIL even when RzIL was
available, overflowed the IL onto a single line, and drew the cursor
position as a detached underline. This reworks it to match the styling
of the commands users already know and adds a cursor-position summary.

- Byte order on screen follows cfg.bigendian: big-endian shows the
  byte at the current offset on the left, little-endian reorders so the
  MSB is on the left. Cursor movement and every byte-write key go
  through a MEM_BYTE() mapping so edits land on the byte under the
  cursor regardless of endianness; the buffer stays in memory order.
- chr/dec/hex byte cells are colored by value via rz_print_byte_color,
  the same helper px uses. The asm line keeps rz_asm_colorize_asm_str.
- The rzil line is colored like plf: core_colorify_il_statement is
  split into an address-prefix wrapper and a body-only colorizer
  (rz_core_il_colorize_body) shared by both. Long IL is soft-wrapped at
  the terminal width, breaking between top-level seq children and
  indenting continuations.
- RzIL is preferred over ESIL; the analysis op now also requests
  RZ_ANALYSIS_OP_MASK_IL. When neither is available the line is omitted.
- The bit under the cursor is reverse-video highlighted (a graphics
  attribute emitted regardless of scr.color); padding bits are dimmed
  via pal.comment. The empty-bit padding glyph is the middle-dot when
  color or Unicode is on, else a plain period.
- The position indicator now sits between the two bit rows as a single
  marker pointing at both, and a compact info line summarizes the
  cursor: "byte N - nibble H|L - bit B [P] - LE|BE".
- The ? help is expanded with a description of the mode and a legend
  for the position line; the key table is colored like the other
  visual help screens via rz_core_visual_append_help.
- Fix a leak of the asm op on the q/Q exit path.

Closes #6361
2026-05-28 23:14:33 +08:00
Anton Kochkov ef4d2334a2 arch/tms320: pdf rendering tests for c55x and c55x+ functions
Adds full-function disassembly (pdf) tests for non-trivial functions on
both CPUs, to lock in correct rendering of basic-block boundaries,
reflines (forward and backward branches), call/data/string cross-
references and operand formatting.

C55x (emulateme_nostd.ccsv5.c55x.ticoff2.dbg.coff):
  - sym._uart_write_hex: a compact two-block function with a forward
    conditional branch, an unconditional branch refline and a call ref.
  - sym.___text: a four-block loop with conditional branches both ways,
    a back-edge, a call into another function, data references and
    parallel-instruction (||) operands.

C55x+ (coff2/19_emulateme_nostd.obj):
  - sym._c_strlen: a four-block scan loop with a back-edge and forward
    and backward bcc reflines.
  - sym._main: a five-block function with nested conditional branches
    and two call references (_c_strlen, _decrypt).

All four render cleanly with the existing decoder and analyzers; no
behavior change was needed.
2026-05-28 17:44:54 +08:00
Anton Kochkov 13ebcbc2c7 arch/tms320: named instruction IDs (TMS320C55_INS_*) from the disassembler
Gives the C55x / C55x+ disassembler a Capstone-style per-instruction
identifier and threads it through to analysis, so the analyzers dispatch
on named operations instead of raw opcode bytes.

What lands
==========

* librz/arch/isa/tms320/tms320c55x_insn.{c,h} -- a shared TMS320C55InsID enum
  (TMS320C55_INS_AADD, TMS320C55_INS_B, TMS320C55_INS_CALL, ...) covering
  C55x and C55x+, plus tms320c55x_insn_name(), tms320c55x_insn_id_from_syntax()
  and tms320c55x_insn_optype(). The prefix is TMS320C55_ / tms320c55x_
  rather than TMS320_ / tms320_ because the other TMS320 families (C54x,
  C64x, C28x) have substantially different instruction sets; the enum,
  the file and these helpers are C55x/C55x+ specific.

* insn_head_t gains an .id field; every head entry in c55x/table.h is
  tagged with its TMS320C55InsID. The disassembler resolves the decoded
  instruction ID from the emitted mnemonic (so multi-form leading bytes
  such as 0x95 -> intr/trap, 0x48 -> ret/reti/rpt, 0x50 -> sftl/popboth
  resolve to the exact instruction, which a static byte->head map cannot).
  tms320_dasm_t gains an insn_id field and tms320_dasm_insn_id() accessor.

* tms320_c55x_insn_id_decode() / tms320_c55x_plus_insn_id_decode() let the
  analyzers resolve the named ID for a byte sequence via a cached decoder
  instance.

* The C55x analyzer's dispatch is rewritten from switch(opcode_byte) to
  switch(TMS320C55InsID). Both analyzers set op->id to the named ID, the
  same way the Capstone-based plugins (e.g. c64x) populate op->id.

* The C55x+ analyzer keeps its byte-level dispatch for control flow,
  stack deltas and operands, but takes the final arithmetic/logical/move/
  multiply/stack type from tms320c55x_insn_optype(op->id). A leading byte on
  C55x+ encodes several instructions (selected by operand bits), so the
  byte switch alone cannot tell ADD from SUB, AND from OR/XOR, or AMOV
  from ASUB; the decoded id can.

Bugs fixed
==========

Driving dispatch / typing from the decoded id fixes a number of latent
mis-classifications the raw-byte switch had masked, verified against the
TI dis55 reference disassembler and the C55x+ documentation:

  - 0x50 0x66 (psh Tx) was typed SHL; now a stack push (corrects
    sym._main's computed stackframe in the rel.stripped.coff test).
  - 0x48 0x05 (reti) was typed REP; now RET.
  - 0x95 0x0F / 0x8F (intr vs trap) distinguished by the decoder.
  - C55x+ 0x7B: byte1 bit7 selects LD (mov) vs add/sub, and within
    add/sub byte2 bit7 selects sub; was always typed add/mov by nibble.
    (TI SWPU104 Table 7-2, opcode 01111011.)
  - C55x+ 0xD2 mar(XDAa op k24): address-register modify, now LEA like
    AADD / AMOV; was typed SUB. (Table 7-2, opcode 11010010.)
  - 57 further C55x+ arith/logical/move/stack contradictions found by
    cross-referencing a Motorola Droid (Wrigley3G) C55x+ baseband dump
    against the decoder are resolved by the optype override.

* DELAY is a memory-delay MOVE per TI SWPU104 sec.6.7.1 (Memory Delay,
  grouped under Move Operations): it copies Smem to Smem+1. Both
  analyzers now mark it as a memory access (width 2, write) and drop the
  spurious FAMILY_CPU (CPU is already the default family).

Tests
=====

New checks assert op->id carries the right TMS320C55_INS_* value on each
CPU, plus regression tests for every byte/decoded-id mismatch fixed above
(c55x: 0x50/0x48/0x95/0xb6; c55x+: 0x7b/0xd2). The c55x opcode-
classification and stackframe expectations are updated to the corrected
output.

Cross-reference
===============

  TI SPRU374    'TMS320C55x DSP Mnemonic Instruction Set Reference Guide'
  TI SWPU086    'TMS320C55x+ DSP Algebraic Instruction Set Reference Guide'
  TI SWPU104    'TMS320C55x+ DSP Mnemonic Instruction Set Reference Guide'
2026-05-28 17:44:54 +08:00
Anton Kochkov 6d57743bb6 arch/tms320: add README explaining the three supported CPUs
Short summary of the three cpu= values supported by the tms320 arch
plugin (c55x, c55x+, c64x), the silicon they map to, and a note on
the two distinct meanings of 'c55x+': TI's publicly-named C55x DSP
Core+ shipping in current low-power C55x parts (C5504-C5545), and
the pre-release Ryujin revision documented in TI SWPU086 / SWPU104
that lives in older modem silicon. The rizin plugin handles both.
2026-05-28 17:44:54 +08:00
Anton Kochkov d81489e40d bin/dwarf: force big-endian read on TMS320 COFF DWARF sections
TI's cl55 compiler writes COFF files with little-endian file and
section headers, but the data inside DWARF sections (.debug_info,
.debug_abbrev, .debug_frame, .debug_line) is laid out as 16-bit
big-endian words. The DWARF parser was reading the unit length as
LE and getting absurd values, then bailing out with zero
compilation units.

Result: afvl, avgl, afs all returned empty for every
emulateme*.ticoff2.dbg.coff in rizin-testbins even though the
file had a fully-populated .debug_info section, the abbrev
tables parsed cleanly, and the per-architecture DWARF register
mapping (added separately) was available.

Override bf_bigendian() for arch=tms320 so the DWARF endian reader
swaps correctly. The COFF info struct stays in the same
little-endian state it always was; only the dwarf reader's view
flips.

After this fix, cl55-compiled TI COFF v2 binaries with debug info
yield:
  afvl @ dbg.main  -> arg int argc @ ar4
  afs  @ dbg.main  -> int main(int argc);
  avgl             -> 7 globals (uart_address, seckrit, _lock, ...)
  pdf  @ <fn>      -> renders with signatures, named args, reflines,
                      resolved call targets
2026-05-28 17:44:54 +08:00
Anton Kochkov 4221d56cb9 arch/tms320: c55x and c55x+ analysis classifiers (byte-driven)
Rewrites the C55x and C55x+ analysis classifiers as pure byte-level
dispatch -- no mnemonic-string matching, no round-trip through the
disassembler -- and adds the supporting infrastructure they need to
produce useful RzAnalysisOp metadata.

What lands
==========

* librz/arch/isa/tms320/c55x/c55x_analysis.{c,h} -- C55x baseline
  classifier, ~360 lines, 256-entry size table extracted from the
  decoder's table.h.
* librz/arch/isa/tms320/c55x_plus/c55plus_analysis.c -- C55x+
  classifier rewritten in the same shape, ~470 lines covering 90+
  opcodes with byte-level disambiguation for 0x02 / 0x03 / 0x74 /
  0x76 / 0x7B / 0xC5.
* librz/arch/isa/tms320/tms320_dwarf_regnum_table.h plus a hook in
  librz/arch/dwarf_process.c -- TI cgt55 ABI DWARF register-number
  mapping, so the cl55 compiler's .debug_info variable locations
  resolve into rizin register names instead of returning the dummy
  "?" placeholder.
* librz/arch/p/analysis/analysis_tms320.c -- thin dispatcher that
  picks the per-cpu classifier and stops carrying the tms320_dasm_t
  engine in analysis state.

Why a byte-driven classifier
============================

The old classifier round-tripped through the disassembler and did
strncasecmp() on the mnemonic string. Three problems:

1. It kept a tms320_dasm_t engine alive in the analysis context
   just to read its 'syntax' buffer after every classify call.
   Removing it shrinks the per-analysis state and removes a
   tms320_dasm_init/_fini pair from the analysis_init/_fini path.

2. It only set op->type -- never op->jump, op->fail, op->stackop,
   op->stackptr, op->val, op->eob. Basic-block formation followed
   only the most obvious control flow, and call/ret/push/pop
   semantics were invisible to higher-level analysis.

3. It couldn't disambiguate predicated versus unconditional calls:
   the disassembler emits 'callcc' vs 'call', but the substring
   match missed the conditional fail-path for CALLCC.

The new classifiers fix all three:

  - Read the leading byte (and second-byte refinements where the
    encoding family is shared) directly from buf.
  - Resolve jump and call targets from BE-stored displacement and
    absolute fields, with correct sign extension for the 8-bit and
    16-bit relative forms.
  - Read 24-bit absolute targets via rz_read_at_be24().
  - Set op->fail = addr + size for every conditional jump/call,
    op->eob = true for unconditional branches and RET so basic-block
    walkers terminate correctly.
  - Track the stack: PSH/POP per ISA cluster, CALL/CALLCC +2,
    RET/RETI -2.
  - Capture INTR/TRAP immediates in op->val via set_imm().
  - Disambiguate sub-opcodes that share a leading byte by reading
    the relevant bits of the second byte. For C55x, the most
    notable case is 0x48 (RPT/RPTADD/RPTSUB/RET/RETI) which uses
    bits 0-2 of byte 1; for C55x+ the disambiguations are 0x02,
    0x03, 0x74, 0x76, 0x7B and 0xC5.
  - Handle parallel-prefix bytes (odd-valued leading bytes below
    0x80 in C55x like 0x03, 0x05, 0x07, 0x11, ...) by treating
    them as a 1-byte prefix and dispatching on byte 1 so paired
    '|| retcc', '|| bcc', etc. classify correctly.

Both classifiers ship analyzer helpers (set_cjmp, set_call, set_jmp,
set_ret, set_cret, set_push, set_pop, set_imm, set_mem_width,
set_dst_reg, set_ireg, set_dir, set_disp) so each opcode entry fills
the RzAnalysisOp ptr / val / stackop / stackptr / fail / eob fields
uniformly across both architectures.

DWARF register mapping
======================

Loading any cl55-compiled TI COFF v2 with debug info (every
emulateme*.ticoff2.dbg.coff in rizin-testbins) used to fire:

  ERROR: No DWARF register mapping function defined for tms320 32 bits

per variable, because dwarf_process.c had no entry for arch=tms320.
The new tms320_dwarf_regnum_table.h covers the cgt55 ABI numbering:
AC0-AC3, T0-T3, AR0-AR7, SP/SSP/CDP, BK03/BK47/BKC, DP/PDP, CSR,
BRC0/BRC1, TRN0/TRN1, RPTC, IER0/IER1, IFR0/IFR1, DBIER0/DBIER1,
IVPD/IVPH, ST0_55..ST3_55 (42 entries). Reach into the table is
guarded; out-of-range numbers fall back to NULL so the caller
surfaces the dummy "?" instead of confidently picking the wrong
register.

Wrigley3G coverage
==================

Validation against a 3.1 MB Wrigley3G baseband firmware (Motorola
Droid A855, MSG39UPEU_A1.19_1.80, partition CG45.img) found 31
leading-byte values producing real instructions classified as NULL.
The c55x+ classifier here covers those:

  0x50-0x5F        MOV memory/register cluster
  0x88, 0x8A       MOV ACx <-> mem high/low halves
  0x8C             ADD with carry, mem -> ACx
  0x97             Dual-memory MOV (parallel)
  0xA0             MOV with parallel dual addressing
  0xAC, 0xAD       MOV #k16, ACx (long immediate)
  0xB4, 0xB5       MOV with rounding and shift
  0xB6, 0xB7       ADD with shift (T-register or immediate)
  0xC0, 0xC2, 0xC4 ADD #k16 with shift slots
  0xCC             Packed ADD :: MOV dual-instruction encoding
  0xD0             MOV ACx, dbl(*(#abs24))
  0x2E, 0x2F       XCCPART predicated execute
  0x0B, 0x23       Wrigley silicon pseudo-ops (TRAP)
  0xC6             BFXTR / BFXPA bit-field extract (MOV)

The 0x03 family classifier extends from a 4-bit (0xF0) to a 6-bit
(0xC0) mask so the full encoded range resolves:

  0x03 0x00-0x3F   INTR #k5
  0x03 0x40-0x7F   TRAP #k5
  0x03 0x80-0xBF   SWAP register pairs
  0x03 0xC0-0xFF   SIM_TRIG (Wrigley-specific simulator trigger)

Coverage on Wrigley3G rises from 94.4% to 97.4% (2000-sample
random survey).

Tests
=====

Two new test suites land alongside the classifiers:

  test/db/analysis/tms320.c55x_32       11 tests (batched)
  test/db/analysis/tms320.c55x+_32      13 tests (batched + binary
                                                  fixtures)

Tests are intentionally batched -- each test bundles 10-12 opcode
checks behind one rizin process spawn instead of one per check.
That brings both suites down to under 0.5 seconds combined.

The c55x+ suite includes six binary-fixture tests against the
companion rizin-testbins drop-in tms320/coff2/*.obj corpus,
covering function discovery (afl), stack-pointer tracking
(afvs / afS), data-section walk (iS), and globals enumeration
(is). The c55x suite covers tms320/emulateme_nostd.ccsv5.c55x
.ticoff2.dbg.coff from the existing rizin-testbins tree.

Cross-reference
===============

  TI SPRU374    'TMS320C55x DSP Mnemonic Instruction Set Reference
                Guide' (publicly available) -- C55x baseline.
  TI SWPU086    'TMS320C55x+ DSP Algebraic Instruction Set Reference
                Guide' (May 2005) -- C55x+ instruction encodings.
  TI SWPU104    'TMS320C55x+ DSP Mnemonic Instruction Set Reference
                Guide' (December 2006) -- C55x+ mnemonic forms.
2026-05-28 17:44:54 +08:00
Anton Kochkov e0ce234a35 arch/tms320/c55x_plus: decode V/VV field as Carry/TC2 and expand asm corpus
Two related fixes to the c55x+ disassembler glue, plus the matching
expansion of the c55x+ asm test corpus from 25 to 104 cases.

V/VV decode (case 51)
2026-05-28 17:44:54 +08:00
Anton Kochkov 385daedf70 arch/tms320/c55x_plus: modernize disassembler glue
The c55x_plus disassembler glue layer (c55plus.c) is rewritten as a
thin shim over the th0rpe c55plus_decode() walker:

  - Drop the ad-hoc ctype tolower() loop; use rz_str_case() to
    lower-case the walker's mixed-case mnemonics in one call.
  - Reorder the includes; drop the unused ones.
  - Scope local variables to where they are actually used.
  - Move the global setup (ins_buff / ins_buff_len) into the same
    block as the c55plus_decode() call so the dataflow is obvious.

While here, fix a pre-existing off-by-one in utils.c. The hex-digit
lookup table was declared as a 17-character string with a duplicated
leading '0':

  static char hex_str[] = "01234567890abcdef";

This shifted every nibble >= 0xA by one position in the table:

  hex_str[10] = '0'  (should be 'a')
  hex_str[11] = 'a'  (should be 'b')
  ...
  hex_str[15] = 'e'  (should be 'f')
  hex_str[16] = 'f'  (unreachable)

Result: get_hex_str(0xff) returned "ee", get_hex_str(0xab) returned
"0a", and every disassembled '.byte 0xNN' for an unknown opcode with
nibbles >= A came out wrong. The function is used from
c55plus_decode.c on the unknown-opcode fallback path
(hash_code == 0x223), so the bug surfaces whenever the decoder bails
out and emits a raw byte.

Fix: use the correct 16-character table "0123456789abcdef" and rename
the static to hex_digits to make the role obvious. While here, tidy
strcat_dup() to use bitwise tests on the n_free bitmask so the
'3 = free both' contract is enforced uniformly, add docstrings to both
helpers, and drop the redundant memcpy length guard that was a no-op
for non-NULL length-zero strings.

No behavioural change for either piece beyond the bug fix above.
2026-05-28 17:44:54 +08:00
Anton Kochkov 9ccee37999 arch/tms320/c55x_plus: drop utils.{c,h}, use rz_util helpers
The c55x_plus decoder shipped with two private string helpers in
utils.c:

  strcat_dup(s1, s2, n_free)  - allocate s1+s2 and optionally free
                                inputs, with a bitmask controlling
                                which of s1/s2 are released
  get_hex_str(n)              - format the low 8 bits of n as a
                                two-character lowercase hex string

Both have direct equivalents in rz_util:

  strcat_dup(s, lit, 1)       -> rz_str_append(s, lit)
  strcat_dup(lit, s, 2)       -> rz_str_prepend(s, lit)
  strcat_dup(s1, s2, 3)       -> rz_str_append_owned(s1, s2)
  strcat_dup(s1, s2, 1) where
    s2 is also owned and freed
    manually right afterwards -> rz_str_append_owned(s1, s2)
  get_hex_str(n)              -> rz_str_newf("%02x", n & 0xff)

This commit converts all 56 strcat_dup call sites in
c55plus_decode.c and decode_funcs.c plus the single get_hex_str
site, then deletes utils.c and utils.h entirely.

While here, replace several local sprintf-into-stack-buffer +
rz_str_dup patterns with direct rz_str_newf calls:

  - get_AR_regs_class1: was malloc(50) + sprintf per case, now a
    single rz_str_newf per case returning the result directly.
    The function is reduced from 34 lines to 14.
  - get_AR_regs_class2: same pattern, reduced from 130 lines to
    79 with no allocation needed at the top.
  - get_token_decoded case 40/48, 70/72/80, 41/73: sprintf into
    a 512-byte stack buffer then rz_str_dup -> single rz_str_newf.
  - decode_funcs.c case 2 of get_status_regs_and_bits: was
    calloc(50) + sprintf, now rz_str_newf.

The 512-byte stack buffer 'buff_aux' in get_token_decoded becomes
unused and is removed.

C55PLUS_DEBUG, the only useful symbol that used to live in utils.h,
moves to ins.h (which all c55x_plus translation units transitively
include). ins.h gains a direct <rz_util.h> include so the rest of
the headers don't need to pull it in indirectly.

No behavioural change. Full c55x_plus test regression passes:
asm/tms320_c55x+_32 104/104, analysis/tms320.c55x+_32 45/45,
parity against TI dis55.exe v4.3.6 on the 13-source testbins corpus
remains 140/140.
2026-05-28 17:44:54 +08:00
Anton Kochkov 64c1cad7e5 bin/coff: promote globals in code sections to FUNC
COFF C_EXT (external/global) symbols carry their function-or-not
status in two places: the DTYPE field of n_type (the ISFCN bit), and
implicitly by the section they live in. The existing code only
honoured the DTYPE bit:

  ptr->type = DTYPE_IS_FUNCTION(s->n_type) || !strcmp(name, "main")
      ? RZ_BIN_TYPE_FUNC_STR : RZ_BIN_TYPE_UNKNOWN_STR;

C and C++ compilers set the ISFCN bit when emitting object code, so
this works for compiled output. But assembler-emitted globals -- TI's
asm55p / cl55, the GNU GAS COFF backend on legacy targets, and any
hand-written .s -- often leave n_type at zero. Every assembly symbol
then comes back as RZ_BIN_TYPE_UNKNOWN_STR, and 'aaa' has no way to
distinguish a function from a data label. Concrete example: with TI
asm55p output for the C55x+ test corpus, none of the eight .global
labels in 03_branches_calls.s (_short_ret, _short_branch, _short_call,
...) were promoted to functions, so analysis only found those
reachable by following control flow from a hard-coded entry.

Add a section-flag fallback: if the symbol's containing section has
COFF_SCN_CNT_CODE set (i.e. it's a .text / code section), the symbol
is a function. This keeps the DTYPE check as the primary signal but
fills the gap on assembler output.

Verified with TI C55x+ .obj files: all .global labels now appear as
RZ_BIN_TYPE_FUNC_STR and are picked up by 'aaa'. No regression on
the standard COFF test suite (Windows i386/amd64 .obj from compiled
C output).
2026-05-28 17:44:54 +08:00
Anton Kochkov 88a4121d70 bin/coff: support TI COFF v2 48-byte section header
The COFF section table walker assumed every COFF section header is
40 bytes -- the standard COFF1 form. The TI Common Object File Format
(SPRAAO8) extends this for TI COFF v2 (file magic 0x00C2) used by the
TI tools (asm55, cl55, cl6x, cl28, etc.):

  ------------------------------------------------------------------
  offset  size  field         standard COFF1     TI COFF v2
  ------------------------------------------------------------------
  0x00    8     s_name        char[8]            char[8]
  0x08    4     s_paddr       ut32               ut32
  0x0c    4     s_vaddr       ut32               ut32
  0x10    4     s_size        ut32               ut32
  0x14    4     s_scnptr      ut32               ut32
  0x18    4     s_relptr      ut32               ut32
  0x1c    4     s_lnnoptr     ut32               ut32
  0x20    2/4   s_nreloc      ut16               ut32  <-- widened
  0x22    2/4   s_nlnno       ut16               ut32  <-- widened
  0x24    4     s_flags       ut32               ut32
  0x28    -     reserved      -                  ut16  <-- new
  0x2a    -     mempage       -                  ut16  <-- new
  ------------------------------------------------------------------
  TOTAL          40                              48

Reading TI COFF v2 with the standard 40-byte stride walks the section
table off-by-8 per section, producing nonsense values for every
section after the first. In practice, vaddr and size for the second
section spill into the next section's name field, surfacing as
attention-grabbing decimal values like 0x7461642e (ASCII '.dat'
reversed -- bytes from the upcoming '.data' name being interpreted as
a size).

Concrete reproducer with TI asm55p output:
  $ wine asm55p.exe -v5505 03_branches_calls.s
  $ rz-bin -S 03_branches_calls.obj                # before this fix
  ...
  0x00000061 0x7461642e 0x00000040 0x7461642e ...  # garbage size
  ...
  $ rz-bin -S 03_branches_calls.obj                # after this fix
  0x000000fa       0x34 0x00000030       0x34 -r-x .text
  ...

Fix: add a parallel coff_init_scn_hdr_ti() that reads the 48-byte
layout, with nreloc/nlnno as ut32 (clamped to ut16 because the rest
of the COFF code keeps them as 16-bit and counts above 64K are not
encountered in practice). bin_coff_init_scn_hdr() picks the variant
based on coff_is_ti_machine() -- the same predicate already used in
the file-header parser to consume TI's f_target_id field.

Tested with TI asm55p output for C55x, C55x+, and C5500 (machine ids
0x9c, 0xa1, and TI_1/TI_2 file magics) -- sections now parse with the
correct sizes, vaddrs, and flags, and the resulting binaries open
cleanly under 'rizin -A' for analysis.
2026-05-28 17:44:54 +08:00
Anton Kochkov d2c67fe2c5 arch/tms320: fix =PC alias in c64x register profile
The c64x branch of tms320_reg_profile() declared '=PC pc' but only
ever registered pce1 -- pc was never one of c64x's declared registers.
This raised:

  WARNING: Invalid alias given in register profile: pc.

on every rz-asm / rizin invocation of any tms320 cpu, including c55x
and c55x+, because the warning fires during analysis init before the
cpu-specific branch of the profile is selected.

The C64x ISA uses pce1 (Program Counter Extension 1, .32 at index
545) as its program counter -- the only PC-named control register
declared in the c64x profile -- so '=PC pce1' is the correct alias.
The companion test/db/analysis/tms320.c64x_32 'arp' expectation is
updated to match.

The c55x / c55x+ branch (is_c5000) is unchanged -- those profiles do
declare 'pc' as a 24-bit program counter, so '=PC pc' stays valid
there.

This change is independent of the c55x_plus work in the rest of this
series; it would be a useful cleanup on its own. Included here because
it surfaces immediately whenever any of the new c55x+ analysis tests
are run.
2026-05-28 17:44:54 +08:00
Anton Kochkov cc8a02949e test: force little endian on cBPF test 2026-03-25 05:00:05 +08:00
Anton Kochkov 7f1be3d94a build: compile cBPF plugin only for capstone>=6 2026-03-25 05:00:05 +08:00
Anton Kochkov 20769eaaa7 ci: fix macOS package creation 2026-02-01 20:29:59 +08:00
Anton Kochkov 6cacb99e98 hppa: use capstone disassembler 2026-02-01 18:23:12 +08:00
Anton Kochkov ac6276d220 hppa: remove GNU plugin 2026-02-01 18:23:12 +08:00
Anton Kochkov e96b1ad95f debug: remove globals from XNU native debugger 2025-12-27 02:46:55 +08:00
Anton Kochkov 2574cbf50a ci: fix Travis CI dr tests 2025-12-23 11:56:04 +04:00
Anton Kochkov f94add3f6e ci: fix BSD dr tests 2025-12-22 20:49:26 +04:00
Anton Kochkov 95e9827651 ci: macos pip manage external environment 2025-11-12 01:19:46 +08:00
Anton Kochkov a3e8160207 ci: macos-13 is deprecated, use macos-15 2025-11-12 01:19:46 +08:00
58b0b3715b Add FreeBSD x86_64 debug tests (#3273)
Co-authored-by: well-mannered-goat <[email protected]>
Co-authored-by: Rot127 <[email protected]>
2025-06-24 21:19:31 +08:00
Anton Kochkov 67a1e2b327 util/table: add basic query tests 2025-06-21 01:31:53 +08:00
Anton Kochkov bf1952e457 util/table: remove dead code 2025-06-21 01:31:53 +08:00
Anton Kochkov ce6328496d Bump version to v0.9.0 2025-04-23 16:49:14 +08:00
Anton Kochkov 28a706442a ci: allow running Coverity manually 2025-03-19 22:40:47 +04:00
Anton Kochkov cb094f8445 shell: remove wrong autocompletion test 2025-03-07 09:45:07 +00:00
Anton Kochkov 929f582148 subprojects: regenerate shell grammar with 0.25.3 2025-03-07 09:45:07 +00:00
Anton Kochkov d253d24d07 subprojects: update tree-sitter 2025-03-07 09:45:07 +00:00
Anton Kochkov c8e653fbc1 subprojects: update libzip from 1.9.2 to 1.11.3 (#3667) 2025-03-01 15:25:09 +08:00
Anton Kochkov 2d0030e847 subprojects: update rz-libdemangle (#4791) 2024-12-23 22:03:15 +08:00
Anton Kochkov 100f20194a ci: use dev or stable rz-bindgen branches 2024-12-19 21:49:52 +08:00
Anton Kochkov 316023bc63 test: fix macOS debugging test 2024-12-17 14:34:49 +08:00
Anton Kochkov 7f45d584dc test: unbreak remaining write command tests 2024-12-17 14:34:49 +08:00
Anton Kochkov 4af9514ee6 rz-diff: remove 5Mb size limitation (#4767) 2024-12-15 12:57:20 +08:00
Anton Kochkov ad4e1cd34e librz/arch/alpha: build only for Capstone > 5 (#4735) 2024-11-24 23:46:19 +08:00
Anton Kochkov a8da505c5f DEC Alpha disassembly and analysis plugins (#4059) 2024-11-24 21:17:29 +08:00
Anton Kochkov f1e555901f ci: use muon-bootstrap name for bootstrap (#4700) 2024-11-04 13:17:03 +08:00
Anton Kochkov 2fafb3dbe5 ci: add Python 3.13 for macOS builders (#4688) 2024-10-25 00:05:04 +08:00