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 { 4359275386Sdim bfd_boolean looks_soish; 4360275386Sdim const char *print_name; 4361275386Sdim int print_len; 4362275386Sdim size_t len, lend = 0; 4363275386Sdim 4364275386Sdim looks_soish = FALSE; 4365275386Sdim print_name = soname; 4366275386Sdim print_len = strlen(soname); 4367275386Sdim if (strncmp(soname, "lib", 3) == 0) 4368275386Sdim { 4369275386Sdim len = print_len; 4370275386Sdim if (len > 5 && strcmp(soname + len - 2, ".a") == 0) 4371275386Sdim lend = len - 5; 4372275386Sdim else 4373275386Sdim { 4374275386Sdim while (len > 6 && (ISDIGIT(soname[len - 1]) || 4375275386Sdim soname[len - 1] == '.')) 4376275386Sdim len--; 4377275386Sdim if (strncmp(soname + len - 3, ".so", 3) == 0) 4378275386Sdim lend = len - 6; 4379275386Sdim } 4380275386Sdim if (lend != 0) 4381275386Sdim { 4382275386Sdim print_name = soname + 3; 4383275386Sdim print_len = lend; 4384275386Sdim looks_soish = TRUE; 4385275386Sdim } 4386275386Sdim } 4387275386Sdim 4388218822Sdim (*_bfd_error_handler) 4389275386Sdim (_("undefined reference to symbol `%s' (try adding -l%s%.*s)"), 4390275386Sdim name, looks_soish? "" : ":", print_len, print_name); 4391218822Sdim bfd_set_error (bfd_error_bad_value); 4392218822Sdim goto error_free_vers; 4393218822Sdim } 4394218822Sdim 4395218822Sdim elf_dyn_lib_class (abfd) &= ~DYN_AS_NEEDED; 4396218822Sdim 4397130561Sobrien add_needed = TRUE; 4398218822Sdim ret = elf_add_dt_needed_tag (abfd, info, soname, add_needed); 4399130561Sobrien if (ret < 0) 4400130561Sobrien goto error_free_vers; 4401130561Sobrien 4402130561Sobrien BFD_ASSERT (ret == 0); 4403130561Sobrien } 4404130561Sobrien } 4405130561Sobrien } 4406130561Sobrien 4407218822Sdim if (extversym != NULL) 4408218822Sdim { 4409218822Sdim free (extversym); 4410218822Sdim extversym = NULL; 4411218822Sdim } 4412218822Sdim 4413218822Sdim if (isymbuf != NULL) 4414218822Sdim { 4415218822Sdim free (isymbuf); 4416218822Sdim isymbuf = NULL; 4417218822Sdim } 4418218822Sdim 4419218822Sdim if ((elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0) 4420218822Sdim { 4421218822Sdim unsigned int i; 4422218822Sdim 4423218822Sdim /* Restore the symbol table. */ 4424218822Sdim if (bed->as_needed_cleanup) 4425218822Sdim (*bed->as_needed_cleanup) (abfd, info); 4426218822Sdim old_hash = (char *) old_tab + tabsize; 4427218822Sdim old_ent = (char *) old_hash + hashsize; 4428218822Sdim sym_hash = elf_sym_hashes (abfd); 4429218822Sdim htab->root.table.table = old_table; 4430218822Sdim htab->root.table.size = old_size; 4431218822Sdim htab->root.table.count = old_count; 4432218822Sdim memcpy (htab->root.table.table, old_tab, tabsize); 4433218822Sdim memcpy (sym_hash, old_hash, hashsize); 4434218822Sdim htab->root.undefs = old_undefs; 4435218822Sdim htab->root.undefs_tail = old_undefs_tail; 4436218822Sdim for (i = 0; i < htab->root.table.size; i++) 4437218822Sdim { 4438218822Sdim struct bfd_hash_entry *p; 4439218822Sdim struct elf_link_hash_entry *h; 4440218822Sdim 4441218822Sdim for (p = htab->root.table.table[i]; p != NULL; p = p->next) 4442218822Sdim { 4443218822Sdim h = (struct elf_link_hash_entry *) p; 4444218822Sdim if (h->root.type == bfd_link_hash_warning) 4445218822Sdim h = (struct elf_link_hash_entry *) h->root.u.i.link; 4446218822Sdim if (h->dynindx >= old_dynsymcount) 4447218822Sdim _bfd_elf_strtab_delref (htab->dynstr, h->dynstr_index); 4448218822Sdim 4449218822Sdim memcpy (p, old_ent, htab->root.table.entsize); 4450218822Sdim old_ent = (char *) old_ent + htab->root.table.entsize; 4451218822Sdim h = (struct elf_link_hash_entry *) p; 4452218822Sdim if (h->root.type == bfd_link_hash_warning) 4453218822Sdim { 4454218822Sdim memcpy (h->root.u.i.link, old_ent, htab->root.table.entsize); 4455218822Sdim old_ent = (char *) old_ent + htab->root.table.entsize; 4456218822Sdim } 4457218822Sdim } 4458218822Sdim } 4459218822Sdim 4460218822Sdim /* Make a special call to the linker "notice" function to 4461218822Sdim tell it that symbols added for crefs may need to be removed. */ 4462218822Sdim if (!(*info->callbacks->notice) (info, NULL, abfd, NULL, 4463218822Sdim notice_not_needed)) 4464218822Sdim return FALSE; 4465218822Sdim 4466218822Sdim free (old_tab); 4467218822Sdim objalloc_free_block ((struct objalloc *) htab->root.table.memory, 4468218822Sdim alloc_mark); 4469218822Sdim if (nondeflt_vers != NULL) 4470218822Sdim free (nondeflt_vers); 4471218822Sdim return TRUE; 4472218822Sdim } 4473218822Sdim 4474218822Sdim if (old_tab != NULL) 4475218822Sdim { 4476218822Sdim if (!(*info->callbacks->notice) (info, NULL, abfd, NULL, 4477218822Sdim notice_needed)) 4478218822Sdim return FALSE; 4479218822Sdim free (old_tab); 4480218822Sdim old_tab = NULL; 4481218822Sdim } 4482218822Sdim 4483130561Sobrien /* Now that all the symbols from this input file are created, handle 4484130561Sobrien .symver foo, foo@BAR such that any relocs against foo become foo@BAR. */ 4485130561Sobrien if (nondeflt_vers != NULL) 4486130561Sobrien { 4487130561Sobrien bfd_size_type cnt, symidx; 4488130561Sobrien 4489130561Sobrien for (cnt = 0; cnt < nondeflt_vers_cnt; ++cnt) 4490130561Sobrien { 4491130561Sobrien struct elf_link_hash_entry *h = nondeflt_vers[cnt], *hi; 4492130561Sobrien char *shortname, *p; 4493130561Sobrien 4494130561Sobrien p = strchr (h->root.root.string, ELF_VER_CHR); 4495130561Sobrien if (p == NULL 4496130561Sobrien || (h->root.type != bfd_link_hash_defined 4497130561Sobrien && h->root.type != bfd_link_hash_defweak)) 4498130561Sobrien continue; 4499130561Sobrien 4500130561Sobrien amt = p - h->root.root.string; 4501130561Sobrien shortname = bfd_malloc (amt + 1); 4502130561Sobrien memcpy (shortname, h->root.root.string, amt); 4503130561Sobrien shortname[amt] = '\0'; 4504130561Sobrien 4505130561Sobrien hi = (struct elf_link_hash_entry *) 4506218822Sdim bfd_link_hash_lookup (&htab->root, shortname, 4507130561Sobrien FALSE, FALSE, FALSE); 4508130561Sobrien if (hi != NULL 4509130561Sobrien && hi->root.type == h->root.type 4510130561Sobrien && hi->root.u.def.value == h->root.u.def.value 4511130561Sobrien && hi->root.u.def.section == h->root.u.def.section) 4512130561Sobrien { 4513130561Sobrien (*bed->elf_backend_hide_symbol) (info, hi, TRUE); 4514130561Sobrien hi->root.type = bfd_link_hash_indirect; 4515130561Sobrien hi->root.u.i.link = (struct bfd_link_hash_entry *) h; 4516218822Sdim (*bed->elf_backend_copy_indirect_symbol) (info, h, hi); 4517130561Sobrien sym_hash = elf_sym_hashes (abfd); 4518130561Sobrien if (sym_hash) 4519130561Sobrien for (symidx = 0; symidx < extsymcount; ++symidx) 4520130561Sobrien if (sym_hash[symidx] == hi) 4521130561Sobrien { 4522130561Sobrien sym_hash[symidx] = h; 4523130561Sobrien break; 4524130561Sobrien } 4525130561Sobrien } 4526130561Sobrien free (shortname); 4527130561Sobrien } 4528130561Sobrien free (nondeflt_vers); 4529130561Sobrien nondeflt_vers = NULL; 4530130561Sobrien } 4531130561Sobrien 4532130561Sobrien /* Now set the weakdefs field correctly for all the weak defined 4533130561Sobrien symbols we found. The only way to do this is to search all the 4534130561Sobrien symbols. Since we only need the information for non functions in 4535130561Sobrien dynamic objects, that's the only time we actually put anything on 4536130561Sobrien the list WEAKS. We need this information so that if a regular 4537130561Sobrien object refers to a symbol defined weakly in a dynamic object, the 4538130561Sobrien real symbol in the dynamic object is also put in the dynamic 4539130561Sobrien symbols; we also must arrange for both symbols to point to the 4540130561Sobrien same memory location. We could handle the general case of symbol 4541130561Sobrien aliasing, but a general symbol alias can only be generated in 4542130561Sobrien assembler code, handling it correctly would be very time 4543130561Sobrien consuming, and other ELF linkers don't handle general aliasing 4544130561Sobrien either. */ 4545130561Sobrien if (weaks != NULL) 4546130561Sobrien { 4547130561Sobrien struct elf_link_hash_entry **hpp; 4548130561Sobrien struct elf_link_hash_entry **hppend; 4549130561Sobrien struct elf_link_hash_entry **sorted_sym_hash; 4550130561Sobrien struct elf_link_hash_entry *h; 4551130561Sobrien size_t sym_count; 4552130561Sobrien 4553130561Sobrien /* Since we have to search the whole symbol list for each weak 4554130561Sobrien defined symbol, search time for N weak defined symbols will be 4555130561Sobrien O(N^2). Binary search will cut it down to O(NlogN). */ 4556130561Sobrien amt = extsymcount * sizeof (struct elf_link_hash_entry *); 4557130561Sobrien sorted_sym_hash = bfd_malloc (amt); 4558130561Sobrien if (sorted_sym_hash == NULL) 4559130561Sobrien goto error_return; 4560130561Sobrien sym_hash = sorted_sym_hash; 4561130561Sobrien hpp = elf_sym_hashes (abfd); 4562130561Sobrien hppend = hpp + extsymcount; 4563130561Sobrien sym_count = 0; 4564130561Sobrien for (; hpp < hppend; hpp++) 4565130561Sobrien { 4566130561Sobrien h = *hpp; 4567130561Sobrien if (h != NULL 4568130561Sobrien && h->root.type == bfd_link_hash_defined 4569218822Sdim && !bed->is_function_type (h->type)) 4570130561Sobrien { 4571130561Sobrien *sym_hash = h; 4572130561Sobrien sym_hash++; 4573130561Sobrien sym_count++; 4574130561Sobrien } 4575130561Sobrien } 4576130561Sobrien 4577130561Sobrien qsort (sorted_sym_hash, sym_count, 4578130561Sobrien sizeof (struct elf_link_hash_entry *), 4579130561Sobrien elf_sort_symbol); 4580130561Sobrien 4581130561Sobrien while (weaks != NULL) 4582130561Sobrien { 4583130561Sobrien struct elf_link_hash_entry *hlook; 4584130561Sobrien asection *slook; 4585130561Sobrien bfd_vma vlook; 4586130561Sobrien long ilook; 4587130561Sobrien size_t i, j, idx; 4588130561Sobrien 4589130561Sobrien hlook = weaks; 4590218822Sdim weaks = hlook->u.weakdef; 4591218822Sdim hlook->u.weakdef = NULL; 4592130561Sobrien 4593130561Sobrien BFD_ASSERT (hlook->root.type == bfd_link_hash_defined 4594130561Sobrien || hlook->root.type == bfd_link_hash_defweak 4595130561Sobrien || hlook->root.type == bfd_link_hash_common 4596130561Sobrien || hlook->root.type == bfd_link_hash_indirect); 4597130561Sobrien slook = hlook->root.u.def.section; 4598130561Sobrien vlook = hlook->root.u.def.value; 4599130561Sobrien 4600130561Sobrien ilook = -1; 4601130561Sobrien i = 0; 4602130561Sobrien j = sym_count; 4603130561Sobrien while (i < j) 4604130561Sobrien { 4605130561Sobrien bfd_signed_vma vdiff; 4606130561Sobrien idx = (i + j) / 2; 4607130561Sobrien h = sorted_sym_hash [idx]; 4608130561Sobrien vdiff = vlook - h->root.u.def.value; 4609130561Sobrien if (vdiff < 0) 4610130561Sobrien j = idx; 4611130561Sobrien else if (vdiff > 0) 4612130561Sobrien i = idx + 1; 4613130561Sobrien else 4614130561Sobrien { 4615218822Sdim long sdiff = slook->id - h->root.u.def.section->id; 4616130561Sobrien if (sdiff < 0) 4617130561Sobrien j = idx; 4618130561Sobrien else if (sdiff > 0) 4619130561Sobrien i = idx + 1; 4620130561Sobrien else 4621130561Sobrien { 4622130561Sobrien ilook = idx; 4623130561Sobrien break; 4624130561Sobrien } 4625130561Sobrien } 4626130561Sobrien } 4627130561Sobrien 4628130561Sobrien /* We didn't find a value/section match. */ 4629130561Sobrien if (ilook == -1) 4630130561Sobrien continue; 4631130561Sobrien 4632130561Sobrien for (i = ilook; i < sym_count; i++) 4633130561Sobrien { 4634130561Sobrien h = sorted_sym_hash [i]; 4635130561Sobrien 4636130561Sobrien /* Stop if value or section doesn't match. */ 4637130561Sobrien if (h->root.u.def.value != vlook 4638130561Sobrien || h->root.u.def.section != slook) 4639130561Sobrien break; 4640130561Sobrien else if (h != hlook) 4641130561Sobrien { 4642218822Sdim hlook->u.weakdef = h; 4643130561Sobrien 4644130561Sobrien /* If the weak definition is in the list of dynamic 4645130561Sobrien symbols, make sure the real definition is put 4646130561Sobrien there as well. */ 4647130561Sobrien if (hlook->dynindx != -1 && h->dynindx == -1) 4648130561Sobrien { 4649130561Sobrien if (! bfd_elf_link_record_dynamic_symbol (info, h)) 4650130561Sobrien goto error_return; 4651130561Sobrien } 4652130561Sobrien 4653130561Sobrien /* If the real definition is in the list of dynamic 4654130561Sobrien symbols, make sure the weak definition is put 4655130561Sobrien there as well. If we don't do this, then the 4656130561Sobrien dynamic loader might not merge the entries for the 4657130561Sobrien real definition and the weak definition. */ 4658130561Sobrien if (h->dynindx != -1 && hlook->dynindx == -1) 4659130561Sobrien { 4660130561Sobrien if (! bfd_elf_link_record_dynamic_symbol (info, hlook)) 4661130561Sobrien goto error_return; 4662130561Sobrien } 4663130561Sobrien break; 4664130561Sobrien } 4665130561Sobrien } 4666130561Sobrien } 4667130561Sobrien 4668130561Sobrien free (sorted_sym_hash); 4669130561Sobrien } 4670130561Sobrien 4671218822Sdim if (bed->check_directives) 4672218822Sdim (*bed->check_directives) (abfd, info); 4673218822Sdim 4674130561Sobrien /* If this object is the same format as the output object, and it is 4675130561Sobrien not a shared library, then let the backend look through the 4676130561Sobrien relocs. 4677130561Sobrien 4678130561Sobrien This is required to build global offset table entries and to 4679130561Sobrien arrange for dynamic relocs. It is not required for the 4680130561Sobrien particular common case of linking non PIC code, even when linking 4681130561Sobrien against shared libraries, but unfortunately there is no way of 4682130561Sobrien knowing whether an object file has been compiled PIC or not. 4683130561Sobrien Looking through the relocs is not particularly time consuming. 4684130561Sobrien The problem is that we must either (1) keep the relocs in memory, 4685130561Sobrien which causes the linker to require additional runtime memory or 4686130561Sobrien (2) read the relocs twice from the input file, which wastes time. 4687130561Sobrien This would be a good case for using mmap. 4688130561Sobrien 4689130561Sobrien I have no idea how to handle linking PIC code into a file of a 4690130561Sobrien different format. It probably can't be done. */ 4691130561Sobrien if (! dynamic 4692218822Sdim && is_elf_hash_table (htab) 4693218822Sdim && bed->check_relocs != NULL 4694218822Sdim && (*bed->relocs_compatible) (abfd->xvec, htab->root.creator)) 4695130561Sobrien { 4696130561Sobrien asection *o; 4697130561Sobrien 4698130561Sobrien for (o = abfd->sections; o != NULL; o = o->next) 4699130561Sobrien { 4700130561Sobrien Elf_Internal_Rela *internal_relocs; 4701130561Sobrien bfd_boolean ok; 4702130561Sobrien 4703130561Sobrien if ((o->flags & SEC_RELOC) == 0 4704130561Sobrien || o->reloc_count == 0 4705130561Sobrien || ((info->strip == strip_all || info->strip == strip_debugger) 4706130561Sobrien && (o->flags & SEC_DEBUGGING) != 0) 4707130561Sobrien || bfd_is_abs_section (o->output_section)) 4708130561Sobrien continue; 4709130561Sobrien 4710130561Sobrien internal_relocs = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, 4711130561Sobrien info->keep_memory); 4712130561Sobrien if (internal_relocs == NULL) 4713130561Sobrien goto error_return; 4714130561Sobrien 4715218822Sdim ok = (*bed->check_relocs) (abfd, info, o, internal_relocs); 4716130561Sobrien 4717130561Sobrien if (elf_section_data (o)->relocs != internal_relocs) 4718130561Sobrien free (internal_relocs); 4719130561Sobrien 4720130561Sobrien if (! ok) 4721130561Sobrien goto error_return; 4722130561Sobrien } 4723130561Sobrien } 4724130561Sobrien 4725130561Sobrien /* If this is a non-traditional link, try to optimize the handling 4726130561Sobrien of the .stab/.stabstr sections. */ 4727130561Sobrien if (! dynamic 4728130561Sobrien && ! info->traditional_format 4729218822Sdim && is_elf_hash_table (htab) 4730130561Sobrien && (info->strip != strip_all && info->strip != strip_debugger)) 4731130561Sobrien { 4732130561Sobrien asection *stabstr; 4733130561Sobrien 4734130561Sobrien stabstr = bfd_get_section_by_name (abfd, ".stabstr"); 4735130561Sobrien if (stabstr != NULL) 4736130561Sobrien { 4737130561Sobrien bfd_size_type string_offset = 0; 4738130561Sobrien asection *stab; 4739130561Sobrien 4740130561Sobrien for (stab = abfd->sections; stab; stab = stab->next) 4741218822Sdim if (CONST_STRNEQ (stab->name, ".stab") 4742130561Sobrien && (!stab->name[5] || 4743130561Sobrien (stab->name[5] == '.' && ISDIGIT (stab->name[6]))) 4744130561Sobrien && (stab->flags & SEC_MERGE) == 0 4745130561Sobrien && !bfd_is_abs_section (stab->output_section)) 4746130561Sobrien { 4747130561Sobrien struct bfd_elf_section_data *secdata; 4748130561Sobrien 4749130561Sobrien secdata = elf_section_data (stab); 4750218822Sdim if (! _bfd_link_section_stabs (abfd, &htab->stab_info, stab, 4751218822Sdim stabstr, &secdata->sec_info, 4752130561Sobrien &string_offset)) 4753130561Sobrien goto error_return; 4754130561Sobrien if (secdata->sec_info) 4755130561Sobrien stab->sec_info_type = ELF_INFO_TYPE_STABS; 4756130561Sobrien } 4757130561Sobrien } 4758130561Sobrien } 4759130561Sobrien 4760218822Sdim if (is_elf_hash_table (htab) && add_needed) 4761130561Sobrien { 4762130561Sobrien /* Add this bfd to the loaded list. */ 4763130561Sobrien struct elf_link_loaded_list *n; 4764130561Sobrien 4765130561Sobrien n = bfd_alloc (abfd, sizeof (struct elf_link_loaded_list)); 4766130561Sobrien if (n == NULL) 4767130561Sobrien goto error_return; 4768130561Sobrien n->abfd = abfd; 4769218822Sdim n->next = htab->loaded; 4770218822Sdim htab->loaded = n; 4771130561Sobrien } 4772130561Sobrien 4773130561Sobrien return TRUE; 4774130561Sobrien 4775130561Sobrien error_free_vers: 4776218822Sdim if (old_tab != NULL) 4777218822Sdim free (old_tab); 4778130561Sobrien if (nondeflt_vers != NULL) 4779130561Sobrien free (nondeflt_vers); 4780130561Sobrien if (extversym != NULL) 4781130561Sobrien free (extversym); 4782130561Sobrien error_free_sym: 4783130561Sobrien if (isymbuf != NULL) 4784130561Sobrien free (isymbuf); 4785130561Sobrien error_return: 4786130561Sobrien return FALSE; 4787130561Sobrien} 4788130561Sobrien 4789218822Sdim/* Return the linker hash table entry of a symbol that might be 4790218822Sdim satisfied by an archive symbol. Return -1 on error. */ 4791218822Sdim 4792218822Sdimstruct elf_link_hash_entry * 4793218822Sdim_bfd_elf_archive_symbol_lookup (bfd *abfd, 4794218822Sdim struct bfd_link_info *info, 4795218822Sdim const char *name) 4796218822Sdim{ 4797218822Sdim struct elf_link_hash_entry *h; 4798218822Sdim char *p, *copy; 4799218822Sdim size_t len, first; 4800218822Sdim 4801218822Sdim h = elf_link_hash_lookup (elf_hash_table (info), name, FALSE, FALSE, FALSE); 4802218822Sdim if (h != NULL) 4803218822Sdim return h; 4804218822Sdim 4805218822Sdim /* If this is a default version (the name contains @@), look up the 4806218822Sdim symbol again with only one `@' as well as without the version. 4807218822Sdim The effect is that references to the symbol with and without the 4808218822Sdim version will be matched by the default symbol in the archive. */ 4809218822Sdim 4810218822Sdim p = strchr (name, ELF_VER_CHR); 4811218822Sdim if (p == NULL || p[1] != ELF_VER_CHR) 4812218822Sdim return h; 4813218822Sdim 4814218822Sdim /* First check with only one `@'. */ 4815218822Sdim len = strlen (name); 4816218822Sdim copy = bfd_alloc (abfd, len); 4817218822Sdim if (copy == NULL) 4818327471Sdim return (struct elf_link_hash_entry *)(intptr_t)-1; 4819218822Sdim 4820218822Sdim first = p - name + 1; 4821218822Sdim memcpy (copy, name, first); 4822218822Sdim memcpy (copy + first, name + first + 1, len - first); 4823218822Sdim 4824218822Sdim h = elf_link_hash_lookup (elf_hash_table (info), copy, FALSE, FALSE, FALSE); 4825218822Sdim if (h == NULL) 4826218822Sdim { 4827218822Sdim /* We also need to check references to the symbol without the 4828218822Sdim version. */ 4829218822Sdim copy[first - 1] = '\0'; 4830218822Sdim h = elf_link_hash_lookup (elf_hash_table (info), copy, 4831218822Sdim FALSE, FALSE, FALSE); 4832218822Sdim } 4833218822Sdim 4834218822Sdim bfd_release (abfd, copy); 4835218822Sdim return h; 4836218822Sdim} 4837218822Sdim 4838130561Sobrien/* Add symbols from an ELF archive file to the linker hash table. We 4839130561Sobrien don't use _bfd_generic_link_add_archive_symbols because of a 4840130561Sobrien problem which arises on UnixWare. The UnixWare libc.so is an 4841130561Sobrien archive which includes an entry libc.so.1 which defines a bunch of 4842130561Sobrien symbols. The libc.so archive also includes a number of other 4843130561Sobrien object files, which also define symbols, some of which are the same 4844130561Sobrien as those defined in libc.so.1. Correct linking requires that we 4845130561Sobrien consider each object file in turn, and include it if it defines any 4846130561Sobrien symbols we need. _bfd_generic_link_add_archive_symbols does not do 4847130561Sobrien this; it looks through the list of undefined symbols, and includes 4848130561Sobrien any object file which defines them. When this algorithm is used on 4849130561Sobrien UnixWare, it winds up pulling in libc.so.1 early and defining a 4850130561Sobrien bunch of symbols. This means that some of the other objects in the 4851130561Sobrien archive are not included in the link, which is incorrect since they 4852130561Sobrien precede libc.so.1 in the archive. 4853130561Sobrien 4854130561Sobrien Fortunately, ELF archive handling is simpler than that done by 4855130561Sobrien _bfd_generic_link_add_archive_symbols, which has to allow for a.out 4856130561Sobrien oddities. In ELF, if we find a symbol in the archive map, and the 4857130561Sobrien symbol is currently undefined, we know that we must pull in that 4858130561Sobrien object file. 4859130561Sobrien 4860130561Sobrien Unfortunately, we do have to make multiple passes over the symbol 4861130561Sobrien table until nothing further is resolved. */ 4862130561Sobrien 4863130561Sobrienstatic bfd_boolean 4864130561Sobrienelf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) 4865130561Sobrien{ 4866130561Sobrien symindex c; 4867130561Sobrien bfd_boolean *defined = NULL; 4868130561Sobrien bfd_boolean *included = NULL; 4869130561Sobrien carsym *symdefs; 4870130561Sobrien bfd_boolean loop; 4871130561Sobrien bfd_size_type amt; 4872218822Sdim const struct elf_backend_data *bed; 4873218822Sdim struct elf_link_hash_entry * (*archive_symbol_lookup) 4874218822Sdim (bfd *, struct bfd_link_info *, const char *); 4875130561Sobrien 4876130561Sobrien if (! bfd_has_map (abfd)) 4877130561Sobrien { 4878130561Sobrien /* An empty archive is a special case. */ 4879130561Sobrien if (bfd_openr_next_archived_file (abfd, NULL) == NULL) 4880130561Sobrien return TRUE; 4881130561Sobrien bfd_set_error (bfd_error_no_armap); 4882130561Sobrien return FALSE; 4883130561Sobrien } 4884130561Sobrien 4885130561Sobrien /* Keep track of all symbols we know to be already defined, and all 4886130561Sobrien files we know to be already included. This is to speed up the 4887130561Sobrien second and subsequent passes. */ 4888130561Sobrien c = bfd_ardata (abfd)->symdef_count; 4889130561Sobrien if (c == 0) 4890130561Sobrien return TRUE; 4891130561Sobrien amt = c; 4892130561Sobrien amt *= sizeof (bfd_boolean); 4893130561Sobrien defined = bfd_zmalloc (amt); 4894130561Sobrien included = bfd_zmalloc (amt); 4895130561Sobrien if (defined == NULL || included == NULL) 4896130561Sobrien goto error_return; 4897130561Sobrien 4898130561Sobrien symdefs = bfd_ardata (abfd)->symdefs; 4899218822Sdim bed = get_elf_backend_data (abfd); 4900218822Sdim archive_symbol_lookup = bed->elf_backend_archive_symbol_lookup; 4901130561Sobrien 4902130561Sobrien do 4903130561Sobrien { 4904130561Sobrien file_ptr last; 4905130561Sobrien symindex i; 4906130561Sobrien carsym *symdef; 4907130561Sobrien carsym *symdefend; 4908130561Sobrien 4909130561Sobrien loop = FALSE; 4910130561Sobrien last = -1; 4911130561Sobrien 4912130561Sobrien symdef = symdefs; 4913130561Sobrien symdefend = symdef + c; 4914130561Sobrien for (i = 0; symdef < symdefend; symdef++, i++) 4915130561Sobrien { 4916107492Sobrien struct elf_link_hash_entry *h; 4917130561Sobrien bfd *element; 4918130561Sobrien struct bfd_link_hash_entry *undefs_tail; 4919130561Sobrien symindex mark; 4920107492Sobrien 4921130561Sobrien if (defined[i] || included[i]) 4922130561Sobrien continue; 4923130561Sobrien if (symdef->file_offset == last) 4924130561Sobrien { 4925130561Sobrien included[i] = TRUE; 4926130561Sobrien continue; 4927130561Sobrien } 492833965Sjdp 4929218822Sdim h = archive_symbol_lookup (abfd, info, symdef->name); 4930327471Sdim if (h == (struct elf_link_hash_entry *)(intptr_t)-1) 4931218822Sdim goto error_return; 493233965Sjdp 4933130561Sobrien if (h == NULL) 4934130561Sobrien continue; 4935130561Sobrien 4936130561Sobrien if (h->root.type == bfd_link_hash_common) 4937130561Sobrien { 4938130561Sobrien /* We currently have a common symbol. The archive map contains 4939130561Sobrien a reference to this symbol, so we may want to include it. We 4940130561Sobrien only want to include it however, if this archive element 4941130561Sobrien contains a definition of the symbol, not just another common 4942130561Sobrien declaration of it. 4943130561Sobrien 4944130561Sobrien Unfortunately some archivers (including GNU ar) will put 4945130561Sobrien declarations of common symbols into their archive maps, as 4946130561Sobrien well as real definitions, so we cannot just go by the archive 4947130561Sobrien map alone. Instead we must read in the element's symbol 4948130561Sobrien table and check that to see what kind of symbol definition 4949130561Sobrien this is. */ 4950130561Sobrien if (! elf_link_is_defined_archive_symbol (abfd, symdef)) 4951130561Sobrien continue; 4952130561Sobrien } 4953130561Sobrien else if (h->root.type != bfd_link_hash_undefined) 4954130561Sobrien { 4955130561Sobrien if (h->root.type != bfd_link_hash_undefweak) 4956130561Sobrien defined[i] = TRUE; 4957130561Sobrien continue; 4958130561Sobrien } 4959130561Sobrien 4960130561Sobrien /* We need to include this archive member. */ 4961130561Sobrien element = _bfd_get_elt_at_filepos (abfd, symdef->file_offset); 4962130561Sobrien if (element == NULL) 4963130561Sobrien goto error_return; 4964130561Sobrien 4965130561Sobrien if (! bfd_check_format (element, bfd_object)) 4966130561Sobrien goto error_return; 4967130561Sobrien 4968130561Sobrien /* Doublecheck that we have not included this object 4969130561Sobrien already--it should be impossible, but there may be 4970130561Sobrien something wrong with the archive. */ 4971130561Sobrien if (element->archive_pass != 0) 4972130561Sobrien { 4973130561Sobrien bfd_set_error (bfd_error_bad_value); 4974130561Sobrien goto error_return; 4975130561Sobrien } 4976130561Sobrien element->archive_pass = 1; 4977130561Sobrien 4978130561Sobrien undefs_tail = info->hash->undefs_tail; 4979130561Sobrien 4980130561Sobrien if (! (*info->callbacks->add_archive_element) (info, element, 4981130561Sobrien symdef->name)) 4982130561Sobrien goto error_return; 4983130561Sobrien if (! bfd_link_add_symbols (element, info)) 4984130561Sobrien goto error_return; 4985130561Sobrien 4986130561Sobrien /* If there are any new undefined symbols, we need to make 4987130561Sobrien another pass through the archive in order to see whether 4988130561Sobrien they can be defined. FIXME: This isn't perfect, because 4989130561Sobrien common symbols wind up on undefs_tail and because an 4990130561Sobrien undefined symbol which is defined later on in this pass 4991130561Sobrien does not require another pass. This isn't a bug, but it 4992130561Sobrien does make the code less efficient than it could be. */ 4993130561Sobrien if (undefs_tail != info->hash->undefs_tail) 4994130561Sobrien loop = TRUE; 4995130561Sobrien 4996130561Sobrien /* Look backward to mark all symbols from this object file 4997130561Sobrien which we have already seen in this pass. */ 4998130561Sobrien mark = i; 4999130561Sobrien do 5000130561Sobrien { 5001130561Sobrien included[mark] = TRUE; 5002130561Sobrien if (mark == 0) 5003130561Sobrien break; 5004130561Sobrien --mark; 5005130561Sobrien } 5006130561Sobrien while (symdefs[mark].file_offset == symdef->file_offset); 5007130561Sobrien 5008130561Sobrien /* We mark subsequent symbols from this object file as we go 5009130561Sobrien on through the loop. */ 5010130561Sobrien last = symdef->file_offset; 501133965Sjdp } 501233965Sjdp } 5013130561Sobrien while (loop); 501433965Sjdp 5015130561Sobrien free (defined); 5016130561Sobrien free (included); 501733965Sjdp 5018130561Sobrien return TRUE; 501933965Sjdp 5020130561Sobrien error_return: 5021130561Sobrien if (defined != NULL) 5022130561Sobrien free (defined); 5023130561Sobrien if (included != NULL) 5024130561Sobrien free (included); 5025130561Sobrien return FALSE; 5026130561Sobrien} 5027130561Sobrien 5028130561Sobrien/* Given an ELF BFD, add symbols to the global hash table as 5029130561Sobrien appropriate. */ 5030130561Sobrien 5031130561Sobrienbfd_boolean 5032130561Sobrienbfd_elf_link_add_symbols (bfd *abfd, struct bfd_link_info *info) 5033130561Sobrien{ 5034130561Sobrien switch (bfd_get_format (abfd)) 5035130561Sobrien { 5036130561Sobrien case bfd_object: 5037130561Sobrien return elf_link_add_object_symbols (abfd, info); 5038130561Sobrien case bfd_archive: 5039130561Sobrien return elf_link_add_archive_symbols (abfd, info); 5040130561Sobrien default: 5041130561Sobrien bfd_set_error (bfd_error_wrong_format); 5042130561Sobrien return FALSE; 5043130561Sobrien } 5044130561Sobrien} 5045130561Sobrien 5046130561Sobrien/* This function will be called though elf_link_hash_traverse to store 5047130561Sobrien all hash value of the exported symbols in an array. */ 5048130561Sobrien 5049130561Sobrienstatic bfd_boolean 5050130561Sobrienelf_collect_hash_codes (struct elf_link_hash_entry *h, void *data) 5051130561Sobrien{ 5052130561Sobrien unsigned long **valuep = data; 5053130561Sobrien const char *name; 5054130561Sobrien char *p; 5055130561Sobrien unsigned long ha; 5056130561Sobrien char *alc = NULL; 5057130561Sobrien 5058130561Sobrien if (h->root.type == bfd_link_hash_warning) 5059130561Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 5060130561Sobrien 5061130561Sobrien /* Ignore indirect symbols. These are added by the versioning code. */ 5062130561Sobrien if (h->dynindx == -1) 5063130561Sobrien return TRUE; 5064130561Sobrien 5065130561Sobrien name = h->root.root.string; 5066130561Sobrien p = strchr (name, ELF_VER_CHR); 5067130561Sobrien if (p != NULL) 5068130561Sobrien { 5069130561Sobrien alc = bfd_malloc (p - name + 1); 5070130561Sobrien memcpy (alc, name, p - name); 5071130561Sobrien alc[p - name] = '\0'; 5072130561Sobrien name = alc; 5073130561Sobrien } 5074130561Sobrien 5075130561Sobrien /* Compute the hash value. */ 5076130561Sobrien ha = bfd_elf_hash (name); 5077130561Sobrien 5078130561Sobrien /* Store the found hash value in the array given as the argument. */ 5079130561Sobrien *(*valuep)++ = ha; 5080130561Sobrien 5081130561Sobrien /* And store it in the struct so that we can put it in the hash table 5082130561Sobrien later. */ 5083218822Sdim h->u.elf_hash_value = ha; 5084130561Sobrien 5085130561Sobrien if (alc != NULL) 5086130561Sobrien free (alc); 5087130561Sobrien 5088130561Sobrien return TRUE; 5089130561Sobrien} 5090130561Sobrien 5091218822Sdimstruct collect_gnu_hash_codes 5092218822Sdim{ 5093218822Sdim bfd *output_bfd; 5094218822Sdim const struct elf_backend_data *bed; 5095218822Sdim unsigned long int nsyms; 5096218822Sdim unsigned long int maskbits; 5097218822Sdim unsigned long int *hashcodes; 5098218822Sdim unsigned long int *hashval; 5099218822Sdim unsigned long int *indx; 5100218822Sdim unsigned long int *counts; 5101218822Sdim bfd_vma *bitmask; 5102218822Sdim bfd_byte *contents; 5103218822Sdim long int min_dynindx; 5104218822Sdim unsigned long int bucketcount; 5105218822Sdim unsigned long int symindx; 5106218822Sdim long int local_indx; 5107218822Sdim long int shift1, shift2; 5108218822Sdim unsigned long int mask; 5109218822Sdim}; 5110218822Sdim 5111218822Sdim/* This function will be called though elf_link_hash_traverse to store 5112218822Sdim all hash value of the exported symbols in an array. */ 5113218822Sdim 5114218822Sdimstatic bfd_boolean 5115218822Sdimelf_collect_gnu_hash_codes (struct elf_link_hash_entry *h, void *data) 5116218822Sdim{ 5117218822Sdim struct collect_gnu_hash_codes *s = data; 5118218822Sdim const char *name; 5119218822Sdim char *p; 5120218822Sdim unsigned long ha; 5121218822Sdim char *alc = NULL; 5122218822Sdim 5123218822Sdim if (h->root.type == bfd_link_hash_warning) 5124218822Sdim h = (struct elf_link_hash_entry *) h->root.u.i.link; 5125218822Sdim 5126218822Sdim /* Ignore indirect symbols. These are added by the versioning code. */ 5127218822Sdim if (h->dynindx == -1) 5128218822Sdim return TRUE; 5129218822Sdim 5130218822Sdim /* Ignore also local symbols and undefined symbols. */ 5131218822Sdim if (! (*s->bed->elf_hash_symbol) (h)) 5132218822Sdim return TRUE; 5133218822Sdim 5134218822Sdim name = h->root.root.string; 5135218822Sdim p = strchr (name, ELF_VER_CHR); 5136218822Sdim if (p != NULL) 5137218822Sdim { 5138218822Sdim alc = bfd_malloc (p - name + 1); 5139218822Sdim memcpy (alc, name, p - name); 5140218822Sdim alc[p - name] = '\0'; 5141218822Sdim name = alc; 5142218822Sdim } 5143218822Sdim 5144218822Sdim /* Compute the hash value. */ 5145218822Sdim ha = bfd_elf_gnu_hash (name); 5146218822Sdim 5147218822Sdim /* Store the found hash value in the array for compute_bucket_count, 5148218822Sdim and also for .dynsym reordering purposes. */ 5149218822Sdim s->hashcodes[s->nsyms] = ha; 5150218822Sdim s->hashval[h->dynindx] = ha; 5151218822Sdim ++s->nsyms; 5152218822Sdim if (s->min_dynindx < 0 || s->min_dynindx > h->dynindx) 5153218822Sdim s->min_dynindx = h->dynindx; 5154218822Sdim 5155218822Sdim if (alc != NULL) 5156218822Sdim free (alc); 5157218822Sdim 5158218822Sdim return TRUE; 5159218822Sdim} 5160218822Sdim 5161218822Sdim/* This function will be called though elf_link_hash_traverse to do 5162218822Sdim final dynaminc symbol renumbering. */ 5163218822Sdim 5164218822Sdimstatic bfd_boolean 5165218822Sdimelf_renumber_gnu_hash_syms (struct elf_link_hash_entry *h, void *data) 5166218822Sdim{ 5167218822Sdim struct collect_gnu_hash_codes *s = data; 5168218822Sdim unsigned long int bucket; 5169218822Sdim unsigned long int val; 5170218822Sdim 5171218822Sdim if (h->root.type == bfd_link_hash_warning) 5172218822Sdim h = (struct elf_link_hash_entry *) h->root.u.i.link; 5173218822Sdim 5174218822Sdim /* Ignore indirect symbols. */ 5175218822Sdim if (h->dynindx == -1) 5176218822Sdim return TRUE; 5177218822Sdim 5178218822Sdim /* Ignore also local symbols and undefined symbols. */ 5179218822Sdim if (! (*s->bed->elf_hash_symbol) (h)) 5180218822Sdim { 5181218822Sdim if (h->dynindx >= s->min_dynindx) 5182218822Sdim h->dynindx = s->local_indx++; 5183218822Sdim return TRUE; 5184218822Sdim } 5185218822Sdim 5186218822Sdim bucket = s->hashval[h->dynindx] % s->bucketcount; 5187218822Sdim val = (s->hashval[h->dynindx] >> s->shift1) 5188218822Sdim & ((s->maskbits >> s->shift1) - 1); 5189218822Sdim s->bitmask[val] |= ((bfd_vma) 1) << (s->hashval[h->dynindx] & s->mask); 5190218822Sdim s->bitmask[val] 5191218822Sdim |= ((bfd_vma) 1) << ((s->hashval[h->dynindx] >> s->shift2) & s->mask); 5192218822Sdim val = s->hashval[h->dynindx] & ~(unsigned long int) 1; 5193218822Sdim if (s->counts[bucket] == 1) 5194218822Sdim /* Last element terminates the chain. */ 5195218822Sdim val |= 1; 5196218822Sdim bfd_put_32 (s->output_bfd, val, 5197218822Sdim s->contents + (s->indx[bucket] - s->symindx) * 4); 5198218822Sdim --s->counts[bucket]; 5199218822Sdim h->dynindx = s->indx[bucket]++; 5200218822Sdim return TRUE; 5201218822Sdim} 5202218822Sdim 5203218822Sdim/* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */ 5204218822Sdim 5205218822Sdimbfd_boolean 5206218822Sdim_bfd_elf_hash_symbol (struct elf_link_hash_entry *h) 5207218822Sdim{ 5208218822Sdim return !(h->forced_local 5209218822Sdim || h->root.type == bfd_link_hash_undefined 5210218822Sdim || h->root.type == bfd_link_hash_undefweak 5211218822Sdim || ((h->root.type == bfd_link_hash_defined 5212218822Sdim || h->root.type == bfd_link_hash_defweak) 5213218822Sdim && h->root.u.def.section->output_section == NULL)); 5214218822Sdim} 5215218822Sdim 5216130561Sobrien/* Array used to determine the number of hash table buckets to use 5217130561Sobrien based on the number of symbols there are. If there are fewer than 5218130561Sobrien 3 symbols we use 1 bucket, fewer than 17 symbols we use 3 buckets, 5219130561Sobrien fewer than 37 we use 17 buckets, and so forth. We never use more 5220130561Sobrien than 32771 buckets. */ 5221130561Sobrien 5222130561Sobrienstatic const size_t elf_buckets[] = 5223130561Sobrien{ 5224130561Sobrien 1, 3, 17, 37, 67, 97, 131, 197, 263, 521, 1031, 2053, 4099, 8209, 5225130561Sobrien 16411, 32771, 0 5226130561Sobrien}; 5227130561Sobrien 5228130561Sobrien/* Compute bucket count for hashing table. We do not use a static set 5229130561Sobrien of possible tables sizes anymore. Instead we determine for all 5230130561Sobrien possible reasonable sizes of the table the outcome (i.e., the 5231130561Sobrien number of collisions etc) and choose the best solution. The 5232130561Sobrien weighting functions are not too simple to allow the table to grow 5233130561Sobrien without bounds. Instead one of the weighting factors is the size. 5234130561Sobrien Therefore the result is always a good payoff between few collisions 5235130561Sobrien (= short chain lengths) and table size. */ 5236130561Sobrienstatic size_t 5237218822Sdimcompute_bucket_count (struct bfd_link_info *info, unsigned long int *hashcodes, 5238218822Sdim unsigned long int nsyms, int gnu_hash) 5239130561Sobrien{ 5240130561Sobrien size_t dynsymcount = elf_hash_table (info)->dynsymcount; 5241130561Sobrien size_t best_size = 0; 5242130561Sobrien unsigned long int i; 5243130561Sobrien bfd_size_type amt; 5244130561Sobrien 5245130561Sobrien /* We have a problem here. The following code to optimize the table 5246130561Sobrien size requires an integer type with more the 32 bits. If 5247130561Sobrien BFD_HOST_U_64_BIT is set we know about such a type. */ 5248130561Sobrien#ifdef BFD_HOST_U_64_BIT 5249130561Sobrien if (info->optimize) 5250130561Sobrien { 5251130561Sobrien size_t minsize; 5252130561Sobrien size_t maxsize; 5253130561Sobrien BFD_HOST_U_64_BIT best_chlen = ~((BFD_HOST_U_64_BIT) 0); 5254130561Sobrien bfd *dynobj = elf_hash_table (info)->dynobj; 5255130561Sobrien const struct elf_backend_data *bed = get_elf_backend_data (dynobj); 5256218822Sdim unsigned long int *counts; 5257130561Sobrien 5258130561Sobrien /* Possible optimization parameters: if we have NSYMS symbols we say 5259130561Sobrien that the hashing table must at least have NSYMS/4 and at most 5260130561Sobrien 2*NSYMS buckets. */ 5261130561Sobrien minsize = nsyms / 4; 5262130561Sobrien if (minsize == 0) 5263130561Sobrien minsize = 1; 5264130561Sobrien best_size = maxsize = nsyms * 2; 5265218822Sdim if (gnu_hash) 5266218822Sdim { 5267218822Sdim if (minsize < 2) 5268218822Sdim minsize = 2; 5269218822Sdim if ((best_size & 31) == 0) 5270218822Sdim ++best_size; 5271218822Sdim } 5272130561Sobrien 5273130561Sobrien /* Create array where we count the collisions in. We must use bfd_malloc 5274130561Sobrien since the size could be large. */ 5275130561Sobrien amt = maxsize; 5276130561Sobrien amt *= sizeof (unsigned long int); 5277130561Sobrien counts = bfd_malloc (amt); 5278130561Sobrien if (counts == NULL) 5279218822Sdim return 0; 5280130561Sobrien 5281130561Sobrien /* Compute the "optimal" size for the hash table. The criteria is a 5282130561Sobrien minimal chain length. The minor criteria is (of course) the size 5283130561Sobrien of the table. */ 5284130561Sobrien for (i = minsize; i < maxsize; ++i) 5285130561Sobrien { 5286130561Sobrien /* Walk through the array of hashcodes and count the collisions. */ 5287130561Sobrien BFD_HOST_U_64_BIT max; 5288130561Sobrien unsigned long int j; 5289130561Sobrien unsigned long int fact; 5290130561Sobrien 5291218822Sdim if (gnu_hash && (i & 31) == 0) 5292218822Sdim continue; 5293218822Sdim 5294130561Sobrien memset (counts, '\0', i * sizeof (unsigned long int)); 5295130561Sobrien 5296130561Sobrien /* Determine how often each hash bucket is used. */ 5297130561Sobrien for (j = 0; j < nsyms; ++j) 5298130561Sobrien ++counts[hashcodes[j] % i]; 5299130561Sobrien 5300130561Sobrien /* For the weight function we need some information about the 5301130561Sobrien pagesize on the target. This is information need not be 100% 5302130561Sobrien accurate. Since this information is not available (so far) we 5303130561Sobrien define it here to a reasonable default value. If it is crucial 5304130561Sobrien to have a better value some day simply define this value. */ 5305130561Sobrien# ifndef BFD_TARGET_PAGESIZE 5306130561Sobrien# define BFD_TARGET_PAGESIZE (4096) 5307130561Sobrien# endif 5308130561Sobrien 5309218822Sdim /* We in any case need 2 + DYNSYMCOUNT entries for the size values 5310218822Sdim and the chains. */ 5311218822Sdim max = (2 + dynsymcount) * bed->s->sizeof_hash_entry; 5312130561Sobrien 5313130561Sobrien# if 1 5314130561Sobrien /* Variant 1: optimize for short chains. We add the squares 5315130561Sobrien of all the chain lengths (which favors many small chain 5316130561Sobrien over a few long chains). */ 5317130561Sobrien for (j = 0; j < i; ++j) 5318130561Sobrien max += counts[j] * counts[j]; 5319130561Sobrien 5320130561Sobrien /* This adds penalties for the overall size of the table. */ 5321218822Sdim fact = i / (BFD_TARGET_PAGESIZE / bed->s->sizeof_hash_entry) + 1; 5322130561Sobrien max *= fact * fact; 5323130561Sobrien# else 5324130561Sobrien /* Variant 2: Optimize a lot more for small table. Here we 5325130561Sobrien also add squares of the size but we also add penalties for 5326130561Sobrien empty slots (the +1 term). */ 5327130561Sobrien for (j = 0; j < i; ++j) 5328130561Sobrien max += (1 + counts[j]) * (1 + counts[j]); 5329130561Sobrien 5330130561Sobrien /* The overall size of the table is considered, but not as 5331130561Sobrien strong as in variant 1, where it is squared. */ 5332218822Sdim fact = i / (BFD_TARGET_PAGESIZE / bed->s->sizeof_hash_entry) + 1; 5333130561Sobrien max *= fact; 5334130561Sobrien# endif 5335130561Sobrien 5336130561Sobrien /* Compare with current best results. */ 5337130561Sobrien if (max < best_chlen) 5338130561Sobrien { 5339130561Sobrien best_chlen = max; 5340130561Sobrien best_size = i; 5341130561Sobrien } 5342130561Sobrien } 5343130561Sobrien 5344130561Sobrien free (counts); 5345130561Sobrien } 5346130561Sobrien else 5347130561Sobrien#endif /* defined (BFD_HOST_U_64_BIT) */ 5348130561Sobrien { 5349130561Sobrien /* This is the fallback solution if no 64bit type is available or if we 5350130561Sobrien are not supposed to spend much time on optimizations. We select the 5351130561Sobrien bucket count using a fixed set of numbers. */ 5352130561Sobrien for (i = 0; elf_buckets[i] != 0; i++) 5353130561Sobrien { 5354130561Sobrien best_size = elf_buckets[i]; 5355218822Sdim if (nsyms < elf_buckets[i + 1]) 5356130561Sobrien break; 5357130561Sobrien } 5358218822Sdim if (gnu_hash && best_size < 2) 5359218822Sdim best_size = 2; 5360130561Sobrien } 5361130561Sobrien 5362130561Sobrien return best_size; 5363130561Sobrien} 5364130561Sobrien 5365130561Sobrien/* Set up the sizes and contents of the ELF dynamic sections. This is 5366130561Sobrien called by the ELF linker emulation before_allocation routine. We 5367130561Sobrien must set the sizes of the sections before the linker sets the 5368130561Sobrien addresses of the various sections. */ 5369130561Sobrien 5370130561Sobrienbfd_boolean 5371130561Sobrienbfd_elf_size_dynamic_sections (bfd *output_bfd, 5372130561Sobrien const char *soname, 5373130561Sobrien const char *rpath, 5374130561Sobrien const char *filter_shlib, 5375130561Sobrien const char * const *auxiliary_filters, 5376130561Sobrien struct bfd_link_info *info, 5377130561Sobrien asection **sinterpptr, 5378130561Sobrien struct bfd_elf_version_tree *verdefs) 5379130561Sobrien{ 5380130561Sobrien bfd_size_type soname_indx; 5381130561Sobrien bfd *dynobj; 5382130561Sobrien const struct elf_backend_data *bed; 5383130561Sobrien struct elf_assign_sym_version_info asvinfo; 5384130561Sobrien 5385130561Sobrien *sinterpptr = NULL; 5386130561Sobrien 5387130561Sobrien soname_indx = (bfd_size_type) -1; 5388130561Sobrien 5389130561Sobrien if (!is_elf_hash_table (info->hash)) 5390130561Sobrien return TRUE; 5391130561Sobrien 5392218822Sdim bed = get_elf_backend_data (output_bfd); 5393218822Sdim elf_tdata (output_bfd)->relro = info->relro; 5394130561Sobrien if (info->execstack) 5395130561Sobrien elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X; 5396130561Sobrien else if (info->noexecstack) 5397130561Sobrien elf_tdata (output_bfd)->stack_flags = PF_R | PF_W; 5398130561Sobrien else 5399130561Sobrien { 5400130561Sobrien bfd *inputobj; 5401130561Sobrien asection *notesec = NULL; 5402130561Sobrien int exec = 0; 5403130561Sobrien 5404130561Sobrien for (inputobj = info->input_bfds; 5405130561Sobrien inputobj; 5406130561Sobrien inputobj = inputobj->link_next) 5407130561Sobrien { 5408130561Sobrien asection *s; 5409130561Sobrien 5410218822Sdim if (inputobj->flags & (DYNAMIC | BFD_LINKER_CREATED)) 5411130561Sobrien continue; 5412130561Sobrien s = bfd_get_section_by_name (inputobj, ".note.GNU-stack"); 5413130561Sobrien if (s) 5414130561Sobrien { 5415130561Sobrien if (s->flags & SEC_CODE) 5416130561Sobrien exec = PF_X; 5417130561Sobrien notesec = s; 5418130561Sobrien } 5419218822Sdim else if (bed->default_execstack) 5420130561Sobrien exec = PF_X; 5421130561Sobrien } 5422130561Sobrien if (notesec) 5423130561Sobrien { 5424130561Sobrien elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | exec; 5425130561Sobrien if (exec && info->relocatable 5426130561Sobrien && notesec->output_section != bfd_abs_section_ptr) 5427130561Sobrien notesec->output_section->flags |= SEC_CODE; 5428130561Sobrien } 5429130561Sobrien } 5430130561Sobrien 5431130561Sobrien /* Any syms created from now on start with -1 in 5432130561Sobrien got.refcount/offset and plt.refcount/offset. */ 5433218822Sdim elf_hash_table (info)->init_got_refcount 5434218822Sdim = elf_hash_table (info)->init_got_offset; 5435218822Sdim elf_hash_table (info)->init_plt_refcount 5436218822Sdim = elf_hash_table (info)->init_plt_offset; 5437130561Sobrien 5438130561Sobrien /* The backend may have to create some sections regardless of whether 5439130561Sobrien we're dynamic or not. */ 5440130561Sobrien if (bed->elf_backend_always_size_sections 5441130561Sobrien && ! (*bed->elf_backend_always_size_sections) (output_bfd, info)) 5442130561Sobrien return FALSE; 5443130561Sobrien 5444218822Sdim if (! _bfd_elf_maybe_strip_eh_frame_hdr (info)) 5445218822Sdim return FALSE; 5446218822Sdim 5447130561Sobrien dynobj = elf_hash_table (info)->dynobj; 5448130561Sobrien 5449130561Sobrien /* If there were no dynamic objects in the link, there is nothing to 5450130561Sobrien do here. */ 5451130561Sobrien if (dynobj == NULL) 5452130561Sobrien return TRUE; 5453130561Sobrien 5454130561Sobrien if (elf_hash_table (info)->dynamic_sections_created) 5455130561Sobrien { 5456130561Sobrien struct elf_info_failed eif; 5457130561Sobrien struct elf_link_hash_entry *h; 5458130561Sobrien asection *dynstr; 5459130561Sobrien struct bfd_elf_version_tree *t; 5460130561Sobrien struct bfd_elf_version_expr *d; 5461218822Sdim asection *s; 5462130561Sobrien bfd_boolean all_defined; 5463130561Sobrien 5464130561Sobrien *sinterpptr = bfd_get_section_by_name (dynobj, ".interp"); 5465130561Sobrien BFD_ASSERT (*sinterpptr != NULL || !info->executable); 5466130561Sobrien 5467130561Sobrien if (soname != NULL) 5468130561Sobrien { 5469130561Sobrien soname_indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, 5470130561Sobrien soname, TRUE); 5471130561Sobrien if (soname_indx == (bfd_size_type) -1 5472130561Sobrien || !_bfd_elf_add_dynamic_entry (info, DT_SONAME, soname_indx)) 5473130561Sobrien return FALSE; 5474130561Sobrien } 5475130561Sobrien 5476130561Sobrien if (info->symbolic) 5477130561Sobrien { 5478130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_SYMBOLIC, 0)) 5479130561Sobrien return FALSE; 5480130561Sobrien info->flags |= DF_SYMBOLIC; 5481130561Sobrien } 5482130561Sobrien 5483130561Sobrien if (rpath != NULL) 5484130561Sobrien { 5485130561Sobrien bfd_size_type indx; 5486130561Sobrien 5487130561Sobrien indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, rpath, 5488130561Sobrien TRUE); 5489130561Sobrien if (indx == (bfd_size_type) -1 5490130561Sobrien || !_bfd_elf_add_dynamic_entry (info, DT_RPATH, indx)) 5491130561Sobrien return FALSE; 5492130561Sobrien 5493130561Sobrien if (info->new_dtags) 5494130561Sobrien { 5495130561Sobrien _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr, indx); 5496130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_RUNPATH, indx)) 5497130561Sobrien return FALSE; 5498130561Sobrien } 5499130561Sobrien } 5500130561Sobrien 5501130561Sobrien if (filter_shlib != NULL) 5502130561Sobrien { 5503130561Sobrien bfd_size_type indx; 5504130561Sobrien 5505130561Sobrien indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, 5506130561Sobrien filter_shlib, TRUE); 5507130561Sobrien if (indx == (bfd_size_type) -1 5508130561Sobrien || !_bfd_elf_add_dynamic_entry (info, DT_FILTER, indx)) 5509130561Sobrien return FALSE; 5510130561Sobrien } 5511130561Sobrien 5512130561Sobrien if (auxiliary_filters != NULL) 5513130561Sobrien { 5514130561Sobrien const char * const *p; 5515130561Sobrien 5516130561Sobrien for (p = auxiliary_filters; *p != NULL; p++) 5517130561Sobrien { 5518130561Sobrien bfd_size_type indx; 5519130561Sobrien 5520130561Sobrien indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, 5521130561Sobrien *p, TRUE); 5522130561Sobrien if (indx == (bfd_size_type) -1 5523130561Sobrien || !_bfd_elf_add_dynamic_entry (info, DT_AUXILIARY, indx)) 5524130561Sobrien return FALSE; 5525130561Sobrien } 5526130561Sobrien } 5527130561Sobrien 5528130561Sobrien eif.info = info; 5529130561Sobrien eif.verdefs = verdefs; 5530130561Sobrien eif.failed = FALSE; 5531130561Sobrien 5532130561Sobrien /* If we are supposed to export all symbols into the dynamic symbol 5533130561Sobrien table (this is not the normal case), then do so. */ 5534218822Sdim if (info->export_dynamic 5535218822Sdim || (info->executable && info->dynamic)) 5536130561Sobrien { 5537130561Sobrien elf_link_hash_traverse (elf_hash_table (info), 5538130561Sobrien _bfd_elf_export_symbol, 5539130561Sobrien &eif); 5540130561Sobrien if (eif.failed) 5541130561Sobrien return FALSE; 5542130561Sobrien } 5543130561Sobrien 5544130561Sobrien /* Make all global versions with definition. */ 5545130561Sobrien for (t = verdefs; t != NULL; t = t->next) 5546130561Sobrien for (d = t->globals.list; d != NULL; d = d->next) 5547130561Sobrien if (!d->symver && d->symbol) 5548130561Sobrien { 5549130561Sobrien const char *verstr, *name; 5550130561Sobrien size_t namelen, verlen, newlen; 5551130561Sobrien char *newname, *p; 5552130561Sobrien struct elf_link_hash_entry *newh; 5553130561Sobrien 5554130561Sobrien name = d->symbol; 5555130561Sobrien namelen = strlen (name); 5556130561Sobrien verstr = t->name; 5557130561Sobrien verlen = strlen (verstr); 5558130561Sobrien newlen = namelen + verlen + 3; 5559130561Sobrien 5560130561Sobrien newname = bfd_malloc (newlen); 5561130561Sobrien if (newname == NULL) 5562130561Sobrien return FALSE; 5563130561Sobrien memcpy (newname, name, namelen); 5564130561Sobrien 5565130561Sobrien /* Check the hidden versioned definition. */ 5566130561Sobrien p = newname + namelen; 5567130561Sobrien *p++ = ELF_VER_CHR; 5568130561Sobrien memcpy (p, verstr, verlen + 1); 5569130561Sobrien newh = elf_link_hash_lookup (elf_hash_table (info), 5570130561Sobrien newname, FALSE, FALSE, 5571130561Sobrien FALSE); 5572130561Sobrien if (newh == NULL 5573130561Sobrien || (newh->root.type != bfd_link_hash_defined 5574130561Sobrien && newh->root.type != bfd_link_hash_defweak)) 5575130561Sobrien { 5576130561Sobrien /* Check the default versioned definition. */ 5577130561Sobrien *p++ = ELF_VER_CHR; 5578130561Sobrien memcpy (p, verstr, verlen + 1); 5579130561Sobrien newh = elf_link_hash_lookup (elf_hash_table (info), 5580130561Sobrien newname, FALSE, FALSE, 5581130561Sobrien FALSE); 5582130561Sobrien } 5583130561Sobrien free (newname); 5584130561Sobrien 5585130561Sobrien /* Mark this version if there is a definition and it is 5586130561Sobrien not defined in a shared object. */ 5587130561Sobrien if (newh != NULL 5588218822Sdim && !newh->def_dynamic 5589130561Sobrien && (newh->root.type == bfd_link_hash_defined 5590130561Sobrien || newh->root.type == bfd_link_hash_defweak)) 5591130561Sobrien d->symver = 1; 5592130561Sobrien } 5593130561Sobrien 5594130561Sobrien /* Attach all the symbols to their version information. */ 5595130561Sobrien asvinfo.output_bfd = output_bfd; 5596130561Sobrien asvinfo.info = info; 5597130561Sobrien asvinfo.verdefs = verdefs; 5598130561Sobrien asvinfo.failed = FALSE; 5599130561Sobrien 5600130561Sobrien elf_link_hash_traverse (elf_hash_table (info), 5601130561Sobrien _bfd_elf_link_assign_sym_version, 5602130561Sobrien &asvinfo); 5603130561Sobrien if (asvinfo.failed) 5604130561Sobrien return FALSE; 5605130561Sobrien 5606130561Sobrien if (!info->allow_undefined_version) 5607130561Sobrien { 5608130561Sobrien /* Check if all global versions have a definition. */ 5609130561Sobrien all_defined = TRUE; 5610130561Sobrien for (t = verdefs; t != NULL; t = t->next) 5611130561Sobrien for (d = t->globals.list; d != NULL; d = d->next) 5612130561Sobrien if (!d->symver && !d->script) 5613130561Sobrien { 5614130561Sobrien (*_bfd_error_handler) 5615130561Sobrien (_("%s: undefined version: %s"), 5616130561Sobrien d->pattern, t->name); 5617130561Sobrien all_defined = FALSE; 5618130561Sobrien } 5619130561Sobrien 5620130561Sobrien if (!all_defined) 5621130561Sobrien { 5622130561Sobrien bfd_set_error (bfd_error_bad_value); 5623130561Sobrien return FALSE; 5624130561Sobrien } 5625130561Sobrien } 5626130561Sobrien 5627130561Sobrien /* Find all symbols which were defined in a dynamic object and make 5628130561Sobrien the backend pick a reasonable value for them. */ 5629130561Sobrien elf_link_hash_traverse (elf_hash_table (info), 5630130561Sobrien _bfd_elf_adjust_dynamic_symbol, 5631130561Sobrien &eif); 5632130561Sobrien if (eif.failed) 5633130561Sobrien return FALSE; 5634130561Sobrien 5635130561Sobrien /* Add some entries to the .dynamic section. We fill in some of the 5636218822Sdim values later, in bfd_elf_final_link, but we must add the entries 5637130561Sobrien now so that we know the final size of the .dynamic section. */ 5638130561Sobrien 5639130561Sobrien /* If there are initialization and/or finalization functions to 5640130561Sobrien call then add the corresponding DT_INIT/DT_FINI entries. */ 5641130561Sobrien h = (info->init_function 5642130561Sobrien ? elf_link_hash_lookup (elf_hash_table (info), 5643130561Sobrien info->init_function, FALSE, 5644130561Sobrien FALSE, FALSE) 5645130561Sobrien : NULL); 5646130561Sobrien if (h != NULL 5647218822Sdim && (h->ref_regular 5648218822Sdim || h->def_regular)) 5649130561Sobrien { 5650130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_INIT, 0)) 5651130561Sobrien return FALSE; 5652130561Sobrien } 5653130561Sobrien h = (info->fini_function 5654130561Sobrien ? elf_link_hash_lookup (elf_hash_table (info), 5655130561Sobrien info->fini_function, FALSE, 5656130561Sobrien FALSE, FALSE) 5657130561Sobrien : NULL); 5658130561Sobrien if (h != NULL 5659218822Sdim && (h->ref_regular 5660218822Sdim || h->def_regular)) 5661130561Sobrien { 5662130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_FINI, 0)) 5663130561Sobrien return FALSE; 5664130561Sobrien } 5665130561Sobrien 5666218822Sdim s = bfd_get_section_by_name (output_bfd, ".preinit_array"); 5667218822Sdim if (s != NULL && s->linker_has_input) 5668130561Sobrien { 5669130561Sobrien /* DT_PREINIT_ARRAY is not allowed in shared library. */ 5670130561Sobrien if (! info->executable) 5671130561Sobrien { 5672130561Sobrien bfd *sub; 5673130561Sobrien asection *o; 5674130561Sobrien 5675130561Sobrien for (sub = info->input_bfds; sub != NULL; 5676130561Sobrien sub = sub->link_next) 5677218822Sdim if (bfd_get_flavour (sub) == bfd_target_elf_flavour) 5678218822Sdim for (o = sub->sections; o != NULL; o = o->next) 5679218822Sdim if (elf_section_data (o)->this_hdr.sh_type 5680218822Sdim == SHT_PREINIT_ARRAY) 5681218822Sdim { 5682218822Sdim (*_bfd_error_handler) 5683218822Sdim (_("%B: .preinit_array section is not allowed in DSO"), 5684218822Sdim sub); 5685218822Sdim break; 5686218822Sdim } 5687130561Sobrien 5688130561Sobrien bfd_set_error (bfd_error_nonrepresentable_section); 5689130561Sobrien return FALSE; 5690130561Sobrien } 5691130561Sobrien 5692130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_PREINIT_ARRAY, 0) 5693130561Sobrien || !_bfd_elf_add_dynamic_entry (info, DT_PREINIT_ARRAYSZ, 0)) 5694130561Sobrien return FALSE; 5695130561Sobrien } 5696218822Sdim s = bfd_get_section_by_name (output_bfd, ".init_array"); 5697218822Sdim if (s != NULL && s->linker_has_input) 5698130561Sobrien { 5699130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_INIT_ARRAY, 0) 5700130561Sobrien || !_bfd_elf_add_dynamic_entry (info, DT_INIT_ARRAYSZ, 0)) 5701130561Sobrien return FALSE; 5702130561Sobrien } 5703218822Sdim s = bfd_get_section_by_name (output_bfd, ".fini_array"); 5704218822Sdim if (s != NULL && s->linker_has_input) 5705130561Sobrien { 5706130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_FINI_ARRAY, 0) 5707130561Sobrien || !_bfd_elf_add_dynamic_entry (info, DT_FINI_ARRAYSZ, 0)) 5708130561Sobrien return FALSE; 5709130561Sobrien } 5710130561Sobrien 5711130561Sobrien dynstr = bfd_get_section_by_name (dynobj, ".dynstr"); 5712130561Sobrien /* If .dynstr is excluded from the link, we don't want any of 5713130561Sobrien these tags. Strictly, we should be checking each section 5714130561Sobrien individually; This quick check covers for the case where 5715130561Sobrien someone does a /DISCARD/ : { *(*) }. */ 5716130561Sobrien if (dynstr != NULL && dynstr->output_section != bfd_abs_section_ptr) 5717130561Sobrien { 5718130561Sobrien bfd_size_type strsize; 5719130561Sobrien 5720130561Sobrien strsize = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr); 5721218822Sdim if ((info->emit_hash 5722218822Sdim && !_bfd_elf_add_dynamic_entry (info, DT_HASH, 0)) 5723218822Sdim || (info->emit_gnu_hash 5724218822Sdim && !_bfd_elf_add_dynamic_entry (info, DT_GNU_HASH, 0)) 5725130561Sobrien || !_bfd_elf_add_dynamic_entry (info, DT_STRTAB, 0) 5726130561Sobrien || !_bfd_elf_add_dynamic_entry (info, DT_SYMTAB, 0) 5727130561Sobrien || !_bfd_elf_add_dynamic_entry (info, DT_STRSZ, strsize) 5728130561Sobrien || !_bfd_elf_add_dynamic_entry (info, DT_SYMENT, 5729130561Sobrien bed->s->sizeof_sym)) 5730130561Sobrien return FALSE; 5731130561Sobrien } 5732130561Sobrien } 5733130561Sobrien 5734130561Sobrien /* The backend must work out the sizes of all the other dynamic 5735130561Sobrien sections. */ 5736130561Sobrien if (bed->elf_backend_size_dynamic_sections 5737130561Sobrien && ! (*bed->elf_backend_size_dynamic_sections) (output_bfd, info)) 5738130561Sobrien return FALSE; 5739130561Sobrien 5740130561Sobrien if (elf_hash_table (info)->dynamic_sections_created) 5741130561Sobrien { 5742218822Sdim unsigned long section_sym_count; 5743130561Sobrien asection *s; 5744130561Sobrien 5745130561Sobrien /* Set up the version definition section. */ 5746130561Sobrien s = bfd_get_section_by_name (dynobj, ".gnu.version_d"); 5747130561Sobrien BFD_ASSERT (s != NULL); 5748130561Sobrien 5749130561Sobrien /* We may have created additional version definitions if we are 5750130561Sobrien just linking a regular application. */ 5751130561Sobrien verdefs = asvinfo.verdefs; 5752130561Sobrien 5753130561Sobrien /* Skip anonymous version tag. */ 5754130561Sobrien if (verdefs != NULL && verdefs->vernum == 0) 5755130561Sobrien verdefs = verdefs->next; 5756130561Sobrien 5757218822Sdim if (verdefs == NULL && !info->create_default_symver) 5758218822Sdim s->flags |= SEC_EXCLUDE; 5759130561Sobrien else 5760130561Sobrien { 5761130561Sobrien unsigned int cdefs; 5762130561Sobrien bfd_size_type size; 5763130561Sobrien struct bfd_elf_version_tree *t; 5764130561Sobrien bfd_byte *p; 5765130561Sobrien Elf_Internal_Verdef def; 5766130561Sobrien Elf_Internal_Verdaux defaux; 5767218822Sdim struct bfd_link_hash_entry *bh; 5768218822Sdim struct elf_link_hash_entry *h; 5769218822Sdim const char *name; 5770130561Sobrien 5771130561Sobrien cdefs = 0; 5772130561Sobrien size = 0; 5773130561Sobrien 5774130561Sobrien /* Make space for the base version. */ 5775130561Sobrien size += sizeof (Elf_External_Verdef); 5776130561Sobrien size += sizeof (Elf_External_Verdaux); 5777130561Sobrien ++cdefs; 5778130561Sobrien 5779218822Sdim /* Make space for the default version. */ 5780218822Sdim if (info->create_default_symver) 5781218822Sdim { 5782218822Sdim size += sizeof (Elf_External_Verdef); 5783218822Sdim ++cdefs; 5784218822Sdim } 5785218822Sdim 5786130561Sobrien for (t = verdefs; t != NULL; t = t->next) 5787130561Sobrien { 5788130561Sobrien struct bfd_elf_version_deps *n; 5789130561Sobrien 5790130561Sobrien size += sizeof (Elf_External_Verdef); 5791130561Sobrien size += sizeof (Elf_External_Verdaux); 5792130561Sobrien ++cdefs; 5793130561Sobrien 5794130561Sobrien for (n = t->deps; n != NULL; n = n->next) 5795130561Sobrien size += sizeof (Elf_External_Verdaux); 5796130561Sobrien } 5797130561Sobrien 5798218822Sdim s->size = size; 5799218822Sdim s->contents = bfd_alloc (output_bfd, s->size); 5800218822Sdim if (s->contents == NULL && s->size != 0) 5801130561Sobrien return FALSE; 5802130561Sobrien 5803130561Sobrien /* Fill in the version definition section. */ 5804130561Sobrien 5805130561Sobrien p = s->contents; 5806130561Sobrien 5807130561Sobrien def.vd_version = VER_DEF_CURRENT; 5808130561Sobrien def.vd_flags = VER_FLG_BASE; 5809130561Sobrien def.vd_ndx = 1; 5810130561Sobrien def.vd_cnt = 1; 5811218822Sdim if (info->create_default_symver) 5812218822Sdim { 5813218822Sdim def.vd_aux = 2 * sizeof (Elf_External_Verdef); 5814218822Sdim def.vd_next = sizeof (Elf_External_Verdef); 5815218822Sdim } 5816218822Sdim else 5817218822Sdim { 5818218822Sdim def.vd_aux = sizeof (Elf_External_Verdef); 5819218822Sdim def.vd_next = (sizeof (Elf_External_Verdef) 5820218822Sdim + sizeof (Elf_External_Verdaux)); 5821218822Sdim } 5822130561Sobrien 5823130561Sobrien if (soname_indx != (bfd_size_type) -1) 5824130561Sobrien { 5825130561Sobrien _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr, 5826130561Sobrien soname_indx); 5827130561Sobrien def.vd_hash = bfd_elf_hash (soname); 5828130561Sobrien defaux.vda_name = soname_indx; 5829218822Sdim name = soname; 5830130561Sobrien } 5831130561Sobrien else 5832130561Sobrien { 5833130561Sobrien bfd_size_type indx; 5834130561Sobrien 5835218822Sdim name = lbasename (output_bfd->filename); 5836130561Sobrien def.vd_hash = bfd_elf_hash (name); 5837130561Sobrien indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, 5838130561Sobrien name, FALSE); 5839130561Sobrien if (indx == (bfd_size_type) -1) 5840130561Sobrien return FALSE; 5841130561Sobrien defaux.vda_name = indx; 5842130561Sobrien } 5843130561Sobrien defaux.vda_next = 0; 5844130561Sobrien 5845130561Sobrien _bfd_elf_swap_verdef_out (output_bfd, &def, 5846130561Sobrien (Elf_External_Verdef *) p); 5847130561Sobrien p += sizeof (Elf_External_Verdef); 5848218822Sdim if (info->create_default_symver) 5849218822Sdim { 5850218822Sdim /* Add a symbol representing this version. */ 5851218822Sdim bh = NULL; 5852218822Sdim if (! (_bfd_generic_link_add_one_symbol 5853218822Sdim (info, dynobj, name, BSF_GLOBAL, bfd_abs_section_ptr, 5854218822Sdim 0, NULL, FALSE, 5855218822Sdim get_elf_backend_data (dynobj)->collect, &bh))) 5856218822Sdim return FALSE; 5857218822Sdim h = (struct elf_link_hash_entry *) bh; 5858218822Sdim h->non_elf = 0; 5859218822Sdim h->def_regular = 1; 5860218822Sdim h->type = STT_OBJECT; 5861218822Sdim h->verinfo.vertree = NULL; 5862218822Sdim 5863218822Sdim if (! bfd_elf_link_record_dynamic_symbol (info, h)) 5864218822Sdim return FALSE; 5865218822Sdim 5866218822Sdim /* Create a duplicate of the base version with the same 5867218822Sdim aux block, but different flags. */ 5868218822Sdim def.vd_flags = 0; 5869218822Sdim def.vd_ndx = 2; 5870218822Sdim def.vd_aux = sizeof (Elf_External_Verdef); 5871218822Sdim if (verdefs) 5872218822Sdim def.vd_next = (sizeof (Elf_External_Verdef) 5873218822Sdim + sizeof (Elf_External_Verdaux)); 5874218822Sdim else 5875218822Sdim def.vd_next = 0; 5876218822Sdim _bfd_elf_swap_verdef_out (output_bfd, &def, 5877218822Sdim (Elf_External_Verdef *) p); 5878218822Sdim p += sizeof (Elf_External_Verdef); 5879218822Sdim } 5880130561Sobrien _bfd_elf_swap_verdaux_out (output_bfd, &defaux, 5881130561Sobrien (Elf_External_Verdaux *) p); 5882130561Sobrien p += sizeof (Elf_External_Verdaux); 5883130561Sobrien 5884130561Sobrien for (t = verdefs; t != NULL; t = t->next) 5885130561Sobrien { 5886130561Sobrien unsigned int cdeps; 5887130561Sobrien struct bfd_elf_version_deps *n; 5888130561Sobrien 5889130561Sobrien cdeps = 0; 5890130561Sobrien for (n = t->deps; n != NULL; n = n->next) 5891130561Sobrien ++cdeps; 5892130561Sobrien 5893130561Sobrien /* Add a symbol representing this version. */ 5894130561Sobrien bh = NULL; 5895130561Sobrien if (! (_bfd_generic_link_add_one_symbol 5896130561Sobrien (info, dynobj, t->name, BSF_GLOBAL, bfd_abs_section_ptr, 5897130561Sobrien 0, NULL, FALSE, 5898130561Sobrien get_elf_backend_data (dynobj)->collect, &bh))) 5899130561Sobrien return FALSE; 5900130561Sobrien h = (struct elf_link_hash_entry *) bh; 5901218822Sdim h->non_elf = 0; 5902218822Sdim h->def_regular = 1; 5903130561Sobrien h->type = STT_OBJECT; 5904130561Sobrien h->verinfo.vertree = t; 5905130561Sobrien 5906130561Sobrien if (! bfd_elf_link_record_dynamic_symbol (info, h)) 5907130561Sobrien return FALSE; 5908130561Sobrien 5909130561Sobrien def.vd_version = VER_DEF_CURRENT; 5910130561Sobrien def.vd_flags = 0; 5911130561Sobrien if (t->globals.list == NULL 5912130561Sobrien && t->locals.list == NULL 5913130561Sobrien && ! t->used) 5914130561Sobrien def.vd_flags |= VER_FLG_WEAK; 5915218822Sdim def.vd_ndx = t->vernum + (info->create_default_symver ? 2 : 1); 5916130561Sobrien def.vd_cnt = cdeps + 1; 5917130561Sobrien def.vd_hash = bfd_elf_hash (t->name); 5918130561Sobrien def.vd_aux = sizeof (Elf_External_Verdef); 5919130561Sobrien def.vd_next = 0; 5920130561Sobrien if (t->next != NULL) 5921130561Sobrien def.vd_next = (sizeof (Elf_External_Verdef) 5922130561Sobrien + (cdeps + 1) * sizeof (Elf_External_Verdaux)); 5923130561Sobrien 5924130561Sobrien _bfd_elf_swap_verdef_out (output_bfd, &def, 5925130561Sobrien (Elf_External_Verdef *) p); 5926130561Sobrien p += sizeof (Elf_External_Verdef); 5927130561Sobrien 5928130561Sobrien defaux.vda_name = h->dynstr_index; 5929130561Sobrien _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr, 5930130561Sobrien h->dynstr_index); 5931130561Sobrien defaux.vda_next = 0; 5932130561Sobrien if (t->deps != NULL) 5933130561Sobrien defaux.vda_next = sizeof (Elf_External_Verdaux); 5934130561Sobrien t->name_indx = defaux.vda_name; 5935130561Sobrien 5936130561Sobrien _bfd_elf_swap_verdaux_out (output_bfd, &defaux, 5937130561Sobrien (Elf_External_Verdaux *) p); 5938130561Sobrien p += sizeof (Elf_External_Verdaux); 5939130561Sobrien 5940130561Sobrien for (n = t->deps; n != NULL; n = n->next) 5941130561Sobrien { 5942130561Sobrien if (n->version_needed == NULL) 5943130561Sobrien { 5944130561Sobrien /* This can happen if there was an error in the 5945130561Sobrien version script. */ 5946130561Sobrien defaux.vda_name = 0; 5947130561Sobrien } 5948130561Sobrien else 5949130561Sobrien { 5950130561Sobrien defaux.vda_name = n->version_needed->name_indx; 5951130561Sobrien _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr, 5952130561Sobrien defaux.vda_name); 5953130561Sobrien } 5954130561Sobrien if (n->next == NULL) 5955130561Sobrien defaux.vda_next = 0; 5956130561Sobrien else 5957130561Sobrien defaux.vda_next = sizeof (Elf_External_Verdaux); 5958130561Sobrien 5959130561Sobrien _bfd_elf_swap_verdaux_out (output_bfd, &defaux, 5960130561Sobrien (Elf_External_Verdaux *) p); 5961130561Sobrien p += sizeof (Elf_External_Verdaux); 5962130561Sobrien } 5963130561Sobrien } 5964130561Sobrien 5965130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_VERDEF, 0) 5966130561Sobrien || !_bfd_elf_add_dynamic_entry (info, DT_VERDEFNUM, cdefs)) 5967130561Sobrien return FALSE; 5968130561Sobrien 5969130561Sobrien elf_tdata (output_bfd)->cverdefs = cdefs; 5970130561Sobrien } 5971130561Sobrien 5972130561Sobrien if ((info->new_dtags && info->flags) || (info->flags & DF_STATIC_TLS)) 5973130561Sobrien { 5974130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_FLAGS, info->flags)) 5975130561Sobrien return FALSE; 5976130561Sobrien } 5977130561Sobrien else if (info->flags & DF_BIND_NOW) 5978130561Sobrien { 5979130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_BIND_NOW, 0)) 5980130561Sobrien return FALSE; 5981130561Sobrien } 5982130561Sobrien 5983130561Sobrien if (info->flags_1) 5984130561Sobrien { 5985130561Sobrien if (info->executable) 5986130561Sobrien info->flags_1 &= ~ (DF_1_INITFIRST 5987130561Sobrien | DF_1_NODELETE 5988130561Sobrien | DF_1_NOOPEN); 5989130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_FLAGS_1, info->flags_1)) 5990130561Sobrien return FALSE; 5991130561Sobrien } 5992130561Sobrien 5993130561Sobrien /* Work out the size of the version reference section. */ 5994130561Sobrien 5995130561Sobrien s = bfd_get_section_by_name (dynobj, ".gnu.version_r"); 5996130561Sobrien BFD_ASSERT (s != NULL); 5997130561Sobrien { 5998130561Sobrien struct elf_find_verdep_info sinfo; 5999130561Sobrien 6000130561Sobrien sinfo.output_bfd = output_bfd; 6001130561Sobrien sinfo.info = info; 6002130561Sobrien sinfo.vers = elf_tdata (output_bfd)->cverdefs; 6003130561Sobrien if (sinfo.vers == 0) 6004130561Sobrien sinfo.vers = 1; 6005130561Sobrien sinfo.failed = FALSE; 6006130561Sobrien 6007130561Sobrien elf_link_hash_traverse (elf_hash_table (info), 6008130561Sobrien _bfd_elf_link_find_version_dependencies, 6009130561Sobrien &sinfo); 6010130561Sobrien 6011130561Sobrien if (elf_tdata (output_bfd)->verref == NULL) 6012218822Sdim s->flags |= SEC_EXCLUDE; 6013130561Sobrien else 6014130561Sobrien { 6015130561Sobrien Elf_Internal_Verneed *t; 6016130561Sobrien unsigned int size; 6017130561Sobrien unsigned int crefs; 6018130561Sobrien bfd_byte *p; 6019130561Sobrien 6020130561Sobrien /* Build the version definition section. */ 6021130561Sobrien size = 0; 6022130561Sobrien crefs = 0; 6023130561Sobrien for (t = elf_tdata (output_bfd)->verref; 6024130561Sobrien t != NULL; 6025130561Sobrien t = t->vn_nextref) 6026130561Sobrien { 6027130561Sobrien Elf_Internal_Vernaux *a; 6028130561Sobrien 6029130561Sobrien size += sizeof (Elf_External_Verneed); 6030130561Sobrien ++crefs; 6031130561Sobrien for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) 6032130561Sobrien size += sizeof (Elf_External_Vernaux); 6033130561Sobrien } 6034130561Sobrien 6035218822Sdim s->size = size; 6036218822Sdim s->contents = bfd_alloc (output_bfd, s->size); 6037130561Sobrien if (s->contents == NULL) 6038130561Sobrien return FALSE; 6039130561Sobrien 6040130561Sobrien p = s->contents; 6041130561Sobrien for (t = elf_tdata (output_bfd)->verref; 6042130561Sobrien t != NULL; 6043130561Sobrien t = t->vn_nextref) 6044130561Sobrien { 6045130561Sobrien unsigned int caux; 6046130561Sobrien Elf_Internal_Vernaux *a; 6047130561Sobrien bfd_size_type indx; 6048130561Sobrien 6049130561Sobrien caux = 0; 6050130561Sobrien for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) 6051130561Sobrien ++caux; 6052130561Sobrien 6053130561Sobrien t->vn_version = VER_NEED_CURRENT; 6054130561Sobrien t->vn_cnt = caux; 6055130561Sobrien indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, 6056130561Sobrien elf_dt_name (t->vn_bfd) != NULL 6057130561Sobrien ? elf_dt_name (t->vn_bfd) 6058218822Sdim : lbasename (t->vn_bfd->filename), 6059130561Sobrien FALSE); 6060130561Sobrien if (indx == (bfd_size_type) -1) 6061130561Sobrien return FALSE; 6062130561Sobrien t->vn_file = indx; 6063130561Sobrien t->vn_aux = sizeof (Elf_External_Verneed); 6064130561Sobrien if (t->vn_nextref == NULL) 6065130561Sobrien t->vn_next = 0; 6066130561Sobrien else 6067130561Sobrien t->vn_next = (sizeof (Elf_External_Verneed) 6068130561Sobrien + caux * sizeof (Elf_External_Vernaux)); 6069130561Sobrien 6070130561Sobrien _bfd_elf_swap_verneed_out (output_bfd, t, 6071130561Sobrien (Elf_External_Verneed *) p); 6072130561Sobrien p += sizeof (Elf_External_Verneed); 6073130561Sobrien 6074130561Sobrien for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr) 6075130561Sobrien { 6076130561Sobrien a->vna_hash = bfd_elf_hash (a->vna_nodename); 6077130561Sobrien indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, 6078130561Sobrien a->vna_nodename, FALSE); 6079130561Sobrien if (indx == (bfd_size_type) -1) 6080130561Sobrien return FALSE; 6081130561Sobrien a->vna_name = indx; 6082130561Sobrien if (a->vna_nextptr == NULL) 6083130561Sobrien a->vna_next = 0; 6084130561Sobrien else 6085130561Sobrien a->vna_next = sizeof (Elf_External_Vernaux); 6086130561Sobrien 6087130561Sobrien _bfd_elf_swap_vernaux_out (output_bfd, a, 6088130561Sobrien (Elf_External_Vernaux *) p); 6089130561Sobrien p += sizeof (Elf_External_Vernaux); 6090130561Sobrien } 6091130561Sobrien } 6092130561Sobrien 6093130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_VERNEED, 0) 6094130561Sobrien || !_bfd_elf_add_dynamic_entry (info, DT_VERNEEDNUM, crefs)) 6095130561Sobrien return FALSE; 6096130561Sobrien 6097130561Sobrien elf_tdata (output_bfd)->cverrefs = crefs; 6098130561Sobrien } 6099130561Sobrien } 6100130561Sobrien 6101218822Sdim if ((elf_tdata (output_bfd)->cverrefs == 0 6102218822Sdim && elf_tdata (output_bfd)->cverdefs == 0) 6103218822Sdim || _bfd_elf_link_renumber_dynsyms (output_bfd, info, 6104218822Sdim §ion_sym_count) == 0) 6105218822Sdim { 6106218822Sdim s = bfd_get_section_by_name (dynobj, ".gnu.version"); 6107218822Sdim s->flags |= SEC_EXCLUDE; 6108218822Sdim } 6109218822Sdim } 6110218822Sdim return TRUE; 6111218822Sdim} 6112218822Sdim 6113218822Sdim/* Find the first non-excluded output section. We'll use its 6114218822Sdim section symbol for some emitted relocs. */ 6115218822Sdimvoid 6116218822Sdim_bfd_elf_init_1_index_section (bfd *output_bfd, struct bfd_link_info *info) 6117218822Sdim{ 6118218822Sdim asection *s; 6119218822Sdim 6120218822Sdim for (s = output_bfd->sections; s != NULL; s = s->next) 6121218822Sdim if ((s->flags & (SEC_EXCLUDE | SEC_ALLOC)) == SEC_ALLOC 6122218822Sdim && !_bfd_elf_link_omit_section_dynsym (output_bfd, info, s)) 6123218822Sdim { 6124218822Sdim elf_hash_table (info)->text_index_section = s; 6125218822Sdim break; 6126218822Sdim } 6127218822Sdim} 6128218822Sdim 6129218822Sdim/* Find two non-excluded output sections, one for code, one for data. 6130218822Sdim We'll use their section symbols for some emitted relocs. */ 6131218822Sdimvoid 6132218822Sdim_bfd_elf_init_2_index_sections (bfd *output_bfd, struct bfd_link_info *info) 6133218822Sdim{ 6134218822Sdim asection *s; 6135218822Sdim 6136218822Sdim for (s = output_bfd->sections; s != NULL; s = s->next) 6137218822Sdim if (((s->flags & (SEC_EXCLUDE | SEC_ALLOC | SEC_READONLY)) 6138218822Sdim == (SEC_ALLOC | SEC_READONLY)) 6139218822Sdim && !_bfd_elf_link_omit_section_dynsym (output_bfd, info, s)) 6140218822Sdim { 6141218822Sdim elf_hash_table (info)->text_index_section = s; 6142218822Sdim break; 6143218822Sdim } 6144218822Sdim 6145218822Sdim for (s = output_bfd->sections; s != NULL; s = s->next) 6146218822Sdim if (((s->flags & (SEC_EXCLUDE | SEC_ALLOC | SEC_READONLY)) == SEC_ALLOC) 6147218822Sdim && !_bfd_elf_link_omit_section_dynsym (output_bfd, info, s)) 6148218822Sdim { 6149218822Sdim elf_hash_table (info)->data_index_section = s; 6150218822Sdim break; 6151218822Sdim } 6152218822Sdim 6153218822Sdim if (elf_hash_table (info)->text_index_section == NULL) 6154218822Sdim elf_hash_table (info)->text_index_section 6155218822Sdim = elf_hash_table (info)->data_index_section; 6156218822Sdim} 6157218822Sdim 6158218822Sdimbfd_boolean 6159218822Sdimbfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info) 6160218822Sdim{ 6161218822Sdim const struct elf_backend_data *bed; 6162218822Sdim 6163218822Sdim if (!is_elf_hash_table (info->hash)) 6164218822Sdim return TRUE; 6165218822Sdim 6166218822Sdim bed = get_elf_backend_data (output_bfd); 6167218822Sdim (*bed->elf_backend_init_index_section) (output_bfd, info); 6168218822Sdim 6169218822Sdim if (elf_hash_table (info)->dynamic_sections_created) 6170218822Sdim { 6171218822Sdim bfd *dynobj; 6172218822Sdim asection *s; 6173218822Sdim bfd_size_type dynsymcount; 6174218822Sdim unsigned long section_sym_count; 6175218822Sdim unsigned int dtagcount; 6176218822Sdim 6177218822Sdim dynobj = elf_hash_table (info)->dynobj; 6178218822Sdim 6179130561Sobrien /* Assign dynsym indicies. In a shared library we generate a 6180130561Sobrien section symbol for each output section, which come first. 6181130561Sobrien Next come all of the back-end allocated local dynamic syms, 6182130561Sobrien followed by the rest of the global symbols. */ 6183130561Sobrien 6184218822Sdim dynsymcount = _bfd_elf_link_renumber_dynsyms (output_bfd, info, 6185218822Sdim §ion_sym_count); 6186130561Sobrien 6187130561Sobrien /* Work out the size of the symbol version section. */ 6188130561Sobrien s = bfd_get_section_by_name (dynobj, ".gnu.version"); 6189130561Sobrien BFD_ASSERT (s != NULL); 6190218822Sdim if (dynsymcount != 0 6191218822Sdim && (s->flags & SEC_EXCLUDE) == 0) 6192130561Sobrien { 6193218822Sdim s->size = dynsymcount * sizeof (Elf_External_Versym); 6194218822Sdim s->contents = bfd_zalloc (output_bfd, s->size); 6195130561Sobrien if (s->contents == NULL) 6196130561Sobrien return FALSE; 6197130561Sobrien 6198130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_VERSYM, 0)) 6199130561Sobrien return FALSE; 6200130561Sobrien } 6201130561Sobrien 6202130561Sobrien /* Set the size of the .dynsym and .hash sections. We counted 6203130561Sobrien the number of dynamic symbols in elf_link_add_object_symbols. 6204130561Sobrien We will build the contents of .dynsym and .hash when we build 6205130561Sobrien the final symbol table, because until then we do not know the 6206130561Sobrien correct value to give the symbols. We built the .dynstr 6207130561Sobrien section as we went along in elf_link_add_object_symbols. */ 6208130561Sobrien s = bfd_get_section_by_name (dynobj, ".dynsym"); 6209130561Sobrien BFD_ASSERT (s != NULL); 6210218822Sdim s->size = dynsymcount * bed->s->sizeof_sym; 6211130561Sobrien 6212130561Sobrien if (dynsymcount != 0) 6213130561Sobrien { 6214218822Sdim s->contents = bfd_alloc (output_bfd, s->size); 6215218822Sdim if (s->contents == NULL) 6216218822Sdim return FALSE; 6217130561Sobrien 6218218822Sdim /* The first entry in .dynsym is a dummy symbol. 6219218822Sdim Clear all the section syms, in case we don't output them all. */ 6220218822Sdim ++section_sym_count; 6221218822Sdim memset (s->contents, 0, section_sym_count * bed->s->sizeof_sym); 6222130561Sobrien } 6223130561Sobrien 6224218822Sdim elf_hash_table (info)->bucketcount = 0; 6225218822Sdim 6226130561Sobrien /* Compute the size of the hashing table. As a side effect this 6227130561Sobrien computes the hash values for all the names we export. */ 6228218822Sdim if (info->emit_hash) 6229218822Sdim { 6230218822Sdim unsigned long int *hashcodes; 6231218822Sdim unsigned long int *hashcodesp; 6232218822Sdim bfd_size_type amt; 6233218822Sdim unsigned long int nsyms; 6234218822Sdim size_t bucketcount; 6235218822Sdim size_t hash_entry_size; 6236130561Sobrien 6237218822Sdim /* Compute the hash values for all exported symbols. At the same 6238218822Sdim time store the values in an array so that we could use them for 6239218822Sdim optimizations. */ 6240218822Sdim amt = dynsymcount * sizeof (unsigned long int); 6241218822Sdim hashcodes = bfd_malloc (amt); 6242218822Sdim if (hashcodes == NULL) 6243218822Sdim return FALSE; 6244218822Sdim hashcodesp = hashcodes; 6245130561Sobrien 6246218822Sdim /* Put all hash values in HASHCODES. */ 6247218822Sdim elf_link_hash_traverse (elf_hash_table (info), 6248218822Sdim elf_collect_hash_codes, &hashcodesp); 6249130561Sobrien 6250218822Sdim nsyms = hashcodesp - hashcodes; 6251218822Sdim bucketcount 6252218822Sdim = compute_bucket_count (info, hashcodes, nsyms, 0); 6253218822Sdim free (hashcodes); 6254130561Sobrien 6255218822Sdim if (bucketcount == 0) 6256218822Sdim return FALSE; 6257218822Sdim 6258218822Sdim elf_hash_table (info)->bucketcount = bucketcount; 6259218822Sdim 6260218822Sdim s = bfd_get_section_by_name (dynobj, ".hash"); 6261218822Sdim BFD_ASSERT (s != NULL); 6262218822Sdim hash_entry_size = elf_section_data (s)->this_hdr.sh_entsize; 6263218822Sdim s->size = ((2 + bucketcount + dynsymcount) * hash_entry_size); 6264218822Sdim s->contents = bfd_zalloc (output_bfd, s->size); 6265218822Sdim if (s->contents == NULL) 6266218822Sdim return FALSE; 6267218822Sdim 6268218822Sdim bfd_put (8 * hash_entry_size, output_bfd, bucketcount, s->contents); 6269218822Sdim bfd_put (8 * hash_entry_size, output_bfd, dynsymcount, 6270218822Sdim s->contents + hash_entry_size); 6271218822Sdim } 6272218822Sdim 6273218822Sdim if (info->emit_gnu_hash) 6274218822Sdim { 6275218822Sdim size_t i, cnt; 6276218822Sdim unsigned char *contents; 6277218822Sdim struct collect_gnu_hash_codes cinfo; 6278218822Sdim bfd_size_type amt; 6279218822Sdim size_t bucketcount; 6280218822Sdim 6281218822Sdim memset (&cinfo, 0, sizeof (cinfo)); 6282218822Sdim 6283218822Sdim /* Compute the hash values for all exported symbols. At the same 6284218822Sdim time store the values in an array so that we could use them for 6285218822Sdim optimizations. */ 6286218822Sdim amt = dynsymcount * 2 * sizeof (unsigned long int); 6287218822Sdim cinfo.hashcodes = bfd_malloc (amt); 6288218822Sdim if (cinfo.hashcodes == NULL) 6289218822Sdim return FALSE; 6290218822Sdim 6291218822Sdim cinfo.hashval = cinfo.hashcodes + dynsymcount; 6292218822Sdim cinfo.min_dynindx = -1; 6293218822Sdim cinfo.output_bfd = output_bfd; 6294218822Sdim cinfo.bed = bed; 6295218822Sdim 6296218822Sdim /* Put all hash values in HASHCODES. */ 6297218822Sdim elf_link_hash_traverse (elf_hash_table (info), 6298218822Sdim elf_collect_gnu_hash_codes, &cinfo); 6299218822Sdim 6300218822Sdim bucketcount 6301218822Sdim = compute_bucket_count (info, cinfo.hashcodes, cinfo.nsyms, 1); 6302218822Sdim 6303218822Sdim if (bucketcount == 0) 6304218822Sdim { 6305218822Sdim free (cinfo.hashcodes); 6306218822Sdim return FALSE; 6307218822Sdim } 6308218822Sdim 6309218822Sdim s = bfd_get_section_by_name (dynobj, ".gnu.hash"); 6310218822Sdim BFD_ASSERT (s != NULL); 6311218822Sdim 6312218822Sdim if (cinfo.nsyms == 0) 6313218822Sdim { 6314218822Sdim /* Empty .gnu.hash section is special. */ 6315218822Sdim BFD_ASSERT (cinfo.min_dynindx == -1); 6316218822Sdim free (cinfo.hashcodes); 6317218822Sdim s->size = 5 * 4 + bed->s->arch_size / 8; 6318218822Sdim contents = bfd_zalloc (output_bfd, s->size); 6319218822Sdim if (contents == NULL) 6320218822Sdim return FALSE; 6321218822Sdim s->contents = contents; 6322218822Sdim /* 1 empty bucket. */ 6323218822Sdim bfd_put_32 (output_bfd, 1, contents); 6324218822Sdim /* SYMIDX above the special symbol 0. */ 6325218822Sdim bfd_put_32 (output_bfd, 1, contents + 4); 6326218822Sdim /* Just one word for bitmask. */ 6327218822Sdim bfd_put_32 (output_bfd, 1, contents + 8); 6328218822Sdim /* Only hash fn bloom filter. */ 6329218822Sdim bfd_put_32 (output_bfd, 0, contents + 12); 6330218822Sdim /* No hashes are valid - empty bitmask. */ 6331218822Sdim bfd_put (bed->s->arch_size, output_bfd, 0, contents + 16); 6332218822Sdim /* No hashes in the only bucket. */ 6333218822Sdim bfd_put_32 (output_bfd, 0, 6334218822Sdim contents + 16 + bed->s->arch_size / 8); 6335218822Sdim } 6336218822Sdim else 6337218822Sdim { 6338218822Sdim unsigned long int maskwords, maskbitslog2; 6339218822Sdim BFD_ASSERT (cinfo.min_dynindx != -1); 6340218822Sdim 6341218822Sdim maskbitslog2 = bfd_log2 (cinfo.nsyms) + 1; 6342218822Sdim if (maskbitslog2 < 3) 6343218822Sdim maskbitslog2 = 5; 6344218822Sdim else if ((1 << (maskbitslog2 - 2)) & cinfo.nsyms) 6345218822Sdim maskbitslog2 = maskbitslog2 + 3; 6346218822Sdim else 6347218822Sdim maskbitslog2 = maskbitslog2 + 2; 6348218822Sdim if (bed->s->arch_size == 64) 6349218822Sdim { 6350218822Sdim if (maskbitslog2 == 5) 6351218822Sdim maskbitslog2 = 6; 6352218822Sdim cinfo.shift1 = 6; 6353218822Sdim } 6354218822Sdim else 6355218822Sdim cinfo.shift1 = 5; 6356218822Sdim cinfo.mask = (1 << cinfo.shift1) - 1; 6357218822Sdim cinfo.shift2 = maskbitslog2; 6358218822Sdim cinfo.maskbits = 1 << maskbitslog2; 6359218822Sdim maskwords = 1 << (maskbitslog2 - cinfo.shift1); 6360218822Sdim amt = bucketcount * sizeof (unsigned long int) * 2; 6361218822Sdim amt += maskwords * sizeof (bfd_vma); 6362218822Sdim cinfo.bitmask = bfd_malloc (amt); 6363218822Sdim if (cinfo.bitmask == NULL) 6364218822Sdim { 6365218822Sdim free (cinfo.hashcodes); 6366218822Sdim return FALSE; 6367218822Sdim } 6368218822Sdim 6369218822Sdim cinfo.counts = (void *) (cinfo.bitmask + maskwords); 6370218822Sdim cinfo.indx = cinfo.counts + bucketcount; 6371218822Sdim cinfo.symindx = dynsymcount - cinfo.nsyms; 6372218822Sdim memset (cinfo.bitmask, 0, maskwords * sizeof (bfd_vma)); 6373218822Sdim 6374218822Sdim /* Determine how often each hash bucket is used. */ 6375218822Sdim memset (cinfo.counts, 0, bucketcount * sizeof (cinfo.counts[0])); 6376218822Sdim for (i = 0; i < cinfo.nsyms; ++i) 6377218822Sdim ++cinfo.counts[cinfo.hashcodes[i] % bucketcount]; 6378218822Sdim 6379218822Sdim for (i = 0, cnt = cinfo.symindx; i < bucketcount; ++i) 6380218822Sdim if (cinfo.counts[i] != 0) 6381218822Sdim { 6382218822Sdim cinfo.indx[i] = cnt; 6383218822Sdim cnt += cinfo.counts[i]; 6384218822Sdim } 6385218822Sdim BFD_ASSERT (cnt == dynsymcount); 6386218822Sdim cinfo.bucketcount = bucketcount; 6387218822Sdim cinfo.local_indx = cinfo.min_dynindx; 6388218822Sdim 6389218822Sdim s->size = (4 + bucketcount + cinfo.nsyms) * 4; 6390218822Sdim s->size += cinfo.maskbits / 8; 6391218822Sdim contents = bfd_zalloc (output_bfd, s->size); 6392218822Sdim if (contents == NULL) 6393218822Sdim { 6394218822Sdim free (cinfo.bitmask); 6395218822Sdim free (cinfo.hashcodes); 6396218822Sdim return FALSE; 6397218822Sdim } 6398218822Sdim 6399218822Sdim s->contents = contents; 6400218822Sdim bfd_put_32 (output_bfd, bucketcount, contents); 6401218822Sdim bfd_put_32 (output_bfd, cinfo.symindx, contents + 4); 6402218822Sdim bfd_put_32 (output_bfd, maskwords, contents + 8); 6403218822Sdim bfd_put_32 (output_bfd, cinfo.shift2, contents + 12); 6404218822Sdim contents += 16 + cinfo.maskbits / 8; 6405218822Sdim 6406218822Sdim for (i = 0; i < bucketcount; ++i) 6407218822Sdim { 6408218822Sdim if (cinfo.counts[i] == 0) 6409218822Sdim bfd_put_32 (output_bfd, 0, contents); 6410218822Sdim else 6411218822Sdim bfd_put_32 (output_bfd, cinfo.indx[i], contents); 6412218822Sdim contents += 4; 6413218822Sdim } 6414218822Sdim 6415218822Sdim cinfo.contents = contents; 6416218822Sdim 6417218822Sdim /* Renumber dynamic symbols, populate .gnu.hash section. */ 6418218822Sdim elf_link_hash_traverse (elf_hash_table (info), 6419218822Sdim elf_renumber_gnu_hash_syms, &cinfo); 6420218822Sdim 6421218822Sdim contents = s->contents + 16; 6422218822Sdim for (i = 0; i < maskwords; ++i) 6423218822Sdim { 6424218822Sdim bfd_put (bed->s->arch_size, output_bfd, cinfo.bitmask[i], 6425218822Sdim contents); 6426218822Sdim contents += bed->s->arch_size / 8; 6427218822Sdim } 6428218822Sdim 6429218822Sdim free (cinfo.bitmask); 6430218822Sdim free (cinfo.hashcodes); 6431218822Sdim } 6432218822Sdim } 6433218822Sdim 6434130561Sobrien s = bfd_get_section_by_name (dynobj, ".dynstr"); 6435130561Sobrien BFD_ASSERT (s != NULL); 6436130561Sobrien 6437130561Sobrien elf_finalize_dynstr (output_bfd, info); 6438130561Sobrien 6439218822Sdim s->size = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr); 6440130561Sobrien 6441130561Sobrien for (dtagcount = 0; dtagcount <= info->spare_dynamic_tags; ++dtagcount) 6442130561Sobrien if (!_bfd_elf_add_dynamic_entry (info, DT_NULL, 0)) 6443130561Sobrien return FALSE; 6444130561Sobrien } 6445130561Sobrien 6446130561Sobrien return TRUE; 6447130561Sobrien} 6448130561Sobrien 6449130561Sobrien/* Final phase of ELF linker. */ 6450130561Sobrien 6451130561Sobrien/* A structure we use to avoid passing large numbers of arguments. */ 6452130561Sobrien 6453130561Sobrienstruct elf_final_link_info 6454130561Sobrien{ 6455130561Sobrien /* General link information. */ 6456130561Sobrien struct bfd_link_info *info; 6457130561Sobrien /* Output BFD. */ 6458130561Sobrien bfd *output_bfd; 6459130561Sobrien /* Symbol string table. */ 6460130561Sobrien struct bfd_strtab_hash *symstrtab; 6461130561Sobrien /* .dynsym section. */ 6462130561Sobrien asection *dynsym_sec; 6463130561Sobrien /* .hash section. */ 6464130561Sobrien asection *hash_sec; 6465130561Sobrien /* symbol version section (.gnu.version). */ 6466130561Sobrien asection *symver_sec; 6467130561Sobrien /* Buffer large enough to hold contents of any section. */ 6468130561Sobrien bfd_byte *contents; 6469130561Sobrien /* Buffer large enough to hold external relocs of any section. */ 6470130561Sobrien void *external_relocs; 6471130561Sobrien /* Buffer large enough to hold internal relocs of any section. */ 6472130561Sobrien Elf_Internal_Rela *internal_relocs; 6473130561Sobrien /* Buffer large enough to hold external local symbols of any input 6474130561Sobrien BFD. */ 6475130561Sobrien bfd_byte *external_syms; 6476130561Sobrien /* And a buffer for symbol section indices. */ 6477130561Sobrien Elf_External_Sym_Shndx *locsym_shndx; 6478130561Sobrien /* Buffer large enough to hold internal local symbols of any input 6479130561Sobrien BFD. */ 6480130561Sobrien Elf_Internal_Sym *internal_syms; 6481130561Sobrien /* Array large enough to hold a symbol index for each local symbol 6482130561Sobrien of any input BFD. */ 6483130561Sobrien long *indices; 6484130561Sobrien /* Array large enough to hold a section pointer for each local 6485130561Sobrien symbol of any input BFD. */ 6486130561Sobrien asection **sections; 6487130561Sobrien /* Buffer to hold swapped out symbols. */ 6488130561Sobrien bfd_byte *symbuf; 6489130561Sobrien /* And one for symbol section indices. */ 6490130561Sobrien Elf_External_Sym_Shndx *symshndxbuf; 6491130561Sobrien /* Number of swapped out symbols in buffer. */ 6492130561Sobrien size_t symbuf_count; 6493130561Sobrien /* Number of symbols which fit in symbuf. */ 6494130561Sobrien size_t symbuf_size; 6495130561Sobrien /* And same for symshndxbuf. */ 6496130561Sobrien size_t shndxbuf_size; 6497130561Sobrien}; 6498130561Sobrien 6499130561Sobrien/* This struct is used to pass information to elf_link_output_extsym. */ 6500130561Sobrien 6501130561Sobrienstruct elf_outext_info 6502130561Sobrien{ 6503130561Sobrien bfd_boolean failed; 6504130561Sobrien bfd_boolean localsyms; 6505130561Sobrien struct elf_final_link_info *finfo; 6506130561Sobrien}; 6507130561Sobrien 6508218822Sdim 6509218822Sdim/* Support for evaluating a complex relocation. 6510218822Sdim 6511218822Sdim Complex relocations are generalized, self-describing relocations. The 6512218822Sdim implementation of them consists of two parts: complex symbols, and the 6513218822Sdim relocations themselves. 6514218822Sdim 6515218822Sdim The relocations are use a reserved elf-wide relocation type code (R_RELC 6516218822Sdim external / BFD_RELOC_RELC internal) and an encoding of relocation field 6517218822Sdim information (start bit, end bit, word width, etc) into the addend. This 6518218822Sdim information is extracted from CGEN-generated operand tables within gas. 6519218822Sdim 6520218822Sdim Complex symbols are mangled symbols (BSF_RELC external / STT_RELC 6521218822Sdim internal) representing prefix-notation expressions, including but not 6522218822Sdim limited to those sorts of expressions normally encoded as addends in the 6523218822Sdim addend field. The symbol mangling format is: 6524218822Sdim 6525218822Sdim <node> := <literal> 6526218822Sdim | <unary-operator> ':' <node> 6527218822Sdim | <binary-operator> ':' <node> ':' <node> 6528218822Sdim ; 6529218822Sdim 6530218822Sdim <literal> := 's' <digits=N> ':' <N character symbol name> 6531218822Sdim | 'S' <digits=N> ':' <N character section name> 6532218822Sdim | '#' <hexdigits> 6533218822Sdim ; 6534218822Sdim 6535218822Sdim <binary-operator> := as in C 6536218822Sdim <unary-operator> := as in C, plus "0-" for unambiguous negation. */ 6537218822Sdim 6538218822Sdimstatic void 6539218822Sdimset_symbol_value (bfd * bfd_with_globals, 6540218822Sdim struct elf_final_link_info * finfo, 6541218822Sdim int symidx, 6542218822Sdim bfd_vma val) 6543218822Sdim{ 6544218822Sdim bfd_boolean is_local; 6545218822Sdim Elf_Internal_Sym * sym; 6546218822Sdim struct elf_link_hash_entry ** sym_hashes; 6547218822Sdim struct elf_link_hash_entry * h; 6548218822Sdim 6549218822Sdim sym_hashes = elf_sym_hashes (bfd_with_globals); 6550218822Sdim sym = finfo->internal_syms + symidx; 6551218822Sdim is_local = ELF_ST_BIND(sym->st_info) == STB_LOCAL; 6552218822Sdim 6553218822Sdim if (is_local) 6554218822Sdim { 6555218822Sdim /* It is a local symbol: move it to the 6556218822Sdim "absolute" section and give it a value. */ 6557218822Sdim sym->st_shndx = SHN_ABS; 6558218822Sdim sym->st_value = val; 6559218822Sdim } 6560218822Sdim else 6561218822Sdim { 6562218822Sdim /* It is a global symbol: set its link type 6563218822Sdim to "defined" and give it a value. */ 6564218822Sdim h = sym_hashes [symidx]; 6565218822Sdim while (h->root.type == bfd_link_hash_indirect 6566218822Sdim || h->root.type == bfd_link_hash_warning) 6567218822Sdim h = (struct elf_link_hash_entry *) h->root.u.i.link; 6568218822Sdim h->root.type = bfd_link_hash_defined; 6569218822Sdim h->root.u.def.value = val; 6570218822Sdim h->root.u.def.section = bfd_abs_section_ptr; 6571218822Sdim } 6572218822Sdim} 6573218822Sdim 6574218822Sdimstatic bfd_boolean 6575218822Sdimresolve_symbol (const char * name, 6576218822Sdim bfd * input_bfd, 6577218822Sdim struct elf_final_link_info * finfo, 6578218822Sdim bfd_vma * result, 6579218822Sdim size_t locsymcount) 6580218822Sdim{ 6581218822Sdim Elf_Internal_Sym * sym; 6582218822Sdim struct bfd_link_hash_entry * global_entry; 6583218822Sdim const char * candidate = NULL; 6584218822Sdim Elf_Internal_Shdr * symtab_hdr; 6585218822Sdim asection * sec = NULL; 6586218822Sdim size_t i; 6587218822Sdim 6588218822Sdim symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr; 6589218822Sdim 6590218822Sdim for (i = 0; i < locsymcount; ++ i) 6591218822Sdim { 6592218822Sdim sym = finfo->internal_syms + i; 6593218822Sdim sec = finfo->sections [i]; 6594218822Sdim 6595218822Sdim if (ELF_ST_BIND (sym->st_info) != STB_LOCAL) 6596218822Sdim continue; 6597218822Sdim 6598218822Sdim candidate = bfd_elf_string_from_elf_section (input_bfd, 6599218822Sdim symtab_hdr->sh_link, 6600218822Sdim sym->st_name); 6601218822Sdim#ifdef DEBUG 6602218822Sdim printf ("Comparing string: '%s' vs. '%s' = 0x%x\n", 6603218822Sdim name, candidate, (unsigned int)sym->st_value); 6604218822Sdim#endif 6605218822Sdim if (candidate && strcmp (candidate, name) == 0) 6606218822Sdim { 6607218822Sdim * result = sym->st_value; 6608218822Sdim 6609218822Sdim if (sym->st_shndx > SHN_UNDEF && 6610218822Sdim sym->st_shndx < SHN_LORESERVE) 6611218822Sdim { 6612218822Sdim#ifdef DEBUG 6613218822Sdim printf ("adjusting for sec '%s' @ 0x%x + 0x%x\n", 6614218822Sdim sec->output_section->name, 6615218822Sdim (unsigned int)sec->output_section->vma, 6616218822Sdim (unsigned int)sec->output_offset); 6617218822Sdim#endif 6618218822Sdim * result += sec->output_offset + sec->output_section->vma; 6619218822Sdim } 6620218822Sdim#ifdef DEBUG 6621218822Sdim printf ("Found symbol with effective value %8.8x\n", (unsigned int)* result); 6622218822Sdim#endif 6623218822Sdim return TRUE; 6624218822Sdim } 6625218822Sdim } 6626218822Sdim 6627218822Sdim /* Hmm, haven't found it yet. perhaps it is a global. */ 6628218822Sdim global_entry = bfd_link_hash_lookup (finfo->info->hash, name, FALSE, FALSE, TRUE); 6629218822Sdim if (!global_entry) 6630218822Sdim return FALSE; 6631218822Sdim 6632218822Sdim if (global_entry->type == bfd_link_hash_defined 6633218822Sdim || global_entry->type == bfd_link_hash_defweak) 6634218822Sdim { 6635218822Sdim * result = global_entry->u.def.value 6636218822Sdim + global_entry->u.def.section->output_section->vma 6637218822Sdim + global_entry->u.def.section->output_offset; 6638218822Sdim#ifdef DEBUG 6639218822Sdim printf ("Found GLOBAL symbol '%s' with value %8.8x\n", 6640218822Sdim global_entry->root.string, (unsigned int)*result); 6641218822Sdim#endif 6642218822Sdim return TRUE; 6643218822Sdim } 6644218822Sdim 6645218822Sdim if (global_entry->type == bfd_link_hash_common) 6646218822Sdim { 6647218822Sdim *result = global_entry->u.def.value + 6648218822Sdim bfd_com_section_ptr->output_section->vma + 6649218822Sdim bfd_com_section_ptr->output_offset; 6650218822Sdim#ifdef DEBUG 6651218822Sdim printf ("Found COMMON symbol '%s' with value %8.8x\n", 6652218822Sdim global_entry->root.string, (unsigned int)*result); 6653218822Sdim#endif 6654218822Sdim return TRUE; 6655218822Sdim } 6656218822Sdim 6657218822Sdim return FALSE; 6658218822Sdim} 6659218822Sdim 6660218822Sdimstatic bfd_boolean 6661218822Sdimresolve_section (const char * name, 6662218822Sdim asection * sections, 6663218822Sdim bfd_vma * result) 6664218822Sdim{ 6665218822Sdim asection * curr; 6666218822Sdim unsigned int len; 6667218822Sdim 6668218822Sdim for (curr = sections; curr; curr = curr->next) 6669218822Sdim if (strcmp (curr->name, name) == 0) 6670218822Sdim { 6671218822Sdim *result = curr->vma; 6672218822Sdim return TRUE; 6673218822Sdim } 6674218822Sdim 6675218822Sdim /* Hmm. still haven't found it. try pseudo-section names. */ 6676218822Sdim for (curr = sections; curr; curr = curr->next) 6677218822Sdim { 6678218822Sdim len = strlen (curr->name); 6679218822Sdim if (len > strlen (name)) 6680218822Sdim continue; 6681218822Sdim 6682218822Sdim if (strncmp (curr->name, name, len) == 0) 6683218822Sdim { 6684218822Sdim if (strncmp (".end", name + len, 4) == 0) 6685218822Sdim { 6686218822Sdim *result = curr->vma + curr->size; 6687218822Sdim return TRUE; 6688218822Sdim } 6689218822Sdim 6690218822Sdim /* Insert more pseudo-section names here, if you like. */ 6691218822Sdim } 6692218822Sdim } 6693218822Sdim 6694218822Sdim return FALSE; 6695218822Sdim} 6696218822Sdim 6697218822Sdimstatic void 6698218822Sdimundefined_reference (const char * reftype, 6699218822Sdim const char * name) 6700218822Sdim{ 6701218822Sdim _bfd_error_handler (_("undefined %s reference in complex symbol: %s"), reftype, name); 6702218822Sdim} 6703218822Sdim 6704218822Sdimstatic bfd_boolean 6705218822Sdimeval_symbol (bfd_vma * result, 6706218822Sdim char * sym, 6707218822Sdim char ** advanced, 6708218822Sdim bfd * input_bfd, 6709218822Sdim struct elf_final_link_info * finfo, 6710218822Sdim bfd_vma addr, 6711218822Sdim bfd_vma section_offset, 6712218822Sdim size_t locsymcount, 6713218822Sdim int signed_p) 6714218822Sdim{ 6715218822Sdim int len; 6716218822Sdim int symlen; 6717218822Sdim bfd_vma a; 6718218822Sdim bfd_vma b; 6719218822Sdim const int bufsz = 4096; 6720218822Sdim char symbuf [bufsz]; 6721218822Sdim const char * symend; 6722218822Sdim bfd_boolean symbol_is_section = FALSE; 6723218822Sdim 6724218822Sdim len = strlen (sym); 6725218822Sdim symend = sym + len; 6726218822Sdim 6727218822Sdim if (len < 1 || len > bufsz) 6728218822Sdim { 6729218822Sdim bfd_set_error (bfd_error_invalid_operation); 6730218822Sdim return FALSE; 6731218822Sdim } 6732218822Sdim 6733218822Sdim switch (* sym) 6734218822Sdim { 6735218822Sdim case '.': 6736218822Sdim * result = addr + section_offset; 6737218822Sdim * advanced = sym + 1; 6738218822Sdim return TRUE; 6739218822Sdim 6740218822Sdim case '#': 6741218822Sdim ++ sym; 6742218822Sdim * result = strtoul (sym, advanced, 16); 6743218822Sdim return TRUE; 6744218822Sdim 6745218822Sdim case 'S': 6746218822Sdim symbol_is_section = TRUE; 6747218822Sdim case 's': 6748218822Sdim ++ sym; 6749218822Sdim symlen = strtol (sym, &sym, 10); 6750218822Sdim ++ sym; /* Skip the trailing ':'. */ 6751218822Sdim 6752218822Sdim if ((symend < sym) || ((symlen + 1) > bufsz)) 6753218822Sdim { 6754218822Sdim bfd_set_error (bfd_error_invalid_operation); 6755218822Sdim return FALSE; 6756218822Sdim } 6757218822Sdim 6758218822Sdim memcpy (symbuf, sym, symlen); 6759218822Sdim symbuf [symlen] = '\0'; 6760218822Sdim * advanced = sym + symlen; 6761218822Sdim 6762218822Sdim /* Is it always possible, with complex symbols, that gas "mis-guessed" 6763218822Sdim the symbol as a section, or vice-versa. so we're pretty liberal in our 6764218822Sdim interpretation here; section means "try section first", not "must be a 6765218822Sdim section", and likewise with symbol. */ 6766218822Sdim 6767218822Sdim if (symbol_is_section) 6768218822Sdim { 6769218822Sdim if ((resolve_section (symbuf, finfo->output_bfd->sections, result) != TRUE) 6770218822Sdim && (resolve_symbol (symbuf, input_bfd, finfo, result, locsymcount) != TRUE)) 6771218822Sdim { 6772218822Sdim undefined_reference ("section", symbuf); 6773218822Sdim return FALSE; 6774218822Sdim } 6775218822Sdim } 6776218822Sdim else 6777218822Sdim { 6778218822Sdim if ((resolve_symbol (symbuf, input_bfd, finfo, result, locsymcount) != TRUE) 6779218822Sdim && (resolve_section (symbuf, finfo->output_bfd->sections, 6780218822Sdim result) != TRUE)) 6781218822Sdim { 6782218822Sdim undefined_reference ("symbol", symbuf); 6783218822Sdim return FALSE; 6784218822Sdim } 6785218822Sdim } 6786218822Sdim 6787218822Sdim return TRUE; 6788218822Sdim 6789218822Sdim /* All that remains are operators. */ 6790218822Sdim 6791218822Sdim#define UNARY_OP(op) \ 6792218822Sdim if (strncmp (sym, #op, strlen (#op)) == 0) \ 6793218822Sdim { \ 6794218822Sdim sym += strlen (#op); \ 6795218822Sdim if (* sym == ':') \ 6796218822Sdim ++ sym; \ 6797218822Sdim if (eval_symbol (& a, sym, & sym, input_bfd, finfo, addr, \ 6798218822Sdim section_offset, locsymcount, signed_p) \ 6799218822Sdim != TRUE) \ 6800218822Sdim return FALSE; \ 6801218822Sdim if (signed_p) \ 6802218822Sdim * result = op ((signed)a); \ 6803218822Sdim else \ 6804218822Sdim * result = op a; \ 6805218822Sdim * advanced = sym; \ 6806218822Sdim return TRUE; \ 6807218822Sdim } 6808218822Sdim 6809218822Sdim#define BINARY_OP(op) \ 6810218822Sdim if (strncmp (sym, #op, strlen (#op)) == 0) \ 6811218822Sdim { \ 6812218822Sdim sym += strlen (#op); \ 6813218822Sdim if (* sym == ':') \ 6814218822Sdim ++ sym; \ 6815218822Sdim if (eval_symbol (& a, sym, & sym, input_bfd, finfo, addr, \ 6816218822Sdim section_offset, locsymcount, signed_p) \ 6817218822Sdim != TRUE) \ 6818218822Sdim return FALSE; \ 6819218822Sdim ++ sym; \ 6820218822Sdim if (eval_symbol (& b, sym, & sym, input_bfd, finfo, addr, \ 6821218822Sdim section_offset, locsymcount, signed_p) \ 6822218822Sdim != TRUE) \ 6823218822Sdim return FALSE; \ 6824218822Sdim if (signed_p) \ 6825218822Sdim * result = ((signed) a) op ((signed) b); \ 6826218822Sdim else \ 6827218822Sdim * result = a op b; \ 6828218822Sdim * advanced = sym; \ 6829218822Sdim return TRUE; \ 6830218822Sdim } 6831218822Sdim 6832218822Sdim default: 6833218822Sdim UNARY_OP (0-); 6834218822Sdim BINARY_OP (<<); 6835218822Sdim BINARY_OP (>>); 6836218822Sdim BINARY_OP (==); 6837218822Sdim BINARY_OP (!=); 6838218822Sdim BINARY_OP (<=); 6839218822Sdim BINARY_OP (>=); 6840218822Sdim BINARY_OP (&&); 6841218822Sdim BINARY_OP (||); 6842218822Sdim UNARY_OP (~); 6843218822Sdim UNARY_OP (!); 6844218822Sdim BINARY_OP (*); 6845218822Sdim BINARY_OP (/); 6846218822Sdim BINARY_OP (%); 6847218822Sdim BINARY_OP (^); 6848218822Sdim BINARY_OP (|); 6849218822Sdim BINARY_OP (&); 6850218822Sdim BINARY_OP (+); 6851218822Sdim BINARY_OP (-); 6852218822Sdim BINARY_OP (<); 6853218822Sdim BINARY_OP (>); 6854218822Sdim#undef UNARY_OP 6855218822Sdim#undef BINARY_OP 6856218822Sdim _bfd_error_handler (_("unknown operator '%c' in complex symbol"), * sym); 6857218822Sdim bfd_set_error (bfd_error_invalid_operation); 6858218822Sdim return FALSE; 6859218822Sdim } 6860218822Sdim} 6861218822Sdim 6862218822Sdim/* Entry point to evaluator, called from elf_link_input_bfd. */ 6863218822Sdim 6864218822Sdimstatic bfd_boolean 6865218822Sdimevaluate_complex_relocation_symbols (bfd * input_bfd, 6866218822Sdim struct elf_final_link_info * finfo, 6867218822Sdim size_t locsymcount) 6868218822Sdim{ 6869218822Sdim const struct elf_backend_data * bed; 6870218822Sdim Elf_Internal_Shdr * symtab_hdr; 6871218822Sdim struct elf_link_hash_entry ** sym_hashes; 6872218822Sdim asection * reloc_sec; 6873218822Sdim bfd_boolean result = TRUE; 6874218822Sdim 6875218822Sdim /* For each section, we're going to check and see if it has any 6876218822Sdim complex relocations, and we're going to evaluate any of them 6877218822Sdim we can. */ 6878218822Sdim 6879218822Sdim if (finfo->info->relocatable) 6880218822Sdim return TRUE; 6881218822Sdim 6882218822Sdim symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr; 6883218822Sdim sym_hashes = elf_sym_hashes (input_bfd); 6884218822Sdim bed = get_elf_backend_data (input_bfd); 6885218822Sdim 6886218822Sdim for (reloc_sec = input_bfd->sections; reloc_sec; reloc_sec = reloc_sec->next) 6887218822Sdim { 6888218822Sdim Elf_Internal_Rela * internal_relocs; 6889218822Sdim unsigned long i; 6890218822Sdim 6891218822Sdim /* This section was omitted from the link. */ 6892218822Sdim if (! reloc_sec->linker_mark) 6893218822Sdim continue; 6894218822Sdim 6895218822Sdim /* Only process sections containing relocs. */ 6896218822Sdim if ((reloc_sec->flags & SEC_RELOC) == 0) 6897218822Sdim continue; 6898218822Sdim 6899218822Sdim if (reloc_sec->reloc_count == 0) 6900218822Sdim continue; 6901218822Sdim 6902218822Sdim /* Read in the relocs for this section. */ 6903218822Sdim internal_relocs 6904218822Sdim = _bfd_elf_link_read_relocs (input_bfd, reloc_sec, NULL, 6905218822Sdim (Elf_Internal_Rela *) NULL, 6906218822Sdim FALSE); 6907218822Sdim if (internal_relocs == NULL) 6908218822Sdim continue; 6909218822Sdim 6910218822Sdim for (i = reloc_sec->reloc_count; i--;) 6911218822Sdim { 6912218822Sdim Elf_Internal_Rela * rel; 6913218822Sdim char * sym_name; 6914218822Sdim bfd_vma index; 6915218822Sdim Elf_Internal_Sym * sym; 6916218822Sdim bfd_vma result; 6917218822Sdim bfd_vma section_offset; 6918218822Sdim bfd_vma addr; 6919218822Sdim int signed_p = 0; 6920218822Sdim 6921218822Sdim rel = internal_relocs + i; 6922218822Sdim section_offset = reloc_sec->output_section->vma 6923218822Sdim + reloc_sec->output_offset; 6924218822Sdim addr = rel->r_offset; 6925218822Sdim 6926218822Sdim index = ELF32_R_SYM (rel->r_info); 6927218822Sdim if (bed->s->arch_size == 64) 6928218822Sdim index >>= 24; 6929218822Sdim 6930218822Sdim if (index == STN_UNDEF) 6931218822Sdim continue; 6932218822Sdim 6933218822Sdim if (index < locsymcount) 6934218822Sdim { 6935218822Sdim /* The symbol is local. */ 6936218822Sdim sym = finfo->internal_syms + index; 6937218822Sdim 6938218822Sdim /* We're only processing STT_RELC or STT_SRELC type symbols. */ 6939218822Sdim if ((ELF_ST_TYPE (sym->st_info) != STT_RELC) && 6940218822Sdim (ELF_ST_TYPE (sym->st_info) != STT_SRELC)) 6941218822Sdim continue; 6942218822Sdim 6943218822Sdim sym_name = bfd_elf_string_from_elf_section 6944218822Sdim (input_bfd, symtab_hdr->sh_link, sym->st_name); 6945218822Sdim 6946218822Sdim signed_p = (ELF_ST_TYPE (sym->st_info) == STT_SRELC); 6947218822Sdim } 6948218822Sdim else 6949218822Sdim { 6950218822Sdim /* The symbol is global. */ 6951218822Sdim struct elf_link_hash_entry * h; 6952218822Sdim 6953218822Sdim if (elf_bad_symtab (input_bfd)) 6954218822Sdim continue; 6955218822Sdim 6956218822Sdim h = sym_hashes [index - locsymcount]; 6957218822Sdim while ( h->root.type == bfd_link_hash_indirect 6958218822Sdim || h->root.type == bfd_link_hash_warning) 6959218822Sdim h = (struct elf_link_hash_entry *) h->root.u.i.link; 6960218822Sdim 6961218822Sdim if (h->type != STT_RELC && h->type != STT_SRELC) 6962218822Sdim continue; 6963218822Sdim 6964218822Sdim signed_p = (h->type == STT_SRELC); 6965218822Sdim sym_name = (char *) h->root.root.string; 6966218822Sdim } 6967218822Sdim#ifdef DEBUG 6968218822Sdim printf ("Encountered a complex symbol!"); 6969218822Sdim printf (" (input_bfd %s, section %s, reloc %ld\n", 6970218822Sdim input_bfd->filename, reloc_sec->name, i); 6971218822Sdim printf (" symbol: idx %8.8lx, name %s\n", 6972218822Sdim index, sym_name); 6973218822Sdim printf (" reloc : info %8.8lx, addr %8.8lx\n", 6974218822Sdim rel->r_info, addr); 6975218822Sdim printf (" Evaluating '%s' ...\n ", sym_name); 6976218822Sdim#endif 6977218822Sdim if (eval_symbol (& result, sym_name, & sym_name, input_bfd, 6978218822Sdim finfo, addr, section_offset, locsymcount, 6979218822Sdim signed_p)) 6980218822Sdim /* Symbol evaluated OK. Update to absolute value. */ 6981218822Sdim set_symbol_value (input_bfd, finfo, index, result); 6982218822Sdim 6983218822Sdim else 6984218822Sdim result = FALSE; 6985218822Sdim } 6986218822Sdim 6987218822Sdim if (internal_relocs != elf_section_data (reloc_sec)->relocs) 6988218822Sdim free (internal_relocs); 6989218822Sdim } 6990218822Sdim 6991218822Sdim /* If nothing went wrong, then we adjusted 6992218822Sdim everything we wanted to adjust. */ 6993218822Sdim return result; 6994218822Sdim} 6995218822Sdim 6996218822Sdimstatic void 6997218822Sdimput_value (bfd_vma size, 6998218822Sdim unsigned long chunksz, 6999218822Sdim bfd * input_bfd, 7000218822Sdim bfd_vma x, 7001218822Sdim bfd_byte * location) 7002218822Sdim{ 7003218822Sdim location += (size - chunksz); 7004218822Sdim 7005218822Sdim for (; size; size -= chunksz, location -= chunksz, x >>= (chunksz * 8)) 7006218822Sdim { 7007218822Sdim switch (chunksz) 7008218822Sdim { 7009218822Sdim default: 7010218822Sdim case 0: 7011218822Sdim abort (); 7012218822Sdim case 1: 7013218822Sdim bfd_put_8 (input_bfd, x, location); 7014218822Sdim break; 7015218822Sdim case 2: 7016218822Sdim bfd_put_16 (input_bfd, x, location); 7017218822Sdim break; 7018218822Sdim case 4: 7019218822Sdim bfd_put_32 (input_bfd, x, location); 7020218822Sdim break; 7021218822Sdim case 8: 7022218822Sdim#ifdef BFD64 7023218822Sdim bfd_put_64 (input_bfd, x, location); 7024218822Sdim#else 7025218822Sdim abort (); 7026218822Sdim#endif 7027218822Sdim break; 7028218822Sdim } 7029218822Sdim } 7030218822Sdim} 7031218822Sdim 7032218822Sdimstatic bfd_vma 7033218822Sdimget_value (bfd_vma size, 7034218822Sdim unsigned long chunksz, 7035218822Sdim bfd * input_bfd, 7036218822Sdim bfd_byte * location) 7037218822Sdim{ 7038218822Sdim bfd_vma x = 0; 7039218822Sdim 7040218822Sdim for (; size; size -= chunksz, location += chunksz) 7041218822Sdim { 7042218822Sdim switch (chunksz) 7043218822Sdim { 7044218822Sdim default: 7045218822Sdim case 0: 7046218822Sdim abort (); 7047218822Sdim case 1: 7048218822Sdim x = (x << (8 * chunksz)) | bfd_get_8 (input_bfd, location); 7049218822Sdim break; 7050218822Sdim case 2: 7051218822Sdim x = (x << (8 * chunksz)) | bfd_get_16 (input_bfd, location); 7052218822Sdim break; 7053218822Sdim case 4: 7054218822Sdim x = (x << (8 * chunksz)) | bfd_get_32 (input_bfd, location); 7055218822Sdim break; 7056218822Sdim case 8: 7057218822Sdim#ifdef BFD64 7058218822Sdim x = (x << (8 * chunksz)) | bfd_get_64 (input_bfd, location); 7059218822Sdim#else 7060218822Sdim abort (); 7061218822Sdim#endif 7062218822Sdim break; 7063218822Sdim } 7064218822Sdim } 7065218822Sdim return x; 7066218822Sdim} 7067218822Sdim 7068218822Sdimstatic void 7069218822Sdimdecode_complex_addend 7070218822Sdim (unsigned long * start, /* in bits */ 7071218822Sdim unsigned long * oplen, /* in bits */ 7072218822Sdim unsigned long * len, /* in bits */ 7073218822Sdim unsigned long * wordsz, /* in bytes */ 7074218822Sdim unsigned long * chunksz, /* in bytes */ 7075218822Sdim unsigned long * lsb0_p, 7076218822Sdim unsigned long * signed_p, 7077218822Sdim unsigned long * trunc_p, 7078218822Sdim unsigned long encoded) 7079218822Sdim{ 7080218822Sdim * start = encoded & 0x3F; 7081218822Sdim * len = (encoded >> 6) & 0x3F; 7082218822Sdim * oplen = (encoded >> 12) & 0x3F; 7083218822Sdim * wordsz = (encoded >> 18) & 0xF; 7084218822Sdim * chunksz = (encoded >> 22) & 0xF; 7085218822Sdim * lsb0_p = (encoded >> 27) & 1; 7086218822Sdim * signed_p = (encoded >> 28) & 1; 7087218822Sdim * trunc_p = (encoded >> 29) & 1; 7088218822Sdim} 7089218822Sdim 7090218822Sdimvoid 7091218822Sdimbfd_elf_perform_complex_relocation 7092218822Sdim (bfd * output_bfd ATTRIBUTE_UNUSED, 7093218822Sdim struct bfd_link_info * info, 7094218822Sdim bfd * input_bfd, 7095218822Sdim asection * input_section, 7096218822Sdim bfd_byte * contents, 7097218822Sdim Elf_Internal_Rela * rel, 7098218822Sdim Elf_Internal_Sym * local_syms, 7099218822Sdim asection ** local_sections) 7100218822Sdim{ 7101218822Sdim const struct elf_backend_data * bed; 7102218822Sdim Elf_Internal_Shdr * symtab_hdr; 7103218822Sdim asection * sec; 7104218822Sdim bfd_vma relocation = 0, shift, x; 7105218822Sdim bfd_vma r_symndx; 7106218822Sdim bfd_vma mask; 7107218822Sdim unsigned long start, oplen, len, wordsz, 7108218822Sdim chunksz, lsb0_p, signed_p, trunc_p; 7109218822Sdim 7110218822Sdim /* Perform this reloc, since it is complex. 7111218822Sdim (this is not to say that it necessarily refers to a complex 7112218822Sdim symbol; merely that it is a self-describing CGEN based reloc. 7113218822Sdim i.e. the addend has the complete reloc information (bit start, end, 7114218822Sdim word size, etc) encoded within it.). */ 7115218822Sdim r_symndx = ELF32_R_SYM (rel->r_info); 7116218822Sdim bed = get_elf_backend_data (input_bfd); 7117218822Sdim if (bed->s->arch_size == 64) 7118218822Sdim r_symndx >>= 24; 7119218822Sdim 7120218822Sdim#ifdef DEBUG 7121218822Sdim printf ("Performing complex relocation %ld...\n", r_symndx); 7122218822Sdim#endif 7123218822Sdim 7124218822Sdim symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr; 7125218822Sdim if (r_symndx < symtab_hdr->sh_info) 7126218822Sdim { 7127218822Sdim /* The symbol is local. */ 7128218822Sdim Elf_Internal_Sym * sym; 7129218822Sdim 7130218822Sdim sym = local_syms + r_symndx; 7131218822Sdim sec = local_sections [r_symndx]; 7132218822Sdim relocation = sym->st_value; 7133218822Sdim if (sym->st_shndx > SHN_UNDEF && 7134218822Sdim sym->st_shndx < SHN_LORESERVE) 7135218822Sdim relocation += (sec->output_offset + 7136218822Sdim sec->output_section->vma); 7137218822Sdim } 7138218822Sdim else 7139218822Sdim { 7140218822Sdim /* The symbol is global. */ 7141218822Sdim struct elf_link_hash_entry **sym_hashes; 7142218822Sdim struct elf_link_hash_entry * h; 7143218822Sdim 7144218822Sdim sym_hashes = elf_sym_hashes (input_bfd); 7145218822Sdim h = sym_hashes [r_symndx]; 7146218822Sdim 7147218822Sdim while (h->root.type == bfd_link_hash_indirect 7148218822Sdim || h->root.type == bfd_link_hash_warning) 7149218822Sdim h = (struct elf_link_hash_entry *) h->root.u.i.link; 7150218822Sdim 7151218822Sdim if (h->root.type == bfd_link_hash_defined 7152218822Sdim || h->root.type == bfd_link_hash_defweak) 7153218822Sdim { 7154218822Sdim sec = h->root.u.def.section; 7155218822Sdim relocation = h->root.u.def.value; 7156218822Sdim 7157218822Sdim if (! bfd_is_abs_section (sec)) 7158218822Sdim relocation += (sec->output_section->vma 7159218822Sdim + sec->output_offset); 7160218822Sdim } 7161218822Sdim if (h->root.type == bfd_link_hash_undefined 7162218822Sdim && !((*info->callbacks->undefined_symbol) 7163218822Sdim (info, h->root.root.string, input_bfd, 7164218822Sdim input_section, rel->r_offset, 7165218822Sdim info->unresolved_syms_in_objects == RM_GENERATE_ERROR 7166218822Sdim || ELF_ST_VISIBILITY (h->other)))) 7167218822Sdim return; 7168218822Sdim } 7169218822Sdim 7170218822Sdim decode_complex_addend (& start, & oplen, & len, & wordsz, 7171218822Sdim & chunksz, & lsb0_p, & signed_p, 7172218822Sdim & trunc_p, rel->r_addend); 7173218822Sdim 7174218822Sdim mask = (((1L << (len - 1)) - 1) << 1) | 1; 7175218822Sdim 7176218822Sdim if (lsb0_p) 7177218822Sdim shift = (start + 1) - len; 7178218822Sdim else 7179218822Sdim shift = (8 * wordsz) - (start + len); 7180218822Sdim 7181218822Sdim x = get_value (wordsz, chunksz, input_bfd, contents + rel->r_offset); 7182218822Sdim 7183218822Sdim#ifdef DEBUG 7184218822Sdim printf ("Doing complex reloc: " 7185218822Sdim "lsb0? %ld, signed? %ld, trunc? %ld, wordsz %ld, " 7186218822Sdim "chunksz %ld, start %ld, len %ld, oplen %ld\n" 7187218822Sdim " dest: %8.8lx, mask: %8.8lx, reloc: %8.8lx\n", 7188218822Sdim lsb0_p, signed_p, trunc_p, wordsz, chunksz, start, len, 7189218822Sdim oplen, x, mask, relocation); 7190218822Sdim#endif 7191218822Sdim 7192218822Sdim if (! trunc_p) 7193218822Sdim { 7194218822Sdim /* Now do an overflow check. */ 7195218822Sdim if (bfd_check_overflow ((signed_p ? 7196218822Sdim complain_overflow_signed : 7197218822Sdim complain_overflow_unsigned), 7198218822Sdim len, 0, (8 * wordsz), 7199218822Sdim relocation) == bfd_reloc_overflow) 7200218822Sdim (*_bfd_error_handler) 7201218822Sdim ("%s (%s + 0x%lx): relocation overflow: 0x%lx %sdoes not fit " 7202218822Sdim "within 0x%lx", 7203218822Sdim input_bfd->filename, input_section->name, rel->r_offset, 7204218822Sdim relocation, (signed_p ? "(signed) " : ""), mask); 7205218822Sdim } 7206218822Sdim 7207218822Sdim /* Do the deed. */ 7208218822Sdim x = (x & ~(mask << shift)) | ((relocation & mask) << shift); 7209218822Sdim 7210218822Sdim#ifdef DEBUG 7211218822Sdim printf (" relocation: %8.8lx\n" 7212218822Sdim " shifted mask: %8.8lx\n" 7213218822Sdim " shifted/masked reloc: %8.8lx\n" 7214218822Sdim " result: %8.8lx\n", 7215218822Sdim relocation, (mask << shift), 7216218822Sdim ((relocation & mask) << shift), x); 7217218822Sdim#endif 7218218822Sdim put_value (wordsz, chunksz, input_bfd, x, contents + rel->r_offset); 7219218822Sdim} 7220218822Sdim 7221130561Sobrien/* When performing a relocatable link, the input relocations are 7222130561Sobrien preserved. But, if they reference global symbols, the indices 7223130561Sobrien referenced must be updated. Update all the relocations in 7224130561Sobrien REL_HDR (there are COUNT of them), using the data in REL_HASH. */ 7225130561Sobrien 7226130561Sobrienstatic void 7227130561Sobrienelf_link_adjust_relocs (bfd *abfd, 7228130561Sobrien Elf_Internal_Shdr *rel_hdr, 7229130561Sobrien unsigned int count, 7230130561Sobrien struct elf_link_hash_entry **rel_hash) 7231130561Sobrien{ 7232130561Sobrien unsigned int i; 7233130561Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 7234130561Sobrien bfd_byte *erela; 7235130561Sobrien void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *); 7236130561Sobrien void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *); 7237130561Sobrien bfd_vma r_type_mask; 7238130561Sobrien int r_sym_shift; 7239130561Sobrien 7240130561Sobrien if (rel_hdr->sh_entsize == bed->s->sizeof_rel) 7241130561Sobrien { 7242130561Sobrien swap_in = bed->s->swap_reloc_in; 7243130561Sobrien swap_out = bed->s->swap_reloc_out; 7244130561Sobrien } 7245130561Sobrien else if (rel_hdr->sh_entsize == bed->s->sizeof_rela) 7246130561Sobrien { 7247130561Sobrien swap_in = bed->s->swap_reloca_in; 7248130561Sobrien swap_out = bed->s->swap_reloca_out; 7249130561Sobrien } 7250130561Sobrien else 7251130561Sobrien abort (); 7252130561Sobrien 7253130561Sobrien if (bed->s->int_rels_per_ext_rel > MAX_INT_RELS_PER_EXT_REL) 7254130561Sobrien abort (); 7255130561Sobrien 7256130561Sobrien if (bed->s->arch_size == 32) 7257130561Sobrien { 7258130561Sobrien r_type_mask = 0xff; 7259130561Sobrien r_sym_shift = 8; 7260130561Sobrien } 7261130561Sobrien else 7262130561Sobrien { 7263130561Sobrien r_type_mask = 0xffffffff; 7264130561Sobrien r_sym_shift = 32; 7265130561Sobrien } 7266130561Sobrien 7267130561Sobrien erela = rel_hdr->contents; 7268130561Sobrien for (i = 0; i < count; i++, rel_hash++, erela += rel_hdr->sh_entsize) 7269130561Sobrien { 7270130561Sobrien Elf_Internal_Rela irela[MAX_INT_RELS_PER_EXT_REL]; 7271130561Sobrien unsigned int j; 7272130561Sobrien 7273130561Sobrien if (*rel_hash == NULL) 7274130561Sobrien continue; 7275130561Sobrien 7276130561Sobrien BFD_ASSERT ((*rel_hash)->indx >= 0); 7277130561Sobrien 7278130561Sobrien (*swap_in) (abfd, erela, irela); 7279130561Sobrien for (j = 0; j < bed->s->int_rels_per_ext_rel; j++) 7280130561Sobrien irela[j].r_info = ((bfd_vma) (*rel_hash)->indx << r_sym_shift 7281130561Sobrien | (irela[j].r_info & r_type_mask)); 7282130561Sobrien (*swap_out) (abfd, irela, erela); 7283130561Sobrien } 7284130561Sobrien} 7285130561Sobrien 7286130561Sobrienstruct elf_link_sort_rela 7287130561Sobrien{ 7288130561Sobrien union { 7289130561Sobrien bfd_vma offset; 7290130561Sobrien bfd_vma sym_mask; 7291130561Sobrien } u; 7292130561Sobrien enum elf_reloc_type_class type; 7293130561Sobrien /* We use this as an array of size int_rels_per_ext_rel. */ 7294130561Sobrien Elf_Internal_Rela rela[1]; 7295130561Sobrien}; 7296130561Sobrien 7297130561Sobrienstatic int 7298130561Sobrienelf_link_sort_cmp1 (const void *A, const void *B) 7299130561Sobrien{ 7300130561Sobrien const struct elf_link_sort_rela *a = A; 7301130561Sobrien const struct elf_link_sort_rela *b = B; 7302130561Sobrien int relativea, relativeb; 7303130561Sobrien 7304130561Sobrien relativea = a->type == reloc_class_relative; 7305130561Sobrien relativeb = b->type == reloc_class_relative; 7306130561Sobrien 7307130561Sobrien if (relativea < relativeb) 7308130561Sobrien return 1; 7309130561Sobrien if (relativea > relativeb) 7310130561Sobrien return -1; 7311130561Sobrien if ((a->rela->r_info & a->u.sym_mask) < (b->rela->r_info & b->u.sym_mask)) 7312130561Sobrien return -1; 7313130561Sobrien if ((a->rela->r_info & a->u.sym_mask) > (b->rela->r_info & b->u.sym_mask)) 7314130561Sobrien return 1; 7315130561Sobrien if (a->rela->r_offset < b->rela->r_offset) 7316130561Sobrien return -1; 7317130561Sobrien if (a->rela->r_offset > b->rela->r_offset) 7318130561Sobrien return 1; 7319130561Sobrien return 0; 7320130561Sobrien} 7321130561Sobrien 7322130561Sobrienstatic int 7323130561Sobrienelf_link_sort_cmp2 (const void *A, const void *B) 7324130561Sobrien{ 7325130561Sobrien const struct elf_link_sort_rela *a = A; 7326130561Sobrien const struct elf_link_sort_rela *b = B; 7327130561Sobrien int copya, copyb; 7328130561Sobrien 7329130561Sobrien if (a->u.offset < b->u.offset) 7330130561Sobrien return -1; 7331130561Sobrien if (a->u.offset > b->u.offset) 7332130561Sobrien return 1; 7333130561Sobrien copya = (a->type == reloc_class_copy) * 2 + (a->type == reloc_class_plt); 7334130561Sobrien copyb = (b->type == reloc_class_copy) * 2 + (b->type == reloc_class_plt); 7335130561Sobrien if (copya < copyb) 7336130561Sobrien return -1; 7337130561Sobrien if (copya > copyb) 7338130561Sobrien return 1; 7339130561Sobrien if (a->rela->r_offset < b->rela->r_offset) 7340130561Sobrien return -1; 7341130561Sobrien if (a->rela->r_offset > b->rela->r_offset) 7342130561Sobrien return 1; 7343130561Sobrien return 0; 7344130561Sobrien} 7345130561Sobrien 7346130561Sobrienstatic size_t 7347130561Sobrienelf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec) 7348130561Sobrien{ 7349218822Sdim asection *dynamic_relocs; 7350218822Sdim asection *rela_dyn; 7351218822Sdim asection *rel_dyn; 7352130561Sobrien bfd_size_type count, size; 7353130561Sobrien size_t i, ret, sort_elt, ext_size; 7354130561Sobrien bfd_byte *sort, *s_non_relative, *p; 7355130561Sobrien struct elf_link_sort_rela *sq; 7356130561Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 7357130561Sobrien int i2e = bed->s->int_rels_per_ext_rel; 7358130561Sobrien void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *); 7359130561Sobrien void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *); 7360130561Sobrien struct bfd_link_order *lo; 7361130561Sobrien bfd_vma r_sym_mask; 7362218822Sdim bfd_boolean use_rela; 7363130561Sobrien 7364218822Sdim /* Find a dynamic reloc section. */ 7365218822Sdim rela_dyn = bfd_get_section_by_name (abfd, ".rela.dyn"); 7366218822Sdim rel_dyn = bfd_get_section_by_name (abfd, ".rel.dyn"); 7367218822Sdim if (rela_dyn != NULL && rela_dyn->size > 0 7368218822Sdim && rel_dyn != NULL && rel_dyn->size > 0) 7369130561Sobrien { 7370218822Sdim bfd_boolean use_rela_initialised = FALSE; 7371218822Sdim 7372218822Sdim /* This is just here to stop gcc from complaining. 7373218822Sdim It's initialization checking code is not perfect. */ 7374218822Sdim use_rela = TRUE; 7375218822Sdim 7376218822Sdim /* Both sections are present. Examine the sizes 7377218822Sdim of the indirect sections to help us choose. */ 7378218822Sdim for (lo = rela_dyn->map_head.link_order; lo != NULL; lo = lo->next) 7379218822Sdim if (lo->type == bfd_indirect_link_order) 7380218822Sdim { 7381218822Sdim asection *o = lo->u.indirect.section; 7382218822Sdim 7383218822Sdim if ((o->size % bed->s->sizeof_rela) == 0) 7384218822Sdim { 7385218822Sdim if ((o->size % bed->s->sizeof_rel) == 0) 7386218822Sdim /* Section size is divisible by both rel and rela sizes. 7387218822Sdim It is of no help to us. */ 7388218822Sdim ; 7389218822Sdim else 7390218822Sdim { 7391218822Sdim /* Section size is only divisible by rela. */ 7392218822Sdim if (use_rela_initialised && (use_rela == FALSE)) 7393218822Sdim { 7394218822Sdim _bfd_error_handler 7395218822Sdim (_("%B: Unable to sort relocs - they are in more than one size"), abfd); 7396218822Sdim bfd_set_error (bfd_error_invalid_operation); 7397218822Sdim return 0; 7398218822Sdim } 7399218822Sdim else 7400218822Sdim { 7401218822Sdim use_rela = TRUE; 7402218822Sdim use_rela_initialised = TRUE; 7403218822Sdim } 7404218822Sdim } 7405218822Sdim } 7406218822Sdim else if ((o->size % bed->s->sizeof_rel) == 0) 7407218822Sdim { 7408218822Sdim /* Section size is only divisible by rel. */ 7409218822Sdim if (use_rela_initialised && (use_rela == TRUE)) 7410218822Sdim { 7411218822Sdim _bfd_error_handler 7412218822Sdim (_("%B: Unable to sort relocs - they are in more than one size"), abfd); 7413218822Sdim bfd_set_error (bfd_error_invalid_operation); 7414218822Sdim return 0; 7415218822Sdim } 7416218822Sdim else 7417218822Sdim { 7418218822Sdim use_rela = FALSE; 7419218822Sdim use_rela_initialised = TRUE; 7420218822Sdim } 7421218822Sdim } 7422218822Sdim else 7423218822Sdim { 7424218822Sdim /* The section size is not divisible by either - something is wrong. */ 7425218822Sdim _bfd_error_handler 7426218822Sdim (_("%B: Unable to sort relocs - they are of an unknown size"), abfd); 7427218822Sdim bfd_set_error (bfd_error_invalid_operation); 7428218822Sdim return 0; 7429218822Sdim } 7430218822Sdim } 7431218822Sdim 7432218822Sdim for (lo = rel_dyn->map_head.link_order; lo != NULL; lo = lo->next) 7433218822Sdim if (lo->type == bfd_indirect_link_order) 7434218822Sdim { 7435218822Sdim asection *o = lo->u.indirect.section; 7436218822Sdim 7437218822Sdim if ((o->size % bed->s->sizeof_rela) == 0) 7438218822Sdim { 7439218822Sdim if ((o->size % bed->s->sizeof_rel) == 0) 7440218822Sdim /* Section size is divisible by both rel and rela sizes. 7441218822Sdim It is of no help to us. */ 7442218822Sdim ; 7443218822Sdim else 7444218822Sdim { 7445218822Sdim /* Section size is only divisible by rela. */ 7446218822Sdim if (use_rela_initialised && (use_rela == FALSE)) 7447218822Sdim { 7448218822Sdim _bfd_error_handler 7449218822Sdim (_("%B: Unable to sort relocs - they are in more than one size"), abfd); 7450218822Sdim bfd_set_error (bfd_error_invalid_operation); 7451218822Sdim return 0; 7452218822Sdim } 7453218822Sdim else 7454218822Sdim { 7455218822Sdim use_rela = TRUE; 7456218822Sdim use_rela_initialised = TRUE; 7457218822Sdim } 7458218822Sdim } 7459218822Sdim } 7460218822Sdim else if ((o->size % bed->s->sizeof_rel) == 0) 7461218822Sdim { 7462218822Sdim /* Section size is only divisible by rel. */ 7463218822Sdim if (use_rela_initialised && (use_rela == TRUE)) 7464218822Sdim { 7465218822Sdim _bfd_error_handler 7466218822Sdim (_("%B: Unable to sort relocs - they are in more than one size"), abfd); 7467218822Sdim bfd_set_error (bfd_error_invalid_operation); 7468218822Sdim return 0; 7469218822Sdim } 7470218822Sdim else 7471218822Sdim { 7472218822Sdim use_rela = FALSE; 7473218822Sdim use_rela_initialised = TRUE; 7474218822Sdim } 7475218822Sdim } 7476218822Sdim else 7477218822Sdim { 7478218822Sdim /* The section size is not divisible by either - something is wrong. */ 7479218822Sdim _bfd_error_handler 7480218822Sdim (_("%B: Unable to sort relocs - they are of an unknown size"), abfd); 7481218822Sdim bfd_set_error (bfd_error_invalid_operation); 7482218822Sdim return 0; 7483218822Sdim } 7484218822Sdim } 7485218822Sdim 7486218822Sdim if (! use_rela_initialised) 7487218822Sdim /* Make a guess. */ 7488218822Sdim use_rela = TRUE; 7489130561Sobrien } 7490218822Sdim else if (rela_dyn != NULL && rela_dyn->size > 0) 7491218822Sdim use_rela = TRUE; 7492218822Sdim else if (rel_dyn != NULL && rel_dyn->size > 0) 7493218822Sdim use_rela = FALSE; 7494130561Sobrien else 7495218822Sdim return 0; 7496218822Sdim 7497218822Sdim if (use_rela) 7498130561Sobrien { 7499218822Sdim dynamic_relocs = rela_dyn; 7500130561Sobrien ext_size = bed->s->sizeof_rela; 7501130561Sobrien swap_in = bed->s->swap_reloca_in; 7502130561Sobrien swap_out = bed->s->swap_reloca_out; 7503130561Sobrien } 7504218822Sdim else 7505218822Sdim { 7506218822Sdim dynamic_relocs = rel_dyn; 7507218822Sdim ext_size = bed->s->sizeof_rel; 7508218822Sdim swap_in = bed->s->swap_reloc_in; 7509218822Sdim swap_out = bed->s->swap_reloc_out; 7510218822Sdim } 7511130561Sobrien 7512130561Sobrien size = 0; 7513218822Sdim for (lo = dynamic_relocs->map_head.link_order; lo != NULL; lo = lo->next) 7514130561Sobrien if (lo->type == bfd_indirect_link_order) 7515218822Sdim size += lo->u.indirect.section->size; 7516130561Sobrien 7517218822Sdim if (size != dynamic_relocs->size) 7518130561Sobrien return 0; 7519130561Sobrien 7520130561Sobrien sort_elt = (sizeof (struct elf_link_sort_rela) 7521130561Sobrien + (i2e - 1) * sizeof (Elf_Internal_Rela)); 7522218822Sdim 7523218822Sdim count = dynamic_relocs->size / ext_size; 7524130561Sobrien sort = bfd_zmalloc (sort_elt * count); 7525218822Sdim 7526130561Sobrien if (sort == NULL) 7527130561Sobrien { 7528130561Sobrien (*info->callbacks->warning) 7529130561Sobrien (info, _("Not enough memory to sort relocations"), 0, abfd, 0, 0); 7530130561Sobrien return 0; 7531130561Sobrien } 7532130561Sobrien 7533130561Sobrien if (bed->s->arch_size == 32) 7534130561Sobrien r_sym_mask = ~(bfd_vma) 0xff; 7535130561Sobrien else 7536130561Sobrien r_sym_mask = ~(bfd_vma) 0xffffffff; 7537130561Sobrien 7538218822Sdim for (lo = dynamic_relocs->map_head.link_order; lo != NULL; lo = lo->next) 7539130561Sobrien if (lo->type == bfd_indirect_link_order) 7540130561Sobrien { 7541130561Sobrien bfd_byte *erel, *erelend; 7542130561Sobrien asection *o = lo->u.indirect.section; 7543130561Sobrien 7544218822Sdim if (o->contents == NULL && o->size != 0) 7545218822Sdim { 7546218822Sdim /* This is a reloc section that is being handled as a normal 7547218822Sdim section. See bfd_section_from_shdr. We can't combine 7548218822Sdim relocs in this case. */ 7549218822Sdim free (sort); 7550218822Sdim return 0; 7551218822Sdim } 7552130561Sobrien erel = o->contents; 7553218822Sdim erelend = o->contents + o->size; 7554130561Sobrien p = sort + o->output_offset / ext_size * sort_elt; 7555218822Sdim 7556130561Sobrien while (erel < erelend) 7557130561Sobrien { 7558130561Sobrien struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p; 7559218822Sdim 7560130561Sobrien (*swap_in) (abfd, erel, s->rela); 7561130561Sobrien s->type = (*bed->elf_backend_reloc_type_class) (s->rela); 7562130561Sobrien s->u.sym_mask = r_sym_mask; 7563130561Sobrien p += sort_elt; 7564130561Sobrien erel += ext_size; 7565130561Sobrien } 7566130561Sobrien } 7567130561Sobrien 7568130561Sobrien qsort (sort, count, sort_elt, elf_link_sort_cmp1); 7569130561Sobrien 7570130561Sobrien for (i = 0, p = sort; i < count; i++, p += sort_elt) 7571130561Sobrien { 7572130561Sobrien struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p; 7573130561Sobrien if (s->type != reloc_class_relative) 7574130561Sobrien break; 7575130561Sobrien } 7576130561Sobrien ret = i; 7577130561Sobrien s_non_relative = p; 7578130561Sobrien 7579130561Sobrien sq = (struct elf_link_sort_rela *) s_non_relative; 7580130561Sobrien for (; i < count; i++, p += sort_elt) 7581130561Sobrien { 7582130561Sobrien struct elf_link_sort_rela *sp = (struct elf_link_sort_rela *) p; 7583130561Sobrien if (((sp->rela->r_info ^ sq->rela->r_info) & r_sym_mask) != 0) 7584130561Sobrien sq = sp; 7585130561Sobrien sp->u.offset = sq->rela->r_offset; 7586130561Sobrien } 7587130561Sobrien 7588130561Sobrien qsort (s_non_relative, count - ret, sort_elt, elf_link_sort_cmp2); 7589130561Sobrien 7590218822Sdim for (lo = dynamic_relocs->map_head.link_order; lo != NULL; lo = lo->next) 7591130561Sobrien if (lo->type == bfd_indirect_link_order) 7592130561Sobrien { 7593130561Sobrien bfd_byte *erel, *erelend; 7594130561Sobrien asection *o = lo->u.indirect.section; 7595130561Sobrien 7596130561Sobrien erel = o->contents; 7597218822Sdim erelend = o->contents + o->size; 7598130561Sobrien p = sort + o->output_offset / ext_size * sort_elt; 7599130561Sobrien while (erel < erelend) 7600130561Sobrien { 7601130561Sobrien struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p; 7602130561Sobrien (*swap_out) (abfd, s->rela, erel); 7603130561Sobrien p += sort_elt; 7604130561Sobrien erel += ext_size; 7605130561Sobrien } 7606130561Sobrien } 7607130561Sobrien 7608130561Sobrien free (sort); 7609218822Sdim *psec = dynamic_relocs; 7610130561Sobrien return ret; 7611130561Sobrien} 7612130561Sobrien 7613130561Sobrien/* Flush the output symbols to the file. */ 7614130561Sobrien 7615130561Sobrienstatic bfd_boolean 7616130561Sobrienelf_link_flush_output_syms (struct elf_final_link_info *finfo, 7617130561Sobrien const struct elf_backend_data *bed) 7618130561Sobrien{ 7619130561Sobrien if (finfo->symbuf_count > 0) 7620130561Sobrien { 7621130561Sobrien Elf_Internal_Shdr *hdr; 7622130561Sobrien file_ptr pos; 7623130561Sobrien bfd_size_type amt; 7624130561Sobrien 7625130561Sobrien hdr = &elf_tdata (finfo->output_bfd)->symtab_hdr; 7626130561Sobrien pos = hdr->sh_offset + hdr->sh_size; 7627130561Sobrien amt = finfo->symbuf_count * bed->s->sizeof_sym; 7628130561Sobrien if (bfd_seek (finfo->output_bfd, pos, SEEK_SET) != 0 7629130561Sobrien || bfd_bwrite (finfo->symbuf, amt, finfo->output_bfd) != amt) 7630130561Sobrien return FALSE; 7631130561Sobrien 7632130561Sobrien hdr->sh_size += amt; 7633130561Sobrien finfo->symbuf_count = 0; 7634130561Sobrien } 7635130561Sobrien 7636130561Sobrien return TRUE; 7637130561Sobrien} 7638130561Sobrien 7639130561Sobrien/* Add a symbol to the output symbol table. */ 7640130561Sobrien 7641130561Sobrienstatic bfd_boolean 7642130561Sobrienelf_link_output_sym (struct elf_final_link_info *finfo, 7643130561Sobrien const char *name, 7644130561Sobrien Elf_Internal_Sym *elfsym, 7645130561Sobrien asection *input_sec, 7646130561Sobrien struct elf_link_hash_entry *h) 7647130561Sobrien{ 7648130561Sobrien bfd_byte *dest; 7649130561Sobrien Elf_External_Sym_Shndx *destshndx; 7650130561Sobrien bfd_boolean (*output_symbol_hook) 7651130561Sobrien (struct bfd_link_info *, const char *, Elf_Internal_Sym *, asection *, 7652130561Sobrien struct elf_link_hash_entry *); 7653130561Sobrien const struct elf_backend_data *bed; 7654130561Sobrien 7655130561Sobrien bed = get_elf_backend_data (finfo->output_bfd); 7656130561Sobrien output_symbol_hook = bed->elf_backend_link_output_symbol_hook; 7657130561Sobrien if (output_symbol_hook != NULL) 7658130561Sobrien { 7659130561Sobrien if (! (*output_symbol_hook) (finfo->info, name, elfsym, input_sec, h)) 7660130561Sobrien return FALSE; 7661130561Sobrien } 7662130561Sobrien 7663130561Sobrien if (name == NULL || *name == '\0') 7664130561Sobrien elfsym->st_name = 0; 7665130561Sobrien else if (input_sec->flags & SEC_EXCLUDE) 7666130561Sobrien elfsym->st_name = 0; 7667130561Sobrien else 7668130561Sobrien { 7669130561Sobrien elfsym->st_name = (unsigned long) _bfd_stringtab_add (finfo->symstrtab, 7670130561Sobrien name, TRUE, FALSE); 7671130561Sobrien if (elfsym->st_name == (unsigned long) -1) 7672130561Sobrien return FALSE; 7673130561Sobrien } 7674130561Sobrien 7675130561Sobrien if (finfo->symbuf_count >= finfo->symbuf_size) 7676130561Sobrien { 7677130561Sobrien if (! elf_link_flush_output_syms (finfo, bed)) 7678130561Sobrien return FALSE; 7679130561Sobrien } 7680130561Sobrien 7681130561Sobrien dest = finfo->symbuf + finfo->symbuf_count * bed->s->sizeof_sym; 7682130561Sobrien destshndx = finfo->symshndxbuf; 7683130561Sobrien if (destshndx != NULL) 7684130561Sobrien { 7685130561Sobrien if (bfd_get_symcount (finfo->output_bfd) >= finfo->shndxbuf_size) 7686130561Sobrien { 7687130561Sobrien bfd_size_type amt; 7688130561Sobrien 7689130561Sobrien amt = finfo->shndxbuf_size * sizeof (Elf_External_Sym_Shndx); 7690130561Sobrien finfo->symshndxbuf = destshndx = bfd_realloc (destshndx, amt * 2); 7691130561Sobrien if (destshndx == NULL) 7692130561Sobrien return FALSE; 7693130561Sobrien memset ((char *) destshndx + amt, 0, amt); 7694130561Sobrien finfo->shndxbuf_size *= 2; 7695130561Sobrien } 7696130561Sobrien destshndx += bfd_get_symcount (finfo->output_bfd); 7697130561Sobrien } 7698130561Sobrien 7699130561Sobrien bed->s->swap_symbol_out (finfo->output_bfd, elfsym, dest, destshndx); 7700130561Sobrien finfo->symbuf_count += 1; 7701130561Sobrien bfd_get_symcount (finfo->output_bfd) += 1; 7702130561Sobrien 7703130561Sobrien return TRUE; 7704130561Sobrien} 7705130561Sobrien 7706218822Sdim/* Return TRUE if the dynamic symbol SYM in ABFD is supported. */ 7707218822Sdim 7708218822Sdimstatic bfd_boolean 7709218822Sdimcheck_dynsym (bfd *abfd, Elf_Internal_Sym *sym) 7710218822Sdim{ 7711218822Sdim if (sym->st_shndx > SHN_HIRESERVE) 7712218822Sdim { 7713218822Sdim /* The gABI doesn't support dynamic symbols in output sections 7714218822Sdim beyond 64k. */ 7715218822Sdim (*_bfd_error_handler) 7716218822Sdim (_("%B: Too many sections: %d (>= %d)"), 7717218822Sdim abfd, bfd_count_sections (abfd), SHN_LORESERVE); 7718218822Sdim bfd_set_error (bfd_error_nonrepresentable_section); 7719218822Sdim return FALSE; 7720218822Sdim } 7721218822Sdim return TRUE; 7722218822Sdim} 7723218822Sdim 7724130561Sobrien/* For DSOs loaded in via a DT_NEEDED entry, emulate ld.so in 7725130561Sobrien allowing an unsatisfied unversioned symbol in the DSO to match a 7726130561Sobrien versioned symbol that would normally require an explicit version. 7727130561Sobrien We also handle the case that a DSO references a hidden symbol 7728130561Sobrien which may be satisfied by a versioned symbol in another DSO. */ 7729130561Sobrien 7730130561Sobrienstatic bfd_boolean 7731130561Sobrienelf_link_check_versioned_symbol (struct bfd_link_info *info, 7732130561Sobrien const struct elf_backend_data *bed, 7733130561Sobrien struct elf_link_hash_entry *h) 7734130561Sobrien{ 7735130561Sobrien bfd *abfd; 7736130561Sobrien struct elf_link_loaded_list *loaded; 7737130561Sobrien 7738130561Sobrien if (!is_elf_hash_table (info->hash)) 7739130561Sobrien return FALSE; 7740130561Sobrien 7741130561Sobrien switch (h->root.type) 7742130561Sobrien { 7743130561Sobrien default: 7744130561Sobrien abfd = NULL; 7745130561Sobrien break; 7746130561Sobrien 7747130561Sobrien case bfd_link_hash_undefined: 7748130561Sobrien case bfd_link_hash_undefweak: 7749130561Sobrien abfd = h->root.u.undef.abfd; 7750130561Sobrien if ((abfd->flags & DYNAMIC) == 0 7751218822Sdim || (elf_dyn_lib_class (abfd) & DYN_DT_NEEDED) == 0) 7752130561Sobrien return FALSE; 7753130561Sobrien break; 7754130561Sobrien 7755130561Sobrien case bfd_link_hash_defined: 7756130561Sobrien case bfd_link_hash_defweak: 7757130561Sobrien abfd = h->root.u.def.section->owner; 7758130561Sobrien break; 7759130561Sobrien 7760130561Sobrien case bfd_link_hash_common: 7761130561Sobrien abfd = h->root.u.c.p->section->owner; 7762130561Sobrien break; 7763130561Sobrien } 7764130561Sobrien BFD_ASSERT (abfd != NULL); 7765130561Sobrien 7766130561Sobrien for (loaded = elf_hash_table (info)->loaded; 7767130561Sobrien loaded != NULL; 7768130561Sobrien loaded = loaded->next) 7769130561Sobrien { 7770130561Sobrien bfd *input; 7771130561Sobrien Elf_Internal_Shdr *hdr; 7772130561Sobrien bfd_size_type symcount; 7773130561Sobrien bfd_size_type extsymcount; 7774130561Sobrien bfd_size_type extsymoff; 7775130561Sobrien Elf_Internal_Shdr *versymhdr; 7776130561Sobrien Elf_Internal_Sym *isym; 7777130561Sobrien Elf_Internal_Sym *isymend; 7778130561Sobrien Elf_Internal_Sym *isymbuf; 7779130561Sobrien Elf_External_Versym *ever; 7780130561Sobrien Elf_External_Versym *extversym; 7781130561Sobrien 7782130561Sobrien input = loaded->abfd; 7783130561Sobrien 7784130561Sobrien /* We check each DSO for a possible hidden versioned definition. */ 7785130561Sobrien if (input == abfd 7786130561Sobrien || (input->flags & DYNAMIC) == 0 7787130561Sobrien || elf_dynversym (input) == 0) 7788130561Sobrien continue; 7789130561Sobrien 7790130561Sobrien hdr = &elf_tdata (input)->dynsymtab_hdr; 7791130561Sobrien 7792130561Sobrien symcount = hdr->sh_size / bed->s->sizeof_sym; 7793130561Sobrien if (elf_bad_symtab (input)) 7794130561Sobrien { 7795130561Sobrien extsymcount = symcount; 7796130561Sobrien extsymoff = 0; 7797130561Sobrien } 7798130561Sobrien else 7799130561Sobrien { 7800130561Sobrien extsymcount = symcount - hdr->sh_info; 7801130561Sobrien extsymoff = hdr->sh_info; 7802130561Sobrien } 7803130561Sobrien 7804130561Sobrien if (extsymcount == 0) 7805130561Sobrien continue; 7806130561Sobrien 7807130561Sobrien isymbuf = bfd_elf_get_elf_syms (input, hdr, extsymcount, extsymoff, 7808130561Sobrien NULL, NULL, NULL); 7809130561Sobrien if (isymbuf == NULL) 7810130561Sobrien return FALSE; 7811130561Sobrien 7812130561Sobrien /* Read in any version definitions. */ 7813130561Sobrien versymhdr = &elf_tdata (input)->dynversym_hdr; 7814130561Sobrien extversym = bfd_malloc (versymhdr->sh_size); 7815130561Sobrien if (extversym == NULL) 7816130561Sobrien goto error_ret; 7817130561Sobrien 7818130561Sobrien if (bfd_seek (input, versymhdr->sh_offset, SEEK_SET) != 0 7819130561Sobrien || (bfd_bread (extversym, versymhdr->sh_size, input) 7820130561Sobrien != versymhdr->sh_size)) 7821130561Sobrien { 7822130561Sobrien free (extversym); 7823130561Sobrien error_ret: 7824130561Sobrien free (isymbuf); 7825130561Sobrien return FALSE; 7826130561Sobrien } 7827130561Sobrien 7828130561Sobrien ever = extversym + extsymoff; 7829130561Sobrien isymend = isymbuf + extsymcount; 7830130561Sobrien for (isym = isymbuf; isym < isymend; isym++, ever++) 7831130561Sobrien { 7832130561Sobrien const char *name; 7833130561Sobrien Elf_Internal_Versym iver; 7834130561Sobrien unsigned short version_index; 7835130561Sobrien 7836130561Sobrien if (ELF_ST_BIND (isym->st_info) == STB_LOCAL 7837130561Sobrien || isym->st_shndx == SHN_UNDEF) 7838130561Sobrien continue; 7839130561Sobrien 7840130561Sobrien name = bfd_elf_string_from_elf_section (input, 7841130561Sobrien hdr->sh_link, 7842130561Sobrien isym->st_name); 7843130561Sobrien if (strcmp (name, h->root.root.string) != 0) 7844130561Sobrien continue; 7845130561Sobrien 7846130561Sobrien _bfd_elf_swap_versym_in (input, ever, &iver); 7847130561Sobrien 7848130561Sobrien if ((iver.vs_vers & VERSYM_HIDDEN) == 0) 7849130561Sobrien { 7850130561Sobrien /* If we have a non-hidden versioned sym, then it should 7851130561Sobrien have provided a definition for the undefined sym. */ 7852130561Sobrien abort (); 7853130561Sobrien } 7854130561Sobrien 7855130561Sobrien version_index = iver.vs_vers & VERSYM_VERSION; 7856130561Sobrien if (version_index == 1 || version_index == 2) 7857130561Sobrien { 7858130561Sobrien /* This is the base or first version. We can use it. */ 7859130561Sobrien free (extversym); 7860130561Sobrien free (isymbuf); 7861130561Sobrien return TRUE; 7862130561Sobrien } 7863130561Sobrien } 7864130561Sobrien 7865130561Sobrien free (extversym); 7866130561Sobrien free (isymbuf); 7867130561Sobrien } 7868130561Sobrien 7869130561Sobrien return FALSE; 7870130561Sobrien} 7871130561Sobrien 7872130561Sobrien/* Add an external symbol to the symbol table. This is called from 7873130561Sobrien the hash table traversal routine. When generating a shared object, 7874130561Sobrien we go through the symbol table twice. The first time we output 7875130561Sobrien anything that might have been forced to local scope in a version 7876130561Sobrien script. The second time we output the symbols that are still 7877130561Sobrien global symbols. */ 7878130561Sobrien 7879130561Sobrienstatic bfd_boolean 7880130561Sobrienelf_link_output_extsym (struct elf_link_hash_entry *h, void *data) 7881130561Sobrien{ 7882130561Sobrien struct elf_outext_info *eoinfo = data; 7883130561Sobrien struct elf_final_link_info *finfo = eoinfo->finfo; 7884130561Sobrien bfd_boolean strip; 7885130561Sobrien Elf_Internal_Sym sym; 7886130561Sobrien asection *input_sec; 7887130561Sobrien const struct elf_backend_data *bed; 7888130561Sobrien 7889130561Sobrien if (h->root.type == bfd_link_hash_warning) 7890130561Sobrien { 7891130561Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 7892130561Sobrien if (h->root.type == bfd_link_hash_new) 7893130561Sobrien return TRUE; 7894130561Sobrien } 7895130561Sobrien 7896130561Sobrien /* Decide whether to output this symbol in this pass. */ 7897130561Sobrien if (eoinfo->localsyms) 7898130561Sobrien { 7899218822Sdim if (!h->forced_local) 7900130561Sobrien return TRUE; 7901130561Sobrien } 7902130561Sobrien else 7903130561Sobrien { 7904218822Sdim if (h->forced_local) 7905130561Sobrien return TRUE; 7906130561Sobrien } 7907130561Sobrien 7908130561Sobrien bed = get_elf_backend_data (finfo->output_bfd); 7909130561Sobrien 7910218822Sdim if (h->root.type == bfd_link_hash_undefined) 7911130561Sobrien { 7912218822Sdim /* If we have an undefined symbol reference here then it must have 7913218822Sdim come from a shared library that is being linked in. (Undefined 7914218822Sdim references in regular files have already been handled). */ 7915218822Sdim bfd_boolean ignore_undef = FALSE; 7916218822Sdim 7917218822Sdim /* Some symbols may be special in that the fact that they're 7918218822Sdim undefined can be safely ignored - let backend determine that. */ 7919218822Sdim if (bed->elf_backend_ignore_undef_symbol) 7920218822Sdim ignore_undef = bed->elf_backend_ignore_undef_symbol (h); 7921218822Sdim 7922218822Sdim /* If we are reporting errors for this situation then do so now. */ 7923218822Sdim if (ignore_undef == FALSE 7924218822Sdim && h->ref_dynamic 7925218822Sdim && ! h->ref_regular 7926218822Sdim && ! elf_link_check_versioned_symbol (finfo->info, bed, h) 7927218822Sdim && finfo->info->unresolved_syms_in_shared_libs != RM_IGNORE) 7928130561Sobrien { 7929218822Sdim if (! (finfo->info->callbacks->undefined_symbol 7930218822Sdim (finfo->info, h->root.root.string, h->root.u.undef.abfd, 7931218822Sdim NULL, 0, finfo->info->unresolved_syms_in_shared_libs == RM_GENERATE_ERROR))) 7932218822Sdim { 7933218822Sdim eoinfo->failed = TRUE; 7934218822Sdim return FALSE; 7935218822Sdim } 7936130561Sobrien } 7937130561Sobrien } 7938130561Sobrien 7939130561Sobrien /* We should also warn if a forced local symbol is referenced from 7940130561Sobrien shared libraries. */ 7941130561Sobrien if (! finfo->info->relocatable 7942130561Sobrien && (! finfo->info->shared) 7943218822Sdim && h->forced_local 7944218822Sdim && h->ref_dynamic 7945218822Sdim && !h->dynamic_def 7946218822Sdim && !h->dynamic_weak 7947130561Sobrien && ! elf_link_check_versioned_symbol (finfo->info, bed, h)) 7948130561Sobrien { 7949130561Sobrien (*_bfd_error_handler) 7950218822Sdim (_("%B: %s symbol `%s' in %B is referenced by DSO"), 7951218822Sdim finfo->output_bfd, 7952218822Sdim h->root.u.def.section == bfd_abs_section_ptr 7953218822Sdim ? finfo->output_bfd : h->root.u.def.section->owner, 7954130561Sobrien ELF_ST_VISIBILITY (h->other) == STV_INTERNAL 7955130561Sobrien ? "internal" 7956130561Sobrien : ELF_ST_VISIBILITY (h->other) == STV_HIDDEN 7957218822Sdim ? "hidden" : "local", 7958218822Sdim h->root.root.string); 7959130561Sobrien eoinfo->failed = TRUE; 7960130561Sobrien return FALSE; 7961130561Sobrien } 7962130561Sobrien 7963130561Sobrien /* We don't want to output symbols that have never been mentioned by 7964130561Sobrien a regular file, or that we have been told to strip. However, if 7965130561Sobrien h->indx is set to -2, the symbol is used by a reloc and we must 7966130561Sobrien output it. */ 7967130561Sobrien if (h->indx == -2) 7968130561Sobrien strip = FALSE; 7969218822Sdim else if ((h->def_dynamic 7970218822Sdim || h->ref_dynamic 7971218822Sdim || h->root.type == bfd_link_hash_new) 7972218822Sdim && !h->def_regular 7973218822Sdim && !h->ref_regular) 7974130561Sobrien strip = TRUE; 7975130561Sobrien else if (finfo->info->strip == strip_all) 7976130561Sobrien strip = TRUE; 7977130561Sobrien else if (finfo->info->strip == strip_some 7978130561Sobrien && bfd_hash_lookup (finfo->info->keep_hash, 7979130561Sobrien h->root.root.string, FALSE, FALSE) == NULL) 7980130561Sobrien strip = TRUE; 7981130561Sobrien else if (finfo->info->strip_discarded 7982130561Sobrien && (h->root.type == bfd_link_hash_defined 7983130561Sobrien || h->root.type == bfd_link_hash_defweak) 7984130561Sobrien && elf_discarded_section (h->root.u.def.section)) 7985130561Sobrien strip = TRUE; 7986130561Sobrien else 7987130561Sobrien strip = FALSE; 7988130561Sobrien 7989130561Sobrien /* If we're stripping it, and it's not a dynamic symbol, there's 7990130561Sobrien nothing else to do unless it is a forced local symbol. */ 7991130561Sobrien if (strip 7992130561Sobrien && h->dynindx == -1 7993218822Sdim && !h->forced_local) 7994130561Sobrien return TRUE; 7995130561Sobrien 7996130561Sobrien sym.st_value = 0; 7997130561Sobrien sym.st_size = h->size; 7998130561Sobrien sym.st_other = h->other; 7999218822Sdim if (h->forced_local) 8000130561Sobrien sym.st_info = ELF_ST_INFO (STB_LOCAL, h->type); 8001130561Sobrien else if (h->root.type == bfd_link_hash_undefweak 8002130561Sobrien || h->root.type == bfd_link_hash_defweak) 8003130561Sobrien sym.st_info = ELF_ST_INFO (STB_WEAK, h->type); 8004130561Sobrien else 8005130561Sobrien sym.st_info = ELF_ST_INFO (STB_GLOBAL, h->type); 8006130561Sobrien 8007130561Sobrien switch (h->root.type) 8008130561Sobrien { 8009130561Sobrien default: 8010130561Sobrien case bfd_link_hash_new: 8011130561Sobrien case bfd_link_hash_warning: 8012130561Sobrien abort (); 8013130561Sobrien return FALSE; 8014130561Sobrien 8015130561Sobrien case bfd_link_hash_undefined: 8016130561Sobrien case bfd_link_hash_undefweak: 8017130561Sobrien input_sec = bfd_und_section_ptr; 8018130561Sobrien sym.st_shndx = SHN_UNDEF; 8019130561Sobrien break; 8020130561Sobrien 8021130561Sobrien case bfd_link_hash_defined: 8022130561Sobrien case bfd_link_hash_defweak: 8023130561Sobrien { 8024130561Sobrien input_sec = h->root.u.def.section; 8025130561Sobrien if (input_sec->output_section != NULL) 8026130561Sobrien { 8027130561Sobrien sym.st_shndx = 8028130561Sobrien _bfd_elf_section_from_bfd_section (finfo->output_bfd, 8029130561Sobrien input_sec->output_section); 8030130561Sobrien if (sym.st_shndx == SHN_BAD) 8031130561Sobrien { 8032130561Sobrien (*_bfd_error_handler) 8033218822Sdim (_("%B: could not find output section %A for input section %A"), 8034218822Sdim finfo->output_bfd, input_sec->output_section, input_sec); 8035130561Sobrien eoinfo->failed = TRUE; 8036130561Sobrien return FALSE; 8037130561Sobrien } 8038130561Sobrien 8039130561Sobrien /* ELF symbols in relocatable files are section relative, 8040130561Sobrien but in nonrelocatable files they are virtual 8041130561Sobrien addresses. */ 8042130561Sobrien sym.st_value = h->root.u.def.value + input_sec->output_offset; 8043130561Sobrien if (! finfo->info->relocatable) 8044130561Sobrien { 8045130561Sobrien sym.st_value += input_sec->output_section->vma; 8046130561Sobrien if (h->type == STT_TLS) 8047130561Sobrien { 8048130561Sobrien /* STT_TLS symbols are relative to PT_TLS segment 8049130561Sobrien base. */ 8050130561Sobrien BFD_ASSERT (elf_hash_table (finfo->info)->tls_sec != NULL); 8051130561Sobrien sym.st_value -= elf_hash_table (finfo->info)->tls_sec->vma; 8052130561Sobrien } 8053130561Sobrien } 8054130561Sobrien } 8055130561Sobrien else 8056130561Sobrien { 8057130561Sobrien BFD_ASSERT (input_sec->owner == NULL 8058130561Sobrien || (input_sec->owner->flags & DYNAMIC) != 0); 8059130561Sobrien sym.st_shndx = SHN_UNDEF; 8060130561Sobrien input_sec = bfd_und_section_ptr; 8061130561Sobrien } 8062130561Sobrien } 8063130561Sobrien break; 8064130561Sobrien 8065130561Sobrien case bfd_link_hash_common: 8066130561Sobrien input_sec = h->root.u.c.p->section; 8067218822Sdim sym.st_shndx = bed->common_section_index (input_sec); 8068130561Sobrien sym.st_value = 1 << h->root.u.c.p->alignment_power; 8069130561Sobrien break; 8070130561Sobrien 8071130561Sobrien case bfd_link_hash_indirect: 8072130561Sobrien /* These symbols are created by symbol versioning. They point 8073130561Sobrien to the decorated version of the name. For example, if the 8074130561Sobrien symbol foo@@GNU_1.2 is the default, which should be used when 8075130561Sobrien foo is used with no version, then we add an indirect symbol 8076130561Sobrien foo which points to foo@@GNU_1.2. We ignore these symbols, 8077130561Sobrien since the indirected symbol is already in the hash table. */ 8078130561Sobrien return TRUE; 8079130561Sobrien } 8080130561Sobrien 8081130561Sobrien /* Give the processor backend a chance to tweak the symbol value, 8082130561Sobrien and also to finish up anything that needs to be done for this 8083130561Sobrien symbol. FIXME: Not calling elf_backend_finish_dynamic_symbol for 8084130561Sobrien forced local syms when non-shared is due to a historical quirk. */ 8085130561Sobrien if ((h->dynindx != -1 8086218822Sdim || h->forced_local) 8087130561Sobrien && ((finfo->info->shared 8088130561Sobrien && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT 8089130561Sobrien || h->root.type != bfd_link_hash_undefweak)) 8090218822Sdim || !h->forced_local) 8091130561Sobrien && elf_hash_table (finfo->info)->dynamic_sections_created) 8092130561Sobrien { 8093130561Sobrien if (! ((*bed->elf_backend_finish_dynamic_symbol) 8094130561Sobrien (finfo->output_bfd, finfo->info, h, &sym))) 8095130561Sobrien { 8096130561Sobrien eoinfo->failed = TRUE; 8097130561Sobrien return FALSE; 8098130561Sobrien } 8099130561Sobrien } 8100130561Sobrien 8101130561Sobrien /* If we are marking the symbol as undefined, and there are no 8102130561Sobrien non-weak references to this symbol from a regular object, then 8103130561Sobrien mark the symbol as weak undefined; if there are non-weak 8104130561Sobrien references, mark the symbol as strong. We can't do this earlier, 8105130561Sobrien because it might not be marked as undefined until the 8106130561Sobrien finish_dynamic_symbol routine gets through with it. */ 8107130561Sobrien if (sym.st_shndx == SHN_UNDEF 8108218822Sdim && h->ref_regular 8109130561Sobrien && (ELF_ST_BIND (sym.st_info) == STB_GLOBAL 8110130561Sobrien || ELF_ST_BIND (sym.st_info) == STB_WEAK)) 8111130561Sobrien { 8112130561Sobrien int bindtype; 8113130561Sobrien 8114218822Sdim if (h->ref_regular_nonweak) 8115130561Sobrien bindtype = STB_GLOBAL; 8116130561Sobrien else 8117130561Sobrien bindtype = STB_WEAK; 8118130561Sobrien sym.st_info = ELF_ST_INFO (bindtype, ELF_ST_TYPE (sym.st_info)); 8119130561Sobrien } 8120130561Sobrien 8121130561Sobrien /* If a non-weak symbol with non-default visibility is not defined 8122130561Sobrien locally, it is a fatal error. */ 8123130561Sobrien if (! finfo->info->relocatable 8124130561Sobrien && ELF_ST_VISIBILITY (sym.st_other) != STV_DEFAULT 8125130561Sobrien && ELF_ST_BIND (sym.st_info) != STB_WEAK 8126130561Sobrien && h->root.type == bfd_link_hash_undefined 8127218822Sdim && !h->def_regular) 8128130561Sobrien { 8129130561Sobrien (*_bfd_error_handler) 8130218822Sdim (_("%B: %s symbol `%s' isn't defined"), 8131218822Sdim finfo->output_bfd, 8132218822Sdim ELF_ST_VISIBILITY (sym.st_other) == STV_PROTECTED 8133218822Sdim ? "protected" 8134218822Sdim : ELF_ST_VISIBILITY (sym.st_other) == STV_INTERNAL 8135218822Sdim ? "internal" : "hidden", 8136218822Sdim h->root.root.string); 8137130561Sobrien eoinfo->failed = TRUE; 8138130561Sobrien return FALSE; 8139130561Sobrien } 8140130561Sobrien 8141130561Sobrien /* If this symbol should be put in the .dynsym section, then put it 8142130561Sobrien there now. We already know the symbol index. We also fill in 8143130561Sobrien the entry in the .hash section. */ 8144130561Sobrien if (h->dynindx != -1 8145130561Sobrien && elf_hash_table (finfo->info)->dynamic_sections_created) 8146130561Sobrien { 8147130561Sobrien bfd_byte *esym; 8148130561Sobrien 8149130561Sobrien sym.st_name = h->dynstr_index; 8150130561Sobrien esym = finfo->dynsym_sec->contents + h->dynindx * bed->s->sizeof_sym; 8151218822Sdim if (! check_dynsym (finfo->output_bfd, &sym)) 8152218822Sdim { 8153218822Sdim eoinfo->failed = TRUE; 8154218822Sdim return FALSE; 8155218822Sdim } 8156130561Sobrien bed->s->swap_symbol_out (finfo->output_bfd, &sym, esym, 0); 8157130561Sobrien 8158218822Sdim if (finfo->hash_sec != NULL) 8159218822Sdim { 8160218822Sdim size_t hash_entry_size; 8161218822Sdim bfd_byte *bucketpos; 8162218822Sdim bfd_vma chain; 8163218822Sdim size_t bucketcount; 8164218822Sdim size_t bucket; 8165130561Sobrien 8166218822Sdim bucketcount = elf_hash_table (finfo->info)->bucketcount; 8167218822Sdim bucket = h->u.elf_hash_value % bucketcount; 8168218822Sdim 8169218822Sdim hash_entry_size 8170218822Sdim = elf_section_data (finfo->hash_sec)->this_hdr.sh_entsize; 8171218822Sdim bucketpos = ((bfd_byte *) finfo->hash_sec->contents 8172218822Sdim + (bucket + 2) * hash_entry_size); 8173218822Sdim chain = bfd_get (8 * hash_entry_size, finfo->output_bfd, bucketpos); 8174218822Sdim bfd_put (8 * hash_entry_size, finfo->output_bfd, h->dynindx, bucketpos); 8175218822Sdim bfd_put (8 * hash_entry_size, finfo->output_bfd, chain, 8176218822Sdim ((bfd_byte *) finfo->hash_sec->contents 8177218822Sdim + (bucketcount + 2 + h->dynindx) * hash_entry_size)); 8178218822Sdim } 8179218822Sdim 8180130561Sobrien if (finfo->symver_sec != NULL && finfo->symver_sec->contents != NULL) 8181130561Sobrien { 8182130561Sobrien Elf_Internal_Versym iversym; 8183130561Sobrien Elf_External_Versym *eversym; 8184130561Sobrien 8185218822Sdim if (!h->def_regular) 8186130561Sobrien { 8187130561Sobrien if (h->verinfo.verdef == NULL) 8188130561Sobrien iversym.vs_vers = 0; 8189130561Sobrien else 8190130561Sobrien iversym.vs_vers = h->verinfo.verdef->vd_exp_refno + 1; 8191130561Sobrien } 8192130561Sobrien else 8193130561Sobrien { 8194130561Sobrien if (h->verinfo.vertree == NULL) 8195130561Sobrien iversym.vs_vers = 1; 8196130561Sobrien else 8197130561Sobrien iversym.vs_vers = h->verinfo.vertree->vernum + 1; 8198218822Sdim if (finfo->info->create_default_symver) 8199218822Sdim iversym.vs_vers++; 8200130561Sobrien } 8201130561Sobrien 8202218822Sdim if (h->hidden) 8203130561Sobrien iversym.vs_vers |= VERSYM_HIDDEN; 8204130561Sobrien 8205130561Sobrien eversym = (Elf_External_Versym *) finfo->symver_sec->contents; 8206130561Sobrien eversym += h->dynindx; 8207130561Sobrien _bfd_elf_swap_versym_out (finfo->output_bfd, &iversym, eversym); 8208130561Sobrien } 8209130561Sobrien } 8210130561Sobrien 8211130561Sobrien /* If we're stripping it, then it was just a dynamic symbol, and 8212130561Sobrien there's nothing else to do. */ 8213130561Sobrien if (strip || (input_sec->flags & SEC_EXCLUDE) != 0) 8214130561Sobrien return TRUE; 8215130561Sobrien 8216130561Sobrien h->indx = bfd_get_symcount (finfo->output_bfd); 8217130561Sobrien 8218130561Sobrien if (! elf_link_output_sym (finfo, h->root.root.string, &sym, input_sec, h)) 8219130561Sobrien { 8220130561Sobrien eoinfo->failed = TRUE; 8221130561Sobrien return FALSE; 8222130561Sobrien } 8223130561Sobrien 8224130561Sobrien return TRUE; 8225130561Sobrien} 8226130561Sobrien 8227218822Sdim/* Return TRUE if special handling is done for relocs in SEC against 8228218822Sdim symbols defined in discarded sections. */ 8229218822Sdim 8230130561Sobrienstatic bfd_boolean 8231130561Sobrienelf_section_ignore_discarded_relocs (asection *sec) 8232130561Sobrien{ 8233130561Sobrien const struct elf_backend_data *bed; 8234130561Sobrien 8235130561Sobrien switch (sec->sec_info_type) 8236130561Sobrien { 8237130561Sobrien case ELF_INFO_TYPE_STABS: 8238130561Sobrien case ELF_INFO_TYPE_EH_FRAME: 8239130561Sobrien return TRUE; 8240130561Sobrien default: 8241130561Sobrien break; 8242130561Sobrien } 8243130561Sobrien 8244130561Sobrien bed = get_elf_backend_data (sec->owner); 8245130561Sobrien if (bed->elf_backend_ignore_discarded_relocs != NULL 8246130561Sobrien && (*bed->elf_backend_ignore_discarded_relocs) (sec)) 8247130561Sobrien return TRUE; 8248130561Sobrien 8249130561Sobrien return FALSE; 8250130561Sobrien} 8251130561Sobrien 8252218822Sdim/* Return a mask saying how ld should treat relocations in SEC against 8253218822Sdim symbols defined in discarded sections. If this function returns 8254218822Sdim COMPLAIN set, ld will issue a warning message. If this function 8255218822Sdim returns PRETEND set, and the discarded section was link-once and the 8256218822Sdim same size as the kept link-once section, ld will pretend that the 8257218822Sdim symbol was actually defined in the kept section. Otherwise ld will 8258218822Sdim zero the reloc (at least that is the intent, but some cooperation by 8259218822Sdim the target dependent code is needed, particularly for REL targets). */ 8260218822Sdim 8261218822Sdimunsigned int 8262218822Sdim_bfd_elf_default_action_discarded (asection *sec) 8263218822Sdim{ 8264218822Sdim if (sec->flags & SEC_DEBUGGING) 8265218822Sdim return PRETEND; 8266218822Sdim 8267218822Sdim if (strcmp (".eh_frame", sec->name) == 0) 8268218822Sdim return 0; 8269218822Sdim 8270218822Sdim if (strcmp (".gcc_except_table", sec->name) == 0) 8271218822Sdim return 0; 8272218822Sdim 8273218822Sdim return COMPLAIN | PRETEND; 8274218822Sdim} 8275218822Sdim 8276218822Sdim/* Find a match between a section and a member of a section group. */ 8277218822Sdim 8278218822Sdimstatic asection * 8279218822Sdimmatch_group_member (asection *sec, asection *group, 8280218822Sdim struct bfd_link_info *info) 8281218822Sdim{ 8282218822Sdim asection *first = elf_next_in_group (group); 8283218822Sdim asection *s = first; 8284218822Sdim 8285218822Sdim while (s != NULL) 8286218822Sdim { 8287218822Sdim if (bfd_elf_match_symbols_in_sections (s, sec, info)) 8288218822Sdim return s; 8289218822Sdim 8290218822Sdim s = elf_next_in_group (s); 8291218822Sdim if (s == first) 8292218822Sdim break; 8293218822Sdim } 8294218822Sdim 8295218822Sdim return NULL; 8296218822Sdim} 8297218822Sdim 8298218822Sdim/* Check if the kept section of a discarded section SEC can be used 8299218822Sdim to replace it. Return the replacement if it is OK. Otherwise return 8300218822Sdim NULL. */ 8301218822Sdim 8302218822Sdimasection * 8303218822Sdim_bfd_elf_check_kept_section (asection *sec, struct bfd_link_info *info) 8304218822Sdim{ 8305218822Sdim asection *kept; 8306218822Sdim 8307218822Sdim kept = sec->kept_section; 8308218822Sdim if (kept != NULL) 8309218822Sdim { 8310218822Sdim if ((kept->flags & SEC_GROUP) != 0) 8311218822Sdim kept = match_group_member (sec, kept, info); 8312218822Sdim if (kept != NULL && sec->size != kept->size) 8313218822Sdim kept = NULL; 8314218822Sdim sec->kept_section = kept; 8315218822Sdim } 8316218822Sdim return kept; 8317218822Sdim} 8318218822Sdim 8319130561Sobrien/* Link an input file into the linker output file. This function 8320130561Sobrien handles all the sections and relocations of the input file at once. 8321130561Sobrien This is so that we only have to read the local symbols once, and 8322130561Sobrien don't have to keep them in memory. */ 8323130561Sobrien 8324130561Sobrienstatic bfd_boolean 8325130561Sobrienelf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd) 8326130561Sobrien{ 8327218822Sdim int (*relocate_section) 8328130561Sobrien (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, 8329130561Sobrien Elf_Internal_Rela *, Elf_Internal_Sym *, asection **); 8330130561Sobrien bfd *output_bfd; 8331130561Sobrien Elf_Internal_Shdr *symtab_hdr; 8332130561Sobrien size_t locsymcount; 8333130561Sobrien size_t extsymoff; 8334130561Sobrien Elf_Internal_Sym *isymbuf; 8335130561Sobrien Elf_Internal_Sym *isym; 8336130561Sobrien Elf_Internal_Sym *isymend; 8337130561Sobrien long *pindex; 8338130561Sobrien asection **ppsection; 8339130561Sobrien asection *o; 8340130561Sobrien const struct elf_backend_data *bed; 8341130561Sobrien struct elf_link_hash_entry **sym_hashes; 8342130561Sobrien 8343130561Sobrien output_bfd = finfo->output_bfd; 8344130561Sobrien bed = get_elf_backend_data (output_bfd); 8345130561Sobrien relocate_section = bed->elf_backend_relocate_section; 8346130561Sobrien 8347130561Sobrien /* If this is a dynamic object, we don't want to do anything here: 8348130561Sobrien we don't want the local symbols, and we don't want the section 8349130561Sobrien contents. */ 8350130561Sobrien if ((input_bfd->flags & DYNAMIC) != 0) 8351130561Sobrien return TRUE; 8352130561Sobrien 8353130561Sobrien symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; 8354130561Sobrien if (elf_bad_symtab (input_bfd)) 8355130561Sobrien { 8356130561Sobrien locsymcount = symtab_hdr->sh_size / bed->s->sizeof_sym; 8357130561Sobrien extsymoff = 0; 8358130561Sobrien } 8359130561Sobrien else 8360130561Sobrien { 8361130561Sobrien locsymcount = symtab_hdr->sh_info; 8362130561Sobrien extsymoff = symtab_hdr->sh_info; 8363130561Sobrien } 8364130561Sobrien 8365130561Sobrien /* Read the local symbols. */ 8366130561Sobrien isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; 8367130561Sobrien if (isymbuf == NULL && locsymcount != 0) 8368130561Sobrien { 8369130561Sobrien isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, locsymcount, 0, 8370130561Sobrien finfo->internal_syms, 8371130561Sobrien finfo->external_syms, 8372130561Sobrien finfo->locsym_shndx); 8373130561Sobrien if (isymbuf == NULL) 8374130561Sobrien return FALSE; 8375130561Sobrien } 8376218822Sdim /* evaluate_complex_relocation_symbols looks for symbols in 8377218822Sdim finfo->internal_syms. */ 8378218822Sdim else if (isymbuf != NULL && locsymcount != 0) 8379218822Sdim { 8380218822Sdim bfd_elf_get_elf_syms (input_bfd, symtab_hdr, locsymcount, 0, 8381218822Sdim finfo->internal_syms, 8382218822Sdim finfo->external_syms, 8383218822Sdim finfo->locsym_shndx); 8384218822Sdim } 8385130561Sobrien 8386130561Sobrien /* Find local symbol sections and adjust values of symbols in 8387130561Sobrien SEC_MERGE sections. Write out those local symbols we know are 8388130561Sobrien going into the output file. */ 8389130561Sobrien isymend = isymbuf + locsymcount; 8390130561Sobrien for (isym = isymbuf, pindex = finfo->indices, ppsection = finfo->sections; 8391130561Sobrien isym < isymend; 8392130561Sobrien isym++, pindex++, ppsection++) 8393130561Sobrien { 8394130561Sobrien asection *isec; 8395130561Sobrien const char *name; 8396130561Sobrien Elf_Internal_Sym osym; 8397130561Sobrien 8398130561Sobrien *pindex = -1; 8399130561Sobrien 8400130561Sobrien if (elf_bad_symtab (input_bfd)) 8401130561Sobrien { 8402130561Sobrien if (ELF_ST_BIND (isym->st_info) != STB_LOCAL) 8403130561Sobrien { 8404130561Sobrien *ppsection = NULL; 8405130561Sobrien continue; 8406130561Sobrien } 8407130561Sobrien } 8408130561Sobrien 8409130561Sobrien if (isym->st_shndx == SHN_UNDEF) 8410130561Sobrien isec = bfd_und_section_ptr; 8411130561Sobrien else if (isym->st_shndx < SHN_LORESERVE 8412130561Sobrien || isym->st_shndx > SHN_HIRESERVE) 8413130561Sobrien { 8414130561Sobrien isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx); 8415130561Sobrien if (isec 8416130561Sobrien && isec->sec_info_type == ELF_INFO_TYPE_MERGE 8417130561Sobrien && ELF_ST_TYPE (isym->st_info) != STT_SECTION) 8418130561Sobrien isym->st_value = 8419130561Sobrien _bfd_merged_section_offset (output_bfd, &isec, 8420130561Sobrien elf_section_data (isec)->sec_info, 8421218822Sdim isym->st_value); 8422130561Sobrien } 8423130561Sobrien else if (isym->st_shndx == SHN_ABS) 8424130561Sobrien isec = bfd_abs_section_ptr; 8425130561Sobrien else if (isym->st_shndx == SHN_COMMON) 8426130561Sobrien isec = bfd_com_section_ptr; 8427130561Sobrien else 8428130561Sobrien { 8429218822Sdim /* Don't attempt to output symbols with st_shnx in the 8430218822Sdim reserved range other than SHN_ABS and SHN_COMMON. */ 8431218822Sdim *ppsection = NULL; 8432218822Sdim continue; 8433130561Sobrien } 8434130561Sobrien 8435130561Sobrien *ppsection = isec; 8436130561Sobrien 8437130561Sobrien /* Don't output the first, undefined, symbol. */ 8438130561Sobrien if (ppsection == finfo->sections) 8439130561Sobrien continue; 8440130561Sobrien 8441130561Sobrien if (ELF_ST_TYPE (isym->st_info) == STT_SECTION) 8442130561Sobrien { 8443130561Sobrien /* We never output section symbols. Instead, we use the 8444130561Sobrien section symbol of the corresponding section in the output 8445130561Sobrien file. */ 8446130561Sobrien continue; 8447130561Sobrien } 8448130561Sobrien 8449130561Sobrien /* If we are stripping all symbols, we don't want to output this 8450130561Sobrien one. */ 8451130561Sobrien if (finfo->info->strip == strip_all) 8452130561Sobrien continue; 8453130561Sobrien 8454130561Sobrien /* If we are discarding all local symbols, we don't want to 8455130561Sobrien output this one. If we are generating a relocatable output 8456130561Sobrien file, then some of the local symbols may be required by 8457130561Sobrien relocs; we output them below as we discover that they are 8458130561Sobrien needed. */ 8459130561Sobrien if (finfo->info->discard == discard_all) 8460130561Sobrien continue; 8461130561Sobrien 8462130561Sobrien /* If this symbol is defined in a section which we are 8463218822Sdim discarding, we don't need to keep it. */ 8464218822Sdim if (isym->st_shndx != SHN_UNDEF 8465218822Sdim && (isym->st_shndx < SHN_LORESERVE || isym->st_shndx > SHN_HIRESERVE) 8466218822Sdim && (isec == NULL 8467218822Sdim || bfd_section_removed_from_list (output_bfd, 8468218822Sdim isec->output_section))) 8469130561Sobrien continue; 8470130561Sobrien 8471130561Sobrien /* Get the name of the symbol. */ 8472130561Sobrien name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, 8473130561Sobrien isym->st_name); 8474130561Sobrien if (name == NULL) 8475130561Sobrien return FALSE; 8476130561Sobrien 8477130561Sobrien /* See if we are discarding symbols with this name. */ 8478130561Sobrien if ((finfo->info->strip == strip_some 8479130561Sobrien && (bfd_hash_lookup (finfo->info->keep_hash, name, FALSE, FALSE) 8480130561Sobrien == NULL)) 8481130561Sobrien || (((finfo->info->discard == discard_sec_merge 8482130561Sobrien && (isec->flags & SEC_MERGE) && ! finfo->info->relocatable) 8483130561Sobrien || finfo->info->discard == discard_l) 8484130561Sobrien && bfd_is_local_label_name (input_bfd, name))) 8485130561Sobrien continue; 8486130561Sobrien 8487130561Sobrien /* If we get here, we are going to output this symbol. */ 8488130561Sobrien 8489130561Sobrien osym = *isym; 8490130561Sobrien 8491130561Sobrien /* Adjust the section index for the output file. */ 8492130561Sobrien osym.st_shndx = _bfd_elf_section_from_bfd_section (output_bfd, 8493130561Sobrien isec->output_section); 8494130561Sobrien if (osym.st_shndx == SHN_BAD) 8495130561Sobrien return FALSE; 8496130561Sobrien 8497130561Sobrien *pindex = bfd_get_symcount (output_bfd); 8498130561Sobrien 8499130561Sobrien /* ELF symbols in relocatable files are section relative, but 8500130561Sobrien in executable files they are virtual addresses. Note that 8501130561Sobrien this code assumes that all ELF sections have an associated 8502130561Sobrien BFD section with a reasonable value for output_offset; below 8503130561Sobrien we assume that they also have a reasonable value for 8504130561Sobrien output_section. Any special sections must be set up to meet 8505130561Sobrien these requirements. */ 8506130561Sobrien osym.st_value += isec->output_offset; 8507130561Sobrien if (! finfo->info->relocatable) 8508130561Sobrien { 8509130561Sobrien osym.st_value += isec->output_section->vma; 8510130561Sobrien if (ELF_ST_TYPE (osym.st_info) == STT_TLS) 8511130561Sobrien { 8512130561Sobrien /* STT_TLS symbols are relative to PT_TLS segment base. */ 8513130561Sobrien BFD_ASSERT (elf_hash_table (finfo->info)->tls_sec != NULL); 8514130561Sobrien osym.st_value -= elf_hash_table (finfo->info)->tls_sec->vma; 8515130561Sobrien } 8516130561Sobrien } 8517130561Sobrien 8518130561Sobrien if (! elf_link_output_sym (finfo, name, &osym, isec, NULL)) 8519130561Sobrien return FALSE; 8520130561Sobrien } 8521130561Sobrien 8522218822Sdim if (! evaluate_complex_relocation_symbols (input_bfd, finfo, locsymcount)) 8523218822Sdim return FALSE; 8524218822Sdim 8525130561Sobrien /* Relocate the contents of each section. */ 8526130561Sobrien sym_hashes = elf_sym_hashes (input_bfd); 8527130561Sobrien for (o = input_bfd->sections; o != NULL; o = o->next) 8528130561Sobrien { 8529130561Sobrien bfd_byte *contents; 8530130561Sobrien 8531130561Sobrien if (! o->linker_mark) 8532130561Sobrien { 8533130561Sobrien /* This section was omitted from the link. */ 8534130561Sobrien continue; 8535130561Sobrien } 8536130561Sobrien 8537130561Sobrien if ((o->flags & SEC_HAS_CONTENTS) == 0 8538218822Sdim || (o->size == 0 && (o->flags & SEC_RELOC) == 0)) 8539130561Sobrien continue; 8540130561Sobrien 8541130561Sobrien if ((o->flags & SEC_LINKER_CREATED) != 0) 8542130561Sobrien { 8543130561Sobrien /* Section was created by _bfd_elf_link_create_dynamic_sections 8544130561Sobrien or somesuch. */ 8545130561Sobrien continue; 8546130561Sobrien } 8547130561Sobrien 8548130561Sobrien /* Get the contents of the section. They have been cached by a 8549130561Sobrien relaxation routine. Note that o is a section in an input 8550130561Sobrien file, so the contents field will not have been set by any of 8551130561Sobrien the routines which work on output files. */ 8552130561Sobrien if (elf_section_data (o)->this_hdr.contents != NULL) 8553130561Sobrien contents = elf_section_data (o)->this_hdr.contents; 8554130561Sobrien else 8555130561Sobrien { 8556218822Sdim bfd_size_type amt = o->rawsize ? o->rawsize : o->size; 8557218822Sdim 8558130561Sobrien contents = finfo->contents; 8559218822Sdim if (! bfd_get_section_contents (input_bfd, o, contents, 0, amt)) 8560130561Sobrien return FALSE; 8561130561Sobrien } 8562130561Sobrien 8563130561Sobrien if ((o->flags & SEC_RELOC) != 0) 8564130561Sobrien { 8565130561Sobrien Elf_Internal_Rela *internal_relocs; 8566130561Sobrien bfd_vma r_type_mask; 8567130561Sobrien int r_sym_shift; 8568218822Sdim int ret; 8569130561Sobrien 8570130561Sobrien /* Get the swapped relocs. */ 8571130561Sobrien internal_relocs 8572130561Sobrien = _bfd_elf_link_read_relocs (input_bfd, o, finfo->external_relocs, 8573130561Sobrien finfo->internal_relocs, FALSE); 8574130561Sobrien if (internal_relocs == NULL 8575130561Sobrien && o->reloc_count > 0) 8576130561Sobrien return FALSE; 8577130561Sobrien 8578130561Sobrien if (bed->s->arch_size == 32) 8579130561Sobrien { 8580130561Sobrien r_type_mask = 0xff; 8581130561Sobrien r_sym_shift = 8; 8582130561Sobrien } 8583130561Sobrien else 8584130561Sobrien { 8585130561Sobrien r_type_mask = 0xffffffff; 8586130561Sobrien r_sym_shift = 32; 8587130561Sobrien } 8588130561Sobrien 8589130561Sobrien /* Run through the relocs looking for any against symbols 8590130561Sobrien from discarded sections and section symbols from 8591130561Sobrien removed link-once sections. Complain about relocs 8592130561Sobrien against discarded sections. Zero relocs against removed 8593218822Sdim link-once sections. */ 8594130561Sobrien if (!elf_section_ignore_discarded_relocs (o)) 8595130561Sobrien { 8596130561Sobrien Elf_Internal_Rela *rel, *relend; 8597218822Sdim unsigned int action = (*bed->action_discarded) (o); 8598130561Sobrien 8599130561Sobrien rel = internal_relocs; 8600130561Sobrien relend = rel + o->reloc_count * bed->s->int_rels_per_ext_rel; 8601130561Sobrien for ( ; rel < relend; rel++) 8602130561Sobrien { 8603130561Sobrien unsigned long r_symndx = rel->r_info >> r_sym_shift; 8604218822Sdim asection **ps, *sec; 8605218822Sdim struct elf_link_hash_entry *h = NULL; 8606218822Sdim const char *sym_name; 8607130561Sobrien 8608218822Sdim if (r_symndx == STN_UNDEF) 8609218822Sdim continue; 8610218822Sdim 8611130561Sobrien if (r_symndx >= locsymcount 8612130561Sobrien || (elf_bad_symtab (input_bfd) 8613130561Sobrien && finfo->sections[r_symndx] == NULL)) 8614130561Sobrien { 8615218822Sdim h = sym_hashes[r_symndx - extsymoff]; 8616130561Sobrien 8617218822Sdim /* Badly formatted input files can contain relocs that 8618218822Sdim reference non-existant symbols. Check here so that 8619218822Sdim we do not seg fault. */ 8620218822Sdim if (h == NULL) 8621218822Sdim { 8622218822Sdim char buffer [32]; 8623218822Sdim 8624218822Sdim sprintf_vma (buffer, rel->r_info); 8625218822Sdim (*_bfd_error_handler) 8626218822Sdim (_("error: %B contains a reloc (0x%s) for section %A " 8627218822Sdim "that references a non-existent global symbol"), 8628218822Sdim input_bfd, o, buffer); 8629218822Sdim bfd_set_error (bfd_error_bad_value); 8630218822Sdim return FALSE; 8631218822Sdim } 8632218822Sdim 8633130561Sobrien while (h->root.type == bfd_link_hash_indirect 8634130561Sobrien || h->root.type == bfd_link_hash_warning) 8635130561Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 8636130561Sobrien 8637218822Sdim if (h->root.type != bfd_link_hash_defined 8638218822Sdim && h->root.type != bfd_link_hash_defweak) 8639218822Sdim continue; 8640218822Sdim 8641218822Sdim ps = &h->root.u.def.section; 8642218822Sdim sym_name = h->root.root.string; 8643130561Sobrien } 8644130561Sobrien else 8645130561Sobrien { 8646218822Sdim Elf_Internal_Sym *sym = isymbuf + r_symndx; 8647218822Sdim ps = &finfo->sections[r_symndx]; 8648218822Sdim sym_name = bfd_elf_sym_name (input_bfd, 8649218822Sdim symtab_hdr, 8650218822Sdim sym, *ps); 8651218822Sdim } 8652130561Sobrien 8653218822Sdim /* Complain if the definition comes from a 8654218822Sdim discarded section. */ 8655218822Sdim if ((sec = *ps) != NULL && elf_discarded_section (sec)) 8656218822Sdim { 8657218822Sdim BFD_ASSERT (r_symndx != 0); 8658218822Sdim if (action & COMPLAIN) 8659218822Sdim (*finfo->info->callbacks->einfo) 8660218822Sdim (_("%X`%s' referenced in section `%A' of %B: " 8661218822Sdim "defined in discarded section `%A' of %B\n"), 8662218822Sdim sym_name, o, input_bfd, sec, sec->owner); 8663218822Sdim 8664218822Sdim /* Try to do the best we can to support buggy old 8665218822Sdim versions of gcc. Pretend that the symbol is 8666218822Sdim really defined in the kept linkonce section. 8667218822Sdim FIXME: This is quite broken. Modifying the 8668218822Sdim symbol here means we will be changing all later 8669218822Sdim uses of the symbol, not just in this section. */ 8670218822Sdim if (action & PRETEND) 8671130561Sobrien { 8672218822Sdim asection *kept; 8673218822Sdim 8674218822Sdim kept = _bfd_elf_check_kept_section (sec, 8675218822Sdim finfo->info); 8676218822Sdim if (kept != NULL) 8677130561Sobrien { 8678218822Sdim *ps = kept; 8679218822Sdim continue; 8680130561Sobrien } 8681130561Sobrien } 8682130561Sobrien } 8683130561Sobrien } 8684130561Sobrien } 8685130561Sobrien 8686130561Sobrien /* Relocate the section by invoking a back end routine. 8687130561Sobrien 8688130561Sobrien The back end routine is responsible for adjusting the 8689130561Sobrien section contents as necessary, and (if using Rela relocs 8690130561Sobrien and generating a relocatable output file) adjusting the 8691130561Sobrien reloc addend as necessary. 8692130561Sobrien 8693130561Sobrien The back end routine does not have to worry about setting 8694130561Sobrien the reloc address or the reloc symbol index. 8695130561Sobrien 8696130561Sobrien The back end routine is given a pointer to the swapped in 8697130561Sobrien internal symbols, and can access the hash table entries 8698130561Sobrien for the external symbols via elf_sym_hashes (input_bfd). 8699130561Sobrien 8700130561Sobrien When generating relocatable output, the back end routine 8701130561Sobrien must handle STB_LOCAL/STT_SECTION symbols specially. The 8702130561Sobrien output symbol is going to be a section symbol 8703130561Sobrien corresponding to the output section, which will require 8704130561Sobrien the addend to be adjusted. */ 8705130561Sobrien 8706218822Sdim ret = (*relocate_section) (output_bfd, finfo->info, 8707130561Sobrien input_bfd, o, contents, 8708130561Sobrien internal_relocs, 8709130561Sobrien isymbuf, 8710218822Sdim finfo->sections); 8711218822Sdim if (!ret) 8712130561Sobrien return FALSE; 8713130561Sobrien 8714218822Sdim if (ret == 2 8715218822Sdim || finfo->info->relocatable 8716218822Sdim || finfo->info->emitrelocations) 8717130561Sobrien { 8718130561Sobrien Elf_Internal_Rela *irela; 8719130561Sobrien Elf_Internal_Rela *irelaend; 8720130561Sobrien bfd_vma last_offset; 8721130561Sobrien struct elf_link_hash_entry **rel_hash; 8722218822Sdim struct elf_link_hash_entry **rel_hash_list; 8723130561Sobrien Elf_Internal_Shdr *input_rel_hdr, *input_rel_hdr2; 8724130561Sobrien unsigned int next_erel; 8725130561Sobrien bfd_boolean rela_normal; 8726130561Sobrien 8727130561Sobrien input_rel_hdr = &elf_section_data (o)->rel_hdr; 8728130561Sobrien rela_normal = (bed->rela_normal 8729130561Sobrien && (input_rel_hdr->sh_entsize 8730130561Sobrien == bed->s->sizeof_rela)); 8731130561Sobrien 8732130561Sobrien /* Adjust the reloc addresses and symbol indices. */ 8733130561Sobrien 8734130561Sobrien irela = internal_relocs; 8735130561Sobrien irelaend = irela + o->reloc_count * bed->s->int_rels_per_ext_rel; 8736130561Sobrien rel_hash = (elf_section_data (o->output_section)->rel_hashes 8737130561Sobrien + elf_section_data (o->output_section)->rel_count 8738130561Sobrien + elf_section_data (o->output_section)->rel_count2); 8739218822Sdim rel_hash_list = rel_hash; 8740130561Sobrien last_offset = o->output_offset; 8741130561Sobrien if (!finfo->info->relocatable) 8742130561Sobrien last_offset += o->output_section->vma; 8743130561Sobrien for (next_erel = 0; irela < irelaend; irela++, next_erel++) 8744130561Sobrien { 8745130561Sobrien unsigned long r_symndx; 8746130561Sobrien asection *sec; 8747130561Sobrien Elf_Internal_Sym sym; 8748130561Sobrien 8749130561Sobrien if (next_erel == bed->s->int_rels_per_ext_rel) 8750130561Sobrien { 8751130561Sobrien rel_hash++; 8752130561Sobrien next_erel = 0; 8753130561Sobrien } 8754130561Sobrien 8755130561Sobrien irela->r_offset = _bfd_elf_section_offset (output_bfd, 8756130561Sobrien finfo->info, o, 8757130561Sobrien irela->r_offset); 8758130561Sobrien if (irela->r_offset >= (bfd_vma) -2) 8759130561Sobrien { 8760130561Sobrien /* This is a reloc for a deleted entry or somesuch. 8761130561Sobrien Turn it into an R_*_NONE reloc, at the same 8762130561Sobrien offset as the last reloc. elf_eh_frame.c and 8763218822Sdim bfd_elf_discard_info rely on reloc offsets 8764130561Sobrien being ordered. */ 8765130561Sobrien irela->r_offset = last_offset; 8766130561Sobrien irela->r_info = 0; 8767130561Sobrien irela->r_addend = 0; 8768130561Sobrien continue; 8769130561Sobrien } 8770130561Sobrien 8771130561Sobrien irela->r_offset += o->output_offset; 8772130561Sobrien 8773130561Sobrien /* Relocs in an executable have to be virtual addresses. */ 8774130561Sobrien if (!finfo->info->relocatable) 8775130561Sobrien irela->r_offset += o->output_section->vma; 8776130561Sobrien 8777130561Sobrien last_offset = irela->r_offset; 8778130561Sobrien 8779130561Sobrien r_symndx = irela->r_info >> r_sym_shift; 8780130561Sobrien if (r_symndx == STN_UNDEF) 8781130561Sobrien continue; 8782130561Sobrien 8783130561Sobrien if (r_symndx >= locsymcount 8784130561Sobrien || (elf_bad_symtab (input_bfd) 8785130561Sobrien && finfo->sections[r_symndx] == NULL)) 8786130561Sobrien { 8787130561Sobrien struct elf_link_hash_entry *rh; 8788130561Sobrien unsigned long indx; 8789130561Sobrien 8790130561Sobrien /* This is a reloc against a global symbol. We 8791130561Sobrien have not yet output all the local symbols, so 8792130561Sobrien we do not know the symbol index of any global 8793130561Sobrien symbol. We set the rel_hash entry for this 8794130561Sobrien reloc to point to the global hash table entry 8795130561Sobrien for this symbol. The symbol index is then 8796218822Sdim set at the end of bfd_elf_final_link. */ 8797130561Sobrien indx = r_symndx - extsymoff; 8798130561Sobrien rh = elf_sym_hashes (input_bfd)[indx]; 8799130561Sobrien while (rh->root.type == bfd_link_hash_indirect 8800130561Sobrien || rh->root.type == bfd_link_hash_warning) 8801130561Sobrien rh = (struct elf_link_hash_entry *) rh->root.u.i.link; 8802130561Sobrien 8803130561Sobrien /* Setting the index to -2 tells 8804130561Sobrien elf_link_output_extsym that this symbol is 8805130561Sobrien used by a reloc. */ 8806130561Sobrien BFD_ASSERT (rh->indx < 0); 8807130561Sobrien rh->indx = -2; 8808130561Sobrien 8809130561Sobrien *rel_hash = rh; 8810130561Sobrien 8811130561Sobrien continue; 8812130561Sobrien } 8813130561Sobrien 8814130561Sobrien /* This is a reloc against a local symbol. */ 8815130561Sobrien 8816130561Sobrien *rel_hash = NULL; 8817130561Sobrien sym = isymbuf[r_symndx]; 8818130561Sobrien sec = finfo->sections[r_symndx]; 8819130561Sobrien if (ELF_ST_TYPE (sym.st_info) == STT_SECTION) 8820130561Sobrien { 8821130561Sobrien /* I suppose the backend ought to fill in the 8822130561Sobrien section of any STT_SECTION symbol against a 8823218822Sdim processor specific section. */ 8824218822Sdim r_symndx = 0; 8825218822Sdim if (bfd_is_abs_section (sec)) 8826218822Sdim ; 8827130561Sobrien else if (sec == NULL || sec->owner == NULL) 8828130561Sobrien { 8829130561Sobrien bfd_set_error (bfd_error_bad_value); 8830130561Sobrien return FALSE; 8831130561Sobrien } 8832130561Sobrien else 8833130561Sobrien { 8834218822Sdim asection *osec = sec->output_section; 8835218822Sdim 8836218822Sdim /* If we have discarded a section, the output 8837218822Sdim section will be the absolute section. In 8838218822Sdim case of discarded SEC_MERGE sections, use 8839218822Sdim the kept section. relocate_section should 8840218822Sdim have already handled discarded linkonce 8841218822Sdim sections. */ 8842218822Sdim if (bfd_is_abs_section (osec) 8843218822Sdim && sec->kept_section != NULL 8844218822Sdim && sec->kept_section->output_section != NULL) 8845218822Sdim { 8846218822Sdim osec = sec->kept_section->output_section; 8847218822Sdim irela->r_addend -= osec->vma; 8848218822Sdim } 8849218822Sdim 8850218822Sdim if (!bfd_is_abs_section (osec)) 8851218822Sdim { 8852218822Sdim r_symndx = osec->target_index; 8853218822Sdim if (r_symndx == 0) 8854218822Sdim { 8855218822Sdim struct elf_link_hash_table *htab; 8856218822Sdim asection *oi; 8857218822Sdim 8858218822Sdim htab = elf_hash_table (finfo->info); 8859218822Sdim oi = htab->text_index_section; 8860218822Sdim if ((osec->flags & SEC_READONLY) == 0 8861218822Sdim && htab->data_index_section != NULL) 8862218822Sdim oi = htab->data_index_section; 8863218822Sdim 8864218822Sdim if (oi != NULL) 8865218822Sdim { 8866218822Sdim irela->r_addend += osec->vma - oi->vma; 8867218822Sdim r_symndx = oi->target_index; 8868218822Sdim } 8869218822Sdim } 8870218822Sdim 8871218822Sdim BFD_ASSERT (r_symndx != 0); 8872218822Sdim } 8873130561Sobrien } 8874130561Sobrien 8875130561Sobrien /* Adjust the addend according to where the 8876130561Sobrien section winds up in the output section. */ 8877130561Sobrien if (rela_normal) 8878130561Sobrien irela->r_addend += sec->output_offset; 8879130561Sobrien } 8880130561Sobrien else 8881130561Sobrien { 8882130561Sobrien if (finfo->indices[r_symndx] == -1) 8883130561Sobrien { 8884130561Sobrien unsigned long shlink; 8885130561Sobrien const char *name; 8886130561Sobrien asection *osec; 8887130561Sobrien 8888130561Sobrien if (finfo->info->strip == strip_all) 8889130561Sobrien { 8890130561Sobrien /* You can't do ld -r -s. */ 8891130561Sobrien bfd_set_error (bfd_error_invalid_operation); 8892130561Sobrien return FALSE; 8893130561Sobrien } 8894130561Sobrien 8895130561Sobrien /* This symbol was skipped earlier, but 8896130561Sobrien since it is needed by a reloc, we 8897130561Sobrien must output it now. */ 8898130561Sobrien shlink = symtab_hdr->sh_link; 8899130561Sobrien name = (bfd_elf_string_from_elf_section 8900130561Sobrien (input_bfd, shlink, sym.st_name)); 8901130561Sobrien if (name == NULL) 8902130561Sobrien return FALSE; 8903130561Sobrien 8904130561Sobrien osec = sec->output_section; 8905130561Sobrien sym.st_shndx = 8906130561Sobrien _bfd_elf_section_from_bfd_section (output_bfd, 8907130561Sobrien osec); 8908130561Sobrien if (sym.st_shndx == SHN_BAD) 8909130561Sobrien return FALSE; 8910130561Sobrien 8911130561Sobrien sym.st_value += sec->output_offset; 8912130561Sobrien if (! finfo->info->relocatable) 8913130561Sobrien { 8914130561Sobrien sym.st_value += osec->vma; 8915130561Sobrien if (ELF_ST_TYPE (sym.st_info) == STT_TLS) 8916130561Sobrien { 8917130561Sobrien /* STT_TLS symbols are relative to PT_TLS 8918130561Sobrien segment base. */ 8919130561Sobrien BFD_ASSERT (elf_hash_table (finfo->info) 8920130561Sobrien ->tls_sec != NULL); 8921130561Sobrien sym.st_value -= (elf_hash_table (finfo->info) 8922130561Sobrien ->tls_sec->vma); 8923130561Sobrien } 8924130561Sobrien } 8925130561Sobrien 8926130561Sobrien finfo->indices[r_symndx] 8927130561Sobrien = bfd_get_symcount (output_bfd); 8928130561Sobrien 8929130561Sobrien if (! elf_link_output_sym (finfo, name, &sym, sec, 8930130561Sobrien NULL)) 8931130561Sobrien return FALSE; 8932130561Sobrien } 8933130561Sobrien 8934130561Sobrien r_symndx = finfo->indices[r_symndx]; 8935130561Sobrien } 8936130561Sobrien 8937130561Sobrien irela->r_info = ((bfd_vma) r_symndx << r_sym_shift 8938130561Sobrien | (irela->r_info & r_type_mask)); 8939130561Sobrien } 8940130561Sobrien 8941130561Sobrien /* Swap out the relocs. */ 8942130561Sobrien if (input_rel_hdr->sh_size != 0 8943218822Sdim && !bed->elf_backend_emit_relocs (output_bfd, o, 8944218822Sdim input_rel_hdr, 8945218822Sdim internal_relocs, 8946218822Sdim rel_hash_list)) 8947130561Sobrien return FALSE; 8948130561Sobrien 8949130561Sobrien input_rel_hdr2 = elf_section_data (o)->rel_hdr2; 8950130561Sobrien if (input_rel_hdr2 && input_rel_hdr2->sh_size != 0) 8951130561Sobrien { 8952130561Sobrien internal_relocs += (NUM_SHDR_ENTRIES (input_rel_hdr) 8953130561Sobrien * bed->s->int_rels_per_ext_rel); 8954218822Sdim rel_hash_list += NUM_SHDR_ENTRIES (input_rel_hdr); 8955218822Sdim if (!bed->elf_backend_emit_relocs (output_bfd, o, 8956218822Sdim input_rel_hdr2, 8957218822Sdim internal_relocs, 8958218822Sdim rel_hash_list)) 8959130561Sobrien return FALSE; 8960130561Sobrien } 8961130561Sobrien } 8962130561Sobrien } 8963130561Sobrien 8964130561Sobrien /* Write out the modified section contents. */ 8965130561Sobrien if (bed->elf_backend_write_section 8966218822Sdim && (*bed->elf_backend_write_section) (output_bfd, finfo->info, o, 8967218822Sdim contents)) 8968130561Sobrien { 8969130561Sobrien /* Section written out. */ 8970130561Sobrien } 8971130561Sobrien else switch (o->sec_info_type) 8972130561Sobrien { 8973130561Sobrien case ELF_INFO_TYPE_STABS: 8974130561Sobrien if (! (_bfd_write_section_stabs 8975130561Sobrien (output_bfd, 8976130561Sobrien &elf_hash_table (finfo->info)->stab_info, 8977130561Sobrien o, &elf_section_data (o)->sec_info, contents))) 8978130561Sobrien return FALSE; 8979130561Sobrien break; 8980130561Sobrien case ELF_INFO_TYPE_MERGE: 8981130561Sobrien if (! _bfd_write_merged_section (output_bfd, o, 8982130561Sobrien elf_section_data (o)->sec_info)) 8983130561Sobrien return FALSE; 8984130561Sobrien break; 8985130561Sobrien case ELF_INFO_TYPE_EH_FRAME: 8986130561Sobrien { 8987130561Sobrien if (! _bfd_elf_write_section_eh_frame (output_bfd, finfo->info, 8988130561Sobrien o, contents)) 8989130561Sobrien return FALSE; 8990130561Sobrien } 8991130561Sobrien break; 8992130561Sobrien default: 8993130561Sobrien { 8994130561Sobrien if (! (o->flags & SEC_EXCLUDE) 8995130561Sobrien && ! bfd_set_section_contents (output_bfd, o->output_section, 8996130561Sobrien contents, 8997130561Sobrien (file_ptr) o->output_offset, 8998218822Sdim o->size)) 8999130561Sobrien return FALSE; 9000130561Sobrien } 9001130561Sobrien break; 9002130561Sobrien } 9003130561Sobrien } 9004130561Sobrien 9005130561Sobrien return TRUE; 9006130561Sobrien} 9007130561Sobrien 9008130561Sobrien/* Generate a reloc when linking an ELF file. This is a reloc 9009218822Sdim requested by the linker, and does not come from any input file. This 9010130561Sobrien is used to build constructor and destructor tables when linking 9011130561Sobrien with -Ur. */ 9012130561Sobrien 9013130561Sobrienstatic bfd_boolean 9014130561Sobrienelf_reloc_link_order (bfd *output_bfd, 9015130561Sobrien struct bfd_link_info *info, 9016130561Sobrien asection *output_section, 9017130561Sobrien struct bfd_link_order *link_order) 9018130561Sobrien{ 9019130561Sobrien reloc_howto_type *howto; 9020130561Sobrien long indx; 9021130561Sobrien bfd_vma offset; 9022130561Sobrien bfd_vma addend; 9023130561Sobrien struct elf_link_hash_entry **rel_hash_ptr; 9024130561Sobrien Elf_Internal_Shdr *rel_hdr; 9025130561Sobrien const struct elf_backend_data *bed = get_elf_backend_data (output_bfd); 9026130561Sobrien Elf_Internal_Rela irel[MAX_INT_RELS_PER_EXT_REL]; 9027130561Sobrien bfd_byte *erel; 9028130561Sobrien unsigned int i; 9029130561Sobrien 9030130561Sobrien howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc); 9031130561Sobrien if (howto == NULL) 9032130561Sobrien { 9033130561Sobrien bfd_set_error (bfd_error_bad_value); 9034130561Sobrien return FALSE; 9035130561Sobrien } 9036130561Sobrien 9037130561Sobrien addend = link_order->u.reloc.p->addend; 9038130561Sobrien 9039130561Sobrien /* Figure out the symbol index. */ 9040130561Sobrien rel_hash_ptr = (elf_section_data (output_section)->rel_hashes 9041130561Sobrien + elf_section_data (output_section)->rel_count 9042130561Sobrien + elf_section_data (output_section)->rel_count2); 9043130561Sobrien if (link_order->type == bfd_section_reloc_link_order) 9044130561Sobrien { 9045130561Sobrien indx = link_order->u.reloc.p->u.section->target_index; 9046130561Sobrien BFD_ASSERT (indx != 0); 9047130561Sobrien *rel_hash_ptr = NULL; 9048130561Sobrien } 9049130561Sobrien else 9050130561Sobrien { 9051130561Sobrien struct elf_link_hash_entry *h; 9052130561Sobrien 9053130561Sobrien /* Treat a reloc against a defined symbol as though it were 9054130561Sobrien actually against the section. */ 9055130561Sobrien h = ((struct elf_link_hash_entry *) 9056130561Sobrien bfd_wrapped_link_hash_lookup (output_bfd, info, 9057130561Sobrien link_order->u.reloc.p->u.name, 9058130561Sobrien FALSE, FALSE, TRUE)); 9059130561Sobrien if (h != NULL 9060130561Sobrien && (h->root.type == bfd_link_hash_defined 9061130561Sobrien || h->root.type == bfd_link_hash_defweak)) 9062130561Sobrien { 9063130561Sobrien asection *section; 9064130561Sobrien 9065130561Sobrien section = h->root.u.def.section; 9066130561Sobrien indx = section->output_section->target_index; 9067130561Sobrien *rel_hash_ptr = NULL; 9068130561Sobrien /* It seems that we ought to add the symbol value to the 9069130561Sobrien addend here, but in practice it has already been added 9070130561Sobrien because it was passed to constructor_callback. */ 9071130561Sobrien addend += section->output_section->vma + section->output_offset; 9072130561Sobrien } 9073130561Sobrien else if (h != NULL) 9074130561Sobrien { 9075130561Sobrien /* Setting the index to -2 tells elf_link_output_extsym that 9076130561Sobrien this symbol is used by a reloc. */ 9077130561Sobrien h->indx = -2; 9078130561Sobrien *rel_hash_ptr = h; 9079130561Sobrien indx = 0; 9080130561Sobrien } 9081130561Sobrien else 9082130561Sobrien { 9083130561Sobrien if (! ((*info->callbacks->unattached_reloc) 9084130561Sobrien (info, link_order->u.reloc.p->u.name, NULL, NULL, 0))) 9085130561Sobrien return FALSE; 9086130561Sobrien indx = 0; 9087130561Sobrien } 9088130561Sobrien } 9089130561Sobrien 9090130561Sobrien /* If this is an inplace reloc, we must write the addend into the 9091130561Sobrien object file. */ 9092130561Sobrien if (howto->partial_inplace && addend != 0) 9093130561Sobrien { 9094130561Sobrien bfd_size_type size; 9095130561Sobrien bfd_reloc_status_type rstat; 9096130561Sobrien bfd_byte *buf; 9097130561Sobrien bfd_boolean ok; 9098130561Sobrien const char *sym_name; 9099130561Sobrien 9100130561Sobrien size = bfd_get_reloc_size (howto); 9101130561Sobrien buf = bfd_zmalloc (size); 9102130561Sobrien if (buf == NULL) 9103130561Sobrien return FALSE; 9104130561Sobrien rstat = _bfd_relocate_contents (howto, output_bfd, addend, buf); 9105130561Sobrien switch (rstat) 9106130561Sobrien { 9107130561Sobrien case bfd_reloc_ok: 9108130561Sobrien break; 9109130561Sobrien 9110130561Sobrien default: 9111130561Sobrien case bfd_reloc_outofrange: 9112130561Sobrien abort (); 9113130561Sobrien 9114130561Sobrien case bfd_reloc_overflow: 9115130561Sobrien if (link_order->type == bfd_section_reloc_link_order) 9116130561Sobrien sym_name = bfd_section_name (output_bfd, 9117130561Sobrien link_order->u.reloc.p->u.section); 9118130561Sobrien else 9119130561Sobrien sym_name = link_order->u.reloc.p->u.name; 9120130561Sobrien if (! ((*info->callbacks->reloc_overflow) 9121218822Sdim (info, NULL, sym_name, howto->name, addend, NULL, 9122218822Sdim NULL, (bfd_vma) 0))) 9123130561Sobrien { 9124130561Sobrien free (buf); 9125130561Sobrien return FALSE; 9126130561Sobrien } 9127130561Sobrien break; 9128130561Sobrien } 9129130561Sobrien ok = bfd_set_section_contents (output_bfd, output_section, buf, 9130130561Sobrien link_order->offset, size); 9131130561Sobrien free (buf); 9132130561Sobrien if (! ok) 9133130561Sobrien return FALSE; 9134130561Sobrien } 9135130561Sobrien 9136130561Sobrien /* The address of a reloc is relative to the section in a 9137130561Sobrien relocatable file, and is a virtual address in an executable 9138130561Sobrien file. */ 9139130561Sobrien offset = link_order->offset; 9140130561Sobrien if (! info->relocatable) 9141130561Sobrien offset += output_section->vma; 9142130561Sobrien 9143130561Sobrien for (i = 0; i < bed->s->int_rels_per_ext_rel; i++) 9144130561Sobrien { 9145130561Sobrien irel[i].r_offset = offset; 9146130561Sobrien irel[i].r_info = 0; 9147130561Sobrien irel[i].r_addend = 0; 9148130561Sobrien } 9149130561Sobrien if (bed->s->arch_size == 32) 9150130561Sobrien irel[0].r_info = ELF32_R_INFO (indx, howto->type); 9151130561Sobrien else 9152130561Sobrien irel[0].r_info = ELF64_R_INFO (indx, howto->type); 9153130561Sobrien 9154130561Sobrien rel_hdr = &elf_section_data (output_section)->rel_hdr; 9155130561Sobrien erel = rel_hdr->contents; 9156130561Sobrien if (rel_hdr->sh_type == SHT_REL) 9157130561Sobrien { 9158130561Sobrien erel += (elf_section_data (output_section)->rel_count 9159130561Sobrien * bed->s->sizeof_rel); 9160130561Sobrien (*bed->s->swap_reloc_out) (output_bfd, irel, erel); 9161130561Sobrien } 9162130561Sobrien else 9163130561Sobrien { 9164130561Sobrien irel[0].r_addend = addend; 9165130561Sobrien erel += (elf_section_data (output_section)->rel_count 9166130561Sobrien * bed->s->sizeof_rela); 9167130561Sobrien (*bed->s->swap_reloca_out) (output_bfd, irel, erel); 9168130561Sobrien } 9169130561Sobrien 9170130561Sobrien ++elf_section_data (output_section)->rel_count; 9171130561Sobrien 9172130561Sobrien return TRUE; 9173130561Sobrien} 9174130561Sobrien 9175218822Sdim 9176218822Sdim/* Get the output vma of the section pointed to by the sh_link field. */ 9177218822Sdim 9178218822Sdimstatic bfd_vma 9179218822Sdimelf_get_linked_section_vma (struct bfd_link_order *p) 9180218822Sdim{ 9181218822Sdim Elf_Internal_Shdr **elf_shdrp; 9182218822Sdim asection *s; 9183218822Sdim int elfsec; 9184218822Sdim 9185218822Sdim s = p->u.indirect.section; 9186218822Sdim elf_shdrp = elf_elfsections (s->owner); 9187218822Sdim elfsec = _bfd_elf_section_from_bfd_section (s->owner, s); 9188218822Sdim elfsec = elf_shdrp[elfsec]->sh_link; 9189218822Sdim /* PR 290: 9190218822Sdim The Intel C compiler generates SHT_IA_64_UNWIND with 9191218822Sdim SHF_LINK_ORDER. But it doesn't set the sh_link or 9192218822Sdim sh_info fields. Hence we could get the situation 9193218822Sdim where elfsec is 0. */ 9194218822Sdim if (elfsec == 0) 9195218822Sdim { 9196218822Sdim const struct elf_backend_data *bed 9197218822Sdim = get_elf_backend_data (s->owner); 9198218822Sdim if (bed->link_order_error_handler) 9199218822Sdim bed->link_order_error_handler 9200218822Sdim (_("%B: warning: sh_link not set for section `%A'"), s->owner, s); 9201218822Sdim return 0; 9202218822Sdim } 9203218822Sdim else 9204218822Sdim { 9205218822Sdim s = elf_shdrp[elfsec]->bfd_section; 9206218822Sdim return s->output_section->vma + s->output_offset; 9207218822Sdim } 9208218822Sdim} 9209218822Sdim 9210218822Sdim 9211218822Sdim/* Compare two sections based on the locations of the sections they are 9212218822Sdim linked to. Used by elf_fixup_link_order. */ 9213218822Sdim 9214218822Sdimstatic int 9215218822Sdimcompare_link_order (const void * a, const void * b) 9216218822Sdim{ 9217218822Sdim bfd_vma apos; 9218218822Sdim bfd_vma bpos; 9219218822Sdim 9220218822Sdim apos = elf_get_linked_section_vma (*(struct bfd_link_order **)a); 9221218822Sdim bpos = elf_get_linked_section_vma (*(struct bfd_link_order **)b); 9222218822Sdim if (apos < bpos) 9223218822Sdim return -1; 9224218822Sdim return apos > bpos; 9225218822Sdim} 9226218822Sdim 9227218822Sdim 9228218822Sdim/* Looks for sections with SHF_LINK_ORDER set. Rearranges them into the same 9229218822Sdim order as their linked sections. Returns false if this could not be done 9230218822Sdim because an output section includes both ordered and unordered 9231218822Sdim sections. Ideally we'd do this in the linker proper. */ 9232218822Sdim 9233218822Sdimstatic bfd_boolean 9234218822Sdimelf_fixup_link_order (bfd *abfd, asection *o) 9235218822Sdim{ 9236218822Sdim int seen_linkorder; 9237218822Sdim int seen_other; 9238218822Sdim int n; 9239218822Sdim struct bfd_link_order *p; 9240218822Sdim bfd *sub; 9241218822Sdim const struct elf_backend_data *bed = get_elf_backend_data (abfd); 9242218822Sdim unsigned elfsec; 9243218822Sdim struct bfd_link_order **sections; 9244218822Sdim asection *s, *other_sec, *linkorder_sec; 9245218822Sdim bfd_vma offset; 9246218822Sdim 9247218822Sdim other_sec = NULL; 9248218822Sdim linkorder_sec = NULL; 9249218822Sdim seen_other = 0; 9250218822Sdim seen_linkorder = 0; 9251218822Sdim for (p = o->map_head.link_order; p != NULL; p = p->next) 9252218822Sdim { 9253218822Sdim if (p->type == bfd_indirect_link_order) 9254218822Sdim { 9255218822Sdim s = p->u.indirect.section; 9256218822Sdim sub = s->owner; 9257218822Sdim if (bfd_get_flavour (sub) == bfd_target_elf_flavour 9258218822Sdim && elf_elfheader (sub)->e_ident[EI_CLASS] == bed->s->elfclass 9259218822Sdim && (elfsec = _bfd_elf_section_from_bfd_section (sub, s)) 9260218822Sdim && elfsec < elf_numsections (sub) 9261218822Sdim && elf_elfsections (sub)[elfsec]->sh_flags & SHF_LINK_ORDER) 9262218822Sdim { 9263218822Sdim seen_linkorder++; 9264218822Sdim linkorder_sec = s; 9265218822Sdim } 9266218822Sdim else 9267218822Sdim { 9268218822Sdim seen_other++; 9269218822Sdim other_sec = s; 9270218822Sdim } 9271218822Sdim } 9272218822Sdim else 9273218822Sdim seen_other++; 9274218822Sdim 9275218822Sdim if (seen_other && seen_linkorder) 9276218822Sdim { 9277218822Sdim if (other_sec && linkorder_sec) 9278218822Sdim (*_bfd_error_handler) (_("%A has both ordered [`%A' in %B] and unordered [`%A' in %B] sections"), 9279218822Sdim o, linkorder_sec, 9280218822Sdim linkorder_sec->owner, other_sec, 9281218822Sdim other_sec->owner); 9282218822Sdim else 9283218822Sdim (*_bfd_error_handler) (_("%A has both ordered and unordered sections"), 9284218822Sdim o); 9285218822Sdim bfd_set_error (bfd_error_bad_value); 9286218822Sdim return FALSE; 9287218822Sdim } 9288218822Sdim } 9289218822Sdim 9290218822Sdim if (!seen_linkorder) 9291218822Sdim return TRUE; 9292218822Sdim 9293218822Sdim sections = (struct bfd_link_order **) 9294218822Sdim xmalloc (seen_linkorder * sizeof (struct bfd_link_order *)); 9295218822Sdim seen_linkorder = 0; 9296218822Sdim 9297218822Sdim for (p = o->map_head.link_order; p != NULL; p = p->next) 9298218822Sdim { 9299218822Sdim sections[seen_linkorder++] = p; 9300218822Sdim } 9301218822Sdim /* Sort the input sections in the order of their linked section. */ 9302218822Sdim qsort (sections, seen_linkorder, sizeof (struct bfd_link_order *), 9303218822Sdim compare_link_order); 9304218822Sdim 9305218822Sdim /* Change the offsets of the sections. */ 9306218822Sdim offset = 0; 9307218822Sdim for (n = 0; n < seen_linkorder; n++) 9308218822Sdim { 9309218822Sdim s = sections[n]->u.indirect.section; 9310218822Sdim offset &= ~(bfd_vma)((1 << s->alignment_power) - 1); 9311218822Sdim s->output_offset = offset; 9312218822Sdim sections[n]->offset = offset; 9313218822Sdim offset += sections[n]->size; 9314218822Sdim } 9315218822Sdim 9316218822Sdim return TRUE; 9317218822Sdim} 9318218822Sdim 9319218822Sdim 9320130561Sobrien/* Do the final step of an ELF link. */ 9321130561Sobrien 9322130561Sobrienbfd_boolean 9323130561Sobrienbfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) 9324130561Sobrien{ 9325130561Sobrien bfd_boolean dynamic; 9326130561Sobrien bfd_boolean emit_relocs; 9327130561Sobrien bfd *dynobj; 9328130561Sobrien struct elf_final_link_info finfo; 9329130561Sobrien register asection *o; 9330130561Sobrien register struct bfd_link_order *p; 9331130561Sobrien register bfd *sub; 9332130561Sobrien bfd_size_type max_contents_size; 9333130561Sobrien bfd_size_type max_external_reloc_size; 9334130561Sobrien bfd_size_type max_internal_reloc_count; 9335130561Sobrien bfd_size_type max_sym_count; 9336130561Sobrien bfd_size_type max_sym_shndx_count; 9337130561Sobrien file_ptr off; 9338130561Sobrien Elf_Internal_Sym elfsym; 9339130561Sobrien unsigned int i; 9340130561Sobrien Elf_Internal_Shdr *symtab_hdr; 9341130561Sobrien Elf_Internal_Shdr *symtab_shndx_hdr; 9342130561Sobrien Elf_Internal_Shdr *symstrtab_hdr; 9343130561Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 9344130561Sobrien struct elf_outext_info eoinfo; 9345130561Sobrien bfd_boolean merged; 9346130561Sobrien size_t relativecount = 0; 9347130561Sobrien asection *reldyn = 0; 9348130561Sobrien bfd_size_type amt; 9349218822Sdim asection *attr_section = NULL; 9350218822Sdim bfd_vma attr_size = 0; 9351218822Sdim const char *std_attrs_section; 9352130561Sobrien 9353130561Sobrien if (! is_elf_hash_table (info->hash)) 9354130561Sobrien return FALSE; 9355130561Sobrien 9356130561Sobrien if (info->shared) 9357130561Sobrien abfd->flags |= DYNAMIC; 9358130561Sobrien 9359130561Sobrien dynamic = elf_hash_table (info)->dynamic_sections_created; 9360130561Sobrien dynobj = elf_hash_table (info)->dynobj; 9361130561Sobrien 9362130561Sobrien emit_relocs = (info->relocatable 9363218822Sdim || info->emitrelocations); 9364130561Sobrien 9365130561Sobrien finfo.info = info; 9366130561Sobrien finfo.output_bfd = abfd; 9367130561Sobrien finfo.symstrtab = _bfd_elf_stringtab_init (); 9368130561Sobrien if (finfo.symstrtab == NULL) 9369130561Sobrien return FALSE; 9370130561Sobrien 9371130561Sobrien if (! dynamic) 9372130561Sobrien { 9373130561Sobrien finfo.dynsym_sec = NULL; 9374130561Sobrien finfo.hash_sec = NULL; 9375130561Sobrien finfo.symver_sec = NULL; 9376130561Sobrien } 9377130561Sobrien else 9378130561Sobrien { 9379130561Sobrien finfo.dynsym_sec = bfd_get_section_by_name (dynobj, ".dynsym"); 9380130561Sobrien finfo.hash_sec = bfd_get_section_by_name (dynobj, ".hash"); 9381218822Sdim BFD_ASSERT (finfo.dynsym_sec != NULL); 9382130561Sobrien finfo.symver_sec = bfd_get_section_by_name (dynobj, ".gnu.version"); 9383130561Sobrien /* Note that it is OK if symver_sec is NULL. */ 9384130561Sobrien } 9385130561Sobrien 9386130561Sobrien finfo.contents = NULL; 9387130561Sobrien finfo.external_relocs = NULL; 9388130561Sobrien finfo.internal_relocs = NULL; 9389130561Sobrien finfo.external_syms = NULL; 9390130561Sobrien finfo.locsym_shndx = NULL; 9391130561Sobrien finfo.internal_syms = NULL; 9392130561Sobrien finfo.indices = NULL; 9393130561Sobrien finfo.sections = NULL; 9394130561Sobrien finfo.symbuf = NULL; 9395130561Sobrien finfo.symshndxbuf = NULL; 9396130561Sobrien finfo.symbuf_count = 0; 9397130561Sobrien finfo.shndxbuf_size = 0; 9398130561Sobrien 9399218822Sdim /* The object attributes have been merged. Remove the input 9400218822Sdim sections from the link, and set the contents of the output 9401218822Sdim secton. */ 9402218822Sdim std_attrs_section = get_elf_backend_data (abfd)->obj_attrs_section; 9403218822Sdim for (o = abfd->sections; o != NULL; o = o->next) 9404218822Sdim { 9405218822Sdim if ((std_attrs_section && strcmp (o->name, std_attrs_section) == 0) 9406218822Sdim || strcmp (o->name, ".gnu.attributes") == 0) 9407218822Sdim { 9408218822Sdim for (p = o->map_head.link_order; p != NULL; p = p->next) 9409218822Sdim { 9410218822Sdim asection *input_section; 9411218822Sdim 9412218822Sdim if (p->type != bfd_indirect_link_order) 9413218822Sdim continue; 9414218822Sdim input_section = p->u.indirect.section; 9415218822Sdim /* Hack: reset the SEC_HAS_CONTENTS flag so that 9416218822Sdim elf_link_input_bfd ignores this section. */ 9417218822Sdim input_section->flags &= ~SEC_HAS_CONTENTS; 9418218822Sdim } 9419218822Sdim 9420218822Sdim attr_size = bfd_elf_obj_attr_size (abfd); 9421218822Sdim if (attr_size) 9422218822Sdim { 9423218822Sdim bfd_set_section_size (abfd, o, attr_size); 9424218822Sdim attr_section = o; 9425218822Sdim /* Skip this section later on. */ 9426218822Sdim o->map_head.link_order = NULL; 9427218822Sdim } 9428218822Sdim else 9429218822Sdim o->flags |= SEC_EXCLUDE; 9430218822Sdim } 9431218822Sdim } 9432218822Sdim 9433130561Sobrien /* Count up the number of relocations we will output for each output 9434130561Sobrien section, so that we know the sizes of the reloc sections. We 9435130561Sobrien also figure out some maximum sizes. */ 9436130561Sobrien max_contents_size = 0; 9437130561Sobrien max_external_reloc_size = 0; 9438130561Sobrien max_internal_reloc_count = 0; 9439130561Sobrien max_sym_count = 0; 9440130561Sobrien max_sym_shndx_count = 0; 9441130561Sobrien merged = FALSE; 9442130561Sobrien for (o = abfd->sections; o != NULL; o = o->next) 9443130561Sobrien { 9444130561Sobrien struct bfd_elf_section_data *esdo = elf_section_data (o); 9445130561Sobrien o->reloc_count = 0; 9446130561Sobrien 9447218822Sdim for (p = o->map_head.link_order; p != NULL; p = p->next) 9448130561Sobrien { 9449130561Sobrien unsigned int reloc_count = 0; 9450130561Sobrien struct bfd_elf_section_data *esdi = NULL; 9451130561Sobrien unsigned int *rel_count1; 9452130561Sobrien 9453130561Sobrien if (p->type == bfd_section_reloc_link_order 9454130561Sobrien || p->type == bfd_symbol_reloc_link_order) 9455130561Sobrien reloc_count = 1; 9456130561Sobrien else if (p->type == bfd_indirect_link_order) 9457130561Sobrien { 9458130561Sobrien asection *sec; 9459130561Sobrien 9460130561Sobrien sec = p->u.indirect.section; 9461130561Sobrien esdi = elf_section_data (sec); 9462130561Sobrien 9463130561Sobrien /* Mark all sections which are to be included in the 9464130561Sobrien link. This will normally be every section. We need 9465130561Sobrien to do this so that we can identify any sections which 9466130561Sobrien the linker has decided to not include. */ 9467130561Sobrien sec->linker_mark = TRUE; 9468130561Sobrien 9469130561Sobrien if (sec->flags & SEC_MERGE) 9470130561Sobrien merged = TRUE; 9471130561Sobrien 9472130561Sobrien if (info->relocatable || info->emitrelocations) 9473130561Sobrien reloc_count = sec->reloc_count; 9474130561Sobrien else if (bed->elf_backend_count_relocs) 9475130561Sobrien { 9476130561Sobrien Elf_Internal_Rela * relocs; 9477130561Sobrien 9478218822Sdim relocs = _bfd_elf_link_read_relocs (sec->owner, sec, 9479218822Sdim NULL, NULL, 9480130561Sobrien info->keep_memory); 9481130561Sobrien 9482218822Sdim if (relocs != NULL) 9483218822Sdim { 9484218822Sdim reloc_count 9485218822Sdim = (*bed->elf_backend_count_relocs) (sec, relocs); 9486130561Sobrien 9487218822Sdim if (elf_section_data (sec)->relocs != relocs) 9488218822Sdim free (relocs); 9489218822Sdim } 9490130561Sobrien } 9491130561Sobrien 9492218822Sdim if (sec->rawsize > max_contents_size) 9493218822Sdim max_contents_size = sec->rawsize; 9494218822Sdim if (sec->size > max_contents_size) 9495218822Sdim max_contents_size = sec->size; 9496130561Sobrien 9497130561Sobrien /* We are interested in just local symbols, not all 9498130561Sobrien symbols. */ 9499130561Sobrien if (bfd_get_flavour (sec->owner) == bfd_target_elf_flavour 9500130561Sobrien && (sec->owner->flags & DYNAMIC) == 0) 9501130561Sobrien { 9502130561Sobrien size_t sym_count; 9503130561Sobrien 9504130561Sobrien if (elf_bad_symtab (sec->owner)) 9505130561Sobrien sym_count = (elf_tdata (sec->owner)->symtab_hdr.sh_size 9506130561Sobrien / bed->s->sizeof_sym); 9507130561Sobrien else 9508130561Sobrien sym_count = elf_tdata (sec->owner)->symtab_hdr.sh_info; 9509130561Sobrien 9510130561Sobrien if (sym_count > max_sym_count) 9511130561Sobrien max_sym_count = sym_count; 9512130561Sobrien 9513130561Sobrien if (sym_count > max_sym_shndx_count 9514130561Sobrien && elf_symtab_shndx (sec->owner) != 0) 9515130561Sobrien max_sym_shndx_count = sym_count; 9516130561Sobrien 9517130561Sobrien if ((sec->flags & SEC_RELOC) != 0) 9518130561Sobrien { 9519130561Sobrien size_t ext_size; 9520130561Sobrien 9521130561Sobrien ext_size = elf_section_data (sec)->rel_hdr.sh_size; 9522130561Sobrien if (ext_size > max_external_reloc_size) 9523130561Sobrien max_external_reloc_size = ext_size; 9524130561Sobrien if (sec->reloc_count > max_internal_reloc_count) 9525130561Sobrien max_internal_reloc_count = sec->reloc_count; 9526130561Sobrien } 9527130561Sobrien } 9528130561Sobrien } 9529130561Sobrien 9530130561Sobrien if (reloc_count == 0) 9531130561Sobrien continue; 9532130561Sobrien 9533130561Sobrien o->reloc_count += reloc_count; 9534130561Sobrien 9535130561Sobrien /* MIPS may have a mix of REL and RELA relocs on sections. 9536130561Sobrien To support this curious ABI we keep reloc counts in 9537130561Sobrien elf_section_data too. We must be careful to add the 9538130561Sobrien relocations from the input section to the right output 9539130561Sobrien count. FIXME: Get rid of one count. We have 9540130561Sobrien o->reloc_count == esdo->rel_count + esdo->rel_count2. */ 9541130561Sobrien rel_count1 = &esdo->rel_count; 9542130561Sobrien if (esdi != NULL) 9543130561Sobrien { 9544130561Sobrien bfd_boolean same_size; 9545130561Sobrien bfd_size_type entsize1; 9546130561Sobrien 9547130561Sobrien entsize1 = esdi->rel_hdr.sh_entsize; 9548130561Sobrien BFD_ASSERT (entsize1 == bed->s->sizeof_rel 9549130561Sobrien || entsize1 == bed->s->sizeof_rela); 9550130561Sobrien same_size = !o->use_rela_p == (entsize1 == bed->s->sizeof_rel); 9551130561Sobrien 9552130561Sobrien if (!same_size) 9553130561Sobrien rel_count1 = &esdo->rel_count2; 9554130561Sobrien 9555130561Sobrien if (esdi->rel_hdr2 != NULL) 9556130561Sobrien { 9557130561Sobrien bfd_size_type entsize2 = esdi->rel_hdr2->sh_entsize; 9558130561Sobrien unsigned int alt_count; 9559130561Sobrien unsigned int *rel_count2; 9560130561Sobrien 9561130561Sobrien BFD_ASSERT (entsize2 != entsize1 9562130561Sobrien && (entsize2 == bed->s->sizeof_rel 9563130561Sobrien || entsize2 == bed->s->sizeof_rela)); 9564130561Sobrien 9565130561Sobrien rel_count2 = &esdo->rel_count2; 9566130561Sobrien if (!same_size) 9567130561Sobrien rel_count2 = &esdo->rel_count; 9568130561Sobrien 9569130561Sobrien /* The following is probably too simplistic if the 9570130561Sobrien backend counts output relocs unusually. */ 9571130561Sobrien BFD_ASSERT (bed->elf_backend_count_relocs == NULL); 9572130561Sobrien alt_count = NUM_SHDR_ENTRIES (esdi->rel_hdr2); 9573130561Sobrien *rel_count2 += alt_count; 9574130561Sobrien reloc_count -= alt_count; 9575130561Sobrien } 9576130561Sobrien } 9577130561Sobrien *rel_count1 += reloc_count; 9578130561Sobrien } 9579130561Sobrien 9580130561Sobrien if (o->reloc_count > 0) 9581130561Sobrien o->flags |= SEC_RELOC; 9582130561Sobrien else 9583130561Sobrien { 9584130561Sobrien /* Explicitly clear the SEC_RELOC flag. The linker tends to 9585130561Sobrien set it (this is probably a bug) and if it is set 9586130561Sobrien assign_section_numbers will create a reloc section. */ 9587130561Sobrien o->flags &=~ SEC_RELOC; 9588130561Sobrien } 9589130561Sobrien 9590130561Sobrien /* If the SEC_ALLOC flag is not set, force the section VMA to 9591130561Sobrien zero. This is done in elf_fake_sections as well, but forcing 9592130561Sobrien the VMA to 0 here will ensure that relocs against these 9593130561Sobrien sections are handled correctly. */ 9594130561Sobrien if ((o->flags & SEC_ALLOC) == 0 9595130561Sobrien && ! o->user_set_vma) 9596130561Sobrien o->vma = 0; 9597130561Sobrien } 9598130561Sobrien 9599130561Sobrien if (! info->relocatable && merged) 9600130561Sobrien elf_link_hash_traverse (elf_hash_table (info), 9601130561Sobrien _bfd_elf_link_sec_merge_syms, abfd); 9602130561Sobrien 9603130561Sobrien /* Figure out the file positions for everything but the symbol table 9604130561Sobrien and the relocs. We set symcount to force assign_section_numbers 9605130561Sobrien to create a symbol table. */ 9606130561Sobrien bfd_get_symcount (abfd) = info->strip == strip_all ? 0 : 1; 9607130561Sobrien BFD_ASSERT (! abfd->output_has_begun); 9608130561Sobrien if (! _bfd_elf_compute_section_file_positions (abfd, info)) 9609130561Sobrien goto error_return; 9610130561Sobrien 9611218822Sdim /* Set sizes, and assign file positions for reloc sections. */ 9612130561Sobrien for (o = abfd->sections; o != NULL; o = o->next) 9613130561Sobrien { 9614130561Sobrien if ((o->flags & SEC_RELOC) != 0) 9615130561Sobrien { 9616130561Sobrien if (!(_bfd_elf_link_size_reloc_section 9617130561Sobrien (abfd, &elf_section_data (o)->rel_hdr, o))) 9618130561Sobrien goto error_return; 9619130561Sobrien 9620130561Sobrien if (elf_section_data (o)->rel_hdr2 9621130561Sobrien && !(_bfd_elf_link_size_reloc_section 9622130561Sobrien (abfd, elf_section_data (o)->rel_hdr2, o))) 9623130561Sobrien goto error_return; 9624130561Sobrien } 9625130561Sobrien 9626130561Sobrien /* Now, reset REL_COUNT and REL_COUNT2 so that we can use them 9627130561Sobrien to count upwards while actually outputting the relocations. */ 9628130561Sobrien elf_section_data (o)->rel_count = 0; 9629130561Sobrien elf_section_data (o)->rel_count2 = 0; 9630130561Sobrien } 9631130561Sobrien 9632130561Sobrien _bfd_elf_assign_file_positions_for_relocs (abfd); 9633130561Sobrien 9634130561Sobrien /* We have now assigned file positions for all the sections except 9635130561Sobrien .symtab and .strtab. We start the .symtab section at the current 9636130561Sobrien file position, and write directly to it. We build the .strtab 9637130561Sobrien section in memory. */ 9638130561Sobrien bfd_get_symcount (abfd) = 0; 9639130561Sobrien symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 9640130561Sobrien /* sh_name is set in prep_headers. */ 9641130561Sobrien symtab_hdr->sh_type = SHT_SYMTAB; 9642130561Sobrien /* sh_flags, sh_addr and sh_size all start off zero. */ 9643130561Sobrien symtab_hdr->sh_entsize = bed->s->sizeof_sym; 9644130561Sobrien /* sh_link is set in assign_section_numbers. */ 9645130561Sobrien /* sh_info is set below. */ 9646130561Sobrien /* sh_offset is set just below. */ 9647130561Sobrien symtab_hdr->sh_addralign = 1 << bed->s->log_file_align; 9648130561Sobrien 9649130561Sobrien off = elf_tdata (abfd)->next_file_pos; 9650130561Sobrien off = _bfd_elf_assign_file_position_for_section (symtab_hdr, off, TRUE); 9651130561Sobrien 9652130561Sobrien /* Note that at this point elf_tdata (abfd)->next_file_pos is 9653130561Sobrien incorrect. We do not yet know the size of the .symtab section. 9654130561Sobrien We correct next_file_pos below, after we do know the size. */ 9655130561Sobrien 9656130561Sobrien /* Allocate a buffer to hold swapped out symbols. This is to avoid 9657130561Sobrien continuously seeking to the right position in the file. */ 9658130561Sobrien if (! info->keep_memory || max_sym_count < 20) 9659130561Sobrien finfo.symbuf_size = 20; 9660130561Sobrien else 9661130561Sobrien finfo.symbuf_size = max_sym_count; 9662130561Sobrien amt = finfo.symbuf_size; 9663130561Sobrien amt *= bed->s->sizeof_sym; 9664130561Sobrien finfo.symbuf = bfd_malloc (amt); 9665130561Sobrien if (finfo.symbuf == NULL) 9666130561Sobrien goto error_return; 9667130561Sobrien if (elf_numsections (abfd) > SHN_LORESERVE) 9668130561Sobrien { 9669130561Sobrien /* Wild guess at number of output symbols. realloc'd as needed. */ 9670130561Sobrien amt = 2 * max_sym_count + elf_numsections (abfd) + 1000; 9671130561Sobrien finfo.shndxbuf_size = amt; 9672130561Sobrien amt *= sizeof (Elf_External_Sym_Shndx); 9673130561Sobrien finfo.symshndxbuf = bfd_zmalloc (amt); 9674130561Sobrien if (finfo.symshndxbuf == NULL) 9675130561Sobrien goto error_return; 9676130561Sobrien } 9677130561Sobrien 9678130561Sobrien /* Start writing out the symbol table. The first symbol is always a 9679130561Sobrien dummy symbol. */ 9680130561Sobrien if (info->strip != strip_all 9681130561Sobrien || emit_relocs) 9682130561Sobrien { 9683130561Sobrien elfsym.st_value = 0; 9684130561Sobrien elfsym.st_size = 0; 9685130561Sobrien elfsym.st_info = 0; 9686130561Sobrien elfsym.st_other = 0; 9687130561Sobrien elfsym.st_shndx = SHN_UNDEF; 9688130561Sobrien if (! elf_link_output_sym (&finfo, NULL, &elfsym, bfd_und_section_ptr, 9689130561Sobrien NULL)) 9690130561Sobrien goto error_return; 9691130561Sobrien } 9692130561Sobrien 9693130561Sobrien /* Output a symbol for each section. We output these even if we are 9694130561Sobrien discarding local symbols, since they are used for relocs. These 9695130561Sobrien symbols have no names. We store the index of each one in the 9696130561Sobrien index field of the section, so that we can find it again when 9697130561Sobrien outputting relocs. */ 9698130561Sobrien if (info->strip != strip_all 9699130561Sobrien || emit_relocs) 9700130561Sobrien { 9701130561Sobrien elfsym.st_size = 0; 9702130561Sobrien elfsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); 9703130561Sobrien elfsym.st_other = 0; 9704218822Sdim elfsym.st_value = 0; 9705130561Sobrien for (i = 1; i < elf_numsections (abfd); i++) 9706130561Sobrien { 9707130561Sobrien o = bfd_section_from_elf_index (abfd, i); 9708130561Sobrien if (o != NULL) 9709218822Sdim { 9710218822Sdim o->target_index = bfd_get_symcount (abfd); 9711218822Sdim elfsym.st_shndx = i; 9712218822Sdim if (!info->relocatable) 9713218822Sdim elfsym.st_value = o->vma; 9714218822Sdim if (!elf_link_output_sym (&finfo, NULL, &elfsym, o, NULL)) 9715218822Sdim goto error_return; 9716218822Sdim } 9717130561Sobrien if (i == SHN_LORESERVE - 1) 9718130561Sobrien i += SHN_HIRESERVE + 1 - SHN_LORESERVE; 9719130561Sobrien } 9720130561Sobrien } 9721130561Sobrien 9722130561Sobrien /* Allocate some memory to hold information read in from the input 9723130561Sobrien files. */ 9724130561Sobrien if (max_contents_size != 0) 9725130561Sobrien { 9726130561Sobrien finfo.contents = bfd_malloc (max_contents_size); 9727130561Sobrien if (finfo.contents == NULL) 9728130561Sobrien goto error_return; 9729130561Sobrien } 9730130561Sobrien 9731130561Sobrien if (max_external_reloc_size != 0) 9732130561Sobrien { 9733130561Sobrien finfo.external_relocs = bfd_malloc (max_external_reloc_size); 9734130561Sobrien if (finfo.external_relocs == NULL) 9735130561Sobrien goto error_return; 9736130561Sobrien } 9737130561Sobrien 9738130561Sobrien if (max_internal_reloc_count != 0) 9739130561Sobrien { 9740130561Sobrien amt = max_internal_reloc_count * bed->s->int_rels_per_ext_rel; 9741130561Sobrien amt *= sizeof (Elf_Internal_Rela); 9742130561Sobrien finfo.internal_relocs = bfd_malloc (amt); 9743130561Sobrien if (finfo.internal_relocs == NULL) 9744130561Sobrien goto error_return; 9745130561Sobrien } 9746130561Sobrien 9747130561Sobrien if (max_sym_count != 0) 9748130561Sobrien { 9749130561Sobrien amt = max_sym_count * bed->s->sizeof_sym; 9750130561Sobrien finfo.external_syms = bfd_malloc (amt); 9751130561Sobrien if (finfo.external_syms == NULL) 9752130561Sobrien goto error_return; 9753130561Sobrien 9754130561Sobrien amt = max_sym_count * sizeof (Elf_Internal_Sym); 9755130561Sobrien finfo.internal_syms = bfd_malloc (amt); 9756130561Sobrien if (finfo.internal_syms == NULL) 9757130561Sobrien goto error_return; 9758130561Sobrien 9759130561Sobrien amt = max_sym_count * sizeof (long); 9760130561Sobrien finfo.indices = bfd_malloc (amt); 9761130561Sobrien if (finfo.indices == NULL) 9762130561Sobrien goto error_return; 9763130561Sobrien 9764130561Sobrien amt = max_sym_count * sizeof (asection *); 9765130561Sobrien finfo.sections = bfd_malloc (amt); 9766130561Sobrien if (finfo.sections == NULL) 9767130561Sobrien goto error_return; 9768130561Sobrien } 9769130561Sobrien 9770130561Sobrien if (max_sym_shndx_count != 0) 9771130561Sobrien { 9772130561Sobrien amt = max_sym_shndx_count * sizeof (Elf_External_Sym_Shndx); 9773130561Sobrien finfo.locsym_shndx = bfd_malloc (amt); 9774130561Sobrien if (finfo.locsym_shndx == NULL) 9775130561Sobrien goto error_return; 9776130561Sobrien } 9777130561Sobrien 9778130561Sobrien if (elf_hash_table (info)->tls_sec) 9779130561Sobrien { 9780130561Sobrien bfd_vma base, end = 0; 9781130561Sobrien asection *sec; 9782130561Sobrien 9783130561Sobrien for (sec = elf_hash_table (info)->tls_sec; 9784130561Sobrien sec && (sec->flags & SEC_THREAD_LOCAL); 9785130561Sobrien sec = sec->next) 9786130561Sobrien { 9787218822Sdim bfd_size_type size = sec->size; 9788130561Sobrien 9789218822Sdim if (size == 0 9790218822Sdim && (sec->flags & SEC_HAS_CONTENTS) == 0) 9791130561Sobrien { 9792218822Sdim struct bfd_link_order *o = sec->map_tail.link_order; 9793218822Sdim if (o != NULL) 9794218822Sdim size = o->offset + o->size; 9795130561Sobrien } 9796130561Sobrien end = sec->vma + size; 9797130561Sobrien } 9798130561Sobrien base = elf_hash_table (info)->tls_sec->vma; 9799130561Sobrien end = align_power (end, elf_hash_table (info)->tls_sec->alignment_power); 9800130561Sobrien elf_hash_table (info)->tls_size = end - base; 9801130561Sobrien } 9802130561Sobrien 9803218822Sdim /* Reorder SHF_LINK_ORDER sections. */ 9804218822Sdim for (o = abfd->sections; o != NULL; o = o->next) 9805218822Sdim { 9806218822Sdim if (!elf_fixup_link_order (abfd, o)) 9807218822Sdim return FALSE; 9808218822Sdim } 9809218822Sdim 9810130561Sobrien /* Since ELF permits relocations to be against local symbols, we 9811130561Sobrien must have the local symbols available when we do the relocations. 9812130561Sobrien Since we would rather only read the local symbols once, and we 9813130561Sobrien would rather not keep them in memory, we handle all the 9814130561Sobrien relocations for a single input file at the same time. 9815130561Sobrien 9816130561Sobrien Unfortunately, there is no way to know the total number of local 9817130561Sobrien symbols until we have seen all of them, and the local symbol 9818130561Sobrien indices precede the global symbol indices. This means that when 9819130561Sobrien we are generating relocatable output, and we see a reloc against 9820130561Sobrien a global symbol, we can not know the symbol index until we have 9821130561Sobrien finished examining all the local symbols to see which ones we are 9822130561Sobrien going to output. To deal with this, we keep the relocations in 9823130561Sobrien memory, and don't output them until the end of the link. This is 9824130561Sobrien an unfortunate waste of memory, but I don't see a good way around 9825130561Sobrien it. Fortunately, it only happens when performing a relocatable 9826130561Sobrien link, which is not the common case. FIXME: If keep_memory is set 9827130561Sobrien we could write the relocs out and then read them again; I don't 9828130561Sobrien know how bad the memory loss will be. */ 9829130561Sobrien 9830130561Sobrien for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) 9831130561Sobrien sub->output_has_begun = FALSE; 9832130561Sobrien for (o = abfd->sections; o != NULL; o = o->next) 9833130561Sobrien { 9834218822Sdim for (p = o->map_head.link_order; p != NULL; p = p->next) 9835130561Sobrien { 9836130561Sobrien if (p->type == bfd_indirect_link_order 9837130561Sobrien && (bfd_get_flavour ((sub = p->u.indirect.section->owner)) 9838130561Sobrien == bfd_target_elf_flavour) 9839130561Sobrien && elf_elfheader (sub)->e_ident[EI_CLASS] == bed->s->elfclass) 9840130561Sobrien { 9841130561Sobrien if (! sub->output_has_begun) 9842130561Sobrien { 9843130561Sobrien if (! elf_link_input_bfd (&finfo, sub)) 9844130561Sobrien goto error_return; 9845130561Sobrien sub->output_has_begun = TRUE; 9846130561Sobrien } 9847130561Sobrien } 9848130561Sobrien else if (p->type == bfd_section_reloc_link_order 9849130561Sobrien || p->type == bfd_symbol_reloc_link_order) 9850130561Sobrien { 9851130561Sobrien if (! elf_reloc_link_order (abfd, info, o, p)) 9852130561Sobrien goto error_return; 9853130561Sobrien } 9854130561Sobrien else 9855130561Sobrien { 9856130561Sobrien if (! _bfd_default_link_order (abfd, info, o, p)) 9857130561Sobrien goto error_return; 9858130561Sobrien } 9859130561Sobrien } 9860130561Sobrien } 9861130561Sobrien 9862218822Sdim /* Free symbol buffer if needed. */ 9863218822Sdim if (!info->reduce_memory_overheads) 9864218822Sdim { 9865218822Sdim for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) 9866218822Sdim if (bfd_get_flavour (sub) == bfd_target_elf_flavour 9867218822Sdim && elf_tdata (sub)->symbuf) 9868218822Sdim { 9869218822Sdim free (elf_tdata (sub)->symbuf); 9870218822Sdim elf_tdata (sub)->symbuf = NULL; 9871218822Sdim } 9872218822Sdim } 9873218822Sdim 9874130561Sobrien /* Output any global symbols that got converted to local in a 9875130561Sobrien version script or due to symbol visibility. We do this in a 9876130561Sobrien separate step since ELF requires all local symbols to appear 9877130561Sobrien prior to any global symbols. FIXME: We should only do this if 9878130561Sobrien some global symbols were, in fact, converted to become local. 9879130561Sobrien FIXME: Will this work correctly with the Irix 5 linker? */ 9880130561Sobrien eoinfo.failed = FALSE; 9881130561Sobrien eoinfo.finfo = &finfo; 9882130561Sobrien eoinfo.localsyms = TRUE; 9883130561Sobrien elf_link_hash_traverse (elf_hash_table (info), elf_link_output_extsym, 9884130561Sobrien &eoinfo); 9885130561Sobrien if (eoinfo.failed) 9886130561Sobrien return FALSE; 9887130561Sobrien 9888218822Sdim /* If backend needs to output some local symbols not present in the hash 9889218822Sdim table, do it now. */ 9890218822Sdim if (bed->elf_backend_output_arch_local_syms) 9891218822Sdim { 9892218822Sdim typedef bfd_boolean (*out_sym_func) 9893218822Sdim (void *, const char *, Elf_Internal_Sym *, asection *, 9894218822Sdim struct elf_link_hash_entry *); 9895218822Sdim 9896218822Sdim if (! ((*bed->elf_backend_output_arch_local_syms) 9897218822Sdim (abfd, info, &finfo, (out_sym_func) elf_link_output_sym))) 9898218822Sdim return FALSE; 9899218822Sdim } 9900218822Sdim 9901130561Sobrien /* That wrote out all the local symbols. Finish up the symbol table 9902130561Sobrien with the global symbols. Even if we want to strip everything we 9903130561Sobrien can, we still need to deal with those global symbols that got 9904130561Sobrien converted to local in a version script. */ 9905130561Sobrien 9906130561Sobrien /* The sh_info field records the index of the first non local symbol. */ 9907130561Sobrien symtab_hdr->sh_info = bfd_get_symcount (abfd); 9908130561Sobrien 9909130561Sobrien if (dynamic 9910130561Sobrien && finfo.dynsym_sec->output_section != bfd_abs_section_ptr) 9911130561Sobrien { 9912130561Sobrien Elf_Internal_Sym sym; 9913130561Sobrien bfd_byte *dynsym = finfo.dynsym_sec->contents; 9914130561Sobrien long last_local = 0; 9915130561Sobrien 9916130561Sobrien /* Write out the section symbols for the output sections. */ 9917218822Sdim if (info->shared || elf_hash_table (info)->is_relocatable_executable) 9918130561Sobrien { 9919130561Sobrien asection *s; 9920130561Sobrien 9921130561Sobrien sym.st_size = 0; 9922130561Sobrien sym.st_name = 0; 9923130561Sobrien sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); 9924130561Sobrien sym.st_other = 0; 9925130561Sobrien 9926130561Sobrien for (s = abfd->sections; s != NULL; s = s->next) 9927130561Sobrien { 9928130561Sobrien int indx; 9929130561Sobrien bfd_byte *dest; 9930130561Sobrien long dynindx; 9931130561Sobrien 9932218822Sdim dynindx = elf_section_data (s)->dynindx; 9933218822Sdim if (dynindx <= 0) 9934218822Sdim continue; 9935130561Sobrien indx = elf_section_data (s)->this_idx; 9936130561Sobrien BFD_ASSERT (indx > 0); 9937130561Sobrien sym.st_shndx = indx; 9938218822Sdim if (! check_dynsym (abfd, &sym)) 9939218822Sdim return FALSE; 9940130561Sobrien sym.st_value = s->vma; 9941130561Sobrien dest = dynsym + dynindx * bed->s->sizeof_sym; 9942218822Sdim if (last_local < dynindx) 9943218822Sdim last_local = dynindx; 9944130561Sobrien bed->s->swap_symbol_out (abfd, &sym, dest, 0); 9945130561Sobrien } 9946130561Sobrien } 9947130561Sobrien 9948130561Sobrien /* Write out the local dynsyms. */ 9949130561Sobrien if (elf_hash_table (info)->dynlocal) 9950130561Sobrien { 9951130561Sobrien struct elf_link_local_dynamic_entry *e; 9952130561Sobrien for (e = elf_hash_table (info)->dynlocal; e ; e = e->next) 9953130561Sobrien { 9954130561Sobrien asection *s; 9955130561Sobrien bfd_byte *dest; 9956130561Sobrien 9957130561Sobrien sym.st_size = e->isym.st_size; 9958130561Sobrien sym.st_other = e->isym.st_other; 9959130561Sobrien 9960130561Sobrien /* Copy the internal symbol as is. 9961130561Sobrien Note that we saved a word of storage and overwrote 9962130561Sobrien the original st_name with the dynstr_index. */ 9963130561Sobrien sym = e->isym; 9964130561Sobrien 9965130561Sobrien if (e->isym.st_shndx != SHN_UNDEF 9966130561Sobrien && (e->isym.st_shndx < SHN_LORESERVE 9967130561Sobrien || e->isym.st_shndx > SHN_HIRESERVE)) 9968130561Sobrien { 9969130561Sobrien s = bfd_section_from_elf_index (e->input_bfd, 9970130561Sobrien e->isym.st_shndx); 9971130561Sobrien 9972130561Sobrien sym.st_shndx = 9973130561Sobrien elf_section_data (s->output_section)->this_idx; 9974218822Sdim if (! check_dynsym (abfd, &sym)) 9975218822Sdim return FALSE; 9976130561Sobrien sym.st_value = (s->output_section->vma 9977130561Sobrien + s->output_offset 9978130561Sobrien + e->isym.st_value); 9979130561Sobrien } 9980130561Sobrien 9981130561Sobrien if (last_local < e->dynindx) 9982130561Sobrien last_local = e->dynindx; 9983130561Sobrien 9984130561Sobrien dest = dynsym + e->dynindx * bed->s->sizeof_sym; 9985130561Sobrien bed->s->swap_symbol_out (abfd, &sym, dest, 0); 9986130561Sobrien } 9987130561Sobrien } 9988130561Sobrien 9989130561Sobrien elf_section_data (finfo.dynsym_sec->output_section)->this_hdr.sh_info = 9990130561Sobrien last_local + 1; 9991130561Sobrien } 9992130561Sobrien 9993130561Sobrien /* We get the global symbols from the hash table. */ 9994130561Sobrien eoinfo.failed = FALSE; 9995130561Sobrien eoinfo.localsyms = FALSE; 9996130561Sobrien eoinfo.finfo = &finfo; 9997130561Sobrien elf_link_hash_traverse (elf_hash_table (info), elf_link_output_extsym, 9998130561Sobrien &eoinfo); 9999130561Sobrien if (eoinfo.failed) 10000130561Sobrien return FALSE; 10001130561Sobrien 10002130561Sobrien /* If backend needs to output some symbols not present in the hash 10003130561Sobrien table, do it now. */ 10004130561Sobrien if (bed->elf_backend_output_arch_syms) 10005130561Sobrien { 10006130561Sobrien typedef bfd_boolean (*out_sym_func) 10007130561Sobrien (void *, const char *, Elf_Internal_Sym *, asection *, 10008130561Sobrien struct elf_link_hash_entry *); 10009130561Sobrien 10010130561Sobrien if (! ((*bed->elf_backend_output_arch_syms) 10011130561Sobrien (abfd, info, &finfo, (out_sym_func) elf_link_output_sym))) 10012130561Sobrien return FALSE; 10013130561Sobrien } 10014130561Sobrien 10015130561Sobrien /* Flush all symbols to the file. */ 10016130561Sobrien if (! elf_link_flush_output_syms (&finfo, bed)) 10017130561Sobrien return FALSE; 10018130561Sobrien 10019130561Sobrien /* Now we know the size of the symtab section. */ 10020130561Sobrien off += symtab_hdr->sh_size; 10021130561Sobrien 10022130561Sobrien symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr; 10023130561Sobrien if (symtab_shndx_hdr->sh_name != 0) 10024130561Sobrien { 10025130561Sobrien symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX; 10026130561Sobrien symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx); 10027130561Sobrien symtab_shndx_hdr->sh_addralign = sizeof (Elf_External_Sym_Shndx); 10028130561Sobrien amt = bfd_get_symcount (abfd) * sizeof (Elf_External_Sym_Shndx); 10029130561Sobrien symtab_shndx_hdr->sh_size = amt; 10030130561Sobrien 10031130561Sobrien off = _bfd_elf_assign_file_position_for_section (symtab_shndx_hdr, 10032130561Sobrien off, TRUE); 10033130561Sobrien 10034130561Sobrien if (bfd_seek (abfd, symtab_shndx_hdr->sh_offset, SEEK_SET) != 0 10035130561Sobrien || (bfd_bwrite (finfo.symshndxbuf, amt, abfd) != amt)) 10036130561Sobrien return FALSE; 10037130561Sobrien } 10038130561Sobrien 10039130561Sobrien 10040130561Sobrien /* Finish up and write out the symbol string table (.strtab) 10041130561Sobrien section. */ 10042130561Sobrien symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr; 10043130561Sobrien /* sh_name was set in prep_headers. */ 10044130561Sobrien symstrtab_hdr->sh_type = SHT_STRTAB; 10045130561Sobrien symstrtab_hdr->sh_flags = 0; 10046130561Sobrien symstrtab_hdr->sh_addr = 0; 10047130561Sobrien symstrtab_hdr->sh_size = _bfd_stringtab_size (finfo.symstrtab); 10048130561Sobrien symstrtab_hdr->sh_entsize = 0; 10049130561Sobrien symstrtab_hdr->sh_link = 0; 10050130561Sobrien symstrtab_hdr->sh_info = 0; 10051130561Sobrien /* sh_offset is set just below. */ 10052130561Sobrien symstrtab_hdr->sh_addralign = 1; 10053130561Sobrien 10054130561Sobrien off = _bfd_elf_assign_file_position_for_section (symstrtab_hdr, off, TRUE); 10055130561Sobrien elf_tdata (abfd)->next_file_pos = off; 10056130561Sobrien 10057130561Sobrien if (bfd_get_symcount (abfd) > 0) 10058130561Sobrien { 10059130561Sobrien if (bfd_seek (abfd, symstrtab_hdr->sh_offset, SEEK_SET) != 0 10060130561Sobrien || ! _bfd_stringtab_emit (abfd, finfo.symstrtab)) 10061130561Sobrien return FALSE; 10062130561Sobrien } 10063130561Sobrien 10064130561Sobrien /* Adjust the relocs to have the correct symbol indices. */ 10065130561Sobrien for (o = abfd->sections; o != NULL; o = o->next) 10066130561Sobrien { 10067130561Sobrien if ((o->flags & SEC_RELOC) == 0) 10068130561Sobrien continue; 10069130561Sobrien 10070130561Sobrien elf_link_adjust_relocs (abfd, &elf_section_data (o)->rel_hdr, 10071130561Sobrien elf_section_data (o)->rel_count, 10072130561Sobrien elf_section_data (o)->rel_hashes); 10073130561Sobrien if (elf_section_data (o)->rel_hdr2 != NULL) 10074130561Sobrien elf_link_adjust_relocs (abfd, elf_section_data (o)->rel_hdr2, 10075130561Sobrien elf_section_data (o)->rel_count2, 10076130561Sobrien (elf_section_data (o)->rel_hashes 10077130561Sobrien + elf_section_data (o)->rel_count)); 10078130561Sobrien 10079130561Sobrien /* Set the reloc_count field to 0 to prevent write_relocs from 10080130561Sobrien trying to swap the relocs out itself. */ 10081130561Sobrien o->reloc_count = 0; 10082130561Sobrien } 10083130561Sobrien 10084130561Sobrien if (dynamic && info->combreloc && dynobj != NULL) 10085130561Sobrien relativecount = elf_link_sort_relocs (abfd, info, &reldyn); 10086130561Sobrien 10087130561Sobrien /* If we are linking against a dynamic object, or generating a 10088130561Sobrien shared library, finish up the dynamic linking information. */ 10089130561Sobrien if (dynamic) 10090130561Sobrien { 10091130561Sobrien bfd_byte *dyncon, *dynconend; 10092130561Sobrien 10093130561Sobrien /* Fix up .dynamic entries. */ 10094130561Sobrien o = bfd_get_section_by_name (dynobj, ".dynamic"); 10095130561Sobrien BFD_ASSERT (o != NULL); 10096130561Sobrien 10097130561Sobrien dyncon = o->contents; 10098218822Sdim dynconend = o->contents + o->size; 10099130561Sobrien for (; dyncon < dynconend; dyncon += bed->s->sizeof_dyn) 10100130561Sobrien { 10101130561Sobrien Elf_Internal_Dyn dyn; 10102130561Sobrien const char *name; 10103130561Sobrien unsigned int type; 10104130561Sobrien 10105130561Sobrien bed->s->swap_dyn_in (dynobj, dyncon, &dyn); 10106130561Sobrien 10107130561Sobrien switch (dyn.d_tag) 10108130561Sobrien { 10109130561Sobrien default: 10110130561Sobrien continue; 10111130561Sobrien case DT_NULL: 10112130561Sobrien if (relativecount > 0 && dyncon + bed->s->sizeof_dyn < dynconend) 10113130561Sobrien { 10114130561Sobrien switch (elf_section_data (reldyn)->this_hdr.sh_type) 10115130561Sobrien { 10116130561Sobrien case SHT_REL: dyn.d_tag = DT_RELCOUNT; break; 10117130561Sobrien case SHT_RELA: dyn.d_tag = DT_RELACOUNT; break; 10118130561Sobrien default: continue; 10119130561Sobrien } 10120130561Sobrien dyn.d_un.d_val = relativecount; 10121130561Sobrien relativecount = 0; 10122130561Sobrien break; 10123130561Sobrien } 10124130561Sobrien continue; 10125130561Sobrien 10126130561Sobrien case DT_INIT: 10127130561Sobrien name = info->init_function; 10128130561Sobrien goto get_sym; 10129130561Sobrien case DT_FINI: 10130130561Sobrien name = info->fini_function; 10131130561Sobrien get_sym: 10132130561Sobrien { 10133130561Sobrien struct elf_link_hash_entry *h; 10134130561Sobrien 10135130561Sobrien h = elf_link_hash_lookup (elf_hash_table (info), name, 10136130561Sobrien FALSE, FALSE, TRUE); 10137130561Sobrien if (h != NULL 10138130561Sobrien && (h->root.type == bfd_link_hash_defined 10139130561Sobrien || h->root.type == bfd_link_hash_defweak)) 10140130561Sobrien { 10141130561Sobrien dyn.d_un.d_val = h->root.u.def.value; 10142130561Sobrien o = h->root.u.def.section; 10143130561Sobrien if (o->output_section != NULL) 10144130561Sobrien dyn.d_un.d_val += (o->output_section->vma 10145130561Sobrien + o->output_offset); 10146130561Sobrien else 10147130561Sobrien { 10148130561Sobrien /* The symbol is imported from another shared 10149130561Sobrien library and does not apply to this one. */ 10150130561Sobrien dyn.d_un.d_val = 0; 10151130561Sobrien } 10152130561Sobrien break; 10153130561Sobrien } 10154130561Sobrien } 10155130561Sobrien continue; 10156130561Sobrien 10157130561Sobrien case DT_PREINIT_ARRAYSZ: 10158130561Sobrien name = ".preinit_array"; 10159130561Sobrien goto get_size; 10160130561Sobrien case DT_INIT_ARRAYSZ: 10161130561Sobrien name = ".init_array"; 10162130561Sobrien goto get_size; 10163130561Sobrien case DT_FINI_ARRAYSZ: 10164130561Sobrien name = ".fini_array"; 10165130561Sobrien get_size: 10166130561Sobrien o = bfd_get_section_by_name (abfd, name); 10167130561Sobrien if (o == NULL) 10168130561Sobrien { 10169130561Sobrien (*_bfd_error_handler) 10170218822Sdim (_("%B: could not find output section %s"), abfd, name); 10171130561Sobrien goto error_return; 10172130561Sobrien } 10173218822Sdim if (o->size == 0) 10174130561Sobrien (*_bfd_error_handler) 10175130561Sobrien (_("warning: %s section has zero size"), name); 10176218822Sdim dyn.d_un.d_val = o->size; 10177130561Sobrien break; 10178130561Sobrien 10179130561Sobrien case DT_PREINIT_ARRAY: 10180130561Sobrien name = ".preinit_array"; 10181130561Sobrien goto get_vma; 10182130561Sobrien case DT_INIT_ARRAY: 10183130561Sobrien name = ".init_array"; 10184130561Sobrien goto get_vma; 10185130561Sobrien case DT_FINI_ARRAY: 10186130561Sobrien name = ".fini_array"; 10187130561Sobrien goto get_vma; 10188130561Sobrien 10189130561Sobrien case DT_HASH: 10190130561Sobrien name = ".hash"; 10191130561Sobrien goto get_vma; 10192218822Sdim case DT_GNU_HASH: 10193218822Sdim name = ".gnu.hash"; 10194218822Sdim goto get_vma; 10195130561Sobrien case DT_STRTAB: 10196130561Sobrien name = ".dynstr"; 10197130561Sobrien goto get_vma; 10198130561Sobrien case DT_SYMTAB: 10199130561Sobrien name = ".dynsym"; 10200130561Sobrien goto get_vma; 10201130561Sobrien case DT_VERDEF: 10202130561Sobrien name = ".gnu.version_d"; 10203130561Sobrien goto get_vma; 10204130561Sobrien case DT_VERNEED: 10205130561Sobrien name = ".gnu.version_r"; 10206130561Sobrien goto get_vma; 10207130561Sobrien case DT_VERSYM: 10208130561Sobrien name = ".gnu.version"; 10209130561Sobrien get_vma: 10210130561Sobrien o = bfd_get_section_by_name (abfd, name); 10211130561Sobrien if (o == NULL) 10212130561Sobrien { 10213130561Sobrien (*_bfd_error_handler) 10214218822Sdim (_("%B: could not find output section %s"), abfd, name); 10215130561Sobrien goto error_return; 10216130561Sobrien } 10217130561Sobrien dyn.d_un.d_ptr = o->vma; 10218130561Sobrien break; 10219130561Sobrien 10220130561Sobrien case DT_REL: 10221130561Sobrien case DT_RELA: 10222130561Sobrien case DT_RELSZ: 10223130561Sobrien case DT_RELASZ: 10224130561Sobrien if (dyn.d_tag == DT_REL || dyn.d_tag == DT_RELSZ) 10225130561Sobrien type = SHT_REL; 10226130561Sobrien else 10227130561Sobrien type = SHT_RELA; 10228130561Sobrien dyn.d_un.d_val = 0; 10229130561Sobrien for (i = 1; i < elf_numsections (abfd); i++) 10230130561Sobrien { 10231130561Sobrien Elf_Internal_Shdr *hdr; 10232130561Sobrien 10233130561Sobrien hdr = elf_elfsections (abfd)[i]; 10234130561Sobrien if (hdr->sh_type == type 10235130561Sobrien && (hdr->sh_flags & SHF_ALLOC) != 0) 10236130561Sobrien { 10237130561Sobrien if (dyn.d_tag == DT_RELSZ || dyn.d_tag == DT_RELASZ) 10238130561Sobrien dyn.d_un.d_val += hdr->sh_size; 10239130561Sobrien else 10240130561Sobrien { 10241130561Sobrien if (dyn.d_un.d_val == 0 10242130561Sobrien || hdr->sh_addr < dyn.d_un.d_val) 10243130561Sobrien dyn.d_un.d_val = hdr->sh_addr; 10244130561Sobrien } 10245130561Sobrien } 10246130561Sobrien } 10247130561Sobrien break; 10248130561Sobrien } 10249130561Sobrien bed->s->swap_dyn_out (dynobj, &dyn, dyncon); 10250130561Sobrien } 10251130561Sobrien } 10252130561Sobrien 10253130561Sobrien /* If we have created any dynamic sections, then output them. */ 10254130561Sobrien if (dynobj != NULL) 10255130561Sobrien { 10256130561Sobrien if (! (*bed->elf_backend_finish_dynamic_sections) (abfd, info)) 10257130561Sobrien goto error_return; 10258130561Sobrien 10259218822Sdim /* Check for DT_TEXTREL (late, in case the backend removes it). */ 10260218822Sdim if (info->warn_shared_textrel && info->shared) 10261218822Sdim { 10262218822Sdim bfd_byte *dyncon, *dynconend; 10263218822Sdim 10264218822Sdim /* Fix up .dynamic entries. */ 10265218822Sdim o = bfd_get_section_by_name (dynobj, ".dynamic"); 10266218822Sdim BFD_ASSERT (o != NULL); 10267218822Sdim 10268218822Sdim dyncon = o->contents; 10269218822Sdim dynconend = o->contents + o->size; 10270218822Sdim for (; dyncon < dynconend; dyncon += bed->s->sizeof_dyn) 10271218822Sdim { 10272218822Sdim Elf_Internal_Dyn dyn; 10273218822Sdim 10274218822Sdim bed->s->swap_dyn_in (dynobj, dyncon, &dyn); 10275218822Sdim 10276218822Sdim if (dyn.d_tag == DT_TEXTREL) 10277218822Sdim { 10278218822Sdim info->callbacks->einfo 10279218822Sdim (_("%P: warning: creating a DT_TEXTREL in a shared object.\n")); 10280218822Sdim break; 10281218822Sdim } 10282218822Sdim } 10283218822Sdim } 10284218822Sdim 10285130561Sobrien for (o = dynobj->sections; o != NULL; o = o->next) 10286130561Sobrien { 10287130561Sobrien if ((o->flags & SEC_HAS_CONTENTS) == 0 10288218822Sdim || o->size == 0 10289130561Sobrien || o->output_section == bfd_abs_section_ptr) 10290130561Sobrien continue; 10291130561Sobrien if ((o->flags & SEC_LINKER_CREATED) == 0) 10292130561Sobrien { 10293130561Sobrien /* At this point, we are only interested in sections 10294130561Sobrien created by _bfd_elf_link_create_dynamic_sections. */ 10295130561Sobrien continue; 10296130561Sobrien } 10297218822Sdim if (elf_hash_table (info)->stab_info.stabstr == o) 10298218822Sdim continue; 10299218822Sdim if (elf_hash_table (info)->eh_info.hdr_sec == o) 10300218822Sdim continue; 10301130561Sobrien if ((elf_section_data (o->output_section)->this_hdr.sh_type 10302130561Sobrien != SHT_STRTAB) 10303130561Sobrien || strcmp (bfd_get_section_name (abfd, o), ".dynstr") != 0) 10304130561Sobrien { 10305130561Sobrien if (! bfd_set_section_contents (abfd, o->output_section, 10306130561Sobrien o->contents, 10307130561Sobrien (file_ptr) o->output_offset, 10308218822Sdim o->size)) 10309130561Sobrien goto error_return; 10310130561Sobrien } 10311130561Sobrien else 10312130561Sobrien { 10313130561Sobrien /* The contents of the .dynstr section are actually in a 10314130561Sobrien stringtab. */ 10315130561Sobrien off = elf_section_data (o->output_section)->this_hdr.sh_offset; 10316130561Sobrien if (bfd_seek (abfd, off, SEEK_SET) != 0 10317130561Sobrien || ! _bfd_elf_strtab_emit (abfd, 10318130561Sobrien elf_hash_table (info)->dynstr)) 10319130561Sobrien goto error_return; 10320130561Sobrien } 10321130561Sobrien } 10322130561Sobrien } 10323130561Sobrien 10324130561Sobrien if (info->relocatable) 10325130561Sobrien { 10326130561Sobrien bfd_boolean failed = FALSE; 10327130561Sobrien 10328130561Sobrien bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed); 10329130561Sobrien if (failed) 10330130561Sobrien goto error_return; 10331130561Sobrien } 10332130561Sobrien 10333130561Sobrien /* If we have optimized stabs strings, output them. */ 10334218822Sdim if (elf_hash_table (info)->stab_info.stabstr != NULL) 10335130561Sobrien { 10336130561Sobrien if (! _bfd_write_stab_strings (abfd, &elf_hash_table (info)->stab_info)) 10337130561Sobrien goto error_return; 10338130561Sobrien } 10339130561Sobrien 10340130561Sobrien if (info->eh_frame_hdr) 10341130561Sobrien { 10342130561Sobrien if (! _bfd_elf_write_section_eh_frame_hdr (abfd, info)) 10343130561Sobrien goto error_return; 10344130561Sobrien } 10345130561Sobrien 10346130561Sobrien if (finfo.symstrtab != NULL) 10347130561Sobrien _bfd_stringtab_free (finfo.symstrtab); 10348130561Sobrien if (finfo.contents != NULL) 10349130561Sobrien free (finfo.contents); 10350130561Sobrien if (finfo.external_relocs != NULL) 10351130561Sobrien free (finfo.external_relocs); 10352130561Sobrien if (finfo.internal_relocs != NULL) 10353130561Sobrien free (finfo.internal_relocs); 10354130561Sobrien if (finfo.external_syms != NULL) 10355130561Sobrien free (finfo.external_syms); 10356130561Sobrien if (finfo.locsym_shndx != NULL) 10357130561Sobrien free (finfo.locsym_shndx); 10358130561Sobrien if (finfo.internal_syms != NULL) 10359130561Sobrien free (finfo.internal_syms); 10360130561Sobrien if (finfo.indices != NULL) 10361130561Sobrien free (finfo.indices); 10362130561Sobrien if (finfo.sections != NULL) 10363130561Sobrien free (finfo.sections); 10364130561Sobrien if (finfo.symbuf != NULL) 10365130561Sobrien free (finfo.symbuf); 10366130561Sobrien if (finfo.symshndxbuf != NULL) 10367130561Sobrien free (finfo.symshndxbuf); 10368130561Sobrien for (o = abfd->sections; o != NULL; o = o->next) 10369130561Sobrien { 10370130561Sobrien if ((o->flags & SEC_RELOC) != 0 10371130561Sobrien && elf_section_data (o)->rel_hashes != NULL) 10372130561Sobrien free (elf_section_data (o)->rel_hashes); 10373130561Sobrien } 10374130561Sobrien 10375130561Sobrien elf_tdata (abfd)->linker = TRUE; 10376130561Sobrien 10377218822Sdim if (attr_section) 10378218822Sdim { 10379218822Sdim bfd_byte *contents = bfd_malloc (attr_size); 10380218822Sdim if (contents == NULL) 10381218822Sdim goto error_return; 10382218822Sdim bfd_elf_set_obj_attr_contents (abfd, contents, attr_size); 10383218822Sdim bfd_set_section_contents (abfd, attr_section, contents, 0, attr_size); 10384218822Sdim free (contents); 10385218822Sdim } 10386218822Sdim 10387130561Sobrien return TRUE; 10388130561Sobrien 10389130561Sobrien error_return: 10390130561Sobrien if (finfo.symstrtab != NULL) 10391130561Sobrien _bfd_stringtab_free (finfo.symstrtab); 10392130561Sobrien if (finfo.contents != NULL) 10393130561Sobrien free (finfo.contents); 10394130561Sobrien if (finfo.external_relocs != NULL) 10395130561Sobrien free (finfo.external_relocs); 10396130561Sobrien if (finfo.internal_relocs != NULL) 10397130561Sobrien free (finfo.internal_relocs); 10398130561Sobrien if (finfo.external_syms != NULL) 10399130561Sobrien free (finfo.external_syms); 10400130561Sobrien if (finfo.locsym_shndx != NULL) 10401130561Sobrien free (finfo.locsym_shndx); 10402130561Sobrien if (finfo.internal_syms != NULL) 10403130561Sobrien free (finfo.internal_syms); 10404130561Sobrien if (finfo.indices != NULL) 10405130561Sobrien free (finfo.indices); 10406130561Sobrien if (finfo.sections != NULL) 10407130561Sobrien free (finfo.sections); 10408130561Sobrien if (finfo.symbuf != NULL) 10409130561Sobrien free (finfo.symbuf); 10410130561Sobrien if (finfo.symshndxbuf != NULL) 10411130561Sobrien free (finfo.symshndxbuf); 10412130561Sobrien for (o = abfd->sections; o != NULL; o = o->next) 10413130561Sobrien { 10414130561Sobrien if ((o->flags & SEC_RELOC) != 0 10415130561Sobrien && elf_section_data (o)->rel_hashes != NULL) 10416130561Sobrien free (elf_section_data (o)->rel_hashes); 10417130561Sobrien } 10418130561Sobrien 10419130561Sobrien return FALSE; 1042033965Sjdp} 1042133965Sjdp 10422130561Sobrien/* Garbage collect unused sections. */ 1042333965Sjdp 10424218822Sdim/* Default gc_mark_hook. */ 10425218822Sdim 10426218822Sdimasection * 10427218822Sdim_bfd_elf_gc_mark_hook (asection *sec, 10428218822Sdim struct bfd_link_info *info ATTRIBUTE_UNUSED, 10429218822Sdim Elf_Internal_Rela *rel ATTRIBUTE_UNUSED, 10430218822Sdim struct elf_link_hash_entry *h, 10431218822Sdim Elf_Internal_Sym *sym) 10432218822Sdim{ 10433218822Sdim if (h != NULL) 10434218822Sdim { 10435218822Sdim switch (h->root.type) 10436218822Sdim { 10437218822Sdim case bfd_link_hash_defined: 10438218822Sdim case bfd_link_hash_defweak: 10439218822Sdim return h->root.u.def.section; 10440218822Sdim 10441218822Sdim case bfd_link_hash_common: 10442218822Sdim return h->root.u.c.p->section; 10443218822Sdim 10444218822Sdim default: 10445218822Sdim break; 10446218822Sdim } 10447218822Sdim } 10448218822Sdim else 10449218822Sdim return bfd_section_from_elf_index (sec->owner, sym->st_shndx); 10450218822Sdim 10451218822Sdim return NULL; 10452218822Sdim} 10453218822Sdim 10454130561Sobrien/* The mark phase of garbage collection. For a given section, mark 10455130561Sobrien it and any sections in this section's group, and all the sections 10456130561Sobrien which define symbols to which it refers. */ 10457130561Sobrien 10458218822Sdimbfd_boolean 10459218822Sdim_bfd_elf_gc_mark (struct bfd_link_info *info, 10460218822Sdim asection *sec, 10461218822Sdim elf_gc_mark_hook_fn gc_mark_hook) 1046233965Sjdp{ 10463130561Sobrien bfd_boolean ret; 10464218822Sdim bfd_boolean is_eh; 10465130561Sobrien asection *group_sec; 10466130561Sobrien 10467130561Sobrien sec->gc_mark = 1; 10468130561Sobrien 10469130561Sobrien /* Mark all the sections in the group. */ 10470130561Sobrien group_sec = elf_section_data (sec)->next_in_group; 10471130561Sobrien if (group_sec && !group_sec->gc_mark) 10472218822Sdim if (!_bfd_elf_gc_mark (info, group_sec, gc_mark_hook)) 10473130561Sobrien return FALSE; 10474130561Sobrien 10475130561Sobrien /* Look through the section relocs. */ 10476130561Sobrien ret = TRUE; 10477218822Sdim is_eh = strcmp (sec->name, ".eh_frame") == 0; 10478130561Sobrien if ((sec->flags & SEC_RELOC) != 0 && sec->reloc_count > 0) 1047933965Sjdp { 10480130561Sobrien Elf_Internal_Rela *relstart, *rel, *relend; 10481130561Sobrien Elf_Internal_Shdr *symtab_hdr; 10482130561Sobrien struct elf_link_hash_entry **sym_hashes; 10483130561Sobrien size_t nlocsyms; 10484130561Sobrien size_t extsymoff; 10485130561Sobrien bfd *input_bfd = sec->owner; 10486130561Sobrien const struct elf_backend_data *bed = get_elf_backend_data (input_bfd); 10487130561Sobrien Elf_Internal_Sym *isym = NULL; 10488130561Sobrien int r_sym_shift; 10489130561Sobrien 10490130561Sobrien symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; 10491130561Sobrien sym_hashes = elf_sym_hashes (input_bfd); 10492130561Sobrien 10493130561Sobrien /* Read the local symbols. */ 10494130561Sobrien if (elf_bad_symtab (input_bfd)) 10495130561Sobrien { 10496130561Sobrien nlocsyms = symtab_hdr->sh_size / bed->s->sizeof_sym; 10497130561Sobrien extsymoff = 0; 10498130561Sobrien } 10499130561Sobrien else 10500130561Sobrien extsymoff = nlocsyms = symtab_hdr->sh_info; 10501130561Sobrien 10502130561Sobrien isym = (Elf_Internal_Sym *) symtab_hdr->contents; 10503130561Sobrien if (isym == NULL && nlocsyms != 0) 10504130561Sobrien { 10505130561Sobrien isym = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, nlocsyms, 0, 10506130561Sobrien NULL, NULL, NULL); 10507130561Sobrien if (isym == NULL) 10508130561Sobrien return FALSE; 10509130561Sobrien } 10510130561Sobrien 10511130561Sobrien /* Read the relocations. */ 10512130561Sobrien relstart = _bfd_elf_link_read_relocs (input_bfd, sec, NULL, NULL, 10513130561Sobrien info->keep_memory); 10514130561Sobrien if (relstart == NULL) 10515130561Sobrien { 10516130561Sobrien ret = FALSE; 10517130561Sobrien goto out1; 10518130561Sobrien } 10519130561Sobrien relend = relstart + sec->reloc_count * bed->s->int_rels_per_ext_rel; 10520130561Sobrien 10521130561Sobrien if (bed->s->arch_size == 32) 10522130561Sobrien r_sym_shift = 8; 10523130561Sobrien else 10524130561Sobrien r_sym_shift = 32; 10525130561Sobrien 10526130561Sobrien for (rel = relstart; rel < relend; rel++) 10527130561Sobrien { 10528130561Sobrien unsigned long r_symndx; 10529130561Sobrien asection *rsec; 10530130561Sobrien struct elf_link_hash_entry *h; 10531130561Sobrien 10532130561Sobrien r_symndx = rel->r_info >> r_sym_shift; 10533130561Sobrien if (r_symndx == 0) 10534130561Sobrien continue; 10535130561Sobrien 10536130561Sobrien if (r_symndx >= nlocsyms 10537130561Sobrien || ELF_ST_BIND (isym[r_symndx].st_info) != STB_LOCAL) 10538130561Sobrien { 10539130561Sobrien h = sym_hashes[r_symndx - extsymoff]; 10540218822Sdim while (h->root.type == bfd_link_hash_indirect 10541218822Sdim || h->root.type == bfd_link_hash_warning) 10542218822Sdim h = (struct elf_link_hash_entry *) h->root.u.i.link; 10543130561Sobrien rsec = (*gc_mark_hook) (sec, info, rel, h, NULL); 10544130561Sobrien } 10545130561Sobrien else 10546130561Sobrien { 10547130561Sobrien rsec = (*gc_mark_hook) (sec, info, rel, NULL, &isym[r_symndx]); 10548130561Sobrien } 10549130561Sobrien 10550130561Sobrien if (rsec && !rsec->gc_mark) 10551130561Sobrien { 10552130561Sobrien if (bfd_get_flavour (rsec->owner) != bfd_target_elf_flavour) 10553130561Sobrien rsec->gc_mark = 1; 10554218822Sdim else if (is_eh) 10555218822Sdim rsec->gc_mark_from_eh = 1; 10556218822Sdim else if (!_bfd_elf_gc_mark (info, rsec, gc_mark_hook)) 10557130561Sobrien { 10558130561Sobrien ret = FALSE; 10559130561Sobrien goto out2; 10560130561Sobrien } 10561130561Sobrien } 10562130561Sobrien } 10563130561Sobrien 10564130561Sobrien out2: 10565130561Sobrien if (elf_section_data (sec)->relocs != relstart) 10566130561Sobrien free (relstart); 10567130561Sobrien out1: 10568130561Sobrien if (isym != NULL && symtab_hdr->contents != (unsigned char *) isym) 10569130561Sobrien { 10570130561Sobrien if (! info->keep_memory) 10571130561Sobrien free (isym); 10572130561Sobrien else 10573130561Sobrien symtab_hdr->contents = (unsigned char *) isym; 10574130561Sobrien } 1057533965Sjdp } 1057633965Sjdp 10577130561Sobrien return ret; 1057833965Sjdp} 10579130561Sobrien 10580130561Sobrien/* Sweep symbols in swept sections. Called via elf_link_hash_traverse. */ 10581130561Sobrien 10582218822Sdimstruct elf_gc_sweep_symbol_info 10583218822Sdim{ 10584218822Sdim struct bfd_link_info *info; 10585218822Sdim void (*hide_symbol) (struct bfd_link_info *, struct elf_link_hash_entry *, 10586218822Sdim bfd_boolean); 10587218822Sdim}; 10588218822Sdim 10589130561Sobrienstatic bfd_boolean 10590218822Sdimelf_gc_sweep_symbol (struct elf_link_hash_entry *h, void *data) 10591130561Sobrien{ 10592130561Sobrien if (h->root.type == bfd_link_hash_warning) 10593130561Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 10594130561Sobrien 10595218822Sdim if ((h->root.type == bfd_link_hash_defined 10596218822Sdim || h->root.type == bfd_link_hash_defweak) 10597218822Sdim && !h->root.u.def.section->gc_mark 10598218822Sdim && !(h->root.u.def.section->owner->flags & DYNAMIC)) 10599218822Sdim { 10600218822Sdim struct elf_gc_sweep_symbol_info *inf = data; 10601218822Sdim (*inf->hide_symbol) (inf->info, h, TRUE); 10602218822Sdim } 10603130561Sobrien 10604130561Sobrien return TRUE; 10605130561Sobrien} 10606130561Sobrien 10607130561Sobrien/* The sweep phase of garbage collection. Remove all garbage sections. */ 10608130561Sobrien 10609130561Sobrientypedef bfd_boolean (*gc_sweep_hook_fn) 10610130561Sobrien (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *); 10611130561Sobrien 10612130561Sobrienstatic bfd_boolean 10613218822Sdimelf_gc_sweep (bfd *abfd, struct bfd_link_info *info) 10614130561Sobrien{ 10615130561Sobrien bfd *sub; 10616218822Sdim const struct elf_backend_data *bed = get_elf_backend_data (abfd); 10617218822Sdim gc_sweep_hook_fn gc_sweep_hook = bed->gc_sweep_hook; 10618218822Sdim unsigned long section_sym_count; 10619218822Sdim struct elf_gc_sweep_symbol_info sweep_info; 10620130561Sobrien 10621130561Sobrien for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) 10622130561Sobrien { 10623130561Sobrien asection *o; 10624130561Sobrien 10625130561Sobrien if (bfd_get_flavour (sub) != bfd_target_elf_flavour) 10626130561Sobrien continue; 10627130561Sobrien 10628130561Sobrien for (o = sub->sections; o != NULL; o = o->next) 10629130561Sobrien { 10630218822Sdim /* Keep debug and special sections. */ 10631218822Sdim if ((o->flags & (SEC_DEBUGGING | SEC_LINKER_CREATED)) != 0 10632244600Sdim || elf_section_data (o)->this_hdr.sh_type == SHT_NOTE 10633218822Sdim || (o->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0) 10634130561Sobrien o->gc_mark = 1; 10635130561Sobrien 10636130561Sobrien if (o->gc_mark) 10637130561Sobrien continue; 10638130561Sobrien 10639130561Sobrien /* Skip sweeping sections already excluded. */ 10640130561Sobrien if (o->flags & SEC_EXCLUDE) 10641130561Sobrien continue; 10642130561Sobrien 10643130561Sobrien /* Since this is early in the link process, it is simple 10644130561Sobrien to remove a section from the output. */ 10645130561Sobrien o->flags |= SEC_EXCLUDE; 10646130561Sobrien 10647218822Sdim if (info->print_gc_sections && o->size != 0) 10648218822Sdim _bfd_error_handler (_("Removing unused section '%s' in file '%B'"), sub, o->name); 10649218822Sdim 10650130561Sobrien /* But we also have to update some of the relocation 10651130561Sobrien info we collected before. */ 10652130561Sobrien if (gc_sweep_hook 10653218822Sdim && (o->flags & SEC_RELOC) != 0 10654218822Sdim && o->reloc_count > 0 10655218822Sdim && !bfd_is_abs_section (o->output_section)) 10656130561Sobrien { 10657130561Sobrien Elf_Internal_Rela *internal_relocs; 10658130561Sobrien bfd_boolean r; 10659130561Sobrien 10660130561Sobrien internal_relocs 10661130561Sobrien = _bfd_elf_link_read_relocs (o->owner, o, NULL, NULL, 10662130561Sobrien info->keep_memory); 10663130561Sobrien if (internal_relocs == NULL) 10664130561Sobrien return FALSE; 10665130561Sobrien 10666130561Sobrien r = (*gc_sweep_hook) (o->owner, info, o, internal_relocs); 10667130561Sobrien 10668130561Sobrien if (elf_section_data (o)->relocs != internal_relocs) 10669130561Sobrien free (internal_relocs); 10670130561Sobrien 10671130561Sobrien if (!r) 10672130561Sobrien return FALSE; 10673130561Sobrien } 10674130561Sobrien } 10675130561Sobrien } 10676130561Sobrien 10677130561Sobrien /* Remove the symbols that were in the swept sections from the dynamic 10678130561Sobrien symbol table. GCFIXME: Anyone know how to get them out of the 10679130561Sobrien static symbol table as well? */ 10680218822Sdim sweep_info.info = info; 10681218822Sdim sweep_info.hide_symbol = bed->elf_backend_hide_symbol; 10682218822Sdim elf_link_hash_traverse (elf_hash_table (info), elf_gc_sweep_symbol, 10683218822Sdim &sweep_info); 10684130561Sobrien 10685218822Sdim _bfd_elf_link_renumber_dynsyms (abfd, info, §ion_sym_count); 10686130561Sobrien return TRUE; 10687130561Sobrien} 10688130561Sobrien 10689130561Sobrien/* Propagate collected vtable information. This is called through 10690130561Sobrien elf_link_hash_traverse. */ 10691130561Sobrien 10692130561Sobrienstatic bfd_boolean 10693130561Sobrienelf_gc_propagate_vtable_entries_used (struct elf_link_hash_entry *h, void *okp) 10694130561Sobrien{ 10695130561Sobrien if (h->root.type == bfd_link_hash_warning) 10696130561Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 10697130561Sobrien 10698130561Sobrien /* Those that are not vtables. */ 10699218822Sdim if (h->vtable == NULL || h->vtable->parent == NULL) 10700130561Sobrien return TRUE; 10701130561Sobrien 10702130561Sobrien /* Those vtables that do not have parents, we cannot merge. */ 10703218822Sdim if (h->vtable->parent == (struct elf_link_hash_entry *) -1) 10704130561Sobrien return TRUE; 10705130561Sobrien 10706130561Sobrien /* If we've already been done, exit. */ 10707218822Sdim if (h->vtable->used && h->vtable->used[-1]) 10708130561Sobrien return TRUE; 10709130561Sobrien 10710130561Sobrien /* Make sure the parent's table is up to date. */ 10711218822Sdim elf_gc_propagate_vtable_entries_used (h->vtable->parent, okp); 10712130561Sobrien 10713218822Sdim if (h->vtable->used == NULL) 10714130561Sobrien { 10715130561Sobrien /* None of this table's entries were referenced. Re-use the 10716130561Sobrien parent's table. */ 10717218822Sdim h->vtable->used = h->vtable->parent->vtable->used; 10718218822Sdim h->vtable->size = h->vtable->parent->vtable->size; 10719130561Sobrien } 10720130561Sobrien else 10721130561Sobrien { 10722130561Sobrien size_t n; 10723130561Sobrien bfd_boolean *cu, *pu; 10724130561Sobrien 10725130561Sobrien /* Or the parent's entries into ours. */ 10726218822Sdim cu = h->vtable->used; 10727130561Sobrien cu[-1] = TRUE; 10728218822Sdim pu = h->vtable->parent->vtable->used; 10729130561Sobrien if (pu != NULL) 10730130561Sobrien { 10731130561Sobrien const struct elf_backend_data *bed; 10732130561Sobrien unsigned int log_file_align; 10733130561Sobrien 10734130561Sobrien bed = get_elf_backend_data (h->root.u.def.section->owner); 10735130561Sobrien log_file_align = bed->s->log_file_align; 10736218822Sdim n = h->vtable->parent->vtable->size >> log_file_align; 10737130561Sobrien while (n--) 10738130561Sobrien { 10739130561Sobrien if (*pu) 10740130561Sobrien *cu = TRUE; 10741130561Sobrien pu++; 10742130561Sobrien cu++; 10743130561Sobrien } 10744130561Sobrien } 10745130561Sobrien } 10746130561Sobrien 10747130561Sobrien return TRUE; 10748130561Sobrien} 10749130561Sobrien 10750130561Sobrienstatic bfd_boolean 10751130561Sobrienelf_gc_smash_unused_vtentry_relocs (struct elf_link_hash_entry *h, void *okp) 10752130561Sobrien{ 10753130561Sobrien asection *sec; 10754130561Sobrien bfd_vma hstart, hend; 10755130561Sobrien Elf_Internal_Rela *relstart, *relend, *rel; 10756130561Sobrien const struct elf_backend_data *bed; 10757130561Sobrien unsigned int log_file_align; 10758130561Sobrien 10759130561Sobrien if (h->root.type == bfd_link_hash_warning) 10760130561Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 10761130561Sobrien 10762130561Sobrien /* Take care of both those symbols that do not describe vtables as 10763130561Sobrien well as those that are not loaded. */ 10764218822Sdim if (h->vtable == NULL || h->vtable->parent == NULL) 10765130561Sobrien return TRUE; 10766130561Sobrien 10767130561Sobrien BFD_ASSERT (h->root.type == bfd_link_hash_defined 10768130561Sobrien || h->root.type == bfd_link_hash_defweak); 10769130561Sobrien 10770130561Sobrien sec = h->root.u.def.section; 10771130561Sobrien hstart = h->root.u.def.value; 10772130561Sobrien hend = hstart + h->size; 10773130561Sobrien 10774130561Sobrien relstart = _bfd_elf_link_read_relocs (sec->owner, sec, NULL, NULL, TRUE); 10775130561Sobrien if (!relstart) 10776130561Sobrien return *(bfd_boolean *) okp = FALSE; 10777130561Sobrien bed = get_elf_backend_data (sec->owner); 10778130561Sobrien log_file_align = bed->s->log_file_align; 10779130561Sobrien 10780130561Sobrien relend = relstart + sec->reloc_count * bed->s->int_rels_per_ext_rel; 10781130561Sobrien 10782130561Sobrien for (rel = relstart; rel < relend; ++rel) 10783130561Sobrien if (rel->r_offset >= hstart && rel->r_offset < hend) 10784130561Sobrien { 10785130561Sobrien /* If the entry is in use, do nothing. */ 10786218822Sdim if (h->vtable->used 10787218822Sdim && (rel->r_offset - hstart) < h->vtable->size) 10788130561Sobrien { 10789130561Sobrien bfd_vma entry = (rel->r_offset - hstart) >> log_file_align; 10790218822Sdim if (h->vtable->used[entry]) 10791130561Sobrien continue; 10792130561Sobrien } 10793130561Sobrien /* Otherwise, kill it. */ 10794130561Sobrien rel->r_offset = rel->r_info = rel->r_addend = 0; 10795130561Sobrien } 10796130561Sobrien 10797130561Sobrien return TRUE; 10798130561Sobrien} 10799130561Sobrien 10800218822Sdim/* Mark sections containing dynamically referenced symbols. When 10801218822Sdim building shared libraries, we must assume that any visible symbol is 10802218822Sdim referenced. */ 10803218822Sdim 10804218822Sdimbfd_boolean 10805218822Sdimbfd_elf_gc_mark_dynamic_ref_symbol (struct elf_link_hash_entry *h, void *inf) 10806218822Sdim{ 10807218822Sdim struct bfd_link_info *info = (struct bfd_link_info *) inf; 10808218822Sdim 10809218822Sdim if (h->root.type == bfd_link_hash_warning) 10810218822Sdim h = (struct elf_link_hash_entry *) h->root.u.i.link; 10811218822Sdim 10812218822Sdim if ((h->root.type == bfd_link_hash_defined 10813218822Sdim || h->root.type == bfd_link_hash_defweak) 10814218822Sdim && (h->ref_dynamic 10815218822Sdim || (!info->executable 10816218822Sdim && h->def_regular 10817218822Sdim && ELF_ST_VISIBILITY (h->other) != STV_INTERNAL 10818218822Sdim && ELF_ST_VISIBILITY (h->other) != STV_HIDDEN))) 10819218822Sdim h->root.u.def.section->flags |= SEC_KEEP; 10820218822Sdim 10821218822Sdim return TRUE; 10822218822Sdim} 10823218822Sdim 10824130561Sobrien/* Do mark and sweep of unused sections. */ 10825130561Sobrien 10826130561Sobrienbfd_boolean 10827130561Sobrienbfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info) 10828130561Sobrien{ 10829130561Sobrien bfd_boolean ok = TRUE; 10830130561Sobrien bfd *sub; 10831218822Sdim elf_gc_mark_hook_fn gc_mark_hook; 10832218822Sdim const struct elf_backend_data *bed = get_elf_backend_data (abfd); 10833130561Sobrien 10834218822Sdim if (!bed->can_gc_sections 10835130561Sobrien || info->relocatable 10836130561Sobrien || info->emitrelocations 10837218822Sdim || !is_elf_hash_table (info->hash)) 10838130561Sobrien { 10839130561Sobrien (*_bfd_error_handler)(_("Warning: gc-sections option ignored")); 10840130561Sobrien return TRUE; 10841130561Sobrien } 10842130561Sobrien 10843130561Sobrien /* Apply transitive closure to the vtable entry usage info. */ 10844130561Sobrien elf_link_hash_traverse (elf_hash_table (info), 10845130561Sobrien elf_gc_propagate_vtable_entries_used, 10846130561Sobrien &ok); 10847130561Sobrien if (!ok) 10848130561Sobrien return FALSE; 10849130561Sobrien 10850130561Sobrien /* Kill the vtable relocations that were not used. */ 10851130561Sobrien elf_link_hash_traverse (elf_hash_table (info), 10852130561Sobrien elf_gc_smash_unused_vtentry_relocs, 10853130561Sobrien &ok); 10854130561Sobrien if (!ok) 10855130561Sobrien return FALSE; 10856130561Sobrien 10857218822Sdim /* Mark dynamically referenced symbols. */ 10858218822Sdim if (elf_hash_table (info)->dynamic_sections_created) 10859218822Sdim elf_link_hash_traverse (elf_hash_table (info), 10860218822Sdim bed->gc_mark_dynamic_ref, 10861218822Sdim info); 10862218822Sdim 10863130561Sobrien /* Grovel through relocs to find out who stays ... */ 10864218822Sdim gc_mark_hook = bed->gc_mark_hook; 10865218822Sdim for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) 10866218822Sdim { 10867218822Sdim asection *o; 10868130561Sobrien 10869218822Sdim if (bfd_get_flavour (sub) != bfd_target_elf_flavour) 10870218822Sdim continue; 10871218822Sdim 10872218822Sdim for (o = sub->sections; o != NULL; o = o->next) 10873218822Sdim if ((o->flags & (SEC_EXCLUDE | SEC_KEEP)) == SEC_KEEP && !o->gc_mark) 10874218822Sdim if (!_bfd_elf_gc_mark (info, o, gc_mark_hook)) 10875218822Sdim return FALSE; 10876218822Sdim } 10877218822Sdim 10878218822Sdim /* Allow the backend to mark additional target specific sections. */ 10879218822Sdim if (bed->gc_mark_extra_sections) 10880218822Sdim bed->gc_mark_extra_sections(info, gc_mark_hook); 10881218822Sdim 10882218822Sdim /* ... again for sections marked from eh_frame. */ 10883130561Sobrien for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) 10884130561Sobrien { 10885130561Sobrien asection *o; 10886130561Sobrien 10887130561Sobrien if (bfd_get_flavour (sub) != bfd_target_elf_flavour) 10888130561Sobrien continue; 10889130561Sobrien 10890218822Sdim /* Keep .gcc_except_table.* if the associated .text.* (or the 10891218822Sdim associated .gnu.linkonce.t.* if .text.* doesn't exist) is 10892218822Sdim marked. This isn't very nice, but the proper solution, 10893218822Sdim splitting .eh_frame up and using comdat doesn't pan out 10894218822Sdim easily due to needing special relocs to handle the 10895218822Sdim difference of two symbols in separate sections. 10896218822Sdim Don't keep code sections referenced by .eh_frame. */ 10897218822Sdim#define TEXT_PREFIX ".text." 10898218822Sdim#define TEXT_PREFIX2 ".gnu.linkonce.t." 10899218822Sdim#define GCC_EXCEPT_TABLE_PREFIX ".gcc_except_table." 10900130561Sobrien for (o = sub->sections; o != NULL; o = o->next) 10901218822Sdim if (!o->gc_mark && o->gc_mark_from_eh && (o->flags & SEC_CODE) == 0) 10902218822Sdim { 10903218822Sdim if (CONST_STRNEQ (o->name, GCC_EXCEPT_TABLE_PREFIX)) 10904218822Sdim { 10905218822Sdim char *fn_name; 10906218822Sdim const char *sec_name; 10907218822Sdim asection *fn_text; 10908218822Sdim unsigned o_name_prefix_len , fn_name_prefix_len, tmp; 10909218822Sdim 10910218822Sdim o_name_prefix_len = strlen (GCC_EXCEPT_TABLE_PREFIX); 10911218822Sdim sec_name = o->name + o_name_prefix_len; 10912218822Sdim fn_name_prefix_len = strlen (TEXT_PREFIX); 10913218822Sdim tmp = strlen (TEXT_PREFIX2); 10914218822Sdim if (tmp > fn_name_prefix_len) 10915218822Sdim fn_name_prefix_len = tmp; 10916218822Sdim fn_name 10917218822Sdim = bfd_malloc (fn_name_prefix_len + strlen (sec_name) + 1); 10918218822Sdim if (fn_name == NULL) 10919218822Sdim return FALSE; 10920218822Sdim 10921218822Sdim /* Try the first prefix. */ 10922218822Sdim sprintf (fn_name, "%s%s", TEXT_PREFIX, sec_name); 10923218822Sdim fn_text = bfd_get_section_by_name (sub, fn_name); 10924218822Sdim 10925218822Sdim /* Try the second prefix. */ 10926218822Sdim if (fn_text == NULL) 10927218822Sdim { 10928218822Sdim sprintf (fn_name, "%s%s", TEXT_PREFIX2, sec_name); 10929218822Sdim fn_text = bfd_get_section_by_name (sub, fn_name); 10930218822Sdim } 10931218822Sdim 10932218822Sdim free (fn_name); 10933218822Sdim if (fn_text == NULL || !fn_text->gc_mark) 10934218822Sdim continue; 10935218822Sdim } 10936218822Sdim 10937218822Sdim /* If not using specially named exception table section, 10938218822Sdim then keep whatever we are using. */ 10939218822Sdim if (!_bfd_elf_gc_mark (info, o, gc_mark_hook)) 10940130561Sobrien return FALSE; 10941218822Sdim } 10942130561Sobrien } 10943130561Sobrien 10944130561Sobrien /* ... and mark SEC_EXCLUDE for those that go. */ 10945218822Sdim return elf_gc_sweep (abfd, info); 10946130561Sobrien} 1094733965Sjdp 10948130561Sobrien/* Called from check_relocs to record the existence of a VTINHERIT reloc. */ 1094933965Sjdp 10950130561Sobrienbfd_boolean 10951130561Sobrienbfd_elf_gc_record_vtinherit (bfd *abfd, 10952130561Sobrien asection *sec, 10953130561Sobrien struct elf_link_hash_entry *h, 10954130561Sobrien bfd_vma offset) 1095533965Sjdp{ 10956130561Sobrien struct elf_link_hash_entry **sym_hashes, **sym_hashes_end; 10957130561Sobrien struct elf_link_hash_entry **search, *child; 10958130561Sobrien bfd_size_type extsymcount; 10959130561Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 1096033965Sjdp 10961130561Sobrien /* The sh_info field of the symtab header tells us where the 10962130561Sobrien external symbols start. We don't care about the local symbols at 10963130561Sobrien this point. */ 10964130561Sobrien extsymcount = elf_tdata (abfd)->symtab_hdr.sh_size / bed->s->sizeof_sym; 10965130561Sobrien if (!elf_bad_symtab (abfd)) 10966130561Sobrien extsymcount -= elf_tdata (abfd)->symtab_hdr.sh_info; 10967130561Sobrien 10968130561Sobrien sym_hashes = elf_sym_hashes (abfd); 10969130561Sobrien sym_hashes_end = sym_hashes + extsymcount; 10970130561Sobrien 10971130561Sobrien /* Hunt down the child symbol, which is in this section at the same 10972130561Sobrien offset as the relocation. */ 10973130561Sobrien for (search = sym_hashes; search != sym_hashes_end; ++search) 1097433965Sjdp { 10975130561Sobrien if ((child = *search) != NULL 10976130561Sobrien && (child->root.type == bfd_link_hash_defined 10977130561Sobrien || child->root.type == bfd_link_hash_defweak) 10978130561Sobrien && child->root.u.def.section == sec 10979130561Sobrien && child->root.u.def.value == offset) 10980130561Sobrien goto win; 1098133965Sjdp } 1098233965Sjdp 10983218822Sdim (*_bfd_error_handler) ("%B: %A+%lu: No symbol found for INHERIT", 10984218822Sdim abfd, sec, (unsigned long) offset); 10985130561Sobrien bfd_set_error (bfd_error_invalid_operation); 10986130561Sobrien return FALSE; 10987130561Sobrien 10988130561Sobrien win: 10989218822Sdim if (!child->vtable) 10990218822Sdim { 10991218822Sdim child->vtable = bfd_zalloc (abfd, sizeof (*child->vtable)); 10992218822Sdim if (!child->vtable) 10993218822Sdim return FALSE; 10994218822Sdim } 10995130561Sobrien if (!h) 10996130561Sobrien { 10997130561Sobrien /* This *should* only be the absolute section. It could potentially 10998130561Sobrien be that someone has defined a non-global vtable though, which 10999130561Sobrien would be bad. It isn't worth paging in the local symbols to be 11000130561Sobrien sure though; that case should simply be handled by the assembler. */ 11001130561Sobrien 11002218822Sdim child->vtable->parent = (struct elf_link_hash_entry *) -1; 11003130561Sobrien } 11004130561Sobrien else 11005218822Sdim child->vtable->parent = h; 11006130561Sobrien 11007130561Sobrien return TRUE; 1100833965Sjdp} 11009130561Sobrien 11010130561Sobrien/* Called from check_relocs to record the existence of a VTENTRY reloc. */ 11011130561Sobrien 11012130561Sobrienbfd_boolean 11013130561Sobrienbfd_elf_gc_record_vtentry (bfd *abfd ATTRIBUTE_UNUSED, 11014130561Sobrien asection *sec ATTRIBUTE_UNUSED, 11015130561Sobrien struct elf_link_hash_entry *h, 11016130561Sobrien bfd_vma addend) 11017130561Sobrien{ 11018130561Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 11019130561Sobrien unsigned int log_file_align = bed->s->log_file_align; 11020130561Sobrien 11021218822Sdim if (!h->vtable) 11022130561Sobrien { 11023218822Sdim h->vtable = bfd_zalloc (abfd, sizeof (*h->vtable)); 11024218822Sdim if (!h->vtable) 11025218822Sdim return FALSE; 11026218822Sdim } 11027218822Sdim 11028218822Sdim if (addend >= h->vtable->size) 11029218822Sdim { 11030130561Sobrien size_t size, bytes, file_align; 11031218822Sdim bfd_boolean *ptr = h->vtable->used; 11032130561Sobrien 11033130561Sobrien /* While the symbol is undefined, we have to be prepared to handle 11034130561Sobrien a zero size. */ 11035130561Sobrien file_align = 1 << log_file_align; 11036130561Sobrien if (h->root.type == bfd_link_hash_undefined) 11037130561Sobrien size = addend + file_align; 11038130561Sobrien else 11039130561Sobrien { 11040130561Sobrien size = h->size; 11041130561Sobrien if (addend >= size) 11042130561Sobrien { 11043130561Sobrien /* Oops! We've got a reference past the defined end of 11044130561Sobrien the table. This is probably a bug -- shall we warn? */ 11045130561Sobrien size = addend + file_align; 11046130561Sobrien } 11047130561Sobrien } 11048130561Sobrien size = (size + file_align - 1) & -file_align; 11049130561Sobrien 11050130561Sobrien /* Allocate one extra entry for use as a "done" flag for the 11051130561Sobrien consolidation pass. */ 11052130561Sobrien bytes = ((size >> log_file_align) + 1) * sizeof (bfd_boolean); 11053130561Sobrien 11054130561Sobrien if (ptr) 11055130561Sobrien { 11056130561Sobrien ptr = bfd_realloc (ptr - 1, bytes); 11057130561Sobrien 11058130561Sobrien if (ptr != NULL) 11059130561Sobrien { 11060130561Sobrien size_t oldbytes; 11061130561Sobrien 11062218822Sdim oldbytes = (((h->vtable->size >> log_file_align) + 1) 11063130561Sobrien * sizeof (bfd_boolean)); 11064130561Sobrien memset (((char *) ptr) + oldbytes, 0, bytes - oldbytes); 11065130561Sobrien } 11066130561Sobrien } 11067130561Sobrien else 11068130561Sobrien ptr = bfd_zmalloc (bytes); 11069130561Sobrien 11070130561Sobrien if (ptr == NULL) 11071130561Sobrien return FALSE; 11072130561Sobrien 11073130561Sobrien /* And arrange for that done flag to be at index -1. */ 11074218822Sdim h->vtable->used = ptr + 1; 11075218822Sdim h->vtable->size = size; 11076130561Sobrien } 11077130561Sobrien 11078218822Sdim h->vtable->used[addend >> log_file_align] = TRUE; 11079130561Sobrien 11080130561Sobrien return TRUE; 11081130561Sobrien} 11082130561Sobrien 11083130561Sobrienstruct alloc_got_off_arg { 11084130561Sobrien bfd_vma gotoff; 11085130561Sobrien unsigned int got_elt_size; 11086130561Sobrien}; 11087130561Sobrien 11088130561Sobrien/* We need a special top-level link routine to convert got reference counts 11089130561Sobrien to real got offsets. */ 11090130561Sobrien 11091130561Sobrienstatic bfd_boolean 11092130561Sobrienelf_gc_allocate_got_offsets (struct elf_link_hash_entry *h, void *arg) 11093130561Sobrien{ 11094130561Sobrien struct alloc_got_off_arg *gofarg = arg; 11095130561Sobrien 11096130561Sobrien if (h->root.type == bfd_link_hash_warning) 11097130561Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 11098130561Sobrien 11099130561Sobrien if (h->got.refcount > 0) 11100130561Sobrien { 11101130561Sobrien h->got.offset = gofarg->gotoff; 11102130561Sobrien gofarg->gotoff += gofarg->got_elt_size; 11103130561Sobrien } 11104130561Sobrien else 11105130561Sobrien h->got.offset = (bfd_vma) -1; 11106130561Sobrien 11107130561Sobrien return TRUE; 11108130561Sobrien} 11109130561Sobrien 11110130561Sobrien/* And an accompanying bit to work out final got entry offsets once 11111130561Sobrien we're done. Should be called from final_link. */ 11112130561Sobrien 11113130561Sobrienbfd_boolean 11114130561Sobrienbfd_elf_gc_common_finalize_got_offsets (bfd *abfd, 11115130561Sobrien struct bfd_link_info *info) 11116130561Sobrien{ 11117130561Sobrien bfd *i; 11118130561Sobrien const struct elf_backend_data *bed = get_elf_backend_data (abfd); 11119130561Sobrien bfd_vma gotoff; 11120130561Sobrien unsigned int got_elt_size = bed->s->arch_size / 8; 11121130561Sobrien struct alloc_got_off_arg gofarg; 11122130561Sobrien 11123130561Sobrien if (! is_elf_hash_table (info->hash)) 11124130561Sobrien return FALSE; 11125130561Sobrien 11126130561Sobrien /* The GOT offset is relative to the .got section, but the GOT header is 11127130561Sobrien put into the .got.plt section, if the backend uses it. */ 11128130561Sobrien if (bed->want_got_plt) 11129130561Sobrien gotoff = 0; 11130130561Sobrien else 11131130561Sobrien gotoff = bed->got_header_size; 11132130561Sobrien 11133130561Sobrien /* Do the local .got entries first. */ 11134130561Sobrien for (i = info->input_bfds; i; i = i->link_next) 11135130561Sobrien { 11136130561Sobrien bfd_signed_vma *local_got; 11137130561Sobrien bfd_size_type j, locsymcount; 11138130561Sobrien Elf_Internal_Shdr *symtab_hdr; 11139130561Sobrien 11140130561Sobrien if (bfd_get_flavour (i) != bfd_target_elf_flavour) 11141130561Sobrien continue; 11142130561Sobrien 11143130561Sobrien local_got = elf_local_got_refcounts (i); 11144130561Sobrien if (!local_got) 11145130561Sobrien continue; 11146130561Sobrien 11147130561Sobrien symtab_hdr = &elf_tdata (i)->symtab_hdr; 11148130561Sobrien if (elf_bad_symtab (i)) 11149130561Sobrien locsymcount = symtab_hdr->sh_size / bed->s->sizeof_sym; 11150130561Sobrien else 11151130561Sobrien locsymcount = symtab_hdr->sh_info; 11152130561Sobrien 11153130561Sobrien for (j = 0; j < locsymcount; ++j) 11154130561Sobrien { 11155130561Sobrien if (local_got[j] > 0) 11156130561Sobrien { 11157130561Sobrien local_got[j] = gotoff; 11158130561Sobrien gotoff += got_elt_size; 11159130561Sobrien } 11160130561Sobrien else 11161130561Sobrien local_got[j] = (bfd_vma) -1; 11162130561Sobrien } 11163130561Sobrien } 11164130561Sobrien 11165130561Sobrien /* Then the global .got entries. .plt refcounts are handled by 11166130561Sobrien adjust_dynamic_symbol */ 11167130561Sobrien gofarg.gotoff = gotoff; 11168130561Sobrien gofarg.got_elt_size = got_elt_size; 11169130561Sobrien elf_link_hash_traverse (elf_hash_table (info), 11170130561Sobrien elf_gc_allocate_got_offsets, 11171130561Sobrien &gofarg); 11172130561Sobrien return TRUE; 11173130561Sobrien} 11174130561Sobrien 11175130561Sobrien/* Many folk need no more in the way of final link than this, once 11176130561Sobrien got entry reference counting is enabled. */ 11177130561Sobrien 11178130561Sobrienbfd_boolean 11179130561Sobrienbfd_elf_gc_common_final_link (bfd *abfd, struct bfd_link_info *info) 11180130561Sobrien{ 11181130561Sobrien if (!bfd_elf_gc_common_finalize_got_offsets (abfd, info)) 11182130561Sobrien return FALSE; 11183130561Sobrien 11184130561Sobrien /* Invoke the regular ELF backend linker to do all the work. */ 11185130561Sobrien return bfd_elf_final_link (abfd, info); 11186130561Sobrien} 11187130561Sobrien 11188130561Sobrienbfd_boolean 11189130561Sobrienbfd_elf_reloc_symbol_deleted_p (bfd_vma offset, void *cookie) 11190130561Sobrien{ 11191130561Sobrien struct elf_reloc_cookie *rcookie = cookie; 11192130561Sobrien 11193130561Sobrien if (rcookie->bad_symtab) 11194130561Sobrien rcookie->rel = rcookie->rels; 11195130561Sobrien 11196130561Sobrien for (; rcookie->rel < rcookie->relend; rcookie->rel++) 11197130561Sobrien { 11198130561Sobrien unsigned long r_symndx; 11199130561Sobrien 11200130561Sobrien if (! rcookie->bad_symtab) 11201130561Sobrien if (rcookie->rel->r_offset > offset) 11202130561Sobrien return FALSE; 11203130561Sobrien if (rcookie->rel->r_offset != offset) 11204130561Sobrien continue; 11205130561Sobrien 11206130561Sobrien r_symndx = rcookie->rel->r_info >> rcookie->r_sym_shift; 11207130561Sobrien if (r_symndx == SHN_UNDEF) 11208130561Sobrien return TRUE; 11209130561Sobrien 11210130561Sobrien if (r_symndx >= rcookie->locsymcount 11211130561Sobrien || ELF_ST_BIND (rcookie->locsyms[r_symndx].st_info) != STB_LOCAL) 11212130561Sobrien { 11213130561Sobrien struct elf_link_hash_entry *h; 11214130561Sobrien 11215130561Sobrien h = rcookie->sym_hashes[r_symndx - rcookie->extsymoff]; 11216130561Sobrien 11217130561Sobrien while (h->root.type == bfd_link_hash_indirect 11218130561Sobrien || h->root.type == bfd_link_hash_warning) 11219130561Sobrien h = (struct elf_link_hash_entry *) h->root.u.i.link; 11220130561Sobrien 11221130561Sobrien if ((h->root.type == bfd_link_hash_defined 11222130561Sobrien || h->root.type == bfd_link_hash_defweak) 11223130561Sobrien && elf_discarded_section (h->root.u.def.section)) 11224130561Sobrien return TRUE; 11225130561Sobrien else 11226130561Sobrien return FALSE; 11227130561Sobrien } 11228130561Sobrien else 11229130561Sobrien { 11230130561Sobrien /* It's not a relocation against a global symbol, 11231130561Sobrien but it could be a relocation against a local 11232130561Sobrien symbol for a discarded section. */ 11233130561Sobrien asection *isec; 11234130561Sobrien Elf_Internal_Sym *isym; 11235130561Sobrien 11236130561Sobrien /* Need to: get the symbol; get the section. */ 11237130561Sobrien isym = &rcookie->locsyms[r_symndx]; 11238130561Sobrien if (isym->st_shndx < SHN_LORESERVE || isym->st_shndx > SHN_HIRESERVE) 11239130561Sobrien { 11240130561Sobrien isec = bfd_section_from_elf_index (rcookie->abfd, isym->st_shndx); 11241130561Sobrien if (isec != NULL && elf_discarded_section (isec)) 11242130561Sobrien return TRUE; 11243130561Sobrien } 11244130561Sobrien } 11245130561Sobrien return FALSE; 11246130561Sobrien } 11247130561Sobrien return FALSE; 11248130561Sobrien} 11249130561Sobrien 11250130561Sobrien/* Discard unneeded references to discarded sections. 11251130561Sobrien Returns TRUE if any section's size was changed. */ 11252130561Sobrien/* This function assumes that the relocations are in sorted order, 11253130561Sobrien which is true for all known assemblers. */ 11254130561Sobrien 11255130561Sobrienbfd_boolean 11256130561Sobrienbfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info) 11257130561Sobrien{ 11258130561Sobrien struct elf_reloc_cookie cookie; 11259130561Sobrien asection *stab, *eh; 11260130561Sobrien Elf_Internal_Shdr *symtab_hdr; 11261130561Sobrien const struct elf_backend_data *bed; 11262130561Sobrien bfd *abfd; 11263130561Sobrien unsigned int count; 11264130561Sobrien bfd_boolean ret = FALSE; 11265130561Sobrien 11266130561Sobrien if (info->traditional_format 11267130561Sobrien || !is_elf_hash_table (info->hash)) 11268130561Sobrien return FALSE; 11269130561Sobrien 11270130561Sobrien for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next) 11271130561Sobrien { 11272130561Sobrien if (bfd_get_flavour (abfd) != bfd_target_elf_flavour) 11273130561Sobrien continue; 11274130561Sobrien 11275130561Sobrien bed = get_elf_backend_data (abfd); 11276130561Sobrien 11277130561Sobrien if ((abfd->flags & DYNAMIC) != 0) 11278130561Sobrien continue; 11279130561Sobrien 11280218822Sdim eh = NULL; 11281218822Sdim if (!info->relocatable) 11282218822Sdim { 11283218822Sdim eh = bfd_get_section_by_name (abfd, ".eh_frame"); 11284218822Sdim if (eh != NULL 11285218822Sdim && (eh->size == 0 11286218822Sdim || bfd_is_abs_section (eh->output_section))) 11287218822Sdim eh = NULL; 11288218822Sdim } 11289130561Sobrien 11290130561Sobrien stab = bfd_get_section_by_name (abfd, ".stab"); 11291130561Sobrien if (stab != NULL 11292218822Sdim && (stab->size == 0 11293130561Sobrien || bfd_is_abs_section (stab->output_section) 11294130561Sobrien || stab->sec_info_type != ELF_INFO_TYPE_STABS)) 11295130561Sobrien stab = NULL; 11296130561Sobrien 11297130561Sobrien if (stab == NULL 11298130561Sobrien && eh == NULL 11299130561Sobrien && bed->elf_backend_discard_info == NULL) 11300130561Sobrien continue; 11301130561Sobrien 11302130561Sobrien symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 11303130561Sobrien cookie.abfd = abfd; 11304130561Sobrien cookie.sym_hashes = elf_sym_hashes (abfd); 11305130561Sobrien cookie.bad_symtab = elf_bad_symtab (abfd); 11306130561Sobrien if (cookie.bad_symtab) 11307130561Sobrien { 11308130561Sobrien cookie.locsymcount = symtab_hdr->sh_size / bed->s->sizeof_sym; 11309130561Sobrien cookie.extsymoff = 0; 11310130561Sobrien } 11311130561Sobrien else 11312130561Sobrien { 11313130561Sobrien cookie.locsymcount = symtab_hdr->sh_info; 11314130561Sobrien cookie.extsymoff = symtab_hdr->sh_info; 11315130561Sobrien } 11316130561Sobrien 11317130561Sobrien if (bed->s->arch_size == 32) 11318130561Sobrien cookie.r_sym_shift = 8; 11319130561Sobrien else 11320130561Sobrien cookie.r_sym_shift = 32; 11321130561Sobrien 11322130561Sobrien cookie.locsyms = (Elf_Internal_Sym *) symtab_hdr->contents; 11323130561Sobrien if (cookie.locsyms == NULL && cookie.locsymcount != 0) 11324130561Sobrien { 11325130561Sobrien cookie.locsyms = bfd_elf_get_elf_syms (abfd, symtab_hdr, 11326130561Sobrien cookie.locsymcount, 0, 11327130561Sobrien NULL, NULL, NULL); 11328130561Sobrien if (cookie.locsyms == NULL) 11329218822Sdim { 11330218822Sdim info->callbacks->einfo (_("%P%X: can not read symbols: %E\n")); 11331218822Sdim return FALSE; 11332218822Sdim } 11333130561Sobrien } 11334130561Sobrien 11335130561Sobrien if (stab != NULL) 11336130561Sobrien { 11337130561Sobrien cookie.rels = NULL; 11338130561Sobrien count = stab->reloc_count; 11339130561Sobrien if (count != 0) 11340130561Sobrien cookie.rels = _bfd_elf_link_read_relocs (abfd, stab, NULL, NULL, 11341130561Sobrien info->keep_memory); 11342130561Sobrien if (cookie.rels != NULL) 11343130561Sobrien { 11344130561Sobrien cookie.rel = cookie.rels; 11345130561Sobrien cookie.relend = cookie.rels; 11346130561Sobrien cookie.relend += count * bed->s->int_rels_per_ext_rel; 11347130561Sobrien if (_bfd_discard_section_stabs (abfd, stab, 11348130561Sobrien elf_section_data (stab)->sec_info, 11349130561Sobrien bfd_elf_reloc_symbol_deleted_p, 11350130561Sobrien &cookie)) 11351130561Sobrien ret = TRUE; 11352130561Sobrien if (elf_section_data (stab)->relocs != cookie.rels) 11353130561Sobrien free (cookie.rels); 11354130561Sobrien } 11355130561Sobrien } 11356130561Sobrien 11357130561Sobrien if (eh != NULL) 11358130561Sobrien { 11359130561Sobrien cookie.rels = NULL; 11360130561Sobrien count = eh->reloc_count; 11361130561Sobrien if (count != 0) 11362130561Sobrien cookie.rels = _bfd_elf_link_read_relocs (abfd, eh, NULL, NULL, 11363130561Sobrien info->keep_memory); 11364130561Sobrien cookie.rel = cookie.rels; 11365130561Sobrien cookie.relend = cookie.rels; 11366130561Sobrien if (cookie.rels != NULL) 11367130561Sobrien cookie.relend += count * bed->s->int_rels_per_ext_rel; 11368130561Sobrien 11369130561Sobrien if (_bfd_elf_discard_section_eh_frame (abfd, info, eh, 11370130561Sobrien bfd_elf_reloc_symbol_deleted_p, 11371130561Sobrien &cookie)) 11372130561Sobrien ret = TRUE; 11373130561Sobrien 11374130561Sobrien if (cookie.rels != NULL 11375130561Sobrien && elf_section_data (eh)->relocs != cookie.rels) 11376130561Sobrien free (cookie.rels); 11377130561Sobrien } 11378130561Sobrien 11379130561Sobrien if (bed->elf_backend_discard_info != NULL 11380130561Sobrien && (*bed->elf_backend_discard_info) (abfd, &cookie, info)) 11381130561Sobrien ret = TRUE; 11382130561Sobrien 11383130561Sobrien if (cookie.locsyms != NULL 11384130561Sobrien && symtab_hdr->contents != (unsigned char *) cookie.locsyms) 11385130561Sobrien { 11386130561Sobrien if (! info->keep_memory) 11387130561Sobrien free (cookie.locsyms); 11388130561Sobrien else 11389130561Sobrien symtab_hdr->contents = (unsigned char *) cookie.locsyms; 11390130561Sobrien } 11391130561Sobrien } 11392130561Sobrien 11393130561Sobrien if (info->eh_frame_hdr 11394130561Sobrien && !info->relocatable 11395130561Sobrien && _bfd_elf_discard_section_eh_frame_hdr (output_bfd, info)) 11396130561Sobrien ret = TRUE; 11397130561Sobrien 11398130561Sobrien return ret; 11399130561Sobrien} 11400218822Sdim 11401218822Sdimvoid 11402218822Sdim_bfd_elf_section_already_linked (bfd *abfd, struct bfd_section *sec, 11403218822Sdim struct bfd_link_info *info) 11404218822Sdim{ 11405218822Sdim flagword flags; 11406218822Sdim const char *name, *p; 11407218822Sdim struct bfd_section_already_linked *l; 11408218822Sdim struct bfd_section_already_linked_hash_entry *already_linked_list; 11409218822Sdim 11410218822Sdim if (sec->output_section == bfd_abs_section_ptr) 11411218822Sdim return; 11412218822Sdim 11413218822Sdim flags = sec->flags; 11414218822Sdim 11415218822Sdim /* Return if it isn't a linkonce section. A comdat group section 11416218822Sdim also has SEC_LINK_ONCE set. */ 11417218822Sdim if ((flags & SEC_LINK_ONCE) == 0) 11418218822Sdim return; 11419218822Sdim 11420218822Sdim /* Don't put group member sections on our list of already linked 11421218822Sdim sections. They are handled as a group via their group section. */ 11422218822Sdim if (elf_sec_group (sec) != NULL) 11423218822Sdim return; 11424218822Sdim 11425218822Sdim /* FIXME: When doing a relocatable link, we may have trouble 11426218822Sdim copying relocations in other sections that refer to local symbols 11427218822Sdim in the section being discarded. Those relocations will have to 11428218822Sdim be converted somehow; as of this writing I'm not sure that any of 11429218822Sdim the backends handle that correctly. 11430218822Sdim 11431218822Sdim It is tempting to instead not discard link once sections when 11432218822Sdim doing a relocatable link (technically, they should be discarded 11433218822Sdim whenever we are building constructors). However, that fails, 11434218822Sdim because the linker winds up combining all the link once sections 11435218822Sdim into a single large link once section, which defeats the purpose 11436218822Sdim of having link once sections in the first place. 11437218822Sdim 11438218822Sdim Also, not merging link once sections in a relocatable link 11439218822Sdim causes trouble for MIPS ELF, which relies on link once semantics 11440218822Sdim to handle the .reginfo section correctly. */ 11441218822Sdim 11442218822Sdim name = bfd_get_section_name (abfd, sec); 11443218822Sdim 11444218822Sdim if (CONST_STRNEQ (name, ".gnu.linkonce.") 11445218822Sdim && (p = strchr (name + sizeof (".gnu.linkonce.") - 1, '.')) != NULL) 11446218822Sdim p++; 11447218822Sdim else 11448218822Sdim p = name; 11449218822Sdim 11450218822Sdim already_linked_list = bfd_section_already_linked_table_lookup (p); 11451218822Sdim 11452218822Sdim for (l = already_linked_list->entry; l != NULL; l = l->next) 11453218822Sdim { 11454218822Sdim /* We may have 2 different types of sections on the list: group 11455218822Sdim sections and linkonce sections. Match like sections. */ 11456218822Sdim if ((flags & SEC_GROUP) == (l->sec->flags & SEC_GROUP) 11457218822Sdim && strcmp (name, l->sec->name) == 0 11458218822Sdim && bfd_coff_get_comdat_section (l->sec->owner, l->sec) == NULL) 11459218822Sdim { 11460218822Sdim /* The section has already been linked. See if we should 11461218822Sdim issue a warning. */ 11462218822Sdim switch (flags & SEC_LINK_DUPLICATES) 11463218822Sdim { 11464218822Sdim default: 11465218822Sdim abort (); 11466218822Sdim 11467218822Sdim case SEC_LINK_DUPLICATES_DISCARD: 11468218822Sdim break; 11469218822Sdim 11470218822Sdim case SEC_LINK_DUPLICATES_ONE_ONLY: 11471218822Sdim (*_bfd_error_handler) 11472218822Sdim (_("%B: ignoring duplicate section `%A'"), 11473218822Sdim abfd, sec); 11474218822Sdim break; 11475218822Sdim 11476218822Sdim case SEC_LINK_DUPLICATES_SAME_SIZE: 11477218822Sdim if (sec->size != l->sec->size) 11478218822Sdim (*_bfd_error_handler) 11479218822Sdim (_("%B: duplicate section `%A' has different size"), 11480218822Sdim abfd, sec); 11481218822Sdim break; 11482218822Sdim 11483218822Sdim case SEC_LINK_DUPLICATES_SAME_CONTENTS: 11484218822Sdim if (sec->size != l->sec->size) 11485218822Sdim (*_bfd_error_handler) 11486218822Sdim (_("%B: duplicate section `%A' has different size"), 11487218822Sdim abfd, sec); 11488218822Sdim else if (sec->size != 0) 11489218822Sdim { 11490310368Spfg bfd_byte *sec_contents, *l_sec_contents = NULL; 11491218822Sdim 11492218822Sdim if (!bfd_malloc_and_get_section (abfd, sec, &sec_contents)) 11493218822Sdim (*_bfd_error_handler) 11494218822Sdim (_("%B: warning: could not read contents of section `%A'"), 11495218822Sdim abfd, sec); 11496218822Sdim else if (!bfd_malloc_and_get_section (l->sec->owner, l->sec, 11497218822Sdim &l_sec_contents)) 11498218822Sdim (*_bfd_error_handler) 11499218822Sdim (_("%B: warning: could not read contents of section `%A'"), 11500218822Sdim l->sec->owner, l->sec); 11501218822Sdim else if (memcmp (sec_contents, l_sec_contents, sec->size) != 0) 11502218822Sdim (*_bfd_error_handler) 11503218822Sdim (_("%B: warning: duplicate section `%A' has different contents"), 11504218822Sdim abfd, sec); 11505218822Sdim 11506218822Sdim if (sec_contents) 11507218822Sdim free (sec_contents); 11508218822Sdim if (l_sec_contents) 11509218822Sdim free (l_sec_contents); 11510218822Sdim } 11511218822Sdim break; 11512218822Sdim } 11513218822Sdim 11514218822Sdim /* Set the output_section field so that lang_add_section 11515218822Sdim does not create a lang_input_section structure for this 11516218822Sdim section. Since there might be a symbol in the section 11517218822Sdim being discarded, we must retain a pointer to the section 11518218822Sdim which we are really going to use. */ 11519218822Sdim sec->output_section = bfd_abs_section_ptr; 11520218822Sdim sec->kept_section = l->sec; 11521218822Sdim 11522218822Sdim if (flags & SEC_GROUP) 11523218822Sdim { 11524218822Sdim asection *first = elf_next_in_group (sec); 11525218822Sdim asection *s = first; 11526218822Sdim 11527218822Sdim while (s != NULL) 11528218822Sdim { 11529218822Sdim s->output_section = bfd_abs_section_ptr; 11530218822Sdim /* Record which group discards it. */ 11531218822Sdim s->kept_section = l->sec; 11532218822Sdim s = elf_next_in_group (s); 11533218822Sdim /* These lists are circular. */ 11534218822Sdim if (s == first) 11535218822Sdim break; 11536218822Sdim } 11537218822Sdim } 11538218822Sdim 11539218822Sdim return; 11540218822Sdim } 11541218822Sdim } 11542218822Sdim 11543218822Sdim /* A single member comdat group section may be discarded by a 11544218822Sdim linkonce section and vice versa. */ 11545218822Sdim 11546218822Sdim if ((flags & SEC_GROUP) != 0) 11547218822Sdim { 11548218822Sdim asection *first = elf_next_in_group (sec); 11549218822Sdim 11550218822Sdim if (first != NULL && elf_next_in_group (first) == first) 11551218822Sdim /* Check this single member group against linkonce sections. */ 11552218822Sdim for (l = already_linked_list->entry; l != NULL; l = l->next) 11553218822Sdim if ((l->sec->flags & SEC_GROUP) == 0 11554218822Sdim && bfd_coff_get_comdat_section (l->sec->owner, l->sec) == NULL 11555218822Sdim && bfd_elf_match_symbols_in_sections (l->sec, first, info)) 11556218822Sdim { 11557218822Sdim first->output_section = bfd_abs_section_ptr; 11558218822Sdim first->kept_section = l->sec; 11559218822Sdim sec->output_section = bfd_abs_section_ptr; 11560218822Sdim break; 11561218822Sdim } 11562218822Sdim } 11563218822Sdim else 11564218822Sdim /* Check this linkonce section against single member groups. */ 11565218822Sdim for (l = already_linked_list->entry; l != NULL; l = l->next) 11566218822Sdim if (l->sec->flags & SEC_GROUP) 11567218822Sdim { 11568218822Sdim asection *first = elf_next_in_group (l->sec); 11569218822Sdim 11570218822Sdim if (first != NULL 11571218822Sdim && elf_next_in_group (first) == first 11572218822Sdim && bfd_elf_match_symbols_in_sections (first, sec, info)) 11573218822Sdim { 11574218822Sdim sec->output_section = bfd_abs_section_ptr; 11575218822Sdim sec->kept_section = first; 11576218822Sdim break; 11577218822Sdim } 11578218822Sdim } 11579218822Sdim 11580218822Sdim /* This is the first section with this name. Record it. */ 11581218822Sdim bfd_section_already_linked_table_insert (already_linked_list, sec); 11582218822Sdim} 11583218822Sdim 11584218822Sdimbfd_boolean 11585218822Sdim_bfd_elf_common_definition (Elf_Internal_Sym *sym) 11586218822Sdim{ 11587218822Sdim return sym->st_shndx == SHN_COMMON; 11588218822Sdim} 11589218822Sdim 11590218822Sdimunsigned int 11591218822Sdim_bfd_elf_common_section_index (asection *sec ATTRIBUTE_UNUSED) 11592218822Sdim{ 11593218822Sdim return SHN_COMMON; 11594218822Sdim} 11595218822Sdim 11596218822Sdimasection * 11597218822Sdim_bfd_elf_common_section (asection *sec ATTRIBUTE_UNUSED) 11598218822Sdim{ 11599218822Sdim return bfd_com_section_ptr; 11600218822Sdim} 11601