elf32.em revision 76232
160525Sobrien# $FreeBSD: head/contrib/binutils/ld/emultempl/elf32.em 76232 2001-05-03 01:49:58Z obrien $
233965Sjdp# This shell script emits a C file. -*- C -*-
333965Sjdp# It does some substitutions.
433965Sjdp# This file is now misnamed, because it supports both 32 bit and 64 bit
533965Sjdp# ELF emulations.
633965Sjdptest -z "${ELFSIZE}" && ELFSIZE=32
733965Sjdpcat >e${EMULATION_NAME}.c <<EOF
833965Sjdp/* This file is is generated by a shell script.  DO NOT EDIT! */
933965Sjdp
1033965Sjdp/* ${ELFSIZE} bit ELF emulation code for ${EMULATION_NAME}
1168778Sobrien   Copyright (C) 1991, 93, 94, 95, 96, 97, 98, 99, 2000
1260525Sobrien   Free Software Foundation, Inc.
1333965Sjdp   Written by Steve Chamberlain <sac@cygnus.com>
1433965Sjdp   ELF support by Ian Lance Taylor <ian@cygnus.com>
1533965Sjdp
1633965SjdpThis file is part of GLD, the Gnu Linker.
1733965Sjdp
1833965SjdpThis program is free software; you can redistribute it and/or modify
1933965Sjdpit under the terms of the GNU General Public License as published by
2033965Sjdpthe Free Software Foundation; either version 2 of the License, or
2133965Sjdp(at your option) any later version.
2233965Sjdp
2333965SjdpThis program is distributed in the hope that it will be useful,
2433965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of
2533965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2633965SjdpGNU General Public License for more details.
2733965Sjdp
2833965SjdpYou should have received a copy of the GNU General Public License
2933965Sjdpalong with this program; if not, write to the Free Software
3033965SjdpFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
3133965Sjdp
3233965Sjdp#define TARGET_IS_${EMULATION_NAME}
3333965Sjdp
3433965Sjdp#include "bfd.h"
3533965Sjdp#include "sysdep.h"
3633965Sjdp
3733965Sjdp#include <ctype.h>
3833965Sjdp
3933965Sjdp#include "bfdlink.h"
4033965Sjdp
4133965Sjdp#include "ld.h"
4233965Sjdp#include "ldmain.h"
4333965Sjdp#include "ldemul.h"
4433965Sjdp#include "ldfile.h"
4533965Sjdp#include "ldmisc.h"
4633965Sjdp#include "ldexp.h"
4733965Sjdp#include "ldlang.h"
4833965Sjdp#include "ldgram.h"
4933965Sjdp
5033965Sjdpstatic void gld${EMULATION_NAME}_before_parse PARAMS ((void));
5133965Sjdpstatic boolean gld${EMULATION_NAME}_open_dynamic_archive
5233965Sjdp  PARAMS ((const char *, search_dirs_type *, lang_input_statement_type *));
5333965Sjdpstatic void gld${EMULATION_NAME}_after_open PARAMS ((void));
5433965Sjdpstatic void gld${EMULATION_NAME}_check_needed
5533965Sjdp  PARAMS ((lang_input_statement_type *));
5633965Sjdpstatic void gld${EMULATION_NAME}_stat_needed
5733965Sjdp  PARAMS ((lang_input_statement_type *));
5833965Sjdpstatic boolean gld${EMULATION_NAME}_search_needed
5938889Sjdp  PARAMS ((const char *, const char *, int));
6038889Sjdpstatic boolean gld${EMULATION_NAME}_try_needed PARAMS ((const char *, int));
6138889Sjdpstatic void gld${EMULATION_NAME}_vercheck
6238889Sjdp  PARAMS ((lang_input_statement_type *));
6333965Sjdpstatic void gld${EMULATION_NAME}_before_allocation PARAMS ((void));
6433965Sjdpstatic void gld${EMULATION_NAME}_find_statement_assignment
6533965Sjdp  PARAMS ((lang_statement_union_type *));
6633965Sjdpstatic void gld${EMULATION_NAME}_find_exp_assignment PARAMS ((etree_type *));
6768778Sobrienstatic lang_output_section_statement_type *output_rel_find PARAMS ((void));
6833965Sjdpstatic boolean gld${EMULATION_NAME}_place_orphan
6933965Sjdp  PARAMS ((lang_input_statement_type *, asection *));
7033965Sjdpstatic char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
7133965Sjdp
7233965Sjdpstatic void
7333965Sjdpgld${EMULATION_NAME}_before_parse()
7433965Sjdp{
7533965Sjdp  ldfile_output_architecture = bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`;
7633965Sjdp  config.dynamic_link = ${DYNAMIC_LINK-true};
7760525Sobrien  config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo true ; else echo false ; fi`;
7833965Sjdp}
7933965Sjdp
8033965Sjdp/* Try to open a dynamic archive.  This is where we know that ELF
8160525Sobrien   dynamic libraries have an extension of .so (or .sl on oddball systems
8260525Sobrien   like hpux).  */
8333965Sjdp
8433965Sjdpstatic boolean
8533965Sjdpgld${EMULATION_NAME}_open_dynamic_archive (arch, search, entry)
8633965Sjdp     const char *arch;
8733965Sjdp     search_dirs_type *search;
8833965Sjdp     lang_input_statement_type *entry;
8933965Sjdp{
9033965Sjdp  const char *filename;
9133965Sjdp  char *string;
9233965Sjdp
9333965Sjdp  if (! entry->is_archive)
9433965Sjdp    return false;
9533965Sjdp
9633965Sjdp  filename = entry->filename;
9733965Sjdp
9860525Sobrien  /* This allocates a few bytes too many when EXTRA_SHLIB_EXTENSION
9960525Sobrien     is defined, but it does not seem worth the headache to optimize
10060525Sobrien     away those two bytes of space.  */
10133965Sjdp  string = (char *) xmalloc (strlen (search->name)
10233965Sjdp			     + strlen (filename)
10333965Sjdp			     + strlen (arch)
10460525Sobrien#ifdef EXTRA_SHLIB_EXTENSION
10560525Sobrien			     + strlen (EXTRA_SHLIB_EXTENSION)
10660525Sobrien#endif
10733965Sjdp			     + sizeof "/lib.so");
10833965Sjdp
10933965Sjdp  sprintf (string, "%s/lib%s%s.so", search->name, filename, arch);
11033965Sjdp
11160525Sobrien#ifdef EXTRA_SHLIB_EXTENSION
11260525Sobrien  /* Try the .so extension first.  If that fails build a new filename
11360525Sobrien     using EXTRA_SHLIB_EXTENSION.  */
11433965Sjdp  if (! ldfile_try_open_bfd (string, entry))
11560525Sobrien    sprintf (string, "%s/lib%s%s%s", search->name,
11660525Sobrien	     filename, arch, EXTRA_SHLIB_EXTENSION);
11760525Sobrien#endif
11860525Sobrien
11960525Sobrien  if (! ldfile_try_open_bfd (string, entry))
12033965Sjdp    {
12133965Sjdp      free (string);
12233965Sjdp      return false;
12333965Sjdp    }
12433965Sjdp
12533965Sjdp  entry->filename = string;
12633965Sjdp
12733965Sjdp  /* We have found a dynamic object to include in the link.  The ELF
12833965Sjdp     backend linker will create a DT_NEEDED entry in the .dynamic
12933965Sjdp     section naming this file.  If this file includes a DT_SONAME
13033965Sjdp     entry, it will be used.  Otherwise, the ELF linker will just use
13133965Sjdp     the name of the file.  For an archive found by searching, like
13233965Sjdp     this one, the DT_NEEDED entry should consist of just the name of
13333965Sjdp     the file, without the path information used to find it.  Note
13433965Sjdp     that we only need to do this if we have a dynamic object; an
13533965Sjdp     archive will never be referenced by a DT_NEEDED entry.
13633965Sjdp
13733965Sjdp     FIXME: This approach--using bfd_elf_set_dt_needed_name--is not
13833965Sjdp     very pretty.  I haven't been able to think of anything that is
13933965Sjdp     pretty, though.  */
14033965Sjdp  if (bfd_check_format (entry->the_bfd, bfd_object)
14133965Sjdp      && (entry->the_bfd->flags & DYNAMIC) != 0)
14233965Sjdp    {
14333965Sjdp      char *needed_name;
14433965Sjdp
14533965Sjdp      ASSERT (entry->is_archive && entry->search_dirs_flag);
14660525Sobrien
14760525Sobrien      /* Rather than duplicating the logic above.  Just use the
14860525Sobrien	 filename we recorded earlier.
14960525Sobrien
15060525Sobrien	 First strip off everything before the last '/'.  */
15160525Sobrien      filename = strrchr (entry->filename, '/');
15260525Sobrien      filename++;
15360525Sobrien
15460525Sobrien      needed_name = (char *) xmalloc (strlen (filename) + 1);
15560525Sobrien      strcpy (needed_name, filename);
15633965Sjdp      bfd_elf_set_dt_needed_name (entry->the_bfd, needed_name);
15733965Sjdp    }
15833965Sjdp
15933965Sjdp  return true;
16033965Sjdp}
16133965Sjdp
16233965SjdpEOF
16333965Sjdpif [ "x${host}" = "x${target}" ] ; then
16460525Sobrien  case " ${EMULATION_LIBPATH} " in
16560525Sobrien  *" ${EMULATION_NAME} "*)
16642372Speter    case ${target} in
16742372Speter      *-*-freebsd*)
16842372Speter	cat >>e${EMULATION_NAME}.c <<EOF
16942372Speter/*
17042372Speter * Read the system search path the FreeBSD way rather than like Linux.
17142372Speter */
17276232Sobrien#include <elf-hints.h>
17333965Sjdp
17442372Speterstatic boolean gld${EMULATION_NAME}_check_ld_elf_hints
17542372Speter  PARAMS ((const char *, int));
17642372Speter
17742372Speterstatic boolean
17842372Spetergld${EMULATION_NAME}_check_ld_elf_hints (name, force)
17942372Speter     const char *name;
18042372Speter     int force;
18142372Speter{
18242372Speter  static boolean initialized;
18342372Speter  static char *ld_elf_hints;
18442372Speter
18542372Speter  if (! initialized)
18642372Speter    {
18742372Speter      FILE *f;
18842372Speter
18942372Speter      f = fopen (_PATH_ELF_HINTS, FOPEN_RB);
19042372Speter      if (f != NULL)
19142372Speter	{
19242372Speter	  struct elfhints_hdr hdr;
19342372Speter
19442372Speter	  if (fread(&hdr, 1, sizeof(hdr), f) == sizeof(hdr) &&
19542372Speter	      hdr.magic == ELFHINTS_MAGIC &&
19642372Speter	      hdr.version == 1)
19742372Speter	    {
19842372Speter	      if (fseek(f, hdr.strtab + hdr.dirlist, SEEK_SET) != -1)
19942372Speter		{
20042372Speter		  char *b;
20142372Speter
20242372Speter		  b = (char *) xmalloc (hdr.dirlistlen + 1);
20342372Speter		  if (fread(b, 1, hdr.dirlistlen + 1, f) !=
20442372Speter		      hdr.dirlistlen + 1)
20542372Speter		    {
20642372Speter		      free(b);
20742372Speter		    }
20842372Speter		  else
20942372Speter		    {
21042372Speter		      ld_elf_hints = b;
21142372Speter		    }
21242372Speter		}
21342372Speter	    }
21442372Speter	  fclose (f);
21542372Speter	}
21642372Speter
21742372Speter      initialized = true;
21842372Speter    }
21942372Speter
22042372Speter  if (ld_elf_hints == NULL)
22142372Speter    return false;
22242372Speter
22342372Speter  return gld${EMULATION_NAME}_search_needed (ld_elf_hints, name, force);
22442372Speter}
22542372SpeterEOF
22642372Speter	;;
22760525Sobrien
22860525Sobrien      *linux*|*Linux*|*LINUX*)
22942372Speter	cat >>e${EMULATION_NAME}.c <<EOF
23060525Sobrien
23133965Sjdp/* For a native linker, check the file /etc/ld.so.conf for directories
23233965Sjdp   in which we may find shared libraries.  /etc/ld.so.conf is really
23360525Sobrien   only meaningful on Linux.  */
23433965Sjdp
23538889Sjdpstatic boolean gld${EMULATION_NAME}_check_ld_so_conf
23638889Sjdp  PARAMS ((const char *, int));
23733965Sjdp
23833965Sjdpstatic boolean
23938889Sjdpgld${EMULATION_NAME}_check_ld_so_conf (name, force)
24033965Sjdp     const char *name;
24138889Sjdp     int force;
24233965Sjdp{
24333965Sjdp  static boolean initialized;
24433965Sjdp  static char *ld_so_conf;
24533965Sjdp
24633965Sjdp  if (! initialized)
24733965Sjdp    {
24833965Sjdp      FILE *f;
24933965Sjdp
25033965Sjdp      f = fopen ("/etc/ld.so.conf", FOPEN_RT);
25133965Sjdp      if (f != NULL)
25233965Sjdp	{
25333965Sjdp	  char *b;
25433965Sjdp	  size_t len, alloc;
25533965Sjdp	  int c;
25633965Sjdp
25733965Sjdp	  len = 0;
25833965Sjdp	  alloc = 100;
25933965Sjdp	  b = (char *) xmalloc (alloc);
26033965Sjdp
26133965Sjdp	  while ((c = getc (f)) != EOF)
26233965Sjdp	    {
26333965Sjdp	      if (len + 1 >= alloc)
26433965Sjdp		{
26533965Sjdp		  alloc *= 2;
26633965Sjdp		  b = (char *) xrealloc (b, alloc);
26733965Sjdp		}
26833965Sjdp	      if (c != ':'
26933965Sjdp		  && c != ' '
27033965Sjdp		  && c != '\t'
27133965Sjdp		  && c != '\n'
27233965Sjdp		  && c != ',')
27333965Sjdp		{
27433965Sjdp		  b[len] = c;
27533965Sjdp		  ++len;
27633965Sjdp		}
27733965Sjdp	      else
27833965Sjdp		{
27933965Sjdp		  if (len > 0 && b[len - 1] != ':')
28033965Sjdp		    {
28133965Sjdp		      b[len] = ':';
28233965Sjdp		      ++len;
28333965Sjdp		    }
28433965Sjdp		}
28533965Sjdp	    }
28633965Sjdp
28733965Sjdp	  if (len > 0 && b[len - 1] == ':')
28833965Sjdp	    --len;
28933965Sjdp
29033965Sjdp	  if (len > 0)
29133965Sjdp	    b[len] = '\0';
29233965Sjdp	  else
29333965Sjdp	    {
29433965Sjdp	      free (b);
29533965Sjdp	      b = NULL;
29633965Sjdp	    }
29733965Sjdp
29833965Sjdp	  fclose (f);
29933965Sjdp
30033965Sjdp	  ld_so_conf = b;
30133965Sjdp	}
30233965Sjdp
30333965Sjdp      initialized = true;
30433965Sjdp    }
30533965Sjdp
30633965Sjdp  if (ld_so_conf == NULL)
30733965Sjdp    return false;
30833965Sjdp
30938889Sjdp  return gld${EMULATION_NAME}_search_needed (ld_so_conf, name, force);
31033965Sjdp}
31160525Sobrien
31233965SjdpEOF
31360525Sobrien	;;
31442372Speter    esac
31560525Sobrien  esac
31633965Sjdpfi
31733965Sjdpcat >>e${EMULATION_NAME}.c <<EOF
31833965Sjdp
31933965Sjdp/* These variables are required to pass information back and forth
32038889Sjdp   between after_open and check_needed and stat_needed and vercheck.  */
32133965Sjdp
32233965Sjdpstatic struct bfd_link_needed_list *global_needed;
32333965Sjdpstatic struct stat global_stat;
32433965Sjdpstatic boolean global_found;
32538889Sjdpstatic struct bfd_link_needed_list *global_vercheck_needed;
32638889Sjdpstatic boolean global_vercheck_failed;
32733965Sjdp
32833965Sjdp/* This is called after all the input files have been opened.  */
32933965Sjdp
33033965Sjdpstatic void
33133965Sjdpgld${EMULATION_NAME}_after_open ()
33233965Sjdp{
33333965Sjdp  struct bfd_link_needed_list *needed, *l;
33433965Sjdp
33533965Sjdp  /* We only need to worry about this when doing a final link.  */
33633965Sjdp  if (link_info.relocateable || link_info.shared)
33733965Sjdp    return;
33833965Sjdp
33933965Sjdp  /* Get the list of files which appear in DT_NEEDED entries in
34033965Sjdp     dynamic objects included in the link (often there will be none).
34133965Sjdp     For each such file, we want to track down the corresponding
34233965Sjdp     library, and include the symbol table in the link.  This is what
34333965Sjdp     the runtime dynamic linker will do.  Tracking the files down here
34433965Sjdp     permits one dynamic object to include another without requiring
34533965Sjdp     special action by the person doing the link.  Note that the
34633965Sjdp     needed list can actually grow while we are stepping through this
34733965Sjdp     loop.  */
34833965Sjdp  needed = bfd_elf_get_needed_list (output_bfd, &link_info);
34933965Sjdp  for (l = needed; l != NULL; l = l->next)
35033965Sjdp    {
35133965Sjdp      struct bfd_link_needed_list *ll;
35238889Sjdp      int force;
35333965Sjdp
35433965Sjdp      /* If we've already seen this file, skip it.  */
35533965Sjdp      for (ll = needed; ll != l; ll = ll->next)
35633965Sjdp	if (strcmp (ll->name, l->name) == 0)
35733965Sjdp	  break;
35833965Sjdp      if (ll != l)
35933965Sjdp	continue;
36033965Sjdp
36133965Sjdp      /* See if this file was included in the link explicitly.  */
36233965Sjdp      global_needed = l;
36333965Sjdp      global_found = false;
36433965Sjdp      lang_for_each_input_file (gld${EMULATION_NAME}_check_needed);
36533965Sjdp      if (global_found)
36633965Sjdp	continue;
36733965Sjdp
36833965Sjdp      /* We need to find this file and include the symbol table.  We
36933965Sjdp	 want to search for the file in the same way that the dynamic
37033965Sjdp	 linker will search.  That means that we want to use
37133965Sjdp	 rpath_link, rpath, then the environment variable
37233965Sjdp	 LD_LIBRARY_PATH (native only), then the linker script
37338889Sjdp	 LIB_SEARCH_DIRS.  We do not search using the -L arguments.
37438889Sjdp
37538889Sjdp	 We search twice.  The first time, we skip objects which may
37638889Sjdp	 introduce version mismatches.  The second time, we force
37738889Sjdp	 their use.  See gld${EMULATION_NAME}_vercheck comment.  */
37838889Sjdp      for (force = 0; force < 2; force++)
37933965Sjdp	{
38038889Sjdp	  const char *lib_path;
38138889Sjdp	  size_t len;
38238889Sjdp	  search_dirs_type *search;
38338889Sjdp
38438889Sjdp	  if (gld${EMULATION_NAME}_search_needed (command_line.rpath_link,
38538889Sjdp						  l->name, force))
38638889Sjdp	    break;
38738889Sjdp	  if (gld${EMULATION_NAME}_search_needed (command_line.rpath,
38838889Sjdp						  l->name, force))
38938889Sjdp	    break;
39038889Sjdp	  if (command_line.rpath_link == NULL
39138889Sjdp	      && command_line.rpath == NULL)
39238889Sjdp	    {
39338889Sjdp	      lib_path = (const char *) getenv ("LD_RUN_PATH");
39438889Sjdp	      if (gld${EMULATION_NAME}_search_needed (lib_path, l->name,
39538889Sjdp						      force))
39638889Sjdp		break;
39738889Sjdp	    }
39833965SjdpEOF
39933965Sjdpif [ "x${host}" = "x${target}" ] ; then
40060525Sobrien  case " ${EMULATION_LIBPATH} " in
40160525Sobrien  *" ${EMULATION_NAME} "*)
40233965Sjdpcat >>e${EMULATION_NAME}.c <<EOF
40338889Sjdp	  lib_path = (const char *) getenv ("LD_LIBRARY_PATH");
40438889Sjdp	  if (gld${EMULATION_NAME}_search_needed (lib_path, l->name, force))
40538889Sjdp	    break;
40633965SjdpEOF
40760525Sobrien  ;;
40860525Sobrien  esac
40933965Sjdpfi
41033965Sjdpcat >>e${EMULATION_NAME}.c <<EOF
41138889Sjdp	  len = strlen (l->name);
41238889Sjdp	  for (search = search_head; search != NULL; search = search->next)
41338889Sjdp	    {
41438889Sjdp	      char *filename;
41533965Sjdp
41638889Sjdp	      if (search->cmdline)
41738889Sjdp		continue;
41838889Sjdp	      filename = (char *) xmalloc (strlen (search->name) + len + 2);
41938889Sjdp	      sprintf (filename, "%s/%s", search->name, l->name);
42038889Sjdp	      if (gld${EMULATION_NAME}_try_needed (filename, force))
42138889Sjdp		break;
42238889Sjdp	      free (filename);
42338889Sjdp	    }
42438889Sjdp	  if (search != NULL)
42533965Sjdp	    break;
42633965SjdpEOF
42733965Sjdpif [ "x${host}" = "x${target}" ] ; then
42860525Sobrien  case " ${EMULATION_LIBPATH} " in
42960525Sobrien  *" ${EMULATION_NAME} "*)
43042372Speter    case ${target} in
43142372Speter      *-*-freebsd*)
43242372Speter	cat >>e${EMULATION_NAME}.c <<EOF
43342372Speter	  if (gld${EMULATION_NAME}_check_ld_elf_hints (l->name, force))
43442372Speter	    break;
43542372SpeterEOF
43642372Speter        ;;
43760525Sobrien      *linux*|*Linux*|*LINUX*)
43842372Speter	cat >>e${EMULATION_NAME}.c <<EOF
43938889Sjdp	  if (gld${EMULATION_NAME}_check_ld_so_conf (l->name, force))
44038889Sjdp	    break;
44133965SjdpEOF
44242372Speter        ;;
44342372Speter    esac
44460525Sobrien  ;;
44560525Sobrien  esac
44633965Sjdpfi
44733965Sjdpcat >>e${EMULATION_NAME}.c <<EOF
44838889Sjdp	}
44933965Sjdp
45038889Sjdp      if (force < 2)
45138889Sjdp	continue;
45238889Sjdp
45368778Sobrien      einfo ("%P: warning: %s, needed by %B, not found (try using -rpath or -rpath-link)\n",
45433965Sjdp	     l->name, l->by);
45533965Sjdp    }
45633965Sjdp}
45733965Sjdp
45833965Sjdp/* Search for a needed file in a path.  */
45933965Sjdp
46033965Sjdpstatic boolean
46138889Sjdpgld${EMULATION_NAME}_search_needed (path, name, force)
46233965Sjdp     const char *path;
46333965Sjdp     const char *name;
46438889Sjdp     int force;
46533965Sjdp{
46633965Sjdp  const char *s;
46733965Sjdp  size_t len;
46833965Sjdp
46933965Sjdp  if (path == NULL || *path == '\0')
47033965Sjdp    return false;
47133965Sjdp  len = strlen (name);
47233965Sjdp  while (1)
47333965Sjdp    {
47433965Sjdp      char *filename, *sset;
47533965Sjdp
47633965Sjdp      s = strchr (path, ':');
47733965Sjdp      if (s == NULL)
47833965Sjdp	s = path + strlen (path);
47933965Sjdp
48033965Sjdp      filename = (char *) xmalloc (s - path + len + 2);
48133965Sjdp      if (s == path)
48233965Sjdp	sset = filename;
48333965Sjdp      else
48433965Sjdp	{
48533965Sjdp	  memcpy (filename, path, s - path);
48633965Sjdp	  filename[s - path] = '/';
48733965Sjdp	  sset = filename + (s - path) + 1;
48833965Sjdp	}
48933965Sjdp      strcpy (sset, name);
49033965Sjdp
49138889Sjdp      if (gld${EMULATION_NAME}_try_needed (filename, force))
49233965Sjdp	return true;
49333965Sjdp
49433965Sjdp      free (filename);
49533965Sjdp
49633965Sjdp      if (*s == '\0')
49733965Sjdp	break;
49833965Sjdp      path = s + 1;
49933965Sjdp    }
50033965Sjdp
50133965Sjdp  return false;	  
50233965Sjdp}
50333965Sjdp
50433965Sjdp/* This function is called for each possible name for a dynamic object
50538889Sjdp   named by a DT_NEEDED entry.  The FORCE parameter indicates whether
50638889Sjdp   to skip the check for a conflicting version.  */
50733965Sjdp
50833965Sjdpstatic boolean
50938889Sjdpgld${EMULATION_NAME}_try_needed (name, force)
51033965Sjdp     const char *name;
51138889Sjdp     int force;
51233965Sjdp{
51333965Sjdp  bfd *abfd;
51433965Sjdp
51533965Sjdp  abfd = bfd_openr (name, bfd_get_target (output_bfd));
51633965Sjdp  if (abfd == NULL)
51733965Sjdp    return false;
51833965Sjdp  if (! bfd_check_format (abfd, bfd_object))
51933965Sjdp    {
52033965Sjdp      (void) bfd_close (abfd);
52133965Sjdp      return false;
52233965Sjdp    }
52333965Sjdp  if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0)
52433965Sjdp    {
52533965Sjdp      (void) bfd_close (abfd);
52633965Sjdp      return false;
52733965Sjdp    }
52833965Sjdp
52938889Sjdp  /* Check whether this object would include any conflicting library
53038889Sjdp     versions.  If FORCE is set, then we skip this check; we use this
53138889Sjdp     the second time around, if we couldn't find any compatible
53238889Sjdp     instance of the shared library.  */
53338889Sjdp
53438889Sjdp  if (! force)
53538889Sjdp    {
53638889Sjdp      struct bfd_link_needed_list *needed;
53738889Sjdp
53838889Sjdp      if (! bfd_elf_get_bfd_needed_list (abfd, &needed))
53938889Sjdp	einfo ("%F%P:%B: bfd_elf_get_bfd_needed_list failed: %E\n", abfd);
54038889Sjdp
54138889Sjdp      if (needed != NULL)
54238889Sjdp	{
54338889Sjdp	  global_vercheck_needed = needed;
54438889Sjdp	  global_vercheck_failed = false;
54538889Sjdp	  lang_for_each_input_file (gld${EMULATION_NAME}_vercheck);
54638889Sjdp	  if (global_vercheck_failed)
54738889Sjdp	    {
54838889Sjdp	      (void) bfd_close (abfd);
54938889Sjdp	      /* Return false to force the caller to move on to try
55038889Sjdp                 another file on the search path.  */
55138889Sjdp	      return false;
55238889Sjdp	    }
55338889Sjdp
55438889Sjdp	  /* But wait!  It gets much worse.  On Linux, if a shared
55538889Sjdp             library does not use libc at all, we are supposed to skip
55638889Sjdp             it the first time around in case we encounter a shared
55738889Sjdp             library later on with the same name which does use the
55838889Sjdp             version of libc that we want.  This is much too horrible
55938889Sjdp             to use on any system other than Linux.  */
56038889Sjdp
56138889SjdpEOF
56238889Sjdpcase ${target} in
56338889Sjdp  *-*-linux-gnu*)
56438889Sjdp    cat >>e${EMULATION_NAME}.c <<EOF
56538889Sjdp	  {
56638889Sjdp	    struct bfd_link_needed_list *l;
56738889Sjdp
56838889Sjdp	    for (l = needed; l != NULL; l = l->next)
56938889Sjdp	      if (strncmp (l->name, "libc.so", 7) == 0)
57038889Sjdp		break;
57138889Sjdp	    if (l == NULL)
57238889Sjdp	      {
57338889Sjdp		(void) bfd_close (abfd);
57438889Sjdp		return false;
57538889Sjdp	      }
57638889Sjdp	  }
57738889Sjdp
57838889SjdpEOF
57938889Sjdp    ;;
58038889Sjdpesac
58138889Sjdpcat >>e${EMULATION_NAME}.c <<EOF
58238889Sjdp	}
58338889Sjdp    }
58438889Sjdp
58533965Sjdp  /* We've found a dynamic object matching the DT_NEEDED entry.  */
58633965Sjdp
58733965Sjdp  /* We have already checked that there is no other input file of the
58833965Sjdp     same name.  We must now check again that we are not including the
58933965Sjdp     same file twice.  We need to do this because on many systems
59033965Sjdp     libc.so is a symlink to, e.g., libc.so.1.  The SONAME entry will
59133965Sjdp     reference libc.so.1.  If we have already included libc.so, we
59233965Sjdp     don't want to include libc.so.1 if they are the same file, and we
59333965Sjdp     can only check that using stat.  */
59433965Sjdp
59533965Sjdp  if (bfd_stat (abfd, &global_stat) != 0)
59633965Sjdp    einfo ("%F%P:%B: bfd_stat failed: %E\n", abfd);
59733965Sjdp  global_found = false;
59833965Sjdp  lang_for_each_input_file (gld${EMULATION_NAME}_stat_needed);
59933965Sjdp  if (global_found)
60033965Sjdp    {
60133965Sjdp      /* Return true to indicate that we found the file, even though
60233965Sjdp         we aren't going to do anything with it.  */
60333965Sjdp      return true;
60433965Sjdp    }
60533965Sjdp
60633965Sjdp  /* Tell the ELF backend that don't want the output file to have a
60733965Sjdp     DT_NEEDED entry for this file.  */
60833965Sjdp  bfd_elf_set_dt_needed_name (abfd, "");
60933965Sjdp
61033965Sjdp  /* Add this file into the symbol table.  */
61133965Sjdp  if (! bfd_link_add_symbols (abfd, &link_info))
61233965Sjdp    einfo ("%F%B: could not read symbols: %E\n", abfd);
61333965Sjdp
61433965Sjdp  return true;
61533965Sjdp}
61633965Sjdp
61733965Sjdp/* See if an input file matches a DT_NEEDED entry by name.  */
61833965Sjdp
61933965Sjdpstatic void
62033965Sjdpgld${EMULATION_NAME}_check_needed (s)
62133965Sjdp     lang_input_statement_type *s;
62233965Sjdp{
62333965Sjdp  if (global_found)
62433965Sjdp    return;
62533965Sjdp
62633965Sjdp  if (s->filename != NULL
62733965Sjdp      && strcmp (s->filename, global_needed->name) == 0)
62833965Sjdp    {
62933965Sjdp      global_found = true;
63033965Sjdp      return;
63133965Sjdp    }
63233965Sjdp
63333965Sjdp  if (s->the_bfd != NULL)
63433965Sjdp    {
63533965Sjdp      const char *soname;
63633965Sjdp
63733965Sjdp      soname = bfd_elf_get_dt_soname (s->the_bfd);
63833965Sjdp      if (soname != NULL
63933965Sjdp	  && strcmp (soname, global_needed->name) == 0)
64033965Sjdp	{
64133965Sjdp	  global_found = true;
64233965Sjdp	  return;
64333965Sjdp	}
64433965Sjdp    }
64533965Sjdp	  
64633965Sjdp  if (s->search_dirs_flag
64733965Sjdp      && s->filename != NULL
64833965Sjdp      && strchr (global_needed->name, '/') == NULL)
64933965Sjdp    {
65033965Sjdp      const char *f;
65133965Sjdp
65233965Sjdp      f = strrchr (s->filename, '/');
65333965Sjdp      if (f != NULL
65433965Sjdp	  && strcmp (f + 1, global_needed->name) == 0)
65533965Sjdp	{
65633965Sjdp	  global_found = true;
65733965Sjdp	  return;
65833965Sjdp	}
65933965Sjdp    }
66033965Sjdp}
66133965Sjdp
66233965Sjdp/* See if an input file matches a DT_NEEDED entry by running stat on
66333965Sjdp   the file.  */
66433965Sjdp
66533965Sjdpstatic void
66633965Sjdpgld${EMULATION_NAME}_stat_needed (s)
66733965Sjdp     lang_input_statement_type *s;
66833965Sjdp{
66933965Sjdp  struct stat st;
67033965Sjdp  const char *suffix;
67133965Sjdp  const char *soname;
67233965Sjdp  const char *f;
67333965Sjdp
67433965Sjdp  if (global_found)
67533965Sjdp    return;
67633965Sjdp  if (s->the_bfd == NULL)
67733965Sjdp    return;
67833965Sjdp
67933965Sjdp  if (bfd_stat (s->the_bfd, &st) != 0)
68033965Sjdp    {
68133965Sjdp      einfo ("%P:%B: bfd_stat failed: %E\n", s->the_bfd);
68233965Sjdp      return;
68333965Sjdp    }
68433965Sjdp
68533965Sjdp  if (st.st_dev == global_stat.st_dev
68633965Sjdp      && st.st_ino == global_stat.st_ino)
68733965Sjdp    {
68833965Sjdp      global_found = true;
68933965Sjdp      return;
69033965Sjdp    }
69133965Sjdp
69233965Sjdp  /* We issue a warning if it looks like we are including two
69333965Sjdp     different versions of the same shared library.  For example,
69433965Sjdp     there may be a problem if -lc picks up libc.so.6 but some other
69533965Sjdp     shared library has a DT_NEEDED entry of libc.so.5.  This is a
69633965Sjdp     hueristic test, and it will only work if the name looks like
69733965Sjdp     NAME.so.VERSION.  FIXME: Depending on file names is error-prone.
69833965Sjdp     If we really want to issue warnings about mixing version numbers
69933965Sjdp     of shared libraries, we need to find a better way.  */
70033965Sjdp
70133965Sjdp  if (strchr (global_needed->name, '/') != NULL)
70233965Sjdp    return;
70333965Sjdp  suffix = strstr (global_needed->name, ".so.");
70433965Sjdp  if (suffix == NULL)
70533965Sjdp    return;
70633965Sjdp  suffix += sizeof ".so." - 1;
70733965Sjdp
70833965Sjdp  soname = bfd_elf_get_dt_soname (s->the_bfd);
70933965Sjdp  if (soname == NULL)
71033965Sjdp    soname = s->filename;
71133965Sjdp
71233965Sjdp  f = strrchr (soname, '/');
71333965Sjdp  if (f != NULL)
71433965Sjdp    ++f;
71533965Sjdp  else
71633965Sjdp    f = soname;
71733965Sjdp
71833965Sjdp  if (strncmp (f, global_needed->name, suffix - global_needed->name) == 0)
71933965Sjdp    einfo ("%P: warning: %s, needed by %B, may conflict with %s\n",
72033965Sjdp	   global_needed->name, global_needed->by, f);
72133965Sjdp}
72233965Sjdp
72338889Sjdp/* On Linux, it's possible to have different versions of the same
72438889Sjdp   shared library linked against different versions of libc.  The
72538889Sjdp   dynamic linker somehow tags which libc version to use in
72638889Sjdp   /etc/ld.so.cache, and, based on the libc that it sees in the
72738889Sjdp   executable, chooses which version of the shared library to use.
72838889Sjdp
72938889Sjdp   We try to do a similar check here by checking whether this shared
73038889Sjdp   library needs any other shared libraries which may conflict with
73138889Sjdp   libraries we have already included in the link.  If it does, we
73238889Sjdp   skip it, and try to find another shared library farther on down the
73338889Sjdp   link path.
73438889Sjdp
73538889Sjdp   This is called via lang_for_each_input_file.
73638889Sjdp   GLOBAL_VERCHECK_NEEDED is the list of objects needed by the object
73738889Sjdp   which we ar checking.  This sets GLOBAL_VERCHECK_FAILED if we find
73838889Sjdp   a conflicting version.  */
73938889Sjdp
74038889Sjdpstatic void
74138889Sjdpgld${EMULATION_NAME}_vercheck (s)
74238889Sjdp     lang_input_statement_type *s;
74338889Sjdp{
74438889Sjdp  const char *soname, *f;
74538889Sjdp  struct bfd_link_needed_list *l;
74638889Sjdp
74738889Sjdp  if (global_vercheck_failed)
74838889Sjdp    return;
74938889Sjdp  if (s->the_bfd == NULL
75038889Sjdp      || (bfd_get_file_flags (s->the_bfd) & DYNAMIC) == 0)
75138889Sjdp    return;
75238889Sjdp
75338889Sjdp  soname = bfd_elf_get_dt_soname (s->the_bfd);
75438889Sjdp  if (soname == NULL)
75538889Sjdp    soname = bfd_get_filename (s->the_bfd);
75638889Sjdp
75738889Sjdp  f = strrchr (soname, '/');
75838889Sjdp  if (f != NULL)
75938889Sjdp    ++f;
76038889Sjdp  else
76138889Sjdp    f = soname;
76238889Sjdp
76338889Sjdp  for (l = global_vercheck_needed; l != NULL; l = l->next)
76438889Sjdp    {
76538889Sjdp      const char *suffix;
76638889Sjdp
76738889Sjdp      if (strcmp (f, l->name) == 0)
76838889Sjdp	{
76938889Sjdp	  /* Probably can't happen, but it's an easy check.  */
77038889Sjdp	  continue;
77138889Sjdp	}
77238889Sjdp
77338889Sjdp      if (strchr (l->name, '/') != NULL)
77438889Sjdp	continue;
77538889Sjdp
77638889Sjdp      suffix = strstr (l->name, ".so.");
77738889Sjdp      if (suffix == NULL)
77838889Sjdp	continue;
77938889Sjdp
78038889Sjdp      suffix += sizeof ".so." - 1;
78138889Sjdp
78238889Sjdp      if (strncmp (f, l->name, suffix - l->name) == 0)
78338889Sjdp	{
78438889Sjdp	  /* Here we know that S is a dynamic object FOO.SO.VER1, and
78538889Sjdp             the object we are considering needs a dynamic object
78638889Sjdp             FOO.SO.VER2, and VER1 and VER2 are different.  This
78738889Sjdp             appears to be a version mismatch, so we tell the caller
78838889Sjdp             to try a different version of this library.  */
78938889Sjdp	  global_vercheck_failed = true;
79038889Sjdp	  return;
79138889Sjdp	}
79238889Sjdp    }
79338889Sjdp}
79438889Sjdp
79533965Sjdp/* This is called after the sections have been attached to output
79633965Sjdp   sections, but before any sizes or addresses have been set.  */
79733965Sjdp
79833965Sjdpstatic void
79933965Sjdpgld${EMULATION_NAME}_before_allocation ()
80033965Sjdp{
80133965Sjdp  const char *rpath;
80233965Sjdp  asection *sinterp;
80333965Sjdp
80433965Sjdp  /* If we are going to make any variable assignments, we need to let
80533965Sjdp     the ELF backend know about them in case the variables are
80633965Sjdp     referred to by dynamic objects.  */
80733965Sjdp  lang_for_each_statement (gld${EMULATION_NAME}_find_statement_assignment);
80833965Sjdp
80933965Sjdp  /* Let the ELF backend work out the sizes of any sections required
81033965Sjdp     by dynamic linking.  */
81133965Sjdp  rpath = command_line.rpath;
81233965Sjdp  if (rpath == NULL)
81333965Sjdp    rpath = (const char *) getenv ("LD_RUN_PATH");
81433965Sjdp  if (! (bfd_elf${ELFSIZE}_size_dynamic_sections
81533965Sjdp         (output_bfd, command_line.soname, rpath,
81633965Sjdp	  command_line.export_dynamic, command_line.filter_shlib,
81733965Sjdp	  (const char * const *) command_line.auxiliary_filters,
81833965Sjdp	  &link_info, &sinterp, lang_elf_version_info)))
81933965Sjdp    einfo ("%P%F: failed to set dynamic section sizes: %E\n");
82033965Sjdp
82133965Sjdp  /* Let the user override the dynamic linker we are using.  */
82233965Sjdp  if (command_line.interpreter != NULL
82333965Sjdp      && sinterp != NULL)
82433965Sjdp    {
82533965Sjdp      sinterp->contents = (bfd_byte *) command_line.interpreter;
82633965Sjdp      sinterp->_raw_size = strlen (command_line.interpreter) + 1;
82733965Sjdp    }
82833965Sjdp
82933965Sjdp  /* Look for any sections named .gnu.warning.  As a GNU extensions,
83033965Sjdp     we treat such sections as containing warning messages.  We print
83133965Sjdp     out the warning message, and then zero out the section size so
83233965Sjdp     that it does not get copied into the output file.  */
83333965Sjdp
83433965Sjdp  {
83533965Sjdp    LANG_FOR_EACH_INPUT_STATEMENT (is)
83633965Sjdp      {
83733965Sjdp	asection *s;
83833965Sjdp	bfd_size_type sz;
83933965Sjdp	char *msg;
84033965Sjdp	boolean ret;
84133965Sjdp
84233965Sjdp	if (is->just_syms_flag)
84333965Sjdp	  continue;
84433965Sjdp
84533965Sjdp	s = bfd_get_section_by_name (is->the_bfd, ".gnu.warning");
84633965Sjdp	if (s == NULL)
84733965Sjdp	  continue;
84833965Sjdp
84933965Sjdp	sz = bfd_section_size (is->the_bfd, s);
85033965Sjdp	msg = xmalloc ((size_t) sz + 1);
85133965Sjdp	if (! bfd_get_section_contents (is->the_bfd, s, msg, (file_ptr) 0, sz))
85233965Sjdp	  einfo ("%F%B: Can't read contents of section .gnu.warning: %E\n",
85333965Sjdp		 is->the_bfd);
85433965Sjdp	msg[sz] = '\0';
85533965Sjdp	ret = link_info.callbacks->warning (&link_info, msg,
85633965Sjdp					    (const char *) NULL,
85733965Sjdp					    is->the_bfd, (asection *) NULL,
85833965Sjdp					    (bfd_vma) 0);
85933965Sjdp	ASSERT (ret);
86033965Sjdp	free (msg);
86133965Sjdp
86233965Sjdp	/* Clobber the section size, so that we don't waste copying the
86333965Sjdp	   warning into the output file.  */
86433965Sjdp	s->_raw_size = 0;
86533965Sjdp      }
86633965Sjdp  }
86733965Sjdp}
86833965Sjdp
86933965Sjdp/* This is called by the before_allocation routine via
87033965Sjdp   lang_for_each_statement.  It locates any assignment statements, and
87133965Sjdp   tells the ELF backend about them, in case they are assignments to
87233965Sjdp   symbols which are referred to by dynamic objects.  */
87333965Sjdp
87433965Sjdpstatic void
87533965Sjdpgld${EMULATION_NAME}_find_statement_assignment (s)
87633965Sjdp     lang_statement_union_type *s;
87733965Sjdp{
87833965Sjdp  if (s->header.type == lang_assignment_statement_enum)
87933965Sjdp    gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp);
88033965Sjdp}
88133965Sjdp
88233965Sjdp/* Look through an expression for an assignment statement.  */
88333965Sjdp
88433965Sjdpstatic void
88533965Sjdpgld${EMULATION_NAME}_find_exp_assignment (exp)
88633965Sjdp     etree_type *exp;
88733965Sjdp{
88833965Sjdp  struct bfd_link_hash_entry *h;
88933965Sjdp
89033965Sjdp  switch (exp->type.node_class)
89133965Sjdp    {
89233965Sjdp    case etree_provide:
89333965Sjdp      h = bfd_link_hash_lookup (link_info.hash, exp->assign.dst,
89433965Sjdp				false, false, false);
89533965Sjdp      if (h == NULL)
89633965Sjdp	break;
89733965Sjdp
89833965Sjdp      /* We call record_link_assignment even if the symbol is defined.
89933965Sjdp	 This is because if it is defined by a dynamic object, we
90033965Sjdp	 actually want to use the value defined by the linker script,
90133965Sjdp	 not the value from the dynamic object (because we are setting
90233965Sjdp	 symbols like etext).  If the symbol is defined by a regular
90333965Sjdp	 object, then, as it happens, calling record_link_assignment
90433965Sjdp	 will do no harm.  */
90533965Sjdp
90633965Sjdp      /* Fall through.  */
90733965Sjdp    case etree_assign:
90833965Sjdp      if (strcmp (exp->assign.dst, ".") != 0)
90933965Sjdp	{
91033965Sjdp	  if (! (bfd_elf${ELFSIZE}_record_link_assignment
91133965Sjdp		 (output_bfd, &link_info, exp->assign.dst,
91233965Sjdp		  exp->type.node_class == etree_provide ? true : false)))
91333965Sjdp	    einfo ("%P%F: failed to record assignment to %s: %E\n",
91433965Sjdp		   exp->assign.dst);
91533965Sjdp	}
91633965Sjdp      gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src);
91733965Sjdp      break;
91833965Sjdp
91933965Sjdp    case etree_binary:
92033965Sjdp      gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs);
92133965Sjdp      gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs);
92233965Sjdp      break;
92333965Sjdp
92433965Sjdp    case etree_trinary:
92533965Sjdp      gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.cond);
92633965Sjdp      gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs);
92733965Sjdp      gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs);
92833965Sjdp      break;
92933965Sjdp
93033965Sjdp    case etree_unary:
93133965Sjdp      gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child);
93233965Sjdp      break;
93333965Sjdp
93433965Sjdp    default:
93533965Sjdp      break;
93633965Sjdp    }
93733965Sjdp}
93833965Sjdp
93968778Sobrien/* A variant of lang_output_section_find.  Used by place_orphan.  */
94068778Sobrien
94168778Sobrienstatic lang_output_section_statement_type *
94268778Sobrienoutput_rel_find ()
94368778Sobrien{
94468778Sobrien  lang_statement_union_type *u;
94568778Sobrien  lang_output_section_statement_type *lookup;
94668778Sobrien
94768778Sobrien  for (u = lang_output_section_statement.head;
94868778Sobrien       u != (lang_statement_union_type *) NULL;
94968778Sobrien       u = lookup->next)
95068778Sobrien    {
95168778Sobrien      lookup = &u->output_section_statement;
95268778Sobrien      if (strncmp (".rel", lookup->name, 4) == 0
95368778Sobrien	  && lookup->bfd_section != NULL
95468778Sobrien	  && (lookup->bfd_section->flags & SEC_ALLOC) != 0)
95568778Sobrien	{
95668778Sobrien	  return lookup;
95768778Sobrien	}
95868778Sobrien    }
95968778Sobrien  return (lang_output_section_statement_type *) NULL;
96068778Sobrien}
96168778Sobrien
96233965Sjdp/* Place an orphan section.  We use this to put random SHF_ALLOC
96333965Sjdp   sections in the right segment.  */
96433965Sjdp
96568778Sobrienstruct orphan_save {
96668778Sobrien  lang_output_section_statement_type *os;
96768778Sobrien  asection **section;
96868778Sobrien  lang_statement_union_type **stmt;
96968778Sobrien};
97033965Sjdp
97133965Sjdpstatic boolean
97233965Sjdpgld${EMULATION_NAME}_place_orphan (file, s)
97333965Sjdp     lang_input_statement_type *file;
97433965Sjdp     asection *s;
97533965Sjdp{
97668778Sobrien  static struct orphan_save hold_text;
97768778Sobrien  static struct orphan_save hold_rodata;
97868778Sobrien  static struct orphan_save hold_data;
97968778Sobrien  static struct orphan_save hold_bss;
98068778Sobrien  static struct orphan_save hold_rel;
98168778Sobrien  static struct orphan_save hold_interp;
98268778Sobrien  struct orphan_save *place;
98333965Sjdp  lang_statement_list_type *old;
98433965Sjdp  lang_statement_list_type add;
98533965Sjdp  etree_type *address;
98668778Sobrien  const char *secname;
98733965Sjdp  const char *outsecname;
98868778Sobrien  const char *ps = NULL;
98933965Sjdp  lang_output_section_statement_type *os;
99033965Sjdp
99168778Sobrien  secname = bfd_get_section_name (s->owner, s);
99233965Sjdp
99368778Sobrien  /* Look through the script to see where to place this section.  */ 
99468778Sobrien  os = lang_output_section_find (secname);
99533965Sjdp
99668778Sobrien  if (os != NULL
99768778Sobrien      && os->bfd_section != NULL
99868778Sobrien      && ((s->flags ^ os->bfd_section->flags) & (SEC_LOAD | SEC_ALLOC)) == 0)
99933965Sjdp    {
100033965Sjdp      /* We have already placed a section with this name.  */
100168778Sobrien      wild_doit (&os->children, s, os, file);
100233965Sjdp      return true;
100333965Sjdp    }
100433965Sjdp
100568778Sobrien  if (hold_text.os == NULL)
100668778Sobrien    hold_text.os = lang_output_section_find (".text");
100733965Sjdp
100833965Sjdp  /* If this is a final link, then always put .gnu.warning.SYMBOL
100933965Sjdp     sections into the .text section to get them out of the way.  */
101033965Sjdp  if (! link_info.shared
101133965Sjdp      && ! link_info.relocateable
101233965Sjdp      && strncmp (secname, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0
101368778Sobrien      && hold_text.os != NULL)
101433965Sjdp    {
101568778Sobrien      wild_doit (&hold_text.os->children, s, hold_text.os, file);
101633965Sjdp      return true;
101733965Sjdp    }
101833965Sjdp
101933965Sjdp  /* Decide which segment the section should go in based on the
102033965Sjdp     section name and section flags.  We put loadable .note sections
102133965Sjdp     right after the .interp section, so that the PT_NOTE segment is
102233965Sjdp     stored right after the program headers where the OS can read it
102333965Sjdp     in the first page.  */
102468778Sobrien#define HAVE_SECTION(hold, name) \
102568778Sobrien(hold.os != NULL || (hold.os = lang_output_section_find (name)) != NULL)
102668778Sobrien
102760525Sobrien  if (s->flags & SEC_EXCLUDE)
102860525Sobrien    return false;
102968778Sobrien
103068778Sobrien  place = NULL;
103168778Sobrien  if ((s->flags & SEC_ALLOC) == 0)
103268778Sobrien    ;
103360525Sobrien  else if ((s->flags & SEC_LOAD) != 0
103468778Sobrien	   && strncmp (secname, ".note", 4) == 0
103568778Sobrien	   && HAVE_SECTION (hold_interp, ".interp"))
103668778Sobrien    place = &hold_interp;
103733965Sjdp  else if ((s->flags & SEC_HAS_CONTENTS) == 0
103868778Sobrien	   && HAVE_SECTION (hold_bss, ".bss"))
103968778Sobrien    place = &hold_bss;
104033965Sjdp  else if ((s->flags & SEC_READONLY) == 0
104168778Sobrien	   && HAVE_SECTION (hold_data, ".data"))
104268778Sobrien    place = &hold_data;
104333965Sjdp  else if (strncmp (secname, ".rel", 4) == 0
104468778Sobrien	   && (hold_rel.os != NULL
104568778Sobrien	       || (hold_rel.os = output_rel_find ()) != NULL))
104668778Sobrien    place = &hold_rel;
104768778Sobrien  else if ((s->flags & (SEC_CODE | SEC_READONLY)) == SEC_READONLY
104868778Sobrien	   && HAVE_SECTION (hold_rodata, ".rodata"))
104968778Sobrien    place = &hold_rodata;
105068778Sobrien  else if ((s->flags & (SEC_CODE | SEC_READONLY)) == (SEC_CODE | SEC_READONLY)
105168778Sobrien	   && hold_text.os != NULL)
105268778Sobrien    place = &hold_text;
105333965Sjdp
105468778Sobrien#undef HAVE_SECTION
105568778Sobrien
105633965Sjdp  /* Choose a unique name for the section.  This will be needed if the
105733965Sjdp     same section name appears in the input file with different
105833965Sjdp     loadable or allocateable characteristics.  */
105933965Sjdp  outsecname = secname;
106033965Sjdp  if (bfd_get_section_by_name (output_bfd, outsecname) != NULL)
106133965Sjdp    {
106233965Sjdp      unsigned int len;
106333965Sjdp      char *newname;
106433965Sjdp      unsigned int i;
106533965Sjdp
106633965Sjdp      len = strlen (outsecname);
106733965Sjdp      newname = xmalloc (len + 5);
106833965Sjdp      strcpy (newname, outsecname);
106933965Sjdp      i = 0;
107033965Sjdp      do
107133965Sjdp	{
107233965Sjdp	  sprintf (newname + len, "%d", i);
107333965Sjdp	  ++i;
107433965Sjdp	}
107533965Sjdp      while (bfd_get_section_by_name (output_bfd, newname) != NULL);
107633965Sjdp
107733965Sjdp      outsecname = newname;
107833965Sjdp    }
107933965Sjdp
108068778Sobrien  /* Start building a list of statements for this section.
108168778Sobrien     First save the current statement pointer.  */
108268778Sobrien  old = stat_ptr;
108368778Sobrien
108468778Sobrien  /* If we have found an appropriate place for the output section
108568778Sobrien     statements for this orphan, add them to our own private list,
108668778Sobrien     inserting them later into the global statement list.  */
108768778Sobrien  if (place != NULL)
108833965Sjdp    {
108968778Sobrien      stat_ptr = &add;
109068778Sobrien      lang_list_init (stat_ptr);
109133965Sjdp    }
109233965Sjdp
109368778Sobrien  if (config.build_constructors)
109433965Sjdp    {
109568778Sobrien      /* If the name of the section is representable in C, then create
109668778Sobrien	 symbols to mark the start and the end of the section.  */
109768778Sobrien      for (ps = outsecname; *ps != '\0'; ps++)
109868778Sobrien	if (! isalnum ((unsigned char) *ps) && *ps != '_')
109968778Sobrien	  break;
110068778Sobrien      if (*ps == '\0')
110168778Sobrien	{
110268778Sobrien	  char *symname;
110368778Sobrien	  etree_type *e_align;
110433965Sjdp
110568778Sobrien	  symname = (char *) xmalloc (ps - outsecname + sizeof "__start_");
110668778Sobrien	  sprintf (symname, "__start_%s", outsecname);
110768778Sobrien	  e_align = exp_unop (ALIGN_K,
110868778Sobrien			      exp_intop ((bfd_vma) 1 << s->alignment_power));
110968778Sobrien	  lang_add_assignment (exp_assop ('=', symname, e_align));
111068778Sobrien	}
111133965Sjdp    }
111233965Sjdp
111368778Sobrien  if (link_info.relocateable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0)
111468778Sobrien    address = exp_intop ((bfd_vma) 0);
111568778Sobrien  else
111633965Sjdp    address = NULL;
111733965Sjdp
111868778Sobrien  os = lang_enter_output_section_statement (outsecname, address, 0,
111968778Sobrien					    (bfd_vma) 0,
112068778Sobrien					    (etree_type *) NULL,
112168778Sobrien					    (etree_type *) NULL,
112268778Sobrien					    (etree_type *) NULL);
112333965Sjdp
112433965Sjdp  wild_doit (&os->children, s, os, file);
112533965Sjdp
112633965Sjdp  lang_leave_output_section_statement
112768778Sobrien    ((bfd_vma) 0, "*default*",
112868778Sobrien     (struct lang_output_section_phdr_list *) NULL, "*default*");
112933965Sjdp
113068778Sobrien  if (config.build_constructors && *ps == '\0')
113133965Sjdp    {
113233965Sjdp      char *symname;
113333965Sjdp
113468778Sobrien      /* lang_leave_ouput_section_statement resets stat_ptr.  Put
113568778Sobrien	 stat_ptr back where we want it.  */
113668778Sobrien      if (place != NULL)
113768778Sobrien	stat_ptr = &add;
113868778Sobrien
113933965Sjdp      symname = (char *) xmalloc (ps - outsecname + sizeof "__stop_");
114033965Sjdp      sprintf (symname, "__stop_%s", outsecname);
114133965Sjdp      lang_add_assignment (exp_assop ('=', symname,
114233965Sjdp				      exp_nameop (NAME, ".")));
114333965Sjdp    }
114433965Sjdp
114568778Sobrien  /* Restore the global list pointer.  */
114633965Sjdp  stat_ptr = old;
114733965Sjdp
114868778Sobrien  if (place != NULL)
114968778Sobrien    {
115068778Sobrien      asection *snew, **pps;
115133965Sjdp
115268778Sobrien      snew = os->bfd_section;
115368778Sobrien      if (place->section != NULL
115468778Sobrien	  || (place->os->bfd_section != NULL
115568778Sobrien	      && place->os->bfd_section != snew))
115668778Sobrien	{
115768778Sobrien	  /* Shuffle the section to make the output file look neater.
115868778Sobrien	     This is really only cosmetic.  */
115968778Sobrien	  if (place->section == NULL)
116068778Sobrien	    {
116168778Sobrien#if 0
116268778Sobrien	      /* Finding the end of the list is a little tricky.  We
116368778Sobrien		 make a wild stab at it by comparing section flags.  */
116468778Sobrien	      flagword first_flags = place->os->bfd_section->flags;
116568778Sobrien	      for (pps = &place->os->bfd_section->next;
116668778Sobrien		   *pps != NULL && (*pps)->flags == first_flags;
116768778Sobrien		   pps = &(*pps)->next)
116868778Sobrien		;
116968778Sobrien	      place->section = pps;
117068778Sobrien#else
117168778Sobrien	      /* Put orphans after the first section on the list.  */
117268778Sobrien	      place->section = &place->os->bfd_section->next;
117368778Sobrien#endif
117468778Sobrien	    }
117533965Sjdp
117668778Sobrien	  /*  Unlink the section.  */
117768778Sobrien	  for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
117868778Sobrien	    ;
117968778Sobrien	  *pps = snew->next;
118033965Sjdp
118168778Sobrien	  /* Now tack it on to the "place->os" section list.  */
118268778Sobrien	  snew->next = *place->section;
118368778Sobrien	  *place->section = snew;
118468778Sobrien	}
118568778Sobrien      place->section = &snew->next;	/* Save the end of this list.  */
118633965Sjdp
118768778Sobrien      if (add.head != NULL)
118868778Sobrien	{
118968778Sobrien	  /* We try to put the output statements in some sort of
119068778Sobrien	     reasonable order here, because they determine the final
119168778Sobrien	     load addresses of the orphan sections.  */
119268778Sobrien	  if (place->stmt == NULL)
119368778Sobrien	    {
119468778Sobrien	      /* Put the new statement list right at the head.  */
119568778Sobrien	      *add.tail = place->os->header.next;
119668778Sobrien	      place->os->header.next = add.head;
119768778Sobrien	    }
119868778Sobrien	  else
119968778Sobrien	    {
120068778Sobrien	      /* Put it after the last orphan statement we added.  */
120168778Sobrien	      *add.tail = *place->stmt;
120268778Sobrien	      *place->stmt = add.head;
120368778Sobrien	    }
120433965Sjdp
120568778Sobrien	  /* Fix the global list pointer if we happened to tack our
120668778Sobrien	     new list at the tail.  */
120768778Sobrien	  if (*old->tail == add.head)
120868778Sobrien	    old->tail = add.tail;
120968778Sobrien
121068778Sobrien	  /* Save the end of this list.  */
121168778Sobrien	  place->stmt = add.tail;
121268778Sobrien	}
121368778Sobrien    }
121468778Sobrien
121568778Sobrien  return true;
121633965Sjdp}
121733965Sjdp
121833965Sjdpstatic char *
121933965Sjdpgld${EMULATION_NAME}_get_script(isfile)
122033965Sjdp     int *isfile;
122133965SjdpEOF
122233965Sjdp
122333965Sjdpif test -n "$COMPILE_IN"
122433965Sjdpthen
122533965Sjdp# Scripts compiled in.
122633965Sjdp
122733965Sjdp# sed commands to quote an ld script as a C string.
122860525Sobriensc="-f stringify.sed"
122933965Sjdp
123033965Sjdpcat >>e${EMULATION_NAME}.c <<EOF
123133965Sjdp{			     
123233965Sjdp  *isfile = 0;
123333965Sjdp
123433965Sjdp  if (link_info.relocateable == true && config.build_constructors == true)
123560525Sobrien    return
123633965SjdpEOF
123760525Sobriensed $sc ldscripts/${EMULATION_NAME}.xu                     >> e${EMULATION_NAME}.c
123860525Sobrienecho '  ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c
123960525Sobriensed $sc ldscripts/${EMULATION_NAME}.xr                     >> e${EMULATION_NAME}.c
124060525Sobrienecho '  ; else if (!config.text_read_only) return'         >> e${EMULATION_NAME}.c
124160525Sobriensed $sc ldscripts/${EMULATION_NAME}.xbn                    >> e${EMULATION_NAME}.c
124260525Sobrienecho '  ; else if (!config.magic_demand_paged) return'     >> e${EMULATION_NAME}.c
124360525Sobriensed $sc ldscripts/${EMULATION_NAME}.xn                     >> e${EMULATION_NAME}.c
124433965Sjdp
124560525Sobrienif test -n "$GENERATE_SHLIB_SCRIPT" ; then
124660525Sobrienecho '  ; else if (link_info.shared) return'		   >> e${EMULATION_NAME}.c
124760525Sobriensed $sc ldscripts/${EMULATION_NAME}.xs                     >> e${EMULATION_NAME}.c
124860525Sobrienfi
124960525Sobrien
125060525Sobrienecho '  ; else return'                                     >> e${EMULATION_NAME}.c
125160525Sobriensed $sc ldscripts/${EMULATION_NAME}.x                      >> e${EMULATION_NAME}.c
125260525Sobrienecho '; }'                                                 >> e${EMULATION_NAME}.c
125360525Sobrien
125433965Sjdpelse
125533965Sjdp# Scripts read from the filesystem.
125633965Sjdp
125733965Sjdpcat >>e${EMULATION_NAME}.c <<EOF
125833965Sjdp{			     
125933965Sjdp  *isfile = 1;
126033965Sjdp
126133965Sjdp  if (link_info.relocateable == true && config.build_constructors == true)
126233965Sjdp    return "ldscripts/${EMULATION_NAME}.xu";
126333965Sjdp  else if (link_info.relocateable == true)
126433965Sjdp    return "ldscripts/${EMULATION_NAME}.xr";
126533965Sjdp  else if (!config.text_read_only)
126633965Sjdp    return "ldscripts/${EMULATION_NAME}.xbn";
126733965Sjdp  else if (!config.magic_demand_paged)
126833965Sjdp    return "ldscripts/${EMULATION_NAME}.xn";
126933965Sjdp  else if (link_info.shared)
127033965Sjdp    return "ldscripts/${EMULATION_NAME}.xs";
127133965Sjdp  else
127233965Sjdp    return "ldscripts/${EMULATION_NAME}.x";
127333965Sjdp}
127433965SjdpEOF
127533965Sjdp
127633965Sjdpfi
127733965Sjdp
127860525Sobrienif test -n "$PARSE_AND_LIST_ARGS" ; then
127933965Sjdpcat >>e${EMULATION_NAME}.c <<EOF
128060525Sobrienstatic int  gld_${EMULATION_NAME}_parse_args PARAMS ((int, char **));
128160525Sobrienstatic void gld_${EMULATION_NAME}_list_options PARAMS ((FILE * file));
128233965Sjdp
128360525Sobrien $PARSE_AND_LIST_ARGS
128460525SobrienEOF
128560525Sobrienelse
128660525Sobrien
128760525Sobriencat >>e${EMULATION_NAME}.c <<EOF
128860525Sobrien#define gld_${EMULATION_NAME}_parse_args   NULL
128960525Sobrien#define gld_${EMULATION_NAME}_list_options NULL
129060525SobrienEOF
129160525Sobrien
129260525Sobrienfi
129360525Sobrien
129460525Sobriencat >>e${EMULATION_NAME}.c <<EOF
129560525Sobrien
129633965Sjdpstruct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = 
129733965Sjdp{
129833965Sjdp  gld${EMULATION_NAME}_before_parse,
129933965Sjdp  syslib_default,
130033965Sjdp  hll_default,
130133965Sjdp  after_parse_default,
130233965Sjdp  gld${EMULATION_NAME}_after_open,
130333965Sjdp  after_allocation_default,
130433965Sjdp  set_output_arch_default,
130533965Sjdp  ldemul_default_target,
130633965Sjdp  gld${EMULATION_NAME}_before_allocation,
130733965Sjdp  gld${EMULATION_NAME}_get_script,
130833965Sjdp  "${EMULATION_NAME}",
130933965Sjdp  "${OUTPUT_FORMAT}",
131060525Sobrien  NULL, 	/* finish */
131160525Sobrien  NULL, 	/* create output section statements */
131233965Sjdp  gld${EMULATION_NAME}_open_dynamic_archive,
131360525Sobrien  gld${EMULATION_NAME}_place_orphan,
131460525Sobrien  NULL,		/* set_symbols */
131560525Sobrien  gld_${EMULATION_NAME}_parse_args,
131660525Sobrien  NULL,		/* unrecognized_file */
131760525Sobrien  gld_${EMULATION_NAME}_list_options,
131860525Sobrien  NULL,		/* recognized_file */
131960525Sobrien  NULL		/* find_potential_libraries */
132033965Sjdp};
132133965SjdpEOF
1322