2009-06-16 Paul Pluzhnikov <ppluzhnikov@google.com>

* dwarf2read.c (dwarf_info_section, dwarf_abbrev_section)
	(dwarf_line_section, dwarf_pubnames_section, dwarf_aranges_section)
	(dwarf_loc_section, dwarf_macinfo_section, dwarf_str_section)
	(dwarf_ranges_section, dwarf_frame_section)
	(dwarf_eh_frame_section): Removed.
	(dwarf2_resize_section): Likewise.
	(dwarf2_read_section): Now static, use bfd_mmap() if possible.
	(dwarf2_get_section_info): New function.
	(munmap_section_buffer): Likewise.
	(dwarf2_per_objfile_cleanup): Likewise.
	(section_is_p): Signature change.
	* dwarf2-frame.c (dwarf2_build_frame_info): Use
	dwarf2_get_section_info instead of dwarf2_read_section.
This commit is contained in:
Paul Pluzhnikov 2009-06-16 21:06:40 +00:00
parent 7eedccfa2a
commit dce234bc19
3 changed files with 361 additions and 350 deletions

View File

@ -1,3 +1,19 @@
2009-06-16 Paul Pluzhnikov <ppluzhnikov@google.com>
* dwarf2read.c (dwarf_info_section, dwarf_abbrev_section)
(dwarf_line_section, dwarf_pubnames_section, dwarf_aranges_section)
(dwarf_loc_section, dwarf_macinfo_section, dwarf_str_section)
(dwarf_ranges_section, dwarf_frame_section)
(dwarf_eh_frame_section): Removed.
(dwarf2_resize_section): Likewise.
(dwarf2_read_section): Now static, use bfd_mmap() if possible.
(dwarf2_get_section_info): New function.
(munmap_section_buffer): Likewise.
(dwarf2_per_objfile_cleanup): Likewise.
(section_is_p): Signature change.
* dwarf2-frame.c (dwarf2_build_frame_info): Use
dwarf2_get_section_info instead of dwarf2_read_section.
2009-06-16 Paul Pluzhnikov <ppluzhnikov@google.com>
* solib.c (symbol_add_stub): New FLAGS parameter.

View File

