| /* ELF linking support for BFD. |
| Copyright (C) 1995-2019 Free Software Foundation, Inc. |
| |
| This file is part of BFD, the Binary File Descriptor library. |
| |
| This program is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 3 of the License, or |
| (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program; if not, write to the Free Software |
| Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
| MA 02110-1301, USA. */ |
| |
| #include "sysdep.h" |
| #include "bfd.h" |
| #include "bfdlink.h" |
| #include "libbfd.h" |
| #define ARCH_SIZE 0 |
| #include "elf-bfd.h" |
| #include "safe-ctype.h" |
| #include "libiberty.h" |
| #include "objalloc.h" |
| #if BFD_SUPPORTS_PLUGINS |
| #include "plugin-api.h" |
| #include "plugin.h" |
| #endif |
| |
| /* This struct is used to pass information to routines called via |
| elf_link_hash_traverse which must return failure. */ |
| |
| struct elf_info_failed |
| { |
| struct bfd_link_info *info; |
| bfd_boolean failed; |
| }; |
| |
| /* This structure is used to pass information to |
| _bfd_elf_link_find_version_dependencies. */ |
| |
| struct elf_find_verdep_info |
| { |
| /* General link information. */ |
| struct bfd_link_info *info; |
| /* The number of dependencies. */ |
| unsigned int vers; |
| /* Whether we had a failure. */ |
| bfd_boolean failed; |
| }; |
| |
| static bfd_boolean _bfd_elf_fix_symbol_flags |
| (struct elf_link_hash_entry *, struct elf_info_failed *); |
| |
| asection * |
| _bfd_elf_section_for_symbol (struct elf_reloc_cookie *cookie, |
| unsigned long r_symndx, |
| bfd_boolean discard) |
| { |
| if (r_symndx >= cookie->locsymcount |
| || ELF_ST_BIND (cookie->locsyms[r_symndx].st_info) != STB_LOCAL) |
| { |
| struct elf_link_hash_entry *h; |
| |
| h = cookie->sym_hashes[r_symndx - cookie->extsymoff]; |
| |
| while (h->root.type == bfd_link_hash_indirect |
| || h->root.type == bfd_link_hash_warning) |
| h = (struct elf_link_hash_entry *) h->root.u.i.link; |
| |
| if ((h->root.type == bfd_link_hash_defined |
| || h->root.type == bfd_link_hash_defweak) |
| && discarded_section (h->root.u.def.section)) |
| return h->root.u.def.section; |
| else |
| return NULL; |
| } |
| else |
| { |
| /* It's not a relocation against a global symbol, |
| but it could be a relocation against a local |
| symbol for a discarded section. */ |
| asection *isec; |
| Elf_Internal_Sym *isym; |
| |
| /* Need to: get the symbol; get the section. */ |
| isym = &cookie->locsyms[r_symndx]; |
| isec = bfd_section_from_elf_index (cookie->abfd, isym->st_shndx); |
| if (isec != NULL |
| && discard ? discarded_section (isec) : 1) |
| return isec; |
| } |
| return NULL; |
| } |
| |
| /* Define a symbol in a dynamic linkage section. */ |
| |
| struct elf_link_hash_entry * |
| _bfd_elf_define_linkage_sym (bfd *abfd, |
| struct bfd_link_info *info, |
| asection *sec, |
| const char *name) |
| { |
| struct elf_link_hash_entry *h; |
| struct bfd_link_hash_entry *bh; |
| const struct elf_backend_data *bed; |
| |
| h = elf_link_hash_lookup (elf_hash_table (info), name, FALSE, FALSE, FALSE); |
| if (h != NULL) |
| { |
| /* Zap symbol defined in an as-needed lib that wasn't linked. |
| This is a symptom of a larger problem: Absolute symbols |
| defined in shared libraries can't be overridden, because we |
| lose the link to the bfd which is via the symbol section. */ |
| h->root.type = bfd_link_hash_new; |
| bh = &h->root; |
| } |
| else |
| bh = NULL; |
| |
| bed = get_elf_backend_data (abfd); |
| if (!_bfd_generic_link_add_one_symbol (info, abfd, name, BSF_GLOBAL, |
| sec, 0, NULL, FALSE, bed->collect, |
| &bh)) |
| return NULL; |
| h = (struct elf_link_hash_entry *) bh; |
| BFD_ASSERT (h != NULL); |
| h->def_regular = 1; |
| h->non_elf = 0; |
| h->root.linker_def = 1; |
| h->type = STT_OBJECT; |
| if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL) |
| h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN; |
| |
| (*bed->elf_backend_hide_symbol) (info, h, TRUE); |
| return h; |
| } |
| |
| bfd_boolean |
| _bfd_elf_create_got_section (bfd *abfd, struct bfd_link_info *info) |
| { |
| flagword flags; |
| asection *s; |
| struct elf_link_hash_entry *h; |
| const struct elf_backend_data *bed = get_elf_backend_data (abfd); |
| struct elf_link_hash_table *htab = elf_hash_table (info); |
| |
| /* This function may be called more than once. */ |
| if (htab->sgot != NULL) |
| return TRUE; |
| |
| flags = bed->dynamic_sec_flags; |
| |
| s = bfd_make_section_anyway_with_flags (abfd, |
| (bed->rela_plts_and_copies_p |
| ? ".rela.got" : ".rel.got"), |
| (bed->dynamic_sec_flags |
| | SEC_READONLY)); |
| if (s == NULL |
| || !bfd_set_section_alignment (s, bed->s->log_file_align)) |
| return FALSE; |
| htab->srelgot = s; |
| |
| s = bfd_make_section_anyway_with_flags (abfd, ".got", flags); |
| if (s == NULL |
| || !bfd_set_section_alignment (s, bed->s->log_file_align)) |
| return FALSE; |
| htab->sgot = s; |
| |
| if (bed->want_got_plt) |
| { |
| s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags); |
| if (s == NULL |
| || !bfd_set_section_alignment (s, bed->s->log_file_align)) |
| return FALSE; |
| htab->sgotplt = s; |
| } |
| |
| /* The first bit of the global offset table is the header. */ |
| s->size += bed->got_header_size; |
| |
| if (bed->want_got_sym) |
| { |
| /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got |
| (or .got.plt) section. We don't do this in the linker script |
| because we don't want to define the symbol if we are not creating |
| a global offset table. */ |
| h = _bfd_elf_define_linkage_sym (abfd, info, s, |
| "_GLOBAL_OFFSET_TABLE_"); |
| elf_hash_table (info)->hgot = h; |
| if (h == NULL) |
| return FALSE; |
| } |
| |
| return TRUE; |
| } |
| |
| /* Create a strtab to hold the dynamic symbol names. */ |
| static bfd_boolean |
| _bfd_elf_link_create_dynstrtab (bfd *abfd, struct bfd_link_info *info) |
| { |
| struct elf_link_hash_table *hash_table; |
| |
| hash_table = elf_hash_table (info); |
| if (hash_table->dynobj == NULL) |
| { |
| /* We may not set dynobj, an input file holding linker created |
| dynamic sections to abfd, which may be a dynamic object with |
| its own dynamic sections. We need to find a normal input file |
| to hold linker created sections if possible. */ |
| if ((abfd->flags & (DYNAMIC | BFD_PLUGIN)) != 0) |
| { |
| bfd *ibfd; |
| asection *s; |
| for (ibfd = info->input_bfds; ibfd; ibfd = ibfd->link.next) |
| if ((ibfd->flags |
| & (DYNAMIC | BFD_LINKER_CREATED | BFD_PLUGIN)) == 0 |
| && bfd_get_flavour (ibfd) == bfd_target_elf_flavour |
| && elf_object_id (ibfd) == elf_hash_table_id (hash_table) |
| && !((s = ibfd->sections) != NULL |
| && s->sec_info_type == SEC_INFO_TYPE_JUST_SYMS)) |
| { |
| abfd = ibfd; |
| break; |
| } |
| } |
| hash_table->dynobj = abfd; |
| } |
| |
| if (hash_table->dynstr == NULL) |
| { |
| hash_table->dynstr = _bfd_elf_strtab_init (); |
| if (hash_table->dynstr == NULL) |
| return FALSE; |
| } |
| return TRUE; |
| } |
| |
| /* Create some sections which will be filled in with dynamic linking |
| information. ABFD is an input file which requires dynamic sections |
| to be created. The dynamic sections take up virtual memory space |
| when the final executable is run, so we need to create them before |
| addresses are assigned to the output sections. We work out the |
| actual contents and size of these sections later. */ |
| |
| bfd_boolean |
| _bfd_elf_link_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) |
| { |
| flagword flags; |
| asection *s; |
| const struct elf_backend_data *bed; |
| struct elf_link_hash_entry *h; |
| |
| if (! is_elf_hash_table (info->hash)) |
| return FALSE; |
| |
| if (elf_hash_table (info)->dynamic_sections_created) |
| return TRUE; |
| |
| if (!_bfd_elf_link_create_dynstrtab (abfd, info)) |
| return FALSE; |
| |
| abfd = elf_hash_table (info)->dynobj; |
| bed = get_elf_backend_data (abfd); |
| |
| flags = bed->dynamic_sec_flags; |
| |
| /* A dynamically linked executable has a .interp section, but a |
| shared library does not. */ |
| if (bfd_link_executable (info) && !info->nointerp) |
| { |
| s = bfd_make_section_anyway_with_flags (abfd, ".interp", |
| flags | SEC_READONLY); |
| if (s == NULL) |
| return FALSE; |
| } |
| |
| /* Create sections to hold version informations. These are removed |
| if they are not needed. */ |
| s = bfd_make_section_anyway_with_flags (abfd, ".gnu.version_d", |
| flags | SEC_READONLY); |
| if (s == NULL |
| || !bfd_set_section_alignment (s, bed->s->log_file_align)) |
| return FALSE; |
| |
| s = bfd_make_section_anyway_with_flags (abfd, ".gnu.version", |
| flags | SEC_READONLY); |
| if (s == NULL |
| || !bfd_set_section_alignment (s, 1)) |
| return FALSE; |
| |
| s = bfd_make_section_anyway_with_flags (abfd, ".gnu.version_r", |
| flags | SEC_READONLY); |
| if (s == NULL |
| || !bfd_set_section_alignment (s, bed->s->log_file_align)) |
| return FALSE; |
| |
| s = bfd_make_section_anyway_with_flags (abfd, ".dynsym", |
| flags | SEC_READONLY); |
| if (s == NULL |
| || !bfd_set_section_alignment (s, bed->s->log_file_align)) |
| return FALSE; |
| elf_hash_table (info)->dynsym = s; |
| |
| s = bfd_make_section_anyway_with_flags (abfd, ".dynstr", |
| flags | SEC_READONLY); |
| if (s == NULL) |
| return FALSE; |
| |
| s = bfd_make_section_anyway_with_flags (abfd, ".dynamic", flags); |
| if (s == NULL |
| || !bfd_set_section_alignment (s, bed->s->log_file_align)) |
| return FALSE; |
| |
| /* The special symbol _DYNAMIC is always set to the start of the |
| .dynamic section. We could set _DYNAMIC in a linker script, but we |
| only want to define it if we are, in fact, creating a .dynamic |
| section. We don't want to define it if there is no .dynamic |
| section, since on some ELF platforms the start up code examines it |
| to decide how to initialize the process. */ |
| h = _bfd_elf_define_linkage_sym (abfd, info, s, "_DYNAMIC"); |
| elf_hash_table (info)->hdynamic = h; |
| if (h == NULL) |
| return FALSE; |
| |
| if (info->emit_hash) |
| { |
| s = bfd_make_section_anyway_with_flags (abfd, ".hash", |
| flags | SEC_READONLY); |
| if (s == NULL |
| || !bfd_set_section_alignment (s, bed->s->log_file_align)) |
| return FALSE; |
| elf_section_data (s)->this_hdr.sh_entsize = bed->s->sizeof_hash_entry; |
| } |
| |
| if (info->emit_gnu_hash && bed->record_xhash_symbol == NULL) |
| { |
| s = bfd_make_section_anyway_with_flags (abfd, ".gnu.hash", |
| flags | SEC_READONLY); |
| if (s == NULL |
| || !bfd_set_section_alignment (s, bed->s->log_file_align)) |
| return FALSE; |
| /* For 64-bit ELF, .gnu.hash is a non-uniform entity size section: |
| 4 32-bit words followed by variable count of 64-bit words, then |
| variable count of 32-bit words. */ |
| if (bed->s->arch_size == 64) |
| elf_section_data (s)->this_hdr.sh_entsize = 0; |
| else |
| elf_section_data (s)->this_hdr.sh_entsize = 4; |
| } |
| |
| /* Let the backend create the rest of the sections. This lets the |
| backend set the right flags. The backend will normally create |
| the .got and .plt sections. */ |
| if (bed->elf_backend_create_dynamic_sections == NULL |
| || ! (*bed->elf_backend_create_dynamic_sections) (abfd, info)) |
| return FALSE; |
| |
| elf_hash_table (info)->dynamic_sections_created = TRUE; |
| |
| return TRUE; |
| } |
| |
| /* Create dynamic sections when linking against a dynamic object. */ |
| |
| bfd_boolean |
| _bfd_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) |
| { |
| flagword flags, pltflags; |
| struct elf_link_hash_entry *h; |
| asection *s; |
| const struct elf_backend_data *bed = get_elf_backend_data (abfd); |
| struct elf_link_hash_table *htab = elf_hash_table (info); |
| |
| /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and |
| .rel[a].bss sections. */ |
| flags = bed->dynamic_sec_flags; |
| |
| pltflags = flags; |
| if (bed->plt_not_loaded) |
| /* We do not clear SEC_ALLOC here because we still want the OS to |
| allocate space for the section; it's just that there's nothing |
| to read in from the object file. */ |
| pltflags &= ~ (SEC_CODE | SEC_LOAD | SEC_HAS_CONTENTS); |
| else |
| pltflags |= SEC_ALLOC | SEC_CODE | SEC_LOAD; |
| if (bed->plt_readonly) |
| pltflags |= SEC_READONLY; |
| |
| s = bfd_make_section_anyway_with_flags (abfd, ".plt", pltflags); |
| if (s == NULL |
| || !bfd_set_section_alignment (s, bed->plt_alignment)) |
| return FALSE; |
| htab->splt = s; |
| |
| /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the |
| .plt section. */ |
| if (bed->want_plt_sym) |
| { |
| h = _bfd_elf_define_linkage_sym (abfd, info, s, |
| "_PROCEDURE_LINKAGE_TABLE_"); |
| elf_hash_table (info)->hplt = h; |
| if (h == NULL) |
| return FALSE; |
| } |
| |
| s = bfd_make_section_anyway_with_flags (abfd, |
| (bed->rela_plts_and_copies_p |
| ? ".rela.plt" : ".rel.plt"), |
| flags | SEC_READONLY); |
| if (s == NULL |
| || !bfd_set_section_alignment (s, bed->s->log_file_align)) |
| return FALSE; |
| htab->srelplt = s; |
| |
| if (! _bfd_elf_create_got_section (abfd, info)) |
| return FALSE; |
| |
| if (bed->want_dynbss) |
| { |
| /* The .dynbss section is a place to put symbols which are defined |
| by dynamic objects, are referenced by regular objects, and are |
| not functions. We must allocate space for them in the process |
| image and use a R_*_COPY reloc to tell the dynamic linker to |
| initialize them at run time. The linker script puts the .dynbss |
| section into the .bss section of the final image. */ |
| s = bfd_make_section_anyway_with_flags (abfd, ".dynbss", |
| SEC_ALLOC | SEC_LINKER_CREATED); |
| if (s == NULL) |
| return FALSE; |
| htab->sdynbss = s; |
| |
| if (bed->want_dynrelro) |
| { |
| /* Similarly, but for symbols that were originally in read-only |
| sections. This section doesn't really need to have contents, |
| but make it like other .data.rel.ro sections. */ |
| s = bfd_make_section_anyway_with_flags (abfd, ".data.rel.ro", |
| flags); |
| if (s == NULL) |
| return FALSE; |
| htab->sdynrelro = s; |
| } |
| |
| /* The .rel[a].bss section holds copy relocs. This section is not |
| normally needed. We need to create it here, though, so that the |
| linker will map it to an output section. We can't just create it |
| only if we need it, because we will not know whether we need it |
| until we have seen all the input files, and the first time the |
| main linker code calls BFD after examining all the input files |
| (size_dynamic_sections) the input sections have already been |
| mapped to the output sections. If the section turns out not to |
| be needed, we can discard it later. We will never need this |
| section when generating a shared object, since they do not use |
| copy relocs. */ |
| if (bfd_link_executable (info)) |
| { |
| s = bfd_make_section_anyway_with_flags (abfd, |
| (bed->rela_plts_and_copies_p |
| ? ".rela.bss" : ".rel.bss"), |
| flags | SEC_READONLY); |
| if (s == NULL |
| || !bfd_set_section_alignment (s, bed->s->log_file_align)) |
| return FALSE; |
| htab->srelbss = s; |
| |
| if (bed->want_dynrelro) |
| { |
| s = (bfd_make_section_anyway_with_flags |
| (abfd, (bed->rela_plts_and_copies_p |
| ? ".rela.data.rel.ro" : ".rel.data.rel.ro"), |
| flags | SEC_READONLY)); |
| if (s == NULL |
| || !bfd_set_section_alignment (s, bed->s->log_file_align)) |
| return FALSE; |
| htab->sreldynrelro = s; |
| } |
| } |
| } |
| |
| return TRUE; |
| } |
| |
| /* Record a new dynamic symbol. We record the dynamic symbols as we |
| read the input files, since we need to have a list of all of them |
| before we can determine the final sizes of the output sections. |
| Note that we may actually call this function even though we are not |
| going to output any dynamic symbols; in some cases we know that a |
| symbol should be in the dynamic symbol table, but only if there is |
| one. */ |
| |
| bfd_boolean |
| bfd_elf_link_record_dynamic_symbol (struct bfd_link_info *info, |
| struct elf_link_hash_entry *h) |
| { |
| if (h->dynindx == -1) |
| { |
| struct elf_strtab_hash *dynstr; |
| char *p; |
| const char *name; |
| size_t indx; |
| |
| /* XXX: The ABI draft says the linker must turn hidden and |
| internal symbols into STB_LOCAL symbols when producing the |
| DSO. However, if ld.so honors st_other in the dynamic table, |
| this would not be necessary. */ |
| switch (ELF_ST_VISIBILITY (h->other)) |
| { |
| case STV_INTERNAL: |
| case STV_HIDDEN: |
| if (h->root.type != bfd_link_hash_undefined |
| && h->root.type != bfd_link_hash_undefweak) |
| { |
| h->forced_local = 1; |
| if (!elf_hash_table (info)->is_relocatable_executable) |
| return TRUE; |
| } |
| |
| default: |
| break; |
| } |
| |
| h->dynindx = elf_hash_table (info)->dynsymcount; |
| ++elf_hash_table (info)->dynsymcount; |
| |
| dynstr = elf_hash_table (info)->dynstr; |
| if (dynstr == NULL) |
| { |
| /* Create a strtab to hold the dynamic symbol names. */ |
| elf_hash_table (info)->dynstr = dynstr = _bfd_elf_strtab_init (); |
| if (dynstr == NULL) |
| return FALSE; |
| } |
| |
| /* We don't put any version information in the dynamic string |
| table. */ |
| name = h->root.root.string; |
| p = strchr (name, ELF_VER_CHR); |
| if (p != NULL) |
| /* We know that the p points into writable memory. In fact, |
| there are only a few symbols that have read-only names, being |
| those like _GLOBAL_OFFSET_TABLE_ that are created specially |
| by the backends. Most symbols will have names pointing into |
| an ELF string table read from a file, or to objalloc memory. */ |
| *p = 0; |
| |
| indx = _bfd_elf_strtab_add (dynstr, name, p != NULL); |
| |
| if (p != NULL) |
| *p = ELF_VER_CHR; |
| |
| if (indx == (size_t) -1) |
| return FALSE; |
| h->dynstr_index = indx; |
| } |
| |
| return TRUE; |
| } |
| |
| /* Mark a symbol dynamic. */ |
| |
| static void |
| bfd_elf_link_mark_dynamic_symbol (struct bfd_link_info *info, |
| struct elf_link_hash_entry *h, |
| Elf_Internal_Sym *sym) |
| { |
| struct bfd_elf_dynamic_list *d = info->dynamic_list; |
| |
| /* It may be called more than once on the same H. */ |
| if(h->dynamic || bfd_link_relocatable (info)) |
| return; |
| |
| if ((info->dynamic_data |
| && (h->type == STT_OBJECT |
| || h->type == STT_COMMON |
| || (sym != NULL |
| && (ELF_ST_TYPE (sym->st_info) == STT_OBJECT |
| || ELF_ST_TYPE (sym->st_info) == STT_COMMON)))) |
| || (d != NULL |
| && h->non_elf |
| && (*d->match) (&d->head, NULL, h->root.root.string))) |
| { |
| h->dynamic = 1; |
| /* NB: If a symbol is made dynamic by --dynamic-list, it has |
| non-IR reference. */ |
| h->root.non_ir_ref_dynamic = 1; |
| } |
| } |
| |
| /* Record an assignment to a symbol made by a linker script. We need |
| this in case some dynamic object refers to this symbol. */ |
| |
| bfd_boolean |
| bfd_elf_record_link_assignment (bfd *output_bfd, |
| struct bfd_link_info *info, |
| const char *name, |
| bfd_boolean provide, |
| bfd_boolean hidden) |
| { |
| struct elf_link_hash_entry *h, *hv; |
| struct elf_link_hash_table *htab; |
| const struct elf_backend_data *bed; |
| |
| if (!is_elf_hash_table (info->hash)) |
| return TRUE; |
| |
| htab = elf_hash_table (info); |
| h = elf_link_hash_lookup (htab, name, !provide, TRUE, FALSE); |
| if (h == NULL) |
| return provide; |
| |
| if (h->root.type == bfd_link_hash_warning) |
| h = (struct elf_link_hash_entry *) h->root.u.i.link; |
| |
| if (h->versioned == unknown) |
| { |
| /* Set versioned if symbol version is unknown. */ |
| char *version = strrchr (name, ELF_VER_CHR); |
| if (version) |
| { |
| if (version > name && version[-1] != ELF_VER_CHR) |
| h->versioned = versioned_hidden; |
| else |
| h->versioned = versioned; |
| } |
| } |
| |
| /* Symbols defined in a linker script but not referenced anywhere |
| else will have non_elf set. */ |
| if (h->non_elf) |
| { |
| bfd_elf_link_mark_dynamic_symbol (info, h, NULL); |
| h->non_elf = 0; |
| } |
| |
| switch (h->root.type) |
| { |
| case bfd_link_hash_defined: |
| case bfd_link_hash_defweak: |
| case bfd_link_hash_common: |
| break; |
| case bfd_link_hash_undefweak: |
| case bfd_link_hash_undefined: |
| /* Since we're defining the symbol, don't let it seem to have not |
| been defined. record_dynamic_symbol and size_dynamic_sections |
| may depend on this. */ |
| h->root.type = bfd_link_hash_new; |
| if (h->root.u.undef.next != NULL || htab->root.undefs_tail == &h->root) |
| bfd_link_repair_undef_list (&htab->root); |
| break; |
| case bfd_link_hash_new: |
| break; |
| case bfd_link_hash_indirect: |
| /* We had a versioned symbol in a dynamic library. We make the |
| the versioned symbol point to this one. */ |
| bed = get_elf_backend_data (output_bfd); |
| hv = h; |
| while (hv->root.type == bfd_link_hash_indirect |
| || hv->root.type == bfd_link_hash_warning) |
| hv = (struct elf_link_hash_entry *) hv->root.u.i.link; |
| /* We don't need to update h->root.u since linker will set them |
| later. */ |
| h->root.type = bfd_link_hash_undefined; |
| hv->root.type = bfd_link_hash_indirect; |
| hv->root.u.i.link = (struct bfd_link_hash_entry *) h; |
| (*bed->elf_backend_copy_indirect_symbol) (info, h, hv); |
| break; |
| default: |
| BFD_FAIL (); |
| return FALSE; |
| } |
| |
| /* If this symbol is being provided by the linker script, and it is |
| currently defined by a dynamic object, but not by a regular |
| object, then mark it as undefined so that the generic linker will |
| force the correct value. */ |
| if (provide |
| && h->def_dynamic |
| && !h->def_regular) |
| h->root.type = bfd_link_hash_undefined; |
| |
| /* If this symbol is currently defined by a dynamic object, but not |
| by a regular object, then clear out any version information because |
| the symbol will not be associated with the dynamic object any |
| more. */ |
| if (h->def_dynamic && !h->def_regular) |
| h->verinfo.verdef = NULL; |
| |
| /* Make sure this symbol is not garbage collected. */ |
| h->mark = 1; |
| |
| h->def_regular = 1; |
| |
| if (hidden) |
| { |
| bed = get_elf_backend_data (output_bfd); |
| if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL) |
| h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN; |
| (*bed->elf_backend_hide_symbol) (info, h, TRUE); |
| } |
| |
| /* STV_HIDDEN and STV_INTERNAL symbols must be STB_LOCAL in shared objects |
| and executables. */ |
| if (!bfd_link_relocatable (info) |
| && h->dynindx != -1 |
| && (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN |
| || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL)) |
| h->forced_local = 1; |
| |
| if ((h->def_dynamic |
| || h->ref_dynamic |
| || bfd_link_dll (info) |
| || elf_hash_table (info)->is_relocatable_executable) |
| && !h->forced_local |
| && h->dynindx == -1) |
| { |
| if (! bfd_elf_link_record_dynamic_symbol (info, h)) |
| return FALSE; |
| |
| /* If this is a weak defined symbol, and we know a corresponding |
| real symbol from the same dynamic object, make sure the real |
| symbol is also made into a dynamic symbol. */ |
| if (h->is_weakalias) |
| { |
| struct elf_link_hash_entry *def = weakdef (h); |
| |
| if (def->dynindx == -1 |
| && !bfd_elf_link_record_dynamic_symbol (info, def)) |
| return FALSE; |
| } |
| } |
| |
| return TRUE; |
| } |
| |
| /* Record a new local dynamic symbol. Returns 0 on failure, 1 on |
| success, and 2 on a failure caused by attempting to record a symbol |
| in a discarded section, eg. a discarded link-once section symbol. */ |
| |
| int |
| bfd_elf_link_record_local_dynamic_symbol (struct bfd_link_info *info, |
| bfd *input_bfd, |
| long input_indx) |
| { |
| bfd_size_type amt; |
| struct elf_link_local_dynamic_entry *entry; |
| struct elf_link_hash_table *eht; |
| struct elf_strtab_hash *dynstr; |
| size_t dynstr_index; |
| char *name; |
| Elf_External_Sym_Shndx eshndx; |
| char esym[sizeof (Elf64_External_Sym)]; |
| |
| if (! is_elf_hash_table (info->hash)) |
| return 0; |
| |
| /* See if the entry exists already. */ |
| for (entry = elf_hash_table (info)->dynlocal; entry ; entry = entry->next) |
| if (entry->input_bfd == input_bfd && entry->input_indx == input_indx) |
| return 1; |
| |
| amt = sizeof (*entry); |
| entry = (struct elf_link_local_dynamic_entry *) bfd_alloc (input_bfd, amt); |
| if (entry == NULL) |
| return 0; |
| |
| /* Go find the symbol, so that we can find it's name. */ |
| if (!bfd_elf_get_elf_syms (input_bfd, &elf_tdata (input_bfd)->symtab_hdr, |
| 1, input_indx, &entry->isym, esym, &eshndx)) |
| { |
| bfd_release (input_bfd, entry); |
| return 0; |
| } |
| |
| if (entry->isym.st_shndx != SHN_UNDEF |
| && entry->isym.st_shndx < SHN_LORESERVE) |
| { |
| asection *s; |
| |
| s = bfd_section_from_elf_index (input_bfd, entry->isym.st_shndx); |
| if (s == NULL || bfd_is_abs_section (s->output_section)) |
| { |
| /* We can still bfd_release here as nothing has done another |
| bfd_alloc. We can't do this later in this function. */ |
| bfd_release (input_bfd, entry); |
| return 2; |
| } |
| } |
| |
| name = (bfd_elf_string_from_elf_section |
| (input_bfd, elf_tdata (input_bfd)->symtab_hdr.sh_link, |
| entry->isym.st_name)); |
| |
| dynstr = elf_hash_table (info)->dynstr; |
| if (dynstr == NULL) |
| { |
| /* Create a strtab to hold the dynamic symbol names. */ |
| elf_hash_table (info)->dynstr = dynstr = _bfd_elf_strtab_init (); |
| if (dynstr == NULL) |
| return 0; |
| } |
| |
| dynstr_index = _bfd_elf_strtab_add (dynstr, name, FALSE); |
| if (dynstr_index == (size_t) -1) |
| return 0; |
| entry->isym.st_name = dynstr_index; |
| |
| eht = elf_hash_table (info); |
| |
| entry->next = eht->dynlocal; |
| eht->dynlocal = entry; |
| entry->input_bfd = input_bfd; |
| entry->input_indx = input_indx; |
| eht->dynsymcount++; |
| |
| /* Whatever binding the symbol had before, it's now local. */ |
| entry->isym.st_info |
| = ELF_ST_INFO (STB_LOCAL, ELF_ST_TYPE (entry->isym.st_info)); |
| |
| /* The dynindx will be set at the end of size_dynamic_sections. */ |
| |
| return 1; |
| } |
| |
| /* Return the dynindex of a local dynamic symbol. */ |
| |
| long |
| _bfd_elf_link_lookup_local_dynindx (struct bfd_link_info *info, |
| bfd *input_bfd, |
| long input_indx) |
| { |
| struct elf_link_local_dynamic_entry *e; |
| |
| for (e = elf_hash_table (info)->dynlocal; e ; e = e->next) |
| if (e->input_bfd == input_bfd && e->input_indx == input_indx) |
| return e->dynindx; |
| return -1; |
| } |
| |
| /* This function is used to renumber the dynamic symbols, if some of |
| them are removed because they are marked as local. This is called |
| via elf_link_hash_traverse. */ |
| |
| static bfd_boolean |
| elf_link_renumber_hash_table_dynsyms (struct elf_link_hash_entry *h, |
| void *data) |
| { |
| size_t *count = (size_t *) data; |
| |
| if (h->forced_local) |
| return TRUE; |
| |
| if (h->dynindx != -1) |
| h->dynindx = ++(*count); |
| |
| return TRUE; |
| } |
| |
| |
| /* Like elf_link_renumber_hash_table_dynsyms, but just number symbols with |
| STB_LOCAL binding. */ |
| |
| static bfd_boolean |
| elf_link_renumber_local_hash_table_dynsyms (struct elf_link_hash_entry *h, |
| void *data) |
| { |
| size_t *count = (size_t *) data; |
| |
| if (!h->forced_local) |
| return TRUE; |
| |
| if (h->dynindx != -1) |
| h->dynindx = ++(*count); |
| |
| return TRUE; |
| } |
| |
| /* Return true if the dynamic symbol for a given section should be |
| omitted when creating a shared library. */ |
| bfd_boolean |
| _bfd_elf_omit_section_dynsym_default (bfd *output_bfd ATTRIBUTE_UNUSED, |
| struct bfd_link_info *info, |
| asection *p) |
| { |
| struct elf_link_hash_table *htab; |
| asection *ip; |
| |
| switch (elf_section_data (p)->this_hdr.sh_type) |
| { |
| case SHT_PROGBITS: |
| case SHT_NOBITS: |
| /* If sh_type is yet undecided, assume it could be |
| SHT_PROGBITS/SHT_NOBITS. */ |
| case SHT_NULL: |
| htab = elf_hash_table (info); |
| if (htab->text_index_section != NULL) |
| return p != htab->text_index_section && p != htab->data_index_section; |
| |
| return (htab->dynobj != NULL |
| && (ip = bfd_get_linker_section (htab->dynobj, p->name)) != NULL |
| && ip->output_section == p); |
| |
| /* There shouldn't be section relative relocations |
| against any other section. */ |
| default: |
| return TRUE; |
| } |
| } |
| |
| bfd_boolean |
| _bfd_elf_omit_section_dynsym_all |
| (bfd *output_bfd ATTRIBUTE_UNUSED, |
| struct bfd_link_info *info ATTRIBUTE_UNUSED, |
| asection *p ATTRIBUTE_UNUSED) |
| { |
| return TRUE; |
| } |
| |
| /* Assign dynsym indices. In a shared library we generate a section |
| symbol for each output section, which come first. Next come symbols |
| which have been forced to local binding. Then all of the back-end |
| allocated local dynamic syms, followed by the rest of the global |
| symbols. If SECTION_SYM_COUNT is NULL, section dynindx is not set. |
| (This prevents the early call before elf_backend_init_index_section |
| and strip_excluded_output_sections setting dynindx for sections |
| that are stripped.) */ |
| |
| static unsigned long |
| _bfd_elf_link_renumber_dynsyms (bfd *output_bfd, |
| struct bfd_link_info *info, |
| unsigned long *section_sym_count) |
| { |
| unsigned long dynsymcount = 0; |
| bfd_boolean do_sec = section_sym_count != NULL; |
| |
| if (bfd_link_pic (info) |
| || elf_hash_table (info)->is_relocatable_executable) |
| { |
| const struct elf_backend_data *bed = get_elf_backend_data (output_bfd); |
| asection *p; |
| for (p = output_bfd->sections; p ; p = p->next) |
| if ((p->flags & SEC_EXCLUDE) == 0 |
| && (p->flags & SEC_ALLOC) != 0 |
| && elf_hash_table (info)->dynamic_relocs |
| && !(*bed->elf_backend_omit_section_dynsym) (output_bfd, info, p)) |
| { |
| ++dynsymcount; |
| if (do_sec) |
| elf_section_data (p)->dynindx = dynsymcount; |
| } |
| else if (do_sec) |
| elf_section_data (p)->dynindx = 0; |
| } |
| if (do_sec) |
| *section_sym_count = dynsymcount; |
| |
| elf_link_hash_traverse (elf_hash_table (info), |
| elf_link_renumber_local_hash_table_dynsyms, |
| &dynsymcount); |
| |
| if (elf_hash_table (info)->dynlocal) |
| { |
| struct elf_link_local_dynamic_entry *p; |
| for (p = elf_hash_table (info)->dynlocal; p ; p = p->next) |
| p->dynindx = ++dynsymcount; |
| } |
| elf_hash_table (info)->local_dynsymcount = dynsymcount; |
| |
| elf_link_hash_traverse (elf_hash_table (info), |
| elf_link_renumber_hash_table_dynsyms, |
| &dynsymcount); |
| |
| /* There is an unused NULL entry at the head of the table which we |
| must account for in our count even if the table is empty since it |
| is intended for the mandatory DT_SYMTAB tag (.dynsym section) in |
| .dynamic section. */ |
| dynsymcount++; |
| |
| elf_hash_table (info)->dynsymcount = dynsymcount; |
| return dynsymcount; |
| } |
| |
| /* Merge st_other field. */ |
| |
| static void |
| elf_merge_st_other (bfd *abfd, struct elf_link_hash_entry *h, |
| const Elf_Internal_Sym *isym, asection *sec, |
| bfd_boolean definition, bfd_boolean dynamic) |
| { |
| const struct elf_backend_data *bed = get_elf_backend_data (abfd); |
| |
| /* If st_other has a processor-specific meaning, specific |
| code might be needed here. */ |
| if (bed->elf_backend_merge_symbol_attribute) |
| (*bed->elf_backend_merge_symbol_attribute) (h, isym, definition, |
| dynamic); |
| |
| if (!dynamic) |
| { |
| unsigned symvis = ELF_ST_VISIBILITY (isym->st_other); |
| unsigned hvis = ELF_ST_VISIBILITY (h->other); |
| |
| /* Keep the most constraining visibility. Leave the remainder |
| of the st_other field to elf_backend_merge_symbol_attribute. */ |
| if (symvis - 1 < hvis - 1) |
| h->other = symvis | (h->other & ~ELF_ST_VISIBILITY (-1)); |
| } |
| else if (definition |
| && ELF_ST_VISIBILITY (isym->st_other) != STV_DEFAULT |
| && (sec->flags & SEC_READONLY) == 0) |
| h->protected_def = 1; |
| } |
| |
| /* This function is called when we want to merge a new symbol with an |
| existing symbol. It handles the various cases which arise when we |
| find a definition in a dynamic object, or when there is already a |
| definition in a dynamic object. The new symbol is described by |
| NAME, SYM, PSEC, and PVALUE. We set SYM_HASH to the hash table |
| entry. We set POLDBFD to the old symbol's BFD. We set POLD_WEAK |
| if the old symbol was weak. We set POLD_ALIGNMENT to the alignment |
| of an old common symbol. We set OVERRIDE if the old symbol is |
| overriding a new definition. We set TYPE_CHANGE_OK if it is OK for |
| the type to change. We set SIZE_CHANGE_OK if it is OK for the size |
| to change. By OK to change, we mean that we shouldn't warn if the |
| type or size does change. */ |
| |
| static bfd_boolean |
| _bfd_elf_merge_symbol (bfd *abfd, |
| struct bfd_link_info *info, |
| const char *name, |
| Elf_Internal_Sym *sym, |
| asection **psec, |
| bfd_vma *pvalue, |
| struct elf_link_hash_entry **sym_hash, |
| bfd **poldbfd, |
| bfd_boolean *pold_weak, |
| unsigned int *pold_alignment, |
| bfd_boolean *skip, |
| bfd_boolean *override, |
| bfd_boolean *type_change_ok, |
| bfd_boolean *size_change_ok, |
| bfd_boolean *matched) |
| { |
| asection *sec, *oldsec; |
| struct elf_link_hash_entry *h; |
| struct elf_link_hash_entry *hi; |
| struct elf_link_hash_entry *flip; |
| int bind; |
| bfd *oldbfd; |
| bfd_boolean newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon; |
| bfd_boolean newweak, oldweak, newfunc, oldfunc; |
| const struct elf_backend_data *bed; |
| char *new_version; |
| bfd_boolean default_sym = *matched; |
| |
| *skip = FALSE; |
| *override = FALSE; |
| |
| sec = *psec; |
| bind = ELF_ST_BIND (sym->st_info); |
| |
| if (! bfd_is_und_section (sec)) |
| h = elf_link_hash_lookup (elf_hash_table (info), name, TRUE, FALSE, FALSE); |
| else |
| h = ((struct elf_link_hash_entry *) |
| bfd_wrapped_link_hash_lookup (abfd, info, name, TRUE, FALSE, FALSE)); |
| if (h == NULL) |
| return FALSE; |
| *sym_hash = h; |
| |
| bed = get_elf_backend_data (abfd); |
| |
| /* NEW_VERSION is the symbol version of the new symbol. */ |
| if (h->versioned != unversioned) |
| { |
| /* Symbol version is unknown or versioned. */ |
| new_version = strrchr (name, ELF_VER_CHR); |
| if (new_version) |
| { |
| if (h->versioned == unknown) |
| { |
| if (new_version > name && new_version[-1] != ELF_VER_CHR) |
| h->versioned = versioned_hidden; |
| else |
| h->versioned = versioned; |
| } |
| new_version += 1; |
| if (new_version[0] == '\0') |
| new_version = NULL; |
| } |
| else |
| h->versioned = unversioned; |
| } |
| else |
| new_version = NULL; |
| |
| /* For merging, we only care about real symbols. But we need to make |
| sure that indirect symbol dynamic flags are updated. */ |
| hi = h; |
| while (h->root.type == bfd_link_hash_indirect |
| || h->root.type == bfd_link_hash_warning) |
| h = (struct elf_link_hash_entry *) h->root.u.i.link; |
| |
| if (!*matched) |
| { |
| if (hi == h || h->root.type == bfd_link_hash_new) |
| *matched = TRUE; |
| else |
| { |
| /* OLD_HIDDEN is true if the existing symbol is only visible |
| to the symbol with the same symbol version. NEW_HIDDEN is |
| true if the new symbol is only visible to the symbol with |
| the same symbol version. */ |
| bfd_boolean old_hidden = h->versioned == versioned_hidden; |
| bfd_boolean new_hidden = hi->versioned == versioned_hidden; |
| if (!old_hidden && !new_hidden) |
| /* The new symbol matches the existing symbol if both |
| aren't hidden. */ |
| *matched = TRUE; |
| else |
| { |
| /* OLD_VERSION is the symbol version of the existing |
| symbol. */ |
| char *old_version; |
| |
| if (h->versioned >= versioned) |
| old_version = strrchr (h->root.root.string, |
| ELF_VER_CHR) + 1; |
| else |
| old_version = NULL; |
| |
| /* The new symbol matches the existing symbol if they |
| have the same symbol version. */ |
| *matched = (old_version == new_version |
| || (old_version != NULL |
| && new_version != NULL |
| && strcmp (old_version, new_version) == 0)); |
| } |
| } |
| } |
| |
| /* OLDBFD and OLDSEC are a BFD and an ASECTION associated with the |
| existing symbol. */ |
| |
| oldbfd = NULL; |
| oldsec = NULL; |
| switch (h->root.type) |
| { |
| default: |
| break; |
| |
| case bfd_link_hash_undefined: |
| case bfd_link_hash_undefweak: |
| oldbfd = h->root.u.undef.abfd; |
| break; |
| |
| case bfd_link_hash_defined: |
| case bfd_link_hash_defweak: |
| oldbfd = h->root.u.def.section->owner; |
| oldsec = h->root.u.def.section; |
| break; |
| |
| case bfd_link_hash_common: |
| oldbfd = h->root.u.c.p->section->owner; |
| oldsec = h->root.u.c.p->section; |
| if (pold_alignment) |
| *pold_alignment = h->root.u.c.p->alignment_power; |
| break; |
| } |
| if (poldbfd && *poldbfd == NULL) |
| *poldbfd = oldbfd; |
| |
| /* Differentiate strong and weak symbols. */ |
| newweak = bind == STB_WEAK; |
| oldweak = (h->root.type == bfd_link_hash_defweak |
| || h->root.type == bfd_link_hash_undefweak); |
| if (pold_weak) |
| *pold_weak = oldweak; |
| |
| /* We have to check it for every instance since the first few may be |
| references and not all compilers emit symbol type for undefined |
| symbols. */ |
| bfd_elf_link_mark_dynamic_symbol (info, h, sym); |
| |
| /* NEWDYN and OLDDYN indicate whether the new or old symbol, |
| respectively, is from a dynamic object. */ |
| |
| newdyn = (abfd->flags & DYNAMIC) != 0; |
| |
| /* ref_dynamic_nonweak and dynamic_def flags track actual undefined |
| syms and defined syms in dynamic libraries respectively. |
| ref_dynamic on the other hand can be set for a symbol defined in |
| a dynamic library, and def_dynamic may not be set; When the |
| definition in a dynamic lib is overridden by a definition in the |
| executable use of the symbol in the dynamic lib becomes a |
| reference to the executable symbol. */ |
| if (newdyn) |
| { |
| if (bfd_is_und_section (sec)) |
| { |
| if (bind != STB_WEAK) |
| { |
| h->ref_dynamic_nonweak = 1; |
| hi->ref_dynamic_nonweak = 1; |
| } |
| } |
| else |
| { |
| /* Update the existing symbol only if they match. */ |
| if (*matched) |
| h->dynamic_def = 1; |
| hi->dynamic_def = 1; |
| } |
| } |
| |
| /* If we just created the symbol, mark it as being an ELF symbol. |
| Other than that, there is nothing to do--there is no merge issue |
| with a newly defined symbol--so we just return. */ |
| |
| if (h->root.type == bfd_link_hash_new) |
| { |
| h->non_elf = 0; |
| return TRUE; |
| } |
| |
| /* In cases involving weak versioned symbols, we may wind up trying |
| to merge a symbol with itself. Catch that here, to avoid the |
| confusion that results if we try to override a symbol with |
| itself. The additional tests catch cases like |
| _GLOBAL_OFFSET_TABLE_, which are regular symbols defined in a |
| dynamic object, which we do want to handle here. */ |
| if (abfd == oldbfd |
| && (newweak || oldweak) |
| && ((abfd->flags & DYNAMIC) == 0 |
| || !h->def_regular)) |
| return TRUE; |
| |
| olddyn = FALSE; |
| if (oldbfd != NULL) |
| olddyn = (oldbfd->flags & DYNAMIC) != 0; |
| else if (oldsec != NULL) |
| { |
| /* This handles the special SHN_MIPS_{TEXT,DATA} section |
| indices used by MIPS ELF. */ |
| olddyn = (oldsec->symbol->flags & BSF_DYNAMIC) != 0; |
| } |
| |
| /* Handle a case where plugin_notice won't be called and thus won't |
| set the non_ir_ref flags on the first pass over symbols. */ |
| if (oldbfd != NULL |
| && (oldbfd->flags & BFD_PLUGIN) != (abfd->flags & BFD_PLUGIN) |
| && newdyn != olddyn) |
| { |
| h->root.non_ir_ref_dynamic = TRUE; |
| hi->root.non_ir_ref_dynamic = TRUE; |
| } |
| |
| /* NEWDEF and OLDDEF indicate whether the new or old symbol, |
| respectively, appear to be a definition rather than reference. */ |
| |
| newdef = !bfd_is_und_section (sec) && !bfd_is_com_section (sec); |
| |
| olddef = (h->root.type != bfd_link_hash_undefined |
| && h->root.type != bfd_link_hash_undefweak |
| && h->root.type != bfd_link_hash_common); |
| |
| /* NEWFUNC and OLDFUNC indicate whether the new or old symbol, |
| respectively, appear to be a function. */ |
| |
| newfunc = (ELF_ST_TYPE (sym->st_info) != STT_NOTYPE |
| && bed->is_function_type (ELF_ST_TYPE (sym->st_info))); |
| |
| oldfunc = (h->type != STT_NOTYPE |
| && bed->is_function_type (h->type)); |
| |
| if (!(newfunc && oldfunc) |
| && ELF_ST_TYPE (sym->st_info) != h->type |
| && ELF_ST_TYPE (sym->st_info) != STT_NOTYPE |
| && h->type != STT_NOTYPE |
| && (newdef || bfd_is_com_section (sec)) |
| && (olddef || h->root.type == bfd_link_hash_common)) |
| { |
| /* If creating a default indirect symbol ("foo" or "foo@") from |
| a dynamic versioned definition ("foo@@") skip doing so if |
| there is an existing regular definition with a different |
| type. We don't want, for example, a "time" variable in the |
| executable overriding a "time" function in a shared library. */ |
| if (newdyn |
| && !olddyn) |
| { |
| *skip = TRUE; |
| return TRUE; |
| } |
| |
| /* When adding a symbol from a regular object file after we have |
| created indirect symbols, undo the indirection and any |
| dynamic state. */ |
| if (hi != h |
| && !newdyn |
| && olddyn) |
| { |
| h = hi; |
| (*bed->elf_backend_hide_symbol) (info, h, TRUE); |
| h->forced_local = 0; |
| h->ref_dynamic = 0; |
| h->def_dynamic = 0; |
| h->dynamic_def = 0; |
| if (h->root.u.undef.next || info->hash->undefs_tail == &h->root) |
| { |
| h->root.type = bfd_link_hash_undefined; |
| h->root.u.undef.abfd = abfd; |
| } |
| else |
| { |
| h->root.type = bfd_link_hash_new; |
| h->root.u.undef.abfd = NULL; |
| } |
| return TRUE; |
| } |
| } |
| |
| /* Check TLS symbols. We don't check undefined symbols introduced |
| by "ld -u" which have no type (and oldbfd NULL), and we don't |
| check symbols from plugins because they also have no type. */ |
| if (oldbfd != NULL |
| && (oldbfd->flags & BFD_PLUGIN) == 0 |
| && (abfd->flags & BFD_PLUGIN) == 0 |
| && ELF_ST_TYPE (sym->st_info) != h->type |
| && (ELF_ST_TYPE (sym->st_info) == STT_TLS || h->type == STT_TLS)) |
| { |
| bfd *ntbfd, *tbfd; |
| bfd_boolean ntdef, tdef; |
| asection *ntsec, *tsec; |
| |
| if (h->type == STT_TLS) |
| { |
| ntbfd = abfd; |
| ntsec = sec; |
| ntdef = newdef; |
| tbfd = oldbfd; |
| tsec = oldsec; |
| tdef = olddef; |
| } |
| else |
| { |
| ntbfd = oldbfd; |
| ntsec = oldsec; |
| ntdef = olddef; |
| tbfd = abfd; |
| tsec = sec; |
| tdef = newdef; |
| } |
| |
| if (tdef && ntdef) |
| _bfd_error_handler |
| /* xgettext:c-format */ |
| (_("%s: TLS definition in %pB section %pA " |
| "mismatches non-TLS definition in %pB section %pA"), |
| h->root.root.string, tbfd, tsec, ntbfd, ntsec); |
| else if (!tdef && !ntdef) |
| _bfd_error_handler |
| /* xgettext:c-format */ |
| (_("%s: TLS reference in %pB " |
| "mismatches non-TLS reference in %pB"), |
| h->root.root.string, tbfd, ntbfd); |
| else if (tdef) |
| _bfd_error_handler |
| /* xgettext:c-format */ |
| (_("%s: TLS definition in %pB section %pA " |
| "mismatches non-TLS reference in %pB"), |
| h->root.root.string, tbfd, tsec, ntbfd); |
| else |
| _bfd_error_handler |
| /* xgettext:c-format */ |
| (_("%s: TLS reference in %pB " |
| "mismatches non-TLS definition in %pB section %pA"), |
| h->root.root.string, tbfd, ntbfd, ntsec); |
| |
| bfd_set_error (bfd_error_bad_value); |
| return FALSE; |
| } |
| |
| /* If the old symbol has non-default visibility, we ignore the new |
| definition from a dynamic object. */ |
| if (newdyn |
| && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT |
| && !bfd_is_und_section (sec)) |
| { |
| *skip = TRUE; |
| /* Make sure this symbol is dynamic. */ |
| h->ref_dynamic = 1; |
| hi->ref_dynamic = 1; |
| /* A protected symbol has external availability. Make sure it is |
| recorded as dynamic. |
| |
| FIXME: Should we check type and size for protected symbol? */ |
| if (ELF_ST_VISIBILITY (h->other) == STV_PROTECTED) |
| return bfd_elf_link_record_dynamic_symbol (info, h); |
| else |
| return TRUE; |
| } |
| else if (!newdyn |
| && ELF_ST_VISIBILITY (sym->st_other) != STV_DEFAULT |
| && h->def_dynamic) |
| { |
| /* If the new symbol with non-default visibility comes from a |
| relocatable file and the old definition comes from a dynamic |
| object, we remove the old definition. */ |
| if (hi->root.type == bfd_link_hash_indirect) |
| { |
| /* Handle the case where the old dynamic definition is |
| default versioned. We need to copy the symbol info from |
| the symbol with default version to the normal one if it |
| was referenced before. */ |
| if (h->ref_regular) |
| { |
| hi->root.type = h->root.type; |
| h->root.type = bfd_link_hash_indirect; |
| (*bed->elf_backend_copy_indirect_symbol) (info, hi, h); |
| |
| h->root.u.i.link = (struct bfd_link_hash_entry *) hi; |
| if (ELF_ST_VISIBILITY (sym->st_other) != STV_PROTECTED) |
| { |
| /* If the new symbol is hidden or internal, completely undo |
| any dynamic link state. */ |
| (*bed->elf_backend_hide_symbol) (info, h, TRUE); |
| h->forced_local = 0; |
| h->ref_dynamic = 0; |
| } |
| else |
| h->ref_dynamic = 1; |
| |
| h->def_dynamic = 0; |
| /* FIXME: Should we check type and size for protected symbol? */ |
| h->size = 0; |
| h->type = 0; |
| |
| h = hi; |
| } |
| else |
| h = hi; |
| } |
| |
| /* If the old symbol was undefined before, then it will still be |
| on the undefs list. If the new symbol is undefined or |
| common, we can't make it bfd_link_hash_new here, because new |
| undefined or common symbols will be added to the undefs list |
| by _bfd_generic_link_add_one_symbol. Symbols may not be |
| added twice to the undefs list. Also, if the new symbol is |
| undefweak then we don't want to lose the strong undef. */ |
| if (h->root.u.undef.next || info->hash->undefs_tail == &h->root) |
| { |
| h->root.type = bfd_link_hash_undefined; |
| h->root.u.undef.abfd = abfd; |
| } |
| else |
| { |
| h->root.type = bfd_link_hash_new; |
| h->root.u.undef.abfd = NULL; |
| } |
| |
| if (ELF_ST_VISIBILITY (sym->st_other) != STV_PROTECTED) |
| { |
| /* If the new symbol is hidden or internal, completely undo |
| any dynamic link state. */ |
| (*bed->elf_backend_hide_symbol) (info, h, TRUE); |
| h->forced_local = 0; |
| h->ref_dynamic = 0; |
| } |
| else |
| h->ref_dynamic = 1; |
| h->def_dynamic = 0; |
| /* FIXME: Should we check type and size for protected symbol? */ |
| h->size = 0; |
| h->type = 0; |
| return TRUE; |
| } |
| |
| /* If a new weak symbol definition comes from a regular file and the |
| old symbol comes from a dynamic library, we treat the new one as |
| strong. Similarly, an old weak symbol definition from a regular |
| file is treated as strong when the new symbol comes from a dynamic |
| library. Further, an old weak symbol from a dynamic library is |
| treated as strong if the new symbol is from a dynamic library. |
| This reflects the way glibc's ld.so works. |
| |
| Also allow a weak symbol to override a linker script symbol |
| defined by an early pass over the script. This is done so the |
| linker knows the symbol is defined in an object file, for the |
| DEFINED script function. |
| |
| Do this before setting *type_change_ok or *size_change_ok so that |
| we warn properly when dynamic library symbols are overridden. */ |
| |
| if (newdef && !newdyn && (olddyn || h->root.ldscript_def)) |
| newweak = FALSE; |
| if (olddef && newdyn) |
| oldweak = FALSE; |
| |
| /* Allow changes between different types of function symbol. */ |
| if (newfunc && oldfunc) |
| *type_change_ok = TRUE; |
| |
| /* It's OK to change the type if either the existing symbol or the |
| new symbol is weak. A type change is also OK if the old symbol |
| is undefined and the new symbol is defined. */ |
| |
| if (oldweak |
| || newweak |
| || (newdef |
| && h->root.type == bfd_link_hash_undefined)) |
| *type_change_ok = TRUE; |
| |
| /* It's OK to change the size if either the existing symbol or the |
| new symbol is weak, or if the old symbol is undefined. */ |
| |
| if (*type_change_ok |
| || h->root.type == bfd_link_hash_undefined) |
| *size_change_ok = TRUE; |
| |
| /* NEWDYNCOMMON and OLDDYNCOMMON indicate whether the new or old |
| symbol, respectively, appears to be a common symbol in a dynamic |
| object. If a symbol appears in an uninitialized section, and is |
| not weak, and is not a function, then it may be a common symbol |
| which was resolved when the dynamic object was created. We want |
| to treat such symbols specially, because they raise special |
| considerations when setting the symbol size: if the symbol |
| appears as a common symbol in a regular object, and the size in |
| the regular object is larger, we must make sure that we use the |
| larger size. This problematic case can always be avoided in C, |
| but it must be handled correctly when using Fortran shared |
| libraries. |
| |
| Note that if NEWDYNCOMMON is set, NEWDEF will be set, and |
| likewise for OLDDYNCOMMON and OLDDEF. |
| |
| Note that this test is just a heuristic, and that it is quite |
| possible to have an uninitialized symbol in a shared object which |
| is really a definition, rather than a common symbol. This could |
| lead to some minor confusion when the symbol really is a common |
| symbol in some regular object. However, I think it will be |
| harmless. */ |
| |
| if (newdyn |
| && newdef |
| && !newweak |
| && (sec->flags & SEC_ALLOC) != 0 |
| && (sec->flags & SEC_LOAD) == 0 |
| && sym->st_size > 0 |
| && !newfunc) |
| newdyncommon = TRUE; |
| else |
| newdyncommon = FALSE; |
| |
| if (olddyn |
| && olddef |
| && h->root.type == bfd_link_hash_defined |
| && h->def_dynamic |
| && (h->root.u.def.section->flags & SEC_ALLOC) != 0 |
| && (h->root.u.def.section->flags & SEC_LOAD) == 0 |
| && h->size > 0 |
| && !oldfunc) |
| olddyncommon = TRUE; |
| else |
| olddyncommon = FALSE; |
| |
| /* We now know everything about the old and new symbols. We ask the |
| backend to check if we can merge them. */ |
| if (bed->merge_symbol != NULL) |
| { |
| if (!bed->merge_symbol (h, sym, psec, newdef, olddef, oldbfd, oldsec)) |
| return FALSE; |
| sec = *psec; |
| } |
| |
| /* There are multiple definitions of a normal symbol. Skip the |
| default symbol as well as definition from an IR object. */ |
| if (olddef && !olddyn && !oldweak && newdef && !newdyn && !newweak |
| && !default_sym && h->def_regular |
| && !(oldbfd != NULL |
| && (oldbfd->flags & BFD_PLUGIN) != 0 |
| && (abfd->flags & BFD_PLUGIN) == 0)) |
| { |
| /* Handle a multiple definition. */ |
| (*info->callbacks->multiple_definition) (info, &h->root, |
| abfd, sec, *pvalue); |
| *skip = TRUE; |
| return TRUE; |
| } |
| |
| /* If both the old and the new symbols look like common symbols in a |
| dynamic object, set the size of the symbol to the larger of the |
| two. */ |
| |
| if (olddyncommon |
| && newdyncommon |
| && sym->st_size != h->size) |
| { |
| /* Since we think we have two common symbols, issue a multiple |
| common warning if desired. Note that we only warn if the |
| size is different. If the size is the same, we simply let |
| the old symbol override the new one as normally happens with |
| symbols defined in dynamic objects. */ |
| |
| (*info->callbacks->multiple_common) (info, &h->root, abfd, |
| bfd_link_hash_common, sym->st_size); |
| if (sym->st_size > h->size) |
| h->size = sym->st_size; |
| |
| *size_change_ok = TRUE; |
| } |
| |
| /* If we are looking at a dynamic object, and we have found a |
| definition, we need to see if the symbol was already defined by |
| some other object. If so, we want to use the existing |
| definition, and we do not want to report a multiple symbol |
| definition error; we do this by clobbering *PSEC to be |
| bfd_und_section_ptr. |
| |
| We treat a common symbol as a definition if the symbol in the |
| shared library is a function, since common symbols always |
| represent variables; this can cause confusion in principle, but |
| any such confusion would seem to indicate an erroneous program or |
| shared library. We also permit a common symbol in a regular |
| object to override a weak symbol in a shared object. */ |
| |
| if (newdyn |
| && newdef |
| && (olddef |
| || (h->root.type == bfd_link_hash_common |
| && (newweak || newfunc)))) |
| { |
| *override = TRUE; |
| newdef = FALSE; |
| newdyncommon = FALSE; |
| |
| *psec = sec = bfd_und_section_ptr; |
| *size_change_ok = TRUE; |
| |
| /* If we get here when the old symbol is a common symbol, then |
| we are explicitly letting it override a weak symbol or |
| function in a dynamic object, and we don't want to warn about |
| a type change. If the old symbol is a defined symbol, a type |
| change warning may still be appropriate. */ |
| |
| if (h->root.type == bfd_link_hash_common) |
| *type_change_ok = TRUE; |
| } |
| |
| /* Handle the special case of an old common symbol merging with a |
| new symbol which looks like a common symbol in a shared object. |
| We change *PSEC and *PVALUE to make the new symbol look like a |
| common symbol, and let _bfd_generic_link_add_one_symbol do the |
| right thing. */ |
| |
| if (newdyncommon |
| && h->root.type == bfd_link_hash_common) |
| { |
| *override = TRUE; |
| newdef = FALSE; |
| newdyncommon = FALSE; |
| *pvalue = sym->st_size; |
| *psec = sec = bed->common_section (oldsec); |
| *size_change_ok = TRUE; |
| } |
| |
| /* Skip weak definitions of symbols that are already defined. */ |
| if (newdef && olddef && newweak) |
| { |
| /* Don't skip new non-IR weak syms. */ |
| if (!(oldbfd != NULL |
| && (oldbfd->flags & BFD_PLUGIN) != 0 |
| && (abfd->flags & BFD_PLUGIN) == 0)) |
| { |
| newdef = FALSE; |
| *skip = TRUE; |
| } |
| |
| /* Merge st_other. If the symbol already has a dynamic index, |
| but visibility says it should not be visible, turn it into a |
| local symbol. */ |
| elf_merge_st_other (abfd, h, sym, sec, newdef, newdyn); |
| if (h->dynindx != -1) |
| switch (ELF_ST_VISIBILITY (h->other)) |
| { |
| case STV_INTERNAL: |
| case STV_HIDDEN: |
| (*bed->elf_backend_hide_symbol) (info, h, TRUE); |
| break; |
| } |
| } |
| |
| /* If the old symbol is from a dynamic object, and the new symbol is |
| a definition which is not from a dynamic object, then the new |
| symbol overrides the old symbol. Symbols from regular files |
| always take precedence over symbols from dynamic objects, even if |
| they are defined after the dynamic object in the link. |
| |
| As above, we again permit a common symbol in a regular object to |
| override a definition in a shared object if the shared object |
| symbol is a function or is weak. */ |
| |
| flip = NULL; |
| if (!newdyn |
| && (newdef |
| || (bfd_is_com_section (sec) |
| && (oldweak || oldfunc))) |
| && olddyn |
| && olddef |
| && h->def_dynamic) |
| { |
| /* Change the hash table entry to undefined, and let |
| _bfd_generic_link_add_one_symbol do the right thing with the |
| new definition. */ |
| |
| h->root.type = bfd_link_hash_undefined; |
| h->root.u.undef.abfd = h->root.u.def.section->owner; |
| *size_change_ok = TRUE; |
| |
| olddef = FALSE; |
| olddyncommon = FALSE; |
| |
| /* We again permit a type change when a common symbol may be |
| overriding a function. */ |
| |
| if (bfd_is_com_section (sec)) |
| { |
| if (oldfunc) |
| { |
| /* If a common symbol overrides a function, make sure |
| that it isn't defined dynamically nor has type |
| function. */ |
| h->def_dynamic = 0; |
| h->type = STT_NOTYPE; |
| } |
| *type_change_ok = TRUE; |
| } |
| |
| if (hi->root.type == bfd_link_hash_indirect) |
| flip = hi; |
| else |
| /* This union may have been set to be non-NULL when this symbol |
| was seen in a dynamic object. We must force the union to be |
| NULL, so that it is correct for a regular symbol. */ |
| h->verinfo.vertree = NULL; |
| } |
| |
| /* Handle the special case of a new common symbol merging with an |
| old symbol that looks like it might be a common symbol defined in |
| a shared object. Note that we have already handled the case in |
| which a new common symbol should simply override the definition |
| in the shared library. */ |
| |
| if (! newdyn |
| && bfd_is_com_section (sec) |
| && olddyncommon) |
| { |
| /* It would be best if we could set the hash table entry to a |
| common symbol, but we don't know what to use for the section |
| or the alignment. */ |
| (*info->callbacks->multiple_common) (info, &h->root, abfd, |
| bfd_link_hash_common, sym->st_size); |
| |
| /* If the presumed common symbol in the dynamic object is |
| larger, pretend that the new symbol has its size. */ |
| |
| if (h->size > *pvalue) |
| *pvalue = h->size; |
| |
| /* We need to remember the alignment required by the symbol |
| in the dynamic object. */ |
| BFD_ASSERT (pold_alignment); |
| *pold_alignment = h->root.u.def.section->alignment_power; |
| |
| olddef = FALSE; |
| olddyncommon = FALSE; |
| |
| h->root.type = bfd_link_hash_undefined; |
| h->root.u.undef.abfd = h->root.u.def.section->owner; |
| |
| *size_change_ok = TRUE; |
| *type_change_ok = TRUE; |
| |
| if (hi->root.type == bfd_link_hash_indirect) |
| flip = hi; |
| else |
| h->verinfo.vertree = NULL; |
| } |
| |
| if (flip != NULL) |
| { |
| /* Handle the case where we had a versioned symbol in a dynamic |
| library and now find a definition in a normal object. In this |
| case, we make the versioned symbol point to the normal one. */ |
| flip->root.type = h->root.type; |
| flip->root.u.undef.abfd = h->root.u.undef.abfd; |
| h->root.type = bfd_link_hash_indirect; |
| h->root.u.i.link = (struct bfd_link_hash_entry *) flip; |
| (*bed->elf_backend_copy_indirect_symbol) (info, flip, h); |
| if (h->def_dynamic) |
| { |
| h->def_dynamic = 0; |
| flip->ref_dynamic = 1; |
| } |
| } |
| |
| return TRUE; |
| } |
| |
| /* This function is called to create an indirect symbol from the |
| default for the symbol with the default version if needed. The |
| symbol is described by H, NAME, SYM, SEC, and VALUE. We |
| set DYNSYM if the new indirect symbol is dynamic. */ |
| |
| static bfd_boolean |
| _bfd_elf_add_default_symbol (bfd *abfd, |
| struct bfd_link_info *info, |
| struct elf_link_hash_entry *h, |
| const char *name, |
| Elf_Internal_Sym *sym, |
| asection *sec, |
| bfd_vma value, |
| bfd **poldbfd, |
| bfd_boolean *dynsym) |
| { |
| bfd_boolean type_change_ok; |
| bfd_boolean size_change_ok; |
| bfd_boolean skip; |
| char *shortname; |
| struct elf_link_hash_entry *hi; |
| struct bfd_link_hash_entry *bh; |
| const struct elf_backend_data *bed; |
| bfd_boolean collect; |
| bfd_boolean dynamic; |
| bfd_boolean override; |
| char *p; |
| size_t len, shortlen; |
| asection *tmp_sec; |
| bfd_boolean matched; |
| |
| if (h->versioned == unversioned || h->versioned == versioned_hidden) |
| return TRUE; |
| |
| /* If this symbol has a version, and it is the default version, we |
| create an indirect symbol from the default name to the fully |
| decorated name. This will cause external references which do not |
| specify a version to be bound to this version of the symbol. */ |
| p = strchr (name, ELF_VER_CHR); |
| if (h->versioned == unknown) |
| { |
| if (p == NULL) |
| { |
| h->versioned = unversioned; |
| return TRUE; |
| } |
| else |
| { |
| if (p[1] != ELF_VER_CHR) |
| { |
| h->versioned = versioned_hidden; |
| return TRUE; |
| } |
| else |
| h->versioned = versioned; |
| } |
| } |
| else |
| { |
| /* PR ld/19073: We may see an unversioned definition after the |
| default version. */ |
| if (p == NULL) |
| return TRUE; |
| } |
| |
| bed = get_elf_backend_data (abfd); |
| collect = bed->collect; |
| dynamic = (abfd->flags & DYNAMIC) != 0; |
| |
| shortlen = p - name; |
| shortname = (char *) bfd_hash_allocate (&info->hash->table, shortlen + 1); |
| if (shortname == NULL) |
| return FALSE; |
| memcpy (shortname, name, shortlen); |
| shortname[shortlen] = '\0'; |
| |
| /* We are going to create a new symbol. Merge it with any existing |
| symbol with this name. For the purposes of the merge, act as |
| though we were defining the symbol we just defined, although we |
| actually going to define an indirect symbol. */ |
| type_change_ok = FALSE; |
| size_change_ok = FALSE; |
| matched = TRUE; |
| tmp_sec = sec; |
| if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &tmp_sec, &value, |
| &hi, poldbfd, NULL, NULL, &skip, &override, |
| &type_change_ok, &size_change_ok, &matched)) |
| return FALSE; |
| |
| if (skip) |
| goto nondefault; |
| |
| if (hi->def_regular || ELF_COMMON_DEF_P (hi)) |
| { |
| /* If the undecorated symbol will have a version added by a |
| script different to H, then don't indirect to/from the |
| undecorated symbol. This isn't ideal because we may not yet |
| have seen symbol versions, if given by a script on the |
| command line rather than via --version-script. */ |
| if (hi->verinfo.vertree == NULL && info->version_info != NULL) |
| { |
| bfd_boolean hide; |
| |
| hi->verinfo.vertree |
| = bfd_find_version_for_sym (info->version_info, |
| hi->root.root.string, &hide); |
| if (hi->verinfo.vertree != NULL && hide) |
| { |
| (*bed->elf_backend_hide_symbol) (info, hi, TRUE); |
| goto nondefault; |
| } |
| } |
| if (hi->verinfo.vertree != NULL |
| && strcmp (p + 1 + (p[1] == '@'), hi->verinfo.vertree->name) != 0) |
| goto nondefault; |
| } |
| |
| if (! override) |
| { |
| /* Add the default symbol if not performing a relocatable link. */ |
| if (! bfd_link_relocatable (info)) |
| { |
| bh = &hi->root; |
| if (bh->type == bfd_link_hash_defined |
| && bh->u.def.section->owner != NULL |
| && (bh->u.def.section->owner->flags & BFD_PLUGIN) != 0) |
| { |
| /* Mark the previous definition from IR object as |
| undefined so that the generic linker will override |
| it. */ |
| bh->type = bfd_link_hash_undefined; |
| bh->u.undef.abfd = bh->u.def.section->owner; |
| } |
| if (! (_bfd_generic_link_add_one_symbol |
| (info, abfd, shortname, BSF_INDIRECT, |
| bfd_ind_section_ptr, |
| 0, name, FALSE, collect, &bh))) |
| return FALSE; |
| hi = (struct elf_link_hash_entry *) bh; |
| } |
| } |
| else |
| { |
| /* In this case the symbol named SHORTNAME is overriding the |
| indirect symbol we want to add. We were planning on making |
| SHORTNAME an indirect symbol referring to NAME. SHORTNAME |
| is the name without a version. NAME is the fully versioned |
| name, and it is the default version. |
| |
| Overriding means that we already saw a definition for the |
| symbol SHORTNAME in a regular object, and it is overriding |
| the symbol defined in the dynamic object. |
| |
| When this happens, we actually want to change NAME, the |
| symbol we just added, to refer to SHORTNAME. This will cause |
| references to NAME in the shared object to become references |
| to SHORTNAME in the regular object. This is what we expect |
| when we override a function in a shared object: that the |
| references in the shared object will be mapped to the |
| definition in the regular object. */ |
| |
| while (hi->root.type == bfd_link_hash_indirect |
| || hi->root.type == bfd_link_hash_warning) |
| hi = (struct elf_link_hash_entry *) hi->root.u.i.link; |
| |
| h->root.type = bfd_link_hash_indirect; |
| h->root.u.i.link = (struct bfd_link_hash_entry *) hi; |
| if (h->def_dynamic) |
| { |
| h->def_dynamic = 0; |
| hi->ref_dynamic = 1; |
| if (hi->ref_regular |
| || hi->def_regular) |
| { |
| if (! bfd_elf_link_record_dynamic_symbol (info, hi)) |
| return FALSE; |
| } |
| } |
| |
| /* Now set HI to H, so that the following code will set the |
| other fields correctly. */ |
| hi = h; |
| } |
| |
| /* Check if HI is a warning symbol. */ |
| if (hi->root.type == bfd_link_hash_warning) |
| hi = (struct elf_link_hash_entry *) hi->root.u.i.link; |
| |
| /* If there is a duplicate definition somewhere, then HI may not |
| point to an indirect symbol. We will have reported an error to |
| the user in that case. */ |
| |
| if (hi->root.type == bfd_link_hash_indirect) |
| { |
| struct elf_link_hash_entry *ht; |
| |
| ht = (struct elf_link_hash_entry *) hi->root.u.i.link; |
| (*bed->elf_backend_copy_indirect_symbol) (info, ht, hi); |
| |
| /* A reference to the SHORTNAME symbol from a dynamic library |
| will be satisfied by the versioned symbol at runtime. In |
| effect, we have a reference to the versioned symbol. */ |
| ht->ref_dynamic_nonweak |= hi->ref_dynamic_nonweak; |
| hi->dynamic_def |= ht->dynamic_def; |
| |
| /* See if the new flags lead us to realize that the symbol must |
| be dynamic. */ |
| if (! *dynsym) |
| { |
| if (! dynamic) |
| { |
| if (! bfd_link_executable (info) |
| || hi->def_dynamic |
| || hi->ref_dynamic) |
| *dynsym = TRUE; |
| } |
| else |
| { |
| if (hi->ref_regular) |
| *dynsym = TRUE; |
| } |
| } |
| } |
| |
| /* We also need to define an indirection from the nondefault version |
| of the symbol. */ |
| |
| nondefault: |
| len = strlen (name); |
| shortname = (char *) bfd_hash_allocate (&info->hash->table, len); |
| if (shortname == NULL) |
| return FALSE; |
| memcpy (shortname, name, shortlen); |
| memcpy (shortname + shortlen, p + 1, len - shortlen); |
| |
| /* Once again, merge with any existing symbol. */ |
| type_change_ok = FALSE; |
| size_change_ok = FALSE; |
| tmp_sec = sec; |
| if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &tmp_sec, &value, |
| &hi, poldbfd, NULL, NULL, &skip, &override, |
| &type_change_ok, &size_change_ok, &matched)) |
| return FALSE; |
| |
| if (skip) |
| return TRUE; |
| |
| if (override) |
| { |
| /* Here SHORTNAME is a versioned name, so we don't expect to see |
| the type of override we do in the case above unless it is |
| overridden by a versioned definition. */ |
| if (hi->root.type != bfd_link_hash_defined |
| && hi->root.type != bfd_link_hash_defweak) |
| _bfd_error_handler |
| /* xgettext:c-format */ |
| (_("%pB: unexpected redefinition of indirect versioned symbol `%s'"), |
| abfd, shortname); |
| } |
| else |
| { |
| bh = &hi->root; |
| if (! (_bfd_generic_link_add_one_symbol |
| (info, abfd, shortname, BSF_INDIRECT, |
| bfd_ind_section_ptr, 0, name, FALSE, collect, &bh))) |
| return FALSE; |
| hi = (struct elf_link_hash_entry *) bh; |
| |
| /* If there is a duplicate definition somewhere, then HI may not |
| point to an indirect symbol. We will have reported an error |
| to the user in that case. */ |
| |
| if (hi->root.type == bfd_link_hash_indirect) |
| { |
| (*bed->elf_backend_copy_indirect_symbol) (info, h, hi); |
| h->ref_dynamic_nonweak |= hi->ref_dynamic_nonweak; |
| hi->dynamic_def |= h->dynamic_def; |
| |
| /* See if the new flags lead us to realize that the symbol |
| must be dynamic. */ |
| if (! *dynsym) |
| { |
| if (! dynamic) |
| { |
| if (! bfd_link_executable (info) |
| || hi->ref_dynamic) |
| *dynsym = TRUE; |
| } |
| else |
| { |
| if (hi->ref_regular) |
| *dynsym = TRUE; |
| } |
| } |
| } |
| } |
| |
| return TRUE; |
| } |
| |
| /* This routine is used to export all defined symbols into the dynamic |
| symbol table. It is called via elf_link_hash_traverse. */ |
| |
| static bfd_boolean |
| _bfd_elf_export_symbol (struct elf_link_hash_entry *h, void *data) |
| { |
| struct elf_info_failed *eif = (struct elf_info_failed *) data; |
| |
| /* Ignore indirect symbols. These are added by the versioning code. */ |
| if (h->root.type == bfd_link_hash_indirect) |
| return TRUE; |
| |
| /* Ignore this if we won't export it. */ |
| if (!eif->info->export_dynamic && !h->dynamic) |
| return TRUE; |
| |
| if (h->dynindx == -1 |
| && (h->def_regular || h->ref_regular) |
| && ! bfd_hide_sym_by_version (eif->info->version_info, |
| h->root.root.string)) |
| { |
| if (! bfd_elf_link_record_dynamic_symbol (eif->info, h)) |
| { |
| eif->failed = TRUE; |
| return FALSE; |
| } |
| } |
| |
| return TRUE; |
| } |
| |
| /* Look through the symbols which are defined in other shared |
| libraries and referenced here. Update the list of version |
| dependencies. This will be put into the .gnu.version_r section. |
| This function is called via elf_link_hash_traverse. */ |
| |
| static bfd_boolean |
| _bfd_elf_link_find_version_dependencies (struct elf_link_hash_entry *h, |
| void *data) |
| { |
| struct elf_find_verdep_info *rinfo = (struct elf_find_verdep_info *) data; |
| Elf_Internal_Verneed *t; |
| Elf_Internal_Vernaux *a; |
| bfd_size_type amt; |
| |
| /* We only care about symbols defined in shared objects with version |
| information. */ |
| if (!h->def_dynamic |
| || h->def_regular |
| || h->dynindx == -1 |
| || h->verinfo.verdef == NULL |
| || (elf_dyn_lib_class (h->verinfo.verdef->vd_bfd) |
| & (DYN_AS_NEEDED | DYN_DT_NEEDED | DYN_NO_NEEDED))) |
| return TRUE; |
| |
| /* See if we already know about this version. */ |
| for (t = elf_tdata (rinfo->info->output_bfd)->verref; |
| t != NULL; |
| t = t->vn_nextref) |
| { |
| if (t->vn_bfd != h->verinfo.verdef->vd_bfd) |
| continue; |
| |
| for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) |
| if (a->vna_nodename == h->verinfo.verdef->vd_nodename) |
| return TRUE; |
| |
| break; |
| } |
| |
| /* This is a new version. Add it to tree we are building. */ |
| |
| if (t == NULL) |
| { |
| amt = sizeof *t; |
| t = (Elf_Internal_Verneed *) bfd_zalloc (rinfo->info->output_bfd, amt); |
| if (t == NULL) |
| { |
| rinfo->failed = TRUE; |
| return FALSE; |
| } |
| |
| t->vn_bfd = h->verinfo.verdef->vd_bfd; |
| t->vn_nextref = elf_tdata (rinfo->info->output_bfd)->verref; |
| elf_tdata (rinfo->info->output_bfd)->verref = t; |
| } |
| |
| amt = sizeof *a; |
| a = (Elf_Internal_Vernaux *) bfd_zalloc (rinfo->info->output_bfd, amt); |
| if (a == NULL) |
| { |
| rinfo->failed = TRUE; |
| return FALSE; |
| } |
| |
| /* Note that we are copying a string pointer here, and testing it |
| above. If bfd_elf_string_from_elf_section is ever changed to |
| discard the string data when low in memory, this will have to be |
| fixed. */ |
| a->vna_nodename = h->verinfo.verdef->vd_nodename; |
| |
| a->vna_flags = h->verinfo.verdef->vd_flags; |
| a->vna_nextptr = t->vn_auxptr; |
| |
| h->verinfo.verdef->vd_exp_refno = rinfo->vers; |
| ++rinfo->vers; |
| |
| a->vna_other = h->verinfo.verdef->vd_exp_refno + 1; |
| |
| t->vn_auxptr = a; |
| |
| return TRUE; |
| } |
| |
| /* Return TRUE and set *HIDE to TRUE if the versioned symbol is |
| hidden. Set *T_P to NULL if there is no match. */ |
| |
| static bfd_boolean |
| _bfd_elf_link_hide_versioned_symbol (struct bfd_link_info *info, |
| struct elf_link_hash_entry *h, |
| const char *version_p, |
| struct bfd_elf_version_tree **t_p, |
| bfd_boolean *hide) |
| { |
| struct bfd_elf_version_tree *t; |
| |
| /* Look for the version. If we find it, it is no longer weak. */ |
| for (t = info->version_info; t != NULL; t = t->next) |
| { |
| if (strcmp (t->name, version_p) == 0) |
| { |
| size_t len; |
| char *alc; |
| struct bfd_elf_version_expr *d; |
| |
| len = version_p - h->root.root.string; |
| alc = (char *) bfd_malloc (len); |
| if (alc == NULL) |
| return FALSE; |
| memcpy (alc, h->root.root.string, len - 1); |
| alc[len - 1] = '\0'; |
| if (alc[len - 2] == ELF_VER_CHR) |
| alc[len - 2] = '\0'; |
| |
| h->verinfo.vertree = t; |
| t->used = TRUE; |
| d = NULL; |
| |
| if (t->globals.list != NULL) |
| d = (*t->match) (&t->globals, NULL, alc); |
| |
| /* See if there is anything to force this symbol to |
| local scope. */ |
| if (d == NULL && t->locals.list != NULL) |
| { |
| d = (*t->match) (&t->locals, NULL, alc); |
| if (d != NULL |
| && h->dynindx != -1 |
| && ! info->export_dynamic) |
| *hide = TRUE; |
| } |
| |
| free (alc); |
| break; |
| } |
| } |
| |
| *t_p = t; |
| |
| return TRUE; |
| } |
| |
| /* Return TRUE if the symbol H is hidden by version script. */ |
| |
| bfd_boolean |
| _bfd_elf_link_hide_sym_by_version (struct bfd_link_info *info, |
| struct elf_link_hash_entry *h) |
| { |
| const char *p; |
| bfd_boolean hide = FALSE; |
| const struct elf_backend_data *bed |
| = get_elf_backend_data (info->output_bfd); |
| |
| /* Version script only hides symbols defined in regular objects. */ |
| if (!h->def_regular && !ELF_COMMON_DEF_P (h)) |
| return TRUE; |
| |
| p = strchr (h->root.root.string, ELF_VER_CHR); |
| if (p != NULL && h->verinfo.vertree == NULL) |
| { |
| struct bfd_elf_version_tree *t; |
| |
| ++p; |
| if (*p == ELF_VER_CHR) |
| ++p; |
| |
| if (*p != '\0' |
| && _bfd_elf_link_hide_versioned_symbol (info, h, p, &t, &hide) |
| && hide) |
| { |
| if (hide) |
| (*bed->elf_backend_hide_symbol) (info, h, TRUE); |
| return TRUE; |
| } |
| } |
| |
| /* If we don't have a version for this symbol, see if we can find |
| something. */ |
| if (h->verinfo.vertree == NULL && info->version_info != NULL) |
| { |
| h->verinfo.vertree |
| = bfd_find_version_for_sym (info->version_info, |
| h->root.root.string, &hide); |
| if (h->verinfo.vertree != NULL && hide) |
| { |
| (*bed->elf_backend_hide_symbol) (info, h, TRUE); |
| return TRUE; |
| } |
| } |
| |
| return FALSE; |
| } |
| |
| /* Figure out appropriate versions for all the symbols. We may not |
| have the version number script until we have read all of the input |
| files, so until that point we don't know which symbols should be |
| local. This function is called via elf_link_hash_traverse. */ |
| |
| static bfd_boolean |
| _bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data) |
| { |
| struct elf_info_failed *sinfo; |
| struct bfd_link_info *info; |
| const struct elf_backend_data *bed; |
| struct elf_info_failed eif; |
| char *p; |
| bfd_boolean hide; |
| |
| sinfo = (struct elf_info_failed *) data; |
| info = sinfo->info; |
| |
| /* Fix the symbol flags. */ |
| eif.failed = FALSE; |
| eif.info = info; |
| if (! _bfd_elf_fix_symbol_flags (h, &eif)) |
| { |
| if (eif.failed) |
| sinfo->failed = TRUE; |
| return FALSE; |
| } |
| |
| bed = get_elf_backend_data (info->output_bfd); |
| |
| /* We only need version numbers for symbols defined in regular |
| objects. */ |
| if (!h->def_regular && !ELF_COMMON_DEF_P (h)) |
| { |
| /* Hide symbols defined in discarded input sections. */ |
| if ((h->root.type == bfd_link_hash_defined |
| || h->root.type == bfd_link_hash_defweak) |
| && discarded_section (h->root.u.def.section)) |
| (*bed->elf_backend_hide_symbol) (info, h, TRUE); |
| return TRUE; |
| } |
| |
| hide = FALSE; |
| p = strchr (h->root.root.string, ELF_VER_CHR); |
| if (p != NULL && h->verinfo.vertree == NULL) |
| { |
| struct bfd_elf_version_tree *t; |
| |
| ++p; |
| if (*p == ELF_VER_CHR) |
| ++p; |
| |
| /* If there is no version string, we can just return out. */ |
| if (*p == '\0') |
| return TRUE; |
| |
| if (!_bfd_elf_link_hide_versioned_symbol (info, h, p, &t, &hide)) |
| { |
| sinfo->failed = TRUE; |
| return FALSE; |
| } |
| |
| if (hide) |
| (*bed->elf_backend_hide_symbol) (info, h, TRUE); |
| |
| /* If we are building an application, we need to create a |
| version node for this version. */ |
| if (t == NULL && bfd_link_executable (info)) |
| { |
| struct bfd_elf_version_tree **pp; |
| int version_index; |
| |
| /* If we aren't going to export this symbol, we don't need |
| to worry about it. */ |
| if (h->dynindx == -1) |
| return TRUE; |
| |
| t = (struct bfd_elf_version_tree *) bfd_zalloc (info->output_bfd, |
| sizeof *t); |
| if (t == NULL) |
| { |
| sinfo->failed = TRUE; |
| return FALSE; |
| } |
| |
| t->name = p; |
| t->name_indx = (unsigned int) -1; |
| t->used = TRUE; |
| |
| version_index = 1; |
| /* Don't count anonymous version tag. */ |
| if (sinfo->info->version_info != NULL |
| && sinfo->info->version_info->vernum == 0) |
| version_index = 0; |
| for (pp = &sinfo->info->version_info; |
| *pp != NULL; |
| pp = &(*pp)->next) |
| ++version_index; |
| t->vernum = version_index; |
| |
| *pp = t; |
| |
| h->verinfo.vertree = t; |
| } |
| else if (t == NULL) |
| { |
| /* We could not find the version for a symbol when |
| generating a shared archive. Return an error. */ |
| _bfd_error_handler |
| /* xgettext:c-format */ |
| (_("%pB: version node not found for symbol %s"), |
| info->output_bfd, h->root.root.string); |
| bfd_set_error (bfd_error_bad_value); |
| sinfo->failed = TRUE; |
| return FALSE; |
| } |
| } |
| |
| /* If we don't have a version for this symbol, see if we can find |
| something. */ |
| if (!hide |
| && h->verinfo.vertree == NULL |
| && sinfo->info->version_info != NULL) |
| { |
| h->verinfo.vertree |
| = bfd_find_version_for_sym (sinfo->info->version_info, |
| h->root.root.string, &hide); |
| if (h->verinfo.vertree != NULL && hide) |
| (*bed->elf_backend_hide_symbol) (info, h, TRUE); |
| } |
| |
| return TRUE; |
| } |
| |
| /* Read and swap the relocs from the section indicated by SHDR. This |
| may be either a REL or a RELA section. The relocations are |
| translated into RELA relocations and stored in INTERNAL_RELOCS, |
| which should have already been allocated to contain enough space. |
| The EXTERNAL_RELOCS are a buffer where the external form of the |
| relocations should be stored. |
| |
| Returns FALSE if something goes wrong. */ |
| |
| static bfd_boolean |
| elf_link_read_relocs_from_section (bfd *abfd, |
| asection *sec, |
| Elf_Internal_Shdr *shdr, |
| void *external_relocs, |
| Elf_Internal_Rela *internal_relocs) |
| { |
| const struct elf_backend_data *bed; |
| void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *); |
| const bfd_byte *erela; |
| const bfd_byte *erelaend; |
| Elf_Internal_Rela *irela; |
| Elf_Internal_Shdr *symtab_hdr; |
| size_t nsyms; |
| |
| /* Position ourselves at the start of the section. */ |
| if (bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0) |
| return FALSE; |
| |
| /* Read the relocations. */ |
| if (bfd_bread (external_relocs, shdr->sh_size, abfd) != shdr->sh_size) |
| return FALSE; |
| |
| symtab_hdr = &elf_tdata (abfd)->symtab_hdr; |
| nsyms = NUM_SHDR_ENTRIES (symtab_hdr); |
| |
| bed = get_elf_backend_data (abfd); |
| |
| /* Convert the external relocations to the internal format. */ |
| if (shdr->sh_entsize == bed->s->sizeof_rel) |
| swap_in = bed->s->swap_reloc_in; |
| else if (shdr->sh_entsize == bed->s->sizeof_rela) |
| swap_in = bed->s->swap_reloca_in; |
| else |
| { |
| bfd_set_error (bfd_error_wrong_format); |
| return FALSE; |
| } |
| |
| erela = (const bfd_byte *) external_relocs; |
| /* Setting erelaend like this and comparing with <= handles case of |
| a fuzzed object with sh_size not a multiple of sh_entsize. */ |
| erelaend = erela + shdr->sh_size - shdr->sh_entsize; |
| irela = internal_relocs; |
| while (erela <= erelaend) |
| { |
| bfd_vma r_symndx; |
| |
| (*swap_in) (abfd, erela, irela); |
| r_symndx = ELF32_R_SYM (irela->r_info); |
| if (bed->s->arch_size == 64) |
| r_symndx >>= 24; |
| if (nsyms > 0) |
| { |
| if ((size_t) r_symndx >= nsyms) |
| { |
| _bfd_error_handler |
| /* xgettext:c-format */ |
| (_("%pB: bad reloc symbol index (%#" PRIx64 " >= %#lx)" |
| " for offset %#" PRIx64 " in section `%pA'"), |
| abfd, (uint64_t) r_symndx, (unsigned long) nsyms, |
| (uint64_t) irela->r_offset, sec); |
| bfd_set_error (bfd_error_bad_value); |
| return FALSE; |
| } |
| } |
| else if (r_symndx != STN_UNDEF) |
| { |
| _bfd_error_handler |
| /* xgettext:c-format */ |
| (_("%pB: non-zero symbol index (%#" PRIx64 ")" |
| " for offset %#" PRIx64 " in section `%pA'" |
| " when the object file has no symbol table"), |
| abfd, (uint64_t) r_symndx, |
| (uint64_t) irela->r_offset, sec); |
| bfd_set_error (bfd_error_bad_value); |
| return FALSE; |
| } |
| irela += bed->s->int_rels_per_ext_rel; |
| erela += shdr->sh_entsize; |
| } |
| |
| return TRUE; |
| } |
| |
| /* Read and swap the relocs for a section O. They may have been |
| cached. If the EXTERNAL_RELOCS and INTERNAL_RELOCS arguments are |
| not NULL, they are used as buffers to read into. They are known to |
| be large enough. If the INTERNAL_RELOCS relocs argument is NULL, |
| the return value is allocated using either malloc or bfd_alloc, |
| according to the KEEP_MEMORY argument. If O has two relocation |
| sections (both REL and RELA relocations), then the REL_HDR |
| relocations will appear first in INTERNAL_RELOCS, followed by the |
| RELA_HDR relocations. */ |
| |
| Elf_Internal_Rela * |
| _bfd_elf_link_read_relocs (bfd *abfd, |
| asection *o, |
| void *external_relocs, |
| Elf_Internal_Rela *internal_relocs, |
| bfd_boolean keep_memory) |
| { |
| void *alloc1 = NULL; |
| Elf_Internal_Rela *alloc2 = NULL; |
| const struct elf_backend_data *bed = get_elf_backend_data (abfd); |
| struct bfd_elf_section_data *esdo = elf_section_data (o); |
| Elf_Internal_Rela *internal_rela_relocs; |
| |
| if (esdo->relocs != NULL) |
| return esdo->relocs; |
| |
| if (o->reloc_count == 0) |
| return NULL; |
| |
| if (internal_relocs == NULL) |
| { |
| bfd_size_type size; |
| |
| size = (bfd_size_type) o->reloc_count * sizeof (Elf_Internal_Rela); |
| if (keep_memory) |
| internal_relocs = alloc2 = (Elf_Internal_Rela *) bfd_alloc (abfd, size); |
| else |
| internal_relocs = alloc2 = (Elf_Internal_Rela *) bfd_malloc (size); |
| if (internal_relocs == NULL) |
| goto error_return; |
| } |
| |
| if (external_relocs == NULL) |
| { |
| bfd_size_type size = 0; |
| |
| if (esdo->rel.hdr) |
| size += esdo->rel.hdr->sh_size; |
| if (esdo->rela.hdr) |
| size += esdo->rela.hdr->sh_size; |
| |
| alloc1 = bfd_malloc (size); |
| if (alloc1 == NULL) |
| goto error_return; |
| external_relocs = alloc1; |
| } |
| |
| internal_rela_relocs = internal_relocs; |
| if (esdo->rel.hdr) |
| { |
| if (!elf_link_read_relocs_from_section (abfd, o, esdo->rel.hdr, |
| external_relocs, |
| internal_relocs)) |
| goto error_return; |
| external_relocs = (((bfd_byte *) external_relocs) |
| + esdo->rel.hdr->sh_size); |
| internal_rela_relocs += (NUM_SHDR_ENTRIES (esdo->rel.hdr) |
| * bed->s->int_rels_per_ext_rel); |
| } |
| |
| if (esdo->rela.hdr |
| && (!elf_link_read_relocs_from_section (abfd, o, esdo->rela.hdr, |
| external_relocs, |
| internal_rela_relocs))) |
| goto error_return; |
| |
| /* Cache the results for next time, if we can. */ |
| if (keep_memory) |
| esdo->relocs = internal_relocs; |
| |
| if (alloc1 != NULL) |
| free (alloc1); |
| |
| /* Don't free alloc2, since if it was allocated we are passing it |
| back (under the name of internal_relocs). */ |
| |
| return internal_relocs; |
| |
| error_return: |
| if (alloc1 != NULL) |
| free (alloc1); |
| if (alloc2 != NULL) |
| { |
| if (keep_memory) |
| bfd_release (abfd, alloc2); |
| else |
| free (alloc2); |
| } |
| return NULL; |
| } |
| |
| /* Compute the size of, and allocate space for, REL_HDR which is the |
| section header for a section containing relocations for O. */ |
| |
| static bfd_boolean |
| _bfd_elf_link_size_reloc_section (bfd *abfd, |
| struct bfd_elf_section_reloc_data *reldata) |
| { |
| Elf_Internal_Shdr *rel_hdr = reldata->hdr; |
| |
| /* That allows us to calculate the size of the section. */ |
| rel_hdr->sh_size = rel_hdr->sh_entsize * reldata->count; |
| |
| /* The contents field must last into write_object_contents, so we |
| allocate it with bfd_alloc rather than malloc. Also since we |
| cannot be sure that the contents will actually be filled in, |
| we zero the allocated space. */ |
| rel_hdr->contents = (unsigned char *) bfd_zalloc (abfd, rel_hdr->sh_size); |
| if (rel_hdr->contents == NULL && rel_hdr->sh_size != 0) |
| return FALSE; |
| |
| if (reldata->hashes == NULL && reldata->count) |
| { |
| struct elf_link_hash_entry **p; |
| |
| p = ((struct elf_link_hash_entry **) |
| bfd_zmalloc (reldata->count * sizeof (*p))); |
| if (p == NULL) |
| return FALSE; |
| |
| reldata->hashes = p; |
| } |
| |
| return TRUE; |
| } |
| |
| /* Copy the relocations indicated by the INTERNAL_RELOCS (which |
| originated from the section given by INPUT_REL_HDR) to the |
| OUTPUT_BFD. */ |
| |
| bfd_boolean |
| _bfd_elf_link_output_relocs (bfd *output_bfd, |
| asection *input_section, |
| Elf_Internal_Shdr *input_rel_hdr, |
| Elf_Internal_Rela *internal_relocs, |
| struct elf_link_hash_entry **rel_hash |
| ATTRIBUTE_UNUSED) |
| { |
| Elf_Internal_Rela *irela; |
| Elf_Internal_Rela *irelaend; |
| bfd_byte *erel; |
| struct bfd_elf_section_reloc_data *output_reldata; |
| asection *output_section; |
| const struct elf_backend_data *bed; |
| void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *); |
| struct bfd_elf_section_data *esdo; |
| |
| output_section = input_section->output_section; |
| |
| bed = get_elf_backend_data (output_bfd); |
| esdo = elf_section_data (output_section); |
| if (esdo->rel.hdr && esdo->rel.hdr->sh_entsize == input_rel_hdr->sh_entsize) |
| { |
| output_reldata = &esdo->rel; |
| swap_out = bed->s->swap_reloc_out; |
| } |
| else if (esdo->rela.hdr |
| && esdo->rela.hdr->sh_entsize == input_rel_hdr->sh_entsize) |
| { |
| output_reldata = &esdo->rela; |
| swap_out = bed->s->swap_reloca_out; |
| } |
| else |
| { |
| _bfd_error_handler |
| /* xgettext:c-format */ |
| (_("%pB: relocation size mismatch in %pB section %pA"), |
| output_bfd, input_section->owner, input_section); |
| bfd_set_error (bfd_error_wrong_format); |
| return FALSE; |
| } |
| |
| erel = output_reldata->hdr->contents; |
| erel += output_reldata->count * input_rel_hdr->sh_entsize; |
| irela = internal_relocs; |
| irelaend = irela + (NUM_SHDR_ENTRIES (input_rel_hdr) |
| * bed->s->int_rels_per_ext_rel); |
| while (irela < irelaend) |
| { |
| (*swap_out) (output_bfd, irela, erel); |
| irela += bed->s->int_rels_per_ext_rel; |
| erel += input_rel_hdr->sh_entsize; |
| } |
| |
| /* Bump the counter, so that we know where to add the next set of |
| relocations. */ |
| output_reldata->count += NUM_SHDR_ENTRIES (input_rel_hdr); |
| |
| return TRUE; |
| } |
| |
| /* Make weak undefined symbols in PIE dynamic. */ |
| |
| bfd_boolean |
| _bfd_elf_link_hash_fixup_symbol (struct bfd_link_info *info, |
| struct elf_link_hash_entry *h) |
| { |
| if (bfd_link_pie (info) |
| && h->dynindx == -1 |
| && h->root.type == bfd_link_hash_undefweak) |
| return bfd_elf_link_record_dynamic_symbol (info, h); |
| |
| return TRUE; |
| } |
| |
| /* Fix up the flags for a symbol. This handles various cases which |
| can only be fixed after all the input files are seen. This is |
| currently called by both adjust_dynamic_symbol and |
| assign_sym_version, which is unnecessary but perhaps more robust in |
| the face of future changes. */ |
| |
| static bfd_boolean |
| _bfd_elf_fix_symbol_flags (struct elf_link_hash_entry *h, |
| struct elf_info_failed *eif) |
| { |
| const struct elf_backend_data *bed; |
| |
| /* If this symbol was mentioned in a non-ELF file, try to set |
| DEF_REGULAR and REF_REGULAR correctly. This is the only way to |
| permit a non-ELF file to correctly refer to a symbol defined in |
| an ELF dynamic object. */ |
| if (h->non_elf) |
| { |
| while (h->root.type == bfd_link_hash_indirect) |
| h = (struct elf_link_hash_entry *) h->root.u.i.link; |
| |
| if (h->root.type != bfd_link_hash_defined |
| && h->root.type != bfd_link_hash_defweak) |
| { |
| h->ref_regular = 1; |
| h->ref_regular_nonweak = 1; |
| } |
| else |
| { |
| if (h->root.u.def.section->owner != NULL |
| && (bfd_get_flavour (h->root.u.def.section->owner) |
| == bfd_target_elf_flavour)) |
| { |
| h->ref_regular = 1; |
| h->ref_regular_nonweak = 1; |
| } |
| else |
| h->def_regular = 1; |
| } |
| |
| if (h->dynindx == -1 |
| && (h->def_dynamic |
| || h->ref_dynamic)) |
| { |
| if (! bfd_elf_link_record_dynamic_symbol (eif->info, h)) |
| { |
| eif->failed = TRUE; |
| return FALSE; |
| } |
| } |
| } |
| else |
| { |
| /* Unfortunately, NON_ELF is only correct if the symbol |
| was first seen in a non-ELF file. Fortunately, if the symbol |
| was first seen in an ELF file, we're probably OK unless the |
| symbol was defined in a non-ELF file. Catch that case here. |
| FIXME: We're still in trouble if the symbol was first seen in |
| a dynamic object, and then later in a non-ELF regular object. */ |
| if ((h->root.type == bfd_link_hash_defined |
| || h->root.type == bfd_link_hash_defweak) |
| && !h->def_regular |
| && (h->root.u.def.section->owner != NULL |
| ? (bfd_get_flavour (h->root.u.def.section->owner) |
| != bfd_target_elf_flavour) |
| : (bfd_is_abs_section (h->root.u.def.section) |
| && !h->def_dynamic))) |
| h->def_regular = 1; |
| } |
| |
| /* Backend specific symbol fixup. */ |
| bed = get_elf_backend_data (elf_hash_table (eif->info)->dynobj); |
| if (bed->elf_backend_fixup_symbol |
| && !(*bed->elf_backend_fixup_symbol) (eif->info, h)) |
| return FALSE; |
| |
| /* If this is a final link, and the symbol was defined as a common |
| symbol in a regular object file, and there was no definition in |
| any dynamic object, then the linker will have allocated space for |
| the symbol in a common section but the DEF_REGULAR |
| flag will not have been set. */ |
| if (h->root.type == bfd_link_hash_defined |
| && !h->def_regular |
| && h->ref_regular |
| && !h->def_dynamic |
| && (h->root.u.def.section->owner->flags & (DYNAMIC | BFD_PLUGIN)) == 0) |
| h->def_regular = 1; |
| |
| /* Symbols defined in discarded sections shouldn't be dynamic. */ |
| if (h->root.type == bfd_link_hash_undefined && h->indx == -3) |
| (*bed->elf_backend_hide_symbol) (eif->info, h, TRUE); |
| |
| /* If a weak undefined symbol has non-default visibility, we also |
| hide it from the dynamic linker. */ |
| else if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT |
| && h->root.type == bfd_link_hash_undefweak) |
| (*bed->elf_backend_hide_symbol) (eif->info, h, TRUE); |
| |
| /* A hidden versioned symbol in executable should be forced local if |
| it is is locally defined, not referenced by shared library and not |
| exported. */ |
| else if (bfd_link_executable (eif->info) |
| && h->versioned == versioned_hidden |
| && !eif->info->export_dynamic |
| && !h->dynamic |
| && !h->ref_dynamic |
| && h->def_regular) |
| (*bed->elf_backend_hide_symbol) (eif->info, h, TRUE); |
| |
| /* If -Bsymbolic was used (which means to bind references to global |
| symbols to the definition within the shared object), and this |
| symbol was defined in a regular object, then it actually doesn't |
| need a PLT entry. Likewise, if the symbol has non-default |
| visibility. If the symbol has hidden or internal visibility, we |
| will force it local. */ |
| else if (h->needs_plt |
| && bfd_link_pic (eif->info) |
| && is_elf_hash_table (eif->info->hash) |
| && (SYMBOLIC_BIND (eif->info, h) |
| || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) |
| && h->def_regular) |
| { |
| bfd_boolean force_local; |
| |
| force_local = (ELF_ST_VISIBILITY (h->other) == STV_INTERNAL |
| || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN); |
| (*bed->elf_backend_hide_symbol) (eif->info, h, force_local); |
| } |
| |
| /* If this is a weak defined symbol in a dynamic object, and we know |
| the real definition in the dynamic object, copy interesting flags |
| over to the real definition. */ |
| if (h->is_weakalias) |
| { |
| struct elf_link_hash_entry *def = weakdef (h); |
| |
| /* If the real definition is defined by a regular object file, |
| don't do anything special. See the longer description in |
| _bfd_elf_adjust_dynamic_symbol, below. If the def is not |
| bfd_link_hash_defined as it was when put on the alias list |
| then it must have originally been a versioned symbol (for |
| which a non-versioned indirect symbol is created) and later |
| a definition for the non-versioned symbol is found. In that |
| case the indirection is flipped with the versioned symbol |
| becoming an indirect pointing at the non-versioned symbol. |
| Thus, not an alias any more. */ |
| if (def->def_regular |
| || def->root.type != bfd_link_hash_defined) |
| { |
| h = def; |
| while ((h = h->u.alias) != def) |
| h->is_weakalias = 0; |
| } |
| else |
| { |
| while (h->root.type == bfd_link_hash_indirect) |
| h = (struct elf_link_hash_entry *) h->root.u.i.link; |
| BFD_ASSERT (h->root.type == bfd_link_hash_defined |
| || h->root.type == bfd_link_hash_defweak); |
| BFD_ASSERT (def->def_dynamic); |
| (*bed->elf_backend_copy_indirect_symbol) (eif->info, def, h); |
| } |
| } |
| |
| return TRUE; |
| } |
| |
| /* Make the backend pick a good value for a dynamic symbol. This is |
| called via elf_link_hash_traverse, and also calls itself |
| recursively. */ |
| |
| static bfd_boolean |
| _bfd_elf_adjust_dynamic_symbol (struct elf_link_hash_entry *h, void *data) |
| { |
| struct elf_info_failed *eif = (struct elf_info_failed *) data; |
| struct elf_link_hash_table *htab; |
| const struct elf_backend_data *bed; |
| |
| if (! is_elf_hash_table (eif->info->hash)) |
| return FALSE; |
| |
| /* Ignore indirect symbols. These are added by the versioning code. */ |
| if (h->root.type == bfd_link_hash_indirect) |
| return TRUE; |
| |
| /* Fix the symbol flags. */ |
| if (! _bfd_elf_fix_symbol_flags (h, eif)) |
| return FALSE; |
| |
| htab = elf_hash_table (eif->info); |
| bed = get_elf_backend_data (htab->dynobj); |
| |
| if (h->root.type == bfd_link_hash_undefweak) |
| { |
| if (eif->info->dynamic_undefined_weak == 0) |
| (*bed->elf_backend_hide_symbol) (eif->info, h, TRUE); |
| else if (eif->info->dynamic_undefined_weak > 0 |
| && h->ref_regular |
| && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT |
| && !bfd_hide_sym_by_version (eif->info->version_info, |
| h->root.root.string)) |
| { |
| if (!bfd_elf_link_record_dynamic_symbol (eif->info, h)) |
| { |
| eif->failed = TRUE; |
| return FALSE; |
| } |
| } |
| } |
| |
| /* If this symbol does not require a PLT entry, and it is not |
| defined by a dynamic object, or is not referenced by a regular |
| object, ignore it. We do have to handle a weak defined symbol, |
| even if no regular object refers to it, if we decided to add it |
| to the dynamic symbol table. FIXME: Do we normally need to worry |
| about symbols which are defined by one dynamic object and |
| referenced by another one? */ |
| if (!h->needs_plt |
| && h->type != STT_GNU_IFUNC |
| && (h->def_regular |
| || !h->def_dynamic |
| || (!h->ref_regular |
| && (!h->is_weakalias || weakdef (h)->dynindx == -1)))) |
| { |
| h->plt = elf_hash_table (eif->info)->init_plt_offset; |
| return TRUE; |
| } |
| |
| /* If we've already adjusted this symbol, don't do it again. This |
| can happen via a recursive call. */ |
| if (h->dynamic_adjusted) |
| return TRUE; |
| |
| /* Don't look at this symbol again. Note that we must set this |
| after checking the above conditions, because we may look at a |
| symbol once, decide not to do anything, and then get called |
| recursively later after REF_REGULAR is set below. */ |
| h->dynamic_adjusted = 1; |
| |
| /* If this is a weak definition, and we know a real definition, and |
| the real symbol is not itself defined by a regular object file, |
| then get a good value for the real definition. We handle the |
| real symbol first, for the convenience of the backend routine. |
| |
| Note that there is a confusing case here. If the real definition |
| is defined by a regular object file, we don't get the real symbol |
| from the dynamic object, but we do get the weak symbol. If the |
| processor backend uses a COPY reloc, then if some routine in the |
| dynamic object changes the real symbol, we will not see that |
| change in the corresponding weak symbol. This is the way other |
| ELF linkers work as well, and seems to be a result of the shared |
| library model. |
| |
| I will clarify this issue. Most SVR4 shared libraries define the |
| variable _timezone and define timezone as a weak synonym. The |
| tzset call changes _timezone. If you write |
| extern int timezone; |
| int _timezone = 5; |
| int main () { tzset (); printf ("%d %d\n", timezone, _timezone); } |
| you might expect that, since timezone is a synonym for _timezone, |
| the same number will print both times. However, if the processor |
| backend uses a COPY reloc, then actually timezone will be copied |
| into your process image, and, since you define _timezone |
| yourself, _timezone will not. Thus timezone and _timezone will |
| wind up at different memory locations. The tzset call will set |
| _timezone, leaving timezone unchanged. */ |
| |
| if (h->is_weakalias) |
| { |
| struct elf_link_hash_entry *def = weakdef (h); |
| |
| /* If we get to this point, there is an implicit reference to |
| the alias by a regular object file via the weak symbol H. */ |
| def->ref_regular = 1; |
| |
| /* Ensure that the backend adjust_dynamic_symbol function sees |
| the strong alias before H by recursively calling ourselves. */ |
| if (!_bfd_elf_adjust_dynamic_symbol (def, eif)) |
| return FALSE; |
| } |
| |
| /* If a symbol has no type and no size and does not require a PLT |
| entry, then we are probably about to do the wrong thing here: we |
| are probably going to create a COPY reloc for an empty object. |
| This case can arise when a shared object is built with assembly |
| code, and the assembly code fails to set the symbol type. */ |
| if (h->size == 0 |
| && h->type == STT_NOTYPE |
| && !h->needs_plt) |
| _bfd_error_handler |
| (_("warning: type and size of dynamic symbol `%s' are not defined"), |
| h->root.root.string); |
| |
| if (! (*bed->elf_backend_adjust_dynamic_symbol) (eif->info, h)) |
| { |
| eif->failed = TRUE; |
| return FALSE; |
| } |
| |
| return TRUE; |
| } |
| |
| /* Adjust the dynamic symbol, H, for copy in the dynamic bss section, |
| DYNBSS. */ |
| |
| bfd_boolean |
| _bfd_elf_adjust_dynamic_copy (struct bfd_link_info *info, |
| struct elf_link_hash_entry *h, |
| asection *dynbss) |
| { |
| unsigned int power_of_two; |
| bfd_vma mask; |
| asection *sec = h->root.u.def.section; |
| |
| /* The section alignment of the definition is the maximum alignment |
| requirement of symbols defined in the section. Since we don't |
| know the symbol alignment requirement, we start with the |
| maximum alignment and check low bits of the symbol address |
| for the minimum alignment. */ |
| power_of_two = bfd_section_alignment (sec); |
| mask = ((bfd_vma) 1 << power_of_two) - 1; |
| while ((h->root.u.def.value & mask) != 0) |
| { |
| mask >>= 1; |
| --power_of_two; |
| } |
| |
| if (power_of_two > bfd_section_alignment (dynbss)) |
| { |
| |