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