/* When non-zero, dump DIEs after they are read in. */
static int dwarf2_die_debug = 0;
+/* When non-zero, cross-check physname against demangler. */
+static int check_physname = 0;
+
static int pagesize;
/* When set, the file that we're processing is known to have debugging
asection *asection;
gdb_byte *buffer;
bfd_size_type size;
- int was_mmapped;
+ /* Not NULL if the section was actually mmapped. */
+ void *map_addr;
+ /* Page aligned size of mmapped area. */
+ bfd_size_type map_len;
/* True if we have tried to read this section. */
int readin;
};
+typedef struct dwarf2_section_info dwarf2_section_info_def;
+DEF_VEC_O (dwarf2_section_info_def);
+
/* All offsets in the index are of this type. It must be
architecture-independent. */
typedef uint32_t offset_type;
a comment by the code that writes the index. */
struct mapped_index
{
+ /* Index data format version. */
+ int version;
+
/* The total length of the buffer. */
off_t total_size;
+
/* A pointer to the address table data. */
const gdb_byte *address_table;
+
/* Size of the address table data in bytes. */
offset_type address_table_size;
+
/* The symbol table, implemented as a hash table. */
const offset_type *symbol_table;
+
/* Size in slots, each slot is 2 offset_types. */
offset_type symbol_table_slots;
+
/* A pointer to the constant pool. */
const char *constant_pool;
};
struct dwarf2_section_info line;
struct dwarf2_section_info loc;
struct dwarf2_section_info macinfo;
+ struct dwarf2_section_info macro;
struct dwarf2_section_info str;
struct dwarf2_section_info ranges;
- struct dwarf2_section_info types;
struct dwarf2_section_info frame;
struct dwarf2_section_info eh_frame;
struct dwarf2_section_info gdb_index;
+ VEC (dwarf2_section_info_def) *types;
+
/* Back link. */
struct objfile *objfile;
static struct dwarf2_per_objfile *dwarf2_per_objfile;
-/* names of the debugging sections */
+/* Default names of the debugging sections. */
/* Note that if the debugging section has been compressed, it might
have a name like .zdebug_info. */
-#define INFO_SECTION "debug_info"
-#define ABBREV_SECTION "debug_abbrev"
-#define LINE_SECTION "debug_line"
-#define LOC_SECTION "debug_loc"
-#define MACINFO_SECTION "debug_macinfo"
-#define STR_SECTION "debug_str"
-#define RANGES_SECTION "debug_ranges"
-#define TYPES_SECTION "debug_types"
-#define FRAME_SECTION "debug_frame"
-#define EH_FRAME_SECTION "eh_frame"
-#define GDB_INDEX_SECTION "gdb_index"
+static const struct dwarf2_debug_sections dwarf2_elf_names = {
+ { ".debug_info", ".zdebug_info" },
+ { ".debug_abbrev", ".zdebug_abbrev" },
+ { ".debug_line", ".zdebug_line" },
+ { ".debug_loc", ".zdebug_loc" },
+ { ".debug_macinfo", ".zdebug_macinfo" },
+ { ".debug_macro", ".zdebug_macro" },
+ { ".debug_str", ".zdebug_str" },
+ { ".debug_ranges", ".zdebug_ranges" },
+ { ".debug_types", ".zdebug_types" },
+ { ".debug_frame", ".zdebug_frame" },
+ { ".eh_frame", NULL },
+ { ".gdb_index", ".zgdb_index" },
+ 23
+};
/* local data types */
after all type information has been read. */
VEC (delayed_method_info) *method_list;
+ /* To be copied to symtab->call_site_htab. */
+ htab_t call_site_htab;
+
/* Mark used when releasing cached dies. */
unsigned int mark : 1;
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;
};
/* Persistent data held for a compilation unit, even when not
hash table and don't find it. */
unsigned int load_all_dies : 1;
- /* Non-zero if this CU is from .debug_types.
- Otherwise it's from .debug_info. */
- unsigned int from_debug_types : 1;
+ /* Non-null if this CU is from .debug_types; in which case it points
+ to the section. Otherwise it's from .debug_info. */
+ struct dwarf2_section_info *debug_type_section;
/* Set to non-NULL iff this CU is currently loaded. When it gets freed out
of the CU cache it gets reset to NULL again. */
{
ULONGEST signature;
- /* Offset in .debug_types of the TU (type_unit) for this type. */
- unsigned int offset;
-
/* Offset in .debug_types of the type defined by this TU. */
unsigned int type_offset;
struct dwarf_block
{
unsigned int size;
+
+ /* Valid only if SIZE is not zero. */
gdb_byte *data;
};
}
static void
-dwarf2_macros_too_long_complaint (void)
+dwarf2_macros_too_long_complaint (struct dwarf2_section_info *section)
{
complaint (&symfile_complaints,
- _("macro info runs off end of `.debug_macinfo' section"));
+ _("macro info runs off end of `%s' section"),
+ section->asection->name);
}
static void
static void dwarf2_create_include_psymtab (char *, struct partial_symtab *,
struct objfile *);
+static void dwarf2_find_base_address (struct die_info *die,
+ struct dwarf2_cu *cu);
+
static void dwarf2_build_psymtabs_hard (struct objfile *);
static void scan_partial_symbols (struct partial_die_info *,
static void dwarf2_free_abbrev_table (void *);
+static unsigned int peek_abbrev_code (bfd *, gdb_byte *);
+
static struct abbrev_info *peek_die_abbrev (gdb_byte *, unsigned int *,
struct dwarf2_cu *);
static void read_lexical_block_scope (struct die_info *, struct dwarf2_cu *);
+static void read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu);
+
static int dwarf2_ranges_read (unsigned, CORE_ADDR *, CORE_ADDR *,
struct dwarf2_cu *, struct partial_symtab *);
struct attribute *,
struct dwarf2_cu **);
+static struct signatured_type *lookup_signatured_type_at_offset
+ (struct objfile *objfile,
+ struct dwarf2_section_info *section,
+ unsigned int offset);
+
static void read_signatured_type_at_offset (struct objfile *objfile,
+ struct dwarf2_section_info *sect,
unsigned int offset);
static void read_signatured_type (struct objfile *,
struct dwarf2_cu *);
static void dwarf_decode_macros (struct line_header *, unsigned int,
- char *, bfd *, struct dwarf2_cu *);
+ char *, bfd *, struct dwarf2_cu *,
+ struct dwarf2_section_info *,
+ int);
static int attr_form_is_block (struct attribute *);
gdb_byte *info_ptr,
gdb_byte *buffer,
unsigned int buffer_size,
- bfd *abfd);
+ bfd *abfd,
+ int is_debug_type_section);
static void init_cu_die_reader (struct die_reader_specs *reader,
struct dwarf2_cu *cu);
struct dwarf2_cu *cu);
/* Try to locate the sections we need for DWARF 2 debugging
- information and return true if we have enough to do something. */
+ information and return true if we have enough to do something.
+ NAMES points to the dwarf2 section names, or is NULL if the standard
+ ELF names are used. */
int
-dwarf2_has_info (struct objfile *objfile)
+dwarf2_has_info (struct objfile *objfile,
+ const struct dwarf2_debug_sections *names)
{
dwarf2_per_objfile = objfile_data (objfile, dwarf2_objfile_data_key);
if (!dwarf2_per_objfile)
set_objfile_data (objfile, dwarf2_objfile_data_key, data);
dwarf2_per_objfile = data;
- bfd_map_over_sections (objfile->obfd, dwarf2_locate_sections, NULL);
+ bfd_map_over_sections (objfile->obfd, dwarf2_locate_sections,
+ (void *) names);
dwarf2_per_objfile->objfile = objfile;
}
return (dwarf2_per_objfile->info.asection != NULL
&& dwarf2_per_objfile->abbrev.asection != NULL);
}
-/* When loading sections, we can either look for ".<name>", or for
- * ".z<name>", which indicates a compressed section. */
+/* When loading sections, we look either for uncompressed section or for
+ compressed section names. */
static int
-section_is_p (const char *section_name, const char *name)
+section_is_p (const char *section_name,
+ const struct dwarf2_section_names *names)
{
- return (section_name[0] == '.'
- && (strcmp (section_name + 1, name) == 0
- || (section_name[1] == 'z'
- && strcmp (section_name + 2, name) == 0)));
+ if (names->normal != NULL
+ && strcmp (section_name, names->normal) == 0)
+ return 1;
+ if (names->compressed != NULL
+ && strcmp (section_name, names->compressed) == 0)
+ return 1;
+ return 0;
}
/* This function is mapped across the sections and remembers the
in. */
static void
-dwarf2_locate_sections (bfd *abfd, asection *sectp, void *ignore_ptr)
+dwarf2_locate_sections (bfd *abfd, asection *sectp, void *vnames)
{
- if (section_is_p (sectp->name, INFO_SECTION))
+ const struct dwarf2_debug_sections *names;
+
+ if (vnames == NULL)
+ names = &dwarf2_elf_names;
+ else
+ names = (const struct dwarf2_debug_sections *) vnames;
+
+ if (section_is_p (sectp->name, &names->info))
{
dwarf2_per_objfile->info.asection = sectp;
dwarf2_per_objfile->info.size = bfd_get_section_size (sectp);
}
- else if (section_is_p (sectp->name, ABBREV_SECTION))
+ else if (section_is_p (sectp->name, &names->abbrev))
{
dwarf2_per_objfile->abbrev.asection = sectp;
dwarf2_per_objfile->abbrev.size = bfd_get_section_size (sectp);
}
- else if (section_is_p (sectp->name, LINE_SECTION))
+ else if (section_is_p (sectp->name, &names->line))
{
dwarf2_per_objfile->line.asection = sectp;
dwarf2_per_objfile->line.size = bfd_get_section_size (sectp);
}
- else if (section_is_p (sectp->name, LOC_SECTION))
+ else if (section_is_p (sectp->name, &names->loc))
{
dwarf2_per_objfile->loc.asection = sectp;
dwarf2_per_objfile->loc.size = bfd_get_section_size (sectp);
}
- else if (section_is_p (sectp->name, MACINFO_SECTION))
+ else if (section_is_p (sectp->name, &names->macinfo))
{
dwarf2_per_objfile->macinfo.asection = sectp;
dwarf2_per_objfile->macinfo.size = bfd_get_section_size (sectp);
}
- else if (section_is_p (sectp->name, STR_SECTION))
+ else if (section_is_p (sectp->name, &names->macro))
+ {
+ dwarf2_per_objfile->macro.asection = sectp;
+ dwarf2_per_objfile->macro.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->str))
{
dwarf2_per_objfile->str.asection = sectp;
dwarf2_per_objfile->str.size = bfd_get_section_size (sectp);
}
- else if (section_is_p (sectp->name, FRAME_SECTION))
+ else if (section_is_p (sectp->name, &names->frame))
{
dwarf2_per_objfile->frame.asection = sectp;
dwarf2_per_objfile->frame.size = bfd_get_section_size (sectp);
}
- else if (section_is_p (sectp->name, EH_FRAME_SECTION))
+ else if (section_is_p (sectp->name, &names->eh_frame))
{
flagword aflag = bfd_get_section_flags (ignore_abfd, sectp);
dwarf2_per_objfile->eh_frame.size = bfd_get_section_size (sectp);
}
}
- else if (section_is_p (sectp->name, RANGES_SECTION))
+ else if (section_is_p (sectp->name, &names->ranges))
{
dwarf2_per_objfile->ranges.asection = sectp;
dwarf2_per_objfile->ranges.size = bfd_get_section_size (sectp);
}
- else if (section_is_p (sectp->name, TYPES_SECTION))
+ else if (section_is_p (sectp->name, &names->types))
{
- dwarf2_per_objfile->types.asection = sectp;
- dwarf2_per_objfile->types.size = bfd_get_section_size (sectp);
+ struct dwarf2_section_info type_section;
+
+ memset (&type_section, 0, sizeof (type_section));
+ type_section.asection = sectp;
+ type_section.size = bfd_get_section_size (sectp);
+
+ VEC_safe_push (dwarf2_section_info_def, dwarf2_per_objfile->types,
+ &type_section);
}
- else if (section_is_p (sectp->name, GDB_INDEX_SECTION))
+ else if (section_is_p (sectp->name, &names->gdb_index))
{
dwarf2_per_objfile->gdb_index.asection = sectp;
dwarf2_per_objfile->gdb_index.size = bfd_get_section_size (sectp);
if (info->readin)
return;
info->buffer = NULL;
- info->was_mmapped = 0;
+ info->map_addr = NULL;
info->readin = 1;
if (dwarf2_section_empty_p (info))
if (info->size > 4 * pagesize && (sectp->flags & SEC_RELOC) == 0)
{
- off_t pg_offset = sectp->filepos & ~(pagesize - 1);
- size_t map_length = info->size + sectp->filepos - pg_offset;
- caddr_t retbuf = bfd_mmap (abfd, 0, map_length, PROT_READ,
- MAP_PRIVATE, pg_offset);
+ info->buffer = bfd_mmap (abfd, 0, info->size, PROT_READ,
+ MAP_PRIVATE, sectp->filepos,
+ &info->map_addr, &info->map_len);
- if (retbuf != MAP_FAILED)
+ if ((caddr_t)info->buffer != MAP_FAILED)
{
- info->was_mmapped = 1;
- info->buffer = retbuf + (sectp->filepos & (pagesize - 1)) ;
#if HAVE_POSIX_MADVISE
- posix_madvise (retbuf, map_length, POSIX_MADV_WILLNEED);
+ posix_madvise (info->map_addr, info->map_len, POSIX_MADV_WILLNEED);
#endif
return;
}
SECTION_NAME. */
void
-dwarf2_get_section_info (struct objfile *objfile, const char *section_name,
+dwarf2_get_section_info (struct objfile *objfile,
+ enum dwarf2_section_enum sect,
asection **sectp, gdb_byte **bufp,
bfd_size_type *sizep)
{
*sizep = 0;
return;
}
- if (section_is_p (section_name, EH_FRAME_SECTION))
- info = &data->eh_frame;
- else if (section_is_p (section_name, FRAME_SECTION))
- info = &data->frame;
- else
- gdb_assert_not_reached ("unexpected section");
+ switch (sect)
+ {
+ case DWARF2_DEBUG_FRAME:
+ info = &data->frame;
+ break;
+ case DWARF2_EH_FRAME:
+ info = &data->eh_frame;
+ break;
+ default:
+ gdb_assert_not_reached ("unexpected section");
+ }
dwarf2_read_section (objfile, info);
delete_file_name_entry, xcalloc, xfree);
}
+/* Read in PER_CU->CU. This function is unrelated to symtabs, symtab would
+ have to be created afterwards. You should call age_cached_comp_units after
+ processing PER_CU->CU. dw2_setup must have been already called. */
+
+static void
+load_cu (struct dwarf2_per_cu_data *per_cu)
+{
+ if (per_cu->debug_type_section)
+ read_signatured_type_at_offset (per_cu->objfile,
+ per_cu->debug_type_section,
+ per_cu->offset);
+ else
+ load_full_comp_unit (per_cu, per_cu->objfile);
+
+ dwarf2_find_base_address (per_cu->cu->dies, per_cu->cu);
+
+ gdb_assert (per_cu->cu != NULL);
+}
+
/* Read in the symbols for PER_CU. OBJFILE is the objfile from which
this CU came. */
queue_comp_unit (per_cu, objfile);
- if (per_cu->from_debug_types)
- read_signatured_type_at_offset (objfile, per_cu->offset);
- else
- load_full_comp_unit (per_cu, objfile);
+ load_cu (per_cu);
process_queue (objfile);
static int
create_signatured_type_table_from_index (struct objfile *objfile,
+ struct dwarf2_section_info *section,
const gdb_byte *bytes,
offset_type elements)
{
type_sig = OBSTACK_ZALLOC (&objfile->objfile_obstack,
struct signatured_type);
type_sig->signature = signature;
- type_sig->offset = offset;
type_sig->type_offset = type_offset;
- type_sig->per_cu.from_debug_types = 1;
+ type_sig->per_cu.debug_type_section = section;
type_sig->per_cu.offset = offset;
type_sig->per_cu.objfile = objfile;
type_sig->per_cu.v.quick
SYMBOL_HASH_NEXT, but we keep a separate copy to maintain control over the
implementation. This is necessary because the hash function is tied to the
format of the mapped index file. The hash values do not have to match with
- SYMBOL_HASH_NEXT. */
+ SYMBOL_HASH_NEXT.
+
+ Use INT_MAX for INDEX_VERSION if you generate the current index format. */
static hashval_t
-mapped_index_string_hash (const void *p)
+mapped_index_string_hash (int index_version, const void *p)
{
const unsigned char *str = (const unsigned char *) p;
hashval_t r = 0;
unsigned char c;
while ((c = *str++) != 0)
- r = r * 67 + c - 113;
+ {
+ if (index_version >= 5)
+ c = tolower (c);
+ r = r * 67 + c - 113;
+ }
return r;
}
struct cleanup *back_to = make_cleanup (null_cleanup, 0);
offset_type hash;
offset_type slot, step;
+ int (*cmp) (const char *, const char *);
if (current_language->la_language == language_cplus
|| current_language->la_language == language_java
}
}
- hash = mapped_index_string_hash (name);
+ /* Index version 4 did not support case insensitive searches. But the
+ indexes 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
+ ? 5 : index->version),
+ name);
+
slot = hash & (index->symbol_table_slots - 1);
step = ((hash * 17) & (index->symbol_table_slots - 1)) | 1;
+ cmp = (case_sensitivity == case_sensitive_on ? strcmp : strcasecmp);
for (;;)
{
}
str = index->constant_pool + MAYBE_SWAP (index->symbol_table[i]);
- if (!strcmp (name, str))
+ if (!cmp (name, str))
{
*vec_out = (offset_type *) (index->constant_pool
+ MAYBE_SWAP (index->symbol_table[i + 1]));
/* 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. */
+ indices. Index version 4 uses a different hash function than index
+ version 5 and later. */
if (version < 4)
return 0;
/* Indexes with higher version than the one supported by GDB may be no
longer backward compatible. */
- if (version > 4)
+ if (version > 5)
return 0;
map = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct mapped_index);
+ map->version = version;
map->total_size = dwarf2_per_objfile->gdb_index.size;
metadata = (offset_type *) (addr + sizeof (offset_type));
if (!create_cus_from_index (objfile, cu_list, cu_list_elements))
return 0;
- if (types_list_elements
- && !create_signatured_type_table_from_index (objfile, types_list,
- types_list_elements))
- return 0;
+ if (types_list_elements)
+ {
+ struct dwarf2_section_info *section;
+
+ /* We can only handle a single .debug_types when we have an
+ index. */
+ if (VEC_length (dwarf2_section_info_def, dwarf2_per_objfile->types) != 1)
+ return 0;
+
+ section = VEC_index (dwarf2_section_info_def,
+ dwarf2_per_objfile->types, 0);
+
+ if (!create_signatured_type_table_from_index (objfile, section,
+ types_list,
+ types_list_elements))
+ return 0;
+ }
create_addrmap_from_index (objfile, map);
struct cleanup *cleanups;
struct die_info *comp_unit_die;
struct dwarf2_section_info* sec;
- gdb_byte *beg_of_comp_unit, *info_ptr, *buffer;
+ gdb_byte *info_ptr, *buffer;
int has_children, i;
struct dwarf2_cu cu;
unsigned int bytes_read, buffer_size;
init_one_comp_unit (&cu, objfile);
cleanups = make_cleanup (free_stack_comp_unit, &cu);
- if (this_cu->from_debug_types)
- sec = &dwarf2_per_objfile->types;
+ if (this_cu->debug_type_section)
+ sec = this_cu->debug_type_section;
else
sec = &dwarf2_per_objfile->info;
dwarf2_read_section (objfile, sec);
buffer_size = sec->size;
buffer = sec->buffer;
info_ptr = buffer + this_cu->offset;
- beg_of_comp_unit = info_ptr;
info_ptr = partial_read_comp_unit_head (&cu.header, info_ptr,
buffer, buffer_size,
- abfd);
+ abfd,
+ this_cu->debug_type_section != NULL);
- /* Complete the cu_header. */
- cu.header.offset = beg_of_comp_unit - buffer;
- cu.header.first_die_offset = info_ptr - beg_of_comp_unit;
+ /* Skip dummy compilation units. */
+ if (info_ptr >= buffer + buffer_size
+ || peek_abbrev_code (abfd, info_ptr) == 0)
+ {
+ do_cleanups (cleanups);
+ return NULL;
+ }
this_cu->cu = &cu;
cu.per_cu = this_cu;
dwarf2_read_abbrevs (abfd, &cu);
make_cleanup (dwarf2_free_abbrev_table, &cu);
- if (this_cu->from_debug_types)
- info_ptr += 8 /*signature*/ + cu.header.offset_size;
init_cu_die_reader (&reader_specs, &cu);
read_full_die (&reader_specs, &comp_unit_die, info_ptr,
&has_children);
/* index_table is NULL if OBJF_READNOW. */
if (!dwarf2_per_objfile->index_table)
- return NULL;
+ {
+ struct symtab *s;
+
+ ALL_OBJFILE_SYMTABS (objfile, s)
+ if (s->primary)
+ {
+ struct blockvector *bv = BLOCKVECTOR (s);
+ const struct block *block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ struct symbol *sym = lookup_block_symbol (block, name, VAR_DOMAIN);
+
+ if (sym)
+ return sym->symtab->filename;
+ }
+ return NULL;
+ }
if (!find_slot_in_mapped_hash (dwarf2_per_objfile->index_table,
name, &vec))
return;
index = dwarf2_per_objfile->index_table;
- 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;
+ 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;
- per_cu->v.quick->mark = 0;
- if (per_cu->v.quick->symtab)
- continue;
+ per_cu->v.quick->mark = 0;
+ if (per_cu->v.quick->symtab)
+ continue;
- file_data = dw2_get_file_names (objfile, per_cu);
- if (file_data == NULL)
- continue;
+ file_data = dw2_get_file_names (objfile, per_cu);
+ if (file_data == NULL)
+ 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;
- }
- }
- }
+ 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;
+ }
+ }
+ }
for (iter = 0; iter < index->symbol_table_slots; ++iter)
{
struct dwarf2_per_cu_data *per_cu;
per_cu = dw2_get_cu (MAYBE_SWAP (vec[vec_idx + 1]));
- if (per_cu->v.quick->mark)
+ if (file_matcher == NULL || per_cu->v.quick->mark)
dw2_instantiate_symtab (objfile, per_cu);
}
}
}
static void
-dw2_map_symbol_names (struct objfile *objfile,
- void (*fun) (const char *, void *),
- void *data)
-{
- offset_type iter;
- struct mapped_index *index;
-
- dw2_setup (objfile);
-
- /* index_table is NULL if OBJF_READNOW. */
- if (!dwarf2_per_objfile->index_table)
- return;
- index = dwarf2_per_objfile->index_table;
-
- for (iter = 0; iter < index->symbol_table_slots; ++iter)
- {
- offset_type idx = 2 * iter;
- const char *name;
- offset_type *vec, vec_len, vec_idx;
-
- if (index->symbol_table[idx] == 0 && index->symbol_table[idx + 1] == 0)
- continue;
-
- name = (index->constant_pool + MAYBE_SWAP (index->symbol_table[idx]));
-
- (*fun) (name, data);
- }
-}
-
-static void
-dw2_map_symbol_filenames (struct objfile *objfile,
- void (*fun) (const char *, const char *, void *),
+dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun,
void *data)
{
int i;
dw2_map_matching_symbols,
dw2_expand_symtabs_matching,
dw2_find_pc_sect_symtab,
- dw2_map_symbol_names,
dw2_map_symbol_filenames
};
return info_ptr;
}
+/* Read in a CU header and perform some basic error checking. */
+
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)
+ bfd *abfd, int is_debug_type_section)
{
gdb_byte *beg_of_comp_unit = info_ptr;
+ header->offset = beg_of_comp_unit - buffer;
+
info_ptr = read_comp_unit_head (header, info_ptr, abfd);
+ /* If we're reading a type unit, skip over the signature and
+ type_offset fields. */
+ if (is_debug_type_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,
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)
{
gdb_byte *initial_types_ptr = types_ptr;
- dwarf2_read_section (dwarf2_per_objfile->objfile,
- &dwarf2_per_objfile->types);
- cu_header->offset = types_ptr - dwarf2_per_objfile->types.buffer;
+ dwarf2_read_section (dwarf2_per_objfile->objfile, section);
+ cu_header->offset = types_ptr - section->buffer;
types_ptr = read_comp_unit_head (cu_header, types_ptr, abfd);
static int
create_debug_types_hash_table (struct objfile *objfile)
{
- gdb_byte *info_ptr;
- htab_t types_htab;
+ htab_t types_htab = NULL;
struct dwarf2_per_cu_data **iter;
+ int ix;
+ struct dwarf2_section_info *section;
- dwarf2_read_section (objfile, &dwarf2_per_objfile->types);
- info_ptr = dwarf2_per_objfile->types.buffer;
-
- if (info_ptr == NULL)
+ if (VEC_empty (dwarf2_section_info_def, dwarf2_per_objfile->types))
{
dwarf2_per_objfile->signatured_types = NULL;
return 0;
}
- types_htab = allocate_signatured_type_table (objfile);
+ for (ix = 0;
+ VEC_iterate (dwarf2_section_info_def, dwarf2_per_objfile->types,
+ ix, section);
+ ++ix)
+ {
+ gdb_byte *info_ptr, *end_ptr;
- if (dwarf2_die_debug)
- fprintf_unfiltered (gdb_stdlog, "Signatured types:\n");
+ dwarf2_read_section (objfile, section);
+ info_ptr = section->buffer;
- while (info_ptr < dwarf2_per_objfile->types.buffer
- + dwarf2_per_objfile->types.size)
- {
- 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;
+ if (info_ptr == NULL)
+ continue;
- offset = ptr - dwarf2_per_objfile->types.buffer;
+ if (types_htab == NULL)
+ types_htab = allocate_signatured_type_table (objfile);
- /* 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. */
+ if (dwarf2_die_debug)
+ fprintf_unfiltered (gdb_stdlog, "Signatured types:\n");
- /* Sanity check to ensure entire cu is present. */
- length = read_initial_length (objfile->obfd, ptr, &initial_length_size);
- if (ptr + length + initial_length_size
- > dwarf2_per_objfile->types.buffer + dwarf2_per_objfile->types.size)
+ end_ptr = info_ptr + section->size;
+ while (info_ptr < end_ptr)
{
- complaint (&symfile_complaints,
- _("debug type entry runs off end "
- "of `.debug_types' section, ignored"));
- break;
- }
+ 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;
- 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);
+ offset = ptr - section->buffer;
- type_sig = obstack_alloc (&objfile->objfile_obstack, sizeof (*type_sig));
- memset (type_sig, 0, sizeof (*type_sig));
- type_sig->signature = signature;
- type_sig->offset = offset;
- type_sig->type_offset = type_offset;
- type_sig->per_cu.objfile = objfile;
- type_sig->per_cu.from_debug_types = 1;
+ /* 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. */
- slot = htab_find_slot (types_htab, type_sig, INSERT);
- gdb_assert (slot != NULL);
- *slot = type_sig;
+ /* 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;
+ }
- if (dwarf2_die_debug)
- fprintf_unfiltered (gdb_stdlog, " offset 0x%x, signature 0x%s\n",
- offset, phex (signature, sizeof (signature)));
+ 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;
+
+ /* Skip dummy type units. */
+ if (ptr >= end_ptr || peek_abbrev_code (objfile->obfd, ptr) == 0)
+ {
+ info_ptr = info_ptr + initial_length_size + 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_type_section = section;
+ type_sig->per_cu.offset = offset;
+
+ slot = htab_find_slot (types_htab, type_sig, INSERT);
+ gdb_assert (slot != NULL);
+ if (*slot != NULL)
+ {
+ const struct signatured_type *dup_sig = *slot;
+
+ 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,
+ phex (signature, sizeof (signature)));
+ gdb_assert (signature == dup_sig->signature);
+ }
+ *slot = type_sig;
- info_ptr = info_ptr + initial_length_size + length;
+ if (dwarf2_die_debug)
+ fprintf_unfiltered (gdb_stdlog, " offset 0x%x, signature 0x%s\n",
+ offset, phex (signature, sizeof (signature)));
+
+ info_ptr = info_ptr + initial_length_size + length;
+ }
}
dwarf2_per_objfile->signatured_types = types_htab;
{
reader->abfd = cu->objfile->obfd;
reader->cu = cu;
- if (cu->per_cu->from_debug_types)
+ if (cu->per_cu->debug_type_section)
{
- gdb_assert (dwarf2_per_objfile->types.readin);
- reader->buffer = dwarf2_per_objfile->types.buffer;
+ gdb_assert (cu->per_cu->debug_type_section->readin);
+ reader->buffer = cu->per_cu->debug_type_section->buffer;
}
else
{
info_ptr = partial_read_comp_unit_head (&cu.header, info_ptr,
buffer, buffer_size,
- abfd);
+ abfd,
+ this_cu->debug_type_section != NULL);
- /* Complete the cu_header. */
- cu.header.offset = beg_of_comp_unit - buffer;
- cu.header.first_die_offset = info_ptr - beg_of_comp_unit;
+ /* Skip dummy compilation units. */
+ if (info_ptr >= buffer + buffer_size
+ || peek_abbrev_code (abfd, info_ptr) == 0)
+ {
+ info_ptr = (beg_of_comp_unit + cu.header.length
+ + cu.header.initial_length_size);
+ do_cleanups (back_to_inner);
+ return info_ptr;
+ }
cu.list_in_scope = &file_symbols;
make_cleanup (dwarf2_free_abbrev_table, &cu);
/* Read the compilation unit die. */
- if (this_cu->from_debug_types)
- info_ptr += 8 /*signature*/ + cu.header.offset_size;
init_cu_die_reader (&reader_specs, &cu);
info_ptr = read_full_die (&reader_specs, &comp_unit_die, info_ptr,
&has_children);
- if (this_cu->from_debug_types)
+ if (this_cu->debug_type_section)
{
- /* offset,length haven't been set yet for type units. */
- this_cu->offset = cu.header.offset;
+ /* LENGTH has not been set yet for type units. */
+ gdb_assert (this_cu->offset == cu.header.offset);
this_cu->length = cu.header.length + cu.header.initial_length_size;
}
else if (comp_unit_die->tag == DW_TAG_partial_unit)
info_ptr = (beg_of_comp_unit + cu.header.length
+ cu.header.initial_length_size);
- if (this_cu->from_debug_types)
+ if (this_cu->debug_type_section)
{
/* It's not clear we want to do anything with stmt lists here.
Waiting to see what gcc ultimately does. */
this_cu = &entry->per_cu;
- gdb_assert (dwarf2_per_objfile->types.readin);
+ gdb_assert (this_cu->debug_type_section->readin);
process_psymtab_comp_unit (objfile, this_cu,
- dwarf2_per_objfile->types.buffer,
- dwarf2_per_objfile->types.buffer + entry->offset,
- dwarf2_per_objfile->types.size);
+ this_cu->debug_type_section->buffer,
+ (this_cu->debug_type_section->buffer
+ + this_cu->offset),
+ this_cu->debug_type_section->size);
return 1;
}
struct objfile *objfile)
{
bfd *abfd = objfile->obfd;
- gdb_byte *info_ptr, *beg_of_comp_unit;
+ gdb_byte *info_ptr;
struct die_info *comp_unit_die;
struct dwarf2_cu *cu;
struct cleanup *free_abbrevs_cleanup, *free_cu_cleanup = NULL;
struct die_reader_specs reader_specs;
int read_cu = 0;
- gdb_assert (! this_cu->from_debug_types);
+ gdb_assert (! this_cu->debug_type_section);
gdb_assert (dwarf2_per_objfile->info.readin);
info_ptr = dwarf2_per_objfile->info.buffer + this_cu->offset;
- beg_of_comp_unit = info_ptr;
if (this_cu->cu == NULL)
{
info_ptr = partial_read_comp_unit_head (&cu->header, info_ptr,
dwarf2_per_objfile->info.buffer,
dwarf2_per_objfile->info.size,
- abfd);
+ abfd, 0);
- /* Complete the cu_header. */
- cu->header.offset = this_cu->offset;
- cu->header.first_die_offset = info_ptr - beg_of_comp_unit;
+ /* Skip dummy compilation units. */
+ if (info_ptr >= (dwarf2_per_objfile->info.buffer
+ + dwarf2_per_objfile->info.size)
+ || peek_abbrev_code (abfd, info_ptr) == 0)
+ {
+ do_cleanups (free_cu_cleanup);
+ return;
+ }
/* Link this compilation unit into the compilation unit tree. */
this_cu->cu = cu;
return NULL;
}
- if (parent->tag == DW_TAG_namespace
+ if (pdi->tag == DW_TAG_enumerator)
+ /* Enumerators should not get the name of the enumeration as a prefix. */
+ parent->scope = grandparent_scope;
+ else if (parent->tag == DW_TAG_namespace
|| parent->tag == DW_TAG_module
|| parent->tag == DW_TAG_structure_type
|| parent->tag == DW_TAG_class_type
grandparent_scope,
parent->name, 0, cu);
}
- else if (parent->tag == DW_TAG_enumerator)
- /* Enumerators should not get the name of the enumeration as a prefix. */
- parent->scope = grandparent_scope;
else
{
/* FIXME drow/2004-04-01: What should we be doing with
}
}
+/* Return the initial uleb128 in the die at INFO_PTR. */
+
+static unsigned int
+peek_abbrev_code (bfd *abfd, gdb_byte *info_ptr)
+{
+ unsigned int bytes_read;
+
+ return read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+}
+
/* Read the initial uleb128 in the die at INFO_PTR in compilation unit CU.
Return the corresponding abbrev, or NULL if the number is zero (indicating
an empty DIE). In either case *BYTES_READ will be set to the length of
struct attribute *attr;
int read_cu = 0;
- gdb_assert (! per_cu->from_debug_types);
+ gdb_assert (! per_cu->debug_type_section);
/* Set local variables from the partial symbol table info. */
offset = per_cu->offset;
/* Read in the comp_unit header. */
info_ptr = read_comp_unit_head (&cu->header, info_ptr, abfd);
+ /* Skip dummy compilation units. */
+ if (info_ptr >= (dwarf2_per_objfile->info.buffer
+ + dwarf2_per_objfile->info.size)
+ || peek_abbrev_code (abfd, info_ptr) == 0)
+ {
+ do_cleanups (free_cu_cleanup);
+ return;
+ }
+
/* Complete the cu_header. */
cu->header.offset = offset;
cu->header.first_die_offset = info_ptr - beg_of_comp_unit;
struct delayed_method_info *mi;
for (i = 0; VEC_iterate (delayed_method_info, cu->method_list, i, mi) ; ++i)
{
- char *physname;
+ const char *physname;
struct fn_fieldlist *fn_flp
= &TYPE_FN_FIELDLIST (mi->type, mi->fnfield_index);
- physname = (char *) dwarf2_physname ((char *) mi->name, mi->die, cu);
+ physname = dwarf2_physname ((char *) mi->name, mi->die, cu);
fn_flp->fn_fields[mi->index].physname = physname ? physname : "";
}
}
cu->list_in_scope = &file_symbols;
- dwarf2_find_base_address (cu->dies, cu);
-
/* Do line number decoding in read_file_scope () */
process_die (cu->dies, cu);
symtab = end_symtab (highpc + baseaddr, objfile, SECT_OFF_TEXT (objfile));
- /* Set symtab language to language from DW_AT_language.
- If the compilation is from a C file generated by language preprocessors,
- do not set the language if it was already deduced by start_subfile. */
- if (symtab != NULL
- && !(cu->language == language_c && symtab->language != language_c))
+ if (symtab != NULL)
{
- symtab->language = cu->language;
+ int gcc_4_minor = producer_is_gcc_ge_4 (cu->producer);
+
+ /* Set symtab language to language from DW_AT_language. If the
+ compilation is from a C file generated by language preprocessors, do
+ not set the language if it was already deduced by start_subfile. */
+ if (!(cu->language == language_c && symtab->language != language_c))
+ symtab->language = cu->language;
+
+ /* 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.
+
+ 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)
+ symtab->locations_valid = 1;
+
+ if (gcc_4_minor >= 5)
+ symtab->epilogue_unwind_valid = 1;
+
+ symtab->call_site_htab = cu->call_site_htab;
}
if (dwarf2_per_objfile->using_index)
case DW_TAG_catch_block:
read_lexical_block_scope (die, cu);
break;
+ case DW_TAG_GNU_call_site:
+ read_call_site_scope (die, cu);
+ break;
case DW_TAG_class_type:
case DW_TAG_interface_type:
case DW_TAG_structure_type:
static const char *
dwarf2_physname (char *name, struct die_info *die, struct dwarf2_cu *cu)
{
- return dwarf2_compute_name (name, die, cu, 1);
+ struct attribute *attr;
+ const char *retval, *mangled = NULL, *canon = NULL;
+ struct cleanup *back_to;
+ int need_copy = 1;
+
+ /* In this case dwarf2_compute_name is just a shortcut not building anything
+ on its own. */
+ if (!die_needs_namespace (die, cu))
+ return dwarf2_compute_name (name, die, cu, 1);
+
+ back_to = make_cleanup (null_cleanup, NULL);
+
+ attr = dwarf2_attr (die, DW_AT_linkage_name, cu);
+ if (!attr)
+ attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu);
+
+ /* DW_AT_linkage_name is missing in some cases - depend on what GDB
+ has computed. */
+ if (attr && DW_STRING (attr))
+ {
+ char *demangled;
+
+ mangled = DW_STRING (attr);
+
+ /* Use DMGL_RET_DROP for C++ template functions to suppress their return
+ type. It is easier for GDB users to search for such functions as
+ `name(params)' than `long name(params)'. In such case the minimal
+ symbol names do not match the full symbol names but for template
+ functions there is never a need to look up their definition from their
+ declaration so the only disadvantage remains the minimal symbol
+ variant `long name(params)' does not have the proper inferior type.
+ */
+
+ demangled = cplus_demangle (mangled, (DMGL_PARAMS | DMGL_ANSI
+ | (cu->language == language_java
+ ? DMGL_JAVA | DMGL_RET_POSTFIX
+ : DMGL_RET_DROP)));
+ if (demangled)
+ {
+ make_cleanup (xfree, demangled);
+ canon = demangled;
+ }
+ else
+ {
+ canon = mangled;
+ need_copy = 0;
+ }
+ }
+
+ if (canon == NULL || check_physname)
+ {
+ const char *physname = dwarf2_compute_name (name, die, cu, 1);
+
+ if (canon != NULL && strcmp (physname, canon) != 0)
+ {
+ /* It may not mean a bug in GDB. The compiler could also
+ compute DW_AT_linkage_name incorrectly. But in such case
+ GDB would need to be bug-to-bug compatible. */
+
+ 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, cu->objfile->name);
+
+ /* Prefer DW_AT_linkage_name (in the CANON form) - when it
+ is available here - over computed PHYSNAME. It is safer
+ against both buggy GDB and buggy compilers. */
+
+ retval = canon;
+ }
+ else
+ {
+ retval = physname;
+ need_copy = 0;
+ }
+ }
+ else
+ retval = canon;
+
+ if (need_copy)
+ retval = obsavestring (retval, strlen (retval),
+ &cu->objfile->objfile_obstack);
+
+ do_cleanups (back_to);
+ return retval;
}
/* Read the import statement specified by the given die and record it. */
read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
{
struct attribute *import_attr;
- struct die_info *imported_die;
+ struct die_info *imported_die, *child_die;
struct dwarf2_cu *imported_cu;
const char *imported_name;
const char *imported_name_prefix;
const char *import_alias;
const char *imported_declaration = NULL;
const char *import_prefix;
+ VEC (const_char_ptr) *excludes = NULL;
+ struct cleanup *cleanups;
char *temp;
else
canonical_name = imported_name;
- cp_add_using_directive (import_prefix,
- canonical_name,
- import_alias,
- imported_declaration,
- &cu->objfile->objfile_obstack);
-}
+ cleanups = make_cleanup (VEC_cleanup (const_char_ptr), &excludes);
-static void
-initialize_cu_func_list (struct dwarf2_cu *cu)
-{
- cu->first_fn = cu->last_fn = cu->cached_fn = NULL;
-}
+ if (die->tag == DW_TAG_imported_module && cu->language == language_fortran)
+ for (child_die = die->child; child_die && child_die->tag;
+ child_die = sibling_die (child_die))
+ {
+ /* DWARF-4: A Fortran use statement with a “rename list” may be
+ represented by an imported module entry with an import attribute
+ referring to the module and owned entries corresponding to those
+ entities that are renamed as part of being imported. */
-/* Cleanup function for read_file_scope. */
+ if (child_die->tag != DW_TAG_imported_declaration)
+ {
+ complaint (&symfile_complaints,
+ _("child DW_TAG_imported_declaration expected "
+ "- DIE at 0x%x [in module %s]"),
+ child_die->offset, cu->objfile->name);
+ continue;
+ }
-static void
-free_cu_line_header (void *arg)
-{
+ import_attr = dwarf2_attr (child_die, DW_AT_import, cu);
+ if (import_attr == NULL)
+ {
+ complaint (&symfile_complaints, _("Tag '%s' has no DW_AT_import"),
+ dwarf_tag_name (child_die->tag));
+ continue;
+ }
+
+ imported_cu = cu;
+ imported_die = follow_die_ref_or_sig (child_die, import_attr,
+ &imported_cu);
+ imported_name = dwarf2_name (imported_die, imported_cu);
+ if (imported_name == NULL)
+ {
+ complaint (&symfile_complaints,
+ _("child DW_TAG_imported_declaration has unknown "
+ "imported name - DIE at 0x%x [in module %s]"),
+ child_die->offset, cu->objfile->name);
+ continue;
+ }
+
+ VEC_safe_push (const_char_ptr, excludes, imported_name);
+
+ process_die (child_die, cu);
+ }
+
+ cp_add_using_directive (import_prefix,
+ canonical_name,
+ import_alias,
+ imported_declaration,
+ excludes,
+ &cu->objfile->objfile_obstack);
+
+ do_cleanups (cleanups);
+}
+
+static void
+initialize_cu_func_list (struct dwarf2_cu *cu)
+{
+ cu->first_fn = cu->last_fn = cu->cached_fn = NULL;
+}
+
+/* Cleanup function for read_file_scope. */
+
+static void
+free_cu_line_header (void *arg)
+{
struct dwarf2_cu *cu = arg;
free_line_header (cu->line_header);
*name = "<unknown>";
}
+/* Handle DW_AT_stmt_list for a compilation unit. */
+
+static void
+handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
+ const char *comp_dir)
+{
+ 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)
+ {
+ unsigned int line_offset = DW_UNSND (attr);
+ struct line_header *line_header
+ = dwarf_decode_line_header (line_offset, abfd, cu);
+
+ if (line_header)
+ {
+ cu->line_header = line_header;
+ make_cleanup (free_cu_line_header, cu);
+ dwarf_decode_lines (line_header, comp_dir, abfd, cu, NULL);
+ }
+ }
+}
+
/* Process DW_TAG_compile_unit. */
static void
char *comp_dir = NULL;
struct die_info *child_die;
bfd *abfd = objfile->obfd;
- struct line_header *line_header = 0;
CORE_ADDR baseaddr;
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
initialize_cu_func_list (cu);
- /* 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)
- {
- unsigned int line_offset = DW_UNSND (attr);
- line_header = dwarf_decode_line_header (line_offset, abfd, cu);
- if (line_header)
- {
- cu->line_header = line_header;
- make_cleanup (free_cu_line_header, cu);
- dwarf_decode_lines (line_header, comp_dir, abfd, cu, NULL);
- }
- }
+ handle_DW_AT_stmt_list (die, cu, comp_dir);
/* Process all dies in compilation unit. */
if (die->child != NULL)
refers to information in the line number info statement program
header, so we can only read it if we've read the header
successfully. */
- attr = dwarf2_attr (die, DW_AT_macro_info, cu);
- if (attr && line_header)
+ attr = dwarf2_attr (die, DW_AT_GNU_macros, cu);
+ if (attr && cu->line_header)
+ {
+ if (dwarf2_attr (die, DW_AT_macro_info, cu))
+ complaint (&symfile_complaints,
+ _("CU refers to both DW_AT_GNU_macros and DW_AT_macro_info"));
+
+ dwarf_decode_macros (cu->line_header, DW_UNSND (attr),
+ comp_dir, abfd, cu,
+ &dwarf2_per_objfile->macro, 1);
+ }
+ else
{
- unsigned int macro_offset = DW_UNSND (attr);
+ attr = dwarf2_attr (die, DW_AT_macro_info, cu);
+ if (attr && cu->line_header)
+ {
+ unsigned int macro_offset = DW_UNSND (attr);
- dwarf_decode_macros (line_header, macro_offset,
- comp_dir, abfd, cu);
+ dwarf_decode_macros (cu->line_header, macro_offset,
+ comp_dir, abfd, cu,
+ &dwarf2_per_objfile->macinfo, 0);
+ }
}
do_cleanups (back_to);
}
record_debugformat ("DWARF 2");
record_producer (cu->producer);
+ handle_DW_AT_stmt_list (die, cu, comp_dir);
+
/* Process the dies in the type unit. */
if (die->child == NULL)
{
using_directives = new->using_directives;
}
+/* Read in DW_TAG_GNU_call_site and insert it to CU->call_site_htab. */
+
+static void
+read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct objfile *objfile = cu->objfile;
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ CORE_ADDR pc, baseaddr;
+ struct attribute *attr;
+ struct call_site *call_site, call_site_local;
+ void **slot;
+ int nparams;
+ struct die_info *child_die;
+
+ baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+
+ attr = dwarf2_attr (die, DW_AT_low_pc, cu);
+ if (!attr)
+ {
+ complaint (&symfile_complaints,
+ _("missing DW_AT_low_pc for DW_TAG_GNU_call_site "
+ "DIE 0x%x [in module %s]"),
+ die->offset, cu->objfile->name);
+ return;
+ }
+ pc = DW_ADDR (attr) + baseaddr;
+
+ if (cu->call_site_htab == NULL)
+ cu->call_site_htab = htab_create_alloc_ex (16, core_addr_hash, core_addr_eq,
+ NULL, &objfile->objfile_obstack,
+ hashtab_obstack_allocate, NULL);
+ call_site_local.pc = pc;
+ slot = htab_find_slot (cu->call_site_htab, &call_site_local, INSERT);
+ if (*slot != NULL)
+ {
+ complaint (&symfile_complaints,
+ _("Duplicate PC %s for DW_TAG_GNU_call_site "
+ "DIE 0x%x [in module %s]"),
+ paddress (gdbarch, pc), die->offset, cu->objfile->name);
+ return;
+ }
+
+ /* Count parameters at the caller. */
+
+ nparams = 0;
+ for (child_die = die->child; child_die && child_die->tag;
+ child_die = sibling_die (child_die))
+ {
+ if (child_die->tag != DW_TAG_GNU_call_site_parameter)
+ {
+ 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, cu->objfile->name);
+ continue;
+ }
+
+ nparams++;
+ }
+
+ call_site = obstack_alloc (&objfile->objfile_obstack,
+ (sizeof (*call_site)
+ + (sizeof (*call_site->parameter)
+ * (nparams - 1))));
+ *slot = call_site;
+ memset (call_site, 0, sizeof (*call_site) - sizeof (*call_site->parameter));
+ call_site->pc = pc;
+
+ if (dwarf2_flag_true_p (die, DW_AT_GNU_tail_call, cu))
+ {
+ struct die_info *func_die;
+
+ /* Skip also over DW_TAG_inlined_subroutine. */
+ for (func_die = die->parent;
+ func_die && func_die->tag != DW_TAG_subprogram
+ && func_die->tag != DW_TAG_subroutine_type;
+ func_die = func_die->parent);
+
+ /* DW_AT_GNU_all_call_sites is a superset
+ of DW_AT_GNU_all_tail_call_sites. */
+ if (func_die
+ && !dwarf2_flag_true_p (func_die, DW_AT_GNU_all_call_sites, cu)
+ && !dwarf2_flag_true_p (func_die, DW_AT_GNU_all_tail_call_sites, cu))
+ {
+ /* TYPE_TAIL_CALL_LIST is not interesting in functions where it is
+ not complete. But keep CALL_SITE for look ups via call_site_htab,
+ both the initial caller containing the real return address PC and
+ the final callee containing the current PC of a chain of tail
+ calls do not need to have the tail call list complete. But any
+ function candidate for a virtual tail call frame searched via
+ TYPE_TAIL_CALL_LIST must have the tail call list complete to be
+ determined unambiguously. */
+ }
+ else
+ {
+ struct type *func_type = NULL;
+
+ if (func_die)
+ func_type = get_die_type (func_die, cu);
+ if (func_type != NULL)
+ {
+ gdb_assert (TYPE_CODE (func_type) == TYPE_CODE_FUNC);
+
+ /* Enlist this call site to the function. */
+ call_site->tail_call_next = TYPE_TAIL_CALL_LIST (func_type);
+ TYPE_TAIL_CALL_LIST (func_type) = call_site;
+ }
+ else
+ complaint (&symfile_complaints,
+ _("Cannot find function owning DW_TAG_GNU_call_site "
+ "DIE 0x%x [in module %s]"),
+ die->offset, cu->objfile->name);
+ }
+ }
+
+ attr = dwarf2_attr (die, DW_AT_GNU_call_site_target, cu);
+ if (attr == NULL)
+ attr = dwarf2_attr (die, DW_AT_abstract_origin, cu);
+ SET_FIELD_DWARF_BLOCK (call_site->target, NULL);
+ if (!attr || (attr_form_is_block (attr) && DW_BLOCK (attr)->size == 0))
+ /* Keep NULL DWARF_BLOCK. */;
+ else if (attr_form_is_block (attr))
+ {
+ struct dwarf2_locexpr_baton *dlbaton;
+
+ dlbaton = obstack_alloc (&objfile->objfile_obstack, sizeof (*dlbaton));
+ dlbaton->data = DW_BLOCK (attr)->data;
+ dlbaton->size = DW_BLOCK (attr)->size;
+ dlbaton->per_cu = cu->per_cu;
+
+ SET_FIELD_DWARF_BLOCK (call_site->target, dlbaton);
+ }
+ else if (is_ref_attr (attr))
+ {
+ struct objfile *objfile = cu->objfile;
+ struct dwarf2_cu *target_cu = cu;
+ struct die_info *target_die;
+
+ target_die = follow_die_ref_or_sig (die, attr, &target_cu);
+ gdb_assert (target_cu->objfile == objfile);
+ if (die_is_declaration (target_die, target_cu))
+ {
+ const char *target_physname;
+
+ target_physname = dwarf2_physname (NULL, target_die, target_cu);
+ if (target_physname == NULL)
+ complaint (&symfile_complaints,
+ _("DW_AT_GNU_call_site_target target DIE has invalid "
+ "physname, for referencing DIE 0x%x [in module %s]"),
+ die->offset, cu->objfile->name);
+ else
+ SET_FIELD_PHYSNAME (call_site->target, (char *) target_physname);
+ }
+ else
+ {
+ CORE_ADDR lowpc;
+
+ /* DW_AT_entry_pc should be preferred. */
+ if (!dwarf2_get_pc_bounds (target_die, &lowpc, NULL, target_cu, NULL))
+ 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, cu->objfile->name);
+ else
+ SET_FIELD_PHYSADDR (call_site->target, lowpc + baseaddr);
+ }
+ }
+ else
+ 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, cu->objfile->name);
+
+ call_site->per_cu = cu->per_cu;
+
+ for (child_die = die->child;
+ child_die && child_die->tag;
+ child_die = sibling_die (child_die))
+ {
+ struct dwarf2_locexpr_baton *dlbaton;
+ struct call_site_parameter *parameter;
+
+ if (child_die->tag != DW_TAG_GNU_call_site_parameter)
+ {
+ /* Already printed the complaint above. */
+ continue;
+ }
+
+ gdb_assert (call_site->parameter_count < nparams);
+ parameter = &call_site->parameter[call_site->parameter_count];
+
+ /* DW_AT_location specifies the register number. Value of the data
+ assumed for the register is contained in DW_AT_GNU_call_site_value. */
+
+ attr = dwarf2_attr (child_die, DW_AT_location, cu);
+ if (!attr || !attr_form_is_block (attr))
+ {
+ 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, cu->objfile->name);
+ continue;
+ }
+ parameter->dwarf_reg = dwarf_block_to_dwarf_reg (DW_BLOCK (attr)->data,
+ &DW_BLOCK (attr)->data[DW_BLOCK (attr)->size]);
+ if (parameter->dwarf_reg == -1
+ && !dwarf_block_to_sp_offset (gdbarch, DW_BLOCK (attr)->data,
+ &DW_BLOCK (attr)->data[DW_BLOCK (attr)->size],
+ ¶meter->fb_offset))
+ {
+ complaint (&symfile_complaints,
+ _("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, cu->objfile->name);
+ continue;
+ }
+
+ attr = dwarf2_attr (child_die, DW_AT_GNU_call_site_value, cu);
+ if (!attr_form_is_block (attr))
+ {
+ 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, cu->objfile->name);
+ continue;
+ }
+ parameter->value = DW_BLOCK (attr)->data;
+ parameter->value_size = DW_BLOCK (attr)->size;
+
+ /* Parameters are not pre-cleared by memset above. */
+ parameter->data_value = NULL;
+ parameter->data_value_size = 0;
+ call_site->parameter_count++;
+
+ attr = dwarf2_attr (child_die, DW_AT_GNU_call_site_data_value, cu);
+ if (attr)
+ {
+ if (!attr_form_is_block (attr))
+ 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, cu->objfile->name);
+ else
+ {
+ parameter->data_value = DW_BLOCK (attr)->data;
+ parameter->data_value_size = DW_BLOCK (attr)->size;
+ }
+ }
+ }
+}
+
/* Get low and high pc attributes from DW_AT_ranges attribute value OFFSET.
Return 1 if the attributes are present and valid, otherwise, return 0.
If RANGES_PST is not NULL we should setup `objfile->psymtabs_addrmap'. */
return 0;
*lowpc = low;
- *highpc = high;
+ if (highpc)
+ *highpc = high;
return ret;
}
}
}
+/* Look for DW_AT_data_member_location. Set *OFFSET to the byte
+ offset. If the attribute was not found return 0, otherwise return
+ 1. If it was found but could not properly be handled, set *OFFSET
+ to 0. */
+
+static int
+handle_data_member_location (struct die_info *die, struct dwarf2_cu *cu,
+ LONGEST *offset)
+{
+ struct attribute *attr;
+
+ attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
+ if (attr != NULL)
+ {
+ *offset = 0;
+
+ /* Note that we do not check for a section offset first here.
+ This is because DW_AT_data_member_location is new in DWARF 4,
+ so if we see it, we can assume that a constant form is really
+ a constant and not a section offset. */
+ if (attr_form_is_constant (attr))
+ *offset = dwarf2_get_attr_constant_value (attr, 0);
+ else if (attr_form_is_section_offset (attr))
+ dwarf2_complex_location_expr_complaint ();
+ else if (attr_form_is_block (attr))
+ *offset = decode_locdesc (DW_BLOCK (attr), cu);
+ else
+ dwarf2_complex_location_expr_complaint ();
+
+ return 1;
+ }
+
+ return 0;
+}
+
/* Add an aggregate field to the field list. */
static void
if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
{
+ LONGEST offset;
+
/* Data member other than a C++ static data member. */
/* Get type of field. */
}
/* Get bit offset of field. */
- attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
- if (attr)
- {
- int byte_offset = 0;
-
- if (attr_form_is_section_offset (attr))
- dwarf2_complex_location_expr_complaint ();
- else if (attr_form_is_constant (attr))
- byte_offset = dwarf2_get_attr_constant_value (attr, 0);
- else if (attr_form_is_block (attr))
- byte_offset = decode_locdesc (DW_BLOCK (attr), cu);
- else
- dwarf2_complex_location_expr_complaint ();
-
- SET_FIELD_BITPOS (*fp, byte_offset * bits_per_byte);
- }
+ if (handle_data_member_location (die, cu, &offset))
+ SET_FIELD_BITPOS (*fp, offset * bits_per_byte);
attr = dwarf2_attr (die, DW_AT_bit_offset, cu);
if (attr)
{
(so through at least 3.2.1) incorrectly generate
DW_TAG_variable tags. */
- char *physname;
+ const char *physname;
/* Get name of field. */
fieldname = dwarf2_name (die, cu);
}
/* Get physical name. */
- physname = (char *) dwarf2_physname (fieldname, die, cu);
+ physname = dwarf2_physname (fieldname, die, cu);
/* The name is already allocated along with this objfile, so we don't
need to duplicate it for the type. */
}
else if (die->tag == DW_TAG_inheritance)
{
- /* C++ base class field. */
- attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
- if (attr)
- {
- int byte_offset = 0;
-
- if (attr_form_is_section_offset (attr))
- dwarf2_complex_location_expr_complaint ();
- else if (attr_form_is_constant (attr))
- byte_offset = dwarf2_get_attr_constant_value (attr, 0);
- else if (attr_form_is_block (attr))
- byte_offset = decode_locdesc (DW_BLOCK (attr), cu);
- else
- dwarf2_complex_location_expr_complaint ();
+ LONGEST offset;
- SET_FIELD_BITPOS (*fp, byte_offset * bits_per_byte);
- }
+ /* C++ base class field. */
+ if (handle_data_member_location (die, cu, &offset))
+ SET_FIELD_BITPOS (*fp, offset * bits_per_byte);
FIELD_BITSIZE (*fp) = 0;
FIELD_TYPE (*fp) = die_type (die, cu);
FIELD_NAME (*fp) = type_name_no_tag (fp->type);
}
else
{
- char *physname = (char *) dwarf2_physname (fieldname, die, cu);
+ const char *physname = dwarf2_physname (fieldname, die, cu);
fnp->physname = physname ? physname : "";
}
}
do_cleanups (back_to);
+
+ if (HAVE_CPLUS_STRUCT (type))
+ TYPE_CPLUS_REALLY_JAVA (type) = cu->language == language_java;
}
quirk_gcc_member_function_pointer (type, cu->objfile);
TYPE_UNSIGNED (this_type) = 1;
}
+ /* If we are reading an enum from a .debug_types unit, and the enum
+ is a declaration, and the enum is not the signatured type in the
+ unit, then we do not want to add a symbol for it. Adding a
+ symbol would in some cases obscure the true definition of the
+ enum, giving users an incomplete type when the definition is
+ actually available. Note that we do not want to do this for all
+ enums which are just declarations, because C++0x allows forward
+ enum declarations. */
+ if (cu->per_cu->debug_type_section
+ && die_is_declaration (die, cu))
+ {
+ struct signatured_type *type_sig;
+
+ type_sig
+ = lookup_signatured_type_at_offset (dwarf2_per_objfile->objfile,
+ cu->per_cu->debug_type_section,
+ cu->per_cu->offset);
+ if (type_sig->type_offset != die->offset)
+ return;
+ }
+
new_symbol (die, this_type, cu);
}
child_die = die->child;
while (child_die && child_die->tag)
{
+ LONGEST offset;
+
sym = new_symbol (child_die, NULL, cu);
- attr = dwarf2_attr (child_die, DW_AT_data_member_location, cu);
- if (sym != NULL && attr != NULL)
+ if (sym != NULL
+ && handle_data_member_location (child_die, cu, &offset))
{
- CORE_ADDR byte_offset = 0;
-
- if (attr_form_is_section_offset (attr))
- dwarf2_complex_location_expr_complaint ();
- else if (attr_form_is_constant (attr))
- byte_offset = dwarf2_get_attr_constant_value (attr, 0);
- else if (attr_form_is_block (attr))
- byte_offset = decode_locdesc (DW_BLOCK (attr), cu);
- else
- dwarf2_complex_location_expr_complaint ();
-
- SYMBOL_VALUE_ADDRESS (sym) = base + byte_offset;
+ SYMBOL_VALUE_ADDRESS (sym) = base + offset;
add_symbol_to_list (sym, &global_symbols);
}
child_die = sibling_die (child_die);
const char *previous_prefix = determine_prefix (die, cu);
cp_add_using_directive (previous_prefix, TYPE_NAME (type), NULL,
- NULL, &objfile->objfile_obstack);
+ NULL, NULL, &objfile->objfile_obstack);
}
}
*is_anonymous = (name == NULL);
if (*is_anonymous)
- name = "(anonymous namespace)";
+ name = CP_ANONYMOUS_NAMESPACE_STR;
return name;
}
break;
case DW_ATE_unsigned:
type_flags |= TYPE_FLAG_UNSIGNED;
+ if (cu->language == language_fortran
+ && name
+ && strncmp (name, "character(", sizeof ("character(") - 1) == 0)
+ code = TYPE_CODE_CHAR;
break;
case DW_ATE_signed_char:
if (cu->language == language_ada || cu->language == language_m2
- || cu->language == language_pascal)
+ || cu->language == language_pascal
+ || cu->language == language_fortran)
code = TYPE_CODE_CHAR;
break;
case DW_ATE_unsigned_char:
if (cu->language == language_ada || cu->language == language_m2
- || cu->language == language_pascal)
+ || cu->language == language_pascal
+ || cu->language == language_fortran)
code = TYPE_CODE_CHAR;
type_flags |= TYPE_FLAG_UNSIGNED;
break;
attr = dwarf2_attr (die, DW_AT_upper_bound, cu);
if (attr)
{
- if (attr->form == DW_FORM_block1 || is_ref_attr (attr))
+ if (attr_form_is_block (attr) || is_ref_attr (attr))
{
/* GCC encodes arrays with unspecified or dynamic length
with a DW_FORM_block1 attribute or a reference attribute.
/* Mark arrays with dynamic length at least as an array of unspecified
length. GDB could check the boundary but before it gets implemented at
least allow accessing the array elements. */
- if (attr && attr->form == DW_FORM_block1)
+ if (attr && attr_form_is_block (attr))
TYPE_HIGH_BOUND_UNDEFINED (range_type) = 1;
/* Ada expects an empty array on no boundary attributes. */
{
fprintf_unfiltered (gdb_stdlog,
"\nRead die from %s of %s:\n",
- reader->buffer == dwarf2_per_objfile->info.buffer
- ? ".debug_info"
- : reader->buffer == dwarf2_per_objfile->types.buffer
- ? ".debug_types"
- : "unknown section",
+ (reader->cu->per_cu->debug_type_section
+ ? ".debug_types"
+ : ".debug_info"),
reader->abfd->filename);
dump_die (result, dwarf2_die_debug);
}
if (parent_die == NULL
&& part_die->has_specification == 0
&& part_die->is_declaration == 0
- && (part_die->tag == DW_TAG_typedef
+ && ((part_die->tag == DW_TAG_typedef && !part_die->has_children)
|| part_die->tag == DW_TAG_base_type
|| part_die->tag == DW_TAG_subrange_type))
{
continue;
}
+ /* The exception for DW_TAG_typedef with has_children above is
+ a workaround of GCC PR debug/47510. In the case of this complaint
+ type_name_no_tag_or_error will error on such types later.
+
+ GDB skipped children of DW_TAG_typedef by the shortcut above and then
+ it could not find the child DIEs referenced later, this is checked
+ above. In correct DWARF DW_TAG_typedef should have no children. */
+
+ if (part_die->tag == DW_TAG_typedef && part_die->has_children)
+ complaint (&symfile_complaints,
+ _("DW_TAG_typedef has childen - GCC PR debug/47510 bug "
+ "- DIE at 0x%x [in module %s]"),
+ part_die->offset, cu->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
namespace elsewhere), then we can add the partial symbol now
struct dwarf2_per_cu_data *per_cu = NULL;
struct partial_die_info *pd = NULL;
- if (cu->per_cu->from_debug_types)
+ if (cu->per_cu->debug_type_section)
{
pd = find_partial_die_in_comp_unit (offset, cu);
if (pd != NULL)
/* Set default names for some unnamed DIEs. */
if (part_die->name == NULL && part_die->tag == DW_TAG_namespace)
- part_die->name = "(anonymous namespace)";
+ part_die->name = CP_ANONYMOUS_NAMESPACE_STR;
/* If there is no parent die to provide a namespace, and there are
children, see if we can determine the namespace from their linkage
NOTE: We need to do this even if cu->has_namespace_info != 0.
gcc-4.5 -gdwarf-4 can drop the enclosing namespace. */
if (cu->language == language_cplus
- && dwarf2_per_objfile->types.asection != NULL
+ && !VEC_empty (dwarf2_section_info_def, dwarf2_per_objfile->types)
&& part_die->die_parent == NULL
&& part_die->has_children
&& (part_die->tag == DW_TAG_class_type
/* GCC might emit a nameless struct or union that has a linkage
name. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47510. */
if (part_die->name == NULL
- && (part_die->tag == DW_TAG_structure_type
- || part_die->tag == DW_TAG_union_type
- || part_die->tag == DW_TAG_class_type)
+ && (part_die->tag == DW_TAG_class_type
+ || part_die->tag == DW_TAG_interface_type
+ || part_die->tag == DW_TAG_structure_type
+ || part_die->tag == DW_TAG_union_type)
&& part_die->linkage_name != NULL)
{
char *demangled;
demangled = cplus_demangle (part_die->linkage_name, DMGL_TYPES);
if (demangled)
{
- part_die->name = obsavestring (demangled, strlen (demangled),
+ const char *base;
+
+ /* Strip any leading namespaces/classes, keep only the base name.
+ DW_AT_name for named DIEs does not contain the prefixes. */
+ base = strrchr (demangled, ':');
+ if (base && base > demangled && base[-1] == ':')
+ base++;
+ else
+ base = demangled;
+
+ part_die->name = obsavestring (base, strlen (base),
&cu->objfile->objfile_obstack);
xfree (demangled);
}
}
static char *
-read_indirect_string (bfd *abfd, gdb_byte *buf,
- const struct comp_unit_head *cu_header,
- unsigned int *bytes_read_ptr)
+read_indirect_string_at_offset (bfd *abfd, LONGEST str_offset)
{
- LONGEST str_offset = read_offset (abfd, buf, cu_header, bytes_read_ptr);
-
dwarf2_read_section (dwarf2_per_objfile->objfile, &dwarf2_per_objfile->str);
if (dwarf2_per_objfile->str.buffer == NULL)
- {
- error (_("DW_FORM_strp used without .debug_str section [in module %s]"),
- bfd_get_filename (abfd));
- return NULL;
- }
+ error (_("DW_FORM_strp used without .debug_str section [in module %s]"),
+ bfd_get_filename (abfd));
if (str_offset >= dwarf2_per_objfile->str.size)
- {
- error (_("DW_FORM_strp pointing outside of "
- ".debug_str section [in module %s]"),
- bfd_get_filename (abfd));
- return NULL;
- }
+ error (_("DW_FORM_strp pointing outside of "
+ ".debug_str section [in module %s]"),
+ bfd_get_filename (abfd));
gdb_assert (HOST_CHAR_BIT == 8);
if (dwarf2_per_objfile->str.buffer[str_offset] == '\0')
return NULL;
return (char *) (dwarf2_per_objfile->str.buffer + str_offset);
}
+static char *
+read_indirect_string (bfd *abfd, gdb_byte *buf,
+ const struct comp_unit_head *cu_header,
+ unsigned int *bytes_read_ptr)
+{
+ LONGEST str_offset = read_offset (abfd, buf, cu_header, bytes_read_ptr);
+
+ return read_indirect_string_at_offset (abfd, str_offset);
+}
+
static unsigned long
read_unsigned_leb128 (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr)
{
dwarf2_symbol_mark_computed (attr, sym, cu);
SYMBOL_CLASS (sym) = LOC_COMPUTED;
+
+ if (SYMBOL_COMPUTED_OPS (sym) == &dwarf2_loclist_funcs)
+ cu->has_loclist = 1;
}
/* Given a pointer to a DWARF information entry, figure out if we need
{
dwarf2_const_value (attr, sym, cu);
}
- attr = dwarf2_attr (die, DW_AT_variable_parameter, cu);
- if (attr && DW_UNSND (attr))
- {
- struct type *ref_type;
-
- ref_type = lookup_reference_type (SYMBOL_TYPE (sym));
- SYMBOL_TYPE (sym) = ref_type;
- }
list_to_add = cu->list_in_scope;
break;
namespaces based on the demangled name. */
if (!processing_has_namespace_info
&& cu->language == language_cplus)
- cp_scan_for_anonymous_namespaces (sym);
+ cp_scan_for_anonymous_namespaces (sym, objfile);
}
return (sym);
}
"at 0x%x [in module %s]"),
die->offset, cu->objfile->name);
- gdb_assert (sig_type->per_cu.from_debug_types);
- offset = sig_type->offset + sig_type->type_offset;
+ gdb_assert (sig_type->per_cu.debug_type_section);
+ offset = sig_type->per_cu.offset + sig_type->type_offset;
this_type = get_die_type_at_offset (offset, &sig_type->per_cu);
}
else
return NULL;
}
+/* GCC might emit a nameless typedef that has a linkage name. Determine the
+ prefix part in such case. See
+ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47510. */
+
+static char *
+anonymous_struct_prefix (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct attribute *attr;
+ char *base;
+
+ if (die->tag != DW_TAG_class_type && die->tag != DW_TAG_interface_type
+ && die->tag != DW_TAG_structure_type && die->tag != DW_TAG_union_type)
+ return NULL;
+
+ attr = dwarf2_attr (die, DW_AT_name, cu);
+ if (attr != NULL && DW_STRING (attr) != NULL)
+ return NULL;
+
+ attr = dwarf2_attr (die, DW_AT_linkage_name, cu);
+ if (attr == NULL)
+ attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu);
+ if (attr == NULL || DW_STRING (attr) == NULL)
+ return NULL;
+
+ /* dwarf2_name had to be already called. */
+ gdb_assert (DW_STRING_IS_CANONICAL (attr));
+
+ /* Strip the base name, keep any leading namespaces/classes. */
+ base = strrchr (DW_STRING (attr), ':');
+ if (base == NULL || base == DW_STRING (attr) || base[-1] != ':')
+ return "";
+
+ return obsavestring (DW_STRING (attr), &base[-1] - DW_STRING (attr),
+ &cu->objfile->objfile_obstack);
+}
+
/* Return the name of the namespace/class that DIE is defined within,
or "" if we can't tell. The caller should not xfree the result.
struct die_info *parent, *spec_die;
struct dwarf2_cu *spec_cu;
struct type *parent_type;
+ char *retval;
if (cu->language != language_cplus && cu->language != language_java
&& cu->language != language_fortran)
return "";
+ retval = anonymous_struct_prefix (die, cu);
+ if (retval)
+ return retval;
+
/* We have to be careful in the presence of DW_AT_specification.
For example, with GCC 3.4, given the code
case DW_TAG_compile_unit:
/* gcc-4.5 -gdwarf-4 can drop the enclosing namespace. Cope. */
if (cu->language == language_cplus
- && dwarf2_per_objfile->types.asection != NULL
+ && !VEC_empty (dwarf2_section_info_def, dwarf2_per_objfile->types)
&& die->child != NULL
&& (die->tag == DW_TAG_class_type
|| die->tag == DW_TAG_structure_type
if (demangled)
{
+ char *base;
+
/* FIXME: we already did this for the partial symbol... */
- DW_STRING (attr)
- = obsavestring (demangled, strlen (demangled),
- &cu->objfile->objfile_obstack);
+ DW_STRING (attr) = obsavestring (demangled, strlen (demangled),
+ &cu->objfile->objfile_obstack);
DW_STRING_IS_CANONICAL (attr) = 1;
xfree (demangled);
+
+ /* Strip any leading namespaces/classes, keep only the base name.
+ DW_AT_name for named DIEs does not contain the prefixes. */
+ base = strrchr (DW_STRING (attr), ':');
+ if (base && base > DW_STRING (attr) && base[-1] == ':')
+ return &base[1];
+ else
+ return DW_STRING (attr);
}
}
break;
return "DW_TAG_PGI_kanji_type";
case DW_TAG_PGI_interface_block:
return "DW_TAG_PGI_interface_block";
+ case DW_TAG_GNU_call_site:
+ return "DW_TAG_GNU_call_site";
default:
return "DW_TAG_<unknown>";
}
return "DW_OP_GNU_uninit";
case DW_OP_GNU_implicit_pointer:
return "DW_OP_GNU_implicit_pointer";
+ case DW_OP_GNU_entry_value:
+ return "DW_OP_GNU_entry_value";
+ case DW_OP_GNU_const_type:
+ return "DW_OP_GNU_const_type";
+ case DW_OP_GNU_regval_type:
+ return "DW_OP_GNU_regval_type";
+ case DW_OP_GNU_deref_type:
+ return "DW_OP_GNU_deref_type";
+ case DW_OP_GNU_convert:
+ return "DW_OP_GNU_convert";
+ case DW_OP_GNU_reinterpret:
+ return "DW_OP_GNU_reinterpret";
default:
return NULL;
}
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])->offset);
+ DW_SIGNATURED_TYPE (&die->attrs[i])->per_cu.offset);
else
fprintf_unfiltered (f, "signatured type, offset: unknown");
break;
target_cu = cu;
- if (cu->per_cu->from_debug_types)
+ if (cu->per_cu->debug_type_section)
{
/* .debug_types CUs cannot reference anything outside their CU.
If they need to, they have to reference a signatured type via
return die;
}
-/* Return DWARF block and its CU referenced by OFFSET at PER_CU. Returned
- value is intended for DW_OP_call*. */
+/* Return DWARF block referenced by DW_AT_location of DIE at OFFSET at PER_CU.
+ Returned value is intended for DW_OP_call*. Returned
+ dwarf2_locexpr_baton->data has lifetime of PER_CU->OBJFILE. */
struct dwarf2_locexpr_baton
dwarf2_fetch_die_location_block (unsigned int offset,
CORE_ADDR (*get_frame_pc) (void *baton),
void *baton)
{
- struct dwarf2_cu *cu = per_cu->cu;
+ struct dwarf2_cu *cu;
struct die_info *die;
struct attribute *attr;
struct dwarf2_locexpr_baton retval;
dw2_setup (per_cu->objfile);
+ if (per_cu->cu == NULL)
+ load_cu (per_cu);
+ cu = per_cu->cu;
+
die = follow_die_offset (offset, &cu);
if (!die)
error (_("Dwarf Error: Cannot find DIE at 0x%x referenced in module %s"),
attr = dwarf2_attr (die, DW_AT_location, cu);
if (!attr)
{
- /* DWARF: "If there is no such attribute, then there is no effect.". */
+ /* DWARF: "If there is no such attribute, then there is no effect.".
+ DATA is ignored if SIZE is 0. */
retval.data = NULL;
retval.size = 0;
retval.size = DW_BLOCK (attr)->size;
}
retval.per_cu = cu->per_cu;
+
+ age_cached_comp_units ();
+
return retval;
}
+/* Return the type of the DIE at DIE_OFFSET in the CU named by
+ PER_CU. */
+
+struct type *
+dwarf2_get_die_type (unsigned int die_offset,
+ struct dwarf2_per_cu_data *per_cu)
+{
+ dw2_setup (per_cu->objfile);
+ return get_die_type_at_offset (die_offset, per_cu);
+}
+
/* Follow the signature attribute ATTR in SRC_DIE.
On entry *REF_CU is the CU of SRC_DIE.
On exit *REF_CU is the CU of the result. */
/* Given an offset of a signatured type, return its signatured_type. */
static struct signatured_type *
-lookup_signatured_type_at_offset (struct objfile *objfile, unsigned int offset)
+lookup_signatured_type_at_offset (struct objfile *objfile,
+ struct dwarf2_section_info *section,
+ unsigned int offset)
{
- gdb_byte *info_ptr = dwarf2_per_objfile->types.buffer + offset;
+ gdb_byte *info_ptr = section->buffer + offset;
unsigned int length, initial_length_size;
unsigned int sig_offset;
struct signatured_type find_entry, *type_sig;
/* 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->offset);
+ gdb_assert (offset == type_sig->per_cu.offset);
return type_sig;
}
static void
read_signatured_type_at_offset (struct objfile *objfile,
+ struct dwarf2_section_info *sect,
unsigned int offset)
{
struct signatured_type *type_sig;
- dwarf2_read_section (objfile, &dwarf2_per_objfile->types);
+ dwarf2_read_section (objfile, sect);
/* We have the section offset, but we need the signature to do the
hash table lookup. */
- type_sig = lookup_signatured_type_at_offset (objfile, offset);
+ type_sig = lookup_signatured_type_at_offset (objfile, sect, offset);
gdb_assert (type_sig->per_cu.cu == NULL);
struct dwarf2_cu *cu;
ULONGEST signature;
struct cleanup *back_to, *free_cu_cleanup;
+ struct dwarf2_section_info *section = type_sig->per_cu.debug_type_section;
- dwarf2_read_section (objfile, &dwarf2_per_objfile->types);
- types_ptr = dwarf2_per_objfile->types.buffer + type_sig->offset;
+ dwarf2_read_section (objfile, section);
+ types_ptr = section->buffer + type_sig->per_cu.offset;
gdb_assert (type_sig->per_cu.cu == NULL);
/* If an error occurs while loading, release our storage. */
free_cu_cleanup = make_cleanup (free_one_comp_unit, cu);
- types_ptr = read_type_comp_unit_head (&cu->header, &signature,
+ types_ptr = read_type_comp_unit_head (&cu->header, section, &signature,
types_ptr, objfile->obfd);
gdb_assert (signature == type_sig->signature);
dwarf2_macro_malformed_definition_complaint (body);
}
+/* Skip some bytes from BYTES according to the form given in FORM.
+ Returns the new pointer. */
-static void
-dwarf_decode_macros (struct line_header *lh, unsigned int offset,
- char *comp_dir, bfd *abfd,
- struct dwarf2_cu *cu)
+static gdb_byte *
+skip_form_bytes (bfd *abfd, gdb_byte *bytes,
+ enum dwarf_form form,
+ unsigned int offset_size,
+ struct dwarf2_section_info *section)
{
- gdb_byte *mac_ptr, *mac_end;
- struct macro_source_file *current_file = 0;
- enum dwarf_macinfo_record_type macinfo_type;
- int at_commandline;
+ unsigned int bytes_read;
- dwarf2_read_section (dwarf2_per_objfile->objfile,
- &dwarf2_per_objfile->macinfo);
- if (dwarf2_per_objfile->macinfo.buffer == NULL)
+ switch (form)
{
- complaint (&symfile_complaints, _("missing .debug_macinfo section"));
- return;
+ case DW_FORM_data1:
+ case DW_FORM_flag:
+ ++bytes;
+ break;
+
+ case DW_FORM_data2:
+ bytes += 2;
+ break;
+
+ case DW_FORM_data4:
+ bytes += 4;
+ break;
+
+ case DW_FORM_data8:
+ bytes += 8;
+ break;
+
+ case DW_FORM_string:
+ read_direct_string (abfd, bytes, &bytes_read);
+ bytes += bytes_read;
+ break;
+
+ case DW_FORM_sec_offset:
+ case DW_FORM_strp:
+ bytes += offset_size;
+ break;
+
+ case DW_FORM_block:
+ bytes += read_unsigned_leb128 (abfd, bytes, &bytes_read);
+ bytes += bytes_read;
+ break;
+
+ case DW_FORM_block1:
+ bytes += 1 + read_1_byte (abfd, bytes);
+ break;
+ case DW_FORM_block2:
+ bytes += 2 + read_2_bytes (abfd, bytes);
+ break;
+ case DW_FORM_block4:
+ bytes += 4 + read_4_bytes (abfd, bytes);
+ break;
+
+ case DW_FORM_sdata:
+ case DW_FORM_udata:
+ bytes = skip_leb128 (abfd, bytes);
+ break;
+
+ default:
+ {
+ complain:
+ complaint (&symfile_complaints,
+ _("invalid form 0x%x in `%s'"),
+ form,
+ section->asection->name);
+ return NULL;
+ }
}
- /* First pass: Find the name of the base filename.
- This filename is needed in order to process all macros whose definition
- (or undefinition) comes from the command line. These macros are defined
- before the first DW_MACINFO_start_file entry, and yet still need to be
- associated to the base file.
+ return bytes;
+}
- To determine the base file name, we scan the macro definitions until we
- reach the first DW_MACINFO_start_file entry. We then initialize
- CURRENT_FILE accordingly so that any macro definition found before the
- first DW_MACINFO_start_file can still be associated to the base file. */
+/* A helper for dwarf_decode_macros that handles skipping an unknown
+ opcode. Returns an updated pointer to the macro data buffer; or,
+ on error, issues a complaint and returns NULL. */
- mac_ptr = dwarf2_per_objfile->macinfo.buffer + offset;
- mac_end = dwarf2_per_objfile->macinfo.buffer
- + dwarf2_per_objfile->macinfo.size;
+static gdb_byte *
+skip_unknown_opcode (unsigned int opcode,
+ gdb_byte **opcode_definitions,
+ gdb_byte *mac_ptr,
+ bfd *abfd,
+ unsigned int offset_size,
+ struct dwarf2_section_info *section)
+{
+ unsigned int bytes_read, i;
+ unsigned long arg;
+ gdb_byte *defn;
- do
+ if (opcode_definitions[opcode] == NULL)
{
- /* Do we at least have room for a macinfo type byte? */
- if (mac_ptr >= mac_end)
- {
- /* Complaint is printed during the second pass as GDB will probably
- stop the first pass earlier upon finding
- DW_MACINFO_start_file. */
- break;
- }
+ complaint (&symfile_complaints,
+ _("unrecognized DW_MACFINO opcode 0x%x"),
+ opcode);
+ return NULL;
+ }
- macinfo_type = read_1_byte (abfd, mac_ptr);
- mac_ptr++;
+ defn = opcode_definitions[opcode];
+ arg = read_unsigned_leb128 (abfd, defn, &bytes_read);
+ defn += bytes_read;
- switch (macinfo_type)
- {
- /* A zero macinfo type indicates the end of the macro
- information. */
- case 0:
- break;
+ for (i = 0; i < arg; ++i)
+ {
+ mac_ptr = skip_form_bytes (abfd, mac_ptr, defn[i], offset_size, section);
+ if (mac_ptr == NULL)
+ {
+ /* skip_form_bytes already issued the complaint. */
+ return NULL;
+ }
+ }
- case DW_MACINFO_define:
- case DW_MACINFO_undef:
- /* Only skip the data by MAC_PTR. */
- {
- unsigned int bytes_read;
+ return mac_ptr;
+}
- read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
- mac_ptr += bytes_read;
- read_direct_string (abfd, mac_ptr, &bytes_read);
- mac_ptr += bytes_read;
- }
- break;
+/* A helper function which parses the header of a macro section.
+ If the macro section is the extended (for now called "GNU") type,
+ then this updates *OFFSET_SIZE. Returns a pointer to just after
+ the header, or issues a complaint and returns NULL on error. */
- case DW_MACINFO_start_file:
- {
- unsigned int bytes_read;
- int line, file;
+static gdb_byte *
+dwarf_parse_macro_header (gdb_byte **opcode_definitions,
+ bfd *abfd,
+ gdb_byte *mac_ptr,
+ unsigned int *offset_size,
+ int section_is_gnu)
+{
+ memset (opcode_definitions, 0, 256 * sizeof (gdb_byte *));
- line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
- mac_ptr += bytes_read;
- file = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
- mac_ptr += bytes_read;
+ if (section_is_gnu)
+ {
+ unsigned int version, flags;
- current_file = macro_start_file (file, line, current_file,
- comp_dir, lh, cu->objfile);
- }
- break;
+ version = read_2_bytes (abfd, mac_ptr);
+ if (version != 4)
+ {
+ complaint (&symfile_complaints,
+ _("unrecognized version `%d' in .debug_macro section"),
+ version);
+ return NULL;
+ }
+ mac_ptr += 2;
- case DW_MACINFO_end_file:
- /* No data to skip by MAC_PTR. */
- break;
+ flags = read_1_byte (abfd, mac_ptr);
+ ++mac_ptr;
+ *offset_size = (flags & 1) ? 8 : 4;
- case DW_MACINFO_vendor_ext:
- /* Only skip the data by MAC_PTR. */
- {
- unsigned int bytes_read;
+ if ((flags & 2) != 0)
+ /* We don't need the line table offset. */
+ mac_ptr += *offset_size;
- read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
- mac_ptr += bytes_read;
- read_direct_string (abfd, mac_ptr, &bytes_read);
- mac_ptr += bytes_read;
- }
- break;
+ /* Vendor opcode descriptions. */
+ if ((flags & 4) != 0)
+ {
+ unsigned int i, count;
- default:
- break;
+ count = read_1_byte (abfd, mac_ptr);
+ ++mac_ptr;
+ for (i = 0; i < count; ++i)
+ {
+ unsigned int opcode, bytes_read;
+ unsigned long arg;
+
+ opcode = read_1_byte (abfd, mac_ptr);
+ ++mac_ptr;
+ opcode_definitions[opcode] = mac_ptr;
+ arg = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+ mac_ptr += arg;
+ }
}
- } while (macinfo_type != 0 && current_file == NULL);
+ }
- /* Second pass: Process all entries.
+ return mac_ptr;
+}
- Use the AT_COMMAND_LINE flag to determine whether we are still processing
- command-line macro definitions/undefinitions. This flag is unset when we
- reach the first DW_MACINFO_start_file entry. */
+/* A helper for dwarf_decode_macros that handles the GNU extensions,
+ including DW_GNU_MACINFO_transparent_include. */
+
+static void
+dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end,
+ struct macro_source_file *current_file,
+ struct line_header *lh, char *comp_dir,
+ struct dwarf2_section_info *section,
+ int section_is_gnu,
+ unsigned int offset_size,
+ struct objfile *objfile)
+{
+ enum dwarf_macro_record_type macinfo_type;
+ int at_commandline;
+ gdb_byte *opcode_definitions[256];
- mac_ptr = dwarf2_per_objfile->macinfo.buffer + offset;
+ mac_ptr = dwarf_parse_macro_header (opcode_definitions, abfd, mac_ptr,
+ &offset_size, section_is_gnu);
+ if (mac_ptr == NULL)
+ {
+ /* We already issued a complaint. */
+ return;
+ }
/* Determines if GDB is still before first DW_MACINFO_start_file. If true
GDB is still reading the definitions from command line. First
/* Do we at least have room for a macinfo type byte? */
if (mac_ptr >= mac_end)
{
- dwarf2_macros_too_long_complaint ();
+ dwarf2_macros_too_long_complaint (section);
break;
}
macinfo_type = read_1_byte (abfd, mac_ptr);
mac_ptr++;
+ /* Note that we rely on the fact that the corresponding GNU and
+ DWARF constants are the same. */
switch (macinfo_type)
{
/* A zero macinfo type indicates the end of the macro
case 0:
break;
- case DW_MACINFO_define:
- case DW_MACINFO_undef:
+ case DW_MACRO_GNU_define:
+ case DW_MACRO_GNU_undef:
+ case DW_MACRO_GNU_define_indirect:
+ case DW_MACRO_GNU_undef_indirect:
{
unsigned int bytes_read;
int line;
char *body;
+ int is_define;
- line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
- mac_ptr += bytes_read;
- body = read_direct_string (abfd, mac_ptr, &bytes_read);
- mac_ptr += bytes_read;
+ line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+
+ if (macinfo_type == DW_MACRO_GNU_define
+ || macinfo_type == DW_MACRO_GNU_undef)
+ {
+ body = read_direct_string (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+ }
+ else
+ {
+ LONGEST str_offset;
+ str_offset = read_offset_1 (abfd, mac_ptr, offset_size);
+ mac_ptr += offset_size;
+
+ body = read_indirect_string_at_offset (abfd, str_offset);
+ }
+
+ is_define = (macinfo_type == DW_MACRO_GNU_define
+ || macinfo_type == DW_MACRO_GNU_define_indirect);
if (! current_file)
{
/* DWARF violation as no main source is present. */
complaint (&symfile_complaints,
_("debug info with no main source gives macro %s "
"on line %d: %s"),
- macinfo_type == DW_MACINFO_define ?
- _("definition") :
- macinfo_type == DW_MACINFO_undef ?
- _("undefinition") :
- _("something-or-other"), line, body);
+ is_define ? _("definition") : _("undefinition"),
+ line, body);
break;
}
if ((line == 0 && !at_commandline)
complaint (&symfile_complaints,
_("debug info gives %s macro %s with %s line %d: %s"),
at_commandline ? _("command-line") : _("in-file"),
- macinfo_type == DW_MACINFO_define ?
- _("definition") :
- macinfo_type == DW_MACINFO_undef ?
- _("undefinition") :
- _("something-or-other"),
+ is_define ? _("definition") : _("undefinition"),
line == 0 ? _("zero") : _("non-zero"), line, body);
- if (macinfo_type == DW_MACINFO_define)
+ if (is_define)
parse_macro_definition (current_file, line, body);
- else if (macinfo_type == DW_MACINFO_undef)
- macro_undef (current_file, line, body);
+ else
+ {
+ gdb_assert (macinfo_type == DW_MACRO_GNU_undef
+ || macinfo_type == DW_MACRO_GNU_undef_indirect);
+ macro_undef (current_file, line, body);
+ }
}
break;
- case DW_MACINFO_start_file:
+ case DW_MACRO_GNU_start_file:
{
unsigned int bytes_read;
int line, file;
if (at_commandline)
{
- /* This DW_MACINFO_start_file was executed in the pass one. */
+ /* This DW_MACRO_GNU_start_file was executed in the
+ pass one. */
at_commandline = 0;
}
else
current_file = macro_start_file (file, line,
current_file, comp_dir,
- lh, cu->objfile);
+ lh, objfile);
}
break;
- case DW_MACINFO_end_file:
+ case DW_MACRO_GNU_end_file:
if (! current_file)
complaint (&symfile_complaints,
_("macro debug info has an unmatched "
current_file = current_file->included_by;
if (! current_file)
{
- enum dwarf_macinfo_record_type next_type;
+ enum dwarf_macro_record_type next_type;
/* GCC circa March 2002 doesn't produce the zero
type byte marking the end of the compilation
/* Do we at least have room for a macinfo type byte? */
if (mac_ptr >= mac_end)
{
- dwarf2_macros_too_long_complaint ();
+ dwarf2_macros_too_long_complaint (section);
return;
}
}
break;
+ case DW_MACRO_GNU_transparent_include:
+ {
+ LONGEST offset;
+
+ 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);
+ }
+ break;
+
case DW_MACINFO_vendor_ext:
- {
- unsigned int bytes_read;
- int constant;
+ if (!section_is_gnu)
+ {
+ unsigned int bytes_read;
+ int constant;
- constant = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
- mac_ptr += bytes_read;
- read_direct_string (abfd, mac_ptr, &bytes_read);
- mac_ptr += bytes_read;
+ constant = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+ read_direct_string (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
- /* We don't recognize any vendor extensions. */
- }
- break;
+ /* We don't recognize any vendor extensions. */
+ break;
+ }
+ /* FALLTHROUGH */
+
+ default:
+ mac_ptr = skip_unknown_opcode (macinfo_type, opcode_definitions,
+ mac_ptr, abfd, offset_size,
+ section);
+ if (mac_ptr == NULL)
+ return;
+ break;
}
} while (macinfo_type != 0);
}
+static void
+dwarf_decode_macros (struct line_header *lh, unsigned int offset,
+ char *comp_dir, bfd *abfd,
+ struct dwarf2_cu *cu,
+ struct dwarf2_section_info *section,
+ int section_is_gnu)
+{
+ gdb_byte *mac_ptr, *mac_end;
+ struct macro_source_file *current_file = 0;
+ enum dwarf_macro_record_type macinfo_type;
+ unsigned int offset_size = cu->header.offset_size;
+ gdb_byte *opcode_definitions[256];
+
+ dwarf2_read_section (dwarf2_per_objfile->objfile, section);
+ if (section->buffer == NULL)
+ {
+ complaint (&symfile_complaints, _("missing %s section"),
+ section->asection->name);
+ return;
+ }
+
+ /* First pass: Find the name of the base filename.
+ This filename is needed in order to process all macros whose definition
+ (or undefinition) comes from the command line. These macros are defined
+ before the first DW_MACINFO_start_file entry, and yet still need to be
+ associated to the base file.
+
+ To determine the base file name, we scan the macro definitions until we
+ reach the first DW_MACINFO_start_file entry. We then initialize
+ CURRENT_FILE accordingly so that any macro definition found before the
+ first DW_MACINFO_start_file can still be associated to the base file. */
+
+ mac_ptr = section->buffer + offset;
+ mac_end = section->buffer + section->size;
+
+ mac_ptr = dwarf_parse_macro_header (opcode_definitions, abfd, mac_ptr,
+ &offset_size, section_is_gnu);
+ if (mac_ptr == NULL)
+ {
+ /* We already issued a complaint. */
+ return;
+ }
+
+ do
+ {
+ /* Do we at least have room for a macinfo type byte? */
+ if (mac_ptr >= mac_end)
+ {
+ /* Complaint is printed during the second pass as GDB will probably
+ stop the first pass earlier upon finding
+ DW_MACINFO_start_file. */
+ break;
+ }
+
+ macinfo_type = read_1_byte (abfd, mac_ptr);
+ mac_ptr++;
+
+ /* Note that we rely on the fact that the corresponding GNU and
+ DWARF constants are the same. */
+ switch (macinfo_type)
+ {
+ /* A zero macinfo type indicates the end of the macro
+ information. */
+ case 0:
+ break;
+
+ case DW_MACRO_GNU_define:
+ case DW_MACRO_GNU_undef:
+ /* Only skip the data by MAC_PTR. */
+ {
+ unsigned int bytes_read;
+
+ read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+ read_direct_string (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+ }
+ break;
+
+ case DW_MACRO_GNU_start_file:
+ {
+ unsigned int bytes_read;
+ int line, file;
+
+ line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+ file = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+
+ current_file = macro_start_file (file, line, current_file,
+ comp_dir, lh, cu->objfile);
+ }
+ break;
+
+ case DW_MACRO_GNU_end_file:
+ /* No data to skip by MAC_PTR. */
+ break;
+
+ case DW_MACRO_GNU_define_indirect:
+ case DW_MACRO_GNU_undef_indirect:
+ {
+ unsigned int bytes_read;
+
+ read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+ mac_ptr += offset_size;
+ }
+ break;
+
+ case DW_MACRO_GNU_transparent_include:
+ /* Note that, according to the spec, a transparent include
+ chain cannot call DW_MACRO_GNU_start_file. So, we can just
+ skip this opcode. */
+ mac_ptr += offset_size;
+ break;
+
+ case DW_MACINFO_vendor_ext:
+ /* Only skip the data by MAC_PTR. */
+ if (!section_is_gnu)
+ {
+ unsigned int bytes_read;
+
+ read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+ read_direct_string (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+ }
+ /* FALLTHROUGH */
+
+ default:
+ mac_ptr = skip_unknown_opcode (macinfo_type, opcode_definitions,
+ mac_ptr, abfd, offset_size,
+ section);
+ if (mac_ptr == NULL)
+ return;
+ break;
+ }
+ } while (macinfo_type != 0 && current_file == NULL);
+
+ /* Second pass: Process all entries.
+
+ Use the AT_COMMAND_LINE flag to determine whether we are still processing
+ 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,
+ current_file, lh, comp_dir, section, section_is_gnu,
+ offset_size, cu->objfile);
+}
+
/* Check if the attribute's form is a DW_FORM_block*
if so return true else false. */
static int
dwarf2_invalid_attrib_class_complaint ("location description",
SYMBOL_NATURAL_NAME (sym));
baton->size = 0;
- baton->data = NULL;
}
SYMBOL_COMPUTED_OPS (sym) = &dwarf2_locexpr_funcs;
return objfile;
}
+/* Return comp_unit_head for PER_CU, either already available in PER_CU->CU
+ (CU_HEADERP is unused in such case) or prepare a temporary copy at
+ CU_HEADERP first. */
+
+static const struct comp_unit_head *
+per_cu_header_read_in (struct comp_unit_head *cu_headerp,
+ struct dwarf2_per_cu_data *per_cu)
+{
+ struct objfile *objfile;
+ struct dwarf2_per_objfile *per_objfile;
+ gdb_byte *info_ptr;
+
+ if (per_cu->cu)
+ return &per_cu->cu->header;
+
+ objfile = per_cu->objfile;
+ per_objfile = objfile_data (objfile, dwarf2_objfile_data_key);
+ info_ptr = per_objfile->info.buffer + per_cu->offset;
+
+ memset (cu_headerp, 0, sizeof (*cu_headerp));
+ read_comp_unit_head (cu_headerp, info_ptr, objfile->obfd);
+
+ return cu_headerp;
+}
+
/* Return the address size given in the compilation unit header for CU. */
CORE_ADDR
dwarf2_per_cu_addr_size (struct dwarf2_per_cu_data *per_cu)
{
- if (per_cu->cu)
- return per_cu->cu->header.addr_size;
- else
- {
- /* If the CU is not currently read in, we re-read its header. */
- struct objfile *objfile = per_cu->objfile;
- struct dwarf2_per_objfile *per_objfile
- = objfile_data (objfile, dwarf2_objfile_data_key);
- gdb_byte *info_ptr = per_objfile->info.buffer + per_cu->offset;
- struct comp_unit_head cu_header;
+ struct comp_unit_head cu_header_local;
+ const struct comp_unit_head *cu_headerp;
- memset (&cu_header, 0, sizeof cu_header);
- read_comp_unit_head (&cu_header, info_ptr, objfile->obfd);
- return cu_header.addr_size;
- }
+ cu_headerp = per_cu_header_read_in (&cu_header_local, per_cu);
+
+ return cu_headerp->addr_size;
}
/* Return the offset size given in the compilation unit header for CU. */
int
dwarf2_per_cu_offset_size (struct dwarf2_per_cu_data *per_cu)
{
- if (per_cu->cu)
- return per_cu->cu->header.offset_size;
- else
- {
- /* If the CU is not currently read in, we re-read its header. */
- struct objfile *objfile = per_cu->objfile;
- struct dwarf2_per_objfile *per_objfile
- = objfile_data (objfile, dwarf2_objfile_data_key);
- gdb_byte *info_ptr = per_objfile->info.buffer + per_cu->offset;
- struct comp_unit_head cu_header;
+ struct comp_unit_head cu_header_local;
+ const struct comp_unit_head *cu_headerp;
- memset (&cu_header, 0, sizeof cu_header);
- read_comp_unit_head (&cu_header, info_ptr, objfile->obfd);
- return cu_header.offset_size;
- }
+ cu_headerp = per_cu_header_read_in (&cu_header_local, per_cu);
+
+ return cu_headerp->offset_size;
+}
+
+/* See its dwarf2loc.h declaration. */
+
+int
+dwarf2_per_cu_ref_addr_size (struct dwarf2_per_cu_data *per_cu)
+{
+ struct comp_unit_head cu_header_local;
+ const struct comp_unit_head *cu_headerp;
+
+ cu_headerp = per_cu_header_read_in (&cu_header_local, per_cu);
+
+ if (cu_headerp->version == 2)
+ return cu_headerp->addr_size;
+ else
+ return cu_headerp->offset_size;
}
/* Return the text offset of the CU. The returned offset comes from
&& !HAVE_GNAT_AUX_INFO (type))
INIT_GNAT_SPECIFIC (type);
- if (cu->per_cu->from_debug_types)
+ if (cu->per_cu->debug_type_section)
type_hash_ptr = &dwarf2_per_objfile->debug_types_type_hash;
else
type_hash_ptr = &dwarf2_per_objfile->debug_info_type_hash;
struct dwarf2_offset_and_type *slot, ofs;
htab_t type_hash;
- if (per_cu->from_debug_types)
+ if (per_cu->debug_type_section)
type_hash = dwarf2_per_objfile->debug_types_type_hash;
else
type_hash = dwarf2_per_objfile->debug_info_type_hash;
struct dwarf2_per_cu_data *per_cu;
per_cu = (struct dwarf2_per_cu_data *) *slot;
+
+ /* cu->dependencies references may not yet have been ever read if QUIT aborts
+ reading of the chain. As such dependencies remain valid it is not much
+ useful to track and undo them during QUIT cleanups. */
+ if (per_cu->cu == NULL)
+ return 1;
+
if (per_cu->cu->mark)
return 1;
per_cu->cu->mark = 1;
static void
munmap_section_buffer (struct dwarf2_section_info *info)
{
- if (info->was_mmapped)
+ if (info->map_addr != NULL)
{
#ifdef HAVE_MMAP
- intptr_t begin = (intptr_t) info->buffer;
- intptr_t map_begin = begin & ~(pagesize - 1);
- size_t map_length = info->size + begin - map_begin;
+ int res;
- gdb_assert (munmap ((void *) map_begin, map_length) == 0);
+ res = munmap (info->map_addr, info->map_len);
+ gdb_assert (res == 0);
#else
/* Without HAVE_MMAP, we should never be here to begin with. */
gdb_assert_not_reached ("no mmap support");
dwarf2_per_objfile_free (struct objfile *objfile, void *d)
{
struct dwarf2_per_objfile *data = d;
+ int ix;
+ struct dwarf2_section_info *section;
/* This is sorted according to the order they're defined in to make it easier
to keep in sync. */
munmap_section_buffer (&data->line);
munmap_section_buffer (&data->loc);
munmap_section_buffer (&data->macinfo);
+ munmap_section_buffer (&data->macro);
munmap_section_buffer (&data->str);
munmap_section_buffer (&data->ranges);
- munmap_section_buffer (&data->types);
munmap_section_buffer (&data->frame);
munmap_section_buffer (&data->eh_frame);
munmap_section_buffer (&data->gdb_index);
+
+ for (ix = 0;
+ VEC_iterate (dwarf2_section_info_def, data->types, ix, section);
+ ++ix)
+ munmap_section_buffer (section);
+
+ VEC_free (dwarf2_section_info_def, data->types);
}
\f
const char *str;
};
-/* Hash function for a strtab_entry. */
+/* Hash function for a strtab_entry.
+
+ Function is used only during write_hash_table so no index format backward
+ compatibility is needed. */
static hashval_t
hash_strtab_entry (const void *e)
{
const struct strtab_entry *entry = e;
- return mapped_index_string_hash (entry->str);
+ return mapped_index_string_hash (INT_MAX, entry->str);
}
/* Equality function for a strtab_entry. */
}
/* Find a slot in SYMTAB for the symbol NAME. Returns a pointer to
- the slot. */
+ the slot.
+
+ Function is used only during write_hash_table so no index format backward
+ compatibility is needed. */
static struct symtab_index_entry **
find_slot (struct mapped_symtab *symtab, const char *name)
{
- offset_type index, step, hash = mapped_index_string_hash (name);
+ offset_type index, step, hash = mapped_index_string_hash (INT_MAX, name);
index = hash & (symtab->size - 1);
step = ((hash * 17) & (symtab->size - 1)) | 1;
/* Don't push an index twice. Due to how we add entries we only
have to check the last one. */
if (VEC_empty (offset_type, (*slot)->cu_indices)
- || VEC_length (offset_type, (*slot)->cu_indices) != cu_index)
+ || VEC_last (offset_type, (*slot)->cu_indices) != cu_index)
VEC_safe_push (offset_type, (*slot)->cu_indices, cu_index);
}
psymtab->n_static_syms, info->cu_index,
1);
- store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->offset);
+ store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->per_cu.offset);
obstack_grow (info->types_list, val, 8);
store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->type_offset);
obstack_grow (info->types_list, val, 8);
return 1;
}
-/* A cleanup function for an htab_t. */
-
-static void
-cleanup_htab (void *arg)
-{
- htab_delete (arg);
-}
-
/* Create an index file for OBJFILE in the directory DIR. */
static void
htab_t cu_index_htab;
struct psymtab_cu_index_map *psymtab_cu_index_map;
- if (!objfile->psymtabs)
+ if (!objfile->psymtabs || !objfile->psymtabs_addrmap)
return;
+
if (dwarf2_per_objfile->using_index)
error (_("Cannot use an index to create the index"));
+ if (VEC_length (dwarf2_section_info_def, dwarf2_per_objfile->types) > 1)
+ error (_("Cannot make an index when the file has multiple .debug_types sections"));
+
if (stat (objfile->name, &st) < 0)
perror_with_name (objfile->name);
psyms_seen = htab_create_alloc (100, htab_hash_pointer, htab_eq_pointer,
NULL, xcalloc, xfree);
- make_cleanup (cleanup_htab, psyms_seen);
+ make_cleanup_htab_delete (psyms_seen);
/* While we're scanning CU's create a table that maps a psymtab pointer
(which is what addrmap records) to its index (which is what is recorded
hash_psymtab_cu_index,
eq_psymtab_cu_index,
NULL, xcalloc, xfree);
- make_cleanup (cleanup_htab, cu_index_htab);
+ make_cleanup_htab_delete (cu_index_htab);
psymtab_cu_index_map = (struct psymtab_cu_index_map *)
xmalloc (sizeof (struct psymtab_cu_index_map)
* dwarf2_per_objfile->n_comp_units);
total_len = size_of_contents;
/* The version number. */
- val = MAYBE_SWAP (4);
+ val = MAYBE_SWAP (5);
obstack_grow (&contents, &val, sizeof (val));
/* The offset of the CU list from the start of the file. */
do_cleanups (cleanup);
}
-/* The mapped index file format is designed to be directly mmap()able
- on any architecture. In most cases, a datum is represented using a
- little-endian 32-bit integer value, called an offset_type. Big
- endian machines must byte-swap the values before using them.
- Exceptions to this rule are noted. The data is laid out such that
- alignment is always respected.
-
- A mapped index consists of several sections.
-
- 1. The file header. This is a sequence of values, of offset_type
- unless otherwise noted:
-
- [0] The version number, currently 4. Versions 1, 2 and 3 are
- obsolete.
- [1] The offset, from the start of the file, of the CU list.
- [2] The offset, from the start of the file, of the types CU list.
- Note that this section can be empty, in which case this offset will
- be equal to the next offset.
- [3] The offset, from the start of the file, of the address section.
- [4] The offset, from the start of the file, of the symbol table.
- [5] The offset, from the start of the file, of the constant pool.
-
- 2. The CU list. This is a sequence of pairs of 64-bit
- little-endian values, sorted by the CU offset. The first element
- in each pair is the offset of a CU in the .debug_info section. The
- second element in each pair is the length of that CU. References
- to a CU elsewhere in the map are done using a CU index, which is
- just the 0-based index into this table. Note that if there are
- type CUs, then conceptually CUs and type CUs form a single list for
- the purposes of CU indices.
-
- 3. The types CU list. This is a sequence of triplets of 64-bit
- little-endian values. In a triplet, the first value is the CU
- offset, the second value is the type offset in the CU, and the
- third value is the type signature. The types CU list is not
- sorted.
-
- 4. The address section. The address section consists of a sequence
- of address entries. Each address entry has three elements.
- [0] The low address. This is a 64-bit little-endian value.
- [1] The high address. This is a 64-bit little-endian value.
- Like DW_AT_high_pc, the value is one byte beyond the end.
- [2] The CU index. This is an offset_type value.
-
- 5. The symbol table. This is a hash table. The size of the hash
- table is always a power of 2. The initial hash and the step are
- currently defined by the `find_slot' function.
-
- Each slot in the hash table consists of a pair of offset_type
- values. The first value is the offset of the symbol's name in the
- constant pool. The second value is the offset of the CU vector in
- the constant pool.
-
- If both values are 0, then this slot in the hash table is empty.
- This is ok because while 0 is a valid constant pool index, it
- cannot be a valid index for both a string and a CU vector.
-
- A string in the constant pool is stored as a \0-terminated string,
- as you'd expect.
-
- A CU vector in the constant pool is a sequence of offset_type
- values. The first value is the number of CU indices in the vector.
- Each subsequent value is the index of a CU in the CU list. This
- element in the hash table is used to indicate which CUs define the
- symbol.
-
- 6. The constant pool. This is simply a bunch of bytes. It is
- organized so that alignment is correct: CU vectors are stored
- first, followed by strings. */
+/* Implementation of the `save gdb-index' command.
+
+ Note that the file format used by this command is documented in the
+ GDB manual. Any changes here must be documented there. */
static void
save_gdb_index_command (char *arg, int from_tty)
value);
}
+static void
+show_check_physname (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file,
+ _("Whether to check \"physname\" is %s.\n"),
+ value);
+}
+
void _initialize_dwarf2_read (void);
void
NULL,
&setdebuglist, &showdebuglist);
+ add_setshow_boolean_cmd ("check-physname", no_class, &check_physname, _("\
+Set cross-checking of \"physname\" code against demangler."), _("\
+Show cross-checking of \"physname\" code against demangler."), _("\
+When enabled, GDB's internal \"physname\" code is checked against\n\
+the demangler."),
+ NULL, show_check_physname,
+ &setdebuglist, &showdebuglist);
+
c = add_cmd ("gdb-index", class_files, save_gdb_index_command,
_("\
Save a gdb-index file.\n\