summaryrefslogtreecommitdiffstats
path: root/gnu
diff options
context:
space:
mode:
authorjkh <jkh@FreeBSD.org>1993-12-11 12:02:10 +0000
committerjkh <jkh@FreeBSD.org>1993-12-11 12:02:10 +0000
commitfa2f9983992b8f76f4876d186e7f838007698a3a (patch)
tree9dc50398c34bcf4df5b21ad170bcfc2ec5d49cff /gnu
parentfae8cc8948a605d587d12154817c04384efa8e15 (diff)
downloadFreeBSD-src-fa2f9983992b8f76f4876d186e7f838007698a3a.zip
FreeBSD-src-fa2f9983992b8f76f4876d186e7f838007698a3a.tar.gz
Sync up with Paul K's latest ld from cesium.
Diffstat (limited to 'gnu')
-rw-r--r--gnu/usr.bin/ld/etc.c26
-rw-r--r--gnu/usr.bin/ld/i386/md.h30
-rw-r--r--gnu/usr.bin/ld/ld.c325
-rw-r--r--gnu/usr.bin/ld/ld.h19
-rw-r--r--gnu/usr.bin/ld/lib.c150
-rw-r--r--gnu/usr.bin/ld/rrs.c61
-rw-r--r--gnu/usr.bin/ld/shlib.c36
-rw-r--r--gnu/usr.bin/ld/sparc/md-static-funcs.c2
-rw-r--r--gnu/usr.bin/ld/sparc/md.c39
-rw-r--r--gnu/usr.bin/ld/warnings.c43
10 files changed, 558 insertions, 173 deletions
diff --git a/gnu/usr.bin/ld/etc.c b/gnu/usr.bin/ld/etc.c
index 2670283..22fdfd8 100644
--- a/gnu/usr.bin/ld/etc.c
+++ b/gnu/usr.bin/ld/etc.c
@@ -1,5 +1,5 @@
/*
- * $Id: etc.c,v 1.4 1993/12/02 00:56:33 jkh Exp $
+ * $Id: etc.c,v 1.5 1993/12/04 00:52:55 jkh Exp $
*/
#include <sys/param.h>
@@ -85,7 +85,7 @@ fatal(fmt, va_alist)
char *
concat(s1, s2, s3)
- char *s1, *s2, *s3;
+ const char *s1, *s2, *s3;
{
register int len1 = strlen (s1),
len2 = strlen (s2),
@@ -150,22 +150,6 @@ xrealloc(ptr, size)
}
-#ifdef USG
-void
-bzero(p, n)
- char *p;
-{
- memset (p, 0, n);
-}
-
-void
-bcopy(from, to, n)
- char *from, *to;
-{
- memcpy (to, from, n);
-}
-#endif
-
/* These must move */
@@ -192,8 +176,10 @@ mywrite (buf, count, eltsize, desc)
}
}
-/* Output PADDING zero-bytes to descriptor OUTDESC.
- PADDING may be negative; in that case, do nothing. */
+/*
+ * Output PADDING zero-bytes to descriptor OUTDESC.
+ * PADDING may be negative; in that case, do nothing.
+ */
void
padfile (padding, outdesc)
diff --git a/gnu/usr.bin/ld/i386/md.h b/gnu/usr.bin/ld/i386/md.h
index 714073b..285b0e6 100644
--- a/gnu/usr.bin/ld/i386/md.h
+++ b/gnu/usr.bin/ld/i386/md.h
@@ -1,5 +1,33 @@
/*
- * $Id: md.h,v 1.3 1993/11/22 19:05:24 jkh Exp $ - I386 dependent definitions
+ * Copyright (c) 1993 Paul Kranenburg
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Paul Kranenburg.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: md.h,v 1.5 1993/12/08 10:14:48 pk Exp $
*/
diff --git a/gnu/usr.bin/ld/ld.c b/gnu/usr.bin/ld/ld.c
index 3b24f43..567b536 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.14 1993/12/02 05:09:52 nate Exp $
+ * $Id: ld.c,v 1.15 1993/12/04 00:52:56 jkh Exp $
*/
/* Define how to initialize system-dependent header fields. */
@@ -55,6 +55,10 @@ 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;
/* 1 => write relocation into output file so can re-input it later. */
@@ -77,6 +81,9 @@ int force_alias_definition;
if `relocatable_output'. */
int pic_code_seen;
+/* 1 => data segment must be page aligned, even if `-n' or `-N' */
+int page_align_data;
+
/*
* Which symbols should be stripped (omitted from the output): none, all, or
* debugger symbols.
@@ -127,6 +134,25 @@ int specified_data_size;
long *set_vectors;
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 enter_global_ref __P((struct localsymbol *,
+ char *, struct file_entry *));
+static void digest_symbols __P((void));
+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 perform_relocation __P((char *, int,
+ struct relocation_info *, int,
+ struct file_entry *, int));
+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 assign_symbolnums __P((struct file_entry *, int *));
+
int
main(argc, argv)
char **argv;
@@ -163,6 +189,7 @@ main(argc, argv)
data_pad = 0;
text_pad = 0;
+ page_align_data = 0;
/* Initialize the data about options. */
@@ -180,7 +207,10 @@ main(argc, argv)
make_executable = 1;
force_executable = 0;
link_mode = DYNAMIC;
- soversion = LD_VERSION_BSD;
+#ifdef SUNOS4
+ link_mode |= SILLYARCHIVE;
+#endif
+ soversion = DEFAULT_SOVERSION;
/* Initialize the cumulative counts of symbols. */
@@ -262,8 +292,6 @@ main(argc, argv)
exit(!make_executable);
}
-void decode_option();
-
/*
* Analyze a command line argument. Return 0 if the argument is a filename.
* Return 1 if the argument is a option complete in itself. Return 2 if the
@@ -273,7 +301,7 @@ void decode_option();
* options.
*/
-int
+static int
classify_arg(arg)
register char *arg;
{
@@ -320,10 +348,10 @@ classify_arg(arg)
* each input file, and setting variables according to the options.
*/
-void
+static void
decode_command(argc, argv)
- char **argv;
int argc;
+ char **argv;
{
register int i;
register struct file_entry *p;
@@ -390,6 +418,12 @@ decode_command(argc, argv)
link_mode |= FORCEARCHIVE;
else if (strcmp(string, "shareable") == 0)
link_mode |= SHAREABLE;
+#ifdef SUN_COMPAT
+ else if (strcmp(string, "silly") == 0)
+ link_mode |= SILLYARCHIVE;
+ else if (strcmp(string, "~silly") == 0)
+ link_mode &= ~SILLYARCHIVE;
+#endif
}
if (argv[i][1] == 'A') {
if (p != file_table)
@@ -467,7 +501,7 @@ set_element_prefixed_p(name)
* files.
*/
-void
+static void
decode_option(swt, arg)
register char *swt, *arg;
{
@@ -484,6 +518,10 @@ decode_option(swt, arg)
return;
if (!strcmp(swt + 1, "assert"))
return;
+#ifdef SUN_COMPAT
+ if (!strcmp(swt + 1, "Bsilly"))
+ return;
+#endif
if (!strcmp(swt + 1, "Ttext")) {
text_start = parse(arg, "%x", "invalid argument to -Ttext");
T_flag_specified = 1;
@@ -551,16 +589,19 @@ decode_option(swt, arg)
case 'Q':
magic = oldmagic = QMAGIC;
return;
-#endif
case 'Z':
- magic = ZMAGIC;
- oldmagic = 0;
+ magic = oldmagic = ZMAGIC;
return;
+#endif
case 'o':
output_filename = arg;
return;
+ case 'p':
+ page_align_data = 1;
+ return;
+
case 'r':
relocatable_output = 1;
magic = OMAGIC;
@@ -644,17 +685,38 @@ each_file(function, arg)
for (i = 0; i < number_of_files; i++) {
register struct file_entry *entry = &file_table[i];
+ register struct file_entry *subentry;
+
if (entry->scrapped)
continue;
- if (entry->library_flag) {
- register struct file_entry *subentry = entry->subfiles;
+
+ if (!entry->library_flag)
+ (*function) (entry, arg);
+
+ subentry = entry->subfiles;
+ for (; subentry; subentry = subentry->chain) {
+ if (subentry->scrapped)
+ continue;
+ (*function) (subentry, arg);
+ }
+
+#ifdef SUN_COMPAT
+ if (entry->silly_archive) {
+
+ if (!entry->is_dynamic)
+ error("Silly");
+
+ if (!entry->silly_archive->library_flag)
+ error("Sillier");
+
+ subentry = entry->silly_archive->subfiles;
for (; subentry; subentry = subentry->chain) {
if (subentry->scrapped)
continue;
(*function) (subentry, arg);
}
- } else
- (*function) (entry, arg);
+ }
+#endif
}
}
@@ -704,15 +766,41 @@ each_full_file(function, arg)
for (i = 0; i < number_of_files; i++) {
register struct file_entry *entry = &file_table[i];
- if (entry->scrapped ||
- entry->just_syms_flag || entry->is_dynamic)
+ register struct file_entry *subentry;
+
+ if (entry->scrapped || entry->just_syms_flag)
continue;
- if (entry->library_flag) {
- register struct file_entry *subentry = entry->subfiles;
- for (; subentry; subentry = subentry->chain)
+
+#ifdef SUN_COMPAT
+ if (entry->silly_archive) {
+
+ if (!entry->is_dynamic)
+ error("Silly");
+
+ if (!entry->silly_archive->library_flag)
+ error("Sillier");
+
+ subentry = entry->silly_archive->subfiles;
+ for (; subentry; subentry = subentry->chain) {
+ if (subentry->scrapped)
+ continue;
(*function) (subentry, arg);
- } else
+ }
+ }
+#endif
+ if (entry->is_dynamic)
+ continue;
+
+ if (!entry->library_flag)
(*function) (entry, arg);
+
+ subentry = entry->subfiles;
+ for (; subentry; subentry = subentry->chain) {
+ if (subentry->scrapped)
+ continue;
+ (*function) (subentry, arg);
+ }
+
}
}
@@ -737,7 +825,7 @@ file_open (entry)
{
register int desc;
- if (entry->superfile)
+ if (entry->superfile && entry->superfile->library_flag)
return file_open (entry->superfile);
if (entry == input_file)
@@ -802,6 +890,7 @@ read_header (desc, entry)
* descriptor DESC. Also read the length of the string table, which follows
* the symbol table, but don't read the contents of the string table.
*/
+
void
read_entry_symbols (desc, entry)
struct file_entry *entry;
@@ -941,8 +1030,6 @@ read_entry_relocation (desc, entry)
/* Read in the symbols of all input files. */
-void read_file_symbols (), read_entry_symbols ();
-void enter_file_symbols (), enter_global_ref ();
void
load_symbols ()
@@ -990,7 +1077,7 @@ read_file_symbols (entry)
return;
}
entry->is_dynamic = 1;
- if (rrs_add_shobj(entry))
+ if (entry->superfile || rrs_add_shobj(entry))
read_shared_object(desc, entry);
else
entry->scrapped = 1;
@@ -1095,7 +1182,7 @@ enter_file_symbols (entry)
*
*/
-void
+static void
enter_global_ref (lsp, name, entry)
struct localsymbol *lsp;
char *name;
@@ -1117,8 +1204,9 @@ enter_global_ref (lsp, name, entry)
lsp->nzlist.nz_type = N_TEXT|N_EXT;
lsp->nzlist.nz_value = 0;
make_executable = 0;
- } else
+ } else {
global_alias_count++;
+ }
}
if (entry->is_dynamic) {
@@ -1273,9 +1361,6 @@ contains_symbol (entry, np)
}
-void consider_file_section_lengths (), relocate_file_addresses ();
-void consider_relocation();
-
/*
* Having entered all the global symbols and found the sizes of sections of
* all files to be linked, make all appropriate deductions from this data.
@@ -1295,7 +1380,7 @@ void consider_relocation();
* symbols originating from shared objects is searched for a definition.
*
* 2) Then the relocation information of each relocatable file is examined
- * for for possible contributions to the RRS section.
+ * for possible contributions to the RRS section.
*
* 3) When this is done, the sizes and start addresses are set of all segments
* that will appear in the output file (including the RRS segment).
@@ -1307,9 +1392,8 @@ void consider_relocation();
*
*/
-void digest_pass1(), digest_pass2();
-void
+static void
digest_symbols ()
{
@@ -1323,9 +1407,9 @@ digest_symbols ()
* the vector, plus a word for each symbol for a zero at the
* end of the vector (for incremental linking).
*/
- set_sect_size = (2 * set_symbol_count + set_vector_count) *
+ set_sect_size = (set_symbol_count + 2 * set_vector_count) *
sizeof (unsigned long);
- set_vectors = (unsigned long *) xmalloc (set_sect_size);
+ set_vectors = (long *)xmalloc (set_sect_size);
setv_fill_count = 0;
}
@@ -1354,7 +1438,7 @@ digest_symbols ()
* the padding in the text segment size.
*/
- if (magic == ZMAGIC) {
+ if (magic == ZMAGIC || page_align_data) {
int text_end = text_size + N_TXTOFF(outheader);
text_pad = PALIGN(text_end, page_size) - text_end;
text_size += text_pad;
@@ -1429,12 +1513,24 @@ printf("bssstart = %#x, bsssize = %#x\n",
if (got_symbol->referenced)
global_sym_count++;
- if (relocatable_output)
+ if (relocatable_output || building_shared_object)
/* For each alias we write out two struct nlists */
- global_sym_count += global_alias_count + size_sym_count;
+ global_sym_count += global_alias_count;
+
+ if (relocatable_output)
+ /* We write out the original N_SET* symbols */
+ global_sym_count += size_sym_count;
+
+#ifdef DEBUG
+printf("global symbols %d (defined %d, undefined %d, aliases %d), locals: %d, \
+debug symbols: %d, set_symbols %d\n",
+ global_sym_count,
+ defined_global_sym_count, undefined_global_sym_count, global_alias_count,
+ local_sym_count, debugger_sym_count, set_symbol_count);
+#endif
}
-void
+static void
digest_pass1()
{
@@ -1510,7 +1606,14 @@ digest_pass1()
if ((sp->defined & N_TYPE) == N_SETV)
/* Allocate zero entry in set vector */
setv_fill_count++;
- defined_global_sym_count++;
+ /*
+ * At this stage, we do not know whether an alias
+ * is going to be defined for real here, or whether
+ * it refers to a shared object symbol. The decision
+ * is deferred until digest_pass2().
+ */
+ if (!sp->alias)
+ defined_global_sym_count++;
continue;
}
@@ -1528,6 +1631,7 @@ digest_pass1()
continue;
}
+ again:
for (lsp = sp->sorefs; lsp; lsp = lsp->next) {
register struct nlist *p = &lsp->nzlist.nlist;
register int type = p->n_type;
@@ -1537,17 +1641,29 @@ digest_pass1()
/* non-common definition */
sp->def_nlist = p;
sp->so_defined = type;
- undefined_global_sym_count--;
+ if (sp->referenced)
+ undefined_global_sym_count--;
+ else
+ sp->referenced = 1;
#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) {
+ sp = sp->alias;
+ goto again;
+ }
break;
}
}
} END_EACH_SYMBOL;
+
+ if (setv_fill_count != set_sect_size/sizeof(long))
+ fatal("internal error: allocated set symbol space (%d) \
+doesn't match actual (%d)",
+ set_sect_size/sizeof(long), setv_fill_count);
}
-void
+static void
digest_pass2()
{
/*
@@ -1562,6 +1678,16 @@ digest_pass2()
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
@@ -1676,11 +1802,12 @@ digest_pass2()
} END_EACH_SYMBOL;
}
+
/*
* Scan relocation info in ENTRY for contributions to the dynamic section of
* the output file.
*/
-void
+static void
consider_relocation (entry, dataseg)
struct file_entry *entry;
int dataseg;
@@ -1849,7 +1976,7 @@ printf("%s: FUNC flag set\n", sp->name);
* Accumulate the section sizes of input file ENTRY into the section sizes of
* the output file.
*/
-void
+static void
consider_file_section_lengths (entry)
register struct file_entry *entry;
{
@@ -1875,7 +2002,7 @@ consider_file_section_lengths (entry)
* and determine which of the local symbols will make it into the
* output symbol table.
*/
-void
+static void
relocate_file_addresses (entry)
register struct file_entry *entry;
{
@@ -2025,18 +2152,20 @@ write_output ()
if (chmod (output_filename, filemode | 0111) == -1)
perror_name (output_filename);
}
-
-void modify_location (), perform_relocation (), copy_text (), copy_data ();
/* Total number of symbols to be written in the output file. */
-int nsyms;
+static int nsyms;
void
write_header ()
{
int flags = (rrs_section_type == RRS_FULL) ? EX_DYNAMIC : 0;
- if (!oldmagic) N_SET_FLAG (outheader, flags);
+#ifdef QMAGIC
+ if (!oldmagic)
+#endif
+ N_SET_FLAG (outheader, flags);
+
outheader.a_text = text_size;
outheader.a_data = data_size;
outheader.a_bss = bss_size;
@@ -2051,15 +2180,6 @@ write_header ()
if (relocatable_output)
nsyms += set_symbol_count;
-#ifdef DEBUG
-printf("global symbols %d (defined %d, undefined %d), locals: %d, \
-debug symbols: %d, set_symbols %d, aliases %d --> nsyms %d\n",
- global_sym_count,
- defined_global_sym_count, undefined_global_sym_count,
- local_sym_count, debugger_sym_count,
- set_symbol_count, global_alias_count, nsyms);
-#endif
-
outheader.a_syms = nsyms * sizeof (struct nlist);
if (relocatable_output) {
@@ -2462,10 +2582,10 @@ printf("%s: BSS found in so_defined\n", sp->name);
}
}
-/* For relocatable_output only: write out the relocation,
- relocating the addresses-to-be-relocated. */
-
-void coptxtrel(), copdatrel(), assign_symbolnums();
+/*
+ * For relocatable_output only: write out the relocation,
+ * relocating the addresses-to-be-relocated.
+ */
void
write_rel ()
@@ -2513,10 +2633,11 @@ write_rel ()
fprintf (stderr, "\n");
}
+
/*
* Assign symbol ordinal numbers to local symbols in each entry.
*/
-void
+static void
assign_symbolnums(entry, countp)
struct file_entry *entry;
int *countp;
@@ -2537,7 +2658,7 @@ assign_symbolnums(entry, countp)
*countp = n;
}
-void
+static void
coptxtrel(entry)
struct file_entry *entry;
{
@@ -2613,7 +2734,7 @@ coptxtrel(entry)
sizeof(struct relocation_info), outdesc);
}
-void
+static void
copdatrel(entry)
struct file_entry *entry;
{
@@ -2684,28 +2805,28 @@ void write_string_table __P((void));
/* Offsets and current lengths of symbol and string tables in output file. */
-int symbol_table_offset;
-int symbol_table_len;
+static int symbol_table_offset;
+static int symbol_table_len;
/* Address in output file where string table starts. */
-int string_table_offset;
+static int string_table_offset;
/* Offset within string table
where the strings in `strtab_vector' should be written. */
-int string_table_len;
+static int string_table_len;
/* Total size of string table strings allocated so far,
including strings in `strtab_vector'. */
-int strtab_size;
+static int strtab_size;
/* Vector whose elements are strings to be added to the string table. */
-char **strtab_vector;
+static char **strtab_vector;
/* Vector whose elements are the lengths of those strings. */
-int *strtab_lens;
+static int *strtab_lens;
/* Index in `strtab_vector' at which the next string will be stored. */
-int strtab_index;
+static int strtab_index;
/*
* Add the string NAME to the output file string table. Record it in
@@ -2713,7 +2834,7 @@ int strtab_index;
* table that this string will have.
*/
-int
+static int
assign_string_table_index(name)
char *name;
{
@@ -2823,6 +2944,7 @@ write_syms()
/* Scan the symbol hash table, bucket by bucket. */
FOR_EACH_SYMBOL(i, sp) {
+
if (sp == dynamic_symbol)
/* Already dealt with above */
continue;
@@ -2831,7 +2953,7 @@ write_syms()
/* Came from shared object but was not used */
continue;
- if (sp->so_defined)
+ if (sp->so_defined || (sp->alias && sp->alias->so_defined))
/*
* Definition came from shared object,
* don't mention it here
@@ -2850,39 +2972,52 @@ write_syms()
continue;
}
- /* Construct a `struct nlist' for the symbol. */
+ if (syms_written >= global_sym_count)
+ fatal(
+ "internal error: number of symbols exceeds alloc'd %d",
+ global_sym_count);
+ /*
+ * Construct a `struct nlist' for the symbol.
+ */
nl.n_other = 0;
nl.n_desc = 0;
- /*
- * common condition needs to be before undefined
- * condition because unallocated commons are set
- * undefined in digest_symbols
- */
if (sp->defined > 1) {
- /* defined with known type */
-
- if (!relocatable_output && sp->alias &&
- sp->alias->defined > 1) {
+ /*
+ * defined with known type
+ */
+ if (!relocatable_output && !building_shared_object &&
+ sp->alias && sp->alias->defined > 1) {
/*
* If the target of an indirect symbol has
* been defined and we are outputting an
* executable, resolve the indirection; it's
- * no longer needed
+ * no longer needed.
*/
nl.n_type = sp->alias->defined;
- nl.n_type = sp->alias->value;
- } else if (sp->defined == N_SIZE)
- nl.n_type = N_DATA | N_EXT;
- else
- nl.n_type = sp->defined;
- nl.n_value = sp->value;
+ nl.n_value = sp->alias->value;
+ } else {
+ if (sp->defined == N_SIZE)
+ nl.n_type = N_DATA | N_EXT;
+ else
+ nl.n_type = sp->defined;
+ if (nl.n_type == (N_INDR|N_EXT) &&
+ sp->value != 0)
+ fatal("%s: N_INDR has value %#x",
+ sp->name, sp->value);
+ nl.n_value = sp->value;
+ }
+
} else if (sp->max_common_size) {
/*
* defined as common but not allocated,
* happens only with -r and not -d, write out
- * a common definition
+ * a common definition.
+ *
+ * common condition needs to be before undefined
+ * condition because unallocated commons are set
+ * undefined in digest_symbols.
*/
nl.n_type = N_UNDF | N_EXT;
nl.n_value = sp->max_common_size;
@@ -2903,10 +3038,6 @@ write_syms()
/* Output to the buffer and count it. */
- if (syms_written >= global_sym_count)
- fatal(
- "internal error: number of symbols exceeds allocated %d",
- global_sym_count);
*bufp++ = nl;
syms_written++;
diff --git a/gnu/usr.bin/ld/ld.h b/gnu/usr.bin/ld/ld.h
index 7b9a706..081734e 100644
--- a/gnu/usr.bin/ld/ld.h
+++ b/gnu/usr.bin/ld/ld.h
@@ -1,4 +1,4 @@
-/* $Id: ld.h,v 1.6 1993/12/02 00:56:37 jkh Exp $ */
+/* $Id: ld.h,v 1.7 1993/12/04 00:52:58 jkh Exp $ */
/*-
* This code is derived from software copyrighted by the Free Software
* Foundation.
@@ -678,6 +678,11 @@ struct file_entry {
/* For library member, points to next entry for next member. */
struct file_entry *chain;
+#ifdef SUN_COMPAT
+ /* For shared libraries which have a .sa companion */
+ struct file_entry *silly_archive;
+#endif
+
/* 1 if file is a library. */
char library_flag;
@@ -722,7 +727,8 @@ int number_of_files;
#define FORCEARCHIVE 4 /* Force inclusion of all members
of archives */
#define SHAREABLE 8 /* Build a shared object */
-int link_mode;
+#define SILLYARCHIVE 16 /* Process .sa companions, if any */
+int link_mode;
/*
* Runtime Relocation Section (RRS).
@@ -824,13 +830,14 @@ char **search_dirs;
/* Length of the vector `search_dirs'. */
int n_search_dirs;
-void digest_symbols __P((void));
void load_symbols __P((void));
-void decode_command __P((int, char **));
void read_header __P((int, struct file_entry *));
void read_entry_symbols __P((int, struct file_entry *));
void read_entry_strings __P((int, struct file_entry *));
void read_entry_relocation __P((int, struct file_entry *));
+void enter_file_symbols __P((struct file_entry *));
+void read_file_symbols __P((struct file_entry *));
+
void write_output __P((void));
void write_header __P((void));
void write_text __P((void));
@@ -856,7 +863,7 @@ void *xrealloc __P((void *, int));
void fatal __P((char *, ...));
void error __P((char *, ...));
void padfile __P((int,int));
-char *concat __P((char *, char *, char *));
+char *concat __P((const char *, const char *, const char *));
int parse __P((char *, char *, char *));
/* In symbol.c: */
@@ -869,7 +876,7 @@ void read_shared_object __P((int, struct file_entry *));
int findlib __P((struct file_entry *));
/* In shlib.c: */
-char *findshlib __P((char *, int *, int *));
+char *findshlib __P((char *, int *, int *, int));
void add_search_dir __P((char *));
void std_search_dirs __P((char *));
diff --git a/gnu/usr.bin/ld/lib.c b/gnu/usr.bin/ld/lib.c
index 3a6cbbb..46e5d46 100644
--- a/gnu/usr.bin/ld/lib.c
+++ b/gnu/usr.bin/ld/lib.c
@@ -1,5 +1,5 @@
/*
- * $Id: lib.c,v 1.5 1993/12/02 00:56:38 jkh Exp $ - library routines
+ * $Id: lib.c,v 1.6 1993/12/04 00:52:59 jkh Exp $ - library routines
*/
#include <sys/param.h>
@@ -78,7 +78,8 @@ decode_library_subfile(desc, library_entry, subfile_offset, length_loc)
{
int bytes_read;
register int namelen;
- int member_length;
+ int member_length, content_length;
+ int starting_offset;
register char *name;
struct ar_hdr hdr1;
register struct file_entry *subentry;
@@ -104,22 +105,49 @@ decode_library_subfile(desc, library_entry, subfile_offset, length_loc)
&& hdr1.ar_name[namelen] != '/';
namelen++);
- name = (char *) xmalloc(namelen + 1);
- strncpy(name, hdr1.ar_name, namelen);
- name[namelen] = 0;
+ starting_offset = subfile_offset + sizeof hdr1;
+ content_length = member_length;
+
+#ifdef AR_EFMT1
+ /*
+ * BSD 4.4 extended AR format: #1/<namelen>, with name as the
+ * first <namelen> bytes of the file
+ */
+ if ( (hdr1.ar_name[0] == '#') &&
+ (hdr1.ar_name[1] == '1') &&
+ (hdr1.ar_name[2] == '/') &&
+ (isdigit(hdr1.ar_name[3]))) {
+
+ namelen = atoi(&hdr1.ar_name[3]);
+ name = (char *)xmalloc(namelen + 1);
+ if (read(desc, name, namelen) != namelen)
+ fatal_with_file(
+ "malformatted header of archive member in ",
+ library_entry);
+ name[namelen] = 0;
+ content_length -= namelen;
+ starting_offset += namelen;
+ } else
+
+#endif
+ {
+ name = (char *)xmalloc(namelen + 1);
+ strncpy(name, hdr1.ar_name, namelen);
+ name[namelen] = 0;
+ }
subentry->filename = name;
subentry->local_sym_name = name;
subentry->symbols = 0;
subentry->strings = 0;
subentry->subfiles = 0;
- subentry->starting_offset = subfile_offset + sizeof hdr1;
+ subentry->starting_offset = starting_offset;
subentry->superfile = library_entry;
subentry->library_flag = 0;
subentry->header_read_flag = 0;
subentry->just_syms_flag = 0;
subentry->chain = 0;
- subentry->total_size = member_length;
+ subentry->total_size = content_length;
(*length_loc) = member_length;
@@ -474,6 +502,9 @@ subfile_wanted_p(entry)
int defs = 0;
/* Check for undefined symbols in shared objects */
+ if (sp->sorefs == NULL)
+ continue;
+
for (lsp = sp->sorefs; lsp; lsp = lsp->next) {
type = lsp->nzlist.nlist.n_type;
if ( (type & N_EXT) &&
@@ -590,9 +621,110 @@ read_shared_object (desc, entry)
enter_file_symbols (entry);
entry->strings = 0;
- /* TODO: examine needed shared objects */
+ /*
+ * Load any subsidiary shared objects.
+ */
if (dyn2.ld_need) {
+ struct link_object lobj;
+ off_t offset;
+ struct file_entry *subentry, *prev = NULL;
+
+ subentry = (struct file_entry *)
+ xmalloc(sizeof(struct file_entry));
+ bzero(subentry, sizeof(struct file_entry));
+
+ subentry->superfile = entry;
+
+ offset = (off_t)dyn2.ld_need;
+ while (1) {
+ char *libname, name[MAXPATHLEN]; /*XXX*/
+
+ lseek(desc, offset, L_SET);
+ if (read(desc, &lobj, sizeof(lobj)) != sizeof(lobj)) {
+ fatal_with_file(
+ "premature eof while reading link objects ",
+ entry);
+ }
+ md_swapin_link_object(&lobj, 1);
+ (void)lseek(desc, (off_t)lobj.lo_name, L_SET);
+ (void)read(desc, name, sizeof(name)); /*XXX*/
+ if (lobj.lo_library) {
+ int lo_major = lobj.lo_major;
+ int lo_minor = lobj.lo_minor;
+
+ libname = findshlib(name,
+ &lo_major, &lo_minor, 0);
+ if (libname == NULL)
+ fatal("no shared -l%s.%d.%d available",
+ name, lobj.lo_major, lobj.lo_minor);
+ subentry->filename = libname;
+ subentry->local_sym_name = concat("-l", name, "");
+ } else {
+ subentry->filename = strdup(name);
+ subentry->local_sym_name = strdup(name);
+ }
+ read_file_symbols(subentry);
+
+ if (prev)
+ prev->chain = subentry;
+ else
+ entry->subfiles = subentry;
+ prev = subentry;
+ file_open(entry);
+ if ((offset = (off_t)lobj.lo_next) == 0)
+ break;
+ }
+ }
+#ifdef SUN_COMPAT
+ if (link_mode & SILLYARCHIVE) {
+ char *cp, *sa_name;
+ char armag[SARMAG];
+ int fd;
+ struct file_entry *subentry;
+
+ sa_name = strdup(entry->filename);
+ if (sa_name == NULL)
+ goto out;
+ cp = sa_name + strlen(sa_name) - 1;
+ while (cp > sa_name) {
+ if (!isdigit(*cp) && *cp != '.')
+ break;
+ --cp;
+ }
+ if (cp <= sa_name || *cp != 'o') {
+ /* Not in `libxxx.so.n.m' form */
+ free(sa_name);
+ goto out;
+ }
+
+ *cp = 'a';
+ if ((fd = open(sa_name, O_RDONLY, 0)) < 0)
+ goto out;
+
+ /* Read archive magic */
+ bzero(armag, SARMAG);
+ (void)read(fd, armag, SARMAG);
+ (void)close(fd);
+ if (strncmp(armag, ARMAG, SARMAG) != 0) {
+ error("%s: malformed silly archive",
+ get_file_name(entry));
+ goto out;
+ }
+
+ subentry = (struct file_entry *)
+ xmalloc(sizeof(struct file_entry));
+ bzero(subentry, sizeof(struct file_entry));
+
+ entry->silly_archive = subentry;
+ subentry->superfile = entry;
+ subentry->filename = sa_name;
+ subentry->local_sym_name = sa_name;
+ subentry->library_flag = 1;
+ search_library(file_open(subentry), subentry);
+out:
+ ;
}
+#endif
}
#undef major
@@ -611,7 +743,7 @@ struct file_entry *p;
if (p->search_dynamic_flag == 0)
goto dot_a;
- fname = findshlib(p->filename, &major, &minor);
+ fname = findshlib(p->filename, &major, &minor, 1);
if (fname && (desc = open (fname, O_RDONLY, 0)) > 0) {
p->filename = fname;
diff --git a/gnu/usr.bin/ld/rrs.c b/gnu/usr.bin/ld/rrs.c
index 4be027a..6de17b9 100644
--- a/gnu/usr.bin/ld/rrs.c
+++ b/gnu/usr.bin/ld/rrs.c
@@ -27,7 +27,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: rrs.c,v 1.8 1993/12/02 09:32:26 ache Exp $
+ * $Id: rrs.c,v 1.9 1993/12/04 00:53:00 jkh Exp $
*/
#include <sys/param.h>
@@ -726,6 +726,16 @@ consider_rrs_section_lengths()
rrs_strtab_size += 1 + strlen(sp->name);
if (sp != dynamic_symbol)
sp->rrs_symbolnum = number_of_rrs_symbols++;
+ if (sp->alias) {
+ /*
+ * (sigh) Always allocate space to hold the
+ * indirection. At this point there's not
+ * enough information to decide whether it's
+ * actually needed or not.
+ */
+ number_of_rrs_symbols++;
+ rrs_strtab_size += 1 + strlen(sp->alias->name);
+ }
}
} END_EACH_SYMBOL;
@@ -973,7 +983,17 @@ write_rrs_text()
if (sp->defined > 1) {
/* defined with known type */
- if (sp->defined == N_SIZE) {
+ if (!(link_mode & SHAREABLE) &&
+ sp->alias && sp->alias->defined > 1) {
+ /*
+ * If the target of an indirect symbol has
+ * been defined and we are outputting an
+ * executable, resolve the indirection; it's
+ * no longer needed.
+ */
+ nlp->nz_type = sp->alias->defined;
+ nlp->nz_value = sp->alias->value;
+ } else if (sp->defined == N_SIZE) {
/*
* Make sure this symbol isn't going
* to define anything.
@@ -1001,7 +1021,6 @@ write_rrs_text()
"internal error: %s defined in mysterious way",
sp->name);
-
/* Handle auxialiary type qualifiers */
switch (sp->aux) {
case 0:
@@ -1020,7 +1039,7 @@ write_rrs_text()
break;
default:
fatal(
- "internal error: %s: unsupported other value: %x",
+ "internal error: %s: unsupported other value: %x",
sp->name, sp->aux);
break;
}
@@ -1030,14 +1049,32 @@ write_rrs_text()
strcpy(rrs_strtab + offset, sp->name);
offset += 1 + strlen(sp->name);
+ if (sp->alias) {
+ /*
+ * Write an extra symbol for indirections (possibly
+ * just a dummy).
+ */
+ int t = (nlp->nz_type == N_INDR + N_EXT);
+
+ INCR_NLP(nlp);
+ nlp->nz_type = N_UNDF + t?N_EXT:0;
+ nlp->nz_un.n_strx = offset;
+ nlp->nz_value = 0;
+ nlp->nz_other = 0;
+ nlp->nz_desc = 0;
+ nlp->nz_size = 0;
+ strcpy(rrs_strtab + offset, sp->alias->name);
+ offset += 1 + strlen(sp->alias->name);
+ }
+
INCR_NLP(nlp);
} END_EACH_SYMBOL;
if (MALIGN(offset) != rrs_strtab_size)
fatal(
- "internal error: inconsistent RRS string table length: %d",
- offset);
+ "internal error: inconsistent RRS string table length: %d, expected %d",
+ offset, rrs_strtab_size);
/* Write the symbol table */
if (rrs_symbol_size == sizeof(struct nlist))
@@ -1059,8 +1096,9 @@ write_rrs_text()
for (i = 0, shp = rrs_shobjs; shp; i++, shp = shp->next) {
char *name = shp->entry->local_sym_name;
- if (shp == NULL)
- fatal("internal error: shp == NULL");
+ if (i >= number_of_shobjs)
+ fatal("internal error: # of link objects exceeds %d",
+ number_of_shobjs);
lo[i].lo_name = pos;
lo[i].lo_major = shp->entry->lib_major;
@@ -1075,10 +1113,11 @@ write_rrs_text()
pos += 1 + strlen(name);
lo[i].lo_next = (i == number_of_shobjs - 1) ? 0 :
(rrs_dyn2.ld_need + (i+1)*sizeof(struct link_object));
-
}
- if (shp != NULL)
- fatal("internal error: shp != NULL");
+
+ if (i < number_of_shobjs)
+ fatal("internal error: # of link objects less then expected %d",
+ number_of_shobjs);
md_swapout_link_object(lo, number_of_shobjs);
mywrite(lo, number_of_shobjs, sizeof(struct link_object), outdesc);
diff --git a/gnu/usr.bin/ld/shlib.c b/gnu/usr.bin/ld/shlib.c
index b6cb74e..dcca01f 100644
--- a/gnu/usr.bin/ld/shlib.c
+++ b/gnu/usr.bin/ld/shlib.c
@@ -1,5 +1,5 @@
/*
- * $Id: shlib.c,v 1.4 1993/12/02 00:56:40 jkh Exp $
+ * $Id: shlib.c,v 1.5 1993/12/04 00:53:02 jkh Exp $
*/
#include <sys/param.h>
@@ -11,16 +11,21 @@
#include <sys/time.h>
#include <fcntl.h>
#include <string.h>
+#include <ctype.h>
#include <dirent.h>
#include <a.out.h>
#include "ld.h"
+#ifdef SUNOS4
+char *strsep();
+#endif
+
/*
* Standard directories to search for files specified by -l.
*/
#ifndef STANDARD_SEARCH_DIRS
-#define STANDARD_SEARCH_DIRS "/usr/lib", "/usr/local/lib"
+#define STANDARD_SEARCH_DIRS "/usr/lib", "/usr/X386/lib", "/usr/local/lib"
#endif
char *standard_search_dirs[] = {
@@ -132,9 +137,10 @@ int n1, n2;
#undef minor
char *
-findshlib(name, majorp, minorp)
+findshlib(name, majorp, minorp, do_dot_a)
char *name;
int *majorp, *minorp;
+int do_dot_a;
{
int dewey[MAXDEWEY];
int ndewey;
@@ -154,6 +160,7 @@ int *majorp, *minorp;
for (i = 0; i < n_search_dirs; i++) {
DIR *dd = opendir(search_dirs[i]);
struct dirent *dp;
+ int found_dot_a = 0;
if (dd == NULL)
continue;
@@ -161,6 +168,16 @@ int *majorp, *minorp;
while ((dp = readdir(dd)) != NULL) {
int n, j, might_take_it = 0;
+ if (do_dot_a && path == NULL &&
+ dp->d_namlen == len + 2 &&
+ strncmp(dp->d_name, lname, len) == 0 &&
+ (dp->d_name+len)[0] == '.' &&
+ (dp->d_name+len)[1] == 'a') {
+
+ path = concat(search_dirs[i], "/", dp->d_name);
+ found_dot_a = 1;
+ }
+
if (dp->d_namlen < len + 4)
continue;
if (strncmp(dp->d_name, lname, len) != 0)
@@ -171,6 +188,12 @@ int *majorp, *minorp;
if ((n = getdewey(tmp, dp->d_name+len+4)) == 0)
continue;
+ if (major != -1 && found_dot_a) { /* XXX */
+ free(path);
+ path = NULL;
+ found_dot_a = 0;
+ }
+
if (major == -1 && minor == -1) {
might_take_it = 1;
} else if (major != -1 && minor == -1) {
@@ -192,12 +215,19 @@ int *majorp, *minorp;
if (path)
free(path);
path = concat(search_dirs[i], "/", dp->d_name);
+ found_dot_a = 0;
bcopy(tmp, dewey, sizeof(dewey));
ndewey = n;
*majorp = dewey[0];
*minorp = dewey[1];
}
closedir(dd);
+
+ if (found_dot_a)
+ /*
+ * There's a .a archive here.
+ */
+ return path;
}
return path;
diff --git a/gnu/usr.bin/ld/sparc/md-static-funcs.c b/gnu/usr.bin/ld/sparc/md-static-funcs.c
index 99e6240..2672cb5 100644
--- a/gnu/usr.bin/ld/sparc/md-static-funcs.c
+++ b/gnu/usr.bin/ld/sparc/md-static-funcs.c
@@ -1,5 +1,7 @@
/*
+ * $Id: md-static-funcs.c,v 1.2 1993/12/08 10:28:56 pk Exp $
+ *
* Simple SPARC relocations for the benefit of self-relocation of ld.so
* avoiding the use of global variables (ie. reloc_bitshift[] et. al.).
* Only types supported are RELOC_32 and RELOC_RELATIVE.
diff --git a/gnu/usr.bin/ld/sparc/md.c b/gnu/usr.bin/ld/sparc/md.c
index bfe184b..3ae54e3 100644
--- a/gnu/usr.bin/ld/sparc/md.c
+++ b/gnu/usr.bin/ld/sparc/md.c
@@ -1,5 +1,33 @@
/*
- * $Id: md.c,v 1.3 1993/11/22 19:05:30 jkh Exp $
+ * Copyright (c) 1993 Paul Kranenburg
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Paul Kranenburg.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: md.c,v 1.6 1993/12/08 10:29:02 pk Exp $
*/
#include <sys/param.h>
@@ -181,9 +209,14 @@ int type;
#if 1
/*
* This wouldn't be strictly necessary - we could record the
- * location value "in situ" in stead of in the r_addend field -
+ * relocation value "in situ" in stead of in the r_addend field -
* but we are being Sun compatible here. Besides, Sun's ld.so
- * has a bug that prevents it from handling this alternate method
+ * has a bug that prevents it from handling this alternate method.
+ *
+ * IT WOULD BE REALLY NICE TO HAVE CONSISTENCY THROUGHOUT THE ENTIRE
+ * RELOCATION PROCESS, ie. using `r_addend' for storing all partially
+ * completed relocations, in stead of mixing them in both relocation
+ * records and in the segment data.
*/
if (RELOC_PCREL_P(rp))
r->r_addend -= pc_relocation;
diff --git a/gnu/usr.bin/ld/warnings.c b/gnu/usr.bin/ld/warnings.c
index e191074..1e47cfd 100644
--- a/gnu/usr.bin/ld/warnings.c
+++ b/gnu/usr.bin/ld/warnings.c
@@ -1,5 +1,5 @@
/*
- * $Id: warnings.c,v 1.4 1993/11/05 12:45:25 pk Exp $
+ * $Id: warnings.c,v 1.2 1993/11/09 04:19:06 paul Exp $
*/
#include <sys/param.h>
@@ -9,6 +9,7 @@
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/time.h>
+#include <sys/errno.h>
#include <fcntl.h>
#include <ar.h>
#include <ranlib.h>
@@ -112,10 +113,8 @@ fatal_with_file (fmt, entry, va_alist)
*/
void
perror_name (name)
- char *name;
+ char *name;
{
- extern int errno, sys_nerr;
- extern char *sys_errlist[];
char *s;
if (errno < sys_nerr)
@@ -133,8 +132,6 @@ void
perror_file (entry)
struct file_entry *entry;
{
- extern int errno, sys_nerr;
- extern char *sys_errlist[];
char *s;
if (errno < sys_nerr)
@@ -165,19 +162,17 @@ print_symbols(outfile)
for (i = 0; i < TABSIZE; i++) {
register symbol *sp;
for (sp = symtab[i]; sp; sp = sp->link) {
- if (sp->defined == 1)
+ if (sp->defined == (N_UNDF|N_EXT))
fprintf(outfile, " %s: common, length %#x\n",
sp->name, sp->max_common_size);
- if ( sp->referenced) {
- if (sp->defined)
- fprintf(outfile, " %s: %#x %#x\n",
- sp->name, sp->value, sp->size);
- else
- fprintf(outfile, " %s: undefined\n",
- sp->name);
- } else
+ if (!sp->referenced)
fprintf(outfile, " %s: unreferenced\n",
- sp->name);
+ sp->name);
+ else if (!sp->defined)
+ fprintf(outfile, " %s: undefined\n", sp->name);
+ else
+ fprintf(outfile, " %s: %#x, size %#x\n",
+ sp->name, sp->value, sp->size);
}
}
@@ -191,7 +186,7 @@ describe_file_sections(entry, outfile)
{
fprintf(outfile, " ");
print_file_name(entry, outfile);
- if (entry->just_syms_flag)
+ if (entry->just_syms_flag || entry->is_dynamic)
fprintf(outfile, " symbols only\n", 0);
else
fprintf(outfile, " text %x(%x), data %x(%x), bss %x(%x) hex\n",
@@ -659,15 +654,17 @@ do_file_warnings (entry, outfile)
if (list_multiple_defs && g->multiply_defined) {
errfmt = "Definition of symbol %s (multiply defined)";
switch (s->n_type) {
+
case N_TEXT | N_EXT:
line_number = address_to_line (s->n_value, text_scan);
file_name = text_scan[0].filename;
break;
+
case N_DATA | N_EXT:
line_number = address_to_line (s->n_value, data_scan);
file_name = data_scan[0].filename;
break;
-#if 0
+
case N_SETA | N_EXT:
case N_SETT | N_EXT:
case N_SETD | N_EXT:
@@ -676,16 +673,16 @@ do_file_warnings (entry, outfile)
continue;
errfmt = "First set element definition of symbol %s (multiply defined)";
break;
-#endif
+
default:
- /* Don't print out multiple defs
- at references.*/
+printf("Multiple def: %s, type %#x\n", g->name, s->n_type);
+ /* Don't print out multiple defs at references.*/
continue;
}
- } else if (BIT_SET_P (nlist_bitvector, i))
+ } else if (BIT_SET_P (nlist_bitvector, i)) {
continue;
- else if (list_unresolved_refs && !g->defined && !g->so_defined) {
+ } else if (list_unresolved_refs && !g->defined && !g->so_defined) {
if (g->undef_refs >= MAX_UREFS_PRINTED)
continue;
OpenPOWER on IntegriCloud