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