summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormidipix <writeonce@midipix.org>2019-09-15 21:16:44 +0000
committermidipix <writeonce@midipix.org>2019-09-16 07:07:34 +0000
commite8aae1bb96522e64a9cdf82be40b3cf71f2f711d (patch)
tree1fd16500e1997a9d861ae5c651e9da788c445203
parent726ed01920804bc3cce70bb01c62588945768469 (diff)
downloadchainport-e8aae1bb96522e64a9cdf82be40b3cf71f2f711d.tar.bz2
chainport-e8aae1bb96522e64a9cdf82be40b3cf71f2f711d.tar.xz
mgdb; winnt_resume{_one|_all}(): initial implementation and integration.
-rw-r--r--overlay/mgdb/gdb/winnt-nat.c91
1 files changed, 89 insertions, 2 deletions
diff --git a/overlay/mgdb/gdb/winnt-nat.c b/overlay/mgdb/gdb/winnt-nat.c
index 9f25f4e..e5d054a 100644
--- a/overlay/mgdb/gdb/winnt-nat.c
+++ b/overlay/mgdb/gdb/winnt-nat.c
@@ -29,6 +29,8 @@
#include <perk/perk.h>
#define WINNT_OUTBUF_SIZE 65536
+#define X86_DR_RTM_MASK (1 << 16)
+#define X86_EFLAGS_TRACE (1 << 8)
#define winnt_error(msg) \
error("%s(): %s.",__FUNCTION__,msg)
@@ -458,7 +460,6 @@ static void winnt_add_thread(int pfd, ptid_t ptid)
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);
@@ -474,7 +475,7 @@ static void winnt_add_thread(int pfd, ptid_t ptid)
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_dr6 = X86_DR_RTM_MASK;
tctx->uc_dr7 = pidinfo->dr_cache[7];
winnt_set_thread_context_state(
@@ -804,11 +805,97 @@ static ptid_t winnt_wait(
return inferior_ptid;
}
+static void winnt_resume_one(ptid_t ptid, int step, enum gdb_signal sig)
+{
+ pid_t tid;
+ struct winnt_process * process;
+ struct winnt_thread * thread;
+ mcontext_t * tctx;
+ int response;
+
+ if ((tid = inferior_ptid.tid) <= 0)
+ if ((process = winnt_process_record(ptid.pid)))
+ tid = process->systid;
+
+ if (!(thread = winnt_get_thread_from_ptid(ptid)))
+ winnt_perror("internal error: thread record not found",tid);
+
+ process = thread->process;
+ tctx = &thread->regctx;
+
+ if (process->dr_state) {
+ tctx->uc_dr0 = process->dr_cache[0];
+ tctx->uc_dr1 = process->dr_cache[1];
+ tctx->uc_dr2 = process->dr_cache[2];
+ tctx->uc_dr3 = process->dr_cache[3];
+ tctx->uc_dr6 = X86_DR_RTM_MASK;
+ tctx->uc_dr7 = process->dr_cache[7];
+ }
+
+ if (step && !(tctx->uc_eflags & X86_EFLAGS_TRACE)) {
+ tctx->uc_eflags |= X86_EFLAGS_TRACE;
+ winnt_set_thread_context_state(
+ thread,
+ WINNT_THREAD_CONTEXT_DIRTY);
+ }
+
+ if (process->dr_state || tctx->uc_context_flags)
+ __dbg_regs_store(process->pfd,tid,tctx);
+
+ if (tid == process->event.systid) {
+ switch (process->event.evttype) {
+ case __DBG_STATE_EXCEPTION:
+ response = __DBG_RESPONSE_EXCEPTION_NOT_HANDLED;
+ break;
+
+ default:
+ response = __DBG_RESPONSE_CONTINUE;
+ break;
+ }
+
+ process->event.eresponse = response;
+
+ __dbg_event_respond(
+ process->pfd,
+ &process->event);
+
+ process->event.syspid = 0;
+ process->event.systid = 0;
+ }
+}
+
+static void winnt_resume_all(int step, enum gdb_signal sig)
+{
+ struct winnt_process * pdbg;
+ struct winnt_process * pcap;
+ struct winnt_thread * thread;
+ ptid_t ptid;
+
+ for (pdbg=plist, pcap=&plist[pcnt]; pdbg<pcap; pdbg++) {
+ if (pdbg->pfd && (thread = pdbg->threads)) {
+ for (; thread; ) {
+ ptid.pid = pdbg->syspid;
+ ptid.tid = thread->tid;
+ ptid.lwp = 0;
+
+ winnt_resume_one(ptid,step,sig);
+
+ thread = thread->next;
+ }
+ }
+ }
+}
+
static void winnt_resume (
struct target_ops * t,
ptid_t ptid, int step,
enum gdb_signal sig)
{
+ target_terminal_inferior();
+
+ ptid_equal(ptid,minus_one_ptid)
+ ? winnt_resume_all(step,sig)
+ : winnt_resume_one(ptid,step,sig);
}
static void winnt_kill (struct target_ops * t)