This is the mail archive of the
gdb-prs@sources.redhat.com
mailing list for the GDB project.
pending/1029: [RFA] Location list support.
- From: Michal Ludvig <mludvig at suse dot cz>
- To: gdb-gnats at sources dot redhat dot com
- Date: Sat, 01 Feb 2003 08:50:13 +0100
- Subject: 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: