This is the mail archive of the gdb-patches@sourceware.cygnus.com mailing list for the GDB project. See the GDB home page for more information.


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

Patch for one element location lists from .debug_loc


At least one compiler, Aonix ObjectAda, uses the .debug_loc section for some
location list information (even when not optimizing code--eg. register
tracking).  This patch adds basic support for reading location information
from the .debug_loc section.  This patch doesn't extend gdb to handle code
which has different locations for an object through its lifetime.


Mon May  3 15:54:41 1999 Brian Nettleton <bn@aonix.com>

	* dwarf2read.c: Added partial support for reading locations out of
	.debug_loc section.


Index: gdb/dwarf2read.c
*** ../gdb-4.17.patch/gdb/dwarf2read.c	Mon May  3 15:28:38 1999
--- gdb/dwarf2read.c	Mon May  3 15:50:29 1999
*************** static unsigned int identifier_case;
*** 292,297 ****
--- 292,298 ----
  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
*** 358,363 ****
--- 359,368 ----
    /* 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
*** 366,371 ****
--- 371,377 ----
  #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_subrange_type PARAMS ((
*** 673,678 ****
--- 679,686 ----
  
  static struct type *dwarf_base_type PARAMS ((int, int, struct objfile *));
  
+ static struct dwarf_block * locblock PARAMS ((struct attribute *, bfd *));
+ 
  static CORE_ADDR decode_locdesc PARAMS ((struct dwarf_block *,
  					 struct objfile *));
  
*************** int
*** 759,765 ****
  dwarf2_has_info (abfd)
       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)
      {
--- 767,774 ----
  dwarf2_has_info (abfd)
       bfd *abfd;
  {
!   dwarf_info_offset = dwarf_abbrev_offset = dwarf_line_offset = 
!     dwarf_loc_offset = 0;
    bfd_map_over_sections (abfd, dwarf2_locate_sections, NULL);
    if (dwarf_info_offset && dwarf_abbrev_offset)
      {
*************** dwarf2_build_psymtabs (objfile, section_
*** 843,848 ****
--- 852,860 ----
    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 (objfile, sec
*** 1002,1007 ****
--- 1014,1020 ----
        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 (section_offsets, 0);
  
        /* Store the function that reads in the rest of the symbol table */
*************** psymtab_to_symtab_1 (pst)
*** 1303,1308 ****
--- 1316,1322 ----
    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, 0);
    cu_header_offset = offset;
    info_ptr = dwarf_info_buffer + offset;
