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