mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-28 12:33:36 +08:00
* 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>
|
2012-07-18 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
* dwarf2read.c (try_open_dwo_file): use gdb_bfd_open.
|
* 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_string.h"
|
||||||
#include "gdb_assert.h"
|
#include "gdb_assert.h"
|
||||||
#include <sys/types.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;
|
typedef struct symbol *symbolp;
|
||||||
DEF_VEC_P (symbolp);
|
DEF_VEC_P (symbolp);
|
||||||
@ -96,8 +87,6 @@ static int check_physname = 0;
|
|||||||
/* When non-zero, do not reject deprecated .gdb_index sections. */
|
/* When non-zero, do not reject deprecated .gdb_index sections. */
|
||||||
int use_deprecated_index_sections = 0;
|
int use_deprecated_index_sections = 0;
|
||||||
|
|
||||||
static int pagesize;
|
|
||||||
|
|
||||||
/* When set, the file that we're processing is known to have debugging
|
/* 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,
|
info for C++ namespaces. GCC 3.3.x did not produce this information,
|
||||||
but later versions do. */
|
but later versions do. */
|
||||||
@ -111,10 +100,6 @@ struct dwarf2_section_info
|
|||||||
asection *asection;
|
asection *asection;
|
||||||
gdb_byte *buffer;
|
gdb_byte *buffer;
|
||||||
bfd_size_type size;
|
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. */
|
/* True if we have tried to read this section. */
|
||||||
int readin;
|
int readin;
|
||||||
};
|
};
|
||||||
@ -1609,8 +1594,6 @@ static struct dwo_unit *lookup_dwo_type_unit
|
|||||||
|
|
||||||
static void free_dwo_file_cleanup (void *);
|
static void free_dwo_file_cleanup (void *);
|
||||||
|
|
||||||
static void munmap_section_buffer (struct dwarf2_section_info *);
|
|
||||||
|
|
||||||
static void process_cu_includes (void);
|
static void process_cu_includes (void);
|
||||||
|
|
||||||
#if WORDS_BIGENDIAN
|
#if WORDS_BIGENDIAN
|
||||||
@ -1780,85 +1763,6 @@ dwarf2_locate_sections (bfd *abfd, asection *sectp, void *vnames)
|
|||||||
dwarf2_per_objfile->has_section_at_zero = 1;
|
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,
|
/* A helper function that decides whether a section is empty,
|
||||||
or not present. */
|
or not present. */
|
||||||
|
|
||||||
@ -1885,56 +1789,27 @@ dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info)
|
|||||||
if (info->readin)
|
if (info->readin)
|
||||||
return;
|
return;
|
||||||
info->buffer = NULL;
|
info->buffer = NULL;
|
||||||
info->map_addr = NULL;
|
|
||||||
info->readin = 1;
|
info->readin = 1;
|
||||||
|
|
||||||
if (dwarf2_section_empty_p (info))
|
if (dwarf2_section_empty_p (info))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Note that ABFD may not be from OBJFILE, e.g. a DWO section. */
|
|
||||||
abfd = sectp->owner;
|
abfd = sectp->owner;
|
||||||
|
|
||||||
/* Check if the file has a 4-byte header indicating compression. */
|
/* If the section has relocations, we must read it ourselves.
|
||||||
if (info->size > sizeof (header)
|
Otherwise we attach it to the BFD. */
|
||||||
&& bfd_seek (abfd, sectp->filepos, SEEK_SET) == 0
|
if ((sectp->flags & SEC_RELOC) == 0)
|
||||||
&& bfd_bread (header, sizeof (header), abfd) == sizeof (header))
|
|
||||||
{
|
{
|
||||||
/* Upon decompression, update the buffer and its size. */
|
const gdb_byte *bytes = gdb_bfd_map_section (sectp, &info->size);
|
||||||
if (strncmp (header, "ZLIB", sizeof (header)) == 0)
|
|
||||||
{
|
/* We have to cast away const here for historical reasons.
|
||||||
zlib_decompress_section (objfile, sectp, &info->buffer,
|
Fixing dwarf2read to be const-correct would be quite nice. */
|
||||||
&info->size);
|
info->buffer = (gdb_byte *) bytes;
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_MMAP
|
buf = obstack_alloc (&objfile->objfile_obstack, info->size);
|
||||||
if (pagesize == 0)
|
info->buffer = buf;
|
||||||
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);
|
|
||||||
|
|
||||||
/* When debugging .o files, we may need to apply relocations; see
|
/* When debugging .o files, we may need to apply relocations; see
|
||||||
http://sourceware.org/ml/gdb-patches/2002-04/msg00136.html .
|
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_assert (dwo_file->dwo_bfd != objfile->obfd);
|
||||||
gdb_bfd_unref (dwo_file->dwo_bfd);
|
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);
|
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, "");
|
cmd_show_list (show_dwarf2_cmdlist, from_tty, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If section described by INFO was mmapped, munmap it now. */
|
/* Free data associated with OBJFILE, if necessary. */
|
||||||
|
|
||||||
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. */
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dwarf2_per_objfile_free (struct objfile *objfile, void *d)
|
dwarf2_per_objfile_free (struct objfile *objfile, void *d)
|
||||||
{
|
{
|
||||||
struct dwarf2_per_objfile *data = d;
|
struct dwarf2_per_objfile *data = d;
|
||||||
int ix;
|
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)
|
for (ix = 0; ix < dwarf2_per_objfile->n_comp_units; ++ix)
|
||||||
VEC_free (dwarf2_per_cu_ptr,
|
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_assert.h"
|
||||||
#include "gdb_string.h"
|
#include "gdb_string.h"
|
||||||
#include "hashtab.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. */
|
/* See gdb_bfd.h. */
|
||||||
|
|
||||||
@ -149,6 +173,30 @@ gdb_bfd_open (const char *name, const char *target, int fd)
|
|||||||
return gdb_bfd_ref (abfd);
|
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. */
|
/* Close ABFD, and warn if that fails. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -157,6 +205,8 @@ gdb_bfd_close_or_warn (struct bfd *abfd)
|
|||||||
int ret;
|
int ret;
|
||||||
char *name = bfd_get_filename (abfd);
|
char *name = bfd_get_filename (abfd);
|
||||||
|
|
||||||
|
bfd_map_over_sections (abfd, free_one_bfd_section, NULL);
|
||||||
|
|
||||||
ret = bfd_close (abfd);
|
ret = bfd_close (abfd);
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
@ -229,3 +279,205 @@ gdb_bfd_unref (struct bfd *abfd)
|
|||||||
|
|
||||||
gdb_bfd_close_or_warn (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.
|
/* Definitions for BFD wrappers used by GDB.
|
||||||
|
|
||||||
Copyright (C) 2011
|
Copyright (C) 2011, 2012
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of GDB.
|
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);
|
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 */
|
#endif /* GDB_BFD_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user