#include "dwarf2.h"
#include "buildsym.h"
#include "demangle.h"
+#include "gdb-demangle.h"
#include "expression.h"
#include "filenames.h" /* for DOSish file names */
#include "macrotab.h"
/* 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 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;
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. */
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)
{
struct signatured_type);
type_sig->signature = signature;
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);
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);
struct symtab **result)
{
int i;
- int check_basename = lbasename (name) == name;
+ const char *name_basename = lbasename (name);
+ int check_basename = name_basename == name;
struct dwarf2_per_cu_data *base_cu = NULL;
dw2_setup (objfile);
struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
struct quick_file_names *file_data;
+ /* We only need to look at symtabs not already expanded. */
if (per_cu->v.quick->symtab)
continue;
&& FILENAME_CMP (lbasename (this_name), name) == 0)
base_cu = per_cu;
+ /* Before we invoke realpath, which can get expensive when many
+ files are involved, do a quick comparison of the basenames. */
+ if (! basenames_may_differ
+ && FILENAME_CMP (lbasename (this_name), name_basename) != 0)
+ continue;
+
if (full_path != NULL)
{
const char *this_real_name = dw2_get_real_path (objfile,
struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
struct quick_file_names *file_data;
+ /* We only need to look at symtabs not already expanded. */
if (per_cu->v.quick->symtab)
continue;
/* 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))
struct quick_file_names *file_data;
per_cu->v.quick->mark = 0;
+
+ /* We only need to look at symtabs not already expanded. */
if (per_cu->v.quick->symtab)
continue;
}
static void
-dw2_map_symbol_filenames (struct objfile *objfile,
- void (*fun) (const char *, const char *, void *),
- void *data)
+dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun,
+ void *data, int need_fullname)
{
int i;
struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
struct quick_file_names *file_data;
+ /* We only need to look at symtabs not already expanded. */
if (per_cu->v.quick->symtab)
continue;
for (j = 0; j < file_data->num_file_names; ++j)
{
- const char *this_real_name = dw2_get_real_path (objfile, file_data,
- j);
+ const char *this_real_name;
+
+ if (need_fullname)
+ this_real_name = dw2_get_real_path (objfile, file_data, j);
+ else
+ this_real_name = NULL;
(*fun) (file_data->file_names[j], this_real_name, data);
}
}
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->type_offset = type_offset;
- type_sig->per_cu.objfile = objfile;
- type_sig->per_cu.from_debug_types = 1;
- type_sig->per_cu.offset = offset;
+ /* 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);
- if (*slot != NULL)
- {
- const struct signatured_type *dup_sig = *slot;
+ /* 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;
+ }
- 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;
+ 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;
+ }
- if (dwarf2_die_debug)
- fprintf_unfiltered (gdb_stdlog, " offset 0x%x, signature 0x%s\n",
- offset, phex (signature, sizeof (signature)));
+ 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)
{
/* LENGTH has not been set yet for type units. */
gdb_assert (this_cu->offset == cu.header.offset);
0,
objfile->global_psymbols.next,
objfile->static_psymbols.next);
+ pst->psymtabs_addrmap_supported = 1;
attr = dwarf2_attr (comp_unit_die, DW_AT_comp_dir, &cu);
if (attr != NULL)
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 + this_cu->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;
}
}
-/* Check for GCC >= 4.0. */
-
-static int
-producer_is_gcc_ge_4_0 (struct dwarf2_cu *cu)
-{
- const char *cs;
- int major, minor;
-
- if (cu->producer == NULL)
- {
- /* For unknown compilers expect their behavior is not compliant. For GCC
- this case can also happen for -gdwarf-4 type units supported since
- gcc-4.5. */
-
- return 0;
- }
-
- /* Skip any identifier after "GNU " - such as "C++" or "Java". */
-
- if (strncmp (cu->producer, "GNU ", strlen ("GNU ")) != 0)
- {
- /* For non-GCC compilers expect their behavior is not compliant. */
-
- return 0;
- }
- cs = &cu->producer[strlen ("GNU ")];
- while (*cs && !isdigit (*cs))
- cs++;
- if (sscanf (cs, "%d.%d", &major, &minor) != 2)
- {
- /* Not recognized as GCC. */
-
- return 0;
- }
-
- return major >= 4;
-}
-
/* Generate full symbol information for PST and CU, whose DIEs have
already been loaded into memory. */
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->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. */
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;
+
+ 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;
+ 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)
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;
}
}
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);
}
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
/* 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_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);
+ 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);
}
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>";
}
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;
}
/* 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;
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->per_cu.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;
- }
-
- /* 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.
+ case DW_FORM_data1:
+ case DW_FORM_flag:
+ ++bytes;
+ break;
- 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. */
+ case DW_FORM_data2:
+ bytes += 2;
+ break;
- mac_ptr = dwarf2_per_objfile->macinfo.buffer + offset;
- mac_end = dwarf2_per_objfile->macinfo.buffer
- + dwarf2_per_objfile->macinfo.size;
+ case DW_FORM_data4:
+ bytes += 4;
+ break;
- 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;
- }
+ case DW_FORM_data8:
+ bytes += 8;
+ break;
- macinfo_type = read_1_byte (abfd, mac_ptr);
- mac_ptr++;
+ case DW_FORM_string:
+ read_direct_string (abfd, bytes, &bytes_read);
+ bytes += bytes_read;
+ break;
- switch (macinfo_type)
- {
- /* A zero macinfo type indicates the end of the macro
- information. */
- case 0:
- break;
+ case DW_FORM_sec_offset:
+ case DW_FORM_strp:
+ bytes += offset_size;
+ break;
- case DW_MACINFO_define:
- case DW_MACINFO_undef:
- /* Only skip the data by MAC_PTR. */
- {
- unsigned int bytes_read;
+ case DW_FORM_block:
+ bytes += read_unsigned_leb128 (abfd, bytes, &bytes_read);
+ bytes += bytes_read;
+ break;
- 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_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_MACINFO_start_file:
- {
- unsigned int bytes_read;
- int line, file;
+ case DW_FORM_sdata:
+ case DW_FORM_udata:
+ bytes = skip_leb128 (abfd, bytes);
+ break;
- 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;
+ default:
+ {
+ complain:
+ complaint (&symfile_complaints,
+ _("invalid form 0x%x in `%s'"),
+ form,
+ section->asection->name);
+ return NULL;
+ }
+ }
- current_file = macro_start_file (file, line, current_file,
- comp_dir, lh, cu->objfile);
- }
- break;
+ return bytes;
+}
- case DW_MACINFO_end_file:
- /* No data to skip by MAC_PTR. */
- break;
+/* 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. */
- case DW_MACINFO_vendor_ext:
- /* Only skip the data by MAC_PTR. */
- {
- unsigned int bytes_read;
+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;
- 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;
+ if (opcode_definitions[opcode] == NULL)
+ {
+ complaint (&symfile_complaints,
+ _("unrecognized DW_MACFINO opcode 0x%x"),
+ opcode);
+ return NULL;
+ }
- default:
- break;
+ defn = opcode_definitions[opcode];
+ arg = read_unsigned_leb128 (abfd, defn, &bytes_read);
+ defn += bytes_read;
+
+ 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;
}
- } 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 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. */
- mac_ptr = dwarf2_per_objfile->macinfo.buffer + offset;
+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 *));
+
+ if (section_is_gnu)
+ {
+ unsigned int version, flags;
+
+ 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;
+
+ flags = read_1_byte (abfd, mac_ptr);
+ ++mac_ptr;
+ *offset_size = (flags & 1) ? 8 : 4;
+
+ if ((flags & 2) != 0)
+ /* We don't need the line table offset. */
+ mac_ptr += *offset_size;
+
+ /* Vendor opcode descriptions. */
+ if ((flags & 4) != 0)
+ {
+ unsigned int i, count;
+
+ 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;
+ }
+ }
+ }
+
+ return mac_ptr;
+}
+
+/* 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 = 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
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
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);
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\