elflink.c revision 327471
133965Sjdp/* ELF linking support for BFD.
2218822Sdim   Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3218822Sdim   2005, 2006, 2007 Free Software Foundation, Inc.
433965Sjdp
5218822Sdim   This file is part of BFD, the Binary File Descriptor library.
633965Sjdp
7218822Sdim   This program is free software; you can redistribute it and/or modify
8218822Sdim   it under the terms of the GNU General Public License as published by
9218822Sdim   the Free Software Foundation; either version 2 of the License, or
10218822Sdim   (at your option) any later version.
1133965Sjdp
12218822Sdim   This program is distributed in the hope that it will be useful,
13218822Sdim   but WITHOUT ANY WARRANTY; without even the implied warranty of
14218822Sdim   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15218822Sdim   GNU General Public License for more details.
1633965Sjdp
17218822Sdim   You should have received a copy of the GNU General Public License
18218822Sdim   along with this program; if not, write to the Free Software
19218822Sdim   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
2033965Sjdp
21218822Sdim#include "sysdep.h"
2233965Sjdp#include "bfd.h"
2333965Sjdp#include "bfdlink.h"
2433965Sjdp#include "libbfd.h"
2533965Sjdp#define ARCH_SIZE 0
2633965Sjdp#include "elf-bfd.h"
27130561Sobrien#include "safe-ctype.h"
28130561Sobrien#include "libiberty.h"
29218822Sdim#include "objalloc.h"
3033965Sjdp
31218822Sdim/* Define a symbol in a dynamic linkage section.  */
32218822Sdim
33218822Sdimstruct elf_link_hash_entry *
34218822Sdim_bfd_elf_define_linkage_sym (bfd *abfd,
35218822Sdim			     struct bfd_link_info *info,
36218822Sdim			     asection *sec,
37218822Sdim			     const char *name)
38218822Sdim{
39218822Sdim  struct elf_link_hash_entry *h;
40218822Sdim  struct bfd_link_hash_entry *bh;
41218822Sdim  const struct elf_backend_data *bed;
42218822Sdim
43218822Sdim  h = elf_link_hash_lookup (elf_hash_table (info), name, FALSE, FALSE, FALSE);
44218822Sdim  if (h != NULL)
45218822Sdim    {
46218822Sdim      /* Zap symbol defined in an as-needed lib that wasn't linked.
47218822Sdim	 This is a symptom of a larger problem:  Absolute symbols
48218822Sdim	 defined in shared libraries can't be overridden, because we
49218822Sdim	 lose the link to the bfd which is via the symbol section.  */
50218822Sdim      h->root.type = bfd_link_hash_new;
51218822Sdim    }
52218822Sdim
53218822Sdim  bh = &h->root;
54218822Sdim  if (!_bfd_generic_link_add_one_symbol (info, abfd, name, BSF_GLOBAL,
55218822Sdim					 sec, 0, NULL, FALSE,
56218822Sdim					 get_elf_backend_data (abfd)->collect,
57218822Sdim					 &bh))
58218822Sdim    return NULL;
59218822Sdim  h = (struct elf_link_hash_entry *) bh;
60218822Sdim  h->def_regular = 1;
61218822Sdim  h->type = STT_OBJECT;
62218822Sdim  h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
63218822Sdim
64218822Sdim  bed = get_elf_backend_data (abfd);
65218822Sdim  (*bed->elf_backend_hide_symbol) (info, h, TRUE);
66218822Sdim  return h;
67218822Sdim}
68218822Sdim
69130561Sobrienbfd_boolean
70130561Sobrien_bfd_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
7133965Sjdp{
7233965Sjdp  flagword flags;
73130561Sobrien  asection *s;
7433965Sjdp  struct elf_link_hash_entry *h;
75130561Sobrien  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
7638889Sjdp  int ptralign;
7733965Sjdp
7833965Sjdp  /* This function may be called more than once.  */
79130561Sobrien  s = bfd_get_section_by_name (abfd, ".got");
80130561Sobrien  if (s != NULL && (s->flags & SEC_LINKER_CREATED) != 0)
81130561Sobrien    return TRUE;
8233965Sjdp
8338889Sjdp  switch (bed->s->arch_size)
8438889Sjdp    {
8577298Sobrien    case 32:
8677298Sobrien      ptralign = 2;
8777298Sobrien      break;
8877298Sobrien
8977298Sobrien    case 64:
9077298Sobrien      ptralign = 3;
9177298Sobrien      break;
9277298Sobrien
9377298Sobrien    default:
9477298Sobrien      bfd_set_error (bfd_error_bad_value);
95130561Sobrien      return FALSE;
9638889Sjdp    }
9738889Sjdp
98218822Sdim  flags = bed->dynamic_sec_flags;
9933965Sjdp
100218822Sdim  s = bfd_make_section_with_flags (abfd, ".got", flags);
10133965Sjdp  if (s == NULL
10238889Sjdp      || !bfd_set_section_alignment (abfd, s, ptralign))
103130561Sobrien    return FALSE;
10433965Sjdp
10533965Sjdp  if (bed->want_got_plt)
10633965Sjdp    {
107218822Sdim      s = bfd_make_section_with_flags (abfd, ".got.plt", flags);
10833965Sjdp      if (s == NULL
10938889Sjdp	  || !bfd_set_section_alignment (abfd, s, ptralign))
110130561Sobrien	return FALSE;
11133965Sjdp    }
11233965Sjdp
11389857Sobrien  if (bed->want_got_sym)
11489857Sobrien    {
11589857Sobrien      /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
11689857Sobrien	 (or .got.plt) section.  We don't do this in the linker script
11789857Sobrien	 because we don't want to define the symbol if we are not creating
11889857Sobrien	 a global offset table.  */
119218822Sdim      h = _bfd_elf_define_linkage_sym (abfd, info, s, "_GLOBAL_OFFSET_TABLE_");
120218822Sdim      elf_hash_table (info)->hgot = h;
121218822Sdim      if (h == NULL)
122130561Sobrien	return FALSE;
12389857Sobrien    }
12433965Sjdp
12560484Sobrien  /* The first bit of the global offset table is the header.  */
126218822Sdim  s->size += bed->got_header_size;
12733965Sjdp
128130561Sobrien  return TRUE;
12933965Sjdp}
13033965Sjdp
131218822Sdim/* Create a strtab to hold the dynamic symbol names.  */
132218822Sdimstatic bfd_boolean
133218822Sdim_bfd_elf_link_create_dynstrtab (bfd *abfd, struct bfd_link_info *info)
134218822Sdim{
135218822Sdim  struct elf_link_hash_table *hash_table;
136218822Sdim
137218822Sdim  hash_table = elf_hash_table (info);
138218822Sdim  if (hash_table->dynobj == NULL)
139218822Sdim    hash_table->dynobj = abfd;
140218822Sdim
141218822Sdim  if (hash_table->dynstr == NULL)
142218822Sdim    {
143218822Sdim      hash_table->dynstr = _bfd_elf_strtab_init ();
144218822Sdim      if (hash_table->dynstr == NULL)
145218822Sdim	return FALSE;
146218822Sdim    }
147218822Sdim  return TRUE;
148218822Sdim}
149218822Sdim
150130561Sobrien/* Create some sections which will be filled in with dynamic linking
151130561Sobrien   information.  ABFD is an input file which requires dynamic sections
152130561Sobrien   to be created.  The dynamic sections take up virtual memory space
153130561Sobrien   when the final executable is run, so we need to create them before
154130561Sobrien   addresses are assigned to the output sections.  We work out the
155130561Sobrien   actual contents and size of these sections later.  */
15633965Sjdp
157130561Sobrienbfd_boolean
158130561Sobrien_bfd_elf_link_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
15933965Sjdp{
160130561Sobrien  flagword flags;
16133965Sjdp  register asection *s;
162130561Sobrien  const struct elf_backend_data *bed;
16333965Sjdp
164130561Sobrien  if (! is_elf_hash_table (info->hash))
165130561Sobrien    return FALSE;
166130561Sobrien
167130561Sobrien  if (elf_hash_table (info)->dynamic_sections_created)
168130561Sobrien    return TRUE;
169130561Sobrien
170218822Sdim  if (!_bfd_elf_link_create_dynstrtab (abfd, info))
171218822Sdim    return FALSE;
172130561Sobrien
173218822Sdim  abfd = elf_hash_table (info)->dynobj;
174218822Sdim  bed = get_elf_backend_data (abfd);
175130561Sobrien
176218822Sdim  flags = bed->dynamic_sec_flags;
177218822Sdim
178130561Sobrien  /* A dynamically linked executable has a .interp section, but a
179130561Sobrien     shared library does not.  */
180130561Sobrien  if (info->executable)
18138889Sjdp    {
182218822Sdim      s = bfd_make_section_with_flags (abfd, ".interp",
183218822Sdim				       flags | SEC_READONLY);
184218822Sdim      if (s == NULL)
185130561Sobrien	return FALSE;
186130561Sobrien    }
18777298Sobrien
188130561Sobrien  /* Create sections to hold version informations.  These are removed
189130561Sobrien     if they are not needed.  */
190218822Sdim  s = bfd_make_section_with_flags (abfd, ".gnu.version_d",
191218822Sdim				   flags | SEC_READONLY);
192130561Sobrien  if (s == NULL
193130561Sobrien      || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
194130561Sobrien    return FALSE;
195130561Sobrien
196218822Sdim  s = bfd_make_section_with_flags (abfd, ".gnu.version",
197218822Sdim				   flags | SEC_READONLY);
198130561Sobrien  if (s == NULL
199130561Sobrien      || ! bfd_set_section_alignment (abfd, s, 1))
200130561Sobrien    return FALSE;
201130561Sobrien
202218822Sdim  s = bfd_make_section_with_flags (abfd, ".gnu.version_r",
203218822Sdim				   flags | SEC_READONLY);
204130561Sobrien  if (s == NULL
205130561Sobrien      || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
206130561Sobrien    return FALSE;
207130561Sobrien
208218822Sdim  s = bfd_make_section_with_flags (abfd, ".dynsym",
209218822Sdim				   flags | SEC_READONLY);
210130561Sobrien  if (s == NULL
211130561Sobrien      || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
212130561Sobrien    return FALSE;
213130561Sobrien
214218822Sdim  s = bfd_make_section_with_flags (abfd, ".dynstr",
215218822Sdim				   flags | SEC_READONLY);
216218822Sdim  if (s == NULL)
217130561Sobrien    return FALSE;
218130561Sobrien
219218822Sdim  s = bfd_make_section_with_flags (abfd, ".dynamic", flags);
220130561Sobrien  if (s == NULL
221130561Sobrien      || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
222130561Sobrien    return FALSE;
223130561Sobrien
224130561Sobrien  /* The special symbol _DYNAMIC is always set to the start of the
225218822Sdim     .dynamic section.  We could set _DYNAMIC in a linker script, but we
226218822Sdim     only want to define it if we are, in fact, creating a .dynamic
227218822Sdim     section.  We don't want to define it if there is no .dynamic
228218822Sdim     section, since on some ELF platforms the start up code examines it
229218822Sdim     to decide how to initialize the process.  */
230218822Sdim  if (!_bfd_elf_define_linkage_sym (abfd, info, s, "_DYNAMIC"))
231130561Sobrien    return FALSE;
232130561Sobrien
233218822Sdim  if (info->emit_hash)
234218822Sdim    {
235218822Sdim      s = bfd_make_section_with_flags (abfd, ".hash", flags | SEC_READONLY);
236218822Sdim      if (s == NULL
237218822Sdim	  || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
238218822Sdim	return FALSE;
239218822Sdim      elf_section_data (s)->this_hdr.sh_entsize = bed->s->sizeof_hash_entry;
240218822Sdim    }
241130561Sobrien
242218822Sdim  if (info->emit_gnu_hash)
243218822Sdim    {
244218822Sdim      s = bfd_make_section_with_flags (abfd, ".gnu.hash",
245218822Sdim				       flags | SEC_READONLY);
246218822Sdim      if (s == NULL
247218822Sdim	  || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
248218822Sdim	return FALSE;
249218822Sdim      /* For 64-bit ELF, .gnu.hash is a non-uniform entity size section:
250218822Sdim	 4 32-bit words followed by variable count of 64-bit words, then
251218822Sdim	 variable count of 32-bit words.  */
252218822Sdim      if (bed->s->arch_size == 64)
253218822Sdim	elf_section_data (s)->this_hdr.sh_entsize = 0;
254218822Sdim      else
255218822Sdim	elf_section_data (s)->this_hdr.sh_entsize = 4;
256218822Sdim    }
257130561Sobrien
258130561Sobrien  /* Let the backend create the rest of the sections.  This lets the
259130561Sobrien     backend set the right flags.  The backend will normally create
260130561Sobrien     the .got and .plt sections.  */
261130561Sobrien  if (! (*bed->elf_backend_create_dynamic_sections) (abfd, info))
262130561Sobrien    return FALSE;
263130561Sobrien
264130561Sobrien  elf_hash_table (info)->dynamic_sections_created = TRUE;
265130561Sobrien
266130561Sobrien  return TRUE;
267130561Sobrien}
268130561Sobrien
269130561Sobrien/* Create dynamic sections when linking against a dynamic object.  */
270130561Sobrien
271130561Sobrienbfd_boolean
272130561Sobrien_bfd_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
273130561Sobrien{
274130561Sobrien  flagword flags, pltflags;
275218822Sdim  struct elf_link_hash_entry *h;
276130561Sobrien  asection *s;
277130561Sobrien  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
278130561Sobrien
27933965Sjdp  /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and
28033965Sjdp     .rel[a].bss sections.  */
281218822Sdim  flags = bed->dynamic_sec_flags;
28233965Sjdp
28338889Sjdp  pltflags = flags;
28438889Sjdp  if (bed->plt_not_loaded)
285218822Sdim    /* We do not clear SEC_ALLOC here because we still want the OS to
286218822Sdim       allocate space for the section; it's just that there's nothing
287218822Sdim       to read in from the object file.  */
28889857Sobrien    pltflags &= ~ (SEC_CODE | SEC_LOAD | SEC_HAS_CONTENTS);
289218822Sdim  else
290218822Sdim    pltflags |= SEC_ALLOC | SEC_CODE | SEC_LOAD;
29138889Sjdp  if (bed->plt_readonly)
29238889Sjdp    pltflags |= SEC_READONLY;
29338889Sjdp
294218822Sdim  s = bfd_make_section_with_flags (abfd, ".plt", pltflags);
29533965Sjdp  if (s == NULL
29638889Sjdp      || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
297130561Sobrien    return FALSE;
29833965Sjdp
299218822Sdim  /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
300218822Sdim     .plt section.  */
30133965Sjdp  if (bed->want_plt_sym)
30233965Sjdp    {
303218822Sdim      h = _bfd_elf_define_linkage_sym (abfd, info, s,
304218822Sdim				       "_PROCEDURE_LINKAGE_TABLE_");
305218822Sdim      elf_hash_table (info)->hplt = h;
306218822Sdim      if (h == NULL)
307130561Sobrien	return FALSE;
30833965Sjdp    }
30933965Sjdp
310218822Sdim  s = bfd_make_section_with_flags (abfd,
311218822Sdim				   (bed->default_use_rela_p
312218822Sdim				    ? ".rela.plt" : ".rel.plt"),
313218822Sdim				   flags | SEC_READONLY);
31433965Sjdp  if (s == NULL
315130561Sobrien      || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
316130561Sobrien    return FALSE;
31733965Sjdp
31833965Sjdp  if (! _bfd_elf_create_got_section (abfd, info))
319130561Sobrien    return FALSE;
32033965Sjdp
32160484Sobrien  if (bed->want_dynbss)
32260484Sobrien    {
32360484Sobrien      /* The .dynbss section is a place to put symbols which are defined
32460484Sobrien	 by dynamic objects, are referenced by regular objects, and are
32560484Sobrien	 not functions.  We must allocate space for them in the process
32660484Sobrien	 image and use a R_*_COPY reloc to tell the dynamic linker to
32760484Sobrien	 initialize them at run time.  The linker script puts the .dynbss
32860484Sobrien	 section into the .bss section of the final image.  */
329218822Sdim      s = bfd_make_section_with_flags (abfd, ".dynbss",
330218822Sdim				       (SEC_ALLOC
331218822Sdim					| SEC_LINKER_CREATED));
332218822Sdim      if (s == NULL)
333130561Sobrien	return FALSE;
33433965Sjdp
33560484Sobrien      /* The .rel[a].bss section holds copy relocs.  This section is not
336218822Sdim	 normally needed.  We need to create it here, though, so that the
337218822Sdim	 linker will map it to an output section.  We can't just create it
338218822Sdim	 only if we need it, because we will not know whether we need it
339218822Sdim	 until we have seen all the input files, and the first time the
340218822Sdim	 main linker code calls BFD after examining all the input files
341218822Sdim	 (size_dynamic_sections) the input sections have already been
342218822Sdim	 mapped to the output sections.  If the section turns out not to
343218822Sdim	 be needed, we can discard it later.  We will never need this
344218822Sdim	 section when generating a shared object, since they do not use
345218822Sdim	 copy relocs.  */
34660484Sobrien      if (! info->shared)
34760484Sobrien	{
348218822Sdim	  s = bfd_make_section_with_flags (abfd,
349218822Sdim					   (bed->default_use_rela_p
350218822Sdim					    ? ".rela.bss" : ".rel.bss"),
351218822Sdim					   flags | SEC_READONLY);
35260484Sobrien	  if (s == NULL
353130561Sobrien	      || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
354130561Sobrien	    return FALSE;
35560484Sobrien	}
35633965Sjdp    }
35733965Sjdp
358130561Sobrien  return TRUE;
35933965Sjdp}
36033965Sjdp
36133965Sjdp/* Record a new dynamic symbol.  We record the dynamic symbols as we
36233965Sjdp   read the input files, since we need to have a list of all of them
36333965Sjdp   before we can determine the final sizes of the output sections.
36433965Sjdp   Note that we may actually call this function even though we are not
36533965Sjdp   going to output any dynamic symbols; in some cases we know that a
36633965Sjdp   symbol should be in the dynamic symbol table, but only if there is
36733965Sjdp   one.  */
36833965Sjdp
369130561Sobrienbfd_boolean
370130561Sobrienbfd_elf_link_record_dynamic_symbol (struct bfd_link_info *info,
371130561Sobrien				    struct elf_link_hash_entry *h)
37233965Sjdp{
37333965Sjdp  if (h->dynindx == -1)
37433965Sjdp    {
37589857Sobrien      struct elf_strtab_hash *dynstr;
376130561Sobrien      char *p;
37733965Sjdp      const char *name;
37833965Sjdp      bfd_size_type indx;
37933965Sjdp
38060484Sobrien      /* XXX: The ABI draft says the linker must turn hidden and
38160484Sobrien	 internal symbols into STB_LOCAL symbols when producing the
38260484Sobrien	 DSO. However, if ld.so honors st_other in the dynamic table,
38360484Sobrien	 this would not be necessary.  */
38460484Sobrien      switch (ELF_ST_VISIBILITY (h->other))
38560484Sobrien	{
38660484Sobrien	case STV_INTERNAL:
38760484Sobrien	case STV_HIDDEN:
38868765Sobrien	  if (h->root.type != bfd_link_hash_undefined
38968765Sobrien	      && h->root.type != bfd_link_hash_undefweak)
39060484Sobrien	    {
391218822Sdim	      h->forced_local = 1;
392218822Sdim	      if (!elf_hash_table (info)->is_relocatable_executable)
393218822Sdim		return TRUE;
39460484Sobrien	    }
39568765Sobrien
39660484Sobrien	default:
39760484Sobrien	  break;
39860484Sobrien	}
39960484Sobrien
40033965Sjdp      h->dynindx = elf_hash_table (info)->dynsymcount;
40133965Sjdp      ++elf_hash_table (info)->dynsymcount;
40233965Sjdp
40333965Sjdp      dynstr = elf_hash_table (info)->dynstr;
40433965Sjdp      if (dynstr == NULL)
40533965Sjdp	{
40633965Sjdp	  /* Create a strtab to hold the dynamic symbol names.  */
40789857Sobrien	  elf_hash_table (info)->dynstr = dynstr = _bfd_elf_strtab_init ();
40833965Sjdp	  if (dynstr == NULL)
409130561Sobrien	    return FALSE;
41033965Sjdp	}
41133965Sjdp
41233965Sjdp      /* We don't put any version information in the dynamic string
413130561Sobrien	 table.  */
41433965Sjdp      name = h->root.root.string;
41533965Sjdp      p = strchr (name, ELF_VER_CHR);
416130561Sobrien      if (p != NULL)
417130561Sobrien	/* We know that the p points into writable memory.  In fact,
418130561Sobrien	   there are only a few symbols that have read-only names, being
419130561Sobrien	   those like _GLOBAL_OFFSET_TABLE_ that are created specially
420130561Sobrien	   by the backends.  Most symbols will have names pointing into
421130561Sobrien	   an ELF string table read from a file, or to objalloc memory.  */
422130561Sobrien	*p = 0;
423104834Sobrien
424130561Sobrien      indx = _bfd_elf_strtab_add (dynstr, name, p != NULL);
42533965Sjdp
426130561Sobrien      if (p != NULL)
427130561Sobrien	*p = ELF_VER_CHR;
42833965Sjdp
42933965Sjdp      if (indx == (bfd_size_type) -1)
430130561Sobrien	return FALSE;
43133965Sjdp      h->dynstr_index = indx;
43233965Sjdp    }
43333965Sjdp
434130561Sobrien  return TRUE;
43533965Sjdp}
436130561Sobrien
437218822Sdim/* Mark a symbol dynamic.  */
438218822Sdim
439218822Sdimvoid
440218822Sdimbfd_elf_link_mark_dynamic_symbol (struct bfd_link_info *info,
441218822Sdim				  struct elf_link_hash_entry *h,
442218822Sdim				  Elf_Internal_Sym *sym)
443218822Sdim{
444218822Sdim  struct bfd_elf_dynamic_list *d = info->dynamic_list;
445218822Sdim
446218822Sdim  /* It may be called more than once on the same H.  */
447218822Sdim  if(h->dynamic || info->relocatable)
448218822Sdim    return;
449218822Sdim
450218822Sdim  if ((info->dynamic_data
451218822Sdim       && (h->type == STT_OBJECT
452218822Sdim	   || (sym != NULL
453218822Sdim	       && ELF_ST_TYPE (sym->st_info) == STT_OBJECT)))
454218822Sdim      || (d != NULL
455218822Sdim	  && h->root.type == bfd_link_hash_new
456218822Sdim	  && (*d->match) (&d->head, NULL, h->root.root.string)))
457218822Sdim    h->dynamic = 1;
458218822Sdim}
459218822Sdim
460130561Sobrien/* Record an assignment to a symbol made by a linker script.  We need
461130561Sobrien   this in case some dynamic object refers to this symbol.  */
46260484Sobrien
463130561Sobrienbfd_boolean
464218822Sdimbfd_elf_record_link_assignment (bfd *output_bfd,
465130561Sobrien				struct bfd_link_info *info,
466130561Sobrien				const char *name,
467218822Sdim				bfd_boolean provide,
468218822Sdim				bfd_boolean hidden)
469130561Sobrien{
470130561Sobrien  struct elf_link_hash_entry *h;
471218822Sdim  struct elf_link_hash_table *htab;
472130561Sobrien
473130561Sobrien  if (!is_elf_hash_table (info->hash))
474130561Sobrien    return TRUE;
475130561Sobrien
476218822Sdim  htab = elf_hash_table (info);
477218822Sdim  h = elf_link_hash_lookup (htab, name, !provide, TRUE, FALSE);
478130561Sobrien  if (h == NULL)
479218822Sdim    return provide;
480130561Sobrien
481130561Sobrien  /* Since we're defining the symbol, don't let it seem to have not
482130561Sobrien     been defined.  record_dynamic_symbol and size_dynamic_sections
483130561Sobrien     may depend on this.  */
484130561Sobrien  if (h->root.type == bfd_link_hash_undefweak
485130561Sobrien      || h->root.type == bfd_link_hash_undefined)
486218822Sdim    {
487218822Sdim      h->root.type = bfd_link_hash_new;
488218822Sdim      if (h->root.u.undef.next != NULL || htab->root.undefs_tail == &h->root)
489218822Sdim	bfd_link_repair_undef_list (&htab->root);
490218822Sdim    }
491255931Sdim  else if (h->root.type == bfd_link_hash_new)
492218822Sdim    {
493218822Sdim      bfd_elf_link_mark_dynamic_symbol (info, h, NULL);
494218822Sdim      h->non_elf = 0;
495218822Sdim    }
496255931Sdim  else if (h->root.type == bfd_link_hash_indirect)
497255931Sdim    {
498255931Sdim      const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
499255931Sdim      struct elf_link_hash_entry *hv = h;
500255931Sdim      do
501255931Sdim	hv = (struct elf_link_hash_entry *) hv->root.u.i.link;
502255931Sdim      while (hv->root.type == bfd_link_hash_indirect
503255931Sdim	     || hv->root.type == bfd_link_hash_warning);
504255931Sdim      h->root.type = bfd_link_hash_undefined;
505255931Sdim      hv->root.type = bfd_link_hash_indirect;
506255931Sdim      hv->root.u.i.link = (struct bfd_link_hash_entry *) h;
507255931Sdim      (*bed->elf_backend_copy_indirect_symbol) (info, h, hv);
508255931Sdim    }
509255931Sdim  else if (h->root.type == bfd_link_hash_warning)
510255931Sdim    {
511255931Sdim      abort ();
512255931Sdim    }
513130561Sobrien
514130561Sobrien  /* If this symbol is being provided by the linker script, and it is
515130561Sobrien     currently defined by a dynamic object, but not by a regular
516130561Sobrien     object, then mark it as undefined so that the generic linker will
517130561Sobrien     force the correct value.  */
518130561Sobrien  if (provide
519218822Sdim      && h->def_dynamic
520218822Sdim      && !h->def_regular)
521130561Sobrien    h->root.type = bfd_link_hash_undefined;
522130561Sobrien
523130561Sobrien  /* If this symbol is not being provided by the linker script, and it is
524130561Sobrien     currently defined by a dynamic object, but not by a regular object,
525130561Sobrien     then clear out any version information because the symbol will not be
526130561Sobrien     associated with the dynamic object any more.  */
527130561Sobrien  if (!provide
528218822Sdim      && h->def_dynamic
529218822Sdim      && !h->def_regular)
530130561Sobrien    h->verinfo.verdef = NULL;
531130561Sobrien
532218822Sdim  h->def_regular = 1;
533130561Sobrien
534218822Sdim  if (provide && hidden)
535218822Sdim    {
536218822Sdim      const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
537218822Sdim
538218822Sdim      h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
539218822Sdim      (*bed->elf_backend_hide_symbol) (info, h, TRUE);
540218822Sdim    }
541218822Sdim
542218822Sdim  /* STV_HIDDEN and STV_INTERNAL symbols must be STB_LOCAL in shared objects
543218822Sdim     and executables.  */
544218822Sdim  if (!info->relocatable
545218822Sdim      && h->dynindx != -1
546218822Sdim      && (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
547218822Sdim	  || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL))
548218822Sdim    h->forced_local = 1;
549218822Sdim
550218822Sdim  if ((h->def_dynamic
551218822Sdim       || h->ref_dynamic
552218822Sdim       || info->shared
553218822Sdim       || (info->executable && elf_hash_table (info)->is_relocatable_executable))
554130561Sobrien      && h->dynindx == -1)
555130561Sobrien    {
556130561Sobrien      if (! bfd_elf_link_record_dynamic_symbol (info, h))
557130561Sobrien	return FALSE;
558130561Sobrien
559130561Sobrien      /* If this is a weak defined symbol, and we know a corresponding
560130561Sobrien	 real symbol from the same dynamic object, make sure the real
561130561Sobrien	 symbol is also made into a dynamic symbol.  */
562218822Sdim      if (h->u.weakdef != NULL
563218822Sdim	  && h->u.weakdef->dynindx == -1)
564130561Sobrien	{
565218822Sdim	  if (! bfd_elf_link_record_dynamic_symbol (info, h->u.weakdef))
566130561Sobrien	    return FALSE;
567130561Sobrien	}
568130561Sobrien    }
569130561Sobrien
570130561Sobrien  return TRUE;
571130561Sobrien}
572130561Sobrien
573104834Sobrien/* Record a new local dynamic symbol.  Returns 0 on failure, 1 on
574104834Sobrien   success, and 2 on a failure caused by attempting to record a symbol
575104834Sobrien   in a discarded section, eg. a discarded link-once section symbol.  */
576104834Sobrien
577104834Sobrienint
578130561Sobrienbfd_elf_link_record_local_dynamic_symbol (struct bfd_link_info *info,
579130561Sobrien					  bfd *input_bfd,
580130561Sobrien					  long input_indx)
581104834Sobrien{
582104834Sobrien  bfd_size_type amt;
583104834Sobrien  struct elf_link_local_dynamic_entry *entry;
584104834Sobrien  struct elf_link_hash_table *eht;
585104834Sobrien  struct elf_strtab_hash *dynstr;
586104834Sobrien  unsigned long dynstr_index;
587104834Sobrien  char *name;
588104834Sobrien  Elf_External_Sym_Shndx eshndx;
589104834Sobrien  char esym[sizeof (Elf64_External_Sym)];
590104834Sobrien
591130561Sobrien  if (! is_elf_hash_table (info->hash))
592104834Sobrien    return 0;
593104834Sobrien
594104834Sobrien  /* See if the entry exists already.  */
595104834Sobrien  for (entry = elf_hash_table (info)->dynlocal; entry ; entry = entry->next)
596104834Sobrien    if (entry->input_bfd == input_bfd && entry->input_indx == input_indx)
597104834Sobrien      return 1;
598104834Sobrien
599104834Sobrien  amt = sizeof (*entry);
600130561Sobrien  entry = bfd_alloc (input_bfd, amt);
601104834Sobrien  if (entry == NULL)
602104834Sobrien    return 0;
603104834Sobrien
604104834Sobrien  /* Go find the symbol, so that we can find it's name.  */
605104834Sobrien  if (!bfd_elf_get_elf_syms (input_bfd, &elf_tdata (input_bfd)->symtab_hdr,
606130561Sobrien			     1, input_indx, &entry->isym, esym, &eshndx))
607104834Sobrien    {
608104834Sobrien      bfd_release (input_bfd, entry);
609104834Sobrien      return 0;
610104834Sobrien    }
611104834Sobrien
612104834Sobrien  if (entry->isym.st_shndx != SHN_UNDEF
613104834Sobrien      && (entry->isym.st_shndx < SHN_LORESERVE
614104834Sobrien	  || entry->isym.st_shndx > SHN_HIRESERVE))
615104834Sobrien    {
616104834Sobrien      asection *s;
617104834Sobrien
618104834Sobrien      s = bfd_section_from_elf_index (input_bfd, entry->isym.st_shndx);
619104834Sobrien      if (s == NULL || bfd_is_abs_section (s->output_section))
620104834Sobrien	{
621104834Sobrien	  /* We can still bfd_release here as nothing has done another
622104834Sobrien	     bfd_alloc.  We can't do this later in this function.  */
623104834Sobrien	  bfd_release (input_bfd, entry);
624104834Sobrien	  return 2;
625104834Sobrien	}
626104834Sobrien    }
627104834Sobrien
628104834Sobrien  name = (bfd_elf_string_from_elf_section
629104834Sobrien	  (input_bfd, elf_tdata (input_bfd)->symtab_hdr.sh_link,
630104834Sobrien	   entry->isym.st_name));
631104834Sobrien
632104834Sobrien  dynstr = elf_hash_table (info)->dynstr;
633104834Sobrien  if (dynstr == NULL)
634104834Sobrien    {
635104834Sobrien      /* Create a strtab to hold the dynamic symbol names.  */
636104834Sobrien      elf_hash_table (info)->dynstr = dynstr = _bfd_elf_strtab_init ();
637104834Sobrien      if (dynstr == NULL)
638104834Sobrien	return 0;
639104834Sobrien    }
640104834Sobrien
641130561Sobrien  dynstr_index = _bfd_elf_strtab_add (dynstr, name, FALSE);
642104834Sobrien  if (dynstr_index == (unsigned long) -1)
643104834Sobrien    return 0;
644104834Sobrien  entry->isym.st_name = dynstr_index;
645104834Sobrien
646104834Sobrien  eht = elf_hash_table (info);
647104834Sobrien
648104834Sobrien  entry->next = eht->dynlocal;
649104834Sobrien  eht->dynlocal = entry;
650104834Sobrien  entry->input_bfd = input_bfd;
651104834Sobrien  entry->input_indx = input_indx;
652104834Sobrien  eht->dynsymcount++;
653104834Sobrien
654104834Sobrien  /* Whatever binding the symbol had before, it's now local.  */
655104834Sobrien  entry->isym.st_info
656104834Sobrien    = ELF_ST_INFO (STB_LOCAL, ELF_ST_TYPE (entry->isym.st_info));
657104834Sobrien
658104834Sobrien  /* The dynindx will be set at the end of size_dynamic_sections.  */
659104834Sobrien
660104834Sobrien  return 1;
661104834Sobrien}
662104834Sobrien
66360484Sobrien/* Return the dynindex of a local dynamic symbol.  */
66460484Sobrien
66560484Sobrienlong
666130561Sobrien_bfd_elf_link_lookup_local_dynindx (struct bfd_link_info *info,
667130561Sobrien				    bfd *input_bfd,
668130561Sobrien				    long input_indx)
66960484Sobrien{
67060484Sobrien  struct elf_link_local_dynamic_entry *e;
67160484Sobrien
67260484Sobrien  for (e = elf_hash_table (info)->dynlocal; e ; e = e->next)
67360484Sobrien    if (e->input_bfd == input_bfd && e->input_indx == input_indx)
67460484Sobrien      return e->dynindx;
67560484Sobrien  return -1;
67660484Sobrien}
67760484Sobrien
67860484Sobrien/* This function is used to renumber the dynamic symbols, if some of
67960484Sobrien   them are removed because they are marked as local.  This is called
68060484Sobrien   via elf_link_hash_traverse.  */
68160484Sobrien
682130561Sobrienstatic bfd_boolean
683130561Sobrienelf_link_renumber_hash_table_dynsyms (struct elf_link_hash_entry *h,
684130561Sobrien				      void *data)
68560484Sobrien{
686130561Sobrien  size_t *count = data;
68760484Sobrien
68894536Sobrien  if (h->root.type == bfd_link_hash_warning)
68994536Sobrien    h = (struct elf_link_hash_entry *) h->root.u.i.link;
69094536Sobrien
691218822Sdim  if (h->forced_local)
692218822Sdim    return TRUE;
693218822Sdim
69460484Sobrien  if (h->dynindx != -1)
69560484Sobrien    h->dynindx = ++(*count);
69660484Sobrien
697130561Sobrien  return TRUE;
69860484Sobrien}
69960484Sobrien
700218822Sdim
701218822Sdim/* Like elf_link_renumber_hash_table_dynsyms, but just number symbols with
702218822Sdim   STB_LOCAL binding.  */
703218822Sdim
704218822Sdimstatic bfd_boolean
705218822Sdimelf_link_renumber_local_hash_table_dynsyms (struct elf_link_hash_entry *h,
706218822Sdim					    void *data)
707218822Sdim{
708218822Sdim  size_t *count = data;
709218822Sdim
710218822Sdim  if (h->root.type == bfd_link_hash_warning)
711218822Sdim    h = (struct elf_link_hash_entry *) h->root.u.i.link;
712218822Sdim
713218822Sdim  if (!h->forced_local)
714218822Sdim    return TRUE;
715218822Sdim
716218822Sdim  if (h->dynindx != -1)
717218822Sdim    h->dynindx = ++(*count);
718218822Sdim
719218822Sdim  return TRUE;
720218822Sdim}
721218822Sdim
722218822Sdim/* Return true if the dynamic symbol for a given section should be
723218822Sdim   omitted when creating a shared library.  */
724218822Sdimbfd_boolean
725218822Sdim_bfd_elf_link_omit_section_dynsym (bfd *output_bfd ATTRIBUTE_UNUSED,
726218822Sdim				   struct bfd_link_info *info,
727218822Sdim				   asection *p)
728218822Sdim{
729218822Sdim  struct elf_link_hash_table *htab;
730218822Sdim
731218822Sdim  switch (elf_section_data (p)->this_hdr.sh_type)
732218822Sdim    {
733218822Sdim    case SHT_PROGBITS:
734218822Sdim    case SHT_NOBITS:
735218822Sdim      /* If sh_type is yet undecided, assume it could be
736218822Sdim	 SHT_PROGBITS/SHT_NOBITS.  */
737218822Sdim    case SHT_NULL:
738218822Sdim      htab = elf_hash_table (info);
739218822Sdim      if (p == htab->tls_sec)
740218822Sdim	return FALSE;
741218822Sdim
742218822Sdim      if (htab->text_index_section != NULL)
743218822Sdim	return p != htab->text_index_section && p != htab->data_index_section;
744218822Sdim
745218822Sdim      if (strcmp (p->name, ".got") == 0
746218822Sdim	  || strcmp (p->name, ".got.plt") == 0
747218822Sdim	  || strcmp (p->name, ".plt") == 0)
748218822Sdim	{
749218822Sdim	  asection *ip;
750218822Sdim
751218822Sdim	  if (htab->dynobj != NULL
752218822Sdim	      && (ip = bfd_get_section_by_name (htab->dynobj, p->name)) != NULL
753218822Sdim	      && (ip->flags & SEC_LINKER_CREATED)
754218822Sdim	      && ip->output_section == p)
755218822Sdim	    return TRUE;
756218822Sdim	}
757218822Sdim      return FALSE;
758218822Sdim
759218822Sdim      /* There shouldn't be section relative relocations
760218822Sdim	 against any other section.  */
761218822Sdim    default:
762218822Sdim      return TRUE;
763218822Sdim    }
764218822Sdim}
765218822Sdim
76678828Sobrien/* Assign dynsym indices.  In a shared library we generate a section
767218822Sdim   symbol for each output section, which come first.  Next come symbols
768218822Sdim   which have been forced to local binding.  Then all of the back-end
769218822Sdim   allocated local dynamic syms, followed by the rest of the global
770218822Sdim   symbols.  */
77160484Sobrien
772218822Sdimstatic unsigned long
773218822Sdim_bfd_elf_link_renumber_dynsyms (bfd *output_bfd,
774218822Sdim				struct bfd_link_info *info,
775218822Sdim				unsigned long *section_sym_count)
77660484Sobrien{
77760484Sobrien  unsigned long dynsymcount = 0;
77860484Sobrien
779218822Sdim  if (info->shared || elf_hash_table (info)->is_relocatable_executable)
78060484Sobrien    {
781218822Sdim      const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
78260484Sobrien      asection *p;
78360484Sobrien      for (p = output_bfd->sections; p ; p = p->next)
784218822Sdim	if ((p->flags & SEC_EXCLUDE) == 0
785218822Sdim	    && (p->flags & SEC_ALLOC) != 0
786218822Sdim	    && !(*bed->elf_backend_omit_section_dynsym) (output_bfd, info, p))
787104834Sobrien	  elf_section_data (p)->dynindx = ++dynsymcount;
788218822Sdim	else
789218822Sdim	  elf_section_data (p)->dynindx = 0;
79060484Sobrien    }
791218822Sdim  *section_sym_count = dynsymcount;
79260484Sobrien
793218822Sdim  elf_link_hash_traverse (elf_hash_table (info),
794218822Sdim			  elf_link_renumber_local_hash_table_dynsyms,
795218822Sdim			  &dynsymcount);
796218822Sdim
79760484Sobrien  if (elf_hash_table (info)->dynlocal)
79860484Sobrien    {
79960484Sobrien      struct elf_link_local_dynamic_entry *p;
80060484Sobrien      for (p = elf_hash_table (info)->dynlocal; p ; p = p->next)
80160484Sobrien	p->dynindx = ++dynsymcount;
80260484Sobrien    }
80360484Sobrien
80460484Sobrien  elf_link_hash_traverse (elf_hash_table (info),
80560484Sobrien			  elf_link_renumber_hash_table_dynsyms,
80660484Sobrien			  &dynsymcount);
80760484Sobrien
80860484Sobrien  /* There is an unused NULL entry at the head of the table which
80960484Sobrien     we must account for in our count.  Unless there weren't any
81060484Sobrien     symbols, which means we'll have no table at all.  */
81160484Sobrien  if (dynsymcount != 0)
81260484Sobrien    ++dynsymcount;
81360484Sobrien
814218822Sdim  elf_hash_table (info)->dynsymcount = dynsymcount;
815218822Sdim  return dynsymcount;
81660484Sobrien}
817130561Sobrien
818130561Sobrien/* This function is called when we want to define a new symbol.  It
819130561Sobrien   handles the various cases which arise when we find a definition in
820130561Sobrien   a dynamic object, or when there is already a definition in a
821130561Sobrien   dynamic object.  The new symbol is described by NAME, SYM, PSEC,
822130561Sobrien   and PVALUE.  We set SYM_HASH to the hash table entry.  We set
823130561Sobrien   OVERRIDE if the old symbol is overriding a new definition.  We set
824130561Sobrien   TYPE_CHANGE_OK if it is OK for the type to change.  We set
825130561Sobrien   SIZE_CHANGE_OK if it is OK for the size to change.  By OK to
826130561Sobrien   change, we mean that we shouldn't warn if the type or size does
827218822Sdim   change.  We set POLD_ALIGNMENT if an old common symbol in a dynamic
828218822Sdim   object is overridden by a regular object.  */
829130561Sobrien
830130561Sobrienbfd_boolean
831130561Sobrien_bfd_elf_merge_symbol (bfd *abfd,
832130561Sobrien		       struct bfd_link_info *info,
833130561Sobrien		       const char *name,
834130561Sobrien		       Elf_Internal_Sym *sym,
835130561Sobrien		       asection **psec,
836130561Sobrien		       bfd_vma *pvalue,
837218822Sdim		       unsigned int *pold_alignment,
838130561Sobrien		       struct elf_link_hash_entry **sym_hash,
839130561Sobrien		       bfd_boolean *skip,
840130561Sobrien		       bfd_boolean *override,
841130561Sobrien		       bfd_boolean *type_change_ok,
842130561Sobrien		       bfd_boolean *size_change_ok)
843130561Sobrien{
844218822Sdim  asection *sec, *oldsec;
845130561Sobrien  struct elf_link_hash_entry *h;
846130561Sobrien  struct elf_link_hash_entry *flip;
847130561Sobrien  int bind;
848130561Sobrien  bfd *oldbfd;
849130561Sobrien  bfd_boolean newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon;
850130561Sobrien  bfd_boolean newweak, oldweak;
851218822Sdim  const struct elf_backend_data *bed;
852130561Sobrien
853130561Sobrien  *skip = FALSE;
854130561Sobrien  *override = FALSE;
855130561Sobrien
856130561Sobrien  sec = *psec;
857130561Sobrien  bind = ELF_ST_BIND (sym->st_info);
858130561Sobrien
859218822Sdim  /* Silently discard TLS symbols from --just-syms.  There's no way to
860218822Sdim     combine a static TLS block with a new TLS block for this executable.  */
861218822Sdim  if (ELF_ST_TYPE (sym->st_info) == STT_TLS
862218822Sdim      && sec->sec_info_type == ELF_INFO_TYPE_JUST_SYMS)
863218822Sdim    {
864218822Sdim      *skip = TRUE;
865218822Sdim      return TRUE;
866218822Sdim    }
867218822Sdim
868130561Sobrien  if (! bfd_is_und_section (sec))
869130561Sobrien    h = elf_link_hash_lookup (elf_hash_table (info), name, TRUE, FALSE, FALSE);
870130561Sobrien  else
871130561Sobrien    h = ((struct elf_link_hash_entry *)
872130561Sobrien	 bfd_wrapped_link_hash_lookup (abfd, info, name, TRUE, FALSE, FALSE));
873130561Sobrien  if (h == NULL)
874130561Sobrien    return FALSE;
875130561Sobrien  *sym_hash = h;
876130561Sobrien
877218822Sdim  bed = get_elf_backend_data (abfd);
878218822Sdim
879130561Sobrien  /* This code is for coping with dynamic objects, and is only useful
880130561Sobrien     if we are doing an ELF link.  */
881218822Sdim  if (!(*bed->relocs_compatible) (abfd->xvec, info->hash->creator))
882130561Sobrien    return TRUE;
883130561Sobrien
884130561Sobrien  /* For merging, we only care about real symbols.  */
885130561Sobrien
886130561Sobrien  while (h->root.type == bfd_link_hash_indirect
887130561Sobrien	 || h->root.type == bfd_link_hash_warning)
888130561Sobrien    h = (struct elf_link_hash_entry *) h->root.u.i.link;
889130561Sobrien
890218822Sdim  /* We have to check it for every instance since the first few may be
891218822Sdim     refereences and not all compilers emit symbol type for undefined
892218822Sdim     symbols.  */
893218822Sdim  bfd_elf_link_mark_dynamic_symbol (info, h, sym);
894218822Sdim
895130561Sobrien  /* If we just created the symbol, mark it as being an ELF symbol.
896130561Sobrien     Other than that, there is nothing to do--there is no merge issue
897130561Sobrien     with a newly defined symbol--so we just return.  */
898130561Sobrien
899130561Sobrien  if (h->root.type == bfd_link_hash_new)
900130561Sobrien    {
901218822Sdim      h->non_elf = 0;
902130561Sobrien      return TRUE;
903130561Sobrien    }
904130561Sobrien
905218822Sdim  /* OLDBFD and OLDSEC are a BFD and an ASECTION associated with the
906218822Sdim     existing symbol.  */
907130561Sobrien
908130561Sobrien  switch (h->root.type)
909130561Sobrien    {
910130561Sobrien    default:
911130561Sobrien      oldbfd = NULL;
912218822Sdim      oldsec = NULL;
913130561Sobrien      break;
914130561Sobrien
915130561Sobrien    case bfd_link_hash_undefined:
916130561Sobrien    case bfd_link_hash_undefweak:
917130561Sobrien      oldbfd = h->root.u.undef.abfd;
918218822Sdim      oldsec = NULL;
919130561Sobrien      break;
920130561Sobrien
921130561Sobrien    case bfd_link_hash_defined:
922130561Sobrien    case bfd_link_hash_defweak:
923130561Sobrien      oldbfd = h->root.u.def.section->owner;
924218822Sdim      oldsec = h->root.u.def.section;
925130561Sobrien      break;
926130561Sobrien
927130561Sobrien    case bfd_link_hash_common:
928130561Sobrien      oldbfd = h->root.u.c.p->section->owner;
929218822Sdim      oldsec = h->root.u.c.p->section;
930130561Sobrien      break;
931130561Sobrien    }
932130561Sobrien
933130561Sobrien  /* In cases involving weak versioned symbols, we may wind up trying
934130561Sobrien     to merge a symbol with itself.  Catch that here, to avoid the
935130561Sobrien     confusion that results if we try to override a symbol with
936130561Sobrien     itself.  The additional tests catch cases like
937130561Sobrien     _GLOBAL_OFFSET_TABLE_, which are regular symbols defined in a
938130561Sobrien     dynamic object, which we do want to handle here.  */
939130561Sobrien  if (abfd == oldbfd
940130561Sobrien      && ((abfd->flags & DYNAMIC) == 0
941218822Sdim	  || !h->def_regular))
942130561Sobrien    return TRUE;
943130561Sobrien
944130561Sobrien  /* NEWDYN and OLDDYN indicate whether the new or old symbol,
945130561Sobrien     respectively, is from a dynamic object.  */
946130561Sobrien
947218822Sdim  newdyn = (abfd->flags & DYNAMIC) != 0;
948130561Sobrien
949218822Sdim  olddyn = FALSE;
950130561Sobrien  if (oldbfd != NULL)
951130561Sobrien    olddyn = (oldbfd->flags & DYNAMIC) != 0;
952218822Sdim  else if (oldsec != NULL)
953130561Sobrien    {
954218822Sdim      /* This handles the special SHN_MIPS_{TEXT,DATA} section
955130561Sobrien	 indices used by MIPS ELF.  */
956218822Sdim      olddyn = (oldsec->symbol->flags & BSF_DYNAMIC) != 0;
957218822Sdim    }
958130561Sobrien
959218822Sdim  /* NEWDEF and OLDDEF indicate whether the new or old symbol,
960218822Sdim     respectively, appear to be a definition rather than reference.  */
961130561Sobrien
962218822Sdim  newdef = !bfd_is_und_section (sec) && !bfd_is_com_section (sec);
963130561Sobrien
964218822Sdim  olddef = (h->root.type != bfd_link_hash_undefined
965218822Sdim	    && h->root.type != bfd_link_hash_undefweak
966218822Sdim	    && h->root.type != bfd_link_hash_common);
967218822Sdim
968218822Sdim  /* When we try to create a default indirect symbol from the dynamic
969218822Sdim     definition with the default version, we skip it if its type and
970218822Sdim     the type of existing regular definition mismatch.  We only do it
971218822Sdim     if the existing regular definition won't be dynamic.  */
972218822Sdim  if (pold_alignment == NULL
973218822Sdim      && !info->shared
974218822Sdim      && !info->export_dynamic
975218822Sdim      && !h->ref_dynamic
976218822Sdim      && newdyn
977218822Sdim      && newdef
978218822Sdim      && !olddyn
979218822Sdim      && (olddef || h->root.type == bfd_link_hash_common)
980218822Sdim      && ELF_ST_TYPE (sym->st_info) != h->type
981218822Sdim      && ELF_ST_TYPE (sym->st_info) != STT_NOTYPE
982218822Sdim      && h->type != STT_NOTYPE
983218822Sdim      && !(bed->is_function_type (ELF_ST_TYPE (sym->st_info))
984218822Sdim	   && bed->is_function_type (h->type)))
985218822Sdim    {
986218822Sdim      *skip = TRUE;
987218822Sdim      return TRUE;
988130561Sobrien    }
989130561Sobrien
990218822Sdim  /* Check TLS symbol.  We don't check undefined symbol introduced by
991218822Sdim     "ld -u".  */
992218822Sdim  if ((ELF_ST_TYPE (sym->st_info) == STT_TLS || h->type == STT_TLS)
993218822Sdim      && ELF_ST_TYPE (sym->st_info) != h->type
994218822Sdim      && oldbfd != NULL)
995218822Sdim    {
996218822Sdim      bfd *ntbfd, *tbfd;
997218822Sdim      bfd_boolean ntdef, tdef;
998218822Sdim      asection *ntsec, *tsec;
999130561Sobrien
1000218822Sdim      if (h->type == STT_TLS)
1001218822Sdim	{
1002218822Sdim	  ntbfd = abfd;
1003218822Sdim	  ntsec = sec;
1004218822Sdim	  ntdef = newdef;
1005218822Sdim	  tbfd = oldbfd;
1006218822Sdim	  tsec = oldsec;
1007218822Sdim	  tdef = olddef;
1008218822Sdim	}
1009218822Sdim      else
1010218822Sdim	{
1011218822Sdim	  ntbfd = oldbfd;
1012218822Sdim	  ntsec = oldsec;
1013218822Sdim	  ntdef = olddef;
1014218822Sdim	  tbfd = abfd;
1015218822Sdim	  tsec = sec;
1016218822Sdim	  tdef = newdef;
1017218822Sdim	}
1018130561Sobrien
1019218822Sdim      if (tdef && ntdef)
1020218822Sdim	(*_bfd_error_handler)
1021218822Sdim	  (_("%s: TLS definition in %B section %A mismatches non-TLS definition in %B section %A"),
1022218822Sdim	   tbfd, tsec, ntbfd, ntsec, h->root.root.string);
1023218822Sdim      else if (!tdef && !ntdef)
1024218822Sdim	(*_bfd_error_handler)
1025218822Sdim	  (_("%s: TLS reference in %B mismatches non-TLS reference in %B"),
1026218822Sdim	   tbfd, ntbfd, h->root.root.string);
1027218822Sdim      else if (tdef)
1028218822Sdim	(*_bfd_error_handler)
1029218822Sdim	  (_("%s: TLS definition in %B section %A mismatches non-TLS reference in %B"),
1030218822Sdim	   tbfd, tsec, ntbfd, h->root.root.string);
1031218822Sdim      else
1032218822Sdim	(*_bfd_error_handler)
1033218822Sdim	  (_("%s: TLS reference in %B mismatches non-TLS definition in %B section %A"),
1034218822Sdim	   tbfd, ntbfd, ntsec, h->root.root.string);
1035130561Sobrien
1036218822Sdim      bfd_set_error (bfd_error_bad_value);
1037218822Sdim      return FALSE;
1038218822Sdim    }
1039218822Sdim
1040130561Sobrien  /* We need to remember if a symbol has a definition in a dynamic
1041130561Sobrien     object or is weak in all dynamic objects. Internal and hidden
1042130561Sobrien     visibility will make it unavailable to dynamic objects.  */
1043218822Sdim  if (newdyn && !h->dynamic_def)
1044130561Sobrien    {
1045130561Sobrien      if (!bfd_is_und_section (sec))
1046218822Sdim	h->dynamic_def = 1;
1047130561Sobrien      else
1048130561Sobrien	{
1049130561Sobrien	  /* Check if this symbol is weak in all dynamic objects. If it
1050130561Sobrien	     is the first time we see it in a dynamic object, we mark
1051130561Sobrien	     if it is weak. Otherwise, we clear it.  */
1052218822Sdim	  if (!h->ref_dynamic)
1053130561Sobrien	    {
1054130561Sobrien	      if (bind == STB_WEAK)
1055218822Sdim		h->dynamic_weak = 1;
1056130561Sobrien	    }
1057130561Sobrien	  else if (bind != STB_WEAK)
1058218822Sdim	    h->dynamic_weak = 0;
1059130561Sobrien	}
1060130561Sobrien    }
1061130561Sobrien
1062130561Sobrien  /* If the old symbol has non-default visibility, we ignore the new
1063130561Sobrien     definition from a dynamic object.  */
1064130561Sobrien  if (newdyn
1065130561Sobrien      && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
1066130561Sobrien      && !bfd_is_und_section (sec))
1067130561Sobrien    {
1068130561Sobrien      *skip = TRUE;
1069130561Sobrien      /* Make sure this symbol is dynamic.  */
1070218822Sdim      h->ref_dynamic = 1;
1071130561Sobrien      /* A protected symbol has external availability. Make sure it is
1072130561Sobrien	 recorded as dynamic.
1073130561Sobrien
1074130561Sobrien	 FIXME: Should we check type and size for protected symbol?  */
1075130561Sobrien      if (ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
1076130561Sobrien	return bfd_elf_link_record_dynamic_symbol (info, h);
1077130561Sobrien      else
1078130561Sobrien	return TRUE;
1079130561Sobrien    }
1080130561Sobrien  else if (!newdyn
1081130561Sobrien	   && ELF_ST_VISIBILITY (sym->st_other) != STV_DEFAULT
1082218822Sdim	   && h->def_dynamic)
1083130561Sobrien    {
1084130561Sobrien      /* If the new symbol with non-default visibility comes from a
1085130561Sobrien	 relocatable file and the old definition comes from a dynamic
1086130561Sobrien	 object, we remove the old definition.  */
1087130561Sobrien      if ((*sym_hash)->root.type == bfd_link_hash_indirect)
1088218822Sdim	{
1089218822Sdim	  /* Handle the case where the old dynamic definition is
1090218822Sdim	     default versioned.  We need to copy the symbol info from
1091218822Sdim	     the symbol with default version to the normal one if it
1092218822Sdim	     was referenced before.  */
1093218822Sdim	  if (h->ref_regular)
1094218822Sdim	    {
1095218822Sdim	      const struct elf_backend_data *bed
1096218822Sdim		= get_elf_backend_data (abfd);
1097218822Sdim	      struct elf_link_hash_entry *vh = *sym_hash;
1098218822Sdim	      vh->root.type = h->root.type;
1099218822Sdim	      h->root.type = bfd_link_hash_indirect;
1100218822Sdim	      (*bed->elf_backend_copy_indirect_symbol) (info, vh, h);
1101218822Sdim	      /* Protected symbols will override the dynamic definition
1102218822Sdim		 with default version.  */
1103218822Sdim	      if (ELF_ST_VISIBILITY (sym->st_other) == STV_PROTECTED)
1104218822Sdim		{
1105218822Sdim		  h->root.u.i.link = (struct bfd_link_hash_entry *) vh;
1106218822Sdim		  vh->dynamic_def = 1;
1107218822Sdim		  vh->ref_dynamic = 1;
1108218822Sdim		}
1109218822Sdim	      else
1110218822Sdim		{
1111218822Sdim		  h->root.type = vh->root.type;
1112218822Sdim		  vh->ref_dynamic = 0;
1113218822Sdim		  /* We have to hide it here since it was made dynamic
1114218822Sdim		     global with extra bits when the symbol info was
1115218822Sdim		     copied from the old dynamic definition.  */
1116218822Sdim		  (*bed->elf_backend_hide_symbol) (info, vh, TRUE);
1117218822Sdim		}
1118218822Sdim	      h = vh;
1119218822Sdim	    }
1120218822Sdim	  else
1121218822Sdim	    h = *sym_hash;
1122218822Sdim	}
1123130561Sobrien
1124218822Sdim      if ((h->root.u.undef.next || info->hash->undefs_tail == &h->root)
1125130561Sobrien	  && bfd_is_und_section (sec))
1126130561Sobrien	{
1127130561Sobrien	  /* If the new symbol is undefined and the old symbol was
1128130561Sobrien	     also undefined before, we need to make sure
1129130561Sobrien	     _bfd_generic_link_add_one_symbol doesn't mess
1130218822Sdim	     up the linker hash table undefs list.  Since the old
1131130561Sobrien	     definition came from a dynamic object, it is still on the
1132130561Sobrien	     undefs list.  */
1133130561Sobrien	  h->root.type = bfd_link_hash_undefined;
1134130561Sobrien	  h->root.u.undef.abfd = abfd;
1135130561Sobrien	}
1136130561Sobrien      else
1137130561Sobrien	{
1138130561Sobrien	  h->root.type = bfd_link_hash_new;
1139130561Sobrien	  h->root.u.undef.abfd = NULL;
1140130561Sobrien	}
1141130561Sobrien
1142218822Sdim      if (h->def_dynamic)
1143130561Sobrien	{
1144218822Sdim	  h->def_dynamic = 0;
1145218822Sdim	  h->ref_dynamic = 1;
1146218822Sdim	  h->dynamic_def = 1;
1147130561Sobrien	}
1148130561Sobrien      /* FIXME: Should we check type and size for protected symbol?  */
1149130561Sobrien      h->size = 0;
1150130561Sobrien      h->type = 0;
1151130561Sobrien      return TRUE;
1152130561Sobrien    }
1153130561Sobrien
1154130561Sobrien  /* Differentiate strong and weak symbols.  */
1155130561Sobrien  newweak = bind == STB_WEAK;
1156130561Sobrien  oldweak = (h->root.type == bfd_link_hash_defweak
1157130561Sobrien	     || h->root.type == bfd_link_hash_undefweak);
1158130561Sobrien
1159130561Sobrien  /* If a new weak symbol definition comes from a regular file and the
1160130561Sobrien     old symbol comes from a dynamic library, we treat the new one as
1161130561Sobrien     strong.  Similarly, an old weak symbol definition from a regular
1162130561Sobrien     file is treated as strong when the new symbol comes from a dynamic
1163130561Sobrien     library.  Further, an old weak symbol from a dynamic library is
1164130561Sobrien     treated as strong if the new symbol is from a dynamic library.
1165130561Sobrien     This reflects the way glibc's ld.so works.
1166130561Sobrien
1167130561Sobrien     Do this before setting *type_change_ok or *size_change_ok so that
1168130561Sobrien     we warn properly when dynamic library symbols are overridden.  */
1169130561Sobrien
1170130561Sobrien  if (newdef && !newdyn && olddyn)
1171130561Sobrien    newweak = FALSE;
1172130561Sobrien  if (olddef && newdyn)
1173130561Sobrien    oldweak = FALSE;
1174130561Sobrien
1175218822Sdim  /* Allow changes between different types of funciton symbol.  */
1176218822Sdim  if (bed->is_function_type (ELF_ST_TYPE (sym->st_info))
1177218822Sdim      && bed->is_function_type (h->type))
1178218822Sdim    *type_change_ok = TRUE;
1179218822Sdim
1180130561Sobrien  /* It's OK to change the type if either the existing symbol or the
1181130561Sobrien     new symbol is weak.  A type change is also OK if the old symbol
1182130561Sobrien     is undefined and the new symbol is defined.  */
1183130561Sobrien
1184130561Sobrien  if (oldweak
1185130561Sobrien      || newweak
1186130561Sobrien      || (newdef
1187130561Sobrien	  && h->root.type == bfd_link_hash_undefined))
1188130561Sobrien    *type_change_ok = TRUE;
1189130561Sobrien
1190130561Sobrien  /* It's OK to change the size if either the existing symbol or the
1191130561Sobrien     new symbol is weak, or if the old symbol is undefined.  */
1192130561Sobrien
1193130561Sobrien  if (*type_change_ok
1194130561Sobrien      || h->root.type == bfd_link_hash_undefined)
1195130561Sobrien    *size_change_ok = TRUE;
1196130561Sobrien
1197130561Sobrien  /* NEWDYNCOMMON and OLDDYNCOMMON indicate whether the new or old
1198130561Sobrien     symbol, respectively, appears to be a common symbol in a dynamic
1199130561Sobrien     object.  If a symbol appears in an uninitialized section, and is
1200130561Sobrien     not weak, and is not a function, then it may be a common symbol
1201130561Sobrien     which was resolved when the dynamic object was created.  We want
1202130561Sobrien     to treat such symbols specially, because they raise special
1203130561Sobrien     considerations when setting the symbol size: if the symbol
1204130561Sobrien     appears as a common symbol in a regular object, and the size in
1205130561Sobrien     the regular object is larger, we must make sure that we use the
1206130561Sobrien     larger size.  This problematic case can always be avoided in C,
1207130561Sobrien     but it must be handled correctly when using Fortran shared
1208130561Sobrien     libraries.
1209130561Sobrien
1210130561Sobrien     Note that if NEWDYNCOMMON is set, NEWDEF will be set, and
1211130561Sobrien     likewise for OLDDYNCOMMON and OLDDEF.
1212130561Sobrien
1213130561Sobrien     Note that this test is just a heuristic, and that it is quite
1214130561Sobrien     possible to have an uninitialized symbol in a shared object which
1215130561Sobrien     is really a definition, rather than a common symbol.  This could
1216130561Sobrien     lead to some minor confusion when the symbol really is a common
1217130561Sobrien     symbol in some regular object.  However, I think it will be
1218130561Sobrien     harmless.  */
1219130561Sobrien
1220130561Sobrien  if (newdyn
1221130561Sobrien      && newdef
1222130561Sobrien      && !newweak
1223130561Sobrien      && (sec->flags & SEC_ALLOC) != 0
1224130561Sobrien      && (sec->flags & SEC_LOAD) == 0
1225130561Sobrien      && sym->st_size > 0
1226218822Sdim      && !bed->is_function_type (ELF_ST_TYPE (sym->st_info)))
1227130561Sobrien    newdyncommon = TRUE;
1228130561Sobrien  else
1229130561Sobrien    newdyncommon = FALSE;
1230130561Sobrien
1231130561Sobrien  if (olddyn
1232130561Sobrien      && olddef
1233130561Sobrien      && h->root.type == bfd_link_hash_defined
1234218822Sdim      && h->def_dynamic
1235130561Sobrien      && (h->root.u.def.section->flags & SEC_ALLOC) != 0
1236130561Sobrien      && (h->root.u.def.section->flags & SEC_LOAD) == 0
1237130561Sobrien      && h->size > 0
1238218822Sdim      && !bed->is_function_type (h->type))
1239130561Sobrien    olddyncommon = TRUE;
1240130561Sobrien  else
1241130561Sobrien    olddyncommon = FALSE;
1242130561Sobrien
1243218822Sdim  /* We now know everything about the old and new symbols.  We ask the
1244218822Sdim     backend to check if we can merge them.  */
1245218822Sdim  if (bed->merge_symbol
1246218822Sdim      && !bed->merge_symbol (info, sym_hash, h, sym, psec, pvalue,
1247218822Sdim			     pold_alignment, skip, override,
1248218822Sdim			     type_change_ok, size_change_ok,
1249218822Sdim			     &newdyn, &newdef, &newdyncommon, &newweak,
1250218822Sdim			     abfd, &sec,
1251218822Sdim			     &olddyn, &olddef, &olddyncommon, &oldweak,
1252218822Sdim			     oldbfd, &oldsec))
1253218822Sdim    return FALSE;
1254218822Sdim
1255130561Sobrien  /* If both the old and the new symbols look like common symbols in a
1256130561Sobrien     dynamic object, set the size of the symbol to the larger of the
1257130561Sobrien     two.  */
1258130561Sobrien
1259130561Sobrien  if (olddyncommon
1260130561Sobrien      && newdyncommon
1261130561Sobrien      && sym->st_size != h->size)
1262130561Sobrien    {
1263130561Sobrien      /* Since we think we have two common symbols, issue a multiple
1264130561Sobrien	 common warning if desired.  Note that we only warn if the
1265130561Sobrien	 size is different.  If the size is the same, we simply let
1266130561Sobrien	 the old symbol override the new one as normally happens with
1267130561Sobrien	 symbols defined in dynamic objects.  */
1268130561Sobrien
1269130561Sobrien      if (! ((*info->callbacks->multiple_common)
1270130561Sobrien	     (info, h->root.root.string, oldbfd, bfd_link_hash_common,
1271130561Sobrien	      h->size, abfd, bfd_link_hash_common, sym->st_size)))
1272130561Sobrien	return FALSE;
1273130561Sobrien
1274130561Sobrien      if (sym->st_size > h->size)
1275130561Sobrien	h->size = sym->st_size;
1276130561Sobrien
1277130561Sobrien      *size_change_ok = TRUE;
1278130561Sobrien    }
1279130561Sobrien
1280130561Sobrien  /* If we are looking at a dynamic object, and we have found a
1281130561Sobrien     definition, we need to see if the symbol was already defined by
1282130561Sobrien     some other object.  If so, we want to use the existing
1283130561Sobrien     definition, and we do not want to report a multiple symbol
1284130561Sobrien     definition error; we do this by clobbering *PSEC to be
1285130561Sobrien     bfd_und_section_ptr.
1286130561Sobrien
1287130561Sobrien     We treat a common symbol as a definition if the symbol in the
1288130561Sobrien     shared library is a function, since common symbols always
1289130561Sobrien     represent variables; this can cause confusion in principle, but
1290130561Sobrien     any such confusion would seem to indicate an erroneous program or
1291130561Sobrien     shared library.  We also permit a common symbol in a regular
1292130561Sobrien     object to override a weak symbol in a shared object.  */
1293130561Sobrien
1294130561Sobrien  if (newdyn
1295130561Sobrien      && newdef
1296130561Sobrien      && (olddef
1297130561Sobrien	  || (h->root.type == bfd_link_hash_common
1298130561Sobrien	      && (newweak
1299218822Sdim		  || bed->is_function_type (ELF_ST_TYPE (sym->st_info))))))
1300130561Sobrien    {
1301130561Sobrien      *override = TRUE;
1302130561Sobrien      newdef = FALSE;
1303130561Sobrien      newdyncommon = FALSE;
1304130561Sobrien
1305130561Sobrien      *psec = sec = bfd_und_section_ptr;
1306130561Sobrien      *size_change_ok = TRUE;
1307130561Sobrien
1308130561Sobrien      /* If we get here when the old symbol is a common symbol, then
1309130561Sobrien	 we are explicitly letting it override a weak symbol or
1310130561Sobrien	 function in a dynamic object, and we don't want to warn about
1311130561Sobrien	 a type change.  If the old symbol is a defined symbol, a type
1312130561Sobrien	 change warning may still be appropriate.  */
1313130561Sobrien
1314130561Sobrien      if (h->root.type == bfd_link_hash_common)
1315130561Sobrien	*type_change_ok = TRUE;
1316130561Sobrien    }
1317130561Sobrien
1318130561Sobrien  /* Handle the special case of an old common symbol merging with a
1319130561Sobrien     new symbol which looks like a common symbol in a shared object.
1320130561Sobrien     We change *PSEC and *PVALUE to make the new symbol look like a
1321218822Sdim     common symbol, and let _bfd_generic_link_add_one_symbol do the
1322218822Sdim     right thing.  */
1323130561Sobrien
1324130561Sobrien  if (newdyncommon
1325130561Sobrien      && h->root.type == bfd_link_hash_common)
1326130561Sobrien    {
1327130561Sobrien      *override = TRUE;
1328130561Sobrien      newdef = FALSE;
1329130561Sobrien      newdyncommon = FALSE;
1330130561Sobrien      *pvalue = sym->st_size;
1331218822Sdim      *psec = sec = bed->common_section (oldsec);
1332130561Sobrien      *size_change_ok = TRUE;
1333130561Sobrien    }
1334130561Sobrien
1335218822Sdim  /* Skip weak definitions of symbols that are already defined.  */
1336218822Sdim  if (newdef && olddef && newweak)
1337218822Sdim    *skip = TRUE;
1338218822Sdim
1339130561Sobrien  /* If the old symbol is from a dynamic object, and the new symbol is
1340130561Sobrien     a definition which is not from a dynamic object, then the new
1341130561Sobrien     symbol overrides the old symbol.  Symbols from regular files
1342130561Sobrien     always take precedence over symbols from dynamic objects, even if
1343130561Sobrien     they are defined after the dynamic object in the link.
1344130561Sobrien
1345130561Sobrien     As above, we again permit a common symbol in a regular object to
1346130561Sobrien     override a definition in a shared object if the shared object
1347130561Sobrien     symbol is a function or is weak.  */
1348130561Sobrien
1349130561Sobrien  flip = NULL;
1350218822Sdim  if (!newdyn
1351130561Sobrien      && (newdef
1352130561Sobrien	  || (bfd_is_com_section (sec)
1353130561Sobrien	      && (oldweak
1354218822Sdim		  || bed->is_function_type (h->type))))
1355130561Sobrien      && olddyn
1356130561Sobrien      && olddef
1357218822Sdim      && h->def_dynamic)
1358130561Sobrien    {
1359130561Sobrien      /* Change the hash table entry to undefined, and let
1360130561Sobrien	 _bfd_generic_link_add_one_symbol do the right thing with the
1361130561Sobrien	 new definition.  */
1362130561Sobrien
1363130561Sobrien      h->root.type = bfd_link_hash_undefined;
1364130561Sobrien      h->root.u.undef.abfd = h->root.u.def.section->owner;
1365130561Sobrien      *size_change_ok = TRUE;
1366130561Sobrien
1367130561Sobrien      olddef = FALSE;
1368130561Sobrien      olddyncommon = FALSE;
1369130561Sobrien
1370130561Sobrien      /* We again permit a type change when a common symbol may be
1371130561Sobrien	 overriding a function.  */
1372130561Sobrien
1373130561Sobrien      if (bfd_is_com_section (sec))
1374130561Sobrien	*type_change_ok = TRUE;
1375130561Sobrien
1376130561Sobrien      if ((*sym_hash)->root.type == bfd_link_hash_indirect)
1377130561Sobrien	flip = *sym_hash;
1378130561Sobrien      else
1379130561Sobrien	/* This union may have been set to be non-NULL when this symbol
1380130561Sobrien	   was seen in a dynamic object.  We must force the union to be
1381130561Sobrien	   NULL, so that it is correct for a regular symbol.  */
1382130561Sobrien	h->verinfo.vertree = NULL;
1383130561Sobrien    }
1384130561Sobrien
1385130561Sobrien  /* Handle the special case of a new common symbol merging with an
1386130561Sobrien     old symbol that looks like it might be a common symbol defined in
1387130561Sobrien     a shared object.  Note that we have already handled the case in
1388130561Sobrien     which a new common symbol should simply override the definition
1389130561Sobrien     in the shared library.  */
1390130561Sobrien
1391130561Sobrien  if (! newdyn
1392130561Sobrien      && bfd_is_com_section (sec)
1393130561Sobrien      && olddyncommon)
1394130561Sobrien    {
1395130561Sobrien      /* It would be best if we could set the hash table entry to a
1396130561Sobrien	 common symbol, but we don't know what to use for the section
1397130561Sobrien	 or the alignment.  */
1398130561Sobrien      if (! ((*info->callbacks->multiple_common)
1399130561Sobrien	     (info, h->root.root.string, oldbfd, bfd_link_hash_common,
1400130561Sobrien	      h->size, abfd, bfd_link_hash_common, sym->st_size)))
1401130561Sobrien	return FALSE;
1402130561Sobrien
1403130561Sobrien      /* If the presumed common symbol in the dynamic object is
1404130561Sobrien	 larger, pretend that the new symbol has its size.  */
1405130561Sobrien
1406130561Sobrien      if (h->size > *pvalue)
1407130561Sobrien	*pvalue = h->size;
1408130561Sobrien
1409218822Sdim      /* We need to remember the alignment required by the symbol
1410218822Sdim	 in the dynamic object.  */
1411218822Sdim      BFD_ASSERT (pold_alignment);
1412218822Sdim      *pold_alignment = h->root.u.def.section->alignment_power;
1413130561Sobrien
1414130561Sobrien      olddef = FALSE;
1415130561Sobrien      olddyncommon = FALSE;
1416130561Sobrien
1417130561Sobrien      h->root.type = bfd_link_hash_undefined;
1418130561Sobrien      h->root.u.undef.abfd = h->root.u.def.section->owner;
1419130561Sobrien
1420130561Sobrien      *size_change_ok = TRUE;
1421130561Sobrien      *type_change_ok = TRUE;
1422130561Sobrien
1423130561Sobrien      if ((*sym_hash)->root.type == bfd_link_hash_indirect)
1424130561Sobrien	flip = *sym_hash;
1425130561Sobrien      else
1426130561Sobrien	h->verinfo.vertree = NULL;
1427130561Sobrien    }
1428130561Sobrien
1429130561Sobrien  if (flip != NULL)
1430130561Sobrien    {
1431130561Sobrien      /* Handle the case where we had a versioned symbol in a dynamic
1432130561Sobrien	 library and now find a definition in a normal object.  In this
1433130561Sobrien	 case, we make the versioned symbol point to the normal one.  */
1434130561Sobrien      const struct elf_backend_data *bed = get_elf_backend_data (abfd);
1435130561Sobrien      flip->root.type = h->root.type;
1436255931Sdim      flip->root.u.undef.abfd = h->root.u.undef.abfd;
1437130561Sobrien      h->root.type = bfd_link_hash_indirect;
1438130561Sobrien      h->root.u.i.link = (struct bfd_link_hash_entry *) flip;
1439218822Sdim      (*bed->elf_backend_copy_indirect_symbol) (info, flip, h);
1440218822Sdim      if (h->def_dynamic)
1441130561Sobrien	{
1442218822Sdim	  h->def_dynamic = 0;
1443218822Sdim	  flip->ref_dynamic = 1;
1444130561Sobrien	}
1445130561Sobrien    }
1446130561Sobrien
1447130561Sobrien  return TRUE;
1448130561Sobrien}
1449130561Sobrien
1450130561Sobrien/* This function is called to create an indirect symbol from the
1451130561Sobrien   default for the symbol with the default version if needed. The
1452130561Sobrien   symbol is described by H, NAME, SYM, PSEC, VALUE, and OVERRIDE.  We
1453130561Sobrien   set DYNSYM if the new indirect symbol is dynamic.  */
1454130561Sobrien
1455130561Sobrienbfd_boolean
1456130561Sobrien_bfd_elf_add_default_symbol (bfd *abfd,
1457130561Sobrien			     struct bfd_link_info *info,
1458130561Sobrien			     struct elf_link_hash_entry *h,
1459130561Sobrien			     const char *name,
1460130561Sobrien			     Elf_Internal_Sym *sym,
1461130561Sobrien			     asection **psec,
1462130561Sobrien			     bfd_vma *value,
1463130561Sobrien			     bfd_boolean *dynsym,
1464130561Sobrien			     bfd_boolean override)
1465130561Sobrien{
1466130561Sobrien  bfd_boolean type_change_ok;
1467130561Sobrien  bfd_boolean size_change_ok;
1468130561Sobrien  bfd_boolean skip;
1469130561Sobrien  char *shortname;
1470130561Sobrien  struct elf_link_hash_entry *hi;
1471130561Sobrien  struct bfd_link_hash_entry *bh;
1472130561Sobrien  const struct elf_backend_data *bed;
1473130561Sobrien  bfd_boolean collect;
1474130561Sobrien  bfd_boolean dynamic;
1475130561Sobrien  char *p;
1476130561Sobrien  size_t len, shortlen;
1477130561Sobrien  asection *sec;
1478130561Sobrien
1479130561Sobrien  /* If this symbol has a version, and it is the default version, we
1480130561Sobrien     create an indirect symbol from the default name to the fully
1481130561Sobrien     decorated name.  This will cause external references which do not
1482130561Sobrien     specify a version to be bound to this version of the symbol.  */
1483130561Sobrien  p = strchr (name, ELF_VER_CHR);
1484130561Sobrien  if (p == NULL || p[1] != ELF_VER_CHR)
1485130561Sobrien    return TRUE;
1486130561Sobrien
1487130561Sobrien  if (override)
1488130561Sobrien    {
1489130561Sobrien      /* We are overridden by an old definition. We need to check if we
1490130561Sobrien	 need to create the indirect symbol from the default name.  */
1491130561Sobrien      hi = elf_link_hash_lookup (elf_hash_table (info), name, TRUE,
1492130561Sobrien				 FALSE, FALSE);
1493130561Sobrien      BFD_ASSERT (hi != NULL);
1494130561Sobrien      if (hi == h)
1495130561Sobrien	return TRUE;
1496130561Sobrien      while (hi->root.type == bfd_link_hash_indirect
1497130561Sobrien	     || hi->root.type == bfd_link_hash_warning)
1498130561Sobrien	{
1499130561Sobrien	  hi = (struct elf_link_hash_entry *) hi->root.u.i.link;
1500130561Sobrien	  if (hi == h)
1501130561Sobrien	    return TRUE;
1502130561Sobrien	}
1503130561Sobrien    }
1504130561Sobrien
1505130561Sobrien  bed = get_elf_backend_data (abfd);
1506130561Sobrien  collect = bed->collect;
1507130561Sobrien  dynamic = (abfd->flags & DYNAMIC) != 0;
1508130561Sobrien
1509130561Sobrien  shortlen = p - name;
1510130561Sobrien  shortname = bfd_hash_allocate (&info->hash->table, shortlen + 1);
1511130561Sobrien  if (shortname == NULL)
1512130561Sobrien    return FALSE;
1513130561Sobrien  memcpy (shortname, name, shortlen);
1514130561Sobrien  shortname[shortlen] = '\0';
1515130561Sobrien
1516130561Sobrien  /* We are going to create a new symbol.  Merge it with any existing
1517130561Sobrien     symbol with this name.  For the purposes of the merge, act as
1518130561Sobrien     though we were defining the symbol we just defined, although we
1519130561Sobrien     actually going to define an indirect symbol.  */
1520130561Sobrien  type_change_ok = FALSE;
1521130561Sobrien  size_change_ok = FALSE;
1522130561Sobrien  sec = *psec;
1523130561Sobrien  if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &sec, value,
1524218822Sdim			      NULL, &hi, &skip, &override,
1525218822Sdim			      &type_change_ok, &size_change_ok))
1526130561Sobrien    return FALSE;
1527130561Sobrien
1528130561Sobrien  if (skip)
1529130561Sobrien    goto nondefault;
1530130561Sobrien
1531130561Sobrien  if (! override)
1532130561Sobrien    {
1533130561Sobrien      bh = &hi->root;
1534130561Sobrien      if (! (_bfd_generic_link_add_one_symbol
1535130561Sobrien	     (info, abfd, shortname, BSF_INDIRECT, bfd_ind_section_ptr,
1536130561Sobrien	      0, name, FALSE, collect, &bh)))
1537130561Sobrien	return FALSE;
1538130561Sobrien      hi = (struct elf_link_hash_entry *) bh;
1539130561Sobrien    }
1540130561Sobrien  else
1541130561Sobrien    {
1542130561Sobrien      /* In this case the symbol named SHORTNAME is overriding the
1543130561Sobrien	 indirect symbol we want to add.  We were planning on making
1544130561Sobrien	 SHORTNAME an indirect symbol referring to NAME.  SHORTNAME
1545130561Sobrien	 is the name without a version.  NAME is the fully versioned
1546130561Sobrien	 name, and it is the default version.
1547130561Sobrien
1548130561Sobrien	 Overriding means that we already saw a definition for the
1549130561Sobrien	 symbol SHORTNAME in a regular object, and it is overriding
1550130561Sobrien	 the symbol defined in the dynamic object.
1551130561Sobrien
1552130561Sobrien	 When this happens, we actually want to change NAME, the
1553130561Sobrien	 symbol we just added, to refer to SHORTNAME.  This will cause
1554130561Sobrien	 references to NAME in the shared object to become references
1555130561Sobrien	 to SHORTNAME in the regular object.  This is what we expect
1556130561Sobrien	 when we override a function in a shared object: that the
1557130561Sobrien	 references in the shared object will be mapped to the
1558130561Sobrien	 definition in the regular object.  */
1559130561Sobrien
1560130561Sobrien      while (hi->root.type == bfd_link_hash_indirect
1561130561Sobrien	     || hi->root.type == bfd_link_hash_warning)
1562130561Sobrien	hi = (struct elf_link_hash_entry *) hi->root.u.i.link;
1563130561Sobrien
1564130561Sobrien      h->root.type = bfd_link_hash_indirect;
1565130561Sobrien      h->root.u.i.link = (struct bfd_link_hash_entry *) hi;
1566218822Sdim      if (h->def_dynamic)
1567130561Sobrien	{
1568218822Sdim	  h->def_dynamic = 0;
1569218822Sdim	  hi->ref_dynamic = 1;
1570218822Sdim	  if (hi->ref_regular
1571218822Sdim	      || hi->def_regular)
1572130561Sobrien	    {
1573130561Sobrien	      if (! bfd_elf_link_record_dynamic_symbol (info, hi))
1574130561Sobrien		return FALSE;
1575130561Sobrien	    }
1576130561Sobrien	}
1577130561Sobrien
1578130561Sobrien      /* Now set HI to H, so that the following code will set the
1579130561Sobrien	 other fields correctly.  */
1580130561Sobrien      hi = h;
1581130561Sobrien    }
1582130561Sobrien
1583218822Sdim  /* Check if HI is a warning symbol.  */
1584218822Sdim  if (hi->root.type == bfd_link_hash_warning)
1585218822Sdim    hi = (struct elf_link_hash_entry *) hi->root.u.i.link;
1586218822Sdim
1587130561Sobrien  /* If there is a duplicate definition somewhere, then HI may not
1588130561Sobrien     point to an indirect symbol.  We will have reported an error to
1589130561Sobrien     the user in that case.  */
1590130561Sobrien
1591130561Sobrien  if (hi->root.type == bfd_link_hash_indirect)
1592130561Sobrien    {
1593130561Sobrien      struct elf_link_hash_entry *ht;
1594130561Sobrien
1595130561Sobrien      ht = (struct elf_link_hash_entry *) hi->root.u.i.link;
1596218822Sdim      (*bed->elf_backend_copy_indirect_symbol) (info, ht, hi);
1597130561Sobrien
1598130561Sobrien      /* See if the new flags lead us to realize that the symbol must
1599130561Sobrien	 be dynamic.  */
1600130561Sobrien      if (! *dynsym)
1601130561Sobrien	{
1602130561Sobrien	  if (! dynamic)
1603130561Sobrien	    {
1604130561Sobrien	      if (info->shared
1605218822Sdim		  || hi->ref_dynamic)
1606130561Sobrien		*dynsym = TRUE;
1607130561Sobrien	    }
1608130561Sobrien	  else
1609130561Sobrien	    {
1610218822Sdim	      if (hi->ref_regular)
1611130561Sobrien		*dynsym = TRUE;
1612130561Sobrien	    }
1613130561Sobrien	}
1614130561Sobrien    }
1615130561Sobrien
1616130561Sobrien  /* We also need to define an indirection from the nondefault version
1617130561Sobrien     of the symbol.  */
1618130561Sobrien
1619130561Sobriennondefault:
1620130561Sobrien  len = strlen (name);
1621130561Sobrien  shortname = bfd_hash_allocate (&info->hash->table, len);
1622130561Sobrien  if (shortname == NULL)
1623130561Sobrien    return FALSE;
1624130561Sobrien  memcpy (shortname, name, shortlen);
1625130561Sobrien  memcpy (shortname + shortlen, p + 1, len - shortlen);
1626130561Sobrien
1627130561Sobrien  /* Once again, merge with any existing symbol.  */
1628130561Sobrien  type_change_ok = FALSE;
1629130561Sobrien  size_change_ok = FALSE;
1630130561Sobrien  sec = *psec;
1631130561Sobrien  if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &sec, value,
1632218822Sdim			      NULL, &hi, &skip, &override,
1633218822Sdim			      &type_change_ok, &size_change_ok))
1634130561Sobrien    return FALSE;
1635130561Sobrien
1636130561Sobrien  if (skip)
1637130561Sobrien    return TRUE;
1638130561Sobrien
1639130561Sobrien  if (override)
1640130561Sobrien    {
1641130561Sobrien      /* Here SHORTNAME is a versioned name, so we don't expect to see
1642130561Sobrien	 the type of override we do in the case above unless it is
1643130561Sobrien	 overridden by a versioned definition.  */
1644130561Sobrien      if (hi->root.type != bfd_link_hash_defined
1645130561Sobrien	  && hi->root.type != bfd_link_hash_defweak)
1646130561Sobrien	(*_bfd_error_handler)
1647218822Sdim	  (_("%B: unexpected redefinition of indirect versioned symbol `%s'"),
1648218822Sdim	   abfd, shortname);
1649130561Sobrien    }
1650130561Sobrien  else
1651130561Sobrien    {
1652130561Sobrien      bh = &hi->root;
1653130561Sobrien      if (! (_bfd_generic_link_add_one_symbol
1654130561Sobrien	     (info, abfd, shortname, BSF_INDIRECT,
1655130561Sobrien	      bfd_ind_section_ptr, 0, name, FALSE, collect, &bh)))
1656130561Sobrien	return FALSE;
1657130561Sobrien      hi = (struct elf_link_hash_entry *) bh;
1658130561Sobrien
1659130561Sobrien      /* If there is a duplicate definition somewhere, then HI may not
1660130561Sobrien	 point to an indirect symbol.  We will have reported an error
1661130561Sobrien	 to the user in that case.  */
1662130561Sobrien
1663130561Sobrien      if (hi->root.type == bfd_link_hash_indirect)
1664130561Sobrien	{
1665218822Sdim	  (*bed->elf_backend_copy_indirect_symbol) (info, h, hi);
1666130561Sobrien
1667130561Sobrien	  /* See if the new flags lead us to realize that the symbol
1668130561Sobrien	     must be dynamic.  */
1669130561Sobrien	  if (! *dynsym)
1670130561Sobrien	    {
1671130561Sobrien	      if (! dynamic)
1672130561Sobrien		{
1673130561Sobrien		  if (info->shared
1674218822Sdim		      || hi->ref_dynamic)
1675130561Sobrien		    *dynsym = TRUE;
1676130561Sobrien		}
1677130561Sobrien	      else
1678130561Sobrien		{
1679218822Sdim		  if (hi->ref_regular)
1680130561Sobrien		    *dynsym = TRUE;
1681130561Sobrien		}
1682130561Sobrien	    }
1683130561Sobrien	}
1684130561Sobrien    }
1685130561Sobrien
1686130561Sobrien  return TRUE;
1687130561Sobrien}
168833965Sjdp
1689130561Sobrien/* This routine is used to export all defined symbols into the dynamic
1690130561Sobrien   symbol table.  It is called via elf_link_hash_traverse.  */
169133965Sjdp
1692130561Sobrienbfd_boolean
1693130561Sobrien_bfd_elf_export_symbol (struct elf_link_hash_entry *h, void *data)
169433965Sjdp{
1695130561Sobrien  struct elf_info_failed *eif = data;
169633965Sjdp
1697218822Sdim  /* Ignore this if we won't export it.  */
1698218822Sdim  if (!eif->info->export_dynamic && !h->dynamic)
1699218822Sdim    return TRUE;
1700218822Sdim
1701130561Sobrien  /* Ignore indirect symbols.  These are added by the versioning code.  */
1702130561Sobrien  if (h->root.type == bfd_link_hash_indirect)
1703130561Sobrien    return TRUE;
170433965Sjdp
1705130561Sobrien  if (h->root.type == bfd_link_hash_warning)
1706130561Sobrien    h = (struct elf_link_hash_entry *) h->root.u.i.link;
1707130561Sobrien
1708130561Sobrien  if (h->dynindx == -1
1709218822Sdim      && (h->def_regular
1710218822Sdim	  || h->ref_regular))
171133965Sjdp    {
1712130561Sobrien      struct bfd_elf_version_tree *t;
1713130561Sobrien      struct bfd_elf_version_expr *d;
1714130561Sobrien
1715130561Sobrien      for (t = eif->verdefs; t != NULL; t = t->next)
1716130561Sobrien	{
1717130561Sobrien	  if (t->globals.list != NULL)
1718130561Sobrien	    {
1719130561Sobrien	      d = (*t->match) (&t->globals, NULL, h->root.root.string);
1720130561Sobrien	      if (d != NULL)
1721130561Sobrien		goto doit;
1722130561Sobrien	    }
1723130561Sobrien
1724130561Sobrien	  if (t->locals.list != NULL)
1725130561Sobrien	    {
1726130561Sobrien	      d = (*t->match) (&t->locals, NULL, h->root.root.string);
1727130561Sobrien	      if (d != NULL)
1728130561Sobrien		return TRUE;
1729130561Sobrien	    }
1730130561Sobrien	}
1731130561Sobrien
1732130561Sobrien      if (!eif->verdefs)
1733130561Sobrien	{
1734130561Sobrien	doit:
1735130561Sobrien	  if (! bfd_elf_link_record_dynamic_symbol (eif->info, h))
1736130561Sobrien	    {
1737130561Sobrien	      eif->failed = TRUE;
1738130561Sobrien	      return FALSE;
1739130561Sobrien	    }
1740130561Sobrien	}
1741130561Sobrien    }
1742130561Sobrien
1743130561Sobrien  return TRUE;
1744130561Sobrien}
1745130561Sobrien
1746130561Sobrien/* Look through the symbols which are defined in other shared
1747130561Sobrien   libraries and referenced here.  Update the list of version
1748130561Sobrien   dependencies.  This will be put into the .gnu.version_r section.
1749130561Sobrien   This function is called via elf_link_hash_traverse.  */
1750130561Sobrien
1751130561Sobrienbfd_boolean
1752130561Sobrien_bfd_elf_link_find_version_dependencies (struct elf_link_hash_entry *h,
1753130561Sobrien					 void *data)
1754130561Sobrien{
1755130561Sobrien  struct elf_find_verdep_info *rinfo = data;
1756130561Sobrien  Elf_Internal_Verneed *t;
1757130561Sobrien  Elf_Internal_Vernaux *a;
1758130561Sobrien  bfd_size_type amt;
1759130561Sobrien
1760130561Sobrien  if (h->root.type == bfd_link_hash_warning)
1761130561Sobrien    h = (struct elf_link_hash_entry *) h->root.u.i.link;
1762130561Sobrien
1763130561Sobrien  /* We only care about symbols defined in shared objects with version
1764130561Sobrien     information.  */
1765218822Sdim  if (!h->def_dynamic
1766218822Sdim      || h->def_regular
1767130561Sobrien      || h->dynindx == -1
1768130561Sobrien      || h->verinfo.verdef == NULL)
1769130561Sobrien    return TRUE;
1770130561Sobrien
1771130561Sobrien  /* See if we already know about this version.  */
1772130561Sobrien  for (t = elf_tdata (rinfo->output_bfd)->verref; t != NULL; t = t->vn_nextref)
1773130561Sobrien    {
1774130561Sobrien      if (t->vn_bfd != h->verinfo.verdef->vd_bfd)
1775130561Sobrien	continue;
1776130561Sobrien
1777130561Sobrien      for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
1778130561Sobrien	if (a->vna_nodename == h->verinfo.verdef->vd_nodename)
1779130561Sobrien	  return TRUE;
1780130561Sobrien
1781130561Sobrien      break;
1782130561Sobrien    }
1783130561Sobrien
1784130561Sobrien  /* This is a new version.  Add it to tree we are building.  */
1785130561Sobrien
1786130561Sobrien  if (t == NULL)
1787130561Sobrien    {
1788130561Sobrien      amt = sizeof *t;
1789130561Sobrien      t = bfd_zalloc (rinfo->output_bfd, amt);
1790130561Sobrien      if (t == NULL)
1791130561Sobrien	{
1792130561Sobrien	  rinfo->failed = TRUE;
1793130561Sobrien	  return FALSE;
1794130561Sobrien	}
1795130561Sobrien
1796130561Sobrien      t->vn_bfd = h->verinfo.verdef->vd_bfd;
1797130561Sobrien      t->vn_nextref = elf_tdata (rinfo->output_bfd)->verref;
1798130561Sobrien      elf_tdata (rinfo->output_bfd)->verref = t;
1799130561Sobrien    }
1800130561Sobrien
1801130561Sobrien  amt = sizeof *a;
1802130561Sobrien  a = bfd_zalloc (rinfo->output_bfd, amt);
1803130561Sobrien
1804130561Sobrien  /* Note that we are copying a string pointer here, and testing it
1805130561Sobrien     above.  If bfd_elf_string_from_elf_section is ever changed to
1806130561Sobrien     discard the string data when low in memory, this will have to be
1807130561Sobrien     fixed.  */
1808130561Sobrien  a->vna_nodename = h->verinfo.verdef->vd_nodename;
1809130561Sobrien
1810130561Sobrien  a->vna_flags = h->verinfo.verdef->vd_flags;
1811130561Sobrien  a->vna_nextptr = t->vn_auxptr;
1812130561Sobrien
1813130561Sobrien  h->verinfo.verdef->vd_exp_refno = rinfo->vers;
1814130561Sobrien  ++rinfo->vers;
1815130561Sobrien
1816130561Sobrien  a->vna_other = h->verinfo.verdef->vd_exp_refno + 1;
1817130561Sobrien
1818130561Sobrien  t->vn_auxptr = a;
1819130561Sobrien
1820130561Sobrien  return TRUE;
1821130561Sobrien}
1822130561Sobrien
1823130561Sobrien/* Figure out appropriate versions for all the symbols.  We may not
1824130561Sobrien   have the version number script until we have read all of the input
1825130561Sobrien   files, so until that point we don't know which symbols should be
1826130561Sobrien   local.  This function is called via elf_link_hash_traverse.  */
1827130561Sobrien
1828130561Sobrienbfd_boolean
1829130561Sobrien_bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data)
1830130561Sobrien{
1831130561Sobrien  struct elf_assign_sym_version_info *sinfo;
1832130561Sobrien  struct bfd_link_info *info;
1833130561Sobrien  const struct elf_backend_data *bed;
1834130561Sobrien  struct elf_info_failed eif;
1835130561Sobrien  char *p;
1836130561Sobrien  bfd_size_type amt;
1837130561Sobrien
1838130561Sobrien  sinfo = data;
1839130561Sobrien  info = sinfo->info;
1840130561Sobrien
1841130561Sobrien  if (h->root.type == bfd_link_hash_warning)
1842130561Sobrien    h = (struct elf_link_hash_entry *) h->root.u.i.link;
1843130561Sobrien
1844130561Sobrien  /* Fix the symbol flags.  */
1845130561Sobrien  eif.failed = FALSE;
1846130561Sobrien  eif.info = info;
1847130561Sobrien  if (! _bfd_elf_fix_symbol_flags (h, &eif))
1848130561Sobrien    {
1849130561Sobrien      if (eif.failed)
1850130561Sobrien	sinfo->failed = TRUE;
1851130561Sobrien      return FALSE;
1852130561Sobrien    }
1853130561Sobrien
1854130561Sobrien  /* We only need version numbers for symbols defined in regular
1855130561Sobrien     objects.  */
1856218822Sdim  if (!h->def_regular)
1857130561Sobrien    return TRUE;
1858130561Sobrien
1859130561Sobrien  bed = get_elf_backend_data (sinfo->output_bfd);
1860130561Sobrien  p = strchr (h->root.root.string, ELF_VER_CHR);
1861130561Sobrien  if (p != NULL && h->verinfo.vertree == NULL)
1862130561Sobrien    {
1863130561Sobrien      struct bfd_elf_version_tree *t;
1864130561Sobrien      bfd_boolean hidden;
1865130561Sobrien
1866130561Sobrien      hidden = TRUE;
1867130561Sobrien
1868130561Sobrien      /* There are two consecutive ELF_VER_CHR characters if this is
1869130561Sobrien	 not a hidden symbol.  */
1870130561Sobrien      ++p;
1871130561Sobrien      if (*p == ELF_VER_CHR)
1872130561Sobrien	{
1873130561Sobrien	  hidden = FALSE;
1874130561Sobrien	  ++p;
1875130561Sobrien	}
1876130561Sobrien
1877130561Sobrien      /* If there is no version string, we can just return out.  */
1878130561Sobrien      if (*p == '\0')
1879130561Sobrien	{
1880130561Sobrien	  if (hidden)
1881218822Sdim	    h->hidden = 1;
1882130561Sobrien	  return TRUE;
1883130561Sobrien	}
1884130561Sobrien
1885130561Sobrien      /* Look for the version.  If we find it, it is no longer weak.  */
1886130561Sobrien      for (t = sinfo->verdefs; t != NULL; t = t->next)
1887130561Sobrien	{
1888130561Sobrien	  if (strcmp (t->name, p) == 0)
1889130561Sobrien	    {
1890130561Sobrien	      size_t len;
1891130561Sobrien	      char *alc;
1892130561Sobrien	      struct bfd_elf_version_expr *d;
1893130561Sobrien
1894130561Sobrien	      len = p - h->root.root.string;
1895130561Sobrien	      alc = bfd_malloc (len);
1896130561Sobrien	      if (alc == NULL)
1897130561Sobrien		return FALSE;
1898130561Sobrien	      memcpy (alc, h->root.root.string, len - 1);
1899130561Sobrien	      alc[len - 1] = '\0';
1900130561Sobrien	      if (alc[len - 2] == ELF_VER_CHR)
1901130561Sobrien		alc[len - 2] = '\0';
1902130561Sobrien
1903130561Sobrien	      h->verinfo.vertree = t;
1904130561Sobrien	      t->used = TRUE;
1905130561Sobrien	      d = NULL;
1906130561Sobrien
1907130561Sobrien	      if (t->globals.list != NULL)
1908130561Sobrien		d = (*t->match) (&t->globals, NULL, alc);
1909130561Sobrien
1910130561Sobrien	      /* See if there is anything to force this symbol to
1911130561Sobrien		 local scope.  */
1912130561Sobrien	      if (d == NULL && t->locals.list != NULL)
1913130561Sobrien		{
1914130561Sobrien		  d = (*t->match) (&t->locals, NULL, alc);
1915130561Sobrien		  if (d != NULL
1916130561Sobrien		      && h->dynindx != -1
1917130561Sobrien		      && ! info->export_dynamic)
1918130561Sobrien		    (*bed->elf_backend_hide_symbol) (info, h, TRUE);
1919130561Sobrien		}
1920130561Sobrien
1921130561Sobrien	      free (alc);
1922130561Sobrien	      break;
1923130561Sobrien	    }
1924130561Sobrien	}
1925130561Sobrien
1926130561Sobrien      /* If we are building an application, we need to create a
1927130561Sobrien	 version node for this version.  */
1928130561Sobrien      if (t == NULL && info->executable)
1929130561Sobrien	{
1930130561Sobrien	  struct bfd_elf_version_tree **pp;
1931130561Sobrien	  int version_index;
1932130561Sobrien
1933130561Sobrien	  /* If we aren't going to export this symbol, we don't need
1934130561Sobrien	     to worry about it.  */
1935130561Sobrien	  if (h->dynindx == -1)
1936130561Sobrien	    return TRUE;
1937130561Sobrien
1938130561Sobrien	  amt = sizeof *t;
1939130561Sobrien	  t = bfd_zalloc (sinfo->output_bfd, amt);
1940130561Sobrien	  if (t == NULL)
1941130561Sobrien	    {
1942130561Sobrien	      sinfo->failed = TRUE;
1943130561Sobrien	      return FALSE;
1944130561Sobrien	    }
1945130561Sobrien
1946130561Sobrien	  t->name = p;
1947130561Sobrien	  t->name_indx = (unsigned int) -1;
1948130561Sobrien	  t->used = TRUE;
1949130561Sobrien
1950130561Sobrien	  version_index = 1;
1951130561Sobrien	  /* Don't count anonymous version tag.  */
1952130561Sobrien	  if (sinfo->verdefs != NULL && sinfo->verdefs->vernum == 0)
1953130561Sobrien	    version_index = 0;
1954130561Sobrien	  for (pp = &sinfo->verdefs; *pp != NULL; pp = &(*pp)->next)
1955130561Sobrien	    ++version_index;
1956130561Sobrien	  t->vernum = version_index;
1957130561Sobrien
1958130561Sobrien	  *pp = t;
1959130561Sobrien
1960130561Sobrien	  h->verinfo.vertree = t;
1961130561Sobrien	}
1962130561Sobrien      else if (t == NULL)
1963130561Sobrien	{
1964130561Sobrien	  /* We could not find the version for a symbol when
1965130561Sobrien	     generating a shared archive.  Return an error.  */
1966130561Sobrien	  (*_bfd_error_handler)
1967218822Sdim	    (_("%B: version node not found for symbol %s"),
1968218822Sdim	     sinfo->output_bfd, h->root.root.string);
1969130561Sobrien	  bfd_set_error (bfd_error_bad_value);
1970130561Sobrien	  sinfo->failed = TRUE;
1971130561Sobrien	  return FALSE;
1972130561Sobrien	}
1973130561Sobrien
1974130561Sobrien      if (hidden)
1975218822Sdim	h->hidden = 1;
1976130561Sobrien    }
1977130561Sobrien
1978130561Sobrien  /* If we don't have a version for this symbol, see if we can find
1979130561Sobrien     something.  */
1980130561Sobrien  if (h->verinfo.vertree == NULL && sinfo->verdefs != NULL)
1981130561Sobrien    {
1982130561Sobrien      struct bfd_elf_version_tree *t;
1983130561Sobrien      struct bfd_elf_version_tree *local_ver;
1984130561Sobrien      struct bfd_elf_version_expr *d;
1985130561Sobrien
1986130561Sobrien      /* See if can find what version this symbol is in.  If the
1987130561Sobrien	 symbol is supposed to be local, then don't actually register
1988130561Sobrien	 it.  */
1989130561Sobrien      local_ver = NULL;
1990130561Sobrien      for (t = sinfo->verdefs; t != NULL; t = t->next)
1991130561Sobrien	{
1992130561Sobrien	  if (t->globals.list != NULL)
1993130561Sobrien	    {
1994130561Sobrien	      bfd_boolean matched;
1995130561Sobrien
1996130561Sobrien	      matched = FALSE;
1997130561Sobrien	      d = NULL;
1998130561Sobrien	      while ((d = (*t->match) (&t->globals, d,
1999130561Sobrien				       h->root.root.string)) != NULL)
2000130561Sobrien		if (d->symver)
2001130561Sobrien		  matched = TRUE;
2002130561Sobrien		else
2003130561Sobrien		  {
2004130561Sobrien		    /* There is a version without definition.  Make
2005130561Sobrien		       the symbol the default definition for this
2006130561Sobrien		       version.  */
2007130561Sobrien		    h->verinfo.vertree = t;
2008130561Sobrien		    local_ver = NULL;
2009130561Sobrien		    d->script = 1;
2010130561Sobrien		    break;
2011130561Sobrien		  }
2012130561Sobrien	      if (d != NULL)
2013130561Sobrien		break;
2014130561Sobrien	      else if (matched)
2015130561Sobrien		/* There is no undefined version for this symbol. Hide the
2016130561Sobrien		   default one.  */
2017130561Sobrien		(*bed->elf_backend_hide_symbol) (info, h, TRUE);
2018130561Sobrien	    }
2019130561Sobrien
2020130561Sobrien	  if (t->locals.list != NULL)
2021130561Sobrien	    {
2022130561Sobrien	      d = NULL;
2023130561Sobrien	      while ((d = (*t->match) (&t->locals, d,
2024130561Sobrien				       h->root.root.string)) != NULL)
2025130561Sobrien		{
2026130561Sobrien		  local_ver = t;
2027130561Sobrien		  /* If the match is "*", keep looking for a more
2028130561Sobrien		     explicit, perhaps even global, match.
2029130561Sobrien		     XXX: Shouldn't this be !d->wildcard instead?  */
2030130561Sobrien		  if (d->pattern[0] != '*' || d->pattern[1] != '\0')
2031130561Sobrien		    break;
2032130561Sobrien		}
2033130561Sobrien
2034130561Sobrien	      if (d != NULL)
2035130561Sobrien		break;
2036130561Sobrien	    }
2037130561Sobrien	}
2038130561Sobrien
2039130561Sobrien      if (local_ver != NULL)
2040130561Sobrien	{
2041130561Sobrien	  h->verinfo.vertree = local_ver;
2042130561Sobrien	  if (h->dynindx != -1
2043130561Sobrien	      && ! info->export_dynamic)
2044130561Sobrien	    {
2045130561Sobrien	      (*bed->elf_backend_hide_symbol) (info, h, TRUE);
2046130561Sobrien	    }
2047130561Sobrien	}
2048130561Sobrien    }
2049130561Sobrien
2050130561Sobrien  return TRUE;
2051130561Sobrien}
2052130561Sobrien
2053130561Sobrien/* Read and swap the relocs from the section indicated by SHDR.  This
2054130561Sobrien   may be either a REL or a RELA section.  The relocations are
2055130561Sobrien   translated into RELA relocations and stored in INTERNAL_RELOCS,
2056130561Sobrien   which should have already been allocated to contain enough space.
2057130561Sobrien   The EXTERNAL_RELOCS are a buffer where the external form of the
2058130561Sobrien   relocations should be stored.
2059130561Sobrien
2060130561Sobrien   Returns FALSE if something goes wrong.  */
2061130561Sobrien
2062130561Sobrienstatic bfd_boolean
2063130561Sobrienelf_link_read_relocs_from_section (bfd *abfd,
2064130561Sobrien				   asection *sec,
2065130561Sobrien				   Elf_Internal_Shdr *shdr,
2066130561Sobrien				   void *external_relocs,
2067130561Sobrien				   Elf_Internal_Rela *internal_relocs)
2068130561Sobrien{
2069130561Sobrien  const struct elf_backend_data *bed;
2070130561Sobrien  void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *);
2071130561Sobrien  const bfd_byte *erela;
2072130561Sobrien  const bfd_byte *erelaend;
2073130561Sobrien  Elf_Internal_Rela *irela;
2074130561Sobrien  Elf_Internal_Shdr *symtab_hdr;
2075130561Sobrien  size_t nsyms;
2076130561Sobrien
2077130561Sobrien  /* Position ourselves at the start of the section.  */
2078130561Sobrien  if (bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0)
2079130561Sobrien    return FALSE;
2080130561Sobrien
2081130561Sobrien  /* Read the relocations.  */
2082130561Sobrien  if (bfd_bread (external_relocs, shdr->sh_size, abfd) != shdr->sh_size)
2083130561Sobrien    return FALSE;
2084130561Sobrien
2085130561Sobrien  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2086130561Sobrien  nsyms = symtab_hdr->sh_size / symtab_hdr->sh_entsize;
2087130561Sobrien
2088130561Sobrien  bed = get_elf_backend_data (abfd);
2089130561Sobrien
2090130561Sobrien  /* Convert the external relocations to the internal format.  */
2091130561Sobrien  if (shdr->sh_entsize == bed->s->sizeof_rel)
2092130561Sobrien    swap_in = bed->s->swap_reloc_in;
2093130561Sobrien  else if (shdr->sh_entsize == bed->s->sizeof_rela)
2094130561Sobrien    swap_in = bed->s->swap_reloca_in;
2095130561Sobrien  else
2096130561Sobrien    {
2097130561Sobrien      bfd_set_error (bfd_error_wrong_format);
2098130561Sobrien      return FALSE;
2099130561Sobrien    }
2100130561Sobrien
2101130561Sobrien  erela = external_relocs;
2102130561Sobrien  erelaend = erela + shdr->sh_size;
2103130561Sobrien  irela = internal_relocs;
2104130561Sobrien  while (erela < erelaend)
2105130561Sobrien    {
2106130561Sobrien      bfd_vma r_symndx;
2107130561Sobrien
2108130561Sobrien      (*swap_in) (abfd, erela, irela);
2109130561Sobrien      r_symndx = ELF32_R_SYM (irela->r_info);
2110130561Sobrien      if (bed->s->arch_size == 64)
2111130561Sobrien	r_symndx >>= 24;
2112130561Sobrien      if ((size_t) r_symndx >= nsyms)
2113130561Sobrien	{
2114130561Sobrien	  (*_bfd_error_handler)
2115218822Sdim	    (_("%B: bad reloc symbol index (0x%lx >= 0x%lx)"
2116218822Sdim	       " for offset 0x%lx in section `%A'"),
2117218822Sdim	     abfd, sec,
2118218822Sdim	     (unsigned long) r_symndx, (unsigned long) nsyms, irela->r_offset);
2119130561Sobrien	  bfd_set_error (bfd_error_bad_value);
2120130561Sobrien	  return FALSE;
2121130561Sobrien	}
2122130561Sobrien      irela += bed->s->int_rels_per_ext_rel;
2123130561Sobrien      erela += shdr->sh_entsize;
2124130561Sobrien    }
2125130561Sobrien
2126130561Sobrien  return TRUE;
2127130561Sobrien}
2128130561Sobrien
2129130561Sobrien/* Read and swap the relocs for a section O.  They may have been
2130130561Sobrien   cached.  If the EXTERNAL_RELOCS and INTERNAL_RELOCS arguments are
2131130561Sobrien   not NULL, they are used as buffers to read into.  They are known to
2132130561Sobrien   be large enough.  If the INTERNAL_RELOCS relocs argument is NULL,
2133130561Sobrien   the return value is allocated using either malloc or bfd_alloc,
2134130561Sobrien   according to the KEEP_MEMORY argument.  If O has two relocation
2135130561Sobrien   sections (both REL and RELA relocations), then the REL_HDR
2136130561Sobrien   relocations will appear first in INTERNAL_RELOCS, followed by the
2137130561Sobrien   REL_HDR2 relocations.  */
2138130561Sobrien
2139130561SobrienElf_Internal_Rela *
2140130561Sobrien_bfd_elf_link_read_relocs (bfd *abfd,
2141130561Sobrien			   asection *o,
2142130561Sobrien			   void *external_relocs,
2143130561Sobrien			   Elf_Internal_Rela *internal_relocs,
2144130561Sobrien			   bfd_boolean keep_memory)
2145130561Sobrien{
2146130561Sobrien  Elf_Internal_Shdr *rel_hdr;
2147130561Sobrien  void *alloc1 = NULL;
2148130561Sobrien  Elf_Internal_Rela *alloc2 = NULL;
2149130561Sobrien  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
2150130561Sobrien
2151130561Sobrien  if (elf_section_data (o)->relocs != NULL)
2152130561Sobrien    return elf_section_data (o)->relocs;
2153130561Sobrien
2154130561Sobrien  if (o->reloc_count == 0)
2155130561Sobrien    return NULL;
2156130561Sobrien
2157130561Sobrien  rel_hdr = &elf_section_data (o)->rel_hdr;
2158130561Sobrien
2159130561Sobrien  if (internal_relocs == NULL)
2160130561Sobrien    {
2161130561Sobrien      bfd_size_type size;
2162130561Sobrien
2163130561Sobrien      size = o->reloc_count;
2164130561Sobrien      size *= bed->s->int_rels_per_ext_rel * sizeof (Elf_Internal_Rela);
2165130561Sobrien      if (keep_memory)
2166130561Sobrien	internal_relocs = bfd_alloc (abfd, size);
2167130561Sobrien      else
2168130561Sobrien	internal_relocs = alloc2 = bfd_malloc (size);
2169130561Sobrien      if (internal_relocs == NULL)
2170130561Sobrien	goto error_return;
2171130561Sobrien    }
2172130561Sobrien
2173130561Sobrien  if (external_relocs == NULL)
2174130561Sobrien    {
2175130561Sobrien      bfd_size_type size = rel_hdr->sh_size;
2176130561Sobrien
2177130561Sobrien      if (elf_section_data (o)->rel_hdr2)
2178130561Sobrien	size += elf_section_data (o)->rel_hdr2->sh_size;
2179130561Sobrien      alloc1 = bfd_malloc (size);
2180130561Sobrien      if (alloc1 == NULL)
2181130561Sobrien	goto error_return;
2182130561Sobrien      external_relocs = alloc1;
2183130561Sobrien    }
2184130561Sobrien
2185130561Sobrien  if (!elf_link_read_relocs_from_section (abfd, o, rel_hdr,
2186130561Sobrien					  external_relocs,
2187130561Sobrien					  internal_relocs))
2188130561Sobrien    goto error_return;
2189130561Sobrien  if (elf_section_data (o)->rel_hdr2
2190130561Sobrien      && (!elf_link_read_relocs_from_section
2191130561Sobrien	  (abfd, o,
2192130561Sobrien	   elf_section_data (o)->rel_hdr2,
2193130561Sobrien	   ((bfd_byte *) external_relocs) + rel_hdr->sh_size,
2194130561Sobrien	   internal_relocs + (NUM_SHDR_ENTRIES (rel_hdr)
2195130561Sobrien			      * bed->s->int_rels_per_ext_rel))))
2196130561Sobrien    goto error_return;
2197130561Sobrien
2198130561Sobrien  /* Cache the results for next time, if we can.  */
2199130561Sobrien  if (keep_memory)
2200130561Sobrien    elf_section_data (o)->relocs = internal_relocs;
2201130561Sobrien
2202130561Sobrien  if (alloc1 != NULL)
2203130561Sobrien    free (alloc1);
2204130561Sobrien
2205130561Sobrien  /* Don't free alloc2, since if it was allocated we are passing it
2206130561Sobrien     back (under the name of internal_relocs).  */
2207130561Sobrien
2208130561Sobrien  return internal_relocs;
2209130561Sobrien
2210130561Sobrien error_return:
2211130561Sobrien  if (alloc1 != NULL)
2212130561Sobrien    free (alloc1);
2213130561Sobrien  if (alloc2 != NULL)
2214130561Sobrien    free (alloc2);
2215130561Sobrien  return NULL;
2216130561Sobrien}
2217130561Sobrien
2218130561Sobrien/* Compute the size of, and allocate space for, REL_HDR which is the
2219130561Sobrien   section header for a section containing relocations for O.  */
2220130561Sobrien
2221130561Sobrienbfd_boolean
2222130561Sobrien_bfd_elf_link_size_reloc_section (bfd *abfd,
2223130561Sobrien				  Elf_Internal_Shdr *rel_hdr,
2224130561Sobrien				  asection *o)
2225130561Sobrien{
2226130561Sobrien  bfd_size_type reloc_count;
2227130561Sobrien  bfd_size_type num_rel_hashes;
2228130561Sobrien
2229130561Sobrien  /* Figure out how many relocations there will be.  */
2230130561Sobrien  if (rel_hdr == &elf_section_data (o)->rel_hdr)
2231130561Sobrien    reloc_count = elf_section_data (o)->rel_count;
2232130561Sobrien  else
2233130561Sobrien    reloc_count = elf_section_data (o)->rel_count2;
2234130561Sobrien
2235130561Sobrien  num_rel_hashes = o->reloc_count;
2236130561Sobrien  if (num_rel_hashes < reloc_count)
2237130561Sobrien    num_rel_hashes = reloc_count;
2238130561Sobrien
2239130561Sobrien  /* That allows us to calculate the size of the section.  */
2240130561Sobrien  rel_hdr->sh_size = rel_hdr->sh_entsize * reloc_count;
2241130561Sobrien
2242130561Sobrien  /* The contents field must last into write_object_contents, so we
2243130561Sobrien     allocate it with bfd_alloc rather than malloc.  Also since we
2244130561Sobrien     cannot be sure that the contents will actually be filled in,
2245130561Sobrien     we zero the allocated space.  */
2246130561Sobrien  rel_hdr->contents = bfd_zalloc (abfd, rel_hdr->sh_size);
2247130561Sobrien  if (rel_hdr->contents == NULL && rel_hdr->sh_size != 0)
2248130561Sobrien    return FALSE;
2249130561Sobrien
2250130561Sobrien  /* We only allocate one set of hash entries, so we only do it the
2251130561Sobrien     first time we are called.  */
2252130561Sobrien  if (elf_section_data (o)->rel_hashes == NULL
2253130561Sobrien      && num_rel_hashes)
2254130561Sobrien    {
2255130561Sobrien      struct elf_link_hash_entry **p;
2256130561Sobrien
2257130561Sobrien      p = bfd_zmalloc (num_rel_hashes * sizeof (struct elf_link_hash_entry *));
2258130561Sobrien      if (p == NULL)
2259130561Sobrien	return FALSE;
2260130561Sobrien
2261130561Sobrien      elf_section_data (o)->rel_hashes = p;
2262130561Sobrien    }
2263130561Sobrien
2264130561Sobrien  return TRUE;
2265130561Sobrien}
2266130561Sobrien
2267130561Sobrien/* Copy the relocations indicated by the INTERNAL_RELOCS (which
2268130561Sobrien   originated from the section given by INPUT_REL_HDR) to the
2269130561Sobrien   OUTPUT_BFD.  */
2270130561Sobrien
2271130561Sobrienbfd_boolean
2272130561Sobrien_bfd_elf_link_output_relocs (bfd *output_bfd,
2273130561Sobrien			     asection *input_section,
2274130561Sobrien			     Elf_Internal_Shdr *input_rel_hdr,
2275218822Sdim			     Elf_Internal_Rela *internal_relocs,
2276218822Sdim			     struct elf_link_hash_entry **rel_hash
2277218822Sdim			       ATTRIBUTE_UNUSED)
2278130561Sobrien{
2279130561Sobrien  Elf_Internal_Rela *irela;
2280130561Sobrien  Elf_Internal_Rela *irelaend;
2281130561Sobrien  bfd_byte *erel;
2282130561Sobrien  Elf_Internal_Shdr *output_rel_hdr;
2283130561Sobrien  asection *output_section;
2284130561Sobrien  unsigned int *rel_countp = NULL;
2285130561Sobrien  const struct elf_backend_data *bed;
2286130561Sobrien  void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
2287130561Sobrien
2288130561Sobrien  output_section = input_section->output_section;
2289130561Sobrien  output_rel_hdr = NULL;
2290130561Sobrien
2291130561Sobrien  if (elf_section_data (output_section)->rel_hdr.sh_entsize
2292130561Sobrien      == input_rel_hdr->sh_entsize)
2293130561Sobrien    {
2294130561Sobrien      output_rel_hdr = &elf_section_data (output_section)->rel_hdr;
2295130561Sobrien      rel_countp = &elf_section_data (output_section)->rel_count;
2296130561Sobrien    }
2297130561Sobrien  else if (elf_section_data (output_section)->rel_hdr2
2298130561Sobrien	   && (elf_section_data (output_section)->rel_hdr2->sh_entsize
2299130561Sobrien	       == input_rel_hdr->sh_entsize))
2300130561Sobrien    {
2301130561Sobrien      output_rel_hdr = elf_section_data (output_section)->rel_hdr2;
2302130561Sobrien      rel_countp = &elf_section_data (output_section)->rel_count2;
2303130561Sobrien    }
2304130561Sobrien  else
2305130561Sobrien    {
2306130561Sobrien      (*_bfd_error_handler)
2307218822Sdim	(_("%B: relocation size mismatch in %B section %A"),
2308218822Sdim	 output_bfd, input_section->owner, input_section);
2309130561Sobrien      bfd_set_error (bfd_error_wrong_object_format);
2310130561Sobrien      return FALSE;
2311130561Sobrien    }
2312130561Sobrien
2313130561Sobrien  bed = get_elf_backend_data (output_bfd);
2314130561Sobrien  if (input_rel_hdr->sh_entsize == bed->s->sizeof_rel)
2315130561Sobrien    swap_out = bed->s->swap_reloc_out;
2316130561Sobrien  else if (input_rel_hdr->sh_entsize == bed->s->sizeof_rela)
2317130561Sobrien    swap_out = bed->s->swap_reloca_out;
2318130561Sobrien  else
2319130561Sobrien    abort ();
2320130561Sobrien
2321130561Sobrien  erel = output_rel_hdr->contents;
2322130561Sobrien  erel += *rel_countp * input_rel_hdr->sh_entsize;
2323130561Sobrien  irela = internal_relocs;
2324130561Sobrien  irelaend = irela + (NUM_SHDR_ENTRIES (input_rel_hdr)
2325130561Sobrien		      * bed->s->int_rels_per_ext_rel);
2326130561Sobrien  while (irela < irelaend)
2327130561Sobrien    {
2328130561Sobrien      (*swap_out) (output_bfd, irela, erel);
2329130561Sobrien      irela += bed->s->int_rels_per_ext_rel;
2330130561Sobrien      erel += input_rel_hdr->sh_entsize;
2331130561Sobrien    }
2332130561Sobrien
2333130561Sobrien  /* Bump the counter, so that we know where to add the next set of
2334130561Sobrien     relocations.  */
2335130561Sobrien  *rel_countp += NUM_SHDR_ENTRIES (input_rel_hdr);
2336130561Sobrien
2337130561Sobrien  return TRUE;
2338130561Sobrien}
2339130561Sobrien
2340218822Sdim/* Make weak undefined symbols in PIE dynamic.  */
2341218822Sdim
2342218822Sdimbfd_boolean
2343218822Sdim_bfd_elf_link_hash_fixup_symbol (struct bfd_link_info *info,
2344218822Sdim				 struct elf_link_hash_entry *h)
2345218822Sdim{
2346218822Sdim  if (info->pie
2347218822Sdim      && h->dynindx == -1
2348218822Sdim      && h->root.type == bfd_link_hash_undefweak)
2349218822Sdim    return bfd_elf_link_record_dynamic_symbol (info, h);
2350218822Sdim
2351218822Sdim  return TRUE;
2352218822Sdim}
2353218822Sdim
2354130561Sobrien/* Fix up the flags for a symbol.  This handles various cases which
2355130561Sobrien   can only be fixed after all the input files are seen.  This is
2356130561Sobrien   currently called by both adjust_dynamic_symbol and
2357130561Sobrien   assign_sym_version, which is unnecessary but perhaps more robust in
2358130561Sobrien   the face of future changes.  */
2359130561Sobrien
2360130561Sobrienbfd_boolean
2361130561Sobrien_bfd_elf_fix_symbol_flags (struct elf_link_hash_entry *h,
2362130561Sobrien			   struct elf_info_failed *eif)
2363130561Sobrien{
2364218822Sdim  const struct elf_backend_data *bed = NULL;
2365218822Sdim
2366130561Sobrien  /* If this symbol was mentioned in a non-ELF file, try to set
2367130561Sobrien     DEF_REGULAR and REF_REGULAR correctly.  This is the only way to
2368130561Sobrien     permit a non-ELF file to correctly refer to a symbol defined in
2369130561Sobrien     an ELF dynamic object.  */
2370218822Sdim  if (h->non_elf)
2371130561Sobrien    {
2372130561Sobrien      while (h->root.type == bfd_link_hash_indirect)
2373130561Sobrien	h = (struct elf_link_hash_entry *) h->root.u.i.link;
2374130561Sobrien
2375130561Sobrien      if (h->root.type != bfd_link_hash_defined
2376130561Sobrien	  && h->root.type != bfd_link_hash_defweak)
2377218822Sdim	{
2378218822Sdim	  h->ref_regular = 1;
2379218822Sdim	  h->ref_regular_nonweak = 1;
2380218822Sdim	}
2381130561Sobrien      else
2382130561Sobrien	{
2383130561Sobrien	  if (h->root.u.def.section->owner != NULL
2384130561Sobrien	      && (bfd_get_flavour (h->root.u.def.section->owner)
2385130561Sobrien		  == bfd_target_elf_flavour))
2386218822Sdim	    {
2387218822Sdim	      h->ref_regular = 1;
2388218822Sdim	      h->ref_regular_nonweak = 1;
2389218822Sdim	    }
2390130561Sobrien	  else
2391218822Sdim	    h->def_regular = 1;
2392130561Sobrien	}
2393130561Sobrien
2394130561Sobrien      if (h->dynindx == -1
2395218822Sdim	  && (h->def_dynamic
2396218822Sdim	      || h->ref_dynamic))
2397130561Sobrien	{
2398130561Sobrien	  if (! bfd_elf_link_record_dynamic_symbol (eif->info, h))
2399130561Sobrien	    {
2400130561Sobrien	      eif->failed = TRUE;
2401130561Sobrien	      return FALSE;
2402130561Sobrien	    }
2403130561Sobrien	}
2404130561Sobrien    }
2405130561Sobrien  else
2406130561Sobrien    {
2407218822Sdim      /* Unfortunately, NON_ELF is only correct if the symbol
2408130561Sobrien	 was first seen in a non-ELF file.  Fortunately, if the symbol
2409130561Sobrien	 was first seen in an ELF file, we're probably OK unless the
2410130561Sobrien	 symbol was defined in a non-ELF file.  Catch that case here.
2411130561Sobrien	 FIXME: We're still in trouble if the symbol was first seen in
2412130561Sobrien	 a dynamic object, and then later in a non-ELF regular object.  */
2413130561Sobrien      if ((h->root.type == bfd_link_hash_defined
2414130561Sobrien	   || h->root.type == bfd_link_hash_defweak)
2415218822Sdim	  && !h->def_regular
2416130561Sobrien	  && (h->root.u.def.section->owner != NULL
2417130561Sobrien	      ? (bfd_get_flavour (h->root.u.def.section->owner)
2418130561Sobrien		 != bfd_target_elf_flavour)
2419130561Sobrien	      : (bfd_is_abs_section (h->root.u.def.section)
2420218822Sdim		 && !h->def_dynamic)))
2421218822Sdim	h->def_regular = 1;
2422130561Sobrien    }
2423130561Sobrien
2424218822Sdim  /* Backend specific symbol fixup.  */
2425218822Sdim  if (elf_hash_table (eif->info)->dynobj)
2426218822Sdim    {
2427218822Sdim      bed = get_elf_backend_data (elf_hash_table (eif->info)->dynobj);
2428218822Sdim      if (bed->elf_backend_fixup_symbol
2429218822Sdim	  && !(*bed->elf_backend_fixup_symbol) (eif->info, h))
2430218822Sdim	return FALSE;
2431218822Sdim    }
2432218822Sdim
2433130561Sobrien  /* If this is a final link, and the symbol was defined as a common
2434130561Sobrien     symbol in a regular object file, and there was no definition in
2435130561Sobrien     any dynamic object, then the linker will have allocated space for
2436218822Sdim     the symbol in a common section but the DEF_REGULAR
2437130561Sobrien     flag will not have been set.  */
2438130561Sobrien  if (h->root.type == bfd_link_hash_defined
2439218822Sdim      && !h->def_regular
2440218822Sdim      && h->ref_regular
2441218822Sdim      && !h->def_dynamic
2442130561Sobrien      && (h->root.u.def.section->owner->flags & DYNAMIC) == 0)
2443218822Sdim    h->def_regular = 1;
2444130561Sobrien
2445130561Sobrien  /* If -Bsymbolic was used (which means to bind references to global
2446130561Sobrien     symbols to the definition within the shared object), and this
2447130561Sobrien     symbol was defined in a regular object, then it actually doesn't
2448130561Sobrien     need a PLT entry.  Likewise, if the symbol has non-default
2449130561Sobrien     visibility.  If the symbol has hidden or internal visibility, we
2450130561Sobrien     will force it local.  */
2451218822Sdim  if (h->needs_plt
2452130561Sobrien      && eif->info->shared
2453130561Sobrien      && is_elf_hash_table (eif->info->hash)
2454218822Sdim      && (SYMBOLIC_BIND (eif->info, h)
2455130561Sobrien	  || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
2456218822Sdim      && h->def_regular)
2457130561Sobrien    {
2458130561Sobrien      bfd_boolean force_local;
2459130561Sobrien
2460130561Sobrien      force_local = (ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
2461130561Sobrien		     || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN);
2462130561Sobrien      (*bed->elf_backend_hide_symbol) (eif->info, h, force_local);
2463130561Sobrien    }
2464130561Sobrien
2465130561Sobrien  /* If a weak undefined symbol has non-default visibility, we also
2466130561Sobrien     hide it from the dynamic linker.  */
2467130561Sobrien  if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
2468130561Sobrien      && h->root.type == bfd_link_hash_undefweak)
2469130561Sobrien    {
2470130561Sobrien      const struct elf_backend_data *bed;
2471130561Sobrien      bed = get_elf_backend_data (elf_hash_table (eif->info)->dynobj);
2472130561Sobrien      (*bed->elf_backend_hide_symbol) (eif->info, h, TRUE);
2473130561Sobrien    }
2474130561Sobrien
2475130561Sobrien  /* If this is a weak defined symbol in a dynamic object, and we know
2476130561Sobrien     the real definition in the dynamic object, copy interesting flags
2477130561Sobrien     over to the real definition.  */
2478218822Sdim  if (h->u.weakdef != NULL)
2479130561Sobrien    {
2480130561Sobrien      struct elf_link_hash_entry *weakdef;
2481130561Sobrien
2482218822Sdim      weakdef = h->u.weakdef;
2483130561Sobrien      if (h->root.type == bfd_link_hash_indirect)
2484130561Sobrien	h = (struct elf_link_hash_entry *) h->root.u.i.link;
2485130561Sobrien
2486130561Sobrien      BFD_ASSERT (h->root.type == bfd_link_hash_defined
2487130561Sobrien		  || h->root.type == bfd_link_hash_defweak);
2488130561Sobrien      BFD_ASSERT (weakdef->root.type == bfd_link_hash_defined
2489130561Sobrien		  || weakdef->root.type == bfd_link_hash_defweak);
2490218822Sdim      BFD_ASSERT (weakdef->def_dynamic);
2491130561Sobrien
2492130561Sobrien      /* If the real definition is defined by a regular object file,
2493130561Sobrien	 don't do anything special.  See the longer description in
2494130561Sobrien	 _bfd_elf_adjust_dynamic_symbol, below.  */
2495218822Sdim      if (weakdef->def_regular)
2496218822Sdim	h->u.weakdef = NULL;
2497130561Sobrien      else
2498218822Sdim	(*bed->elf_backend_copy_indirect_symbol) (eif->info, weakdef,
2499218822Sdim						  h);
2500130561Sobrien    }
2501130561Sobrien
2502130561Sobrien  return TRUE;
2503130561Sobrien}
2504130561Sobrien
2505130561Sobrien/* Make the backend pick a good value for a dynamic symbol.  This is
2506130561Sobrien   called via elf_link_hash_traverse, and also calls itself
2507130561Sobrien   recursively.  */
2508130561Sobrien
2509130561Sobrienbfd_boolean
2510130561Sobrien_bfd_elf_adjust_dynamic_symbol (struct elf_link_hash_entry *h, void *data)
2511130561Sobrien{
2512130561Sobrien  struct elf_info_failed *eif = data;
2513130561Sobrien  bfd *dynobj;
2514130561Sobrien  const struct elf_backend_data *bed;
2515130561Sobrien
2516130561Sobrien  if (! is_elf_hash_table (eif->info->hash))
2517130561Sobrien    return FALSE;
2518130561Sobrien
2519130561Sobrien  if (h->root.type == bfd_link_hash_warning)
2520130561Sobrien    {
2521218822Sdim      h->got = elf_hash_table (eif->info)->init_got_offset;
2522218822Sdim      h->plt = elf_hash_table (eif->info)->init_plt_offset;
2523130561Sobrien
2524130561Sobrien      /* When warning symbols are created, they **replace** the "real"
2525130561Sobrien	 entry in the hash table, thus we never get to see the real
2526130561Sobrien	 symbol in a hash traversal.  So look at it now.  */
2527130561Sobrien      h = (struct elf_link_hash_entry *) h->root.u.i.link;
2528130561Sobrien    }
2529130561Sobrien
2530130561Sobrien  /* Ignore indirect symbols.  These are added by the versioning code.  */
2531130561Sobrien  if (h->root.type == bfd_link_hash_indirect)
2532130561Sobrien    return TRUE;
2533130561Sobrien
2534130561Sobrien  /* Fix the symbol flags.  */
2535130561Sobrien  if (! _bfd_elf_fix_symbol_flags (h, eif))
2536130561Sobrien    return FALSE;
2537130561Sobrien
2538130561Sobrien  /* If this symbol does not require a PLT entry, and it is not
2539130561Sobrien     defined by a dynamic object, or is not referenced by a regular
2540130561Sobrien     object, ignore it.  We do have to handle a weak defined symbol,
2541130561Sobrien     even if no regular object refers to it, if we decided to add it
2542130561Sobrien     to the dynamic symbol table.  FIXME: Do we normally need to worry
2543130561Sobrien     about symbols which are defined by one dynamic object and
2544130561Sobrien     referenced by another one?  */
2545218822Sdim  if (!h->needs_plt
2546218822Sdim      && (h->def_regular
2547218822Sdim	  || !h->def_dynamic
2548218822Sdim	  || (!h->ref_regular
2549218822Sdim	      && (h->u.weakdef == NULL || h->u.weakdef->dynindx == -1))))
2550130561Sobrien    {
2551218822Sdim      h->plt = elf_hash_table (eif->info)->init_plt_offset;
2552130561Sobrien      return TRUE;
2553130561Sobrien    }
2554130561Sobrien
2555130561Sobrien  /* If we've already adjusted this symbol, don't do it again.  This
2556130561Sobrien     can happen via a recursive call.  */
2557218822Sdim  if (h->dynamic_adjusted)
2558130561Sobrien    return TRUE;
2559130561Sobrien
2560130561Sobrien  /* Don't look at this symbol again.  Note that we must set this
2561130561Sobrien     after checking the above conditions, because we may look at a
2562130561Sobrien     symbol once, decide not to do anything, and then get called
2563130561Sobrien     recursively later after REF_REGULAR is set below.  */
2564218822Sdim  h->dynamic_adjusted = 1;
2565130561Sobrien
2566130561Sobrien  /* If this is a weak definition, and we know a real definition, and
2567130561Sobrien     the real symbol is not itself defined by a regular object file,
2568130561Sobrien     then get a good value for the real definition.  We handle the
2569130561Sobrien     real symbol first, for the convenience of the backend routine.
2570130561Sobrien
2571130561Sobrien     Note that there is a confusing case here.  If the real definition
2572130561Sobrien     is defined by a regular object file, we don't get the real symbol
2573130561Sobrien     from the dynamic object, but we do get the weak symbol.  If the
2574130561Sobrien     processor backend uses a COPY reloc, then if some routine in the
2575130561Sobrien     dynamic object changes the real symbol, we will not see that
2576130561Sobrien     change in the corresponding weak symbol.  This is the way other
2577130561Sobrien     ELF linkers work as well, and seems to be a result of the shared
2578130561Sobrien     library model.
2579130561Sobrien
2580130561Sobrien     I will clarify this issue.  Most SVR4 shared libraries define the
2581130561Sobrien     variable _timezone and define timezone as a weak synonym.  The
2582130561Sobrien     tzset call changes _timezone.  If you write
2583130561Sobrien       extern int timezone;
2584130561Sobrien       int _timezone = 5;
2585130561Sobrien       int main () { tzset (); printf ("%d %d\n", timezone, _timezone); }
2586130561Sobrien     you might expect that, since timezone is a synonym for _timezone,
2587130561Sobrien     the same number will print both times.  However, if the processor
2588130561Sobrien     backend uses a COPY reloc, then actually timezone will be copied
2589130561Sobrien     into your process image, and, since you define _timezone
2590130561Sobrien     yourself, _timezone will not.  Thus timezone and _timezone will
2591130561Sobrien     wind up at different memory locations.  The tzset call will set
2592130561Sobrien     _timezone, leaving timezone unchanged.  */
2593130561Sobrien
2594218822Sdim  if (h->u.weakdef != NULL)
2595130561Sobrien    {
2596130561Sobrien      /* If we get to this point, we know there is an implicit
2597130561Sobrien	 reference by a regular object file via the weak symbol H.
2598130561Sobrien	 FIXME: Is this really true?  What if the traversal finds
2599218822Sdim	 H->U.WEAKDEF before it finds H?  */
2600218822Sdim      h->u.weakdef->ref_regular = 1;
2601130561Sobrien
2602218822Sdim      if (! _bfd_elf_adjust_dynamic_symbol (h->u.weakdef, eif))
2603130561Sobrien	return FALSE;
2604130561Sobrien    }
2605130561Sobrien
2606130561Sobrien  /* If a symbol has no type and no size and does not require a PLT
2607130561Sobrien     entry, then we are probably about to do the wrong thing here: we
2608130561Sobrien     are probably going to create a COPY reloc for an empty object.
2609130561Sobrien     This case can arise when a shared object is built with assembly
2610130561Sobrien     code, and the assembly code fails to set the symbol type.  */
2611130561Sobrien  if (h->size == 0
2612130561Sobrien      && h->type == STT_NOTYPE
2613218822Sdim      && !h->needs_plt)
2614130561Sobrien    (*_bfd_error_handler)
2615130561Sobrien      (_("warning: type and size of dynamic symbol `%s' are not defined"),
2616130561Sobrien       h->root.root.string);
2617130561Sobrien
2618130561Sobrien  dynobj = elf_hash_table (eif->info)->dynobj;
2619130561Sobrien  bed = get_elf_backend_data (dynobj);
2620130561Sobrien  if (! (*bed->elf_backend_adjust_dynamic_symbol) (eif->info, h))
2621130561Sobrien    {
2622130561Sobrien      eif->failed = TRUE;
2623130561Sobrien      return FALSE;
2624130561Sobrien    }
2625130561Sobrien
2626130561Sobrien  return TRUE;
2627130561Sobrien}
2628130561Sobrien
2629218822Sdim/* Adjust the dynamic symbol, H, for copy in the dynamic bss section,
2630218822Sdim   DYNBSS.  */
2631218822Sdim
2632218822Sdimbfd_boolean
2633218822Sdim_bfd_elf_adjust_dynamic_copy (struct elf_link_hash_entry *h,
2634218822Sdim			      asection *dynbss)
2635218822Sdim{
2636218822Sdim  unsigned int power_of_two;
2637218822Sdim  bfd_vma mask;
2638218822Sdim  asection *sec = h->root.u.def.section;
2639218822Sdim
2640218822Sdim  /* The section aligment of definition is the maximum alignment
2641218822Sdim     requirement of symbols defined in the section.  Since we don't
2642218822Sdim     know the symbol alignment requirement, we start with the
2643218822Sdim     maximum alignment and check low bits of the symbol address
2644218822Sdim     for the minimum alignment.  */
2645218822Sdim  power_of_two = bfd_get_section_alignment (sec->owner, sec);
2646218822Sdim  mask = ((bfd_vma) 1 << power_of_two) - 1;
2647218822Sdim  while ((h->root.u.def.value & mask) != 0)
2648218822Sdim    {
2649218822Sdim       mask >>= 1;
2650218822Sdim       --power_of_two;
2651218822Sdim    }
2652218822Sdim
2653218822Sdim  if (power_of_two > bfd_get_section_alignment (dynbss->owner,
2654218822Sdim						dynbss))
2655218822Sdim    {
2656218822Sdim      /* Adjust the section alignment if needed.  */
2657218822Sdim      if (! bfd_set_section_alignment (dynbss->owner, dynbss,
2658218822Sdim				       power_of_two))
2659218822Sdim	return FALSE;
2660218822Sdim    }
2661218822Sdim
2662218822Sdim  /* We make sure that the symbol will be aligned properly.  */
2663218822Sdim  dynbss->size = BFD_ALIGN (dynbss->size, mask + 1);
2664218822Sdim
2665218822Sdim  /* Define the symbol as being at this point in DYNBSS.  */
2666218822Sdim  h->root.u.def.section = dynbss;
2667218822Sdim  h->root.u.def.value = dynbss->size;
2668218822Sdim
2669218822Sdim  /* Increment the size of DYNBSS to make room for the symbol.  */
2670218822Sdim  dynbss->size += h->size;
2671218822Sdim
2672218822Sdim  return TRUE;
2673218822Sdim}
2674218822Sdim
2675130561Sobrien/* Adjust all external symbols pointing into SEC_MERGE sections
2676130561Sobrien   to reflect the object merging within the sections.  */
2677130561Sobrien
2678130561Sobrienbfd_boolean
2679130561Sobrien_bfd_elf_link_sec_merge_syms (struct elf_link_hash_entry *h, void *data)
2680130561Sobrien{
2681130561Sobrien  asection *sec;
2682130561Sobrien
2683130561Sobrien  if (h->root.type == bfd_link_hash_warning)
2684130561Sobrien    h = (struct elf_link_hash_entry *) h->root.u.i.link;
2685130561Sobrien
2686130561Sobrien  if ((h->root.type == bfd_link_hash_defined
2687130561Sobrien       || h->root.type == bfd_link_hash_defweak)
2688130561Sobrien      && ((sec = h->root.u.def.section)->flags & SEC_MERGE)
2689130561Sobrien      && sec->sec_info_type == ELF_INFO_TYPE_MERGE)
2690130561Sobrien    {
2691130561Sobrien      bfd *output_bfd = data;
2692130561Sobrien
2693130561Sobrien      h->root.u.def.value =
2694130561Sobrien	_bfd_merged_section_offset (output_bfd,
2695130561Sobrien				    &h->root.u.def.section,
2696130561Sobrien				    elf_section_data (sec)->sec_info,
2697218822Sdim				    h->root.u.def.value);
2698130561Sobrien    }
2699130561Sobrien
2700130561Sobrien  return TRUE;
2701130561Sobrien}
2702130561Sobrien
2703130561Sobrien/* Returns false if the symbol referred to by H should be considered
2704130561Sobrien   to resolve local to the current module, and true if it should be
2705130561Sobrien   considered to bind dynamically.  */
2706130561Sobrien
2707130561Sobrienbfd_boolean
2708130561Sobrien_bfd_elf_dynamic_symbol_p (struct elf_link_hash_entry *h,
2709130561Sobrien			   struct bfd_link_info *info,
2710130561Sobrien			   bfd_boolean ignore_protected)
2711130561Sobrien{
2712130561Sobrien  bfd_boolean binding_stays_local_p;
2713218822Sdim  const struct elf_backend_data *bed;
2714218822Sdim  struct elf_link_hash_table *hash_table;
2715130561Sobrien
2716130561Sobrien  if (h == NULL)
2717130561Sobrien    return FALSE;
2718130561Sobrien
2719130561Sobrien  while (h->root.type == bfd_link_hash_indirect
2720130561Sobrien	 || h->root.type == bfd_link_hash_warning)
2721130561Sobrien    h = (struct elf_link_hash_entry *) h->root.u.i.link;
2722130561Sobrien
2723130561Sobrien  /* If it was forced local, then clearly it's not dynamic.  */
2724130561Sobrien  if (h->dynindx == -1)
2725130561Sobrien    return FALSE;
2726218822Sdim  if (h->forced_local)
2727130561Sobrien    return FALSE;
2728130561Sobrien
2729130561Sobrien  /* Identify the cases where name binding rules say that a
2730130561Sobrien     visible symbol resolves locally.  */
2731218822Sdim  binding_stays_local_p = info->executable || SYMBOLIC_BIND (info, h);
2732130561Sobrien
2733130561Sobrien  switch (ELF_ST_VISIBILITY (h->other))
2734130561Sobrien    {
2735130561Sobrien    case STV_INTERNAL:
2736130561Sobrien    case STV_HIDDEN:
2737130561Sobrien      return FALSE;
2738130561Sobrien
2739130561Sobrien    case STV_PROTECTED:
2740218822Sdim      hash_table = elf_hash_table (info);
2741218822Sdim      if (!is_elf_hash_table (hash_table))
2742218822Sdim	return FALSE;
2743218822Sdim
2744218822Sdim      bed = get_elf_backend_data (hash_table->dynobj);
2745218822Sdim
2746130561Sobrien      /* Proper resolution for function pointer equality may require
2747130561Sobrien	 that these symbols perhaps be resolved dynamically, even though
2748130561Sobrien	 we should be resolving them to the current module.  */
2749218822Sdim      if (!ignore_protected || !bed->is_function_type (h->type))
2750130561Sobrien	binding_stays_local_p = TRUE;
2751130561Sobrien      break;
2752130561Sobrien
2753130561Sobrien    default:
2754130561Sobrien      break;
2755130561Sobrien    }
2756130561Sobrien
2757130561Sobrien  /* If it isn't defined locally, then clearly it's dynamic.  */
2758218822Sdim  if (!h->def_regular)
2759130561Sobrien    return TRUE;
2760130561Sobrien
2761130561Sobrien  /* Otherwise, the symbol is dynamic if binding rules don't tell
2762130561Sobrien     us that it remains local.  */
2763130561Sobrien  return !binding_stays_local_p;
2764130561Sobrien}
2765130561Sobrien
2766130561Sobrien/* Return true if the symbol referred to by H should be considered
2767130561Sobrien   to resolve local to the current module, and false otherwise.  Differs
2768130561Sobrien   from (the inverse of) _bfd_elf_dynamic_symbol_p in the treatment of
2769130561Sobrien   undefined symbols and weak symbols.  */
2770130561Sobrien
2771130561Sobrienbfd_boolean
2772130561Sobrien_bfd_elf_symbol_refs_local_p (struct elf_link_hash_entry *h,
2773130561Sobrien			      struct bfd_link_info *info,
2774130561Sobrien			      bfd_boolean local_protected)
2775130561Sobrien{
2776218822Sdim  const struct elf_backend_data *bed;
2777218822Sdim  struct elf_link_hash_table *hash_table;
2778218822Sdim
2779130561Sobrien  /* If it's a local sym, of course we resolve locally.  */
2780130561Sobrien  if (h == NULL)
2781130561Sobrien    return TRUE;
2782130561Sobrien
2783218822Sdim  /* Common symbols that become definitions don't get the DEF_REGULAR
2784218822Sdim     flag set, so test it first, and don't bail out.  */
2785218822Sdim  if (ELF_COMMON_DEF_P (h))
2786218822Sdim    /* Do nothing.  */;
2787130561Sobrien  /* If we don't have a definition in a regular file, then we can't
2788130561Sobrien     resolve locally.  The sym is either undefined or dynamic.  */
2789218822Sdim  else if (!h->def_regular)
2790130561Sobrien    return FALSE;
2791130561Sobrien
2792130561Sobrien  /* Forced local symbols resolve locally.  */
2793218822Sdim  if (h->forced_local)
2794130561Sobrien    return TRUE;
2795130561Sobrien
2796130561Sobrien  /* As do non-dynamic symbols.  */
2797130561Sobrien  if (h->dynindx == -1)
2798130561Sobrien    return TRUE;
2799130561Sobrien
2800130561Sobrien  /* At this point, we know the symbol is defined and dynamic.  In an
2801130561Sobrien     executable it must resolve locally, likewise when building symbolic
2802130561Sobrien     shared libraries.  */
2803218822Sdim  if (info->executable || SYMBOLIC_BIND (info, h))
2804130561Sobrien    return TRUE;
2805130561Sobrien
2806130561Sobrien  /* Now deal with defined dynamic symbols in shared libraries.  Ones
2807130561Sobrien     with default visibility might not resolve locally.  */
2808130561Sobrien  if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
2809130561Sobrien    return FALSE;
2810130561Sobrien
2811130561Sobrien  /* However, STV_HIDDEN or STV_INTERNAL ones must be local.  */
2812130561Sobrien  if (ELF_ST_VISIBILITY (h->other) != STV_PROTECTED)
2813130561Sobrien    return TRUE;
2814130561Sobrien
2815218822Sdim  hash_table = elf_hash_table (info);
2816218822Sdim  if (!is_elf_hash_table (hash_table))
2817218822Sdim    return TRUE;
2818218822Sdim
2819218822Sdim  bed = get_elf_backend_data (hash_table->dynobj);
2820218822Sdim
2821218822Sdim  /* STV_PROTECTED non-function symbols are local.  */
2822218822Sdim  if (!bed->is_function_type (h->type))
2823218822Sdim    return TRUE;
2824218822Sdim
2825130561Sobrien  /* Function pointer equality tests may require that STV_PROTECTED
2826130561Sobrien     symbols be treated as dynamic symbols, even when we know that the
2827130561Sobrien     dynamic linker will resolve them locally.  */
2828130561Sobrien  return local_protected;
2829130561Sobrien}
2830130561Sobrien
2831130561Sobrien/* Caches some TLS segment info, and ensures that the TLS segment vma is
2832130561Sobrien   aligned.  Returns the first TLS output section.  */
2833130561Sobrien
2834130561Sobrienstruct bfd_section *
2835130561Sobrien_bfd_elf_tls_setup (bfd *obfd, struct bfd_link_info *info)
2836130561Sobrien{
2837130561Sobrien  struct bfd_section *sec, *tls;
2838130561Sobrien  unsigned int align = 0;
2839130561Sobrien
2840130561Sobrien  for (sec = obfd->sections; sec != NULL; sec = sec->next)
2841130561Sobrien    if ((sec->flags & SEC_THREAD_LOCAL) != 0)
2842130561Sobrien      break;
2843130561Sobrien  tls = sec;
2844130561Sobrien
2845130561Sobrien  for (; sec != NULL && (sec->flags & SEC_THREAD_LOCAL) != 0; sec = sec->next)
2846130561Sobrien    if (sec->alignment_power > align)
2847130561Sobrien      align = sec->alignment_power;
2848130561Sobrien
2849130561Sobrien  elf_hash_table (info)->tls_sec = tls;
2850130561Sobrien
2851130561Sobrien  /* Ensure the alignment of the first section is the largest alignment,
2852130561Sobrien     so that the tls segment starts aligned.  */
2853130561Sobrien  if (tls != NULL)
2854130561Sobrien    tls->alignment_power = align;
2855130561Sobrien
2856130561Sobrien  return tls;
2857130561Sobrien}
2858130561Sobrien
2859130561Sobrien/* Return TRUE iff this is a non-common, definition of a non-function symbol.  */
2860130561Sobrienstatic bfd_boolean
2861130561Sobrienis_global_data_symbol_definition (bfd *abfd ATTRIBUTE_UNUSED,
2862130561Sobrien				  Elf_Internal_Sym *sym)
2863130561Sobrien{
2864218822Sdim  const struct elf_backend_data *bed;
2865218822Sdim
2866130561Sobrien  /* Local symbols do not count, but target specific ones might.  */
2867130561Sobrien  if (ELF_ST_BIND (sym->st_info) != STB_GLOBAL
2868130561Sobrien      && ELF_ST_BIND (sym->st_info) < STB_LOOS)
2869130561Sobrien    return FALSE;
2870130561Sobrien
2871218822Sdim  bed = get_elf_backend_data (abfd);
2872130561Sobrien  /* Function symbols do not count.  */
2873218822Sdim  if (bed->is_function_type (ELF_ST_TYPE (sym->st_info)))
2874130561Sobrien    return FALSE;
2875130561Sobrien
2876130561Sobrien  /* If the section is undefined, then so is the symbol.  */
2877130561Sobrien  if (sym->st_shndx == SHN_UNDEF)
2878130561Sobrien    return FALSE;
2879130561Sobrien
2880130561Sobrien  /* If the symbol is defined in the common section, then
2881130561Sobrien     it is a common definition and so does not count.  */
2882218822Sdim  if (bed->common_definition (sym))
2883130561Sobrien    return FALSE;
2884130561Sobrien
2885130561Sobrien  /* If the symbol is in a target specific section then we
2886130561Sobrien     must rely upon the backend to tell us what it is.  */
2887130561Sobrien  if (sym->st_shndx >= SHN_LORESERVE && sym->st_shndx < SHN_ABS)
2888130561Sobrien    /* FIXME - this function is not coded yet:
2889130561Sobrien
2890130561Sobrien       return _bfd_is_global_symbol_definition (abfd, sym);
2891130561Sobrien
2892130561Sobrien       Instead for now assume that the definition is not global,
2893130561Sobrien       Even if this is wrong, at least the linker will behave
2894130561Sobrien       in the same way that it used to do.  */
2895130561Sobrien    return FALSE;
2896130561Sobrien
2897130561Sobrien  return TRUE;
2898130561Sobrien}
2899130561Sobrien
2900130561Sobrien/* Search the symbol table of the archive element of the archive ABFD
2901130561Sobrien   whose archive map contains a mention of SYMDEF, and determine if
2902130561Sobrien   the symbol is defined in this element.  */
2903130561Sobrienstatic bfd_boolean
2904130561Sobrienelf_link_is_defined_archive_symbol (bfd * abfd, carsym * symdef)
2905130561Sobrien{
2906130561Sobrien  Elf_Internal_Shdr * hdr;
2907130561Sobrien  bfd_size_type symcount;
2908130561Sobrien  bfd_size_type extsymcount;
2909130561Sobrien  bfd_size_type extsymoff;
2910130561Sobrien  Elf_Internal_Sym *isymbuf;
2911130561Sobrien  Elf_Internal_Sym *isym;
2912130561Sobrien  Elf_Internal_Sym *isymend;
2913130561Sobrien  bfd_boolean result;
2914130561Sobrien
2915130561Sobrien  abfd = _bfd_get_elt_at_filepos (abfd, symdef->file_offset);
2916130561Sobrien  if (abfd == NULL)
2917130561Sobrien    return FALSE;
2918130561Sobrien
2919130561Sobrien  if (! bfd_check_format (abfd, bfd_object))
2920130561Sobrien    return FALSE;
2921130561Sobrien
2922130561Sobrien  /* If we have already included the element containing this symbol in the
2923130561Sobrien     link then we do not need to include it again.  Just claim that any symbol
2924130561Sobrien     it contains is not a definition, so that our caller will not decide to
2925130561Sobrien     (re)include this element.  */
2926130561Sobrien  if (abfd->archive_pass)
2927130561Sobrien    return FALSE;
2928130561Sobrien
2929130561Sobrien  /* Select the appropriate symbol table.  */
2930130561Sobrien  if ((abfd->flags & DYNAMIC) == 0 || elf_dynsymtab (abfd) == 0)
2931130561Sobrien    hdr = &elf_tdata (abfd)->symtab_hdr;
2932130561Sobrien  else
2933130561Sobrien    hdr = &elf_tdata (abfd)->dynsymtab_hdr;
2934130561Sobrien
2935130561Sobrien  symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym;
2936130561Sobrien
2937130561Sobrien  /* The sh_info field of the symtab header tells us where the
2938130561Sobrien     external symbols start.  We don't care about the local symbols.  */
2939130561Sobrien  if (elf_bad_symtab (abfd))
2940130561Sobrien    {
2941130561Sobrien      extsymcount = symcount;
2942130561Sobrien      extsymoff = 0;
2943130561Sobrien    }
2944130561Sobrien  else
2945130561Sobrien    {
2946130561Sobrien      extsymcount = symcount - hdr->sh_info;
2947130561Sobrien      extsymoff = hdr->sh_info;
2948130561Sobrien    }
2949130561Sobrien
2950130561Sobrien  if (extsymcount == 0)
2951130561Sobrien    return FALSE;
2952130561Sobrien
2953130561Sobrien  /* Read in the symbol table.  */
2954130561Sobrien  isymbuf = bfd_elf_get_elf_syms (abfd, hdr, extsymcount, extsymoff,
2955130561Sobrien				  NULL, NULL, NULL);
2956130561Sobrien  if (isymbuf == NULL)
2957130561Sobrien    return FALSE;
2958130561Sobrien
2959130561Sobrien  /* Scan the symbol table looking for SYMDEF.  */
2960130561Sobrien  result = FALSE;
2961130561Sobrien  for (isym = isymbuf, isymend = isymbuf + extsymcount; isym < isymend; isym++)
2962130561Sobrien    {
2963130561Sobrien      const char *name;
2964130561Sobrien
2965130561Sobrien      name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
2966130561Sobrien					      isym->st_name);
2967130561Sobrien      if (name == NULL)
2968130561Sobrien	break;
2969130561Sobrien
2970130561Sobrien      if (strcmp (name, symdef->name) == 0)
2971130561Sobrien	{
2972130561Sobrien	  result = is_global_data_symbol_definition (abfd, isym);
2973130561Sobrien	  break;
2974130561Sobrien	}
2975130561Sobrien    }
2976130561Sobrien
2977130561Sobrien  free (isymbuf);
2978130561Sobrien
2979130561Sobrien  return result;
2980130561Sobrien}
2981130561Sobrien
2982130561Sobrien/* Add an entry to the .dynamic table.  */
2983130561Sobrien
2984130561Sobrienbfd_boolean
2985130561Sobrien_bfd_elf_add_dynamic_entry (struct bfd_link_info *info,
2986130561Sobrien			    bfd_vma tag,
2987130561Sobrien			    bfd_vma val)
2988130561Sobrien{
2989130561Sobrien  struct elf_link_hash_table *hash_table;
2990130561Sobrien  const struct elf_backend_data *bed;
2991130561Sobrien  asection *s;
2992130561Sobrien  bfd_size_type newsize;
2993130561Sobrien  bfd_byte *newcontents;
2994130561Sobrien  Elf_Internal_Dyn dyn;
2995130561Sobrien
2996130561Sobrien  hash_table = elf_hash_table (info);
2997130561Sobrien  if (! is_elf_hash_table (hash_table))
2998130561Sobrien    return FALSE;
2999130561Sobrien
3000130561Sobrien  bed = get_elf_backend_data (hash_table->dynobj);
3001130561Sobrien  s = bfd_get_section_by_name (hash_table->dynobj, ".dynamic");
3002130561Sobrien  BFD_ASSERT (s != NULL);
3003130561Sobrien
3004218822Sdim  newsize = s->size + bed->s->sizeof_dyn;
3005130561Sobrien  newcontents = bfd_realloc (s->contents, newsize);
3006130561Sobrien  if (newcontents == NULL)
3007130561Sobrien    return FALSE;
3008130561Sobrien
3009130561Sobrien  dyn.d_tag = tag;
3010130561Sobrien  dyn.d_un.d_val = val;
3011218822Sdim  bed->s->swap_dyn_out (hash_table->dynobj, &dyn, newcontents + s->size);
3012130561Sobrien
3013218822Sdim  s->size = newsize;
3014130561Sobrien  s->contents = newcontents;
3015130561Sobrien
3016130561Sobrien  return TRUE;
3017130561Sobrien}
3018130561Sobrien
3019130561Sobrien/* Add a DT_NEEDED entry for this dynamic object if DO_IT is true,
3020130561Sobrien   otherwise just check whether one already exists.  Returns -1 on error,
3021130561Sobrien   1 if a DT_NEEDED tag already exists, and 0 on success.  */
3022130561Sobrien
3023130561Sobrienstatic int
3024218822Sdimelf_add_dt_needed_tag (bfd *abfd,
3025218822Sdim		       struct bfd_link_info *info,
3026130561Sobrien		       const char *soname,
3027130561Sobrien		       bfd_boolean do_it)
3028130561Sobrien{
3029130561Sobrien  struct elf_link_hash_table *hash_table;
3030130561Sobrien  bfd_size_type oldsize;
3031130561Sobrien  bfd_size_type strindex;
3032130561Sobrien
3033218822Sdim  if (!_bfd_elf_link_create_dynstrtab (abfd, info))
3034218822Sdim    return -1;
3035218822Sdim
3036130561Sobrien  hash_table = elf_hash_table (info);
3037130561Sobrien  oldsize = _bfd_elf_strtab_size (hash_table->dynstr);
3038130561Sobrien  strindex = _bfd_elf_strtab_add (hash_table->dynstr, soname, FALSE);
3039130561Sobrien  if (strindex == (bfd_size_type) -1)
3040130561Sobrien    return -1;
3041130561Sobrien
3042130561Sobrien  if (oldsize == _bfd_elf_strtab_size (hash_table->dynstr))
3043130561Sobrien    {
3044130561Sobrien      asection *sdyn;
3045130561Sobrien      const struct elf_backend_data *bed;
3046130561Sobrien      bfd_byte *extdyn;
3047130561Sobrien
3048130561Sobrien      bed = get_elf_backend_data (hash_table->dynobj);
3049130561Sobrien      sdyn = bfd_get_section_by_name (hash_table->dynobj, ".dynamic");
3050218822Sdim      if (sdyn != NULL)
3051218822Sdim	for (extdyn = sdyn->contents;
3052218822Sdim	     extdyn < sdyn->contents + sdyn->size;
3053218822Sdim	     extdyn += bed->s->sizeof_dyn)
3054218822Sdim	  {
3055218822Sdim	    Elf_Internal_Dyn dyn;
3056130561Sobrien
3057218822Sdim	    bed->s->swap_dyn_in (hash_table->dynobj, extdyn, &dyn);
3058218822Sdim	    if (dyn.d_tag == DT_NEEDED
3059218822Sdim		&& dyn.d_un.d_val == strindex)
3060218822Sdim	      {
3061218822Sdim		_bfd_elf_strtab_delref (hash_table->dynstr, strindex);
3062218822Sdim		return 1;
3063218822Sdim	      }
3064218822Sdim	  }
3065130561Sobrien    }
3066130561Sobrien
3067130561Sobrien  if (do_it)
3068130561Sobrien    {
3069218822Sdim      if (!_bfd_elf_link_create_dynamic_sections (hash_table->dynobj, info))
3070218822Sdim	return -1;
3071218822Sdim
3072130561Sobrien      if (!_bfd_elf_add_dynamic_entry (info, DT_NEEDED, strindex))
3073130561Sobrien	return -1;
3074130561Sobrien    }
3075130561Sobrien  else
3076130561Sobrien    /* We were just checking for existence of the tag.  */
3077130561Sobrien    _bfd_elf_strtab_delref (hash_table->dynstr, strindex);
3078130561Sobrien
3079130561Sobrien  return 0;
3080130561Sobrien}
3081130561Sobrien
3082130561Sobrien/* Sort symbol by value and section.  */
3083130561Sobrienstatic int
3084130561Sobrienelf_sort_symbol (const void *arg1, const void *arg2)
3085130561Sobrien{
3086130561Sobrien  const struct elf_link_hash_entry *h1;
3087130561Sobrien  const struct elf_link_hash_entry *h2;
3088130561Sobrien  bfd_signed_vma vdiff;
3089130561Sobrien
3090130561Sobrien  h1 = *(const struct elf_link_hash_entry **) arg1;
3091130561Sobrien  h2 = *(const struct elf_link_hash_entry **) arg2;
3092130561Sobrien  vdiff = h1->root.u.def.value - h2->root.u.def.value;
3093130561Sobrien  if (vdiff != 0)
3094130561Sobrien    return vdiff > 0 ? 1 : -1;
3095130561Sobrien  else
3096130561Sobrien    {
3097218822Sdim      long sdiff = h1->root.u.def.section->id - h2->root.u.def.section->id;
3098130561Sobrien      if (sdiff != 0)
3099130561Sobrien	return sdiff > 0 ? 1 : -1;
3100130561Sobrien    }
3101130561Sobrien  return 0;
3102130561Sobrien}
3103130561Sobrien
3104130561Sobrien/* This function is used to adjust offsets into .dynstr for
3105130561Sobrien   dynamic symbols.  This is called via elf_link_hash_traverse.  */
3106130561Sobrien
3107130561Sobrienstatic bfd_boolean
3108130561Sobrienelf_adjust_dynstr_offsets (struct elf_link_hash_entry *h, void *data)
3109130561Sobrien{
3110130561Sobrien  struct elf_strtab_hash *dynstr = data;
3111130561Sobrien
3112130561Sobrien  if (h->root.type == bfd_link_hash_warning)
3113130561Sobrien    h = (struct elf_link_hash_entry *) h->root.u.i.link;
3114130561Sobrien
3115130561Sobrien  if (h->dynindx != -1)
3116130561Sobrien    h->dynstr_index = _bfd_elf_strtab_offset (dynstr, h->dynstr_index);
3117130561Sobrien  return TRUE;
3118130561Sobrien}
3119130561Sobrien
3120130561Sobrien/* Assign string offsets in .dynstr, update all structures referencing
3121130561Sobrien   them.  */
3122130561Sobrien
3123130561Sobrienstatic bfd_boolean
3124130561Sobrienelf_finalize_dynstr (bfd *output_bfd, struct bfd_link_info *info)
3125130561Sobrien{
3126130561Sobrien  struct elf_link_hash_table *hash_table = elf_hash_table (info);
3127130561Sobrien  struct elf_link_local_dynamic_entry *entry;
3128130561Sobrien  struct elf_strtab_hash *dynstr = hash_table->dynstr;
3129130561Sobrien  bfd *dynobj = hash_table->dynobj;
3130130561Sobrien  asection *sdyn;
3131130561Sobrien  bfd_size_type size;
3132130561Sobrien  const struct elf_backend_data *bed;
3133130561Sobrien  bfd_byte *extdyn;
3134130561Sobrien
3135130561Sobrien  _bfd_elf_strtab_finalize (dynstr);
3136130561Sobrien  size = _bfd_elf_strtab_size (dynstr);
3137130561Sobrien
3138130561Sobrien  bed = get_elf_backend_data (dynobj);
3139130561Sobrien  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
3140130561Sobrien  BFD_ASSERT (sdyn != NULL);
3141130561Sobrien
3142130561Sobrien  /* Update all .dynamic entries referencing .dynstr strings.  */
3143130561Sobrien  for (extdyn = sdyn->contents;
3144218822Sdim       extdyn < sdyn->contents + sdyn->size;
3145130561Sobrien       extdyn += bed->s->sizeof_dyn)
3146130561Sobrien    {
3147130561Sobrien      Elf_Internal_Dyn dyn;
3148130561Sobrien
3149130561Sobrien      bed->s->swap_dyn_in (dynobj, extdyn, &dyn);
3150130561Sobrien      switch (dyn.d_tag)
3151130561Sobrien	{
3152130561Sobrien	case DT_STRSZ:
3153130561Sobrien	  dyn.d_un.d_val = size;
3154130561Sobrien	  break;
3155130561Sobrien	case DT_NEEDED:
3156130561Sobrien	case DT_SONAME:
3157130561Sobrien	case DT_RPATH:
3158130561Sobrien	case DT_RUNPATH:
3159130561Sobrien	case DT_FILTER:
3160130561Sobrien	case DT_AUXILIARY:
3161130561Sobrien	  dyn.d_un.d_val = _bfd_elf_strtab_offset (dynstr, dyn.d_un.d_val);
3162130561Sobrien	  break;
3163130561Sobrien	default:
3164130561Sobrien	  continue;
3165130561Sobrien	}
3166130561Sobrien      bed->s->swap_dyn_out (dynobj, &dyn, extdyn);
3167130561Sobrien    }
3168130561Sobrien
3169130561Sobrien  /* Now update local dynamic symbols.  */
3170130561Sobrien  for (entry = hash_table->dynlocal; entry ; entry = entry->next)
3171130561Sobrien    entry->isym.st_name = _bfd_elf_strtab_offset (dynstr,
3172130561Sobrien						  entry->isym.st_name);
3173130561Sobrien
3174130561Sobrien  /* And the rest of dynamic symbols.  */
3175130561Sobrien  elf_link_hash_traverse (hash_table, elf_adjust_dynstr_offsets, dynstr);
3176130561Sobrien
3177130561Sobrien  /* Adjust version definitions.  */
3178130561Sobrien  if (elf_tdata (output_bfd)->cverdefs)
3179130561Sobrien    {
318033965Sjdp      asection *s;
3181130561Sobrien      bfd_byte *p;
3182130561Sobrien      bfd_size_type i;
3183130561Sobrien      Elf_Internal_Verdef def;
3184130561Sobrien      Elf_Internal_Verdaux defaux;
318533965Sjdp
3186130561Sobrien      s = bfd_get_section_by_name (dynobj, ".gnu.version_d");
3187130561Sobrien      p = s->contents;
3188130561Sobrien      do
3189130561Sobrien	{
3190130561Sobrien	  _bfd_elf_swap_verdef_in (output_bfd, (Elf_External_Verdef *) p,
3191130561Sobrien				   &def);
3192130561Sobrien	  p += sizeof (Elf_External_Verdef);
3193218822Sdim	  if (def.vd_aux != sizeof (Elf_External_Verdef))
3194218822Sdim	    continue;
3195130561Sobrien	  for (i = 0; i < def.vd_cnt; ++i)
3196130561Sobrien	    {
3197130561Sobrien	      _bfd_elf_swap_verdaux_in (output_bfd,
3198130561Sobrien					(Elf_External_Verdaux *) p, &defaux);
3199130561Sobrien	      defaux.vda_name = _bfd_elf_strtab_offset (dynstr,
3200130561Sobrien							defaux.vda_name);
3201130561Sobrien	      _bfd_elf_swap_verdaux_out (output_bfd,
3202130561Sobrien					 &defaux, (Elf_External_Verdaux *) p);
3203130561Sobrien	      p += sizeof (Elf_External_Verdaux);
3204130561Sobrien	    }
3205130561Sobrien	}
3206130561Sobrien      while (def.vd_next);
3207130561Sobrien    }
320833965Sjdp
3209130561Sobrien  /* Adjust version references.  */
3210130561Sobrien  if (elf_tdata (output_bfd)->verref)
3211130561Sobrien    {
3212130561Sobrien      asection *s;
3213130561Sobrien      bfd_byte *p;
3214130561Sobrien      bfd_size_type i;
3215130561Sobrien      Elf_Internal_Verneed need;
3216130561Sobrien      Elf_Internal_Vernaux needaux;
321733965Sjdp
3218130561Sobrien      s = bfd_get_section_by_name (dynobj, ".gnu.version_r");
3219130561Sobrien      p = s->contents;
3220130561Sobrien      do
322133965Sjdp	{
3222130561Sobrien	  _bfd_elf_swap_verneed_in (output_bfd, (Elf_External_Verneed *) p,
3223130561Sobrien				    &need);
3224130561Sobrien	  need.vn_file = _bfd_elf_strtab_offset (dynstr, need.vn_file);
3225130561Sobrien	  _bfd_elf_swap_verneed_out (output_bfd, &need,
3226130561Sobrien				     (Elf_External_Verneed *) p);
3227130561Sobrien	  p += sizeof (Elf_External_Verneed);
3228130561Sobrien	  for (i = 0; i < need.vn_cnt; ++i)
3229130561Sobrien	    {
3230130561Sobrien	      _bfd_elf_swap_vernaux_in (output_bfd,
3231130561Sobrien					(Elf_External_Vernaux *) p, &needaux);
3232130561Sobrien	      needaux.vna_name = _bfd_elf_strtab_offset (dynstr,
3233130561Sobrien							 needaux.vna_name);
3234130561Sobrien	      _bfd_elf_swap_vernaux_out (output_bfd,
3235130561Sobrien					 &needaux,
3236130561Sobrien					 (Elf_External_Vernaux *) p);
3237130561Sobrien	      p += sizeof (Elf_External_Vernaux);
3238130561Sobrien	    }
3239130561Sobrien	}
3240130561Sobrien      while (need.vn_next);
3241130561Sobrien    }
324233965Sjdp
3243130561Sobrien  return TRUE;
3244130561Sobrien}
3245130561Sobrien
3246218822Sdim/* Return TRUE iff relocations for INPUT are compatible with OUTPUT.
3247218822Sdim   The default is to only match when the INPUT and OUTPUT are exactly
3248218822Sdim   the same target.  */
3249218822Sdim
3250218822Sdimbfd_boolean
3251218822Sdim_bfd_elf_default_relocs_compatible (const bfd_target *input,
3252218822Sdim				    const bfd_target *output)
3253218822Sdim{
3254218822Sdim  return input == output;
3255218822Sdim}
3256218822Sdim
3257218822Sdim/* Return TRUE iff relocations for INPUT are compatible with OUTPUT.
3258218822Sdim   This version is used when different targets for the same architecture
3259218822Sdim   are virtually identical.  */
3260218822Sdim
3261218822Sdimbfd_boolean
3262218822Sdim_bfd_elf_relocs_compatible (const bfd_target *input,
3263218822Sdim			    const bfd_target *output)
3264218822Sdim{
3265218822Sdim  const struct elf_backend_data *obed, *ibed;
3266218822Sdim
3267218822Sdim  if (input == output)
3268218822Sdim    return TRUE;
3269218822Sdim
3270218822Sdim  ibed = xvec_get_elf_backend_data (input);
3271218822Sdim  obed = xvec_get_elf_backend_data (output);
3272218822Sdim
3273218822Sdim  if (ibed->arch != obed->arch)
3274218822Sdim    return FALSE;
3275218822Sdim
3276218822Sdim  /* If both backends are using this function, deem them compatible.  */
3277218822Sdim  return ibed->relocs_compatible == obed->relocs_compatible;
3278218822Sdim}
3279218822Sdim
3280130561Sobrien/* Add symbols from an ELF object file to the linker hash table.  */
328133965Sjdp
3282130561Sobrienstatic bfd_boolean
3283130561Sobrienelf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
3284130561Sobrien{
3285130561Sobrien  Elf_Internal_Shdr *hdr;
3286130561Sobrien  bfd_size_type symcount;
3287130561Sobrien  bfd_size_type extsymcount;
3288130561Sobrien  bfd_size_type extsymoff;
3289130561Sobrien  struct elf_link_hash_entry **sym_hash;
3290130561Sobrien  bfd_boolean dynamic;
3291130561Sobrien  Elf_External_Versym *extversym = NULL;
3292130561Sobrien  Elf_External_Versym *ever;
3293130561Sobrien  struct elf_link_hash_entry *weaks;
3294130561Sobrien  struct elf_link_hash_entry **nondeflt_vers = NULL;
3295130561Sobrien  bfd_size_type nondeflt_vers_cnt = 0;
3296130561Sobrien  Elf_Internal_Sym *isymbuf = NULL;
3297130561Sobrien  Elf_Internal_Sym *isym;
3298130561Sobrien  Elf_Internal_Sym *isymend;
3299130561Sobrien  const struct elf_backend_data *bed;
3300130561Sobrien  bfd_boolean add_needed;
3301218822Sdim  struct elf_link_hash_table *htab;
3302130561Sobrien  bfd_size_type amt;
3303218822Sdim  void *alloc_mark = NULL;
3304218822Sdim  struct bfd_hash_entry **old_table = NULL;
3305218822Sdim  unsigned int old_size = 0;
3306218822Sdim  unsigned int old_count = 0;
3307218822Sdim  void *old_tab = NULL;
3308218822Sdim  void *old_hash;
3309218822Sdim  void *old_ent;
3310218822Sdim  struct bfd_link_hash_entry *old_undefs = NULL;
3311218822Sdim  struct bfd_link_hash_entry *old_undefs_tail = NULL;
3312218822Sdim  long old_dynsymcount = 0;
3313218822Sdim  size_t tabsize = 0;
3314218822Sdim  size_t hashsize = 0;
3315130561Sobrien
3316218822Sdim  htab = elf_hash_table (info);
3317130561Sobrien  bed = get_elf_backend_data (abfd);
3318130561Sobrien
3319130561Sobrien  if ((abfd->flags & DYNAMIC) == 0)
3320130561Sobrien    dynamic = FALSE;
3321130561Sobrien  else
3322130561Sobrien    {
3323130561Sobrien      dynamic = TRUE;
3324130561Sobrien
3325130561Sobrien      /* You can't use -r against a dynamic object.  Also, there's no
3326130561Sobrien	 hope of using a dynamic object which does not exactly match
3327130561Sobrien	 the format of the output file.  */
3328130561Sobrien      if (info->relocatable
3329218822Sdim	  || !is_elf_hash_table (htab)
3330218822Sdim	  || htab->root.creator != abfd->xvec)
3331130561Sobrien	{
3332218822Sdim	  if (info->relocatable)
3333218822Sdim	    bfd_set_error (bfd_error_invalid_operation);
3334218822Sdim	  else
3335218822Sdim	    bfd_set_error (bfd_error_wrong_format);
3336130561Sobrien	  goto error_return;
333733965Sjdp	}
3338130561Sobrien    }
333933965Sjdp
3340130561Sobrien  /* As a GNU extension, any input sections which are named
3341130561Sobrien     .gnu.warning.SYMBOL are treated as warning symbols for the given
3342130561Sobrien     symbol.  This differs from .gnu.warning sections, which generate
3343130561Sobrien     warnings when they are included in an output file.  */
3344130561Sobrien  if (info->executable)
3345130561Sobrien    {
3346130561Sobrien      asection *s;
334733965Sjdp
3348130561Sobrien      for (s = abfd->sections; s != NULL; s = s->next)
334933965Sjdp	{
3350130561Sobrien	  const char *name;
3351130561Sobrien
3352130561Sobrien	  name = bfd_get_section_name (abfd, s);
3353218822Sdim	  if (CONST_STRNEQ (name, ".gnu.warning."))
335433965Sjdp	    {
3355130561Sobrien	      char *msg;
3356130561Sobrien	      bfd_size_type sz;
335733965Sjdp
3358130561Sobrien	      name += sizeof ".gnu.warning." - 1;
3359130561Sobrien
3360130561Sobrien	      /* If this is a shared object, then look up the symbol
3361130561Sobrien		 in the hash table.  If it is there, and it is already
3362130561Sobrien		 been defined, then we will not be using the entry
3363130561Sobrien		 from this shared object, so we don't need to warn.
3364130561Sobrien		 FIXME: If we see the definition in a regular object
3365130561Sobrien		 later on, we will warn, but we shouldn't.  The only
3366130561Sobrien		 fix is to keep track of what warnings we are supposed
3367130561Sobrien		 to emit, and then handle them all at the end of the
3368130561Sobrien		 link.  */
3369130561Sobrien	      if (dynamic)
3370130561Sobrien		{
3371130561Sobrien		  struct elf_link_hash_entry *h;
3372130561Sobrien
3373218822Sdim		  h = elf_link_hash_lookup (htab, name, FALSE, FALSE, TRUE);
3374130561Sobrien
3375130561Sobrien		  /* FIXME: What about bfd_link_hash_common?  */
3376130561Sobrien		  if (h != NULL
3377130561Sobrien		      && (h->root.type == bfd_link_hash_defined
3378130561Sobrien			  || h->root.type == bfd_link_hash_defweak))
3379130561Sobrien		    {
3380130561Sobrien		      /* We don't want to issue this warning.  Clobber
3381130561Sobrien			 the section size so that the warning does not
3382130561Sobrien			 get copied into the output file.  */
3383218822Sdim		      s->size = 0;
3384130561Sobrien		      continue;
3385130561Sobrien		    }
3386130561Sobrien		}
3387130561Sobrien
3388218822Sdim	      sz = s->size;
3389218822Sdim	      msg = bfd_alloc (abfd, sz + 1);
3390130561Sobrien	      if (msg == NULL)
3391130561Sobrien		goto error_return;
3392130561Sobrien
3393218822Sdim	      if (! bfd_get_section_contents (abfd, s, msg, 0, sz))
3394130561Sobrien		goto error_return;
3395130561Sobrien
3396218822Sdim	      msg[sz] = '\0';
3397130561Sobrien
3398130561Sobrien	      if (! (_bfd_generic_link_add_one_symbol
3399130561Sobrien		     (info, abfd, name, BSF_WARNING, s, 0, msg,
3400218822Sdim		      FALSE, bed->collect, NULL)))
3401130561Sobrien		goto error_return;
3402130561Sobrien
3403130561Sobrien	      if (! info->relocatable)
3404130561Sobrien		{
3405130561Sobrien		  /* Clobber the section size so that the warning does
3406130561Sobrien		     not get copied into the output file.  */
3407218822Sdim		  s->size = 0;
3408218822Sdim
3409218822Sdim		  /* Also set SEC_EXCLUDE, so that symbols defined in
3410218822Sdim		     the warning section don't get copied to the output.  */
3411218822Sdim		  s->flags |= SEC_EXCLUDE;
3412130561Sobrien		}
341333965Sjdp	    }
341433965Sjdp	}
3415130561Sobrien    }
341633965Sjdp
3417130561Sobrien  add_needed = TRUE;
3418130561Sobrien  if (! dynamic)
3419130561Sobrien    {
3420130561Sobrien      /* If we are creating a shared library, create all the dynamic
3421130561Sobrien	 sections immediately.  We need to attach them to something,
3422130561Sobrien	 so we attach them to this BFD, provided it is the right
3423130561Sobrien	 format.  FIXME: If there are no input BFD's of the same
3424130561Sobrien	 format as the output, we can't make a shared library.  */
3425130561Sobrien      if (info->shared
3426218822Sdim	  && is_elf_hash_table (htab)
3427218822Sdim	  && htab->root.creator == abfd->xvec
3428218822Sdim	  && !htab->dynamic_sections_created)
3429130561Sobrien	{
3430130561Sobrien	  if (! _bfd_elf_link_create_dynamic_sections (abfd, info))
3431130561Sobrien	    goto error_return;
3432130561Sobrien	}
3433130561Sobrien    }
3434218822Sdim  else if (!is_elf_hash_table (htab))
3435130561Sobrien    goto error_return;
3436130561Sobrien  else
3437130561Sobrien    {
3438130561Sobrien      asection *s;
3439130561Sobrien      const char *soname = NULL;
3440130561Sobrien      struct bfd_link_needed_list *rpath = NULL, *runpath = NULL;
3441130561Sobrien      int ret;
344233965Sjdp
3443130561Sobrien      /* ld --just-symbols and dynamic objects don't mix very well.
3444218822Sdim	 ld shouldn't allow it.  */
3445130561Sobrien      if ((s = abfd->sections) != NULL
3446130561Sobrien	  && s->sec_info_type == ELF_INFO_TYPE_JUST_SYMS)
3447218822Sdim	abort ();
3448130561Sobrien
3449130561Sobrien      /* If this dynamic lib was specified on the command line with
3450130561Sobrien	 --as-needed in effect, then we don't want to add a DT_NEEDED
3451130561Sobrien	 tag unless the lib is actually used.  Similary for libs brought
3452218822Sdim	 in by another lib's DT_NEEDED.  When --no-add-needed is used
3453218822Sdim	 on a dynamic lib, we don't want to add a DT_NEEDED entry for
3454218822Sdim	 any dynamic library in DT_NEEDED tags in the dynamic lib at
3455218822Sdim	 all.  */
3456218822Sdim      add_needed = (elf_dyn_lib_class (abfd)
3457218822Sdim		    & (DYN_AS_NEEDED | DYN_DT_NEEDED
3458218822Sdim		       | DYN_NO_NEEDED)) == 0;
3459130561Sobrien
3460130561Sobrien      s = bfd_get_section_by_name (abfd, ".dynamic");
3461130561Sobrien      if (s != NULL)
346233965Sjdp	{
3463130561Sobrien	  bfd_byte *dynbuf;
3464130561Sobrien	  bfd_byte *extdyn;
3465130561Sobrien	  int elfsec;
3466130561Sobrien	  unsigned long shlink;
3467130561Sobrien
3468218822Sdim	  if (!bfd_malloc_and_get_section (abfd, s, &dynbuf))
3469130561Sobrien	    goto error_free_dyn;
3470130561Sobrien
3471130561Sobrien	  elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
3472130561Sobrien	  if (elfsec == -1)
3473130561Sobrien	    goto error_free_dyn;
3474130561Sobrien	  shlink = elf_elfsections (abfd)[elfsec]->sh_link;
3475130561Sobrien
3476130561Sobrien	  for (extdyn = dynbuf;
3477218822Sdim	       extdyn < dynbuf + s->size;
3478130561Sobrien	       extdyn += bed->s->sizeof_dyn)
3479130561Sobrien	    {
3480130561Sobrien	      Elf_Internal_Dyn dyn;
3481130561Sobrien
3482130561Sobrien	      bed->s->swap_dyn_in (abfd, extdyn, &dyn);
3483130561Sobrien	      if (dyn.d_tag == DT_SONAME)
3484130561Sobrien		{
3485130561Sobrien		  unsigned int tagv = dyn.d_un.d_val;
3486130561Sobrien		  soname = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
3487130561Sobrien		  if (soname == NULL)
3488130561Sobrien		    goto error_free_dyn;
3489130561Sobrien		}
3490130561Sobrien	      if (dyn.d_tag == DT_NEEDED)
3491130561Sobrien		{
3492130561Sobrien		  struct bfd_link_needed_list *n, **pn;
3493130561Sobrien		  char *fnm, *anm;
3494130561Sobrien		  unsigned int tagv = dyn.d_un.d_val;
3495130561Sobrien
3496130561Sobrien		  amt = sizeof (struct bfd_link_needed_list);
3497130561Sobrien		  n = bfd_alloc (abfd, amt);
3498130561Sobrien		  fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
3499130561Sobrien		  if (n == NULL || fnm == NULL)
3500130561Sobrien		    goto error_free_dyn;
3501130561Sobrien		  amt = strlen (fnm) + 1;
3502130561Sobrien		  anm = bfd_alloc (abfd, amt);
3503130561Sobrien		  if (anm == NULL)
3504130561Sobrien		    goto error_free_dyn;
3505130561Sobrien		  memcpy (anm, fnm, amt);
3506130561Sobrien		  n->name = anm;
3507130561Sobrien		  n->by = abfd;
3508130561Sobrien		  n->next = NULL;
3509218822Sdim		  for (pn = &htab->needed; *pn != NULL; pn = &(*pn)->next)
3510130561Sobrien		    ;
3511130561Sobrien		  *pn = n;
3512130561Sobrien		}
3513130561Sobrien	      if (dyn.d_tag == DT_RUNPATH)
3514130561Sobrien		{
3515130561Sobrien		  struct bfd_link_needed_list *n, **pn;
3516130561Sobrien		  char *fnm, *anm;
3517130561Sobrien		  unsigned int tagv = dyn.d_un.d_val;
3518130561Sobrien
3519130561Sobrien		  amt = sizeof (struct bfd_link_needed_list);
3520130561Sobrien		  n = bfd_alloc (abfd, amt);
3521130561Sobrien		  fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
3522130561Sobrien		  if (n == NULL || fnm == NULL)
3523130561Sobrien		    goto error_free_dyn;
3524130561Sobrien		  amt = strlen (fnm) + 1;
3525130561Sobrien		  anm = bfd_alloc (abfd, amt);
3526130561Sobrien		  if (anm == NULL)
3527130561Sobrien		    goto error_free_dyn;
3528130561Sobrien		  memcpy (anm, fnm, amt);
3529130561Sobrien		  n->name = anm;
3530130561Sobrien		  n->by = abfd;
3531130561Sobrien		  n->next = NULL;
3532130561Sobrien		  for (pn = & runpath;
3533130561Sobrien		       *pn != NULL;
3534130561Sobrien		       pn = &(*pn)->next)
3535130561Sobrien		    ;
3536130561Sobrien		  *pn = n;
3537130561Sobrien		}
3538130561Sobrien	      /* Ignore DT_RPATH if we have seen DT_RUNPATH.  */
3539130561Sobrien	      if (!runpath && dyn.d_tag == DT_RPATH)
3540130561Sobrien		{
3541130561Sobrien		  struct bfd_link_needed_list *n, **pn;
3542130561Sobrien		  char *fnm, *anm;
3543130561Sobrien		  unsigned int tagv = dyn.d_un.d_val;
3544130561Sobrien
3545130561Sobrien		  amt = sizeof (struct bfd_link_needed_list);
3546130561Sobrien		  n = bfd_alloc (abfd, amt);
3547130561Sobrien		  fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
3548130561Sobrien		  if (n == NULL || fnm == NULL)
3549130561Sobrien		    goto error_free_dyn;
3550130561Sobrien		  amt = strlen (fnm) + 1;
3551130561Sobrien		  anm = bfd_alloc (abfd, amt);
3552130561Sobrien		  if (anm == NULL)
3553130561Sobrien		    {
3554130561Sobrien		    error_free_dyn:
3555130561Sobrien		      free (dynbuf);
3556130561Sobrien		      goto error_return;
3557130561Sobrien		    }
3558130561Sobrien		  memcpy (anm, fnm, amt);
3559130561Sobrien		  n->name = anm;
3560130561Sobrien		  n->by = abfd;
3561130561Sobrien		  n->next = NULL;
3562130561Sobrien		  for (pn = & rpath;
3563130561Sobrien		       *pn != NULL;
3564130561Sobrien		       pn = &(*pn)->next)
3565130561Sobrien		    ;
3566130561Sobrien		  *pn = n;
3567130561Sobrien		}
3568130561Sobrien	    }
3569130561Sobrien
3570130561Sobrien	  free (dynbuf);
3571130561Sobrien	}
3572130561Sobrien
3573130561Sobrien      /* DT_RUNPATH overrides DT_RPATH.  Do _NOT_ bfd_release, as that
3574130561Sobrien	 frees all more recently bfd_alloc'd blocks as well.  */
3575130561Sobrien      if (runpath)
3576130561Sobrien	rpath = runpath;
3577130561Sobrien
3578130561Sobrien      if (rpath)
3579130561Sobrien	{
3580130561Sobrien	  struct bfd_link_needed_list **pn;
3581218822Sdim	  for (pn = &htab->runpath; *pn != NULL; pn = &(*pn)->next)
3582130561Sobrien	    ;
3583130561Sobrien	  *pn = rpath;
3584130561Sobrien	}
3585130561Sobrien
3586130561Sobrien      /* We do not want to include any of the sections in a dynamic
3587130561Sobrien	 object in the output file.  We hack by simply clobbering the
3588130561Sobrien	 list of sections in the BFD.  This could be handled more
3589130561Sobrien	 cleanly by, say, a new section flag; the existing
3590130561Sobrien	 SEC_NEVER_LOAD flag is not the one we want, because that one
3591130561Sobrien	 still implies that the section takes up space in the output
3592130561Sobrien	 file.  */
3593130561Sobrien      bfd_section_list_clear (abfd);
3594130561Sobrien
3595130561Sobrien      /* Find the name to use in a DT_NEEDED entry that refers to this
3596130561Sobrien	 object.  If the object has a DT_SONAME entry, we use it.
3597130561Sobrien	 Otherwise, if the generic linker stuck something in
3598130561Sobrien	 elf_dt_name, we use that.  Otherwise, we just use the file
3599130561Sobrien	 name.  */
3600130561Sobrien      if (soname == NULL || *soname == '\0')
3601130561Sobrien	{
3602130561Sobrien	  soname = elf_dt_name (abfd);
3603130561Sobrien	  if (soname == NULL || *soname == '\0')
3604130561Sobrien	    soname = bfd_get_filename (abfd);
3605130561Sobrien	}
3606130561Sobrien
3607130561Sobrien      /* Save the SONAME because sometimes the linker emulation code
3608130561Sobrien	 will need to know it.  */
3609130561Sobrien      elf_dt_name (abfd) = soname;
3610130561Sobrien
3611218822Sdim      ret = elf_add_dt_needed_tag (abfd, info, soname, add_needed);
3612130561Sobrien      if (ret < 0)
3613130561Sobrien	goto error_return;
3614130561Sobrien
3615130561Sobrien      /* If we have already included this dynamic object in the
3616130561Sobrien	 link, just ignore it.  There is no reason to include a
3617130561Sobrien	 particular dynamic object more than once.  */
3618130561Sobrien      if (ret > 0)
3619130561Sobrien	return TRUE;
3620130561Sobrien    }
3621130561Sobrien
3622130561Sobrien  /* If this is a dynamic object, we always link against the .dynsym
3623130561Sobrien     symbol table, not the .symtab symbol table.  The dynamic linker
3624130561Sobrien     will only see the .dynsym symbol table, so there is no reason to
3625130561Sobrien     look at .symtab for a dynamic object.  */
3626130561Sobrien
3627130561Sobrien  if (! dynamic || elf_dynsymtab (abfd) == 0)
3628130561Sobrien    hdr = &elf_tdata (abfd)->symtab_hdr;
3629130561Sobrien  else
3630130561Sobrien    hdr = &elf_tdata (abfd)->dynsymtab_hdr;
3631130561Sobrien
3632130561Sobrien  symcount = hdr->sh_size / bed->s->sizeof_sym;
3633130561Sobrien
3634130561Sobrien  /* The sh_info field of the symtab header tells us where the
3635130561Sobrien     external symbols start.  We don't care about the local symbols at
3636130561Sobrien     this point.  */
3637130561Sobrien  if (elf_bad_symtab (abfd))
3638130561Sobrien    {
3639130561Sobrien      extsymcount = symcount;
3640130561Sobrien      extsymoff = 0;
3641130561Sobrien    }
3642130561Sobrien  else
3643130561Sobrien    {
3644130561Sobrien      extsymcount = symcount - hdr->sh_info;
3645130561Sobrien      extsymoff = hdr->sh_info;
3646130561Sobrien    }
3647130561Sobrien
3648130561Sobrien  sym_hash = NULL;
3649130561Sobrien  if (extsymcount != 0)
3650130561Sobrien    {
3651130561Sobrien      isymbuf = bfd_elf_get_elf_syms (abfd, hdr, extsymcount, extsymoff,
3652130561Sobrien				      NULL, NULL, NULL);
3653130561Sobrien      if (isymbuf == NULL)
3654130561Sobrien	goto error_return;
3655130561Sobrien
3656130561Sobrien      /* We store a pointer to the hash table entry for each external
3657130561Sobrien	 symbol.  */
3658130561Sobrien      amt = extsymcount * sizeof (struct elf_link_hash_entry *);
3659130561Sobrien      sym_hash = bfd_alloc (abfd, amt);
3660130561Sobrien      if (sym_hash == NULL)
3661130561Sobrien	goto error_free_sym;
3662130561Sobrien      elf_sym_hashes (abfd) = sym_hash;
3663130561Sobrien    }
3664130561Sobrien
3665130561Sobrien  if (dynamic)
3666130561Sobrien    {
3667130561Sobrien      /* Read in any version definitions.  */
3668218822Sdim      if (!_bfd_elf_slurp_version_tables (abfd,
3669218822Sdim					  info->default_imported_symver))
3670130561Sobrien	goto error_free_sym;
3671130561Sobrien
3672130561Sobrien      /* Read in the symbol versions, but don't bother to convert them
3673130561Sobrien	 to internal format.  */
3674130561Sobrien      if (elf_dynversym (abfd) != 0)
3675130561Sobrien	{
3676130561Sobrien	  Elf_Internal_Shdr *versymhdr;
3677130561Sobrien
3678130561Sobrien	  versymhdr = &elf_tdata (abfd)->dynversym_hdr;
3679130561Sobrien	  extversym = bfd_malloc (versymhdr->sh_size);
3680130561Sobrien	  if (extversym == NULL)
3681130561Sobrien	    goto error_free_sym;
3682130561Sobrien	  amt = versymhdr->sh_size;
3683130561Sobrien	  if (bfd_seek (abfd, versymhdr->sh_offset, SEEK_SET) != 0
3684130561Sobrien	      || bfd_bread (extversym, amt, abfd) != amt)
3685130561Sobrien	    goto error_free_vers;
3686130561Sobrien	}
3687130561Sobrien    }
3688130561Sobrien
3689218822Sdim  /* If we are loading an as-needed shared lib, save the symbol table
3690218822Sdim     state before we start adding symbols.  If the lib turns out
3691218822Sdim     to be unneeded, restore the state.  */
3692218822Sdim  if ((elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0)
3693218822Sdim    {
3694218822Sdim      unsigned int i;
3695218822Sdim      size_t entsize;
3696218822Sdim
3697218822Sdim      for (entsize = 0, i = 0; i < htab->root.table.size; i++)
3698218822Sdim	{
3699218822Sdim	  struct bfd_hash_entry *p;
3700218822Sdim	  struct elf_link_hash_entry *h;
3701218822Sdim
3702218822Sdim	  for (p = htab->root.table.table[i]; p != NULL; p = p->next)
3703218822Sdim	    {
3704218822Sdim	      h = (struct elf_link_hash_entry *) p;
3705218822Sdim	      entsize += htab->root.table.entsize;
3706218822Sdim	      if (h->root.type == bfd_link_hash_warning)
3707218822Sdim		entsize += htab->root.table.entsize;
3708218822Sdim	    }
3709218822Sdim	}
3710218822Sdim
3711218822Sdim      tabsize = htab->root.table.size * sizeof (struct bfd_hash_entry *);
3712218822Sdim      hashsize = extsymcount * sizeof (struct elf_link_hash_entry *);
3713218822Sdim      old_tab = bfd_malloc (tabsize + entsize + hashsize);
3714218822Sdim      if (old_tab == NULL)
3715218822Sdim	goto error_free_vers;
3716218822Sdim
3717218822Sdim      /* Remember the current objalloc pointer, so that all mem for
3718218822Sdim	 symbols added can later be reclaimed.  */
3719218822Sdim      alloc_mark = bfd_hash_allocate (&htab->root.table, 1);
3720218822Sdim      if (alloc_mark == NULL)
3721218822Sdim	goto error_free_vers;
3722218822Sdim
3723218822Sdim      /* Make a special call to the linker "notice" function to
3724218822Sdim	 tell it that we are about to handle an as-needed lib.  */
3725218822Sdim      if (!(*info->callbacks->notice) (info, NULL, abfd, NULL,
3726218822Sdim				       notice_as_needed))
3727218822Sdim	return FALSE;
3728218822Sdim
3729218822Sdim
3730218822Sdim      /* Clone the symbol table and sym hashes.  Remember some
3731218822Sdim	 pointers into the symbol table, and dynamic symbol count.  */
3732218822Sdim      old_hash = (char *) old_tab + tabsize;
3733218822Sdim      old_ent = (char *) old_hash + hashsize;
3734218822Sdim      memcpy (old_tab, htab->root.table.table, tabsize);
3735218822Sdim      memcpy (old_hash, sym_hash, hashsize);
3736218822Sdim      old_undefs = htab->root.undefs;
3737218822Sdim      old_undefs_tail = htab->root.undefs_tail;
3738218822Sdim      old_table = htab->root.table.table;
3739218822Sdim      old_size = htab->root.table.size;
3740218822Sdim      old_count = htab->root.table.count;
3741218822Sdim      old_dynsymcount = htab->dynsymcount;
3742218822Sdim
3743218822Sdim      for (i = 0; i < htab->root.table.size; i++)
3744218822Sdim	{
3745218822Sdim	  struct bfd_hash_entry *p;
3746218822Sdim	  struct elf_link_hash_entry *h;
3747218822Sdim
3748218822Sdim	  for (p = htab->root.table.table[i]; p != NULL; p = p->next)
3749218822Sdim	    {
3750218822Sdim	      memcpy (old_ent, p, htab->root.table.entsize);
3751218822Sdim	      old_ent = (char *) old_ent + htab->root.table.entsize;
3752218822Sdim	      h = (struct elf_link_hash_entry *) p;
3753218822Sdim	      if (h->root.type == bfd_link_hash_warning)
3754218822Sdim		{
3755218822Sdim		  memcpy (old_ent, h->root.u.i.link, htab->root.table.entsize);
3756218822Sdim		  old_ent = (char *) old_ent + htab->root.table.entsize;
3757218822Sdim		}
3758218822Sdim	    }
3759218822Sdim	}
3760218822Sdim    }
3761218822Sdim
3762130561Sobrien  weaks = NULL;
3763130561Sobrien  ever = extversym != NULL ? extversym + extsymoff : NULL;
3764130561Sobrien  for (isym = isymbuf, isymend = isymbuf + extsymcount;
3765130561Sobrien       isym < isymend;
3766130561Sobrien       isym++, sym_hash++, ever = (ever != NULL ? ever + 1 : NULL))
3767130561Sobrien    {
3768130561Sobrien      int bind;
3769130561Sobrien      bfd_vma value;
3770218822Sdim      asection *sec, *new_sec;
3771130561Sobrien      flagword flags;
3772130561Sobrien      const char *name;
3773130561Sobrien      struct elf_link_hash_entry *h;
3774130561Sobrien      bfd_boolean definition;
3775130561Sobrien      bfd_boolean size_change_ok;
3776130561Sobrien      bfd_boolean type_change_ok;
3777130561Sobrien      bfd_boolean new_weakdef;
3778130561Sobrien      bfd_boolean override;
3779218822Sdim      bfd_boolean common;
3780130561Sobrien      unsigned int old_alignment;
3781130561Sobrien      bfd *old_bfd;
3782130561Sobrien
3783130561Sobrien      override = FALSE;
3784130561Sobrien
3785130561Sobrien      flags = BSF_NO_FLAGS;
3786130561Sobrien      sec = NULL;
3787130561Sobrien      value = isym->st_value;
3788130561Sobrien      *sym_hash = NULL;
3789218822Sdim      common = bed->common_definition (isym);
3790130561Sobrien
3791130561Sobrien      bind = ELF_ST_BIND (isym->st_info);
3792130561Sobrien      if (bind == STB_LOCAL)
3793130561Sobrien	{
3794130561Sobrien	  /* This should be impossible, since ELF requires that all
3795130561Sobrien	     global symbols follow all local symbols, and that sh_info
3796130561Sobrien	     point to the first global symbol.  Unfortunately, Irix 5
3797130561Sobrien	     screws this up.  */
3798130561Sobrien	  continue;
3799130561Sobrien	}
3800130561Sobrien      else if (bind == STB_GLOBAL)
3801130561Sobrien	{
3802218822Sdim	  if (isym->st_shndx != SHN_UNDEF && !common)
3803130561Sobrien	    flags = BSF_GLOBAL;
3804130561Sobrien	}
3805130561Sobrien      else if (bind == STB_WEAK)
3806130561Sobrien	flags = BSF_WEAK;
3807130561Sobrien      else
3808130561Sobrien	{
3809130561Sobrien	  /* Leave it up to the processor backend.  */
3810130561Sobrien	}
3811130561Sobrien
3812130561Sobrien      if (isym->st_shndx == SHN_UNDEF)
3813130561Sobrien	sec = bfd_und_section_ptr;
3814218822Sdim      else if (isym->st_shndx < SHN_LORESERVE
3815218822Sdim	       || isym->st_shndx > SHN_HIRESERVE)
3816130561Sobrien	{
3817130561Sobrien	  sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
3818130561Sobrien	  if (sec == NULL)
3819130561Sobrien	    sec = bfd_abs_section_ptr;
3820218822Sdim	  else if (sec->kept_section)
3821218822Sdim	    {
3822218822Sdim	      /* Symbols from discarded section are undefined.  We keep
3823218822Sdim		 its visibility.  */
3824218822Sdim	      sec = bfd_und_section_ptr;
3825218822Sdim	      isym->st_shndx = SHN_UNDEF;
3826218822Sdim	    }
3827130561Sobrien	  else if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
3828130561Sobrien	    value -= sec->vma;
3829130561Sobrien	}
3830130561Sobrien      else if (isym->st_shndx == SHN_ABS)
3831130561Sobrien	sec = bfd_abs_section_ptr;
3832130561Sobrien      else if (isym->st_shndx == SHN_COMMON)
3833130561Sobrien	{
3834130561Sobrien	  sec = bfd_com_section_ptr;
3835130561Sobrien	  /* What ELF calls the size we call the value.  What ELF
3836130561Sobrien	     calls the value we call the alignment.  */
3837130561Sobrien	  value = isym->st_size;
3838130561Sobrien	}
3839130561Sobrien      else
3840130561Sobrien	{
3841130561Sobrien	  /* Leave it up to the processor backend.  */
3842130561Sobrien	}
3843130561Sobrien
3844130561Sobrien      name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
3845130561Sobrien					      isym->st_name);
3846130561Sobrien      if (name == NULL)
3847130561Sobrien	goto error_free_vers;
3848130561Sobrien
3849130561Sobrien      if (isym->st_shndx == SHN_COMMON
3850218822Sdim	  && ELF_ST_TYPE (isym->st_info) == STT_TLS
3851218822Sdim	  && !info->relocatable)
3852130561Sobrien	{
3853130561Sobrien	  asection *tcomm = bfd_get_section_by_name (abfd, ".tcommon");
3854130561Sobrien
3855130561Sobrien	  if (tcomm == NULL)
3856130561Sobrien	    {
3857218822Sdim	      tcomm = bfd_make_section_with_flags (abfd, ".tcommon",
3858218822Sdim						   (SEC_ALLOC
3859218822Sdim						    | SEC_IS_COMMON
3860218822Sdim						    | SEC_LINKER_CREATED
3861218822Sdim						    | SEC_THREAD_LOCAL));
3862218822Sdim	      if (tcomm == NULL)
3863130561Sobrien		goto error_free_vers;
3864130561Sobrien	    }
3865130561Sobrien	  sec = tcomm;
3866130561Sobrien	}
3867218822Sdim      else if (bed->elf_add_symbol_hook)
3868130561Sobrien	{
3869218822Sdim	  if (! (*bed->elf_add_symbol_hook) (abfd, info, isym, &name, &flags,
3870218822Sdim					     &sec, &value))
3871130561Sobrien	    goto error_free_vers;
3872130561Sobrien
3873130561Sobrien	  /* The hook function sets the name to NULL if this symbol
3874130561Sobrien	     should be skipped for some reason.  */
3875130561Sobrien	  if (name == NULL)
3876130561Sobrien	    continue;
3877130561Sobrien	}
3878130561Sobrien
3879130561Sobrien      /* Sanity check that all possibilities were handled.  */
3880130561Sobrien      if (sec == NULL)
3881130561Sobrien	{
3882130561Sobrien	  bfd_set_error (bfd_error_bad_value);
3883130561Sobrien	  goto error_free_vers;
3884130561Sobrien	}
3885130561Sobrien
3886130561Sobrien      if (bfd_is_und_section (sec)
3887130561Sobrien	  || bfd_is_com_section (sec))
3888130561Sobrien	definition = FALSE;
3889130561Sobrien      else
3890130561Sobrien	definition = TRUE;
3891130561Sobrien
3892130561Sobrien      size_change_ok = FALSE;
3893218822Sdim      type_change_ok = bed->type_change_ok;
3894130561Sobrien      old_alignment = 0;
3895130561Sobrien      old_bfd = NULL;
3896218822Sdim      new_sec = sec;
3897130561Sobrien
3898218822Sdim      if (is_elf_hash_table (htab))
3899130561Sobrien	{
3900130561Sobrien	  Elf_Internal_Versym iver;
3901130561Sobrien	  unsigned int vernum = 0;
3902130561Sobrien	  bfd_boolean skip;
3903130561Sobrien
3904218822Sdim	  if (ever == NULL)
3905130561Sobrien	    {
3906218822Sdim	      if (info->default_imported_symver)
3907218822Sdim		/* Use the default symbol version created earlier.  */
3908218822Sdim		iver.vs_vers = elf_tdata (abfd)->cverdefs;
3909218822Sdim	      else
3910218822Sdim		iver.vs_vers = 0;
3911218822Sdim	    }
3912218822Sdim	  else
3913218822Sdim	    _bfd_elf_swap_versym_in (abfd, ever, &iver);
3914130561Sobrien
3915218822Sdim	  vernum = iver.vs_vers & VERSYM_VERSION;
3916218822Sdim
3917218822Sdim	  /* If this is a hidden symbol, or if it is not version
3918218822Sdim	     1, we append the version name to the symbol name.
3919218822Sdim	     However, we do not modify a non-hidden absolute symbol
3920218822Sdim	     if it is not a function, because it might be the version
3921218822Sdim	     symbol itself.  FIXME: What if it isn't?  */
3922218822Sdim	  if ((iver.vs_vers & VERSYM_HIDDEN) != 0
3923218822Sdim	      || (vernum > 1
3924218822Sdim		  && (!bfd_is_abs_section (sec)
3925218822Sdim		      || bed->is_function_type (ELF_ST_TYPE (isym->st_info)))))
3926218822Sdim	    {
3927218822Sdim	      const char *verstr;
3928218822Sdim	      size_t namelen, verlen, newlen;
3929218822Sdim	      char *newname, *p;
3930218822Sdim
3931218822Sdim	      if (isym->st_shndx != SHN_UNDEF)
3932130561Sobrien		{
3933218822Sdim		  if (vernum > elf_tdata (abfd)->cverdefs)
3934218822Sdim		    verstr = NULL;
3935218822Sdim		  else if (vernum > 1)
3936218822Sdim		    verstr =
3937218822Sdim		      elf_tdata (abfd)->verdef[vernum - 1].vd_nodename;
3938218822Sdim		  else
3939218822Sdim		    verstr = "";
3940130561Sobrien
3941218822Sdim		  if (verstr == NULL)
3942130561Sobrien		    {
3943218822Sdim		      (*_bfd_error_handler)
3944218822Sdim			(_("%B: %s: invalid version %u (max %d)"),
3945218822Sdim			 abfd, name, vernum,
3946218822Sdim			 elf_tdata (abfd)->cverdefs);
3947218822Sdim		      bfd_set_error (bfd_error_bad_value);
3948218822Sdim		      goto error_free_vers;
3949130561Sobrien		    }
3950218822Sdim		}
3951218822Sdim	      else
3952218822Sdim		{
3953218822Sdim		  /* We cannot simply test for the number of
3954218822Sdim		     entries in the VERNEED section since the
3955218822Sdim		     numbers for the needed versions do not start
3956218822Sdim		     at 0.  */
3957218822Sdim		  Elf_Internal_Verneed *t;
3958218822Sdim
3959218822Sdim		  verstr = NULL;
3960218822Sdim		  for (t = elf_tdata (abfd)->verref;
3961218822Sdim		       t != NULL;
3962218822Sdim		       t = t->vn_nextref)
3963130561Sobrien		    {
3964218822Sdim		      Elf_Internal_Vernaux *a;
3965130561Sobrien
3966218822Sdim		      for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
3967130561Sobrien			{
3968218822Sdim			  if (a->vna_other == vernum)
3969130561Sobrien			    {
3970218822Sdim			      verstr = a->vna_nodename;
3971218822Sdim			      break;
3972130561Sobrien			    }
3973130561Sobrien			}
3974218822Sdim		      if (a != NULL)
3975218822Sdim			break;
3976130561Sobrien		    }
3977218822Sdim		  if (verstr == NULL)
3978218822Sdim		    {
3979218822Sdim		      (*_bfd_error_handler)
3980218822Sdim			(_("%B: %s: invalid needed version %d"),
3981218822Sdim			 abfd, name, vernum);
3982218822Sdim		      bfd_set_error (bfd_error_bad_value);
3983218822Sdim		      goto error_free_vers;
3984218822Sdim		    }
3985218822Sdim		}
3986130561Sobrien
3987218822Sdim	      namelen = strlen (name);
3988218822Sdim	      verlen = strlen (verstr);
3989218822Sdim	      newlen = namelen + verlen + 2;
3990218822Sdim	      if ((iver.vs_vers & VERSYM_HIDDEN) == 0
3991218822Sdim		  && isym->st_shndx != SHN_UNDEF)
3992218822Sdim		++newlen;
3993130561Sobrien
3994218822Sdim	      newname = bfd_hash_allocate (&htab->root.table, newlen);
3995218822Sdim	      if (newname == NULL)
3996218822Sdim		goto error_free_vers;
3997218822Sdim	      memcpy (newname, name, namelen);
3998218822Sdim	      p = newname + namelen;
3999218822Sdim	      *p++ = ELF_VER_CHR;
4000218822Sdim	      /* If this is a defined non-hidden version symbol,
4001218822Sdim		 we add another @ to the name.  This indicates the
4002218822Sdim		 default version of the symbol.  */
4003218822Sdim	      if ((iver.vs_vers & VERSYM_HIDDEN) == 0
4004218822Sdim		  && isym->st_shndx != SHN_UNDEF)
4005218822Sdim		*p++ = ELF_VER_CHR;
4006218822Sdim	      memcpy (p, verstr, verlen + 1);
4007130561Sobrien
4008218822Sdim	      name = newname;
4009130561Sobrien	    }
4010130561Sobrien
4011218822Sdim	  if (!_bfd_elf_merge_symbol (abfd, info, name, isym, &sec,
4012218822Sdim				      &value, &old_alignment,
4013130561Sobrien				      sym_hash, &skip, &override,
4014130561Sobrien				      &type_change_ok, &size_change_ok))
4015130561Sobrien	    goto error_free_vers;
4016130561Sobrien
4017130561Sobrien	  if (skip)
4018130561Sobrien	    continue;
4019130561Sobrien
4020130561Sobrien	  if (override)
4021130561Sobrien	    definition = FALSE;
4022130561Sobrien
4023130561Sobrien	  h = *sym_hash;
4024130561Sobrien	  while (h->root.type == bfd_link_hash_indirect
4025130561Sobrien		 || h->root.type == bfd_link_hash_warning)
4026130561Sobrien	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
4027130561Sobrien
4028130561Sobrien	  /* Remember the old alignment if this is a common symbol, so
4029130561Sobrien	     that we don't reduce the alignment later on.  We can't
4030130561Sobrien	     check later, because _bfd_generic_link_add_one_symbol
4031130561Sobrien	     will set a default for the alignment which we want to
4032130561Sobrien	     override. We also remember the old bfd where the existing
4033130561Sobrien	     definition comes from.  */
4034130561Sobrien	  switch (h->root.type)
4035130561Sobrien	    {
4036130561Sobrien	    default:
4037130561Sobrien	      break;
4038130561Sobrien
4039130561Sobrien	    case bfd_link_hash_defined:
4040130561Sobrien	    case bfd_link_hash_defweak:
4041130561Sobrien	      old_bfd = h->root.u.def.section->owner;
4042130561Sobrien	      break;
4043130561Sobrien
4044130561Sobrien	    case bfd_link_hash_common:
4045130561Sobrien	      old_bfd = h->root.u.c.p->section->owner;
4046130561Sobrien	      old_alignment = h->root.u.c.p->alignment_power;
4047130561Sobrien	      break;
4048130561Sobrien	    }
4049130561Sobrien
4050130561Sobrien	  if (elf_tdata (abfd)->verdef != NULL
4051130561Sobrien	      && ! override
4052130561Sobrien	      && vernum > 1
4053130561Sobrien	      && definition)
4054130561Sobrien	    h->verinfo.verdef = &elf_tdata (abfd)->verdef[vernum - 1];
4055130561Sobrien	}
4056130561Sobrien
4057130561Sobrien      if (! (_bfd_generic_link_add_one_symbol
4058218822Sdim	     (info, abfd, name, flags, sec, value, NULL, FALSE, bed->collect,
4059130561Sobrien	      (struct bfd_link_hash_entry **) sym_hash)))
4060130561Sobrien	goto error_free_vers;
4061130561Sobrien
4062130561Sobrien      h = *sym_hash;
4063130561Sobrien      while (h->root.type == bfd_link_hash_indirect
4064130561Sobrien	     || h->root.type == bfd_link_hash_warning)
4065130561Sobrien	h = (struct elf_link_hash_entry *) h->root.u.i.link;
4066130561Sobrien      *sym_hash = h;
4067130561Sobrien
4068130561Sobrien      new_weakdef = FALSE;
4069130561Sobrien      if (dynamic
4070130561Sobrien	  && definition
4071130561Sobrien	  && (flags & BSF_WEAK) != 0
4072218822Sdim	  && !bed->is_function_type (ELF_ST_TYPE (isym->st_info))
4073218822Sdim	  && is_elf_hash_table (htab)
4074218822Sdim	  && h->u.weakdef == NULL)
4075130561Sobrien	{
4076130561Sobrien	  /* Keep a list of all weak defined non function symbols from
4077130561Sobrien	     a dynamic object, using the weakdef field.  Later in this
4078130561Sobrien	     function we will set the weakdef field to the correct
4079130561Sobrien	     value.  We only put non-function symbols from dynamic
4080130561Sobrien	     objects on this list, because that happens to be the only
4081130561Sobrien	     time we need to know the normal symbol corresponding to a
4082130561Sobrien	     weak symbol, and the information is time consuming to
4083130561Sobrien	     figure out.  If the weakdef field is not already NULL,
4084130561Sobrien	     then this symbol was already defined by some previous
4085130561Sobrien	     dynamic object, and we will be using that previous
4086130561Sobrien	     definition anyhow.  */
4087130561Sobrien
4088218822Sdim	  h->u.weakdef = weaks;
4089130561Sobrien	  weaks = h;
4090130561Sobrien	  new_weakdef = TRUE;
4091130561Sobrien	}
4092130561Sobrien
4093130561Sobrien      /* Set the alignment of a common symbol.  */
4094218822Sdim      if ((common || bfd_is_com_section (sec))
4095130561Sobrien	  && h->root.type == bfd_link_hash_common)
4096130561Sobrien	{
4097130561Sobrien	  unsigned int align;
4098130561Sobrien
4099218822Sdim	  if (common)
4100218822Sdim	    align = bfd_log2 (isym->st_value);
4101218822Sdim	  else
4102218822Sdim	    {
4103218822Sdim	      /* The new symbol is a common symbol in a shared object.
4104218822Sdim		 We need to get the alignment from the section.  */
4105218822Sdim	      align = new_sec->alignment_power;
4106218822Sdim	    }
4107130561Sobrien	  if (align > old_alignment
4108130561Sobrien	      /* Permit an alignment power of zero if an alignment of one
4109130561Sobrien		 is specified and no other alignments have been specified.  */
4110130561Sobrien	      || (isym->st_value == 1 && old_alignment == 0))
4111130561Sobrien	    h->root.u.c.p->alignment_power = align;
4112130561Sobrien	  else
4113130561Sobrien	    h->root.u.c.p->alignment_power = old_alignment;
4114130561Sobrien	}
4115130561Sobrien
4116218822Sdim      if (is_elf_hash_table (htab))
4117130561Sobrien	{
4118130561Sobrien	  bfd_boolean dynsym;
4119130561Sobrien
4120130561Sobrien	  /* Check the alignment when a common symbol is involved. This
4121130561Sobrien	     can change when a common symbol is overridden by a normal
4122130561Sobrien	     definition or a common symbol is ignored due to the old
4123130561Sobrien	     normal definition. We need to make sure the maximum
4124130561Sobrien	     alignment is maintained.  */
4125218822Sdim	  if ((old_alignment || common)
4126130561Sobrien	      && h->root.type != bfd_link_hash_common)
4127130561Sobrien	    {
4128130561Sobrien	      unsigned int common_align;
4129130561Sobrien	      unsigned int normal_align;
4130130561Sobrien	      unsigned int symbol_align;
4131130561Sobrien	      bfd *normal_bfd;
4132130561Sobrien	      bfd *common_bfd;
4133130561Sobrien
4134130561Sobrien	      symbol_align = ffs (h->root.u.def.value) - 1;
4135130561Sobrien	      if (h->root.u.def.section->owner != NULL
4136130561Sobrien		  && (h->root.u.def.section->owner->flags & DYNAMIC) == 0)
4137130561Sobrien		{
4138130561Sobrien		  normal_align = h->root.u.def.section->alignment_power;
4139130561Sobrien		  if (normal_align > symbol_align)
4140130561Sobrien		    normal_align = symbol_align;
4141130561Sobrien		}
4142130561Sobrien	      else
4143130561Sobrien		normal_align = symbol_align;
4144130561Sobrien
4145130561Sobrien	      if (old_alignment)
4146130561Sobrien		{
4147130561Sobrien		  common_align = old_alignment;
4148130561Sobrien		  common_bfd = old_bfd;
4149130561Sobrien		  normal_bfd = abfd;
4150130561Sobrien		}
4151130561Sobrien	      else
4152130561Sobrien		{
4153130561Sobrien		  common_align = bfd_log2 (isym->st_value);
4154130561Sobrien		  common_bfd = abfd;
4155130561Sobrien		  normal_bfd = old_bfd;
4156130561Sobrien		}
4157130561Sobrien
4158130561Sobrien	      if (normal_align < common_align)
4159218822Sdim		{
4160218822Sdim		  /* PR binutils/2735 */
4161218822Sdim		  if (normal_bfd == NULL)
4162218822Sdim		    (*_bfd_error_handler)
4163218822Sdim		      (_("Warning: alignment %u of common symbol `%s' in %B"
4164218822Sdim			 " is greater than the alignment (%u) of its section %A"),
4165218822Sdim		       common_bfd, h->root.u.def.section,
4166218822Sdim		       1 << common_align, name, 1 << normal_align);
4167218822Sdim		  else
4168218822Sdim		    (*_bfd_error_handler)
4169218822Sdim		      (_("Warning: alignment %u of symbol `%s' in %B"
4170218822Sdim			 " is smaller than %u in %B"),
4171218822Sdim		       normal_bfd, common_bfd,
4172218822Sdim		       1 << normal_align, name, 1 << common_align);
4173218822Sdim		}
4174130561Sobrien	    }
4175130561Sobrien
4176218822Sdim	  /* Remember the symbol size if it isn't undefined.  */
4177218822Sdim	  if ((isym->st_size != 0 && isym->st_shndx != SHN_UNDEF)
4178130561Sobrien	      && (definition || h->size == 0))
4179130561Sobrien	    {
4180218822Sdim	      if (h->size != 0
4181218822Sdim		  && h->size != isym->st_size
4182218822Sdim		  && ! size_change_ok)
4183130561Sobrien		(*_bfd_error_handler)
4184218822Sdim		  (_("Warning: size of symbol `%s' changed"
4185218822Sdim		     " from %lu in %B to %lu in %B"),
4186218822Sdim		   old_bfd, abfd,
4187130561Sobrien		   name, (unsigned long) h->size,
4188218822Sdim		   (unsigned long) isym->st_size);
4189130561Sobrien
4190130561Sobrien	      h->size = isym->st_size;
4191130561Sobrien	    }
4192130561Sobrien
4193130561Sobrien	  /* If this is a common symbol, then we always want H->SIZE
4194130561Sobrien	     to be the size of the common symbol.  The code just above
4195130561Sobrien	     won't fix the size if a common symbol becomes larger.  We
4196130561Sobrien	     don't warn about a size change here, because that is
4197218822Sdim	     covered by --warn-common.  Allow changed between different
4198218822Sdim	     function types.  */
4199130561Sobrien	  if (h->root.type == bfd_link_hash_common)
4200130561Sobrien	    h->size = h->root.u.c.size;
4201130561Sobrien
4202130561Sobrien	  if (ELF_ST_TYPE (isym->st_info) != STT_NOTYPE
4203130561Sobrien	      && (definition || h->type == STT_NOTYPE))
4204130561Sobrien	    {
4205130561Sobrien	      if (h->type != STT_NOTYPE
4206130561Sobrien		  && h->type != ELF_ST_TYPE (isym->st_info)
4207130561Sobrien		  && ! type_change_ok)
4208130561Sobrien		(*_bfd_error_handler)
4209218822Sdim		  (_("Warning: type of symbol `%s' changed"
4210218822Sdim		     " from %d to %d in %B"),
4211218822Sdim		   abfd, name, h->type, ELF_ST_TYPE (isym->st_info));
4212130561Sobrien
4213130561Sobrien	      h->type = ELF_ST_TYPE (isym->st_info);
4214130561Sobrien	    }
4215130561Sobrien
4216130561Sobrien	  /* If st_other has a processor-specific meaning, specific
4217130561Sobrien	     code might be needed here. We never merge the visibility
4218130561Sobrien	     attribute with the one from a dynamic object.  */
4219130561Sobrien	  if (bed->elf_backend_merge_symbol_attribute)
4220130561Sobrien	    (*bed->elf_backend_merge_symbol_attribute) (h, isym, definition,
4221130561Sobrien							dynamic);
4222130561Sobrien
4223218822Sdim	  /* If this symbol has default visibility and the user has requested
4224218822Sdim	     we not re-export it, then mark it as hidden.  */
4225218822Sdim	  if (definition && !dynamic
4226218822Sdim	      && (abfd->no_export
4227218822Sdim		  || (abfd->my_archive && abfd->my_archive->no_export))
4228218822Sdim	      && ELF_ST_VISIBILITY (isym->st_other) != STV_INTERNAL)
4229218822Sdim	    isym->st_other = (STV_HIDDEN
4230218822Sdim			      | (isym->st_other & ~ELF_ST_VISIBILITY (-1)));
4231218822Sdim
4232218822Sdim	  if (ELF_ST_VISIBILITY (isym->st_other) != 0 && !dynamic)
4233130561Sobrien	    {
4234130561Sobrien	      unsigned char hvis, symvis, other, nvis;
4235130561Sobrien
4236218822Sdim	      /* Only merge the visibility. Leave the remainder of the
4237218822Sdim		 st_other field to elf_backend_merge_symbol_attribute.  */
4238218822Sdim	      other = h->other & ~ELF_ST_VISIBILITY (-1);
4239130561Sobrien
4240130561Sobrien	      /* Combine visibilities, using the most constraining one.  */
4241130561Sobrien	      hvis   = ELF_ST_VISIBILITY (h->other);
4242130561Sobrien	      symvis = ELF_ST_VISIBILITY (isym->st_other);
4243130561Sobrien	      if (! hvis)
4244130561Sobrien		nvis = symvis;
4245130561Sobrien	      else if (! symvis)
4246130561Sobrien		nvis = hvis;
4247130561Sobrien	      else
4248130561Sobrien		nvis = hvis < symvis ? hvis : symvis;
4249130561Sobrien
4250130561Sobrien	      h->other = other | nvis;
4251130561Sobrien	    }
4252130561Sobrien
4253130561Sobrien	  /* Set a flag in the hash table entry indicating the type of
4254130561Sobrien	     reference or definition we just found.  Keep a count of
4255130561Sobrien	     the number of dynamic symbols we find.  A dynamic symbol
4256130561Sobrien	     is one which is referenced or defined by both a regular
4257130561Sobrien	     object and a shared object.  */
4258130561Sobrien	  dynsym = FALSE;
4259130561Sobrien	  if (! dynamic)
4260130561Sobrien	    {
4261130561Sobrien	      if (! definition)
4262130561Sobrien		{
4263218822Sdim		  h->ref_regular = 1;
4264130561Sobrien		  if (bind != STB_WEAK)
4265218822Sdim		    h->ref_regular_nonweak = 1;
4266130561Sobrien		}
4267130561Sobrien	      else
4268218822Sdim		h->def_regular = 1;
4269130561Sobrien	      if (! info->executable
4270218822Sdim		  || h->def_dynamic
4271218822Sdim		  || h->ref_dynamic)
4272130561Sobrien		dynsym = TRUE;
4273130561Sobrien	    }
4274130561Sobrien	  else
4275130561Sobrien	    {
4276130561Sobrien	      if (! definition)
4277218822Sdim		h->ref_dynamic = 1;
4278130561Sobrien	      else
4279218822Sdim		h->def_dynamic = 1;
4280218822Sdim	      if (h->def_regular
4281218822Sdim		  || h->ref_regular
4282218822Sdim		  || (h->u.weakdef != NULL
4283130561Sobrien		      && ! new_weakdef
4284218822Sdim		      && h->u.weakdef->dynindx != -1))
4285130561Sobrien		dynsym = TRUE;
4286130561Sobrien	    }
4287130561Sobrien
4288218822Sdim	  if (definition && (sec->flags & SEC_DEBUGGING))
4289218822Sdim	    {
4290218822Sdim	      /* We don't want to make debug symbol dynamic.  */
4291218822Sdim	      (*bed->elf_backend_hide_symbol) (info, h, TRUE);
4292218822Sdim	      dynsym = FALSE;
4293218822Sdim	    }
4294130561Sobrien
4295130561Sobrien	  /* Check to see if we need to add an indirect symbol for
4296130561Sobrien	     the default name.  */
4297130561Sobrien	  if (definition || h->root.type == bfd_link_hash_common)
4298130561Sobrien	    if (!_bfd_elf_add_default_symbol (abfd, info, h, name, isym,
4299130561Sobrien					      &sec, &value, &dynsym,
4300130561Sobrien					      override))
4301130561Sobrien	      goto error_free_vers;
4302130561Sobrien
4303130561Sobrien	  if (definition && !dynamic)
4304130561Sobrien	    {
4305130561Sobrien	      char *p = strchr (name, ELF_VER_CHR);
4306130561Sobrien	      if (p != NULL && p[1] != ELF_VER_CHR)
4307130561Sobrien		{
4308130561Sobrien		  /* Queue non-default versions so that .symver x, x@FOO
4309130561Sobrien		     aliases can be checked.  */
4310218822Sdim		  if (!nondeflt_vers)
4311130561Sobrien		    {
4312218822Sdim		      amt = ((isymend - isym + 1)
4313218822Sdim			     * sizeof (struct elf_link_hash_entry *));
4314130561Sobrien		      nondeflt_vers = bfd_malloc (amt);
4315130561Sobrien		    }
4316218822Sdim		  nondeflt_vers[nondeflt_vers_cnt++] = h;
4317130561Sobrien		}
4318130561Sobrien	    }
4319130561Sobrien
4320130561Sobrien	  if (dynsym && h->dynindx == -1)
4321130561Sobrien	    {
4322130561Sobrien	      if (! bfd_elf_link_record_dynamic_symbol (info, h))
4323130561Sobrien		goto error_free_vers;
4324218822Sdim	      if (h->u.weakdef != NULL
4325130561Sobrien		  && ! new_weakdef
4326218822Sdim		  && h->u.weakdef->dynindx == -1)
4327130561Sobrien		{
4328218822Sdim		  if (!bfd_elf_link_record_dynamic_symbol (info, h->u.weakdef))
4329130561Sobrien		    goto error_free_vers;
4330130561Sobrien		}
4331130561Sobrien	    }
4332130561Sobrien	  else if (dynsym && h->dynindx != -1)
4333130561Sobrien	    /* If the symbol already has a dynamic index, but
4334130561Sobrien	       visibility says it should not be visible, turn it into
4335130561Sobrien	       a local symbol.  */
4336130561Sobrien	    switch (ELF_ST_VISIBILITY (h->other))
4337130561Sobrien	      {
4338130561Sobrien	      case STV_INTERNAL:
4339130561Sobrien	      case STV_HIDDEN:
4340130561Sobrien		(*bed->elf_backend_hide_symbol) (info, h, TRUE);
4341130561Sobrien		dynsym = FALSE;
4342130561Sobrien		break;
4343130561Sobrien	      }
4344130561Sobrien
4345130561Sobrien	  if (!add_needed
4346130561Sobrien	      && definition
4347130561Sobrien	      && dynsym
4348218822Sdim	      && h->ref_regular)
4349130561Sobrien	    {
4350130561Sobrien	      int ret;
4351130561Sobrien	      const char *soname = elf_dt_name (abfd);
4352130561Sobrien
4353130561Sobrien	      /* A symbol from a library loaded via DT_NEEDED of some
4354130561Sobrien		 other library is referenced by a regular object.
4355218822Sdim		 Add a DT_NEEDED entry for it.  Issue an error if
4356218822Sdim		 --no-add-needed is used.  */
4357218822Sdim	      if ((elf_dyn_lib_class (abfd) & DYN_NO_NEEDED) != 0)
4358218822Sdim		{
4359275386Sdim		  bfd_boolean looks_soish;
4360275386Sdim		  const char *print_name;
4361275386Sdim		  int print_len;
4362275386Sdim		  size_t len, lend = 0;
4363275386Sdim
4364275386Sdim		  looks_soish = FALSE;
4365275386Sdim		  print_name = soname;
4366275386Sdim		  print_len = strlen(soname);
4367275386Sdim		  if (strncmp(soname, "lib", 3) == 0)
4368275386Sdim		    {
4369275386Sdim		      len = print_len;
4370275386Sdim		      if (len > 5 && strcmp(soname + len - 2, ".a") == 0)
4371275386Sdim			lend = len - 5;
4372275386Sdim		      else
4373275386Sdim			{
4374275386Sdim			  while (len > 6 && (ISDIGIT(soname[len - 1]) ||
4375275386Sdim					     soname[len - 1] == '.'))
4376275386Sdim			    len--;
4377275386Sdim			  if (strncmp(soname + len - 3, ".so", 3) == 0)
4378275386Sdim			    lend = len - 6;
4379275386Sdim			}
4380275386Sdim		      if (lend != 0)
4381275386Sdim			{
4382275386Sdim			  print_name = soname + 3;
4383275386Sdim			  print_len = lend;
4384275386Sdim			  looks_soish = TRUE;
4385275386Sdim		    	}
4386275386Sdim		    }
4387275386Sdim
4388218822Sdim		  (*_bfd_error_handler)
4389275386Sdim		    (_("undefined reference to symbol `%s' (try adding -l%s%.*s)"),
4390275386Sdim		    name, looks_soish? "" : ":", print_len, print_name);
4391218822Sdim		  bfd_set_error (bfd_error_bad_value);
4392218822Sdim		  goto error_free_vers;
4393218822Sdim		}
4394218822Sdim
4395218822Sdim	      elf_dyn_lib_class (abfd) &= ~DYN_AS_NEEDED;
4396218822Sdim
4397130561Sobrien	      add_needed = TRUE;
4398218822Sdim	      ret = elf_add_dt_needed_tag (abfd, info, soname, add_needed);
4399130561Sobrien	      if (ret < 0)
4400130561Sobrien		goto error_free_vers;
4401130561Sobrien
4402130561Sobrien	      BFD_ASSERT (ret == 0);
4403130561Sobrien	    }
4404130561Sobrien	}
4405130561Sobrien    }
4406130561Sobrien
4407218822Sdim  if (extversym != NULL)
4408218822Sdim    {
4409218822Sdim      free (extversym);
4410218822Sdim      extversym = NULL;
4411218822Sdim    }
4412218822Sdim
4413218822Sdim  if (isymbuf != NULL)
4414218822Sdim    {
4415218822Sdim      free (isymbuf);
4416218822Sdim      isymbuf = NULL;
4417218822Sdim    }
4418218822Sdim
4419218822Sdim  if ((elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0)
4420218822Sdim    {
4421218822Sdim      unsigned int i;
4422218822Sdim
4423218822Sdim      /* Restore the symbol table.  */
4424218822Sdim      if (bed->as_needed_cleanup)
4425218822Sdim	(*bed->as_needed_cleanup) (abfd, info);
4426218822Sdim      old_hash = (char *) old_tab + tabsize;
4427218822Sdim      old_ent = (char *) old_hash + hashsize;
4428218822Sdim      sym_hash = elf_sym_hashes (abfd);
4429218822Sdim      htab->root.table.table = old_table;
4430218822Sdim      htab->root.table.size = old_size;
4431218822Sdim      htab->root.table.count = old_count;
4432218822Sdim      memcpy (htab->root.table.table, old_tab, tabsize);
4433218822Sdim      memcpy (sym_hash, old_hash, hashsize);
4434218822Sdim      htab->root.undefs = old_undefs;
4435218822Sdim      htab->root.undefs_tail = old_undefs_tail;
4436218822Sdim      for (i = 0; i < htab->root.table.size; i++)
4437218822Sdim	{
4438218822Sdim	  struct bfd_hash_entry *p;
4439218822Sdim	  struct elf_link_hash_entry *h;
4440218822Sdim
4441218822Sdim	  for (p = htab->root.table.table[i]; p != NULL; p = p->next)
4442218822Sdim	    {
4443218822Sdim	      h = (struct elf_link_hash_entry *) p;
4444218822Sdim	      if (h->root.type == bfd_link_hash_warning)
4445218822Sdim		h = (struct elf_link_hash_entry *) h->root.u.i.link;
4446218822Sdim	      if (h->dynindx >= old_dynsymcount)
4447218822Sdim		_bfd_elf_strtab_delref (htab->dynstr, h->dynstr_index);
4448218822Sdim
4449218822Sdim	      memcpy (p, old_ent, htab->root.table.entsize);
4450218822Sdim	      old_ent = (char *) old_ent + htab->root.table.entsize;
4451218822Sdim	      h = (struct elf_link_hash_entry *) p;
4452218822Sdim	      if (h->root.type == bfd_link_hash_warning)
4453218822Sdim		{
4454218822Sdim		  memcpy (h->root.u.i.link, old_ent, htab->root.table.entsize);
4455218822Sdim		  old_ent = (char *) old_ent + htab->root.table.entsize;
4456218822Sdim		}
4457218822Sdim	    }
4458218822Sdim	}
4459218822Sdim
4460218822Sdim      /* Make a special call to the linker "notice" function to
4461218822Sdim	 tell it that symbols added for crefs may need to be removed.  */
4462218822Sdim      if (!(*info->callbacks->notice) (info, NULL, abfd, NULL,
4463218822Sdim				       notice_not_needed))
4464218822Sdim	return FALSE;
4465218822Sdim
4466218822Sdim      free (old_tab);
4467218822Sdim      objalloc_free_block ((struct objalloc *) htab->root.table.memory,
4468218822Sdim			   alloc_mark);
4469218822Sdim      if (nondeflt_vers != NULL)
4470218822Sdim	free (nondeflt_vers);
4471218822Sdim      return TRUE;
4472218822Sdim    }
4473218822Sdim
4474218822Sdim  if (old_tab != NULL)
4475218822Sdim    {
4476218822Sdim      if (!(*info->callbacks->notice) (info, NULL, abfd, NULL,
4477218822Sdim				       notice_needed))
4478218822Sdim	return FALSE;
4479218822Sdim      free (old_tab);
4480218822Sdim      old_tab = NULL;
4481218822Sdim    }
4482218822Sdim
4483130561Sobrien  /* Now that all the symbols from this input file are created, handle
4484130561Sobrien     .symver foo, foo@BAR such that any relocs against foo become foo@BAR.  */
4485130561Sobrien  if (nondeflt_vers != NULL)
4486130561Sobrien    {
4487130561Sobrien      bfd_size_type cnt, symidx;
4488130561Sobrien
4489130561Sobrien      for (cnt = 0; cnt < nondeflt_vers_cnt; ++cnt)
4490130561Sobrien	{
4491130561Sobrien	  struct elf_link_hash_entry *h = nondeflt_vers[cnt], *hi;
4492130561Sobrien	  char *shortname, *p;
4493130561Sobrien
4494130561Sobrien	  p = strchr (h->root.root.string, ELF_VER_CHR);
4495130561Sobrien	  if (p == NULL
4496130561Sobrien	      || (h->root.type != bfd_link_hash_defined
4497130561Sobrien		  && h->root.type != bfd_link_hash_defweak))
4498130561Sobrien	    continue;
4499130561Sobrien
4500130561Sobrien	  amt = p - h->root.root.string;
4501130561Sobrien	  shortname = bfd_malloc (amt + 1);
4502130561Sobrien	  memcpy (shortname, h->root.root.string, amt);
4503130561Sobrien	  shortname[amt] = '\0';
4504130561Sobrien
4505130561Sobrien	  hi = (struct elf_link_hash_entry *)
4506218822Sdim	       bfd_link_hash_lookup (&htab->root, shortname,
4507130561Sobrien				     FALSE, FALSE, FALSE);
4508130561Sobrien	  if (hi != NULL
4509130561Sobrien	      && hi->root.type == h->root.type
4510130561Sobrien	      && hi->root.u.def.value == h->root.u.def.value
4511130561Sobrien	      && hi->root.u.def.section == h->root.u.def.section)
4512130561Sobrien	    {
4513130561Sobrien	      (*bed->elf_backend_hide_symbol) (info, hi, TRUE);
4514130561Sobrien	      hi->root.type = bfd_link_hash_indirect;
4515130561Sobrien	      hi->root.u.i.link = (struct bfd_link_hash_entry *) h;
4516218822Sdim	      (*bed->elf_backend_copy_indirect_symbol) (info, h, hi);
4517130561Sobrien	      sym_hash = elf_sym_hashes (abfd);
4518130561Sobrien	      if (sym_hash)
4519130561Sobrien		for (symidx = 0; symidx < extsymcount; ++symidx)
4520130561Sobrien		  if (sym_hash[symidx] == hi)
4521130561Sobrien		    {
4522130561Sobrien		      sym_hash[symidx] = h;
4523130561Sobrien		      break;
4524130561Sobrien		    }
4525130561Sobrien	    }
4526130561Sobrien	  free (shortname);
4527130561Sobrien	}
4528130561Sobrien      free (nondeflt_vers);
4529130561Sobrien      nondeflt_vers = NULL;
4530130561Sobrien    }
4531130561Sobrien
4532130561Sobrien  /* Now set the weakdefs field correctly for all the weak defined
4533130561Sobrien     symbols we found.  The only way to do this is to search all the
4534130561Sobrien     symbols.  Since we only need the information for non functions in
4535130561Sobrien     dynamic objects, that's the only time we actually put anything on
4536130561Sobrien     the list WEAKS.  We need this information so that if a regular
4537130561Sobrien     object refers to a symbol defined weakly in a dynamic object, the
4538130561Sobrien     real symbol in the dynamic object is also put in the dynamic
4539130561Sobrien     symbols; we also must arrange for both symbols to point to the
4540130561Sobrien     same memory location.  We could handle the general case of symbol
4541130561Sobrien     aliasing, but a general symbol alias can only be generated in
4542130561Sobrien     assembler code, handling it correctly would be very time
4543130561Sobrien     consuming, and other ELF linkers don't handle general aliasing
4544130561Sobrien     either.  */
4545130561Sobrien  if (weaks != NULL)
4546130561Sobrien    {
4547130561Sobrien      struct elf_link_hash_entry **hpp;
4548130561Sobrien      struct elf_link_hash_entry **hppend;
4549130561Sobrien      struct elf_link_hash_entry **sorted_sym_hash;
4550130561Sobrien      struct elf_link_hash_entry *h;
4551130561Sobrien      size_t sym_count;
4552130561Sobrien
4553130561Sobrien      /* Since we have to search the whole symbol list for each weak
4554130561Sobrien	 defined symbol, search time for N weak defined symbols will be
4555130561Sobrien	 O(N^2). Binary search will cut it down to O(NlogN).  */
4556130561Sobrien      amt = extsymcount * sizeof (struct elf_link_hash_entry *);
4557130561Sobrien      sorted_sym_hash = bfd_malloc (amt);
4558130561Sobrien      if (sorted_sym_hash == NULL)
4559130561Sobrien	goto error_return;
4560130561Sobrien      sym_hash = sorted_sym_hash;
4561130561Sobrien      hpp = elf_sym_hashes (abfd);
4562130561Sobrien      hppend = hpp + extsymcount;
4563130561Sobrien      sym_count = 0;
4564130561Sobrien      for (; hpp < hppend; hpp++)
4565130561Sobrien	{
4566130561Sobrien	  h = *hpp;
4567130561Sobrien	  if (h != NULL
4568130561Sobrien	      && h->root.type == bfd_link_hash_defined
4569218822Sdim	      && !bed->is_function_type (h->type))
4570130561Sobrien	    {
4571130561Sobrien	      *sym_hash = h;
4572130561Sobrien	      sym_hash++;
4573130561Sobrien	      sym_count++;
4574130561Sobrien	    }
4575130561Sobrien	}
4576130561Sobrien
4577130561Sobrien      qsort (sorted_sym_hash, sym_count,
4578130561Sobrien	     sizeof (struct elf_link_hash_entry *),
4579130561Sobrien	     elf_sort_symbol);
4580130561Sobrien
4581130561Sobrien      while (weaks != NULL)
4582130561Sobrien	{
4583130561Sobrien	  struct elf_link_hash_entry *hlook;
4584130561Sobrien	  asection *slook;
4585130561Sobrien	  bfd_vma vlook;
4586130561Sobrien	  long ilook;
4587130561Sobrien	  size_t i, j, idx;
4588130561Sobrien
4589130561Sobrien	  hlook = weaks;
4590218822Sdim	  weaks = hlook->u.weakdef;
4591218822Sdim	  hlook->u.weakdef = NULL;
4592130561Sobrien
4593130561Sobrien	  BFD_ASSERT (hlook->root.type == bfd_link_hash_defined
4594130561Sobrien		      || hlook->root.type == bfd_link_hash_defweak
4595130561Sobrien		      || hlook->root.type == bfd_link_hash_common
4596130561Sobrien		      || hlook->root.type == bfd_link_hash_indirect);
4597130561Sobrien	  slook = hlook->root.u.def.section;
4598130561Sobrien	  vlook = hlook->root.u.def.value;
4599130561Sobrien
4600130561Sobrien	  ilook = -1;
4601130561Sobrien	  i = 0;
4602130561Sobrien	  j = sym_count;
4603130561Sobrien	  while (i < j)
4604130561Sobrien	    {
4605130561Sobrien	      bfd_signed_vma vdiff;
4606130561Sobrien	      idx = (i + j) / 2;
4607130561Sobrien	      h = sorted_sym_hash [idx];
4608130561Sobrien	      vdiff = vlook - h->root.u.def.value;
4609130561Sobrien	      if (vdiff < 0)
4610130561Sobrien		j = idx;
4611130561Sobrien	      else if (vdiff > 0)
4612130561Sobrien		i = idx + 1;
4613130561Sobrien	      else
4614130561Sobrien		{
4615218822Sdim		  long sdiff = slook->id - h->root.u.def.section->id;
4616130561Sobrien		  if (sdiff < 0)
4617130561Sobrien		    j = idx;
4618130561Sobrien		  else if (sdiff > 0)
4619130561Sobrien		    i = idx + 1;
4620130561Sobrien		  else
4621130561Sobrien		    {
4622130561Sobrien		      ilook = idx;
4623130561Sobrien		      break;
4624130561Sobrien		    }
4625130561Sobrien		}
4626130561Sobrien	    }
4627130561Sobrien
4628130561Sobrien	  /* We didn't find a value/section match.  */
4629130561Sobrien	  if (ilook == -1)
4630130561Sobrien	    continue;
4631130561Sobrien
4632130561Sobrien	  for (i = ilook; i < sym_count; i++)
4633130561Sobrien	    {
4634130561Sobrien	      h = sorted_sym_hash [i];
4635130561Sobrien
4636130561Sobrien	      /* Stop if value or section doesn't match.  */
4637130561Sobrien	      if (h->root.u.def.value != vlook
4638130561Sobrien		  || h->root.u.def.section != slook)
4639130561Sobrien		break;
4640130561Sobrien	      else if (h != hlook)
4641130561Sobrien		{
4642218822Sdim		  hlook->u.weakdef = h;
4643130561Sobrien
4644130561Sobrien		  /* If the weak definition is in the list of dynamic
4645130561Sobrien		     symbols, make sure the real definition is put
4646130561Sobrien		     there as well.  */
4647130561Sobrien		  if (hlook->dynindx != -1 && h->dynindx == -1)
4648130561Sobrien		    {
4649130561Sobrien		      if (! bfd_elf_link_record_dynamic_symbol (info, h))
4650130561Sobrien			goto error_return;
4651130561Sobrien		    }
4652130561Sobrien
4653130561Sobrien		  /* If the real definition is in the list of dynamic
4654130561Sobrien		     symbols, make sure the weak definition is put
4655130561Sobrien		     there as well.  If we don't do this, then the
4656130561Sobrien		     dynamic loader might not merge the entries for the
4657130561Sobrien		     real definition and the weak definition.  */
4658130561Sobrien		  if (h->dynindx != -1 && hlook->dynindx == -1)
4659130561Sobrien		    {
4660130561Sobrien		      if (! bfd_elf_link_record_dynamic_symbol (info, hlook))
4661130561Sobrien			goto error_return;
4662130561Sobrien		    }
4663130561Sobrien		  break;
4664130561Sobrien		}
4665130561Sobrien	    }
4666130561Sobrien	}
4667130561Sobrien
4668130561Sobrien      free (sorted_sym_hash);
4669130561Sobrien    }
4670130561Sobrien
4671218822Sdim  if (bed->check_directives)
4672218822Sdim    (*bed->check_directives) (abfd, info);
4673218822Sdim
4674130561Sobrien  /* If this object is the same format as the output object, and it is
4675130561Sobrien     not a shared library, then let the backend look through the
4676130561Sobrien     relocs.
4677130561Sobrien
4678130561Sobrien     This is required to build global offset table entries and to
4679130561Sobrien     arrange for dynamic relocs.  It is not required for the
4680130561Sobrien     particular common case of linking non PIC code, even when linking
4681130561Sobrien     against shared libraries, but unfortunately there is no way of
4682130561Sobrien     knowing whether an object file has been compiled PIC or not.
4683130561Sobrien     Looking through the relocs is not particularly time consuming.
4684130561Sobrien     The problem is that we must either (1) keep the relocs in memory,
4685130561Sobrien     which causes the linker to require additional runtime memory or
4686130561Sobrien     (2) read the relocs twice from the input file, which wastes time.
4687130561Sobrien     This would be a good case for using mmap.
4688130561Sobrien
4689130561Sobrien     I have no idea how to handle linking PIC code into a file of a
4690130561Sobrien     different format.  It probably can't be done.  */
4691130561Sobrien  if (! dynamic
4692218822Sdim      && is_elf_hash_table (htab)
4693218822Sdim      && bed->check_relocs != NULL
4694218822Sdim      && (*bed->relocs_compatible) (abfd->xvec, htab->root.creator))
4695130561Sobrien    {
4696130561Sobrien      asection *o;
4697130561Sobrien
4698130561Sobrien      for (o = abfd->sections; o != NULL; o = o->next)
4699130561Sobrien	{
4700130561Sobrien	  Elf_Internal_Rela *internal_relocs;
4701130561Sobrien	  bfd_boolean ok;
4702130561Sobrien
4703130561Sobrien	  if ((o->flags & SEC_RELOC) == 0
4704130561Sobrien	      || o->reloc_count == 0
4705130561Sobrien	      || ((info->strip == strip_all || info->strip == strip_debugger)
4706130561Sobrien		  && (o->flags & SEC_DEBUGGING) != 0)
4707130561Sobrien	      || bfd_is_abs_section (o->output_section))
4708130561Sobrien	    continue;
4709130561Sobrien
4710130561Sobrien	  internal_relocs = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL,
4711130561Sobrien						       info->keep_memory);
4712130561Sobrien	  if (internal_relocs == NULL)
4713130561Sobrien	    goto error_return;
4714130561Sobrien
4715218822Sdim	  ok = (*bed->check_relocs) (abfd, info, o, internal_relocs);
4716130561Sobrien
4717130561Sobrien	  if (elf_section_data (o)->relocs != internal_relocs)
4718130561Sobrien	    free (internal_relocs);
4719130561Sobrien
4720130561Sobrien	  if (! ok)
4721130561Sobrien	    goto error_return;
4722130561Sobrien	}
4723130561Sobrien    }
4724130561Sobrien
4725130561Sobrien  /* If this is a non-traditional link, try to optimize the handling
4726130561Sobrien     of the .stab/.stabstr sections.  */
4727130561Sobrien  if (! dynamic
4728130561Sobrien      && ! info->traditional_format
4729218822Sdim      && is_elf_hash_table (htab)
4730130561Sobrien      && (info->strip != strip_all && info->strip != strip_debugger))
4731130561Sobrien    {
4732130561Sobrien      asection *stabstr;
4733130561Sobrien
4734130561Sobrien      stabstr = bfd_get_section_by_name (abfd, ".stabstr");
4735130561Sobrien      if (stabstr != NULL)
4736130561Sobrien	{
4737130561Sobrien	  bfd_size_type string_offset = 0;
4738130561Sobrien	  asection *stab;
4739130561Sobrien
4740130561Sobrien	  for (stab = abfd->sections; stab; stab = stab->next)
4741218822Sdim	    if (CONST_STRNEQ (stab->name, ".stab")
4742130561Sobrien		&& (!stab->name[5] ||
4743130561Sobrien		    (stab->name[5] == '.' && ISDIGIT (stab->name[6])))
4744130561Sobrien		&& (stab->flags & SEC_MERGE) == 0
4745130561Sobrien		&& !bfd_is_abs_section (stab->output_section))
4746130561Sobrien	      {
4747130561Sobrien		struct bfd_elf_section_data *secdata;
4748130561Sobrien
4749130561Sobrien		secdata = elf_section_data (stab);
4750218822Sdim		if (! _bfd_link_section_stabs (abfd, &htab->stab_info, stab,
4751218822Sdim					       stabstr, &secdata->sec_info,
4752130561Sobrien					       &string_offset))
4753130561Sobrien		  goto error_return;
4754130561Sobrien		if (secdata->sec_info)
4755130561Sobrien		  stab->sec_info_type = ELF_INFO_TYPE_STABS;
4756130561Sobrien	    }
4757130561Sobrien	}
4758130561Sobrien    }
4759130561Sobrien
4760218822Sdim  if (is_elf_hash_table (htab) && add_needed)
4761130561Sobrien    {
4762130561Sobrien      /* Add this bfd to the loaded list.  */
4763130561Sobrien      struct elf_link_loaded_list *n;
4764130561Sobrien
4765130561Sobrien      n = bfd_alloc (abfd, sizeof (struct elf_link_loaded_list));
4766130561Sobrien      if (n == NULL)
4767130561Sobrien	goto error_return;
4768130561Sobrien      n->abfd = abfd;
4769218822Sdim      n->next = htab->loaded;
4770218822Sdim      htab->loaded = n;
4771130561Sobrien    }
4772130561Sobrien
4773130561Sobrien  return TRUE;
4774130561Sobrien
4775130561Sobrien error_free_vers:
4776218822Sdim  if (old_tab != NULL)
4777218822Sdim    free (old_tab);
4778130561Sobrien  if (nondeflt_vers != NULL)
4779130561Sobrien    free (nondeflt_vers);
4780130561Sobrien  if (extversym != NULL)
4781130561Sobrien    free (extversym);
4782130561Sobrien error_free_sym:
4783130561Sobrien  if (isymbuf != NULL)
4784130561Sobrien    free (isymbuf);
4785130561Sobrien error_return:
4786130561Sobrien  return FALSE;
4787130561Sobrien}
4788130561Sobrien
4789218822Sdim/* Return the linker hash table entry of a symbol that might be
4790218822Sdim   satisfied by an archive symbol.  Return -1 on error.  */
4791218822Sdim
4792218822Sdimstruct elf_link_hash_entry *
4793218822Sdim_bfd_elf_archive_symbol_lookup (bfd *abfd,
4794218822Sdim				struct bfd_link_info *info,
4795218822Sdim				const char *name)
4796218822Sdim{
4797218822Sdim  struct elf_link_hash_entry *h;
4798218822Sdim  char *p, *copy;
4799218822Sdim  size_t len, first;
4800218822Sdim
4801218822Sdim  h = elf_link_hash_lookup (elf_hash_table (info), name, FALSE, FALSE, FALSE);
4802218822Sdim  if (h != NULL)
4803218822Sdim    return h;
4804218822Sdim
4805218822Sdim  /* If this is a default version (the name contains @@), look up the
4806218822Sdim     symbol again with only one `@' as well as without the version.
4807218822Sdim     The effect is that references to the symbol with and without the
4808218822Sdim     version will be matched by the default symbol in the archive.  */
4809218822Sdim
4810218822Sdim  p = strchr (name, ELF_VER_CHR);
4811218822Sdim  if (p == NULL || p[1] != ELF_VER_CHR)
4812218822Sdim    return h;
4813218822Sdim
4814218822Sdim  /* First check with only one `@'.  */
4815218822Sdim  len = strlen (name);
4816218822Sdim  copy = bfd_alloc (abfd, len);
4817218822Sdim  if (copy == NULL)
4818327471Sdim    return (struct elf_link_hash_entry *)(intptr_t)-1;
4819218822Sdim
4820218822Sdim  first = p - name + 1;
4821218822Sdim  memcpy (copy, name, first);
4822218822Sdim  memcpy (copy + first, name + first + 1, len - first);
4823218822Sdim
4824218822Sdim  h = elf_link_hash_lookup (elf_hash_table (info), copy, FALSE, FALSE, FALSE);
4825218822Sdim  if (h == NULL)
4826218822Sdim    {
4827218822Sdim      /* We also need to check references to the symbol without the
4828218822Sdim	 version.  */
4829218822Sdim      copy[first - 1] = '\0';
4830218822Sdim      h = elf_link_hash_lookup (elf_hash_table (info), copy,
4831218822Sdim				FALSE, FALSE, FALSE);
4832218822Sdim    }
4833218822Sdim
4834218822Sdim  bfd_release (abfd, copy);
4835218822Sdim  return h;
4836218822Sdim}
4837218822Sdim
4838130561Sobrien/* Add symbols from an ELF archive file to the linker hash table.  We
4839130561Sobrien   don't use _bfd_generic_link_add_archive_symbols because of a
4840130561Sobrien   problem which arises on UnixWare.  The UnixWare libc.so is an
4841130561Sobrien   archive which includes an entry libc.so.1 which defines a bunch of
4842130561Sobrien   symbols.  The libc.so archive also includes a number of other
4843130561Sobrien   object files, which also define symbols, some of which are the same
4844130561Sobrien   as those defined in libc.so.1.  Correct linking requires that we
4845130561Sobrien   consider each object file in turn, and include it if it defines any
4846130561Sobrien   symbols we need.  _bfd_generic_link_add_archive_symbols does not do
4847130561Sobrien   this; it looks through the list of undefined symbols, and includes
4848130561Sobrien   any object file which defines them.  When this algorithm is used on
4849130561Sobrien   UnixWare, it winds up pulling in libc.so.1 early and defining a
4850130561Sobrien   bunch of symbols.  This means that some of the other objects in the
4851130561Sobrien   archive are not included in the link, which is incorrect since they
4852130561Sobrien   precede libc.so.1 in the archive.
4853130561Sobrien
4854130561Sobrien   Fortunately, ELF archive handling is simpler than that done by
4855130561Sobrien   _bfd_generic_link_add_archive_symbols, which has to allow for a.out
4856130561Sobrien   oddities.  In ELF, if we find a symbol in the archive map, and the
4857130561Sobrien   symbol is currently undefined, we know that we must pull in that
4858130561Sobrien   object file.
4859130561Sobrien
4860130561Sobrien   Unfortunately, we do have to make multiple passes over the symbol
4861130561Sobrien   table until nothing further is resolved.  */
4862130561Sobrien
4863130561Sobrienstatic bfd_boolean
4864130561Sobrienelf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
4865130561Sobrien{
4866130561Sobrien  symindex c;
4867130561Sobrien  bfd_boolean *defined = NULL;
4868130561Sobrien  bfd_boolean *included = NULL;
4869130561Sobrien  carsym *symdefs;
4870130561Sobrien  bfd_boolean loop;
4871130561Sobrien  bfd_size_type amt;
4872218822Sdim  const struct elf_backend_data *bed;
4873218822Sdim  struct elf_link_hash_entry * (*archive_symbol_lookup)
4874218822Sdim    (bfd *, struct bfd_link_info *, const char *);
4875130561Sobrien
4876130561Sobrien  if (! bfd_has_map (abfd))
4877130561Sobrien    {
4878130561Sobrien      /* An empty archive is a special case.  */
4879130561Sobrien      if (bfd_openr_next_archived_file (abfd, NULL) == NULL)
4880130561Sobrien	return TRUE;
4881130561Sobrien      bfd_set_error (bfd_error_no_armap);
4882130561Sobrien      return FALSE;
4883130561Sobrien    }
4884130561Sobrien
4885130561Sobrien  /* Keep track of all symbols we know to be already defined, and all
4886130561Sobrien     files we know to be already included.  This is to speed up the
4887130561Sobrien     second and subsequent passes.  */
4888130561Sobrien  c = bfd_ardata (abfd)->symdef_count;
4889130561Sobrien  if (c == 0)
4890130561Sobrien    return TRUE;
4891130561Sobrien  amt = c;
4892130561Sobrien  amt *= sizeof (bfd_boolean);
4893130561Sobrien  defined = bfd_zmalloc (amt);
4894130561Sobrien  included = bfd_zmalloc (amt);
4895130561Sobrien  if (defined == NULL || included == NULL)
4896130561Sobrien    goto error_return;
4897130561Sobrien
4898130561Sobrien  symdefs = bfd_ardata (abfd)->symdefs;
4899218822Sdim  bed = get_elf_backend_data (abfd);
4900218822Sdim  archive_symbol_lookup = bed->elf_backend_archive_symbol_lookup;
4901130561Sobrien
4902130561Sobrien  do
4903130561Sobrien    {
4904130561Sobrien      file_ptr last;
4905130561Sobrien      symindex i;
4906130561Sobrien      carsym *symdef;
4907130561Sobrien      carsym *symdefend;
4908130561Sobrien
4909130561Sobrien      loop = FALSE;
4910130561Sobrien      last = -1;
4911130561Sobrien
4912130561Sobrien      symdef = symdefs;
4913130561Sobrien      symdefend = symdef + c;
4914130561Sobrien      for (i = 0; symdef < symdefend; symdef++, i++)
4915130561Sobrien	{
4916107492Sobrien	  struct elf_link_hash_entry *h;
4917130561Sobrien	  bfd *element;
4918130561Sobrien	  struct bfd_link_hash_entry *undefs_tail;
4919130561Sobrien	  symindex mark;
4920107492Sobrien
4921130561Sobrien	  if (defined[i] || included[i])
4922130561Sobrien	    continue;
4923130561Sobrien	  if (symdef->file_offset == last)
4924130561Sobrien	    {
4925130561Sobrien	      included[i] = TRUE;
4926130561Sobrien	      continue;
4927130561Sobrien	    }
492833965Sjdp
4929218822Sdim	  h = archive_symbol_lookup (abfd, info, symdef->name);
4930327471Sdim	  if (h == (struct elf_link_hash_entry *)(intptr_t)-1)
4931218822Sdim	    goto error_return;
493233965Sjdp
4933130561Sobrien	  if (h == NULL)
4934130561Sobrien	    continue;
4935130561Sobrien
4936130561Sobrien	  if (h->root.type == bfd_link_hash_common)
4937130561Sobrien	    {
4938130561Sobrien	      /* We currently have a common symbol.  The archive map contains
4939130561Sobrien		 a reference to this symbol, so we may want to include it.  We
4940130561Sobrien		 only want to include it however, if this archive element
4941130561Sobrien		 contains a definition of the symbol, not just another common
4942130561Sobrien		 declaration of it.
4943130561Sobrien
4944130561Sobrien		 Unfortunately some archivers (including GNU ar) will put
4945130561Sobrien		 declarations of common symbols into their archive maps, as
4946130561Sobrien		 well as real definitions, so we cannot just go by the archive
4947130561Sobrien		 map alone.  Instead we must read in the element's symbol
4948130561Sobrien		 table and check that to see what kind of symbol definition
4949130561Sobrien		 this is.  */
4950130561Sobrien	      if (! elf_link_is_defined_archive_symbol (abfd, symdef))
4951130561Sobrien		continue;
4952130561Sobrien	    }
4953130561Sobrien	  else if (h->root.type != bfd_link_hash_undefined)
4954130561Sobrien	    {
4955130561Sobrien	      if (h->root.type != bfd_link_hash_undefweak)
4956130561Sobrien		defined[i] = TRUE;
4957130561Sobrien	      continue;
4958130561Sobrien	    }
4959130561Sobrien
4960130561Sobrien	  /* We need to include this archive member.  */
4961130561Sobrien	  element = _bfd_get_elt_at_filepos (abfd, symdef->file_offset);
4962130561Sobrien	  if (element == NULL)
4963130561Sobrien	    goto error_return;
4964130561Sobrien
4965130561Sobrien	  if (! bfd_check_format (element, bfd_object))
4966130561Sobrien	    goto error_return;
4967130561Sobrien
4968130561Sobrien	  /* Doublecheck that we have not included this object
4969130561Sobrien	     already--it should be impossible, but there may be
4970130561Sobrien	     something wrong with the archive.  */
4971130561Sobrien	  if (element->archive_pass != 0)
4972130561Sobrien	    {
4973130561Sobrien	      bfd_set_error (bfd_error_bad_value);
4974130561Sobrien	      goto error_return;
4975130561Sobrien	    }
4976130561Sobrien	  element->archive_pass = 1;
4977130561Sobrien
4978130561Sobrien	  undefs_tail = info->hash->undefs_tail;
4979130561Sobrien
4980130561Sobrien	  if (! (*info->callbacks->add_archive_element) (info, element,
4981130561Sobrien							 symdef->name))
4982130561Sobrien	    goto error_return;
4983130561Sobrien	  if (! bfd_link_add_symbols (element, info))
4984130561Sobrien	    goto error_return;
4985130561Sobrien
4986130561Sobrien	  /* If there are any new undefined symbols, we need to make
4987130561Sobrien	     another pass through the archive in order to see whether
4988130561Sobrien	     they can be defined.  FIXME: This isn't perfect, because
4989130561Sobrien	     common symbols wind up on undefs_tail and because an
4990130561Sobrien	     undefined symbol which is defined later on in this pass
4991130561Sobrien	     does not require another pass.  This isn't a bug, but it
4992130561Sobrien	     does make the code less efficient than it could be.  */
4993130561Sobrien	  if (undefs_tail != info->hash->undefs_tail)
4994130561Sobrien	    loop = TRUE;
4995130561Sobrien
4996130561Sobrien	  /* Look backward to mark all symbols from this object file
4997130561Sobrien	     which we have already seen in this pass.  */
4998130561Sobrien	  mark = i;
4999130561Sobrien	  do
5000130561Sobrien	    {
5001130561Sobrien	      included[mark] = TRUE;
5002130561Sobrien	      if (mark == 0)
5003130561Sobrien		break;
5004130561Sobrien	      --mark;
5005130561Sobrien	    }
5006130561Sobrien	  while (symdefs[mark].file_offset == symdef->file_offset);
5007130561Sobrien
5008130561Sobrien	  /* We mark subsequent symbols from this object file as we go
5009130561Sobrien	     on through the loop.  */
5010130561Sobrien	  last = symdef->file_offset;
501133965Sjdp	}
501233965Sjdp    }
5013130561Sobrien  while (loop);
501433965Sjdp
5015130561Sobrien  free (defined);
5016130561Sobrien  free (included);
501733965Sjdp
5018130561Sobrien  return TRUE;
501933965Sjdp
5020130561Sobrien error_return:
5021130561Sobrien  if (defined != NULL)
5022130561Sobrien    free (defined);
5023130561Sobrien  if (included != NULL)
5024130561Sobrien    free (included);
5025130561Sobrien  return FALSE;
5026130561Sobrien}
5027130561Sobrien
5028130561Sobrien/* Given an ELF BFD, add symbols to the global hash table as
5029130561Sobrien   appropriate.  */
5030130561Sobrien
5031130561Sobrienbfd_boolean
5032130561Sobrienbfd_elf_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
5033130561Sobrien{
5034130561Sobrien  switch (bfd_get_format (abfd))
5035130561Sobrien    {
5036130561Sobrien    case bfd_object:
5037130561Sobrien      return elf_link_add_object_symbols (abfd, info);
5038130561Sobrien    case bfd_archive:
5039130561Sobrien      return elf_link_add_archive_symbols (abfd, info);
5040130561Sobrien    default:
5041130561Sobrien      bfd_set_error (bfd_error_wrong_format);
5042130561Sobrien      return FALSE;
5043130561Sobrien    }
5044130561Sobrien}
5045130561Sobrien
5046130561Sobrien/* This function will be called though elf_link_hash_traverse to store
5047130561Sobrien   all hash value of the exported symbols in an array.  */
5048130561Sobrien
5049130561Sobrienstatic bfd_boolean
5050130561Sobrienelf_collect_hash_codes (struct elf_link_hash_entry *h, void *data)
5051130561Sobrien{
5052130561Sobrien  unsigned long **valuep = data;
5053130561Sobrien  const char *name;
5054130561Sobrien  char *p;
5055130561Sobrien  unsigned long ha;
5056130561Sobrien  char *alc = NULL;
5057130561Sobrien
5058130561Sobrien  if (h->root.type == bfd_link_hash_warning)
5059130561Sobrien    h = (struct elf_link_hash_entry *) h->root.u.i.link;
5060130561Sobrien
5061130561Sobrien  /* Ignore indirect symbols.  These are added by the versioning code.  */
5062130561Sobrien  if (h->dynindx == -1)
5063130561Sobrien    return TRUE;
5064130561Sobrien
5065130561Sobrien  name = h->root.root.string;
5066130561Sobrien  p = strchr (name, ELF_VER_CHR);
5067130561Sobrien  if (p != NULL)
5068130561Sobrien    {
5069130561Sobrien      alc = bfd_malloc (p - name + 1);
5070130561Sobrien      memcpy (alc, name, p - name);
5071130561Sobrien      alc[p - name] = '\0';
5072130561Sobrien      name = alc;
5073130561Sobrien    }
5074130561Sobrien
5075130561Sobrien  /* Compute the hash value.  */
5076130561Sobrien  ha = bfd_elf_hash (name);
5077130561Sobrien
5078130561Sobrien  /* Store the found hash value in the array given as the argument.  */
5079130561Sobrien  *(*valuep)++ = ha;
5080130561Sobrien
5081130561Sobrien  /* And store it in the struct so that we can put it in the hash table
5082130561Sobrien     later.  */
5083218822Sdim  h->u.elf_hash_value = ha;
5084130561Sobrien
5085130561Sobrien  if (alc != NULL)
5086130561Sobrien    free (alc);
5087130561Sobrien
5088130561Sobrien  return TRUE;
5089130561Sobrien}
5090130561Sobrien
5091218822Sdimstruct collect_gnu_hash_codes
5092218822Sdim{
5093218822Sdim  bfd *output_bfd;
5094218822Sdim  const struct elf_backend_data *bed;
5095218822Sdim  unsigned long int nsyms;
5096218822Sdim  unsigned long int maskbits;
5097218822Sdim  unsigned long int *hashcodes;
5098218822Sdim  unsigned long int *hashval;
5099218822Sdim  unsigned long int *indx;
5100218822Sdim  unsigned long int *counts;
5101218822Sdim  bfd_vma *bitmask;
5102218822Sdim  bfd_byte *contents;
5103218822Sdim  long int min_dynindx;
5104218822Sdim  unsigned long int bucketcount;
5105218822Sdim  unsigned long int symindx;
5106218822Sdim  long int local_indx;
5107218822Sdim  long int shift1, shift2;
5108218822Sdim  unsigned long int mask;
5109218822Sdim};
5110218822Sdim
5111218822Sdim/* This function will be called though elf_link_hash_traverse to store
5112218822Sdim   all hash value of the exported symbols in an array.  */
5113218822Sdim
5114218822Sdimstatic bfd_boolean
5115218822Sdimelf_collect_gnu_hash_codes (struct elf_link_hash_entry *h, void *data)
5116218822Sdim{
5117218822Sdim  struct collect_gnu_hash_codes *s = data;
5118218822Sdim  const char *name;
5119218822Sdim  char *p;
5120218822Sdim  unsigned long ha;
5121218822Sdim  char *alc = NULL;
5122218822Sdim
5123218822Sdim  if (h->root.type == bfd_link_hash_warning)
5124218822Sdim    h = (struct elf_link_hash_entry *) h->root.u.i.link;
5125218822Sdim
5126218822Sdim  /* Ignore indirect symbols.  These are added by the versioning code.  */
5127218822Sdim  if (h->dynindx == -1)
5128218822Sdim    return TRUE;
5129218822Sdim
5130218822Sdim  /* Ignore also local symbols and undefined symbols.  */
5131218822Sdim  if (! (*s->bed->elf_hash_symbol) (h))
5132218822Sdim    return TRUE;
5133218822Sdim
5134218822Sdim  name = h->root.root.string;
5135218822Sdim  p = strchr (name, ELF_VER_CHR);
5136218822Sdim  if (p != NULL)
5137218822Sdim    {
5138218822Sdim      alc = bfd_malloc (p - name + 1);
5139218822Sdim      memcpy (alc, name, p - name);
5140218822Sdim      alc[p - name] = '\0';
5141218822Sdim      name = alc;
5142218822Sdim    }
5143218822Sdim
5144218822Sdim  /* Compute the hash value.  */
5145218822Sdim  ha = bfd_elf_gnu_hash (name);
5146218822Sdim
5147218822Sdim  /* Store the found hash value in the array for compute_bucket_count,
5148218822Sdim     and also for .dynsym reordering purposes.  */
5149218822Sdim  s->hashcodes[s->nsyms] = ha;
5150218822Sdim  s->hashval[h->dynindx] = ha;
5151218822Sdim  ++s->nsyms;
5152218822Sdim  if (s->min_dynindx < 0 || s->min_dynindx > h->dynindx)
5153218822Sdim    s->min_dynindx = h->dynindx;
5154218822Sdim
5155218822Sdim  if (alc != NULL)
5156218822Sdim    free (alc);
5157218822Sdim
5158218822Sdim  return TRUE;
5159218822Sdim}
5160218822Sdim
5161218822Sdim/* This function will be called though elf_link_hash_traverse to do
5162218822Sdim   final dynaminc symbol renumbering.  */
5163218822Sdim
5164218822Sdimstatic bfd_boolean
5165218822Sdimelf_renumber_gnu_hash_syms (struct elf_link_hash_entry *h, void *data)
5166218822Sdim{
5167218822Sdim  struct collect_gnu_hash_codes *s = data;
5168218822Sdim  unsigned long int bucket;
5169218822Sdim  unsigned long int val;
5170218822Sdim
5171218822Sdim  if (h->root.type == bfd_link_hash_warning)
5172218822Sdim    h = (struct elf_link_hash_entry *) h->root.u.i.link;
5173218822Sdim
5174218822Sdim  /* Ignore indirect symbols.  */
5175218822Sdim  if (h->dynindx == -1)
5176218822Sdim    return TRUE;
5177218822Sdim
5178218822Sdim  /* Ignore also local symbols and undefined symbols.  */
5179218822Sdim  if (! (*s->bed->elf_hash_symbol) (h))
5180218822Sdim    {
5181218822Sdim      if (h->dynindx >= s->min_dynindx)
5182218822Sdim	h->dynindx = s->local_indx++;
5183218822Sdim      return TRUE;
5184218822Sdim    }
5185218822Sdim
5186218822Sdim  bucket = s->hashval[h->dynindx] % s->bucketcount;
5187218822Sdim  val = (s->hashval[h->dynindx] >> s->shift1)
5188218822Sdim	& ((s->maskbits >> s->shift1) - 1);
5189218822Sdim  s->bitmask[val] |= ((bfd_vma) 1) << (s->hashval[h->dynindx] & s->mask);
5190218822Sdim  s->bitmask[val]
5191218822Sdim    |= ((bfd_vma) 1) << ((s->hashval[h->dynindx] >> s->shift2) & s->mask);
5192218822Sdim  val = s->hashval[h->dynindx] & ~(unsigned long int) 1;
5193218822Sdim  if (s->counts[bucket] == 1)
5194218822Sdim    /* Last element terminates the chain.  */
5195218822Sdim    val |= 1;
5196218822Sdim  bfd_put_32 (s->output_bfd, val,
5197218822Sdim	      s->contents + (s->indx[bucket] - s->symindx) * 4);
5198218822Sdim  --s->counts[bucket];
5199218822Sdim  h->dynindx = s->indx[bucket]++;
5200218822Sdim  return TRUE;
5201218822Sdim}
5202218822Sdim
5203218822Sdim/* Return TRUE if symbol should be hashed in the `.gnu.hash' section.  */
5204218822Sdim
5205218822Sdimbfd_boolean
5206218822Sdim_bfd_elf_hash_symbol (struct elf_link_hash_entry *h)
5207218822Sdim{
5208218822Sdim  return !(h->forced_local
5209218822Sdim	   || h->root.type == bfd_link_hash_undefined
5210218822Sdim	   || h->root.type == bfd_link_hash_undefweak
5211218822Sdim	   || ((h->root.type == bfd_link_hash_defined
5212218822Sdim		|| h->root.type == bfd_link_hash_defweak)
5213218822Sdim	       && h->root.u.def.section->output_section == NULL));
5214218822Sdim}
5215218822Sdim
5216130561Sobrien/* Array used to determine the number of hash table buckets to use
5217130561Sobrien   based on the number of symbols there are.  If there are fewer than
5218130561Sobrien   3 symbols we use 1 bucket, fewer than 17 symbols we use 3 buckets,
5219130561Sobrien   fewer than 37 we use 17 buckets, and so forth.  We never use more
5220130561Sobrien   than 32771 buckets.  */
5221130561Sobrien
5222130561Sobrienstatic const size_t elf_buckets[] =
5223130561Sobrien{
5224130561Sobrien  1, 3, 17, 37, 67, 97, 131, 197, 263, 521, 1031, 2053, 4099, 8209,
5225130561Sobrien  16411, 32771, 0
5226130561Sobrien};
5227130561Sobrien
5228130561Sobrien/* Compute bucket count for hashing table.  We do not use a static set
5229130561Sobrien   of possible tables sizes anymore.  Instead we determine for all
5230130561Sobrien   possible reasonable sizes of the table the outcome (i.e., the
5231130561Sobrien   number of collisions etc) and choose the best solution.  The
5232130561Sobrien   weighting functions are not too simple to allow the table to grow
5233130561Sobrien   without bounds.  Instead one of the weighting factors is the size.
5234130561Sobrien   Therefore the result is always a good payoff between few collisions
5235130561Sobrien   (= short chain lengths) and table size.  */
5236130561Sobrienstatic size_t
5237218822Sdimcompute_bucket_count (struct bfd_link_info *info, unsigned long int *hashcodes,
5238218822Sdim		      unsigned long int nsyms, int gnu_hash)
5239130561Sobrien{
5240130561Sobrien  size_t dynsymcount = elf_hash_table (info)->dynsymcount;
5241130561Sobrien  size_t best_size = 0;
5242130561Sobrien  unsigned long int i;
5243130561Sobrien  bfd_size_type amt;
5244130561Sobrien
5245130561Sobrien  /* We have a problem here.  The following code to optimize the table
5246130561Sobrien     size requires an integer type with more the 32 bits.  If
5247130561Sobrien     BFD_HOST_U_64_BIT is set we know about such a type.  */
5248130561Sobrien#ifdef BFD_HOST_U_64_BIT
5249130561Sobrien  if (info->optimize)
5250130561Sobrien    {
5251130561Sobrien      size_t minsize;
5252130561Sobrien      size_t maxsize;
5253130561Sobrien      BFD_HOST_U_64_BIT best_chlen = ~((BFD_HOST_U_64_BIT) 0);
5254130561Sobrien      bfd *dynobj = elf_hash_table (info)->dynobj;
5255130561Sobrien      const struct elf_backend_data *bed = get_elf_backend_data (dynobj);
5256218822Sdim      unsigned long int *counts;
5257130561Sobrien
5258130561Sobrien      /* Possible optimization parameters: if we have NSYMS symbols we say
5259130561Sobrien	 that the hashing table must at least have NSYMS/4 and at most
5260130561Sobrien	 2*NSYMS buckets.  */
5261130561Sobrien      minsize = nsyms / 4;
5262130561Sobrien      if (minsize == 0)
5263130561Sobrien	minsize = 1;
5264130561Sobrien      best_size = maxsize = nsyms * 2;
5265218822Sdim      if (gnu_hash)
5266218822Sdim	{
5267218822Sdim	  if (minsize < 2)
5268218822Sdim	    minsize = 2;
5269218822Sdim	  if ((best_size & 31) == 0)
5270218822Sdim	    ++best_size;
5271218822Sdim	}
5272130561Sobrien
5273130561Sobrien      /* Create array where we count the collisions in.  We must use bfd_malloc
5274130561Sobrien	 since the size could be large.  */
5275130561Sobrien      amt = maxsize;
5276130561Sobrien      amt *= sizeof (unsigned long int);
5277130561Sobrien      counts = bfd_malloc (amt);
5278130561Sobrien      if (counts == NULL)
5279218822Sdim	return 0;
5280130561Sobrien
5281130561Sobrien      /* Compute the "optimal" size for the hash table.  The criteria is a
5282130561Sobrien	 minimal chain length.  The minor criteria is (of course) the size
5283130561Sobrien	 of the table.  */
5284130561Sobrien      for (i = minsize; i < maxsize; ++i)
5285130561Sobrien	{
5286130561Sobrien	  /* Walk through the array of hashcodes and count the collisions.  */
5287130561Sobrien	  BFD_HOST_U_64_BIT max;
5288130561Sobrien	  unsigned long int j;
5289130561Sobrien	  unsigned long int fact;
5290130561Sobrien
5291218822Sdim	  if (gnu_hash && (i & 31) == 0)
5292218822Sdim	    continue;
5293218822Sdim
5294130561Sobrien	  memset (counts, '\0', i * sizeof (unsigned long int));
5295130561Sobrien
5296130561Sobrien	  /* Determine how often each hash bucket is used.  */
5297130561Sobrien	  for (j = 0; j < nsyms; ++j)
5298130561Sobrien	    ++counts[hashcodes[j] % i];
5299130561Sobrien
5300130561Sobrien	  /* For the weight function we need some information about the
5301130561Sobrien	     pagesize on the target.  This is information need not be 100%
5302130561Sobrien	     accurate.  Since this information is not available (so far) we
5303130561Sobrien	     define it here to a reasonable default value.  If it is crucial
5304130561Sobrien	     to have a better value some day simply define this value.  */
5305130561Sobrien# ifndef BFD_TARGET_PAGESIZE
5306130561Sobrien#  define BFD_TARGET_PAGESIZE	(4096)
5307130561Sobrien# endif
5308130561Sobrien
5309218822Sdim	  /* We in any case need 2 + DYNSYMCOUNT entries for the size values
5310218822Sdim	     and the chains.  */
5311218822Sdim	  max = (2 + dynsymcount) * bed->s->sizeof_hash_entry;
5312130561Sobrien
5313130561Sobrien# if 1
5314130561Sobrien	  /* Variant 1: optimize for short chains.  We add the squares
5315130561Sobrien	     of all the chain lengths (which favors many small chain
5316130561Sobrien	     over a few long chains).  */
5317130561Sobrien	  for (j = 0; j < i; ++j)
5318130561Sobrien	    max += counts[j] * counts[j];
5319130561Sobrien
5320130561Sobrien	  /* This adds penalties for the overall size of the table.  */
5321218822Sdim	  fact = i / (BFD_TARGET_PAGESIZE / bed->s->sizeof_hash_entry) + 1;
5322130561Sobrien	  max *= fact * fact;
5323130561Sobrien# else
5324130561Sobrien	  /* Variant 2: Optimize a lot more for small table.  Here we
5325130561Sobrien	     also add squares of the size but we also add penalties for
5326130561Sobrien	     empty slots (the +1 term).  */
5327130561Sobrien	  for (j = 0; j < i; ++j)
5328130561Sobrien	    max += (1 + counts[j]) * (1 + counts[j]);
5329130561Sobrien
5330130561Sobrien	  /* The overall size of the table is considered, but not as
5331130561Sobrien	     strong as in variant 1, where it is squared.  */
5332218822Sdim	  fact = i / (BFD_TARGET_PAGESIZE / bed->s->sizeof_hash_entry) + 1;
5333130561Sobrien	  max *= fact;
5334130561Sobrien# endif
5335130561Sobrien
5336130561Sobrien	  /* Compare with current best results.  */
5337130561Sobrien	  if (max < best_chlen)
5338130561Sobrien	    {
5339130561Sobrien	      best_chlen = max;
5340130561Sobrien	      best_size = i;
5341130561Sobrien	    }
5342130561Sobrien	}
5343130561Sobrien
5344130561Sobrien      free (counts);
5345130561Sobrien    }
5346130561Sobrien  else
5347130561Sobrien#endif /* defined (BFD_HOST_U_64_BIT) */
5348130561Sobrien    {
5349130561Sobrien      /* This is the fallback solution if no 64bit type is available or if we
5350130561Sobrien	 are not supposed to spend much time on optimizations.  We select the
5351130561Sobrien	 bucket count using a fixed set of numbers.  */
5352130561Sobrien      for (i = 0; elf_buckets[i] != 0; i++)
5353130561Sobrien	{
5354130561Sobrien	  best_size = elf_buckets[i];
5355218822Sdim	  if (nsyms < elf_buckets[i + 1])
5356130561Sobrien	    break;
5357130561Sobrien	}
5358218822Sdim      if (gnu_hash && best_size < 2)
5359218822Sdim	best_size = 2;
5360130561Sobrien    }
5361130561Sobrien
5362130561Sobrien  return best_size;
5363130561Sobrien}
5364130561Sobrien
5365130561Sobrien/* Set up the sizes and contents of the ELF dynamic sections.  This is
5366130561Sobrien   called by the ELF linker emulation before_allocation routine.  We
5367130561Sobrien   must set the sizes of the sections before the linker sets the
5368130561Sobrien   addresses of the various sections.  */
5369130561Sobrien
5370130561Sobrienbfd_boolean
5371130561Sobrienbfd_elf_size_dynamic_sections (bfd *output_bfd,
5372130561Sobrien			       const char *soname,
5373130561Sobrien			       const char *rpath,
5374130561Sobrien			       const char *filter_shlib,
5375130561Sobrien			       const char * const *auxiliary_filters,
5376130561Sobrien			       struct bfd_link_info *info,
5377130561Sobrien			       asection **sinterpptr,
5378130561Sobrien			       struct bfd_elf_version_tree *verdefs)
5379130561Sobrien{
5380130561Sobrien  bfd_size_type soname_indx;
5381130561Sobrien  bfd *dynobj;
5382130561Sobrien  const struct elf_backend_data *bed;
5383130561Sobrien  struct elf_assign_sym_version_info asvinfo;
5384130561Sobrien
5385130561Sobrien  *sinterpptr = NULL;
5386130561Sobrien
5387130561Sobrien  soname_indx = (bfd_size_type) -1;
5388130561Sobrien
5389130561Sobrien  if (!is_elf_hash_table (info->hash))
5390130561Sobrien    return TRUE;
5391130561Sobrien
5392218822Sdim  bed = get_elf_backend_data (output_bfd);
5393218822Sdim  elf_tdata (output_bfd)->relro = info->relro;
5394130561Sobrien  if (info->execstack)
5395130561Sobrien    elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X;
5396130561Sobrien  else if (info->noexecstack)
5397130561Sobrien    elf_tdata (output_bfd)->stack_flags = PF_R | PF_W;
5398130561Sobrien  else
5399130561Sobrien    {
5400130561Sobrien      bfd *inputobj;
5401130561Sobrien      asection *notesec = NULL;
5402130561Sobrien      int exec = 0;
5403130561Sobrien
5404130561Sobrien      for (inputobj = info->input_bfds;
5405130561Sobrien	   inputobj;
5406130561Sobrien	   inputobj = inputobj->link_next)
5407130561Sobrien	{
5408130561Sobrien	  asection *s;
5409130561Sobrien
5410218822Sdim	  if (inputobj->flags & (DYNAMIC | BFD_LINKER_CREATED))
5411130561Sobrien	    continue;
5412130561Sobrien	  s = bfd_get_section_by_name (inputobj, ".note.GNU-stack");
5413130561Sobrien	  if (s)
5414130561Sobrien	    {
5415130561Sobrien	      if (s->flags & SEC_CODE)
5416130561Sobrien		exec = PF_X;
5417130561Sobrien	      notesec = s;
5418130561Sobrien	    }
5419218822Sdim	  else if (bed->default_execstack)
5420130561Sobrien	    exec = PF_X;
5421130561Sobrien	}
5422130561Sobrien      if (notesec)
5423130561Sobrien	{
5424130561Sobrien	  elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | exec;
5425130561Sobrien	  if (exec && info->relocatable
5426130561Sobrien	      && notesec->output_section != bfd_abs_section_ptr)
5427130561Sobrien	    notesec->output_section->flags |= SEC_CODE;
5428130561Sobrien	}
5429130561Sobrien    }
5430130561Sobrien
5431130561Sobrien  /* Any syms created from now on start with -1 in
5432130561Sobrien     got.refcount/offset and plt.refcount/offset.  */
5433218822Sdim  elf_hash_table (info)->init_got_refcount
5434218822Sdim    = elf_hash_table (info)->init_got_offset;
5435218822Sdim  elf_hash_table (info)->init_plt_refcount
5436218822Sdim    = elf_hash_table (info)->init_plt_offset;
5437130561Sobrien
5438130561Sobrien  /* The backend may have to create some sections regardless of whether
5439130561Sobrien     we're dynamic or not.  */
5440130561Sobrien  if (bed->elf_backend_always_size_sections
5441130561Sobrien      && ! (*bed->elf_backend_always_size_sections) (output_bfd, info))
5442130561Sobrien    return FALSE;
5443130561Sobrien
5444218822Sdim  if (! _bfd_elf_maybe_strip_eh_frame_hdr (info))
5445218822Sdim    return FALSE;
5446218822Sdim
5447130561Sobrien  dynobj = elf_hash_table (info)->dynobj;
5448130561Sobrien
5449130561Sobrien  /* If there were no dynamic objects in the link, there is nothing to
5450130561Sobrien     do here.  */
5451130561Sobrien  if (dynobj == NULL)
5452130561Sobrien    return TRUE;
5453130561Sobrien
5454130561Sobrien  if (elf_hash_table (info)->dynamic_sections_created)
5455130561Sobrien    {
5456130561Sobrien      struct elf_info_failed eif;
5457130561Sobrien      struct elf_link_hash_entry *h;
5458130561Sobrien      asection *dynstr;
5459130561Sobrien      struct bfd_elf_version_tree *t;
5460130561Sobrien      struct bfd_elf_version_expr *d;
5461218822Sdim      asection *s;
5462130561Sobrien      bfd_boolean all_defined;
5463130561Sobrien
5464130561Sobrien      *sinterpptr = bfd_get_section_by_name (dynobj, ".interp");
5465130561Sobrien      BFD_ASSERT (*sinterpptr != NULL || !info->executable);
5466130561Sobrien
5467130561Sobrien      if (soname != NULL)
5468130561Sobrien	{
5469130561Sobrien	  soname_indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
5470130561Sobrien					     soname, TRUE);
5471130561Sobrien	  if (soname_indx == (bfd_size_type) -1
5472130561Sobrien	      || !_bfd_elf_add_dynamic_entry (info, DT_SONAME, soname_indx))
5473130561Sobrien	    return FALSE;
5474130561Sobrien	}
5475130561Sobrien
5476130561Sobrien      if (info->symbolic)
5477130561Sobrien	{
5478130561Sobrien	  if (!_bfd_elf_add_dynamic_entry (info, DT_SYMBOLIC, 0))
5479130561Sobrien	    return FALSE;
5480130561Sobrien	  info->flags |= DF_SYMBOLIC;
5481130561Sobrien	}
5482130561Sobrien
5483130561Sobrien      if (rpath != NULL)
5484130561Sobrien	{
5485130561Sobrien	  bfd_size_type indx;
5486130561Sobrien
5487130561Sobrien	  indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, rpath,
5488130561Sobrien				      TRUE);
5489130561Sobrien	  if (indx == (bfd_size_type) -1
5490130561Sobrien	      || !_bfd_elf_add_dynamic_entry (info, DT_RPATH, indx))
5491130561Sobrien	    return FALSE;
5492130561Sobrien
5493130561Sobrien	  if  (info->new_dtags)
5494130561Sobrien	    {
5495130561Sobrien	      _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr, indx);
5496130561Sobrien	      if (!_bfd_elf_add_dynamic_entry (info, DT_RUNPATH, indx))
5497130561Sobrien		return FALSE;
5498130561Sobrien	    }
5499130561Sobrien	}
5500130561Sobrien
5501130561Sobrien      if (filter_shlib != NULL)
5502130561Sobrien	{
5503130561Sobrien	  bfd_size_type indx;
5504130561Sobrien
5505130561Sobrien	  indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
5506130561Sobrien				      filter_shlib, TRUE);
5507130561Sobrien	  if (indx == (bfd_size_type) -1
5508130561Sobrien	      || !_bfd_elf_add_dynamic_entry (info, DT_FILTER, indx))
5509130561Sobrien	    return FALSE;
5510130561Sobrien	}
5511130561Sobrien
5512130561Sobrien      if (auxiliary_filters != NULL)
5513130561Sobrien	{
5514130561Sobrien	  const char * const *p;
5515130561Sobrien
5516130561Sobrien	  for (p = auxiliary_filters; *p != NULL; p++)
5517130561Sobrien	    {
5518130561Sobrien	      bfd_size_type indx;
5519130561Sobrien
5520130561Sobrien	      indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
5521130561Sobrien					  *p, TRUE);
5522130561Sobrien	      if (indx == (bfd_size_type) -1
5523130561Sobrien		  || !_bfd_elf_add_dynamic_entry (info, DT_AUXILIARY, indx))
5524130561Sobrien		return FALSE;
5525130561Sobrien	    }
5526130561Sobrien	}
5527130561Sobrien
5528130561Sobrien      eif.info = info;
5529130561Sobrien      eif.verdefs = verdefs;
5530130561Sobrien      eif.failed = FALSE;
5531130561Sobrien
5532130561Sobrien      /* If we are supposed to export all symbols into the dynamic symbol
5533130561Sobrien	 table (this is not the normal case), then do so.  */
5534218822Sdim      if (info->export_dynamic
5535218822Sdim	  || (info->executable && info->dynamic))
5536130561Sobrien	{
5537130561Sobrien	  elf_link_hash_traverse (elf_hash_table (info),
5538130561Sobrien				  _bfd_elf_export_symbol,
5539130561Sobrien				  &eif);
5540130561Sobrien	  if (eif.failed)
5541130561Sobrien	    return FALSE;
5542130561Sobrien	}
5543130561Sobrien
5544130561Sobrien      /* Make all global versions with definition.  */
5545130561Sobrien      for (t = verdefs; t != NULL; t = t->next)
5546130561Sobrien	for (d = t->globals.list; d != NULL; d = d->next)
5547130561Sobrien	  if (!d->symver && d->symbol)
5548130561Sobrien	    {
5549130561Sobrien	      const char *verstr, *name;
5550130561Sobrien	      size_t namelen, verlen, newlen;
5551130561Sobrien	      char *newname, *p;
5552130561Sobrien	      struct elf_link_hash_entry *newh;
5553130561Sobrien
5554130561Sobrien	      name = d->symbol;
5555130561Sobrien	      namelen = strlen (name);
5556130561Sobrien	      verstr = t->name;
5557130561Sobrien	      verlen = strlen (verstr);
5558130561Sobrien	      newlen = namelen + verlen + 3;
5559130561Sobrien
5560130561Sobrien	      newname = bfd_malloc (newlen);
5561130561Sobrien	      if (newname == NULL)
5562130561Sobrien		return FALSE;
5563130561Sobrien	      memcpy (newname, name, namelen);
5564130561Sobrien
5565130561Sobrien	      /* Check the hidden versioned definition.  */
5566130561Sobrien	      p = newname + namelen;
5567130561Sobrien	      *p++ = ELF_VER_CHR;
5568130561Sobrien	      memcpy (p, verstr, verlen + 1);
5569130561Sobrien	      newh = elf_link_hash_lookup (elf_hash_table (info),
5570130561Sobrien					   newname, FALSE, FALSE,
5571130561Sobrien					   FALSE);
5572130561Sobrien	      if (newh == NULL
5573130561Sobrien		  || (newh->root.type != bfd_link_hash_defined
5574130561Sobrien		      && newh->root.type != bfd_link_hash_defweak))
5575130561Sobrien		{
5576130561Sobrien		  /* Check the default versioned definition.  */
5577130561Sobrien		  *p++ = ELF_VER_CHR;
5578130561Sobrien		  memcpy (p, verstr, verlen + 1);
5579130561Sobrien		  newh = elf_link_hash_lookup (elf_hash_table (info),
5580130561Sobrien					       newname, FALSE, FALSE,
5581130561Sobrien					       FALSE);
5582130561Sobrien		}
5583130561Sobrien	      free (newname);
5584130561Sobrien
5585130561Sobrien	      /* Mark this version if there is a definition and it is
5586130561Sobrien		 not defined in a shared object.  */
5587130561Sobrien	      if (newh != NULL
5588218822Sdim		  && !newh->def_dynamic
5589130561Sobrien		  && (newh->root.type == bfd_link_hash_defined
5590130561Sobrien		      || newh->root.type == bfd_link_hash_defweak))
5591130561Sobrien		d->symver = 1;
5592130561Sobrien	    }
5593130561Sobrien
5594130561Sobrien      /* Attach all the symbols to their version information.  */
5595130561Sobrien      asvinfo.output_bfd = output_bfd;
5596130561Sobrien      asvinfo.info = info;
5597130561Sobrien      asvinfo.verdefs = verdefs;
5598130561Sobrien      asvinfo.failed = FALSE;
5599130561Sobrien
5600130561Sobrien      elf_link_hash_traverse (elf_hash_table (info),
5601130561Sobrien			      _bfd_elf_link_assign_sym_version,
5602130561Sobrien			      &asvinfo);
5603130561Sobrien      if (asvinfo.failed)
5604130561Sobrien	return FALSE;
5605130561Sobrien
5606130561Sobrien      if (!info->allow_undefined_version)
5607130561Sobrien	{
5608130561Sobrien	  /* Check if all global versions have a definition.  */
5609130561Sobrien	  all_defined = TRUE;
5610130561Sobrien	  for (t = verdefs; t != NULL; t = t->next)
5611130561Sobrien	    for (d = t->globals.list; d != NULL; d = d->next)
5612130561Sobrien	      if (!d->symver && !d->script)
5613130561Sobrien		{
5614130561Sobrien		  (*_bfd_error_handler)
5615130561Sobrien		    (_("%s: undefined version: %s"),
5616130561Sobrien		     d->pattern, t->name);
5617130561Sobrien		  all_defined = FALSE;
5618130561Sobrien		}
5619130561Sobrien
5620130561Sobrien	  if (!all_defined)
5621130561Sobrien	    {
5622130561Sobrien	      bfd_set_error (bfd_error_bad_value);
5623130561Sobrien	      return FALSE;
5624130561Sobrien	    }
5625130561Sobrien	}
5626130561Sobrien
5627130561Sobrien      /* Find all symbols which were defined in a dynamic object and make
5628130561Sobrien	 the backend pick a reasonable value for them.  */
5629130561Sobrien      elf_link_hash_traverse (elf_hash_table (info),
5630130561Sobrien			      _bfd_elf_adjust_dynamic_symbol,
5631130561Sobrien			      &eif);
5632130561Sobrien      if (eif.failed)
5633130561Sobrien	return FALSE;
5634130561Sobrien
5635130561Sobrien      /* Add some entries to the .dynamic section.  We fill in some of the
5636218822Sdim	 values later, in bfd_elf_final_link, but we must add the entries
5637130561Sobrien	 now so that we know the final size of the .dynamic section.  */
5638130561Sobrien
5639130561Sobrien      /* If there are initialization and/or finalization functions to
5640130561Sobrien	 call then add the corresponding DT_INIT/DT_FINI entries.  */
5641130561Sobrien      h = (info->init_function
5642130561Sobrien	   ? elf_link_hash_lookup (elf_hash_table (info),
5643130561Sobrien				   info->init_function, FALSE,
5644130561Sobrien				   FALSE, FALSE)
5645130561Sobrien	   : NULL);
5646130561Sobrien      if (h != NULL
5647218822Sdim	  && (h->ref_regular
5648218822Sdim	      || h->def_regular))
5649130561Sobrien	{
5650130561Sobrien	  if (!_bfd_elf_add_dynamic_entry (info, DT_INIT, 0))
5651130561Sobrien	    return FALSE;
5652130561Sobrien	}
5653130561Sobrien      h = (info->fini_function
5654130561Sobrien	   ? elf_link_hash_lookup (elf_hash_table (info),
5655130561Sobrien				   info->fini_function, FALSE,
5656130561Sobrien				   FALSE, FALSE)
5657130561Sobrien	   : NULL);
5658130561Sobrien      if (h != NULL
5659218822Sdim	  && (h->ref_regular
5660218822Sdim	      || h->def_regular))
5661130561Sobrien	{
5662130561Sobrien	  if (!_bfd_elf_add_dynamic_entry (info, DT_FINI, 0))
5663130561Sobrien	    return FALSE;
5664130561Sobrien	}
5665130561Sobrien
5666218822Sdim      s = bfd_get_section_by_name (output_bfd, ".preinit_array");
5667218822Sdim      if (s != NULL && s->linker_has_input)
5668130561Sobrien	{
5669130561Sobrien	  /* DT_PREINIT_ARRAY is not allowed in shared library.  */
5670130561Sobrien	  if (! info->executable)
5671130561Sobrien	    {
5672130561Sobrien	      bfd *sub;
5673130561Sobrien	      asection *o;
5674130561Sobrien
5675130561Sobrien	      for (sub = info->input_bfds; sub != NULL;
5676130561Sobrien		   sub = sub->link_next)
5677218822Sdim		if (bfd_get_flavour (sub) == bfd_target_elf_flavour)
5678218822Sdim		  for (o = sub->sections; o != NULL; o = o->next)
5679218822Sdim		    if (elf_section_data (o)->this_hdr.sh_type
5680218822Sdim			== SHT_PREINIT_ARRAY)
5681218822Sdim		      {
5682218822Sdim			(*_bfd_error_handler)
5683218822Sdim			  (_("%B: .preinit_array section is not allowed in DSO"),
5684218822Sdim			   sub);
5685218822Sdim			break;
5686218822Sdim		      }
5687130561Sobrien
5688130561Sobrien	      bfd_set_error (bfd_error_nonrepresentable_section);
5689130561Sobrien	      return FALSE;
5690130561Sobrien	    }
5691130561Sobrien
5692130561Sobrien	  if (!_bfd_elf_add_dynamic_entry (info, DT_PREINIT_ARRAY, 0)
5693130561Sobrien	      || !_bfd_elf_add_dynamic_entry (info, DT_PREINIT_ARRAYSZ, 0))
5694130561Sobrien	    return FALSE;
5695130561Sobrien	}
5696218822Sdim      s = bfd_get_section_by_name (output_bfd, ".init_array");
5697218822Sdim      if (s != NULL && s->linker_has_input)
5698130561Sobrien	{
5699130561Sobrien	  if (!_bfd_elf_add_dynamic_entry (info, DT_INIT_ARRAY, 0)
5700130561Sobrien	      || !_bfd_elf_add_dynamic_entry (info, DT_INIT_ARRAYSZ, 0))
5701130561Sobrien	    return FALSE;
5702130561Sobrien	}
5703218822Sdim      s = bfd_get_section_by_name (output_bfd, ".fini_array");
5704218822Sdim      if (s != NULL && s->linker_has_input)
5705130561Sobrien	{
5706130561Sobrien	  if (!_bfd_elf_add_dynamic_entry (info, DT_FINI_ARRAY, 0)
5707130561Sobrien	      || !_bfd_elf_add_dynamic_entry (info, DT_FINI_ARRAYSZ, 0))
5708130561Sobrien	    return FALSE;
5709130561Sobrien	}
5710130561Sobrien
5711130561Sobrien      dynstr = bfd_get_section_by_name (dynobj, ".dynstr");
5712130561Sobrien      /* If .dynstr is excluded from the link, we don't want any of
5713130561Sobrien	 these tags.  Strictly, we should be checking each section
5714130561Sobrien	 individually;  This quick check covers for the case where
5715130561Sobrien	 someone does a /DISCARD/ : { *(*) }.  */
5716130561Sobrien      if (dynstr != NULL && dynstr->output_section != bfd_abs_section_ptr)
5717130561Sobrien	{
5718130561Sobrien	  bfd_size_type strsize;
5719130561Sobrien
5720130561Sobrien	  strsize = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
5721218822Sdim	  if ((info->emit_hash
5722218822Sdim	       && !_bfd_elf_add_dynamic_entry (info, DT_HASH, 0))
5723218822Sdim	      || (info->emit_gnu_hash
5724218822Sdim		  && !_bfd_elf_add_dynamic_entry (info, DT_GNU_HASH, 0))
5725130561Sobrien	      || !_bfd_elf_add_dynamic_entry (info, DT_STRTAB, 0)
5726130561Sobrien	      || !_bfd_elf_add_dynamic_entry (info, DT_SYMTAB, 0)
5727130561Sobrien	      || !_bfd_elf_add_dynamic_entry (info, DT_STRSZ, strsize)
5728130561Sobrien	      || !_bfd_elf_add_dynamic_entry (info, DT_SYMENT,
5729130561Sobrien					      bed->s->sizeof_sym))
5730130561Sobrien	    return FALSE;
5731130561Sobrien	}
5732130561Sobrien    }
5733130561Sobrien
5734130561Sobrien  /* The backend must work out the sizes of all the other dynamic
5735130561Sobrien     sections.  */
5736130561Sobrien  if (bed->elf_backend_size_dynamic_sections
5737130561Sobrien      && ! (*bed->elf_backend_size_dynamic_sections) (output_bfd, info))
5738130561Sobrien    return FALSE;
5739130561Sobrien
5740130561Sobrien  if (elf_hash_table (info)->dynamic_sections_created)
5741130561Sobrien    {
5742218822Sdim      unsigned long section_sym_count;
5743130561Sobrien      asection *s;
5744130561Sobrien
5745130561Sobrien      /* Set up the version definition section.  */
5746130561Sobrien      s = bfd_get_section_by_name (dynobj, ".gnu.version_d");
5747130561Sobrien      BFD_ASSERT (s != NULL);
5748130561Sobrien
5749130561Sobrien      /* We may have created additional version definitions if we are
5750130561Sobrien	 just linking a regular application.  */
5751130561Sobrien      verdefs = asvinfo.verdefs;
5752130561Sobrien
5753130561Sobrien      /* Skip anonymous version tag.  */
5754130561Sobrien      if (verdefs != NULL && verdefs->vernum == 0)
5755130561Sobrien	verdefs = verdefs->next;
5756130561Sobrien
5757218822Sdim      if (verdefs == NULL && !info->create_default_symver)
5758218822Sdim	s->flags |= SEC_EXCLUDE;
5759130561Sobrien      else
5760130561Sobrien	{
5761130561Sobrien	  unsigned int cdefs;
5762130561Sobrien	  bfd_size_type size;
5763130561Sobrien	  struct bfd_elf_version_tree *t;
5764130561Sobrien	  bfd_byte *p;
5765130561Sobrien	  Elf_Internal_Verdef def;
5766130561Sobrien	  Elf_Internal_Verdaux defaux;
5767218822Sdim	  struct bfd_link_hash_entry *bh;
5768218822Sdim	  struct elf_link_hash_entry *h;
5769218822Sdim	  const char *name;
5770130561Sobrien
5771130561Sobrien	  cdefs = 0;
5772130561Sobrien	  size = 0;
5773130561Sobrien
5774130561Sobrien	  /* Make space for the base version.  */
5775130561Sobrien	  size += sizeof (Elf_External_Verdef);
5776130561Sobrien	  size += sizeof (Elf_External_Verdaux);
5777130561Sobrien	  ++cdefs;
5778130561Sobrien
5779218822Sdim	  /* Make space for the default version.  */
5780218822Sdim	  if (info->create_default_symver)
5781218822Sdim	    {
5782218822Sdim	      size += sizeof (Elf_External_Verdef);
5783218822Sdim	      ++cdefs;
5784218822Sdim	    }
5785218822Sdim
5786130561Sobrien	  for (t = verdefs; t != NULL; t = t->next)
5787130561Sobrien	    {
5788130561Sobrien	      struct bfd_elf_version_deps *n;
5789130561Sobrien
5790130561Sobrien	      size += sizeof (Elf_External_Verdef);
5791130561Sobrien	      size += sizeof (Elf_External_Verdaux);
5792130561Sobrien	      ++cdefs;
5793130561Sobrien
5794130561Sobrien	      for (n = t->deps; n != NULL; n = n->next)
5795130561Sobrien		size += sizeof (Elf_External_Verdaux);
5796130561Sobrien	    }
5797130561Sobrien
5798218822Sdim	  s->size = size;
5799218822Sdim	  s->contents = bfd_alloc (output_bfd, s->size);
5800218822Sdim	  if (s->contents == NULL && s->size != 0)
5801130561Sobrien	    return FALSE;
5802130561Sobrien
5803130561Sobrien	  /* Fill in the version definition section.  */
5804130561Sobrien
5805130561Sobrien	  p = s->contents;
5806130561Sobrien
5807130561Sobrien	  def.vd_version = VER_DEF_CURRENT;
5808130561Sobrien	  def.vd_flags = VER_FLG_BASE;
5809130561Sobrien	  def.vd_ndx = 1;
5810130561Sobrien	  def.vd_cnt = 1;
5811218822Sdim	  if (info->create_default_symver)
5812218822Sdim	    {
5813218822Sdim	      def.vd_aux = 2 * sizeof (Elf_External_Verdef);
5814218822Sdim	      def.vd_next = sizeof (Elf_External_Verdef);
5815218822Sdim	    }
5816218822Sdim	  else
5817218822Sdim	    {
5818218822Sdim	      def.vd_aux = sizeof (Elf_External_Verdef);
5819218822Sdim	      def.vd_next = (sizeof (Elf_External_Verdef)
5820218822Sdim			     + sizeof (Elf_External_Verdaux));
5821218822Sdim	    }
5822130561Sobrien
5823130561Sobrien	  if (soname_indx != (bfd_size_type) -1)
5824130561Sobrien	    {
5825130561Sobrien	      _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr,
5826130561Sobrien				      soname_indx);
5827130561Sobrien	      def.vd_hash = bfd_elf_hash (soname);
5828130561Sobrien	      defaux.vda_name = soname_indx;
5829218822Sdim	      name = soname;
5830130561Sobrien	    }
5831130561Sobrien	  else
5832130561Sobrien	    {
5833130561Sobrien	      bfd_size_type indx;
5834130561Sobrien
5835218822Sdim	      name = lbasename (output_bfd->filename);
5836130561Sobrien	      def.vd_hash = bfd_elf_hash (name);
5837130561Sobrien	      indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
5838130561Sobrien					  name, FALSE);
5839130561Sobrien	      if (indx == (bfd_size_type) -1)
5840130561Sobrien		return FALSE;
5841130561Sobrien	      defaux.vda_name = indx;
5842130561Sobrien	    }
5843130561Sobrien	  defaux.vda_next = 0;
5844130561Sobrien
5845130561Sobrien	  _bfd_elf_swap_verdef_out (output_bfd, &def,
5846130561Sobrien				    (Elf_External_Verdef *) p);
5847130561Sobrien	  p += sizeof (Elf_External_Verdef);
5848218822Sdim	  if (info->create_default_symver)
5849218822Sdim	    {
5850218822Sdim	      /* Add a symbol representing this version.  */
5851218822Sdim	      bh = NULL;
5852218822Sdim	      if (! (_bfd_generic_link_add_one_symbol
5853218822Sdim		     (info, dynobj, name, BSF_GLOBAL, bfd_abs_section_ptr,
5854218822Sdim		      0, NULL, FALSE,
5855218822Sdim		      get_elf_backend_data (dynobj)->collect, &bh)))
5856218822Sdim		return FALSE;
5857218822Sdim	      h = (struct elf_link_hash_entry *) bh;
5858218822Sdim	      h->non_elf = 0;
5859218822Sdim	      h->def_regular = 1;
5860218822Sdim	      h->type = STT_OBJECT;
5861218822Sdim	      h->verinfo.vertree = NULL;
5862218822Sdim
5863218822Sdim	      if (! bfd_elf_link_record_dynamic_symbol (info, h))
5864218822Sdim		return FALSE;
5865218822Sdim
5866218822Sdim	      /* Create a duplicate of the base version with the same
5867218822Sdim		 aux block, but different flags.  */
5868218822Sdim	      def.vd_flags = 0;
5869218822Sdim	      def.vd_ndx = 2;
5870218822Sdim	      def.vd_aux = sizeof (Elf_External_Verdef);
5871218822Sdim	      if (verdefs)
5872218822Sdim		def.vd_next = (sizeof (Elf_External_Verdef)
5873218822Sdim			       + sizeof (Elf_External_Verdaux));
5874218822Sdim	      else
5875218822Sdim		def.vd_next = 0;
5876218822Sdim	      _bfd_elf_swap_verdef_out (output_bfd, &def,
5877218822Sdim					(Elf_External_Verdef *) p);
5878218822Sdim	      p += sizeof (Elf_External_Verdef);
5879218822Sdim	    }
5880130561Sobrien	  _bfd_elf_swap_verdaux_out (output_bfd, &defaux,
5881130561Sobrien				     (Elf_External_Verdaux *) p);
5882130561Sobrien	  p += sizeof (Elf_External_Verdaux);
5883130561Sobrien
5884130561Sobrien	  for (t = verdefs; t != NULL; t = t->next)
5885130561Sobrien	    {
5886130561Sobrien	      unsigned int cdeps;
5887130561Sobrien	      struct bfd_elf_version_deps *n;
5888130561Sobrien
5889130561Sobrien	      cdeps = 0;
5890130561Sobrien	      for (n = t->deps; n != NULL; n = n->next)
5891130561Sobrien		++cdeps;
5892130561Sobrien
5893130561Sobrien	      /* Add a symbol representing this version.  */
5894130561Sobrien	      bh = NULL;
5895130561Sobrien	      if (! (_bfd_generic_link_add_one_symbol
5896130561Sobrien		     (info, dynobj, t->name, BSF_GLOBAL, bfd_abs_section_ptr,
5897130561Sobrien		      0, NULL, FALSE,
5898130561Sobrien		      get_elf_backend_data (dynobj)->collect, &bh)))
5899130561Sobrien		return FALSE;
5900130561Sobrien	      h = (struct elf_link_hash_entry *) bh;
5901218822Sdim	      h->non_elf = 0;
5902218822Sdim	      h->def_regular = 1;
5903130561Sobrien	      h->type = STT_OBJECT;
5904130561Sobrien	      h->verinfo.vertree = t;
5905130561Sobrien
5906130561Sobrien	      if (! bfd_elf_link_record_dynamic_symbol (info, h))
5907130561Sobrien		return FALSE;
5908130561Sobrien
5909130561Sobrien	      def.vd_version = VER_DEF_CURRENT;
5910130561Sobrien	      def.vd_flags = 0;
5911130561Sobrien	      if (t->globals.list == NULL
5912130561Sobrien		  && t->locals.list == NULL
5913130561Sobrien		  && ! t->used)
5914130561Sobrien		def.vd_flags |= VER_FLG_WEAK;
5915218822Sdim	      def.vd_ndx = t->vernum + (info->create_default_symver ? 2 : 1);
5916130561Sobrien	      def.vd_cnt = cdeps + 1;
5917130561Sobrien	      def.vd_hash = bfd_elf_hash (t->name);
5918130561Sobrien	      def.vd_aux = sizeof (Elf_External_Verdef);
5919130561Sobrien	      def.vd_next = 0;
5920130561Sobrien	      if (t->next != NULL)
5921130561Sobrien		def.vd_next = (sizeof (Elf_External_Verdef)
5922130561Sobrien			       + (cdeps + 1) * sizeof (Elf_External_Verdaux));
5923130561Sobrien
5924130561Sobrien	      _bfd_elf_swap_verdef_out (output_bfd, &def,
5925130561Sobrien					(Elf_External_Verdef *) p);
5926130561Sobrien	      p += sizeof (Elf_External_Verdef);
5927130561Sobrien
5928130561Sobrien	      defaux.vda_name = h->dynstr_index;
5929130561Sobrien	      _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr,
5930130561Sobrien				      h->dynstr_index);
5931130561Sobrien	      defaux.vda_next = 0;
5932130561Sobrien	      if (t->deps != NULL)
5933130561Sobrien		defaux.vda_next = sizeof (Elf_External_Verdaux);
5934130561Sobrien	      t->name_indx = defaux.vda_name;
5935130561Sobrien
5936130561Sobrien	      _bfd_elf_swap_verdaux_out (output_bfd, &defaux,
5937130561Sobrien					 (Elf_External_Verdaux *) p);
5938130561Sobrien	      p += sizeof (Elf_External_Verdaux);
5939130561Sobrien
5940130561Sobrien	      for (n = t->deps; n != NULL; n = n->next)
5941130561Sobrien		{
5942130561Sobrien		  if (n->version_needed == NULL)
5943130561Sobrien		    {
5944130561Sobrien		      /* This can happen if there was an error in the
5945130561Sobrien			 version script.  */
5946130561Sobrien		      defaux.vda_name = 0;
5947130561Sobrien		    }
5948130561Sobrien		  else
5949130561Sobrien		    {
5950130561Sobrien		      defaux.vda_name = n->version_needed->name_indx;
5951130561Sobrien		      _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr,
5952130561Sobrien					      defaux.vda_name);
5953130561Sobrien		    }
5954130561Sobrien		  if (n->next == NULL)
5955130561Sobrien		    defaux.vda_next = 0;
5956130561Sobrien		  else
5957130561Sobrien		    defaux.vda_next = sizeof (Elf_External_Verdaux);
5958130561Sobrien
5959130561Sobrien		  _bfd_elf_swap_verdaux_out (output_bfd, &defaux,
5960130561Sobrien					     (Elf_External_Verdaux *) p);
5961130561Sobrien		  p += sizeof (Elf_External_Verdaux);
5962130561Sobrien		}
5963130561Sobrien	    }
5964130561Sobrien
5965130561Sobrien	  if (!_bfd_elf_add_dynamic_entry (info, DT_VERDEF, 0)
5966130561Sobrien	      || !_bfd_elf_add_dynamic_entry (info, DT_VERDEFNUM, cdefs))
5967130561Sobrien	    return FALSE;
5968130561Sobrien
5969130561Sobrien	  elf_tdata (output_bfd)->cverdefs = cdefs;
5970130561Sobrien	}
5971130561Sobrien
5972130561Sobrien      if ((info->new_dtags && info->flags) || (info->flags & DF_STATIC_TLS))
5973130561Sobrien	{
5974130561Sobrien	  if (!_bfd_elf_add_dynamic_entry (info, DT_FLAGS, info->flags))
5975130561Sobrien	    return FALSE;
5976130561Sobrien	}
5977130561Sobrien      else if (info->flags & DF_BIND_NOW)
5978130561Sobrien	{
5979130561Sobrien	  if (!_bfd_elf_add_dynamic_entry (info, DT_BIND_NOW, 0))
5980130561Sobrien	    return FALSE;
5981130561Sobrien	}
5982130561Sobrien
5983130561Sobrien      if (info->flags_1)
5984130561Sobrien	{
5985130561Sobrien	  if (info->executable)
5986130561Sobrien	    info->flags_1 &= ~ (DF_1_INITFIRST
5987130561Sobrien				| DF_1_NODELETE
5988130561Sobrien				| DF_1_NOOPEN);
5989130561Sobrien	  if (!_bfd_elf_add_dynamic_entry (info, DT_FLAGS_1, info->flags_1))
5990130561Sobrien	    return FALSE;
5991130561Sobrien	}
5992130561Sobrien
5993130561Sobrien      /* Work out the size of the version reference section.  */
5994130561Sobrien
5995130561Sobrien      s = bfd_get_section_by_name (dynobj, ".gnu.version_r");
5996130561Sobrien      BFD_ASSERT (s != NULL);
5997130561Sobrien      {
5998130561Sobrien	struct elf_find_verdep_info sinfo;
5999130561Sobrien
6000130561Sobrien	sinfo.output_bfd = output_bfd;
6001130561Sobrien	sinfo.info = info;
6002130561Sobrien	sinfo.vers = elf_tdata (output_bfd)->cverdefs;
6003130561Sobrien	if (sinfo.vers == 0)
6004130561Sobrien	  sinfo.vers = 1;
6005130561Sobrien	sinfo.failed = FALSE;
6006130561Sobrien
6007130561Sobrien	elf_link_hash_traverse (elf_hash_table (info),
6008130561Sobrien				_bfd_elf_link_find_version_dependencies,
6009130561Sobrien				&sinfo);
6010130561Sobrien
6011130561Sobrien	if (elf_tdata (output_bfd)->verref == NULL)
6012218822Sdim	  s->flags |= SEC_EXCLUDE;
6013130561Sobrien	else
6014130561Sobrien	  {
6015130561Sobrien	    Elf_Internal_Verneed *t;
6016130561Sobrien	    unsigned int size;
6017130561Sobrien	    unsigned int crefs;
6018130561Sobrien	    bfd_byte *p;
6019130561Sobrien
6020130561Sobrien	    /* Build the version definition section.  */
6021130561Sobrien	    size = 0;
6022130561Sobrien	    crefs = 0;
6023130561Sobrien	    for (t = elf_tdata (output_bfd)->verref;
6024130561Sobrien		 t != NULL;
6025130561Sobrien		 t = t->vn_nextref)
6026130561Sobrien	      {
6027130561Sobrien		Elf_Internal_Vernaux *a;
6028130561Sobrien
6029130561Sobrien		size += sizeof (Elf_External_Verneed);
6030130561Sobrien		++crefs;
6031130561Sobrien		for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
6032130561Sobrien		  size += sizeof (Elf_External_Vernaux);
6033130561Sobrien	      }
6034130561Sobrien
6035218822Sdim	    s->size = size;
6036218822Sdim	    s->contents = bfd_alloc (output_bfd, s->size);
6037130561Sobrien	    if (s->contents == NULL)
6038130561Sobrien	      return FALSE;
6039130561Sobrien
6040130561Sobrien	    p = s->contents;
6041130561Sobrien	    for (t = elf_tdata (output_bfd)->verref;
6042130561Sobrien		 t != NULL;
6043130561Sobrien		 t = t->vn_nextref)
6044130561Sobrien	      {
6045130561Sobrien		unsigned int caux;
6046130561Sobrien		Elf_Internal_Vernaux *a;
6047130561Sobrien		bfd_size_type indx;
6048130561Sobrien
6049130561Sobrien		caux = 0;
6050130561Sobrien		for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
6051130561Sobrien		  ++caux;
6052130561Sobrien
6053130561Sobrien		t->vn_version = VER_NEED_CURRENT;
6054130561Sobrien		t->vn_cnt = caux;
6055130561Sobrien		indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
6056130561Sobrien					    elf_dt_name (t->vn_bfd) != NULL
6057130561Sobrien					    ? elf_dt_name (t->vn_bfd)
6058218822Sdim					    : lbasename (t->vn_bfd->filename),
6059130561Sobrien					    FALSE);
6060130561Sobrien		if (indx == (bfd_size_type) -1)
6061130561Sobrien		  return FALSE;
6062130561Sobrien		t->vn_file = indx;
6063130561Sobrien		t->vn_aux = sizeof (Elf_External_Verneed);
6064130561Sobrien		if (t->vn_nextref == NULL)
6065130561Sobrien		  t->vn_next = 0;
6066130561Sobrien		else
6067130561Sobrien		  t->vn_next = (sizeof (Elf_External_Verneed)
6068130561Sobrien				+ caux * sizeof (Elf_External_Vernaux));
6069130561Sobrien
6070130561Sobrien		_bfd_elf_swap_verneed_out (output_bfd, t,
6071130561Sobrien					   (Elf_External_Verneed *) p);
6072130561Sobrien		p += sizeof (Elf_External_Verneed);
6073130561Sobrien
6074130561Sobrien		for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
6075130561Sobrien		  {
6076130561Sobrien		    a->vna_hash = bfd_elf_hash (a->vna_nodename);
6077130561Sobrien		    indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
6078130561Sobrien						a->vna_nodename, FALSE);
6079130561Sobrien		    if (indx == (bfd_size_type) -1)
6080130561Sobrien		      return FALSE;
6081130561Sobrien		    a->vna_name = indx;
6082130561Sobrien		    if (a->vna_nextptr == NULL)
6083130561Sobrien		      a->vna_next = 0;
6084130561Sobrien		    else
6085130561Sobrien		      a->vna_next = sizeof (Elf_External_Vernaux);
6086130561Sobrien
6087130561Sobrien		    _bfd_elf_swap_vernaux_out (output_bfd, a,
6088130561Sobrien					       (Elf_External_Vernaux *) p);
6089130561Sobrien		    p += sizeof (Elf_External_Vernaux);
6090130561Sobrien		  }
6091130561Sobrien	      }
6092130561Sobrien
6093130561Sobrien	    if (!_bfd_elf_add_dynamic_entry (info, DT_VERNEED, 0)
6094130561Sobrien		|| !_bfd_elf_add_dynamic_entry (info, DT_VERNEEDNUM, crefs))
6095130561Sobrien	      return FALSE;
6096130561Sobrien
6097130561Sobrien	    elf_tdata (output_bfd)->cverrefs = crefs;
6098130561Sobrien	  }
6099130561Sobrien      }
6100130561Sobrien
6101218822Sdim      if ((elf_tdata (output_bfd)->cverrefs == 0
6102218822Sdim	   && elf_tdata (output_bfd)->cverdefs == 0)
6103218822Sdim	  || _bfd_elf_link_renumber_dynsyms (output_bfd, info,
6104218822Sdim					     &section_sym_count) == 0)
6105218822Sdim	{
6106218822Sdim	  s = bfd_get_section_by_name (dynobj, ".gnu.version");
6107218822Sdim	  s->flags |= SEC_EXCLUDE;
6108218822Sdim	}
6109218822Sdim    }
6110218822Sdim  return TRUE;
6111218822Sdim}
6112218822Sdim
6113218822Sdim/* Find the first non-excluded output section.  We'll use its
6114218822Sdim   section symbol for some emitted relocs.  */
6115218822Sdimvoid
6116218822Sdim_bfd_elf_init_1_index_section (bfd *output_bfd, struct bfd_link_info *info)
6117218822Sdim{
6118218822Sdim  asection *s;
6119218822Sdim
6120218822Sdim  for (s = output_bfd->sections; s != NULL; s = s->next)
6121218822Sdim    if ((s->flags & (SEC_EXCLUDE | SEC_ALLOC)) == SEC_ALLOC
6122218822Sdim	&& !_bfd_elf_link_omit_section_dynsym (output_bfd, info, s))
6123218822Sdim      {
6124218822Sdim	elf_hash_table (info)->text_index_section = s;
6125218822Sdim	break;
6126218822Sdim      }
6127218822Sdim}
6128218822Sdim
6129218822Sdim/* Find two non-excluded output sections, one for code, one for data.
6130218822Sdim   We'll use their section symbols for some emitted relocs.  */
6131218822Sdimvoid
6132218822Sdim_bfd_elf_init_2_index_sections (bfd *output_bfd, struct bfd_link_info *info)
6133218822Sdim{
6134218822Sdim  asection *s;
6135218822Sdim
6136218822Sdim  for (s = output_bfd->sections; s != NULL; s = s->next)
6137218822Sdim    if (((s->flags & (SEC_EXCLUDE | SEC_ALLOC | SEC_READONLY))
6138218822Sdim	 == (SEC_ALLOC | SEC_READONLY))
6139218822Sdim	&& !_bfd_elf_link_omit_section_dynsym (output_bfd, info, s))
6140218822Sdim      {
6141218822Sdim	elf_hash_table (info)->text_index_section = s;
6142218822Sdim	break;
6143218822Sdim      }
6144218822Sdim
6145218822Sdim  for (s = output_bfd->sections; s != NULL; s = s->next)
6146218822Sdim    if (((s->flags & (SEC_EXCLUDE | SEC_ALLOC | SEC_READONLY)) == SEC_ALLOC)
6147218822Sdim	&& !_bfd_elf_link_omit_section_dynsym (output_bfd, info, s))
6148218822Sdim      {
6149218822Sdim	elf_hash_table (info)->data_index_section = s;
6150218822Sdim	break;
6151218822Sdim      }
6152218822Sdim
6153218822Sdim  if (elf_hash_table (info)->text_index_section == NULL)
6154218822Sdim    elf_hash_table (info)->text_index_section
6155218822Sdim      = elf_hash_table (info)->data_index_section;
6156218822Sdim}
6157218822Sdim
6158218822Sdimbfd_boolean
6159218822Sdimbfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info)
6160218822Sdim{
6161218822Sdim  const struct elf_backend_data *bed;
6162218822Sdim
6163218822Sdim  if (!is_elf_hash_table (info->hash))
6164218822Sdim    return TRUE;
6165218822Sdim
6166218822Sdim  bed = get_elf_backend_data (output_bfd);
6167218822Sdim  (*bed->elf_backend_init_index_section) (output_bfd, info);
6168218822Sdim
6169218822Sdim  if (elf_hash_table (info)->dynamic_sections_created)
6170218822Sdim    {
6171218822Sdim      bfd *dynobj;
6172218822Sdim      asection *s;
6173218822Sdim      bfd_size_type dynsymcount;
6174218822Sdim      unsigned long section_sym_count;
6175218822Sdim      unsigned int dtagcount;
6176218822Sdim
6177218822Sdim      dynobj = elf_hash_table (info)->dynobj;
6178218822Sdim
6179130561Sobrien      /* Assign dynsym indicies.  In a shared library we generate a
6180130561Sobrien	 section symbol for each output section, which come first.
6181130561Sobrien	 Next come all of the back-end allocated local dynamic syms,
6182130561Sobrien	 followed by the rest of the global symbols.  */
6183130561Sobrien
6184218822Sdim      dynsymcount = _bfd_elf_link_renumber_dynsyms (output_bfd, info,
6185218822Sdim						    &section_sym_count);
6186130561Sobrien
6187130561Sobrien      /* Work out the size of the symbol version section.  */
6188130561Sobrien      s = bfd_get_section_by_name (dynobj, ".gnu.version");
6189130561Sobrien      BFD_ASSERT (s != NULL);
6190218822Sdim      if (dynsymcount != 0
6191218822Sdim	  && (s->flags & SEC_EXCLUDE) == 0)
6192130561Sobrien	{
6193218822Sdim	  s->size = dynsymcount * sizeof (Elf_External_Versym);
6194218822Sdim	  s->contents = bfd_zalloc (output_bfd, s->size);
6195130561Sobrien	  if (s->contents == NULL)
6196130561Sobrien	    return FALSE;
6197130561Sobrien
6198130561Sobrien	  if (!_bfd_elf_add_dynamic_entry (info, DT_VERSYM, 0))
6199130561Sobrien	    return FALSE;
6200130561Sobrien	}
6201130561Sobrien
6202130561Sobrien      /* Set the size of the .dynsym and .hash sections.  We counted
6203130561Sobrien	 the number of dynamic symbols in elf_link_add_object_symbols.
6204130561Sobrien	 We will build the contents of .dynsym and .hash when we build
6205130561Sobrien	 the final symbol table, because until then we do not know the
6206130561Sobrien	 correct value to give the symbols.  We built the .dynstr
6207130561Sobrien	 section as we went along in elf_link_add_object_symbols.  */
6208130561Sobrien      s = bfd_get_section_by_name (dynobj, ".dynsym");
6209130561Sobrien      BFD_ASSERT (s != NULL);
6210218822Sdim      s->size = dynsymcount * bed->s->sizeof_sym;
6211130561Sobrien
6212130561Sobrien      if (dynsymcount != 0)
6213130561Sobrien	{
6214218822Sdim	  s->contents = bfd_alloc (output_bfd, s->size);
6215218822Sdim	  if (s->contents == NULL)
6216218822Sdim	    return FALSE;
6217130561Sobrien
6218218822Sdim	  /* The first entry in .dynsym is a dummy symbol.
6219218822Sdim	     Clear all the section syms, in case we don't output them all.  */
6220218822Sdim	  ++section_sym_count;
6221218822Sdim	  memset (s->contents, 0, section_sym_count * bed->s->sizeof_sym);
6222130561Sobrien	}
6223130561Sobrien
6224218822Sdim      elf_hash_table (info)->bucketcount = 0;
6225218822Sdim
6226130561Sobrien      /* Compute the size of the hashing table.  As a side effect this
6227130561Sobrien	 computes the hash values for all the names we export.  */
6228218822Sdim      if (info->emit_hash)
6229218822Sdim	{
6230218822Sdim	  unsigned long int *hashcodes;
6231218822Sdim	  unsigned long int *hashcodesp;
6232218822Sdim	  bfd_size_type amt;
6233218822Sdim	  unsigned long int nsyms;
6234218822Sdim	  size_t bucketcount;
6235218822Sdim	  size_t hash_entry_size;
6236130561Sobrien
6237218822Sdim	  /* Compute the hash values for all exported symbols.  At the same
6238218822Sdim	     time store the values in an array so that we could use them for
6239218822Sdim	     optimizations.  */
6240218822Sdim	  amt = dynsymcount * sizeof (unsigned long int);
6241218822Sdim	  hashcodes = bfd_malloc (amt);
6242218822Sdim	  if (hashcodes == NULL)
6243218822Sdim	    return FALSE;
6244218822Sdim	  hashcodesp = hashcodes;
6245130561Sobrien
6246218822Sdim	  /* Put all hash values in HASHCODES.  */
6247218822Sdim	  elf_link_hash_traverse (elf_hash_table (info),
6248218822Sdim				  elf_collect_hash_codes, &hashcodesp);
6249130561Sobrien
6250218822Sdim	  nsyms = hashcodesp - hashcodes;
6251218822Sdim	  bucketcount
6252218822Sdim	    = compute_bucket_count (info, hashcodes, nsyms, 0);
6253218822Sdim	  free (hashcodes);
6254130561Sobrien
6255218822Sdim	  if (bucketcount == 0)
6256218822Sdim	    return FALSE;
6257218822Sdim
6258218822Sdim	  elf_hash_table (info)->bucketcount = bucketcount;
6259218822Sdim
6260218822Sdim	  s = bfd_get_section_by_name (dynobj, ".hash");
6261218822Sdim	  BFD_ASSERT (s != NULL);
6262218822Sdim	  hash_entry_size = elf_section_data (s)->this_hdr.sh_entsize;
6263218822Sdim	  s->size = ((2 + bucketcount + dynsymcount) * hash_entry_size);
6264218822Sdim	  s->contents = bfd_zalloc (output_bfd, s->size);
6265218822Sdim	  if (s->contents == NULL)
6266218822Sdim	    return FALSE;
6267218822Sdim
6268218822Sdim	  bfd_put (8 * hash_entry_size, output_bfd, bucketcount, s->contents);
6269218822Sdim	  bfd_put (8 * hash_entry_size, output_bfd, dynsymcount,
6270218822Sdim		   s->contents + hash_entry_size);
6271218822Sdim	}
6272218822Sdim
6273218822Sdim      if (info->emit_gnu_hash)
6274218822Sdim	{
6275218822Sdim	  size_t i, cnt;
6276218822Sdim	  unsigned char *contents;
6277218822Sdim	  struct collect_gnu_hash_codes cinfo;
6278218822Sdim	  bfd_size_type amt;
6279218822Sdim	  size_t bucketcount;
6280218822Sdim
6281218822Sdim	  memset (&cinfo, 0, sizeof (cinfo));
6282218822Sdim
6283218822Sdim	  /* Compute the hash values for all exported symbols.  At the same
6284218822Sdim	     time store the values in an array so that we could use them for
6285218822Sdim	     optimizations.  */
6286218822Sdim	  amt = dynsymcount * 2 * sizeof (unsigned long int);
6287218822Sdim	  cinfo.hashcodes = bfd_malloc (amt);
6288218822Sdim	  if (cinfo.hashcodes == NULL)
6289218822Sdim	    return FALSE;
6290218822Sdim
6291218822Sdim	  cinfo.hashval = cinfo.hashcodes + dynsymcount;
6292218822Sdim	  cinfo.min_dynindx = -1;
6293218822Sdim	  cinfo.output_bfd = output_bfd;
6294218822Sdim	  cinfo.bed = bed;
6295218822Sdim
6296218822Sdim	  /* Put all hash values in HASHCODES.  */
6297218822Sdim	  elf_link_hash_traverse (elf_hash_table (info),
6298218822Sdim				  elf_collect_gnu_hash_codes, &cinfo);
6299218822Sdim
6300218822Sdim	  bucketcount
6301218822Sdim	    = compute_bucket_count (info, cinfo.hashcodes, cinfo.nsyms, 1);
6302218822Sdim
6303218822Sdim	  if (bucketcount == 0)
6304218822Sdim	    {
6305218822Sdim	      free (cinfo.hashcodes);
6306218822Sdim	      return FALSE;
6307218822Sdim	    }
6308218822Sdim
6309218822Sdim	  s = bfd_get_section_by_name (dynobj, ".gnu.hash");
6310218822Sdim	  BFD_ASSERT (s != NULL);
6311218822Sdim
6312218822Sdim	  if (cinfo.nsyms == 0)
6313218822Sdim	    {
6314218822Sdim	      /* Empty .gnu.hash section is special.  */
6315218822Sdim	      BFD_ASSERT (cinfo.min_dynindx == -1);
6316218822Sdim	      free (cinfo.hashcodes);
6317218822Sdim	      s->size = 5 * 4 + bed->s->arch_size / 8;
6318218822Sdim	      contents = bfd_zalloc (output_bfd, s->size);
6319218822Sdim	      if (contents == NULL)
6320218822Sdim		return FALSE;
6321218822Sdim	      s->contents = contents;
6322218822Sdim	      /* 1 empty bucket.  */
6323218822Sdim	      bfd_put_32 (output_bfd, 1, contents);
6324218822Sdim	      /* SYMIDX above the special symbol 0.  */
6325218822Sdim	      bfd_put_32 (output_bfd, 1, contents + 4);
6326218822Sdim	      /* Just one word for bitmask.  */
6327218822Sdim	      bfd_put_32 (output_bfd, 1, contents + 8);
6328218822Sdim	      /* Only hash fn bloom filter.  */
6329218822Sdim	      bfd_put_32 (output_bfd, 0, contents + 12);
6330218822Sdim	      /* No hashes are valid - empty bitmask.  */
6331218822Sdim	      bfd_put (bed->s->arch_size, output_bfd, 0, contents + 16);
6332218822Sdim	      /* No hashes in the only bucket.  */
6333218822Sdim	      bfd_put_32 (output_bfd, 0,
6334218822Sdim			  contents + 16 + bed->s->arch_size / 8);
6335218822Sdim	    }
6336218822Sdim	  else
6337218822Sdim	    {
6338218822Sdim	      unsigned long int maskwords, maskbitslog2;
6339218822Sdim	      BFD_ASSERT (cinfo.min_dynindx != -1);
6340218822Sdim
6341218822Sdim	      maskbitslog2 = bfd_log2 (cinfo.nsyms) + 1;
6342218822Sdim	      if (maskbitslog2 < 3)
6343218822Sdim		maskbitslog2 = 5;
6344218822Sdim	      else if ((1 << (maskbitslog2 - 2)) & cinfo.nsyms)
6345218822Sdim		maskbitslog2 = maskbitslog2 + 3;
6346218822Sdim	      else
6347218822Sdim		maskbitslog2 = maskbitslog2 + 2;
6348218822Sdim	      if (bed->s->arch_size == 64)
6349218822Sdim		{
6350218822Sdim		  if (maskbitslog2 == 5)
6351218822Sdim		    maskbitslog2 = 6;
6352218822Sdim		  cinfo.shift1 = 6;
6353218822Sdim		}
6354218822Sdim	      else
6355218822Sdim		cinfo.shift1 = 5;
6356218822Sdim	      cinfo.mask = (1 << cinfo.shift1) - 1;
6357218822Sdim	      cinfo.shift2 = maskbitslog2;
6358218822Sdim	      cinfo.maskbits = 1 << maskbitslog2;
6359218822Sdim	      maskwords = 1 << (maskbitslog2 - cinfo.shift1);
6360218822Sdim	      amt = bucketcount * sizeof (unsigned long int) * 2;
6361218822Sdim	      amt += maskwords * sizeof (bfd_vma);
6362218822Sdim	      cinfo.bitmask = bfd_malloc (amt);
6363218822Sdim	      if (cinfo.bitmask == NULL)
6364218822Sdim		{
6365218822Sdim		  free (cinfo.hashcodes);
6366218822Sdim		  return FALSE;
6367218822Sdim		}
6368218822Sdim
6369218822Sdim	      cinfo.counts = (void *) (cinfo.bitmask + maskwords);
6370218822Sdim	      cinfo.indx = cinfo.counts + bucketcount;
6371218822Sdim	      cinfo.symindx = dynsymcount - cinfo.nsyms;
6372218822Sdim	      memset (cinfo.bitmask, 0, maskwords * sizeof (bfd_vma));
6373218822Sdim
6374218822Sdim	      /* Determine how often each hash bucket is used.  */
6375218822Sdim	      memset (cinfo.counts, 0, bucketcount * sizeof (cinfo.counts[0]));
6376218822Sdim	      for (i = 0; i < cinfo.nsyms; ++i)
6377218822Sdim		++cinfo.counts[cinfo.hashcodes[i] % bucketcount];
6378218822Sdim
6379218822Sdim	      for (i = 0, cnt = cinfo.symindx; i < bucketcount; ++i)
6380218822Sdim		if (cinfo.counts[i] != 0)
6381218822Sdim		  {
6382218822Sdim		    cinfo.indx[i] = cnt;
6383218822Sdim		    cnt += cinfo.counts[i];
6384218822Sdim		  }
6385218822Sdim	      BFD_ASSERT (cnt == dynsymcount);
6386218822Sdim	      cinfo.bucketcount = bucketcount;
6387218822Sdim	      cinfo.local_indx = cinfo.min_dynindx;
6388218822Sdim
6389218822Sdim	      s->size = (4 + bucketcount + cinfo.nsyms) * 4;
6390218822Sdim	      s->size += cinfo.maskbits / 8;
6391218822Sdim	      contents = bfd_zalloc (output_bfd, s->size);
6392218822Sdim	      if (contents == NULL)
6393218822Sdim		{
6394218822Sdim		  free (cinfo.bitmask);
6395218822Sdim		  free (cinfo.hashcodes);
6396218822Sdim		  return FALSE;
6397218822Sdim		}
6398218822Sdim
6399218822Sdim	      s->contents = contents;
6400218822Sdim	      bfd_put_32 (output_bfd, bucketcount, contents);
6401218822Sdim	      bfd_put_32 (output_bfd, cinfo.symindx, contents + 4);
6402218822Sdim	      bfd_put_32 (output_bfd, maskwords, contents + 8);
6403218822Sdim	      bfd_put_32 (output_bfd, cinfo.shift2, contents + 12);
6404218822Sdim	      contents += 16 + cinfo.maskbits / 8;
6405218822Sdim
6406218822Sdim	      for (i = 0; i < bucketcount; ++i)
6407218822Sdim		{
6408218822Sdim		  if (cinfo.counts[i] == 0)
6409218822Sdim		    bfd_put_32 (output_bfd, 0, contents);
6410218822Sdim		  else
6411218822Sdim		    bfd_put_32 (output_bfd, cinfo.indx[i], contents);
6412218822Sdim		  contents += 4;
6413218822Sdim		}
6414218822Sdim
6415218822Sdim	      cinfo.contents = contents;
6416218822Sdim
6417218822Sdim	      /* Renumber dynamic symbols, populate .gnu.hash section.  */
6418218822Sdim	      elf_link_hash_traverse (elf_hash_table (info),
6419218822Sdim				      elf_renumber_gnu_hash_syms, &cinfo);
6420218822Sdim
6421218822Sdim	      contents = s->contents + 16;
6422218822Sdim	      for (i = 0; i < maskwords; ++i)
6423218822Sdim		{
6424218822Sdim		  bfd_put (bed->s->arch_size, output_bfd, cinfo.bitmask[i],
6425218822Sdim			   contents);
6426218822Sdim		  contents += bed->s->arch_size / 8;
6427218822Sdim		}
6428218822Sdim
6429218822Sdim	      free (cinfo.bitmask);
6430218822Sdim	      free (cinfo.hashcodes);
6431218822Sdim	    }
6432218822Sdim	}
6433218822Sdim
6434130561Sobrien      s = bfd_get_section_by_name (dynobj, ".dynstr");
6435130561Sobrien      BFD_ASSERT (s != NULL);
6436130561Sobrien
6437130561Sobrien      elf_finalize_dynstr (output_bfd, info);
6438130561Sobrien
6439218822Sdim      s->size = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
6440130561Sobrien
6441130561Sobrien      for (dtagcount = 0; dtagcount <= info->spare_dynamic_tags; ++dtagcount)
6442130561Sobrien	if (!_bfd_elf_add_dynamic_entry (info, DT_NULL, 0))
6443130561Sobrien	  return FALSE;
6444130561Sobrien    }
6445130561Sobrien
6446130561Sobrien  return TRUE;
6447130561Sobrien}
6448130561Sobrien
6449130561Sobrien/* Final phase of ELF linker.  */
6450130561Sobrien
6451130561Sobrien/* A structure we use to avoid passing large numbers of arguments.  */
6452130561Sobrien
6453130561Sobrienstruct elf_final_link_info
6454130561Sobrien{
6455130561Sobrien  /* General link information.  */
6456130561Sobrien  struct bfd_link_info *info;
6457130561Sobrien  /* Output BFD.  */
6458130561Sobrien  bfd *output_bfd;
6459130561Sobrien  /* Symbol string table.  */
6460130561Sobrien  struct bfd_strtab_hash *symstrtab;
6461130561Sobrien  /* .dynsym section.  */
6462130561Sobrien  asection *dynsym_sec;
6463130561Sobrien  /* .hash section.  */
6464130561Sobrien  asection *hash_sec;
6465130561Sobrien  /* symbol version section (.gnu.version).  */
6466130561Sobrien  asection *symver_sec;
6467130561Sobrien  /* Buffer large enough to hold contents of any section.  */
6468130561Sobrien  bfd_byte *contents;
6469130561Sobrien  /* Buffer large enough to hold external relocs of any section.  */
6470130561Sobrien  void *external_relocs;
6471130561Sobrien  /* Buffer large enough to hold internal relocs of any section.  */
6472130561Sobrien  Elf_Internal_Rela *internal_relocs;
6473130561Sobrien  /* Buffer large enough to hold external local symbols of any input
6474130561Sobrien     BFD.  */
6475130561Sobrien  bfd_byte *external_syms;
6476130561Sobrien  /* And a buffer for symbol section indices.  */
6477130561Sobrien  Elf_External_Sym_Shndx *locsym_shndx;
6478130561Sobrien  /* Buffer large enough to hold internal local symbols of any input
6479130561Sobrien     BFD.  */
6480130561Sobrien  Elf_Internal_Sym *internal_syms;
6481130561Sobrien  /* Array large enough to hold a symbol index for each local symbol
6482130561Sobrien     of any input BFD.  */
6483130561Sobrien  long *indices;
6484130561Sobrien  /* Array large enough to hold a section pointer for each local
6485130561Sobrien     symbol of any input BFD.  */
6486130561Sobrien  asection **sections;
6487130561Sobrien  /* Buffer to hold swapped out symbols.  */
6488130561Sobrien  bfd_byte *symbuf;
6489130561Sobrien  /* And one for symbol section indices.  */
6490130561Sobrien  Elf_External_Sym_Shndx *symshndxbuf;
6491130561Sobrien  /* Number of swapped out symbols in buffer.  */
6492130561Sobrien  size_t symbuf_count;
6493130561Sobrien  /* Number of symbols which fit in symbuf.  */
6494130561Sobrien  size_t symbuf_size;
6495130561Sobrien  /* And same for symshndxbuf.  */
6496130561Sobrien  size_t shndxbuf_size;
6497130561Sobrien};
6498130561Sobrien
6499130561Sobrien/* This struct is used to pass information to elf_link_output_extsym.  */
6500130561Sobrien
6501130561Sobrienstruct elf_outext_info
6502130561Sobrien{
6503130561Sobrien  bfd_boolean failed;
6504130561Sobrien  bfd_boolean localsyms;
6505130561Sobrien  struct elf_final_link_info *finfo;
6506130561Sobrien};
6507130561Sobrien
6508218822Sdim
6509218822Sdim/* Support for evaluating a complex relocation.
6510218822Sdim
6511218822Sdim   Complex relocations are generalized, self-describing relocations.  The
6512218822Sdim   implementation of them consists of two parts: complex symbols, and the
6513218822Sdim   relocations themselves.
6514218822Sdim
6515218822Sdim   The relocations are use a reserved elf-wide relocation type code (R_RELC
6516218822Sdim   external / BFD_RELOC_RELC internal) and an encoding of relocation field
6517218822Sdim   information (start bit, end bit, word width, etc) into the addend.  This
6518218822Sdim   information is extracted from CGEN-generated operand tables within gas.
6519218822Sdim
6520218822Sdim   Complex symbols are mangled symbols (BSF_RELC external / STT_RELC
6521218822Sdim   internal) representing prefix-notation expressions, including but not
6522218822Sdim   limited to those sorts of expressions normally encoded as addends in the
6523218822Sdim   addend field.  The symbol mangling format is:
6524218822Sdim
6525218822Sdim   <node> := <literal>
6526218822Sdim          |  <unary-operator> ':' <node>
6527218822Sdim          |  <binary-operator> ':' <node> ':' <node>
6528218822Sdim	  ;
6529218822Sdim
6530218822Sdim   <literal> := 's' <digits=N> ':' <N character symbol name>
6531218822Sdim             |  'S' <digits=N> ':' <N character section name>
6532218822Sdim	     |  '#' <hexdigits>
6533218822Sdim	     ;
6534218822Sdim
6535218822Sdim   <binary-operator> := as in C
6536218822Sdim   <unary-operator> := as in C, plus "0-" for unambiguous negation.  */
6537218822Sdim
6538218822Sdimstatic void
6539218822Sdimset_symbol_value (bfd *                         bfd_with_globals,
6540218822Sdim		  struct elf_final_link_info *  finfo,
6541218822Sdim		  int                           symidx,
6542218822Sdim		  bfd_vma                       val)
6543218822Sdim{
6544218822Sdim  bfd_boolean                    is_local;
6545218822Sdim  Elf_Internal_Sym *             sym;
6546218822Sdim  struct elf_link_hash_entry **  sym_hashes;
6547218822Sdim  struct elf_link_hash_entry *   h;
6548218822Sdim
6549218822Sdim  sym_hashes = elf_sym_hashes (bfd_with_globals);
6550218822Sdim  sym = finfo->internal_syms + symidx;
6551218822Sdim  is_local = ELF_ST_BIND(sym->st_info) == STB_LOCAL;
6552218822Sdim
6553218822Sdim  if (is_local)
6554218822Sdim    {
6555218822Sdim      /* It is a local symbol: move it to the
6556218822Sdim	 "absolute" section and give it a value.  */
6557218822Sdim      sym->st_shndx = SHN_ABS;
6558218822Sdim      sym->st_value = val;
6559218822Sdim    }
6560218822Sdim  else
6561218822Sdim    {
6562218822Sdim      /* It is a global symbol: set its link type
6563218822Sdim	 to "defined" and give it a value.  */
6564218822Sdim      h = sym_hashes [symidx];
6565218822Sdim      while (h->root.type == bfd_link_hash_indirect
6566218822Sdim	     || h->root.type == bfd_link_hash_warning)
6567218822Sdim	h = (struct elf_link_hash_entry *) h->root.u.i.link;
6568218822Sdim      h->root.type = bfd_link_hash_defined;
6569218822Sdim      h->root.u.def.value = val;
6570218822Sdim      h->root.u.def.section = bfd_abs_section_ptr;
6571218822Sdim    }
6572218822Sdim}
6573218822Sdim
6574218822Sdimstatic bfd_boolean
6575218822Sdimresolve_symbol (const char *                  name,
6576218822Sdim		bfd *                         input_bfd,
6577218822Sdim		struct elf_final_link_info *  finfo,
6578218822Sdim		bfd_vma *                     result,
6579218822Sdim		size_t                        locsymcount)
6580218822Sdim{
6581218822Sdim  Elf_Internal_Sym *            sym;
6582218822Sdim  struct bfd_link_hash_entry *  global_entry;
6583218822Sdim  const char *                  candidate = NULL;
6584218822Sdim  Elf_Internal_Shdr *           symtab_hdr;
6585218822Sdim  asection *                    sec = NULL;
6586218822Sdim  size_t                        i;
6587218822Sdim
6588218822Sdim  symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
6589218822Sdim
6590218822Sdim  for (i = 0; i < locsymcount; ++ i)
6591218822Sdim    {
6592218822Sdim      sym = finfo->internal_syms + i;
6593218822Sdim      sec = finfo->sections [i];
6594218822Sdim
6595218822Sdim      if (ELF_ST_BIND (sym->st_info) != STB_LOCAL)
6596218822Sdim	continue;
6597218822Sdim
6598218822Sdim      candidate = bfd_elf_string_from_elf_section (input_bfd,
6599218822Sdim						   symtab_hdr->sh_link,
6600218822Sdim						   sym->st_name);
6601218822Sdim#ifdef DEBUG
6602218822Sdim      printf ("Comparing string: '%s' vs. '%s' = 0x%x\n",
6603218822Sdim	      name, candidate, (unsigned int)sym->st_value);
6604218822Sdim#endif
6605218822Sdim      if (candidate && strcmp (candidate, name) == 0)
6606218822Sdim	{
6607218822Sdim	  * result = sym->st_value;
6608218822Sdim
6609218822Sdim	  if (sym->st_shndx > SHN_UNDEF &&
6610218822Sdim	      sym->st_shndx < SHN_LORESERVE)
6611218822Sdim	    {
6612218822Sdim#ifdef DEBUG
6613218822Sdim	      printf ("adjusting for sec '%s' @ 0x%x + 0x%x\n",
6614218822Sdim		      sec->output_section->name,
6615218822Sdim		      (unsigned int)sec->output_section->vma,
6616218822Sdim		      (unsigned int)sec->output_offset);
6617218822Sdim#endif
6618218822Sdim	      * result += sec->output_offset + sec->output_section->vma;
6619218822Sdim	    }
6620218822Sdim#ifdef DEBUG
6621218822Sdim	  printf ("Found symbol with effective value %8.8x\n", (unsigned int)* result);
6622218822Sdim#endif
6623218822Sdim	  return TRUE;
6624218822Sdim	}
6625218822Sdim    }
6626218822Sdim
6627218822Sdim  /* Hmm, haven't found it yet. perhaps it is a global.  */
6628218822Sdim  global_entry = bfd_link_hash_lookup (finfo->info->hash, name, FALSE, FALSE, TRUE);
6629218822Sdim  if (!global_entry)
6630218822Sdim    return FALSE;
6631218822Sdim
6632218822Sdim  if (global_entry->type == bfd_link_hash_defined
6633218822Sdim      || global_entry->type == bfd_link_hash_defweak)
6634218822Sdim    {
6635218822Sdim      * result = global_entry->u.def.value
6636218822Sdim	+ global_entry->u.def.section->output_section->vma
6637218822Sdim	+ global_entry->u.def.section->output_offset;
6638218822Sdim#ifdef DEBUG
6639218822Sdim      printf ("Found GLOBAL symbol '%s' with value %8.8x\n",
6640218822Sdim	      global_entry->root.string, (unsigned int)*result);
6641218822Sdim#endif
6642218822Sdim      return TRUE;
6643218822Sdim    }
6644218822Sdim
6645218822Sdim  if (global_entry->type == bfd_link_hash_common)
6646218822Sdim    {
6647218822Sdim      *result = global_entry->u.def.value +
6648218822Sdim	bfd_com_section_ptr->output_section->vma +
6649218822Sdim	bfd_com_section_ptr->output_offset;
6650218822Sdim#ifdef DEBUG
6651218822Sdim      printf ("Found COMMON symbol '%s' with value %8.8x\n",
6652218822Sdim	      global_entry->root.string, (unsigned int)*result);
6653218822Sdim#endif
6654218822Sdim      return TRUE;
6655218822Sdim    }
6656218822Sdim
6657218822Sdim  return FALSE;
6658218822Sdim}
6659218822Sdim
6660218822Sdimstatic bfd_boolean
6661218822Sdimresolve_section (const char *  name,
6662218822Sdim		 asection *    sections,
6663218822Sdim		 bfd_vma *     result)
6664218822Sdim{
6665218822Sdim  asection *    curr;
6666218822Sdim  unsigned int  len;
6667218822Sdim
6668218822Sdim  for (curr = sections; curr; curr = curr->next)
6669218822Sdim    if (strcmp (curr->name, name) == 0)
6670218822Sdim      {
6671218822Sdim	*result = curr->vma;
6672218822Sdim	return TRUE;
6673218822Sdim      }
6674218822Sdim
6675218822Sdim  /* Hmm. still haven't found it. try pseudo-section names.  */
6676218822Sdim  for (curr = sections; curr; curr = curr->next)
6677218822Sdim    {
6678218822Sdim      len = strlen (curr->name);
6679218822Sdim      if (len > strlen (name))
6680218822Sdim	continue;
6681218822Sdim
6682218822Sdim      if (strncmp (curr->name, name, len) == 0)
6683218822Sdim	{
6684218822Sdim	  if (strncmp (".end", name + len, 4) == 0)
6685218822Sdim	    {
6686218822Sdim	      *result = curr->vma + curr->size;
6687218822Sdim	      return TRUE;
6688218822Sdim	    }
6689218822Sdim
6690218822Sdim	  /* Insert more pseudo-section names here, if you like.  */
6691218822Sdim	}
6692218822Sdim    }
6693218822Sdim
6694218822Sdim  return FALSE;
6695218822Sdim}
6696218822Sdim
6697218822Sdimstatic void
6698218822Sdimundefined_reference (const char *  reftype,
6699218822Sdim		     const char *  name)
6700218822Sdim{
6701218822Sdim  _bfd_error_handler (_("undefined %s reference in complex symbol: %s"), reftype, name);
6702218822Sdim}
6703218822Sdim
6704218822Sdimstatic bfd_boolean
6705218822Sdimeval_symbol (bfd_vma *                     result,
6706218822Sdim	     char *                        sym,
6707218822Sdim	     char **                       advanced,
6708218822Sdim	     bfd *                         input_bfd,
6709218822Sdim	     struct elf_final_link_info *  finfo,
6710218822Sdim	     bfd_vma                       addr,
6711218822Sdim	     bfd_vma                       section_offset,
6712218822Sdim	     size_t                        locsymcount,
6713218822Sdim	     int                           signed_p)
6714218822Sdim{
6715218822Sdim  int           len;
6716218822Sdim  int           symlen;
6717218822Sdim  bfd_vma       a;
6718218822Sdim  bfd_vma       b;
6719218822Sdim  const int     bufsz = 4096;
6720218822Sdim  char          symbuf [bufsz];
6721218822Sdim  const char *  symend;
6722218822Sdim  bfd_boolean   symbol_is_section = FALSE;
6723218822Sdim
6724218822Sdim  len = strlen (sym);
6725218822Sdim  symend = sym + len;
6726218822Sdim
6727218822Sdim  if (len < 1 || len > bufsz)
6728218822Sdim    {
6729218822Sdim      bfd_set_error (bfd_error_invalid_operation);
6730218822Sdim      return FALSE;
6731218822Sdim    }
6732218822Sdim
6733218822Sdim  switch (* sym)
6734218822Sdim    {
6735218822Sdim    case '.':
6736218822Sdim      * result = addr + section_offset;
6737218822Sdim      * advanced = sym + 1;
6738218822Sdim      return TRUE;
6739218822Sdim
6740218822Sdim    case '#':
6741218822Sdim      ++ sym;
6742218822Sdim      * result = strtoul (sym, advanced, 16);
6743218822Sdim      return TRUE;
6744218822Sdim
6745218822Sdim    case 'S':
6746218822Sdim      symbol_is_section = TRUE;
6747218822Sdim    case 's':
6748218822Sdim      ++ sym;
6749218822Sdim      symlen = strtol (sym, &sym, 10);
6750218822Sdim      ++ sym; /* Skip the trailing ':'.  */
6751218822Sdim
6752218822Sdim      if ((symend < sym) || ((symlen + 1) > bufsz))
6753218822Sdim	{
6754218822Sdim	  bfd_set_error (bfd_error_invalid_operation);
6755218822Sdim	  return FALSE;
6756218822Sdim	}
6757218822Sdim
6758218822Sdim      memcpy (symbuf, sym, symlen);
6759218822Sdim      symbuf [symlen] = '\0';
6760218822Sdim      * advanced = sym + symlen;
6761218822Sdim
6762218822Sdim      /* Is it always possible, with complex symbols, that gas "mis-guessed"
6763218822Sdim	 the symbol as a section, or vice-versa. so we're pretty liberal in our
6764218822Sdim	 interpretation here; section means "try section first", not "must be a
6765218822Sdim	 section", and likewise with symbol.  */
6766218822Sdim
6767218822Sdim      if (symbol_is_section)
6768218822Sdim	{
6769218822Sdim	  if ((resolve_section (symbuf, finfo->output_bfd->sections, result) != TRUE)
6770218822Sdim	      && (resolve_symbol (symbuf, input_bfd, finfo, result, locsymcount) != TRUE))
6771218822Sdim	    {
6772218822Sdim	      undefined_reference ("section", symbuf);
6773218822Sdim	      return FALSE;
6774218822Sdim	    }
6775218822Sdim	}
6776218822Sdim      else
6777218822Sdim	{
6778218822Sdim	  if ((resolve_symbol (symbuf, input_bfd, finfo, result, locsymcount) != TRUE)
6779218822Sdim	      && (resolve_section (symbuf, finfo->output_bfd->sections,
6780218822Sdim				   result) != TRUE))
6781218822Sdim	    {
6782218822Sdim	      undefined_reference ("symbol", symbuf);
6783218822Sdim	      return FALSE;
6784218822Sdim	    }
6785218822Sdim	}
6786218822Sdim
6787218822Sdim      return TRUE;
6788218822Sdim
6789218822Sdim      /* All that remains are operators.  */
6790218822Sdim
6791218822Sdim#define UNARY_OP(op)						\
6792218822Sdim  if (strncmp (sym, #op, strlen (#op)) == 0)			\
6793218822Sdim    {								\
6794218822Sdim      sym += strlen (#op);					\
6795218822Sdim      if (* sym == ':')						\
6796218822Sdim        ++ sym;							\
6797218822Sdim      if (eval_symbol (& a, sym, & sym, input_bfd, finfo, addr, \
6798218822Sdim                       section_offset, locsymcount, signed_p)   \
6799218822Sdim	                                             != TRUE)	\
6800218822Sdim        return FALSE;						\
6801218822Sdim      if (signed_p)                                             \
6802218822Sdim        * result = op ((signed)a);         			\
6803218822Sdim      else                                                      \
6804218822Sdim        * result = op a;                                        \
6805218822Sdim      * advanced = sym; 					\
6806218822Sdim      return TRUE;						\
6807218822Sdim    }
6808218822Sdim
6809218822Sdim#define BINARY_OP(op)						\
6810218822Sdim  if (strncmp (sym, #op, strlen (#op)) == 0)			\
6811218822Sdim    {								\
6812218822Sdim      sym += strlen (#op);					\
6813218822Sdim      if (* sym == ':')						\
6814218822Sdim        ++ sym;							\
6815218822Sdim      if (eval_symbol (& a, sym, & sym, input_bfd, finfo, addr, \
6816218822Sdim                       section_offset, locsymcount, signed_p)   \
6817218822Sdim                                                     != TRUE)	\
6818218822Sdim        return FALSE;						\
6819218822Sdim      ++ sym;							\
6820218822Sdim      if (eval_symbol (& b, sym, & sym, input_bfd, finfo, addr, \
6821218822Sdim                       section_offset, locsymcount, signed_p)   \
6822218822Sdim                                                     != TRUE)	\
6823218822Sdim        return FALSE;						\
6824218822Sdim      if (signed_p)                                             \
6825218822Sdim        * result = ((signed) a) op ((signed) b);	        \
6826218822Sdim      else                                                      \
6827218822Sdim        * result = a op b;                                      \
6828218822Sdim      * advanced = sym;						\
6829218822Sdim      return TRUE;						\
6830218822Sdim    }
6831218822Sdim
6832218822Sdim    default:
6833218822Sdim      UNARY_OP  (0-);
6834218822Sdim      BINARY_OP (<<);
6835218822Sdim      BINARY_OP (>>);
6836218822Sdim      BINARY_OP (==);
6837218822Sdim      BINARY_OP (!=);
6838218822Sdim      BINARY_OP (<=);
6839218822Sdim      BINARY_OP (>=);
6840218822Sdim      BINARY_OP (&&);
6841218822Sdim      BINARY_OP (||);
6842218822Sdim      UNARY_OP  (~);
6843218822Sdim      UNARY_OP  (!);
6844218822Sdim      BINARY_OP (*);
6845218822Sdim      BINARY_OP (/);
6846218822Sdim      BINARY_OP (%);
6847218822Sdim      BINARY_OP (^);
6848218822Sdim      BINARY_OP (|);
6849218822Sdim      BINARY_OP (&);
6850218822Sdim      BINARY_OP (+);
6851218822Sdim      BINARY_OP (-);
6852218822Sdim      BINARY_OP (<);
6853218822Sdim      BINARY_OP (>);
6854218822Sdim#undef UNARY_OP
6855218822Sdim#undef BINARY_OP
6856218822Sdim      _bfd_error_handler (_("unknown operator '%c' in complex symbol"), * sym);
6857218822Sdim      bfd_set_error (bfd_error_invalid_operation);
6858218822Sdim      return FALSE;
6859218822Sdim    }
6860218822Sdim}
6861218822Sdim
6862218822Sdim/* Entry point to evaluator, called from elf_link_input_bfd.  */
6863218822Sdim
6864218822Sdimstatic bfd_boolean
6865218822Sdimevaluate_complex_relocation_symbols (bfd * input_bfd,
6866218822Sdim				     struct elf_final_link_info * finfo,
6867218822Sdim				     size_t locsymcount)
6868218822Sdim{
6869218822Sdim  const struct elf_backend_data * bed;
6870218822Sdim  Elf_Internal_Shdr *             symtab_hdr;
6871218822Sdim  struct elf_link_hash_entry **   sym_hashes;
6872218822Sdim  asection *                      reloc_sec;
6873218822Sdim  bfd_boolean                     result = TRUE;
6874218822Sdim
6875218822Sdim  /* For each section, we're going to check and see if it has any
6876218822Sdim     complex relocations, and we're going to evaluate any of them
6877218822Sdim     we can.  */
6878218822Sdim
6879218822Sdim  if (finfo->info->relocatable)
6880218822Sdim    return TRUE;
6881218822Sdim
6882218822Sdim  symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
6883218822Sdim  sym_hashes = elf_sym_hashes (input_bfd);
6884218822Sdim  bed = get_elf_backend_data (input_bfd);
6885218822Sdim
6886218822Sdim  for (reloc_sec = input_bfd->sections; reloc_sec; reloc_sec = reloc_sec->next)
6887218822Sdim    {
6888218822Sdim      Elf_Internal_Rela * internal_relocs;
6889218822Sdim      unsigned long i;
6890218822Sdim
6891218822Sdim      /* This section was omitted from the link.  */
6892218822Sdim      if (! reloc_sec->linker_mark)
6893218822Sdim	continue;
6894218822Sdim
6895218822Sdim      /* Only process sections containing relocs.  */
6896218822Sdim      if ((reloc_sec->flags & SEC_RELOC) == 0)
6897218822Sdim	continue;
6898218822Sdim
6899218822Sdim      if (reloc_sec->reloc_count == 0)
6900218822Sdim	continue;
6901218822Sdim
6902218822Sdim      /* Read in the relocs for this section.  */
6903218822Sdim      internal_relocs
6904218822Sdim	= _bfd_elf_link_read_relocs (input_bfd, reloc_sec, NULL,
6905218822Sdim				     (Elf_Internal_Rela *) NULL,
6906218822Sdim				     FALSE);
6907218822Sdim      if (internal_relocs == NULL)
6908218822Sdim	continue;
6909218822Sdim
6910218822Sdim      for (i = reloc_sec->reloc_count; i--;)
6911218822Sdim	{
6912218822Sdim	  Elf_Internal_Rela * rel;
6913218822Sdim	  char * sym_name;
6914218822Sdim	  bfd_vma index;
6915218822Sdim	  Elf_Internal_Sym * sym;
6916218822Sdim	  bfd_vma result;
6917218822Sdim	  bfd_vma section_offset;
6918218822Sdim	  bfd_vma addr;
6919218822Sdim	  int signed_p = 0;
6920218822Sdim
6921218822Sdim	  rel = internal_relocs + i;
6922218822Sdim	  section_offset = reloc_sec->output_section->vma
6923218822Sdim	    + reloc_sec->output_offset;
6924218822Sdim	  addr = rel->r_offset;
6925218822Sdim
6926218822Sdim	  index = ELF32_R_SYM (rel->r_info);
6927218822Sdim	  if (bed->s->arch_size == 64)
6928218822Sdim	    index >>= 24;
6929218822Sdim
6930218822Sdim	  if (index == STN_UNDEF)
6931218822Sdim	    continue;
6932218822Sdim
6933218822Sdim	  if (index < locsymcount)
6934218822Sdim	    {
6935218822Sdim	      /* The symbol is local.  */
6936218822Sdim	      sym = finfo->internal_syms + index;
6937218822Sdim
6938218822Sdim	      /* We're only processing STT_RELC or STT_SRELC type symbols.  */
6939218822Sdim	      if ((ELF_ST_TYPE (sym->st_info) != STT_RELC) &&
6940218822Sdim		  (ELF_ST_TYPE (sym->st_info) != STT_SRELC))
6941218822Sdim		continue;
6942218822Sdim
6943218822Sdim	      sym_name = bfd_elf_string_from_elf_section
6944218822Sdim		(input_bfd, symtab_hdr->sh_link, sym->st_name);
6945218822Sdim
6946218822Sdim	      signed_p = (ELF_ST_TYPE (sym->st_info) == STT_SRELC);
6947218822Sdim	    }
6948218822Sdim	  else
6949218822Sdim	    {
6950218822Sdim	      /* The symbol is global.  */
6951218822Sdim	      struct elf_link_hash_entry * h;
6952218822Sdim
6953218822Sdim	      if (elf_bad_symtab (input_bfd))
6954218822Sdim		continue;
6955218822Sdim
6956218822Sdim	      h = sym_hashes [index - locsymcount];
6957218822Sdim	      while (   h->root.type == bfd_link_hash_indirect
6958218822Sdim		     || h->root.type == bfd_link_hash_warning)
6959218822Sdim		h = (struct elf_link_hash_entry *) h->root.u.i.link;
6960218822Sdim
6961218822Sdim	      if (h->type != STT_RELC && h->type != STT_SRELC)
6962218822Sdim		continue;
6963218822Sdim
6964218822Sdim	      signed_p = (h->type == STT_SRELC);
6965218822Sdim	      sym_name = (char *) h->root.root.string;
6966218822Sdim	    }
6967218822Sdim#ifdef DEBUG
6968218822Sdim	  printf ("Encountered a complex symbol!");
6969218822Sdim	  printf (" (input_bfd %s, section %s, reloc %ld\n",
6970218822Sdim		  input_bfd->filename, reloc_sec->name, i);
6971218822Sdim	  printf (" symbol: idx  %8.8lx, name %s\n",
6972218822Sdim		  index, sym_name);
6973218822Sdim	  printf (" reloc : info %8.8lx, addr %8.8lx\n",
6974218822Sdim		  rel->r_info, addr);
6975218822Sdim	  printf (" Evaluating '%s' ...\n ", sym_name);
6976218822Sdim#endif
6977218822Sdim	  if (eval_symbol (& result, sym_name, & sym_name, input_bfd,
6978218822Sdim			   finfo, addr, section_offset, locsymcount,
6979218822Sdim			   signed_p))
6980218822Sdim	    /* Symbol evaluated OK.  Update to absolute value.  */
6981218822Sdim	    set_symbol_value (input_bfd, finfo, index, result);
6982218822Sdim
6983218822Sdim	  else
6984218822Sdim	    result = FALSE;
6985218822Sdim	}
6986218822Sdim
6987218822Sdim      if (internal_relocs != elf_section_data (reloc_sec)->relocs)
6988218822Sdim	free (internal_relocs);
6989218822Sdim    }
6990218822Sdim
6991218822Sdim  /* If nothing went wrong, then we adjusted
6992218822Sdim     everything we wanted to adjust.  */
6993218822Sdim  return result;
6994218822Sdim}
6995218822Sdim
6996218822Sdimstatic void
6997218822Sdimput_value (bfd_vma        size,
6998218822Sdim	   unsigned long  chunksz,
6999218822Sdim	   bfd *          input_bfd,
7000218822Sdim	   bfd_vma        x,
7001218822Sdim	   bfd_byte *     location)
7002218822Sdim{
7003218822Sdim  location += (size - chunksz);
7004218822Sdim
7005218822Sdim  for (; size; size -= chunksz, location -= chunksz, x >>= (chunksz * 8))
7006218822Sdim    {
7007218822Sdim      switch (chunksz)
7008218822Sdim	{
7009218822Sdim	default:
7010218822Sdim	case 0:
7011218822Sdim	  abort ();
7012218822Sdim	case 1:
7013218822Sdim	  bfd_put_8 (input_bfd, x, location);
7014218822Sdim	  break;
7015218822Sdim	case 2:
7016218822Sdim	  bfd_put_16 (input_bfd, x, location);
7017218822Sdim	  break;
7018218822Sdim	case 4:
7019218822Sdim	  bfd_put_32 (input_bfd, x, location);
7020218822Sdim	  break;
7021218822Sdim	case 8:
7022218822Sdim#ifdef BFD64
7023218822Sdim	  bfd_put_64 (input_bfd, x, location);
7024218822Sdim#else
7025218822Sdim	  abort ();
7026218822Sdim#endif
7027218822Sdim	  break;
7028218822Sdim	}
7029218822Sdim    }
7030218822Sdim}
7031218822Sdim
7032218822Sdimstatic bfd_vma
7033218822Sdimget_value (bfd_vma        size,
7034218822Sdim	   unsigned long  chunksz,
7035218822Sdim	   bfd *          input_bfd,
7036218822Sdim	   bfd_byte *     location)
7037218822Sdim{
7038218822Sdim  bfd_vma x = 0;
7039218822Sdim
7040218822Sdim  for (; size; size -= chunksz, location += chunksz)
7041218822Sdim    {
7042218822Sdim      switch (chunksz)
7043218822Sdim	{
7044218822Sdim	default:
7045218822Sdim	case 0:
7046218822Sdim	  abort ();
7047218822Sdim	case 1:
7048218822Sdim	  x = (x << (8 * chunksz)) | bfd_get_8 (input_bfd, location);
7049218822Sdim	  break;
7050218822Sdim	case 2:
7051218822Sdim	  x = (x << (8 * chunksz)) | bfd_get_16 (input_bfd, location);
7052218822Sdim	  break;
7053218822Sdim	case 4:
7054218822Sdim	  x = (x << (8 * chunksz)) | bfd_get_32 (input_bfd, location);
7055218822Sdim	  break;
7056218822Sdim	case 8:
7057218822Sdim#ifdef BFD64
7058218822Sdim	  x = (x << (8 * chunksz)) | bfd_get_64 (input_bfd, location);
7059218822Sdim#else
7060218822Sdim	  abort ();
7061218822Sdim#endif
7062218822Sdim	  break;
7063218822Sdim	}
7064218822Sdim    }
7065218822Sdim  return x;
7066218822Sdim}
7067218822Sdim
7068218822Sdimstatic void
7069218822Sdimdecode_complex_addend
7070218822Sdim    (unsigned long * start,   /* in bits */
7071218822Sdim     unsigned long * oplen,   /* in bits */
7072218822Sdim     unsigned long * len,     /* in bits */
7073218822Sdim     unsigned long * wordsz,  /* in bytes */
7074218822Sdim     unsigned long * chunksz,  /* in bytes */
7075218822Sdim     unsigned long * lsb0_p,
7076218822Sdim     unsigned long * signed_p,
7077218822Sdim     unsigned long * trunc_p,
7078218822Sdim     unsigned long encoded)
7079218822Sdim{
7080218822Sdim  * start     =  encoded        & 0x3F;
7081218822Sdim  * len       = (encoded >>  6) & 0x3F;
7082218822Sdim  * oplen     = (encoded >> 12) & 0x3F;
7083218822Sdim  * wordsz    = (encoded >> 18) & 0xF;
7084218822Sdim  * chunksz   = (encoded >> 22) & 0xF;
7085218822Sdim  * lsb0_p    = (encoded >> 27) & 1;
7086218822Sdim  * signed_p  = (encoded >> 28) & 1;
7087218822Sdim  * trunc_p   = (encoded >> 29) & 1;
7088218822Sdim}
7089218822Sdim
7090218822Sdimvoid
7091218822Sdimbfd_elf_perform_complex_relocation
7092218822Sdim    (bfd *                   output_bfd ATTRIBUTE_UNUSED,
7093218822Sdim     struct bfd_link_info *  info,
7094218822Sdim     bfd *                   input_bfd,
7095218822Sdim     asection *              input_section,
7096218822Sdim     bfd_byte *              contents,
7097218822Sdim     Elf_Internal_Rela *     rel,
7098218822Sdim     Elf_Internal_Sym *      local_syms,
7099218822Sdim     asection **             local_sections)
7100218822Sdim{
7101218822Sdim  const struct elf_backend_data * bed;
7102218822Sdim  Elf_Internal_Shdr * symtab_hdr;
7103218822Sdim  asection * sec;
7104218822Sdim  bfd_vma relocation = 0, shift, x;
7105218822Sdim  bfd_vma r_symndx;
7106218822Sdim  bfd_vma mask;
7107218822Sdim  unsigned long start, oplen, len, wordsz,
7108218822Sdim    chunksz, lsb0_p, signed_p, trunc_p;
7109218822Sdim
7110218822Sdim  /*  Perform this reloc, since it is complex.
7111218822Sdim      (this is not to say that it necessarily refers to a complex
7112218822Sdim      symbol; merely that it is a self-describing CGEN based reloc.
7113218822Sdim      i.e. the addend has the complete reloc information (bit start, end,
7114218822Sdim      word size, etc) encoded within it.).  */
7115218822Sdim  r_symndx = ELF32_R_SYM (rel->r_info);
7116218822Sdim  bed = get_elf_backend_data (input_bfd);
7117218822Sdim  if (bed->s->arch_size == 64)
7118218822Sdim    r_symndx >>= 24;
7119218822Sdim
7120218822Sdim#ifdef DEBUG
7121218822Sdim  printf ("Performing complex relocation %ld...\n", r_symndx);
7122218822Sdim#endif
7123218822Sdim
7124218822Sdim  symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
7125218822Sdim  if (r_symndx < symtab_hdr->sh_info)
7126218822Sdim    {
7127218822Sdim      /* The symbol is local.  */
7128218822Sdim      Elf_Internal_Sym * sym;
7129218822Sdim
7130218822Sdim      sym = local_syms + r_symndx;
7131218822Sdim      sec = local_sections [r_symndx];
7132218822Sdim      relocation = sym->st_value;
7133218822Sdim      if (sym->st_shndx > SHN_UNDEF &&
7134218822Sdim	  sym->st_shndx < SHN_LORESERVE)
7135218822Sdim	relocation += (sec->output_offset +
7136218822Sdim		       sec->output_section->vma);
7137218822Sdim    }
7138218822Sdim  else
7139218822Sdim    {
7140218822Sdim      /* The symbol is global.  */
7141218822Sdim      struct elf_link_hash_entry **sym_hashes;
7142218822Sdim      struct elf_link_hash_entry * h;
7143218822Sdim
7144218822Sdim      sym_hashes = elf_sym_hashes (input_bfd);
7145218822Sdim      h = sym_hashes [r_symndx];
7146218822Sdim
7147218822Sdim      while (h->root.type == bfd_link_hash_indirect
7148218822Sdim	     || h->root.type == bfd_link_hash_warning)
7149218822Sdim	h = (struct elf_link_hash_entry *) h->root.u.i.link;
7150218822Sdim
7151218822Sdim      if (h->root.type == bfd_link_hash_defined
7152218822Sdim	  || h->root.type == bfd_link_hash_defweak)
7153218822Sdim	{
7154218822Sdim	  sec = h->root.u.def.section;
7155218822Sdim	  relocation = h->root.u.def.value;
7156218822Sdim
7157218822Sdim	  if (! bfd_is_abs_section (sec))
7158218822Sdim	    relocation += (sec->output_section->vma
7159218822Sdim			   + sec->output_offset);
7160218822Sdim	}
7161218822Sdim      if (h->root.type == bfd_link_hash_undefined
7162218822Sdim	  && !((*info->callbacks->undefined_symbol)
7163218822Sdim	       (info, h->root.root.string, input_bfd,
7164218822Sdim		input_section, rel->r_offset,
7165218822Sdim		info->unresolved_syms_in_objects == RM_GENERATE_ERROR
7166218822Sdim		|| ELF_ST_VISIBILITY (h->other))))
7167218822Sdim	return;
7168218822Sdim    }
7169218822Sdim
7170218822Sdim  decode_complex_addend (& start, & oplen, & len, & wordsz,
7171218822Sdim			 & chunksz, & lsb0_p, & signed_p,
7172218822Sdim			 & trunc_p, rel->r_addend);
7173218822Sdim
7174218822Sdim  mask = (((1L << (len - 1)) - 1) << 1) | 1;
7175218822Sdim
7176218822Sdim  if (lsb0_p)
7177218822Sdim    shift = (start + 1) - len;
7178218822Sdim  else
7179218822Sdim    shift = (8 * wordsz) - (start + len);
7180218822Sdim
7181218822Sdim  x = get_value (wordsz, chunksz, input_bfd, contents + rel->r_offset);
7182218822Sdim
7183218822Sdim#ifdef DEBUG
7184218822Sdim  printf ("Doing complex reloc: "
7185218822Sdim	  "lsb0? %ld, signed? %ld, trunc? %ld, wordsz %ld, "
7186218822Sdim	  "chunksz %ld, start %ld, len %ld, oplen %ld\n"
7187218822Sdim	  "    dest: %8.8lx, mask: %8.8lx, reloc: %8.8lx\n",
7188218822Sdim	  lsb0_p, signed_p, trunc_p, wordsz, chunksz, start, len,
7189218822Sdim	  oplen, x, mask,  relocation);
7190218822Sdim#endif
7191218822Sdim
7192218822Sdim  if (! trunc_p)
7193218822Sdim    {
7194218822Sdim      /* Now do an overflow check.  */
7195218822Sdim      if (bfd_check_overflow ((signed_p ?
7196218822Sdim			       complain_overflow_signed :
7197218822Sdim			       complain_overflow_unsigned),
7198218822Sdim			      len, 0, (8 * wordsz),
7199218822Sdim			      relocation) == bfd_reloc_overflow)
7200218822Sdim	(*_bfd_error_handler)
7201218822Sdim	  ("%s (%s + 0x%lx): relocation overflow: 0x%lx %sdoes not fit "
7202218822Sdim	   "within 0x%lx",
7203218822Sdim	   input_bfd->filename, input_section->name, rel->r_offset,
7204218822Sdim	   relocation, (signed_p ? "(signed) " : ""), mask);
7205218822Sdim    }
7206218822Sdim
7207218822Sdim  /* Do the deed.  */
7208218822Sdim  x = (x & ~(mask << shift)) | ((relocation & mask) << shift);
7209218822Sdim
7210218822Sdim#ifdef DEBUG
7211218822Sdim  printf ("           relocation: %8.8lx\n"
7212218822Sdim	  "         shifted mask: %8.8lx\n"
7213218822Sdim	  " shifted/masked reloc: %8.8lx\n"
7214218822Sdim	  "               result: %8.8lx\n",
7215218822Sdim	  relocation, (mask << shift),
7216218822Sdim	  ((relocation & mask) << shift), x);
7217218822Sdim#endif
7218218822Sdim  put_value (wordsz, chunksz, input_bfd, x, contents + rel->r_offset);
7219218822Sdim}
7220218822Sdim
7221130561Sobrien/* When performing a relocatable link, the input relocations are
7222130561Sobrien   preserved.  But, if they reference global symbols, the indices
7223130561Sobrien   referenced must be updated.  Update all the relocations in
7224130561Sobrien   REL_HDR (there are COUNT of them), using the data in REL_HASH.  */
7225130561Sobrien
7226130561Sobrienstatic void
7227130561Sobrienelf_link_adjust_relocs (bfd *abfd,
7228130561Sobrien			Elf_Internal_Shdr *rel_hdr,
7229130561Sobrien			unsigned int count,
7230130561Sobrien			struct elf_link_hash_entry **rel_hash)
7231130561Sobrien{
7232130561Sobrien  unsigned int i;
7233130561Sobrien  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
7234130561Sobrien  bfd_byte *erela;
7235130561Sobrien  void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *);
7236130561Sobrien  void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
7237130561Sobrien  bfd_vma r_type_mask;
7238130561Sobrien  int r_sym_shift;
7239130561Sobrien
7240130561Sobrien  if (rel_hdr->sh_entsize == bed->s->sizeof_rel)
7241130561Sobrien    {
7242130561Sobrien      swap_in = bed->s->swap_reloc_in;
7243130561Sobrien      swap_out = bed->s->swap_reloc_out;
7244130561Sobrien    }
7245130561Sobrien  else if (rel_hdr->sh_entsize == bed->s->sizeof_rela)
7246130561Sobrien    {
7247130561Sobrien      swap_in = bed->s->swap_reloca_in;
7248130561Sobrien      swap_out = bed->s->swap_reloca_out;
7249130561Sobrien    }
7250130561Sobrien  else
7251130561Sobrien    abort ();
7252130561Sobrien
7253130561Sobrien  if (bed->s->int_rels_per_ext_rel > MAX_INT_RELS_PER_EXT_REL)
7254130561Sobrien    abort ();
7255130561Sobrien
7256130561Sobrien  if (bed->s->arch_size == 32)
7257130561Sobrien    {
7258130561Sobrien      r_type_mask = 0xff;
7259130561Sobrien      r_sym_shift = 8;
7260130561Sobrien    }
7261130561Sobrien  else
7262130561Sobrien    {
7263130561Sobrien      r_type_mask = 0xffffffff;
7264130561Sobrien      r_sym_shift = 32;
7265130561Sobrien    }
7266130561Sobrien
7267130561Sobrien  erela = rel_hdr->contents;
7268130561Sobrien  for (i = 0; i < count; i++, rel_hash++, erela += rel_hdr->sh_entsize)
7269130561Sobrien    {
7270130561Sobrien      Elf_Internal_Rela irela[MAX_INT_RELS_PER_EXT_REL];
7271130561Sobrien      unsigned int j;
7272130561Sobrien
7273130561Sobrien      if (*rel_hash == NULL)
7274130561Sobrien	continue;
7275130561Sobrien
7276130561Sobrien      BFD_ASSERT ((*rel_hash)->indx >= 0);
7277130561Sobrien
7278130561Sobrien      (*swap_in) (abfd, erela, irela);
7279130561Sobrien      for (j = 0; j < bed->s->int_rels_per_ext_rel; j++)
7280130561Sobrien	irela[j].r_info = ((bfd_vma) (*rel_hash)->indx << r_sym_shift
7281130561Sobrien			   | (irela[j].r_info & r_type_mask));
7282130561Sobrien      (*swap_out) (abfd, irela, erela);
7283130561Sobrien    }
7284130561Sobrien}
7285130561Sobrien
7286130561Sobrienstruct elf_link_sort_rela
7287130561Sobrien{
7288130561Sobrien  union {
7289130561Sobrien    bfd_vma offset;
7290130561Sobrien    bfd_vma sym_mask;
7291130561Sobrien  } u;
7292130561Sobrien  enum elf_reloc_type_class type;
7293130561Sobrien  /* We use this as an array of size int_rels_per_ext_rel.  */
7294130561Sobrien  Elf_Internal_Rela rela[1];
7295130561Sobrien};
7296130561Sobrien
7297130561Sobrienstatic int
7298130561Sobrienelf_link_sort_cmp1 (const void *A, const void *B)
7299130561Sobrien{
7300130561Sobrien  const struct elf_link_sort_rela *a = A;
7301130561Sobrien  const struct elf_link_sort_rela *b = B;
7302130561Sobrien  int relativea, relativeb;
7303130561Sobrien
7304130561Sobrien  relativea = a->type == reloc_class_relative;
7305130561Sobrien  relativeb = b->type == reloc_class_relative;
7306130561Sobrien
7307130561Sobrien  if (relativea < relativeb)
7308130561Sobrien    return 1;
7309130561Sobrien  if (relativea > relativeb)
7310130561Sobrien    return -1;
7311130561Sobrien  if ((a->rela->r_info & a->u.sym_mask) < (b->rela->r_info & b->u.sym_mask))
7312130561Sobrien    return -1;
7313130561Sobrien  if ((a->rela->r_info & a->u.sym_mask) > (b->rela->r_info & b->u.sym_mask))
7314130561Sobrien    return 1;
7315130561Sobrien  if (a->rela->r_offset < b->rela->r_offset)
7316130561Sobrien    return -1;
7317130561Sobrien  if (a->rela->r_offset > b->rela->r_offset)
7318130561Sobrien    return 1;
7319130561Sobrien  return 0;
7320130561Sobrien}
7321130561Sobrien
7322130561Sobrienstatic int
7323130561Sobrienelf_link_sort_cmp2 (const void *A, const void *B)
7324130561Sobrien{
7325130561Sobrien  const struct elf_link_sort_rela *a = A;
7326130561Sobrien  const struct elf_link_sort_rela *b = B;
7327130561Sobrien  int copya, copyb;
7328130561Sobrien
7329130561Sobrien  if (a->u.offset < b->u.offset)
7330130561Sobrien    return -1;
7331130561Sobrien  if (a->u.offset > b->u.offset)
7332130561Sobrien    return 1;
7333130561Sobrien  copya = (a->type == reloc_class_copy) * 2 + (a->type == reloc_class_plt);
7334130561Sobrien  copyb = (b->type == reloc_class_copy) * 2 + (b->type == reloc_class_plt);
7335130561Sobrien  if (copya < copyb)
7336130561Sobrien    return -1;
7337130561Sobrien  if (copya > copyb)
7338130561Sobrien    return 1;
7339130561Sobrien  if (a->rela->r_offset < b->rela->r_offset)
7340130561Sobrien    return -1;
7341130561Sobrien  if (a->rela->r_offset > b->rela->r_offset)
7342130561Sobrien    return 1;
7343130561Sobrien  return 0;
7344130561Sobrien}
7345130561Sobrien
7346130561Sobrienstatic size_t
7347130561Sobrienelf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec)
7348130561Sobrien{
7349218822Sdim  asection *dynamic_relocs;
7350218822Sdim  asection *rela_dyn;
7351218822Sdim  asection *rel_dyn;
7352130561Sobrien  bfd_size_type count, size;
7353130561Sobrien  size_t i, ret, sort_elt, ext_size;
7354130561Sobrien  bfd_byte *sort, *s_non_relative, *p;
7355130561Sobrien  struct elf_link_sort_rela *sq;
7356130561Sobrien  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
7357130561Sobrien  int i2e = bed->s->int_rels_per_ext_rel;
7358130561Sobrien  void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *);
7359130561Sobrien  void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
7360130561Sobrien  struct bfd_link_order *lo;
7361130561Sobrien  bfd_vma r_sym_mask;
7362218822Sdim  bfd_boolean use_rela;
7363130561Sobrien
7364218822Sdim  /* Find a dynamic reloc section.  */
7365218822Sdim  rela_dyn = bfd_get_section_by_name (abfd, ".rela.dyn");
7366218822Sdim  rel_dyn  = bfd_get_section_by_name (abfd, ".rel.dyn");
7367218822Sdim  if (rela_dyn != NULL && rela_dyn->size > 0
7368218822Sdim      && rel_dyn != NULL && rel_dyn->size > 0)
7369130561Sobrien    {
7370218822Sdim      bfd_boolean use_rela_initialised = FALSE;
7371218822Sdim
7372218822Sdim      /* This is just here to stop gcc from complaining.
7373218822Sdim	 It's initialization checking code is not perfect.  */
7374218822Sdim      use_rela = TRUE;
7375218822Sdim
7376218822Sdim      /* Both sections are present.  Examine the sizes
7377218822Sdim	 of the indirect sections to help us choose.  */
7378218822Sdim      for (lo = rela_dyn->map_head.link_order; lo != NULL; lo = lo->next)
7379218822Sdim	if (lo->type == bfd_indirect_link_order)
7380218822Sdim	  {
7381218822Sdim	    asection *o = lo->u.indirect.section;
7382218822Sdim
7383218822Sdim	    if ((o->size % bed->s->sizeof_rela) == 0)
7384218822Sdim	      {
7385218822Sdim		if ((o->size % bed->s->sizeof_rel) == 0)
7386218822Sdim		  /* Section size is divisible by both rel and rela sizes.
7387218822Sdim		     It is of no help to us.  */
7388218822Sdim		  ;
7389218822Sdim		else
7390218822Sdim		  {
7391218822Sdim		    /* Section size is only divisible by rela.  */
7392218822Sdim		    if (use_rela_initialised && (use_rela == FALSE))
7393218822Sdim		      {
7394218822Sdim			_bfd_error_handler
7395218822Sdim			  (_("%B: Unable to sort relocs - they are in more than one size"), abfd);
7396218822Sdim			bfd_set_error (bfd_error_invalid_operation);
7397218822Sdim			return 0;
7398218822Sdim		      }
7399218822Sdim		    else
7400218822Sdim		      {
7401218822Sdim			use_rela = TRUE;
7402218822Sdim			use_rela_initialised = TRUE;
7403218822Sdim		      }
7404218822Sdim		  }
7405218822Sdim	      }
7406218822Sdim	    else if ((o->size % bed->s->sizeof_rel) == 0)
7407218822Sdim	      {
7408218822Sdim		/* Section size is only divisible by rel.  */
7409218822Sdim		if (use_rela_initialised && (use_rela == TRUE))
7410218822Sdim		  {
7411218822Sdim		    _bfd_error_handler
7412218822Sdim		      (_("%B: Unable to sort relocs - they are in more than one size"), abfd);
7413218822Sdim		    bfd_set_error (bfd_error_invalid_operation);
7414218822Sdim		    return 0;
7415218822Sdim		  }
7416218822Sdim		else
7417218822Sdim		  {
7418218822Sdim		    use_rela = FALSE;
7419218822Sdim		    use_rela_initialised = TRUE;
7420218822Sdim		  }
7421218822Sdim	      }
7422218822Sdim	    else
7423218822Sdim	      {
7424218822Sdim		/* The section size is not divisible by either - something is wrong.  */
7425218822Sdim		_bfd_error_handler
7426218822Sdim		  (_("%B: Unable to sort relocs - they are of an unknown size"), abfd);
7427218822Sdim		bfd_set_error (bfd_error_invalid_operation);
7428218822Sdim		return 0;
7429218822Sdim	      }
7430218822Sdim	  }
7431218822Sdim
7432218822Sdim      for (lo = rel_dyn->map_head.link_order; lo != NULL; lo = lo->next)
7433218822Sdim	if (lo->type == bfd_indirect_link_order)
7434218822Sdim	  {
7435218822Sdim	    asection *o = lo->u.indirect.section;
7436218822Sdim
7437218822Sdim	    if ((o->size % bed->s->sizeof_rela) == 0)
7438218822Sdim	      {
7439218822Sdim		if ((o->size % bed->s->sizeof_rel) == 0)
7440218822Sdim		  /* Section size is divisible by both rel and rela sizes.
7441218822Sdim		     It is of no help to us.  */
7442218822Sdim		  ;
7443218822Sdim		else
7444218822Sdim		  {
7445218822Sdim		    /* Section size is only divisible by rela.  */
7446218822Sdim		    if (use_rela_initialised && (use_rela == FALSE))
7447218822Sdim		      {
7448218822Sdim			_bfd_error_handler
7449218822Sdim			  (_("%B: Unable to sort relocs - they are in more than one size"), abfd);
7450218822Sdim			bfd_set_error (bfd_error_invalid_operation);
7451218822Sdim			return 0;
7452218822Sdim		      }
7453218822Sdim		    else
7454218822Sdim		      {
7455218822Sdim			use_rela = TRUE;
7456218822Sdim			use_rela_initialised = TRUE;
7457218822Sdim		      }
7458218822Sdim		  }
7459218822Sdim	      }
7460218822Sdim	    else if ((o->size % bed->s->sizeof_rel) == 0)
7461218822Sdim	      {
7462218822Sdim		/* Section size is only divisible by rel.  */
7463218822Sdim		if (use_rela_initialised && (use_rela == TRUE))
7464218822Sdim		  {
7465218822Sdim		    _bfd_error_handler
7466218822Sdim		      (_("%B: Unable to sort relocs - they are in more than one size"), abfd);
7467218822Sdim		    bfd_set_error (bfd_error_invalid_operation);
7468218822Sdim		    return 0;
7469218822Sdim		  }
7470218822Sdim		else
7471218822Sdim		  {
7472218822Sdim		    use_rela = FALSE;
7473218822Sdim		    use_rela_initialised = TRUE;
7474218822Sdim		  }
7475218822Sdim	      }
7476218822Sdim	    else
7477218822Sdim	      {
7478218822Sdim		/* The section size is not divisible by either - something is wrong.  */
7479218822Sdim		_bfd_error_handler
7480218822Sdim		  (_("%B: Unable to sort relocs - they are of an unknown size"), abfd);
7481218822Sdim		bfd_set_error (bfd_error_invalid_operation);
7482218822Sdim		return 0;
7483218822Sdim	      }
7484218822Sdim	  }
7485218822Sdim
7486218822Sdim      if (! use_rela_initialised)
7487218822Sdim	/* Make a guess.  */
7488218822Sdim	use_rela = TRUE;
7489130561Sobrien    }
7490218822Sdim  else if (rela_dyn != NULL && rela_dyn->size > 0)
7491218822Sdim    use_rela = TRUE;
7492218822Sdim  else if (rel_dyn != NULL && rel_dyn->size > 0)
7493218822Sdim    use_rela = FALSE;
7494130561Sobrien  else
7495218822Sdim    return 0;
7496218822Sdim
7497218822Sdim  if (use_rela)
7498130561Sobrien    {
7499218822Sdim      dynamic_relocs = rela_dyn;
7500130561Sobrien      ext_size = bed->s->sizeof_rela;
7501130561Sobrien      swap_in = bed->s->swap_reloca_in;
7502130561Sobrien      swap_out = bed->s->swap_reloca_out;
7503130561Sobrien    }
7504218822Sdim  else
7505218822Sdim    {
7506218822Sdim      dynamic_relocs = rel_dyn;
7507218822Sdim      ext_size = bed->s->sizeof_rel;
7508218822Sdim      swap_in = bed->s->swap_reloc_in;
7509218822Sdim      swap_out = bed->s->swap_reloc_out;
7510218822Sdim    }
7511130561Sobrien
7512130561Sobrien  size = 0;
7513218822Sdim  for (lo = dynamic_relocs->map_head.link_order; lo != NULL; lo = lo->next)
7514130561Sobrien    if (lo->type == bfd_indirect_link_order)
7515218822Sdim      size += lo->u.indirect.section->size;
7516130561Sobrien
7517218822Sdim  if (size != dynamic_relocs->size)
7518130561Sobrien    return 0;
7519130561Sobrien
7520130561Sobrien  sort_elt = (sizeof (struct elf_link_sort_rela)
7521130561Sobrien	      + (i2e - 1) * sizeof (Elf_Internal_Rela));
7522218822Sdim
7523218822Sdim  count = dynamic_relocs->size / ext_size;
7524130561Sobrien  sort = bfd_zmalloc (sort_elt * count);
7525218822Sdim
7526130561Sobrien  if (sort == NULL)
7527130561Sobrien    {
7528130561Sobrien      (*info->callbacks->warning)
7529130561Sobrien	(info, _("Not enough memory to sort relocations"), 0, abfd, 0, 0);
7530130561Sobrien      return 0;
7531130561Sobrien    }
7532130561Sobrien
7533130561Sobrien  if (bed->s->arch_size == 32)
7534130561Sobrien    r_sym_mask = ~(bfd_vma) 0xff;
7535130561Sobrien  else
7536130561Sobrien    r_sym_mask = ~(bfd_vma) 0xffffffff;
7537130561Sobrien
7538218822Sdim  for (lo = dynamic_relocs->map_head.link_order; lo != NULL; lo = lo->next)
7539130561Sobrien    if (lo->type == bfd_indirect_link_order)
7540130561Sobrien      {
7541130561Sobrien	bfd_byte *erel, *erelend;
7542130561Sobrien	asection *o = lo->u.indirect.section;
7543130561Sobrien
7544218822Sdim	if (o->contents == NULL && o->size != 0)
7545218822Sdim	  {
7546218822Sdim	    /* This is a reloc section that is being handled as a normal
7547218822Sdim	       section.  See bfd_section_from_shdr.  We can't combine
7548218822Sdim	       relocs in this case.  */
7549218822Sdim	    free (sort);
7550218822Sdim	    return 0;
7551218822Sdim	  }
7552130561Sobrien	erel = o->contents;
7553218822Sdim	erelend = o->contents + o->size;
7554130561Sobrien	p = sort + o->output_offset / ext_size * sort_elt;
7555218822Sdim
7556130561Sobrien	while (erel < erelend)
7557130561Sobrien	  {
7558130561Sobrien	    struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p;
7559218822Sdim
7560130561Sobrien	    (*swap_in) (abfd, erel, s->rela);
7561130561Sobrien	    s->type = (*bed->elf_backend_reloc_type_class) (s->rela);
7562130561Sobrien	    s->u.sym_mask = r_sym_mask;
7563130561Sobrien	    p += sort_elt;
7564130561Sobrien	    erel += ext_size;
7565130561Sobrien	  }
7566130561Sobrien      }
7567130561Sobrien
7568130561Sobrien  qsort (sort, count, sort_elt, elf_link_sort_cmp1);
7569130561Sobrien
7570130561Sobrien  for (i = 0, p = sort; i < count; i++, p += sort_elt)
7571130561Sobrien    {
7572130561Sobrien      struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p;
7573130561Sobrien      if (s->type != reloc_class_relative)
7574130561Sobrien	break;
7575130561Sobrien    }
7576130561Sobrien  ret = i;
7577130561Sobrien  s_non_relative = p;
7578130561Sobrien
7579130561Sobrien  sq = (struct elf_link_sort_rela *) s_non_relative;
7580130561Sobrien  for (; i < count; i++, p += sort_elt)
7581130561Sobrien    {
7582130561Sobrien      struct elf_link_sort_rela *sp = (struct elf_link_sort_rela *) p;
7583130561Sobrien      if (((sp->rela->r_info ^ sq->rela->r_info) & r_sym_mask) != 0)
7584130561Sobrien	sq = sp;
7585130561Sobrien      sp->u.offset = sq->rela->r_offset;
7586130561Sobrien    }
7587130561Sobrien
7588130561Sobrien  qsort (s_non_relative, count - ret, sort_elt, elf_link_sort_cmp2);
7589130561Sobrien
7590218822Sdim  for (lo = dynamic_relocs->map_head.link_order; lo != NULL; lo = lo->next)
7591130561Sobrien    if (lo->type == bfd_indirect_link_order)
7592130561Sobrien      {
7593130561Sobrien	bfd_byte *erel, *erelend;
7594130561Sobrien	asection *o = lo->u.indirect.section;
7595130561Sobrien
7596130561Sobrien	erel = o->contents;
7597218822Sdim	erelend = o->contents + o->size;
7598130561Sobrien	p = sort + o->output_offset / ext_size * sort_elt;
7599130561Sobrien	while (erel < erelend)
7600130561Sobrien	  {
7601130561Sobrien	    struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p;
7602130561Sobrien	    (*swap_out) (abfd, s->rela, erel);
7603130561Sobrien	    p += sort_elt;
7604130561Sobrien	    erel += ext_size;
7605130561Sobrien	  }
7606130561Sobrien      }
7607130561Sobrien
7608130561Sobrien  free (sort);
7609218822Sdim  *psec = dynamic_relocs;
7610130561Sobrien  return ret;
7611130561Sobrien}
7612130561Sobrien
7613130561Sobrien/* Flush the output symbols to the file.  */
7614130561Sobrien
7615130561Sobrienstatic bfd_boolean
7616130561Sobrienelf_link_flush_output_syms (struct elf_final_link_info *finfo,
7617130561Sobrien			    const struct elf_backend_data *bed)
7618130561Sobrien{
7619130561Sobrien  if (finfo->symbuf_count > 0)
7620130561Sobrien    {
7621130561Sobrien      Elf_Internal_Shdr *hdr;
7622130561Sobrien      file_ptr pos;
7623130561Sobrien      bfd_size_type amt;
7624130561Sobrien
7625130561Sobrien      hdr = &elf_tdata (finfo->output_bfd)->symtab_hdr;
7626130561Sobrien      pos = hdr->sh_offset + hdr->sh_size;
7627130561Sobrien      amt = finfo->symbuf_count * bed->s->sizeof_sym;
7628130561Sobrien      if (bfd_seek (finfo->output_bfd, pos, SEEK_SET) != 0
7629130561Sobrien	  || bfd_bwrite (finfo->symbuf, amt, finfo->output_bfd) != amt)
7630130561Sobrien	return FALSE;
7631130561Sobrien
7632130561Sobrien      hdr->sh_size += amt;
7633130561Sobrien      finfo->symbuf_count = 0;
7634130561Sobrien    }
7635130561Sobrien
7636130561Sobrien  return TRUE;
7637130561Sobrien}
7638130561Sobrien
7639130561Sobrien/* Add a symbol to the output symbol table.  */
7640130561Sobrien
7641130561Sobrienstatic bfd_boolean
7642130561Sobrienelf_link_output_sym (struct elf_final_link_info *finfo,
7643130561Sobrien		     const char *name,
7644130561Sobrien		     Elf_Internal_Sym *elfsym,
7645130561Sobrien		     asection *input_sec,
7646130561Sobrien		     struct elf_link_hash_entry *h)
7647130561Sobrien{
7648130561Sobrien  bfd_byte *dest;
7649130561Sobrien  Elf_External_Sym_Shndx *destshndx;
7650130561Sobrien  bfd_boolean (*output_symbol_hook)
7651130561Sobrien    (struct bfd_link_info *, const char *, Elf_Internal_Sym *, asection *,
7652130561Sobrien     struct elf_link_hash_entry *);
7653130561Sobrien  const struct elf_backend_data *bed;
7654130561Sobrien
7655130561Sobrien  bed = get_elf_backend_data (finfo->output_bfd);
7656130561Sobrien  output_symbol_hook = bed->elf_backend_link_output_symbol_hook;
7657130561Sobrien  if (output_symbol_hook != NULL)
7658130561Sobrien    {
7659130561Sobrien      if (! (*output_symbol_hook) (finfo->info, name, elfsym, input_sec, h))
7660130561Sobrien	return FALSE;
7661130561Sobrien    }
7662130561Sobrien
7663130561Sobrien  if (name == NULL || *name == '\0')
7664130561Sobrien    elfsym->st_name = 0;
7665130561Sobrien  else if (input_sec->flags & SEC_EXCLUDE)
7666130561Sobrien    elfsym->st_name = 0;
7667130561Sobrien  else
7668130561Sobrien    {
7669130561Sobrien      elfsym->st_name = (unsigned long) _bfd_stringtab_add (finfo->symstrtab,
7670130561Sobrien							    name, TRUE, FALSE);
7671130561Sobrien      if (elfsym->st_name == (unsigned long) -1)
7672130561Sobrien	return FALSE;
7673130561Sobrien    }
7674130561Sobrien
7675130561Sobrien  if (finfo->symbuf_count >= finfo->symbuf_size)
7676130561Sobrien    {
7677130561Sobrien      if (! elf_link_flush_output_syms (finfo, bed))
7678130561Sobrien	return FALSE;
7679130561Sobrien    }
7680130561Sobrien
7681130561Sobrien  dest = finfo->symbuf + finfo->symbuf_count * bed->s->sizeof_sym;
7682130561Sobrien  destshndx = finfo->symshndxbuf;
7683130561Sobrien  if (destshndx != NULL)
7684130561Sobrien    {
7685130561Sobrien      if (bfd_get_symcount (finfo->output_bfd) >= finfo->shndxbuf_size)
7686130561Sobrien	{
7687130561Sobrien	  bfd_size_type amt;
7688130561Sobrien
7689130561Sobrien	  amt = finfo->shndxbuf_size * sizeof (Elf_External_Sym_Shndx);
7690130561Sobrien	  finfo->symshndxbuf = destshndx = bfd_realloc (destshndx, amt * 2);
7691130561Sobrien	  if (destshndx == NULL)
7692130561Sobrien	    return FALSE;
7693130561Sobrien	  memset ((char *) destshndx + amt, 0, amt);
7694130561Sobrien	  finfo->shndxbuf_size *= 2;
7695130561Sobrien	}
7696130561Sobrien      destshndx += bfd_get_symcount (finfo->output_bfd);
7697130561Sobrien    }
7698130561Sobrien
7699130561Sobrien  bed->s->swap_symbol_out (finfo->output_bfd, elfsym, dest, destshndx);
7700130561Sobrien  finfo->symbuf_count += 1;
7701130561Sobrien  bfd_get_symcount (finfo->output_bfd) += 1;
7702130561Sobrien
7703130561Sobrien  return TRUE;
7704130561Sobrien}
7705130561Sobrien
7706218822Sdim/* Return TRUE if the dynamic symbol SYM in ABFD is supported.  */
7707218822Sdim
7708218822Sdimstatic bfd_boolean
7709218822Sdimcheck_dynsym (bfd *abfd, Elf_Internal_Sym *sym)
7710218822Sdim{
7711218822Sdim  if (sym->st_shndx > SHN_HIRESERVE)
7712218822Sdim    {
7713218822Sdim      /* The gABI doesn't support dynamic symbols in output sections
7714218822Sdim         beyond 64k.  */
7715218822Sdim      (*_bfd_error_handler)
7716218822Sdim	(_("%B: Too many sections: %d (>= %d)"),
7717218822Sdim	 abfd, bfd_count_sections (abfd), SHN_LORESERVE);
7718218822Sdim      bfd_set_error (bfd_error_nonrepresentable_section);
7719218822Sdim      return FALSE;
7720218822Sdim    }
7721218822Sdim  return TRUE;
7722218822Sdim}
7723218822Sdim
7724130561Sobrien/* For DSOs loaded in via a DT_NEEDED entry, emulate ld.so in
7725130561Sobrien   allowing an unsatisfied unversioned symbol in the DSO to match a
7726130561Sobrien   versioned symbol that would normally require an explicit version.
7727130561Sobrien   We also handle the case that a DSO references a hidden symbol
7728130561Sobrien   which may be satisfied by a versioned symbol in another DSO.  */
7729130561Sobrien
7730130561Sobrienstatic bfd_boolean
7731130561Sobrienelf_link_check_versioned_symbol (struct bfd_link_info *info,
7732130561Sobrien				 const struct elf_backend_data *bed,
7733130561Sobrien				 struct elf_link_hash_entry *h)
7734130561Sobrien{
7735130561Sobrien  bfd *abfd;
7736130561Sobrien  struct elf_link_loaded_list *loaded;
7737130561Sobrien
7738130561Sobrien  if (!is_elf_hash_table (info->hash))
7739130561Sobrien    return FALSE;
7740130561Sobrien
7741130561Sobrien  switch (h->root.type)
7742130561Sobrien    {
7743130561Sobrien    default:
7744130561Sobrien      abfd = NULL;
7745130561Sobrien      break;
7746130561Sobrien
7747130561Sobrien    case bfd_link_hash_undefined:
7748130561Sobrien    case bfd_link_hash_undefweak:
7749130561Sobrien      abfd = h->root.u.undef.abfd;
7750130561Sobrien      if ((abfd->flags & DYNAMIC) == 0
7751218822Sdim	  || (elf_dyn_lib_class (abfd) & DYN_DT_NEEDED) == 0)
7752130561Sobrien	return FALSE;
7753130561Sobrien      break;
7754130561Sobrien
7755130561Sobrien    case bfd_link_hash_defined:
7756130561Sobrien    case bfd_link_hash_defweak:
7757130561Sobrien      abfd = h->root.u.def.section->owner;
7758130561Sobrien      break;
7759130561Sobrien
7760130561Sobrien    case bfd_link_hash_common:
7761130561Sobrien      abfd = h->root.u.c.p->section->owner;
7762130561Sobrien      break;
7763130561Sobrien    }
7764130561Sobrien  BFD_ASSERT (abfd != NULL);
7765130561Sobrien
7766130561Sobrien  for (loaded = elf_hash_table (info)->loaded;
7767130561Sobrien       loaded != NULL;
7768130561Sobrien       loaded = loaded->next)
7769130561Sobrien    {
7770130561Sobrien      bfd *input;
7771130561Sobrien      Elf_Internal_Shdr *hdr;
7772130561Sobrien      bfd_size_type symcount;
7773130561Sobrien      bfd_size_type extsymcount;
7774130561Sobrien      bfd_size_type extsymoff;
7775130561Sobrien      Elf_Internal_Shdr *versymhdr;
7776130561Sobrien      Elf_Internal_Sym *isym;
7777130561Sobrien      Elf_Internal_Sym *isymend;
7778130561Sobrien      Elf_Internal_Sym *isymbuf;
7779130561Sobrien      Elf_External_Versym *ever;
7780130561Sobrien      Elf_External_Versym *extversym;
7781130561Sobrien
7782130561Sobrien      input = loaded->abfd;
7783130561Sobrien
7784130561Sobrien      /* We check each DSO for a possible hidden versioned definition.  */
7785130561Sobrien      if (input == abfd
7786130561Sobrien	  || (input->flags & DYNAMIC) == 0
7787130561Sobrien	  || elf_dynversym (input) == 0)
7788130561Sobrien	continue;
7789130561Sobrien
7790130561Sobrien      hdr = &elf_tdata (input)->dynsymtab_hdr;
7791130561Sobrien
7792130561Sobrien      symcount = hdr->sh_size / bed->s->sizeof_sym;
7793130561Sobrien      if (elf_bad_symtab (input))
7794130561Sobrien	{
7795130561Sobrien	  extsymcount = symcount;
7796130561Sobrien	  extsymoff = 0;
7797130561Sobrien	}
7798130561Sobrien      else
7799130561Sobrien	{
7800130561Sobrien	  extsymcount = symcount - hdr->sh_info;
7801130561Sobrien	  extsymoff = hdr->sh_info;
7802130561Sobrien	}
7803130561Sobrien
7804130561Sobrien      if (extsymcount == 0)
7805130561Sobrien	continue;
7806130561Sobrien
7807130561Sobrien      isymbuf = bfd_elf_get_elf_syms (input, hdr, extsymcount, extsymoff,
7808130561Sobrien				      NULL, NULL, NULL);
7809130561Sobrien      if (isymbuf == NULL)
7810130561Sobrien	return FALSE;
7811130561Sobrien
7812130561Sobrien      /* Read in any version definitions.  */
7813130561Sobrien      versymhdr = &elf_tdata (input)->dynversym_hdr;
7814130561Sobrien      extversym = bfd_malloc (versymhdr->sh_size);
7815130561Sobrien      if (extversym == NULL)
7816130561Sobrien	goto error_ret;
7817130561Sobrien
7818130561Sobrien      if (bfd_seek (input, versymhdr->sh_offset, SEEK_SET) != 0
7819130561Sobrien	  || (bfd_bread (extversym, versymhdr->sh_size, input)
7820130561Sobrien	      != versymhdr->sh_size))
7821130561Sobrien	{
7822130561Sobrien	  free (extversym);
7823130561Sobrien	error_ret:
7824130561Sobrien	  free (isymbuf);
7825130561Sobrien	  return FALSE;
7826130561Sobrien	}
7827130561Sobrien
7828130561Sobrien      ever = extversym + extsymoff;
7829130561Sobrien      isymend = isymbuf + extsymcount;
7830130561Sobrien      for (isym = isymbuf; isym < isymend; isym++, ever++)
7831130561Sobrien	{
7832130561Sobrien	  const char *name;
7833130561Sobrien	  Elf_Internal_Versym iver;
7834130561Sobrien	  unsigned short version_index;
7835130561Sobrien
7836130561Sobrien	  if (ELF_ST_BIND (isym->st_info) == STB_LOCAL
7837130561Sobrien	      || isym->st_shndx == SHN_UNDEF)
7838130561Sobrien	    continue;
7839130561Sobrien
7840130561Sobrien	  name = bfd_elf_string_from_elf_section (input,
7841130561Sobrien						  hdr->sh_link,
7842130561Sobrien						  isym->st_name);
7843130561Sobrien	  if (strcmp (name, h->root.root.string) != 0)
7844130561Sobrien	    continue;
7845130561Sobrien
7846130561Sobrien	  _bfd_elf_swap_versym_in (input, ever, &iver);
7847130561Sobrien
7848130561Sobrien	  if ((iver.vs_vers & VERSYM_HIDDEN) == 0)
7849130561Sobrien	    {
7850130561Sobrien	      /* If we have a non-hidden versioned sym, then it should
7851130561Sobrien		 have provided a definition for the undefined sym.  */
7852130561Sobrien	      abort ();
7853130561Sobrien	    }
7854130561Sobrien
7855130561Sobrien	  version_index = iver.vs_vers & VERSYM_VERSION;
7856130561Sobrien	  if (version_index == 1 || version_index == 2)
7857130561Sobrien	    {
7858130561Sobrien	      /* This is the base or first version.  We can use it.  */
7859130561Sobrien	      free (extversym);
7860130561Sobrien	      free (isymbuf);
7861130561Sobrien	      return TRUE;
7862130561Sobrien	    }
7863130561Sobrien	}
7864130561Sobrien
7865130561Sobrien      free (extversym);
7866130561Sobrien      free (isymbuf);
7867130561Sobrien    }
7868130561Sobrien
7869130561Sobrien  return FALSE;
7870130561Sobrien}
7871130561Sobrien
7872130561Sobrien/* Add an external symbol to the symbol table.  This is called from
7873130561Sobrien   the hash table traversal routine.  When generating a shared object,
7874130561Sobrien   we go through the symbol table twice.  The first time we output
7875130561Sobrien   anything that might have been forced to local scope in a version
7876130561Sobrien   script.  The second time we output the symbols that are still
7877130561Sobrien   global symbols.  */
7878130561Sobrien
7879130561Sobrienstatic bfd_boolean
7880130561Sobrienelf_link_output_extsym (struct elf_link_hash_entry *h, void *data)
7881130561Sobrien{
7882130561Sobrien  struct elf_outext_info *eoinfo = data;
7883130561Sobrien  struct elf_final_link_info *finfo = eoinfo->finfo;
7884130561Sobrien  bfd_boolean strip;
7885130561Sobrien  Elf_Internal_Sym sym;
7886130561Sobrien  asection *input_sec;
7887130561Sobrien  const struct elf_backend_data *bed;
7888130561Sobrien
7889130561Sobrien  if (h->root.type == bfd_link_hash_warning)
7890130561Sobrien    {
7891130561Sobrien      h = (struct elf_link_hash_entry *) h->root.u.i.link;
7892130561Sobrien      if (h->root.type == bfd_link_hash_new)
7893130561Sobrien	return TRUE;
7894130561Sobrien    }
7895130561Sobrien
7896130561Sobrien  /* Decide whether to output this symbol in this pass.  */
7897130561Sobrien  if (eoinfo->localsyms)
7898130561Sobrien    {
7899218822Sdim      if (!h->forced_local)
7900130561Sobrien	return TRUE;
7901130561Sobrien    }
7902130561Sobrien  else
7903130561Sobrien    {
7904218822Sdim      if (h->forced_local)
7905130561Sobrien	return TRUE;
7906130561Sobrien    }
7907130561Sobrien
7908130561Sobrien  bed = get_elf_backend_data (finfo->output_bfd);
7909130561Sobrien
7910218822Sdim  if (h->root.type == bfd_link_hash_undefined)
7911130561Sobrien    {
7912218822Sdim      /* If we have an undefined symbol reference here then it must have
7913218822Sdim	 come from a shared library that is being linked in.  (Undefined
7914218822Sdim	 references in regular files have already been handled).  */
7915218822Sdim      bfd_boolean ignore_undef = FALSE;
7916218822Sdim
7917218822Sdim      /* Some symbols may be special in that the fact that they're
7918218822Sdim	 undefined can be safely ignored - let backend determine that.  */
7919218822Sdim      if (bed->elf_backend_ignore_undef_symbol)
7920218822Sdim	ignore_undef = bed->elf_backend_ignore_undef_symbol (h);
7921218822Sdim
7922218822Sdim      /* If we are reporting errors for this situation then do so now.  */
7923218822Sdim      if (ignore_undef == FALSE
7924218822Sdim	  && h->ref_dynamic
7925218822Sdim	  && ! h->ref_regular
7926218822Sdim	  && ! elf_link_check_versioned_symbol (finfo->info, bed, h)
7927218822Sdim	  && finfo->info->unresolved_syms_in_shared_libs != RM_IGNORE)
7928130561Sobrien	{
7929218822Sdim	  if (! (finfo->info->callbacks->undefined_symbol
7930218822Sdim		 (finfo->info, h->root.root.string, h->root.u.undef.abfd,
7931218822Sdim		  NULL, 0, finfo->info->unresolved_syms_in_shared_libs == RM_GENERATE_ERROR)))
7932218822Sdim	    {
7933218822Sdim	      eoinfo->failed = TRUE;
7934218822Sdim	      return FALSE;
7935218822Sdim	    }
7936130561Sobrien	}
7937130561Sobrien    }
7938130561Sobrien
7939130561Sobrien  /* We should also warn if a forced local symbol is referenced from
7940130561Sobrien     shared libraries.  */
7941130561Sobrien  if (! finfo->info->relocatable
7942130561Sobrien      && (! finfo->info->shared)
7943218822Sdim      && h->forced_local
7944218822Sdim      && h->ref_dynamic
7945218822Sdim      && !h->dynamic_def
7946218822Sdim      && !h->dynamic_weak
7947130561Sobrien      && ! elf_link_check_versioned_symbol (finfo->info, bed, h))
7948130561Sobrien    {
7949130561Sobrien      (*_bfd_error_handler)
7950218822Sdim	(_("%B: %s symbol `%s' in %B is referenced by DSO"),
7951218822Sdim	 finfo->output_bfd,
7952218822Sdim	 h->root.u.def.section == bfd_abs_section_ptr
7953218822Sdim	 ? finfo->output_bfd : h->root.u.def.section->owner,
7954130561Sobrien	 ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
7955130561Sobrien	 ? "internal"
7956130561Sobrien	 : ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
7957218822Sdim	 ? "hidden" : "local",
7958218822Sdim	 h->root.root.string);
7959130561Sobrien      eoinfo->failed = TRUE;
7960130561Sobrien      return FALSE;
7961130561Sobrien    }
7962130561Sobrien
7963130561Sobrien  /* We don't want to output symbols that have never been mentioned by
7964130561Sobrien     a regular file, or that we have been told to strip.  However, if
7965130561Sobrien     h->indx is set to -2, the symbol is used by a reloc and we must
7966130561Sobrien     output it.  */
7967130561Sobrien  if (h->indx == -2)
7968130561Sobrien    strip = FALSE;
7969218822Sdim  else if ((h->def_dynamic
7970218822Sdim	    || h->ref_dynamic
7971218822Sdim	    || h->root.type == bfd_link_hash_new)
7972218822Sdim	   && !h->def_regular
7973218822Sdim	   && !h->ref_regular)
7974130561Sobrien    strip = TRUE;
7975130561Sobrien  else if (finfo->info->strip == strip_all)
7976130561Sobrien    strip = TRUE;
7977130561Sobrien  else if (finfo->info->strip == strip_some
7978130561Sobrien	   && bfd_hash_lookup (finfo->info->keep_hash,
7979130561Sobrien			       h->root.root.string, FALSE, FALSE) == NULL)
7980130561Sobrien    strip = TRUE;
7981130561Sobrien  else if (finfo->info->strip_discarded
7982130561Sobrien	   && (h->root.type == bfd_link_hash_defined
7983130561Sobrien	       || h->root.type == bfd_link_hash_defweak)
7984130561Sobrien	   && elf_discarded_section (h->root.u.def.section))
7985130561Sobrien    strip = TRUE;
7986130561Sobrien  else
7987130561Sobrien    strip = FALSE;
7988130561Sobrien
7989130561Sobrien  /* If we're stripping it, and it's not a dynamic symbol, there's
7990130561Sobrien     nothing else to do unless it is a forced local symbol.  */
7991130561Sobrien  if (strip
7992130561Sobrien      && h->dynindx == -1
7993218822Sdim      && !h->forced_local)
7994130561Sobrien    return TRUE;
7995130561Sobrien
7996130561Sobrien  sym.st_value = 0;
7997130561Sobrien  sym.st_size = h->size;
7998130561Sobrien  sym.st_other = h->other;
7999218822Sdim  if (h->forced_local)
8000130561Sobrien    sym.st_info = ELF_ST_INFO (STB_LOCAL, h->type);
8001130561Sobrien  else if (h->root.type == bfd_link_hash_undefweak
8002130561Sobrien	   || h->root.type == bfd_link_hash_defweak)
8003130561Sobrien    sym.st_info = ELF_ST_INFO (STB_WEAK, h->type);
8004130561Sobrien  else
8005130561Sobrien    sym.st_info = ELF_ST_INFO (STB_GLOBAL, h->type);
8006130561Sobrien
8007130561Sobrien  switch (h->root.type)
8008130561Sobrien    {
8009130561Sobrien    default:
8010130561Sobrien    case bfd_link_hash_new:
8011130561Sobrien    case bfd_link_hash_warning:
8012130561Sobrien      abort ();
8013130561Sobrien      return FALSE;
8014130561Sobrien
8015130561Sobrien    case bfd_link_hash_undefined:
8016130561Sobrien    case bfd_link_hash_undefweak:
8017130561Sobrien      input_sec = bfd_und_section_ptr;
8018130561Sobrien      sym.st_shndx = SHN_UNDEF;
8019130561Sobrien      break;
8020130561Sobrien
8021130561Sobrien    case bfd_link_hash_defined:
8022130561Sobrien    case bfd_link_hash_defweak:
8023130561Sobrien      {
8024130561Sobrien	input_sec = h->root.u.def.section;
8025130561Sobrien	if (input_sec->output_section != NULL)
8026130561Sobrien	  {
8027130561Sobrien	    sym.st_shndx =
8028130561Sobrien	      _bfd_elf_section_from_bfd_section (finfo->output_bfd,
8029130561Sobrien						 input_sec->output_section);
8030130561Sobrien	    if (sym.st_shndx == SHN_BAD)
8031130561Sobrien	      {
8032130561Sobrien		(*_bfd_error_handler)
8033218822Sdim		  (_("%B: could not find output section %A for input section %A"),
8034218822Sdim		   finfo->output_bfd, input_sec->output_section, input_sec);
8035130561Sobrien		eoinfo->failed = TRUE;
8036130561Sobrien		return FALSE;
8037130561Sobrien	      }
8038130561Sobrien
8039130561Sobrien	    /* ELF symbols in relocatable files are section relative,
8040130561Sobrien	       but in nonrelocatable files they are virtual
8041130561Sobrien	       addresses.  */
8042130561Sobrien	    sym.st_value = h->root.u.def.value + input_sec->output_offset;
8043130561Sobrien	    if (! finfo->info->relocatable)
8044130561Sobrien	      {
8045130561Sobrien		sym.st_value += input_sec->output_section->vma;
8046130561Sobrien		if (h->type == STT_TLS)
8047130561Sobrien		  {
8048130561Sobrien		    /* STT_TLS symbols are relative to PT_TLS segment
8049130561Sobrien		       base.  */
8050130561Sobrien		    BFD_ASSERT (elf_hash_table (finfo->info)->tls_sec != NULL);
8051130561Sobrien		    sym.st_value -= elf_hash_table (finfo->info)->tls_sec->vma;
8052130561Sobrien		  }
8053130561Sobrien	      }
8054130561Sobrien	  }
8055130561Sobrien	else
8056130561Sobrien	  {
8057130561Sobrien	    BFD_ASSERT (input_sec->owner == NULL
8058130561Sobrien			|| (input_sec->owner->flags & DYNAMIC) != 0);
8059130561Sobrien	    sym.st_shndx = SHN_UNDEF;
8060130561Sobrien	    input_sec = bfd_und_section_ptr;
8061130561Sobrien	  }
8062130561Sobrien      }
8063130561Sobrien      break;
8064130561Sobrien
8065130561Sobrien    case bfd_link_hash_common:
8066130561Sobrien      input_sec = h->root.u.c.p->section;
8067218822Sdim      sym.st_shndx = bed->common_section_index (input_sec);
8068130561Sobrien      sym.st_value = 1 << h->root.u.c.p->alignment_power;
8069130561Sobrien      break;
8070130561Sobrien
8071130561Sobrien    case bfd_link_hash_indirect:
8072130561Sobrien      /* These symbols are created by symbol versioning.  They point
8073130561Sobrien	 to the decorated version of the name.  For example, if the
8074130561Sobrien	 symbol foo@@GNU_1.2 is the default, which should be used when
8075130561Sobrien	 foo is used with no version, then we add an indirect symbol
8076130561Sobrien	 foo which points to foo@@GNU_1.2.  We ignore these symbols,
8077130561Sobrien	 since the indirected symbol is already in the hash table.  */
8078130561Sobrien      return TRUE;
8079130561Sobrien    }
8080130561Sobrien
8081130561Sobrien  /* Give the processor backend a chance to tweak the symbol value,
8082130561Sobrien     and also to finish up anything that needs to be done for this
8083130561Sobrien     symbol.  FIXME: Not calling elf_backend_finish_dynamic_symbol for
8084130561Sobrien     forced local syms when non-shared is due to a historical quirk.  */
8085130561Sobrien  if ((h->dynindx != -1
8086218822Sdim       || h->forced_local)
8087130561Sobrien      && ((finfo->info->shared
8088130561Sobrien	   && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
8089130561Sobrien	       || h->root.type != bfd_link_hash_undefweak))
8090218822Sdim	  || !h->forced_local)
8091130561Sobrien      && elf_hash_table (finfo->info)->dynamic_sections_created)
8092130561Sobrien    {
8093130561Sobrien      if (! ((*bed->elf_backend_finish_dynamic_symbol)
8094130561Sobrien	     (finfo->output_bfd, finfo->info, h, &sym)))
8095130561Sobrien	{
8096130561Sobrien	  eoinfo->failed = TRUE;
8097130561Sobrien	  return FALSE;
8098130561Sobrien	}
8099130561Sobrien    }
8100130561Sobrien
8101130561Sobrien  /* If we are marking the symbol as undefined, and there are no
8102130561Sobrien     non-weak references to this symbol from a regular object, then
8103130561Sobrien     mark the symbol as weak undefined; if there are non-weak
8104130561Sobrien     references, mark the symbol as strong.  We can't do this earlier,
8105130561Sobrien     because it might not be marked as undefined until the
8106130561Sobrien     finish_dynamic_symbol routine gets through with it.  */
8107130561Sobrien  if (sym.st_shndx == SHN_UNDEF
8108218822Sdim      && h->ref_regular
8109130561Sobrien      && (ELF_ST_BIND (sym.st_info) == STB_GLOBAL
8110130561Sobrien	  || ELF_ST_BIND (sym.st_info) == STB_WEAK))
8111130561Sobrien    {
8112130561Sobrien      int bindtype;
8113130561Sobrien
8114218822Sdim      if (h->ref_regular_nonweak)
8115130561Sobrien	bindtype = STB_GLOBAL;
8116130561Sobrien      else
8117130561Sobrien	bindtype = STB_WEAK;
8118130561Sobrien      sym.st_info = ELF_ST_INFO (bindtype, ELF_ST_TYPE (sym.st_info));
8119130561Sobrien    }
8120130561Sobrien
8121130561Sobrien  /* If a non-weak symbol with non-default visibility is not defined
8122130561Sobrien     locally, it is a fatal error.  */
8123130561Sobrien  if (! finfo->info->relocatable
8124130561Sobrien      && ELF_ST_VISIBILITY (sym.st_other) != STV_DEFAULT
8125130561Sobrien      && ELF_ST_BIND (sym.st_info) != STB_WEAK
8126130561Sobrien      && h->root.type == bfd_link_hash_undefined
8127218822Sdim      && !h->def_regular)
8128130561Sobrien    {
8129130561Sobrien      (*_bfd_error_handler)
8130218822Sdim	(_("%B: %s symbol `%s' isn't defined"),
8131218822Sdim	 finfo->output_bfd,
8132218822Sdim	 ELF_ST_VISIBILITY (sym.st_other) == STV_PROTECTED
8133218822Sdim	 ? "protected"
8134218822Sdim	 : ELF_ST_VISIBILITY (sym.st_other) == STV_INTERNAL
8135218822Sdim	 ? "internal" : "hidden",
8136218822Sdim	 h->root.root.string);
8137130561Sobrien      eoinfo->failed = TRUE;
8138130561Sobrien      return FALSE;
8139130561Sobrien    }
8140130561Sobrien
8141130561Sobrien  /* If this symbol should be put in the .dynsym section, then put it
8142130561Sobrien     there now.  We already know the symbol index.  We also fill in
8143130561Sobrien     the entry in the .hash section.  */
8144130561Sobrien  if (h->dynindx != -1
8145130561Sobrien      && elf_hash_table (finfo->info)->dynamic_sections_created)
8146130561Sobrien    {
8147130561Sobrien      bfd_byte *esym;
8148130561Sobrien
8149130561Sobrien      sym.st_name = h->dynstr_index;
8150130561Sobrien      esym = finfo->dynsym_sec->contents + h->dynindx * bed->s->sizeof_sym;
8151218822Sdim      if (! check_dynsym (finfo->output_bfd, &sym))
8152218822Sdim	{
8153218822Sdim	  eoinfo->failed = TRUE;
8154218822Sdim	  return FALSE;
8155218822Sdim	}
8156130561Sobrien      bed->s->swap_symbol_out (finfo->output_bfd, &sym, esym, 0);
8157130561Sobrien
8158218822Sdim      if (finfo->hash_sec != NULL)
8159218822Sdim	{
8160218822Sdim	  size_t hash_entry_size;
8161218822Sdim	  bfd_byte *bucketpos;
8162218822Sdim	  bfd_vma chain;
8163218822Sdim	  size_t bucketcount;
8164218822Sdim	  size_t bucket;
8165130561Sobrien
8166218822Sdim	  bucketcount = elf_hash_table (finfo->info)->bucketcount;
8167218822Sdim	  bucket = h->u.elf_hash_value % bucketcount;
8168218822Sdim
8169218822Sdim	  hash_entry_size
8170218822Sdim	    = elf_section_data (finfo->hash_sec)->this_hdr.sh_entsize;
8171218822Sdim	  bucketpos = ((bfd_byte *) finfo->hash_sec->contents
8172218822Sdim		       + (bucket + 2) * hash_entry_size);
8173218822Sdim	  chain = bfd_get (8 * hash_entry_size, finfo->output_bfd, bucketpos);
8174218822Sdim	  bfd_put (8 * hash_entry_size, finfo->output_bfd, h->dynindx, bucketpos);
8175218822Sdim	  bfd_put (8 * hash_entry_size, finfo->output_bfd, chain,
8176218822Sdim		   ((bfd_byte *) finfo->hash_sec->contents
8177218822Sdim		    + (bucketcount + 2 + h->dynindx) * hash_entry_size));
8178218822Sdim	}
8179218822Sdim
8180130561Sobrien      if (finfo->symver_sec != NULL && finfo->symver_sec->contents != NULL)
8181130561Sobrien	{
8182130561Sobrien	  Elf_Internal_Versym iversym;
8183130561Sobrien	  Elf_External_Versym *eversym;
8184130561Sobrien
8185218822Sdim	  if (!h->def_regular)
8186130561Sobrien	    {
8187130561Sobrien	      if (h->verinfo.verdef == NULL)
8188130561Sobrien		iversym.vs_vers = 0;
8189130561Sobrien	      else
8190130561Sobrien		iversym.vs_vers = h->verinfo.verdef->vd_exp_refno + 1;
8191130561Sobrien	    }
8192130561Sobrien	  else
8193130561Sobrien	    {
8194130561Sobrien	      if (h->verinfo.vertree == NULL)
8195130561Sobrien		iversym.vs_vers = 1;
8196130561Sobrien	      else
8197130561Sobrien		iversym.vs_vers = h->verinfo.vertree->vernum + 1;
8198218822Sdim	      if (finfo->info->create_default_symver)
8199218822Sdim		iversym.vs_vers++;
8200130561Sobrien	    }
8201130561Sobrien
8202218822Sdim	  if (h->hidden)
8203130561Sobrien	    iversym.vs_vers |= VERSYM_HIDDEN;
8204130561Sobrien
8205130561Sobrien	  eversym = (Elf_External_Versym *) finfo->symver_sec->contents;
8206130561Sobrien	  eversym += h->dynindx;
8207130561Sobrien	  _bfd_elf_swap_versym_out (finfo->output_bfd, &iversym, eversym);
8208130561Sobrien	}
8209130561Sobrien    }
8210130561Sobrien
8211130561Sobrien  /* If we're stripping it, then it was just a dynamic symbol, and
8212130561Sobrien     there's nothing else to do.  */
8213130561Sobrien  if (strip || (input_sec->flags & SEC_EXCLUDE) != 0)
8214130561Sobrien    return TRUE;
8215130561Sobrien
8216130561Sobrien  h->indx = bfd_get_symcount (finfo->output_bfd);
8217130561Sobrien
8218130561Sobrien  if (! elf_link_output_sym (finfo, h->root.root.string, &sym, input_sec, h))
8219130561Sobrien    {
8220130561Sobrien      eoinfo->failed = TRUE;
8221130561Sobrien      return FALSE;
8222130561Sobrien    }
8223130561Sobrien
8224130561Sobrien  return TRUE;
8225130561Sobrien}
8226130561Sobrien
8227218822Sdim/* Return TRUE if special handling is done for relocs in SEC against
8228218822Sdim   symbols defined in discarded sections.  */
8229218822Sdim
8230130561Sobrienstatic bfd_boolean
8231130561Sobrienelf_section_ignore_discarded_relocs (asection *sec)
8232130561Sobrien{
8233130561Sobrien  const struct elf_backend_data *bed;
8234130561Sobrien
8235130561Sobrien  switch (sec->sec_info_type)
8236130561Sobrien    {
8237130561Sobrien    case ELF_INFO_TYPE_STABS:
8238130561Sobrien    case ELF_INFO_TYPE_EH_FRAME:
8239130561Sobrien      return TRUE;
8240130561Sobrien    default:
8241130561Sobrien      break;
8242130561Sobrien    }
8243130561Sobrien
8244130561Sobrien  bed = get_elf_backend_data (sec->owner);
8245130561Sobrien  if (bed->elf_backend_ignore_discarded_relocs != NULL
8246130561Sobrien      && (*bed->elf_backend_ignore_discarded_relocs) (sec))
8247130561Sobrien    return TRUE;
8248130561Sobrien
8249130561Sobrien  return FALSE;
8250130561Sobrien}
8251130561Sobrien
8252218822Sdim/* Return a mask saying how ld should treat relocations in SEC against
8253218822Sdim   symbols defined in discarded sections.  If this function returns
8254218822Sdim   COMPLAIN set, ld will issue a warning message.  If this function
8255218822Sdim   returns PRETEND set, and the discarded section was link-once and the
8256218822Sdim   same size as the kept link-once section, ld will pretend that the
8257218822Sdim   symbol was actually defined in the kept section.  Otherwise ld will
8258218822Sdim   zero the reloc (at least that is the intent, but some cooperation by
8259218822Sdim   the target dependent code is needed, particularly for REL targets).  */
8260218822Sdim
8261218822Sdimunsigned int
8262218822Sdim_bfd_elf_default_action_discarded (asection *sec)
8263218822Sdim{
8264218822Sdim  if (sec->flags & SEC_DEBUGGING)
8265218822Sdim    return PRETEND;
8266218822Sdim
8267218822Sdim  if (strcmp (".eh_frame", sec->name) == 0)
8268218822Sdim    return 0;
8269218822Sdim
8270218822Sdim  if (strcmp (".gcc_except_table", sec->name) == 0)
8271218822Sdim    return 0;
8272218822Sdim
8273218822Sdim  return COMPLAIN | PRETEND;
8274218822Sdim}
8275218822Sdim
8276218822Sdim/* Find a match between a section and a member of a section group.  */
8277218822Sdim
8278218822Sdimstatic asection *
8279218822Sdimmatch_group_member (asection *sec, asection *group,
8280218822Sdim		    struct bfd_link_info *info)
8281218822Sdim{
8282218822Sdim  asection *first = elf_next_in_group (group);
8283218822Sdim  asection *s = first;
8284218822Sdim
8285218822Sdim  while (s != NULL)
8286218822Sdim    {
8287218822Sdim      if (bfd_elf_match_symbols_in_sections (s, sec, info))
8288218822Sdim	return s;
8289218822Sdim
8290218822Sdim      s = elf_next_in_group (s);
8291218822Sdim      if (s == first)
8292218822Sdim	break;
8293218822Sdim    }
8294218822Sdim
8295218822Sdim  return NULL;
8296218822Sdim}
8297218822Sdim
8298218822Sdim/* Check if the kept section of a discarded section SEC can be used
8299218822Sdim   to replace it.  Return the replacement if it is OK.  Otherwise return
8300218822Sdim   NULL.  */
8301218822Sdim
8302218822Sdimasection *
8303218822Sdim_bfd_elf_check_kept_section (asection *sec, struct bfd_link_info *info)
8304218822Sdim{
8305218822Sdim  asection *kept;
8306218822Sdim
8307218822Sdim  kept = sec->kept_section;
8308218822Sdim  if (kept != NULL)
8309218822Sdim    {
8310218822Sdim      if ((kept->flags & SEC_GROUP) != 0)
8311218822Sdim	kept = match_group_member (sec, kept, info);
8312218822Sdim      if (kept != NULL && sec->size != kept->size)
8313218822Sdim	kept = NULL;
8314218822Sdim      sec->kept_section = kept;
8315218822Sdim    }
8316218822Sdim  return kept;
8317218822Sdim}
8318218822Sdim
8319130561Sobrien/* Link an input file into the linker output file.  This function
8320130561Sobrien   handles all the sections and relocations of the input file at once.
8321130561Sobrien   This is so that we only have to read the local symbols once, and
8322130561Sobrien   don't have to keep them in memory.  */
8323130561Sobrien
8324130561Sobrienstatic bfd_boolean
8325130561Sobrienelf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
8326130561Sobrien{
8327218822Sdim  int (*relocate_section)
8328130561Sobrien    (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
8329130561Sobrien     Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
8330130561Sobrien  bfd *output_bfd;
8331130561Sobrien  Elf_Internal_Shdr *symtab_hdr;
8332130561Sobrien  size_t locsymcount;
8333130561Sobrien  size_t extsymoff;
8334130561Sobrien  Elf_Internal_Sym *isymbuf;
8335130561Sobrien  Elf_Internal_Sym *isym;
8336130561Sobrien  Elf_Internal_Sym *isymend;
8337130561Sobrien  long *pindex;
8338130561Sobrien  asection **ppsection;
8339130561Sobrien  asection *o;
8340130561Sobrien  const struct elf_backend_data *bed;
8341130561Sobrien  struct elf_link_hash_entry **sym_hashes;
8342130561Sobrien
8343130561Sobrien  output_bfd = finfo->output_bfd;
8344130561Sobrien  bed = get_elf_backend_data (output_bfd);
8345130561Sobrien  relocate_section = bed->elf_backend_relocate_section;
8346130561Sobrien
8347130561Sobrien  /* If this is a dynamic object, we don't want to do anything here:
8348130561Sobrien     we don't want the local symbols, and we don't want the section
8349130561Sobrien     contents.  */
8350130561Sobrien  if ((input_bfd->flags & DYNAMIC) != 0)
8351130561Sobrien    return TRUE;
8352130561Sobrien
8353130561Sobrien  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
8354130561Sobrien  if (elf_bad_symtab (input_bfd))
8355130561Sobrien    {
8356130561Sobrien      locsymcount = symtab_hdr->sh_size / bed->s->sizeof_sym;
8357130561Sobrien      extsymoff = 0;
8358130561Sobrien    }
8359130561Sobrien  else
8360130561Sobrien    {
8361130561Sobrien      locsymcount = symtab_hdr->sh_info;
8362130561Sobrien      extsymoff = symtab_hdr->sh_info;
8363130561Sobrien    }
8364130561Sobrien
8365130561Sobrien  /* Read the local symbols.  */
8366130561Sobrien  isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
8367130561Sobrien  if (isymbuf == NULL && locsymcount != 0)
8368130561Sobrien    {
8369130561Sobrien      isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, locsymcount, 0,
8370130561Sobrien				      finfo->internal_syms,
8371130561Sobrien				      finfo->external_syms,
8372130561Sobrien				      finfo->locsym_shndx);
8373130561Sobrien      if (isymbuf == NULL)
8374130561Sobrien	return FALSE;
8375130561Sobrien    }
8376218822Sdim  /* evaluate_complex_relocation_symbols looks for symbols in
8377218822Sdim     finfo->internal_syms.  */
8378218822Sdim  else if (isymbuf != NULL && locsymcount != 0)
8379218822Sdim    {
8380218822Sdim      bfd_elf_get_elf_syms (input_bfd, symtab_hdr, locsymcount, 0,
8381218822Sdim			    finfo->internal_syms,
8382218822Sdim			    finfo->external_syms,
8383218822Sdim			    finfo->locsym_shndx);
8384218822Sdim    }
8385130561Sobrien
8386130561Sobrien  /* Find local symbol sections and adjust values of symbols in
8387130561Sobrien     SEC_MERGE sections.  Write out those local symbols we know are
8388130561Sobrien     going into the output file.  */
8389130561Sobrien  isymend = isymbuf + locsymcount;
8390130561Sobrien  for (isym = isymbuf, pindex = finfo->indices, ppsection = finfo->sections;
8391130561Sobrien       isym < isymend;
8392130561Sobrien       isym++, pindex++, ppsection++)
8393130561Sobrien    {
8394130561Sobrien      asection *isec;
8395130561Sobrien      const char *name;
8396130561Sobrien      Elf_Internal_Sym osym;
8397130561Sobrien
8398130561Sobrien      *pindex = -1;
8399130561Sobrien
8400130561Sobrien      if (elf_bad_symtab (input_bfd))
8401130561Sobrien	{
8402130561Sobrien	  if (ELF_ST_BIND (isym->st_info) != STB_LOCAL)
8403130561Sobrien	    {
8404130561Sobrien	      *ppsection = NULL;
8405130561Sobrien	      continue;
8406130561Sobrien	    }
8407130561Sobrien	}
8408130561Sobrien
8409130561Sobrien      if (isym->st_shndx == SHN_UNDEF)
8410130561Sobrien	isec = bfd_und_section_ptr;
8411130561Sobrien      else if (isym->st_shndx < SHN_LORESERVE
8412130561Sobrien	       || isym->st_shndx > SHN_HIRESERVE)
8413130561Sobrien	{
8414130561Sobrien	  isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
8415130561Sobrien	  if (isec
8416130561Sobrien	      && isec->sec_info_type == ELF_INFO_TYPE_MERGE
8417130561Sobrien	      && ELF_ST_TYPE (isym->st_info) != STT_SECTION)
8418130561Sobrien	    isym->st_value =
8419130561Sobrien	      _bfd_merged_section_offset (output_bfd, &isec,
8420130561Sobrien					  elf_section_data (isec)->sec_info,
8421218822Sdim					  isym->st_value);
8422130561Sobrien	}
8423130561Sobrien      else if (isym->st_shndx == SHN_ABS)
8424130561Sobrien	isec = bfd_abs_section_ptr;
8425130561Sobrien      else if (isym->st_shndx == SHN_COMMON)
8426130561Sobrien	isec = bfd_com_section_ptr;
8427130561Sobrien      else
8428130561Sobrien	{
8429218822Sdim	  /* Don't attempt to output symbols with st_shnx in the
8430218822Sdim	     reserved range other than SHN_ABS and SHN_COMMON.  */
8431218822Sdim	  *ppsection = NULL;
8432218822Sdim	  continue;
8433130561Sobrien	}
8434130561Sobrien
8435130561Sobrien      *ppsection = isec;
8436130561Sobrien
8437130561Sobrien      /* Don't output the first, undefined, symbol.  */
8438130561Sobrien      if (ppsection == finfo->sections)
8439130561Sobrien	continue;
8440130561Sobrien
8441130561Sobrien      if (ELF_ST_TYPE (isym->st_info) == STT_SECTION)
8442130561Sobrien	{
8443130561Sobrien	  /* We never output section symbols.  Instead, we use the
8444130561Sobrien	     section symbol of the corresponding section in the output
8445130561Sobrien	     file.  */
8446130561Sobrien	  continue;
8447130561Sobrien	}
8448130561Sobrien
8449130561Sobrien      /* If we are stripping all symbols, we don't want to output this
8450130561Sobrien	 one.  */
8451130561Sobrien      if (finfo->info->strip == strip_all)
8452130561Sobrien	continue;
8453130561Sobrien
8454130561Sobrien      /* If we are discarding all local symbols, we don't want to
8455130561Sobrien	 output this one.  If we are generating a relocatable output
8456130561Sobrien	 file, then some of the local symbols may be required by
8457130561Sobrien	 relocs; we output them below as we discover that they are
8458130561Sobrien	 needed.  */
8459130561Sobrien      if (finfo->info->discard == discard_all)
8460130561Sobrien	continue;
8461130561Sobrien
8462130561Sobrien      /* If this symbol is defined in a section which we are
8463218822Sdim	 discarding, we don't need to keep it.  */
8464218822Sdim      if (isym->st_shndx != SHN_UNDEF
8465218822Sdim	  && (isym->st_shndx < SHN_LORESERVE || isym->st_shndx > SHN_HIRESERVE)
8466218822Sdim	  && (isec == NULL
8467218822Sdim	      || bfd_section_removed_from_list (output_bfd,
8468218822Sdim						isec->output_section)))
8469130561Sobrien	continue;
8470130561Sobrien
8471130561Sobrien      /* Get the name of the symbol.  */
8472130561Sobrien      name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link,
8473130561Sobrien					      isym->st_name);
8474130561Sobrien      if (name == NULL)
8475130561Sobrien	return FALSE;
8476130561Sobrien
8477130561Sobrien      /* See if we are discarding symbols with this name.  */
8478130561Sobrien      if ((finfo->info->strip == strip_some
8479130561Sobrien	   && (bfd_hash_lookup (finfo->info->keep_hash, name, FALSE, FALSE)
8480130561Sobrien	       == NULL))
8481130561Sobrien	  || (((finfo->info->discard == discard_sec_merge
8482130561Sobrien		&& (isec->flags & SEC_MERGE) && ! finfo->info->relocatable)
8483130561Sobrien	       || finfo->info->discard == discard_l)
8484130561Sobrien	      && bfd_is_local_label_name (input_bfd, name)))
8485130561Sobrien	continue;
8486130561Sobrien
8487130561Sobrien      /* If we get here, we are going to output this symbol.  */
8488130561Sobrien
8489130561Sobrien      osym = *isym;
8490130561Sobrien
8491130561Sobrien      /* Adjust the section index for the output file.  */
8492130561Sobrien      osym.st_shndx = _bfd_elf_section_from_bfd_section (output_bfd,
8493130561Sobrien							 isec->output_section);
8494130561Sobrien      if (osym.st_shndx == SHN_BAD)
8495130561Sobrien	return FALSE;
8496130561Sobrien
8497130561Sobrien      *pindex = bfd_get_symcount (output_bfd);
8498130561Sobrien
8499130561Sobrien      /* ELF symbols in relocatable files are section relative, but
8500130561Sobrien	 in executable files they are virtual addresses.  Note that
8501130561Sobrien	 this code assumes that all ELF sections have an associated
8502130561Sobrien	 BFD section with a reasonable value for output_offset; below
8503130561Sobrien	 we assume that they also have a reasonable value for
8504130561Sobrien	 output_section.  Any special sections must be set up to meet
8505130561Sobrien	 these requirements.  */
8506130561Sobrien      osym.st_value += isec->output_offset;
8507130561Sobrien      if (! finfo->info->relocatable)
8508130561Sobrien	{
8509130561Sobrien	  osym.st_value += isec->output_section->vma;
8510130561Sobrien	  if (ELF_ST_TYPE (osym.st_info) == STT_TLS)
8511130561Sobrien	    {
8512130561Sobrien	      /* STT_TLS symbols are relative to PT_TLS segment base.  */
8513130561Sobrien	      BFD_ASSERT (elf_hash_table (finfo->info)->tls_sec != NULL);
8514130561Sobrien	      osym.st_value -= elf_hash_table (finfo->info)->tls_sec->vma;
8515130561Sobrien	    }
8516130561Sobrien	}
8517130561Sobrien
8518130561Sobrien      if (! elf_link_output_sym (finfo, name, &osym, isec, NULL))
8519130561Sobrien	return FALSE;
8520130561Sobrien    }
8521130561Sobrien
8522218822Sdim  if (! evaluate_complex_relocation_symbols (input_bfd, finfo, locsymcount))
8523218822Sdim    return FALSE;
8524218822Sdim
8525130561Sobrien  /* Relocate the contents of each section.  */
8526130561Sobrien  sym_hashes = elf_sym_hashes (input_bfd);
8527130561Sobrien  for (o = input_bfd->sections; o != NULL; o = o->next)
8528130561Sobrien    {
8529130561Sobrien      bfd_byte *contents;
8530130561Sobrien
8531130561Sobrien      if (! o->linker_mark)
8532130561Sobrien	{
8533130561Sobrien	  /* This section was omitted from the link.  */
8534130561Sobrien	  continue;
8535130561Sobrien	}
8536130561Sobrien
8537130561Sobrien      if ((o->flags & SEC_HAS_CONTENTS) == 0
8538218822Sdim	  || (o->size == 0 && (o->flags & SEC_RELOC) == 0))
8539130561Sobrien	continue;
8540130561Sobrien
8541130561Sobrien      if ((o->flags & SEC_LINKER_CREATED) != 0)
8542130561Sobrien	{
8543130561Sobrien	  /* Section was created by _bfd_elf_link_create_dynamic_sections
8544130561Sobrien	     or somesuch.  */
8545130561Sobrien	  continue;
8546130561Sobrien	}
8547130561Sobrien
8548130561Sobrien      /* Get the contents of the section.  They have been cached by a
8549130561Sobrien	 relaxation routine.  Note that o is a section in an input
8550130561Sobrien	 file, so the contents field will not have been set by any of
8551130561Sobrien	 the routines which work on output files.  */
8552130561Sobrien      if (elf_section_data (o)->this_hdr.contents != NULL)
8553130561Sobrien	contents = elf_section_data (o)->this_hdr.contents;
8554130561Sobrien      else
8555130561Sobrien	{
8556218822Sdim	  bfd_size_type amt = o->rawsize ? o->rawsize : o->size;
8557218822Sdim
8558130561Sobrien	  contents = finfo->contents;
8559218822Sdim	  if (! bfd_get_section_contents (input_bfd, o, contents, 0, amt))
8560130561Sobrien	    return FALSE;
8561130561Sobrien	}
8562130561Sobrien
8563130561Sobrien      if ((o->flags & SEC_RELOC) != 0)
8564130561Sobrien	{
8565130561Sobrien	  Elf_Internal_Rela *internal_relocs;
8566130561Sobrien	  bfd_vma r_type_mask;
8567130561Sobrien	  int r_sym_shift;
8568218822Sdim	  int ret;
8569130561Sobrien
8570130561Sobrien	  /* Get the swapped relocs.  */
8571130561Sobrien	  internal_relocs
8572130561Sobrien	    = _bfd_elf_link_read_relocs (input_bfd, o, finfo->external_relocs,
8573130561Sobrien					 finfo->internal_relocs, FALSE);
8574130561Sobrien	  if (internal_relocs == NULL
8575130561Sobrien	      && o->reloc_count > 0)
8576130561Sobrien	    return FALSE;
8577130561Sobrien
8578130561Sobrien	  if (bed->s->arch_size == 32)
8579130561Sobrien	    {
8580130561Sobrien	      r_type_mask = 0xff;
8581130561Sobrien	      r_sym_shift = 8;
8582130561Sobrien	    }
8583130561Sobrien	  else
8584130561Sobrien	    {
8585130561Sobrien	      r_type_mask = 0xffffffff;
8586130561Sobrien	      r_sym_shift = 32;
8587130561Sobrien	    }
8588130561Sobrien
8589130561Sobrien	  /* Run through the relocs looking for any against symbols
8590130561Sobrien	     from discarded sections and section symbols from
8591130561Sobrien	     removed link-once sections.  Complain about relocs
8592130561Sobrien	     against discarded sections.  Zero relocs against removed
8593218822Sdim	     link-once sections.  */
8594130561Sobrien	  if (!elf_section_ignore_discarded_relocs (o))
8595130561Sobrien	    {
8596130561Sobrien	      Elf_Internal_Rela *rel, *relend;
8597218822Sdim	      unsigned int action = (*bed->action_discarded) (o);
8598130561Sobrien
8599130561Sobrien	      rel = internal_relocs;
8600130561Sobrien	      relend = rel + o->reloc_count * bed->s->int_rels_per_ext_rel;
8601130561Sobrien	      for ( ; rel < relend; rel++)
8602130561Sobrien		{
8603130561Sobrien		  unsigned long r_symndx = rel->r_info >> r_sym_shift;
8604218822Sdim		  asection **ps, *sec;
8605218822Sdim		  struct elf_link_hash_entry *h = NULL;
8606218822Sdim		  const char *sym_name;
8607130561Sobrien
8608218822Sdim		  if (r_symndx == STN_UNDEF)
8609218822Sdim		    continue;
8610218822Sdim
8611130561Sobrien		  if (r_symndx >= locsymcount
8612130561Sobrien		      || (elf_bad_symtab (input_bfd)
8613130561Sobrien			  && finfo->sections[r_symndx] == NULL))
8614130561Sobrien		    {
8615218822Sdim		      h = sym_hashes[r_symndx - extsymoff];
8616130561Sobrien
8617218822Sdim		      /* Badly formatted input files can contain relocs that
8618218822Sdim			 reference non-existant symbols.  Check here so that
8619218822Sdim			 we do not seg fault.  */
8620218822Sdim		      if (h == NULL)
8621218822Sdim			{
8622218822Sdim			  char buffer [32];
8623218822Sdim
8624218822Sdim			  sprintf_vma (buffer, rel->r_info);
8625218822Sdim			  (*_bfd_error_handler)
8626218822Sdim			    (_("error: %B contains a reloc (0x%s) for section %A "
8627218822Sdim			       "that references a non-existent global symbol"),
8628218822Sdim			     input_bfd, o, buffer);
8629218822Sdim			  bfd_set_error (bfd_error_bad_value);
8630218822Sdim			  return FALSE;
8631218822Sdim			}
8632218822Sdim
8633130561Sobrien		      while (h->root.type == bfd_link_hash_indirect
8634130561Sobrien			     || h->root.type == bfd_link_hash_warning)
8635130561Sobrien			h = (struct elf_link_hash_entry *) h->root.u.i.link;
8636130561Sobrien
8637218822Sdim		      if (h->root.type != bfd_link_hash_defined
8638218822Sdim			  && h->root.type != bfd_link_hash_defweak)
8639218822Sdim			continue;
8640218822Sdim
8641218822Sdim		      ps = &h->root.u.def.section;
8642218822Sdim		      sym_name = h->root.root.string;
8643130561Sobrien		    }
8644130561Sobrien		  else
8645130561Sobrien		    {
8646218822Sdim		      Elf_Internal_Sym *sym = isymbuf + r_symndx;
8647218822Sdim		      ps = &finfo->sections[r_symndx];
8648218822Sdim		      sym_name = bfd_elf_sym_name (input_bfd,
8649218822Sdim						   symtab_hdr,
8650218822Sdim						   sym, *ps);
8651218822Sdim		    }
8652130561Sobrien
8653218822Sdim		  /* Complain if the definition comes from a
8654218822Sdim		     discarded section.  */
8655218822Sdim		  if ((sec = *ps) != NULL && elf_discarded_section (sec))
8656218822Sdim		    {
8657218822Sdim		      BFD_ASSERT (r_symndx != 0);
8658218822Sdim		      if (action & COMPLAIN)
8659218822Sdim			(*finfo->info->callbacks->einfo)
8660218822Sdim			  (_("%X`%s' referenced in section `%A' of %B: "
8661218822Sdim			     "defined in discarded section `%A' of %B\n"),
8662218822Sdim			   sym_name, o, input_bfd, sec, sec->owner);
8663218822Sdim
8664218822Sdim		      /* Try to do the best we can to support buggy old
8665218822Sdim			 versions of gcc.  Pretend that the symbol is
8666218822Sdim			 really defined in the kept linkonce section.
8667218822Sdim			 FIXME: This is quite broken.  Modifying the
8668218822Sdim			 symbol here means we will be changing all later
8669218822Sdim			 uses of the symbol, not just in this section.  */
8670218822Sdim		      if (action & PRETEND)
8671130561Sobrien			{
8672218822Sdim			  asection *kept;
8673218822Sdim
8674218822Sdim			  kept = _bfd_elf_check_kept_section (sec,
8675218822Sdim							      finfo->info);
8676218822Sdim			  if (kept != NULL)
8677130561Sobrien			    {
8678218822Sdim			      *ps = kept;
8679218822Sdim			      continue;
8680130561Sobrien			    }
8681130561Sobrien			}
8682130561Sobrien		    }
8683130561Sobrien		}
8684130561Sobrien	    }
8685130561Sobrien
8686130561Sobrien	  /* Relocate the section by invoking a back end routine.
8687130561Sobrien
8688130561Sobrien	     The back end routine is responsible for adjusting the
8689130561Sobrien	     section contents as necessary, and (if using Rela relocs
8690130561Sobrien	     and generating a relocatable output file) adjusting the
8691130561Sobrien	     reloc addend as necessary.
8692130561Sobrien
8693130561Sobrien	     The back end routine does not have to worry about setting
8694130561Sobrien	     the reloc address or the reloc symbol index.
8695130561Sobrien
8696130561Sobrien	     The back end routine is given a pointer to the swapped in
8697130561Sobrien	     internal symbols, and can access the hash table entries
8698130561Sobrien	     for the external symbols via elf_sym_hashes (input_bfd).
8699130561Sobrien
8700130561Sobrien	     When generating relocatable output, the back end routine
8701130561Sobrien	     must handle STB_LOCAL/STT_SECTION symbols specially.  The
8702130561Sobrien	     output symbol is going to be a section symbol
8703130561Sobrien	     corresponding to the output section, which will require
8704130561Sobrien	     the addend to be adjusted.  */
8705130561Sobrien
8706218822Sdim	  ret = (*relocate_section) (output_bfd, finfo->info,
8707130561Sobrien				     input_bfd, o, contents,
8708130561Sobrien				     internal_relocs,
8709130561Sobrien				     isymbuf,
8710218822Sdim				     finfo->sections);
8711218822Sdim	  if (!ret)
8712130561Sobrien	    return FALSE;
8713130561Sobrien
8714218822Sdim	  if (ret == 2
8715218822Sdim	      || finfo->info->relocatable
8716218822Sdim	      || finfo->info->emitrelocations)
8717130561Sobrien	    {
8718130561Sobrien	      Elf_Internal_Rela *irela;
8719130561Sobrien	      Elf_Internal_Rela *irelaend;
8720130561Sobrien	      bfd_vma last_offset;
8721130561Sobrien	      struct elf_link_hash_entry **rel_hash;
8722218822Sdim	      struct elf_link_hash_entry **rel_hash_list;
8723130561Sobrien	      Elf_Internal_Shdr *input_rel_hdr, *input_rel_hdr2;
8724130561Sobrien	      unsigned int next_erel;
8725130561Sobrien	      bfd_boolean rela_normal;
8726130561Sobrien
8727130561Sobrien	      input_rel_hdr = &elf_section_data (o)->rel_hdr;
8728130561Sobrien	      rela_normal = (bed->rela_normal
8729130561Sobrien			     && (input_rel_hdr->sh_entsize
8730130561Sobrien				 == bed->s->sizeof_rela));
8731130561Sobrien
8732130561Sobrien	      /* Adjust the reloc addresses and symbol indices.  */
8733130561Sobrien
8734130561Sobrien	      irela = internal_relocs;
8735130561Sobrien	      irelaend = irela + o->reloc_count * bed->s->int_rels_per_ext_rel;
8736130561Sobrien	      rel_hash = (elf_section_data (o->output_section)->rel_hashes
8737130561Sobrien			  + elf_section_data (o->output_section)->rel_count
8738130561Sobrien			  + elf_section_data (o->output_section)->rel_count2);
8739218822Sdim	      rel_hash_list = rel_hash;
8740130561Sobrien	      last_offset = o->output_offset;
8741130561Sobrien	      if (!finfo->info->relocatable)
8742130561Sobrien		last_offset += o->output_section->vma;
8743130561Sobrien	      for (next_erel = 0; irela < irelaend; irela++, next_erel++)
8744130561Sobrien		{
8745130561Sobrien		  unsigned long r_symndx;
8746130561Sobrien		  asection *sec;
8747130561Sobrien		  Elf_Internal_Sym sym;
8748130561Sobrien
8749130561Sobrien		  if (next_erel == bed->s->int_rels_per_ext_rel)
8750130561Sobrien		    {
8751130561Sobrien		      rel_hash++;
8752130561Sobrien		      next_erel = 0;
8753130561Sobrien		    }
8754130561Sobrien
8755130561Sobrien		  irela->r_offset = _bfd_elf_section_offset (output_bfd,
8756130561Sobrien							     finfo->info, o,
8757130561Sobrien							     irela->r_offset);
8758130561Sobrien		  if (irela->r_offset >= (bfd_vma) -2)
8759130561Sobrien		    {
8760130561Sobrien		      /* This is a reloc for a deleted entry or somesuch.
8761130561Sobrien			 Turn it into an R_*_NONE reloc, at the same
8762130561Sobrien			 offset as the last reloc.  elf_eh_frame.c and
8763218822Sdim			 bfd_elf_discard_info rely on reloc offsets
8764130561Sobrien			 being ordered.  */
8765130561Sobrien		      irela->r_offset = last_offset;
8766130561Sobrien		      irela->r_info = 0;
8767130561Sobrien		      irela->r_addend = 0;
8768130561Sobrien		      continue;
8769130561Sobrien		    }
8770130561Sobrien
8771130561Sobrien		  irela->r_offset += o->output_offset;
8772130561Sobrien
8773130561Sobrien		  /* Relocs in an executable have to be virtual addresses.  */
8774130561Sobrien		  if (!finfo->info->relocatable)
8775130561Sobrien		    irela->r_offset += o->output_section->vma;
8776130561Sobrien
8777130561Sobrien		  last_offset = irela->r_offset;
8778130561Sobrien
8779130561Sobrien		  r_symndx = irela->r_info >> r_sym_shift;
8780130561Sobrien		  if (r_symndx == STN_UNDEF)
8781130561Sobrien		    continue;
8782130561Sobrien
8783130561Sobrien		  if (r_symndx >= locsymcount
8784130561Sobrien		      || (elf_bad_symtab (input_bfd)
8785130561Sobrien			  && finfo->sections[r_symndx] == NULL))
8786130561Sobrien		    {
8787130561Sobrien		      struct elf_link_hash_entry *rh;
8788130561Sobrien		      unsigned long indx;
8789130561Sobrien
8790130561Sobrien		      /* This is a reloc against a global symbol.  We
8791130561Sobrien			 have not yet output all the local symbols, so
8792130561Sobrien			 we do not know the symbol index of any global
8793130561Sobrien			 symbol.  We set the rel_hash entry for this
8794130561Sobrien			 reloc to point to the global hash table entry
8795130561Sobrien			 for this symbol.  The symbol index is then
8796218822Sdim			 set at the end of bfd_elf_final_link.  */
8797130561Sobrien		      indx = r_symndx - extsymoff;
8798130561Sobrien		      rh = elf_sym_hashes (input_bfd)[indx];
8799130561Sobrien		      while (rh->root.type == bfd_link_hash_indirect
8800130561Sobrien			     || rh->root.type == bfd_link_hash_warning)
8801130561Sobrien			rh = (struct elf_link_hash_entry *) rh->root.u.i.link;
8802130561Sobrien
8803130561Sobrien		      /* Setting the index to -2 tells
8804130561Sobrien			 elf_link_output_extsym that this symbol is
8805130561Sobrien			 used by a reloc.  */
8806130561Sobrien		      BFD_ASSERT (rh->indx < 0);
8807130561Sobrien		      rh->indx = -2;
8808130561Sobrien
8809130561Sobrien		      *rel_hash = rh;
8810130561Sobrien
8811130561Sobrien		      continue;
8812130561Sobrien		    }
8813130561Sobrien
8814130561Sobrien		  /* This is a reloc against a local symbol.  */
8815130561Sobrien
8816130561Sobrien		  *rel_hash = NULL;
8817130561Sobrien		  sym = isymbuf[r_symndx];
8818130561Sobrien		  sec = finfo->sections[r_symndx];
8819130561Sobrien		  if (ELF_ST_TYPE (sym.st_info) == STT_SECTION)
8820130561Sobrien		    {
8821130561Sobrien		      /* I suppose the backend ought to fill in the
8822130561Sobrien			 section of any STT_SECTION symbol against a
8823218822Sdim			 processor specific section.  */
8824218822Sdim		      r_symndx = 0;
8825218822Sdim		      if (bfd_is_abs_section (sec))
8826218822Sdim			;
8827130561Sobrien		      else if (sec == NULL || sec->owner == NULL)
8828130561Sobrien			{
8829130561Sobrien			  bfd_set_error (bfd_error_bad_value);
8830130561Sobrien			  return FALSE;
8831130561Sobrien			}
8832130561Sobrien		      else
8833130561Sobrien			{
8834218822Sdim			  asection *osec = sec->output_section;
8835218822Sdim
8836218822Sdim			  /* If we have discarded a section, the output
8837218822Sdim			     section will be the absolute section.  In
8838218822Sdim			     case of discarded SEC_MERGE sections, use
8839218822Sdim			     the kept section.  relocate_section should
8840218822Sdim			     have already handled discarded linkonce
8841218822Sdim			     sections.  */
8842218822Sdim			  if (bfd_is_abs_section (osec)
8843218822Sdim			      && sec->kept_section != NULL
8844218822Sdim			      && sec->kept_section->output_section != NULL)
8845218822Sdim			    {
8846218822Sdim			      osec = sec->kept_section->output_section;
8847218822Sdim			      irela->r_addend -= osec->vma;
8848218822Sdim			    }
8849218822Sdim
8850218822Sdim			  if (!bfd_is_abs_section (osec))
8851218822Sdim			    {
8852218822Sdim			      r_symndx = osec->target_index;
8853218822Sdim			      if (r_symndx == 0)
8854218822Sdim				{
8855218822Sdim				  struct elf_link_hash_table *htab;
8856218822Sdim				  asection *oi;
8857218822Sdim
8858218822Sdim				  htab = elf_hash_table (finfo->info);
8859218822Sdim				  oi = htab->text_index_section;
8860218822Sdim				  if ((osec->flags & SEC_READONLY) == 0
8861218822Sdim				      && htab->data_index_section != NULL)
8862218822Sdim				    oi = htab->data_index_section;
8863218822Sdim
8864218822Sdim				  if (oi != NULL)
8865218822Sdim				    {
8866218822Sdim				      irela->r_addend += osec->vma - oi->vma;
8867218822Sdim				      r_symndx = oi->target_index;
8868218822Sdim				    }
8869218822Sdim				}
8870218822Sdim
8871218822Sdim			      BFD_ASSERT (r_symndx != 0);
8872218822Sdim			    }
8873130561Sobrien			}
8874130561Sobrien
8875130561Sobrien		      /* Adjust the addend according to where the
8876130561Sobrien			 section winds up in the output section.  */
8877130561Sobrien		      if (rela_normal)
8878130561Sobrien			irela->r_addend += sec->output_offset;
8879130561Sobrien		    }
8880130561Sobrien		  else
8881130561Sobrien		    {
8882130561Sobrien		      if (finfo->indices[r_symndx] == -1)
8883130561Sobrien			{
8884130561Sobrien			  unsigned long shlink;
8885130561Sobrien			  const char *name;
8886130561Sobrien			  asection *osec;
8887130561Sobrien
8888130561Sobrien			  if (finfo->info->strip == strip_all)
8889130561Sobrien			    {
8890130561Sobrien			      /* You can't do ld -r -s.  */
8891130561Sobrien			      bfd_set_error (bfd_error_invalid_operation);
8892130561Sobrien			      return FALSE;
8893130561Sobrien			    }
8894130561Sobrien
8895130561Sobrien			  /* This symbol was skipped earlier, but
8896130561Sobrien			     since it is needed by a reloc, we
8897130561Sobrien			     must output it now.  */
8898130561Sobrien			  shlink = symtab_hdr->sh_link;
8899130561Sobrien			  name = (bfd_elf_string_from_elf_section
8900130561Sobrien				  (input_bfd, shlink, sym.st_name));
8901130561Sobrien			  if (name == NULL)
8902130561Sobrien			    return FALSE;
8903130561Sobrien
8904130561Sobrien			  osec = sec->output_section;
8905130561Sobrien			  sym.st_shndx =
8906130561Sobrien			    _bfd_elf_section_from_bfd_section (output_bfd,
8907130561Sobrien							       osec);
8908130561Sobrien			  if (sym.st_shndx == SHN_BAD)
8909130561Sobrien			    return FALSE;
8910130561Sobrien
8911130561Sobrien			  sym.st_value += sec->output_offset;
8912130561Sobrien			  if (! finfo->info->relocatable)
8913130561Sobrien			    {
8914130561Sobrien			      sym.st_value += osec->vma;
8915130561Sobrien			      if (ELF_ST_TYPE (sym.st_info) == STT_TLS)
8916130561Sobrien				{
8917130561Sobrien				  /* STT_TLS symbols are relative to PT_TLS
8918130561Sobrien				     segment base.  */
8919130561Sobrien				  BFD_ASSERT (elf_hash_table (finfo->info)
8920130561Sobrien					      ->tls_sec != NULL);
8921130561Sobrien				  sym.st_value -= (elf_hash_table (finfo->info)
8922130561Sobrien						   ->tls_sec->vma);
8923130561Sobrien				}
8924130561Sobrien			    }
8925130561Sobrien
8926130561Sobrien			  finfo->indices[r_symndx]
8927130561Sobrien			    = bfd_get_symcount (output_bfd);
8928130561Sobrien
8929130561Sobrien			  if (! elf_link_output_sym (finfo, name, &sym, sec,
8930130561Sobrien						     NULL))
8931130561Sobrien			    return FALSE;
8932130561Sobrien			}
8933130561Sobrien
8934130561Sobrien		      r_symndx = finfo->indices[r_symndx];
8935130561Sobrien		    }
8936130561Sobrien
8937130561Sobrien		  irela->r_info = ((bfd_vma) r_symndx << r_sym_shift
8938130561Sobrien				   | (irela->r_info & r_type_mask));
8939130561Sobrien		}
8940130561Sobrien
8941130561Sobrien	      /* Swap out the relocs.  */
8942130561Sobrien	      if (input_rel_hdr->sh_size != 0
8943218822Sdim		  && !bed->elf_backend_emit_relocs (output_bfd, o,
8944218822Sdim						    input_rel_hdr,
8945218822Sdim						    internal_relocs,
8946218822Sdim						    rel_hash_list))
8947130561Sobrien		return FALSE;
8948130561Sobrien
8949130561Sobrien	      input_rel_hdr2 = elf_section_data (o)->rel_hdr2;
8950130561Sobrien	      if (input_rel_hdr2 && input_rel_hdr2->sh_size != 0)
8951130561Sobrien		{
8952130561Sobrien		  internal_relocs += (NUM_SHDR_ENTRIES (input_rel_hdr)
8953130561Sobrien				      * bed->s->int_rels_per_ext_rel);
8954218822Sdim		  rel_hash_list += NUM_SHDR_ENTRIES (input_rel_hdr);
8955218822Sdim		  if (!bed->elf_backend_emit_relocs (output_bfd, o,
8956218822Sdim						     input_rel_hdr2,
8957218822Sdim						     internal_relocs,
8958218822Sdim						     rel_hash_list))
8959130561Sobrien		    return FALSE;
8960130561Sobrien		}
8961130561Sobrien	    }
8962130561Sobrien	}
8963130561Sobrien
8964130561Sobrien      /* Write out the modified section contents.  */
8965130561Sobrien      if (bed->elf_backend_write_section
8966218822Sdim	  && (*bed->elf_backend_write_section) (output_bfd, finfo->info, o,
8967218822Sdim						contents))
8968130561Sobrien	{
8969130561Sobrien	  /* Section written out.  */
8970130561Sobrien	}
8971130561Sobrien      else switch (o->sec_info_type)
8972130561Sobrien	{
8973130561Sobrien	case ELF_INFO_TYPE_STABS:
8974130561Sobrien	  if (! (_bfd_write_section_stabs
8975130561Sobrien		 (output_bfd,
8976130561Sobrien		  &elf_hash_table (finfo->info)->stab_info,
8977130561Sobrien		  o, &elf_section_data (o)->sec_info, contents)))
8978130561Sobrien	    return FALSE;
8979130561Sobrien	  break;
8980130561Sobrien	case ELF_INFO_TYPE_MERGE:
8981130561Sobrien	  if (! _bfd_write_merged_section (output_bfd, o,
8982130561Sobrien					   elf_section_data (o)->sec_info))
8983130561Sobrien	    return FALSE;
8984130561Sobrien	  break;
8985130561Sobrien	case ELF_INFO_TYPE_EH_FRAME:
8986130561Sobrien	  {
8987130561Sobrien	    if (! _bfd_elf_write_section_eh_frame (output_bfd, finfo->info,
8988130561Sobrien						   o, contents))
8989130561Sobrien	      return FALSE;
8990130561Sobrien	  }
8991130561Sobrien	  break;
8992130561Sobrien	default:
8993130561Sobrien	  {
8994130561Sobrien	    if (! (o->flags & SEC_EXCLUDE)
8995130561Sobrien		&& ! bfd_set_section_contents (output_bfd, o->output_section,
8996130561Sobrien					       contents,
8997130561Sobrien					       (file_ptr) o->output_offset,
8998218822Sdim					       o->size))
8999130561Sobrien	      return FALSE;
9000130561Sobrien	  }
9001130561Sobrien	  break;
9002130561Sobrien	}
9003130561Sobrien    }
9004130561Sobrien
9005130561Sobrien  return TRUE;
9006130561Sobrien}
9007130561Sobrien
9008130561Sobrien/* Generate a reloc when linking an ELF file.  This is a reloc
9009218822Sdim   requested by the linker, and does not come from any input file.  This
9010130561Sobrien   is used to build constructor and destructor tables when linking
9011130561Sobrien   with -Ur.  */
9012130561Sobrien
9013130561Sobrienstatic bfd_boolean
9014130561Sobrienelf_reloc_link_order (bfd *output_bfd,
9015130561Sobrien		      struct bfd_link_info *info,
9016130561Sobrien		      asection *output_section,
9017130561Sobrien		      struct bfd_link_order *link_order)
9018130561Sobrien{
9019130561Sobrien  reloc_howto_type *howto;
9020130561Sobrien  long indx;
9021130561Sobrien  bfd_vma offset;
9022130561Sobrien  bfd_vma addend;
9023130561Sobrien  struct elf_link_hash_entry **rel_hash_ptr;
9024130561Sobrien  Elf_Internal_Shdr *rel_hdr;
9025130561Sobrien  const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
9026130561Sobrien  Elf_Internal_Rela irel[MAX_INT_RELS_PER_EXT_REL];
9027130561Sobrien  bfd_byte *erel;
9028130561Sobrien  unsigned int i;
9029130561Sobrien
9030130561Sobrien  howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc);
9031130561Sobrien  if (howto == NULL)
9032130561Sobrien    {
9033130561Sobrien      bfd_set_error (bfd_error_bad_value);
9034130561Sobrien      return FALSE;
9035130561Sobrien    }
9036130561Sobrien
9037130561Sobrien  addend = link_order->u.reloc.p->addend;
9038130561Sobrien
9039130561Sobrien  /* Figure out the symbol index.  */
9040130561Sobrien  rel_hash_ptr = (elf_section_data (output_section)->rel_hashes
9041130561Sobrien		  + elf_section_data (output_section)->rel_count
9042130561Sobrien		  + elf_section_data (output_section)->rel_count2);
9043130561Sobrien  if (link_order->type == bfd_section_reloc_link_order)
9044130561Sobrien    {
9045130561Sobrien      indx = link_order->u.reloc.p->u.section->target_index;
9046130561Sobrien      BFD_ASSERT (indx != 0);
9047130561Sobrien      *rel_hash_ptr = NULL;
9048130561Sobrien    }
9049130561Sobrien  else
9050130561Sobrien    {
9051130561Sobrien      struct elf_link_hash_entry *h;
9052130561Sobrien
9053130561Sobrien      /* Treat a reloc against a defined symbol as though it were
9054130561Sobrien	 actually against the section.  */
9055130561Sobrien      h = ((struct elf_link_hash_entry *)
9056130561Sobrien	   bfd_wrapped_link_hash_lookup (output_bfd, info,
9057130561Sobrien					 link_order->u.reloc.p->u.name,
9058130561Sobrien					 FALSE, FALSE, TRUE));
9059130561Sobrien      if (h != NULL
9060130561Sobrien	  && (h->root.type == bfd_link_hash_defined
9061130561Sobrien	      || h->root.type == bfd_link_hash_defweak))
9062130561Sobrien	{
9063130561Sobrien	  asection *section;
9064130561Sobrien
9065130561Sobrien	  section = h->root.u.def.section;
9066130561Sobrien	  indx = section->output_section->target_index;
9067130561Sobrien	  *rel_hash_ptr = NULL;
9068130561Sobrien	  /* It seems that we ought to add the symbol value to the
9069130561Sobrien	     addend here, but in practice it has already been added
9070130561Sobrien	     because it was passed to constructor_callback.  */
9071130561Sobrien	  addend += section->output_section->vma + section->output_offset;
9072130561Sobrien	}
9073130561Sobrien      else if (h != NULL)
9074130561Sobrien	{
9075130561Sobrien	  /* Setting the index to -2 tells elf_link_output_extsym that
9076130561Sobrien	     this symbol is used by a reloc.  */
9077130561Sobrien	  h->indx = -2;
9078130561Sobrien	  *rel_hash_ptr = h;
9079130561Sobrien	  indx = 0;
9080130561Sobrien	}
9081130561Sobrien      else
9082130561Sobrien	{
9083130561Sobrien	  if (! ((*info->callbacks->unattached_reloc)
9084130561Sobrien		 (info, link_order->u.reloc.p->u.name, NULL, NULL, 0)))
9085130561Sobrien	    return FALSE;
9086130561Sobrien	  indx = 0;
9087130561Sobrien	}
9088130561Sobrien    }
9089130561Sobrien
9090130561Sobrien  /* If this is an inplace reloc, we must write the addend into the
9091130561Sobrien     object file.  */
9092130561Sobrien  if (howto->partial_inplace && addend != 0)
9093130561Sobrien    {
9094130561Sobrien      bfd_size_type size;
9095130561Sobrien      bfd_reloc_status_type rstat;
9096130561Sobrien      bfd_byte *buf;
9097130561Sobrien      bfd_boolean ok;
9098130561Sobrien      const char *sym_name;
9099130561Sobrien
9100130561Sobrien      size = bfd_get_reloc_size (howto);
9101130561Sobrien      buf = bfd_zmalloc (size);
9102130561Sobrien      if (buf == NULL)
9103130561Sobrien	return FALSE;
9104130561Sobrien      rstat = _bfd_relocate_contents (howto, output_bfd, addend, buf);
9105130561Sobrien      switch (rstat)
9106130561Sobrien	{
9107130561Sobrien	case bfd_reloc_ok:
9108130561Sobrien	  break;
9109130561Sobrien
9110130561Sobrien	default:
9111130561Sobrien	case bfd_reloc_outofrange:
9112130561Sobrien	  abort ();
9113130561Sobrien
9114130561Sobrien	case bfd_reloc_overflow:
9115130561Sobrien	  if (link_order->type == bfd_section_reloc_link_order)
9116130561Sobrien	    sym_name = bfd_section_name (output_bfd,
9117130561Sobrien					 link_order->u.reloc.p->u.section);
9118130561Sobrien	  else
9119130561Sobrien	    sym_name = link_order->u.reloc.p->u.name;
9120130561Sobrien	  if (! ((*info->callbacks->reloc_overflow)
9121218822Sdim		 (info, NULL, sym_name, howto->name, addend, NULL,
9122218822Sdim		  NULL, (bfd_vma) 0)))
9123130561Sobrien	    {
9124130561Sobrien	      free (buf);
9125130561Sobrien	      return FALSE;
9126130561Sobrien	    }
9127130561Sobrien	  break;
9128130561Sobrien	}
9129130561Sobrien      ok = bfd_set_section_contents (output_bfd, output_section, buf,
9130130561Sobrien				     link_order->offset, size);
9131130561Sobrien      free (buf);
9132130561Sobrien      if (! ok)
9133130561Sobrien	return FALSE;
9134130561Sobrien    }
9135130561Sobrien
9136130561Sobrien  /* The address of a reloc is relative to the section in a
9137130561Sobrien     relocatable file, and is a virtual address in an executable
9138130561Sobrien     file.  */
9139130561Sobrien  offset = link_order->offset;
9140130561Sobrien  if (! info->relocatable)
9141130561Sobrien    offset += output_section->vma;
9142130561Sobrien
9143130561Sobrien  for (i = 0; i < bed->s->int_rels_per_ext_rel; i++)
9144130561Sobrien    {
9145130561Sobrien      irel[i].r_offset = offset;
9146130561Sobrien      irel[i].r_info = 0;
9147130561Sobrien      irel[i].r_addend = 0;
9148130561Sobrien    }
9149130561Sobrien  if (bed->s->arch_size == 32)
9150130561Sobrien    irel[0].r_info = ELF32_R_INFO (indx, howto->type);
9151130561Sobrien  else
9152130561Sobrien    irel[0].r_info = ELF64_R_INFO (indx, howto->type);
9153130561Sobrien
9154130561Sobrien  rel_hdr = &elf_section_data (output_section)->rel_hdr;
9155130561Sobrien  erel = rel_hdr->contents;
9156130561Sobrien  if (rel_hdr->sh_type == SHT_REL)
9157130561Sobrien    {
9158130561Sobrien      erel += (elf_section_data (output_section)->rel_count
9159130561Sobrien	       * bed->s->sizeof_rel);
9160130561Sobrien      (*bed->s->swap_reloc_out) (output_bfd, irel, erel);
9161130561Sobrien    }
9162130561Sobrien  else
9163130561Sobrien    {
9164130561Sobrien      irel[0].r_addend = addend;
9165130561Sobrien      erel += (elf_section_data (output_section)->rel_count
9166130561Sobrien	       * bed->s->sizeof_rela);
9167130561Sobrien      (*bed->s->swap_reloca_out) (output_bfd, irel, erel);
9168130561Sobrien    }
9169130561Sobrien
9170130561Sobrien  ++elf_section_data (output_section)->rel_count;
9171130561Sobrien
9172130561Sobrien  return TRUE;
9173130561Sobrien}
9174130561Sobrien
9175218822Sdim
9176218822Sdim/* Get the output vma of the section pointed to by the sh_link field.  */
9177218822Sdim
9178218822Sdimstatic bfd_vma
9179218822Sdimelf_get_linked_section_vma (struct bfd_link_order *p)
9180218822Sdim{
9181218822Sdim  Elf_Internal_Shdr **elf_shdrp;
9182218822Sdim  asection *s;
9183218822Sdim  int elfsec;
9184218822Sdim
9185218822Sdim  s = p->u.indirect.section;
9186218822Sdim  elf_shdrp = elf_elfsections (s->owner);
9187218822Sdim  elfsec = _bfd_elf_section_from_bfd_section (s->owner, s);
9188218822Sdim  elfsec = elf_shdrp[elfsec]->sh_link;
9189218822Sdim  /* PR 290:
9190218822Sdim     The Intel C compiler generates SHT_IA_64_UNWIND with
9191218822Sdim     SHF_LINK_ORDER.  But it doesn't set the sh_link or
9192218822Sdim     sh_info fields.  Hence we could get the situation
9193218822Sdim     where elfsec is 0.  */
9194218822Sdim  if (elfsec == 0)
9195218822Sdim    {
9196218822Sdim      const struct elf_backend_data *bed
9197218822Sdim	= get_elf_backend_data (s->owner);
9198218822Sdim      if (bed->link_order_error_handler)
9199218822Sdim	bed->link_order_error_handler
9200218822Sdim	  (_("%B: warning: sh_link not set for section `%A'"), s->owner, s);
9201218822Sdim      return 0;
9202218822Sdim    }
9203218822Sdim  else
9204218822Sdim    {
9205218822Sdim      s = elf_shdrp[elfsec]->bfd_section;
9206218822Sdim      return s->output_section->vma + s->output_offset;
9207218822Sdim    }
9208218822Sdim}
9209218822Sdim
9210218822Sdim
9211218822Sdim/* Compare two sections based on the locations of the sections they are
9212218822Sdim   linked to.  Used by elf_fixup_link_order.  */
9213218822Sdim
9214218822Sdimstatic int
9215218822Sdimcompare_link_order (const void * a, const void * b)
9216218822Sdim{
9217218822Sdim  bfd_vma apos;
9218218822Sdim  bfd_vma bpos;
9219218822Sdim
9220218822Sdim  apos = elf_get_linked_section_vma (*(struct bfd_link_order **)a);
9221218822Sdim  bpos = elf_get_linked_section_vma (*(struct bfd_link_order **)b);
9222218822Sdim  if (apos < bpos)
9223218822Sdim    return -1;
9224218822Sdim  return apos > bpos;
9225218822Sdim}
9226218822Sdim
9227218822Sdim
9228218822Sdim/* Looks for sections with SHF_LINK_ORDER set.  Rearranges them into the same
9229218822Sdim   order as their linked sections.  Returns false if this could not be done
9230218822Sdim   because an output section includes both ordered and unordered
9231218822Sdim   sections.  Ideally we'd do this in the linker proper.  */
9232218822Sdim
9233218822Sdimstatic bfd_boolean
9234218822Sdimelf_fixup_link_order (bfd *abfd, asection *o)
9235218822Sdim{
9236218822Sdim  int seen_linkorder;
9237218822Sdim  int seen_other;
9238218822Sdim  int n;
9239218822Sdim  struct bfd_link_order *p;
9240218822Sdim  bfd *sub;
9241218822Sdim  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
9242218822Sdim  unsigned elfsec;
9243218822Sdim  struct bfd_link_order **sections;
9244218822Sdim  asection *s, *other_sec, *linkorder_sec;
9245218822Sdim  bfd_vma offset;
9246218822Sdim
9247218822Sdim  other_sec = NULL;
9248218822Sdim  linkorder_sec = NULL;
9249218822Sdim  seen_other = 0;
9250218822Sdim  seen_linkorder = 0;
9251218822Sdim  for (p = o->map_head.link_order; p != NULL; p = p->next)
9252218822Sdim    {
9253218822Sdim      if (p->type == bfd_indirect_link_order)
9254218822Sdim	{
9255218822Sdim	  s = p->u.indirect.section;
9256218822Sdim	  sub = s->owner;
9257218822Sdim	  if (bfd_get_flavour (sub) == bfd_target_elf_flavour
9258218822Sdim	      && elf_elfheader (sub)->e_ident[EI_CLASS] == bed->s->elfclass
9259218822Sdim	      && (elfsec = _bfd_elf_section_from_bfd_section (sub, s))
9260218822Sdim	      && elfsec < elf_numsections (sub)
9261218822Sdim	      && elf_elfsections (sub)[elfsec]->sh_flags & SHF_LINK_ORDER)
9262218822Sdim	    {
9263218822Sdim	      seen_linkorder++;
9264218822Sdim	      linkorder_sec = s;
9265218822Sdim	    }
9266218822Sdim	  else
9267218822Sdim	    {
9268218822Sdim	      seen_other++;
9269218822Sdim	      other_sec = s;
9270218822Sdim	    }
9271218822Sdim	}
9272218822Sdim      else
9273218822Sdim	seen_other++;
9274218822Sdim
9275218822Sdim      if (seen_other && seen_linkorder)
9276218822Sdim	{
9277218822Sdim	  if (other_sec && linkorder_sec)
9278218822Sdim	    (*_bfd_error_handler) (_("%A has both ordered [`%A' in %B] and unordered [`%A' in %B] sections"),
9279218822Sdim				   o, linkorder_sec,
9280218822Sdim				   linkorder_sec->owner, other_sec,
9281218822Sdim				   other_sec->owner);
9282218822Sdim	  else
9283218822Sdim	    (*_bfd_error_handler) (_("%A has both ordered and unordered sections"),
9284218822Sdim				   o);
9285218822Sdim	  bfd_set_error (bfd_error_bad_value);
9286218822Sdim	  return FALSE;
9287218822Sdim	}
9288218822Sdim    }
9289218822Sdim
9290218822Sdim  if (!seen_linkorder)
9291218822Sdim    return TRUE;
9292218822Sdim
9293218822Sdim  sections = (struct bfd_link_order **)
9294218822Sdim    xmalloc (seen_linkorder * sizeof (struct bfd_link_order *));
9295218822Sdim  seen_linkorder = 0;
9296218822Sdim
9297218822Sdim  for (p = o->map_head.link_order; p != NULL; p = p->next)
9298218822Sdim    {
9299218822Sdim      sections[seen_linkorder++] = p;
9300218822Sdim    }
9301218822Sdim  /* Sort the input sections in the order of their linked section.  */
9302218822Sdim  qsort (sections, seen_linkorder, sizeof (struct bfd_link_order *),
9303218822Sdim	 compare_link_order);
9304218822Sdim
9305218822Sdim  /* Change the offsets of the sections.  */
9306218822Sdim  offset = 0;
9307218822Sdim  for (n = 0; n < seen_linkorder; n++)
9308218822Sdim    {
9309218822Sdim      s = sections[n]->u.indirect.section;
9310218822Sdim      offset &= ~(bfd_vma)((1 << s->alignment_power) - 1);
9311218822Sdim      s->output_offset = offset;
9312218822Sdim      sections[n]->offset = offset;
9313218822Sdim      offset += sections[n]->size;
9314218822Sdim    }
9315218822Sdim
9316218822Sdim  return TRUE;
9317218822Sdim}
9318218822Sdim
9319218822Sdim
9320130561Sobrien/* Do the final step of an ELF link.  */
9321130561Sobrien
9322130561Sobrienbfd_boolean
9323130561Sobrienbfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
9324130561Sobrien{
9325130561Sobrien  bfd_boolean dynamic;
9326130561Sobrien  bfd_boolean emit_relocs;
9327130561Sobrien  bfd *dynobj;
9328130561Sobrien  struct elf_final_link_info finfo;
9329130561Sobrien  register asection *o;
9330130561Sobrien  register struct bfd_link_order *p;
9331130561Sobrien  register bfd *sub;
9332130561Sobrien  bfd_size_type max_contents_size;
9333130561Sobrien  bfd_size_type max_external_reloc_size;
9334130561Sobrien  bfd_size_type max_internal_reloc_count;
9335130561Sobrien  bfd_size_type max_sym_count;
9336130561Sobrien  bfd_size_type max_sym_shndx_count;
9337130561Sobrien  file_ptr off;
9338130561Sobrien  Elf_Internal_Sym elfsym;
9339130561Sobrien  unsigned int i;
9340130561Sobrien  Elf_Internal_Shdr *symtab_hdr;
9341130561Sobrien  Elf_Internal_Shdr *symtab_shndx_hdr;
9342130561Sobrien  Elf_Internal_Shdr *symstrtab_hdr;
9343130561Sobrien  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
9344130561Sobrien  struct elf_outext_info eoinfo;
9345130561Sobrien  bfd_boolean merged;
9346130561Sobrien  size_t relativecount = 0;
9347130561Sobrien  asection *reldyn = 0;
9348130561Sobrien  bfd_size_type amt;
9349218822Sdim  asection *attr_section = NULL;
9350218822Sdim  bfd_vma attr_size = 0;
9351218822Sdim  const char *std_attrs_section;
9352130561Sobrien
9353130561Sobrien  if (! is_elf_hash_table (info->hash))
9354130561Sobrien    return FALSE;
9355130561Sobrien
9356130561Sobrien  if (info->shared)
9357130561Sobrien    abfd->flags |= DYNAMIC;
9358130561Sobrien
9359130561Sobrien  dynamic = elf_hash_table (info)->dynamic_sections_created;
9360130561Sobrien  dynobj = elf_hash_table (info)->dynobj;
9361130561Sobrien
9362130561Sobrien  emit_relocs = (info->relocatable
9363218822Sdim		 || info->emitrelocations);
9364130561Sobrien
9365130561Sobrien  finfo.info = info;
9366130561Sobrien  finfo.output_bfd = abfd;
9367130561Sobrien  finfo.symstrtab = _bfd_elf_stringtab_init ();
9368130561Sobrien  if (finfo.symstrtab == NULL)
9369130561Sobrien    return FALSE;
9370130561Sobrien
9371130561Sobrien  if (! dynamic)
9372130561Sobrien    {
9373130561Sobrien      finfo.dynsym_sec = NULL;
9374130561Sobrien      finfo.hash_sec = NULL;
9375130561Sobrien      finfo.symver_sec = NULL;
9376130561Sobrien    }
9377130561Sobrien  else
9378130561Sobrien    {
9379130561Sobrien      finfo.dynsym_sec = bfd_get_section_by_name (dynobj, ".dynsym");
9380130561Sobrien      finfo.hash_sec = bfd_get_section_by_name (dynobj, ".hash");
9381218822Sdim      BFD_ASSERT (finfo.dynsym_sec != NULL);
9382130561Sobrien      finfo.symver_sec = bfd_get_section_by_name (dynobj, ".gnu.version");
9383130561Sobrien      /* Note that it is OK if symver_sec is NULL.  */
9384130561Sobrien    }
9385130561Sobrien
9386130561Sobrien  finfo.contents = NULL;
9387130561Sobrien  finfo.external_relocs = NULL;
9388130561Sobrien  finfo.internal_relocs = NULL;
9389130561Sobrien  finfo.external_syms = NULL;
9390130561Sobrien  finfo.locsym_shndx = NULL;
9391130561Sobrien  finfo.internal_syms = NULL;
9392130561Sobrien  finfo.indices = NULL;
9393130561Sobrien  finfo.sections = NULL;
9394130561Sobrien  finfo.symbuf = NULL;
9395130561Sobrien  finfo.symshndxbuf = NULL;
9396130561Sobrien  finfo.symbuf_count = 0;
9397130561Sobrien  finfo.shndxbuf_size = 0;
9398130561Sobrien
9399218822Sdim  /* The object attributes have been merged.  Remove the input
9400218822Sdim     sections from the link, and set the contents of the output
9401218822Sdim     secton.  */
9402218822Sdim  std_attrs_section = get_elf_backend_data (abfd)->obj_attrs_section;
9403218822Sdim  for (o = abfd->sections; o != NULL; o = o->next)
9404218822Sdim    {
9405218822Sdim      if ((std_attrs_section && strcmp (o->name, std_attrs_section) == 0)
9406218822Sdim	  || strcmp (o->name, ".gnu.attributes") == 0)
9407218822Sdim	{
9408218822Sdim	  for (p = o->map_head.link_order; p != NULL; p = p->next)
9409218822Sdim	    {
9410218822Sdim	      asection *input_section;
9411218822Sdim
9412218822Sdim	      if (p->type != bfd_indirect_link_order)
9413218822Sdim		continue;
9414218822Sdim	      input_section = p->u.indirect.section;
9415218822Sdim	      /* Hack: reset the SEC_HAS_CONTENTS flag so that
9416218822Sdim		 elf_link_input_bfd ignores this section.  */
9417218822Sdim	      input_section->flags &= ~SEC_HAS_CONTENTS;
9418218822Sdim	    }
9419218822Sdim
9420218822Sdim	  attr_size = bfd_elf_obj_attr_size (abfd);
9421218822Sdim	  if (attr_size)
9422218822Sdim	    {
9423218822Sdim	      bfd_set_section_size (abfd, o, attr_size);
9424218822Sdim	      attr_section = o;
9425218822Sdim	      /* Skip this section later on.  */
9426218822Sdim	      o->map_head.link_order = NULL;
9427218822Sdim	    }
9428218822Sdim	  else
9429218822Sdim	    o->flags |= SEC_EXCLUDE;
9430218822Sdim	}
9431218822Sdim    }
9432218822Sdim
9433130561Sobrien  /* Count up the number of relocations we will output for each output
9434130561Sobrien     section, so that we know the sizes of the reloc sections.  We
9435130561Sobrien     also figure out some maximum sizes.  */
9436130561Sobrien  max_contents_size = 0;
9437130561Sobrien  max_external_reloc_size = 0;
9438130561Sobrien  max_internal_reloc_count = 0;
9439130561Sobrien  max_sym_count = 0;
9440130561Sobrien  max_sym_shndx_count = 0;
9441130561Sobrien  merged = FALSE;
9442130561Sobrien  for (o = abfd->sections; o != NULL; o = o->next)
9443130561Sobrien    {
9444130561Sobrien      struct bfd_elf_section_data *esdo = elf_section_data (o);
9445130561Sobrien      o->reloc_count = 0;
9446130561Sobrien
9447218822Sdim      for (p = o->map_head.link_order; p != NULL; p = p->next)
9448130561Sobrien	{
9449130561Sobrien	  unsigned int reloc_count = 0;
9450130561Sobrien	  struct bfd_elf_section_data *esdi = NULL;
9451130561Sobrien	  unsigned int *rel_count1;
9452130561Sobrien
9453130561Sobrien	  if (p->type == bfd_section_reloc_link_order
9454130561Sobrien	      || p->type == bfd_symbol_reloc_link_order)
9455130561Sobrien	    reloc_count = 1;
9456130561Sobrien	  else if (p->type == bfd_indirect_link_order)
9457130561Sobrien	    {
9458130561Sobrien	      asection *sec;
9459130561Sobrien
9460130561Sobrien	      sec = p->u.indirect.section;
9461130561Sobrien	      esdi = elf_section_data (sec);
9462130561Sobrien
9463130561Sobrien	      /* Mark all sections which are to be included in the
9464130561Sobrien		 link.  This will normally be every section.  We need
9465130561Sobrien		 to do this so that we can identify any sections which
9466130561Sobrien		 the linker has decided to not include.  */
9467130561Sobrien	      sec->linker_mark = TRUE;
9468130561Sobrien
9469130561Sobrien	      if (sec->flags & SEC_MERGE)
9470130561Sobrien		merged = TRUE;
9471130561Sobrien
9472130561Sobrien	      if (info->relocatable || info->emitrelocations)
9473130561Sobrien		reloc_count = sec->reloc_count;
9474130561Sobrien	      else if (bed->elf_backend_count_relocs)
9475130561Sobrien		{
9476130561Sobrien		  Elf_Internal_Rela * relocs;
9477130561Sobrien
9478218822Sdim		  relocs = _bfd_elf_link_read_relocs (sec->owner, sec,
9479218822Sdim						      NULL, NULL,
9480130561Sobrien						      info->keep_memory);
9481130561Sobrien
9482218822Sdim		  if (relocs != NULL)
9483218822Sdim		    {
9484218822Sdim		      reloc_count
9485218822Sdim			= (*bed->elf_backend_count_relocs) (sec, relocs);
9486130561Sobrien
9487218822Sdim		      if (elf_section_data (sec)->relocs != relocs)
9488218822Sdim			free (relocs);
9489218822Sdim		    }
9490130561Sobrien		}
9491130561Sobrien
9492218822Sdim	      if (sec->rawsize > max_contents_size)
9493218822Sdim		max_contents_size = sec->rawsize;
9494218822Sdim	      if (sec->size > max_contents_size)
9495218822Sdim		max_contents_size = sec->size;
9496130561Sobrien
9497130561Sobrien	      /* We are interested in just local symbols, not all
9498130561Sobrien		 symbols.  */
9499130561Sobrien	      if (bfd_get_flavour (sec->owner) == bfd_target_elf_flavour
9500130561Sobrien		  && (sec->owner->flags & DYNAMIC) == 0)
9501130561Sobrien		{
9502130561Sobrien		  size_t sym_count;
9503130561Sobrien
9504130561Sobrien		  if (elf_bad_symtab (sec->owner))
9505130561Sobrien		    sym_count = (elf_tdata (sec->owner)->symtab_hdr.sh_size
9506130561Sobrien				 / bed->s->sizeof_sym);
9507130561Sobrien		  else
9508130561Sobrien		    sym_count = elf_tdata (sec->owner)->symtab_hdr.sh_info;
9509130561Sobrien
9510130561Sobrien		  if (sym_count > max_sym_count)
9511130561Sobrien		    max_sym_count = sym_count;
9512130561Sobrien
9513130561Sobrien		  if (sym_count > max_sym_shndx_count
9514130561Sobrien		      && elf_symtab_shndx (sec->owner) != 0)
9515130561Sobrien		    max_sym_shndx_count = sym_count;
9516130561Sobrien
9517130561Sobrien		  if ((sec->flags & SEC_RELOC) != 0)
9518130561Sobrien		    {
9519130561Sobrien		      size_t ext_size;
9520130561Sobrien
9521130561Sobrien		      ext_size = elf_section_data (sec)->rel_hdr.sh_size;
9522130561Sobrien		      if (ext_size > max_external_reloc_size)
9523130561Sobrien			max_external_reloc_size = ext_size;
9524130561Sobrien		      if (sec->reloc_count > max_internal_reloc_count)
9525130561Sobrien			max_internal_reloc_count = sec->reloc_count;
9526130561Sobrien		    }
9527130561Sobrien		}
9528130561Sobrien	    }
9529130561Sobrien
9530130561Sobrien	  if (reloc_count == 0)
9531130561Sobrien	    continue;
9532130561Sobrien
9533130561Sobrien	  o->reloc_count += reloc_count;
9534130561Sobrien
9535130561Sobrien	  /* MIPS may have a mix of REL and RELA relocs on sections.
9536130561Sobrien	     To support this curious ABI we keep reloc counts in
9537130561Sobrien	     elf_section_data too.  We must be careful to add the
9538130561Sobrien	     relocations from the input section to the right output
9539130561Sobrien	     count.  FIXME: Get rid of one count.  We have
9540130561Sobrien	     o->reloc_count == esdo->rel_count + esdo->rel_count2.  */
9541130561Sobrien	  rel_count1 = &esdo->rel_count;
9542130561Sobrien	  if (esdi != NULL)
9543130561Sobrien	    {
9544130561Sobrien	      bfd_boolean same_size;
9545130561Sobrien	      bfd_size_type entsize1;
9546130561Sobrien
9547130561Sobrien	      entsize1 = esdi->rel_hdr.sh_entsize;
9548130561Sobrien	      BFD_ASSERT (entsize1 == bed->s->sizeof_rel
9549130561Sobrien			  || entsize1 == bed->s->sizeof_rela);
9550130561Sobrien	      same_size = !o->use_rela_p == (entsize1 == bed->s->sizeof_rel);
9551130561Sobrien
9552130561Sobrien	      if (!same_size)
9553130561Sobrien		rel_count1 = &esdo->rel_count2;
9554130561Sobrien
9555130561Sobrien	      if (esdi->rel_hdr2 != NULL)
9556130561Sobrien		{
9557130561Sobrien		  bfd_size_type entsize2 = esdi->rel_hdr2->sh_entsize;
9558130561Sobrien		  unsigned int alt_count;
9559130561Sobrien		  unsigned int *rel_count2;
9560130561Sobrien
9561130561Sobrien		  BFD_ASSERT (entsize2 != entsize1
9562130561Sobrien			      && (entsize2 == bed->s->sizeof_rel
9563130561Sobrien				  || entsize2 == bed->s->sizeof_rela));
9564130561Sobrien
9565130561Sobrien		  rel_count2 = &esdo->rel_count2;
9566130561Sobrien		  if (!same_size)
9567130561Sobrien		    rel_count2 = &esdo->rel_count;
9568130561Sobrien
9569130561Sobrien		  /* The following is probably too simplistic if the
9570130561Sobrien		     backend counts output relocs unusually.  */
9571130561Sobrien		  BFD_ASSERT (bed->elf_backend_count_relocs == NULL);
9572130561Sobrien		  alt_count = NUM_SHDR_ENTRIES (esdi->rel_hdr2);
9573130561Sobrien		  *rel_count2 += alt_count;
9574130561Sobrien		  reloc_count -= alt_count;
9575130561Sobrien		}
9576130561Sobrien	    }
9577130561Sobrien	  *rel_count1 += reloc_count;
9578130561Sobrien	}
9579130561Sobrien
9580130561Sobrien      if (o->reloc_count > 0)
9581130561Sobrien	o->flags |= SEC_RELOC;
9582130561Sobrien      else
9583130561Sobrien	{
9584130561Sobrien	  /* Explicitly clear the SEC_RELOC flag.  The linker tends to
9585130561Sobrien	     set it (this is probably a bug) and if it is set
9586130561Sobrien	     assign_section_numbers will create a reloc section.  */
9587130561Sobrien	  o->flags &=~ SEC_RELOC;
9588130561Sobrien	}
9589130561Sobrien
9590130561Sobrien      /* If the SEC_ALLOC flag is not set, force the section VMA to
9591130561Sobrien	 zero.  This is done in elf_fake_sections as well, but forcing
9592130561Sobrien	 the VMA to 0 here will ensure that relocs against these
9593130561Sobrien	 sections are handled correctly.  */
9594130561Sobrien      if ((o->flags & SEC_ALLOC) == 0
9595130561Sobrien	  && ! o->user_set_vma)
9596130561Sobrien	o->vma = 0;
9597130561Sobrien    }
9598130561Sobrien
9599130561Sobrien  if (! info->relocatable && merged)
9600130561Sobrien    elf_link_hash_traverse (elf_hash_table (info),
9601130561Sobrien			    _bfd_elf_link_sec_merge_syms, abfd);
9602130561Sobrien
9603130561Sobrien  /* Figure out the file positions for everything but the symbol table
9604130561Sobrien     and the relocs.  We set symcount to force assign_section_numbers
9605130561Sobrien     to create a symbol table.  */
9606130561Sobrien  bfd_get_symcount (abfd) = info->strip == strip_all ? 0 : 1;
9607130561Sobrien  BFD_ASSERT (! abfd->output_has_begun);
9608130561Sobrien  if (! _bfd_elf_compute_section_file_positions (abfd, info))
9609130561Sobrien    goto error_return;
9610130561Sobrien
9611218822Sdim  /* Set sizes, and assign file positions for reloc sections.  */
9612130561Sobrien  for (o = abfd->sections; o != NULL; o = o->next)
9613130561Sobrien    {
9614130561Sobrien      if ((o->flags & SEC_RELOC) != 0)
9615130561Sobrien	{
9616130561Sobrien	  if (!(_bfd_elf_link_size_reloc_section
9617130561Sobrien		(abfd, &elf_section_data (o)->rel_hdr, o)))
9618130561Sobrien	    goto error_return;
9619130561Sobrien
9620130561Sobrien	  if (elf_section_data (o)->rel_hdr2
9621130561Sobrien	      && !(_bfd_elf_link_size_reloc_section
9622130561Sobrien		   (abfd, elf_section_data (o)->rel_hdr2, o)))
9623130561Sobrien	    goto error_return;
9624130561Sobrien	}
9625130561Sobrien
9626130561Sobrien      /* Now, reset REL_COUNT and REL_COUNT2 so that we can use them
9627130561Sobrien	 to count upwards while actually outputting the relocations.  */
9628130561Sobrien      elf_section_data (o)->rel_count = 0;
9629130561Sobrien      elf_section_data (o)->rel_count2 = 0;
9630130561Sobrien    }
9631130561Sobrien
9632130561Sobrien  _bfd_elf_assign_file_positions_for_relocs (abfd);
9633130561Sobrien
9634130561Sobrien  /* We have now assigned file positions for all the sections except
9635130561Sobrien     .symtab and .strtab.  We start the .symtab section at the current
9636130561Sobrien     file position, and write directly to it.  We build the .strtab
9637130561Sobrien     section in memory.  */
9638130561Sobrien  bfd_get_symcount (abfd) = 0;
9639130561Sobrien  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
9640130561Sobrien  /* sh_name is set in prep_headers.  */
9641130561Sobrien  symtab_hdr->sh_type = SHT_SYMTAB;
9642130561Sobrien  /* sh_flags, sh_addr and sh_size all start off zero.  */
9643130561Sobrien  symtab_hdr->sh_entsize = bed->s->sizeof_sym;
9644130561Sobrien  /* sh_link is set in assign_section_numbers.  */
9645130561Sobrien  /* sh_info is set below.  */
9646130561Sobrien  /* sh_offset is set just below.  */
9647130561Sobrien  symtab_hdr->sh_addralign = 1 << bed->s->log_file_align;
9648130561Sobrien
9649130561Sobrien  off = elf_tdata (abfd)->next_file_pos;
9650130561Sobrien  off = _bfd_elf_assign_file_position_for_section (symtab_hdr, off, TRUE);
9651130561Sobrien
9652130561Sobrien  /* Note that at this point elf_tdata (abfd)->next_file_pos is
9653130561Sobrien     incorrect.  We do not yet know the size of the .symtab section.
9654130561Sobrien     We correct next_file_pos below, after we do know the size.  */
9655130561Sobrien
9656130561Sobrien  /* Allocate a buffer to hold swapped out symbols.  This is to avoid
9657130561Sobrien     continuously seeking to the right position in the file.  */
9658130561Sobrien  if (! info->keep_memory || max_sym_count < 20)
9659130561Sobrien    finfo.symbuf_size = 20;
9660130561Sobrien  else
9661130561Sobrien    finfo.symbuf_size = max_sym_count;
9662130561Sobrien  amt = finfo.symbuf_size;
9663130561Sobrien  amt *= bed->s->sizeof_sym;
9664130561Sobrien  finfo.symbuf = bfd_malloc (amt);
9665130561Sobrien  if (finfo.symbuf == NULL)
9666130561Sobrien    goto error_return;
9667130561Sobrien  if (elf_numsections (abfd) > SHN_LORESERVE)
9668130561Sobrien    {
9669130561Sobrien      /* Wild guess at number of output symbols.  realloc'd as needed.  */
9670130561Sobrien      amt = 2 * max_sym_count + elf_numsections (abfd) + 1000;
9671130561Sobrien      finfo.shndxbuf_size = amt;
9672130561Sobrien      amt *= sizeof (Elf_External_Sym_Shndx);
9673130561Sobrien      finfo.symshndxbuf = bfd_zmalloc (amt);
9674130561Sobrien      if (finfo.symshndxbuf == NULL)
9675130561Sobrien	goto error_return;
9676130561Sobrien    }
9677130561Sobrien
9678130561Sobrien  /* Start writing out the symbol table.  The first symbol is always a
9679130561Sobrien     dummy symbol.  */
9680130561Sobrien  if (info->strip != strip_all
9681130561Sobrien      || emit_relocs)
9682130561Sobrien    {
9683130561Sobrien      elfsym.st_value = 0;
9684130561Sobrien      elfsym.st_size = 0;
9685130561Sobrien      elfsym.st_info = 0;
9686130561Sobrien      elfsym.st_other = 0;
9687130561Sobrien      elfsym.st_shndx = SHN_UNDEF;
9688130561Sobrien      if (! elf_link_output_sym (&finfo, NULL, &elfsym, bfd_und_section_ptr,
9689130561Sobrien				 NULL))
9690130561Sobrien	goto error_return;
9691130561Sobrien    }
9692130561Sobrien
9693130561Sobrien  /* Output a symbol for each section.  We output these even if we are
9694130561Sobrien     discarding local symbols, since they are used for relocs.  These
9695130561Sobrien     symbols have no names.  We store the index of each one in the
9696130561Sobrien     index field of the section, so that we can find it again when
9697130561Sobrien     outputting relocs.  */
9698130561Sobrien  if (info->strip != strip_all
9699130561Sobrien      || emit_relocs)
9700130561Sobrien    {
9701130561Sobrien      elfsym.st_size = 0;
9702130561Sobrien      elfsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
9703130561Sobrien      elfsym.st_other = 0;
9704218822Sdim      elfsym.st_value = 0;
9705130561Sobrien      for (i = 1; i < elf_numsections (abfd); i++)
9706130561Sobrien	{
9707130561Sobrien	  o = bfd_section_from_elf_index (abfd, i);
9708130561Sobrien	  if (o != NULL)
9709218822Sdim	    {
9710218822Sdim	      o->target_index = bfd_get_symcount (abfd);
9711218822Sdim	      elfsym.st_shndx = i;
9712218822Sdim	      if (!info->relocatable)
9713218822Sdim		elfsym.st_value = o->vma;
9714218822Sdim	      if (!elf_link_output_sym (&finfo, NULL, &elfsym, o, NULL))
9715218822Sdim		goto error_return;
9716218822Sdim	    }
9717130561Sobrien	  if (i == SHN_LORESERVE - 1)
9718130561Sobrien	    i += SHN_HIRESERVE + 1 - SHN_LORESERVE;
9719130561Sobrien	}
9720130561Sobrien    }
9721130561Sobrien
9722130561Sobrien  /* Allocate some memory to hold information read in from the input
9723130561Sobrien     files.  */
9724130561Sobrien  if (max_contents_size != 0)
9725130561Sobrien    {
9726130561Sobrien      finfo.contents = bfd_malloc (max_contents_size);
9727130561Sobrien      if (finfo.contents == NULL)
9728130561Sobrien	goto error_return;
9729130561Sobrien    }
9730130561Sobrien
9731130561Sobrien  if (max_external_reloc_size != 0)
9732130561Sobrien    {
9733130561Sobrien      finfo.external_relocs = bfd_malloc (max_external_reloc_size);
9734130561Sobrien      if (finfo.external_relocs == NULL)
9735130561Sobrien	goto error_return;
9736130561Sobrien    }
9737130561Sobrien
9738130561Sobrien  if (max_internal_reloc_count != 0)
9739130561Sobrien    {
9740130561Sobrien      amt = max_internal_reloc_count * bed->s->int_rels_per_ext_rel;
9741130561Sobrien      amt *= sizeof (Elf_Internal_Rela);
9742130561Sobrien      finfo.internal_relocs = bfd_malloc (amt);
9743130561Sobrien      if (finfo.internal_relocs == NULL)
9744130561Sobrien	goto error_return;
9745130561Sobrien    }
9746130561Sobrien
9747130561Sobrien  if (max_sym_count != 0)
9748130561Sobrien    {
9749130561Sobrien      amt = max_sym_count * bed->s->sizeof_sym;
9750130561Sobrien      finfo.external_syms = bfd_malloc (amt);
9751130561Sobrien      if (finfo.external_syms == NULL)
9752130561Sobrien	goto error_return;
9753130561Sobrien
9754130561Sobrien      amt = max_sym_count * sizeof (Elf_Internal_Sym);
9755130561Sobrien      finfo.internal_syms = bfd_malloc (amt);
9756130561Sobrien      if (finfo.internal_syms == NULL)
9757130561Sobrien	goto error_return;
9758130561Sobrien
9759130561Sobrien      amt = max_sym_count * sizeof (long);
9760130561Sobrien      finfo.indices = bfd_malloc (amt);
9761130561Sobrien      if (finfo.indices == NULL)
9762130561Sobrien	goto error_return;
9763130561Sobrien
9764130561Sobrien      amt = max_sym_count * sizeof (asection *);
9765130561Sobrien      finfo.sections = bfd_malloc (amt);
9766130561Sobrien      if (finfo.sections == NULL)
9767130561Sobrien	goto error_return;
9768130561Sobrien    }
9769130561Sobrien
9770130561Sobrien  if (max_sym_shndx_count != 0)
9771130561Sobrien    {
9772130561Sobrien      amt = max_sym_shndx_count * sizeof (Elf_External_Sym_Shndx);
9773130561Sobrien      finfo.locsym_shndx = bfd_malloc (amt);
9774130561Sobrien      if (finfo.locsym_shndx == NULL)
9775130561Sobrien	goto error_return;
9776130561Sobrien    }
9777130561Sobrien
9778130561Sobrien  if (elf_hash_table (info)->tls_sec)
9779130561Sobrien    {
9780130561Sobrien      bfd_vma base, end = 0;
9781130561Sobrien      asection *sec;
9782130561Sobrien
9783130561Sobrien      for (sec = elf_hash_table (info)->tls_sec;
9784130561Sobrien	   sec && (sec->flags & SEC_THREAD_LOCAL);
9785130561Sobrien	   sec = sec->next)
9786130561Sobrien	{
9787218822Sdim	  bfd_size_type size = sec->size;
9788130561Sobrien
9789218822Sdim	  if (size == 0
9790218822Sdim	      && (sec->flags & SEC_HAS_CONTENTS) == 0)
9791130561Sobrien	    {
9792218822Sdim	      struct bfd_link_order *o = sec->map_tail.link_order;
9793218822Sdim	      if (o != NULL)
9794218822Sdim		size = o->offset + o->size;
9795130561Sobrien	    }
9796130561Sobrien	  end = sec->vma + size;
9797130561Sobrien	}
9798130561Sobrien      base = elf_hash_table (info)->tls_sec->vma;
9799130561Sobrien      end = align_power (end, elf_hash_table (info)->tls_sec->alignment_power);
9800130561Sobrien      elf_hash_table (info)->tls_size = end - base;
9801130561Sobrien    }
9802130561Sobrien
9803218822Sdim  /* Reorder SHF_LINK_ORDER sections.  */
9804218822Sdim  for (o = abfd->sections; o != NULL; o = o->next)
9805218822Sdim    {
9806218822Sdim      if (!elf_fixup_link_order (abfd, o))
9807218822Sdim	return FALSE;
9808218822Sdim    }
9809218822Sdim
9810130561Sobrien  /* Since ELF permits relocations to be against local symbols, we
9811130561Sobrien     must have the local symbols available when we do the relocations.
9812130561Sobrien     Since we would rather only read the local symbols once, and we
9813130561Sobrien     would rather not keep them in memory, we handle all the
9814130561Sobrien     relocations for a single input file at the same time.
9815130561Sobrien
9816130561Sobrien     Unfortunately, there is no way to know the total number of local
9817130561Sobrien     symbols until we have seen all of them, and the local symbol
9818130561Sobrien     indices precede the global symbol indices.  This means that when
9819130561Sobrien     we are generating relocatable output, and we see a reloc against
9820130561Sobrien     a global symbol, we can not know the symbol index until we have
9821130561Sobrien     finished examining all the local symbols to see which ones we are
9822130561Sobrien     going to output.  To deal with this, we keep the relocations in
9823130561Sobrien     memory, and don't output them until the end of the link.  This is
9824130561Sobrien     an unfortunate waste of memory, but I don't see a good way around
9825130561Sobrien     it.  Fortunately, it only happens when performing a relocatable
9826130561Sobrien     link, which is not the common case.  FIXME: If keep_memory is set
9827130561Sobrien     we could write the relocs out and then read them again; I don't
9828130561Sobrien     know how bad the memory loss will be.  */
9829130561Sobrien
9830130561Sobrien  for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
9831130561Sobrien    sub->output_has_begun = FALSE;
9832130561Sobrien  for (o = abfd->sections; o != NULL; o = o->next)
9833130561Sobrien    {
9834218822Sdim      for (p = o->map_head.link_order; p != NULL; p = p->next)
9835130561Sobrien	{
9836130561Sobrien	  if (p->type == bfd_indirect_link_order
9837130561Sobrien	      && (bfd_get_flavour ((sub = p->u.indirect.section->owner))
9838130561Sobrien		  == bfd_target_elf_flavour)
9839130561Sobrien	      && elf_elfheader (sub)->e_ident[EI_CLASS] == bed->s->elfclass)
9840130561Sobrien	    {
9841130561Sobrien	      if (! sub->output_has_begun)
9842130561Sobrien		{
9843130561Sobrien		  if (! elf_link_input_bfd (&finfo, sub))
9844130561Sobrien		    goto error_return;
9845130561Sobrien		  sub->output_has_begun = TRUE;
9846130561Sobrien		}
9847130561Sobrien	    }
9848130561Sobrien	  else if (p->type == bfd_section_reloc_link_order
9849130561Sobrien		   || p->type == bfd_symbol_reloc_link_order)
9850130561Sobrien	    {
9851130561Sobrien	      if (! elf_reloc_link_order (abfd, info, o, p))
9852130561Sobrien		goto error_return;
9853130561Sobrien	    }
9854130561Sobrien	  else
9855130561Sobrien	    {
9856130561Sobrien	      if (! _bfd_default_link_order (abfd, info, o, p))
9857130561Sobrien		goto error_return;
9858130561Sobrien	    }
9859130561Sobrien	}
9860130561Sobrien    }
9861130561Sobrien
9862218822Sdim  /* Free symbol buffer if needed.  */
9863218822Sdim  if (!info->reduce_memory_overheads)
9864218822Sdim    {
9865218822Sdim      for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
9866218822Sdim	if (bfd_get_flavour (sub) == bfd_target_elf_flavour
9867218822Sdim	    && elf_tdata (sub)->symbuf)
9868218822Sdim	  {
9869218822Sdim	    free (elf_tdata (sub)->symbuf);
9870218822Sdim	    elf_tdata (sub)->symbuf = NULL;
9871218822Sdim	  }
9872218822Sdim    }
9873218822Sdim
9874130561Sobrien  /* Output any global symbols that got converted to local in a
9875130561Sobrien     version script or due to symbol visibility.  We do this in a
9876130561Sobrien     separate step since ELF requires all local symbols to appear
9877130561Sobrien     prior to any global symbols.  FIXME: We should only do this if
9878130561Sobrien     some global symbols were, in fact, converted to become local.
9879130561Sobrien     FIXME: Will this work correctly with the Irix 5 linker?  */
9880130561Sobrien  eoinfo.failed = FALSE;
9881130561Sobrien  eoinfo.finfo = &finfo;
9882130561Sobrien  eoinfo.localsyms = TRUE;
9883130561Sobrien  elf_link_hash_traverse (elf_hash_table (info), elf_link_output_extsym,
9884130561Sobrien			  &eoinfo);
9885130561Sobrien  if (eoinfo.failed)
9886130561Sobrien    return FALSE;
9887130561Sobrien
9888218822Sdim  /* If backend needs to output some local symbols not present in the hash
9889218822Sdim     table, do it now.  */
9890218822Sdim  if (bed->elf_backend_output_arch_local_syms)
9891218822Sdim    {
9892218822Sdim      typedef bfd_boolean (*out_sym_func)
9893218822Sdim	(void *, const char *, Elf_Internal_Sym *, asection *,
9894218822Sdim	 struct elf_link_hash_entry *);
9895218822Sdim
9896218822Sdim      if (! ((*bed->elf_backend_output_arch_local_syms)
9897218822Sdim	     (abfd, info, &finfo, (out_sym_func) elf_link_output_sym)))
9898218822Sdim	return FALSE;
9899218822Sdim    }
9900218822Sdim
9901130561Sobrien  /* That wrote out all the local symbols.  Finish up the symbol table
9902130561Sobrien     with the global symbols. Even if we want to strip everything we
9903130561Sobrien     can, we still need to deal with those global symbols that got
9904130561Sobrien     converted to local in a version script.  */
9905130561Sobrien
9906130561Sobrien  /* The sh_info field records the index of the first non local symbol.  */
9907130561Sobrien  symtab_hdr->sh_info = bfd_get_symcount (abfd);
9908130561Sobrien
9909130561Sobrien  if (dynamic
9910130561Sobrien      && finfo.dynsym_sec->output_section != bfd_abs_section_ptr)
9911130561Sobrien    {
9912130561Sobrien      Elf_Internal_Sym sym;
9913130561Sobrien      bfd_byte *dynsym = finfo.dynsym_sec->contents;
9914130561Sobrien      long last_local = 0;
9915130561Sobrien
9916130561Sobrien      /* Write out the section symbols for the output sections.  */
9917218822Sdim      if (info->shared || elf_hash_table (info)->is_relocatable_executable)
9918130561Sobrien	{
9919130561Sobrien	  asection *s;
9920130561Sobrien
9921130561Sobrien	  sym.st_size = 0;
9922130561Sobrien	  sym.st_name = 0;
9923130561Sobrien	  sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
9924130561Sobrien	  sym.st_other = 0;
9925130561Sobrien
9926130561Sobrien	  for (s = abfd->sections; s != NULL; s = s->next)
9927130561Sobrien	    {
9928130561Sobrien	      int indx;
9929130561Sobrien	      bfd_byte *dest;
9930130561Sobrien	      long dynindx;
9931130561Sobrien
9932218822Sdim	      dynindx = elf_section_data (s)->dynindx;
9933218822Sdim	      if (dynindx <= 0)
9934218822Sdim		continue;
9935130561Sobrien	      indx = elf_section_data (s)->this_idx;
9936130561Sobrien	      BFD_ASSERT (indx > 0);
9937130561Sobrien	      sym.st_shndx = indx;
9938218822Sdim	      if (! check_dynsym (abfd, &sym))
9939218822Sdim		return FALSE;
9940130561Sobrien	      sym.st_value = s->vma;
9941130561Sobrien	      dest = dynsym + dynindx * bed->s->sizeof_sym;
9942218822Sdim	      if (last_local < dynindx)
9943218822Sdim		last_local = dynindx;
9944130561Sobrien	      bed->s->swap_symbol_out (abfd, &sym, dest, 0);
9945130561Sobrien	    }
9946130561Sobrien	}
9947130561Sobrien
9948130561Sobrien      /* Write out the local dynsyms.  */
9949130561Sobrien      if (elf_hash_table (info)->dynlocal)
9950130561Sobrien	{
9951130561Sobrien	  struct elf_link_local_dynamic_entry *e;
9952130561Sobrien	  for (e = elf_hash_table (info)->dynlocal; e ; e = e->next)
9953130561Sobrien	    {
9954130561Sobrien	      asection *s;
9955130561Sobrien	      bfd_byte *dest;
9956130561Sobrien
9957130561Sobrien	      sym.st_size = e->isym.st_size;
9958130561Sobrien	      sym.st_other = e->isym.st_other;
9959130561Sobrien
9960130561Sobrien	      /* Copy the internal symbol as is.
9961130561Sobrien		 Note that we saved a word of storage and overwrote
9962130561Sobrien		 the original st_name with the dynstr_index.  */
9963130561Sobrien	      sym = e->isym;
9964130561Sobrien
9965130561Sobrien	      if (e->isym.st_shndx != SHN_UNDEF
9966130561Sobrien		  && (e->isym.st_shndx < SHN_LORESERVE
9967130561Sobrien		      || e->isym.st_shndx > SHN_HIRESERVE))
9968130561Sobrien		{
9969130561Sobrien		  s = bfd_section_from_elf_index (e->input_bfd,
9970130561Sobrien						  e->isym.st_shndx);
9971130561Sobrien
9972130561Sobrien		  sym.st_shndx =
9973130561Sobrien		    elf_section_data (s->output_section)->this_idx;
9974218822Sdim		  if (! check_dynsym (abfd, &sym))
9975218822Sdim		    return FALSE;
9976130561Sobrien		  sym.st_value = (s->output_section->vma
9977130561Sobrien				  + s->output_offset
9978130561Sobrien				  + e->isym.st_value);
9979130561Sobrien		}
9980130561Sobrien
9981130561Sobrien	      if (last_local < e->dynindx)
9982130561Sobrien		last_local = e->dynindx;
9983130561Sobrien
9984130561Sobrien	      dest = dynsym + e->dynindx * bed->s->sizeof_sym;
9985130561Sobrien	      bed->s->swap_symbol_out (abfd, &sym, dest, 0);
9986130561Sobrien	    }
9987130561Sobrien	}
9988130561Sobrien
9989130561Sobrien      elf_section_data (finfo.dynsym_sec->output_section)->this_hdr.sh_info =
9990130561Sobrien	last_local + 1;
9991130561Sobrien    }
9992130561Sobrien
9993130561Sobrien  /* We get the global symbols from the hash table.  */
9994130561Sobrien  eoinfo.failed = FALSE;
9995130561Sobrien  eoinfo.localsyms = FALSE;
9996130561Sobrien  eoinfo.finfo = &finfo;
9997130561Sobrien  elf_link_hash_traverse (elf_hash_table (info), elf_link_output_extsym,
9998130561Sobrien			  &eoinfo);
9999130561Sobrien  if (eoinfo.failed)
10000130561Sobrien    return FALSE;
10001130561Sobrien
10002130561Sobrien  /* If backend needs to output some symbols not present in the hash
10003130561Sobrien     table, do it now.  */
10004130561Sobrien  if (bed->elf_backend_output_arch_syms)
10005130561Sobrien    {
10006130561Sobrien      typedef bfd_boolean (*out_sym_func)
10007130561Sobrien	(void *, const char *, Elf_Internal_Sym *, asection *,
10008130561Sobrien	 struct elf_link_hash_entry *);
10009130561Sobrien
10010130561Sobrien      if (! ((*bed->elf_backend_output_arch_syms)
10011130561Sobrien	     (abfd, info, &finfo, (out_sym_func) elf_link_output_sym)))
10012130561Sobrien	return FALSE;
10013130561Sobrien    }
10014130561Sobrien
10015130561Sobrien  /* Flush all symbols to the file.  */
10016130561Sobrien  if (! elf_link_flush_output_syms (&finfo, bed))
10017130561Sobrien    return FALSE;
10018130561Sobrien
10019130561Sobrien  /* Now we know the size of the symtab section.  */
10020130561Sobrien  off += symtab_hdr->sh_size;
10021130561Sobrien
10022130561Sobrien  symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
10023130561Sobrien  if (symtab_shndx_hdr->sh_name != 0)
10024130561Sobrien    {
10025130561Sobrien      symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX;
10026130561Sobrien      symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx);
10027130561Sobrien      symtab_shndx_hdr->sh_addralign = sizeof (Elf_External_Sym_Shndx);
10028130561Sobrien      amt = bfd_get_symcount (abfd) * sizeof (Elf_External_Sym_Shndx);
10029130561Sobrien      symtab_shndx_hdr->sh_size = amt;
10030130561Sobrien
10031130561Sobrien      off = _bfd_elf_assign_file_position_for_section (symtab_shndx_hdr,
10032130561Sobrien						       off, TRUE);
10033130561Sobrien
10034130561Sobrien      if (bfd_seek (abfd, symtab_shndx_hdr->sh_offset, SEEK_SET) != 0
10035130561Sobrien	  || (bfd_bwrite (finfo.symshndxbuf, amt, abfd) != amt))
10036130561Sobrien	return FALSE;
10037130561Sobrien    }
10038130561Sobrien
10039130561Sobrien
10040130561Sobrien  /* Finish up and write out the symbol string table (.strtab)
10041130561Sobrien     section.  */
10042130561Sobrien  symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
10043130561Sobrien  /* sh_name was set in prep_headers.  */
10044130561Sobrien  symstrtab_hdr->sh_type = SHT_STRTAB;
10045130561Sobrien  symstrtab_hdr->sh_flags = 0;
10046130561Sobrien  symstrtab_hdr->sh_addr = 0;
10047130561Sobrien  symstrtab_hdr->sh_size = _bfd_stringtab_size (finfo.symstrtab);
10048130561Sobrien  symstrtab_hdr->sh_entsize = 0;
10049130561Sobrien  symstrtab_hdr->sh_link = 0;
10050130561Sobrien  symstrtab_hdr->sh_info = 0;
10051130561Sobrien  /* sh_offset is set just below.  */
10052130561Sobrien  symstrtab_hdr->sh_addralign = 1;
10053130561Sobrien
10054130561Sobrien  off = _bfd_elf_assign_file_position_for_section (symstrtab_hdr, off, TRUE);
10055130561Sobrien  elf_tdata (abfd)->next_file_pos = off;
10056130561Sobrien
10057130561Sobrien  if (bfd_get_symcount (abfd) > 0)
10058130561Sobrien    {
10059130561Sobrien      if (bfd_seek (abfd, symstrtab_hdr->sh_offset, SEEK_SET) != 0
10060130561Sobrien	  || ! _bfd_stringtab_emit (abfd, finfo.symstrtab))
10061130561Sobrien	return FALSE;
10062130561Sobrien    }
10063130561Sobrien
10064130561Sobrien  /* Adjust the relocs to have the correct symbol indices.  */
10065130561Sobrien  for (o = abfd->sections; o != NULL; o = o->next)
10066130561Sobrien    {
10067130561Sobrien      if ((o->flags & SEC_RELOC) == 0)
10068130561Sobrien	continue;
10069130561Sobrien
10070130561Sobrien      elf_link_adjust_relocs (abfd, &elf_section_data (o)->rel_hdr,
10071130561Sobrien			      elf_section_data (o)->rel_count,
10072130561Sobrien			      elf_section_data (o)->rel_hashes);
10073130561Sobrien      if (elf_section_data (o)->rel_hdr2 != NULL)
10074130561Sobrien	elf_link_adjust_relocs (abfd, elf_section_data (o)->rel_hdr2,
10075130561Sobrien				elf_section_data (o)->rel_count2,
10076130561Sobrien				(elf_section_data (o)->rel_hashes
10077130561Sobrien				 + elf_section_data (o)->rel_count));
10078130561Sobrien
10079130561Sobrien      /* Set the reloc_count field to 0 to prevent write_relocs from
10080130561Sobrien	 trying to swap the relocs out itself.  */
10081130561Sobrien      o->reloc_count = 0;
10082130561Sobrien    }
10083130561Sobrien
10084130561Sobrien  if (dynamic && info->combreloc && dynobj != NULL)
10085130561Sobrien    relativecount = elf_link_sort_relocs (abfd, info, &reldyn);
10086130561Sobrien
10087130561Sobrien  /* If we are linking against a dynamic object, or generating a
10088130561Sobrien     shared library, finish up the dynamic linking information.  */
10089130561Sobrien  if (dynamic)
10090130561Sobrien    {
10091130561Sobrien      bfd_byte *dyncon, *dynconend;
10092130561Sobrien
10093130561Sobrien      /* Fix up .dynamic entries.  */
10094130561Sobrien      o = bfd_get_section_by_name (dynobj, ".dynamic");
10095130561Sobrien      BFD_ASSERT (o != NULL);
10096130561Sobrien
10097130561Sobrien      dyncon = o->contents;
10098218822Sdim      dynconend = o->contents + o->size;
10099130561Sobrien      for (; dyncon < dynconend; dyncon += bed->s->sizeof_dyn)
10100130561Sobrien	{
10101130561Sobrien	  Elf_Internal_Dyn dyn;
10102130561Sobrien	  const char *name;
10103130561Sobrien	  unsigned int type;
10104130561Sobrien
10105130561Sobrien	  bed->s->swap_dyn_in (dynobj, dyncon, &dyn);
10106130561Sobrien
10107130561Sobrien	  switch (dyn.d_tag)
10108130561Sobrien	    {
10109130561Sobrien	    default:
10110130561Sobrien	      continue;
10111130561Sobrien	    case DT_NULL:
10112130561Sobrien	      if (relativecount > 0 && dyncon + bed->s->sizeof_dyn < dynconend)
10113130561Sobrien		{
10114130561Sobrien		  switch (elf_section_data (reldyn)->this_hdr.sh_type)
10115130561Sobrien		    {
10116130561Sobrien		    case SHT_REL: dyn.d_tag = DT_RELCOUNT; break;
10117130561Sobrien		    case SHT_RELA: dyn.d_tag = DT_RELACOUNT; break;
10118130561Sobrien		    default: continue;
10119130561Sobrien		    }
10120130561Sobrien		  dyn.d_un.d_val = relativecount;
10121130561Sobrien		  relativecount = 0;
10122130561Sobrien		  break;
10123130561Sobrien		}
10124130561Sobrien	      continue;
10125130561Sobrien
10126130561Sobrien	    case DT_INIT:
10127130561Sobrien	      name = info->init_function;
10128130561Sobrien	      goto get_sym;
10129130561Sobrien	    case DT_FINI:
10130130561Sobrien	      name = info->fini_function;
10131130561Sobrien	    get_sym:
10132130561Sobrien	      {
10133130561Sobrien		struct elf_link_hash_entry *h;
10134130561Sobrien
10135130561Sobrien		h = elf_link_hash_lookup (elf_hash_table (info), name,
10136130561Sobrien					  FALSE, FALSE, TRUE);
10137130561Sobrien		if (h != NULL
10138130561Sobrien		    && (h->root.type == bfd_link_hash_defined
10139130561Sobrien			|| h->root.type == bfd_link_hash_defweak))
10140130561Sobrien		  {
10141130561Sobrien		    dyn.d_un.d_val = h->root.u.def.value;
10142130561Sobrien		    o = h->root.u.def.section;
10143130561Sobrien		    if (o->output_section != NULL)
10144130561Sobrien		      dyn.d_un.d_val += (o->output_section->vma
10145130561Sobrien					 + o->output_offset);
10146130561Sobrien		    else
10147130561Sobrien		      {
10148130561Sobrien			/* The symbol is imported from another shared
10149130561Sobrien			   library and does not apply to this one.  */
10150130561Sobrien			dyn.d_un.d_val = 0;
10151130561Sobrien		      }
10152130561Sobrien		    break;
10153130561Sobrien		  }
10154130561Sobrien	      }
10155130561Sobrien	      continue;
10156130561Sobrien
10157130561Sobrien	    case DT_PREINIT_ARRAYSZ:
10158130561Sobrien	      name = ".preinit_array";
10159130561Sobrien	      goto get_size;
10160130561Sobrien	    case DT_INIT_ARRAYSZ:
10161130561Sobrien	      name = ".init_array";
10162130561Sobrien	      goto get_size;
10163130561Sobrien	    case DT_FINI_ARRAYSZ:
10164130561Sobrien	      name = ".fini_array";
10165130561Sobrien	    get_size:
10166130561Sobrien	      o = bfd_get_section_by_name (abfd, name);
10167130561Sobrien	      if (o == NULL)
10168130561Sobrien		{
10169130561Sobrien		  (*_bfd_error_handler)
10170218822Sdim		    (_("%B: could not find output section %s"), abfd, name);
10171130561Sobrien		  goto error_return;
10172130561Sobrien		}
10173218822Sdim	      if (o->size == 0)
10174130561Sobrien		(*_bfd_error_handler)
10175130561Sobrien		  (_("warning: %s section has zero size"), name);
10176218822Sdim	      dyn.d_un.d_val = o->size;
10177130561Sobrien	      break;
10178130561Sobrien
10179130561Sobrien	    case DT_PREINIT_ARRAY:
10180130561Sobrien	      name = ".preinit_array";
10181130561Sobrien	      goto get_vma;
10182130561Sobrien	    case DT_INIT_ARRAY:
10183130561Sobrien	      name = ".init_array";
10184130561Sobrien	      goto get_vma;
10185130561Sobrien	    case DT_FINI_ARRAY:
10186130561Sobrien	      name = ".fini_array";
10187130561Sobrien	      goto get_vma;
10188130561Sobrien
10189130561Sobrien	    case DT_HASH:
10190130561Sobrien	      name = ".hash";
10191130561Sobrien	      goto get_vma;
10192218822Sdim	    case DT_GNU_HASH:
10193218822Sdim	      name = ".gnu.hash";
10194218822Sdim	      goto get_vma;
10195130561Sobrien	    case DT_STRTAB:
10196130561Sobrien	      name = ".dynstr";
10197130561Sobrien	      goto get_vma;
10198130561Sobrien	    case DT_SYMTAB:
10199130561Sobrien	      name = ".dynsym";
10200130561Sobrien	      goto get_vma;
10201130561Sobrien	    case DT_VERDEF:
10202130561Sobrien	      name = ".gnu.version_d";
10203130561Sobrien	      goto get_vma;
10204130561Sobrien	    case DT_VERNEED:
10205130561Sobrien	      name = ".gnu.version_r";
10206130561Sobrien	      goto get_vma;
10207130561Sobrien	    case DT_VERSYM:
10208130561Sobrien	      name = ".gnu.version";
10209130561Sobrien	    get_vma:
10210130561Sobrien	      o = bfd_get_section_by_name (abfd, name);
10211130561Sobrien	      if (o == NULL)
10212130561Sobrien		{
10213130561Sobrien		  (*_bfd_error_handler)
10214218822Sdim		    (_("%B: could not find output section %s"), abfd, name);
10215130561Sobrien		  goto error_return;
10216130561Sobrien		}
10217130561Sobrien	      dyn.d_un.d_ptr = o->vma;
10218130561Sobrien	      break;
10219130561Sobrien
10220130561Sobrien	    case DT_REL:
10221130561Sobrien	    case DT_RELA:
10222130561Sobrien	    case DT_RELSZ:
10223130561Sobrien	    case DT_RELASZ:
10224130561Sobrien	      if (dyn.d_tag == DT_REL || dyn.d_tag == DT_RELSZ)
10225130561Sobrien		type = SHT_REL;
10226130561Sobrien	      else
10227130561Sobrien		type = SHT_RELA;
10228130561Sobrien	      dyn.d_un.d_val = 0;
10229130561Sobrien	      for (i = 1; i < elf_numsections (abfd); i++)
10230130561Sobrien		{
10231130561Sobrien		  Elf_Internal_Shdr *hdr;
10232130561Sobrien
10233130561Sobrien		  hdr = elf_elfsections (abfd)[i];
10234130561Sobrien		  if (hdr->sh_type == type
10235130561Sobrien		      && (hdr->sh_flags & SHF_ALLOC) != 0)
10236130561Sobrien		    {
10237130561Sobrien		      if (dyn.d_tag == DT_RELSZ || dyn.d_tag == DT_RELASZ)
10238130561Sobrien			dyn.d_un.d_val += hdr->sh_size;
10239130561Sobrien		      else
10240130561Sobrien			{
10241130561Sobrien			  if (dyn.d_un.d_val == 0
10242130561Sobrien			      || hdr->sh_addr < dyn.d_un.d_val)
10243130561Sobrien			    dyn.d_un.d_val = hdr->sh_addr;
10244130561Sobrien			}
10245130561Sobrien		    }
10246130561Sobrien		}
10247130561Sobrien	      break;
10248130561Sobrien	    }
10249130561Sobrien	  bed->s->swap_dyn_out (dynobj, &dyn, dyncon);
10250130561Sobrien	}
10251130561Sobrien    }
10252130561Sobrien
10253130561Sobrien  /* If we have created any dynamic sections, then output them.  */
10254130561Sobrien  if (dynobj != NULL)
10255130561Sobrien    {
10256130561Sobrien      if (! (*bed->elf_backend_finish_dynamic_sections) (abfd, info))
10257130561Sobrien	goto error_return;
10258130561Sobrien
10259218822Sdim      /* Check for DT_TEXTREL (late, in case the backend removes it).  */
10260218822Sdim      if (info->warn_shared_textrel && info->shared)
10261218822Sdim	{
10262218822Sdim	  bfd_byte *dyncon, *dynconend;
10263218822Sdim
10264218822Sdim	  /* Fix up .dynamic entries.  */
10265218822Sdim	  o = bfd_get_section_by_name (dynobj, ".dynamic");
10266218822Sdim	  BFD_ASSERT (o != NULL);
10267218822Sdim
10268218822Sdim	  dyncon = o->contents;
10269218822Sdim	  dynconend = o->contents + o->size;
10270218822Sdim	  for (; dyncon < dynconend; dyncon += bed->s->sizeof_dyn)
10271218822Sdim	    {
10272218822Sdim	      Elf_Internal_Dyn dyn;
10273218822Sdim
10274218822Sdim	      bed->s->swap_dyn_in (dynobj, dyncon, &dyn);
10275218822Sdim
10276218822Sdim	      if (dyn.d_tag == DT_TEXTREL)
10277218822Sdim		{
10278218822Sdim		 info->callbacks->einfo
10279218822Sdim		    (_("%P: warning: creating a DT_TEXTREL in a shared object.\n"));
10280218822Sdim		  break;
10281218822Sdim		}
10282218822Sdim	    }
10283218822Sdim	}
10284218822Sdim
10285130561Sobrien      for (o = dynobj->sections; o != NULL; o = o->next)
10286130561Sobrien	{
10287130561Sobrien	  if ((o->flags & SEC_HAS_CONTENTS) == 0
10288218822Sdim	      || o->size == 0
10289130561Sobrien	      || o->output_section == bfd_abs_section_ptr)
10290130561Sobrien	    continue;
10291130561Sobrien	  if ((o->flags & SEC_LINKER_CREATED) == 0)
10292130561Sobrien	    {
10293130561Sobrien	      /* At this point, we are only interested in sections
10294130561Sobrien		 created by _bfd_elf_link_create_dynamic_sections.  */
10295130561Sobrien	      continue;
10296130561Sobrien	    }
10297218822Sdim	  if (elf_hash_table (info)->stab_info.stabstr == o)
10298218822Sdim	    continue;
10299218822Sdim	  if (elf_hash_table (info)->eh_info.hdr_sec == o)
10300218822Sdim	    continue;
10301130561Sobrien	  if ((elf_section_data (o->output_section)->this_hdr.sh_type
10302130561Sobrien	       != SHT_STRTAB)
10303130561Sobrien	      || strcmp (bfd_get_section_name (abfd, o), ".dynstr") != 0)
10304130561Sobrien	    {
10305130561Sobrien	      if (! bfd_set_section_contents (abfd, o->output_section,
10306130561Sobrien					      o->contents,
10307130561Sobrien					      (file_ptr) o->output_offset,
10308218822Sdim					      o->size))
10309130561Sobrien		goto error_return;
10310130561Sobrien	    }
10311130561Sobrien	  else
10312130561Sobrien	    {
10313130561Sobrien	      /* The contents of the .dynstr section are actually in a
10314130561Sobrien		 stringtab.  */
10315130561Sobrien	      off = elf_section_data (o->output_section)->this_hdr.sh_offset;
10316130561Sobrien	      if (bfd_seek (abfd, off, SEEK_SET) != 0
10317130561Sobrien		  || ! _bfd_elf_strtab_emit (abfd,
10318130561Sobrien					     elf_hash_table (info)->dynstr))
10319130561Sobrien		goto error_return;
10320130561Sobrien	    }
10321130561Sobrien	}
10322130561Sobrien    }
10323130561Sobrien
10324130561Sobrien  if (info->relocatable)
10325130561Sobrien    {
10326130561Sobrien      bfd_boolean failed = FALSE;
10327130561Sobrien
10328130561Sobrien      bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed);
10329130561Sobrien      if (failed)
10330130561Sobrien	goto error_return;
10331130561Sobrien    }
10332130561Sobrien
10333130561Sobrien  /* If we have optimized stabs strings, output them.  */
10334218822Sdim  if (elf_hash_table (info)->stab_info.stabstr != NULL)
10335130561Sobrien    {
10336130561Sobrien      if (! _bfd_write_stab_strings (abfd, &elf_hash_table (info)->stab_info))
10337130561Sobrien	goto error_return;
10338130561Sobrien    }
10339130561Sobrien
10340130561Sobrien  if (info->eh_frame_hdr)
10341130561Sobrien    {
10342130561Sobrien      if (! _bfd_elf_write_section_eh_frame_hdr (abfd, info))
10343130561Sobrien	goto error_return;
10344130561Sobrien    }
10345130561Sobrien
10346130561Sobrien  if (finfo.symstrtab != NULL)
10347130561Sobrien    _bfd_stringtab_free (finfo.symstrtab);
10348130561Sobrien  if (finfo.contents != NULL)
10349130561Sobrien    free (finfo.contents);
10350130561Sobrien  if (finfo.external_relocs != NULL)
10351130561Sobrien    free (finfo.external_relocs);
10352130561Sobrien  if (finfo.internal_relocs != NULL)
10353130561Sobrien    free (finfo.internal_relocs);
10354130561Sobrien  if (finfo.external_syms != NULL)
10355130561Sobrien    free (finfo.external_syms);
10356130561Sobrien  if (finfo.locsym_shndx != NULL)
10357130561Sobrien    free (finfo.locsym_shndx);
10358130561Sobrien  if (finfo.internal_syms != NULL)
10359130561Sobrien    free (finfo.internal_syms);
10360130561Sobrien  if (finfo.indices != NULL)
10361130561Sobrien    free (finfo.indices);
10362130561Sobrien  if (finfo.sections != NULL)
10363130561Sobrien    free (finfo.sections);
10364130561Sobrien  if (finfo.symbuf != NULL)
10365130561Sobrien    free (finfo.symbuf);
10366130561Sobrien  if (finfo.symshndxbuf != NULL)
10367130561Sobrien    free (finfo.symshndxbuf);
10368130561Sobrien  for (o = abfd->sections; o != NULL; o = o->next)
10369130561Sobrien    {
10370130561Sobrien      if ((o->flags & SEC_RELOC) != 0
10371130561Sobrien	  && elf_section_data (o)->rel_hashes != NULL)
10372130561Sobrien	free (elf_section_data (o)->rel_hashes);
10373130561Sobrien    }
10374130561Sobrien
10375130561Sobrien  elf_tdata (abfd)->linker = TRUE;
10376130561Sobrien
10377218822Sdim  if (attr_section)
10378218822Sdim    {
10379218822Sdim      bfd_byte *contents = bfd_malloc (attr_size);
10380218822Sdim      if (contents == NULL)
10381218822Sdim	goto error_return;
10382218822Sdim      bfd_elf_set_obj_attr_contents (abfd, contents, attr_size);
10383218822Sdim      bfd_set_section_contents (abfd, attr_section, contents, 0, attr_size);
10384218822Sdim      free (contents);
10385218822Sdim    }
10386218822Sdim
10387130561Sobrien  return TRUE;
10388130561Sobrien
10389130561Sobrien error_return:
10390130561Sobrien  if (finfo.symstrtab != NULL)
10391130561Sobrien    _bfd_stringtab_free (finfo.symstrtab);
10392130561Sobrien  if (finfo.contents != NULL)
10393130561Sobrien    free (finfo.contents);
10394130561Sobrien  if (finfo.external_relocs != NULL)
10395130561Sobrien    free (finfo.external_relocs);
10396130561Sobrien  if (finfo.internal_relocs != NULL)
10397130561Sobrien    free (finfo.internal_relocs);
10398130561Sobrien  if (finfo.external_syms != NULL)
10399130561Sobrien    free (finfo.external_syms);
10400130561Sobrien  if (finfo.locsym_shndx != NULL)
10401130561Sobrien    free (finfo.locsym_shndx);
10402130561Sobrien  if (finfo.internal_syms != NULL)
10403130561Sobrien    free (finfo.internal_syms);
10404130561Sobrien  if (finfo.indices != NULL)
10405130561Sobrien    free (finfo.indices);
10406130561Sobrien  if (finfo.sections != NULL)
10407130561Sobrien    free (finfo.sections);
10408130561Sobrien  if (finfo.symbuf != NULL)
10409130561Sobrien    free (finfo.symbuf);
10410130561Sobrien  if (finfo.symshndxbuf != NULL)
10411130561Sobrien    free (finfo.symshndxbuf);
10412130561Sobrien  for (o = abfd->sections; o != NULL; o = o->next)
10413130561Sobrien    {
10414130561Sobrien      if ((o->flags & SEC_RELOC) != 0
10415130561Sobrien	  && elf_section_data (o)->rel_hashes != NULL)
10416130561Sobrien	free (elf_section_data (o)->rel_hashes);
10417130561Sobrien    }
10418130561Sobrien
10419130561Sobrien  return FALSE;
1042033965Sjdp}
1042133965Sjdp
10422130561Sobrien/* Garbage collect unused sections.  */
1042333965Sjdp
10424218822Sdim/* Default gc_mark_hook.  */
10425218822Sdim
10426218822Sdimasection *
10427218822Sdim_bfd_elf_gc_mark_hook (asection *sec,
10428218822Sdim		       struct bfd_link_info *info ATTRIBUTE_UNUSED,
10429218822Sdim		       Elf_Internal_Rela *rel ATTRIBUTE_UNUSED,
10430218822Sdim		       struct elf_link_hash_entry *h,
10431218822Sdim		       Elf_Internal_Sym *sym)
10432218822Sdim{
10433218822Sdim  if (h != NULL)
10434218822Sdim    {
10435218822Sdim      switch (h->root.type)
10436218822Sdim	{
10437218822Sdim	case bfd_link_hash_defined:
10438218822Sdim	case bfd_link_hash_defweak:
10439218822Sdim	  return h->root.u.def.section;
10440218822Sdim
10441218822Sdim	case bfd_link_hash_common:
10442218822Sdim	  return h->root.u.c.p->section;
10443218822Sdim
10444218822Sdim	default:
10445218822Sdim	  break;
10446218822Sdim	}
10447218822Sdim    }
10448218822Sdim  else
10449218822Sdim    return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
10450218822Sdim
10451218822Sdim  return NULL;
10452218822Sdim}
10453218822Sdim
10454130561Sobrien/* The mark phase of garbage collection.  For a given section, mark
10455130561Sobrien   it and any sections in this section's group, and all the sections
10456130561Sobrien   which define symbols to which it refers.  */
10457130561Sobrien
10458218822Sdimbfd_boolean
10459218822Sdim_bfd_elf_gc_mark (struct bfd_link_info *info,
10460218822Sdim		  asection *sec,
10461218822Sdim		  elf_gc_mark_hook_fn gc_mark_hook)
1046233965Sjdp{
10463130561Sobrien  bfd_boolean ret;
10464218822Sdim  bfd_boolean is_eh;
10465130561Sobrien  asection *group_sec;
10466130561Sobrien
10467130561Sobrien  sec->gc_mark = 1;
10468130561Sobrien
10469130561Sobrien  /* Mark all the sections in the group.  */
10470130561Sobrien  group_sec = elf_section_data (sec)->next_in_group;
10471130561Sobrien  if (group_sec && !group_sec->gc_mark)
10472218822Sdim    if (!_bfd_elf_gc_mark (info, group_sec, gc_mark_hook))
10473130561Sobrien      return FALSE;
10474130561Sobrien
10475130561Sobrien  /* Look through the section relocs.  */
10476130561Sobrien  ret = TRUE;
10477218822Sdim  is_eh = strcmp (sec->name, ".eh_frame") == 0;
10478130561Sobrien  if ((sec->flags & SEC_RELOC) != 0 && sec->reloc_count > 0)
1047933965Sjdp    {
10480130561Sobrien      Elf_Internal_Rela *relstart, *rel, *relend;
10481130561Sobrien      Elf_Internal_Shdr *symtab_hdr;
10482130561Sobrien      struct elf_link_hash_entry **sym_hashes;
10483130561Sobrien      size_t nlocsyms;
10484130561Sobrien      size_t extsymoff;
10485130561Sobrien      bfd *input_bfd = sec->owner;
10486130561Sobrien      const struct elf_backend_data *bed = get_elf_backend_data (input_bfd);
10487130561Sobrien      Elf_Internal_Sym *isym = NULL;
10488130561Sobrien      int r_sym_shift;
10489130561Sobrien
10490130561Sobrien      symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
10491130561Sobrien      sym_hashes = elf_sym_hashes (input_bfd);
10492130561Sobrien
10493130561Sobrien      /* Read the local symbols.  */
10494130561Sobrien      if (elf_bad_symtab (input_bfd))
10495130561Sobrien	{
10496130561Sobrien	  nlocsyms = symtab_hdr->sh_size / bed->s->sizeof_sym;
10497130561Sobrien	  extsymoff = 0;
10498130561Sobrien	}
10499130561Sobrien      else
10500130561Sobrien	extsymoff = nlocsyms = symtab_hdr->sh_info;
10501130561Sobrien
10502130561Sobrien      isym = (Elf_Internal_Sym *) symtab_hdr->contents;
10503130561Sobrien      if (isym == NULL && nlocsyms != 0)
10504130561Sobrien	{
10505130561Sobrien	  isym = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, nlocsyms, 0,
10506130561Sobrien				       NULL, NULL, NULL);
10507130561Sobrien	  if (isym == NULL)
10508130561Sobrien	    return FALSE;
10509130561Sobrien	}
10510130561Sobrien
10511130561Sobrien      /* Read the relocations.  */
10512130561Sobrien      relstart = _bfd_elf_link_read_relocs (input_bfd, sec, NULL, NULL,
10513130561Sobrien					    info->keep_memory);
10514130561Sobrien      if (relstart == NULL)
10515130561Sobrien	{
10516130561Sobrien	  ret = FALSE;
10517130561Sobrien	  goto out1;
10518130561Sobrien	}
10519130561Sobrien      relend = relstart + sec->reloc_count * bed->s->int_rels_per_ext_rel;
10520130561Sobrien
10521130561Sobrien      if (bed->s->arch_size == 32)
10522130561Sobrien	r_sym_shift = 8;
10523130561Sobrien      else
10524130561Sobrien	r_sym_shift = 32;
10525130561Sobrien
10526130561Sobrien      for (rel = relstart; rel < relend; rel++)
10527130561Sobrien	{
10528130561Sobrien	  unsigned long r_symndx;
10529130561Sobrien	  asection *rsec;
10530130561Sobrien	  struct elf_link_hash_entry *h;
10531130561Sobrien
10532130561Sobrien	  r_symndx = rel->r_info >> r_sym_shift;
10533130561Sobrien	  if (r_symndx == 0)
10534130561Sobrien	    continue;
10535130561Sobrien
10536130561Sobrien	  if (r_symndx >= nlocsyms
10537130561Sobrien	      || ELF_ST_BIND (isym[r_symndx].st_info) != STB_LOCAL)
10538130561Sobrien	    {
10539130561Sobrien	      h = sym_hashes[r_symndx - extsymoff];
10540218822Sdim	      while (h->root.type == bfd_link_hash_indirect
10541218822Sdim		     || h->root.type == bfd_link_hash_warning)
10542218822Sdim		h = (struct elf_link_hash_entry *) h->root.u.i.link;
10543130561Sobrien	      rsec = (*gc_mark_hook) (sec, info, rel, h, NULL);
10544130561Sobrien	    }
10545130561Sobrien	  else
10546130561Sobrien	    {
10547130561Sobrien	      rsec = (*gc_mark_hook) (sec, info, rel, NULL, &isym[r_symndx]);
10548130561Sobrien	    }
10549130561Sobrien
10550130561Sobrien	  if (rsec && !rsec->gc_mark)
10551130561Sobrien	    {
10552130561Sobrien	      if (bfd_get_flavour (rsec->owner) != bfd_target_elf_flavour)
10553130561Sobrien		rsec->gc_mark = 1;
10554218822Sdim	      else if (is_eh)
10555218822Sdim		rsec->gc_mark_from_eh = 1;
10556218822Sdim	      else if (!_bfd_elf_gc_mark (info, rsec, gc_mark_hook))
10557130561Sobrien		{
10558130561Sobrien		  ret = FALSE;
10559130561Sobrien		  goto out2;
10560130561Sobrien		}
10561130561Sobrien	    }
10562130561Sobrien	}
10563130561Sobrien
10564130561Sobrien    out2:
10565130561Sobrien      if (elf_section_data (sec)->relocs != relstart)
10566130561Sobrien	free (relstart);
10567130561Sobrien    out1:
10568130561Sobrien      if (isym != NULL && symtab_hdr->contents != (unsigned char *) isym)
10569130561Sobrien	{
10570130561Sobrien	  if (! info->keep_memory)
10571130561Sobrien	    free (isym);
10572130561Sobrien	  else
10573130561Sobrien	    symtab_hdr->contents = (unsigned char *) isym;
10574130561Sobrien	}
1057533965Sjdp    }
1057633965Sjdp
10577130561Sobrien  return ret;
1057833965Sjdp}
10579130561Sobrien
10580130561Sobrien/* Sweep symbols in swept sections.  Called via elf_link_hash_traverse.  */
10581130561Sobrien
10582218822Sdimstruct elf_gc_sweep_symbol_info
10583218822Sdim{
10584218822Sdim  struct bfd_link_info *info;
10585218822Sdim  void (*hide_symbol) (struct bfd_link_info *, struct elf_link_hash_entry *,
10586218822Sdim		       bfd_boolean);
10587218822Sdim};
10588218822Sdim
10589130561Sobrienstatic bfd_boolean
10590218822Sdimelf_gc_sweep_symbol (struct elf_link_hash_entry *h, void *data)
10591130561Sobrien{
10592130561Sobrien  if (h->root.type == bfd_link_hash_warning)
10593130561Sobrien    h = (struct elf_link_hash_entry *) h->root.u.i.link;
10594130561Sobrien
10595218822Sdim  if ((h->root.type == bfd_link_hash_defined
10596218822Sdim       || h->root.type == bfd_link_hash_defweak)
10597218822Sdim      && !h->root.u.def.section->gc_mark
10598218822Sdim      && !(h->root.u.def.section->owner->flags & DYNAMIC))
10599218822Sdim    {
10600218822Sdim      struct elf_gc_sweep_symbol_info *inf = data;
10601218822Sdim      (*inf->hide_symbol) (inf->info, h, TRUE);
10602218822Sdim    }
10603130561Sobrien
10604130561Sobrien  return TRUE;
10605130561Sobrien}
10606130561Sobrien
10607130561Sobrien/* The sweep phase of garbage collection.  Remove all garbage sections.  */
10608130561Sobrien
10609130561Sobrientypedef bfd_boolean (*gc_sweep_hook_fn)
10610130561Sobrien  (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
10611130561Sobrien
10612130561Sobrienstatic bfd_boolean
10613218822Sdimelf_gc_sweep (bfd *abfd, struct bfd_link_info *info)
10614130561Sobrien{
10615130561Sobrien  bfd *sub;
10616218822Sdim  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
10617218822Sdim  gc_sweep_hook_fn gc_sweep_hook = bed->gc_sweep_hook;
10618218822Sdim  unsigned long section_sym_count;
10619218822Sdim  struct elf_gc_sweep_symbol_info sweep_info;
10620130561Sobrien
10621130561Sobrien  for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
10622130561Sobrien    {
10623130561Sobrien      asection *o;
10624130561Sobrien
10625130561Sobrien      if (bfd_get_flavour (sub) != bfd_target_elf_flavour)
10626130561Sobrien	continue;
10627130561Sobrien
10628130561Sobrien      for (o = sub->sections; o != NULL; o = o->next)
10629130561Sobrien	{
10630218822Sdim	  /* Keep debug and special sections.  */
10631218822Sdim	  if ((o->flags & (SEC_DEBUGGING | SEC_LINKER_CREATED)) != 0
10632244600Sdim	      || elf_section_data (o)->this_hdr.sh_type == SHT_NOTE
10633218822Sdim	      || (o->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0)
10634130561Sobrien	    o->gc_mark = 1;
10635130561Sobrien
10636130561Sobrien	  if (o->gc_mark)
10637130561Sobrien	    continue;
10638130561Sobrien
10639130561Sobrien	  /* Skip sweeping sections already excluded.  */
10640130561Sobrien	  if (o->flags & SEC_EXCLUDE)
10641130561Sobrien	    continue;
10642130561Sobrien
10643130561Sobrien	  /* Since this is early in the link process, it is simple
10644130561Sobrien	     to remove a section from the output.  */
10645130561Sobrien	  o->flags |= SEC_EXCLUDE;
10646130561Sobrien
10647218822Sdim	  if (info->print_gc_sections && o->size != 0)
10648218822Sdim	    _bfd_error_handler (_("Removing unused section '%s' in file '%B'"), sub, o->name);
10649218822Sdim
10650130561Sobrien	  /* But we also have to update some of the relocation
10651130561Sobrien	     info we collected before.  */
10652130561Sobrien	  if (gc_sweep_hook
10653218822Sdim	      && (o->flags & SEC_RELOC) != 0
10654218822Sdim	      && o->reloc_count > 0
10655218822Sdim	      && !bfd_is_abs_section (o->output_section))
10656130561Sobrien	    {
10657130561Sobrien	      Elf_Internal_Rela *internal_relocs;
10658130561Sobrien	      bfd_boolean r;
10659130561Sobrien
10660130561Sobrien	      internal_relocs
10661130561Sobrien		= _bfd_elf_link_read_relocs (o->owner, o, NULL, NULL,
10662130561Sobrien					     info->keep_memory);
10663130561Sobrien	      if (internal_relocs == NULL)
10664130561Sobrien		return FALSE;
10665130561Sobrien
10666130561Sobrien	      r = (*gc_sweep_hook) (o->owner, info, o, internal_relocs);
10667130561Sobrien
10668130561Sobrien	      if (elf_section_data (o)->relocs != internal_relocs)
10669130561Sobrien		free (internal_relocs);
10670130561Sobrien
10671130561Sobrien	      if (!r)
10672130561Sobrien		return FALSE;
10673130561Sobrien	    }
10674130561Sobrien	}
10675130561Sobrien    }
10676130561Sobrien
10677130561Sobrien  /* Remove the symbols that were in the swept sections from the dynamic
10678130561Sobrien     symbol table.  GCFIXME: Anyone know how to get them out of the
10679130561Sobrien     static symbol table as well?  */
10680218822Sdim  sweep_info.info = info;
10681218822Sdim  sweep_info.hide_symbol = bed->elf_backend_hide_symbol;
10682218822Sdim  elf_link_hash_traverse (elf_hash_table (info), elf_gc_sweep_symbol,
10683218822Sdim			  &sweep_info);
10684130561Sobrien
10685218822Sdim  _bfd_elf_link_renumber_dynsyms (abfd, info, &section_sym_count);
10686130561Sobrien  return TRUE;
10687130561Sobrien}
10688130561Sobrien
10689130561Sobrien/* Propagate collected vtable information.  This is called through
10690130561Sobrien   elf_link_hash_traverse.  */
10691130561Sobrien
10692130561Sobrienstatic bfd_boolean
10693130561Sobrienelf_gc_propagate_vtable_entries_used (struct elf_link_hash_entry *h, void *okp)
10694130561Sobrien{
10695130561Sobrien  if (h->root.type == bfd_link_hash_warning)
10696130561Sobrien    h = (struct elf_link_hash_entry *) h->root.u.i.link;
10697130561Sobrien
10698130561Sobrien  /* Those that are not vtables.  */
10699218822Sdim  if (h->vtable == NULL || h->vtable->parent == NULL)
10700130561Sobrien    return TRUE;
10701130561Sobrien
10702130561Sobrien  /* Those vtables that do not have parents, we cannot merge.  */
10703218822Sdim  if (h->vtable->parent == (struct elf_link_hash_entry *) -1)
10704130561Sobrien    return TRUE;
10705130561Sobrien
10706130561Sobrien  /* If we've already been done, exit.  */
10707218822Sdim  if (h->vtable->used && h->vtable->used[-1])
10708130561Sobrien    return TRUE;
10709130561Sobrien
10710130561Sobrien  /* Make sure the parent's table is up to date.  */
10711218822Sdim  elf_gc_propagate_vtable_entries_used (h->vtable->parent, okp);
10712130561Sobrien
10713218822Sdim  if (h->vtable->used == NULL)
10714130561Sobrien    {
10715130561Sobrien      /* None of this table's entries were referenced.  Re-use the
10716130561Sobrien	 parent's table.  */
10717218822Sdim      h->vtable->used = h->vtable->parent->vtable->used;
10718218822Sdim      h->vtable->size = h->vtable->parent->vtable->size;
10719130561Sobrien    }
10720130561Sobrien  else
10721130561Sobrien    {
10722130561Sobrien      size_t n;
10723130561Sobrien      bfd_boolean *cu, *pu;
10724130561Sobrien
10725130561Sobrien      /* Or the parent's entries into ours.  */
10726218822Sdim      cu = h->vtable->used;
10727130561Sobrien      cu[-1] = TRUE;
10728218822Sdim      pu = h->vtable->parent->vtable->used;
10729130561Sobrien      if (pu != NULL)
10730130561Sobrien	{
10731130561Sobrien	  const struct elf_backend_data *bed;
10732130561Sobrien	  unsigned int log_file_align;
10733130561Sobrien
10734130561Sobrien	  bed = get_elf_backend_data (h->root.u.def.section->owner);
10735130561Sobrien	  log_file_align = bed->s->log_file_align;
10736218822Sdim	  n = h->vtable->parent->vtable->size >> log_file_align;
10737130561Sobrien	  while (n--)
10738130561Sobrien	    {
10739130561Sobrien	      if (*pu)
10740130561Sobrien		*cu = TRUE;
10741130561Sobrien	      pu++;
10742130561Sobrien	      cu++;
10743130561Sobrien	    }
10744130561Sobrien	}
10745130561Sobrien    }
10746130561Sobrien
10747130561Sobrien  return TRUE;
10748130561Sobrien}
10749130561Sobrien
10750130561Sobrienstatic bfd_boolean
10751130561Sobrienelf_gc_smash_unused_vtentry_relocs (struct elf_link_hash_entry *h, void *okp)
10752130561Sobrien{
10753130561Sobrien  asection *sec;
10754130561Sobrien  bfd_vma hstart, hend;
10755130561Sobrien  Elf_Internal_Rela *relstart, *relend, *rel;
10756130561Sobrien  const struct elf_backend_data *bed;
10757130561Sobrien  unsigned int log_file_align;
10758130561Sobrien
10759130561Sobrien  if (h->root.type == bfd_link_hash_warning)
10760130561Sobrien    h = (struct elf_link_hash_entry *) h->root.u.i.link;
10761130561Sobrien
10762130561Sobrien  /* Take care of both those symbols that do not describe vtables as
10763130561Sobrien     well as those that are not loaded.  */
10764218822Sdim  if (h->vtable == NULL || h->vtable->parent == NULL)
10765130561Sobrien    return TRUE;
10766130561Sobrien
10767130561Sobrien  BFD_ASSERT (h->root.type == bfd_link_hash_defined
10768130561Sobrien	      || h->root.type == bfd_link_hash_defweak);
10769130561Sobrien
10770130561Sobrien  sec = h->root.u.def.section;
10771130561Sobrien  hstart = h->root.u.def.value;
10772130561Sobrien  hend = hstart + h->size;
10773130561Sobrien
10774130561Sobrien  relstart = _bfd_elf_link_read_relocs (sec->owner, sec, NULL, NULL, TRUE);
10775130561Sobrien  if (!relstart)
10776130561Sobrien    return *(bfd_boolean *) okp = FALSE;
10777130561Sobrien  bed = get_elf_backend_data (sec->owner);
10778130561Sobrien  log_file_align = bed->s->log_file_align;
10779130561Sobrien
10780130561Sobrien  relend = relstart + sec->reloc_count * bed->s->int_rels_per_ext_rel;
10781130561Sobrien
10782130561Sobrien  for (rel = relstart; rel < relend; ++rel)
10783130561Sobrien    if (rel->r_offset >= hstart && rel->r_offset < hend)
10784130561Sobrien      {
10785130561Sobrien	/* If the entry is in use, do nothing.  */
10786218822Sdim	if (h->vtable->used
10787218822Sdim	    && (rel->r_offset - hstart) < h->vtable->size)
10788130561Sobrien	  {
10789130561Sobrien	    bfd_vma entry = (rel->r_offset - hstart) >> log_file_align;
10790218822Sdim	    if (h->vtable->used[entry])
10791130561Sobrien	      continue;
10792130561Sobrien	  }
10793130561Sobrien	/* Otherwise, kill it.  */
10794130561Sobrien	rel->r_offset = rel->r_info = rel->r_addend = 0;
10795130561Sobrien      }
10796130561Sobrien
10797130561Sobrien  return TRUE;
10798130561Sobrien}
10799130561Sobrien
10800218822Sdim/* Mark sections containing dynamically referenced symbols.  When
10801218822Sdim   building shared libraries, we must assume that any visible symbol is
10802218822Sdim   referenced.  */
10803218822Sdim
10804218822Sdimbfd_boolean
10805218822Sdimbfd_elf_gc_mark_dynamic_ref_symbol (struct elf_link_hash_entry *h, void *inf)
10806218822Sdim{
10807218822Sdim  struct bfd_link_info *info = (struct bfd_link_info *) inf;
10808218822Sdim
10809218822Sdim  if (h->root.type == bfd_link_hash_warning)
10810218822Sdim    h = (struct elf_link_hash_entry *) h->root.u.i.link;
10811218822Sdim
10812218822Sdim  if ((h->root.type == bfd_link_hash_defined
10813218822Sdim       || h->root.type == bfd_link_hash_defweak)
10814218822Sdim      && (h->ref_dynamic
10815218822Sdim	  || (!info->executable
10816218822Sdim	      && h->def_regular
10817218822Sdim	      && ELF_ST_VISIBILITY (h->other) != STV_INTERNAL
10818218822Sdim	      && ELF_ST_VISIBILITY (h->other) != STV_HIDDEN)))
10819218822Sdim    h->root.u.def.section->flags |= SEC_KEEP;
10820218822Sdim
10821218822Sdim  return TRUE;
10822218822Sdim}
10823218822Sdim
10824130561Sobrien/* Do mark and sweep of unused sections.  */
10825130561Sobrien
10826130561Sobrienbfd_boolean
10827130561Sobrienbfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info)
10828130561Sobrien{
10829130561Sobrien  bfd_boolean ok = TRUE;
10830130561Sobrien  bfd *sub;
10831218822Sdim  elf_gc_mark_hook_fn gc_mark_hook;
10832218822Sdim  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
10833130561Sobrien
10834218822Sdim  if (!bed->can_gc_sections
10835130561Sobrien      || info->relocatable
10836130561Sobrien      || info->emitrelocations
10837218822Sdim      || !is_elf_hash_table (info->hash))
10838130561Sobrien    {
10839130561Sobrien      (*_bfd_error_handler)(_("Warning: gc-sections option ignored"));
10840130561Sobrien      return TRUE;
10841130561Sobrien    }
10842130561Sobrien
10843130561Sobrien  /* Apply transitive closure to the vtable entry usage info.  */
10844130561Sobrien  elf_link_hash_traverse (elf_hash_table (info),
10845130561Sobrien			  elf_gc_propagate_vtable_entries_used,
10846130561Sobrien			  &ok);
10847130561Sobrien  if (!ok)
10848130561Sobrien    return FALSE;
10849130561Sobrien
10850130561Sobrien  /* Kill the vtable relocations that were not used.  */
10851130561Sobrien  elf_link_hash_traverse (elf_hash_table (info),
10852130561Sobrien			  elf_gc_smash_unused_vtentry_relocs,
10853130561Sobrien			  &ok);
10854130561Sobrien  if (!ok)
10855130561Sobrien    return FALSE;
10856130561Sobrien
10857218822Sdim  /* Mark dynamically referenced symbols.  */
10858218822Sdim  if (elf_hash_table (info)->dynamic_sections_created)
10859218822Sdim    elf_link_hash_traverse (elf_hash_table (info),
10860218822Sdim			    bed->gc_mark_dynamic_ref,
10861218822Sdim			    info);
10862218822Sdim
10863130561Sobrien  /* Grovel through relocs to find out who stays ...  */
10864218822Sdim  gc_mark_hook = bed->gc_mark_hook;
10865218822Sdim  for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
10866218822Sdim    {
10867218822Sdim      asection *o;
10868130561Sobrien
10869218822Sdim      if (bfd_get_flavour (sub) != bfd_target_elf_flavour)
10870218822Sdim	continue;
10871218822Sdim
10872218822Sdim      for (o = sub->sections; o != NULL; o = o->next)
10873218822Sdim	if ((o->flags & (SEC_EXCLUDE | SEC_KEEP)) == SEC_KEEP && !o->gc_mark)
10874218822Sdim	  if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
10875218822Sdim	    return FALSE;
10876218822Sdim    }
10877218822Sdim
10878218822Sdim  /* Allow the backend to mark additional target specific sections.  */
10879218822Sdim  if (bed->gc_mark_extra_sections)
10880218822Sdim    bed->gc_mark_extra_sections(info, gc_mark_hook);
10881218822Sdim
10882218822Sdim  /* ... again for sections marked from eh_frame.  */
10883130561Sobrien  for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
10884130561Sobrien    {
10885130561Sobrien      asection *o;
10886130561Sobrien
10887130561Sobrien      if (bfd_get_flavour (sub) != bfd_target_elf_flavour)
10888130561Sobrien	continue;
10889130561Sobrien
10890218822Sdim      /* Keep .gcc_except_table.* if the associated .text.* (or the
10891218822Sdim	 associated .gnu.linkonce.t.* if .text.* doesn't exist) is
10892218822Sdim	 marked.  This isn't very nice, but the proper solution,
10893218822Sdim	 splitting .eh_frame up and using comdat doesn't pan out
10894218822Sdim	 easily due to needing special relocs to handle the
10895218822Sdim	 difference of two symbols in separate sections.
10896218822Sdim	 Don't keep code sections referenced by .eh_frame.  */
10897218822Sdim#define TEXT_PREFIX			".text."
10898218822Sdim#define TEXT_PREFIX2			".gnu.linkonce.t."
10899218822Sdim#define GCC_EXCEPT_TABLE_PREFIX		".gcc_except_table."
10900130561Sobrien      for (o = sub->sections; o != NULL; o = o->next)
10901218822Sdim	if (!o->gc_mark && o->gc_mark_from_eh && (o->flags & SEC_CODE) == 0)
10902218822Sdim	  {
10903218822Sdim	    if (CONST_STRNEQ (o->name, GCC_EXCEPT_TABLE_PREFIX))
10904218822Sdim	      {
10905218822Sdim		char *fn_name;
10906218822Sdim		const char *sec_name;
10907218822Sdim		asection *fn_text;
10908218822Sdim		unsigned o_name_prefix_len , fn_name_prefix_len, tmp;
10909218822Sdim
10910218822Sdim		o_name_prefix_len = strlen (GCC_EXCEPT_TABLE_PREFIX);
10911218822Sdim		sec_name = o->name + o_name_prefix_len;
10912218822Sdim		fn_name_prefix_len = strlen (TEXT_PREFIX);
10913218822Sdim		tmp = strlen (TEXT_PREFIX2);
10914218822Sdim		if (tmp > fn_name_prefix_len)
10915218822Sdim		  fn_name_prefix_len = tmp;
10916218822Sdim		fn_name
10917218822Sdim		  = bfd_malloc (fn_name_prefix_len + strlen (sec_name) + 1);
10918218822Sdim		if (fn_name == NULL)
10919218822Sdim		  return FALSE;
10920218822Sdim
10921218822Sdim		/* Try the first prefix.  */
10922218822Sdim		sprintf (fn_name, "%s%s", TEXT_PREFIX, sec_name);
10923218822Sdim		fn_text = bfd_get_section_by_name (sub, fn_name);
10924218822Sdim
10925218822Sdim		/* Try the second prefix.  */
10926218822Sdim		if (fn_text == NULL)
10927218822Sdim		  {
10928218822Sdim		    sprintf (fn_name, "%s%s", TEXT_PREFIX2, sec_name);
10929218822Sdim		    fn_text = bfd_get_section_by_name (sub, fn_name);
10930218822Sdim		  }
10931218822Sdim
10932218822Sdim		free (fn_name);
10933218822Sdim		if (fn_text == NULL || !fn_text->gc_mark)
10934218822Sdim		  continue;
10935218822Sdim	      }
10936218822Sdim
10937218822Sdim	    /* If not using specially named exception table section,
10938218822Sdim	       then keep whatever we are using.  */
10939218822Sdim	    if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
10940130561Sobrien	      return FALSE;
10941218822Sdim	  }
10942130561Sobrien    }
10943130561Sobrien
10944130561Sobrien  /* ... and mark SEC_EXCLUDE for those that go.  */
10945218822Sdim  return elf_gc_sweep (abfd, info);
10946130561Sobrien}
1094733965Sjdp
10948130561Sobrien/* Called from check_relocs to record the existence of a VTINHERIT reloc.  */
1094933965Sjdp
10950130561Sobrienbfd_boolean
10951130561Sobrienbfd_elf_gc_record_vtinherit (bfd *abfd,
10952130561Sobrien			     asection *sec,
10953130561Sobrien			     struct elf_link_hash_entry *h,
10954130561Sobrien			     bfd_vma offset)
1095533965Sjdp{
10956130561Sobrien  struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
10957130561Sobrien  struct elf_link_hash_entry **search, *child;
10958130561Sobrien  bfd_size_type extsymcount;
10959130561Sobrien  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
1096033965Sjdp
10961130561Sobrien  /* The sh_info field of the symtab header tells us where the
10962130561Sobrien     external symbols start.  We don't care about the local symbols at
10963130561Sobrien     this point.  */
10964130561Sobrien  extsymcount = elf_tdata (abfd)->symtab_hdr.sh_size / bed->s->sizeof_sym;
10965130561Sobrien  if (!elf_bad_symtab (abfd))
10966130561Sobrien    extsymcount -= elf_tdata (abfd)->symtab_hdr.sh_info;
10967130561Sobrien
10968130561Sobrien  sym_hashes = elf_sym_hashes (abfd);
10969130561Sobrien  sym_hashes_end = sym_hashes + extsymcount;
10970130561Sobrien
10971130561Sobrien  /* Hunt down the child symbol, which is in this section at the same
10972130561Sobrien     offset as the relocation.  */
10973130561Sobrien  for (search = sym_hashes; search != sym_hashes_end; ++search)
1097433965Sjdp    {
10975130561Sobrien      if ((child = *search) != NULL
10976130561Sobrien	  && (child->root.type == bfd_link_hash_defined
10977130561Sobrien	      || child->root.type == bfd_link_hash_defweak)
10978130561Sobrien	  && child->root.u.def.section == sec
10979130561Sobrien	  && child->root.u.def.value == offset)
10980130561Sobrien	goto win;
1098133965Sjdp    }
1098233965Sjdp
10983218822Sdim  (*_bfd_error_handler) ("%B: %A+%lu: No symbol found for INHERIT",
10984218822Sdim			 abfd, sec, (unsigned long) offset);
10985130561Sobrien  bfd_set_error (bfd_error_invalid_operation);
10986130561Sobrien  return FALSE;
10987130561Sobrien
10988130561Sobrien win:
10989218822Sdim  if (!child->vtable)
10990218822Sdim    {
10991218822Sdim      child->vtable = bfd_zalloc (abfd, sizeof (*child->vtable));
10992218822Sdim      if (!child->vtable)
10993218822Sdim	return FALSE;
10994218822Sdim    }
10995130561Sobrien  if (!h)
10996130561Sobrien    {
10997130561Sobrien      /* This *should* only be the absolute section.  It could potentially
10998130561Sobrien	 be that someone has defined a non-global vtable though, which
10999130561Sobrien	 would be bad.  It isn't worth paging in the local symbols to be
11000130561Sobrien	 sure though; that case should simply be handled by the assembler.  */
11001130561Sobrien
11002218822Sdim      child->vtable->parent = (struct elf_link_hash_entry *) -1;
11003130561Sobrien    }
11004130561Sobrien  else
11005218822Sdim    child->vtable->parent = h;
11006130561Sobrien
11007130561Sobrien  return TRUE;
1100833965Sjdp}
11009130561Sobrien
11010130561Sobrien/* Called from check_relocs to record the existence of a VTENTRY reloc.  */
11011130561Sobrien
11012130561Sobrienbfd_boolean
11013130561Sobrienbfd_elf_gc_record_vtentry (bfd *abfd ATTRIBUTE_UNUSED,
11014130561Sobrien			   asection *sec ATTRIBUTE_UNUSED,
11015130561Sobrien			   struct elf_link_hash_entry *h,
11016130561Sobrien			   bfd_vma addend)
11017130561Sobrien{
11018130561Sobrien  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
11019130561Sobrien  unsigned int log_file_align = bed->s->log_file_align;
11020130561Sobrien
11021218822Sdim  if (!h->vtable)
11022130561Sobrien    {
11023218822Sdim      h->vtable = bfd_zalloc (abfd, sizeof (*h->vtable));
11024218822Sdim      if (!h->vtable)
11025218822Sdim	return FALSE;
11026218822Sdim    }
11027218822Sdim
11028218822Sdim  if (addend >= h->vtable->size)
11029218822Sdim    {
11030130561Sobrien      size_t size, bytes, file_align;
11031218822Sdim      bfd_boolean *ptr = h->vtable->used;
11032130561Sobrien
11033130561Sobrien      /* While the symbol is undefined, we have to be prepared to handle
11034130561Sobrien	 a zero size.  */
11035130561Sobrien      file_align = 1 << log_file_align;
11036130561Sobrien      if (h->root.type == bfd_link_hash_undefined)
11037130561Sobrien	size = addend + file_align;
11038130561Sobrien      else
11039130561Sobrien	{
11040130561Sobrien	  size = h->size;
11041130561Sobrien	  if (addend >= size)
11042130561Sobrien	    {
11043130561Sobrien	      /* Oops!  We've got a reference past the defined end of
11044130561Sobrien		 the table.  This is probably a bug -- shall we warn?  */
11045130561Sobrien	      size = addend + file_align;
11046130561Sobrien	    }
11047130561Sobrien	}
11048130561Sobrien      size = (size + file_align - 1) & -file_align;
11049130561Sobrien
11050130561Sobrien      /* Allocate one extra entry for use as a "done" flag for the
11051130561Sobrien	 consolidation pass.  */
11052130561Sobrien      bytes = ((size >> log_file_align) + 1) * sizeof (bfd_boolean);
11053130561Sobrien
11054130561Sobrien      if (ptr)
11055130561Sobrien	{
11056130561Sobrien	  ptr = bfd_realloc (ptr - 1, bytes);
11057130561Sobrien
11058130561Sobrien	  if (ptr != NULL)
11059130561Sobrien	    {
11060130561Sobrien	      size_t oldbytes;
11061130561Sobrien
11062218822Sdim	      oldbytes = (((h->vtable->size >> log_file_align) + 1)
11063130561Sobrien			  * sizeof (bfd_boolean));
11064130561Sobrien	      memset (((char *) ptr) + oldbytes, 0, bytes - oldbytes);
11065130561Sobrien	    }
11066130561Sobrien	}
11067130561Sobrien      else
11068130561Sobrien	ptr = bfd_zmalloc (bytes);
11069130561Sobrien
11070130561Sobrien      if (ptr == NULL)
11071130561Sobrien	return FALSE;
11072130561Sobrien
11073130561Sobrien      /* And arrange for that done flag to be at index -1.  */
11074218822Sdim      h->vtable->used = ptr + 1;
11075218822Sdim      h->vtable->size = size;
11076130561Sobrien    }
11077130561Sobrien
11078218822Sdim  h->vtable->used[addend >> log_file_align] = TRUE;
11079130561Sobrien
11080130561Sobrien  return TRUE;
11081130561Sobrien}
11082130561Sobrien
11083130561Sobrienstruct alloc_got_off_arg {
11084130561Sobrien  bfd_vma gotoff;
11085130561Sobrien  unsigned int got_elt_size;
11086130561Sobrien};
11087130561Sobrien
11088130561Sobrien/* We need a special top-level link routine to convert got reference counts
11089130561Sobrien   to real got offsets.  */
11090130561Sobrien
11091130561Sobrienstatic bfd_boolean
11092130561Sobrienelf_gc_allocate_got_offsets (struct elf_link_hash_entry *h, void *arg)
11093130561Sobrien{
11094130561Sobrien  struct alloc_got_off_arg *gofarg = arg;
11095130561Sobrien
11096130561Sobrien  if (h->root.type == bfd_link_hash_warning)
11097130561Sobrien    h = (struct elf_link_hash_entry *) h->root.u.i.link;
11098130561Sobrien
11099130561Sobrien  if (h->got.refcount > 0)
11100130561Sobrien    {
11101130561Sobrien      h->got.offset = gofarg->gotoff;
11102130561Sobrien      gofarg->gotoff += gofarg->got_elt_size;
11103130561Sobrien    }
11104130561Sobrien  else
11105130561Sobrien    h->got.offset = (bfd_vma) -1;
11106130561Sobrien
11107130561Sobrien  return TRUE;
11108130561Sobrien}
11109130561Sobrien
11110130561Sobrien/* And an accompanying bit to work out final got entry offsets once
11111130561Sobrien   we're done.  Should be called from final_link.  */
11112130561Sobrien
11113130561Sobrienbfd_boolean
11114130561Sobrienbfd_elf_gc_common_finalize_got_offsets (bfd *abfd,
11115130561Sobrien					struct bfd_link_info *info)
11116130561Sobrien{
11117130561Sobrien  bfd *i;
11118130561Sobrien  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
11119130561Sobrien  bfd_vma gotoff;
11120130561Sobrien  unsigned int got_elt_size = bed->s->arch_size / 8;
11121130561Sobrien  struct alloc_got_off_arg gofarg;
11122130561Sobrien
11123130561Sobrien  if (! is_elf_hash_table (info->hash))
11124130561Sobrien    return FALSE;
11125130561Sobrien
11126130561Sobrien  /* The GOT offset is relative to the .got section, but the GOT header is
11127130561Sobrien     put into the .got.plt section, if the backend uses it.  */
11128130561Sobrien  if (bed->want_got_plt)
11129130561Sobrien    gotoff = 0;
11130130561Sobrien  else
11131130561Sobrien    gotoff = bed->got_header_size;
11132130561Sobrien
11133130561Sobrien  /* Do the local .got entries first.  */
11134130561Sobrien  for (i = info->input_bfds; i; i = i->link_next)
11135130561Sobrien    {
11136130561Sobrien      bfd_signed_vma *local_got;
11137130561Sobrien      bfd_size_type j, locsymcount;
11138130561Sobrien      Elf_Internal_Shdr *symtab_hdr;
11139130561Sobrien
11140130561Sobrien      if (bfd_get_flavour (i) != bfd_target_elf_flavour)
11141130561Sobrien	continue;
11142130561Sobrien
11143130561Sobrien      local_got = elf_local_got_refcounts (i);
11144130561Sobrien      if (!local_got)
11145130561Sobrien	continue;
11146130561Sobrien
11147130561Sobrien      symtab_hdr = &elf_tdata (i)->symtab_hdr;
11148130561Sobrien      if (elf_bad_symtab (i))
11149130561Sobrien	locsymcount = symtab_hdr->sh_size / bed->s->sizeof_sym;
11150130561Sobrien      else
11151130561Sobrien	locsymcount = symtab_hdr->sh_info;
11152130561Sobrien
11153130561Sobrien      for (j = 0; j < locsymcount; ++j)
11154130561Sobrien	{
11155130561Sobrien	  if (local_got[j] > 0)
11156130561Sobrien	    {
11157130561Sobrien	      local_got[j] = gotoff;
11158130561Sobrien	      gotoff += got_elt_size;
11159130561Sobrien	    }
11160130561Sobrien	  else
11161130561Sobrien	    local_got[j] = (bfd_vma) -1;
11162130561Sobrien	}
11163130561Sobrien    }
11164130561Sobrien
11165130561Sobrien  /* Then the global .got entries.  .plt refcounts are handled by
11166130561Sobrien     adjust_dynamic_symbol  */
11167130561Sobrien  gofarg.gotoff = gotoff;
11168130561Sobrien  gofarg.got_elt_size = got_elt_size;
11169130561Sobrien  elf_link_hash_traverse (elf_hash_table (info),
11170130561Sobrien			  elf_gc_allocate_got_offsets,
11171130561Sobrien			  &gofarg);
11172130561Sobrien  return TRUE;
11173130561Sobrien}
11174130561Sobrien
11175130561Sobrien/* Many folk need no more in the way of final link than this, once
11176130561Sobrien   got entry reference counting is enabled.  */
11177130561Sobrien
11178130561Sobrienbfd_boolean
11179130561Sobrienbfd_elf_gc_common_final_link (bfd *abfd, struct bfd_link_info *info)
11180130561Sobrien{
11181130561Sobrien  if (!bfd_elf_gc_common_finalize_got_offsets (abfd, info))
11182130561Sobrien    return FALSE;
11183130561Sobrien
11184130561Sobrien  /* Invoke the regular ELF backend linker to do all the work.  */
11185130561Sobrien  return bfd_elf_final_link (abfd, info);
11186130561Sobrien}
11187130561Sobrien
11188130561Sobrienbfd_boolean
11189130561Sobrienbfd_elf_reloc_symbol_deleted_p (bfd_vma offset, void *cookie)
11190130561Sobrien{
11191130561Sobrien  struct elf_reloc_cookie *rcookie = cookie;
11192130561Sobrien
11193130561Sobrien  if (rcookie->bad_symtab)
11194130561Sobrien    rcookie->rel = rcookie->rels;
11195130561Sobrien
11196130561Sobrien  for (; rcookie->rel < rcookie->relend; rcookie->rel++)
11197130561Sobrien    {
11198130561Sobrien      unsigned long r_symndx;
11199130561Sobrien
11200130561Sobrien      if (! rcookie->bad_symtab)
11201130561Sobrien	if (rcookie->rel->r_offset > offset)
11202130561Sobrien	  return FALSE;
11203130561Sobrien      if (rcookie->rel->r_offset != offset)
11204130561Sobrien	continue;
11205130561Sobrien
11206130561Sobrien      r_symndx = rcookie->rel->r_info >> rcookie->r_sym_shift;
11207130561Sobrien      if (r_symndx == SHN_UNDEF)
11208130561Sobrien	return TRUE;
11209130561Sobrien
11210130561Sobrien      if (r_symndx >= rcookie->locsymcount
11211130561Sobrien	  || ELF_ST_BIND (rcookie->locsyms[r_symndx].st_info) != STB_LOCAL)
11212130561Sobrien	{
11213130561Sobrien	  struct elf_link_hash_entry *h;
11214130561Sobrien
11215130561Sobrien	  h = rcookie->sym_hashes[r_symndx - rcookie->extsymoff];
11216130561Sobrien
11217130561Sobrien	  while (h->root.type == bfd_link_hash_indirect
11218130561Sobrien		 || h->root.type == bfd_link_hash_warning)
11219130561Sobrien	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
11220130561Sobrien
11221130561Sobrien	  if ((h->root.type == bfd_link_hash_defined
11222130561Sobrien	       || h->root.type == bfd_link_hash_defweak)
11223130561Sobrien	      && elf_discarded_section (h->root.u.def.section))
11224130561Sobrien	    return TRUE;
11225130561Sobrien	  else
11226130561Sobrien	    return FALSE;
11227130561Sobrien	}
11228130561Sobrien      else
11229130561Sobrien	{
11230130561Sobrien	  /* It's not a relocation against a global symbol,
11231130561Sobrien	     but it could be a relocation against a local
11232130561Sobrien	     symbol for a discarded section.  */
11233130561Sobrien	  asection *isec;
11234130561Sobrien	  Elf_Internal_Sym *isym;
11235130561Sobrien
11236130561Sobrien	  /* Need to: get the symbol; get the section.  */
11237130561Sobrien	  isym = &rcookie->locsyms[r_symndx];
11238130561Sobrien	  if (isym->st_shndx < SHN_LORESERVE || isym->st_shndx > SHN_HIRESERVE)
11239130561Sobrien	    {
11240130561Sobrien	      isec = bfd_section_from_elf_index (rcookie->abfd, isym->st_shndx);
11241130561Sobrien	      if (isec != NULL && elf_discarded_section (isec))
11242130561Sobrien		return TRUE;
11243130561Sobrien	    }
11244130561Sobrien	}
11245130561Sobrien      return FALSE;
11246130561Sobrien    }
11247130561Sobrien  return FALSE;
11248130561Sobrien}
11249130561Sobrien
11250130561Sobrien/* Discard unneeded references to discarded sections.
11251130561Sobrien   Returns TRUE if any section's size was changed.  */
11252130561Sobrien/* This function assumes that the relocations are in sorted order,
11253130561Sobrien   which is true for all known assemblers.  */
11254130561Sobrien
11255130561Sobrienbfd_boolean
11256130561Sobrienbfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info)
11257130561Sobrien{
11258130561Sobrien  struct elf_reloc_cookie cookie;
11259130561Sobrien  asection *stab, *eh;
11260130561Sobrien  Elf_Internal_Shdr *symtab_hdr;
11261130561Sobrien  const struct elf_backend_data *bed;
11262130561Sobrien  bfd *abfd;
11263130561Sobrien  unsigned int count;
11264130561Sobrien  bfd_boolean ret = FALSE;
11265130561Sobrien
11266130561Sobrien  if (info->traditional_format
11267130561Sobrien      || !is_elf_hash_table (info->hash))
11268130561Sobrien    return FALSE;
11269130561Sobrien
11270130561Sobrien  for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
11271130561Sobrien    {
11272130561Sobrien      if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
11273130561Sobrien	continue;
11274130561Sobrien
11275130561Sobrien      bed = get_elf_backend_data (abfd);
11276130561Sobrien
11277130561Sobrien      if ((abfd->flags & DYNAMIC) != 0)
11278130561Sobrien	continue;
11279130561Sobrien
11280218822Sdim      eh = NULL;
11281218822Sdim      if (!info->relocatable)
11282218822Sdim	{
11283218822Sdim	  eh = bfd_get_section_by_name (abfd, ".eh_frame");
11284218822Sdim	  if (eh != NULL
11285218822Sdim	      && (eh->size == 0
11286218822Sdim		  || bfd_is_abs_section (eh->output_section)))
11287218822Sdim	    eh = NULL;
11288218822Sdim	}
11289130561Sobrien
11290130561Sobrien      stab = bfd_get_section_by_name (abfd, ".stab");
11291130561Sobrien      if (stab != NULL
11292218822Sdim	  && (stab->size == 0
11293130561Sobrien	      || bfd_is_abs_section (stab->output_section)
11294130561Sobrien	      || stab->sec_info_type != ELF_INFO_TYPE_STABS))
11295130561Sobrien	stab = NULL;
11296130561Sobrien
11297130561Sobrien      if (stab == NULL
11298130561Sobrien	  && eh == NULL
11299130561Sobrien	  && bed->elf_backend_discard_info == NULL)
11300130561Sobrien	continue;
11301130561Sobrien
11302130561Sobrien      symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
11303130561Sobrien      cookie.abfd = abfd;
11304130561Sobrien      cookie.sym_hashes = elf_sym_hashes (abfd);
11305130561Sobrien      cookie.bad_symtab = elf_bad_symtab (abfd);
11306130561Sobrien      if (cookie.bad_symtab)
11307130561Sobrien	{
11308130561Sobrien	  cookie.locsymcount = symtab_hdr->sh_size / bed->s->sizeof_sym;
11309130561Sobrien	  cookie.extsymoff = 0;
11310130561Sobrien	}
11311130561Sobrien      else
11312130561Sobrien	{
11313130561Sobrien	  cookie.locsymcount = symtab_hdr->sh_info;
11314130561Sobrien	  cookie.extsymoff = symtab_hdr->sh_info;
11315130561Sobrien	}
11316130561Sobrien
11317130561Sobrien      if (bed->s->arch_size == 32)
11318130561Sobrien	cookie.r_sym_shift = 8;
11319130561Sobrien      else
11320130561Sobrien	cookie.r_sym_shift = 32;
11321130561Sobrien
11322130561Sobrien      cookie.locsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
11323130561Sobrien      if (cookie.locsyms == NULL && cookie.locsymcount != 0)
11324130561Sobrien	{
11325130561Sobrien	  cookie.locsyms = bfd_elf_get_elf_syms (abfd, symtab_hdr,
11326130561Sobrien						 cookie.locsymcount, 0,
11327130561Sobrien						 NULL, NULL, NULL);
11328130561Sobrien	  if (cookie.locsyms == NULL)
11329218822Sdim	    {
11330218822Sdim	      info->callbacks->einfo (_("%P%X: can not read symbols: %E\n"));
11331218822Sdim	      return FALSE;
11332218822Sdim	    }
11333130561Sobrien	}
11334130561Sobrien
11335130561Sobrien      if (stab != NULL)
11336130561Sobrien	{
11337130561Sobrien	  cookie.rels = NULL;
11338130561Sobrien	  count = stab->reloc_count;
11339130561Sobrien	  if (count != 0)
11340130561Sobrien	    cookie.rels = _bfd_elf_link_read_relocs (abfd, stab, NULL, NULL,
11341130561Sobrien						     info->keep_memory);
11342130561Sobrien	  if (cookie.rels != NULL)
11343130561Sobrien	    {
11344130561Sobrien	      cookie.rel = cookie.rels;
11345130561Sobrien	      cookie.relend = cookie.rels;
11346130561Sobrien	      cookie.relend += count * bed->s->int_rels_per_ext_rel;
11347130561Sobrien	      if (_bfd_discard_section_stabs (abfd, stab,
11348130561Sobrien					      elf_section_data (stab)->sec_info,
11349130561Sobrien					      bfd_elf_reloc_symbol_deleted_p,
11350130561Sobrien					      &cookie))
11351130561Sobrien		ret = TRUE;
11352130561Sobrien	      if (elf_section_data (stab)->relocs != cookie.rels)
11353130561Sobrien		free (cookie.rels);
11354130561Sobrien	    }
11355130561Sobrien	}
11356130561Sobrien
11357130561Sobrien      if (eh != NULL)
11358130561Sobrien	{
11359130561Sobrien	  cookie.rels = NULL;
11360130561Sobrien	  count = eh->reloc_count;
11361130561Sobrien	  if (count != 0)
11362130561Sobrien	    cookie.rels = _bfd_elf_link_read_relocs (abfd, eh, NULL, NULL,
11363130561Sobrien						     info->keep_memory);
11364130561Sobrien	  cookie.rel = cookie.rels;
11365130561Sobrien	  cookie.relend = cookie.rels;
11366130561Sobrien	  if (cookie.rels != NULL)
11367130561Sobrien	    cookie.relend += count * bed->s->int_rels_per_ext_rel;
11368130561Sobrien
11369130561Sobrien	  if (_bfd_elf_discard_section_eh_frame (abfd, info, eh,
11370130561Sobrien						 bfd_elf_reloc_symbol_deleted_p,
11371130561Sobrien						 &cookie))
11372130561Sobrien	    ret = TRUE;
11373130561Sobrien
11374130561Sobrien	  if (cookie.rels != NULL
11375130561Sobrien	      && elf_section_data (eh)->relocs != cookie.rels)
11376130561Sobrien	    free (cookie.rels);
11377130561Sobrien	}
11378130561Sobrien
11379130561Sobrien      if (bed->elf_backend_discard_info != NULL
11380130561Sobrien	  && (*bed->elf_backend_discard_info) (abfd, &cookie, info))
11381130561Sobrien	ret = TRUE;
11382130561Sobrien
11383130561Sobrien      if (cookie.locsyms != NULL
11384130561Sobrien	  && symtab_hdr->contents != (unsigned char *) cookie.locsyms)
11385130561Sobrien	{
11386130561Sobrien	  if (! info->keep_memory)
11387130561Sobrien	    free (cookie.locsyms);
11388130561Sobrien	  else
11389130561Sobrien	    symtab_hdr->contents = (unsigned char *) cookie.locsyms;
11390130561Sobrien	}
11391130561Sobrien    }
11392130561Sobrien
11393130561Sobrien  if (info->eh_frame_hdr
11394130561Sobrien      && !info->relocatable
11395130561Sobrien      && _bfd_elf_discard_section_eh_frame_hdr (output_bfd, info))
11396130561Sobrien    ret = TRUE;
11397130561Sobrien
11398130561Sobrien  return ret;
11399130561Sobrien}
11400218822Sdim
11401218822Sdimvoid
11402218822Sdim_bfd_elf_section_already_linked (bfd *abfd, struct bfd_section *sec,
11403218822Sdim				 struct bfd_link_info *info)
11404218822Sdim{
11405218822Sdim  flagword flags;
11406218822Sdim  const char *name, *p;
11407218822Sdim  struct bfd_section_already_linked *l;
11408218822Sdim  struct bfd_section_already_linked_hash_entry *already_linked_list;
11409218822Sdim
11410218822Sdim  if (sec->output_section == bfd_abs_section_ptr)
11411218822Sdim    return;
11412218822Sdim
11413218822Sdim  flags = sec->flags;
11414218822Sdim
11415218822Sdim  /* Return if it isn't a linkonce section.  A comdat group section
11416218822Sdim     also has SEC_LINK_ONCE set.  */
11417218822Sdim  if ((flags & SEC_LINK_ONCE) == 0)
11418218822Sdim    return;
11419218822Sdim
11420218822Sdim  /* Don't put group member sections on our list of already linked
11421218822Sdim     sections.  They are handled as a group via their group section.  */
11422218822Sdim  if (elf_sec_group (sec) != NULL)
11423218822Sdim    return;
11424218822Sdim
11425218822Sdim  /* FIXME: When doing a relocatable link, we may have trouble
11426218822Sdim     copying relocations in other sections that refer to local symbols
11427218822Sdim     in the section being discarded.  Those relocations will have to
11428218822Sdim     be converted somehow; as of this writing I'm not sure that any of
11429218822Sdim     the backends handle that correctly.
11430218822Sdim
11431218822Sdim     It is tempting to instead not discard link once sections when
11432218822Sdim     doing a relocatable link (technically, they should be discarded
11433218822Sdim     whenever we are building constructors).  However, that fails,
11434218822Sdim     because the linker winds up combining all the link once sections
11435218822Sdim     into a single large link once section, which defeats the purpose
11436218822Sdim     of having link once sections in the first place.
11437218822Sdim
11438218822Sdim     Also, not merging link once sections in a relocatable link
11439218822Sdim     causes trouble for MIPS ELF, which relies on link once semantics
11440218822Sdim     to handle the .reginfo section correctly.  */
11441218822Sdim
11442218822Sdim  name = bfd_get_section_name (abfd, sec);
11443218822Sdim
11444218822Sdim  if (CONST_STRNEQ (name, ".gnu.linkonce.")
11445218822Sdim      && (p = strchr (name + sizeof (".gnu.linkonce.") - 1, '.')) != NULL)
11446218822Sdim    p++;
11447218822Sdim  else
11448218822Sdim    p = name;
11449218822Sdim
11450218822Sdim  already_linked_list = bfd_section_already_linked_table_lookup (p);
11451218822Sdim
11452218822Sdim  for (l = already_linked_list->entry; l != NULL; l = l->next)
11453218822Sdim    {
11454218822Sdim      /* We may have 2 different types of sections on the list: group
11455218822Sdim	 sections and linkonce sections.  Match like sections.  */
11456218822Sdim      if ((flags & SEC_GROUP) == (l->sec->flags & SEC_GROUP)
11457218822Sdim	  && strcmp (name, l->sec->name) == 0
11458218822Sdim	  && bfd_coff_get_comdat_section (l->sec->owner, l->sec) == NULL)
11459218822Sdim	{
11460218822Sdim	  /* The section has already been linked.  See if we should
11461218822Sdim	     issue a warning.  */
11462218822Sdim	  switch (flags & SEC_LINK_DUPLICATES)
11463218822Sdim	    {
11464218822Sdim	    default:
11465218822Sdim	      abort ();
11466218822Sdim
11467218822Sdim	    case SEC_LINK_DUPLICATES_DISCARD:
11468218822Sdim	      break;
11469218822Sdim
11470218822Sdim	    case SEC_LINK_DUPLICATES_ONE_ONLY:
11471218822Sdim	      (*_bfd_error_handler)
11472218822Sdim		(_("%B: ignoring duplicate section `%A'"),
11473218822Sdim		 abfd, sec);
11474218822Sdim	      break;
11475218822Sdim
11476218822Sdim	    case SEC_LINK_DUPLICATES_SAME_SIZE:
11477218822Sdim	      if (sec->size != l->sec->size)
11478218822Sdim		(*_bfd_error_handler)
11479218822Sdim		  (_("%B: duplicate section `%A' has different size"),
11480218822Sdim		   abfd, sec);
11481218822Sdim	      break;
11482218822Sdim
11483218822Sdim	    case SEC_LINK_DUPLICATES_SAME_CONTENTS:
11484218822Sdim	      if (sec->size != l->sec->size)
11485218822Sdim		(*_bfd_error_handler)
11486218822Sdim		  (_("%B: duplicate section `%A' has different size"),
11487218822Sdim		   abfd, sec);
11488218822Sdim	      else if (sec->size != 0)
11489218822Sdim		{
11490310368Spfg		  bfd_byte *sec_contents, *l_sec_contents = NULL;
11491218822Sdim
11492218822Sdim		  if (!bfd_malloc_and_get_section (abfd, sec, &sec_contents))
11493218822Sdim		    (*_bfd_error_handler)
11494218822Sdim		      (_("%B: warning: could not read contents of section `%A'"),
11495218822Sdim		       abfd, sec);
11496218822Sdim		  else if (!bfd_malloc_and_get_section (l->sec->owner, l->sec,
11497218822Sdim							&l_sec_contents))
11498218822Sdim		    (*_bfd_error_handler)
11499218822Sdim		      (_("%B: warning: could not read contents of section `%A'"),
11500218822Sdim		       l->sec->owner, l->sec);
11501218822Sdim		  else if (memcmp (sec_contents, l_sec_contents, sec->size) != 0)
11502218822Sdim		    (*_bfd_error_handler)
11503218822Sdim		      (_("%B: warning: duplicate section `%A' has different contents"),
11504218822Sdim		       abfd, sec);
11505218822Sdim
11506218822Sdim		  if (sec_contents)
11507218822Sdim		    free (sec_contents);
11508218822Sdim		  if (l_sec_contents)
11509218822Sdim		    free (l_sec_contents);
11510218822Sdim		}
11511218822Sdim	      break;
11512218822Sdim	    }
11513218822Sdim
11514218822Sdim	  /* Set the output_section field so that lang_add_section
11515218822Sdim	     does not create a lang_input_section structure for this
11516218822Sdim	     section.  Since there might be a symbol in the section
11517218822Sdim	     being discarded, we must retain a pointer to the section
11518218822Sdim	     which we are really going to use.  */
11519218822Sdim	  sec->output_section = bfd_abs_section_ptr;
11520218822Sdim	  sec->kept_section = l->sec;
11521218822Sdim
11522218822Sdim	  if (flags & SEC_GROUP)
11523218822Sdim	    {
11524218822Sdim	      asection *first = elf_next_in_group (sec);
11525218822Sdim	      asection *s = first;
11526218822Sdim
11527218822Sdim	      while (s != NULL)
11528218822Sdim		{
11529218822Sdim		  s->output_section = bfd_abs_section_ptr;
11530218822Sdim		  /* Record which group discards it.  */
11531218822Sdim		  s->kept_section = l->sec;
11532218822Sdim		  s = elf_next_in_group (s);
11533218822Sdim		  /* These lists are circular.  */
11534218822Sdim		  if (s == first)
11535218822Sdim		    break;
11536218822Sdim		}
11537218822Sdim	    }
11538218822Sdim
11539218822Sdim	  return;
11540218822Sdim	}
11541218822Sdim    }
11542218822Sdim
11543218822Sdim  /* A single member comdat group section may be discarded by a
11544218822Sdim     linkonce section and vice versa.  */
11545218822Sdim
11546218822Sdim  if ((flags & SEC_GROUP) != 0)
11547218822Sdim    {
11548218822Sdim      asection *first = elf_next_in_group (sec);
11549218822Sdim
11550218822Sdim      if (first != NULL && elf_next_in_group (first) == first)
11551218822Sdim	/* Check this single member group against linkonce sections.  */
11552218822Sdim	for (l = already_linked_list->entry; l != NULL; l = l->next)
11553218822Sdim	  if ((l->sec->flags & SEC_GROUP) == 0
11554218822Sdim	      && bfd_coff_get_comdat_section (l->sec->owner, l->sec) == NULL
11555218822Sdim	      && bfd_elf_match_symbols_in_sections (l->sec, first, info))
11556218822Sdim	    {
11557218822Sdim	      first->output_section = bfd_abs_section_ptr;
11558218822Sdim	      first->kept_section = l->sec;
11559218822Sdim	      sec->output_section = bfd_abs_section_ptr;
11560218822Sdim	      break;
11561218822Sdim	    }
11562218822Sdim    }
11563218822Sdim  else
11564218822Sdim    /* Check this linkonce section against single member groups.  */
11565218822Sdim    for (l = already_linked_list->entry; l != NULL; l = l->next)
11566218822Sdim      if (l->sec->flags & SEC_GROUP)
11567218822Sdim	{
11568218822Sdim	  asection *first = elf_next_in_group (l->sec);
11569218822Sdim
11570218822Sdim	  if (first != NULL
11571218822Sdim	      && elf_next_in_group (first) == first
11572218822Sdim	      && bfd_elf_match_symbols_in_sections (first, sec, info))
11573218822Sdim	    {
11574218822Sdim	      sec->output_section = bfd_abs_section_ptr;
11575218822Sdim	      sec->kept_section = first;
11576218822Sdim	      break;
11577218822Sdim	    }
11578218822Sdim	}
11579218822Sdim
11580218822Sdim  /* This is the first section with this name.  Record it.  */
11581218822Sdim  bfd_section_already_linked_table_insert (already_linked_list, sec);
11582218822Sdim}
11583218822Sdim
11584218822Sdimbfd_boolean
11585218822Sdim_bfd_elf_common_definition (Elf_Internal_Sym *sym)
11586218822Sdim{
11587218822Sdim  return sym->st_shndx == SHN_COMMON;
11588218822Sdim}
11589218822Sdim
11590218822Sdimunsigned int
11591218822Sdim_bfd_elf_common_section_index (asection *sec ATTRIBUTE_UNUSED)
11592218822Sdim{
11593218822Sdim  return SHN_COMMON;
11594218822Sdim}
11595218822Sdim
11596218822Sdimasection *
11597218822Sdim_bfd_elf_common_section (asection *sec ATTRIBUTE_UNUSED)
11598218822Sdim{
11599218822Sdim  return bfd_com_section_ptr;
11600218822Sdim}
11601