Warning: this also swaps the arguments of the old rz_bv_append() to be
consistend with the new inplace variant.
The reason why the inplace function has the low as the first operand is
that it can be more efficient to append to an existing vector inplace
than to prepend to it. Then, the first argument is being used as the
in-out one in all other inplace functions.
Consolidate the Unicode subscript notation used when rendering
bit-vector and float values (the subscript width on a bit-vector
constant, e.g. 0x2c followed by a subscript 8, and the format width
on a float, e.g. .f followed by a subscript 32) into one place, so
the RzIL Unicode exporter, the RzNum value printer, and the
RzNum->RzIL lift cannot drift apart.
RzUtil gains the single source of truth:
* rz_str_append_subscript() / rz_str_append_superscript() /
rz_str_subscript() render a number as Unicode subscript or
superscript digits;
* rz_bv_width_subscript() / rz_bv_as_unicode_string() build a
bit-vector's width subscript on top of the str helper;
* rz_float_format_subscript() renders a float format's width
subscript (16/32/64/80/128, with the decimal-format marker),
reusing the same digit renderer.
The RzIL Unicode exporter (il_export_string_unicode.c) is switched
fully onto these: every append_subscript() call site (bit-vector
constant width, cast length, memory indices) now goes through
rz_str_append_subscript(), and the hardcoded per-format subscript
macro is replaced by rz_float_format_subscript(). The exporter's
private subscript-digit table and ut32 glyph helper are removed, so
there is no longer a second, parallel implementation to keep in sync.
Signed-off-by: Anton Kochkov <anton.kochkov@gmail.com>
Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
Resulting bitvector contents for fill_bit = true were incorrect. In
particular, when extending, the new bits were not set and when
shrinking, the cut off bits were set to the fill_bit, even though they
would be out of range.
This brings these copy functions in line with the more common order of
dst, src as used in memcpy and rz_bv_*_inplace functions.
This is a breaking change and callers of rz_bv_copy() and
rz_bv_copy_nbits() must adjust to the new order.
* Add an in-place addition of bitvectors.
* Decouple _elem_len from assumption it has just enough bytes to hold len in bits.
* Add in-place copy of bits.
* Use default copy bits bitvector function.
* Mark stack allocated bit vector.
* Add inplace variant of complement_1
* Implement inplace bitvecotr not.
* Add inplace variant of rz_bv_and
* Implement inplace variant of rz_bv_or
* Implement inplace variant of rz_bv_xor
* Constify rz_bv_lsb/msb
* Implement inplace variant of rz_bv_neg
* Fix inplace add. Add inplace SUB
* Remove prefix
* Remove invalid const
* Implement in-place casting of bit vectors.
* Add a hash test
* Fix unnecessary &
* Prevent OOB reads & writes by copying only the minimum of bytes.
* Add inplace MUL
* Add ble version for bitvector set/get with bytes.
* Add documentation for inplace bitvector functions.
* Add bench of add/sub() and sub/add_inplace().
* Remove rz_bv_copy_nbits_inplace because it was the same as rz_bv_copy_nbits.
* Implement optimized functions for small to large and large to small
* Add benchmark instructions in testREADME.md
* Use the term unaligned consistently instead of nonaligned
* Slightly improve bitvector test error message
* Remove unnecessary annotations
* Edit readme
* Add explicit fallthrough comments
* Return statement for rz_bv_toggle_all()
* Extend tests
* Add benchmark for rz_bv_copy_nbits
* Improve performance for large to large and small to small bitvector copy
* Fix bug with nbit=64 and simplify code
* Add test for same bitvector copy
* Move bit copy logic to separate function in rz_bits.h + improve comments
* Support same vector copy for unaligned case
* Expect non-null RzTable in bench utils and add comments
* Test against reference implementation instead of hardcoded values
* fix: format with clang-format-20
* fix: fix clang-format linter with rewrite '^#define.*/\*.*\\$'
* fix: update clang-format to version 20 in workflows and documentation
* fix: add SPDX license information to .git-blame-ignore-revs
* Add extra bitvector operations defined in core theory basic extra part
* Add extra bitvector operations test
* Fix bv64 init const overflow in windows x64 test
* Add test case for bv_pred and bv_succ near 0
* Print a warning if config for VM was NULL.
* Add warning if register is not added to VM due to overlap.
* Update PPC register profile.
* Add vector and float registers. As well as some control and system registers.
* Enable to write values 4bit registers.
* PPC: Uplift most common instructions.
* Print warning if reserved SPR instruction is encountered.
* Update PC/LR addresses and add ca32 writes.
* Write cache needs to get flushed so load and store tests don't share the same memory.
* Add missing T/F branch mnemonics.
* Add Move to/from CR/CR0-7
* Fix TA address calculation for branch instructions.
* Add branch tests for branch mnemonics.
* Add XNOP
* NOP cache touch instructions.
* Add undocumented ATTN instruction to the not_implemented group.
* Add isel instruction.
* Implement CRCLR, CRSET, CROR.
* Add CNTLZ instructions.
* Add mcrf instructions.
* Add inacive test for cmpb.
* Add Load bytes reverse instructions.
* Add test and add address alignment to dcbz.
* Add eqv test
* Correct DIV and MUL operations
* Add div tests.
* Add tests and correct MT/MFXER
* Remove register ca32, ov32
* Remove explici setting of cr register because QEMU does not do it. Otherwise we get a mismatch in the trace
* Simplify carry set for add and sub. Sub instructions are exclusivly defined with addition. Hence no sub case needed.
* Unify BD and fix branch instructions. Fix: Check the single bit not the cr reg
* Document Conditional branches and replace NOPs with EMPTY
* Add mulli instruction to double word instructions.
* Fix ca set for shift instructions:
* ca value had to be determined before the shift happened. The wrong ca value was calculated if the src and target reg were the same.
* Replace NOP wit EMPTY.
* Use MSB isntead of SLT.
* Brought fixup of ADD and SUB instructions: The add and sub instructions had several issues which let to incorrect execution.
* The carry was incorrectly if three add operations happened (only the last add were checked, not both).
* The carry was incorrectly set if the src and target register matched.
* Same applies for the CR bit.
* It was too complex. Several local variables were introduced for this.
* Set result in local var, since it would change if src and target reg are the same.
* Remove MTMSR and MFMSR since it is too complex and untestable currently.
* Use unsigned int for shift. Otherwise the 0x1c shift produces a runtime error since 0xf is int as default.
* Fix mtxer: Only write flag bits.
* Let NOT_IMPLEMENTED macro return NULL.
* Mark st[wd]cx and l[wd]cx as not implemented.
* Increase dcache_line_size to 128 bytes.
* Fix cntlz for ppc32. m was set incorrectly, since it is 0 not 32 for 32bit cpus.
* Fix isel: Use op.crx reg instead of imm.
* Unify helper function names: Prependnig `ppc_` mark as IPI
* Add more "Move to SPR" cases.
* MULLI opeartes only on double word on 64bit CPUs.
* Most registers are now assigned the control register type and no longer show up in the ar command.
* Fix xor if dest and src registers match by saving result in local var.
* Fix BE/LE issue for Load BRX instructions.
* Fix shifts: Use only lower 6bits of n.
* User Pure local variables for ROT macros.
* Fix rldimi instructions.
* n was not inverted.
* more than 6 bits of n could be used
* Add 32bit emulateme tests.
* Add 64bit emulateme tests.
* Determine lg(v) in inline function.
* Calculate CR bit in C not in the VM.
* Check if `~mask = 0` and skip mask calculation if yes.
* Check for `sh == 0` and skip rotations where possible.
* Remove `la` instruction. `la` is a mnemonic for `addi`.
* Remove SPR instructions which are not supported by QEMU or not traced yet. For most set/read SPR instructions QEMU segfaults.
In case of SPR 1 (xer), 8 (lr) and 9 (ctr) the assembler resolves them to their mnemonics (mtxer, mtlr etc.). This means the code here is never reached.
To test the get_xer code MFXER was added again. The rz-tracetests will fail for this instructions (due to missing ca32, ov32). But this case is covert in an issue.
Problems fixed:
* Division by repeated addition is horribly slow, now it's classic
shift+sub
* a / a = 1, not a
* rz_bv_set_all() was setting too many bits if len % 8 != 0
* Removed print on div by 0 because we define it to all 1s (like BAP)
mod just uses div and we use regular ut64 division when possible.
Previously, bits were stored in the big endian in reversed order, such
that bit 0 of byte 0 would contain the msb. This requires reversing them
for any calculation and becomes even more confusing when the size is not
a multiple of 8, so let's just store them in classic little endian with
bit 0 of byte 0 containing the lsb.
This also fixes rz_bv_as_hex_string() for bvs that have a size not
divisiable by 0.
* Removed nullability where not needed
* Made events take RzILVal instead of force-converting to RzILBitVector
for variables
* Added more fine-grained tests for events from specific ops
Before:
store(key:var(v:ptr), value:add(x:load(key:var(v:ptr), mem:0),
y:int(value:1, length:8)), mem:0)
After:
(store 0 (var ptr) (+ (load 0 (var ptr)) (bv 8 0x1)))
S-Expressions like this are more concise and will be trivial to parse,
in case we want a parser for this later. It is also very similar to what
BAP uses, so it will be easier to compare.
There are now three kinds of vars: global, local and local pure. Global
and local pure are exactly like in BAP, local ones are defined by their
initial set op and have the scope of a single lifted instruction.
The set op now handles both global and local vars, let is now pure and
binds only inside its body. Vars have static types, global and local are
always mutable, local pure naturally immutable.
The var op specifies the kind of variable to take from, and the
individual variable sets are separate. This corresponds to BAP's
behavior where the kind of variable is part of the identifier.
Variable content storage has also been rewritten and RzILBag removed.
Plugins do not create register-based variables themselves anymore, but
they are derived from the register profile. However not all registers
may be bound and not all variables may be actual registers. The concrete
relations between an RzILVM and registers is described by an
RzILRegBinding object. It is simply a list of register names and
variables are created of the same names. When stepping with aezs, the
registers are synchronized automatically. From now on, aezv is primarily
useful for debugging, but interacting with emulation from the user side
should be done with ar.
* C352467: Free the heap allocated string after appending to `RzStrBuf`
* Remove unused variable `nofail`
* C352453: Free `fieldstr` after appending to `format`
* C350836: Free `name` before returning inside the loop
* C349252, C349231: Free `ta` when breaking halfway through the loop
* C349248: Free `pj` before breaking from switch statement
* C366622: Check result of `strtok` (`fcnname_aux`) for `NULL`
* Free `RzList` before returning from macro `SYNC_READ`
* Fixes Coverity issues 366625, 366624, 366623, 366621 and probably
a few others as well
* C366620: Check `arg` for `NULL` before dereferncing in `strchr`
* C366618: Cleanup `parse_lis` and use `rz_str_*` API instead of C `str` API
* Fix `SYNC_` macros in `cmd_regs.c` to no return prematurely
* C365952: Check `x` for `NULL` before dereferencing
* C365936: Use a wider integer type for the bitshift
* C365808: Fix double free of `real_type`
* C365805: Remove redundant `NULL` check for `path`