* 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.
This commit is contained in:
parent
d452c4bcef
commit
c2250ad1c4
9 changed files with 134 additions and 34 deletions
|
@ -1,3 +1,31 @@
|
|||
2009-07-02 Ulrich Weigand <uweigand@de.ibm.com>
|
||||
|
||||
* 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 <uweigand@de.ibm.com>
|
||||
|
||||
* python/python-internal.h (struct language_defn): Declare.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
if (current_regcache && ptid_equal (current_regcache->ptid, ptid)
|
||||
&& get_regcache_arch (current_regcache) == thread_gdbarch)
|
||||
return current_regcache;
|
||||
static struct regcache_list *current_regcache;
|
||||
|
||||
if (current_regcache)
|
||||
regcache_xfree (current_regcache);
|
||||
struct regcache *
|
||||
get_thread_arch_regcache (ptid_t ptid, struct gdbarch *gdbarch)
|
||||
{
|
||||
struct regcache_list *list;
|
||||
struct regcache *new_regcache;
|
||||
|
||||
current_regcache = regcache_xmalloc (thread_gdbarch);
|
||||
current_regcache->readonly_p = 0;
|
||||
current_regcache->ptid = ptid;
|
||||
for (list = current_regcache; list; list = list->next)
|
||||
if (ptid_equal (list->regcache->ptid, ptid)
|
||||
&& get_regcache_arch (list->regcache) == gdbarch)
|
||||
return list->regcache;
|
||||
|
||||
return current_regcache;
|
||||
new_regcache = regcache_xmalloc (gdbarch);
|
||||
new_regcache->readonly_p = 0;
|
||||
new_regcache->ptid = ptid;
|
||||
|
||||
list = xmalloc (sizeof (struct regcache_list));
|
||||
list->regcache = new_regcache;
|
||||
list->next = current_regcache;
|
||||
current_regcache = list;
|
||||
|
||||
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 ();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
26
gdb/target.c
26
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
|
Loading…
Add table
Reference in a new issue