* emultempl/sunos.em (gld${EMULATION_NAME}_find_so): Move
[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             {
622               find_assign = h->root.string;
623               found_assign = false;
624               lang_for_each_statement (gld${EMULATION_NAME}_find_assignment);
625               if (! found_assign)
626                 {
627                   link_info.shared = true;
628                   break;
629                 }
630             }
631         }
632     }
633
634   if (link_info.shared)
635     {
636       lang_output_section_statement_type *os;
637
638       /* Set the .text section to start at 0x20, not 0x2020.  FIXME:
639          This is too magical.  */
640       os = lang_output_section_statement_lookup (".text");
641       if (os->addr_tree == NULL)
642         os->addr_tree = exp_intop (0x20);
643     }
644
645   /* We need to create a __DYNAMIC symbol.  We don't do this in the
646      linker script because we want to set the value to the start of
647      the dynamic section if there is one, or to zero if there isn't
648      one.  We need to create the symbol before calling
649      size_dynamic_sections, although we can't set the value until
650      afterward.  */
651   if (! link_info.relocateable)
652     {
653       hdyn = bfd_link_hash_lookup (link_info.hash, "__DYNAMIC", true, false,
654                                    false);
655       if (hdyn == NULL)
656         einfo ("%P%F: bfd_link_hash_lookup: %E\n");
657       if (! bfd_sunos_record_link_assignment (output_bfd, &link_info,
658                                               "__DYNAMIC"))
659         einfo ("%P%F: failed to record assignment to __DYNAMIC: %E\n");
660     }
661
662   /* If we are going to make any variable assignments, we need to let
663      the backend linker know about them in case the variables are
664      referred to by dynamic objects.  */
665   lang_for_each_statement (gld${EMULATION_NAME}_find_assignment);
666
667   /* Let the backend linker work out the sizes of any sections
668      required by dynamic linking.  */
669   if (! bfd_sunos_size_dynamic_sections (output_bfd, &link_info, &sdyn,
670                                          &sneed, &srules))
671     einfo ("%P%F: failed to set dynamic section sizes: %E\n");
672
673   if (sneed != NULL)
674     {
675       /* Set up the .need section.  See the description of the ld_need
676          field in include/aout/sun4.h.  */
677
678       need_entries = 0;
679       need_size = 0;
680
681       lang_for_each_input_file (gld${EMULATION_NAME}_count_need);
682
683       /* We should only have a .need section if we have at least one
684          dynamic object.  */
685       ASSERT (need_entries != 0);
686
687       sneed->_raw_size = need_size;
688       sneed->contents = (bfd_byte *) xmalloc (need_size);
689
690       need_contents = sneed->contents;
691       need_pinfo = sneed->contents;
692       need_pnames = sneed->contents + need_entries * 16;
693
694       lang_for_each_input_file (gld${EMULATION_NAME}_set_need);
695
696       ASSERT ((bfd_size_type) (need_pnames - sneed->contents) == need_size);
697     }
698
699   if (srules != NULL)
700     {
701       /* Set up the .rules section.  This is just a PATH like string
702          of the -L arguments given on the command line.  We permit the
703          user to specify the directories using the -rpath command line
704          option.  */
705       if (command_line.rpath)
706         {
707           srules->_raw_size = strlen (command_line.rpath);
708           srules->contents = (bfd_byte *) command_line.rpath;
709         }
710       else
711         {
712           unsigned int size;
713           search_dirs_type *search;
714
715           size = 0;
716           for (search = search_head; search != NULL; search = search->next)
717             if (search->cmdline)
718               size += strlen (search->name) + 1;
719           srules->_raw_size = size;
720           if (size > 0)
721             {
722               char *p;
723
724               srules->contents = (bfd_byte *) xmalloc (size);
725               p = (char *) srules->contents;
726               *p = '\0';
727               for (search = search_head; search != NULL; search = search->next)
728                 {
729                   if (search->cmdline)
730                     {
731                       if (p != (char *) srules->contents)
732                         *p++ = ':';
733                       strcpy (p, search->name);
734                       p += strlen (p);
735                     }
736                 }
737             }
738         }
739     }
740
741   /* We must assign a value to __DYNAMIC.  It should be zero if we are
742      not doing a dynamic link, or the start of the .dynamic section if
743      we are doing one.  */
744   if (! link_info.relocateable)
745     {
746       hdyn->type = bfd_link_hash_defined;
747       hdyn->u.def.value = 0;
748       if (sdyn != NULL)
749         hdyn->u.def.section = sdyn;
750       else
751         hdyn->u.def.section = bfd_abs_section_ptr;
752     }
753 }
754
755 /* This is called by the before_allocation routine via
756    lang_for_each_statement.  It does one of two things: if the
757    variable find_assign is set, it sets found_assign if it finds an
758    assignment to that variable; otherwise it tells the backend linker
759    about all assignment statements, in case they are assignments to
760    symbols which are referred to by dynamic objects.  */
761
762 static void
763 gld${EMULATION_NAME}_find_assignment (s)
764      lang_statement_union_type *s;
765 {
766   if (s->header.type == lang_assignment_statement_enum
767       && (find_assign == NULL || ! found_assign))
768     gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp);
769 }
770
771 /* Look through an expression for an assignment statement.  */
772
773 static void
774 gld${EMULATION_NAME}_find_exp_assignment (exp)
775      etree_type *exp;
776 {
777   switch (exp->type.node_class)
778     {
779     case etree_assign:
780       if (find_assign != NULL)
781         {
782           if (strcmp (find_assign, exp->assign.dst) == 0)
783             found_assign = true;
784           return;
785         }
786
787       if (strcmp (exp->assign.dst, ".") != 0)
788         {
789           if (! bfd_sunos_record_link_assignment (output_bfd, &link_info,
790                                                   exp->assign.dst))
791             einfo ("%P%F: failed to record assignment to %s: %E\n",
792                    exp->assign.dst);
793         }
794       gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src);
795       break;
796
797     case etree_binary:
798       gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs);
799       gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs);
800       break;
801
802     case etree_trinary:
803       gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs);
804       gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs);
805       gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs);
806       break;
807
808     case etree_unary:
809       gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child);
810       break;
811
812     default:
813       break;
814     }
815 }
816
817 /* Work out the size of the .need section, and the number of entries.
818    The backend will set the ld_need field of the dynamic linking
819    information to point to the .need section.  See include/aout/sun4.h
820    for more information.  */
821
822 static void
823 gld${EMULATION_NAME}_count_need (inp)
824      lang_input_statement_type *inp;
825 {
826   if (inp->the_bfd != NULL
827       && (inp->the_bfd->flags & DYNAMIC) != 0)
828     {
829       ++need_entries;
830       need_size += NEED_ENTRY_SIZE;
831       if (! inp->is_archive)
832         need_size += strlen (inp->filename) + 1;
833       else
834         {
835           ASSERT (inp->local_sym_name[0] == '-'
836                   && inp->local_sym_name[1] == 'l');
837           need_size += strlen (inp->local_sym_name + 2) + 1;
838         }
839     }
840 }
841
842 /* Fill in the contents of the .need section.  */
843
844 static void
845 gld${EMULATION_NAME}_set_need (inp)
846      lang_input_statement_type *inp;
847 {
848   if (inp->the_bfd != NULL
849       && (inp->the_bfd->flags & DYNAMIC) != 0)
850     {
851       bfd_size_type c;
852
853       /* To really fill in the .need section contents, we need to know
854          the final file position of the section, but we don't.
855          Instead, we use offsets, and rely on the BFD backend to
856          finish the section up correctly.  FIXME: Talk about lack of
857          referential locality.  */
858       bfd_put_32 (output_bfd, need_pnames - need_contents, need_pinfo);
859       if (! inp->is_archive)
860         {
861           bfd_put_32 (output_bfd, (bfd_vma) 0, need_pinfo + 4);
862           bfd_put_16 (output_bfd, (bfd_vma) 0, need_pinfo + 8);
863           bfd_put_16 (output_bfd, (bfd_vma) 0, need_pinfo + 10);
864           strcpy (need_pnames, inp->filename);
865         }
866       else
867         {
868           char *verstr;
869           int maj, min;
870
871           bfd_put_32 (output_bfd, (bfd_vma) 0x80000000, need_pinfo + 4);
872           maj = 0;
873           min = 0;
874           verstr = strstr (inp->filename, ".so.");
875           if (verstr != NULL)
876             sscanf (verstr, ".so.%d.%d", &maj, &min);
877           bfd_put_16 (output_bfd, (bfd_vma) maj, need_pinfo + 8);
878           bfd_put_16 (output_bfd, (bfd_vma) min, need_pinfo + 10);
879           strcpy (need_pnames, inp->local_sym_name + 2);
880         }
881
882       c = (need_pinfo - need_contents) / NEED_ENTRY_SIZE;
883       if (c + 1 >= need_entries)
884         bfd_put_32 (output_bfd, (bfd_vma) 0, need_pinfo + 12);
885       else
886         bfd_put_32 (output_bfd, (bfd_vma) (c + 1) * NEED_ENTRY_SIZE,
887                     need_pinfo + 12);
888
889       need_pinfo += NEED_ENTRY_SIZE;
890       need_pnames += strlen (need_pnames) + 1;
891     }
892 }
893
894 static char *
895 gld${EMULATION_NAME}_get_script(isfile)
896      int *isfile;
897 EOF
898
899 if test -n "$COMPILE_IN"
900 then
901 # Scripts compiled in.
902
903 # sed commands to quote an ld script as a C string.
904 sc='s/["\\]/\\&/g
905 s/$/\\n\\/
906 1s/^/"/
907 $s/$/n"/
908 '
909
910 cat >>e${EMULATION_NAME}.c <<EOF
911 {                            
912   *isfile = 0;
913
914   if (link_info.relocateable == true && config.build_constructors == true)
915     return `sed "$sc" ldscripts/${EMULATION_NAME}.xu`;
916   else if (link_info.relocateable == true)
917     return `sed "$sc" ldscripts/${EMULATION_NAME}.xr`;
918   else if (!config.text_read_only)
919     return `sed "$sc" ldscripts/${EMULATION_NAME}.xbn`;
920   else if (!config.magic_demand_paged)
921     return `sed "$sc" ldscripts/${EMULATION_NAME}.xn`;
922   else
923     return `sed "$sc" ldscripts/${EMULATION_NAME}.x`;
924 }
925 EOF
926
927 else
928 # Scripts read from the filesystem.
929
930 cat >>e${EMULATION_NAME}.c <<EOF
931 {                            
932   *isfile = 1;
933
934   if (link_info.relocateable == true && config.build_constructors == true)
935     return "ldscripts/${EMULATION_NAME}.xu";
936   else if (link_info.relocateable == true)
937     return "ldscripts/${EMULATION_NAME}.xr";
938   else if (!config.text_read_only)
939     return "ldscripts/${EMULATION_NAME}.xbn";
940   else if (!config.magic_demand_paged)
941     return "ldscripts/${EMULATION_NAME}.xn";
942   else
943     return "ldscripts/${EMULATION_NAME}.x";
944 }
945 EOF
946
947 fi
948
949 cat >>e${EMULATION_NAME}.c <<EOF
950
951 struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = 
952 {
953   gld${EMULATION_NAME}_before_parse,
954   syslib_default,
955   hll_default,
956   after_parse_default,
957   gld${EMULATION_NAME}_after_open,
958   after_allocation_default,
959   set_output_arch_default,
960   ldemul_default_target,
961   gld${EMULATION_NAME}_before_allocation,
962   gld${EMULATION_NAME}_get_script,
963   "${EMULATION_NAME}",
964   "${OUTPUT_FORMAT}",
965   NULL, /* finish */
966   gld${EMULATION_NAME}_create_output_section_statements,
967   NULL /* open_dynamic_library */
968 };
969 EOF