diff options
author | Daniel Jacobowitz <drow@false.org> | 2003-04-13 15:43:35 +0000 |
---|---|---|
committer | Daniel Jacobowitz <drow@false.org> | 2003-04-13 15:43:35 +0000 |
commit | 0d53c4c49facfc7400795d0d4fc7489b296d743d (patch) | |
tree | f448041b3ca20debb7bbb7f2614ffd78abd7d3eb /gdb/dwarf2read.c | |
parent | 6aca59a35914f39148f06d4d43f56a56c3cc4e55 (diff) | |
download | gdb-0d53c4c49facfc7400795d0d4fc7489b296d743d.zip gdb-0d53c4c49facfc7400795d0d4fc7489b296d743d.tar.gz gdb-0d53c4c49facfc7400795d0d4fc7489b296d743d.tar.bz2 |
2003-04-13 Daniel Jacobowitz <drow@mvista.com>
* dwarf2expr.c (dwarf2_read_address): Renamed from read_address;
made non-static.
(execute_stack_op): All callers updated.
* dwarf2expr.h: Add prototype for dwarf2_read_address.
* dwarf2loc.c (find_location_expression): New function.
(dwarf_expr_frame_base): Call it.
(dwarf2_evaluate_loc_desc): Handle 0-length location expressions.
(dwarf2_tracepoint_var_ref): New function, broken out from
locexpr_tracepoint_var_ref.
(locexpr_tracepoint_var_ref): Call dwarf2_tracepoint_var_ref.
Make static.
(loclist_read_variable, loclist_read_needs_frame): New functions.
(loclist_describe_location, loclist_tracepoint_var_ref): New
functions.
(dwarf2_loclist_funcs): New struct location_funcs.
* dwarf2loc.h (struct dwarf2_loclist_baton): New type.
(struct dwarf2_locexpr_baton): Add comments.
(dwarf2_loclist_funcs): New extern.
* dwarf2read.c (struct comp_unit_head): Remove DIE member, add
base_address and base_known.
(dwarf_loc_buffer): New variable.
(struct dwarf2_pinfo): Add dwarf_loc_buffer and dwarf_loc_size.
(DWARF_LOC_BUFFER, DWARF_LOC_SIZE): New macros.
(dwarf2_has_info): Initialize dwarf_loc_offset.
(dwarf2_build_psymtabs): Read in .debug_loc.
(dwarf2_build_psymtabs_hard): Use DWARF_LOC_BUFFER and
DWARF_LOC_SIZE.
(psymtab_to_symtab_1): Likewise. Move base address calculation
here, from...
(dwarf2_get_pc_bounds): ... here. Use the base address from
cu_header.
(dwarf2_symbol_mark_computed): Handle location lists.
Diffstat (limited to 'gdb/dwarf2read.c')
-rw-r--r-- | gdb/dwarf2read.c | 151 |
1 files changed, 104 insertions, 47 deletions
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index c77642d..b5fd389 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -220,9 +220,13 @@ struct comp_unit_head struct abbrev_info *dwarf2_abbrevs[ABBREV_HASH_SIZE]; - /* Pointer to the DIE associated with the compilation unit. */ + /* Base address of this compilation unit. */ - struct die_info *die; + CORE_ADDR base_address; + + /* Non-zero if base_address has been set. */ + + int base_known; }; /* The line number information for a compilation unit (found in the @@ -395,6 +399,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; @@ -511,6 +516,13 @@ struct dwarf2_pinfo unsigned int dwarf_ranges_size; + /* Pointer to start of dwarf locations buffer for the objfile. */ + + char *dwarf_loc_buffer; + + /* Size of dwarf locations buffer for the objfile. */ + + unsigned int dwarf_loc_size; }; #define PST_PRIVATE(p) ((struct dwarf2_pinfo *)(p)->read_symtab_private) @@ -526,6 +538,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 @@ -926,6 +940,7 @@ dwarf2_has_info (bfd *abfd) dwarf_frame_offset = 0; dwarf_eh_frame_offset = 0; dwarf_ranges_offset = 0; + dwarf_loc_offset = 0; bfd_map_over_sections (abfd, dwarf2_locate_sections, NULL); if (dwarf_info_offset && dwarf_abbrev_offset) @@ -1062,6 +1077,14 @@ dwarf2_build_psymtabs (struct objfile *objfile, int mainline) 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)) @@ -1283,6 +1306,8 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) 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 */ @@ -1607,6 +1632,7 @@ psymtab_to_symtab_1 (struct partial_symtab *pst) char *info_ptr; struct symtab *symtab; struct cleanup *back_to; + struct attribute *attr; /* Set local variables from the partial symbol table info. */ offset = DWARF_INFO_OFFSET (pst); @@ -1621,6 +1647,8 @@ psymtab_to_symtab_1 (struct partial_symtab *pst) 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; @@ -1642,8 +1670,32 @@ psymtab_to_symtab_1 (struct partial_symtab *pst) make_cleanup_free_die_list (dies); + /* Find the base address of the compilation unit for range lists and + location lists. It will normally be specified by DW_AT_low_pc. + In DWARF-3 draft 4, the base address could be overridden by + DW_AT_entry_pc. It's been removed, but GCC still uses this for + compilation units with discontinuous ranges. */ + + cu_header.base_known = 0; + cu_header.base_address = 0; + + attr = dwarf_attr (dies, DW_AT_entry_pc); + if (attr) + { + cu_header.base_address = DW_ADDR (attr); + cu_header.base_known = 1; + } + else + { + attr = dwarf_attr (dies, DW_AT_low_pc); + if (attr) + { + cu_header.base_address = DW_ADDR (attr); + cu_header.base_known = 1; + } + } + /* 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)) @@ -2122,40 +2174,18 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc, .debug_renges section. */ unsigned int offset = DW_UNSND (attr); /* Base address selection entry. */ - CORE_ADDR base = 0; - int found_base = 0; + CORE_ADDR base; + int found_base; int dummy; unsigned int i; char *buffer; CORE_ADDR marker; int low_set; - /* The applicable base address is determined by (1) the closest - preceding base address selection entry in the range list or - (2) the DW_AT_low_pc of the compilation unit. */ - - /* ??? Was in dwarf3 draft4, and has since been removed. - GCC still uses it though. */ - attr = dwarf_attr (cu_header->die, DW_AT_entry_pc); - if (attr) - { - base = DW_ADDR (attr); - found_base = 1; - } - - if (!found_base) - { - attr = dwarf_attr (cu_header->die, DW_AT_low_pc); - if (attr) - { - base = DW_ADDR (attr); - found_base = 1; - } - } - + found_base = cu_header->base_known; + base = cu_header->base_address; buffer = dwarf_ranges_buffer + offset; - /* Read in the largest possible address. */ marker = read_address (obfd, buffer, cu_header, &dummy); if ((marker & mask) == mask) @@ -7328,26 +7358,53 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym, const struct comp_unit_head *cu_header, struct objfile *objfile) { - struct dwarf2_locexpr_baton *baton; - - /* When support for location lists is added, this will go away. */ - if (!attr_form_is_block (attr)) + if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8) { - dwarf2_complex_location_expr_complaint (); - return; - } + struct dwarf2_loclist_baton *baton; - baton = obstack_alloc (&objfile->symbol_obstack, - sizeof (struct dwarf2_locexpr_baton)); - baton->objfile = objfile; + baton = obstack_alloc (&objfile->symbol_obstack, + sizeof (struct dwarf2_loclist_baton)); + baton->objfile = objfile; - /* Note that we're just copying the block's data pointer here, not - the actual data. We're still pointing into the dwarf_info_buffer - for SYM's objfile; right now we never release that buffer, but - when we do clean up properly this may need to change. */ - baton->size = DW_BLOCK (attr)->size; - baton->data = DW_BLOCK (attr)->data; + /* We don't know how long the location list is, but make sure we + don't run off the edge of the section. */ + baton->size = dwarf_loc_size - DW_UNSND (attr); + baton->data = dwarf_loc_buffer + DW_UNSND (attr); + baton->base_address = cu_header->base_address; + if (cu_header->base_known == 0) + complaint (&symfile_complaints, + "Location list used without specifying the CU base address."); - SYMBOL_LOCATION_FUNCS (sym) = &dwarf2_locexpr_funcs; - SYMBOL_LOCATION_BATON (sym) = baton; + SYMBOL_LOCATION_FUNCS (sym) = &dwarf2_loclist_funcs; + SYMBOL_LOCATION_BATON (sym) = baton; + } + else + { + struct dwarf2_locexpr_baton *baton; + + baton = obstack_alloc (&objfile->symbol_obstack, + sizeof (struct dwarf2_locexpr_baton)); + baton->objfile = objfile; + + if (attr_form_is_block (attr)) + { + /* Note that we're just copying the block's data pointer + here, not the actual data. We're still pointing into the + dwarf_info_buffer for SYM's objfile; right now we never + release that buffer, but when we do clean up properly + this may need to change. */ + baton->size = DW_BLOCK (attr)->size; + baton->data = DW_BLOCK (attr)->data; + } + else + { + dwarf2_invalid_attrib_class_complaint ("location description", + SYMBOL_NATURAL_NAME (sym)); + baton->size = 0; + baton->data = NULL; + } + + SYMBOL_LOCATION_FUNCS (sym) = &dwarf2_locexpr_funcs; + SYMBOL_LOCATION_BATON (sym) = baton; + } } |