elf32.em revision 38889
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
14233965Sjdpcat >>e${EMULATION_NAME}.c <<EOF
14333965Sjdp
14433965Sjdp/* For a native linker, check the file /etc/ld.so.conf for directories
14533965Sjdp   in which we may find shared libraries.  /etc/ld.so.conf is really
14633965Sjdp   only meaningful on Linux, but we check it on other systems anyhow.  */
14733965Sjdp
14838889Sjdpstatic boolean gld${EMULATION_NAME}_check_ld_so_conf
14938889Sjdp  PARAMS ((const char *, int));
15033965Sjdp
15133965Sjdpstatic boolean
15238889Sjdpgld${EMULATION_NAME}_check_ld_so_conf (name, force)
15333965Sjdp     const char *name;
15438889Sjdp     int force;
15533965Sjdp{
15633965Sjdp  static boolean initialized;
15733965Sjdp  static char *ld_so_conf;
15833965Sjdp
15933965Sjdp  if (! initialized)
16033965Sjdp    {
16133965Sjdp      FILE *f;
16233965Sjdp
16333965Sjdp      f = fopen ("/etc/ld.so.conf", FOPEN_RT);
16433965Sjdp      if (f != NULL)
16533965Sjdp	{
16633965Sjdp	  char *b;
16733965Sjdp	  size_t len, alloc;
16833965Sjdp	  int c;
16933965Sjdp
17033965Sjdp	  len = 0;
17133965Sjdp	  alloc = 100;
17233965Sjdp	  b = (char *) xmalloc (alloc);
17333965Sjdp
17433965Sjdp	  while ((c = getc (f)) != EOF)
17533965Sjdp	    {
17633965Sjdp	      if (len + 1 >= alloc)
17733965Sjdp		{
17833965Sjdp		  alloc *= 2;
17933965Sjdp		  b = (char *) xrealloc (b, alloc);
18033965Sjdp		}
18133965Sjdp	      if (c != ':'
18233965Sjdp		  && c != ' '
18333965Sjdp		  && c != '\t'
18433965Sjdp		  && c != '\n'
18533965Sjdp		  && c != ',')
18633965Sjdp		{
18733965Sjdp		  b[len] = c;
18833965Sjdp		  ++len;
18933965Sjdp		}
19033965Sjdp	      else
19133965Sjdp		{
19233965Sjdp		  if (len > 0 && b[len - 1] != ':')
19333965Sjdp		    {
19433965Sjdp		      b[len] = ':';
19533965Sjdp		      ++len;
19633965Sjdp		    }
19733965Sjdp		}
19833965Sjdp	    }
19933965Sjdp
20033965Sjdp	  if (len > 0 && b[len - 1] == ':')
20133965Sjdp	    --len;
20233965Sjdp
20333965Sjdp	  if (len > 0)
20433965Sjdp	    b[len] = '\0';
20533965Sjdp	  else
20633965Sjdp	    {
20733965Sjdp	      free (b);
20833965Sjdp	      b = NULL;
20933965Sjdp	    }
21033965Sjdp
21133965Sjdp	  fclose (f);
21233965Sjdp
21333965Sjdp	  ld_so_conf = b;
21433965Sjdp	}
21533965Sjdp
21633965Sjdp      initialized = true;
21733965Sjdp    }
21833965Sjdp
21933965Sjdp  if (ld_so_conf == NULL)
22033965Sjdp    return false;
22133965Sjdp
22238889Sjdp  return gld${EMULATION_NAME}_search_needed (ld_so_conf, name, force);
22333965Sjdp}
22433965Sjdp
22533965SjdpEOF
22633965Sjdp  fi
22733965Sjdpfi
22833965Sjdpcat >>e${EMULATION_NAME}.c <<EOF
22933965Sjdp
23033965Sjdp/* These variables are required to pass information back and forth
23138889Sjdp   between after_open and check_needed and stat_needed and vercheck.  */
23233965Sjdp
23333965Sjdpstatic struct bfd_link_needed_list *global_needed;
23433965Sjdpstatic struct stat global_stat;
23533965Sjdpstatic boolean global_found;
23638889Sjdpstatic struct bfd_link_needed_list *global_vercheck_needed;
23738889Sjdpstatic boolean global_vercheck_failed;
23833965Sjdp
23933965Sjdp/* This is called after all the input files have been opened.  */
24033965Sjdp
24133965Sjdpstatic void
24233965Sjdpgld${EMULATION_NAME}_after_open ()
24333965Sjdp{
24433965Sjdp  struct bfd_link_needed_list *needed, *l;
24533965Sjdp
24633965Sjdp  /* We only need to worry about this when doing a final link.  */
24733965Sjdp  if (link_info.relocateable || link_info.shared)
24833965Sjdp    return;
24933965Sjdp
25033965Sjdp  /* Get the list of files which appear in DT_NEEDED entries in
25133965Sjdp     dynamic objects included in the link (often there will be none).
25233965Sjdp     For each such file, we want to track down the corresponding
25333965Sjdp     library, and include the symbol table in the link.  This is what
25433965Sjdp     the runtime dynamic linker will do.  Tracking the files down here
25533965Sjdp     permits one dynamic object to include another without requiring
25633965Sjdp     special action by the person doing the link.  Note that the
25733965Sjdp     needed list can actually grow while we are stepping through this
25833965Sjdp     loop.  */
25933965Sjdp  needed = bfd_elf_get_needed_list (output_bfd, &link_info);
26033965Sjdp  for (l = needed; l != NULL; l = l->next)
26133965Sjdp    {
26233965Sjdp      struct bfd_link_needed_list *ll;
26338889Sjdp      int force;
26433965Sjdp
26533965Sjdp      /* If we've already seen this file, skip it.  */
26633965Sjdp      for (ll = needed; ll != l; ll = ll->next)
26733965Sjdp	if (strcmp (ll->name, l->name) == 0)
26833965Sjdp	  break;
26933965Sjdp      if (ll != l)
27033965Sjdp	continue;
27133965Sjdp
27233965Sjdp      /* See if this file was included in the link explicitly.  */
27333965Sjdp      global_needed = l;
27433965Sjdp      global_found = false;
27533965Sjdp      lang_for_each_input_file (gld${EMULATION_NAME}_check_needed);
27633965Sjdp      if (global_found)
27733965Sjdp	continue;
27833965Sjdp
27933965Sjdp      /* We need to find this file and include the symbol table.  We
28033965Sjdp	 want to search for the file in the same way that the dynamic
28133965Sjdp	 linker will search.  That means that we want to use
28233965Sjdp	 rpath_link, rpath, then the environment variable
28333965Sjdp	 LD_LIBRARY_PATH (native only), then the linker script
28438889Sjdp	 LIB_SEARCH_DIRS.  We do not search using the -L arguments.
28538889Sjdp
28638889Sjdp	 We search twice.  The first time, we skip objects which may
28738889Sjdp	 introduce version mismatches.  The second time, we force
28838889Sjdp	 their use.  See gld${EMULATION_NAME}_vercheck comment.  */
28938889Sjdp      for (force = 0; force < 2; force++)
29033965Sjdp	{
29138889Sjdp	  const char *lib_path;
29238889Sjdp	  size_t len;
29338889Sjdp	  search_dirs_type *search;
29438889Sjdp
29538889Sjdp	  if (gld${EMULATION_NAME}_search_needed (command_line.rpath_link,
29638889Sjdp						  l->name, force))
29738889Sjdp	    break;
29838889Sjdp	  if (gld${EMULATION_NAME}_search_needed (command_line.rpath,
29938889Sjdp						  l->name, force))
30038889Sjdp	    break;
30138889Sjdp	  if (command_line.rpath_link == NULL
30238889Sjdp	      && command_line.rpath == NULL)
30338889Sjdp	    {
30438889Sjdp	      lib_path = (const char *) getenv ("LD_RUN_PATH");
30538889Sjdp	      if (gld${EMULATION_NAME}_search_needed (lib_path, l->name,
30638889Sjdp						      force))
30738889Sjdp		break;
30838889Sjdp	    }
30933965SjdpEOF
31033965Sjdpif [ "x${host}" = "x${target}" ] ; then
31133965Sjdp  if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then
31233965Sjdpcat >>e${EMULATION_NAME}.c <<EOF
31338889Sjdp	  lib_path = (const char *) getenv ("LD_LIBRARY_PATH");
31438889Sjdp	  if (gld${EMULATION_NAME}_search_needed (lib_path, l->name, force))
31538889Sjdp	    break;
31633965SjdpEOF
31733965Sjdp  fi
31833965Sjdpfi
31933965Sjdpcat >>e${EMULATION_NAME}.c <<EOF
32038889Sjdp	  len = strlen (l->name);
32138889Sjdp	  for (search = search_head; search != NULL; search = search->next)
32238889Sjdp	    {
32338889Sjdp	      char *filename;
32433965Sjdp
32538889Sjdp	      if (search->cmdline)
32638889Sjdp		continue;
32738889Sjdp	      filename = (char *) xmalloc (strlen (search->name) + len + 2);
32838889Sjdp	      sprintf (filename, "%s/%s", search->name, l->name);
32938889Sjdp	      if (gld${EMULATION_NAME}_try_needed (filename, force))
33038889Sjdp		break;
33138889Sjdp	      free (filename);
33238889Sjdp	    }
33338889Sjdp	  if (search != NULL)
33433965Sjdp	    break;
33533965SjdpEOF
33633965Sjdpif [ "x${host}" = "x${target}" ] ; then
33733965Sjdp  if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then
33833965Sjdpcat >>e${EMULATION_NAME}.c <<EOF
33938889Sjdp	  if (gld${EMULATION_NAME}_check_ld_so_conf (l->name, force))
34038889Sjdp	    break;
34133965SjdpEOF
34233965Sjdp  fi
34333965Sjdpfi
34433965Sjdpcat >>e${EMULATION_NAME}.c <<EOF
34538889Sjdp	}
34633965Sjdp
34738889Sjdp      if (force < 2)
34838889Sjdp	continue;
34938889Sjdp
35033965Sjdp      einfo ("%P: warning: %s, needed by %B, not found (try using --rpath)\n",
35133965Sjdp	     l->name, l->by);
35233965Sjdp    }
35333965Sjdp}
35433965Sjdp
35533965Sjdp/* Search for a needed file in a path.  */
35633965Sjdp
35733965Sjdpstatic boolean
35838889Sjdpgld${EMULATION_NAME}_search_needed (path, name, force)
35933965Sjdp     const char *path;
36033965Sjdp     const char *name;
36138889Sjdp     int force;
36233965Sjdp{
36333965Sjdp  const char *s;
36433965Sjdp  size_t len;
36533965Sjdp
36633965Sjdp  if (path == NULL || *path == '\0')
36733965Sjdp    return false;
36833965Sjdp  len = strlen (name);
36933965Sjdp  while (1)
37033965Sjdp    {
37133965Sjdp      char *filename, *sset;
37233965Sjdp
37333965Sjdp      s = strchr (path, ':');
37433965Sjdp      if (s == NULL)
37533965Sjdp	s = path + strlen (path);
37633965Sjdp
37733965Sjdp      filename = (char *) xmalloc (s - path + len + 2);
37833965Sjdp      if (s == path)
37933965Sjdp	sset = filename;
38033965Sjdp      else
38133965Sjdp	{
38233965Sjdp	  memcpy (filename, path, s - path);
38333965Sjdp	  filename[s - path] = '/';
38433965Sjdp	  sset = filename + (s - path) + 1;
38533965Sjdp	}
38633965Sjdp      strcpy (sset, name);
38733965Sjdp
38838889Sjdp      if (gld${EMULATION_NAME}_try_needed (filename, force))
38933965Sjdp	return true;
39033965Sjdp
39133965Sjdp      free (filename);
39233965Sjdp
39333965Sjdp      if (*s == '\0')
39433965Sjdp	break;
39533965Sjdp      path = s + 1;
39633965Sjdp    }
39733965Sjdp
39833965Sjdp  return false;	  
39933965Sjdp}
40033965Sjdp
40133965Sjdp/* This function is called for each possible name for a dynamic object
40238889Sjdp   named by a DT_NEEDED entry.  The FORCE parameter indicates whether
40338889Sjdp   to skip the check for a conflicting version.  */
40433965Sjdp
40533965Sjdpstatic boolean
40638889Sjdpgld${EMULATION_NAME}_try_needed (name, force)
40733965Sjdp     const char *name;
40838889Sjdp     int force;
40933965Sjdp{
41033965Sjdp  bfd *abfd;
41133965Sjdp
41233965Sjdp  abfd = bfd_openr (name, bfd_get_target (output_bfd));
41333965Sjdp  if (abfd == NULL)
41433965Sjdp    return false;
41533965Sjdp  if (! bfd_check_format (abfd, bfd_object))
41633965Sjdp    {
41733965Sjdp      (void) bfd_close (abfd);
41833965Sjdp      return false;
41933965Sjdp    }
42033965Sjdp  if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0)
42133965Sjdp    {
42233965Sjdp      (void) bfd_close (abfd);
42333965Sjdp      return false;
42433965Sjdp    }
42533965Sjdp
42638889Sjdp  /* Check whether this object would include any conflicting library
42738889Sjdp     versions.  If FORCE is set, then we skip this check; we use this
42838889Sjdp     the second time around, if we couldn't find any compatible
42938889Sjdp     instance of the shared library.  */
43038889Sjdp
43138889Sjdp  if (! force)
43238889Sjdp    {
43338889Sjdp      struct bfd_link_needed_list *needed;
43438889Sjdp
43538889Sjdp      if (! bfd_elf_get_bfd_needed_list (abfd, &needed))
43638889Sjdp	einfo ("%F%P:%B: bfd_elf_get_bfd_needed_list failed: %E\n", abfd);
43738889Sjdp
43838889Sjdp      if (needed != NULL)
43938889Sjdp	{
44038889Sjdp	  global_vercheck_needed = needed;
44138889Sjdp	  global_vercheck_failed = false;
44238889Sjdp	  lang_for_each_input_file (gld${EMULATION_NAME}_vercheck);
44338889Sjdp	  if (global_vercheck_failed)
44438889Sjdp	    {
44538889Sjdp	      (void) bfd_close (abfd);
44638889Sjdp	      /* Return false to force the caller to move on to try
44738889Sjdp                 another file on the search path.  */
44838889Sjdp	      return false;
44938889Sjdp	    }
45038889Sjdp
45138889Sjdp	  /* But wait!  It gets much worse.  On Linux, if a shared
45238889Sjdp             library does not use libc at all, we are supposed to skip
45338889Sjdp             it the first time around in case we encounter a shared
45438889Sjdp             library later on with the same name which does use the
45538889Sjdp             version of libc that we want.  This is much too horrible
45638889Sjdp             to use on any system other than Linux.  */
45738889Sjdp
45838889SjdpEOF
45938889Sjdpcase ${target} in
46038889Sjdp  *-*-linux-gnu*)
46138889Sjdp    cat >>e${EMULATION_NAME}.c <<EOF
46238889Sjdp	  {
46338889Sjdp	    struct bfd_link_needed_list *l;
46438889Sjdp
46538889Sjdp	    for (l = needed; l != NULL; l = l->next)
46638889Sjdp	      if (strncmp (l->name, "libc.so", 7) == 0)
46738889Sjdp		break;
46838889Sjdp	    if (l == NULL)
46938889Sjdp	      {
47038889Sjdp		(void) bfd_close (abfd);
47138889Sjdp		return false;
47238889Sjdp	      }
47338889Sjdp	  }
47438889Sjdp
47538889SjdpEOF
47638889Sjdp    ;;
47738889Sjdpesac
47838889Sjdpcat >>e${EMULATION_NAME}.c <<EOF
47938889Sjdp	}
48038889Sjdp    }
48138889Sjdp
48233965Sjdp  /* We've found a dynamic object matching the DT_NEEDED entry.  */
48333965Sjdp
48433965Sjdp  /* We have already checked that there is no other input file of the
48533965Sjdp     same name.  We must now check again that we are not including the
48633965Sjdp     same file twice.  We need to do this because on many systems
48733965Sjdp     libc.so is a symlink to, e.g., libc.so.1.  The SONAME entry will
48833965Sjdp     reference libc.so.1.  If we have already included libc.so, we
48933965Sjdp     don't want to include libc.so.1 if they are the same file, and we
49033965Sjdp     can only check that using stat.  */
49133965Sjdp
49233965Sjdp  if (bfd_stat (abfd, &global_stat) != 0)
49333965Sjdp    einfo ("%F%P:%B: bfd_stat failed: %E\n", abfd);
49433965Sjdp  global_found = false;
49533965Sjdp  lang_for_each_input_file (gld${EMULATION_NAME}_stat_needed);
49633965Sjdp  if (global_found)
49733965Sjdp    {
49833965Sjdp      /* Return true to indicate that we found the file, even though
49933965Sjdp         we aren't going to do anything with it.  */
50033965Sjdp      return true;
50133965Sjdp    }
50233965Sjdp
50333965Sjdp  /* Tell the ELF backend that don't want the output file to have a
50433965Sjdp     DT_NEEDED entry for this file.  */
50533965Sjdp  bfd_elf_set_dt_needed_name (abfd, "");
50633965Sjdp
50733965Sjdp  /* Add this file into the symbol table.  */
50833965Sjdp  if (! bfd_link_add_symbols (abfd, &link_info))
50933965Sjdp    einfo ("%F%B: could not read symbols: %E\n", abfd);
51033965Sjdp
51133965Sjdp  return true;
51233965Sjdp}
51333965Sjdp
51433965Sjdp/* See if an input file matches a DT_NEEDED entry by name.  */
51533965Sjdp
51633965Sjdpstatic void
51733965Sjdpgld${EMULATION_NAME}_check_needed (s)
51833965Sjdp     lang_input_statement_type *s;
51933965Sjdp{
52033965Sjdp  if (global_found)
52133965Sjdp    return;
52233965Sjdp
52333965Sjdp  if (s->filename != NULL
52433965Sjdp      && strcmp (s->filename, global_needed->name) == 0)
52533965Sjdp    {
52633965Sjdp      global_found = true;
52733965Sjdp      return;
52833965Sjdp    }
52933965Sjdp
53033965Sjdp  if (s->the_bfd != NULL)
53133965Sjdp    {
53233965Sjdp      const char *soname;
53333965Sjdp
53433965Sjdp      soname = bfd_elf_get_dt_soname (s->the_bfd);
53533965Sjdp      if (soname != NULL
53633965Sjdp	  && strcmp (soname, global_needed->name) == 0)
53733965Sjdp	{
53833965Sjdp	  global_found = true;
53933965Sjdp	  return;
54033965Sjdp	}
54133965Sjdp    }
54233965Sjdp	  
54333965Sjdp  if (s->search_dirs_flag
54433965Sjdp      && s->filename != NULL
54533965Sjdp      && strchr (global_needed->name, '/') == NULL)
54633965Sjdp    {
54733965Sjdp      const char *f;
54833965Sjdp
54933965Sjdp      f = strrchr (s->filename, '/');
55033965Sjdp      if (f != NULL
55133965Sjdp	  && strcmp (f + 1, global_needed->name) == 0)
55233965Sjdp	{
55333965Sjdp	  global_found = true;
55433965Sjdp	  return;
55533965Sjdp	}
55633965Sjdp    }
55733965Sjdp}
55833965Sjdp
55933965Sjdp/* See if an input file matches a DT_NEEDED entry by running stat on
56033965Sjdp   the file.  */
56133965Sjdp
56233965Sjdpstatic void
56333965Sjdpgld${EMULATION_NAME}_stat_needed (s)
56433965Sjdp     lang_input_statement_type *s;
56533965Sjdp{
56633965Sjdp  struct stat st;
56733965Sjdp  const char *suffix;
56833965Sjdp  const char *soname;
56933965Sjdp  const char *f;
57033965Sjdp
57133965Sjdp  if (global_found)
57233965Sjdp    return;
57333965Sjdp  if (s->the_bfd == NULL)
57433965Sjdp    return;
57533965Sjdp
57633965Sjdp  if (bfd_stat (s->the_bfd, &st) != 0)
57733965Sjdp    {
57833965Sjdp      einfo ("%P:%B: bfd_stat failed: %E\n", s->the_bfd);
57933965Sjdp      return;
58033965Sjdp    }
58133965Sjdp
58233965Sjdp  if (st.st_dev == global_stat.st_dev
58333965Sjdp      && st.st_ino == global_stat.st_ino)
58433965Sjdp    {
58533965Sjdp      global_found = true;
58633965Sjdp      return;
58733965Sjdp    }
58833965Sjdp
58933965Sjdp  /* We issue a warning if it looks like we are including two
59033965Sjdp     different versions of the same shared library.  For example,
59133965Sjdp     there may be a problem if -lc picks up libc.so.6 but some other
59233965Sjdp     shared library has a DT_NEEDED entry of libc.so.5.  This is a
59333965Sjdp     hueristic test, and it will only work if the name looks like
59433965Sjdp     NAME.so.VERSION.  FIXME: Depending on file names is error-prone.
59533965Sjdp     If we really want to issue warnings about mixing version numbers
59633965Sjdp     of shared libraries, we need to find a better way.  */
59733965Sjdp
59833965Sjdp  if (strchr (global_needed->name, '/') != NULL)
59933965Sjdp    return;
60033965Sjdp  suffix = strstr (global_needed->name, ".so.");
60133965Sjdp  if (suffix == NULL)
60233965Sjdp    return;
60333965Sjdp  suffix += sizeof ".so." - 1;
60433965Sjdp
60533965Sjdp  soname = bfd_elf_get_dt_soname (s->the_bfd);
60633965Sjdp  if (soname == NULL)
60733965Sjdp    soname = s->filename;
60833965Sjdp
60933965Sjdp  f = strrchr (soname, '/');
61033965Sjdp  if (f != NULL)
61133965Sjdp    ++f;
61233965Sjdp  else
61333965Sjdp    f = soname;
61433965Sjdp
61533965Sjdp  if (strncmp (f, global_needed->name, suffix - global_needed->name) == 0)
61633965Sjdp    einfo ("%P: warning: %s, needed by %B, may conflict with %s\n",
61733965Sjdp	   global_needed->name, global_needed->by, f);
61833965Sjdp}
61933965Sjdp
62038889Sjdp/* On Linux, it's possible to have different versions of the same
62138889Sjdp   shared library linked against different versions of libc.  The
62238889Sjdp   dynamic linker somehow tags which libc version to use in
62338889Sjdp   /etc/ld.so.cache, and, based on the libc that it sees in the
62438889Sjdp   executable, chooses which version of the shared library to use.
62538889Sjdp
62638889Sjdp   We try to do a similar check here by checking whether this shared
62738889Sjdp   library needs any other shared libraries which may conflict with
62838889Sjdp   libraries we have already included in the link.  If it does, we
62938889Sjdp   skip it, and try to find another shared library farther on down the
63038889Sjdp   link path.
63138889Sjdp
63238889Sjdp   This is called via lang_for_each_input_file.
63338889Sjdp   GLOBAL_VERCHECK_NEEDED is the list of objects needed by the object
63438889Sjdp   which we ar checking.  This sets GLOBAL_VERCHECK_FAILED if we find
63538889Sjdp   a conflicting version.  */
63638889Sjdp
63738889Sjdpstatic void
63838889Sjdpgld${EMULATION_NAME}_vercheck (s)
63938889Sjdp     lang_input_statement_type *s;
64038889Sjdp{
64138889Sjdp  const char *soname, *f;
64238889Sjdp  struct bfd_link_needed_list *l;
64338889Sjdp
64438889Sjdp  if (global_vercheck_failed)
64538889Sjdp    return;
64638889Sjdp  if (s->the_bfd == NULL
64738889Sjdp      || (bfd_get_file_flags (s->the_bfd) & DYNAMIC) == 0)
64838889Sjdp    return;
64938889Sjdp
65038889Sjdp  soname = bfd_elf_get_dt_soname (s->the_bfd);
65138889Sjdp  if (soname == NULL)
65238889Sjdp    soname = bfd_get_filename (s->the_bfd);
65338889Sjdp
65438889Sjdp  f = strrchr (soname, '/');
65538889Sjdp  if (f != NULL)
65638889Sjdp    ++f;
65738889Sjdp  else
65838889Sjdp    f = soname;
65938889Sjdp
66038889Sjdp  for (l = global_vercheck_needed; l != NULL; l = l->next)
66138889Sjdp    {
66238889Sjdp      const char *suffix;
66338889Sjdp
66438889Sjdp      if (strcmp (f, l->name) == 0)
66538889Sjdp	{
66638889Sjdp	  /* Probably can't happen, but it's an easy check.  */
66738889Sjdp	  continue;
66838889Sjdp	}
66938889Sjdp
67038889Sjdp      if (strchr (l->name, '/') != NULL)
67138889Sjdp	continue;
67238889Sjdp
67338889Sjdp      suffix = strstr (l->name, ".so.");
67438889Sjdp      if (suffix == NULL)
67538889Sjdp	continue;
67638889Sjdp
67738889Sjdp      suffix += sizeof ".so." - 1;
67838889Sjdp
67938889Sjdp      if (strncmp (f, l->name, suffix - l->name) == 0)
68038889Sjdp	{
68138889Sjdp	  /* Here we know that S is a dynamic object FOO.SO.VER1, and
68238889Sjdp             the object we are considering needs a dynamic object
68338889Sjdp             FOO.SO.VER2, and VER1 and VER2 are different.  This
68438889Sjdp             appears to be a version mismatch, so we tell the caller
68538889Sjdp             to try a different version of this library.  */
68638889Sjdp	  global_vercheck_failed = true;
68738889Sjdp	  return;
68838889Sjdp	}
68938889Sjdp    }
69038889Sjdp}
69138889Sjdp
69233965Sjdp/* This is called after the sections have been attached to output
69333965Sjdp   sections, but before any sizes or addresses have been set.  */
69433965Sjdp
69533965Sjdpstatic void
69633965Sjdpgld${EMULATION_NAME}_before_allocation ()
69733965Sjdp{
69833965Sjdp  const char *rpath;
69933965Sjdp  asection *sinterp;
70033965Sjdp
70133965Sjdp  /* If we are going to make any variable assignments, we need to let
70233965Sjdp     the ELF backend know about them in case the variables are
70333965Sjdp     referred to by dynamic objects.  */
70433965Sjdp  lang_for_each_statement (gld${EMULATION_NAME}_find_statement_assignment);
70533965Sjdp
70633965Sjdp  /* Let the ELF backend work out the sizes of any sections required
70733965Sjdp     by dynamic linking.  */
70833965Sjdp  rpath = command_line.rpath;
70933965Sjdp  if (rpath == NULL)
71033965Sjdp    rpath = (const char *) getenv ("LD_RUN_PATH");
71133965Sjdp  if (! (bfd_elf${ELFSIZE}_size_dynamic_sections
71233965Sjdp         (output_bfd, command_line.soname, rpath,
71333965Sjdp	  command_line.export_dynamic, command_line.filter_shlib,
71433965Sjdp	  (const char * const *) command_line.auxiliary_filters,
71533965Sjdp	  &link_info, &sinterp, lang_elf_version_info)))
71633965Sjdp    einfo ("%P%F: failed to set dynamic section sizes: %E\n");
71733965Sjdp
71833965Sjdp  /* Let the user override the dynamic linker we are using.  */
71933965Sjdp  if (command_line.interpreter != NULL
72033965Sjdp      && sinterp != NULL)
72133965Sjdp    {
72233965Sjdp      sinterp->contents = (bfd_byte *) command_line.interpreter;
72333965Sjdp      sinterp->_raw_size = strlen (command_line.interpreter) + 1;
72433965Sjdp    }
72533965Sjdp
72633965Sjdp  /* Look for any sections named .gnu.warning.  As a GNU extensions,
72733965Sjdp     we treat such sections as containing warning messages.  We print
72833965Sjdp     out the warning message, and then zero out the section size so
72933965Sjdp     that it does not get copied into the output file.  */
73033965Sjdp
73133965Sjdp  {
73233965Sjdp    LANG_FOR_EACH_INPUT_STATEMENT (is)
73333965Sjdp      {
73433965Sjdp	asection *s;
73533965Sjdp	bfd_size_type sz;
73633965Sjdp	char *msg;
73733965Sjdp	boolean ret;
73833965Sjdp
73933965Sjdp	if (is->just_syms_flag)
74033965Sjdp	  continue;
74133965Sjdp
74233965Sjdp	s = bfd_get_section_by_name (is->the_bfd, ".gnu.warning");
74333965Sjdp	if (s == NULL)
74433965Sjdp	  continue;
74533965Sjdp
74633965Sjdp	sz = bfd_section_size (is->the_bfd, s);
74733965Sjdp	msg = xmalloc ((size_t) sz + 1);
74833965Sjdp	if (! bfd_get_section_contents (is->the_bfd, s, msg, (file_ptr) 0, sz))
74933965Sjdp	  einfo ("%F%B: Can't read contents of section .gnu.warning: %E\n",
75033965Sjdp		 is->the_bfd);
75133965Sjdp	msg[sz] = '\0';
75233965Sjdp	ret = link_info.callbacks->warning (&link_info, msg,
75333965Sjdp					    (const char *) NULL,
75433965Sjdp					    is->the_bfd, (asection *) NULL,
75533965Sjdp					    (bfd_vma) 0);
75633965Sjdp	ASSERT (ret);
75733965Sjdp	free (msg);
75833965Sjdp
75933965Sjdp	/* Clobber the section size, so that we don't waste copying the
76033965Sjdp	   warning into the output file.  */
76133965Sjdp	s->_raw_size = 0;
76233965Sjdp      }
76333965Sjdp  }
76433965Sjdp
76533965Sjdp#if defined (TARGET_IS_elf32bmip) || defined (TARGET_IS_elf32lmip)
76633965Sjdp  /* For MIPS ELF the .reginfo section requires special handling.
76733965Sjdp     Each input section is 24 bytes, and the final output section must
76833965Sjdp     also be 24 bytes.  We handle this by clobbering all but the first
76933965Sjdp     input section size to 0.  The .reginfo section is handled
77033965Sjdp     specially by the backend code anyhow.  */
77133965Sjdp  {
77233965Sjdp    boolean found = false;
77333965Sjdp    LANG_FOR_EACH_INPUT_STATEMENT (is)
77433965Sjdp      {
77533965Sjdp	asection *s;
77633965Sjdp
77733965Sjdp	if (is->just_syms_flag)
77833965Sjdp	  continue;
77933965Sjdp
78033965Sjdp	s = bfd_get_section_by_name (is->the_bfd, ".reginfo");
78133965Sjdp	if (s == NULL)
78233965Sjdp	  continue;
78333965Sjdp
78433965Sjdp	if (! found)
78533965Sjdp	  {
78633965Sjdp	    found = true;
78733965Sjdp	    continue;
78833965Sjdp	  }
78933965Sjdp
79033965Sjdp	s->_raw_size = 0;
79133965Sjdp	s->_cooked_size = 0;
79233965Sjdp      }
79333965Sjdp  }
79433965Sjdp#endif
79533965Sjdp}
79633965Sjdp
79733965Sjdp/* This is called by the before_allocation routine via
79833965Sjdp   lang_for_each_statement.  It locates any assignment statements, and
79933965Sjdp   tells the ELF backend about them, in case they are assignments to
80033965Sjdp   symbols which are referred to by dynamic objects.  */
80133965Sjdp
80233965Sjdpstatic void
80333965Sjdpgld${EMULATION_NAME}_find_statement_assignment (s)
80433965Sjdp     lang_statement_union_type *s;
80533965Sjdp{
80633965Sjdp  if (s->header.type == lang_assignment_statement_enum)
80733965Sjdp    gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp);
80833965Sjdp}
80933965Sjdp
81033965Sjdp/* Look through an expression for an assignment statement.  */
81133965Sjdp
81233965Sjdpstatic void
81333965Sjdpgld${EMULATION_NAME}_find_exp_assignment (exp)
81433965Sjdp     etree_type *exp;
81533965Sjdp{
81633965Sjdp  struct bfd_link_hash_entry *h;
81733965Sjdp
81833965Sjdp  switch (exp->type.node_class)
81933965Sjdp    {
82033965Sjdp    case etree_provide:
82133965Sjdp      h = bfd_link_hash_lookup (link_info.hash, exp->assign.dst,
82233965Sjdp				false, false, false);
82333965Sjdp      if (h == NULL)
82433965Sjdp	break;
82533965Sjdp
82633965Sjdp      /* We call record_link_assignment even if the symbol is defined.
82733965Sjdp	 This is because if it is defined by a dynamic object, we
82833965Sjdp	 actually want to use the value defined by the linker script,
82933965Sjdp	 not the value from the dynamic object (because we are setting
83033965Sjdp	 symbols like etext).  If the symbol is defined by a regular
83133965Sjdp	 object, then, as it happens, calling record_link_assignment
83233965Sjdp	 will do no harm.  */
83333965Sjdp
83433965Sjdp      /* Fall through.  */
83533965Sjdp    case etree_assign:
83633965Sjdp      if (strcmp (exp->assign.dst, ".") != 0)
83733965Sjdp	{
83833965Sjdp	  if (! (bfd_elf${ELFSIZE}_record_link_assignment
83933965Sjdp		 (output_bfd, &link_info, exp->assign.dst,
84033965Sjdp		  exp->type.node_class == etree_provide ? true : false)))
84133965Sjdp	    einfo ("%P%F: failed to record assignment to %s: %E\n",
84233965Sjdp		   exp->assign.dst);
84333965Sjdp	}
84433965Sjdp      gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src);
84533965Sjdp      break;
84633965Sjdp
84733965Sjdp    case etree_binary:
84833965Sjdp      gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs);
84933965Sjdp      gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs);
85033965Sjdp      break;
85133965Sjdp
85233965Sjdp    case etree_trinary:
85333965Sjdp      gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.cond);
85433965Sjdp      gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs);
85533965Sjdp      gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs);
85633965Sjdp      break;
85733965Sjdp
85833965Sjdp    case etree_unary:
85933965Sjdp      gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child);
86033965Sjdp      break;
86133965Sjdp
86233965Sjdp    default:
86333965Sjdp      break;
86433965Sjdp    }
86533965Sjdp}
86633965Sjdp
86733965Sjdp/* Place an orphan section.  We use this to put random SHF_ALLOC
86833965Sjdp   sections in the right segment.  */
86933965Sjdp
87033965Sjdpstatic asection *hold_section;
87133965Sjdpstatic lang_output_section_statement_type *hold_use;
87233965Sjdpstatic lang_output_section_statement_type *hold_text;
87333965Sjdpstatic lang_output_section_statement_type *hold_rodata;
87433965Sjdpstatic lang_output_section_statement_type *hold_data;
87533965Sjdpstatic lang_output_section_statement_type *hold_bss;
87633965Sjdpstatic lang_output_section_statement_type *hold_rel;
87733965Sjdpstatic lang_output_section_statement_type *hold_interp;
87833965Sjdp
87933965Sjdp/*ARGSUSED*/
88033965Sjdpstatic boolean
88133965Sjdpgld${EMULATION_NAME}_place_orphan (file, s)
88233965Sjdp     lang_input_statement_type *file;
88333965Sjdp     asection *s;
88433965Sjdp{
88533965Sjdp  lang_output_section_statement_type *place;
88633965Sjdp  asection *snew, **pps;
88733965Sjdp  lang_statement_list_type *old;
88833965Sjdp  lang_statement_list_type add;
88933965Sjdp  etree_type *address;
89033965Sjdp  const char *secname, *ps;
89133965Sjdp  const char *outsecname;
89233965Sjdp  lang_output_section_statement_type *os;
89333965Sjdp
89433965Sjdp  if ((s->flags & SEC_ALLOC) == 0)
89533965Sjdp    return false;
89633965Sjdp
89733965Sjdp  /* Look through the script to see where to place this section.  */
89833965Sjdp  hold_section = s;
89933965Sjdp  hold_use = NULL;
90033965Sjdp  lang_for_each_statement (gld${EMULATION_NAME}_place_section);
90133965Sjdp
90233965Sjdp  if (hold_use != NULL)
90333965Sjdp    {
90433965Sjdp      /* We have already placed a section with this name.  */
90533965Sjdp      wild_doit (&hold_use->children, s, hold_use, file);
90633965Sjdp      return true;
90733965Sjdp    }
90833965Sjdp
90933965Sjdp  secname = bfd_get_section_name (s->owner, s);
91033965Sjdp
91133965Sjdp  /* If this is a final link, then always put .gnu.warning.SYMBOL
91233965Sjdp     sections into the .text section to get them out of the way.  */
91333965Sjdp  if (! link_info.shared
91433965Sjdp      && ! link_info.relocateable
91533965Sjdp      && strncmp (secname, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0
91633965Sjdp      && hold_text != NULL)
91733965Sjdp    {
91833965Sjdp      wild_doit (&hold_text->children, s, hold_text, file);
91933965Sjdp      return true;
92033965Sjdp    }
92133965Sjdp
92233965Sjdp  /* Decide which segment the section should go in based on the
92333965Sjdp     section name and section flags.  We put loadable .note sections
92433965Sjdp     right after the .interp section, so that the PT_NOTE segment is
92533965Sjdp     stored right after the program headers where the OS can read it
92633965Sjdp     in the first page.  */
92733965Sjdp  place = NULL;
92833965Sjdp  if ((s->flags & SEC_LOAD) != 0
92933965Sjdp      && strncmp (secname, ".note", 4) == 0
93033965Sjdp      && hold_interp != NULL)
93133965Sjdp    place = hold_interp;
93233965Sjdp  else if ((s->flags & SEC_HAS_CONTENTS) == 0
93333965Sjdp	   && hold_bss != NULL)
93433965Sjdp    place = hold_bss;
93533965Sjdp  else if ((s->flags & SEC_READONLY) == 0
93633965Sjdp	   && hold_data != NULL)
93733965Sjdp    place = hold_data;
93833965Sjdp  else if (strncmp (secname, ".rel", 4) == 0
93933965Sjdp	   && hold_rel != NULL)
94033965Sjdp    place = hold_rel;
94133965Sjdp  else if ((s->flags & SEC_CODE) == 0
94233965Sjdp	   && (s->flags & SEC_READONLY) != 0
94333965Sjdp	   && hold_rodata != NULL)
94433965Sjdp    place = hold_rodata;
94533965Sjdp  else if ((s->flags & SEC_READONLY) != 0
94633965Sjdp	   && hold_text != NULL)
94733965Sjdp    place = hold_text;
94833965Sjdp  if (place == NULL)
94933965Sjdp    return false;
95033965Sjdp
95133965Sjdp  /* Choose a unique name for the section.  This will be needed if the
95233965Sjdp     same section name appears in the input file with different
95333965Sjdp     loadable or allocateable characteristics.  */
95433965Sjdp  outsecname = secname;
95533965Sjdp  if (bfd_get_section_by_name (output_bfd, outsecname) != NULL)
95633965Sjdp    {
95733965Sjdp      unsigned int len;
95833965Sjdp      char *newname;
95933965Sjdp      unsigned int i;
96033965Sjdp
96133965Sjdp      len = strlen (outsecname);
96233965Sjdp      newname = xmalloc (len + 5);
96333965Sjdp      strcpy (newname, outsecname);
96433965Sjdp      i = 0;
96533965Sjdp      do
96633965Sjdp	{
96733965Sjdp	  sprintf (newname + len, "%d", i);
96833965Sjdp	  ++i;
96933965Sjdp	}
97033965Sjdp      while (bfd_get_section_by_name (output_bfd, newname) != NULL);
97133965Sjdp
97233965Sjdp      outsecname = newname;
97333965Sjdp    }
97433965Sjdp
97533965Sjdp  /* Create the section in the output file, and put it in the right
97633965Sjdp     place.  This shuffling is to make the output file look neater.  */
97733965Sjdp  snew = bfd_make_section (output_bfd, outsecname);
97833965Sjdp  if (snew == NULL)
97933965Sjdp      einfo ("%P%F: output format %s cannot represent section called %s\n",
98033965Sjdp	     output_bfd->xvec->name, outsecname);
98133965Sjdp  if (place->bfd_section != NULL)
98233965Sjdp    {
98333965Sjdp      for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
98433965Sjdp	;
98533965Sjdp      *pps = snew->next;
98633965Sjdp      snew->next = place->bfd_section->next;
98733965Sjdp      place->bfd_section->next = snew;
98833965Sjdp    }
98933965Sjdp
99033965Sjdp  /* Start building a list of statements for this section.  */
99133965Sjdp  old = stat_ptr;
99233965Sjdp  stat_ptr = &add;
99333965Sjdp  lang_list_init (stat_ptr);
99433965Sjdp
99533965Sjdp  /* If the name of the section is representable in C, then create
99633965Sjdp     symbols to mark the start and the end of the section.  */
99733965Sjdp  for (ps = outsecname; *ps != '\0'; ps++)
99838889Sjdp    if (! isalnum ((unsigned char) *ps) && *ps != '_')
99933965Sjdp      break;
100033965Sjdp  if (*ps == '\0' && config.build_constructors)
100133965Sjdp    {
100233965Sjdp      char *symname;
100333965Sjdp
100433965Sjdp      symname = (char *) xmalloc (ps - outsecname + sizeof "__start_");
100533965Sjdp      sprintf (symname, "__start_%s", outsecname);
100633965Sjdp      lang_add_assignment (exp_assop ('=', symname,
100733965Sjdp				      exp_unop (ALIGN_K,
100833965Sjdp						exp_intop ((bfd_vma) 1
100933965Sjdp							   << s->alignment_power))));
101033965Sjdp    }
101133965Sjdp
101233965Sjdp  if (! link_info.relocateable)
101333965Sjdp    address = NULL;
101433965Sjdp  else
101533965Sjdp    address = exp_intop ((bfd_vma) 0);
101633965Sjdp
101733965Sjdp  lang_enter_output_section_statement (outsecname, address, 0,
101833965Sjdp				       (bfd_vma) 0,
101933965Sjdp				       (etree_type *) NULL,
102033965Sjdp				       (etree_type *) NULL,
102133965Sjdp				       (etree_type *) NULL);
102233965Sjdp
102333965Sjdp  os = lang_output_section_statement_lookup (outsecname);
102433965Sjdp  wild_doit (&os->children, s, os, file);
102533965Sjdp
102633965Sjdp  lang_leave_output_section_statement
102733965Sjdp    ((bfd_vma) 0, "*default*", (struct lang_output_section_phdr_list *) NULL);
102833965Sjdp  stat_ptr = &add;
102933965Sjdp
103033965Sjdp  if (*ps == '\0' && config.build_constructors)
103133965Sjdp    {
103233965Sjdp      char *symname;
103333965Sjdp
103433965Sjdp      symname = (char *) xmalloc (ps - outsecname + sizeof "__stop_");
103533965Sjdp      sprintf (symname, "__stop_%s", outsecname);
103633965Sjdp      lang_add_assignment (exp_assop ('=', symname,
103733965Sjdp				      exp_nameop (NAME, ".")));
103833965Sjdp    }
103933965Sjdp
104033965Sjdp  /* Now stick the new statement list right after PLACE.  */
104133965Sjdp  *add.tail = place->header.next;
104233965Sjdp  place->header.next = add.head;
104333965Sjdp
104433965Sjdp  stat_ptr = old;
104533965Sjdp
104633965Sjdp  return true;
104733965Sjdp}
104833965Sjdp
104933965Sjdpstatic void
105033965Sjdpgld${EMULATION_NAME}_place_section (s)
105133965Sjdp     lang_statement_union_type *s;
105233965Sjdp{
105333965Sjdp  lang_output_section_statement_type *os;
105433965Sjdp
105533965Sjdp  if (s->header.type != lang_output_section_statement_enum)
105633965Sjdp    return;
105733965Sjdp
105833965Sjdp  os = &s->output_section_statement;
105933965Sjdp
106033965Sjdp  if (strcmp (os->name, hold_section->name) == 0
106138889Sjdp      && os->bfd_section != NULL
106233965Sjdp      && ((hold_section->flags & (SEC_LOAD | SEC_ALLOC))
106333965Sjdp	  == (os->bfd_section->flags & (SEC_LOAD | SEC_ALLOC))))
106433965Sjdp    hold_use = os;
106533965Sjdp
106633965Sjdp  if (strcmp (os->name, ".text") == 0)
106733965Sjdp    hold_text = os;
106833965Sjdp  else if (strcmp (os->name, ".rodata") == 0)
106933965Sjdp    hold_rodata = os;
107033965Sjdp  else if (strcmp (os->name, ".data") == 0)
107133965Sjdp    hold_data = os;
107233965Sjdp  else if (strcmp (os->name, ".bss") == 0)
107333965Sjdp    hold_bss = os;
107433965Sjdp  else if (hold_rel == NULL
107533965Sjdp	   && os->bfd_section != NULL
107633965Sjdp	   && (os->bfd_section->flags & SEC_ALLOC) != 0
107733965Sjdp	   && strncmp (os->name, ".rel", 4) == 0)
107833965Sjdp    hold_rel = os;
107933965Sjdp  else if (strcmp (os->name, ".interp") == 0)
108033965Sjdp    hold_interp = os;
108133965Sjdp}
108233965Sjdp
108333965Sjdpstatic char *
108433965Sjdpgld${EMULATION_NAME}_get_script(isfile)
108533965Sjdp     int *isfile;
108633965SjdpEOF
108733965Sjdp
108833965Sjdpif test -n "$COMPILE_IN"
108933965Sjdpthen
109033965Sjdp# Scripts compiled in.
109133965Sjdp
109233965Sjdp# sed commands to quote an ld script as a C string.
109333965Sjdpsc='s/["\\]/\\&/g
109433965Sjdps/$/\\n\\/
109533965Sjdp1s/^/"/
109633965Sjdp$s/$/n"/
109733965Sjdp'
109833965Sjdp
109933965Sjdpcat >>e${EMULATION_NAME}.c <<EOF
110033965Sjdp{			     
110133965Sjdp  *isfile = 0;
110233965Sjdp
110333965Sjdp  if (link_info.relocateable == true && config.build_constructors == true)
110433965Sjdp    return `sed "$sc" ldscripts/${EMULATION_NAME}.xu`;
110533965Sjdp  else if (link_info.relocateable == true)
110633965Sjdp    return `sed "$sc" ldscripts/${EMULATION_NAME}.xr`;
110733965Sjdp  else if (!config.text_read_only)
110833965Sjdp    return `sed "$sc" ldscripts/${EMULATION_NAME}.xbn`;
110933965Sjdp  else if (!config.magic_demand_paged)
111033965Sjdp    return `sed "$sc" ldscripts/${EMULATION_NAME}.xn`;
111133965Sjdp  else if (link_info.shared)
111233965Sjdp    return `sed "$sc" ldscripts/${EMULATION_NAME}.xs`;
111333965Sjdp  else
111433965Sjdp    return `sed "$sc" ldscripts/${EMULATION_NAME}.x`;
111533965Sjdp}
111633965SjdpEOF
111733965Sjdp
111833965Sjdpelse
111933965Sjdp# Scripts read from the filesystem.
112033965Sjdp
112133965Sjdpcat >>e${EMULATION_NAME}.c <<EOF
112233965Sjdp{			     
112333965Sjdp  *isfile = 1;
112433965Sjdp
112533965Sjdp  if (link_info.relocateable == true && config.build_constructors == true)
112633965Sjdp    return "ldscripts/${EMULATION_NAME}.xu";
112733965Sjdp  else if (link_info.relocateable == true)
112833965Sjdp    return "ldscripts/${EMULATION_NAME}.xr";
112933965Sjdp  else if (!config.text_read_only)
113033965Sjdp    return "ldscripts/${EMULATION_NAME}.xbn";
113133965Sjdp  else if (!config.magic_demand_paged)
113233965Sjdp    return "ldscripts/${EMULATION_NAME}.xn";
113333965Sjdp  else if (link_info.shared)
113433965Sjdp    return "ldscripts/${EMULATION_NAME}.xs";
113533965Sjdp  else
113633965Sjdp    return "ldscripts/${EMULATION_NAME}.x";
113733965Sjdp}
113833965SjdpEOF
113933965Sjdp
114033965Sjdpfi
114133965Sjdp
114233965Sjdpcat >>e${EMULATION_NAME}.c <<EOF
114333965Sjdp
114433965Sjdpstruct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = 
114533965Sjdp{
114633965Sjdp  gld${EMULATION_NAME}_before_parse,
114733965Sjdp  syslib_default,
114833965Sjdp  hll_default,
114933965Sjdp  after_parse_default,
115033965Sjdp  gld${EMULATION_NAME}_after_open,
115133965Sjdp  after_allocation_default,
115233965Sjdp  set_output_arch_default,
115333965Sjdp  ldemul_default_target,
115433965Sjdp  gld${EMULATION_NAME}_before_allocation,
115533965Sjdp  gld${EMULATION_NAME}_get_script,
115633965Sjdp  "${EMULATION_NAME}",
115733965Sjdp  "${OUTPUT_FORMAT}",
115833965Sjdp  NULL,
115933965Sjdp  NULL,
116033965Sjdp  gld${EMULATION_NAME}_open_dynamic_archive,
116133965Sjdp  gld${EMULATION_NAME}_place_orphan
116233965Sjdp};
116333965SjdpEOF
1164