fsf address update, but not in COPYING files
[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 /* FIXME: On some hosts we will need to include a different file.
33    This is correct for SunOS, which is the only place this file will
34    typically be compiled.  However, if somebody configures the linker
35    for all targets, they will run into trouble here.  */
36 #include <dirent.h>
37
38 #include "bfd.h"
39 #include "sysdep.h"
40 #include "bfdlink.h"
41
42 #include "ld.h"
43 #include "config.h"
44 #include "ldmain.h"
45 #include "ldemul.h"
46 #include "ldfile.h"
47 #include "ldmisc.h"
48 #include "ldexp.h"
49 #include "ldlang.h"
50
51 static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
52 static void gld${EMULATION_NAME}_create_output_section_statements
53   PARAMS ((void));
54 static void gld${EMULATION_NAME}_find_so
55   PARAMS ((lang_input_statement_type *));
56 static void gld${EMULATION_NAME}_before_allocation PARAMS ((void));
57 static void gld${EMULATION_NAME}_find_statement_assignment
58   PARAMS ((lang_statement_union_type *));
59 static void gld${EMULATION_NAME}_find_exp_assignment PARAMS ((etree_type *));
60 static void gld${EMULATION_NAME}_count_need
61   PARAMS ((lang_input_statement_type *));
62 static void gld${EMULATION_NAME}_set_need
63   PARAMS ((lang_input_statement_type *));
64 static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
65
66 static void
67 gld${EMULATION_NAME}_before_parse()
68 {
69   ldfile_output_architecture = bfd_arch_${ARCH};
70   config.dynamic_link = true;
71 }
72
73 /* Despite the name, we use this routine to search for dynamic
74    libraries.  On SunOS this requires a directory search.  We need to
75    find the .so file with the highest version number.  The user may
76    restrict the major version by saying, e.g., -lc.1.  Also, if we
77    find a .so file, we need to look for a the same file after
78    replacing .so with .sa; if it exists, it will be an archive which
79    provide some initializations for data symbols, and we need to
80    search it after including the .so file.  */
81
82 static void
83 gld${EMULATION_NAME}_create_output_section_statements ()
84 {
85   if (config.dynamic_link)
86     lang_for_each_input_file (gld${EMULATION_NAME}_find_so);
87 }
88
89 /* Search the directory for a .so file for each library search.  */
90
91 static void
92 gld${EMULATION_NAME}_find_so (inp)
93      lang_input_statement_type *inp;
94 {
95   search_dirs_type *search;
96   const char *filename;
97   const char *dot;
98   int force_maj;
99   unsigned int len;
100   char *alc;
101   int max_maj, max_min;
102   char *found;
103   boolean found_static;
104   struct stat st;
105
106   if (! inp->search_dirs_flag
107       || ! inp->is_archive)
108     return;
109
110   ASSERT (strncmp (inp->local_sym_name, "-l", 2) == 0);
111
112   filename = inp->filename;
113   force_maj = -1;
114   dot = strchr (filename, '.');
115   if (dot == NULL)
116     len = strlen (filename);
117   else
118     {
119       force_maj = atoi (dot + 1);
120       len = dot - filename;
121       alc = (char *) alloca (len + 1);
122       strncpy (alc, filename, len);
123       alc[len] = '\0';
124       filename = alc;
125     }
126
127   found = NULL;
128   found_static = false;
129   max_maj = max_min = 0;
130   for (search = search_head; search != NULL; search = search->next)
131     {
132       DIR *dir;
133       struct dirent *entry;
134
135       dir = opendir (search->name);
136       if (dir == NULL)
137         continue;
138   
139       while ((entry = readdir (dir)) != NULL)
140         {
141           int found_maj, found_min;
142
143           if (strncmp (entry->d_name, "lib", 3) != 0
144               || strncmp (entry->d_name + 3, inp->filename, len) != 0)
145             continue;
146
147           if (dot == NULL
148               && strncmp (entry->d_name + 3 + len, ".a", 2) == 0)
149             {
150               found_static = true;
151               continue;
152             }
153
154           if (strncmp (entry->d_name + 3 + len, ".so", 3) != 0)
155             continue;
156
157           /* We've found a .so file.  Work out the major and minor
158              version numbers.  */
159           found_maj = 0;
160           found_min = 0;
161           sscanf (entry->d_name + 3 + len, ".so.%d.%d",
162                   &found_maj, &found_min);
163
164           if (force_maj != -1 && force_maj != found_maj)
165             continue;
166
167           /* We've found a match for the name we are searching for.
168              See if this is the version we should use.  If the major
169              and minor versions match, we use the last entry in
170              alphabetical order; I don't know if this is how SunOS
171              distinguishes libc.so.1.8 from libc.so.1.8.1, but it
172              ought to suffice.  */
173           if (found == NULL
174               || (found_maj > max_maj)
175               || (found_maj == max_maj
176                   && (found_min > max_min
177                       || (found_min == max_min
178                           && strcmp (entry->d_name, found) > 0))))
179             {
180               if (found != NULL)
181                 free (found);
182               found = (char *) xmalloc (strlen (entry->d_name) + 1);
183               strcpy (found, entry->d_name);
184               max_maj = found_maj;
185               max_min = found_min;
186             }
187         }
188
189       closedir (dir);
190
191       if (found != NULL || found_static)
192         break;
193     }
194
195   if (found == NULL)
196     {
197       /* We did not find a matching .so file.  This isn't an error,
198          since there might still be a matching .a file, which will be
199          found by the usual search.  */
200       return;
201     }
202
203   /* Replace the filename with the one we have found.  */
204   alc = (char *) xmalloc (strlen (search->name) + strlen (found) + 2);
205   sprintf (alc, "%s/%s", search->name, found);
206   inp->filename = alc;
207
208   /* Turn off the search_dirs_flag to prevent ldfile_open_file from
209      searching for this file again.  */
210   inp->search_dirs_flag = false;
211
212   free (found);
213
214   /* Now look for the same file name, but with .sa instead of .so.  If
215      found, add it to the list of input files.  */
216   alc = (char *) alloca (strlen (inp->filename) + 1);
217   strcpy (alc, inp->filename);
218   strstr (alc, ".so.")[2] = 'a';
219   if (stat (alc, &st) == 0)
220     {
221       lang_input_statement_type *sa;
222       char *a;
223
224       /* Add the .sa file to the statement list just after the .so
225          file.  This is really a hack.  */
226       sa = ((lang_input_statement_type *)
227             xmalloc (sizeof (lang_input_statement_type)));
228       sa->header.next = inp->header.next;
229       sa->header.type = lang_input_statement_enum;
230       a = (char *) xmalloc (strlen (alc) + 1);
231       strcpy (a, alc);
232       sa->filename = a;
233       sa->local_sym_name = a;
234       sa->the_bfd = NULL;
235       sa->asymbols = NULL;
236       sa->symbol_count = 0;
237       sa->next = NULL;
238       sa->next_real_file = inp->next_real_file;
239       sa->is_archive = false;
240       sa->search_dirs_flag = false;
241       sa->just_syms_flag = false;
242       sa->loaded = false;
243       sa->real = true;
244       sa->complained = false;
245
246       /* Put the new statement next on the list of statements and next
247          on the list of input files.  */
248       inp->header.next = (lang_statement_union_type *) sa;
249       inp->next_real_file = (lang_statement_union_type *) sa;
250     }
251 }
252
253 /* We need to use static variables to pass information around the call
254    to lang_for_each_input_file.  Ick.  */
255
256 static bfd_size_type need_size;
257 static bfd_size_type need_entries;
258 static bfd_byte *need_contents;
259 static bfd_byte *need_pinfo;
260 static bfd_byte *need_pnames;
261
262 /* The size of one entry in the .need section, not including the file
263    name.  */
264
265 #define NEED_ENTRY_SIZE (16)
266
267 /* This is called after the sections have been attached to output
268    sections, but before any sizes or addresses have been set.  */
269
270 static void
271 gld${EMULATION_NAME}_before_allocation ()
272 {
273   struct bfd_link_hash_entry *h = NULL;
274   asection *sneed;
275   asection *srules;
276   asection *sdyn;
277
278   /* We need to create a __DYNAMIC symbol.  We don't do this in the
279      linker script because we want to set the value to the start of
280      the dynamic section if there is one, or to zero if there isn't
281      one.  We need to create the symbol before calling
282      size_dynamic_sections, although we can't set the value until
283      afterward.  */
284   if (! link_info.relocateable)
285     {
286       h = bfd_link_hash_lookup (link_info.hash, "__DYNAMIC", true, false,
287                                 false);
288       if (h == NULL)
289         einfo ("%P%F: bfd_link_hash_lookup: %E\n");
290       if (! bfd_sunos_record_link_assignment (output_bfd, &link_info,
291                                               "__DYNAMIC"))
292         einfo ("%P%F: failed to record assignment to __DYNAMIC: %E\n");
293     }
294
295   /* If we are going to make any variable assignments, we need to let
296      the backend linker know about them in case the variables are
297      referred to by dynamic objects.  */
298   lang_for_each_statement (gld${EMULATION_NAME}_find_statement_assignment);
299
300   /* Let the backend linker work out the sizes of any sections
301      required by dynamic linking.  */
302   if (! bfd_sunos_size_dynamic_sections (output_bfd, &link_info, &sdyn,
303                                          &sneed, &srules))
304     einfo ("%P%F: failed to set dynamic section sizes: %E\n");
305
306   if (sneed != NULL)
307     {
308       /* Set up the .need section.  See the description of the ld_need
309          field in include/aout/sun4.h.  */
310
311       need_entries = 0;
312       need_size = 0;
313
314       lang_for_each_input_file (gld${EMULATION_NAME}_count_need);
315
316       /* We should only have a .need section if we have at least one
317          dynamic object.  */
318       ASSERT (need_entries != 0);
319
320       sneed->_raw_size = need_size;
321       sneed->contents = (bfd_byte *) xmalloc (need_size);
322
323       need_contents = sneed->contents;
324       need_pinfo = sneed->contents;
325       need_pnames = sneed->contents + need_entries * 16;
326
327       lang_for_each_input_file (gld${EMULATION_NAME}_set_need);
328
329       ASSERT (need_pnames - sneed->contents == need_size);
330     }
331
332   if (srules != NULL)
333     {
334       unsigned int size;
335       search_dirs_type *search;
336
337       /* Set up the .rules section.  This is just a PATH like string
338          of the -L arguments given on the command line.  */
339       size = 0;
340       for (search = search_head; search != NULL; search = search->next)
341         if (search->cmdline)
342           size += strlen (search->name) + 1;
343       srules->_raw_size = size;
344       if (size > 0)
345         {
346           char *p;
347
348           srules->contents = (bfd_byte *) xmalloc (size);
349           p = (char *) srules->contents;
350           *p = '\0';
351           for (search = search_head; search != NULL; search = search->next)
352             {
353               if (search->cmdline)
354                 {
355                   if (p != (char *) srules->contents)
356                     *p++ = ':';
357                   strcpy (p, search->name);
358                   p += strlen (p);
359                 }
360             }
361         }
362     }
363
364   /* We must assign a value to __DYNAMIC.  It should be zero if we are
365      not doing a dynamic link, or the start of the .dynamic section if
366      we are doing one.  */
367   if (! link_info.relocateable)
368     {
369       h->type = bfd_link_hash_defined;
370       h->u.def.value = 0;
371       if (sdyn != NULL)
372         h->u.def.section = sdyn;
373       else
374         h->u.def.section = bfd_abs_section_ptr;
375     }
376 }
377
378 /* This is called by the before_allocation routine via
379    lang_for_each_statement.  It locates any assignment statements, and
380    tells the backend linker about them, in case they are assignments
381    to symbols which are referred to by dynamic objects.  */
382
383 static void
384 gld${EMULATION_NAME}_find_statement_assignment (s)
385      lang_statement_union_type *s;
386 {
387   if (s->header.type == lang_assignment_statement_enum)
388     gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp);
389 }
390
391 /* Look through an expression for an assignment statement.  */
392
393 static void
394 gld${EMULATION_NAME}_find_exp_assignment (exp)
395      etree_type *exp;
396 {
397   switch (exp->type.node_class)
398     {
399     case etree_assign:
400       if (strcmp (exp->assign.dst, ".") != 0)
401         {
402           if (! bfd_sunos_record_link_assignment (output_bfd, &link_info,
403                                                   exp->assign.dst))
404             einfo ("%P%F: failed to record assignment to %s: %E\n",
405                    exp->assign.dst);
406         }
407       gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src);
408       break;
409
410     case etree_binary:
411       gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs);
412       gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs);
413       break;
414
415     case etree_trinary:
416       gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs);
417       gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs);
418       gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs);
419       break;
420
421     case etree_unary:
422       gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child);
423       break;
424
425     default:
426       break;
427     }
428 }
429
430 /* Work out the size of the .need section, and the number of entries.
431    The backend will set the ld_need field of the dynamic linking
432    information to point to the .need section.  See include/aout/sun4.h
433    for more information.  */
434
435 static void
436 gld${EMULATION_NAME}_count_need (inp)
437      lang_input_statement_type *inp;
438 {
439   if (inp->the_bfd != NULL
440       && (inp->the_bfd->flags & DYNAMIC) != 0)
441     {
442       ++need_entries;
443       need_size += NEED_ENTRY_SIZE;
444       if (! inp->is_archive)
445         need_size += strlen (inp->filename) + 1;
446       else
447         {
448           ASSERT (inp->local_sym_name[0] == '-'
449                   && inp->local_sym_name[1] == 'l');
450           need_size += strlen (inp->local_sym_name + 2) + 1;
451         }
452     }
453 }
454
455 /* Fill in the contents of the .need section.  */
456
457 static void
458 gld${EMULATION_NAME}_set_need (inp)
459      lang_input_statement_type *inp;
460 {
461   if (inp->the_bfd != NULL
462       && (inp->the_bfd->flags & DYNAMIC) != 0)
463     {
464       bfd_size_type c;
465
466       /* To really fill in the .need section contents, we need to know
467          the final file position of the section, but we don't.
468          Instead, we use offsets, and rely on the BFD backend to
469          finish the section up correctly.  FIXME: Talk about lack of
470          referential locality.  */
471       bfd_put_32 (output_bfd, need_pnames - need_contents, need_pinfo);
472       if (! inp->is_archive)
473         {
474           bfd_put_32 (output_bfd, (bfd_vma) 0, need_pinfo + 4);
475           bfd_put_16 (output_bfd, (bfd_vma) 0, need_pinfo + 8);
476           bfd_put_16 (output_bfd, (bfd_vma) 0, need_pinfo + 10);
477           strcpy (need_pnames, inp->filename);
478         }
479       else
480         {
481           char *verstr;
482           int maj, min;
483
484           bfd_put_32 (output_bfd, (bfd_vma) 0x80000000, need_pinfo + 4);
485           maj = 0;
486           min = 0;
487           verstr = strstr (inp->filename, ".so.");
488           if (verstr != NULL)
489             sscanf (verstr, ".so.%d.%d", &maj, &min);
490           bfd_put_16 (output_bfd, (bfd_vma) maj, need_pinfo + 8);
491           bfd_put_16 (output_bfd, (bfd_vma) min, need_pinfo + 10);
492           strcpy (need_pnames, inp->local_sym_name + 2);
493         }
494
495       c = (need_pinfo - need_contents) / NEED_ENTRY_SIZE;
496       if (c + 1 >= need_entries)
497         bfd_put_32 (output_bfd, (bfd_vma) 0, need_pinfo + 12);
498       else
499         bfd_put_32 (output_bfd, (bfd_vma) (c + 1) * NEED_ENTRY_SIZE,
500                     need_pinfo + 12);
501
502       need_pinfo += NEED_ENTRY_SIZE;
503       need_pnames += strlen (need_pnames) + 1;
504     }
505 }
506
507 static char *
508 gld${EMULATION_NAME}_get_script(isfile)
509      int *isfile;
510 EOF
511
512 if test -n "$COMPILE_IN"
513 then
514 # Scripts compiled in.
515
516 # sed commands to quote an ld script as a C string.
517 sc='s/["\\]/\\&/g
518 s/$/\\n\\/
519 1s/^/"/
520 $s/$/n"/
521 '
522
523 cat >>e${EMULATION_NAME}.c <<EOF
524 {                            
525   *isfile = 0;
526
527   if (link_info.relocateable == true && config.build_constructors == true)
528     return `sed "$sc" ldscripts/${EMULATION_NAME}.xu`;
529   else if (link_info.relocateable == true)
530     return `sed "$sc" ldscripts/${EMULATION_NAME}.xr`;
531   else if (!config.text_read_only)
532     return `sed "$sc" ldscripts/${EMULATION_NAME}.xbn`;
533   else if (!config.magic_demand_paged)
534     return `sed "$sc" ldscripts/${EMULATION_NAME}.xn`;
535   else
536     return `sed "$sc" ldscripts/${EMULATION_NAME}.x`;
537 }
538 EOF
539
540 else
541 # Scripts read from the filesystem.
542
543 cat >>e${EMULATION_NAME}.c <<EOF
544 {                            
545   *isfile = 1;
546
547   if (link_info.relocateable == true && config.build_constructors == true)
548     return "ldscripts/${EMULATION_NAME}.xu";
549   else if (link_info.relocateable == true)
550     return "ldscripts/${EMULATION_NAME}.xr";
551   else if (!config.text_read_only)
552     return "ldscripts/${EMULATION_NAME}.xbn";
553   else if (!config.magic_demand_paged)
554     return "ldscripts/${EMULATION_NAME}.xn";
555   else
556     return "ldscripts/${EMULATION_NAME}.x";
557 }
558 EOF
559
560 fi
561
562 cat >>e${EMULATION_NAME}.c <<EOF
563
564 struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = 
565 {
566   gld${EMULATION_NAME}_before_parse,
567   syslib_default,
568   hll_default,
569   after_parse_default,
570   after_open_default,
571   after_allocation_default,
572   set_output_arch_default,
573   ldemul_default_target,
574   gld${EMULATION_NAME}_before_allocation,
575   gld${EMULATION_NAME}_get_script,
576   "${EMULATION_NAME}",
577   "${OUTPUT_FORMAT}",
578   NULL, /* finish */
579   gld${EMULATION_NAME}_create_output_section_statements,
580   NULL /* open_dynamic_library */
581 };
582 EOF