#ifdef HAVE_ZLIB_H
#include <zlib.h>
#endif
-
-/* A note on memory usage for this file.
-
- At the present time, this code reads the debug info sections into
- the objfile's objfile_obstack. A definite improvement for startup
- time, on platforms which do not emit relocations for debug
- sections, would be to use mmap instead. The object's complete
- debug information is loaded into memory, partly to simplify
- absolute DIE references.
-
- Whether using obstacks or mmap, the sections should remain loaded
- until the objfile is released, and pointers into the section data
- can be used for any other data associated to the objfile (symbol
- names, type names, location expressions to name a few). */
+#ifdef HAVE_MMAP
+#include <sys/mman.h>
+#endif
#if 0
/* .debug_info header for a compilation unit
/* When non-zero, dump DIEs after they are read in. */
static int dwarf2_die_debug = 0;
+static int pagesize;
+
/* When set, the file that we're processing is known to have debugging
info for C++ namespaces. GCC 3.3.x did not produce this information,
but later versions do. */
static const struct objfile_data *dwarf2_objfile_data_key;
+struct dwarf2_section_info
+{
+ asection *asection;
+ gdb_byte *buffer;
+ bfd_size_type size;
+ int was_mmapped;
+};
+
struct dwarf2_per_objfile
{
- /* Sizes of debugging sections. */
- unsigned int info_size;
- unsigned int abbrev_size;
- unsigned int line_size;
- unsigned int pubnames_size;
- unsigned int aranges_size;
- unsigned int loc_size;
- unsigned int macinfo_size;
- unsigned int str_size;
- unsigned int ranges_size;
- unsigned int frame_size;
- unsigned int eh_frame_size;
-
- /* Loaded data from the sections. */
- gdb_byte *info_buffer;
- gdb_byte *abbrev_buffer;
- gdb_byte *line_buffer;
- gdb_byte *str_buffer;
- gdb_byte *macinfo_buffer;
- gdb_byte *ranges_buffer;
- gdb_byte *loc_buffer;
+ struct dwarf2_section_info info;
+ struct dwarf2_section_info abbrev;
+ struct dwarf2_section_info line;
+ struct dwarf2_section_info pubnames;
+ struct dwarf2_section_info aranges;
+ struct dwarf2_section_info loc;
+ struct dwarf2_section_info macinfo;
+ struct dwarf2_section_info str;
+ struct dwarf2_section_info ranges;
+ struct dwarf2_section_info frame;
+ struct dwarf2_section_info eh_frame;
/* A list of all the compilation units. This is used to locate
the target compilation unit of a particular reference. */
static struct dwarf2_per_objfile *dwarf2_per_objfile;
-static asection *dwarf_info_section;
-static asection *dwarf_abbrev_section;
-static asection *dwarf_line_section;
-static asection *dwarf_pubnames_section;
-static asection *dwarf_aranges_section;
-static asection *dwarf_loc_section;
-static asection *dwarf_macinfo_section;
-static asection *dwarf_str_section;
-static asection *dwarf_ranges_section;
-asection *dwarf_frame_section;
-asection *dwarf_eh_frame_section;
-
/* names of the debugging sections */
/* Note that if the debugging section has been compressed, it might
ENUM_BITFIELD(dwarf_form) form : 16;
};
+/* Additional GDB-specific attribute forms. */
+enum
+ {
+ /* A string which has been updated to GDB's internal
+ representation (e.g. converted to canonical form) and does not
+ need to be updated again. */
+ GDB_FORM_cached_string = 0xff
+ };
+
/* Attributes have a name and a value */
struct attribute
{
CORE_ADDR *lowpc, CORE_ADDR *highpc,
int need_pc, struct dwarf2_cu *cu);
+static void add_partial_module (struct partial_die_info *pdi, CORE_ADDR *lowpc,
+ CORE_ADDR *highpc, int need_pc,
+ struct dwarf2_cu *cu);
+
static void add_partial_enumeration (struct partial_die_info *enum_pdi,
struct dwarf2_cu *cu);
static void psymtab_to_symtab_1 (struct partial_symtab *);
-gdb_byte *dwarf2_read_section (struct objfile *, asection *);
-
static void dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu);
static void dwarf2_free_abbrev_table (void *);
static void read_namespace (struct die_info *die, struct dwarf2_cu *);
+static void read_module (struct die_info *die, struct dwarf2_cu *cu);
+
static const char *namespace_name (struct die_info *die,
int *is_anonymous, struct dwarf2_cu *);
static char *dwarf2_linkage_name (struct die_info *, struct dwarf2_cu *);
+static char *dwarf2_canonicalize_name (char *, struct dwarf2_cu *,
+ struct obstack *);
+
static char *dwarf2_name (struct die_info *die, struct dwarf2_cu *);
static struct die_info *dwarf2_extension (struct die_info *die,
set_objfile_data (objfile, dwarf2_objfile_data_key, data);
dwarf2_per_objfile = data;
- dwarf_info_section = 0;
- dwarf_abbrev_section = 0;
- dwarf_line_section = 0;
- dwarf_str_section = 0;
- dwarf_macinfo_section = 0;
- dwarf_frame_section = 0;
- dwarf_eh_frame_section = 0;
- dwarf_ranges_section = 0;
- dwarf_loc_section = 0;
-
bfd_map_over_sections (objfile->obfd, dwarf2_locate_sections, NULL);
- return (dwarf_info_section != NULL && dwarf_abbrev_section != NULL);
+ return (data->info.asection != NULL && data->abbrev.asection != NULL);
}
/* When loading sections, we can either look for ".<name>", or for
* ".z<name>", which indicates a compressed section. */
static int
-section_is_p (asection *sectp, const char *name)
+section_is_p (const char *section_name, const char *name)
{
- return ((sectp->name[0] == '.'
- && strcmp (sectp->name + 1, name) == 0)
- || (sectp->name[0] == '.' && sectp->name[1] == 'z'
- && strcmp (sectp->name + 2, name) == 0));
+ return (section_name[0] == '.'
+ && (strcmp (section_name + 1, name) == 0
+ || (section_name[1] == 'z'
+ && strcmp (section_name + 2, name) == 0)));
}
/* This function is mapped across the sections and remembers the
static void
dwarf2_locate_sections (bfd *abfd, asection *sectp, void *ignore_ptr)
{
- if (section_is_p (sectp, INFO_SECTION))
+ if (section_is_p (sectp->name, INFO_SECTION))
{
- dwarf2_per_objfile->info_size = bfd_get_section_size (sectp);
- dwarf_info_section = sectp;
+ dwarf2_per_objfile->info.asection = sectp;
+ dwarf2_per_objfile->info.size = bfd_get_section_size (sectp);
}
- else if (section_is_p (sectp, ABBREV_SECTION))
+ else if (section_is_p (sectp->name, ABBREV_SECTION))
{
- dwarf2_per_objfile->abbrev_size = bfd_get_section_size (sectp);
- dwarf_abbrev_section = sectp;
+ dwarf2_per_objfile->abbrev.asection = sectp;
+ dwarf2_per_objfile->abbrev.size = bfd_get_section_size (sectp);
}
- else if (section_is_p (sectp, LINE_SECTION))
+ else if (section_is_p (sectp->name, LINE_SECTION))
{
- dwarf2_per_objfile->line_size = bfd_get_section_size (sectp);
- dwarf_line_section = sectp;
+ dwarf2_per_objfile->line.asection = sectp;
+ dwarf2_per_objfile->line.size = bfd_get_section_size (sectp);
}
- else if (section_is_p (sectp, PUBNAMES_SECTION))
+ else if (section_is_p (sectp->name, PUBNAMES_SECTION))
{
- dwarf2_per_objfile->pubnames_size = bfd_get_section_size (sectp);
- dwarf_pubnames_section = sectp;
+ dwarf2_per_objfile->pubnames.asection = sectp;
+ dwarf2_per_objfile->pubnames.size = bfd_get_section_size (sectp);
}
- else if (section_is_p (sectp, ARANGES_SECTION))
+ else if (section_is_p (sectp->name, ARANGES_SECTION))
{
- dwarf2_per_objfile->aranges_size = bfd_get_section_size (sectp);
- dwarf_aranges_section = sectp;
+ dwarf2_per_objfile->aranges.asection = sectp;
+ dwarf2_per_objfile->aranges.size = bfd_get_section_size (sectp);
}
- else if (section_is_p (sectp, LOC_SECTION))
+ else if (section_is_p (sectp->name, LOC_SECTION))
{
- dwarf2_per_objfile->loc_size = bfd_get_section_size (sectp);
- dwarf_loc_section = sectp;
+ dwarf2_per_objfile->loc.asection = sectp;
+ dwarf2_per_objfile->loc.size = bfd_get_section_size (sectp);
}
- else if (section_is_p (sectp, MACINFO_SECTION))
+ else if (section_is_p (sectp->name, MACINFO_SECTION))
{
- dwarf2_per_objfile->macinfo_size = bfd_get_section_size (sectp);
- dwarf_macinfo_section = sectp;
+ dwarf2_per_objfile->macinfo.asection = sectp;
+ dwarf2_per_objfile->macinfo.size = bfd_get_section_size (sectp);
}
- else if (section_is_p (sectp, STR_SECTION))
+ else if (section_is_p (sectp->name, STR_SECTION))
{
- dwarf2_per_objfile->str_size = bfd_get_section_size (sectp);
- dwarf_str_section = sectp;
+ dwarf2_per_objfile->str.asection = sectp;
+ dwarf2_per_objfile->str.size = bfd_get_section_size (sectp);
}
- else if (section_is_p (sectp, FRAME_SECTION))
+ else if (section_is_p (sectp->name, FRAME_SECTION))
{
- dwarf2_per_objfile->frame_size = bfd_get_section_size (sectp);
- dwarf_frame_section = sectp;
+ dwarf2_per_objfile->frame.asection = sectp;
+ dwarf2_per_objfile->frame.size = bfd_get_section_size (sectp);
}
- else if (section_is_p (sectp, EH_FRAME_SECTION))
+ else if (section_is_p (sectp->name, EH_FRAME_SECTION))
{
flagword aflag = bfd_get_section_flags (ignore_abfd, sectp);
if (aflag & SEC_HAS_CONTENTS)
{
- dwarf2_per_objfile->eh_frame_size = bfd_get_section_size (sectp);
- dwarf_eh_frame_section = sectp;
+ dwarf2_per_objfile->eh_frame.asection = sectp;
+ dwarf2_per_objfile->eh_frame.size = bfd_get_section_size (sectp);
}
}
- else if (section_is_p (sectp, RANGES_SECTION))
+ else if (section_is_p (sectp->name, RANGES_SECTION))
{
- dwarf2_per_objfile->ranges_size = bfd_get_section_size (sectp);
- dwarf_ranges_section = sectp;
+ dwarf2_per_objfile->ranges.asection = sectp;
+ dwarf2_per_objfile->ranges.size = bfd_get_section_size (sectp);
}
-
+
if ((bfd_get_section_flags (abfd, sectp) & SEC_LOAD)
&& bfd_section_vma (abfd, sectp) == 0)
dwarf2_per_objfile->has_section_at_zero = 1;
}
-/* This function is called after decompressing a section, so
- dwarf2_per_objfile can record its new, uncompressed size. */
+/* Decompress a section that was compressed using zlib. Store the
+ decompressed buffer, and its size, in OUTBUF and OUTSIZE. */
static void
-dwarf2_resize_section (asection *sectp, bfd_size_type new_size)
-{
- if (section_is_p (sectp, INFO_SECTION))
- dwarf2_per_objfile->info_size = new_size;
- else if (section_is_p (sectp, ABBREV_SECTION))
- dwarf2_per_objfile->abbrev_size = new_size;
- else if (section_is_p (sectp, LINE_SECTION))
- dwarf2_per_objfile->line_size = new_size;
- else if (section_is_p (sectp, PUBNAMES_SECTION))
- dwarf2_per_objfile->pubnames_size = new_size;
- else if (section_is_p (sectp, ARANGES_SECTION))
- dwarf2_per_objfile->aranges_size = new_size;
- else if (section_is_p (sectp, LOC_SECTION))
- dwarf2_per_objfile->loc_size = new_size;
- else if (section_is_p (sectp, MACINFO_SECTION))
- dwarf2_per_objfile->macinfo_size = new_size;
- else if (section_is_p (sectp, STR_SECTION))
- dwarf2_per_objfile->str_size = new_size;
- else if (section_is_p (sectp, FRAME_SECTION))
- dwarf2_per_objfile->frame_size = new_size;
- else if (section_is_p (sectp, EH_FRAME_SECTION))
- dwarf2_per_objfile->eh_frame_size = new_size;
- else if (section_is_p (sectp, RANGES_SECTION))
- dwarf2_per_objfile->ranges_size = new_size;
- else
- internal_error (__FILE__, __LINE__,
- _("dwarf2_resize_section: missing section_is_p check: %s"),
- sectp->name);
+zlib_decompress_section (struct objfile *objfile, asection *sectp,
+ gdb_byte **outbuf, bfd_size_type *outsize)
+{
+ bfd *abfd = objfile->obfd;
+#ifndef HAVE_ZLIB_H
+ error (_("Support for zlib-compressed DWARF data (from '%s') "
+ "is disabled in this copy of GDB"),
+ bfd_get_filename (abfd));
+#else
+ bfd_size_type compressed_size = bfd_get_section_size (sectp);
+ gdb_byte *compressed_buffer = xmalloc (compressed_size);
+ bfd_size_type uncompressed_size;
+ gdb_byte *uncompressed_buffer;
+ z_stream strm;
+ int rc;
+ int header_size = 12;
+
+ if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0
+ || bfd_bread (compressed_buffer, compressed_size, abfd) != compressed_size)
+ error (_("Dwarf Error: Can't read DWARF data from '%s'"),
+ bfd_get_filename (abfd));
+
+ /* Read the zlib header. In this case, it should be "ZLIB" followed
+ by the uncompressed section size, 8 bytes in big-endian order. */
+ if (compressed_size < header_size
+ || strncmp (compressed_buffer, "ZLIB", 4) != 0)
+ error (_("Dwarf Error: Corrupt DWARF ZLIB header from '%s'"),
+ bfd_get_filename (abfd));
+ uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[11];
+
+ /* It is possible the section consists of several compressed
+ buffers concatenated together, so we uncompress in a loop. */
+ strm.zalloc = NULL;
+ strm.zfree = NULL;
+ strm.opaque = NULL;
+ strm.avail_in = compressed_size - header_size;
+ strm.next_in = (Bytef*) compressed_buffer + header_size;
+ strm.avail_out = uncompressed_size;
+ uncompressed_buffer = obstack_alloc (&objfile->objfile_obstack,
+ uncompressed_size);
+ rc = inflateInit (&strm);
+ while (strm.avail_in > 0)
+ {
+ if (rc != Z_OK)
+ error (_("Dwarf Error: setting up DWARF uncompression in '%s': %d"),
+ bfd_get_filename (abfd), rc);
+ strm.next_out = ((Bytef*) uncompressed_buffer
+ + (uncompressed_size - strm.avail_out));
+ rc = inflate (&strm, Z_FINISH);
+ if (rc != Z_STREAM_END)
+ error (_("Dwarf Error: zlib error uncompressing from '%s': %d"),
+ bfd_get_filename (abfd), rc);
+ rc = inflateReset (&strm);
+ }
+ rc = inflateEnd (&strm);
+ if (rc != Z_OK
+ || strm.avail_out != 0)
+ error (_("Dwarf Error: concluding DWARF uncompression in '%s': %d"),
+ bfd_get_filename (abfd), rc);
+
+ xfree (compressed_buffer);
+ *outbuf = uncompressed_buffer;
+ *outsize = uncompressed_size;
+#endif
}
-/* Build a partial symbol table. */
+/* Read the contents of the section SECTP from object file specified by
+ OBJFILE, store info about the section into INFO.
+ If the section is compressed, uncompress it before returning. */
-void
-dwarf2_build_psymtabs (struct objfile *objfile, int mainline)
+static void
+dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info)
{
- /* We definitely need the .debug_info and .debug_abbrev sections */
+ bfd *abfd = objfile->obfd;
+ asection *sectp = info->asection;
+ gdb_byte *buf, *retbuf;
+ unsigned char header[4];
- dwarf2_per_objfile->info_buffer = dwarf2_read_section (objfile, dwarf_info_section);
- dwarf2_per_objfile->abbrev_buffer = dwarf2_read_section (objfile, dwarf_abbrev_section);
+ info->buffer = NULL;
+ info->was_mmapped = 0;
- if (dwarf_line_section)
- dwarf2_per_objfile->line_buffer = dwarf2_read_section (objfile, dwarf_line_section);
- else
- dwarf2_per_objfile->line_buffer = NULL;
+ if (info->asection == NULL || info->size == 0)
+ return;
- if (dwarf_str_section)
- dwarf2_per_objfile->str_buffer = dwarf2_read_section (objfile, dwarf_str_section);
- else
- dwarf2_per_objfile->str_buffer = NULL;
+ /* Check if the file has a 4-byte header indicating compression. */
+ if (info->size > sizeof (header)
+ && bfd_seek (abfd, sectp->filepos, SEEK_SET) == 0
+ && bfd_bread (header, sizeof (header), abfd) == sizeof (header))
+ {
+ /* Upon decompression, update the buffer and its size. */
+ if (strncmp (header, "ZLIB", sizeof (header)) == 0)
+ {
+ zlib_decompress_section (objfile, sectp, &info->buffer,
+ &info->size);
+ return;
+ }
+ }
- if (dwarf_macinfo_section)
- dwarf2_per_objfile->macinfo_buffer = dwarf2_read_section (objfile,
- dwarf_macinfo_section);
- else
- dwarf2_per_objfile->macinfo_buffer = NULL;
+#ifdef HAVE_MMAP
+ if (pagesize == 0)
+ pagesize = getpagesize ();
- if (dwarf_ranges_section)
- dwarf2_per_objfile->ranges_buffer = dwarf2_read_section (objfile, dwarf_ranges_section);
- else
- dwarf2_per_objfile->ranges_buffer = NULL;
+ /* Only try to mmap sections which are large enough: we don't want to
+ waste space due to fragmentation. Also, only try mmap for sections
+ without relocations. */
- if (dwarf_loc_section)
- dwarf2_per_objfile->loc_buffer = dwarf2_read_section (objfile, dwarf_loc_section);
+ 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);
+
+ if (retbuf != MAP_FAILED)
+ {
+ info->was_mmapped = 1;
+ info->buffer = retbuf + (sectp->filepos & (pagesize - 1)) ;
+ return;
+ }
+ }
+#endif
+
+ /* If we get here, we are a normal, not-compressed section. */
+ info->buffer = buf
+ = obstack_alloc (&objfile->objfile_obstack, info->size);
+
+ /* When debugging .o files, we may need to apply relocations; see
+ http://sourceware.org/ml/gdb-patches/2002-04/msg00136.html .
+ We never compress sections in .o files, so we only need to
+ try this when the section is not compressed. */
+ retbuf = symfile_relocate_debug_section (abfd, sectp, buf);
+ if (retbuf != NULL)
+ {
+ info->buffer = retbuf;
+ return;
+ }
+
+ if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0
+ || bfd_bread (buf, info->size, abfd) != info->size)
+ error (_("Dwarf Error: Can't read DWARF data from '%s'"),
+ bfd_get_filename (abfd));
+}
+
+/* Fill in SECTP, BUFP and SIZEP with section info, given OBJFILE and
+ SECTION_NAME. */
+
+void
+dwarf2_get_section_info (struct objfile *objfile, const char *section_name,
+ asection **sectp, gdb_byte **bufp,
+ bfd_size_type *sizep)
+{
+ struct dwarf2_per_objfile *data
+ = objfile_data (objfile, dwarf2_objfile_data_key);
+ struct dwarf2_section_info *info;
+ 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
- dwarf2_per_objfile->loc_buffer = NULL;
+ gdb_assert (0);
+
+ if (info->asection != NULL && info->size != 0 && info->buffer == NULL)
+ /* We haven't read this section in yet. Do it now. */
+ dwarf2_read_section (objfile, info);
+
+ *sectp = info->asection;
+ *bufp = info->buffer;
+ *sizep = info->size;
+}
+
+/* Build a partial symbol table. */
+
+void
+dwarf2_build_psymtabs (struct objfile *objfile, int mainline)
+{
+ dwarf2_read_section (objfile, &dwarf2_per_objfile->info);
+ dwarf2_read_section (objfile, &dwarf2_per_objfile->abbrev);
+ dwarf2_read_section (objfile, &dwarf2_per_objfile->line);
+ dwarf2_read_section (objfile, &dwarf2_per_objfile->str);
+ dwarf2_read_section (objfile, &dwarf2_per_objfile->macinfo);
+ dwarf2_read_section (objfile, &dwarf2_per_objfile->ranges);
+ dwarf2_read_section (objfile, &dwarf2_per_objfile->loc);
+ dwarf2_read_section (objfile, &dwarf2_per_objfile->eh_frame);
+ dwarf2_read_section (objfile, &dwarf2_per_objfile->frame);
if (mainline
|| (objfile->global_psymbols.size == 0
pubnames_buffer = dwarf2_read_section (objfile,
dwarf_pubnames_section);
pubnames_ptr = pubnames_buffer;
- while ((pubnames_ptr - pubnames_buffer) < dwarf2_per_objfile->pubnames_size)
+ while ((pubnames_ptr - pubnames_buffer) < dwarf2_per_objfile->pubnames.size)
{
unsigned int bytes_read;
"(is %d, should be %d) [in module %s]"), header->version,
2, bfd_get_filename (abfd));
- if (header->abbrev_offset >= dwarf2_per_objfile->abbrev_size)
+ if (header->abbrev_offset >= dwarf2_per_objfile->abbrev.size)
error (_("Dwarf Error: bad offset (0x%lx) in compilation unit header "
"(offset 0x%lx + 6) [in module %s]"),
(long) header->abbrev_offset,
- (long) (beg_of_comp_unit - dwarf2_per_objfile->info_buffer),
+ (long) (beg_of_comp_unit - dwarf2_per_objfile->info.buffer),
bfd_get_filename (abfd));
if (beg_of_comp_unit + header->length + header->initial_length_size
- > dwarf2_per_objfile->info_buffer + dwarf2_per_objfile->info_size)
+ > dwarf2_per_objfile->info.buffer + dwarf2_per_objfile->info.size)
error (_("Dwarf Error: bad length (0x%lx) in compilation unit header "
"(offset 0x%lx + 0) [in module %s]"),
(long) header->length,
- (long) (beg_of_comp_unit - dwarf2_per_objfile->info_buffer),
+ (long) (beg_of_comp_unit - dwarf2_per_objfile->info.buffer),
bfd_get_filename (abfd));
return info_ptr;
struct cleanup *back_to;
CORE_ADDR baseaddr;
- info_ptr = dwarf2_per_objfile->info_buffer;
+ info_ptr = dwarf2_per_objfile->info.buffer;
/* Any cached compilation units will be linked by the per-objfile
read_in_chain. Make sure to free them when we're done. */
For this loop condition, simply checking whether there's any data
left at all should be sufficient. */
- while (info_ptr < (dwarf2_per_objfile->info_buffer
- + dwarf2_per_objfile->info_size))
+ while (info_ptr < (dwarf2_per_objfile->info.buffer
+ + dwarf2_per_objfile->info.size))
{
struct cleanup *back_to_inner;
struct dwarf2_cu cu;
info_ptr = partial_read_comp_unit_head (&cu.header, info_ptr, abfd);
/* Complete the cu_header */
- cu.header.offset = beg_of_comp_unit - dwarf2_per_objfile->info_buffer;
+ cu.header.offset = beg_of_comp_unit - dwarf2_per_objfile->info.buffer;
cu.header.first_die_offset = info_ptr - beg_of_comp_unit;
cu.list_in_scope = &file_symbols;
unsigned int bytes_read;
struct cleanup *back_to;
- info_ptr = dwarf2_per_objfile->info_buffer + this_cu->offset;
+ info_ptr = dwarf2_per_objfile->info.buffer + this_cu->offset;
beg_of_comp_unit = info_ptr;
cu = xmalloc (sizeof (struct dwarf2_cu));
info_ptr = partial_read_comp_unit_head (&cu->header, info_ptr, abfd);
/* Complete the cu_header. */
- cu->header.offset = beg_of_comp_unit - dwarf2_per_objfile->info_buffer;
+ cu->header.offset = beg_of_comp_unit - dwarf2_per_objfile->info.buffer;
cu->header.first_die_offset = info_ptr - beg_of_comp_unit;
/* Read the abbrevs for this compilation unit into a table. */
int n_allocated;
int n_comp_units;
struct dwarf2_per_cu_data **all_comp_units;
- gdb_byte *info_ptr = dwarf2_per_objfile->info_buffer;
+ gdb_byte *info_ptr = dwarf2_per_objfile->info.buffer;
n_comp_units = 0;
n_allocated = 10;
all_comp_units = xmalloc (n_allocated
* sizeof (struct dwarf2_per_cu_data *));
- while (info_ptr < dwarf2_per_objfile->info_buffer + dwarf2_per_objfile->info_size)
+ while (info_ptr < dwarf2_per_objfile->info.buffer + dwarf2_per_objfile->info.size)
{
unsigned int length, initial_length_size;
gdb_byte *beg_of_comp_unit;
struct dwarf2_per_cu_data *this_cu;
unsigned int offset;
- offset = info_ptr - dwarf2_per_objfile->info_buffer;
+ offset = info_ptr - dwarf2_per_objfile->info.buffer;
/* Read just enough information to find out where the next
compilation unit is. */
case DW_TAG_namespace:
add_partial_namespace (pdi, lowpc, highpc, need_pc, cu);
break;
+ case DW_TAG_module:
+ add_partial_module (pdi, lowpc, highpc, need_pc, cu);
+ break;
default:
break;
}
scan_partial_symbols (pdi->die_child, lowpc, highpc, need_pc, cu);
}
+/* Read a partial die corresponding to a Fortran module. */
+
+static void
+add_partial_module (struct partial_die_info *pdi, CORE_ADDR *lowpc,
+ CORE_ADDR *highpc, int need_pc, struct dwarf2_cu *cu)
+{
+ /* Now scan partial symbols in that module.
+
+ FIXME: Support the separate Fortran module namespaces. */
+
+ if (pdi->has_children)
+ scan_partial_symbols (pdi->die_child, lowpc, highpc, need_pc, cu);
+}
+
/* Read a partial die corresponding to a subprogram and create a partial
symbol for that subprogram. When the CU language allows it, this
routine also defines a partial symbol for each nested subprogram
if (attr.form == DW_FORM_ref_addr)
complaint (&symfile_complaints, _("ignoring absolute DW_AT_sibling"));
else
- return dwarf2_per_objfile->info_buffer
+ return dwarf2_per_objfile->info.buffer
+ dwarf2_get_ref_die_offset (&attr);
}
dwarf2_per_objfile = objfile_data (pst->objfile,
dwarf2_objfile_data_key);
+ /* If this psymtab is constructed from a debug-only objfile, the
+ has_section_at_zero flag will not necessarily be correct. We
+ can get the correct value for this flag by looking at the data
+ associated with the (presumably stripped) associated objfile. */
+ if (pst->objfile->separate_debug_objfile_backlink)
+ {
+ struct dwarf2_per_objfile *dpo_backlink
+ = objfile_data (pst->objfile->separate_debug_objfile_backlink,
+ dwarf2_objfile_data_key);
+ dwarf2_per_objfile->has_section_at_zero
+ = dpo_backlink->has_section_at_zero;
+ }
+
psymtab_to_symtab_1 (pst);
/* Finish up the debug error message. */
/* Set local variables from the partial symbol table info. */
offset = per_cu->offset;
- info_ptr = dwarf2_per_objfile->info_buffer + offset;
+ info_ptr = dwarf2_per_objfile->info.buffer + offset;
cu = xmalloc (sizeof (struct dwarf2_cu));
memset (cu, 0, sizeof (struct dwarf2_cu));
case DW_TAG_base_type:
case DW_TAG_subrange_type:
+ case DW_TAG_typedef:
/* Add a typedef symbol for the type definition, if it has a
DW_AT_name. */
new_symbol (die, read_type_die (die, cu), cu);
processing_has_namespace_info = 1;
read_namespace (die, cu);
break;
+ case DW_TAG_module:
+ read_module (die, cu);
+ break;
case DW_TAG_imported_declaration:
case DW_TAG_imported_module:
/* FIXME: carlton/2002-10-16: Eventually, we should use the
cu->last_fn = thisfn;
}
+/* qsort helper for inherit_abstract_dies. */
+
+static int
+unsigned_int_compar (const void *ap, const void *bp)
+{
+ unsigned int a = *(unsigned int *) ap;
+ unsigned int b = *(unsigned int *) bp;
+
+ return (a > b) - (b > a);
+}
+
+/* DW_AT_abstract_origin inherits whole DIEs (not just their attributes).
+ Inherit only the children of the DW_AT_abstract_origin DIE not being already
+ referenced by DW_AT_abstract_origin from the children of the current DIE. */
+
+static void
+inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct die_info *child_die;
+ unsigned die_children_count;
+ /* CU offsets which were referenced by children of the current DIE. */
+ unsigned *offsets;
+ unsigned *offsets_end, *offsetp;
+ /* Parent of DIE - referenced by DW_AT_abstract_origin. */
+ struct die_info *origin_die;
+ /* Iterator of the ORIGIN_DIE children. */
+ struct die_info *origin_child_die;
+ struct cleanup *cleanups;
+ struct attribute *attr;
+
+ attr = dwarf2_attr (die, DW_AT_abstract_origin, cu);
+ if (!attr)
+ return;
+
+ origin_die = follow_die_ref (die, attr, &cu);
+ if (die->tag != origin_die->tag)
+ complaint (&symfile_complaints,
+ _("DIE 0x%x and its abstract origin 0x%x have different tags"),
+ die->offset, origin_die->offset);
+
+ child_die = die->child;
+ die_children_count = 0;
+ while (child_die && child_die->tag)
+ {
+ child_die = sibling_die (child_die);
+ die_children_count++;
+ }
+ offsets = xmalloc (sizeof (*offsets) * die_children_count);
+ cleanups = make_cleanup (xfree, offsets);
+
+ offsets_end = offsets;
+ child_die = die->child;
+ while (child_die && child_die->tag)
+ {
+ attr = dwarf2_attr (child_die, DW_AT_abstract_origin, cu);
+ /* According to DWARF3 3.3.8.2 #3 new entries without their abstract
+ counterpart may exist. */
+ if (attr)
+ {
+ struct die_info *child_origin_die;
+
+ child_origin_die = follow_die_ref (child_die, attr, &cu);
+ if (child_die->tag != child_origin_die->tag)
+ complaint (&symfile_complaints,
+ _("Child DIE 0x%x and its abstract origin 0x%x have "
+ "different tags"), child_die->offset,
+ child_origin_die->offset);
+ *offsets_end++ = child_origin_die->offset;
+ }
+ child_die = sibling_die (child_die);
+ }
+ qsort (offsets, offsets_end - offsets, sizeof (*offsets),
+ unsigned_int_compar);
+ for (offsetp = offsets + 1; offsetp < offsets_end; offsetp++)
+ if (offsetp[-1] == *offsetp)
+ complaint (&symfile_complaints, _("Multiple children of DIE 0x%x refer "
+ "to DIE 0x%x as their abstract origin"),
+ die->offset, *offsetp);
+
+ offsetp = offsets;
+ origin_child_die = origin_die->child;
+ while (origin_child_die && origin_child_die->tag)
+ {
+ /* Is ORIGIN_CHILD_DIE referenced by any of the DIE children? */
+ while (offsetp < offsets_end && *offsetp < origin_child_die->offset)
+ offsetp++;
+ if (offsetp >= offsets_end || *offsetp > origin_child_die->offset)
+ {
+ /* Found that ORIGIN_CHILD_DIE is really not referenced. */
+ process_die (origin_child_die, cu);
+ }
+ origin_child_die = sibling_die (origin_child_die);
+ }
+
+ do_cleanups (cleanups);
+}
+
static void
read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
{
}
}
+ inherit_abstract_dies (die, cu);
+
new = pop_context ();
/* Make a block for the local symbols within. */
block = finish_block (new->name, &local_symbols, new->old_blocks,
found_base = cu->base_known;
base = cu->base_address;
- if (offset >= dwarf2_per_objfile->ranges_size)
+ if (offset >= dwarf2_per_objfile->ranges.size)
{
complaint (&symfile_complaints,
_("Offset %d out of bounds for DW_AT_ranges attribute"),
offset);
return 0;
}
- buffer = dwarf2_per_objfile->ranges_buffer + offset;
+ buffer = dwarf2_per_objfile->ranges.buffer + offset;
/* Read in the largest possible address. */
marker = read_address (obfd, buffer, cu, &dummy);
/* The value of the DW_AT_ranges attribute is the offset of the
address range list in the .debug_ranges section. */
unsigned long offset = DW_UNSND (attr);
- gdb_byte *buffer = dwarf2_per_objfile->ranges_buffer + offset;
+ gdb_byte *buffer = dwarf2_per_objfile->ranges.buffer + offset;
/* For some target architectures, but not others, the
read_address function sign-extends the addresses it returns.
CORE_ADDR base = cu->base_address;
int base_known = cu->base_known;
- if (offset >= dwarf2_per_objfile->ranges_size)
+ if (offset >= dwarf2_per_objfile->ranges.size)
{
complaint (&symfile_complaints,
_("Offset %lu out of bounds for DW_AT_ranges attribute"),
}
}
+/* Read a Fortran module. */
+
+static void
+read_module (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct die_info *child_die = die->child;
+
+ /* FIXME: Support the separate Fortran module namespaces. */
+
+ while (child_die && child_die->tag)
+ {
+ process_die (child_die, cu);
+ child_die = sibling_die (child_die);
+ }
+}
+
/* Return the name of the namespace represented by DIE. Set
*IS_ANONYMOUS to tell whether or not the namespace is an anonymous
namespace. */
read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
struct type *type, *range_type, *index_type, *char_type;
struct attribute *attr;
unsigned int length;
index_type = builtin_type_int32;
range_type = create_range_type (NULL, index_type, 1, length);
- type = create_string_type (NULL, range_type);
+ char_type = language_string_char_type (cu->language_defn, gdbarch);
+ type = create_string_type (NULL, char_type, range_type);
return set_die_type (die, type, cu);
}
struct attribute *attr;
type = die_type (die, cu);
- ftype = make_function_type (type, (struct type **) 0);
+ ftype = make_function_type (type, (struct type **) 0, cu->objfile);
/* All functions in C++, Pascal and Java have prototypes. */
attr = dwarf2_attr (die, DW_AT_prototyped, cu);
type_flags |= TYPE_FLAG_UNSIGNED;
break;
case DW_ATE_signed_char:
- if (cu->language == language_ada || cu->language == language_m2)
+ if (cu->language == language_ada || cu->language == language_m2
+ || cu->language == language_pascal)
code = TYPE_CODE_CHAR;
break;
case DW_ATE_unsigned_char:
- if (cu->language == language_ada || cu->language == language_m2)
+ if (cu->language == language_ada || cu->language == language_m2
+ || cu->language == language_pascal)
code = TYPE_CODE_CHAR;
type_flags |= TYPE_FLAG_UNSIGNED;
break;
}
}
-/* Decompress a section that was compressed using zlib. Store the
- decompressed buffer, and its size, in OUTBUF and OUTSIZE. */
-
-static void
-zlib_decompress_section (struct objfile *objfile, asection *sectp,
- gdb_byte **outbuf, bfd_size_type *outsize)
-{
- bfd *abfd = objfile->obfd;
-#ifndef HAVE_ZLIB_H
- error (_("Support for zlib-compressed DWARF data (from '%s') "
- "is disabled in this copy of GDB"),
- bfd_get_filename (abfd));
-#else
- bfd_size_type compressed_size = bfd_get_section_size (sectp);
- gdb_byte *compressed_buffer = xmalloc (compressed_size);
- bfd_size_type uncompressed_size;
- gdb_byte *uncompressed_buffer;
- z_stream strm;
- int rc;
- int header_size = 12;
-
- if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0
- || bfd_bread (compressed_buffer, compressed_size, abfd) != compressed_size)
- error (_("Dwarf Error: Can't read DWARF data from '%s'"),
- bfd_get_filename (abfd));
-
- /* Read the zlib header. In this case, it should be "ZLIB" followed
- by the uncompressed section size, 8 bytes in big-endian order. */
- if (compressed_size < header_size
- || strncmp (compressed_buffer, "ZLIB", 4) != 0)
- error (_("Dwarf Error: Corrupt DWARF ZLIB header from '%s'"),
- bfd_get_filename (abfd));
- uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
- uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
- uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
- uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
- uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
- uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
- uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
- uncompressed_size += compressed_buffer[11];
-
- /* It is possible the section consists of several compressed
- buffers concatenated together, so we uncompress in a loop. */
- strm.zalloc = NULL;
- strm.zfree = NULL;
- strm.opaque = NULL;
- strm.avail_in = compressed_size - header_size;
- strm.next_in = (Bytef*) compressed_buffer + header_size;
- strm.avail_out = uncompressed_size;
- uncompressed_buffer = obstack_alloc (&objfile->objfile_obstack,
- uncompressed_size);
- rc = inflateInit (&strm);
- while (strm.avail_in > 0)
- {
- if (rc != Z_OK)
- error (_("Dwarf Error: setting up DWARF uncompression in '%s': %d"),
- bfd_get_filename (abfd), rc);
- strm.next_out = ((Bytef*) uncompressed_buffer
- + (uncompressed_size - strm.avail_out));
- rc = inflate (&strm, Z_FINISH);
- if (rc != Z_STREAM_END)
- error (_("Dwarf Error: zlib error uncompressing from '%s': %d"),
- bfd_get_filename (abfd), rc);
- rc = inflateReset (&strm);
- }
- rc = inflateEnd (&strm);
- if (rc != Z_OK
- || strm.avail_out != 0)
- error (_("Dwarf Error: concluding DWARF uncompression in '%s': %d"),
- bfd_get_filename (abfd), rc);
-
- xfree (compressed_buffer);
- *outbuf = uncompressed_buffer;
- *outsize = uncompressed_size;
-#endif
-}
-
-
-/* Read the contents of the section at OFFSET and of size SIZE from the
- object file specified by OBJFILE into the objfile_obstack and return it.
- If the section is compressed, uncompress it before returning. */
-
-gdb_byte *
-dwarf2_read_section (struct objfile *objfile, asection *sectp)
-{
- bfd *abfd = objfile->obfd;
- gdb_byte *buf, *retbuf;
- bfd_size_type size = bfd_get_section_size (sectp);
- unsigned char header[4];
-
- if (size == 0)
- return NULL;
-
- /* Check if the file has a 4-byte header indicating compression. */
- if (size > sizeof (header)
- && bfd_seek (abfd, sectp->filepos, SEEK_SET) == 0
- && bfd_bread (header, sizeof (header), abfd) == sizeof (header))
- {
- /* Upon decompression, update the buffer and its size. */
- if (strncmp (header, "ZLIB", sizeof (header)) == 0)
- {
- zlib_decompress_section (objfile, sectp, &buf, &size);
- dwarf2_resize_section (sectp, size);
- return buf;
- }
- }
-
- /* If we get here, we are a normal, not-compressed section. */
- buf = obstack_alloc (&objfile->objfile_obstack, size);
- /* When debugging .o files, we may need to apply relocations; see
- http://sourceware.org/ml/gdb-patches/2002-04/msg00136.html .
- We never compress sections in .o files, so we only need to
- try this when the section is not compressed. */
- retbuf = symfile_relocate_debug_section (abfd, sectp, buf);
- if (retbuf != NULL)
- return retbuf;
-
- if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0
- || bfd_bread (buf, size, abfd) != size)
- error (_("Dwarf Error: Can't read DWARF data from '%s'"),
- bfd_get_filename (abfd));
-
- return buf;
-}
-
/* In DWARF version 2, the description of the debugging information is
stored in a separate .debug_abbrev section. Before we read any
dies from a section we read in all abbreviations and install them
memset (cu->dwarf2_abbrevs, 0,
ABBREV_HASH_SIZE * sizeof (struct abbrev_info *));
- abbrev_ptr = dwarf2_per_objfile->abbrev_buffer + cu_header->abbrev_offset;
+ abbrev_ptr = dwarf2_per_objfile->abbrev.buffer + cu_header->abbrev_offset;
abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
abbrev_ptr += bytes_read;
already read (which means we are about to read the abbreviations
for the next compile unit) or if the end of the abbreviation
table is reached. */
- if ((unsigned int) (abbrev_ptr - dwarf2_per_objfile->abbrev_buffer)
- >= dwarf2_per_objfile->abbrev_size)
+ if ((unsigned int) (abbrev_ptr - dwarf2_per_objfile->abbrev.buffer)
+ >= dwarf2_per_objfile->abbrev.size)
break;
abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
abbrev_ptr += bytes_read;
memset (part_die, 0, sizeof (struct partial_die_info));
- part_die->offset = info_ptr - dwarf2_per_objfile->info_buffer;
+ part_die->offset = info_ptr - dwarf2_per_objfile->info.buffer;
info_ptr += abbrev_len;
switch (attr.name)
{
case DW_AT_name:
-
- /* Prefer DW_AT_MIPS_linkage_name over DW_AT_name. */
- if (part_die->name == NULL)
- part_die->name = DW_STRING (&attr);
+ switch (part_die->tag)
+ {
+ case DW_TAG_compile_unit:
+ /* Compilation units have a DW_AT_name that is a filename, not
+ a source language identifier. */
+ case DW_TAG_enumeration_type:
+ case DW_TAG_enumerator:
+ /* These tags always have simple identifiers already; no need
+ to canonicalize them. */
+ part_die->name = DW_STRING (&attr);
+ break;
+ default:
+ part_die->name
+ = dwarf2_canonicalize_name (DW_STRING (&attr), cu,
+ &cu->comp_unit_obstack);
+ break;
+ }
break;
case DW_AT_comp_dir:
if (part_die->dirname == NULL)
if (attr.form == DW_FORM_ref_addr)
complaint (&symfile_complaints, _("ignoring absolute DW_AT_sibling"));
else
- part_die->sibling = dwarf2_per_objfile->info_buffer
+ part_die->sibling = dwarf2_per_objfile->info.buffer
+ dwarf2_get_ref_die_offset (&attr);
break;
case DW_AT_stmt_list:
dwarf2_read_abbrevs (per_cu->cu->objfile->obfd, per_cu->cu);
back_to = make_cleanup (dwarf2_free_abbrev_table, per_cu->cu);
}
- info_ptr = (dwarf2_per_objfile->info_buffer
+ info_ptr = (dwarf2_per_objfile->info.buffer
+ per_cu->cu->header.offset
+ per_cu->cu->header.first_die_offset);
abbrev = peek_die_abbrev (info_ptr, &bytes_read, per_cu->cu);
struct abbrev_info *abbrev;
struct die_info *die;
- offset = info_ptr - dwarf2_per_objfile->info_buffer;
+ offset = info_ptr - dwarf2_per_objfile->info.buffer;
abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
info_ptr += bytes_read;
if (!abbrev_number)
{
LONGEST str_offset = read_offset (abfd, buf, cu_header, bytes_read_ptr);
- if (dwarf2_per_objfile->str_buffer == NULL)
+ 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;
}
- if (str_offset >= dwarf2_per_objfile->str_size)
+ 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;
}
gdb_assert (HOST_CHAR_BIT == 8);
- if (dwarf2_per_objfile->str_buffer[str_offset] == '\0')
+ if (dwarf2_per_objfile->str.buffer[str_offset] == '\0')
return NULL;
- return (char *) (dwarf2_per_objfile->str_buffer + str_offset);
+ return (char *) (dwarf2_per_objfile->str.buffer + str_offset);
}
static unsigned long
switch (lang)
{
case DW_LANG_C89:
+ case DW_LANG_C99:
case DW_LANG_C:
cu->language = language_c;
break;
int i;
char *cur_dir, *cur_file;
- if (dwarf2_per_objfile->line_buffer == NULL)
+ if (dwarf2_per_objfile->line.buffer == NULL)
{
complaint (&symfile_complaints, _("missing .debug_line section"));
return 0;
/* Make sure that at least there's room for the total_length field.
That could be 12 bytes long, but we're just going to fudge that. */
- if (offset + 4 >= dwarf2_per_objfile->line_size)
+ if (offset + 4 >= dwarf2_per_objfile->line.size)
{
dwarf2_statement_list_fits_in_line_number_section_complaint ();
return 0;
back_to = make_cleanup ((make_cleanup_ftype *) free_line_header,
(void *) lh);
- line_ptr = dwarf2_per_objfile->line_buffer + offset;
+ line_ptr = dwarf2_per_objfile->line.buffer + offset;
/* Read in the header. */
lh->total_length =
read_checked_initial_length_and_offset (abfd, line_ptr, &cu->header,
&bytes_read, &offset_size);
line_ptr += bytes_read;
- if (line_ptr + lh->total_length > (dwarf2_per_objfile->line_buffer
- + dwarf2_per_objfile->line_size))
+ if (line_ptr + lh->total_length > (dwarf2_per_objfile->line.buffer
+ + dwarf2_per_objfile->line.size))
{
dwarf2_statement_list_fits_in_line_number_section_complaint ();
return 0;
line_ptr += bytes_read;
lh->statement_program_start = line_ptr;
- if (line_ptr > (dwarf2_per_objfile->line_buffer
- + dwarf2_per_objfile->line_size))
+ if (line_ptr > (dwarf2_per_objfile->line.buffer
+ + dwarf2_per_objfile->line.size))
complaint (&symfile_complaints,
_("line number info header doesn't fit in `.debug_line' section"));
unsigned char op_code, extended_op, adj_opcode;
CORE_ADDR baseaddr;
struct objfile *objfile = cu->objfile;
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
const int decode_for_pst_p = (pst != NULL);
struct subfile *last_subfile = NULL, *first_subfile = current_subfile;
int is_stmt = lh->default_is_stmt;
int basic_block = 0;
int end_sequence = 0;
+ CORE_ADDR addr;
if (!decode_for_pst_p && lh->num_file_names >= file)
{
{
lh->file_names[file - 1].included_p = 1;
if (!decode_for_pst_p)
- {
- if (last_subfile != current_subfile)
- {
- if (last_subfile)
- record_line (last_subfile, 0, address);
- last_subfile = current_subfile;
- }
+ {
+ if (last_subfile != current_subfile)
+ {
+ addr = gdbarch_addr_bits_remove (gdbarch, address);
+ if (last_subfile)
+ record_line (last_subfile, 0, addr);
+ last_subfile = current_subfile;
+ }
/* Append row to matrix using current values. */
- record_line (current_subfile, line,
- check_cu_functions (address, cu));
+ addr = check_cu_functions (address, cu);
+ addr = gdbarch_addr_bits_remove (gdbarch, addr);
+ record_line (current_subfile, line, addr);
}
}
basic_block = 1;
add_file_name (lh, cur_file, dir_index, mod_time, length);
}
break;
+ case DW_LNE_set_discriminator:
+ /* The discriminator is not interesting to the debugger;
+ just ignore it. */
+ line_ptr = extended_end;
+ break;
default:
complaint (&symfile_complaints,
_("mangled .debug_line section"));
{
lh->file_names[file - 1].included_p = 1;
if (!decode_for_pst_p)
- {
- if (last_subfile != current_subfile)
- {
- if (last_subfile)
- record_line (last_subfile, 0, address);
- last_subfile = current_subfile;
- }
- record_line (current_subfile, line,
- check_cu_functions (address, cu));
- }
+ {
+ if (last_subfile != current_subfile)
+ {
+ addr = gdbarch_addr_bits_remove (gdbarch, address);
+ if (last_subfile)
+ record_line (last_subfile, 0, addr);
+ last_subfile = current_subfile;
+ }
+ addr = check_cu_functions (address, cu);
+ addr = gdbarch_addr_bits_remove (gdbarch, addr);
+ record_line (current_subfile, line, addr);
+ }
}
basic_block = 0;
break;
{
lh->file_names[file - 1].included_p = 1;
if (!decode_for_pst_p)
- record_line (current_subfile, 0, address);
+ {
+ addr = gdbarch_addr_bits_remove (gdbarch, address);
+ record_line (current_subfile, 0, addr);
+ }
}
}
&& dwarf2_attr (die, DW_AT_type, cu) != NULL)
{
SYMBOL_CLASS (sym) = LOC_UNRESOLVED;
- add_symbol_to_list (sym, &global_symbols);
+ add_symbol_to_list (sym, cu->list_in_scope);
+ }
+ else if (!die_is_declaration (die, cu))
+ {
+ /* Use the default LOC_OPTIMIZED_OUT class. */
+ gdb_assert (SYMBOL_CLASS (sym) == LOC_OPTIMIZED_OUT);
+ add_symbol_to_list (sym, cu->list_in_scope);
}
}
break;
DW_ADDR (attr));
SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
break;
+ case DW_FORM_string:
case DW_FORM_strp:
/* DW_STRING is already allocated on the obstack, point directly
to it. */
attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu);
if (attr && DW_STRING (attr))
return DW_STRING (attr);
- attr = dwarf2_attr (die, DW_AT_name, cu);
- if (attr && DW_STRING (attr))
- return DW_STRING (attr);
- return NULL;
+ return dwarf2_name (die, cu);
+}
+
+/* Get name of a die, return NULL if not found. */
+
+static char *
+dwarf2_canonicalize_name (char *name, struct dwarf2_cu *cu,
+ struct obstack *obstack)
+{
+ if (name && cu->language == language_cplus)
+ {
+ char *canon_name = cp_canonicalize_string (name);
+
+ if (canon_name != NULL)
+ {
+ if (strcmp (canon_name, name) != 0)
+ name = obsavestring (canon_name, strlen (canon_name),
+ obstack);
+ xfree (canon_name);
+ }
+ }
+
+ return name;
}
/* Get name of a die, return NULL if not found. */
struct attribute *attr;
attr = dwarf2_attr (die, DW_AT_name, cu);
- if (attr && DW_STRING (attr))
- return DW_STRING (attr);
- return NULL;
+ if (!attr || !DW_STRING (attr))
+ return NULL;
+
+ switch (die->tag)
+ {
+ case DW_TAG_compile_unit:
+ /* Compilation units have a DW_AT_name that is a filename, not
+ a source language identifier. */
+ case DW_TAG_enumeration_type:
+ case DW_TAG_enumerator:
+ /* These tags always have simple identifiers already; no need
+ to canonicalize them. */
+ return DW_STRING (attr);
+ default:
+ if (attr->form != GDB_FORM_cached_string)
+ {
+ DW_STRING (attr)
+ = dwarf2_canonicalize_name (DW_STRING (attr), cu,
+ &cu->objfile->objfile_obstack);
+ attr->form = GDB_FORM_cached_string;
+ }
+ return DW_STRING (attr);
+ }
}
/* Return the die that this die in an extension of, or NULL if there
return "DW_FORM_ref_udata";
case DW_FORM_indirect:
return "DW_FORM_indirect";
+ case GDB_FORM_cached_string:
+ return "GDB_FORM_cached_string";
default:
return "DW_FORM_<unknown>";
}
break;
case DW_FORM_string:
case DW_FORM_strp:
+ case GDB_FORM_cached_string:
fprintf_unfiltered (f, "string: \"%s\"",
DW_STRING (&die->attrs[i])
? DW_STRING (&die->attrs[i]) : "");
queue_comp_unit (per_cu, this_cu->objfile);
}
+/* Follow reference attribute ATTR of SRC_DIE.
+ On entry *REF_CU is the CU of SRC_DIE.
+ On exit *REF_CU is the CU of the result. */
+
static struct die_info *
follow_die_ref (struct die_info *src_die, struct attribute *attr,
struct dwarf2_cu **ref_cu)
{
gdb_byte *mac_ptr, *mac_end;
struct macro_source_file *current_file = 0;
+ enum dwarf_macinfo_record_type macinfo_type;
+ int at_commandline;
- if (dwarf2_per_objfile->macinfo_buffer == NULL)
+ if (dwarf2_per_objfile->macinfo.buffer == NULL)
{
complaint (&symfile_complaints, _("missing .debug_macinfo section"));
return;
}
- mac_ptr = dwarf2_per_objfile->macinfo_buffer + offset;
- mac_end = dwarf2_per_objfile->macinfo_buffer
- + dwarf2_per_objfile->macinfo_size;
+ /* 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.
- for (;;)
- {
- enum dwarf_macinfo_record_type macinfo_type;
+ 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 = dwarf2_per_objfile->macinfo.buffer + offset;
+ mac_end = dwarf2_per_objfile->macinfo.buffer
+ + dwarf2_per_objfile->macinfo.size;
+
+ do
+ {
/* Do we at least have room for a macinfo type byte? */
if (mac_ptr >= mac_end)
{
- dwarf2_macros_too_long_complaint ();
- return;
+ /* 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);
/* A zero macinfo type indicates the end of the macro
information. */
case 0:
- return;
+ break;
+
+ case DW_MACINFO_define:
+ case DW_MACINFO_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_string (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+ }
+ break;
+
+ case DW_MACINFO_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_MACINFO_end_file:
+ /* No data to skip by MAC_PTR. */
+ break;
+
+ case DW_MACINFO_vendor_ext:
+ /* Only skip the data by MAC_PTR. */
+ {
+ unsigned int bytes_read;
+
+ read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+ read_string (abfd, mac_ptr, &bytes_read);
+ mac_ptr += bytes_read;
+ }
+ break;
+
+ default:
+ 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. */
+
+ mac_ptr = dwarf2_per_objfile->macinfo.buffer + offset;
+
+ /* Determines if GDB is still before first DW_MACINFO_start_file. If true
+ GDB is still reading the definitions from command line. First
+ DW_MACINFO_start_file will need to be ignored as it was already executed
+ to create CURRENT_FILE for the main source holding also the command line
+ definitions. On first met DW_MACINFO_start_file this flag is reset to
+ normally execute all the remaining DW_MACINFO_start_file macinfos. */
+
+ at_commandline = 1;
+
+ do
+ {
+ /* Do we at least have room for a macinfo type byte? */
+ if (mac_ptr >= mac_end)
+ {
+ dwarf2_macros_too_long_complaint ();
+ break;
+ }
+
+ macinfo_type = read_1_byte (abfd, mac_ptr);
+ mac_ptr++;
+
+ switch (macinfo_type)
+ {
+ /* A zero macinfo type indicates the end of the macro
+ information. */
+ case 0:
+ break;
case DW_MACINFO_define:
case DW_MACINFO_undef:
mac_ptr += bytes_read;
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);
+ break;
+ }
+ if ((line == 0 && !at_commandline) || (line != 0 && at_commandline))
complaint (&symfile_complaints,
- _("debug info gives macro %s outside of any file: %s"),
+ _("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", body);
- else
- {
- if (macinfo_type == DW_MACINFO_define)
- parse_macro_definition (current_file, line, body);
- else if (macinfo_type == DW_MACINFO_undef)
- macro_undef (current_file, line, body);
- }
+ DW_MACINFO_define ? _("definition") : macinfo_type ==
+ DW_MACINFO_undef ? _("undefinition") :
+ "something-or-other",
+ line == 0 ? _("zero") : _("non-zero"), line, body);
+
+ if (macinfo_type == DW_MACINFO_define)
+ parse_macro_definition (current_file, line, body);
+ else if (macinfo_type == DW_MACINFO_undef)
+ macro_undef (current_file, line, body);
}
break;
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);
+ if ((line == 0 && !at_commandline) || (line != 0 && at_commandline))
+ complaint (&symfile_complaints,
+ _("debug info gives source %d included "
+ "from %s at %s line %d"),
+ file, at_commandline ? _("command-line") : _("file"),
+ line == 0 ? _("zero") : _("non-zero"), line);
+
+ if (at_commandline)
+ {
+ /* This DW_MACINFO_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);
}
break;
}
break;
}
- }
+ } while (macinfo_type != 0);
}
/* Check if the attribute's form is a DW_FORM_block*
/* ".debug_loc" may not exist at all, or the offset may be outside
the section. If so, fall through to the complaint in the
other branch. */
- && DW_UNSND (attr) < dwarf2_per_objfile->loc_size)
+ && DW_UNSND (attr) < dwarf2_per_objfile->loc.size)
{
struct dwarf2_loclist_baton *baton;
/* We don't know how long the location list is, but make sure we
don't run off the edge of the section. */
- baton->size = dwarf2_per_objfile->loc_size - DW_UNSND (attr);
- baton->data = dwarf2_per_objfile->loc_buffer + DW_UNSND (attr);
+ baton->size = dwarf2_per_objfile->loc.size - DW_UNSND (attr);
+ baton->data = dwarf2_per_objfile->loc.buffer + DW_UNSND (attr);
baton->base_address = cu->base_address;
if (cu->base_known == 0)
complaint (&symfile_complaints,
_("Location list used without specifying the CU base address."));
- SYMBOL_OPS (sym) = &dwarf2_loclist_funcs;
+ SYMBOL_COMPUTED_OPS (sym) = &dwarf2_loclist_funcs;
SYMBOL_LOCATION_BATON (sym) = baton;
}
else
baton->data = NULL;
}
- SYMBOL_OPS (sym) = &dwarf2_locexpr_funcs;
+ SYMBOL_COMPUTED_OPS (sym) = &dwarf2_locexpr_funcs;
SYMBOL_LOCATION_BATON (sym) = baton;
}
}
struct objfile *objfile = per_cu->psymtab->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;
+ gdb_byte *info_ptr = per_objfile->info.buffer + per_cu->offset;
struct comp_unit_head cu_header;
memset (&cu_header, 0, sizeof cu_header);
return NULL;
}
-/* Set the mark field in CU and in every other compilation unit in the
- cache that we must keep because we are keeping CU. */
-
/* Add a dependence relationship from CU to REF_PER_CU. */
static void
*slot = ref_per_cu;
}
-/* Set the mark field in CU and in every other compilation unit in the
+/* Subroutine of dwarf2_mark to pass to htab_traverse.
+ Set the mark field in every compilation unit in the
cache that we must keep because we are keeping CU. */
static int
return 1;
}
+/* Set the mark field in CU and in every other compilation unit in the
+ cache that we must keep because we are keeping CU. */
+
static void
dwarf2_mark (struct dwarf2_cu *cu)
{
cmd_show_list (show_dwarf2_cmdlist, from_tty, "");
}
+/* If section described by INFO was mmapped, munmap it now. */
+
+static void
+munmap_section_buffer (struct dwarf2_section_info *info)
+{
+ if (info->was_mmapped)
+ {
+#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;
+ gdb_assert (munmap ((void *) map_begin, map_length) == 0);
+#else
+ /* Without HAVE_MMAP, we should never be here to begin with. */
+ gdb_assert (0);
+#endif
+ }
+}
+
+/* munmap debug sections for OBJFILE, if necessary. */
+
+static void
+dwarf2_per_objfile_cleanup (struct objfile *objfile, void *d)
+{
+ struct dwarf2_per_objfile *data = d;
+ munmap_section_buffer (&data->info);
+ munmap_section_buffer (&data->abbrev);
+ munmap_section_buffer (&data->line);
+ munmap_section_buffer (&data->str);
+ munmap_section_buffer (&data->macinfo);
+ munmap_section_buffer (&data->ranges);
+ munmap_section_buffer (&data->loc);
+ munmap_section_buffer (&data->frame);
+ munmap_section_buffer (&data->eh_frame);
+}
+
void _initialize_dwarf2_read (void);
void
_initialize_dwarf2_read (void)
{
- dwarf2_objfile_data_key = register_objfile_data ();
+ dwarf2_objfile_data_key
+ = register_objfile_data_with_cleanup (dwarf2_per_objfile_cleanup);
add_prefix_cmd ("dwarf2", class_maintenance, set_dwarf2_cmd, _("\
Set DWARF 2 specific variables.\n\