summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormidipix <writeonce@midipix.org>2019-08-31 19:59:36 +0000
committermidipix <writeonce@midipix.org>2019-08-31 19:59:36 +0000
commit89d5544644d3e517568ae1dcacb13ad6ef133c6f (patch)
treecd6991b110ff2d7b925440d44f46cfaae037e25c
parent7333060bb8477a09326b469722543520eeea3a6d (diff)
downloadchainport-89d5544644d3e517568ae1dcacb13ad6ef133c6f.tar.bz2
chainport-89d5544644d3e517568ae1dcacb13ad6ef133c6f.tar.xz
gdb: midipix-specific bits: introduced gdb/winnt-nat.c.
-rw-r--r--overlay/mgdb/gdb/winnt-nat.c284
1 files changed, 284 insertions, 0 deletions
diff --git a/overlay/mgdb/gdb/winnt-nat.c b/overlay/mgdb/gdb/winnt-nat.c
new file mode 100644
index 0000000..d56805a
--- /dev/null
+++ b/overlay/mgdb/gdb/winnt-nat.c
@@ -0,0 +1,284 @@
+#include "defs.h"
+#include "osabi.h"
+#include "config.h"
+#include "target.h"
+#include "utils.h"
+#include "inferior.h"
+#include "inf-child.h"
+#include "x86-nat.h"
+
+#include <poll.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <pthread.h>
+#include <sys/debug.h>
+
+#define winnt_error(msg) \
+ error("%s(): %s.",__FUNCTION__,msg)
+
+#define winnt_perror(msg,pid) \
+ error("%s(): %s (pid %d).",__FUNCTION__,msg,pid)
+
+struct winnt_process {
+ int pfd;
+ pid_t pid;
+};
+
+static size_t pcnt;
+static winnt_process * plist;
+
+static winnt_process * winnt_plist_expand (void)
+{
+ struct winnt_process * pnew;
+ struct winnt_process * pold;
+ size_t idx;
+
+ if (!(pnew = (struct winnt_process *)calloc(pcnt+32, sizeof(*pnew))))
+ return 0;
+
+ memcpy(
+ pnew,plist,
+ pcnt*sizeof(*plist));
+
+ pold = plist;
+ plist = pnew;
+ pcnt += 32;
+
+ free(pold);
+
+ return pnew;
+}
+
+static int winnt_plist_add (pid_t pid, int pfd)
+{
+ struct winnt_process * pdbg;
+ struct winnt_process * pcap;
+
+ for (pdbg=plist, pcap=&plist[pcnt]; pdbg<pcap; pdbg++) {
+ if (!pdbg->pid) {
+ pdbg->pid = pid;
+ pdbg->pfd = pfd;
+ return 0;
+ }
+ }
+
+ return winnt_plist_expand()
+ ? winnt_plist_add(pid,pfd)
+ : -1;
+}
+
+static void winnt_plist_remove (pid_t pid)
+{
+ struct winnt_process * pdbg;
+ struct winnt_process * pcap;
+
+ for (pdbg=plist, pcap=&plist[pcnt]; pdbg<pcap; pdbg++) {
+ if (pdbg->pid == pid) {
+ pdbg->pid = 0;
+ return;
+ }
+ }
+}
+
+static int winnt_pfd_from_pid (pid_t pid)
+{
+ winnt_process * pdbg;
+ winnt_process * pcap;
+
+ for (pdbg=plist, pcap=&plist[pcnt]; pdbg<pcap; pdbg++)
+ if (pdbg->pid == pid)
+ return pdbg->pfd;
+
+ return -1;
+}
+
+static nfds_t winnt_poll_one_init (struct pollfd * pfds, pid_t pid)
+{
+ winnt_process * pdbg;
+ winnt_process * pcap;
+
+ for (pdbg=plist, pcap=&plist[pcnt]; pdbg<pcap; pdbg++) {
+ if (pdbg->pid == pid) {
+ pfds->fd = pdbg->pfd;
+ pfds->events = POLLIN;
+
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static nfds_t winnt_poll_init (struct pollfd * pfds)
+{
+ winnt_process * pdbg;
+ winnt_process * pcap;
+ struct pollfd * pfd;
+
+ for (pfd=pfds, pdbg=plist, pcap=&plist[pcnt]; pdbg<pcap; pdbg++) {
+ if (pdbg->pid) {
+ pfd->fd = pdbg->pfd;
+ pfd->events = POLLIN;
+ pfd++;
+ }
+ }
+
+ return pfd - pfds;
+}
+
+static void winnt_close (struct target_ops * t)
+{
+}
+
+static void winnt_xclose (struct target_ops * t)
+{
+}
+
+static void winnt_attach (struct target_ops * t, const char * args, int from_tty)
+{
+ pid_t pid;
+ int pfd;
+
+ if ((pid = parse_pid_to_attach(args)) < 0) {
+ winnt_error ("cannot parse pid to attach");
+ }
+
+
+ if ((pfd = __dbg_attach(pid)) < 0) {
+ winnt_perror ("cannot attach to process",pid);
+ }
+
+
+ if ((pfd = __dbg_rbreak(pfd)) < 0) {
+ __dbg_detach(pfd);
+ winnt_perror ("could not issue a breakpoint in process",pid);
+ }
+
+
+ if (winnt_plist_add(pid,pfd) < 0) {
+ __dbg_detach(pfd);
+ winnt_error ("could not expand debuggee list");
+ }
+}
+
+static void winnt_detach (struct target_ops * t, const char * args, int from_tty)
+{
+ pid_t pid;
+ int pfd;
+
+ if ((pid = ptid_get_pid(inferior_ptid)) < 0)
+ winnt_error ("cannot parse pid to detach");
+
+ if ((pfd = winnt_pfd_from_pid(pid)) < 0)
+ winnt_perror ("debuggee record does not exist",pid);
+
+ if (__dbg_detach(pfd) < 0)
+ winnt_perror ("could not attach from process",pid);
+
+ winnt_plist_remove(pid);
+
+ x86_cleanup_dregs();
+}
+
+static ptid_t winnt_wait(
+ struct target_ops * t,
+ ptid_t ptid,
+ struct target_waitstatus * waitstatus,
+ int target_options)
+{
+ struct __dbg_event dbgevent;
+ struct pollfd pollfdbuf[512];
+ struct pollfd * pfds;
+ struct pollfd * pfd;
+ nfds_t nfds,i;
+
+ if (pcnt*sizeof(*pfds) < sizeof(pollfdbuf))
+ pfds = pollfdbuf;
+ else if (!(pfds = (struct pollfd *)calloc(pcnt,sizeof(*pfds))))
+ return null_ptid;
+
+ nfds = (ptid.pid > 0)
+ ? winnt_poll_one_init(pfds,ptid.pid)
+ : winnt_poll_init(pfds);
+
+ if (poll(pfds,nfds,-1) < 0)
+ return null_ptid;
+
+ for (i=0, pfd=0; i<nfds && !pfd; i++)
+ if (pfds[i].revents & POLLIN)
+ pfd = &pfds[i];
+
+ if (!pfd)
+ return null_ptid;
+
+ if (__dbg_event_query_one(pfd->fd,&dbgevent) < 0)
+ return null_ptid;
+
+ return ptid_build(
+ dbgevent.cpid ? dbgevent.cpid : dbgevent.syspid,
+ 0,
+ dbgevent.ctid ? dbgevent.ctid : dbgevent.systid);
+}
+
+static void winnt_resume (
+ struct target_ops * t,
+ ptid_t ptid, int step,
+ enum gdb_signal sig)
+{
+}
+
+static void winnt_kill (struct target_ops * t)
+{
+ /* current_inferior() */
+}
+
+static void winnt_mourn_inferior (struct target_ops * t)
+{
+ /* update plist, etc. */
+}
+
+static void winnt_create_inferior(
+ struct target_ops * ops,
+ char * exec_file,
+ char * allargs,
+ char ** in_env,
+ int from_tty)
+{
+ winnt_error("Not implemented");
+}
+
+static target_ops * winnt_target_alloc (void)
+{
+ target_ops * t = inf_child_target();
+
+ t->to_attach_no_wait = 1;
+ t->to_has_thread_control = 1;
+
+ t->to_close = winnt_close;
+ t->to_xclose = winnt_xclose;
+
+ t->to_attach = winnt_attach;
+ t->to_detach = winnt_detach;
+
+ t->to_wait = winnt_wait;
+ t->to_resume = winnt_resume;
+
+ t->to_kill = winnt_kill;
+ t->to_mourn_inferior = winnt_mourn_inferior;
+ t->to_create_inferior = winnt_create_inferior;
+
+ x86_use_watchpoints(t);
+
+ return t;
+}
+
+
+
+extern initialize_file_ftype _initialize_winnt_nat;
+
+void
+_initialize_winnt_nat(void)
+{
+ add_target(winnt_target_alloc());
+}