This is the mail archive of the gdb-prs@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]
Other format: [Raw text]

pending/1029: [RFA] Location list support.


>Number:         1029
>Category:       pending
>Synopsis:       [RFA] Location list support.
>Confidential:   yes
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          change-request
>Submitter-Id:   unknown
>Arrival-Date:   Wed Feb 05 00:18:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     
>Release:        
>Organization:
>Environment:
>Description:
 This is a multi-part message in MIME format.
 --------------050605070107060100040601
 Content-Type: text/plain; charset=us-ascii; format=flowed
 Content-Transfer-Encoding: 7bit
 
 Hi all,
 this is a first part of my attempt to enable use of dwarf3 .debug_loc 
 sections (as generated by GCC's rtlopt-branch) for variable tracking.
 With this patch GDB at least doesn't segfault as it did when trying to 
 debug a binary with .debug_loc section.
 It can already read and parse .debug_loc and then use the appropriate 
 first block found for a given DIE for obtaining the SYMBOL_VALUE() in 
 newsymbol(). So now it behaves exactly like it did with GCCs that didn't 
 emit .debug_loc.
 I hope to have a full support (ie. SYMBOL_VALUE that depends on PC) 
 available soon.
 This was developped in gdb-5.3 but should be usable with mainline with 
 no problems.
 
 Comments? Approvals?
 
 Michal Ludvig
 -- 
 * SuSE CR, s.r.o     * mludvig@suse.cz
 * (+420) 296.545.373 * http://www.suse.cz
 
 --------------050605070107060100040601
 Content-Type: text/plain;
  name="loclist-1.diff"
 Content-Transfer-Encoding: quoted-printable
 Content-Disposition: inline;
  filename="loclist-1.diff"
 
 2003-02-01  Michal Ludvig  <mludvig@suse.cz>
 
 	* dwarf2read.c (struct loclist_block)
 	(struct loclist_master): New structures.
 	(loclist_base, dwarf_loc_buffer): New variables.
 	(struct dwarf2_pinfo): New items dwarf_loc_buffer and=20
 	dwarf_loc_size.
 	(DWARF_LOC_BUFFER, DWARF_LOC_SIZE): New macros.
 	(dwarf2_read_loclist, dwarf2_read_loclist_blocks)
 	(dwarf_alloc_loclist_block, dwarf_alloc_loclist_master)
 	(dwarf2_loclist_lookup_block): New functions.
 	(psymtab_to_symtab_1): Call dwarf2_read_loclist().
 	(new_symbol): Handle .debug_loc references.
 
 Index: dwarf2read.c
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
 RCS file: /cvs/src/src/gdb/dwarf2read.c,v
 retrieving revision 1.66.2.2
 diff -u -p -r1.66.2.2 dwarf2read.c
 --- dwarf2read.c	25 Nov 2002 21:46:54 -0000	1.66.2.2
 +++ dwarf2read.c	31 Jan 2003 18:10:53 -0000
 @@ -312,6 +312,22 @@ struct dwarf_block
      char *data;
    };
 =20
 +struct loclist_block
 +  {
 +    CORE_ADDR lowpc, highpc;	/* Range where attribute is valid.  */
 +    struct dwarf_block blk;
 +    struct loclist_block *next;
 +  };
 +
 +struct loclist_master
 +  {
 +    unsigned int offset;	/* Offset of this block in .debug_loc.  */
 +    struct loclist_block *blocks;
 +    struct loclist_master *next;
 +  };
 +
 +static struct loclist_master *loclist_base;
 +
  /* We only hold one compilation unit's abbrevs in
     memory at any one time.  */
  #ifndef ABBREV_HASH_SIZE
 @@ -352,6 +368,7 @@ static char *dwarf_abbrev_buffer;
  static char *dwarf_line_buffer;
  static char *dwarf_str_buffer;
  static char *dwarf_macinfo_buffer;
 +static char *dwarf_loc_buffer;
 =20
  /* A zeroed version of a partial die for initialization purposes.  */
  static struct partial_die_info zeroed_partial_die;
 @@ -454,6 +471,13 @@ struct dwarf2_pinfo
     =20
      unsigned int dwarf_macinfo_size;
 =20
 +    /* Pointer to start of dwarf location list buffer for the objfile.  =
 */
 +
 +    char *dwarf_loc_buffer;
 +
 +    /* Size of dwarf location list section for the objfile.  */
 +
 +    unsigned int dwarf_loc_size;
    };
 =20
  #define PST_PRIVATE(p) ((struct dwarf2_pinfo *)(p)->read_symtab_private)=
 
 @@ -467,6 +491,8 @@ struct dwarf2_pinfo
  #define DWARF_STR_SIZE(p)    (PST_PRIVATE(p)->dwarf_str_size)
  #define DWARF_MACINFO_BUFFER(p) (PST_PRIVATE(p)->dwarf_macinfo_buffer)
  #define DWARF_MACINFO_SIZE(p)   (PST_PRIVATE(p)->dwarf_macinfo_size)
 +#define DWARF_LOC_BUFFER(p) (PST_PRIVATE(p)->dwarf_loc_buffer)
 +#define DWARF_LOC_SIZE(p)   (PST_PRIVATE(p)->dwarf_loc_size)
 =20
  /* Maintain an array of referenced fundamental types for the current
     compilation unit being read.  For DWARF version 1, we have to constru=
 ct
 @@ -688,6 +714,8 @@ char *dwarf2_read_section (struct objfil
 =20
  static void dwarf2_read_abbrevs (bfd *, unsigned int);
 =20
 +static void dwarf2_read_loclist (bfd *abfd, struct comp_unit_head *cu_he=
 ader);
 +
  static void dwarf2_empty_abbrev_table (PTR);
 =20
  static struct abbrev_info *dwarf2_lookup_abbrev (unsigned int);
 @@ -874,12 +902,6 @@ static char *dwarf_bool_name (unsigned i
 =20
  static char *dwarf_type_encoding_name (unsigned int);
 =20
 -#if 0
 -static char *dwarf_cfi_name (unsigned int);
 -
 -struct die_info *copy_die (struct die_info *);
 -#endif
 -
  static struct die_info *sibling_die (struct die_info *);
 =20
  static void dump_die (struct die_info *);
 @@ -906,6 +928,9 @@ static struct abbrev_info *dwarf_alloc_a
 =20
  static struct die_info *dwarf_alloc_die (void);
 =20
 +static struct loclist_block *dwarf_alloc_loclist_block (void);
 +static struct loclist_master *dwarf_alloc_loclist_master (void);
 +
  static void initialize_cu_func_list (void);
 =20
  static void add_to_cu_func_list (const char *, CORE_ADDR, CORE_ADDR);
 @@ -927,6 +952,7 @@ dwarf2_has_info (bfd *abfd)
    dwarf_line_offset =3D 0;
    dwarf_str_offset =3D 0;
    dwarf_macinfo_offset =3D 0;
 +  dwarf_loc_offset =3D 0;
    dwarf_frame_offset =3D 0;
    dwarf_eh_frame_offset =3D 0;
    bfd_map_over_sections (abfd, dwarf2_locate_sections, NULL);
 @@ -1035,6 +1061,13 @@ dwarf2_build_psymtabs (struct objfile *o
    else
      dwarf_macinfo_buffer =3D NULL;
 =20
 +  if (dwarf_loc_offset)
 +    dwarf_loc_buffer =3D dwarf2_read_section (objfile,
 +		    			    dwarf_loc_offset,
 +					    dwarf_loc_size);
 +  else
 +    dwarf_loc_buffer =3D NULL;
 + =20
    if (mainline
        || (objfile->global_psymbols.size =3D=3D 0
  	  && objfile->static_psymbols.size =3D=3D 0))
 @@ -1245,6 +1280,8 @@ dwarf2_build_psymtabs_hard (struct objfi
        DWARF_STR_SIZE (pst) =3D dwarf_str_size;
        DWARF_MACINFO_BUFFER (pst) =3D dwarf_macinfo_buffer;
        DWARF_MACINFO_SIZE (pst) =3D dwarf_macinfo_size;
 +      DWARF_LOC_BUFFER (pst) =3D dwarf_loc_buffer;
 +      DWARF_LOC_SIZE (pst) =3D dwarf_loc_size;
        baseaddr =3D ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (ob=
 jfile));
 =20
        /* Store the function that reads in the rest of the symbol table *=
 /
 @@ -1581,6 +1618,8 @@ psymtab_to_symtab_1 (struct partial_symt
    dwarf_str_size =3D DWARF_STR_SIZE (pst);
    dwarf_macinfo_buffer =3D DWARF_MACINFO_BUFFER (pst);
    dwarf_macinfo_size =3D DWARF_MACINFO_SIZE (pst);
 +  dwarf_loc_buffer =3D DWARF_LOC_BUFFER (pst);
 +  dwarf_loc_size =3D DWARF_LOC_SIZE (pst);
    baseaddr =3D ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (objfile));=
 
    cu_header_offset =3D offset;
    info_ptr =3D dwarf_info_buffer + offset;
 @@ -1598,6 +1637,7 @@ psymtab_to_symtab_1 (struct partial_symt
    dwarf2_read_abbrevs (abfd, cu_header.abbrev_offset);
    make_cleanup (dwarf2_empty_abbrev_table, NULL);
 =20
 +  dwarf2_read_loclist (abfd, &cu_header);
    dies =3D read_comp_unit (info_ptr, abfd, &cu_header);
 =20
    make_cleanup_free_die_list (dies);
 @@ -3408,6 +3448,115 @@ dwarf2_read_section (struct objfile *obj
    return buf;
  }
 =20
 +static struct loclist_block *
 +dwarf2_loclist_lookup_block (unsigned int offset)
 +{
 +  /* .debug_loc goes here ... mludvig */
 +  struct dwarf_block *blkp;
 +  struct loclist_master *ll_ptr;
 +
 +  ll_ptr =3D loclist_base;
 + =20
 +  while (ll_ptr && ll_ptr->offset !=3D offset)
 +    ll_ptr =3D ll_ptr->next;
 +
 +  if(!ll_ptr)
 +  {
 +    warning ("Couldn't find appropriate location list for offset %u\n",
 +		offset);
 +    return NULL;
 +  }
 + =20
 +  if (ll_ptr && !ll_ptr->blocks)
 +  {
 +    warning ("Loclist for off=3D%u doesn't have any blocks?\n", offset);=
 
 +    return NULL;
 +  }
 + =20
 +  return ll_ptr->blocks;
 +}
 +
 +static struct loclist_block *
 +dwarf2_read_loclist_blocks (bfd *abfd, char **base, char *end,=20
 +		unsigned int addr_size)
 +{
 +	char *ptr;
 +	CORE_ADDR lopc, hipc;
 +	unsigned int data_size;
 +	char *data_ptr;
 +	struct loclist_block *llb_first =3D NULL, *llb_last =3D NULL;
 +=09
 +	ptr =3D *base;
 +
 +	while (ptr < end) {
 +		if (addr_size =3D=3D 4) {
 +			lopc =3D read_4_bytes (abfd, ptr);
 +			ptr +=3D 4;
 +			hipc =3D read_4_bytes (abfd, ptr);
 +			ptr +=3D 4;
 +		}
 +		else if (addr_size =3D=3D 8) {
 +			lopc =3D read_8_bytes (abfd, ptr);
 +			ptr +=3D 8;
 +			hipc =3D read_8_bytes (abfd, ptr);
 +			ptr +=3D 8;
 +		}
 +		else
 +			error ("Address size =3D=3D %d ... unsupported!", addr_size);
 +
 +		if (lopc =3D=3D 0 && hipc =3D=3D 0)
 +			break;
 +
 +		if (lopc =3D=3D 0 && llb_last !=3D NULL)
 +		{
 +			ptr -=3D 8;
 +			break;
 +		}
 +
 +		if (llb_last =3D=3D NULL) {
 +			llb_last =3D dwarf_alloc_loclist_block ();
 +			llb_first =3D llb_last;
 +		}
 +		else {
 +			llb_last->next =3D dwarf_alloc_loclist_block ();
 +			llb_last =3D llb_last->next;
 +		}
 +
 +		llb_last->lowpc =3D lopc;
 +		llb_last->highpc =3D hipc;
 +
 +		llb_last->blk.size =3D read_2_bytes (abfd, ptr);
 +		ptr +=3D 2;
 +		llb_last->blk.data =3D ptr;
 +		ptr +=3D llb_last->blk.size;
 +	}
 +=09
 +	*base =3D ptr;
 +	return llb_first;
 +}
 +
 +static void=20
 +dwarf2_read_loclist (bfd *abfd, struct comp_unit_head *cu_header)
 +{
 +	char *loclist_ptr, *loclist_end;
 +	struct loclist_master *ll_master;
 +=09
 +	loclist_ptr =3D dwarf_loc_buffer;
 +	loclist_end =3D dwarf_loc_buffer + dwarf_loc_size;
 +
 +	while (loclist_ptr < loclist_end)
 +	{
 +		ll_master =3D dwarf_alloc_loclist_master();
 +		ll_master->next =3D loclist_base;
 +		loclist_base =3D ll_master;
 +
 +		ll_master->offset =3D loclist_ptr - dwarf_loc_buffer;
 +		ll_master->blocks =3D dwarf2_read_loclist_blocks=20
 +					(abfd, &loclist_ptr, loclist_end,
 +					 cu_header->addr_size);
 +	}
 +}
 +
  /* In DWARF version 2, the description of the debugging information is
     stored in a separate .debug_abbrev section.  Before we read any
     dies from a section we read in all abbreviations and install them
 @@ -4785,7 +4942,16 @@ new_symbol (struct die_info *die, struct
                    else if (attr->form =3D=3D DW_FORM_data4
                             || attr->form =3D=3D DW_FORM_data8)
                      {
 -                      complain (&dwarf2_complex_location_expr);
 +		      struct dwarf_block *blkp =3D NULL;
 +		      struct loclist_block *llbp;
 +
 +		      llbp =3D dwarf2_loclist_lookup_block (
 +				      (unsigned int)DW_ADDR (attr));
 +		      if (llbp)
 +			blkp =3D &llbp->blk;
 +		      if (blkp)
 +		        SYMBOL_VALUE_ADDRESS (sym) =3D
 +		          decode_locdesc (blkp, objfile, cu_header);
                      }
                    else
                      {
 @@ -4823,7 +4989,16 @@ new_symbol (struct die_info *die, struct
                    else if (attr->form =3D=3D DW_FORM_data4
                             || attr->form =3D=3D DW_FORM_data8)
                      {
 -                      complain (&dwarf2_complex_location_expr);
 +		      struct dwarf_block *blkp =3D NULL;
 +		      struct loclist_block *llbp;
 +
 +		      llbp =3D dwarf2_loclist_lookup_block (
 +				      (unsigned int)DW_ADDR (attr));
 +		      if (llbp)
 +			blkp =3D &llbp->blk;
 +		      if (blkp)
 +		        SYMBOL_VALUE_ADDRESS (sym) =3D addr =3D
 +		          decode_locdesc (blkp, objfile, cu_header);
                      }
                    else
                      {
 @@ -4882,8 +5057,31 @@ new_symbol (struct die_info *die, struct
  	  attr =3D dwarf_attr (die, DW_AT_location);
  	  if (attr)
  	    {
 -	      SYMBOL_VALUE (sym) =3D
 -		decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
 +	      if (attr_form_is_block (attr))
 +	      {
 +	        SYMBOL_VALUE (sym) =3D
 +		  decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
 +	      }
 +	      else if (attr->form =3D=3D DW_FORM_data4
 +		       || attr->form =3D=3D DW_FORM_data8)
 +	      {
 +		 struct dwarf_block *blkp =3D NULL;
 +		 struct loclist_block *llbp;
 +
 +		 llbp =3D dwarf2_loclist_lookup_block (
 +		   	      (unsigned int)DW_ADDR (attr));
 +		 if (llbp)
 +		   blkp =3D &llbp->blk;
 +		 if (blkp)
 +		   SYMBOL_VALUE_ADDRESS (sym) =3D
 +		     decode_locdesc (blkp, objfile, cu_header);
 +	      }
 +              else
 +                {
 +                  complain (&dwarf2_invalid_attrib_class, "DW_AT_locatio=
 n",
 +                            "external variable");
 +                  addr =3D 0;
 +                }
  	      if (isreg)
  		{
  		  SYMBOL_CLASS (sym) =3D LOC_REGPARM;
 @@ -6660,6 +6863,26 @@ dwarf_alloc_die (void)
    die =3D (struct die_info *) xmalloc (sizeof (struct die_info));
    memset (die, 0, sizeof (struct die_info));
    return (die);
 +}
 +
 +static struct loclist_block *
 +dwarf_alloc_loclist_block (void)
 +{
 +  struct loclist_block *llb;
 +
 +  llb =3D (struct loclist_block *) xmalloc (sizeof (struct loclist_block=
 ));
 +  memset (llb, 0, sizeof (struct loclist_block));
 +  return (llb);
 +}
 +
 +static struct loclist_master *
 +dwarf_alloc_loclist_master (void)
 +{
 +  struct loclist_master *llm;
 +
 +  llm =3D (struct loclist_master *) xmalloc (sizeof (struct loclist_mast=
 er));
 +  memset (llm, 0, sizeof (struct loclist_master));
 +  return (llm);
  }
 =20
  =0C
 
 --------------050605070107060100040601--
 
 
>How-To-Repeat:
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:


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