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] Eliminate implicit current_gdbarch use in dwarf2_read_address


Hello,

the DWARF-2 symbol readers are nearly fully free of references to
the global current_gdbarch by now.  However, there is one remaining
reference that is somewhat hidden: dwarf2_read_address reads an
address by converting the data to a value object and then back to
a CORE_ADDR via value_as_address.

Not only is this somewhat wasteful (as the comment notes), but
it relies on value_as_address calling the appropriate version of
gdbarch_integer_to_address to perform the arch-specific conversion
that is the real goal of this mechanism.

However, value_as_address simply uses current_gdbarch.  This causes
actual problems for the combined Cell debugger right now.  

In the end, the value infrastructure will have to care about
architecture settings.  For now, however, I've simply changed
dwarf2_read_address to directly call gdbarch_integer_to_address
with the appropriate gdbarch.  This seems to be preferable anyway
to save the overhead of allocating a value object.

In order to be able to pass in a gdbarch value from its call sites
in execute_stack_op, I had to add a gdbarch to struct dwarf_expr_context.
Otherwise the choice of architecture is relatively straightforward;
for regular DWARF-2 decoding the per-objfile architecture is used,
while DWARF-2 CFI operations use the per-frame architecture.

Any comments on this approach?

Tested on powerpc-linux, powerpc64-linux, and spu-elf.

Bye,
Ulrich



ChangeLog:

	* dwarf2expr.h (dwarf2_read_address): Add gdbarch argument.
	* dwarf2expr.c (dwarf2_read_address): Add gdbarch argument.
	Call gdbarch_integer_to_address directly instead of converting
	to value and back.  Update comment.
	(execute_stack_op): Update call site.
	* dwarf2loc.c (find_location_expression): Likewise.
	(locexpr_describe_location): Update

	* dwarf2expr.h (struct dwarf_expr_context): Add gdbarch member.
	* dwarf2-frame.c (execute_stack_op): Initialize ctx->gdbarch.
	* dwarf2loc. (dwarf2_evaluate_loc_desc): Likewise.
	(dwarf2_loc_desc_needs_frame): Likewise.


diff -urNp src-orig/gdb/dwarf2expr.c src/gdb/dwarf2expr.c
--- src-orig/gdb/dwarf2expr.c	2008-06-05 20:25:30.000000000 +0200
+++ src/gdb/dwarf2expr.c	2008-08-23 20:53:03.856290902 +0200
@@ -204,7 +204,8 @@ read_sleb128 (gdb_byte *buf, gdb_byte *b
    doesn't extend past BUF_END.  */
 
 CORE_ADDR
-dwarf2_read_address (gdb_byte *buf, gdb_byte *buf_end, int addr_size)
+dwarf2_read_address (struct gdbarch *gdbarch, gdb_byte *buf,
+		     gdb_byte *buf_end, int addr_size)
 {
   CORE_ADDR result;
 
@@ -215,28 +216,18 @@ dwarf2_read_address (gdb_byte *buf, gdb_
      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.
+     result.  Make sure we invoke gdbarch_integer_to_address()
+     for those architectures which require it.
 
      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 (addr_size),
-			       extract_unsigned_integer (buf, addr_size)));
-  return result;
+  if (gdbarch_integer_to_address_p (gdbarch))
+    return gdbarch_integer_to_address
+	     (gdbarch, unsigned_address_type (addr_size), buf);
+
+  return extract_unsigned_integer (buf, addr_size);
 }
 
 /* Return the type of an address of size ADDR_SIZE,
@@ -339,7 +330,8 @@ execute_stack_op (struct dwarf_expr_cont
 	  break;
 
 	case DW_OP_addr:
-	  result = dwarf2_read_address (op_ptr, op_end, ctx->addr_size);
+	  result = dwarf2_read_address (ctx->gdbarch,
+					op_ptr, op_end, ctx->addr_size);
 	  op_ptr += ctx->addr_size;
 	  break;
 
@@ -559,7 +551,8 @@ execute_stack_op (struct dwarf_expr_cont
 	      {
 		gdb_byte *buf = alloca (ctx->addr_size);
 		(ctx->read_mem) (ctx->baton, buf, result, ctx->addr_size);
-		result = dwarf2_read_address (buf, buf + ctx->addr_size,
+		result = dwarf2_read_address (ctx->gdbarch,
+					      buf, buf + ctx->addr_size,
 					      ctx->addr_size);
 	      }
 	      break;
@@ -569,7 +562,8 @@ execute_stack_op (struct dwarf_expr_cont
 		int addr_size = *op_ptr++;
 		gdb_byte *buf = alloca (addr_size);
 		(ctx->read_mem) (ctx->baton, buf, result, addr_size);
-		result = dwarf2_read_address (buf, buf + addr_size,
+		result = dwarf2_read_address (ctx->gdbarch,
+					      buf, buf + addr_size,
 					      addr_size);
 	      }
 	      break;
diff -urNp src-orig/gdb/dwarf2expr.h src/gdb/dwarf2expr.h
--- src-orig/gdb/dwarf2expr.h	2008-03-18 20:40:47.000000000 +0100
+++ src/gdb/dwarf2expr.h	2008-08-23 20:52:12.032870533 +0200
@@ -34,6 +34,9 @@ struct dwarf_expr_context
      number of elements allocated to the stack.  */
   int stack_len, stack_allocated;
 
