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;
};
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 */
{
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 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);
}
- 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);
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.offset = offset;
}
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;
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;
+ 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)
if (this_cu->from_debug_types)
{
- /* 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)
gdb_assert (dwarf2_per_objfile->types.readin);
process_psymtab_comp_unit (objfile, this_cu,
dwarf2_per_objfile->types.buffer,
- dwarf2_per_objfile->types.buffer + entry->offset,
+ dwarf2_per_objfile->types.buffer + this_cu->offset,
dwarf2_per_objfile->types.size);
return 1;
}
}
-/* 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
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)
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
(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. */
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;
/* 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
die->offset, cu->objfile->name);
gdb_assert (sig_type->per_cu.from_debug_types);
- offset = sig_type->offset + sig_type->type_offset;
+ 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_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;
/* 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;
}
struct cleanup *back_to, *free_cu_cleanup;
dwarf2_read_section (objfile, &dwarf2_per_objfile->types);
- types_ptr = dwarf2_per_objfile->types.buffer + type_sig->offset;
+ types_ptr = dwarf2_per_objfile->types.buffer + type_sig->per_cu.offset;
gdb_assert (type_sig->per_cu.cu == NULL);
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");
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);