If a function calls 'rz_cons_break_push()' but never calls 'rz_cons_break_pop()' before return,
the stack count of 'RzConsContext->break_stack' contains too many elements (each time one too much).
This in turn will lead to not resetting 'RzConsContext->breaked' flag.
Because the flag is only set to false, if 'rz_stack_is_empty(context->break_stack) == true'
(in 'rz_cons_context_break_push()').
This wasn't a problem so far, because 'RzConsContext->breaked' is simply never set to true
(exceptions are some timeout cases as far as I can see).
Also these cases when 'rz_cons_break_pop()' was forgetten to be called, were edge error cases.
So not often hit.
But if Rizin is usd by Cutter 'RzConsContext->breaked' is set to 'true',
if an `AnalysisTask` interrupt is handled (in 'AnalysisTask::interrupt()').
This interrupt is triggered for example, when the introduction dialog is closed
and the main Cutter window opens (after the optional 'aaa').
Now, if the binary file was analysed with 'aaa', and a lot of error cases were hit,
those error cases sometimes never called 'rz_cons_break_pop()' before returning from their function.
Although, of course, they should have to the `RzConsContext->break_stack` is in a proper state.
This means, when the main Cutter window opens binary files which trigger many error edge cases,
the `RzConsContext->break_stack` is not empty
(because of the not executed 'rz_cons_break_pop()').
This also means, that the last thing done, was setting 'RzConsContext->breaked = true'
(by 'AnalysisTask::interrupt()').
If Cutter wants to show some disassembly, it calls 'rz_core_print_disasm()' which checks
'RzConsContext == false' via 'rz_cons_is_breaked()'. This condition is never true, because
the flag was not reset to `false` because the stack was never empty.
So it returns before anything was disassembled.
Hence Cutter gets no disassembly text.
Fixes https://github.com/rizinorg/cutter/issues/2552
Fixes https://github.com/rizinorg/cutter/issues/3275
* librz: do not duplicate plugins
Plugins structures are statically defined at the file scope and not
dynamically allocated. Plugins should not allocate them either as
RzLibPlugin keeps a reference to them anyway.
* cmd: Fix summary of few "L" sub-commands
* util: start decluttering plugins handling
- Add Doxygen docs
- Remove unused API functions and make others internal only
- Use RzLibType enum for plugin type instead of int
* util: move dlopen/dlsym/dlclose to rz_sys
* util: make rz_lib_open/close return bool
* util: simplify rz_lib_add_handler and rz_lib_open*
* libs: implement rz_*_plugin_del to remove a plugin
* core: remove commands from RzCmd when removing plugins
* librz: call plugins 'fini' method when removing a plugin
* core/cmd: do not fail if the hashmap removal fails
When removing a group command, the inner command might have the same
name, thus it would result in trying to remove the same name twice.
Ignore it, as it is fine.
* librz: make RzCrypto plugins handling like the others
* librz/crypto: add rz_crypto_reset and use it
* librz: allocate the plugin structures before adding them
dbg->bits was checked in reg/windows_arm64.h, but when returning the reg
profile from the dmp plugin, this (deprecated) variable held the host
value when 64 was expected.
So it is better to move this check to the respective points where the
profile file is included.
RzDebug.bits often has nonsensical contents set from all kinds of
places. Specifically, when debugging fat binaries on arm64, it had a
value not matching the debuggee when the reg profile was loaded,
resulting in the arm32 profile being used.
The right way to determine the profile is to do it after attach, when
the cpu type of the debuggee is known.
Adds /*<type>*/ comments and a linter check from rz-bindgen to enforce
their existence and consistency
Also includes the following fixes made when adding the annotations:
* removed unused intern_table arguments in pyc_dis.c, pyc_dis.h, asm_pyc.c
* removed unused classes argument from place_nodes in agraph.c
* removed unused recurse and recurse_bb functions in canalysis.c
* removed unused vars field from RzPrint struct
* removed unused RzAnalysisType* structs from rz_analysis.h
* removed unused list field from RzEgg struct
* fixed bug in bp_plugin.c where duplication-checking logic iterates over the wrong list
* removed unused q_regs field from RzDebug struct
* removed unused backtrace field from RzDebugPlugin struct
* removed unused classes_list field from RzBinNXOObj struct
* removed unused methods_list and classes_list fields from RzBinZimgObj struct
Duplicated code for pkg-config and cmake configuration is avoided by
letting every rizin module register itself in a global dictionary
called "modules" which is then iterated in one place to perform any
shared logic, inspired by how qemu handles multiple targets in its meson
build system.
This is an almost pure refactor, so the resulting .pc/.cmake files
should be identical with the following exceptions:
- rz_reg.pc does not have plugindir anymore as rz_reg has no plugins.
- Some other modules have their dependencies in .pc files altered to be
consistent with cmake.
ARM_THREAD_STATE64 fetches arm_thread_state64_t but our struct was
arm_unified_thread_state_t, which adds a header. The pc in the register
profile was hacked to account for the shift, but all the x-regs were
not, so x7 had the value of x8 for example. Now we just use the specific
state for 32 or 64.
This fixes basic single-stepping on macOS/arm64.
dbg->bits is affected by all kinds of things going on in rizin, in
particular it currently randomly switches to 16 when calling pd during
an arm64 debug session, causing the stepping code to break.
We now fetch the cpu type of the process once during attach, similar to
how lldb does it. They also use 0 for the "invalid" value, so we do that
as well.
This fixes the following minor issues:
* Errors like "Cannot create flag (...) because there is already (...)
flag" during debug startup
* Unnecessary seeks during .dm* causing io reads and e.g. delays of up
to 5s on x86 macOS during debug startup
* Flags are now created in the "maps" flagspace, rather than globally,
making them easier to clean up later
* Flags now have the same size as the maps and not +1
Getting the thread list with task_threads() allocates a mapping in the
caller's memory that should then be freed with vm_deallocate() later.
However rz_xnu_get_cur_thread() was passing the debuggee's task to the
deallocate rather than its own, meaning the thread list would probably
leak and the debuggee's maps would get broken if there was something at
that address.
ptrace with PT_ATTACHEXC will send a SIGSTOP to the process, which we then
sometimes received in the first mach_msg loop while waiting for hitting a
breakpoint, when having been already attached at this point.
See also bsd/kern/mach_process.c:287 in xnu-8020.121.3.
Correct attaching works like this, in exactly this order:
* posix_spawn the process with POSIX_SPAWN_START_SUSPENDED
* set up the Mach port for receiving exceptions
* ptrace(PT_ATTACHEXC) -> sends SIGSTOP
* wait on the Mach port until receiving the SIGSTOP msg
* call task_suspend
* reply to the msg
Then we have a beautiful process suspended right at the start in dyld.
* Drop sdb_json in `librz/cons/grep.c`
* Do not print the JSON key in grep
* Use proper JSON paths in tests
* Use signed number in case of RzJson in tests
* Do not add quotes for sole RZ_JSON_STRING
* Ignore resent packets
* Resend packet if we didn't get an ACK
* Break if Ctrl-C is pressed
* Always wait for a state change packet in debug event wait function
Entire files are now avoided to be built by checking in meson rather
than using #if DEBUGGER. This now also includes bsd_debug.c, which
is currently slightly broken on OpenBSD/sparc64 and caused compile
errors even with -Ddebugger=false.
If the kernel/system where Rizin is currently run does not support
ptrace(PTRACE_GETREGSET, ..., NT_X86_XSTATE, ...), ENODEV is returned by
the kernel. In such cases, we print the error message once and never
execute the ptrace call again, assuming it is not supported.
Signed-off-by: Riccardo Schirone <sirmy15@gmail.com>
Although the reg profile was not really used yet it will be relevant for the RZIL uplifting.
Introduces:
* Double/quadruple registers now properly overlap with their counterparts.
* Registers have correct types assigned (vec, ctr, sys etc. Before, all regs were of type gbr)
* Consistent register names (asm name style: c3:2, r31 etc, alias style: lc1:sa1, lr etc.)
* Adds _tmp registers in the profile. Later used by uplifted instructions (think of .new registers).