+  /* Target architecture to use for address operations.  */
+  struct gdbarch *gdbarch;
+
   /* Target address size in bytes.  */
   int addr_size;
 
@@ -138,7 +141,7 @@ CORE_ADDR dwarf_expr_fetch (struct dwarf
 
 gdb_byte *read_uleb128 (gdb_byte *buf, gdb_byte *buf_end, ULONGEST * r);
 gdb_byte *read_sleb128 (gdb_byte *buf, gdb_byte *buf_end, LONGEST * r);
-CORE_ADDR dwarf2_read_address (gdb_byte *buf, gdb_byte *buf_end,
-			       int addr_size);
+CORE_ADDR dwarf2_read_address (struct gdbarch *gdbarch, gdb_byte *buf,
+			       gdb_byte *buf_end, int addr_size);
 
 #endif /* dwarf2expr.h */
diff -urNp src-orig/gdb/dwarf2-frame.c src/gdb/dwarf2-frame.c
--- src-orig/gdb/dwarf2-frame.c	2008-07-15 20:40:03.000000000 +0200
+++ src/gdb/dwarf2-frame.c	2008-08-23 20:49:13.786286068 +0200
@@ -348,6 +348,7 @@ execute_stack_op (gdb_byte *exp, ULONGES
   CORE_ADDR result;
 
   ctx = new_dwarf_expr_context ();
+  ctx->gdbarch = get_frame_arch (this_frame);
   ctx->addr_size = addr_size;
   ctx->baton = this_frame;
   ctx->read_reg = read_reg;
diff -urNp src-orig/gdb/dwarf2loc.c src/gdb/dwarf2loc.c
--- src-orig/gdb/dwarf2loc.c	2008-05-04 14:44:16.000000000 +0200
+++ src/gdb/dwarf2loc.c	2008-08-23 20:49:04.826239865 +0200
@@ -55,6 +55,7 @@ find_location_expression (struct dwarf2_
   gdb_byte *loc_ptr, *buf_end;
   int length;
   struct objfile *objfile = dwarf2_per_cu_objfile (baton->per_cu);
+  struct gdbarch *gdbarch = get_objfile_arch (objfile);
   unsigned int addr_size = dwarf2_per_cu_addr_size (baton->per_cu);
   CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
   /* Adjust base_address for relocatable objects.  */
@@ -67,9 +68,9 @@ find_location_expression (struct dwarf2_
 
   while (1)
     {
-      low = dwarf2_read_address (loc_ptr, buf_end, addr_size);
+      low = dwarf2_read_address (gdbarch, loc_ptr, buf_end, addr_size);
       loc_ptr += addr_size;
-      high = dwarf2_read_address (loc_ptr, buf_end, addr_size);
+      high = dwarf2_read_address (gdbarch, loc_ptr, buf_end, addr_size);
       loc_ptr += addr_size;
 
       /* An end-of-list entry.  */
@@ -215,6 +216,7 @@ dwarf2_evaluate_loc_desc (struct symbol 
   baton.objfile = dwarf2_per_cu_objfile (per_cu);
 
   ctx = new_dwarf_expr_context ();
+  ctx->gdbarch = get_objfile_arch (baton.objfile);
   ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
   ctx->baton = &baton;
   ctx->read_reg = dwarf_expr_read_reg;
@@ -336,6 +338,7 @@ dwarf2_loc_desc_needs_frame (gdb_byte *d
   baton.needs_frame = 0;
 
   ctx = new_dwarf_expr_context ();
+  ctx->gdbarch = get_objfile_arch (dwarf2_per_cu_objfile (per_cu));
   ctx->addr_size = dwarf2_per_cu_addr_size (per_cu);
   ctx->baton = &baton;
   ctx->read_reg = needs_frame_read_reg;
@@ -492,7 +495,9 @@ locexpr_describe_location (struct symbol
     if (dlbaton->data[0] == DW_OP_addr)
       {
 	struct objfile *objfile = dwarf2_per_cu_objfile (dlbaton->per_cu);
-	CORE_ADDR offset = dwarf2_read_address (&dlbaton->data[1],
+	struct gdbarch *gdbarch = get_objfile_arch (objfile);
+	CORE_ADDR offset = dwarf2_read_address (gdbarch,
+						&dlbaton->data[1],
 						&dlbaton->data[dlbaton->size - 1],
 						addr_size);
 	fprintf_filtered (stream, 
-- 
  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]