From c2250ad1c4567fd2235cb4131f7cb7c06da3769a Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Thu, 2 Jul 2009 17:06:44 +0000 Subject: [PATCH] * target.h (struct target_ops): New member to_thread_architecture. (target_thread_architecture): New macro. * target.c (update_current_target): Inherit to_thread_architecture. (default_thread_architecture): New function. (debug_to_thread_architecture): New function. (setup_target_debug): Handle to_thread_architecture. * regcache.h (get_thread_arch_regcache): New. * regcache.c (struct regcache_list): New data type. (current_regcache): Hold regcache list instead of single regcache. (current_thread_ptid, current_thread_arch): New static variables. (get_thread_arch_regcache): New function. (get_thread_regcache): Use it. Call target_thread_architecture. (regcache_thread_ptid_changed): Update to current_regcache changes. (registers_changed): Likewise. Reset current_thread_arch and current_thread_ptid. * remote.c (remote_wait): Access target registers in target_gdbarch. * linux-nat.c (linux_nat_do_thread_registers): Likewise. * proc-service.c (ps_lgetregs, ps_lsetregs): Likewise. (ps_lgetfpregs, ps_lsetfpregs): Likewise. * sol-thread.c (ps_lgetregs, ps_lsetregs): Likewise. (ps_lgetfpregs, ps_lsetfpregs): Likewise. * solib-svr4.c (enable_break): Likewise. (svr4_relocate_main_executable): Likewise. --- gdb/ChangeLog | 28 ++++++++++++++++ gdb/linux-nat.c | 4 +-- gdb/proc-service.c | 8 ++--- gdb/regcache.c | 79 +++++++++++++++++++++++++++++++++------------- gdb/regcache.h | 1 + gdb/sol-thread.c | 8 ++--- gdb/solib-svr4.c | 6 ++-- gdb/target.c | 26 +++++++++++++++ gdb/target.h | 8 +++++ 9 files changed, 134 insertions(+), 34 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 335b939328d..3a1936975de 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,31 @@ +2009-07-02 Ulrich Weigand + + * target.h (struct target_ops): New member to_thread_architecture. + (target_thread_architecture): New macro. + * target.c (update_current_target): Inherit to_thread_architecture. + (default_thread_architecture): New function. + (debug_to_thread_architecture): New function. + (setup_target_debug): Handle to_thread_architecture. + + * regcache.h (get_thread_arch_regcache): New. + * regcache.c (struct regcache_list): New data type. + (current_regcache): Hold regcache list instead of single regcache. + (current_thread_ptid, current_thread_arch): New static variables. + (get_thread_arch_regcache): New function. + (get_thread_regcache): Use it. Call target_thread_architecture. + (regcache_thread_ptid_changed): Update to current_regcache changes. + (registers_changed): Likewise. Reset current_thread_arch and + current_thread_ptid. + + * remote.c (remote_wait): Access target registers in target_gdbarch. + * linux-nat.c (linux_nat_do_thread_registers): Likewise. + * proc-service.c (ps_lgetregs, ps_lsetregs): Likewise. + (ps_lgetfpregs, ps_lsetfpregs): Likewise. + * sol-thread.c (ps_lgetregs, ps_lsetregs): Likewise. + (ps_lgetfpregs, ps_lsetfpregs): Likewise. + * solib-svr4.c (enable_break): Likewise. + (svr4_relocate_main_executable): Likewise. + 2009-07-02 Ulrich Weigand * python/python-internal.h (struct language_defn): Declare. diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index 35114ce3051..29d959445dc 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -3495,8 +3495,8 @@ linux_nat_do_thread_registers (bfd *obfd, ptid_t ptid, gdb_gregset_t gregs; gdb_fpregset_t fpregs; unsigned long lwp = ptid_get_lwp (ptid); - struct regcache *regcache = get_thread_regcache (ptid); - struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct gdbarch *gdbarch = target_gdbarch; + struct regcache *regcache = get_thread_arch_regcache (ptid, gdbarch); const struct regset *regset; int core_regset_p; struct cleanup *old_chain; diff --git a/gdb/proc-service.c b/gdb/proc-service.c index dc0544054f9..d581b973f8d 100644 --- a/gdb/proc-service.c +++ b/gdb/proc-service.c @@ -258,7 +258,7 @@ ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset) struct regcache *regcache; inferior_ptid = BUILD_LWP (lwpid, ptid_get_pid (ph->ptid)); - regcache = get_thread_regcache (inferior_ptid); + regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch); target_fetch_registers (regcache, -1); fill_gregset (regcache, (gdb_gregset_t *) gregset, -1); @@ -277,7 +277,7 @@ ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, const prgregset_t gregset) struct regcache *regcache; inferior_ptid = BUILD_LWP (lwpid, ptid_get_pid (ph->ptid)); - regcache = get_thread_regcache (inferior_ptid); + regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch); supply_gregset (regcache, (const gdb_gregset_t *) gregset); target_store_registers (regcache, -1); @@ -297,7 +297,7 @@ ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, struct regcache *regcache; inferior_ptid = BUILD_LWP (lwpid, ptid_get_pid (ph->ptid)); - regcache = get_thread_regcache (inferior_ptid); + regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch); target_fetch_registers (regcache, -1); fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1); @@ -317,7 +317,7 @@ ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, struct regcache *regcache; inferior_ptid = BUILD_LWP (lwpid, ptid_get_pid (ph->ptid)); - regcache = get_thread_regcache (inferior_ptid); + regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch); supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset); target_store_registers (regcache, -1); diff --git a/gdb/regcache.c b/gdb/regcache.c index bbf58125966..2bea4e2cc2f 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -410,36 +410,60 @@ regcache_invalidate (struct regcache *regcache, int regnum) /* Global structure containing the current regcache. */ -/* FIXME: cagney/2002-05-11: The two global arrays registers[] and - deprecated_register_valid[] currently point into this structure. */ -static struct regcache *current_regcache; /* NOTE: this is a write-through cache. There is no "dirty" bit for recording if the register values have been changed (eg. by the user). Therefore all registers must be written back to the target when appropriate. */ -struct regcache *get_thread_regcache (ptid_t ptid) +struct regcache_list { - /* NOTE: uweigand/2007-05-05: We need to detect the thread's - current architecture at this point. */ - struct gdbarch *thread_gdbarch = current_gdbarch; + struct regcache *regcache; + struct regcache_list *next; +}; + +static struct regcache_list *current_regcache; + +struct regcache * +get_thread_arch_regcache (ptid_t ptid, struct gdbarch *gdbarch) +{ + struct regcache_list *list; + struct regcache *new_regcache; - if (current_regcache && ptid_equal (current_regcache->ptid, ptid) - && get_regcache_arch (current_regcache) == thread_gdbarch) - return current_regcache; + for (list = current_regcache; list; list = list->next) + if (ptid_equal (list->regcache->ptid, ptid) + && get_regcache_arch (list->regcache) == gdbarch) + return list->regcache; - if (current_regcache) - regcache_xfree (current_regcache); + new_regcache = regcache_xmalloc (gdbarch); + new_regcache->readonly_p = 0; + new_regcache->ptid = ptid; - current_regcache = regcache_xmalloc (thread_gdbarch); - current_regcache->readonly_p = 0; - current_regcache->ptid = ptid; + list = xmalloc (sizeof (struct regcache_list)); + list->regcache = new_regcache; + list->next = current_regcache; + current_regcache = list; - return current_regcache; + return new_regcache; } -struct regcache *get_current_regcache (void) +static ptid_t current_thread_ptid; +static struct gdbarch *current_thread_arch; + +struct regcache * +get_thread_regcache (ptid_t ptid) +{ + if (!current_thread_arch || !ptid_equal (current_thread_ptid, ptid)) + { + current_thread_ptid = ptid; + current_thread_arch = target_thread_architecture (ptid); + } + + return get_thread_arch_regcache (ptid, current_thread_arch); +} + +struct regcache * +get_current_regcache (void) { return get_thread_regcache (inferior_ptid); } @@ -458,9 +482,11 @@ regcache_observer_target_changed (struct target_ops *target) static void regcache_thread_ptid_changed (ptid_t old_ptid, ptid_t new_ptid) { - if (current_regcache != NULL - && ptid_equal (current_regcache->ptid, old_ptid)) - current_regcache->ptid = new_ptid; + struct regcache_list *list; + + for (list = current_regcache; list; list = list->next) + if (ptid_equal (list->regcache->ptid, old_ptid)) + list->regcache->ptid = new_ptid; } /* Low level examining and depositing of registers. @@ -477,11 +503,20 @@ regcache_thread_ptid_changed (ptid_t old_ptid, ptid_t new_ptid) void registers_changed (void) { - int i; + struct regcache_list *list, *next; + + for (list = current_regcache; list; list = next) + { + next = list->next; + regcache_xfree (list->regcache); + xfree (list); + } - regcache_xfree (current_regcache); current_regcache = NULL; + current_thread_ptid = null_ptid; + current_thread_arch = NULL; + /* Need to forget about any frames we have cached, too. */ reinit_frame_cache (); diff --git a/gdb/regcache.h b/gdb/regcache.h index 5f8ce750626..4a32602d16f 100644 --- a/gdb/regcache.h +++ b/gdb/regcache.h @@ -26,6 +26,7 @@ struct gdbarch; extern struct regcache *get_current_regcache (void); extern struct regcache *get_thread_regcache (ptid_t ptid); +extern struct regcache *get_thread_arch_regcache (ptid_t, struct gdbarch *); void regcache_xfree (struct regcache *regcache); struct cleanup *make_cleanup_regcache_xfree (struct regcache *regcache); diff --git a/gdb/sol-thread.c b/gdb/sol-thread.c index 512239eeafb..1b0489c8f62 100644 --- a/gdb/sol-thread.c +++ b/gdb/sol-thread.c @@ -918,7 +918,7 @@ ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset) old_chain = save_inferior_ptid (); inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid)); - regcache = get_thread_regcache (inferior_ptid); + regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch); target_fetch_registers (regcache, -1); fill_gregset (regcache, (gdb_gregset_t *) gregset, -1); @@ -940,7 +940,7 @@ ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, old_chain = save_inferior_ptid (); inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid)); - regcache = get_thread_regcache (inferior_ptid); + regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch); supply_gregset (regcache, (const gdb_gregset_t *) gregset); target_store_registers (regcache, -1); @@ -1048,7 +1048,7 @@ ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, old_chain = save_inferior_ptid (); inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid)); - regcache = get_thread_regcache (inferior_ptid); + regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch); target_fetch_registers (regcache, -1); fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1); @@ -1070,7 +1070,7 @@ ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, old_chain = save_inferior_ptid (); inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid)); - regcache = get_thread_regcache (inferior_ptid); + regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch); supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset); target_store_registers (regcache, -1); diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index 29ccbb6f0df..bb2cefc7ae7 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -1380,7 +1380,8 @@ enable_break (struct svr4_info *info) most cases. */ if (!load_addr_found) { - struct regcache *regcache = get_thread_regcache (inferior_ptid); + struct regcache *regcache + = get_thread_arch_regcache (inferior_ptid, target_gdbarch); load_addr = (regcache_read_pc (regcache) - exec_entry_point (tmp_bfd, tmp_bfd_target)); } @@ -1517,7 +1518,8 @@ static void svr4_relocate_main_executable (void) { asection *interp_sect; - struct regcache *regcache = get_thread_regcache (inferior_ptid); + struct regcache *regcache + = get_thread_arch_regcache (inferior_ptid, target_gdbarch); CORE_ADDR pc = regcache_read_pc (regcache); /* Decide if the objfile needs to be relocated. As indicated above, diff --git a/gdb/target.c b/gdb/target.c index ca94300db54..24497cb2a31 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -93,6 +93,9 @@ static LONGEST target_xfer_partial (struct target_ops *ops, void *readbuf, const void *writebuf, ULONGEST offset, LONGEST len); +static struct gdbarch *default_thread_architecture (struct target_ops *ops, + ptid_t ptid); + static void init_dummy_target (void); static struct target_ops debug_target; @@ -630,6 +633,7 @@ update_current_target (void) INHERIT (to_make_corefile_notes, t); /* Do not inherit to_get_thread_local_address. */ INHERIT (to_can_execute_reverse, t); + INHERIT (to_thread_architecture, t); /* Do not inherit to_read_description. */ INHERIT (to_get_ada_task_ptid, t); /* Do not inherit to_search_memory. */ @@ -770,6 +774,8 @@ update_current_target (void) de_fault (to_async_mask, (int (*) (int)) return_one); + de_fault (to_thread_architecture, + default_thread_architecture); current_target.to_read_description = NULL; de_fault (to_get_ada_task_ptid, (ptid_t (*) (long, long)) @@ -2448,6 +2454,12 @@ default_watchpoint_addr_within_range (struct target_ops *target, return addr >= start && addr < start + length; } +static struct gdbarch * +default_thread_architecture (struct target_ops *ops, ptid_t ptid) +{ + return target_gdbarch; +} + static int return_zero (void) { @@ -3236,6 +3248,19 @@ debug_to_notice_signals (ptid_t ptid) PIDGET (ptid)); } +static struct gdbarch * +debug_to_thread_architecture (struct target_ops *ops, ptid_t ptid) +{ + struct gdbarch *retval; + + retval = debug_target.to_thread_architecture (ops, ptid); + + fprintf_unfiltered (gdb_stdlog, "target_thread_architecture (%s) = %p [%s]\n", + target_pid_to_str (ptid), retval, + gdbarch_bfd_arch_info (retval)->printable_name); + return retval; +} + static void debug_to_stop (ptid_t ptid) { @@ -3309,6 +3334,7 @@ setup_target_debug (void) current_target.to_stop = debug_to_stop; current_target.to_rcmd = debug_to_rcmd; current_target.to_pid_to_exec_file = debug_to_pid_to_exec_file; + current_target.to_thread_architecture = debug_to_thread_architecture; } diff --git a/gdb/target.h b/gdb/target.h index 89d99bba029..2434a640735 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -542,6 +542,9 @@ struct target_ops simultaneously? */ int (*to_supports_multi_process) (void); + /* Determine current architecture of thread PTID. */ + struct gdbarch *(*to_thread_architecture) (struct target_ops *, ptid_t); + int to_magic; /* Need sub-structure for target machine related rather than comm related? */ @@ -1039,6 +1042,11 @@ extern char *normal_pid_to_str (ptid_t ptid); #define target_pid_to_exec_file(pid) \ (current_target.to_pid_to_exec_file) (pid) +/* Determine current architecture of thread PTID. */ + +#define target_thread_architecture(ptid) \ + (current_target.to_thread_architecture (¤t_target, ptid)) + /* * Iterator function for target memory regions. * Calls a callback function once for each memory region 'mapped' -- 2.30.2