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