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