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