mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-23 01:53:38 +08:00
elf: Add _bfd_elf_m[un]map_section_contents
Add _bfd_elf_mmap_section_contents and _bfd_elf_munmap_section_contents. A backend must opt-in to use mmap. It should replace bfd_malloc_and_get_section -> _bfd_elf_mmap_section_contents free -> _bfd_elf_munmap_section_contents on section contents. * compress.c (bfd_get_full_section_contents): Don't allocate buffer if mmapped_p is true. * elf-bfd.h (elf_backend_data): Add use_mmap. (bfd_elf_section_data): Add contents_addr and contents_size. (_bfd_elf_mmap_section_contents): New. (_bfd_elf_munmap_section_contents): Likewise. * elf-eh-frame.c (_bfd_elf_parse_eh_frame): Replace bfd_malloc_and_get_section and free with _bfd_elf_mmap_section_contents and _bfd_elf_munmap_section_contents on section contents. * elf-sframe.c (_bfd_elf_parse_sframe): Likewise. * elf.c (_bfd_elf_make_section_from_shdr): Replace bfd_malloc_and_get_section and free with _bfd_elf_mmap_section_contents and _bfd_elf_munmap_section_contents on section contents. (_bfd_elf_print_private_bfd_data): Likewise. (_bfd_elf_mmap_section_contents): New. (_bfd_elf_munmap_section_contents): Likewise. * elf32-i386.c (elf_i386_scan_relocs): Replace bfd_malloc_and_get_section and free with _bfd_elf_mmap_section_contents and _bfd_elf_munmap_section_contents on section contents. * elf64-x86-64.c (elf_x86_64_scan_relocs): Likewise. (elf_x86_64_get_synthetic_symtab): Likewise. * elfcode.h (elf_checksum_contents): Likewise. * elflink.c (elf_link_add_object_symbols): Likewise. (bfd_elf_get_bfd_needed_list): Likewise. * elfxx-target.h (elf_backend_use_mmap): New. (elfNN_bed): Add elf_backend_use_mmap. * elfxx-x86.c (elf_x86_size_or_finish_relative_reloc): Replace bfd_malloc_and_get_section and free with _bfd_elf_mmap_section_contents and _bfd_elf_munmap_section_contents on section contents. (_bfd_x86_elf_get_synthetic_symtab): Replace free with _bfd_elf_munmap_section_contents. * elfxx-x86.h (elf_backend_use_mmap): New. * libbfd.c: Include "elf-bfd.h". (_bfd_generic_get_section_contents): Call bfd_mmap_local for mmapped_p. * opncls.c (_bfd_delete_bfd): Also munmap ELF section contents. * section.c (asection): Add mmapped_p. (BFD_FAKE_SECTION): Updated. (bfd_malloc_and_get_section): Add a sanity check for not mmapped_p. * bfd-in2.h: Regenerated.
This commit is contained in:
parent
9ba56acee5
commit
584b30e4b3
@ -689,6 +689,9 @@ typedef struct bfd_section
|
||||
/* Nonzero if this section uses RELA relocations, rather than REL. */
|
||||
unsigned int use_rela_p:1;
|
||||
|
||||
/* Nonzero if this section contents are mmapped, rather than malloced. */
|
||||
unsigned int mmapped_p:1;
|
||||
|
||||
/* Bits used by various backends. The generic code doesn't touch
|
||||
these fields. */
|
||||
|
||||
@ -976,8 +979,8 @@ discarded_section (const asection *sec)
|
||||
/* linker_mark, linker_has_input, gc_mark, decompress_status, */ \
|
||||
0, 0, 1, 0, \
|
||||
\
|
||||
/* segment_mark, sec_info_type, use_rela_p, */ \
|
||||
0, 0, 0, \
|
||||
/* segment_mark, sec_info_type, use_rela_p, mmapped_p, */ \
|
||||
0, 0, 0, 0, \
|
||||
\
|
||||
/* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5, */ \
|
||||
0, 0, 0, 0, 0, 0, \
|
||||
|
@ -753,7 +753,7 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
|
||||
switch (compress_status)
|
||||
{
|
||||
case COMPRESS_SECTION_NONE:
|
||||
if (p == NULL)
|
||||
if (p == NULL && !sec->mmapped_p)
|
||||
{
|
||||
p = (bfd_byte *) bfd_malloc (allocsz);
|
||||
if (p == NULL)
|
||||
|
@ -1778,6 +1778,12 @@ struct elf_backend_data
|
||||
/* True if the 64-bit Linux PRPSINFO structure's `pr_uid' and `pr_gid'
|
||||
members use a 16-bit data type. */
|
||||
unsigned linux_prpsinfo64_ugid16 : 1;
|
||||
|
||||
/* True if the backend can use mmap to map in all input section
|
||||
contents. All bfd_malloc_and_get_section and free usages on
|
||||
section contents must be replaced by _bfd_elf_mmap_section_contents
|
||||
and _bfd_elf_munmap_section_contents. */
|
||||
unsigned use_mmap : 1;
|
||||
};
|
||||
|
||||
/* Information about reloc sections associated with a bfd_elf_section_data
|
||||
@ -1859,6 +1865,15 @@ struct bfd_elf_section_data
|
||||
/* Link from a text section to its .eh_frame_entry section. */
|
||||
asection *eh_frame_entry;
|
||||
|
||||
/* If the mmapped_p flag is set, this points to the actual mmapped
|
||||
address of contents. If it is set to NULL, contents isn't
|
||||
mmapped. */
|
||||
void *contents_addr;
|
||||
|
||||
/* If the mmapped_p flag is set, this is the actual mmapped size of
|
||||
contents. */
|
||||
size_t contents_size;
|
||||
|
||||
/* TRUE if the section has secondary reloc sections associated with it.
|
||||
FIXME: In the future it might be better to change this into a list
|
||||
of secondary reloc sections, making lookup easier and faster. */
|
||||
@ -3127,6 +3142,11 @@ extern bool _bfd_elf_maybe_set_textrel
|
||||
extern bool _bfd_elf_add_dynamic_tags
|
||||
(bfd *, struct bfd_link_info *, bool);
|
||||
|
||||
extern bool _bfd_elf_mmap_section_contents
|
||||
(bfd *abfd, asection *section, bfd_byte **buf);
|
||||
extern void _bfd_elf_munmap_section_contents
|
||||
(asection *, void *);
|
||||
|
||||
/* Large common section. */
|
||||
extern asection _bfd_elf_large_com_section;
|
||||
|
||||
|
@ -618,7 +618,7 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
|
||||
|
||||
/* Read the frame unwind information from abfd. */
|
||||
|
||||
REQUIRE (bfd_malloc_and_get_section (abfd, sec, &ehbuf));
|
||||
REQUIRE (_bfd_elf_mmap_section_contents (abfd, sec, &ehbuf));
|
||||
|
||||
/* If .eh_frame section size doesn't fit into int, we cannot handle
|
||||
it (it would need to use 64-bit .eh_frame format anyway). */
|
||||
@ -1052,7 +1052,7 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
|
||||
hdr_info->u.dwarf.table = false;
|
||||
free (sec_info);
|
||||
success:
|
||||
free (ehbuf);
|
||||
_bfd_elf_munmap_section_contents (sec, ehbuf);
|
||||
free (local_cies);
|
||||
#undef REQUIRE
|
||||
}
|
||||
|
@ -208,7 +208,7 @@ _bfd_elf_parse_sframe (bfd *abfd,
|
||||
}
|
||||
|
||||
/* Read the SFrame stack trace information from abfd. */
|
||||
if (!bfd_malloc_and_get_section (abfd, sec, &sfbuf))
|
||||
if (!_bfd_elf_mmap_section_contents (abfd, sec, &sfbuf))
|
||||
goto fail_no_free;
|
||||
|
||||
/* Decode the buffer and keep decoded contents for later use.
|
||||
@ -241,7 +241,7 @@ fail_no_free:
|
||||
abfd, sec);
|
||||
return false;
|
||||
success:
|
||||
free (sfbuf);
|
||||
_bfd_elf_munmap_section_contents (sec, sfbuf);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
87
bfd/elf.c
87
bfd/elf.c
@ -1111,12 +1111,12 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
|
||||
{
|
||||
bfd_byte *contents;
|
||||
|
||||
if (!bfd_malloc_and_get_section (abfd, newsect, &contents))
|
||||
if (!_bfd_elf_mmap_section_contents (abfd, newsect, &contents))
|
||||
return false;
|
||||
|
||||
elf_parse_notes (abfd, (char *) contents, hdr->sh_size,
|
||||
hdr->sh_offset, hdr->sh_addralign);
|
||||
free (contents);
|
||||
_bfd_elf_munmap_section_contents (newsect, contents);
|
||||
}
|
||||
|
||||
if ((newsect->flags & SEC_ALLOC) != 0)
|
||||
@ -1686,7 +1686,7 @@ _bfd_elf_print_private_bfd_data (bfd *abfd, void *farg)
|
||||
|
||||
fprintf (f, _("\nDynamic Section:\n"));
|
||||
|
||||
if (!bfd_malloc_and_get_section (abfd, s, &dynbuf))
|
||||
if (!_bfd_elf_mmap_section_contents (abfd, s, &dynbuf))
|
||||
goto error_return;
|
||||
|
||||
elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
|
||||
@ -1808,7 +1808,7 @@ _bfd_elf_print_private_bfd_data (bfd *abfd, void *farg)
|
||||
fprintf (f, "\n");
|
||||
}
|
||||
|
||||
free (dynbuf);
|
||||
_bfd_elf_munmap_section_contents (s, dynbuf);
|
||||
dynbuf = NULL;
|
||||
}
|
||||
|
||||
@ -1865,7 +1865,7 @@ _bfd_elf_print_private_bfd_data (bfd *abfd, void *farg)
|
||||
return true;
|
||||
|
||||
error_return:
|
||||
free (dynbuf);
|
||||
_bfd_elf_munmap_section_contents (s, dynbuf);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -14370,3 +14370,80 @@ _bfd_elf_write_secondary_reloc_section (bfd *abfd, asection *sec)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Mmap in section contents. */
|
||||
|
||||
bool
|
||||
_bfd_elf_mmap_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **buf)
|
||||
{
|
||||
#ifdef USE_MMAP
|
||||
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
|
||||
if (bed->use_mmap
|
||||
&& sec->compress_status == COMPRESS_SECTION_NONE
|
||||
&& (sec->flags & SEC_LINKER_CREATED) == 0)
|
||||
{
|
||||
/* Use mmap only if section size >= the minimum mmap section
|
||||
size. */
|
||||
size_t readsz = bfd_get_section_limit_octets (abfd, sec);
|
||||
size_t allocsz = bfd_get_section_alloc_size (abfd, sec);
|
||||
if (readsz == allocsz && readsz >= _bfd_minimum_mmap_size)
|
||||
{
|
||||
if (sec->contents != NULL)
|
||||
{
|
||||
if (!sec->mmapped_p)
|
||||
abort ();
|
||||
*buf = sec->contents;
|
||||
return true;
|
||||
}
|
||||
if (sec->mmapped_p)
|
||||
abort ();
|
||||
sec->mmapped_p = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
*buf = NULL;
|
||||
bool ret = bfd_get_full_section_contents (abfd, sec, buf);
|
||||
if (ret && sec->mmapped_p)
|
||||
*buf = sec->contents;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Munmap section contents. */
|
||||
|
||||
void
|
||||
_bfd_elf_munmap_section_contents (asection *sec ATTRIBUTE_UNUSED,
|
||||
void *contents)
|
||||
{
|
||||
/* NB: Since _bfd_elf_munmap_section_contents is called like free,
|
||||
CONTENTS may be NULL. */
|
||||
if (contents == NULL)
|
||||
return;
|
||||
|
||||
#ifdef USE_MMAP
|
||||
if (sec->mmapped_p)
|
||||
{
|
||||
/* _bfd_elf_mmap_section_contents may return the previously
|
||||
mapped section contents. Munmap the section contents only
|
||||
if they haven't been cached. */
|
||||
if (elf_section_data (sec)->this_hdr.contents == contents)
|
||||
return;
|
||||
|
||||
/* When _bfd_elf_mmap_section_contents returns CONTENTS as
|
||||
malloced, CONTENTS_ADDR is set to NULL. */
|
||||
if (elf_section_data (sec)->contents_addr != NULL)
|
||||
{
|
||||
/* NB: CONTENTS_ADDR and CONTENTS_SIZE must be valid. */
|
||||
if (munmap (elf_section_data (sec)->contents_addr,
|
||||
elf_section_data (sec)->contents_size) != 0)
|
||||
abort ();
|
||||
sec->mmapped_p = 0;
|
||||
sec->contents = NULL;
|
||||
elf_section_data (sec)->contents_addr = NULL;
|
||||
elf_section_data (sec)->contents_size = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
free (contents);
|
||||
}
|
||||
|
@ -1499,7 +1499,7 @@ elf_i386_scan_relocs (bfd *abfd,
|
||||
/* Get the section contents. */
|
||||
if (elf_section_data (sec)->this_hdr.contents != NULL)
|
||||
contents = elf_section_data (sec)->this_hdr.contents;
|
||||
else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
|
||||
else if (!_bfd_elf_mmap_section_contents (abfd, sec, &contents))
|
||||
{
|
||||
sec->check_relocs_failed = 1;
|
||||
return false;
|
||||
@ -1933,7 +1933,7 @@ elf_i386_scan_relocs (bfd *abfd,
|
||||
if (elf_section_data (sec)->this_hdr.contents != contents)
|
||||
{
|
||||
if (!converted && !_bfd_link_keep_memory (info))
|
||||
free (contents);
|
||||
_bfd_elf_munmap_section_contents (sec, contents);
|
||||
else
|
||||
{
|
||||
/* Cache the section contents for elf_link_input_bfd if any
|
||||
@ -1951,7 +1951,7 @@ elf_i386_scan_relocs (bfd *abfd,
|
||||
|
||||
error_return:
|
||||
if (elf_section_data (sec)->this_hdr.contents != contents)
|
||||
free (contents);
|
||||
_bfd_elf_munmap_section_contents (sec, contents);
|
||||
sec->check_relocs_failed = 1;
|
||||
return false;
|
||||
}
|
||||
|
@ -2057,7 +2057,7 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
/* Get the section contents. */
|
||||
if (elf_section_data (sec)->this_hdr.contents != NULL)
|
||||
contents = elf_section_data (sec)->this_hdr.contents;
|
||||
else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
|
||||
else if (!_bfd_elf_mmap_section_contents (abfd, sec, &contents))
|
||||
{
|
||||
sec->check_relocs_failed = 1;
|
||||
return false;
|
||||
@ -2591,7 +2591,7 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
if (elf_section_data (sec)->this_hdr.contents != contents)
|
||||
{
|
||||
if (!converted && !_bfd_link_keep_memory (info))
|
||||
free (contents);
|
||||
_bfd_elf_munmap_section_contents (sec, contents);
|
||||
else
|
||||
{
|
||||
/* Cache the section contents for elf_link_input_bfd if any
|
||||
@ -2609,7 +2609,7 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info,
|
||||
|
||||
error_return:
|
||||
if (elf_section_data (sec)->this_hdr.contents != contents)
|
||||
free (contents);
|
||||
_bfd_elf_munmap_section_contents (sec, contents);
|
||||
sec->check_relocs_failed = 1;
|
||||
return false;
|
||||
}
|
||||
@ -5273,7 +5273,7 @@ elf_x86_64_get_synthetic_symtab (bfd *abfd,
|
||||
continue;
|
||||
|
||||
/* Get the PLT section contents. */
|
||||
if (!bfd_malloc_and_get_section (abfd, plt, &plt_contents))
|
||||
if (!_bfd_elf_mmap_section_contents (abfd, plt, &plt_contents))
|
||||
break;
|
||||
|
||||
/* Check what kind of PLT it is. */
|
||||
@ -5366,7 +5366,7 @@ elf_x86_64_get_synthetic_symtab (bfd *abfd,
|
||||
|
||||
if (plt_type == plt_unknown)
|
||||
{
|
||||
free (plt_contents);
|
||||
_bfd_elf_munmap_section_contents (plt, plt_contents);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1195,6 +1195,7 @@ elf_checksum_contents (bfd *abfd,
|
||||
Elf_Internal_Shdr i_shdr;
|
||||
Elf_External_Shdr x_shdr;
|
||||
bfd_byte *contents, *free_contents;
|
||||
asection *sec = NULL;
|
||||
|
||||
i_shdr = *i_shdrp[count];
|
||||
i_shdr.sh_offset = 0;
|
||||
@ -1210,8 +1211,6 @@ elf_checksum_contents (bfd *abfd,
|
||||
contents = i_shdr.contents;
|
||||
if (contents == NULL)
|
||||
{
|
||||
asection *sec;
|
||||
|
||||
sec = bfd_section_from_elf_index (abfd, count);
|
||||
if (sec != NULL)
|
||||
{
|
||||
@ -1220,7 +1219,7 @@ elf_checksum_contents (bfd *abfd,
|
||||
{
|
||||
/* Force rereading from file. */
|
||||
sec->flags &= ~SEC_IN_MEMORY;
|
||||
if (!bfd_malloc_and_get_section (abfd, sec, &free_contents))
|
||||
if (!_bfd_elf_mmap_section_contents (abfd, sec, &free_contents))
|
||||
continue;
|
||||
contents = free_contents;
|
||||
}
|
||||
@ -1229,7 +1228,7 @@ elf_checksum_contents (bfd *abfd,
|
||||
if (contents != NULL)
|
||||
{
|
||||
(*process) (contents, i_shdr.sh_size, arg);
|
||||
free (free_contents);
|
||||
_bfd_elf_munmap_section_contents (sec, free_contents);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4426,10 +4426,10 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
|
||||
unsigned int elfsec;
|
||||
unsigned long shlink;
|
||||
|
||||
if (!bfd_malloc_and_get_section (abfd, s, &dynbuf))
|
||||
if (!_bfd_elf_mmap_section_contents (abfd, s, &dynbuf))
|
||||
{
|
||||
error_free_dyn:
|
||||
free (dynbuf);
|
||||
_bfd_elf_munmap_section_contents (s, dynbuf);
|
||||
goto error_return;
|
||||
}
|
||||
|
||||
@ -4535,7 +4535,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
|
||||
elf_tdata (abfd)->is_pie = (dyn.d_un.d_val & DF_1_PIE) != 0;
|
||||
}
|
||||
|
||||
free (dynbuf);
|
||||
_bfd_elf_munmap_section_contents (s, dynbuf);
|
||||
}
|
||||
|
||||
/* DT_RUNPATH overrides DT_RPATH. Do _NOT_ bfd_release, as that
|
||||
@ -8282,7 +8282,7 @@ bfd_elf_get_bfd_needed_list (bfd *abfd,
|
||||
if (s == NULL || s->size == 0 || (s->flags & SEC_HAS_CONTENTS) == 0)
|
||||
return true;
|
||||
|
||||
if (!bfd_malloc_and_get_section (abfd, s, &dynbuf))
|
||||
if (!_bfd_elf_mmap_section_contents (abfd, s, &dynbuf))
|
||||
goto error_return;
|
||||
|
||||
elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
|
||||
@ -8328,12 +8328,12 @@ bfd_elf_get_bfd_needed_list (bfd *abfd,
|
||||
}
|
||||
}
|
||||
|
||||
free (dynbuf);
|
||||
_bfd_elf_munmap_section_contents (s, dynbuf);
|
||||
|
||||
return true;
|
||||
|
||||
error_return:
|
||||
free (dynbuf);
|
||||
_bfd_elf_munmap_section_contents (s, dynbuf);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -148,6 +148,9 @@
|
||||
#ifndef elf_backend_strtab_flags
|
||||
#define elf_backend_strtab_flags 0
|
||||
#endif
|
||||
#ifndef elf_backend_use_mmap
|
||||
#define elf_backend_use_mmap false
|
||||
#endif
|
||||
|
||||
#define bfd_elfNN_bfd_debug_info_start _bfd_void_bfd
|
||||
#define bfd_elfNN_bfd_debug_info_end _bfd_void_bfd
|
||||
@ -979,7 +982,8 @@ static const struct elf_backend_data elfNN_bed =
|
||||
elf_backend_extern_protected_data,
|
||||
elf_backend_always_renumber_dynsyms,
|
||||
elf_backend_linux_prpsinfo32_ugid16,
|
||||
elf_backend_linux_prpsinfo64_ugid16
|
||||
elf_backend_linux_prpsinfo64_ugid16,
|
||||
elf_backend_use_mmap
|
||||
};
|
||||
|
||||
/* Forward declaration for use when initialising alternative_target field. */
|
||||
|
@ -1566,9 +1566,9 @@ elf_x86_size_or_finish_relative_reloc
|
||||
= elf_section_data (sec)->this_hdr.contents;
|
||||
else
|
||||
{
|
||||
if (!bfd_malloc_and_get_section (sec->owner,
|
||||
sec,
|
||||
&contents))
|
||||
if (!_bfd_elf_mmap_section_contents (sec->owner,
|
||||
sec,
|
||||
&contents))
|
||||
info->callbacks->einfo
|
||||
/* xgettext:c-format */
|
||||
(_("%F%P: %pB: failed to allocate memory for section `%pA'\n"),
|
||||
@ -3789,7 +3789,7 @@ _bfd_x86_elf_get_synthetic_symtab (bfd *abfd,
|
||||
count = n;
|
||||
|
||||
for (j = 0; plts[j].name != NULL; j++)
|
||||
free (plts[j].contents);
|
||||
_bfd_elf_munmap_section_contents (plts[j].sec, plts[j].contents);
|
||||
|
||||
free (dynrelbuf);
|
||||
|
||||
|
@ -960,6 +960,7 @@ extern void _bfd_x86_elf_link_report_relative_reloc
|
||||
_bfd_elf_x86_size_relative_relocs
|
||||
#define elf_backend_finish_relative_relocs \
|
||||
_bfd_elf_x86_finish_relative_relocs
|
||||
#define elf_backend_use_mmap true
|
||||
|
||||
#define ELF_P_ALIGN ELF_MINPAGESIZE
|
||||
|
||||
|
59
bfd/libbfd.c
59
bfd/libbfd.c
@ -21,6 +21,7 @@
|
||||
|
||||
#include "sysdep.h"
|
||||
#include "bfd.h"
|
||||
#include "elf-bfd.h"
|
||||
#include "libbfd.h"
|
||||
#include "objalloc.h"
|
||||
|
||||
@ -1196,6 +1197,19 @@ _bfd_generic_get_section_contents (bfd *abfd,
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef USE_MMAP
|
||||
if (section->mmapped_p
|
||||
&& (section->contents != NULL || location != NULL))
|
||||
{
|
||||
_bfd_error_handler
|
||||
/* xgettext:c-format */
|
||||
(_("%pB: mapped section %pA has non-NULL buffer"),
|
||||
abfd, section);
|
||||
bfd_set_error (bfd_error_invalid_operation);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
sz = bfd_get_section_limit_octets (abfd, section);
|
||||
if (offset + count < count
|
||||
|| offset + count > sz
|
||||
@ -1208,8 +1222,49 @@ _bfd_generic_get_section_contents (bfd *abfd,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
|
||||
|| bfd_read (location, count, abfd) != count)
|
||||
if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0)
|
||||
return false;
|
||||
|
||||
#ifdef USE_MMAP
|
||||
if (section->mmapped_p)
|
||||
{
|
||||
if (location != 0
|
||||
|| bfd_get_flavour (abfd) != bfd_target_elf_flavour)
|
||||
abort ();
|
||||
|
||||
int prot = ((section->reloc_count == 0)
|
||||
? PROT_READ : PROT_READ | PROT_WRITE);
|
||||
|
||||
location = bfd_mmap_local
|
||||
(abfd, count, prot, &elf_section_data (section)->contents_addr,
|
||||
&elf_section_data (section)->contents_size);
|
||||
|
||||
if (location == NULL)
|
||||
return false;
|
||||
|
||||
/* Check for iovec not supporting mmap. */
|
||||
if (location != MAP_FAILED)
|
||||
{
|
||||
section->contents = location;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Malloc the buffer and call bfd_read. */
|
||||
location = (bfd_byte *) bfd_malloc (count);
|
||||
if (location == NULL)
|
||||
{
|
||||
if (bfd_get_error () == bfd_error_no_memory)
|
||||
_bfd_error_handler
|
||||
/* xgettext:c-format */
|
||||
(_("error: %pB(%pA) is too large (%#" PRIx64 " bytes)"),
|
||||
abfd, section, (uint64_t) count);
|
||||
return false;
|
||||
}
|
||||
section->contents = location;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (bfd_read (location, count, abfd) != count)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -164,6 +164,15 @@ static void
|
||||
_bfd_delete_bfd (bfd *abfd)
|
||||
{
|
||||
#ifdef USE_MMAP
|
||||
if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
|
||||
{
|
||||
asection *sec;
|
||||
for (sec = abfd->sections; sec != NULL; sec = sec->next)
|
||||
if (sec->mmapped_p)
|
||||
munmap (elf_section_data (sec)->contents_addr,
|
||||
elf_section_data (sec)->contents_size);
|
||||
}
|
||||
|
||||
struct bfd_mmapped *mmapped, *next;
|
||||
for (mmapped = abfd->mmapped; mmapped != NULL; mmapped = next)
|
||||
{
|
||||
|
@ -422,6 +422,9 @@ CODE_FRAGMENT
|
||||
. {* Nonzero if this section uses RELA relocations, rather than REL. *}
|
||||
. unsigned int use_rela_p:1;
|
||||
.
|
||||
. {* Nonzero if this section contents are mmapped, rather than malloced. *}
|
||||
. unsigned int mmapped_p:1;
|
||||
.
|
||||
. {* Bits used by various backends. The generic code doesn't touch
|
||||
. these fields. *}
|
||||
.
|
||||
@ -711,8 +714,8 @@ EXTERNAL
|
||||
. {* linker_mark, linker_has_input, gc_mark, decompress_status, *} \
|
||||
. 0, 0, 1, 0, \
|
||||
. \
|
||||
. {* segment_mark, sec_info_type, use_rela_p, *} \
|
||||
. 0, 0, 0, \
|
||||
. {* segment_mark, sec_info_type, use_rela_p, mmapped_p, *} \
|
||||
. 0, 0, 0, 0, \
|
||||
. \
|
||||
. {* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5, *} \
|
||||
. 0, 0, 0, 0, 0, 0, \
|
||||
@ -1625,6 +1628,8 @@ DESCRIPTION
|
||||
bool
|
||||
bfd_malloc_and_get_section (bfd *abfd, sec_ptr sec, bfd_byte **buf)
|
||||
{
|
||||
if (sec->mmapped_p)
|
||||
abort ();
|
||||
*buf = NULL;
|
||||
return bfd_get_full_section_contents (abfd, sec, buf);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user