Home | History | Annotate | Download | only in emultempl
      1 # This shell script emits a C file. -*- C -*-
      2 # It does some substitutions.
      3 if [ -z "$MACHINE" ]; then
      4   OUTPUT_ARCH=${ARCH}
      5 else
      6   OUTPUT_ARCH=${ARCH}:${MACHINE}
      7 fi
      8 fragment <<EOF
      9 /* This file is is generated by a shell script.  DO NOT EDIT! */
     10 
     11 /* SunOS emulation code for ${EMULATION_NAME}
     12    Copyright (C) 1991-2014 Free Software Foundation, Inc.
     13    Written by Steve Chamberlain <sac (a] cygnus.com>
     14    SunOS shared library support by Ian Lance Taylor <ian (a] cygnus.com>
     15 
     16    This file is part of the GNU Binutils.
     17 
     18    This program is free software; you can redistribute it and/or modify
     19    it under the terms of the GNU General Public License as published by
     20    the Free Software Foundation; either version 3 of the License, or
     21    (at your option) any later version.
     22 
     23    This program is distributed in the hope that it will be useful,
     24    but WITHOUT ANY WARRANTY; without even the implied warranty of
     25    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     26    GNU General Public License for more details.
     27 
     28    You should have received a copy of the GNU General Public License
     29    along with this program; if not, write to the Free Software
     30    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     31    MA 02110-1301, USA.  */
     32 
     33 #define TARGET_IS_${EMULATION_NAME}
     34 
     35 #include "sysdep.h"
     36 #include "bfd.h"
     37 #include "bfdlink.h"
     38 #include "libiberty.h"
     39 #include "safe-ctype.h"
     40 
     41 #include "ld.h"
     42 #include "ldmain.h"
     43 #include "ldmisc.h"
     44 #include "ldexp.h"
     45 #include "ldlang.h"
     46 #include "ldfile.h"
     47 #include "ldemul.h"
     48 
     49 #ifdef HAVE_DIRENT_H
     50 # include <dirent.h>
     51 #else
     52 # define dirent direct
     53 # ifdef HAVE_SYS_NDIR_H
     54 #  include <sys/ndir.h>
     55 # endif
     56 # ifdef HAVE_SYS_DIR_H
     57 #  include <sys/dir.h>
     58 # endif
     59 # ifdef HAVE_NDIR_H
     60 #  include <ndir.h>
     61 # endif
     62 #endif
     63 
     64 static void gld${EMULATION_NAME}_find_so
     65   (lang_input_statement_type *);
     66 static char *gld${EMULATION_NAME}_search_dir
     67   (const char *, const char *, bfd_boolean *);
     68 static void gld${EMULATION_NAME}_check_needed
     69   (lang_input_statement_type *);
     70 static bfd_boolean gld${EMULATION_NAME}_search_needed
     71   (const char *, const char *);
     72 static bfd_boolean gld${EMULATION_NAME}_try_needed
     73   (const char *, const char *);
     74 static void gld${EMULATION_NAME}_find_assignment
     75   (lang_statement_union_type *);
     76 static void gld${EMULATION_NAME}_find_exp_assignment
     77   (etree_type *);
     78 static void gld${EMULATION_NAME}_count_need
     79   (lang_input_statement_type *);
     80 static void gld${EMULATION_NAME}_set_need
     81   (lang_input_statement_type *);
     82 
     83 static void
     84 gld${EMULATION_NAME}_before_parse (void)
     85 {
     86   ldfile_set_output_arch ("${OUTPUT_ARCH}", bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`);
     87   input_flags.dynamic = TRUE;
     88   config.has_shared = TRUE;
     89 }
     90 
     91 /* This is called after the command line arguments have been parsed,
     92    but before the linker script has been read.  If this is a native
     93    linker, we add the directories in LD_LIBRARY_PATH to the search
     94    list.  */
     95 
     96 static void
     97 gld${EMULATION_NAME}_set_symbols (void)
     98 {
     99 EOF
    100 if [ "x${host}" = "x${target}" ] ; then
    101   case " ${EMULATION_LIBPATH} " in
    102   *" ${EMULATION_NAME} "*)
    103 fragment <<EOF
    104   const char *env;
    105 
    106   env = (const char *) getenv ("LD_LIBRARY_PATH");
    107   if (env != NULL)
    108     {
    109       char *l;
    110 
    111       l = xstrdup (env);
    112       while (1)
    113 	{
    114 	  char *c;
    115 
    116 	  c = strchr (l, ':');
    117 	  if (c != NULL)
    118 	    *c++ = '\0';
    119 	  if (*l != '\0')
    120 	    ldfile_add_library_path (l, FALSE);
    121 	  if (c == NULL)
    122 	    break;
    123 	  l = c;
    124 	}
    125     }
    126 EOF
    127   ;;
    128   esac
    129 fi
    130 fragment <<EOF
    131 }
    132 
    133 /* Despite the name, we use this routine to search for dynamic
    134    libraries.  On SunOS this requires a directory search.  We need to
    135    find the .so file with the highest version number.  The user may
    136    restrict the major version by saying, e.g., -lc.1.  Also, if we
    137    find a .so file, we need to look for a the same file after
    138    replacing .so with .sa; if it exists, it will be an archive which
    139    provide some initializations for data symbols, and we need to
    140    search it after including the .so file.  */
    141 
    142 static void
    143 gld${EMULATION_NAME}_create_output_section_statements (void)
    144 {
    145   lang_for_each_input_file (gld${EMULATION_NAME}_find_so);
    146 }
    147 
    148 /* Search the directory for a .so file for each library search.  */
    149 
    150 static void
    151 gld${EMULATION_NAME}_find_so (lang_input_statement_type *inp)
    152 {
    153   search_dirs_type *search;
    154   char *found = NULL;
    155   char *alc;
    156   struct stat st;
    157 
    158   if (! inp->flags.search_dirs
    159       || ! inp->flags.maybe_archive
    160       || ! inp->flags.dynamic)
    161     return;
    162 
    163   ASSERT (CONST_STRNEQ (inp->local_sym_name, "-l"));
    164 
    165   for (search = search_head; search != NULL; search = search->next)
    166     {
    167       bfd_boolean found_static;
    168 
    169       found = gld${EMULATION_NAME}_search_dir (search->name, inp->filename,
    170 					       &found_static);
    171       if (found != NULL || found_static)
    172 	break;
    173     }
    174 
    175   if (found == NULL)
    176     {
    177       /* We did not find a matching .so file.  This isn't an error,
    178 	 since there might still be a matching .a file, which will be
    179 	 found by the usual search.  */
    180       return;
    181     }
    182 
    183   /* Replace the filename with the one we have found.  */
    184   alc = (char *) xmalloc (strlen (search->name) + strlen (found) + 2);
    185   sprintf (alc, "%s/%s", search->name, found);
    186   inp->filename = alc;
    187 
    188   /* Turn off the search_dirs_flag to prevent ldfile_open_file from
    189      searching for this file again.  */
    190   inp->flags.search_dirs = FALSE;
    191 
    192   free (found);
    193 
    194   /* Now look for the same file name, but with .sa instead of .so.  If
    195      found, add it to the list of input files.  */
    196   alc = (char *) xmalloc (strlen (inp->filename) + 1);
    197   strcpy (alc, inp->filename);
    198   strstr (alc + strlen (search->name), ".so")[2] = 'a';
    199   if (stat (alc, &st) != 0)
    200     free (alc);
    201   else
    202     {
    203       lang_input_statement_type *sa;
    204 
    205       /* Add the .sa file to the statement list just before the .so
    206 	 file.  This is really a hack.  */
    207       sa = ((lang_input_statement_type *)
    208 	    xmalloc (sizeof (lang_input_statement_type)));
    209       *sa = *inp;
    210 
    211       inp->filename = alc;
    212       inp->local_sym_name = alc;
    213 
    214       inp->header.next = (lang_statement_union_type *) sa;
    215       inp->next_real_file = (lang_statement_union_type *) sa;
    216     }
    217 }
    218 
    219 /* Search a directory for a .so file.  */
    220 
    221 static char *
    222 gld${EMULATION_NAME}_search_dir
    223   (const char *dirname, const char *filename, bfd_boolean *found_static)
    224 {
    225   int force_maj, force_min;
    226   const char *dot;
    227   unsigned int len;
    228   char *alc;
    229   char *found;
    230   int max_maj, max_min;
    231   DIR *dir;
    232   struct dirent *entry;
    233   unsigned int dirnamelen;
    234   char *full_path;
    235   int statval;
    236   struct stat st;
    237 
    238   *found_static = FALSE;
    239 
    240   force_maj = -1;
    241   force_min = -1;
    242   dot = strchr (filename, '.');
    243   if (dot == NULL)
    244     {
    245       len = strlen (filename);
    246       alc = NULL;
    247     }
    248   else
    249     {
    250       force_maj = atoi (dot + 1);
    251 
    252       len = dot - filename;
    253       alc = (char *) xmalloc (len + 1);
    254       strncpy (alc, filename, len);
    255       alc[len] = '\0';
    256       filename = alc;
    257 
    258       dot = strchr (dot + 1, '.');
    259       if (dot != NULL)
    260 	force_min = atoi (dot + 1);
    261     }
    262 
    263   found = NULL;
    264   max_maj = max_min = 0;
    265 
    266   dir = opendir (dirname);
    267   if (dir == NULL)
    268     return NULL;
    269   dirnamelen = strlen (dirname);
    270 
    271   while ((entry = readdir (dir)) != NULL)
    272     {
    273       const char *s;
    274       int found_maj, found_min;
    275 
    276       if (! CONST_STRNEQ (entry->d_name, "lib")
    277 	  || strncmp (entry->d_name + 3, filename, len) != 0)
    278 	continue;
    279 
    280       if (dot == NULL
    281 	  && strcmp (entry->d_name + 3 + len, ".a") == 0)
    282 	{
    283 	  *found_static = TRUE;
    284 	  continue;
    285 	}
    286 
    287       /* We accept libfoo.so without a version number, even though the
    288 	 native linker does not.  This is more convenient for packages
    289 	 which just generate .so files for shared libraries, as on ELF
    290 	 systems.  */
    291       if (! CONST_STRNEQ (entry->d_name + 3 + len, ".so"))
    292 	continue;
    293       if (entry->d_name[6 + len] == '\0')
    294 	;
    295       else if (entry->d_name[6 + len] == '.'
    296 	       && ISDIGIT (entry->d_name[7 + len]))
    297 	;
    298       else
    299 	continue;
    300 
    301       for (s = entry->d_name + 6 + len; *s != '\0'; s++)
    302 	if (*s != '.' && ! ISDIGIT (*s))
    303 	  break;
    304       if (*s != '\0')
    305 	continue;
    306 
    307       /* We've found a .so file.  Work out the major and minor
    308 	 version numbers.  */
    309       found_maj = 0;
    310       found_min = 0;
    311       sscanf (entry->d_name + 3 + len, ".so.%d.%d",
    312 	      &found_maj, &found_min);
    313 
    314       if ((force_maj != -1 && force_maj != found_maj)
    315 	  || (force_min != -1 && force_min != found_min))
    316 	continue;
    317 
    318       /* Make sure the file really exists (ignore broken symlinks).  */
    319       full_path = xmalloc (dirnamelen + 1 + strlen (entry->d_name) + 1);
    320       sprintf (full_path, "%s/%s", dirname, entry->d_name);
    321       statval = stat (full_path, &st);
    322       free (full_path);
    323       if (statval != 0)
    324 	continue;
    325 
    326       /* We've found a match for the name we are searching for.  See
    327 	 if this is the version we should use.  If the major and minor
    328 	 versions match, we use the last entry in alphabetical order;
    329 	 I don't know if this is how SunOS distinguishes libc.so.1.8
    330 	 from libc.so.1.8.1, but it ought to suffice.  */
    331       if (found == NULL
    332 	  || (found_maj > max_maj)
    333 	  || (found_maj == max_maj
    334 	      && (found_min > max_min
    335 		  || (found_min == max_min
    336 		      && strcmp (entry->d_name, found) > 0))))
    337 	{
    338 	  if (found != NULL)
    339 	    free (found);
    340 	  found = (char *) xmalloc (strlen (entry->d_name) + 1);
    341 	  strcpy (found, entry->d_name);
    342 	  max_maj = found_maj;
    343 	  max_min = found_min;
    344 	}
    345     }
    346 
    347   closedir (dir);
    348 
    349   if (alc != NULL)
    350     free (alc);
    351 
    352   return found;
    353 }
    354 
    355 /* These variables are required to pass information back and forth
    356    between after_open and check_needed.  */
    357 
    358 static struct bfd_link_needed_list *global_needed;
    359 static bfd_boolean global_found;
    360 
    361 /* This is called after all the input files have been opened.  */
    362 
    363 static void
    364 gld${EMULATION_NAME}_after_open (void)
    365 {
    366   struct bfd_link_needed_list *needed, *l;
    367 
    368   after_open_default ();
    369 
    370   /* We only need to worry about this when doing a final link.  */
    371   if (link_info.relocatable || link_info.shared)
    372     return;
    373 
    374   /* Get the list of files which appear in ld_need entries in dynamic
    375      objects included in the link.  For each such file, we want to
    376      track down the corresponding library, and include the symbol
    377      table in the link.  This is what the runtime dynamic linker will
    378      do.  Tracking the files down here permits one dynamic object to
    379      include another without requiring special action by the person
    380      doing the link.  Note that the needed list can actually grow
    381      while we are stepping through this loop.  */
    382   needed = bfd_sunos_get_needed_list (link_info.output_bfd, &link_info);
    383   for (l = needed; l != NULL; l = l->next)
    384     {
    385       struct bfd_link_needed_list *ll;
    386       const char *lname;
    387       search_dirs_type *search;
    388 
    389       lname = l->name;
    390 
    391       /* If we've already seen this file, skip it.  */
    392       for (ll = needed; ll != l; ll = ll->next)
    393 	if (strcmp (ll->name, lname) == 0)
    394 	  break;
    395       if (ll != l)
    396 	continue;
    397 
    398       /* See if this file was included in the link explicitly.  */
    399       global_needed = l;
    400       global_found = FALSE;
    401       lang_for_each_input_file (gld${EMULATION_NAME}_check_needed);
    402       if (global_found)
    403 	continue;
    404 
    405       if (! CONST_STRNEQ (lname, "-l"))
    406 	{
    407 	  bfd *abfd;
    408 
    409 	  abfd = bfd_openr (lname, bfd_get_target (link_info.output_bfd));
    410 	  if (abfd != NULL)
    411 	    {
    412 	      if (! bfd_check_format (abfd, bfd_object))
    413 		{
    414 		  (void) bfd_close (abfd);
    415 		  abfd = NULL;
    416 		}
    417 	    }
    418 	  if (abfd != NULL)
    419 	    {
    420 	      if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0)
    421 		{
    422 		  (void) bfd_close (abfd);
    423 		  abfd = NULL;
    424 		}
    425 	    }
    426 	  if (abfd != NULL)
    427 	    {
    428 	      /* We've found the needed dynamic object.  */
    429 	      if (! bfd_link_add_symbols (abfd, &link_info))
    430 		einfo ("%F%B: error adding symbols: %E\n", abfd);
    431 	    }
    432 	  else
    433 	    {
    434 	      einfo ("%P: warning: %s, needed by %B, not found\n",
    435 		     lname, l->by);
    436 	    }
    437 
    438 	  continue;
    439 	}
    440 
    441       lname += 2;
    442 
    443       /* We want to search for the file in the same way that the
    444 	 dynamic linker will search.  That means that we want to use
    445 	 rpath_link, rpath or -L, then the environment variable
    446 	 LD_LIBRARY_PATH (native only), then (if rpath was used) the
    447 	 linker script LIB_SEARCH_DIRS.  */
    448       if (gld${EMULATION_NAME}_search_needed (command_line.rpath_link,
    449 					      lname))
    450 	continue;
    451       if (command_line.rpath != NULL)
    452 	{
    453 	  if (gld${EMULATION_NAME}_search_needed (command_line.rpath, lname))
    454 	    continue;
    455 	}
    456       else
    457 	{
    458 	  for (search = search_head; search != NULL; search = search->next)
    459 	    if (gld${EMULATION_NAME}_try_needed (search->name, lname))
    460 	      break;
    461 	  if (search != NULL)
    462 	    continue;
    463 	}
    464 EOF
    465 if [ "x${host}" = "x${target}" ] ; then
    466   case " ${EMULATION_LIBPATH} " in
    467   *" ${EMULATION_NAME} "*)
    468 fragment <<EOF
    469       {
    470 	const char *lib_path;
    471 
    472 	lib_path = (const char *) getenv ("LD_LIBRARY_PATH");
    473 	if (gld${EMULATION_NAME}_search_needed (lib_path, lname))
    474 	  continue;
    475       }
    476 EOF
    477   ;;
    478   esac
    479 fi
    480 fragment <<EOF
    481       if (command_line.rpath != NULL)
    482 	{
    483 	  for (search = search_head; search != NULL; search = search->next)
    484 	    {
    485 	      if (search->cmdline)
    486 		continue;
    487 	      if (gld${EMULATION_NAME}_try_needed (search->name, lname))
    488 		break;
    489 	    }
    490 	  if (search != NULL)
    491 	    continue;
    492 	}
    493 
    494       einfo ("%P: warning: %s, needed by %B, not found\n",
    495 	     l->name, l->by);
    496     }
    497 }
    498 
    499 /* Search for a needed file in a path.  */
    500 
    501 static bfd_boolean
    502 gld${EMULATION_NAME}_search_needed (const char *path, const char *name)
    503 {
    504   const char *s;
    505 
    506   if (path == NULL || *path == '\0')
    507     return FALSE;
    508   while (1)
    509     {
    510       const char *dir;
    511       char *dircopy;
    512 
    513       s = strchr (path, ':');
    514       if (s == NULL)
    515 	{
    516 	  dircopy = NULL;
    517 	  dir = path;
    518 	}
    519       else
    520 	{
    521 	  dircopy = (char *) xmalloc (s - path + 1);
    522 	  memcpy (dircopy, path, s - path);
    523 	  dircopy[s - path] = '\0';
    524 	  dir = dircopy;
    525 	}
    526 
    527       if (gld${EMULATION_NAME}_try_needed (dir, name))
    528 	return TRUE;
    529 
    530       if (dircopy != NULL)
    531 	free (dircopy);
    532 
    533       if (s == NULL)
    534 	break;
    535       path = s + 1;
    536     }
    537 
    538   return FALSE;
    539 }
    540 
    541 /* This function is called for each possible directory for a needed
    542    dynamic object.  */
    543 
    544 static bfd_boolean
    545 gld${EMULATION_NAME}_try_needed (const char *dir, const char *name)
    546 {
    547   char *file;
    548   char *alc;
    549   bfd_boolean ignore;
    550   bfd *abfd;
    551 
    552   file = gld${EMULATION_NAME}_search_dir (dir, name, &ignore);
    553   if (file == NULL)
    554     return FALSE;
    555 
    556   alc = (char *) xmalloc (strlen (dir) + strlen (file) + 2);
    557   sprintf (alc, "%s/%s", dir, file);
    558   free (file);
    559   abfd = bfd_openr (alc, bfd_get_target (link_info.output_bfd));
    560   if (abfd == NULL)
    561     return FALSE;
    562   if (! bfd_check_format (abfd, bfd_object))
    563     {
    564       (void) bfd_close (abfd);
    565       return FALSE;
    566     }
    567   if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0)
    568     {
    569       (void) bfd_close (abfd);
    570       return FALSE;
    571     }
    572 
    573   /* We've found the needed dynamic object.  */
    574 
    575   /* Add this file into the symbol table.  */
    576   if (! bfd_link_add_symbols (abfd, &link_info))
    577     einfo ("%F%B: error adding symbols: %E\n", abfd);
    578 
    579   return TRUE;
    580 }
    581 
    582 /* See if we have already included a needed object in the link.  This
    583    does not have to be precise, as it does no harm to include a
    584    dynamic object more than once.  */
    585 
    586 static void
    587 gld${EMULATION_NAME}_check_needed (lang_input_statement_type *s)
    588 {
    589   if (s->filename == NULL)
    590     return;
    591   if (! CONST_STRNEQ (global_needed->name, "-l"))
    592     {
    593       if (strcmp (s->filename, global_needed->name) == 0)
    594 	global_found = TRUE;
    595     }
    596   else
    597     {
    598       const char *sname, *lname;
    599       const char *sdot, *ldot;
    600       int lmaj, lmin, smaj, smin;
    601 
    602       lname = global_needed->name + 2;
    603 
    604       sname = strrchr (s->filename, '/');
    605       if (sname == NULL)
    606 	sname = s->filename;
    607       else
    608 	++sname;
    609 
    610       if (! CONST_STRNEQ (sname, "lib"))
    611 	return;
    612       sname += 3;
    613 
    614       ldot = strchr (lname, '.');
    615       if (ldot == NULL)
    616 	ldot = lname + strlen (lname);
    617 
    618       sdot = strstr (sname, ".so.");
    619       if (sdot == NULL)
    620 	return;
    621 
    622       if (sdot - sname != ldot - lname
    623 	  || strncmp (lname, sname, sdot - sname) != 0)
    624 	return;
    625 
    626       lmaj = lmin = -1;
    627       sscanf (ldot, ".%d.%d", &lmaj, &lmin);
    628       smaj = smin = -1;
    629       sscanf (sdot, ".so.%d.%d", &smaj, &smin);
    630       if ((smaj != lmaj && smaj != -1 && lmaj != -1)
    631 	  || (smin != lmin && smin != -1 && lmin != -1))
    632 	return;
    633 
    634       global_found = TRUE;
    635     }
    636 }
    637 
    638 /* We need to use static variables to pass information around the call
    639    to lang_for_each_statement.  Ick.  */
    640 
    641 static const char *find_assign;
    642 static bfd_boolean found_assign;
    643 
    644 /* We need to use static variables to pass information around the call
    645    to lang_for_each_input_file.  Ick.  */
    646 
    647 static bfd_size_type need_size;
    648 static bfd_size_type need_entries;
    649 static bfd_byte *need_contents;
    650 static bfd_byte *need_pinfo;
    651 static bfd_byte *need_pnames;
    652 
    653 /* The size of one entry in the .need section, not including the file
    654    name.  */
    655 
    656 #define NEED_ENTRY_SIZE (16)
    657 
    658 /* This is called after the sections have been attached to output
    659    sections, but before any sizes or addresses have been set.  */
    660 
    661 static void
    662 gld${EMULATION_NAME}_before_allocation (void)
    663 {
    664   struct bfd_link_hash_entry *hdyn = NULL;
    665   asection *sneed;
    666   asection *srules;
    667   asection *sdyn;
    668 
    669   /* The SunOS native linker creates a shared library whenever there
    670      are any undefined symbols in a link, unless -e is used.  This is
    671      pretty weird, but we are compatible.  */
    672   if (! link_info.shared && ! link_info.relocatable && ! entry_from_cmdline)
    673     {
    674       struct bfd_link_hash_entry *h;
    675 
    676       for (h = link_info.hash->undefs; h != NULL; h = h->u.undef.next)
    677 	{
    678 	  if (h->type == bfd_link_hash_undefined
    679 	      && h->u.undef.abfd != NULL
    680 	      && (h->u.undef.abfd->flags & DYNAMIC) == 0
    681 	      && strcmp (h->root.string, "__DYNAMIC") != 0
    682 	      && strcmp (h->root.string, "__GLOBAL_OFFSET_TABLE_") != 0)
    683 	    {
    684 	      find_assign = h->root.string;
    685 	      found_assign = FALSE;
    686 	      lang_for_each_statement (gld${EMULATION_NAME}_find_assignment);
    687 	      if (! found_assign)
    688 		{
    689 		  link_info.shared = TRUE;
    690 		  break;
    691 		}
    692 	    }
    693 	}
    694     }
    695 
    696   if (link_info.shared)
    697     {
    698       lang_output_section_statement_type *os;
    699 
    700       /* Set the .text section to start at 0x20, not 0x2020.  FIXME:
    701 	 This is too magical.  */
    702       os = lang_output_section_statement_lookup (".text", 0, TRUE);
    703       if (os->addr_tree == NULL)
    704 	os->addr_tree = exp_intop (0x20);
    705     }
    706 
    707   /* We need to create a __DYNAMIC symbol.  We don't do this in the
    708      linker script because we want to set the value to the start of
    709      the dynamic section if there is one, or to zero if there isn't
    710      one.  We need to create the symbol before calling
    711      size_dynamic_sections, although we can't set the value until
    712      afterward.  */
    713   if (! link_info.relocatable)
    714     {
    715       hdyn = bfd_link_hash_lookup (link_info.hash, "__DYNAMIC", TRUE, FALSE,
    716 				   FALSE);
    717       if (hdyn == NULL)
    718 	einfo ("%P%F: bfd_link_hash_lookup: %E\n");
    719       if (! bfd_sunos_record_link_assignment (link_info.output_bfd, &link_info,
    720 					      "__DYNAMIC"))
    721 	einfo ("%P%F: failed to record assignment to __DYNAMIC: %E\n");
    722     }
    723 
    724   /* If we are going to make any variable assignments, we need to let
    725      the backend linker know about them in case the variables are
    726      referred to by dynamic objects.  */
    727   lang_for_each_statement (gld${EMULATION_NAME}_find_assignment);
    728 
    729   /* Let the backend linker work out the sizes of any sections
    730      required by dynamic linking.  */
    731   if (! bfd_sunos_size_dynamic_sections (link_info.output_bfd, &link_info,
    732 					 &sdyn, &sneed, &srules))
    733     einfo ("%P%F: failed to set dynamic section sizes: %E\n");
    734 
    735   if (sneed != NULL)
    736     {
    737       /* Set up the .need section.  See the description of the ld_need
    738 	 field in include/aout/sun4.h.  */
    739 
    740       need_entries = 0;
    741       need_size = 0;
    742 
    743       lang_for_each_input_file (gld${EMULATION_NAME}_count_need);
    744 
    745       /* We should only have a .need section if we have at least one
    746 	 dynamic object.  */
    747       ASSERT (need_entries != 0);
    748 
    749       sneed->size = need_size;
    750       sneed->contents = (bfd_byte *) xmalloc (need_size);
    751 
    752       need_contents = sneed->contents;
    753       need_pinfo = sneed->contents;
    754       need_pnames = sneed->contents + need_entries * 16;
    755 
    756       lang_for_each_input_file (gld${EMULATION_NAME}_set_need);
    757 
    758       ASSERT ((bfd_size_type) (need_pnames - sneed->contents) == need_size);
    759     }
    760 
    761   if (srules != NULL)
    762     {
    763       /* Set up the .rules section.  This is just a PATH like string
    764 	 of the -L arguments given on the command line.  We permit the
    765 	 user to specify the directories using the -rpath command line
    766 	 option.  */
    767       if (command_line.rpath)
    768 	{
    769 	  srules->size = strlen (command_line.rpath);
    770 	  srules->contents = (bfd_byte *) command_line.rpath;
    771 	}
    772       else
    773 	{
    774 	  unsigned int size;
    775 	  search_dirs_type *search;
    776 
    777 	  size = 0;
    778 	  for (search = search_head; search != NULL; search = search->next)
    779 	    if (search->cmdline)
    780 	      size += strlen (search->name) + 1;
    781 	  srules->size = size;
    782 	  if (size > 0)
    783 	    {
    784 	      char *p;
    785 
    786 	      srules->contents = (bfd_byte *) xmalloc (size);
    787 	      p = (char *) srules->contents;
    788 	      *p = '\0';
    789 	      for (search = search_head; search != NULL; search = search->next)
    790 		{
    791 		  if (search->cmdline)
    792 		    {
    793 		      if (p != (char *) srules->contents)
    794 			*p++ = ':';
    795 		      strcpy (p, search->name);
    796 		      p += strlen (p);
    797 		    }
    798 		}
    799 	    }
    800 	}
    801     }
    802 
    803   /* We must assign a value to __DYNAMIC.  It should be zero if we are
    804      not doing a dynamic link, or the start of the .dynamic section if
    805      we are doing one.  */
    806   if (! link_info.relocatable)
    807     {
    808       hdyn->type = bfd_link_hash_defined;
    809       hdyn->u.def.value = 0;
    810       if (sdyn != NULL)
    811 	hdyn->u.def.section = sdyn;
    812       else
    813 	hdyn->u.def.section = bfd_abs_section_ptr;
    814     }
    815 
    816   before_allocation_default ();
    817 }
    818 
    819 /* This is called by the before_allocation routine via
    820    lang_for_each_statement.  It does one of two things: if the
    821    variable find_assign is set, it sets found_assign if it finds an
    822    assignment to that variable; otherwise it tells the backend linker
    823    about all assignment statements, in case they are assignments to
    824    symbols which are referred to by dynamic objects.  */
    825 
    826 static void
    827 gld${EMULATION_NAME}_find_assignment (lang_statement_union_type *s)
    828 {
    829   if (s->header.type == lang_assignment_statement_enum
    830       && (find_assign == NULL || ! found_assign))
    831     gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp);
    832 }
    833 
    834 /* Look through an expression for an assignment statement.  */
    835 
    836 static void
    837 gld${EMULATION_NAME}_find_exp_assignment (etree_type *exp)
    838 {
    839   switch (exp->type.node_class)
    840     {
    841     case etree_assign:
    842       if (find_assign != NULL)
    843 	{
    844 	  if (strcmp (find_assign, exp->assign.dst) == 0)
    845 	    found_assign = TRUE;
    846 	  return;
    847 	}
    848 
    849       if (strcmp (exp->assign.dst, ".") != 0)
    850 	{
    851 	  if (! bfd_sunos_record_link_assignment (link_info.output_bfd,
    852 						  &link_info,
    853 						  exp->assign.dst))
    854 	    einfo ("%P%F: failed to record assignment to %s: %E\n",
    855 		   exp->assign.dst);
    856 	}
    857       gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src);
    858       break;
    859 
    860     case etree_binary:
    861       gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs);
    862       gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs);
    863       break;
    864 
    865     case etree_trinary:
    866       gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.cond);
    867       gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs);
    868       gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs);
    869       break;
    870 
    871     case etree_unary:
    872       gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child);
    873       break;
    874 
    875     default:
    876       break;
    877     }
    878 }
    879 
    880 /* Work out the size of the .need section, and the number of entries.
    881    The backend will set the ld_need field of the dynamic linking
    882    information to point to the .need section.  See include/aout/sun4.h
    883    for more information.  */
    884 
    885 static void
    886 gld${EMULATION_NAME}_count_need (lang_input_statement_type *inp)
    887 {
    888   if (inp->the_bfd != NULL
    889       && (inp->the_bfd->flags & DYNAMIC) != 0)
    890     {
    891       ++need_entries;
    892       need_size += NEED_ENTRY_SIZE;
    893       if (! inp->flags.maybe_archive)
    894 	need_size += strlen (inp->filename) + 1;
    895       else
    896 	{
    897 	  ASSERT (inp->local_sym_name[0] == '-'
    898 		  && inp->local_sym_name[1] == 'l');
    899 	  need_size += strlen (inp->local_sym_name + 2) + 1;
    900 	}
    901     }
    902 }
    903 
    904 /* Fill in the contents of the .need section.  */
    905 
    906 static void
    907 gld${EMULATION_NAME}_set_need (lang_input_statement_type *inp)
    908 {
    909   if (inp->the_bfd != NULL
    910       && (inp->the_bfd->flags & DYNAMIC) != 0)
    911     {
    912       bfd_size_type c;
    913 
    914       /* To really fill in the .need section contents, we need to know
    915 	 the final file position of the section, but we don't.
    916 	 Instead, we use offsets, and rely on the BFD backend to
    917 	 finish the section up correctly.  FIXME: Talk about lack of
    918 	 referential locality.  */
    919       bfd_put_32 (link_info.output_bfd, need_pnames - need_contents,
    920 		  need_pinfo);
    921       if (! inp->flags.maybe_archive)
    922 	{
    923 	  bfd_put_32 (link_info.output_bfd, (bfd_vma) 0, need_pinfo + 4);
    924 	  bfd_put_16 (link_info.output_bfd, (bfd_vma) 0, need_pinfo + 8);
    925 	  bfd_put_16 (link_info.output_bfd, (bfd_vma) 0, need_pinfo + 10);
    926 	  strcpy ((char *) need_pnames, inp->filename);
    927 	}
    928       else
    929 	{
    930 	  char *verstr;
    931 	  int maj, min;
    932 
    933 	  bfd_put_32 (link_info.output_bfd, (bfd_vma) 0x80000000,
    934 		      need_pinfo + 4);
    935 	  maj = 0;
    936 	  min = 0;
    937 	  verstr = strstr (inp->filename, ".so.");
    938 	  if (verstr != NULL)
    939 	    sscanf (verstr, ".so.%d.%d", &maj, &min);
    940 	  bfd_put_16 (link_info.output_bfd, (bfd_vma) maj, need_pinfo + 8);
    941 	  bfd_put_16 (link_info.output_bfd, (bfd_vma) min, need_pinfo + 10);
    942 	  strcpy ((char *) need_pnames, inp->local_sym_name + 2);
    943 	}
    944 
    945       c = (need_pinfo - need_contents) / NEED_ENTRY_SIZE;
    946       if (c + 1 >= need_entries)
    947 	bfd_put_32 (link_info.output_bfd, (bfd_vma) 0, need_pinfo + 12);
    948       else
    949 	bfd_put_32 (link_info.output_bfd, (bfd_vma) (c + 1) * NEED_ENTRY_SIZE,
    950 		    need_pinfo + 12);
    951 
    952       need_pinfo += NEED_ENTRY_SIZE;
    953       need_pnames += strlen ((char *) need_pnames) + 1;
    954     }
    955 }
    956 
    957 static char *
    958 gld${EMULATION_NAME}_get_script (int *isfile)
    959 EOF
    960 
    961 if test x"$COMPILE_IN" = xyes
    962 then
    963 # Scripts compiled in.
    964 
    965 # sed commands to quote an ld script as a C string.
    966 sc="-f stringify.sed"
    967 
    968 fragment <<EOF
    969 {
    970   *isfile = 0;
    971 
    972   if (link_info.relocatable && config.build_constructors)
    973     return
    974 EOF
    975 sed $sc ldscripts/${EMULATION_NAME}.xu                     >> e${EMULATION_NAME}.c
    976 echo '  ; else if (link_info.relocatable) return'         >> e${EMULATION_NAME}.c
    977 sed $sc ldscripts/${EMULATION_NAME}.xr                     >> e${EMULATION_NAME}.c
    978 echo '  ; else if (!config.text_read_only) return'         >> e${EMULATION_NAME}.c
    979 sed $sc ldscripts/${EMULATION_NAME}.xbn                    >> e${EMULATION_NAME}.c
    980 echo '  ; else if (!config.magic_demand_paged) return'     >> e${EMULATION_NAME}.c
    981 sed $sc ldscripts/${EMULATION_NAME}.xn                     >> e${EMULATION_NAME}.c
    982 echo '  ; else return'                                     >> e${EMULATION_NAME}.c
    983 sed $sc ldscripts/${EMULATION_NAME}.x                      >> e${EMULATION_NAME}.c
    984 echo '; }'                                                 >> e${EMULATION_NAME}.c
    985 
    986 else
    987 # Scripts read from the filesystem.
    988 
    989 fragment <<EOF
    990 {
    991   *isfile = 1;
    992 
    993   if (link_info.relocatable && config.build_constructors)
    994     return "ldscripts/${EMULATION_NAME}.xu";
    995   else if (link_info.relocatable)
    996     return "ldscripts/${EMULATION_NAME}.xr";
    997   else if (!config.text_read_only)
    998     return "ldscripts/${EMULATION_NAME}.xbn";
    999   else if (!config.magic_demand_paged)
   1000     return "ldscripts/${EMULATION_NAME}.xn";
   1001   else
   1002     return "ldscripts/${EMULATION_NAME}.x";
   1003 }
   1004 EOF
   1005 
   1006 fi
   1007 
   1008 fragment <<EOF
   1009 
   1010 struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
   1011 {
   1012   gld${EMULATION_NAME}_before_parse,
   1013   syslib_default,
   1014   hll_default,
   1015   after_parse_default,
   1016   gld${EMULATION_NAME}_after_open,
   1017   after_allocation_default,
   1018   set_output_arch_default,
   1019   ldemul_default_target,
   1020   gld${EMULATION_NAME}_before_allocation,
   1021   gld${EMULATION_NAME}_get_script,
   1022   "${EMULATION_NAME}",
   1023   "${OUTPUT_FORMAT}",
   1024   finish_default,
   1025   gld${EMULATION_NAME}_create_output_section_statements,
   1026   NULL,	/* open dynamic archive */
   1027   NULL,	/* place orphan */
   1028   gld${EMULATION_NAME}_set_symbols,
   1029   NULL,	/* parse args */
   1030   NULL,	/* add_options */
   1031   NULL,	/* handle_option */
   1032   NULL,	/* unrecognized file */
   1033   NULL,	/* list options */
   1034   NULL,	/* recognized file */
   1035   NULL,	/* find_potential_libraries */
   1036   NULL,	/* new_vers_pattern */
   1037   NULL	/* extra_map_file_text */
   1038 };
   1039 EOF
   1040