/* DWARF 2 debugging format support for GDB.
- Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004, 2005, 2006
- Free Software Foundation, Inc.
+ Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+ 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
Inc. with support from Florida State University (under contract
with the Ada Joint Program Office), and Silicon Graphics, Inc.
Initial contribution by Brent Benson, Harris Computer Systems, Inc.,
based on Fred Fish's (Cygnus Support) implementation of DWARF 1
- support in dwarfread.c
+ support.
This file is part of GDB.
can be used for any other data associated to the objfile (symbol
names, type names, location expressions to name a few). */
-#ifndef DWARF2_REG_TO_REGNUM
-#define DWARF2_REG_TO_REGNUM(REG) (REG)
-#endif
-
#if 0
/* .debug_info header for a compilation unit
Because of alignment constraints, this structure has padding and cannot
/* A chain of compilation units that are currently read in, so that
they can be freed later. */
struct dwarf2_per_cu_data *read_in_chain;
+
+ /* A flag indicating wether this objfile has a section loaded at a
+ VMA of 0. */
+ int has_section_at_zero;
};
static struct dwarf2_per_objfile *dwarf2_per_objfile;
partial symbol tables do not have dependencies. */
htab_t dependencies;
+ /* Header data from the line table, during full symbol processing. */
+ struct line_header *line_header;
+
/* Mark used when releasing cached dies. */
unsigned int mark : 1;
it. */
htab_t type_hash;
- /* The partial symbol table associated with this compilation unit. */
+ /* The partial symbol table associated with this compilation unit,
+ or NULL for partial units (which do not have an associated
+ symtab). */
struct partial_symtab *psymtab;
};
unsigned int mod_time;
unsigned int length;
int included_p; /* Non-zero if referenced by the Line Number Program. */
+ struct symtab *symtab; /* The associated symbol table, if any. */
} *file_names;
/* The start and end of the statement program following this
computed. */
unsigned int scope_set : 1;
+ /* Flag set if the DIE has a byte_size attribute. */
+ unsigned int has_byte_size : 1;
+
/* The name of this DIE. Normally the value of DW_AT_name, but
sometimes DW_TAG_MIPS_linkage_name or a string computed in some
other fashion. */
_("statement list doesn't fit in .debug_line section"));
}
+static void
+dwarf2_debug_line_missing_file_complaint (void)
+{
+ complaint (&symfile_complaints,
+ _(".debug_line section has line data without a file"));
+}
+
static void
dwarf2_complex_location_expr_complaint (void)
{
static int attr_form_is_block (struct attribute *);
-static void
-dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
- struct dwarf2_cu *cu);
+static void dwarf2_symbol_mark_computed (struct attribute *attr,
+ struct symbol *sym,
+ struct dwarf2_cu *cu);
static gdb_byte *skip_one_die (gdb_byte *info_ptr, struct abbrev_info *abbrev,
struct dwarf2_cu *cu);
static void create_all_comp_units (struct objfile *);
-static struct dwarf2_cu *load_full_comp_unit (struct dwarf2_per_cu_data *);
+static struct dwarf2_cu *load_full_comp_unit (struct dwarf2_per_cu_data *,
+ struct objfile *);
static void process_full_comp_unit (struct dwarf2_per_cu_data *);
in. */
static void
-dwarf2_locate_sections (bfd *ignore_abfd, asection *sectp, void *ignore_ptr)
+dwarf2_locate_sections (bfd *abfd, asection *sectp, void *ignore_ptr)
{
if (strcmp (sectp->name, INFO_SECTION) == 0)
{
dwarf2_per_objfile->ranges_size = bfd_get_section_size (sectp);
dwarf_ranges_section = sectp;
}
+
+ if ((bfd_get_section_flags (abfd, sectp) & SEC_LOAD)
+ && bfd_section_vma (abfd, sectp) == 0)
+ dwarf2_per_objfile->has_section_at_zero = 1;
}
/* Build a partial symbol table. */
info_ptr = read_comp_unit_head (header, info_ptr, abfd);
- if (header->version != 2)
+ if (header->version != 2 && header->version != 3)
error (_("Dwarf Error: wrong version in compilation unit header "
"(is %d, should be %d) [in module %s]"), header->version,
2, bfd_get_filename (abfd));
info_ptr = read_partial_die (&comp_unit_die, abbrev, bytes_read,
abfd, info_ptr, &cu);
+ if (comp_unit_die.tag == DW_TAG_partial_unit)
+ {
+ info_ptr = (beg_of_comp_unit + cu.header.length
+ + cu.header.initial_length_size);
+ do_cleanups (back_to_inner);
+ continue;
+ }
+
/* Set the language we're debugging */
set_cu_language (comp_unit_die.language, &cu);
case DW_TAG_structure_type:
case DW_TAG_union_type:
case DW_TAG_enumeration_type:
- /* Skip aggregate types without children, these are external
- references. */
+ /* Skip external references. The DWARF standard says in the section
+ about "Structure, Union, and Class Type Entries": "An incomplete
+ structure, union or class type is represented by a structure,
+ union or class entry that does not have a byte size attribute
+ and that has a DW_AT_declaration attribute." */
+ if (!pdi->has_byte_size && pdi->is_declaration)
+ return;
+
/* NOTE: carlton/2003-10-07: See comment in new_symbol about
static vs. global. */
- if (pdi->has_children == 0)
- return;
add_psymbol_to_list (actual_name, strlen (actual_name),
STRUCT_DOMAIN, LOC_TYPEDEF,
(cu->language == language_cplus
0, (CORE_ADDR) 0, cu->language, objfile);
if (cu->language == language_cplus
- || cu->language == language_java)
+ || cu->language == language_java
+ || cu->language == language_ada)
{
/* For C++ and Java, these implicitly act as typedefs as well. */
add_psymbol_to_list (actual_name, strlen (actual_name),
{
/* Read in this compilation unit. This may add new items to
the end of the queue. */
- load_full_comp_unit (item->per_cu);
+ load_full_comp_unit (item->per_cu, objfile);
item->per_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
dwarf2_per_objfile->read_in_chain = item->per_cu;
/* If this compilation unit has already had full symbols created,
reset the TYPE fields in each DIE. */
- if (item->per_cu->psymtab->readin)
+ if (item->per_cu->type_hash)
reset_die_and_siblings_types (item->per_cu->cu->dies,
item->per_cu->cu);
}
them, one at a time, removing from the queue as we finish. */
for (item = dwarf2_queue; item != NULL; dwarf2_queue = item = next_item)
{
- if (!item->per_cu->psymtab->readin)
+ if (item->per_cu->psymtab && !item->per_cu->psymtab->readin)
process_full_comp_unit (item->per_cu);
item->per_cu->queued = 0;
/* Load the DIEs associated with PST and PER_CU into memory. */
static struct dwarf2_cu *
-load_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
+load_full_comp_unit (struct dwarf2_per_cu_data *per_cu, struct objfile *objfile)
{
- struct partial_symtab *pst = per_cu->psymtab;
- bfd *abfd = pst->objfile->obfd;
+ bfd *abfd = objfile->obfd;
struct dwarf2_cu *cu;
unsigned long offset;
gdb_byte *info_ptr;
/* If an error occurs while loading, release our storage. */
free_cu_cleanup = make_cleanup (free_one_comp_unit, cu);
- cu->objfile = pst->objfile;
+ cu->objfile = objfile;
/* read in the comp_unit header */
info_ptr = read_comp_unit_head (&cu->header, info_ptr, abfd);
cu->first_fn = cu->last_fn = cu->cached_fn = NULL;
}
+static void
+free_cu_line_header (void *arg)
+{
+ struct dwarf2_cu *cu = arg;
+
+ free_line_header (cu->line_header);
+ cu->line_header = NULL;
+}
+
static void
read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
{
CORE_ADDR lowpc = ((CORE_ADDR) -1);
CORE_ADDR highpc = ((CORE_ADDR) 0);
struct attribute *attr;
- char *name = "<unknown>";
+ char *name = NULL;
char *comp_dir = NULL;
struct die_info *child_die;
bfd *abfd = objfile->obfd;
{
name = DW_STRING (attr);
}
+
attr = dwarf2_attr (die, DW_AT_comp_dir, cu);
if (attr)
+ comp_dir = DW_STRING (attr);
+ else if (name != NULL && IS_ABSOLUTE_PATH (name))
{
- comp_dir = DW_STRING (attr);
- if (comp_dir)
- {
- /* Irix 6.2 native cc prepends <machine>.: to the compilation
- directory, get rid of it. */
- char *cp = strchr (comp_dir, ':');
+ comp_dir = ldirname (name);
+ if (comp_dir != NULL)
+ make_cleanup (xfree, comp_dir);
+ }
+ if (comp_dir != NULL)
+ {
+ /* Irix 6.2 native cc prepends <machine>.: to the compilation
+ directory, get rid of it. */
+ char *cp = strchr (comp_dir, ':');
- if (cp && cp != comp_dir && cp[-1] == '.' && cp[1] == '/')
- comp_dir = cp + 1;
- }
+ if (cp && cp != comp_dir && cp[-1] == '.' && cp[1] == '/')
+ comp_dir = cp + 1;
}
+ if (name == NULL)
+ name = "<unknown>";
+
attr = dwarf2_attr (die, DW_AT_language, cu);
if (attr)
{
attr = dwarf2_attr (die, DW_AT_producer, cu);
if (attr)
cu->producer = DW_STRING (attr);
-
+
/* We assume that we're processing GCC output. */
processing_gcc_compilation = 2;
-#if 0
- /* FIXME:Do something here. */
- if (dip->at_producer != NULL)
- {
- handle_producer (dip->at_producer);
- }
-#endif
/* The compilation unit may be in a different language or objfile,
zero out all remembered fundamental types. */
start_symtab (name, comp_dir, lowpc);
record_debugformat ("DWARF 2");
+ record_producer (cu->producer);
initialize_cu_func_list (cu);
- /* Process all dies in compilation unit. */
- if (die->child != NULL)
- {
- child_die = die->child;
- while (child_die && child_die->tag)
- {
- process_die (child_die, cu);
- child_die = sibling_die (child_die);
- }
- }
-
- /* Decode line number information if present. */
+ /* Decode line number information if present. We do this before
+ processing child DIEs, so that the line header table is available
+ for DW_AT_decl_file. */
attr = dwarf2_attr (die, DW_AT_stmt_list, cu);
if (attr)
{
line_header = dwarf_decode_line_header (line_offset, abfd, cu);
if (line_header)
{
- make_cleanup ((make_cleanup_ftype *) free_line_header,
- (void *) line_header);
+ cu->line_header = line_header;
+ make_cleanup (free_cu_line_header, cu);
dwarf_decode_lines (line_header, comp_dir, abfd, cu, NULL);
}
}
+ /* Process all dies in compilation unit. */
+ if (die->child != NULL)
+ {
+ child_die = die->child;
+ while (child_die && child_die->tag)
+ {
+ process_die (child_die, cu);
+ child_die = sibling_die (child_die);
+ }
+ }
+
/* Decode macro information, if present. Dwarf 2 macro information
refers to information in the line number info statement program
header, so we can only read it if we've read the header
labels are not in the output, so the relocs get a value of 0.
If this is a discarded function, mark the pc bounds as invalid,
so that GDB will ignore it. */
- if (low == 0 && (bfd_get_file_flags (obfd) & HAS_RELOC) == 0)
+ if (low == 0 && !dwarf2_per_objfile->has_section_at_zero)
return 0;
*lowpc = low;
TYPE_NFN_FIELDS_TOTAL (type) = total_length;
}
-
/* Returns non-zero if NAME is the name of a vtable member in CU's
language, zero otherwise. */
static int
return 0;
}
+/* GCC outputs unnamed structures that are really pointers to member
+ functions, with the ABI-specified layout. If DIE (from CU) describes
+ such a structure, set its type, and return nonzero. Otherwise return
+ zero.
+
+ GCC shouldn't do this; it should just output pointer to member DIEs.
+ This is GCC PR debug/28767. */
+
+static int
+quirk_gcc_member_function_pointer (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct objfile *objfile = cu->objfile;
+ struct type *type;
+ struct die_info *pfn_die, *delta_die;
+ struct attribute *pfn_name, *delta_name;
+ struct type *pfn_type, *domain_type;
+
+ /* Check for a structure with no name and two children. */
+ if (die->tag != DW_TAG_structure_type
+ || dwarf2_attr (die, DW_AT_name, cu) != NULL
+ || die->child == NULL
+ || die->child->sibling == NULL
+ || (die->child->sibling->sibling != NULL
+ && die->child->sibling->sibling->tag != DW_TAG_padding))
+ return 0;
+
+ /* Check for __pfn and __delta members. */
+ pfn_die = die->child;
+ pfn_name = dwarf2_attr (pfn_die, DW_AT_name, cu);
+ if (pfn_die->tag != DW_TAG_member
+ || pfn_name == NULL
+ || DW_STRING (pfn_name) == NULL
+ || strcmp ("__pfn", DW_STRING (pfn_name)) != 0)
+ return 0;
+
+ delta_die = pfn_die->sibling;
+ delta_name = dwarf2_attr (delta_die, DW_AT_name, cu);
+ if (delta_die->tag != DW_TAG_member
+ || delta_name == NULL
+ || DW_STRING (delta_name) == NULL
+ || strcmp ("__delta", DW_STRING (delta_name)) != 0)
+ return 0;
+
+ /* Find the type of the method. */
+ pfn_type = die_type (pfn_die, cu);
+ if (pfn_type == NULL
+ || TYPE_CODE (pfn_type) != TYPE_CODE_PTR
+ || TYPE_CODE (TYPE_TARGET_TYPE (pfn_type)) != TYPE_CODE_FUNC)
+ return 0;
+
+ /* Look for the "this" argument. */
+ pfn_type = TYPE_TARGET_TYPE (pfn_type);
+ if (TYPE_NFIELDS (pfn_type) == 0
+ || TYPE_CODE (TYPE_FIELD_TYPE (pfn_type, 0)) != TYPE_CODE_PTR)
+ return 0;
+
+ domain_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (pfn_type, 0));
+ type = alloc_type (objfile);
+ smash_to_method_type (type, domain_type, TYPE_TARGET_TYPE (pfn_type),
+ TYPE_FIELDS (pfn_type), TYPE_NFIELDS (pfn_type),
+ TYPE_VARARGS (pfn_type));
+ type = lookup_methodptr_type (type);
+ set_die_type (die, type, cu);
+
+ return 1;
+}
/* Called when we find the DIE that starts a structure or union scope
(definition) to process all dies that define the members of the
if (die->type)
return;
- type = alloc_type (objfile);
+ if (quirk_gcc_member_function_pointer (die, cu))
+ return;
+ type = alloc_type (objfile);
INIT_CPLUS_SPECIFIC (type);
attr = dwarf2_attr (die, DW_AT_name, cu);
if (attr && DW_STRING (attr))
TYPE_LENGTH (type) = 0;
}
+ TYPE_FLAGS (type) |= TYPE_FLAG_STUB_SUPPORTED;
if (die_is_declaration (die, cu))
TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
child_die = sibling_die (child_die);
}
- if (die->child != NULL && ! die_is_declaration (die, cu))
+ /* Do not consider external references. According to the DWARF standard,
+ these DIEs are identified by the fact that they have no byte_size
+ attribute, and a declaration attribute. */
+ if (dwarf2_attr (die, DW_AT_byte_size, cu) != NULL
+ || !die_is_declaration (die, cu))
new_symbol (die, die->type, cu);
processing_current_prefix = previous_prefix;
if (attr)
TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR;
+ attr = dwarf2_attr (die, DW_AT_name, cu);
+ if (attr && DW_STRING (attr))
+ TYPE_NAME (type) = DW_STRING (attr);
+
do_cleanups (back_to);
/* Install the type in the die. */
length accordingly. */
if (TYPE_LENGTH (type) != byte_size || addr_class != DW_ADDR_none)
{
- if (ADDRESS_CLASS_TYPE_FLAGS_P ())
+ if (gdbarch_address_class_type_flags_p (current_gdbarch))
{
int type_flags;
- type_flags = ADDRESS_CLASS_TYPE_FLAGS (byte_size, addr_class);
+ type_flags = gdbarch_address_class_type_flags
+ (current_gdbarch, byte_size, addr_class);
gdb_assert ((type_flags & ~TYPE_FLAG_ADDRESS_CLASS_ALL) == 0);
type = make_type_with_address_space (type, type_flags);
}
return;
}
- type = alloc_type (objfile);
to_type = die_type (die, cu);
domain = die_containing_type (die, cu);
- smash_to_member_type (type, domain, to_type);
+
+ if (TYPE_CODE (check_typedef (to_type)) == TYPE_CODE_METHOD)
+ type = lookup_methodptr_type (to_type);
+ else
+ type = lookup_memberptr_type (to_type, domain);
set_die_type (die, type, cu);
}
return;
base_type = die_type (die, cu);
- if (base_type == NULL)
+ if (TYPE_CODE (base_type) == TYPE_CODE_VOID)
{
complaint (&symfile_complaints,
_("DW_AT_type missing from DW_TAG_subrange_type"));
- return;
+ base_type
+ = dwarf_base_type (DW_ATE_signed,
+ gdbarch_addr_bit (current_gdbarch) / 8, cu);
}
- if (TYPE_CODE (base_type) == TYPE_CODE_VOID)
- base_type = alloc_type (NULL);
-
if (cu->language == language_fortran)
{
/* FORTRAN implies a lower bound of 1, if not given. */
set_die_type (die, range_type, cu);
}
+static void
+read_unspecified_type (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct type *type;
+ struct attribute *attr;
+
+ if (die->type)
+ return;
+
+ /* For now, we only support the C meaning of an unspecified type: void. */
+
+ attr = dwarf2_attr (die, DW_AT_name, cu);
+ type = init_type (TYPE_CODE_VOID, 0, 0, attr ? DW_STRING (attr) : "",
+ cu->objfile);
+
+ set_die_type (die, type, cu);
+}
/* Read a whole compilation unit into a linked list of dies. */
part_die->has_stmt_list = 1;
part_die->line_offset = DW_UNSND (&attr);
break;
+ case DW_AT_byte_size:
+ part_die->has_byte_size = 1;
+ break;
default:
break;
}
if (has_low_pc_attr && has_high_pc_attr
&& part_die->lowpc < part_die->highpc
&& (part_die->lowpc != 0
- || (bfd_get_file_flags (abfd) & HAS_RELOC)))
+ || dwarf2_per_objfile->has_section_at_zero))
part_die->has_pc_info = 1;
return info_ptr;
}
case DW_LANG_Modula2:
cu->language = language_m2;
break;
+ case DW_LANG_Pascal83:
+ cu->language = language_pascal;
+ break;
case DW_LANG_Cobol74:
case DW_LANG_Cobol85:
- case DW_LANG_Pascal83:
default:
cu->language = language_minimal;
break;
fe->mod_time = mod_time;
fe->length = length;
fe->included_p = 0;
+ fe->symtab = NULL;
}
CORE_ADDR baseaddr;
struct objfile *objfile = cu->objfile;
const int decode_for_pst_p = (pst != NULL);
+ struct subfile *last_subfile = NULL, *first_subfile = current_subfile;
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
address += (adj_opcode / lh->line_range)
* lh->minimum_instruction_length;
line += lh->line_base + (adj_opcode % lh->line_range);
- lh->file_names[file - 1].included_p = 1;
- if (!decode_for_pst_p)
- {
- /* Append row to matrix using current values. */
- record_line (current_subfile, line,
- check_cu_functions (address, cu));
- }
+ if (lh->num_file_names < file)
+ dwarf2_debug_line_missing_file_complaint ();
+ else
+ {
+ lh->file_names[file - 1].included_p = 1;
+ if (!decode_for_pst_p)
+ {
+ if (last_subfile != current_subfile)
+ {
+ if (last_subfile)
+ record_line (last_subfile, 0, address);
+ last_subfile = current_subfile;
+ }
+ /* Append row to matrix using current values. */
+ record_line (current_subfile, line,
+ check_cu_functions (address, cu));
+ }
+ }
basic_block = 1;
}
else switch (op_code)
{
case DW_LNE_end_sequence:
end_sequence = 1;
- lh->file_names[file - 1].included_p = 1;
- if (!decode_for_pst_p)
- record_line (current_subfile, 0, address);
+
+ if (lh->num_file_names < file)
+ dwarf2_debug_line_missing_file_complaint ();
+ else
+ {
+ lh->file_names[file - 1].included_p = 1;
+ if (!decode_for_pst_p)
+ record_line (current_subfile, 0, address);
+ }
break;
case DW_LNE_set_address:
address = read_address (abfd, line_ptr, cu, &bytes_read);
}
break;
case DW_LNS_copy:
- lh->file_names[file - 1].included_p = 1;
- if (!decode_for_pst_p)
- record_line (current_subfile, line,
- check_cu_functions (address, cu));
+ if (lh->num_file_names < file)
+ dwarf2_debug_line_missing_file_complaint ();
+ else
+ {
+ lh->file_names[file - 1].included_p = 1;
+ if (!decode_for_pst_p)
+ {
+ if (last_subfile != current_subfile)
+ {
+ if (last_subfile)
+ record_line (last_subfile, 0, address);
+ last_subfile = current_subfile;
+ }
+ record_line (current_subfile, line,
+ check_cu_functions (address, cu));
+ }
+ }
basic_block = 0;
break;
case DW_LNS_advance_pc:
file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
line_ptr += bytes_read;
- fe = &lh->file_names[file - 1];
- if (fe->dir_index)
- dir = lh->include_dirs[fe->dir_index - 1];
-
- if (!decode_for_pst_p)
- dwarf2_start_subfile (fe->name, dir, comp_dir);
+ if (lh->num_file_names < file)
+ dwarf2_debug_line_missing_file_complaint ();
+ else
+ {
+ fe = &lh->file_names[file - 1];
+ if (fe->dir_index)
+ dir = lh->include_dirs[fe->dir_index - 1];
+ if (!decode_for_pst_p)
+ {
+ last_subfile = current_subfile;
+ dwarf2_start_subfile (fe->name, dir, comp_dir);
+ }
+ }
}
break;
case DW_LNS_set_column:
dwarf2_create_include_psymtab (include_name, pst, objfile);
}
}
+ else
+ {
+ /* Make sure a symtab is created for every file, even files
+ which contain only variables (i.e. no code with associated
+ line numbers). */
+
+ int i;
+ struct file_entry *fe;
+
+ for (i = 0; i < lh->num_file_names; i++)
+ {
+ char *dir = NULL;
+ fe = &lh->file_names[i];
+ if (fe->dir_index)
+ dir = lh->include_dirs[fe->dir_index - 1];
+ dwarf2_start_subfile (fe->name, dir, comp_dir);
+
+ /* Skip the main file; we don't need it, and it must be
+ allocated last, so that it will show up before the
+ non-primary symtabs in the objfile's symtab list. */
+ if (current_subfile == first_subfile)
+ continue;
+
+ if (current_subfile->symtab == NULL)
+ current_subfile->symtab = allocate_symtab (current_subfile->name,
+ cu->objfile);
+ fe->symtab = current_subfile->symtab;
+ }
+ }
}
/* Start a subfile for DWARF. FILENAME is the name of the file and
{
SYMBOL_LINE (sym) = DW_UNSND (attr);
}
+
+ attr = dwarf2_attr (die, DW_AT_decl_file, cu);
+ if (attr)
+ {
+ int file_index = DW_UNSND (attr);
+ if (cu->line_header == NULL
+ || file_index > cu->line_header->num_file_names)
+ complaint (&symfile_complaints,
+ _("file index out of range"));
+ else if (file_index > 0)
+ {
+ struct file_entry *fe;
+ fe = &cu->line_header->file_names[file_index - 1];
+ SYMBOL_SYMTAB (sym) = fe->symtab;
+ }
+ }
+
switch (die->tag)
{
case DW_TAG_label:
to something sensible. */
if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_VOID)
SYMBOL_TYPE (sym) = init_type (TYPE_CODE_INT,
- TARGET_INT_BIT / HOST_CHAR_BIT, 0,
- "<variable, no debug info>",
+ gdbarch_int_bit (current_gdbarch)
+ / HOST_CHAR_BIT,
+ 0, "<variable, no debug info>",
objfile);
attr = dwarf2_attr (die, DW_AT_const_value, cu);
if (attr)
defines a typedef for the class. Synthesize a typedef symbol
so that "ptype foo" works as expected. */
if (cu->language == language_cplus
- || cu->language == language_java)
+ || cu->language == language_java
+ || cu->language == language_ada)
{
struct symbol *typedef_sym = (struct symbol *)
obstack_alloc (&objfile->objfile_obstack,
case DW_TAG_base_type:
read_base_type (die, cu);
break;
+ case DW_TAG_unspecified_type:
+ read_unspecified_type (die, cu);
+ break;
default:
complaint (&symfile_complaints, _("unexpected tag in read_type_die: '%s'"),
dwarf_tag_name (die->tag));
return "DW_TAG_partial_unit";
case DW_TAG_imported_unit:
return "DW_TAG_imported_unit";
+ case DW_TAG_condition:
+ return "DW_TAG_condition";
+ case DW_TAG_shared_type:
+ return "DW_TAG_shared_type";
case DW_TAG_MIPS_loop:
return "DW_TAG_MIPS_loop";
+ case DW_TAG_HP_array_descriptor:
+ return "DW_TAG_HP_array_descriptor";
case DW_TAG_format_label:
return "DW_TAG_format_label";
case DW_TAG_function_template:
return "DW_TAG_function_template";
case DW_TAG_class_template:
return "DW_TAG_class_template";
+ case DW_TAG_GNU_BINCL:
+ return "DW_TAG_GNU_BINCL";
+ case DW_TAG_GNU_EINCL:
+ return "DW_TAG_GNU_EINCL";
+ case DW_TAG_upc_shared_type:
+ return "DW_TAG_upc_shared_type";
+ case DW_TAG_upc_strict_type:
+ return "DW_TAG_upc_strict_type";
+ case DW_TAG_upc_relaxed_type:
+ return "DW_TAG_upc_relaxed_type";
+ case DW_TAG_PGI_kanji_type:
+ return "DW_TAG_PGI_kanji_type";
+ case DW_TAG_PGI_interface_block:
+ return "DW_TAG_PGI_interface_block";
default:
return "DW_TAG_<unknown>";
}
return "DW_AT_virtuality";
case DW_AT_vtable_elem_location:
return "DW_AT_vtable_elem_location";
+ /* DWARF 3 values. */
case DW_AT_allocated:
return "DW_AT_allocated";
case DW_AT_associated:
return "DW_AT_call_file";
case DW_AT_call_line:
return "DW_AT_call_line";
+ case DW_AT_description:
+ return "DW_AT_description";
+ case DW_AT_binary_scale:
+ return "DW_AT_binary_scale";
+ case DW_AT_decimal_scale:
+ return "DW_AT_decimal_scale";
+ case DW_AT_small:
+ return "DW_AT_small";
+ case DW_AT_decimal_sign:
+ return "DW_AT_decimal_sign";
+ case DW_AT_digit_count:
+ return "DW_AT_digit_count";
+ case DW_AT_picture_string:
+ return "DW_AT_picture_string";
+ case DW_AT_mutable:
+ return "DW_AT_mutable";
+ case DW_AT_threads_scaled:
+ return "DW_AT_threads_scaled";
+ case DW_AT_explicit:
+ return "DW_AT_explicit";
+ case DW_AT_object_pointer:
+ return "DW_AT_object_pointer";
+ case DW_AT_endianity:
+ return "DW_AT_endianity";
+ case DW_AT_elemental:
+ return "DW_AT_elemental";
+ case DW_AT_pure:
+ return "DW_AT_pure";
+ case DW_AT_recursive:
+ return "DW_AT_recursive";
#ifdef MIPS
+ /* SGI/MIPS extensions. */
case DW_AT_MIPS_fde:
return "DW_AT_MIPS_fde";
case DW_AT_MIPS_loop_begin:
return "DW_AT_MIPS_loop_unroll_factor";
case DW_AT_MIPS_software_pipeline_depth:
return "DW_AT_MIPS_software_pipeline_depth";
-#endif
case DW_AT_MIPS_linkage_name:
return "DW_AT_MIPS_linkage_name";
-
+ case DW_AT_MIPS_stride:
+ return "DW_AT_MIPS_stride";
+ case DW_AT_MIPS_abstract_name:
+ return "DW_AT_MIPS_abstract_name";
+ case DW_AT_MIPS_clone_origin:
+ return "DW_AT_MIPS_clone_origin";
+ case DW_AT_MIPS_has_inlines:
+ return "DW_AT_MIPS_has_inlines";
+#endif
+ /* HP extensions. */
+ case DW_AT_HP_block_index:
+ return "DW_AT_HP_block_index";
+ case DW_AT_HP_unmodifiable:
+ return "DW_AT_HP_unmodifiable";
+ case DW_AT_HP_actuals_stmt_list:
+ return "DW_AT_HP_actuals_stmt_list";
+ case DW_AT_HP_proc_per_section:
+ return "DW_AT_HP_proc_per_section";
+ case DW_AT_HP_raw_data_ptr:
+ return "DW_AT_HP_raw_data_ptr";
+ case DW_AT_HP_pass_by_reference:
+ return "DW_AT_HP_pass_by_reference";
+ case DW_AT_HP_opt_level:
+ return "DW_AT_HP_opt_level";
+ case DW_AT_HP_prof_version_id:
+ return "DW_AT_HP_prof_version_id";
+ case DW_AT_HP_opt_flags:
+ return "DW_AT_HP_opt_flags";
+ case DW_AT_HP_cold_region_low_pc:
+ return "DW_AT_HP_cold_region_low_pc";
+ case DW_AT_HP_cold_region_high_pc:
+ return "DW_AT_HP_cold_region_high_pc";
+ case DW_AT_HP_all_variables_modifiable:
+ return "DW_AT_HP_all_variables_modifiable";
+ case DW_AT_HP_linkage_name:
+ return "DW_AT_HP_linkage_name";
+ case DW_AT_HP_prof_flags:
+ return "DW_AT_HP_prof_flags";
+ /* GNU extensions. */
case DW_AT_sf_names:
return "DW_AT_sf_names";
case DW_AT_src_info:
return "DW_AT_body_end";
case DW_AT_GNU_vector:
return "DW_AT_GNU_vector";
+ /* VMS extensions. */
+ case DW_AT_VMS_rtnbeg_pd_address:
+ return "DW_AT_VMS_rtnbeg_pd_address";
+ /* UPC extension. */
+ case DW_AT_upc_threads_scaled:
+ return "DW_AT_upc_threads_scaled";
+ /* PGI (STMicroelectronics) extensions. */
+ case DW_AT_PGI_lbase:
+ return "DW_AT_PGI_lbase";
+ case DW_AT_PGI_soffset:
+ return "DW_AT_PGI_soffset";
+ case DW_AT_PGI_lstride:
+ return "DW_AT_PGI_lstride";
default:
return "DW_AT_<unknown>";
}
return "DW_OP_xderef_size";
case DW_OP_nop:
return "DW_OP_nop";
- /* DWARF 3 extensions. */
+ /* DWARF 3 extensions. */
case DW_OP_push_object_address:
return "DW_OP_push_object_address";
case DW_OP_call2:
return "DW_OP_call4";
case DW_OP_call_ref:
return "DW_OP_call_ref";
- /* GNU extensions. */
+ /* GNU extensions. */
+ case DW_OP_form_tls_address:
+ return "DW_OP_form_tls_address";
+ case DW_OP_call_frame_cfa:
+ return "DW_OP_call_frame_cfa";
+ case DW_OP_bit_piece:
+ return "DW_OP_bit_piece";
case DW_OP_GNU_push_tls_address:
return "DW_OP_GNU_push_tls_address";
+ case DW_OP_GNU_uninit:
+ return "DW_OP_GNU_uninit";
+ /* HP extensions. */
+ case DW_OP_HP_is_value:
+ return "DW_OP_HP_is_value";
+ case DW_OP_HP_fltconst4:
+ return "DW_OP_HP_fltconst4";
+ case DW_OP_HP_fltconst8:
+ return "DW_OP_HP_fltconst8";
+ case DW_OP_HP_mod_range:
+ return "DW_OP_HP_mod_range";
+ case DW_OP_HP_unmod_range:
+ return "DW_OP_HP_unmod_range";
+ case DW_OP_HP_tls:
+ return "DW_OP_HP_tls";
default:
return "OP_<unknown>";
}
{
switch (enc)
{
+ case DW_ATE_void:
+ return "DW_ATE_void";
case DW_ATE_address:
return "DW_ATE_address";
case DW_ATE_boolean:
return "DW_ATE_unsigned";
case DW_ATE_unsigned_char:
return "DW_ATE_unsigned_char";
+ /* DWARF 3. */
case DW_ATE_imaginary_float:
return "DW_ATE_imaginary_float";
+ case DW_ATE_packed_decimal:
+ return "DW_ATE_packed_decimal";
+ case DW_ATE_numeric_string:
+ return "DW_ATE_numeric_string";
+ case DW_ATE_edited:
+ return "DW_ATE_edited";
+ case DW_ATE_signed_fixed:
+ return "DW_ATE_signed_fixed";
+ case DW_ATE_unsigned_fixed:
+ return "DW_ATE_unsigned_fixed";
+ case DW_ATE_decimal_float:
+ return "DW_ATE_decimal_float";
+ /* HP extensions. */
+ case DW_ATE_HP_float80:
+ return "DW_ATE_HP_float80";
+ case DW_ATE_HP_complex_float80:
+ return "DW_ATE_HP_complex_float80";
+ case DW_ATE_HP_float128:
+ return "DW_ATE_HP_float128";
+ case DW_ATE_HP_complex_float128:
+ return "DW_ATE_HP_complex_float128";
+ case DW_ATE_HP_floathpintel:
+ return "DW_ATE_HP_floathpintel";
+ case DW_ATE_HP_imaginary_float80:
+ return "DW_ATE_HP_imaginary_float80";
+ case DW_ATE_HP_imaginary_float128:
+ return "DW_ATE_HP_imaginary_float128";
default:
return "DW_ATE_<unknown>";
}
return "DW_CFA_def_cfa_register";
case DW_CFA_def_cfa_offset:
return "DW_CFA_def_cfa_offset";
-
- /* DWARF 3 */
+ /* DWARF 3. */
case DW_CFA_def_cfa_expression:
return "DW_CFA_def_cfa_expression";
case DW_CFA_expression:
return "DW_CFA_def_cfa_sf";
case DW_CFA_def_cfa_offset_sf:
return "DW_CFA_def_cfa_offset_sf";
-
- /* SGI/MIPS specific */
+ case DW_CFA_val_offset:
+ return "DW_CFA_val_offset";
+ case DW_CFA_val_offset_sf:
+ return "DW_CFA_val_offset_sf";
+ case DW_CFA_val_expression:
+ return "DW_CFA_val_expression";
+ /* SGI/MIPS specific. */
case DW_CFA_MIPS_advance_loc8:
return "DW_CFA_MIPS_advance_loc8";
-
- /* GNU extensions */
+ /* GNU extensions. */
case DW_CFA_GNU_window_save:
return "DW_CFA_GNU_window_save";
case DW_CFA_GNU_args_size:
return "DW_CFA_GNU_args_size";
case DW_CFA_GNU_negative_offset_extended:
return "DW_CFA_GNU_negative_offset_extended";
-
default:
return "DW_CFA_<unknown>";
}
dwarf2_complex_location_expr_complaint ();
break;
+ case DW_OP_GNU_uninit:
+ break;
+
default:
complaint (&symfile_complaints, _("unsupported stack op: '%s'"),
dwarf_stack_op_name (op));
dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
struct dwarf2_cu *cu)
{
- if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8)
+ struct objfile *objfile = cu->objfile;
+
+ /* Save the master objfile, so that we can report and look up the
+ correct file containing this variable. */
+ if (objfile->separate_debug_objfile_backlink)
+ objfile = objfile->separate_debug_objfile_backlink;
+
+ if ((attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8)
+ /* ".debug_loc" may not exist at all, or the offset may be outside
+ the section. If so, fall through to the complaint in the
+ other branch. */
+ && DW_UNSND (attr) < dwarf2_per_objfile->loc_size)
{
struct dwarf2_loclist_baton *baton;
baton = obstack_alloc (&cu->objfile->objfile_obstack,
sizeof (struct dwarf2_loclist_baton));
- baton->objfile = cu->objfile;
+ baton->objfile = objfile;
/* We don't know how long the location list is, but make sure we
don't run off the edge of the section. */
baton = obstack_alloc (&cu->objfile->objfile_obstack,
sizeof (struct dwarf2_locexpr_baton));
- baton->objfile = cu->objfile;
+ baton->objfile = objfile;
if (attr_form_is_block (attr))
{