/* Back link. */
struct objfile *objfile;
- /* A list of all the compilation units. This is used to locate
+ /* Table of all the compilation units. This is used to locate
the target compilation unit of a particular reference. */
struct dwarf2_per_cu_data **all_comp_units;
int n_comp_units;
/* The number of .debug_types-related CUs. */
- int n_type_comp_units;
+ int n_type_units;
- /* The .debug_types-related CUs. */
- struct dwarf2_per_cu_data **type_comp_units;
+ /* The .debug_types-related CUs (TUs). */
+ struct dwarf2_per_cu_data **all_type_units;
/* A chain of compilation units that are currently read in, so that
they can be freed later. */
/* Mark used when releasing cached dies. */
unsigned int mark : 1;
- /* This flag will be set if this compilation unit might include
- inter-compilation-unit references. */
- unsigned int has_form_ref_addr : 1;
-
- /* This flag will be set if this compilation unit includes any
- DW_TAG_namespace DIEs. If we know that there are explicit
- DIEs for namespaces, we don't need to try to infer them
- from mangled names. */
- unsigned int has_namespace_info : 1;
-
/* This CU references .debug_loc. See the symtab->locations_valid field.
This test is imperfect as there may exist optimized debug code not using
any location list and still facing inlining issues if handled as
(unsigned int offset,
bfd *abfd, struct dwarf2_cu *cu));
-static void dwarf_decode_lines (struct line_header *, const char *, bfd *,
- struct dwarf2_cu *, struct partial_symtab *);
+static void dwarf_decode_lines (struct line_header *, const char *,
+ struct dwarf2_cu *, struct partial_symtab *,
+ int);
static void dwarf2_start_subfile (char *, const char *, const char *);
static struct type *read_type_die_1 (struct die_info *, struct dwarf2_cu *);
-static char *determine_prefix (struct die_info *die, struct dwarf2_cu *);
+static const char *determine_prefix (struct die_info *die, struct dwarf2_cu *);
static char *typename_concat (struct obstack *obs, const char *prefix,
const char *suffix, int physname,
static char *file_full_name (int file, struct line_header *lh,
const char *comp_dir);
-static gdb_byte *partial_read_comp_unit_head (struct comp_unit_head *header,
- gdb_byte *info_ptr,
- gdb_byte *buffer,
- unsigned int buffer_size,
- bfd *abfd,
- int is_debug_types_section);
+static gdb_byte *read_and_check_comp_unit_head
+ (struct comp_unit_head *header,
+ struct dwarf2_section_info *section, gdb_byte *info_ptr,
+ int is_debug_types_section);
static void init_cu_die_reader (struct die_reader_specs *reader,
struct dwarf2_cu *cu);
if (index >= dwarf2_per_objfile->n_comp_units)
{
index -= dwarf2_per_objfile->n_comp_units;
- return dwarf2_per_objfile->type_comp_units[index];
+ return dwarf2_per_objfile->all_type_units[index];
}
return dwarf2_per_objfile->all_comp_units[index];
}
offset_type i;
htab_t sig_types_hash;
- dwarf2_per_objfile->n_type_comp_units = elements / 3;
- dwarf2_per_objfile->type_comp_units
+ dwarf2_per_objfile->n_type_units = elements / 3;
+ dwarf2_per_objfile->all_type_units
= obstack_alloc (&objfile->objfile_obstack,
- dwarf2_per_objfile->n_type_comp_units
+ dwarf2_per_objfile->n_type_units
* sizeof (struct dwarf2_per_cu_data *));
sig_types_hash = allocate_signatured_type_table (objfile);
slot = htab_find_slot (sig_types_hash, type_sig, INSERT);
*slot = type_sig;
- dwarf2_per_objfile->type_comp_units[i / 3] = &type_sig->per_cu;
+ dwarf2_per_objfile->all_type_units[i / 3] = &type_sig->per_cu;
}
dwarf2_per_objfile->signatured_types = sig_types_hash;
}
/* Index version 4 did not support case insensitive searches. But the
- indexes for case insensitive languages are built in lowercase, therefore
+ indices for case insensitive languages are built in lowercase, therefore
simulate our NAME being searched is also lowercased. */
hash = mapped_index_string_hash ((index->version == 4
&& case_sensitivity == case_sensitive_off
version 5 and later. */
if (version < 4)
return 0;
- /* Indexes with higher version than the one supported by GDB may be no
+ /* Indices with higher version than the one supported by GDB may be no
longer backward compatible. */
if (version > 5)
return 0;
struct cleanup *cleanups;
struct die_info *comp_unit_die;
struct dwarf2_section_info* sec;
- gdb_byte *info_ptr, *buffer;
+ gdb_byte *info_ptr;
int has_children, i;
struct dwarf2_cu cu;
- unsigned int bytes_read, buffer_size;
+ unsigned int bytes_read;
struct die_reader_specs reader_specs;
char *name, *comp_dir;
void **slot;
else
sec = &dwarf2_per_objfile->info;
dwarf2_read_section (objfile, sec);
- buffer_size = sec->size;
- buffer = sec->buffer;
- info_ptr = buffer + this_cu->offset;
+ info_ptr = sec->buffer + this_cu->offset;
- info_ptr = partial_read_comp_unit_head (&cu.header, info_ptr,
- buffer, buffer_size,
- abfd,
- this_cu->debug_types_section != NULL);
+ info_ptr = read_and_check_comp_unit_head (&cu.header, sec, info_ptr,
+ this_cu->debug_types_section != NULL);
/* Skip dummy compilation units. */
- if (info_ptr >= buffer + buffer_size
+ if (info_ptr >= (sec->buffer + sec->size)
|| peek_abbrev_code (abfd, info_ptr) == 0)
{
do_cleanups (cleanups);
{
int i;
const char *name_basename = lbasename (name);
- int check_basename = name_basename == name;
- struct dwarf2_per_cu_data *base_cu = NULL;
+ int name_len = strlen (name);
+ int is_abs = IS_ABSOLUTE_PATH (name);
dw2_setup (objfile);
for (i = 0; i < (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_comp_units); ++i)
+ + dwarf2_per_objfile->n_type_units); ++i)
{
int j;
struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
{
const char *this_name = file_data->file_names[j];
- if (FILENAME_CMP (name, this_name) == 0)
+ if (FILENAME_CMP (name, this_name) == 0
+ || (!is_abs && compare_filenames_for_search (this_name,
+ name, name_len)))
{
if (dw2_map_expand_apply (objfile, per_cu,
name, full_path, real_path,
return 1;
}
- if (check_basename && ! base_cu
- && FILENAME_CMP (lbasename (this_name), name) == 0)
- base_cu = per_cu;
-
/* Before we invoke realpath, which can get expensive when many
files are involved, do a quick comparison of the basenames. */
if (! basenames_may_differ
file_data, j);
if (this_real_name != NULL
- && FILENAME_CMP (full_path, this_real_name) == 0)
+ && (FILENAME_CMP (full_path, this_real_name) == 0
+ || (!is_abs
+ && compare_filenames_for_search (this_real_name,
+ name, name_len))))
{
if (dw2_map_expand_apply (objfile, per_cu,
name, full_path, real_path,
file_data, j);
if (this_real_name != NULL
- && FILENAME_CMP (real_path, this_real_name) == 0)
+ && (FILENAME_CMP (real_path, this_real_name) == 0
+ || (!is_abs
+ && compare_filenames_for_search (this_real_name,
+ name, name_len))))
{
if (dw2_map_expand_apply (objfile, per_cu,
name, full_path, real_path,
}
}
- if (base_cu)
- {
- if (dw2_map_expand_apply (objfile, base_cu,
- name, full_path, real_path,
- callback, data))
- return 1;
- }
-
return 0;
}
dw2_setup (objfile);
count = 0;
for (i = 0; i < (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_comp_units); ++i)
+ + dwarf2_per_objfile->n_type_units); ++i)
{
struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
dw2_setup (objfile);
for (i = 0; i < (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_comp_units); ++i)
+ + dwarf2_per_objfile->n_type_units); ++i)
{
struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
dw2_expand_symtabs_matching
(struct objfile *objfile,
int (*file_matcher) (const char *, void *),
- int (*name_matcher) (const struct language_defn *, const char *, void *),
+ int (*name_matcher) (const char *, void *),
enum search_domain kind,
void *data)
{
index = dwarf2_per_objfile->index_table;
if (file_matcher != NULL)
- for (i = 0; i < (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_comp_units); ++i)
- {
- int j;
- struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
- struct quick_file_names *file_data;
+ {
+ struct cleanup *cleanup;
+ htab_t visited_found, visited_not_found;
- per_cu->v.quick->mark = 0;
+ visited_found = htab_create_alloc (10,
+ htab_hash_pointer, htab_eq_pointer,
+ NULL, xcalloc, xfree);
+ cleanup = make_cleanup_htab_delete (visited_found);
+ visited_not_found = htab_create_alloc (10,
+ htab_hash_pointer, htab_eq_pointer,
+ NULL, xcalloc, xfree);
+ make_cleanup_htab_delete (visited_not_found);
- /* We only need to look at symtabs not already expanded. */
- if (per_cu->v.quick->symtab)
- continue;
+ for (i = 0; i < (dwarf2_per_objfile->n_comp_units
+ + dwarf2_per_objfile->n_type_units); ++i)
+ {
+ int j;
+ struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
+ struct quick_file_names *file_data;
+ void **slot;
- file_data = dw2_get_file_names (objfile, per_cu);
- if (file_data == NULL)
- continue;
+ per_cu->v.quick->mark = 0;
- for (j = 0; j < file_data->num_file_names; ++j)
- {
- if (file_matcher (file_data->file_names[j], data))
- {
- per_cu->v.quick->mark = 1;
- break;
- }
- }
- }
+ /* We only need to look at symtabs not already expanded. */
+ if (per_cu->v.quick->symtab)
+ continue;
+
+ file_data = dw2_get_file_names (objfile, per_cu);
+ if (file_data == NULL)
+ continue;
+
+ if (htab_find (visited_not_found, file_data) != NULL)
+ continue;
+ else if (htab_find (visited_found, file_data) != NULL)
+ {
+ per_cu->v.quick->mark = 1;
+ continue;
+ }
+
+ for (j = 0; j < file_data->num_file_names; ++j)
+ {
+ if (file_matcher (file_data->file_names[j], data))
+ {
+ per_cu->v.quick->mark = 1;
+ break;
+ }
+ }
+
+ slot = htab_find_slot (per_cu->v.quick->mark
+ ? visited_found
+ : visited_not_found,
+ file_data, INSERT);
+ *slot = file_data;
+ }
+
+ do_cleanups (cleanup);
+ }
for (iter = 0; iter < index->symbol_table_slots; ++iter)
{
name = index->constant_pool + MAYBE_SWAP (index->symbol_table[idx]);
- if (! (*name_matcher) (current_language, name, data))
+ if (! (*name_matcher) (name, data))
continue;
/* The name was matched, now expand corresponding CUs that were
void *data, int need_fullname)
{
int i;
+ struct cleanup *cleanup;
+ htab_t visited = htab_create_alloc (10, htab_hash_pointer, htab_eq_pointer,
+ NULL, xcalloc, xfree);
+ cleanup = make_cleanup_htab_delete (visited);
dw2_setup (objfile);
+ /* We can ignore file names coming from already-expanded CUs. */
for (i = 0; i < (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_comp_units); ++i)
+ + dwarf2_per_objfile->n_type_units); ++i)
+ {
+ struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
+
+ if (per_cu->v.quick->symtab)
+ {
+ void **slot = htab_find_slot (visited, per_cu->v.quick->file_names,
+ INSERT);
+
+ *slot = per_cu->v.quick->file_names;
+ }
+ }
+
+ for (i = 0; i < (dwarf2_per_objfile->n_comp_units
+ + dwarf2_per_objfile->n_type_units); ++i)
{
int j;
struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
struct quick_file_names *file_data;
+ void **slot;
/* We only need to look at symtabs not already expanded. */
if (per_cu->v.quick->symtab)
if (file_data == NULL)
continue;
+ slot = htab_find_slot (visited, file_data, INSERT);
+ if (*slot)
+ {
+ /* Already visited. */
+ continue;
+ }
+ *slot = file_data;
+
for (j = 0; j < file_data->num_file_names; ++j)
{
const char *this_real_name;
(*fun) (file_data->file_names[j], this_real_name, data);
}
}
+
+ do_cleanups (cleanup);
}
static int
create_quick_file_names_table (dwarf2_per_objfile->n_comp_units);
for (i = 0; i < (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_comp_units); ++i)
+ + dwarf2_per_objfile->n_type_units); ++i)
{
struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
return info_ptr;
}
-/* Read in a CU header and perform some basic error checking. */
+/* Subroutine of read_and_check_comp_unit_head and
+ read_and_check_type_unit_head to simplify them.
+ Perform various error checking on the header. */
+
+static void
+error_check_comp_unit_head (struct comp_unit_head *header,
+ struct dwarf2_section_info *section)
+{
+ bfd *abfd = section->asection->owner;
+ const char *filename = bfd_get_filename (abfd);
+
+ if (header->version != 2 && header->version != 3 && header->version != 4)
+ error (_("Dwarf Error: wrong version in compilation unit header "
+ "(is %d, should be 2, 3, or 4) [in module %s]"), header->version,
+ filename);
+
+ if (header->abbrev_offset
+ >= dwarf2_section_size (dwarf2_per_objfile->objfile,
+ &dwarf2_per_objfile->abbrev))
+ error (_("Dwarf Error: bad offset (0x%lx) in compilation unit header "
+ "(offset 0x%lx + 6) [in module %s]"),
+ (long) header->abbrev_offset, (long) header->offset,
+ filename);
+
+ /* Cast to unsigned long to use 64-bit arithmetic when possible to
+ avoid potential 32-bit overflow. */
+ if (((unsigned long) header->offset
+ + header->length + header->initial_length_size)
+ > section->size)
+ error (_("Dwarf Error: bad length (0x%lx) in compilation unit header "
+ "(offset 0x%lx + 0) [in module %s]"),
+ (long) header->length, (long) header->offset,
+ filename);
+}
+
+/* Read in a CU/TU header and perform some basic error checking.
+ The contents of the header are stored in HEADER.
+ The result is a pointer to the start of the first DIE. */
static gdb_byte *
-partial_read_comp_unit_head (struct comp_unit_head *header, gdb_byte *info_ptr,
- gdb_byte *buffer, unsigned int buffer_size,
- bfd *abfd, int is_debug_types_section)
+read_and_check_comp_unit_head (struct comp_unit_head *header,
+ struct dwarf2_section_info *section,
+ gdb_byte *info_ptr,
+ int is_debug_types_section)
{
gdb_byte *beg_of_comp_unit = info_ptr;
+ bfd *abfd = section->asection->owner;
- header->offset = beg_of_comp_unit - buffer;
+ header->offset = beg_of_comp_unit - section->buffer;
info_ptr = read_comp_unit_head (header, info_ptr, abfd);
header->first_die_offset = info_ptr - beg_of_comp_unit;
- if (header->version != 2 && header->version != 3 && header->version != 4)
- error (_("Dwarf Error: wrong version in compilation unit header "
- "(is %d, should be 2, 3, or 4) [in module %s]"), header->version,
- bfd_get_filename (abfd));
-
- if (header->abbrev_offset
- >= dwarf2_section_size (dwarf2_per_objfile->objfile,
- &dwarf2_per_objfile->abbrev))
- error (_("Dwarf Error: bad offset (0x%lx) in compilation unit header "
- "(offset 0x%lx + 6) [in module %s]"),
- (long) header->abbrev_offset,
- (long) (beg_of_comp_unit - buffer),
- bfd_get_filename (abfd));
-
- if (beg_of_comp_unit + header->length + header->initial_length_size
- > buffer + buffer_size)
- error (_("Dwarf Error: bad length (0x%lx) in compilation unit header "
- "(offset 0x%lx + 0) [in module %s]"),
- (long) header->length,
- (long) (beg_of_comp_unit - buffer),
- bfd_get_filename (abfd));
+ error_check_comp_unit_head (header, section);
return info_ptr;
}
types_ptr. The result is a pointer to one past the end of the header. */
static gdb_byte *
-read_type_comp_unit_head (struct comp_unit_head *cu_header,
- struct dwarf2_section_info *section,
- ULONGEST *signature,
- gdb_byte *types_ptr, bfd *abfd)
+read_and_check_type_unit_head (struct comp_unit_head *header,
+ struct dwarf2_section_info *section,
+ gdb_byte *info_ptr,
+ ULONGEST *signature, unsigned int *type_offset)
{
- gdb_byte *initial_types_ptr = types_ptr;
+ gdb_byte *beg_of_comp_unit = info_ptr;
+ bfd *abfd = section->asection->owner;
- dwarf2_read_section (dwarf2_per_objfile->objfile, section);
- cu_header->offset = types_ptr - section->buffer;
+ header->offset = beg_of_comp_unit - section->buffer;
- types_ptr = read_comp_unit_head (cu_header, types_ptr, abfd);
+ info_ptr = read_comp_unit_head (header, info_ptr, abfd);
- *signature = read_8_bytes (abfd, types_ptr);
- types_ptr += 8;
- types_ptr += cu_header->offset_size;
- cu_header->first_die_offset = types_ptr - initial_types_ptr;
+ /* If we're reading a type unit, skip over the signature and
+ type_offset fields. */
+ if (signature != NULL)
+ *signature = read_8_bytes (abfd, info_ptr);
+ info_ptr += 8;
+ if (type_offset != NULL)
+ *type_offset = read_offset_1 (abfd, info_ptr, header->offset_size);
+ info_ptr += header->offset_size;
+
+ header->first_die_offset = info_ptr - beg_of_comp_unit;
+
+ error_check_comp_unit_head (header, section);
- return types_ptr;
+ return info_ptr;
}
/* Allocate a new partial symtab for file named NAME and mark this new
return; /* No linetable, so no includes. */
/* NOTE: pst->dirname is DW_AT_comp_dir (if present). */
- dwarf_decode_lines (lh, pst->dirname, abfd, cu, pst);
+ dwarf_decode_lines (lh, pst->dirname, cu, pst, 1);
free_line_header (lh);
}
dummy_obstack_deallocate);
}
-/* A helper function to add a signatured type CU to a list. */
+/* A helper function to add a signatured type CU to a table. */
static int
-add_signatured_type_cu_to_list (void **slot, void *datum)
+add_signatured_type_cu_to_table (void **slot, void *datum)
{
struct signatured_type *sigt = *slot;
struct dwarf2_per_cu_data ***datap = datum;
return 1;
}
-/* Create the hash table of all entries in the .debug_types section.
+/* Create the hash table of all entries in the .debug_types section(s).
The result is zero if there is an error (e.g. missing .debug_types section),
otherwise non-zero. */
while (info_ptr < end_ptr)
{
unsigned int offset;
- unsigned int offset_size;
unsigned int type_offset;
- unsigned int length, initial_length_size;
- unsigned short version;
ULONGEST signature;
struct signatured_type *type_sig;
void **slot;
gdb_byte *ptr = info_ptr;
+ struct comp_unit_head header;
offset = ptr - section->buffer;
/* We need to read the type's signature in order to build the hash
- table, but we don't need to read anything else just yet. */
+ table, but we don't need anything else just yet. */
- /* Sanity check to ensure entire cu is present. */
- length = read_initial_length (objfile->obfd, ptr,
- &initial_length_size);
- if (ptr + length + initial_length_size > end_ptr)
- {
- complaint (&symfile_complaints,
- _("debug type entry runs off end "
- "of `.debug_types' section, ignored"));
- break;
- }
-
- offset_size = initial_length_size == 4 ? 4 : 8;
- ptr += initial_length_size;
- version = bfd_get_16 (objfile->obfd, ptr);
- ptr += 2;
- ptr += offset_size; /* abbrev offset */
- ptr += 1; /* address size */
- signature = bfd_get_64 (objfile->obfd, ptr);
- ptr += 8;
- type_offset = read_offset_1 (objfile->obfd, ptr, offset_size);
- ptr += offset_size;
+ ptr = read_and_check_type_unit_head (&header, section, ptr,
+ &signature, &type_offset);
/* Skip dummy type units. */
if (ptr >= end_ptr || peek_abbrev_code (objfile->obfd, ptr) == 0)
{
- info_ptr = info_ptr + initial_length_size + length;
+ info_ptr = info_ptr + header.initial_length_size + header.length;
continue;
}
fprintf_unfiltered (gdb_stdlog, " offset 0x%x, signature 0x%s\n",
offset, phex (signature, sizeof (signature)));
- info_ptr = info_ptr + initial_length_size + length;
+ info_ptr = info_ptr + header.initial_length_size + header.length;
}
}
dwarf2_per_objfile->signatured_types = types_htab;
- dwarf2_per_objfile->n_type_comp_units = htab_elements (types_htab);
- dwarf2_per_objfile->type_comp_units
+ dwarf2_per_objfile->n_type_units = htab_elements (types_htab);
+ dwarf2_per_objfile->all_type_units
= obstack_alloc (&objfile->objfile_obstack,
- dwarf2_per_objfile->n_type_comp_units
+ dwarf2_per_objfile->n_type_units
* sizeof (struct dwarf2_per_cu_data *));
- iter = &dwarf2_per_objfile->type_comp_units[0];
- htab_traverse_noresize (types_htab, add_signatured_type_cu_to_list, &iter);
- gdb_assert (iter - &dwarf2_per_objfile->type_comp_units[0]
- == dwarf2_per_objfile->n_type_comp_units);
+ iter = &dwarf2_per_objfile->all_type_units[0];
+ htab_traverse_noresize (types_htab, add_signatured_type_cu_to_table, &iter);
+ gdb_assert (iter - &dwarf2_per_objfile->all_type_units[0]
+ == dwarf2_per_objfile->n_type_units);
return 1;
}
init_one_comp_unit (&cu, this_cu);
back_to_inner = make_cleanup (free_stack_comp_unit, &cu);
- info_ptr = partial_read_comp_unit_head (&cu.header, info_ptr,
- buffer, buffer_size,
- abfd,
- is_debug_types_section);
+ info_ptr = read_and_check_comp_unit_head (&cu.header, section, info_ptr,
+ is_debug_types_section);
/* Skip dummy compilation units. */
if (info_ptr >= buffer + buffer_size
int has_children;
struct die_reader_specs reader_specs;
int read_cu = 0;
+ struct dwarf2_section_info *section = &dwarf2_per_objfile->info;
gdb_assert (! this_cu->debug_types_section);
- gdb_assert (dwarf2_per_objfile->info.readin);
- info_ptr = dwarf2_per_objfile->info.buffer + this_cu->offset;
+ gdb_assert (section->readin);
+ info_ptr = section->buffer + this_cu->offset;
if (this_cu->cu == NULL)
{
/* If an error occurs while loading, release our storage. */
free_cu_cleanup = make_cleanup (free_heap_comp_unit, cu);
- info_ptr = partial_read_comp_unit_head (&cu->header, info_ptr,
- dwarf2_per_objfile->info.buffer,
- dwarf2_per_objfile->info.size,
- abfd, 0);
+ info_ptr = read_and_check_comp_unit_head (&cu->header, section, info_ptr,
+ 0);
/* Skip dummy compilation units. */
- if (info_ptr >= (dwarf2_per_objfile->info.buffer
- + dwarf2_per_objfile->info.size)
+ if (info_ptr >= (section->buffer + section->size)
|| peek_abbrev_code (abfd, info_ptr) == 0)
{
do_cleanups (free_cu_cleanup);
If so, read the rest of the partial symbols from this comp unit.
If not, there's no more debug_info for this comp unit. */
if (has_children)
- load_partial_dies (abfd, dwarf2_per_objfile->info.buffer, info_ptr, 0, cu);
+ load_partial_dies (abfd, section->buffer, info_ptr, 0, cu);
do_cleanups (free_abbrevs_cleanup);
struct objfile *objfile = cu->objfile;
CORE_ADDR addr = 0;
char *actual_name = NULL;
- const struct partial_symbol *psym = NULL;
CORE_ADDR baseaddr;
int built_actual_name = 0;
if (die_needs_namespace (die, cu))
{
long length;
- char *prefix;
+ const char *prefix;
struct ui_file *buf;
prefix = determine_prefix (die, cu);
*name = "<unknown>";
}
-/* Handle DW_AT_stmt_list for a compilation unit. */
+/* Handle DW_AT_stmt_list for a compilation unit or type unit.
+ DIE is the DW_TAG_compile_unit or DW_TAG_type_unit die for CU.
+ COMP_DIR is the compilation directory.
+ WANT_LINE_INFO is non-zero if the pc/line-number mapping is needed. */
static void
handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
- const char *comp_dir)
+ const char *comp_dir, int want_line_info)
{
struct attribute *attr;
struct objfile *objfile = cu->objfile;
bfd *abfd = objfile->obfd;
- /* 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)
{
{
cu->line_header = line_header;
make_cleanup (free_cu_line_header, cu);
- dwarf_decode_lines (line_header, comp_dir, abfd, cu, NULL);
+ dwarf_decode_lines (line_header, comp_dir, cu, NULL, want_line_info);
}
}
}
record_debugformat ("DWARF 2");
record_producer (cu->producer);
- handle_DW_AT_stmt_list (die, cu, comp_dir);
+ /* 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. */
+ handle_DW_AT_stmt_list (die, cu, comp_dir, 1);
/* Process all dies in compilation unit. */
if (die->child != NULL)
record_debugformat ("DWARF 2");
record_producer (cu->producer);
- handle_DW_AT_stmt_list (die, cu, comp_dir);
+ /* 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.
+ We don't need the pc/line-number mapping for type units. */
+ handle_DW_AT_stmt_list (die, cu, comp_dir, 0);
/* Process the dies in the type unit. */
if (die->child == NULL)
i >= TYPE_N_BASECLASSES (t);
--i)
{
- char *fieldname = TYPE_FIELD_NAME (t, i);
+ const char *fieldname = TYPE_FIELD_NAME (t, i);
if (is_vtable_name (fieldname, cu))
{
int num_fields = 0;
int unsigned_enum = 1;
char *name;
+ int flag_enum = 1;
+ ULONGEST mask = 0;
child_die = die->child;
while (child_die && child_die->tag)
{
sym = new_symbol (child_die, this_type, cu);
if (SYMBOL_VALUE (sym) < 0)
- unsigned_enum = 0;
+ {
+ unsigned_enum = 0;
+ flag_enum = 0;
+ }
+ else if ((mask & SYMBOL_VALUE (sym)) != 0)
+ flag_enum = 0;
+ else
+ mask |= SYMBOL_VALUE (sym);
if ((num_fields % DW_FIELD_ALLOC_CHUNK) == 0)
{
}
if (unsigned_enum)
TYPE_UNSIGNED (this_type) = 1;
+ if (flag_enum)
+ TYPE_FLAG_ENUM (this_type) = 1;
}
/* If we are reading an enum from a .debug_types unit, and the enum
cur_abbrev->has_children = read_1_byte (abfd, abbrev_ptr);
abbrev_ptr += 1;
- if (cur_abbrev->tag == DW_TAG_namespace)
- cu->has_namespace_info = 1;
-
/* now read in declarations */
abbrev_name = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
abbrev_ptr += bytes_read;
* sizeof (struct attr_abbrev)));
}
- /* Record whether this compilation unit might have
- inter-compilation-unit references. If we don't know what form
- this attribute will have, then it might potentially be a
- DW_FORM_ref_addr, so we conservatively expect inter-CU
- references. */
-
- if (abbrev_form == DW_FORM_ref_addr
- || abbrev_form == DW_FORM_indirect)
- cu->has_form_ref_addr = 1;
-
cur_attrs[cur_abbrev->num_attrs].name = abbrev_name;
cur_attrs[cur_abbrev->num_attrs++].form = abbrev_form;
abbrev_name = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
/* If there is no parent die to provide a namespace, and there are
children, see if we can determine the namespace from their linkage
- name.
- NOTE: We need to do this even if cu->has_namespace_info != 0.
- gcc-4.5 -gdwarf-4 can drop the enclosing namespace. */
+ name. */
if (cu->language == language_cplus
&& !VEC_empty (dwarf2_section_info_def, dwarf2_per_objfile->types)
&& part_die->die_parent == NULL
return;
}
-/* Decode the Line Number Program (LNP) for the given line_header
- structure and CU. The actual information extracted and the type
- of structures created from the LNP depends on the value of PST.
-
- 1. If PST is NULL, then this procedure uses the data from the program
- to create all necessary symbol tables, and their linetables.
-
- 2. If PST is not NULL, this procedure reads the program to determine
- the list of files included by the unit represented by PST, and
- builds all the associated partial symbol tables.
-
- COMP_DIR is the compilation directory (DW_AT_comp_dir) or NULL if unknown.
- It is used for relative paths in the line table.
- NOTE: When processing partial symtabs (pst != NULL),
- comp_dir == pst->dirname.
-
- NOTE: It is important that psymtabs have the same file name (via strcmp)
- as the corresponding symtab. Since COMP_DIR is not used in the name of the
- symtab we don't use it in the name of the psymtabs we create.
- E.g. expand_line_sal requires this when finding psymtabs to expand.
- A good testcase for this is mb-inline.exp. */
+/* Subroutine of dwarf_decode_lines to simplify it.
+ Process the line number information in LH. */
static void
-dwarf_decode_lines (struct line_header *lh, const char *comp_dir, bfd *abfd,
- struct dwarf2_cu *cu, struct partial_symtab *pst)
+dwarf_decode_lines_1 (struct line_header *lh, const char *comp_dir,
+ struct dwarf2_cu *cu, struct partial_symtab *pst)
{
gdb_byte *line_ptr, *extended_end;
gdb_byte *line_end;
unsigned char op_code, extended_op, adj_opcode;
CORE_ADDR baseaddr;
struct objfile *objfile = cu->objfile;
+ bfd *abfd = objfile->obfd;
struct gdbarch *gdbarch = get_objfile_arch (objfile);
const int decode_for_pst_p = (pst != NULL);
- struct subfile *last_subfile = NULL, *first_subfile = current_subfile;
+ struct subfile *last_subfile = NULL;
void (*p_record_line) (struct subfile *subfile, int line, CORE_ADDR pc)
= record_line;
}
}
}
+}
+
+/* Decode the Line Number Program (LNP) for the given line_header
+ structure and CU. The actual information extracted and the type
+ of structures created from the LNP depends on the value of PST.
+
+ 1. If PST is NULL, then this procedure uses the data from the program
+ to create all necessary symbol tables, and their linetables.
+
+ 2. If PST is not NULL, this procedure reads the program to determine
+ the list of files included by the unit represented by PST, and
+ builds all the associated partial symbol tables.
+
+ COMP_DIR is the compilation directory (DW_AT_comp_dir) or NULL if unknown.
+ It is used for relative paths in the line table.
+ NOTE: When processing partial symtabs (pst != NULL),
+ comp_dir == pst->dirname.
+
+ NOTE: It is important that psymtabs have the same file name (via strcmp)
+ as the corresponding symtab. Since COMP_DIR is not used in the name of the
+ symtab we don't use it in the name of the psymtabs we create.
+ E.g. expand_line_sal requires this when finding psymtabs to expand.
+ A good testcase for this is mb-inline.exp. */
+
+static void
+dwarf_decode_lines (struct line_header *lh, const char *comp_dir,
+ struct dwarf2_cu *cu, struct partial_symtab *pst,
+ int want_line_info)
+{
+ struct objfile *objfile = cu->objfile;
+ const int decode_for_pst_p = (pst != NULL);
+ struct subfile *first_subfile = current_subfile;
+
+ if (want_line_info)
+ dwarf_decode_lines_1 (lh, comp_dir, cu, pst);
if (decode_for_pst_p)
{
/* 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;
+ struct file_entry *fe;
fe = &lh->file_names[i];
if (fe->dir_index)
then determine_prefix on foo's die will return "N::C". */
-static char *
+static const char *
determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
{
struct die_info *parent, *spec_die;
/* If an error occurs while loading, release our storage. */
free_cu_cleanup = make_cleanup (free_heap_comp_unit, cu);
- types_ptr = read_type_comp_unit_head (&cu->header, section, &signature,
- types_ptr, objfile->obfd);
+ types_ptr = read_and_check_type_unit_head (&cu->header, section, types_ptr,
+ &signature, NULL);
gdb_assert (signature == type_sig->signature);
cu->die_hash
}
/* A helper for dwarf_decode_macros that handles the GNU extensions,
- including DW_GNU_MACINFO_transparent_include. */
+ including DW_MACRO_GNU_transparent_include. */
static void
dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end,
struct dwarf2_section_info *section,
int section_is_gnu,
unsigned int offset_size,
- struct objfile *objfile)
+ struct objfile *objfile,
+ htab_t include_hash)
{
enum dwarf_macro_record_type macinfo_type;
int at_commandline;
case DW_MACRO_GNU_transparent_include:
{
LONGEST offset;
+ void **slot;
offset = read_offset_1 (abfd, mac_ptr, offset_size);
mac_ptr += offset_size;
- dwarf_decode_macro_bytes (abfd,
- section->buffer + offset,
- mac_end, current_file,
- lh, comp_dir,
- section, section_is_gnu,
- offset_size, objfile);
+ slot = htab_find_slot (include_hash, mac_ptr, INSERT);
+ if (*slot != NULL)
+ {
+ /* This has actually happened; see
+ http://sourceware.org/bugzilla/show_bug.cgi?id=13568. */
+ complaint (&symfile_complaints,
+ _("recursive DW_MACRO_GNU_transparent_include in "
+ ".debug_macro section"));
+ }
+ else
+ {
+ *slot = mac_ptr;
+
+ dwarf_decode_macro_bytes (abfd,
+ section->buffer + offset,
+ mac_end, current_file,
+ lh, comp_dir,
+ section, section_is_gnu,
+ offset_size, objfile, include_hash);
+
+ htab_remove_elt (include_hash, mac_ptr);
+ }
}
break;
enum dwarf_macro_record_type macinfo_type;
unsigned int offset_size = cu->header.offset_size;
gdb_byte *opcode_definitions[256];
+ struct cleanup *cleanup;
+ htab_t include_hash;
+ void **slot;
dwarf2_read_section (objfile, section);
if (section->buffer == NULL)
command-line macro definitions/undefinitions. This flag is unset when we
reach the first DW_MACINFO_start_file entry. */
- dwarf_decode_macro_bytes (abfd, section->buffer + offset, mac_end,
+ include_hash = htab_create_alloc (1, htab_hash_pointer, htab_eq_pointer,
+ NULL, xcalloc, xfree);
+ cleanup = make_cleanup_htab_delete (include_hash);
+ mac_ptr = section->buffer + offset;
+ slot = htab_find_slot (include_hash, mac_ptr, INSERT);
+ *slot = mac_ptr;
+ dwarf_decode_macro_bytes (abfd, mac_ptr, mac_end,
current_file, lh, comp_dir, section, section_is_gnu,
- offset_size, objfile);
+ offset_size, objfile, include_hash);
+ do_cleanups (cleanup);
}
/* Check if the attribute's form is a DW_FORM_block*