librz/debug: add NetBSD debug tests and fix errors (#5208)
* Fix netbsd-x86_64 register profile * Fix native_wait in netbsd.c * Fix netbsd attach to show error * Add netbsd-x64 debug tests
This commit is contained in:
parent
9f17373515
commit
7117ba75ea
6 changed files with 242 additions and 39 deletions
|
|
@ -14,6 +14,8 @@
|
|||
#define RZ_TEST_OS "darwin"
|
||||
#elif __WINDOWS__
|
||||
#define RZ_TEST_OS "windows"
|
||||
#elif __NetBSD__
|
||||
#define RZ_TEST_OS "netbsd"
|
||||
#else
|
||||
#define RZ_TEST_OS "unknown"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -723,7 +723,6 @@ RZ_API RzDebugReasonType rz_debug_wait(RzDebug *dbg, RzBreakpointItem **bp) {
|
|||
rz_debug_stop(dbg);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* propagate errors from the plugin */
|
||||
if (reason == RZ_DEBUG_REASON_ERROR) {
|
||||
return RZ_DEBUG_REASON_ERROR;
|
||||
|
|
|
|||
|
|
@ -641,10 +641,8 @@ static int get_rz_status(int stat) {
|
|||
return RZ_DBG_PROC_DEAD;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
RzList *bsd_thread_list(RzDebug *dbg, int pid, RzList *list) {
|
||||
#if __KFBSD__
|
||||
static RzList *kfbsd_thread_list(RzDebug *dbg, int pid, RzList *list) {
|
||||
int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID | KERN_PROC_INC_THREAD, pid };
|
||||
struct kinfo_proc *kp;
|
||||
size_t len = 0;
|
||||
|
|
@ -666,19 +664,93 @@ RzList *bsd_thread_list(RzDebug *dbg, int pid, RzList *list) {
|
|||
|
||||
max = len / sizeof(*kp);
|
||||
for (i = 0; i < max; i++) {
|
||||
RzDebugPid *pid_info;
|
||||
int pid_stat;
|
||||
int pid_stat = get_rz_status(kp[i].ki_stat);
|
||||
|
||||
pid_stat = get_rz_status(kp[i].ki_stat);
|
||||
pid_info = rz_debug_pid_new(kp[i].ki_comm, kp[i].ki_tid,
|
||||
RzDebugPid *pid_info = rz_debug_pid_new(kp[i].ki_comm, kp[i].ki_tid,
|
||||
kp[i].ki_uid, pid_stat, (ut64)kp[i].ki_wchan);
|
||||
|
||||
rz_list_append(list, pid_info);
|
||||
}
|
||||
|
||||
free(kp);
|
||||
return list;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if __NetBSD__
|
||||
static int get_rz_status(int stat) {
|
||||
switch (stat) {
|
||||
case LSRUN:
|
||||
case LSONPROC:
|
||||
case LSIDL:
|
||||
return RZ_DBG_PROC_RUN;
|
||||
case LSSTOP:
|
||||
return RZ_DBG_PROC_STOP;
|
||||
case LSZOMB:
|
||||
return RZ_DBG_PROC_ZOMBIE;
|
||||
case LSSLEEP:
|
||||
return RZ_DBG_PROC_SLEEP;
|
||||
case LSSUSPENDED:
|
||||
return RZ_DBG_PROC_STOP;
|
||||
default:
|
||||
return RZ_DBG_PROC_DEAD;
|
||||
}
|
||||
}
|
||||
|
||||
static RzList *netbsd_thread_list(RzDebug *dbg, int pid, RzList *list) {
|
||||
int mib[6] = { CTL_KERN, KERN_PROC2, KERN_PROC_PID, pid, sizeof(struct kinfo_proc2), 0 };
|
||||
struct kinfo_proc2 *kp;
|
||||
size_t len = 0;
|
||||
size_t max;
|
||||
int i = 0;
|
||||
|
||||
if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1) {
|
||||
rz_list_free(list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len += sizeof(*kp) + len / 10;
|
||||
kp = malloc(len);
|
||||
if (!kp) {
|
||||
rz_list_free(list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mib[5] = len / sizeof(struct kinfo_proc2);
|
||||
|
||||
if (sysctl(mib, 6, kp, &len, NULL, 0) == -1) {
|
||||
free(kp);
|
||||
rz_list_free(list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
max = len / sizeof(*kp);
|
||||
|
||||
for (i = 0; i < max; i++) {
|
||||
int pid_stat = get_rz_status(kp[i].p_stat);
|
||||
|
||||
RzDebugPid *pid_info = rz_debug_pid_new(kp[i].p_comm, kp[i].p_pid,
|
||||
kp[i].p_uid, pid_stat, (ut64)kp[i].p_wchan);
|
||||
|
||||
if (pid_info) {
|
||||
rz_list_append(list, pid_info);
|
||||
}
|
||||
}
|
||||
|
||||
free(kp);
|
||||
return list;
|
||||
}
|
||||
#endif
|
||||
|
||||
RzList *bsd_thread_list(RzDebug *dbg, int pid, RzList *list) {
|
||||
#if __KFBSD__
|
||||
RzList *thread_list = kfbsd_thread_list(dbg, pid, list);
|
||||
return thread_list;
|
||||
#elif __NetBSD__
|
||||
RzList *thread_list = netbsd_thread_list(dbg, pid, list);
|
||||
return thread_list;
|
||||
#else
|
||||
eprintf("bsd_thread_list unsupported on this platform\n");
|
||||
RZ_LOG_ERROR("bsd_thread_list unsupported on this platform\n");
|
||||
rz_list_free(list);
|
||||
return NULL;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-FileCopyrightText: 2009-2019 pancake <pancake@nopcode.org>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_util/rz_log.h>
|
||||
#include <errno.h>
|
||||
#if !defined(__HAIKU__) && !defined(__sun)
|
||||
#include <sys/ptrace.h>
|
||||
|
|
@ -40,11 +41,35 @@ static bool rz_debug_native_step(RzDebug *dbg) {
|
|||
return true;
|
||||
}
|
||||
|
||||
int match_pid(const void *pid_o, const void *th_o, void *user) {
|
||||
int pid = *(int *)pid_o;
|
||||
RzDebugPid *th = (RzDebugPid *)th_o;
|
||||
return (pid == th->pid) ? 0 : 1;
|
||||
}
|
||||
|
||||
static RZ_OWN RzList /*<RzDebugPid *>*/ *get_pid_thread_list(RZ_NONNULL RzDebug *dbg, int main_pid) {
|
||||
rz_return_val_if_fail(dbg, NULL);
|
||||
RzList *list = rz_list_new();
|
||||
if (!list) {
|
||||
RZ_LOG_ERROR("Cannot create thread list\n");
|
||||
return NULL;
|
||||
}
|
||||
list = bsd_thread_list(dbg, main_pid, list);
|
||||
dbg->main_pid = main_pid;
|
||||
return list;
|
||||
}
|
||||
|
||||
static int rz_debug_native_attach(RzDebug *dbg, int pid) {
|
||||
int ret = ptrace(PTRACE_ATTACH, pid, 0, 0);
|
||||
if (ret != -1) {
|
||||
eprintf("Trying to attach to %d\n", pid);
|
||||
perror("ptrace (PT_ATTACH)");
|
||||
if (!dbg->threads) {
|
||||
dbg->threads = get_pid_thread_list(dbg, pid);
|
||||
return pid;
|
||||
}
|
||||
if (!rz_list_find(dbg->threads, &pid, &match_pid, NULL)) {
|
||||
int ret = ptrace(PTRACE_ATTACH, pid, 0, 0);
|
||||
if (ret == -1) {
|
||||
RZ_LOG_ERROR("Trying to attach to %d\n", pid);
|
||||
perror("ptrace (PT_ATTACH)");
|
||||
}
|
||||
}
|
||||
return pid;
|
||||
}
|
||||
|
|
@ -77,17 +102,14 @@ static RzDebugReasonType rz_debug_native_wait(RzDebug *dbg, int pid) {
|
|||
RzDebugReasonType reason = RZ_DEBUG_REASON_UNKNOWN;
|
||||
|
||||
if (pid == -1) {
|
||||
eprintf("ERROR: rz_debug_native_wait called with pid -1\n");
|
||||
RZ_LOG_ERROR("rz_debug_native_wait called with pid -1\n");
|
||||
return RZ_DEBUG_REASON_ERROR;
|
||||
}
|
||||
int status = -1;
|
||||
#ifdef WAIT_ON_ALL_CHILDREN
|
||||
int ret = waitpid(-1, &status, WAITPID_FLAGS);
|
||||
#else
|
||||
int ret = waitpid(-1, &status, 0);
|
||||
if (ret != -1) {
|
||||
reason = RZ_DEBUG_REASON_TRAP;
|
||||
}
|
||||
#else
|
||||
int ret = waitpid(pid, &status, 0);
|
||||
#endif
|
||||
if (ret == -1) {
|
||||
rz_sys_perror("waitpid");
|
||||
|
|
@ -101,17 +123,16 @@ static RzDebugReasonType rz_debug_native_wait(RzDebug *dbg, int pid) {
|
|||
/* we don't know what to do yet, let's try harder to figure it out. */
|
||||
if (reason == RZ_DEBUG_REASON_UNKNOWN) {
|
||||
if (WIFEXITED(status)) {
|
||||
eprintf("child exited with status %d\n", WEXITSTATUS(status));
|
||||
if (dbg->pid == pid) {
|
||||
RZ_LOG_WARN("(%d) Process exited with status=0x%x\n", pid, WEXITSTATUS(status));
|
||||
} else {
|
||||
RZ_LOG_WARN("(%d) Thread exited with status=0x%x\n", pid, WEXITSTATUS(status));
|
||||
}
|
||||
reason = RZ_DEBUG_REASON_DEAD;
|
||||
} else if (WIFSIGNALED(status)) {
|
||||
eprintf("child received signal %d\n", WTERMSIG(status));
|
||||
reason = RZ_DEBUG_REASON_SIGNAL;
|
||||
} else if (WIFSTOPPED(status)) {
|
||||
if (WSTOPSIG(status) != SIGTRAP &&
|
||||
WSTOPSIG(status) != SIGSTOP) {
|
||||
eprintf("Child stopped with signal %d\n", WSTOPSIG(status));
|
||||
}
|
||||
|
||||
/* the ptrace documentation says GETSIGINFO is only necessary for
|
||||
* differentiating the various stops.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ return rz_str_dup(
|
|||
"=A3 rcx\n"
|
||||
"=A4 r8\n"
|
||||
"=A5 r9\n"
|
||||
"# no profile defined for x86-64\n"
|
||||
"gpr rdi .64 0 0\n"
|
||||
"gpr edi .32 0 0\n"
|
||||
"gpr di .16 0 0\n"
|
||||
|
|
@ -72,21 +71,23 @@ return rz_str_dup(
|
|||
"gpr eax .32 112 0\n"
|
||||
"gpr ax .16 112 0\n"
|
||||
"gpr al .8 112 0\n"
|
||||
"gpr rsp .64 120 0\n"
|
||||
"gpr esp .32 120 0\n"
|
||||
"gpr sp .16 120 0\n"
|
||||
"gpr spl .8 120 0\n"
|
||||
"gpr rip .64 128 0\n"
|
||||
"gpr rflags .64 136 0 c1p.a.zstido.n.rv\n"
|
||||
"seg cs .64 144 0\n"
|
||||
"seg ss .64 152 0\n"
|
||||
"seg ds .64 160 0\n"
|
||||
"seg es .64 168 0\n"
|
||||
"seg fs .64 176 0\n"
|
||||
"seg gs .64 184 0\n"
|
||||
"seg gs .64 120 0\n"
|
||||
"seg fs .64 128 0\n"
|
||||
"seg es .64 136 0\n"
|
||||
"seg ds .64 144 0\n"
|
||||
"gpr trapno .64 152 0\n"
|
||||
"gpr err .64 160 0\n"
|
||||
"gpr rip .64 168 0\n"
|
||||
"seg cs .64 176 0\n"
|
||||
"gpr rflags .64 184 0 c1p.a.zstido.n.rv\n"
|
||||
"gpr rsp .64 192 0\n"
|
||||
"gpr esp .32 192 0\n"
|
||||
"gpr sp .16 192 0\n"
|
||||
"gpr spl .8 192 0\n"
|
||||
"seg ss .64 200 0\n"
|
||||
"drx dr0 .32 0 0\n"
|
||||
"drx dr1 .32 4 0\n"
|
||||
"drx dr2 .32 8 0\n"
|
||||
"drx dr3 .32 12 0\n"
|
||||
"drx dr6 .32 24 0\n"
|
||||
"drx dr7 .32 28 0\n");
|
||||
"drx dr7 .32 28 0\n");
|
||||
108
test/db/archos/netbsd-x64/dbg
Normal file
108
test/db/archos/netbsd-x64/dbg
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
NAME=dcu + read
|
||||
FILE=bins/elf/netbsd-hello-x64
|
||||
ARGS=-d
|
||||
CMDS=<<EOF
|
||||
dcu main
|
||||
pi 5
|
||||
dc
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
mov edi, str.Hello_World
|
||||
call sym.imp.puts
|
||||
mov eax, 0x00
|
||||
Hello World
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=maps
|
||||
FILE=bins/elf/netbsd-hello-x64
|
||||
ARGS=-d
|
||||
CMDS=<<EOF
|
||||
dm~hello~[3-9]
|
||||
dc
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
- usr 4K s r-x 1581273 /home/build/rizin-testbins/elf/netbsd-hello-x64
|
||||
Hello World
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=step and check pc
|
||||
FILE=bins/elf/netbsd-calculate-x64
|
||||
ARGS=-d
|
||||
CMDS=<<EOF
|
||||
dcu main
|
||||
5 ds
|
||||
dr rip
|
||||
ds
|
||||
dr rip
|
||||
dc
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
rip = 0x0000000000400984
|
||||
rip = 0x0000000000400988
|
||||
Result = 42
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=write gpr
|
||||
FILE=bins/elf/netbsd-calculate-x64
|
||||
ARGS=-d
|
||||
CMDS=<<EOF
|
||||
db @ main + 64
|
||||
dc
|
||||
dr rax
|
||||
dr rax = 1337
|
||||
dr rax
|
||||
dc
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
rax = 0x0000000000000028
|
||||
rax = 0x0000000000000539
|
||||
Result = 1339
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=Signal handling
|
||||
FILE=bins/elf/netbsd-calculate-x64
|
||||
ARGS=-d
|
||||
CMDS=<<EOF
|
||||
dkl~SIGTERM
|
||||
dko 15 skip
|
||||
dkl~SIGTERM
|
||||
dko 15 reset
|
||||
dkl~SIGTERM
|
||||
dk 15
|
||||
dc
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
15 SIGTERM
|
||||
15 SIGTERM skip
|
||||
15 SIGTERM
|
||||
[+] signal 15 aka SIGTERM received 0
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=Step and Step over
|
||||
FILE=bins/elf/netbsd_basic_test-x64
|
||||
ARGS=-d
|
||||
CMDS=<<EOF
|
||||
db @ main + 73
|
||||
dc
|
||||
ds 3
|
||||
dr rax
|
||||
dr rdx
|
||||
dso
|
||||
dr rax
|
||||
dr rdx
|
||||
dc
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
rax = 0x0000000000000034
|
||||
rdx = 0x00000000000000c8
|
||||
rax = 0x00000000000000fc
|
||||
rdx = 0x0000000000000034
|
||||
EOF
|
||||
RUN
|
||||
Loading…
Reference in a new issue