Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [RFC] DWARF 2 address size != pointer size
@ 2006-05-10 18:24 Fred Fish
  2006-05-11 22:44 ` Jim Blandy
  2006-05-12 19:57 ` Mark Kettenis
  0 siblings, 2 replies; 8+ messages in thread
From: Fred Fish @ 2006-05-10 18:24 UTC (permalink / raw)
  To: gdb-patches; +Cc: fnf

For at least one target, MIPS using the o64 ABI with -mlong64, the
target DWARF2 address size used in the DWARF info (32 bit) is not the
same as the target pointer size (64 bit).  For example, below are some
fragments from dumping the DWARF info for a simple test case:

  Compilation Unit @ 0:
   Length:        175
   Version:       2
   Abbrev Offset: 0
   Pointer Size:  4	
 <1><91>: Abbrev Number: 3 (DW_TAG_base_type)
     DW_AT_name        : long int
     DW_AT_byte_size   : 8
 <1><b0>: Abbrev Number: 4 (DW_TAG_pointer_type)
     DW_AT_byte_size   : 8

Note that the header records the address size as 4, which is the
number of bytes written to the DWARF info when writing addresses, but
that the target pointer size is 8.

Currently gdb computes the DWARF info address size as:

	TARGET_ADDR_BIT / TARGET_CHAR_BIT

Given that the address size is actually recorded in the compilation
unit header, I believe the best solution would be to use that recorded
value somehow.  I spent a couple days looking for an easy way to tie
the address size to DWARF expressions that were recorded for later
evaluation, but didn't come up with anything clean enough to submit.

Another way to divorce the DWARF address size from the TARGET_ADDR_BIT
is to add another gdbarch paramter, accessed as TARGET_DWARF_ADDR_BIT.
I've attached a patch that does that.  It's simple, but not my first
choice for solving the problem.

Comments?

-Fred

============================================================================

2006-05-10  Fred Fish  <fnf@specifix.com>
 
	* gdbarch.sh: Add and document TARGET_DWARF_ADDR_BIT.
	* gdbarch.c: Regenerated.
	* gdbarch.h: Regenerated.
	* mips-tdep.c (mips_find_long_section): New function.
	(mips_find_pointer_section): New function.
	(mips_find_float_section): New function.
	(mips_gdbarch_init): Add long_bit and ptr_bit local variables.
	Call bfd_map_over_sections with mips_find_float_section,
	mips_find_long section, and mips_find_pointer_section.
	Call set_gdbarch_dwarf_addr_bit to get 32 bit DWARF addresses
	for MIPS_ABI_O64 and 64 bit DWARF addresses for MIPS_ABI_N64.
	* dwarf2expr.c (dwarf2_read_address): Replace TARGET_ADDR_BIT with
	TARGET_DWARF_ADDR_BIT.
	(unsigned_address_type): Ditto.
	(signed_address_type): Ditto.
	(execute_stack_op): Ditto.
	* dwarf2loc.c (find_location_expression):  Replace TARGET_ADDR_BIT with
	TARGET_DWARF_ADDR_BIT.
	* dwarf2read.c (read_comp_unit_head): Call set_gdbarch_dwarf_addr_bit
	with value computed from address size read from header.


Index: gdb/gdb/dwarf2expr.c
===================================================================
RCS file: /cvsroots/specifix/gnusense/gdb/gdb/dwarf2expr.c,v
retrieving revision 1.1.1.5
diff -u -p -r1.1.1.5 dwarf2expr.c
--- gdb/gdb/dwarf2expr.c	22 Dec 2005 01:56:13 -0000	1.1.1.5
+++ gdb/gdb/dwarf2expr.c	3 May 2006 18:56:10 -0000
@@ -201,13 +201,13 @@ dwarf2_read_address (gdb_byte *buf, gdb_
 {
   CORE_ADDR result;
 
-  if (buf_end - buf < TARGET_ADDR_BIT / TARGET_CHAR_BIT)
+  if (buf_end - buf < TARGET_DWARF_ADDR_BIT / TARGET_CHAR_BIT)
     error (_("dwarf2_read_address: Corrupted DWARF expression."));
 
-  *bytes_read = TARGET_ADDR_BIT / TARGET_CHAR_BIT;
+  *bytes_read = TARGET_DWARF_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);
+  result = extract_unsigned_integer (buf, TARGET_DWARF_ADDR_BIT / TARGET_CHAR_BIT);
   return result;
 }
 
