summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/ld/ld.c
diff options
context:
space:
mode:
authorjkh <jkh@FreeBSD.org>1994-02-13 20:43:13 +0000
committerjkh <jkh@FreeBSD.org>1994-02-13 20:43:13 +0000
commit477937c24f744be139c6f05fca05ef839596d8d0 (patch)
tree6947a3f67de9a2d5a7e3753ee49932ec50fa8e59 /gnu/usr.bin/ld/ld.c
parent872e15cb55f29ca2d280bb299f35887b21506b1a (diff)
downloadFreeBSD-src-477937c24f744be139c6f05fca05ef839596d8d0.zip
FreeBSD-src-477937c24f744be139c6f05fca05ef839596d8d0.tar.gz
This is Paul K's latest set of ld changes. A commit was necessary at this
late stage due to the fact that link.h was copyright Sun Microsystems. This version of ld sync's us up with NetBSD's ld and supports compatablily with NetBSD's -[zZ] flags (which we had reversed). Compiling with this new ld will give you RRS warnings for libraries which do not contain .type infomation - these wsarnings are harmless and will go away as soon as you recompile your libraries (cd /usr/src; make libraries).
Diffstat (limited to 'gnu/usr.bin/ld/ld.c')
-rw-r--r--gnu/usr.bin/ld/ld.c903
1 files changed, 547 insertions, 356 deletions
diff --git a/gnu/usr.bin/ld/ld.c b/gnu/usr.bin/ld/ld.c
index ad6f9a6..1d63c82 100644
--- a/gnu/usr.bin/ld/ld.c
+++ b/gnu/usr.bin/ld/ld.c
@@ -32,7 +32,7 @@ static char sccsid[] = "@(#)ld.c 6.10 (Berkeley) 5/22/91";
Set, indirect, and warning symbol features added by Randy Smith. */
/*
- * $Id: ld.c,v 1.18 1994/01/03 18:35:14 davidg Exp $
+ * $Id: ld.c,v 1.19 1994/01/19 15:00:27 davidg Exp $
*/
/* Define how to initialize system-dependent header fields. */
@@ -55,17 +55,18 @@ static char sccsid[] = "@(#)ld.c 6.10 (Berkeley) 5/22/91";
#include "ld.h"
-#ifndef DEFAULT_SOVERSION
-#define DEFAULT_SOVERSION LD_VERSION_BSD
-#endif
-
-int building_shared_object;
+/* Vector of entries for input files specified by arguments.
+ These are all the input files except for members of specified libraries. */
+struct file_entry *file_table;
+int number_of_files;
-/* 1 => write relocation into output file so can re-input it later. */
+/* 1 => write relocation into output file so can re-input it later. */
int relocatable_output;
-/* Non zero means to create the output executable. */
-/* Cleared by nonfatal errors. */
+/* 1 => building a shared object, set by `-Bshareable'. */
+int building_shared_object;
+
+/* 1 => create the output executable. */
int make_executable;
/* Force the executable to be output, even if there are non-fatal errors */
@@ -81,9 +82,72 @@ int force_alias_definition;
if `relocatable_output'. */
int pic_code_seen;
+/* 1 => segments must be page aligned (ZMAGIC, QMAGIC) */
+int page_align_segments;
+
/* 1 => data segment must be page aligned, even if `-n' or `-N' */
int page_align_data;
+/* Version number to put in __DYNAMIC (set by -V) */
+int soversion;
+
+int text_size; /* total size of text. */
+int text_start; /* start of text */
+int text_pad; /* clear space between text and data */
+int data_size; /* total size of data. */
+int data_start; /* start of data */
+int data_pad; /* part of bss segment as part of data */
+
+int bss_size; /* total size of bss. */
+int bss_start; /* start of bss */
+
+int text_reloc_size; /* total size of text relocation. */
+int data_reloc_size; /* total size of data relocation. */
+
+int rrs_section_type; /* What's in the RRS section */
+int rrs_text_size; /* Size of RRS text additions */
+int rrs_text_start; /* Location of above */
+int rrs_data_size; /* Size of RRS data additions */
+int rrs_data_start; /* Location of above */
+
+/* Specifications of start and length of the area reserved at the end
+ of the data segment for the set vectors. Computed in 'digest_symbols' */
+int set_sect_start; /* start of set element vectors */
+int set_sect_size; /* size of above */
+
+int link_mode; /* Current link mode */
+
+/*
+ * When loading the text and data, we can avoid doing a close
+ * and another open between members of the same library.
+ *
+ * These two variables remember the file that is currently open.
+ * Both are zero if no file is open.
+ *
+ * See `each_file' and `file_close'.
+ */
+struct file_entry *input_file;
+int input_desc;
+
+/* The name of the file to write; "a.out" by default. */
+char *output_filename; /* Output file name. */
+int outdesc; /* Output file descriptor. */
+struct exec outheader; /* Output file header. */
+int magic; /* Output file magic. */
+int oldmagic;
+int relocatable_output; /* `-r'-ed output */
+
+symbol *entry_symbol;
+int entry_offset;
+
+int page_size; /* Size of a page (machine dependent) */
+
+/* Keep a list of any symbols referenced from the command line (so
+ that error messages for these guys can be generated). This list is
+ zero terminated. */
+struct glosym **cmdline_references;
+int cl_refs_allocated;
+
/*
* Which symbols should be stripped (omitted from the output): none, all, or
* debugger symbols.
@@ -100,11 +164,33 @@ enum {
DISCARD_NONE, DISCARD_ALL, DISCARD_L
} discard_locals;
-/* Nonzero means print names of input files as processed. */
-int trace_files;
+int global_sym_count; /* # of nlist entries for global symbols */
+int size_sym_count; /* # of N_SIZE nlist entries for output
+ (relocatable_output only) */
+int local_sym_count; /* # of nlist entries for local symbols. */
+int non_L_local_sym_count; /* # of nlist entries for non-L symbols */
+int debugger_sym_count; /* # of nlist entries for debugger info. */
+int undefined_global_sym_count; /* # of global symbols referenced and
+ not defined. */
+int undefined_shobj_sym_count; /* # of undefined symbols referenced
+ by shared objects */
+int multiple_def_count; /* # of multiply defined symbols. */
+int defined_global_sym_count; /* # of defined global symbols. */
+int common_defined_global_count; /* # of common symbols. */
+
+int special_sym_count; /* # of linker defined symbols. */
+ /* XXX - Currently, only __DYNAMIC and _G_O_T_ go here if required,
+ * perhaps _etext, _edata and _end should go here too.
+ */
+int global_alias_count; /* # of aliased symbols */
+int set_symbol_count; /* # of N_SET* symbols. */
+int set_vector_count; /* # of set vectors in output. */
+int warning_count; /* # of warning symbols encountered. */
-/* Magic number to use for the output file, set by switch. */
-int magic;
+struct string_list_element *set_element_prefixes;
+
+int trace_files; /* print names of input files as processed (`-t'). */
+int write_map; /* write a load map (`-M') */
/*
* `text-start' address is normally this much plus a page boundary.
@@ -137,6 +223,7 @@ int setv_fill_count;
static void decode_option __P((char *, char *));
static void decode_command __P((int, char **));
static int classify_arg __P((char *));
+static void load_symbols __P((void));
static void enter_global_ref __P((struct localsymbol *,
char *, struct file_entry *));
static void digest_symbols __P((void));
@@ -144,6 +231,7 @@ static void digest_pass1 __P((void)), digest_pass2 __P((void));
static void consider_file_section_lengths __P((struct file_entry *));
static void relocate_file_addresses __P((struct file_entry *));
static void consider_relocation __P((struct file_entry *, int));
+static void consider_local_symbols __P((struct file_entry *));
static void perform_relocation __P((char *, int,
struct relocation_info *, int,
struct file_entry *, int));
@@ -151,7 +239,15 @@ static void copy_text __P((struct file_entry *));
static void copy_data __P((struct file_entry *));
static void coptxtrel __P((struct file_entry *));
static void copdatrel __P((struct file_entry *));
+static void write_output __P((void));
+static void write_header __P((void));
+static void write_text __P((void));
+static void write_data __P((void));
+static void write_rel __P((void));
+static void write_syms __P((void));
static void assign_symbolnums __P((struct file_entry *, int *));
+static void myfatal __P((void));
+
int
main(argc, argv)
@@ -189,6 +285,7 @@ main(argc, argv)
data_pad = 0;
text_pad = 0;
+ page_align_segments = 0;
page_align_data = 0;
/* Initialize the data about options. */
@@ -251,6 +348,9 @@ main(argc, argv)
* of system and on the output format selected.
*/
+ if (magic == ZMAGIC || magic == QMAGIC)
+ page_align_segments = 1;
+
md_init_header(&outheader, magic, 0);
text_size = sizeof(struct exec);
@@ -430,15 +530,15 @@ decode_command(argc, argv)
fatal("-A specified before an input file other than the first");
p->filename = string;
p->local_sym_name = string;
- p->just_syms_flag = 1;
+ p->flags |= E_JUST_SYMS;
p++;
}
if (argv[i][1] == 'l') {
p->filename = string;
p->local_sym_name = concat("-l", string, "");
- p->search_dirs_flag = 1;
+ p->flags |= E_SEARCH_DIRS;
if (link_mode & DYNAMIC && !relocatable_output)
- p->search_dynamic_flag = 1;
+ p->flags |= E_SEARCH_DYNAMIC;
p++;
}
i += code - 1;
@@ -446,8 +546,8 @@ decode_command(argc, argv)
/* Now check some option settings for consistency. */
- if ((magic != OMAGIC)
- && (text_start - text_start_alignment) & (page_size - 1))
+ if (page_align_segments
+ && (text_start - text_start_alignment) & (page_size - 1))
fatal("-T argument not multiple of page size, with sharable output");
/* Append the standard search directories to the user-specified ones. */
@@ -456,9 +556,9 @@ decode_command(argc, argv)
void
add_cmdline_ref(sp)
- struct glosym *sp;
+ symbol *sp;
{
- struct glosym **ptr;
+ symbol **ptr;
for (ptr = cmdline_references;
ptr < cmdline_references + cl_refs_allocated && *ptr;
@@ -474,7 +574,7 @@ add_cmdline_ref(sp)
ptr = cmdline_references + diff;
}
*ptr++ = sp;
- *ptr = (struct glosym *) 0;
+ *ptr = (symbol *) 0;
}
int
@@ -505,7 +605,6 @@ static void
decode_option(swt, arg)
register char *swt, *arg;
{
- /* We get Bstatic from gcc on suns. */
if (!strcmp(swt + 1, "Bstatic"))
return;
if (!strcmp(swt + 1, "Bdynamic"))
@@ -558,9 +657,10 @@ decode_option(swt, arg)
case 'e':
entry_symbol = getsym(arg);
- if (!entry_symbol->defined && !entry_symbol->referenced)
+ if (!entry_symbol->defined &&
+ !(entry_symbol->flags & GS_REFERENCED))
undefined_global_sym_count++;
- entry_symbol->referenced = 1;
+ entry_symbol->flags |= GS_REFERENCED;
add_cmdline_ref(entry_symbol);
return;
@@ -579,19 +679,9 @@ decode_option(swt, arg)
magic = OMAGIC;
return;
-#ifdef NMAGIC
case 'n':
magic = NMAGIC;
return;
-#endif
-
- case 'Q':
- magic = QMAGIC;
- return;
- case 'Z':
- magic = ZMAGIC;
- netzmagic = 1;
- return;
case 'o':
output_filename = arg;
@@ -601,6 +691,12 @@ decode_option(swt, arg)
page_align_data = 1;
return;
+#ifdef QMAGIC
+ case 'Q':
+ magic = QMAGIC;
+ return;
+#endif
+
case 'r':
relocatable_output = 1;
magic = OMAGIC;
@@ -628,9 +724,9 @@ decode_option(swt, arg)
{
register symbol *sp = getsym(arg);
- if (!sp->defined && !sp->referenced)
+ if (!sp->defined && !(sp->flags & GS_REFERENCED))
undefined_global_sym_count++;
- sp->referenced = 1;
+ sp->flags |= GS_REFERENCED;
add_cmdline_ref(sp);
}
return;
@@ -652,12 +748,17 @@ decode_option(swt, arg)
case 'y':
{
register symbol *sp = getsym(&swt[2]);
- sp->trace = 1;
+ sp->flags |= GS_TRACE;
}
return;
case 'z':
magic = ZMAGIC;
+ oldmagic = 0;
+ return;
+
+ case 'Z':
+ magic = oldmagic = ZMAGIC;
return;
default:
@@ -686,15 +787,15 @@ each_file(function, arg)
register struct file_entry *entry = &file_table[i];
register struct file_entry *subentry;
- if (entry->scrapped)
+ if (entry->flags & E_SCRAPPED)
continue;
- if (!entry->library_flag)
+ if (!(entry->flags & E_IS_LIBRARY))
(*function) (entry, arg);
subentry = entry->subfiles;
for (; subentry; subentry = subentry->chain) {
- if (subentry->scrapped)
+ if (subentry->flags & E_SCRAPPED)
continue;
(*function) (subentry, arg);
}
@@ -702,15 +803,15 @@ each_file(function, arg)
#ifdef SUN_COMPAT
if (entry->silly_archive) {
- if (!entry->is_dynamic)
+ if (!(entry->flags & E_DYNAMIC))
error("Silly");
- if (!entry->silly_archive->library_flag)
+ if (!(entry->silly_archive->flags & E_IS_LIBRARY))
error("Sillier");
subentry = entry->silly_archive->subfiles;
for (; subentry; subentry = subentry->chain) {
- if (subentry->scrapped)
+ if (subentry->flags & E_SCRAPPED)
continue;
(*function) (subentry, arg);
}
@@ -738,12 +839,12 @@ check_each_file(function, arg)
for (i = 0; i < number_of_files; i++) {
register struct file_entry *entry = &file_table[i];
- if (entry->scrapped)
+ if (entry->flags & E_SCRAPPED)
continue;
- if (entry->library_flag) {
+ if (entry->flags & E_IS_LIBRARY) {
register struct file_entry *subentry = entry->subfiles;
for (; subentry; subentry = subentry->chain) {
- if (subentry->scrapped)
+ if (subentry->flags & E_SCRAPPED)
continue;
if (return_val = (*function) (subentry, arg))
return return_val;
@@ -767,35 +868,35 @@ each_full_file(function, arg)
register struct file_entry *entry = &file_table[i];
register struct file_entry *subentry;
- if (entry->scrapped || entry->just_syms_flag)
+ if (entry->flags & (E_SCRAPPED | E_JUST_SYMS))
continue;
#ifdef SUN_COMPAT
if (entry->silly_archive) {
- if (!entry->is_dynamic)
+ if (!(entry->flags & E_DYNAMIC))
error("Silly");
- if (!entry->silly_archive->library_flag)
+ if (!(entry->silly_archive->flags & E_IS_LIBRARY))
error("Sillier");
subentry = entry->silly_archive->subfiles;
for (; subentry; subentry = subentry->chain) {
- if (subentry->scrapped)
+ if (subentry->flags & E_SCRAPPED)
continue;
(*function) (subentry, arg);
}
}
#endif
- if (entry->is_dynamic)
+ if (entry->flags & E_DYNAMIC)
continue;
- if (!entry->library_flag)
+ if (!(entry->flags & E_IS_LIBRARY))
(*function) (entry, arg);
subentry = entry->subfiles;
for (; subentry; subentry = subentry->chain) {
- if (subentry->scrapped)
+ if (subentry->flags & E_SCRAPPED)
continue;
(*function) (subentry, arg);
}
@@ -824,7 +925,7 @@ file_open (entry)
{
register int desc;
- if (entry->superfile && entry->superfile->library_flag)
+ if (entry->superfile && (entry->superfile->flags & E_IS_LIBRARY))
return file_open (entry->superfile);
if (entry == input_file)
@@ -832,7 +933,7 @@ file_open (entry)
if (input_file) file_close ();
- if (entry->search_dirs_flag) {
+ if (entry->flags & E_SEARCH_DIRS) {
desc = findlib(entry);
} else
desc = open (entry->filename, O_RDONLY, 0);
@@ -853,8 +954,8 @@ text_offset (entry)
{
return entry->starting_offset + N_TXTOFF (entry->header);
}
-
-/* Medium-level input routines for rel files. */
+
+/*---------------------------------------------------------------------------*/
/*
* Read a file's header into the proper place in the file_entry. DESC is the
@@ -865,8 +966,7 @@ read_header (desc, entry)
int desc;
register struct file_entry *entry;
{
- register int len;
- struct exec *loc = (struct exec *) &entry->header;
+ register int len, mid;
if (lseek (desc, entry->starting_offset, L_SET) !=
entry->starting_offset)
@@ -878,10 +978,13 @@ read_header (desc, entry)
md_swapin_exec_hdr(&entry->header);
- if (N_BADMAG (*loc))
+ if (N_BADMAG (entry->header))
fatal_with_file ("bad magic number in ", entry);
- entry->header_read_flag = 1;
+ if (N_BADMID(entry->header))
+ fatal_with_file ("non-native input file ", entry);
+
+ entry->flags |= E_HEADER_VALID;
}
/*
@@ -899,7 +1002,7 @@ read_entry_symbols (desc, entry)
struct nlist *np;
int i;
- if (!entry->header_read_flag)
+ if (!(entry->flags & E_HEADER_VALID))
read_header (desc, entry);
np = (struct nlist *) alloca (entry->header.a_syms);
@@ -921,11 +1024,9 @@ read_entry_symbols (desc, entry)
entry->symbols[i].nzlist.nz_size = 0;
entry->symbols[i].symbol = NULL;
entry->symbols[i].next = NULL;
+ entry->symbols[i].entry = entry;
entry->symbols[i].gotslot_offset = -1;
- entry->symbols[i].gotslot_claimed = 0;
- entry->symbols[i].write = 0;
- entry->symbols[i].is_L_symbol = 0;
- entry->symbols[i].rename = 0;
+ entry->symbols[i].flags = 0;
}
entry->strings_offset = N_STROFF(entry->header) +
@@ -949,7 +1050,7 @@ read_entry_strings (desc, entry)
{
int buffer;
- if (!entry->header_read_flag || !entry->strings_offset)
+ if (!(entry->flags & E_HEADER_VALID) || !entry->strings_offset)
fatal_with_file("internal error: cannot read string table for ",
entry);
@@ -963,14 +1064,6 @@ read_entry_strings (desc, entry)
return;
}
-/* DEAD - Read in all of the relocation information */
-
-void
-read_relocation ()
-{
- each_full_file (read_entry_relocation, 0);
-}
-
/* Read in the relocation sections of ENTRY if necessary */
void
@@ -1026,23 +1119,24 @@ read_entry_relocation (desc, entry)
}
}
-
-/* Read in the symbols of all input files. */
-
+/*---------------------------------------------------------------------------*/
-void
+/*
+ * Read in the symbols of all input files.
+ */
+static void
load_symbols ()
{
register int i;
- if (trace_files) fprintf (stderr, "Loading symbols:\n\n");
+ if (trace_files)
+ fprintf(stderr, "Loading symbols:\n\n");
- for (i = 0; i < number_of_files; i++) {
- register struct file_entry *entry = &file_table[i];
- read_file_symbols (entry);
- }
+ for (i = 0; i < number_of_files; i++)
+ read_file_symbols(&file_table[i]);
- if (trace_files) fprintf (stderr, "\n");
+ if (trace_files)
+ fprintf (stderr, "\n");
}
/*
@@ -1068,18 +1162,18 @@ read_file_symbols (entry)
md_swapin_exec_hdr(&hdr);
if (!N_BADMAG (hdr)) {
- if (N_IS_DYNAMIC(hdr)) {
+ if (N_IS_DYNAMIC(hdr) && !(entry->flags & E_JUST_SYMS)) {
if (relocatable_output) {
fatal_with_file(
"-r and shared objects currently not supported ",
entry);
return;
}
- entry->is_dynamic = 1;
+ entry->flags |= E_DYNAMIC;
if (entry->superfile || rrs_add_shobj(entry))
read_shared_object(desc, entry);
else
- entry->scrapped = 1;
+ entry->flags |= E_SCRAPPED;
} else {
read_entry_symbols (desc, entry);
entry->strings = (char *) alloca (entry->string_size);
@@ -1096,14 +1190,17 @@ read_file_symbols (entry)
strncmp (armag, ARMAG, SARMAG))
fatal_with_file(
"malformed input file (not rel or archive) ", entry);
- entry->library_flag = 1;
+ entry->flags |= E_IS_LIBRARY;
search_library (desc, entry);
}
file_close ();
}
-
-/* Enter the external symbol defs and refs of ENTRY in the hash table. */
+
+
+/*
+ * Enter the external symbol defs and refs of ENTRY in the hash table.
+ */
void
enter_file_symbols (entry)
@@ -1160,7 +1257,7 @@ enter_file_symbols (entry)
p->n_un.n_strx + entry->strings, entry);
} else if (p->n_un.n_strx &&
(p->n_un.n_strx + entry->strings)[0] == LPREFIX)
- lsp->is_L_symbol = 1;
+ lsp->flags |= LS_L_SYMBOL;
}
}
@@ -1190,9 +1287,9 @@ enter_global_ref (lsp, name, entry)
register struct nzlist *nzp = &lsp->nzlist;
register symbol *sp = getsym (name);
register int type = nzp->nz_type;
- int oldref = sp->referenced;
+ int oldref = (sp->flags & GS_REFERENCED);
int olddef = sp->defined;
- int com = sp->defined && sp->max_common_size;
+ int com = sp->defined && sp->common_size;
if (type == (N_INDR | N_EXT)) {
sp->alias = getsym(entry->strings + (lsp + 1)->nzlist.nz_strx);
@@ -1208,7 +1305,7 @@ enter_global_ref (lsp, name, entry)
}
}
- if (entry->is_dynamic) {
+ if (entry->flags & E_DYNAMIC) {
lsp->next = sp->sorefs;
sp->sorefs = lsp;
@@ -1223,11 +1320,17 @@ enter_global_ref (lsp, name, entry)
if (oldref)
undefined_global_sym_count--;
common_defined_global_count++;
- sp->max_common_size = nzp->nz_value;
+ sp->common_size = nzp->nz_value;
sp->defined = N_UNDF | N_EXT;
- } else if (com && sp->max_common_size < nzp->nz_value) {
- sp->max_common_size = nzp->nz_value;
+ } else if (com && sp->common_size < nzp->nz_value) {
+ sp->common_size = nzp->nz_value;
}
+ } else if (type != (N_UNDF | N_EXT) && !oldref) {
+ /*
+ * This is an ex common...
+ */
+ sp->common_size = 0;
+ sp->defined = 0;
}
/*
@@ -1244,10 +1347,10 @@ enter_global_ref (lsp, name, entry)
sp->refs = lsp;
lsp->symbol = sp;
- sp->referenced = 1;
+ sp->flags |= GS_REFERENCED;
if (sp == dynamic_symbol || sp == got_symbol) {
- if (type != (N_UNDF | N_EXT) && !entry->just_syms_flag)
+ if (type != (N_UNDF | N_EXT) && !(entry->flags & E_JUST_SYMS))
fatal("Linker reserved symbol %s defined as type %x ",
name, type);
return;
@@ -1281,33 +1384,38 @@ enter_global_ref (lsp, name, entry)
* First definition and it's common.
*/
common_defined_global_count++;
- sp->max_common_size = nzp->nz_value;
+ sp->common_size = nzp->nz_value;
} else if (com && type != (N_UNDF | N_EXT)) {
/*
* It used to be common and we're defining
* it as something else.
*/
common_defined_global_count--;
- sp->max_common_size = 0;
+ sp->common_size = 0;
} else if (com && type == (N_UNDF | N_EXT)
- && sp->max_common_size < nzp->nz_value)
+ && sp->common_size < nzp->nz_value)
/*
* It used to be common and this is a new common entry
* to which we need to pay attention.
*/
- sp->max_common_size = nzp->nz_value;
+ sp->common_size = nzp->nz_value;
if (SET_ELEMENT_P(type) && (!olddef || com))
set_vector_count++;
- } else if (!oldref)
+ } else if (!oldref && !com)
+ /*
+ * An unreferenced symbol can already be defined
+ * as common by shared objects.
+ */
undefined_global_sym_count++;
- if (sp == end_symbol && entry->just_syms_flag && !T_flag_specified)
+ if (sp == end_symbol && (entry->flags & E_JUST_SYMS) &&
+ !T_flag_specified)
text_start = nzp->nz_value;
- if (sp->trace) {
+ if (sp->flags & GS_TRACE) {
register char *reftype;
switch (type & N_TYPE) {
case N_UNDF:
@@ -1343,7 +1451,7 @@ enter_global_ref (lsp, name, entry)
}
/*
- * This return 0 if the given file entry's symbol table does *not* contain
+ * This returns 0 if the given file entry's symbol table does *not* contain
* the nlist point entry, and it returns the files entry pointer (cast to
* unsigned long) if it does.
*/
@@ -1391,7 +1499,6 @@ contains_symbol (entry, np)
*
*/
-
static void
digest_symbols ()
{
@@ -1419,6 +1526,8 @@ digest_symbols ()
each_full_file(consider_relocation, 0); /* Text */
each_full_file(consider_relocation, 1); /* Data */
+ each_file(consider_local_symbols, 0);
+
/*
* Compute total size of sections.
* RRS data is the first output data section, RRS text is the last
@@ -1437,7 +1546,7 @@ digest_symbols ()
* the padding in the text segment size.
*/
- if (magic == ZMAGIC || magic == QMAGIC || page_align_data) {
+ if (page_align_segments || page_align_data) {
int text_end = text_size + N_TXTOFF(outheader);
text_pad = PALIGN(text_end, page_size) - text_end;
text_size += text_pad;
@@ -1490,7 +1599,7 @@ printf("bssstart = %#x, bsssize = %#x\n",
if (specified_data_size && specified_data_size > data_size)
data_pad = specified_data_size - data_size;
- if (magic == ZMAGIC || magic == QMAGIC)
+ if (page_align_segments)
data_pad = PALIGN(data_pad + data_size, page_size) - data_size;
bss_size -= data_pad;
@@ -1506,10 +1615,10 @@ printf("bssstart = %#x, bsssize = %#x\n",
global_sym_count = defined_global_sym_count +
undefined_global_sym_count;
- if (dynamic_symbol->referenced)
+ if (dynamic_symbol->flags & GS_REFERENCED)
global_sym_count++;
- if (got_symbol->referenced)
+ if (got_symbol->flags & GS_REFERENCED)
global_sym_count++;
if (relocatable_output || building_shared_object)
@@ -1529,12 +1638,15 @@ debug symbols: %d, set_symbols %d\n",
#endif
}
+/*
+ * Determine the definition of each global symbol.
+ */
static void
digest_pass1()
{
/*
- * Now, for each symbol, verify that it is defined globally at most
+ * For each symbol, verify that it is defined globally at most
* once within relocatable files (except when building a shared lib).
* and set the `defined' field if there is a definition.
*
@@ -1546,7 +1658,7 @@ digest_pass1()
struct localsymbol *lsp;
int defs = 0;
- if (!sp->referenced) {
+ if (!(sp->flags & GS_REFERENCED)) {
#if 0
/* Check for undefined symbols in shared objects */
int type;
@@ -1580,7 +1692,7 @@ digest_pass1()
sp->value =
setv_fill_count++ * sizeof(long);
} else if ((sp->defined & N_TYPE) != N_SETV) {
- sp->multiply_defined = 1;
+ sp->mult_defs = 1;
multiple_def_count++;
}
/* Keep count and remember symbol */
@@ -1588,6 +1700,12 @@ digest_pass1()
set_vectors[setv_fill_count++] = (long)p;
if (building_shared_object) {
struct relocation_info reloc;
+
+ /*
+ * Make sure to relocate the contents
+ * of this set vector.
+ */
+ bzero(&reloc, sizeof(reloc));
RELOC_ADDRESS(&reloc) =
setv_fill_count * sizeof(long);
alloc_rrs_segment_reloc(NULL, &reloc);
@@ -1598,12 +1716,14 @@ digest_pass1()
&& (type & N_TYPE) != N_SIZE) {
/* non-common definition */
if (defs++ && sp->value != p->n_value
- && entry_symbol) {
- sp->multiply_defined = 1;
+ && entry_symbol/*XXX*/) {
+ sp->mult_defs = 1;
multiple_def_count++;
}
sp->def_nlist = p;
+ lsp->entry->flags |= E_SYMBOLS_USED;
sp->defined = type;
+ sp->aux = N_AUX(p);
}
}
@@ -1645,15 +1765,17 @@ digest_pass1()
&& (type & N_TYPE) != N_FN) {
/* non-common definition */
sp->def_nlist = p;
+ lsp->entry->flags |= E_SYMBOLS_USED;
sp->so_defined = type;
- if (sp->referenced)
+ sp->aux = N_AUX(p);
+ if (sp->flags & GS_REFERENCED)
undefined_global_sym_count--;
else
- sp->referenced = 1;
+ sp->flags |= GS_REFERENCED;
#ifdef DEBUG
printf("shr: %s gets defined to %x with value %x\n", sp->name, type, sp->value);
#endif
- if (sp->alias && !sp->alias->referenced) {
+ if (sp->alias && !(sp->alias->flags & GS_REFERENCED)) {
sp = sp->alias;
goto again;
}
@@ -1668,159 +1790,10 @@ doesn't match actual (%d)",
set_sect_size/sizeof(long), setv_fill_count);
}
-static void
-digest_pass2()
-{
- /*
- * Assign each symbol its final value.
- * If not -r'ing, allocate common symbols in the BSS section.
- */
-
- FOR_EACH_SYMBOL(i, sp) {
- int size;
- int align = sizeof(int);
-
- if (!sp->referenced)
- continue;
-
- if (sp->alias &&
- (relocatable_output || building_shared_object ||
- (sp->alias->defined && !sp->alias->so_defined)))
- /*
- * The alias points at a defined symbol, so it
- * must itself be counted as one too, in order to
- * compute the correct number of symbol table entries.
- */
- defined_global_sym_count++;
-
- if ((sp->defined & N_TYPE) == N_SETV) {
- /*
- * Set length word at front of vector and zero byte
- * at end. Reverse the vector itself to put it in
- * file order.
- */
- unsigned long i, tmp;
- unsigned long length_word_index =
- sp->value / sizeof(long);
-
- /* Relocate symbol value */
- sp->value += set_sect_start;
-
- set_vectors[length_word_index] = sp->setv_count;
-
- /*
- * Relocate vector to final address.
- */
- for (i = 0; i < sp->setv_count; i++) {
- struct nlist *p = (struct nlist *)
- set_vectors[1+i+length_word_index];
-
- set_vectors[1+i+length_word_index] = p->n_value;
- if (building_shared_object) {
- struct relocation_info reloc;
- RELOC_ADDRESS(&reloc) =
- (1 + i + length_word_index) *
- sizeof(long)
- + set_sect_start;
- RELOC_TYPE(&reloc) =
- (sp->defined & N_TYPE);
- claim_rrs_segment_reloc(NULL, &reloc);
- }
- }
-
- /*
- * Reverse the vector.
- */
- for (i = 1; i < (sp->setv_count - 1)/2 + 1; i++) {
-
- tmp = set_vectors[length_word_index + i];
- set_vectors[length_word_index + i] =
- set_vectors[length_word_index + sp->setv_count + 1 - i];
- set_vectors[length_word_index + sp->setv_count + 1 - i] = tmp;
- }
-
- /* Clear terminating entry */
- set_vectors[length_word_index + sp->setv_count + 1] = 0;
- continue;
- }
-
-
- if (sp->defined && sp->def_nlist &&
- ((sp->defined & ~N_EXT) != N_SETV))
- sp->value = sp->def_nlist->n_value;
-
- if (building_shared_object && !(link_mode & SYMBOLIC))
- /* No common allocation in shared objects */
- continue;
-
- if ((size = sp->max_common_size) != 0) {
- /*
- * It's a common.
- */
- if (sp->defined != (N_UNDF + N_EXT))
- fatal("%s: common isn't", sp->name);
-
- } else if ((size = sp->size) != 0 && sp->defined == N_SIZE) {
- /*
- * It's data from shared object with size info.
- */
- if (!sp->so_defined)
- fatal("%s: Bogus N_SIZE item", sp->name);
-
- } else
- /*
- * It's neither
- */
- continue;
-
-
- if (relocatable_output && !force_common_definition) {
- sp->defined = 0;
- undefined_global_sym_count++;
- defined_global_sym_count--;
- continue;
- }
-
- /*
- * Round up to nearest sizeof (int). I don't know whether
- * this is necessary or not (given that alignment is taken
- * care of later), but it's traditional, so I'll leave it in.
- * Note that if this size alignment is ever removed, ALIGN
- * above will have to be initialized to 1 instead of sizeof
- * (int).
- */
-
- size = PALIGN(size, sizeof(int));
-
- while (!(size & align))
- align <<= 1;
-
- align = align > MAX_ALIGNMENT ?
- MAX_ALIGNMENT : align;
-
- bss_size = PALIGN(bss_size + data_size + rrs_data_start, align)
- - (data_size + rrs_data_start);
-
- sp->value = rrs_data_start + data_size + bss_size;
- if (sp->defined == (N_UNDF | N_EXT))
- sp->defined = N_BSS | N_EXT;
- else {
- sp->so_defined = 0;
- defined_global_sym_count++;
- }
- bss_size += size;
- if (write_map)
- printf("Allocating %s %s: %x at %x\n",
- sp->defined==(N_BSS|N_EXT)?"common":"data",
- sp->name, size, sp->value);
-
- } END_EACH_SYMBOL;
-}
-
/*
- * Scan relocation info in ENTRY for contributions to the dynamic section of
- * the output file.
+ * Scan relocation info in ENTRY for contributions to the RRS section
+ * of the output file.
*/
static void
consider_relocation (entry, dataseg)
@@ -1848,7 +1821,7 @@ consider_relocation (entry, dataseg)
if (RELOC_BASEREL_P(reloc)) {
pic_code_seen = 1;
if (!RELOC_EXTERN_P(reloc))
- lsp->rename = 1;
+ lsp->flags |= LS_RENAME;
}
continue;
}
@@ -1939,39 +1912,20 @@ consider_relocation (entry, dataseg)
continue;
}
- /*
- * Only allocate an alias for function calls. Use
- * sp->size here as a heuristic to discriminate
- * between function definitions and data residing
- * in the text segment.
- * NOTE THAT THE COMPILER MUST NOT GENERATE ".size"
- * DIRECTIVES FOR FUNCTIONS.
- * In the future we might go for ".type" directives.
- */
- if (force_alias_definition && sp->size == 0 &&
- sp->so_defined == N_TEXT + N_EXT) {
+ if (force_alias_definition && sp->so_defined &&
+ sp->aux == AUX_FUNC) {
/* Call to shared library procedure */
alloc_rrs_jmpslot(entry, sp);
-#define EXPERIMENTAL
-#ifdef EXPERIMENTAL
- if (!RELOC_PCREL_P(reloc)) {
-#ifdef DEBUG
-printf("%s: FUNC flag set\n", sp->name);
-#endif
- sp->aux = RRS_FUNC;
- }
-#endif
- } else if (sp->size &&
- (sp->so_defined == N_DATA + N_EXT ||
- sp->so_defined == N_TEXT + N_EXT)) {
+ } else if (sp->size && sp->so_defined &&
+ sp->aux == AUX_OBJECT) {
/* Reference to shared library data */
alloc_rrs_cpy_reloc(entry, sp);
sp->defined = N_SIZE;
- } else if (!sp->defined && sp->max_common_size == 0)
+ } else if (!sp->defined && sp->common_size == 0)
alloc_rrs_reloc(entry, sp);
} else {
@@ -1988,6 +1942,76 @@ printf("%s: FUNC flag set\n", sp->name);
}
/*
+ * Determine the disposition of each local symbol.
+ */
+static void
+consider_local_symbols(entry)
+ register struct file_entry *entry;
+{
+ register struct localsymbol *lsp, *lspend;
+
+ if (entry->flags & E_DYNAMIC)
+ return;
+
+ lspend = entry->symbols + entry->nsymbols;
+
+ /*
+ * For each symbol determine whether it should go
+ * in the output symbol table.
+ */
+
+ for (lsp = entry->symbols; lsp < lspend; lsp++) {
+ register struct nlist *p = &lsp->nzlist.nlist;
+ register int type = p->n_type;
+
+ if (type == N_WARNING)
+ continue;
+
+ if (SET_ELEMENT_P (type)) {
+ /*
+ * This occurs even if global. These types of
+ * symbols are never written globally, though
+ * they are stored globally.
+ */
+ if (relocatable_output)
+ lsp->flags |= LS_WRITE;
+
+ } else if (!(type & (N_STAB | N_EXT))) {
+
+ /*
+ * Ordinary local symbol
+ */
+ if ((lsp->flags & LS_RENAME) || (
+ discard_locals != DISCARD_ALL &&
+ !(discard_locals == DISCARD_L &&
+ (lsp->flags & LS_L_SYMBOL))) ) {
+
+ lsp->flags |= LS_WRITE;
+ local_sym_count++;
+ }
+
+ } else if (!(type & N_EXT)) {
+
+ /*
+ * Debugger symbol
+ */
+ if (strip_symbols == STRIP_NONE) {
+ lsp->flags |= LS_WRITE;
+ debugger_sym_count++;
+ }
+ }
+ }
+
+ /*
+ * Count one for the local symbol that we generate,
+ * whose name is the file's name (usually) and whose address
+ * is the start of the file's text.
+ */
+ if (discard_locals != DISCARD_ALL)
+ local_sym_count++;
+}
+
+/*
* Accumulate the section sizes of input file ENTRY into the section sizes of
* the output file.
*/
@@ -1995,8 +2019,6 @@ static void
consider_file_section_lengths (entry)
register struct file_entry *entry;
{
- if (entry->just_syms_flag)
- return;
entry->text_start_address = text_size;
/* If there were any vectors, we need to chop them off */
@@ -2013,9 +2035,7 @@ consider_file_section_lengths (entry)
/*
* Determine where the sections of ENTRY go into the output file,
* whose total section sizes are already known.
- * Also relocate the addresses of the file's local and debugger symbols
- * and determine which of the local symbols will make it into the
- * output symbol table.
+ * Also relocate the addresses of the file's local and debugger symbols.
*/
static void
relocate_file_addresses (entry)
@@ -2072,57 +2092,165 @@ printf("%s: datastart: %#x, bss %#x\n", get_file_name(entry),
break;
}
- /*
- * See if this symbol should be in the output symbol table.
- */
+ }
- if (type == N_WARNING)
+}
+
+/*
+ * Assign a value to each global symbol.
+ */
+static void
+digest_pass2()
+{
+ FOR_EACH_SYMBOL(i, sp) {
+ int size;
+ int align = sizeof(int);
+
+ if (!(sp->flags & GS_REFERENCED))
continue;
- if (SET_ELEMENT_P (type)) {
+ if (sp->alias &&
+ (relocatable_output || building_shared_object ||
+ (sp->alias->defined && !sp->alias->so_defined)))
/*
- * This occurs even if global. These types of
- * symbols are never written globally, though
- * they are stored globally.
+ * The alias points at a defined symbol, so it
+ * must itself be counted as one too, in order to
+ * compute the correct number of symbol table entries.
*/
- lsp->write = relocatable_output;
+ defined_global_sym_count++;
- } else if (!(type & (N_STAB | N_EXT))) {
+ if ((sp->defined & N_TYPE) == N_SETV) {
+ /*
+ * Set length word at front of vector and zero byte
+ * at end. Reverse the vector itself to put it in
+ * file order.
+ */
+ unsigned long i, *p, *q;
+ unsigned long length_word_index =
+ sp->value / sizeof(long);
+
+ /* Relocate symbol value */
+ sp->value += set_sect_start;
+
+ set_vectors[length_word_index] = sp->setv_count;
/*
- * Ordinary local symbol
+ * Relocate vector to final address.
*/
- lsp->write = (lsp->rename || (
- discard_locals != DISCARD_ALL &&
- !(discard_locals == DISCARD_L &&
- lsp->is_L_symbol)));
- if (lsp->write)
- local_sym_count++;
+ for (i = 0; i < sp->setv_count; i++) {
+ struct nlist *p = (struct nlist *)
+ set_vectors[1+i+length_word_index];
- } else if (!(type & N_EXT)) {
+ set_vectors[1+i+length_word_index] = p->n_value;
+ if (building_shared_object) {
+ struct relocation_info reloc;
+
+ bzero(&reloc, sizeof(reloc));
+ RELOC_ADDRESS(&reloc) =
+ (1 + i + length_word_index) *
+ sizeof(long)
+ + set_sect_start;
+ RELOC_TYPE(&reloc) =
+ (p->n_type - (N_SETA - N_ABS)) & N_TYPE;
+ claim_rrs_segment_reloc(NULL, &reloc);
+ }
+ }
/*
- * Debugger symbol
+ * Reverse the vector.
*/
- lsp->write = (strip_symbols == STRIP_NONE);
- if (lsp->write)
- debugger_sym_count++;
+ p = &set_vectors[length_word_index + 1];
+ q = &set_vectors[length_word_index + sp->setv_count];
+ while (p < q) {
+ unsigned long tmp = *p;
+ *p++ = *q;
+ *q-- = tmp;
+ }
+ /* Clear terminating entry */
+ set_vectors[length_word_index + sp->setv_count + 1] = 0;
+ continue;
}
- }
- /*
- * Count one for the local symbol that we generate,
- * whose name is the file's name (usually) and whose address
- * is the start of the file's text.
- */
- if (discard_locals != DISCARD_ALL)
- local_sym_count++;
+ if (sp->defined && sp->def_nlist &&
+ ((sp->defined & ~N_EXT) != N_SETV))
+ sp->value = sp->def_nlist->n_value;
+
+ /*
+ * If not -r'ing, allocate common symbols in the BSS section.
+ */
+ if (building_shared_object && !(link_mode & SYMBOLIC))
+ /* No common allocation in shared objects */
+ continue;
+
+ if ((size = sp->common_size) != 0) {
+ /*
+ * It's a common.
+ */
+ if (sp->defined != (N_UNDF + N_EXT))
+ fatal("%s: common isn't", sp->name);
+
+ } else if ((size = sp->size) != 0 && sp->defined == N_SIZE) {
+ /*
+ * It's data from shared object with size info.
+ */
+ if (!sp->so_defined)
+ fatal("%s: Bogus N_SIZE item", sp->name);
+
+ } else
+ /*
+ * It's neither
+ */
+ continue;
+
+
+ if (relocatable_output && !force_common_definition) {
+ sp->defined = 0;
+ undefined_global_sym_count++;
+ defined_global_sym_count--;
+ continue;
+ }
+
+ /*
+ * Round up to nearest sizeof (int). I don't know whether
+ * this is necessary or not (given that alignment is taken
+ * care of later), but it's traditional, so I'll leave it in.
+ * Note that if this size alignment is ever removed, ALIGN
+ * above will have to be initialized to 1 instead of sizeof
+ * (int).
+ */
+
+ size = PALIGN(size, sizeof(int));
+
+ while (!(size & align))
+ align <<= 1;
+
+ align = align > MAX_ALIGNMENT ? MAX_ALIGNMENT : align;
+
+ bss_size = PALIGN(bss_size + data_size + rrs_data_start, align)
+ - (data_size + rrs_data_start);
+
+ sp->value = rrs_data_start + data_size + bss_size;
+ if (sp->defined == (N_UNDF | N_EXT))
+ sp->defined = N_BSS | N_EXT;
+ else {
+ sp->so_defined = 0;
+ defined_global_sym_count++;
+ }
+ bss_size += size;
+ if (write_map)
+ printf("Allocating %s %s: %x at %x\n",
+ sp->defined==(N_BSS|N_EXT)?"common":"data",
+ sp->name, size, sp->value);
+
+ } END_EACH_SYMBOL;
}
-
-/* Write the output file */
+
+/* -------------------------------------------------------------------*/
+
+/* Write the output file */
void
write_output ()
{
@@ -2138,6 +2266,8 @@ write_output ()
if (outdesc < 0)
perror_name (output_filename);
+ fatal_cleanup_hook = myfatal;
+
if (fstat (outdesc, &statbuf) < 0)
perror_name (output_filename);
@@ -2176,6 +2306,9 @@ write_header ()
{
int flags = (rrs_section_type == RRS_FULL) ? EX_DYNAMIC : 0;
+ if (oldmagic && (flags & EX_DYNAMIC))
+ error("Cannot set flag in old magic headers\n");
+
N_SET_FLAG (outheader, flags);
outheader.a_text = text_size;
@@ -2339,7 +2472,7 @@ copy_data (entry)
mywrite (bytes, 1, entry->header.a_data, outdesc);
}
-
+
/*
* Relocate ENTRY's text or data section contents. DATA is the address of the
* contents, in core. DATA_SIZE is the length of the contents. PC_RELOCATION
@@ -2347,6 +2480,10 @@ copy_data (entry)
* and its address in the input file. RELOC is the address of the
* relocation info, in core. NRELOC says how many there are.
*/
+
+/* HACK: md.c may need access to this */
+int pc_relocation;
+
void
perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
char *data;
@@ -2356,12 +2493,13 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
struct file_entry *entry;
int dataseg;
{
- register struct relocation_info *r = reloc;
- struct relocation_info *end = reloc + nreloc;
- text_relocation = entry->text_start_address;
- data_relocation = entry->data_start_address - entry->header.a_text;
- bss_relocation = entry->bss_start_address -
+ register struct relocation_info *r = reloc;
+ struct relocation_info *end = reloc + nreloc;
+
+ int text_relocation = entry->text_start_address;
+ int data_relocation = entry->data_start_address - entry->header.a_text;
+ int bss_relocation = entry->bss_start_address -
entry->header.a_text - entry->header.a_data;
pc_relocation = dataseg?
entry->data_start_address - entry->header.a_text:
@@ -2616,10 +2754,10 @@ write_rel ()
/* BLECH - Assign number 0 to __DYNAMIC (!! Sun compatibility) */
- if (dynamic_symbol->referenced)
+ if (dynamic_symbol->flags & GS_REFERENCED)
dynamic_symbol->symbolnum = count++;
FOR_EACH_SYMBOL(i, sp) {
- if (sp != dynamic_symbol && sp->referenced) {
+ if (sp != dynamic_symbol && (sp->flags & GS_REFERENCED)) {
sp->symbolnum = count++;
if (sp->size)
count++;
@@ -2664,7 +2802,7 @@ assign_symbolnums(entry, countp)
n++;
for (lsp = entry->symbols; lsp < lspend; lsp++) {
- if (lsp->write)
+ if (lsp->flags & LS_WRITE)
lsp->symbolnum = n++;
}
*countp = n;
@@ -2729,10 +2867,11 @@ coptxtrel(entry)
* If we aren't going to be adding in the
* value in memory on the next pass of the
* loader, then we need to add it in from the
- * relocation entry. Otherwise the work we
+ * relocation entry, unless the symbol remains
+ * external in our output. Otherwise the work we
* did in this pass is lost.
*/
- if (!RELOC_MEMORY_ADD_P(r))
+ if (!RELOC_MEMORY_ADD_P(r) && !RELOC_EXTERN_P(r))
RELOC_ADD_EXTRA(r) += sp->value;
#endif
} else
@@ -2794,7 +2933,7 @@ copdatrel(entry)
symtype = sp->defined & N_TYPE;
- if (!pic_code_seen && (force_common_definition ||
+ if (!pic_code_seen && ( symtype == N_BSS ||
symtype == N_DATA ||
symtype == N_TEXT ||
symtype == N_ABS)) {
@@ -2939,7 +3078,7 @@ write_syms()
* If defined (ie. not relocatable_output), make it look
* like an internal symbol.
*/
- if (dynamic_symbol->referenced) {
+ if (dynamic_symbol->flags & GS_REFERENCED) {
nl.n_other = 0;
nl.n_desc = 0;
nl.n_type = dynamic_symbol->defined;
@@ -2961,7 +3100,7 @@ write_syms()
/* Already dealt with above */
continue;
- if (!sp->referenced)
+ if (!(sp->flags & GS_REFERENCED))
/* Came from shared object but was not used */
continue;
@@ -3009,6 +3148,7 @@ write_syms()
*/
nl.n_type = sp->alias->defined;
nl.n_value = sp->alias->value;
+ nl.n_other = N_OTHER(0, sp->alias->aux);
} else {
if (sp->defined == N_SIZE)
nl.n_type = N_DATA | N_EXT;
@@ -3019,9 +3159,10 @@ write_syms()
fatal("%s: N_INDR has value %#x",
sp->name, sp->value);
nl.n_value = sp->value;
+ nl.n_other = N_OTHER(0, sp->aux);
}
- } else if (sp->max_common_size) {
+ } else if (sp->common_size) {
/*
* defined as common but not allocated,
* happens only with -r and not -d, write out
@@ -3032,7 +3173,7 @@ write_syms()
* undefined in digest_symbols.
*/
nl.n_type = N_UNDF | N_EXT;
- nl.n_value = sp->max_common_size;
+ nl.n_value = sp->common_size;
} else if (!sp->defined) {
/* undefined -- legit only if -r */
nl.n_type = N_UNDF | N_EXT;
@@ -3053,6 +3194,9 @@ write_syms()
*bufp++ = nl;
syms_written++;
+ /*
+ * Write second symbol of an alias pair.
+ */
if (nl.n_type == N_INDR + N_EXT) {
if (sp->alias == NULL)
fatal("internal error: alias in hyperspace");
@@ -3066,6 +3210,9 @@ write_syms()
syms_written++;
}
+ /*
+ * Write N_SIZE symbol for a symbol with a known size.
+ */
if (relocatable_output && sp->size) {
nl.n_type = N_SIZE + N_EXT;
nl.n_un.n_strx = assign_string_table_index(sp->name);
@@ -3144,7 +3291,7 @@ write_file_syms(entry, syms_written_addr)
register struct nlist *bufp = buf;
- if (entry->is_dynamic)
+ if (entry->flags & E_DYNAMIC)
return;
/*
@@ -3168,9 +3315,6 @@ write_file_syms(entry, syms_written_addr)
nl.n_other = 0;
*bufp++ = nl;
(*syms_written_addr)++;
-#if 0
- entry->local_syms_offset = *syms_written_addr * sizeof(struct nlist);
-#endif
}
/* Read the file's string table. */
@@ -3185,12 +3329,12 @@ write_file_syms(entry, syms_written_addr)
register int write = 0;
char *name;
- if (! lsp->write)
+ if (!(lsp->flags & LS_WRITE))
continue;
if (p->n_un.n_strx == 0)
name = NULL;
- else if (lsp->rename == 0)
+ else if (!(lsp->flags & LS_RENAME))
name = p->n_un.n_strx + entry->strings;
else {
char *cp = p->n_un.n_strx + entry->strings;
@@ -3229,3 +3373,50 @@ write_file_syms(entry, syms_written_addr)
write_string_table();
entry->strings = 0; /* Since it will disappear anyway. */
}
+
+/*
+ * Output COUNT*ELTSIZE bytes of data at BUF to the descriptor DESC.
+ */
+void
+mywrite (buf, count, eltsize, desc)
+ void *buf;
+ int count;
+ int eltsize;
+ int desc;
+{
+ register int val;
+ register int bytes = count * eltsize;
+
+ while (bytes > 0) {
+ val = write (desc, buf, bytes);
+ if (val <= 0)
+ perror(output_filename);
+ buf += val;
+ bytes -= val;
+ }
+}
+
+static void
+myfatal()
+{
+ if (outdesc > 0)
+ unlink(output_filename);
+}
+
+/*
+ * Output PADDING zero-bytes to descriptor OUTDESC.
+ * PADDING may be negative; in that case, do nothing.
+ */
+void
+padfile (padding, outdesc)
+ int padding;
+ int outdesc;
+{
+ register char *buf;
+ if (padding <= 0)
+ return;
+
+ buf = (char *) alloca (padding);
+ bzero (buf, padding);
+ mywrite (buf, padding, 1, outdesc);
+}
OpenPOWER on IntegriCloud