X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fregcache.c;h=715dd349ff2da017d42ab45ac1f6f9e98e47df25;hb=0219b378ea49d403ec68b0a1e36ad356930ab38d;hp=74ca6f069ff1d21ab1e25f4dc94ffbb9b3c22074;hpb=724b958c4168d40f59a35112c36ebf9e02c43d56;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/regcache.c b/gdb/regcache.c index 74ca6f069f..715dd349ff 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -1,7 +1,7 @@ /* Cache and manage the values of registers for GDB, the GNU debugger. Copyright (C) 1986, 1987, 1989, 1991, 1994, 1995, 1996, 1998, 2000, 2001, - 2002, 2004, 2007, 2008 Free Software Foundation, Inc. + 2002, 2004, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GDB. @@ -185,6 +185,11 @@ register_size (struct gdbarch *gdbarch, int regnum) struct regcache { struct regcache_descr *descr; + + /* The address space of this register cache (for registers where it + makes sense, like PC or SP). */ + struct address_space *aspace; + /* The register buffers. A read-only register cache can hold the full [0 .. gdbarch_num_regs + gdbarch_num_pseudo_regs) while a read/write register cache can only hold [0 .. gdbarch_num_regs). */ @@ -219,6 +224,7 @@ regcache_xmalloc (struct gdbarch *gdbarch) = XCALLOC (descr->sizeof_raw_registers, gdb_byte); regcache->register_valid_p = XCALLOC (descr->sizeof_raw_register_valid_p, gdb_byte); + regcache->aspace = NULL; regcache->readonly_p = 1; regcache->ptid = minus_one_ptid; return regcache; @@ -254,6 +260,12 @@ get_regcache_arch (const struct regcache *regcache) return regcache->descr->gdbarch; } +struct address_space * +get_regcache_aspace (const struct regcache *regcache) +{ + return regcache->aspace; +} + /* Return a pointer to register REGNUM's buffer cache. */ static gdb_byte * @@ -340,10 +352,14 @@ regcache_cpy (struct regcache *dst, struct regcache *src) { int i; gdb_byte *buf; + gdb_assert (src != NULL && dst != NULL); gdb_assert (src->descr->gdbarch == dst->descr->gdbarch); gdb_assert (src != dst); gdb_assert (src->readonly_p || dst->readonly_p); + + dst->aspace = src->aspace; + if (!src->readonly_p) regcache_save (dst, do_cooked_read, src); else if (!dst->readonly_p) @@ -362,6 +378,8 @@ regcache_cpy_no_passthrough (struct regcache *dst, struct regcache *src) move of data into the current regcache. Doing this would be silly - it would mean that valid_p would be completely invalid. */ gdb_assert (dst->readonly_p); + + dst->aspace = src->aspace; memcpy (dst->registers, src->registers, dst->descr->sizeof_raw_registers); memcpy (dst->register_valid_p, src->register_valid_p, dst->descr->sizeof_raw_register_valid_p); @@ -410,36 +428,62 @@ 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; + + for (list = current_regcache; list; list = list->next) + if (ptid_equal (list->regcache->ptid, ptid) + && get_regcache_arch (list->regcache) == gdbarch) + return list->regcache; + + new_regcache = regcache_xmalloc (gdbarch); + new_regcache->readonly_p = 0; + new_regcache->ptid = ptid; + new_regcache->aspace = target_thread_address_space (ptid); + gdb_assert (new_regcache->aspace != NULL); + + list = xmalloc (sizeof (struct regcache_list)); + list->regcache = new_regcache; + list->next = current_regcache; + current_regcache = list; + + return new_regcache; +} - current_regcache = regcache_xmalloc (thread_gdbarch); - current_regcache->readonly_p = 0; - current_regcache->ptid = ptid; +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 current_regcache; + return get_thread_arch_regcache (ptid, current_thread_arch); } -struct regcache *get_current_regcache (void) +struct regcache * +get_current_regcache (void) { return get_thread_regcache (inferior_ptid); } @@ -447,7 +491,7 @@ struct regcache *get_current_regcache (void) /* Observer for the target_changed event. */ -void +static void regcache_observer_target_changed (struct target_ops *target) { registers_changed (); @@ -458,9 +502,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 +523,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 (); @@ -535,8 +590,9 @@ regcache_raw_read_signed (struct regcache *regcache, int regnum, LONGEST *val) gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers); buf = alloca (regcache->descr->sizeof_register[regnum]); regcache_raw_read (regcache, regnum, buf); - (*val) = extract_signed_integer (buf, - regcache->descr->sizeof_register[regnum]); + (*val) = extract_signed_integer + (buf, regcache->descr->sizeof_register[regnum], + gdbarch_byte_order (regcache->descr->gdbarch)); } void @@ -548,8 +604,9 @@ regcache_raw_read_unsigned (struct regcache *regcache, int regnum, gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers); buf = alloca (regcache->descr->sizeof_register[regnum]); regcache_raw_read (regcache, regnum, buf); - (*val) = extract_unsigned_integer (buf, - regcache->descr->sizeof_register[regnum]); + (*val) = extract_unsigned_integer + (buf, regcache->descr->sizeof_register[regnum], + gdbarch_byte_order (regcache->descr->gdbarch)); } void @@ -559,7 +616,8 @@ regcache_raw_write_signed (struct regcache *regcache, int regnum, LONGEST val) gdb_assert (regcache != NULL); gdb_assert (regnum >=0 && regnum < regcache->descr->nr_raw_registers); buf = alloca (regcache->descr->sizeof_register[regnum]); - store_signed_integer (buf, regcache->descr->sizeof_register[regnum], val); + store_signed_integer (buf, regcache->descr->sizeof_register[regnum], + gdbarch_byte_order (regcache->descr->gdbarch), val); regcache_raw_write (regcache, regnum, buf); } @@ -571,7 +629,8 @@ regcache_raw_write_unsigned (struct regcache *regcache, int regnum, gdb_assert (regcache != NULL); gdb_assert (regnum >=0 && regnum < regcache->descr->nr_raw_registers); buf = alloca (regcache->descr->sizeof_register[regnum]); - store_unsigned_integer (buf, regcache->descr->sizeof_register[regnum], val); + store_unsigned_integer (buf, regcache->descr->sizeof_register[regnum], + gdbarch_byte_order (regcache->descr->gdbarch), val); regcache_raw_write (regcache, regnum, buf); } @@ -602,8 +661,9 @@ regcache_cooked_read_signed (struct regcache *regcache, int regnum, gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_cooked_registers); buf = alloca (regcache->descr->sizeof_register[regnum]); regcache_cooked_read (regcache, regnum, buf); - (*val) = extract_signed_integer (buf, - regcache->descr->sizeof_register[regnum]); + (*val) = extract_signed_integer + (buf, regcache->descr->sizeof_register[regnum], + gdbarch_byte_order (regcache->descr->gdbarch)); } void @@ -615,8 +675,9 @@ regcache_cooked_read_unsigned (struct regcache *regcache, int regnum, gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_cooked_registers); buf = alloca (regcache->descr->sizeof_register[regnum]); regcache_cooked_read (regcache, regnum, buf); - (*val) = extract_unsigned_integer (buf, - regcache->descr->sizeof_register[regnum]); + (*val) = extract_unsigned_integer + (buf, regcache->descr->sizeof_register[regnum], + gdbarch_byte_order (regcache->descr->gdbarch)); } void @@ -627,7 +688,8 @@ regcache_cooked_write_signed (struct regcache *regcache, int regnum, gdb_assert (regcache != NULL); gdb_assert (regnum >=0 && regnum < regcache->descr->nr_cooked_registers); buf = alloca (regcache->descr->sizeof_register[regnum]); - store_signed_integer (buf, regcache->descr->sizeof_register[regnum], val); + store_signed_integer (buf, regcache->descr->sizeof_register[regnum], + gdbarch_byte_order (regcache->descr->gdbarch), val); regcache_cooked_write (regcache, regnum, buf); } @@ -639,7 +701,8 @@ regcache_cooked_write_unsigned (struct regcache *regcache, int regnum, gdb_assert (regcache != NULL); gdb_assert (regnum >=0 && regnum < regcache->descr->nr_cooked_registers); buf = alloca (regcache->descr->sizeof_register[regnum]); - store_unsigned_integer (buf, regcache->descr->sizeof_register[regnum], val); + store_unsigned_integer (buf, regcache->descr->sizeof_register[regnum], + gdbarch_byte_order (regcache->descr->gdbarch), val); regcache_cooked_write (regcache, regnum, buf); } @@ -841,12 +904,6 @@ regcache_read_pc (struct regcache *regcache) return pc_val; } -CORE_ADDR -read_pc (void) -{ - return regcache_read_pc (get_current_regcache ()); -} - void regcache_write_pc (struct regcache *regcache, CORE_ADDR pc) { @@ -860,12 +917,10 @@ regcache_write_pc (struct regcache *regcache, CORE_ADDR pc) else internal_error (__FILE__, __LINE__, _("regcache_write_pc: Unable to update PC")); -} -void -write_pc (CORE_ADDR pc) -{ - regcache_write_pc (get_current_regcache (), pc); + /* Writing the PC (for instance, from "load") invalidates the + current frame. */ + reinit_frame_cache (); }