This commit was generated by cvs2svn to track changes on a CVS vendor
[unix-history] / gnu / usr.bin / ld / ld.c
CommitLineData
fb459a62
NW
1/*-
2 * This code is derived from software copyrighted by the Free Software
3 * Foundation.
4 *
5 * Modified 1991 by Donn Seeley at UUNET Technologies, Inc.
1136f72d
PR
6 *
7 * Modified 1993 by Paul Kranenburg, Erasmus University
fb459a62
NW
8 */
9
10#ifndef lint
11static char sccsid[] = "@(#)ld.c 6.10 (Berkeley) 5/22/91";
12#endif /* not lint */
13
14/* Linker `ld' for GNU
15 Copyright (C) 1988 Free Software Foundation, Inc.
16
17 This program is free software; you can redistribute it and/or modify
18 it under the terms of the GNU General Public License as published by
19 the Free Software Foundation; either version 1, or (at your option)
20 any later version.
21
22 This program is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 GNU General Public License for more details.
26
27 You should have received a copy of the GNU General Public License
28 along with this program; if not, write to the Free Software
29 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
30
31/* Written by Richard Stallman with some help from Eric Albert.
7fc7155d 32 Set, indirect, and warning symbol features added by Randy Smith. */
1136f72d
PR
33
34/*
5e358090 35 * $Id: ld.c,v 1.17 1993/12/22 23:28:08 jkh Exp $
1136f72d 36 */
fb459a62
NW
37
38/* Define how to initialize system-dependent header fields. */
39
1136f72d 40#include <sys/param.h>
fb459a62 41#include <stdio.h>
1136f72d 42#include <stdlib.h>
fb459a62
NW
43#include <sys/types.h>
44#include <sys/stat.h>
45#include <sys/file.h>
46#include <sys/time.h>
47#include <sys/resource.h>
48#include <fcntl.h>
1136f72d
PR
49#include <ar.h>
50#include <ranlib.h>
fb459a62
NW
51#include <a.out.h>
52#include <stab.h>
53#include <string.h>
1136f72d 54#include <strings.h>
fb459a62 55
1136f72d 56#include "ld.h"
fb459a62 57
0f052032
JH
58#ifndef DEFAULT_SOVERSION
59#define DEFAULT_SOVERSION LD_VERSION_BSD
60#endif
61
1136f72d 62int building_shared_object;
fb459a62 63
1136f72d
PR
64/* 1 => write relocation into output file so can re-input it later. */
65int relocatable_output;
fb459a62 66
1136f72d
PR
67/* Non zero means to create the output executable. */
68/* Cleared by nonfatal errors. */
69int make_executable;
fb459a62 70
1136f72d
PR
71/* Force the executable to be output, even if there are non-fatal errors */
72int force_executable;
fb459a62 73
1136f72d
PR
74/* 1 => assign space to common symbols even if `relocatable_output'. */
75int force_common_definition;
76
77/* 1 => assign jmp slots to text symbols in shared objects even if non-PIC */
78int force_alias_definition;
fb459a62 79
27b6ced7
JH
80/* 1 => some files contain PIC code, affects relocation bits
81 if `relocatable_output'. */
82int pic_code_seen;
83
0f052032
JH
84/* 1 => data segment must be page aligned, even if `-n' or `-N' */
85int page_align_data;
86
1136f72d
PR
87/*
88 * Which symbols should be stripped (omitted from the output): none, all, or
89 * debugger symbols.
90 */
91enum {
92 STRIP_NONE, STRIP_ALL, STRIP_DEBUGGER
93} strip_symbols;
fb459a62 94
1136f72d
PR
95/*
96 * Which local symbols should be omitted: none, all, or those starting with L.
97 * This is irrelevant if STRIP_NONE.
98 */
99enum {
100 DISCARD_NONE, DISCARD_ALL, DISCARD_L
101} discard_locals;
fb459a62 102
1136f72d
PR
103/* Nonzero means print names of input files as processed. */
104int trace_files;
fb459a62 105
1136f72d
PR
106/* Magic number to use for the output file, set by switch. */
107int magic;
fb459a62 108
fb459a62 109/*
1136f72d
PR
110 * `text-start' address is normally this much plus a page boundary.
111 * This is not a user option; it is fixed for each system.
fb459a62 112 */
1136f72d 113int text_start_alignment;
fb459a62 114
1136f72d
PR
115/*
116 * Nonzero if -T was specified in the command line.
117 * This prevents text_start from being set later to default values.
118 */
119int T_flag_specified;
120
121/*
122 * Nonzero if -Tdata was specified in the command line.
123 * This prevents data_start from being set later to default values.
124 */
125int Tdata_flag_specified;
fb459a62 126
1136f72d
PR
127/*
128 * Size to pad data section up to.
129 * We simply increase the size of the data section, padding with zeros,
130 * and reduce the size of the bss section to match.
131 */
132int specified_data_size;
fb459a62 133
1136f72d
PR
134long *set_vectors;
135int setv_fill_count;
fb459a62 136
0f052032
JH
137static void decode_option __P((char *, char *));
138static void decode_command __P((int, char **));
139static int classify_arg __P((char *));
140static void enter_global_ref __P((struct localsymbol *,
141 char *, struct file_entry *));
142static void digest_symbols __P((void));
143static void digest_pass1 __P((void)), digest_pass2 __P((void));
144static void consider_file_section_lengths __P((struct file_entry *));
145static void relocate_file_addresses __P((struct file_entry *));
146static void consider_relocation __P((struct file_entry *, int));
147static void perform_relocation __P((char *, int,
148 struct relocation_info *, int,
149 struct file_entry *, int));
150static void copy_text __P((struct file_entry *));
151static void copy_data __P((struct file_entry *));
152static void coptxtrel __P((struct file_entry *));
153static void copdatrel __P((struct file_entry *));
154static void assign_symbolnums __P((struct file_entry *, int *));
155
1136f72d
PR
156int
157main(argc, argv)
158 char **argv;
159 int argc;
160{
fb459a62 161
1136f72d
PR
162 if ((progname = strrchr(argv[0], '/')) == NULL)
163 progname = argv[0];
164 else
165 progname++;
fb459a62 166
1136f72d
PR
167 /* Added this to stop ld core-dumping on very large .o files. */
168#ifdef RLIMIT_STACK
169 /* Get rid of any avoidable limit on stack size. */
170 {
171 struct rlimit rlim;
fb459a62 172
1136f72d
PR
173 /* Set the stack limit huge so that alloca does not fail. */
174 getrlimit(RLIMIT_STACK, &rlim);
175 rlim.rlim_cur = rlim.rlim_max;
176 setrlimit(RLIMIT_STACK, &rlim);
177 }
178#endif /* RLIMIT_STACK */
179
180 page_size = PAGSIZ;
181
182 /* Clear the cumulative info on the output file. */
183
184 text_size = 0;
185 data_size = 0;
186 bss_size = 0;
187 text_reloc_size = 0;
188 data_reloc_size = 0;
fb459a62 189
1136f72d
PR
190 data_pad = 0;
191 text_pad = 0;
0f052032 192 page_align_data = 0;
fb459a62 193
1136f72d 194 /* Initialize the data about options. */
fb459a62 195
1136f72d
PR
196 specified_data_size = 0;
197 strip_symbols = STRIP_NONE;
198 trace_files = 0;
199 discard_locals = DISCARD_NONE;
200 entry_symbol = 0;
201 write_map = 0;
202 relocatable_output = 0;
203 force_common_definition = 0;
204 T_flag_specified = 0;
205 Tdata_flag_specified = 0;
206 magic = DEFAULT_MAGIC;
207 make_executable = 1;
208 force_executable = 0;
209 link_mode = DYNAMIC;
0f052032
JH
210#ifdef SUNOS4
211 link_mode |= SILLYARCHIVE;
212#endif
213 soversion = DEFAULT_SOVERSION;
fb459a62 214
1136f72d 215 /* Initialize the cumulative counts of symbols. */
fb459a62 216
1136f72d
PR
217 local_sym_count = 0;
218 non_L_local_sym_count = 0;
219 debugger_sym_count = 0;
220 undefined_global_sym_count = 0;
221 warning_count = 0;
222 multiple_def_count = 0;
223 common_defined_global_count = 0;
fb459a62 224
1136f72d
PR
225 /* Keep a list of symbols referenced from the command line */
226 cl_refs_allocated = 10;
227 cmdline_references
228 = (struct glosym **) xmalloc(cl_refs_allocated
229 * sizeof(struct glosym *));
230 *cmdline_references = 0;
fb459a62 231
1136f72d
PR
232 /* Completely decode ARGV. */
233 decode_command(argc, argv);
fb459a62 234
1136f72d
PR
235 building_shared_object =
236 (!relocatable_output && (link_mode & SHAREABLE));
fb459a62 237
27b6ced7
JH
238 if (building_shared_object && entry_symbol) {
239 fatal("`-Bshareable' and `-e' options are mutually exclusive");
240 }
241
1136f72d
PR
242 /* Create the symbols `etext', `edata' and `end'. */
243 symtab_init(relocatable_output);
fb459a62 244
1136f72d
PR
245 /* Prepare for the run-time linking support. */
246 init_rrs();
fb459a62 247
1136f72d
PR
248 /*
249 * Determine whether to count the header as part of the text size,
250 * and initialize the text size accordingly. This depends on the kind
251 * of system and on the output format selected.
252 */
fb459a62 253
1136f72d 254 md_init_header(&outheader, magic, 0);
fb459a62 255
1136f72d
PR
256 text_size = sizeof(struct exec);
257 text_size -= N_TXTOFF(outheader);
fb459a62 258
1136f72d
PR
259 if (text_size < 0)
260 text_size = 0;
261 entry_offset = text_size;
fb459a62 262
1136f72d
PR
263 if (!T_flag_specified && !relocatable_output)
264 text_start = TEXT_START(outheader);
fb459a62 265
1136f72d
PR
266 /* The text-start address is normally this far past a page boundary. */
267 text_start_alignment = text_start % page_size;
fb459a62 268
1136f72d
PR
269 /*
270 * Load symbols of all input files. Also search all libraries and
271 * decide which library members to load.
272 */
273 load_symbols();
fb459a62 274
1136f72d
PR
275 /* Compute where each file's sections go, and relocate symbols. */
276 digest_symbols();
fb459a62 277
1136f72d
PR
278 /*
279 * Print error messages for any missing symbols, for any warning
280 * symbols, and possibly multiple definitions
281 */
282 make_executable = do_warnings(stderr);
fb459a62 283
1136f72d
PR
284 /* Print a map, if requested. */
285 if (write_map)
286 print_symbols(stdout);
fb459a62 287
1136f72d
PR
288 /* Write the output file. */
289 if (make_executable || force_executable)
290 write_output();
fb459a62 291
1136f72d
PR
292 exit(!make_executable);
293}
fb459a62 294
1136f72d
PR
295/*
296 * Analyze a command line argument. Return 0 if the argument is a filename.
297 * Return 1 if the argument is a option complete in itself. Return 2 if the
298 * argument is a option which uses an argument.
299 *
300 * Thus, the value is the number of consecutive arguments that are part of
301 * options.
302 */
fb459a62 303
0f052032 304static int
1136f72d
PR
305classify_arg(arg)
306 register char *arg;
307{
308 if (*arg != '-')
309 return 0;
310 switch (arg[1]) {
311 case 'a':
312 if (!strcmp(&arg[2], "ssert"))
313 return 2;
314 case 'A':
315 case 'D':
316 case 'e':
317 case 'L':
318 case 'l':
319 case 'o':
320 case 'u':
321 case 'V':
322 case 'y':
323 if (arg[2])
324 return 1;
325 return 2;
326
327 case 'B':
328 if (!strcmp(&arg[2], "static"))
329 return 1;
330 if (!strcmp(&arg[2], "dynamic"))
331 return 1;
332
333 case 'T':
334 if (arg[2] == 0)
335 return 2;
336 if (!strcmp(&arg[2], "text"))
337 return 2;
338 if (!strcmp(&arg[2], "data"))
339 return 2;
340 return 1;
341 }
fb459a62 342
1136f72d
PR
343 return 1;
344}
fb459a62 345
1136f72d
PR
346/*
347 * Process the command arguments, setting up file_table with an entry for
348 * each input file, and setting variables according to the options.
349 */
fb459a62 350
0f052032 351static void
1136f72d 352decode_command(argc, argv)
1136f72d 353 int argc;
0f052032 354 char **argv;
1136f72d
PR
355{
356 register int i;
357 register struct file_entry *p;
358 char *cp;
fb459a62 359
1136f72d
PR
360 number_of_files = 0;
361 output_filename = "a.out";
fb459a62 362
1136f72d
PR
363 /*
364 * First compute number_of_files so we know how long to make
365 * file_table.
366 * Also process most options completely.
367 */
fb459a62 368
1136f72d
PR
369 for (i = 1; i < argc; i++) {
370 register int code = classify_arg(argv[i]);
371 if (code) {
372 if (i + code > argc)
373 fatal("no argument following %s\n", argv[i]);
fb459a62 374
1136f72d 375 decode_option(argv[i], argv[i + 1]);
fb459a62 376
1136f72d
PR
377 if (argv[i][1] == 'l' || argv[i][1] == 'A')
378 number_of_files++;
fb459a62 379
1136f72d
PR
380 i += code - 1;
381 } else
382 number_of_files++;
383 }
fb459a62 384
1136f72d
PR
385 if (!number_of_files)
386 fatal("no input files");
fb459a62 387
1136f72d
PR
388 p = file_table = (struct file_entry *)
389 xmalloc(number_of_files * sizeof(struct file_entry));
390 bzero(p, number_of_files * sizeof(struct file_entry));
fb459a62 391
1136f72d
PR
392 /* Now scan again and fill in file_table. */
393 /* All options except -A and -l are ignored here. */
fb459a62 394
1136f72d
PR
395 for (i = 1; i < argc; i++) {
396 char *string;
397 register int code = classify_arg(argv[i]);
fb459a62 398
1136f72d
PR
399 if (code == 0) {
400 p->filename = argv[i];
401 p->local_sym_name = argv[i];
402 p++;
403 continue;
404 }
405 if (code == 2)
406 string = argv[i + 1];
407 else
408 string = &argv[i][2];
409
410 if (argv[i][1] == 'B') {
411 if (strcmp(string, "static") == 0)
412 link_mode &= ~DYNAMIC;
413 else if (strcmp(string, "dynamic") == 0)
414 link_mode |= DYNAMIC;
415 else if (strcmp(string, "symbolic") == 0)
416 link_mode |= SYMBOLIC;
417 else if (strcmp(string, "forcearchive") == 0)
418 link_mode |= FORCEARCHIVE;
419 else if (strcmp(string, "shareable") == 0)
420 link_mode |= SHAREABLE;
0f052032
JH
421#ifdef SUN_COMPAT
422 else if (strcmp(string, "silly") == 0)
423 link_mode |= SILLYARCHIVE;
424 else if (strcmp(string, "~silly") == 0)
425 link_mode &= ~SILLYARCHIVE;
426#endif
1136f72d
PR
427 }
428 if (argv[i][1] == 'A') {
429 if (p != file_table)
430 fatal("-A specified before an input file other than the first");
431 p->filename = string;
432 p->local_sym_name = string;
433 p->just_syms_flag = 1;
434 p++;
435 }
436 if (argv[i][1] == 'l') {
437 p->filename = string;
438 p->local_sym_name = concat("-l", string, "");
439 p->search_dirs_flag = 1;
440 if (link_mode & DYNAMIC && !relocatable_output)
441 p->search_dynamic_flag = 1;
442 p++;
443 }
444 i += code - 1;
445 }
fb459a62 446
1136f72d 447 /* Now check some option settings for consistency. */
fb459a62 448
1136f72d
PR
449 if ((magic != OMAGIC)
450 && (text_start - text_start_alignment) & (page_size - 1))
451 fatal("-T argument not multiple of page size, with sharable output");
fb459a62 452
1136f72d
PR
453 /* Append the standard search directories to the user-specified ones. */
454 std_search_dirs(getenv("LD_LIBRARY_PATH"));
455}
fb459a62 456
1136f72d
PR
457void
458add_cmdline_ref(sp)
459 struct glosym *sp;
fb459a62 460{
1136f72d 461 struct glosym **ptr;
fb459a62 462
1136f72d
PR
463 for (ptr = cmdline_references;
464 ptr < cmdline_references + cl_refs_allocated && *ptr;
465 ptr++);
fb459a62 466
1136f72d
PR
467 if (ptr >= cmdline_references + cl_refs_allocated - 1) {
468 int diff = ptr - cmdline_references;
fb459a62 469
1136f72d
PR
470 cl_refs_allocated *= 2;
471 cmdline_references = (struct glosym **)
472 xrealloc(cmdline_references,
473 cl_refs_allocated * sizeof(struct glosym *));
474 ptr = cmdline_references + diff;
475 }
476 *ptr++ = sp;
477 *ptr = (struct glosym *) 0;
fb459a62 478}
fb459a62
NW
479
480int
1136f72d
PR
481set_element_prefixed_p(name)
482 char *name;
fb459a62 483{
1136f72d
PR
484 struct string_list_element *p;
485 int i;
fb459a62 486
1136f72d 487 for (p = set_element_prefixes; p; p = p->next) {
fb459a62 488
1136f72d
PR
489 for (i = 0; p->str[i] != '\0' && (p->str[i] == name[i]); i++);
490 if (p->str[i] == '\0')
491 return 1;
492 }
493 return 0;
fb459a62
NW
494}
495
1136f72d
PR
496/*
497 * Record an option and arrange to act on it later. ARG should be the
498 * following command argument, which may or may not be used by this option.
499 *
500 * The `l' and `A' options are ignored here since they actually specify input
501 * files.
502 */
fb459a62 503
0f052032 504static void
1136f72d
PR
505decode_option(swt, arg)
506 register char *swt, *arg;
507{
508 /* We get Bstatic from gcc on suns. */
509 if (!strcmp(swt + 1, "Bstatic"))
510 return;
511 if (!strcmp(swt + 1, "Bdynamic"))
512 return;
513 if (!strcmp(swt + 1, "Bsymbolic"))
514 return;
515 if (!strcmp(swt + 1, "Bforcearchive"))
516 return;
517 if (!strcmp(swt + 1, "Bshareable"))
518 return;
519 if (!strcmp(swt + 1, "assert"))
520 return;
0f052032
JH
521#ifdef SUN_COMPAT
522 if (!strcmp(swt + 1, "Bsilly"))
523 return;
524#endif
1136f72d
PR
525 if (!strcmp(swt + 1, "Ttext")) {
526 text_start = parse(arg, "%x", "invalid argument to -Ttext");
527 T_flag_specified = 1;
528 return;
fb459a62 529 }
1136f72d
PR
530 if (!strcmp(swt + 1, "Tdata")) {
531 rrs_data_start = parse(arg, "%x", "invalid argument to -Tdata");
532 Tdata_flag_specified = 1;
533 return;
534 }
535 if (!strcmp(swt + 1, "noinhibit-exec")) {
536 force_executable = 1;
537 return;
538 }
539 if (swt[2] != 0)
540 arg = &swt[2];
541
542 switch (swt[1]) {
543 case 'A':
544 return;
545
546 case 'D':
547 specified_data_size = parse(arg, "%x", "invalid argument to -D");
548 return;
549
550 case 'd':
551 if (*arg == 'c')
552 force_common_definition = 1;
553 else if (*arg == 'p')
554 force_alias_definition = 1;
555 else
556 fatal("-d option takes 'c' or 'p' argument");
557 return;
fb459a62 558
1136f72d
PR
559 case 'e':
560 entry_symbol = getsym(arg);
561 if (!entry_symbol->defined && !entry_symbol->referenced)
562 undefined_global_sym_count++;
563 entry_symbol->referenced = 1;
564 add_cmdline_ref(entry_symbol);
565 return;
fb459a62 566
1136f72d
PR
567 case 'l':
568 return;
fb459a62 569
1136f72d
PR
570 case 'L':
571 add_search_dir(arg);
572 return;
fb459a62 573
1136f72d
PR
574 case 'M':
575 write_map = 1;
576 return;
fb459a62 577
1136f72d
PR
578 case 'N':
579 magic = OMAGIC;
580 return;
fb459a62
NW
581
582#ifdef NMAGIC
1136f72d
PR
583 case 'n':
584 magic = NMAGIC;
585 return;
fb459a62 586#endif
fb459a62 587
1136f72d 588 case 'Q':
5e358090 589 magic = QMAGIC;
1136f72d
PR
590 return;
591 case 'Z':
5e358090
DG
592 magic = ZMAGIC;
593 netzmagic = 1;
1136f72d 594 return;
fb459a62 595
1136f72d
PR
596 case 'o':
597 output_filename = arg;
598 return;
fb459a62 599
0f052032
JH
600 case 'p':
601 page_align_data = 1;
602 return;
603
1136f72d
PR
604 case 'r':
605 relocatable_output = 1;
606 magic = OMAGIC;
607 text_start = 0;
608 return;
fb459a62 609
1136f72d
PR
610 case 'S':
611 strip_symbols = STRIP_DEBUGGER;
612 return;
fb459a62 613
1136f72d
PR
614 case 's':
615 strip_symbols = STRIP_ALL;
616 return;
fb459a62 617
1136f72d
PR
618 case 'T':
619 text_start = parse(arg, "%x", "invalid argument to -T");
620 T_flag_specified = 1;
621 return;
fb459a62 622
1136f72d
PR
623 case 't':
624 trace_files = 1;
625 return;
fb459a62 626
1136f72d
PR
627 case 'u':
628 {
629 register symbol *sp = getsym(arg);
fb459a62 630
1136f72d
PR
631 if (!sp->defined && !sp->referenced)
632 undefined_global_sym_count++;
633 sp->referenced = 1;
634 add_cmdline_ref(sp);
635 }
636 return;
637
638#if 1
639 case 'V':
640 soversion = parse(arg, "%d", "invalid argument to -V");
641 return;
fb459a62
NW
642#endif
643
1136f72d
PR
644 case 'X':
645 discard_locals = DISCARD_L;
646 return;
fb459a62 647
1136f72d
PR
648 case 'x':
649 discard_locals = DISCARD_ALL;
650 return;
c53138ba 651
1136f72d
PR
652 case 'y':
653 {
654 register symbol *sp = getsym(&swt[2]);
655 sp->trace = 1;
656 }
657 return;
658
659 case 'z':
5e358090 660 magic = ZMAGIC;
1136f72d
PR
661 return;
662
663 default:
664 fatal("invalid command option `%s'", swt);
665 }
fb459a62
NW
666}
667\f
1136f72d 668/* Convenient functions for operating on one or all files being loaded. */
fb459a62 669
1136f72d
PR
670/*
671 * Call FUNCTION on each input file entry. Do not call for entries for
672 * libraries; instead, call once for each library member that is being
673 * loaded.
674 *
675 * FUNCTION receives two arguments: the entry, and ARG.
676 */
fb459a62
NW
677
678void
1136f72d
PR
679each_file(function, arg)
680 register void (*function) ();
681 register int arg;
682{
683 register int i;
684
685 for (i = 0; i < number_of_files; i++) {
686 register struct file_entry *entry = &file_table[i];
0f052032
JH
687 register struct file_entry *subentry;
688
80f25b52
JH
689 if (entry->scrapped)
690 continue;
0f052032
JH
691
692 if (!entry->library_flag)
693 (*function) (entry, arg);
694
695 subentry = entry->subfiles;
696 for (; subentry; subentry = subentry->chain) {
697 if (subentry->scrapped)
698 continue;
699 (*function) (subentry, arg);
700 }
701
702#ifdef SUN_COMPAT
703 if (entry->silly_archive) {
704
705 if (!entry->is_dynamic)
706 error("Silly");
707
708 if (!entry->silly_archive->library_flag)
709 error("Sillier");
710
711 subentry = entry->silly_archive->subfiles;
80f25b52
JH
712 for (; subentry; subentry = subentry->chain) {
713 if (subentry->scrapped)
714 continue;
1136f72d 715 (*function) (subentry, arg);
80f25b52 716 }
0f052032
JH
717 }
718#endif
fb459a62 719 }
fb459a62
NW
720}
721
1136f72d
PR
722/*
723 * Call FUNCTION on each input file entry until it returns a non-zero value.
724 * Return this value. Do not call for entries for libraries; instead, call
725 * once for each library member that is being loaded.
726 *
727 * FUNCTION receives two arguments: the entry, and ARG. It must be a function
728 * returning unsigned long (though this can probably be fudged).
729 */
fb459a62
NW
730
731unsigned long
1136f72d
PR
732check_each_file(function, arg)
733 register unsigned long (*function) ();
734 register int arg;
735{
736 register int i;
737 register unsigned long return_val;
738
739 for (i = 0; i < number_of_files; i++) {
740 register struct file_entry *entry = &file_table[i];
80f25b52
JH
741 if (entry->scrapped)
742 continue;
1136f72d
PR
743 if (entry->library_flag) {
744 register struct file_entry *subentry = entry->subfiles;
80f25b52
JH
745 for (; subentry; subentry = subentry->chain) {
746 if (subentry->scrapped)
747 continue;
1136f72d
PR
748 if (return_val = (*function) (subentry, arg))
749 return return_val;
80f25b52 750 }
1136f72d
PR
751 } else if (return_val = (*function) (entry, arg))
752 return return_val;
fb459a62 753 }
1136f72d 754 return 0;
fb459a62
NW
755}
756
757/* Like `each_file' but ignore files that were just for symbol definitions. */
758
759void
1136f72d
PR
760each_full_file(function, arg)
761 register void (*function) ();
762 register int arg;
763{
764 register int i;
765
766 for (i = 0; i < number_of_files; i++) {
767 register struct file_entry *entry = &file_table[i];
0f052032
JH
768 register struct file_entry *subentry;
769
770 if (entry->scrapped || entry->just_syms_flag)
1136f72d 771 continue;
0f052032
JH
772
773#ifdef SUN_COMPAT
774 if (entry->silly_archive) {
775
776 if (!entry->is_dynamic)
777 error("Silly");
778
779 if (!entry->silly_archive->library_flag)
780 error("Sillier");
781
782 subentry = entry->silly_archive->subfiles;
783 for (; subentry; subentry = subentry->chain) {
784 if (subentry->scrapped)
785 continue;
1136f72d 786 (*function) (subentry, arg);
0f052032
JH
787 }
788 }
789#endif
790 if (entry->is_dynamic)
791 continue;
792
793 if (!entry->library_flag)
1136f72d 794 (*function) (entry, arg);
0f052032
JH
795
796 subentry = entry->subfiles;
797 for (; subentry; subentry = subentry->chain) {
798 if (subentry->scrapped)
799 continue;
800 (*function) (subentry, arg);
801 }
802
fb459a62 803 }
fb459a62
NW
804}
805
806/* Close the input file that is now open. */
807
808void
1136f72d 809file_close()
fb459a62 810{
1136f72d
PR
811 close(input_desc);
812 input_desc = 0;
813 input_file = 0;
fb459a62
NW
814}
815
1136f72d
PR
816/*
817 * Open the input file specified by 'entry', and return a descriptor. The
818 * open file is remembered; if the same file is opened twice in a row, a new
819 * open is not actually done.
820 */
fb459a62
NW
821int
822file_open (entry)
823 register struct file_entry *entry;
824{
1136f72d 825 register int desc;
fb459a62 826
0f052032 827 if (entry->superfile && entry->superfile->library_flag)
1136f72d 828 return file_open (entry->superfile);
fb459a62 829
1136f72d
PR
830 if (entry == input_file)
831 return input_desc;
fb459a62 832
1136f72d 833 if (input_file) file_close ();
fb459a62 834
1136f72d
PR
835 if (entry->search_dirs_flag) {
836 desc = findlib(entry);
837 } else
838 desc = open (entry->filename, O_RDONLY, 0);
fb459a62 839
1136f72d
PR
840 if (desc > 0) {
841 input_file = entry;
842 input_desc = desc;
843 return desc;
fb459a62 844 }
fb459a62 845
1136f72d
PR
846 perror_file (entry);
847 /* NOTREACHED */
fb459a62
NW
848}
849
1136f72d
PR
850int
851text_offset (entry)
fb459a62
NW
852 struct file_entry *entry;
853{
1136f72d 854 return entry->starting_offset + N_TXTOFF (entry->header);
fb459a62
NW
855}
856\f
857/* Medium-level input routines for rel files. */
858
1136f72d
PR
859/*
860 * Read a file's header into the proper place in the file_entry. DESC is the
861 * descriptor on which the file is open. ENTRY is the file's entry.
862 */
fb459a62
NW
863void
864read_header (desc, entry)
865 int desc;
866 register struct file_entry *entry;
867{
1136f72d
PR
868 register int len;
869 struct exec *loc = (struct exec *) &entry->header;
fb459a62 870
1136f72d
PR
871 if (lseek (desc, entry->starting_offset, L_SET) !=
872 entry->starting_offset)
873 fatal_with_file("read_header: lseek failure ", entry);
fb459a62 874
1136f72d
PR
875 len = read (desc, &entry->header, sizeof (struct exec));
876 if (len != sizeof (struct exec))
877 fatal_with_file ("failure reading header of ", entry);
878
879 md_swapin_exec_hdr(&entry->header);
fb459a62 880
1136f72d
PR
881 if (N_BADMAG (*loc))
882 fatal_with_file ("bad magic number in ", entry);
883
884 entry->header_read_flag = 1;
885}
fb459a62 886
1136f72d
PR
887/*
888 * Read the symbols of file ENTRY into core. Assume it is already open, on
889 * descriptor DESC. Also read the length of the string table, which follows
890 * the symbol table, but don't read the contents of the string table.
891 */
0f052032 892
fb459a62
NW
893void
894read_entry_symbols (desc, entry)
895 struct file_entry *entry;
896 int desc;
897{
1136f72d
PR
898 int str_size;
899 struct nlist *np;
900 int i;
fb459a62 901
1136f72d
PR
902 if (!entry->header_read_flag)
903 read_header (desc, entry);
fb459a62 904
1136f72d
PR
905 np = (struct nlist *) alloca (entry->header.a_syms);
906 entry->nsymbols = entry->header.a_syms / sizeof(struct nlist);
907 entry->symbols = (struct localsymbol *)
908 xmalloc(entry->nsymbols * sizeof(struct localsymbol));
fb459a62 909
1136f72d
PR
910 if (lseek(desc, N_SYMOFF(entry->header) + entry->starting_offset, L_SET)
911 != N_SYMOFF(entry->header) + entry->starting_offset)
912 fatal_with_file ("read_symbols(h): lseek failure ", entry);
fb459a62 913
1136f72d
PR
914 if (entry->header.a_syms != read (desc, np, entry->header.a_syms))
915 fatal_with_file ("premature end of file in symbols of ", entry);
fb459a62 916
1136f72d
PR
917 md_swapin_symbols(np, entry->header.a_syms / sizeof(struct nlist));
918
919 for (i = 0; i < entry->nsymbols; i++) {
920 entry->symbols[i].nzlist.nlist = *np++;
921 entry->symbols[i].nzlist.nz_size = 0;
922 entry->symbols[i].symbol = NULL;
923 entry->symbols[i].next = NULL;
924 entry->symbols[i].gotslot_offset = -1;
925 entry->symbols[i].gotslot_claimed = 0;
27b6ced7
JH
926 entry->symbols[i].write = 0;
927 entry->symbols[i].is_L_symbol = 0;
80f25b52 928 entry->symbols[i].rename = 0;
1136f72d
PR
929 }
930
931 entry->strings_offset = N_STROFF(entry->header) +
932 entry->starting_offset;
933 if (lseek(desc, entry->strings_offset, 0) == (off_t)-1)
934 fatal_with_file ("read_symbols(s): lseek failure ", entry);
935 if (sizeof str_size != read (desc, &str_size, sizeof str_size))
936 fatal_with_file ("bad string table size in ", entry);
fb459a62 937
1136f72d
PR
938 entry->string_size = md_swap_long(str_size);
939}
fb459a62 940
1136f72d
PR
941/*
942 * Read the string table of file ENTRY into core. Assume it is already open,
943 * on descriptor DESC.
944 */
fb459a62
NW
945void
946read_entry_strings (desc, entry)
947 struct file_entry *entry;
948 int desc;
949{
1136f72d 950 int buffer;
fb459a62 951
1136f72d 952 if (!entry->header_read_flag || !entry->strings_offset)
80f25b52
JH
953 fatal_with_file("internal error: cannot read string table for ",
954 entry);
fb459a62 955
1136f72d
PR
956 if (lseek (desc, entry->strings_offset, L_SET) != entry->strings_offset)
957 fatal_with_file ("read_strings: lseek failure ", entry);
958
959 if (entry->string_size !=
960 read (desc, entry->strings, entry->string_size))
961 fatal_with_file ("premature end of file in strings of ", entry);
fb459a62 962
fb459a62 963 return;
fb459a62 964}
1136f72d
PR
965
966/* DEAD - Read in all of the relocation information */
967
968void
969read_relocation ()
970{
971 each_full_file (read_entry_relocation, 0);
972}
973
974/* Read in the relocation sections of ENTRY if necessary */
975
976void
977read_entry_relocation (desc, entry)
978 int desc;
979 struct file_entry *entry;
980{
981 register struct relocation_info *reloc;
982 off_t pos;
983
984 if (!entry->textrel) {
985
986 reloc = (struct relocation_info *)
987 xmalloc(entry->header.a_trsize);
988
989 pos = text_offset(entry) +
990 entry->header.a_text + entry->header.a_data;
991
992 if (lseek(desc, pos, L_SET) != pos)
993 fatal_with_file("read_reloc(t): lseek failure ", entry);
994
995 if (entry->header.a_trsize !=
996 read(desc, reloc, entry->header.a_trsize)) {
997 fatal_with_file (
998 "premature eof in text relocation of ", entry);
999 }
1000 md_swapin_reloc(reloc, entry->header.a_trsize / sizeof(*reloc));
1001 entry->textrel = reloc;
1002 entry->ntextrel = entry->header.a_trsize / sizeof(*reloc);
1003
1004 }
1005
1006 if (!entry->datarel) {
1007
1008 reloc = (struct relocation_info *)
1009 xmalloc(entry->header.a_drsize);
1010
1011 pos = text_offset(entry) + entry->header.a_text +
1012 entry->header.a_data + entry->header.a_trsize;
1013
1014 if (lseek(desc, pos, L_SET) != pos)
1015 fatal_with_file("read_reloc(d): lseek failure ", entry);
1016
1017 if (entry->header.a_drsize !=
1018 read (desc, reloc, entry->header.a_drsize)) {
1019 fatal_with_file (
1020 "premature eof in data relocation of ", entry);
1021 }
1022 md_swapin_reloc(reloc, entry->header.a_drsize / sizeof(*reloc));
1023 entry->datarel = reloc;
1024 entry->ndatarel = entry->header.a_drsize / sizeof(*reloc);
1025
1026 }
1027}
1028
fb459a62
NW
1029\f
1030/* Read in the symbols of all input files. */
1031
fb459a62
NW
1032
1033void
1034load_symbols ()
1035{
1136f72d 1036 register int i;
fb459a62 1037
1136f72d 1038 if (trace_files) fprintf (stderr, "Loading symbols:\n\n");
fb459a62 1039
1136f72d
PR
1040 for (i = 0; i < number_of_files; i++) {
1041 register struct file_entry *entry = &file_table[i];
1042 read_file_symbols (entry);
1043 }
fb459a62 1044
1136f72d 1045 if (trace_files) fprintf (stderr, "\n");
fb459a62
NW
1046}
1047
1136f72d
PR
1048/*
1049 * If ENTRY is a rel file, read its symbol and string sections into core. If
1050 * it is a library, search it and load the appropriate members (which means
1051 * calling this function recursively on those members).
1052 */
fb459a62
NW
1053
1054void
1055read_file_symbols (entry)
1056 register struct file_entry *entry;
1057{
1136f72d
PR
1058 register int desc;
1059 register int len;
1060 struct exec hdr;
1061
1062 desc = file_open (entry);
1063
1064 len = read (desc, &hdr, sizeof hdr);
1065 if (len != sizeof hdr)
1066 fatal_with_file ("failure reading header of ", entry);
1067
1068 md_swapin_exec_hdr(&hdr);
1069
1070 if (!N_BADMAG (hdr)) {
1071 if (N_IS_DYNAMIC(hdr)) {
1072 if (relocatable_output) {
1073 fatal_with_file(
1074 "-r and shared objects currently not supported ",
1075 entry);
1076 return;
1077 }
1078 entry->is_dynamic = 1;
0f052032 1079 if (entry->superfile || rrs_add_shobj(entry))
80f25b52
JH
1080 read_shared_object(desc, entry);
1081 else
1082 entry->scrapped = 1;
1136f72d
PR
1083 } else {
1084 read_entry_symbols (desc, entry);
1085 entry->strings = (char *) alloca (entry->string_size);
1086 read_entry_strings (desc, entry);
1087 read_entry_relocation(desc, entry);
1088 enter_file_symbols (entry);
1089 entry->strings = 0;
1090 }
1091 } else {
1092 char armag[SARMAG];
1093
1094 lseek (desc, 0, 0);
1095 if (SARMAG != read (desc, armag, SARMAG) ||
1096 strncmp (armag, ARMAG, SARMAG))
1097 fatal_with_file(
1098 "malformed input file (not rel or archive) ", entry);
1099 entry->library_flag = 1;
1100 search_library (desc, entry);
1101 }
fb459a62 1102
1136f72d 1103 file_close ();
fb459a62
NW
1104}
1105\f
1106/* Enter the external symbol defs and refs of ENTRY in the hash table. */
1107
1108void
1109enter_file_symbols (entry)
1110 struct file_entry *entry;
1111{
1136f72d
PR
1112 struct localsymbol *lsp, *lspend;
1113
1114 if (trace_files) prline_file_name (entry, stderr);
1115
1116 lspend = entry->symbols + entry->nsymbols;
1117
1118 for (lsp = entry->symbols; lsp < lspend; lsp++) {
1119 register struct nlist *p = &lsp->nzlist.nlist;
1120
1121 if (p->n_type == (N_SETV | N_EXT))
1122 continue;
1123
1124 /*
1125 * Turn magically prefixed symbols into set symbols of
1126 * a corresponding type.
1127 */
1128 if (set_element_prefixes &&
1129 set_element_prefixed_p(entry->strings+lsp->nzlist.nz_strx))
1130 lsp->nzlist.nz_type += (N_SETA - N_ABS);
1131
1132 if (SET_ELEMENT_P(p->n_type)) {
1133 set_symbol_count++;
1134 if (!relocatable_output)
1135 enter_global_ref(lsp,
1136 p->n_un.n_strx + entry->strings, entry);
1137 } else if (p->n_type == N_WARNING) {
1138 char *name = p->n_un.n_strx + entry->strings;
1139
1140 /* Grab the next entry. */
1141 p++;
1142 if (p->n_type != (N_UNDF | N_EXT)) {
1143 error("Warning symbol found in %s without external reference following.",
1144 get_file_name(entry));
1145 make_executable = 0;
1146 p--; /* Process normally. */
1147 } else {
1148 symbol *sp;
1149 char *sname = p->n_un.n_strx + entry->strings;
1150 /* Deal with the warning symbol. */
1151 enter_global_ref(lsp,
1152 p->n_un.n_strx + entry->strings, entry);
1153 sp = getsym (sname);
1154 sp->warning = (char *)xmalloc(strlen(name)+1);
1155 strcpy (sp->warning, name);
1156 warning_count++;
1157 }
1158 } else if (p->n_type & N_EXT) {
1159 enter_global_ref(lsp,
1160 p->n_un.n_strx + entry->strings, entry);
27b6ced7
JH
1161 } else if (p->n_un.n_strx &&
1162 (p->n_un.n_strx + entry->strings)[0] == LPREFIX)
1163 lsp->is_L_symbol = 1;
fb459a62 1164 }
fb459a62 1165
fb459a62
NW
1166}
1167
1136f72d
PR
1168/*
1169 * Enter one global symbol in the hash table. LSP points to the `struct
1170 * localsymbol' from the file that describes the global symbol. NAME is the
1171 * symbol's name. ENTRY is the file entry for the file the symbol comes from.
1172 *
1173 * LSP is put on the chain of all such structs that refer to the same symbol.
1174 * This chain starts in the `refs' for symbols from relocatable objects. A
1175 * backpointer to the global symbol is kept in LSP.
1176 *
27b6ced7 1177 * Symbols from shared objects are linked through `soref'. For such symbols
1136f72d
PR
1178 * that's all we do at this stage, with the exception of the case where the
1179 * symbol is a common. The `referenced' bit is only set for references from
1180 * relocatable objects.
1181 *
1182 */
fb459a62 1183
0f052032 1184static void
1136f72d
PR
1185enter_global_ref (lsp, name, entry)
1186 struct localsymbol *lsp;
fb459a62
NW
1187 char *name;
1188 struct file_entry *entry;
1189{
1136f72d
PR
1190 register struct nzlist *nzp = &lsp->nzlist;
1191 register symbol *sp = getsym (name);
1192 register int type = nzp->nz_type;
1193 int oldref = sp->referenced;
1194 int olddef = sp->defined;
1195 int com = sp->defined && sp->max_common_size;
1196
1197 if (type == (N_INDR | N_EXT)) {
1198 sp->alias = getsym(entry->strings + (lsp + 1)->nzlist.nz_strx);
1199 if (sp == sp->alias) {
1200 error("%s: %s is alias for itself",
1201 get_file_name(entry), name);
1202 /* Rewrite symbol as global text symbol with value 0 */
1203 lsp->nzlist.nz_type = N_TEXT|N_EXT;
1204 lsp->nzlist.nz_value = 0;
1205 make_executable = 0;
0f052032 1206 } else {
1136f72d 1207 global_alias_count++;
0f052032 1208 }
1136f72d 1209 }
fb459a62 1210
1136f72d
PR
1211 if (entry->is_dynamic) {
1212 lsp->next = sp->sorefs;
1213 sp->sorefs = lsp;
1214
1215 /*
1216 * Handle commons from shared objects:
1217 * 1) If symbol hitherto undefined, turn it into a common.
1218 * 2) If symbol already common, update size if necessary.
1219 */
1220/*XXX - look at case where commons are only in shared objects */
1221 if (type == (N_UNDF | N_EXT) && nzp->nz_value) {
1222 if (!olddef) {
1223 if (oldref)
1224 undefined_global_sym_count--;
1225 common_defined_global_count++;
1226 sp->max_common_size = nzp->nz_value;
1227 sp->defined = N_UNDF | N_EXT;
1228 } else if (com && sp->max_common_size < nzp->nz_value) {
1229 sp->max_common_size = nzp->nz_value;
1230 }
1231 }
fb459a62 1232
1136f72d
PR
1233 /*
1234 * Handle size information in shared objects.
1235 */
1236 if (nzp->nz_size > sp->size)
1237 sp->size = nzp->nz_size;
fb459a62 1238
1136f72d
PR
1239 lsp->symbol = sp;
1240 return;
fb459a62 1241 }
fb459a62 1242
1136f72d
PR
1243 lsp->next = sp->refs;
1244 sp->refs = lsp;
1245 lsp->symbol = sp;
fb459a62 1246
1136f72d
PR
1247 sp->referenced = 1;
1248
1249 if (sp == dynamic_symbol || sp == got_symbol) {
1250 if (type != (N_UNDF | N_EXT) && !entry->just_syms_flag)
1251 fatal("Linker reserved symbol %s defined as type %x ",
1252 name, type);
1253 return;
fb459a62
NW
1254 }
1255
1136f72d
PR
1256#ifdef N_SIZE
1257 if (type == (N_SIZE | N_EXT)) {
27b6ced7
JH
1258 if (relocatable_output && nzp->nz_value != 0 && sp->size == 0)
1259 size_sym_count++;
1136f72d
PR
1260 if (sp->size < nzp->nz_value)
1261 sp->size = nzp->nz_value;
1262 } else
1263#endif
1264 if (type != (N_UNDF | N_EXT) || nzp->nz_value) {
1265
1266 /*
1267 * Set `->defined' here, so commons and undefined globals
1268 * can be counted correctly.
1269 */
1270 if (!sp->defined || sp->defined == (N_UNDF | N_EXT))
1271 sp->defined = type;
1272
1273 if (oldref && !olddef)
1274 /*
1275 * It used to be undefined and we're defining it.
1276 */
1277 undefined_global_sym_count--;
1278
1279 if (!olddef && type == (N_UNDF | N_EXT) && nzp->nz_value) {
1280 /*
1281 * First definition and it's common.
1282 */
1283 common_defined_global_count++;
1284 sp->max_common_size = nzp->nz_value;
1285 } else if (com && type != (N_UNDF | N_EXT)) {
1286 /*
1287 * It used to be common and we're defining
1288 * it as something else.
1289 */
1290 common_defined_global_count--;
1291 sp->max_common_size = 0;
1292 } else if (com && type == (N_UNDF | N_EXT)
1293 && sp->max_common_size < nzp->nz_value)
1294 /*
1295 * It used to be common and this is a new common entry
1296 * to which we need to pay attention.
1297 */
1298 sp->max_common_size = nzp->nz_value;
1299
1300 if (SET_ELEMENT_P(type) && (!olddef || com))
1301 set_vector_count++;
1302
1303 } else if (!oldref)
1304 undefined_global_sym_count++;
1305
1306
1307 if (sp == end_symbol && entry->just_syms_flag && !T_flag_specified)
1308 text_start = nzp->nz_value;
1309
1310 if (sp->trace) {
1311 register char *reftype;
1312 switch (type & N_TYPE) {
1313 case N_UNDF:
1314 reftype = nzp->nz_value?
1315 "defined as common":"referenced";
1316 break;
1317
1318 case N_ABS:
1319 reftype = "defined as absolute";
1320 break;
1321
1322 case N_TEXT:
1323 reftype = "defined in text section";
1324 break;
1325
1326 case N_DATA:
1327 reftype = "defined in data section";
1328 break;
1329
1330 case N_BSS:
1331 reftype = "defined in BSS section";
1332 break;
1333
1334 default:
1335 reftype = "I don't know this type";
1336 break;
1337 }
1338
1339 fprintf (stderr, "symbol %s %s in ", sp->name, reftype);
1340 print_file_name (entry, stderr);
1341 fprintf (stderr, "\n");
1342 }
fb459a62
NW
1343}
1344
1136f72d
PR
1345/*
1346 * This return 0 if the given file entry's symbol table does *not* contain
1347 * the nlist point entry, and it returns the files entry pointer (cast to
1348 * unsigned long) if it does.
1349 */
fb459a62
NW
1350
1351unsigned long
1136f72d 1352contains_symbol (entry, np)
fb459a62 1353 struct file_entry *entry;
1136f72d 1354 register struct nlist *np;
fb459a62 1355{
1136f72d
PR
1356 if (np >= &entry->symbols->nzlist.nlist &&
1357 np < &(entry->symbols + entry->nsymbols)->nzlist.nlist)
1358 return (unsigned long) entry;
1359 return 0;
fb459a62
NW
1360}
1361
fb459a62 1362
1136f72d
PR
1363/*
1364 * Having entered all the global symbols and found the sizes of sections of
1365 * all files to be linked, make all appropriate deductions from this data.
1366 *
1367 * We propagate global symbol values from definitions to references. We compute
1368 * the layout of the output file and where each input file's contents fit
1369 * into it.
1370 *
1371 * This is now done in several stages.
1372 *
1373 * 1) All global symbols are examined for definitions in relocatable (.o)
1374 * files. The symbols' type is set according to the definition found,
1375 * but its value can not yet be determined. In stead, we keep a pointer
1376 * to the file entry's localsymbol that bequeathed the global symbol with
1377 * its definition. Also, multiple (incompatible) definitions are checked
1378 * for in this pass. If no definition comes forward, the set of local
1379 * symbols originating from shared objects is searched for a definition.
1380 *
1381 * 2) Then the relocation information of each relocatable file is examined
0f052032 1382 * for possible contributions to the RRS section.
1136f72d
PR
1383 *
1384 * 3) When this is done, the sizes and start addresses are set of all segments
1385 * that will appear in the output file (including the RRS segment).
1386 *
1387 * 4) Finally, all symbols are relocated according according to the start
1388 * of the entry they are part of. Then global symbols are assigned their
1389 * final values. Also, space for commons and imported data are allocated
1390 * during this pass, if the link mode in effect so demands.
1391 *
1392 */
fb459a62 1393
fb459a62 1394
0f052032 1395static void
1136f72d 1396digest_symbols ()
fb459a62 1397{
fb459a62 1398
1136f72d
PR
1399 if (trace_files)
1400 fprintf(stderr, "Digesting symbol information:\n\n");
1401
1402 if (!relocatable_output) {
1403 /*
1404 * The set sector size is the number of set elements + a word
1405 * for each symbol for the length word at the beginning of
1406 * the vector, plus a word for each symbol for a zero at the
1407 * end of the vector (for incremental linking).
1408 */
0f052032 1409 set_sect_size = (set_symbol_count + 2 * set_vector_count) *
1136f72d 1410 sizeof (unsigned long);
0f052032 1411 set_vectors = (long *)xmalloc (set_sect_size);
1136f72d
PR
1412 setv_fill_count = 0;
1413 }
fb459a62 1414
1136f72d
PR
1415 /* Pass 1: check and define symbols */
1416 defined_global_sym_count = 0;
1417 digest_pass1();
fb459a62 1418
27b6ced7
JH
1419 each_full_file(consider_relocation, 0); /* Text */
1420 each_full_file(consider_relocation, 1); /* Data */
fb459a62 1421
1136f72d
PR
1422 /*
1423 * Compute total size of sections.
1424 * RRS data is the first output data section, RRS text is the last
1425 * text section. Thus, DATA_START is calculated from RRS_DATA_START
1426 * and RRS_DATA_SIZE, while RRS_TEXT_START is derived from TEXT_START
1427 * and TEXT_SIZE.
1428 */
1429 consider_rrs_section_lengths();
1430 each_full_file(consider_file_section_lengths, 0);
1431 rrs_text_start = text_start + text_size;
1432 text_size += rrs_text_size;
1433 data_size += rrs_data_size;
1434
1435 /*
1436 * If necessary, pad text section to full page in the file. Include
1437 * the padding in the text segment size.
1438 */
1439
5e358090 1440 if (magic == ZMAGIC || magic == QMAGIC || page_align_data) {
1136f72d
PR
1441 int text_end = text_size + N_TXTOFF(outheader);
1442 text_pad = PALIGN(text_end, page_size) - text_end;
1443 text_size += text_pad;
fb459a62 1444 }
1136f72d 1445 outheader.a_text = text_size;
fb459a62 1446
1136f72d
PR
1447 /*
1448 * Make the data segment address start in memory on a suitable
1449 * boundary.
1450 */
fb459a62 1451
1136f72d
PR
1452 if (!Tdata_flag_specified)
1453 rrs_data_start = text_start +
1454 DATA_START(outheader) - TEXT_START(outheader);
fb459a62 1455
1136f72d
PR
1456 data_start = rrs_data_start + rrs_data_size;
1457 if (!relocatable_output) {
1458 set_sect_start = rrs_data_start + data_size;
1459 data_size += set_sect_size;
1460 }
1461 bss_start = rrs_data_start + data_size;
1462
1463#ifdef DEBUG
1464printf("textstart = %#x, textsize = %#x, rrs_text_start = %#x, rrs_text_size %#x\n",
1465 text_start, text_size, rrs_text_start, rrs_text_size);
1466printf("datastart = %#x, datasize = %#x, rrs_data_start %#x, rrs_data_size %#x\n",
1467 data_start, data_size, rrs_data_start, rrs_data_size);
1468printf("bssstart = %#x, bsssize = %#x\n",
1469 bss_start, bss_size);
fb459a62
NW
1470#endif
1471
1136f72d 1472 /* Compute start addresses of each file's sections and symbols. */
fb459a62 1473
1136f72d
PR
1474 each_full_file(relocate_file_addresses, 0);
1475 relocate_rrs_addresses();
fb459a62 1476
1136f72d
PR
1477 /* Pass 2: assign values to symbols */
1478 digest_pass2();
fb459a62 1479
1136f72d
PR
1480 if (end_symbol) { /* These are null if -r. */
1481 etext_symbol->value = text_start + text_size - text_pad;
1482 edata_symbol->value = rrs_data_start + data_size;
1483 end_symbol->value = rrs_data_start + data_size + bss_size;
fb459a62 1484 }
1136f72d
PR
1485 /*
1486 * Figure the data_pad now, so that it overlaps with the bss
1487 * addresses.
1488 */
fb459a62 1489
1136f72d
PR
1490 if (specified_data_size && specified_data_size > data_size)
1491 data_pad = specified_data_size - data_size;
fb459a62 1492
5e358090 1493 if (magic == ZMAGIC || magic == QMAGIC)
1136f72d 1494 data_pad = PALIGN(data_pad + data_size, page_size) - data_size;
fb459a62 1495
1136f72d
PR
1496 bss_size -= data_pad;
1497 if (bss_size < 0)
1498 bss_size = 0;
fb459a62 1499
1136f72d 1500 data_size += data_pad;
27b6ced7
JH
1501
1502 /*
1503 * Calculate total number of symbols that will go into
1504 * the output symbol table (barring DISCARD_* settings).
1505 */
1506 global_sym_count = defined_global_sym_count +
1507 undefined_global_sym_count;
1508
1509 if (dynamic_symbol->referenced)
1510 global_sym_count++;
1511
1512 if (got_symbol->referenced)
1513 global_sym_count++;
1514
0f052032 1515 if (relocatable_output || building_shared_object)
27b6ced7 1516 /* For each alias we write out two struct nlists */
0f052032
JH
1517 global_sym_count += global_alias_count;
1518
1519 if (relocatable_output)
1520 /* We write out the original N_SET* symbols */
1521 global_sym_count += size_sym_count;
1522
1523#ifdef DEBUG
1524printf("global symbols %d (defined %d, undefined %d, aliases %d), locals: %d, \
1525debug symbols: %d, set_symbols %d\n",
1526 global_sym_count,
1527 defined_global_sym_count, undefined_global_sym_count, global_alias_count,
1528 local_sym_count, debugger_sym_count, set_symbol_count);
1529#endif
1136f72d 1530}
fb459a62 1531
0f052032 1532static void
1136f72d
PR
1533digest_pass1()
1534{
1535
1536 /*
1537 * Now, for each symbol, verify that it is defined globally at most
1538 * once within relocatable files (except when building a shared lib).
1539 * and set the `defined' field if there is a definition.
1540 *
1541 * Then check the shared object symbol chain for any remaining
1542 * undefined symbols. Set the `so_defined' field for any
1543 * definition find this way.
1544 */
1545 FOR_EACH_SYMBOL(i, sp) {
1546 struct localsymbol *lsp;
1547 int defs = 0;
1548
1549 if (!sp->referenced) {
1550#if 0
1551 /* Check for undefined symbols in shared objects */
1552 int type;
1553 for (lsp = sp->sorefs; lsp; lsp = lsp->next) {
1554 type = lsp->nzlist.nlist.n_type;
1555 if ((type & N_EXT) && type != (N_UNDF | N_EXT))
1556 break;
1557 }
1558 if ((type & N_EXT) && type == (N_UNDF | N_EXT))
1559 undefined_shobj_sym_count++;
fb459a62
NW
1560#endif
1561
1136f72d
PR
1562 /* Superfluous symbol from shared object */
1563 continue;
fb459a62 1564 }
fb459a62 1565
1136f72d
PR
1566 if (sp == got_symbol || sp == dynamic_symbol)
1567 continue;
1568
1569 for (lsp = sp->refs; lsp; lsp = lsp->next) {
1570 register struct nlist *p = &lsp->nzlist.nlist;
1571 register int type = p->n_type;
1572
1573 if (SET_ELEMENT_P(type)) {
1574 if (relocatable_output)
1575 fatal(
1576 "internal error: global ref to set el %s with -r",
1577 sp->name);
1578 if (!defs++) {
1579 sp->defined = N_SETV | N_EXT;
1580 sp->value =
1581 setv_fill_count++ * sizeof(long);
1582 } else if ((sp->defined & N_TYPE) != N_SETV) {
1583 sp->multiply_defined = 1;
1584 multiple_def_count++;
1585 }
1586 /* Keep count and remember symbol */
1587 sp->setv_count++;
1588 set_vectors[setv_fill_count++] = (long)p;
92575836
JH
1589 if (building_shared_object) {
1590 struct relocation_info reloc;
1591 RELOC_ADDRESS(&reloc) =
1592 setv_fill_count * sizeof(long);
1593 alloc_rrs_segment_reloc(NULL, &reloc);
1594 }
1136f72d
PR
1595
1596 } else if ((type & N_EXT) && type != (N_UNDF | N_EXT)
1597 && (type & N_TYPE) != N_FN
1598 && (type & N_TYPE) != N_SIZE) {
1599 /* non-common definition */
1600 if (defs++ && sp->value != p->n_value
1601 && entry_symbol) {
1602 sp->multiply_defined = 1;
1603 multiple_def_count++;
1604 }
1605 sp->def_nlist = p;
1606 sp->defined = type;
1607 }
fb459a62
NW
1608 }
1609
1136f72d
PR
1610 if (sp->defined) {
1611 if ((sp->defined & N_TYPE) == N_SETV)
1612 /* Allocate zero entry in set vector */
1613 setv_fill_count++;
0f052032
JH
1614 /*
1615 * At this stage, we do not know whether an alias
1616 * is going to be defined for real here, or whether
1617 * it refers to a shared object symbol. The decision
1618 * is deferred until digest_pass2().
1619 */
1620 if (!sp->alias)
1621 defined_global_sym_count++;
1136f72d
PR
1622 continue;
1623 }
fb459a62 1624
1136f72d
PR
1625 if (relocatable_output)
1626 /* We're done */
1627 continue;
1628
1629 /*
1630 * Still undefined, search the shared object symbols for a
1631 * definition. This symbol must go into the RRS.
1632 */
1633 if (building_shared_object) {
1634 /* Just punt for now */
1635 undefined_global_sym_count--;
1636 continue;
1637 }
fb459a62 1638
0f052032 1639 again:
1136f72d
PR
1640 for (lsp = sp->sorefs; lsp; lsp = lsp->next) {
1641 register struct nlist *p = &lsp->nzlist.nlist;
1642 register int type = p->n_type;
1643
1644 if ((type & N_EXT) && type != (N_UNDF | N_EXT)
80f25b52 1645 && (type & N_TYPE) != N_FN) {
1136f72d
PR
1646 /* non-common definition */
1647 sp->def_nlist = p;
1648 sp->so_defined = type;
0f052032
JH
1649 if (sp->referenced)
1650 undefined_global_sym_count--;
1651 else
1652 sp->referenced = 1;
1136f72d
PR
1653#ifdef DEBUG
1654printf("shr: %s gets defined to %x with value %x\n", sp->name, type, sp->value);
1655#endif
0f052032
JH
1656 if (sp->alias && !sp->alias->referenced) {
1657 sp = sp->alias;
1658 goto again;
1659 }
1136f72d
PR
1660 break;
1661 }
1662 }
1663 } END_EACH_SYMBOL;
0f052032
JH
1664
1665 if (setv_fill_count != set_sect_size/sizeof(long))
1666 fatal("internal error: allocated set symbol space (%d) \
1667doesn't match actual (%d)",
1668 set_sect_size/sizeof(long), setv_fill_count);
fb459a62 1669}
fb459a62 1670
0f052032 1671static void
1136f72d
PR
1672digest_pass2()
1673{
1674 /*
1675 * Assign each symbol its final value.
1676 * If not -r'ing, allocate common symbols in the BSS section.
1677 */
1678
1679 FOR_EACH_SYMBOL(i, sp) {
1680 int size;
1681 int align = sizeof(int);
1682
1683 if (!sp->referenced)
1684 continue;
1685
0f052032
JH
1686 if (sp->alias &&
1687 (relocatable_output || building_shared_object ||
1688 (sp->alias->defined && !sp->alias->so_defined)))
1689 /*
1690 * The alias points at a defined symbol, so it
1691 * must itself be counted as one too, in order to
1692 * compute the correct number of symbol table entries.
1693 */
1694 defined_global_sym_count++;
1695
1136f72d
PR
1696 if ((sp->defined & N_TYPE) == N_SETV) {
1697 /*
1698 * Set length word at front of vector and zero byte
1699 * at end. Reverse the vector itself to put it in
1700 * file order.
1701 */
1702 unsigned long i, tmp;
1703 unsigned long length_word_index =
1704 sp->value / sizeof(long);
1705
1706 /* Relocate symbol value */
1707 sp->value += set_sect_start;
1708
1709 set_vectors[length_word_index] = sp->setv_count;
1710
1711 /*
1712 * Relocate vector to final address.
1713 */
1714 for (i = 0; i < sp->setv_count; i++) {
1715 struct nlist *p = (struct nlist *)
1716 set_vectors[1+i+length_word_index];
1717
1718 set_vectors[1+i+length_word_index] = p->n_value;
92575836
JH
1719 if (building_shared_object) {
1720 struct relocation_info reloc;
1721 RELOC_ADDRESS(&reloc) =
1722 (1 + i + length_word_index) *
1723 sizeof(long)
1724 + set_sect_start;
1725 RELOC_TYPE(&reloc) =
1726 (sp->defined & N_TYPE);
1727 claim_rrs_segment_reloc(NULL, &reloc);
1728 }
1136f72d
PR
1729 }
1730
1731 /*
1732 * Reverse the vector.
1733 */
1734 for (i = 1; i < (sp->setv_count - 1)/2 + 1; i++) {
1735
1736 tmp = set_vectors[length_word_index + i];
1737 set_vectors[length_word_index + i] =
1738 set_vectors[length_word_index + sp->setv_count + 1 - i];
1739 set_vectors[length_word_index + sp->setv_count + 1 - i] = tmp;
1740 }
1741
1742 /* Clear terminating entry */
1743 set_vectors[length_word_index + sp->setv_count + 1] = 0;
1744 continue;
1745 }
fb459a62 1746
fb459a62 1747
1136f72d
PR
1748 if (sp->defined && sp->def_nlist &&
1749 ((sp->defined & ~N_EXT) != N_SETV))
1750 sp->value = sp->def_nlist->n_value;
1751
1752 if (building_shared_object && !(link_mode & SYMBOLIC))
1753 /* No common allocation in shared objects */
1754 continue;
1755
1756 if ((size = sp->max_common_size) != 0) {
1757 /*
1758 * It's a common.
1759 */
1760 if (sp->defined != (N_UNDF + N_EXT))
1761 fatal("%s: common isn't", sp->name);
1762
1763 } else if ((size = sp->size) != 0 && sp->defined == N_SIZE) {
1764 /*
1765 * It's data from shared object with size info.
1766 */
7fc7155d 1767 if (!sp->so_defined)
1136f72d
PR
1768 fatal("%s: Bogus N_SIZE item", sp->name);
1769
1770 } else
1771 /*
1772 * It's neither
1773 */
1774 continue;
1775
1776
1777 if (relocatable_output && !force_common_definition) {
1778 sp->defined = 0;
1779 undefined_global_sym_count++;
1780 defined_global_sym_count--;
1781 continue;
1782 }
fb459a62 1783
1136f72d
PR
1784 /*
1785 * Round up to nearest sizeof (int). I don't know whether
1786 * this is necessary or not (given that alignment is taken
1787 * care of later), but it's traditional, so I'll leave it in.
1788 * Note that if this size alignment is ever removed, ALIGN
1789 * above will have to be initialized to 1 instead of sizeof
1790 * (int).
1791 */
fb459a62 1792
1136f72d 1793 size = PALIGN(size, sizeof(int));
fb459a62 1794
1136f72d
PR
1795 while (!(size & align))
1796 align <<= 1;
fb459a62 1797
1136f72d
PR
1798 align = align > MAX_ALIGNMENT ?
1799 MAX_ALIGNMENT : align;
fb459a62 1800
1136f72d
PR
1801 bss_size = PALIGN(bss_size + data_size + rrs_data_start, align)
1802 - (data_size + rrs_data_start);
fb459a62 1803
1136f72d
PR
1804 sp->value = rrs_data_start + data_size + bss_size;
1805 if (sp->defined == (N_UNDF | N_EXT))
1806 sp->defined = N_BSS | N_EXT;
1807 else {
1808 sp->so_defined = 0;
1809 defined_global_sym_count++;
1810 }
1811 bss_size += size;
1812 if (write_map)
1813 printf("Allocating %s %s: %x at %x\n",
1814 sp->defined==(N_BSS|N_EXT)?"common":"data",
1815 sp->name, size, sp->value);
fb459a62 1816
1136f72d 1817 } END_EACH_SYMBOL;
fb459a62
NW
1818}
1819
0f052032 1820
fb459a62 1821/*
1136f72d
PR
1822 * Scan relocation info in ENTRY for contributions to the dynamic section of
1823 * the output file.
fb459a62 1824 */
0f052032 1825static void
1136f72d
PR
1826consider_relocation (entry, dataseg)
1827 struct file_entry *entry;
1828 int dataseg;
1829{
1830 struct relocation_info *reloc, *end;
1831 struct localsymbol *lsp;
1832 symbol *sp;
1833
1834 if (dataseg == 0) {
1835 /* Text relocations */
1836 reloc = entry->textrel;
1837 end = entry->textrel + entry->ntextrel;
1838 } else {
1839 /* Data relocations */
1840 reloc = entry->datarel;
1841 end = entry->datarel + entry->ndatarel;
fb459a62 1842 }
fb459a62 1843
1136f72d
PR
1844 for (; reloc < end; reloc++) {
1845
80f25b52
JH
1846 if (relocatable_output) {
1847 lsp = &entry->symbols[reloc->r_symbolnum];
27b6ced7
JH
1848 if (RELOC_BASEREL_P(reloc)) {
1849 pic_code_seen = 1;
1850 if (!RELOC_EXTERN_P(reloc))
1851 lsp->rename = 1;
80f25b52
JH
1852 }
1853 continue;
1854 }
1855
1136f72d
PR
1856 /*
1857 * First, do the PIC specific relocs.
1858 * r_relative and r_copy should not occur at this point
1859 * (we do output them). The others break down to these
1860 * combinations:
1861 *
1862 * jmptab: extern: needs jmp slot
1863 * !extern: "intersegment" jump/call,
1864 * should get resolved in output
1865 *
1866 * baserel: extern: need GOT entry
1867 * !extern: may need GOT entry,
1868 * machine dependent
1869 *
1870 * baserel's always refer to symbol through `r_symbolnum'
1871 * whether extern or not. Internal baserels refer to statics
1872 * that must be accessed either *through* the GOT table like
1873 * global data, or by means of an offset from the GOT table.
1874 * The macro RELOC_STATICS_THROUGH_GOT_P() determines which
1875 * applies, since this is a machine (compiler?) dependent
1876 * addressing mode.
1877 */
1878
1879 if (RELOC_JMPTAB_P(reloc)) {
1880
1881 if (!RELOC_EXTERN_P(reloc))
1882 continue;
1883
1884 lsp = &entry->symbols[reloc->r_symbolnum];
1885 sp = lsp->symbol;
1886 if (sp->alias)
1887 sp = sp->alias;
27b6ced7 1888 alloc_rrs_jmpslot(entry, sp);
1136f72d
PR
1889
1890 } else if (RELOC_BASEREL_P(reloc)) {
1891
1892 lsp = &entry->symbols[reloc->r_symbolnum];
27b6ced7 1893 alloc_rrs_gotslot(entry, reloc, lsp);
1136f72d
PR
1894
1895 } else if (RELOC_EXTERN_P(reloc)) {
1896
1897 /*
1898 * Non-PIC relocations.
1899 * If the definition comes from a shared object
1900 * we need a relocation entry in RRS.
1901 *
1902 * If the .so definition is N_TEXT a jmpslot is
1903 * allocated.
1904 *
1905 * If it is N_DATA we allocate an address in BSS (?)
1906 * and arrange for the data to be copied at run-time.
1907 * The symbol is temporarily marked with N_SIZE in
1908 * the `defined' field, so we know what to do in
1909 * pass2() and during actual relocation. We convert
1910 * the type back to something real again when writing
1911 * out the symbols.
1912 *
1913 */
1914 lsp = &entry->symbols[reloc->r_symbolnum];
1915 sp = lsp->symbol;
1916 if (sp == NULL)
1917 fatal_with_file(
1918 "internal error, sp==NULL", entry);
1919
1920 if (sp->alias)
1921 sp = sp->alias;
1922
1923 /*
1924 * Skip refs to _GLOBAL_OFFSET_TABLE_ and __DYNAMIC
1925 */
1926 if (sp == got_symbol) {
1927 if (!CHECK_GOT_RELOC(reloc))
1928 fatal_with_file(
1929 "Unexpected relocation type ", entry);
1930 continue;
1931 }
1932
1933 /*
1934 * This symbol gives rise to a RRS entry
1935 */
1936
1937 if (building_shared_object) {
27b6ced7 1938 alloc_rrs_reloc(entry, sp);
1136f72d
PR
1939 continue;
1940 }
1941
7fc7155d
PR
1942 /*
1943 * Only allocate an alias for function calls. Use
1944 * sp->size here as a heuristic to discriminate
1945 * between function definitions and data residing
1946 * in the text segment.
1947 * NOTE THAT THE COMPILER MUST NOT GENERATE ".size"
1948 * DIRECTIVES FOR FUNCTIONS.
1949 * In the future we might go for ".type" directives.
1950 */
1951 if (force_alias_definition && sp->size == 0 &&
1136f72d
PR
1952 sp->so_defined == N_TEXT + N_EXT) {
1953
1954 /* Call to shared library procedure */
27b6ced7
JH
1955 alloc_rrs_jmpslot(entry, sp);
1956#define EXPERIMENTAL
1957#ifdef EXPERIMENTAL
c62b29f8 1958 if (!RELOC_PCREL_P(reloc)) {
27b6ced7
JH
1959#ifdef DEBUG
1960printf("%s: FUNC flag set\n", sp->name);
1961#endif
c62b29f8
JH
1962 sp->aux = RRS_FUNC;
1963 }
27b6ced7
JH
1964#endif
1965
1136f72d 1966 } else if (sp->size &&
7fc7155d
PR
1967 (sp->so_defined == N_DATA + N_EXT ||
1968 sp->so_defined == N_TEXT + N_EXT)) {
1136f72d
PR
1969
1970 /* Reference to shared library data */
27b6ced7 1971 alloc_rrs_cpy_reloc(entry, sp);
1136f72d
PR
1972 sp->defined = N_SIZE;
1973
1974 } else if (!sp->defined && sp->max_common_size == 0)
27b6ced7 1975 alloc_rrs_reloc(entry, sp);
1136f72d
PR
1976
1977 } else {
1978 /*
1979 * Segment relocation.
1980 * Prepare an RRS relocation as these are load
1981 * address dependent.
1982 */
1983 if (building_shared_object) {
27b6ced7 1984 alloc_rrs_segment_reloc(entry, reloc);
1136f72d
PR
1985 }
1986 }
fb459a62 1987 }
fb459a62
NW
1988}
1989
1136f72d
PR
1990/*
1991 * Accumulate the section sizes of input file ENTRY into the section sizes of
1992 * the output file.
1993 */
0f052032 1994static void
1136f72d
PR
1995consider_file_section_lengths (entry)
1996 register struct file_entry *entry;
fb459a62 1997{
1136f72d
PR
1998 if (entry->just_syms_flag)
1999 return;
fb459a62 2000
1136f72d
PR
2001 entry->text_start_address = text_size;
2002 /* If there were any vectors, we need to chop them off */
2003 text_size += entry->header.a_text;
2004 entry->data_start_address = data_size;
2005 data_size += entry->header.a_data;
2006 entry->bss_start_address = bss_size;
2007 bss_size += entry->header.a_bss;
fb459a62 2008
1136f72d
PR
2009 text_reloc_size += entry->header.a_trsize;
2010 data_reloc_size += entry->header.a_drsize;
fb459a62
NW
2011}
2012
1136f72d
PR
2013/*
2014 * Determine where the sections of ENTRY go into the output file,
2015 * whose total section sizes are already known.
27b6ced7
JH
2016 * Also relocate the addresses of the file's local and debugger symbols
2017 * and determine which of the local symbols will make it into the
2018 * output symbol table.
1136f72d 2019 */
0f052032 2020static void
1136f72d
PR
2021relocate_file_addresses (entry)
2022 register struct file_entry *entry;
fb459a62 2023{
27b6ced7 2024 register struct localsymbol *lsp, *lspend;
1136f72d
PR
2025
2026 entry->text_start_address += text_start;
2027 /*
2028 * Note that `data_start' and `data_size' have not yet been
2029 * adjusted for `data_pad'. If they had been, we would get the wrong
2030 * results here.
2031 */
2032 entry->data_start_address += data_start;
2033 entry->bss_start_address += bss_start;
2034#ifdef DEBUG
2035printf("%s: datastart: %#x, bss %#x\n", get_file_name(entry),
2036 entry->data_start_address, entry->bss_start_address);
2037#endif
fb459a62 2038
1136f72d
PR
2039 lspend = entry->symbols + entry->nsymbols;
2040
2041 for (lsp = entry->symbols; lsp < lspend; lsp++) {
2042 register struct nlist *p = &lsp->nzlist.nlist;
27b6ced7
JH
2043 register int type = p->n_type;
2044
1136f72d
PR
2045 /*
2046 * If this belongs to a section, update it
2047 * by the section's start address
2048 */
1136f72d 2049
27b6ced7 2050 switch (type & N_TYPE) {
1136f72d
PR
2051 case N_TEXT:
2052 case N_SETT:
2053 p->n_value += entry->text_start_address;
2054 break;
2055 case N_DATA:
2056 case N_SETD:
2057 case N_SETV:
2058 /*
2059 * A symbol whose value is in the data section is
2060 * present in the input file as if the data section
2061 * started at an address equal to the length of the
2062 * file's text.
2063 */
2064 p->n_value += entry->data_start_address -
2065 entry->header.a_text;
2066 break;
2067 case N_BSS:
2068 case N_SETB:
2069 /* likewise for symbols with value in BSS. */
2070 p->n_value += entry->bss_start_address
2071 - entry->header.a_text - entry->header.a_data;
2072 break;
2073 }
27b6ced7
JH
2074
2075 /*
2076 * See if this symbol should be in the output symbol table.
2077 */
2078
2079 if (type == N_WARNING)
2080 continue;
2081
2082 if (SET_ELEMENT_P (type)) {
2083 /*
2084 * This occurs even if global. These types of
2085 * symbols are never written globally, though
2086 * they are stored globally.
2087 */
2088 lsp->write = relocatable_output;
2089
2090 } else if (!(type & (N_STAB | N_EXT))) {
2091
2092 /*
2093 * Ordinary local symbol
2094 */
2095 lsp->write = (lsp->rename || (
2096 discard_locals != DISCARD_ALL &&
2097 !(discard_locals == DISCARD_L &&
2098 lsp->is_L_symbol)));
2099 if (lsp->write)
2100 local_sym_count++;
2101
2102 } else if (!(type & N_EXT)) {
2103
2104 /*
2105 * Debugger symbol
2106 */
2107 lsp->write = (strip_symbols == STRIP_NONE);
2108 if (lsp->write)
2109 debugger_sym_count++;
2110
2111 }
fb459a62 2112 }
27b6ced7
JH
2113
2114 /*
2115 * Count one for the local symbol that we generate,
2116 * whose name is the file's name (usually) and whose address
2117 * is the start of the file's text.
2118 */
2119 if (discard_locals != DISCARD_ALL)
2120 local_sym_count++;
2121
fb459a62
NW
2122}
2123\f
2124/* Write the output file */
2125
2126void
2127write_output ()
2128{
1136f72d
PR
2129 struct stat statbuf;
2130 int filemode;
2131
2132 if (lstat(output_filename, &statbuf) != -1) {
2133 if (!S_ISDIR(statbuf.st_mode))
2134 (void)unlink(output_filename);
2135 }
fb459a62 2136
1136f72d
PR
2137 outdesc = open (output_filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
2138 if (outdesc < 0)
2139 perror_name (output_filename);
fb459a62 2140
1136f72d
PR
2141 if (fstat (outdesc, &statbuf) < 0)
2142 perror_name (output_filename);
fb459a62 2143
1136f72d 2144 filemode = statbuf.st_mode;
fb459a62 2145
1136f72d 2146 chmod (output_filename, filemode & ~0111);
fb459a62 2147
1136f72d
PR
2148 /* Output the a.out header. */
2149 write_header ();
fb459a62 2150
1136f72d
PR
2151 /* Output the text and data segments, relocating as we go. */
2152 write_text ();
2153 write_data ();
fb459a62 2154
1136f72d
PR
2155 /* Output the merged relocation info, if requested with `-r'. */
2156 if (relocatable_output)
2157 write_rel ();
fb459a62 2158
1136f72d
PR
2159 /* Output the symbol table (both globals and locals). */
2160 write_syms ();
fb459a62 2161
1136f72d
PR
2162 /* Output the RSS section */
2163 write_rrs ();
fb459a62 2164
1136f72d 2165 close (outdesc);
fb459a62 2166
1136f72d
PR
2167 if (chmod (output_filename, filemode | 0111) == -1)
2168 perror_name (output_filename);
fb459a62 2169}
fb459a62 2170
1136f72d 2171/* Total number of symbols to be written in the output file. */
0f052032 2172static int nsyms;
1136f72d 2173
fb459a62
NW
2174void
2175write_header ()
2176{
1136f72d
PR
2177 int flags = (rrs_section_type == RRS_FULL) ? EX_DYNAMIC : 0;
2178
5e358090 2179 if (netzmagic || magic == QMAGIC || (link_mode & DYNAMIC))
0f052032
JH
2180 N_SET_FLAG (outheader, flags);
2181
1136f72d
PR
2182 outheader.a_text = text_size;
2183 outheader.a_data = data_size;
2184 outheader.a_bss = bss_size;
2185 outheader.a_entry = (entry_symbol ? entry_symbol->value
2186 : text_start + entry_offset);
2187
2188 if (strip_symbols == STRIP_ALL)
2189 nsyms = 0;
27b6ced7
JH
2190 else
2191 nsyms = global_sym_count + local_sym_count + debugger_sym_count;
fb459a62 2192
27b6ced7
JH
2193 if (relocatable_output)
2194 nsyms += set_symbol_count;
fb459a62 2195
1136f72d
PR
2196 outheader.a_syms = nsyms * sizeof (struct nlist);
2197
2198 if (relocatable_output) {
2199 outheader.a_trsize = text_reloc_size;
2200 outheader.a_drsize = data_reloc_size;
2201 } else {
2202 outheader.a_trsize = 0;
2203 outheader.a_drsize = 0;
2204 }
2205
2206 md_swapout_exec_hdr(&outheader);
2207 mywrite (&outheader, sizeof (struct exec), 1, outdesc);
2208 md_swapin_exec_hdr(&outheader);
2209
2210 /*
2211 * Output whatever padding is required in the executable file
2212 * between the header and the start of the text.
2213 */
fb459a62
NW
2214
2215#ifndef COFF_ENCAPSULATE
1136f72d 2216 padfile (N_TXTOFF(outheader) - sizeof outheader, outdesc);
fb459a62
NW
2217#endif
2218}
2219\f
2220/* Relocate the text segment of each input file
2221 and write to the output file. */
2222
2223void
2224write_text ()
2225{
fb459a62 2226
1136f72d
PR
2227 if (trace_files)
2228 fprintf (stderr, "Copying and relocating text:\n\n");
fb459a62 2229
1136f72d
PR
2230 each_full_file (copy_text, 0);
2231 file_close ();
fb459a62 2232
1136f72d
PR
2233 if (trace_files)
2234 fprintf (stderr, "\n");
fb459a62 2235
1136f72d 2236 padfile (text_pad, outdesc);
fb459a62
NW
2237}
2238
1136f72d
PR
2239/*
2240 * Read the text segment contents of ENTRY, relocate them, and write the
2241 * result to the output file. If `-r', save the text relocation for later
2242 * reuse.
2243 */
fb459a62
NW
2244void
2245copy_text (entry)
2246 struct file_entry *entry;
2247{
1136f72d
PR
2248 register char *bytes;
2249 register int desc;
fb459a62 2250
1136f72d
PR
2251 if (trace_files)
2252 prline_file_name (entry, stderr);
fb459a62 2253
1136f72d 2254 desc = file_open (entry);
fb459a62 2255
1136f72d
PR
2256 /* Allocate space for the file's text section */
2257 bytes = (char *) alloca (entry->header.a_text);
fb459a62 2258
1136f72d
PR
2259 /* Deal with relocation information however is appropriate */
2260 if (entry->textrel == NULL)
2261 fatal_with_file("no text relocation of ", entry);
fb459a62 2262
1136f72d
PR
2263 /* Read the text section into core. */
2264 lseek (desc, text_offset (entry), 0);
2265 if (entry->header.a_text != read (desc, bytes, entry->header.a_text))
2266 fatal_with_file ("premature eof in text section of ", entry);
fb459a62 2267
fb459a62 2268
1136f72d
PR
2269 /* Relocate the text according to the text relocation. */
2270 perform_relocation (bytes, entry->header.a_text,
2271 entry->textrel, entry->ntextrel, entry, 0);
fb459a62 2272
1136f72d
PR
2273 /* Write the relocated text to the output file. */
2274 mywrite (bytes, 1, entry->header.a_text, outdesc);
fb459a62
NW
2275}
2276\f
2277/* Relocate the data segment of each input file
2278 and write to the output file. */
2279
2280void
2281write_data ()
2282{
1136f72d 2283 long pos;
fb459a62 2284
1136f72d
PR
2285 if (trace_files)
2286 fprintf (stderr, "Copying and relocating data:\n\n");
fb459a62 2287
1136f72d
PR
2288 pos = N_DATOFF(outheader) + data_start - rrs_data_start;
2289 if (lseek(outdesc, pos, L_SET) != pos)
2290 fatal("write_data: lseek: cant position data offset");
fb459a62 2291
1136f72d
PR
2292 each_full_file (copy_data, 0);
2293 file_close ();
fb459a62 2294
1136f72d
PR
2295 /*
2296 * Write out the set element vectors. See digest symbols for
2297 * description of length of the set vector section.
2298 */
fb459a62 2299
1136f72d 2300 if (set_vector_count) {
92575836
JH
2301 swap_longs(set_vectors, set_symbol_count + 2*set_vector_count);
2302 mywrite (set_vectors, set_symbol_count + 2*set_vector_count,
1136f72d
PR
2303 sizeof (unsigned long), outdesc);
2304 }
2305
2306 if (trace_files)
2307 fprintf (stderr, "\n");
fb459a62 2308
1136f72d
PR
2309 padfile (data_pad, outdesc);
2310}
fb459a62 2311
1136f72d
PR
2312/*
2313 * Read the data segment contents of ENTRY, relocate them, and write the
2314 * result to the output file. If `-r', save the data relocation for later
2315 * reuse. See comments in `copy_text'.
2316 */
fb459a62
NW
2317void
2318copy_data (entry)
2319 struct file_entry *entry;
2320{
1136f72d
PR
2321 register char *bytes;
2322 register int desc;
fb459a62 2323
1136f72d
PR
2324 if (trace_files)
2325 prline_file_name (entry, stderr);
fb459a62 2326
1136f72d 2327 desc = file_open (entry);
fb459a62 2328
1136f72d 2329 bytes = (char *)alloca(entry->header.a_data);
fb459a62 2330
1136f72d
PR
2331 if (entry->datarel == NULL)
2332 fatal_with_file("no data relocation of ", entry);
fb459a62 2333
1136f72d
PR
2334 lseek (desc, text_offset (entry) + entry->header.a_text, 0);
2335 if (entry->header.a_data != read(desc, bytes, entry->header.a_data))
2336 fatal_with_file ("premature eof in data section of ", entry);
fb459a62 2337
1136f72d
PR
2338 perform_relocation (bytes, entry->header.a_data,
2339 entry->datarel, entry->ndatarel, entry, 1);
fb459a62 2340
1136f72d
PR
2341 mywrite (bytes, 1, entry->header.a_data, outdesc);
2342}
2343\f
2344/*
2345 * Relocate ENTRY's text or data section contents. DATA is the address of the
2346 * contents, in core. DATA_SIZE is the length of the contents. PC_RELOCATION
2347 * is the difference between the address of the contents in the output file
2348 * and its address in the input file. RELOC is the address of the
2349 * relocation info, in core. NRELOC says how many there are.
2350 */
2351void
2352perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
2353 char *data;
2354 int data_size;
2355 struct relocation_info *reloc;
2356 int nreloc;
2357 struct file_entry *entry;
2358 int dataseg;
2359{
2360 register struct relocation_info *r = reloc;
2361 struct relocation_info *end = reloc + nreloc;
2362
2363 text_relocation = entry->text_start_address;
2364 data_relocation = entry->data_start_address - entry->header.a_text;
2365 bss_relocation = entry->bss_start_address -
2366 entry->header.a_text - entry->header.a_data;
2367 pc_relocation = dataseg?
2368 entry->data_start_address - entry->header.a_text:
2369 entry->text_start_address;
2370
2371 for (; r < end; r++) {
2372 int addr = RELOC_ADDRESS(r);
2373 long addend = md_get_addend(r, data+addr);
2374 long relocation;
2375
2376 /*
2377 * Loop over the relocations again as we did in
2378 * consider_relocation(), claiming the reserved RRS
2379 * relocations.
2380 */
2381
2382 if (addr >= data_size)
2383 fatal_with_file(
2384 "relocation address out of range in ", entry);
2385
2386 if (RELOC_JMPTAB_P(r)) {
2387
2388 int symindex = RELOC_SYMBOL(r);
2389 struct localsymbol *lsp = &entry->symbols[symindex];
2390 symbol *sp;
2391
2392 if (symindex >= entry->nsymbols)
2393 fatal_with_file(
2394 "relocation symbolnum out of range in ", entry);
2395
2396 sp = lsp->symbol;
2397 if (sp->alias)
2398 sp = sp->alias;
2399
2400 if (relocatable_output)
2401 relocation = addend;
2402 else if (!RELOC_EXTERN_P(r)) {
2403 relocation = addend +
2404 data_relocation - text_relocation;
2405 } else
2406 relocation = addend +
27b6ced7 2407 claim_rrs_jmpslot(entry, r, sp, addend);
1136f72d
PR
2408
2409 } else if (RELOC_BASEREL_P(r)) {
2410
2411 int symindex = RELOC_SYMBOL(r);
2412 struct localsymbol *lsp = &entry->symbols[symindex];
2413
2414 if (symindex >= entry->nsymbols)
2415 fatal_with_file(
2416 "relocation symbolnum out of range in ", entry);
2417
2418 if (relocatable_output)
2419 relocation = addend;
2420 else if (!RELOC_EXTERN_P(r))
2421 relocation = claim_rrs_internal_gotslot(entry,
2422 r, lsp, addend);
2423 else
27b6ced7
JH
2424 relocation = claim_rrs_gotslot(entry,
2425 r, lsp, addend);
1136f72d
PR
2426
2427 } else if (RELOC_EXTERN_P(r)) {
2428
2429 int symindex = RELOC_SYMBOL(r);
2430 symbol *sp;
2431
2432 if (symindex >= entry->nsymbols)
2433 fatal_with_file(
2434 "relocation symbolnum out of range in ", entry);
2435
2436 sp = entry->symbols[symindex].symbol;
2437 if (sp->alias)
2438 sp = sp->alias;
2439
2440 if (relocatable_output) {
27b6ced7
JH
2441 relocation = addend;
2442 /*
2443 * In PIC code, we keep the reference to the
2444 * external symbol, even if defined now.
2445 */
2446 if (!pic_code_seen)
2447 relocation += sp->value;
1136f72d
PR
2448 } else if (sp->defined) {
2449 if (sp == got_symbol) {
2450 /* Handle _GOT_ refs */
2451 relocation = addend + sp->value
2452 + md_got_reloc(r);
2453 } else if (building_shared_object) {
2454 /*
2455 * Normal (non-PIC) relocation needs
2456 * to be converted into an RRS reloc
2457 * when building a shared object.
2458 */
2459 r->r_address += dataseg?
2460 entry->data_start_address:
2461 entry->text_start_address;
2462 relocation = addend;
27b6ced7
JH
2463 if (claim_rrs_reloc(entry, r,
2464 sp, &relocation))
1136f72d
PR
2465 continue;
2466 } else if (sp->defined == N_SIZE) {
2467 /*
2468 * If size is known, arrange a
2469 * run-time copy.
2470 */
2471 if (!sp->size)
2472 fatal("Copy item isn't: %s",
2473 sp->name);
2474
2475 relocation = addend + sp->value;
2476 r->r_address = sp->value;
27b6ced7 2477 claim_rrs_cpy_reloc(entry, r, sp);
1136f72d
PR
2478 } else
2479 /* Plain old relocation */
2480 relocation = addend + sp->value;
2481 } else {
2482 /*
2483 * If the symbol is undefined, we relocate it
2484 * in a way similar to -r case. We use an
2485 * RRS relocation to resolve the symbol at
2486 * run-time. The r_address field is updated
2487 * to reflect the changed position in the
2488 * output file.
2489 *
2490 * In case the symbol is defined in a shared
2491 * object as N_TEXT or N_DATA, an appropriate
2492 * jmpslot or copy relocation is generated.
2493 */
2494 switch (sp->so_defined) {
2495
2496 case N_TEXT+N_EXT:
2497 /*
2498 * Claim a jmpslot if one was
2499 * allocated (dependent on
2500 * `force_alias_flag').
2501 */
2502
2503 if (sp->jmpslot_offset == -1)
2504 goto undefined;
2505
2506 relocation = addend +
27b6ced7
JH
2507 claim_rrs_jmpslot(entry, r,
2508 sp, addend);
1136f72d
PR
2509 break;
2510
2511 case N_DATA+N_EXT:
2512 /*FALLTHROUGH*/
2513 case 0:
2514 undefined:
2515 r->r_address += dataseg?
2516 entry->data_start_address:
2517 entry->text_start_address;
2518 relocation = addend;
27b6ced7
JH
2519 if (claim_rrs_reloc(entry, r,
2520 sp, &relocation))
1136f72d
PR
2521 continue;
2522 break;
2523
2524 case N_BSS+N_EXT:
2525printf("%s: BSS found in so_defined\n", sp->name);
2526 /*break;*/
2527
2528 default:
2529 fatal("%s: shobj symbol with unknown type %#x", sp->name, sp->so_defined);
2530 break;
2531 }
2532 }
2533
2534 } else {
2535
2536 switch (RELOC_TYPE(r)) {
2537 case N_TEXT:
2538 case N_TEXT | N_EXT:
2539 relocation = addend + text_relocation;
2540 break;
2541
2542 case N_DATA:
2543 case N_DATA | N_EXT:
2544 /*
2545 * A word that points to beginning of the the
2546 * data section initially contains not 0 but
2547 * rather the "address" of that section in
2548 * the input file, which is the length of the
2549 * file's text.
2550 */
2551 relocation = addend + data_relocation;
2552 break;
2553
2554 case N_BSS:
2555 case N_BSS | N_EXT:
2556 /*
2557 * Similarly, an input word pointing to the
2558 * beginning of the bss initially contains
2559 * the length of text plus data of the file.
2560 */
2561 relocation = addend + bss_relocation;
2562 break;
2563
2564 case N_ABS:
2565 case N_ABS | N_EXT:
2566 /*
2567 * Don't know why this code would occur, but
2568 * apparently it does.
2569 */
2570 break;
2571
2572 default:
2573 fatal_with_file(
2574 "nonexternal relocation code invalid in ", entry);
2575 }
2576
2577 /*
2578 * When building a shared object, these segment
2579 * relocations need a "load address relative"
2580 * RRS fixup.
2581 */
2582 if (building_shared_object) {
2583 r->r_address += dataseg?
2584 entry->data_start_address:
2585 entry->text_start_address;
27b6ced7 2586 claim_rrs_segment_reloc(entry, r);
1136f72d
PR
2587 }
2588 }
fb459a62 2589
1136f72d
PR
2590 if (RELOC_PCREL_P(r))
2591 relocation -= pc_relocation;
fb459a62 2592
1136f72d 2593 md_relocate(r, relocation, data+addr, relocatable_output);
fb459a62 2594
fb459a62 2595 }
fb459a62
NW
2596}
2597\f
0f052032
JH
2598/*
2599 * For relocatable_output only: write out the relocation,
2600 * relocating the addresses-to-be-relocated.
2601 */
fb459a62
NW
2602
2603void
2604write_rel ()
2605{
80f25b52 2606 int count = 0;
1136f72d
PR
2607
2608 if (trace_files)
2609 fprintf (stderr, "Writing text relocation:\n\n");
2610
2611 /*
2612 * Assign each global symbol a sequence number, giving the order
2613 * in which `write_syms' will write it.
2614 * This is so we can store the proper symbolnum fields
2615 * in relocation entries we write.
2616 *
2617
2618 /* BLECH - Assign number 0 to __DYNAMIC (!! Sun compatibility) */
2619
2620 if (dynamic_symbol->referenced)
2621 dynamic_symbol->symbolnum = count++;
2622 FOR_EACH_SYMBOL(i, sp) {
2623 if (sp != dynamic_symbol && sp->referenced) {
2624 sp->symbolnum = count++;
27b6ced7
JH
2625 if (sp->size)
2626 count++;
2627 if (sp->alias)
2628 count++;
1136f72d
PR
2629 }
2630 } END_EACH_SYMBOL;
2631
27b6ced7 2632 if (count != global_sym_count)
1136f72d
PR
2633 fatal ("internal error: write_rel: count = %d", count);
2634
80f25b52
JH
2635 each_full_file (assign_symbolnums, &count);
2636
1136f72d
PR
2637 /* Write out the relocations of all files, remembered from copy_text. */
2638 each_full_file (coptxtrel, 0);
2639
2640 if (trace_files)
2641 fprintf (stderr, "\nWriting data relocation:\n\n");
2642
2643 each_full_file (copdatrel, 0);
2644
2645 if (trace_files)
2646 fprintf (stderr, "\n");
fb459a62
NW
2647}
2648
0f052032 2649
80f25b52
JH
2650/*
2651 * Assign symbol ordinal numbers to local symbols in each entry.
2652 */
0f052032 2653static void
80f25b52
JH
2654assign_symbolnums(entry, countp)
2655 struct file_entry *entry;
2656 int *countp;
2657{
2658 struct localsymbol *lsp, *lspend;
2659 int n = *countp;
2660
2661 lspend = entry->symbols + entry->nsymbols;
2662
27b6ced7
JH
2663 if (discard_locals != DISCARD_ALL)
2664 /* Count the N_FN symbol for this entry */
2665 n++;
2666
80f25b52 2667 for (lsp = entry->symbols; lsp < lspend; lsp++) {
27b6ced7
JH
2668 if (lsp->write)
2669 lsp->symbolnum = n++;
80f25b52
JH
2670 }
2671 *countp = n;
2672}
2673
0f052032 2674static void
1136f72d
PR
2675coptxtrel(entry)
2676 struct file_entry *entry;
fb459a62 2677{
1136f72d
PR
2678 register struct relocation_info *r, *end;
2679 register int reloc = entry->text_start_address;
fb459a62 2680
1136f72d
PR
2681 r = entry->textrel;
2682 end = r + entry->ntextrel;
2683
2684 for (; r < end; r++) {
27b6ced7
JH
2685 register int symindex;
2686 struct localsymbol *lsp;
2687 symbol *sp;
1136f72d
PR
2688
2689 RELOC_ADDRESS(r) += reloc;
2690
1136f72d 2691 symindex = RELOC_SYMBOL(r);
27b6ced7
JH
2692 lsp = &entry->symbols[symindex];
2693
2694 if (!RELOC_EXTERN_P(r)) {
2695 if (!pic_code_seen)
2696 continue;
2697 if (RELOC_BASEREL_P(r))
2698 RELOC_SYMBOL(r) = lsp->symbolnum;
2699 continue;
2700 }
1136f72d
PR
2701
2702 if (symindex >= entry->nsymbols)
2703 fatal_with_file(
2704 "relocation symbolnum out of range in ", entry);
fb459a62 2705
27b6ced7
JH
2706 sp = lsp->symbol;
2707
fb459a62 2708#ifdef N_INDR
1136f72d
PR
2709 /* Resolve indirection. */
2710 if ((sp->defined & ~N_EXT) == N_INDR) {
2711 if (sp->alias == NULL)
2712 fatal("internal error: alias in hyperspace");
2713 sp = sp->alias;
2714 }
fb459a62
NW
2715#endif
2716
1136f72d
PR
2717 /*
2718 * If the symbol is now defined, change the external
2719 * relocation to an internal one.
2720 */
fb459a62 2721
1136f72d 2722 if (sp->defined) {
27b6ced7
JH
2723 if (!pic_code_seen) {
2724 RELOC_EXTERN_P(r) = 0;
2725 RELOC_SYMBOL(r) = (sp->defined & N_TYPE);
2726 } else
2727 RELOC_SYMBOL(r) = sp->symbolnum;
fb459a62 2728#ifdef RELOC_ADD_EXTRA
1136f72d
PR
2729 /*
2730 * If we aren't going to be adding in the
2731 * value in memory on the next pass of the
2732 * loader, then we need to add it in from the
2733 * relocation entry. Otherwise the work we
2734 * did in this pass is lost.
2735 */
2736 if (!RELOC_MEMORY_ADD_P(r))
2737 RELOC_ADD_EXTRA(r) += sp->value;
fb459a62 2738#endif
1136f72d
PR
2739 } else
2740 /*
2741 * Global symbols come first.
2742 */
2743 RELOC_SYMBOL(r) = sp->symbolnum;
fb459a62 2744 }
1136f72d
PR
2745 md_swapout_reloc(entry->textrel, entry->ntextrel);
2746 mywrite(entry->textrel, entry->ntextrel,
2747 sizeof(struct relocation_info), outdesc);
fb459a62
NW
2748}
2749
0f052032 2750static void
1136f72d
PR
2751copdatrel(entry)
2752 struct file_entry *entry;
fb459a62 2753{
1136f72d
PR
2754 register struct relocation_info *r, *end;
2755 /*
2756 * Relocate the address of the relocation. Old address is relative to
2757 * start of the input file's data section. New address is relative to
2758 * start of the output file's data section.
2759 */
2760 register int reloc = entry->data_start_address - text_size;
fb459a62 2761
1136f72d
PR
2762 r = entry->datarel;
2763 end = r + entry->ndatarel;
2764
2765 for (; r < end; r++) {
2766 register int symindex;
2767 symbol *sp;
2768 int symtype;
2769
2770 RELOC_ADDRESS(r) += reloc;
2771
27b6ced7
JH
2772 if (!RELOC_EXTERN_P(r)) {
2773 if (RELOC_BASEREL_P(r))
2774 fatal_with_file(
2775 "Unsupported relocation type in ",
2776 entry);
1136f72d 2777 continue;
27b6ced7 2778 }
1136f72d
PR
2779
2780 symindex = RELOC_SYMBOL(r);
2781 sp = entry->symbols[symindex].symbol;
2782
2783 if (symindex >= entry->header.a_syms)
2784 fatal_with_file(
2785 "relocation symbolnum out of range in ", entry);
fb459a62
NW
2786
2787#ifdef N_INDR
1136f72d
PR
2788 /* Resolve indirection. */
2789 if ((sp->defined & ~N_EXT) == N_INDR) {
2790 if (sp->alias == NULL)
2791 fatal("internal error: alias in hyperspace");
2792 sp = sp->alias;
2793 }
fb459a62
NW
2794#endif
2795
1136f72d
PR
2796 symtype = sp->defined & N_TYPE;
2797
27b6ced7 2798 if (!pic_code_seen && (force_common_definition ||
1136f72d
PR
2799 symtype == N_DATA ||
2800 symtype == N_TEXT ||
27b6ced7 2801 symtype == N_ABS)) {
1136f72d
PR
2802 RELOC_EXTERN_P(r) = 0;
2803 RELOC_SYMBOL(r) = symtype;
2804 } else
2805 /*
2806 * Global symbols come first.
2807 */
2808 RELOC_SYMBOL(r) =
2809 entry->symbols[symindex].symbol->symbolnum;
fb459a62 2810 }
1136f72d
PR
2811 md_swapout_reloc(entry->datarel, entry->ndatarel);
2812 mywrite(entry->datarel, entry->ndatarel,
2813 sizeof(struct relocation_info), outdesc);
fb459a62
NW
2814}
2815\f
27b6ced7
JH
2816void write_file_syms __P((struct file_entry *, int *));
2817void write_string_table __P((void));
fb459a62
NW
2818
2819/* Offsets and current lengths of symbol and string tables in output file. */
2820
0f052032
JH
2821static int symbol_table_offset;
2822static int symbol_table_len;
fb459a62
NW
2823
2824/* Address in output file where string table starts. */
0f052032 2825static int string_table_offset;
fb459a62
NW
2826
2827/* Offset within string table
2828 where the strings in `strtab_vector' should be written. */
0f052032 2829static int string_table_len;
fb459a62
NW
2830
2831/* Total size of string table strings allocated so far,
2832 including strings in `strtab_vector'. */
0f052032 2833static int strtab_size;
fb459a62
NW
2834
2835/* Vector whose elements are strings to be added to the string table. */
0f052032 2836static char **strtab_vector;
fb459a62
NW
2837
2838/* Vector whose elements are the lengths of those strings. */
0f052032 2839static int *strtab_lens;
fb459a62
NW
2840
2841/* Index in `strtab_vector' at which the next string will be stored. */
0f052032 2842static int strtab_index;
fb459a62 2843
1136f72d
PR
2844/*
2845 * Add the string NAME to the output file string table. Record it in
2846 * `strtab_vector' to be output later. Return the index within the string
2847 * table that this string will have.
2848 */
fb459a62 2849
0f052032 2850static int
1136f72d
PR
2851assign_string_table_index(name)
2852 char *name;
fb459a62 2853{
1136f72d
PR
2854 register int index = strtab_size;
2855 register int len = strlen(name) + 1;
fb459a62 2856
1136f72d
PR
2857 strtab_size += len;
2858 strtab_vector[strtab_index] = name;
2859 strtab_lens[strtab_index++] = len;
fb459a62 2860
1136f72d 2861 return index;
fb459a62
NW
2862}
2863
1136f72d 2864FILE *outstream = (FILE *) 0;
fb459a62 2865
1136f72d
PR
2866/*
2867 * Write the contents of `strtab_vector' into the string table. This is done
2868 * once for each file's local&debugger symbols and once for the global
2869 * symbols.
2870 */
fb459a62
NW
2871void
2872write_string_table ()
2873{
1136f72d 2874 register int i;
fb459a62 2875
1136f72d 2876 lseek (outdesc, string_table_offset + string_table_len, 0);
fb459a62 2877
1136f72d
PR
2878 if (!outstream)
2879 outstream = fdopen (outdesc, "w");
fb459a62 2880
1136f72d
PR
2881 for (i = 0; i < strtab_index; i++) {
2882 fwrite (strtab_vector[i], 1, strtab_lens[i], outstream);
2883 string_table_len += strtab_lens[i];
2884 }
fb459a62 2885
1136f72d 2886 fflush (outstream);
fb459a62 2887
1136f72d
PR
2888 /* Report I/O error such as disk full. */
2889 if (ferror (outstream))
2890 perror_name (output_filename);
fb459a62
NW
2891}
2892\f
2893/* Write the symbol table and string table of the output file. */
2894
2895void
1136f72d
PR
2896write_syms()
2897{
2898 /* Number of symbols written so far. */
1136f72d
PR
2899 int syms_written = 0;
2900 struct nlist nl;
2901
2902 /*
2903 * Buffer big enough for all the global symbols. One extra struct
2904 * for each indirect symbol to hold the extra reference following.
2905 */
27b6ced7
JH
2906 struct nlist *buf = (struct nlist *)
2907 alloca(global_sym_count * sizeof(struct nlist));
1136f72d
PR
2908 /* Pointer for storing into BUF. */
2909 register struct nlist *bufp = buf;
2910
2911 /* Size of string table includes the bytes that store the size. */
2912 strtab_size = sizeof strtab_size;
2913
2914 symbol_table_offset = N_SYMOFF(outheader);
2915 symbol_table_len = 0;
2916 string_table_offset = N_STROFF(outheader);
2917 string_table_len = strtab_size;
2918
2919 if (strip_symbols == STRIP_ALL)
2920 return;
2921
2922 /* First, write out the global symbols. */
2923
2924 /*
2925 * Allocate two vectors that record the data to generate the string
2926 * table from the global symbols written so far. This must include
2927 * extra space for the references following indirect outputs.
2928 */
2929
27b6ced7
JH
2930 strtab_vector = (char **) alloca((global_sym_count) * sizeof(char *));
2931 strtab_lens = (int *) alloca((global_sym_count) * sizeof(int));
1136f72d
PR
2932 strtab_index = 0;
2933
2934 /*
2935 * __DYNAMIC symbol *must* be first for Sun compatibility, as Sun's
2936 * ld.so reads the shared object's first symbol. This means that
2937 * (Sun's) shared libraries cannot be stripped! (We only assume
2938 * that __DYNAMIC is the first item in the data segment)
2939 *
2940 * If defined (ie. not relocatable_output), make it look
2941 * like an internal symbol.
2942 */
2943 if (dynamic_symbol->referenced) {
2944 nl.n_other = 0;
2945 nl.n_desc = 0;
2946 nl.n_type = dynamic_symbol->defined;
2947 if (nl.n_type == N_UNDF)
2948 nl.n_type |= N_EXT;
fb459a62 2949 else
1136f72d
PR
2950 nl.n_type &= ~N_EXT;
2951 nl.n_value = dynamic_symbol->value;
2952 nl.n_un.n_strx = assign_string_table_index(dynamic_symbol->name);
2953 *bufp++ = nl;
fb459a62 2954 syms_written++;
fb459a62 2955 }
fb459a62 2956
1136f72d
PR
2957 /* Scan the symbol hash table, bucket by bucket. */
2958
2959 FOR_EACH_SYMBOL(i, sp) {
0f052032 2960
1136f72d
PR
2961 if (sp == dynamic_symbol)
2962 /* Already dealt with above */
2963 continue;
2964
2965 if (!sp->referenced)
2966 /* Came from shared object but was not used */
2967 continue;
2968
0f052032 2969 if (sp->so_defined || (sp->alias && sp->alias->so_defined))
1136f72d
PR
2970 /*
2971 * Definition came from shared object,
2972 * don't mention it here
2973 */
2974 continue;
2975
2976 if (!sp->defined && !relocatable_output) {
2977 /*
2978 * We're building a shared object and there
2979 * are still undefined symbols. Don't output
2980 * these, symbol was discounted in digest_pass1()
2981 * (they are in the RRS symbol table).
2982 */
2983 if (!building_shared_object)
2984 error("symbol %s remains undefined", sp->name);
2985 continue;
2986 }
fb459a62 2987
0f052032
JH
2988 if (syms_written >= global_sym_count)
2989 fatal(
2990 "internal error: number of symbols exceeds alloc'd %d",
2991 global_sym_count);
1136f72d 2992
0f052032
JH
2993 /*
2994 * Construct a `struct nlist' for the symbol.
2995 */
1136f72d
PR
2996 nl.n_other = 0;
2997 nl.n_desc = 0;
2998
1136f72d 2999 if (sp->defined > 1) {
0f052032
JH
3000 /*
3001 * defined with known type
3002 */
3003 if (!relocatable_output && !building_shared_object &&
3004 sp->alias && sp->alias->defined > 1) {
1136f72d
PR
3005 /*
3006 * If the target of an indirect symbol has
3007 * been defined and we are outputting an
3008 * executable, resolve the indirection; it's
0f052032 3009 * no longer needed.
1136f72d
PR
3010 */
3011 nl.n_type = sp->alias->defined;
0f052032
JH
3012 nl.n_value = sp->alias->value;
3013 } else {
3014 if (sp->defined == N_SIZE)
3015 nl.n_type = N_DATA | N_EXT;
3016 else
3017 nl.n_type = sp->defined;
3018 if (nl.n_type == (N_INDR|N_EXT) &&
3019 sp->value != 0)
3020 fatal("%s: N_INDR has value %#x",
3021 sp->name, sp->value);
3022 nl.n_value = sp->value;
3023 }
3024
1136f72d
PR
3025 } else if (sp->max_common_size) {
3026 /*
3027 * defined as common but not allocated,
3028 * happens only with -r and not -d, write out
0f052032
JH
3029 * a common definition.
3030 *
3031 * common condition needs to be before undefined
3032 * condition because unallocated commons are set
3033 * undefined in digest_symbols.
1136f72d
PR
3034 */
3035 nl.n_type = N_UNDF | N_EXT;
3036 nl.n_value = sp->max_common_size;
3037 } else if (!sp->defined) {
3038 /* undefined -- legit only if -r */
3039 nl.n_type = N_UNDF | N_EXT;
3040 nl.n_value = 0;
3041 } else
3042 fatal(
3043 "internal error: %s defined in mysterious way",
3044 sp->name);
3045
3046 /*
3047 * Allocate string table space for the symbol name.
3048 */
3049
3050 nl.n_un.n_strx = assign_string_table_index(sp->name);
3051
3052 /* Output to the buffer and count it. */
3053
1136f72d
PR
3054 *bufp++ = nl;
3055 syms_written++;
fb459a62 3056
1136f72d
PR
3057 if (nl.n_type == N_INDR + N_EXT) {
3058 if (sp->alias == NULL)
3059 fatal("internal error: alias in hyperspace");
3060 nl.n_type = N_UNDF + N_EXT;
3061 nl.n_un.n_strx =
3062 assign_string_table_index(sp->alias->name);
3063 nl.n_value = 0;
27b6ced7
JH
3064 nl.n_other = 0;
3065 nl.n_desc = 0;
3066 *bufp++ = nl;
3067 syms_written++;
3068 }
3069
3070 if (relocatable_output && sp->size) {
3071 nl.n_type = N_SIZE + N_EXT;
3072 nl.n_un.n_strx = assign_string_table_index(sp->name);
3073 nl.n_value = sp->size;
3074 nl.n_other = 0;
3075 nl.n_desc = 0;
1136f72d
PR
3076 *bufp++ = nl;
3077 syms_written++;
3078 }
fb459a62 3079
1136f72d
PR
3080#ifdef DEBUG
3081printf("writesym(#%d): %s, type %x\n", syms_written, sp->name, sp->defined);
fb459a62 3082#endif
1136f72d 3083 } END_EACH_SYMBOL;
fb459a62 3084
27b6ced7 3085 if (syms_written != strtab_index || strtab_index != global_sym_count)
1136f72d
PR
3086 fatal("internal error:\
3087wrong number (%d) of global symbols written into output file, should be %d",
27b6ced7 3088 syms_written, global_sym_count);
fb459a62 3089
1136f72d 3090 /* Output the buffer full of `struct nlist's. */
fb459a62 3091
1136f72d
PR
3092 lseek(outdesc, symbol_table_offset + symbol_table_len, 0);
3093 md_swapout_symbols(buf, bufp - buf);
3094 mywrite(buf, bufp - buf, sizeof(struct nlist), outdesc);
3095 symbol_table_len += sizeof(struct nlist) * (bufp - buf);
fb459a62 3096
1136f72d
PR
3097 /* Write the strings for the global symbols. */
3098 write_string_table();
fb459a62 3099
1136f72d
PR
3100 /* Write the local symbols defined by the various files. */
3101 each_file(write_file_syms, &syms_written);
3102 file_close();
fb459a62 3103
1136f72d
PR
3104 if (syms_written != nsyms)
3105 fatal("internal error:\
3106wrong number of symbols (%d) written into output file, should be %d",
3107 syms_written, nsyms);
fb459a62 3108
1136f72d
PR
3109 if (symbol_table_offset + symbol_table_len != string_table_offset)
3110 fatal(
3111 "internal error: inconsistent symbol table length: %d vs %s",
3112 symbol_table_offset + symbol_table_len, string_table_offset);
fb459a62 3113
1136f72d
PR
3114 lseek(outdesc, string_table_offset, 0);
3115 strtab_size = md_swap_long(strtab_size);
3116 mywrite(&strtab_size, sizeof(int), 1, outdesc);
fb459a62
NW
3117}
3118
fb459a62 3119
1136f72d
PR
3120/*
3121 * Write the local and debugger symbols of file ENTRY. Increment
3122 * *SYMS_WRITTEN_ADDR for each symbol that is written.
3123 */
fb459a62 3124
1136f72d
PR
3125/*
3126 * Note that we do not combine identical names of local symbols. dbx or gdb
3127 * would be confused if we did that.
3128 */
fb459a62 3129void
1136f72d
PR
3130write_file_syms(entry, syms_written_addr)
3131 struct file_entry *entry;
3132 int *syms_written_addr;
fb459a62 3133{
1136f72d 3134 struct localsymbol *lsp, *lspend;
fb459a62 3135
1136f72d
PR
3136 /* Upper bound on number of syms to be written here. */
3137 int max_syms = entry->nsymbols + 1;
fb459a62 3138
1136f72d
PR
3139 /*
3140 * Buffer to accumulate all the syms before writing them. It has one
3141 * extra slot for the local symbol we generate here.
3142 */
3143 struct nlist *buf = (struct nlist *)
3144 alloca(max_syms * sizeof(struct nlist));
fb459a62 3145
1136f72d 3146 register struct nlist *bufp = buf;
fb459a62 3147
1136f72d
PR
3148 if (entry->is_dynamic)
3149 return;
fb459a62 3150
1136f72d
PR
3151 /*
3152 * Make tables that record, for each symbol, its name and its name's
3153 * length. The elements are filled in by `assign_string_table_index'.
3154 */
fb459a62 3155
1136f72d
PR
3156 strtab_vector = (char **) alloca(max_syms * sizeof(char *));
3157 strtab_lens = (int *) alloca(max_syms * sizeof(int));
3158 strtab_index = 0;
fb459a62 3159
1136f72d 3160 /* Generate a local symbol for the start of this file's text. */
fb459a62 3161
1136f72d
PR
3162 if (discard_locals != DISCARD_ALL) {
3163 struct nlist nl;
fb459a62 3164
1136f72d
PR
3165 nl.n_type = N_FN | N_EXT;
3166 nl.n_un.n_strx = assign_string_table_index(entry->local_sym_name);
3167 nl.n_value = entry->text_start_address;
3168 nl.n_desc = 0;
3169 nl.n_other = 0;
3170 *bufp++ = nl;
3171 (*syms_written_addr)++;
27b6ced7 3172#if 0
1136f72d 3173 entry->local_syms_offset = *syms_written_addr * sizeof(struct nlist);
27b6ced7 3174#endif
1136f72d
PR
3175 }
3176 /* Read the file's string table. */
3177
3178 entry->strings = (char *) alloca(entry->string_size);
3179 read_entry_strings(file_open(entry), entry);
3180
3181 lspend = entry->symbols + entry->nsymbols;
3182
3183 for (lsp = entry->symbols; lsp < lspend; lsp++) {
3184 register struct nlist *p = &lsp->nzlist.nlist;
3185 register int type = p->n_type;
3186 register int write = 0;
80f25b52
JH
3187 char *name;
3188
27b6ced7
JH
3189 if (! lsp->write)
3190 continue;
3191
80f25b52
JH
3192 if (p->n_un.n_strx == 0)
3193 name = NULL;
3194 else if (lsp->rename == 0)
3195 name = p->n_un.n_strx + entry->strings;
3196 else {
3197 char *cp = p->n_un.n_strx + entry->strings;
3198 name = (char *)alloca(
3199 strlen(entry->local_sym_name) +
3200 strlen(cp) + 2 );
3201 (void)sprintf(name, "%s.%s", entry->local_sym_name, cp);
80f25b52 3202 }
1136f72d
PR
3203
3204 /*
27b6ced7
JH
3205 * If this symbol has a name, allocate space for it
3206 * in the output string table.
1136f72d 3207 */
1136f72d 3208
27b6ced7
JH
3209 if (name)
3210 p->n_un.n_strx = assign_string_table_index(name);
1136f72d 3211
27b6ced7 3212 /* Output this symbol to the buffer and count it. */
1136f72d 3213
27b6ced7
JH
3214 *bufp++ = *p;
3215 (*syms_written_addr)++;
1136f72d 3216 }
fb459a62 3217
1136f72d 3218 /* All the symbols are now in BUF; write them. */
fb459a62 3219
1136f72d
PR
3220 lseek(outdesc, symbol_table_offset + symbol_table_len, 0);
3221 md_swapout_symbols(buf, bufp - buf);
3222 mywrite(buf, bufp - buf, sizeof(struct nlist), outdesc);
3223 symbol_table_len += sizeof(struct nlist) * (bufp - buf);
fb459a62 3224
1136f72d
PR
3225 /*
3226 * Write the string-table data for the symbols just written, using
3227 * the data in vectors `strtab_vector' and `strtab_lens'.
3228 */
fb459a62 3229
1136f72d
PR
3230 write_string_table();
3231 entry->strings = 0; /* Since it will disappear anyway. */
fb459a62 3232}