elf32.em revision 42372
133965Sjdp# This shell script emits a C file. -*- C -*-
233965Sjdp# It does some substitutions.
333965Sjdp# This file is now misnamed, because it supports both 32 bit and 64 bit
433965Sjdp# ELF emulations.
533965Sjdptest -z "${ELFSIZE}" && ELFSIZE=32
633965Sjdpcat >e${EMULATION_NAME}.c <<EOF
733965Sjdp/* This file is is generated by a shell script.  DO NOT EDIT! */
833965Sjdp
933965Sjdp/* ${ELFSIZE} bit ELF emulation code for ${EMULATION_NAME}
1038889Sjdp   Copyright (C) 1991, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
1133965Sjdp   Written by Steve Chamberlain <sac@cygnus.com>
1233965Sjdp   ELF support by Ian Lance Taylor <ian@cygnus.com>
1333965Sjdp
1433965SjdpThis file is part of GLD, the Gnu Linker.
1533965Sjdp
1633965SjdpThis program is free software; you can redistribute it and/or modify
1733965Sjdpit under the terms of the GNU General Public License as published by
1833965Sjdpthe Free Software Foundation; either version 2 of the License, or
1933965Sjdp(at your option) any later version.
2033965Sjdp
2133965SjdpThis program is distributed in the hope that it will be useful,
2233965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of
2333965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2433965SjdpGNU General Public License for more details.
2533965Sjdp
2633965SjdpYou should have received a copy of the GNU General Public License
2733965Sjdpalong with this program; if not, write to the Free Software
2833965SjdpFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
2933965Sjdp
3033965Sjdp#define TARGET_IS_${EMULATION_NAME}
3133965Sjdp
3233965Sjdp#include "bfd.h"
3333965Sjdp#include "sysdep.h"
3433965Sjdp
3533965Sjdp#include <ctype.h>
3633965Sjdp
3733965Sjdp#include "bfdlink.h"
3833965Sjdp
3933965Sjdp#include "ld.h"
4033965Sjdp#include "ldmain.h"
4133965Sjdp#include "ldemul.h"
4233965Sjdp#include "ldfile.h"
4333965Sjdp#include "ldmisc.h"
4433965Sjdp#include "ldexp.h"
4533965Sjdp#include "ldlang.h"
4633965Sjdp#include "ldgram.h"
4733965Sjdp
4833965Sjdpstatic void gld${EMULATION_NAME}_before_parse PARAMS ((void));
4933965Sjdpstatic boolean gld${EMULATION_NAME}_open_dynamic_archive
5033965Sjdp  PARAMS ((const char *, search_dirs_type *, lang_input_statement_type *));
5133965Sjdpstatic void gld${EMULATION_NAME}_after_open PARAMS ((void));
5233965Sjdpstatic void gld${EMULATION_NAME}_check_needed
5333965Sjdp  PARAMS ((lang_input_statement_type *));
5433965Sjdpstatic void gld${EMULATION_NAME}_stat_needed
5533965Sjdp  PARAMS ((lang_input_statement_type *));
5633965Sjdpstatic boolean gld${EMULATION_NAME}_search_needed
5738889Sjdp  PARAMS ((const char *, const char *, int));
5838889Sjdpstatic boolean gld${EMULATION_NAME}_try_needed PARAMS ((const char *, int));
5938889Sjdpstatic void gld${EMULATION_NAME}_vercheck
6038889Sjdp  PARAMS ((lang_input_statement_type *));
6133965Sjdpstatic void gld${EMULATION_NAME}_before_allocation PARAMS ((void));
6233965Sjdpstatic void gld${EMULATION_NAME}_find_statement_assignment
6333965Sjdp  PARAMS ((lang_statement_union_type *));
6433965Sjdpstatic void gld${EMULATION_NAME}_find_exp_assignment PARAMS ((etree_type *));
6533965Sjdpstatic boolean gld${EMULATION_NAME}_place_orphan
6633965Sjdp  PARAMS ((lang_input_statement_type *, asection *));
6733965Sjdpstatic void gld${EMULATION_NAME}_place_section
6833965Sjdp  PARAMS ((lang_statement_union_type *));
6933965Sjdpstatic char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
7033965Sjdp
7133965Sjdpstatic void
7233965Sjdpgld${EMULATION_NAME}_before_parse()
7333965Sjdp{
7433965Sjdp  ldfile_output_architecture = bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`;
7533965Sjdp  config.dynamic_link = ${DYNAMIC_LINK-true};
7633965Sjdp}
7733965Sjdp
7833965Sjdp/* Try to open a dynamic archive.  This is where we know that ELF
7933965Sjdp   dynamic libraries have an extension of .so.  */
8033965Sjdp
8133965Sjdpstatic boolean
8233965Sjdpgld${EMULATION_NAME}_open_dynamic_archive (arch, search, entry)
8333965Sjdp     const char *arch;
8433965Sjdp     search_dirs_type *search;
8533965Sjdp     lang_input_statement_type *entry;
8633965Sjdp{
8733965Sjdp  const char *filename;
8833965Sjdp  char *string;
8933965Sjdp
9033965Sjdp  if (! entry->is_archive)
9133965Sjdp    return false;
9233965Sjdp
9333965Sjdp  filename = entry->filename;
9433965Sjdp
9533965Sjdp  string = (char *) xmalloc (strlen (search->name)
9633965Sjdp			     + strlen (filename)
9733965Sjdp			     + strlen (arch)
9833965Sjdp			     + sizeof "/lib.so");
9933965Sjdp
10033965Sjdp  sprintf (string, "%s/lib%s%s.so", search->name, filename, arch);
10133965Sjdp
10233965Sjdp  if (! ldfile_try_open_bfd (string, entry))
10333965Sjdp    {
10433965Sjdp      free (string);
10533965Sjdp      return false;
10633965Sjdp    }
10733965Sjdp
10833965Sjdp  entry->filename = string;
10933965Sjdp
11033965Sjdp  /* We have found a dynamic object to include in the link.  The ELF
11133965Sjdp     backend linker will create a DT_NEEDED entry in the .dynamic
11233965Sjdp     section naming this file.  If this file includes a DT_SONAME
11333965Sjdp     entry, it will be used.  Otherwise, the ELF linker will just use
11433965Sjdp     the name of the file.  For an archive found by searching, like
11533965Sjdp     this one, the DT_NEEDED entry should consist of just the name of
11633965Sjdp     the file, without the path information used to find it.  Note
11733965Sjdp     that we only need to do this if we have a dynamic object; an
11833965Sjdp     archive will never be referenced by a DT_NEEDED entry.
11933965Sjdp
12033965Sjdp     FIXME: This approach--using bfd_elf_set_dt_needed_name--is not
12133965Sjdp     very pretty.  I haven't been able to think of anything that is
12233965Sjdp     pretty, though.  */
12333965Sjdp  if (bfd_check_format (entry->the_bfd, bfd_object)
12433965Sjdp      && (entry->the_bfd->flags & DYNAMIC) != 0)
12533965Sjdp    {
12633965Sjdp      char *needed_name;
12733965Sjdp
12833965Sjdp      ASSERT (entry->is_archive && entry->search_dirs_flag);
12933965Sjdp      needed_name = (char *) xmalloc (strlen (filename)
13033965Sjdp				      + strlen (arch)
13133965Sjdp				      + sizeof "lib.so");
13233965Sjdp      sprintf (needed_name, "lib%s%s.so", filename, arch);
13333965Sjdp      bfd_elf_set_dt_needed_name (entry->the_bfd, needed_name);
13433965Sjdp    }
13533965Sjdp
13633965Sjdp  return true;
13733965Sjdp}
13833965Sjdp
13933965SjdpEOF
14033965Sjdpif [ "x${host}" = "x${target}" ] ; then
14133965Sjdp  if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then
14242372Speter    case ${target} in
14342372Speter      *-*-freebsd*)
14442372Speter	cat >>e${EMULATION_NAME}.c <<EOF
14542372Speter/*
14642372Speter * Read the system search path the FreeBSD way rather than like Linux.
14742372Speter */
14842372Speter#include <elf.h>
14933965Sjdp
15042372Speterstatic boolean gld${EMULATION_NAME}_check_ld_elf_hints
15142372Speter  PARAMS ((const char *, int));
15242372Speter
15342372Speterstatic boolean
15442372Spetergld${EMULATION_NAME}_check_ld_elf_hints (name, force)
15542372Speter     const char *name;
15642372Speter     int force;
15742372Speter{
15842372Speter  static boolean initialized;
15942372Speter  static char *ld_elf_hints;
16042372Speter
16142372Speter  if (! initialized)
16242372Speter    {
16342372Speter      FILE *f;
16442372Speter
16542372Speter      f = fopen (_PATH_ELF_HINTS, FOPEN_RB);
16642372Speter      if (f != NULL)
16742372Speter	{
16842372Speter	  struct elfhints_hdr hdr;
16942372Speter
17042372Speter	  if (fread(&hdr, 1, sizeof(hdr), f) == sizeof(hdr) &&
17142372Speter	      hdr.magic == ELFHINTS_MAGIC &&
17242372Speter	      hdr.version == 1)
17342372Speter	    {
17442372Speter	      if (fseek(f, hdr.strtab + hdr.dirlist, SEEK_SET) != -1)
17542372Speter		{
17642372Speter		  char *b;
17742372Speter
17842372Speter		  b = (char *) xmalloc (hdr.dirlistlen + 1);
17942372Speter		  if (fread(b, 1, hdr.dirlistlen + 1, f) !=
18042372Speter		      hdr.dirlistlen + 1)
18142372Speter		    {
18242372Speter		      free(b);
18342372Speter		    }
18442372Speter		  else
18542372Speter		    {
18642372Speter		      ld_elf_hints = b;
18742372Speter		    }
18842372Speter		}
18942372Speter	    }
19042372Speter	  fclose (f);
19142372Speter	}
19242372Speter
19342372Speter      initialized = true;
19442372Speter    }
19542372Speter
19642372Speter  if (ld_elf_hints == NULL)
19742372Speter    return false;
19842372Speter
19942372Speter  return gld${EMULATION_NAME}_search_needed (ld_elf_hints, name, force);
20042372Speter}
20142372SpeterEOF
20242372Speter	;;
20342372Speter      *)
20442372Speter	cat >>e${EMULATION_NAME}.c <<EOF
20533965Sjdp/* For a native linker, check the file /etc/ld.so.conf for directories
20633965Sjdp   in which we may find shared libraries.  /etc/ld.so.conf is really
20733965Sjdp   only meaningful on Linux, but we check it on other systems anyhow.  */
20833965Sjdp
20938889Sjdpstatic boolean gld${EMULATION_NAME}_check_ld_so_conf
21038889Sjdp  PARAMS ((const char *, int));
21133965Sjdp
21233965Sjdpstatic boolean
21338889Sjdpgld${EMULATION_NAME}_check_ld_so_conf (name, force)
21433965Sjdp     const char *name;
21538889Sjdp     int force;
21633965Sjdp{
21733965Sjdp  static boolean initialized;
21833965Sjdp  static char *ld_so_conf;
21933965Sjdp
22033965Sjdp  if (! initialized)
22133965Sjdp    {
22233965Sjdp      FILE *f;
22333965Sjdp
22433965Sjdp      f = fopen ("/etc/ld.so.conf", FOPEN_RT);
22533965Sjdp      if (f != NULL)
22633965Sjdp	{
22733965Sjdp	  char *b;
22833965Sjdp	  size_t len, alloc;
22933965Sjdp	  int c;
23033965Sjdp
23133965Sjdp	  len = 0;
23233965Sjdp	  alloc = 100;
23333965Sjdp	  b = (char *) xmalloc (alloc);
23433965Sjdp
23533965Sjdp	  while ((c = getc (f)) != EOF)
23633965Sjdp	    {
23733965Sjdp	      if (len + 1 >= alloc)
23833965Sjdp		{
23933965Sjdp		  alloc *= 2;
24033965Sjdp		  b = (char *) xrealloc (b, alloc);
24133965Sjdp		}
24233965Sjdp	      if (c != ':'
24333965Sjdp		  && c != ' '
24433965Sjdp		  && c != '\t'
24533965Sjdp		  && c != '\n'
24633965Sjdp		  && c != ',')
24733965Sjdp		{
24833965Sjdp		  b[len] = c;
24933965Sjdp		  ++len;
25033965Sjdp		}
25133965Sjdp	      else
25233965Sjdp		{
25333965Sjdp		  if (len > 0 && b[len - 1] != ':')
25433965Sjdp		    {
25533965Sjdp		      b[len] = ':';
25633965Sjdp		      ++len;
25733965Sjdp		    }
25833965Sjdp		}
25933965Sjdp	    }
26033965Sjdp
26133965Sjdp	  if (len > 0 && b[len - 1] == ':')
26233965Sjdp	    --len;
26333965Sjdp
26433965Sjdp	  if (len > 0)
26533965Sjdp	    b[len] = '\0';
26633965Sjdp	  else
26733965Sjdp	    {
26833965Sjdp	      free (b);
26933965Sjdp	      b = NULL;
27033965Sjdp	    }
27133965Sjdp
27233965Sjdp	  fclose (f);
27333965Sjdp
27433965Sjdp	  ld_so_conf = b;
27533965Sjdp	}
27633965Sjdp
27733965Sjdp      initialized = true;
27833965Sjdp    }
27933965Sjdp
28033965Sjdp  if (ld_so_conf == NULL)
28133965Sjdp    return false;
28233965Sjdp
28338889Sjdp  return gld${EMULATION_NAME}_search_needed (ld_so_conf, name, force);
28433965Sjdp}
28533965SjdpEOF
28642372Speter    esac
28733965Sjdp  fi
28833965Sjdpfi
28933965Sjdpcat >>e${EMULATION_NAME}.c <<EOF
29033965Sjdp
29133965Sjdp/* These variables are required to pass information back and forth
29238889Sjdp   between after_open and check_needed and stat_needed and vercheck.  */
29333965Sjdp
29433965Sjdpstatic struct bfd_link_needed_list *global_needed;
29533965Sjdpstatic struct stat global_stat;
29633965Sjdpstatic boolean global_found;
29738889Sjdpstatic struct bfd_link_needed_list *global_vercheck_needed;
29838889Sjdpstatic boolean global_vercheck_failed;
29933965Sjdp
30033965Sjdp/* This is called after all the input files have been opened.  */
30133965Sjdp
30233965Sjdpstatic void
30333965Sjdpgld${EMULATION_NAME}_after_open ()
30433965Sjdp{
30533965Sjdp  struct bfd_link_needed_list *needed, *l;
30633965Sjdp
30733965Sjdp  /* We only need to worry about this when doing a final link.  */
30833965Sjdp  if (link_info.relocateable || link_info.shared)
30933965Sjdp    return;
31033965Sjdp
31133965Sjdp  /* Get the list of files which appear in DT_NEEDED entries in
31233965Sjdp     dynamic objects included in the link (often there will be none).
31333965Sjdp     For each such file, we want to track down the corresponding
31433965Sjdp     library, and include the symbol table in the link.  This is what
31533965Sjdp     the runtime dynamic linker will do.  Tracking the files down here
31633965Sjdp     permits one dynamic object to include another without requiring
31733965Sjdp     special action by the person doing the link.  Note that the
31833965Sjdp     needed list can actually grow while we are stepping through this
31933965Sjdp     loop.  */
32033965Sjdp  needed = bfd_elf_get_needed_list (output_bfd, &link_info);
32133965Sjdp  for (l = needed; l != NULL; l = l->next)
32233965Sjdp    {
32333965Sjdp      struct bfd_link_needed_list *ll;
32438889Sjdp      int force;
32533965Sjdp
32633965Sjdp      /* If we've already seen this file, skip it.  */
32733965Sjdp      for (ll = needed; ll != l; ll = ll->next)
32833965Sjdp	if (strcmp (ll->name, l->name) == 0)
32933965Sjdp	  break;
33033965Sjdp      if (ll != l)
33133965Sjdp	continue;
33233965Sjdp
33333965Sjdp      /* See if this file was included in the link explicitly.  */
33433965Sjdp      global_needed = l;
33533965Sjdp      global_found = false;
33633965Sjdp      lang_for_each_input_file (gld${EMULATION_NAME}_check_needed);
33733965Sjdp      if (global_found)
33833965Sjdp	continue;
33933965Sjdp
34033965Sjdp      /* We need to find this file and include the symbol table.  We
34133965Sjdp	 want to search for the file in the same way that the dynamic
34233965Sjdp	 linker will search.  That means that we want to use
34333965Sjdp	 rpath_link, rpath, then the environment variable
34433965Sjdp	 LD_LIBRARY_PATH (native only), then the linker script
34538889Sjdp	 LIB_SEARCH_DIRS.  We do not search using the -L arguments.
34638889Sjdp
34738889Sjdp	 We search twice.  The first time, we skip objects which may
34838889Sjdp	 introduce version mismatches.  The second time, we force
34938889Sjdp	 their use.  See gld${EMULATION_NAME}_vercheck comment.  */
35038889Sjdp      for (force = 0; force < 2; force++)
35133965Sjdp	{
35238889Sjdp	  const char *lib_path;
35338889Sjdp	  size_t len;
35438889Sjdp	  search_dirs_type *search;
35538889Sjdp
35638889Sjdp	  if (gld${EMULATION_NAME}_search_needed (command_line.rpath_link,
35738889Sjdp						  l->name, force))
35838889Sjdp	    break;
35938889Sjdp	  if (gld${EMULATION_NAME}_search_needed (command_line.rpath,
36038889Sjdp						  l->name, force))
36138889Sjdp	    break;
36238889Sjdp	  if (command_line.rpath_link == NULL
36338889Sjdp	      && command_line.rpath == NULL)
36438889Sjdp	    {
36538889Sjdp	      lib_path = (const char *) getenv ("LD_RUN_PATH");
36638889Sjdp	      if (gld${EMULATION_NAME}_search_needed (lib_path, l->name,
36738889Sjdp						      force))
36838889Sjdp		break;
36938889Sjdp	    }
37033965SjdpEOF
37133965Sjdpif [ "x${host}" = "x${target}" ] ; then
37233965Sjdp  if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then
37333965Sjdpcat >>e${EMULATION_NAME}.c <<EOF
37438889Sjdp	  lib_path = (const char *) getenv ("LD_LIBRARY_PATH");
37538889Sjdp	  if (gld${EMULATION_NAME}_search_needed (lib_path, l->name, force))
37638889Sjdp	    break;
37733965SjdpEOF
37833965Sjdp  fi
37933965Sjdpfi
38033965Sjdpcat >>e${EMULATION_NAME}.c <<EOF
38138889Sjdp	  len = strlen (l->name);
38238889Sjdp	  for (search = search_head; search != NULL; search = search->next)
38338889Sjdp	    {
38438889Sjdp	      char *filename;
38533965Sjdp
38638889Sjdp	      if (search->cmdline)
38738889Sjdp		continue;
38838889Sjdp	      filename = (char *) xmalloc (strlen (search->name) + len + 2);
38938889Sjdp	      sprintf (filename, "%s/%s", search->name, l->name);
39038889Sjdp	      if (gld${EMULATION_NAME}_try_needed (filename, force))
39138889Sjdp		break;
39238889Sjdp	      free (filename);
39338889Sjdp	    }
39438889Sjdp	  if (search != NULL)
39533965Sjdp	    break;
39633965SjdpEOF
39733965Sjdpif [ "x${host}" = "x${target}" ] ; then
39833965Sjdp  if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then
39942372Speter    case ${target} in
40042372Speter      *-*-freebsd*)
40142372Speter	cat >>e${EMULATION_NAME}.c <<EOF
40242372Speter	  if (gld${EMULATION_NAME}_check_ld_elf_hints (l->name, force))
40342372Speter	    break;
40442372SpeterEOF
40542372Speter        ;;
40642372Speter      *)
40742372Speter	cat >>e${EMULATION_NAME}.c <<EOF
40838889Sjdp	  if (gld${EMULATION_NAME}_check_ld_so_conf (l->name, force))
40938889Sjdp	    break;
41033965SjdpEOF
41142372Speter        ;;
41242372Speter    esac
41333965Sjdp  fi
41433965Sjdpfi
41533965Sjdpcat >>e${EMULATION_NAME}.c <<EOF
41638889Sjdp	}
41733965Sjdp
41838889Sjdp      if (force < 2)
41938889Sjdp	continue;
42038889Sjdp
42133965Sjdp      einfo ("%P: warning: %s, needed by %B, not found (try using --rpath)\n",
42233965Sjdp	     l->name, l->by);
42333965Sjdp    }
42433965Sjdp}
42533965Sjdp
42633965Sjdp/* Search for a needed file in a path.  */
42733965Sjdp
42833965Sjdpstatic boolean
42938889Sjdpgld${EMULATION_NAME}_search_needed (path, name, force)
43033965Sjdp     const char *path;
43133965Sjdp     const char *name;
43238889Sjdp     int force;
43333965Sjdp{
43433965Sjdp  const char *s;
43533965Sjdp  size_t len;
43633965Sjdp
43733965Sjdp  if (path == NULL || *path == '\0')
43833965Sjdp    return false;
43933965Sjdp  len = strlen (name);
44033965Sjdp  while (1)
44133965Sjdp    {
44233965Sjdp      char *filename, *sset;
44333965Sjdp
44433965Sjdp      s = strchr (path, ':');
44533965Sjdp      if (s == NULL)
44633965Sjdp	s = path + strlen (path);
44733965Sjdp
44833965Sjdp      filename = (char *) xmalloc (s - path + len + 2);
44933965Sjdp      if (s == path)
45033965Sjdp	sset = filename;
45133965Sjdp      else
45233965Sjdp	{
45333965Sjdp	  memcpy (filename, path, s - path);
45433965Sjdp	  filename[s - path] = '/';
45533965Sjdp	  sset = filename + (s - path) + 1;
45633965Sjdp	}
45733965Sjdp      strcpy (sset, name);
45833965Sjdp
45938889Sjdp      if (gld${EMULATION_NAME}_try_needed (filename, force))
46033965Sjdp	return true;
46133965Sjdp
46233965Sjdp      free (filename);
46333965Sjdp
46433965Sjdp      if (*s == '\0')
46533965Sjdp	break;
46633965Sjdp      path = s + 1;
46733965Sjdp    }
46833965Sjdp
46933965Sjdp  return false;	  
47033965Sjdp}
47133965Sjdp
47233965Sjdp/* This function is called for each possible name for a dynamic object
47338889Sjdp   named by a DT_NEEDED entry.  The FORCE parameter indicates whether
47438889Sjdp   to skip the check for a conflicting version.  */
47533965Sjdp
47633965Sjdpstatic boolean
47738889Sjdpgld${EMULATION_NAME}_try_needed (name, force)
47833965Sjdp     const char *name;
47938889Sjdp     int force;
48033965Sjdp{
48133965Sjdp  bfd *abfd;
48233965Sjdp
48333965Sjdp  abfd = bfd_openr (name, bfd_get_target (output_bfd));
48433965Sjdp  if (abfd == NULL)
48533965Sjdp    return false;
48633965Sjdp  if (! bfd_check_format (abfd, bfd_object))
48733965Sjdp    {
48833965Sjdp      (void) bfd_close (abfd);
48933965Sjdp      return false;
49033965Sjdp    }
49133965Sjdp  if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0)
49233965Sjdp    {
49333965Sjdp      (void) bfd_close (abfd);
49433965Sjdp      return false;
49533965Sjdp    }
49633965Sjdp
49738889Sjdp  /* Check whether this object would include any conflicting library
49838889Sjdp     versions.  If FORCE is set, then we skip this check; we use this
49938889Sjdp     the second time around, if we couldn't find any compatible
50038889Sjdp     instance of the shared library.  */
50138889Sjdp
50238889Sjdp  if (! force)
50338889Sjdp    {
50438889Sjdp      struct bfd_link_needed_list *needed;
50538889Sjdp
50638889Sjdp      if (! bfd_elf_get_bfd_needed_list (abfd, &needed))
50738889Sjdp	einfo ("%F%P:%B: bfd_elf_get_bfd_needed_list failed: %E\n", abfd);
50838889Sjdp
50938889Sjdp      if (needed != NULL)
51038889Sjdp	{
51138889Sjdp	  global_vercheck_needed = needed;
51238889Sjdp	  global_vercheck_failed = false;
51338889Sjdp	  lang_for_each_input_file (gld${EMULATION_NAME}_vercheck);
51438889Sjdp	  if (global_vercheck_failed)
51538889Sjdp	    {
51638889Sjdp	      (void) bfd_close (abfd);
51738889Sjdp	      /* Return false to force the caller to move on to try
51838889Sjdp                 another file on the search path.  */
51938889Sjdp	      return false;
52038889Sjdp	    }
52138889Sjdp
52238889Sjdp	  /* But wait!  It gets much worse.  On Linux, if a shared
52338889Sjdp             library does not use libc at all, we are supposed to skip
52438889Sjdp             it the first time around in case we encounter a shared
52538889Sjdp             library later on with the same name which does use the
52638889Sjdp             version of libc that we want.  This is much too horrible
52738889Sjdp             to use on any system other than Linux.  */
52838889Sjdp
52938889SjdpEOF
53038889Sjdpcase ${target} in
53138889Sjdp  *-*-linux-gnu*)
53238889Sjdp    cat >>e${EMULATION_NAME}.c <<EOF
53338889Sjdp	  {
53438889Sjdp	    struct bfd_link_needed_list *l;
53538889Sjdp
53638889Sjdp	    for (l = needed; l != NULL; l = l->next)
53738889Sjdp	      if (strncmp (l->name, "libc.so", 7) == 0)
53838889Sjdp		break;
53938889Sjdp	    if (l == NULL)
54038889Sjdp	      {
54138889Sjdp		(void) bfd_close (abfd);
54238889Sjdp		return false;
54338889Sjdp	      }
54438889Sjdp	  }
54538889Sjdp
54638889SjdpEOF
54738889Sjdp    ;;
54838889Sjdpesac
54938889Sjdpcat >>e${EMULATION_NAME}.c <<EOF
55038889Sjdp	}
55138889Sjdp    }
55238889Sjdp
55333965Sjdp  /* We've found a dynamic object matching the DT_NEEDED entry.  */
55433965Sjdp
55533965Sjdp  /* We have already checked that there is no other input file of the
55633965Sjdp     same name.  We must now check again that we are not including the
55733965Sjdp     same file twice.  We need to do this because on many systems
55833965Sjdp     libc.so is a symlink to, e.g., libc.so.1.  The SONAME entry will
55933965Sjdp     reference libc.so.1.  If we have already included libc.so, we
56033965Sjdp     don't want to include libc.so.1 if they are the same file, and we
56133965Sjdp     can only check that using stat.  */
56233965Sjdp
56333965Sjdp  if (bfd_stat (abfd, &global_stat) != 0)
56433965Sjdp    einfo ("%F%P:%B: bfd_stat failed: %E\n", abfd);
56533965Sjdp  global_found = false;
56633965Sjdp  lang_for_each_input_file (gld${EMULATION_NAME}_stat_needed);
56733965Sjdp  if (global_found)
56833965Sjdp    {
56933965Sjdp      /* Return true to indicate that we found the file, even though
57033965Sjdp         we aren't going to do anything with it.  */
57133965Sjdp      return true;
57233965Sjdp    }
57333965Sjdp
57433965Sjdp  /* Tell the ELF backend that don't want the output file to have a
57533965Sjdp     DT_NEEDED entry for this file.  */
57633965Sjdp  bfd_elf_set_dt_needed_name (abfd, "");
57733965Sjdp
57833965Sjdp  /* Add this file into the symbol table.  */
57933965Sjdp  if (! bfd_link_add_symbols (abfd, &link_info))
58033965Sjdp    einfo ("%F%B: could not read symbols: %E\n", abfd);
58133965Sjdp
58233965Sjdp  return true;
58333965Sjdp}
58433965Sjdp
58533965Sjdp/* See if an input file matches a DT_NEEDED entry by name.  */
58633965Sjdp
58733965Sjdpstatic void
58833965Sjdpgld${EMULATION_NAME}_check_needed (s)
58933965Sjdp     lang_input_statement_type *s;
59033965Sjdp{
59133965Sjdp  if (global_found)
59233965Sjdp    return;
59333965Sjdp
59433965Sjdp  if (s->filename != NULL
59533965Sjdp      && strcmp (s->filename, global_needed->name) == 0)
59633965Sjdp    {
59733965Sjdp      global_found = true;
59833965Sjdp      return;
59933965Sjdp    }
60033965Sjdp
60133965Sjdp  if (s->the_bfd != NULL)
60233965Sjdp    {
60333965Sjdp      const char *soname;
60433965Sjdp
60533965Sjdp      soname = bfd_elf_get_dt_soname (s->the_bfd);
60633965Sjdp      if (soname != NULL
60733965Sjdp	  && strcmp (soname, global_needed->name) == 0)
60833965Sjdp	{
60933965Sjdp	  global_found = true;
61033965Sjdp	  return;
61133965Sjdp	}
61233965Sjdp    }
61333965Sjdp	  
61433965Sjdp  if (s->search_dirs_flag
61533965Sjdp      && s->filename != NULL
61633965Sjdp      && strchr (global_needed->name, '/') == NULL)
61733965Sjdp    {
61833965Sjdp      const char *f;
61933965Sjdp
62033965Sjdp      f = strrchr (s->filename, '/');
62133965Sjdp      if (f != NULL
62233965Sjdp	  && strcmp (f + 1, global_needed->name) == 0)
62333965Sjdp	{
62433965Sjdp	  global_found = true;
62533965Sjdp	  return;
62633965Sjdp	}
62733965Sjdp    }
62833965Sjdp}
62933965Sjdp
63033965Sjdp/* See if an input file matches a DT_NEEDED entry by running stat on
63133965Sjdp   the file.  */
63233965Sjdp
63333965Sjdpstatic void
63433965Sjdpgld${EMULATION_NAME}_stat_needed (s)
63533965Sjdp     lang_input_statement_type *s;
63633965Sjdp{
63733965Sjdp  struct stat st;
63833965Sjdp  const char *suffix;
63933965Sjdp  const char *soname;
64033965Sjdp  const char *f;
64133965Sjdp
64233965Sjdp  if (global_found)
64333965Sjdp    return;
64433965Sjdp  if (s->the_bfd == NULL)
64533965Sjdp    return;
64633965Sjdp
64733965Sjdp  if (bfd_stat (s->the_bfd, &st) != 0)
64833965Sjdp    {
64933965Sjdp      einfo ("%P:%B: bfd_stat failed: %E\n", s->the_bfd);
65033965Sjdp      return;
65133965Sjdp    }
65233965Sjdp
65333965Sjdp  if (st.st_dev == global_stat.st_dev
65433965Sjdp      && st.st_ino == global_stat.st_ino)
65533965Sjdp    {
65633965Sjdp      global_found = true;
65733965Sjdp      return;
65833965Sjdp    }
65933965Sjdp
66033965Sjdp  /* We issue a warning if it looks like we are including two
66133965Sjdp     different versions of the same shared library.  For example,
66233965Sjdp     there may be a problem if -lc picks up libc.so.6 but some other
66333965Sjdp     shared library has a DT_NEEDED entry of libc.so.5.  This is a
66433965Sjdp     hueristic test, and it will only work if the name looks like
66533965Sjdp     NAME.so.VERSION.  FIXME: Depending on file names is error-prone.
66633965Sjdp     If we really want to issue warnings about mixing version numbers
66733965Sjdp     of shared libraries, we need to find a better way.  */
66833965Sjdp
66933965Sjdp  if (strchr (global_needed->name, '/') != NULL)
67033965Sjdp    return;
67133965Sjdp  suffix = strstr (global_needed->name, ".so.");
67233965Sjdp  if (suffix == NULL)
67333965Sjdp    return;
67433965Sjdp  suffix += sizeof ".so." - 1;
67533965Sjdp
67633965Sjdp  soname = bfd_elf_get_dt_soname (s->the_bfd);
67733965Sjdp  if (soname == NULL)
67833965Sjdp    soname = s->filename;
67933965Sjdp
68033965Sjdp  f = strrchr (soname, '/');
68133965Sjdp  if (f != NULL)
68233965Sjdp    ++f;
68333965Sjdp  else
68433965Sjdp    f = soname;
68533965Sjdp
68633965Sjdp  if (strncmp (f, global_needed->name, suffix - global_needed->name) == 0)
68733965Sjdp    einfo ("%P: warning: %s, needed by %B, may conflict with %s\n",
68833965Sjdp	   global_needed->name, global_needed->by, f);
68933965Sjdp}
69033965Sjdp
69138889Sjdp/* On Linux, it's possible to have different versions of the same
69238889Sjdp   shared library linked against different versions of libc.  The
69338889Sjdp   dynamic linker somehow tags which libc version to use in
69438889Sjdp   /etc/ld.so.cache, and, based on the libc that it sees in the
69538889Sjdp   executable, chooses which version of the shared library to use.
69638889Sjdp
69738889Sjdp   We try to do a similar check here by checking whether this shared
69838889Sjdp   library needs any other shared libraries which may conflict with
69938889Sjdp   libraries we have already included in the link.  If it does, we
70038889Sjdp   skip it, and try to find another shared library farther on down the
70138889Sjdp   link path.
70238889Sjdp
70338889Sjdp   This is called via lang_for_each_input_file.
70438889Sjdp   GLOBAL_VERCHECK_NEEDED is the list of objects needed by the object
70538889Sjdp   which we ar checking.  This sets GLOBAL_VERCHECK_FAILED if we find
70638889Sjdp   a conflicting version.  */
70738889Sjdp
70838889Sjdpstatic void
70938889Sjdpgld${EMULATION_NAME}_vercheck (s)
71038889Sjdp     lang_input_statement_type *s;
71138889Sjdp{
71238889Sjdp  const char *soname, *f;
71338889Sjdp  struct bfd_link_needed_list *l;
71438889Sjdp
71538889Sjdp  if (global_vercheck_failed)
71638889Sjdp    return;
71738889Sjdp  if (s->the_bfd == NULL
71838889Sjdp      || (bfd_get_file_flags (s->the_bfd) & DYNAMIC) == 0)
71938889Sjdp    return;
72038889Sjdp
72138889Sjdp  soname = bfd_elf_get_dt_soname (s->the_bfd);
72238889Sjdp  if (soname == NULL)
72338889Sjdp    soname = bfd_get_filename (s->the_bfd);
72438889Sjdp
72538889Sjdp  f = strrchr (soname, '/');
72638889Sjdp  if (f != NULL)
72738889Sjdp    ++f;
72838889Sjdp  else
72938889Sjdp    f = soname;
73038889Sjdp
73138889Sjdp  for (l = global_vercheck_needed; l != NULL; l = l->next)
73238889Sjdp    {
73338889Sjdp      const char *suffix;
73438889Sjdp
73538889Sjdp      if (strcmp (f, l->name) == 0)
73638889Sjdp	{
73738889Sjdp	  /* Probably can't happen, but it's an easy check.  */
73838889Sjdp	  continue;
73938889Sjdp	}
74038889Sjdp
74138889Sjdp      if (strchr (l->name, '/') != NULL)
74238889Sjdp	continue;
74338889Sjdp
74438889Sjdp      suffix = strstr (l->name, ".so.");
74538889Sjdp      if (suffix == NULL)
74638889Sjdp	continue;
74738889Sjdp
74838889Sjdp      suffix += sizeof ".so." - 1;
74938889Sjdp
75038889Sjdp      if (strncmp (f, l->name, suffix - l->name) == 0)
75138889Sjdp	{
75238889Sjdp	  /* Here we know that S is a dynamic object FOO.SO.VER1, and
75338889Sjdp             the object we are considering needs a dynamic object
75438889Sjdp             FOO.SO.VER2, and VER1 and VER2 are different.  This
75538889Sjdp             appears to be a version mismatch, so we tell the caller
75638889Sjdp             to try a different version of this library.  */
75738889Sjdp	  global_vercheck_failed = true;
75838889Sjdp	  return;
75938889Sjdp	}
76038889Sjdp    }
76138889Sjdp}
76238889Sjdp
76333965Sjdp/* This is called after the sections have been attached to output
76433965Sjdp   sections, but before any sizes or addresses have been set.  */
76533965Sjdp
76633965Sjdpstatic void
76733965Sjdpgld${EMULATION_NAME}_before_allocation ()
76833965Sjdp{
76933965Sjdp  const char *rpath;
77033965Sjdp  asection *sinterp;
77133965Sjdp
77233965Sjdp  /* If we are going to make any variable assignments, we need to let
77333965Sjdp     the ELF backend know about them in case the variables are
77433965Sjdp     referred to by dynamic objects.  */
77533965Sjdp  lang_for_each_statement (gld${EMULATION_NAME}_find_statement_assignment);
77633965Sjdp
77733965Sjdp  /* Let the ELF backend work out the sizes of any sections required
77833965Sjdp     by dynamic linking.  */
77933965Sjdp  rpath = command_line.rpath;
78033965Sjdp  if (rpath == NULL)
78133965Sjdp    rpath = (const char *) getenv ("LD_RUN_PATH");
78233965Sjdp  if (! (bfd_elf${ELFSIZE}_size_dynamic_sections
78333965Sjdp         (output_bfd, command_line.soname, rpath,
78433965Sjdp	  command_line.export_dynamic, command_line.filter_shlib,
78533965Sjdp	  (const char * const *) command_line.auxiliary_filters,
78633965Sjdp	  &link_info, &sinterp, lang_elf_version_info)))
78733965Sjdp    einfo ("%P%F: failed to set dynamic section sizes: %E\n");
78833965Sjdp
78933965Sjdp  /* Let the user override the dynamic linker we are using.  */
79033965Sjdp  if (command_line.interpreter != NULL
79133965Sjdp      && sinterp != NULL)
79233965Sjdp    {
79333965Sjdp      sinterp->contents = (bfd_byte *) command_line.interpreter;
79433965Sjdp      sinterp->_raw_size = strlen (command_line.interpreter) + 1;
79533965Sjdp    }
79633965Sjdp
79733965Sjdp  /* Look for any sections named .gnu.warning.  As a GNU extensions,
79833965Sjdp     we treat such sections as containing warning messages.  We print
79933965Sjdp     out the warning message, and then zero out the section size so
80033965Sjdp     that it does not get copied into the output file.  */
80133965Sjdp
80233965Sjdp  {
80333965Sjdp    LANG_FOR_EACH_INPUT_STATEMENT (is)
80433965Sjdp      {
80533965Sjdp	asection *s;
80633965Sjdp	bfd_size_type sz;
80733965Sjdp	char *msg;
80833965Sjdp	boolean ret;
80933965Sjdp
81033965Sjdp	if (is->just_syms_flag)
81133965Sjdp	  continue;
81233965Sjdp
81333965Sjdp	s = bfd_get_section_by_name (is->the_bfd, ".gnu.warning");
81433965Sjdp	if (s == NULL)
81533965Sjdp	  continue;
81633965Sjdp
81733965Sjdp	sz = bfd_section_size (is->the_bfd, s);
81833965Sjdp	msg = xmalloc ((size_t) sz + 1);
81933965Sjdp	if (! bfd_get_section_contents (is->the_bfd, s, msg, (file_ptr) 0, sz))
82033965Sjdp	  einfo ("%F%B: Can't read contents of section .gnu.warning: %E\n",
82133965Sjdp		 is->the_bfd);
82233965Sjdp	msg[sz] = '\0';
82333965Sjdp	ret = link_info.callbacks->warning (&link_info, msg,
82433965Sjdp					    (const char *) NULL,
82533965Sjdp					    is->the_bfd, (asection *) NULL,
82633965Sjdp					    (bfd_vma) 0);
82733965Sjdp	ASSERT (ret);
82833965Sjdp	free (msg);
82933965Sjdp
83033965Sjdp	/* Clobber the section size, so that we don't waste copying the
83133965Sjdp	   warning into the output file.  */
83233965Sjdp	s->_raw_size = 0;
83333965Sjdp      }
83433965Sjdp  }
83533965Sjdp
83633965Sjdp#if defined (TARGET_IS_elf32bmip) || defined (TARGET_IS_elf32lmip)
83733965Sjdp  /* For MIPS ELF the .reginfo section requires special handling.
83833965Sjdp     Each input section is 24 bytes, and the final output section must
83933965Sjdp     also be 24 bytes.  We handle this by clobbering all but the first
84033965Sjdp     input section size to 0.  The .reginfo section is handled
84133965Sjdp     specially by the backend code anyhow.  */
84233965Sjdp  {
84333965Sjdp    boolean found = false;
84433965Sjdp    LANG_FOR_EACH_INPUT_STATEMENT (is)
84533965Sjdp      {
84633965Sjdp	asection *s;
84733965Sjdp
84833965Sjdp	if (is->just_syms_flag)
84933965Sjdp	  continue;
85033965Sjdp
85133965Sjdp	s = bfd_get_section_by_name (is->the_bfd, ".reginfo");
85233965Sjdp	if (s == NULL)
85333965Sjdp	  continue;
85433965Sjdp
85533965Sjdp	if (! found)
85633965Sjdp	  {
85733965Sjdp	    found = true;
85833965Sjdp	    continue;
85933965Sjdp	  }
86033965Sjdp
86133965Sjdp	s->_raw_size = 0;
86233965Sjdp	s->_cooked_size = 0;
86333965Sjdp      }
86433965Sjdp  }
86533965Sjdp#endif
86633965Sjdp}
86733965Sjdp
86833965Sjdp/* This is called by the before_allocation routine via
86933965Sjdp   lang_for_each_statement.  It locates any assignment statements, and
87033965Sjdp   tells the ELF backend about them, in case they are assignments to
87133965Sjdp   symbols which are referred to by dynamic objects.  */
87233965Sjdp
87333965Sjdpstatic void
87433965Sjdpgld${EMULATION_NAME}_find_statement_assignment (s)
87533965Sjdp     lang_statement_union_type *s;
87633965Sjdp{
87733965Sjdp  if (s->header.type == lang_assignment_statement_enum)
87833965Sjdp    gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp);
87933965Sjdp}
88033965Sjdp
88133965Sjdp/* Look through an expression for an assignment statement.  */
88233965Sjdp
88333965Sjdpstatic void
88433965Sjdpgld${EMULATION_NAME}_find_exp_assignment (exp)
88533965Sjdp     etree_type *exp;
88633965Sjdp{
88733965Sjdp  struct bfd_link_hash_entry *h;
88833965Sjdp
88933965Sjdp  switch (exp->type.node_class)
89033965Sjdp    {
89133965Sjdp    case etree_provide:
89233965Sjdp      h = bfd_link_hash_lookup (link_info.hash, exp->assign.dst,
89333965Sjdp				false, false, false);
89433965Sjdp      if (h == NULL)
89533965Sjdp	break;
89633965Sjdp
89733965Sjdp      /* We call record_link_assignment even if the symbol is defined.
89833965Sjdp	 This is because if it is defined by a dynamic object, we
89933965Sjdp	 actually want to use the value defined by the linker script,
90033965Sjdp	 not the value from the dynamic object (because we are setting
90133965Sjdp	 symbols like etext).  If the symbol is defined by a regular
90233965Sjdp	 object, then, as it happens, calling record_link_assignment
90333965Sjdp	 will do no harm.  */
90433965Sjdp
90533965Sjdp      /* Fall through.  */
90633965Sjdp    case etree_assign:
90733965Sjdp      if (strcmp (exp->assign.dst, ".") != 0)
90833965Sjdp	{
90933965Sjdp	  if (! (bfd_elf${ELFSIZE}_record_link_assignment
91033965Sjdp		 (output_bfd, &link_info, exp->assign.dst,
91133965Sjdp		  exp->type.node_class == etree_provide ? true : false)))
91233965Sjdp	    einfo ("%P%F: failed to record assignment to %s: %E\n",
91333965Sjdp		   exp->assign.dst);
91433965Sjdp	}
91533965Sjdp      gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src);
91633965Sjdp      break;
91733965Sjdp
91833965Sjdp    case etree_binary:
91933965Sjdp      gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs);
92033965Sjdp      gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs);
92133965Sjdp      break;
92233965Sjdp
92333965Sjdp    case etree_trinary:
92433965Sjdp      gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.cond);
92533965Sjdp      gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs);
92633965Sjdp      gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs);
92733965Sjdp      break;
92833965Sjdp
92933965Sjdp    case etree_unary:
93033965Sjdp      gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child);
93133965Sjdp      break;
93233965Sjdp
93333965Sjdp    default:
93433965Sjdp      break;
93533965Sjdp    }
93633965Sjdp}
93733965Sjdp
93833965Sjdp/* Place an orphan section.  We use this to put random SHF_ALLOC
93933965Sjdp   sections in the right segment.  */
94033965Sjdp
94133965Sjdpstatic asection *hold_section;
94233965Sjdpstatic lang_output_section_statement_type *hold_use;
94333965Sjdpstatic lang_output_section_statement_type *hold_text;
94433965Sjdpstatic lang_output_section_statement_type *hold_rodata;
94533965Sjdpstatic lang_output_section_statement_type *hold_data;
94633965Sjdpstatic lang_output_section_statement_type *hold_bss;
94733965Sjdpstatic lang_output_section_statement_type *hold_rel;
94833965Sjdpstatic lang_output_section_statement_type *hold_interp;
94933965Sjdp
95033965Sjdp/*ARGSUSED*/
95133965Sjdpstatic boolean
95233965Sjdpgld${EMULATION_NAME}_place_orphan (file, s)
95333965Sjdp     lang_input_statement_type *file;
95433965Sjdp     asection *s;
95533965Sjdp{
95633965Sjdp  lang_output_section_statement_type *place;
95733965Sjdp  asection *snew, **pps;
95833965Sjdp  lang_statement_list_type *old;
95933965Sjdp  lang_statement_list_type add;
96033965Sjdp  etree_type *address;
96133965Sjdp  const char *secname, *ps;
96233965Sjdp  const char *outsecname;
96333965Sjdp  lang_output_section_statement_type *os;
96433965Sjdp
96533965Sjdp  if ((s->flags & SEC_ALLOC) == 0)
96633965Sjdp    return false;
96733965Sjdp
96833965Sjdp  /* Look through the script to see where to place this section.  */
96933965Sjdp  hold_section = s;
97033965Sjdp  hold_use = NULL;
97133965Sjdp  lang_for_each_statement (gld${EMULATION_NAME}_place_section);
97233965Sjdp
97333965Sjdp  if (hold_use != NULL)
97433965Sjdp    {
97533965Sjdp      /* We have already placed a section with this name.  */
97633965Sjdp      wild_doit (&hold_use->children, s, hold_use, file);
97733965Sjdp      return true;
97833965Sjdp    }
97933965Sjdp
98033965Sjdp  secname = bfd_get_section_name (s->owner, s);
98133965Sjdp
98233965Sjdp  /* If this is a final link, then always put .gnu.warning.SYMBOL
98333965Sjdp     sections into the .text section to get them out of the way.  */
98433965Sjdp  if (! link_info.shared
98533965Sjdp      && ! link_info.relocateable
98633965Sjdp      && strncmp (secname, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0
98733965Sjdp      && hold_text != NULL)
98833965Sjdp    {
98933965Sjdp      wild_doit (&hold_text->children, s, hold_text, file);
99033965Sjdp      return true;
99133965Sjdp    }
99233965Sjdp
99333965Sjdp  /* Decide which segment the section should go in based on the
99433965Sjdp     section name and section flags.  We put loadable .note sections
99533965Sjdp     right after the .interp section, so that the PT_NOTE segment is
99633965Sjdp     stored right after the program headers where the OS can read it
99733965Sjdp     in the first page.  */
99833965Sjdp  place = NULL;
99933965Sjdp  if ((s->flags & SEC_LOAD) != 0
100033965Sjdp      && strncmp (secname, ".note", 4) == 0
100133965Sjdp      && hold_interp != NULL)
100233965Sjdp    place = hold_interp;
100333965Sjdp  else if ((s->flags & SEC_HAS_CONTENTS) == 0
100433965Sjdp	   && hold_bss != NULL)
100533965Sjdp    place = hold_bss;
100633965Sjdp  else if ((s->flags & SEC_READONLY) == 0
100733965Sjdp	   && hold_data != NULL)
100833965Sjdp    place = hold_data;
100933965Sjdp  else if (strncmp (secname, ".rel", 4) == 0
101033965Sjdp	   && hold_rel != NULL)
101133965Sjdp    place = hold_rel;
101233965Sjdp  else if ((s->flags & SEC_CODE) == 0
101333965Sjdp	   && (s->flags & SEC_READONLY) != 0
101433965Sjdp	   && hold_rodata != NULL)
101533965Sjdp    place = hold_rodata;
101633965Sjdp  else if ((s->flags & SEC_READONLY) != 0
101733965Sjdp	   && hold_text != NULL)
101833965Sjdp    place = hold_text;
101933965Sjdp  if (place == NULL)
102033965Sjdp    return false;
102133965Sjdp
102233965Sjdp  /* Choose a unique name for the section.  This will be needed if the
102333965Sjdp     same section name appears in the input file with different
102433965Sjdp     loadable or allocateable characteristics.  */
102533965Sjdp  outsecname = secname;
102633965Sjdp  if (bfd_get_section_by_name (output_bfd, outsecname) != NULL)
102733965Sjdp    {
102833965Sjdp      unsigned int len;
102933965Sjdp      char *newname;
103033965Sjdp      unsigned int i;
103133965Sjdp
103233965Sjdp      len = strlen (outsecname);
103333965Sjdp      newname = xmalloc (len + 5);
103433965Sjdp      strcpy (newname, outsecname);
103533965Sjdp      i = 0;
103633965Sjdp      do
103733965Sjdp	{
103833965Sjdp	  sprintf (newname + len, "%d", i);
103933965Sjdp	  ++i;
104033965Sjdp	}
104133965Sjdp      while (bfd_get_section_by_name (output_bfd, newname) != NULL);
104233965Sjdp
104333965Sjdp      outsecname = newname;
104433965Sjdp    }
104533965Sjdp
104633965Sjdp  /* Create the section in the output file, and put it in the right
104733965Sjdp     place.  This shuffling is to make the output file look neater.  */
104833965Sjdp  snew = bfd_make_section (output_bfd, outsecname);
104933965Sjdp  if (snew == NULL)
105033965Sjdp      einfo ("%P%F: output format %s cannot represent section called %s\n",
105133965Sjdp	     output_bfd->xvec->name, outsecname);
105233965Sjdp  if (place->bfd_section != NULL)
105333965Sjdp    {
105433965Sjdp      for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
105533965Sjdp	;
105633965Sjdp      *pps = snew->next;
105733965Sjdp      snew->next = place->bfd_section->next;
105833965Sjdp      place->bfd_section->next = snew;
105933965Sjdp    }
106033965Sjdp
106133965Sjdp  /* Start building a list of statements for this section.  */
106233965Sjdp  old = stat_ptr;
106333965Sjdp  stat_ptr = &add;
106433965Sjdp  lang_list_init (stat_ptr);
106533965Sjdp
106633965Sjdp  /* If the name of the section is representable in C, then create
106733965Sjdp     symbols to mark the start and the end of the section.  */
106833965Sjdp  for (ps = outsecname; *ps != '\0'; ps++)
106938889Sjdp    if (! isalnum ((unsigned char) *ps) && *ps != '_')
107033965Sjdp      break;
107133965Sjdp  if (*ps == '\0' && config.build_constructors)
107233965Sjdp    {
107333965Sjdp      char *symname;
107433965Sjdp
107533965Sjdp      symname = (char *) xmalloc (ps - outsecname + sizeof "__start_");
107633965Sjdp      sprintf (symname, "__start_%s", outsecname);
107733965Sjdp      lang_add_assignment (exp_assop ('=', symname,
107833965Sjdp				      exp_unop (ALIGN_K,
107933965Sjdp						exp_intop ((bfd_vma) 1
108033965Sjdp							   << s->alignment_power))));
108133965Sjdp    }
108233965Sjdp
108333965Sjdp  if (! link_info.relocateable)
108433965Sjdp    address = NULL;
108533965Sjdp  else
108633965Sjdp    address = exp_intop ((bfd_vma) 0);
108733965Sjdp
108833965Sjdp  lang_enter_output_section_statement (outsecname, address, 0,
108933965Sjdp				       (bfd_vma) 0,
109033965Sjdp				       (etree_type *) NULL,
109133965Sjdp				       (etree_type *) NULL,
109233965Sjdp				       (etree_type *) NULL);
109333965Sjdp
109433965Sjdp  os = lang_output_section_statement_lookup (outsecname);
109533965Sjdp  wild_doit (&os->children, s, os, file);
109633965Sjdp
109733965Sjdp  lang_leave_output_section_statement
109833965Sjdp    ((bfd_vma) 0, "*default*", (struct lang_output_section_phdr_list *) NULL);
109933965Sjdp  stat_ptr = &add;
110033965Sjdp
110133965Sjdp  if (*ps == '\0' && config.build_constructors)
110233965Sjdp    {
110333965Sjdp      char *symname;
110433965Sjdp
110533965Sjdp      symname = (char *) xmalloc (ps - outsecname + sizeof "__stop_");
110633965Sjdp      sprintf (symname, "__stop_%s", outsecname);
110733965Sjdp      lang_add_assignment (exp_assop ('=', symname,
110833965Sjdp				      exp_nameop (NAME, ".")));
110933965Sjdp    }
111033965Sjdp
111133965Sjdp  /* Now stick the new statement list right after PLACE.  */
111233965Sjdp  *add.tail = place->header.next;
111333965Sjdp  place->header.next = add.head;
111433965Sjdp
111533965Sjdp  stat_ptr = old;
111633965Sjdp
111733965Sjdp  return true;
111833965Sjdp}
111933965Sjdp
112033965Sjdpstatic void
112133965Sjdpgld${EMULATION_NAME}_place_section (s)
112233965Sjdp     lang_statement_union_type *s;
112333965Sjdp{
112433965Sjdp  lang_output_section_statement_type *os;
112533965Sjdp
112633965Sjdp  if (s->header.type != lang_output_section_statement_enum)
112733965Sjdp    return;
112833965Sjdp
112933965Sjdp  os = &s->output_section_statement;
113033965Sjdp
113133965Sjdp  if (strcmp (os->name, hold_section->name) == 0
113238889Sjdp      && os->bfd_section != NULL
113333965Sjdp      && ((hold_section->flags & (SEC_LOAD | SEC_ALLOC))
113433965Sjdp	  == (os->bfd_section->flags & (SEC_LOAD | SEC_ALLOC))))
113533965Sjdp    hold_use = os;
113633965Sjdp
113733965Sjdp  if (strcmp (os->name, ".text") == 0)
113833965Sjdp    hold_text = os;
113933965Sjdp  else if (strcmp (os->name, ".rodata") == 0)
114033965Sjdp    hold_rodata = os;
114133965Sjdp  else if (strcmp (os->name, ".data") == 0)
114233965Sjdp    hold_data = os;
114333965Sjdp  else if (strcmp (os->name, ".bss") == 0)
114433965Sjdp    hold_bss = os;
114533965Sjdp  else if (hold_rel == NULL
114633965Sjdp	   && os->bfd_section != NULL
114733965Sjdp	   && (os->bfd_section->flags & SEC_ALLOC) != 0
114833965Sjdp	   && strncmp (os->name, ".rel", 4) == 0)
114933965Sjdp    hold_rel = os;
115033965Sjdp  else if (strcmp (os->name, ".interp") == 0)
115133965Sjdp    hold_interp = os;
115233965Sjdp}
115333965Sjdp
115433965Sjdpstatic char *
115533965Sjdpgld${EMULATION_NAME}_get_script(isfile)
115633965Sjdp     int *isfile;
115733965SjdpEOF
115833965Sjdp
115933965Sjdpif test -n "$COMPILE_IN"
116033965Sjdpthen
116133965Sjdp# Scripts compiled in.
116233965Sjdp
116333965Sjdp# sed commands to quote an ld script as a C string.
116433965Sjdpsc='s/["\\]/\\&/g
116533965Sjdps/$/\\n\\/
116633965Sjdp1s/^/"/
116733965Sjdp$s/$/n"/
116833965Sjdp'
116933965Sjdp
117033965Sjdpcat >>e${EMULATION_NAME}.c <<EOF
117133965Sjdp{			     
117233965Sjdp  *isfile = 0;
117333965Sjdp
117433965Sjdp  if (link_info.relocateable == true && config.build_constructors == true)
117533965Sjdp    return `sed "$sc" ldscripts/${EMULATION_NAME}.xu`;
117633965Sjdp  else if (link_info.relocateable == true)
117733965Sjdp    return `sed "$sc" ldscripts/${EMULATION_NAME}.xr`;
117833965Sjdp  else if (!config.text_read_only)
117933965Sjdp    return `sed "$sc" ldscripts/${EMULATION_NAME}.xbn`;
118033965Sjdp  else if (!config.magic_demand_paged)
118133965Sjdp    return `sed "$sc" ldscripts/${EMULATION_NAME}.xn`;
118233965Sjdp  else if (link_info.shared)
118333965Sjdp    return `sed "$sc" ldscripts/${EMULATION_NAME}.xs`;
118433965Sjdp  else
118533965Sjdp    return `sed "$sc" ldscripts/${EMULATION_NAME}.x`;
118633965Sjdp}
118733965SjdpEOF
118833965Sjdp
118933965Sjdpelse
119033965Sjdp# Scripts read from the filesystem.
119133965Sjdp
119233965Sjdpcat >>e${EMULATION_NAME}.c <<EOF
119333965Sjdp{			     
119433965Sjdp  *isfile = 1;
119533965Sjdp
119633965Sjdp  if (link_info.relocateable == true && config.build_constructors == true)
119733965Sjdp    return "ldscripts/${EMULATION_NAME}.xu";
119833965Sjdp  else if (link_info.relocateable == true)
119933965Sjdp    return "ldscripts/${EMULATION_NAME}.xr";
120033965Sjdp  else if (!config.text_read_only)
120133965Sjdp    return "ldscripts/${EMULATION_NAME}.xbn";
120233965Sjdp  else if (!config.magic_demand_paged)
120333965Sjdp    return "ldscripts/${EMULATION_NAME}.xn";
120433965Sjdp  else if (link_info.shared)
120533965Sjdp    return "ldscripts/${EMULATION_NAME}.xs";
120633965Sjdp  else
120733965Sjdp    return "ldscripts/${EMULATION_NAME}.x";
120833965Sjdp}
120933965SjdpEOF
121033965Sjdp
121133965Sjdpfi
121233965Sjdp
121333965Sjdpcat >>e${EMULATION_NAME}.c <<EOF
121433965Sjdp
121533965Sjdpstruct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = 
121633965Sjdp{
121733965Sjdp  gld${EMULATION_NAME}_before_parse,
121833965Sjdp  syslib_default,
121933965Sjdp  hll_default,
122033965Sjdp  after_parse_default,
122133965Sjdp  gld${EMULATION_NAME}_after_open,
122233965Sjdp  after_allocation_default,
122333965Sjdp  set_output_arch_default,
122433965Sjdp  ldemul_default_target,
122533965Sjdp  gld${EMULATION_NAME}_before_allocation,
122633965Sjdp  gld${EMULATION_NAME}_get_script,
122733965Sjdp  "${EMULATION_NAME}",
122833965Sjdp  "${OUTPUT_FORMAT}",
122933965Sjdp  NULL,
123033965Sjdp  NULL,
123133965Sjdp  gld${EMULATION_NAME}_open_dynamic_archive,
123233965Sjdp  gld${EMULATION_NAME}_place_orphan
123333965Sjdp};
123433965SjdpEOF
1235