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