From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21384 invoked by alias); 1 Feb 2003 07:50:15 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 21374 invoked from network); 1 Feb 2003 07:50:14 -0000 Received: from unknown (HELO kerberos.suse.cz) (195.47.106.10) by 172.16.49.205 with SMTP; 1 Feb 2003 07:50:14 -0000 Received: from chimera.suse.cz (chimera.suse.cz [10.20.0.2]) by kerberos.suse.cz (SuSE SMTP server) with ESMTP id 91D5359D353 for ; Sat, 1 Feb 2003 08:50:13 +0100 (CET) Received: from suse.cz (naga.suse.cz [10.20.1.16]) by chimera.suse.cz (8.11.0/8.11.0/SuSE Linux 8.11.0-0.4) with ESMTP id h117oD422500 for ; Sat, 1 Feb 2003 08:50:13 +0100 X-Authentication-Warning: chimera.suse.cz: Host naga.suse.cz [10.20.1.16] claimed to be suse.cz Message-ID: <3E3B7C35.6030208@suse.cz> Date: Sat, 01 Feb 2003 07:50:00 -0000 From: Michal Ludvig Organization: SuSE CR User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.2.1) Gecko/20021130 X-Accept-Language: cs, cz, en MIME-Version: 1.0 To: GDB Patches Subject: [RFA] Location list support. Content-Type: multipart/mixed; boundary="------------050605070107060100040601" X-SW-Source: 2003-02/txt/msg00014.txt.bz2 This is a multi-part message in MIME format. --------------050605070107060100040601 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Content-length: 786 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" Content-length: 11705 2003-02-01 Michal Ludvig * 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=20=20=20=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 construct @@ -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_head= er); + 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=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 (objf= ile)); =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=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=20 + if (ll_ptr && !ll_ptr->blocks) + { + warning ("Loclist for off=3D%u doesn't have any blocks?\n", offset); + return NULL; + } +=20=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_location", + "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_master= )); + memset (llm, 0, sizeof (struct loclist_master)); + return (llm); } =20 =0C --------------050605070107060100040601--