rizin/librz/debug/p/native/bt.c
GustavoLCR 53a7694631
Add support for Windows on ARM (#1502)
* Support building for Windows on ARM

* Fix usage of reserved function name on ARM
* Fix architecture dependent `CONTEXT` fields access

* Fixes for debugging on Windows on ARM

* Fix breakpoint behavior on windows on ARM
* Fix register profile when debugging
* Remove `drx` error message if not supported
* Add support for hardware breakpoints
* Disable support for hardware single-stepping

* Fix Windows Message breakpoints on ARM

* Fix software single-stepping on return instruction on ARM

* Consider link register as destination for return instructions

* Fix setting debug bits to 16

* Rename `r12` to `ip` for windows arm register profile

* Remove debug bits hardcoding on windows

* Add 32bit registers to Windows ARM64 register profile

* Fix software step breakpoint alignment when entering thumb mode

* Define `RZ_TEST_ARCH` for `arm` and `arm64`

* Use `StackWalk64` API for backtracing on Windows

* Fix software single-stepping ARM in thumb mode

* Sync `asm.bits` with debugger

* Cleanup windows_debug.c

* Add SPDX for cross-arm64-windows.txt

* Add floating point control register flags

* Fix Windows Arm register profile alignment

* Keep `drx` warning
2021-11-24 20:13:42 +08:00

90 lines
1.9 KiB
C

// SPDX-FileCopyrightText: 2009-2018 pancake <pancake@nopcode.org>
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_analysis.h>
#if __WINDOWS__
#include "bt/windows-all.c"
#endif
#include "bt/generic-x86.c"
#include "bt/generic-x64.c"
#include "bt/fuzzy-all.c"
typedef RzList *(*RzDebugFrameCallback)(RzDebug *dbg, ut64 at);
static void prepend_current_pc(RzDebug *dbg, RzList *list) {
RzDebugFrame *frame;
const char *pcname;
if (list) {
pcname = rz_reg_get_name(dbg->reg, RZ_REG_NAME_PC);
if (pcname) {
ut64 addr = rz_reg_getv(dbg->reg, pcname);
frame = RZ_NEW0(RzDebugFrame);
frame->addr = addr;
frame->size = 0;
rz_list_prepend(list, frame);
}
}
}
#if HAVE_PTRACE
struct frames_proxy_args {
RzDebugFrameCallback cb;
RzDebug *dbg;
ut64 at;
};
static void *backtrace_proxy(void *user) {
struct frames_proxy_args *args = user;
if (args->cb) {
return args->cb(args->dbg, args->at);
}
return NULL;
}
#endif
static RzList *rz_debug_native_frames(RzDebug *dbg, ut64 at) {
RzDebugFrameCallback cb = NULL;
if (dbg->btalgo) {
if (!strcmp(dbg->btalgo, "fuzzy")) {
cb = backtrace_fuzzy;
} else if (!strcmp(dbg->btalgo, "analysis")) {
if (!strcmp(dbg->arch, "x86")) {
if (dbg->bits == RZ_SYS_BITS_64) {
cb = backtrace_x86_64_analysis;
} else {
cb = backtrace_x86_32_analysis;
}
} else {
eprintf("Analysis backtrace not available for current architecture (%s)\n", dbg->arch);
return NULL;
}
}
}
if (!cb) {
#if __WINDOWS__
cb = backtrace_windows;
#else
if (dbg->bits == RZ_SYS_BITS_64) {
cb = backtrace_x86_64;
} else {
cb = backtrace_x86_32;
}
#endif
}
RzList *list;
if (dbg->btalgo && !strcmp(dbg->btalgo, "trace")) {
list = rz_list_clone(dbg->call_frames);
} else {
#if HAVE_PTRACE
struct frames_proxy_args args = { cb, dbg, at };
list = rz_debug_ptrace_func(dbg, backtrace_proxy, &args);
#else
list = cb(dbg, at);
#endif
}
prepend_current_pc(dbg, list);
return list;
}