/* When non-zero, cross-check physname against demangler. */
static int check_physname = 0;
+/* When non-zero, do not reject deprecated .gdb_index sections. */
+int use_deprecated_index_sections = 0;
+
static int pagesize;
/* When set, the file that we're processing is known to have debugging
/* 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. */
To keep things simple we allocate both lazily. */
htab_t debug_info_type_hash;
- /* Table mapping type .debug_types DIE offsets to types.
+ /* Table mapping type .debug_types DIE sect_offset to types.
This is NULL if not allocated yet. */
htab_t debug_types_type_hash;
};
short version;
unsigned char addr_size;
unsigned char signed_addr_p;
- unsigned int abbrev_offset;
+ sect_offset abbrev_offset;
/* Size of file offsets; either 4 or 8. */
unsigned int offset_size;
/* Offset to the first byte of this compilation unit header in the
.debug_info section, for resolving relative reference dies. */
- unsigned int offset;
+ sect_offset offset;
/* Offset to first die in this cu from the start of the cu.
This will be the first byte following the compilation unit header. */
- unsigned int first_die_offset;
+ cu_offset first_die_offset;
};
/* Type used for delaying computation of method physnames.
/* Storage for the abbrev table. */
struct obstack abbrev_obstack;
- /* Hash table holding all the loaded partial DIEs. */
+ /* Hash table holding all the loaded partial DIEs
+ with partial_die->offset.SECT_OFF as hash. */
htab_t partial_dies;
/* Storage for things with the same lifetime as this read-in compilation
/* How many compilation units ago was this CU last referenced? */
int last_used;
- /* A hash table of die offsets for following references. */
+ /* A hash table of DIE cu_offset for following references with
+ die_info->offset.sect_off as hash. */
htab_t die_hash;
/* Full DIEs if read in. */
/* 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
unoptimized code. For a future better test see GCC PR other/32998. */
unsigned int has_loclist : 1;
+
+ /* These cache the results of producer_is_gxx_lt_4_6.
+ CHECKED_PRODUCER is set if PRODUCER_IS_GXX_LT_4_6 is valid. This
+ information is cached because profiling CU expansion showed
+ excessive time spent in producer_is_gxx_lt_4_6. */
+ unsigned int checked_producer : 1;
+ unsigned int producer_is_gxx_lt_4_6 : 1;
};
/* Persistent data held for a compilation unit, even when not
- if it doesn't, GDB will fall over anyway.
NOTE: Unlike comp_unit_head.length, this length includes
initial_length_size. */
- unsigned int offset;
+ sect_offset offset;
unsigned int length : 29;
/* Flag indicating this compilation unit will be read in before
any of the current compilation units are processed. */
unsigned int queued : 1;
- /* This flag will be set if we need to load absolutely all DIEs
- for this compilation unit, instead of just the ones we think
- are interesting. It gets set if we look for a DIE in the
+ /* This flag will be set when reading partial DIEs if we need to load
+ absolutely all DIEs for this compilation unit, instead of just the ones
+ we think are interesting. It gets set if we look for a DIE in the
hash table and don't find it. */
unsigned int load_all_dies : 1;
{
ULONGEST signature;
- /* Offset in .debug_types of the type defined by this TU. */
- unsigned int type_offset;
+ /* Offset in this TU of the type defined by this TU. */
+ cu_offset type_offset;
/* The CU(/TU) of this type. */
struct dwarf2_per_cu_data per_cu;
struct partial_die_info
{
/* Offset of this DIE. */
- unsigned int offset;
+ sect_offset offset;
/* DWARF-2 tag for this DIE. */
ENUM_BITFIELD(dwarf_tag) tag : 16;
unsigned int has_type : 1;
unsigned int has_specification : 1;
unsigned int has_pc_info : 1;
+ unsigned int may_be_inlined : 1;
/* Flag set if the SCOPE field of this structure has been
computed. */
/* If HAS_SPECIFICATION, the offset of the DIE referred to by
DW_AT_specification (or DW_AT_abstract_origin or
DW_AT_extension). */
- unsigned int spec_offset;
+ sect_offset spec_offset;
/* Pointers to this DIE's parent, first child, and next sibling,
if any. */
unsigned int abbrev;
/* Offset in .debug_info or .debug_types section. */
- unsigned int offset;
+ sect_offset offset;
/* The dies in a compilation unit form an n-ary tree. PARENT
points to this die's parent; CHILD points to the first child of
gdb_byte *, gdb_byte *,
struct dwarf2_cu *);
-static struct partial_die_info *find_partial_die (unsigned int,
+static struct partial_die_info *find_partial_die (sect_offset,
struct dwarf2_cu *);
static void fixup_partial_die (struct partial_die_info *,
(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 int is_ref_attr (struct attribute *);
-static unsigned int dwarf2_get_ref_die_offset (struct attribute *);
+static sect_offset dwarf2_get_ref_die_offset (struct attribute *);
static LONGEST dwarf2_get_attr_constant_value (struct attribute *, int);
static struct signatured_type *lookup_signatured_type_at_offset
(struct objfile *objfile,
- struct dwarf2_section_info *section,
- unsigned int offset);
+ struct dwarf2_section_info *section, sect_offset offset);
static void load_full_type_unit (struct dwarf2_per_cu_data *per_cu);
-static void read_signatured_type (struct signatured_type *type_sig);
+static void read_signatured_type (struct signatured_type *);
/* memory allocation interface */
static int partial_die_eq (const void *item_lhs, const void *item_rhs);
static struct dwarf2_per_cu_data *dwarf2_find_containing_comp_unit
- (unsigned int offset, struct objfile *objfile);
+ (sect_offset offset, struct objfile *objfile);
static void init_one_comp_unit (struct dwarf2_cu *cu,
struct dwarf2_per_cu_data *per_cu);
static void create_all_comp_units (struct objfile *);
-static int create_debug_types_hash_table (struct objfile *objfile);
+static int create_all_type_units (struct objfile *);
static void load_full_comp_unit (struct dwarf2_per_cu_data *);
static void dwarf2_clear_marks (struct dwarf2_per_cu_data *);
-static struct type *get_die_type_at_offset (unsigned int,
+static struct type *get_die_type_at_offset (sect_offset,
struct dwarf2_per_cu_data *per_cu);
static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu);
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];
}
the_cu = OBSTACK_ZALLOC (&objfile->objfile_obstack,
struct dwarf2_per_cu_data);
- the_cu->offset = offset;
+ the_cu->offset.sect_off = offset;
the_cu->length = length;
the_cu->objfile = objfile;
the_cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack,
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);
for (i = 0; i < elements; i += 3)
{
- struct signatured_type *type_sig;
- ULONGEST offset, type_offset, signature;
+ struct signatured_type *sig_type;
+ ULONGEST offset, type_offset_in_tu, signature;
void **slot;
if (!extract_cu_value (bytes, &offset)
- || !extract_cu_value (bytes + 8, &type_offset))
+ || !extract_cu_value (bytes + 8, &type_offset_in_tu))
return 0;
signature = extract_unsigned_integer (bytes + 16, 8, BFD_ENDIAN_LITTLE);
bytes += 3 * 8;
- type_sig = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
struct signatured_type);
- type_sig->signature = signature;
- type_sig->type_offset = type_offset;
- type_sig->per_cu.debug_types_section = section;
- type_sig->per_cu.offset = offset;
- type_sig->per_cu.objfile = objfile;
- type_sig->per_cu.v.quick
+ sig_type->signature = signature;
+ sig_type->type_offset.cu_off = type_offset_in_tu;
+ sig_type->per_cu.debug_types_section = section;
+ sig_type->per_cu.offset.sect_off = offset;
+ sig_type->per_cu.objfile = objfile;
+ sig_type->per_cu.v.quick
= OBSTACK_ZALLOC (&objfile->objfile_obstack,
struct dwarf2_per_cu_quick_data);
- slot = htab_find_slot (sig_types_hash, type_sig, INSERT);
- *slot = type_sig;
+ slot = htab_find_slot (sig_types_hash, sig_type, INSERT);
+ *slot = sig_type;
- dwarf2_per_objfile->type_comp_units[i / 3] = &type_sig->per_cu;
+ dwarf2_per_objfile->all_type_units[i / 3] = &sig_type->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
/* Versions earlier than 3 emitted every copy of a psymbol. This
causes the index to behave very poorly for certain requests. Version 3
contained incomplete addrmap. So, it seems better to just ignore such
- indices. Index version 4 uses a different hash function than index
- version 5 and later. */
+ indices. */
if (version < 4)
- return 0;
+ {
+ static int warning_printed = 0;
+ if (!warning_printed)
+ {
+ warning (_("Skipping obsolete .gdb_index section in %s."),
+ objfile->name);
+ warning_printed = 1;
+ }
+ return 0;
+ }
+ /* Index version 4 uses a different hash function than index version
+ 5 and later.
+
+ Versions earlier than 6 did not emit psymbols for inlined
+ functions. Using these files will cause GDB not to be able to
+ set breakpoints on inlined functions by name, so we ignore these
+ indices unless the --use-deprecated-index-sections command line
+ option was supplied. */
+ if (version < 6 && !use_deprecated_index_sections)
+ {
+ static int warning_printed = 0;
+ if (!warning_printed)
+ {
+ warning (_("Skipping deprecated .gdb_index section in %s, pass "
+ "--use-deprecated-index-sections to use them anyway"),
+ objfile->name);
+ warning_printed = 1;
+ }
+ return 0;
+ }
/* Indexes with higher version than the one supported by GDB may be no
longer backward compatible. */
- if (version > 5)
+ if (version > 6)
return 0;
map = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct mapped_index);
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.sect_off;
- 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
dwarf2_per_objfile->using_index = 1;
create_all_comp_units (objfile);
- create_debug_types_hash_table (objfile);
+ create_all_type_units (objfile);
dwarf2_per_objfile->quick_file_names_table =
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 TRUE if OFFSET is within CU_HEADER. */
static inline int
-offset_in_cu_p (const struct comp_unit_head *cu_header, unsigned int offset)
+offset_in_cu_p (const struct comp_unit_head *cu_header, sect_offset offset)
{
- unsigned int bottom = cu_header->offset;
- unsigned int top = (cu_header->offset
- + cu_header->length
- + cu_header->initial_length_size);
+ sect_offset bottom = { cu_header->offset.sect_off };
+ sect_offset top = { (cu_header->offset.sect_off + cu_header->length
+ + cu_header->initial_length_size) };
- return (offset >= bottom && offset < top);
+ return (offset.sect_off >= bottom.sect_off && offset.sect_off < top.sect_off);
}
/* Read in the comp unit header information from the debug_info at info_ptr.
info_ptr += bytes_read;
cu_header->version = read_2_bytes (abfd, info_ptr);
info_ptr += 2;
- cu_header->abbrev_offset = read_offset (abfd, info_ptr, cu_header,
- &bytes_read);
+ cu_header->abbrev_offset.sect_off = read_offset (abfd, info_ptr, cu_header,
+ &bytes_read);
info_ptr += bytes_read;
cu_header->addr_size = read_1_byte (abfd, info_ptr);
info_ptr += 1;
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.sect_off
+ >= 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.sect_off, (long) header->offset.sect_off,
+ filename);
+
+ /* Cast to unsigned long to use 64-bit arithmetic when possible to
+ avoid potential 32-bit overflow. */
+ if (((unsigned long) header->offset.sect_off
+ + 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.sect_off,
+ 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.sect_off = beg_of_comp_unit - section->buffer;
info_ptr = read_comp_unit_head (header, info_ptr, abfd);
if (is_debug_types_section)
info_ptr += 8 /*signature*/ + header->offset_size;
- 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));
+ header->first_die_offset.cu_off = info_ptr - beg_of_comp_unit;
- 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, cu_offset *type_offset)
{
- gdb_byte *initial_types_ptr = types_ptr;
+ gdb_byte *beg_of_comp_unit = info_ptr;
+ bfd *abfd = section->asection->owner;
+
+ header->offset.sect_off = beg_of_comp_unit - section->buffer;
- dwarf2_read_section (dwarf2_per_objfile->objfile, section);
- cu_header->offset = types_ptr - section->buffer;
+ info_ptr = read_comp_unit_head (header, info_ptr, abfd);
- types_ptr = read_comp_unit_head (cu_header, types_ptr, abfd);
+ /* 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->cu_off = read_offset_1 (abfd, info_ptr, header->offset_size);
+ info_ptr += header->offset_size;
- *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;
+ header->first_die_offset.cu_off = info_ptr - beg_of_comp_unit;
- return types_ptr;
+ error_check_comp_unit_head (header, section);
+
+ 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);
}
static hashval_t
-hash_type_signature (const void *item)
+hash_signatured_type (const void *item)
{
- const struct signatured_type *type_sig = item;
+ const struct signatured_type *sig_type = item;
/* This drops the top 32 bits of the signature, but is ok for a hash. */
- return type_sig->signature;
+ return sig_type->signature;
}
static int
-eq_type_signature (const void *item_lhs, const void *item_rhs)
+eq_signatured_type (const void *item_lhs, const void *item_rhs)
{
const struct signatured_type *lhs = item_lhs;
const struct signatured_type *rhs = item_rhs;
allocate_signatured_type_table (struct objfile *objfile)
{
return htab_create_alloc_ex (41,
- hash_type_signature,
- eq_type_signature,
+ hash_signatured_type,
+ eq_signatured_type,
NULL,
&objfile->objfile_obstack,
hashtab_obstack_allocate,
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.
- The result is zero if there is an error (e.g. missing .debug_types section),
- otherwise non-zero. */
+/* Create the hash table of all entries in the .debug_types section(s).
+ The result is zero if there are no .debug_types sections,
+ otherwise non-zero. */
static int
-create_debug_types_hash_table (struct objfile *objfile)
+create_all_type_units (struct objfile *objfile)
{
htab_t types_htab = NULL;
struct dwarf2_per_cu_data **iter;
end_ptr = info_ptr + section->size;
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;
+ sect_offset offset;
+ cu_offset type_offset;
ULONGEST signature;
- struct signatured_type *type_sig;
+ struct signatured_type *sig_type;
void **slot;
gdb_byte *ptr = info_ptr;
+ struct comp_unit_head header;
- offset = ptr - section->buffer;
+ offset.sect_off = 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. */
-
- /* 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;
- }
+ table, but we don't need anything else just yet. */
- 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;
}
- type_sig = obstack_alloc (&objfile->objfile_obstack, sizeof (*type_sig));
- memset (type_sig, 0, sizeof (*type_sig));
- type_sig->signature = signature;
- type_sig->type_offset = type_offset;
- type_sig->per_cu.objfile = objfile;
- type_sig->per_cu.debug_types_section = section;
- type_sig->per_cu.offset = offset;
+ sig_type = obstack_alloc (&objfile->objfile_obstack, sizeof (*sig_type));
+ memset (sig_type, 0, sizeof (*sig_type));
+ sig_type->signature = signature;
+ sig_type->type_offset = type_offset;
+ sig_type->per_cu.objfile = objfile;
+ sig_type->per_cu.debug_types_section = section;
+ sig_type->per_cu.offset = offset;
- slot = htab_find_slot (types_htab, type_sig, INSERT);
+ slot = htab_find_slot (types_htab, sig_type, INSERT);
gdb_assert (slot != NULL);
if (*slot != NULL)
{
complaint (&symfile_complaints,
_("debug type entry at offset 0x%x is duplicate to the "
"entry at offset 0x%x, signature 0x%s"),
- offset, dup_sig->per_cu.offset,
+ offset.sect_off, dup_sig->per_cu.offset.sect_off,
phex (signature, sizeof (signature)));
gdb_assert (signature == dup_sig->signature);
}
- *slot = type_sig;
+ *slot = sig_type;
if (dwarf2_die_debug)
fprintf_unfiltered (gdb_stdlog, " offset 0x%x, signature 0x%s\n",
- offset, phex (signature, sizeof (signature)));
+ offset.sect_off,
+ 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;
}
/* Lookup a signature based type.
- Returns NULL if SIG is not present in the table. */
+ Returns NULL if signature SIG is not present in the table. */
static struct signatured_type *
-lookup_signatured_type (struct objfile *objfile, ULONGEST sig)
+lookup_signatured_type (ULONGEST sig)
{
struct signatured_type find_entry, *entry;
SECTION is the section the CU/TU comes from,
either .debug_info or .debug_types. */
-void
+static void
process_psymtab_comp_unit (struct dwarf2_per_cu_data *this_cu,
struct dwarf2_section_info *section,
int is_debug_types_section)
struct objfile *objfile = this_cu->objfile;
bfd *abfd = objfile->obfd;
gdb_byte *buffer = section->buffer;
- gdb_byte *info_ptr = buffer + this_cu->offset;
+ gdb_byte *info_ptr = buffer + this_cu->offset.sect_off;
unsigned int buffer_size = section->size;
gdb_byte *beg_of_comp_unit = info_ptr;
struct die_info *comp_unit_die;
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
if (is_debug_types_section)
{
/* LENGTH has not been set yet for type units. */
- gdb_assert (this_cu->offset == cu.header.offset);
+ gdb_assert (this_cu->offset.sect_off == cu.header.offset.sect_off);
this_cu->length = cu.header.length + cu.header.initial_length_size;
}
else if (comp_unit_die->tag == DW_TAG_partial_unit)
static void
build_type_psymtabs (struct objfile *objfile)
{
- if (! create_debug_types_hash_table (objfile))
+ if (! create_all_type_units (objfile))
return;
htab_traverse_noresize (dwarf2_per_objfile->signatured_types,
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.sect_off;
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);
return;
}
-
- /* Link this CU into read_in_chain. */
- this_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
- dwarf2_per_objfile->read_in_chain = this_cu;
}
else
{
cu = this_cu->cu;
- info_ptr += cu->header.first_die_offset;
+ info_ptr += cu->header.first_die_offset.cu_off;
}
/* Read the abbrevs for this compilation unit into a table. */
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);
/* We've successfully allocated this compilation unit. Let our
caller clean it up when finished with it. */
discard_cleanups (free_cu_cleanup);
+
+ /* Link this CU into read_in_chain. */
+ this_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
+ dwarf2_per_objfile->read_in_chain = this_cu;
}
}
{
unsigned int length, initial_length_size;
struct dwarf2_per_cu_data *this_cu;
- unsigned int offset;
+ sect_offset offset;
- offset = info_ptr - dwarf2_per_objfile->info.buffer;
+ offset.sect_off = info_ptr - dwarf2_per_objfile->info.buffer;
/* Read just enough information to find out where the next
compilation unit is. */
ignoring them. */
complaint (&symfile_complaints,
_("unhandled containing DIE tag %d for DIE at %d"),
- parent->tag, pdi->offset);
+ parent->tag, pdi->offset.sect_off);
parent->scope = grandparent_scope;
}
struct attribute attr;
struct dwarf2_cu *ref_cu = cu;
+ /* DW_FORM_ref_addr is using section offset. */
attr.name = 0;
attr.form = DW_FORM_ref_addr;
- attr.u.addr = pdi->offset;
+ attr.u.addr = pdi->offset.sect_off;
die = follow_die_ref (NULL, &attr, &ref_cu);
return xstrdup (dwarf2_full_name (NULL, die, ref_cu));
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;
pdi->highpc - 1 + baseaddr,
cu->per_cu->v.psymtab);
}
+ }
+
+ if (pdi->has_pc_info || (!pdi->is_external && pdi->may_be_inlined))
+ {
if (!pdi->is_declaration)
/* Ignore subprogram DIEs that do not have a name, they are
illegal. Do not emit a complaint at this point, we will
complaint (&symfile_complaints,
_("ignoring absolute DW_AT_sibling"));
else
- return buffer + dwarf2_get_ref_die_offset (&attr);
+ return buffer + dwarf2_get_ref_die_offset (&attr).sect_off;
}
/* If it isn't DW_AT_sibling, skip this attribute. */
struct objfile *objfile = per_cu->objfile;
bfd *abfd = objfile->obfd;
struct dwarf2_cu *cu;
- unsigned int offset;
+ sect_offset offset;
gdb_byte *info_ptr, *beg_of_comp_unit;
- struct cleanup *free_abbrevs_cleanup = NULL, *free_cu_cleanup = NULL;
+ struct cleanup *free_cu_cleanup = NULL;
struct attribute *attr;
int read_cu = 0;
offset = per_cu->offset;
dwarf2_read_section (objfile, &dwarf2_per_objfile->info);
- info_ptr = dwarf2_per_objfile->info.buffer + offset;
+ info_ptr = dwarf2_per_objfile->info.buffer + offset.sect_off;
beg_of_comp_unit = info_ptr;
if (per_cu->cu == NULL)
/* Complete the cu_header. */
cu->header.offset = offset;
- cu->header.first_die_offset = info_ptr - beg_of_comp_unit;
-
- /* Read the abbrevs for this compilation unit. */
- dwarf2_read_abbrevs (cu);
- free_abbrevs_cleanup = make_cleanup (dwarf2_free_abbrev_table, cu);
-
- /* Link this CU into read_in_chain. */
- per_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
- dwarf2_per_objfile->read_in_chain = per_cu;
+ cu->header.first_die_offset.cu_off = info_ptr - beg_of_comp_unit;
}
else
{
cu = per_cu->cu;
- info_ptr += cu->header.first_die_offset;
+ info_ptr += cu->header.first_die_offset.cu_off;
}
cu->dies = read_comp_unit (info_ptr, cu);
if (read_cu)
{
- do_cleanups (free_abbrevs_cleanup);
-
/* We've successfully allocated this compilation unit. Let our
caller clean it up when finished with it. */
discard_cleanups (free_cu_cleanup);
+
+ /* Link this CU into read_in_chain. */
+ per_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
+ dwarf2_per_objfile->read_in_chain = per_cu;
}
}
/* GCC-4.0 has started to support -fvar-tracking. GCC-3.x still can
produce DW_AT_location with location lists but it can be possibly
- invalid without -fvar-tracking.
+ invalid without -fvar-tracking. Still up to GCC-4.4.x incl. 4.4.0
+ there were bugs in prologue debug info, fixed later in GCC-4.5
+ by "unwind info for epilogues" patch (which is not directly related).
For -gdwarf-4 type units LOCATIONS_VALID indication is fortunately not
needed, it would be wrong due to missing DW_AT_producer there.
Still one can confuse GDB by using non-standard GCC compilation
options - this waits on GCC PR other/32998 (-frecord-gcc-switches).
*/
- if (cu->has_loclist && gcc_4_minor >= 0)
+ if (cu->has_loclist && gcc_4_minor >= 5)
symtab->locations_valid = 1;
if (gcc_4_minor >= 5)
if (die_needs_namespace (die, cu))
{
long length;
- char *prefix;
+ const char *prefix;
struct ui_file *buf;
prefix = determine_prefix (die, cu);
complaint (&symfile_complaints,
_("Computed physname <%s> does not match demangled <%s> "
"(from linkage <%s>) - DIE at 0x%x [in module %s]"),
- physname, canon, mangled, die->offset, objfile->name);
+ physname, canon, mangled, die->offset.sect_off, objfile->name);
/* Prefer DW_AT_linkage_name (in the CANON form) - when it
is available here - over computed PHYSNAME. It is safer
complaint (&symfile_complaints,
_("child DW_TAG_imported_declaration expected "
"- DIE at 0x%x [in module %s]"),
- child_die->offset, objfile->name);
+ child_die->offset.sect_off, objfile->name);
continue;
}
complaint (&symfile_complaints,
_("child DW_TAG_imported_declaration has unknown "
"imported name - DIE at 0x%x [in module %s]"),
- child_die->offset, objfile->name);
+ child_die->offset.sect_off, objfile->name);
continue;
}
*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)
struct die_info *child_die;
unsigned die_children_count;
/* CU offsets which were referenced by children of the current DIE. */
- unsigned *offsets;
- unsigned *offsets_end, *offsetp;
+ sect_offset *offsets;
+ sect_offset *offsets_end, *offsetp;
/* Parent of DIE - referenced by DW_AT_abstract_origin. */
struct die_info *origin_die;
/* Iterator of the ORIGIN_DIE children. */
&& origin_die->tag == DW_TAG_subprogram))
complaint (&symfile_complaints,
_("DIE 0x%x and its abstract origin 0x%x have different tags"),
- die->offset, origin_die->offset);
+ die->offset.sect_off, origin_die->offset.sect_off);
child_die = die->child;
die_children_count = 0;
&& child_origin_die->tag == DW_TAG_subprogram))
complaint (&symfile_complaints,
_("Child DIE 0x%x and its abstract origin 0x%x have "
- "different tags"), child_die->offset,
- child_origin_die->offset);
+ "different tags"), child_die->offset.sect_off,
+ child_origin_die->offset.sect_off);
if (child_origin_die->parent != origin_die)
complaint (&symfile_complaints,
_("Child DIE 0x%x and its abstract origin 0x%x have "
- "different parents"), child_die->offset,
- child_origin_die->offset);
+ "different parents"), child_die->offset.sect_off,
+ child_origin_die->offset.sect_off);
else
*offsets_end++ = child_origin_die->offset;
}
qsort (offsets, offsets_end - offsets, sizeof (*offsets),
unsigned_int_compar);
for (offsetp = offsets + 1; offsetp < offsets_end; offsetp++)
- if (offsetp[-1] == *offsetp)
+ if (offsetp[-1].sect_off == offsetp->sect_off)
complaint (&symfile_complaints,
_("Multiple children of DIE 0x%x refer "
"to DIE 0x%x as their abstract origin"),
- die->offset, *offsetp);
+ die->offset.sect_off, offsetp->sect_off);
offsetp = offsets;
origin_child_die = origin_die->child;
while (origin_child_die && origin_child_die->tag)
{
/* Is ORIGIN_CHILD_DIE referenced by any of the DIE children? */
- while (offsetp < offsets_end && *offsetp < origin_child_die->offset)
+ while (offsetp < offsets_end
+ && offsetp->sect_off < origin_child_die->offset.sect_off)
offsetp++;
- if (offsetp >= offsets_end || *offsetp > origin_child_die->offset)
+ if (offsetp >= offsets_end
+ || offsetp->sect_off > origin_child_die->offset.sect_off)
{
/* Found that ORIGIN_CHILD_DIE is really not referenced. */
process_die (origin_child_die, origin_cu);
if (name == NULL)
{
complaint (&symfile_complaints,
- _("missing name for subprogram DIE at %d"), die->offset);
+ _("missing name for subprogram DIE at %d"),
+ die->offset.sect_off);
return;
}
complaint (&symfile_complaints,
_("cannot get low and high bounds "
"for subprogram DIE at %d"),
- die->offset);
+ die->offset.sect_off);
return;
}
complaint (&symfile_complaints,
_("missing DW_AT_low_pc for DW_TAG_GNU_call_site "
"DIE 0x%x [in module %s]"),
- die->offset, objfile->name);
+ die->offset.sect_off, objfile->name);
return;
}
pc = DW_ADDR (attr) + baseaddr;
complaint (&symfile_complaints,
_("Duplicate PC %s for DW_TAG_GNU_call_site "
"DIE 0x%x [in module %s]"),
- paddress (gdbarch, pc), die->offset, objfile->name);
+ paddress (gdbarch, pc), die->offset.sect_off, objfile->name);
return;
}
complaint (&symfile_complaints,
_("Tag %d is not DW_TAG_GNU_call_site_parameter in "
"DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
- child_die->tag, child_die->offset, objfile->name);
+ child_die->tag, child_die->offset.sect_off, objfile->name);
continue;
}
complaint (&symfile_complaints,
_("Cannot find function owning DW_TAG_GNU_call_site "
"DIE 0x%x [in module %s]"),
- die->offset, objfile->name);
+ die->offset.sect_off, objfile->name);
}
}
complaint (&symfile_complaints,
_("DW_AT_GNU_call_site_target target DIE has invalid "
"physname, for referencing DIE 0x%x [in module %s]"),
- die->offset, objfile->name);
+ die->offset.sect_off, objfile->name);
else
SET_FIELD_PHYSNAME (call_site->target, (char *) target_physname);
}
complaint (&symfile_complaints,
_("DW_AT_GNU_call_site_target target DIE has invalid "
"low pc, for referencing DIE 0x%x [in module %s]"),
- die->offset, objfile->name);
+ die->offset.sect_off, objfile->name);
else
SET_FIELD_PHYSADDR (call_site->target, lowpc + baseaddr);
}
complaint (&symfile_complaints,
_("DW_TAG_GNU_call_site DW_AT_GNU_call_site_target is neither "
"block nor reference, for DIE 0x%x [in module %s]"),
- die->offset, objfile->name);
+ die->offset.sect_off, objfile->name);
call_site->per_cu = cu->per_cu;
complaint (&symfile_complaints,
_("No DW_FORM_block* DW_AT_location for "
"DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
- child_die->offset, objfile->name);
+ child_die->offset.sect_off, objfile->name);
continue;
}
parameter->dwarf_reg = dwarf_block_to_dwarf_reg (DW_BLOCK (attr)->data,
_("Only single DW_OP_reg or DW_OP_fbreg is supported "
"for DW_FORM_block* DW_AT_location for "
"DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
- child_die->offset, objfile->name);
+ child_die->offset.sect_off, objfile->name);
continue;
}
complaint (&symfile_complaints,
_("No DW_FORM_block* DW_AT_GNU_call_site_value for "
"DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
- child_die->offset, objfile->name);
+ child_die->offset.sect_off, objfile->name);
continue;
}
parameter->value = DW_BLOCK (attr)->data;
complaint (&symfile_complaints,
_("No DW_FORM_block* DW_AT_GNU_call_site_data_value for "
"DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
- child_die->offset, objfile->name);
+ child_die->offset.sect_off, objfile->name);
else
{
parameter->data_value = DW_BLOCK (attr)->data;
{
const char *cs;
int major, minor, release;
+ int result = 0;
if (cu->producer == NULL)
{
return 0;
}
+ if (cu->checked_producer)
+ return cu->producer_is_gxx_lt_4_6;
+
/* Skip any identifier after "GNU " - such as "C++" or "Java". */
if (strncmp (cu->producer, "GNU ", strlen ("GNU ")) != 0)
{
/* For non-GCC compilers expect their behavior is DWARF version
compliant. */
-
- return 0;
}
- cs = &cu->producer[strlen ("GNU ")];
- while (*cs && !isdigit (*cs))
- cs++;
- if (sscanf (cs, "%d.%d.%d", &major, &minor, &release) != 3)
+ else
{
- /* Not recognized as GCC. */
-
- return 0;
+ cs = &cu->producer[strlen ("GNU ")];
+ while (*cs && !isdigit (*cs))
+ cs++;
+ if (sscanf (cs, "%d.%d.%d", &major, &minor, &release) != 3)
+ {
+ /* Not recognized as GCC. */
+ }
+ else
+ result = major < 4 || (major == 4 && minor < 6);
}
- return major < 4 || (major == 4 && minor < 6);
+ cu->checked_producer = 1;
+ cu->producer_is_gxx_lt_4_6 = result;
+
+ return result;
}
/* Return the default accessibility type if it is not overriden by
complaint (&symfile_complaints,
_("Member function \"%s\" (offset %d) is virtual "
"but the vtable offset is not specified"),
- fieldname, die->offset);
+ fieldname, die->offset.sect_off);
ALLOCATE_CPLUS_STRUCT_TYPE (type);
TYPE_CPLUS_DYNAMIC (type) = 1;
}
struct dwarf2_cu *cu)
{
struct fnfieldlist *flp;
- int total_length = 0;
int i;
if (cu->language == language_ada)
TYPE_ALLOC (type, sizeof (struct fn_field) * flp->length);
for (k = flp->length; (k--, nfp); nfp = nfp->next)
fn_flp->fn_fields[k] = nfp->fnfield;
-
- total_length += flp->length;
}
TYPE_NFN_FIELDS (type) = fip->nfnfields;
- TYPE_NFN_FIELDS_TOTAL (type) = total_length;
}
/* Returns non-zero if NAME is the name of a vtable member in CU's
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
if (cu->per_cu->debug_types_section
&& die_is_declaration (die, cu))
{
- struct signatured_type *type_sig;
+ struct signatured_type *sig_type;
- type_sig
+ sig_type
= lookup_signatured_type_at_offset (dwarf2_per_objfile->objfile,
cu->per_cu->debug_types_section,
cu->per_cu->offset);
- if (type_sig->type_offset != die->offset)
+ if (sig_type->per_cu.offset.sect_off + sig_type->type_offset.cu_off
+ != die->offset.sect_off)
return;
}
if (!module_name)
complaint (&symfile_complaints,
_("DW_TAG_module has no name, offset 0x%x"),
- die->offset);
+ die->offset.sect_off);
type = init_type (TYPE_CODE_MODULE, 0, 0, module_name, objfile);
/* determine_prefix uses TYPE_TAG_NAME. */
complaint (&symfile_complaints,
_("Self-referential DW_TAG_typedef "
"- DIE at 0x%x [in module %s]"),
- die->offset, objfile->name);
+ die->offset.sect_off, objfile->name);
TYPE_TARGET_TYPE (this_type) = NULL;
}
return this_type;
{
const struct die_info *die = item;
- return die->offset;
+ return die->offset.sect_off;
}
/* Trivial comparison function for die_info structures: two DIEs
const struct die_info *die_lhs = item_lhs;
const struct die_info *die_rhs = item_rhs;
- return die_lhs->offset == die_rhs->offset;
+ return die_lhs->offset.sect_off == die_rhs->offset.sect_off;
}
/* Read a whole compilation unit into a linked list of dies. */
struct die_info **diep, gdb_byte *info_ptr,
int *has_children)
{
- unsigned int abbrev_number, bytes_read, i, offset;
+ unsigned int abbrev_number, bytes_read, i;
+ sect_offset offset;
struct abbrev_info *abbrev;
struct die_info *die;
struct dwarf2_cu *cu = reader->cu;
bfd *abfd = reader->abfd;
- offset = info_ptr - reader->buffer;
+ offset.sect_off = info_ptr - reader->buffer;
abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
info_ptr += bytes_read;
if (!abbrev_number)
dwarf2_read_section (dwarf2_per_objfile->objfile,
&dwarf2_per_objfile->abbrev);
- abbrev_ptr = dwarf2_per_objfile->abbrev.buffer + cu_header->abbrev_offset;
+ abbrev_ptr = (dwarf2_per_objfile->abbrev.buffer
+ + cu_header->abbrev_offset.sect_off);
abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
abbrev_ptr += bytes_read;
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);
struct abbrev_info *abbrev;
unsigned int bytes_read;
unsigned int load_all = 0;
-
int nesting_level = 1;
parent_die = NULL;
last_die = NULL;
- if (cu->per_cu && cu->per_cu->load_all_dies)
+ gdb_assert (cu->per_cu != NULL);
+ if (cu->per_cu->load_all_dies)
load_all = 1;
cu->partial_dies
}
}
- /* We only recurse into subprograms looking for template arguments.
+ /* We only recurse into c++ subprograms looking for template arguments.
Skip their other children. */
if (!load_all
&& cu->language == language_cplus
complaint (&symfile_complaints,
_("DW_TAG_typedef has childen - GCC PR debug/47510 bug "
"- DIE at 0x%x [in module %s]"),
- part_die->offset, objfile->name);
+ part_die->offset.sect_off, objfile->name);
/* If we're at the second level, and we're an enumerator, and
our parent has no specification (meaning possibly lives in a
void **slot;
slot = htab_find_slot_with_hash (cu->partial_dies, part_die,
- part_die->offset, INSERT);
+ part_die->offset.sect_off, INSERT);
*slot = part_die;
}
memset (part_die, 0, sizeof (struct partial_die_info));
- part_die->offset = info_ptr - buffer;
+ part_die->offset.sect_off = info_ptr - buffer;
info_ptr += abbrev_len;
complaint (&symfile_complaints,
_("ignoring absolute DW_AT_sibling"));
else
- part_die->sibling = buffer + dwarf2_get_ref_die_offset (&attr);
+ part_die->sibling = buffer + dwarf2_get_ref_die_offset (&attr).sect_off;
break;
case DW_AT_byte_size:
part_die->has_byte_size = 1;
language_of_main = language_fortran;
}
break;
+ case DW_AT_inline:
+ if (DW_UNSND (&attr) == DW_INL_inlined
+ || DW_UNSND (&attr) == DW_INL_declared_inlined)
+ part_die->may_be_inlined = 1;
+ break;
default:
break;
}
_("DW_AT_low_pc %s is zero "
"for DIE at 0x%x [in module %s]"),
paddress (gdbarch, part_die->lowpc),
- part_die->offset, objfile->name);
+ part_die->offset.sect_off, objfile->name);
}
/* dwarf2_get_pc_bounds has also the strict low < high requirement. */
else if (part_die->lowpc >= part_die->highpc)
"for DIE at 0x%x [in module %s]"),
paddress (gdbarch, part_die->lowpc),
paddress (gdbarch, part_die->highpc),
- part_die->offset, objfile->name);
+ part_die->offset.sect_off, objfile->name);
}
else
part_die->has_pc_info = 1;
/* Find a cached partial DIE at OFFSET in CU. */
static struct partial_die_info *
-find_partial_die_in_comp_unit (unsigned int offset, struct dwarf2_cu *cu)
+find_partial_die_in_comp_unit (sect_offset offset, struct dwarf2_cu *cu)
{
struct partial_die_info *lookup_die = NULL;
struct partial_die_info part_die;
part_die.offset = offset;
- lookup_die = htab_find_with_hash (cu->partial_dies, &part_die, offset);
+ lookup_die = htab_find_with_hash (cu->partial_dies, &part_die,
+ offset.sect_off);
return lookup_die;
}
DW_FORM_ref_sig8). */
static struct partial_die_info *
-find_partial_die (unsigned int offset, struct dwarf2_cu *cu)
+find_partial_die (sect_offset offset, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
struct dwarf2_per_cu_data *per_cu = NULL;
struct partial_die_info *pd = NULL;
- if (cu->per_cu->debug_types_section)
- {
- pd = find_partial_die_in_comp_unit (offset, cu);
- if (pd != NULL)
- return pd;
- goto not_found;
- }
-
if (offset_in_cu_p (&cu->header, offset))
{
pd = find_partial_die_in_comp_unit (offset, cu);
if (pd != NULL)
return pd;
+ /* We missed recording what we needed.
+ Load all dies and try again. */
+ per_cu = cu->per_cu;
}
+ else
+ {
+ /* TUs don't reference other CUs/TUs (except via type signatures). */
+ if (cu->per_cu->debug_types_section)
+ {
+ error (_("Dwarf Error: Type Unit at offset 0x%lx contains"
+ " external reference to offset 0x%lx [in module %s].\n"),
+ (long) cu->header.offset.sect_off, (long) offset.sect_off,
+ bfd_get_filename (objfile->obfd));
+ }
+ per_cu = dwarf2_find_containing_comp_unit (offset, objfile);
- per_cu = dwarf2_find_containing_comp_unit (offset, objfile);
-
- if (per_cu->cu == NULL || per_cu->cu->partial_dies == NULL)
- load_partial_comp_unit (per_cu);
+ if (per_cu->cu == NULL || per_cu->cu->partial_dies == NULL)
+ load_partial_comp_unit (per_cu);
- per_cu->cu->last_used = 0;
- pd = find_partial_die_in_comp_unit (offset, per_cu->cu);
+ per_cu->cu->last_used = 0;
+ pd = find_partial_die_in_comp_unit (offset, per_cu->cu);
+ }
if (pd == NULL && per_cu->load_all_dies == 0)
{
struct abbrev_info *abbrev;
unsigned int bytes_read;
char *info_ptr;
+ struct dwarf2_section_info *sec;
per_cu->load_all_dies = 1;
- /* Re-read the DIEs. */
+ if (per_cu->debug_types_section)
+ sec = per_cu->debug_types_section;
+ else
+ sec = &dwarf2_per_objfile->info;
+
+ /* Re-read the DIEs, this time reading all of them.
+ NOTE: We don't discard the previous set of DIEs.
+ This doesn't happen very often so it's (hopefully) not a problem. */
back_to = make_cleanup (null_cleanup, 0);
if (per_cu->cu->dwarf2_abbrevs == NULL)
{
dwarf2_read_abbrevs (per_cu->cu);
make_cleanup (dwarf2_free_abbrev_table, per_cu->cu);
}
- info_ptr = (dwarf2_per_objfile->info.buffer
- + per_cu->cu->header.offset
- + per_cu->cu->header.first_die_offset);
+ info_ptr = (sec->buffer
+ + per_cu->cu->header.offset.sect_off
+ + per_cu->cu->header.first_die_offset.cu_off);
abbrev = peek_die_abbrev (info_ptr, &bytes_read, per_cu->cu);
info_ptr = read_partial_die (&comp_unit_die, abbrev, bytes_read,
- objfile->obfd,
- dwarf2_per_objfile->info.buffer, info_ptr,
+ objfile->obfd, sec->buffer, info_ptr,
per_cu->cu);
if (comp_unit_die.has_children)
- load_partial_dies (objfile->obfd,
- dwarf2_per_objfile->info.buffer, info_ptr,
- 0, per_cu->cu);
+ load_partial_dies (objfile->obfd, sec->buffer, info_ptr, 0,
+ per_cu->cu);
do_cleanups (back_to);
pd = find_partial_die_in_comp_unit (offset, per_cu->cu);
}
- not_found:
-
if (pd == NULL)
internal_error (__FILE__, __LINE__,
_("could not find partial DIE 0x%x "
"in cache [from module %s]\n"),
- offset, bfd_get_filename (objfile->obfd));
+ offset.sect_off, bfd_get_filename (objfile->obfd));
return pd;
}
/* 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
info_ptr += bytes_read;
break;
case DW_FORM_ref1:
- DW_ADDR (attr) = cu->header.offset + read_1_byte (abfd, info_ptr);
+ DW_ADDR (attr) = (cu->header.offset.sect_off
+ + read_1_byte (abfd, info_ptr));
info_ptr += 1;
break;
case DW_FORM_ref2:
- DW_ADDR (attr) = cu->header.offset + read_2_bytes (abfd, info_ptr);
+ DW_ADDR (attr) = (cu->header.offset.sect_off
+ + read_2_bytes (abfd, info_ptr));
info_ptr += 2;
break;
case DW_FORM_ref4:
- DW_ADDR (attr) = cu->header.offset + read_4_bytes (abfd, info_ptr);
+ DW_ADDR (attr) = (cu->header.offset.sect_off
+ + read_4_bytes (abfd, info_ptr));
info_ptr += 4;
break;
case DW_FORM_ref8:
- DW_ADDR (attr) = cu->header.offset + read_8_bytes (abfd, info_ptr);
+ DW_ADDR (attr) = (cu->header.offset.sect_off
+ + read_8_bytes (abfd, info_ptr));
info_ptr += 8;
break;
case DW_FORM_ref_sig8:
for later lookup.
NOTE: This is NULL if the type wasn't found. */
DW_SIGNATURED_TYPE (attr) =
- lookup_signatured_type (cu->objfile, read_8_bytes (abfd, info_ptr));
+ lookup_signatured_type (read_8_bytes (abfd, info_ptr));
info_ptr += 8;
break;
case DW_FORM_ref_udata:
- DW_ADDR (attr) = (cu->header.offset
+ DW_ADDR (attr) = (cu->header.offset.sect_off
+ read_unsigned_leb128 (abfd, info_ptr, &bytes_read));
info_ptr += bytes_read;
break;
static struct attribute *
dwarf2_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *cu)
{
- unsigned int i;
- struct attribute *spec = NULL;
-
- for (i = 0; i < die->num_attrs; ++i)
+ for (;;)
{
- if (die->attrs[i].name == name)
- return &die->attrs[i];
- if (die->attrs[i].name == DW_AT_specification
- || die->attrs[i].name == DW_AT_abstract_origin)
- spec = &die->attrs[i];
- }
+ unsigned int i;
+ struct attribute *spec = NULL;
+
+ for (i = 0; i < die->num_attrs; ++i)
+ {
+ if (die->attrs[i].name == name)
+ return &die->attrs[i];
+ if (die->attrs[i].name == DW_AT_specification
+ || die->attrs[i].name == DW_AT_abstract_origin)
+ spec = &die->attrs[i];
+ }
+
+ if (!spec)
+ break;
- if (spec)
- {
die = follow_die_ref (die, spec, &cu);
- return dwarf2_attr (die, name, cu);
}
return 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)
finish_block. */
SYMBOL_CLASS (sym) = LOC_BLOCK;
SYMBOL_INLINED (sym) = 1;
- /* Do not add the symbol to any lists. It will be found via
- BLOCK_FUNCTION from the blockvector. */
+ list_to_add = cu->list_in_scope;
break;
case DW_TAG_template_value_param:
suppress_add = 1;
if (is_ref_attr (attr))
{
- unsigned int offset = dwarf2_get_ref_die_offset (attr);
+ sect_offset offset = dwarf2_get_ref_die_offset (attr);
this_type = get_die_type_at_offset (offset, cu->per_cu);
}
{
struct signatured_type *sig_type = DW_SIGNATURED_TYPE (attr);
struct dwarf2_cu *sig_cu;
- unsigned int offset;
+ sect_offset offset;
/* sig_type will be NULL if the signatured type is missing from
the debug info. */
if (sig_type == NULL)
error (_("Dwarf Error: Cannot find signatured DIE referenced from DIE "
"at 0x%x [in module %s]"),
- die->offset, objfile->name);
+ die->offset.sect_off, objfile->name);
gdb_assert (sig_type->per_cu.debug_types_section);
- offset = sig_type->per_cu.offset + sig_type->type_offset;
+ offset.sect_off = (sig_type->per_cu.offset.sect_off
+ + sig_type->type_offset.cu_off);
this_type = get_die_type_at_offset (offset, &sig_type->per_cu);
}
else
/* read_type_die already issued a complaint. */
message = xstrprintf (_("<unknown type in %s, CU 0x%x, DIE 0x%x>"),
objfile->name,
- cu->header.offset,
- die->offset);
+ cu->header.offset.sect_off,
+ die->offset.sect_off);
saved = obstack_copy0 (&objfile->objfile_obstack,
message, strlen (message));
xfree (message);
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;
return "DW_OP_GNU_push_tls_address";
case DW_OP_GNU_uninit:
return "DW_OP_GNU_uninit";
+ case DW_OP_GNU_encoded_addr:
+ return "DW_OP_GNU_encoded_addr";
case DW_OP_GNU_implicit_pointer:
return "DW_OP_GNU_implicit_pointer";
case DW_OP_GNU_entry_value:
return "DW_OP_GNU_convert";
case DW_OP_GNU_reinterpret:
return "DW_OP_GNU_reinterpret";
+ case DW_OP_GNU_parameter_ref:
+ return "DW_OP_GNU_parameter_ref";
default:
return NULL;
}
print_spaces (indent, f);
fprintf_unfiltered (f, "Die: %s (abbrev %d, offset 0x%x)\n",
- dwarf_tag_name (die->tag), die->abbrev, die->offset);
+ dwarf_tag_name (die->tag), die->abbrev, die->offset.sect_off);
if (die->parent != NULL)
{
print_spaces (indent, f);
fprintf_unfiltered (f, " parent at offset: 0x%x\n",
- die->parent->offset);
+ die->parent->offset.sect_off);
}
print_spaces (indent, f);
case DW_FORM_ref_sig8:
if (DW_SIGNATURED_TYPE (&die->attrs[i]) != NULL)
fprintf_unfiltered (f, "signatured type, offset: 0x%x",
- DW_SIGNATURED_TYPE (&die->attrs[i])->per_cu.offset);
+ DW_SIGNATURED_TYPE (&die->attrs[i])->per_cu.offset.sect_off);
else
fprintf_unfiltered (f, "signatured type, offset: unknown");
break;
{
void **slot;
- slot = htab_find_slot_with_hash (cu->die_hash, die, die->offset, INSERT);
+ slot = htab_find_slot_with_hash (cu->die_hash, die, die->offset.sect_off,
+ INSERT);
*slot = die;
}
+/* DW_ADDR is always stored already as sect_offset; despite for the forms
+ besides DW_FORM_ref_addr it is stored as cu_offset in the DWARF file. */
+
static int
is_ref_attr (struct attribute *attr)
{
}
}
-static unsigned int
+/* Return DIE offset of ATTR. Return 0 with complaint if ATTR is not of the
+ required kind. */
+
+static sect_offset
dwarf2_get_ref_die_offset (struct attribute *attr)
{
+ sect_offset retval = { DW_ADDR (attr) };
+
if (is_ref_attr (attr))
- return DW_ADDR (attr);
+ return retval;
+ retval.sect_off = 0;
complaint (&symfile_complaints,
_("unsupported die ref attribute form: '%s'"),
dwarf_form_name (attr->form));
- return 0;
+ return retval;
}
/* Return the constant value held by ATTR. Return DEFAULT_VALUE if
Returns NULL if OFFSET is invalid. */
static struct die_info *
-follow_die_offset (unsigned int offset, struct dwarf2_cu **ref_cu)
+follow_die_offset (sect_offset offset, struct dwarf2_cu **ref_cu)
{
struct die_info temp_die;
struct dwarf2_cu *target_cu, *cu = *ref_cu;
*ref_cu = target_cu;
temp_die.offset = offset;
- return htab_find_with_hash (target_cu->die_hash, &temp_die, offset);
+ return htab_find_with_hash (target_cu->die_hash, &temp_die, offset.sect_off);
}
/* Follow reference attribute ATTR of SRC_DIE.
follow_die_ref (struct die_info *src_die, struct attribute *attr,
struct dwarf2_cu **ref_cu)
{
- unsigned int offset = dwarf2_get_ref_die_offset (attr);
+ sect_offset offset = dwarf2_get_ref_die_offset (attr);
struct dwarf2_cu *cu = *ref_cu;
struct die_info *die;
if (!die)
error (_("Dwarf Error: Cannot find DIE at 0x%x referenced from DIE "
"at 0x%x [in module %s]"),
- offset, src_die->offset, cu->objfile->name);
+ offset.sect_off, src_die->offset.sect_off, cu->objfile->name);
return die;
}
dwarf2_locexpr_baton->data has lifetime of PER_CU->OBJFILE. */
struct dwarf2_locexpr_baton
-dwarf2_fetch_die_location_block (unsigned int offset,
+dwarf2_fetch_die_location_block (cu_offset offset_in_cu,
struct dwarf2_per_cu_data *per_cu,
CORE_ADDR (*get_frame_pc) (void *baton),
void *baton)
{
+ sect_offset offset = { per_cu->offset.sect_off + offset_in_cu.cu_off };
struct dwarf2_cu *cu;
struct die_info *die;
struct attribute *attr;
die = follow_die_offset (offset, &cu);
if (!die)
error (_("Dwarf Error: Cannot find DIE at 0x%x referenced in module %s"),
- offset, per_cu->objfile->name);
+ offset.sect_off, per_cu->objfile->name);
attr = dwarf2_attr (die, DW_AT_location, cu);
if (!attr)
if (!attr_form_is_block (attr))
error (_("Dwarf Error: DIE at 0x%x referenced in module %s "
"is neither DW_FORM_block* nor DW_FORM_exprloc"),
- offset, per_cu->objfile->name);
+ offset.sect_off, per_cu->objfile->name);
retval.data = DW_BLOCK (attr)->data;
retval.size = DW_BLOCK (attr)->size;
PER_CU. */
struct type *
-dwarf2_get_die_type (unsigned int die_offset,
+dwarf2_get_die_type (cu_offset die_offset,
struct dwarf2_per_cu_data *per_cu)
{
+ sect_offset die_offset_sect;
+
dw2_setup (per_cu->objfile);
- return get_die_type_at_offset (die_offset, per_cu);
+
+ die_offset_sect.sect_off = per_cu->offset.sect_off + die_offset.cu_off;
+ return get_die_type_at_offset (die_offset_sect, per_cu);
}
/* Follow the signature attribute ATTR in SRC_DIE.
if (sig_type == NULL)
error (_("Dwarf Error: Cannot find signatured DIE referenced from DIE "
"at 0x%x [in module %s]"),
- src_die->offset, objfile->name);
+ src_die->offset.sect_off, objfile->name);
/* If necessary, add it to the queue and load its DIEs. */
gdb_assert (sig_type->per_cu.cu != NULL);
sig_cu = sig_type->per_cu.cu;
- temp_die.offset = sig_cu->header.offset + sig_type->type_offset;
- die = htab_find_with_hash (sig_cu->die_hash, &temp_die, temp_die.offset);
+ temp_die.offset.sect_off = (sig_type->per_cu.offset.sect_off
+ + sig_type->type_offset.cu_off);
+ die = htab_find_with_hash (sig_cu->die_hash, &temp_die,
+ temp_die.offset.sect_off);
if (die)
{
*ref_cu = sig_cu;
error (_("Dwarf Error: Cannot find signatured DIE at 0x%x referenced "
"from DIE at 0x%x [in module %s]"),
- sig_type->type_offset, src_die->offset, objfile->name);
+ temp_die.offset.sect_off, src_die->offset.sect_off, objfile->name);
}
/* Given an offset of a signatured type, return its signatured_type. */
static struct signatured_type *
lookup_signatured_type_at_offset (struct objfile *objfile,
struct dwarf2_section_info *section,
- unsigned int offset)
+ sect_offset offset)
{
- gdb_byte *info_ptr = section->buffer + offset;
+ gdb_byte *info_ptr = section->buffer + offset.sect_off;
unsigned int length, initial_length_size;
unsigned int sig_offset;
- struct signatured_type find_entry, *type_sig;
+ struct signatured_type find_entry, *sig_type;
length = read_initial_length (objfile->obfd, info_ptr, &initial_length_size);
sig_offset = (initial_length_size
+ (initial_length_size == 4 ? 4 : 8) /*debug_abbrev_offset*/
+ 1 /*address_size*/);
find_entry.signature = bfd_get_64 (objfile->obfd, info_ptr + sig_offset);
- type_sig = htab_find (dwarf2_per_objfile->signatured_types, &find_entry);
+ sig_type = htab_find (dwarf2_per_objfile->signatured_types, &find_entry);
/* This is only used to lookup previously recorded types.
If we didn't find it, it's our bug. */
- gdb_assert (type_sig != NULL);
- gdb_assert (offset == type_sig->per_cu.offset);
+ gdb_assert (sig_type != NULL);
+ gdb_assert (offset.sect_off == sig_type->per_cu.offset.sect_off);
- return type_sig;
+ return sig_type;
}
/* Load the DIEs associated with type unit PER_CU into memory. */
{
struct objfile *objfile = per_cu->objfile;
struct dwarf2_section_info *sect = per_cu->debug_types_section;
- unsigned int offset = per_cu->offset;
- struct signatured_type *type_sig;
+ sect_offset offset = per_cu->offset;
+ struct signatured_type *sig_type;
dwarf2_read_section (objfile, sect);
the signature to assert we found the right one.
Ok, but it's a lot of work. We should simplify things so any needed
assert doesn't require all this clumsiness. */
- type_sig = lookup_signatured_type_at_offset (objfile, sect, offset);
+ sig_type = lookup_signatured_type_at_offset (objfile, sect, offset);
- gdb_assert (type_sig->per_cu.cu == NULL);
+ gdb_assert (sig_type->per_cu.cu == NULL);
- read_signatured_type (type_sig);
+ read_signatured_type (sig_type);
- gdb_assert (type_sig->per_cu.cu != NULL);
+ gdb_assert (sig_type->per_cu.cu != NULL);
}
/* Read in a signatured type and build its CU and DIEs. */
static void
-read_signatured_type (struct signatured_type *type_sig)
+read_signatured_type (struct signatured_type *sig_type)
{
- struct objfile *objfile = type_sig->per_cu.objfile;
+ struct objfile *objfile = sig_type->per_cu.objfile;
gdb_byte *types_ptr;
struct die_reader_specs reader_specs;
struct dwarf2_cu *cu;
ULONGEST signature;
struct cleanup *back_to, *free_cu_cleanup;
- struct dwarf2_section_info *section = type_sig->per_cu.debug_types_section;
+ struct dwarf2_section_info *section = sig_type->per_cu.debug_types_section;
dwarf2_read_section (objfile, section);
- types_ptr = section->buffer + type_sig->per_cu.offset;
+ types_ptr = section->buffer + sig_type->per_cu.offset.sect_off;
- gdb_assert (type_sig->per_cu.cu == NULL);
+ gdb_assert (sig_type->per_cu.cu == NULL);
cu = xmalloc (sizeof (*cu));
- init_one_comp_unit (cu, &type_sig->per_cu);
+ init_one_comp_unit (cu, &sig_type->per_cu);
/* 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);
- gdb_assert (signature == type_sig->signature);
+ types_ptr = read_and_check_type_unit_head (&cu->header, section, types_ptr,
+ &signature, NULL);
+ gdb_assert (signature == sig_type->signature);
cu->die_hash
= htab_create_alloc_ex (cu->header.length / 12,
clean it up when finished with it. */
discard_cleanups (free_cu_cleanup);
- type_sig->per_cu.cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
- dwarf2_per_objfile->read_in_chain = &type_sig->per_cu;
+ /* Link this TU into read_in_chain. */
+ sig_type->per_cu.cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
+ dwarf2_per_objfile->read_in_chain = &sig_type->per_cu;
}
/* Decode simple location descriptions.
}
/* 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*
objfile = per_cu->objfile;
per_objfile = objfile_data (objfile, dwarf2_objfile_data_key);
- info_ptr = per_objfile->info.buffer + per_cu->offset;
+ info_ptr = per_objfile->info.buffer + per_cu->offset.sect_off;
memset (cu_headerp, 0, sizeof (*cu_headerp));
read_comp_unit_head (cu_headerp, info_ptr, objfile->obfd);
the DIE at OFFSET. Raises an error on failure. */
static struct dwarf2_per_cu_data *
-dwarf2_find_containing_comp_unit (unsigned int offset,
+dwarf2_find_containing_comp_unit (sect_offset offset,
struct objfile *objfile)
{
struct dwarf2_per_cu_data *this_cu;
{
int mid = low + (high - low) / 2;
- if (dwarf2_per_objfile->all_comp_units[mid]->offset >= offset)
+ if (dwarf2_per_objfile->all_comp_units[mid]->offset.sect_off
+ >= offset.sect_off)
high = mid;
else
low = mid + 1;
}
gdb_assert (low == high);
- if (dwarf2_per_objfile->all_comp_units[low]->offset > offset)
+ if (dwarf2_per_objfile->all_comp_units[low]->offset.sect_off
+ > offset.sect_off)
{
if (low == 0)
error (_("Dwarf Error: could not find partial DIE containing "
"offset 0x%lx [in module %s]"),
- (long) offset, bfd_get_filename (objfile->obfd));
+ (long) offset.sect_off, bfd_get_filename (objfile->obfd));
- gdb_assert (dwarf2_per_objfile->all_comp_units[low-1]->offset <= offset);
+ gdb_assert (dwarf2_per_objfile->all_comp_units[low-1]->offset.sect_off
+ <= offset.sect_off);
return dwarf2_per_objfile->all_comp_units[low-1];
}
else
{
this_cu = dwarf2_per_objfile->all_comp_units[low];
if (low == dwarf2_per_objfile->n_comp_units - 1
- && offset >= this_cu->offset + this_cu->length)
- error (_("invalid dwarf2 offset %u"), offset);
- gdb_assert (offset < this_cu->offset + this_cu->length);
+ && offset.sect_off >= this_cu->offset.sect_off + this_cu->length)
+ error (_("invalid dwarf2 offset %u"), offset.sect_off);
+ gdb_assert (offset.sect_off < this_cu->offset.sect_off + this_cu->length);
return this_cu;
}
}
struct dwarf2_offset_and_type
{
- unsigned int offset;
+ sect_offset offset;
struct type *type;
};
{
const struct dwarf2_offset_and_type *ofs = item;
- return ofs->offset;
+ return ofs->offset.sect_off;
}
/* Equality function for a dwarf2_offset_and_type. */
const struct dwarf2_offset_and_type *ofs_lhs = item_lhs;
const struct dwarf2_offset_and_type *ofs_rhs = item_rhs;
- return ofs_lhs->offset == ofs_rhs->offset;
+ return ofs_lhs->offset.sect_off == ofs_rhs->offset.sect_off;
}
/* Set the type associated with DIE to TYPE. Save it in CU's hash
ofs.offset = die->offset;
ofs.type = type;
slot = (struct dwarf2_offset_and_type **)
- htab_find_slot_with_hash (*type_hash_ptr, &ofs, ofs.offset, INSERT);
+ htab_find_slot_with_hash (*type_hash_ptr, &ofs, ofs.offset.sect_off,
+ INSERT);
if (*slot)
complaint (&symfile_complaints,
_("A problem internal to GDB: DIE 0x%x has type already set"),
- die->offset);
+ die->offset.sect_off);
*slot = obstack_alloc (&objfile->objfile_obstack, sizeof (**slot));
**slot = ofs;
return type;
table, or return NULL if the die does not have a saved type. */
static struct type *
-get_die_type_at_offset (unsigned int offset,
+get_die_type_at_offset (sect_offset offset,
struct dwarf2_per_cu_data *per_cu)
{
struct dwarf2_offset_and_type *slot, ofs;
return NULL;
ofs.offset = offset;
- slot = htab_find_with_hash (type_hash, &ofs, ofs.offset);
+ slot = htab_find_with_hash (type_hash, &ofs, ofs.offset.sect_off);
if (slot)
return slot->type;
else
{
const struct partial_die_info *part_die = item;
- return part_die->offset;
+ return part_die->offset.sect_off;
}
/* Trivial comparison function for partial_die_info structures: two DIEs
const struct partial_die_info *part_die_lhs = item_lhs;
const struct partial_die_info *part_die_rhs = item_rhs;
- return part_die_lhs->offset == part_die_rhs->offset;
+ return part_die_lhs->offset.sect_off == part_die_rhs->offset.sect_off;
}
static struct cmd_list_element *set_dwarf2_cmdlist;
psymtab->n_static_syms, info->cu_index,
1);
- store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->per_cu.offset);
+ store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE,
+ entry->per_cu.offset.sect_off);
obstack_grow (info->types_list, val, 8);
- store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->type_offset);
+ store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->type_offset.cu_off);
obstack_grow (info->types_list, val, 8);
store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->signature);
obstack_grow (info->types_list, val, 8);
gdb_assert (*slot == NULL);
*slot = map;
- store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, per_cu->offset);
+ store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE,
+ per_cu->offset.sect_off);
obstack_grow (&cu_list, val, 8);
store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, per_cu->length);
obstack_grow (&cu_list, val, 8);
total_len = size_of_contents;
/* The version number. */
- val = MAYBE_SWAP (5);
+ val = MAYBE_SWAP (6);
obstack_grow (&contents, &val, sizeof (val));
/* The offset of the CU list from the start of the file. */