From ba49c89f2bcbbcc46bb8648ade788fb607f04d85 Mon Sep 17 00:00:00 2001 From: midipix Date: Sat, 14 Sep 2019 20:01:18 +0000 Subject: mgdb: struct winnt_process: added .solibs member, related interfaces. --- overlay/mgdb/gdb/amd64-winnt-tdep.c | 5 ++ overlay/mgdb/gdb/winnt-nat.c | 128 +++++++++++++++++++++++++++++++++--- 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 @@ -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; modulemodule_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,"\n"); + + for (; modulemodule_name) { + if ((xmlstr = xml_escape_text(module->module_name))) { + mark += sprintf(mark,"",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,"",(void *)text); + + mark += sprintf(mark,""); + } + module++; + } + + mark += sprintf(mark,"\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; -- cgit v1.2.3