133965Sjdp/* ELF linking support for BFD. 2218822Sdim Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 3218822Sdim 2005, 2006, 2007 Free Software Foundation, Inc. 433965Sjdp 5218822Sdim This file is part of BFD, the Binary File Descriptor library. 633965Sjdp 7218822Sdim This program is free software; you can redistribute it and/or modify 8218822Sdim it under the terms of the GNU General Public License as published by 9218822Sdim the Free Software Foundation; either version 2 of the License, or 10218822Sdim (at your option) any later version. 1133965Sjdp 12218822Sdim This program is distributed in the hope that it will be useful, 13218822Sdim but WITHOUT ANY WARRANTY; without even the implied warranty of 14218822Sdim MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15218822Sdim GNU General Public License for more details. 1633965Sjdp 17218822Sdim You should have received a copy of the GNU General Public License 18218822Sdim along with this program; if not, write to the Free Software 19218822Sdim Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 2033965Sjdp 21218822Sdim#include "sysdep.h" 2233965Sjdp#include "bfd.h" 2333965Sjdp#include "bfdlink.h" 2433965Sjdp#include "libbfd.h" 2533965Sjdp#define ARCH_SIZE 0 2633965Sjdp#include "elf-bfd.h" 27130561Sobrien#include "safe-ctype.h" 28130561Sobrien#include "libiberty.h" 29218822Sdim#include "objalloc.h" 3033965Sjdp 31218822Sdim/* Define a symbol in a dynamic linkage section. */ 32218822Sdim 33218822Sdimstruct elf_link_hash_entry * 34218822Sdim_bfd_elf_define_linkage_sym (bfd *abfd, 35218822Sdim struct bfd_link_info *info, 36218822Sdim asection *sec, 37218822Sdim const char *name) 38218822Sdim{ 39218822Sdim struct elf_link_hash_entry *h; 40218822Sdim struct bfd_link_hash_entry *bh; 41218822Sdim const struct elf_backend_data *bed; 42218822Sdim 43218822Sdim h = elf_link_hash_lookup (elf_hash_table (info), name, FALSE, FALSE, FALSE); 44218822Sdim if (h != NULL) 45218822Sdim { 46218822Sdim /* Zap symbol defined in an as-needed lib that wasn't linked. 47218822Sdim This is a symptom of a larger problem: Absolute symbols 48218822Sdim defined in shared libraries can't be overridden, because we 49218822Sdim lose the link to the bfd which is via the symbol section. */ 50218822Sdim h->root.type = bfd_link_hash_new; 51218822Sdim } 52218822Sdim 53218822Sdim bh = &h->root; 54218822Sdim if (!_bfd_generic_link_add_one_symbol (info, abfd, name, BSF_GLOBAL, 55218822Sdim sec, 0, NULL, FALSE, 56218822Sdim get_elf_backend_data (abfd)->collect, 57218822Sdim &bh)) 58218822Sdim return NULL; 59218822Sdim h = (struct elf_link_hash_entry *) bh; 60218822Sdim h->def_regular = 1; 61218822Sdim h->type = STT_OBJECT; 62218822Sdim h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN; 63218822Sdim 64218822Sdim bed = get_elf_backend_data (abfd); 65218822Sdim (*bed->elf_backend_hide_symbol) (info, h, TRUE); 66218822Sdim return h; 67218822Sdim} 68218822Sdim 69130561Sobrienbfd_boolean 70130561Sobrien_bfd_elf_create_got_section (bfd *abfd, struct bfd_link_info *info) 7133965Sjdp{ 7233965Sjdp flagword flags; 73130561Sobrien asection *s; 7433965Sjdp struct elf_link_hash_entry *h; 75130561Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 7638889Sjdp int ptralign; 7733965Sjdp 7833965Sjdp /* This function may be called more than once. */ 79130561Sobrien s = bfd_get_section_by_name (abfd, ".got"); 80130561Sobrien if (s != NULL && (s->flags & SEC_LINKER_CREATED) != 0) 81130561Sobrien return TRUE; 8233965Sjdp 8338889Sjdp switch (bed->s->arch_size) 8438889Sjdp { 8577298Sobrien case 32: 8677298Sobrien ptralign = 2; 8777298Sobrien break; 8877298Sobrien 8977298Sobrien case 64: 9077298Sobrien ptralign = 3; 9177298Sobrien break; 9277298Sobrien 9377298Sobrien default: 9477298Sobrien bfd_set_error (bfd_error_bad_value); 95130561Sobrien return FALSE; 9638889Sjdp } 9738889Sjdp 98218822Sdim flags = bed->dynamic_sec_flags; 9933965Sjdp 100218822Sdim s = bfd_make_section_with_flags (abfd, ".got", flags); 10133965Sjdp if (s == NULL 10238889Sjdp || !bfd_set_section_alignment (abfd, s, ptralign)) 103130561Sobrien return FALSE; 10433965Sjdp 10533965Sjdp if (bed->want_got_plt) 10633965Sjdp { 107218822Sdim s = bfd_make_section_with_flags (abfd, ".got.plt", flags); 10833965Sjdp if (s == NULL 10938889Sjdp || !bfd_set_section_alignment (abfd, s, ptralign)) 110130561Sobrien return FALSE; 11133965Sjdp } 11233965Sjdp 11389857Sobrien if (bed->want_got_sym) 11489857Sobrien { 11589857Sobrien /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got 11689857Sobrien (or .got.plt) section. We don't do this in the linker script 11789857Sobrien because we don't want to define the symbol if we are not creating 11889857Sobrien a global offset table. */ 119218822Sdim h = _bfd_elf_define_linkage_sym (abfd, info, s, "_GLOBAL_OFFSET_TABLE_"); 120218822Sdim elf_hash_table (info)->hgot = h; 121218822Sdim if (h == NULL) 122130561Sobrien return FALSE; 12389857Sobrien } 12433965Sjdp 12560484Sobrien /* The first bit of the global offset table is the header. */ 126218822Sdim s->size += bed->got_header_size; 12733965Sjdp 128130561Sobrien return TRUE; 12933965Sjdp} 13033965Sjdp 131218822Sdim/* Create a strtab to hold the dynamic symbol names. */ 132218822Sdimstatic bfd_boolean 133218822Sdim_bfd_elf_link_create_dynstrtab (bfd *abfd, struct bfd_link_info *info) 134218822Sdim{ 135218822Sdim struct elf_link_hash_table *hash_table; 136218822Sdim 137218822Sdim hash_table = elf_hash_table (info); 138218822Sdim if (hash_table->dynobj == NULL) 139218822Sdim hash_table->dynobj = abfd; 140218822Sdim 141218822Sdim if (hash_table->dynstr == NULL) 142218822Sdim { 143218822Sdim hash_table->dynstr = _bfd_elf_strtab_init (); 144218822Sdim if (hash_table->dynstr == NULL) 145218822Sdim return FALSE; 146218822Sdim } 147218822Sdim return TRUE; 148218822Sdim} 149218822Sdim 150130561Sobrien/* Create some sections which will be filled in with dynamic linking 151130561Sobrien information. ABFD is an input file which requires dynamic sections 152130561Sobrien to be created. The dynamic sections take up virtual memory space 153130561Sobrien when the final executable is run, so we need to create them before 154130561Sobrien addresses are assigned to the output sections. We work out the 155130561Sobrien actual contents and size of these sections later. */ 15633965Sjdp 157130561Sobrienbfd_boolean 158130561Sobrien_bfd_elf_link_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) 15933965Sjdp{ 160130561Sobrien flagword flags; 16133965Sjdp register asection *s; 162130561Sobrien const struct elf_backend_data *bed; 16333965Sjdp 164130561Sobrien if (! is_elf_hash_table (info->hash)) 165130561Sobrien return FALSE; 166130561Sobrien 167130561Sobrien if (elf_hash_table (info)->dynamic_sections_created) 168130561Sobrien return TRUE; 169130561Sobrien 170218822Sdim if (!_bfd_elf_link_create_dynstrtab (abfd, info)) 171218822Sdim return FALSE; 172130561Sobrien 173218822Sdim abfd = elf_hash_table (info)->dynobj; 174218822Sdim bed = get_elf_backend_data (abfd); 175130561Sobrien 176218822Sdim flags = bed->dynamic_sec_flags; 177218822Sdim 178130561Sobrien /* A dynamically linked executable has a .interp section, but a 179130561Sobrien shared library does not. */ 180130561Sobrien if (info->executable) 18138889Sjdp { 182218822Sdim s = bfd_make_section_with_flags (abfd, ".interp", 183218822Sdim flags | SEC_READONLY); 184218822Sdim if (s == NULL) 185130561Sobrien return FALSE; 186130561Sobrien } 18777298Sobrien 188130561Sobrien /* Create sections to hold version informations. These are removed 189130561Sobrien if they are not needed. */ 190218822Sdim s = bfd_make_section_with_flags (abfd, ".gnu.version_d", 191218822Sdim flags | SEC_READONLY); 192130561Sobrien if (s == NULL 193130561Sobrien || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) 194130561Sobrien return FALSE; 195130561Sobrien 196218822Sdim s = bfd_make_section_with_flags (abfd, ".gnu.version", 197218822Sdim flags | SEC_READONLY); 198130561Sobrien if (s == NULL 199130561Sobrien || ! bfd_set_section_alignment (abfd, s, 1)) 200130561Sobrien return FALSE; 201130561Sobrien 202218822Sdim s = bfd_make_section_with_flags (abfd, ".gnu.version_r", 203218822Sdim flags | SEC_READONLY); 204130561Sobrien if (s == NULL 205130561Sobrien || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) 206130561Sobrien return FALSE; 207130561Sobrien 208218822Sdim s = bfd_make_section_with_flags (abfd, ".dynsym", 209218822Sdim flags | SEC_READONLY); 210130561Sobrien if (s == NULL 211130561Sobrien || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) 212130561Sobrien return FALSE; 213130561Sobrien 214218822Sdim s = bfd_make_section_with_flags (abfd, ".dynstr", 215218822Sdim flags | SEC_READONLY); 216218822Sdim if (s == NULL) 217130561Sobrien return FALSE; 218130561Sobrien 219218822Sdim s = bfd_make_section_with_flags (abfd, ".dynamic", flags); 220130561Sobrien if (s == NULL 221130561Sobrien || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) 222130561Sobrien return FALSE; 223130561Sobrien 224130561Sobrien /* The special symbol _DYNAMIC is always set to the start of the 225218822Sdim .dynamic section. We could set _DYNAMIC in a linker script, but we 226218822Sdim only want to define it if we are, in fact, creating a .dynamic 227218822Sdim section. We don't want to define it if there is no .dynamic 228218822Sdim section, since on some ELF platforms the start up code examines it 229218822Sdim to decide how to initialize the process. */ 230218822Sdim if (!_bfd_elf_define_linkage_sym (abfd, info, s, "_DYNAMIC")) 231130561Sobrien return FALSE; 232130561Sobrien 233218822Sdim if (info->emit_hash) 234218822Sdim { 235218822Sdim s = bfd_make_section_with_flags (abfd, ".hash", flags | SEC_READONLY); 236218822Sdim if (s == NULL 237218822Sdim || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) 238218822Sdim return FALSE; 239218822Sdim elf_section_data (s)->this_hdr.sh_entsize = bed->s->sizeof_hash_entry; 240218822Sdim } 241130561Sobrien 242218822Sdim if (info->emit_gnu_hash) 243218822Sdim { 244218822Sdim s = bfd_make_section_with_flags (abfd, ".gnu.hash", 245218822Sdim flags | SEC_READONLY); 246218822Sdim if (s == NULL 247218822Sdim || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) 248218822Sdim return FALSE; 249218822Sdim /* For 64-bit ELF, .gnu.hash is a non-uniform entity size section: 250218822Sdim 4 32-bit words followed by variable count of 64-bit words, then 251218822Sdim variable count of 32-bit words. */ 252218822Sdim if (bed->s->arch_size == 64) 253218822Sdim elf_section_data (s)->this_hdr.sh_entsize = 0; 254218822Sdim else 255218822Sdim elf_section_data (s)->this_hdr.sh_entsize = 4; 256218822Sdim } 257130561Sobrien 258130561Sobrien /* Let the backend create the rest of the sections. This lets the 259130561Sobrien backend set the right flags. The backend will normally create 260130561Sobrien the .got and .plt sections. */ 261130561Sobrien if (! (*bed->elf_backend_create_dynamic_sections) (abfd, info)) 262130561Sobrien return FALSE; 263130561Sobrien 264130561Sobrien elf_hash_table (info)->dynamic_sections_created = TRUE; 265130561Sobrien 266130561Sobrien return TRUE; 267130561Sobrien} 268130561Sobrien 269130561Sobrien/* Create dynamic sections when linking against a dynamic object. */ 270130561Sobrien 271130561Sobrienbfd_boolean 272130561Sobrien_bfd_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) 273130561Sobrien{ 274130561Sobrien flagword flags, pltflags; 275218822Sdim struct elf_link_hash_entry *h; 276130561Sobrien asection *s; 277130561Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 278130561Sobrien 27933965Sjdp /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and 28033965Sjdp .rel[a].bss sections. */ 281218822Sdim flags = bed->dynamic_sec_flags; 28233965Sjdp 28338889Sjdp pltflags = flags; 28438889Sjdp if (bed->plt_not_loaded) 285218822Sdim /* We do not clear SEC_ALLOC here because we still want the OS to 286218822Sdim allocate space for the section; it's just that there's nothing 287218822Sdim to read in from the object file. */ 28889857Sobrien pltflags &= ~ (SEC_CODE | SEC_LOAD | SEC_HAS_CONTENTS); 289218822Sdim else 290218822Sdim pltflags |= SEC_ALLOC | SEC_CODE | SEC_LOAD; 29138889Sjdp if (bed->plt_readonly) 29238889Sjdp pltflags |= SEC_READONLY; 29338889Sjdp 294218822Sdim s = bfd_make_section_with_flags (abfd, ".plt", pltflags); 29533965Sjdp if (s == NULL 29638889Sjdp || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment)) 297130561Sobrien return FALSE; 29833965Sjdp 299218822Sdim /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the 300218822Sdim .plt section. */ 30133965Sjdp if (bed->want_plt_sym) 30233965Sjdp { 303218822Sdim h = _bfd_elf_define_linkage_sym (abfd, info, s, 304218822Sdim "_PROCEDURE_LINKAGE_TABLE_"); 305218822Sdim elf_hash_table (info)->hplt = h; 306218822Sdim if (h == NULL) 307130561Sobrien return FALSE; 30833965Sjdp } 30933965Sjdp 310218822Sdim s = bfd_make_section_with_flags (abfd, 311218822Sdim (bed->default_use_rela_p 312218822Sdim ? ".rela.plt" : ".rel.plt"), 313218822Sdim flags | SEC_READONLY); 31433965Sjdp if (s == NULL 315130561Sobrien || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) 316130561Sobrien return FALSE; 31733965Sjdp 31833965Sjdp if (! _bfd_elf_create_got_section (abfd, info)) 319130561Sobrien return FALSE; 32033965Sjdp 32160484Sobrien if (bed->want_dynbss) 32260484Sobrien { 32360484Sobrien /* The .dynbss section is a place to put symbols which are defined 32460484Sobrien by dynamic objects, are referenced by regular objects, and are 32560484Sobrien not functions. We must allocate space for them in the process 32660484Sobrien image and use a R_*_COPY reloc to tell the dynamic linker to 32760484Sobrien initialize them at run time. The linker script puts the .dynbss 32860484Sobrien section into the .bss section of the final image. */ 329218822Sdim s = bfd_make_section_with_flags (abfd, ".dynbss", 330218822Sdim (SEC_ALLOC 331218822Sdim | SEC_LINKER_CREATED)); 332218822Sdim if (s == NULL) 333130561Sobrien return FALSE; 33433965Sjdp 33560484Sobrien /* The .rel[a].bss section holds copy relocs. This section is not 336218822Sdim normally needed. We need to create it here, though, so that the 337218822Sdim linker will map it to an output section. We can't just create it 338218822Sdim only if we need it, because we will not know whether we need it 339218822Sdim until we have seen all the input files, and the first time the 340218822Sdim main linker code calls BFD after examining all the input files 341218822Sdim (size_dynamic_sections) the input sections have already been 342218822Sdim mapped to the output sections. If the section turns out not to 343218822Sdim be needed, we can discard it later. We will never need this 344218822Sdim section when generating a shared object, since they do not use 345218822Sdim copy relocs. */ 34660484Sobrien if (! info->shared) 34760484Sobrien { 348218822Sdim s = bfd_make_section_with_flags (abfd, 349218822Sdim (bed->default_use_rela_p 350218822Sdim ? ".rela.bss" : ".rel.bss"), 351218822Sdim flags | SEC_READONLY); 35260484Sobrien if (s == NULL 353130561Sobrien || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) 354130561Sobrien return FALSE; 35560484Sobrien } 35633965Sjdp } 35733965Sjdp 358130561Sobrien return TRUE; 35933965Sjdp} 36033965Sjdp 36133965Sjdp/* Record a new dynamic symbol. We record the dynamic symbols as we 36233965Sjdp read the input files, since we need to have a list of all of them 36333965Sjdp before we can determine the final sizes of the output sections. 36433965Sjdp Note that we may actually call this function even though we are not 36533965Sjdp going to output any dynamic symbols; in some cases we know that a 36633965Sjdp symbol should be in the dynamic symbol table, but only if there is 36733965Sjdp one. */ 36833965Sjdp 369130561Sobrienbfd_boolean 370130561Sobrienbfd_elf_link_record_dynamic_symbol (struct bfd_link_info *info, 371130561Sobrien struct elf_link_hash_entry *h) 37233965Sjdp{ 37333965Sjdp if (h->dynindx == -1) 37433965Sjdp { 37589857Sobrien struct elf_strtab_hash *dynstr; 376130561Sobrien char *p; 37733965Sjdp const char *name; 37833965Sjdp bfd_size_type indx; 37933965Sjdp 38060484Sobrien /* XXX: The ABI draft says the linker must turn hidden and 38160484Sobrien internal symbols into STB_LOCAL symbols when producing the 38260484Sobrien DSO. However, if ld.so honors st_other in the dynamic table, 38360484Sobrien this would not be necessary. */ 38460484Sobrien switch (ELF_ST_VISIBILITY (h->other)) 38560484Sobrien { 38660484Sobrien case STV_INTERNAL: 38760484Sobrien case STV_HIDDEN: 38868765Sobrien if (h->root.type != bfd_link_hash_undefined 38968765Sobrien && h->root.type != bfd_link_hash_undefweak) 39060484Sobrien { 391218822Sdim h->forced_local = 1; 392218822Sdim if (!elf_hash_table (info)->is_relocatable_executable) 393218822Sdim return TRUE; 39460484Sobrien } 39568765Sobrien 39660484Sobrien default: 39760484Sobrien break; 39860484Sobrien } 39960484Sobrien 40033965Sjdp h->dynindx = elf_hash_table (info)->dynsymcount; 40133965Sjdp ++elf_hash_table (info)->dynsymcount; 40233965Sjdp 40333965Sjdp dynstr = elf_hash_table (info)->dynstr; 40433965Sjdp if (dynstr == NULL) 40533965Sjdp { 40633965Sjdp /* Create a strtab to hold the dynamic symbol names. */ 40789857Sobrien elf_hash_table (info)->dynstr = dynstr = _bfd_elf_strtab_init (); 40833965Sjdp if (dynstr == NULL) 409130561Sobrien return FALSE; 41033965Sjdp } 41133965Sjdp 41233965Sjdp /* We don't put any version information in the dynamic string 413130561Sobrien table. */ 41433965Sjdp name = h->root.root.string; 41533965Sjdp p = strchr (name, ELF_VER_CHR); 416130561Sobrien if (p != NULL) 417130561Sobrien /* We know that the p points into writable memory. In fact, 418130561Sobrien there are only a few symbols that have read-only names, being 419130561Sobrien those like _GLOBAL_OFFSET_TABLE_ that are created specially 420130561Sobrien by the backends. Most symbols will have names pointing into 421130561Sobrien an ELF string table read from a file, or to objalloc memory. */ 422130561Sobrien *p = 0; 423104834Sobrien 424130561Sobrien indx = _bfd_elf_strtab_add (dynstr, name, p != NULL); 42533965Sjdp 426130561Sobrien if (p != NULL) 427130561Sobrien *p = ELF_VER_CHR; 42833965Sjdp 42933965Sjdp if (indx == (bfd_size_type) -1) 430130561Sobrien return FALSE; 43133965Sjdp h->dynstr_index = indx; 43233965Sjdp } 43333965Sjdp 434130561Sobrien return TRUE; 43533965Sjdp} 436130561Sobrien 437218822Sdim/* Mark a symbol dynamic. */ 438218822Sdim 439218822Sdimvoid 440218822Sdimbfd_elf_link_mark_dynamic_symbol (struct bfd_link_info *info, 441218822Sdim struct elf_link_hash_entry *h, 442218822Sdim Elf_Internal_Sym *sym) 443218822Sdim{ 444218822Sdim struct bfd_elf_dynamic_list *d = info->dynamic_list; 445218822Sdim 446218822Sdim /* It may be called more than once on the same H. */ 447218822Sdim if(h->dynamic || info->relocatable) 448218822Sdim return; 449218822Sdim 450218822Sdim if ((info->dynamic_data 451218822Sdim && (h->type == STT_OBJECT 452218822Sdim || (sym != NULL 453218822Sdim && ELF_ST_TYPE (sym->st_info) == STT_OBJECT))) 454218822Sdim || (d != NULL 455218822Sdim && h->root.type == bfd_link_hash_new 456218822Sdim && (*d->match) (&d->head, NULL, h->root.root.string))) 457218822Sdim h->dynamic = 1; 458218822Sdim} 459218822Sdim 460130561Sobrien/* Record an assignment to a symbol made by a linker script. We need 461130561Sobrien this in case some dynamic object refers to this symbol. */ 46260484Sobrien 463130561Sobrienbfd_boolean 464218822Sdimbfd_elf_record_link_assignment (bfd *output_bfd, 465130561Sobrien struct bfd_link_info *info, 466130561Sobrien const char *name, 467218822Sdim bfd_boolean provide, 468218822Sdim bfd_boolean hidden) 469130561Sobrien{ 470130561Sobrien struct elf_link_hash_entry *h; 471218822Sdim struct elf_link_hash_table *htab; 472130561Sobrien 473130561Sobrien if (!is_elf_hash_table (info->hash)) 474130561Sobrien return TRUE; 475130561Sobrien 476218822Sdim htab = elf_hash_table (info); 477218822Sdim h = elf_link_hash_lookup (htab, name, !provide, TRUE, FALSE); 478130561Sobrien if (h == NULL) 479218822Sdim return provide; 480130561Sobrien 481130561Sobrien /* Since we're defining the symbol, don't let it seem to have not 482130561Sobrien been defined. record_dynamic_symbol and size_dynamic_sections 483130561Sobrien may depend on this. */ 484130561Sobrien if (h->root.type == bfd_link_hash_undefweak 485130561Sobrien || h->root.type == bfd_link_hash_undefined) 486218822Sdim { 487218822Sdim h->root.type = bfd_link_hash_new; 488218822Sdim if (h->root.u.undef.next != NULL || htab->root.undefs_tail == &h->root) 489218822Sdim bfd_link_repair_undef_list (&htab->root); 490218822Sdim } 491255931Sdim else if (h->root.type == bfd_link_hash_new) 492218822Sdim { 493218822Sdim bfd_elf_link_mark_dynamic_symbol (info, h, NULL); 494218822Sdim h->non_elf = 0; 495218822Sdim } 496255931Sdim else if (h->root.type == bfd_link_hash_indirect) 497255931Sdim { 498255931Sdim const struct elf_backend_data *bed = get_elf_backend_data (output_bfd); 499255931Sdim struct elf_link_hash_entry *hv = h; 500255931Sdim do 501255931Sdim hv = (struct elf_link_hash_entry *) hv->root.u.i.link; 502255931Sdim while (hv->root.type == bfd_link_hash_indirect 503255931Sdim || hv->root.type == bfd_link_hash_warning); 504255931Sdim h->root.type = bfd_link_hash_undefined; 505255931Sdim hv->root.type = bfd_link_hash_indirect; 506255931Sdim hv->root.u.i.link = (struct bfd_link_hash_entry *) h; 507255931Sdim (*bed->elf_backend_copy_indirect_symbol) (info, h, hv); 508255931Sdim } 509255931Sdim else if (h->root.type == bfd_link_hash_warning) 510255931Sdim { 511255931Sdim abort (); 512255931Sdim } 513130561Sobrien 514130561Sobrien /* If this symbol is being provided by the linker script, and it is 515130561Sobrien currently defined by a dynamic object, but not by a regular 516130561Sobrien object, then mark it as undefined so that the generic linker will 517130561Sobrien force the correct value. */ 518130561Sobrien if (provide 519218822Sdim && h->def_dynamic 520218822Sdim && !h->def_regular) 521130561Sobrien h->root.type = bfd_link_hash_undefined; 522130561Sobrien 523130561Sobrien /* If this symbol is not being provided by the linker script, and it is 524130561Sobrien currently defined by a dynamic object, but not by a regular object, 525130561Sobrien then clear out any version information because the symbol will not be 526130561Sobrien associated with the dynamic object any more. */ 527130561Sobrien if (!provide 528218822Sdim && h->def_dynamic 529218822Sdim && !h->def_regular) 530130561Sobrien h->verinfo.verdef = NULL; 531130561Sobrien 532218822Sdim h->def_regular = 1; 533130561Sobrien 534218822Sdim if (provide && hidden) 535218822Sdim { 536218822Sdim const struct elf_backend_data *bed = get_elf_backend_data (output_bfd); 537218822Sdim 538218822Sdim h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN; 539218822Sdim (*bed->elf_backend_hide_symbol) (info, h, TRUE); 540218822Sdim } 541218822Sdim 542218822Sdim /* STV_HIDDEN and STV_INTERNAL symbols must be STB_LOCAL in shared objects 543218822Sdim and executables. */ 544218822Sdim if (!info->relocatable 545218822Sdim && h->dynindx != -1 546218822Sdim && (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN 547218822Sdim || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL)) 548218822Sdim h->forced_local = 1; 549218822Sdim 550218822Sdim if ((h->def_dynamic 551218822Sdim || h->ref_dynamic 552218822Sdim || info->shared 553218822Sdim || (info->executable && elf_hash_table (info)->is_relocatable_executable)) 554130561Sobrien && h->dynindx == -1) 555130561Sobrien { 556130561Sobrien if (! bfd_elf_link_record_dynamic_symbol (info, h)) 557130561Sobrien return FALSE; 558130561Sobrien 559130561Sobrien /* If this is a weak defined symbol, and we know a corresponding 560130561Sobrien real symbol from the same dynamic object, make sure the real 561130561Sobrien symbol is also made into a dynamic symbol. */ 562218822Sdim if (h->u.weakdef != NULL 563218822Sdim && h->u.weakdef->dynindx == -1) 564130561Sobrien { 565218822Sdim if (! bfd_elf_link_record_dynamic_symbol (info, h->u.weakdef)) 566130561Sobrien return FALSE; 567130561Sobrien } 568130561Sobrien } 569130561Sobrien 570130561Sobrien return TRUE; 571130561Sobrien} 572130561Sobrien 573104834Sobrien/* Record a new local dynamic symbol. Returns 0 on failure, 1 on 574104834Sobrien success, and 2 on a failure caused by attempting to record a symbol 575104834Sobrien in a discarded section, eg. a discarded link-once section symbol. */ 576104834Sobrien 577104834Sobrienint 578130561Sobrienbfd_elf_link_record_local_dynamic_symbol (struct bfd_link_info *info, 579130561Sobrien bfd *input_bfd, 580130561Sobrien long input_indx) 581104834Sobrien{ 582104834Sobrien bfd_size_type amt; 583104834Sobrien struct elf_link_local_dynamic_entry *entry; 584104834Sobrien struct elf_link_hash_table *eht; 585104834Sobrien struct elf_strtab_hash *dynstr; 586104834Sobrien unsigned long dynstr_index; 587104834Sobrien char *name; 588104834Sobrien Elf_External_Sym_Shndx eshndx; 589104834Sobrien char esym[sizeof (Elf64_External_Sym)]; 590104834Sobrien 591130561Sobrien if (! is_elf_hash_table (info->hash)) 592104834Sobrien return 0; 593104834Sobrien 594104834Sobrien /* See if the entry exists already. */ 595104834Sobrien for (entry = elf_hash_table (info)->dynlocal; entry ; entry = entry->next) 596104834Sobrien if (entry->input_bfd == input_bfd && entry->input_indx == input_indx) 597104834Sobrien return 1; 598104834Sobrien 599104834Sobrien amt = sizeof (*entry); 600130561Sobrien entry = bfd_alloc (input_bfd, amt); 601104834Sobrien if (entry == NULL) 602104834Sobrien return 0; 603104834Sobrien 604104834Sobrien /* Go find the symbol, so that we can find it's name. */ 605104834Sobrien if (!bfd_elf_get_elf_syms (input_bfd, &elf_tdata (input_bfd)->symtab_hdr, 606130561Sobrien 1, input_indx, &entry->isym, esym, &eshndx)) 607104834Sobrien { 608104834Sobrien bfd_release (input_bfd, entry); 609104834Sobrien return 0; 610104834Sobrien } 611104834Sobrien 612104834Sobrien if (entry->isym.st_shndx != SHN_UNDEF 613104834Sobrien && (entry->isym.st_shndx < SHN_LORESERVE 614104834Sobrien || entry->isym.st_shndx > SHN_HIRESERVE)) 615104834Sobrien { 616104834Sobrien asection *s; 617104834Sobrien 618104834Sobrien s = bfd_section_from_elf_index (input_bfd, entry->isym.st_shndx); 619104834Sobrien if (s == NULL || bfd_is_abs_section (s->output_section)) 620104834Sobrien { 621104834Sobrien /* We can still bfd_release here as nothing has done another 622104834Sobrien bfd_alloc. We can't do this later in this function. */ 623104834Sobrien bfd_release (input_bfd, entry); 624104834Sobrien return 2; 625104834Sobrien } 626104834Sobrien } 627104834Sobrien 628104834Sobrien name = (bfd_elf_string_from_elf_section 629104834Sobrien (input_bfd, elf_tdata (input_bfd)->symtab_hdr.sh_link, 630104834Sobrien entry->isym.st_name)); 631104834Sobrien 632104834Sobrien dynstr = elf_hash_table (info)->dynstr; 633104834Sobrien if (dynstr == NULL) 634104834Sobrien { 635104834Sobrien /* Create a strtab to hold the dynamic symbol names. */ 636104834Sobrien elf_hash_table (info)->dynstr = dynstr = _bfd_elf_strtab_init (); 637104834Sobrien if (dynstr == NULL) 638104834Sobrien return 0; 639104834Sobrien } 640104834Sobrien 641130561Sobrien dynstr_index = _bfd_elf_strtab_add (dynstr, name, FALSE); 642104834Sobrien if (dynstr_index == (unsigned long) -1) 643104834Sobrien return 0; 644104834Sobrien entry->isym.st_name = dynstr_index; 645104834Sobrien 646104834Sobrien eht = elf_hash_table (info); 647104834Sobrien 648104834Sobrien entry->next = eht->dynlocal; 649104834Sobrien eht->dynlocal = entry; 650104834Sobrien entry->input_bfd = input_bfd; 651104834Sobrien entry->input_indx = input_indx; 652104834Sobrien eht->dynsymcount++; 653104834Sobrien 654104834Sobrien /* Whatever binding the symbol had before, it's now local. */ 655104834Sobrien entry->isym.st_info 656104834Sobrien = ELF_ST_INFO (STB_LOCAL, ELF_ST_TYPE (entry->isym.st_info)); 657104834Sobrien 658104834Sobrien /* The dynindx will be set at the end of size_dynamic_sections. */ 659104834Sobrien 660104834Sobrien return 1; 661104834Sobrien} 662104834Sobrien 66360484Sobrien/* Return the dynindex of a local dynamic symbol. */ 66460484Sobrien 66560484Sobrienlong 666130561Sobrien_bfd_elf_link_lookup_local_dynindx (struct bfd_link_info *info, 667130561Sobrien bfd *input_bfd, 668130561Sobrien long input_indx) 66960484Sobrien{ 67060484Sobrien struct elf_link_local_dynamic_entry *e; 67160484Sobrien 67260484Sobrien for (e = elf_hash_table (info)->dynlocal; e ; e = e->next) 67360484Sobrien if (e->input_bfd == input_bfd && e->input_indx == input_indx) 67460484Sobrien return e->dynindx; 67560484Sobrien return -1; 67660484Sobrien} 67760484Sobrien 67860484Sobrien/* This function is used to renumber the dynamic symbols, if some of 67960484Sobrien them are removed because they are marked as local. This is called 68060484Sobrien via elf_link_hash_traverse. */ 68160484Sobrien 682130561Sobrienstatic bfd_boolean 683130561Sobrienelf_link_renumber_hash_table_dynsyms (struct elf_link_hash_entry *h, 684130561Sobrien void *data) 68560484Sobrien{ 686130561Sobrien size_t *count = data; 68760484Sobrien 68894536Sobrien if (h->root.type == bfd_link_hash_warning) 68994536Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 69094536Sobrien 691218822Sdim if (h->forced_local) 692218822Sdim return TRUE; 693218822Sdim 69460484Sobrien if (h->dynindx != -1) 69560484Sobrien h->dynindx = ++(*count); 69660484Sobrien 697130561Sobrien return TRUE; 69860484Sobrien} 69960484Sobrien 700218822Sdim 701218822Sdim/* Like elf_link_renumber_hash_table_dynsyms, but just number symbols with 702218822Sdim STB_LOCAL binding. */ 703218822Sdim 704218822Sdimstatic bfd_boolean 705218822Sdimelf_link_renumber_local_hash_table_dynsyms (struct elf_link_hash_entry *h, 706218822Sdim void *data) 707218822Sdim{ 708218822Sdim size_t *count = data; 709218822Sdim 710218822Sdim if (h->root.type == bfd_link_hash_warning) 711218822Sdim h = (struct elf_link_hash_entry *) h->root.u.i.link; 712218822Sdim 713218822Sdim if (!h->forced_local) 714218822Sdim return TRUE; 715218822Sdim 716218822Sdim if (h->dynindx != -1) 717218822Sdim h->dynindx = ++(*count); 718218822Sdim 719218822Sdim return TRUE; 720218822Sdim} 721218822Sdim 722218822Sdim/* Return true if the dynamic symbol for a given section should be 723218822Sdim omitted when creating a shared library. */ 724218822Sdimbfd_boolean 725218822Sdim_bfd_elf_link_omit_section_dynsym (bfd *output_bfd ATTRIBUTE_UNUSED, 726218822Sdim struct bfd_link_info *info, 727218822Sdim asection *p) 728218822Sdim{ 729218822Sdim struct elf_link_hash_table *htab; 730218822Sdim 731218822Sdim switch (elf_section_data (p)->this_hdr.sh_type) 732218822Sdim { 733218822Sdim case SHT_PROGBITS: 734218822Sdim case SHT_NOBITS: 735218822Sdim /* If sh_type is yet undecided, assume it could be 736218822Sdim SHT_PROGBITS/SHT_NOBITS. */ 737218822Sdim case SHT_NULL: 738218822Sdim htab = elf_hash_table (info); 739218822Sdim if (p == htab->tls_sec) 740218822Sdim return FALSE; 741218822Sdim 742218822Sdim if (htab->text_index_section != NULL) 743218822Sdim return p != htab->text_index_section && p != htab->data_index_section; 744218822Sdim 745218822Sdim if (strcmp (p->name, ".got") == 0 746218822Sdim || strcmp (p->name, ".got.plt") == 0 747218822Sdim || strcmp (p->name, ".plt") == 0) 748218822Sdim { 749218822Sdim asection *ip; 750218822Sdim 751218822Sdim if (htab->dynobj != NULL 752218822Sdim && (ip = bfd_get_section_by_name (htab->dynobj, p->name)) != NULL 753218822Sdim && (ip->flags & SEC_LINKER_CREATED) 754218822Sdim && ip->output_section == p) 755218822Sdim return TRUE; 756218822Sdim } 757218822Sdim return FALSE; 758218822Sdim 759218822Sdim /* There shouldn't be section relative relocations 760218822Sdim against any other section. */ 761218822Sdim default: 762218822Sdim return TRUE; 763218822Sdim } 764218822Sdim} 765218822Sdim 76678828Sobrien/* Assign dynsym indices. In a shared library we generate a section 767218822Sdim symbol for each output section, which come first. Next come symbols 768218822Sdim which have been forced to local binding. Then all of the back-end 769218822Sdim allocated local dynamic syms, followed by the rest of the global 770218822Sdim symbols. */ 77160484Sobrien 772218822Sdimstatic unsigned long 773218822Sdim_bfd_elf_link_renumber_dynsyms (bfd *output_bfd, 774218822Sdim struct bfd_link_info *info, 775218822Sdim unsigned long *section_sym_count) 77660484Sobrien{ 77760484Sobrien unsigned long dynsymcount = 0; 77860484Sobrien 779218822Sdim if (info->shared || elf_hash_table (info)->is_relocatable_executable) 78060484Sobrien { 781218822Sdim const struct elf_backend_data *bed = get_elf_backend_data (output_bfd); 78260484Sobrien asection *p; 78360484Sobrien for (p = output_bfd->sections; p ; p = p->next) 784218822Sdim if ((p->flags & SEC_EXCLUDE) == 0 785218822Sdim && (p->flags & SEC_ALLOC) != 0 786218822Sdim && !(*bed->elf_backend_omit_section_dynsym) (output_bfd, info, p)) 787104834Sobrien elf_section_data (p)->dynindx = ++dynsymcount; 788218822Sdim else 789218822Sdim elf_section_data (p)->dynindx = 0; 79060484Sobrien } 791218822Sdim *section_sym_count = dynsymcount; 79260484Sobrien 793218822Sdim elf_link_hash_traverse (elf_hash_table (info), 794218822Sdim elf_link_renumber_local_hash_table_dynsyms, 795218822Sdim &dynsymcount); 796218822Sdim 79760484Sobrien if (elf_hash_table (info)->dynlocal) 79860484Sobrien { 79960484Sobrien struct elf_link_local_dynamic_entry *p; 80060484Sobrien for (p = elf_hash_table (info)->dynlocal; p ; p = p->next) 80160484Sobrien p->dynindx = ++dynsymcount; 80260484Sobrien } 80360484Sobrien 80460484Sobrien elf_link_hash_traverse (elf_hash_table (info), 80560484Sobrien elf_link_renumber_hash_table_dynsyms, 80660484Sobrien &dynsymcount); 80760484Sobrien 80860484Sobrien /* There is an unused NULL entry at the head of the table which 80960484Sobrien we must account for in our count. Unless there weren't any 81060484Sobrien symbols, which means we'll have no table at all. */ 81160484Sobrien if (dynsymcount != 0) 81260484Sobrien ++dynsymcount; 81360484Sobrien 814218822Sdim elf_hash_table (info)->dynsymcount = dynsymcount; 815218822Sdim return dynsymcount; 81660484Sobrien} 817130561Sobrien 818130561Sobrien/* This function is called when we want to define a new symbol. It 819130561Sobrien handles the various cases which arise when we find a definition in 820130561Sobrien a dynamic object, or when there is already a definition in a 821130561Sobrien dynamic object. The new symbol is described by NAME, SYM, PSEC, 822130561Sobrien and PVALUE. We set SYM_HASH to the hash table entry. We set 823130561Sobrien OVERRIDE if the old symbol is overriding a new definition. We set 824130561Sobrien TYPE_CHANGE_OK if it is OK for the type to change. We set 825130561Sobrien SIZE_CHANGE_OK if it is OK for the size to change. By OK to 826130561Sobrien change, we mean that we shouldn't warn if the type or size does 827218822Sdim change. We set POLD_ALIGNMENT if an old common symbol in a dynamic 828218822Sdim object is overridden by a regular object. */ 829130561Sobrien 830130561Sobrienbfd_boolean 831130561Sobrien_bfd_elf_merge_symbol (bfd *abfd, 832130561Sobrien struct bfd_link_info *info, 833130561Sobrien const char *name, 834130561Sobrien Elf_Internal_Sym *sym, 835130561Sobrien asection **psec, 836130561Sobrien bfd_vma *pvalue, 837218822Sdim unsigned int *pold_alignment, 838130561Sobrien struct elf_link_hash_entry **sym_hash, 839130561Sobrien bfd_boolean *skip, 840130561Sobrien bfd_boolean *override, 841130561Sobrien bfd_boolean *type_change_ok, 842130561Sobrien bfd_boolean *size_change_ok) 843130561Sobrien{ 844218822Sdim asection *sec, *oldsec; 845130561Sobrien struct elf_link_hash_entry *h; 846130561Sobrien struct elf_link_hash_entry *flip; 847130561Sobrien int bind; 848130561Sobrien bfd *oldbfd; 849130561Sobrien bfd_boolean newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon; 850130561Sobrien bfd_boolean newweak, oldweak; 851218822Sdim const struct elf_backend_data *bed; 852130561Sobrien 853130561Sobrien *skip = FALSE; 854130561Sobrien *override = FALSE; 855130561Sobrien 856130561Sobrien sec = *psec; 857130561Sobrien bind = ELF_ST_BIND (sym->st_info); 858130561Sobrien 859218822Sdim /* Silently discard TLS symbols from --just-syms. There's no way to 860218822Sdim combine a static TLS block with a new TLS block for this executable. */ 861218822Sdim if (ELF_ST_TYPE (sym->st_info) == STT_TLS 862218822Sdim && sec->sec_info_type == ELF_INFO_TYPE_JUST_SYMS) 863218822Sdim { 864218822Sdim *skip = TRUE; 865218822Sdim return TRUE; 866218822Sdim } 867218822Sdim 868130561Sobrien if (! bfd_is_und_section (sec)) 869130561Sobrien h = elf_link_hash_lookup (elf_hash_table (info), name, TRUE, FALSE, FALSE); 870130561Sobrien else 871130561Sobrien h = ((struct elf_link_hash_entry *) 872130561Sobrien bfd_wrapped_link_hash_lookup (abfd, info, name, TRUE, FALSE, FALSE)); 873130561Sobrien if (h == NULL) 874130561Sobrien return FALSE; 875130561Sobrien *sym_hash = h; 876130561Sobrien 877218822Sdim bed = get_elf_backend_data (abfd); 878218822Sdim 879130561Sobrien /* This code is for coping with dynamic objects, and is only useful 880130561Sobrien if we are doing an ELF link. */ 881218822Sdim if (!(*bed->relocs_compatible) (abfd->xvec, info->hash->creator)) 882130561Sobrien return TRUE; 883130561Sobrien 884130561Sobrien /* For merging, we only care about real symbols. */ 885130561Sobrien 886130561Sobrien while (h->root.type == bfd_link_hash_indirect 887130561Sobrien || h->root.type == bfd_link_hash_warning) 888130561Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 889130561Sobrien 890218822Sdim /* We have to check it for every instance since the first few may be 891218822Sdim refereences and not all compilers emit symbol type for undefined 892218822Sdim symbols. */ 893218822Sdim bfd_elf_link_mark_dynamic_symbol (info, h, sym); 894218822Sdim 895130561Sobrien /* If we just created the symbol, mark it as being an ELF symbol. 896130561Sobrien Other than that, there is nothing to do--there is no merge issue 897130561Sobrien with a newly defined symbol--so we just return. */ 898130561Sobrien 899130561Sobrien if (h->root.type == bfd_link_hash_new) 900130561Sobrien { 901218822Sdim h->non_elf = 0; 902130561Sobrien return TRUE; 903130561Sobrien } 904130561Sobrien 905218822Sdim /* OLDBFD and OLDSEC are a BFD and an ASECTION associated with the 906218822Sdim existing symbol. */ 907130561Sobrien 908130561Sobrien switch (h->root.type) 909130561Sobrien { 910130561Sobrien default: 911130561Sobrien oldbfd = NULL; 912218822Sdim oldsec = NULL; 913130561Sobrien break; 914130561Sobrien 915130561Sobrien case bfd_link_hash_undefined: 916130561Sobrien case bfd_link_hash_undefweak: 917130561Sobrien oldbfd = h->root.u.undef.abfd; 918218822Sdim oldsec = NULL; 919130561Sobrien break; 920130561Sobrien 921130561Sobrien case bfd_link_hash_defined: 922130561Sobrien case bfd_link_hash_defweak: 923130561Sobrien oldbfd = h->root.u.def.section->owner; 924218822Sdim oldsec = h->root.u.def.section; 925130561Sobrien break; 926130561Sobrien 927130561Sobrien case bfd_link_hash_common: 928130561Sobrien oldbfd = h->root.u.c.p->section->owner; 929218822Sdim oldsec = h->root.u.c.p->section; 930130561Sobrien break; 931130561Sobrien } 932130561Sobrien 933130561Sobrien /* In cases involving weak versioned symbols, we may wind up trying 934130561Sobrien to merge a symbol with itself. Catch that here, to avoid the 935130561Sobrien confusion that results if we try to override a symbol with 936130561Sobrien itself. The additional tests catch cases like 937130561Sobrien _GLOBAL_OFFSET_TABLE_, which are regular symbols defined in a 938130561Sobrien dynamic object, which we do want to handle here. */ 939130561Sobrien if (abfd == oldbfd 940130561Sobrien && ((abfd->flags & DYNAMIC) == 0 941218822Sdim || !h->def_regular)) 942130561Sobrien return TRUE; 943130561Sobrien 944130561Sobrien /* NEWDYN and OLDDYN indicate whether the new or old symbol, 945130561Sobrien respectively, is from a dynamic object. */ 946130561Sobrien 947218822Sdim newdyn = (abfd->flags & DYNAMIC) != 0; 948130561Sobrien 949218822Sdim olddyn = FALSE; 950130561Sobrien if (oldbfd != NULL) 951130561Sobrien olddyn = (oldbfd->flags & DYNAMIC) != 0; 952218822Sdim else if (oldsec != NULL) 953130561Sobrien { 954218822Sdim /* This handles the special SHN_MIPS_{TEXT,DATA} section 955130561Sobrien indices used by MIPS ELF. */ 956218822Sdim olddyn = (oldsec->symbol->flags & BSF_DYNAMIC) != 0; 957218822Sdim } 958130561Sobrien 959218822Sdim /* NEWDEF and OLDDEF indicate whether the new or old symbol, 960218822Sdim respectively, appear to be a definition rather than reference. */ 961130561Sobrien 962218822Sdim newdef = !bfd_is_und_section (sec) && !bfd_is_com_section (sec); 963130561Sobrien 964218822Sdim olddef = (h->root.type != bfd_link_hash_undefined 965218822Sdim && h->root.type != bfd_link_hash_undefweak 966218822Sdim && h->root.type != bfd_link_hash_common); 967218822Sdim 968218822Sdim /* When we try to create a default indirect symbol from the dynamic 969218822Sdim definition with the default version, we skip it if its type and 970218822Sdim the type of existing regular definition mismatch. We only do it 971218822Sdim if the existing regular definition won't be dynamic. */ 972218822Sdim if (pold_alignment == NULL 973218822Sdim && !info->shared 974218822Sdim && !info->export_dynamic 975218822Sdim && !h->ref_dynamic 976218822Sdim && newdyn 977218822Sdim && newdef 978218822Sdim && !olddyn 979218822Sdim && (olddef || h->root.type == bfd_link_hash_common) 980218822Sdim && ELF_ST_TYPE (sym->st_info) != h->type 981218822Sdim && ELF_ST_TYPE (sym->st_info) != STT_NOTYPE 982218822Sdim && h->type != STT_NOTYPE 983218822Sdim && !(bed->is_function_type (ELF_ST_TYPE (sym->st_info)) 984218822Sdim && bed->is_function_type (h->type))) 985218822Sdim { 986218822Sdim *skip = TRUE; 987218822Sdim return TRUE; 988130561Sobrien } 989130561Sobrien 990218822Sdim /* Check TLS symbol. We don't check undefined symbol introduced by 991218822Sdim "ld -u". */ 992218822Sdim if ((ELF_ST_TYPE (sym->st_info) == STT_TLS || h->type == STT_TLS) 993218822Sdim && ELF_ST_TYPE (sym->st_info) != h->type 994218822Sdim && oldbfd != NULL) 995218822Sdim { 996218822Sdim bfd *ntbfd, *tbfd; 997218822Sdim bfd_boolean ntdef, tdef; 998218822Sdim asection *ntsec, *tsec; 999130561Sobrien 1000218822Sdim if (h->type == STT_TLS) 1001218822Sdim { 1002218822Sdim ntbfd = abfd; 1003218822Sdim ntsec = sec; 1004218822Sdim ntdef = newdef; 1005218822Sdim tbfd = oldbfd; 1006218822Sdim tsec = oldsec; 1007218822Sdim tdef = olddef; 1008218822Sdim } 1009218822Sdim else 1010218822Sdim { 1011218822Sdim ntbfd = oldbfd; 1012218822Sdim ntsec = oldsec; 1013218822Sdim ntdef = olddef; 1014218822Sdim tbfd = abfd; 1015218822Sdim tsec = sec; 1016218822Sdim tdef = newdef; 1017218822Sdim } 1018130561Sobrien 1019218822Sdim if (tdef && ntdef) 1020218822Sdim (*_bfd_error_handler) 1021218822Sdim (_("%s: TLS definition in %B section %A mismatches non-TLS definition in %B section %A"), 1022218822Sdim tbfd, tsec, ntbfd, ntsec, h->root.root.string); 1023218822Sdim else if (!tdef && !ntdef) 1024218822Sdim (*_bfd_error_handler) 1025218822Sdim (_("%s: TLS reference in %B mismatches non-TLS reference in %B"), 1026218822Sdim tbfd, ntbfd, h->root.root.string); 1027218822Sdim else if (tdef) 1028218822Sdim (*_bfd_error_handler) 1029218822Sdim (_("%s: TLS definition in %B section %A mismatches non-TLS reference in %B"), 1030218822Sdim tbfd, tsec, ntbfd, h->root.root.string); 1031218822Sdim else 1032218822Sdim (*_bfd_error_handler) 1033218822Sdim (_("%s: TLS reference in %B mismatches non-TLS definition in %B section %A"), 1034218822Sdim tbfd, ntbfd, ntsec, h->root.root.string); 1035130561Sobrien 1036218822Sdim bfd_set_error (bfd_error_bad_value); 1037218822Sdim return FALSE; 1038218822Sdim } 1039218822Sdim 1040130561Sobrien /* We need to remember if a symbol has a definition in a dynamic 1041130561Sobrien object or is weak in all dynamic objects. Internal and hidden 1042130561Sobrien visibility will make it unavailable to dynamic objects. */ 1043218822Sdim if (newdyn && !h->dynamic_def) 1044130561Sobrien { 1045130561Sobrien if (!bfd_is_und_section (sec)) 1046218822Sdim h->dynamic_def = 1; 1047130561Sobrien else 1048130561Sobrien { 1049130561Sobrien /* Check if this symbol is weak in all dynamic objects. If it 1050130561Sobrien is the first time we see it in a dynamic object, we mark 1051130561Sobrien if it is weak. Otherwise, we clear it. */ 1052218822Sdim if (!h->ref_dynamic) 1053130561Sobrien { 1054130561Sobrien if (bind == STB_WEAK) 1055218822Sdim h->dynamic_weak = 1; 1056130561Sobrien } 1057130561Sobrien else if (bind != STB_WEAK) 1058218822Sdim h->dynamic_weak = 0; 1059130561Sobrien } 1060130561Sobrien } 1061130561Sobrien 1062130561Sobrien /* If the old symbol has non-default visibility, we ignore the new 1063130561Sobrien definition from a dynamic object. */ 1064130561Sobrien if (newdyn 1065130561Sobrien && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT 1066130561Sobrien && !bfd_is_und_section (sec)) 1067130561Sobrien { 1068130561Sobrien *skip = TRUE; 1069130561Sobrien /* Make sure this symbol is dynamic. */ 1070218822Sdim h->ref_dynamic = 1; 1071130561Sobrien /* A protected symbol has external availability. Make sure it is 1072130561Sobrien recorded as dynamic. 1073130561Sobrien 1074130561Sobrien FIXME: Should we check type and size for protected symbol? */ 1075130561Sobrien if (ELF_ST_VISIBILITY (h->other) == STV_PROTECTED) 1076130561Sobrien return bfd_elf_link_record_dynamic_symbol (info, h); 1077130561Sobrien else 1078130561Sobrien return TRUE; 1079130561Sobrien } 1080130561Sobrien else if (!newdyn 1081130561Sobrien && ELF_ST_VISIBILITY (sym->st_other) != STV_DEFAULT 1082218822Sdim && h->def_dynamic) 1083130561Sobrien { 1084130561Sobrien /* If the new symbol with non-default visibility comes from a 1085130561Sobrien relocatable file and the old definition comes from a dynamic 1086130561Sobrien object, we remove the old definition. */ 1087130561Sobrien if ((*sym_hash)->root.type == bfd_link_hash_indirect) 1088218822Sdim { 1089218822Sdim /* Handle the case where the old dynamic definition is 1090218822Sdim default versioned. We need to copy the symbol info from 1091218822Sdim the symbol with default version to the normal one if it 1092218822Sdim was referenced before. */ 1093218822Sdim if (h->ref_regular) 1094218822Sdim { 1095218822Sdim const struct elf_backend_data *bed 1096218822Sdim = get_elf_backend_data (abfd); 1097218822Sdim struct elf_link_hash_entry *vh = *sym_hash; 1098218822Sdim vh->root.type = h->root.type; 1099218822Sdim h->root.type = bfd_link_hash_indirect; 1100218822Sdim (*bed->elf_backend_copy_indirect_symbol) (info, vh, h); 1101218822Sdim /* Protected symbols will override the dynamic definition 1102218822Sdim with default version. */ 1103218822Sdim if (ELF_ST_VISIBILITY (sym->st_other) == STV_PROTECTED) 1104218822Sdim { 1105218822Sdim h->root.u.i.link = (struct bfd_link_hash_entry *) vh; 1106218822Sdim vh->dynamic_def = 1; 1107218822Sdim vh->ref_dynamic = 1; 1108218822Sdim } 1109218822Sdim else 1110218822Sdim { 1111218822Sdim h->root.type = vh->root.type; 1112218822Sdim vh->ref_dynamic = 0; 1113218822Sdim /* We have to hide it here since it was made dynamic 1114218822Sdim global with extra bits when the symbol info was 1115218822Sdim copied from the old dynamic definition. */ 1116218822Sdim (*bed->elf_backend_hide_symbol) (info, vh, TRUE); 1117218822Sdim } 1118218822Sdim h = vh; 1119218822Sdim } 1120218822Sdim else 1121218822Sdim h = *sym_hash; 1122218822Sdim } 1123130561Sobrien 1124218822Sdim if ((h->root.u.undef.next || info->hash->undefs_tail == &h->root) 1125130561Sobrien && bfd_is_und_section (sec)) 1126130561Sobrien { 1127130561Sobrien /* If the new symbol is undefined and the old symbol was 1128130561Sobrien also undefined before, we need to make sure 1129130561Sobrien _bfd_generic_link_add_one_symbol doesn't mess 1130218822Sdim up the linker hash table undefs list. Since the old 1131130561Sobrien definition came from a dynamic object, it is still on the 1132130561Sobrien undefs list. */ 1133130561Sobrien h->root.type = bfd_link_hash_undefined; 1134130561Sobrien h->root.u.undef.abfd = abfd; 1135130561Sobrien } 1136130561Sobrien else 1137130561Sobrien { 1138130561Sobrien h->root.type = bfd_link_hash_new; 1139130561Sobrien h->root.u.undef.abfd = NULL; 1140130561Sobrien } 1141130561Sobrien 1142218822Sdim if (h->def_dynamic) 1143130561Sobrien { 1144218822Sdim h->def_dynamic = 0; 1145218822Sdim h->ref_dynamic = 1; 1146218822Sdim h->dynamic_def = 1; 1147130561Sobrien } 1148130561Sobrien /* FIXME: Should we check type and size for protected symbol? */ 1149130561Sobrien h->size = 0; 1150130561Sobrien h->type = 0; 1151130561Sobrien return TRUE; 1152130561Sobrien } 1153130561Sobrien 1154130561Sobrien /* Differentiate strong and weak symbols. */ 1155130561Sobrien newweak = bind == STB_WEAK; 1156130561Sobrien oldweak = (h->root.type == bfd_link_hash_defweak 1157130561Sobrien || h->root.type == bfd_link_hash_undefweak); 1158130561Sobrien 1159130561Sobrien /* If a new weak symbol definition comes from a regular file and the 1160130561Sobrien old symbol comes from a dynamic library, we treat the new one as 1161130561Sobrien strong. Similarly, an old weak symbol definition from a regular 1162130561Sobrien file is treated as strong when the new symbol comes from a dynamic 1163130561Sobrien library. Further, an old weak symbol from a dynamic library is 1164130561Sobrien treated as strong if the new symbol is from a dynamic library. 1165130561Sobrien This reflects the way glibc's ld.so works. 1166130561Sobrien 1167130561Sobrien Do this before setting *type_change_ok or *size_change_ok so that 1168130561Sobrien we warn properly when dynamic library symbols are overridden. */ 1169130561Sobrien 1170130561Sobrien if (newdef && !newdyn && olddyn) 1171130561Sobrien newweak = FALSE; 1172130561Sobrien if (olddef && newdyn) 1173130561Sobrien oldweak = FALSE; 1174130561Sobrien 1175218822Sdim /* Allow changes between different types of funciton symbol. */ 1176218822Sdim if (bed->is_function_type (ELF_ST_TYPE (sym->st_info)) 1177218822Sdim && bed->is_function_type (h->type)) 1178218822Sdim *type_change_ok = TRUE; 1179218822Sdim 1180130561Sobrien /* It's OK to change the type if either the existing symbol or the 1181130561Sobrien new symbol is weak. A type change is also OK if the old symbol 1182130561Sobrien is undefined and the new symbol is defined. */ 1183130561Sobrien 1184130561Sobrien if (oldweak 1185130561Sobrien || newweak 1186130561Sobrien || (newdef 1187130561Sobrien && h->root.type == bfd_link_hash_undefined)) 1188130561Sobrien *type_change_ok = TRUE; 1189130561Sobrien 1190130561Sobrien /* It's OK to change the size if either the existing symbol or the 1191130561Sobrien new symbol is weak, or if the old symbol is undefined. */ 1192130561Sobrien 1193130561Sobrien if (*type_change_ok 1194130561Sobrien || h->root.type == bfd_link_hash_undefined) 1195130561Sobrien *size_change_ok = TRUE; 1196130561Sobrien 1197130561Sobrien /* NEWDYNCOMMON and OLDDYNCOMMON indicate whether the new or old 1198130561Sobrien symbol, respectively, appears to be a common symbol in a dynamic 1199130561Sobrien object. If a symbol appears in an uninitialized section, and is 1200130561Sobrien not weak, and is not a function, then it may be a common symbol 1201130561Sobrien which was resolved when the dynamic object was created. We want 1202130561Sobrien to treat such symbols specially, because they raise special 1203130561Sobrien considerations when setting the symbol size: if the symbol 1204130561Sobrien appears as a common symbol in a regular object, and the size in 1205130561Sobrien the regular object is larger, we must make sure that we use the 1206130561Sobrien larger size. This problematic case can always be avoided in C, 1207130561Sobrien but it must be handled correctly when using Fortran shared 1208130561Sobrien libraries. 1209130561Sobrien 1210130561Sobrien Note that if NEWDYNCOMMON is set, NEWDEF will be set, and 1211130561Sobrien likewise for OLDDYNCOMMON and OLDDEF. 1212130561Sobrien 1213130561Sobrien Note that this test is just a heuristic, and that it is quite 1214130561Sobrien possible to have an uninitialized symbol in a shared object which 1215130561Sobrien is really a definition, rather than a common symbol. This could 1216130561Sobrien lead to some minor confusion when the symbol really is a common 1217130561Sobrien symbol in some regular object. However, I think it will be 1218130561Sobrien harmless. */ 1219130561Sobrien 1220130561Sobrien if (newdyn 1221130561Sobrien && newdef 1222130561Sobrien && !newweak 1223130561Sobrien && (sec->flags & SEC_ALLOC) != 0 1224130561Sobrien && (sec->flags & SEC_LOAD) == 0 1225130561Sobrien && sym->st_size > 0 1226218822Sdim && !bed->is_function_type (ELF_ST_TYPE (sym->st_info))) 1227130561Sobrien newdyncommon = TRUE; 1228130561Sobrien else 1229130561Sobrien newdyncommon = FALSE; 1230130561Sobrien 1231130561Sobrien if (olddyn 1232130561Sobrien && olddef 1233130561Sobrien && h->root.type == bfd_link_hash_defined 1234218822Sdim && h->def_dynamic 1235130561Sobrien && (h->root.u.def.section->flags & SEC_ALLOC) != 0 1236130561Sobrien && (h->root.u.def.section->flags & SEC_LOAD) == 0 1237130561Sobrien && h->size > 0 1238218822Sdim && !bed->is_function_type (h->type)) 1239130561Sobrien olddyncommon = TRUE; 1240130561Sobrien else 1241130561Sobrien olddyncommon = FALSE; 1242130561Sobrien 1243218822Sdim /* We now know everything about the old and new symbols. We ask the 1244218822Sdim backend to check if we can merge them. */ 1245218822Sdim if (bed->merge_symbol 1246218822Sdim && !bed->merge_symbol (info, sym_hash, h, sym, psec, pvalue, 1247218822Sdim pold_alignment, skip, override, 1248218822Sdim type_change_ok, size_change_ok, 1249218822Sdim &newdyn, &newdef, &newdyncommon, &newweak, 1250218822Sdim abfd, &sec, 1251218822Sdim &olddyn, &olddef, &olddyncommon, &oldweak, 1252218822Sdim oldbfd, &oldsec)) 1253218822Sdim return FALSE; 1254218822Sdim 1255130561Sobrien /* If both the old and the new symbols look like common symbols in a 1256130561Sobrien dynamic object, set the size of the symbol to the larger of the 1257130561Sobrien two. */ 1258130561Sobrien 1259130561Sobrien if (olddyncommon 1260130561Sobrien && newdyncommon 1261130561Sobrien && sym->st_size != h->size) 1262130561Sobrien { 1263130561Sobrien /* Since we think we have two common symbols, issue a multiple 1264130561Sobrien common warning if desired. Note that we only warn if the 1265130561Sobrien size is different. If the size is the same, we simply let 1266130561Sobrien the old symbol override the new one as normally happens with 1267130561Sobrien symbols defined in dynamic objects. */ 1268130561Sobrien 1269130561Sobrien if (! ((*info->callbacks->multiple_common) 1270130561Sobrien (info, h->root.root.string, oldbfd, bfd_link_hash_common, 1271130561Sobrien h->size, abfd, bfd_link_hash_common, sym->st_size))) 1272130561Sobrien return FALSE; 1273130561Sobrien 1274130561Sobrien if (sym->st_size > h->size) 1275130561Sobrien h->size = sym->st_size; 1276130561Sobrien 1277130561Sobrien *size_change_ok = TRUE; 1278130561Sobrien } 1279130561Sobrien 1280130561Sobrien /* If we are looking at a dynamic object, and we have found a 1281130561Sobrien definition, we need to see if the symbol was already defined by 1282130561Sobrien some other object. If so, we want to use the existing 1283130561Sobrien definition, and we do not want to report a multiple symbol 1284130561Sobrien definition error; we do this by clobbering *PSEC to be 1285130561Sobrien bfd_und_section_ptr. 1286130561Sobrien 1287130561Sobrien We treat a common symbol as a definition if the symbol in the 1288130561Sobrien shared library is a function, since common symbols always 1289130561Sobrien represent variables; this can cause confusion in principle, but 1290130561Sobrien any such confusion would seem to indicate an erroneous program or 1291130561Sobrien shared library. We also permit a common symbol in a regular 1292130561Sobrien object to override a weak symbol in a shared object. */ 1293130561Sobrien 1294130561Sobrien if (newdyn 1295130561Sobrien && newdef 1296130561Sobrien && (olddef 1297130561Sobrien || (h->root.type == bfd_link_hash_common 1298130561Sobrien && (newweak 1299218822Sdim || bed->is_function_type (ELF_ST_TYPE (sym->st_info)))))) 1300130561Sobrien { 1301130561Sobrien *override = TRUE; 1302130561Sobrien newdef = FALSE; 1303130561Sobrien newdyncommon = FALSE; 1304130561Sobrien 1305130561Sobrien *psec = sec = bfd_und_section_ptr; 1306130561Sobrien *size_change_ok = TRUE; 1307130561Sobrien 1308130561Sobrien /* If we get here when the old symbol is a common symbol, then 1309130561Sobrien we are explicitly letting it override a weak symbol or 1310130561Sobrien function in a dynamic object, and we don't want to warn about 1311130561Sobrien a type change. If the old symbol is a defined symbol, a type 1312130561Sobrien change warning may still be appropriate. */ 1313130561Sobrien 1314130561Sobrien if (h->root.type == bfd_link_hash_common) 1315130561Sobrien *type_change_ok = TRUE; 1316130561Sobrien } 1317130561Sobrien 1318130561Sobrien /* Handle the special case of an old common symbol merging with a 1319130561Sobrien new symbol which looks like a common symbol in a shared object. 1320130561Sobrien We change *PSEC and *PVALUE to make the new symbol look like a 1321218822Sdim common symbol, and let _bfd_generic_link_add_one_symbol do the 1322218822Sdim right thing. */ 1323130561Sobrien 1324130561Sobrien if (newdyncommon 1325130561Sobrien && h->root.type == bfd_link_hash_common) 1326130561Sobrien { 1327130561Sobrien *override = TRUE; 1328130561Sobrien newdef = FALSE; 1329130561Sobrien newdyncommon = FALSE; 1330130561Sobrien *pvalue = sym->st_size; 1331218822Sdim *psec = sec = bed->common_section (oldsec); 1332130561Sobrien *size_change_ok = TRUE; 1333130561Sobrien } 1334130561Sobrien 1335218822Sdim /* Skip weak definitions of symbols that are already defined. */ 1336218822Sdim if (newdef && olddef && newweak) 1337218822Sdim *skip = TRUE; 1338218822Sdim 1339130561Sobrien /* If the old symbol is from a dynamic object, and the new symbol is 1340130561Sobrien a definition which is not from a dynamic object, then the new 1341130561Sobrien symbol overrides the old symbol. Symbols from regular files 1342130561Sobrien always take precedence over symbols from dynamic objects, even if 1343130561Sobrien they are defined after the dynamic object in the link. 1344130561Sobrien 1345130561Sobrien As above, we again permit a common symbol in a regular object to 1346130561Sobrien override a definition in a shared object if the shared object 1347130561Sobrien symbol is a function or is weak. */ 1348130561Sobrien 1349130561Sobrien flip = NULL; 1350218822Sdim if (!newdyn 1351130561Sobrien && (newdef 1352130561Sobrien || (bfd_is_com_section (sec) 1353130561Sobrien && (oldweak 1354218822Sdim || bed->is_function_type (h->type)))) 1355130561Sobrien && olddyn 1356130561Sobrien && olddef 1357218822Sdim && h->def_dynamic) 1358130561Sobrien { 1359130561Sobrien /* Change the hash table entry to undefined, and let 1360130561Sobrien _bfd_generic_link_add_one_symbol do the right thing with the 1361130561Sobrien new definition. */ 1362130561Sobrien 1363130561Sobrien h->root.type = bfd_link_hash_undefined; 1364130561Sobrien h->root.u.undef.abfd = h->root.u.def.section->owner; 1365130561Sobrien *size_change_ok = TRUE; 1366130561Sobrien 1367130561Sobrien olddef = FALSE; 1368130561Sobrien olddyncommon = FALSE; 1369130561Sobrien 1370130561Sobrien /* We again permit a type change when a common symbol may be 1371130561Sobrien overriding a function. */ 1372130561Sobrien 1373130561Sobrien if (bfd_is_com_section (sec)) 1374130561Sobrien *type_change_ok = TRUE; 1375130561Sobrien 1376130561Sobrien if ((*sym_hash)->root.type == bfd_link_hash_indirect) 1377130561Sobrien flip = *sym_hash; 1378130561Sobrien else 1379130561Sobrien /* This union may have been set to be non-NULL when this symbol 1380130561Sobrien was seen in a dynamic object. We must force the union to be 1381130561Sobrien NULL, so that it is correct for a regular symbol. */ 1382130561Sobrien h->verinfo.vertree = NULL; 1383130561Sobrien } 1384130561Sobrien 1385130561Sobrien /* Handle the special case of a new common symbol merging with an 1386130561Sobrien old symbol that looks like it might be a common symbol defined in 1387130561Sobrien a shared object. Note that we have already handled the case in 1388130561Sobrien which a new common symbol should simply override the definition 1389130561Sobrien in the shared library. */ 1390130561Sobrien 1391130561Sobrien if (! newdyn 1392130561Sobrien && bfd_is_com_section (sec) 1393130561Sobrien && olddyncommon) 1394130561Sobrien { 1395130561Sobrien /* It would be best if we could set the hash table entry to a 1396130561Sobrien common symbol, but we don't know what to use for the section 1397130561Sobrien or the alignment. */ 1398130561Sobrien if (! ((*info->callbacks->multiple_common) 1399130561Sobrien (info, h->root.root.string, oldbfd, bfd_link_hash_common, 1400130561Sobrien h->size, abfd, bfd_link_hash_common, sym->st_size))) 1401130561Sobrien return FALSE; 1402130561Sobrien 1403130561Sobrien /* If the presumed common symbol in the dynamic object is 1404130561Sobrien larger, pretend that the new symbol has its size. */ 1405130561Sobrien 1406130561Sobrien if (h->size > *pvalue) 1407130561Sobrien *pvalue = h->size; 1408130561Sobrien 1409218822Sdim /* We need to remember the alignment required by the symbol 1410218822Sdim in the dynamic object. */ 1411218822Sdim BFD_ASSERT (pold_alignment); 1412218822Sdim *pold_alignment = h->root.u.def.section->alignment_power; 1413130561Sobrien 1414130561Sobrien olddef = FALSE; 1415130561Sobrien olddyncommon = FALSE; 1416130561Sobrien 1417130561Sobrien h->root.type = bfd_link_hash_undefined; 1418130561Sobrien h->root.u.undef.abfd = h->root.u.def.section->owner; 1419130561Sobrien 1420130561Sobrien *size_change_ok = TRUE; 1421130561Sobrien *type_change_ok = TRUE; 1422130561Sobrien 1423130561Sobrien if ((*sym_hash)->root.type == bfd_link_hash_indirect) 1424130561Sobrien flip = *sym_hash; 1425130561Sobrien else 1426130561Sobrien h->verinfo.vertree = NULL; 1427130561Sobrien } 1428130561Sobrien 1429130561Sobrien if (flip != NULL) 1430130561Sobrien { 1431130561Sobrien /* Handle the case where we had a versioned symbol in a dynamic 1432130561Sobrien library and now find a definition in a normal object. In this 1433130561Sobrien case, we make the versioned symbol point to the normal one. */ 1434130561Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 1435130561Sobrien flip->root.type = h->root.type; 1436255931Sdim flip->root.u.undef.abfd = h->root.u.undef.abfd; 1437130561Sobrien h->root.type = bfd_link_hash_indirect; 1438130561Sobrien h->root.u.i.link = (struct bfd_link_hash_entry *) flip; 1439218822Sdim (*bed->elf_backend_copy_indirect_symbol) (info, flip, h); 1440218822Sdim if (h->def_dynamic) 1441130561Sobrien { 1442218822Sdim h->def_dynamic = 0; 1443218822Sdim flip->ref_dynamic = 1; 1444130561Sobrien } 1445130561Sobrien } 1446130561Sobrien 1447130561Sobrien return TRUE; 1448130561Sobrien} 1449130561Sobrien 1450130561Sobrien/* This function is called to create an indirect symbol from the 1451130561Sobrien default for the symbol with the default version if needed. The 1452130561Sobrien symbol is described by H, NAME, SYM, PSEC, VALUE, and OVERRIDE. We 1453130561Sobrien set DYNSYM if the new indirect symbol is dynamic. */ 1454130561Sobrien 1455130561Sobrienbfd_boolean 1456130561Sobrien_bfd_elf_add_default_symbol (bfd *abfd, 1457130561Sobrien struct bfd_link_info *info, 1458130561Sobrien struct elf_link_hash_entry *h, 1459130561Sobrien const char *name, 1460130561Sobrien Elf_Internal_Sym *sym, 1461130561Sobrien asection **psec, 1462130561Sobrien bfd_vma *value, 1463130561Sobrien bfd_boolean *dynsym, 1464130561Sobrien bfd_boolean override) 1465130561Sobrien{ 1466130561Sobrien bfd_boolean type_change_ok; 1467130561Sobrien bfd_boolean size_change_ok; 1468130561Sobrien bfd_boolean skip; 1469130561Sobrien char *shortname; 1470130561Sobrien struct elf_link_hash_entry *hi; 1471130561Sobrien struct bfd_link_hash_entry *bh; 1472130561Sobrien const struct elf_backend_data *bed; 1473130561Sobrien bfd_boolean collect; 1474130561Sobrien bfd_boolean dynamic; 1475130561Sobrien char *p; 1476130561Sobrien size_t len, shortlen; 1477130561Sobrien asection *sec; 1478130561Sobrien 1479130561Sobrien /* If this symbol has a version, and it is the default version, we 1480130561Sobrien create an indirect symbol from the default name to the fully 1481130561Sobrien decorated name. This will cause external references which do not 1482130561Sobrien specify a version to be bound to this version of the symbol. */ 1483130561Sobrien p = strchr (name, ELF_VER_CHR); 1484130561Sobrien if (p == NULL || p[1] != ELF_VER_CHR) 1485130561Sobrien return TRUE; 1486130561Sobrien 1487130561Sobrien if (override) 1488130561Sobrien { 1489130561Sobrien /* We are overridden by an old definition. We need to check if we 1490130561Sobrien need to create the indirect symbol from the default name. */ 1491130561Sobrien hi = elf_link_hash_lookup (elf_hash_table (info), name, TRUE, 1492130561Sobrien FALSE, FALSE); 1493130561Sobrien BFD_ASSERT (hi != NULL); 1494130561Sobrien if (hi == h) 1495130561Sobrien return TRUE; 1496130561Sobrien while (hi->root.type == bfd_link_hash_indirect 1497130561Sobrien || hi->root.type == bfd_link_hash_warning) 1498130561Sobrien { 1499130561Sobrien hi = (struct elf_link_hash_entry *) hi->root.u.i.link; 1500130561Sobrien if (hi == h) 1501130561Sobrien return TRUE; 1502130561Sobrien } 1503130561Sobrien } 1504130561Sobrien 1505130561Sobrien bed = get_elf_backend_data (abfd); 1506130561Sobrien collect = bed->collect; 1507130561Sobrien dynamic = (abfd->flags & DYNAMIC) != 0; 1508130561Sobrien 1509130561Sobrien shortlen = p - name; 1510130561Sobrien shortname = bfd_hash_allocate (&info->hash->table, shortlen + 1); 1511130561Sobrien if (shortname == NULL) 1512130561Sobrien return FALSE; 1513130561Sobrien memcpy (shortname, name, shortlen); 1514130561Sobrien shortname[shortlen] = '\0'; 1515130561Sobrien 1516130561Sobrien /* We are going to create a new symbol. Merge it with any existing 1517130561Sobrien symbol with this name. For the purposes of the merge, act as 1518130561Sobrien though we were defining the symbol we just defined, although we 1519130561Sobrien actually going to define an indirect symbol. */ 1520130561Sobrien type_change_ok = FALSE; 1521130561Sobrien size_change_ok = FALSE; 1522130561Sobrien sec = *psec; 1523130561Sobrien if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &sec, value, 1524218822Sdim NULL, &hi, &skip, &override, 1525218822Sdim &type_change_ok, &size_change_ok)) 1526130561Sobrien return FALSE; 1527130561Sobrien 1528130561Sobrien if (skip) 1529130561Sobrien goto nondefault; 1530130561Sobrien 1531130561Sobrien if (! override) 1532130561Sobrien { 1533130561Sobrien bh = &hi->root; 1534130561Sobrien if (! (_bfd_generic_link_add_one_symbol 1535130561Sobrien (info, abfd, shortname, BSF_INDIRECT, bfd_ind_section_ptr, 1536130561Sobrien 0, name, FALSE, collect, &bh))) 1537130561Sobrien return FALSE; 1538130561Sobrien hi = (struct elf_link_hash_entry *) bh; 1539130561Sobrien } 1540130561Sobrien else 1541130561Sobrien { 1542130561Sobrien /* In this case the symbol named SHORTNAME is overriding the 1543130561Sobrien indirect symbol we want to add. We were planning on making 1544130561Sobrien SHORTNAME an indirect symbol referring to NAME. SHORTNAME 1545130561Sobrien is the name without a version. NAME is the fully versioned 1546130561Sobrien name, and it is the default version. 1547130561Sobrien 1548130561Sobrien Overriding means that we already saw a definition for the 1549130561Sobrien symbol SHORTNAME in a regular object, and it is overriding 1550130561Sobrien the symbol defined in the dynamic object. 1551130561Sobrien 1552130561Sobrien When this happens, we actually want to change NAME, the 1553130561Sobrien symbol we just added, to refer to SHORTNAME. This will cause 1554130561Sobrien references to NAME in the shared object to become references 1555130561Sobrien to SHORTNAME in the regular object. This is what we expect 1556130561Sobrien when we override a function in a shared object: that the 1557130561Sobrien references in the shared object will be mapped to the 1558130561Sobrien definition in the regular object. */ 1559130561Sobrien 1560130561Sobrien while (hi->root.type == bfd_link_hash_indirect 1561130561Sobrien || hi->root.type == bfd_link_hash_warning) 1562130561Sobrien hi = (struct elf_link_hash_entry *) hi->root.u.i.link; 1563130561Sobrien 1564130561Sobrien h->root.type = bfd_link_hash_indirect; 1565130561Sobrien h->root.u.i.link = (struct bfd_link_hash_entry *) hi; 1566218822Sdim if (h->def_dynamic) 1567130561Sobrien { 1568218822Sdim h->def_dynamic = 0; 1569218822Sdim hi->ref_dynamic = 1; 1570218822Sdim if (hi->ref_regular 1571218822Sdim || hi->def_regular) 1572130561Sobrien { 1573130561Sobrien if (! bfd_elf_link_record_dynamic_symbol (info, hi)) 1574130561Sobrien return FALSE; 1575130561Sobrien } 1576130561Sobrien } 1577130561Sobrien 1578130561Sobrien /* Now set HI to H, so that the following code will set the 1579130561Sobrien other fields correctly. */ 1580130561Sobrien hi = h; 1581130561Sobrien } 1582130561Sobrien 1583218822Sdim /* Check if HI is a warning symbol. */ 1584218822Sdim if (hi->root.type == bfd_link_hash_warning) 1585218822Sdim hi = (struct elf_link_hash_entry *) hi->root.u.i.link; 1586218822Sdim 1587130561Sobrien /* If there is a duplicate definition somewhere, then HI may not 1588130561Sobrien point to an indirect symbol. We will have reported an error to 1589130561Sobrien the user in that case. */ 1590130561Sobrien 1591130561Sobrien if (hi->root.type == bfd_link_hash_indirect) 1592130561Sobrien { 1593130561Sobrien struct elf_link_hash_entry *ht; 1594130561Sobrien 1595130561Sobrien ht = (struct elf_link_hash_entry *) hi->root.u.i.link; 1596218822Sdim (*bed->elf_backend_copy_indirect_symbol) (info, ht, hi); 1597130561Sobrien 1598130561Sobrien /* See if the new flags lead us to realize that the symbol must 1599130561Sobrien be dynamic. */ 1600130561Sobrien if (! *dynsym) 1601130561Sobrien { 1602130561Sobrien if (! dynamic) 1603130561Sobrien { 1604130561Sobrien if (info->shared 1605218822Sdim || hi->ref_dynamic) 1606130561Sobrien *dynsym = TRUE; 1607130561Sobrien } 1608130561Sobrien else 1609130561Sobrien { 1610218822Sdim if (hi->ref_regular) 1611130561Sobrien *dynsym = TRUE; 1612130561Sobrien } 1613130561Sobrien } 1614130561Sobrien } 1615130561Sobrien 1616130561Sobrien /* We also need to define an indirection from the nondefault version 1617130561Sobrien of the symbol. */ 1618130561Sobrien 1619130561Sobriennondefault: 1620130561Sobrien len = strlen (name); 1621130561Sobrien shortname = bfd_hash_allocate (&info->hash->table, len); 1622130561Sobrien if (shortname == NULL) 1623130561Sobrien return FALSE; 1624130561Sobrien memcpy (shortname, name, shortlen); 1625130561Sobrien memcpy (shortname + shortlen, p + 1, len - shortlen); 1626130561Sobrien 1627130561Sobrien /* Once again, merge with any existing symbol. */ 1628130561Sobrien type_change_ok = FALSE; 1629130561Sobrien size_change_ok = FALSE; 1630130561Sobrien sec = *psec; 1631130561Sobrien if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &sec, value, 1632218822Sdim NULL, &hi, &skip, &override, 1633218822Sdim &type_change_ok, &size_change_ok)) 1634130561Sobrien return FALSE; 1635130561Sobrien 1636130561Sobrien if (skip) 1637130561Sobrien return TRUE; 1638130561Sobrien 1639130561Sobrien if (override) 1640130561Sobrien { 1641130561Sobrien /* Here SHORTNAME is a versioned name, so we don't expect to see 1642130561Sobrien the type of override we do in the case above unless it is 1643130561Sobrien overridden by a versioned definition. */ 1644130561Sobrien if (hi->root.type != bfd_link_hash_defined 1645130561Sobrien && hi->root.type != bfd_link_hash_defweak) 1646130561Sobrien (*_bfd_error_handler) 1647218822Sdim (_("%B: unexpected redefinition of indirect versioned symbol `%s'"), 1648218822Sdim abfd, shortname); 1649130561Sobrien } 1650130561Sobrien else 1651130561Sobrien { 1652130561Sobrien bh = &hi->root; 1653130561Sobrien if (! (_bfd_generic_link_add_one_symbol 1654130561Sobrien (info, abfd, shortname, BSF_INDIRECT, 1655130561Sobrien bfd_ind_section_ptr, 0, name, FALSE, collect, &bh))) 1656130561Sobrien return FALSE; 1657130561Sobrien hi = (struct elf_link_hash_entry *) bh; 1658130561Sobrien 1659130561Sobrien /* If there is a duplicate definition somewhere, then HI may not 1660130561Sobrien point to an indirect symbol. We will have reported an error 1661130561Sobrien to the user in that case. */ 1662130561Sobrien 1663130561Sobrien if (hi->root.type == bfd_link_hash_indirect) 1664130561Sobrien { 1665218822Sdim (*bed->elf_backend_copy_indirect_symbol) (info, h, hi); 1666130561Sobrien 1667130561Sobrien /* See if the new flags lead us to realize that the symbol 1668130561Sobrien must be dynamic. */ 1669130561Sobrien if (! *dynsym) 1670130561Sobrien { 1671130561Sobrien if (! dynamic) 1672130561Sobrien { 1673130561Sobrien if (info->shared 1674218822Sdim || hi->ref_dynamic) 1675130561Sobrien *dynsym = TRUE; 1676130561Sobrien } 1677130561Sobrien else 1678130561Sobrien { 1679218822Sdim if (hi->ref_regular) 1680130561Sobrien *dynsym = TRUE; 1681130561Sobrien } 1682130561Sobrien } 1683130561Sobrien } 1684130561Sobrien } 1685130561Sobrien 1686130561Sobrien return TRUE; 1687130561Sobrien} 168833965Sjdp 1689130561Sobrien/* This routine is used to export all defined symbols into the dynamic 1690130561Sobrien symbol table. It is called via elf_link_hash_traverse. */ 169133965Sjdp 1692130561Sobrienbfd_boolean 1693130561Sobrien_bfd_elf_export_symbol (struct elf_link_hash_entry *h, void *data) 169433965Sjdp{ 1695130561Sobrien struct elf_info_failed *eif = data; 169633965Sjdp 1697218822Sdim /* Ignore this if we won't export it. */ 1698218822Sdim if (!eif->info->export_dynamic && !h->dynamic) 1699218822Sdim return TRUE; 1700218822Sdim 1701130561Sobrien /* Ignore indirect symbols. These are added by the versioning code. */ 1702130561Sobrien if (h->root.type == bfd_link_hash_indirect) 1703130561Sobrien return TRUE; 170433965Sjdp 1705130561Sobrien if (h->root.type == bfd_link_hash_warning) 1706130561Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 1707130561Sobrien 1708130561Sobrien if (h->dynindx == -1 1709218822Sdim && (h->def_regular 1710218822Sdim || h->ref_regular)) 171133965Sjdp { 1712130561Sobrien struct bfd_elf_version_tree *t; 1713130561Sobrien struct bfd_elf_version_expr *d; 1714130561Sobrien 1715130561Sobrien for (t = eif->verdefs; t != NULL; t = t->next) 1716130561Sobrien { 1717130561Sobrien if (t->globals.list != NULL) 1718130561Sobrien { 1719130561Sobrien d = (*t->match) (&t->globals, NULL, h->root.root.string); 1720130561Sobrien if (d != NULL) 1721130561Sobrien goto doit; 1722130561Sobrien } 1723130561Sobrien 1724130561Sobrien if (t->locals.list != NULL) 1725130561Sobrien { 1726130561Sobrien d = (*t->match) (&t->locals, NULL, h->root.root.string); 1727130561Sobrien if (d != NULL) 1728130561Sobrien return TRUE; 1729130561Sobrien } 1730130561Sobrien } 1731130561Sobrien 1732130561Sobrien if (!eif->verdefs) 1733130561Sobrien { 1734130561Sobrien doit: 1735130561Sobrien if (! bfd_elf_link_record_dynamic_symbol (eif->info, h)) 1736130561Sobrien { 1737130561Sobrien eif->failed = TRUE; 1738130561Sobrien return FALSE; 1739130561Sobrien } 1740130561Sobrien } 1741130561Sobrien } 1742130561Sobrien 1743130561Sobrien return TRUE; 1744130561Sobrien} 1745130561Sobrien 1746130561Sobrien/* Look through the symbols which are defined in other shared 1747130561Sobrien libraries and referenced here. Update the list of version 1748130561Sobrien dependencies. This will be put into the .gnu.version_r section. 1749130561Sobrien This function is called via elf_link_hash_traverse. */ 1750130561Sobrien 1751130561Sobrienbfd_boolean 1752130561Sobrien_bfd_elf_link_find_version_dependencies (struct elf_link_hash_entry *h, 1753130561Sobrien void *data) 1754130561Sobrien{ 1755130561Sobrien struct elf_find_verdep_info *rinfo = data; 1756130561Sobrien Elf_Internal_Verneed *t; 1757130561Sobrien Elf_Internal_Vernaux *a; 1758130561Sobrien bfd_size_type amt; 1759130561Sobrien 1760130561Sobrien if (h->root.type == bfd_link_hash_warning) 1761130561Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 1762130561Sobrien 1763130561Sobrien /* We only care about symbols defined in shared objects with version 1764130561Sobrien information. */ 1765218822Sdim if (!h->def_dynamic 1766218822Sdim || h->def_regular 1767130561Sobrien || h->dynindx == -1 1768130561Sobrien || h->verinfo.verdef == NULL) 1769130561Sobrien return TRUE; 1770130561Sobrien 1771130561Sobrien /* See if we already know about this version. */ 1772130561Sobrien for (t = elf_tdata (rinfo->output_bfd)->verref; t != NULL; t = t->vn_nextref) 1773130561Sobrien { 1774130561Sobrien if (t->vn_bfd != h->verinfo.verdef->vd_bfd) 1775130561Sobrien continue; 1776130561Sobrien 1777130561Sobrien for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) 1778130561Sobrien if (a->vna_nodename == h->verinfo.verdef->vd_nodename) 1779130561Sobrien return TRUE; 1780130561Sobrien 1781130561Sobrien break; 1782130561Sobrien } 1783130561Sobrien 1784130561Sobrien /* This is a new version. Add it to tree we are building. */ 1785130561Sobrien 1786130561Sobrien if (t == NULL) 1787130561Sobrien { 1788130561Sobrien amt = sizeof *t; 1789130561Sobrien t = bfd_zalloc (rinfo->output_bfd, amt); 1790130561Sobrien if (t == NULL) 1791130561Sobrien { 1792130561Sobrien rinfo->failed = TRUE; 1793130561Sobrien return FALSE; 1794130561Sobrien } 1795130561Sobrien 1796130561Sobrien t->vn_bfd = h->verinfo.verdef->vd_bfd; 1797130561Sobrien t->vn_nextref = elf_tdata (rinfo->output_bfd)->verref; 1798130561Sobrien elf_tdata (rinfo->output_bfd)->verref = t; 1799130561Sobrien } 1800130561Sobrien 1801130561Sobrien amt = sizeof *a; 1802130561Sobrien a = bfd_zalloc (rinfo->output_bfd, amt); 1803130561Sobrien 1804130561Sobrien /* Note that we are copying a string pointer here, and testing it 1805130561Sobrien above. If bfd_elf_string_from_elf_section is ever changed to 1806130561Sobrien discard the string data when low in memory, this will have to be 1807130561Sobrien fixed. */ 1808130561Sobrien a->vna_nodename = h->verinfo.verdef->vd_nodename; 1809130561Sobrien 1810130561Sobrien a->vna_flags = h->verinfo.verdef->vd_flags; 1811130561Sobrien a->vna_nextptr = t->vn_auxptr; 1812130561Sobrien 1813130561Sobrien h->verinfo.verdef->vd_exp_refno = rinfo->vers; 1814130561Sobrien ++rinfo->vers; 1815130561Sobrien 1816130561Sobrien a->vna_other = h->verinfo.verdef->vd_exp_refno + 1; 1817130561Sobrien 1818130561Sobrien t->vn_auxptr = a; 1819130561Sobrien 1820130561Sobrien return TRUE; 1821130561Sobrien} 1822130561Sobrien 1823130561Sobrien/* Figure out appropriate versions for all the symbols. We may not 1824130561Sobrien have the version number script until we have read all of the input 1825130561Sobrien files, so until that point we don't know which symbols should be 1826130561Sobrien local. This function is called via elf_link_hash_traverse. */ 1827130561Sobrien 1828130561Sobrienbfd_boolean 1829130561Sobrien_bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data) 1830130561Sobrien{ 1831130561Sobrien struct elf_assign_sym_version_info *sinfo; 1832130561Sobrien struct bfd_link_info *info; 1833130561Sobrien const struct elf_backend_data *bed; 1834130561Sobrien struct elf_info_failed eif; 1835130561Sobrien char *p; 1836130561Sobrien bfd_size_type amt; 1837130561Sobrien 1838130561Sobrien sinfo = data; 1839130561Sobrien info = sinfo->info; 1840130561Sobrien 1841130561Sobrien if (h->root.type == bfd_link_hash_warning) 1842130561Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 1843130561Sobrien 1844130561Sobrien /* Fix the symbol flags. */ 1845130561Sobrien eif.failed = FALSE; 1846130561Sobrien eif.info = info; 1847130561Sobrien if (! _bfd_elf_fix_symbol_flags (h, &eif)) 1848130561Sobrien { 1849130561Sobrien if (eif.failed) 1850130561Sobrien sinfo->failed = TRUE; 1851130561Sobrien return FALSE; 1852130561Sobrien } 1853130561Sobrien 1854130561Sobrien /* We only need version numbers for symbols defined in regular 1855130561Sobrien objects. */ 1856218822Sdim if (!h->def_regular) 1857130561Sobrien return TRUE; 1858130561Sobrien 1859130561Sobrien bed = get_elf_backend_data (sinfo->output_bfd); 1860130561Sobrien p = strchr (h->root.root.string, ELF_VER_CHR); 1861130561Sobrien if (p != NULL && h->verinfo.vertree == NULL) 1862130561Sobrien { 1863130561Sobrien struct bfd_elf_version_tree *t; 1864130561Sobrien bfd_boolean hidden; 1865130561Sobrien 1866130561Sobrien hidden = TRUE; 1867130561Sobrien 1868130561Sobrien /* There are two consecutive ELF_VER_CHR characters if this is 1869130561Sobrien not a hidden symbol. */ 1870130561Sobrien ++p; 1871130561Sobrien if (*p == ELF_VER_CHR) 1872130561Sobrien { 1873130561Sobrien hidden = FALSE; 1874130561Sobrien ++p; 1875130561Sobrien } 1876130561Sobrien 1877130561Sobrien /* If there is no version string, we can just return out. */ 1878130561Sobrien if (*p == '\0') 1879130561Sobrien { 1880130561Sobrien if (hidden) 1881218822Sdim h->hidden = 1; 1882130561Sobrien return TRUE; 1883130561Sobrien } 1884130561Sobrien 1885130561Sobrien /* Look for the version. If we find it, it is no longer weak. */ 1886130561Sobrien for (t = sinfo->verdefs; t != NULL; t = t->next) 1887130561Sobrien { 1888130561Sobrien if (strcmp (t->name, p) == 0) 1889130561Sobrien { 1890130561Sobrien size_t len; 1891130561Sobrien char *alc; 1892130561Sobrien struct bfd_elf_version_expr *d; 1893130561Sobrien 1894130561Sobrien len = p - h->root.root.string; 1895130561Sobrien alc = bfd_malloc (len); 1896130561Sobrien if (alc == NULL) 1897130561Sobrien return FALSE; 1898130561Sobrien memcpy (alc, h->root.root.string, len - 1); 1899130561Sobrien alc[len - 1] = '\0'; 1900130561Sobrien if (alc[len - 2] == ELF_VER_CHR) 1901130561Sobrien alc[len - 2] = '\0'; 1902130561Sobrien 1903130561Sobrien h->verinfo.vertree = t; 1904130561Sobrien t->used = TRUE; 1905130561Sobrien d = NULL; 1906130561Sobrien 1907130561Sobrien if (t->globals.list != NULL) 1908130561Sobrien d = (*t->match) (&t->globals, NULL, alc); 1909130561Sobrien 1910130561Sobrien /* See if there is anything to force this symbol to 1911130561Sobrien local scope. */ 1912130561Sobrien if (d == NULL && t->locals.list != NULL) 1913130561Sobrien { 1914130561Sobrien d = (*t->match) (&t->locals, NULL, alc); 1915130561Sobrien if (d != NULL 1916130561Sobrien && h->dynindx != -1 1917130561Sobrien && ! info->export_dynamic) 1918130561Sobrien (*bed->elf_backend_hide_symbol) (info, h, TRUE); 1919130561Sobrien } 1920130561Sobrien 1921130561Sobrien free (alc); 1922130561Sobrien break; 1923130561Sobrien } 1924130561Sobrien } 1925130561Sobrien 1926130561Sobrien /* If we are building an application, we need to create a 1927130561Sobrien version node for this version. */ 1928130561Sobrien if (t == NULL && info->executable) 1929130561Sobrien { 1930130561Sobrien struct bfd_elf_version_tree **pp; 1931130561Sobrien int version_index; 1932130561Sobrien 1933130561Sobrien /* If we aren't going to export this symbol, we don't need 1934130561Sobrien to worry about it. */ 1935130561Sobrien if (h->dynindx == -1) 1936130561Sobrien return TRUE; 1937130561Sobrien 1938130561Sobrien amt = sizeof *t; 1939130561Sobrien t = bfd_zalloc (sinfo->output_bfd, amt); 1940130561Sobrien if (t == NULL) 1941130561Sobrien { 1942130561Sobrien sinfo->failed = TRUE; 1943130561Sobrien return FALSE; 1944130561Sobrien } 1945130561Sobrien 1946130561Sobrien t->name = p; 1947130561Sobrien t->name_indx = (unsigned int) -1; 1948130561Sobrien t->used = TRUE; 1949130561Sobrien 1950130561Sobrien version_index = 1; 1951130561Sobrien /* Don't count anonymous version tag. */ 1952130561Sobrien if (sinfo->verdefs != NULL && sinfo->verdefs->vernum == 0) 1953130561Sobrien version_index = 0; 1954130561Sobrien for (pp = &sinfo->verdefs; *pp != NULL; pp = &(*pp)->next) 1955130561Sobrien ++version_index; 1956130561Sobrien t->vernum = version_index; 1957130561Sobrien 1958130561Sobrien *pp = t; 1959130561Sobrien 1960130561Sobrien h->verinfo.vertree = t; 1961130561Sobrien } 1962130561Sobrien else if (t == NULL) 1963130561Sobrien { 1964130561Sobrien /* We could not find the version for a symbol when 1965130561Sobrien generating a shared archive. Return an error. */ 1966130561Sobrien (*_bfd_error_handler) 1967218822Sdim (_("%B: version node not found for symbol %s"), 1968218822Sdim sinfo->output_bfd, h->root.root.string); 1969130561Sobrien bfd_set_error (bfd_error_bad_value); 1970130561Sobrien sinfo->failed = TRUE; 1971130561Sobrien return FALSE; 1972130561Sobrien } 1973130561Sobrien 1974130561Sobrien if (hidden) 1975218822Sdim h->hidden = 1; 1976130561Sobrien } 1977130561Sobrien 1978130561Sobrien /* If we don't have a version for this symbol, see if we can find 1979130561Sobrien something. */ 1980130561Sobrien if (h->verinfo.vertree == NULL && sinfo->verdefs != NULL) 1981130561Sobrien { 1982130561Sobrien struct bfd_elf_version_tree *t; 1983130561Sobrien struct bfd_elf_version_tree *local_ver; 1984130561Sobrien struct bfd_elf_version_expr *d; 1985130561Sobrien 1986130561Sobrien /* See if can find what version this symbol is in. If the 1987130561Sobrien symbol is supposed to be local, then don't actually register 1988130561Sobrien it. */ 1989130561Sobrien local_ver = NULL; 1990130561Sobrien for (t = sinfo->verdefs; t != NULL; t = t->next) 1991130561Sobrien { 1992130561Sobrien if (t->globals.list != NULL) 1993130561Sobrien { 1994130561Sobrien bfd_boolean matched; 1995130561Sobrien 1996130561Sobrien matched = FALSE; 1997130561Sobrien d = NULL; 1998130561Sobrien while ((d = (*t->match) (&t->globals, d, 1999130561Sobrien h->root.root.string)) != NULL) 2000130561Sobrien if (d->symver) 2001130561Sobrien matched = TRUE; 2002130561Sobrien else 2003130561Sobrien { 2004130561Sobrien /* There is a version without definition. Make 2005130561Sobrien the symbol the default definition for this 2006130561Sobrien version. */ 2007130561Sobrien h->verinfo.vertree = t; 2008130561Sobrien local_ver = NULL; 2009130561Sobrien d->script = 1; 2010130561Sobrien break; 2011130561Sobrien } 2012130561Sobrien if (d != NULL) 2013130561Sobrien break; 2014130561Sobrien else if (matched) 2015130561Sobrien /* There is no undefined version for this symbol. Hide the 2016130561Sobrien default one. */ 2017130561Sobrien (*bed->elf_backend_hide_symbol) (info, h, TRUE); 2018130561Sobrien } 2019130561Sobrien 2020130561Sobrien if (t->locals.list != NULL) 2021130561Sobrien { 2022130561Sobrien d = NULL; 2023130561Sobrien while ((d = (*t->match) (&t->locals, d, 2024130561Sobrien h->root.root.string)) != NULL) 2025130561Sobrien { 2026130561Sobrien local_ver = t; 2027130561Sobrien /* If the match is "*", keep looking for a more 2028130561Sobrien explicit, perhaps even global, match. 2029130561Sobrien XXX: Shouldn't this be !d->wildcard instead? */ 2030130561Sobrien if (d->pattern[0] != '*' || d->pattern[1] != '\0') 2031130561Sobrien break; 2032130561Sobrien } 2033130561Sobrien 2034130561Sobrien if (d != NULL) 2035130561Sobrien break; 2036130561Sobrien } 2037130561Sobrien } 2038130561Sobrien 2039130561Sobrien if (local_ver != NULL) 2040130561Sobrien { 2041130561Sobrien h->verinfo.vertree = local_ver; 2042130561Sobrien if (h->dynindx != -1 2043130561Sobrien && ! info->export_dynamic) 2044130561Sobrien { 2045130561Sobrien (*bed->elf_backend_hide_symbol) (info, h, TRUE); 2046130561Sobrien } 2047130561Sobrien } 2048130561Sobrien } 2049130561Sobrien 2050130561Sobrien return TRUE; 2051130561Sobrien} 2052130561Sobrien 2053130561Sobrien/* Read and swap the relocs from the section indicated by SHDR. This 2054130561Sobrien may be either a REL or a RELA section. The relocations are 2055130561Sobrien translated into RELA relocations and stored in INTERNAL_RELOCS, 2056130561Sobrien which should have already been allocated to contain enough space. 2057130561Sobrien The EXTERNAL_RELOCS are a buffer where the external form of the 2058130561Sobrien relocations should be stored. 2059130561Sobrien 2060130561Sobrien Returns FALSE if something goes wrong. */ 2061130561Sobrien 2062130561Sobrienstatic bfd_boolean 2063130561Sobrienelf_link_read_relocs_from_section (bfd *abfd, 2064130561Sobrien asection *sec, 2065130561Sobrien Elf_Internal_Shdr *shdr, 2066130561Sobrien void *external_relocs, 2067130561Sobrien Elf_Internal_Rela *internal_relocs) 2068130561Sobrien{ 2069130561Sobrien const struct elf_backend_data *bed; 2070130561Sobrien void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *); 2071130561Sobrien const bfd_byte *erela; 2072130561Sobrien const bfd_byte *erelaend; 2073130561Sobrien Elf_Internal_Rela *irela; 2074130561Sobrien Elf_Internal_Shdr *symtab_hdr; 2075130561Sobrien size_t nsyms; 2076130561Sobrien 2077130561Sobrien /* Position ourselves at the start of the section. */ 2078130561Sobrien if (bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0) 2079130561Sobrien return FALSE; 2080130561Sobrien 2081130561Sobrien /* Read the relocations. */ 2082130561Sobrien if (bfd_bread (external_relocs, shdr->sh_size, abfd) != shdr->sh_size) 2083130561Sobrien return FALSE; 2084130561Sobrien 2085130561Sobrien symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 2086130561Sobrien nsyms = symtab_hdr->sh_size / symtab_hdr->sh_entsize; 2087130561Sobrien 2088130561Sobrien bed = get_elf_backend_data (abfd); 2089130561Sobrien 2090130561Sobrien /* Convert the external relocations to the internal format. */ 2091130561Sobrien if (shdr->sh_entsize == bed->s->sizeof_rel) 2092130561Sobrien swap_in = bed->s->swap_reloc_in; 2093130561Sobrien else if (shdr->sh_entsize == bed->s->sizeof_rela) 2094130561Sobrien swap_in = bed->s->swap_reloca_in; 2095130561Sobrien else 2096130561Sobrien { 2097130561Sobrien bfd_set_error (bfd_error_wrong_format); 2098130561Sobrien return FALSE; 2099130561Sobrien } 2100130561Sobrien 2101130561Sobrien erela = external_relocs; 2102130561Sobrien erelaend = erela + shdr->sh_size; 2103130561Sobrien irela = internal_relocs; 2104130561Sobrien while (erela < erelaend) 2105130561Sobrien { 2106130561Sobrien bfd_vma r_symndx; 2107130561Sobrien 2108130561Sobrien (*swap_in) (abfd, erela, irela); 2109130561Sobrien r_symndx = ELF32_R_SYM (irela->r_info); 2110130561Sobrien if (bed->s->arch_size == 64) 2111130561Sobrien r_symndx >>= 24; 2112130561Sobrien if ((size_t) r_symndx >= nsyms) 2113130561Sobrien { 2114130561Sobrien (*_bfd_error_handler) 2115218822Sdim (_("%B: bad reloc symbol index (0x%lx >= 0x%lx)" 2116218822Sdim " for offset 0x%lx in section `%A'"), 2117218822Sdim abfd, sec, 2118218822Sdim (unsigned long) r_symndx, (unsigned long) nsyms, irela->r_offset); 2119130561Sobrien bfd_set_error (bfd_error_bad_value); 2120130561Sobrien return FALSE; 2121130561Sobrien } 2122130561Sobrien irela += bed->s->int_rels_per_ext_rel; 2123130561Sobrien erela += shdr->sh_entsize; 2124130561Sobrien } 2125130561Sobrien 2126130561Sobrien return TRUE; 2127130561Sobrien} 2128130561Sobrien 2129130561Sobrien/* Read and swap the relocs for a section O. They may have been 2130130561Sobrien cached. If the EXTERNAL_RELOCS and INTERNAL_RELOCS arguments are 2131130561Sobrien not NULL, they are used as buffers to read into. They are known to 2132130561Sobrien be large enough. If the INTERNAL_RELOCS relocs argument is NULL, 2133130561Sobrien the return value is allocated using either malloc or bfd_alloc, 2134130561Sobrien according to the KEEP_MEMORY argument. If O has two relocation 2135130561Sobrien sections (both REL and RELA relocations), then the REL_HDR 2136130561Sobrien relocations will appear first in INTERNAL_RELOCS, followed by the 2137130561Sobrien REL_HDR2 relocations. */ 2138130561Sobrien 2139130561SobrienElf_Internal_Rela * 2140130561Sobrien_bfd_elf_link_read_relocs (bfd *abfd, 2141130561Sobrien asection *o, 2142130561Sobrien void *external_relocs, 2143130561Sobrien Elf_Internal_Rela *internal_relocs, 2144130561Sobrien bfd_boolean keep_memory) 2145130561Sobrien{ 2146130561Sobrien Elf_Internal_Shdr *rel_hdr; 2147130561Sobrien void *alloc1 = NULL; 2148130561Sobrien Elf_Internal_Rela *alloc2 = NULL; 2149130561Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 2150130561Sobrien 2151130561Sobrien if (elf_section_data (o)->relocs != NULL) 2152130561Sobrien return elf_section_data (o)->relocs; 2153130561Sobrien 2154130561Sobrien if (o->reloc_count == 0) 2155130561Sobrien return NULL; 2156130561Sobrien 2157130561Sobrien rel_hdr = &elf_section_data (o)->rel_hdr; 2158130561Sobrien 2159130561Sobrien if (internal_relocs == NULL) 2160130561Sobrien { 2161130561Sobrien bfd_size_type size; 2162130561Sobrien 2163130561Sobrien size = o->reloc_count; 2164130561Sobrien size *= bed->s->int_rels_per_ext_rel * sizeof (Elf_Internal_Rela); 2165130561Sobrien if (keep_memory) 2166130561Sobrien internal_relocs = bfd_alloc (abfd, size); 2167130561Sobrien else 2168130561Sobrien internal_relocs = alloc2 = bfd_malloc (size); 2169130561Sobrien if (internal_relocs == NULL) 2170130561Sobrien goto error_return; 2171130561Sobrien } 2172130561Sobrien 2173130561Sobrien if (external_relocs == NULL) 2174130561Sobrien { 2175130561Sobrien bfd_size_type size = rel_hdr->sh_size; 2176130561Sobrien 2177130561Sobrien if (elf_section_data (o)->rel_hdr2) 2178130561Sobrien size += elf_section_data (o)->rel_hdr2->sh_size; 2179130561Sobrien alloc1 = bfd_malloc (size); 2180130561Sobrien if (alloc1 == NULL) 2181130561Sobrien goto error_return; 2182130561Sobrien external_relocs = alloc1; 2183130561Sobrien } 2184130561Sobrien 2185130561Sobrien if (!elf_link_read_relocs_from_section (abfd, o, rel_hdr, 2186130561Sobrien external_relocs, 2187130561Sobrien internal_relocs)) 2188130561Sobrien goto error_return; 2189130561Sobrien if (elf_section_data (o)->rel_hdr2 2190130561Sobrien && (!elf_link_read_relocs_from_section 2191130561Sobrien (abfd, o, 2192130561Sobrien elf_section_data (o)->rel_hdr2, 2193130561Sobrien ((bfd_byte *) external_relocs) + rel_hdr->sh_size, 2194130561Sobrien internal_relocs + (NUM_SHDR_ENTRIES (rel_hdr) 2195130561Sobrien * bed->s->int_rels_per_ext_rel)))) 2196130561Sobrien goto error_return; 2197130561Sobrien 2198130561Sobrien /* Cache the results for next time, if we can. */ 2199130561Sobrien if (keep_memory) 2200130561Sobrien elf_section_data (o)->relocs = internal_relocs; 2201130561Sobrien 2202130561Sobrien if (alloc1 != NULL) 2203130561Sobrien free (alloc1); 2204130561Sobrien 2205130561Sobrien /* Don't free alloc2, since if it was allocated we are passing it 2206130561Sobrien back (under the name of internal_relocs). */ 2207130561Sobrien 2208130561Sobrien return internal_relocs; 2209130561Sobrien 2210130561Sobrien error_return: 2211130561Sobrien if (alloc1 != NULL) 2212130561Sobrien free (alloc1); 2213130561Sobrien if (alloc2 != NULL) 2214130561Sobrien free (alloc2); 2215130561Sobrien return NULL; 2216130561Sobrien} 2217130561Sobrien 2218130561Sobrien/* Compute the size of, and allocate space for, REL_HDR which is the 2219130561Sobrien section header for a section containing relocations for O. */ 2220130561Sobrien 2221130561Sobrienbfd_boolean 2222130561Sobrien_bfd_elf_link_size_reloc_section (bfd *abfd, 2223130561Sobrien Elf_Internal_Shdr *rel_hdr, 2224130561Sobrien asection *o) 2225130561Sobrien{ 2226130561Sobrien bfd_size_type reloc_count; 2227130561Sobrien bfd_size_type num_rel_hashes; 2228130561Sobrien 2229130561Sobrien /* Figure out how many relocations there will be. */ 2230130561Sobrien if (rel_hdr == &elf_section_data (o)->rel_hdr) 2231130561Sobrien reloc_count = elf_section_data (o)->rel_count; 2232130561Sobrien else 2233130561Sobrien reloc_count = elf_section_data (o)->rel_count2; 2234130561Sobrien 2235130561Sobrien num_rel_hashes = o->reloc_count; 2236130561Sobrien if (num_rel_hashes < reloc_count) 2237130561Sobrien num_rel_hashes = reloc_count; 2238130561Sobrien 2239130561Sobrien /* That allows us to calculate the size of the section. */ 2240130561Sobrien rel_hdr->sh_size = rel_hdr->sh_entsize * reloc_count; 2241130561Sobrien 2242130561Sobrien /* The contents field must last into write_object_contents, so we 2243130561Sobrien allocate it with bfd_alloc rather than malloc. Also since we 2244130561Sobrien cannot be sure that the contents will actually be filled in, 2245130561Sobrien we zero the allocated space. */ 2246130561Sobrien rel_hdr->contents = bfd_zalloc (abfd, rel_hdr->sh_size); 2247130561Sobrien if (rel_hdr->contents == NULL && rel_hdr->sh_size != 0) 2248130561Sobrien return FALSE; 2249130561Sobrien 2250130561Sobrien /* We only allocate one set of hash entries, so we only do it the 2251130561Sobrien first time we are called. */ 2252130561Sobrien if (elf_section_data (o)->rel_hashes == NULL 2253130561Sobrien && num_rel_hashes) 2254130561Sobrien { 2255130561Sobrien struct elf_link_hash_entry **p; 2256130561Sobrien 2257130561Sobrien p = bfd_zmalloc (num_rel_hashes * sizeof (struct elf_link_hash_entry *)); 2258130561Sobrien if (p == NULL) 2259130561Sobrien return FALSE; 2260130561Sobrien 2261130561Sobrien elf_section_data (o)->rel_hashes = p; 2262130561Sobrien } 2263130561Sobrien 2264130561Sobrien return TRUE; 2265130561Sobrien} 2266130561Sobrien 2267130561Sobrien/* Copy the relocations indicated by the INTERNAL_RELOCS (which 2268130561Sobrien originated from the section given by INPUT_REL_HDR) to the 2269130561Sobrien OUTPUT_BFD. */ 2270130561Sobrien 2271130561Sobrienbfd_boolean 2272130561Sobrien_bfd_elf_link_output_relocs (bfd *output_bfd, 2273130561Sobrien asection *input_section, 2274130561Sobrien Elf_Internal_Shdr *input_rel_hdr, 2275218822Sdim Elf_Internal_Rela *internal_relocs, 2276218822Sdim struct elf_link_hash_entry **rel_hash 2277218822Sdim ATTRIBUTE_UNUSED) 2278130561Sobrien{ 2279130561Sobrien Elf_Internal_Rela *irela; 2280130561Sobrien Elf_Internal_Rela *irelaend; 2281130561Sobrien bfd_byte *erel; 2282130561Sobrien Elf_Internal_Shdr *output_rel_hdr; 2283130561Sobrien asection *output_section; 2284130561Sobrien unsigned int *rel_countp = NULL; 2285130561Sobrien const struct elf_backend_data *bed; 2286130561Sobrien void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *); 2287130561Sobrien 2288130561Sobrien output_section = input_section->output_section; 2289130561Sobrien output_rel_hdr = NULL; 2290130561Sobrien 2291130561Sobrien if (elf_section_data (output_section)->rel_hdr.sh_entsize 2292130561Sobrien == input_rel_hdr->sh_entsize) 2293130561Sobrien { 2294130561Sobrien output_rel_hdr = &elf_section_data (output_section)->rel_hdr; 2295130561Sobrien rel_countp = &elf_section_data (output_section)->rel_count; 2296130561Sobrien } 2297130561Sobrien else if (elf_section_data (output_section)->rel_hdr2 2298130561Sobrien && (elf_section_data (output_section)->rel_hdr2->sh_entsize 2299130561Sobrien == input_rel_hdr->sh_entsize)) 2300130561Sobrien { 2301130561Sobrien output_rel_hdr = elf_section_data (output_section)->rel_hdr2; 2302130561Sobrien rel_countp = &elf_section_data (output_section)->rel_count2; 2303130561Sobrien } 2304130561Sobrien else 2305130561Sobrien { 2306130561Sobrien (*_bfd_error_handler) 2307218822Sdim (_("%B: relocation size mismatch in %B section %A"), 2308218822Sdim output_bfd, input_section->owner, input_section); 2309130561Sobrien bfd_set_error (bfd_error_wrong_object_format); 2310130561Sobrien return FALSE; 2311130561Sobrien } 2312130561Sobrien 2313130561Sobrien bed = get_elf_backend_data (output_bfd); 2314130561Sobrien if (input_rel_hdr->sh_entsize == bed->s->sizeof_rel) 2315130561Sobrien swap_out = bed->s->swap_reloc_out; 2316130561Sobrien else if (input_rel_hdr->sh_entsize == bed->s->sizeof_rela) 2317130561Sobrien swap_out = bed->s->swap_reloca_out; 2318130561Sobrien else 2319130561Sobrien abort (); 2320130561Sobrien 2321130561Sobrien erel = output_rel_hdr->contents; 2322130561Sobrien erel += *rel_countp * input_rel_hdr->sh_entsize; 2323130561Sobrien irela = internal_relocs; 2324130561Sobrien irelaend = irela + (NUM_SHDR_ENTRIES (input_rel_hdr) 2325130561Sobrien * bed->s->int_rels_per_ext_rel); 2326130561Sobrien while (irela < irelaend) 2327130561Sobrien { 2328130561Sobrien (*swap_out) (output_bfd, irela, erel); 2329130561Sobrien irela += bed->s->int_rels_per_ext_rel; 2330130561Sobrien erel += input_rel_hdr->sh_entsize; 2331130561Sobrien } 2332130561Sobrien 2333130561Sobrien /* Bump the counter, so that we know where to add the next set of 2334130561Sobrien relocations. */ 2335130561Sobrien *rel_countp += NUM_SHDR_ENTRIES (input_rel_hdr); 2336130561Sobrien 2337130561Sobrien return TRUE; 2338130561Sobrien} 2339130561Sobrien 2340218822Sdim/* Make weak undefined symbols in PIE dynamic. */ 2341218822Sdim 2342218822Sdimbfd_boolean 2343218822Sdim_bfd_elf_link_hash_fixup_symbol (struct bfd_link_info *info, 2344218822Sdim struct elf_link_hash_entry *h) 2345218822Sdim{ 2346218822Sdim if (info->pie 2347218822Sdim && h->dynindx == -1 2348218822Sdim && h->root.type == bfd_link_hash_undefweak) 2349218822Sdim return bfd_elf_link_record_dynamic_symbol (info, h); 2350218822Sdim 2351218822Sdim return TRUE; 2352218822Sdim} 2353218822Sdim 2354130561Sobrien/* Fix up the flags for a symbol. This handles various cases which 2355130561Sobrien can only be fixed after all the input files are seen. This is 2356130561Sobrien currently called by both adjust_dynamic_symbol and 2357130561Sobrien assign_sym_version, which is unnecessary but perhaps more robust in 2358130561Sobrien the face of future changes. */ 2359130561Sobrien 2360130561Sobrienbfd_boolean 2361130561Sobrien_bfd_elf_fix_symbol_flags (struct elf_link_hash_entry *h, 2362130561Sobrien struct elf_info_failed *eif) 2363130561Sobrien{ 2364218822Sdim const struct elf_backend_data *bed = NULL; 2365218822Sdim 2366130561Sobrien /* If this symbol was mentioned in a non-ELF file, try to set 2367130561Sobrien DEF_REGULAR and REF_REGULAR correctly. This is the only way to 2368130561Sobrien permit a non-ELF file to correctly refer to a symbol defined in 2369130561Sobrien an ELF dynamic object. */ 2370218822Sdim if (h->non_elf) 2371130561Sobrien { 2372130561Sobrien while (h->root.type == bfd_link_hash_indirect) 2373130561Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 2374130561Sobrien 2375130561Sobrien if (h->root.type != bfd_link_hash_defined 2376130561Sobrien && h->root.type != bfd_link_hash_defweak) 2377218822Sdim { 2378218822Sdim h->ref_regular = 1; 2379218822Sdim h->ref_regular_nonweak = 1; 2380218822Sdim } 2381130561Sobrien else 2382130561Sobrien { 2383130561Sobrien if (h->root.u.def.section->owner != NULL 2384130561Sobrien && (bfd_get_flavour (h->root.u.def.section->owner) 2385130561Sobrien == bfd_target_elf_flavour)) 2386218822Sdim { 2387218822Sdim h->ref_regular = 1; 2388218822Sdim h->ref_regular_nonweak = 1; 2389218822Sdim } 2390130561Sobrien else 2391218822Sdim h->def_regular = 1; 2392130561Sobrien } 2393130561Sobrien 2394130561Sobrien if (h->dynindx == -1 2395218822Sdim && (h->def_dynamic 2396218822Sdim || h->ref_dynamic)) 2397130561Sobrien { 2398130561Sobrien if (! bfd_elf_link_record_dynamic_symbol (eif->info, h)) 2399130561Sobrien { 2400130561Sobrien eif->failed = TRUE; 2401130561Sobrien return FALSE; 2402130561Sobrien } 2403130561Sobrien } 2404130561Sobrien } 2405130561Sobrien else 2406130561Sobrien { 2407218822Sdim /* Unfortunately, NON_ELF is only correct if the symbol 2408130561Sobrien was first seen in a non-ELF file. Fortunately, if the symbol 2409130561Sobrien was first seen in an ELF file, we're probably OK unless the 2410130561Sobrien symbol was defined in a non-ELF file. Catch that case here. 2411130561Sobrien FIXME: We're still in trouble if the symbol was first seen in 2412130561Sobrien a dynamic object, and then later in a non-ELF regular object. */ 2413130561Sobrien if ((h->root.type == bfd_link_hash_defined 2414130561Sobrien || h->root.type == bfd_link_hash_defweak) 2415218822Sdim && !h->def_regular 2416130561Sobrien && (h->root.u.def.section->owner != NULL 2417130561Sobrien ? (bfd_get_flavour (h->root.u.def.section->owner) 2418130561Sobrien != bfd_target_elf_flavour) 2419130561Sobrien : (bfd_is_abs_section (h->root.u.def.section) 2420218822Sdim && !h->def_dynamic))) 2421218822Sdim h->def_regular = 1; 2422130561Sobrien } 2423130561Sobrien 2424218822Sdim /* Backend specific symbol fixup. */ 2425218822Sdim if (elf_hash_table (eif->info)->dynobj) 2426218822Sdim { 2427218822Sdim bed = get_elf_backend_data (elf_hash_table (eif->info)->dynobj); 2428218822Sdim if (bed->elf_backend_fixup_symbol 2429218822Sdim && !(*bed->elf_backend_fixup_symbol) (eif->info, h)) 2430218822Sdim return FALSE; 2431218822Sdim } 2432218822Sdim 2433130561Sobrien /* If this is a final link, and the symbol was defined as a common 2434130561Sobrien symbol in a regular object file, and there was no definition in 2435130561Sobrien any dynamic object, then the linker will have allocated space for 2436218822Sdim the symbol in a common section but the DEF_REGULAR 2437130561Sobrien flag will not have been set. */ 2438130561Sobrien if (h->root.type == bfd_link_hash_defined 2439218822Sdim && !h->def_regular 2440218822Sdim && h->ref_regular 2441218822Sdim && !h->def_dynamic 2442130561Sobrien && (h->root.u.def.section->owner->flags & DYNAMIC) == 0) 2443218822Sdim h->def_regular = 1; 2444130561Sobrien 2445130561Sobrien /* If -Bsymbolic was used (which means to bind references to global 2446130561Sobrien symbols to the definition within the shared object), and this 2447130561Sobrien symbol was defined in a regular object, then it actually doesn't 2448130561Sobrien need a PLT entry. Likewise, if the symbol has non-default 2449130561Sobrien visibility. If the symbol has hidden or internal visibility, we 2450130561Sobrien will force it local. */ 2451218822Sdim if (h->needs_plt 2452130561Sobrien && eif->info->shared 2453130561Sobrien && is_elf_hash_table (eif->info->hash) 2454218822Sdim && (SYMBOLIC_BIND (eif->info, h) 2455130561Sobrien || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) 2456218822Sdim && h->def_regular) 2457130561Sobrien { 2458130561Sobrien bfd_boolean force_local; 2459130561Sobrien 2460130561Sobrien force_local = (ELF_ST_VISIBILITY (h->other) == STV_INTERNAL 2461130561Sobrien || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN); 2462130561Sobrien (*bed->elf_backend_hide_symbol) (eif->info, h, force_local); 2463130561Sobrien } 2464130561Sobrien 2465130561Sobrien /* If a weak undefined symbol has non-default visibility, we also 2466130561Sobrien hide it from the dynamic linker. */ 2467130561Sobrien if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT 2468130561Sobrien && h->root.type == bfd_link_hash_undefweak) 2469130561Sobrien { 2470130561Sobrien const struct elf_backend_data *bed; 2471130561Sobrien bed = get_elf_backend_data (elf_hash_table (eif->info)->dynobj); 2472130561Sobrien (*bed->elf_backend_hide_symbol) (eif->info, h, TRUE); 2473130561Sobrien } 2474130561Sobrien 2475130561Sobrien /* If this is a weak defined symbol in a dynamic object, and we know 2476130561Sobrien the real definition in the dynamic object, copy interesting flags 2477130561Sobrien over to the real definition. */ 2478218822Sdim if (h->u.weakdef != NULL) 2479130561Sobrien { 2480130561Sobrien struct elf_link_hash_entry *weakdef; 2481130561Sobrien 2482218822Sdim weakdef = h->u.weakdef; 2483130561Sobrien if (h->root.type == bfd_link_hash_indirect) 2484130561Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 2485130561Sobrien 2486130561Sobrien BFD_ASSERT (h->root.type == bfd_link_hash_defined 2487130561Sobrien || h->root.type == bfd_link_hash_defweak); 2488130561Sobrien BFD_ASSERT (weakdef->root.type == bfd_link_hash_defined 2489130561Sobrien || weakdef->root.type == bfd_link_hash_defweak); 2490218822Sdim BFD_ASSERT (weakdef->def_dynamic); 2491130561Sobrien 2492130561Sobrien /* If the real definition is defined by a regular object file, 2493130561Sobrien don't do anything special. See the longer description in 2494130561Sobrien _bfd_elf_adjust_dynamic_symbol, below. */ 2495218822Sdim if (weakdef->def_regular) 2496218822Sdim h->u.weakdef = NULL; 2497130561Sobrien else 2498218822Sdim (*bed->elf_backend_copy_indirect_symbol) (eif->info, weakdef, 2499218822Sdim h); 2500130561Sobrien } 2501130561Sobrien 2502130561Sobrien return TRUE; 2503130561Sobrien} 2504130561Sobrien 2505130561Sobrien/* Make the backend pick a good value for a dynamic symbol. This is 2506130561Sobrien called via elf_link_hash_traverse, and also calls itself 2507130561Sobrien recursively. */ 2508130561Sobrien 2509130561Sobrienbfd_boolean 2510130561Sobrien_bfd_elf_adjust_dynamic_symbol (struct elf_link_hash_entry *h, void *data) 2511130561Sobrien{ 2512130561Sobrien struct elf_info_failed *eif = data; 2513130561Sobrien bfd *dynobj; 2514130561Sobrien const struct elf_backend_data *bed; 2515130561Sobrien 2516130561Sobrien if (! is_elf_hash_table (eif->info->hash)) 2517130561Sobrien return FALSE; 2518130561Sobrien 2519130561Sobrien if (h->root.type == bfd_link_hash_warning) 2520130561Sobrien { 2521218822Sdim h->got = elf_hash_table (eif->info)->init_got_offset; 2522218822Sdim h->plt = elf_hash_table (eif->info)->init_plt_offset; 2523130561Sobrien 2524130561Sobrien /* When warning symbols are created, they **replace** the "real" 2525130561Sobrien entry in the hash table, thus we never get to see the real 2526130561Sobrien symbol in a hash traversal. So look at it now. */ 2527130561Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 2528130561Sobrien } 2529130561Sobrien 2530130561Sobrien /* Ignore indirect symbols. These are added by the versioning code. */ 2531130561Sobrien if (h->root.type == bfd_link_hash_indirect) 2532130561Sobrien return TRUE; 2533130561Sobrien 2534130561Sobrien /* Fix the symbol flags. */ 2535130561Sobrien if (! _bfd_elf_fix_symbol_flags (h, eif)) 2536130561Sobrien return FALSE; 2537130561Sobrien 2538130561Sobrien /* If this symbol does not require a PLT entry, and it is not 2539130561Sobrien defined by a dynamic object, or is not referenced by a regular 2540130561Sobrien object, ignore it. We do have to handle a weak defined symbol, 2541130561Sobrien even if no regular object refers to it, if we decided to add it 2542130561Sobrien to the dynamic symbol table. FIXME: Do we normally need to worry 2543130561Sobrien about symbols which are defined by one dynamic object and 2544130561Sobrien referenced by another one? */ 2545218822Sdim if (!h->needs_plt 2546218822Sdim && (h->def_regular 2547218822Sdim || !h->def_dynamic 2548218822Sdim || (!h->ref_regular 2549218822Sdim && (h->u.weakdef == NULL || h->u.weakdef->dynindx == -1)))) 2550130561Sobrien { 2551218822Sdim h->plt = elf_hash_table (eif->info)->init_plt_offset; 2552130561Sobrien return TRUE; 2553130561Sobrien } 2554130561Sobrien 2555130561Sobrien /* If we've already adjusted this symbol, don't do it again. This 2556130561Sobrien can happen via a recursive call. */ 2557218822Sdim if (h->dynamic_adjusted) 2558130561Sobrien return TRUE; 2559130561Sobrien 2560130561Sobrien /* Don't look at this symbol again. Note that we must set this 2561130561Sobrien after checking the above conditions, because we may look at a 2562130561Sobrien symbol once, decide not to do anything, and then get called 2563130561Sobrien recursively later after REF_REGULAR is set below. */ 2564218822Sdim h->dynamic_adjusted = 1; 2565130561Sobrien 2566130561Sobrien /* If this is a weak definition, and we know a real definition, and 2567130561Sobrien the real symbol is not itself defined by a regular object file, 2568130561Sobrien then get a good value for the real definition. We handle the 2569130561Sobrien real symbol first, for the convenience of the backend routine. 2570130561Sobrien 2571130561Sobrien Note that there is a confusing case here. If the real definition 2572130561Sobrien is defined by a regular object file, we don't get the real symbol 2573130561Sobrien from the dynamic object, but we do get the weak symbol. If the 2574130561Sobrien processor backend uses a COPY reloc, then if some routine in the 2575130561Sobrien dynamic object changes the real symbol, we will not see that 2576130561Sobrien change in the corresponding weak symbol. This is the way other 2577130561Sobrien ELF linkers work as well, and seems to be a result of the shared 2578130561Sobrien library model. 2579130561Sobrien 2580130561Sobrien I will clarify this issue. Most SVR4 shared libraries define the 2581130561Sobrien variable _timezone and define timezone as a weak synonym. The 2582130561Sobrien tzset call changes _timezone. If you write 2583130561Sobrien extern int timezone; 2584130561Sobrien int _timezone = 5; 2585130561Sobrien int main () { tzset (); printf ("%d %d\n", timezone, _timezone); } 2586130561Sobrien you might expect that, since timezone is a synonym for _timezone, 2587130561Sobrien the same number will print both times. However, if the processor 2588130561Sobrien backend uses a COPY reloc, then actually timezone will be copied 2589130561Sobrien into your process image, and, since you define _timezone 2590130561Sobrien yourself, _timezone will not. Thus timezone and _timezone will 2591130561Sobrien wind up at different memory locations. The tzset call will set 2592130561Sobrien _timezone, leaving timezone unchanged. */ 2593130561Sobrien 2594218822Sdim if (h->u.weakdef != NULL) 2595130561Sobrien { 2596130561Sobrien /* If we get to this point, we know there is an implicit 2597130561Sobrien reference by a regular object file via the weak symbol H. 2598130561Sobrien FIXME: Is this really true? What if the traversal finds 2599218822Sdim H->U.WEAKDEF before it finds H? */ 2600218822Sdim h->u.weakdef->ref_regular = 1; 2601130561Sobrien 2602218822Sdim if (! _bfd_elf_adjust_dynamic_symbol (h->u.weakdef, eif)) 2603130561Sobrien return FALSE; 2604130561Sobrien } 2605130561Sobrien 2606130561Sobrien /* If a symbol has no type and no size and does not require a PLT 2607130561Sobrien entry, then we are probably about to do the wrong thing here: we 2608130561Sobrien are probably going to create a COPY reloc for an empty object. 2609130561Sobrien This case can arise when a shared object is built with assembly 2610130561Sobrien code, and the assembly code fails to set the symbol type. */ 2611130561Sobrien if (h->size == 0 2612130561Sobrien && h->type == STT_NOTYPE 2613218822Sdim && !h->needs_plt) 2614130561Sobrien (*_bfd_error_handler) 2615130561Sobrien (_("warning: type and size of dynamic symbol `%s' are not defined"), 2616130561Sobrien h->root.root.string); 2617130561Sobrien 2618130561Sobrien dynobj = elf_hash_table (eif->info)->dynobj; 2619130561Sobrien bed = get_elf_backend_data (dynobj); 2620130561Sobrien if (! (*bed->elf_backend_adjust_dynamic_symbol) (eif->info, h)) 2621130561Sobrien { 2622130561Sobrien eif->failed = TRUE; 2623130561Sobrien return FALSE; 2624130561Sobrien } 2625130561Sobrien 2626130561Sobrien return TRUE; 2627130561Sobrien} 2628130561Sobrien 2629218822Sdim/* Adjust the dynamic symbol, H, for copy in the dynamic bss section, 2630218822Sdim DYNBSS. */ 2631218822Sdim 2632218822Sdimbfd_boolean 2633218822Sdim_bfd_elf_adjust_dynamic_copy (struct elf_link_hash_entry *h, 2634218822Sdim asection *dynbss) 2635218822Sdim{ 2636218822Sdim unsigned int power_of_two; 2637218822Sdim bfd_vma mask; 2638218822Sdim asection *sec = h->root.u.def.section; 2639218822Sdim 2640218822Sdim /* The section aligment of definition is the maximum alignment 2641218822Sdim requirement of symbols defined in the section. Since we don't 2642218822Sdim know the symbol alignment requirement, we start with the 2643218822Sdim maximum alignment and check low bits of the symbol address 2644218822Sdim for the minimum alignment. */ 2645218822Sdim power_of_two = bfd_get_section_alignment (sec->owner, sec); 2646218822Sdim mask = ((bfd_vma) 1 << power_of_two) - 1; 2647218822Sdim while ((h->root.u.def.value & mask) != 0) 2648218822Sdim { 2649218822Sdim mask >>= 1; 2650218822Sdim --power_of_two; 2651218822Sdim } 2652218822Sdim 2653218822Sdim if (power_of_two > bfd_get_section_alignment (dynbss->owner, 2654218822Sdim dynbss)) 2655218822Sdim { 2656218822Sdim /* Adjust the section alignment if needed. */ 2657218822Sdim if (! bfd_set_section_alignment (dynbss->owner, dynbss, 2658218822Sdim power_of_two)) 2659218822Sdim return FALSE; 2660218822Sdim } 2661218822Sdim 2662218822Sdim /* We make sure that the symbol will be aligned properly. */ 2663218822Sdim dynbss->size = BFD_ALIGN (dynbss->size, mask + 1); 2664218822Sdim 2665218822Sdim /* Define the symbol as being at this point in DYNBSS. */ 2666218822Sdim h->root.u.def.section = dynbss; 2667218822Sdim h->root.u.def.value = dynbss->size; 2668218822Sdim 2669218822Sdim /* Increment the size of DYNBSS to make room for the symbol. */ 2670218822Sdim dynbss->size += h->size; 2671218822Sdim 2672218822Sdim return TRUE; 2673218822Sdim} 2674218822Sdim 2675130561Sobrien/* Adjust all external symbols pointing into SEC_MERGE sections 2676130561Sobrien to reflect the object merging within the sections. */ 2677130561Sobrien 2678130561Sobrienbfd_boolean 2679130561Sobrien_bfd_elf_link_sec_merge_syms (struct elf_link_hash_entry *h, void *data) 2680130561Sobrien{ 2681130561Sobrien asection *sec; 2682130561Sobrien 2683130561Sobrien if (h->root.type == bfd_link_hash_warning) 2684130561Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 2685130561Sobrien 2686130561Sobrien if ((h->root.type == bfd_link_hash_defined 2687130561Sobrien || h->root.type == bfd_link_hash_defweak) 2688130561Sobrien && ((sec = h->root.u.def.section)->flags & SEC_MERGE) 2689130561Sobrien && sec->sec_info_type == ELF_INFO_TYPE_MERGE) 2690130561Sobrien { 2691130561Sobrien bfd *output_bfd = data; 2692130561Sobrien 2693130561Sobrien h->root.u.def.value = 2694130561Sobrien _bfd_merged_section_offset (output_bfd, 2695130561Sobrien &h->root.u.def.section, 2696130561Sobrien elf_section_data (sec)->sec_info, 2697218822Sdim h->root.u.def.value); 2698130561Sobrien } 2699130561Sobrien 2700130561Sobrien return TRUE; 2701130561Sobrien} 2702130561Sobrien 2703130561Sobrien/* Returns false if the symbol referred to by H should be considered 2704130561Sobrien to resolve local to the current module, and true if it should be 2705130561Sobrien considered to bind dynamically. */ 2706130561Sobrien 2707130561Sobrienbfd_boolean 2708130561Sobrien_bfd_elf_dynamic_symbol_p (struct elf_link_hash_entry *h, 2709130561Sobrien struct bfd_link_info *info, 2710130561Sobrien bfd_boolean ignore_protected) 2711130561Sobrien{ 2712130561Sobrien bfd_boolean binding_stays_local_p; 2713218822Sdim const struct elf_backend_data *bed; 2714218822Sdim struct elf_link_hash_table *hash_table; 2715130561Sobrien 2716130561Sobrien if (h == NULL) 2717130561Sobrien return FALSE; 2718130561Sobrien 2719130561Sobrien while (h->root.type == bfd_link_hash_indirect 2720130561Sobrien || h->root.type == bfd_link_hash_warning) 2721130561Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 2722130561Sobrien 2723130561Sobrien /* If it was forced local, then clearly it's not dynamic. */ 2724130561Sobrien if (h->dynindx == -1) 2725130561Sobrien return FALSE; 2726218822Sdim if (h->forced_local) 2727130561Sobrien return FALSE; 2728130561Sobrien 2729130561Sobrien /* Identify the cases where name binding rules say that a 2730130561Sobrien visible symbol resolves locally. */ 2731218822Sdim binding_stays_local_p = info->executable || SYMBOLIC_BIND (info, h); 2732130561Sobrien 2733130561Sobrien switch (ELF_ST_VISIBILITY (h->other)) 2734130561Sobrien { 2735130561Sobrien case STV_INTERNAL: 2736130561Sobrien case STV_HIDDEN: 2737130561Sobrien return FALSE; 2738130561Sobrien 2739130561Sobrien case STV_PROTECTED: 2740218822Sdim hash_table = elf_hash_table (info); 2741218822Sdim if (!is_elf_hash_table (hash_table)) 2742218822Sdim return FALSE; 2743218822Sdim 2744218822Sdim bed = get_elf_backend_data (hash_table->dynobj); 2745218822Sdim 2746130561Sobrien /* Proper resolution for function pointer equality may require 2747130561Sobrien that these symbols perhaps be resolved dynamically, even though 2748130561Sobrien we should be resolving them to the current module. */ 2749218822Sdim if (!ignore_protected || !bed->is_function_type (h->type)) 2750130561Sobrien binding_stays_local_p = TRUE; 2751130561Sobrien break; 2752130561Sobrien 2753130561Sobrien default: 2754130561Sobrien break; 2755130561Sobrien } 2756130561Sobrien 2757130561Sobrien /* If it isn't defined locally, then clearly it's dynamic. */ 2758218822Sdim if (!h->def_regular) 2759130561Sobrien return TRUE; 2760130561Sobrien 2761130561Sobrien /* Otherwise, the symbol is dynamic if binding rules don't tell 2762130561Sobrien us that it remains local. */ 2763130561Sobrien return !binding_stays_local_p; 2764130561Sobrien} 2765130561Sobrien 2766130561Sobrien/* Return true if the symbol referred to by H should be considered 2767130561Sobrien to resolve local to the current module, and false otherwise. Differs 2768130561Sobrien from (the inverse of) _bfd_elf_dynamic_symbol_p in the treatment of 2769130561Sobrien undefined symbols and weak symbols. */ 2770130561Sobrien 2771130561Sobrienbfd_boolean 2772130561Sobrien_bfd_elf_symbol_refs_local_p (struct elf_link_hash_entry *h, 2773130561Sobrien struct bfd_link_info *info, 2774130561Sobrien bfd_boolean local_protected) 2775130561Sobrien{ 2776218822Sdim const struct elf_backend_data *bed; 2777218822Sdim struct elf_link_hash_table *hash_table; 2778218822Sdim 2779130561Sobrien /* If it's a local sym, of course we resolve locally. */ 2780130561Sobrien if (h == NULL) 2781130561Sobrien return TRUE; 2782130561Sobrien 2783218822Sdim /* Common symbols that become definitions don't get the DEF_REGULAR 2784218822Sdim flag set, so test it first, and don't bail out. */ 2785218822Sdim if (ELF_COMMON_DEF_P (h)) 2786218822Sdim /* Do nothing. */; 2787130561Sobrien /* If we don't have a definition in a regular file, then we can't 2788130561Sobrien resolve locally. The sym is either undefined or dynamic. */ 2789218822Sdim else if (!h->def_regular) 2790130561Sobrien return FALSE; 2791130561Sobrien 2792130561Sobrien /* Forced local symbols resolve locally. */ 2793218822Sdim if (h->forced_local) 2794130561Sobrien return TRUE; 2795130561Sobrien 2796130561Sobrien /* As do non-dynamic symbols. */ 2797130561Sobrien if (h->dynindx == -1) 2798130561Sobrien return TRUE; 2799130561Sobrien 2800130561Sobrien /* At this point, we know the symbol is defined and dynamic. In an 2801130561Sobrien executable it must resolve locally, likewise when building symbolic 2802130561Sobrien shared libraries. */ 2803218822Sdim if (info->executable || SYMBOLIC_BIND (info, h)) 2804130561Sobrien return TRUE; 2805130561Sobrien 2806130561Sobrien /* Now deal with defined dynamic symbols in shared libraries. Ones 2807130561Sobrien with default visibility might not resolve locally. */ 2808130561Sobrien if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) 2809130561Sobrien return FALSE; 2810130561Sobrien 2811130561Sobrien /* However, STV_HIDDEN or STV_INTERNAL ones must be local. */ 2812130561Sobrien if (ELF_ST_VISIBILITY (h->other) != STV_PROTECTED) 2813130561Sobrien return TRUE; 2814130561Sobrien 2815218822Sdim hash_table = elf_hash_table (info); 2816218822Sdim if (!is_elf_hash_table (hash_table)) 2817218822Sdim return TRUE; 2818218822Sdim 2819218822Sdim bed = get_elf_backend_data (hash_table->dynobj); 2820218822Sdim 2821218822Sdim /* STV_PROTECTED non-function symbols are local. */ 2822218822Sdim if (!bed->is_function_type (h->type)) 2823218822Sdim return TRUE; 2824218822Sdim 2825130561Sobrien /* Function pointer equality tests may require that STV_PROTECTED 2826130561Sobrien symbols be treated as dynamic symbols, even when we know that the 2827130561Sobrien dynamic linker will resolve them locally. */ 2828130561Sobrien return local_protected; 2829130561Sobrien} 2830130561Sobrien 2831130561Sobrien/* Caches some TLS segment info, and ensures that the TLS segment vma is 2832130561Sobrien aligned. Returns the first TLS output section. */ 2833130561Sobrien 2834130561Sobrienstruct bfd_section * 2835130561Sobrien_bfd_elf_tls_setup (bfd *obfd, struct bfd_link_info *info) 2836130561Sobrien{ 2837130561Sobrien struct bfd_section *sec, *tls; 2838130561Sobrien unsigned int align = 0; 2839130561Sobrien 2840130561Sobrien for (sec = obfd->sections; sec != NULL; sec = sec->next) 2841130561Sobrien if ((sec->flags & SEC_THREAD_LOCAL) != 0) 2842130561Sobrien break; 2843130561Sobrien tls = sec; 2844130561Sobrien 2845130561Sobrien for (; sec != NULL && (sec->flags & SEC_THREAD_LOCAL) != 0; sec = sec->next) 2846130561Sobrien if (sec->alignment_power > align) 2847130561Sobrien align = sec->alignment_power; 2848130561Sobrien 2849130561Sobrien elf_hash_table (info)->tls_sec = tls; 2850130561Sobrien 2851130561Sobrien /* Ensure the alignment of the first section is the largest alignment, 2852130561Sobrien so that the tls segment starts aligned. */ 2853130561Sobrien if (tls != NULL) 2854130561Sobrien tls->alignment_power = align; 2855130561Sobrien 2856130561Sobrien return tls; 2857130561Sobrien} 2858130561Sobrien 2859130561Sobrien/* Return TRUE iff this is a non-common, definition of a non-function symbol. */ 2860130561Sobrienstatic bfd_boolean 2861130561Sobrienis_global_data_symbol_definition (bfd *abfd ATTRIBUTE_UNUSED, 2862130561Sobrien Elf_Internal_Sym *sym) 2863130561Sobrien{ 2864218822Sdim const struct elf_backend_data *bed; 2865218822Sdim 2866130561Sobrien /* Local symbols do not count, but target specific ones might. */ 2867130561Sobrien if (ELF_ST_BIND (sym->st_info) != STB_GLOBAL 2868130561Sobrien && ELF_ST_BIND (sym->st_info) < STB_LOOS) 2869130561Sobrien return FALSE; 2870130561Sobrien 2871218822Sdim bed = get_elf_backend_data (abfd); 2872130561Sobrien /* Function symbols do not count. */ 2873218822Sdim if (bed->is_function_type (ELF_ST_TYPE (sym->st_info))) 2874130561Sobrien return FALSE; 2875130561Sobrien 2876130561Sobrien /* If the section is undefined, then so is the symbol. */ 2877130561Sobrien if (sym->st_shndx == SHN_UNDEF) 2878130561Sobrien return FALSE; 2879130561Sobrien 2880130561Sobrien /* If the symbol is defined in the common section, then 2881130561Sobrien it is a common definition and so does not count. */ 2882218822Sdim if (bed->common_definition (sym)) 2883130561Sobrien return FALSE; 2884130561Sobrien 2885130561Sobrien /* If the symbol is in a target specific section then we 2886130561Sobrien must rely upon the backend to tell us what it is. */ 2887130561Sobrien if (sym->st_shndx >= SHN_LORESERVE && sym->st_shndx < SHN_ABS) 2888130561Sobrien /* FIXME - this function is not coded yet: 2889130561Sobrien 2890130561Sobrien return _bfd_is_global_symbol_definition (abfd, sym); 2891130561Sobrien 2892130561Sobrien Instead for now assume that the definition is not global, 2893130561Sobrien Even if this is wrong, at least the linker will behave 2894130561Sobrien in the same way that it used to do. */ 2895130561Sobrien return FALSE; 2896130561Sobrien 2897130561Sobrien return TRUE; 2898130561Sobrien} 2899130561Sobrien 2900130561Sobrien/* Search the symbol table of the archive element of the archive ABFD 2901130561Sobrien whose archive map contains a mention of SYMDEF, and determine if 2902130561Sobrien the symbol is defined in this element. */ 2903130561Sobrienstatic bfd_boolean 2904130561Sobrienelf_link_is_defined_archive_symbol (bfd * abfd, carsym * symdef) 2905130561Sobrien{ 2906130561Sobrien Elf_Internal_Shdr * hdr; 2907130561Sobrien bfd_size_type symcount; 2908130561Sobrien bfd_size_type extsymcount; 2909130561Sobrien bfd_size_type extsymoff; 2910130561Sobrien Elf_Internal_Sym *isymbuf; 2911130561Sobrien Elf_Internal_Sym *isym; 2912130561Sobrien Elf_Internal_Sym *isymend; 2913130561Sobrien bfd_boolean result; 2914130561Sobrien 2915130561Sobrien abfd = _bfd_get_elt_at_filepos (abfd, symdef->file_offset); 2916130561Sobrien if (abfd == NULL) 2917130561Sobrien return FALSE; 2918130561Sobrien 2919130561Sobrien if (! bfd_check_format (abfd, bfd_object)) 2920130561Sobrien return FALSE; 2921130561Sobrien 2922130561Sobrien /* If we have already included the element containing this symbol in the 2923130561Sobrien link then we do not need to include it again. Just claim that any symbol 2924130561Sobrien it contains is not a definition, so that our caller will not decide to 2925130561Sobrien (re)include this element. */ 2926130561Sobrien if (abfd->archive_pass) 2927130561Sobrien return FALSE; 2928130561Sobrien 2929130561Sobrien /* Select the appropriate symbol table. */ 2930130561Sobrien if ((abfd->flags & DYNAMIC) == 0 || elf_dynsymtab (abfd) == 0) 2931130561Sobrien hdr = &elf_tdata (abfd)->symtab_hdr; 2932130561Sobrien else 2933130561Sobrien hdr = &elf_tdata (abfd)->dynsymtab_hdr; 2934130561Sobrien 2935130561Sobrien symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym; 2936130561Sobrien 2937130561Sobrien /* The sh_info field of the symtab header tells us where the 2938130561Sobrien external symbols start. We don't care about the local symbols. */ 2939130561Sobrien if (elf_bad_symtab (abfd)) 2940130561Sobrien { 2941130561Sobrien extsymcount = symcount; 2942130561Sobrien extsymoff = 0; 2943130561Sobrien } 2944130561Sobrien else 2945130561Sobrien { 2946130561Sobrien extsymcount = symcount - hdr->sh_info; 2947130561Sobrien extsymoff = hdr->sh_info; 2948130561Sobrien } 2949130561Sobrien 2950130561Sobrien if (extsymcount == 0) 2951130561Sobrien return FALSE; 2952130561Sobrien 2953130561Sobrien /* Read in the symbol table. */ 2954130561Sobrien isymbuf = bfd_elf_get_elf_syms (abfd, hdr, extsymcount, extsymoff, 2955130561Sobrien NULL, NULL, NULL); 2956130561Sobrien if (isymbuf == NULL) 2957130561Sobrien return FALSE; 2958130561Sobrien 2959130561Sobrien /* Scan the symbol table looking for SYMDEF. */ 2960130561Sobrien result = FALSE; 2961130561Sobrien for (isym = isymbuf, isymend = isymbuf + extsymcount; isym < isymend; isym++) 2962130561Sobrien { 2963130561Sobrien const char *name; 2964130561Sobrien 2965130561Sobrien name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link, 2966130561Sobrien isym->st_name); 2967130561Sobrien if (name == NULL) 2968130561Sobrien break; 2969130561Sobrien 2970130561Sobrien if (strcmp (name, symdef->name) == 0) 2971130561Sobrien { 2972130561Sobrien result = is_global_data_symbol_definition (abfd, isym); 2973130561Sobrien break; 2974130561Sobrien } 2975130561Sobrien } 2976130561Sobrien 2977130561Sobrien free (isymbuf); 2978130561Sobrien 2979130561Sobrien return result; 2980130561Sobrien} 2981130561Sobrien 2982130561Sobrien/* Add an entry to the .dynamic table. */ 2983130561Sobrien 2984130561Sobrienbfd_boolean 2985130561Sobrien_bfd_elf_add_dynamic_entry (struct bfd_link_info *info, 2986130561Sobrien bfd_vma tag, 2987130561Sobrien bfd_vma val) 2988130561Sobrien{ 2989130561Sobrien struct elf_link_hash_table *hash_table; 2990130561Sobrien const struct elf_backend_data *bed; 2991130561Sobrien asection *s; 2992130561Sobrien bfd_size_type newsize; 2993130561Sobrien bfd_byte *newcontents; 2994130561Sobrien Elf_Internal_Dyn dyn; 2995130561Sobrien 2996130561Sobrien hash_table = elf_hash_table (info); 2997130561Sobrien if (! is_elf_hash_table (hash_table)) 2998130561Sobrien return FALSE; 2999130561Sobrien 3000130561Sobrien bed = get_elf_backend_data (hash_table->dynobj); 3001130561Sobrien s = bfd_get_section_by_name (hash_table->dynobj, ".dynamic"); 3002130561Sobrien BFD_ASSERT (s != NULL); 3003130561Sobrien 3004218822Sdim newsize = s->size + bed->s->sizeof_dyn; 3005130561Sobrien newcontents = bfd_realloc (s->contents, newsize); 3006130561Sobrien if (newcontents == NULL) 3007130561Sobrien return FALSE; 3008130561Sobrien 3009130561Sobrien dyn.d_tag = tag; 3010130561Sobrien dyn.d_un.d_val = val; 3011218822Sdim bed->s->swap_dyn_out (hash_table->dynobj, &dyn, newcontents + s->size); 3012130561Sobrien 3013218822Sdim s->size = newsize; 3014130561Sobrien s->contents = newcontents; 3015130561Sobrien 3016130561Sobrien return TRUE; 3017130561Sobrien} 3018130561Sobrien 3019130561Sobrien/* Add a DT_NEEDED entry for this dynamic object if DO_IT is true, 3020130561Sobrien otherwise just check whether one already exists. Returns -1 on error, 3021130561Sobrien 1 if a DT_NEEDED tag already exists, and 0 on success. */ 3022130561Sobrien 3023130561Sobrienstatic int 3024218822Sdimelf_add_dt_needed_tag (bfd *abfd, 3025218822Sdim struct bfd_link_info *info, 3026130561Sobrien const char *soname, 3027130561Sobrien bfd_boolean do_it) 3028130561Sobrien{ 3029130561Sobrien struct elf_link_hash_table *hash_table; 3030130561Sobrien bfd_size_type oldsize; 3031130561Sobrien bfd_size_type strindex; 3032130561Sobrien 3033218822Sdim if (!_bfd_elf_link_create_dynstrtab (abfd, info)) 3034218822Sdim return -1; 3035218822Sdim 3036130561Sobrien hash_table = elf_hash_table (info); 3037130561Sobrien oldsize = _bfd_elf_strtab_size (hash_table->dynstr); 3038130561Sobrien strindex = _bfd_elf_strtab_add (hash_table->dynstr, soname, FALSE); 3039130561Sobrien if (strindex == (bfd_size_type) -1) 3040130561Sobrien return -1; 3041130561Sobrien 3042130561Sobrien if (oldsize == _bfd_elf_strtab_size (hash_table->dynstr)) 3043130561Sobrien { 3044130561Sobrien asection *sdyn; 3045130561Sobrien const struct elf_backend_data *bed; 3046130561Sobrien bfd_byte *extdyn; 3047130561Sobrien 3048130561Sobrien bed = get_elf_backend_data (hash_table->dynobj); 3049130561Sobrien sdyn = bfd_get_section_by_name (hash_table->dynobj, ".dynamic"); 3050218822Sdim if (sdyn != NULL) 3051218822Sdim for (extdyn = sdyn->contents; 3052218822Sdim extdyn < sdyn->contents + sdyn->size; 3053218822Sdim extdyn += bed->s->sizeof_dyn) 3054218822Sdim { 3055218822Sdim Elf_Internal_Dyn dyn; 3056130561Sobrien 3057218822Sdim bed->s->swap_dyn_in (hash_table->dynobj, extdyn, &dyn); 3058218822Sdim if (dyn.d_tag == DT_NEEDED 3059218822Sdim && dyn.d_un.d_val == strindex) 3060218822Sdim { 3061218822Sdim _bfd_elf_strtab_delref (hash_table->dynstr, strindex); 3062218822Sdim return 1; 3063218822Sdim } 3064218822Sdim } 3065130561Sobrien } 3066130561Sobrien 3067130561Sobrien if (do_it) 3068130561Sobrien { 3069218822Sdim if (!_bfd_elf_link_create_dynamic_sections (hash_table->dynobj, info)) 3070218822Sdim return -1; 3071218822Sdim 3072130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_NEEDED, strindex)) 3073130561Sobrien return -1; 3074130561Sobrien } 3075130561Sobrien else 3076130561Sobrien /* We were just checking for existence of the tag. */ 3077130561Sobrien _bfd_elf_strtab_delref (hash_table->dynstr, strindex); 3078130561Sobrien 3079130561Sobrien return 0; 3080130561Sobrien} 3081130561Sobrien 3082130561Sobrien/* Sort symbol by value and section. */ 3083130561Sobrienstatic int 3084130561Sobrienelf_sort_symbol (const void *arg1, const void *arg2) 3085130561Sobrien{ 3086130561Sobrien const struct elf_link_hash_entry *h1; 3087130561Sobrien const struct elf_link_hash_entry *h2; 3088130561Sobrien bfd_signed_vma vdiff; 3089130561Sobrien 3090130561Sobrien h1 = *(const struct elf_link_hash_entry **) arg1; 3091130561Sobrien h2 = *(const struct elf_link_hash_entry **) arg2; 3092130561Sobrien vdiff = h1->root.u.def.value - h2->root.u.def.value; 3093130561Sobrien if (vdiff != 0) 3094130561Sobrien return vdiff > 0 ? 1 : -1; 3095130561Sobrien else 3096130561Sobrien { 3097218822Sdim long sdiff = h1->root.u.def.section->id - h2->root.u.def.section->id; 3098130561Sobrien if (sdiff != 0) 3099130561Sobrien return sdiff > 0 ? 1 : -1; 3100130561Sobrien } 3101130561Sobrien return 0; 3102130561Sobrien} 3103130561Sobrien 3104130561Sobrien/* This function is used to adjust offsets into .dynstr for 3105130561Sobrien dynamic symbols. This is called via elf_link_hash_traverse. */ 3106130561Sobrien 3107130561Sobrienstatic bfd_boolean 3108130561Sobrienelf_adjust_dynstr_offsets (struct elf_link_hash_entry *h, void *data) 3109130561Sobrien{ 3110130561Sobrien struct elf_strtab_hash *dynstr = data; 3111130561Sobrien 3112130561Sobrien if (h->root.type == bfd_link_hash_warning) 3113130561Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 3114130561Sobrien 3115130561Sobrien if (h->dynindx != -1) 3116130561Sobrien h->dynstr_index = _bfd_elf_strtab_offset (dynstr, h->dynstr_index); 3117130561Sobrien return TRUE; 3118130561Sobrien} 3119130561Sobrien 3120130561Sobrien/* Assign string offsets in .dynstr, update all structures referencing 3121130561Sobrien them. */ 3122130561Sobrien 3123130561Sobrienstatic bfd_boolean 3124130561Sobrienelf_finalize_dynstr (bfd *output_bfd, struct bfd_link_info *info) 3125130561Sobrien{ 3126130561Sobrien struct elf_link_hash_table *hash_table = elf_hash_table (info); 3127130561Sobrien struct elf_link_local_dynamic_entry *entry; 3128130561Sobrien struct elf_strtab_hash *dynstr = hash_table->dynstr; 3129130561Sobrien bfd *dynobj = hash_table->dynobj; 3130130561Sobrien asection *sdyn; 3131130561Sobrien bfd_size_type size; 3132130561Sobrien const struct elf_backend_data *bed; 3133130561Sobrien bfd_byte *extdyn; 3134130561Sobrien 3135130561Sobrien _bfd_elf_strtab_finalize (dynstr); 3136130561Sobrien size = _bfd_elf_strtab_size (dynstr); 3137130561Sobrien 3138130561Sobrien bed = get_elf_backend_data (dynobj); 3139130561Sobrien sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); 3140130561Sobrien BFD_ASSERT (sdyn != NULL); 3141130561Sobrien 3142130561Sobrien /* Update all .dynamic entries referencing .dynstr strings. */ 3143130561Sobrien for (extdyn = sdyn->contents; 3144218822Sdim extdyn < sdyn->contents + sdyn->size; 3145130561Sobrien extdyn += bed->s->sizeof_dyn) 3146130561Sobrien { 3147130561Sobrien Elf_Internal_Dyn dyn; 3148130561Sobrien 3149130561Sobrien bed->s->swap_dyn_in (dynobj, extdyn, &dyn); 3150130561Sobrien switch (dyn.d_tag) 3151130561Sobrien { 3152130561Sobrien case DT_STRSZ: 3153130561Sobrien dyn.d_un.d_val = size; 3154130561Sobrien break; 3155130561Sobrien case DT_NEEDED: 3156130561Sobrien case DT_SONAME: 3157130561Sobrien case DT_RPATH: 3158130561Sobrien case DT_RUNPATH: 3159130561Sobrien case DT_FILTER: 3160130561Sobrien case DT_AUXILIARY: 3161130561Sobrien dyn.d_un.d_val = _bfd_elf_strtab_offset (dynstr, dyn.d_un.d_val); 3162130561Sobrien break; 3163130561Sobrien default: 3164130561Sobrien continue; 3165130561Sobrien } 3166130561Sobrien bed->s->swap_dyn_out (dynobj, &dyn, extdyn); 3167130561Sobrien } 3168130561Sobrien 3169130561Sobrien /* Now update local dynamic symbols. */ 3170130561Sobrien for (entry = hash_table->dynlocal; entry ; entry = entry->next) 3171130561Sobrien entry->isym.st_name = _bfd_elf_strtab_offset (dynstr, 3172130561Sobrien entry->isym.st_name); 3173130561Sobrien 3174130561Sobrien /* And the rest of dynamic symbols. */ 3175130561Sobrien elf_link_hash_traverse (hash_table, elf_adjust_dynstr_offsets, dynstr); 3176130561Sobrien 3177130561Sobrien /* Adjust version definitions. */ 3178130561Sobrien if (elf_tdata (output_bfd)->cverdefs) 3179130561Sobrien { 318033965Sjdp asection *s; 3181130561Sobrien bfd_byte *p; 3182130561Sobrien bfd_size_type i; 3183130561Sobrien Elf_Internal_Verdef def; 3184130561Sobrien Elf_Internal_Verdaux defaux; 318533965Sjdp 3186130561Sobrien s = bfd_get_section_by_name (dynobj, ".gnu.version_d"); 3187130561Sobrien p = s->contents; 3188130561Sobrien do 3189130561Sobrien { 3190130561Sobrien _bfd_elf_swap_verdef_in (output_bfd, (Elf_External_Verdef *) p, 3191130561Sobrien &def); 3192130561Sobrien p += sizeof (Elf_External_Verdef); 3193218822Sdim if (def.vd_aux != sizeof (Elf_External_Verdef)) 3194218822Sdim continue; 3195130561Sobrien for (i = 0; i < def.vd_cnt; ++i) 3196130561Sobrien { 3197130561Sobrien _bfd_elf_swap_verdaux_in (output_bfd, 3198130561Sobrien (Elf_External_Verdaux *) p, &defaux); 3199130561Sobrien defaux.vda_name = _bfd_elf_strtab_offset (dynstr, 3200130561Sobrien defaux.vda_name); 3201130561Sobrien _bfd_elf_swap_verdaux_out (output_bfd, 3202130561Sobrien &defaux, (Elf_External_Verdaux *) p); 3203130561Sobrien p += sizeof (Elf_External_Verdaux); 3204130561Sobrien } 3205130561Sobrien } 3206130561Sobrien while (def.vd_next); 3207130561Sobrien } 320833965Sjdp 3209130561Sobrien /* Adjust version references. */ 3210130561Sobrien if (elf_tdata (output_bfd)->verref) 3211130561Sobrien { 3212130561Sobrien asection *s; 3213130561Sobrien bfd_byte *p; 3214130561Sobrien bfd_size_type i; 3215130561Sobrien Elf_Internal_Verneed need; 3216130561Sobrien Elf_Internal_Vernaux needaux; 321733965Sjdp 3218130561Sobrien s = bfd_get_section_by_name (dynobj, ".gnu.version_r"); 3219130561Sobrien p = s->contents; 3220130561Sobrien do 322133965Sjdp { 3222130561Sobrien _bfd_elf_swap_verneed_in (output_bfd, (Elf_External_Verneed *) p, 3223130561Sobrien &need); 3224130561Sobrien need.vn_file = _bfd_elf_strtab_offset (dynstr, need.vn_file); 3225130561Sobrien _bfd_elf_swap_verneed_out (output_bfd, &need, 3226130561Sobrien (Elf_External_Verneed *) p); 3227130561Sobrien p += sizeof (Elf_External_Verneed); 3228130561Sobrien for (i = 0; i < need.vn_cnt; ++i) 3229130561Sobrien { 3230130561Sobrien _bfd_elf_swap_vernaux_in (output_bfd, 3231130561Sobrien (Elf_External_Vernaux *) p, &needaux); 3232130561Sobrien needaux.vna_name = _bfd_elf_strtab_offset (dynstr, 3233130561Sobrien needaux.vna_name); 3234130561Sobrien _bfd_elf_swap_vernaux_out (output_bfd, 3235130561Sobrien &needaux, 3236130561Sobrien (Elf_External_Vernaux *) p); 3237130561Sobrien p += sizeof (Elf_External_Vernaux); 3238130561Sobrien } 3239130561Sobrien } 3240130561Sobrien while (need.vn_next); 3241130561Sobrien } 324233965Sjdp 3243130561Sobrien return TRUE; 3244130561Sobrien} 3245130561Sobrien 3246218822Sdim/* Return TRUE iff relocations for INPUT are compatible with OUTPUT. 3247218822Sdim The default is to only match when the INPUT and OUTPUT are exactly 3248218822Sdim the same target. */ 3249218822Sdim 3250218822Sdimbfd_boolean 3251218822Sdim_bfd_elf_default_relocs_compatible (const bfd_target *input, 3252218822Sdim const bfd_target *output) 3253218822Sdim{ 3254218822Sdim return input == output; 3255218822Sdim} 3256218822Sdim 3257218822Sdim/* Return TRUE iff relocations for INPUT are compatible with OUTPUT. 3258218822Sdim This version is used when different targets for the same architecture 3259218822Sdim are virtually identical. */ 3260218822Sdim 3261218822Sdimbfd_boolean 3262218822Sdim_bfd_elf_relocs_compatible (const bfd_target *input, 3263218822Sdim const bfd_target *output) 3264218822Sdim{ 3265218822Sdim const struct elf_backend_data *obed, *ibed; 3266218822Sdim 3267218822Sdim if (input == output) 3268218822Sdim return TRUE; 3269218822Sdim 3270218822Sdim ibed = xvec_get_elf_backend_data (input); 3271218822Sdim obed = xvec_get_elf_backend_data (output); 3272218822Sdim 3273218822Sdim if (ibed->arch != obed->arch) 3274218822Sdim return FALSE; 3275218822Sdim 3276218822Sdim /* If both backends are using this function, deem them compatible. */ 3277218822Sdim return ibed->relocs_compatible == obed->relocs_compatible; 3278218822Sdim} 3279218822Sdim 3280130561Sobrien/* Add symbols from an ELF object file to the linker hash table. */ 328133965Sjdp 3282130561Sobrienstatic bfd_boolean 3283130561Sobrienelf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) 3284130561Sobrien{ 3285130561Sobrien Elf_Internal_Shdr *hdr; 3286130561Sobrien bfd_size_type symcount; 3287130561Sobrien bfd_size_type extsymcount; 3288130561Sobrien bfd_size_type extsymoff; 3289130561Sobrien struct elf_link_hash_entry **sym_hash; 3290130561Sobrien bfd_boolean dynamic; 3291130561Sobrien Elf_External_Versym *extversym = NULL; 3292130561Sobrien Elf_External_Versym *ever; 3293130561Sobrien struct elf_link_hash_entry *weaks; 3294130561Sobrien struct elf_link_hash_entry **nondeflt_vers = NULL; 3295130561Sobrien bfd_size_type nondeflt_vers_cnt = 0; 3296130561Sobrien Elf_Internal_Sym *isymbuf = NULL; 3297130561Sobrien Elf_Internal_Sym *isym; 3298130561Sobrien Elf_Internal_Sym *isymend; 3299130561Sobrien const struct elf_backend_data *bed; 3300130561Sobrien bfd_boolean add_needed; 3301218822Sdim struct elf_link_hash_table *htab; 3302130561Sobrien bfd_size_type amt; 3303218822Sdim void *alloc_mark = NULL; 3304218822Sdim struct bfd_hash_entry **old_table = NULL; 3305218822Sdim unsigned int old_size = 0; 3306218822Sdim unsigned int old_count = 0; 3307218822Sdim void *old_tab = NULL; 3308218822Sdim void *old_hash; 3309218822Sdim void *old_ent; 3310218822Sdim struct bfd_link_hash_entry *old_undefs = NULL; 3311218822Sdim struct bfd_link_hash_entry *old_undefs_tail = NULL; 3312218822Sdim long old_dynsymcount = 0; 3313218822Sdim size_t tabsize = 0; 3314218822Sdim size_t hashsize = 0; 3315130561Sobrien 3316218822Sdim htab = elf_hash_table (info); 3317130561Sobrien bed = get_elf_backend_data (abfd); 3318130561Sobrien 3319130561Sobrien if ((abfd->flags & DYNAMIC) == 0) 3320130561Sobrien dynamic = FALSE; 3321130561Sobrien else 3322130561Sobrien { 3323130561Sobrien dynamic = TRUE; 3324130561Sobrien 3325130561Sobrien /* You can't use -r against a dynamic object. Also, there's no 3326130561Sobrien hope of using a dynamic object which does not exactly match 3327130561Sobrien the format of the output file. */ 3328130561Sobrien if (info->relocatable 3329218822Sdim || !is_elf_hash_table (htab) 3330218822Sdim || htab->root.creator != abfd->xvec) 3331130561Sobrien { 3332218822Sdim if (info->relocatable) 3333218822Sdim bfd_set_error (bfd_error_invalid_operation); 3334218822Sdim else 3335218822Sdim bfd_set_error (bfd_error_wrong_format); 3336130561Sobrien goto error_return; 333733965Sjdp } 3338130561Sobrien } 333933965Sjdp 3340130561Sobrien /* As a GNU extension, any input sections which are named 3341130561Sobrien .gnu.warning.SYMBOL are treated as warning symbols for the given 3342130561Sobrien symbol. This differs from .gnu.warning sections, which generate 3343130561Sobrien warnings when they are included in an output file. */ 3344130561Sobrien if (info->executable) 3345130561Sobrien { 3346130561Sobrien asection *s; 334733965Sjdp 3348130561Sobrien for (s = abfd->sections; s != NULL; s = s->next) 334933965Sjdp { 3350130561Sobrien const char *name; 3351130561Sobrien 3352130561Sobrien name = bfd_get_section_name (abfd, s); 3353218822Sdim if (CONST_STRNEQ (name, ".gnu.warning.")) 335433965Sjdp { 3355130561Sobrien char *msg; 3356130561Sobrien bfd_size_type sz; 335733965Sjdp 3358130561Sobrien name += sizeof ".gnu.warning." - 1; 3359130561Sobrien 3360130561Sobrien /* If this is a shared object, then look up the symbol 3361130561Sobrien in the hash table. If it is there, and it is already 3362130561Sobrien been defined, then we will not be using the entry 3363130561Sobrien from this shared object, so we don't need to warn. 3364130561Sobrien FIXME: If we see the definition in a regular object 3365130561Sobrien later on, we will warn, but we shouldn't. The only 3366130561Sobrien fix is to keep track of what warnings we are supposed 3367130561Sobrien to emit, and then handle them all at the end of the 3368130561Sobrien link. */ 3369130561Sobrien if (dynamic) 3370130561Sobrien { 3371130561Sobrien struct elf_link_hash_entry *h; 3372130561Sobrien 3373218822Sdim h = elf_link_hash_lookup (htab, name, FALSE, FALSE, TRUE); 3374130561Sobrien 3375130561Sobrien /* FIXME: What about bfd_link_hash_common? */ 3376130561Sobrien if (h != NULL 3377130561Sobrien && (h->root.type == bfd_link_hash_defined 3378130561Sobrien || h->root.type == bfd_link_hash_defweak)) 3379130561Sobrien { 3380130561Sobrien /* We don't want to issue this warning. Clobber 3381130561Sobrien the section size so that the warning does not 3382130561Sobrien get copied into the output file. */ 3383218822Sdim s->size = 0; 3384130561Sobrien continue; 3385130561Sobrien } 3386130561Sobrien } 3387130561Sobrien 3388218822Sdim sz = s->size; 3389218822Sdim msg = bfd_alloc (abfd, sz + 1); 3390130561Sobrien if (msg == NULL) 3391130561Sobrien goto error_return; 3392130561Sobrien 3393218822Sdim if (! bfd_get_section_contents (abfd, s, msg, 0, sz)) 3394130561Sobrien goto error_return; 3395130561Sobrien 3396218822Sdim msg[sz] = '\0'; 3397130561Sobrien 3398130561Sobrien if (! (_bfd_generic_link_add_one_symbol 3399130561Sobrien (info, abfd, name, BSF_WARNING, s, 0, msg, 3400218822Sdim FALSE, bed->collect, NULL))) 3401130561Sobrien goto error_return; 3402130561Sobrien 3403130561Sobrien if (! info->relocatable) 3404130561Sobrien { 3405130561Sobrien /* Clobber the section size so that the warning does 3406130561Sobrien not get copied into the output file. */ 3407218822Sdim s->size = 0; 3408218822Sdim 3409218822Sdim /* Also set SEC_EXCLUDE, so that symbols defined in 3410218822Sdim the warning section don't get copied to the output. */ 3411218822Sdim s->flags |= SEC_EXCLUDE; 3412130561Sobrien } 341333965Sjdp } 341433965Sjdp } 3415130561Sobrien } 341633965Sjdp 3417130561Sobrien add_needed = TRUE; 3418130561Sobrien if (! dynamic) 3419130561Sobrien { 3420130561Sobrien /* If we are creating a shared library, create all the dynamic 3421130561Sobrien sections immediately. We need to attach them to something, 3422130561Sobrien so we attach them to this BFD, provided it is the right 3423130561Sobrien format. FIXME: If there are no input BFD's of the same 3424130561Sobrien format as the output, we can't make a shared library. */ 3425130561Sobrien if (info->shared 3426218822Sdim && is_elf_hash_table (htab) 3427218822Sdim && htab->root.creator == abfd->xvec 3428218822Sdim && !htab->dynamic_sections_created) 3429130561Sobrien { 3430130561Sobrien if (! _bfd_elf_link_create_dynamic_sections (abfd, info)) 3431130561Sobrien goto error_return; 3432130561Sobrien } 3433130561Sobrien } 3434218822Sdim else if (!is_elf_hash_table (htab)) 3435130561Sobrien goto error_return; 3436130561Sobrien else 3437130561Sobrien { 3438130561Sobrien asection *s; 3439130561Sobrien const char *soname = NULL; 3440130561Sobrien struct bfd_link_needed_list *rpath = NULL, *runpath = NULL; 3441130561Sobrien int ret; 344233965Sjdp 3443130561Sobrien /* ld --just-symbols and dynamic objects don't mix very well. 3444218822Sdim ld shouldn't allow it. */ 3445130561Sobrien if ((s = abfd->sections) != NULL 3446130561Sobrien && s->sec_info_type == ELF_INFO_TYPE_JUST_SYMS) 3447218822Sdim abort (); 3448130561Sobrien 3449130561Sobrien /* If this dynamic lib was specified on the command line with 3450130561Sobrien --as-needed in effect, then we don't want to add a DT_NEEDED 3451130561Sobrien tag unless the lib is actually used. Similary for libs brought 3452218822Sdim in by another lib's DT_NEEDED. When --no-add-needed is used 3453218822Sdim on a dynamic lib, we don't want to add a DT_NEEDED entry for 3454218822Sdim any dynamic library in DT_NEEDED tags in the dynamic lib at 3455218822Sdim all. */ 3456218822Sdim add_needed = (elf_dyn_lib_class (abfd) 3457218822Sdim & (DYN_AS_NEEDED | DYN_DT_NEEDED 3458218822Sdim | DYN_NO_NEEDED)) == 0; 3459130561Sobrien 3460130561Sobrien s = bfd_get_section_by_name (abfd, ".dynamic"); 3461130561Sobrien if (s != NULL) 346233965Sjdp { 3463130561Sobrien bfd_byte *dynbuf; 3464130561Sobrien bfd_byte *extdyn; 3465130561Sobrien int elfsec; 3466130561Sobrien unsigned long shlink; 3467130561Sobrien 3468218822Sdim if (!bfd_malloc_and_get_section (abfd, s, &dynbuf)) 3469130561Sobrien goto error_free_dyn; 3470130561Sobrien 3471130561Sobrien elfsec = _bfd_elf_section_from_bfd_section (abfd, s); 3472130561Sobrien if (elfsec == -1) 3473130561Sobrien goto error_free_dyn; 3474130561Sobrien shlink = elf_elfsections (abfd)[elfsec]->sh_link; 3475130561Sobrien 3476130561Sobrien for (extdyn = dynbuf; 3477218822Sdim extdyn < dynbuf + s->size; 3478130561Sobrien extdyn += bed->s->sizeof_dyn) 3479130561Sobrien { 3480130561Sobrien Elf_Internal_Dyn dyn; 3481130561Sobrien 3482130561Sobrien bed->s->swap_dyn_in (abfd, extdyn, &dyn); 3483130561Sobrien if (dyn.d_tag == DT_SONAME) 3484130561Sobrien { 3485130561Sobrien unsigned int tagv = dyn.d_un.d_val; 3486130561Sobrien soname = bfd_elf_string_from_elf_section (abfd, shlink, tagv); 3487130561Sobrien if (soname == NULL) 3488130561Sobrien goto error_free_dyn; 3489130561Sobrien } 3490130561Sobrien if (dyn.d_tag == DT_NEEDED) 3491130561Sobrien { 3492130561Sobrien struct bfd_link_needed_list *n, **pn; 3493130561Sobrien char *fnm, *anm; 3494130561Sobrien unsigned int tagv = dyn.d_un.d_val; 3495130561Sobrien 3496130561Sobrien amt = sizeof (struct bfd_link_needed_list); 3497130561Sobrien n = bfd_alloc (abfd, amt); 3498130561Sobrien fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv); 3499130561Sobrien if (n == NULL || fnm == NULL) 3500130561Sobrien goto error_free_dyn; 3501130561Sobrien amt = strlen (fnm) + 1; 3502130561Sobrien anm = bfd_alloc (abfd, amt); 3503130561Sobrien if (anm == NULL) 3504130561Sobrien goto error_free_dyn; 3505130561Sobrien memcpy (anm, fnm, amt); 3506130561Sobrien n->name = anm; 3507130561Sobrien n->by = abfd; 3508130561Sobrien n->next = NULL; 3509218822Sdim for (pn = &htab->needed; *pn != NULL; pn = &(*pn)->next) 3510130561Sobrien ; 3511130561Sobrien *pn = n; 3512130561Sobrien } 3513130561Sobrien if (dyn.d_tag == DT_RUNPATH) 3514130561Sobrien { 3515130561Sobrien struct bfd_link_needed_list *n, **pn; 3516130561Sobrien char *fnm, *anm; 3517130561Sobrien unsigned int tagv = dyn.d_un.d_val; 3518130561Sobrien 3519130561Sobrien amt = sizeof (struct bfd_link_needed_list); 3520130561Sobrien n = bfd_alloc (abfd, amt); 3521130561Sobrien fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv); 3522130561Sobrien if (n == NULL || fnm == NULL) 3523130561Sobrien goto error_free_dyn; 3524130561Sobrien amt = strlen (fnm) + 1; 3525130561Sobrien anm = bfd_alloc (abfd, amt); 3526130561Sobrien if (anm == NULL) 3527130561Sobrien goto error_free_dyn; 3528130561Sobrien memcpy (anm, fnm, amt); 3529130561Sobrien n->name = anm; 3530130561Sobrien n->by = abfd; 3531130561Sobrien n->next = NULL; 3532130561Sobrien for (pn = & runpath; 3533130561Sobrien *pn != NULL; 3534130561Sobrien pn = &(*pn)->next) 3535130561Sobrien ; 3536130561Sobrien *pn = n; 3537130561Sobrien } 3538130561Sobrien /* Ignore DT_RPATH if we have seen DT_RUNPATH. */ 3539130561Sobrien if (!runpath && dyn.d_tag == DT_RPATH) 3540130561Sobrien { 3541130561Sobrien struct bfd_link_needed_list *n, **pn; 3542130561Sobrien char *fnm, *anm; 3543130561Sobrien unsigned int tagv = dyn.d_un.d_val; 3544130561Sobrien 3545130561Sobrien amt = sizeof (struct bfd_link_needed_list); 3546130561Sobrien n = bfd_alloc (abfd, amt); 3547130561Sobrien fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv); 3548130561Sobrien if (n == NULL || fnm == NULL) 3549130561Sobrien goto error_free_dyn; 3550130561Sobrien amt = strlen (fnm) + 1; 3551130561Sobrien anm = bfd_alloc (abfd, amt); 3552130561Sobrien if (anm == NULL) 3553130561Sobrien { 3554130561Sobrien error_free_dyn: 3555130561Sobrien free (dynbuf); 3556130561Sobrien goto error_return; 3557130561Sobrien } 3558130561Sobrien memcpy (anm, fnm, amt); 3559130561Sobrien n->name = anm; 3560130561Sobrien n->by = abfd; 3561130561Sobrien n->next = NULL; 3562130561Sobrien for (pn = & rpath; 3563130561Sobrien *pn != NULL; 3564130561Sobrien pn = &(*pn)->next) 3565130561Sobrien ; 3566130561Sobrien *pn = n; 3567130561Sobrien } 3568130561Sobrien } 3569130561Sobrien 3570130561Sobrien free (dynbuf); 3571130561Sobrien } 3572130561Sobrien 3573130561Sobrien /* DT_RUNPATH overrides DT_RPATH. Do _NOT_ bfd_release, as that 3574130561Sobrien frees all more recently bfd_alloc'd blocks as well. */ 3575130561Sobrien if (runpath) 3576130561Sobrien rpath = runpath; 3577130561Sobrien 3578130561Sobrien if (rpath) 3579130561Sobrien { 3580130561Sobrien struct bfd_link_needed_list **pn; 3581218822Sdim for (pn = &htab->runpath; *pn != NULL; pn = &(*pn)->next) 3582130561Sobrien ; 3583130561Sobrien *pn = rpath; 3584130561Sobrien } 3585130561Sobrien 3586130561Sobrien /* We do not want to include any of the sections in a dynamic 3587130561Sobrien object in the output file. We hack by simply clobbering the 3588130561Sobrien list of sections in the BFD. This could be handled more 3589130561Sobrien cleanly by, say, a new section flag; the existing 3590130561Sobrien SEC_NEVER_LOAD flag is not the one we want, because that one 3591130561Sobrien still implies that the section takes up space in the output 3592130561Sobrien file. */ 3593130561Sobrien bfd_section_list_clear (abfd); 3594130561Sobrien 3595130561Sobrien /* Find the name to use in a DT_NEEDED entry that refers to this 3596130561Sobrien object. If the object has a DT_SONAME entry, we use it. 3597130561Sobrien Otherwise, if the generic linker stuck something in 3598130561Sobrien elf_dt_name, we use that. Otherwise, we just use the file 3599130561Sobrien name. */ 3600130561Sobrien if (soname == NULL || *soname == '\0') 3601130561Sobrien { 3602130561Sobrien soname = elf_dt_name (abfd); 3603130561Sobrien if (soname == NULL || *soname == '\0') 3604130561Sobrien soname = bfd_get_filename (abfd); 3605130561Sobrien } 3606130561Sobrien 3607130561Sobrien /* Save the SONAME because sometimes the linker emulation code 3608130561Sobrien will need to know it. */ 3609130561Sobrien elf_dt_name (abfd) = soname; 3610130561Sobrien 3611218822Sdim ret = elf_add_dt_needed_tag (abfd, info, soname, add_needed); 3612130561Sobrien if (ret < 0) 3613130561Sobrien goto error_return; 3614130561Sobrien 3615130561Sobrien /* If we have already included this dynamic object in the 3616130561Sobrien link, just ignore it. There is no reason to include a 3617130561Sobrien particular dynamic object more than once. */ 3618130561Sobrien if (ret > 0) 3619130561Sobrien return TRUE; 3620130561Sobrien } 3621130561Sobrien 3622130561Sobrien /* If this is a dynamic object, we always link against the .dynsym 3623130561Sobrien symbol table, not the .symtab symbol table. The dynamic linker 3624130561Sobrien will only see the .dynsym symbol table, so there is no reason to 3625130561Sobrien look at .symtab for a dynamic object. */ 3626130561Sobrien 3627130561Sobrien if (! dynamic || elf_dynsymtab (abfd) == 0) 3628130561Sobrien hdr = &elf_tdata (abfd)->symtab_hdr; 3629130561Sobrien else 3630130561Sobrien hdr = &elf_tdata (abfd)->dynsymtab_hdr; 3631130561Sobrien 3632130561Sobrien symcount = hdr->sh_size / bed->s->sizeof_sym; 3633130561Sobrien 3634130561Sobrien /* The sh_info field of the symtab header tells us where the 3635130561Sobrien external symbols start. We don't care about the local symbols at 3636130561Sobrien this point. */ 3637130561Sobrien if (elf_bad_symtab (abfd)) 3638130561Sobrien { 3639130561Sobrien extsymcount = symcount; 3640130561Sobrien extsymoff = 0; 3641130561Sobrien } 3642130561Sobrien else 3643130561Sobrien { 3644130561Sobrien extsymcount = symcount - hdr->sh_info; 3645130561Sobrien extsymoff = hdr->sh_info; 3646130561Sobrien } 3647130561Sobrien 3648130561Sobrien sym_hash = NULL; 3649130561Sobrien if (extsymcount != 0) 3650130561Sobrien { 3651130561Sobrien isymbuf = bfd_elf_get_elf_syms (abfd, hdr, extsymcount, extsymoff, 3652130561Sobrien NULL, NULL, NULL); 3653130561Sobrien if (isymbuf == NULL) 3654130561Sobrien goto error_return; 3655130561Sobrien 3656130561Sobrien /* We store a pointer to the hash table entry for each external 3657130561Sobrien symbol. */ 3658130561Sobrien amt = extsymcount * sizeof (struct elf_link_hash_entry *); 3659130561Sobrien sym_hash = bfd_alloc (abfd, amt); 3660130561Sobrien if (sym_hash == NULL) 3661130561Sobrien goto error_free_sym; 3662130561Sobrien elf_sym_hashes (abfd) = sym_hash; 3663130561Sobrien } 3664130561Sobrien 3665130561Sobrien if (dynamic) 3666130561Sobrien { 3667130561Sobrien /* Read in any version definitions. */ 3668218822Sdim if (!_bfd_elf_slurp_version_tables (abfd, 3669218822Sdim info->default_imported_symver)) 3670130561Sobrien goto error_free_sym; 3671130561Sobrien 3672130561Sobrien /* Read in the symbol versions, but don't bother to convert them 3673130561Sobrien to internal format. */ 3674130561Sobrien if (elf_dynversym (abfd) != 0) 3675130561Sobrien { 3676130561Sobrien Elf_Internal_Shdr *versymhdr; 3677130561Sobrien 3678130561Sobrien versymhdr = &elf_tdata (abfd)->dynversym_hdr; 3679130561Sobrien extversym = bfd_malloc (versymhdr->sh_size); 3680130561Sobrien if (extversym == NULL) 3681130561Sobrien goto error_free_sym; 3682130561Sobrien amt = versymhdr->sh_size; 3683130561Sobrien if (bfd_seek (abfd, versymhdr->sh_offset, SEEK_SET) != 0 3684130561Sobrien || bfd_bread (extversym, amt, abfd) != amt) 3685130561Sobrien goto error_free_vers; 3686130561Sobrien } 3687130561Sobrien } 3688130561Sobrien 3689218822Sdim /* If we are loading an as-needed shared lib, save the symbol table 3690218822Sdim state before we start adding symbols. If the lib turns out 3691218822Sdim to be unneeded, restore the state. */ 3692218822Sdim if ((elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0) 3693218822Sdim { 3694218822Sdim unsigned int i; 3695218822Sdim size_t entsize; 3696218822Sdim 3697218822Sdim for (entsize = 0, i = 0; i < htab->root.table.size; i++) 3698218822Sdim { 3699218822Sdim struct bfd_hash_entry *p; 3700218822Sdim struct elf_link_hash_entry *h; 3701218822Sdim 3702218822Sdim for (p = htab->root.table.table[i]; p != NULL; p = p->next) 3703218822Sdim { 3704218822Sdim h = (struct elf_link_hash_entry *) p; 3705218822Sdim entsize += htab->root.table.entsize; 3706218822Sdim if (h->root.type == bfd_link_hash_warning) 3707218822Sdim entsize += htab->root.table.entsize; 3708218822Sdim } 3709218822Sdim } 3710218822Sdim 3711218822Sdim tabsize = htab->root.table.size * sizeof (struct bfd_hash_entry *); 3712218822Sdim hashsize = extsymcount * sizeof (struct elf_link_hash_entry *); 3713218822Sdim old_tab = bfd_malloc (tabsize + entsize + hashsize); 3714218822Sdim if (old_tab == NULL) 3715218822Sdim goto error_free_vers; 3716218822Sdim 3717218822Sdim /* Remember the current objalloc pointer, so that all mem for 3718218822Sdim symbols added can later be reclaimed. */ 3719218822Sdim alloc_mark = bfd_hash_allocate (&htab->root.table, 1); 3720218822Sdim if (alloc_mark == NULL) 3721218822Sdim goto error_free_vers; 3722218822Sdim 3723218822Sdim /* Make a special call to the linker "notice" function to 3724218822Sdim tell it that we are about to handle an as-needed lib. */ 3725218822Sdim if (!(*info->callbacks->notice) (info, NULL, abfd, NULL, 3726218822Sdim notice_as_needed)) 3727218822Sdim return FALSE; 3728218822Sdim 3729218822Sdim 3730218822Sdim /* Clone the symbol table and sym hashes. Remember some 3731218822Sdim pointers into the symbol table, and dynamic symbol count. */ 3732218822Sdim old_hash = (char *) old_tab + tabsize; 3733218822Sdim old_ent = (char *) old_hash + hashsize; 3734218822Sdim memcpy (old_tab, htab->root.table.table, tabsize); 3735218822Sdim memcpy (old_hash, sym_hash, hashsize); 3736218822Sdim old_undefs = htab->root.undefs; 3737218822Sdim old_undefs_tail = htab->root.undefs_tail; 3738218822Sdim old_table = htab->root.table.table; 3739218822Sdim old_size = htab->root.table.size; 3740218822Sdim old_count = htab->root.table.count; 3741218822Sdim old_dynsymcount = htab->dynsymcount; 3742218822Sdim 3743218822Sdim for (i = 0; i < htab->root.table.size; i++) 3744218822Sdim { 3745218822Sdim struct bfd_hash_entry *p; 3746218822Sdim struct elf_link_hash_entry *h; 3747218822Sdim 3748218822Sdim for (p = htab->root.table.table[i]; p != NULL; p = p->next) 3749218822Sdim { 3750218822Sdim memcpy (old_ent, p, htab->root.table.entsize); 3751218822Sdim old_ent = (char *) old_ent + htab->root.table.entsize; 3752218822Sdim h = (struct elf_link_hash_entry *) p; 3753218822Sdim if (h->root.type == bfd_link_hash_warning) 3754218822Sdim { 3755218822Sdim memcpy (old_ent, h->root.u.i.link, htab->root.table.entsize); 3756218822Sdim old_ent = (char *) old_ent + htab->root.table.entsize; 3757218822Sdim } 3758218822Sdim } 3759218822Sdim } 3760218822Sdim } 3761218822Sdim 3762130561Sobrien weaks = NULL; 3763130561Sobrien ever = extversym != NULL ? extversym + extsymoff : NULL; 3764130561Sobrien for (isym = isymbuf, isymend = isymbuf + extsymcount; 3765130561Sobrien isym < isymend; 3766130561Sobrien isym++, sym_hash++, ever = (ever != NULL ? ever + 1 : NULL)) 3767130561Sobrien { 3768130561Sobrien int bind; 3769130561Sobrien bfd_vma value; 3770218822Sdim asection *sec, *new_sec; 3771130561Sobrien flagword flags; 3772130561Sobrien const char *name; 3773130561Sobrien struct elf_link_hash_entry *h; 3774130561Sobrien bfd_boolean definition; 3775130561Sobrien bfd_boolean size_change_ok; 3776130561Sobrien bfd_boolean type_change_ok; 3777130561Sobrien bfd_boolean new_weakdef; 3778130561Sobrien bfd_boolean override; 3779218822Sdim bfd_boolean common; 3780130561Sobrien unsigned int old_alignment; 3781130561Sobrien bfd *old_bfd; 3782130561Sobrien 3783130561Sobrien override = FALSE; 3784130561Sobrien 3785130561Sobrien flags = BSF_NO_FLAGS; 3786130561Sobrien sec = NULL; 3787130561Sobrien value = isym->st_value; 3788130561Sobrien *sym_hash = NULL; 3789218822Sdim common = bed->common_definition (isym); 3790130561Sobrien 3791130561Sobrien bind = ELF_ST_BIND (isym->st_info); 3792130561Sobrien if (bind == STB_LOCAL) 3793130561Sobrien { 3794130561Sobrien /* This should be impossible, since ELF requires that all 3795130561Sobrien global symbols follow all local symbols, and that sh_info 3796130561Sobrien point to the first global symbol. Unfortunately, Irix 5 3797130561Sobrien screws this up. */ 3798130561Sobrien continue; 3799130561Sobrien } 3800130561Sobrien else if (bind == STB_GLOBAL) 3801130561Sobrien { 3802218822Sdim if (isym->st_shndx != SHN_UNDEF && !common) 3803130561Sobrien flags = BSF_GLOBAL; 3804130561Sobrien } 3805130561Sobrien else if (bind == STB_WEAK) 3806130561Sobrien flags = BSF_WEAK; 3807130561Sobrien else 3808130561Sobrien { 3809130561Sobrien /* Leave it up to the processor backend. */ 3810130561Sobrien } 3811130561Sobrien 3812130561Sobrien if (isym->st_shndx == SHN_UNDEF) 3813130561Sobrien sec = bfd_und_section_ptr; 3814218822Sdim else if (isym->st_shndx < SHN_LORESERVE 3815218822Sdim || isym->st_shndx > SHN_HIRESERVE) 3816130561Sobrien { 3817130561Sobrien sec = bfd_section_from_elf_index (abfd, isym->st_shndx); 3818130561Sobrien if (sec == NULL) 3819130561Sobrien sec = bfd_abs_section_ptr; 3820218822Sdim else if (sec->kept_section) 3821218822Sdim { 3822218822Sdim /* Symbols from discarded section are undefined. We keep 3823218822Sdim its visibility. */ 3824218822Sdim sec = bfd_und_section_ptr; 3825218822Sdim isym->st_shndx = SHN_UNDEF; 3826218822Sdim } 3827130561Sobrien else if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0) 3828130561Sobrien value -= sec->vma; 3829130561Sobrien } 3830130561Sobrien else if (isym->st_shndx == SHN_ABS) 3831130561Sobrien sec = bfd_abs_section_ptr; 3832130561Sobrien else if (isym->st_shndx == SHN_COMMON) 3833130561Sobrien { 3834130561Sobrien sec = bfd_com_section_ptr; 3835130561Sobrien /* What ELF calls the size we call the value. What ELF 3836130561Sobrien calls the value we call the alignment. */ 3837130561Sobrien value = isym->st_size; 3838130561Sobrien } 3839130561Sobrien else 3840130561Sobrien { 3841130561Sobrien /* Leave it up to the processor backend. */ 3842130561Sobrien } 3843130561Sobrien 3844130561Sobrien name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link, 3845130561Sobrien isym->st_name); 3846130561Sobrien if (name == NULL) 3847130561Sobrien goto error_free_vers; 3848130561Sobrien 3849130561Sobrien if (isym->st_shndx == SHN_COMMON 3850218822Sdim && ELF_ST_TYPE (isym->st_info) == STT_TLS 3851218822Sdim && !info->relocatable) 3852130561Sobrien { 3853130561Sobrien asection *tcomm = bfd_get_section_by_name (abfd, ".tcommon"); 3854130561Sobrien 3855130561Sobrien if (tcomm == NULL) 3856130561Sobrien { 3857218822Sdim tcomm = bfd_make_section_with_flags (abfd, ".tcommon", 3858218822Sdim (SEC_ALLOC 3859218822Sdim | SEC_IS_COMMON 3860218822Sdim | SEC_LINKER_CREATED 3861218822Sdim | SEC_THREAD_LOCAL)); 3862218822Sdim if (tcomm == NULL) 3863130561Sobrien goto error_free_vers; 3864130561Sobrien } 3865130561Sobrien sec = tcomm; 3866130561Sobrien } 3867218822Sdim else if (bed->elf_add_symbol_hook) 3868130561Sobrien { 3869218822Sdim if (! (*bed->elf_add_symbol_hook) (abfd, info, isym, &name, &flags, 3870218822Sdim &sec, &value)) 3871130561Sobrien goto error_free_vers; 3872130561Sobrien 3873130561Sobrien /* The hook function sets the name to NULL if this symbol 3874130561Sobrien should be skipped for some reason. */ 3875130561Sobrien if (name == NULL) 3876130561Sobrien continue; 3877130561Sobrien } 3878130561Sobrien 3879130561Sobrien /* Sanity check that all possibilities were handled. */ 3880130561Sobrien if (sec == NULL) 3881130561Sobrien { 3882130561Sobrien bfd_set_error (bfd_error_bad_value); 3883130561Sobrien goto error_free_vers; 3884130561Sobrien } 3885130561Sobrien 3886130561Sobrien if (bfd_is_und_section (sec) 3887130561Sobrien || bfd_is_com_section (sec)) 3888130561Sobrien definition = FALSE; 3889130561Sobrien else 3890130561Sobrien definition = TRUE; 3891130561Sobrien 3892130561Sobrien size_change_ok = FALSE; 3893218822Sdim type_change_ok = bed->type_change_ok; 3894130561Sobrien old_alignment = 0; 3895130561Sobrien old_bfd = NULL; 3896218822Sdim new_sec = sec; 3897130561Sobrien 3898218822Sdim if (is_elf_hash_table (htab)) 3899130561Sobrien { 3900130561Sobrien Elf_Internal_Versym iver; 3901130561Sobrien unsigned int vernum = 0; 3902130561Sobrien bfd_boolean skip; 3903130561Sobrien 3904218822Sdim if (ever == NULL) 3905130561Sobrien { 3906218822Sdim if (info->default_imported_symver) 3907218822Sdim /* Use the default symbol version created earlier. */ 3908218822Sdim iver.vs_vers = elf_tdata (abfd)->cverdefs; 3909218822Sdim else 3910218822Sdim iver.vs_vers = 0; 3911218822Sdim } 3912218822Sdim else 3913218822Sdim _bfd_elf_swap_versym_in (abfd, ever, &iver); 3914130561Sobrien 3915218822Sdim vernum = iver.vs_vers & VERSYM_VERSION; 3916218822Sdim 3917218822Sdim /* If this is a hidden symbol, or if it is not version 3918218822Sdim 1, we append the version name to the symbol name. 3919218822Sdim However, we do not modify a non-hidden absolute symbol 3920218822Sdim if it is not a function, because it might be the version 3921218822Sdim symbol itself. FIXME: What if it isn't? */ 3922218822Sdim if ((iver.vs_vers & VERSYM_HIDDEN) != 0 3923218822Sdim || (vernum > 1 3924218822Sdim && (!bfd_is_abs_section (sec) 3925218822Sdim || bed->is_function_type (ELF_ST_TYPE (isym->st_info))))) 3926218822Sdim { 3927218822Sdim const char *verstr; 3928218822Sdim size_t namelen, verlen, newlen; 3929218822Sdim char *newname, *p; 3930218822Sdim 3931218822Sdim if (isym->st_shndx != SHN_UNDEF) 3932130561Sobrien { 3933218822Sdim if (vernum > elf_tdata (abfd)->cverdefs) 3934218822Sdim verstr = NULL; 3935218822Sdim else if (vernum > 1) 3936218822Sdim verstr = 3937218822Sdim elf_tdata (abfd)->verdef[vernum - 1].vd_nodename; 3938218822Sdim else 3939218822Sdim verstr = ""; 3940130561Sobrien 3941218822Sdim if (verstr == NULL) 3942130561Sobrien { 3943218822Sdim (*_bfd_error_handler) 3944218822Sdim (_("%B: %s: invalid version %u (max %d)"), 3945218822Sdim abfd, name, vernum, 3946218822Sdim elf_tdata (abfd)->cverdefs); 3947218822Sdim bfd_set_error (bfd_error_bad_value); 3948218822Sdim goto error_free_vers; 3949130561Sobrien } 3950218822Sdim } 3951218822Sdim else 3952218822Sdim { 3953218822Sdim /* We cannot simply test for the number of 3954218822Sdim entries in the VERNEED section since the 3955218822Sdim numbers for the needed versions do not start 3956218822Sdim at 0. */ 3957218822Sdim Elf_Internal_Verneed *t; 3958218822Sdim 3959218822Sdim verstr = NULL; 3960218822Sdim for (t = elf_tdata (abfd)->verref; 3961218822Sdim t != NULL; 3962218822Sdim t = t->vn_nextref) 3963130561Sobrien { 3964218822Sdim Elf_Internal_Vernaux *a; 3965130561Sobrien 3966218822Sdim for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) 3967130561Sobrien { 3968218822Sdim if (a->vna_other == vernum) 3969130561Sobrien { 3970218822Sdim verstr = a->vna_nodename; 3971218822Sdim break; 3972130561Sobrien } 3973130561Sobrien } 3974218822Sdim if (a != NULL) 3975218822Sdim break; 3976130561Sobrien } 3977218822Sdim if (verstr == NULL) 3978218822Sdim { 3979218822Sdim (*_bfd_error_handler) 3980218822Sdim (_("%B: %s: invalid needed version %d"), 3981218822Sdim abfd, name, vernum); 3982218822Sdim bfd_set_error (bfd_error_bad_value); 3983218822Sdim goto error_free_vers; 3984218822Sdim } 3985218822Sdim } 3986130561Sobrien 3987218822Sdim namelen = strlen (name); 3988218822Sdim verlen = strlen (verstr); 3989218822Sdim newlen = namelen + verlen + 2; 3990218822Sdim if ((iver.vs_vers & VERSYM_HIDDEN) == 0 3991218822Sdim && isym->st_shndx != SHN_UNDEF) 3992218822Sdim ++newlen; 3993130561Sobrien 3994218822Sdim newname = bfd_hash_allocate (&htab->root.table, newlen); 3995218822Sdim if (newname == NULL) 3996218822Sdim goto error_free_vers; 3997218822Sdim memcpy (newname, name, namelen); 3998218822Sdim p = newname + namelen; 3999218822Sdim *p++ = ELF_VER_CHR; 4000218822Sdim /* If this is a defined non-hidden version symbol, 4001218822Sdim we add another @ to the name. This indicates the 4002218822Sdim default version of the symbol. */ 4003218822Sdim if ((iver.vs_vers & VERSYM_HIDDEN) == 0 4004218822Sdim && isym->st_shndx != SHN_UNDEF) 4005218822Sdim *p++ = ELF_VER_CHR; 4006218822Sdim memcpy (p, verstr, verlen + 1); 4007130561Sobrien 4008218822Sdim name = newname; 4009130561Sobrien } 4010130561Sobrien 4011218822Sdim if (!_bfd_elf_merge_symbol (abfd, info, name, isym, &sec, 4012218822Sdim &value, &old_alignment, 4013130561Sobrien sym_hash, &skip, &override, 4014130561Sobrien &type_change_ok, &size_change_ok)) 4015130561Sobrien goto error_free_vers; 4016130561Sobrien 4017130561Sobrien if (skip) 4018130561Sobrien continue; 4019130561Sobrien 4020130561Sobrien if (override) 4021130561Sobrien definition = FALSE; 4022130561Sobrien 4023130561Sobrien h = *sym_hash; 4024130561Sobrien while (h->root.type == bfd_link_hash_indirect 4025130561Sobrien || h->root.type == bfd_link_hash_warning) 4026130561Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 4027130561Sobrien 4028130561Sobrien /* Remember the old alignment if this is a common symbol, so 4029130561Sobrien that we don't reduce the alignment later on. We can't 4030130561Sobrien check later, because _bfd_generic_link_add_one_symbol 4031130561Sobrien will set a default for the alignment which we want to 4032130561Sobrien override. We also remember the old bfd where the existing 4033130561Sobrien definition comes from. */ 4034130561Sobrien switch (h->root.type) 4035130561Sobrien { 4036130561Sobrien default: 4037130561Sobrien break; 4038130561Sobrien 4039130561Sobrien case bfd_link_hash_defined: 4040130561Sobrien case bfd_link_hash_defweak: 4041130561Sobrien old_bfd = h->root.u.def.section->owner; 4042130561Sobrien break; 4043130561Sobrien 4044130561Sobrien case bfd_link_hash_common: 4045130561Sobrien old_bfd = h->root.u.c.p->section->owner; 4046130561Sobrien old_alignment = h->root.u.c.p->alignment_power; 4047130561Sobrien break; 4048130561Sobrien } 4049130561Sobrien 4050130561Sobrien if (elf_tdata (abfd)->verdef != NULL 4051130561Sobrien && ! override 4052130561Sobrien && vernum > 1 4053130561Sobrien && definition) 4054130561Sobrien h->verinfo.verdef = &elf_tdata (abfd)->verdef[vernum - 1]; 4055130561Sobrien } 4056130561Sobrien 4057130561Sobrien if (! (_bfd_generic_link_add_one_symbol 4058218822Sdim (info, abfd, name, flags, sec, value, NULL, FALSE, bed->collect, 4059130561Sobrien (struct bfd_link_hash_entry **) sym_hash))) 4060130561Sobrien goto error_free_vers; 4061130561Sobrien 4062130561Sobrien h = *sym_hash; 4063130561Sobrien while (h->root.type == bfd_link_hash_indirect 4064130561Sobrien || h->root.type == bfd_link_hash_warning) 4065130561Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 4066130561Sobrien *sym_hash = h; 4067130561Sobrien 4068130561Sobrien new_weakdef = FALSE; 4069130561Sobrien if (dynamic 4070130561Sobrien && definition 4071130561Sobrien && (flags & BSF_WEAK) != 0 4072218822Sdim && !bed->is_function_type (ELF_ST_TYPE (isym->st_info)) 4073218822Sdim && is_elf_hash_table (htab) 4074218822Sdim && h->u.weakdef == NULL) 4075130561Sobrien { 4076130561Sobrien /* Keep a list of all weak defined non function symbols from 4077130561Sobrien a dynamic object, using the weakdef field. Later in this 4078130561Sobrien function we will set the weakdef field to the correct 4079130561Sobrien value. We only put non-function symbols from dynamic 4080130561Sobrien objects on this list, because that happens to be the only 4081130561Sobrien time we need to know the normal symbol corresponding to a 4082130561Sobrien weak symbol, and the information is time consuming to 4083130561Sobrien figure out. If the weakdef field is not already NULL, 4084130561Sobrien then this symbol was already defined by some previous 4085130561Sobrien dynamic object, and we will be using that previous 4086130561Sobrien definition anyhow. */ 4087130561Sobrien 4088218822Sdim h->u.weakdef = weaks; 4089130561Sobrien weaks = h; 4090130561Sobrien new_weakdef = TRUE; 4091130561Sobrien } 4092130561Sobrien 4093130561Sobrien /* Set the alignment of a common symbol. */ 4094218822Sdim if ((common || bfd_is_com_section (sec)) 4095130561Sobrien && h->root.type == bfd_link_hash_common) 4096130561Sobrien { 4097130561Sobrien unsigned int align; 4098130561Sobrien 4099218822Sdim if (common) 4100218822Sdim align = bfd_log2 (isym->st_value); 4101218822Sdim else 4102218822Sdim { 4103218822Sdim /* The new symbol is a common symbol in a shared object. 4104218822Sdim We need to get the alignment from the section. */ 4105218822Sdim align = new_sec->alignment_power; 4106218822Sdim } 4107130561Sobrien if (align > old_alignment 4108130561Sobrien /* Permit an alignment power of zero if an alignment of one 4109130561Sobrien is specified and no other alignments have been specified. */ 4110130561Sobrien || (isym->st_value == 1 && old_alignment == 0)) 4111130561Sobrien h->root.u.c.p->alignment_power = align; 4112130561Sobrien else 4113130561Sobrien h->root.u.c.p->alignment_power = old_alignment; 4114130561Sobrien } 4115130561Sobrien 4116218822Sdim if (is_elf_hash_table (htab)) 4117130561Sobrien { 4118130561Sobrien bfd_boolean dynsym; 4119130561Sobrien 4120130561Sobrien /* Check the alignment when a common symbol is involved. This 4121130561Sobrien can change when a common symbol is overridden by a normal 4122130561Sobrien definition or a common symbol is ignored due to the old 4123130561Sobrien normal definition. We need to make sure the maximum 4124130561Sobrien alignment is maintained. */ 4125218822Sdim if ((old_alignment || common) 4126130561Sobrien && h->root.type != bfd_link_hash_common) 4127130561Sobrien { 4128130561Sobrien unsigned int common_align; 4129130561Sobrien unsigned int normal_align; 4130130561Sobrien unsigned int symbol_align; 4131130561Sobrien bfd *normal_bfd; 4132130561Sobrien bfd *common_bfd; 4133130561Sobrien 4134130561Sobrien symbol_align = ffs (h->root.u.def.value) - 1; 4135130561Sobrien if (h->root.u.def.section->owner != NULL 4136130561Sobrien && (h->root.u.def.section->owner->flags & DYNAMIC) == 0) 4137130561Sobrien { 4138130561Sobrien normal_align = h->root.u.def.section->alignment_power; 4139130561Sobrien if (normal_align > symbol_align) 4140130561Sobrien normal_align = symbol_align; 4141130561Sobrien } 4142130561Sobrien else 4143130561Sobrien normal_align = symbol_align; 4144130561Sobrien 4145130561Sobrien if (old_alignment) 4146130561Sobrien { 4147130561Sobrien common_align = old_alignment; 4148130561Sobrien common_bfd = old_bfd; 4149130561Sobrien normal_bfd = abfd; 4150130561Sobrien } 4151130561Sobrien else 4152130561Sobrien { 4153130561Sobrien common_align = bfd_log2 (isym->st_value); 4154130561Sobrien common_bfd = abfd; 4155130561Sobrien normal_bfd = old_bfd; 4156130561Sobrien } 4157130561Sobrien 4158130561Sobrien if (normal_align < common_align) 4159218822Sdim { 4160218822Sdim /* PR binutils/2735 */ 4161218822Sdim if (normal_bfd == NULL) 4162218822Sdim (*_bfd_error_handler) 4163218822Sdim (_("Warning: alignment %u of common symbol `%s' in %B" 4164218822Sdim " is greater than the alignment (%u) of its section %A"), 4165218822Sdim common_bfd, h->root.u.def.section, 4166218822Sdim 1 << common_align, name, 1 << normal_align); 4167218822Sdim else 4168218822Sdim (*_bfd_error_handler) 4169218822Sdim (_("Warning: alignment %u of symbol `%s' in %B" 4170218822Sdim " is smaller than %u in %B"), 4171218822Sdim normal_bfd, common_bfd, 4172218822Sdim 1 << normal_align, name, 1 << common_align); 4173218822Sdim } 4174130561Sobrien } 4175130561Sobrien 4176218822Sdim /* Remember the symbol size if it isn't undefined. */ 4177218822Sdim if ((isym->st_size != 0 && isym->st_shndx != SHN_UNDEF) 4178130561Sobrien && (definition || h->size == 0)) 4179130561Sobrien { 4180218822Sdim if (h->size != 0 4181218822Sdim && h->size != isym->st_size 4182218822Sdim && ! size_change_ok) 4183130561Sobrien (*_bfd_error_handler) 4184218822Sdim (_("Warning: size of symbol `%s' changed" 4185218822Sdim " from %lu in %B to %lu in %B"), 4186218822Sdim old_bfd, abfd, 4187130561Sobrien name, (unsigned long) h->size, 4188218822Sdim (unsigned long) isym->st_size); 4189130561Sobrien 4190130561Sobrien h->size = isym->st_size; 4191130561Sobrien } 4192130561Sobrien 4193130561Sobrien /* If this is a common symbol, then we always want H->SIZE 4194130561Sobrien to be the size of the common symbol. The code just above 4195130561Sobrien won't fix the size if a common symbol becomes larger. We 4196130561Sobrien don't warn about a size change here, because that is 4197218822Sdim covered by --warn-common. Allow changed between different 4198218822Sdim function types. */ 4199130561Sobrien if (h->root.type == bfd_link_hash_common) 4200130561Sobrien h->size = h->root.u.c.size; 4201130561Sobrien 4202130561Sobrien if (ELF_ST_TYPE (isym->st_info) != STT_NOTYPE 4203130561Sobrien && (definition || h->type == STT_NOTYPE)) 4204130561Sobrien { 4205130561Sobrien if (h->type != STT_NOTYPE 4206130561Sobrien && h->type != ELF_ST_TYPE (isym->st_info) 4207130561Sobrien && ! type_change_ok) 4208130561Sobrien (*_bfd_error_handler) 4209218822Sdim (_("Warning: type of symbol `%s' changed" 4210218822Sdim " from %d to %d in %B"), 4211218822Sdim abfd, name, h->type, ELF_ST_TYPE (isym->st_info)); 4212130561Sobrien 4213130561Sobrien h->type = ELF_ST_TYPE (isym->st_info); 4214130561Sobrien } 4215130561Sobrien 4216130561Sobrien /* If st_other has a processor-specific meaning, specific 4217130561Sobrien code might be needed here. We never merge the visibility 4218130561Sobrien attribute with the one from a dynamic object. */ 4219130561Sobrien if (bed->elf_backend_merge_symbol_attribute) 4220130561Sobrien (*bed->elf_backend_merge_symbol_attribute) (h, isym, definition, 4221130561Sobrien dynamic); 4222130561Sobrien 4223218822Sdim /* If this symbol has default visibility and the user has requested 4224218822Sdim we not re-export it, then mark it as hidden. */ 4225218822Sdim if (definition && !dynamic 4226218822Sdim && (abfd->no_export 4227218822Sdim || (abfd->my_archive && abfd->my_archive->no_export)) 4228218822Sdim && ELF_ST_VISIBILITY (isym->st_other) != STV_INTERNAL) 4229218822Sdim isym->st_other = (STV_HIDDEN 4230218822Sdim | (isym->st_other & ~ELF_ST_VISIBILITY (-1))); 4231218822Sdim 4232218822Sdim if (ELF_ST_VISIBILITY (isym->st_other) != 0 && !dynamic) 4233130561Sobrien { 4234130561Sobrien unsigned char hvis, symvis, other, nvis; 4235130561Sobrien 4236218822Sdim /* Only merge the visibility. Leave the remainder of the 4237218822Sdim st_other field to elf_backend_merge_symbol_attribute. */ 4238218822Sdim other = h->other & ~ELF_ST_VISIBILITY (-1); 4239130561Sobrien 4240130561Sobrien /* Combine visibilities, using the most constraining one. */ 4241130561Sobrien hvis = ELF_ST_VISIBILITY (h->other); 4242130561Sobrien symvis = ELF_ST_VISIBILITY (isym->st_other); 4243130561Sobrien if (! hvis) 4244130561Sobrien nvis = symvis; 4245130561Sobrien else if (! symvis) 4246130561Sobrien nvis = hvis; 4247130561Sobrien else 4248130561Sobrien nvis = hvis < symvis ? hvis : symvis; 4249130561Sobrien 4250130561Sobrien h->other = other | nvis; 4251130561Sobrien } 4252130561Sobrien 4253130561Sobrien /* Set a flag in the hash table entry indicating the type of 4254130561Sobrien reference or definition we just found. Keep a count of 4255130561Sobrien the number of dynamic symbols we find. A dynamic symbol 4256130561Sobrien is one which is referenced or defined by both a regular 4257130561Sobrien object and a shared object. */ 4258130561Sobrien dynsym = FALSE; 4259130561Sobrien if (! dynamic) 4260130561Sobrien { 4261130561Sobrien if (! definition) 4262130561Sobrien { 4263218822Sdim h->ref_regular = 1; 4264130561Sobrien if (bind != STB_WEAK) 4265218822Sdim h->ref_regular_nonweak = 1; 4266130561Sobrien } 4267130561Sobrien else 4268218822Sdim h->def_regular = 1; 4269130561Sobrien if (! info->executable 4270218822Sdim || h->def_dynamic 4271218822Sdim || h->ref_dynamic) 4272130561Sobrien dynsym = TRUE; 4273130561Sobrien } 4274130561Sobrien else 4275130561Sobrien { 4276130561Sobrien if (! definition) 4277218822Sdim h->ref_dynamic = 1; 4278130561Sobrien else 4279218822Sdim h->def_dynamic = 1; 4280218822Sdim if (h->def_regular 4281218822Sdim || h->ref_regular 4282218822Sdim || (h->u.weakdef != NULL 4283130561Sobrien && ! new_weakdef 4284218822Sdim && h->u.weakdef->dynindx != -1)) 4285130561Sobrien dynsym = TRUE; 4286130561Sobrien } 4287130561Sobrien 4288218822Sdim if (definition && (sec->flags & SEC_DEBUGGING)) 4289218822Sdim { 4290218822Sdim /* We don't want to make debug symbol dynamic. */ 4291218822Sdim (*bed->elf_backend_hide_symbol) (info, h, TRUE); 4292218822Sdim dynsym = FALSE; 4293218822Sdim } 4294130561Sobrien 4295130561Sobrien /* Check to see if we need to add an indirect symbol for 4296130561Sobrien the default name. */ 4297130561Sobrien if (definition || h->root.type == bfd_link_hash_common) 4298130561Sobrien if (!_bfd_elf_add_default_symbol (abfd, info, h, name, isym, 4299130561Sobrien &sec, &value, &dynsym, 4300130561Sobrien override)) 4301130561Sobrien goto error_free_vers; 4302130561Sobrien 4303130561Sobrien if (definition && !dynamic) 4304130561Sobrien { 4305130561Sobrien char *p = strchr (name, ELF_VER_CHR); 4306130561Sobrien if (p != NULL && p[1] != ELF_VER_CHR) 4307130561Sobrien { 4308130561Sobrien /* Queue non-default versions so that .symver x, x@FOO 4309130561Sobrien aliases can be checked. */ 4310218822Sdim if (!nondeflt_vers) 4311130561Sobrien { 4312218822Sdim amt = ((isymend - isym + 1) 4313218822Sdim * sizeof (struct elf_link_hash_entry *)); 4314130561Sobrien nondeflt_vers = bfd_malloc (amt); 4315130561Sobrien } 4316218822Sdim nondeflt_vers[nondeflt_vers_cnt++] = h; 4317130561Sobrien } 4318130561Sobrien } 4319130561Sobrien 4320130561Sobrien if (dynsym && h->dynindx == -1) 4321130561Sobrien { 4322130561Sobrien if (! bfd_elf_link_record_dynamic_symbol (info, h)) 4323130561Sobrien goto error_free_vers; 4324218822Sdim if (h->u.weakdef != NULL 4325130561Sobrien && ! new_weakdef 4326218822Sdim && h->u.weakdef->dynindx == -1) 4327130561Sobrien { 4328218822Sdim if (!bfd_elf_link_record_dynamic_symbol (info, h->u.weakdef)) 4329130561Sobrien goto error_free_vers; 4330130561Sobrien } 4331130561Sobrien } 4332130561Sobrien else if (dynsym && h->dynindx != -1) 4333130561Sobrien /* If the symbol already has a dynamic index, but 4334130561Sobrien visibility says it should not be visible, turn it into 4335130561Sobrien a local symbol. */ 4336130561Sobrien switch (ELF_ST_VISIBILITY (h->other)) 4337130561Sobrien { 4338130561Sobrien case STV_INTERNAL: 4339130561Sobrien case STV_HIDDEN: 4340130561Sobrien (*bed->elf_backend_hide_symbol) (info, h, TRUE); 4341130561Sobrien dynsym = FALSE; 4342130561Sobrien break; 4343130561Sobrien } 4344130561Sobrien 4345130561Sobrien if (!add_needed 4346130561Sobrien && definition 4347130561Sobrien && dynsym 4348218822Sdim && h->ref_regular) 4349130561Sobrien { 4350130561Sobrien int ret; 4351130561Sobrien const char *soname = elf_dt_name (abfd); 4352130561Sobrien 4353130561Sobrien /* A symbol from a library loaded via DT_NEEDED of some 4354130561Sobrien other library is referenced by a regular object. 4355218822Sdim Add a DT_NEEDED entry for it. Issue an error if 4356218822Sdim --no-add-needed is used. */ 4357218822Sdim if ((elf_dyn_lib_class (abfd) & DYN_NO_NEEDED) != 0) 4358218822Sdim { 4359218822Sdim (*_bfd_error_handler) 4360273233Semaste (_("%B: invalid DSO for symbol `%s' definition"), 4361273233Semaste abfd, name); 4362218822Sdim bfd_set_error (bfd_error_bad_value); 4363218822Sdim goto error_free_vers; 4364218822Sdim } 4365218822Sdim 4366218822Sdim elf_dyn_lib_class (abfd) &= ~DYN_AS_NEEDED; 4367218822Sdim 4368130561Sobrien add_needed = TRUE; 4369218822Sdim ret = elf_add_dt_needed_tag (abfd, info, soname, add_needed); 4370130561Sobrien if (ret < 0) 4371130561Sobrien goto error_free_vers; 4372130561Sobrien 4373130561Sobrien BFD_ASSERT (ret == 0); 4374130561Sobrien } 4375130561Sobrien } 4376130561Sobrien } 4377130561Sobrien 4378218822Sdim if (extversym != NULL) 4379218822Sdim { 4380218822Sdim free (extversym); 4381218822Sdim extversym = NULL; 4382218822Sdim } 4383218822Sdim 4384218822Sdim if (isymbuf != NULL) 4385218822Sdim { 4386218822Sdim free (isymbuf); 4387218822Sdim isymbuf = NULL; 4388218822Sdim } 4389218822Sdim 4390218822Sdim if ((elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0) 4391218822Sdim { 4392218822Sdim unsigned int i; 4393218822Sdim 4394218822Sdim /* Restore the symbol table. */ 4395218822Sdim if (bed->as_needed_cleanup) 4396218822Sdim (*bed->as_needed_cleanup) (abfd, info); 4397218822Sdim old_hash = (char *) old_tab + tabsize; 4398218822Sdim old_ent = (char *) old_hash + hashsize; 4399218822Sdim sym_hash = elf_sym_hashes (abfd); 4400218822Sdim htab->root.table.table = old_table; 4401218822Sdim htab->root.table.size = old_size; 4402218822Sdim htab->root.table.count = old_count; 4403218822Sdim memcpy (htab->root.table.table, old_tab, tabsize); 4404218822Sdim memcpy (sym_hash, old_hash, hashsize); 4405218822Sdim htab->root.undefs = old_undefs; 4406218822Sdim htab->root.undefs_tail = old_undefs_tail; 4407218822Sdim for (i = 0; i < htab->root.table.size; i++) 4408218822Sdim { 4409218822Sdim struct bfd_hash_entry *p; 4410218822Sdim struct elf_link_hash_entry *h; 4411218822Sdim 4412218822Sdim for (p = htab->root.table.table[i]; p != NULL; p = p->next) 4413218822Sdim { 4414218822Sdim h = (struct elf_link_hash_entry *) p; 4415218822Sdim if (h->root.type == bfd_link_hash_warning) 4416218822Sdim h = (struct elf_link_hash_entry *) h->root.u.i.link; 4417218822Sdim if (h->dynindx >= old_dynsymcount) 4418218822Sdim _bfd_elf_strtab_delref (htab->dynstr, h->dynstr_index); 4419218822Sdim 4420218822Sdim memcpy (p, old_ent, htab->root.table.entsize); 4421218822Sdim old_ent = (char *) old_ent + htab->root.table.entsize; 4422218822Sdim h = (struct elf_link_hash_entry *) p; 4423218822Sdim if (h->root.type == bfd_link_hash_warning) 4424218822Sdim { 4425218822Sdim memcpy (h->root.u.i.link, old_ent, htab->root.table.entsize); 4426218822Sdim old_ent = (char *) old_ent + htab->root.table.entsize; 4427218822Sdim } 4428218822Sdim } 4429218822Sdim } 4430218822Sdim 4431218822Sdim /* Make a special call to the linker "notice" function to 4432218822Sdim tell it that symbols added for crefs may need to be removed. */ 4433218822Sdim if (!(*info->callbacks->notice) (info, NULL, abfd, NULL, 4434218822Sdim notice_not_needed)) 4435218822Sdim return FALSE; 4436218822Sdim 4437218822Sdim free (old_tab); 4438218822Sdim objalloc_free_block ((struct objalloc *) htab->root.table.memory, 4439218822Sdim alloc_mark); 4440218822Sdim if (nondeflt_vers != NULL) 4441218822Sdim free (nondeflt_vers); 4442218822Sdim return TRUE; 4443218822Sdim } 4444218822Sdim 4445218822Sdim if (old_tab != NULL) 4446218822Sdim { 4447218822Sdim if (!(*info->callbacks->notice) (info, NULL, abfd, NULL, 4448218822Sdim notice_needed)) 4449218822Sdim return FALSE; 4450218822Sdim free (old_tab); 4451218822Sdim old_tab = NULL; 4452218822Sdim } 4453218822Sdim 4454130561Sobrien /* Now that all the symbols from this input file are created, handle 4455130561Sobrien .symver foo, foo@BAR such that any relocs against foo become foo@BAR. */ 4456130561Sobrien if (nondeflt_vers != NULL) 4457130561Sobrien { 4458130561Sobrien bfd_size_type cnt, symidx; 4459130561Sobrien 4460130561Sobrien for (cnt = 0; cnt < nondeflt_vers_cnt; ++cnt) 4461130561Sobrien { 4462130561Sobrien struct elf_link_hash_entry *h = nondeflt_vers[cnt], *hi; 4463130561Sobrien char *shortname, *p; 4464130561Sobrien 4465130561Sobrien p = strchr (h->root.root.string, ELF_VER_CHR); 4466130561Sobrien if (p == NULL 4467130561Sobrien || (h->root.type != bfd_link_hash_defined 4468130561Sobrien && h->root.type != bfd_link_hash_defweak)) 4469130561Sobrien continue; 4470130561Sobrien 4471130561Sobrien amt = p - h->root.root.string; 4472130561Sobrien shortname = bfd_malloc (amt + 1); 4473130561Sobrien memcpy (shortname, h->root.root.string, amt); 4474130561Sobrien shortname[amt] = '\0'; 4475130561Sobrien 4476130561Sobrien hi = (struct elf_link_hash_entry *) 4477218822Sdim bfd_link_hash_lookup (&htab->root, shortname, 4478130561Sobrien FALSE, FALSE, FALSE); 4479130561Sobrien if (hi != NULL 4480130561Sobrien && hi->root.type == h->root.type 4481130561Sobrien && hi->root.u.def.value == h->root.u.def.value 4482130561Sobrien && hi->root.u.def.section == h->root.u.def.section) 4483130561Sobrien { 4484130561Sobrien (*bed->elf_backend_hide_symbol) (info, hi, TRUE); 4485130561Sobrien hi->root.type = bfd_link_hash_indirect; 4486130561Sobrien hi->root.u.i.link = (struct bfd_link_hash_entry *) h; 4487218822Sdim (*bed->elf_backend_copy_indirect_symbol) (info, h, hi); 4488130561Sobrien sym_hash = elf_sym_hashes (abfd); 4489130561Sobrien if (sym_hash) 4490130561Sobrien for (symidx = 0; symidx < extsymcount; ++symidx) 4491130561Sobrien if (sym_hash[symidx] == hi) 4492130561Sobrien { 4493130561Sobrien sym_hash[symidx] = h; 4494130561Sobrien break; 4495130561Sobrien } 4496130561Sobrien } 4497130561Sobrien free (shortname); 4498130561Sobrien } 4499130561Sobrien free (nondeflt_vers); 4500130561Sobrien nondeflt_vers = NULL; 4501130561Sobrien } 4502130561Sobrien 4503130561Sobrien /* Now set the weakdefs field correctly for all the weak defined 4504130561Sobrien symbols we found. The only way to do this is to search all the 4505130561Sobrien symbols. Since we only need the information for non functions in 4506130561Sobrien dynamic objects, that's the only time we actually put anything on 4507130561Sobrien the list WEAKS. We need this information so that if a regular 4508130561Sobrien object refers to a symbol defined weakly in a dynamic object, the 4509130561Sobrien real symbol in the dynamic object is also put in the dynamic 4510130561Sobrien symbols; we also must arrange for both symbols to point to the 4511130561Sobrien same memory location. We could handle the general case of symbol 4512130561Sobrien aliasing, but a general symbol alias can only be generated in 4513130561Sobrien assembler code, handling it correctly would be very time 4514130561Sobrien consuming, and other ELF linkers don't handle general aliasing 4515130561Sobrien either. */ 4516130561Sobrien if (weaks != NULL) 4517130561Sobrien { 4518130561Sobrien struct elf_link_hash_entry **hpp; 4519130561Sobrien struct elf_link_hash_entry **hppend; 4520130561Sobrien struct elf_link_hash_entry **sorted_sym_hash; 4521130561Sobrien struct elf_link_hash_entry *h; 4522130561Sobrien size_t sym_count; 4523130561Sobrien 4524130561Sobrien /* Since we have to search the whole symbol list for each weak 4525130561Sobrien defined symbol, search time for N weak defined symbols will be 4526130561Sobrien O(N^2). Binary search will cut it down to O(NlogN). */ 4527130561Sobrien amt = extsymcount * sizeof (struct elf_link_hash_entry *); 4528130561Sobrien sorted_sym_hash = bfd_malloc (amt); 4529130561Sobrien if (sorted_sym_hash == NULL) 4530130561Sobrien goto error_return; 4531130561Sobrien sym_hash = sorted_sym_hash; 4532130561Sobrien hpp = elf_sym_hashes (abfd); 4533130561Sobrien hppend = hpp + extsymcount; 4534130561Sobrien sym_count = 0; 4535130561Sobrien for (; hpp < hppend; hpp++) 4536130561Sobrien { 4537130561Sobrien h = *hpp; 4538130561Sobrien if (h != NULL 4539130561Sobrien && h->root.type == bfd_link_hash_defined 4540218822Sdim && !bed->is_function_type (h->type)) 4541130561Sobrien { 4542130561Sobrien *sym_hash = h; 4543130561Sobrien sym_hash++; 4544130561Sobrien sym_count++; 4545130561Sobrien } 4546130561Sobrien } 4547130561Sobrien 4548130561Sobrien qsort (sorted_sym_hash, sym_count, 4549130561Sobrien sizeof (struct elf_link_hash_entry *), 4550130561Sobrien elf_sort_symbol); 4551130561Sobrien 4552130561Sobrien while (weaks != NULL) 4553130561Sobrien { 4554130561Sobrien struct elf_link_hash_entry *hlook; 4555130561Sobrien asection *slook; 4556130561Sobrien bfd_vma vlook; 4557130561Sobrien long ilook; 4558130561Sobrien size_t i, j, idx; 4559130561Sobrien 4560130561Sobrien hlook = weaks; 4561218822Sdim weaks = hlook->u.weakdef; 4562218822Sdim hlook->u.weakdef = NULL; 4563130561Sobrien 4564130561Sobrien BFD_ASSERT (hlook->root.type == bfd_link_hash_defined 4565130561Sobrien || hlook->root.type == bfd_link_hash_defweak 4566130561Sobrien || hlook->root.type == bfd_link_hash_common 4567130561Sobrien || hlook->root.type == bfd_link_hash_indirect); 4568130561Sobrien slook = hlook->root.u.def.section; 4569130561Sobrien vlook = hlook->root.u.def.value; 4570130561Sobrien 4571130561Sobrien ilook = -1; 4572130561Sobrien i = 0; 4573130561Sobrien j = sym_count; 4574130561Sobrien while (i < j) 4575130561Sobrien { 4576130561Sobrien bfd_signed_vma vdiff; 4577130561Sobrien idx = (i + j) / 2; 4578130561Sobrien h = sorted_sym_hash [idx]; 4579130561Sobrien vdiff = vlook - h->root.u.def.value; 4580130561Sobrien if (vdiff < 0) 4581130561Sobrien j = idx; 4582130561Sobrien else if (vdiff > 0) 4583130561Sobrien i = idx + 1; 4584130561Sobrien else 4585130561Sobrien { 4586218822Sdim long sdiff = slook->id - h->root.u.def.section->id; 4587130561Sobrien if (sdiff < 0) 4588130561Sobrien j = idx; 4589130561Sobrien else if (sdiff > 0) 4590130561Sobrien i = idx + 1; 4591130561Sobrien else 4592130561Sobrien { 4593130561Sobrien ilook = idx; 4594130561Sobrien break; 4595130561Sobrien } 4596130561Sobrien } 4597130561Sobrien } 4598130561Sobrien 4599130561Sobrien /* We didn't find a value/section match. */ 4600130561Sobrien if (ilook == -1) 4601130561Sobrien continue; 4602130561Sobrien 4603130561Sobrien for (i = ilook; i < sym_count; i++) 4604130561Sobrien { 4605130561Sobrien h = sorted_sym_hash [i]; 4606130561Sobrien 4607130561Sobrien /* Stop if value or section doesn't match. */ 4608130561Sobrien if (h->root.u.def.value != vlook 4609130561Sobrien || h->root.u.def.section != slook) 4610130561Sobrien break; 4611130561Sobrien else if (h != hlook) 4612130561Sobrien { 4613218822Sdim hlook->u.weakdef = h; 4614130561Sobrien 4615130561Sobrien /* If the weak definition is in the list of dynamic 4616130561Sobrien symbols, make sure the real definition is put 4617130561Sobrien there as well. */ 4618130561Sobrien if (hlook->dynindx != -1 && h->dynindx == -1) 4619130561Sobrien { 4620130561Sobrien if (! bfd_elf_link_record_dynamic_symbol (info, h)) 4621130561Sobrien goto error_return; 4622130561Sobrien } 4623130561Sobrien 4624130561Sobrien /* If the real definition is in the list of dynamic 4625130561Sobrien symbols, make sure the weak definition is put 4626130561Sobrien there as well. If we don't do this, then the 4627130561Sobrien dynamic loader might not merge the entries for the 4628130561Sobrien real definition and the weak definition. */ 4629130561Sobrien if (h->dynindx != -1 && hlook->dynindx == -1) 4630130561Sobrien { 4631130561Sobrien if (! bfd_elf_link_record_dynamic_symbol (info, hlook)) 4632130561Sobrien goto error_return; 4633130561Sobrien } 4634130561Sobrien break; 4635130561Sobrien } 4636130561Sobrien } 4637130561Sobrien } 4638130561Sobrien 4639130561Sobrien free (sorted_sym_hash); 4640130561Sobrien } 4641130561Sobrien 4642218822Sdim if (bed->check_directives) 4643218822Sdim (*bed->check_directives) (abfd, info); 4644218822Sdim 4645130561Sobrien /* If this object is the same format as the output object, and it is 4646130561Sobrien not a shared library, then let the backend look through the 4647130561Sobrien relocs. 4648130561Sobrien 4649130561Sobrien This is required to build global offset table entries and to 4650130561Sobrien arrange for dynamic relocs. It is not required for the 4651130561Sobrien particular common case of linking non PIC code, even when linking 4652130561Sobrien against shared libraries, but unfortunately there is no way of 4653130561Sobrien knowing whether an object file has been compiled PIC or not. 4654130561Sobrien Looking through the relocs is not particularly time consuming. 4655130561Sobrien The problem is that we must either (1) keep the relocs in memory, 4656130561Sobrien which causes the linker to require additional runtime memory or 4657130561Sobrien (2) read the relocs twice from the input file, which wastes time. 4658130561Sobrien This would be a good case for using mmap. 4659130561Sobrien 4660130561Sobrien I have no idea how to handle linking PIC code into a file of a 4661130561Sobrien different format. It probably can't be done. */ 4662130561Sobrien if (! dynamic 4663218822Sdim && is_elf_hash_table (htab) 4664218822Sdim && bed->check_relocs != NULL 4665218822Sdim && (*bed->relocs_compatible) (abfd->xvec, htab->root.creator)) 4666130561Sobrien { 4667130561Sobrien asection *o; 4668130561Sobrien 4669130561Sobrien for (o = abfd->sections; o != NULL; o = o->next) 4670130561Sobrien { 4671130561Sobrien Elf_Internal_Rela *internal_relocs; 4672130561Sobrien bfd_boolean ok; 4673130561Sobrien 4674130561Sobrien if ((o->flags & SEC_RELOC) == 0 4675130561Sobrien || o->reloc_count == 0 4676130561Sobrien || ((info->strip == strip_all || info->strip == strip_debugger) 4677130561Sobrien && (o->flags & SEC_DEBUGGING) != 0) 4678130561Sobrien || bfd_is_abs_section (o->output_section)) 4679130561Sobrien continue; 4680130561Sobrien 4681130561Sobrien internal_relocs = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, 4682130561Sobrien info->keep_memory); 4683130561Sobrien if (internal_relocs == NULL) 4684130561Sobrien goto error_return; 4685130561Sobrien 4686218822Sdim ok = (*bed->check_relocs) (abfd, info, o, internal_relocs); 4687130561Sobrien 4688130561Sobrien if (elf_section_data (o)->relocs != internal_relocs) 4689130561Sobrien free (internal_relocs); 4690130561Sobrien 4691130561Sobrien if (! ok) 4692130561Sobrien goto error_return; 4693130561Sobrien } 4694130561Sobrien } 4695130561Sobrien 4696130561Sobrien /* If this is a non-traditional link, try to optimize the handling 4697130561Sobrien of the .stab/.stabstr sections. */ 4698130561Sobrien if (! dynamic 4699130561Sobrien && ! info->traditional_format 4700218822Sdim && is_elf_hash_table (htab) 4701130561Sobrien && (info->strip != strip_all && info->strip != strip_debugger)) 4702130561Sobrien { 4703130561Sobrien asection *stabstr; 4704130561Sobrien 4705130561Sobrien stabstr = bfd_get_section_by_name (abfd, ".stabstr"); 4706130561Sobrien if (stabstr != NULL) 4707130561Sobrien { 4708130561Sobrien bfd_size_type string_offset = 0; 4709130561Sobrien asection *stab; 4710130561Sobrien 4711130561Sobrien for (stab = abfd->sections; stab; stab = stab->next) 4712218822Sdim if (CONST_STRNEQ (stab->name, ".stab") 4713130561Sobrien && (!stab->name[5] || 4714130561Sobrien (stab->name[5] == '.' && ISDIGIT (stab->name[6]))) 4715130561Sobrien && (stab->flags & SEC_MERGE) == 0 4716130561Sobrien && !bfd_is_abs_section (stab->output_section)) 4717130561Sobrien { 4718130561Sobrien struct bfd_elf_section_data *secdata; 4719130561Sobrien 4720130561Sobrien secdata = elf_section_data (stab); 4721218822Sdim if (! _bfd_link_section_stabs (abfd, &htab->stab_info, stab, 4722218822Sdim stabstr, &secdata->sec_info, 4723130561Sobrien &string_offset)) 4724130561Sobrien goto error_return; 4725130561Sobrien if (secdata->sec_info) 4726130561Sobrien stab->sec_info_type = ELF_INFO_TYPE_STABS; 4727130561Sobrien } 4728130561Sobrien } 4729130561Sobrien } 4730130561Sobrien 4731218822Sdim if (is_elf_hash_table (htab) && add_needed) 4732130561Sobrien { 4733130561Sobrien /* Add this bfd to the loaded list. */ 4734130561Sobrien struct elf_link_loaded_list *n; 4735130561Sobrien 4736130561Sobrien n = bfd_alloc (abfd, sizeof (struct elf_link_loaded_list)); 4737130561Sobrien if (n == NULL) 4738130561Sobrien goto error_return; 4739130561Sobrien n->abfd = abfd; 4740218822Sdim n->next = htab->loaded; 4741218822Sdim htab->loaded = n; 4742130561Sobrien } 4743130561Sobrien 4744130561Sobrien return TRUE; 4745130561Sobrien 4746130561Sobrien error_free_vers: 4747218822Sdim if (old_tab != NULL) 4748218822Sdim free (old_tab); 4749130561Sobrien if (nondeflt_vers != NULL) 4750130561Sobrien free (nondeflt_vers); 4751130561Sobrien if (extversym != NULL) 4752130561Sobrien free (extversym); 4753130561Sobrien error_free_sym: 4754130561Sobrien if (isymbuf != NULL) 4755130561Sobrien free (isymbuf); 4756130561Sobrien error_return: 4757130561Sobrien return FALSE; 4758130561Sobrien} 4759130561Sobrien 4760218822Sdim/* Return the linker hash table entry of a symbol that might be 4761218822Sdim satisfied by an archive symbol. Return -1 on error. */ 4762218822Sdim 4763218822Sdimstruct elf_link_hash_entry * 4764218822Sdim_bfd_elf_archive_symbol_lookup (bfd *abfd, 4765218822Sdim struct bfd_link_info *info, 4766218822Sdim const char *name) 4767218822Sdim{ 4768218822Sdim struct elf_link_hash_entry *h; 4769218822Sdim char *p, *copy; 4770218822Sdim size_t len, first; 4771218822Sdim 4772218822Sdim h = elf_link_hash_lookup (elf_hash_table (info), name, FALSE, FALSE, FALSE); 4773218822Sdim if (h != NULL) 4774218822Sdim return h; 4775218822Sdim 4776218822Sdim /* If this is a default version (the name contains @@), look up the 4777218822Sdim symbol again with only one `@' as well as without the version. 4778218822Sdim The effect is that references to the symbol with and without the 4779218822Sdim version will be matched by the default symbol in the archive. */ 4780218822Sdim 4781218822Sdim p = strchr (name, ELF_VER_CHR); 4782218822Sdim if (p == NULL || p[1] != ELF_VER_CHR) 4783218822Sdim return h; 4784218822Sdim 4785218822Sdim /* First check with only one `@'. */ 4786218822Sdim len = strlen (name); 4787218822Sdim copy = bfd_alloc (abfd, len); 4788218822Sdim if (copy == NULL) 4789218822Sdim return (struct elf_link_hash_entry *) 0 - 1; 4790218822Sdim 4791218822Sdim first = p - name + 1; 4792218822Sdim memcpy (copy, name, first); 4793218822Sdim memcpy (copy + first, name + first + 1, len - first); 4794218822Sdim 4795218822Sdim h = elf_link_hash_lookup (elf_hash_table (info), copy, FALSE, FALSE, FALSE); 4796218822Sdim if (h == NULL) 4797218822Sdim { 4798218822Sdim /* We also need to check references to the symbol without the 4799218822Sdim version. */ 4800218822Sdim copy[first - 1] = '\0'; 4801218822Sdim h = elf_link_hash_lookup (elf_hash_table (info), copy, 4802218822Sdim FALSE, FALSE, FALSE); 4803218822Sdim } 4804218822Sdim 4805218822Sdim bfd_release (abfd, copy); 4806218822Sdim return h; 4807218822Sdim} 4808218822Sdim 4809130561Sobrien/* Add symbols from an ELF archive file to the linker hash table. We 4810130561Sobrien don't use _bfd_generic_link_add_archive_symbols because of a 4811130561Sobrien problem which arises on UnixWare. The UnixWare libc.so is an 4812130561Sobrien archive which includes an entry libc.so.1 which defines a bunch of 4813130561Sobrien symbols. The libc.so archive also includes a number of other 4814130561Sobrien object files, which also define symbols, some of which are the same 4815130561Sobrien as those defined in libc.so.1. Correct linking requires that we 4816130561Sobrien consider each object file in turn, and include it if it defines any 4817130561Sobrien symbols we need. _bfd_generic_link_add_archive_symbols does not do 4818130561Sobrien this; it looks through the list of undefined symbols, and includes 4819130561Sobrien any object file which defines them. When this algorithm is used on 4820130561Sobrien UnixWare, it winds up pulling in libc.so.1 early and defining a 4821130561Sobrien bunch of symbols. This means that some of the other objects in the 4822130561Sobrien archive are not included in the link, which is incorrect since they 4823130561Sobrien precede libc.so.1 in the archive. 4824130561Sobrien 4825130561Sobrien Fortunately, ELF archive handling is simpler than that done by 4826130561Sobrien _bfd_generic_link_add_archive_symbols, which has to allow for a.out 4827130561Sobrien oddities. In ELF, if we find a symbol in the archive map, and the 4828130561Sobrien symbol is currently undefined, we know that we must pull in that 4829130561Sobrien object file. 4830130561Sobrien 4831130561Sobrien Unfortunately, we do have to make multiple passes over the symbol 4832130561Sobrien table until nothing further is resolved. */ 4833130561Sobrien 4834130561Sobrienstatic bfd_boolean 4835130561Sobrienelf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) 4836130561Sobrien{ 4837130561Sobrien symindex c; 4838130561Sobrien bfd_boolean *defined = NULL; 4839130561Sobrien bfd_boolean *included = NULL; 4840130561Sobrien carsym *symdefs; 4841130561Sobrien bfd_boolean loop; 4842130561Sobrien bfd_size_type amt; 4843218822Sdim const struct elf_backend_data *bed; 4844218822Sdim struct elf_link_hash_entry * (*archive_symbol_lookup) 4845218822Sdim (bfd *, struct bfd_link_info *, const char *); 4846130561Sobrien 4847130561Sobrien if (! bfd_has_map (abfd)) 4848130561Sobrien { 4849130561Sobrien /* An empty archive is a special case. */ 4850130561Sobrien if (bfd_openr_next_archived_file (abfd, NULL) == NULL) 4851130561Sobrien return TRUE; 4852130561Sobrien bfd_set_error (bfd_error_no_armap); 4853130561Sobrien return FALSE; 4854130561Sobrien } 4855130561Sobrien 4856130561Sobrien /* Keep track of all symbols we know to be already defined, and all 4857130561Sobrien files we know to be already included. This is to speed up the 4858130561Sobrien second and subsequent passes. */ 4859130561Sobrien c = bfd_ardata (abfd)->symdef_count; 4860130561Sobrien if (c == 0) 4861130561Sobrien return TRUE; 4862130561Sobrien amt = c; 4863130561Sobrien amt *= sizeof (bfd_boolean); 4864130561Sobrien defined = bfd_zmalloc (amt); 4865130561Sobrien included = bfd_zmalloc (amt); 4866130561Sobrien if (defined == NULL || included == NULL) 4867130561Sobrien goto error_return; 4868130561Sobrien 4869130561Sobrien symdefs = bfd_ardata (abfd)->symdefs; 4870218822Sdim bed = get_elf_backend_data (abfd); 4871218822Sdim archive_symbol_lookup = bed->elf_backend_archive_symbol_lookup; 4872130561Sobrien 4873130561Sobrien do 4874130561Sobrien { 4875130561Sobrien file_ptr last; 4876130561Sobrien symindex i; 4877130561Sobrien carsym *symdef; 4878130561Sobrien carsym *symdefend; 4879130561Sobrien 4880130561Sobrien loop = FALSE; 4881130561Sobrien last = -1; 4882130561Sobrien 4883130561Sobrien symdef = symdefs; 4884130561Sobrien symdefend = symdef + c; 4885130561Sobrien for (i = 0; symdef < symdefend; symdef++, i++) 4886130561Sobrien { 4887107492Sobrien struct elf_link_hash_entry *h; 4888130561Sobrien bfd *element; 4889130561Sobrien struct bfd_link_hash_entry *undefs_tail; 4890130561Sobrien symindex mark; 4891107492Sobrien 4892130561Sobrien if (defined[i] || included[i]) 4893130561Sobrien continue; 4894130561Sobrien if (symdef->file_offset == last) 4895130561Sobrien { 4896130561Sobrien included[i] = TRUE; 4897130561Sobrien continue; 4898130561Sobrien } 489933965Sjdp 4900218822Sdim h = archive_symbol_lookup (abfd, info, symdef->name); 4901218822Sdim if (h == (struct elf_link_hash_entry *) 0 - 1) 4902218822Sdim goto error_return; 490333965Sjdp 4904130561Sobrien if (h == NULL) 4905130561Sobrien continue; 4906130561Sobrien 4907130561Sobrien if (h->root.type == bfd_link_hash_common) 4908130561Sobrien { 4909130561Sobrien /* We currently have a common symbol. The archive map contains 4910130561Sobrien a reference to this symbol, so we may want to include it. We 4911130561Sobrien only want to include it however, if this archive element 4912130561Sobrien contains a definition of the symbol, not just another common 4913130561Sobrien declaration of it. 4914130561Sobrien 4915130561Sobrien Unfortunately some archivers (including GNU ar) will put 4916130561Sobrien declarations of common symbols into their archive maps, as 4917130561Sobrien well as real definitions, so we cannot just go by the archive 4918130561Sobrien map alone. Instead we must read in the element's symbol 4919130561Sobrien table and check that to see what kind of symbol definition 4920130561Sobrien this is. */ 4921130561Sobrien if (! elf_link_is_defined_archive_symbol (abfd, symdef)) 4922130561Sobrien continue; 4923130561Sobrien } 4924130561Sobrien else if (h->root.type != bfd_link_hash_undefined) 4925130561Sobrien { 4926130561Sobrien if (h->root.type != bfd_link_hash_undefweak) 4927130561Sobrien defined[i] = TRUE; 4928130561Sobrien continue; 4929130561Sobrien } 4930130561Sobrien 4931130561Sobrien /* We need to include this archive member. */ 4932130561Sobrien element = _bfd_get_elt_at_filepos (abfd, symdef->file_offset); 4933130561Sobrien if (element == NULL) 4934130561Sobrien goto error_return; 4935130561Sobrien 4936130561Sobrien if (! bfd_check_format (element, bfd_object)) 4937130561Sobrien goto error_return; 4938130561Sobrien 4939130561Sobrien /* Doublecheck that we have not included this object 4940130561Sobrien already--it should be impossible, but there may be 4941130561Sobrien something wrong with the archive. */ 4942130561Sobrien if (element->archive_pass != 0) 4943130561Sobrien { 4944130561Sobrien bfd_set_error (bfd_error_bad_value); 4945130561Sobrien goto error_return; 4946130561Sobrien } 4947130561Sobrien element->archive_pass = 1; 4948130561Sobrien 4949130561Sobrien undefs_tail = info->hash->undefs_tail; 4950130561Sobrien 4951130561Sobrien if (! (*info->callbacks->add_archive_element) (info, element, 4952130561Sobrien symdef->name)) 4953130561Sobrien goto error_return; 4954130561Sobrien if (! bfd_link_add_symbols (element, info)) 4955130561Sobrien goto error_return; 4956130561Sobrien 4957130561Sobrien /* If there are any new undefined symbols, we need to make 4958130561Sobrien another pass through the archive in order to see whether 4959130561Sobrien they can be defined. FIXME: This isn't perfect, because 4960130561Sobrien common symbols wind up on undefs_tail and because an 4961130561Sobrien undefined symbol which is defined later on in this pass 4962130561Sobrien does not require another pass. This isn't a bug, but it 4963130561Sobrien does make the code less efficient than it could be. */ 4964130561Sobrien if (undefs_tail != info->hash->undefs_tail) 4965130561Sobrien loop = TRUE; 4966130561Sobrien 4967130561Sobrien /* Look backward to mark all symbols from this object file 4968130561Sobrien which we have already seen in this pass. */ 4969130561Sobrien mark = i; 4970130561Sobrien do 4971130561Sobrien { 4972130561Sobrien included[mark] = TRUE; 4973130561Sobrien if (mark == 0) 4974130561Sobrien break; 4975130561Sobrien --mark; 4976130561Sobrien } 4977130561Sobrien while (symdefs[mark].file_offset == symdef->file_offset); 4978130561Sobrien 4979130561Sobrien /* We mark subsequent symbols from this object file as we go 4980130561Sobrien on through the loop. */ 4981130561Sobrien last = symdef->file_offset; 498233965Sjdp } 498333965Sjdp } 4984130561Sobrien while (loop); 498533965Sjdp 4986130561Sobrien free (defined); 4987130561Sobrien free (included); 498833965Sjdp 4989130561Sobrien return TRUE; 499033965Sjdp 4991130561Sobrien error_return: 4992130561Sobrien if (defined != NULL) 4993130561Sobrien free (defined); 4994130561Sobrien if (included != NULL) 4995130561Sobrien free (included); 4996130561Sobrien return FALSE; 4997130561Sobrien} 4998130561Sobrien 4999130561Sobrien/* Given an ELF BFD, add symbols to the global hash table as 5000130561Sobrien appropriate. */ 5001130561Sobrien 5002130561Sobrienbfd_boolean 5003130561Sobrienbfd_elf_link_add_symbols (bfd *abfd, struct bfd_link_info *info) 5004130561Sobrien{ 5005130561Sobrien switch (bfd_get_format (abfd)) 5006130561Sobrien { 5007130561Sobrien case bfd_object: 5008130561Sobrien return elf_link_add_object_symbols (abfd, info); 5009130561Sobrien case bfd_archive: 5010130561Sobrien return elf_link_add_archive_symbols (abfd, info); 5011130561Sobrien default: 5012130561Sobrien bfd_set_error (bfd_error_wrong_format); 5013130561Sobrien return FALSE; 5014130561Sobrien } 5015130561Sobrien} 5016130561Sobrien 5017130561Sobrien/* This function will be called though elf_link_hash_traverse to store 5018130561Sobrien all hash value of the exported symbols in an array. */ 5019130561Sobrien 5020130561Sobrienstatic bfd_boolean 5021130561Sobrienelf_collect_hash_codes (struct elf_link_hash_entry *h, void *data) 5022130561Sobrien{ 5023130561Sobrien unsigned long **valuep = data; 5024130561Sobrien const char *name; 5025130561Sobrien char *p; 5026130561Sobrien unsigned long ha; 5027130561Sobrien char *alc = NULL; 5028130561Sobrien 5029130561Sobrien if (h->root.type == bfd_link_hash_warning) 5030130561Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 5031130561Sobrien 5032130561Sobrien /* Ignore indirect symbols. These are added by the versioning code. */ 5033130561Sobrien if (h->dynindx == -1) 5034130561Sobrien return TRUE; 5035130561Sobrien 5036130561Sobrien name = h->root.root.string; 5037130561Sobrien p = strchr (name, ELF_VER_CHR); 5038130561Sobrien if (p != NULL) 5039130561Sobrien { 5040130561Sobrien alc = bfd_malloc (p - name + 1); 5041130561Sobrien memcpy (alc, name, p - name); 5042130561Sobrien alc[p - name] = '\0'; 5043130561Sobrien name = alc; 5044130561Sobrien } 5045130561Sobrien 5046130561Sobrien /* Compute the hash value. */ 5047130561Sobrien ha = bfd_elf_hash (name); 5048130561Sobrien 5049130561Sobrien /* Store the found hash value in the array given as the argument. */ 5050130561Sobrien *(*valuep)++ = ha; 5051130561Sobrien 5052130561Sobrien /* And store it in the struct so that we can put it in the hash table 5053130561Sobrien later. */ 5054218822Sdim h->u.elf_hash_value = ha; 5055130561Sobrien 5056130561Sobrien if (alc != NULL) 5057130561Sobrien free (alc); 5058130561Sobrien 5059130561Sobrien return TRUE; 5060130561Sobrien} 5061130561Sobrien 5062218822Sdimstruct collect_gnu_hash_codes 5063218822Sdim{ 5064218822Sdim bfd *output_bfd; 5065218822Sdim const struct elf_backend_data *bed; 5066218822Sdim unsigned long int nsyms; 5067218822Sdim unsigned long int maskbits; 5068218822Sdim unsigned long int *hashcodes; 5069218822Sdim unsigned long int *hashval; 5070218822Sdim unsigned long int *indx; 5071218822Sdim unsigned long int *counts; 5072218822Sdim bfd_vma *bitmask; 5073218822Sdim bfd_byte *contents; 5074218822Sdim long int min_dynindx; 5075218822Sdim unsigned long int bucketcount; 5076218822Sdim unsigned long int symindx; 5077218822Sdim long int local_indx; 5078218822Sdim long int shift1, shift2; 5079218822Sdim unsigned long int mask; 5080218822Sdim}; 5081218822Sdim 5082218822Sdim/* This function will be called though elf_link_hash_traverse to store 5083218822Sdim all hash value of the exported symbols in an array. */ 5084218822Sdim 5085218822Sdimstatic bfd_boolean 5086218822Sdimelf_collect_gnu_hash_codes (struct elf_link_hash_entry *h, void *data) 5087218822Sdim{ 5088218822Sdim struct collect_gnu_hash_codes *s = data; 5089218822Sdim const char *name; 5090218822Sdim char *p; 5091218822Sdim unsigned long ha; 5092218822Sdim char *alc = NULL; 5093218822Sdim 5094218822Sdim if (h->root.type == bfd_link_hash_warning) 5095218822Sdim h = (struct elf_link_hash_entry *) h->root.u.i.link; 5096218822Sdim 5097218822Sdim /* Ignore indirect symbols. These are added by the versioning code. */ 5098218822Sdim if (h->dynindx == -1) 5099218822Sdim return TRUE; 5100218822Sdim 5101218822Sdim /* Ignore also local symbols and undefined symbols. */ 5102218822Sdim if (! (*s->bed->elf_hash_symbol) (h)) 5103218822Sdim return TRUE; 5104218822Sdim 5105218822Sdim name = h->root.root.string; 5106218822Sdim p = strchr (name, ELF_VER_CHR); 5107218822Sdim if (p != NULL) 5108218822Sdim { 5109218822Sdim alc = bfd_malloc (p - name + 1); 5110218822Sdim memcpy (alc, name, p - name); 5111218822Sdim alc[p - name] = '\0'; 5112218822Sdim name = alc; 5113218822Sdim } 5114218822Sdim 5115218822Sdim /* Compute the hash value. */ 5116218822Sdim ha = bfd_elf_gnu_hash (name); 5117218822Sdim 5118218822Sdim /* Store the found hash value in the array for compute_bucket_count, 5119218822Sdim and also for .dynsym reordering purposes. */ 5120218822Sdim s->hashcodes[s->nsyms] = ha; 5121218822Sdim s->hashval[h->dynindx] = ha; 5122218822Sdim ++s->nsyms; 5123218822Sdim if (s->min_dynindx < 0 || s->min_dynindx > h->dynindx) 5124218822Sdim s->min_dynindx = h->dynindx; 5125218822Sdim 5126218822Sdim if (alc != NULL) 5127218822Sdim free (alc); 5128218822Sdim 5129218822Sdim return TRUE; 5130218822Sdim} 5131218822Sdim 5132218822Sdim/* This function will be called though elf_link_hash_traverse to do 5133218822Sdim final dynaminc symbol renumbering. */ 5134218822Sdim 5135218822Sdimstatic bfd_boolean 5136218822Sdimelf_renumber_gnu_hash_syms (struct elf_link_hash_entry *h, void *data) 5137218822Sdim{ 5138218822Sdim struct collect_gnu_hash_codes *s = data; 5139218822Sdim unsigned long int bucket; 5140218822Sdim unsigned long int val; 5141218822Sdim 5142218822Sdim if (h->root.type == bfd_link_hash_warning) 5143218822Sdim h = (struct elf_link_hash_entry *) h->root.u.i.link; 5144218822Sdim 5145218822Sdim /* Ignore indirect symbols. */ 5146218822Sdim if (h->dynindx == -1) 5147218822Sdim return TRUE; 5148218822Sdim 5149218822Sdim /* Ignore also local symbols and undefined symbols. */ 5150218822Sdim if (! (*s->bed->elf_hash_symbol) (h)) 5151218822Sdim { 5152218822Sdim if (h->dynindx >= s->min_dynindx) 5153218822Sdim h->dynindx = s->local_indx++; 5154218822Sdim return TRUE; 5155218822Sdim } 5156218822Sdim 5157218822Sdim bucket = s->hashval[h->dynindx] % s->bucketcount; 5158218822Sdim val = (s->hashval[h->dynindx] >> s->shift1) 5159218822Sdim & ((s->maskbits >> s->shift1) - 1); 5160218822Sdim s->bitmask[val] |= ((bfd_vma) 1) << (s->hashval[h->dynindx] & s->mask); 5161218822Sdim s->bitmask[val] 5162218822Sdim |= ((bfd_vma) 1) << ((s->hashval[h->dynindx] >> s->shift2) & s->mask); 5163218822Sdim val = s->hashval[h->dynindx] & ~(unsigned long int) 1; 5164218822Sdim if (s->counts[bucket] == 1) 5165218822Sdim /* Last element terminates the chain. */ 5166218822Sdim val |= 1; 5167218822Sdim bfd_put_32 (s->output_bfd, val, 5168218822Sdim s->contents + (s->indx[bucket] - s->symindx) * 4); 5169218822Sdim --s->counts[bucket]; 5170218822Sdim h->dynindx = s->indx[bucket]++; 5171218822Sdim return TRUE; 5172218822Sdim} 5173218822Sdim 5174218822Sdim/* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */ 5175218822Sdim 5176218822Sdimbfd_boolean 5177218822Sdim_bfd_elf_hash_symbol (struct elf_link_hash_entry *h) 5178218822Sdim{ 5179218822Sdim return !(h->forced_local 5180218822Sdim || h->root.type == bfd_link_hash_undefined 5181218822Sdim || h->root.type == bfd_link_hash_undefweak 5182218822Sdim || ((h->root.type == bfd_link_hash_defined 5183218822Sdim || h->root.type == bfd_link_hash_defweak) 5184218822Sdim && h->root.u.def.section->output_section == NULL)); 5185218822Sdim} 5186218822Sdim 5187130561Sobrien/* Array used to determine the number of hash table buckets to use 5188130561Sobrien based on the number of symbols there are. If there are fewer than 5189130561Sobrien 3 symbols we use 1 bucket, fewer than 17 symbols we use 3 buckets, 5190130561Sobrien fewer than 37 we use 17 buckets, and so forth. We never use more 5191130561Sobrien than 32771 buckets. */ 5192130561Sobrien 5193130561Sobrienstatic const size_t elf_buckets[] = 5194130561Sobrien{ 5195130561Sobrien 1, 3, 17, 37, 67, 97, 131, 197, 263, 521, 1031, 2053, 4099, 8209, 5196130561Sobrien 16411, 32771, 0 5197130561Sobrien}; 5198130561Sobrien 5199130561Sobrien/* Compute bucket count for hashing table. We do not use a static set 5200130561Sobrien of possible tables sizes anymore. Instead we determine for all 5201130561Sobrien possible reasonable sizes of the table the outcome (i.e., the 5202130561Sobrien number of collisions etc) and choose the best solution. The 5203130561Sobrien weighting functions are not too simple to allow the table to grow 5204130561Sobrien without bounds. Instead one of the weighting factors is the size. 5205130561Sobrien Therefore the result is always a good payoff between few collisions 5206130561Sobrien (= short chain lengths) and table size. */ 5207130561Sobrienstatic size_t 5208218822Sdimcompute_bucket_count (struct bfd_link_info *info, unsigned long int *hashcodes, 5209218822Sdim unsigned long int nsyms, int gnu_hash) 5210130561Sobrien{ 5211130561Sobrien size_t dynsymcount = elf_hash_table (info)->dynsymcount; 5212130561Sobrien size_t best_size = 0; 5213130561Sobrien unsigned long int i; 5214130561Sobrien bfd_size_type amt; 5215130561Sobrien 5216130561Sobrien /* We have a problem here. The following code to optimize the table 5217130561Sobrien size requires an integer type with more the 32 bits. If 5218130561Sobrien BFD_HOST_U_64_BIT is set we know about such a type. */ 5219130561Sobrien#ifdef BFD_HOST_U_64_BIT 5220130561Sobrien if (info->optimize) 5221130561Sobrien { 5222130561Sobrien size_t minsize; 5223130561Sobrien size_t maxsize; 5224130561Sobrien BFD_HOST_U_64_BIT best_chlen = ~((BFD_HOST_U_64_BIT) 0); 5225130561Sobrien bfd *dynobj = elf_hash_table (info)->dynobj; 5226130561Sobrien const struct elf_backend_data *bed = get_elf_backend_data (dynobj); 5227218822Sdim unsigned long int *counts; 5228130561Sobrien 5229130561Sobrien /* Possible optimization parameters: if we have NSYMS symbols we say 5230130561Sobrien that the hashing table must at least have NSYMS/4 and at most 5231130561Sobrien 2*NSYMS buckets. */ 5232130561Sobrien minsize = nsyms / 4; 5233130561Sobrien if (minsize == 0) 5234130561Sobrien minsize = 1; 5235130561Sobrien best_size = maxsize = nsyms * 2; 5236218822Sdim if (gnu_hash) 5237218822Sdim { 5238218822Sdim if (minsize < 2) 5239218822Sdim minsize = 2; 5240218822Sdim if ((best_size & 31) == 0) 5241218822Sdim ++best_size; 5242218822Sdim } 5243130561Sobrien 5244130561Sobrien /* Create array where we count the collisions in. We must use bfd_malloc 5245130561Sobrien since the size could be large. */ 5246130561Sobrien amt = maxsize; 5247130561Sobrien amt *= sizeof (unsigned long int); 5248130561Sobrien counts = bfd_malloc (amt); 5249130561Sobrien if (counts == NULL) 5250218822Sdim return 0; 5251130561Sobrien 5252130561Sobrien /* Compute the "optimal" size for the hash table. The criteria is a 5253130561Sobrien minimal chain length. The minor criteria is (of course) the size 5254130561Sobrien of the table. */ 5255130561Sobrien for (i = minsize; i < maxsize; ++i) 5256130561Sobrien { 5257130561Sobrien /* Walk through the array of hashcodes and count the collisions. */ 5258130561Sobrien BFD_HOST_U_64_BIT max; 5259130561Sobrien unsigned long int j; 5260130561Sobrien unsigned long int fact; 5261130561Sobrien 5262218822Sdim if (gnu_hash && (i & 31) == 0) 5263218822Sdim continue; 5264218822Sdim 5265130561Sobrien memset (counts, '\0', i * sizeof (unsigned long int)); 5266130561Sobrien 5267130561Sobrien /* Determine how often each hash bucket is used. */ 5268130561Sobrien for (j = 0; j < nsyms; ++j) 5269130561Sobrien ++counts[hashcodes[j] % i]; 5270130561Sobrien 5271130561Sobrien /* For the weight function we need some information about the 5272130561Sobrien pagesize on the target. This is information need not be 100% 5273130561Sobrien accurate. Since this information is not available (so far) we 5274130561Sobrien define it here to a reasonable default value. If it is crucial 5275130561Sobrien to have a better value some day simply define this value. */ 5276130561Sobrien# ifndef BFD_TARGET_PAGESIZE 5277130561Sobrien# define BFD_TARGET_PAGESIZE (4096) 5278130561Sobrien# endif 5279130561Sobrien 5280218822Sdim /* We in any case need 2 + DYNSYMCOUNT entries for the size values 5281218822Sdim and the chains. */ 5282218822Sdim max = (2 + dynsymcount) * bed->s->sizeof_hash_entry; 5283130561Sobrien 5284130561Sobrien# if 1 5285130561Sobrien /* Variant 1: optimize for short chains. We add the squares 5286130561Sobrien of all the chain lengths (which favors many small chain 5287130561Sobrien over a few long chains). */ 5288130561Sobrien for (j = 0; j < i; ++j) 5289130561Sobrien max += counts[j] * counts[j]; 5290130561Sobrien 5291130561Sobrien /* This adds penalties for the overall size of the table. */ 5292218822Sdim fact = i / (BFD_TARGET_PAGESIZE / bed->s->sizeof_hash_entry) + 1; 5293130561Sobrien max *= fact * fact; 5294130561Sobrien# else 5295130561Sobrien /* Variant 2: Optimize a lot more for small table. Here we 5296130561Sobrien also add squares of the size but we also add penalties for 5297130561Sobrien empty slots (the +1 term). */ 5298130561Sobrien for (j = 0; j < i; ++j) 5299130561Sobrien max += (1 + counts[j]) * (1 + counts[j]); 5300130561Sobrien 5301130561Sobrien /* The overall size of the table is considered, but not as 5302130561Sobrien strong as in variant 1, where it is squared. */ 5303218822Sdim fact = i / (BFD_TARGET_PAGESIZE / bed->s->sizeof_hash_entry) + 1; 5304130561Sobrien max *= fact; 5305130561Sobrien# endif 5306130561Sobrien 5307130561Sobrien /* Compare with current best results. */ 5308130561Sobrien if (max < best_chlen) 5309130561Sobrien { 5310130561Sobrien best_chlen = max; 5311130561Sobrien best_size = i; 5312130561Sobrien } 5313130561Sobrien } 5314130561Sobrien 5315130561Sobrien free (counts); 5316130561Sobrien } 5317130561Sobrien else 5318130561Sobrien#endif /* defined (BFD_HOST_U_64_BIT) */ 5319130561Sobrien { 5320130561Sobrien /* This is the fallback solution if no 64bit type is available or if we 5321130561Sobrien are not supposed to spend much time on optimizations. We select the 5322130561Sobrien bucket count using a fixed set of numbers. */ 5323130561Sobrien for (i = 0; elf_buckets[i] != 0; i++) 5324130561Sobrien { 5325130561Sobrien best_size = elf_buckets[i]; 5326218822Sdim if (nsyms < elf_buckets[i + 1]) 5327130561Sobrien break; 5328130561Sobrien } 5329218822Sdim if (gnu_hash && best_size < 2) 5330218822Sdim best_size = 2; 5331130561Sobrien } 5332130561Sobrien 5333130561Sobrien return best_size; 5334130561Sobrien} 5335130561Sobrien 5336130561Sobrien/* Set up the sizes and contents of the ELF dynamic sections. This is 5337130561Sobrien called by the ELF linker emulation before_allocation routine. We 5338130561Sobrien must set the sizes of the sections before the linker sets the 5339130561Sobrien addresses of the various sections. */ 5340130561Sobrien 5341130561Sobrienbfd_boolean 5342130561Sobrienbfd_elf_size_dynamic_sections (bfd *output_bfd, 5343130561Sobrien const char *soname, 5344130561Sobrien const char *rpath, 5345130561Sobrien const char *filter_shlib, 5346130561Sobrien const char * const *auxiliary_filters, 5347130561Sobrien struct bfd_link_info *info, 5348130561Sobrien asection **sinterpptr, 5349130561Sobrien struct bfd_elf_version_tree *verdefs) 5350130561Sobrien{ 5351130561Sobrien bfd_size_type soname_indx; 5352130561Sobrien bfd *dynobj; 5353130561Sobrien const struct elf_backend_data *bed; 5354130561Sobrien struct elf_assign_sym_version_info asvinfo; 5355130561Sobrien 5356130561Sobrien *sinterpptr = NULL; 5357130561Sobrien 5358130561Sobrien soname_indx = (bfd_size_type) -1; 5359130561Sobrien 5360130561Sobrien if (!is_elf_hash_table (info->hash)) 5361130561Sobrien return TRUE; 5362130561Sobrien 5363218822Sdim bed = get_elf_backend_data (output_bfd); 5364218822Sdim elf_tdata (output_bfd)->relro = info->relro; 5365130561Sobrien if (info->execstack) 5366130561Sobrien elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X; 5367130561Sobrien else if (info->noexecstack) 5368130561Sobrien elf_tdata (output_bfd)->stack_flags = PF_R | PF_W; 5369130561Sobrien else 5370130561Sobrien { 5371130561Sobrien bfd *inputobj; 5372130561Sobrien asection *notesec = NULL; 5373130561Sobrien int exec = 0; 5374130561Sobrien 5375130561Sobrien for (inputobj = info->input_bfds; 5376130561Sobrien inputobj; 5377130561Sobrien inputobj = inputobj->link_next) 5378130561Sobrien { 5379130561Sobrien asection *s; 5380130561Sobrien 5381218822Sdim if (inputobj->flags & (DYNAMIC | BFD_LINKER_CREATED)) 5382130561Sobrien continue; 5383130561Sobrien s = bfd_get_section_by_name (inputobj, ".note.GNU-stack"); 5384130561Sobrien if (s) 5385130561Sobrien { 5386130561Sobrien if (s->flags & SEC_CODE) 5387130561Sobrien exec = PF_X; 5388130561Sobrien notesec = s; 5389130561Sobrien } 5390218822Sdim else if (bed->default_execstack) 5391130561Sobrien exec = PF_X; 5392130561Sobrien } 5393130561Sobrien if (notesec) 5394130561Sobrien { 5395130561Sobrien elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | exec; 5396130561Sobrien if (exec && info->relocatable 5397130561Sobrien && notesec->output_section != bfd_abs_section_ptr) 5398130561Sobrien notesec->output_section->flags |= SEC_CODE; 5399130561Sobrien } 5400130561Sobrien } 5401130561Sobrien 5402130561Sobrien /* Any syms created from now on start with -1 in 5403130561Sobrien got.refcount/offset and plt.refcount/offset. */ 5404218822Sdim elf_hash_table (info)->init_got_refcount 5405218822Sdim = elf_hash_table (info)->init_got_offset; 5406218822Sdim elf_hash_table (info)->init_plt_refcount 5407218822Sdim = elf_hash_table (info)->init_plt_offset; 5408130561Sobrien 5409130561Sobrien /* The backend may have to create some sections regardless of whether 5410130561Sobrien we're dynamic or not. */ 5411130561Sobrien if (bed->elf_backend_always_size_sections 5412130561Sobrien && ! (*bed->elf_backend_always_size_sections) (output_bfd, info)) 5413130561Sobrien return FALSE; 5414130561Sobrien 5415218822Sdim if (! _bfd_elf_maybe_strip_eh_frame_hdr (info)) 5416218822Sdim return FALSE; 5417218822Sdim 5418130561Sobrien dynobj = elf_hash_table (info)->dynobj; 5419130561Sobrien 5420130561Sobrien /* If there were no dynamic objects in the link, there is nothing to 5421130561Sobrien do here. */ 5422130561Sobrien if (dynobj == NULL) 5423130561Sobrien return TRUE; 5424130561Sobrien 5425130561Sobrien if (elf_hash_table (info)->dynamic_sections_created) 5426130561Sobrien { 5427130561Sobrien struct elf_info_failed eif; 5428130561Sobrien struct elf_link_hash_entry *h; 5429130561Sobrien asection *dynstr; 5430130561Sobrien struct bfd_elf_version_tree *t; 5431130561Sobrien struct bfd_elf_version_expr *d; 5432218822Sdim asection *s; 5433130561Sobrien bfd_boolean all_defined; 5434130561Sobrien 5435130561Sobrien *sinterpptr = bfd_get_section_by_name (dynobj, ".interp"); 5436130561Sobrien BFD_ASSERT (*sinterpptr != NULL || !info->executable); 5437130561Sobrien 5438130561Sobrien if (soname != NULL) 5439130561Sobrien { 5440130561Sobrien soname_indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, 5441130561Sobrien soname, TRUE); 5442130561Sobrien if (soname_indx == (bfd_size_type) -1 5443130561Sobrien || !_bfd_elf_add_dynamic_entry (info, DT_SONAME, soname_indx)) 5444130561Sobrien return FALSE; 5445130561Sobrien } 5446130561Sobrien 5447130561Sobrien if (info->symbolic) 5448130561Sobrien { 5449130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_SYMBOLIC, 0)) 5450130561Sobrien return FALSE; 5451130561Sobrien info->flags |= DF_SYMBOLIC; 5452130561Sobrien } 5453130561Sobrien 5454130561Sobrien if (rpath != NULL) 5455130561Sobrien { 5456130561Sobrien bfd_size_type indx; 5457130561Sobrien 5458130561Sobrien indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, rpath, 5459130561Sobrien TRUE); 5460130561Sobrien if (indx == (bfd_size_type) -1 5461130561Sobrien || !_bfd_elf_add_dynamic_entry (info, DT_RPATH, indx)) 5462130561Sobrien return FALSE; 5463130561Sobrien 5464130561Sobrien if (info->new_dtags) 5465130561Sobrien { 5466130561Sobrien _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr, indx); 5467130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_RUNPATH, indx)) 5468130561Sobrien return FALSE; 5469130561Sobrien } 5470130561Sobrien } 5471130561Sobrien 5472130561Sobrien if (filter_shlib != NULL) 5473130561Sobrien { 5474130561Sobrien bfd_size_type indx; 5475130561Sobrien 5476130561Sobrien indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, 5477130561Sobrien filter_shlib, TRUE); 5478130561Sobrien if (indx == (bfd_size_type) -1 5479130561Sobrien || !_bfd_elf_add_dynamic_entry (info, DT_FILTER, indx)) 5480130561Sobrien return FALSE; 5481130561Sobrien } 5482130561Sobrien 5483130561Sobrien if (auxiliary_filters != NULL) 5484130561Sobrien { 5485130561Sobrien const char * const *p; 5486130561Sobrien 5487130561Sobrien for (p = auxiliary_filters; *p != NULL; p++) 5488130561Sobrien { 5489130561Sobrien bfd_size_type indx; 5490130561Sobrien 5491130561Sobrien indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, 5492130561Sobrien *p, TRUE); 5493130561Sobrien if (indx == (bfd_size_type) -1 5494130561Sobrien || !_bfd_elf_add_dynamic_entry (info, DT_AUXILIARY, indx)) 5495130561Sobrien return FALSE; 5496130561Sobrien } 5497130561Sobrien } 5498130561Sobrien 5499130561Sobrien eif.info = info; 5500130561Sobrien eif.verdefs = verdefs; 5501130561Sobrien eif.failed = FALSE; 5502130561Sobrien 5503130561Sobrien /* If we are supposed to export all symbols into the dynamic symbol 5504130561Sobrien table (this is not the normal case), then do so. */ 5505218822Sdim if (info->export_dynamic 5506218822Sdim || (info->executable && info->dynamic)) 5507130561Sobrien { 5508130561Sobrien elf_link_hash_traverse (elf_hash_table (info), 5509130561Sobrien _bfd_elf_export_symbol, 5510130561Sobrien &eif); 5511130561Sobrien if (eif.failed) 5512130561Sobrien return FALSE; 5513130561Sobrien } 5514130561Sobrien 5515130561Sobrien /* Make all global versions with definition. */ 5516130561Sobrien for (t = verdefs; t != NULL; t = t->next) 5517130561Sobrien for (d = t->globals.list; d != NULL; d = d->next) 5518130561Sobrien if (!d->symver && d->symbol) 5519130561Sobrien { 5520130561Sobrien const char *verstr, *name; 5521130561Sobrien size_t namelen, verlen, newlen; 5522130561Sobrien char *newname, *p; 5523130561Sobrien struct elf_link_hash_entry *newh; 5524130561Sobrien 5525130561Sobrien name = d->symbol; 5526130561Sobrien namelen = strlen (name); 5527130561Sobrien verstr = t->name; 5528130561Sobrien verlen = strlen (verstr); 5529130561Sobrien newlen = namelen + verlen + 3; 5530130561Sobrien 5531130561Sobrien newname = bfd_malloc (newlen); 5532130561Sobrien if (newname == NULL) 5533130561Sobrien return FALSE; 5534130561Sobrien memcpy (newname, name, namelen); 5535130561Sobrien 5536130561Sobrien /* Check the hidden versioned definition. */ 5537130561Sobrien p = newname + namelen; 5538130561Sobrien *p++ = ELF_VER_CHR; 5539130561Sobrien memcpy (p, verstr, verlen + 1); 5540130561Sobrien newh = elf_link_hash_lookup (elf_hash_table (info), 5541130561Sobrien newname, FALSE, FALSE, 5542130561Sobrien FALSE); 5543130561Sobrien if (newh == NULL 5544130561Sobrien || (newh->root.type != bfd_link_hash_defined 5545130561Sobrien && newh->root.type != bfd_link_hash_defweak)) 5546130561Sobrien { 5547130561Sobrien /* Check the default versioned definition. */ 5548130561Sobrien *p++ = ELF_VER_CHR; 5549130561Sobrien memcpy (p, verstr, verlen + 1); 5550130561Sobrien newh = elf_link_hash_lookup (elf_hash_table (info), 5551130561Sobrien newname, FALSE, FALSE, 5552130561Sobrien FALSE); 5553130561Sobrien } 5554130561Sobrien free (newname); 5555130561Sobrien 5556130561Sobrien /* Mark this version if there is a definition and it is 5557130561Sobrien not defined in a shared object. */ 5558130561Sobrien if (newh != NULL 5559218822Sdim && !newh->def_dynamic 5560130561Sobrien && (newh->root.type == bfd_link_hash_defined 5561130561Sobrien || newh->root.type == bfd_link_hash_defweak)) 5562130561Sobrien d->symver = 1; 5563130561Sobrien } 5564130561Sobrien 5565130561Sobrien /* Attach all the symbols to their version information. */ 5566130561Sobrien asvinfo.output_bfd = output_bfd; 5567130561Sobrien asvinfo.info = info; 5568130561Sobrien asvinfo.verdefs = verdefs; 5569130561Sobrien asvinfo.failed = FALSE; 5570130561Sobrien 5571130561Sobrien elf_link_hash_traverse (elf_hash_table (info), 5572130561Sobrien _bfd_elf_link_assign_sym_version, 5573130561Sobrien &asvinfo); 5574130561Sobrien if (asvinfo.failed) 5575130561Sobrien return FALSE; 5576130561Sobrien 5577130561Sobrien if (!info->allow_undefined_version) 5578130561Sobrien { 5579130561Sobrien /* Check if all global versions have a definition. */ 5580130561Sobrien all_defined = TRUE; 5581130561Sobrien for (t = verdefs; t != NULL; t = t->next) 5582130561Sobrien for (d = t->globals.list; d != NULL; d = d->next) 5583130561Sobrien if (!d->symver && !d->script) 5584130561Sobrien { 5585130561Sobrien (*_bfd_error_handler) 5586130561Sobrien (_("%s: undefined version: %s"), 5587130561Sobrien d->pattern, t->name); 5588130561Sobrien all_defined = FALSE; 5589130561Sobrien } 5590130561Sobrien 5591130561Sobrien if (!all_defined) 5592130561Sobrien { 5593130561Sobrien bfd_set_error (bfd_error_bad_value); 5594130561Sobrien return FALSE; 5595130561Sobrien } 5596130561Sobrien } 5597130561Sobrien 5598130561Sobrien /* Find all symbols which were defined in a dynamic object and make 5599130561Sobrien the backend pick a reasonable value for them. */ 5600130561Sobrien elf_link_hash_traverse (elf_hash_table (info), 5601130561Sobrien _bfd_elf_adjust_dynamic_symbol, 5602130561Sobrien &eif); 5603130561Sobrien if (eif.failed) 5604130561Sobrien return FALSE; 5605130561Sobrien 5606130561Sobrien /* Add some entries to the .dynamic section. We fill in some of the 5607218822Sdim values later, in bfd_elf_final_link, but we must add the entries 5608130561Sobrien now so that we know the final size of the .dynamic section. */ 5609130561Sobrien 5610130561Sobrien /* If there are initialization and/or finalization functions to 5611130561Sobrien call then add the corresponding DT_INIT/DT_FINI entries. */ 5612130561Sobrien h = (info->init_function 5613130561Sobrien ? elf_link_hash_lookup (elf_hash_table (info), 5614130561Sobrien info->init_function, FALSE, 5615130561Sobrien FALSE, FALSE) 5616130561Sobrien : NULL); 5617130561Sobrien if (h != NULL 5618218822Sdim && (h->ref_regular 5619218822Sdim || h->def_regular)) 5620130561Sobrien { 5621130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_INIT, 0)) 5622130561Sobrien return FALSE; 5623130561Sobrien } 5624130561Sobrien h = (info->fini_function 5625130561Sobrien ? elf_link_hash_lookup (elf_hash_table (info), 5626130561Sobrien info->fini_function, FALSE, 5627130561Sobrien FALSE, FALSE) 5628130561Sobrien : NULL); 5629130561Sobrien if (h != NULL 5630218822Sdim && (h->ref_regular 5631218822Sdim || h->def_regular)) 5632130561Sobrien { 5633130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_FINI, 0)) 5634130561Sobrien return FALSE; 5635130561Sobrien } 5636130561Sobrien 5637218822Sdim s = bfd_get_section_by_name (output_bfd, ".preinit_array"); 5638218822Sdim if (s != NULL && s->linker_has_input) 5639130561Sobrien { 5640130561Sobrien /* DT_PREINIT_ARRAY is not allowed in shared library. */ 5641130561Sobrien if (! info->executable) 5642130561Sobrien { 5643130561Sobrien bfd *sub; 5644130561Sobrien asection *o; 5645130561Sobrien 5646130561Sobrien for (sub = info->input_bfds; sub != NULL; 5647130561Sobrien sub = sub->link_next) 5648218822Sdim if (bfd_get_flavour (sub) == bfd_target_elf_flavour) 5649218822Sdim for (o = sub->sections; o != NULL; o = o->next) 5650218822Sdim if (elf_section_data (o)->this_hdr.sh_type 5651218822Sdim == SHT_PREINIT_ARRAY) 5652218822Sdim { 5653218822Sdim (*_bfd_error_handler) 5654218822Sdim (_("%B: .preinit_array section is not allowed in DSO"), 5655218822Sdim sub); 5656218822Sdim break; 5657218822Sdim } 5658130561Sobrien 5659130561Sobrien bfd_set_error (bfd_error_nonrepresentable_section); 5660130561Sobrien return FALSE; 5661130561Sobrien } 5662130561Sobrien 5663130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_PREINIT_ARRAY, 0) 5664130561Sobrien || !_bfd_elf_add_dynamic_entry (info, DT_PREINIT_ARRAYSZ, 0)) 5665130561Sobrien return FALSE; 5666130561Sobrien } 5667218822Sdim s = bfd_get_section_by_name (output_bfd, ".init_array"); 5668218822Sdim if (s != NULL && s->linker_has_input) 5669130561Sobrien { 5670130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_INIT_ARRAY, 0) 5671130561Sobrien || !_bfd_elf_add_dynamic_entry (info, DT_INIT_ARRAYSZ, 0)) 5672130561Sobrien return FALSE; 5673130561Sobrien } 5674218822Sdim s = bfd_get_section_by_name (output_bfd, ".fini_array"); 5675218822Sdim if (s != NULL && s->linker_has_input) 5676130561Sobrien { 5677130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_FINI_ARRAY, 0) 5678130561Sobrien || !_bfd_elf_add_dynamic_entry (info, DT_FINI_ARRAYSZ, 0)) 5679130561Sobrien return FALSE; 5680130561Sobrien } 5681130561Sobrien 5682130561Sobrien dynstr = bfd_get_section_by_name (dynobj, ".dynstr"); 5683130561Sobrien /* If .dynstr is excluded from the link, we don't want any of 5684130561Sobrien these tags. Strictly, we should be checking each section 5685130561Sobrien individually; This quick check covers for the case where 5686130561Sobrien someone does a /DISCARD/ : { *(*) }. */ 5687130561Sobrien if (dynstr != NULL && dynstr->output_section != bfd_abs_section_ptr) 5688130561Sobrien { 5689130561Sobrien bfd_size_type strsize; 5690130561Sobrien 5691130561Sobrien strsize = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr); 5692218822Sdim if ((info->emit_hash 5693218822Sdim && !_bfd_elf_add_dynamic_entry (info, DT_HASH, 0)) 5694218822Sdim || (info->emit_gnu_hash 5695218822Sdim && !_bfd_elf_add_dynamic_entry (info, DT_GNU_HASH, 0)) 5696130561Sobrien || !_bfd_elf_add_dynamic_entry (info, DT_STRTAB, 0) 5697130561Sobrien || !_bfd_elf_add_dynamic_entry (info, DT_SYMTAB, 0) 5698130561Sobrien || !_bfd_elf_add_dynamic_entry (info, DT_STRSZ, strsize) 5699130561Sobrien || !_bfd_elf_add_dynamic_entry (info, DT_SYMENT, 5700130561Sobrien bed->s->sizeof_sym)) 5701130561Sobrien return FALSE; 5702130561Sobrien } 5703130561Sobrien } 5704130561Sobrien 5705130561Sobrien /* The backend must work out the sizes of all the other dynamic 5706130561Sobrien sections. */ 5707130561Sobrien if (bed->elf_backend_size_dynamic_sections 5708130561Sobrien && ! (*bed->elf_backend_size_dynamic_sections) (output_bfd, info)) 5709130561Sobrien return FALSE; 5710130561Sobrien 5711130561Sobrien if (elf_hash_table (info)->dynamic_sections_created) 5712130561Sobrien { 5713218822Sdim unsigned long section_sym_count; 5714130561Sobrien asection *s; 5715130561Sobrien 5716130561Sobrien /* Set up the version definition section. */ 5717130561Sobrien s = bfd_get_section_by_name (dynobj, ".gnu.version_d"); 5718130561Sobrien BFD_ASSERT (s != NULL); 5719130561Sobrien 5720130561Sobrien /* We may have created additional version definitions if we are 5721130561Sobrien just linking a regular application. */ 5722130561Sobrien verdefs = asvinfo.verdefs; 5723130561Sobrien 5724130561Sobrien /* Skip anonymous version tag. */ 5725130561Sobrien if (verdefs != NULL && verdefs->vernum == 0) 5726130561Sobrien verdefs = verdefs->next; 5727130561Sobrien 5728218822Sdim if (verdefs == NULL && !info->create_default_symver) 5729218822Sdim s->flags |= SEC_EXCLUDE; 5730130561Sobrien else 5731130561Sobrien { 5732130561Sobrien unsigned int cdefs; 5733130561Sobrien bfd_size_type size; 5734130561Sobrien struct bfd_elf_version_tree *t; 5735130561Sobrien bfd_byte *p; 5736130561Sobrien Elf_Internal_Verdef def; 5737130561Sobrien Elf_Internal_Verdaux defaux; 5738218822Sdim struct bfd_link_hash_entry *bh; 5739218822Sdim struct elf_link_hash_entry *h; 5740218822Sdim const char *name; 5741130561Sobrien 5742130561Sobrien cdefs = 0; 5743130561Sobrien size = 0; 5744130561Sobrien 5745130561Sobrien /* Make space for the base version. */ 5746130561Sobrien size += sizeof (Elf_External_Verdef); 5747130561Sobrien size += sizeof (Elf_External_Verdaux); 5748130561Sobrien ++cdefs; 5749130561Sobrien 5750218822Sdim /* Make space for the default version. */ 5751218822Sdim if (info->create_default_symver) 5752218822Sdim { 5753218822Sdim size += sizeof (Elf_External_Verdef); 5754218822Sdim ++cdefs; 5755218822Sdim } 5756218822Sdim 5757130561Sobrien for (t = verdefs; t != NULL; t = t->next) 5758130561Sobrien { 5759130561Sobrien struct bfd_elf_version_deps *n; 5760130561Sobrien 5761130561Sobrien size += sizeof (Elf_External_Verdef); 5762130561Sobrien size += sizeof (Elf_External_Verdaux); 5763130561Sobrien ++cdefs; 5764130561Sobrien 5765130561Sobrien for (n = t->deps; n != NULL; n = n->next) 5766130561Sobrien size += sizeof (Elf_External_Verdaux); 5767130561Sobrien } 5768130561Sobrien 5769218822Sdim s->size = size; 5770218822Sdim s->contents = bfd_alloc (output_bfd, s->size); 5771218822Sdim if (s->contents == NULL && s->size != 0) 5772130561Sobrien return FALSE; 5773130561Sobrien 5774130561Sobrien /* Fill in the version definition section. */ 5775130561Sobrien 5776130561Sobrien p = s->contents; 5777130561Sobrien 5778130561Sobrien def.vd_version = VER_DEF_CURRENT; 5779130561Sobrien def.vd_flags = VER_FLG_BASE; 5780130561Sobrien def.vd_ndx = 1; 5781130561Sobrien def.vd_cnt = 1; 5782218822Sdim if (info->create_default_symver) 5783218822Sdim { 5784218822Sdim def.vd_aux = 2 * sizeof (Elf_External_Verdef); 5785218822Sdim def.vd_next = sizeof (Elf_External_Verdef); 5786218822Sdim } 5787218822Sdim else 5788218822Sdim { 5789218822Sdim def.vd_aux = sizeof (Elf_External_Verdef); 5790218822Sdim def.vd_next = (sizeof (Elf_External_Verdef) 5791218822Sdim + sizeof (Elf_External_Verdaux)); 5792218822Sdim } 5793130561Sobrien 5794130561Sobrien if (soname_indx != (bfd_size_type) -1) 5795130561Sobrien { 5796130561Sobrien _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr, 5797130561Sobrien soname_indx); 5798130561Sobrien def.vd_hash = bfd_elf_hash (soname); 5799130561Sobrien defaux.vda_name = soname_indx; 5800218822Sdim name = soname; 5801130561Sobrien } 5802130561Sobrien else 5803130561Sobrien { 5804130561Sobrien bfd_size_type indx; 5805130561Sobrien 5806218822Sdim name = lbasename (output_bfd->filename); 5807130561Sobrien def.vd_hash = bfd_elf_hash (name); 5808130561Sobrien indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, 5809130561Sobrien name, FALSE); 5810130561Sobrien if (indx == (bfd_size_type) -1) 5811130561Sobrien return FALSE; 5812130561Sobrien defaux.vda_name = indx; 5813130561Sobrien } 5814130561Sobrien defaux.vda_next = 0; 5815130561Sobrien 5816130561Sobrien _bfd_elf_swap_verdef_out (output_bfd, &def, 5817130561Sobrien (Elf_External_Verdef *) p); 5818130561Sobrien p += sizeof (Elf_External_Verdef); 5819218822Sdim if (info->create_default_symver) 5820218822Sdim { 5821218822Sdim /* Add a symbol representing this version. */ 5822218822Sdim bh = NULL; 5823218822Sdim if (! (_bfd_generic_link_add_one_symbol 5824218822Sdim (info, dynobj, name, BSF_GLOBAL, bfd_abs_section_ptr, 5825218822Sdim 0, NULL, FALSE, 5826218822Sdim get_elf_backend_data (dynobj)->collect, &bh))) 5827218822Sdim return FALSE; 5828218822Sdim h = (struct elf_link_hash_entry *) bh; 5829218822Sdim h->non_elf = 0; 5830218822Sdim h->def_regular = 1; 5831218822Sdim h->type = STT_OBJECT; 5832218822Sdim h->verinfo.vertree = NULL; 5833218822Sdim 5834218822Sdim if (! bfd_elf_link_record_dynamic_symbol (info, h)) 5835218822Sdim return FALSE; 5836218822Sdim 5837218822Sdim /* Create a duplicate of the base version with the same 5838218822Sdim aux block, but different flags. */ 5839218822Sdim def.vd_flags = 0; 5840218822Sdim def.vd_ndx = 2; 5841218822Sdim def.vd_aux = sizeof (Elf_External_Verdef); 5842218822Sdim if (verdefs) 5843218822Sdim def.vd_next = (sizeof (Elf_External_Verdef) 5844218822Sdim + sizeof (Elf_External_Verdaux)); 5845218822Sdim else 5846218822Sdim def.vd_next = 0; 5847218822Sdim _bfd_elf_swap_verdef_out (output_bfd, &def, 5848218822Sdim (Elf_External_Verdef *) p); 5849218822Sdim p += sizeof (Elf_External_Verdef); 5850218822Sdim } 5851130561Sobrien _bfd_elf_swap_verdaux_out (output_bfd, &defaux, 5852130561Sobrien (Elf_External_Verdaux *) p); 5853130561Sobrien p += sizeof (Elf_External_Verdaux); 5854130561Sobrien 5855130561Sobrien for (t = verdefs; t != NULL; t = t->next) 5856130561Sobrien { 5857130561Sobrien unsigned int cdeps; 5858130561Sobrien struct bfd_elf_version_deps *n; 5859130561Sobrien 5860130561Sobrien cdeps = 0; 5861130561Sobrien for (n = t->deps; n != NULL; n = n->next) 5862130561Sobrien ++cdeps; 5863130561Sobrien 5864130561Sobrien /* Add a symbol representing this version. */ 5865130561Sobrien bh = NULL; 5866130561Sobrien if (! (_bfd_generic_link_add_one_symbol 5867130561Sobrien (info, dynobj, t->name, BSF_GLOBAL, bfd_abs_section_ptr, 5868130561Sobrien 0, NULL, FALSE, 5869130561Sobrien get_elf_backend_data (dynobj)->collect, &bh))) 5870130561Sobrien return FALSE; 5871130561Sobrien h = (struct elf_link_hash_entry *) bh; 5872218822Sdim h->non_elf = 0; 5873218822Sdim h->def_regular = 1; 5874130561Sobrien h->type = STT_OBJECT; 5875130561Sobrien h->verinfo.vertree = t; 5876130561Sobrien 5877130561Sobrien if (! bfd_elf_link_record_dynamic_symbol (info, h)) 5878130561Sobrien return FALSE; 5879130561Sobrien 5880130561Sobrien def.vd_version = VER_DEF_CURRENT; 5881130561Sobrien def.vd_flags = 0; 5882130561Sobrien if (t->globals.list == NULL 5883130561Sobrien && t->locals.list == NULL 5884130561Sobrien && ! t->used) 5885130561Sobrien def.vd_flags |= VER_FLG_WEAK; 5886218822Sdim def.vd_ndx = t->vernum + (info->create_default_symver ? 2 : 1); 5887130561Sobrien def.vd_cnt = cdeps + 1; 5888130561Sobrien def.vd_hash = bfd_elf_hash (t->name); 5889130561Sobrien def.vd_aux = sizeof (Elf_External_Verdef); 5890130561Sobrien def.vd_next = 0; 5891130561Sobrien if (t->next != NULL) 5892130561Sobrien def.vd_next = (sizeof (Elf_External_Verdef) 5893130561Sobrien + (cdeps + 1) * sizeof (Elf_External_Verdaux)); 5894130561Sobrien 5895130561Sobrien _bfd_elf_swap_verdef_out (output_bfd, &def, 5896130561Sobrien (Elf_External_Verdef *) p); 5897130561Sobrien p += sizeof (Elf_External_Verdef); 5898130561Sobrien 5899130561Sobrien defaux.vda_name = h->dynstr_index; 5900130561Sobrien _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr, 5901130561Sobrien h->dynstr_index); 5902130561Sobrien defaux.vda_next = 0; 5903130561Sobrien if (t->deps != NULL) 5904130561Sobrien defaux.vda_next = sizeof (Elf_External_Verdaux); 5905130561Sobrien t->name_indx = defaux.vda_name; 5906130561Sobrien 5907130561Sobrien _bfd_elf_swap_verdaux_out (output_bfd, &defaux, 5908130561Sobrien (Elf_External_Verdaux *) p); 5909130561Sobrien p += sizeof (Elf_External_Verdaux); 5910130561Sobrien 5911130561Sobrien for (n = t->deps; n != NULL; n = n->next) 5912130561Sobrien { 5913130561Sobrien if (n->version_needed == NULL) 5914130561Sobrien { 5915130561Sobrien /* This can happen if there was an error in the 5916130561Sobrien version script. */ 5917130561Sobrien defaux.vda_name = 0; 5918130561Sobrien } 5919130561Sobrien else 5920130561Sobrien { 5921130561Sobrien defaux.vda_name = n->version_needed->name_indx; 5922130561Sobrien _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr, 5923130561Sobrien defaux.vda_name); 5924130561Sobrien } 5925130561Sobrien if (n->next == NULL) 5926130561Sobrien defaux.vda_next = 0; 5927130561Sobrien else 5928130561Sobrien defaux.vda_next = sizeof (Elf_External_Verdaux); 5929130561Sobrien 5930130561Sobrien _bfd_elf_swap_verdaux_out (output_bfd, &defaux, 5931130561Sobrien (Elf_External_Verdaux *) p); 5932130561Sobrien p += sizeof (Elf_External_Verdaux); 5933130561Sobrien } 5934130561Sobrien } 5935130561Sobrien 5936130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_VERDEF, 0) 5937130561Sobrien || !_bfd_elf_add_dynamic_entry (info, DT_VERDEFNUM, cdefs)) 5938130561Sobrien return FALSE; 5939130561Sobrien 5940130561Sobrien elf_tdata (output_bfd)->cverdefs = cdefs; 5941130561Sobrien } 5942130561Sobrien 5943130561Sobrien if ((info->new_dtags && info->flags) || (info->flags & DF_STATIC_TLS)) 5944130561Sobrien { 5945130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_FLAGS, info->flags)) 5946130561Sobrien return FALSE; 5947130561Sobrien } 5948130561Sobrien else if (info->flags & DF_BIND_NOW) 5949130561Sobrien { 5950130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_BIND_NOW, 0)) 5951130561Sobrien return FALSE; 5952130561Sobrien } 5953130561Sobrien 5954130561Sobrien if (info->flags_1) 5955130561Sobrien { 5956130561Sobrien if (info->executable) 5957130561Sobrien info->flags_1 &= ~ (DF_1_INITFIRST 5958130561Sobrien | DF_1_NODELETE 5959130561Sobrien | DF_1_NOOPEN); 5960130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_FLAGS_1, info->flags_1)) 5961130561Sobrien return FALSE; 5962130561Sobrien } 5963130561Sobrien 5964130561Sobrien /* Work out the size of the version reference section. */ 5965130561Sobrien 5966130561Sobrien s = bfd_get_section_by_name (dynobj, ".gnu.version_r"); 5967130561Sobrien BFD_ASSERT (s != NULL); 5968130561Sobrien { 5969130561Sobrien struct elf_find_verdep_info sinfo; 5970130561Sobrien 5971130561Sobrien sinfo.output_bfd = output_bfd; 5972130561Sobrien sinfo.info = info; 5973130561Sobrien sinfo.vers = elf_tdata (output_bfd)->cverdefs; 5974130561Sobrien if (sinfo.vers == 0) 5975130561Sobrien sinfo.vers = 1; 5976130561Sobrien sinfo.failed = FALSE; 5977130561Sobrien 5978130561Sobrien elf_link_hash_traverse (elf_hash_table (info), 5979130561Sobrien _bfd_elf_link_find_version_dependencies, 5980130561Sobrien &sinfo); 5981130561Sobrien 5982130561Sobrien if (elf_tdata (output_bfd)->verref == NULL) 5983218822Sdim s->flags |= SEC_EXCLUDE; 5984130561Sobrien else 5985130561Sobrien { 5986130561Sobrien Elf_Internal_Verneed *t; 5987130561Sobrien unsigned int size; 5988130561Sobrien unsigned int crefs; 5989130561Sobrien bfd_byte *p; 5990130561Sobrien 5991130561Sobrien /* Build the version definition section. */ 5992130561Sobrien size = 0; 5993130561Sobrien crefs = 0; 5994130561Sobrien for (t = elf_tdata (output_bfd)->verref; 5995130561Sobrien t != NULL; 5996130561Sobrien t = t->vn_nextref) 5997130561Sobrien { 5998130561Sobrien Elf_Internal_Vernaux *a; 5999130561Sobrien 6000130561Sobrien size += sizeof (Elf_External_Verneed); 6001130561Sobrien ++crefs; 6002130561Sobrien for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) 6003130561Sobrien size += sizeof (Elf_External_Vernaux); 6004130561Sobrien } 6005130561Sobrien 6006218822Sdim s->size = size; 6007218822Sdim s->contents = bfd_alloc (output_bfd, s->size); 6008130561Sobrien if (s->contents == NULL) 6009130561Sobrien return FALSE; 6010130561Sobrien 6011130561Sobrien p = s->contents; 6012130561Sobrien for (t = elf_tdata (output_bfd)->verref; 6013130561Sobrien t != NULL; 6014130561Sobrien t = t->vn_nextref) 6015130561Sobrien { 6016130561Sobrien unsigned int caux; 6017130561Sobrien Elf_Internal_Vernaux *a; 6018130561Sobrien bfd_size_type indx; 6019130561Sobrien 6020130561Sobrien caux = 0; 6021130561Sobrien for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) 6022130561Sobrien ++caux; 6023130561Sobrien 6024130561Sobrien t->vn_version = VER_NEED_CURRENT; 6025130561Sobrien t->vn_cnt = caux; 6026130561Sobrien indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, 6027130561Sobrien elf_dt_name (t->vn_bfd) != NULL 6028130561Sobrien ? elf_dt_name (t->vn_bfd) 6029218822Sdim : lbasename (t->vn_bfd->filename), 6030130561Sobrien FALSE); 6031130561Sobrien if (indx == (bfd_size_type) -1) 6032130561Sobrien return FALSE; 6033130561Sobrien t->vn_file = indx; 6034130561Sobrien t->vn_aux = sizeof (Elf_External_Verneed); 6035130561Sobrien if (t->vn_nextref == NULL) 6036130561Sobrien t->vn_next = 0; 6037130561Sobrien else 6038130561Sobrien t->vn_next = (sizeof (Elf_External_Verneed) 6039130561Sobrien + caux * sizeof (Elf_External_Vernaux)); 6040130561Sobrien 6041130561Sobrien _bfd_elf_swap_verneed_out (output_bfd, t, 6042130561Sobrien (Elf_External_Verneed *) p); 6043130561Sobrien p += sizeof (Elf_External_Verneed); 6044130561Sobrien 6045130561Sobrien for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) 6046130561Sobrien { 6047130561Sobrien a->vna_hash = bfd_elf_hash (a->vna_nodename); 6048130561Sobrien indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, 6049130561Sobrien a->vna_nodename, FALSE); 6050130561Sobrien if (indx == (bfd_size_type) -1) 6051130561Sobrien return FALSE; 6052130561Sobrien a->vna_name = indx; 6053130561Sobrien if (a->vna_nextptr == NULL) 6054130561Sobrien a->vna_next = 0; 6055130561Sobrien else 6056130561Sobrien a->vna_next = sizeof (Elf_External_Vernaux); 6057130561Sobrien 6058130561Sobrien _bfd_elf_swap_vernaux_out (output_bfd, a, 6059130561Sobrien (Elf_External_Vernaux *) p); 6060130561Sobrien p += sizeof (Elf_External_Vernaux); 6061130561Sobrien } 6062130561Sobrien } 6063130561Sobrien 6064130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_VERNEED, 0) 6065130561Sobrien || !_bfd_elf_add_dynamic_entry (info, DT_VERNEEDNUM, crefs)) 6066130561Sobrien return FALSE; 6067130561Sobrien 6068130561Sobrien elf_tdata (output_bfd)->cverrefs = crefs; 6069130561Sobrien } 6070130561Sobrien } 6071130561Sobrien 6072218822Sdim if ((elf_tdata (output_bfd)->cverrefs == 0 6073218822Sdim && elf_tdata (output_bfd)->cverdefs == 0) 6074218822Sdim || _bfd_elf_link_renumber_dynsyms (output_bfd, info, 6075218822Sdim §ion_sym_count) == 0) 6076218822Sdim { 6077218822Sdim s = bfd_get_section_by_name (dynobj, ".gnu.version"); 6078218822Sdim s->flags |= SEC_EXCLUDE; 6079218822Sdim } 6080218822Sdim } 6081218822Sdim return TRUE; 6082218822Sdim} 6083218822Sdim 6084218822Sdim/* Find the first non-excluded output section. We'll use its 6085218822Sdim section symbol for some emitted relocs. */ 6086218822Sdimvoid 6087218822Sdim_bfd_elf_init_1_index_section (bfd *output_bfd, struct bfd_link_info *info) 6088218822Sdim{ 6089218822Sdim asection *s; 6090218822Sdim 6091218822Sdim for (s = output_bfd->sections; s != NULL; s = s->next) 6092218822Sdim if ((s->flags & (SEC_EXCLUDE | SEC_ALLOC)) == SEC_ALLOC 6093218822Sdim && !_bfd_elf_link_omit_section_dynsym (output_bfd, info, s)) 6094218822Sdim { 6095218822Sdim elf_hash_table (info)->text_index_section = s; 6096218822Sdim break; 6097218822Sdim } 6098218822Sdim} 6099218822Sdim 6100218822Sdim/* Find two non-excluded output sections, one for code, one for data. 6101218822Sdim We'll use their section symbols for some emitted relocs. */ 6102218822Sdimvoid 6103218822Sdim_bfd_elf_init_2_index_sections (bfd *output_bfd, struct bfd_link_info *info) 6104218822Sdim{ 6105218822Sdim asection *s; 6106218822Sdim 6107218822Sdim for (s = output_bfd->sections; s != NULL; s = s->next) 6108218822Sdim if (((s->flags & (SEC_EXCLUDE | SEC_ALLOC | SEC_READONLY)) 6109218822Sdim == (SEC_ALLOC | SEC_READONLY)) 6110218822Sdim && !_bfd_elf_link_omit_section_dynsym (output_bfd, info, s)) 6111218822Sdim { 6112218822Sdim elf_hash_table (info)->text_index_section = s; 6113218822Sdim break; 6114218822Sdim } 6115218822Sdim 6116218822Sdim for (s = output_bfd->sections; s != NULL; s = s->next) 6117218822Sdim if (((s->flags & (SEC_EXCLUDE | SEC_ALLOC | SEC_READONLY)) == SEC_ALLOC) 6118218822Sdim && !_bfd_elf_link_omit_section_dynsym (output_bfd, info, s)) 6119218822Sdim { 6120218822Sdim elf_hash_table (info)->data_index_section = s; 6121218822Sdim break; 6122218822Sdim } 6123218822Sdim 6124218822Sdim if (elf_hash_table (info)->text_index_section == NULL) 6125218822Sdim elf_hash_table (info)->text_index_section 6126218822Sdim = elf_hash_table (info)->data_index_section; 6127218822Sdim} 6128218822Sdim 6129218822Sdimbfd_boolean 6130218822Sdimbfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info) 6131218822Sdim{ 6132218822Sdim const struct elf_backend_data *bed; 6133218822Sdim 6134218822Sdim if (!is_elf_hash_table (info->hash)) 6135218822Sdim return TRUE; 6136218822Sdim 6137218822Sdim bed = get_elf_backend_data (output_bfd); 6138218822Sdim (*bed->elf_backend_init_index_section) (output_bfd, info); 6139218822Sdim 6140218822Sdim if (elf_hash_table (info)->dynamic_sections_created) 6141218822Sdim { 6142218822Sdim bfd *dynobj; 6143218822Sdim asection *s; 6144218822Sdim bfd_size_type dynsymcount; 6145218822Sdim unsigned long section_sym_count; 6146218822Sdim unsigned int dtagcount; 6147218822Sdim 6148218822Sdim dynobj = elf_hash_table (info)->dynobj; 6149218822Sdim 6150130561Sobrien /* Assign dynsym indicies. In a shared library we generate a 6151130561Sobrien section symbol for each output section, which come first. 6152130561Sobrien Next come all of the back-end allocated local dynamic syms, 6153130561Sobrien followed by the rest of the global symbols. */ 6154130561Sobrien 6155218822Sdim dynsymcount = _bfd_elf_link_renumber_dynsyms (output_bfd, info, 6156218822Sdim §ion_sym_count); 6157130561Sobrien 6158130561Sobrien /* Work out the size of the symbol version section. */ 6159130561Sobrien s = bfd_get_section_by_name (dynobj, ".gnu.version"); 6160130561Sobrien BFD_ASSERT (s != NULL); 6161218822Sdim if (dynsymcount != 0 6162218822Sdim && (s->flags & SEC_EXCLUDE) == 0) 6163130561Sobrien { 6164218822Sdim s->size = dynsymcount * sizeof (Elf_External_Versym); 6165218822Sdim s->contents = bfd_zalloc (output_bfd, s->size); 6166130561Sobrien if (s->contents == NULL) 6167130561Sobrien return FALSE; 6168130561Sobrien 6169130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_VERSYM, 0)) 6170130561Sobrien return FALSE; 6171130561Sobrien } 6172130561Sobrien 6173130561Sobrien /* Set the size of the .dynsym and .hash sections. We counted 6174130561Sobrien the number of dynamic symbols in elf_link_add_object_symbols. 6175130561Sobrien We will build the contents of .dynsym and .hash when we build 6176130561Sobrien the final symbol table, because until then we do not know the 6177130561Sobrien correct value to give the symbols. We built the .dynstr 6178130561Sobrien section as we went along in elf_link_add_object_symbols. */ 6179130561Sobrien s = bfd_get_section_by_name (dynobj, ".dynsym"); 6180130561Sobrien BFD_ASSERT (s != NULL); 6181218822Sdim s->size = dynsymcount * bed->s->sizeof_sym; 6182130561Sobrien 6183130561Sobrien if (dynsymcount != 0) 6184130561Sobrien { 6185218822Sdim s->contents = bfd_alloc (output_bfd, s->size); 6186218822Sdim if (s->contents == NULL) 6187218822Sdim return FALSE; 6188130561Sobrien 6189218822Sdim /* The first entry in .dynsym is a dummy symbol. 6190218822Sdim Clear all the section syms, in case we don't output them all. */ 6191218822Sdim ++section_sym_count; 6192218822Sdim memset (s->contents, 0, section_sym_count * bed->s->sizeof_sym); 6193130561Sobrien } 6194130561Sobrien 6195218822Sdim elf_hash_table (info)->bucketcount = 0; 6196218822Sdim 6197130561Sobrien /* Compute the size of the hashing table. As a side effect this 6198130561Sobrien computes the hash values for all the names we export. */ 6199218822Sdim if (info->emit_hash) 6200218822Sdim { 6201218822Sdim unsigned long int *hashcodes; 6202218822Sdim unsigned long int *hashcodesp; 6203218822Sdim bfd_size_type amt; 6204218822Sdim unsigned long int nsyms; 6205218822Sdim size_t bucketcount; 6206218822Sdim size_t hash_entry_size; 6207130561Sobrien 6208218822Sdim /* Compute the hash values for all exported symbols. At the same 6209218822Sdim time store the values in an array so that we could use them for 6210218822Sdim optimizations. */ 6211218822Sdim amt = dynsymcount * sizeof (unsigned long int); 6212218822Sdim hashcodes = bfd_malloc (amt); 6213218822Sdim if (hashcodes == NULL) 6214218822Sdim return FALSE; 6215218822Sdim hashcodesp = hashcodes; 6216130561Sobrien 6217218822Sdim /* Put all hash values in HASHCODES. */ 6218218822Sdim elf_link_hash_traverse (elf_hash_table (info), 6219218822Sdim elf_collect_hash_codes, &hashcodesp); 6220130561Sobrien 6221218822Sdim nsyms = hashcodesp - hashcodes; 6222218822Sdim bucketcount 6223218822Sdim = compute_bucket_count (info, hashcodes, nsyms, 0); 6224218822Sdim free (hashcodes); 6225130561Sobrien 6226218822Sdim if (bucketcount == 0) 6227218822Sdim return FALSE; 6228218822Sdim 6229218822Sdim elf_hash_table (info)->bucketcount = bucketcount; 6230218822Sdim 6231218822Sdim s = bfd_get_section_by_name (dynobj, ".hash"); 6232218822Sdim BFD_ASSERT (s != NULL); 6233218822Sdim hash_entry_size = elf_section_data (s)->this_hdr.sh_entsize; 6234218822Sdim s->size = ((2 + bucketcount + dynsymcount) * hash_entry_size); 6235218822Sdim s->contents = bfd_zalloc (output_bfd, s->size); 6236218822Sdim if (s->contents == NULL) 6237218822Sdim return FALSE; 6238218822Sdim 6239218822Sdim bfd_put (8 * hash_entry_size, output_bfd, bucketcount, s->contents); 6240218822Sdim bfd_put (8 * hash_entry_size, output_bfd, dynsymcount, 6241218822Sdim s->contents + hash_entry_size); 6242218822Sdim } 6243218822Sdim 6244218822Sdim if (info->emit_gnu_hash) 6245218822Sdim { 6246218822Sdim size_t i, cnt; 6247218822Sdim unsigned char *contents; 6248218822Sdim struct collect_gnu_hash_codes cinfo; 6249218822Sdim bfd_size_type amt; 6250218822Sdim size_t bucketcount; 6251218822Sdim 6252218822Sdim memset (&cinfo, 0, sizeof (cinfo)); 6253218822Sdim 6254218822Sdim /* Compute the hash values for all exported symbols. At the same 6255218822Sdim time store the values in an array so that we could use them for 6256218822Sdim optimizations. */ 6257218822Sdim amt = dynsymcount * 2 * sizeof (unsigned long int); 6258218822Sdim cinfo.hashcodes = bfd_malloc (amt); 6259218822Sdim if (cinfo.hashcodes == NULL) 6260218822Sdim return FALSE; 6261218822Sdim 6262218822Sdim cinfo.hashval = cinfo.hashcodes + dynsymcount; 6263218822Sdim cinfo.min_dynindx = -1; 6264218822Sdim cinfo.output_bfd = output_bfd; 6265218822Sdim cinfo.bed = bed; 6266218822Sdim 6267218822Sdim /* Put all hash values in HASHCODES. */ 6268218822Sdim elf_link_hash_traverse (elf_hash_table (info), 6269218822Sdim elf_collect_gnu_hash_codes, &cinfo); 6270218822Sdim 6271218822Sdim bucketcount 6272218822Sdim = compute_bucket_count (info, cinfo.hashcodes, cinfo.nsyms, 1); 6273218822Sdim 6274218822Sdim if (bucketcount == 0) 6275218822Sdim { 6276218822Sdim free (cinfo.hashcodes); 6277218822Sdim return FALSE; 6278218822Sdim } 6279218822Sdim 6280218822Sdim s = bfd_get_section_by_name (dynobj, ".gnu.hash"); 6281218822Sdim BFD_ASSERT (s != NULL); 6282218822Sdim 6283218822Sdim if (cinfo.nsyms == 0) 6284218822Sdim { 6285218822Sdim /* Empty .gnu.hash section is special. */ 6286218822Sdim BFD_ASSERT (cinfo.min_dynindx == -1); 6287218822Sdim free (cinfo.hashcodes); 6288218822Sdim s->size = 5 * 4 + bed->s->arch_size / 8; 6289218822Sdim contents = bfd_zalloc (output_bfd, s->size); 6290218822Sdim if (contents == NULL) 6291218822Sdim return FALSE; 6292218822Sdim s->contents = contents; 6293218822Sdim /* 1 empty bucket. */ 6294218822Sdim bfd_put_32 (output_bfd, 1, contents); 6295218822Sdim /* SYMIDX above the special symbol 0. */ 6296218822Sdim bfd_put_32 (output_bfd, 1, contents + 4); 6297218822Sdim /* Just one word for bitmask. */ 6298218822Sdim bfd_put_32 (output_bfd, 1, contents + 8); 6299218822Sdim /* Only hash fn bloom filter. */ 6300218822Sdim bfd_put_32 (output_bfd, 0, contents + 12); 6301218822Sdim /* No hashes are valid - empty bitmask. */ 6302218822Sdim bfd_put (bed->s->arch_size, output_bfd, 0, contents + 16); 6303218822Sdim /* No hashes in the only bucket. */ 6304218822Sdim bfd_put_32 (output_bfd, 0, 6305218822Sdim contents + 16 + bed->s->arch_size / 8); 6306218822Sdim } 6307218822Sdim else 6308218822Sdim { 6309218822Sdim unsigned long int maskwords, maskbitslog2; 6310218822Sdim BFD_ASSERT (cinfo.min_dynindx != -1); 6311218822Sdim 6312218822Sdim maskbitslog2 = bfd_log2 (cinfo.nsyms) + 1; 6313218822Sdim if (maskbitslog2 < 3) 6314218822Sdim maskbitslog2 = 5; 6315218822Sdim else if ((1 << (maskbitslog2 - 2)) & cinfo.nsyms) 6316218822Sdim maskbitslog2 = maskbitslog2 + 3; 6317218822Sdim else 6318218822Sdim maskbitslog2 = maskbitslog2 + 2; 6319218822Sdim if (bed->s->arch_size == 64) 6320218822Sdim { 6321218822Sdim if (maskbitslog2 == 5) 6322218822Sdim maskbitslog2 = 6; 6323218822Sdim cinfo.shift1 = 6; 6324218822Sdim } 6325218822Sdim else 6326218822Sdim cinfo.shift1 = 5; 6327218822Sdim cinfo.mask = (1 << cinfo.shift1) - 1; 6328218822Sdim cinfo.shift2 = maskbitslog2; 6329218822Sdim cinfo.maskbits = 1 << maskbitslog2; 6330218822Sdim maskwords = 1 << (maskbitslog2 - cinfo.shift1); 6331218822Sdim amt = bucketcount * sizeof (unsigned long int) * 2; 6332218822Sdim amt += maskwords * sizeof (bfd_vma); 6333218822Sdim cinfo.bitmask = bfd_malloc (amt); 6334218822Sdim if (cinfo.bitmask == NULL) 6335218822Sdim { 6336218822Sdim free (cinfo.hashcodes); 6337218822Sdim return FALSE; 6338218822Sdim } 6339218822Sdim 6340218822Sdim cinfo.counts = (void *) (cinfo.bitmask + maskwords); 6341218822Sdim cinfo.indx = cinfo.counts + bucketcount; 6342218822Sdim cinfo.symindx = dynsymcount - cinfo.nsyms; 6343218822Sdim memset (cinfo.bitmask, 0, maskwords * sizeof (bfd_vma)); 6344218822Sdim 6345218822Sdim /* Determine how often each hash bucket is used. */ 6346218822Sdim memset (cinfo.counts, 0, bucketcount * sizeof (cinfo.counts[0])); 6347218822Sdim for (i = 0; i < cinfo.nsyms; ++i) 6348218822Sdim ++cinfo.counts[cinfo.hashcodes[i] % bucketcount]; 6349218822Sdim 6350218822Sdim for (i = 0, cnt = cinfo.symindx; i < bucketcount; ++i) 6351218822Sdim if (cinfo.counts[i] != 0) 6352218822Sdim { 6353218822Sdim cinfo.indx[i] = cnt; 6354218822Sdim cnt += cinfo.counts[i]; 6355218822Sdim } 6356218822Sdim BFD_ASSERT (cnt == dynsymcount); 6357218822Sdim cinfo.bucketcount = bucketcount; 6358218822Sdim cinfo.local_indx = cinfo.min_dynindx; 6359218822Sdim 6360218822Sdim s->size = (4 + bucketcount + cinfo.nsyms) * 4; 6361218822Sdim s->size += cinfo.maskbits / 8; 6362218822Sdim contents = bfd_zalloc (output_bfd, s->size); 6363218822Sdim if (contents == NULL) 6364218822Sdim { 6365218822Sdim free (cinfo.bitmask); 6366218822Sdim free (cinfo.hashcodes); 6367218822Sdim return FALSE; 6368218822Sdim } 6369218822Sdim 6370218822Sdim s->contents = contents; 6371218822Sdim bfd_put_32 (output_bfd, bucketcount, contents); 6372218822Sdim bfd_put_32 (output_bfd, cinfo.symindx, contents + 4); 6373218822Sdim bfd_put_32 (output_bfd, maskwords, contents + 8); 6374218822Sdim bfd_put_32 (output_bfd, cinfo.shift2, contents + 12); 6375218822Sdim contents += 16 + cinfo.maskbits / 8; 6376218822Sdim 6377218822Sdim for (i = 0; i < bucketcount; ++i) 6378218822Sdim { 6379218822Sdim if (cinfo.counts[i] == 0) 6380218822Sdim bfd_put_32 (output_bfd, 0, contents); 6381218822Sdim else 6382218822Sdim bfd_put_32 (output_bfd, cinfo.indx[i], contents); 6383218822Sdim contents += 4; 6384218822Sdim } 6385218822Sdim 6386218822Sdim cinfo.contents = contents; 6387218822Sdim 6388218822Sdim /* Renumber dynamic symbols, populate .gnu.hash section. */ 6389218822Sdim elf_link_hash_traverse (elf_hash_table (info), 6390218822Sdim elf_renumber_gnu_hash_syms, &cinfo); 6391218822Sdim 6392218822Sdim contents = s->contents + 16; 6393218822Sdim for (i = 0; i < maskwords; ++i) 6394218822Sdim { 6395218822Sdim bfd_put (bed->s->arch_size, output_bfd, cinfo.bitmask[i], 6396218822Sdim contents); 6397218822Sdim contents += bed->s->arch_size / 8; 6398218822Sdim } 6399218822Sdim 6400218822Sdim free (cinfo.bitmask); 6401218822Sdim free (cinfo.hashcodes); 6402218822Sdim } 6403218822Sdim } 6404218822Sdim 6405130561Sobrien s = bfd_get_section_by_name (dynobj, ".dynstr"); 6406130561Sobrien BFD_ASSERT (s != NULL); 6407130561Sobrien 6408130561Sobrien elf_finalize_dynstr (output_bfd, info); 6409130561Sobrien 6410218822Sdim s->size = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr); 6411130561Sobrien 6412130561Sobrien for (dtagcount = 0; dtagcount <= info->spare_dynamic_tags; ++dtagcount) 6413130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_NULL, 0)) 6414130561Sobrien return FALSE; 6415130561Sobrien } 6416130561Sobrien 6417130561Sobrien return TRUE; 6418130561Sobrien} 6419130561Sobrien 6420130561Sobrien/* Final phase of ELF linker. */ 6421130561Sobrien 6422130561Sobrien/* A structure we use to avoid passing large numbers of arguments. */ 6423130561Sobrien 6424130561Sobrienstruct elf_final_link_info 6425130561Sobrien{ 6426130561Sobrien /* General link information. */ 6427130561Sobrien struct bfd_link_info *info; 6428130561Sobrien /* Output BFD. */ 6429130561Sobrien bfd *output_bfd; 6430130561Sobrien /* Symbol string table. */ 6431130561Sobrien struct bfd_strtab_hash *symstrtab; 6432130561Sobrien /* .dynsym section. */ 6433130561Sobrien asection *dynsym_sec; 6434130561Sobrien /* .hash section. */ 6435130561Sobrien asection *hash_sec; 6436130561Sobrien /* symbol version section (.gnu.version). */ 6437130561Sobrien asection *symver_sec; 6438130561Sobrien /* Buffer large enough to hold contents of any section. */ 6439130561Sobrien bfd_byte *contents; 6440130561Sobrien /* Buffer large enough to hold external relocs of any section. */ 6441130561Sobrien void *external_relocs; 6442130561Sobrien /* Buffer large enough to hold internal relocs of any section. */ 6443130561Sobrien Elf_Internal_Rela *internal_relocs; 6444130561Sobrien /* Buffer large enough to hold external local symbols of any input 6445130561Sobrien BFD. */ 6446130561Sobrien bfd_byte *external_syms; 6447130561Sobrien /* And a buffer for symbol section indices. */ 6448130561Sobrien Elf_External_Sym_Shndx *locsym_shndx; 6449130561Sobrien /* Buffer large enough to hold internal local symbols of any input 6450130561Sobrien BFD. */ 6451130561Sobrien Elf_Internal_Sym *internal_syms; 6452130561Sobrien /* Array large enough to hold a symbol index for each local symbol 6453130561Sobrien of any input BFD. */ 6454130561Sobrien long *indices; 6455130561Sobrien /* Array large enough to hold a section pointer for each local 6456130561Sobrien symbol of any input BFD. */ 6457130561Sobrien asection **sections; 6458130561Sobrien /* Buffer to hold swapped out symbols. */ 6459130561Sobrien bfd_byte *symbuf; 6460130561Sobrien /* And one for symbol section indices. */ 6461130561Sobrien Elf_External_Sym_Shndx *symshndxbuf; 6462130561Sobrien /* Number of swapped out symbols in buffer. */ 6463130561Sobrien size_t symbuf_count; 6464130561Sobrien /* Number of symbols which fit in symbuf. */ 6465130561Sobrien size_t symbuf_size; 6466130561Sobrien /* And same for symshndxbuf. */ 6467130561Sobrien size_t shndxbuf_size; 6468130561Sobrien}; 6469130561Sobrien 6470130561Sobrien/* This struct is used to pass information to elf_link_output_extsym. */ 6471130561Sobrien 6472130561Sobrienstruct elf_outext_info 6473130561Sobrien{ 6474130561Sobrien bfd_boolean failed; 6475130561Sobrien bfd_boolean localsyms; 6476130561Sobrien struct elf_final_link_info *finfo; 6477130561Sobrien}; 6478130561Sobrien 6479218822Sdim 6480218822Sdim/* Support for evaluating a complex relocation. 6481218822Sdim 6482218822Sdim Complex relocations are generalized, self-describing relocations. The 6483218822Sdim implementation of them consists of two parts: complex symbols, and the 6484218822Sdim relocations themselves. 6485218822Sdim 6486218822Sdim The relocations are use a reserved elf-wide relocation type code (R_RELC 6487218822Sdim external / BFD_RELOC_RELC internal) and an encoding of relocation field 6488218822Sdim information (start bit, end bit, word width, etc) into the addend. This 6489218822Sdim information is extracted from CGEN-generated operand tables within gas. 6490218822Sdim 6491218822Sdim Complex symbols are mangled symbols (BSF_RELC external / STT_RELC 6492218822Sdim internal) representing prefix-notation expressions, including but not 6493218822Sdim limited to those sorts of expressions normally encoded as addends in the 6494218822Sdim addend field. The symbol mangling format is: 6495218822Sdim 6496218822Sdim <node> := <literal> 6497218822Sdim | <unary-operator> ':' <node> 6498218822Sdim | <binary-operator> ':' <node> ':' <node> 6499218822Sdim ; 6500218822Sdim 6501218822Sdim <literal> := 's' <digits=N> ':' <N character symbol name> 6502218822Sdim | 'S' <digits=N> ':' <N character section name> 6503218822Sdim | '#' <hexdigits> 6504218822Sdim ; 6505218822Sdim 6506218822Sdim <binary-operator> := as in C 6507218822Sdim <unary-operator> := as in C, plus "0-" for unambiguous negation. */ 6508218822Sdim 6509218822Sdimstatic void 6510218822Sdimset_symbol_value (bfd * bfd_with_globals, 6511218822Sdim struct elf_final_link_info * finfo, 6512218822Sdim int symidx, 6513218822Sdim bfd_vma val) 6514218822Sdim{ 6515218822Sdim bfd_boolean is_local; 6516218822Sdim Elf_Internal_Sym * sym; 6517218822Sdim struct elf_link_hash_entry ** sym_hashes; 6518218822Sdim struct elf_link_hash_entry * h; 6519218822Sdim 6520218822Sdim sym_hashes = elf_sym_hashes (bfd_with_globals); 6521218822Sdim sym = finfo->internal_syms + symidx; 6522218822Sdim is_local = ELF_ST_BIND(sym->st_info) == STB_LOCAL; 6523218822Sdim 6524218822Sdim if (is_local) 6525218822Sdim { 6526218822Sdim /* It is a local symbol: move it to the 6527218822Sdim "absolute" section and give it a value. */ 6528218822Sdim sym->st_shndx = SHN_ABS; 6529218822Sdim sym->st_value = val; 6530218822Sdim } 6531218822Sdim else 6532218822Sdim { 6533218822Sdim /* It is a global symbol: set its link type 6534218822Sdim to "defined" and give it a value. */ 6535218822Sdim h = sym_hashes [symidx]; 6536218822Sdim while (h->root.type == bfd_link_hash_indirect 6537218822Sdim || h->root.type == bfd_link_hash_warning) 6538218822Sdim h = (struct elf_link_hash_entry *) h->root.u.i.link; 6539218822Sdim h->root.type = bfd_link_hash_defined; 6540218822Sdim h->root.u.def.value = val; 6541218822Sdim h->root.u.def.section = bfd_abs_section_ptr; 6542218822Sdim } 6543218822Sdim} 6544218822Sdim 6545218822Sdimstatic bfd_boolean 6546218822Sdimresolve_symbol (const char * name, 6547218822Sdim bfd * input_bfd, 6548218822Sdim struct elf_final_link_info * finfo, 6549218822Sdim bfd_vma * result, 6550218822Sdim size_t locsymcount) 6551218822Sdim{ 6552218822Sdim Elf_Internal_Sym * sym; 6553218822Sdim struct bfd_link_hash_entry * global_entry; 6554218822Sdim const char * candidate = NULL; 6555218822Sdim Elf_Internal_Shdr * symtab_hdr; 6556218822Sdim asection * sec = NULL; 6557218822Sdim size_t i; 6558218822Sdim 6559218822Sdim symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr; 6560218822Sdim 6561218822Sdim for (i = 0; i < locsymcount; ++ i) 6562218822Sdim { 6563218822Sdim sym = finfo->internal_syms + i; 6564218822Sdim sec = finfo->sections [i]; 6565218822Sdim 6566218822Sdim if (ELF_ST_BIND (sym->st_info) != STB_LOCAL) 6567218822Sdim continue; 6568218822Sdim 6569218822Sdim candidate = bfd_elf_string_from_elf_section (input_bfd, 6570218822Sdim symtab_hdr->sh_link, 6571218822Sdim sym->st_name); 6572218822Sdim#ifdef DEBUG 6573218822Sdim printf ("Comparing string: '%s' vs. '%s' = 0x%x\n", 6574218822Sdim name, candidate, (unsigned int)sym->st_value); 6575218822Sdim#endif 6576218822Sdim if (candidate && strcmp (candidate, name) == 0) 6577218822Sdim { 6578218822Sdim * result = sym->st_value; 6579218822Sdim 6580218822Sdim if (sym->st_shndx > SHN_UNDEF && 6581218822Sdim sym->st_shndx < SHN_LORESERVE) 6582218822Sdim { 6583218822Sdim#ifdef DEBUG 6584218822Sdim printf ("adjusting for sec '%s' @ 0x%x + 0x%x\n", 6585218822Sdim sec->output_section->name, 6586218822Sdim (unsigned int)sec->output_section->vma, 6587218822Sdim (unsigned int)sec->output_offset); 6588218822Sdim#endif 6589218822Sdim * result += sec->output_offset + sec->output_section->vma; 6590218822Sdim } 6591218822Sdim#ifdef DEBUG 6592218822Sdim printf ("Found symbol with effective value %8.8x\n", (unsigned int)* result); 6593218822Sdim#endif 6594218822Sdim return TRUE; 6595218822Sdim } 6596218822Sdim } 6597218822Sdim 6598218822Sdim /* Hmm, haven't found it yet. perhaps it is a global. */ 6599218822Sdim global_entry = bfd_link_hash_lookup (finfo->info->hash, name, FALSE, FALSE, TRUE); 6600218822Sdim if (!global_entry) 6601218822Sdim return FALSE; 6602218822Sdim 6603218822Sdim if (global_entry->type == bfd_link_hash_defined 6604218822Sdim || global_entry->type == bfd_link_hash_defweak) 6605218822Sdim { 6606218822Sdim * result = global_entry->u.def.value 6607218822Sdim + global_entry->u.def.section->output_section->vma 6608218822Sdim + global_entry->u.def.section->output_offset; 6609218822Sdim#ifdef DEBUG 6610218822Sdim printf ("Found GLOBAL symbol '%s' with value %8.8x\n", 6611218822Sdim global_entry->root.string, (unsigned int)*result); 6612218822Sdim#endif 6613218822Sdim return TRUE; 6614218822Sdim } 6615218822Sdim 6616218822Sdim if (global_entry->type == bfd_link_hash_common) 6617218822Sdim { 6618218822Sdim *result = global_entry->u.def.value + 6619218822Sdim bfd_com_section_ptr->output_section->vma + 6620218822Sdim bfd_com_section_ptr->output_offset; 6621218822Sdim#ifdef DEBUG 6622218822Sdim printf ("Found COMMON symbol '%s' with value %8.8x\n", 6623218822Sdim global_entry->root.string, (unsigned int)*result); 6624218822Sdim#endif 6625218822Sdim return TRUE; 6626218822Sdim } 6627218822Sdim 6628218822Sdim return FALSE; 6629218822Sdim} 6630218822Sdim 6631218822Sdimstatic bfd_boolean 6632218822Sdimresolve_section (const char * name, 6633218822Sdim asection * sections, 6634218822Sdim bfd_vma * result) 6635218822Sdim{ 6636218822Sdim asection * curr; 6637218822Sdim unsigned int len; 6638218822Sdim 6639218822Sdim for (curr = sections; curr; curr = curr->next) 6640218822Sdim if (strcmp (curr->name, name) == 0) 6641218822Sdim { 6642218822Sdim *result = curr->vma; 6643218822Sdim return TRUE; 6644218822Sdim } 6645218822Sdim 6646218822Sdim /* Hmm. still haven't found it. try pseudo-section names. */ 6647218822Sdim for (curr = sections; curr; curr = curr->next) 6648218822Sdim { 6649218822Sdim len = strlen (curr->name); 6650218822Sdim if (len > strlen (name)) 6651218822Sdim continue; 6652218822Sdim 6653218822Sdim if (strncmp (curr->name, name, len) == 0) 6654218822Sdim { 6655218822Sdim if (strncmp (".end", name + len, 4) == 0) 6656218822Sdim { 6657218822Sdim *result = curr->vma + curr->size; 6658218822Sdim return TRUE; 6659218822Sdim } 6660218822Sdim 6661218822Sdim /* Insert more pseudo-section names here, if you like. */ 6662218822Sdim } 6663218822Sdim } 6664218822Sdim 6665218822Sdim return FALSE; 6666218822Sdim} 6667218822Sdim 6668218822Sdimstatic void 6669218822Sdimundefined_reference (const char * reftype, 6670218822Sdim const char * name) 6671218822Sdim{ 6672218822Sdim _bfd_error_handler (_("undefined %s reference in complex symbol: %s"), reftype, name); 6673218822Sdim} 6674218822Sdim 6675218822Sdimstatic bfd_boolean 6676218822Sdimeval_symbol (bfd_vma * result, 6677218822Sdim char * sym, 6678218822Sdim char ** advanced, 6679218822Sdim bfd * input_bfd, 6680218822Sdim struct elf_final_link_info * finfo, 6681218822Sdim bfd_vma addr, 6682218822Sdim bfd_vma section_offset, 6683218822Sdim size_t locsymcount, 6684218822Sdim int signed_p) 6685218822Sdim{ 6686218822Sdim int len; 6687218822Sdim int symlen; 6688218822Sdim bfd_vma a; 6689218822Sdim bfd_vma b; 6690218822Sdim const int bufsz = 4096; 6691218822Sdim char symbuf [bufsz]; 6692218822Sdim const char * symend; 6693218822Sdim bfd_boolean symbol_is_section = FALSE; 6694218822Sdim 6695218822Sdim len = strlen (sym); 6696218822Sdim symend = sym + len; 6697218822Sdim 6698218822Sdim if (len < 1 || len > bufsz) 6699218822Sdim { 6700218822Sdim bfd_set_error (bfd_error_invalid_operation); 6701218822Sdim return FALSE; 6702218822Sdim } 6703218822Sdim 6704218822Sdim switch (* sym) 6705218822Sdim { 6706218822Sdim case '.': 6707218822Sdim * result = addr + section_offset; 6708218822Sdim * advanced = sym + 1; 6709218822Sdim return TRUE; 6710218822Sdim 6711218822Sdim case '#': 6712218822Sdim ++ sym; 6713218822Sdim * result = strtoul (sym, advanced, 16); 6714218822Sdim return TRUE; 6715218822Sdim 6716218822Sdim case 'S': 6717218822Sdim symbol_is_section = TRUE; 6718218822Sdim case 's': 6719218822Sdim ++ sym; 6720218822Sdim symlen = strtol (sym, &sym, 10); 6721218822Sdim ++ sym; /* Skip the trailing ':'. */ 6722218822Sdim 6723218822Sdim if ((symend < sym) || ((symlen + 1) > bufsz)) 6724218822Sdim { 6725218822Sdim bfd_set_error (bfd_error_invalid_operation); 6726218822Sdim return FALSE; 6727218822Sdim } 6728218822Sdim 6729218822Sdim memcpy (symbuf, sym, symlen); 6730218822Sdim symbuf [symlen] = '\0'; 6731218822Sdim * advanced = sym + symlen; 6732218822Sdim 6733218822Sdim /* Is it always possible, with complex symbols, that gas "mis-guessed" 6734218822Sdim the symbol as a section, or vice-versa. so we're pretty liberal in our 6735218822Sdim interpretation here; section means "try section first", not "must be a 6736218822Sdim section", and likewise with symbol. */ 6737218822Sdim 6738218822Sdim if (symbol_is_section) 6739218822Sdim { 6740218822Sdim if ((resolve_section (symbuf, finfo->output_bfd->sections, result) != TRUE) 6741218822Sdim && (resolve_symbol (symbuf, input_bfd, finfo, result, locsymcount) != TRUE)) 6742218822Sdim { 6743218822Sdim undefined_reference ("section", symbuf); 6744218822Sdim return FALSE; 6745218822Sdim } 6746218822Sdim } 6747218822Sdim else 6748218822Sdim { 6749218822Sdim if ((resolve_symbol (symbuf, input_bfd, finfo, result, locsymcount) != TRUE) 6750218822Sdim && (resolve_section (symbuf, finfo->output_bfd->sections, 6751218822Sdim result) != TRUE)) 6752218822Sdim { 6753218822Sdim undefined_reference ("symbol", symbuf); 6754218822Sdim return FALSE; 6755218822Sdim } 6756218822Sdim } 6757218822Sdim 6758218822Sdim return TRUE; 6759218822Sdim 6760218822Sdim /* All that remains are operators. */ 6761218822Sdim 6762218822Sdim#define UNARY_OP(op) \ 6763218822Sdim if (strncmp (sym, #op, strlen (#op)) == 0) \ 6764218822Sdim { \ 6765218822Sdim sym += strlen (#op); \ 6766218822Sdim if (* sym == ':') \ 6767218822Sdim ++ sym; \ 6768218822Sdim if (eval_symbol (& a, sym, & sym, input_bfd, finfo, addr, \ 6769218822Sdim section_offset, locsymcount, signed_p) \ 6770218822Sdim != TRUE) \ 6771218822Sdim return FALSE; \ 6772218822Sdim if (signed_p) \ 6773218822Sdim * result = op ((signed)a); \ 6774218822Sdim else \ 6775218822Sdim * result = op a; \ 6776218822Sdim * advanced = sym; \ 6777218822Sdim return TRUE; \ 6778218822Sdim } 6779218822Sdim 6780218822Sdim#define BINARY_OP(op) \ 6781218822Sdim if (strncmp (sym, #op, strlen (#op)) == 0) \ 6782218822Sdim { \ 6783218822Sdim sym += strlen (#op); \ 6784218822Sdim if (* sym == ':') \ 6785218822Sdim ++ sym; \ 6786218822Sdim if (eval_symbol (& a, sym, & sym, input_bfd, finfo, addr, \ 6787218822Sdim section_offset, locsymcount, signed_p) \ 6788218822Sdim != TRUE) \ 6789218822Sdim return FALSE; \ 6790218822Sdim ++ sym; \ 6791218822Sdim if (eval_symbol (& b, sym, & sym, input_bfd, finfo, addr, \ 6792218822Sdim section_offset, locsymcount, signed_p) \ 6793218822Sdim != TRUE) \ 6794218822Sdim return FALSE; \ 6795218822Sdim if (signed_p) \ 6796218822Sdim * result = ((signed) a) op ((signed) b); \ 6797218822Sdim else \ 6798218822Sdim * result = a op b; \ 6799218822Sdim * advanced = sym; \ 6800218822Sdim return TRUE; \ 6801218822Sdim } 6802218822Sdim 6803218822Sdim default: 6804218822Sdim UNARY_OP (0-); 6805218822Sdim BINARY_OP (<<); 6806218822Sdim BINARY_OP (>>); 6807218822Sdim BINARY_OP (==); 6808218822Sdim BINARY_OP (!=); 6809218822Sdim BINARY_OP (<=); 6810218822Sdim BINARY_OP (>=); 6811218822Sdim BINARY_OP (&&); 6812218822Sdim BINARY_OP (||); 6813218822Sdim UNARY_OP (~); 6814218822Sdim UNARY_OP (!); 6815218822Sdim BINARY_OP (*); 6816218822Sdim BINARY_OP (/); 6817218822Sdim BINARY_OP (%); 6818218822Sdim BINARY_OP (^); 6819218822Sdim BINARY_OP (|); 6820218822Sdim BINARY_OP (&); 6821218822Sdim BINARY_OP (+); 6822218822Sdim BINARY_OP (-); 6823218822Sdim BINARY_OP (<); 6824218822Sdim BINARY_OP (>); 6825218822Sdim#undef UNARY_OP 6826218822Sdim#undef BINARY_OP 6827218822Sdim _bfd_error_handler (_("unknown operator '%c' in complex symbol"), * sym); 6828218822Sdim bfd_set_error (bfd_error_invalid_operation); 6829218822Sdim return FALSE; 6830218822Sdim } 6831218822Sdim} 6832218822Sdim 6833218822Sdim/* Entry point to evaluator, called from elf_link_input_bfd. */ 6834218822Sdim 6835218822Sdimstatic bfd_boolean 6836218822Sdimevaluate_complex_relocation_symbols (bfd * input_bfd, 6837218822Sdim struct elf_final_link_info * finfo, 6838218822Sdim size_t locsymcount) 6839218822Sdim{ 6840218822Sdim const struct elf_backend_data * bed; 6841218822Sdim Elf_Internal_Shdr * symtab_hdr; 6842218822Sdim struct elf_link_hash_entry ** sym_hashes; 6843218822Sdim asection * reloc_sec; 6844218822Sdim bfd_boolean result = TRUE; 6845218822Sdim 6846218822Sdim /* For each section, we're going to check and see if it has any 6847218822Sdim complex relocations, and we're going to evaluate any of them 6848218822Sdim we can. */ 6849218822Sdim 6850218822Sdim if (finfo->info->relocatable) 6851218822Sdim return TRUE; 6852218822Sdim 6853218822Sdim symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr; 6854218822Sdim sym_hashes = elf_sym_hashes (input_bfd); 6855218822Sdim bed = get_elf_backend_data (input_bfd); 6856218822Sdim 6857218822Sdim for (reloc_sec = input_bfd->sections; reloc_sec; reloc_sec = reloc_sec->next) 6858218822Sdim { 6859218822Sdim Elf_Internal_Rela * internal_relocs; 6860218822Sdim unsigned long i; 6861218822Sdim 6862218822Sdim /* This section was omitted from the link. */ 6863218822Sdim if (! reloc_sec->linker_mark) 6864218822Sdim continue; 6865218822Sdim 6866218822Sdim /* Only process sections containing relocs. */ 6867218822Sdim if ((reloc_sec->flags & SEC_RELOC) == 0) 6868218822Sdim continue; 6869218822Sdim 6870218822Sdim if (reloc_sec->reloc_count == 0) 6871218822Sdim continue; 6872218822Sdim 6873218822Sdim /* Read in the relocs for this section. */ 6874218822Sdim internal_relocs 6875218822Sdim = _bfd_elf_link_read_relocs (input_bfd, reloc_sec, NULL, 6876218822Sdim (Elf_Internal_Rela *) NULL, 6877218822Sdim FALSE); 6878218822Sdim if (internal_relocs == NULL) 6879218822Sdim continue; 6880218822Sdim 6881218822Sdim for (i = reloc_sec->reloc_count; i--;) 6882218822Sdim { 6883218822Sdim Elf_Internal_Rela * rel; 6884218822Sdim char * sym_name; 6885218822Sdim bfd_vma index; 6886218822Sdim Elf_Internal_Sym * sym; 6887218822Sdim bfd_vma result; 6888218822Sdim bfd_vma section_offset; 6889218822Sdim bfd_vma addr; 6890218822Sdim int signed_p = 0; 6891218822Sdim 6892218822Sdim rel = internal_relocs + i; 6893218822Sdim section_offset = reloc_sec->output_section->vma 6894218822Sdim + reloc_sec->output_offset; 6895218822Sdim addr = rel->r_offset; 6896218822Sdim 6897218822Sdim index = ELF32_R_SYM (rel->r_info); 6898218822Sdim if (bed->s->arch_size == 64) 6899218822Sdim index >>= 24; 6900218822Sdim 6901218822Sdim if (index == STN_UNDEF) 6902218822Sdim continue; 6903218822Sdim 6904218822Sdim if (index < locsymcount) 6905218822Sdim { 6906218822Sdim /* The symbol is local. */ 6907218822Sdim sym = finfo->internal_syms + index; 6908218822Sdim 6909218822Sdim /* We're only processing STT_RELC or STT_SRELC type symbols. */ 6910218822Sdim if ((ELF_ST_TYPE (sym->st_info) != STT_RELC) && 6911218822Sdim (ELF_ST_TYPE (sym->st_info) != STT_SRELC)) 6912218822Sdim continue; 6913218822Sdim 6914218822Sdim sym_name = bfd_elf_string_from_elf_section 6915218822Sdim (input_bfd, symtab_hdr->sh_link, sym->st_name); 6916218822Sdim 6917218822Sdim signed_p = (ELF_ST_TYPE (sym->st_info) == STT_SRELC); 6918218822Sdim } 6919218822Sdim else 6920218822Sdim { 6921218822Sdim /* The symbol is global. */ 6922218822Sdim struct elf_link_hash_entry * h; 6923218822Sdim 6924218822Sdim if (elf_bad_symtab (input_bfd)) 6925218822Sdim continue; 6926218822Sdim 6927218822Sdim h = sym_hashes [index - locsymcount]; 6928218822Sdim while ( h->root.type == bfd_link_hash_indirect 6929218822Sdim || h->root.type == bfd_link_hash_warning) 6930218822Sdim h = (struct elf_link_hash_entry *) h->root.u.i.link; 6931218822Sdim 6932218822Sdim if (h->type != STT_RELC && h->type != STT_SRELC) 6933218822Sdim continue; 6934218822Sdim 6935218822Sdim signed_p = (h->type == STT_SRELC); 6936218822Sdim sym_name = (char *) h->root.root.string; 6937218822Sdim } 6938218822Sdim#ifdef DEBUG 6939218822Sdim printf ("Encountered a complex symbol!"); 6940218822Sdim printf (" (input_bfd %s, section %s, reloc %ld\n", 6941218822Sdim input_bfd->filename, reloc_sec->name, i); 6942218822Sdim printf (" symbol: idx %8.8lx, name %s\n", 6943218822Sdim index, sym_name); 6944218822Sdim printf (" reloc : info %8.8lx, addr %8.8lx\n", 6945218822Sdim rel->r_info, addr); 6946218822Sdim printf (" Evaluating '%s' ...\n ", sym_name); 6947218822Sdim#endif 6948218822Sdim if (eval_symbol (& result, sym_name, & sym_name, input_bfd, 6949218822Sdim finfo, addr, section_offset, locsymcount, 6950218822Sdim signed_p)) 6951218822Sdim /* Symbol evaluated OK. Update to absolute value. */ 6952218822Sdim set_symbol_value (input_bfd, finfo, index, result); 6953218822Sdim 6954218822Sdim else 6955218822Sdim result = FALSE; 6956218822Sdim } 6957218822Sdim 6958218822Sdim if (internal_relocs != elf_section_data (reloc_sec)->relocs) 6959218822Sdim free (internal_relocs); 6960218822Sdim } 6961218822Sdim 6962218822Sdim /* If nothing went wrong, then we adjusted 6963218822Sdim everything we wanted to adjust. */ 6964218822Sdim return result; 6965218822Sdim} 6966218822Sdim 6967218822Sdimstatic void 6968218822Sdimput_value (bfd_vma size, 6969218822Sdim unsigned long chunksz, 6970218822Sdim bfd * input_bfd, 6971218822Sdim bfd_vma x, 6972218822Sdim bfd_byte * location) 6973218822Sdim{ 6974218822Sdim location += (size - chunksz); 6975218822Sdim 6976218822Sdim for (; size; size -= chunksz, location -= chunksz, x >>= (chunksz * 8)) 6977218822Sdim { 6978218822Sdim switch (chunksz) 6979218822Sdim { 6980218822Sdim default: 6981218822Sdim case 0: 6982218822Sdim abort (); 6983218822Sdim case 1: 6984218822Sdim bfd_put_8 (input_bfd, x, location); 6985218822Sdim break; 6986218822Sdim case 2: 6987218822Sdim bfd_put_16 (input_bfd, x, location); 6988218822Sdim break; 6989218822Sdim case 4: 6990218822Sdim bfd_put_32 (input_bfd, x, location); 6991218822Sdim break; 6992218822Sdim case 8: 6993218822Sdim#ifdef BFD64 6994218822Sdim bfd_put_64 (input_bfd, x, location); 6995218822Sdim#else 6996218822Sdim abort (); 6997218822Sdim#endif 6998218822Sdim break; 6999218822Sdim } 7000218822Sdim } 7001218822Sdim} 7002218822Sdim 7003218822Sdimstatic bfd_vma 7004218822Sdimget_value (bfd_vma size, 7005218822Sdim unsigned long chunksz, 7006218822Sdim bfd * input_bfd, 7007218822Sdim bfd_byte * location) 7008218822Sdim{ 7009218822Sdim bfd_vma x = 0; 7010218822Sdim 7011218822Sdim for (; size; size -= chunksz, location += chunksz) 7012218822Sdim { 7013218822Sdim switch (chunksz) 7014218822Sdim { 7015218822Sdim default: 7016218822Sdim case 0: 7017218822Sdim abort (); 7018218822Sdim case 1: 7019218822Sdim x = (x << (8 * chunksz)) | bfd_get_8 (input_bfd, location); 7020218822Sdim break; 7021218822Sdim case 2: 7022218822Sdim x = (x << (8 * chunksz)) | bfd_get_16 (input_bfd, location); 7023218822Sdim break; 7024218822Sdim case 4: 7025218822Sdim x = (x << (8 * chunksz)) | bfd_get_32 (input_bfd, location); 7026218822Sdim break; 7027218822Sdim case 8: 7028218822Sdim#ifdef BFD64 7029218822Sdim x = (x << (8 * chunksz)) | bfd_get_64 (input_bfd, location); 7030218822Sdim#else 7031218822Sdim abort (); 7032218822Sdim#endif 7033218822Sdim break; 7034218822Sdim } 7035218822Sdim } 7036218822Sdim return x; 7037218822Sdim} 7038218822Sdim 7039218822Sdimstatic void 7040218822Sdimdecode_complex_addend 7041218822Sdim (unsigned long * start, /* in bits */ 7042218822Sdim unsigned long * oplen, /* in bits */ 7043218822Sdim unsigned long * len, /* in bits */ 7044218822Sdim unsigned long * wordsz, /* in bytes */ 7045218822Sdim unsigned long * chunksz, /* in bytes */ 7046218822Sdim unsigned long * lsb0_p, 7047218822Sdim unsigned long * signed_p, 7048218822Sdim unsigned long * trunc_p, 7049218822Sdim unsigned long encoded) 7050218822Sdim{ 7051218822Sdim * start = encoded & 0x3F; 7052218822Sdim * len = (encoded >> 6) & 0x3F; 7053218822Sdim * oplen = (encoded >> 12) & 0x3F; 7054218822Sdim * wordsz = (encoded >> 18) & 0xF; 7055218822Sdim * chunksz = (encoded >> 22) & 0xF; 7056218822Sdim * lsb0_p = (encoded >> 27) & 1; 7057218822Sdim * signed_p = (encoded >> 28) & 1; 7058218822Sdim * trunc_p = (encoded >> 29) & 1; 7059218822Sdim} 7060218822Sdim 7061218822Sdimvoid 7062218822Sdimbfd_elf_perform_complex_relocation 7063218822Sdim (bfd * output_bfd ATTRIBUTE_UNUSED, 7064218822Sdim struct bfd_link_info * info, 7065218822Sdim bfd * input_bfd, 7066218822Sdim asection * input_section, 7067218822Sdim bfd_byte * contents, 7068218822Sdim Elf_Internal_Rela * rel, 7069218822Sdim Elf_Internal_Sym * local_syms, 7070218822Sdim asection ** local_sections) 7071218822Sdim{ 7072218822Sdim const struct elf_backend_data * bed; 7073218822Sdim Elf_Internal_Shdr * symtab_hdr; 7074218822Sdim asection * sec; 7075218822Sdim bfd_vma relocation = 0, shift, x; 7076218822Sdim bfd_vma r_symndx; 7077218822Sdim bfd_vma mask; 7078218822Sdim unsigned long start, oplen, len, wordsz, 7079218822Sdim chunksz, lsb0_p, signed_p, trunc_p; 7080218822Sdim 7081218822Sdim /* Perform this reloc, since it is complex. 7082218822Sdim (this is not to say that it necessarily refers to a complex 7083218822Sdim symbol; merely that it is a self-describing CGEN based reloc. 7084218822Sdim i.e. the addend has the complete reloc information (bit start, end, 7085218822Sdim word size, etc) encoded within it.). */ 7086218822Sdim r_symndx = ELF32_R_SYM (rel->r_info); 7087218822Sdim bed = get_elf_backend_data (input_bfd); 7088218822Sdim if (bed->s->arch_size == 64) 7089218822Sdim r_symndx >>= 24; 7090218822Sdim 7091218822Sdim#ifdef DEBUG 7092218822Sdim printf ("Performing complex relocation %ld...\n", r_symndx); 7093218822Sdim#endif 7094218822Sdim 7095218822Sdim symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr; 7096218822Sdim if (r_symndx < symtab_hdr->sh_info) 7097218822Sdim { 7098218822Sdim /* The symbol is local. */ 7099218822Sdim Elf_Internal_Sym * sym; 7100218822Sdim 7101218822Sdim sym = local_syms + r_symndx; 7102218822Sdim sec = local_sections [r_symndx]; 7103218822Sdim relocation = sym->st_value; 7104218822Sdim if (sym->st_shndx > SHN_UNDEF && 7105218822Sdim sym->st_shndx < SHN_LORESERVE) 7106218822Sdim relocation += (sec->output_offset + 7107218822Sdim sec->output_section->vma); 7108218822Sdim } 7109218822Sdim else 7110218822Sdim { 7111218822Sdim /* The symbol is global. */ 7112218822Sdim struct elf_link_hash_entry **sym_hashes; 7113218822Sdim struct elf_link_hash_entry * h; 7114218822Sdim 7115218822Sdim sym_hashes = elf_sym_hashes (input_bfd); 7116218822Sdim h = sym_hashes [r_symndx]; 7117218822Sdim 7118218822Sdim while (h->root.type == bfd_link_hash_indirect 7119218822Sdim || h->root.type == bfd_link_hash_warning) 7120218822Sdim h = (struct elf_link_hash_entry *) h->root.u.i.link; 7121218822Sdim 7122218822Sdim if (h->root.type == bfd_link_hash_defined 7123218822Sdim || h->root.type == bfd_link_hash_defweak) 7124218822Sdim { 7125218822Sdim sec = h->root.u.def.section; 7126218822Sdim relocation = h->root.u.def.value; 7127218822Sdim 7128218822Sdim if (! bfd_is_abs_section (sec)) 7129218822Sdim relocation += (sec->output_section->vma 7130218822Sdim + sec->output_offset); 7131218822Sdim } 7132218822Sdim if (h->root.type == bfd_link_hash_undefined 7133218822Sdim && !((*info->callbacks->undefined_symbol) 7134218822Sdim (info, h->root.root.string, input_bfd, 7135218822Sdim input_section, rel->r_offset, 7136218822Sdim info->unresolved_syms_in_objects == RM_GENERATE_ERROR 7137218822Sdim || ELF_ST_VISIBILITY (h->other)))) 7138218822Sdim return; 7139218822Sdim } 7140218822Sdim 7141218822Sdim decode_complex_addend (& start, & oplen, & len, & wordsz, 7142218822Sdim & chunksz, & lsb0_p, & signed_p, 7143218822Sdim & trunc_p, rel->r_addend); 7144218822Sdim 7145218822Sdim mask = (((1L << (len - 1)) - 1) << 1) | 1; 7146218822Sdim 7147218822Sdim if (lsb0_p) 7148218822Sdim shift = (start + 1) - len; 7149218822Sdim else 7150218822Sdim shift = (8 * wordsz) - (start + len); 7151218822Sdim 7152218822Sdim x = get_value (wordsz, chunksz, input_bfd, contents + rel->r_offset); 7153218822Sdim 7154218822Sdim#ifdef DEBUG 7155218822Sdim printf ("Doing complex reloc: " 7156218822Sdim "lsb0? %ld, signed? %ld, trunc? %ld, wordsz %ld, " 7157218822Sdim "chunksz %ld, start %ld, len %ld, oplen %ld\n" 7158218822Sdim " dest: %8.8lx, mask: %8.8lx, reloc: %8.8lx\n", 7159218822Sdim lsb0_p, signed_p, trunc_p, wordsz, chunksz, start, len, 7160218822Sdim oplen, x, mask, relocation); 7161218822Sdim#endif 7162218822Sdim 7163218822Sdim if (! trunc_p) 7164218822Sdim { 7165218822Sdim /* Now do an overflow check. */ 7166218822Sdim if (bfd_check_overflow ((signed_p ? 7167218822Sdim complain_overflow_signed : 7168218822Sdim complain_overflow_unsigned), 7169218822Sdim len, 0, (8 * wordsz), 7170218822Sdim relocation) == bfd_reloc_overflow) 7171218822Sdim (*_bfd_error_handler) 7172218822Sdim ("%s (%s + 0x%lx): relocation overflow: 0x%lx %sdoes not fit " 7173218822Sdim "within 0x%lx", 7174218822Sdim input_bfd->filename, input_section->name, rel->r_offset, 7175218822Sdim relocation, (signed_p ? "(signed) " : ""), mask); 7176218822Sdim } 7177218822Sdim 7178218822Sdim /* Do the deed. */ 7179218822Sdim x = (x & ~(mask << shift)) | ((relocation & mask) << shift); 7180218822Sdim 7181218822Sdim#ifdef DEBUG 7182218822Sdim printf (" relocation: %8.8lx\n" 7183218822Sdim " shifted mask: %8.8lx\n" 7184218822Sdim " shifted/masked reloc: %8.8lx\n" 7185218822Sdim " result: %8.8lx\n", 7186218822Sdim relocation, (mask << shift), 7187218822Sdim ((relocation & mask) << shift), x); 7188218822Sdim#endif 7189218822Sdim put_value (wordsz, chunksz, input_bfd, x, contents + rel->r_offset); 7190218822Sdim} 7191218822Sdim 7192130561Sobrien/* When performing a relocatable link, the input relocations are 7193130561Sobrien preserved. But, if they reference global symbols, the indices 7194130561Sobrien referenced must be updated. Update all the relocations in 7195130561Sobrien REL_HDR (there are COUNT of them), using the data in REL_HASH. */ 7196130561Sobrien 7197130561Sobrienstatic void 7198130561Sobrienelf_link_adjust_relocs (bfd *abfd, 7199130561Sobrien Elf_Internal_Shdr *rel_hdr, 7200130561Sobrien unsigned int count, 7201130561Sobrien struct elf_link_hash_entry **rel_hash) 7202130561Sobrien{ 7203130561Sobrien unsigned int i; 7204130561Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 7205130561Sobrien bfd_byte *erela; 7206130561Sobrien void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *); 7207130561Sobrien void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *); 7208130561Sobrien bfd_vma r_type_mask; 7209130561Sobrien int r_sym_shift; 7210130561Sobrien 7211130561Sobrien if (rel_hdr->sh_entsize == bed->s->sizeof_rel) 7212130561Sobrien { 7213130561Sobrien swap_in = bed->s->swap_reloc_in; 7214130561Sobrien swap_out = bed->s->swap_reloc_out; 7215130561Sobrien } 7216130561Sobrien else if (rel_hdr->sh_entsize == bed->s->sizeof_rela) 7217130561Sobrien { 7218130561Sobrien swap_in = bed->s->swap_reloca_in; 7219130561Sobrien swap_out = bed->s->swap_reloca_out; 7220130561Sobrien } 7221130561Sobrien else 7222130561Sobrien abort (); 7223130561Sobrien 7224130561Sobrien if (bed->s->int_rels_per_ext_rel > MAX_INT_RELS_PER_EXT_REL) 7225130561Sobrien abort (); 7226130561Sobrien 7227130561Sobrien if (bed->s->arch_size == 32) 7228130561Sobrien { 7229130561Sobrien r_type_mask = 0xff; 7230130561Sobrien r_sym_shift = 8; 7231130561Sobrien } 7232130561Sobrien else 7233130561Sobrien { 7234130561Sobrien r_type_mask = 0xffffffff; 7235130561Sobrien r_sym_shift = 32; 7236130561Sobrien } 7237130561Sobrien 7238130561Sobrien erela = rel_hdr->contents; 7239130561Sobrien for (i = 0; i < count; i++, rel_hash++, erela += rel_hdr->sh_entsize) 7240130561Sobrien { 7241130561Sobrien Elf_Internal_Rela irela[MAX_INT_RELS_PER_EXT_REL]; 7242130561Sobrien unsigned int j; 7243130561Sobrien 7244130561Sobrien if (*rel_hash == NULL) 7245130561Sobrien continue; 7246130561Sobrien 7247130561Sobrien BFD_ASSERT ((*rel_hash)->indx >= 0); 7248130561Sobrien 7249130561Sobrien (*swap_in) (abfd, erela, irela); 7250130561Sobrien for (j = 0; j < bed->s->int_rels_per_ext_rel; j++) 7251130561Sobrien irela[j].r_info = ((bfd_vma) (*rel_hash)->indx << r_sym_shift 7252130561Sobrien | (irela[j].r_info & r_type_mask)); 7253130561Sobrien (*swap_out) (abfd, irela, erela); 7254130561Sobrien } 7255130561Sobrien} 7256130561Sobrien 7257130561Sobrienstruct elf_link_sort_rela 7258130561Sobrien{ 7259130561Sobrien union { 7260130561Sobrien bfd_vma offset; 7261130561Sobrien bfd_vma sym_mask; 7262130561Sobrien } u; 7263130561Sobrien enum elf_reloc_type_class type; 7264130561Sobrien /* We use this as an array of size int_rels_per_ext_rel. */ 7265130561Sobrien Elf_Internal_Rela rela[1]; 7266130561Sobrien}; 7267130561Sobrien 7268130561Sobrienstatic int 7269130561Sobrienelf_link_sort_cmp1 (const void *A, const void *B) 7270130561Sobrien{ 7271130561Sobrien const struct elf_link_sort_rela *a = A; 7272130561Sobrien const struct elf_link_sort_rela *b = B; 7273130561Sobrien int relativea, relativeb; 7274130561Sobrien 7275130561Sobrien relativea = a->type == reloc_class_relative; 7276130561Sobrien relativeb = b->type == reloc_class_relative; 7277130561Sobrien 7278130561Sobrien if (relativea < relativeb) 7279130561Sobrien return 1; 7280130561Sobrien if (relativea > relativeb) 7281130561Sobrien return -1; 7282130561Sobrien if ((a->rela->r_info & a->u.sym_mask) < (b->rela->r_info & b->u.sym_mask)) 7283130561Sobrien return -1; 7284130561Sobrien if ((a->rela->r_info & a->u.sym_mask) > (b->rela->r_info & b->u.sym_mask)) 7285130561Sobrien return 1; 7286130561Sobrien if (a->rela->r_offset < b->rela->r_offset) 7287130561Sobrien return -1; 7288130561Sobrien if (a->rela->r_offset > b->rela->r_offset) 7289130561Sobrien return 1; 7290130561Sobrien return 0; 7291130561Sobrien} 7292130561Sobrien 7293130561Sobrienstatic int 7294130561Sobrienelf_link_sort_cmp2 (const void *A, const void *B) 7295130561Sobrien{ 7296130561Sobrien const struct elf_link_sort_rela *a = A; 7297130561Sobrien const struct elf_link_sort_rela *b = B; 7298130561Sobrien int copya, copyb; 7299130561Sobrien 7300130561Sobrien if (a->u.offset < b->u.offset) 7301130561Sobrien return -1; 7302130561Sobrien if (a->u.offset > b->u.offset) 7303130561Sobrien return 1; 7304130561Sobrien copya = (a->type == reloc_class_copy) * 2 + (a->type == reloc_class_plt); 7305130561Sobrien copyb = (b->type == reloc_class_copy) * 2 + (b->type == reloc_class_plt); 7306130561Sobrien if (copya < copyb) 7307130561Sobrien return -1; 7308130561Sobrien if (copya > copyb) 7309130561Sobrien return 1; 7310130561Sobrien if (a->rela->r_offset < b->rela->r_offset) 7311130561Sobrien return -1; 7312130561Sobrien if (a->rela->r_offset > b->rela->r_offset) 7313130561Sobrien return 1; 7314130561Sobrien return 0; 7315130561Sobrien} 7316130561Sobrien 7317130561Sobrienstatic size_t 7318130561Sobrienelf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec) 7319130561Sobrien{ 7320218822Sdim asection *dynamic_relocs; 7321218822Sdim asection *rela_dyn; 7322218822Sdim asection *rel_dyn; 7323130561Sobrien bfd_size_type count, size; 7324130561Sobrien size_t i, ret, sort_elt, ext_size; 7325130561Sobrien bfd_byte *sort, *s_non_relative, *p; 7326130561Sobrien struct elf_link_sort_rela *sq; 7327130561Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 7328130561Sobrien int i2e = bed->s->int_rels_per_ext_rel; 7329130561Sobrien void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *); 7330130561Sobrien void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *); 7331130561Sobrien struct bfd_link_order *lo; 7332130561Sobrien bfd_vma r_sym_mask; 7333218822Sdim bfd_boolean use_rela; 7334130561Sobrien 7335218822Sdim /* Find a dynamic reloc section. */ 7336218822Sdim rela_dyn = bfd_get_section_by_name (abfd, ".rela.dyn"); 7337218822Sdim rel_dyn = bfd_get_section_by_name (abfd, ".rel.dyn"); 7338218822Sdim if (rela_dyn != NULL && rela_dyn->size > 0 7339218822Sdim && rel_dyn != NULL && rel_dyn->size > 0) 7340130561Sobrien { 7341218822Sdim bfd_boolean use_rela_initialised = FALSE; 7342218822Sdim 7343218822Sdim /* This is just here to stop gcc from complaining. 7344218822Sdim It's initialization checking code is not perfect. */ 7345218822Sdim use_rela = TRUE; 7346218822Sdim 7347218822Sdim /* Both sections are present. Examine the sizes 7348218822Sdim of the indirect sections to help us choose. */ 7349218822Sdim for (lo = rela_dyn->map_head.link_order; lo != NULL; lo = lo->next) 7350218822Sdim if (lo->type == bfd_indirect_link_order) 7351218822Sdim { 7352218822Sdim asection *o = lo->u.indirect.section; 7353218822Sdim 7354218822Sdim if ((o->size % bed->s->sizeof_rela) == 0) 7355218822Sdim { 7356218822Sdim if ((o->size % bed->s->sizeof_rel) == 0) 7357218822Sdim /* Section size is divisible by both rel and rela sizes. 7358218822Sdim It is of no help to us. */ 7359218822Sdim ; 7360218822Sdim else 7361218822Sdim { 7362218822Sdim /* Section size is only divisible by rela. */ 7363218822Sdim if (use_rela_initialised && (use_rela == FALSE)) 7364218822Sdim { 7365218822Sdim _bfd_error_handler 7366218822Sdim (_("%B: Unable to sort relocs - they are in more than one size"), abfd); 7367218822Sdim bfd_set_error (bfd_error_invalid_operation); 7368218822Sdim return 0; 7369218822Sdim } 7370218822Sdim else 7371218822Sdim { 7372218822Sdim use_rela = TRUE; 7373218822Sdim use_rela_initialised = TRUE; 7374218822Sdim } 7375218822Sdim } 7376218822Sdim } 7377218822Sdim else if ((o->size % bed->s->sizeof_rel) == 0) 7378218822Sdim { 7379218822Sdim /* Section size is only divisible by rel. */ 7380218822Sdim if (use_rela_initialised && (use_rela == TRUE)) 7381218822Sdim { 7382218822Sdim _bfd_error_handler 7383218822Sdim (_("%B: Unable to sort relocs - they are in more than one size"), abfd); 7384218822Sdim bfd_set_error (bfd_error_invalid_operation); 7385218822Sdim return 0; 7386218822Sdim } 7387218822Sdim else 7388218822Sdim { 7389218822Sdim use_rela = FALSE; 7390218822Sdim use_rela_initialised = TRUE; 7391218822Sdim } 7392218822Sdim } 7393218822Sdim else 7394218822Sdim { 7395218822Sdim /* The section size is not divisible by either - something is wrong. */ 7396218822Sdim _bfd_error_handler 7397218822Sdim (_("%B: Unable to sort relocs - they are of an unknown size"), abfd); 7398218822Sdim bfd_set_error (bfd_error_invalid_operation); 7399218822Sdim return 0; 7400218822Sdim } 7401218822Sdim } 7402218822Sdim 7403218822Sdim for (lo = rel_dyn->map_head.link_order; lo != NULL; lo = lo->next) 7404218822Sdim if (lo->type == bfd_indirect_link_order) 7405218822Sdim { 7406218822Sdim asection *o = lo->u.indirect.section; 7407218822Sdim 7408218822Sdim if ((o->size % bed->s->sizeof_rela) == 0) 7409218822Sdim { 7410218822Sdim if ((o->size % bed->s->sizeof_rel) == 0) 7411218822Sdim /* Section size is divisible by both rel and rela sizes. 7412218822Sdim It is of no help to us. */ 7413218822Sdim ; 7414218822Sdim else 7415218822Sdim { 7416218822Sdim /* Section size is only divisible by rela. */ 7417218822Sdim if (use_rela_initialised && (use_rela == FALSE)) 7418218822Sdim { 7419218822Sdim _bfd_error_handler 7420218822Sdim (_("%B: Unable to sort relocs - they are in more than one size"), abfd); 7421218822Sdim bfd_set_error (bfd_error_invalid_operation); 7422218822Sdim return 0; 7423218822Sdim } 7424218822Sdim else 7425218822Sdim { 7426218822Sdim use_rela = TRUE; 7427218822Sdim use_rela_initialised = TRUE; 7428218822Sdim } 7429218822Sdim } 7430218822Sdim } 7431218822Sdim else if ((o->size % bed->s->sizeof_rel) == 0) 7432218822Sdim { 7433218822Sdim /* Section size is only divisible by rel. */ 7434218822Sdim if (use_rela_initialised && (use_rela == TRUE)) 7435218822Sdim { 7436218822Sdim _bfd_error_handler 7437218822Sdim (_("%B: Unable to sort relocs - they are in more than one size"), abfd); 7438218822Sdim bfd_set_error (bfd_error_invalid_operation); 7439218822Sdim return 0; 7440218822Sdim } 7441218822Sdim else 7442218822Sdim { 7443218822Sdim use_rela = FALSE; 7444218822Sdim use_rela_initialised = TRUE; 7445218822Sdim } 7446218822Sdim } 7447218822Sdim else 7448218822Sdim { 7449218822Sdim /* The section size is not divisible by either - something is wrong. */ 7450218822Sdim _bfd_error_handler 7451218822Sdim (_("%B: Unable to sort relocs - they are of an unknown size"), abfd); 7452218822Sdim bfd_set_error (bfd_error_invalid_operation); 7453218822Sdim return 0; 7454218822Sdim } 7455218822Sdim } 7456218822Sdim 7457218822Sdim if (! use_rela_initialised) 7458218822Sdim /* Make a guess. */ 7459218822Sdim use_rela = TRUE; 7460130561Sobrien } 7461218822Sdim else if (rela_dyn != NULL && rela_dyn->size > 0) 7462218822Sdim use_rela = TRUE; 7463218822Sdim else if (rel_dyn != NULL && rel_dyn->size > 0) 7464218822Sdim use_rela = FALSE; 7465130561Sobrien else 7466218822Sdim return 0; 7467218822Sdim 7468218822Sdim if (use_rela) 7469130561Sobrien { 7470218822Sdim dynamic_relocs = rela_dyn; 7471130561Sobrien ext_size = bed->s->sizeof_rela; 7472130561Sobrien swap_in = bed->s->swap_reloca_in; 7473130561Sobrien swap_out = bed->s->swap_reloca_out; 7474130561Sobrien } 7475218822Sdim else 7476218822Sdim { 7477218822Sdim dynamic_relocs = rel_dyn; 7478218822Sdim ext_size = bed->s->sizeof_rel; 7479218822Sdim swap_in = bed->s->swap_reloc_in; 7480218822Sdim swap_out = bed->s->swap_reloc_out; 7481218822Sdim } 7482130561Sobrien 7483130561Sobrien size = 0; 7484218822Sdim for (lo = dynamic_relocs->map_head.link_order; lo != NULL; lo = lo->next) 7485130561Sobrien if (lo->type == bfd_indirect_link_order) 7486218822Sdim size += lo->u.indirect.section->size; 7487130561Sobrien 7488218822Sdim if (size != dynamic_relocs->size) 7489130561Sobrien return 0; 7490130561Sobrien 7491130561Sobrien sort_elt = (sizeof (struct elf_link_sort_rela) 7492130561Sobrien + (i2e - 1) * sizeof (Elf_Internal_Rela)); 7493218822Sdim 7494218822Sdim count = dynamic_relocs->size / ext_size; 7495130561Sobrien sort = bfd_zmalloc (sort_elt * count); 7496218822Sdim 7497130561Sobrien if (sort == NULL) 7498130561Sobrien { 7499130561Sobrien (*info->callbacks->warning) 7500130561Sobrien (info, _("Not enough memory to sort relocations"), 0, abfd, 0, 0); 7501130561Sobrien return 0; 7502130561Sobrien } 7503130561Sobrien 7504130561Sobrien if (bed->s->arch_size == 32) 7505130561Sobrien r_sym_mask = ~(bfd_vma) 0xff; 7506130561Sobrien else 7507130561Sobrien r_sym_mask = ~(bfd_vma) 0xffffffff; 7508130561Sobrien 7509218822Sdim for (lo = dynamic_relocs->map_head.link_order; lo != NULL; lo = lo->next) 7510130561Sobrien if (lo->type == bfd_indirect_link_order) 7511130561Sobrien { 7512130561Sobrien bfd_byte *erel, *erelend; 7513130561Sobrien asection *o = lo->u.indirect.section; 7514130561Sobrien 7515218822Sdim if (o->contents == NULL && o->size != 0) 7516218822Sdim { 7517218822Sdim /* This is a reloc section that is being handled as a normal 7518218822Sdim section. See bfd_section_from_shdr. We can't combine 7519218822Sdim relocs in this case. */ 7520218822Sdim free (sort); 7521218822Sdim return 0; 7522218822Sdim } 7523130561Sobrien erel = o->contents; 7524218822Sdim erelend = o->contents + o->size; 7525130561Sobrien p = sort + o->output_offset / ext_size * sort_elt; 7526218822Sdim 7527130561Sobrien while (erel < erelend) 7528130561Sobrien { 7529130561Sobrien struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p; 7530218822Sdim 7531130561Sobrien (*swap_in) (abfd, erel, s->rela); 7532130561Sobrien s->type = (*bed->elf_backend_reloc_type_class) (s->rela); 7533130561Sobrien s->u.sym_mask = r_sym_mask; 7534130561Sobrien p += sort_elt; 7535130561Sobrien erel += ext_size; 7536130561Sobrien } 7537130561Sobrien } 7538130561Sobrien 7539130561Sobrien qsort (sort, count, sort_elt, elf_link_sort_cmp1); 7540130561Sobrien 7541130561Sobrien for (i = 0, p = sort; i < count; i++, p += sort_elt) 7542130561Sobrien { 7543130561Sobrien struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p; 7544130561Sobrien if (s->type != reloc_class_relative) 7545130561Sobrien break; 7546130561Sobrien } 7547130561Sobrien ret = i; 7548130561Sobrien s_non_relative = p; 7549130561Sobrien 7550130561Sobrien sq = (struct elf_link_sort_rela *) s_non_relative; 7551130561Sobrien for (; i < count; i++, p += sort_elt) 7552130561Sobrien { 7553130561Sobrien struct elf_link_sort_rela *sp = (struct elf_link_sort_rela *) p; 7554130561Sobrien if (((sp->rela->r_info ^ sq->rela->r_info) & r_sym_mask) != 0) 7555130561Sobrien sq = sp; 7556130561Sobrien sp->u.offset = sq->rela->r_offset; 7557130561Sobrien } 7558130561Sobrien 7559130561Sobrien qsort (s_non_relative, count - ret, sort_elt, elf_link_sort_cmp2); 7560130561Sobrien 7561218822Sdim for (lo = dynamic_relocs->map_head.link_order; lo != NULL; lo = lo->next) 7562130561Sobrien if (lo->type == bfd_indirect_link_order) 7563130561Sobrien { 7564130561Sobrien bfd_byte *erel, *erelend; 7565130561Sobrien asection *o = lo->u.indirect.section; 7566130561Sobrien 7567130561Sobrien erel = o->contents; 7568218822Sdim erelend = o->contents + o->size; 7569130561Sobrien p = sort + o->output_offset / ext_size * sort_elt; 7570130561Sobrien while (erel < erelend) 7571130561Sobrien { 7572130561Sobrien struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p; 7573130561Sobrien (*swap_out) (abfd, s->rela, erel); 7574130561Sobrien p += sort_elt; 7575130561Sobrien erel += ext_size; 7576130561Sobrien } 7577130561Sobrien } 7578130561Sobrien 7579130561Sobrien free (sort); 7580218822Sdim *psec = dynamic_relocs; 7581130561Sobrien return ret; 7582130561Sobrien} 7583130561Sobrien 7584130561Sobrien/* Flush the output symbols to the file. */ 7585130561Sobrien 7586130561Sobrienstatic bfd_boolean 7587130561Sobrienelf_link_flush_output_syms (struct elf_final_link_info *finfo, 7588130561Sobrien const struct elf_backend_data *bed) 7589130561Sobrien{ 7590130561Sobrien if (finfo->symbuf_count > 0) 7591130561Sobrien { 7592130561Sobrien Elf_Internal_Shdr *hdr; 7593130561Sobrien file_ptr pos; 7594130561Sobrien bfd_size_type amt; 7595130561Sobrien 7596130561Sobrien hdr = &elf_tdata (finfo->output_bfd)->symtab_hdr; 7597130561Sobrien pos = hdr->sh_offset + hdr->sh_size; 7598130561Sobrien amt = finfo->symbuf_count * bed->s->sizeof_sym; 7599130561Sobrien if (bfd_seek (finfo->output_bfd, pos, SEEK_SET) != 0 7600130561Sobrien || bfd_bwrite (finfo->symbuf, amt, finfo->output_bfd) != amt) 7601130561Sobrien return FALSE; 7602130561Sobrien 7603130561Sobrien hdr->sh_size += amt; 7604130561Sobrien finfo->symbuf_count = 0; 7605130561Sobrien } 7606130561Sobrien 7607130561Sobrien return TRUE; 7608130561Sobrien} 7609130561Sobrien 7610130561Sobrien/* Add a symbol to the output symbol table. */ 7611130561Sobrien 7612130561Sobrienstatic bfd_boolean 7613130561Sobrienelf_link_output_sym (struct elf_final_link_info *finfo, 7614130561Sobrien const char *name, 7615130561Sobrien Elf_Internal_Sym *elfsym, 7616130561Sobrien asection *input_sec, 7617130561Sobrien struct elf_link_hash_entry *h) 7618130561Sobrien{ 7619130561Sobrien bfd_byte *dest; 7620130561Sobrien Elf_External_Sym_Shndx *destshndx; 7621130561Sobrien bfd_boolean (*output_symbol_hook) 7622130561Sobrien (struct bfd_link_info *, const char *, Elf_Internal_Sym *, asection *, 7623130561Sobrien struct elf_link_hash_entry *); 7624130561Sobrien const struct elf_backend_data *bed; 7625130561Sobrien 7626130561Sobrien bed = get_elf_backend_data (finfo->output_bfd); 7627130561Sobrien output_symbol_hook = bed->elf_backend_link_output_symbol_hook; 7628130561Sobrien if (output_symbol_hook != NULL) 7629130561Sobrien { 7630130561Sobrien if (! (*output_symbol_hook) (finfo->info, name, elfsym, input_sec, h)) 7631130561Sobrien return FALSE; 7632130561Sobrien } 7633130561Sobrien 7634130561Sobrien if (name == NULL || *name == '\0') 7635130561Sobrien elfsym->st_name = 0; 7636130561Sobrien else if (input_sec->flags & SEC_EXCLUDE) 7637130561Sobrien elfsym->st_name = 0; 7638130561Sobrien else 7639130561Sobrien { 7640130561Sobrien elfsym->st_name = (unsigned long) _bfd_stringtab_add (finfo->symstrtab, 7641130561Sobrien name, TRUE, FALSE); 7642130561Sobrien if (elfsym->st_name == (unsigned long) -1) 7643130561Sobrien return FALSE; 7644130561Sobrien } 7645130561Sobrien 7646130561Sobrien if (finfo->symbuf_count >= finfo->symbuf_size) 7647130561Sobrien { 7648130561Sobrien if (! elf_link_flush_output_syms (finfo, bed)) 7649130561Sobrien return FALSE; 7650130561Sobrien } 7651130561Sobrien 7652130561Sobrien dest = finfo->symbuf + finfo->symbuf_count * bed->s->sizeof_sym; 7653130561Sobrien destshndx = finfo->symshndxbuf; 7654130561Sobrien if (destshndx != NULL) 7655130561Sobrien { 7656130561Sobrien if (bfd_get_symcount (finfo->output_bfd) >= finfo->shndxbuf_size) 7657130561Sobrien { 7658130561Sobrien bfd_size_type amt; 7659130561Sobrien 7660130561Sobrien amt = finfo->shndxbuf_size * sizeof (Elf_External_Sym_Shndx); 7661130561Sobrien finfo->symshndxbuf = destshndx = bfd_realloc (destshndx, amt * 2); 7662130561Sobrien if (destshndx == NULL) 7663130561Sobrien return FALSE; 7664130561Sobrien memset ((char *) destshndx + amt, 0, amt); 7665130561Sobrien finfo->shndxbuf_size *= 2; 7666130561Sobrien } 7667130561Sobrien destshndx += bfd_get_symcount (finfo->output_bfd); 7668130561Sobrien } 7669130561Sobrien 7670130561Sobrien bed->s->swap_symbol_out (finfo->output_bfd, elfsym, dest, destshndx); 7671130561Sobrien finfo->symbuf_count += 1; 7672130561Sobrien bfd_get_symcount (finfo->output_bfd) += 1; 7673130561Sobrien 7674130561Sobrien return TRUE; 7675130561Sobrien} 7676130561Sobrien 7677218822Sdim/* Return TRUE if the dynamic symbol SYM in ABFD is supported. */ 7678218822Sdim 7679218822Sdimstatic bfd_boolean 7680218822Sdimcheck_dynsym (bfd *abfd, Elf_Internal_Sym *sym) 7681218822Sdim{ 7682218822Sdim if (sym->st_shndx > SHN_HIRESERVE) 7683218822Sdim { 7684218822Sdim /* The gABI doesn't support dynamic symbols in output sections 7685218822Sdim beyond 64k. */ 7686218822Sdim (*_bfd_error_handler) 7687218822Sdim (_("%B: Too many sections: %d (>= %d)"), 7688218822Sdim abfd, bfd_count_sections (abfd), SHN_LORESERVE); 7689218822Sdim bfd_set_error (bfd_error_nonrepresentable_section); 7690218822Sdim return FALSE; 7691218822Sdim } 7692218822Sdim return TRUE; 7693218822Sdim} 7694218822Sdim 7695130561Sobrien/* For DSOs loaded in via a DT_NEEDED entry, emulate ld.so in 7696130561Sobrien allowing an unsatisfied unversioned symbol in the DSO to match a 7697130561Sobrien versioned symbol that would normally require an explicit version. 7698130561Sobrien We also handle the case that a DSO references a hidden symbol 7699130561Sobrien which may be satisfied by a versioned symbol in another DSO. */ 7700130561Sobrien 7701130561Sobrienstatic bfd_boolean 7702130561Sobrienelf_link_check_versioned_symbol (struct bfd_link_info *info, 7703130561Sobrien const struct elf_backend_data *bed, 7704130561Sobrien struct elf_link_hash_entry *h) 7705130561Sobrien{ 7706130561Sobrien bfd *abfd; 7707130561Sobrien struct elf_link_loaded_list *loaded; 7708130561Sobrien 7709130561Sobrien if (!is_elf_hash_table (info->hash)) 7710130561Sobrien return FALSE; 7711130561Sobrien 7712130561Sobrien switch (h->root.type) 7713130561Sobrien { 7714130561Sobrien default: 7715130561Sobrien abfd = NULL; 7716130561Sobrien break; 7717130561Sobrien 7718130561Sobrien case bfd_link_hash_undefined: 7719130561Sobrien case bfd_link_hash_undefweak: 7720130561Sobrien abfd = h->root.u.undef.abfd; 7721130561Sobrien if ((abfd->flags & DYNAMIC) == 0 7722218822Sdim || (elf_dyn_lib_class (abfd) & DYN_DT_NEEDED) == 0) 7723130561Sobrien return FALSE; 7724130561Sobrien break; 7725130561Sobrien 7726130561Sobrien case bfd_link_hash_defined: 7727130561Sobrien case bfd_link_hash_defweak: 7728130561Sobrien abfd = h->root.u.def.section->owner; 7729130561Sobrien break; 7730130561Sobrien 7731130561Sobrien case bfd_link_hash_common: 7732130561Sobrien abfd = h->root.u.c.p->section->owner; 7733130561Sobrien break; 7734130561Sobrien } 7735130561Sobrien BFD_ASSERT (abfd != NULL); 7736130561Sobrien 7737130561Sobrien for (loaded = elf_hash_table (info)->loaded; 7738130561Sobrien loaded != NULL; 7739130561Sobrien loaded = loaded->next) 7740130561Sobrien { 7741130561Sobrien bfd *input; 7742130561Sobrien Elf_Internal_Shdr *hdr; 7743130561Sobrien bfd_size_type symcount; 7744130561Sobrien bfd_size_type extsymcount; 7745130561Sobrien bfd_size_type extsymoff; 7746130561Sobrien Elf_Internal_Shdr *versymhdr; 7747130561Sobrien Elf_Internal_Sym *isym; 7748130561Sobrien Elf_Internal_Sym *isymend; 7749130561Sobrien Elf_Internal_Sym *isymbuf; 7750130561Sobrien Elf_External_Versym *ever; 7751130561Sobrien Elf_External_Versym *extversym; 7752130561Sobrien 7753130561Sobrien input = loaded->abfd; 7754130561Sobrien 7755130561Sobrien /* We check each DSO for a possible hidden versioned definition. */ 7756130561Sobrien if (input == abfd 7757130561Sobrien || (input->flags & DYNAMIC) == 0 7758130561Sobrien || elf_dynversym (input) == 0) 7759130561Sobrien continue; 7760130561Sobrien 7761130561Sobrien hdr = &elf_tdata (input)->dynsymtab_hdr; 7762130561Sobrien 7763130561Sobrien symcount = hdr->sh_size / bed->s->sizeof_sym; 7764130561Sobrien if (elf_bad_symtab (input)) 7765130561Sobrien { 7766130561Sobrien extsymcount = symcount; 7767130561Sobrien extsymoff = 0; 7768130561Sobrien } 7769130561Sobrien else 7770130561Sobrien { 7771130561Sobrien extsymcount = symcount - hdr->sh_info; 7772130561Sobrien extsymoff = hdr->sh_info; 7773130561Sobrien } 7774130561Sobrien 7775130561Sobrien if (extsymcount == 0) 7776130561Sobrien continue; 7777130561Sobrien 7778130561Sobrien isymbuf = bfd_elf_get_elf_syms (input, hdr, extsymcount, extsymoff, 7779130561Sobrien NULL, NULL, NULL); 7780130561Sobrien if (isymbuf == NULL) 7781130561Sobrien return FALSE; 7782130561Sobrien 7783130561Sobrien /* Read in any version definitions. */ 7784130561Sobrien versymhdr = &elf_tdata (input)->dynversym_hdr; 7785130561Sobrien extversym = bfd_malloc (versymhdr->sh_size); 7786130561Sobrien if (extversym == NULL) 7787130561Sobrien goto error_ret; 7788130561Sobrien 7789130561Sobrien if (bfd_seek (input, versymhdr->sh_offset, SEEK_SET) != 0 7790130561Sobrien || (bfd_bread (extversym, versymhdr->sh_size, input) 7791130561Sobrien != versymhdr->sh_size)) 7792130561Sobrien { 7793130561Sobrien free (extversym); 7794130561Sobrien error_ret: 7795130561Sobrien free (isymbuf); 7796130561Sobrien return FALSE; 7797130561Sobrien } 7798130561Sobrien 7799130561Sobrien ever = extversym + extsymoff; 7800130561Sobrien isymend = isymbuf + extsymcount; 7801130561Sobrien for (isym = isymbuf; isym < isymend; isym++, ever++) 7802130561Sobrien { 7803130561Sobrien const char *name; 7804130561Sobrien Elf_Internal_Versym iver; 7805130561Sobrien unsigned short version_index; 7806130561Sobrien 7807130561Sobrien if (ELF_ST_BIND (isym->st_info) == STB_LOCAL 7808130561Sobrien || isym->st_shndx == SHN_UNDEF) 7809130561Sobrien continue; 7810130561Sobrien 7811130561Sobrien name = bfd_elf_string_from_elf_section (input, 7812130561Sobrien hdr->sh_link, 7813130561Sobrien isym->st_name); 7814130561Sobrien if (strcmp (name, h->root.root.string) != 0) 7815130561Sobrien continue; 7816130561Sobrien 7817130561Sobrien _bfd_elf_swap_versym_in (input, ever, &iver); 7818130561Sobrien 7819130561Sobrien if ((iver.vs_vers & VERSYM_HIDDEN) == 0) 7820130561Sobrien { 7821130561Sobrien /* If we have a non-hidden versioned sym, then it should 7822130561Sobrien have provided a definition for the undefined sym. */ 7823130561Sobrien abort (); 7824130561Sobrien } 7825130561Sobrien 7826130561Sobrien version_index = iver.vs_vers & VERSYM_VERSION; 7827130561Sobrien if (version_index == 1 || version_index == 2) 7828130561Sobrien { 7829130561Sobrien /* This is the base or first version. We can use it. */ 7830130561Sobrien free (extversym); 7831130561Sobrien free (isymbuf); 7832130561Sobrien return TRUE; 7833130561Sobrien } 7834130561Sobrien } 7835130561Sobrien 7836130561Sobrien free (extversym); 7837130561Sobrien free (isymbuf); 7838130561Sobrien } 7839130561Sobrien 7840130561Sobrien return FALSE; 7841130561Sobrien} 7842130561Sobrien 7843130561Sobrien/* Add an external symbol to the symbol table. This is called from 7844130561Sobrien the hash table traversal routine. When generating a shared object, 7845130561Sobrien we go through the symbol table twice. The first time we output 7846130561Sobrien anything that might have been forced to local scope in a version 7847130561Sobrien script. The second time we output the symbols that are still 7848130561Sobrien global symbols. */ 7849130561Sobrien 7850130561Sobrienstatic bfd_boolean 7851130561Sobrienelf_link_output_extsym (struct elf_link_hash_entry *h, void *data) 7852130561Sobrien{ 7853130561Sobrien struct elf_outext_info *eoinfo = data; 7854130561Sobrien struct elf_final_link_info *finfo = eoinfo->finfo; 7855130561Sobrien bfd_boolean strip; 7856130561Sobrien Elf_Internal_Sym sym; 7857130561Sobrien asection *input_sec; 7858130561Sobrien const struct elf_backend_data *bed; 7859130561Sobrien 7860130561Sobrien if (h->root.type == bfd_link_hash_warning) 7861130561Sobrien { 7862130561Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 7863130561Sobrien if (h->root.type == bfd_link_hash_new) 7864130561Sobrien return TRUE; 7865130561Sobrien } 7866130561Sobrien 7867130561Sobrien /* Decide whether to output this symbol in this pass. */ 7868130561Sobrien if (eoinfo->localsyms) 7869130561Sobrien { 7870218822Sdim if (!h->forced_local) 7871130561Sobrien return TRUE; 7872130561Sobrien } 7873130561Sobrien else 7874130561Sobrien { 7875218822Sdim if (h->forced_local) 7876130561Sobrien return TRUE; 7877130561Sobrien } 7878130561Sobrien 7879130561Sobrien bed = get_elf_backend_data (finfo->output_bfd); 7880130561Sobrien 7881218822Sdim if (h->root.type == bfd_link_hash_undefined) 7882130561Sobrien { 7883218822Sdim /* If we have an undefined symbol reference here then it must have 7884218822Sdim come from a shared library that is being linked in. (Undefined 7885218822Sdim references in regular files have already been handled). */ 7886218822Sdim bfd_boolean ignore_undef = FALSE; 7887218822Sdim 7888218822Sdim /* Some symbols may be special in that the fact that they're 7889218822Sdim undefined can be safely ignored - let backend determine that. */ 7890218822Sdim if (bed->elf_backend_ignore_undef_symbol) 7891218822Sdim ignore_undef = bed->elf_backend_ignore_undef_symbol (h); 7892218822Sdim 7893218822Sdim /* If we are reporting errors for this situation then do so now. */ 7894218822Sdim if (ignore_undef == FALSE 7895218822Sdim && h->ref_dynamic 7896218822Sdim && ! h->ref_regular 7897218822Sdim && ! elf_link_check_versioned_symbol (finfo->info, bed, h) 7898218822Sdim && finfo->info->unresolved_syms_in_shared_libs != RM_IGNORE) 7899130561Sobrien { 7900218822Sdim if (! (finfo->info->callbacks->undefined_symbol 7901218822Sdim (finfo->info, h->root.root.string, h->root.u.undef.abfd, 7902218822Sdim NULL, 0, finfo->info->unresolved_syms_in_shared_libs == RM_GENERATE_ERROR))) 7903218822Sdim { 7904218822Sdim eoinfo->failed = TRUE; 7905218822Sdim return FALSE; 7906218822Sdim } 7907130561Sobrien } 7908130561Sobrien } 7909130561Sobrien 7910130561Sobrien /* We should also warn if a forced local symbol is referenced from 7911130561Sobrien shared libraries. */ 7912130561Sobrien if (! finfo->info->relocatable 7913130561Sobrien && (! finfo->info->shared) 7914218822Sdim && h->forced_local 7915218822Sdim && h->ref_dynamic 7916218822Sdim && !h->dynamic_def 7917218822Sdim && !h->dynamic_weak 7918130561Sobrien && ! elf_link_check_versioned_symbol (finfo->info, bed, h)) 7919130561Sobrien { 7920130561Sobrien (*_bfd_error_handler) 7921218822Sdim (_("%B: %s symbol `%s' in %B is referenced by DSO"), 7922218822Sdim finfo->output_bfd, 7923218822Sdim h->root.u.def.section == bfd_abs_section_ptr 7924218822Sdim ? finfo->output_bfd : h->root.u.def.section->owner, 7925130561Sobrien ELF_ST_VISIBILITY (h->other) == STV_INTERNAL 7926130561Sobrien ? "internal" 7927130561Sobrien : ELF_ST_VISIBILITY (h->other) == STV_HIDDEN 7928218822Sdim ? "hidden" : "local", 7929218822Sdim h->root.root.string); 7930130561Sobrien eoinfo->failed = TRUE; 7931130561Sobrien return FALSE; 7932130561Sobrien } 7933130561Sobrien 7934130561Sobrien /* We don't want to output symbols that have never been mentioned by 7935130561Sobrien a regular file, or that we have been told to strip. However, if 7936130561Sobrien h->indx is set to -2, the symbol is used by a reloc and we must 7937130561Sobrien output it. */ 7938130561Sobrien if (h->indx == -2) 7939130561Sobrien strip = FALSE; 7940218822Sdim else if ((h->def_dynamic 7941218822Sdim || h->ref_dynamic 7942218822Sdim || h->root.type == bfd_link_hash_new) 7943218822Sdim && !h->def_regular 7944218822Sdim && !h->ref_regular) 7945130561Sobrien strip = TRUE; 7946130561Sobrien else if (finfo->info->strip == strip_all) 7947130561Sobrien strip = TRUE; 7948130561Sobrien else if (finfo->info->strip == strip_some 7949130561Sobrien && bfd_hash_lookup (finfo->info->keep_hash, 7950130561Sobrien h->root.root.string, FALSE, FALSE) == NULL) 7951130561Sobrien strip = TRUE; 7952130561Sobrien else if (finfo->info->strip_discarded 7953130561Sobrien && (h->root.type == bfd_link_hash_defined 7954130561Sobrien || h->root.type == bfd_link_hash_defweak) 7955130561Sobrien && elf_discarded_section (h->root.u.def.section)) 7956130561Sobrien strip = TRUE; 7957130561Sobrien else 7958130561Sobrien strip = FALSE; 7959130561Sobrien 7960130561Sobrien /* If we're stripping it, and it's not a dynamic symbol, there's 7961130561Sobrien nothing else to do unless it is a forced local symbol. */ 7962130561Sobrien if (strip 7963130561Sobrien && h->dynindx == -1 7964218822Sdim && !h->forced_local) 7965130561Sobrien return TRUE; 7966130561Sobrien 7967130561Sobrien sym.st_value = 0; 7968130561Sobrien sym.st_size = h->size; 7969130561Sobrien sym.st_other = h->other; 7970218822Sdim if (h->forced_local) 7971130561Sobrien sym.st_info = ELF_ST_INFO (STB_LOCAL, h->type); 7972130561Sobrien else if (h->root.type == bfd_link_hash_undefweak 7973130561Sobrien || h->root.type == bfd_link_hash_defweak) 7974130561Sobrien sym.st_info = ELF_ST_INFO (STB_WEAK, h->type); 7975130561Sobrien else 7976130561Sobrien sym.st_info = ELF_ST_INFO (STB_GLOBAL, h->type); 7977130561Sobrien 7978130561Sobrien switch (h->root.type) 7979130561Sobrien { 7980130561Sobrien default: 7981130561Sobrien case bfd_link_hash_new: 7982130561Sobrien case bfd_link_hash_warning: 7983130561Sobrien abort (); 7984130561Sobrien return FALSE; 7985130561Sobrien 7986130561Sobrien case bfd_link_hash_undefined: 7987130561Sobrien case bfd_link_hash_undefweak: 7988130561Sobrien input_sec = bfd_und_section_ptr; 7989130561Sobrien sym.st_shndx = SHN_UNDEF; 7990130561Sobrien break; 7991130561Sobrien 7992130561Sobrien case bfd_link_hash_defined: 7993130561Sobrien case bfd_link_hash_defweak: 7994130561Sobrien { 7995130561Sobrien input_sec = h->root.u.def.section; 7996130561Sobrien if (input_sec->output_section != NULL) 7997130561Sobrien { 7998130561Sobrien sym.st_shndx = 7999130561Sobrien _bfd_elf_section_from_bfd_section (finfo->output_bfd, 8000130561Sobrien input_sec->output_section); 8001130561Sobrien if (sym.st_shndx == SHN_BAD) 8002130561Sobrien { 8003130561Sobrien (*_bfd_error_handler) 8004218822Sdim (_("%B: could not find output section %A for input section %A"), 8005218822Sdim finfo->output_bfd, input_sec->output_section, input_sec); 8006130561Sobrien eoinfo->failed = TRUE; 8007130561Sobrien return FALSE; 8008130561Sobrien } 8009130561Sobrien 8010130561Sobrien /* ELF symbols in relocatable files are section relative, 8011130561Sobrien but in nonrelocatable files they are virtual 8012130561Sobrien addresses. */ 8013130561Sobrien sym.st_value = h->root.u.def.value + input_sec->output_offset; 8014130561Sobrien if (! finfo->info->relocatable) 8015130561Sobrien { 8016130561Sobrien sym.st_value += input_sec->output_section->vma; 8017130561Sobrien if (h->type == STT_TLS) 8018130561Sobrien { 8019130561Sobrien /* STT_TLS symbols are relative to PT_TLS segment 8020130561Sobrien base. */ 8021130561Sobrien BFD_ASSERT (elf_hash_table (finfo->info)->tls_sec != NULL); 8022130561Sobrien sym.st_value -= elf_hash_table (finfo->info)->tls_sec->vma; 8023130561Sobrien } 8024130561Sobrien } 8025130561Sobrien } 8026130561Sobrien else 8027130561Sobrien { 8028130561Sobrien BFD_ASSERT (input_sec->owner == NULL 8029130561Sobrien || (input_sec->owner->flags & DYNAMIC) != 0); 8030130561Sobrien sym.st_shndx = SHN_UNDEF; 8031130561Sobrien input_sec = bfd_und_section_ptr; 8032130561Sobrien } 8033130561Sobrien } 8034130561Sobrien break; 8035130561Sobrien 8036130561Sobrien case bfd_link_hash_common: 8037130561Sobrien input_sec = h->root.u.c.p->section; 8038218822Sdim sym.st_shndx = bed->common_section_index (input_sec); 8039130561Sobrien sym.st_value = 1 << h->root.u.c.p->alignment_power; 8040130561Sobrien break; 8041130561Sobrien 8042130561Sobrien case bfd_link_hash_indirect: 8043130561Sobrien /* These symbols are created by symbol versioning. They point 8044130561Sobrien to the decorated version of the name. For example, if the 8045130561Sobrien symbol foo@@GNU_1.2 is the default, which should be used when 8046130561Sobrien foo is used with no version, then we add an indirect symbol 8047130561Sobrien foo which points to foo@@GNU_1.2. We ignore these symbols, 8048130561Sobrien since the indirected symbol is already in the hash table. */ 8049130561Sobrien return TRUE; 8050130561Sobrien } 8051130561Sobrien 8052130561Sobrien /* Give the processor backend a chance to tweak the symbol value, 8053130561Sobrien and also to finish up anything that needs to be done for this 8054130561Sobrien symbol. FIXME: Not calling elf_backend_finish_dynamic_symbol for 8055130561Sobrien forced local syms when non-shared is due to a historical quirk. */ 8056130561Sobrien if ((h->dynindx != -1 8057218822Sdim || h->forced_local) 8058130561Sobrien && ((finfo->info->shared 8059130561Sobrien && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT 8060130561Sobrien || h->root.type != bfd_link_hash_undefweak)) 8061218822Sdim || !h->forced_local) 8062130561Sobrien && elf_hash_table (finfo->info)->dynamic_sections_created) 8063130561Sobrien { 8064130561Sobrien if (! ((*bed->elf_backend_finish_dynamic_symbol) 8065130561Sobrien (finfo->output_bfd, finfo->info, h, &sym))) 8066130561Sobrien { 8067130561Sobrien eoinfo->failed = TRUE; 8068130561Sobrien return FALSE; 8069130561Sobrien } 8070130561Sobrien } 8071130561Sobrien 8072130561Sobrien /* If we are marking the symbol as undefined, and there are no 8073130561Sobrien non-weak references to this symbol from a regular object, then 8074130561Sobrien mark the symbol as weak undefined; if there are non-weak 8075130561Sobrien references, mark the symbol as strong. We can't do this earlier, 8076130561Sobrien because it might not be marked as undefined until the 8077130561Sobrien finish_dynamic_symbol routine gets through with it. */ 8078130561Sobrien if (sym.st_shndx == SHN_UNDEF 8079218822Sdim && h->ref_regular 8080130561Sobrien && (ELF_ST_BIND (sym.st_info) == STB_GLOBAL 8081130561Sobrien || ELF_ST_BIND (sym.st_info) == STB_WEAK)) 8082130561Sobrien { 8083130561Sobrien int bindtype; 8084130561Sobrien 8085218822Sdim if (h->ref_regular_nonweak) 8086130561Sobrien bindtype = STB_GLOBAL; 8087130561Sobrien else 8088130561Sobrien bindtype = STB_WEAK; 8089130561Sobrien sym.st_info = ELF_ST_INFO (bindtype, ELF_ST_TYPE (sym.st_info)); 8090130561Sobrien } 8091130561Sobrien 8092130561Sobrien /* If a non-weak symbol with non-default visibility is not defined 8093130561Sobrien locally, it is a fatal error. */ 8094130561Sobrien if (! finfo->info->relocatable 8095130561Sobrien && ELF_ST_VISIBILITY (sym.st_other) != STV_DEFAULT 8096130561Sobrien && ELF_ST_BIND (sym.st_info) != STB_WEAK 8097130561Sobrien && h->root.type == bfd_link_hash_undefined 8098218822Sdim && !h->def_regular) 8099130561Sobrien { 8100130561Sobrien (*_bfd_error_handler) 8101218822Sdim (_("%B: %s symbol `%s' isn't defined"), 8102218822Sdim finfo->output_bfd, 8103218822Sdim ELF_ST_VISIBILITY (sym.st_other) == STV_PROTECTED 8104218822Sdim ? "protected" 8105218822Sdim : ELF_ST_VISIBILITY (sym.st_other) == STV_INTERNAL 8106218822Sdim ? "internal" : "hidden", 8107218822Sdim h->root.root.string); 8108130561Sobrien eoinfo->failed = TRUE; 8109130561Sobrien return FALSE; 8110130561Sobrien } 8111130561Sobrien 8112130561Sobrien /* If this symbol should be put in the .dynsym section, then put it 8113130561Sobrien there now. We already know the symbol index. We also fill in 8114130561Sobrien the entry in the .hash section. */ 8115130561Sobrien if (h->dynindx != -1 8116130561Sobrien && elf_hash_table (finfo->info)->dynamic_sections_created) 8117130561Sobrien { 8118130561Sobrien bfd_byte *esym; 8119130561Sobrien 8120130561Sobrien sym.st_name = h->dynstr_index; 8121130561Sobrien esym = finfo->dynsym_sec->contents + h->dynindx * bed->s->sizeof_sym; 8122218822Sdim if (! check_dynsym (finfo->output_bfd, &sym)) 8123218822Sdim { 8124218822Sdim eoinfo->failed = TRUE; 8125218822Sdim return FALSE; 8126218822Sdim } 8127130561Sobrien bed->s->swap_symbol_out (finfo->output_bfd, &sym, esym, 0); 8128130561Sobrien 8129218822Sdim if (finfo->hash_sec != NULL) 8130218822Sdim { 8131218822Sdim size_t hash_entry_size; 8132218822Sdim bfd_byte *bucketpos; 8133218822Sdim bfd_vma chain; 8134218822Sdim size_t bucketcount; 8135218822Sdim size_t bucket; 8136130561Sobrien 8137218822Sdim bucketcount = elf_hash_table (finfo->info)->bucketcount; 8138218822Sdim bucket = h->u.elf_hash_value % bucketcount; 8139218822Sdim 8140218822Sdim hash_entry_size 8141218822Sdim = elf_section_data (finfo->hash_sec)->this_hdr.sh_entsize; 8142218822Sdim bucketpos = ((bfd_byte *) finfo->hash_sec->contents 8143218822Sdim + (bucket + 2) * hash_entry_size); 8144218822Sdim chain = bfd_get (8 * hash_entry_size, finfo->output_bfd, bucketpos); 8145218822Sdim bfd_put (8 * hash_entry_size, finfo->output_bfd, h->dynindx, bucketpos); 8146218822Sdim bfd_put (8 * hash_entry_size, finfo->output_bfd, chain, 8147218822Sdim ((bfd_byte *) finfo->hash_sec->contents 8148218822Sdim + (bucketcount + 2 + h->dynindx) * hash_entry_size)); 8149218822Sdim } 8150218822Sdim 8151130561Sobrien if (finfo->symver_sec != NULL && finfo->symver_sec->contents != NULL) 8152130561Sobrien { 8153130561Sobrien Elf_Internal_Versym iversym; 8154130561Sobrien Elf_External_Versym *eversym; 8155130561Sobrien 8156218822Sdim if (!h->def_regular) 8157130561Sobrien { 8158130561Sobrien if (h->verinfo.verdef == NULL) 8159130561Sobrien iversym.vs_vers = 0; 8160130561Sobrien else 8161130561Sobrien iversym.vs_vers = h->verinfo.verdef->vd_exp_refno + 1; 8162130561Sobrien } 8163130561Sobrien else 8164130561Sobrien { 8165130561Sobrien if (h->verinfo.vertree == NULL) 8166130561Sobrien iversym.vs_vers = 1; 8167130561Sobrien else 8168130561Sobrien iversym.vs_vers = h->verinfo.vertree->vernum + 1; 8169218822Sdim if (finfo->info->create_default_symver) 8170218822Sdim iversym.vs_vers++; 8171130561Sobrien } 8172130561Sobrien 8173218822Sdim if (h->hidden) 8174130561Sobrien iversym.vs_vers |= VERSYM_HIDDEN; 8175130561Sobrien 8176130561Sobrien eversym = (Elf_External_Versym *) finfo->symver_sec->contents; 8177130561Sobrien eversym += h->dynindx; 8178130561Sobrien _bfd_elf_swap_versym_out (finfo->output_bfd, &iversym, eversym); 8179130561Sobrien } 8180130561Sobrien } 8181130561Sobrien 8182130561Sobrien /* If we're stripping it, then it was just a dynamic symbol, and 8183130561Sobrien there's nothing else to do. */ 8184130561Sobrien if (strip || (input_sec->flags & SEC_EXCLUDE) != 0) 8185130561Sobrien return TRUE; 8186130561Sobrien 8187130561Sobrien h->indx = bfd_get_symcount (finfo->output_bfd); 8188130561Sobrien 8189130561Sobrien if (! elf_link_output_sym (finfo, h->root.root.string, &sym, input_sec, h)) 8190130561Sobrien { 8191130561Sobrien eoinfo->failed = TRUE; 8192130561Sobrien return FALSE; 8193130561Sobrien } 8194130561Sobrien 8195130561Sobrien return TRUE; 8196130561Sobrien} 8197130561Sobrien 8198218822Sdim/* Return TRUE if special handling is done for relocs in SEC against 8199218822Sdim symbols defined in discarded sections. */ 8200218822Sdim 8201130561Sobrienstatic bfd_boolean 8202130561Sobrienelf_section_ignore_discarded_relocs (asection *sec) 8203130561Sobrien{ 8204130561Sobrien const struct elf_backend_data *bed; 8205130561Sobrien 8206130561Sobrien switch (sec->sec_info_type) 8207130561Sobrien { 8208130561Sobrien case ELF_INFO_TYPE_STABS: 8209130561Sobrien case ELF_INFO_TYPE_EH_FRAME: 8210130561Sobrien return TRUE; 8211130561Sobrien default: 8212130561Sobrien break; 8213130561Sobrien } 8214130561Sobrien 8215130561Sobrien bed = get_elf_backend_data (sec->owner); 8216130561Sobrien if (bed->elf_backend_ignore_discarded_relocs != NULL 8217130561Sobrien && (*bed->elf_backend_ignore_discarded_relocs) (sec)) 8218130561Sobrien return TRUE; 8219130561Sobrien 8220130561Sobrien return FALSE; 8221130561Sobrien} 8222130561Sobrien 8223218822Sdim/* Return a mask saying how ld should treat relocations in SEC against 8224218822Sdim symbols defined in discarded sections. If this function returns 8225218822Sdim COMPLAIN set, ld will issue a warning message. If this function 8226218822Sdim returns PRETEND set, and the discarded section was link-once and the 8227218822Sdim same size as the kept link-once section, ld will pretend that the 8228218822Sdim symbol was actually defined in the kept section. Otherwise ld will 8229218822Sdim zero the reloc (at least that is the intent, but some cooperation by 8230218822Sdim the target dependent code is needed, particularly for REL targets). */ 8231218822Sdim 8232218822Sdimunsigned int 8233218822Sdim_bfd_elf_default_action_discarded (asection *sec) 8234218822Sdim{ 8235218822Sdim if (sec->flags & SEC_DEBUGGING) 8236218822Sdim return PRETEND; 8237218822Sdim 8238218822Sdim if (strcmp (".eh_frame", sec->name) == 0) 8239218822Sdim return 0; 8240218822Sdim 8241218822Sdim if (strcmp (".gcc_except_table", sec->name) == 0) 8242218822Sdim return 0; 8243218822Sdim 8244218822Sdim return COMPLAIN | PRETEND; 8245218822Sdim} 8246218822Sdim 8247218822Sdim/* Find a match between a section and a member of a section group. */ 8248218822Sdim 8249218822Sdimstatic asection * 8250218822Sdimmatch_group_member (asection *sec, asection *group, 8251218822Sdim struct bfd_link_info *info) 8252218822Sdim{ 8253218822Sdim asection *first = elf_next_in_group (group); 8254218822Sdim asection *s = first; 8255218822Sdim 8256218822Sdim while (s != NULL) 8257218822Sdim { 8258218822Sdim if (bfd_elf_match_symbols_in_sections (s, sec, info)) 8259218822Sdim return s; 8260218822Sdim 8261218822Sdim s = elf_next_in_group (s); 8262218822Sdim if (s == first) 8263218822Sdim break; 8264218822Sdim } 8265218822Sdim 8266218822Sdim return NULL; 8267218822Sdim} 8268218822Sdim 8269218822Sdim/* Check if the kept section of a discarded section SEC can be used 8270218822Sdim to replace it. Return the replacement if it is OK. Otherwise return 8271218822Sdim NULL. */ 8272218822Sdim 8273218822Sdimasection * 8274218822Sdim_bfd_elf_check_kept_section (asection *sec, struct bfd_link_info *info) 8275218822Sdim{ 8276218822Sdim asection *kept; 8277218822Sdim 8278218822Sdim kept = sec->kept_section; 8279218822Sdim if (kept != NULL) 8280218822Sdim { 8281218822Sdim if ((kept->flags & SEC_GROUP) != 0) 8282218822Sdim kept = match_group_member (sec, kept, info); 8283218822Sdim if (kept != NULL && sec->size != kept->size) 8284218822Sdim kept = NULL; 8285218822Sdim sec->kept_section = kept; 8286218822Sdim } 8287218822Sdim return kept; 8288218822Sdim} 8289218822Sdim 8290130561Sobrien/* Link an input file into the linker output file. This function 8291130561Sobrien handles all the sections and relocations of the input file at once. 8292130561Sobrien This is so that we only have to read the local symbols once, and 8293130561Sobrien don't have to keep them in memory. */ 8294130561Sobrien 8295130561Sobrienstatic bfd_boolean 8296130561Sobrienelf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd) 8297130561Sobrien{ 8298218822Sdim int (*relocate_section) 8299130561Sobrien (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, 8300130561Sobrien Elf_Internal_Rela *, Elf_Internal_Sym *, asection **); 8301130561Sobrien bfd *output_bfd; 8302130561Sobrien Elf_Internal_Shdr *symtab_hdr; 8303130561Sobrien size_t locsymcount; 8304130561Sobrien size_t extsymoff; 8305130561Sobrien Elf_Internal_Sym *isymbuf; 8306130561Sobrien Elf_Internal_Sym *isym; 8307130561Sobrien Elf_Internal_Sym *isymend; 8308130561Sobrien long *pindex; 8309130561Sobrien asection **ppsection; 8310130561Sobrien asection *o; 8311130561Sobrien const struct elf_backend_data *bed; 8312130561Sobrien struct elf_link_hash_entry **sym_hashes; 8313130561Sobrien 8314130561Sobrien output_bfd = finfo->output_bfd; 8315130561Sobrien bed = get_elf_backend_data (output_bfd); 8316130561Sobrien relocate_section = bed->elf_backend_relocate_section; 8317130561Sobrien 8318130561Sobrien /* If this is a dynamic object, we don't want to do anything here: 8319130561Sobrien we don't want the local symbols, and we don't want the section 8320130561Sobrien contents. */ 8321130561Sobrien if ((input_bfd->flags & DYNAMIC) != 0) 8322130561Sobrien return TRUE; 8323130561Sobrien 8324130561Sobrien symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; 8325130561Sobrien if (elf_bad_symtab (input_bfd)) 8326130561Sobrien { 8327130561Sobrien locsymcount = symtab_hdr->sh_size / bed->s->sizeof_sym; 8328130561Sobrien extsymoff = 0; 8329130561Sobrien } 8330130561Sobrien else 8331130561Sobrien { 8332130561Sobrien locsymcount = symtab_hdr->sh_info; 8333130561Sobrien extsymoff = symtab_hdr->sh_info; 8334130561Sobrien } 8335130561Sobrien 8336130561Sobrien /* Read the local symbols. */ 8337130561Sobrien isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; 8338130561Sobrien if (isymbuf == NULL && locsymcount != 0) 8339130561Sobrien { 8340130561Sobrien isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, locsymcount, 0, 8341130561Sobrien finfo->internal_syms, 8342130561Sobrien finfo->external_syms, 8343130561Sobrien finfo->locsym_shndx); 8344130561Sobrien if (isymbuf == NULL) 8345130561Sobrien return FALSE; 8346130561Sobrien } 8347218822Sdim /* evaluate_complex_relocation_symbols looks for symbols in 8348218822Sdim finfo->internal_syms. */ 8349218822Sdim else if (isymbuf != NULL && locsymcount != 0) 8350218822Sdim { 8351218822Sdim bfd_elf_get_elf_syms (input_bfd, symtab_hdr, locsymcount, 0, 8352218822Sdim finfo->internal_syms, 8353218822Sdim finfo->external_syms, 8354218822Sdim finfo->locsym_shndx); 8355218822Sdim } 8356130561Sobrien 8357130561Sobrien /* Find local symbol sections and adjust values of symbols in 8358130561Sobrien SEC_MERGE sections. Write out those local symbols we know are 8359130561Sobrien going into the output file. */ 8360130561Sobrien isymend = isymbuf + locsymcount; 8361130561Sobrien for (isym = isymbuf, pindex = finfo->indices, ppsection = finfo->sections; 8362130561Sobrien isym < isymend; 8363130561Sobrien isym++, pindex++, ppsection++) 8364130561Sobrien { 8365130561Sobrien asection *isec; 8366130561Sobrien const char *name; 8367130561Sobrien Elf_Internal_Sym osym; 8368130561Sobrien 8369130561Sobrien *pindex = -1; 8370130561Sobrien 8371130561Sobrien if (elf_bad_symtab (input_bfd)) 8372130561Sobrien { 8373130561Sobrien if (ELF_ST_BIND (isym->st_info) != STB_LOCAL) 8374130561Sobrien { 8375130561Sobrien *ppsection = NULL; 8376130561Sobrien continue; 8377130561Sobrien } 8378130561Sobrien } 8379130561Sobrien 8380130561Sobrien if (isym->st_shndx == SHN_UNDEF) 8381130561Sobrien isec = bfd_und_section_ptr; 8382130561Sobrien else if (isym->st_shndx < SHN_LORESERVE 8383130561Sobrien || isym->st_shndx > SHN_HIRESERVE) 8384130561Sobrien { 8385130561Sobrien isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx); 8386130561Sobrien if (isec 8387130561Sobrien && isec->sec_info_type == ELF_INFO_TYPE_MERGE 8388130561Sobrien && ELF_ST_TYPE (isym->st_info) != STT_SECTION) 8389130561Sobrien isym->st_value = 8390130561Sobrien _bfd_merged_section_offset (output_bfd, &isec, 8391130561Sobrien elf_section_data (isec)->sec_info, 8392218822Sdim isym->st_value); 8393130561Sobrien } 8394130561Sobrien else if (isym->st_shndx == SHN_ABS) 8395130561Sobrien isec = bfd_abs_section_ptr; 8396130561Sobrien else if (isym->st_shndx == SHN_COMMON) 8397130561Sobrien isec = bfd_com_section_ptr; 8398130561Sobrien else 8399130561Sobrien { 8400218822Sdim /* Don't attempt to output symbols with st_shnx in the 8401218822Sdim reserved range other than SHN_ABS and SHN_COMMON. */ 8402218822Sdim *ppsection = NULL; 8403218822Sdim continue; 8404130561Sobrien } 8405130561Sobrien 8406130561Sobrien *ppsection = isec; 8407130561Sobrien 8408130561Sobrien /* Don't output the first, undefined, symbol. */ 8409130561Sobrien if (ppsection == finfo->sections) 8410130561Sobrien continue; 8411130561Sobrien 8412130561Sobrien if (ELF_ST_TYPE (isym->st_info) == STT_SECTION) 8413130561Sobrien { 8414130561Sobrien /* We never output section symbols. Instead, we use the 8415130561Sobrien section symbol of the corresponding section in the output 8416130561Sobrien file. */ 8417130561Sobrien continue; 8418130561Sobrien } 8419130561Sobrien 8420130561Sobrien /* If we are stripping all symbols, we don't want to output this 8421130561Sobrien one. */ 8422130561Sobrien if (finfo->info->strip == strip_all) 8423130561Sobrien continue; 8424130561Sobrien 8425130561Sobrien /* If we are discarding all local symbols, we don't want to 8426130561Sobrien output this one. If we are generating a relocatable output 8427130561Sobrien file, then some of the local symbols may be required by 8428130561Sobrien relocs; we output them below as we discover that they are 8429130561Sobrien needed. */ 8430130561Sobrien if (finfo->info->discard == discard_all) 8431130561Sobrien continue; 8432130561Sobrien 8433130561Sobrien /* If this symbol is defined in a section which we are 8434218822Sdim discarding, we don't need to keep it. */ 8435218822Sdim if (isym->st_shndx != SHN_UNDEF 8436218822Sdim && (isym->st_shndx < SHN_LORESERVE || isym->st_shndx > SHN_HIRESERVE) 8437218822Sdim && (isec == NULL 8438218822Sdim || bfd_section_removed_from_list (output_bfd, 8439218822Sdim isec->output_section))) 8440130561Sobrien continue; 8441130561Sobrien 8442130561Sobrien /* Get the name of the symbol. */ 8443130561Sobrien name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, 8444130561Sobrien isym->st_name); 8445130561Sobrien if (name == NULL) 8446130561Sobrien return FALSE; 8447130561Sobrien 8448130561Sobrien /* See if we are discarding symbols with this name. */ 8449130561Sobrien if ((finfo->info->strip == strip_some 8450130561Sobrien && (bfd_hash_lookup (finfo->info->keep_hash, name, FALSE, FALSE) 8451130561Sobrien == NULL)) 8452130561Sobrien || (((finfo->info->discard == discard_sec_merge 8453130561Sobrien && (isec->flags & SEC_MERGE) && ! finfo->info->relocatable) 8454130561Sobrien || finfo->info->discard == discard_l) 8455130561Sobrien && bfd_is_local_label_name (input_bfd, name))) 8456130561Sobrien continue; 8457130561Sobrien 8458130561Sobrien /* If we get here, we are going to output this symbol. */ 8459130561Sobrien 8460130561Sobrien osym = *isym; 8461130561Sobrien 8462130561Sobrien /* Adjust the section index for the output file. */ 8463130561Sobrien osym.st_shndx = _bfd_elf_section_from_bfd_section (output_bfd, 8464130561Sobrien isec->output_section); 8465130561Sobrien if (osym.st_shndx == SHN_BAD) 8466130561Sobrien return FALSE; 8467130561Sobrien 8468130561Sobrien *pindex = bfd_get_symcount (output_bfd); 8469130561Sobrien 8470130561Sobrien /* ELF symbols in relocatable files are section relative, but 8471130561Sobrien in executable files they are virtual addresses. Note that 8472130561Sobrien this code assumes that all ELF sections have an associated 8473130561Sobrien BFD section with a reasonable value for output_offset; below 8474130561Sobrien we assume that they also have a reasonable value for 8475130561Sobrien output_section. Any special sections must be set up to meet 8476130561Sobrien these requirements. */ 8477130561Sobrien osym.st_value += isec->output_offset; 8478130561Sobrien if (! finfo->info->relocatable) 8479130561Sobrien { 8480130561Sobrien osym.st_value += isec->output_section->vma; 8481130561Sobrien if (ELF_ST_TYPE (osym.st_info) == STT_TLS) 8482130561Sobrien { 8483130561Sobrien /* STT_TLS symbols are relative to PT_TLS segment base. */ 8484130561Sobrien BFD_ASSERT (elf_hash_table (finfo->info)->tls_sec != NULL); 8485130561Sobrien osym.st_value -= elf_hash_table (finfo->info)->tls_sec->vma; 8486130561Sobrien } 8487130561Sobrien } 8488130561Sobrien 8489130561Sobrien if (! elf_link_output_sym (finfo, name, &osym, isec, NULL)) 8490130561Sobrien return FALSE; 8491130561Sobrien } 8492130561Sobrien 8493218822Sdim if (! evaluate_complex_relocation_symbols (input_bfd, finfo, locsymcount)) 8494218822Sdim return FALSE; 8495218822Sdim 8496130561Sobrien /* Relocate the contents of each section. */ 8497130561Sobrien sym_hashes = elf_sym_hashes (input_bfd); 8498130561Sobrien for (o = input_bfd->sections; o != NULL; o = o->next) 8499130561Sobrien { 8500130561Sobrien bfd_byte *contents; 8501130561Sobrien 8502130561Sobrien if (! o->linker_mark) 8503130561Sobrien { 8504130561Sobrien /* This section was omitted from the link. */ 8505130561Sobrien continue; 8506130561Sobrien } 8507130561Sobrien 8508130561Sobrien if ((o->flags & SEC_HAS_CONTENTS) == 0 8509218822Sdim || (o->size == 0 && (o->flags & SEC_RELOC) == 0)) 8510130561Sobrien continue; 8511130561Sobrien 8512130561Sobrien if ((o->flags & SEC_LINKER_CREATED) != 0) 8513130561Sobrien { 8514130561Sobrien /* Section was created by _bfd_elf_link_create_dynamic_sections 8515130561Sobrien or somesuch. */ 8516130561Sobrien continue; 8517130561Sobrien } 8518130561Sobrien 8519130561Sobrien /* Get the contents of the section. They have been cached by a 8520130561Sobrien relaxation routine. Note that o is a section in an input 8521130561Sobrien file, so the contents field will not have been set by any of 8522130561Sobrien the routines which work on output files. */ 8523130561Sobrien if (elf_section_data (o)->this_hdr.contents != NULL) 8524130561Sobrien contents = elf_section_data (o)->this_hdr.contents; 8525130561Sobrien else 8526130561Sobrien { 8527218822Sdim bfd_size_type amt = o->rawsize ? o->rawsize : o->size; 8528218822Sdim 8529130561Sobrien contents = finfo->contents; 8530218822Sdim if (! bfd_get_section_contents (input_bfd, o, contents, 0, amt)) 8531130561Sobrien return FALSE; 8532130561Sobrien } 8533130561Sobrien 8534130561Sobrien if ((o->flags & SEC_RELOC) != 0) 8535130561Sobrien { 8536130561Sobrien Elf_Internal_Rela *internal_relocs; 8537130561Sobrien bfd_vma r_type_mask; 8538130561Sobrien int r_sym_shift; 8539218822Sdim int ret; 8540130561Sobrien 8541130561Sobrien /* Get the swapped relocs. */ 8542130561Sobrien internal_relocs 8543130561Sobrien = _bfd_elf_link_read_relocs (input_bfd, o, finfo->external_relocs, 8544130561Sobrien finfo->internal_relocs, FALSE); 8545130561Sobrien if (internal_relocs == NULL 8546130561Sobrien && o->reloc_count > 0) 8547130561Sobrien return FALSE; 8548130561Sobrien 8549130561Sobrien if (bed->s->arch_size == 32) 8550130561Sobrien { 8551130561Sobrien r_type_mask = 0xff; 8552130561Sobrien r_sym_shift = 8; 8553130561Sobrien } 8554130561Sobrien else 8555130561Sobrien { 8556130561Sobrien r_type_mask = 0xffffffff; 8557130561Sobrien r_sym_shift = 32; 8558130561Sobrien } 8559130561Sobrien 8560130561Sobrien /* Run through the relocs looking for any against symbols 8561130561Sobrien from discarded sections and section symbols from 8562130561Sobrien removed link-once sections. Complain about relocs 8563130561Sobrien against discarded sections. Zero relocs against removed 8564218822Sdim link-once sections. */ 8565130561Sobrien if (!elf_section_ignore_discarded_relocs (o)) 8566130561Sobrien { 8567130561Sobrien Elf_Internal_Rela *rel, *relend; 8568218822Sdim unsigned int action = (*bed->action_discarded) (o); 8569130561Sobrien 8570130561Sobrien rel = internal_relocs; 8571130561Sobrien relend = rel + o->reloc_count * bed->s->int_rels_per_ext_rel; 8572130561Sobrien for ( ; rel < relend; rel++) 8573130561Sobrien { 8574130561Sobrien unsigned long r_symndx = rel->r_info >> r_sym_shift; 8575218822Sdim asection **ps, *sec; 8576218822Sdim struct elf_link_hash_entry *h = NULL; 8577218822Sdim const char *sym_name; 8578130561Sobrien 8579218822Sdim if (r_symndx == STN_UNDEF) 8580218822Sdim continue; 8581218822Sdim 8582130561Sobrien if (r_symndx >= locsymcount 8583130561Sobrien || (elf_bad_symtab (input_bfd) 8584130561Sobrien && finfo->sections[r_symndx] == NULL)) 8585130561Sobrien { 8586218822Sdim h = sym_hashes[r_symndx - extsymoff]; 8587130561Sobrien 8588218822Sdim /* Badly formatted input files can contain relocs that 8589218822Sdim reference non-existant symbols. Check here so that 8590218822Sdim we do not seg fault. */ 8591218822Sdim if (h == NULL) 8592218822Sdim { 8593218822Sdim char buffer [32]; 8594218822Sdim 8595218822Sdim sprintf_vma (buffer, rel->r_info); 8596218822Sdim (*_bfd_error_handler) 8597218822Sdim (_("error: %B contains a reloc (0x%s) for section %A " 8598218822Sdim "that references a non-existent global symbol"), 8599218822Sdim input_bfd, o, buffer); 8600218822Sdim bfd_set_error (bfd_error_bad_value); 8601218822Sdim return FALSE; 8602218822Sdim } 8603218822Sdim 8604130561Sobrien while (h->root.type == bfd_link_hash_indirect 8605130561Sobrien || h->root.type == bfd_link_hash_warning) 8606130561Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 8607130561Sobrien 8608218822Sdim if (h->root.type != bfd_link_hash_defined 8609218822Sdim && h->root.type != bfd_link_hash_defweak) 8610218822Sdim continue; 8611218822Sdim 8612218822Sdim ps = &h->root.u.def.section; 8613218822Sdim sym_name = h->root.root.string; 8614130561Sobrien } 8615130561Sobrien else 8616130561Sobrien { 8617218822Sdim Elf_Internal_Sym *sym = isymbuf + r_symndx; 8618218822Sdim ps = &finfo->sections[r_symndx]; 8619218822Sdim sym_name = bfd_elf_sym_name (input_bfd, 8620218822Sdim symtab_hdr, 8621218822Sdim sym, *ps); 8622218822Sdim } 8623130561Sobrien 8624218822Sdim /* Complain if the definition comes from a 8625218822Sdim discarded section. */ 8626218822Sdim if ((sec = *ps) != NULL && elf_discarded_section (sec)) 8627218822Sdim { 8628218822Sdim BFD_ASSERT (r_symndx != 0); 8629218822Sdim if (action & COMPLAIN) 8630218822Sdim (*finfo->info->callbacks->einfo) 8631218822Sdim (_("%X`%s' referenced in section `%A' of %B: " 8632218822Sdim "defined in discarded section `%A' of %B\n"), 8633218822Sdim sym_name, o, input_bfd, sec, sec->owner); 8634218822Sdim 8635218822Sdim /* Try to do the best we can to support buggy old 8636218822Sdim versions of gcc. Pretend that the symbol is 8637218822Sdim really defined in the kept linkonce section. 8638218822Sdim FIXME: This is quite broken. Modifying the 8639218822Sdim symbol here means we will be changing all later 8640218822Sdim uses of the symbol, not just in this section. */ 8641218822Sdim if (action & PRETEND) 8642130561Sobrien { 8643218822Sdim asection *kept; 8644218822Sdim 8645218822Sdim kept = _bfd_elf_check_kept_section (sec, 8646218822Sdim finfo->info); 8647218822Sdim if (kept != NULL) 8648130561Sobrien { 8649218822Sdim *ps = kept; 8650218822Sdim continue; 8651130561Sobrien } 8652130561Sobrien } 8653130561Sobrien } 8654130561Sobrien } 8655130561Sobrien } 8656130561Sobrien 8657130561Sobrien /* Relocate the section by invoking a back end routine. 8658130561Sobrien 8659130561Sobrien The back end routine is responsible for adjusting the 8660130561Sobrien section contents as necessary, and (if using Rela relocs 8661130561Sobrien and generating a relocatable output file) adjusting the 8662130561Sobrien reloc addend as necessary. 8663130561Sobrien 8664130561Sobrien The back end routine does not have to worry about setting 8665130561Sobrien the reloc address or the reloc symbol index. 8666130561Sobrien 8667130561Sobrien The back end routine is given a pointer to the swapped in 8668130561Sobrien internal symbols, and can access the hash table entries 8669130561Sobrien for the external symbols via elf_sym_hashes (input_bfd). 8670130561Sobrien 8671130561Sobrien When generating relocatable output, the back end routine 8672130561Sobrien must handle STB_LOCAL/STT_SECTION symbols specially. The 8673130561Sobrien output symbol is going to be a section symbol 8674130561Sobrien corresponding to the output section, which will require 8675130561Sobrien the addend to be adjusted. */ 8676130561Sobrien 8677218822Sdim ret = (*relocate_section) (output_bfd, finfo->info, 8678130561Sobrien input_bfd, o, contents, 8679130561Sobrien internal_relocs, 8680130561Sobrien isymbuf, 8681218822Sdim finfo->sections); 8682218822Sdim if (!ret) 8683130561Sobrien return FALSE; 8684130561Sobrien 8685218822Sdim if (ret == 2 8686218822Sdim || finfo->info->relocatable 8687218822Sdim || finfo->info->emitrelocations) 8688130561Sobrien { 8689130561Sobrien Elf_Internal_Rela *irela; 8690130561Sobrien Elf_Internal_Rela *irelaend; 8691130561Sobrien bfd_vma last_offset; 8692130561Sobrien struct elf_link_hash_entry **rel_hash; 8693218822Sdim struct elf_link_hash_entry **rel_hash_list; 8694130561Sobrien Elf_Internal_Shdr *input_rel_hdr, *input_rel_hdr2; 8695130561Sobrien unsigned int next_erel; 8696130561Sobrien bfd_boolean rela_normal; 8697130561Sobrien 8698130561Sobrien input_rel_hdr = &elf_section_data (o)->rel_hdr; 8699130561Sobrien rela_normal = (bed->rela_normal 8700130561Sobrien && (input_rel_hdr->sh_entsize 8701130561Sobrien == bed->s->sizeof_rela)); 8702130561Sobrien 8703130561Sobrien /* Adjust the reloc addresses and symbol indices. */ 8704130561Sobrien 8705130561Sobrien irela = internal_relocs; 8706130561Sobrien irelaend = irela + o->reloc_count * bed->s->int_rels_per_ext_rel; 8707130561Sobrien rel_hash = (elf_section_data (o->output_section)->rel_hashes 8708130561Sobrien + elf_section_data (o->output_section)->rel_count 8709130561Sobrien + elf_section_data (o->output_section)->rel_count2); 8710218822Sdim rel_hash_list = rel_hash; 8711130561Sobrien last_offset = o->output_offset; 8712130561Sobrien if (!finfo->info->relocatable) 8713130561Sobrien last_offset += o->output_section->vma; 8714130561Sobrien for (next_erel = 0; irela < irelaend; irela++, next_erel++) 8715130561Sobrien { 8716130561Sobrien unsigned long r_symndx; 8717130561Sobrien asection *sec; 8718130561Sobrien Elf_Internal_Sym sym; 8719130561Sobrien 8720130561Sobrien if (next_erel == bed->s->int_rels_per_ext_rel) 8721130561Sobrien { 8722130561Sobrien rel_hash++; 8723130561Sobrien next_erel = 0; 8724130561Sobrien } 8725130561Sobrien 8726130561Sobrien irela->r_offset = _bfd_elf_section_offset (output_bfd, 8727130561Sobrien finfo->info, o, 8728130561Sobrien irela->r_offset); 8729130561Sobrien if (irela->r_offset >= (bfd_vma) -2) 8730130561Sobrien { 8731130561Sobrien /* This is a reloc for a deleted entry or somesuch. 8732130561Sobrien Turn it into an R_*_NONE reloc, at the same 8733130561Sobrien offset as the last reloc. elf_eh_frame.c and 8734218822Sdim bfd_elf_discard_info rely on reloc offsets 8735130561Sobrien being ordered. */ 8736130561Sobrien irela->r_offset = last_offset; 8737130561Sobrien irela->r_info = 0; 8738130561Sobrien irela->r_addend = 0; 8739130561Sobrien continue; 8740130561Sobrien } 8741130561Sobrien 8742130561Sobrien irela->r_offset += o->output_offset; 8743130561Sobrien 8744130561Sobrien /* Relocs in an executable have to be virtual addresses. */ 8745130561Sobrien if (!finfo->info->relocatable) 8746130561Sobrien irela->r_offset += o->output_section->vma; 8747130561Sobrien 8748130561Sobrien last_offset = irela->r_offset; 8749130561Sobrien 8750130561Sobrien r_symndx = irela->r_info >> r_sym_shift; 8751130561Sobrien if (r_symndx == STN_UNDEF) 8752130561Sobrien continue; 8753130561Sobrien 8754130561Sobrien if (r_symndx >= locsymcount 8755130561Sobrien || (elf_bad_symtab (input_bfd) 8756130561Sobrien && finfo->sections[r_symndx] == NULL)) 8757130561Sobrien { 8758130561Sobrien struct elf_link_hash_entry *rh; 8759130561Sobrien unsigned long indx; 8760130561Sobrien 8761130561Sobrien /* This is a reloc against a global symbol. We 8762130561Sobrien have not yet output all the local symbols, so 8763130561Sobrien we do not know the symbol index of any global 8764130561Sobrien symbol. We set the rel_hash entry for this 8765130561Sobrien reloc to point to the global hash table entry 8766130561Sobrien for this symbol. The symbol index is then 8767218822Sdim set at the end of bfd_elf_final_link. */ 8768130561Sobrien indx = r_symndx - extsymoff; 8769130561Sobrien rh = elf_sym_hashes (input_bfd)[indx]; 8770130561Sobrien while (rh->root.type == bfd_link_hash_indirect 8771130561Sobrien || rh->root.type == bfd_link_hash_warning) 8772130561Sobrien rh = (struct elf_link_hash_entry *) rh->root.u.i.link; 8773130561Sobrien 8774130561Sobrien /* Setting the index to -2 tells 8775130561Sobrien elf_link_output_extsym that this symbol is 8776130561Sobrien used by a reloc. */ 8777130561Sobrien BFD_ASSERT (rh->indx < 0); 8778130561Sobrien rh->indx = -2; 8779130561Sobrien 8780130561Sobrien *rel_hash = rh; 8781130561Sobrien 8782130561Sobrien continue; 8783130561Sobrien } 8784130561Sobrien 8785130561Sobrien /* This is a reloc against a local symbol. */ 8786130561Sobrien 8787130561Sobrien *rel_hash = NULL; 8788130561Sobrien sym = isymbuf[r_symndx]; 8789130561Sobrien sec = finfo->sections[r_symndx]; 8790130561Sobrien if (ELF_ST_TYPE (sym.st_info) == STT_SECTION) 8791130561Sobrien { 8792130561Sobrien /* I suppose the backend ought to fill in the 8793130561Sobrien section of any STT_SECTION symbol against a 8794218822Sdim processor specific section. */ 8795218822Sdim r_symndx = 0; 8796218822Sdim if (bfd_is_abs_section (sec)) 8797218822Sdim ; 8798130561Sobrien else if (sec == NULL || sec->owner == NULL) 8799130561Sobrien { 8800130561Sobrien bfd_set_error (bfd_error_bad_value); 8801130561Sobrien return FALSE; 8802130561Sobrien } 8803130561Sobrien else 8804130561Sobrien { 8805218822Sdim asection *osec = sec->output_section; 8806218822Sdim 8807218822Sdim /* If we have discarded a section, the output 8808218822Sdim section will be the absolute section. In 8809218822Sdim case of discarded SEC_MERGE sections, use 8810218822Sdim the kept section. relocate_section should 8811218822Sdim have already handled discarded linkonce 8812218822Sdim sections. */ 8813218822Sdim if (bfd_is_abs_section (osec) 8814218822Sdim && sec->kept_section != NULL 8815218822Sdim && sec->kept_section->output_section != NULL) 8816218822Sdim { 8817218822Sdim osec = sec->kept_section->output_section; 8818218822Sdim irela->r_addend -= osec->vma; 8819218822Sdim } 8820218822Sdim 8821218822Sdim if (!bfd_is_abs_section (osec)) 8822218822Sdim { 8823218822Sdim r_symndx = osec->target_index; 8824218822Sdim if (r_symndx == 0) 8825218822Sdim { 8826218822Sdim struct elf_link_hash_table *htab; 8827218822Sdim asection *oi; 8828218822Sdim 8829218822Sdim htab = elf_hash_table (finfo->info); 8830218822Sdim oi = htab->text_index_section; 8831218822Sdim if ((osec->flags & SEC_READONLY) == 0 8832218822Sdim && htab->data_index_section != NULL) 8833218822Sdim oi = htab->data_index_section; 8834218822Sdim 8835218822Sdim if (oi != NULL) 8836218822Sdim { 8837218822Sdim irela->r_addend += osec->vma - oi->vma; 8838218822Sdim r_symndx = oi->target_index; 8839218822Sdim } 8840218822Sdim } 8841218822Sdim 8842218822Sdim BFD_ASSERT (r_symndx != 0); 8843218822Sdim } 8844130561Sobrien } 8845130561Sobrien 8846130561Sobrien /* Adjust the addend according to where the 8847130561Sobrien section winds up in the output section. */ 8848130561Sobrien if (rela_normal) 8849130561Sobrien irela->r_addend += sec->output_offset; 8850130561Sobrien } 8851130561Sobrien else 8852130561Sobrien { 8853130561Sobrien if (finfo->indices[r_symndx] == -1) 8854130561Sobrien { 8855130561Sobrien unsigned long shlink; 8856130561Sobrien const char *name; 8857130561Sobrien asection *osec; 8858130561Sobrien 8859130561Sobrien if (finfo->info->strip == strip_all) 8860130561Sobrien { 8861130561Sobrien /* You can't do ld -r -s. */ 8862130561Sobrien bfd_set_error (bfd_error_invalid_operation); 8863130561Sobrien return FALSE; 8864130561Sobrien } 8865130561Sobrien 8866130561Sobrien /* This symbol was skipped earlier, but 8867130561Sobrien since it is needed by a reloc, we 8868130561Sobrien must output it now. */ 8869130561Sobrien shlink = symtab_hdr->sh_link; 8870130561Sobrien name = (bfd_elf_string_from_elf_section 8871130561Sobrien (input_bfd, shlink, sym.st_name)); 8872130561Sobrien if (name == NULL) 8873130561Sobrien return FALSE; 8874130561Sobrien 8875130561Sobrien osec = sec->output_section; 8876130561Sobrien sym.st_shndx = 8877130561Sobrien _bfd_elf_section_from_bfd_section (output_bfd, 8878130561Sobrien osec); 8879130561Sobrien if (sym.st_shndx == SHN_BAD) 8880130561Sobrien return FALSE; 8881130561Sobrien 8882130561Sobrien sym.st_value += sec->output_offset; 8883130561Sobrien if (! finfo->info->relocatable) 8884130561Sobrien { 8885130561Sobrien sym.st_value += osec->vma; 8886130561Sobrien if (ELF_ST_TYPE (sym.st_info) == STT_TLS) 8887130561Sobrien { 8888130561Sobrien /* STT_TLS symbols are relative to PT_TLS 8889130561Sobrien segment base. */ 8890130561Sobrien BFD_ASSERT (elf_hash_table (finfo->info) 8891130561Sobrien ->tls_sec != NULL); 8892130561Sobrien sym.st_value -= (elf_hash_table (finfo->info) 8893130561Sobrien ->tls_sec->vma); 8894130561Sobrien } 8895130561Sobrien } 8896130561Sobrien 8897130561Sobrien finfo->indices[r_symndx] 8898130561Sobrien = bfd_get_symcount (output_bfd); 8899130561Sobrien 8900130561Sobrien if (! elf_link_output_sym (finfo, name, &sym, sec, 8901130561Sobrien NULL)) 8902130561Sobrien return FALSE; 8903130561Sobrien } 8904130561Sobrien 8905130561Sobrien r_symndx = finfo->indices[r_symndx]; 8906130561Sobrien } 8907130561Sobrien 8908130561Sobrien irela->r_info = ((bfd_vma) r_symndx << r_sym_shift 8909130561Sobrien | (irela->r_info & r_type_mask)); 8910130561Sobrien } 8911130561Sobrien 8912130561Sobrien /* Swap out the relocs. */ 8913130561Sobrien if (input_rel_hdr->sh_size != 0 8914218822Sdim && !bed->elf_backend_emit_relocs (output_bfd, o, 8915218822Sdim input_rel_hdr, 8916218822Sdim internal_relocs, 8917218822Sdim rel_hash_list)) 8918130561Sobrien return FALSE; 8919130561Sobrien 8920130561Sobrien input_rel_hdr2 = elf_section_data (o)->rel_hdr2; 8921130561Sobrien if (input_rel_hdr2 && input_rel_hdr2->sh_size != 0) 8922130561Sobrien { 8923130561Sobrien internal_relocs += (NUM_SHDR_ENTRIES (input_rel_hdr) 8924130561Sobrien * bed->s->int_rels_per_ext_rel); 8925218822Sdim rel_hash_list += NUM_SHDR_ENTRIES (input_rel_hdr); 8926218822Sdim if (!bed->elf_backend_emit_relocs (output_bfd, o, 8927218822Sdim input_rel_hdr2, 8928218822Sdim internal_relocs, 8929218822Sdim rel_hash_list)) 8930130561Sobrien return FALSE; 8931130561Sobrien } 8932130561Sobrien } 8933130561Sobrien } 8934130561Sobrien 8935130561Sobrien /* Write out the modified section contents. */ 8936130561Sobrien if (bed->elf_backend_write_section 8937218822Sdim && (*bed->elf_backend_write_section) (output_bfd, finfo->info, o, 8938218822Sdim contents)) 8939130561Sobrien { 8940130561Sobrien /* Section written out. */ 8941130561Sobrien } 8942130561Sobrien else switch (o->sec_info_type) 8943130561Sobrien { 8944130561Sobrien case ELF_INFO_TYPE_STABS: 8945130561Sobrien if (! (_bfd_write_section_stabs 8946130561Sobrien (output_bfd, 8947130561Sobrien &elf_hash_table (finfo->info)->stab_info, 8948130561Sobrien o, &elf_section_data (o)->sec_info, contents))) 8949130561Sobrien return FALSE; 8950130561Sobrien break; 8951130561Sobrien case ELF_INFO_TYPE_MERGE: 8952130561Sobrien if (! _bfd_write_merged_section (output_bfd, o, 8953130561Sobrien elf_section_data (o)->sec_info)) 8954130561Sobrien return FALSE; 8955130561Sobrien break; 8956130561Sobrien case ELF_INFO_TYPE_EH_FRAME: 8957130561Sobrien { 8958130561Sobrien if (! _bfd_elf_write_section_eh_frame (output_bfd, finfo->info, 8959130561Sobrien o, contents)) 8960130561Sobrien return FALSE; 8961130561Sobrien } 8962130561Sobrien break; 8963130561Sobrien default: 8964130561Sobrien { 8965130561Sobrien if (! (o->flags & SEC_EXCLUDE) 8966130561Sobrien && ! bfd_set_section_contents (output_bfd, o->output_section, 8967130561Sobrien contents, 8968130561Sobrien (file_ptr) o->output_offset, 8969218822Sdim o->size)) 8970130561Sobrien return FALSE; 8971130561Sobrien } 8972130561Sobrien break; 8973130561Sobrien } 8974130561Sobrien } 8975130561Sobrien 8976130561Sobrien return TRUE; 8977130561Sobrien} 8978130561Sobrien 8979130561Sobrien/* Generate a reloc when linking an ELF file. This is a reloc 8980218822Sdim requested by the linker, and does not come from any input file. This 8981130561Sobrien is used to build constructor and destructor tables when linking 8982130561Sobrien with -Ur. */ 8983130561Sobrien 8984130561Sobrienstatic bfd_boolean 8985130561Sobrienelf_reloc_link_order (bfd *output_bfd, 8986130561Sobrien struct bfd_link_info *info, 8987130561Sobrien asection *output_section, 8988130561Sobrien struct bfd_link_order *link_order) 8989130561Sobrien{ 8990130561Sobrien reloc_howto_type *howto; 8991130561Sobrien long indx; 8992130561Sobrien bfd_vma offset; 8993130561Sobrien bfd_vma addend; 8994130561Sobrien struct elf_link_hash_entry **rel_hash_ptr; 8995130561Sobrien Elf_Internal_Shdr *rel_hdr; 8996130561Sobrien const struct elf_backend_data *bed = get_elf_backend_data (output_bfd); 8997130561Sobrien Elf_Internal_Rela irel[MAX_INT_RELS_PER_EXT_REL]; 8998130561Sobrien bfd_byte *erel; 8999130561Sobrien unsigned int i; 9000130561Sobrien 9001130561Sobrien howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc); 9002130561Sobrien if (howto == NULL) 9003130561Sobrien { 9004130561Sobrien bfd_set_error (bfd_error_bad_value); 9005130561Sobrien return FALSE; 9006130561Sobrien } 9007130561Sobrien 9008130561Sobrien addend = link_order->u.reloc.p->addend; 9009130561Sobrien 9010130561Sobrien /* Figure out the symbol index. */ 9011130561Sobrien rel_hash_ptr = (elf_section_data (output_section)->rel_hashes 9012130561Sobrien + elf_section_data (output_section)->rel_count 9013130561Sobrien + elf_section_data (output_section)->rel_count2); 9014130561Sobrien if (link_order->type == bfd_section_reloc_link_order) 9015130561Sobrien { 9016130561Sobrien indx = link_order->u.reloc.p->u.section->target_index; 9017130561Sobrien BFD_ASSERT (indx != 0); 9018130561Sobrien *rel_hash_ptr = NULL; 9019130561Sobrien } 9020130561Sobrien else 9021130561Sobrien { 9022130561Sobrien struct elf_link_hash_entry *h; 9023130561Sobrien 9024130561Sobrien /* Treat a reloc against a defined symbol as though it were 9025130561Sobrien actually against the section. */ 9026130561Sobrien h = ((struct elf_link_hash_entry *) 9027130561Sobrien bfd_wrapped_link_hash_lookup (output_bfd, info, 9028130561Sobrien link_order->u.reloc.p->u.name, 9029130561Sobrien FALSE, FALSE, TRUE)); 9030130561Sobrien if (h != NULL 9031130561Sobrien && (h->root.type == bfd_link_hash_defined 9032130561Sobrien || h->root.type == bfd_link_hash_defweak)) 9033130561Sobrien { 9034130561Sobrien asection *section; 9035130561Sobrien 9036130561Sobrien section = h->root.u.def.section; 9037130561Sobrien indx = section->output_section->target_index; 9038130561Sobrien *rel_hash_ptr = NULL; 9039130561Sobrien /* It seems that we ought to add the symbol value to the 9040130561Sobrien addend here, but in practice it has already been added 9041130561Sobrien because it was passed to constructor_callback. */ 9042130561Sobrien addend += section->output_section->vma + section->output_offset; 9043130561Sobrien } 9044130561Sobrien else if (h != NULL) 9045130561Sobrien { 9046130561Sobrien /* Setting the index to -2 tells elf_link_output_extsym that 9047130561Sobrien this symbol is used by a reloc. */ 9048130561Sobrien h->indx = -2; 9049130561Sobrien *rel_hash_ptr = h; 9050130561Sobrien indx = 0; 9051130561Sobrien } 9052130561Sobrien else 9053130561Sobrien { 9054130561Sobrien if (! ((*info->callbacks->unattached_reloc) 9055130561Sobrien (info, link_order->u.reloc.p->u.name, NULL, NULL, 0))) 9056130561Sobrien return FALSE; 9057130561Sobrien indx = 0; 9058130561Sobrien } 9059130561Sobrien } 9060130561Sobrien 9061130561Sobrien /* If this is an inplace reloc, we must write the addend into the 9062130561Sobrien object file. */ 9063130561Sobrien if (howto->partial_inplace && addend != 0) 9064130561Sobrien { 9065130561Sobrien bfd_size_type size; 9066130561Sobrien bfd_reloc_status_type rstat; 9067130561Sobrien bfd_byte *buf; 9068130561Sobrien bfd_boolean ok; 9069130561Sobrien const char *sym_name; 9070130561Sobrien 9071130561Sobrien size = bfd_get_reloc_size (howto); 9072130561Sobrien buf = bfd_zmalloc (size); 9073130561Sobrien if (buf == NULL) 9074130561Sobrien return FALSE; 9075130561Sobrien rstat = _bfd_relocate_contents (howto, output_bfd, addend, buf); 9076130561Sobrien switch (rstat) 9077130561Sobrien { 9078130561Sobrien case bfd_reloc_ok: 9079130561Sobrien break; 9080130561Sobrien 9081130561Sobrien default: 9082130561Sobrien case bfd_reloc_outofrange: 9083130561Sobrien abort (); 9084130561Sobrien 9085130561Sobrien case bfd_reloc_overflow: 9086130561Sobrien if (link_order->type == bfd_section_reloc_link_order) 9087130561Sobrien sym_name = bfd_section_name (output_bfd, 9088130561Sobrien link_order->u.reloc.p->u.section); 9089130561Sobrien else 9090130561Sobrien sym_name = link_order->u.reloc.p->u.name; 9091130561Sobrien if (! ((*info->callbacks->reloc_overflow) 9092218822Sdim (info, NULL, sym_name, howto->name, addend, NULL, 9093218822Sdim NULL, (bfd_vma) 0))) 9094130561Sobrien { 9095130561Sobrien free (buf); 9096130561Sobrien return FALSE; 9097130561Sobrien } 9098130561Sobrien break; 9099130561Sobrien } 9100130561Sobrien ok = bfd_set_section_contents (output_bfd, output_section, buf, 9101130561Sobrien link_order->offset, size); 9102130561Sobrien free (buf); 9103130561Sobrien if (! ok) 9104130561Sobrien return FALSE; 9105130561Sobrien } 9106130561Sobrien 9107130561Sobrien /* The address of a reloc is relative to the section in a 9108130561Sobrien relocatable file, and is a virtual address in an executable 9109130561Sobrien file. */ 9110130561Sobrien offset = link_order->offset; 9111130561Sobrien if (! info->relocatable) 9112130561Sobrien offset += output_section->vma; 9113130561Sobrien 9114130561Sobrien for (i = 0; i < bed->s->int_rels_per_ext_rel; i++) 9115130561Sobrien { 9116130561Sobrien irel[i].r_offset = offset; 9117130561Sobrien irel[i].r_info = 0; 9118130561Sobrien irel[i].r_addend = 0; 9119130561Sobrien } 9120130561Sobrien if (bed->s->arch_size == 32) 9121130561Sobrien irel[0].r_info = ELF32_R_INFO (indx, howto->type); 9122130561Sobrien else 9123130561Sobrien irel[0].r_info = ELF64_R_INFO (indx, howto->type); 9124130561Sobrien 9125130561Sobrien rel_hdr = &elf_section_data (output_section)->rel_hdr; 9126130561Sobrien erel = rel_hdr->contents; 9127130561Sobrien if (rel_hdr->sh_type == SHT_REL) 9128130561Sobrien { 9129130561Sobrien erel += (elf_section_data (output_section)->rel_count 9130130561Sobrien * bed->s->sizeof_rel); 9131130561Sobrien (*bed->s->swap_reloc_out) (output_bfd, irel, erel); 9132130561Sobrien } 9133130561Sobrien else 9134130561Sobrien { 9135130561Sobrien irel[0].r_addend = addend; 9136130561Sobrien erel += (elf_section_data (output_section)->rel_count 9137130561Sobrien * bed->s->sizeof_rela); 9138130561Sobrien (*bed->s->swap_reloca_out) (output_bfd, irel, erel); 9139130561Sobrien } 9140130561Sobrien 9141130561Sobrien ++elf_section_data (output_section)->rel_count; 9142130561Sobrien 9143130561Sobrien return TRUE; 9144130561Sobrien} 9145130561Sobrien 9146218822Sdim 9147218822Sdim/* Get the output vma of the section pointed to by the sh_link field. */ 9148218822Sdim 9149218822Sdimstatic bfd_vma 9150218822Sdimelf_get_linked_section_vma (struct bfd_link_order *p) 9151218822Sdim{ 9152218822Sdim Elf_Internal_Shdr **elf_shdrp; 9153218822Sdim asection *s; 9154218822Sdim int elfsec; 9155218822Sdim 9156218822Sdim s = p->u.indirect.section; 9157218822Sdim elf_shdrp = elf_elfsections (s->owner); 9158218822Sdim elfsec = _bfd_elf_section_from_bfd_section (s->owner, s); 9159218822Sdim elfsec = elf_shdrp[elfsec]->sh_link; 9160218822Sdim /* PR 290: 9161218822Sdim The Intel C compiler generates SHT_IA_64_UNWIND with 9162218822Sdim SHF_LINK_ORDER. But it doesn't set the sh_link or 9163218822Sdim sh_info fields. Hence we could get the situation 9164218822Sdim where elfsec is 0. */ 9165218822Sdim if (elfsec == 0) 9166218822Sdim { 9167218822Sdim const struct elf_backend_data *bed 9168218822Sdim = get_elf_backend_data (s->owner); 9169218822Sdim if (bed->link_order_error_handler) 9170218822Sdim bed->link_order_error_handler 9171218822Sdim (_("%B: warning: sh_link not set for section `%A'"), s->owner, s); 9172218822Sdim return 0; 9173218822Sdim } 9174218822Sdim else 9175218822Sdim { 9176218822Sdim s = elf_shdrp[elfsec]->bfd_section; 9177218822Sdim return s->output_section->vma + s->output_offset; 9178218822Sdim } 9179218822Sdim} 9180218822Sdim 9181218822Sdim 9182218822Sdim/* Compare two sections based on the locations of the sections they are 9183218822Sdim linked to. Used by elf_fixup_link_order. */ 9184218822Sdim 9185218822Sdimstatic int 9186218822Sdimcompare_link_order (const void * a, const void * b) 9187218822Sdim{ 9188218822Sdim bfd_vma apos; 9189218822Sdim bfd_vma bpos; 9190218822Sdim 9191218822Sdim apos = elf_get_linked_section_vma (*(struct bfd_link_order **)a); 9192218822Sdim bpos = elf_get_linked_section_vma (*(struct bfd_link_order **)b); 9193218822Sdim if (apos < bpos) 9194218822Sdim return -1; 9195218822Sdim return apos > bpos; 9196218822Sdim} 9197218822Sdim 9198218822Sdim 9199218822Sdim/* Looks for sections with SHF_LINK_ORDER set. Rearranges them into the same 9200218822Sdim order as their linked sections. Returns false if this could not be done 9201218822Sdim because an output section includes both ordered and unordered 9202218822Sdim sections. Ideally we'd do this in the linker proper. */ 9203218822Sdim 9204218822Sdimstatic bfd_boolean 9205218822Sdimelf_fixup_link_order (bfd *abfd, asection *o) 9206218822Sdim{ 9207218822Sdim int seen_linkorder; 9208218822Sdim int seen_other; 9209218822Sdim int n; 9210218822Sdim struct bfd_link_order *p; 9211218822Sdim bfd *sub; 9212218822Sdim const struct elf_backend_data *bed = get_elf_backend_data (abfd); 9213218822Sdim unsigned elfsec; 9214218822Sdim struct bfd_link_order **sections; 9215218822Sdim asection *s, *other_sec, *linkorder_sec; 9216218822Sdim bfd_vma offset; 9217218822Sdim 9218218822Sdim other_sec = NULL; 9219218822Sdim linkorder_sec = NULL; 9220218822Sdim seen_other = 0; 9221218822Sdim seen_linkorder = 0; 9222218822Sdim for (p = o->map_head.link_order; p != NULL; p = p->next) 9223218822Sdim { 9224218822Sdim if (p->type == bfd_indirect_link_order) 9225218822Sdim { 9226218822Sdim s = p->u.indirect.section; 9227218822Sdim sub = s->owner; 9228218822Sdim if (bfd_get_flavour (sub) == bfd_target_elf_flavour 9229218822Sdim && elf_elfheader (sub)->e_ident[EI_CLASS] == bed->s->elfclass 9230218822Sdim && (elfsec = _bfd_elf_section_from_bfd_section (sub, s)) 9231218822Sdim && elfsec < elf_numsections (sub) 9232218822Sdim && elf_elfsections (sub)[elfsec]->sh_flags & SHF_LINK_ORDER) 9233218822Sdim { 9234218822Sdim seen_linkorder++; 9235218822Sdim linkorder_sec = s; 9236218822Sdim } 9237218822Sdim else 9238218822Sdim { 9239218822Sdim seen_other++; 9240218822Sdim other_sec = s; 9241218822Sdim } 9242218822Sdim } 9243218822Sdim else 9244218822Sdim seen_other++; 9245218822Sdim 9246218822Sdim if (seen_other && seen_linkorder) 9247218822Sdim { 9248218822Sdim if (other_sec && linkorder_sec) 9249218822Sdim (*_bfd_error_handler) (_("%A has both ordered [`%A' in %B] and unordered [`%A' in %B] sections"), 9250218822Sdim o, linkorder_sec, 9251218822Sdim linkorder_sec->owner, other_sec, 9252218822Sdim other_sec->owner); 9253218822Sdim else 9254218822Sdim (*_bfd_error_handler) (_("%A has both ordered and unordered sections"), 9255218822Sdim o); 9256218822Sdim bfd_set_error (bfd_error_bad_value); 9257218822Sdim return FALSE; 9258218822Sdim } 9259218822Sdim } 9260218822Sdim 9261218822Sdim if (!seen_linkorder) 9262218822Sdim return TRUE; 9263218822Sdim 9264218822Sdim sections = (struct bfd_link_order **) 9265218822Sdim xmalloc (seen_linkorder * sizeof (struct bfd_link_order *)); 9266218822Sdim seen_linkorder = 0; 9267218822Sdim 9268218822Sdim for (p = o->map_head.link_order; p != NULL; p = p->next) 9269218822Sdim { 9270218822Sdim sections[seen_linkorder++] = p; 9271218822Sdim } 9272218822Sdim /* Sort the input sections in the order of their linked section. */ 9273218822Sdim qsort (sections, seen_linkorder, sizeof (struct bfd_link_order *), 9274218822Sdim compare_link_order); 9275218822Sdim 9276218822Sdim /* Change the offsets of the sections. */ 9277218822Sdim offset = 0; 9278218822Sdim for (n = 0; n < seen_linkorder; n++) 9279218822Sdim { 9280218822Sdim s = sections[n]->u.indirect.section; 9281218822Sdim offset &= ~(bfd_vma)((1 << s->alignment_power) - 1); 9282218822Sdim s->output_offset = offset; 9283218822Sdim sections[n]->offset = offset; 9284218822Sdim offset += sections[n]->size; 9285218822Sdim } 9286218822Sdim 9287218822Sdim return TRUE; 9288218822Sdim} 9289218822Sdim 9290218822Sdim 9291130561Sobrien/* Do the final step of an ELF link. */ 9292130561Sobrien 9293130561Sobrienbfd_boolean 9294130561Sobrienbfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) 9295130561Sobrien{ 9296130561Sobrien bfd_boolean dynamic; 9297130561Sobrien bfd_boolean emit_relocs; 9298130561Sobrien bfd *dynobj; 9299130561Sobrien struct elf_final_link_info finfo; 9300130561Sobrien register asection *o; 9301130561Sobrien register struct bfd_link_order *p; 9302130561Sobrien register bfd *sub; 9303130561Sobrien bfd_size_type max_contents_size; 9304130561Sobrien bfd_size_type max_external_reloc_size; 9305130561Sobrien bfd_size_type max_internal_reloc_count; 9306130561Sobrien bfd_size_type max_sym_count; 9307130561Sobrien bfd_size_type max_sym_shndx_count; 9308130561Sobrien file_ptr off; 9309130561Sobrien Elf_Internal_Sym elfsym; 9310130561Sobrien unsigned int i; 9311130561Sobrien Elf_Internal_Shdr *symtab_hdr; 9312130561Sobrien Elf_Internal_Shdr *symtab_shndx_hdr; 9313130561Sobrien Elf_Internal_Shdr *symstrtab_hdr; 9314130561Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 9315130561Sobrien struct elf_outext_info eoinfo; 9316130561Sobrien bfd_boolean merged; 9317130561Sobrien size_t relativecount = 0; 9318130561Sobrien asection *reldyn = 0; 9319130561Sobrien bfd_size_type amt; 9320218822Sdim asection *attr_section = NULL; 9321218822Sdim bfd_vma attr_size = 0; 9322218822Sdim const char *std_attrs_section; 9323130561Sobrien 9324130561Sobrien if (! is_elf_hash_table (info->hash)) 9325130561Sobrien return FALSE; 9326130561Sobrien 9327130561Sobrien if (info->shared) 9328130561Sobrien abfd->flags |= DYNAMIC; 9329130561Sobrien 9330130561Sobrien dynamic = elf_hash_table (info)->dynamic_sections_created; 9331130561Sobrien dynobj = elf_hash_table (info)->dynobj; 9332130561Sobrien 9333130561Sobrien emit_relocs = (info->relocatable 9334218822Sdim || info->emitrelocations); 9335130561Sobrien 9336130561Sobrien finfo.info = info; 9337130561Sobrien finfo.output_bfd = abfd; 9338130561Sobrien finfo.symstrtab = _bfd_elf_stringtab_init (); 9339130561Sobrien if (finfo.symstrtab == NULL) 9340130561Sobrien return FALSE; 9341130561Sobrien 9342130561Sobrien if (! dynamic) 9343130561Sobrien { 9344130561Sobrien finfo.dynsym_sec = NULL; 9345130561Sobrien finfo.hash_sec = NULL; 9346130561Sobrien finfo.symver_sec = NULL; 9347130561Sobrien } 9348130561Sobrien else 9349130561Sobrien { 9350130561Sobrien finfo.dynsym_sec = bfd_get_section_by_name (dynobj, ".dynsym"); 9351130561Sobrien finfo.hash_sec = bfd_get_section_by_name (dynobj, ".hash"); 9352218822Sdim BFD_ASSERT (finfo.dynsym_sec != NULL); 9353130561Sobrien finfo.symver_sec = bfd_get_section_by_name (dynobj, ".gnu.version"); 9354130561Sobrien /* Note that it is OK if symver_sec is NULL. */ 9355130561Sobrien } 9356130561Sobrien 9357130561Sobrien finfo.contents = NULL; 9358130561Sobrien finfo.external_relocs = NULL; 9359130561Sobrien finfo.internal_relocs = NULL; 9360130561Sobrien finfo.external_syms = NULL; 9361130561Sobrien finfo.locsym_shndx = NULL; 9362130561Sobrien finfo.internal_syms = NULL; 9363130561Sobrien finfo.indices = NULL; 9364130561Sobrien finfo.sections = NULL; 9365130561Sobrien finfo.symbuf = NULL; 9366130561Sobrien finfo.symshndxbuf = NULL; 9367130561Sobrien finfo.symbuf_count = 0; 9368130561Sobrien finfo.shndxbuf_size = 0; 9369130561Sobrien 9370218822Sdim /* The object attributes have been merged. Remove the input 9371218822Sdim sections from the link, and set the contents of the output 9372218822Sdim secton. */ 9373218822Sdim std_attrs_section = get_elf_backend_data (abfd)->obj_attrs_section; 9374218822Sdim for (o = abfd->sections; o != NULL; o = o->next) 9375218822Sdim { 9376218822Sdim if ((std_attrs_section && strcmp (o->name, std_attrs_section) == 0) 9377218822Sdim || strcmp (o->name, ".gnu.attributes") == 0) 9378218822Sdim { 9379218822Sdim for (p = o->map_head.link_order; p != NULL; p = p->next) 9380218822Sdim { 9381218822Sdim asection *input_section; 9382218822Sdim 9383218822Sdim if (p->type != bfd_indirect_link_order) 9384218822Sdim continue; 9385218822Sdim input_section = p->u.indirect.section; 9386218822Sdim /* Hack: reset the SEC_HAS_CONTENTS flag so that 9387218822Sdim elf_link_input_bfd ignores this section. */ 9388218822Sdim input_section->flags &= ~SEC_HAS_CONTENTS; 9389218822Sdim } 9390218822Sdim 9391218822Sdim attr_size = bfd_elf_obj_attr_size (abfd); 9392218822Sdim if (attr_size) 9393218822Sdim { 9394218822Sdim bfd_set_section_size (abfd, o, attr_size); 9395218822Sdim attr_section = o; 9396218822Sdim /* Skip this section later on. */ 9397218822Sdim o->map_head.link_order = NULL; 9398218822Sdim } 9399218822Sdim else 9400218822Sdim o->flags |= SEC_EXCLUDE; 9401218822Sdim } 9402218822Sdim } 9403218822Sdim 9404130561Sobrien /* Count up the number of relocations we will output for each output 9405130561Sobrien section, so that we know the sizes of the reloc sections. We 9406130561Sobrien also figure out some maximum sizes. */ 9407130561Sobrien max_contents_size = 0; 9408130561Sobrien max_external_reloc_size = 0; 9409130561Sobrien max_internal_reloc_count = 0; 9410130561Sobrien max_sym_count = 0; 9411130561Sobrien max_sym_shndx_count = 0; 9412130561Sobrien merged = FALSE; 9413130561Sobrien for (o = abfd->sections; o != NULL; o = o->next) 9414130561Sobrien { 9415130561Sobrien struct bfd_elf_section_data *esdo = elf_section_data (o); 9416130561Sobrien o->reloc_count = 0; 9417130561Sobrien 9418218822Sdim for (p = o->map_head.link_order; p != NULL; p = p->next) 9419130561Sobrien { 9420130561Sobrien unsigned int reloc_count = 0; 9421130561Sobrien struct bfd_elf_section_data *esdi = NULL; 9422130561Sobrien unsigned int *rel_count1; 9423130561Sobrien 9424130561Sobrien if (p->type == bfd_section_reloc_link_order 9425130561Sobrien || p->type == bfd_symbol_reloc_link_order) 9426130561Sobrien reloc_count = 1; 9427130561Sobrien else if (p->type == bfd_indirect_link_order) 9428130561Sobrien { 9429130561Sobrien asection *sec; 9430130561Sobrien 9431130561Sobrien sec = p->u.indirect.section; 9432130561Sobrien esdi = elf_section_data (sec); 9433130561Sobrien 9434130561Sobrien /* Mark all sections which are to be included in the 9435130561Sobrien link. This will normally be every section. We need 9436130561Sobrien to do this so that we can identify any sections which 9437130561Sobrien the linker has decided to not include. */ 9438130561Sobrien sec->linker_mark = TRUE; 9439130561Sobrien 9440130561Sobrien if (sec->flags & SEC_MERGE) 9441130561Sobrien merged = TRUE; 9442130561Sobrien 9443130561Sobrien if (info->relocatable || info->emitrelocations) 9444130561Sobrien reloc_count = sec->reloc_count; 9445130561Sobrien else if (bed->elf_backend_count_relocs) 9446130561Sobrien { 9447130561Sobrien Elf_Internal_Rela * relocs; 9448130561Sobrien 9449218822Sdim relocs = _bfd_elf_link_read_relocs (sec->owner, sec, 9450218822Sdim NULL, NULL, 9451130561Sobrien info->keep_memory); 9452130561Sobrien 9453218822Sdim if (relocs != NULL) 9454218822Sdim { 9455218822Sdim reloc_count 9456218822Sdim = (*bed->elf_backend_count_relocs) (sec, relocs); 9457130561Sobrien 9458218822Sdim if (elf_section_data (sec)->relocs != relocs) 9459218822Sdim free (relocs); 9460218822Sdim } 9461130561Sobrien } 9462130561Sobrien 9463218822Sdim if (sec->rawsize > max_contents_size) 9464218822Sdim max_contents_size = sec->rawsize; 9465218822Sdim if (sec->size > max_contents_size) 9466218822Sdim max_contents_size = sec->size; 9467130561Sobrien 9468130561Sobrien /* We are interested in just local symbols, not all 9469130561Sobrien symbols. */ 9470130561Sobrien if (bfd_get_flavour (sec->owner) == bfd_target_elf_flavour 9471130561Sobrien && (sec->owner->flags & DYNAMIC) == 0) 9472130561Sobrien { 9473130561Sobrien size_t sym_count; 9474130561Sobrien 9475130561Sobrien if (elf_bad_symtab (sec->owner)) 9476130561Sobrien sym_count = (elf_tdata (sec->owner)->symtab_hdr.sh_size 9477130561Sobrien / bed->s->sizeof_sym); 9478130561Sobrien else 9479130561Sobrien sym_count = elf_tdata (sec->owner)->symtab_hdr.sh_info; 9480130561Sobrien 9481130561Sobrien if (sym_count > max_sym_count) 9482130561Sobrien max_sym_count = sym_count; 9483130561Sobrien 9484130561Sobrien if (sym_count > max_sym_shndx_count 9485130561Sobrien && elf_symtab_shndx (sec->owner) != 0) 9486130561Sobrien max_sym_shndx_count = sym_count; 9487130561Sobrien 9488130561Sobrien if ((sec->flags & SEC_RELOC) != 0) 9489130561Sobrien { 9490130561Sobrien size_t ext_size; 9491130561Sobrien 9492130561Sobrien ext_size = elf_section_data (sec)->rel_hdr.sh_size; 9493130561Sobrien if (ext_size > max_external_reloc_size) 9494130561Sobrien max_external_reloc_size = ext_size; 9495130561Sobrien if (sec->reloc_count > max_internal_reloc_count) 9496130561Sobrien max_internal_reloc_count = sec->reloc_count; 9497130561Sobrien } 9498130561Sobrien } 9499130561Sobrien } 9500130561Sobrien 9501130561Sobrien if (reloc_count == 0) 9502130561Sobrien continue; 9503130561Sobrien 9504130561Sobrien o->reloc_count += reloc_count; 9505130561Sobrien 9506130561Sobrien /* MIPS may have a mix of REL and RELA relocs on sections. 9507130561Sobrien To support this curious ABI we keep reloc counts in 9508130561Sobrien elf_section_data too. We must be careful to add the 9509130561Sobrien relocations from the input section to the right output 9510130561Sobrien count. FIXME: Get rid of one count. We have 9511130561Sobrien o->reloc_count == esdo->rel_count + esdo->rel_count2. */ 9512130561Sobrien rel_count1 = &esdo->rel_count; 9513130561Sobrien if (esdi != NULL) 9514130561Sobrien { 9515130561Sobrien bfd_boolean same_size; 9516130561Sobrien bfd_size_type entsize1; 9517130561Sobrien 9518130561Sobrien entsize1 = esdi->rel_hdr.sh_entsize; 9519130561Sobrien BFD_ASSERT (entsize1 == bed->s->sizeof_rel 9520130561Sobrien || entsize1 == bed->s->sizeof_rela); 9521130561Sobrien same_size = !o->use_rela_p == (entsize1 == bed->s->sizeof_rel); 9522130561Sobrien 9523130561Sobrien if (!same_size) 9524130561Sobrien rel_count1 = &esdo->rel_count2; 9525130561Sobrien 9526130561Sobrien if (esdi->rel_hdr2 != NULL) 9527130561Sobrien { 9528130561Sobrien bfd_size_type entsize2 = esdi->rel_hdr2->sh_entsize; 9529130561Sobrien unsigned int alt_count; 9530130561Sobrien unsigned int *rel_count2; 9531130561Sobrien 9532130561Sobrien BFD_ASSERT (entsize2 != entsize1 9533130561Sobrien && (entsize2 == bed->s->sizeof_rel 9534130561Sobrien || entsize2 == bed->s->sizeof_rela)); 9535130561Sobrien 9536130561Sobrien rel_count2 = &esdo->rel_count2; 9537130561Sobrien if (!same_size) 9538130561Sobrien rel_count2 = &esdo->rel_count; 9539130561Sobrien 9540130561Sobrien /* The following is probably too simplistic if the 9541130561Sobrien backend counts output relocs unusually. */ 9542130561Sobrien BFD_ASSERT (bed->elf_backend_count_relocs == NULL); 9543130561Sobrien alt_count = NUM_SHDR_ENTRIES (esdi->rel_hdr2); 9544130561Sobrien *rel_count2 += alt_count; 9545130561Sobrien reloc_count -= alt_count; 9546130561Sobrien } 9547130561Sobrien } 9548130561Sobrien *rel_count1 += reloc_count; 9549130561Sobrien } 9550130561Sobrien 9551130561Sobrien if (o->reloc_count > 0) 9552130561Sobrien o->flags |= SEC_RELOC; 9553130561Sobrien else 9554130561Sobrien { 9555130561Sobrien /* Explicitly clear the SEC_RELOC flag. The linker tends to 9556130561Sobrien set it (this is probably a bug) and if it is set 9557130561Sobrien assign_section_numbers will create a reloc section. */ 9558130561Sobrien o->flags &=~ SEC_RELOC; 9559130561Sobrien } 9560130561Sobrien 9561130561Sobrien /* If the SEC_ALLOC flag is not set, force the section VMA to 9562130561Sobrien zero. This is done in elf_fake_sections as well, but forcing 9563130561Sobrien the VMA to 0 here will ensure that relocs against these 9564130561Sobrien sections are handled correctly. */ 9565130561Sobrien if ((o->flags & SEC_ALLOC) == 0 9566130561Sobrien && ! o->user_set_vma) 9567130561Sobrien o->vma = 0; 9568130561Sobrien } 9569130561Sobrien 9570130561Sobrien if (! info->relocatable && merged) 9571130561Sobrien elf_link_hash_traverse (elf_hash_table (info), 9572130561Sobrien _bfd_elf_link_sec_merge_syms, abfd); 9573130561Sobrien 9574130561Sobrien /* Figure out the file positions for everything but the symbol table 9575130561Sobrien and the relocs. We set symcount to force assign_section_numbers 9576130561Sobrien to create a symbol table. */ 9577130561Sobrien bfd_get_symcount (abfd) = info->strip == strip_all ? 0 : 1; 9578130561Sobrien BFD_ASSERT (! abfd->output_has_begun); 9579130561Sobrien if (! _bfd_elf_compute_section_file_positions (abfd, info)) 9580130561Sobrien goto error_return; 9581130561Sobrien 9582218822Sdim /* Set sizes, and assign file positions for reloc sections. */ 9583130561Sobrien for (o = abfd->sections; o != NULL; o = o->next) 9584130561Sobrien { 9585130561Sobrien if ((o->flags & SEC_RELOC) != 0) 9586130561Sobrien { 9587130561Sobrien if (!(_bfd_elf_link_size_reloc_section 9588130561Sobrien (abfd, &elf_section_data (o)->rel_hdr, o))) 9589130561Sobrien goto error_return; 9590130561Sobrien 9591130561Sobrien if (elf_section_data (o)->rel_hdr2 9592130561Sobrien && !(_bfd_elf_link_size_reloc_section 9593130561Sobrien (abfd, elf_section_data (o)->rel_hdr2, o))) 9594130561Sobrien goto error_return; 9595130561Sobrien } 9596130561Sobrien 9597130561Sobrien /* Now, reset REL_COUNT and REL_COUNT2 so that we can use them 9598130561Sobrien to count upwards while actually outputting the relocations. */ 9599130561Sobrien elf_section_data (o)->rel_count = 0; 9600130561Sobrien elf_section_data (o)->rel_count2 = 0; 9601130561Sobrien } 9602130561Sobrien 9603130561Sobrien _bfd_elf_assign_file_positions_for_relocs (abfd); 9604130561Sobrien 9605130561Sobrien /* We have now assigned file positions for all the sections except 9606130561Sobrien .symtab and .strtab. We start the .symtab section at the current 9607130561Sobrien file position, and write directly to it. We build the .strtab 9608130561Sobrien section in memory. */ 9609130561Sobrien bfd_get_symcount (abfd) = 0; 9610130561Sobrien symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 9611130561Sobrien /* sh_name is set in prep_headers. */ 9612130561Sobrien symtab_hdr->sh_type = SHT_SYMTAB; 9613130561Sobrien /* sh_flags, sh_addr and sh_size all start off zero. */ 9614130561Sobrien symtab_hdr->sh_entsize = bed->s->sizeof_sym; 9615130561Sobrien /* sh_link is set in assign_section_numbers. */ 9616130561Sobrien /* sh_info is set below. */ 9617130561Sobrien /* sh_offset is set just below. */ 9618130561Sobrien symtab_hdr->sh_addralign = 1 << bed->s->log_file_align; 9619130561Sobrien 9620130561Sobrien off = elf_tdata (abfd)->next_file_pos; 9621130561Sobrien off = _bfd_elf_assign_file_position_for_section (symtab_hdr, off, TRUE); 9622130561Sobrien 9623130561Sobrien /* Note that at this point elf_tdata (abfd)->next_file_pos is 9624130561Sobrien incorrect. We do not yet know the size of the .symtab section. 9625130561Sobrien We correct next_file_pos below, after we do know the size. */ 9626130561Sobrien 9627130561Sobrien /* Allocate a buffer to hold swapped out symbols. This is to avoid 9628130561Sobrien continuously seeking to the right position in the file. */ 9629130561Sobrien if (! info->keep_memory || max_sym_count < 20) 9630130561Sobrien finfo.symbuf_size = 20; 9631130561Sobrien else 9632130561Sobrien finfo.symbuf_size = max_sym_count; 9633130561Sobrien amt = finfo.symbuf_size; 9634130561Sobrien amt *= bed->s->sizeof_sym; 9635130561Sobrien finfo.symbuf = bfd_malloc (amt); 9636130561Sobrien if (finfo.symbuf == NULL) 9637130561Sobrien goto error_return; 9638130561Sobrien if (elf_numsections (abfd) > SHN_LORESERVE) 9639130561Sobrien { 9640130561Sobrien /* Wild guess at number of output symbols. realloc'd as needed. */ 9641130561Sobrien amt = 2 * max_sym_count + elf_numsections (abfd) + 1000; 9642130561Sobrien finfo.shndxbuf_size = amt; 9643130561Sobrien amt *= sizeof (Elf_External_Sym_Shndx); 9644130561Sobrien finfo.symshndxbuf = bfd_zmalloc (amt); 9645130561Sobrien if (finfo.symshndxbuf == NULL) 9646130561Sobrien goto error_return; 9647130561Sobrien } 9648130561Sobrien 9649130561Sobrien /* Start writing out the symbol table. The first symbol is always a 9650130561Sobrien dummy symbol. */ 9651130561Sobrien if (info->strip != strip_all 9652130561Sobrien || emit_relocs) 9653130561Sobrien { 9654130561Sobrien elfsym.st_value = 0; 9655130561Sobrien elfsym.st_size = 0; 9656130561Sobrien elfsym.st_info = 0; 9657130561Sobrien elfsym.st_other = 0; 9658130561Sobrien elfsym.st_shndx = SHN_UNDEF; 9659130561Sobrien if (! elf_link_output_sym (&finfo, NULL, &elfsym, bfd_und_section_ptr, 9660130561Sobrien NULL)) 9661130561Sobrien goto error_return; 9662130561Sobrien } 9663130561Sobrien 9664130561Sobrien /* Output a symbol for each section. We output these even if we are 9665130561Sobrien discarding local symbols, since they are used for relocs. These 9666130561Sobrien symbols have no names. We store the index of each one in the 9667130561Sobrien index field of the section, so that we can find it again when 9668130561Sobrien outputting relocs. */ 9669130561Sobrien if (info->strip != strip_all 9670130561Sobrien || emit_relocs) 9671130561Sobrien { 9672130561Sobrien elfsym.st_size = 0; 9673130561Sobrien elfsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); 9674130561Sobrien elfsym.st_other = 0; 9675218822Sdim elfsym.st_value = 0; 9676130561Sobrien for (i = 1; i < elf_numsections (abfd); i++) 9677130561Sobrien { 9678130561Sobrien o = bfd_section_from_elf_index (abfd, i); 9679130561Sobrien if (o != NULL) 9680218822Sdim { 9681218822Sdim o->target_index = bfd_get_symcount (abfd); 9682218822Sdim elfsym.st_shndx = i; 9683218822Sdim if (!info->relocatable) 9684218822Sdim elfsym.st_value = o->vma; 9685218822Sdim if (!elf_link_output_sym (&finfo, NULL, &elfsym, o, NULL)) 9686218822Sdim goto error_return; 9687218822Sdim } 9688130561Sobrien if (i == SHN_LORESERVE - 1) 9689130561Sobrien i += SHN_HIRESERVE + 1 - SHN_LORESERVE; 9690130561Sobrien } 9691130561Sobrien } 9692130561Sobrien 9693130561Sobrien /* Allocate some memory to hold information read in from the input 9694130561Sobrien files. */ 9695130561Sobrien if (max_contents_size != 0) 9696130561Sobrien { 9697130561Sobrien finfo.contents = bfd_malloc (max_contents_size); 9698130561Sobrien if (finfo.contents == NULL) 9699130561Sobrien goto error_return; 9700130561Sobrien } 9701130561Sobrien 9702130561Sobrien if (max_external_reloc_size != 0) 9703130561Sobrien { 9704130561Sobrien finfo.external_relocs = bfd_malloc (max_external_reloc_size); 9705130561Sobrien if (finfo.external_relocs == NULL) 9706130561Sobrien goto error_return; 9707130561Sobrien } 9708130561Sobrien 9709130561Sobrien if (max_internal_reloc_count != 0) 9710130561Sobrien { 9711130561Sobrien amt = max_internal_reloc_count * bed->s->int_rels_per_ext_rel; 9712130561Sobrien amt *= sizeof (Elf_Internal_Rela); 9713130561Sobrien finfo.internal_relocs = bfd_malloc (amt); 9714130561Sobrien if (finfo.internal_relocs == NULL) 9715130561Sobrien goto error_return; 9716130561Sobrien } 9717130561Sobrien 9718130561Sobrien if (max_sym_count != 0) 9719130561Sobrien { 9720130561Sobrien amt = max_sym_count * bed->s->sizeof_sym; 9721130561Sobrien finfo.external_syms = bfd_malloc (amt); 9722130561Sobrien if (finfo.external_syms == NULL) 9723130561Sobrien goto error_return; 9724130561Sobrien 9725130561Sobrien amt = max_sym_count * sizeof (Elf_Internal_Sym); 9726130561Sobrien finfo.internal_syms = bfd_malloc (amt); 9727130561Sobrien if (finfo.internal_syms == NULL) 9728130561Sobrien goto error_return; 9729130561Sobrien 9730130561Sobrien amt = max_sym_count * sizeof (long); 9731130561Sobrien finfo.indices = bfd_malloc (amt); 9732130561Sobrien if (finfo.indices == NULL) 9733130561Sobrien goto error_return; 9734130561Sobrien 9735130561Sobrien amt = max_sym_count * sizeof (asection *); 9736130561Sobrien finfo.sections = bfd_malloc (amt); 9737130561Sobrien if (finfo.sections == NULL) 9738130561Sobrien goto error_return; 9739130561Sobrien } 9740130561Sobrien 9741130561Sobrien if (max_sym_shndx_count != 0) 9742130561Sobrien { 9743130561Sobrien amt = max_sym_shndx_count * sizeof (Elf_External_Sym_Shndx); 9744130561Sobrien finfo.locsym_shndx = bfd_malloc (amt); 9745130561Sobrien if (finfo.locsym_shndx == NULL) 9746130561Sobrien goto error_return; 9747130561Sobrien } 9748130561Sobrien 9749130561Sobrien if (elf_hash_table (info)->tls_sec) 9750130561Sobrien { 9751130561Sobrien bfd_vma base, end = 0; 9752130561Sobrien asection *sec; 9753130561Sobrien 9754130561Sobrien for (sec = elf_hash_table (info)->tls_sec; 9755130561Sobrien sec && (sec->flags & SEC_THREAD_LOCAL); 9756130561Sobrien sec = sec->next) 9757130561Sobrien { 9758218822Sdim bfd_size_type size = sec->size; 9759130561Sobrien 9760218822Sdim if (size == 0 9761218822Sdim && (sec->flags & SEC_HAS_CONTENTS) == 0) 9762130561Sobrien { 9763218822Sdim struct bfd_link_order *o = sec->map_tail.link_order; 9764218822Sdim if (o != NULL) 9765218822Sdim size = o->offset + o->size; 9766130561Sobrien } 9767130561Sobrien end = sec->vma + size; 9768130561Sobrien } 9769130561Sobrien base = elf_hash_table (info)->tls_sec->vma; 9770130561Sobrien end = align_power (end, elf_hash_table (info)->tls_sec->alignment_power); 9771130561Sobrien elf_hash_table (info)->tls_size = end - base; 9772130561Sobrien } 9773130561Sobrien 9774218822Sdim /* Reorder SHF_LINK_ORDER sections. */ 9775218822Sdim for (o = abfd->sections; o != NULL; o = o->next) 9776218822Sdim { 9777218822Sdim if (!elf_fixup_link_order (abfd, o)) 9778218822Sdim return FALSE; 9779218822Sdim } 9780218822Sdim 9781130561Sobrien /* Since ELF permits relocations to be against local symbols, we 9782130561Sobrien must have the local symbols available when we do the relocations. 9783130561Sobrien Since we would rather only read the local symbols once, and we 9784130561Sobrien would rather not keep them in memory, we handle all the 9785130561Sobrien relocations for a single input file at the same time. 9786130561Sobrien 9787130561Sobrien Unfortunately, there is no way to know the total number of local 9788130561Sobrien symbols until we have seen all of them, and the local symbol 9789130561Sobrien indices precede the global symbol indices. This means that when 9790130561Sobrien we are generating relocatable output, and we see a reloc against 9791130561Sobrien a global symbol, we can not know the symbol index until we have 9792130561Sobrien finished examining all the local symbols to see which ones we are 9793130561Sobrien going to output. To deal with this, we keep the relocations in 9794130561Sobrien memory, and don't output them until the end of the link. This is 9795130561Sobrien an unfortunate waste of memory, but I don't see a good way around 9796130561Sobrien it. Fortunately, it only happens when performing a relocatable 9797130561Sobrien link, which is not the common case. FIXME: If keep_memory is set 9798130561Sobrien we could write the relocs out and then read them again; I don't 9799130561Sobrien know how bad the memory loss will be. */ 9800130561Sobrien 9801130561Sobrien for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) 9802130561Sobrien sub->output_has_begun = FALSE; 9803130561Sobrien for (o = abfd->sections; o != NULL; o = o->next) 9804130561Sobrien { 9805218822Sdim for (p = o->map_head.link_order; p != NULL; p = p->next) 9806130561Sobrien { 9807130561Sobrien if (p->type == bfd_indirect_link_order 9808130561Sobrien && (bfd_get_flavour ((sub = p->u.indirect.section->owner)) 9809130561Sobrien == bfd_target_elf_flavour) 9810130561Sobrien && elf_elfheader (sub)->e_ident[EI_CLASS] == bed->s->elfclass) 9811130561Sobrien { 9812130561Sobrien if (! sub->output_has_begun) 9813130561Sobrien { 9814130561Sobrien if (! elf_link_input_bfd (&finfo, sub)) 9815130561Sobrien goto error_return; 9816130561Sobrien sub->output_has_begun = TRUE; 9817130561Sobrien } 9818130561Sobrien } 9819130561Sobrien else if (p->type == bfd_section_reloc_link_order 9820130561Sobrien || p->type == bfd_symbol_reloc_link_order) 9821130561Sobrien { 9822130561Sobrien if (! elf_reloc_link_order (abfd, info, o, p)) 9823130561Sobrien goto error_return; 9824130561Sobrien } 9825130561Sobrien else 9826130561Sobrien { 9827130561Sobrien if (! _bfd_default_link_order (abfd, info, o, p)) 9828130561Sobrien goto error_return; 9829130561Sobrien } 9830130561Sobrien } 9831130561Sobrien } 9832130561Sobrien 9833218822Sdim /* Free symbol buffer if needed. */ 9834218822Sdim if (!info->reduce_memory_overheads) 9835218822Sdim { 9836218822Sdim for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) 9837218822Sdim if (bfd_get_flavour (sub) == bfd_target_elf_flavour 9838218822Sdim && elf_tdata (sub)->symbuf) 9839218822Sdim { 9840218822Sdim free (elf_tdata (sub)->symbuf); 9841218822Sdim elf_tdata (sub)->symbuf = NULL; 9842218822Sdim } 9843218822Sdim } 9844218822Sdim 9845130561Sobrien /* Output any global symbols that got converted to local in a 9846130561Sobrien version script or due to symbol visibility. We do this in a 9847130561Sobrien separate step since ELF requires all local symbols to appear 9848130561Sobrien prior to any global symbols. FIXME: We should only do this if 9849130561Sobrien some global symbols were, in fact, converted to become local. 9850130561Sobrien FIXME: Will this work correctly with the Irix 5 linker? */ 9851130561Sobrien eoinfo.failed = FALSE; 9852130561Sobrien eoinfo.finfo = &finfo; 9853130561Sobrien eoinfo.localsyms = TRUE; 9854130561Sobrien elf_link_hash_traverse (elf_hash_table (info), elf_link_output_extsym, 9855130561Sobrien &eoinfo); 9856130561Sobrien if (eoinfo.failed) 9857130561Sobrien return FALSE; 9858130561Sobrien 9859218822Sdim /* If backend needs to output some local symbols not present in the hash 9860218822Sdim table, do it now. */ 9861218822Sdim if (bed->elf_backend_output_arch_local_syms) 9862218822Sdim { 9863218822Sdim typedef bfd_boolean (*out_sym_func) 9864218822Sdim (void *, const char *, Elf_Internal_Sym *, asection *, 9865218822Sdim struct elf_link_hash_entry *); 9866218822Sdim 9867218822Sdim if (! ((*bed->elf_backend_output_arch_local_syms) 9868218822Sdim (abfd, info, &finfo, (out_sym_func) elf_link_output_sym))) 9869218822Sdim return FALSE; 9870218822Sdim } 9871218822Sdim 9872130561Sobrien /* That wrote out all the local symbols. Finish up the symbol table 9873130561Sobrien with the global symbols. Even if we want to strip everything we 9874130561Sobrien can, we still need to deal with those global symbols that got 9875130561Sobrien converted to local in a version script. */ 9876130561Sobrien 9877130561Sobrien /* The sh_info field records the index of the first non local symbol. */ 9878130561Sobrien symtab_hdr->sh_info = bfd_get_symcount (abfd); 9879130561Sobrien 9880130561Sobrien if (dynamic 9881130561Sobrien && finfo.dynsym_sec->output_section != bfd_abs_section_ptr) 9882130561Sobrien { 9883130561Sobrien Elf_Internal_Sym sym; 9884130561Sobrien bfd_byte *dynsym = finfo.dynsym_sec->contents; 9885130561Sobrien long last_local = 0; 9886130561Sobrien 9887130561Sobrien /* Write out the section symbols for the output sections. */ 9888218822Sdim if (info->shared || elf_hash_table (info)->is_relocatable_executable) 9889130561Sobrien { 9890130561Sobrien asection *s; 9891130561Sobrien 9892130561Sobrien sym.st_size = 0; 9893130561Sobrien sym.st_name = 0; 9894130561Sobrien sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); 9895130561Sobrien sym.st_other = 0; 9896130561Sobrien 9897130561Sobrien for (s = abfd->sections; s != NULL; s = s->next) 9898130561Sobrien { 9899130561Sobrien int indx; 9900130561Sobrien bfd_byte *dest; 9901130561Sobrien long dynindx; 9902130561Sobrien 9903218822Sdim dynindx = elf_section_data (s)->dynindx; 9904218822Sdim if (dynindx <= 0) 9905218822Sdim continue; 9906130561Sobrien indx = elf_section_data (s)->this_idx; 9907130561Sobrien BFD_ASSERT (indx > 0); 9908130561Sobrien sym.st_shndx = indx; 9909218822Sdim if (! check_dynsym (abfd, &sym)) 9910218822Sdim return FALSE; 9911130561Sobrien sym.st_value = s->vma; 9912130561Sobrien dest = dynsym + dynindx * bed->s->sizeof_sym; 9913218822Sdim if (last_local < dynindx) 9914218822Sdim last_local = dynindx; 9915130561Sobrien bed->s->swap_symbol_out (abfd, &sym, dest, 0); 9916130561Sobrien } 9917130561Sobrien } 9918130561Sobrien 9919130561Sobrien /* Write out the local dynsyms. */ 9920130561Sobrien if (elf_hash_table (info)->dynlocal) 9921130561Sobrien { 9922130561Sobrien struct elf_link_local_dynamic_entry *e; 9923130561Sobrien for (e = elf_hash_table (info)->dynlocal; e ; e = e->next) 9924130561Sobrien { 9925130561Sobrien asection *s; 9926130561Sobrien bfd_byte *dest; 9927130561Sobrien 9928130561Sobrien sym.st_size = e->isym.st_size; 9929130561Sobrien sym.st_other = e->isym.st_other; 9930130561Sobrien 9931130561Sobrien /* Copy the internal symbol as is. 9932130561Sobrien Note that we saved a word of storage and overwrote 9933130561Sobrien the original st_name with the dynstr_index. */ 9934130561Sobrien sym = e->isym; 9935130561Sobrien 9936130561Sobrien if (e->isym.st_shndx != SHN_UNDEF 9937130561Sobrien && (e->isym.st_shndx < SHN_LORESERVE 9938130561Sobrien || e->isym.st_shndx > SHN_HIRESERVE)) 9939130561Sobrien { 9940130561Sobrien s = bfd_section_from_elf_index (e->input_bfd, 9941130561Sobrien e->isym.st_shndx); 9942130561Sobrien 9943130561Sobrien sym.st_shndx = 9944130561Sobrien elf_section_data (s->output_section)->this_idx; 9945218822Sdim if (! check_dynsym (abfd, &sym)) 9946218822Sdim return FALSE; 9947130561Sobrien sym.st_value = (s->output_section->vma 9948130561Sobrien + s->output_offset 9949130561Sobrien + e->isym.st_value); 9950130561Sobrien } 9951130561Sobrien 9952130561Sobrien if (last_local < e->dynindx) 9953130561Sobrien last_local = e->dynindx; 9954130561Sobrien 9955130561Sobrien dest = dynsym + e->dynindx * bed->s->sizeof_sym; 9956130561Sobrien bed->s->swap_symbol_out (abfd, &sym, dest, 0); 9957130561Sobrien } 9958130561Sobrien } 9959130561Sobrien 9960130561Sobrien elf_section_data (finfo.dynsym_sec->output_section)->this_hdr.sh_info = 9961130561Sobrien last_local + 1; 9962130561Sobrien } 9963130561Sobrien 9964130561Sobrien /* We get the global symbols from the hash table. */ 9965130561Sobrien eoinfo.failed = FALSE; 9966130561Sobrien eoinfo.localsyms = FALSE; 9967130561Sobrien eoinfo.finfo = &finfo; 9968130561Sobrien elf_link_hash_traverse (elf_hash_table (info), elf_link_output_extsym, 9969130561Sobrien &eoinfo); 9970130561Sobrien if (eoinfo.failed) 9971130561Sobrien return FALSE; 9972130561Sobrien 9973130561Sobrien /* If backend needs to output some symbols not present in the hash 9974130561Sobrien table, do it now. */ 9975130561Sobrien if (bed->elf_backend_output_arch_syms) 9976130561Sobrien { 9977130561Sobrien typedef bfd_boolean (*out_sym_func) 9978130561Sobrien (void *, const char *, Elf_Internal_Sym *, asection *, 9979130561Sobrien struct elf_link_hash_entry *); 9980130561Sobrien 9981130561Sobrien if (! ((*bed->elf_backend_output_arch_syms) 9982130561Sobrien (abfd, info, &finfo, (out_sym_func) elf_link_output_sym))) 9983130561Sobrien return FALSE; 9984130561Sobrien } 9985130561Sobrien 9986130561Sobrien /* Flush all symbols to the file. */ 9987130561Sobrien if (! elf_link_flush_output_syms (&finfo, bed)) 9988130561Sobrien return FALSE; 9989130561Sobrien 9990130561Sobrien /* Now we know the size of the symtab section. */ 9991130561Sobrien off += symtab_hdr->sh_size; 9992130561Sobrien 9993130561Sobrien symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr; 9994130561Sobrien if (symtab_shndx_hdr->sh_name != 0) 9995130561Sobrien { 9996130561Sobrien symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX; 9997130561Sobrien symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx); 9998130561Sobrien symtab_shndx_hdr->sh_addralign = sizeof (Elf_External_Sym_Shndx); 9999130561Sobrien amt = bfd_get_symcount (abfd) * sizeof (Elf_External_Sym_Shndx); 10000130561Sobrien symtab_shndx_hdr->sh_size = amt; 10001130561Sobrien 10002130561Sobrien off = _bfd_elf_assign_file_position_for_section (symtab_shndx_hdr, 10003130561Sobrien off, TRUE); 10004130561Sobrien 10005130561Sobrien if (bfd_seek (abfd, symtab_shndx_hdr->sh_offset, SEEK_SET) != 0 10006130561Sobrien || (bfd_bwrite (finfo.symshndxbuf, amt, abfd) != amt)) 10007130561Sobrien return FALSE; 10008130561Sobrien } 10009130561Sobrien 10010130561Sobrien 10011130561Sobrien /* Finish up and write out the symbol string table (.strtab) 10012130561Sobrien section. */ 10013130561Sobrien symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr; 10014130561Sobrien /* sh_name was set in prep_headers. */ 10015130561Sobrien symstrtab_hdr->sh_type = SHT_STRTAB; 10016130561Sobrien symstrtab_hdr->sh_flags = 0; 10017130561Sobrien symstrtab_hdr->sh_addr = 0; 10018130561Sobrien symstrtab_hdr->sh_size = _bfd_stringtab_size (finfo.symstrtab); 10019130561Sobrien symstrtab_hdr->sh_entsize = 0; 10020130561Sobrien symstrtab_hdr->sh_link = 0; 10021130561Sobrien symstrtab_hdr->sh_info = 0; 10022130561Sobrien /* sh_offset is set just below. */ 10023130561Sobrien symstrtab_hdr->sh_addralign = 1; 10024130561Sobrien 10025130561Sobrien off = _bfd_elf_assign_file_position_for_section (symstrtab_hdr, off, TRUE); 10026130561Sobrien elf_tdata (abfd)->next_file_pos = off; 10027130561Sobrien 10028130561Sobrien if (bfd_get_symcount (abfd) > 0) 10029130561Sobrien { 10030130561Sobrien if (bfd_seek (abfd, symstrtab_hdr->sh_offset, SEEK_SET) != 0 10031130561Sobrien || ! _bfd_stringtab_emit (abfd, finfo.symstrtab)) 10032130561Sobrien return FALSE; 10033130561Sobrien } 10034130561Sobrien 10035130561Sobrien /* Adjust the relocs to have the correct symbol indices. */ 10036130561Sobrien for (o = abfd->sections; o != NULL; o = o->next) 10037130561Sobrien { 10038130561Sobrien if ((o->flags & SEC_RELOC) == 0) 10039130561Sobrien continue; 10040130561Sobrien 10041130561Sobrien elf_link_adjust_relocs (abfd, &elf_section_data (o)->rel_hdr, 10042130561Sobrien elf_section_data (o)->rel_count, 10043130561Sobrien elf_section_data (o)->rel_hashes); 10044130561Sobrien if (elf_section_data (o)->rel_hdr2 != NULL) 10045130561Sobrien elf_link_adjust_relocs (abfd, elf_section_data (o)->rel_hdr2, 10046130561Sobrien elf_section_data (o)->rel_count2, 10047130561Sobrien (elf_section_data (o)->rel_hashes 10048130561Sobrien + elf_section_data (o)->rel_count)); 10049130561Sobrien 10050130561Sobrien /* Set the reloc_count field to 0 to prevent write_relocs from 10051130561Sobrien trying to swap the relocs out itself. */ 10052130561Sobrien o->reloc_count = 0; 10053130561Sobrien } 10054130561Sobrien 10055130561Sobrien if (dynamic && info->combreloc && dynobj != NULL) 10056130561Sobrien relativecount = elf_link_sort_relocs (abfd, info, &reldyn); 10057130561Sobrien 10058130561Sobrien /* If we are linking against a dynamic object, or generating a 10059130561Sobrien shared library, finish up the dynamic linking information. */ 10060130561Sobrien if (dynamic) 10061130561Sobrien { 10062130561Sobrien bfd_byte *dyncon, *dynconend; 10063130561Sobrien 10064130561Sobrien /* Fix up .dynamic entries. */ 10065130561Sobrien o = bfd_get_section_by_name (dynobj, ".dynamic"); 10066130561Sobrien BFD_ASSERT (o != NULL); 10067130561Sobrien 10068130561Sobrien dyncon = o->contents; 10069218822Sdim dynconend = o->contents + o->size; 10070130561Sobrien for (; dyncon < dynconend; dyncon += bed->s->sizeof_dyn) 10071130561Sobrien { 10072130561Sobrien Elf_Internal_Dyn dyn; 10073130561Sobrien const char *name; 10074130561Sobrien unsigned int type; 10075130561Sobrien 10076130561Sobrien bed->s->swap_dyn_in (dynobj, dyncon, &dyn); 10077130561Sobrien 10078130561Sobrien switch (dyn.d_tag) 10079130561Sobrien { 10080130561Sobrien default: 10081130561Sobrien continue; 10082130561Sobrien case DT_NULL: 10083130561Sobrien if (relativecount > 0 && dyncon + bed->s->sizeof_dyn < dynconend) 10084130561Sobrien { 10085130561Sobrien switch (elf_section_data (reldyn)->this_hdr.sh_type) 10086130561Sobrien { 10087130561Sobrien case SHT_REL: dyn.d_tag = DT_RELCOUNT; break; 10088130561Sobrien case SHT_RELA: dyn.d_tag = DT_RELACOUNT; break; 10089130561Sobrien default: continue; 10090130561Sobrien } 10091130561Sobrien dyn.d_un.d_val = relativecount; 10092130561Sobrien relativecount = 0; 10093130561Sobrien break; 10094130561Sobrien } 10095130561Sobrien continue; 10096130561Sobrien 10097130561Sobrien case DT_INIT: 10098130561Sobrien name = info->init_function; 10099130561Sobrien goto get_sym; 10100130561Sobrien case DT_FINI: 10101130561Sobrien name = info->fini_function; 10102130561Sobrien get_sym: 10103130561Sobrien { 10104130561Sobrien struct elf_link_hash_entry *h; 10105130561Sobrien 10106130561Sobrien h = elf_link_hash_lookup (elf_hash_table (info), name, 10107130561Sobrien FALSE, FALSE, TRUE); 10108130561Sobrien if (h != NULL 10109130561Sobrien && (h->root.type == bfd_link_hash_defined 10110130561Sobrien || h->root.type == bfd_link_hash_defweak)) 10111130561Sobrien { 10112130561Sobrien dyn.d_un.d_val = h->root.u.def.value; 10113130561Sobrien o = h->root.u.def.section; 10114130561Sobrien if (o->output_section != NULL) 10115130561Sobrien dyn.d_un.d_val += (o->output_section->vma 10116130561Sobrien + o->output_offset); 10117130561Sobrien else 10118130561Sobrien { 10119130561Sobrien /* The symbol is imported from another shared 10120130561Sobrien library and does not apply to this one. */ 10121130561Sobrien dyn.d_un.d_val = 0; 10122130561Sobrien } 10123130561Sobrien break; 10124130561Sobrien } 10125130561Sobrien } 10126130561Sobrien continue; 10127130561Sobrien 10128130561Sobrien case DT_PREINIT_ARRAYSZ: 10129130561Sobrien name = ".preinit_array"; 10130130561Sobrien goto get_size; 10131130561Sobrien case DT_INIT_ARRAYSZ: 10132130561Sobrien name = ".init_array"; 10133130561Sobrien goto get_size; 10134130561Sobrien case DT_FINI_ARRAYSZ: 10135130561Sobrien name = ".fini_array"; 10136130561Sobrien get_size: 10137130561Sobrien o = bfd_get_section_by_name (abfd, name); 10138130561Sobrien if (o == NULL) 10139130561Sobrien { 10140130561Sobrien (*_bfd_error_handler) 10141218822Sdim (_("%B: could not find output section %s"), abfd, name); 10142130561Sobrien goto error_return; 10143130561Sobrien } 10144218822Sdim if (o->size == 0) 10145130561Sobrien (*_bfd_error_handler) 10146130561Sobrien (_("warning: %s section has zero size"), name); 10147218822Sdim dyn.d_un.d_val = o->size; 10148130561Sobrien break; 10149130561Sobrien 10150130561Sobrien case DT_PREINIT_ARRAY: 10151130561Sobrien name = ".preinit_array"; 10152130561Sobrien goto get_vma; 10153130561Sobrien case DT_INIT_ARRAY: 10154130561Sobrien name = ".init_array"; 10155130561Sobrien goto get_vma; 10156130561Sobrien case DT_FINI_ARRAY: 10157130561Sobrien name = ".fini_array"; 10158130561Sobrien goto get_vma; 10159130561Sobrien 10160130561Sobrien case DT_HASH: 10161130561Sobrien name = ".hash"; 10162130561Sobrien goto get_vma; 10163218822Sdim case DT_GNU_HASH: 10164218822Sdim name = ".gnu.hash"; 10165218822Sdim goto get_vma; 10166130561Sobrien case DT_STRTAB: 10167130561Sobrien name = ".dynstr"; 10168130561Sobrien goto get_vma; 10169130561Sobrien case DT_SYMTAB: 10170130561Sobrien name = ".dynsym"; 10171130561Sobrien goto get_vma; 10172130561Sobrien case DT_VERDEF: 10173130561Sobrien name = ".gnu.version_d"; 10174130561Sobrien goto get_vma; 10175130561Sobrien case DT_VERNEED: 10176130561Sobrien name = ".gnu.version_r"; 10177130561Sobrien goto get_vma; 10178130561Sobrien case DT_VERSYM: 10179130561Sobrien name = ".gnu.version"; 10180130561Sobrien get_vma: 10181130561Sobrien o = bfd_get_section_by_name (abfd, name); 10182130561Sobrien if (o == NULL) 10183130561Sobrien { 10184130561Sobrien (*_bfd_error_handler) 10185218822Sdim (_("%B: could not find output section %s"), abfd, name); 10186130561Sobrien goto error_return; 10187130561Sobrien } 10188130561Sobrien dyn.d_un.d_ptr = o->vma; 10189130561Sobrien break; 10190130561Sobrien 10191130561Sobrien case DT_REL: 10192130561Sobrien case DT_RELA: 10193130561Sobrien case DT_RELSZ: 10194130561Sobrien case DT_RELASZ: 10195130561Sobrien if (dyn.d_tag == DT_REL || dyn.d_tag == DT_RELSZ) 10196130561Sobrien type = SHT_REL; 10197130561Sobrien else 10198130561Sobrien type = SHT_RELA; 10199130561Sobrien dyn.d_un.d_val = 0; 10200130561Sobrien for (i = 1; i < elf_numsections (abfd); i++) 10201130561Sobrien { 10202130561Sobrien Elf_Internal_Shdr *hdr; 10203130561Sobrien 10204130561Sobrien hdr = elf_elfsections (abfd)[i]; 10205130561Sobrien if (hdr->sh_type == type 10206130561Sobrien && (hdr->sh_flags & SHF_ALLOC) != 0) 10207130561Sobrien { 10208130561Sobrien if (dyn.d_tag == DT_RELSZ || dyn.d_tag == DT_RELASZ) 10209130561Sobrien dyn.d_un.d_val += hdr->sh_size; 10210130561Sobrien else 10211130561Sobrien { 10212130561Sobrien if (dyn.d_un.d_val == 0 10213130561Sobrien || hdr->sh_addr < dyn.d_un.d_val) 10214130561Sobrien dyn.d_un.d_val = hdr->sh_addr; 10215130561Sobrien } 10216130561Sobrien } 10217130561Sobrien } 10218130561Sobrien break; 10219130561Sobrien } 10220130561Sobrien bed->s->swap_dyn_out (dynobj, &dyn, dyncon); 10221130561Sobrien } 10222130561Sobrien } 10223130561Sobrien 10224130561Sobrien /* If we have created any dynamic sections, then output them. */ 10225130561Sobrien if (dynobj != NULL) 10226130561Sobrien { 10227130561Sobrien if (! (*bed->elf_backend_finish_dynamic_sections) (abfd, info)) 10228130561Sobrien goto error_return; 10229130561Sobrien 10230218822Sdim /* Check for DT_TEXTREL (late, in case the backend removes it). */ 10231218822Sdim if (info->warn_shared_textrel && info->shared) 10232218822Sdim { 10233218822Sdim bfd_byte *dyncon, *dynconend; 10234218822Sdim 10235218822Sdim /* Fix up .dynamic entries. */ 10236218822Sdim o = bfd_get_section_by_name (dynobj, ".dynamic"); 10237218822Sdim BFD_ASSERT (o != NULL); 10238218822Sdim 10239218822Sdim dyncon = o->contents; 10240218822Sdim dynconend = o->contents + o->size; 10241218822Sdim for (; dyncon < dynconend; dyncon += bed->s->sizeof_dyn) 10242218822Sdim { 10243218822Sdim Elf_Internal_Dyn dyn; 10244218822Sdim 10245218822Sdim bed->s->swap_dyn_in (dynobj, dyncon, &dyn); 10246218822Sdim 10247218822Sdim if (dyn.d_tag == DT_TEXTREL) 10248218822Sdim { 10249218822Sdim info->callbacks->einfo 10250218822Sdim (_("%P: warning: creating a DT_TEXTREL in a shared object.\n")); 10251218822Sdim break; 10252218822Sdim } 10253218822Sdim } 10254218822Sdim } 10255218822Sdim 10256130561Sobrien for (o = dynobj->sections; o != NULL; o = o->next) 10257130561Sobrien { 10258130561Sobrien if ((o->flags & SEC_HAS_CONTENTS) == 0 10259218822Sdim || o->size == 0 10260130561Sobrien || o->output_section == bfd_abs_section_ptr) 10261130561Sobrien continue; 10262130561Sobrien if ((o->flags & SEC_LINKER_CREATED) == 0) 10263130561Sobrien { 10264130561Sobrien /* At this point, we are only interested in sections 10265130561Sobrien created by _bfd_elf_link_create_dynamic_sections. */ 10266130561Sobrien continue; 10267130561Sobrien } 10268218822Sdim if (elf_hash_table (info)->stab_info.stabstr == o) 10269218822Sdim continue; 10270218822Sdim if (elf_hash_table (info)->eh_info.hdr_sec == o) 10271218822Sdim continue; 10272130561Sobrien if ((elf_section_data (o->output_section)->this_hdr.sh_type 10273130561Sobrien != SHT_STRTAB) 10274130561Sobrien || strcmp (bfd_get_section_name (abfd, o), ".dynstr") != 0) 10275130561Sobrien { 10276130561Sobrien if (! bfd_set_section_contents (abfd, o->output_section, 10277130561Sobrien o->contents, 10278130561Sobrien (file_ptr) o->output_offset, 10279218822Sdim o->size)) 10280130561Sobrien goto error_return; 10281130561Sobrien } 10282130561Sobrien else 10283130561Sobrien { 10284130561Sobrien /* The contents of the .dynstr section are actually in a 10285130561Sobrien stringtab. */ 10286130561Sobrien off = elf_section_data (o->output_section)->this_hdr.sh_offset; 10287130561Sobrien if (bfd_seek (abfd, off, SEEK_SET) != 0 10288130561Sobrien || ! _bfd_elf_strtab_emit (abfd, 10289130561Sobrien elf_hash_table (info)->dynstr)) 10290130561Sobrien goto error_return; 10291130561Sobrien } 10292130561Sobrien } 10293130561Sobrien } 10294130561Sobrien 10295130561Sobrien if (info->relocatable) 10296130561Sobrien { 10297130561Sobrien bfd_boolean failed = FALSE; 10298130561Sobrien 10299130561Sobrien bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed); 10300130561Sobrien if (failed) 10301130561Sobrien goto error_return; 10302130561Sobrien } 10303130561Sobrien 10304130561Sobrien /* If we have optimized stabs strings, output them. */ 10305218822Sdim if (elf_hash_table (info)->stab_info.stabstr != NULL) 10306130561Sobrien { 10307130561Sobrien if (! _bfd_write_stab_strings (abfd, &elf_hash_table (info)->stab_info)) 10308130561Sobrien goto error_return; 10309130561Sobrien } 10310130561Sobrien 10311130561Sobrien if (info->eh_frame_hdr) 10312130561Sobrien { 10313130561Sobrien if (! _bfd_elf_write_section_eh_frame_hdr (abfd, info)) 10314130561Sobrien goto error_return; 10315130561Sobrien } 10316130561Sobrien 10317130561Sobrien if (finfo.symstrtab != NULL) 10318130561Sobrien _bfd_stringtab_free (finfo.symstrtab); 10319130561Sobrien if (finfo.contents != NULL) 10320130561Sobrien free (finfo.contents); 10321130561Sobrien if (finfo.external_relocs != NULL) 10322130561Sobrien free (finfo.external_relocs); 10323130561Sobrien if (finfo.internal_relocs != NULL) 10324130561Sobrien free (finfo.internal_relocs); 10325130561Sobrien if (finfo.external_syms != NULL) 10326130561Sobrien free (finfo.external_syms); 10327130561Sobrien if (finfo.locsym_shndx != NULL) 10328130561Sobrien free (finfo.locsym_shndx); 10329130561Sobrien if (finfo.internal_syms != NULL) 10330130561Sobrien free (finfo.internal_syms); 10331130561Sobrien if (finfo.indices != NULL) 10332130561Sobrien free (finfo.indices); 10333130561Sobrien if (finfo.sections != NULL) 10334130561Sobrien free (finfo.sections); 10335130561Sobrien if (finfo.symbuf != NULL) 10336130561Sobrien free (finfo.symbuf); 10337130561Sobrien if (finfo.symshndxbuf != NULL) 10338130561Sobrien free (finfo.symshndxbuf); 10339130561Sobrien for (o = abfd->sections; o != NULL; o = o->next) 10340130561Sobrien { 10341130561Sobrien if ((o->flags & SEC_RELOC) != 0 10342130561Sobrien && elf_section_data (o)->rel_hashes != NULL) 10343130561Sobrien free (elf_section_data (o)->rel_hashes); 10344130561Sobrien } 10345130561Sobrien 10346130561Sobrien elf_tdata (abfd)->linker = TRUE; 10347130561Sobrien 10348218822Sdim if (attr_section) 10349218822Sdim { 10350218822Sdim bfd_byte *contents = bfd_malloc (attr_size); 10351218822Sdim if (contents == NULL) 10352218822Sdim goto error_return; 10353218822Sdim bfd_elf_set_obj_attr_contents (abfd, contents, attr_size); 10354218822Sdim bfd_set_section_contents (abfd, attr_section, contents, 0, attr_size); 10355218822Sdim free (contents); 10356218822Sdim } 10357218822Sdim 10358130561Sobrien return TRUE; 10359130561Sobrien 10360130561Sobrien error_return: 10361130561Sobrien if (finfo.symstrtab != NULL) 10362130561Sobrien _bfd_stringtab_free (finfo.symstrtab); 10363130561Sobrien if (finfo.contents != NULL) 10364130561Sobrien free (finfo.contents); 10365130561Sobrien if (finfo.external_relocs != NULL) 10366130561Sobrien free (finfo.external_relocs); 10367130561Sobrien if (finfo.internal_relocs != NULL) 10368130561Sobrien free (finfo.internal_relocs); 10369130561Sobrien if (finfo.external_syms != NULL) 10370130561Sobrien free (finfo.external_syms); 10371130561Sobrien if (finfo.locsym_shndx != NULL) 10372130561Sobrien free (finfo.locsym_shndx); 10373130561Sobrien if (finfo.internal_syms != NULL) 10374130561Sobrien free (finfo.internal_syms); 10375130561Sobrien if (finfo.indices != NULL) 10376130561Sobrien free (finfo.indices); 10377130561Sobrien if (finfo.sections != NULL) 10378130561Sobrien free (finfo.sections); 10379130561Sobrien if (finfo.symbuf != NULL) 10380130561Sobrien free (finfo.symbuf); 10381130561Sobrien if (finfo.symshndxbuf != NULL) 10382130561Sobrien free (finfo.symshndxbuf); 10383130561Sobrien for (o = abfd->sections; o != NULL; o = o->next) 10384130561Sobrien { 10385130561Sobrien if ((o->flags & SEC_RELOC) != 0 10386130561Sobrien && elf_section_data (o)->rel_hashes != NULL) 10387130561Sobrien free (elf_section_data (o)->rel_hashes); 10388130561Sobrien } 10389130561Sobrien 10390130561Sobrien return FALSE; 1039133965Sjdp} 1039233965Sjdp 10393130561Sobrien/* Garbage collect unused sections. */ 1039433965Sjdp 10395218822Sdim/* Default gc_mark_hook. */ 10396218822Sdim 10397218822Sdimasection * 10398218822Sdim_bfd_elf_gc_mark_hook (asection *sec, 10399218822Sdim struct bfd_link_info *info ATTRIBUTE_UNUSED, 10400218822Sdim Elf_Internal_Rela *rel ATTRIBUTE_UNUSED, 10401218822Sdim struct elf_link_hash_entry *h, 10402218822Sdim Elf_Internal_Sym *sym) 10403218822Sdim{ 10404218822Sdim if (h != NULL) 10405218822Sdim { 10406218822Sdim switch (h->root.type) 10407218822Sdim { 10408218822Sdim case bfd_link_hash_defined: 10409218822Sdim case bfd_link_hash_defweak: 10410218822Sdim return h->root.u.def.section; 10411218822Sdim 10412218822Sdim case bfd_link_hash_common: 10413218822Sdim return h->root.u.c.p->section; 10414218822Sdim 10415218822Sdim default: 10416218822Sdim break; 10417218822Sdim } 10418218822Sdim } 10419218822Sdim else 10420218822Sdim return bfd_section_from_elf_index (sec->owner, sym->st_shndx); 10421218822Sdim 10422218822Sdim return NULL; 10423218822Sdim} 10424218822Sdim 10425130561Sobrien/* The mark phase of garbage collection. For a given section, mark 10426130561Sobrien it and any sections in this section's group, and all the sections 10427130561Sobrien which define symbols to which it refers. */ 10428130561Sobrien 10429218822Sdimbfd_boolean 10430218822Sdim_bfd_elf_gc_mark (struct bfd_link_info *info, 10431218822Sdim asection *sec, 10432218822Sdim elf_gc_mark_hook_fn gc_mark_hook) 1043333965Sjdp{ 10434130561Sobrien bfd_boolean ret; 10435218822Sdim bfd_boolean is_eh; 10436130561Sobrien asection *group_sec; 10437130561Sobrien 10438130561Sobrien sec->gc_mark = 1; 10439130561Sobrien 10440130561Sobrien /* Mark all the sections in the group. */ 10441130561Sobrien group_sec = elf_section_data (sec)->next_in_group; 10442130561Sobrien if (group_sec && !group_sec->gc_mark) 10443218822Sdim if (!_bfd_elf_gc_mark (info, group_sec, gc_mark_hook)) 10444130561Sobrien return FALSE; 10445130561Sobrien 10446130561Sobrien /* Look through the section relocs. */ 10447130561Sobrien ret = TRUE; 10448218822Sdim is_eh = strcmp (sec->name, ".eh_frame") == 0; 10449130561Sobrien if ((sec->flags & SEC_RELOC) != 0 && sec->reloc_count > 0) 1045033965Sjdp { 10451130561Sobrien Elf_Internal_Rela *relstart, *rel, *relend; 10452130561Sobrien Elf_Internal_Shdr *symtab_hdr; 10453130561Sobrien struct elf_link_hash_entry **sym_hashes; 10454130561Sobrien size_t nlocsyms; 10455130561Sobrien size_t extsymoff; 10456130561Sobrien bfd *input_bfd = sec->owner; 10457130561Sobrien const struct elf_backend_data *bed = get_elf_backend_data (input_bfd); 10458130561Sobrien Elf_Internal_Sym *isym = NULL; 10459130561Sobrien int r_sym_shift; 10460130561Sobrien 10461130561Sobrien symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; 10462130561Sobrien sym_hashes = elf_sym_hashes (input_bfd); 10463130561Sobrien 10464130561Sobrien /* Read the local symbols. */ 10465130561Sobrien if (elf_bad_symtab (input_bfd)) 10466130561Sobrien { 10467130561Sobrien nlocsyms = symtab_hdr->sh_size / bed->s->sizeof_sym; 10468130561Sobrien extsymoff = 0; 10469130561Sobrien } 10470130561Sobrien else 10471130561Sobrien extsymoff = nlocsyms = symtab_hdr->sh_info; 10472130561Sobrien 10473130561Sobrien isym = (Elf_Internal_Sym *) symtab_hdr->contents; 10474130561Sobrien if (isym == NULL && nlocsyms != 0) 10475130561Sobrien { 10476130561Sobrien isym = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, nlocsyms, 0, 10477130561Sobrien NULL, NULL, NULL); 10478130561Sobrien if (isym == NULL) 10479130561Sobrien return FALSE; 10480130561Sobrien } 10481130561Sobrien 10482130561Sobrien /* Read the relocations. */ 10483130561Sobrien relstart = _bfd_elf_link_read_relocs (input_bfd, sec, NULL, NULL, 10484130561Sobrien info->keep_memory); 10485130561Sobrien if (relstart == NULL) 10486130561Sobrien { 10487130561Sobrien ret = FALSE; 10488130561Sobrien goto out1; 10489130561Sobrien } 10490130561Sobrien relend = relstart + sec->reloc_count * bed->s->int_rels_per_ext_rel; 10491130561Sobrien 10492130561Sobrien if (bed->s->arch_size == 32) 10493130561Sobrien r_sym_shift = 8; 10494130561Sobrien else 10495130561Sobrien r_sym_shift = 32; 10496130561Sobrien 10497130561Sobrien for (rel = relstart; rel < relend; rel++) 10498130561Sobrien { 10499130561Sobrien unsigned long r_symndx; 10500130561Sobrien asection *rsec; 10501130561Sobrien struct elf_link_hash_entry *h; 10502130561Sobrien 10503130561Sobrien r_symndx = rel->r_info >> r_sym_shift; 10504130561Sobrien if (r_symndx == 0) 10505130561Sobrien continue; 10506130561Sobrien 10507130561Sobrien if (r_symndx >= nlocsyms 10508130561Sobrien || ELF_ST_BIND (isym[r_symndx].st_info) != STB_LOCAL) 10509130561Sobrien { 10510130561Sobrien h = sym_hashes[r_symndx - extsymoff]; 10511218822Sdim while (h->root.type == bfd_link_hash_indirect 10512218822Sdim || h->root.type == bfd_link_hash_warning) 10513218822Sdim h = (struct elf_link_hash_entry *) h->root.u.i.link; 10514130561Sobrien rsec = (*gc_mark_hook) (sec, info, rel, h, NULL); 10515130561Sobrien } 10516130561Sobrien else 10517130561Sobrien { 10518130561Sobrien rsec = (*gc_mark_hook) (sec, info, rel, NULL, &isym[r_symndx]); 10519130561Sobrien } 10520130561Sobrien 10521130561Sobrien if (rsec && !rsec->gc_mark) 10522130561Sobrien { 10523130561Sobrien if (bfd_get_flavour (rsec->owner) != bfd_target_elf_flavour) 10524130561Sobrien rsec->gc_mark = 1; 10525218822Sdim else if (is_eh) 10526218822Sdim rsec->gc_mark_from_eh = 1; 10527218822Sdim else if (!_bfd_elf_gc_mark (info, rsec, gc_mark_hook)) 10528130561Sobrien { 10529130561Sobrien ret = FALSE; 10530130561Sobrien goto out2; 10531130561Sobrien } 10532130561Sobrien } 10533130561Sobrien } 10534130561Sobrien 10535130561Sobrien out2: 10536130561Sobrien if (elf_section_data (sec)->relocs != relstart) 10537130561Sobrien free (relstart); 10538130561Sobrien out1: 10539130561Sobrien if (isym != NULL && symtab_hdr->contents != (unsigned char *) isym) 10540130561Sobrien { 10541130561Sobrien if (! info->keep_memory) 10542130561Sobrien free (isym); 10543130561Sobrien else 10544130561Sobrien symtab_hdr->contents = (unsigned char *) isym; 10545130561Sobrien } 1054633965Sjdp } 1054733965Sjdp 10548130561Sobrien return ret; 1054933965Sjdp} 10550130561Sobrien 10551130561Sobrien/* Sweep symbols in swept sections. Called via elf_link_hash_traverse. */ 10552130561Sobrien 10553218822Sdimstruct elf_gc_sweep_symbol_info 10554218822Sdim{ 10555218822Sdim struct bfd_link_info *info; 10556218822Sdim void (*hide_symbol) (struct bfd_link_info *, struct elf_link_hash_entry *, 10557218822Sdim bfd_boolean); 10558218822Sdim}; 10559218822Sdim 10560130561Sobrienstatic bfd_boolean 10561218822Sdimelf_gc_sweep_symbol (struct elf_link_hash_entry *h, void *data) 10562130561Sobrien{ 10563130561Sobrien if (h->root.type == bfd_link_hash_warning) 10564130561Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 10565130561Sobrien 10566218822Sdim if ((h->root.type == bfd_link_hash_defined 10567218822Sdim || h->root.type == bfd_link_hash_defweak) 10568218822Sdim && !h->root.u.def.section->gc_mark 10569218822Sdim && !(h->root.u.def.section->owner->flags & DYNAMIC)) 10570218822Sdim { 10571218822Sdim struct elf_gc_sweep_symbol_info *inf = data; 10572218822Sdim (*inf->hide_symbol) (inf->info, h, TRUE); 10573218822Sdim } 10574130561Sobrien 10575130561Sobrien return TRUE; 10576130561Sobrien} 10577130561Sobrien 10578130561Sobrien/* The sweep phase of garbage collection. Remove all garbage sections. */ 10579130561Sobrien 10580130561Sobrientypedef bfd_boolean (*gc_sweep_hook_fn) 10581130561Sobrien (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *); 10582130561Sobrien 10583130561Sobrienstatic bfd_boolean 10584218822Sdimelf_gc_sweep (bfd *abfd, struct bfd_link_info *info) 10585130561Sobrien{ 10586130561Sobrien bfd *sub; 10587218822Sdim const struct elf_backend_data *bed = get_elf_backend_data (abfd); 10588218822Sdim gc_sweep_hook_fn gc_sweep_hook = bed->gc_sweep_hook; 10589218822Sdim unsigned long section_sym_count; 10590218822Sdim struct elf_gc_sweep_symbol_info sweep_info; 10591130561Sobrien 10592130561Sobrien for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) 10593130561Sobrien { 10594130561Sobrien asection *o; 10595130561Sobrien 10596130561Sobrien if (bfd_get_flavour (sub) != bfd_target_elf_flavour) 10597130561Sobrien continue; 10598130561Sobrien 10599130561Sobrien for (o = sub->sections; o != NULL; o = o->next) 10600130561Sobrien { 10601218822Sdim /* Keep debug and special sections. */ 10602218822Sdim if ((o->flags & (SEC_DEBUGGING | SEC_LINKER_CREATED)) != 0 10603244600Sdim || elf_section_data (o)->this_hdr.sh_type == SHT_NOTE 10604218822Sdim || (o->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0) 10605130561Sobrien o->gc_mark = 1; 10606130561Sobrien 10607130561Sobrien if (o->gc_mark) 10608130561Sobrien continue; 10609130561Sobrien 10610130561Sobrien /* Skip sweeping sections already excluded. */ 10611130561Sobrien if (o->flags & SEC_EXCLUDE) 10612130561Sobrien continue; 10613130561Sobrien 10614130561Sobrien /* Since this is early in the link process, it is simple 10615130561Sobrien to remove a section from the output. */ 10616130561Sobrien o->flags |= SEC_EXCLUDE; 10617130561Sobrien 10618218822Sdim if (info->print_gc_sections && o->size != 0) 10619218822Sdim _bfd_error_handler (_("Removing unused section '%s' in file '%B'"), sub, o->name); 10620218822Sdim 10621130561Sobrien /* But we also have to update some of the relocation 10622130561Sobrien info we collected before. */ 10623130561Sobrien if (gc_sweep_hook 10624218822Sdim && (o->flags & SEC_RELOC) != 0 10625218822Sdim && o->reloc_count > 0 10626218822Sdim && !bfd_is_abs_section (o->output_section)) 10627130561Sobrien { 10628130561Sobrien Elf_Internal_Rela *internal_relocs; 10629130561Sobrien bfd_boolean r; 10630130561Sobrien 10631130561Sobrien internal_relocs 10632130561Sobrien = _bfd_elf_link_read_relocs (o->owner, o, NULL, NULL, 10633130561Sobrien info->keep_memory); 10634130561Sobrien if (internal_relocs == NULL) 10635130561Sobrien return FALSE; 10636130561Sobrien 10637130561Sobrien r = (*gc_sweep_hook) (o->owner, info, o, internal_relocs); 10638130561Sobrien 10639130561Sobrien if (elf_section_data (o)->relocs != internal_relocs) 10640130561Sobrien free (internal_relocs); 10641130561Sobrien 10642130561Sobrien if (!r) 10643130561Sobrien return FALSE; 10644130561Sobrien } 10645130561Sobrien } 10646130561Sobrien } 10647130561Sobrien 10648130561Sobrien /* Remove the symbols that were in the swept sections from the dynamic 10649130561Sobrien symbol table. GCFIXME: Anyone know how to get them out of the 10650130561Sobrien static symbol table as well? */ 10651218822Sdim sweep_info.info = info; 10652218822Sdim sweep_info.hide_symbol = bed->elf_backend_hide_symbol; 10653218822Sdim elf_link_hash_traverse (elf_hash_table (info), elf_gc_sweep_symbol, 10654218822Sdim &sweep_info); 10655130561Sobrien 10656218822Sdim _bfd_elf_link_renumber_dynsyms (abfd, info, §ion_sym_count); 10657130561Sobrien return TRUE; 10658130561Sobrien} 10659130561Sobrien 10660130561Sobrien/* Propagate collected vtable information. This is called through 10661130561Sobrien elf_link_hash_traverse. */ 10662130561Sobrien 10663130561Sobrienstatic bfd_boolean 10664130561Sobrienelf_gc_propagate_vtable_entries_used (struct elf_link_hash_entry *h, void *okp) 10665130561Sobrien{ 10666130561Sobrien if (h->root.type == bfd_link_hash_warning) 10667130561Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 10668130561Sobrien 10669130561Sobrien /* Those that are not vtables. */ 10670218822Sdim if (h->vtable == NULL || h->vtable->parent == NULL) 10671130561Sobrien return TRUE; 10672130561Sobrien 10673130561Sobrien /* Those vtables that do not have parents, we cannot merge. */ 10674218822Sdim if (h->vtable->parent == (struct elf_link_hash_entry *) -1) 10675130561Sobrien return TRUE; 10676130561Sobrien 10677130561Sobrien /* If we've already been done, exit. */ 10678218822Sdim if (h->vtable->used && h->vtable->used[-1]) 10679130561Sobrien return TRUE; 10680130561Sobrien 10681130561Sobrien /* Make sure the parent's table is up to date. */ 10682218822Sdim elf_gc_propagate_vtable_entries_used (h->vtable->parent, okp); 10683130561Sobrien 10684218822Sdim if (h->vtable->used == NULL) 10685130561Sobrien { 10686130561Sobrien /* None of this table's entries were referenced. Re-use the 10687130561Sobrien parent's table. */ 10688218822Sdim h->vtable->used = h->vtable->parent->vtable->used; 10689218822Sdim h->vtable->size = h->vtable->parent->vtable->size; 10690130561Sobrien } 10691130561Sobrien else 10692130561Sobrien { 10693130561Sobrien size_t n; 10694130561Sobrien bfd_boolean *cu, *pu; 10695130561Sobrien 10696130561Sobrien /* Or the parent's entries into ours. */ 10697218822Sdim cu = h->vtable->used; 10698130561Sobrien cu[-1] = TRUE; 10699218822Sdim pu = h->vtable->parent->vtable->used; 10700130561Sobrien if (pu != NULL) 10701130561Sobrien { 10702130561Sobrien const struct elf_backend_data *bed; 10703130561Sobrien unsigned int log_file_align; 10704130561Sobrien 10705130561Sobrien bed = get_elf_backend_data (h->root.u.def.section->owner); 10706130561Sobrien log_file_align = bed->s->log_file_align; 10707218822Sdim n = h->vtable->parent->vtable->size >> log_file_align; 10708130561Sobrien while (n--) 10709130561Sobrien { 10710130561Sobrien if (*pu) 10711130561Sobrien *cu = TRUE; 10712130561Sobrien pu++; 10713130561Sobrien cu++; 10714130561Sobrien } 10715130561Sobrien } 10716130561Sobrien } 10717130561Sobrien 10718130561Sobrien return TRUE; 10719130561Sobrien} 10720130561Sobrien 10721130561Sobrienstatic bfd_boolean 10722130561Sobrienelf_gc_smash_unused_vtentry_relocs (struct elf_link_hash_entry *h, void *okp) 10723130561Sobrien{ 10724130561Sobrien asection *sec; 10725130561Sobrien bfd_vma hstart, hend; 10726130561Sobrien Elf_Internal_Rela *relstart, *relend, *rel; 10727130561Sobrien const struct elf_backend_data *bed; 10728130561Sobrien unsigned int log_file_align; 10729130561Sobrien 10730130561Sobrien if (h->root.type == bfd_link_hash_warning) 10731130561Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 10732130561Sobrien 10733130561Sobrien /* Take care of both those symbols that do not describe vtables as 10734130561Sobrien well as those that are not loaded. */ 10735218822Sdim if (h->vtable == NULL || h->vtable->parent == NULL) 10736130561Sobrien return TRUE; 10737130561Sobrien 10738130561Sobrien BFD_ASSERT (h->root.type == bfd_link_hash_defined 10739130561Sobrien || h->root.type == bfd_link_hash_defweak); 10740130561Sobrien 10741130561Sobrien sec = h->root.u.def.section; 10742130561Sobrien hstart = h->root.u.def.value; 10743130561Sobrien hend = hstart + h->size; 10744130561Sobrien 10745130561Sobrien relstart = _bfd_elf_link_read_relocs (sec->owner, sec, NULL, NULL, TRUE); 10746130561Sobrien if (!relstart) 10747130561Sobrien return *(bfd_boolean *) okp = FALSE; 10748130561Sobrien bed = get_elf_backend_data (sec->owner); 10749130561Sobrien log_file_align = bed->s->log_file_align; 10750130561Sobrien 10751130561Sobrien relend = relstart + sec->reloc_count * bed->s->int_rels_per_ext_rel; 10752130561Sobrien 10753130561Sobrien for (rel = relstart; rel < relend; ++rel) 10754130561Sobrien if (rel->r_offset >= hstart && rel->r_offset < hend) 10755130561Sobrien { 10756130561Sobrien /* If the entry is in use, do nothing. */ 10757218822Sdim if (h->vtable->used 10758218822Sdim && (rel->r_offset - hstart) < h->vtable->size) 10759130561Sobrien { 10760130561Sobrien bfd_vma entry = (rel->r_offset - hstart) >> log_file_align; 10761218822Sdim if (h->vtable->used[entry]) 10762130561Sobrien continue; 10763130561Sobrien } 10764130561Sobrien /* Otherwise, kill it. */ 10765130561Sobrien rel->r_offset = rel->r_info = rel->r_addend = 0; 10766130561Sobrien } 10767130561Sobrien 10768130561Sobrien return TRUE; 10769130561Sobrien} 10770130561Sobrien 10771218822Sdim/* Mark sections containing dynamically referenced symbols. When 10772218822Sdim building shared libraries, we must assume that any visible symbol is 10773218822Sdim referenced. */ 10774218822Sdim 10775218822Sdimbfd_boolean 10776218822Sdimbfd_elf_gc_mark_dynamic_ref_symbol (struct elf_link_hash_entry *h, void *inf) 10777218822Sdim{ 10778218822Sdim struct bfd_link_info *info = (struct bfd_link_info *) inf; 10779218822Sdim 10780218822Sdim if (h->root.type == bfd_link_hash_warning) 10781218822Sdim h = (struct elf_link_hash_entry *) h->root.u.i.link; 10782218822Sdim 10783218822Sdim if ((h->root.type == bfd_link_hash_defined 10784218822Sdim || h->root.type == bfd_link_hash_defweak) 10785218822Sdim && (h->ref_dynamic 10786218822Sdim || (!info->executable 10787218822Sdim && h->def_regular 10788218822Sdim && ELF_ST_VISIBILITY (h->other) != STV_INTERNAL 10789218822Sdim && ELF_ST_VISIBILITY (h->other) != STV_HIDDEN))) 10790218822Sdim h->root.u.def.section->flags |= SEC_KEEP; 10791218822Sdim 10792218822Sdim return TRUE; 10793218822Sdim} 10794218822Sdim 10795130561Sobrien/* Do mark and sweep of unused sections. */ 10796130561Sobrien 10797130561Sobrienbfd_boolean 10798130561Sobrienbfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info) 10799130561Sobrien{ 10800130561Sobrien bfd_boolean ok = TRUE; 10801130561Sobrien bfd *sub; 10802218822Sdim elf_gc_mark_hook_fn gc_mark_hook; 10803218822Sdim const struct elf_backend_data *bed = get_elf_backend_data (abfd); 10804130561Sobrien 10805218822Sdim if (!bed->can_gc_sections 10806130561Sobrien || info->relocatable 10807130561Sobrien || info->emitrelocations 10808218822Sdim || !is_elf_hash_table (info->hash)) 10809130561Sobrien { 10810130561Sobrien (*_bfd_error_handler)(_("Warning: gc-sections option ignored")); 10811130561Sobrien return TRUE; 10812130561Sobrien } 10813130561Sobrien 10814130561Sobrien /* Apply transitive closure to the vtable entry usage info. */ 10815130561Sobrien elf_link_hash_traverse (elf_hash_table (info), 10816130561Sobrien elf_gc_propagate_vtable_entries_used, 10817130561Sobrien &ok); 10818130561Sobrien if (!ok) 10819130561Sobrien return FALSE; 10820130561Sobrien 10821130561Sobrien /* Kill the vtable relocations that were not used. */ 10822130561Sobrien elf_link_hash_traverse (elf_hash_table (info), 10823130561Sobrien elf_gc_smash_unused_vtentry_relocs, 10824130561Sobrien &ok); 10825130561Sobrien if (!ok) 10826130561Sobrien return FALSE; 10827130561Sobrien 10828218822Sdim /* Mark dynamically referenced symbols. */ 10829218822Sdim if (elf_hash_table (info)->dynamic_sections_created) 10830218822Sdim elf_link_hash_traverse (elf_hash_table (info), 10831218822Sdim bed->gc_mark_dynamic_ref, 10832218822Sdim info); 10833218822Sdim 10834130561Sobrien /* Grovel through relocs to find out who stays ... */ 10835218822Sdim gc_mark_hook = bed->gc_mark_hook; 10836218822Sdim for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) 10837218822Sdim { 10838218822Sdim asection *o; 10839130561Sobrien 10840218822Sdim if (bfd_get_flavour (sub) != bfd_target_elf_flavour) 10841218822Sdim continue; 10842218822Sdim 10843218822Sdim for (o = sub->sections; o != NULL; o = o->next) 10844218822Sdim if ((o->flags & (SEC_EXCLUDE | SEC_KEEP)) == SEC_KEEP && !o->gc_mark) 10845218822Sdim if (!_bfd_elf_gc_mark (info, o, gc_mark_hook)) 10846218822Sdim return FALSE; 10847218822Sdim } 10848218822Sdim 10849218822Sdim /* Allow the backend to mark additional target specific sections. */ 10850218822Sdim if (bed->gc_mark_extra_sections) 10851218822Sdim bed->gc_mark_extra_sections(info, gc_mark_hook); 10852218822Sdim 10853218822Sdim /* ... again for sections marked from eh_frame. */ 10854130561Sobrien for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) 10855130561Sobrien { 10856130561Sobrien asection *o; 10857130561Sobrien 10858130561Sobrien if (bfd_get_flavour (sub) != bfd_target_elf_flavour) 10859130561Sobrien continue; 10860130561Sobrien 10861218822Sdim /* Keep .gcc_except_table.* if the associated .text.* (or the 10862218822Sdim associated .gnu.linkonce.t.* if .text.* doesn't exist) is 10863218822Sdim marked. This isn't very nice, but the proper solution, 10864218822Sdim splitting .eh_frame up and using comdat doesn't pan out 10865218822Sdim easily due to needing special relocs to handle the 10866218822Sdim difference of two symbols in separate sections. 10867218822Sdim Don't keep code sections referenced by .eh_frame. */ 10868218822Sdim#define TEXT_PREFIX ".text." 10869218822Sdim#define TEXT_PREFIX2 ".gnu.linkonce.t." 10870218822Sdim#define GCC_EXCEPT_TABLE_PREFIX ".gcc_except_table." 10871130561Sobrien for (o = sub->sections; o != NULL; o = o->next) 10872218822Sdim if (!o->gc_mark && o->gc_mark_from_eh && (o->flags & SEC_CODE) == 0) 10873218822Sdim { 10874218822Sdim if (CONST_STRNEQ (o->name, GCC_EXCEPT_TABLE_PREFIX)) 10875218822Sdim { 10876218822Sdim char *fn_name; 10877218822Sdim const char *sec_name; 10878218822Sdim asection *fn_text; 10879218822Sdim unsigned o_name_prefix_len , fn_name_prefix_len, tmp; 10880218822Sdim 10881218822Sdim o_name_prefix_len = strlen (GCC_EXCEPT_TABLE_PREFIX); 10882218822Sdim sec_name = o->name + o_name_prefix_len; 10883218822Sdim fn_name_prefix_len = strlen (TEXT_PREFIX); 10884218822Sdim tmp = strlen (TEXT_PREFIX2); 10885218822Sdim if (tmp > fn_name_prefix_len) 10886218822Sdim fn_name_prefix_len = tmp; 10887218822Sdim fn_name 10888218822Sdim = bfd_malloc (fn_name_prefix_len + strlen (sec_name) + 1); 10889218822Sdim if (fn_name == NULL) 10890218822Sdim return FALSE; 10891218822Sdim 10892218822Sdim /* Try the first prefix. */ 10893218822Sdim sprintf (fn_name, "%s%s", TEXT_PREFIX, sec_name); 10894218822Sdim fn_text = bfd_get_section_by_name (sub, fn_name); 10895218822Sdim 10896218822Sdim /* Try the second prefix. */ 10897218822Sdim if (fn_text == NULL) 10898218822Sdim { 10899218822Sdim sprintf (fn_name, "%s%s", TEXT_PREFIX2, sec_name); 10900218822Sdim fn_text = bfd_get_section_by_name (sub, fn_name); 10901218822Sdim } 10902218822Sdim 10903218822Sdim free (fn_name); 10904218822Sdim if (fn_text == NULL || !fn_text->gc_mark) 10905218822Sdim continue; 10906218822Sdim } 10907218822Sdim 10908218822Sdim /* If not using specially named exception table section, 10909218822Sdim then keep whatever we are using. */ 10910218822Sdim if (!_bfd_elf_gc_mark (info, o, gc_mark_hook)) 10911130561Sobrien return FALSE; 10912218822Sdim } 10913130561Sobrien } 10914130561Sobrien 10915130561Sobrien /* ... and mark SEC_EXCLUDE for those that go. */ 10916218822Sdim return elf_gc_sweep (abfd, info); 10917130561Sobrien} 1091833965Sjdp 10919130561Sobrien/* Called from check_relocs to record the existence of a VTINHERIT reloc. */ 1092033965Sjdp 10921130561Sobrienbfd_boolean 10922130561Sobrienbfd_elf_gc_record_vtinherit (bfd *abfd, 10923130561Sobrien asection *sec, 10924130561Sobrien struct elf_link_hash_entry *h, 10925130561Sobrien bfd_vma offset) 1092633965Sjdp{ 10927130561Sobrien struct elf_link_hash_entry **sym_hashes, **sym_hashes_end; 10928130561Sobrien struct elf_link_hash_entry **search, *child; 10929130561Sobrien bfd_size_type extsymcount; 10930130561Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 1093133965Sjdp 10932130561Sobrien /* The sh_info field of the symtab header tells us where the 10933130561Sobrien external symbols start. We don't care about the local symbols at 10934130561Sobrien this point. */ 10935130561Sobrien extsymcount = elf_tdata (abfd)->symtab_hdr.sh_size / bed->s->sizeof_sym; 10936130561Sobrien if (!elf_bad_symtab (abfd)) 10937130561Sobrien extsymcount -= elf_tdata (abfd)->symtab_hdr.sh_info; 10938130561Sobrien 10939130561Sobrien sym_hashes = elf_sym_hashes (abfd); 10940130561Sobrien sym_hashes_end = sym_hashes + extsymcount; 10941130561Sobrien 10942130561Sobrien /* Hunt down the child symbol, which is in this section at the same 10943130561Sobrien offset as the relocation. */ 10944130561Sobrien for (search = sym_hashes; search != sym_hashes_end; ++search) 1094533965Sjdp { 10946130561Sobrien if ((child = *search) != NULL 10947130561Sobrien && (child->root.type == bfd_link_hash_defined 10948130561Sobrien || child->root.type == bfd_link_hash_defweak) 10949130561Sobrien && child->root.u.def.section == sec 10950130561Sobrien && child->root.u.def.value == offset) 10951130561Sobrien goto win; 1095233965Sjdp } 1095333965Sjdp 10954218822Sdim (*_bfd_error_handler) ("%B: %A+%lu: No symbol found for INHERIT", 10955218822Sdim abfd, sec, (unsigned long) offset); 10956130561Sobrien bfd_set_error (bfd_error_invalid_operation); 10957130561Sobrien return FALSE; 10958130561Sobrien 10959130561Sobrien win: 10960218822Sdim if (!child->vtable) 10961218822Sdim { 10962218822Sdim child->vtable = bfd_zalloc (abfd, sizeof (*child->vtable)); 10963218822Sdim if (!child->vtable) 10964218822Sdim return FALSE; 10965218822Sdim } 10966130561Sobrien if (!h) 10967130561Sobrien { 10968130561Sobrien /* This *should* only be the absolute section. It could potentially 10969130561Sobrien be that someone has defined a non-global vtable though, which 10970130561Sobrien would be bad. It isn't worth paging in the local symbols to be 10971130561Sobrien sure though; that case should simply be handled by the assembler. */ 10972130561Sobrien 10973218822Sdim child->vtable->parent = (struct elf_link_hash_entry *) -1; 10974130561Sobrien } 10975130561Sobrien else 10976218822Sdim child->vtable->parent = h; 10977130561Sobrien 10978130561Sobrien return TRUE; 1097933965Sjdp} 10980130561Sobrien 10981130561Sobrien/* Called from check_relocs to record the existence of a VTENTRY reloc. */ 10982130561Sobrien 10983130561Sobrienbfd_boolean 10984130561Sobrienbfd_elf_gc_record_vtentry (bfd *abfd ATTRIBUTE_UNUSED, 10985130561Sobrien asection *sec ATTRIBUTE_UNUSED, 10986130561Sobrien struct elf_link_hash_entry *h, 10987130561Sobrien bfd_vma addend) 10988130561Sobrien{ 10989130561Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 10990130561Sobrien unsigned int log_file_align = bed->s->log_file_align; 10991130561Sobrien 10992218822Sdim if (!h->vtable) 10993130561Sobrien { 10994218822Sdim h->vtable = bfd_zalloc (abfd, sizeof (*h->vtable)); 10995218822Sdim if (!h->vtable) 10996218822Sdim return FALSE; 10997218822Sdim } 10998218822Sdim 10999218822Sdim if (addend >= h->vtable->size) 11000218822Sdim { 11001130561Sobrien size_t size, bytes, file_align; 11002218822Sdim bfd_boolean *ptr = h->vtable->used; 11003130561Sobrien 11004130561Sobrien /* While the symbol is undefined, we have to be prepared to handle 11005130561Sobrien a zero size. */ 11006130561Sobrien file_align = 1 << log_file_align; 11007130561Sobrien if (h->root.type == bfd_link_hash_undefined) 11008130561Sobrien size = addend + file_align; 11009130561Sobrien else 11010130561Sobrien { 11011130561Sobrien size = h->size; 11012130561Sobrien if (addend >= size) 11013130561Sobrien { 11014130561Sobrien /* Oops! We've got a reference past the defined end of 11015130561Sobrien the table. This is probably a bug -- shall we warn? */ 11016130561Sobrien size = addend + file_align; 11017130561Sobrien } 11018130561Sobrien } 11019130561Sobrien size = (size + file_align - 1) & -file_align; 11020130561Sobrien 11021130561Sobrien /* Allocate one extra entry for use as a "done" flag for the 11022130561Sobrien consolidation pass. */ 11023130561Sobrien bytes = ((size >> log_file_align) + 1) * sizeof (bfd_boolean); 11024130561Sobrien 11025130561Sobrien if (ptr) 11026130561Sobrien { 11027130561Sobrien ptr = bfd_realloc (ptr - 1, bytes); 11028130561Sobrien 11029130561Sobrien if (ptr != NULL) 11030130561Sobrien { 11031130561Sobrien size_t oldbytes; 11032130561Sobrien 11033218822Sdim oldbytes = (((h->vtable->size >> log_file_align) + 1) 11034130561Sobrien * sizeof (bfd_boolean)); 11035130561Sobrien memset (((char *) ptr) + oldbytes, 0, bytes - oldbytes); 11036130561Sobrien } 11037130561Sobrien } 11038130561Sobrien else 11039130561Sobrien ptr = bfd_zmalloc (bytes); 11040130561Sobrien 11041130561Sobrien if (ptr == NULL) 11042130561Sobrien return FALSE; 11043130561Sobrien 11044130561Sobrien /* And arrange for that done flag to be at index -1. */ 11045218822Sdim h->vtable->used = ptr + 1; 11046218822Sdim h->vtable->size = size; 11047130561Sobrien } 11048130561Sobrien 11049218822Sdim h->vtable->used[addend >> log_file_align] = TRUE; 11050130561Sobrien 11051130561Sobrien return TRUE; 11052130561Sobrien} 11053130561Sobrien 11054130561Sobrienstruct alloc_got_off_arg { 11055130561Sobrien bfd_vma gotoff; 11056130561Sobrien unsigned int got_elt_size; 11057130561Sobrien}; 11058130561Sobrien 11059130561Sobrien/* We need a special top-level link routine to convert got reference counts 11060130561Sobrien to real got offsets. */ 11061130561Sobrien 11062130561Sobrienstatic bfd_boolean 11063130561Sobrienelf_gc_allocate_got_offsets (struct elf_link_hash_entry *h, void *arg) 11064130561Sobrien{ 11065130561Sobrien struct alloc_got_off_arg *gofarg = arg; 11066130561Sobrien 11067130561Sobrien if (h->root.type == bfd_link_hash_warning) 11068130561Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 11069130561Sobrien 11070130561Sobrien if (h->got.refcount > 0) 11071130561Sobrien { 11072130561Sobrien h->got.offset = gofarg->gotoff; 11073130561Sobrien gofarg->gotoff += gofarg->got_elt_size; 11074130561Sobrien } 11075130561Sobrien else 11076130561Sobrien h->got.offset = (bfd_vma) -1; 11077130561Sobrien 11078130561Sobrien return TRUE; 11079130561Sobrien} 11080130561Sobrien 11081130561Sobrien/* And an accompanying bit to work out final got entry offsets once 11082130561Sobrien we're done. Should be called from final_link. */ 11083130561Sobrien 11084130561Sobrienbfd_boolean 11085130561Sobrienbfd_elf_gc_common_finalize_got_offsets (bfd *abfd, 11086130561Sobrien struct bfd_link_info *info) 11087130561Sobrien{ 11088130561Sobrien bfd *i; 11089130561Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 11090130561Sobrien bfd_vma gotoff; 11091130561Sobrien unsigned int got_elt_size = bed->s->arch_size / 8; 11092130561Sobrien struct alloc_got_off_arg gofarg; 11093130561Sobrien 11094130561Sobrien if (! is_elf_hash_table (info->hash)) 11095130561Sobrien return FALSE; 11096130561Sobrien 11097130561Sobrien /* The GOT offset is relative to the .got section, but the GOT header is 11098130561Sobrien put into the .got.plt section, if the backend uses it. */ 11099130561Sobrien if (bed->want_got_plt) 11100130561Sobrien gotoff = 0; 11101130561Sobrien else 11102130561Sobrien gotoff = bed->got_header_size; 11103130561Sobrien 11104130561Sobrien /* Do the local .got entries first. */ 11105130561Sobrien for (i = info->input_bfds; i; i = i->link_next) 11106130561Sobrien { 11107130561Sobrien bfd_signed_vma *local_got; 11108130561Sobrien bfd_size_type j, locsymcount; 11109130561Sobrien Elf_Internal_Shdr *symtab_hdr; 11110130561Sobrien 11111130561Sobrien if (bfd_get_flavour (i) != bfd_target_elf_flavour) 11112130561Sobrien continue; 11113130561Sobrien 11114130561Sobrien local_got = elf_local_got_refcounts (i); 11115130561Sobrien if (!local_got) 11116130561Sobrien continue; 11117130561Sobrien 11118130561Sobrien symtab_hdr = &elf_tdata (i)->symtab_hdr; 11119130561Sobrien if (elf_bad_symtab (i)) 11120130561Sobrien locsymcount = symtab_hdr->sh_size / bed->s->sizeof_sym; 11121130561Sobrien else 11122130561Sobrien locsymcount = symtab_hdr->sh_info; 11123130561Sobrien 11124130561Sobrien for (j = 0; j < locsymcount; ++j) 11125130561Sobrien { 11126130561Sobrien if (local_got[j] > 0) 11127130561Sobrien { 11128130561Sobrien local_got[j] = gotoff; 11129130561Sobrien gotoff += got_elt_size; 11130130561Sobrien } 11131130561Sobrien else 11132130561Sobrien local_got[j] = (bfd_vma) -1; 11133130561Sobrien } 11134130561Sobrien } 11135130561Sobrien 11136130561Sobrien /* Then the global .got entries. .plt refcounts are handled by 11137130561Sobrien adjust_dynamic_symbol */ 11138130561Sobrien gofarg.gotoff = gotoff; 11139130561Sobrien gofarg.got_elt_size = got_elt_size; 11140130561Sobrien elf_link_hash_traverse (elf_hash_table (info), 11141130561Sobrien elf_gc_allocate_got_offsets, 11142130561Sobrien &gofarg); 11143130561Sobrien return TRUE; 11144130561Sobrien} 11145130561Sobrien 11146130561Sobrien/* Many folk need no more in the way of final link than this, once 11147130561Sobrien got entry reference counting is enabled. */ 11148130561Sobrien 11149130561Sobrienbfd_boolean 11150130561Sobrienbfd_elf_gc_common_final_link (bfd *abfd, struct bfd_link_info *info) 11151130561Sobrien{ 11152130561Sobrien if (!bfd_elf_gc_common_finalize_got_offsets (abfd, info)) 11153130561Sobrien return FALSE; 11154130561Sobrien 11155130561Sobrien /* Invoke the regular ELF backend linker to do all the work. */ 11156130561Sobrien return bfd_elf_final_link (abfd, info); 11157130561Sobrien} 11158130561Sobrien 11159130561Sobrienbfd_boolean 11160130561Sobrienbfd_elf_reloc_symbol_deleted_p (bfd_vma offset, void *cookie) 11161130561Sobrien{ 11162130561Sobrien struct elf_reloc_cookie *rcookie = cookie; 11163130561Sobrien 11164130561Sobrien if (rcookie->bad_symtab) 11165130561Sobrien rcookie->rel = rcookie->rels; 11166130561Sobrien 11167130561Sobrien for (; rcookie->rel < rcookie->relend; rcookie->rel++) 11168130561Sobrien { 11169130561Sobrien unsigned long r_symndx; 11170130561Sobrien 11171130561Sobrien if (! rcookie->bad_symtab) 11172130561Sobrien if (rcookie->rel->r_offset > offset) 11173130561Sobrien return FALSE; 11174130561Sobrien if (rcookie->rel->r_offset != offset) 11175130561Sobrien continue; 11176130561Sobrien 11177130561Sobrien r_symndx = rcookie->rel->r_info >> rcookie->r_sym_shift; 11178130561Sobrien if (r_symndx == SHN_UNDEF) 11179130561Sobrien return TRUE; 11180130561Sobrien 11181130561Sobrien if (r_symndx >= rcookie->locsymcount 11182130561Sobrien || ELF_ST_BIND (rcookie->locsyms[r_symndx].st_info) != STB_LOCAL) 11183130561Sobrien { 11184130561Sobrien struct elf_link_hash_entry *h; 11185130561Sobrien 11186130561Sobrien h = rcookie->sym_hashes[r_symndx - rcookie->extsymoff]; 11187130561Sobrien 11188130561Sobrien while (h->root.type == bfd_link_hash_indirect 11189130561Sobrien || h->root.type == bfd_link_hash_warning) 11190130561Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 11191130561Sobrien 11192130561Sobrien if ((h->root.type == bfd_link_hash_defined 11193130561Sobrien || h->root.type == bfd_link_hash_defweak) 11194130561Sobrien && elf_discarded_section (h->root.u.def.section)) 11195130561Sobrien return TRUE; 11196130561Sobrien else 11197130561Sobrien return FALSE; 11198130561Sobrien } 11199130561Sobrien else 11200130561Sobrien { 11201130561Sobrien /* It's not a relocation against a global symbol, 11202130561Sobrien but it could be a relocation against a local 11203130561Sobrien symbol for a discarded section. */ 11204130561Sobrien asection *isec; 11205130561Sobrien Elf_Internal_Sym *isym; 11206130561Sobrien 11207130561Sobrien /* Need to: get the symbol; get the section. */ 11208130561Sobrien isym = &rcookie->locsyms[r_symndx]; 11209130561Sobrien if (isym->st_shndx < SHN_LORESERVE || isym->st_shndx > SHN_HIRESERVE) 11210130561Sobrien { 11211130561Sobrien isec = bfd_section_from_elf_index (rcookie->abfd, isym->st_shndx); 11212130561Sobrien if (isec != NULL && elf_discarded_section (isec)) 11213130561Sobrien return TRUE; 11214130561Sobrien } 11215130561Sobrien } 11216130561Sobrien return FALSE; 11217130561Sobrien } 11218130561Sobrien return FALSE; 11219130561Sobrien} 11220130561Sobrien 11221130561Sobrien/* Discard unneeded references to discarded sections. 11222130561Sobrien Returns TRUE if any section's size was changed. */ 11223130561Sobrien/* This function assumes that the relocations are in sorted order, 11224130561Sobrien which is true for all known assemblers. */ 11225130561Sobrien 11226130561Sobrienbfd_boolean 11227130561Sobrienbfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info) 11228130561Sobrien{ 11229130561Sobrien struct elf_reloc_cookie cookie; 11230130561Sobrien asection *stab, *eh; 11231130561Sobrien Elf_Internal_Shdr *symtab_hdr; 11232130561Sobrien const struct elf_backend_data *bed; 11233130561Sobrien bfd *abfd; 11234130561Sobrien unsigned int count; 11235130561Sobrien bfd_boolean ret = FALSE; 11236130561Sobrien 11237130561Sobrien if (info->traditional_format 11238130561Sobrien || !is_elf_hash_table (info->hash)) 11239130561Sobrien return FALSE; 11240130561Sobrien 11241130561Sobrien for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next) 11242130561Sobrien { 11243130561Sobrien if (bfd_get_flavour (abfd) != bfd_target_elf_flavour) 11244130561Sobrien continue; 11245130561Sobrien 11246130561Sobrien bed = get_elf_backend_data (abfd); 11247130561Sobrien 11248130561Sobrien if ((abfd->flags & DYNAMIC) != 0) 11249130561Sobrien continue; 11250130561Sobrien 11251218822Sdim eh = NULL; 11252218822Sdim if (!info->relocatable) 11253218822Sdim { 11254218822Sdim eh = bfd_get_section_by_name (abfd, ".eh_frame"); 11255218822Sdim if (eh != NULL 11256218822Sdim && (eh->size == 0 11257218822Sdim || bfd_is_abs_section (eh->output_section))) 11258218822Sdim eh = NULL; 11259218822Sdim } 11260130561Sobrien 11261130561Sobrien stab = bfd_get_section_by_name (abfd, ".stab"); 11262130561Sobrien if (stab != NULL 11263218822Sdim && (stab->size == 0 11264130561Sobrien || bfd_is_abs_section (stab->output_section) 11265130561Sobrien || stab->sec_info_type != ELF_INFO_TYPE_STABS)) 11266130561Sobrien stab = NULL; 11267130561Sobrien 11268130561Sobrien if (stab == NULL 11269130561Sobrien && eh == NULL 11270130561Sobrien && bed->elf_backend_discard_info == NULL) 11271130561Sobrien continue; 11272130561Sobrien 11273130561Sobrien symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 11274130561Sobrien cookie.abfd = abfd; 11275130561Sobrien cookie.sym_hashes = elf_sym_hashes (abfd); 11276130561Sobrien cookie.bad_symtab = elf_bad_symtab (abfd); 11277130561Sobrien if (cookie.bad_symtab) 11278130561Sobrien { 11279130561Sobrien cookie.locsymcount = symtab_hdr->sh_size / bed->s->sizeof_sym; 11280130561Sobrien cookie.extsymoff = 0; 11281130561Sobrien } 11282130561Sobrien else 11283130561Sobrien { 11284130561Sobrien cookie.locsymcount = symtab_hdr->sh_info; 11285130561Sobrien cookie.extsymoff = symtab_hdr->sh_info; 11286130561Sobrien } 11287130561Sobrien 11288130561Sobrien if (bed->s->arch_size == 32) 11289130561Sobrien cookie.r_sym_shift = 8; 11290130561Sobrien else 11291130561Sobrien cookie.r_sym_shift = 32; 11292130561Sobrien 11293130561Sobrien cookie.locsyms = (Elf_Internal_Sym *) symtab_hdr->contents; 11294130561Sobrien if (cookie.locsyms == NULL && cookie.locsymcount != 0) 11295130561Sobrien { 11296130561Sobrien cookie.locsyms = bfd_elf_get_elf_syms (abfd, symtab_hdr, 11297130561Sobrien cookie.locsymcount, 0, 11298130561Sobrien NULL, NULL, NULL); 11299130561Sobrien if (cookie.locsyms == NULL) 11300218822Sdim { 11301218822Sdim info->callbacks->einfo (_("%P%X: can not read symbols: %E\n")); 11302218822Sdim return FALSE; 11303218822Sdim } 11304130561Sobrien } 11305130561Sobrien 11306130561Sobrien if (stab != NULL) 11307130561Sobrien { 11308130561Sobrien cookie.rels = NULL; 11309130561Sobrien count = stab->reloc_count; 11310130561Sobrien if (count != 0) 11311130561Sobrien cookie.rels = _bfd_elf_link_read_relocs (abfd, stab, NULL, NULL, 11312130561Sobrien info->keep_memory); 11313130561Sobrien if (cookie.rels != NULL) 11314130561Sobrien { 11315130561Sobrien cookie.rel = cookie.rels; 11316130561Sobrien cookie.relend = cookie.rels; 11317130561Sobrien cookie.relend += count * bed->s->int_rels_per_ext_rel; 11318130561Sobrien if (_bfd_discard_section_stabs (abfd, stab, 11319130561Sobrien elf_section_data (stab)->sec_info, 11320130561Sobrien bfd_elf_reloc_symbol_deleted_p, 11321130561Sobrien &cookie)) 11322130561Sobrien ret = TRUE; 11323130561Sobrien if (elf_section_data (stab)->relocs != cookie.rels) 11324130561Sobrien free (cookie.rels); 11325130561Sobrien } 11326130561Sobrien } 11327130561Sobrien 11328130561Sobrien if (eh != NULL) 11329130561Sobrien { 11330130561Sobrien cookie.rels = NULL; 11331130561Sobrien count = eh->reloc_count; 11332130561Sobrien if (count != 0) 11333130561Sobrien cookie.rels = _bfd_elf_link_read_relocs (abfd, eh, NULL, NULL, 11334130561Sobrien info->keep_memory); 11335130561Sobrien cookie.rel = cookie.rels; 11336130561Sobrien cookie.relend = cookie.rels; 11337130561Sobrien if (cookie.rels != NULL) 11338130561Sobrien cookie.relend += count * bed->s->int_rels_per_ext_rel; 11339130561Sobrien 11340130561Sobrien if (_bfd_elf_discard_section_eh_frame (abfd, info, eh, 11341130561Sobrien bfd_elf_reloc_symbol_deleted_p, 11342130561Sobrien &cookie)) 11343130561Sobrien ret = TRUE; 11344130561Sobrien 11345130561Sobrien if (cookie.rels != NULL 11346130561Sobrien && elf_section_data (eh)->relocs != cookie.rels) 11347130561Sobrien free (cookie.rels); 11348130561Sobrien } 11349130561Sobrien 11350130561Sobrien if (bed->elf_backend_discard_info != NULL 11351130561Sobrien && (*bed->elf_backend_discard_info) (abfd, &cookie, info)) 11352130561Sobrien ret = TRUE; 11353130561Sobrien 11354130561Sobrien if (cookie.locsyms != NULL 11355130561Sobrien && symtab_hdr->contents != (unsigned char *) cookie.locsyms) 11356130561Sobrien { 11357130561Sobrien if (! info->keep_memory) 11358130561Sobrien free (cookie.locsyms); 11359130561Sobrien else 11360130561Sobrien symtab_hdr->contents = (unsigned char *) cookie.locsyms; 11361130561Sobrien } 11362130561Sobrien } 11363130561Sobrien 11364130561Sobrien if (info->eh_frame_hdr 11365130561Sobrien && !info->relocatable 11366130561Sobrien && _bfd_elf_discard_section_eh_frame_hdr (output_bfd, info)) 11367130561Sobrien ret = TRUE; 11368130561Sobrien 11369130561Sobrien return ret; 11370130561Sobrien} 11371218822Sdim 11372218822Sdimvoid 11373218822Sdim_bfd_elf_section_already_linked (bfd *abfd, struct bfd_section *sec, 11374218822Sdim struct bfd_link_info *info) 11375218822Sdim{ 11376218822Sdim flagword flags; 11377218822Sdim const char *name, *p; 11378218822Sdim struct bfd_section_already_linked *l; 11379218822Sdim struct bfd_section_already_linked_hash_entry *already_linked_list; 11380218822Sdim 11381218822Sdim if (sec->output_section == bfd_abs_section_ptr) 11382218822Sdim return; 11383218822Sdim 11384218822Sdim flags = sec->flags; 11385218822Sdim 11386218822Sdim /* Return if it isn't a linkonce section. A comdat group section 11387218822Sdim also has SEC_LINK_ONCE set. */ 11388218822Sdim if ((flags & SEC_LINK_ONCE) == 0) 11389218822Sdim return; 11390218822Sdim 11391218822Sdim /* Don't put group member sections on our list of already linked 11392218822Sdim sections. They are handled as a group via their group section. */ 11393218822Sdim if (elf_sec_group (sec) != NULL) 11394218822Sdim return; 11395218822Sdim 11396218822Sdim /* FIXME: When doing a relocatable link, we may have trouble 11397218822Sdim copying relocations in other sections that refer to local symbols 11398218822Sdim in the section being discarded. Those relocations will have to 11399218822Sdim be converted somehow; as of this writing I'm not sure that any of 11400218822Sdim the backends handle that correctly. 11401218822Sdim 11402218822Sdim It is tempting to instead not discard link once sections when 11403218822Sdim doing a relocatable link (technically, they should be discarded 11404218822Sdim whenever we are building constructors). However, that fails, 11405218822Sdim because the linker winds up combining all the link once sections 11406218822Sdim into a single large link once section, which defeats the purpose 11407218822Sdim of having link once sections in the first place. 11408218822Sdim 11409218822Sdim Also, not merging link once sections in a relocatable link 11410218822Sdim causes trouble for MIPS ELF, which relies on link once semantics 11411218822Sdim to handle the .reginfo section correctly. */ 11412218822Sdim 11413218822Sdim name = bfd_get_section_name (abfd, sec); 11414218822Sdim 11415218822Sdim if (CONST_STRNEQ (name, ".gnu.linkonce.") 11416218822Sdim && (p = strchr (name + sizeof (".gnu.linkonce.") - 1, '.')) != NULL) 11417218822Sdim p++; 11418218822Sdim else 11419218822Sdim p = name; 11420218822Sdim 11421218822Sdim already_linked_list = bfd_section_already_linked_table_lookup (p); 11422218822Sdim 11423218822Sdim for (l = already_linked_list->entry; l != NULL; l = l->next) 11424218822Sdim { 11425218822Sdim /* We may have 2 different types of sections on the list: group 11426218822Sdim sections and linkonce sections. Match like sections. */ 11427218822Sdim if ((flags & SEC_GROUP) == (l->sec->flags & SEC_GROUP) 11428218822Sdim && strcmp (name, l->sec->name) == 0 11429218822Sdim && bfd_coff_get_comdat_section (l->sec->owner, l->sec) == NULL) 11430218822Sdim { 11431218822Sdim /* The section has already been linked. See if we should 11432218822Sdim issue a warning. */ 11433218822Sdim switch (flags & SEC_LINK_DUPLICATES) 11434218822Sdim { 11435218822Sdim default: 11436218822Sdim abort (); 11437218822Sdim 11438218822Sdim case SEC_LINK_DUPLICATES_DISCARD: 11439218822Sdim break; 11440218822Sdim 11441218822Sdim case SEC_LINK_DUPLICATES_ONE_ONLY: 11442218822Sdim (*_bfd_error_handler) 11443218822Sdim (_("%B: ignoring duplicate section `%A'"), 11444218822Sdim abfd, sec); 11445218822Sdim break; 11446218822Sdim 11447218822Sdim case SEC_LINK_DUPLICATES_SAME_SIZE: 11448218822Sdim if (sec->size != l->sec->size) 11449218822Sdim (*_bfd_error_handler) 11450218822Sdim (_("%B: duplicate section `%A' has different size"), 11451218822Sdim abfd, sec); 11452218822Sdim break; 11453218822Sdim 11454218822Sdim case SEC_LINK_DUPLICATES_SAME_CONTENTS: 11455218822Sdim if (sec->size != l->sec->size) 11456218822Sdim (*_bfd_error_handler) 11457218822Sdim (_("%B: duplicate section `%A' has different size"), 11458218822Sdim abfd, sec); 11459218822Sdim else if (sec->size != 0) 11460218822Sdim { 11461218822Sdim bfd_byte *sec_contents, *l_sec_contents; 11462218822Sdim 11463218822Sdim if (!bfd_malloc_and_get_section (abfd, sec, &sec_contents)) 11464218822Sdim (*_bfd_error_handler) 11465218822Sdim (_("%B: warning: could not read contents of section `%A'"), 11466218822Sdim abfd, sec); 11467218822Sdim else if (!bfd_malloc_and_get_section (l->sec->owner, l->sec, 11468218822Sdim &l_sec_contents)) 11469218822Sdim (*_bfd_error_handler) 11470218822Sdim (_("%B: warning: could not read contents of section `%A'"), 11471218822Sdim l->sec->owner, l->sec); 11472218822Sdim else if (memcmp (sec_contents, l_sec_contents, sec->size) != 0) 11473218822Sdim (*_bfd_error_handler) 11474218822Sdim (_("%B: warning: duplicate section `%A' has different contents"), 11475218822Sdim abfd, sec); 11476218822Sdim 11477218822Sdim if (sec_contents) 11478218822Sdim free (sec_contents); 11479218822Sdim if (l_sec_contents) 11480218822Sdim free (l_sec_contents); 11481218822Sdim } 11482218822Sdim break; 11483218822Sdim } 11484218822Sdim 11485218822Sdim /* Set the output_section field so that lang_add_section 11486218822Sdim does not create a lang_input_section structure for this 11487218822Sdim section. Since there might be a symbol in the section 11488218822Sdim being discarded, we must retain a pointer to the section 11489218822Sdim which we are really going to use. */ 11490218822Sdim sec->output_section = bfd_abs_section_ptr; 11491218822Sdim sec->kept_section = l->sec; 11492218822Sdim 11493218822Sdim if (flags & SEC_GROUP) 11494218822Sdim { 11495218822Sdim asection *first = elf_next_in_group (sec); 11496218822Sdim asection *s = first; 11497218822Sdim 11498218822Sdim while (s != NULL) 11499218822Sdim { 11500218822Sdim s->output_section = bfd_abs_section_ptr; 11501218822Sdim /* Record which group discards it. */ 11502218822Sdim s->kept_section = l->sec; 11503218822Sdim s = elf_next_in_group (s); 11504218822Sdim /* These lists are circular. */ 11505218822Sdim if (s == first) 11506218822Sdim break; 11507218822Sdim } 11508218822Sdim } 11509218822Sdim 11510218822Sdim return; 11511218822Sdim } 11512218822Sdim } 11513218822Sdim 11514218822Sdim /* A single member comdat group section may be discarded by a 11515218822Sdim linkonce section and vice versa. */ 11516218822Sdim 11517218822Sdim if ((flags & SEC_GROUP) != 0) 11518218822Sdim { 11519218822Sdim asection *first = elf_next_in_group (sec); 11520218822Sdim 11521218822Sdim if (first != NULL && elf_next_in_group (first) == first) 11522218822Sdim /* Check this single member group against linkonce sections. */ 11523218822Sdim for (l = already_linked_list->entry; l != NULL; l = l->next) 11524218822Sdim if ((l->sec->flags & SEC_GROUP) == 0 11525218822Sdim && bfd_coff_get_comdat_section (l->sec->owner, l->sec) == NULL 11526218822Sdim && bfd_elf_match_symbols_in_sections (l->sec, first, info)) 11527218822Sdim { 11528218822Sdim first->output_section = bfd_abs_section_ptr; 11529218822Sdim first->kept_section = l->sec; 11530218822Sdim sec->output_section = bfd_abs_section_ptr; 11531218822Sdim break; 11532218822Sdim } 11533218822Sdim } 11534218822Sdim else 11535218822Sdim /* Check this linkonce section against single member groups. */ 11536218822Sdim for (l = already_linked_list->entry; l != NULL; l = l->next) 11537218822Sdim if (l->sec->flags & SEC_GROUP) 11538218822Sdim { 11539218822Sdim asection *first = elf_next_in_group (l->sec); 11540218822Sdim 11541218822Sdim if (first != NULL 11542218822Sdim && elf_next_in_group (first) == first 11543218822Sdim && bfd_elf_match_symbols_in_sections (first, sec, info)) 11544218822Sdim { 11545218822Sdim sec->output_section = bfd_abs_section_ptr; 11546218822Sdim sec->kept_section = first; 11547218822Sdim break; 11548218822Sdim } 11549218822Sdim } 11550218822Sdim 11551218822Sdim /* This is the first section with this name. Record it. */ 11552218822Sdim bfd_section_already_linked_table_insert (already_linked_list, sec); 11553218822Sdim} 11554218822Sdim 11555218822Sdimbfd_boolean 11556218822Sdim_bfd_elf_common_definition (Elf_Internal_Sym *sym) 11557218822Sdim{ 11558218822Sdim return sym->st_shndx == SHN_COMMON; 11559218822Sdim} 11560218822Sdim 11561218822Sdimunsigned int 11562218822Sdim_bfd_elf_common_section_index (asection *sec ATTRIBUTE_UNUSED) 11563218822Sdim{ 11564218822Sdim return SHN_COMMON; 11565218822Sdim} 11566218822Sdim 11567218822Sdimasection * 11568218822Sdim_bfd_elf_common_section (asection *sec ATTRIBUTE_UNUSED) 11569218822Sdim{ 11570218822Sdim return bfd_com_section_ptr; 11571218822Sdim} 11572