summaryrefslogtreecommitdiff
path: root/overlay/mgdb/gdb/winnt-nat.c
diff options
context:
space:
mode:
Diffstat (limited to 'overlay/mgdb/gdb/winnt-nat.c')
-rw-r--r--overlay/mgdb/gdb/winnt-nat.c182
1 files changed, 117 insertions, 65 deletions
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;