This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[rfc] Fix address vs. offset handling in DWARF-2 location lists
- From: "Ulrich Weigand" <uweigand at de dot ibm dot com>
- To: gdb-patches at sourceware dot org
- Date: Tue, 14 Jul 2009 16:58:32 +0200 (CEST)
- Subject: [rfc] Fix address vs. offset handling in DWARF-2 location lists
Hello,
find_location_expression uses dwarf2_read_address to retrieve the beginning
and ending address offsets in location list entries. This is not quite
correct -- those are not *addresses*, but simple offsets, and therefore
should *not* go through the target's integer_to_address routine. (This
causes problems with the Cell/B.E. combined debugger, where the SPU
architecture provides a non-trivial integer_to_address.)
However, in the special case of a base address selection entry, the
second item *is* an address, so it needs to be retrieved via
dwarf2_read_address.
This patch changes find_location_expression to distinguish the two cases
and use the appropriate routine for each situation.
Tested on powerpc64-linux with no regressions.
Any comments? I'd like to commit this within a couple of days ...
Bye,
Ulrich
ChangeLog:
* dwarf2loc.c (find_location_expression): Retrieve beginning and
ending address offsets in location list entries as integers,
not as addresses.
Index: gdb/dwarf2loc.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2loc.c,v
retrieving revision 1.60
diff -u -p -r1.60 dwarf2loc.c
--- gdb/dwarf2loc.c 2 Jul 2009 17:25:53 -0000 1.60
+++ gdb/dwarf2loc.c 10 Jul 2009 15:43:50 -0000
@@ -70,22 +70,28 @@ find_location_expression (struct dwarf2_
while (1)
{
- low = dwarf2_read_address (gdbarch, loc_ptr, buf_end, addr_size);
- loc_ptr += addr_size;
- high = dwarf2_read_address (gdbarch, loc_ptr, buf_end, addr_size);
- loc_ptr += addr_size;
+ if (buf_end - loc_ptr < 2 * addr_size)
+ error (_("find_location_expression: Corrupted DWARF expression."));
- /* An end-of-list entry. */
- if (low == 0 && high == 0)
- return NULL;
+ low = extract_unsigned_integer (loc_ptr, addr_size, byte_order);
+ loc_ptr += addr_size;
/* A base-address-selection entry. */
- if ((low & base_mask) == base_mask)
+ if (low == base_mask)
{
- base_address = high;
+ base_address = dwarf2_read_address (gdbarch,
+ loc_ptr, buf_end, addr_size);
+ loc_ptr += addr_size;
continue;
}
+ high = extract_unsigned_integer (loc_ptr, addr_size, byte_order);
+ loc_ptr += addr_size;
+
+ /* An end-of-list entry. */
+ if (low == 0 && high == 0)
+ return NULL;
+
/* Otherwise, a location expression entry. */
low += base_address;
high += base_address;
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com