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