diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index fa1846881d3..6183d962a83 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -1932,7 +1932,7 @@ elf_i386_scan_relocs (bfd *abfd, if (elf_section_data (sec)->this_hdr.contents != contents) { - if (!converted && !_bfd_link_keep_memory (info)) + if (!converted) _bfd_elf_munmap_section_contents (sec, contents); else { diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index ebfd455a822..60aa1802552 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -2590,7 +2590,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)) + if (!converted) _bfd_elf_munmap_section_contents (sec, contents); else { diff --git a/bfd/elflink.c b/bfd/elflink.c index 7e9f4c7f0b0..7a33da0a96c 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -49,6 +49,53 @@ struct elf_info_failed static bool _bfd_elf_fix_symbol_flags (struct elf_link_hash_entry *, struct elf_info_failed *); +/* Return false if linker should avoid caching relocation information + and symbol tables of input files in memory. */ + +static bool +_bfd_elf_link_keep_memory (struct bfd_link_info *info) +{ +#ifdef USE_MMAP + /* Don't cache symbol nor relocation tables if they are mapped in. + NB: Since the --no-keep-memory linker option causes: + + https://sourceware.org/bugzilla/show_bug.cgi?id=31458 + + this is opt-in by each backend. */ + const struct elf_backend_data *bed + = get_elf_backend_data (info->output_bfd); + if (bed->use_mmap) + return false; +#endif + bfd *abfd; + bfd_size_type size; + + if (!info->keep_memory) + return false; + + if (info->max_cache_size == (bfd_size_type) -1) + return true; + + abfd = info->input_bfds; + size = info->cache_size; + do + { + if (size >= info->max_cache_size) + { + /* Over the limit. Reduce the memory usage. */ + info->keep_memory = false; + return false; + } + if (!abfd) + break; + size += abfd->alloc_size; + abfd = abfd->link.next; + } + while (1); + + return true; +} + asection * _bfd_elf_section_for_symbol (struct elf_reloc_cookie *cookie, unsigned long r_symndx, @@ -4182,10 +4229,9 @@ _bfd_elf_link_iterate_on_relocs || bfd_is_abs_section (o->output_section)) continue; - internal_relocs = _bfd_elf_link_info_read_relocs (abfd, info, - o, NULL, - NULL, - _bfd_link_keep_memory (info)); + internal_relocs = _bfd_elf_link_info_read_relocs + (abfd, info, o, NULL, NULL, + _bfd_elf_link_keep_memory (info)); if (internal_relocs == NULL) return false; @@ -5551,10 +5597,9 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) && (s->flags & SEC_DEBUGGING) != 0)) continue; - internal_relocs = _bfd_elf_link_info_read_relocs (abfd, info, - s, NULL, - NULL, - _bfd_link_keep_memory (info)); + internal_relocs = _bfd_elf_link_info_read_relocs + (abfd, info, s, NULL, NULL, + _bfd_elf_link_keep_memory (info)); if (internal_relocs == NULL) goto error_free_vers; @@ -13616,7 +13661,7 @@ init_reloc_cookie (struct elf_reloc_cookie *cookie, info->callbacks->einfo (_("%P%X: can not read symbols: %E\n")); return false; } - if (_bfd_link_keep_memory (info) ) + if (_bfd_elf_link_keep_memory (info) ) { symtab_hdr->contents = (bfd_byte *) cookie->locsyms; info->cache_size += (cookie->locsymcount @@ -13653,9 +13698,9 @@ init_reloc_cookie_rels (struct elf_reloc_cookie *cookie, } else { - cookie->rels = _bfd_elf_link_info_read_relocs (abfd, info, sec, - NULL, NULL, - _bfd_link_keep_memory (info)); + cookie->rels = _bfd_elf_link_info_read_relocs + (abfd, info, sec, NULL, NULL, + _bfd_elf_link_keep_memory (info)); if (cookie->rels == NULL) return false; cookie->rel = cookie->rels; diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h index 889b221a950..7bfc58f12d8 100644 --- a/bfd/libbfd-in.h +++ b/bfd/libbfd-in.h @@ -848,9 +848,6 @@ extern bfd_byte * _bfd_write_unsigned_leb128 extern struct bfd_link_info *_bfd_get_link_info (bfd *) ATTRIBUTE_HIDDEN; -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; diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 0676f461382..bed7d88d4ec 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -854,9 +854,6 @@ extern bfd_byte * _bfd_write_unsigned_leb128 extern struct bfd_link_info *_bfd_get_link_info (bfd *) ATTRIBUTE_HIDDEN; -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; diff --git a/bfd/linker.c b/bfd/linker.c index 36cca9624c2..eb42a78b622 100644 --- a/bfd/linker.c +++ b/bfd/linker.c @@ -3556,38 +3556,3 @@ _bfd_nolink_bfd_define_start_stop (struct bfd_link_info *info ATTRIBUTE_UNUSED, { return (struct bfd_link_hash_entry *) _bfd_ptr_bfd_null_error (sec->owner); } - -/* Return false if linker should avoid caching relocation infomation - and symbol tables of input files in memory. */ - -bool -_bfd_link_keep_memory (struct bfd_link_info * info) -{ - bfd *abfd; - bfd_size_type size; - - if (!info->keep_memory) - return false; - - if (info->max_cache_size == (bfd_size_type) -1) - return true; - - abfd = info->input_bfds; - size = info->cache_size; - do - { - if (size >= info->max_cache_size) - { - /* Over the limit. Reduce the memory usage. */ - info->keep_memory = false; - return false; - } - if (!abfd) - break; - size += abfd->alloc_size; - abfd = abfd->link.next; - } - while (1); - - return true; -}