This is the mail archive of the gdb-patches@sources.redhat.com 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]

[RFA]: Add support for .debug_loc to dwarf2 reader


Elenna, since you are listed as backup maintainer for the dwarf
readers, this needs your approval.
I'll happily take dwarf2read off your hands if you don't want to deal
with it, i've got a bunch more patches i'll be submitting soon, and
i'm intimately familiar with the code.

2000-10-21  Daniel Berlin   <dberlin@redhat.com>
	
	* dwarf2read.c (top level) : Add dwarf_loc_buffer for tracking dwarf2
	location list buffer.
  	Add DWARF_LOC_BUFFER to macros for accessing the various dwarf2_pinfo
	buffers.
	Add locblock function prototype.
	(struct dwarf2_pinfo): Add dwarf_loc_buffer here too.
	(dwarf2_has_info): Zero dwarf_loc_offset too. 	
	(dwarf2_build_psymtabs): Read in .debug_loc section too.
	(psymtab_to_symtab_1): Set dwarf_loc_buffer properly.
	(read_func_scope): Use locblock rather than DW_BLOCK in decode_locdesc's.
	(dwarf2_add_field): Ditto.
	(dwarf2_add_member_fn): Ditto.
	(read_common_block): Ditto.
	(new_symbol): Ditto.
	(locblock): New function, determine if location list is in .debug_loc
	section or not, and read it from right location.

Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.16
diff -c -3 -p -r1.16 dwarf2read.c
*** dwarf2read.c	2000/08/04 16:51:47	1.16
--- dwarf2read.c	2000/10/23 13:42:34
*************** static const struct language_defn *cu_la
*** 300,305 ****
--- 318,324 ----
  static char *dwarf_info_buffer;
  static char *dwarf_abbrev_buffer;
  static char *dwarf_line_buffer;
+ static char *dwarf_loc_buffer;
  
  /* A zeroed version of a partial die for initialization purposes.  */
  static struct partial_die_info zeroed_partial_die;
*************** struct dwarf2_pinfo
*** 381,386 ****
--- 400,409 ----
      /* Pointer to start of dwarf line buffer for the objfile.  */
  
      char *dwarf_line_buffer;
+ 
+     /* Pointer to start of dwarf location buffer for the objfile. */
+     
+     char *dwarf_loc_buffer;
    };
  
  #define PST_PRIVATE(p) ((struct dwarf2_pinfo *)(p)->read_symtab_private)
*************** struct dwarf2_pinfo
*** 389,394 ****
--- 412,418 ----
  #define DWARF_ABBREV_BUFFER(p) (PST_PRIVATE(p)->dwarf_abbrev_buffer)
  #define DWARF_ABBREV_SIZE(p) (PST_PRIVATE(p)->dwarf_abbrev_size)
  #define DWARF_LINE_BUFFER(p) (PST_PRIVATE(p)->dwarf_line_buffer)
