/* 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;
struct dwarf2_section_info macinfo;
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_str", ".zdebug_str" },
+ { ".debug_ranges", ".zdebug_ranges" },
+ { ".debug_types", ".zdebug_types" },
+ { ".debug_frame", ".zdebug_frame" },
+ { ".eh_frame", NULL },
+ { ".gdb_index", ".zgdb_index" }
+};
/* local data types */
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;
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 *,
struct dwarf2_cu **);
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 *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->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
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);
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);
dwarf2_read_abbrevs (abfd, &cu);
make_cleanup (dwarf2_free_abbrev_table, &cu);
- if (this_cu->from_debug_types)
+ if (this_cu->debug_type_section)
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,
}
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;
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);
+
+ 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;
+
+ 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;
+ 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
{
make_cleanup (dwarf2_free_abbrev_table, &cu);
/* Read the compilation unit die. */
- if (this_cu->from_debug_types)
+ if (this_cu->debug_type_section)
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 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;
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;
}
}
-/* Check for GCC >= 4.0. */
+/* Check for GCC >= 4.x. Return minor version (x) of 4.x in such case. If it
+ is not GCC or it is GCC older than 4.x return -1. If it is GCC 5.x or
+ higher return INT_MAX. */
static int
-producer_is_gcc_ge_4_0 (struct dwarf2_cu *cu)
+producer_is_gcc_ge_4 (struct dwarf2_cu *cu)
{
const char *cs;
int major, minor;
this case can also happen for -gdwarf-4 type units supported since
gcc-4.5. */
- return 0;
+ return -1;
}
/* Skip any identifier after "GNU " - such as "C++" or "Java". */
{
/* For non-GCC compilers expect their behavior is not compliant. */
- return 0;
+ return -1;
}
cs = &cu->producer[strlen ("GNU ")];
while (*cs && !isdigit (*cs))
{
/* Not recognized as GCC. */
- return 0;
+ return -1;
}
- return major >= 4;
+ if (major < 4)
+ return -1;
+ if (major > 4)
+ return INT_MAX;
+ return minor;
}
/* Generate full symbol information for PST and CU, whose DIEs have
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);
if (symtab != NULL)
{
+ int gcc_4_minor = producer_is_gcc_ge_4 (cu);
+
/* 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. */
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 && producer_is_gcc_ge_4_0 (cu))
+ if (cu->has_loclist && gcc_4_minor >= 0)
symtab->locations_valid = 1;
+
+ if (gcc_4_minor >= 5)
+ symtab->epilogue_unwind_valid = 1;
}
if (dwarf2_per_objfile->using_index)
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;
+ cleanups = make_cleanup (VEC_cleanup (const_char_ptr), &excludes);
+
+ 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. */
+
+ 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;
+ }
+
+ 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
*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)
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)
+ if (attr && cu->line_header)
{
unsigned int macro_offset = DW_UNSND (attr);
- dwarf_decode_macros (line_header, macro_offset,
+ dwarf_decode_macros (cu->line_header, macro_offset,
comp_dir, abfd, cu);
}
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)
{
(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. */
}
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);
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);
}
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
"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
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
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 DWARF block and its CU referenced by OFFSET at PER_CU. Returned
- value is intended for DW_OP_call*. */
+ value is intended for DW_OP_call*. You must call xfree on returned
+ dwarf2_locexpr_baton->data. */
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"),
retval.size = DW_BLOCK (attr)->size;
}
retval.per_cu = cu->per_cu;
+
+ if (retval.data)
+ retval.data = xmemdup (retval.data, retval.size, retval.size);
+
+ age_cached_comp_units ();
+
return retval;
}
/* 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);
&& !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->macinfo);
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
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);
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);
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\