@ -1896,15 +1896,9 @@ decode_frame_entry (struct comp_unit *unit, gdb_byte *start, int eh_frame_p)
}
/* FIXME: kettenis/20030504: This still needs to be integrated with
dwarf2read.c in a better way. */
/* Imported from dwarf2read.c. */
extern asection *dwarf_frame_section;
extern asection *dwarf_eh_frame_section;
/* Imported from dwarf2read.c. */
extern gdb_byte *dwarf2_read_section (struct objfile *objfile, asection *sectp);
extern void dwarf2_get_section_info (struct objfile *, const char *, asection **,
gdb_byte **, bfd_size_type *);
void
dwarf2_build_frame_info (struct objfile *objfile)
@ -1922,17 +1916,15 @@ dwarf2_build_frame_info (struct objfile *objfile)
/* First add the information from the .eh_frame section. That way,
the FDEs from that section are searched last. */
if (dwarf_eh_frame_section)
dwarf2_get_section_info (objfile, ".eh_frame",
&unit->dwarf_frame_section,
&unit->dwarf_frame_buffer,
&unit->dwarf_frame_size);
if (unit->dwarf_frame_size)
{
asection *got, *txt;
unit->cie = NULL;
unit->dwarf_frame_buffer = dwarf2_read_section (objfile,
dwarf_eh_frame_section);
unit->dwarf_frame_size = bfd_get_section_size (dwarf_eh_frame_section);
unit->dwarf_frame_section = dwarf_eh_frame_section;
/* FIXME: kettenis/20030602: This is the DW_EH_PE_datarel base
that is used for the i386/amd64 target, which currently is
the only target in GCC that supports/uses the
@ -1952,13 +1944,13 @@ dwarf2_build_frame_info (struct objfile *objfile)
frame_ptr = decode_frame_entry (unit, frame_ptr, 1);
}
if (dwarf_frame_section)
dwarf2_get_section_info (objfile, ".debug_frame",
&unit->dwarf_frame_section,
&unit->dwarf_frame_buffer,
&unit->dwarf_frame_size);
if (unit->dwarf_frame_size)
{
unit->cie = NULL;
unit->dwarf_frame_buffer = dwarf2_read_section (objfile,
dwarf_frame_section);
unit->dwarf_frame_size = bfd_get_section_size (dwarf_frame_section);
unit->dwarf_frame_section = dwarf_frame_section;
frame_ptr = unit->dwarf_frame_buffer;
while (frame_ptr < unit->dwarf_frame_buffer + unit->dwarf_frame_size)

View File

@ -55,20 +55,9 @@
#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
@ -145,6 +134,8 @@ _STATEMENT_PROLOGUE;
/* 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. */
@ -153,29 +144,27 @@ static int processing_has_namespace_info;
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. */
@ -195,18 +184,6 @@ struct dwarf2_per_objfile
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
@ -803,8 +780,6 @@ static void dwarf2_psymtab_to_symtab (struct partial_symtab *);
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 *);
@ -1130,30 +1105,20 @@ dwarf2_has_info (struct objfile *objfile)
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
@ -1163,103 +1128,250 @@ section_is_p (asection *sectp, const char *name)
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)
zlib_decompress_section (struct objfile *objfile, asection *sectp,
gdb_byte **outbuf, bfd_size_type *outsize)
{
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;
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 SECTP from object file specified by
OBJFILE, store info about the section into INFO.
If the section is compressed, uncompress it before returning. */
static void
dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info)
{
bfd *abfd = objfile->obfd;
asection *sectp = info->asection;
gdb_byte *buf, *retbuf;
unsigned char header[4];
info->buffer = NULL;
info->was_mmapped = 0;
if (info->asection == NULL || info->size == 0)
return;
/* 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;
}
}
#ifdef HAVE_MMAP
if (pagesize == 0)
pagesize = getpagesize ();
/* 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 (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
internal_error (__FILE__, __LINE__,
_("dwarf2_resize_section: missing section_is_p check: %s"),
sectp->name);
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. */
@ -1267,36 +1379,15 @@ dwarf2_resize_section (asection *sectp, bfd_size_type new_size)
void
dwarf2_build_psymtabs (struct objfile *objfile, int mainline)
{
/* We definitely need the .debug_info and .debug_abbrev sections */
dwarf2_per_objfile->info_buffer = dwarf2_read_section (objfile, dwarf_info_section);
dwarf2_per_objfile->abbrev_buffer = dwarf2_read_section (objfile, dwarf_abbrev_section);
if (dwarf_line_section)
dwarf2_per_objfile->line_buffer = dwarf2_read_section (objfile, dwarf_line_section);
else
dwarf2_per_objfile->line_buffer = NULL;
if (dwarf_str_section)
dwarf2_per_objfile->str_buffer = dwarf2_read_section (objfile, dwarf_str_section);
else
dwarf2_per_objfile->str_buffer = NULL;
if (dwarf_macinfo_section)
dwarf2_per_objfile->macinfo_buffer = dwarf2_read_section (objfile,
dwarf_macinfo_section);
else
dwarf2_per_objfile->macinfo_buffer = NULL;
if (dwarf_ranges_section)
dwarf2_per_objfile->ranges_buffer = dwarf2_read_section (objfile, dwarf_ranges_section);
else
dwarf2_per_objfile->ranges_buffer = NULL;
if (dwarf_loc_section)
dwarf2_per_objfile->loc_buffer = dwarf2_read_section (objfile, dwarf_loc_section);
else
dwarf2_per_objfile->loc_buffer = NULL;
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
@ -1337,7 +1428,7 @@ dwarf2_build_psymtabs_easy (struct objfile *objfile, int mainline)
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;
@ -1412,19 +1503,19 @@ partial_read_comp_unit_head (struct comp_unit_head *header, gdb_byte *info_ptr,
"(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;
@ -1506,7 +1597,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
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. */
@ -1530,8 +1621,8 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
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;
@ -1551,7 +1642,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
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;
@ -1708,7 +1799,7 @@ load_comp_unit (struct dwarf2_per_cu_data *this_cu, struct objfile *objfile)
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));
@ -1720,7 +1811,7 @@ load_comp_unit (struct dwarf2_per_cu_data *this_cu, struct objfile *objfile)
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. */
@ -1760,21 +1851,21 @@ create_all_comp_units (struct objfile *objfile)
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. */
@ -2420,7 +2511,7 @@ skip_one_die (gdb_byte *info_ptr, struct abbrev_info *abbrev,
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);
}
@ -2706,7 +2797,7 @@ load_full_comp_unit (struct dwarf2_per_cu_data *per_cu, struct objfile *objfile)
/* 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));
@ -3371,14 +3462,14 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
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);
@ -3653,7 +3744,7 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block,
/* 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.
@ -3672,7 +3763,7 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block,
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"),
@ -5510,131 +5601,6 @@ read_die_and_siblings (gdb_byte *info_ptr, bfd *abfd,
}
}
/* 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
@ -5660,7 +5626,7 @@ dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu)
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;
@ -5732,8 +5698,8 @@ dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu)
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;
@ -6051,7 +6017,7 @@ read_partial_die (struct partial_die_info *part_die,
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;
@ -6164,7 +6130,7 @@ read_partial_die (struct partial_die_info *part_die,
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:
@ -6280,7 +6246,7 @@ find_partial_die (unsigned int offset, struct dwarf2_cu *cu)
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);
@ -6356,7 +6322,7 @@ read_full_die (struct die_info **diep, bfd *abfd, gdb_byte *info_ptr,
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)
@ -6792,22 +6758,22 @@ read_indirect_string (bfd *abfd, gdb_byte *buf,
{
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
@ -7094,7 +7060,7 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd,
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;
@ -7102,7 +7068,7 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd,
/* 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;
@ -7113,15 +7079,15 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd,
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;
@ -7177,8 +7143,8 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd,
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"));
@ -10163,7 +10129,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
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;
@ -10180,9 +10146,9 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
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;
mac_ptr = dwarf2_per_objfile->macinfo.buffer + offset;
mac_end = dwarf2_per_objfile->macinfo.buffer
+ dwarf2_per_objfile->macinfo.size;
do
{
@ -10259,7 +10225,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
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;
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
@ -10477,7 +10443,7 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
/* ".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;
@ -10488,8 +10454,8 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
/* 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,
@ -10558,7 +10524,7 @@ dwarf2_per_cu_addr_size (struct dwarf2_per_cu_data *per_cu)
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);
@ -10951,12 +10917,49 @@ show_dwarf2_cmd (char *args, int from_tty)
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\