+ #define DWARF_LOC_BUFFER(p)  (PST_PRIVATE(p)->dwarf_loc_buffer)
  
  /* Maintain an array of referenced fundamental types for the current
     compilation unit being read.  For DWARF version 1, we have to construct
*************** static void read_enumeration (struct die
*** 700,705 ****
--- 724,732 ----
  
  static struct type *dwarf_base_type (int, int, struct objfile *);
  
+ static struct dwarf_block * locblock (struct attribute *, bfd *, 
+ 				     const struct comp_unit_head *);
+ 
  static CORE_ADDR decode_locdesc (struct dwarf_block *, struct objfile *,
  				 const struct comp_unit_head *);
  
*************** static struct die_info *dwarf_alloc_die 
*** 787,793 ****
  int
  dwarf2_has_info (bfd *abfd)
  {
!   dwarf_info_offset = dwarf_abbrev_offset = dwarf_line_offset = 0;
    bfd_map_over_sections (abfd, dwarf2_locate_sections, NULL);
    if (dwarf_info_offset && dwarf_abbrev_offset)
      {
--- 814,820 ----
  int
  dwarf2_has_info (bfd *abfd)
  {
!   dwarf_loc_offset = dwarf_info_offset = dwarf_abbrev_offset = dwarf_line_offset = 0; 
    bfd_map_over_sections (abfd, dwarf2_locate_sections, NULL);
    if (dwarf_info_offset && dwarf_abbrev_offset)
      {
*************** dwarf2_build_psymtabs (struct objfile *o
*** 865,871 ****
    dwarf_line_buffer = dwarf2_read_section (objfile,
  					   dwarf_line_offset,
  					   dwarf_line_size);
! 
    if (mainline || objfile->global_psymbols.size == 0 ||
        objfile->static_psymbols.size == 0)
      {
--- 892,901 ----
    dwarf_line_buffer = dwarf2_read_section (objfile,
  					   dwarf_line_offset,
  					   dwarf_line_size);
!   dwarf_loc_buffer = dwarf2_read_section (objfile, 
! 					  dwarf_loc_offset, 
! 					  dwarf_loc_size);
!   
    if (mainline || objfile->global_psymbols.size == 0 ||
        objfile->static_psymbols.size == 0)
      {
*************** dwarf2_build_psymtabs_hard (struct objfi
*** 1030,1035 ****
--- 1060,1067 ----
        DWARF_ABBREV_BUFFER (pst) = dwarf_abbrev_buffer;
        DWARF_ABBREV_SIZE (pst) = dwarf_abbrev_size;
        DWARF_LINE_BUFFER (pst) = dwarf_line_buffer;
+       DWARF_LOC_BUFFER (pst) = dwarf_loc_buffer;
+ 
        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
*** 1331,1336 ****
--- 1376,1383 ----
    dwarf_abbrev_buffer = DWARF_ABBREV_BUFFER (pst);
    dwarf_abbrev_size = DWARF_ABBREV_SIZE (pst);
    dwarf_line_buffer = DWARF_LINE_BUFFER (pst);
+   dwarf_loc_buffer = DWARF_LOC_BUFFER (pst);
+ 
    baseaddr = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (objfile));
    cu_header_offset = offset;
    info_ptr = dwarf_info_buffer + offset;
*************** read_func_scope (struct die_info *die, s
*** 1613,1619 ****
    attr = dwarf_attr (die, DW_AT_frame_base);
    if (attr)
      {
!       CORE_ADDR addr = decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
        if (isderef)
  	complain (&dwarf2_unsupported_at_frame_base, name);
        else if (isreg)
--- 1660,1666 ----
    attr = dwarf_attr (die, DW_AT_frame_base);
    if (attr)
      {
!       CORE_ADDR addr = decode_locdesc (locblock(attr, objfile->obfd, cu_header), objfile, cu_header);
        if (isderef)
  	complain (&dwarf2_unsupported_at_frame_base, name);
        else if (isreg)
*************** dwarf2_add_field (struct field_info *fip
*** 1786,1792 ****
        if (attr)
  	{
  	  FIELD_BITPOS (*fp) =
! 	    decode_locdesc (DW_BLOCK (attr), objfile, cu_header) * bits_per_byte;
  	}
        else
  	FIELD_BITPOS (*fp) = 0;
--- 1833,1839 ----
        if (attr)
  	{
  	  FIELD_BITPOS (*fp) =
! 	    decode_locdesc (locblock (attr, objfile->obfd, cu_header), objfile, cu_header) * bits_per_byte;
  	}
        else
  	FIELD_BITPOS (*fp) = 0;
*************** dwarf2_add_field (struct field_info *fip
*** 1875,1881 ****
        /* C++ base class field.  */
        attr = dwarf_attr (die, DW_AT_data_member_location);
        if (attr)
! 	FIELD_BITPOS (*fp) = (decode_locdesc (DW_BLOCK (attr), objfile, cu_header)
  			      * bits_per_byte);
        FIELD_BITSIZE (*fp) = 0;
        FIELD_TYPE (*fp) = die_type (die, objfile, cu_header);
--- 1922,1928 ----
        /* C++ base class field.  */
        attr = dwarf_attr (die, DW_AT_data_member_location);
        if (attr)
! 	FIELD_BITPOS (*fp) = (decode_locdesc (locblock (attr, objfile->obfd, cu_header), objfile, cu_header)
  			      * bits_per_byte);
        FIELD_BITSIZE (*fp) = 0;
        FIELD_TYPE (*fp) = die_type (die, objfile, cu_header);
*************** dwarf2_add_member_fn (struct field_info 
*** 2096,2102 ****
    /* Get index in virtual function table if it is a virtual member function.  */
    attr = dwarf_attr (die, DW_AT_vtable_elem_location);
    if (attr)
!     fnp->voffset = decode_locdesc (DW_BLOCK (attr), objfile, cu_header) + 2;
  }
  
  /* Create the vector of member function fields, and attach it to the type.  */
--- 2143,2149 ----
    /* Get index in virtual function table if it is a virtual member function.  */
    attr = dwarf_attr (die, DW_AT_vtable_elem_location);
    if (attr)
!     fnp->voffset = decode_locdesc (locblock (attr, objfile->obfd, cu_header), objfile, cu_header) + 2;
  }
  
  /* Create the vector of member function fields, and attach it to the type.  */
