diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2024-03-01 06:14:20 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2024-04-03 09:11:03 -0700 |
commit | 584b30e4b3538a64d38bc1da9cfa09fc9355378a (patch) | |
tree | c5d9e8cd2d6dbc695737abb77a523e86e7e411d7 /bfd/libbfd.c | |
parent | 9ba56acee518492cfe21434b974c807f52ac7950 (diff) | |
download | binutils-584b30e4b3538a64d38bc1da9cfa09fc9355378a.zip binutils-584b30e4b3538a64d38bc1da9cfa09fc9355378a.tar.gz binutils-584b30e4b3538a64d38bc1da9cfa09fc9355378a.tar.bz2 |
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.
Diffstat (limited to 'bfd/libbfd.c')
-rw-r--r-- | bfd/libbfd.c | 59 |
1 files changed, 57 insertions, 2 deletions
diff --git a/bfd/libbfd.c b/bfd/libbfd.c index a79c814..e5147a2 100644 --- a/bfd/libbfd.c +++ b/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; |