aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Buettner <kevinb@redhat.com>2007-04-27 22:34:56 +0000
committerKevin Buettner <kevinb@redhat.com>2007-04-27 22:34:56 +0000
commitace186d47aa03fdef613e60d013f594c74ddcbd4 (patch)
tree0096abe6aae22f6daea62a47f04f87584427f4f3
parent89a7ee67c58d0655d4ed0e4c5296482814f04d3c (diff)
downloadgdb-ace186d47aa03fdef613e60d013f594c74ddcbd4.zip
gdb-ace186d47aa03fdef613e60d013f594c74ddcbd4.tar.gz
gdb-ace186d47aa03fdef613e60d013f594c74ddcbd4.tar.bz2
* dwarf2expr.c (unsigned_address_type): Add forward declaration.
(dwarf2_read_address): Sign extend return address as required by target architecture.
-rw-r--r--gdb/ChangeLog6
-rw-r--r--gdb/dwarf2expr.c33
2 files changed, 36 insertions, 3 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index fc66469..8799fa6 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,11 @@
2007-04-27 Kevin Buettner <kevinb@redhat.com>
+ * dwarf2expr.c (unsigned_address_type): Add forward declaration.
+ (dwarf2_read_address): Sign extend return address as required by
+ target architecture.
+
+2007-04-27 Kevin Buettner <kevinb@redhat.com>
+
* solib-frv.c (lm_base): Bail out if the main executable has
not been relocated.
diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c
index 8464f3b..ad259f4 100644
--- a/gdb/dwarf2expr.c
+++ b/gdb/dwarf2expr.c
@@ -33,6 +33,7 @@
static void execute_stack_op (struct dwarf_expr_context *,
gdb_byte *, gdb_byte *);
+static struct type *unsigned_address_type (void);
/* Create a new context for the expression evaluator. */
@@ -205,9 +206,35 @@ dwarf2_read_address (gdb_byte *buf, gdb_byte *buf_end, int *bytes_read)
error (_("dwarf2_read_address: Corrupted DWARF expression."));
*bytes_read = TARGET_ADDR_BIT / TARGET_CHAR_BIT;
- /* NOTE: cagney/2003-05-22: This extract is assuming that a DWARF 2
- address is always unsigned. That may or may not be true. */
- result = extract_unsigned_integer (buf, TARGET_ADDR_BIT / TARGET_CHAR_BIT);
+
+ /* For most architectures, calling extract_unsigned_integer() alone
+ is sufficient for extracting an address. However, some
+ architectures (e.g. MIPS) use signed addresses and using
+ extract_unsigned_integer() will not produce a correct
+ result. Turning the unsigned integer into a value and then
+ decomposing that value as an address will cause
+ gdbarch_integer_to_address() to be invoked for those
+ architectures which require it. Thus, using value_as_address()
+ will produce the correct result for both types of architectures.
+
+ One concern regarding the use of values for this purpose is
+ efficiency. Obviously, these extra calls will take more time to
+ execute and creating a value takes more space, space which will
+ have to be garbage collected at a later time. If constructing
+ and then decomposing a value for this purpose proves to be too
+ inefficient, then gdbarch_integer_to_address() can be called
+ directly.
+
+ The use of `unsigned_address_type' in the code below refers to
+ the type of buf and has no bearing on the signedness of the
+ address being returned. */
+
+ result = value_as_address (value_from_longest
+ (unsigned_address_type (),
+ extract_unsigned_integer
+ (buf,
+ TARGET_ADDR_BIT / TARGET_CHAR_BIT)));
+
return result;
}