summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormidipix <writeonce@midipix.org>2019-09-14 20:01:18 +0000
committermidipix <writeonce@midipix.org>2019-09-14 20:16:52 +0000
commitba49c89f2bcbbcc46bb8648ade788fb607f04d85 (patch)
treecae1ab9dc2bb0f8a9b412ecaf3d3e0ccbd2929de
parentaef6781dbba2f1ce4cd9eac1328c498e2b4f84a8 (diff)
downloadchainport-ba49c89f2bcbbcc46bb8648ade788fb607f04d85.tar.bz2
chainport-ba49c89f2bcbbcc46bb8648ade788fb607f04d85.tar.xz
mgdb: struct winnt_process: added .solibs member, related interfaces.
-rw-r--r--overlay/mgdb/gdb/amd64-winnt-tdep.c5
-rw-r--r--overlay/mgdb/gdb/winnt-nat.c128
2 files changed, 123 insertions, 10 deletions
diff --git a/overlay/mgdb/gdb/amd64-winnt-tdep.c b/overlay/mgdb/gdb/amd64-winnt-tdep.c
index 5d1fa49..ab06122 100644
--- a/overlay/mgdb/gdb/amd64-winnt-tdep.c
+++ b/overlay/mgdb/gdb/amd64-winnt-tdep.c
@@ -6,6 +6,8 @@
#include "defs.h"
#include "osabi.h"
+#include "solib.h"
+#include "solib-target.h"
#include "frame-unwind.h"
#include "amd64-windows-tdep.c"
@@ -36,6 +38,9 @@ static void amd64_winnt_init_abi (struct gdbarch_info info, struct gdbarch * gdb
/* todo: inferior-specific, dynamically detected size of long */
set_gdbarch_long_bit (gdbarch, 64);
+
+ /* solibs */
+ set_solib_ops (gdbarch, &solib_target_so_ops);
}
void windows_init_abi (struct gdbarch_info info, struct gdbarch * gdbarch)
diff --git a/overlay/mgdb/gdb/winnt-nat.c b/overlay/mgdb/gdb/winnt-nat.c
index 0f615e5..8b1cff6 100644
--- a/overlay/mgdb/gdb/winnt-nat.c
+++ b/overlay/mgdb/gdb/winnt-nat.c
@@ -13,6 +13,7 @@
#include "inferior.h"
#include "gdbthread.h"
#include "inf-child.h"
+#include "xml-support.h"
#include "x86-nat.h"
#include <poll.h>
@@ -44,6 +45,7 @@ struct winnt_process {
int nmodules;
struct __dbg_module_info * modules;
struct __dbg_event event;
+ char * solibs;
};
static size_t pcnt;
@@ -111,14 +113,22 @@ static void winnt_free_modules(struct winnt_process * pidinfo)
modules_base = pidinfo->modules;
modules_cap = &modules_base[pidinfo->nmodules];
- for (module=modules_base; module<modules_cap; module++)
+ for (module=modules_base; module<modules_cap; module++) {
if (module->module_name)
free(module->module_name);
+ if (module->module_ctx)
+ pe_free_unit_ctx((pe_unit_ctx *)module->module_ctx);
+ }
+
+ if (pidinfo->solibs)
+ free(pidinfo->solibs);
+
free(pidinfo->modules);
pidinfo->modules = 0;
pidinfo->nmodules = 0;
+ pidinfo->solibs = 0;
}
static void winnt_plist_remove (pid_t pid)
@@ -189,11 +199,18 @@ static char * winnt_pid_to_exec_file (struct target_ops * t, int pid)
static void winnt_get_modules(struct winnt_process * pidinfo)
{
void * addr;
+ char * xmlstr;
+ char * mark;
+ char * text;
+ struct pe_unit_ctx * uctx;
+ struct pe_meta_sec_hdr * sechdr;
struct __dbg_module_info * module;
struct __dbg_module_info * modules;
struct __dbg_module_info * modules_cap;
ssize_t nbytes;
size_t nmodules;
+ size_t buflen;
+ int secidx;
winnt_free_modules(pidinfo);
@@ -221,6 +238,7 @@ static void winnt_get_modules(struct winnt_process * pidinfo)
memcpy(modules,addr,nmodules*sizeof(*modules));
free(addr);
+ buflen = 64;
module = modules;
modules_cap = &modules[nmodules];
@@ -230,14 +248,66 @@ static void winnt_get_modules(struct winnt_process * pidinfo)
__DBG_INFO_MODULE_RPATH,
outbuf,WINNT_OUTBUF_SIZE);
- if (nbytes > 0)
+ if (nbytes > 0) {
module->module_name = strdup(outbuf);
+ xmlstr = xml_escape_text(outbuf);
+
+ if (xmlstr) {
+ buflen += strlen(xmlstr) + 128;
+ xfree(xmlstr);
+ }
+
+ pe_get_unit_ctx(
+ pe_dctx,
+ module->module_name,
+ (pe_unit_ctx **)&module->module_ctx);
+ }
module++;
}
+ module = modules;
pidinfo->modules = modules;
pidinfo->nmodules = nmodules;
+
+ if (!(pidinfo->solibs = (char *)calloc(1,buflen)))
+ return;
+
+ mark = pidinfo->solibs;
+ mark += sprintf(mark,"<library-list>\n");
+
+ for (; module<modules_cap; ) {
+ uctx = 0;
+ text = 0;
+
+ if (module->module_name) {
+ if ((xmlstr = xml_escape_text(module->module_name))) {
+ mark += sprintf(mark,"<library name=");
+ mark += sprintf(mark,"\"%s\">",xmlstr);
+ xfree(xmlstr);
+ }
+
+ /* text */
+ if ((uctx = (pe_unit_ctx *)module->module_ctx)) {
+ secidx = pe_get_named_section_index(
+ uctx->meta,".text");
+
+ if (secidx >= 0) {
+ sechdr = &uctx->meta->m_sectbl[secidx];
+ text = (char *)module->module_base;
+ text += sechdr->sh_virtual_addr;
+ }
+ }
+
+ mark += sprintf(mark,"<segment address=");
+ mark += sprintf(mark,"\"%p\"/>",(void *)text);
+
+ mark += sprintf(mark,"</library>");
+ }
+ module++;
+ }
+
+ mark += sprintf(mark,"</library-list>\n");
}
static void winnt_fetch_registers (
@@ -277,6 +347,30 @@ static void winnt_store_registers (
(void)regnum;
}
+ssize_t winnt_xfer_solibs(
+ struct winnt_process * pidinfo,
+ gdb_byte * readbuf,
+ ULONGEST offset,
+ ULONGEST len)
+{
+ size_t buflen;
+
+ if (!pidinfo->solibs)
+ return -1;
+
+ buflen = strlen(pidinfo->solibs);
+
+ if (offset >= buflen)
+ return 0;
+
+ if (len > (buflen - offset))
+ len = buflen - offset;
+
+ memcpy(readbuf,pidinfo->solibs + offset,len);
+
+ return len;
+}
+
static enum target_xfer_status winnt_xfer_partial(
struct target_ops * t,
enum target_object object,
@@ -287,10 +381,6 @@ static enum target_xfer_status winnt_xfer_partial(
ULONGEST len,
ULONGEST * nxfered)
{
- (void)t;
- (void)object;
- (void)annex;
-
ssize_t ret;
pid_t pid;
struct winnt_process * pidinfo;
@@ -309,11 +399,29 @@ static enum target_xfer_status winnt_xfer_partial(
if (!nxfered)
winnt_error("internal error: nxfered is null.");
- ret = (readbuf)
- ? __dbg_vm_read(pidinfo->pfd,readbuf,len,offset)
- : __dbg_vm_write(pidinfo->pfd,writebuf,len,offset);
+ switch (object) {
+ case TARGET_OBJECT_MEMORY:
+ ret = (readbuf)
+ ? __dbg_vm_read(pidinfo->pfd,readbuf,len,offset)
+ : __dbg_vm_write(pidinfo->pfd,writebuf,len,offset);
+ break;
- if (ret < 0)
+ case TARGET_OBJECT_LIBRARIES:
+ ret = winnt_xfer_solibs(pidinfo,readbuf,offset,len);
+ break;
+
+ default:
+ ret = t->beneath->to_xfer_partial(
+ t,object,annex,
+ readbuf,writebuf,
+ offset,len,nxfered);
+ break;
+ }
+
+ if (ret == 0)
+ return TARGET_XFER_EOF;
+
+ else if (ret < 0)
return TARGET_XFER_E_IO;
*nxfered = ret;