From e8aae1bb96522e64a9cdf82be40b3cf71f2f711d Mon Sep 17 00:00:00 2001 From: midipix Date: Sun, 15 Sep 2019 21:16:44 +0000 Subject: mgdb; winnt_resume{_one|_all}(): initial implementation and integration. --- overlay/mgdb/gdb/winnt-nat.c | 91 +++++++++++++++++++++++++++++++++++++++++++- 1 file 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 #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]; pdbgpfd && (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) -- cgit v1.2.3