*************** read_func_scope (die, objfile)
*** 1605,1611 ****
    attr = dwarf_attr (die, DW_AT_frame_base);
    if (attr)
      {
!       CORE_ADDR addr = decode_locdesc (DW_BLOCK (attr), objfile);
        if (isreg)
  	frame_base_reg = addr;
        else if (offreg)
--- 1619,1625 ----
    attr = dwarf_attr (die, DW_AT_frame_base);
    if (attr)
      {
!       CORE_ADDR addr = decode_locdesc (locblock (attr, objfile->obfd), objfile);
        if (isreg)
  	frame_base_reg = addr;
        else if (offreg)
*************** dwarf2_add_field (fip, die, objfile)
*** 1789,1795 ****
        if (attr)
  	{
  	  FIELD_BITPOS (*fp) =
! 	    decode_locdesc (DW_BLOCK (attr), objfile) * bits_per_byte;
  	}
        else
  	FIELD_BITPOS (*fp) = 0;
--- 1803,1810 ----
        if (attr)
  	{
  	  FIELD_BITPOS (*fp) =
! 	    decode_locdesc (locblock (attr, objfile->obfd), objfile) 
! 	      * bits_per_byte;
  	}
        else
  	FIELD_BITPOS (*fp) = 0;
*************** dwarf2_add_field (fip, die, objfile)
*** 1884,1890 ****
        /* C++ base class field.  */
        attr = dwarf_attr (die, DW_AT_data_member_location);
        if (attr)
! 	FIELD_BITPOS (*fp) = decode_locdesc (DW_BLOCK (attr), objfile) * bits_per_byte;
        FIELD_BITSIZE (*fp) = 0;
        FIELD_TYPE (*fp) = die_type (die, objfile);
        FIELD_NAME (*fp) = type_name_no_tag (fp->type);
--- 1899,1907 ----
        /* C++ base class field.  */
        attr = dwarf_attr (die, DW_AT_data_member_location);
        if (attr)
! 	FIELD_BITPOS (*fp) = decode_locdesc (locblock (attr, objfile->obfd), 
! 					     objfile) 
! 			       * bits_per_byte;
        FIELD_BITSIZE (*fp) = 0;
        FIELD_TYPE (*fp) = die_type (die, objfile);
        FIELD_NAME (*fp) = type_name_no_tag (fp->type);
*************** dwarf2_add_member_fn (fip, die, type, ob
*** 2170,2176 ****
    /* 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) + 2;
  }
  
  /* Create the vector of member function fields, and attach it to the type.  */
--- 2187,2193 ----
    /* 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), objfile) + 2;
  }
  
  /* Create the vector of member function fields, and attach it to the type.  */
*************** read_common_block (die, objfile)
*** 2766,2772 ****
    attr = dwarf_attr (die, DW_AT_location);
    if (attr)
      {
!       base = decode_locdesc (DW_BLOCK (attr), objfile);
      }
    if (die->has_children)
      {
--- 2783,2789 ----
    attr = dwarf_attr (die, DW_AT_location);
    if (attr)
      {
!       base = decode_locdesc (locblock (attr, objfile->obfd), objfile);
      }
    if (die->has_children)
      {
*************** read_common_block (die, objfile)
*** 2778,2784 ****
  	  if (attr)
  	    {
  	      SYMBOL_VALUE_ADDRESS (sym) =
! 		base + decode_locdesc (DW_BLOCK (attr), objfile);
  	      add_symbol_to_list (sym, &global_symbols);
  	    }
  	  child_die = sibling_die (child_die);
--- 2795,2801 ----
  	  if (attr)
  	    {
  	      SYMBOL_VALUE_ADDRESS (sym) =
! 		base + decode_locdesc (locblock (attr, objfile->obfd), objfile);
  	      add_symbol_to_list (sym, &global_symbols);
  	    }
  	  child_die = sibling_die (child_die);
*************** read_partial_die (part_die, abfd, info_p
*** 3391,3397 ****
  	  part_die->highpc = DW_ADDR (&attr);
  	  break;
  	case DW_AT_location:
! 	  part_die->locdesc = DW_BLOCK (&attr);
  	  break;
  	case DW_AT_language:
  	  part_die->language = DW_UNSND (&attr);
--- 3408,3414 ----
  	  part_die->highpc = DW_ADDR (&attr);
  	  break;
  	case DW_AT_location:
! 	  part_die->locdesc = locblock (&attr, abfd);
  	  break;
  	case DW_AT_language:
  	  part_die->language = DW_UNSND (&attr);
*************** new_symbol (die, type, objfile)
*** 4317,4323 ****
  	      if (attr2 && (DW_UNSND (attr2) != 0))
  		{
  		  SYMBOL_VALUE_ADDRESS (sym) =
! 		    decode_locdesc (DW_BLOCK (attr), objfile);
  		  add_symbol_to_list (sym, &global_symbols);
  
  	 	  /* In shared libraries the address of the variable
--- 4334,4340 ----
  	      if (attr2 && (DW_UNSND (attr2) != 0))
  		{
  		  SYMBOL_VALUE_ADDRESS (sym) =
! 		    decode_locdesc (locblock (attr, objfile->obfd), objfile);
  		  add_symbol_to_list (sym, &global_symbols);
  
  	 	  /* In shared libraries the address of the variable
*************** new_symbol (die, type, objfile)
*** 4338,4344 ****
  	      else
  		{
  		  SYMBOL_VALUE (sym) = addr =
! 		    decode_locdesc (DW_BLOCK (attr), objfile);
  		  add_symbol_to_list (sym, list_in_scope);
  		  if (optimized_out)
  		    {
--- 4355,4361 ----
  	      else
  		{
  		  SYMBOL_VALUE (sym) = addr =
! 		    decode_locdesc (locblock (attr, objfile->obfd), objfile);
  		  add_symbol_to_list (sym, list_in_scope);
  		  if (optimized_out)
  		    {
*************** new_symbol (die, type, objfile)
*** 4385,4391 ****
  	  attr = dwarf_attr (die, DW_AT_location);
  	  if (attr)
  	    {
! 	      SYMBOL_VALUE (sym) = decode_locdesc (DW_BLOCK (attr), objfile);
  	      if (isreg)
  		{
  		  SYMBOL_CLASS (sym) = LOC_REGPARM;
--- 4402,4410 ----
  	  attr = dwarf_attr (die, DW_AT_location);
  	  if (attr)
  	    {
! 	      SYMBOL_VALUE (sym) = decode_locdesc (locblock (attr, 
! 							     objfile->obfd), 
! 						   objfile);
  	      if (isreg)
  		{
  		  SYMBOL_CLASS (sym) = LOC_REGPARM;
*************** dwarf2_fundamental_type (objfile, typeid
*** 5772,5777 ****
--- 5791,5836 ----
  
    return (ftypes[typeid]);
  }
+ 
+ /* 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 (attr, abfd)
+      struct attribute *attr;
+      bfd *abfd;
+ {
+   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 += address_size;
+       loc_ptr += address_size;
+       result = dwarf_alloc_block();
+       result->size = read_2_bytes(abfd, loc_ptr);
+       loc_ptr += 2;
+       result->data = loc_ptr;
+       return result;
+     }
+     return NULL;
+ }
+ 
  
  /* Decode simple location descriptions.
     Given a pointer to a dwarf block that defines a location, compute