*************** read_common_block (struct die_info *die,
*** 2550,2556 ****
    attr = dwarf_attr (die, DW_AT_location);
    if (attr)
      {
!       base = decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
      }
    if (die->has_children)
      {
--- 2597,2603 ----
    attr = dwarf_attr (die, DW_AT_location);
    if (attr)
      {
!       base = decode_locdesc (locblock (attr, objfile->obfd, cu_header), objfile, cu_header);
      }
    if (die->has_children)
      {
*************** read_common_block (struct die_info *die,
*** 2562,2568 ****
  	  if (attr)
  	    {
  	      SYMBOL_VALUE_ADDRESS (sym) =
! 		base + decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
  	      add_symbol_to_list (sym, &global_symbols);
  	    }
  	  child_die = sibling_die (child_die);
--- 2609,2615 ----
  	  if (attr)
  	    {
  	      SYMBOL_VALUE_ADDRESS (sym) =
! 		base + decode_locdesc (locblock (attr, objfile->obfd, cu_header), objfile, cu_header);
  	      add_symbol_to_list (sym, &global_symbols);
  	    }
  	  child_die = sibling_die (child_die);
*************** new_symbol (struct die_info *die, struct
*** 4173,4179 ****
  	      if (attr2 && (DW_UNSND (attr2) != 0))
  		{
  		  SYMBOL_VALUE_ADDRESS (sym) =
! 		    decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
  		  add_symbol_to_list (sym, &global_symbols);
  
  		  /* In shared libraries the address of the variable
--- 4251,4257 ----
  	      if (attr2 && (DW_UNSND (attr2) != 0))
  		{
  		  SYMBOL_VALUE_ADDRESS (sym) =
! 		    decode_locdesc (locblock (attr, objfile->obfd, cu_header), objfile, cu_header);
  		  add_symbol_to_list (sym, &global_symbols);
  
  		  /* In shared libraries the address of the variable
*************** new_symbol (struct die_info *die, struct
*** 4194,4200 ****
  	      else
  		{
  		  SYMBOL_VALUE (sym) = addr =
! 		    decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
  		  add_symbol_to_list (sym, list_in_scope);
  		  if (optimized_out)
  		    {
--- 4272,4278 ----
  	      else
  		{
  		  SYMBOL_VALUE (sym) = addr =
! 		    decode_locdesc (locblock (attr, objfile->obfd, cu_header), objfile, cu_header);
  		  add_symbol_to_list (sym, list_in_scope);
  		  if (optimized_out)
  		    {
*************** new_symbol (struct die_info *die, struct
*** 4242,4248 ****
  	  if (attr)
  	    {
  	      SYMBOL_VALUE (sym) =
! 		decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
  	      if (isreg)
  		{
  		  SYMBOL_CLASS (sym) = LOC_REGPARM;
--- 4320,4326 ----
  	  if (attr)
  	    {
  	      SYMBOL_VALUE (sym) =
! 		decode_locdesc (locblock (attr, objfile->obfd, cu_header), objfile, cu_header);
  	      if (isreg)
  		{
  		  SYMBOL_CLASS (sym) = LOC_REGPARM;
*************** dwarf_alloc_die (void)
*** 5948,5950 ****
--- 6037,6080 ----
    memset (die, 0, sizeof (struct die_info));
    return (die);
  }
+ /* Determine whether the location description for the attribute is
+    a block form or a reference form.  Reference form means the location
+    information is in the .debug_loc section (as a list), block form
+    means it's inline in the .debug_info section.
+    
+    FIXME: Complete location lists still aren't supported, only the
+    first element in a location list is read. */
+ static struct dwarf_block *
+ locblock (struct attribute *attr, bfd *abfd, const struct comp_unit_head *cu_header)
+ {
+   char *loc_ptr;
+   struct dwarf_block *result;
+ 
+   switch (attr->form)  
+     {
+     case DW_FORM_block:
+     case DW_FORM_block1:
+     case DW_FORM_block2:
+     case DW_FORM_block4:
+       return DW_BLOCK(attr);
+     case DW_FORM_ref_addr:
+     case DW_FORM_ref_udata:
+       /* return the first block in the
+ 	 location list for now */
+       loc_ptr = dwarf_loc_buffer + dwarf2_get_ref_die_offset(attr);
+       /* skip the two addresses */
+       loc_ptr += cu_header->addr_size;
+       loc_ptr += cu_header->addr_size;
+       result = dwarf_alloc_block();
+       result->size = read_2_bytes(abfd, loc_ptr);
+       loc_ptr += 2;
+       result->data = loc_ptr;
+       return result;
+     }
+   return NULL;
+ }
+ 
+  
+ 
+ 
+ 


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