@@ -216,7 +216,7 @@ dwarf2_read_address (gdb_byte *buf, gdb_
 static struct type *
 unsigned_address_type (void)
 {
-  switch (TARGET_ADDR_BIT / TARGET_CHAR_BIT)
+  switch (TARGET_DWARF_ADDR_BIT / TARGET_CHAR_BIT)
     {
     case 2:
       return builtin_type_uint16;
@@ -235,7 +235,7 @@ unsigned_address_type (void)
 static struct type *
 signed_address_type (void)
 {
-  switch (TARGET_ADDR_BIT / TARGET_CHAR_BIT)
+  switch (TARGET_DWARF_ADDR_BIT / TARGET_CHAR_BIT)
     {
     case 2:
       return builtin_type_int16;
@@ -520,13 +520,13 @@ execute_stack_op (struct dwarf_expr_cont
 	    {
 	    case DW_OP_deref:
 	      {
-		gdb_byte *buf = alloca (TARGET_ADDR_BIT / TARGET_CHAR_BIT);
+		gdb_byte *buf = alloca (TARGET_DWARF_ADDR_BIT / TARGET_CHAR_BIT);
 		int bytes_read;
 
 		(ctx->read_mem) (ctx->baton, buf, result,
-				 TARGET_ADDR_BIT / TARGET_CHAR_BIT);
+				 TARGET_DWARF_ADDR_BIT / TARGET_CHAR_BIT);
 		result = dwarf2_read_address (buf,
-					      buf + (TARGET_ADDR_BIT
+					      buf + (TARGET_DWARF_ADDR_BIT
 						     / TARGET_CHAR_BIT),
 					      &bytes_read);
 	      }
@@ -534,12 +534,12 @@ execute_stack_op (struct dwarf_expr_cont
 
 	    case DW_OP_deref_size:
 	      {
-		gdb_byte *buf = alloca (TARGET_ADDR_BIT / TARGET_CHAR_BIT);
+		gdb_byte *buf = alloca (TARGET_DWARF_ADDR_BIT / TARGET_CHAR_BIT);
 		int bytes_read;
 
 		(ctx->read_mem) (ctx->baton, buf, result, *op_ptr++);
 		result = dwarf2_read_address (buf,
-					      buf + (TARGET_ADDR_BIT
+					      buf + (TARGET_DWARF_ADDR_BIT
 						     / TARGET_CHAR_BIT),
 					      &bytes_read);
 	      }
Index: gdb/gdb/gdbarch.c
===================================================================
RCS file: /cvsroots/specifix/gnusense/gdb/gdb/gdbarch.c,v
retrieving revision 1.1.1.5
diff -u -p -r1.1.1.5 gdbarch.c
--- gdb/gdb/gdbarch.c	22 Dec 2005 01:56:27 -0000	1.1.1.5
+++ gdb/gdb/gdbarch.c	3 May 2006 18:35:19 -0000
@@ -142,6 +142,7 @@ struct gdbarch
   const struct floatformat * long_double_format;
   int ptr_bit;
   int addr_bit;
+  int dwarf_addr_bit;
   int bfd_vma_bit;
   int char_signed;
   gdbarch_read_pc_ftype *read_pc;
@@ -268,6 +269,7 @@ struct gdbarch startup_gdbarch =
   0,  /* long_double_format */
   8 * sizeof (void*),  /* ptr_bit */
   8 * sizeof (void*),  /* addr_bit */
+  8 * sizeof (void*),  /* dwarf_addr_bit */
   8 * sizeof (void*),  /* bfd_vma_bit */
   1,  /* char_signed */
   0,  /* read_pc */
@@ -406,6 +408,7 @@ gdbarch_alloc (const struct gdbarch_info
   current_gdbarch->double_bit = 8*TARGET_CHAR_BIT;
   current_gdbarch->long_double_bit = 8*TARGET_CHAR_BIT;
   current_gdbarch->ptr_bit = TARGET_INT_BIT;
+  current_gdbarch->dwarf_addr_bit = TARGET_PTR_BIT;
   current_gdbarch->bfd_vma_bit = TARGET_ARCHITECTURE->bits_per_address;
   current_gdbarch->char_signed = -1;
   current_gdbarch->write_pc = generic_target_write_pc;
@@ -524,6 +527,7 @@ verify_gdbarch (struct gdbarch *current_
   /* Skip verify of ptr_bit, invalid_p == 0 */
   if (current_gdbarch->addr_bit == 0)
     current_gdbarch->addr_bit = TARGET_PTR_BIT;
+  /* Skip verify of dwarf_addr_bit, invalid_p == 0 */
   /* Skip verify of bfd_vma_bit, invalid_p == 0 */
   if (current_gdbarch->char_signed == -1)
     current_gdbarch->char_signed = 1;
@@ -1018,6 +1022,14 @@ gdbarch_dump (struct gdbarch *current_gd
   fprintf_unfiltered (file,
                       "gdbarch_dump: dwarf2_reg_to_regnum = <0x%lx>\n",
                       (long) current_gdbarch->dwarf2_reg_to_regnum);
+#ifdef TARGET_DWARF_ADDR_BIT
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: TARGET_DWARF_ADDR_BIT # %s\n",
+                      XSTRING (TARGET_DWARF_ADDR_BIT));
+#endif
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: dwarf_addr_bit = %s\n",
+                      paddr_d (current_gdbarch->dwarf_addr_bit));
 #ifdef DWARF_REG_TO_REGNUM
   fprintf_unfiltered (file,
                       "gdbarch_dump: %s # %s\n",
@@ -1871,6 +1883,23 @@ set_gdbarch_addr_bit (struct gdbarch *gd
 }
 
 int
+gdbarch_dwarf_addr_bit (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  /* Skip verify of dwarf_addr_bit, invalid_p == 0 */
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_dwarf_addr_bit called\n");
+  return gdbarch->dwarf_addr_bit;
+}
+
+void
+set_gdbarch_dwarf_addr_bit (struct gdbarch *gdbarch,
+                            int dwarf_addr_bit)
+{
+  gdbarch->dwarf_addr_bit = dwarf_addr_bit;
+}
+
+int
 gdbarch_bfd_vma_bit (struct gdbarch *gdbarch)
 {
   gdb_assert (gdbarch != NULL);
Index: gdb/gdb/gdbarch.h
===================================================================
RCS file: /cvsroots/specifix/gnusense/gdb/gdb/gdbarch.h,v
retrieving revision 1.1.1.5
diff -u -p -r1.1.1.5 gdbarch.h
--- gdb/gdb/gdbarch.h	22 Dec 2005 01:56:16 -0000	1.1.1.5
+++ gdb/gdb/gdbarch.h	3 May 2006 18:53:08 -0000
@@ -200,6 +200,12 @@ extern void set_gdbarch_long_double_form
    If TARGET_PTR_BIT and TARGET_ADDR_BIT are different, you'll probably
    also need to set POINTER_TO_ADDRESS and ADDRESS_TO_POINTER as well.
   
+   For at least one system (MIPS) the size of addresses written to the
+   DWARF debug info changes based on the ABI, and may be different than
+   what might be expected by examining TARGET_ADDR_BIT.  In particular,
+   using -mlong64, it is possible to get 64 bit pointers while still
+   writing out 32 bit addresses in the DWARF info.
+  
    ptr_bit is the size of a pointer on the target */
 
 extern int gdbarch_ptr_bit (struct gdbarch *gdbarch);
@@ -222,6 +228,17 @@ extern void set_gdbarch_addr_bit (struct
 #define TARGET_ADDR_BIT (gdbarch_addr_bit (current_gdbarch))
 #endif
 
+/* dwarf_addr_bit is the size of a target address as represented in the DWARF debug information */
+
+extern int gdbarch_dwarf_addr_bit (struct gdbarch *gdbarch);
+extern void set_gdbarch_dwarf_addr_bit (struct gdbarch *gdbarch, int dwarf_addr_bit);
+#if !defined (GDB_TM_FILE) && defined (TARGET_DWARF_ADDR_BIT)
+#error "Non multi-arch definition of TARGET_DWARF_ADDR_BIT"
+#endif
+#if !defined (TARGET_DWARF_ADDR_BIT)
+#define TARGET_DWARF_ADDR_BIT (gdbarch_dwarf_addr_bit (current_gdbarch))
+#endif
+
 /* Number of bits in a BFD_VMA for the target object file format. */
 
 extern int gdbarch_bfd_vma_bit (struct gdbarch *gdbarch);
Index: gdb/gdb/gdbarch.sh
===================================================================
RCS file: /cvsroots/specifix/gnusense/gdb/gdb/gdbarch.sh,v
retrieving revision 1.1.1.5
diff -u -p -r1.1.1.5 gdbarch.sh
--- gdb/gdb/gdbarch.sh	22 Dec 2005 01:56:10 -0000	1.1.1.5
+++ gdb/gdb/gdbarch.sh	3 May 2006 18:52:41 -0000
@@ -404,10 +404,18 @@ v:TARGET_LONG_DOUBLE_FORMAT:const struct
 # If TARGET_PTR_BIT and TARGET_ADDR_BIT are different, you'll probably
 # also need to set POINTER_TO_ADDRESS and ADDRESS_TO_POINTER as well.
 #
+# For at least one system (MIPS) the size of addresses written to the
+# DWARF debug info changes based on the ABI, and may be different than
+# what might be expected by examining TARGET_ADDR_BIT.  In particular,
+# using -mlong64, it is possible to get 64 bit pointers while still
+# writing out 32 bit addresses in the DWARF info.
+#
 # ptr_bit is the size of a pointer on the target
 v:TARGET_PTR_BIT:int:ptr_bit:::8 * sizeof (void*):TARGET_INT_BIT::0
 # addr_bit is the size of a target address as represented in gdb
 v:TARGET_ADDR_BIT:int:addr_bit:::8 * sizeof (void*):0:TARGET_PTR_BIT:
+# dwarf_addr_bit is the size of a target address as represented in the DWARF debug information
+v:TARGET_DWARF_ADDR_BIT:int:dwarf_addr_bit:::8 * sizeof (void*):TARGET_PTR_BIT::0
 # Number of bits in a BFD_VMA for the target object file format.
 v:TARGET_BFD_VMA_BIT:int:bfd_vma_bit:::8 * sizeof (void*):TARGET_ARCHITECTURE->bits_per_address::0
 #
Index: gdb/gdb/mips-tdep.c
===================================================================
RCS file: /cvsroots/specifix/gnusense/gdb/gdb/mips-tdep.c,v
retrieving revision 1.1.1.5.4.4
diff -u -p -r1.1.1.5.4.4 mips-tdep.c
--- gdb/gdb/mips-tdep.c	2 May 2006 13:15:41 -0000	1.1.1.5.4.4
+++ gdb/gdb/mips-tdep.c	3 May 2006 21:04:04 -0000
@@ -4944,6 +4987,7 @@ mips_gdbarch_init (struct gdbarch_info i
       tdep->default_mask_address_p = 0;
       set_gdbarch_long_bit (gdbarch, 32);
       set_gdbarch_ptr_bit (gdbarch, 32);
+      set_gdbarch_dwarf_addr_bit (gdbarch, 32);
       set_gdbarch_long_long_bit (gdbarch, 64);
       break;
     case MIPS_ABI_EABI32:
@@ -4987,6 +5031,7 @@ mips_gdbarch_init (struct gdbarch_info i
       tdep->default_mask_address_p = 0;
       set_gdbarch_long_bit (gdbarch, 64);
       set_gdbarch_ptr_bit (gdbarch, 64);
+      set_gdbarch_dwarf_addr_bit (gdbarch, 64);
       set_gdbarch_long_long_bit (gdbarch, 64);
       set_gdbarch_long_double_bit (gdbarch, 128);
       set_gdbarch_long_double_format (gdbarch,
Index: dwarf2loc.c
===================================================================
RCS file: /cvsroots/specifix/gnusense/gdb/gdb/dwarf2loc.c,v
retrieving revision 1.1.1.5
diff -u -p -r1.1.1.5 dwarf2loc.c
--- dwarf2loc.c	22 Dec 2005 01:56:10 -0000	1.1.1.5
+++ dwarf2loc.c	10 May 2006 15:26:35 -0000
@@ -59,7 +59,7 @@ find_location_expression (struct dwarf2_
   CORE_ADDR low, high;
   gdb_byte *loc_ptr, *buf_end;
   int length;
-  unsigned int addr_size = TARGET_ADDR_BIT / TARGET_CHAR_BIT;
+  unsigned int addr_size = TARGET_DWARF_ADDR_BIT / TARGET_CHAR_BIT;
   CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
   /* Adjust base_address for relocatable objects.  */
   CORE_ADDR base_offset = ANOFFSET (baton->objfile->section_offsets,
Index: dwarf2read.c
===================================================================
RCS file: /cvsroots/specifix/gnusense/gdb/gdb/dwarf2read.c,v
retrieving revision 1.1.1.5
diff -u -p -r1.1.1.5 dwarf2read.c
--- dwarf2read.c	22 Dec 2005 01:56:25 -0000	1.1.1.5
+++ dwarf2read.c	10 May 2006 15:32:55 -0000
@@ -1278,6 +1278,8 @@ read_comp_unit_head (struct comp_unit_he
                                           &bytes_read);
   info_ptr += bytes_read;
   cu_header->addr_size = read_1_byte (abfd, info_ptr);
+  /* FIXME: This assumes that all compilation units will have the same addr_size */
+  set_gdbarch_dwarf_addr_bit (current_gdbarch, cu_header->addr_size * TARGET_CHAR_BIT);
   info_ptr += 1;
   signed_addr = bfd_get_sign_extend_vma (abfd);
   if (signed_addr < 0)


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC] DWARF 2 address size != pointer size
  2006-05-10 18:24 [RFC] DWARF 2 address size != pointer size Fred Fish
@ 2006-05-11 22:44 ` Jim Blandy
  2006-05-12 14:21   ` Fred Fish
  2006-05-12 19:57 ` Mark Kettenis
  1 sibling, 1 reply; 8+ messages in thread
From: Jim Blandy @ 2006-05-11 22:44 UTC (permalink / raw)
  To: fnf; +Cc: gdb-patches


Fred Fish <fnf@specifix.com> writes:
> For at least one target, MIPS using the o64 ABI with -mlong64, the
> target DWARF2 address size used in the DWARF info (32 bit) is not the
> same as the target pointer size (64 bit).  For example, below are some
> fragments from dumping the DWARF info for a simple test case:
>
>   Compilation Unit @ 0:
>    Length:        175
>    Version:       2
>    Abbrev Offset: 0
>    Pointer Size:  4	
>  <1><91>: Abbrev Number: 3 (DW_TAG_base_type)
>      DW_AT_name        : long int
>      DW_AT_byte_size   : 8
>  <1><b0>: Abbrev Number: 4 (DW_TAG_pointer_type)
>      DW_AT_byte_size   : 8
>
> Note that the header records the address size as 4, which is the
> number of bytes written to the DWARF info when writing addresses, but
> that the target pointer size is 8.
>
> Currently gdb computes the DWARF info address size as:
>
> 	TARGET_ADDR_BIT / TARGET_CHAR_BIT
>
> Given that the address size is actually recorded in the compilation
> unit header, I believe the best solution would be to use that recorded
> value somehow.  I spent a couple days looking for an easy way to tie
> the address size to DWARF expressions that were recorded for later
> evaluation, but didn't come up with anything clean enough to submit.
>
> Another way to divorce the DWARF address size from the TARGET_ADDR_BIT
> is to add another gdbarch paramter, accessed as TARGET_DWARF_ADDR_BIT.
> I've attached a patch that does that.  It's simple, but not my first
> choice for solving the problem.
>
> Comments?

Technically, this isn't quite right, since each CU could potentially
have a different address size.  It's not a global property of the
debug info.

If I'm understanding the problem, I had a patch for this about a year
ago which I discarded because I found a simpler way to solve the
problem for the port I was working on.  But now that other people are
running into it too, I guess I made the wrong choice.  I think it's
actually a good idea because it provides more detailed information in
each symbol; I think that could be handy in other ways in the future.

Here's the patch; is it addressing the same thing yours does?  I'm not
sure it deals with frame info right, but I'm pretty sure the rest of
it is going in the right direction:

- dwarf2expr.c should definitely get the address size from the context
  (this was discussed when dwarf2expr.c was first added, I think).

- dwarf2loc.c should definitely be using psymtab pointers or some sort
  of Dwarf CU pointers for SYMBOL_LOCATION_BATON.

2005-04-07  Jim Blandy  <jimb@redhat.com>

	Include a pointer to the partial symbol table in the symbol
	batons, not to the objfile.
	* dwarf2loc.h (struct dwarf2_locexpr_baton, struct
	dwarf2_loclist_baton): New member 'psymtab', replacing 'objfile'.
	* dwarf2loc.c (dwarf2_evaluate_loc_desc): Expect a psymtab, not an
	objfile.  Store the psymtab's objfile in baton.
	(locexpr_read_variable, loclist_read_variable): Pass
	baton->psymtab to dwarf2_evaluate_loc_desc, not baton->objfile.
	(locexpr_describe_location): Get the file name for thread-local
	storage blocks from dlbaton->psymtab->objfile, instead of
	dlbaton->objfile.
	* dwarf2read.c (struct dwarf2_cu): New member: psymtab.
	(dwarf2_build_psymtabs_hard): Zero cu's psymtab pointer.
	(psymtab_to_symtab_1): Set cu's psymtab pointer.
	(dwarf2_symbol_mark_computed): Store the cu's psymtab in the
	batons we create for location expressions and location lists.

	Allow dwarf2loc.c to find a compilation unit's address size, given
	the psymtab for that compilation unit.
	* dwarf2loc.h (dwarf_psymtab_address_size): New function.
	* dwarf2read.c (struct dwarf2_pinfo): Add 'address_size' member.
	(dwarf2_build_psymtabs_hard): Zero it, since it shouldn't be used yet.
	(psymtab_to_symtab_1): Store the cu's address size in it, now that
	we're reading full symbols.
	(dwarf_psymtab_address_size): New function.

	Use the correct address size when parsing Dwarf 2 location lists,
	and evaluation DW_OP_deref and DW_OP_deref_size opcodes.
	* dwarf2expr.h (struct dwarf_expr_context): New member
	'address_size'.
	(dwarf2_read_address): Adjust prototype; see next change.
	* dwarf2expr.c (dwarf2_read_address): Take the address size as an
	argument, rather than returning the address size via a reference
	parameter.
	(unsigned_address_type, signed_address_type): Take a context as an
	argument, and use the address size it specifies.
	(execute_stack_op): Pass CTX's address size to dwarf2_read_address.
	Use it as the pointer size for DW_OP_deref and DW_OP_deref_size.
	Pass CTX to unsigned_address_type and signed_address_type.
	* dwarf2loc.h (dwarf_psymtab_address_size): New prototype.
	* dwarf2loc.c (find_location_expression): Use baton->psymtab's
	address size.
	(dwarf2_evaluate_loc_desc): Store PSYMTAB's address size in the
	context we're creating.
	(dwarf2_loc_desc_needs_frame): Store 1 as the address size in the
	context we're creating.  Our read_mem just returns zero anyway.
	(locexpr_describe_location): Use dlbaton's psymtab's address
	size to read DW_OP_GNU_push_tls_address's operand.
	* dwarf2-frame.c (size_of_encoded_value): Add forward declaration.
	(execute_stack_op, execute_cfa_program): Use
	size_of_encoded_value (DW_EH_PE_absptr) as the address size.

Index: gdb/dwarf2-frame.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/dwarf2-frame.c,v
retrieving revision 2.9
diff -c -p -r2.9 dwarf2-frame.c
*** gdb/dwarf2-frame.c	24 Feb 2005 17:03:54 -0000	2.9
--- gdb/dwarf2-frame.c	8 Apr 2005 06:09:21 -0000
*************** dwarf2_frame_state_free (void *p)
*** 202,207 ****
--- 202,209 ----
  
  /* Helper functions for execute_stack_op.  */
  
+ static unsigned int size_of_encoded_value (unsigned char encoding);
+ 
  static CORE_ADDR
  read_reg (void *baton, int reg)
  {
*************** execute_stack_op (unsigned char *exp, UL
*** 251,256 ****
--- 253,263 ----
    ctx->get_frame_base = no_get_frame_base;
    ctx->get_tls_address = no_get_tls_address;
  
+   /* This isn't really right, but the Dwarf spec doesn't say what
+      address size is correct to use for CFI, so this is a reasonable
+      guess.  */
+   ctx->address_size = size_of_encoded_value (DW_EH_PE_absptr);
+ 
    dwarf_expr_push (ctx, initial);
    dwarf_expr_eval (ctx, exp, len);
    result = dwarf_expr_fetch (ctx, 0);
*************** execute_cfa_program (unsigned char *insn
*** 301,307 ****
  	  switch (insn)
  	    {
  	    case DW_CFA_set_loc:
! 	      fs->pc = dwarf2_read_address (insn_ptr, insn_end, &bytes_read);
  	      insn_ptr += bytes_read;
  	      break;
  
--- 308,320 ----
  	  switch (insn)
  	    {
  	    case DW_CFA_set_loc:
! 	      /* This isn't really the right address size to use, but
! 		 the Dwarf spec doesn't say what address size is
! 		 correct to use for CFI, so this is a reasonable
! 		 guess.  */
! 	      fs->pc =
! 		dwarf2_read_address (insn_ptr, insn_end,
! 				     size_of_encoded_value (DW_EH_PE_absptr));
  	      insn_ptr += bytes_read;
  	      break;
  
Index: gdb/dwarf2expr.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/dwarf2expr.c,v
retrieving revision 2.10
diff -c -p -r2.10 dwarf2expr.c
*** gdb/dwarf2expr.c	4 Apr 2005 20:51:44 -0000	2.10
--- gdb/dwarf2expr.c	8 Apr 2005 06:09:21 -0000
*************** read_sleb128 (unsigned char *buf, unsign
*** 191,221 ****
    return buf;
  }
  
! /* Read an address from BUF, and verify that it doesn't extend past
!    BUF_END.  The address is returned, and *BYTES_READ is set to the
!    number of bytes read from BUF.  */
  
  CORE_ADDR
! dwarf2_read_address (unsigned char *buf, unsigned char *buf_end, int *bytes_read)
  {
    CORE_ADDR result;
  
!   if (buf_end - buf < TARGET_ADDR_BIT / TARGET_CHAR_BIT)
      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);
    return result;
  }
  
  /* Return the type of an address, for unsigned arithmetic.  */
  
  static struct type *
! unsigned_address_type (void)
  {
!   switch (TARGET_ADDR_BIT / TARGET_CHAR_BIT)
      {
      case 2:
        return builtin_type_uint16;
--- 191,221 ----
    return buf;
  }
  
! /* Read and return an ADDRESS_SIZE-byte address from BUF, and verify
!    that it doesn't extend past BUF_END.  */
  
  CORE_ADDR
! dwarf2_read_address (unsigned char *buf,
! 		     unsigned char *buf_end,
! 		     CORE_ADDR address_size)
  {
    CORE_ADDR result;
  
!   if (buf_end - buf < address_size)
      error ("dwarf2_read_address: Corrupted DWARF expression.");
  
    /* 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, address_size);
    return result;
  }
  
  /* Return the type of an address, for unsigned arithmetic.  */
  
  static struct type *
! unsigned_address_type (struct dwarf_expr_context *ctx)
  {
!   switch (ctx->address_size)
      {
      case 2:
        return builtin_type_uint16;
*************** unsigned_address_type (void)
*** 232,240 ****
  /* Return the type of an address, for signed arithmetic.  */
  
  static struct type *
! signed_address_type (void)
  {
!   switch (TARGET_ADDR_BIT / TARGET_CHAR_BIT)
      {
      case 2:
        return builtin_type_int16;
--- 232,240 ----
  /* Return the type of an address, for signed arithmetic.  */
  
  static struct type *
! signed_address_type (struct dwarf_expr_context *ctx)
  {
!   switch (ctx->address_size)
      {
      case 2:
        return builtin_type_int16;
*************** execute_stack_op (struct dwarf_expr_cont
*** 303,310 ****
  	  break;
  
  	case DW_OP_addr:
! 	  result = dwarf2_read_address (op_ptr, op_end, &bytes_read);
! 	  op_ptr += bytes_read;
  	  break;
  
  	case DW_OP_const1u:
--- 303,310 ----
  	  break;
  
  	case DW_OP_addr:
! 	  result = dwarf2_read_address (op_ptr, op_end, ctx->address_size);
! 	  op_ptr += ctx->address_size;
  	  break;
  
  	case DW_OP_const1u:
*************** execute_stack_op (struct dwarf_expr_cont
*** 519,546 ****
  	    {
  	    case DW_OP_deref:
  	      {
! 		char *buf = alloca (TARGET_ADDR_BIT / TARGET_CHAR_BIT);
! 		int bytes_read;
  
! 		(ctx->read_mem) (ctx->baton, buf, result,
! 				 TARGET_ADDR_BIT / TARGET_CHAR_BIT);
! 		result = dwarf2_read_address (buf,
! 					      buf + (TARGET_ADDR_BIT
! 						     / TARGET_CHAR_BIT),
! 					      &bytes_read);
  	      }
  	      break;
  
  	    case DW_OP_deref_size:
  	      {
! 		char *buf = alloca (TARGET_ADDR_BIT / TARGET_CHAR_BIT);
! 		int bytes_read;
  
  		(ctx->read_mem) (ctx->baton, buf, result, *op_ptr++);
! 		result = dwarf2_read_address (buf,
! 					      buf + (TARGET_ADDR_BIT
! 						     / TARGET_CHAR_BIT),
! 					      &bytes_read);
  	      }
  	      break;
  
--- 519,539 ----
  	    {
  	    case DW_OP_deref:
  	      {
! 		char *buf = alloca (ctx->address_size);
  
! 		(ctx->read_mem) (ctx->baton, buf, result, ctx->address_size);
! 		result = dwarf2_read_address (buf, buf + ctx->address_size,
! 					      ctx->address_size);
  	      }
  	      break;
  
  	    case DW_OP_deref_size:
  	      {
! 		char *buf = alloca (ctx->address_size);
  
  		(ctx->read_mem) (ctx->baton, buf, result, *op_ptr++);
! 		result = dwarf2_read_address (buf, buf + ctx->address_size,
! 					      ctx->address_size);
  	      }
  	      break;
  
*************** execute_stack_op (struct dwarf_expr_cont
*** 591,598 ****
  	    first = dwarf_expr_fetch (ctx, 0);
  	    dwarf_expr_pop (ctx);
  
! 	    val1 = value_from_longest (unsigned_address_type (), first);
! 	    val2 = value_from_longest (unsigned_address_type (), second);
  
  	    switch (op)
  	      {
--- 584,591 ----
  	    first = dwarf_expr_fetch (ctx, 0);
  	    dwarf_expr_pop (ctx);
  
! 	    val1 = value_from_longest (unsigned_address_type (ctx), first);
! 	    val2 = value_from_longest (unsigned_address_type (ctx), second);
  
  	    switch (op)
  	      {
*************** execute_stack_op (struct dwarf_expr_cont
*** 625,631 ****
                  break;
  	      case DW_OP_shra:
  		binop = BINOP_RSH;
! 		val1 = value_from_longest (signed_address_type (), first);
  		break;
  	      case DW_OP_xor:
  		binop = BINOP_BITWISE_XOR;
--- 618,624 ----
                  break;
  	      case DW_OP_shra:
  		binop = BINOP_RSH;
! 		val1 = value_from_longest (signed_address_type (ctx), first);
  		break;
  	      case DW_OP_xor:
  		binop = BINOP_BITWISE_XOR;
Index: gdb/dwarf2expr.h
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/dwarf2expr.h,v
retrieving revision 2.4
diff -c -p -r2.4 dwarf2expr.h
*** gdb/dwarf2expr.h	4 Apr 2005 20:51:44 -0000	2.4
--- gdb/dwarf2expr.h	8 Apr 2005 06:09:21 -0000
*************** struct dwarf_expr_context
*** 32,37 ****
--- 32,42 ----
       number of elements allocated to the stack.  */
    int stack_len, stack_allocated;
  
+   /* The size of an address, in bytes.  For use with operations like
+      DW_OP_addr and DW_OP_deref, and for properly masking arguments to
+      division-like operators.  */
+   CORE_ADDR address_size;
+ 
    /* An opaque argument provided by the caller, which will be passed
       to all of the callback functions.  */
    void *baton;
*************** unsigned char *read_uleb128 (unsigned ch
*** 134,139 ****
  unsigned char *read_sleb128 (unsigned char *buf, unsigned char *buf_end,
  			     LONGEST * r);
  CORE_ADDR dwarf2_read_address (unsigned char *buf, unsigned char *buf_end,
! 			       int *bytes_read);
  
  #endif
--- 139,144 ----
  unsigned char *read_sleb128 (unsigned char *buf, unsigned char *buf_end,
  			     LONGEST * r);
  CORE_ADDR dwarf2_read_address (unsigned char *buf, unsigned char *buf_end,
! 			       CORE_ADDR addr_size);
  
  #endif
Index: gdb/dwarf2loc.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/dwarf2loc.c,v
retrieving revision 2.9.2.2
diff -c -p -r2.9.2.2 dwarf2loc.c
*** gdb/dwarf2loc.c	8 Apr 2005 04:48:06 -0000	2.9.2.2
--- gdb/dwarf2loc.c	8 Apr 2005 06:09:21 -0000
*************** find_location_expression (struct dwarf2_
*** 56,62 ****
    CORE_ADDR base_address = baton->base_address;
    CORE_ADDR low, high;
    char *loc_ptr, *buf_end;
!   unsigned int addr_size = TARGET_ADDR_BIT / TARGET_CHAR_BIT, length;
    CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
  
    loc_ptr = baton->data;
--- 56,63 ----
    CORE_ADDR base_address = baton->base_address;
    CORE_ADDR low, high;
    char *loc_ptr, *buf_end;
!   unsigned int addr_size = dwarf_psymtab_address_size (baton->psymtab);
!   unsigned int length;
    CORE_ADDR base_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
  
    loc_ptr = baton->data;
*************** find_location_expression (struct dwarf2_
*** 64,73 ****
  
    while (1)
      {
!       low = dwarf2_read_address (loc_ptr, buf_end, &length);
!       loc_ptr += length;
!       high = dwarf2_read_address (loc_ptr, buf_end, &length);
!       loc_ptr += length;
  
        /* An end-of-list entry.  */
        if (low == 0 && high == 0)
--- 65,74 ----
  
    while (1)
      {
!       low = dwarf2_read_address (loc_ptr, buf_end, addr_size);
!       loc_ptr += addr_size;
!       high = dwarf2_read_address (loc_ptr, buf_end, addr_size);
!       loc_ptr += addr_size;
  
        /* An end-of-list entry.  */
        if (low == 0 && high == 0)
*************** dwarf_expr_tls_address (void *baton, COR
*** 196,206 ****
  
  /* Evaluate a location description, starting at DATA and with length
     SIZE, to find the current location of variable VAR in the context
!    of FRAME.  */
  static struct value *
  dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
  			  unsigned char *data, unsigned short size,
! 			  struct objfile *objfile)
  {
    struct value *retval;
    struct dwarf_expr_baton baton;
--- 197,208 ----
  
  /* Evaluate a location description, starting at DATA and with length
     SIZE, to find the current location of variable VAR in the context
!    of FRAME.  PSYMTAB is the partial symtab for the compilation unit
!    defining VAR.  */
  static struct value *
  dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
  			  unsigned char *data, unsigned short size,
! 			  struct partial_symtab *psymtab)
  {
    struct value *retval;
    struct dwarf_expr_baton baton;
*************** dwarf2_evaluate_loc_desc (struct symbol 
*** 214,222 ****
      }
  
    baton.frame = frame;
!   baton.objfile = objfile;
  
    ctx = new_dwarf_expr_context ();
    ctx->baton = &baton;
    ctx->read_reg = dwarf_expr_read_reg;
    ctx->read_mem = dwarf_expr_read_mem;
--- 216,225 ----
      }
  
    baton.frame = frame;
!   baton.objfile = psymtab->objfile;
  
    ctx = new_dwarf_expr_context ();
+   ctx->address_size = dwarf_psymtab_address_size (psymtab);
    ctx->baton = &baton;
    ctx->read_reg = dwarf_expr_read_reg;
    ctx->read_mem = dwarf_expr_read_mem;
*************** dwarf2_loc_desc_needs_frame (unsigned ch
*** 328,333 ****
--- 331,337 ----
    baton.needs_frame = 0;
  
    ctx = new_dwarf_expr_context ();
+   ctx->address_size = 1;
    ctx->baton = &baton;
    ctx->read_reg = needs_frame_read_reg;
    ctx->read_mem = needs_frame_read_mem;
*************** locexpr_read_variable (struct symbol *sy
*** 412,418 ****
    struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
    struct value *val;
    val = dwarf2_evaluate_loc_desc (symbol, frame, dlbaton->data, dlbaton->size,
! 				  dlbaton->objfile);
  
    return val;
  }
--- 416,422 ----
    struct dwarf2_locexpr_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
    struct value *val;
    val = dwarf2_evaluate_loc_desc (symbol, frame, dlbaton->data, dlbaton->size,
! 				  dlbaton->psymtab);
  
    return val;
  }
*************** locexpr_describe_location (struct symbol
*** 458,471 ****
        && dlbaton->data[dlbaton->size - 1] == DW_OP_GNU_push_tls_address)
      if (dlbaton->data[0] == DW_OP_addr)
        {
! 	int bytes_read;
! 	CORE_ADDR offset = dwarf2_read_address (&dlbaton->data[1],
! 						&dlbaton->data[dlbaton->size - 1],
! 						&bytes_read);
  	fprintf_filtered (stream, 
  			  "a thread-local variable at offset %s in the "
  			  "thread-local storage for `%s'",
! 			  paddr_nz (offset), dlbaton->objfile->name);
  	return 1;
        }
    
--- 462,476 ----
        && dlbaton->data[dlbaton->size - 1] == DW_OP_GNU_push_tls_address)
      if (dlbaton->data[0] == DW_OP_addr)
        {
! 	int address_size = dwarf_psymtab_address_size (dlbaton->psymtab);
! 	CORE_ADDR offset
! 	  = dwarf2_read_address (&dlbaton->data[1],
! 				 &dlbaton->data[dlbaton->size - 1],
! 				 address_size);
  	fprintf_filtered (stream, 
  			  "a thread-local variable at offset %s in the "
  			  "thread-local storage for `%s'",
! 			  paddr_nz (offset), dlbaton->psymtab->objfile->name);
  	return 1;
        }
    
*************** loclist_read_variable (struct symbol *sy
*** 521,527 ****
    if (data == NULL)
      error ("Variable \"%s\" is not available.", SYMBOL_NATURAL_NAME (symbol));
  
!   val = dwarf2_evaluate_loc_desc (symbol, frame, data, size, dlbaton->objfile);
  
    return val;
  }
--- 526,533 ----
    if (data == NULL)
      error ("Variable \"%s\" is not available.", SYMBOL_NATURAL_NAME (symbol));
  
!   val = dwarf2_evaluate_loc_desc (symbol, frame, data, size,
! 				  dlbaton->psymtab);
  
    return val;
  }
Index: gdb/dwarf2loc.h
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/dwarf2loc.h,v
retrieving revision 2.4
diff -c -p -r2.4 dwarf2loc.h
*** gdb/dwarf2loc.h	13 Apr 2004 16:38:54 -0000	2.4
--- gdb/dwarf2loc.h	8 Apr 2005 06:09:21 -0000
*************** struct symbol_ops;
*** 26,31 ****
--- 26,35 ----
  /* This header is private to the DWARF-2 reader.  It is shared between
     dwarf2read.c and dwarf2loc.c.  */
  
+ /* Return the address size given in the compilation unit header for
+    PSYMTAB.  */
+ CORE_ADDR dwarf_psymtab_address_size (struct partial_symtab *psymtab);
+ 
  /* The symbol location baton types used by the DWARF-2 reader (i.e.
     SYMBOL_LOCATION_BATON for a LOC_COMPUTED symbol).  "struct
     dwarf2_locexpr_baton" is for a symbol with a single location
*************** struct dwarf2_locexpr_baton
*** 40,47 ****
    /* Length of the location expression.  */
    unsigned short size;
  
!   /* The objfile containing the symbol whose location we're computing.  */
!   struct objfile *objfile;
  };
  
  struct dwarf2_loclist_baton
--- 44,55 ----
    /* Length of the location expression.  */
    unsigned short size;
  
!   /* The partial symtab structure for the compilation unit containing
!      the symbol whose location we're computing.  Passing the psymtab
!      instead of the objfile gives us access to compilation-unit-
!      specific information like Dwarf address size, and the psymtab
!      also points to the objfile.  */
!   struct partial_symtab *psymtab;
  };
  
  struct dwarf2_loclist_baton
*************** struct dwarf2_loclist_baton
*** 56,67 ****
    /* Length of the location list.  */
    unsigned short size;
  
!   /* The objfile containing the symbol whose location we're computing.  */
!   /* Used (only???) by thread local variables.  The objfile in which
!      this symbol is defined.  To find a thread-local variable (e.g., a
!      variable declared with the `__thread' storage class), we may need
!      to know which object file it's in.  */
!   struct objfile *objfile;
  };
  
  extern const struct symbol_ops dwarf2_locexpr_funcs;
--- 64,76 ----
    /* Length of the location list.  */
    unsigned short size;
  
! 
!   /* The partial symtab structure for the compilation unit containing
!      the symbol whose location we're computing.  Passing the psymtab
!      instead of the objfile gives us access to compilation-unit-
!      specific information like Dwarf address size, and the psymtab
!      also points to the objfile.  */
!   struct partial_symtab *psymtab;
  };
  
  extern const struct symbol_ops dwarf2_locexpr_funcs;
Index: gdb/dwarf2read.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/dwarf2read.c,v
retrieving revision 2.114
diff -c -p -r2.114 dwarf2read.c
*** gdb/dwarf2read.c	23 Jun 2004 23:49:17 -0000	2.114
--- gdb/dwarf2read.c	8 Apr 2005 06:09:22 -0000
*************** struct dwarf2_cu
*** 249,254 ****
--- 249,257 ----
    /* The objfile containing this compilation unit.  */
    struct objfile *objfile;
  
+   /* The partial symtab for this compilation unit.  */
+   struct partial_symtab *psymtab;
+ 
    /* The header of the compilation unit.
  
       FIXME drow/2003-11-10: Some of the things from the comp_unit_head
*************** struct dwarf2_pinfo
*** 471,476 ****
--- 474,483 ----
      /* Offset in .debug_info for this compilation unit. */
  
      unsigned long dwarf_info_offset;
+     
+     /* Size of addresses in this compilation unit --- from the
+        compilation unit header.  */
+     CORE_ADDR address_size;
    };
  
  #define PST_PRIVATE(p) ((struct dwarf2_pinfo *)(p)->read_symtab_private)
*************** dwarf2_build_psymtabs_hard (struct objfi
*** 1171,1176 ****
--- 1178,1188 ----
        beg_of_comp_unit = info_ptr;
  
        cu.objfile = objfile;
+ 
+       /* We never use the CU's psymtab while building partial symbol
+ 	 tables.  */
+       cu.psymtab = NULL;
+ 
        info_ptr = read_comp_unit_head (&cu.header, info_ptr, abfd);
  
        if (cu.header.version != 2)
*************** dwarf2_build_psymtabs_hard (struct objfi
*** 1223,1228 ****
--- 1235,1244 ----
        pst->read_symtab_private = (char *)
  	obstack_alloc (&objfile->objfile_obstack, sizeof (struct dwarf2_pinfo));
        DWARF_INFO_OFFSET (pst) = beg_of_comp_unit - dwarf2_per_objfile->info_buffer;
+       /* This should never be used until we have read in full symbols
+ 	 for PST.  */
+       PST_PRIVATE (pst)->address_size = 0;
+ 
        baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
  
        /* Store the function that reads in the rest of the symbol table */
*************** psymtab_to_symtab_1 (struct partial_symt
*** 1935,1944 ****
--- 1951,1964 ----
    make_cleanup (really_free_pendings, NULL);
  
    cu.objfile = objfile;
+   cu.psymtab = pst;
  
    /* read in the comp_unit header  */
    info_ptr = read_comp_unit_head (&cu.header, info_ptr, abfd);
  
+   /* Save the address size in the psymtab's private data.  */
+   PST_PRIVATE (pst)->address_size = cu.header.addr_size;
+ 
    /* Read the abbrevs for this compilation unit  */
    dwarf2_read_abbrevs (abfd, &cu);
    make_cleanup (dwarf2_free_abbrev_table, &cu);
*************** psymtab_to_symtab_1 (struct partial_symt
*** 2000,2005 ****
--- 2020,2031 ----
    do_cleanups (back_to);
  }
  
+ CORE_ADDR
+ dwarf_psymtab_address_size (struct partial_symtab *psymtab)
+ {
+   return PST_PRIVATE (psymtab)->address_size;
+ }
+ 
  /* Process a die and its children.  */
  
  static void
*************** dwarf2_symbol_mark_computed (struct attr
*** 8126,8132 ****
  
        baton = obstack_alloc (&cu->objfile->objfile_obstack,
  			     sizeof (struct dwarf2_loclist_baton));
!       baton->objfile = cu->objfile;
  
        /* We don't know how long the location list is, but make sure we
  	 don't run off the edge of the section.  */
--- 8152,8158 ----
  
        baton = obstack_alloc (&cu->objfile->objfile_obstack,
  			     sizeof (struct dwarf2_loclist_baton));
!       baton->psymtab = cu->psymtab;
  
        /* We don't know how long the location list is, but make sure we
  	 don't run off the edge of the section.  */
*************** dwarf2_symbol_mark_computed (struct attr
*** 8146,8152 ****
  
        baton = obstack_alloc (&cu->objfile->objfile_obstack,
  			     sizeof (struct dwarf2_locexpr_baton));
!       baton->objfile = cu->objfile;
  
        if (attr_form_is_block (attr))
  	{
--- 8172,8178 ----
  
        baton = obstack_alloc (&cu->objfile->objfile_obstack,
  			     sizeof (struct dwarf2_locexpr_baton));
!       baton->psymtab = cu->psymtab;
  
        if (attr_form_is_block (attr))
  	{


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC] DWARF 2 address size != pointer size
  2006-05-11 22:44 ` Jim Blandy
@ 2006-05-12 14:21   ` Fred Fish
  2006-05-12 18:19     ` Jim Blandy
  0 siblings, 1 reply; 8+ messages in thread
From: Fred Fish @ 2006-05-12 14:21 UTC (permalink / raw)
  To: Jim Blandy; +Cc: gdb-patches, fnf

On Thursday 11 May 2006 18:44, Jim Blandy wrote:
> Technically, this isn't quite right, since each CU could potentially
> have a different address size.  It's not a global property of the
> debug info.

Correct.  I think my patches have a comment related to that.

> Here's the patch; is it addressing the same thing yours does?  I'm not
> sure it deals with frame info right, but I'm pretty sure the rest of
> it is going in the right direction:

I tried applying it, but it didn't apply cleanly and I gave up trying
to fix it up after I found out it uses code that was deleted a couple
years ago (dwarf2_pinfo for example).

-Fred


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC] DWARF 2 address size != pointer size
  2006-05-12 14:21   ` Fred Fish
@ 2006-05-12 18:19     ` Jim Blandy
  0 siblings, 0 replies; 8+ messages in thread
From: Jim Blandy @ 2006-05-12 18:19 UTC (permalink / raw)
  To: fnf; +Cc: gdb-patches


Fred Fish <fnf@specifix.com> writes:
> On Thursday 11 May 2006 18:44, Jim Blandy wrote:
>> Technically, this isn't quite right, since each CU could potentially
>> have a different address size.  It's not a global property of the
>> debug info.
>
> Correct.  I think my patches have a comment related to that.
>
>> Here's the patch; is it addressing the same thing yours does?  I'm not
>> sure it deals with frame info right, but I'm pretty sure the rest of
>> it is going in the right direction:
>
> I tried applying it, but it didn't apply cleanly and I gave up trying
> to fix it up after I found out it uses code that was deleted a couple
> years ago (dwarf2_pinfo for example).

Sorry --- I should have made clear it wasn't expected to apply to
today's sources.  It'll need some adaptation.  I don't mean to throw
work at you; I just figured I'd offer the work I'd done for whatever
it was still worth.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC] DWARF 2 address size != pointer size
  2006-05-10 18:24 [RFC] DWARF 2 address size != pointer size Fred Fish
  2006-05-11 22:44 ` Jim Blandy
@ 2006-05-12 19:57 ` Mark Kettenis
  2006-05-12 20:07   ` Daniel Jacobowitz
  1 sibling, 1 reply; 8+ messages in thread
From: Mark Kettenis @ 2006-05-12 19:57 UTC (permalink / raw)
  To: fnf; +Cc: gdb-patches, fnf

> From: Fred Fish <fnf@specifix.com>
> Date: Wed, 10 May 2006 14:24:10 -0400
> 
> For at least one target, MIPS using the o64 ABI with -mlong64, the
> target DWARF2 address size used in the DWARF info (32 bit) is not the
> same as the target pointer size (64 bit).

Unbelievable.  As if there aren't enough ABI's for MIPS yet.  But how
can this work?  If the pointers are really 64-bit, how can they be
encoded in the 32-bit DWARF2 adresses?

> For example, below are some fragments from dumping the DWARF info
> for a simple test case:
> 
>   Compilation Unit @ 0:
>    Length:        175
>    Version:       2
>    Abbrev Offset: 0
>    Pointer Size:  4	
>  <1><91>: Abbrev Number: 3 (DW_TAG_base_type)
>      DW_AT_name        : long int
>      DW_AT_byte_size   : 8
>  <1><b0>: Abbrev Number: 4 (DW_TAG_pointer_type)
>      DW_AT_byte_size   : 8
> 
> Note that the header records the address size as 4, which is the
> number of bytes written to the DWARF info when writing addresses, but
> that the target pointer size is 8.
> 
> Currently gdb computes the DWARF info address size as:
> 
> 	TARGET_ADDR_BIT / TARGET_CHAR_BIT
> 
> Given that the address size is actually recorded in the compilation
> unit header, I believe the best solution would be to use that recorded
> value somehow.  I spent a couple days looking for an easy way to tie
> the address size to DWARF expressions that were recorded for later
> evaluation, but didn't come up with anything clean enough to submit.
> 
> Another way to divorce the DWARF address size from the TARGET_ADDR_BIT
> is to add another gdbarch paramter, accessed as TARGET_DWARF_ADDR_BIT.
> I've attached a patch that does that.  It's simple, but not my first
> choice for solving the problem.
> 
> Comments?

I think introducing TARGET_DWARF_ADDR_BIT is a mistake if the debug
info already encodes the info.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC] DWARF 2 address size != pointer size
  2006-05-12 19:57 ` Mark Kettenis
@ 2006-05-12 20:07   ` Daniel Jacobowitz
  2006-05-12 22:32     ` David S. Miller
  0 siblings, 1 reply; 8+ messages in thread
From: Daniel Jacobowitz @ 2006-05-12 20:07 UTC (permalink / raw)
  To: Mark Kettenis; +Cc: fnf, gdb-patches

On Fri, May 12, 2006 at 09:51:02PM +0200, Mark Kettenis wrote:
> > From: Fred Fish <fnf@specifix.com>
> > Date: Wed, 10 May 2006 14:24:10 -0400
> > 
> > For at least one target, MIPS using the o64 ABI with -mlong64, the
> > target DWARF2 address size used in the DWARF info (32 bit) is not the
> > same as the target pointer size (64 bit).
> 
> Unbelievable.  As if there aren't enough ABI's for MIPS yet.  But how
> can this work?  If the pointers are really 64-bit, how can they be
> encoded in the 32-bit DWARF2 adresses?

[Mark, I just got a delayed bounce from your procmail for an earlier
message.  Let's see if I get another...]

It's a code model thing.  It has 64-bit pointers, but all symbols are
32-bit, and IIRC it actually uses 32-bit ELF.

> I think introducing TARGET_DWARF_ADDR_BIT is a mistake if the debug
> info already encodes the info.

I do too.

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC] DWARF 2 address size != pointer size
  2006-05-12 20:07   ` Daniel Jacobowitz
@ 2006-05-12 22:32     ` David S. Miller
  2006-05-12 22:42       ` Daniel Jacobowitz
  0 siblings, 1 reply; 8+ messages in thread
From: David S. Miller @ 2006-05-12 22:32 UTC (permalink / raw)
  To: drow; +Cc: mark.kettenis, fnf, gdb-patches

From: Daniel Jacobowitz <drow@false.org>
Date: Fri, 12 May 2006 15:56:34 -0400

> It's a code model thing.  It has 64-bit pointers, but all symbols are
> 32-bit, and IIRC it actually uses 32-bit ELF.

Sparc64 with -mcmodel=medlow is the same situation, but the DWARF
address sizes are still 64-bit and don't change based upon the 64-bit
code model selected.

I guess this is a side effect of using the MIPS 32-bit ELF target
rather than something explicit the MIPS backend of GCC is doing
to tinker with the DWARF output format?

Actually, there is a Sparc situation which is more like this MIPS
case.  For -mcpu=v8plus{,a,b} and friends, we're generating 32-bit
code and using 32-bit SPARC ELF, but certain registers are available
for full 64-bit integer operations (for "long long").  We don't handle
this in GDB currently because there is no easy way to get at the full
64-bit register values in a 32-bit process with a 32-bit gdb.  With a
64-bit GDB we can easily do this, and under Linux/Sparc there are
special versions of the ptrace commands which allow passing 64-bit
register values back and forth to/from a 32-bit debugger.

I've always wanted to add support for that, but it's going to be real
ugly stuff and take us away from the nice unified Sparc ptrace()
support which several Sparc targets are sharing right now.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC] DWARF 2 address size != pointer size
  2006-05-12 22:32     ` David S. Miller
@ 2006-05-12 22:42       ` Daniel Jacobowitz
  0 siblings, 0 replies; 8+ messages in thread
From: Daniel Jacobowitz @ 2006-05-12 22:42 UTC (permalink / raw)
  To: David S. Miller; +Cc: mark.kettenis, fnf, gdb-patches

On Fri, May 12, 2006 at 03:18:51PM -0700, David S. Miller wrote:
> I guess this is a side effect of using the MIPS 32-bit ELF target
> rather than something explicit the MIPS backend of GCC is doing
> to tinker with the DWARF output format?

Probably.

> Actually, there is a Sparc situation which is more like this MIPS
> case.  For -mcpu=v8plus{,a,b} and friends, we're generating 32-bit
> code and using 32-bit SPARC ELF, but certain registers are available
> for full 64-bit integer operations (for "long long").  We don't handle
> this in GDB currently because there is no easy way to get at the full
> 64-bit register values in a 32-bit process with a 32-bit gdb.  With a
> 64-bit GDB we can easily do this, and under Linux/Sparc there are
> special versions of the ptrace commands which allow passing 64-bit
> register values back and forth to/from a 32-bit debugger.
> 
> I've always wanted to add support for that, but it's going to be real
> ugly stuff and take us away from the nice unified Sparc ptrace()
> support which several Sparc targets are sharing right now.

There's already MIPS support for something like this in GDB. 
Additionally, PPC support was posted.  And, someone posted v8plus
support for Solaris (three or four months ago?).  Don't remember what
became of that.

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2006-05-12 22:32 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-05-10 18:24 [RFC] DWARF 2 address size != pointer size Fred Fish
2006-05-11 22:44 ` Jim Blandy
2006-05-12 14:21   ` Fred Fish
2006-05-12 18:19     ` Jim Blandy
2006-05-12 19:57 ` Mark Kettenis
2006-05-12 20:07   ` Daniel Jacobowitz
2006-05-12 22:32     ` David S. Miller
2006-05-12 22:42       ` Daniel Jacobowitz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox