From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 66299 invoked by alias); 23 Mar 2015 01:19:51 -0000 Mailing-List: contact archer-commits-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: Received: (qmail 66279 invoked by uid 440); 23 Mar 2015 01:19:51 -0000 Date: Mon, 23 Mar 2015 01:19:00 -0000 Message-ID: <20150323011951.66252.qmail@sourceware.org> From: scox@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] scox/dyninst: Split client_state and server_state. X-Git-Refname: refs/heads/scox/dyninst X-Git-Reftype: branch X-Git-Oldrev: c1019e06804801746b14fdc62e2b06f3a2a7e01d X-Git-Newrev: 182451b3fd3afbf1b88867a90c222d4e7c91d3c3 X-SW-Source: 2015-q1/txt/msg00007.txt.bz2 List-Id: The branch, scox/dyninst has been updated via 182451b3fd3afbf1b88867a90c222d4e7c91d3c3 (commit) from c1019e06804801746b14fdc62e2b06f3a2a7e01d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit 182451b3fd3afbf1b88867a90c222d4e7c91d3c3 Author: Stan Cox Date: Sun Mar 22 21:16:15 2015 -0400 Split client_state and server_state. * configure.srv (x86_64-dyninst-linux): New. * dyninst-low.cc (pid_to_string): Add pc= (dyninst_create_inferior): Setup dyninst<->gdb register map. (dyninst_attach): Likewise. (dyninst_process_qsupported): New. * dyninst-low.h (process_qsupported, reg_map_setup): New. * dyninst-x86-low.cc (dyninst_x86_reg_map_setup): Setup dyninst<->gdb register map. (dyninst_x86_fill_gregset dyninst_x86_store_gregset): Use it. (dyninst_linux_process_qsupported): New. (dyninst_x86_arch_setup): Use tdesc_amd64_linux for register setup. (the_low_target): Add dyninst_linux_process_qsupported and dyninst_x85_reg_map_setup. * server.h (lock_modes, struct client_state) New. * server.c (new_server_state, free_server_state) (free_client_state, attach_client_state, count_client_state, delete_client_state): New to support client_state. (set_client_state, match_client_state): Change to support client_state. (set_lock): New to enforce multi client accessing. * event-loop.c (delete_file_handler): Call delete_client_state. * (gdbthread.c, inferiors.h, inferiors.c, linux-arm-low.c, linux-cris-low.c, linux-crisv32-low.c, linux-low.c, linux-mips-low.c, linux-nios2-low.c, linux-s390-low.c, linux-sparc-low.c, linux-tile-low.c, linux-x86-low.c, lynx-low.c, mem-break.c, nto-low.c, proc-service.c, regcache.c, remote-utils.c, target.c, tdesc.c, thread-db.c, tracepoint.c, win32-i386-low.c, win32-low.c, macrotab.h, utils.h): Boilerplate changes to support client/server state: cs->XX To cs->ss->XX ----------------------------------------------------------------------- Summary of changes: gdb/gdbserver/configure.srv | 2 +- gdb/gdbserver/dyninst-low.cc | 124 +++++-- gdb/gdbserver/dyninst-low.h | 2 + gdb/gdbserver/dyninst-x86-low.cc | 197 ++++++++--- gdb/gdbserver/event-loop.c | 9 +- gdb/gdbserver/gdbthread.h | 2 +- gdb/gdbserver/inferiors.c | 35 +- gdb/gdbserver/inferiors.h | 2 +- gdb/gdbserver/linux-aarch64-low.c | 8 +- gdb/gdbserver/linux-arm-low.c | 18 +- gdb/gdbserver/linux-cris-low.c | 2 +- gdb/gdbserver/linux-crisv32-low.c | 10 +- gdb/gdbserver/linux-low.c | 254 +++++++------- gdb/gdbserver/linux-mips-low.c | 14 +- gdb/gdbserver/linux-nios2-low.c | 2 +- gdb/gdbserver/linux-s390-low.c | 2 +- gdb/gdbserver/linux-sparc-low.c | 2 +- gdb/gdbserver/linux-tile-low.c | 2 +- gdb/gdbserver/linux-x86-low.c | 30 +- gdb/gdbserver/lynx-low.c | 14 +- gdb/gdbserver/mem-break.c | 6 +- gdb/gdbserver/nto-low.c | 16 +- gdb/gdbserver/proc-service.c | 10 +- gdb/gdbserver/regcache.c | 18 +- gdb/gdbserver/remote-utils.c | 48 ++- gdb/gdbserver/server.c | 719 ++++++++++++++++++++++++------------- gdb/gdbserver/server.h | 65 +++-- gdb/gdbserver/target.c | 8 +- gdb/gdbserver/tdesc.c | 2 +- gdb/gdbserver/thread-db.c | 24 +- gdb/gdbserver/tracepoint.c | 10 +- gdb/gdbserver/win32-i386-low.c | 10 +- gdb/gdbserver/win32-low.c | 24 +- gdb/macrotab.h | 12 +- gdb/utils.h | 4 +- 35 files changed, 1062 insertions(+), 645 deletions(-) First 500 lines of diff: diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv index 24c4306..3ee0c98 100644 --- a/gdb/gdbserver/configure.srv +++ b/gdb/gdbserver/configure.srv @@ -107,7 +107,7 @@ case "${target}" in srv_xmlfiles="$srv_i386__linux_xmlfiles" srv_dyninst=yes ;; - x86_64-dyninst-linux*) srv_regobj="$srv_amd64_regobj $srv_i386_regobj" + x86_64-dyninst-linux*) srv_regobj="$srv_amd64_linux_regobj $srv_i386_linux_regobj" srv_tgtobj="dyninst-low.o dyninst-x86-low.o" srv_xmlfiles="$srv_i386_linux_xmlfiles $srv_amd64_linux_xmlfiles" srv_dyninst=yes diff --git a/gdb/gdbserver/dyninst-low.cc b/gdb/gdbserver/dyninst-low.cc index 195f664..4e3ac2c 100644 --- a/gdb/gdbserver/dyninst-low.cc +++ b/gdb/gdbserver/dyninst-low.cc @@ -53,8 +53,9 @@ extern "C" cerr << cerrstr << '\n'; \ } + #define DYNERR(errstr,args...) \ - error ("%s %s " errstr, __FUNCTION__, dyninst_process->getLastErrorMsg(), ##args); + fprintf (stderr, "%s %s " errstr "\n", __FUNCTION__, dyninst_process->getLastErrorMsg(), ##args); using namespace std; using namespace __gnu_cxx; @@ -79,7 +80,6 @@ have_callbacks () { fd_set set; struct timeval timeout; - /* Initialize the file descriptor set. */ FD_ZERO (&set); @@ -125,7 +125,6 @@ class EventSet { private: /* The list of events that handleEvents has encountered */ - std::vector current_events_; std::map current_events; public: EventSet() { NULL_Event = Event::const_ptr(); } @@ -133,7 +132,8 @@ public: void insert (Event::const_ptr ev) { ptid_t ptid = ptid_build (ev->getProcess()->getPid(), ev->getThread()->getLWP(), (ev->getThread()->haveUserThreadInfo() ? ev->getThread()->getTID() : -1)); current_events[ptid] = ev; -// current_events.push_back(ev); + if (debug_threads) + dump("after insert "); } void erase (Event::const_ptr ev) { @@ -148,6 +148,8 @@ public: break; } } + if (debug_threads) + dump("after erase "); } /* Get the event for a given PTID */ @@ -248,7 +250,7 @@ public: else return false; } - void dump () + void dump (string comment) { std::map::iterator it; for (it = current_events.begin() ; @@ -258,7 +260,7 @@ public: Event::const_ptr event = it->second; if (event == NULL) continue; - DEBUG(event->name() << " pid=" << ptid.pid << " lwp=" << ptid.lwp << " tid=" << ptid.tid); + DEBUG(comment << event->name() << " pid=" << ptid.pid << " lwp=" << ptid.lwp << " tid=" << ptid.tid); } } @@ -272,6 +274,8 @@ pid_to_string (Dyninst::PID pid, Dyninst::LWP lwp, Dyninst::THR_ID tid) cerr << "pid=*"; else { + ptid_t ptid = ptid_build (pid, lwp, tid); + struct thread_info *ti = find_thread_ptid (ptid); cerr << "pid=" << pid; if (lwp < 0) cerr << " lwp=*"; @@ -279,6 +283,12 @@ pid_to_string (Dyninst::PID pid, Dyninst::LWP lwp, Dyninst::THR_ID tid) cerr << " lwp=" << lwp; if (tid > 0) cerr << " thr=" << tid; + if (ti != NULL) + { + struct regcache *regcache = get_thread_regcache (ti, 1); + CORE_ADDR pc = (*the_low_target.get_pc) (regcache); + cerr << " pc=" << pc; + } } cerr << ' '; } @@ -368,11 +378,28 @@ dyninst_add_thread(int pid, Thread::const_ptr thread) struct thread_info_private *tip = new struct thread_info_private; tip->thread = thread; lwp = thread->getLWP(); - cs->current_thread = add_thread (ptid_build (pid, lwp, 0), tip); + cs->ss->current_thread = add_thread (ptid_build (pid, lwp, 0), tip); } else { - cs->current_thread = add_thread (ptid_build (pid, pid, 0), NULL); + cs->ss->current_thread = add_thread (ptid_build (pid, pid, 0), NULL); + } +} + + +void +dyninst_remove_thread(Thread::const_ptr thread) +{ + if (thread != NULL) + { + ptid_t ptid = ptid_build (thread->getProcess()->getPid(), thread->getLWP(), 0); + struct thread_info *ti = find_thread_ptid (ptid); + if (ti != NULL) + { + delete (struct thread_info_private*)ti->target_data; + ti->target_data = NULL; + remove_thread (ti); + } } } @@ -384,9 +411,7 @@ dyninst_get_inferior_thread() { client_state *cs = get_client_state (); - DEBUG("current_thread=" << cs->current_thread); - struct thread_info_private *tip = (struct thread_info_private*)(cs->current_thread->target_data); - DEBUG("", pid_to_string (cs->current_thread->entry.id)); + struct thread_info_private *tip = (struct thread_info_private*)(cs->ss->current_thread->target_data); if (!tip) error ("No inferior thread"); return tip->thread; @@ -500,9 +525,17 @@ dyninst_create_inferior (char *program, char **allargs) for (thidx = dyninst_process->threads().begin(); thidx != dyninst_process->threads().end(); thidx++) { + bool reg_map_setup = false; + RegisterPool regpool; DEBUG("created thread " << (*thidx)->getTID() << ' ' << (*thidx)->getLWP()); Thread::ptr th = *thidx; dyninst_add_thread (pid, th); + if (! reg_map_setup) + { + th->getAllRegisters (regpool); + (*the_low_target.reg_map_setup)(regpool); + reg_map_setup = true; + } } if (! dyninst_process->stopProc()) @@ -553,9 +586,17 @@ dyninst_attach (unsigned long pid) for (thidx = dyninst_proc->threads().begin(); thidx != dyninst_proc->threads().end(); thidx++) { + bool reg_map_setup = false; + RegisterPool regpool; DEBUG("created thread " << (*thidx)->getTID() << ' ' << (*thidx)->getLWP()); Thread::const_ptr th = *thidx; dyninst_add_thread (pid, th); + if (! reg_map_setup) + { + th->getAllRegisters (regpool); + (*the_low_target.reg_map_setup)(regpool); + reg_map_setup = true; + } } LibraryPool::iterator libidx; @@ -582,7 +623,7 @@ dyninst_resume (struct thread_resume *resume_info, size_t n) ptid_t ptid = resume_info[i].thread; if (ptid_equal (ptid, minus_one_ptid)) - ptid = thread_to_gdb_id (cs->current_thread); + ptid = thread_to_gdb_id (cs->ss->current_thread); Dyninst::PID pid = ptid_get_pid (ptid); ProcessSet::iterator procset_it = dyninst_procset->find(pid); @@ -633,7 +674,7 @@ dyninst_resume (struct thread_resume *resume_info, size_t n) if (! th->setSingleStepMode(true)) DYNERR("Unable to setSingleStepMode"); case resume_continue: - regcache_invalidate (); + regcache_invalidate_thread (ti); if (! th->continueThread()) DYNERR("Unable to continueThread"); break; @@ -673,8 +714,8 @@ in_step_range () { client_state *cs = get_client_state (); - struct thread_info_private *tip = (struct thread_info_private*)(cs->current_thread->target_data); - struct regcache *regcache = get_thread_regcache (cs->current_thread, 1); + struct thread_info_private *tip = (struct thread_info_private*)(cs->ss->current_thread->target_data); + struct regcache *regcache = get_thread_regcache (cs->ss->current_thread, 1); CORE_ADDR pc = (*the_low_target.get_pc) (regcache); return (pc >= tip->step_range_start && pc < tip->step_range_end); @@ -703,13 +744,12 @@ dyninst_wait_1 (ptid_t ptid, struct target_waitstatus *status, int options) pid = (ptid.pid != -1) ? ptid.pid : event->getProcess()->getPid(); new_ptid = ptid_build (pid, pid, 0); pi = find_process_pid(pid); - if (pi) + if (pi && pi->piprivate) pi->piprivate->last_wait_event_ptid = new_ptid; } if (event == NULL) event = events.get(new_ptid); - events.dump(); Thread::const_ptr new_thr; if ((new_thr = events.is_threadcreate(event)) != NULL_Thread) @@ -785,8 +825,8 @@ dyninst_wait_1 (ptid_t ptid, struct target_waitstatus *status, int options) break; } - DEBUG("returning", pid_to_string (ptid_of(cs->current_thread))); - return ptid_of (cs->current_thread); + DEBUG("returning", pid_to_string (ptid_of(cs->ss->current_thread))); + return ptid_of (cs->ss->current_thread); // return new_ptid; } @@ -850,8 +890,23 @@ dyninst_detach (Dyninst::PID pid) static void dyninst_mourn (struct process_info *proc) { - proc->piprivate = NULL; clear_inferiors (); +// TODO + ThreadPool::iterator thidx; + + Process::ptr dyninst_process; + if (false && proc->piprivate) + { + dyninst_process = ((struct process_info_private*)(proc->piprivate))->process; + for (thidx = dyninst_process->threads().begin(); + thidx != dyninst_process->threads().end(); thidx++) + { + Thread::const_ptr th = *thidx; + dyninst_remove_thread (th); + } + } + delete proc->piprivate; + proc->piprivate = NULL; } @@ -891,29 +946,29 @@ dyninst_thread_alive (ptid_t ptid) /* Fetch the current thread's registers into REGCACHE */ + +RegisterPool regpool; + static void dyninst_fetch_registers (struct regcache *regcache, int regno) { Thread::const_ptr thr = dyninst_get_inferior_thread(); Thread::ptr th = boost::const_pointer_cast(thr); - DEBUG("regno=" << regno, pid_to_string (th)); - struct dyninst_regset_info *regset = dyninst_target_regsets; bool thread_was_active = false; - RegisterPool regpool; if (! th->isStopped()) { thread_was_active = true; - if (! th->stopThread()) + if (! th->stopThread()) { DEBUG("stopThread " << getLastErrorMsg()); } else { - DEBUG("stopThread") + DEBUG("stopThread"); } } @@ -941,7 +996,6 @@ dyninst_store_registers (struct regcache *regcache, int regno) bool thread_was_active = false; - RegisterPool regpool; if (! th->isStopped()) { thread_was_active = true; @@ -965,6 +1019,15 @@ dyninst_store_registers (struct regcache *regcache, int regno) th->continueThread(); } + +static void +dyninst_process_qsupported (const char *query) +{ + if (the_low_target.process_qsupported != NULL) + the_low_target.process_qsupported (query); +} + + static CORE_ADDR dyninst_read_pc (struct regcache *regcache) { @@ -990,7 +1053,7 @@ dyninst_write_pc (struct regcache *regcache, CORE_ADDR pc) static int dyninst_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len) { - DEBUG("memaddr" << memaddr << " myaddr=" << (void*)myaddr); + DEBUG("memaddr=" << memaddr << " myaddr=" << (void*)myaddr); Thread::const_ptr th = dyninst_get_inferior_thread(); Process::const_ptr dyninst_process = th->getProcess(); bool result; @@ -1049,7 +1112,7 @@ dyninst_request_interrupt (void) { client_state *cs = get_client_state (); - Dyninst::PID pid = ptid_get_pid (thread_to_gdb_id (cs->current_thread)); + Dyninst::PID pid = ptid_get_pid (thread_to_gdb_id (cs->ss->current_thread)); ProcessSet::iterator procset_it = dyninst_procset->find(pid); Process::ptr dyninst_process = *procset_it; @@ -1067,7 +1130,7 @@ dyninst_read_auxv (CORE_ADDR offset, unsigned char *myaddr, unsigned int len) char filename[PATH_MAX]; int fd, n; client_state *cs = get_client_state (); - int pid = lwpid_of (cs->current_thread); + int pid = lwpid_of (cs->ss->current_thread); xsnprintf (filename, sizeof filename, "/proc/%d/auxv", pid); @@ -1136,6 +1199,7 @@ dyninst_remove_point (enum raw_bkpt_type type, CORE_ADDR addr, int len, std::vector::iterator it; bool result = false; + for (it = dyninst_bpset.begin(); it != dyninst_bpset.end(); it++) { Breakpoint::ptr bp = *it; @@ -1294,7 +1358,7 @@ static struct target_ops dyninst_target_ops = { NULL, // handle_monitor_command NULL, // common_core_of_thread NULL, // read_loadmap - NULL, // process_qsupported + dyninst_process_qsupported, // process_qsupported NULL, // supports_tracepoints dyninst_read_pc, dyninst_write_pc, diff --git a/gdb/gdbserver/dyninst-low.h b/gdb/gdbserver/dyninst-low.h index aab96f2..22fb1c6 100644 --- a/gdb/gdbserver/dyninst-low.h +++ b/gdb/gdbserver/dyninst-low.h @@ -55,9 +55,11 @@ struct dyninst_target_ops { /* Architecture-specific setup. */ void (*arch_setup) (void); + void (*process_qsupported) (const char *query); CORE_ADDR (*get_pc) (struct regcache *regcache); void (*set_pc) (struct regcache *regcache, CORE_ADDR newpc); bool (*supports_range_stepping) (); + void (*reg_map_setup) (RegisterPool regpool); }; extern struct dyninst_target_ops the_low_target; diff --git a/gdb/gdbserver/dyninst-x86-low.cc b/gdb/gdbserver/dyninst-x86-low.cc index fa60b03..4436f6f 100644 --- a/gdb/gdbserver/dyninst-x86-low.cc +++ b/gdb/gdbserver/dyninst-x86-low.cc @@ -37,36 +37,28 @@ extern "C" static std::ostringstream dboss; - -std::map dyninst_x86_gdb_regnum; +std::vector dyninst_x86_gdb_regnum; extern "C" { /* Defined in auto-generated file i386.c. */ -extern void init_registers_amd64 (void); -extern void init_registers_i386 (void); +extern void init_registers_amd64_linux (void); +extern void init_registers_i386_linux (void); extern const struct target_desc *tdesc_i386_linux; extern const struct target_desc *tdesc_amd64_linux; extern const struct target_desc *tdesc_i386; extern const struct target_desc *tdesc_amd64; } -/* Print a debug trace on standard output if debug_threads (--debug) is set. */ +static int use_xml; -static void -dyninst_debug (const char *fmt, ...) -{ - va_list args; - if (!debug_threads) - return; +/* Print a debug trace on standard output if debug_threads (--debug) is set. */ - va_start (args, fmt); - fprintf (stderr, "DEBUG(dyninst): "); - vfprintf (stderr, fmt, args); - fprintf (stderr, "\n"); - va_end (args); -} +#define DEBUG(args...) \ + if (debug_threads) { \ + fprintf (stderr, "%s %s %s\n", "DEBUG(dyninst): ", __FUNCTION__, args); \ + } static unsigned char * register_data (struct regcache *regcache, int n, int fetch) @@ -86,21 +78,84 @@ canonicalize_reg (string ®) } +void +dyninst_x86_reg_map_setup (RegisterPool regpool) +{ + for (int r = 0; r < dyninst_tdesc->num_registers; r++) + { + RegisterPool::iterator regidx = regpool.begin(); + for (; regidx != regpool.end(); regidx++) + { + string reg = (*regidx).first.name(); + string canon_reg = canonicalize_reg (reg); + if (strcmp (canon_reg.c_str(), dyninst_tdesc->reg_defs[r].name) != 0) + continue; + dyninst_x86_gdb_regnum.push_back ((*regidx).first.val()); + break; + } + } +} + + +static void +dump_registers (const char* whoami, RegisterPool regpool) +{ + RegisterPool::iterator regidx; + fprintf (stderr, "%s ", whoami); + for (regidx = regpool.begin(); regidx != regpool.end(); regidx++) + { + MachRegister reg = (*regidx).first; + MachRegisterVal regval = (*regidx).second; + switch (reg.val()) + { + case x86::ieax: + case x86_64::irax: + fprintf (stderr, "rax=%#lx ", regval);break; + case x86::iebx: + case x86_64::irbx: + fprintf (stderr, "rbx=%#lx ", regval);break; + case x86::iecx: + case x86_64::ircx: + fprintf (stderr, "rcx=%#lx ", regval);break; + case x86::iedx: + case x86_64::irdx: + fprintf (stderr, "rdx=%#lx ", regval);break; + case x86::iebp: + case x86_64::irbp: + fprintf (stderr, "rbp=%#lx ", regval);break; + case x86::iesp: + case x86_64::irsp: + fprintf (stderr, "rsp=%#lx ", regval);break; + case x86::iesi: + case x86_64::irsi: + fprintf (stderr, "rsi=%#lx ", regval);break; + case x86::iedi: + case x86_64::irdi: + fprintf (stderr, "rdi=%#lx ", regval);break; + } + } + fprintf (stderr, "\n"); +} + + /* The fill_function for the general-purpose register set. */ static void dyninst_x86_fill_gregset (struct regcache *regcache, RegisterPool regpool) { + for (int r = 0; r < dyninst_tdesc->num_registers; r++) hooks/post-receive -- Repository for Project Archer.