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]

Re: [RFC] DWARF 2 address size != pointer size


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))
  	{


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