aboutsummaryrefslogtreecommitdiff
path: root/bfd/libbfd-in.h
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2024-02-29 11:17:01 -0800
committerH.J. Lu <hjl.tools@gmail.com>2024-04-03 09:11:00 -0700
commit9ba56acee518492cfe21434b974c807f52ac7950 (patch)
tree33eba694516786c5249f41fae1c4b60abd068723 /bfd/libbfd-in.h
parentf89ae595dd1f5195dd6e8e57bc2217463c436888 (diff)
downloadbinutils-9ba56acee518492cfe21434b974c807f52ac7950.zip
binutils-9ba56acee518492cfe21434b974c807f52ac7950.tar.gz
binutils-9ba56acee518492cfe21434b974c807f52ac7950.tar.bz2
elf: Use mmap to map in read-only sections
There are many linker input files in LLVM debug build with huge string sections. All these string sections can be treated as read-only. But linker copies all of them into memory which consumes huge amount of memory and slows down linker significantly. Add _bfd_mmap_readonly_persistent and _bfd_mmap_readonly_temporary to mmap in reado-only sections with size >= 4 * page size. NB: All string sections in valid ELF inputs must be null terminated. There is no need to terminate it again and string sections are mmapped as read-only. * bfd.c (bfd_mmapped_entry): New. (bfd_mmapped): Likewise. (bfd): Add mmapped. * bfdwin.c (bfd_get_file_window): Use _bfd_pagesize. * cache.c (cache_bmmap): Remove pagesize_m1 and use pagesize_m1 instead. * elf.c (bfd_elf_get_str_section): Call _bfd_mmap_readonly_persistent instead of _bfd_alloc_and_read. Don't terminate the string section again. (get_hash_table_data): Call _bfd_mmap_readonly_temporary and _bfd_munmap_readonly_temporary instead of _bfd_malloc_and_read and free. (_bfd_elf_get_dynamic_symbols): Call _bfd_mmap_readonly_persistent instead of _bfd_alloc_and_read. Don't terminate the string section again. Call _bfd_mmap_readonly_temporary and _bfd_munmap_readonly_temporary instead of _bfd_malloc_and_read and free. (_bfd_elf_slurp_version_tables): Call _bfd_mmap_readonly_temporary and _bfd_munmap_readonly_temporary instead of _bfd_malloc_and_read and free. * elflink.c (bfd_elf_link_record_dynamic_symbol): Use bfd_malloc to get the unversioned symbol. * libbfd-in.h (_bfd_pagesize): New. (_bfd_pagesize_m1): Likewise. (_bfd_minimum_mmap_size): Likewise. (_bfd_mmap_readonly_persistent): Likewise. (_bfd_mmap_readonly_temporary): Likewise. (_bfd_munmap_readonly_temporary): Likewise. * libbfd.c (bfd_allocate_mmapped_page): New. (_bfd_mmap_readonly_temporary): Likewise. (_bfd_munmap_readonly_temporary): Likewise. (_bfd_mmap_readonly_persistent): Likewise. (_bfd_pagesize): Likewise. (_bfd_pagesize_m1): Likewise. (_bfd_minimum_mmap_size): Likewise. (bfd_init_pagesize): Likewise. * lynx-core.c (lynx_core_file_p): Use _bfd_pagesize. * opncls.c (_bfd_delete_bfd): Munmap tracked mmapped memories. * sysdep.h (MAP_ANONYMOUS): New. Define if undefined. * bfd-in2.h: Regenerated. * libbfd.h: Likewise.
Diffstat (limited to 'bfd/libbfd-in.h')
-rw-r--r--bfd/libbfd-in.h29
1 files changed, 29 insertions, 0 deletions
diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
index b8b2ce7..c5a79cf 100644
--- a/bfd/libbfd-in.h
+++ b/bfd/libbfd-in.h
@@ -851,6 +851,10 @@ extern struct bfd_link_info *_bfd_get_link_info (bfd *)
extern bool _bfd_link_keep_memory (struct bfd_link_info *)
ATTRIBUTE_HIDDEN;
+extern uintptr_t _bfd_pagesize ATTRIBUTE_HIDDEN;
+extern uintptr_t _bfd_pagesize_m1 ATTRIBUTE_HIDDEN;
+extern uintptr_t _bfd_minimum_mmap_size ATTRIBUTE_HIDDEN;
+
#if GCC_VERSION >= 7000
#define _bfd_mul_overflow(a, b, res) __builtin_mul_overflow (a, b, res)
#else
@@ -888,6 +892,19 @@ _bfd_alloc_and_read (bfd *abfd, bfd_size_type asize, bfd_size_type rsize)
return NULL;
}
+#ifdef USE_MMAP
+extern void *_bfd_mmap_readonly_persistent
+ (bfd *, size_t) ATTRIBUTE_HIDDEN;
+extern void *_bfd_mmap_readonly_temporary
+ (bfd *, size_t, void **, size_t *) ATTRIBUTE_HIDDEN;
+extern void _bfd_munmap_readonly_temporary
+ (void *, size_t) ATTRIBUTE_HIDDEN;
+#else
+#define _bfd_mmap_readonly_persistent(abfd, rsize) \
+ _bfd_alloc_and_read (abfd, rsize, rsize)
+#define _bfd_munmap_readonly_temporary(ptr, rsize) free (ptr)
+#endif
+
static inline void *
_bfd_malloc_and_read (bfd *abfd, bfd_size_type asize, bfd_size_type rsize)
{
@@ -910,3 +927,15 @@ _bfd_malloc_and_read (bfd *abfd, bfd_size_type asize, bfd_size_type rsize)
}
return NULL;
}
+
+#ifndef USE_MMAP
+static inline void *
+_bfd_mmap_readonly_temporary (bfd *abfd, size_t rsize, void **map_addr,
+ size_t *map_size)
+{
+ void *mem = _bfd_malloc_and_read (abfd, rsize, rsize);
+ *map_addr = mem;
+ *map_size = rsize;
+ return mem;
+}
+#endif