* dwarf2read.c: Don't include zlib.h or sys/mman.h.
(pagesize): Remove. (struct dwarf2_section_info) <map_addr, map_len>: Remove. (zlib_decompress_section): Remove. (dwarf2_read_section): Use gdb_bfd_map_section. (munmap_section_buffer): Remove. (free_dwo_file, dwarf2_per_objfile_free): Don't use munmap_section_buffer. * gdb_bfd.c: Include zlib.h, sys/mman.h. (struct gdb_bfd_section_data): New. (free_one_bfd_section): New function. (gdb_bfd_close_or_warn): Use free_one_bfd_section. (get_section_descriptor, zlib_decompress_section) (gdb_bfd_map_section): New functions. * gdb_bfd.h (gdb_bfd_map_section): Declare.
This commit is contained in:
parent
bb39779773
commit
4bf44c1cf1
@ -1,3 +1,21 @@
|
||||
2012-07-18 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* dwarf2read.c: Don't include zlib.h or sys/mman.h.
|
||||
(pagesize): Remove.
|
||||
(struct dwarf2_section_info) <map_addr, map_len>: Remove.
|
||||
(zlib_decompress_section): Remove.
|
||||
(dwarf2_read_section): Use gdb_bfd_map_section.
|
||||
(munmap_section_buffer): Remove.
|
||||
(free_dwo_file, dwarf2_per_objfile_free): Don't use
|
||||
munmap_section_buffer.
|
||||
* gdb_bfd.c: Include zlib.h, sys/mman.h.
|
||||
(struct gdb_bfd_section_data): New.
|
||||
(free_one_bfd_section): New function.
|
||||
(gdb_bfd_close_or_warn): Use free_one_bfd_section.
|
||||
(get_section_descriptor, zlib_decompress_section)
|
||||
(gdb_bfd_map_section): New functions.
|
||||
* gdb_bfd.h (gdb_bfd_map_section): Declare.
|
||||
|
||||
2012-07-18 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* dwarf2read.c (try_open_dwo_file): use gdb_bfd_open.
|
||||
|
202
gdb/dwarf2read.c
202
gdb/dwarf2read.c
@ -70,15 +70,6 @@
|
||||
#include "gdb_string.h"
|
||||
#include "gdb_assert.h"
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_ZLIB_H
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_MMAP
|
||||
#include <sys/mman.h>
|
||||
#ifndef MAP_FAILED
|
||||
#define MAP_FAILED ((void *) -1)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct symbol *symbolp;
|
||||
DEF_VEC_P (symbolp);
|
||||
@ -96,8 +87,6 @@ static int check_physname = 0;
|
||||
/* When non-zero, do not reject deprecated .gdb_index sections. */
|
||||
int use_deprecated_index_sections = 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. */
|
||||
@ -111,10 +100,6 @@ struct dwarf2_section_info
|
||||
asection *asection;
|
||||
gdb_byte *buffer;
|
||||
bfd_size_type size;
|
||||
/* Not NULL if the section was actually mmapped. */
|
||||
void *map_addr;
|
||||
/* Page aligned size of mmapped area. */
|
||||
bfd_size_type map_len;
|
||||
/* True if we have tried to read this section. */
|
||||
int readin;
|
||||
};
|
||||
@ -1609,8 +1594,6 @@ static struct dwo_unit *lookup_dwo_type_unit
|
||||
|
||||
static void free_dwo_file_cleanup (void *);
|
||||
|
||||
static void munmap_section_buffer (struct dwarf2_section_info *);
|
||||
|
||||
static void process_cu_includes (void);
|
||||
|
||||
#if WORDS_BIGENDIAN
|
||||
@ -1780,85 +1763,6 @@ dwarf2_locate_sections (bfd *abfd, asection *sectp, void *vnames)
|
||||
dwarf2_per_objfile->has_section_at_zero = 1;
|
||||
}
|
||||
|
||||
/* 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 = sectp->owner;
|
||||
#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);
|
||||
struct cleanup *cleanup = make_cleanup (xfree, compressed_buffer);
|
||||
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);
|
||||
|
||||
do_cleanups (cleanup);
|
||||
*outbuf = uncompressed_buffer;
|
||||
*outsize = uncompressed_size;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* A helper function that decides whether a section is empty,
|
||||
or not present. */
|
||||
|
||||
@ -1885,56 +1789,27 @@ dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info)
|
||||
if (info->readin)
|
||||
return;
|
||||
info->buffer = NULL;
|
||||
info->map_addr = NULL;
|
||||
info->readin = 1;
|
||||
|
||||
if (dwarf2_section_empty_p (info))
|
||||
return;
|
||||
|
||||
/* Note that ABFD may not be from OBJFILE, e.g. a DWO section. */
|
||||
abfd = sectp->owner;
|
||||
|
||||
/* 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))
|
||||
/* If the section has relocations, we must read it ourselves.
|
||||
Otherwise we attach it to the BFD. */
|
||||
if ((sectp->flags & SEC_RELOC) == 0)
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
const gdb_byte *bytes = gdb_bfd_map_section (sectp, &info->size);
|
||||
|
||||
/* We have to cast away const here for historical reasons.
|
||||
Fixing dwarf2read to be const-correct would be quite nice. */
|
||||
info->buffer = (gdb_byte *) bytes;
|
||||
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)
|
||||
{
|
||||
info->buffer = bfd_mmap (abfd, 0, info->size, PROT_READ,
|
||||
MAP_PRIVATE, sectp->filepos,
|
||||
&info->map_addr, &info->map_len);
|
||||
|
||||
if ((caddr_t)info->buffer != MAP_FAILED)
|
||||
{
|
||||
#if HAVE_POSIX_MADVISE
|
||||
posix_madvise (info->map_addr, info->map_len, POSIX_MADV_WILLNEED);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If we get here, we are a normal, not-compressed section. */
|
||||
info->buffer = buf
|
||||
= obstack_alloc (&objfile->objfile_obstack, info->size);
|
||||
buf = obstack_alloc (&objfile->objfile_obstack, info->size);
|
||||
info->buffer = buf;
|
||||
|
||||
/* When debugging .o files, we may need to apply relocations; see
|
||||
http://sourceware.org/ml/gdb-patches/2002-04/msg00136.html .
|
||||
@ -8324,19 +8199,6 @@ free_dwo_file (struct dwo_file *dwo_file, struct objfile *objfile)
|
||||
gdb_assert (dwo_file->dwo_bfd != objfile->obfd);
|
||||
gdb_bfd_unref (dwo_file->dwo_bfd);
|
||||
|
||||
munmap_section_buffer (&dwo_file->sections.abbrev);
|
||||
munmap_section_buffer (&dwo_file->sections.info);
|
||||
munmap_section_buffer (&dwo_file->sections.line);
|
||||
munmap_section_buffer (&dwo_file->sections.loc);
|
||||
munmap_section_buffer (&dwo_file->sections.str);
|
||||
munmap_section_buffer (&dwo_file->sections.str_offsets);
|
||||
|
||||
for (ix = 0;
|
||||
VEC_iterate (dwarf2_section_info_def, dwo_file->sections.types,
|
||||
ix, section);
|
||||
++ix)
|
||||
munmap_section_buffer (section);
|
||||
|
||||
VEC_free (dwarf2_section_info_def, dwo_file->sections.types);
|
||||
}
|
||||
|
||||
@ -18338,53 +18200,13 @@ 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->map_addr != NULL)
|
||||
{
|
||||
#ifdef HAVE_MMAP
|
||||
int res;
|
||||
|
||||
res = munmap (info->map_addr, info->map_len);
|
||||
gdb_assert (res == 0);
|
||||
#else
|
||||
/* Without HAVE_MMAP, we should never be here to begin with. */
|
||||
gdb_assert_not_reached ("no mmap support");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* munmap debug sections for OBJFILE, if necessary. */
|
||||
/* Free data associated with OBJFILE, if necessary. */
|
||||
|
||||
static void
|
||||
dwarf2_per_objfile_free (struct objfile *objfile, void *d)
|
||||
{
|
||||
struct dwarf2_per_objfile *data = d;
|
||||
int ix;
|
||||
struct dwarf2_section_info *section;
|
||||
|
||||
/* This is sorted according to the order they're defined in to make it easier
|
||||
to keep in sync. */
|
||||
munmap_section_buffer (&data->info);
|
||||
munmap_section_buffer (&data->abbrev);
|
||||
munmap_section_buffer (&data->line);
|
||||
munmap_section_buffer (&data->loc);
|
||||
munmap_section_buffer (&data->macinfo);
|
||||
munmap_section_buffer (&data->macro);
|
||||
munmap_section_buffer (&data->str);
|
||||
munmap_section_buffer (&data->ranges);
|
||||
munmap_section_buffer (&data->addr);
|
||||
munmap_section_buffer (&data->frame);
|
||||
munmap_section_buffer (&data->eh_frame);
|
||||
munmap_section_buffer (&data->gdb_index);
|
||||
|
||||
for (ix = 0;
|
||||
VEC_iterate (dwarf2_section_info_def, data->types, ix, section);
|
||||
++ix)
|
||||
munmap_section_buffer (section);
|
||||
|
||||
for (ix = 0; ix < dwarf2_per_objfile->n_comp_units; ++ix)
|
||||
VEC_free (dwarf2_per_cu_ptr,
|
||||
|
252
gdb/gdb_bfd.c
252
gdb/gdb_bfd.c
@ -23,6 +23,30 @@
|
||||
#include "gdb_assert.h"
|
||||
#include "gdb_string.h"
|
||||
#include "hashtab.h"
|
||||
#ifdef HAVE_ZLIB_H
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_MMAP
|
||||
#include <sys/mman.h>
|
||||
#ifndef MAP_FAILED
|
||||
#define MAP_FAILED ((void *) -1)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* An object of this type is stored in the section's user data when
|
||||
mapping a section. */
|
||||
|
||||
struct gdb_bfd_section_data
|
||||
{
|
||||
/* Size of the data. */
|
||||
bfd_size_type size;
|
||||
/* If the data was mmapped, this is the length of the map. */
|
||||
bfd_size_type map_len;
|
||||
/* The data. If NULL, the section data has not been read. */
|
||||
void *data;
|
||||
/* If the data was mmapped, this is the map address. */
|
||||
void *map_addr;
|
||||
};
|
||||
|
||||
/* See gdb_bfd.h. */
|
||||
|
||||
@ -149,6 +173,30 @@ gdb_bfd_open (const char *name, const char *target, int fd)
|
||||
return gdb_bfd_ref (abfd);
|
||||
}
|
||||
|
||||
/* A helper function that releases any section data attached to the
|
||||
BFD. */
|
||||
|
||||
static void
|
||||
free_one_bfd_section (bfd *abfd, asection *sectp, void *ignore)
|
||||
{
|
||||
struct gdb_bfd_section_data *sect = bfd_get_section_userdata (abfd, sectp);
|
||||
|
||||
if (sect != NULL && sect->data != NULL)
|
||||
{
|
||||
#ifdef HAVE_MMAP
|
||||
if (sect->map_addr != NULL)
|
||||
{
|
||||
int res;
|
||||
|
||||
res = munmap (sect->map_addr, sect->map_len);
|
||||
gdb_assert (res == 0);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
xfree (sect->data);
|
||||
}
|
||||
}
|
||||
|
||||
/* Close ABFD, and warn if that fails. */
|
||||
|
||||
static int
|
||||
@ -157,6 +205,8 @@ gdb_bfd_close_or_warn (struct bfd *abfd)
|
||||
int ret;
|
||||
char *name = bfd_get_filename (abfd);
|
||||
|
||||
bfd_map_over_sections (abfd, free_one_bfd_section, NULL);
|
||||
|
||||
ret = bfd_close (abfd);
|
||||
|
||||
if (!ret)
|
||||
@ -229,3 +279,205 @@ gdb_bfd_unref (struct bfd *abfd)
|
||||
|
||||
gdb_bfd_close_or_warn (abfd);
|
||||
}
|
||||
|
||||
/* A helper function that returns the section data descriptor
|
||||
associated with SECTION. If no such descriptor exists, a new one
|
||||
is allocated and cleared. */
|
||||
|
||||
static struct gdb_bfd_section_data *
|
||||
get_section_descriptor (asection *section)
|
||||
{
|
||||
struct gdb_bfd_section_data *result;
|
||||
|
||||
result = bfd_get_section_userdata (section->owner, section);
|
||||
|
||||
if (result == NULL)
|
||||
{
|
||||
result = bfd_zalloc (section->owner, sizeof (*result));
|
||||
bfd_set_section_userdata (section->owner, section, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Decompress a section that was compressed using zlib. Store the
|
||||
decompressed buffer, and its size, in DESCRIPTOR. */
|
||||
|
||||
static void
|
||||
zlib_decompress_section (asection *sectp,
|
||||
struct gdb_bfd_section_data *descriptor)
|
||||
{
|
||||
bfd *abfd = sectp->owner;
|
||||
#ifndef HAVE_ZLIB_H
|
||||
error (_("Support for zlib-compressed data (from '%s', section '%s') "
|
||||
"is disabled in this copy of GDB"),
|
||||
bfd_get_filename (abfd),
|
||||
bfd_get_section_name (sectp));
|
||||
#else
|
||||
bfd_size_type compressed_size = bfd_get_section_size (sectp);
|
||||
gdb_byte *compressed_buffer = xmalloc (compressed_size);
|
||||
struct cleanup *cleanup = make_cleanup (xfree, compressed_buffer);
|
||||
struct cleanup *inner_cleanup;
|
||||
bfd_size_type uncompressed_size;
|
||||
gdb_byte *uncompressed_buffer;
|
||||
z_stream strm;
|
||||
int rc;
|
||||
int header_size = 12;
|
||||
struct dwarf2_per_bfd_section *section_data;
|
||||
|
||||
if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0
|
||||
|| bfd_bread (compressed_buffer,
|
||||
compressed_size, abfd) != compressed_size)
|
||||
error (_("can't read data from '%s', section '%s'"),
|
||||
bfd_get_filename (abfd),
|
||||
bfd_get_section_name (abfd, sectp));
|
||||
|
||||
/* 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 (_("corrupt ZLIB header from '%s', section '%s'"),
|
||||
bfd_get_filename (abfd),
|
||||
bfd_get_section_name (abfd, sectp));
|
||||
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 = xmalloc (uncompressed_size);
|
||||
inner_cleanup = make_cleanup (xfree, uncompressed_buffer);
|
||||
rc = inflateInit (&strm);
|
||||
while (strm.avail_in > 0)
|
||||
{
|
||||
if (rc != Z_OK)
|
||||
error (_("setting up uncompression in '%s', section '%s': %d"),
|
||||
bfd_get_filename (abfd),
|
||||
bfd_get_section_name (abfd, sectp),
|
||||
rc);
|
||||
strm.next_out = ((Bytef*) uncompressed_buffer
|
||||
+ (uncompressed_size - strm.avail_out));
|
||||
rc = inflate (&strm, Z_FINISH);
|
||||
if (rc != Z_STREAM_END)
|
||||
error (_("zlib error uncompressing from '%s', section '%s': %d"),
|
||||
bfd_get_filename (abfd),
|
||||
bfd_get_section_name (abfd, sectp),
|
||||
rc);
|
||||
rc = inflateReset (&strm);
|
||||
}
|
||||
rc = inflateEnd (&strm);
|
||||
if (rc != Z_OK
|
||||
|| strm.avail_out != 0)
|
||||
error (_("concluding uncompression in '%s', section '%s': %d"),
|
||||
bfd_get_filename (abfd),
|
||||
bfd_get_section_name (abfd, sectp),
|
||||
rc);
|
||||
|
||||
discard_cleanups (inner_cleanup);
|
||||
do_cleanups (cleanup);
|
||||
|
||||
/* Attach the data to the BFD section. */
|
||||
descriptor->data = uncompressed_buffer;
|
||||
descriptor->size = uncompressed_size;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* See gdb_bfd.h. */
|
||||
|
||||
const gdb_byte *
|
||||
gdb_bfd_map_section (asection *sectp, bfd_size_type *size)
|
||||
{
|
||||
bfd *abfd;
|
||||
gdb_byte *buf, *retbuf;
|
||||
unsigned char header[4];
|
||||
struct gdb_bfd_section_data *descriptor;
|
||||
|
||||
gdb_assert ((sectp->flags & SEC_RELOC) == 0);
|
||||
gdb_assert (size != NULL);
|
||||
|
||||
abfd = sectp->owner;
|
||||
|
||||
descriptor = get_section_descriptor (sectp);
|
||||
|
||||
/* If the data was already read for this BFD, just reuse it. */
|
||||
if (descriptor->data != NULL)
|
||||
goto done;
|
||||
|
||||
/* Check if the file has a 4-byte header indicating compression. */
|
||||
if (bfd_get_section_size (sectp) > 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 (sectp, descriptor);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
{
|
||||
/* The page size, used when mmapping. */
|
||||
static int pagesize;
|
||||
|
||||
if (pagesize == 0)
|
||||
pagesize = getpagesize ();
|
||||
|
||||
/* Only try to mmap sections which are large enough: we don't want
|
||||
to waste space due to fragmentation. */
|
||||
|
||||
if (bfd_get_section_size (sectp) > 4 * pagesize)
|
||||
{
|
||||
descriptor->size = bfd_get_section_size (sectp);
|
||||
descriptor->data = bfd_mmap (abfd, 0, descriptor->size, PROT_READ,
|
||||
MAP_PRIVATE, sectp->filepos,
|
||||
&descriptor->map_addr,
|
||||
&descriptor->map_len);
|
||||
|
||||
if ((caddr_t)descriptor->data != MAP_FAILED)
|
||||
{
|
||||
#if HAVE_POSIX_MADVISE
|
||||
posix_madvise (descriptor->map_addr, descriptor->map_len,
|
||||
POSIX_MADV_WILLNEED);
|
||||
#endif
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* On failure, clear out the section data and try again. */
|
||||
memset (descriptor, 0, sizeof (*descriptor));
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_MMAP */
|
||||
|
||||
/* If we get here, we are a normal, not-compressed section. */
|
||||
|
||||
descriptor->size = bfd_get_section_size (sectp);
|
||||
descriptor->data = xmalloc (descriptor->size);
|
||||
|
||||
if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0
|
||||
|| bfd_bread (descriptor->data, bfd_get_section_size (sectp),
|
||||
abfd) != bfd_get_section_size (sectp))
|
||||
{
|
||||
xfree (descriptor->data);
|
||||
descriptor->data = NULL;
|
||||
error (_("Can't read data for section '%s'"),
|
||||
bfd_get_filename (abfd));
|
||||
}
|
||||
|
||||
done:
|
||||
gdb_assert (descriptor->data != NULL);
|
||||
*size = descriptor->size;
|
||||
return descriptor->data;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Definitions for BFD wrappers used by GDB.
|
||||
|
||||
Copyright (C) 2011
|
||||
Copyright (C) 2011, 2012
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
@ -46,4 +46,16 @@ struct bfd *gdb_bfd_ref (struct bfd *abfd);
|
||||
|
||||
void gdb_bfd_unref (struct bfd *abfd);
|
||||
|
||||
/* Try to read or map the contents of the section SECT. If
|
||||
successful, the section data is returned and *SIZE is set to the
|
||||
size of the section data; this may not be the same as the size
|
||||
according to bfd_get_section_size if the section was compressed.
|
||||
The returned section data is associated with the BFD and will be
|
||||
destroyed when the BFD is destroyed. There is no other way to free
|
||||
it; for temporary uses of section data, see
|
||||
bfd_malloc_and_get_section. SECT may not have relocations. This
|
||||
function will throw on error. */
|
||||
|
||||
const gdb_byte *gdb_bfd_map_section (asection *section, bfd_size_type *size);
|
||||
|
||||
#endif /* GDB_BFD_H */
|
||||
|
Loading…
Reference in New Issue
Block a user