aboutsummaryrefslogtreecommitdiff
path: root/bfd/libbfd.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2024-03-01 06:14:20 -0800
committerH.J. Lu <hjl.tools@gmail.com>2024-04-03 09:11:03 -0700
commit584b30e4b3538a64d38bc1da9cfa09fc9355378a (patch)
treec5d9e8cd2d6dbc695737abb77a523e86e7e411d7 /bfd/libbfd.c
parent9ba56acee518492cfe21434b974c807f52ac7950 (diff)
downloadbinutils-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.c59
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;