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