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