xref: /dflybsd-src/contrib/binutils-2.27/ld/emultempl/elf32.em (revision e656dc90e3d65d744d534af2f5ea88cf8101ebcf)
1*a9fa9459Szrj# This shell script emits a C file. -*- C -*-
2*a9fa9459Szrj# It does some substitutions.
3*a9fa9459Szrj# This file is now misnamed, because it supports both 32 bit and 64 bit
4*a9fa9459Szrj# ELF emulations.
5*a9fa9459Szrjtest -z "${ELFSIZE}" && ELFSIZE=32
6*a9fa9459Szrjif [ -z "$MACHINE" ]; then
7*a9fa9459Szrj  OUTPUT_ARCH=${ARCH}
8*a9fa9459Szrjelse
9*a9fa9459Szrj  OUTPUT_ARCH=${ARCH}:${MACHINE}
10*a9fa9459Szrjfi
11*a9fa9459Szrjfragment <<EOF
12*a9fa9459Szrj/* This file is is generated by a shell script.  DO NOT EDIT! */
13*a9fa9459Szrj
14*a9fa9459Szrj/* ${ELFSIZE} bit ELF emulation code for ${EMULATION_NAME}
15*a9fa9459Szrj   Copyright (C) 1991-2016 Free Software Foundation, Inc.
16*a9fa9459Szrj   Written by Steve Chamberlain <sac@cygnus.com>
17*a9fa9459Szrj   ELF support by Ian Lance Taylor <ian@cygnus.com>
18*a9fa9459Szrj
19*a9fa9459Szrj   This file is part of the GNU Binutils.
20*a9fa9459Szrj
21*a9fa9459Szrj   This program is free software; you can redistribute it and/or modify
22*a9fa9459Szrj   it under the terms of the GNU General Public License as published by
23*a9fa9459Szrj   the Free Software Foundation; either version 3 of the License, or
24*a9fa9459Szrj   (at your option) any later version.
25*a9fa9459Szrj
26*a9fa9459Szrj   This program is distributed in the hope that it will be useful,
27*a9fa9459Szrj   but WITHOUT ANY WARRANTY; without even the implied warranty of
28*a9fa9459Szrj   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29*a9fa9459Szrj   GNU General Public License for more details.
30*a9fa9459Szrj
31*a9fa9459Szrj   You should have received a copy of the GNU General Public License
32*a9fa9459Szrj   along with this program; if not, write to the Free Software
33*a9fa9459Szrj   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
34*a9fa9459Szrj   MA 02110-1301, USA.  */
35*a9fa9459Szrj
36*a9fa9459Szrj#define TARGET_IS_${EMULATION_NAME}
37*a9fa9459Szrj
38*a9fa9459Szrj#include "sysdep.h"
39*a9fa9459Szrj#include "bfd.h"
40*a9fa9459Szrj#include "libiberty.h"
41*a9fa9459Szrj#include "safe-ctype.h"
42*a9fa9459Szrj#include "filenames.h"
43*a9fa9459Szrj#include "getopt.h"
44*a9fa9459Szrj#include <fcntl.h>
45*a9fa9459Szrj
46*a9fa9459Szrj#include "bfdlink.h"
47*a9fa9459Szrj
48*a9fa9459Szrj#include "ld.h"
49*a9fa9459Szrj#include "ldmain.h"
50*a9fa9459Szrj#include "ldmisc.h"
51*a9fa9459Szrj#include "ldexp.h"
52*a9fa9459Szrj#include "ldlang.h"
53*a9fa9459Szrj#include "ldfile.h"
54*a9fa9459Szrj#include "ldemul.h"
55*a9fa9459Szrj#include "ldbuildid.h"
56*a9fa9459Szrj#include <ldgram.h>
57*a9fa9459Szrj#include "elf/common.h"
58*a9fa9459Szrj#include "elf-bfd.h"
59*a9fa9459Szrj#include "filenames.h"
60*a9fa9459Szrj
61*a9fa9459Szrj/* Declare functions used by various EXTRA_EM_FILEs.  */
62*a9fa9459Szrjstatic void gld${EMULATION_NAME}_before_parse (void);
63*a9fa9459Szrjstatic void gld${EMULATION_NAME}_after_parse (void);
64*a9fa9459Szrjstatic void gld${EMULATION_NAME}_after_open (void);
65*a9fa9459Szrjstatic void gld${EMULATION_NAME}_before_allocation (void);
66*a9fa9459Szrjstatic void gld${EMULATION_NAME}_after_allocation (void);
67*a9fa9459Szrjstatic lang_output_section_statement_type *gld${EMULATION_NAME}_place_orphan
68*a9fa9459Szrj  (asection *, const char *, int);
69*a9fa9459SzrjEOF
70*a9fa9459Szrj
71*a9fa9459Szrjif [ "x${USE_LIBPATH}" = xyes ] ; then
72*a9fa9459Szrj  case ${target} in
73*a9fa9459Szrj    *-*-linux-* | *-*-k*bsd*-* | *-*-gnu*)
74*a9fa9459Szrj  fragment <<EOF
75*a9fa9459Szrj#ifdef HAVE_GLOB
76*a9fa9459Szrj#include <glob.h>
77*a9fa9459Szrj#endif
78*a9fa9459SzrjEOF
79*a9fa9459Szrj    ;;
80*a9fa9459Szrj  esac
81*a9fa9459Szrjfi
82*a9fa9459Szrj
83*a9fa9459Szrj# Import any needed special functions and/or overrides.
84*a9fa9459Szrj#
85*a9fa9459Szrjsource_em ${srcdir}/emultempl/elf-generic.em
86*a9fa9459Szrjif test -n "$EXTRA_EM_FILE" ; then
87*a9fa9459Szrj  source_em ${srcdir}/emultempl/${EXTRA_EM_FILE}.em
88*a9fa9459Szrjfi
89*a9fa9459Szrj
90*a9fa9459Szrj# Functions in this file can be overridden by setting the LDEMUL_* shell
91*a9fa9459Szrj# variables.  If the name of the overriding function is the same as is
92*a9fa9459Szrj# defined in this file, then don't output this file's version.
93*a9fa9459Szrj# If a different overriding name is given then output the standard function
94*a9fa9459Szrj# as presumably it is called from the overriding function.
95*a9fa9459Szrj#
96*a9fa9459Szrjif test x"$LDEMUL_BEFORE_PARSE" != xgld"$EMULATION_NAME"_before_parse; then
97*a9fa9459Szrjfragment <<EOF
98*a9fa9459Szrj
99*a9fa9459Szrjstatic void
100*a9fa9459Szrjgld${EMULATION_NAME}_before_parse (void)
101*a9fa9459Szrj{
102*a9fa9459Szrj  ldfile_set_output_arch ("${OUTPUT_ARCH}", bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`);
103*a9fa9459Szrj  input_flags.dynamic = ${DYNAMIC_LINK-TRUE};
104*a9fa9459Szrj  config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo TRUE ; else echo FALSE ; fi`;
105*a9fa9459Szrj  config.separate_code = `if test "x${SEPARATE_CODE}" = xyes ; then echo TRUE ; else echo FALSE ; fi`;
106*a9fa9459Szrj  `if test -n "$CALL_NOP_BYTE" ; then echo link_info.call_nop_byte = $CALL_NOP_BYTE; fi`;
107*a9fa9459Szrj  link_info.check_relocs_after_open_input = `if test "x${CHECK_RELOCS_AFTER_OPEN_INPUT}" = xyes ; then echo TRUE ; else echo FALSE ; fi`;
108*a9fa9459Szrj  link_info.relro = DEFAULT_LD_Z_RELRO;
109*a9fa9459Szrj}
110*a9fa9459Szrj
111*a9fa9459SzrjEOF
112*a9fa9459Szrjfi
113*a9fa9459Szrj
114*a9fa9459Szrjif test x"$LDEMUL_AFTER_PARSE" != xgld"$EMULATION_NAME"_after_parse; then
115*a9fa9459Szrjfragment <<EOF
116*a9fa9459Szrj
117*a9fa9459Szrjstatic void
118*a9fa9459Szrjgld${EMULATION_NAME}_after_parse (void)
119*a9fa9459Szrj{
120*a9fa9459Szrj  if (bfd_link_pie (&link_info))
121*a9fa9459Szrj    link_info.flags_1 |= (bfd_vma) DF_1_PIE;
122*a9fa9459Szrj
123*a9fa9459Szrj  after_parse_default ();
124*a9fa9459Szrj}
125*a9fa9459Szrj
126*a9fa9459SzrjEOF
127*a9fa9459Szrjfi
128*a9fa9459Szrj
129*a9fa9459Szrjif test x"$LDEMUL_RECOGNIZED_FILE" != xgld"${EMULATION_NAME}"_load_symbols; then
130*a9fa9459Szrjfragment <<EOF
131*a9fa9459Szrj/* Handle the generation of DT_NEEDED tags.  */
132*a9fa9459Szrj
133*a9fa9459Szrjstatic bfd_boolean
134*a9fa9459Szrjgld${EMULATION_NAME}_load_symbols (lang_input_statement_type *entry)
135*a9fa9459Szrj{
136*a9fa9459Szrj  int link_class = 0;
137*a9fa9459Szrj
138*a9fa9459Szrj  /* Tell the ELF linker that we don't want the output file to have a
139*a9fa9459Szrj     DT_NEEDED entry for this file, unless it is used to resolve
140*a9fa9459Szrj     references in a regular object.  */
141*a9fa9459Szrj  if (entry->flags.add_DT_NEEDED_for_regular)
142*a9fa9459Szrj    link_class = DYN_AS_NEEDED;
143*a9fa9459Szrj
144*a9fa9459Szrj  /* Tell the ELF linker that we don't want the output file to have a
145*a9fa9459Szrj     DT_NEEDED entry for any dynamic library in DT_NEEDED tags from
146*a9fa9459Szrj     this file at all.  */
147*a9fa9459Szrj  if (!entry->flags.add_DT_NEEDED_for_dynamic)
148*a9fa9459Szrj    link_class |= DYN_NO_ADD_NEEDED;
149*a9fa9459Szrj
150*a9fa9459Szrj  if (entry->flags.just_syms
151*a9fa9459Szrj      && (bfd_get_file_flags (entry->the_bfd) & DYNAMIC) != 0)
152*a9fa9459Szrj    einfo (_("%P%F: --just-symbols may not be used on DSO: %B\n"),
153*a9fa9459Szrj	   entry->the_bfd);
154*a9fa9459Szrj
155*a9fa9459Szrj  if (link_class == 0
156*a9fa9459Szrj      || (bfd_get_file_flags (entry->the_bfd) & DYNAMIC) == 0)
157*a9fa9459Szrj    return FALSE;
158*a9fa9459Szrj
159*a9fa9459Szrj  bfd_elf_set_dyn_lib_class (entry->the_bfd,
160*a9fa9459Szrj			     (enum dynamic_lib_link_class) link_class);
161*a9fa9459Szrj
162*a9fa9459Szrj  /* Continue on with normal load_symbols processing.  */
163*a9fa9459Szrj  return FALSE;
164*a9fa9459Szrj}
165*a9fa9459SzrjEOF
166*a9fa9459Szrjfi
167*a9fa9459Szrj
168*a9fa9459Szrjfragment <<EOF
169*a9fa9459Szrj
170*a9fa9459Szrj/* These variables are required to pass information back and forth
171*a9fa9459Szrj   between after_open and check_needed and stat_needed and vercheck.  */
172*a9fa9459Szrj
173*a9fa9459Szrjstatic struct bfd_link_needed_list *global_needed;
174*a9fa9459Szrjstatic struct stat global_stat;
175*a9fa9459Szrjstatic lang_input_statement_type *global_found;
176*a9fa9459Szrjstatic struct bfd_link_needed_list *global_vercheck_needed;
177*a9fa9459Szrjstatic bfd_boolean global_vercheck_failed;
178*a9fa9459Szrj
179*a9fa9459Szrj/* These variables are used to implement target options */
180*a9fa9459Szrj
181*a9fa9459Szrjstatic char *audit; /* colon (typically) separated list of libs */
182*a9fa9459Szrjstatic char *depaudit; /* colon (typically) separated list of libs */
183*a9fa9459Szrj
184*a9fa9459Szrj/* Style of .note.gnu.build-id section.  */
185*a9fa9459Szrjstatic const char *emit_note_gnu_build_id;
186*a9fa9459Szrj
187*a9fa9459Szrj/* On Linux, it's possible to have different versions of the same
188*a9fa9459Szrj   shared library linked against different versions of libc.  The
189*a9fa9459Szrj   dynamic linker somehow tags which libc version to use in
190*a9fa9459Szrj   /etc/ld.so.cache, and, based on the libc that it sees in the
191*a9fa9459Szrj   executable, chooses which version of the shared library to use.
192*a9fa9459Szrj
193*a9fa9459Szrj   We try to do a similar check here by checking whether this shared
194*a9fa9459Szrj   library needs any other shared libraries which may conflict with
195*a9fa9459Szrj   libraries we have already included in the link.  If it does, we
196*a9fa9459Szrj   skip it, and try to find another shared library farther on down the
197*a9fa9459Szrj   link path.
198*a9fa9459Szrj
199*a9fa9459Szrj   This is called via lang_for_each_input_file.
200*a9fa9459Szrj   GLOBAL_VERCHECK_NEEDED is the list of objects needed by the object
201*a9fa9459Szrj   which we are checking.  This sets GLOBAL_VERCHECK_FAILED if we find
202*a9fa9459Szrj   a conflicting version.  */
203*a9fa9459Szrj
204*a9fa9459Szrjstatic void
205*a9fa9459Szrjgld${EMULATION_NAME}_vercheck (lang_input_statement_type *s)
206*a9fa9459Szrj{
207*a9fa9459Szrj  const char *soname;
208*a9fa9459Szrj  struct bfd_link_needed_list *l;
209*a9fa9459Szrj
210*a9fa9459Szrj  if (global_vercheck_failed)
211*a9fa9459Szrj    return;
212*a9fa9459Szrj  if (s->the_bfd == NULL
213*a9fa9459Szrj      || (bfd_get_file_flags (s->the_bfd) & DYNAMIC) == 0)
214*a9fa9459Szrj    return;
215*a9fa9459Szrj
216*a9fa9459Szrj  soname = bfd_elf_get_dt_soname (s->the_bfd);
217*a9fa9459Szrj  if (soname == NULL)
218*a9fa9459Szrj    soname = lbasename (bfd_get_filename (s->the_bfd));
219*a9fa9459Szrj
220*a9fa9459Szrj  for (l = global_vercheck_needed; l != NULL; l = l->next)
221*a9fa9459Szrj    {
222*a9fa9459Szrj      const char *suffix;
223*a9fa9459Szrj
224*a9fa9459Szrj      if (filename_cmp (soname, l->name) == 0)
225*a9fa9459Szrj	{
226*a9fa9459Szrj	  /* Probably can't happen, but it's an easy check.  */
227*a9fa9459Szrj	  continue;
228*a9fa9459Szrj	}
229*a9fa9459Szrj
230*a9fa9459Szrj      if (strchr (l->name, '/') != NULL)
231*a9fa9459Szrj	continue;
232*a9fa9459Szrj
233*a9fa9459Szrj      suffix = strstr (l->name, ".so.");
234*a9fa9459Szrj      if (suffix == NULL)
235*a9fa9459Szrj	continue;
236*a9fa9459Szrj
237*a9fa9459Szrj      suffix += sizeof ".so." - 1;
238*a9fa9459Szrj
239*a9fa9459Szrj      if (filename_ncmp (soname, l->name, suffix - l->name) == 0)
240*a9fa9459Szrj	{
241*a9fa9459Szrj	  /* Here we know that S is a dynamic object FOO.SO.VER1, and
242*a9fa9459Szrj	     the object we are considering needs a dynamic object
243*a9fa9459Szrj	     FOO.SO.VER2, and VER1 and VER2 are different.  This
244*a9fa9459Szrj	     appears to be a version mismatch, so we tell the caller
245*a9fa9459Szrj	     to try a different version of this library.  */
246*a9fa9459Szrj	  global_vercheck_failed = TRUE;
247*a9fa9459Szrj	  return;
248*a9fa9459Szrj	}
249*a9fa9459Szrj    }
250*a9fa9459Szrj}
251*a9fa9459Szrj
252*a9fa9459Szrj
253*a9fa9459Szrj/* See if an input file matches a DT_NEEDED entry by running stat on
254*a9fa9459Szrj   the file.  */
255*a9fa9459Szrj
256*a9fa9459Szrjstatic void
257*a9fa9459Szrjgld${EMULATION_NAME}_stat_needed (lang_input_statement_type *s)
258*a9fa9459Szrj{
259*a9fa9459Szrj  struct stat st;
260*a9fa9459Szrj  const char *suffix;
261*a9fa9459Szrj  const char *soname;
262*a9fa9459Szrj
263*a9fa9459Szrj  if (global_found != NULL)
264*a9fa9459Szrj    return;
265*a9fa9459Szrj  if (s->the_bfd == NULL)
266*a9fa9459Szrj    return;
267*a9fa9459Szrj
268*a9fa9459Szrj  /* If this input file was an as-needed entry, and wasn't found to be
269*a9fa9459Szrj     needed at the stage it was linked, then don't say we have loaded it.  */
270*a9fa9459Szrj  if ((bfd_elf_get_dyn_lib_class (s->the_bfd) & DYN_AS_NEEDED) != 0)
271*a9fa9459Szrj    return;
272*a9fa9459Szrj
273*a9fa9459Szrj  if (bfd_stat (s->the_bfd, &st) != 0)
274*a9fa9459Szrj    {
275*a9fa9459Szrj      einfo ("%P:%B: bfd_stat failed: %E\n", s->the_bfd);
276*a9fa9459Szrj      return;
277*a9fa9459Szrj    }
278*a9fa9459Szrj
279*a9fa9459Szrj  /* Some operating systems, e.g. Windows, do not provide a meaningful
280*a9fa9459Szrj     st_ino; they always set it to zero.  (Windows does provide a
281*a9fa9459Szrj     meaningful st_dev.)  Do not indicate a duplicate library in that
282*a9fa9459Szrj     case.  While there is no guarantee that a system that provides
283*a9fa9459Szrj     meaningful inode numbers will never set st_ino to zero, this is
284*a9fa9459Szrj     merely an optimization, so we do not need to worry about false
285*a9fa9459Szrj     negatives.  */
286*a9fa9459Szrj  if (st.st_dev == global_stat.st_dev
287*a9fa9459Szrj      && st.st_ino == global_stat.st_ino
288*a9fa9459Szrj      && st.st_ino != 0)
289*a9fa9459Szrj    {
290*a9fa9459Szrj      global_found = s;
291*a9fa9459Szrj      return;
292*a9fa9459Szrj    }
293*a9fa9459Szrj
294*a9fa9459Szrj  /* We issue a warning if it looks like we are including two
295*a9fa9459Szrj     different versions of the same shared library.  For example,
296*a9fa9459Szrj     there may be a problem if -lc picks up libc.so.6 but some other
297*a9fa9459Szrj     shared library has a DT_NEEDED entry of libc.so.5.  This is a
298*a9fa9459Szrj     heuristic test, and it will only work if the name looks like
299*a9fa9459Szrj     NAME.so.VERSION.  FIXME: Depending on file names is error-prone.
300*a9fa9459Szrj     If we really want to issue warnings about mixing version numbers
301*a9fa9459Szrj     of shared libraries, we need to find a better way.  */
302*a9fa9459Szrj
303*a9fa9459Szrj  if (strchr (global_needed->name, '/') != NULL)
304*a9fa9459Szrj    return;
305*a9fa9459Szrj  suffix = strstr (global_needed->name, ".so.");
306*a9fa9459Szrj  if (suffix == NULL)
307*a9fa9459Szrj    return;
308*a9fa9459Szrj  suffix += sizeof ".so." - 1;
309*a9fa9459Szrj
310*a9fa9459Szrj  soname = bfd_elf_get_dt_soname (s->the_bfd);
311*a9fa9459Szrj  if (soname == NULL)
312*a9fa9459Szrj    soname = lbasename (s->filename);
313*a9fa9459Szrj
314*a9fa9459Szrj  if (filename_ncmp (soname, global_needed->name, suffix - global_needed->name) == 0)
315*a9fa9459Szrj    einfo ("%P: warning: %s, needed by %B, may conflict with %s\n",
316*a9fa9459Szrj	   global_needed->name, global_needed->by, soname);
317*a9fa9459Szrj}
318*a9fa9459Szrj
319*a9fa9459Szrjstruct dt_needed
320*a9fa9459Szrj{
321*a9fa9459Szrj  bfd *by;
322*a9fa9459Szrj  const char *name;
323*a9fa9459Szrj};
324*a9fa9459Szrj
325*a9fa9459Szrj/* This function is called for each possible name for a dynamic object
326*a9fa9459Szrj   named by a DT_NEEDED entry.  The FORCE parameter indicates whether
327*a9fa9459Szrj   to skip the check for a conflicting version.  */
328*a9fa9459Szrj
329*a9fa9459Szrjstatic bfd_boolean
330*a9fa9459Szrjgld${EMULATION_NAME}_try_needed (struct dt_needed *needed,
331*a9fa9459Szrj				 int force)
332*a9fa9459Szrj{
333*a9fa9459Szrj  bfd *abfd;
334*a9fa9459Szrj  const char *name = needed->name;
335*a9fa9459Szrj  const char *soname;
336*a9fa9459Szrj  int link_class;
337*a9fa9459Szrj
338*a9fa9459Szrj  abfd = bfd_openr (name, bfd_get_target (link_info.output_bfd));
339*a9fa9459Szrj  if (abfd == NULL)
340*a9fa9459Szrj    return FALSE;
341*a9fa9459Szrj
342*a9fa9459Szrj  /* Linker needs to decompress sections.  */
343*a9fa9459Szrj  abfd->flags |= BFD_DECOMPRESS;
344*a9fa9459Szrj
345*a9fa9459Szrj  if (! bfd_check_format (abfd, bfd_object))
346*a9fa9459Szrj    {
347*a9fa9459Szrj      bfd_close (abfd);
348*a9fa9459Szrj      return FALSE;
349*a9fa9459Szrj    }
350*a9fa9459Szrj  if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0)
351*a9fa9459Szrj    {
352*a9fa9459Szrj      bfd_close (abfd);
353*a9fa9459Szrj      return FALSE;
354*a9fa9459Szrj    }
355*a9fa9459Szrj
356*a9fa9459Szrj  /* For DT_NEEDED, they have to match.  */
357*a9fa9459Szrj  if (abfd->xvec != link_info.output_bfd->xvec)
358*a9fa9459Szrj    {
359*a9fa9459Szrj      bfd_close (abfd);
360*a9fa9459Szrj      return FALSE;
361*a9fa9459Szrj    }
362*a9fa9459Szrj
363*a9fa9459Szrj  /* Check whether this object would include any conflicting library
364*a9fa9459Szrj     versions.  If FORCE is set, then we skip this check; we use this
365*a9fa9459Szrj     the second time around, if we couldn't find any compatible
366*a9fa9459Szrj     instance of the shared library.  */
367*a9fa9459Szrj
368*a9fa9459Szrj  if (! force)
369*a9fa9459Szrj    {
370*a9fa9459Szrj      struct bfd_link_needed_list *needs;
371*a9fa9459Szrj
372*a9fa9459Szrj      if (! bfd_elf_get_bfd_needed_list (abfd, &needs))
373*a9fa9459Szrj	einfo ("%F%P:%B: bfd_elf_get_bfd_needed_list failed: %E\n", abfd);
374*a9fa9459Szrj
375*a9fa9459Szrj      if (needs != NULL)
376*a9fa9459Szrj	{
377*a9fa9459Szrj	  global_vercheck_needed = needs;
378*a9fa9459Szrj	  global_vercheck_failed = FALSE;
379*a9fa9459Szrj	  lang_for_each_input_file (gld${EMULATION_NAME}_vercheck);
380*a9fa9459Szrj	  if (global_vercheck_failed)
381*a9fa9459Szrj	    {
382*a9fa9459Szrj	      bfd_close (abfd);
383*a9fa9459Szrj	      /* Return FALSE to force the caller to move on to try
384*a9fa9459Szrj		 another file on the search path.  */
385*a9fa9459Szrj	      return FALSE;
386*a9fa9459Szrj	    }
387*a9fa9459Szrj
388*a9fa9459Szrj	  /* But wait!  It gets much worse.  On Linux, if a shared
389*a9fa9459Szrj	     library does not use libc at all, we are supposed to skip
390*a9fa9459Szrj	     it the first time around in case we encounter a shared
391*a9fa9459Szrj	     library later on with the same name which does use the
392*a9fa9459Szrj	     version of libc that we want.  This is much too horrible
393*a9fa9459Szrj	     to use on any system other than Linux.  */
394*a9fa9459Szrj
395*a9fa9459SzrjEOF
396*a9fa9459Szrjcase ${target} in
397*a9fa9459Szrj  *-*-linux-* | *-*-k*bsd*-* | *-*-gnu*)
398*a9fa9459Szrj    fragment <<EOF
399*a9fa9459Szrj	  {
400*a9fa9459Szrj	    struct bfd_link_needed_list *l;
401*a9fa9459Szrj
402*a9fa9459Szrj	    for (l = needs; l != NULL; l = l->next)
403*a9fa9459Szrj	      if (CONST_STRNEQ (l->name, "libc.so"))
404*a9fa9459Szrj		break;
405*a9fa9459Szrj	    if (l == NULL)
406*a9fa9459Szrj	      {
407*a9fa9459Szrj		bfd_close (abfd);
408*a9fa9459Szrj		return FALSE;
409*a9fa9459Szrj	      }
410*a9fa9459Szrj	  }
411*a9fa9459Szrj
412*a9fa9459SzrjEOF
413*a9fa9459Szrj    ;;
414*a9fa9459Szrjesac
415*a9fa9459Szrjfragment <<EOF
416*a9fa9459Szrj	}
417*a9fa9459Szrj    }
418*a9fa9459Szrj
419*a9fa9459Szrj  /* We've found a dynamic object matching the DT_NEEDED entry.  */
420*a9fa9459Szrj
421*a9fa9459Szrj  /* We have already checked that there is no other input file of the
422*a9fa9459Szrj     same name.  We must now check again that we are not including the
423*a9fa9459Szrj     same file twice.  We need to do this because on many systems
424*a9fa9459Szrj     libc.so is a symlink to, e.g., libc.so.1.  The SONAME entry will
425*a9fa9459Szrj     reference libc.so.1.  If we have already included libc.so, we
426*a9fa9459Szrj     don't want to include libc.so.1 if they are the same file, and we
427*a9fa9459Szrj     can only check that using stat.  */
428*a9fa9459Szrj
429*a9fa9459Szrj  if (bfd_stat (abfd, &global_stat) != 0)
430*a9fa9459Szrj    einfo ("%F%P:%B: bfd_stat failed: %E\n", abfd);
431*a9fa9459Szrj
432*a9fa9459Szrj  /* First strip off everything before the last '/'.  */
433*a9fa9459Szrj  soname = lbasename (abfd->filename);
434*a9fa9459Szrj
435*a9fa9459Szrj  if (verbose)
436*a9fa9459Szrj    info_msg (_("found %s at %s\n"), soname, name);
437*a9fa9459Szrj
438*a9fa9459Szrj  global_found = NULL;
439*a9fa9459Szrj  lang_for_each_input_file (gld${EMULATION_NAME}_stat_needed);
440*a9fa9459Szrj  if (global_found != NULL)
441*a9fa9459Szrj    {
442*a9fa9459Szrj      /* Return TRUE to indicate that we found the file, even though
443*a9fa9459Szrj	 we aren't going to do anything with it.  */
444*a9fa9459Szrj      return TRUE;
445*a9fa9459Szrj    }
446*a9fa9459Szrj
447*a9fa9459Szrj  /* Specify the soname to use.  */
448*a9fa9459Szrj  bfd_elf_set_dt_needed_name (abfd, soname);
449*a9fa9459Szrj
450*a9fa9459Szrj  /* Tell the ELF linker that we don't want the output file to have a
451*a9fa9459Szrj     DT_NEEDED entry for this file, unless it is used to resolve
452*a9fa9459Szrj     references in a regular object.  */
453*a9fa9459Szrj  link_class = DYN_DT_NEEDED;
454*a9fa9459Szrj
455*a9fa9459Szrj  /* Tell the ELF linker that we don't want the output file to have a
456*a9fa9459Szrj     DT_NEEDED entry for this file at all if the entry is from a file
457*a9fa9459Szrj     with DYN_NO_ADD_NEEDED.  */
458*a9fa9459Szrj  if (needed->by != NULL
459*a9fa9459Szrj      && (bfd_elf_get_dyn_lib_class (needed->by) & DYN_NO_ADD_NEEDED) != 0)
460*a9fa9459Szrj    link_class |= DYN_NO_NEEDED | DYN_NO_ADD_NEEDED;
461*a9fa9459Szrj
462*a9fa9459Szrj  bfd_elf_set_dyn_lib_class (abfd, (enum dynamic_lib_link_class) link_class);
463*a9fa9459Szrj
464*a9fa9459Szrj  /* Add this file into the symbol table.  */
465*a9fa9459Szrj  if (! bfd_link_add_symbols (abfd, &link_info))
466*a9fa9459Szrj    einfo ("%F%B: error adding symbols: %E\n", abfd);
467*a9fa9459Szrj
468*a9fa9459Szrj  return TRUE;
469*a9fa9459Szrj}
470*a9fa9459Szrj
471*a9fa9459Szrj
472*a9fa9459Szrj/* Search for a needed file in a path.  */
473*a9fa9459Szrj
474*a9fa9459Szrjstatic bfd_boolean
475*a9fa9459Szrjgld${EMULATION_NAME}_search_needed (const char *path,
476*a9fa9459Szrj				    struct dt_needed *n, int force)
477*a9fa9459Szrj{
478*a9fa9459Szrj  const char *s;
479*a9fa9459Szrj  const char *name = n->name;
480*a9fa9459Szrj  size_t len;
481*a9fa9459Szrj  struct dt_needed needed;
482*a9fa9459Szrj
483*a9fa9459Szrj  if (name[0] == '/')
484*a9fa9459Szrj    return gld${EMULATION_NAME}_try_needed (n, force);
485*a9fa9459Szrj
486*a9fa9459Szrj  if (path == NULL || *path == '\0')
487*a9fa9459Szrj    return FALSE;
488*a9fa9459Szrj
489*a9fa9459Szrj  needed.by = n->by;
490*a9fa9459Szrj  needed.name = n->name;
491*a9fa9459Szrj
492*a9fa9459Szrj  len = strlen (name);
493*a9fa9459Szrj  while (1)
494*a9fa9459Szrj    {
495*a9fa9459Szrj      char *filename, *sset;
496*a9fa9459Szrj
497*a9fa9459Szrj      s = strchr (path, config.rpath_separator);
498*a9fa9459Szrj      if (s == NULL)
499*a9fa9459Szrj	s = path + strlen (path);
500*a9fa9459Szrj
501*a9fa9459Szrj#if HAVE_DOS_BASED_FILE_SYSTEM
502*a9fa9459Szrj      /* Assume a match on the second char is part of drive specifier.  */
503*a9fa9459Szrj      else if (config.rpath_separator == ':'
504*a9fa9459Szrj	       && s == path + 1
505*a9fa9459Szrj	       && ISALPHA (*path))
506*a9fa9459Szrj	{
507*a9fa9459Szrj	  s = strchr (s + 1, config.rpath_separator);
508*a9fa9459Szrj	  if (s == NULL)
509*a9fa9459Szrj	    s = path + strlen (path);
510*a9fa9459Szrj	}
511*a9fa9459Szrj#endif
512*a9fa9459Szrj      filename = (char *) xmalloc (s - path + len + 2);
513*a9fa9459Szrj      if (s == path)
514*a9fa9459Szrj	sset = filename;
515*a9fa9459Szrj      else
516*a9fa9459Szrj	{
517*a9fa9459Szrj	  memcpy (filename, path, s - path);
518*a9fa9459Szrj	  filename[s - path] = '/';
519*a9fa9459Szrj	  sset = filename + (s - path) + 1;
520*a9fa9459Szrj	}
521*a9fa9459Szrj      strcpy (sset, name);
522*a9fa9459Szrj
523*a9fa9459Szrj      needed.name = filename;
524*a9fa9459Szrj      if (gld${EMULATION_NAME}_try_needed (&needed, force))
525*a9fa9459Szrj	return TRUE;
526*a9fa9459Szrj
527*a9fa9459Szrj      free (filename);
528*a9fa9459Szrj
529*a9fa9459Szrj      if (*s == '\0')
530*a9fa9459Szrj	break;
531*a9fa9459Szrj      path = s + 1;
532*a9fa9459Szrj    }
533*a9fa9459Szrj
534*a9fa9459Szrj  return FALSE;
535*a9fa9459Szrj}
536*a9fa9459Szrj
537*a9fa9459SzrjEOF
538*a9fa9459Szrjif [ "x${USE_LIBPATH}" = xyes ] ; then
539*a9fa9459Szrj  fragment <<EOF
540*a9fa9459Szrj
541*a9fa9459Szrj/* Add the sysroot to every entry in a path separated by
542*a9fa9459Szrj   config.rpath_separator.  */
543*a9fa9459Szrj
544*a9fa9459Szrjstatic char *
545*a9fa9459Szrjgld${EMULATION_NAME}_add_sysroot (const char *path)
546*a9fa9459Szrj{
547*a9fa9459Szrj  int len, colons, i;
548*a9fa9459Szrj  char *ret, *p;
549*a9fa9459Szrj
550*a9fa9459Szrj  len = strlen (path);
551*a9fa9459Szrj  colons = 0;
552*a9fa9459Szrj  i = 0;
553*a9fa9459Szrj  while (path[i])
554*a9fa9459Szrj    if (path[i++] == config.rpath_separator)
555*a9fa9459Szrj      colons++;
556*a9fa9459Szrj
557*a9fa9459Szrj  if (path[i])
558*a9fa9459Szrj    colons++;
559*a9fa9459Szrj
560*a9fa9459Szrj  len = len + (colons + 1) * strlen (ld_sysroot);
561*a9fa9459Szrj  ret = xmalloc (len + 1);
562*a9fa9459Szrj  strcpy (ret, ld_sysroot);
563*a9fa9459Szrj  p = ret + strlen (ret);
564*a9fa9459Szrj  i = 0;
565*a9fa9459Szrj  while (path[i])
566*a9fa9459Szrj    if (path[i] == config.rpath_separator)
567*a9fa9459Szrj      {
568*a9fa9459Szrj	*p++ = path[i++];
569*a9fa9459Szrj	strcpy (p, ld_sysroot);
570*a9fa9459Szrj	p = p + strlen (p);
571*a9fa9459Szrj      }
572*a9fa9459Szrj    else
573*a9fa9459Szrj      *p++ = path[i++];
574*a9fa9459Szrj
575*a9fa9459Szrj  *p = 0;
576*a9fa9459Szrj  return ret;
577*a9fa9459Szrj}
578*a9fa9459Szrj
579*a9fa9459SzrjEOF
580*a9fa9459Szrj  case ${target} in
581*a9fa9459Szrj    *-*-freebsd* | *-*-dragonfly*)
582*a9fa9459Szrj      fragment <<EOF
583*a9fa9459Szrj/* Read the system search path the FreeBSD way rather than the Linux way.  */
584*a9fa9459Szrj#ifdef HAVE_ELF_HINTS_H
585*a9fa9459Szrj#include <elf-hints.h>
586*a9fa9459Szrj#else
587*a9fa9459Szrj#include "elf-hints-local.h"
588*a9fa9459Szrj#endif
589*a9fa9459Szrj
590*a9fa9459Szrjstatic bfd_boolean
591*a9fa9459Szrjgld${EMULATION_NAME}_check_ld_elf_hints (const struct bfd_link_needed_list *l,
592*a9fa9459Szrj					 int force)
593*a9fa9459Szrj{
594*a9fa9459Szrj  static bfd_boolean initialized;
595*a9fa9459Szrj  static char *ld_elf_hints;
596*a9fa9459Szrj  struct dt_needed needed;
597*a9fa9459Szrj
598*a9fa9459Szrj  if (!initialized)
599*a9fa9459Szrj    {
600*a9fa9459Szrj      FILE *f;
601*a9fa9459Szrj      char *tmppath;
602*a9fa9459Szrj
603*a9fa9459Szrj      tmppath = concat (ld_sysroot, _PATH_ELF_HINTS, (const char *) NULL);
604*a9fa9459Szrj      f = fopen (tmppath, FOPEN_RB);
605*a9fa9459Szrj      free (tmppath);
606*a9fa9459Szrj      if (f != NULL)
607*a9fa9459Szrj	{
608*a9fa9459Szrj	  struct elfhints_hdr hdr;
609*a9fa9459Szrj
610*a9fa9459Szrj	  if (fread (&hdr, 1, sizeof (hdr), f) == sizeof (hdr)
611*a9fa9459Szrj	      && hdr.magic == ELFHINTS_MAGIC
612*a9fa9459Szrj	      && hdr.version == 1)
613*a9fa9459Szrj	    {
614*a9fa9459Szrj	      if (fseek (f, hdr.strtab + hdr.dirlist, SEEK_SET) != -1)
615*a9fa9459Szrj		{
616*a9fa9459Szrj		  char *b;
617*a9fa9459Szrj
618*a9fa9459Szrj		  b = xmalloc (hdr.dirlistlen + 1);
619*a9fa9459Szrj		  if (fread (b, 1, hdr.dirlistlen + 1, f) ==
620*a9fa9459Szrj		      hdr.dirlistlen + 1)
621*a9fa9459Szrj		    ld_elf_hints = gld${EMULATION_NAME}_add_sysroot (b);
622*a9fa9459Szrj
623*a9fa9459Szrj		  free (b);
624*a9fa9459Szrj		}
625*a9fa9459Szrj	    }
626*a9fa9459Szrj	  fclose (f);
627*a9fa9459Szrj	}
628*a9fa9459Szrj
629*a9fa9459Szrj      initialized = TRUE;
630*a9fa9459Szrj    }
631*a9fa9459Szrj
632*a9fa9459Szrj  if (ld_elf_hints == NULL)
633*a9fa9459Szrj    return FALSE;
634*a9fa9459Szrj
635*a9fa9459Szrj  needed.by = l->by;
636*a9fa9459Szrj  needed.name = l->name;
637*a9fa9459Szrj  return gld${EMULATION_NAME}_search_needed (ld_elf_hints, &needed, force);
638*a9fa9459Szrj}
639*a9fa9459SzrjEOF
640*a9fa9459Szrj    # FreeBSD
641*a9fa9459Szrj    ;;
642*a9fa9459Szrj
643*a9fa9459Szrj    *-*-linux-* | *-*-k*bsd*-* | *-*-gnu*)
644*a9fa9459Szrj      fragment <<EOF
645*a9fa9459Szrj/* For a native linker, check the file /etc/ld.so.conf for directories
646*a9fa9459Szrj   in which we may find shared libraries.  /etc/ld.so.conf is really
647*a9fa9459Szrj   only meaningful on Linux.  */
648*a9fa9459Szrj
649*a9fa9459Szrjstruct gld${EMULATION_NAME}_ld_so_conf
650*a9fa9459Szrj{
651*a9fa9459Szrj  char *path;
652*a9fa9459Szrj  size_t len, alloc;
653*a9fa9459Szrj};
654*a9fa9459Szrj
655*a9fa9459Szrjstatic bfd_boolean
656*a9fa9459Szrjgld${EMULATION_NAME}_parse_ld_so_conf
657*a9fa9459Szrj     (struct gld${EMULATION_NAME}_ld_so_conf *info, const char *filename);
658*a9fa9459Szrj
659*a9fa9459Szrjstatic void
660*a9fa9459Szrjgld${EMULATION_NAME}_parse_ld_so_conf_include
661*a9fa9459Szrj     (struct gld${EMULATION_NAME}_ld_so_conf *info, const char *filename,
662*a9fa9459Szrj      const char *pattern)
663*a9fa9459Szrj{
664*a9fa9459Szrj  char *newp = NULL;
665*a9fa9459Szrj#ifdef HAVE_GLOB
666*a9fa9459Szrj  glob_t gl;
667*a9fa9459Szrj#endif
668*a9fa9459Szrj
669*a9fa9459Szrj  if (pattern[0] != '/')
670*a9fa9459Szrj    {
671*a9fa9459Szrj      char *p = strrchr (filename, '/');
672*a9fa9459Szrj      size_t patlen = strlen (pattern) + 1;
673*a9fa9459Szrj
674*a9fa9459Szrj      newp = xmalloc (p - filename + 1 + patlen);
675*a9fa9459Szrj      memcpy (newp, filename, p - filename + 1);
676*a9fa9459Szrj      memcpy (newp + (p - filename + 1), pattern, patlen);
677*a9fa9459Szrj      pattern = newp;
678*a9fa9459Szrj    }
679*a9fa9459Szrj
680*a9fa9459Szrj#ifdef HAVE_GLOB
681*a9fa9459Szrj  if (glob (pattern, 0, NULL, &gl) == 0)
682*a9fa9459Szrj    {
683*a9fa9459Szrj      size_t i;
684*a9fa9459Szrj
685*a9fa9459Szrj      for (i = 0; i < gl.gl_pathc; ++i)
686*a9fa9459Szrj	gld${EMULATION_NAME}_parse_ld_so_conf (info, gl.gl_pathv[i]);
687*a9fa9459Szrj      globfree (&gl);
688*a9fa9459Szrj    }
689*a9fa9459Szrj#else
690*a9fa9459Szrj  /* If we do not have glob, treat the pattern as a literal filename.  */
691*a9fa9459Szrj  gld${EMULATION_NAME}_parse_ld_so_conf (info, pattern);
692*a9fa9459Szrj#endif
693*a9fa9459Szrj
694*a9fa9459Szrj  if (newp)
695*a9fa9459Szrj    free (newp);
696*a9fa9459Szrj}
697*a9fa9459Szrj
698*a9fa9459Szrjstatic bfd_boolean
699*a9fa9459Szrjgld${EMULATION_NAME}_parse_ld_so_conf
700*a9fa9459Szrj     (struct gld${EMULATION_NAME}_ld_so_conf *info, const char *filename)
701*a9fa9459Szrj{
702*a9fa9459Szrj  FILE *f = fopen (filename, FOPEN_RT);
703*a9fa9459Szrj  char *line;
704*a9fa9459Szrj  size_t linelen;
705*a9fa9459Szrj
706*a9fa9459Szrj  if (f == NULL)
707*a9fa9459Szrj    return FALSE;
708*a9fa9459Szrj
709*a9fa9459Szrj  linelen = 256;
710*a9fa9459Szrj  line = xmalloc (linelen);
711*a9fa9459Szrj  do
712*a9fa9459Szrj    {
713*a9fa9459Szrj      char *p = line, *q;
714*a9fa9459Szrj
715*a9fa9459Szrj      /* Normally this would use getline(3), but we need to be portable.  */
716*a9fa9459Szrj      while ((q = fgets (p, linelen - (p - line), f)) != NULL
717*a9fa9459Szrj	     && strlen (q) == linelen - (p - line) - 1
718*a9fa9459Szrj	     && line[linelen - 2] != '\n')
719*a9fa9459Szrj	{
720*a9fa9459Szrj	  line = xrealloc (line, 2 * linelen);
721*a9fa9459Szrj	  p = line + linelen - 1;
722*a9fa9459Szrj	  linelen += linelen;
723*a9fa9459Szrj	}
724*a9fa9459Szrj
725*a9fa9459Szrj      if (q == NULL && p == line)
726*a9fa9459Szrj	break;
727*a9fa9459Szrj
728*a9fa9459Szrj      p = strchr (line, '\n');
729*a9fa9459Szrj      if (p)
730*a9fa9459Szrj	*p = '\0';
731*a9fa9459Szrj
732*a9fa9459Szrj      /* Because the file format does not know any form of quoting we
733*a9fa9459Szrj	 can search forward for the next '#' character and if found
734*a9fa9459Szrj	 make it terminating the line.  */
735*a9fa9459Szrj      p = strchr (line, '#');
736*a9fa9459Szrj      if (p)
737*a9fa9459Szrj	*p = '\0';
738*a9fa9459Szrj
739*a9fa9459Szrj      /* Remove leading whitespace.  NUL is no whitespace character.  */
740*a9fa9459Szrj      p = line;
741*a9fa9459Szrj      while (*p == ' ' || *p == '\f' || *p == '\r' || *p == '\t' || *p == '\v')
742*a9fa9459Szrj	++p;
743*a9fa9459Szrj
744*a9fa9459Szrj      /* If the line is blank it is ignored.  */
745*a9fa9459Szrj      if (p[0] == '\0')
746*a9fa9459Szrj	continue;
747*a9fa9459Szrj
748*a9fa9459Szrj      if (CONST_STRNEQ (p, "include") && (p[7] == ' ' || p[7] == '\t'))
749*a9fa9459Szrj	{
750*a9fa9459Szrj	  char *dir, c;
751*a9fa9459Szrj	  p += 8;
752*a9fa9459Szrj	  do
753*a9fa9459Szrj	    {
754*a9fa9459Szrj	      while (*p == ' ' || *p == '\t')
755*a9fa9459Szrj		++p;
756*a9fa9459Szrj
757*a9fa9459Szrj	      if (*p == '\0')
758*a9fa9459Szrj		break;
759*a9fa9459Szrj
760*a9fa9459Szrj	      dir = p;
761*a9fa9459Szrj
762*a9fa9459Szrj	      while (*p != ' ' && *p != '\t' && *p)
763*a9fa9459Szrj		++p;
764*a9fa9459Szrj
765*a9fa9459Szrj	      c = *p;
766*a9fa9459Szrj	      *p++ = '\0';
767*a9fa9459Szrj	      if (dir[0] != '\0')
768*a9fa9459Szrj		gld${EMULATION_NAME}_parse_ld_so_conf_include (info, filename,
769*a9fa9459Szrj							       dir);
770*a9fa9459Szrj	    }
771*a9fa9459Szrj	  while (c != '\0');
772*a9fa9459Szrj	}
773*a9fa9459Szrj      else
774*a9fa9459Szrj	{
775*a9fa9459Szrj	  char *dir = p;
776*a9fa9459Szrj	  while (*p && *p != '=' && *p != ' ' && *p != '\t' && *p != '\f'
777*a9fa9459Szrj		 && *p != '\r' && *p != '\v')
778*a9fa9459Szrj	    ++p;
779*a9fa9459Szrj
780*a9fa9459Szrj	  while (p != dir && p[-1] == '/')
781*a9fa9459Szrj	    --p;
782*a9fa9459Szrj	  if (info->path == NULL)
783*a9fa9459Szrj	    {
784*a9fa9459Szrj	      info->alloc = p - dir + 1 + 256;
785*a9fa9459Szrj	      info->path = xmalloc (info->alloc);
786*a9fa9459Szrj	      info->len = 0;
787*a9fa9459Szrj	    }
788*a9fa9459Szrj	  else
789*a9fa9459Szrj	    {
790*a9fa9459Szrj	      if (info->len + 1 + (p - dir) >= info->alloc)
791*a9fa9459Szrj		{
792*a9fa9459Szrj		  info->alloc += p - dir + 256;
793*a9fa9459Szrj		  info->path = xrealloc (info->path, info->alloc);
794*a9fa9459Szrj		}
795*a9fa9459Szrj	      info->path[info->len++] = config.rpath_separator;
796*a9fa9459Szrj	    }
797*a9fa9459Szrj	  memcpy (info->path + info->len, dir, p - dir);
798*a9fa9459Szrj	  info->len += p - dir;
799*a9fa9459Szrj	  info->path[info->len] = '\0';
800*a9fa9459Szrj	}
801*a9fa9459Szrj    }
802*a9fa9459Szrj  while (! feof (f));
803*a9fa9459Szrj  free (line);
804*a9fa9459Szrj  fclose (f);
805*a9fa9459Szrj  return TRUE;
806*a9fa9459Szrj}
807*a9fa9459Szrj
808*a9fa9459Szrjstatic bfd_boolean
809*a9fa9459Szrjgld${EMULATION_NAME}_check_ld_so_conf (const struct bfd_link_needed_list *l,
810*a9fa9459Szrj				       int force)
811*a9fa9459Szrj{
812*a9fa9459Szrj  static bfd_boolean initialized;
813*a9fa9459Szrj  static char *ld_so_conf;
814*a9fa9459Szrj  struct dt_needed needed;
815*a9fa9459Szrj
816*a9fa9459Szrj  if (! initialized)
817*a9fa9459Szrj    {
818*a9fa9459Szrj      char *tmppath;
819*a9fa9459Szrj      struct gld${EMULATION_NAME}_ld_so_conf info;
820*a9fa9459Szrj
821*a9fa9459Szrj      info.path = NULL;
822*a9fa9459Szrj      info.len = info.alloc = 0;
823*a9fa9459Szrj      tmppath = concat (ld_sysroot, "${prefix}/etc/ld.so.conf",
824*a9fa9459Szrj			(const char *) NULL);
825*a9fa9459Szrj      if (!gld${EMULATION_NAME}_parse_ld_so_conf (&info, tmppath))
826*a9fa9459Szrj	{
827*a9fa9459Szrj	  free (tmppath);
828*a9fa9459Szrj	  tmppath = concat (ld_sysroot, "/etc/ld.so.conf",
829*a9fa9459Szrj			    (const char *) NULL);
830*a9fa9459Szrj	  gld${EMULATION_NAME}_parse_ld_so_conf (&info, tmppath);
831*a9fa9459Szrj	}
832*a9fa9459Szrj      free (tmppath);
833*a9fa9459Szrj
834*a9fa9459Szrj      if (info.path)
835*a9fa9459Szrj	{
836*a9fa9459Szrj	  char *d = gld${EMULATION_NAME}_add_sysroot (info.path);
837*a9fa9459Szrj	  free (info.path);
838*a9fa9459Szrj	  ld_so_conf = d;
839*a9fa9459Szrj	}
840*a9fa9459Szrj      initialized = TRUE;
841*a9fa9459Szrj    }
842*a9fa9459Szrj
843*a9fa9459Szrj  if (ld_so_conf == NULL)
844*a9fa9459Szrj    return FALSE;
845*a9fa9459Szrj
846*a9fa9459Szrj
847*a9fa9459Szrj  needed.by = l->by;
848*a9fa9459Szrj  needed.name = l->name;
849*a9fa9459Szrj  return gld${EMULATION_NAME}_search_needed (ld_so_conf, &needed, force);
850*a9fa9459Szrj}
851*a9fa9459Szrj
852*a9fa9459SzrjEOF
853*a9fa9459Szrj    # Linux
854*a9fa9459Szrj    ;;
855*a9fa9459Szrj  esac
856*a9fa9459Szrjfi
857*a9fa9459Szrjfragment <<EOF
858*a9fa9459Szrj
859*a9fa9459Szrj/* See if an input file matches a DT_NEEDED entry by name.  */
860*a9fa9459Szrj
861*a9fa9459Szrjstatic void
862*a9fa9459Szrjgld${EMULATION_NAME}_check_needed (lang_input_statement_type *s)
863*a9fa9459Szrj{
864*a9fa9459Szrj  const char *soname;
865*a9fa9459Szrj
866*a9fa9459Szrj  /* Stop looking if we've found a loaded lib.  */
867*a9fa9459Szrj  if (global_found != NULL
868*a9fa9459Szrj      && (bfd_elf_get_dyn_lib_class (global_found->the_bfd)
869*a9fa9459Szrj	  & DYN_AS_NEEDED) == 0)
870*a9fa9459Szrj    return;
871*a9fa9459Szrj
872*a9fa9459Szrj  if (s->filename == NULL || s->the_bfd == NULL)
873*a9fa9459Szrj    return;
874*a9fa9459Szrj
875*a9fa9459Szrj  /* Don't look for a second non-loaded as-needed lib.  */
876*a9fa9459Szrj  if (global_found != NULL
877*a9fa9459Szrj      && (bfd_elf_get_dyn_lib_class (s->the_bfd) & DYN_AS_NEEDED) != 0)
878*a9fa9459Szrj    return;
879*a9fa9459Szrj
880*a9fa9459Szrj  if (filename_cmp (s->filename, global_needed->name) == 0)
881*a9fa9459Szrj    {
882*a9fa9459Szrj      global_found = s;
883*a9fa9459Szrj      return;
884*a9fa9459Szrj    }
885*a9fa9459Szrj
886*a9fa9459Szrj  if (s->flags.search_dirs)
887*a9fa9459Szrj    {
888*a9fa9459Szrj      const char *f = strrchr (s->filename, '/');
889*a9fa9459Szrj      if (f != NULL
890*a9fa9459Szrj	  && filename_cmp (f + 1, global_needed->name) == 0)
891*a9fa9459Szrj	{
892*a9fa9459Szrj	  global_found = s;
893*a9fa9459Szrj	  return;
894*a9fa9459Szrj	}
895*a9fa9459Szrj    }
896*a9fa9459Szrj
897*a9fa9459Szrj  soname = bfd_elf_get_dt_soname (s->the_bfd);
898*a9fa9459Szrj  if (soname != NULL
899*a9fa9459Szrj      && filename_cmp (soname, global_needed->name) == 0)
900*a9fa9459Szrj    {
901*a9fa9459Szrj      global_found = s;
902*a9fa9459Szrj      return;
903*a9fa9459Szrj    }
904*a9fa9459Szrj}
905*a9fa9459Szrj
906*a9fa9459SzrjEOF
907*a9fa9459Szrj
908*a9fa9459Szrjif test x"$LDEMUL_AFTER_OPEN" != xgld"$EMULATION_NAME"_after_open; then
909*a9fa9459Szrjfragment <<EOF
910*a9fa9459Szrj
911*a9fa9459Szrjstatic bfd_size_type
912*a9fa9459Szrjid_note_section_size (bfd *abfd ATTRIBUTE_UNUSED)
913*a9fa9459Szrj{
914*a9fa9459Szrj  const char *style = emit_note_gnu_build_id;
915*a9fa9459Szrj  bfd_size_type size;
916*a9fa9459Szrj  bfd_size_type build_id_size;
917*a9fa9459Szrj
918*a9fa9459Szrj  size = offsetof (Elf_External_Note, name[sizeof "GNU"]);
919*a9fa9459Szrj  size = (size + 3) & -(bfd_size_type) 4;
920*a9fa9459Szrj
921*a9fa9459Szrj  build_id_size = compute_build_id_size (style);
922*a9fa9459Szrj  if (build_id_size)
923*a9fa9459Szrj    size += build_id_size;
924*a9fa9459Szrj  else
925*a9fa9459Szrj    size = 0;
926*a9fa9459Szrj
927*a9fa9459Szrj  return size;
928*a9fa9459Szrj}
929*a9fa9459Szrj
930*a9fa9459Szrjstatic bfd_boolean
931*a9fa9459Szrjwrite_build_id (bfd *abfd)
932*a9fa9459Szrj{
933*a9fa9459Szrj  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
934*a9fa9459Szrj  struct elf_obj_tdata *t = elf_tdata (abfd);
935*a9fa9459Szrj  const char *style;
936*a9fa9459Szrj  asection *asec;
937*a9fa9459Szrj  Elf_Internal_Shdr *i_shdr;
938*a9fa9459Szrj  unsigned char *contents, *id_bits;
939*a9fa9459Szrj  bfd_size_type size;
940*a9fa9459Szrj  file_ptr position;
941*a9fa9459Szrj  Elf_External_Note *e_note;
942*a9fa9459Szrj
943*a9fa9459Szrj  style = t->o->build_id.style;
944*a9fa9459Szrj  asec = t->o->build_id.sec;
945*a9fa9459Szrj  if (bfd_is_abs_section (asec->output_section))
946*a9fa9459Szrj    {
947*a9fa9459Szrj      einfo (_("%P: warning: .note.gnu.build-id section discarded,"
948*a9fa9459Szrj	       " --build-id ignored.\n"));
949*a9fa9459Szrj      return TRUE;
950*a9fa9459Szrj    }
951*a9fa9459Szrj  i_shdr = &elf_section_data (asec->output_section)->this_hdr;
952*a9fa9459Szrj
953*a9fa9459Szrj  if (i_shdr->contents == NULL)
954*a9fa9459Szrj    {
955*a9fa9459Szrj      if (asec->contents == NULL)
956*a9fa9459Szrj	asec->contents = (unsigned char *) xmalloc (asec->size);
957*a9fa9459Szrj      contents = asec->contents;
958*a9fa9459Szrj    }
959*a9fa9459Szrj  else
960*a9fa9459Szrj    contents = i_shdr->contents + asec->output_offset;
961*a9fa9459Szrj
962*a9fa9459Szrj  e_note = (Elf_External_Note *) contents;
963*a9fa9459Szrj  size = offsetof (Elf_External_Note, name[sizeof "GNU"]);
964*a9fa9459Szrj  size = (size + 3) & -(bfd_size_type) 4;
965*a9fa9459Szrj  id_bits = contents + size;
966*a9fa9459Szrj  size = asec->size - size;
967*a9fa9459Szrj
968*a9fa9459Szrj  bfd_h_put_32 (abfd, sizeof "GNU", &e_note->namesz);
969*a9fa9459Szrj  bfd_h_put_32 (abfd, size, &e_note->descsz);
970*a9fa9459Szrj  bfd_h_put_32 (abfd, NT_GNU_BUILD_ID, &e_note->type);
971*a9fa9459Szrj  memcpy (e_note->name, "GNU", sizeof "GNU");
972*a9fa9459Szrj
973*a9fa9459Szrj  generate_build_id (abfd, style, bed->s->checksum_contents, id_bits, size);
974*a9fa9459Szrj
975*a9fa9459Szrj  position = i_shdr->sh_offset + asec->output_offset;
976*a9fa9459Szrj  size = asec->size;
977*a9fa9459Szrj  return (bfd_seek (abfd, position, SEEK_SET) == 0
978*a9fa9459Szrj	  && bfd_bwrite (contents, size, abfd) == size);
979*a9fa9459Szrj}
980*a9fa9459Szrj
981*a9fa9459Szrj/* Make .note.gnu.build-id section, and set up elf_tdata->build_id.  */
982*a9fa9459Szrj
983*a9fa9459Szrjstatic bfd_boolean
984*a9fa9459Szrjsetup_build_id (bfd *ibfd)
985*a9fa9459Szrj{
986*a9fa9459Szrj  asection *s;
987*a9fa9459Szrj  bfd_size_type size;
988*a9fa9459Szrj  flagword flags;
989*a9fa9459Szrj
990*a9fa9459Szrj  size = id_note_section_size (ibfd);
991*a9fa9459Szrj  if (size == 0)
992*a9fa9459Szrj    {
993*a9fa9459Szrj      einfo ("%P: warning: unrecognized --build-id style ignored.\n");
994*a9fa9459Szrj      return FALSE;
995*a9fa9459Szrj    }
996*a9fa9459Szrj
997*a9fa9459Szrj  flags = (SEC_ALLOC | SEC_LOAD | SEC_IN_MEMORY
998*a9fa9459Szrj	   | SEC_LINKER_CREATED | SEC_READONLY | SEC_DATA);
999*a9fa9459Szrj  s = bfd_make_section_with_flags (ibfd, ".note.gnu.build-id", flags);
1000*a9fa9459Szrj  if (s != NULL && bfd_set_section_alignment (ibfd, s, 2))
1001*a9fa9459Szrj    {
1002*a9fa9459Szrj      struct elf_obj_tdata *t = elf_tdata (link_info.output_bfd);
1003*a9fa9459Szrj      t->o->build_id.after_write_object_contents = &write_build_id;
1004*a9fa9459Szrj      t->o->build_id.style = emit_note_gnu_build_id;
1005*a9fa9459Szrj      t->o->build_id.sec = s;
1006*a9fa9459Szrj      elf_section_type (s) = SHT_NOTE;
1007*a9fa9459Szrj      s->size = size;
1008*a9fa9459Szrj      return TRUE;
1009*a9fa9459Szrj    }
1010*a9fa9459Szrj
1011*a9fa9459Szrj  einfo ("%P: warning: Cannot create .note.gnu.build-id section,"
1012*a9fa9459Szrj	 " --build-id ignored.\n");
1013*a9fa9459Szrj  return FALSE;
1014*a9fa9459Szrj}
1015*a9fa9459Szrj
1016*a9fa9459Szrj/* This is called after all the input files have been opened.  */
1017*a9fa9459Szrj
1018*a9fa9459Szrjstatic void
1019*a9fa9459Szrjgld${EMULATION_NAME}_after_open (void)
1020*a9fa9459Szrj{
1021*a9fa9459Szrj  struct bfd_link_needed_list *needed, *l;
1022*a9fa9459Szrj  struct elf_link_hash_table *htab;
1023*a9fa9459Szrj
1024*a9fa9459Szrj  after_open_default ();
1025*a9fa9459Szrj
1026*a9fa9459Szrj  htab = elf_hash_table (&link_info);
1027*a9fa9459Szrj  if (!is_elf_hash_table (htab))
1028*a9fa9459Szrj    return;
1029*a9fa9459Szrj
1030*a9fa9459Szrj  if (emit_note_gnu_build_id != NULL)
1031*a9fa9459Szrj    {
1032*a9fa9459Szrj      bfd *abfd;
1033*a9fa9459Szrj
1034*a9fa9459Szrj      /* Find an ELF input.  */
1035*a9fa9459Szrj      for (abfd = link_info.input_bfds;
1036*a9fa9459Szrj	   abfd != (bfd *) NULL; abfd = abfd->link.next)
1037*a9fa9459Szrj	if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
1038*a9fa9459Szrj	    && bfd_count_sections (abfd) != 0)
1039*a9fa9459Szrj	  break;
1040*a9fa9459Szrj
1041*a9fa9459Szrj      /* PR 10555: If there are no ELF input files do not try to
1042*a9fa9459Szrj	 create a .note.gnu-build-id section.  */
1043*a9fa9459Szrj      if (abfd == NULL
1044*a9fa9459Szrj	  || !setup_build_id (abfd))
1045*a9fa9459Szrj	{
1046*a9fa9459Szrj	  free ((char *) emit_note_gnu_build_id);
1047*a9fa9459Szrj	  emit_note_gnu_build_id = NULL;
1048*a9fa9459Szrj	}
1049*a9fa9459Szrj    }
1050*a9fa9459Szrj
1051*a9fa9459Szrj  if (bfd_link_relocatable (&link_info))
1052*a9fa9459Szrj    {
1053*a9fa9459Szrj      if (link_info.execstack == ! link_info.noexecstack)
1054*a9fa9459Szrj	/* PR ld/16744: If "-z [no]execstack" has been specified on the
1055*a9fa9459Szrj	   command line and we are perfoming a relocatable link then no
1056*a9fa9459Szrj	   PT_GNU_STACK segment will be created and so the
1057*a9fa9459Szrj	   linkinfo.[no]execstack values set in _handle_option() will have no
1058*a9fa9459Szrj	   effect.  Instead we create a .note.GNU-stack section in much the
1059*a9fa9459Szrj	   same way as the assembler does with its --[no]execstack option.  */
1060*a9fa9459Szrj	(void) bfd_make_section_with_flags (link_info.input_bfds,
1061*a9fa9459Szrj					    ".note.GNU-stack",
1062*a9fa9459Szrj					    SEC_READONLY | (link_info.execstack ? SEC_CODE : 0));
1063*a9fa9459Szrj
1064*a9fa9459Szrj      return;
1065*a9fa9459Szrj    }
1066*a9fa9459Szrj
1067*a9fa9459Szrj  if (!link_info.traditional_format)
1068*a9fa9459Szrj    {
1069*a9fa9459Szrj      bfd *abfd, *elfbfd = NULL;
1070*a9fa9459Szrj      bfd_boolean warn_eh_frame = FALSE;
1071*a9fa9459Szrj      asection *s;
1072*a9fa9459Szrj      int seen_type = 0;
1073*a9fa9459Szrj
1074*a9fa9459Szrj      for (abfd = link_info.input_bfds; abfd; abfd = abfd->link.next)
1075*a9fa9459Szrj	{
1076*a9fa9459Szrj	  int type = 0;
1077*a9fa9459Szrj	  for (s = abfd->sections; s && type < COMPACT_EH_HDR; s = s->next)
1078*a9fa9459Szrj	    {
1079*a9fa9459Szrj	      const char *name = bfd_get_section_name (abfd, s);
1080*a9fa9459Szrj
1081*a9fa9459Szrj	      if (bfd_is_abs_section (s->output_section))
1082*a9fa9459Szrj		continue;
1083*a9fa9459Szrj	      if (CONST_STRNEQ (name, ".eh_frame_entry"))
1084*a9fa9459Szrj		type = COMPACT_EH_HDR;
1085*a9fa9459Szrj	      else if (strcmp (name, ".eh_frame") == 0 && s->size > 8)
1086*a9fa9459Szrj		type = DWARF2_EH_HDR;
1087*a9fa9459Szrj	    }
1088*a9fa9459Szrj
1089*a9fa9459Szrj	  if (type != 0)
1090*a9fa9459Szrj	    {
1091*a9fa9459Szrj	      if (seen_type == 0)
1092*a9fa9459Szrj		{
1093*a9fa9459Szrj		  seen_type = type;
1094*a9fa9459Szrj		}
1095*a9fa9459Szrj	      else if (seen_type != type)
1096*a9fa9459Szrj		{
1097*a9fa9459Szrj		  einfo (_("%P%F: compact frame descriptions incompatible with"
1098*a9fa9459Szrj			 " DWARF2 .eh_frame from %B\n"),
1099*a9fa9459Szrj			 type == DWARF2_EH_HDR ? abfd : elfbfd);
1100*a9fa9459Szrj		  break;
1101*a9fa9459Szrj		}
1102*a9fa9459Szrj
1103*a9fa9459Szrj	      if (!elfbfd
1104*a9fa9459Szrj		  && (type == COMPACT_EH_HDR || link_info.eh_frame_hdr_type != 0))
1105*a9fa9459Szrj		{
1106*a9fa9459Szrj		  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
1107*a9fa9459Szrj		    elfbfd = abfd;
1108*a9fa9459Szrj
1109*a9fa9459Szrj		  warn_eh_frame = TRUE;
1110*a9fa9459Szrj		}
1111*a9fa9459Szrj	    }
1112*a9fa9459Szrj
1113*a9fa9459Szrj	  if (seen_type == COMPACT_EH_HDR)
1114*a9fa9459Szrj	    link_info.eh_frame_hdr_type = COMPACT_EH_HDR;
1115*a9fa9459Szrj
1116*a9fa9459Szrj	  if (bfd_count_sections (abfd) == 0)
1117*a9fa9459Szrj	    continue;
1118*a9fa9459Szrj	}
1119*a9fa9459Szrj      if (elfbfd)
1120*a9fa9459Szrj	{
1121*a9fa9459Szrj	  const struct elf_backend_data *bed;
1122*a9fa9459Szrj
1123*a9fa9459Szrj	  bed = get_elf_backend_data (elfbfd);
1124*a9fa9459Szrj	  s = bfd_make_section_with_flags (elfbfd, ".eh_frame_hdr",
1125*a9fa9459Szrj					   bed->dynamic_sec_flags
1126*a9fa9459Szrj					   | SEC_READONLY);
1127*a9fa9459Szrj	  if (s != NULL
1128*a9fa9459Szrj	      && bfd_set_section_alignment (elfbfd, s, 2))
1129*a9fa9459Szrj	    {
1130*a9fa9459Szrj	      htab->eh_info.hdr_sec = s;
1131*a9fa9459Szrj	      warn_eh_frame = FALSE;
1132*a9fa9459Szrj	    }
1133*a9fa9459Szrj	}
1134*a9fa9459Szrj      if (warn_eh_frame)
1135*a9fa9459Szrj	einfo ("%P: warning: Cannot create .eh_frame_hdr section,"
1136*a9fa9459Szrj	       " --eh-frame-hdr ignored.\n");
1137*a9fa9459Szrj    }
1138*a9fa9459Szrj
1139*a9fa9459Szrj  /* Get the list of files which appear in DT_NEEDED entries in
1140*a9fa9459Szrj     dynamic objects included in the link (often there will be none).
1141*a9fa9459Szrj     For each such file, we want to track down the corresponding
1142*a9fa9459Szrj     library, and include the symbol table in the link.  This is what
1143*a9fa9459Szrj     the runtime dynamic linker will do.  Tracking the files down here
1144*a9fa9459Szrj     permits one dynamic object to include another without requiring
1145*a9fa9459Szrj     special action by the person doing the link.  Note that the
1146*a9fa9459Szrj     needed list can actually grow while we are stepping through this
1147*a9fa9459Szrj     loop.  */
1148*a9fa9459Szrj  needed = bfd_elf_get_needed_list (link_info.output_bfd, &link_info);
1149*a9fa9459Szrj  for (l = needed; l != NULL; l = l->next)
1150*a9fa9459Szrj    {
1151*a9fa9459Szrj      struct bfd_link_needed_list *ll;
1152*a9fa9459Szrj      struct dt_needed n, nn;
1153*a9fa9459Szrj      int force;
1154*a9fa9459Szrj
1155*a9fa9459Szrj      /* If the lib that needs this one was --as-needed and wasn't
1156*a9fa9459Szrj	 found to be needed, then this lib isn't needed either.  */
1157*a9fa9459Szrj      if (l->by != NULL
1158*a9fa9459Szrj	  && (bfd_elf_get_dyn_lib_class (l->by) & DYN_AS_NEEDED) != 0)
1159*a9fa9459Szrj	continue;
1160*a9fa9459Szrj
1161*a9fa9459Szrj      /* Skip the lib if --no-copy-dt-needed-entries and
1162*a9fa9459Szrj	 --allow-shlib-undefined is in effect.  */
1163*a9fa9459Szrj      if (l->by != NULL
1164*a9fa9459Szrj	  && link_info.unresolved_syms_in_shared_libs == RM_IGNORE
1165*a9fa9459Szrj	  && (bfd_elf_get_dyn_lib_class (l->by) & DYN_NO_ADD_NEEDED) != 0)
1166*a9fa9459Szrj	continue;
1167*a9fa9459Szrj
1168*a9fa9459Szrj      /* If we've already seen this file, skip it.  */
1169*a9fa9459Szrj      for (ll = needed; ll != l; ll = ll->next)
1170*a9fa9459Szrj	if ((ll->by == NULL
1171*a9fa9459Szrj	     || (bfd_elf_get_dyn_lib_class (ll->by) & DYN_AS_NEEDED) == 0)
1172*a9fa9459Szrj	    && strcmp (ll->name, l->name) == 0)
1173*a9fa9459Szrj	  break;
1174*a9fa9459Szrj      if (ll != l)
1175*a9fa9459Szrj	continue;
1176*a9fa9459Szrj
1177*a9fa9459Szrj      /* See if this file was included in the link explicitly.  */
1178*a9fa9459Szrj      global_needed = l;
1179*a9fa9459Szrj      global_found = NULL;
1180*a9fa9459Szrj      lang_for_each_input_file (gld${EMULATION_NAME}_check_needed);
1181*a9fa9459Szrj      if (global_found != NULL
1182*a9fa9459Szrj	  && (bfd_elf_get_dyn_lib_class (global_found->the_bfd)
1183*a9fa9459Szrj	      & DYN_AS_NEEDED) == 0)
1184*a9fa9459Szrj	continue;
1185*a9fa9459Szrj
1186*a9fa9459Szrj      n.by = l->by;
1187*a9fa9459Szrj      n.name = l->name;
1188*a9fa9459Szrj      nn.by = l->by;
1189*a9fa9459Szrj      if (verbose)
1190*a9fa9459Szrj	info_msg (_("%s needed by %B\n"), l->name, l->by);
1191*a9fa9459Szrj
1192*a9fa9459Szrj      /* As-needed libs specified on the command line (or linker script)
1193*a9fa9459Szrj	 take priority over libs found in search dirs.  */
1194*a9fa9459Szrj      if (global_found != NULL)
1195*a9fa9459Szrj	{
1196*a9fa9459Szrj	  nn.name = global_found->filename;
1197*a9fa9459Szrj	  if (gld${EMULATION_NAME}_try_needed (&nn, TRUE))
1198*a9fa9459Szrj	    continue;
1199*a9fa9459Szrj	}
1200*a9fa9459Szrj
1201*a9fa9459Szrj      /* We need to find this file and include the symbol table.  We
1202*a9fa9459Szrj	 want to search for the file in the same way that the dynamic
1203*a9fa9459Szrj	 linker will search.  That means that we want to use
1204*a9fa9459Szrj	 rpath_link, rpath, then the environment variable
1205*a9fa9459Szrj	 LD_LIBRARY_PATH (native only), then the DT_RPATH/DT_RUNPATH
1206*a9fa9459Szrj	 entries (native only), then the linker script LIB_SEARCH_DIRS.
1207*a9fa9459Szrj	 We do not search using the -L arguments.
1208*a9fa9459Szrj
1209*a9fa9459Szrj	 We search twice.  The first time, we skip objects which may
1210*a9fa9459Szrj	 introduce version mismatches.  The second time, we force
1211*a9fa9459Szrj	 their use.  See gld${EMULATION_NAME}_vercheck comment.  */
1212*a9fa9459Szrj      for (force = 0; force < 2; force++)
1213*a9fa9459Szrj	{
1214*a9fa9459Szrj	  size_t len;
1215*a9fa9459Szrj	  search_dirs_type *search;
1216*a9fa9459SzrjEOF
1217*a9fa9459Szrjif [ "x${NATIVE}" = xyes ] ; then
1218*a9fa9459Szrjfragment <<EOF
1219*a9fa9459Szrj	  const char *lib_path;
1220*a9fa9459SzrjEOF
1221*a9fa9459Szrjfi
1222*a9fa9459Szrjif [ "x${USE_LIBPATH}" = xyes ] ; then
1223*a9fa9459Szrjfragment <<EOF
1224*a9fa9459Szrj	  struct bfd_link_needed_list *rp;
1225*a9fa9459Szrj	  int found;
1226*a9fa9459SzrjEOF
1227*a9fa9459Szrjfi
1228*a9fa9459Szrjfragment <<EOF
1229*a9fa9459Szrj
1230*a9fa9459Szrj	  if (gld${EMULATION_NAME}_search_needed (command_line.rpath_link,
1231*a9fa9459Szrj						  &n, force))
1232*a9fa9459Szrj	    break;
1233*a9fa9459SzrjEOF
1234*a9fa9459Szrjif [ "x${USE_LIBPATH}" = xyes ] ; then
1235*a9fa9459Szrjfragment <<EOF
1236*a9fa9459Szrj	  if (gld${EMULATION_NAME}_search_needed (command_line.rpath,
1237*a9fa9459Szrj						  &n, force))
1238*a9fa9459Szrj	    break;
1239*a9fa9459SzrjEOF
1240*a9fa9459Szrjfi
1241*a9fa9459Szrjif [ "x${NATIVE}" = xyes ] ; then
1242*a9fa9459Szrjfragment <<EOF
1243*a9fa9459Szrj	  if (command_line.rpath_link == NULL
1244*a9fa9459Szrj	      && command_line.rpath == NULL)
1245*a9fa9459Szrj	    {
1246*a9fa9459Szrj	      lib_path = (const char *) getenv ("LD_RUN_PATH");
1247*a9fa9459Szrj	      if (gld${EMULATION_NAME}_search_needed (lib_path, &n,
1248*a9fa9459Szrj						      force))
1249*a9fa9459Szrj		break;
1250*a9fa9459Szrj	    }
1251*a9fa9459Szrj	  lib_path = (const char *) getenv ("LD_LIBRARY_PATH");
1252*a9fa9459Szrj	  if (gld${EMULATION_NAME}_search_needed (lib_path, &n, force))
1253*a9fa9459Szrj	    break;
1254*a9fa9459SzrjEOF
1255*a9fa9459Szrjfi
1256*a9fa9459Szrjif [ "x${USE_LIBPATH}" = xyes ] ; then
1257*a9fa9459Szrjfragment <<EOF
1258*a9fa9459Szrj	  found = 0;
1259*a9fa9459Szrj	  rp = bfd_elf_get_runpath_list (link_info.output_bfd, &link_info);
1260*a9fa9459Szrj	  for (; !found && rp != NULL; rp = rp->next)
1261*a9fa9459Szrj	    {
1262*a9fa9459Szrj	      const char *tmpname = rp->name;
1263*a9fa9459Szrj
1264*a9fa9459Szrj	      if (IS_ABSOLUTE_PATH (tmpname))
1265*a9fa9459Szrj		tmpname = gld${EMULATION_NAME}_add_sysroot (tmpname);
1266*a9fa9459Szrj	      found = (rp->by == l->by
1267*a9fa9459Szrj		       && gld${EMULATION_NAME}_search_needed (tmpname,
1268*a9fa9459Szrj							      &n,
1269*a9fa9459Szrj							      force));
1270*a9fa9459Szrj	      if (tmpname != rp->name)
1271*a9fa9459Szrj		free ((char *) tmpname);
1272*a9fa9459Szrj	    }
1273*a9fa9459Szrj	  if (found)
1274*a9fa9459Szrj	    break;
1275*a9fa9459Szrj
1276*a9fa9459SzrjEOF
1277*a9fa9459Szrjfi
1278*a9fa9459Szrjif [ "x${USE_LIBPATH}" = xyes ] ; then
1279*a9fa9459Szrj  case ${target} in
1280*a9fa9459Szrj    *-*-freebsd* | *-*-dragonfly*)
1281*a9fa9459Szrj      fragment <<EOF
1282*a9fa9459Szrj	  if (gld${EMULATION_NAME}_check_ld_elf_hints (l, force))
1283*a9fa9459Szrj	    break;
1284*a9fa9459SzrjEOF
1285*a9fa9459Szrj    # FreeBSD
1286*a9fa9459Szrj    ;;
1287*a9fa9459Szrj
1288*a9fa9459Szrj    *-*-linux-* | *-*-k*bsd*-* | *-*-gnu*)
1289*a9fa9459Szrj      fragment <<EOF
1290*a9fa9459Szrj	  if (gld${EMULATION_NAME}_check_ld_so_conf (l, force))
1291*a9fa9459Szrj	    break;
1292*a9fa9459Szrj
1293*a9fa9459SzrjEOF
1294*a9fa9459Szrj    # Linux
1295*a9fa9459Szrj    ;;
1296*a9fa9459Szrj  esac
1297*a9fa9459Szrjfi
1298*a9fa9459Szrjfragment <<EOF
1299*a9fa9459Szrj	  len = strlen (l->name);
1300*a9fa9459Szrj	  for (search = search_head; search != NULL; search = search->next)
1301*a9fa9459Szrj	    {
1302*a9fa9459Szrj	      char *filename;
1303*a9fa9459Szrj
1304*a9fa9459Szrj	      if (search->cmdline)
1305*a9fa9459Szrj		continue;
1306*a9fa9459Szrj	      filename = (char *) xmalloc (strlen (search->name) + len + 2);
1307*a9fa9459Szrj	      sprintf (filename, "%s/%s", search->name, l->name);
1308*a9fa9459Szrj	      nn.name = filename;
1309*a9fa9459Szrj	      if (gld${EMULATION_NAME}_try_needed (&nn, force))
1310*a9fa9459Szrj		break;
1311*a9fa9459Szrj	      free (filename);
1312*a9fa9459Szrj	    }
1313*a9fa9459Szrj	  if (search != NULL)
1314*a9fa9459Szrj	    break;
1315*a9fa9459SzrjEOF
1316*a9fa9459Szrjfragment <<EOF
1317*a9fa9459Szrj	}
1318*a9fa9459Szrj
1319*a9fa9459Szrj      if (force < 2)
1320*a9fa9459Szrj	continue;
1321*a9fa9459Szrj
1322*a9fa9459Szrj      einfo ("%P: warning: %s, needed by %B, not found (try using -rpath or -rpath-link)\n",
1323*a9fa9459Szrj	     l->name, l->by);
1324*a9fa9459Szrj    }
1325*a9fa9459Szrj
1326*a9fa9459Szrj  if (link_info.eh_frame_hdr_type == COMPACT_EH_HDR)
1327*a9fa9459Szrj    if (bfd_elf_parse_eh_frame_entries (NULL, &link_info) == FALSE)
1328*a9fa9459Szrj      einfo (_("%P%F: Failed to parse EH frame entries.\n"));
1329*a9fa9459Szrj}
1330*a9fa9459Szrj
1331*a9fa9459SzrjEOF
1332*a9fa9459Szrjfi
1333*a9fa9459Szrj
1334*a9fa9459Szrjfragment <<EOF
1335*a9fa9459Szrj
1336*a9fa9459Szrj/* Look through an expression for an assignment statement.  */
1337*a9fa9459Szrj
1338*a9fa9459Szrjstatic void
1339*a9fa9459Szrjgld${EMULATION_NAME}_find_exp_assignment (etree_type *exp)
1340*a9fa9459Szrj{
1341*a9fa9459Szrj  bfd_boolean provide = FALSE;
1342*a9fa9459Szrj
1343*a9fa9459Szrj  switch (exp->type.node_class)
1344*a9fa9459Szrj    {
1345*a9fa9459Szrj    case etree_provide:
1346*a9fa9459Szrj    case etree_provided:
1347*a9fa9459Szrj      provide = TRUE;
1348*a9fa9459Szrj      /* Fall thru */
1349*a9fa9459Szrj    case etree_assign:
1350*a9fa9459Szrj      /* We call record_link_assignment even if the symbol is defined.
1351*a9fa9459Szrj	 This is because if it is defined by a dynamic object, we
1352*a9fa9459Szrj	 actually want to use the value defined by the linker script,
1353*a9fa9459Szrj	 not the value from the dynamic object (because we are setting
1354*a9fa9459Szrj	 symbols like etext).  If the symbol is defined by a regular
1355*a9fa9459Szrj	 object, then, as it happens, calling record_link_assignment
1356*a9fa9459Szrj	 will do no harm.  */
1357*a9fa9459Szrj      if (strcmp (exp->assign.dst, ".") != 0)
1358*a9fa9459Szrj	{
1359*a9fa9459Szrj	  if (!bfd_elf_record_link_assignment (link_info.output_bfd,
1360*a9fa9459Szrj					       &link_info,
1361*a9fa9459Szrj					       exp->assign.dst, provide,
1362*a9fa9459Szrj					       exp->assign.hidden))
1363*a9fa9459Szrj	    einfo ("%P%F: failed to record assignment to %s: %E\n",
1364*a9fa9459Szrj		   exp->assign.dst);
1365*a9fa9459Szrj	}
1366*a9fa9459Szrj      gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src);
1367*a9fa9459Szrj      break;
1368*a9fa9459Szrj
1369*a9fa9459Szrj    case etree_binary:
1370*a9fa9459Szrj      gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs);
1371*a9fa9459Szrj      gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs);
1372*a9fa9459Szrj      break;
1373*a9fa9459Szrj
1374*a9fa9459Szrj    case etree_trinary:
1375*a9fa9459Szrj      gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.cond);
1376*a9fa9459Szrj      gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs);
1377*a9fa9459Szrj      gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs);
1378*a9fa9459Szrj      break;
1379*a9fa9459Szrj
1380*a9fa9459Szrj    case etree_unary:
1381*a9fa9459Szrj      gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child);
1382*a9fa9459Szrj      break;
1383*a9fa9459Szrj
1384*a9fa9459Szrj    default:
1385*a9fa9459Szrj      break;
1386*a9fa9459Szrj    }
1387*a9fa9459Szrj}
1388*a9fa9459Szrj
1389*a9fa9459Szrj
1390*a9fa9459Szrj/* This is called by the before_allocation routine via
1391*a9fa9459Szrj   lang_for_each_statement.  It locates any assignment statements, and
1392*a9fa9459Szrj   tells the ELF backend about them, in case they are assignments to
1393*a9fa9459Szrj   symbols which are referred to by dynamic objects.  */
1394*a9fa9459Szrj
1395*a9fa9459Szrjstatic void
1396*a9fa9459Szrjgld${EMULATION_NAME}_find_statement_assignment (lang_statement_union_type *s)
1397*a9fa9459Szrj{
1398*a9fa9459Szrj  if (s->header.type == lang_assignment_statement_enum)
1399*a9fa9459Szrj    gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp);
1400*a9fa9459Szrj}
1401*a9fa9459Szrj
1402*a9fa9459SzrjEOF
1403*a9fa9459Szrj
1404*a9fa9459Szrjif test x"$LDEMUL_BEFORE_ALLOCATION" != xgld"$EMULATION_NAME"_before_allocation; then
1405*a9fa9459Szrj  if test x"${ELF_INTERPRETER_NAME+set}" = xset; then
1406*a9fa9459Szrj    ELF_INTERPRETER_SET_DEFAULT="
1407*a9fa9459Szrj  if (sinterp != NULL)
1408*a9fa9459Szrj    {
1409*a9fa9459Szrj      sinterp->contents = (unsigned char *) ${ELF_INTERPRETER_NAME};
1410*a9fa9459Szrj      sinterp->size = strlen ((char *) sinterp->contents) + 1;
1411*a9fa9459Szrj    }
1412*a9fa9459Szrj
1413*a9fa9459Szrj"
1414*a9fa9459Szrj  else
1415*a9fa9459Szrj    ELF_INTERPRETER_SET_DEFAULT=
1416*a9fa9459Szrj  fi
1417*a9fa9459Szrjfragment <<EOF
1418*a9fa9459Szrj
1419*a9fa9459Szrj/* used by before_allocation and handle_option. */
1420*a9fa9459Szrjstatic void
1421*a9fa9459Szrjgld${EMULATION_NAME}_append_to_separated_string (char **to, char *op_arg)
1422*a9fa9459Szrj{
1423*a9fa9459Szrj  if (*to == NULL)
1424*a9fa9459Szrj    *to = xstrdup (op_arg);
1425*a9fa9459Szrj  else
1426*a9fa9459Szrj    {
1427*a9fa9459Szrj      size_t to_len = strlen (*to);
1428*a9fa9459Szrj      size_t op_arg_len = strlen (op_arg);
1429*a9fa9459Szrj      char *buf;
1430*a9fa9459Szrj      char *cp = *to;
1431*a9fa9459Szrj
1432*a9fa9459Szrj      /* First see whether OPTARG is already in the path.  */
1433*a9fa9459Szrj      do
1434*a9fa9459Szrj	{
1435*a9fa9459Szrj	  if (strncmp (op_arg, cp, op_arg_len) == 0
1436*a9fa9459Szrj	      && (cp[op_arg_len] == 0
1437*a9fa9459Szrj		  || cp[op_arg_len] == config.rpath_separator))
1438*a9fa9459Szrj	    /* We found it.  */
1439*a9fa9459Szrj	    break;
1440*a9fa9459Szrj
1441*a9fa9459Szrj	  /* Not yet found.  */
1442*a9fa9459Szrj	  cp = strchr (cp, config.rpath_separator);
1443*a9fa9459Szrj	  if (cp != NULL)
1444*a9fa9459Szrj	    ++cp;
1445*a9fa9459Szrj	}
1446*a9fa9459Szrj      while (cp != NULL);
1447*a9fa9459Szrj
1448*a9fa9459Szrj      if (cp == NULL)
1449*a9fa9459Szrj	{
1450*a9fa9459Szrj	  buf = xmalloc (to_len + op_arg_len + 2);
1451*a9fa9459Szrj	  sprintf (buf, "%s%c%s", *to,
1452*a9fa9459Szrj		   config.rpath_separator, op_arg);
1453*a9fa9459Szrj	  free (*to);
1454*a9fa9459Szrj	  *to = buf;
1455*a9fa9459Szrj	}
1456*a9fa9459Szrj    }
1457*a9fa9459Szrj}
1458*a9fa9459Szrj
1459*a9fa9459Szrj#if defined(__GNUC__) && GCC_VERSION < 4006
1460*a9fa9459Szrj  /* Work around a GCC uninitialized warning bug fixed in GCC 4.6.  */
1461*a9fa9459Szrjstatic struct bfd_link_hash_entry ehdr_start_empty;
1462*a9fa9459Szrj#endif
1463*a9fa9459Szrj
1464*a9fa9459Szrj/* This is called after the sections have been attached to output
1465*a9fa9459Szrj   sections, but before any sizes or addresses have been set.  */
1466*a9fa9459Szrj
1467*a9fa9459Szrjstatic void
1468*a9fa9459Szrjgld${EMULATION_NAME}_before_allocation (void)
1469*a9fa9459Szrj{
1470*a9fa9459Szrj  const char *rpath;
1471*a9fa9459Szrj  asection *sinterp;
1472*a9fa9459Szrj  bfd *abfd;
1473*a9fa9459Szrj  struct elf_link_hash_entry *ehdr_start = NULL;
1474*a9fa9459Szrj#if defined(__GNUC__) && GCC_VERSION < 4006
1475*a9fa9459Szrj  /* Work around a GCC uninitialized warning bug fixed in GCC 4.6.  */
1476*a9fa9459Szrj  struct bfd_link_hash_entry ehdr_start_save = ehdr_start_empty;
1477*a9fa9459Szrj#else
1478*a9fa9459Szrj  struct bfd_link_hash_entry ehdr_start_save;
1479*a9fa9459Szrj#endif
1480*a9fa9459Szrj
1481*a9fa9459Szrj  if (is_elf_hash_table (link_info.hash))
1482*a9fa9459Szrj    {
1483*a9fa9459Szrj      _bfd_elf_tls_setup (link_info.output_bfd, &link_info);
1484*a9fa9459Szrj
1485*a9fa9459Szrj      /* Make __ehdr_start hidden if it has been referenced, to
1486*a9fa9459Szrj	 prevent the symbol from being dynamic.  */
1487*a9fa9459Szrj      if (!bfd_link_relocatable (&link_info))
1488*a9fa9459Szrj       {
1489*a9fa9459Szrj         struct elf_link_hash_entry *h
1490*a9fa9459Szrj           = elf_link_hash_lookup (elf_hash_table (&link_info), "__ehdr_start",
1491*a9fa9459Szrj                                   FALSE, FALSE, TRUE);
1492*a9fa9459Szrj
1493*a9fa9459Szrj         /* Only adjust the export class if the symbol was referenced
1494*a9fa9459Szrj            and not defined, otherwise leave it alone.  */
1495*a9fa9459Szrj         if (h != NULL
1496*a9fa9459Szrj             && (h->root.type == bfd_link_hash_new
1497*a9fa9459Szrj                 || h->root.type == bfd_link_hash_undefined
1498*a9fa9459Szrj                 || h->root.type == bfd_link_hash_undefweak
1499*a9fa9459Szrj                 || h->root.type == bfd_link_hash_common))
1500*a9fa9459Szrj           {
1501*a9fa9459Szrj             _bfd_elf_link_hash_hide_symbol (&link_info, h, TRUE);
1502*a9fa9459Szrj             if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL)
1503*a9fa9459Szrj               h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
1504*a9fa9459Szrj	     /* Don't leave the symbol undefined.  Undefined hidden
1505*a9fa9459Szrj		symbols typically won't have dynamic relocations, but
1506*a9fa9459Szrj		we most likely will need dynamic relocations for
1507*a9fa9459Szrj		__ehdr_start if we are building a PIE or shared
1508*a9fa9459Szrj		library.  */
1509*a9fa9459Szrj	     ehdr_start = h;
1510*a9fa9459Szrj	     ehdr_start_save = h->root;
1511*a9fa9459Szrj	     h->root.type = bfd_link_hash_defined;
1512*a9fa9459Szrj	     h->root.u.def.section = bfd_abs_section_ptr;
1513*a9fa9459Szrj	     h->root.u.def.value = 0;
1514*a9fa9459Szrj           }
1515*a9fa9459Szrj       }
1516*a9fa9459Szrj
1517*a9fa9459Szrj      /* If we are going to make any variable assignments, we need to
1518*a9fa9459Szrj	 let the ELF backend know about them in case the variables are
1519*a9fa9459Szrj	 referred to by dynamic objects.  */
1520*a9fa9459Szrj      lang_for_each_statement (gld${EMULATION_NAME}_find_statement_assignment);
1521*a9fa9459Szrj    }
1522*a9fa9459Szrj
1523*a9fa9459Szrj  /* Let the ELF backend work out the sizes of any sections required
1524*a9fa9459Szrj     by dynamic linking.  */
1525*a9fa9459Szrj  rpath = command_line.rpath;
1526*a9fa9459Szrj  if (rpath == NULL)
1527*a9fa9459Szrj    rpath = (const char *) getenv ("LD_RUN_PATH");
1528*a9fa9459Szrj
1529*a9fa9459Szrj  for (abfd = link_info.input_bfds; abfd; abfd = abfd->link.next)
1530*a9fa9459Szrj    if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
1531*a9fa9459Szrj      {
1532*a9fa9459Szrj	const char *audit_libs = elf_dt_audit (abfd);
1533*a9fa9459Szrj
1534*a9fa9459Szrj	/* If the input bfd contains an audit entry, we need to add it as
1535*a9fa9459Szrj	   a dep audit entry.  */
1536*a9fa9459Szrj	if (audit_libs && *audit_libs != '\0')
1537*a9fa9459Szrj	  {
1538*a9fa9459Szrj	    char *cp = xstrdup (audit_libs);
1539*a9fa9459Szrj	    do
1540*a9fa9459Szrj	      {
1541*a9fa9459Szrj		int more = 0;
1542*a9fa9459Szrj		char *cp2 = strchr (cp, config.rpath_separator);
1543*a9fa9459Szrj
1544*a9fa9459Szrj		if (cp2)
1545*a9fa9459Szrj		  {
1546*a9fa9459Szrj		    *cp2 = '\0';
1547*a9fa9459Szrj		    more = 1;
1548*a9fa9459Szrj		  }
1549*a9fa9459Szrj
1550*a9fa9459Szrj		if (cp != NULL && *cp != '\0')
1551*a9fa9459Szrj		  gld${EMULATION_NAME}_append_to_separated_string (&depaudit, cp);
1552*a9fa9459Szrj
1553*a9fa9459Szrj		cp = more ? ++cp2 : NULL;
1554*a9fa9459Szrj	      }
1555*a9fa9459Szrj	    while (cp != NULL);
1556*a9fa9459Szrj	  }
1557*a9fa9459Szrj      }
1558*a9fa9459Szrj
1559*a9fa9459Szrj  if (! (bfd_elf_size_dynamic_sections
1560*a9fa9459Szrj	 (link_info.output_bfd, command_line.soname, rpath,
1561*a9fa9459Szrj	  command_line.filter_shlib, audit, depaudit,
1562*a9fa9459Szrj	  (const char * const *) command_line.auxiliary_filters,
1563*a9fa9459Szrj	  &link_info, &sinterp)))
1564*a9fa9459Szrj    einfo ("%P%F: failed to set dynamic section sizes: %E\n");
1565*a9fa9459Szrj
1566*a9fa9459Szrj${ELF_INTERPRETER_SET_DEFAULT}
1567*a9fa9459Szrj  /* Let the user override the dynamic linker we are using.  */
1568*a9fa9459Szrj  if (command_line.interpreter != NULL
1569*a9fa9459Szrj      && sinterp != NULL)
1570*a9fa9459Szrj    {
1571*a9fa9459Szrj      sinterp->contents = (bfd_byte *) command_line.interpreter;
1572*a9fa9459Szrj      sinterp->size = strlen (command_line.interpreter) + 1;
1573*a9fa9459Szrj    }
1574*a9fa9459Szrj
1575*a9fa9459Szrj  /* Look for any sections named .gnu.warning.  As a GNU extensions,
1576*a9fa9459Szrj     we treat such sections as containing warning messages.  We print
1577*a9fa9459Szrj     out the warning message, and then zero out the section size so
1578*a9fa9459Szrj     that it does not get copied into the output file.  */
1579*a9fa9459Szrj
1580*a9fa9459Szrj  {
1581*a9fa9459Szrj    LANG_FOR_EACH_INPUT_STATEMENT (is)
1582*a9fa9459Szrj      {
1583*a9fa9459Szrj	asection *s;
1584*a9fa9459Szrj	bfd_size_type sz;
1585*a9fa9459Szrj	char *msg;
1586*a9fa9459Szrj
1587*a9fa9459Szrj	if (is->flags.just_syms)
1588*a9fa9459Szrj	  continue;
1589*a9fa9459Szrj
1590*a9fa9459Szrj	s = bfd_get_section_by_name (is->the_bfd, ".gnu.warning");
1591*a9fa9459Szrj	if (s == NULL)
1592*a9fa9459Szrj	  continue;
1593*a9fa9459Szrj
1594*a9fa9459Szrj	sz = s->size;
1595*a9fa9459Szrj	msg = (char *) xmalloc ((size_t) (sz + 1));
1596*a9fa9459Szrj	if (! bfd_get_section_contents (is->the_bfd, s,	msg,
1597*a9fa9459Szrj					(file_ptr) 0, sz))
1598*a9fa9459Szrj	  einfo ("%F%B: Can't read contents of section .gnu.warning: %E\n",
1599*a9fa9459Szrj		 is->the_bfd);
1600*a9fa9459Szrj	msg[sz] = '\0';
1601*a9fa9459Szrj	(*link_info.callbacks->warning) (&link_info, msg,
1602*a9fa9459Szrj					 (const char *) NULL, is->the_bfd,
1603*a9fa9459Szrj					 (asection *) NULL, (bfd_vma) 0);
1604*a9fa9459Szrj	free (msg);
1605*a9fa9459Szrj
1606*a9fa9459Szrj	/* Clobber the section size, so that we don't waste space
1607*a9fa9459Szrj	   copying the warning into the output file.  If we've already
1608*a9fa9459Szrj	   sized the output section, adjust its size.  The adjustment
1609*a9fa9459Szrj	   is on rawsize because targets that size sections early will
1610*a9fa9459Szrj	   have called lang_reset_memory_regions after sizing.  */
1611*a9fa9459Szrj	if (s->output_section != NULL
1612*a9fa9459Szrj	    && s->output_section->rawsize >= s->size)
1613*a9fa9459Szrj	  s->output_section->rawsize -= s->size;
1614*a9fa9459Szrj
1615*a9fa9459Szrj	s->size = 0;
1616*a9fa9459Szrj
1617*a9fa9459Szrj	/* Also set SEC_EXCLUDE, so that local symbols defined in the
1618*a9fa9459Szrj	   warning section don't get copied to the output.  */
1619*a9fa9459Szrj	s->flags |= SEC_EXCLUDE | SEC_KEEP;
1620*a9fa9459Szrj      }
1621*a9fa9459Szrj  }
1622*a9fa9459Szrj
1623*a9fa9459Szrj  before_allocation_default ();
1624*a9fa9459Szrj
1625*a9fa9459Szrj  if (!bfd_elf_size_dynsym_hash_dynstr (link_info.output_bfd, &link_info))
1626*a9fa9459Szrj    einfo ("%P%F: failed to set dynamic section sizes: %E\n");
1627*a9fa9459Szrj
1628*a9fa9459Szrj  if (ehdr_start != NULL)
1629*a9fa9459Szrj    {
1630*a9fa9459Szrj      /* If we twiddled __ehdr_start to defined earlier, put it back
1631*a9fa9459Szrj	 as it was.  */
1632*a9fa9459Szrj      ehdr_start->root.type = ehdr_start_save.type;
1633*a9fa9459Szrj      ehdr_start->root.u = ehdr_start_save.u;
1634*a9fa9459Szrj    }
1635*a9fa9459Szrj}
1636*a9fa9459Szrj
1637*a9fa9459SzrjEOF
1638*a9fa9459Szrjfi
1639*a9fa9459Szrj
1640*a9fa9459Szrjif test x"$LDEMUL_OPEN_DYNAMIC_ARCHIVE" != xgld"$EMULATION_NAME"_open_dynamic_archive; then
1641*a9fa9459Szrjfragment <<EOF
1642*a9fa9459Szrj
1643*a9fa9459Szrj/* Try to open a dynamic archive.  This is where we know that ELF
1644*a9fa9459Szrj   dynamic libraries have an extension of .so (or .sl on oddball systems
1645*a9fa9459Szrj   like hpux).  */
1646*a9fa9459Szrj
1647*a9fa9459Szrjstatic bfd_boolean
1648*a9fa9459Szrjgld${EMULATION_NAME}_open_dynamic_archive
1649*a9fa9459Szrj  (const char *arch, search_dirs_type *search, lang_input_statement_type *entry)
1650*a9fa9459Szrj{
1651*a9fa9459Szrj  const char *filename;
1652*a9fa9459Szrj  char *string;
1653*a9fa9459Szrj  size_t len;
1654*a9fa9459Szrj  bfd_boolean opened = FALSE;
1655*a9fa9459Szrj
1656*a9fa9459Szrj  if (! entry->flags.maybe_archive)
1657*a9fa9459Szrj    return FALSE;
1658*a9fa9459Szrj
1659*a9fa9459Szrj  filename = entry->filename;
1660*a9fa9459Szrj  len = strlen (search->name) + strlen (filename);
1661*a9fa9459Szrj  if (entry->flags.full_name_provided)
1662*a9fa9459Szrj    {
1663*a9fa9459Szrj      len += sizeof "/";
1664*a9fa9459Szrj      string = (char *) xmalloc (len);
1665*a9fa9459Szrj      sprintf (string, "%s/%s", search->name, filename);
1666*a9fa9459Szrj    }
1667*a9fa9459Szrj  else
1668*a9fa9459Szrj    {
1669*a9fa9459Szrj      size_t xlen = 0;
1670*a9fa9459Szrj
1671*a9fa9459Szrj      len += strlen (arch) + sizeof "/lib.so";
1672*a9fa9459Szrj#ifdef EXTRA_SHLIB_EXTENSION
1673*a9fa9459Szrj      xlen = (strlen (EXTRA_SHLIB_EXTENSION) > 3
1674*a9fa9459Szrj	      ? strlen (EXTRA_SHLIB_EXTENSION) - 3
1675*a9fa9459Szrj	      : 0);
1676*a9fa9459Szrj#endif
1677*a9fa9459Szrj      string = (char *) xmalloc (len + xlen);
1678*a9fa9459Szrj      sprintf (string, "%s/lib%s%s.so", search->name, filename, arch);
1679*a9fa9459Szrj#ifdef EXTRA_SHLIB_EXTENSION
1680*a9fa9459Szrj      /* Try the .so extension first.  If that fails build a new filename
1681*a9fa9459Szrj	 using EXTRA_SHLIB_EXTENSION.  */
1682*a9fa9459Szrj      opened = ldfile_try_open_bfd (string, entry);
1683*a9fa9459Szrj      if (!opened)
1684*a9fa9459Szrj	strcpy (string + len - 4, EXTRA_SHLIB_EXTENSION);
1685*a9fa9459Szrj#endif
1686*a9fa9459Szrj    }
1687*a9fa9459Szrj
1688*a9fa9459Szrj  if (!opened && !ldfile_try_open_bfd (string, entry))
1689*a9fa9459Szrj    {
1690*a9fa9459Szrj      free (string);
1691*a9fa9459Szrj      return FALSE;
1692*a9fa9459Szrj    }
1693*a9fa9459Szrj
1694*a9fa9459Szrj  entry->filename = string;
1695*a9fa9459Szrj
1696*a9fa9459Szrj  /* We have found a dynamic object to include in the link.  The ELF
1697*a9fa9459Szrj     backend linker will create a DT_NEEDED entry in the .dynamic
1698*a9fa9459Szrj     section naming this file.  If this file includes a DT_SONAME
1699*a9fa9459Szrj     entry, it will be used.  Otherwise, the ELF linker will just use
1700*a9fa9459Szrj     the name of the file.  For an archive found by searching, like
1701*a9fa9459Szrj     this one, the DT_NEEDED entry should consist of just the name of
1702*a9fa9459Szrj     the file, without the path information used to find it.  Note
1703*a9fa9459Szrj     that we only need to do this if we have a dynamic object; an
1704*a9fa9459Szrj     archive will never be referenced by a DT_NEEDED entry.
1705*a9fa9459Szrj
1706*a9fa9459Szrj     FIXME: This approach--using bfd_elf_set_dt_needed_name--is not
1707*a9fa9459Szrj     very pretty.  I haven't been able to think of anything that is
1708*a9fa9459Szrj     pretty, though.  */
1709*a9fa9459Szrj  if (bfd_check_format (entry->the_bfd, bfd_object)
1710*a9fa9459Szrj      && (entry->the_bfd->flags & DYNAMIC) != 0)
1711*a9fa9459Szrj    {
1712*a9fa9459Szrj      ASSERT (entry->flags.maybe_archive && entry->flags.search_dirs);
1713*a9fa9459Szrj
1714*a9fa9459Szrj      /* Rather than duplicating the logic above.  Just use the
1715*a9fa9459Szrj	 filename we recorded earlier.  */
1716*a9fa9459Szrj
1717*a9fa9459Szrj      if (!entry->flags.full_name_provided)
1718*a9fa9459Szrj        filename = lbasename (entry->filename);
1719*a9fa9459Szrj      bfd_elf_set_dt_needed_name (entry->the_bfd, filename);
1720*a9fa9459Szrj    }
1721*a9fa9459Szrj
1722*a9fa9459Szrj  return TRUE;
1723*a9fa9459Szrj}
1724*a9fa9459Szrj
1725*a9fa9459SzrjEOF
1726*a9fa9459Szrjfi
1727*a9fa9459Szrj
1728*a9fa9459Szrjif test x"$LDEMUL_PLACE_ORPHAN" != xgld"$EMULATION_NAME"_place_orphan; then
1729*a9fa9459Szrjfragment <<EOF
1730*a9fa9459Szrj
1731*a9fa9459Szrj/* A variant of lang_output_section_find used by place_orphan.  */
1732*a9fa9459Szrj
1733*a9fa9459Szrjstatic lang_output_section_statement_type *
1734*a9fa9459Szrjoutput_rel_find (asection *sec, int isdyn)
1735*a9fa9459Szrj{
1736*a9fa9459Szrj  lang_output_section_statement_type *lookup;
1737*a9fa9459Szrj  lang_output_section_statement_type *last = NULL;
1738*a9fa9459Szrj  lang_output_section_statement_type *last_alloc = NULL;
1739*a9fa9459Szrj  lang_output_section_statement_type *last_ro_alloc = NULL;
1740*a9fa9459Szrj  lang_output_section_statement_type *last_rel = NULL;
1741*a9fa9459Szrj  lang_output_section_statement_type *last_rel_alloc = NULL;
1742*a9fa9459Szrj  int rela = sec->name[4] == 'a';
1743*a9fa9459Szrj
1744*a9fa9459Szrj  for (lookup = &lang_output_section_statement.head->output_section_statement;
1745*a9fa9459Szrj       lookup != NULL;
1746*a9fa9459Szrj       lookup = lookup->next)
1747*a9fa9459Szrj    {
1748*a9fa9459Szrj      if (lookup->constraint >= 0
1749*a9fa9459Szrj	  && CONST_STRNEQ (lookup->name, ".rel"))
1750*a9fa9459Szrj	{
1751*a9fa9459Szrj	  int lookrela = lookup->name[4] == 'a';
1752*a9fa9459Szrj
1753*a9fa9459Szrj	  /* .rel.dyn must come before all other reloc sections, to suit
1754*a9fa9459Szrj	     GNU ld.so.  */
1755*a9fa9459Szrj	  if (isdyn)
1756*a9fa9459Szrj	    break;
1757*a9fa9459Szrj
1758*a9fa9459Szrj	  /* Don't place after .rel.plt as doing so results in wrong
1759*a9fa9459Szrj	     dynamic tags.  */
1760*a9fa9459Szrj	  if (strcmp (".plt", lookup->name + 4 + lookrela) == 0)
1761*a9fa9459Szrj	    break;
1762*a9fa9459Szrj
1763*a9fa9459Szrj	  if (rela == lookrela || last_rel == NULL)
1764*a9fa9459Szrj	    last_rel = lookup;
1765*a9fa9459Szrj	  if ((rela == lookrela || last_rel_alloc == NULL)
1766*a9fa9459Szrj	      && lookup->bfd_section != NULL
1767*a9fa9459Szrj	      && (lookup->bfd_section->flags & SEC_ALLOC) != 0)
1768*a9fa9459Szrj	    last_rel_alloc = lookup;
1769*a9fa9459Szrj	}
1770*a9fa9459Szrj
1771*a9fa9459Szrj      last = lookup;
1772*a9fa9459Szrj      if (lookup->bfd_section != NULL
1773*a9fa9459Szrj	  && (lookup->bfd_section->flags & SEC_ALLOC) != 0)
1774*a9fa9459Szrj	{
1775*a9fa9459Szrj	  last_alloc = lookup;
1776*a9fa9459Szrj	  if ((lookup->bfd_section->flags & SEC_READONLY) != 0)
1777*a9fa9459Szrj	    last_ro_alloc = lookup;
1778*a9fa9459Szrj	}
1779*a9fa9459Szrj    }
1780*a9fa9459Szrj
1781*a9fa9459Szrj  if (last_rel_alloc)
1782*a9fa9459Szrj    return last_rel_alloc;
1783*a9fa9459Szrj
1784*a9fa9459Szrj  if (last_rel)
1785*a9fa9459Szrj    return last_rel;
1786*a9fa9459Szrj
1787*a9fa9459Szrj  if (last_ro_alloc)
1788*a9fa9459Szrj    return last_ro_alloc;
1789*a9fa9459Szrj
1790*a9fa9459Szrj  if (last_alloc)
1791*a9fa9459Szrj    return last_alloc;
1792*a9fa9459Szrj
1793*a9fa9459Szrj  return last;
1794*a9fa9459Szrj}
1795*a9fa9459Szrj
1796*a9fa9459Szrj/* Place an orphan section.  We use this to put random SHF_ALLOC
1797*a9fa9459Szrj   sections in the right segment.  */
1798*a9fa9459Szrj
1799*a9fa9459Szrjstatic lang_output_section_statement_type *
1800*a9fa9459Szrjgld${EMULATION_NAME}_place_orphan (asection *s,
1801*a9fa9459Szrj				   const char *secname,
1802*a9fa9459Szrj				   int constraint)
1803*a9fa9459Szrj{
1804*a9fa9459Szrj  static struct orphan_save hold[] =
1805*a9fa9459Szrj    {
1806*a9fa9459Szrj      { ".text",
1807*a9fa9459Szrj	SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE,
1808*a9fa9459Szrj	0, 0, 0, 0 },
1809*a9fa9459Szrj      { ".rodata",
1810*a9fa9459Szrj	SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA,
1811*a9fa9459Szrj	0, 0, 0, 0 },
1812*a9fa9459Szrj      { ".tdata",
1813*a9fa9459Szrj	SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_THREAD_LOCAL,
1814*a9fa9459Szrj	0, 0, 0, 0 },
1815*a9fa9459Szrj      { ".data",
1816*a9fa9459Szrj	SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_DATA,
1817*a9fa9459Szrj	0, 0, 0, 0 },
1818*a9fa9459Szrj      { ".bss",
1819*a9fa9459Szrj	SEC_ALLOC,
1820*a9fa9459Szrj	0, 0, 0, 0 },
1821*a9fa9459Szrj      { 0,
1822*a9fa9459Szrj	SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA,
1823*a9fa9459Szrj	0, 0, 0, 0 },
1824*a9fa9459Szrj      { ".interp",
1825*a9fa9459Szrj	SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA,
1826*a9fa9459Szrj	0, 0, 0, 0 },
1827*a9fa9459Szrj      { ".sdata",
1828*a9fa9459Szrj	SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_SMALL_DATA,
1829*a9fa9459Szrj	0, 0, 0, 0 },
1830*a9fa9459Szrj      { ".comment",
1831*a9fa9459Szrj	SEC_HAS_CONTENTS,
1832*a9fa9459Szrj	0, 0, 0, 0 },
1833*a9fa9459Szrj    };
1834*a9fa9459Szrj  enum orphan_save_index
1835*a9fa9459Szrj    {
1836*a9fa9459Szrj      orphan_text = 0,
1837*a9fa9459Szrj      orphan_rodata,
1838*a9fa9459Szrj      orphan_tdata,
1839*a9fa9459Szrj      orphan_data,
1840*a9fa9459Szrj      orphan_bss,
1841*a9fa9459Szrj      orphan_rel,
1842*a9fa9459Szrj      orphan_interp,
1843*a9fa9459Szrj      orphan_sdata,
1844*a9fa9459Szrj      orphan_nonalloc
1845*a9fa9459Szrj    };
1846*a9fa9459Szrj  static int orphan_init_done = 0;
1847*a9fa9459Szrj  struct orphan_save *place;
1848*a9fa9459Szrj  lang_output_section_statement_type *after;
1849*a9fa9459Szrj  lang_output_section_statement_type *os;
1850*a9fa9459Szrj  lang_output_section_statement_type *match_by_name = NULL;
1851*a9fa9459Szrj  int isdyn = 0;
1852*a9fa9459Szrj  int iself = s->owner->xvec->flavour == bfd_target_elf_flavour;
1853*a9fa9459Szrj  unsigned int sh_type = iself ? elf_section_type (s) : SHT_NULL;
1854*a9fa9459Szrj  flagword flags;
1855*a9fa9459Szrj  asection *nexts;
1856*a9fa9459Szrj
1857*a9fa9459Szrj  if (!bfd_link_relocatable (&link_info)
1858*a9fa9459Szrj      && link_info.combreloc
1859*a9fa9459Szrj      && (s->flags & SEC_ALLOC))
1860*a9fa9459Szrj    {
1861*a9fa9459Szrj      if (iself)
1862*a9fa9459Szrj	switch (sh_type)
1863*a9fa9459Szrj	  {
1864*a9fa9459Szrj	  case SHT_RELA:
1865*a9fa9459Szrj	    secname = ".rela.dyn";
1866*a9fa9459Szrj	    isdyn = 1;
1867*a9fa9459Szrj	    break;
1868*a9fa9459Szrj	  case SHT_REL:
1869*a9fa9459Szrj	    secname = ".rel.dyn";
1870*a9fa9459Szrj	    isdyn = 1;
1871*a9fa9459Szrj	    break;
1872*a9fa9459Szrj	  default:
1873*a9fa9459Szrj	    break;
1874*a9fa9459Szrj	  }
1875*a9fa9459Szrj      else if (CONST_STRNEQ (secname, ".rel"))
1876*a9fa9459Szrj	{
1877*a9fa9459Szrj	  secname = secname[4] == 'a' ? ".rela.dyn" : ".rel.dyn";
1878*a9fa9459Szrj	  isdyn = 1;
1879*a9fa9459Szrj	}
1880*a9fa9459Szrj    }
1881*a9fa9459Szrj
1882*a9fa9459Szrj  /* Look through the script to see where to place this section.  */
1883*a9fa9459Szrj  if (constraint == 0)
1884*a9fa9459Szrj    for (os = lang_output_section_find (secname);
1885*a9fa9459Szrj	 os != NULL;
1886*a9fa9459Szrj	 os = next_matching_output_section_statement (os, 0))
1887*a9fa9459Szrj      {
1888*a9fa9459Szrj	/* If we don't match an existing output section, tell
1889*a9fa9459Szrj	   lang_insert_orphan to create a new output section.  */
1890*a9fa9459Szrj	constraint = SPECIAL;
1891*a9fa9459Szrj
1892*a9fa9459Szrj	if (os->bfd_section != NULL
1893*a9fa9459Szrj	    && (os->bfd_section->flags == 0
1894*a9fa9459Szrj		|| (((s->flags ^ os->bfd_section->flags)
1895*a9fa9459Szrj		     & (SEC_LOAD | SEC_ALLOC)) == 0
1896*a9fa9459Szrj		    && _bfd_elf_match_sections_by_type (link_info.output_bfd,
1897*a9fa9459Szrj							os->bfd_section,
1898*a9fa9459Szrj							s->owner, s))))
1899*a9fa9459Szrj	  {
1900*a9fa9459Szrj	    /* We already have an output section statement with this
1901*a9fa9459Szrj	       name, and its bfd section has compatible flags.
1902*a9fa9459Szrj	       If the section already exists but does not have any flags
1903*a9fa9459Szrj	       set, then it has been created by the linker, probably as a
1904*a9fa9459Szrj	       result of a --section-start command line switch.  */
1905*a9fa9459Szrj	    lang_add_section (&os->children, s, NULL, os);
1906*a9fa9459Szrj	    return os;
1907*a9fa9459Szrj	  }
1908*a9fa9459Szrj
1909*a9fa9459Szrj	/* Save unused output sections in case we can match them
1910*a9fa9459Szrj	   against orphans later.  */
1911*a9fa9459Szrj	if (os->bfd_section == NULL)
1912*a9fa9459Szrj	  match_by_name = os;
1913*a9fa9459Szrj      }
1914*a9fa9459Szrj
1915*a9fa9459Szrj  /* If we didn't match an active output section, see if we matched an
1916*a9fa9459Szrj     unused one and use that.  */
1917*a9fa9459Szrj  if (match_by_name)
1918*a9fa9459Szrj    {
1919*a9fa9459Szrj      lang_add_section (&match_by_name->children, s, NULL, match_by_name);
1920*a9fa9459Szrj      return match_by_name;
1921*a9fa9459Szrj    }
1922*a9fa9459Szrj
1923*a9fa9459Szrj  if (!orphan_init_done)
1924*a9fa9459Szrj    {
1925*a9fa9459Szrj      struct orphan_save *ho;
1926*a9fa9459Szrj
1927*a9fa9459Szrj      for (ho = hold; ho < hold + sizeof (hold) / sizeof (hold[0]); ++ho)
1928*a9fa9459Szrj	if (ho->name != NULL)
1929*a9fa9459Szrj	  {
1930*a9fa9459Szrj	    ho->os = lang_output_section_find (ho->name);
1931*a9fa9459Szrj	    if (ho->os != NULL && ho->os->flags == 0)
1932*a9fa9459Szrj	      ho->os->flags = ho->flags;
1933*a9fa9459Szrj	  }
1934*a9fa9459Szrj      orphan_init_done = 1;
1935*a9fa9459Szrj    }
1936*a9fa9459Szrj
1937*a9fa9459Szrj  /* If this is a final link, then always put .gnu.warning.SYMBOL
1938*a9fa9459Szrj     sections into the .text section to get them out of the way.  */
1939*a9fa9459Szrj  if (bfd_link_executable (&link_info)
1940*a9fa9459Szrj      && CONST_STRNEQ (s->name, ".gnu.warning.")
1941*a9fa9459Szrj      && hold[orphan_text].os != NULL)
1942*a9fa9459Szrj    {
1943*a9fa9459Szrj      os = hold[orphan_text].os;
1944*a9fa9459Szrj      lang_add_section (&os->children, s, NULL, os);
1945*a9fa9459Szrj      return os;
1946*a9fa9459Szrj    }
1947*a9fa9459Szrj
1948*a9fa9459Szrj  flags = s->flags;
1949*a9fa9459Szrj  if (!bfd_link_relocatable (&link_info))
1950*a9fa9459Szrj    {
1951*a9fa9459Szrj      nexts = s;
1952*a9fa9459Szrj      while ((nexts = bfd_get_next_section_by_name (nexts->owner, nexts))
1953*a9fa9459Szrj	     != NULL)
1954*a9fa9459Szrj	if (nexts->output_section == NULL
1955*a9fa9459Szrj	    && (nexts->flags & SEC_EXCLUDE) == 0
1956*a9fa9459Szrj	    && ((nexts->flags ^ flags) & (SEC_LOAD | SEC_ALLOC)) == 0
1957*a9fa9459Szrj	    && (nexts->owner->flags & DYNAMIC) == 0
1958*a9fa9459Szrj	    && nexts->owner->usrdata != NULL
1959*a9fa9459Szrj	    && !(((lang_input_statement_type *) nexts->owner->usrdata)
1960*a9fa9459Szrj		 ->flags.just_syms)
1961*a9fa9459Szrj	    && _bfd_elf_match_sections_by_type (nexts->owner, nexts,
1962*a9fa9459Szrj						s->owner, s))
1963*a9fa9459Szrj	  flags = (((flags ^ SEC_READONLY)
1964*a9fa9459Szrj		    | (nexts->flags ^ SEC_READONLY))
1965*a9fa9459Szrj		   ^ SEC_READONLY);
1966*a9fa9459Szrj    }
1967*a9fa9459Szrj
1968*a9fa9459Szrj  /* Decide which segment the section should go in based on the
1969*a9fa9459Szrj     section name and section flags.  We put loadable .note sections
1970*a9fa9459Szrj     right after the .interp section, so that the PT_NOTE segment is
1971*a9fa9459Szrj     stored right after the program headers where the OS can read it
1972*a9fa9459Szrj     in the first page.  */
1973*a9fa9459Szrj
1974*a9fa9459Szrj  place = NULL;
1975*a9fa9459Szrj  if ((flags & (SEC_ALLOC | SEC_DEBUGGING)) == 0)
1976*a9fa9459Szrj    place = &hold[orphan_nonalloc];
1977*a9fa9459Szrj  else if ((flags & SEC_ALLOC) == 0)
1978*a9fa9459Szrj    ;
1979*a9fa9459Szrj  else if ((flags & SEC_LOAD) != 0
1980*a9fa9459Szrj	   && ((iself && sh_type == SHT_NOTE)
1981*a9fa9459Szrj	       || (!iself && CONST_STRNEQ (secname, ".note"))))
1982*a9fa9459Szrj    place = &hold[orphan_interp];
1983*a9fa9459Szrj  else if ((flags & (SEC_LOAD | SEC_HAS_CONTENTS | SEC_THREAD_LOCAL)) == 0)
1984*a9fa9459Szrj    place = &hold[orphan_bss];
1985*a9fa9459Szrj  else if ((flags & SEC_SMALL_DATA) != 0)
1986*a9fa9459Szrj    place = &hold[orphan_sdata];
1987*a9fa9459Szrj  else if ((flags & SEC_THREAD_LOCAL) != 0)
1988*a9fa9459Szrj    place = &hold[orphan_tdata];
1989*a9fa9459Szrj  else if ((flags & SEC_READONLY) == 0)
1990*a9fa9459Szrj    place = &hold[orphan_data];
1991*a9fa9459Szrj  else if (((iself && (sh_type == SHT_RELA || sh_type == SHT_REL))
1992*a9fa9459Szrj	    || (!iself && CONST_STRNEQ (secname, ".rel")))
1993*a9fa9459Szrj	   && (flags & SEC_LOAD) != 0)
1994*a9fa9459Szrj    place = &hold[orphan_rel];
1995*a9fa9459Szrj  else if ((flags & SEC_CODE) == 0)
1996*a9fa9459Szrj    place = &hold[orphan_rodata];
1997*a9fa9459Szrj  else
1998*a9fa9459Szrj    place = &hold[orphan_text];
1999*a9fa9459Szrj
2000*a9fa9459Szrj  after = NULL;
2001*a9fa9459Szrj  if (place != NULL)
2002*a9fa9459Szrj    {
2003*a9fa9459Szrj      if (place->os == NULL)
2004*a9fa9459Szrj	{
2005*a9fa9459Szrj	  if (place->name != NULL)
2006*a9fa9459Szrj	    place->os = lang_output_section_find (place->name);
2007*a9fa9459Szrj	  else
2008*a9fa9459Szrj	    place->os = output_rel_find (s, isdyn);
2009*a9fa9459Szrj	}
2010*a9fa9459Szrj      after = place->os;
2011*a9fa9459Szrj      if (after == NULL)
2012*a9fa9459Szrj	after
2013*a9fa9459Szrj	  = lang_output_section_find_by_flags (s, flags, &place->os,
2014*a9fa9459Szrj					       _bfd_elf_match_sections_by_type);
2015*a9fa9459Szrj      if (after == NULL)
2016*a9fa9459Szrj	/* *ABS* is always the first output section statement.  */
2017*a9fa9459Szrj	after = &lang_output_section_statement.head->output_section_statement;
2018*a9fa9459Szrj    }
2019*a9fa9459Szrj
2020*a9fa9459Szrj  return lang_insert_orphan (s, secname, constraint, after, place, NULL, NULL);
2021*a9fa9459Szrj}
2022*a9fa9459SzrjEOF
2023*a9fa9459Szrjfi
2024*a9fa9459Szrj
2025*a9fa9459Szrjif test x"$LDEMUL_AFTER_ALLOCATION" != xgld"$EMULATION_NAME"_after_allocation; then
2026*a9fa9459Szrjfragment <<EOF
2027*a9fa9459Szrj
2028*a9fa9459Szrjstatic void
2029*a9fa9459Szrjgld${EMULATION_NAME}_after_allocation (void)
2030*a9fa9459Szrj{
2031*a9fa9459Szrj  int need_layout = bfd_elf_discard_info (link_info.output_bfd, &link_info);
2032*a9fa9459Szrj
2033*a9fa9459Szrj  if (need_layout < 0)
2034*a9fa9459Szrj    einfo ("%X%P: .eh_frame/.stab edit: %E\n");
2035*a9fa9459Szrj  else
2036*a9fa9459Szrj    gld${EMULATION_NAME}_map_segments (need_layout);
2037*a9fa9459Szrj}
2038*a9fa9459SzrjEOF
2039*a9fa9459Szrjfi
2040*a9fa9459Szrj
2041*a9fa9459Szrjif test x"$LDEMUL_GET_SCRIPT" != xgld"$EMULATION_NAME"_get_script; then
2042*a9fa9459Szrjfragment <<EOF
2043*a9fa9459Szrj
2044*a9fa9459Szrjstatic char *
2045*a9fa9459Szrjgld${EMULATION_NAME}_get_script (int *isfile)
2046*a9fa9459SzrjEOF
2047*a9fa9459Szrj
2048*a9fa9459Szrjif test x"$COMPILE_IN" = xyes
2049*a9fa9459Szrjthen
2050*a9fa9459Szrj# Scripts compiled in.
2051*a9fa9459Szrj
2052*a9fa9459Szrj# sed commands to quote an ld script as a C string.
2053*a9fa9459Szrjsc="-f stringify.sed"
2054*a9fa9459Szrj
2055*a9fa9459Szrjfragment <<EOF
2056*a9fa9459Szrj{
2057*a9fa9459Szrj  *isfile = 0;
2058*a9fa9459Szrj
2059*a9fa9459Szrj  if (bfd_link_relocatable (&link_info) && config.build_constructors)
2060*a9fa9459Szrj    return
2061*a9fa9459SzrjEOF
2062*a9fa9459Szrjsed $sc ldscripts/${EMULATION_NAME}.xu			>> e${EMULATION_NAME}.c
2063*a9fa9459Szrjecho '  ; else if (bfd_link_relocatable (&link_info)) return' >> e${EMULATION_NAME}.c
2064*a9fa9459Szrjsed $sc ldscripts/${EMULATION_NAME}.xr			>> e${EMULATION_NAME}.c
2065*a9fa9459Szrjecho '  ; else if (!config.text_read_only) return'	>> e${EMULATION_NAME}.c
2066*a9fa9459Szrjsed $sc ldscripts/${EMULATION_NAME}.xbn			>> e${EMULATION_NAME}.c
2067*a9fa9459Szrjif cmp -s ldscripts/${EMULATION_NAME}.x ldscripts/${EMULATION_NAME}.xn; then : ; else
2068*a9fa9459Szrjecho '  ; else if (!config.magic_demand_paged) return'	>> e${EMULATION_NAME}.c
2069*a9fa9459Szrjsed $sc ldscripts/${EMULATION_NAME}.xn			>> e${EMULATION_NAME}.c
2070*a9fa9459Szrjfi
2071*a9fa9459Szrjif test -n "$GENERATE_PIE_SCRIPT" ; then
2072*a9fa9459Szrjif test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
2073*a9fa9459Szrjecho '  ; else if (bfd_link_pie (&link_info)'		>> e${EMULATION_NAME}.c
2074*a9fa9459Szrjecho '             && link_info.combreloc'		>> e${EMULATION_NAME}.c
2075*a9fa9459Szrjecho '             && link_info.relro'			>> e${EMULATION_NAME}.c
2076*a9fa9459Szrjecho '             && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
2077*a9fa9459Szrjsed $sc ldscripts/${EMULATION_NAME}.xdw			>> e${EMULATION_NAME}.c
2078*a9fa9459Szrjecho '  ; else if (bfd_link_pie (&link_info)'		>> e${EMULATION_NAME}.c
2079*a9fa9459Szrjecho '             && link_info.combreloc) return'	>> e${EMULATION_NAME}.c
2080*a9fa9459Szrjsed $sc ldscripts/${EMULATION_NAME}.xdc			>> e${EMULATION_NAME}.c
2081*a9fa9459Szrjfi
2082*a9fa9459Szrjecho '  ; else if (bfd_link_pie (&link_info)) return'	>> e${EMULATION_NAME}.c
2083*a9fa9459Szrjsed $sc ldscripts/${EMULATION_NAME}.xd			>> e${EMULATION_NAME}.c
2084*a9fa9459Szrjfi
2085*a9fa9459Szrjif test -n "$GENERATE_SHLIB_SCRIPT" ; then
2086*a9fa9459Szrjif test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
2087*a9fa9459Szrjecho '  ; else if (bfd_link_dll (&link_info) && link_info.combreloc' >> e${EMULATION_NAME}.c
2088*a9fa9459Szrjecho '             && link_info.relro' >> e${EMULATION_NAME}.c
2089*a9fa9459Szrjecho '             && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
2090*a9fa9459Szrjsed $sc ldscripts/${EMULATION_NAME}.xsw			>> e${EMULATION_NAME}.c
2091*a9fa9459Szrjecho '  ; else if (bfd_link_dll (&link_info) && link_info.combreloc) return' >> e${EMULATION_NAME}.c
2092*a9fa9459Szrjsed $sc ldscripts/${EMULATION_NAME}.xsc			>> e${EMULATION_NAME}.c
2093*a9fa9459Szrjfi
2094*a9fa9459Szrjecho '  ; else if (bfd_link_dll (&link_info)) return'	>> e${EMULATION_NAME}.c
2095*a9fa9459Szrjsed $sc ldscripts/${EMULATION_NAME}.xs			>> e${EMULATION_NAME}.c
2096*a9fa9459Szrjfi
2097*a9fa9459Szrjif test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
2098*a9fa9459Szrjecho '  ; else if (link_info.combreloc && link_info.relro' >> e${EMULATION_NAME}.c
2099*a9fa9459Szrjecho '             && (link_info.flags & DF_BIND_NOW)) return' >> e${EMULATION_NAME}.c
2100*a9fa9459Szrjsed $sc ldscripts/${EMULATION_NAME}.xw			>> e${EMULATION_NAME}.c
2101*a9fa9459Szrjecho '  ; else if (link_info.combreloc) return'		>> e${EMULATION_NAME}.c
2102*a9fa9459Szrjsed $sc ldscripts/${EMULATION_NAME}.xc			>> e${EMULATION_NAME}.c
2103*a9fa9459Szrjfi
2104*a9fa9459Szrjecho '  ; else return'					>> e${EMULATION_NAME}.c
2105*a9fa9459Szrjsed $sc ldscripts/${EMULATION_NAME}.x			>> e${EMULATION_NAME}.c
2106*a9fa9459Szrjecho '; }'						>> e${EMULATION_NAME}.c
2107*a9fa9459Szrj
2108*a9fa9459Szrjelse
2109*a9fa9459Szrj# Scripts read from the filesystem.
2110*a9fa9459Szrj
2111*a9fa9459Szrjfragment <<EOF
2112*a9fa9459Szrj{
2113*a9fa9459Szrj  *isfile = 1;
2114*a9fa9459Szrj
2115*a9fa9459Szrj  if (bfd_link_relocatable (&link_info) && config.build_constructors)
2116*a9fa9459Szrj    return "ldscripts/${EMULATION_NAME}.xu";
2117*a9fa9459Szrj  else if (bfd_link_relocatable (&link_info))
2118*a9fa9459Szrj    return "ldscripts/${EMULATION_NAME}.xr";
2119*a9fa9459Szrj  else if (!config.text_read_only)
2120*a9fa9459Szrj    return "ldscripts/${EMULATION_NAME}.xbn";
2121*a9fa9459SzrjEOF
2122*a9fa9459Szrjif cmp -s ldscripts/${EMULATION_NAME}.x ldscripts/${EMULATION_NAME}.xn; then :
2123*a9fa9459Szrjelse
2124*a9fa9459Szrjfragment <<EOF
2125*a9fa9459Szrj  else if (!config.magic_demand_paged)
2126*a9fa9459Szrj    return "ldscripts/${EMULATION_NAME}.xn";
2127*a9fa9459SzrjEOF
2128*a9fa9459Szrjfi
2129*a9fa9459Szrjif test -n "$GENERATE_PIE_SCRIPT" ; then
2130*a9fa9459Szrjif test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
2131*a9fa9459Szrjfragment <<EOF
2132*a9fa9459Szrj  else if (bfd_link_pie (&link_info)
2133*a9fa9459Szrj	   && link_info.combreloc
2134*a9fa9459Szrj	   && link_info.relro
2135*a9fa9459Szrj	   && (link_info.flags & DF_BIND_NOW))
2136*a9fa9459Szrj    return "ldscripts/${EMULATION_NAME}.xdw";
2137*a9fa9459Szrj  else if (bfd_link_pie (&link_info)
2138*a9fa9459Szrj	   && link_info.combreloc)
2139*a9fa9459Szrj    return "ldscripts/${EMULATION_NAME}.xdc";
2140*a9fa9459SzrjEOF
2141*a9fa9459Szrjfi
2142*a9fa9459Szrjfragment <<EOF
2143*a9fa9459Szrj  else if (bfd_link_pie (&link_info))
2144*a9fa9459Szrj    return "ldscripts/${EMULATION_NAME}.xd";
2145*a9fa9459SzrjEOF
2146*a9fa9459Szrjfi
2147*a9fa9459Szrjif test -n "$GENERATE_SHLIB_SCRIPT" ; then
2148*a9fa9459Szrjif test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
2149*a9fa9459Szrjfragment <<EOF
2150*a9fa9459Szrj  else if (bfd_link_dll (&link_info) && link_info.combreloc
2151*a9fa9459Szrj	   && link_info.relro && (link_info.flags & DF_BIND_NOW))
2152*a9fa9459Szrj    return "ldscripts/${EMULATION_NAME}.xsw";
2153*a9fa9459Szrj  else if (bfd_link_dll (&link_info) && link_info.combreloc)
2154*a9fa9459Szrj    return "ldscripts/${EMULATION_NAME}.xsc";
2155*a9fa9459SzrjEOF
2156*a9fa9459Szrjfi
2157*a9fa9459Szrjfragment <<EOF
2158*a9fa9459Szrj  else if (bfd_link_dll (&link_info))
2159*a9fa9459Szrj    return "ldscripts/${EMULATION_NAME}.xs";
2160*a9fa9459SzrjEOF
2161*a9fa9459Szrjfi
2162*a9fa9459Szrjif test -n "$GENERATE_COMBRELOC_SCRIPT" ; then
2163*a9fa9459Szrjfragment <<EOF
2164*a9fa9459Szrj  else if (link_info.combreloc && link_info.relro
2165*a9fa9459Szrj	   && (link_info.flags & DF_BIND_NOW))
2166*a9fa9459Szrj    return "ldscripts/${EMULATION_NAME}.xw";
2167*a9fa9459Szrj  else if (link_info.combreloc)
2168*a9fa9459Szrj    return "ldscripts/${EMULATION_NAME}.xc";
2169*a9fa9459SzrjEOF
2170*a9fa9459Szrjfi
2171*a9fa9459Szrjfragment <<EOF
2172*a9fa9459Szrj  else
2173*a9fa9459Szrj    return "ldscripts/${EMULATION_NAME}.x";
2174*a9fa9459Szrj}
2175*a9fa9459Szrj
2176*a9fa9459SzrjEOF
2177*a9fa9459Szrjfi
2178*a9fa9459Szrjfi
2179*a9fa9459Szrj
2180*a9fa9459Szrjif test -n "$PARSE_AND_LIST_PROLOGUE" ; then
2181*a9fa9459Szrjfragment <<EOF
2182*a9fa9459Szrj $PARSE_AND_LIST_PROLOGUE
2183*a9fa9459SzrjEOF
2184*a9fa9459Szrjfi
2185*a9fa9459Szrj
2186*a9fa9459Szrjfragment <<EOF
2187*a9fa9459Szrj
2188*a9fa9459Szrj#define OPTION_DISABLE_NEW_DTAGS	(400)
2189*a9fa9459Szrj#define OPTION_ENABLE_NEW_DTAGS		(OPTION_DISABLE_NEW_DTAGS + 1)
2190*a9fa9459Szrj#define OPTION_GROUP			(OPTION_ENABLE_NEW_DTAGS + 1)
2191*a9fa9459Szrj#define OPTION_EH_FRAME_HDR		(OPTION_GROUP + 1)
2192*a9fa9459Szrj#define OPTION_EXCLUDE_LIBS		(OPTION_EH_FRAME_HDR + 1)
2193*a9fa9459Szrj#define OPTION_HASH_STYLE		(OPTION_EXCLUDE_LIBS + 1)
2194*a9fa9459Szrj#define OPTION_BUILD_ID			(OPTION_HASH_STYLE + 1)
2195*a9fa9459Szrj#define OPTION_AUDIT			(OPTION_BUILD_ID + 1)
2196*a9fa9459Szrj#define OPTION_COMPRESS_DEBUG		(OPTION_AUDIT + 1)
2197*a9fa9459Szrj
2198*a9fa9459Szrjstatic void
2199*a9fa9459Szrjgld${EMULATION_NAME}_add_options
2200*a9fa9459Szrj  (int ns, char **shortopts, int nl, struct option **longopts,
2201*a9fa9459Szrj   int nrl ATTRIBUTE_UNUSED, struct option **really_longopts ATTRIBUTE_UNUSED)
2202*a9fa9459Szrj{
2203*a9fa9459SzrjEOF
2204*a9fa9459Szrjif test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
2205*a9fa9459Szrjfragment <<EOF
2206*a9fa9459Szrj  static const char xtra_short[] = "${PARSE_AND_LIST_SHORTOPTS}z:P:";
2207*a9fa9459SzrjEOF
2208*a9fa9459Szrjelse
2209*a9fa9459Szrjfragment <<EOF
2210*a9fa9459Szrj  static const char xtra_short[] = "${PARSE_AND_LIST_SHORTOPTS}z:";
2211*a9fa9459SzrjEOF
2212*a9fa9459Szrjfi
2213*a9fa9459Szrjfragment <<EOF
2214*a9fa9459Szrj  static const struct option xtra_long[] = {
2215*a9fa9459SzrjEOF
2216*a9fa9459Szrjif test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
2217*a9fa9459Szrjfragment <<EOF
2218*a9fa9459Szrj    {"audit", required_argument, NULL, OPTION_AUDIT},
2219*a9fa9459Szrj    {"Bgroup", no_argument, NULL, OPTION_GROUP},
2220*a9fa9459SzrjEOF
2221*a9fa9459Szrjfi
2222*a9fa9459Szrjfragment <<EOF
2223*a9fa9459Szrj    {"build-id", optional_argument, NULL, OPTION_BUILD_ID},
2224*a9fa9459Szrj    {"compress-debug-sections", required_argument, NULL, OPTION_COMPRESS_DEBUG},
2225*a9fa9459SzrjEOF
2226*a9fa9459Szrjif test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
2227*a9fa9459Szrjfragment <<EOF
2228*a9fa9459Szrj    {"depaudit", required_argument, NULL, 'P'},
2229*a9fa9459Szrj    {"disable-new-dtags", no_argument, NULL, OPTION_DISABLE_NEW_DTAGS},
2230*a9fa9459Szrj    {"enable-new-dtags", no_argument, NULL, OPTION_ENABLE_NEW_DTAGS},
2231*a9fa9459Szrj    {"eh-frame-hdr", no_argument, NULL, OPTION_EH_FRAME_HDR},
2232*a9fa9459Szrj    {"exclude-libs", required_argument, NULL, OPTION_EXCLUDE_LIBS},
2233*a9fa9459Szrj    {"hash-style", required_argument, NULL, OPTION_HASH_STYLE},
2234*a9fa9459SzrjEOF
2235*a9fa9459Szrjfi
2236*a9fa9459Szrjif test -n "$PARSE_AND_LIST_LONGOPTS" ; then
2237*a9fa9459Szrjfragment <<EOF
2238*a9fa9459Szrj    $PARSE_AND_LIST_LONGOPTS
2239*a9fa9459SzrjEOF
2240*a9fa9459Szrjfi
2241*a9fa9459Szrjfragment <<EOF
2242*a9fa9459Szrj    {NULL, no_argument, NULL, 0}
2243*a9fa9459Szrj  };
2244*a9fa9459Szrj
2245*a9fa9459Szrj  *shortopts = (char *) xrealloc (*shortopts, ns + sizeof (xtra_short));
2246*a9fa9459Szrj  memcpy (*shortopts + ns, &xtra_short, sizeof (xtra_short));
2247*a9fa9459Szrj  *longopts = (struct option *)
2248*a9fa9459Szrj    xrealloc (*longopts, nl * sizeof (struct option) + sizeof (xtra_long));
2249*a9fa9459Szrj  memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long));
2250*a9fa9459Szrj}
2251*a9fa9459Szrj
2252*a9fa9459Szrj#define DEFAULT_BUILD_ID_STYLE	"sha1"
2253*a9fa9459Szrj
2254*a9fa9459Szrjstatic bfd_boolean
2255*a9fa9459Szrjgld${EMULATION_NAME}_handle_option (int optc)
2256*a9fa9459Szrj{
2257*a9fa9459Szrj  switch (optc)
2258*a9fa9459Szrj    {
2259*a9fa9459Szrj    default:
2260*a9fa9459Szrj      return FALSE;
2261*a9fa9459Szrj
2262*a9fa9459Szrj    case OPTION_BUILD_ID:
2263*a9fa9459Szrj      if (emit_note_gnu_build_id != NULL)
2264*a9fa9459Szrj	{
2265*a9fa9459Szrj	  free ((char *) emit_note_gnu_build_id);
2266*a9fa9459Szrj	  emit_note_gnu_build_id = NULL;
2267*a9fa9459Szrj	}
2268*a9fa9459Szrj      if (optarg == NULL)
2269*a9fa9459Szrj	optarg = DEFAULT_BUILD_ID_STYLE;
2270*a9fa9459Szrj      if (strcmp (optarg, "none"))
2271*a9fa9459Szrj	emit_note_gnu_build_id = xstrdup (optarg);
2272*a9fa9459Szrj      break;
2273*a9fa9459Szrj
2274*a9fa9459Szrj    case OPTION_COMPRESS_DEBUG:
2275*a9fa9459Szrj      if (strcasecmp (optarg, "none") == 0)
2276*a9fa9459Szrj	link_info.compress_debug = COMPRESS_DEBUG_NONE;
2277*a9fa9459Szrj      else if (strcasecmp (optarg, "zlib") == 0)
2278*a9fa9459Szrj	link_info.compress_debug = COMPRESS_DEBUG_GABI_ZLIB;
2279*a9fa9459Szrj      else if (strcasecmp (optarg, "zlib-gnu") == 0)
2280*a9fa9459Szrj	link_info.compress_debug = COMPRESS_DEBUG_GNU_ZLIB;
2281*a9fa9459Szrj      else if (strcasecmp (optarg, "zlib-gabi") == 0)
2282*a9fa9459Szrj	link_info.compress_debug = COMPRESS_DEBUG_GABI_ZLIB;
2283*a9fa9459Szrj      else
2284*a9fa9459Szrj	einfo (_("%P%F: invalid --compress-debug-sections option: \`%s'\n"),
2285*a9fa9459Szrj	       optarg);
2286*a9fa9459Szrj      break;
2287*a9fa9459SzrjEOF
2288*a9fa9459Szrj
2289*a9fa9459Szrjif test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
2290*a9fa9459Szrjfragment <<EOF
2291*a9fa9459Szrj    case OPTION_AUDIT:
2292*a9fa9459Szrj	gld${EMULATION_NAME}_append_to_separated_string (&audit, optarg);
2293*a9fa9459Szrj	break;
2294*a9fa9459Szrj
2295*a9fa9459Szrj    case 'P':
2296*a9fa9459Szrj	gld${EMULATION_NAME}_append_to_separated_string (&depaudit, optarg);
2297*a9fa9459Szrj	break;
2298*a9fa9459Szrj
2299*a9fa9459Szrj    case OPTION_DISABLE_NEW_DTAGS:
2300*a9fa9459Szrj      link_info.new_dtags = FALSE;
2301*a9fa9459Szrj      break;
2302*a9fa9459Szrj
2303*a9fa9459Szrj    case OPTION_ENABLE_NEW_DTAGS:
2304*a9fa9459Szrj      link_info.new_dtags = TRUE;
2305*a9fa9459Szrj      break;
2306*a9fa9459Szrj
2307*a9fa9459Szrj    case OPTION_EH_FRAME_HDR:
2308*a9fa9459Szrj      link_info.eh_frame_hdr_type = DWARF2_EH_HDR;
2309*a9fa9459Szrj      break;
2310*a9fa9459Szrj
2311*a9fa9459Szrj    case OPTION_GROUP:
2312*a9fa9459Szrj      link_info.flags_1 |= (bfd_vma) DF_1_GROUP;
2313*a9fa9459Szrj      /* Groups must be self-contained.  */
2314*a9fa9459Szrj      link_info.unresolved_syms_in_objects = RM_GENERATE_ERROR;
2315*a9fa9459Szrj      link_info.unresolved_syms_in_shared_libs = RM_GENERATE_ERROR;
2316*a9fa9459Szrj      break;
2317*a9fa9459Szrj
2318*a9fa9459Szrj    case OPTION_EXCLUDE_LIBS:
2319*a9fa9459Szrj      add_excluded_libs (optarg);
2320*a9fa9459Szrj      break;
2321*a9fa9459Szrj
2322*a9fa9459Szrj    case OPTION_HASH_STYLE:
2323*a9fa9459Szrj      link_info.emit_hash = FALSE;
2324*a9fa9459Szrj      link_info.emit_gnu_hash = FALSE;
2325*a9fa9459Szrj      if (strcmp (optarg, "sysv") == 0)
2326*a9fa9459Szrj	link_info.emit_hash = TRUE;
2327*a9fa9459Szrj      else if (strcmp (optarg, "gnu") == 0)
2328*a9fa9459Szrj	link_info.emit_gnu_hash = TRUE;
2329*a9fa9459Szrj      else if (strcmp (optarg, "both") == 0)
2330*a9fa9459Szrj	{
2331*a9fa9459Szrj	  link_info.emit_hash = TRUE;
2332*a9fa9459Szrj	  link_info.emit_gnu_hash = TRUE;
2333*a9fa9459Szrj	}
2334*a9fa9459Szrj      else
2335*a9fa9459Szrj	einfo (_("%P%F: invalid hash style \`%s'\n"), optarg);
2336*a9fa9459Szrj      break;
2337*a9fa9459Szrj
2338*a9fa9459SzrjEOF
2339*a9fa9459Szrjfi
2340*a9fa9459Szrjfragment <<EOF
2341*a9fa9459Szrj    case 'z':
2342*a9fa9459Szrj      if (strcmp (optarg, "defs") == 0)
2343*a9fa9459Szrj	link_info.unresolved_syms_in_objects = RM_GENERATE_ERROR;
2344*a9fa9459Szrj      else if (strcmp (optarg, "muldefs") == 0)
2345*a9fa9459Szrj	link_info.allow_multiple_definition = TRUE;
2346*a9fa9459Szrj      else if (CONST_STRNEQ (optarg, "max-page-size="))
2347*a9fa9459Szrj	{
2348*a9fa9459Szrj	  char *end;
2349*a9fa9459Szrj
2350*a9fa9459Szrj	  config.maxpagesize = strtoul (optarg + 14, &end, 0);
2351*a9fa9459Szrj	  if (*end || (config.maxpagesize & (config.maxpagesize - 1)) != 0)
2352*a9fa9459Szrj	    einfo (_("%P%F: invalid maxium page size \`%s'\n"),
2353*a9fa9459Szrj		   optarg + 14);
2354*a9fa9459Szrj	}
2355*a9fa9459Szrj      else if (CONST_STRNEQ (optarg, "common-page-size="))
2356*a9fa9459Szrj	{
2357*a9fa9459Szrj	  char *end;
2358*a9fa9459Szrj	  config.commonpagesize = strtoul (optarg + 17, &end, 0);
2359*a9fa9459Szrj	  if (*end
2360*a9fa9459Szrj	      || (config.commonpagesize & (config.commonpagesize - 1)) != 0)
2361*a9fa9459Szrj	    einfo (_("%P%F: invalid common page size \`%s'\n"),
2362*a9fa9459Szrj		   optarg + 17);
2363*a9fa9459Szrj	}
2364*a9fa9459Szrj      else if (CONST_STRNEQ (optarg, "stack-size="))
2365*a9fa9459Szrj	{
2366*a9fa9459Szrj	  char *end;
2367*a9fa9459Szrj	  link_info.stacksize = strtoul (optarg + 11, &end, 0);
2368*a9fa9459Szrj	  if (*end || link_info.stacksize < 0)
2369*a9fa9459Szrj	    einfo (_("%P%F: invalid stack size \`%s'\n"), optarg + 11);
2370*a9fa9459Szrj	  if (!link_info.stacksize)
2371*a9fa9459Szrj	    /* Use -1 for explicit no-stack, because zero means
2372*a9fa9459Szrj	       'default'.   */
2373*a9fa9459Szrj	    link_info.stacksize = -1;
2374*a9fa9459Szrj	}
2375*a9fa9459Szrj      else if (strcmp (optarg, "execstack") == 0)
2376*a9fa9459Szrj	{
2377*a9fa9459Szrj	  link_info.execstack = TRUE;
2378*a9fa9459Szrj	  link_info.noexecstack = FALSE;
2379*a9fa9459Szrj	}
2380*a9fa9459Szrj      else if (strcmp (optarg, "noexecstack") == 0)
2381*a9fa9459Szrj	{
2382*a9fa9459Szrj	  link_info.noexecstack = TRUE;
2383*a9fa9459Szrj	  link_info.execstack = FALSE;
2384*a9fa9459Szrj	}
2385*a9fa9459SzrjEOF
2386*a9fa9459Szrj
2387*a9fa9459Szrjif test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
2388*a9fa9459Szrjfragment <<EOF
2389*a9fa9459Szrj      else if (strcmp (optarg, "global") == 0)
2390*a9fa9459Szrj	link_info.flags_1 |= (bfd_vma) DF_1_GLOBAL;
2391*a9fa9459Szrj      else if (strcmp (optarg, "initfirst") == 0)
2392*a9fa9459Szrj	link_info.flags_1 |= (bfd_vma) DF_1_INITFIRST;
2393*a9fa9459Szrj      else if (strcmp (optarg, "interpose") == 0)
2394*a9fa9459Szrj	link_info.flags_1 |= (bfd_vma) DF_1_INTERPOSE;
2395*a9fa9459Szrj      else if (strcmp (optarg, "loadfltr") == 0)
2396*a9fa9459Szrj	link_info.flags_1 |= (bfd_vma) DF_1_LOADFLTR;
2397*a9fa9459Szrj      else if (strcmp (optarg, "nodefaultlib") == 0)
2398*a9fa9459Szrj	link_info.flags_1 |= (bfd_vma) DF_1_NODEFLIB;
2399*a9fa9459Szrj      else if (strcmp (optarg, "nodelete") == 0)
2400*a9fa9459Szrj	link_info.flags_1 |= (bfd_vma) DF_1_NODELETE;
2401*a9fa9459Szrj      else if (strcmp (optarg, "nodlopen") == 0)
2402*a9fa9459Szrj	link_info.flags_1 |= (bfd_vma) DF_1_NOOPEN;
2403*a9fa9459Szrj      else if (strcmp (optarg, "nodump") == 0)
2404*a9fa9459Szrj	link_info.flags_1 |= (bfd_vma) DF_1_NODUMP;
2405*a9fa9459Szrj      else if (strcmp (optarg, "now") == 0)
2406*a9fa9459Szrj	{
2407*a9fa9459Szrj	  link_info.flags |= (bfd_vma) DF_BIND_NOW;
2408*a9fa9459Szrj	  link_info.flags_1 |= (bfd_vma) DF_1_NOW;
2409*a9fa9459Szrj	}
2410*a9fa9459Szrj      else if (strcmp (optarg, "lazy") == 0)
2411*a9fa9459Szrj	{
2412*a9fa9459Szrj	  link_info.flags &= ~(bfd_vma) DF_BIND_NOW;
2413*a9fa9459Szrj	  link_info.flags_1 &= ~(bfd_vma) DF_1_NOW;
2414*a9fa9459Szrj	}
2415*a9fa9459Szrj      else if (strcmp (optarg, "origin") == 0)
2416*a9fa9459Szrj	{
2417*a9fa9459Szrj	  link_info.flags |= (bfd_vma) DF_ORIGIN;
2418*a9fa9459Szrj	  link_info.flags_1 |= (bfd_vma) DF_1_ORIGIN;
2419*a9fa9459Szrj	}
2420*a9fa9459Szrj      else if (strcmp (optarg, "combreloc") == 0)
2421*a9fa9459Szrj	link_info.combreloc = TRUE;
2422*a9fa9459Szrj      else if (strcmp (optarg, "nocombreloc") == 0)
2423*a9fa9459Szrj	link_info.combreloc = FALSE;
2424*a9fa9459Szrj      else if (strcmp (optarg, "nocopyreloc") == 0)
2425*a9fa9459Szrj	link_info.nocopyreloc = TRUE;
2426*a9fa9459Szrj      else if (strcmp (optarg, "relro") == 0)
2427*a9fa9459Szrj	link_info.relro = TRUE;
2428*a9fa9459Szrj      else if (strcmp (optarg, "norelro") == 0)
2429*a9fa9459Szrj	link_info.relro = FALSE;
2430*a9fa9459Szrj      else if (strcmp (optarg, "common") == 0)
2431*a9fa9459Szrj	link_info.elf_stt_common = elf_stt_common;
2432*a9fa9459Szrj      else if (strcmp (optarg, "nocommon") == 0)
2433*a9fa9459Szrj	link_info.elf_stt_common = no_elf_stt_common;
2434*a9fa9459Szrj      else if (strcmp (optarg, "text") == 0)
2435*a9fa9459Szrj	link_info.error_textrel = TRUE;
2436*a9fa9459Szrj      else if (strcmp (optarg, "notext") == 0)
2437*a9fa9459Szrj	link_info.error_textrel = FALSE;
2438*a9fa9459Szrj      else if (strcmp (optarg, "textoff") == 0)
2439*a9fa9459Szrj	link_info.error_textrel = FALSE;
2440*a9fa9459SzrjEOF
2441*a9fa9459Szrjfi
2442*a9fa9459Szrj
2443*a9fa9459Szrjif test -n "$PARSE_AND_LIST_ARGS_CASE_Z" ; then
2444*a9fa9459Szrjfragment <<EOF
2445*a9fa9459Szrj $PARSE_AND_LIST_ARGS_CASE_Z
2446*a9fa9459SzrjEOF
2447*a9fa9459Szrjfi
2448*a9fa9459Szrj
2449*a9fa9459Szrjfragment <<EOF
2450*a9fa9459Szrj      else
2451*a9fa9459Szrj	einfo (_("%P: warning: -z %s ignored.\n"), optarg);
2452*a9fa9459Szrj      break;
2453*a9fa9459SzrjEOF
2454*a9fa9459Szrj
2455*a9fa9459Szrjif test -n "$PARSE_AND_LIST_ARGS_CASES" ; then
2456*a9fa9459Szrjfragment <<EOF
2457*a9fa9459Szrj $PARSE_AND_LIST_ARGS_CASES
2458*a9fa9459SzrjEOF
2459*a9fa9459Szrjfi
2460*a9fa9459Szrj
2461*a9fa9459Szrjfragment <<EOF
2462*a9fa9459Szrj    }
2463*a9fa9459Szrj
2464*a9fa9459Szrj  return TRUE;
2465*a9fa9459Szrj}
2466*a9fa9459Szrj
2467*a9fa9459SzrjEOF
2468*a9fa9459Szrj
2469*a9fa9459Szrjif test x"$LDEMUL_LIST_OPTIONS" != xgld"$EMULATION_NAME"_list_options; then
2470*a9fa9459Szrjgld_list_options="gld${EMULATION_NAME}_list_options"
2471*a9fa9459Szrjif test -n "$PARSE_AND_LIST_OPTIONS"; then
2472*a9fa9459Szrjfragment <<EOF
2473*a9fa9459Szrj
2474*a9fa9459Szrjstatic void
2475*a9fa9459Szrjgld${EMULATION_NAME}_list_options (FILE * file)
2476*a9fa9459Szrj{
2477*a9fa9459SzrjEOF
2478*a9fa9459Szrj
2479*a9fa9459Szrjif test -n "$PARSE_AND_LIST_OPTIONS" ; then
2480*a9fa9459Szrjfragment <<EOF
2481*a9fa9459Szrj $PARSE_AND_LIST_OPTIONS
2482*a9fa9459SzrjEOF
2483*a9fa9459Szrjfi
2484*a9fa9459Szrj
2485*a9fa9459Szrjfragment <<EOF
2486*a9fa9459Szrj}
2487*a9fa9459SzrjEOF
2488*a9fa9459Szrjelse
2489*a9fa9459Szrj  gld_list_options="NULL"
2490*a9fa9459Szrjfi
2491*a9fa9459Szrj
2492*a9fa9459Szrjif test -n "$PARSE_AND_LIST_EPILOGUE" ; then
2493*a9fa9459Szrjfragment <<EOF
2494*a9fa9459Szrj $PARSE_AND_LIST_EPILOGUE
2495*a9fa9459SzrjEOF
2496*a9fa9459Szrjfi
2497*a9fa9459Szrjfi
2498*a9fa9459Szrj
2499*a9fa9459Szrjfragment <<EOF
2500*a9fa9459Szrj
2501*a9fa9459Szrjstruct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
2502*a9fa9459Szrj{
2503*a9fa9459Szrj  ${LDEMUL_BEFORE_PARSE-gld${EMULATION_NAME}_before_parse},
2504*a9fa9459Szrj  ${LDEMUL_SYSLIB-syslib_default},
2505*a9fa9459Szrj  ${LDEMUL_HLL-hll_default},
2506*a9fa9459Szrj  ${LDEMUL_AFTER_PARSE-gld${EMULATION_NAME}_after_parse},
2507*a9fa9459Szrj  ${LDEMUL_AFTER_OPEN-gld${EMULATION_NAME}_after_open},
2508*a9fa9459Szrj  ${LDEMUL_AFTER_ALLOCATION-gld${EMULATION_NAME}_after_allocation},
2509*a9fa9459Szrj  ${LDEMUL_SET_OUTPUT_ARCH-set_output_arch_default},
2510*a9fa9459Szrj  ${LDEMUL_CHOOSE_TARGET-ldemul_default_target},
2511*a9fa9459Szrj  ${LDEMUL_BEFORE_ALLOCATION-gld${EMULATION_NAME}_before_allocation},
2512*a9fa9459Szrj  ${LDEMUL_GET_SCRIPT-gld${EMULATION_NAME}_get_script},
2513*a9fa9459Szrj  "${EMULATION_NAME}",
2514*a9fa9459Szrj  "${OUTPUT_FORMAT}",
2515*a9fa9459Szrj  ${LDEMUL_FINISH-finish_default},
2516*a9fa9459Szrj  ${LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS-NULL},
2517*a9fa9459Szrj  ${LDEMUL_OPEN_DYNAMIC_ARCHIVE-gld${EMULATION_NAME}_open_dynamic_archive},
2518*a9fa9459Szrj  ${LDEMUL_PLACE_ORPHAN-gld${EMULATION_NAME}_place_orphan},
2519*a9fa9459Szrj  ${LDEMUL_SET_SYMBOLS-NULL},
2520*a9fa9459Szrj  ${LDEMUL_PARSE_ARGS-NULL},
2521*a9fa9459Szrj  gld${EMULATION_NAME}_add_options,
2522*a9fa9459Szrj  gld${EMULATION_NAME}_handle_option,
2523*a9fa9459Szrj  ${LDEMUL_UNRECOGNIZED_FILE-NULL},
2524*a9fa9459Szrj  ${LDEMUL_LIST_OPTIONS-${gld_list_options}},
2525*a9fa9459Szrj  ${LDEMUL_RECOGNIZED_FILE-gld${EMULATION_NAME}_load_symbols},
2526*a9fa9459Szrj  ${LDEMUL_FIND_POTENTIAL_LIBRARIES-NULL},
2527*a9fa9459Szrj  ${LDEMUL_NEW_VERS_PATTERN-NULL},
2528*a9fa9459Szrj  ${LDEMUL_EXTRA_MAP_FILE_TEXT-NULL}
2529*a9fa9459Szrj};
2530*a9fa9459SzrjEOF
2531