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).