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