public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM] scox/dyninst: Support shared libraries.
@ 2014-12-15 2:58 scox
0 siblings, 0 replies; only message in thread
From: scox @ 2014-12-15 2:58 UTC (permalink / raw)
To: archer-commits
The branch, scox/dyninst has been updated
via 02afeed30a601bea111805ef89f3c6a27dd59ad9 (commit)
from bc5aece835a317ef016557d57a6a32178091d821 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email.
- Log -----------------------------------------------------------------
commit 02afeed30a601bea111805ef89f3c6a27dd59ad9
Author: Stan Cox <scox@redhat.com>
Date: Sun Dec 14 21:54:41 2014 -0500
Support shared libraries.
* configure.srv (*dyninst*): Use *linux_xmlfiles.
* dyninst-low.cc (library_handler): New.
* (dyninst_attach): Add shared libraries.
(dyninst_read_auxv): New.
(dyninst_qxfer_libraries_svr4): New for adding shared libraries.
* dyninst-x85-low.cc (dyninst_x86_fill_gregset): Mark filled registers as valid.
-----------------------------------------------------------------------
Summary of changes:
gdb/gdbserver/configure.srv | 4 +-
gdb/gdbserver/dyninst-low.cc | 224 +++++++++++++++++++++++++++++++++-----
gdb/gdbserver/dyninst-x86-low.cc | 20 +++-
3 files changed, 212 insertions(+), 36 deletions(-)
First 500 lines of diff:
diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
index bb68ded..24c4306 100644
--- a/gdb/gdbserver/configure.srv
+++ b/gdb/gdbserver/configure.srv
@@ -104,12 +104,12 @@ case "${target}" in
;;
i[34567]86-dyninst-linux*) srv_regobj="$srv_i386_regobj"
srv_tgtobj="dyninst-low.o dyninst-x86-low.o"
- srv_xmlfiles="$srv_i386_xmlfiles"
+ srv_xmlfiles="$srv_i386__linux_xmlfiles"
srv_dyninst=yes
;;
x86_64-dyninst-linux*) srv_regobj="$srv_amd64_regobj $srv_i386_regobj"
srv_tgtobj="dyninst-low.o dyninst-x86-low.o"
- srv_xmlfiles="$srv_i386_xmlfiles $srv_amd64_xmlfiles"
+ srv_xmlfiles="$srv_i386_linux_xmlfiles $srv_amd64_linux_xmlfiles"
srv_dyninst=yes
;;
i[34567]86-*-linux*) srv_regobj="$srv_i386_linux_regobj"
diff --git a/gdb/gdbserver/dyninst-low.cc b/gdb/gdbserver/dyninst-low.cc
index 018fa61..39747ac 100644
--- a/gdb/gdbserver/dyninst-low.cc
+++ b/gdb/gdbserver/dyninst-low.cc
@@ -19,6 +19,7 @@ extern "C"
{
#include "server.h"
#include "target.h"
+#include "dll.h"
#include <limits.h>
#include <stdlib.h>
@@ -30,6 +31,8 @@ extern "C"
#include <signal.h>
#include <errno.h>
#include <sys/select.h>
+#include <sys/stat.h>
+#include <fcntl.h>
}
#include <dyninst/PCProcess.h>
@@ -41,6 +44,7 @@ extern "C"
#include "dyninst-low.h"
#include <iostream>
#include <sstream>
+#include <typeinfo>
#define DEBUG(func,cerrstr,args...) \
if (debug_threads) { \
@@ -58,6 +62,8 @@ using namespace ProcControlAPI;
typedef std::vector<Breakpoint::ptr> BreakpointSet;
BreakpointSet dyninst_bpset;
ProcessSet::ptr dyninst_procset;
+typedef std::vector<Library::ptr> LibrarySet;
+LibrarySet dyninst_libset;
Thread::const_ptr NULL_Thread = Thread::const_ptr();
@@ -136,7 +142,7 @@ public:
{
event = *rit;
- if (event->getProcess()->getPid() == ptid.pid)
+ if (ptid.pid == -1 || event->getProcess()->getPid() == ptid.pid)
{
DEBUG("events.get","returning event " << event->name());
return event;
@@ -187,14 +193,16 @@ public:
bool is_threadcreate (Event::const_ptr event)
{
if (event != NULL)
- return event->getEventType().code() == EventType::ThreadCreate;
+ DEBUG("is_threadcreate", event->getEventType().code() << EventType::LWPCreate);
+ if (event != NULL)
+ return event->getEventType().code() == EventType::LWPCreate;
else return false;
}
bool is_threaddestroy(Event::const_ptr event)
{
if (event != NULL)
- return event->getEventType().code() == EventType::ThreadDestroy;
+ return event->getEventType().code() == EventType::UserThreadDestroy;
else return false;
}
@@ -329,7 +337,7 @@ dyninst_get_inferior_thread()
{
DEBUG("dyninst_get_inferior_thread", "current_thread=" << current_thread);
struct thread_info_private *tip = (struct thread_info_private*)(current_thread->target_data);
- DEBUG("dyninst_get_inferior_thread", "", pid_to_string (tip->thread));
+ DEBUG("dyninst_get_inferior_thread", "", pid_to_string (current_thread->entry.id));
if (!tip)
error ("No inferior thread");
return tip->thread;
@@ -353,12 +361,30 @@ Process::cb_ret_t
singlestep_handler(Event::const_ptr ev)
{
events.insert(ev);
- DEBUG("signal_handler", ev->name());
+ DEBUG("singlestep_handler", ev->name());
ev->getThread()->setSingleStepMode(false);
return Process::cbThreadStop;
}
+/* Handle a dyninst Library event */
+
+Process::cb_ret_t
+library_handler(Event::const_ptr ev)
+{
+ EventLibrary::const_ptr lib_ev = ev->getEventLibrary();
+
+ for (set<Library::ptr>::const_iterator i = lib_ev->libsAdded().begin(); i != lib_ev->libsAdded().end(); i++)
+ {
+ Library::ptr lib = *i;
+ DEBUG("dyninst_attach", "added library " << lib->getAbsoluteName() << " " << lib->getDynamicAddress() << " " << lib->getLoadAddress() << endl);
+// loaded_dll (lib->getAbsoluteName().c_str(), lib->getDynamicAddress());
+ }
+
+ return Process::cbDefault;
+}
+
+
void
myregisterCB(EventType et, Process::cb_func_t f)
{
@@ -396,7 +422,7 @@ dyninst_create_inferior (char *program, char **allargs)
myregisterCB(EventType::Exec, signal_handler);
myregisterCB(EventType::Exit, signal_handler);
myregisterCB(EventType::Fork, signal_handler);
-// myregisterCB(EventType::Library, signal_handler);
+ myregisterCB(EventType::Library, library_handler);
myregisterCB(EventType::RPC, signal_handler);
myregisterCB(EventType::Signal, signal_handler);
myregisterCB(EventType::SingleStep, singlestep_handler);
@@ -405,6 +431,7 @@ dyninst_create_inferior (char *program, char **allargs)
myregisterCB(EventType::ThreadCreate, signal_handler);
myregisterCB(EventType::ThreadDestroy, signal_handler);
myregisterCB(EventType::UserThreadCreate, signal_handler);
+ myregisterCB(EventType::UserThreadDestroy, signal_handler);
DEBUG("dyninst_create_inferior", "created process " << dyninst_process->getPid() << program);
@@ -464,6 +491,14 @@ dyninst_attach (unsigned long pid)
dyninst_add_thread (pid, th);
}
+ LibraryPool::iterator libidx;
+ for (libidx = dyninst_proc->libraries().begin(); libidx != dyninst_proc->libraries().end(); libidx++)
+ {
+ Library::ptr lib = *libidx;
+ DEBUG("dyninst_attach", "added library " << lib->getName() << " " << lib->getDynamicAddress() << " " << lib->getLoadAddress() << endl);
+// loaded_dll (lib->getAbsoluteName().c_str(), lib->getDynamicAddress());
+ }
+
return 0;
}
@@ -562,24 +597,23 @@ in_step_range ()
static ptid_t
dyninst_wait_1 (ptid_t ptid, struct target_waitstatus *status, int options)
{
- Dyninst::PID pid = 0;
- ptid_t new_ptid;
+ ptid_t new_ptid = ptid;
+ Dyninst::PID pid = ptid.pid;
DEBUG("dyninst_wait_1", "", pid_to_string (ptid));
- if (ptid_equal (ptid, minus_one_ptid))
- {
- pid = ptid_get_pid (thread_to_gdb_id (current_thread));
- new_ptid = ptid_build (pid, pid, 0);
- }
- else
- {
- pid = ptid_get_pid(ptid);
- new_ptid = ptid;
- }
-
- ProcessSet::iterator procset_it = dyninst_procset->find(pid);
- Process::ptr dyninst_process = *procset_it;
+// if (ptid_equal (ptid, minus_one_ptid))
+// {
+// pid = ptid_get_pid (thread_to_gdb_id (current_thread));
+// new_ptid = ptid_build (pid, pid, 0);
+// }
+// else
+// {
+// pid = ptid_get_pid(ptid);
+// new_ptid = ptid;
+// }
+// ProcessSet::iterator procset_it = dyninst_procset->find(pid);
+// Process::ptr dyninst_process = *procset_it;
Event::const_ptr event;
@@ -589,6 +623,8 @@ dyninst_wait_1 (ptid_t ptid, struct target_waitstatus *status, int options)
if ((event = events.get(new_ptid)))
{
struct process_info *pi;
+ pid = event->getProcess()->getPid();
+ new_ptid = ptid_build (pid, pid, 0);
pi = find_process_pid(pid);
if (pi)
pi->piprivate->last_wait_event_ptid = new_ptid;
@@ -596,19 +632,20 @@ dyninst_wait_1 (ptid_t ptid, struct target_waitstatus *status, int options)
if (event == NULL)
event = events.get(new_ptid);
- events.dump();
+// events.dump();
if (events.is_threadcreate(event))
{
Thread::const_ptr thr;
-// if (event != events.NULL_Event)
+ EventNewLWP::const_ptr newlwp_ev = event->getEventNewLWP();
if (event != NULL)
- thr = event->getThread();
+ thr = newlwp_ev->getNewThread();
else
thr = NULL_Thread;
- DEBUG("dyninst_wait_1", "New thread: ", pid_to_string (ptid));
+ DEBUG("dyninst_wait_1", "New thread: " << event->getThread()->getLWP() << " " << thr->getLWP(), pid_to_string (new_ptid));
dyninst_add_thread (pid, thr);
+ return new_ptid;
}
else if (events.is_exit(event))
{
@@ -666,8 +703,9 @@ dyninst_wait_1 (ptid_t ptid, struct target_waitstatus *status, int options)
break;
}
- DEBUG("dyninst_wait_1 returning", "", pid_to_string (ptid));
- return new_ptid;
+ DEBUG("dyninst_wait_1 returning", "", pid_to_string (ptid_of(current_thread)));
+ return ptid_of (current_thread);
+// return new_ptid;
}
@@ -692,6 +730,8 @@ dyninst_kill (Dyninst::PID pid)
{
struct process_info *process;
ProcessSet::iterator procset_it = dyninst_procset->find(pid);
+ if (procset_it == dyninst_procset->end())
+ return 1;
Process::ptr dyninst_process = *procset_it;
DEBUG("dyninst_kill", "pid=" << pid);
@@ -871,6 +911,34 @@ dyninst_request_interrupt (void)
}
+/* Copy LEN bytes from inferior's auxiliary vector starting at OFFSET
+ to debugger memory starting at MYADDR. */
+
+static int
+dyninst_read_auxv (CORE_ADDR offset, unsigned char *myaddr, unsigned int len)
+{
+ char filename[PATH_MAX];
+ int fd, n;
+ int pid = lwpid_of (current_thread);
+
+ xsnprintf (filename, sizeof filename, "/proc/%d/auxv", pid);
+
+ fd = open (filename, O_RDONLY);
+ if (fd < 0)
+ return -1;
+
+ if (offset != (CORE_ADDR) 0
+ && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
+ n = -1;
+ else
+ n = read (fd, myaddr, len);
+
+ close (fd);
+
+ return n;
+}
+
+
/* Breakpoint/Watchpoint support. */
static int
@@ -917,7 +985,7 @@ dyninst_remove_point (enum raw_bkpt_type type, CORE_ADDR addr, int len,
Process::const_ptr dyninst_process = th->getProcess();
std::vector<Breakpoint::ptr>::iterator it;
- bool result;
+ bool result = false;
for (it = dyninst_bpset.begin(); it != dyninst_bpset.end(); it++)
{
Breakpoint::ptr bp = *it;
@@ -943,6 +1011,102 @@ dyninst_supports_range_stepping (void)
}
+static int
+dyninst_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
+ unsigned const char *writebuf,
+ CORE_ADDR offset, int len)
+{
+#include <string> // std::string
+#include <iostream> // std::cout
+#include <sstream> // std::ostringstream
+
+ // <library-list-svr4 version="1.0" main-lm="0x320cc21168">
+ // <library name="/lib64/libc.so.6" lm="0x7ff37530a700" l_addr="0x0" l_ld="0x320d1b6b40"/>
+ // <library name="/lib64/ld-linux-x86-64.so.2" lm="0x320cc20998" l_addr="0x0" l_ld="0x320cc1fe10"/>
+ // </library-list-svr4>
+
+ Thread::const_ptr th = dyninst_get_inferior_thread();
+ Process::const_ptr dyninst_proc = th->getProcess();
+
+ string document = "<library-list-svr4 version=\"1.0\">";
+
+// Dyninst::PID pid = ptid_get_pid (thread_to_gdb_id (current_thread));
+// ProcessSet::iterator procset_it = dyninst_procset->find(pid);
+// Process::ptr dyninst_proc = *procset_it;
+
+ LibraryPool::const_iterator libidx;
+ bool first = true;
+ for (libidx = dyninst_proc->libraries().begin(); libidx != dyninst_proc->libraries().end(); libidx++)
+ {
+ Library::const_ptr lib = *libidx;
+ if (first)
+ {
+ first = false;
+ continue;
+ }
+ DEBUG("dyninst_qxfer_libraries_svr4", "added library " << lib->getName() << " " << lib->getDynamicAddress() << " " << lib->getLoadAddress() << endl);
+ // loaded_dll (lib->getAbsoluteName().c_str(), lib->getDynamicAddress());
+ std::ostringstream oss;
+
+ oss << "<library name=\"" << lib->getAbsoluteName()
+ << "\" lm=\"0x0\" "
+ << "l_addr=\"0x0\" "
+ << "l_ld=\"" << hex << lib->getDynamicAddress() << "\"/>";
+ document += oss.str();
+ }
+ document += "</library-list-svr4>";
+ document.copy((char*)readbuf, document.length());
+ readbuf[document.length()]='\0';
+
+ return document.length();
+}
+
+
+// Return non-zero if HEADER is a 64-bit ELF file. (from linux-low)
+
+#if 0
+static int
+elf_64_header_p (const Elf64_Ehdr *header, unsigned int *machine)
+{
+ if (header->e_ident[EI_MAG0] == ELFMAG0
+ && header->e_ident[EI_MAG1] == ELFMAG1
+ && header->e_ident[EI_MAG2] == ELFMAG2
+ && header->e_ident[EI_MAG3] == ELFMAG3)
+ {
+ *machine = header->e_machine;
+ return header->e_ident[EI_CLASS] == ELFCLASS64;
+
+ }
+ *machine = EM_NONE;
+ return -1;
+}
+
+// Return non-zero if FILE is a 64-bit ELF file,
+// zero if the file is not a 64-bit ELF file,
+// and -1 if the file is not accessible or doesn't exist.
+
+static int
+elf_64_file_p (const char *file, unsigned int *machine)
+{
+ Elf64_Ehdr header;
+ int fd;
+
+ fd = open (file, O_RDONLY);
+ if (fd < 0)
+ return -1;
+
+ if (read (fd, &header, sizeof (header)) != sizeof (header))
+ {
+ close (fd);
+ return 0;
+ }
+ close (fd);
+
+ return elf_64_header_p (&header, machine);
+}
+#endif
+
+
/* The Dyninst target_ops vector. */
static struct target_ops dyninst_target_ops = {
@@ -963,7 +1127,7 @@ static struct target_ops dyninst_target_ops = {
dyninst_write_memory,
NULL, /* look_up_symbols */
dyninst_request_interrupt,
- NULL, /* read_auxv */
+ dyninst_read_auxv,
dyninst_supports_z_point_type,
dyninst_insert_point, /* insert_point */
dyninst_remove_point, /* remove_point */
@@ -996,7 +1160,7 @@ static struct target_ops dyninst_target_ops = {
NULL, // emit_ops
NULL, // supports_disable_randomization
NULL, // get_min_fast_tracepoint_insn_len
- NULL, // qxfer_libraries_svr4
+ dyninst_qxfer_libraries_svr4, // qxfer_libraries_svr4
NULL, // supports_agent
NULL,
NULL,
diff --git a/gdb/gdbserver/dyninst-x86-low.cc b/gdb/gdbserver/dyninst-x86-low.cc
index 695eddf..fa60b03 100644
--- a/gdb/gdbserver/dyninst-x86-low.cc
+++ b/gdb/gdbserver/dyninst-x86-low.cc
@@ -38,8 +38,6 @@ extern "C"
static std::ostringstream dboss;
-
-// TODO improve this
std::map<string,int> dyninst_x86_gdb_regnum;
extern "C"
@@ -104,6 +102,7 @@ dyninst_x86_fill_gregset (struct regcache *regcache, RegisterPool regpool)
MachRegisterVal regval = (MachRegisterVal)((*regidx).second);
const char *regstr;
+ regcache->register_status[regn] = REG_VALID;
switch (register_size (regcache->tdesc, regn))
{
case 2:
@@ -183,14 +182,27 @@ dyninst_x86_store_gregset (struct regcache *regcache, RegisterPool regpool)
static void
dyninst_x86_fill_fpregset (struct regcache *regcache, RegisterPool regpool)
{
- dyninst_debug("dyninst_x86_fill_fpregset\n");
+ // supported by dyninst
+ // rax rbp rbx rcx rdi rdx rip rsi rsp
+ // r8 - r15
+ // ds es fs gs cs ss flags orax fsbase gsbase
+
+ // supported by dyninst but not in register pool (RegisterConversion-x86.C)
+ // xmm0 - xmm15
+ // TODO support xmm registers
+
+ // not supported by dyninst
+ // fctrl fioff fiseg fooff fop foseg fstat ftag mxcsr
+ // st0 - st7
+ dyninst_debug("dyninst_x86_fill_fpregset: dyninst does not support floating registers.\n");
+// result = th->getRegister(MachRegister(x86_64::xmm0), rspval);
}
static void
dyninst_x86_store_fpregset (struct regcache *regcache, RegisterPool regpool)
{
- dyninst_debug("dyninst_x86_store_fpregset %#lx\n", regcache);
+ dyninst_debug("dyninst_x86_store_fpregset: dyninst does not support floating registers.\n", regcache);
}
hooks/post-receive
--
Repository for Project Archer.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2014-12-15 2:58 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-15 2:58 [SCM] scox/dyninst: Support shared libraries scox
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).