2003-02-21 Michal Ludvig * dwarf2read.c (struct comp_unit_head): Added lowpc, highpc. (struct loclist_block, struct loclist_master) (loclist_base, dwarf_loc_buffer): New variables. (struct dwarf2_pinfo): Added dwarf_loc_buffer, dwarf_loc_size. (DWARF_LOC_BUFFER, DWARF_LOC_SIZE): New macros. (dwarf2_read_loclist, dwarf_alloc_loclist_block) (dwarf_alloc_loclist_master): New functions. (dwarf2_build_psymtabs): Init dwarf_loc_buffer. (dwarf2_build_psymtabs_hard): Use dwarf_loc_{buffer,size}. (psymtab_to_symtab_1): Use dwarf_loc_{buffer,size}. Parse .debug_loc, fill lowpc/highpc. (dwarf2_update_symbol_from_loclist): New function. (update_symbol_class_function): New function type. (update_external_symbol_class, update_variable_symbol_class) (update_parameter_symbol_class, update_symbol_loclist_class): New functions with code moved from new_symbol(). (create_location_list): New function. (new_symbol): Add support for location lists, moved some parts to separate functions. (dwarf_alloc_loclist_block, dwarf_alloc_loclist_master): New helper functions. * findvar.c (read_var_value): Added searching in variable's location list. * symfile.h (dwarf2_update_symbol_from_loclist): New prototype. * symtab.h (union symbol_info_value, union symbol_aux_value): New unions cutted off struct general_symbol_info/struct symbol. (struct symbol_loclist): New. (struct symbol): New item loclist. (SYMBOL_LOCLIST): New macro. Index: dwarf2read.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2read.c,v retrieving revision 1.86 diff -u -p -r1.86 dwarf2read.c --- dwarf2read.c 14 Feb 2003 19:05:52 -0000 1.86 +++ dwarf2read.c 21 Feb 2003 09:53:13 -0000 @@ -221,6 +221,10 @@ struct comp_unit_head /* Pointer to the DIE associated with the compilation unit. */ struct die_info *die; + + /* PC bounds of this CU */ + + CORE_ADDR lowpc, highpc; }; /* The line number information for a compilation unit (found in the @@ -360,6 +364,24 @@ struct dwarf_block char *data; }; +struct loclist_block +{ + CORE_ADDR lowpc, highpc; /* Range where attribute is valid. */ + struct dwarf_block blk; + struct loclist_block *next; + struct loclist_master *parent; +}; + +struct loclist_master +{ + unsigned int offset; /* Offset of this block in .debug_loc. */ + CORE_ADDR baseaddr; + struct loclist_block *blocks; + struct loclist_master *next; +}; + +static struct loclist_master *loclist_base; + #ifndef ATTR_ALLOC_CHUNK #define ATTR_ALLOC_CHUNK 4 #endif @@ -394,6 +416,7 @@ static char *dwarf_line_buffer; static char *dwarf_str_buffer; static char *dwarf_macinfo_buffer; static char *dwarf_ranges_buffer; +static char *dwarf_loc_buffer; /* A zeroed version of a partial die for initialization purposes. */ static struct partial_die_info zeroed_partial_die; @@ -510,6 +533,13 @@ struct dwarf2_pinfo unsigned int dwarf_ranges_size; + /* 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; }; #define PST_PRIVATE(p) ((struct dwarf2_pinfo *)(p)->read_symtab_private) @@ -525,6 +555,8 @@ struct dwarf2_pinfo #define DWARF_MACINFO_SIZE(p) (PST_PRIVATE(p)->dwarf_macinfo_size) #define DWARF_RANGES_BUFFER(p) (PST_PRIVATE(p)->dwarf_ranges_buffer) #define DWARF_RANGES_SIZE(p) (PST_PRIVATE(p)->dwarf_ranges_size) +#define DWARF_LOC_BUFFER(p) (PST_PRIVATE(p)->dwarf_loc_buffer) +#define DWARF_LOC_SIZE(p) (PST_PRIVATE(p)->dwarf_loc_size) /* Maintain an array of referenced fundamental types for the current compilation unit being read. For DWARF version 1, we have to construct @@ -676,6 +708,8 @@ char *dwarf2_read_section (struct objfil static void dwarf2_read_abbrevs (bfd *abfd, struct comp_unit_head *cu_header); +static void dwarf2_read_loclist (bfd *abfd, struct comp_unit_head *cu_header); + static void dwarf2_empty_abbrev_table (void *); static struct abbrev_info *dwarf2_lookup_abbrev (unsigned int, @@ -901,6 +935,9 @@ static struct abbrev_info *dwarf_alloc_a static struct die_info *dwarf_alloc_die (void); +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); static void add_to_cu_func_list (const char *, CORE_ADDR, CORE_ADDR); @@ -922,6 +959,7 @@ dwarf2_has_info (bfd *abfd) dwarf_line_offset = 0; dwarf_str_offset = 0; dwarf_macinfo_offset = 0; + dwarf_loc_offset = 0; dwarf_frame_offset = 0; dwarf_eh_frame_offset = 0; dwarf_ranges_offset = 0; @@ -1061,6 +1099,14 @@ dwarf2_build_psymtabs (struct objfile *o else dwarf_ranges_buffer = NULL; + if (dwarf_loc_offset) + dwarf_loc_buffer = dwarf2_read_section (objfile, + dwarf_loc_offset, + dwarf_loc_size, + dwarf_loc_section); + else + dwarf_loc_buffer = NULL; + if (mainline || (objfile->global_psymbols.size == 0 && objfile->static_psymbols.size == 0)) @@ -1287,6 +1333,8 @@ dwarf2_build_psymtabs_hard (struct objfi DWARF_MACINFO_SIZE (pst) = dwarf_macinfo_size; DWARF_RANGES_BUFFER (pst) = dwarf_ranges_buffer; DWARF_RANGES_SIZE (pst) = dwarf_ranges_size; + DWARF_LOC_BUFFER (pst) = dwarf_loc_buffer; + DWARF_LOC_SIZE (pst) = dwarf_loc_size; baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); /* Store the function that reads in the rest of the symbol table */ @@ -1614,6 +1662,8 @@ psymtab_to_symtab_1 (struct partial_symt struct symtab *symtab; struct cleanup *back_to; + memset (&cu_header, 0, sizeof (cu_header)); + /* Set local variables from the partial symbol table info. */ offset = DWARF_INFO_OFFSET (pst); dwarf_info_buffer = DWARF_INFO_BUFFER (pst); @@ -1627,6 +1677,8 @@ psymtab_to_symtab_1 (struct partial_symt dwarf_macinfo_size = DWARF_MACINFO_SIZE (pst); dwarf_ranges_buffer = DWARF_RANGES_BUFFER (pst); dwarf_ranges_size = DWARF_RANGES_SIZE (pst); + dwarf_loc_buffer = DWARF_LOC_BUFFER (pst); + dwarf_loc_size = DWARF_LOC_SIZE (pst); baseaddr = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (objfile)); cu_header_offset = offset; info_ptr = dwarf_info_buffer + offset; @@ -1644,13 +1696,13 @@ psymtab_to_symtab_1 (struct partial_symt dwarf2_read_abbrevs (abfd, &cu_header); make_cleanup (dwarf2_empty_abbrev_table, cu_header.dwarf2_abbrevs); + dwarf2_read_loclist (abfd, &cu_header); + dies = read_comp_unit (info_ptr, abfd, &cu_header); make_cleanup_free_die_list (dies); - /* Do line number decoding in read_file_scope () */ cu_header.die = dies; - process_die (dies, objfile, &cu_header); if (!dwarf2_get_pc_bounds (dies, &lowpc, &highpc, objfile, &cu_header)) { @@ -1677,6 +1729,13 @@ psymtab_to_symtab_1 (struct partial_symt } } } + + cu_header.lowpc = lowpc; + cu_header.highpc = highpc; + + /* Do line number decoding in read_file_scope () */ + process_die (dies, objfile, &cu_header); + symtab = end_symtab (highpc + baseaddr, objfile, SECT_OFF_TEXT (objfile)); /* Set symtab language to language from DW_AT_language. @@ -3663,6 +3722,124 @@ dwarf2_read_section (struct objfile *obj return buf; } +/* The following functions parse .debug_loc section and + store the contents to a list of lists. These lists are + then used when creating the actual "symbol" structures. */ +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 = loclist_base; + + while (ll_ptr && ll_ptr->offset != offset) + ll_ptr = ll_ptr->next; + + if (!ll_ptr) + { + warning ("Couldn't find appropriate location list for offset %u\n", + offset); + return NULL; + } + + if (ll_ptr && !ll_ptr->blocks) + { + warning ("Loclist for off=%u doesn't have any blocks?\n", offset); + return NULL; + } + + return ll_ptr->blocks; +} + +static struct loclist_block * +dwarf2_read_loclist_blocks (bfd *abfd, char **base, char *end, + unsigned int addr_size, + struct loclist_master *ll_master) +{ + char *ptr; + CORE_ADDR lowpc, highpc; + unsigned int data_size; + char *data_ptr; + struct loclist_block *llb_first = NULL, *llb_last = NULL; + + ptr = *base; + + while (ptr < end) + { + if (addr_size == 4) + { + lowpc = read_4_bytes (abfd, ptr); + ptr += 4; + highpc = read_4_bytes (abfd, ptr); + ptr += 4; + } + else if (addr_size == 8) + { + lowpc = read_8_bytes (abfd, ptr); + ptr += 8; + highpc = read_8_bytes (abfd, ptr); + ptr += 8; + } + else + error ("Address size == %d ... unsupported!", addr_size); + + if (lowpc == 0 && highpc == 0) + break; + + if (lowpc == (CORE_ADDR) -1L) + { + ll_master->baseaddr = highpc; + continue; + } + + if (llb_last == NULL) + { + llb_last = dwarf_alloc_loclist_block (); + llb_first = llb_last; + } + else + { + llb_last->next = dwarf_alloc_loclist_block (); + llb_last = llb_last->next; + } + + llb_last->parent = ll_master; + llb_last->lowpc = lowpc; + llb_last->highpc = highpc; + + llb_last->blk.size = read_2_bytes (abfd, ptr); + ptr += 2; + llb_last->blk.data = ptr; + ptr += llb_last->blk.size; + } + + *base = ptr; + return llb_first; +} + +static void +dwarf2_read_loclist (bfd *abfd, struct comp_unit_head *cu_header) +{ + char *loclist_ptr, *loclist_end; + struct loclist_master *ll_master; + + loclist_ptr = dwarf_loc_buffer; + loclist_end = dwarf_loc_buffer + dwarf_loc_size; + + while (loclist_ptr < loclist_end) + { + ll_master = dwarf_alloc_loclist_master (); + ll_master->next = loclist_base; + loclist_base = ll_master; + + ll_master->offset = loclist_ptr - dwarf_loc_buffer; + ll_master->blocks = dwarf2_read_loclist_blocks + (abfd, &loclist_ptr, loclist_end, cu_header->addr_size, ll_master); + } +} + /* 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 @@ -4952,6 +5129,173 @@ dwarf2_start_subfile (char *filename, ch start_subfile (filename, dirname); } +void +dwarf2_update_symbol_from_loclist (struct symbol *sym, + struct symbol_loclist *symll) +{ + SYMBOL_CLASS (sym) = SYMBOL_CLASS (symll); + memcpy ((void *) &sym->ginfo.value, (void *) &symll->ginfo.value, + sizeof (sym->ginfo.value)); + memcpy ((void *) &sym->aux_value, (void *) &symll->aux_value, + sizeof (union symbol_aux_value)); +} + +typedef void (update_symbol_class_function) (struct symbol * sym, + struct objfile * objfile); + +static void +update_external_symbol_class (struct symbol *sym, struct objfile *objfile) +{ + if (is_thread_local) + { + /* SYMBOL_VALUE_ADDRESS contains at this point the + offset of the variable within the thread local + storage. */ + SYMBOL_CLASS (sym) = LOC_THREAD_LOCAL_STATIC; + SYMBOL_OBJFILE (sym) = objfile; + } + /* In shared libraries the address of the variable + in the location descriptor might still be relocatable, + so its value could be zero. + Enter the symbol as a LOC_UNRESOLVED symbol, if its + value is zero, the address of the variable will then + be determined from the minimal symbol table whenever + the variable is referenced. */ + if (SYMBOL_VALUE_ADDRESS (sym)) + { + fixup_symbol_section (sym, objfile); + SYMBOL_VALUE_ADDRESS (sym) += + ANOFFSET (objfile->section_offsets, SYMBOL_SECTION (sym)); + SYMBOL_CLASS (sym) = LOC_STATIC; + } + else + SYMBOL_CLASS (sym) = LOC_UNRESOLVED; +} + +static void +update_variable_symbol_class (struct symbol *sym, struct objfile *objfile) +{ + if (optimized_out) + SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT; + else if (isreg) + { + SYMBOL_CLASS (sym) = LOC_REGISTER; + SYMBOL_VALUE (sym) = DWARF2_REG_TO_REGNUM (SYMBOL_VALUE (sym)); + } + else if (offreg) + { + SYMBOL_CLASS (sym) = LOC_BASEREG; + SYMBOL_BASEREG (sym) = DWARF2_REG_TO_REGNUM (basereg); + } + else if (islocal) + SYMBOL_CLASS (sym) = LOC_LOCAL; + else if (is_thread_local) + { + SYMBOL_CLASS (sym) = LOC_THREAD_LOCAL_STATIC; + SYMBOL_OBJFILE (sym) = objfile; + } + else + { + fixup_symbol_section (sym, objfile); + SYMBOL_VALUE_ADDRESS (sym) += + ANOFFSET (objfile->section_offsets, SYMBOL_SECTION (sym)); + SYMBOL_CLASS (sym) = LOC_STATIC; + } +} + +static void +update_parameter_symbol_class (struct symbol *sym, struct objfile *objfile) +{ + if (isreg) + { + SYMBOL_CLASS (sym) = LOC_REGPARM; + SYMBOL_VALUE (sym) = DWARF2_REG_TO_REGNUM (SYMBOL_VALUE (sym)); + } + else if (offreg) + { + if (isderef) + { + if (basereg != frame_base_reg) + dwarf2_complex_location_expr_complaint (); + SYMBOL_CLASS (sym) = LOC_REF_ARG; + } + else + { + SYMBOL_CLASS (sym) = LOC_BASEREG_ARG; + SYMBOL_BASEREG (sym) = DWARF2_REG_TO_REGNUM (basereg); + } + } + else + SYMBOL_CLASS (sym) = LOC_ARG; +} + +static void +update_symbol_loclist_class (struct symbol_loclist *symll, + struct objfile *objfile, + update_symbol_class_function * update_function) +{ + struct symbol *sym = alloca (sizeof (struct symbol)); + + SYMBOL_VALUE (sym) = SYMBOL_VALUE (symll); + SYMBOL_BASEREG (sym) = SYMBOL_BASEREG (symll); + + (*update_function) (sym, objfile); + + SYMBOL_VALUE (symll) = SYMBOL_VALUE (sym); + SYMBOL_BASEREG (symll) = SYMBOL_BASEREG (sym); + SYMBOL_CLASS (symll) = SYMBOL_CLASS (sym); +} + +static void +create_location_list (struct symbol *sym, struct objfile *objfile, + struct attribute *attr, + const struct comp_unit_head *cu_header, + update_symbol_class_function * update_function) +{ + struct dwarf_block *blkp = NULL; + struct loclist_block *llbp; + struct symbol_loclist *last_loclist_ptr = NULL; + CORE_ADDR baseaddr; + + llbp = dwarf2_loclist_lookup_block ((unsigned int) DW_ADDR (attr)); + gdb_assert (llbp != NULL); + blkp = &llbp->blk; + gdb_assert (blkp != NULL); + + SYMBOL_VALUE_ADDRESS (sym) = decode_locdesc (blkp, objfile, cu_header); + + (*update_function) (sym, objfile); + + baseaddr = llbp->parent->baseaddr ? + llbp->parent->baseaddr : cu_header->lowpc; + baseaddr += ANOFFSET (objfile->section_offsets, objfile->sect_index_text); + + /* Create location list. */ + while (llbp) + { + struct symbol_loclist *symll; + + blkp = &llbp->blk; + gdb_assert (blkp != NULL); + + symll = xmalloc (sizeof (struct symbol_loclist)); + symll->ginfo.value.address = decode_locdesc (blkp, objfile, cu_header); + + symll->lowpc = llbp->lowpc + baseaddr; + symll->highpc = llbp->highpc + baseaddr; + + if (last_loclist_ptr == NULL) + SYMBOL_LOCLIST (sym) = symll; + else + last_loclist_ptr->next = symll; + last_loclist_ptr = symll; + + update_symbol_loclist_class (symll, objfile, update_function); + + llbp = llbp->next; + } +} + /* Given a pointer to a DWARF information entry, figure out if we need to make a symbol table entry for it, and if so, create a new entry and return a pointer to it. @@ -5048,11 +5392,13 @@ new_symbol (struct die_info *die, struct { SYMBOL_VALUE_ADDRESS (sym) = decode_locdesc (DW_BLOCK (attr), objfile, cu_header); + update_external_symbol_class (sym, objfile); } else if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8) { - dwarf2_complex_location_expr_complaint (); + create_location_list (sym, objfile, attr, cu_header, + update_external_symbol_class); } else { @@ -5060,32 +5406,6 @@ new_symbol (struct die_info *die, struct "external variable"); } add_symbol_to_list (sym, &global_symbols); - if (is_thread_local) - { - /* SYMBOL_VALUE_ADDRESS contains at this point the - offset of the variable within the thread local - storage. */ - SYMBOL_CLASS (sym) = LOC_THREAD_LOCAL_STATIC; - SYMBOL_OBJFILE (sym) = objfile; - } - - /* In shared libraries the address of the variable - in the location descriptor might still be relocatable, - so its value could be zero. - Enter the symbol as a LOC_UNRESOLVED symbol, if its - value is zero, the address of the variable will then - be determined from the minimal symbol table whenever - the variable is referenced. */ - else if (SYMBOL_VALUE_ADDRESS (sym)) - { - fixup_symbol_section (sym, objfile); - SYMBOL_VALUE_ADDRESS (sym) += - ANOFFSET (objfile->section_offsets, - SYMBOL_SECTION (sym)); - SYMBOL_CLASS (sym) = LOC_STATIC; - } - else - SYMBOL_CLASS (sym) = LOC_UNRESOLVED; } else { @@ -5094,11 +5414,13 @@ new_symbol (struct die_info *die, struct { SYMBOL_VALUE (sym) = addr = decode_locdesc (DW_BLOCK (attr), objfile, cu_header); + update_variable_symbol_class (sym, objfile); } else if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8) { - dwarf2_complex_location_expr_complaint (); + create_location_list (sym, objfile, attr, cu_header, + update_variable_symbol_class); } else { @@ -5107,38 +5429,6 @@ new_symbol (struct die_info *die, struct addr = 0; } add_symbol_to_list (sym, list_in_scope); - if (optimized_out) - { - SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT; - } - else if (isreg) - { - SYMBOL_CLASS (sym) = LOC_REGISTER; - SYMBOL_VALUE (sym) = - DWARF2_REG_TO_REGNUM (SYMBOL_VALUE (sym)); - } - else if (offreg) - { - SYMBOL_CLASS (sym) = LOC_BASEREG; - SYMBOL_BASEREG (sym) = DWARF2_REG_TO_REGNUM (basereg); - } - else if (islocal) - { - SYMBOL_CLASS (sym) = LOC_LOCAL; - } - else if (is_thread_local) - { - SYMBOL_CLASS (sym) = LOC_THREAD_LOCAL_STATIC; - SYMBOL_OBJFILE (sym) = objfile; - } - else - { - fixup_symbol_section (sym, objfile); - SYMBOL_VALUE_ADDRESS (sym) = - addr + ANOFFSET (objfile->section_offsets, - SYMBOL_SECTION (sym)); - SYMBOL_CLASS (sym) = LOC_STATIC; - } } } else @@ -5162,31 +5452,21 @@ new_symbol (struct die_info *die, struct attr = dwarf_attr (die, DW_AT_location); if (attr) { - SYMBOL_VALUE (sym) = - decode_locdesc (DW_BLOCK (attr), objfile, cu_header); - if (isreg) + if (attr_form_is_block (attr)) { - SYMBOL_CLASS (sym) = LOC_REGPARM; SYMBOL_VALUE (sym) = - DWARF2_REG_TO_REGNUM (SYMBOL_VALUE (sym)); + decode_locdesc (DW_BLOCK (attr), objfile, cu_header); + update_parameter_symbol_class (sym, objfile); } - else if (offreg) + else if (attr->form == DW_FORM_data4 + || attr->form == DW_FORM_data8) { - if (isderef) - { - if (basereg != frame_base_reg) - dwarf2_complex_location_expr_complaint (); - SYMBOL_CLASS (sym) = LOC_REF_ARG; - } - else - { - SYMBOL_CLASS (sym) = LOC_BASEREG_ARG; - SYMBOL_BASEREG (sym) = DWARF2_REG_TO_REGNUM (basereg); - } + create_location_list (sym, objfile, attr, cu_header, + update_parameter_symbol_class); } else { - SYMBOL_CLASS (sym) = LOC_ARG; + dwarf2_complex_location_expr_complaint (); } } attr = dwarf_attr (die, DW_AT_const_value); @@ -6992,6 +7272,26 @@ dwarf_alloc_die (void) memset (die, 0, sizeof (struct die_info)); return (die); } + +static struct loclist_block * +dwarf_alloc_loclist_block (void) +{ + struct loclist_block *llb; + + llb = (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 = (struct loclist_master *) xmalloc (sizeof (struct loclist_master)); + memset (llm, 0, sizeof (struct loclist_master)); + return (llm); +} /* Macro support. */ Index: findvar.c =================================================================== RCS file: /cvs/src/src/gdb/findvar.c,v retrieving revision 1.47 diff -u -p -r1.47 findvar.c --- findvar.c 20 Feb 2003 17:17:23 -0000 1.47 +++ findvar.c 21 Feb 2003 09:53:13 -0000 @@ -415,12 +415,15 @@ symbol_read_needs_frame (struct symbol * If FRAME is NULL, use the deprecated_selected_frame. */ struct value * -read_var_value (register struct symbol *var, struct frame_info *frame) +read_var_value (register struct symbol *varorig, struct frame_info *frame) { register struct value *v; - struct type *type = SYMBOL_TYPE (var); + struct type *type = SYMBOL_TYPE (varorig); CORE_ADDR addr; register int len; + struct symbol *var = alloca (sizeof (struct symbol)); + + memcpy (var, varorig, sizeof (struct symbol)); v = allocate_value (type); VALUE_LVAL (v) = lval_memory; /* The most likely possibility. */ @@ -431,6 +434,37 @@ read_var_value (register struct symbol * if (frame == NULL) frame = deprecated_selected_frame; + if (var->loclist) + { + struct symbol_loclist *llp = var->loclist; + int i = 0; + + if (info_verbose) + printf (" (%s(%p) ", SYMBOL_NAME (var), (void *) frame->pc); + while (llp) + { + if (llp->lowpc <= frame->pc && llp->highpc > frame->pc) + break; + llp = llp->next; + } + + if (llp) + { + dwarf2_update_symbol_from_loclist (var, llp); + if (info_verbose) + printf (" %p/%p ) ", (void *) llp->lowpc, (void *) llp->highpc); + } + else + { + SYMBOL_CLASS (var) = LOC_OPTIMIZED_OUT; + if (info_verbose) + printf_filtered + ("Variable '%s' has a location list but I couldn't\n" + "find an entry for pc=%p\n", SYMBOL_NAME (var), + (void *) frame->pc); + } + } + switch (SYMBOL_CLASS (var)) { case LOC_CONST: Index: symfile.h =================================================================== RCS file: /cvs/src/src/gdb/symfile.h,v retrieving revision 1.19 diff -u -p -r1.19 symfile.h --- symfile.h 20 Feb 2003 00:01:06 -0000 1.19 +++ symfile.h 21 Feb 2003 09:53:14 -0000 @@ -317,6 +317,9 @@ extern int dwarf2_has_info (bfd * abfd); extern void dwarf2_build_psymtabs (struct objfile *, int); extern void dwarf2_build_frame_info (struct objfile *); +extern void dwarf2_update_symbol_from_loclist (struct symbol *sym, + struct symbol_loclist *symll); + /* From mdebugread.c */ /* Hack to force structures to exist before use in parameter list. */ Index: symtab.h =================================================================== RCS file: /cvs/src/src/gdb/symtab.h,v retrieving revision 1.60 diff -u -p -r1.60 symtab.h --- symtab.h 20 Feb 2003 17:17:25 -0000 1.60 +++ symtab.h 21 Feb 2003 09:53:14 -0000 @@ -42,29 +42,13 @@ struct blockvector; #define BYTE_BITFIELD /*nothing */ #endif -/* Define a structure for the information that is common to all symbol types, - including minimal symbols, partial symbols, and full symbols. In a - multilanguage environment, some language specific information may need to - be recorded along with each symbol. - - These fields are ordered to encourage good packing, since we frequently - have tens or hundreds of thousands of these. */ +/* Value of the symbol. Which member of this union to use, and what + it means, depends on what kind of symbol this is and its + SYMBOL_CLASS. See comments there for more details. All of these + are in host byte order (though what they point to might be in + target byte order, e.g. LOC_CONST_BYTES). */ -struct general_symbol_info -{ - /* Name of the symbol. This is a required field. Storage for the name is - allocated on the psymbol_obstack or symbol_obstack for the associated - objfile. */ - - char *name; - - /* Value of the symbol. Which member of this union to use, and what - it means, depends on what kind of symbol this is and its - SYMBOL_CLASS. See comments there for more details. All of these - are in host byte order (though what they point to might be in - target byte order, e.g. LOC_CONST_BYTES). */ - - union +union symbol_info_value { /* The fact that this is a long not a LONGEST mainly limits the range of a LOC_CONST. Since LOC_CONST_BYTES exists, I'm not @@ -80,8 +64,25 @@ struct general_symbol_info /* for opaque typedef struct chain */ struct symbol *chain; - } - value; + }; + +/* Define a structure for the information that is common to all symbol types, + including minimal symbols, partial symbols, and full symbols. In a + multilanguage environment, some language specific information may need to + be recorded along with each symbol. + + These fields are ordered to encourage good packing, since we frequently + have tens or hundreds of thousands of these. */ + +struct general_symbol_info +{ + /* Name of the symbol. This is a required field. Storage for the name is + allocated on the psymbol_obstack or symbol_obstack for the associated + objfile. */ + + char *name; + + union symbol_info_value value; /* Since one and only one language can apply, wrap the language specific information inside a union. */ @@ -501,6 +502,27 @@ struct alias_list struct alias_list *next; }; +union symbol_aux_value +{ + /* Used by LOC_BASEREG and LOC_BASEREG_ARG. */ + short basereg; + + /* Used by LOC_THREAD_LOCAL_STATIC. The objfile in which this + symbol is defined. To find a thread-local variable (e.g., a + variable declared with the `__thread' storage class), we may + need to know which object file it's in. */ + struct objfile *objfile; +}; + +struct symbol_loclist + { + CORE_ADDR lowpc, highpc; + enum address_class aclass BYTE_BITFIELD; + struct general_symbol_info ginfo; + union symbol_aux_value aux_value; + struct symbol_loclist *next; + }; + struct symbol { @@ -534,19 +556,7 @@ struct symbol /* Some symbols require an additional value to be recorded on a per- symbol basis. Stash those values here. */ - union - { - /* Used by LOC_BASEREG and LOC_BASEREG_ARG. */ - short basereg; - - /* Used by LOC_THREAD_LOCAL_STATIC. The objfile in which this - symbol is defined. To find a thread-local variable (e.g., a - variable declared with the `__thread' storage class), we may - need to know which object file it's in. */ - struct objfile *objfile; - } - aux_value; - + union symbol_aux_value aux_value; /* Link to a list of aliases for this symbol. Only a "primary/main symbol may have aliases. */ @@ -557,6 +567,8 @@ struct symbol struct range_list *ranges; struct symbol *hash_next; + + struct symbol_loclist *loclist; }; @@ -568,6 +580,7 @@ struct symbol #define SYMBOL_OBJFILE(symbol) (symbol)->aux_value.objfile #define SYMBOL_ALIASES(symbol) (symbol)->aliases #define SYMBOL_RANGES(symbol) (symbol)->ranges +#define SYMBOL_LOCLIST(symbol) (symbol)->loclist /* A partial_symbol records the name, namespace, and address class of symbols whose types we have not parsed yet. For functions, it also