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
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;
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
_("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);
{
struct objfile *objfile = cu->objfile;
CORE_ADDR addr = 0;
- char *actual_name;
+ char *actual_name = NULL;
const char *my_prefix;
const struct partial_symbol *psym = NULL;
CORE_ADDR baseaddr;
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
- actual_name = NULL;
-
if (pdi_needs_namespace (pdi->tag))
{
actual_name = partial_die_full_name (pdi, cu);
{
/* Static Variable. Skip symbols without location descriptors. */
if (pdi->locdesc == NULL)
- return;
+ {
+ if (built_actual_name)
+ xfree (actual_name);
+ return;
+ }
addr = decode_locdesc (pdi->locdesc, cu);
/*prim_record_minimal_symbol (actual_name, addr + baseaddr,
mst_file_data, objfile); */
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;
+ {
+ if (built_actual_name)
+ xfree (actual_name);
+ return;
+ }
/* NOTE: carlton/2003-10-07: See comment in new_symbol about
static vs. global. */
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),
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)
{
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
TYPE_LENGTH (type) = 0;
}
+ TYPE_FLAGS (type) |= TYPE_FLAG_STUB_SUPPORTED;
if (die_is_declaration (die, cu))
TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
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;
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. */
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;
}
dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
struct dwarf2_cu *cu, struct partial_symtab *pst)
{
- gdb_byte *line_ptr;
+ gdb_byte *line_ptr, *extended_end;
gdb_byte *line_end;
- unsigned int bytes_read;
+ unsigned int bytes_read, extended_len;
unsigned char op_code, extended_op, adj_opcode;
CORE_ADDR baseaddr;
struct objfile *objfile = cu->objfile;
const int decode_for_pst_p = (pst != NULL);
- struct subfile *last_subfile = 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)
- {
- if (last_subfile != current_subfile)
- {
- if (last_subfile)
- record_line (last_subfile, 0, address);
- last_subfile = current_subfile;
+ 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));
}
- /* 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_LNS_extended_op:
- read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ extended_len = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
line_ptr += bytes_read;
+ extended_end = line_ptr + extended_len;
extended_op = read_1_byte (abfd, line_ptr);
line_ptr += 1;
switch (extended_op)
{
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);
_("mangled .debug_line section"));
return;
}
+ /* Make sure that we parsed the extended op correctly. If e.g.
+ we expected a different address size than the producer used,
+ we may have read the wrong number of bytes. */
+ if (line_ptr != extended_end)
+ {
+ complaint (&symfile_complaints,
+ _("mangled .debug_line section"));
+ return;
+ }
break;
case DW_LNS_copy:
- lh->file_names[file - 1].included_p = 1;
- if (!decode_for_pst_p)
+ if (lh->num_file_names < file)
+ dwarf2_debug_line_missing_file_complaint ();
+ else
{
- 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));
+ 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;
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)
- {
- last_subfile = current_subfile;
- 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:
with missing type entries. Change the misleading `void' type
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>",
- objfile);
+ SYMBOL_TYPE (sym)
+ = builtin_type (current_gdbarch)->nodebug_data_symbol;
+
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,
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";
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)
{
+ 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
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))
{