This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or (at
- your option) any later version.
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "bfd.h"
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
_("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. */
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;
lowpc += baseaddr;
highpc += baseaddr;
+ /* Find the filename. Do not use dwarf2_name here, since the filename
+ is not a source language identifier. */
attr = dwarf2_attr (die, DW_AT_name, cu);
if (attr)
{
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)
{
}
/* Get name of field. */
- attr = dwarf2_attr (die, DW_AT_name, cu);
- if (attr && DW_STRING (attr))
- fieldname = DW_STRING (attr);
+ fieldname = dwarf2_name (die, cu);
+ if (fieldname == NULL)
+ fieldname = "";
/* The name is already allocated along with this objfile, so we don't
need to duplicate it for the type. */
char *physname;
/* Get name of field. */
- attr = dwarf2_attr (die, DW_AT_name, cu);
- if (attr && DW_STRING (attr))
- fieldname = DW_STRING (attr);
- else
+ fieldname = dwarf2_name (die, cu);
+ if (fieldname == NULL)
return;
/* Get physical name. */
struct nextfnfield *new_fnfield;
/* Get name of member function. */
- attr = dwarf2_attr (die, DW_AT_name, cu);
- if (attr && DW_STRING (attr))
- fieldname = DW_STRING (attr);
- else
+ fieldname = dwarf2_name (die, cu);
+ if (fieldname == NULL)
return;
/* Get the mangled name. */
struct attribute *attr;
const char *previous_prefix = processing_current_prefix;
struct cleanup *back_to = NULL;
+ char *name;
if (die->type)
return;
type = alloc_type (objfile);
INIT_CPLUS_SPECIFIC (type);
- attr = dwarf2_attr (die, DW_AT_name, cu);
- if (attr && DW_STRING (attr))
+ name = dwarf2_name (die, cu);
+ if (name != NULL)
{
if (cu->language == language_cplus
|| cu->language == language_java)
{
/* The name is already allocated along with this objfile, so
we don't need to duplicate it for the type. */
- TYPE_TAG_NAME (type) = DW_STRING (attr);
+ TYPE_TAG_NAME (type) = name;
}
}
struct objfile *objfile = cu->objfile;
struct type *type;
struct attribute *attr;
+ char *name;
if (die->type)
return;
type = alloc_type (objfile);
TYPE_CODE (type) = TYPE_CODE_ENUM;
- attr = dwarf2_attr (die, DW_AT_name, cu);
- if (attr && DW_STRING (attr))
+ name = dwarf2_name (die, cu);
+ if (name != NULL)
{
- char *name = DW_STRING (attr);
-
if (processing_has_namespace_info)
{
TYPE_TAG_NAME (type) = typename_concat (&objfile->objfile_obstack,
struct objfile *objfile = cu->objfile;
struct die_info *child_die;
struct field *fields;
- struct attribute *attr;
struct symbol *sym;
int num_fields;
int unsigned_enum = 1;
+ char *name;
num_fields = 0;
fields = NULL;
}
else
{
- attr = dwarf2_attr (child_die, DW_AT_name, cu);
- if (attr)
+ name = dwarf2_name (child_die, cu);
+ if (name)
{
sym = new_symbol (child_die, die->type, cu);
if (SYMBOL_VALUE (sym) < 0)
struct attribute *attr;
int ndim = 0;
struct cleanup *back_to;
+ char *name;
/* Return if we've already decoded this type. */
if (die->type)
to functions. */
attr = dwarf2_attr (die, DW_AT_GNU_vector, cu);
if (attr)
- TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR;
+ make_vector_type (type);
- attr = dwarf2_attr (die, DW_AT_name, cu);
- if (attr && DW_STRING (attr))
- TYPE_NAME (type) = DW_STRING (attr);
+ name = dwarf2_name (die, cu);
+ if (name)
+ TYPE_NAME (type) = name;
do_cleanups (back_to);
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);
}
type = die_type (die, cu);
ftype = make_function_type (type, (struct type **) 0);
- /* All functions in C++ and Java have prototypes. */
+ /* All functions in C++, Pascal and Java have prototypes. */
attr = dwarf2_attr (die, DW_AT_prototyped, cu);
if ((attr && (DW_UNSND (attr) != 0))
|| cu->language == language_cplus
- || cu->language == language_java)
+ || cu->language == language_java
+ || cu->language == language_pascal)
TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED;
if (die->child != NULL)
if (!die->type)
{
- attr = dwarf2_attr (die, DW_AT_name, cu);
- if (attr && DW_STRING (attr))
- {
- name = DW_STRING (attr);
- }
+ name = dwarf2_name (die, cu);
set_die_type (die, init_type (TYPE_CODE_TYPEDEF, 0,
TYPE_FLAG_TARGET_STUB, name, objfile),
cu);
struct type *type;
struct attribute *attr;
int encoding = 0, size = 0;
+ char *name;
/* If we've already decoded this die, this is a no-op. */
if (die->type)
{
size = DW_UNSND (attr);
}
- attr = dwarf2_attr (die, DW_AT_name, cu);
- if (attr && DW_STRING (attr))
+ name = dwarf2_name (die, cu);
+ if (name)
{
enum type_code code = TYPE_CODE_INT;
int type_flags = 0;
case DW_ATE_complex_float:
code = TYPE_CODE_COMPLEX;
break;
+ case DW_ATE_decimal_float:
+ code = TYPE_CODE_DECFLOAT;
+ break;
case DW_ATE_float:
code = TYPE_CODE_FLT;
break;
dwarf_type_encoding_name (encoding));
break;
}
- type = init_type (code, size, type_flags, DW_STRING (attr), objfile);
+ type = init_type (code, size, type_flags, name, objfile);
if (encoding == DW_ATE_address)
TYPE_TARGET_TYPE (type) = dwarf2_fundamental_type (objfile, FT_VOID,
cu);
struct attribute *attr;
int low = 0;
int high = -1;
+ char *name;
/* If we have already decoded this die, then nothing more to do. */
if (die->type)
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. */
range_type = create_range_type (NULL, base_type, low, high);
- attr = dwarf2_attr (die, DW_AT_name, cu);
- if (attr && DW_STRING (attr))
- TYPE_NAME (range_type) = DW_STRING (attr);
+ name = dwarf2_name (die, cu);
+ if (name)
+ TYPE_NAME (range_type) = name;
attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr)
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) : "",
+ type = init_type (TYPE_CODE_VOID, 0, 0, dwarf2_name (die, cu),
cu->objfile);
set_die_type (die, type, cu);
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;
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:
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)
{
type = dwarf2_fundamental_type (objfile, FT_FLOAT, cu);
}
return type;
+ case DW_ATE_decimal_float:
+ if (size == 16)
+ type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_DECFLOAT, cu);
+ else if (size == 8)
+ type = dwarf2_fundamental_type (objfile, FT_EXT_PREC_DECFLOAT, cu);
+ else
+ type = dwarf2_fundamental_type (objfile, FT_DECFLOAT, cu);
+ return type;
case DW_ATE_signed:
switch (size)
{
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))
{
}
}
+/* Release all extra memory associated with OBJFILE. */
+
+void
+dwarf2_free_objfile (struct objfile *objfile)
+{
+ dwarf2_per_objfile = objfile_data (objfile, dwarf2_objfile_data_key);
+
+ if (dwarf2_per_objfile == NULL)
+ return;
+
+ /* Cached DIE trees use xmalloc and the comp_unit_obstack. */
+ free_cached_comp_units (NULL);
+
+ /* Everything else should be on the objfile obstack. */
+}
+
/* A pair of DIE offset and GDB type pointer. We store these
in a hash table separate from the DIEs, and preserve them
when the DIEs are flushed out of cache. */