This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]