summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormidipix <writeonce@midipix.org>2019-09-15 19:12:33 +0000
committermidipix <writeonce@midipix.org>2019-09-16 07:07:34 +0000
commit0354669846be9be0d0353a6aa83297a1021c910d (patch)
tree0ed25c575bc3f8cf24cb4722565cf03d293ed5d4
parentb3b28e32623963e72eee2849dca3b57b0cc215f8 (diff)
downloadchainport-0354669846be9be0d0353a6aa83297a1021c910d.tar.bz2
chainport-0354669846be9be0d0353a6aa83297a1021c910d.tar.xz
mgdb: struct winnt_thread and friends: initial implementation and integration.
-rw-r--r--overlay/mgdb/gdb/amd64-winnt-regcache.c27
-rw-r--r--overlay/mgdb/gdb/i386-winnt-regcache.c8
-rw-r--r--overlay/mgdb/gdb/winnt-nat.c182
-rw-r--r--overlay/mgdb/gdb/winnt-nat.h57
4 files changed, 195 insertions, 79 deletions
diff --git a/overlay/mgdb/gdb/amd64-winnt-regcache.c b/overlay/mgdb/gdb/amd64-winnt-regcache.c
index 83a836c..7a1dab6 100644
--- a/overlay/mgdb/gdb/amd64-winnt-regcache.c
+++ b/overlay/mgdb/gdb/amd64-winnt-regcache.c
@@ -8,6 +8,7 @@
#include "osabi.h"
#include "regcache.h"
#include "amd64-tdep.h"
+#include "winnt-nat.h"
#include <signal.h>
#include <sys/debug.h>
@@ -61,23 +62,29 @@ static void amd64_winnt_supply_core_regs(
amd64_winnt_supply_reg(rcache,AMD64_EFLAGS_REGNUM,regctx->uc_eflags);
}
-int amd64_winnt_fetch_registers(
- int pfd, struct regcache * rcache,
- int regnum, pid_t tid)
+void amd64_winnt_fetch_registers(
+ struct regcache * rcache, int regnum,
+ struct winnt_thread * thread)
{
- int ret;
- mcontext_t regctx;
+ int pfd;
+ pid_t tid;
+ mcontext_t * regctx;
- if ((ret = __dbg_regs_fetch(pfd,tid,&regctx)) < 0)
- return ret;
+ pfd = thread->process->pfd;
+ tid = thread->tid;
+ regctx = &thread->regctx;
+
+ if (thread->regctx.uc_context_flags)
+ if (__dbg_regs_fetch(pfd,tid,regctx) < 0)
+ return;
if (regnum == AMD64_RIP_REGNUM) {
- amd64_winnt_supply_pc_regs(rcache,&regctx);
+ amd64_winnt_supply_pc_regs(rcache,regctx);
} else {
- amd64_winnt_supply_core_regs(rcache,&regctx);
+ amd64_winnt_supply_core_regs(rcache,regctx);
}
- return 0;
+ regctx->uc_context_flags = WINNT_THREAD_CONTEXT_READY;
}
#define AMD64_WINNT_INIT_REG_OFFSET(regnum,regmem) \
diff --git a/overlay/mgdb/gdb/i386-winnt-regcache.c b/overlay/mgdb/gdb/i386-winnt-regcache.c
index 1c2fb3e..7941fd3 100644
--- a/overlay/mgdb/gdb/i386-winnt-regcache.c
+++ b/overlay/mgdb/gdb/i386-winnt-regcache.c
@@ -8,15 +8,15 @@
#include "osabi.h"
#include "frame-unwind.h"
#include "i386-tdep.h"
+#include "winnt-nat.h"
struct regcache;
void i386_winnt_fetch_registers(
- int pfd, struct regcache * rcache,
- int regnum, pid_t tid)
+ struct regcache * rcache, int regnum,
+ struct winnt_thread * thread)
{
- (void)pfd;
(void)rcache;
(void)regnum;
- (void)tid;
+ (void)thread;
}
diff --git a/overlay/mgdb/gdb/winnt-nat.c b/overlay/mgdb/gdb/winnt-nat.c
index ed3fa53..a253426 100644
--- a/overlay/mgdb/gdb/winnt-nat.c
+++ b/overlay/mgdb/gdb/winnt-nat.c
@@ -15,6 +15,7 @@
#include "gdbthread.h"
#include "inf-child.h"
#include "xml-support.h"
+#include "winnt-nat.h"
#include "x86-nat.h"
#include <poll.h>
@@ -35,37 +36,11 @@
#define winnt_perror(msg,pid) \
error("%s(): %s (pid %d).",__FUNCTION__,msg,pid)
-#define WINNT_DR_STATE_DIRTY (0x1)
-
-struct regcache;
-
-struct winnt_process {
- int pfd;
- pid_t pid;
- pid_t syspid;
- pid_t systid;
- pid_t flags;
- int nmodules;
- struct __dbg_module_info * modules;
- struct __dbg_event event;
- char * solibs;
- uintptr_t dr_cache[8];
- uint32_t dr_state;
-};
-
static size_t pcnt;
static winnt_process * plist;
static char * outbuf;
static struct pe_driver_ctx * pe_dctx;
-extern void amd64_winnt_fetch_registers(
- int pfd, struct regcache * rcache,
- int regnum, pid_t tid);
-
-extern void i386_winnt_fetch_registers(
- int pfd, struct regcache * rcache,
- int regnum, pid_t tid);
-
static winnt_process * winnt_plist_expand (void)
{
struct winnt_process * pnew;
@@ -136,6 +111,19 @@ static void winnt_free_modules(struct winnt_process * pidinfo)
pidinfo->solibs = 0;
}
+static void winnt_free_threads(struct winnt_process * pidinfo)
+{
+ struct winnt_thread * thread;
+ struct winnt_thread * next;
+
+ next = pidinfo->threads;
+
+ for (thread=next; thread; thread=next) {
+ next = thread->next;
+ free(thread);
+ }
+}
+
static void winnt_plist_remove (pid_t pid)
{
struct winnt_process * pdbg;
@@ -144,6 +132,7 @@ static void winnt_plist_remove (pid_t pid)
for (pdbg=plist, pcap=&plist[pcnt]; pdbg<pcap; pdbg++) {
if (pdbg->pid == pid) {
winnt_free_modules(pdbg);
+ winnt_free_threads(pdbg);
pdbg->pid = 0;
pdbg->pfd = 0;
return;
@@ -315,43 +304,6 @@ static void winnt_get_modules(struct winnt_process * pidinfo)
mark += sprintf(mark,"</library-list>\n");
}
-static void winnt_fetch_registers (
- struct target_ops * t,
- struct regcache * rcache,
- int regnum)
-{
- pid_t pid;
- pid_t tid;
- struct winnt_process * pidinfo;
-
- pid = inferior_ptid.pid;
- tid = inferior_ptid.tid;
-
- if (!(pidinfo = winnt_process_record(pid)))
- winnt_perror("internal error: record not found",pid);
-
- if (sizeof(uintptr_t) == 8)
- amd64_winnt_fetch_registers(
- pidinfo->pfd,
- rcache,regnum,
- tid);
- else
- i386_winnt_fetch_registers(
- pidinfo->pfd,
- rcache,regnum,
- tid);
-}
-
-static void winnt_store_registers (
- struct target_ops * t,
- struct regcache * rcache,
- int regnum)
-{
- (void)t;
- (void)rcache;
- (void)regnum;
-}
-
ssize_t winnt_xfer_solibs(
struct winnt_process * pidinfo,
gdb_byte * readbuf,
@@ -495,6 +447,73 @@ static void winnt_xclose (struct target_ops * t)
{
}
+static void winnt_set_thread_context_state(struct winnt_thread * thread, int state)
+{
+ thread->regctx.uc_context_flags = state;
+}
+
+static void winnt_add_thread(int pfd, ptid_t ptid)
+{
+ pid_t pid;
+ struct winnt_process * pidinfo;
+ struct winnt_thread * thread;
+ mcontext_t * tctx;
+ uint32_t dr_rtm_mask = (1 << 16);
+
+ pid = ptid_get_pid(inferior_ptid);
+ pidinfo = winnt_process_record(pid);
+
+ if (!(thread = (struct winnt_thread *)calloc(1,sizeof(*thread))))
+ winnt_perror("could not allocate thread record.",pid);
+
+ if (__dbg_regs_fetch(pfd,ptid.tid,&thread->regctx) < 0)
+ winnt_perror("could not fetch registers for thread.",pid);
+
+ tctx = &thread->regctx;
+ tctx->uc_dr0 = pidinfo->dr_cache[0];
+ tctx->uc_dr1 = pidinfo->dr_cache[1];
+ tctx->uc_dr2 = pidinfo->dr_cache[2];
+ tctx->uc_dr3 = pidinfo->dr_cache[3];
+ tctx->uc_dr6 = dr_rtm_mask;
+ tctx->uc_dr7 = pidinfo->dr_cache[7];
+
+ winnt_set_thread_context_state(
+ thread,
+ WINNT_THREAD_CONTEXT_READY);
+
+ if (__dbg_regs_store(pfd,ptid.tid,tctx) < 0)
+ winnt_perror("could not store registers for thread.",pid);
+
+ thread->next = pidinfo->threads;
+ pidinfo->threads = thread;
+
+ thread->process = pidinfo;
+ thread->tid = ptid.tid;
+
+ add_thread(ptid);
+}
+
+static struct winnt_thread * winnt_get_thread(struct winnt_process * pidinfo, pid_t tid)
+{
+ struct winnt_thread * thread;
+
+ for (thread=pidinfo->threads; thread; thread=thread->next)
+ if (thread->tid == tid)
+ return thread;
+
+ return 0;
+}
+
+static struct winnt_thread * winnt_get_thread_from_ptid(ptid_t ptid)
+{
+ struct winnt_process * pidinfo;
+
+ if ((pidinfo = winnt_process_record(ptid.pid)))
+ return winnt_get_thread(pidinfo,ptid.tid);
+
+ return 0;
+}
+
static void winnt_respond (int pfd, struct __dbg_event * event, int response)
{
ptid_t ptid;
@@ -504,12 +523,12 @@ static void winnt_respond (int pfd, struct __dbg_event * event, int response)
switch (event->evttype) {
case __DBG_STATE_CREATE_PROCESS:
ptid = ptid_build(event->syspid,0,event->systid);
- add_thread(ptid);
+ winnt_add_thread(pfd,ptid);
break;
case __DBG_STATE_CREATE_THREAD:
ptid = ptid_build(event->syspid,0,event->systid);
- add_thread(ptid);
+ winnt_add_thread(pfd,ptid);
break;
default:
@@ -589,6 +608,39 @@ static void winnt_prepare (struct target_ops * t, pid_t pid, int pfd, int attach
}
}
+static void winnt_fetch_registers (
+ struct target_ops * t,
+ struct regcache * rcache,
+ int regnum)
+{
+ pid_t tid;
+ struct winnt_thread * thread;
+
+ tid = inferior_ptid.tid;
+
+ if (!(thread = winnt_get_thread_from_ptid(inferior_ptid)))
+ winnt_perror("internal error: thread record not found",tid);
+
+ if (sizeof(uintptr_t) == 8)
+ amd64_winnt_fetch_registers(
+ rcache,regnum,
+ thread);
+ else
+ i386_winnt_fetch_registers(
+ rcache,regnum,
+ thread);
+}
+
+static void winnt_store_registers (
+ struct target_ops * t,
+ struct regcache * rcache,
+ int regnum)
+{
+ (void)t;
+ (void)rcache;
+ (void)regnum;
+}
+
static void winnt_attach (struct target_ops * t, const char * args, int from_tty)
{
pid_t pid;
diff --git a/overlay/mgdb/gdb/winnt-nat.h b/overlay/mgdb/gdb/winnt-nat.h
new file mode 100644
index 0000000..c99d3f4
--- /dev/null
+++ b/overlay/mgdb/gdb/winnt-nat.h
@@ -0,0 +1,57 @@
+/***************************************************************/
+/* mgdb: midipix-specific bits for gdb */
+/* Copyright (C) 2019 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.MGDB. */
+/***************************************************************/
+
+#ifndef WINNT_NAT_H
+#define WINNT_NAT_H
+
+#include <unistd.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <sys/cmd.h>
+#include <sys/debug.h>
+
+#define WINNT_DR_STATE_DIRTY (0x1)
+
+#define WINNT_THREAD_CONTEXT_READY (0X0)
+#define WINNT_THREAD_CONTEXT_DIRTY (0Xffffffff)
+
+struct regcache;
+
+struct winnt_process;
+struct winnt_thread;
+
+struct winnt_process {
+ int pfd;
+ pid_t pid;
+ pid_t syspid;
+ pid_t systid;
+ pid_t flags;
+ int nmodules;
+ struct __dbg_module_info * modules;
+ struct __dbg_event event;
+ char * solibs;
+ uintptr_t dr_cache[8];
+ uint32_t dr_state;
+ struct winnt_thread * threads;
+};
+
+struct winnt_thread {
+ struct winnt_thread * next;
+ struct winnt_process * process;
+ pid_t tid;
+ uint32_t state;
+ mcontext_t regctx;
+};
+
+void amd64_winnt_fetch_registers(
+ struct regcache *, int regnum,
+ struct winnt_thread *);
+
+void i386_winnt_fetch_registers(
+ struct regcache *, int regnum,
+ struct winnt_thread *);
+
+#endif