* librz/type: rewrite pf format parser
Replace the legacy print-format engine in librz/type/format.c with a
clean three-stage pipeline (parse -> read -> render) and a properly
typed DSL.
The new pipeline:
rz_pf_parse(str) source string -> RzPfFormat
rz_pf_read(fmt, buf, len, ctx) RzPfFormat -> RzPfValue[]
rz_pf_render(vals, mode, opts) RzPfValue[] -> printable string
rz_pf_format() one-shot for all of the above
Public API lives in <rz_pf.h> (pulled in transitively via <rz_type.h>).
DSL improvements over the legacy scheme:
* Sized integers with explicit endianness via case:
x4 d4 u4 o4 b4 (LE) vs X4 D4 U4 O4 B4 (BE).
* Sized floats: f2 / f4 / f8 (and BE F2 / F4 / F8).
* Encoding-aware strings: z(utf8) / z(utf16le) / z(utf16be) /
z(utf32le) / z(utf32be) / z(latin1) / z(ebcdic).
* Length-prefixed strings: z[N] reads a N-byte LE prefix then body.
* Parameterized timestamps: t(unix32) / t(unix64) / t(unixms) /
t(unixus) / t(unixns) / t(filetime) / t(dos) / t(hfs) /
t(oletime) / t(webkit) / t(cocoa). ntfs alias maps to filetime.
* GUID: G(ms) (Microsoft mixed-endian, default), G(be), G(le).
* Inline bitfields: B4(FLAG_A=1,FLAG_B=2,FLAG_C=4).
* Alignment: @N advances to next multiple of N.
* Bit fields: :N with optional < (LSB-first) or > (MSB-first).
* Length-by-reference arrays: [@earlier_field]T.
* TLV records: V(t=u1,l=u2,e=le,h=v|l|a,d=table). Dispatch table
uses tlv.<name>.<hex-tag> in the typedb formats hash.
Architecture highlights:
* Per-instance ReadState (bit_cursor + sibling lookup window).
The bit cursor snap-flushes to the next byte when a non-bit
field follows mid-byte.
* Recursion bound via RzPfCtx::max_depth (default 32).
* Five render modes: text (default), json, cstruct, quiet, dot.
The dot renderer emits a column-aligned record with offset/type/
name/value rows, suitable for direct rendering through Graphviz.
* Positioned diagnostics: RzPfError carries severity, category,
column position, and a human-readable message. Each is also
emitted via RZ_LOG_WARN for backward compatibility.
* Optional RzPfPalette and RzPfRenderOpts threaded through render
for inline ANSI colorisation. NULL palette = canonical text.
* Pointer dereference via RzPfCtx::read_at callback.
The integration test expectations in test/db/cmd/cmd_pf* are
updated in the same commit to match the new text-output format and
the new DOT renderer's column-aligned record layout. Bundling these
keeps the test suite green at this commit.
A transitional rz_type_format_data() shim at the bottom of
pf_parser.c forwards legacy callers (cprint.c, disasm.c) to the new
API; it is removed in the librz/core migration commit.
* librz/arch/types: migrate type DB to new pf format codes
Map every legacy single-character format code in the bundled type
SDB files to its new-DSL equivalent:
b / C -> x1 (1-byte hex)
c -> c (signed char, unchanged)
w -> x2 (2-byte hex LE)
i -> d4 (signed 32-bit decimal LE)
d -> x4 (4-byte hex LE)
q -> x8 (8-byte hex LE)
f -> f4 (32-bit float LE)
F -> F8 (64-bit float BE)
Z -> z(utf16le)
x -> x4
o -> o4
X -> r (hexdump)
n / N -> d4 / u4
Also add new typedef-only types for explicit display formats:
bin{8,16,32,64}_t -> b{1,2,4,8} (binary)
hex{8,16,32,64}_t -> x{1,2,4,8} (hex)
oct{8,16,32,64}_t -> o{1,2,4,8} (octal)
These let users opt into a display representation per field without
changing the underlying scalar size.
Update the corresponding integration test expectations in
test/db/cmd/cmd_avg and test/db/cmd/types: the 'tu', 'tuc', 'tp',
and 'avgp' commands report formats via the SDB, so the migrated
codes appear in their text output (e.g. 'pf 0f4x4 a b' instead of
the legacy 'pf 0fd a b' for a union of float + int).
* librz/core: rewrite pf integration on the new parser API
Remove the legacy rz_type_format_data() bridge and rewrite every
caller to use the new <rz_pf.h> API directly.
librz/core/cprint.c
core_print_format() constructs an RzPfCtx populated from the
RzCore (typedb, big_endian, bits, max_depth) and calls
rz_pf_format() in one shot. The bridge between RzCore I/O and the
pf reader is cprint_pf_read_at(), which forwards to rz_io_nread_at.
The bitmask-to-RzPfMode mapping is cprint_pf_mode().
For DOT mode the format name is passed via RzPfRenderOpts::graph_label
so the dot renderer uses it as the top-level record label.
When scr.color > 0 in TEXT mode, an RzPfPalette is populated from
the active color theme via RzConsPrintablePalette so `pf` output
blends with the rest of Rizin's UI and respects user theme
choices (eco / ec). The palette slots map to theme fields as:
pf field offset <- pal->offset (address column)
pf field name <- pal->fname (symbolic name)
pf endian marker <- pal->meta (metadata tag)
pf hex/number literal <- pal->num (numeric literal)
pf typedb label <- pal->flag (resolved symbol)
reset <- pal->reset
Each slot falls back to its previous hardcoded ANSI escape if the
theme field is unset, preserving prior behaviour for stripped-down
contexts. Other modes (json/cstruct/quiet/dot) ignore the palette.
Closes rizinorg/rizin#782.
librz/core/disasm.c
RZ_META_TYPE_FORMAT case rewritten to resolve via rz_pf_resolve_name
and decode via rz_pf_format() directly. Palette is supplied from
the same theme palette when ds->show_color is true so that
pd @ <struct> blends with the surrounding listing.
librz/include/rz_type.h
Drop the rz_type_format_data() forward declaration. Callers must
use the public <rz_pf.h> surface instead.
librz/core/cmd_descs/cmd_print.yaml
Rewrite the pf command help for the new DSL: sized integers
(case-discriminated endian), special scalars (G GUID, V TLV,
: bits, @ align), strings with encodings, parameterized timestamps,
typed composites (E enum, B bitfield, ? struct), DSL extensions
(length-prefix strings, length-by-reference arrays, inline
bitfields), skip/repeat/pointers, example invocations.
cmd_descs.c is regenerated from the YAML.
* test: pf parser unit and DSL-extension integration tests
Add fresh test coverage for the new pf parser. These are purely
additive: existing integration tests were updated in the parser
and SDB-migration commits so the suite stayed green throughout.
test/unit/test_pf.c (new, 131 tests)
Field-size tables (every fixed-size type) and ctype mapping, every
parse path (sized integers / floats / strings / timestamps /
pointers / structs / enums / bitfields / GUIDs / TLV / alignment /
bits / arrays), every read path (with both fixed and length-by-
reference array counts), every render mode (text / json / cstruct /
quiet / dot), every DSL extension (align, bits MSB/LSB, GUID layout,
length-ref array, length-prefix string, inline bitfield, TLV with
dispatch table), pointer dereference via an in-memory I/O callback,
recursion safety on self-referential structs, lifecycle / NULL
safety, diagnostics (positioned errors, all categories, caret-line
formatter, source capture, verbose parse), ambiguity (each
superficially similar DSL form parses unambiguously), the palette /
colorisation API (issue #782) including a regression test surfaced
by the property-based test harness for input bytes containing ESC,
and DOT-mode coverage (column-aligned layout, single field,
empty/filtered, timestamp values, TLV records).
test/db/cmd/cmd_pf_dsl (new)
8 integration tests targeting the new DSL extensions specifically:
@N alignment, :N bits in MSB and LSB ordering, default-layout GUID,
z[N] length-prefixed string, B4(K=V) inline bitfield, bare V TLV
with defaults, V(t=u2,l=u2,e=be) configured TLV.
test/db/cmd/types_format (new)
Verifies that the new bin{N}_t / hex{N}_t / oct{N}_t typedefs apply
the expected display representation when used inside struct fields
via the 'tp' command, demonstrating the per-base rendering
(binary / decimal / octal / hex).
* doc: pf DSL reference and librz/type README
doc/pf.md (new)
User-facing reference for the pf format DSL covering quick
examples, spec grammar (sized integers with case-discriminated
endian, floats, strings with encodings and length prefixes,
parameterized timestamps, composites -- struct ?, enum E, bitfield B
inline and typed, GUID G, TLV V, raw hexdump r), repetition and
arrays ([N], [@name], {N}, leading 0 for union), padding and
alignment (. skip, @N align, :N bits MSB / LSB), pointer
dereference (*<type>), names grammar (plain vs (typename)name),
output modes (text, json, cstruct, quiet, dot), and diagnostics
(severity / category / position / caret-line formatter; backward-
compatible RZ_LOG_WARN channel).
librz/type/README.md (new)
Subsystem architecture doc for librz/type. Covers public headers,
file map, the pf three-stage pipeline (parse -> read -> render) with
a diagram and entry-point table, per-stage explanations (parser
shape, ReadState scoping rules including bit cursor and sibling
lookup window and snap-flush rule, render mode dispatch including
the DOT column-aligned layout and the graph_label parameter),
typedb integration and recursion bound, error-reporting model,
test coverage summary, and pointer to doc/pf.md as the user-facing
reference.
* librz/type: remove legacy DSL conversion shim
All in-tree callers -- librz/bin/d/, librz/bin/format/, and the
integration tests in test/db/cmd/ -- have been migrated to the new
DSL in the earlier commits of this series. The compatibility shim
that translated bare legacy specifiers (x -> x4, b -> x1, w -> x2,
nN -> uN, NN -> UN, etc.) into the new DSL at the entry of
rz_pf_parse() is no longer load-bearing; this commit deletes it.
- librz/type/pf_parser.c: drop the 267-line
convert_legacy_to_new_dsl() function, the WARN_LEGACY macro,
and the per-parse allocation + free of the converted string.
rz_pf_parse() now walks the caller's spec directly.
- test/db/cmd/cmd_pf,cmd_pf2,cmd_pf_write,cmd_pfd,cmd_pf_new,
metadata: migrate legacy specifiers in CMDS blocks to the new
DSL (b -> x1, w -> x2, q -> x8, i -> d4, bare x -> x4, etc.)
and regenerate EXPECT blocks against the new render where
affected.
The parser now only accepts the new DSL. Any caller still passing
bare legacy specifiers will get "unknown specifier" warnings.
* librz/core,type: add scr.pf.short for delta-offset rendering
When scr.pf.short is enabled, MODE_TEXT rendering shows offsets as
deltas (+<n>) from the format's base address instead of the absolute
hex address. Useful for self-contained struct dumps where the
absolute load address is noise:
$ rizin -e scr.pf.short=true -qc 'wx 00007a452a4b9a02
pf fcb1d4 a b c d' =
0 : a = 4000 [LE]
+4 : b = '*'
+5 : c = 0b0100_1011 [LE]
+6 : d = 666 [LE]
Nested structs reset their delta from the same base, so a child of
`head` at offset +8 still prints as +0 in its own struct block.
The base is derived from the offset of the first top-level value;
callers can override it via RzPfRenderOpts::base_offset.
Includes 5 integration tests in test/db/cmd/cmd_pf_short covering
basic struct, off-mode parity (control), nested struct, concatenated
TLV records, and @-offset usage.
* librz/type,test,doc: add v(N) bitvector type for forensics use
Adds a new specifier `v(N)` to the pf DSL that reads N individual
bits (1..4096) from `ceil(N/8)` bytes and exposes them as N
separate 0/1 scalars. Forensics targets: page-frame bitmaps, NTFS
$Bitmap clusters, ext4 block/inode bitmaps, ELF DT_FLAGS_1, PE
characteristics, ACL bitmasks -- anywhere you want to *see* a
bitmap rather than collapse it to a hex number.
Grammar:
v(N) N-bit bitvector, default MSB-first per byte
v(N,lsb) LSB-first per byte (Intel order)
v(N,msb) explicit MSB-first (DWARF / network order)
Rendering:
text: [ 1 0 1 0 1 0 1 1 | 1 1 0 0 ] (12-bit)
json: {"bit_width":12,"value":"101010111100"}
quiet: 1 0 1 0 1 0 1 1 1 1 0 0
Bitvec fields do not participate in the packed-bit cursor used by
:N; each v(N) reads whole bytes and stands alone. A v(N) field
adjacent to a :N field flushes the partial bit cursor first.
Width is clamped to [1, 4096] with a RANGE diagnostic. The reader
consumes exactly ceil(N/8) bytes, leaving the cursor positioned for
the next field. Verified by the existing tail-field test pattern.
Tests:
test/unit/test_pf.c +10 unit tests (146 total OK)
test/db/cmd/cmd_pf_new +9 cmd tests (440 OK / 9 BR / 0 XX / 4 FX
across all 19 pf suites)
property harness +7 properties (140 unique props, 1000
trials each, 0 failures)
Docs:
doc/pf.md bitvector section with examples
librz/type/README.md cursor-interaction note for v(N) vs :N
* librz/core,type,test: address PR CI feedback for pf rewrite
Five fixes prompted by CI feedback and reviewer comments on the pf
rewrite series:
* librz/core/cmd_descs/cmd_print.yaml: two help-text lines exceeded the
yamllint 120-char ceiling (n1/n2/n4/n8 comment and the deprecation
notes entry). Both now use the same folded-scalar (comment: >) form
already used in cmd_analysis.yaml and cmd_descs.yaml. cmd_descs.c is
regenerated.
* test/db/cmd/cmd_pf_write: drop the BROKEN 'pf xxd print' test. It
relied on '.pf*' (run pf output as rizin commands) which the new
parser no longer emits -- analogous to the '.pfw' removal done
earlier. The companion 'pf xxd print happy' test exercises the same
path through 'pf.' and stays.
* librz/type/pf_parser.c: thread the RzTypeDB through render_cstruct
and render_dot (and their inner helpers) so RZ_PF_ENUM resolution
works in pfc and pfd mode the same way it already does in text mode.
Without this, 'pfc elf_header' emitted '/* 0x00000002 */' and 'pfd'
emitted '|value|0x0000ffff|'; with it the comments and cells carry
the symbolic name (ELFCLASS64, ET_HIPROC, etc).
scalar_text() RZ_PF_BITFIELD: when no inline B4(K=V,...) flags are
present but val->type_name names a typedb enum, walk that enum and
treat each case as a settable bit name. This makes the typedb form
'B (pe_characteristics) flags' decode to
'0x00008140 : IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE | ...' instead
of just the raw hex -- previously the bitname decoding only worked
on inline B4(...) forms.
* librz/core/cprint.c: cprint_pf_mode() had no mapping for
RZ_PRINT_VALUE, so 'pfv' fell through to TEXT mode and emitted
'0x00000004 = 0x11111111 [LE]' instead of the bare value '0x11111111'
expected by db/esil/arm_16 and existing pfv users. Added an explicit
RZ_PRINT_VALUE -> RZ_PF_MODE_QUIET mapping; QUIET already emits one
bare scalar per field, which is exactly the pfv contract.
* test EXPECTs: cmd_pfd unbreaks its bitfield case (also fixes the
data buffer -- the original used 'wx 0x00008140' which is parsed
byte-by-byte and yields LE u32 0x40810000, not 0x00008140, so no
flags matched). cmd_pf 'PE test' picks up the now-decoded
characteristics and dllCharacteristics bitfields. cmd_pf 'Print
value only' updates to the bare-value pfv contract. test/db/cmd/print
'elf 64bit ls pfc.elf_header' picks up the decoded enum symbols.
Also picks up clang-format-20 reflows in cprint.c, cmd_print.c,
pf_parser.c, and rz_pf.h that the CI's clang-format check flagged.
Also bumps the offset-delta buffer in render_val_text from 16 to 24
bytes so a worst-case ut64 decimal (20 digits + sign + NUL = 22) fits
without tripping -Werror=format-truncation on gcc with -O0.
Also fixes three swapped-argument mu_assert calls in test_pf.c (the
v(N) bitvector tests added in commit 8): the macro signature is
mu_assert(message, test) but those three calls passed (test, message),
which tripped -Werror=format= under -O3 because the int 'test' was
fed to the format string's %s slot.
Adds a second round of regression fixes prompted by a manual audit
against pristine upstream (review feedback after the first pass):
* render_quiet: handle raw byte-sequential types (RZ_PF_UINT128,
RZ_PF_HEXDUMP). scalar_text() has no per-byte case for these so the
default-clause '?' was emitted, making 'pfq Q' and 'pfv Q' print '?'.
render_quiet now mirrors text mode and emits a space-separated hex
stream for raw types.
* Sized pointers (p{2,4,8}): the legacy parser accepted 'p2', 'p4',
'p8' to force a 16/32/64-bit pointer width regardless of ctx.bits;
the new parser only handled bare 'p'. Restored via a new dispatch
branch ahead of bare 'p', recording the override in
RzPfField::bit_width (overloaded -- documented in rz_pf.h). A new
fld_ptr_size() helper consults the override first; read_ptr, the
pointer-deref read path, the STRPTR read path, and
pf_struct_size_impl all use it. 'pf p2p4p8pp2' now consumes
2+4+8+4+2=20 bytes and renders the right value at each position.
* Numeric pointer dereference: '*d4', '*x2', '*u8', etc. (pointer to
fixed-size scalar) only read the pointer itself and never followed
it. The reader now also calls ctx->read_at to fetch the target word
and populate scalars[0]; the text renderer prints both the pointer
literal and the dereferenced value -- '(*0x20) 42' instead of bare
'(*0x20)'. Affects 'pf *d4 ...' and the 'Pointers' / '32 bit twice
then string' tests.
* Pointer-to-struct dereference (*?): pointer-to-struct fields read
the pointer value but stopped there, so 'pf *?' (or typedb forms like
'(troll)Bah' marked with '*') showed only '(*0x30)'. The reader now
recurses through ctx->read_at into a worst-case 4 KiB buffer and
re-invokes read_nested_struct; the renderer prints the nested struct
body after the '(*ptr)' annotation. Recursion is bounded by
ctx->max_depth so cyclic Bah->Bah pointer chains terminate at the
documented limit instead of unbounded recursion. Affects 'nested
struct', 'complex nested struct', and 'flag for nested struct'.
* String pointer (bare 's'): RZ_PF_STRPTR rendering didn't show the
dereferenced target -- output was bare '"hello"' with no pointer
context. Now emits '(*ptr) "string"' (mirroring '*z') when the
deref produced a non-empty body; falls back to bare '""' on
unmapped or empty targets to avoid advertising a phantom pointer.
* render_val_text is_pointer branch: extended to render the nested
struct body for *? pointers and the dereferenced value for numeric
*d4/*x2/*u8 forms.
* Top-level read loop: rz_pf_read passed both 'cur_off + off' (as
read_field's off parameter) AND 'base_addr + cur_off' (as base_addr),
but read_field computes 'val->offset = base_addr + off'. This
double-added cur_off on every iteration past the first, so 'pf 2ic'
reading 5 bytes per iter reported iter 1's nb at offset 0x0a instead
of 0x05, and 'pf 2F' reported iter 1's double at offset 0x10 instead
of 0x08. Data reads were correct; only the displayed/JSON offsets
drifted. The fix: pass base_addr unchanged so val->offset becomes
base_addr + (cur_off + off). Affects 'array obj', 'print n-times a
format', 'pf', 'pf field name', 'JSON output'.
* Bare 'C' (legacy 1-byte unsigned decimal): the legacy parser accepted
'C' as 'print byte as decimal'; the new parser had dropped it. The
'types' test format 'pf fcb1d4C foo bar fool beer plop' was therefore
truncating to 4 fields. Restored as a deprecated alias for 'u1' (with
the standard 'use u1' note).
* pfw dotted-path navigation: the write-mode lookup only matched
top-level field names, so 'pfw gobelin.Buh.first=42' through nested
structs failed with 'field not found'. Replaced with a segment-by-
segment walker that descends through children at each dot. Affects
'write specific element through nested struct'.
* Drop '.pfw' usage from tests. '.pfw' (execute pfw output as rizin
commands) was a legacy convention -- the new pfw writes directly via
rz_io_write_at and emits a human-readable confirmation line, so the
'.' prefix evaluates that confirmation line as a command and fails.
Same direction as the earlier '.pf*' removal. All cmd_pf,
cmd_pf_write, cmd_pf2 tests updated.
* test/db/cmd/cmd_pf 'Register' marked BROKEN with a tracking comment:
the legacy 'r (regname)' looked up CPU registers via
RzPrint::get_register; the new parser repurposes 'r' as raw hex byte
dump and the register-fetch path is gone. Restoring would mean
wiring a new register-lookup hook through RzPfCtx, which is outside
the parser-rewrite scope.
* test/db/cmd/cmd_pf2 'pf F max precision (#13027)' annotated: not a
precision regression. Values differ from the original #13027 expected
output because the legacy 'F' specifier read bytes as LE-then-
reinterpret while the new parser follows the documented 'UPPERCASE
= BE' rule literally; the 17-digit precision -- the actual subject
of #13027 -- is preserved.
EXPECTs updated to match the corrected output across cmd_pf, cmd_pf2,
cmd_pf_write.
* doc/pf.md updated to reflect all DSL and rendering changes:
documents the sized pointers (p/p2/p4/p8), pointer dereference
semantics (numeric, struct, and string), the missing composites
(Q, U, L, n/N), the case-as-endian rule (no standalone endian
directive), the pfw write mode (dotted-path navigation, direct I/O,
no '.pfw'/'.pf*'), and the table of deprecated single-letter
aliases (b, d, o, q, u, i, f, F, w, Z, t, T, X, C).
* librz/type/pf_render.c (new): extracted the render-mode code paths
from pf_parser.c into their own translation unit. Hosts the text /
quiet / JSON / cstruct / DOT renderers, the per-mode helpers
(scalar_text, scalar_json, render_binary, render_guid,
compute_name_width, field_matches, emit_colored*), the RenderCtx
bag, and the public rz_pf_render() + rz_pf_render_json() entry
points. pf_parser.c keeps the parse + read pipeline and shrinks
from 4831 to 3280 lines. Helpers used by both translation units
(is_string_type, is_raw_type, endian_str, pf_vasprintf) move to
pf_parser.h as static inlines.
* librz/type/pf/ (new directory): moved every pf source out of the
librz/type/ top level into a dedicated pf/ subdirectory; only the
legacy format.c stays top-level. meson.build updated with the new
paths and the pf/ include dir.
* Split the monolithic parser into focused sub-grammar TUs, wired
together by the new pf/pf_internal.h (which centralizes the PF_DIAG
diagnostic macro, the shared ReadState, and all cross-TU
declarations):
- pf_parser_string.c string/encoding specs (z / s / Z)
- pf_parser_bitfield.c inline + typed bitfields
- pf_parser_bitvec.c bitvectors v(N)
- pf_parser_array.c array-count resolution
- pf_parser_struct.c nested struct / union reading
pf_parser.c shrinks from 3280 to ~2620 lines and now hosts only the
parse driver, type-spec dispatcher, reader core, context, and the
public utility surface. The TLV TU was migrated off its bespoke
extern/TLV_DIAG block onto the shared header.
* Add an RzStructuredData renderer: pf/pf_render_sd.c with the public
rz_pf_render_sd() (declared in rz_pf.h). (Named _sd, not _sdb: SDB is
Rizin's key/value database, unrelated to RzStructuredData.) It maps the decoded value
vector to the generic key/value document model -- scalars to typed
entries, arrays/bitvectors to arrays, nested structs to sub-maps
with a _type tag, raw/GUID payloads to byte blocks, timestamps to a
formatted string plus a <name>_raw sibling -- so callers get JSON,
YAML, or iterator access for free. Unit and property tests cover it
(see the consistency-pass note below).
* doc/pf.md and librz/type/README.md updated for the new pf/ layout
and the structured-data render mode.
* Consistency pass over librz/type/pf/: deduplicated the structured-data
scalar dispatch (one classifier feeding thin map/array emitters instead
of two parallel ~60-line switches), dropped unused includes
(pf_parser_time.h from the TLV TU, string.h from the struct TU,
rz_endian.h from the SD renderer) and a redundant extern decl now
covered by pf_internal.h, and fixed a dangling-pointer bug in the SD
char path (the classifier returned a pointer into its own by-value
temporary). Expanded coverage: 11 SD unit tests (157 total) and 6 new
theft properties (SD tree non-NULL, JSON structural well-formedness,
top-level object shape, YAML safety, determinism, filter-narrows).
* Split pf_render.c (1548 lines) into per-mode renderer TUs, mirroring
the earlier pf_render_sd.c extraction: pf_render_text.c (text+quiet),
pf_render_json.c (+rz_pf_render_json), pf_render_cstruct.c, and
pf_render_dot.c. A new pf_render.h carries the shared RenderCtx record
plus the cross-TU helper (pf_field_matches, pf_scalar_text,
pf_render_guid) and per-mode entry-point declarations. pf_render.c now
holds only those shared helpers and the rz_pf_render() dispatcher
(~372 lines). meson.build, the file-doc layout listings, and
librz/type/README.md are updated accordingly.
* Second consistency pass: ensured every public RZ_API entry point has a
Doxygen \brief block (added ones for rz_type_format_struct_size and
rz_pf_render_sd) and every file a \file description (added to
pf_parser.h and pf_parser_time.h). Deduplicated the field-size logic:
pf_struct_size_impl's sum and union loops now share one
pf_field_static_size() helper, the enum/bitfield byte-width override is
a single pf_enum_bitfield_width() helper (was inlined 3x), sized-pointer
width routes through the existing fld_ptr_size(), and the inline-bitflag
test shared by the JSON and DOT renderers became the
pf_value_has_inline_bitflags() predicate in pf_render.h. Dropped unused
includes left over from the render split. No behaviour change (157 unit
tests, 146 theft properties, full cmd sweep all green).
* Fix a CodeQL High alert (cpp/integer-multiplication-cast-to-long) in
the scalar-array path selector: the per-element byte delta was computed
as `idx * width` in 32-bit int before being added to the ut64 offset,
so a large array index could overflow int prior to the widening. The
multiplication is now done in ut64 ((ut64)idx * width). No behaviour
change for in-range indices; verified by the path-selection cmd tests.
* Fix a big-endian bug in the structured-data renderer: the bitvector
reader stores each bit in the RzPfScalar union's v_u8 member, but the
SD classifier read it back through v_u64. On little-endian those alias
to the same low byte so it worked by luck; on big-endian (s390x) v_u8
is the high byte of the 64-bit slot, so every set bit read as a large
number and the test_pf_render_sd_bitvec assertion failed. The
classifier now reads v_u8 for RZ_PF_BITVEC, matching the writer; the
other scalar types already read the same width the reader wrote.
* Clean up leftover refactoring-era comments in the renderer TUs: drop
the "Split out of pf_render.c" changelog phrasing from the file-doc
headers (the docs now describe the current layout) and update two
stale references to the pre-rename helper names (field_matches ->
pf_field_matches, render_guid -> pf_render_guid) in comments.
---------
Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
888 lines
16 KiB
Text
888 lines
16 KiB
Text
NAME=oon
|
|
FILE=bins/mach0/mac-ls2
|
|
CMDS=<<EOF
|
|
oon
|
|
ol
|
|
EOF
|
|
EXPECT=<<EOF
|
|
4 * r-- 0x00009730 bins/mach0/mac-ls2
|
|
EOF
|
|
RUN
|
|
|
|
NAME=oonn
|
|
FILE=bins/mach0/mac-ls2
|
|
CMDS=<<EOF
|
|
pfn~?
|
|
oonn
|
|
pfn~?
|
|
ol~?
|
|
EOF
|
|
EXPECT=<<EOF
|
|
91
|
|
149
|
|
1
|
|
EOF
|
|
RUN
|
|
|
|
NAME=oml=
|
|
FILE=bins/mach0/mac-ls2
|
|
BROKEN=1
|
|
CMDS=oml=
|
|
EXPECT=<<EOF
|
|
|
|
0* 0x100000000 ################-------------- 0x100005000 r-x 3 fmap.TEXT
|
|
1 0x100005000 ---------------####----------- 0x100006000 r-- 3 fmap.DATA
|
|
2 0x100006000 ------------------############ 0x10000a000 r-- 3 fmap.LINKEDIT
|
|
=> 0x1000011e8 ------------------------------ 0x1000012e8
|
|
EOF
|
|
RUN
|
|
|
|
NAME=obo baddrs
|
|
FILE=bins/mach0/mac-ls2
|
|
ARGS=-B0x50000
|
|
CMDS=<<EOF
|
|
s
|
|
o bins/mach0/mac-ls
|
|
s
|
|
obo 3
|
|
s
|
|
obo 4
|
|
s
|
|
EOF
|
|
EXPECT=<<EOF
|
|
0x511e8
|
|
0x100001058
|
|
0x511e8
|
|
0x100001058
|
|
EOF
|
|
RUN
|
|
|
|
NAME=oom
|
|
FILE=bins/elf/libmagic.so
|
|
CMDS=<<EOF
|
|
ol~?
|
|
oom
|
|
ol~malloc?
|
|
EOF
|
|
EXPECT=<<EOF
|
|
4
|
|
1
|
|
EOF
|
|
RUN
|
|
|
|
NAME=o-[0]
|
|
FILE=malloc://1024
|
|
CMDS=o- `o~[0]`;o
|
|
EXPECT=
|
|
RUN
|
|
|
|
NAME=oj-
|
|
FILE=malloc://1024
|
|
CMDS=o- `oj~{[0].fd}`;o
|
|
EXPECT=
|
|
RUN
|
|
|
|
NAME=o =
|
|
FILE=malloc://1024
|
|
CMDS=<<EOF
|
|
o =;ol~?
|
|
EOF
|
|
EXPECT=<<EOF
|
|
2
|
|
EOF
|
|
RUN
|
|
|
|
NAME=om
|
|
FILE=malloc://1024
|
|
CMDS=<<EOF
|
|
om `ol~[0]` 0x4000
|
|
oml~?
|
|
EOF
|
|
EXPECT=<<EOF
|
|
2
|
|
EOF
|
|
RUN
|
|
|
|
NAME=om2
|
|
FILE=malloc://1024
|
|
CMDS=<<EOF
|
|
om `ol~[0]` 0x4000
|
|
om `ol~[0]` 0x4000
|
|
oml~?
|
|
EOF
|
|
EXPECT=<<EOF
|
|
3
|
|
EOF
|
|
RUN
|
|
|
|
NAME=omn - crash
|
|
FILE==
|
|
CMDS=omn
|
|
EXPECT=
|
|
RUN
|
|
|
|
NAME=oob 10
|
|
FILE=bins/elf/analysis/hello-linux-x86_64
|
|
CMDS=<<EOF
|
|
10oob
|
|
pi 1
|
|
EOF
|
|
EXPECT=<<EOF
|
|
xor ebp, ebp
|
|
EOF
|
|
RUN
|
|
|
|
NAME=oo+ 10
|
|
FILE=bins/elf/analysis/hello-linux-x86_64
|
|
CMDS=<<EOF
|
|
10oo+
|
|
pi 1
|
|
EOF
|
|
EXPECT=<<EOF
|
|
xor ebp, ebp
|
|
EOF
|
|
RUN
|
|
|
|
NAME=oob consider baddr
|
|
FILE=bins/mach0/mac-ls
|
|
CMDS=<<EOF
|
|
e bin.baddr=0xf00000
|
|
k old_v=`ieq`
|
|
oob
|
|
iI~baddr[1]
|
|
ie:vaddr:quiet
|
|
p8 10 @ entry0
|
|
p8 10 @ `k old_v`
|
|
EOF
|
|
EXPECT=<<EOF
|
|
0x00f00000
|
|
0x00f01058
|
|
554889e5415741564155
|
|
ffffffffffffffffffff
|
|
EOF
|
|
RUN
|
|
|
|
NAME=oob consider laddr 32bit
|
|
FILE=bins/mach0/fatmach0-3true
|
|
ARGS=-a x86 -b 32
|
|
CMDS=<<EOF
|
|
e bin.laddr=0x5000
|
|
e bin.baddr=-1
|
|
oob
|
|
iI~laddr[1]
|
|
iI~baddr[1]
|
|
EOF
|
|
EXPECT=<<EOF
|
|
0x00000000
|
|
0x00001000
|
|
EOF
|
|
RUN
|
|
|
|
NAME=oob consider laddr 64bit
|
|
FILE=bins/mach0/fatmach0-3true
|
|
ARGS=-a x86 -b 64
|
|
CMDS=<<EOF
|
|
e bin.laddr=0x5000
|
|
e bin.baddr=-1
|
|
oob
|
|
iI~laddr[1]
|
|
iI~baddr[1]
|
|
EOF
|
|
EXPECT=<<EOF
|
|
0x00000000
|
|
0x100000000
|
|
EOF
|
|
RUN
|
|
|
|
NAME=oob from malloc
|
|
FILE=malloc://1024
|
|
CMDS=<<EOF
|
|
wx 7f454c4601010100b32ae9310000000002000300010000000800200020000000010000000000000000002000010000001b0300001b0300000700000000100000e901000000b0e8a502000049e7551ff1c2a03ff17995d4f3f241adf35954d7a87b543f48e7551ff1c3a03ff179bc17f3795487eb79543fc0b0ddf14b78543ff1b4d41632fc944be0c0563ed179e60b197f563ff190273df179bf3e412aeda9f3595485f579543f1987553ff1914c3df1796722677b743f856aeddaf159548dec91813ef179bd7df379544dc722d1e48491ed09f05954859979543f19c3553ff190733df1795e1fa60b3b519659245e820a2350831d781f8216264d88577a11fb73546c9e0b2646d11b214bd10d3c5ad1092650921c274cd10a315a9c0a744b9e59365ad10d265e921c3011df57747d881c7a11df735412cf59074a921a314c8259751ed13a3b51960b354b8415354b98163a4cdf577a35d1597901d1203b4ad11a3551d10a31519559395ad1003b4a835927509d0c20569e177b5c9e14395a9f0d271f900d744b991c745e9316225ad11435569d59355b950b7a11df7354c511b6cac511c2838b48c9899750f5818854b6c7c55fff99915eb199c552e48b865afb8fc512a4e0c511b6cac511bbc7c81cbbc7c81cbbc7c81cbbc7c81cbbc7c81cbbc7c81cbbc7c81cbbc7c81cbbe0ef65fe839611f9848011fe8b9611f7ca9550e49e8c52e3868443fa93c542fb8b895db6998c4bf3c4cb1f9ca28a41f3ca9016fa86c556f39ec542f9878011f09f8b11e1839159b683911f9ce0bc5ee3ca8650f8ca8f5eff84c55cf3ca8445b693845fff99915ed6849049f38ecb5ee48dc55ee4ca8a5fb6c99654f58e8047d68c9754f3848a55f3c48b54e2e0ef74f89e8043b69e8d54b6ba8442e59d8a43f2cadf11b6cae53196ea3ff17954d6f079543f414894b632c950f271bae4d6f079543fd24894b63287978ff2b4d4fc41f092b606f08d92c0a9ffdd0bbabd3cf179548f393a65ff78baede0f37954fe187bea37f1595492f0bab6c4708a3f3bf92c972d2390b84b00200089c689f7b9a5020000c1e902ad35f179543fabe2f7c3e9010000003231c089c3fec0cd80c3
|
|
oba
|
|
i~bintype[1]
|
|
.ie*
|
|
p8 10 @ entry0
|
|
EOF
|
|
EXPECT=<<EOF
|
|
elf
|
|
b32ae931000000000200
|
|
EOF
|
|
RUN
|
|
|
|
NAME=ob select files
|
|
FILE=malloc://1024
|
|
CMDS=<<EOF
|
|
e scr.null=true
|
|
o malloc://512
|
|
e scr.null=false
|
|
i~file[1]
|
|
obo 3
|
|
i~file[1]
|
|
obo 4
|
|
i~file[1]
|
|
obo 3
|
|
i~file[1]
|
|
EOF
|
|
EXPECT=<<EOF
|
|
malloc://512
|
|
malloc://1024
|
|
malloc://512
|
|
malloc://1024
|
|
EOF
|
|
RUN
|
|
|
|
NAME=ob select files binobj
|
|
FILE=bins/elf/libmagic.so
|
|
CMDS=<<EOF
|
|
iiq~?
|
|
e scr.null=true
|
|
o malloc://1024
|
|
e scr.null=false
|
|
iiq~?
|
|
EOF
|
|
EXPECT=<<EOF
|
|
38
|
|
0
|
|
EOF
|
|
RUN
|
|
|
|
NAME=ob select files binobj2
|
|
FILE=bins/elf/libmagic.so
|
|
CMDS=<<EOF
|
|
isq~?
|
|
e scr.null=true
|
|
o bins/elf/true32
|
|
e scr.null=false
|
|
isq~?
|
|
# raise back
|
|
op `ol~:0[0]`
|
|
isq~?
|
|
EOF
|
|
EXPECT=<<EOF
|
|
408
|
|
46
|
|
408
|
|
EOF
|
|
RUN
|
|
|
|
NAME=ob 0 fix
|
|
FILE=<<EOF
|
|
bins/elf/_Exit (42)
|
|
bins/elf/libverifyPass.so
|
|
bins/elf/libc.so.6
|
|
EOF
|
|
CMDS=<<EOF
|
|
obl~[0-1]
|
|
echo
|
|
ob 1; i~^fd
|
|
ob 2; i~^fd
|
|
ob 0; i~^fd
|
|
EOF
|
|
EXPECT=<<EOF
|
|
0 3
|
|
1 5
|
|
2 9
|
|
|
|
fd 5
|
|
fd 9
|
|
fd 3
|
|
EOF
|
|
RUN
|
|
|
|
NAME=oC
|
|
FILE==
|
|
CMDS=<<EOF
|
|
wx 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff
|
|
s 0x10
|
|
px 16~:1
|
|
echo
|
|
oC $b
|
|
px 16~:1
|
|
echo
|
|
oml
|
|
echo
|
|
omp 1
|
|
px 16~:1
|
|
EOF
|
|
EXPECT=<<EOF
|
|
0x00000010 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f ................
|
|
|
|
0x00000010 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f !"#$%&'()*+,-./
|
|
|
|
1 fd: 3 +0x00000000 0x00000000 - 0x000001ff rwx
|
|
2 fd: 4 +0x00000000 0x00000000 * 0x000000ff rwx
|
|
|
|
0x00000010 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f ................
|
|
EOF
|
|
RUN
|
|
|
|
NAME=malloc ob fix
|
|
FILE=--
|
|
CMDS=<<EOF
|
|
e asm.arch=x86
|
|
e asm.bits=64
|
|
o malloc://1024
|
|
obl
|
|
EOF
|
|
EXPECT=<<EOF
|
|
0 3 x86-64 ba:0x00000000 sz:1024 malloc://1024
|
|
EOF
|
|
RUN
|
|
|
|
NAME=oblj
|
|
FILE==
|
|
ARGS=-a x86 -b 64
|
|
CMDS=<<EOF
|
|
oblj~{}
|
|
EOF
|
|
EXPECT=<<EOF
|
|
[
|
|
{
|
|
"name": "malloc://512",
|
|
"iofd": 3,
|
|
"bfid": 0,
|
|
"size": 512,
|
|
"obj": {
|
|
"arch": "x86",
|
|
"bits": 64,
|
|
"binoffset": 0,
|
|
"objsize": 512
|
|
}
|
|
}
|
|
]
|
|
EOF
|
|
RUN
|
|
|
|
NAME=o+ writable maps fix
|
|
FILE=--
|
|
CMDS=<<EOF
|
|
o+ bins/elf/ls
|
|
oml
|
|
# Possible parallelism problem
|
|
# echo
|
|
# pv1
|
|
# $old=`pv1`
|
|
# wx 0x90
|
|
# pv1
|
|
# wx `$old?`
|
|
# pv1
|
|
EOF
|
|
EXPECT=<<EOF
|
|
1 fd: 4 +0x00000000 0x00023560 - 0x00023f17 rwx vmap.reloc-targets
|
|
2 fd: 3 +0x00000000 0x00000000 - 0x0000347f rwx fmap.LOAD0
|
|
3 fd: 3 +0x00004000 0x00004000 * 0x00016790 rwx fmap.LOAD1
|
|
4 fd: 3 +0x00017000 0x00017000 - 0x0001f7bf rwx fmap.LOAD2
|
|
5 fd: 5 +0x00000000 0x00022268 - 0x00023557 rwx mmap.LOAD3
|
|
6 fd: 6 +0x00020050 0x00021050 - 0x00022267 rwx vmap.LOAD3
|
|
EOF
|
|
RUN
|
|
|
|
NAME=o--
|
|
FILE==
|
|
ARGS=-a x86 -b 64
|
|
CMDS=<<EOF
|
|
o =
|
|
ol~?
|
|
obl
|
|
echo --
|
|
o--
|
|
ol~?
|
|
obl
|
|
EOF
|
|
EXPECT=<<EOF
|
|
2
|
|
0 3 x86-64 ba:0x00000000 sz:512 malloc://512
|
|
1 4 x86-64 ba:0x00000000 sz:512 malloc://512
|
|
--
|
|
0
|
|
EOF
|
|
RUN
|
|
|
|
NAME=o- 3
|
|
FILE==
|
|
CMDS=<<EOF
|
|
e asm.arch=x86
|
|
e asm.bits=64
|
|
o =
|
|
o- 3
|
|
ol~?
|
|
obl
|
|
EOF
|
|
EXPECT=<<EOF
|
|
1
|
|
1 4 x86-64 ba:0x00000000 sz:512 malloc://512
|
|
EOF
|
|
RUN
|
|
|
|
NAME=oc
|
|
FILE=bins/elf/true32
|
|
CMDS=<<EOF
|
|
obl~?
|
|
i
|
|
oc =
|
|
# oc resets RzCore completely
|
|
e scr.utf8=false
|
|
e scr.color=0
|
|
echo --
|
|
obl~?
|
|
i
|
|
EOF
|
|
EXPECT=<<EOF
|
|
1
|
|
fd 3
|
|
file bins/elf/true32
|
|
size 0x560c
|
|
humansz 21.5K
|
|
mode r-x
|
|
format elf
|
|
iorw false
|
|
block 0x100
|
|
type EXEC (Executable file)
|
|
arch x86
|
|
cpu N/A
|
|
features N/A
|
|
baddr 0x08048000
|
|
binsz 0x000050bc
|
|
bintype elf
|
|
bits 32
|
|
class ELF32
|
|
compiler N/A
|
|
dbg_file N/A
|
|
endian LE
|
|
hdr.csum N/A
|
|
guid N/A
|
|
intrp /lib/ld-linux.so.2
|
|
laddr 0x00000000
|
|
lang c
|
|
machine Intel 80386
|
|
maxopsz 16
|
|
minopsz 1
|
|
os linux
|
|
cc N/A
|
|
pcalign 1
|
|
relro partial
|
|
rpath NONE
|
|
subsys linux
|
|
stripped true
|
|
havecode true
|
|
va true
|
|
static false
|
|
linenum false
|
|
lsyms false
|
|
canary true
|
|
pie false
|
|
relrocs false
|
|
nx true
|
|
--
|
|
1
|
|
fd 3
|
|
file malloc://512
|
|
size 0x200
|
|
humansz 512
|
|
mode rwx
|
|
format any
|
|
iorw true
|
|
block 0x100
|
|
type
|
|
EOF
|
|
RUN
|
|
|
|
NAME=ob
|
|
FILE=bins/elf/true32
|
|
CMDS=<<EOF
|
|
ob.
|
|
obf bins/elf/ls
|
|
ob.
|
|
ob 0
|
|
ob.
|
|
EOF
|
|
EXPECT=<<EOF
|
|
0
|
|
1
|
|
0
|
|
EOF
|
|
RUN
|
|
|
|
NAME=ox
|
|
FILE=bins/elf/true32
|
|
CMDS=<<EOF
|
|
ol
|
|
oml
|
|
ox 3 4
|
|
ol
|
|
oml
|
|
EOF
|
|
EXPECT=<<EOF
|
|
3 * r-x 0x0000560c bins/elf/true32
|
|
4 - r-x 0x000000b0 vfile://0/reloc-targets
|
|
5 - rw- 0x00000184 null://388
|
|
1 fd: 4 +0x00000000 0x0804e248 - 0x0804e2f7 r-- vmap.reloc-targets
|
|
2 fd: 3 +0x00000000 0x08048000 * 0x0804c657 r-x fmap.LOAD0
|
|
3 fd: 5 +0x00000000 0x0804e0bc - 0x0804e23f rw- mmap.LOAD1
|
|
4 fd: 3 +0x00004ef0 0x0804def0 - 0x0804e0bb r-- fmap.LOAD1
|
|
3 - r-x 0x000000b0 vfile://0/reloc-targets
|
|
4 * r-x 0x0000560c bins/elf/true32
|
|
5 - rw- 0x00000184 null://388
|
|
1 fd: 4 +0x00000000 0x0804e248 - 0x0804e2f7 r-- vmap.reloc-targets
|
|
2 fd: 3 +0x00000000 0x08048000 * 0x0804c657 r-x fmap.LOAD0
|
|
3 fd: 5 +0x00000000 0x0804e0bc - 0x0804e23f rw- mmap.LOAD1
|
|
4 fd: 3 +0x00004ef0 0x0804def0 - 0x0804e0bb r-- fmap.LOAD1
|
|
EOF
|
|
RUN
|
|
|
|
NAME=ol quiet
|
|
FILE=bins/elf/true32
|
|
CMDS=<<EOF
|
|
olq
|
|
ol.
|
|
ol.q
|
|
EOF
|
|
EXPECT=<<EOF
|
|
3
|
|
4
|
|
5
|
|
3 * r-x 0x0000560c bins/elf/true32
|
|
3
|
|
EOF
|
|
RUN
|
|
|
|
NAME=on+
|
|
FILE=bins/elf/true32
|
|
ARGS=-n
|
|
CMDS=<<EOF
|
|
cp `ol.t:uri:quiet` .true32-copy
|
|
on+ .true32-copy
|
|
p8 2
|
|
wx 9090
|
|
p8 2
|
|
o--
|
|
rm .true32-copy
|
|
EOF
|
|
EXPECT=<<EOF
|
|
7f45
|
|
9090
|
|
EOF
|
|
RUN
|
|
|
|
NAME=o=
|
|
FILE=bins/elf/true32
|
|
CMDS=<<EOF
|
|
o=
|
|
EOF
|
|
EXPECT=<<EOF
|
|
3 * r-x 0x0000560c [#########################] bins/elf/true32
|
|
4 - r-x 0x000000b0 [-------------------------] vfile://0/reloc-targets
|
|
5 - rw- 0x00000184 [-------------------------] null://388
|
|
EOF
|
|
RUN
|
|
|
|
NAME=oa
|
|
FILE=bins/elf/true32
|
|
BROKEN=1
|
|
CMDS=<<EOF
|
|
pd 3
|
|
oa arm 64
|
|
pd 3
|
|
EOF
|
|
EXPECT=
|
|
RUN
|
|
|
|
NAME=open priority
|
|
FILE=bins/elf/true32
|
|
CMDS=<<EOF
|
|
o bins/elf/true
|
|
op 3
|
|
ol~*
|
|
opn
|
|
opn
|
|
ol~*
|
|
opp
|
|
ol~*
|
|
opr
|
|
opr
|
|
ol~*
|
|
opr
|
|
ol~*
|
|
EOF
|
|
EXPECT=<<EOF
|
|
3 * r-x 0x0000560c bins/elf/true32
|
|
5 * rw- 0x00000184 null://388
|
|
4 * r-x 0x000000b0 vfile://0/reloc-targets
|
|
11 * r-x 0x000087c0 vfile://1/patched
|
|
3 * r-x 0x0000560c bins/elf/true32
|
|
EOF
|
|
RUN
|
|
|
|
NAME=open maps all VA
|
|
FILE=bins/elf/true32
|
|
CMDS=<<EOF
|
|
oml~true32
|
|
oma 3
|
|
oml~true32
|
|
EOF
|
|
EXPECT=<<EOF
|
|
5 fd: 3 +0x00000000 0x00000000 * 0xfffffffffffffffe r-x bins/elf/true32
|
|
EOF
|
|
RUN
|
|
|
|
NAME=maps relocation
|
|
FILE==
|
|
CMDS=<<EOF
|
|
e asm.arch=x86
|
|
e asm.bits=64
|
|
wx 9090
|
|
pi 2
|
|
oml
|
|
omb 1 0x3000
|
|
oml
|
|
pi 2
|
|
pi 2 @ 0x3000
|
|
EOF
|
|
EXPECT=<<EOF
|
|
nop
|
|
nop
|
|
1 fd: 3 +0x00000000 0x00000000 * 0x000001ff rwx
|
|
1 fd: 3 +0x00000000 0x00003000 - 0x000031ff rwx
|
|
invalid
|
|
invalid
|
|
nop
|
|
nop
|
|
EOF
|
|
RUN
|
|
|
|
NAME=maps cur relocation and priority
|
|
FILE==
|
|
CMDS=<<EOF
|
|
o malloc://512
|
|
o malloc://512
|
|
o malloc://512
|
|
e asm.arch=x86
|
|
e asm.bits=64
|
|
omp 1
|
|
wx 9090
|
|
omp 2
|
|
wx c3c3
|
|
ompd 2
|
|
pi 2
|
|
oml
|
|
omb. 0x3000
|
|
omp 2
|
|
oml
|
|
pi 2
|
|
pi 2 @ 0x3000
|
|
EOF
|
|
EXPECT=<<EOF
|
|
nop
|
|
nop
|
|
2 fd: 4 +0x00000000 0x00000000 - 0x000001ff rw-
|
|
3 fd: 5 +0x00000000 0x00000000 - 0x000001ff rw-
|
|
4 fd: 6 +0x00000000 0x00000000 - 0x000001ff rw-
|
|
1 fd: 3 +0x00000000 0x00000000 * 0x000001ff rwx
|
|
3 fd: 5 +0x00000000 0x00000000 - 0x000001ff rw-
|
|
4 fd: 6 +0x00000000 0x00000000 - 0x000001ff rw-
|
|
1 fd: 3 +0x00000000 0x00003000 - 0x000031ff rwx
|
|
2 fd: 4 +0x00000000 0x00000000 * 0x000001ff rw-
|
|
ret
|
|
ret
|
|
nop
|
|
nop
|
|
EOF
|
|
RUN
|
|
|
|
NAME=maps_names
|
|
FILE==
|
|
CMDS=<<EOF
|
|
omn HelloMap
|
|
oml
|
|
omn-
|
|
oml
|
|
omni 1 HelloMap1
|
|
oml
|
|
omni- 1
|
|
oml
|
|
EOF
|
|
EXPECT=<<EOF
|
|
1 fd: 3 +0x00000000 0x00000000 * 0x000001ff rwx HelloMap
|
|
1 fd: 3 +0x00000000 0x00000000 * 0x000001ff rwx
|
|
1 fd: 3 +0x00000000 0x00000000 * 0x000001ff rwx HelloMap1
|
|
1 fd: 3 +0x00000000 0x00000000 * 0x000001ff rwx
|
|
EOF
|
|
RUN
|
|
|
|
NAME=M68k, HPPA, Sparc, x86
|
|
FILE=bins/mach0/2048-NeXTSTEP
|
|
CMDS=<<EOF
|
|
iA
|
|
EOF
|
|
EXPECT=<<EOF
|
|
offset size arch bits machine big_endian
|
|
------------------------------------------------
|
|
0x00002000 49152 m68k 32 mc68030 true
|
|
0x0000e000 40960 x86 32 386 false
|
|
0x00018000 49152 hppa 32 hppa7100 true
|
|
0x00024000 49152 sparc 32 all true
|
|
EOF
|
|
EXPECT_ERR=
|
|
RUN
|
|
|
|
NAME=M68k, HPPA, Sparc, x86
|
|
FILE=bins/mach0/2048-NeXTSTEP
|
|
CMDS=<<EOF
|
|
|
|
# Test if sane defaults were selected
|
|
echo default (m68k)
|
|
e asm.arch
|
|
e asm.cpu
|
|
e asm.bits
|
|
e cfg.bigendian
|
|
pd 10 @ section.0.__TEXT.__text
|
|
|
|
obs hppa_32_hppa7100
|
|
e asm.arch
|
|
e asm.cpu
|
|
e asm.bits
|
|
e cfg.bigendian
|
|
pd 10 @ section.0.__TEXT.__text
|
|
|
|
obs sparc_32_all
|
|
e asm.arch
|
|
e asm.cpu
|
|
e asm.bits
|
|
e cfg.bigendian
|
|
pd 10 @ section.0.__TEXT.__text
|
|
|
|
obs x86_32_386
|
|
e asm.arch
|
|
e asm.cpu
|
|
e asm.bits
|
|
e cfg.bigendian
|
|
pd 10 @ section.0.__TEXT.__text
|
|
|
|
obs m68k_32_mc68030
|
|
e asm.arch
|
|
e asm.cpu
|
|
e asm.bits
|
|
e cfg.bigendian
|
|
pd 10 @ section.0.__TEXT.__text
|
|
EOF
|
|
EXPECT=<<EOF
|
|
default (m68k)
|
|
m68k
|
|
mc68030
|
|
32
|
|
true
|
|
;-- section.0.__TEXT.__text:
|
|
0x000049c0 movea.l a7, a0 ; [00] -r-x section size 6638 named 0.__TEXT.__text
|
|
0x000049c2 suba.w 0xc, a7
|
|
0x000049c6 move.l (a0)+, d0
|
|
0x000049c8 move.l d0, (a7)
|
|
0x000049ca move.l d0, 0x8004.l
|
|
0x000049d0 move.l a0, 0x4(a7)
|
|
0x000049d4 move.l a0, 0x8008.l
|
|
0x000049da addq.l 0x1, d0
|
|
0x000049dc asl.l 0x2, d0
|
|
0x000049de adda.l d0, a0
|
|
Backed up flag space into 'flags.hppa_32_hppa7100.sdb'. You can restore the flags with the 'ko' command.
|
|
hppa
|
|
hppa7100
|
|
32
|
|
true
|
|
;-- section.0.__TEXT.__text:
|
|
0x000039e8 ldw 0(sp), r26 ; [00] -r-x section size 10588 named 0.__TEXT.__text
|
|
0x000039ec ldo 0x7f(sp), sp
|
|
0x000039f0 ldil 0x3800, r1
|
|
0x000039f4 be 0x1fc(sr4,r1)
|
|
0x000039f8 depi 0, 0x1f, 6, sp
|
|
0x000039fc stw rp, -0x14(sp)
|
|
0x00003a00 stwm r5, 0x80(sp)
|
|
0x00003a04 stw r4, -0x7c(sp)
|
|
0x00003a08 stw r3, -0x78(sp)
|
|
0x00003a0c or r26, flags, r4
|
|
Backed up flag space into 'flags.sparc_32_all.sdb'. You can restore the flags with the 'ko' command.
|
|
sparc
|
|
all
|
|
32
|
|
true
|
|
;-- section.0.__TEXT.__text:
|
|
0x0000441c mov sp, o0 ; [00] -r-x section size 7912 named 0.__TEXT.__text
|
|
0x00004420 sethi 0x11, o5
|
|
0x00004424 or o5, 0x30, o5
|
|
0x00004428 jmp o5
|
|
0x0000442c nop
|
|
0x00004430 save sp, -0x70, sp
|
|
0x00004434 add i0, 0x44, o1
|
|
0x00004438 sethi 0x20, o2
|
|
0x0000443c st o1, [o2+8]
|
|
0x00004440 ld [i0+0x40], o0
|
|
Backed up flag space into 'flags.x86_32_386.sdb'. You can restore the flags with the 'ko' command.
|
|
x86
|
|
386
|
|
32
|
|
false
|
|
;-- section.0.__TEXT.__text:
|
|
0x00002a24 push ebp ; [00] -r-x section size 6524 named 0.__TEXT.__text
|
|
0x00002a25 mov ebp, esp
|
|
0x00002a27 push edi
|
|
0x00002a28 push esi
|
|
0x00002a29 push ebx
|
|
0x00002a2a lea esi, dword [ebp+0x04]
|
|
0x00002a2d mov edx, dword [esi]
|
|
0x00002a2f mov dword [0x6004], edx
|
|
0x00002a35 lea eax, dword [esi+0x04]
|
|
0x00002a38 mov dword [0x6008], eax
|
|
Backed up flag space into 'flags.m68k_32_mc68030.sdb'. You can restore the flags with the 'ko' command.
|
|
m68k
|
|
mc68030
|
|
32
|
|
true
|
|
;-- section.0.__TEXT.__text:
|
|
0x000049c0 movea.l a7, a0 ; [00] -r-x section size 6638 named 0.__TEXT.__text
|
|
0x000049c2 suba.w 0xc, a7
|
|
0x000049c6 move.l (a0)+, d0
|
|
0x000049c8 move.l d0, (a7)
|
|
0x000049ca move.l d0, 0x8004.l
|
|
0x000049d0 move.l a0, 0x4(a7)
|
|
0x000049d4 move.l a0, 0x8008.l
|
|
0x000049da addq.l 0x1, d0
|
|
0x000049dc asl.l 0x2, d0
|
|
0x000049de adda.l d0, a0
|
|
EOF
|
|
EXPECT_ERR=<<EOF
|
|
ERROR: unknown thread state structure 11
|
|
ERROR: mach0: Cannot parse thread
|
|
EOF
|
|
RUN
|
|
|
|
NAME=Switch between same archs, with different bits and machine
|
|
FILE=bins/mach0/AppIOSEntitlements.ios
|
|
CMDS=<<EOF
|
|
obs
|
|
|
|
obs arm_64_all
|
|
echo "# arm_64_all"
|
|
e asm.arch
|
|
e asm.bits
|
|
e asm.cpu
|
|
|
|
obs arm_32_v7
|
|
echo "# arm_32_v7"
|
|
e asm.arch
|
|
e asm.bits
|
|
e asm.cpu
|
|
EOF
|
|
EXPECT=<<EOF
|
|
arm_32_v7
|
|
arm_64_all
|
|
Backed up flag space into 'flags.arm_64_all.sdb'. You can restore the flags with the 'ko' command.
|
|
# arm_64_all
|
|
arm
|
|
64
|
|
all
|
|
Backed up flag space into 'flags.arm_32_v7.sdb'. You can restore the flags with the 'ko' command.
|
|
# arm_32_v7
|
|
arm
|
|
32
|
|
v7
|
|
EOF
|
|
EXPECT_ERR=
|
|
RUN
|