summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin')
-rw-r--r--gnu/usr.bin/ld/i386/md.c47
-rw-r--r--gnu/usr.bin/ld/i386/md.h89
-rw-r--r--gnu/usr.bin/ld/i386/mdprologue.S64
-rw-r--r--gnu/usr.bin/ld/ld.c380
-rw-r--r--gnu/usr.bin/ld/ld.h40
-rw-r--r--gnu/usr.bin/ld/lib.c27
-rw-r--r--gnu/usr.bin/ld/rrs.c395
-rw-r--r--gnu/usr.bin/ld/rtld/Makefile14
-rw-r--r--gnu/usr.bin/ld/rtld/malloc.c5
-rw-r--r--gnu/usr.bin/ld/rtld/rtld.c110
-rw-r--r--gnu/usr.bin/ld/shlib.c4
-rw-r--r--gnu/usr.bin/ld/sparc/md.h12
-rw-r--r--gnu/usr.bin/ld/sparc/mdprologue.S6
-rw-r--r--gnu/usr.bin/ld/warnings.c68
14 files changed, 706 insertions, 555 deletions
diff --git a/gnu/usr.bin/ld/i386/md.c b/gnu/usr.bin/ld/i386/md.c
index 40d9916..07271fc 100644
--- a/gnu/usr.bin/ld/i386/md.c
+++ b/gnu/usr.bin/ld/i386/md.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: md.c,v 1.10 1994/06/15 22:40:44 rich Exp $
+ * $Id: md.c,v 1.11 1994/12/23 22:31:12 nate Exp $
*/
#include <sys/param.h>
@@ -58,9 +58,10 @@ unsigned char *addr;
return get_short(addr);
case 2:
return get_long(addr);
+ default:
+ errx(1, "Unsupported relocation size: %x",
+ RELOC_TARGET_SIZE(rp));
}
- errx(1, "Unsupported relocation size: %x", RELOC_TARGET_SIZE(rp));
- return 0;
}
/*
@@ -76,15 +77,17 @@ int relocatable_output;
switch (RELOC_TARGET_SIZE(rp)) {
case 0:
put_byte(addr, relocation);
- return;
+ break;
case 1:
put_short(addr, relocation);
- return;
+ break;
case 2:
put_long(addr, relocation);
- return;
+ break;
+ default:
+ errx(1, "Unsupported relocation size: %x",
+ RELOC_TARGET_SIZE(rp));
}
- errx(1, "Unsupported relocation size: %x", RELOC_TARGET_SIZE(rp));
}
/*
@@ -257,7 +260,7 @@ int magic, flags;
#endif
/* TEXT_START depends on the value of outheader.a_entry. */
- if (!(link_mode & SHAREABLE)) /*WAS: if (entry_symbol) */
+ if (!(link_mode & SHAREABLE))
hp->a_entry = PAGSIZ;
}
#endif /* RTLD */
@@ -305,15 +308,15 @@ int n;
for (; n; n--, r++) {
r->r_address = md_swap_long(r->r_address);
bits = ((int *)r)[1];
- r->r_symbolnum = md_swap_long(bits & 0xffffff00);
+ r->r_symbolnum = md_swap_long(bits) & 0x00ffffff;
r->r_pcrel = (bits & 1);
- r->r_length = ((bits >> 1) & 3);
- r->r_extern = ((bits >> 3) & 1);
- r->r_baserel = ((bits >> 4) & 1);
- r->r_jmptable = ((bits >> 5) & 1);
- r->r_relative = ((bits >> 6) & 1);
+ r->r_length = (bits >> 1) & 3;
+ r->r_extern = (bits >> 3) & 1;
+ r->r_baserel = (bits >> 4) & 1;
+ r->r_jmptable = (bits >> 5) & 1;
+ r->r_relative = (bits >> 6) & 1;
#ifdef N_SIZE
- r->r_copy = ((bits >> 7) & 1);
+ r->r_copy = (bits >> 7) & 1;
#endif
}
}
@@ -327,15 +330,15 @@ int n;
for (; n; n--, r++) {
r->r_address = md_swap_long(r->r_address);
- bits = (md_swap_long(r->r_symbolnum) & 0xffffff00);
+ bits = md_swap_long(r->r_symbolnum) & 0xffffff00;
bits |= (r->r_pcrel & 1);
- bits |= ((r->r_length << 1) & 6);
- bits |= ((r->r_extern << 3) & 8);
- bits |= ((r->r_baserel << 4) & 0x10);
- bits |= ((r->r_jmptable << 5) & 0x20);
- bits |= ((r->r_relative << 6) & 0x40);
+ bits |= (r->r_length & 3) << 1;
+ bits |= (r->r_extern & 1) << 3;
+ bits |= (r->r_baserel & 1) << 4;
+ bits |= (r->r_jmptable & 1) << 5;
+ bits |= (r->r_relative & 1) << 6;
#ifdef N_SIZE
- bits |= ((r->r_copy << 7) & 0x80);
+ bits |= (r->r_copy & 1) << 7;
#endif
((int *)r)[1] = bits;
}
diff --git a/gnu/usr.bin/ld/i386/md.h b/gnu/usr.bin/ld/i386/md.h
index 89c1213..da5283d 100644
--- a/gnu/usr.bin/ld/i386/md.h
+++ b/gnu/usr.bin/ld/i386/md.h
@@ -27,14 +27,12 @@
* (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.10 1994/06/15 22:40:46 rich Exp $
+ * $Id: md.h,v 1.11 1994/12/23 22:31:14 nate Exp $
*/
#if defined(CROSS_LINKER) && defined(XHOST) && XHOST==sparc
-
#define NEED_SWAP
-
#endif
#define MAX_ALIGNMENT (sizeof (long))
@@ -144,6 +142,34 @@ typedef struct jmpslot {
#ifdef CROSS_LINKER
+#define get_byte(p) ( ((unsigned char *)(p))[0] )
+
+#define get_short(p) ( ( ((unsigned char *)(p))[0] << 8) | \
+ ( ((unsigned char *)(p))[1] ) \
+ )
+
+#define get_long(p) ( ( ((unsigned char *)(p))[0] << 24) | \
+ ( ((unsigned char *)(p))[1] << 16) | \
+ ( ((unsigned char *)(p))[2] << 8 ) | \
+ ( ((unsigned char *)(p))[3] ) \
+ )
+
+#define put_byte(p, v) { ((unsigned char *)(p))[0] = ((unsigned long)(v)); }
+
+#define put_short(p, v) { ((unsigned char *)(p))[0] = \
+ ((((unsigned long)(v)) >> 8) & 0xff); \
+ ((unsigned char *)(p))[1] = \
+ ((((unsigned long)(v)) ) & 0xff); }
+
+#define put_long(p, v) { ((unsigned char *)(p))[0] = \
+ ((((unsigned long)(v)) >> 24) & 0xff); \
+ ((unsigned char *)(p))[1] = \
+ ((((unsigned long)(v)) >> 16) & 0xff); \
+ ((unsigned char *)(p))[2] = \
+ ((((unsigned long)(v)) >> 8) & 0xff); \
+ ((unsigned char *)(p))[3] = \
+ ((((unsigned long)(v)) ) & 0xff); }
+
#ifdef NEED_SWAP
/* Define IO byte swapping routines */
@@ -177,67 +203,11 @@ void md_swapout_jmpslot __P((jmpslot_t *, int));
#define md_swap_long(x) ( (((x) >> 24) & 0xff ) | (((x) >> 8 ) & 0xff00 ) | \
(((x) << 8 ) & 0xff0000) | (((x) << 24) & 0xff000000))
-#define get_byte(p) ( ((unsigned char *)(p))[0] )
-
-#define get_short(p) ( ( ((unsigned char *)(p))[1] << 8) | \
- ( ((unsigned char *)(p))[0] ) \
- )
-#define get_long(p) ( ( ((unsigned char *)(p))[3] << 24) | \
- ( ((unsigned char *)(p))[2] << 16) | \
- ( ((unsigned char *)(p))[1] << 8 ) | \
- ( ((unsigned char *)(p))[0] ) \
- )
-
-#define put_byte(p, v) { ((unsigned char *)(p))[0] = ((unsigned long)(v)); }
-
-#define put_short(p, v) { ((unsigned char *)(p))[1] = \
- ((((unsigned long)(v)) >> 8) & 0xff); \
- ((unsigned char *)(p))[0] = \
- ((((unsigned long)(v)) ) & 0xff); }
-
-#define put_long(p, v) { ((unsigned char *)(p))[3] = \
- ((((unsigned long)(v)) >> 24) & 0xff); \
- ((unsigned char *)(p))[2] = \
- ((((unsigned long)(v)) >> 16) & 0xff); \
- ((unsigned char *)(p))[1] = \
- ((((unsigned long)(v)) >> 8) & 0xff); \
- ((unsigned char *)(p))[0] = \
- ((((unsigned long)(v)) ) & 0xff); }
-
#else /* We need not swap, but must pay attention to alignment: */
#define md_swap_short(x) (x)
#define md_swap_long(x) (x)
-#define get_byte(p) ( ((unsigned char *)(p))[0] )
-
-#define get_short(p) ( ( ((unsigned char *)(p))[0] << 8) | \
- ( ((unsigned char *)(p))[1] ) \
- )
-
-#define get_long(p) ( ( ((unsigned char *)(p))[0] << 24) | \
- ( ((unsigned char *)(p))[1] << 16) | \
- ( ((unsigned char *)(p))[2] << 8 ) | \
- ( ((unsigned char *)(p))[3] ) \
- )
-
-
-#define put_byte(p, v) { ((unsigned char *)(p))[0] = ((unsigned long)(v)); }
-
-#define put_short(p, v) { ((unsigned char *)(p))[0] = \
- ((((unsigned long)(v)) >> 8) & 0xff); \
- ((unsigned char *)(p))[1] = \
- ((((unsigned long)(v)) ) & 0xff); }
-
-#define put_long(p, v) { ((unsigned char *)(p))[0] = \
- ((((unsigned long)(v)) >> 24) & 0xff); \
- ((unsigned char *)(p))[1] = \
- ((((unsigned long)(v)) >> 16) & 0xff); \
- ((unsigned char *)(p))[2] = \
- ((((unsigned long)(v)) >> 8) & 0xff); \
- ((unsigned char *)(p))[3] = \
- ((((unsigned long)(v)) ) & 0xff); }
-
#endif /* NEED_SWAP */
#else /* Not a cross linker: use native */
@@ -254,4 +224,3 @@ void md_swapout_jmpslot __P((jmpslot_t *, int));
#define put_long(where,what) (*(long *)(where) = (what))
#endif /* CROSS_LINKER */
-
diff --git a/gnu/usr.bin/ld/i386/mdprologue.S b/gnu/usr.bin/ld/i386/mdprologue.S
index 43640c6..1de0f72 100644
--- a/gnu/usr.bin/ld/i386/mdprologue.S
+++ b/gnu/usr.bin/ld/i386/mdprologue.S
@@ -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: mdprologue.S,v 1.4 1994/06/15 22:40:49 rich Exp $
+ * $Id: mdprologue.S,v 1.7 1994/12/04 07:42:44 mycroft Exp $
*/
/*
@@ -35,7 +35,6 @@
*/
#include <sys/syscall.h>
-#define LCALL(x,y) .byte 0x9a ; .long y; .word x
.text
.globl _binder, _binder_entry
@@ -46,76 +45,49 @@
_rtl: # crt0 calls us here
pushl %ebp # Allocate stack frame
- movl %esp, %ebp
+ movl %esp,%ebp
pushl %ebx
+
call 1f # PIC function prologue
1:
popl %ebx
- addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
+ addl $_GLOBAL_OFFSET_TABLE_+[.-1b],%ebx
- movl 12(%ebp), %eax # Extract data from interface structure
+ movl 12(%ebp),%eax # Extract data from interface structure
movl (%eax),%eax # base address of ld.so (first field)
# setup arguments for rtld()
- movl (%ebx), %ecx # 1st entry in GOT is our __DYNAMIC
- addl %eax, %ecx # add load address
+ movl (%ebx),%ecx # 1st entry in GOT is our __DYNAMIC
+ addl %eax,%ecx # add load address
pushl %ecx # 3rd arg
pushl 12(%ebp) # 2nd arg == &crt.
pushl 8(%ebp) # 1st arg == version
- addl _rtld@GOT(%ebx), %eax # relocate address of function
+ addl _rtld@GOT(%ebx),%eax # relocate address of function
call %eax # _rtld(version, crtp, DYNAMIC)
addl $12,%esp # pop arguments
- movl -4(%ebp), %ebx # restore %ebx
- leave # remove stack frame,
- ret # let's rock
+ popl %ebx
+ leave # remove stack frame
+ ret
# First call to a procedure generally comes through here for
# binding.
_binder_entry:
pushl %ebp # setup a stack frame
- movl %esp, %ebp
+ movl %esp,%ebp
pusha # save all regs
- movl $0, %eax # clear
- movl 4(%ebp), %esi # return address in PLT
- movw (%esi), %ax # get hold of relocation number
- subl $6, %esi # make it point to the jmpslot
+ xorl %eax,%eax # clear
+ movl 4(%ebp),%esi # return address in PLT
+ movw (%esi),%ax # get hold of relocation number
+ subl $6,%esi # make it point to the jmpslot
pushl %eax # pushd arguments
pushl %esi #
call _binder@PLT # _binder(rpc, index)
- addl $8, %esp # pop arguments
- movl %eax, 4(%ebp) # return value from _binder() == actual
+ addl $8,%esp # pop arguments
+ movl %eax,4(%ebp) # return value from _binder() == actual
# address of function
popa # restore regs
leave # remove our stack frame
ret
-
- # Special system call stubs which return real and effective user and group
- # id's. Saves overhead of making separate calls for each.
- # !! Relies on compatability option in BSD 4.three-and-a-half
-
- .globl _getreuid, _getregid
-_getreuid:
- lea SYS_getuid, %eax
- LCALL(7,0)
- jc out
- movl 4(%esp), %ecx # get 1st arg
- movl %eax, (%ecx) # put value in it
- movl 8(%esp), %ecx # same for 2nd arg
- movl %edx, (%ecx) #
- ret # done
-
-_getregid:
- lea SYS_getgid, %eax
- LCALL(7,0)
- jc out
- movl 4(%esp), %ecx # get 1st arg
- movl %eax, (%ecx) # put value in it
- movl 8(%esp), %ecx # same for 2nd arg
- movl %edx, (%ecx) #
- ret # done
-
-out: jmp cerror@PLT # Call common error routine
-
diff --git a/gnu/usr.bin/ld/ld.c b/gnu/usr.bin/ld/ld.c
index 5d713a0..14f7cd0 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.22 1994/06/15 22:39:40 rich Exp $
+ * $Id: ld.c,v 1.23 1994/12/23 22:30:37 nate Exp $
*/
/* Define how to initialize system-dependent header fields. */
@@ -135,7 +135,7 @@ 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. */
+FILE *outstream; /* Output file descriptor. */
struct exec outheader; /* Output file header. */
int magic; /* Output file magic. */
int oldmagic;
@@ -183,11 +183,15 @@ int undefined_shobj_sym_count; /* # of undefined symbols referenced
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 undefined_weak_sym_count; /* # of weak symbols referenced and
+ not defined. */
+#if notused
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.
*/
+#endif
int global_alias_count; /* # of aliased symbols */
int set_symbol_count; /* # of N_SET* symbols. */
int set_vector_count; /* # of set vectors in output. */
@@ -346,9 +350,6 @@ main(argc, argv)
/* Create the symbols `etext', `edata' and `end'. */
symtab_init(relocatable_output);
- /* Prepare for the run-time linking support. */
- init_rrs();
-
/*
* Determine whether to count the header as part of the text size,
* and initialize the text size accordingly. This depends on the kind
@@ -386,7 +387,7 @@ main(argc, argv)
* Print error messages for any missing symbols, for any warning
* symbols, and possibly multiple definitions
*/
- make_executable = do_warnings(stderr);
+ make_executable &= do_warnings(stderr);
/* Print a map, if requested. */
if (write_map)
@@ -1344,7 +1345,7 @@ enter_global_ref(lsp, name, entry)
int olddef = sp->defined;
int com = sp->defined && sp->common_size;
- if (type == (N_INDR | N_EXT)) {
+ if (type == (N_INDR | N_EXT) && !olddef) {
sp->alias = getsym(entry->strings + (lsp + 1)->nzlist.nz_strx);
if (sp == sp->alias) {
warnx("%s: %s is alias for itself",
@@ -1356,6 +1357,10 @@ enter_global_ref(lsp, name, entry)
} else {
global_alias_count++;
}
+#if 0
+ if (sp->flags & GS_REFERENCED)
+ sp->alias->flags |= GS_REFERENCED;
+#endif
}
if (entry->flags & E_DYNAMIC) {
@@ -1383,6 +1388,8 @@ enter_global_ref(lsp, name, entry)
/*
* This is an ex common...
*/
+ if (com)
+ common_defined_global_count--;
sp->common_size = 0;
sp->defined = 0;
}
@@ -1428,32 +1435,72 @@ enter_global_ref(lsp, name, entry)
return;
}
-#ifdef N_SIZE
+ if (olddef && N_ISWEAK(&nzp->nlist) && !(sp->flags & GS_WEAK)) {
+#ifdef DEBUG
+ printf("%s: not overridden by weak symbol from %s\n",
+ sp->name, get_file_name(entry));
+#endif
+ return;
+ }
+
if (type == (N_SIZE | N_EXT)) {
+
if (relocatable_output && nzp->nz_value != 0 && sp->size == 0)
size_sym_count++;
if (sp->size < nzp->nz_value)
sp->size = nzp->nz_value;
- } else
-#endif
- if (type != (N_UNDF | N_EXT) || nzp->nz_value) {
+
+ } else if (type != (N_UNDF | N_EXT) || nzp->nz_value) {
/*
* Set `->defined' here, so commons and undefined globals
* can be counted correctly.
*/
- if (!sp->defined || sp->defined == (N_UNDF | N_EXT))
+ if (!sp->defined || sp->defined == (N_UNDF | N_EXT)) {
sp->defined = type;
+ }
- if (oldref && !olddef)
+ if ((sp->flags & GS_WEAK) && !N_ISWEAK(&nzp->nlist)) {
+ /*
+ * Upgrade an existing weak definition.
+ * We fake it by pretending the symbol is undefined;
+ * must undo any common fiddling, however.
+ */
+ if (!oldref)
+ errx(1, "internal error: enter_glob_ref: "
+ "weak symbol not referenced");
+ if (!olddef && !com)
+ undefined_weak_sym_count--;
+ undefined_global_sym_count++;
+ sp->defined = type;
+ sp->flags &= ~GS_WEAK;
+ olddef = 0;
+ if (com)
+ common_defined_global_count--;
+ com = 0;
+ sp->common_size = 0;
+ }
+ if (oldref && !olddef) {
/*
* It used to be undefined and we're defining it.
*/
undefined_global_sym_count--;
- if (undefined_global_sym_count < 0)
- errx(1,
- "internal error: enter_glob_ref: undefined_global_sym_count = %d",
- undefined_global_sym_count);
+ if (sp->flags & GS_WEAK)
+ /* Used to be a weak reference */
+ undefined_weak_sym_count--;
+ if (undefined_global_sym_count < 0 ||
+ undefined_weak_sym_count < 0)
+ errx(1, "internal error: enter_glob_ref: "
+ "undefined_global_sym_count = %d, "
+ "undefined_weak_sym_count = %d",
+ undefined_global_sym_count,
+ undefined_weak_sym_count);
+
+ }
+
+ if (N_ISWEAK(&nzp->nlist))
+ /* The definition is weak */
+ sp->flags |= GS_WEAK;
if (!olddef && type == (N_UNDF | N_EXT) && nzp->nz_value) {
/*
@@ -1479,13 +1526,18 @@ enter_global_ref(lsp, name, entry)
if (SET_ELEMENT_P(type) && (!olddef || com))
set_vector_count++;
- } else if (!oldref && !com)
+ } else if (!oldref && !com) {
/*
* An unreferenced symbol can already be defined
* as common by shared objects.
*/
undefined_global_sym_count++;
-
+ if (N_ISWEAK(&nzp->nlist)) {
+ /* The reference is weak */
+ sp->flags |= GS_WEAK;
+ undefined_weak_sym_count++;
+ }
+ }
if (sp == end_symbol && (entry->flags & E_JUST_SYMS) &&
!T_flag_specified)
@@ -1495,8 +1547,8 @@ enter_global_ref(lsp, name, entry)
register char *reftype;
switch (type & N_TYPE) {
case N_UNDF:
- reftype = nzp->nz_value?
- "defined as common":"referenced";
+ reftype = nzp->nz_value
+ ? "defined as common" : "referenced";
break;
case N_ABS:
@@ -1515,12 +1567,21 @@ enter_global_ref(lsp, name, entry)
reftype = "defined in BSS section";
break;
+ case N_INDR:
+ reftype = "alias";
+ break;
+
+ case N_SIZE:
+ reftype = "size spec";
+ break;
+
default:
reftype = "I don't know this type";
break;
}
- fprintf(stderr, "symbol %s %s in ", sp->name, reftype);
+ fprintf(stderr, "symbol %s %s%s in ", sp->name,
+ (N_ISWEAK(&nzp->nlist))?"weakly ":"", reftype);
print_file_name (entry, stderr);
fprintf(stderr, "\n");
}
@@ -1707,17 +1768,20 @@ printf("set_sect_start = %#x, set_sect_size = %#x\n",
}
if (relocatable_output)
- /* We write out the original N_SET* symbols */
+ /* We write out the original N_SIZE symbols */
global_sym_count += size_sym_count;
#ifdef DEBUG
printf(
-"global symbols %d (defined %d, undefined %d, aliases %d, warnings 2 * %d), \
-locals: %d, debug symbols: %d, set_symbols %d\n",
+"global symbols %d "
+"(defined %d, undefined %d, weak %d, aliases %d, warnings 2 * %d, "
+"size symbols %d)\ncommons %d, locals: %d, debug symbols: %d, set_symbols %d\n",
global_sym_count,
defined_global_sym_count, undefined_global_sym_count,
- global_alias_count, warn_sym_count,
- local_sym_count, debugger_sym_count, set_symbol_count);
+ undefined_weak_sym_count,
+ global_alias_count, warn_sym_count, size_sym_count,
+ common_defined_global_count, local_sym_count,
+ debugger_sym_count, set_symbol_count);
#endif
}
@@ -1738,6 +1802,7 @@ digest_pass1()
* definition find this way.
*/
FOR_EACH_SYMBOL(i, sp) {
+ symbol *spsave;
struct localsymbol *lsp;
int defs = 0;
@@ -1792,6 +1857,7 @@ digest_pass1()
* of this set vector.
*/
bzero(&reloc, sizeof(reloc));
+ RELOC_INIT_SEGMENT_RELOC(&reloc);
RELOC_ADDRESS(&reloc) =
setv_fill_count * sizeof(long);
alloc_rrs_segment_reloc(NULL, &reloc);
@@ -1801,15 +1867,18 @@ digest_pass1()
&& (type & N_TYPE) != N_FN
&& (type & N_TYPE) != N_SIZE) {
/* non-common definition */
- if (defs++ && sp->value != p->n_value
- && entry_symbol/*XXX*/) {
+ if (!N_ISWEAK(p))
+ ++defs;
+ if (defs > 1) {
sp->mult_defs = 1;
multiple_def_count++;
+ } else if (!N_ISWEAK(p) ||
+ (!sp->def_lsp && !sp->common_size)) {
+ sp->def_lsp = lsp;
+ lsp->entry->flags |= E_SYMBOLS_USED;
+ sp->defined = type;
+ sp->aux = N_AUX(p);
}
- sp->def_lsp = lsp;
- lsp->entry->flags |= E_SYMBOLS_USED;
- sp->defined = type;
- sp->aux = N_AUX(p);
}
}
@@ -1846,6 +1915,7 @@ digest_pass1()
continue;
}
+ spsave=sp;
again:
for (lsp = sp->sorefs; lsp; lsp = lsp->next) {
register struct nlist *p = &lsp->nzlist.nlist;
@@ -1858,31 +1928,41 @@ digest_pass1()
sp->so_defined = type;
sp->aux = N_AUX(p);
if (lsp->entry->flags & E_SECONDCLASS)
+ /* Keep looking for something better */
continue;
- lsp->entry->flags |= E_SYMBOLS_USED;
- if (sp->flags & GS_REFERENCED)
- undefined_global_sym_count--;
- else
- sp->flags |= GS_REFERENCED;
+ if (N_ISWEAK(p))
+ /* Keep looking for something better */
+ continue;
+ break;
+ }
+ }
+ if (sp->def_lsp) {
#ifdef DEBUG
-printf("shr: %s gets defined to %x with value %x\n", sp->name, type, sp->value);
+printf("pass1: SO definition for %s, type %x in %s at %#x\n",
+ sp->name, sp->so_defined, get_file_name(sp->def_lsp->entry),
+ sp->def_lsp->nzlist.nz_value);
#endif
- if (undefined_global_sym_count < 0)
- errx(1,
- "internal error: digest_pass1,2: %s: undefined_global_sym_count = %d",
+ sp->def_lsp->entry->flags |= E_SYMBOLS_USED;
+ if (sp->flags & GS_REFERENCED)
+ undefined_global_sym_count--;
+ else
+ sp->flags |= GS_REFERENCED;
+ if (undefined_global_sym_count < 0)
+ errx(1, "internal error: digest_pass1,2: "
+ "%s: undefined_global_sym_count = %d",
sp->name, undefined_global_sym_count);
- if (sp->alias && !(sp->alias->flags & GS_REFERENCED)) {
- sp = sp->alias;
- goto again;
- }
- break;
+ if (sp->alias &&
+ !(sp->alias->flags & GS_REFERENCED)) {
+ sp = sp->alias;
+ goto again;
}
}
+ sp=spsave;
} END_EACH_SYMBOL;
if (setv_fill_count != set_sect_size/sizeof(long))
- errx(1, "internal error: allocated set symbol space (%d) \
-doesn't match actual (%d)",
+ errx(1, "internal error: allocated set symbol space (%d) "
+ "doesn't match actual (%d)",
set_sect_size/sizeof(long), setv_fill_count);
}
@@ -1987,7 +2067,7 @@ consider_relocation(entry, dataseg)
lsp = &entry->symbols[reloc->r_symbolnum];
sp = lsp->symbol;
if (sp == NULL)
- errx(1, "%s: internal error, sp==NULL",
+ errx(1, "%s: bogus relocation record",
get_file_name(entry));
if (sp->alias)
@@ -2031,7 +2111,8 @@ consider_relocation(entry, dataseg)
alloc_rrs_cpy_reloc(entry, sp);
sp->defined = N_SIZE;
- } else if (!sp->defined && sp->common_size == 0)
+ } else if (!sp->defined && sp->common_size == 0 &&
+ sp->so_defined)
alloc_rrs_reloc(entry, sp);
} else {
@@ -2217,14 +2298,27 @@ digest_pass2()
continue;
if (sp->alias &&
- (relocatable_output || building_shared_object ||
- (sp->alias->defined && !sp->alias->so_defined)))
+ (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.
*/
+ if (!sp->defined) {
+ /*
+ * Change aliased symbol's definition too.
+ * These things happen if shared object commons
+ * or data is going into our symbol table.
+ */
+ if (sp->so_defined != (N_INDR+N_EXT))
+ warnx( "pass2: %s: alias isn't",
+ sp->name);
+ sp->defined = sp->so_defined;
+ sp->so_defined = 0;
+ }
defined_global_sym_count++;
+ }
if ((sp->defined & N_TYPE) == N_SETV) {
/*
@@ -2253,6 +2347,7 @@ digest_pass2()
struct relocation_info reloc;
bzero(&reloc, sizeof(reloc));
+ RELOC_INIT_SEGMENT_RELOC(&reloc);
RELOC_ADDRESS(&reloc) =
(1 + i + length_word_index) *
sizeof(long)
@@ -2284,7 +2379,11 @@ digest_pass2()
sp->value = sp->def_lsp->nzlist.nz_value;
if (sp->so_defined &&
(sp->def_lsp->entry->flags & E_SECONDCLASS))
+ /* Flag second-hand definitions */
undefined_global_sym_count++;
+ if (sp->flags & GS_TRACE)
+ printf("symbol %s assigned to location %#x\n",
+ sp->name, sp->value);
}
/*
@@ -2333,11 +2432,9 @@ digest_pass2()
size = PALIGN(size, sizeof(int));
- while (!(size & align))
+ while (align < MAX_ALIGNMENT && !(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);
@@ -2372,19 +2469,21 @@ write_output()
(void)unlink(output_filename);
}
- outdesc = open(output_filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
- if (outdesc < 0)
+ outstream = fopen(output_filename, "w");
+ if (outstream == NULL)
err(1, "open: %s", output_filename);
if (atexit(cleanup))
err(1, "atexit");
- if (fstat (outdesc, &statbuf) < 0)
+ if (fstat(fileno(outstream), &statbuf) < 0)
err(1, "fstat: %s", output_filename);
filemode = statbuf.st_mode;
- chmod (output_filename, filemode & ~0111);
+ if (S_ISREG(statbuf.st_mode) &&
+ chmod(output_filename, filemode & ~0111) == -1)
+ err(1, "chmod: %s", output_filename);
/* Output the a.out header. */
write_header();
@@ -2406,8 +2505,11 @@ write_output()
if (chmod (output_filename, filemode | 0111) == -1)
err(1, "chmod: %s", output_filename);
- close(outdesc);
- outdesc = 0;
+ fflush(outstream);
+ /* Report I/O error such as disk full. */
+ if (ferror(outstream) || fclose(outstream) != 0)
+ err(1, "write_output: %s", output_filename);
+ outstream = 0;
}
/* Total number of symbols to be written in the output file. */
@@ -2419,12 +2521,19 @@ write_header()
int flags;
if (link_mode & SHAREABLE)
+ /* Output is shared object */
flags = EX_DYNAMIC | EX_PIC;
- else if (pic_code_seen)
+ else if (relocatable_output && pic_code_seen)
+ /* Output is relocatable and contains PIC code */
flags = EX_PIC;
else if (rrs_section_type == RRS_FULL)
+ /* Output is a dynamic executable */
flags = EX_DYNAMIC;
else
+ /*
+ * Output is a static executable
+ * or a non-PIC relocatable object
+ */
flags = 0;
if (oldmagic && (flags & EX_DPMASK))
@@ -2457,7 +2566,7 @@ write_header()
}
md_swapout_exec_hdr(&outheader);
- mywrite(&outheader, sizeof (struct exec), 1, outdesc);
+ mywrite(&outheader, sizeof (struct exec), 1, outstream);
md_swapin_exec_hdr(&outheader);
/*
@@ -2466,7 +2575,7 @@ write_header()
*/
#ifndef COFF_ENCAPSULATE
- padfile(N_TXTOFF(outheader) - sizeof outheader, outdesc);
+ padfile(N_TXTOFF(outheader) - sizeof outheader, outstream);
#endif
}
@@ -2487,7 +2596,7 @@ write_text()
if (trace_files)
fprintf(stderr, "\n");
- padfile(text_pad, outdesc);
+ padfile(text_pad, outstream);
}
/*
@@ -2525,7 +2634,7 @@ copy_text(entry)
entry->textrel, entry->ntextrel, entry, 0);
/* Write the relocated text to the output file. */
- mywrite(bytes, 1, entry->header.a_text, outdesc);
+ mywrite(bytes, 1, entry->header.a_text, outstream);
}
/*
@@ -2542,8 +2651,8 @@ write_data()
fprintf(stderr, "Copying and relocating data:\n\n");
pos = N_DATOFF(outheader) + data_start - rrs_data_start;
- if (lseek(outdesc, pos, L_SET) != pos)
- errx(1, "write_data: lseek");
+ if (fseek(outstream, pos, SEEK_SET) != 0)
+ errx(1, "write_data: fseek");
each_full_file(copy_data, 0);
file_close();
@@ -2556,13 +2665,13 @@ write_data()
if (set_vector_count) {
swap_longs(set_vectors, set_symbol_count + 2*set_vector_count);
mywrite(set_vectors, set_symbol_count + 2*set_vector_count,
- sizeof (unsigned long), outdesc);
+ sizeof (unsigned long), outstream);
}
if (trace_files)
fprintf(stderr, "\n");
- padfile(data_pad, outdesc);
+ padfile(data_pad, outstream);
}
/*
@@ -2596,7 +2705,7 @@ copy_data(entry)
perform_relocation(bytes, entry->header.a_data,
entry->datarel, entry->ndatarel, entry, 1);
- mywrite(bytes, 1, entry->header.a_data, outdesc);
+ mywrite(bytes, 1, entry->header.a_data, outstream);
}
/*
@@ -2657,6 +2766,9 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
get_file_name(entry));
sp = lsp->symbol;
+ if (sp == NULL)
+ errx(1, "%s: bogus relocation record",
+ get_file_name(entry));
if (sp->alias)
sp = sp->alias;
@@ -2697,6 +2809,9 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
get_file_name(entry));
sp = entry->symbols[symindex].symbol;
+ if (sp == NULL)
+ errx(1, "%s: bogus relocation record",
+ get_file_name(entry));
if (sp->alias)
sp = sp->alias;
@@ -2761,11 +2876,11 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
"symbol %s claims RRS in %s%s\n",
sp->name, get_file_name(entry),
(sp->so_defined == (N_TEXT+N_EXT) &&
- sp->jmpslot_offset != -1)?
+ sp->flags & GS_HASJMPSLOT)?
" (JMPSLOT)":"");
}
if (sp->so_defined == (N_TEXT+N_EXT) &&
- sp->jmpslot_offset != -1) {
+ sp->flags & GS_HASJMPSLOT) {
/*
* Claim a jmpslot if one was allocated.
*
@@ -2781,8 +2896,10 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
entry->data_start_address:
entry->text_start_address;
relocation = addend;
- if (claim_rrs_reloc(
- entry, r, sp, &relocation))
+ if ((building_shared_object ||
+ sp->so_defined) &&
+ claim_rrs_reloc(entry, r, sp,
+ &relocation))
continue;
}
}
@@ -3005,7 +3122,7 @@ coptxtrel(entry)
}
md_swapout_reloc(entry->textrel, entry->ntextrel);
mywrite(entry->textrel, entry->ntextrel,
- sizeof(struct relocation_info), outdesc);
+ sizeof(struct relocation_info), outstream);
}
static void
@@ -3070,7 +3187,7 @@ copdatrel(entry)
}
md_swapout_reloc(entry->datarel, entry->ndatarel);
mywrite(entry->datarel, entry->ndatarel,
- sizeof(struct relocation_info), outdesc);
+ sizeof(struct relocation_info), outstream);
}
void write_file_syms __P((struct file_entry *, int *));
@@ -3078,15 +3195,15 @@ void write_string_table __P((void));
/* Offsets and current lengths of symbol and string tables in output file. */
-static int symbol_table_offset;
-static int symbol_table_len;
+static int symtab_offset;
+static int symtab_len;
/* Address in output file where string table starts. */
-static int string_table_offset;
+static int strtab_offset;
/* Offset within string table
where the strings in `strtab_vector' should be written. */
-static int string_table_len;
+static int strtab_len;
/* Total size of string table strings allocated so far,
including strings in `strtab_vector'. */
@@ -3121,8 +3238,6 @@ assign_string_table_index(name)
return index;
}
-FILE *outstream = (FILE *)0;
-
/*
* Write the contents of `strtab_vector' into the string table. This is done
* once for each file's local&debugger symbols and once for the global
@@ -3133,23 +3248,13 @@ write_string_table()
{
register int i;
- if (lseek(outdesc, string_table_offset + string_table_len, 0) ==
- (off_t)-1)
- err(1, "write_string_table: %s: lseek", output_filename);
-
- if (!outstream)
- outstream = fdopen(outdesc, "w");
+ if (fseek(outstream, strtab_offset + strtab_len, SEEK_SET) != 0)
+ err(1, "write_string_table: %s: fseek", output_filename);
for (i = 0; i < strtab_index; i++) {
- fwrite (strtab_vector[i], 1, strtab_lens[i], outstream);
- string_table_len += strtab_lens[i];
+ mywrite(strtab_vector[i], 1, strtab_lens[i], outstream);
+ strtab_len += strtab_lens[i];
}
-
- fflush(outstream);
-
- /* Report I/O error such as disk full. */
- if (ferror(outstream))
- err(1, "write_string_table: %s", output_filename);
}
/* Write the symbol table and string table of the output file. */
@@ -3173,10 +3278,10 @@ write_syms()
/* Size of string table includes the bytes that store the size. */
strtab_size = sizeof strtab_size;
- symbol_table_offset = N_SYMOFF(outheader);
- symbol_table_len = 0;
- string_table_offset = N_STROFF(outheader);
- string_table_len = strtab_size;
+ symtab_offset = N_SYMOFF(outheader);
+ symtab_len = 0;
+ strtab_offset = N_STROFF(outheader);
+ strtab_len = strtab_size;
if (strip_symbols == STRIP_ALL)
return;
@@ -3264,9 +3369,10 @@ write_syms()
* these, symbol was discounted in digest_pass1()
* (they are in the RRS symbol table).
*/
- if (!building_shared_object)
+ if (building_shared_object)
+ continue;
+ if (!(sp->flags & GS_WEAK))
warnx("symbol %s remains undefined", sp->name);
- continue;
}
if (syms_written >= global_sym_count)
@@ -3296,6 +3402,8 @@ write_syms()
nl.n_value = sp->alias->value;
nl.n_other = N_OTHER(0, sp->alias->aux);
} else {
+ int bind = 0;
+
if (sp->defined == N_SIZE)
nl.n_type = N_DATA | N_EXT;
else
@@ -3305,7 +3413,9 @@ write_syms()
errx(1, "%s: N_INDR has value %#x",
sp->name, sp->value);
nl.n_value = sp->value;
- nl.n_other = N_OTHER(0, sp->aux);
+ if (sp->def_lsp)
+ bind = N_BIND(&sp->def_lsp->nzlist.nlist);
+ nl.n_other = N_OTHER(bind, sp->aux);
}
} else if (sp->common_size) {
@@ -3375,18 +3485,17 @@ printf("writesym(#%d): %s, type %x\n", syms_written, sp->name, sp->defined);
} END_EACH_SYMBOL;
if (syms_written != strtab_index || strtab_index != global_sym_count)
- errx(1, "internal error:\
-wrong number (%d) of global symbols written into output file, should be %d",
- syms_written, global_sym_count);
+ errx(1, "internal error: wrong number (%d) of global symbols "
+ "written into output file, should be %d",
+ syms_written, global_sym_count);
/* Output the buffer full of `struct nlist's. */
- if (lseek(outdesc, symbol_table_offset + symbol_table_len, 0) ==
- (off_t)-1)
- err(1, "write_syms: lseek");
+ if (fseek(outstream, symtab_offset + symtab_len, SEEK_SET) != 0)
+ err(1, "write_syms: fseek");
md_swapout_symbols(buf, bufp - buf);
- mywrite(buf, bufp - buf, sizeof(struct nlist), outdesc);
- symbol_table_len += sizeof(struct nlist) * (bufp - buf);
+ mywrite(buf, bufp - buf, sizeof(struct nlist), outstream);
+ symtab_len += sizeof(struct nlist) * (bufp - buf);
/* Write the strings for the global symbols. */
write_string_table();
@@ -3396,18 +3505,19 @@ wrong number (%d) of global symbols written into output file, should be %d",
file_close();
if (syms_written != nsyms)
- errx(1, "internal error:\
-wrong number of symbols (%d) written into output file, should be %d",
- syms_written, nsyms);
+ errx(1, "internal error: wrong number of symbols (%d) "
+ "written into output file, should be %d",
+ syms_written, nsyms);
- if (symbol_table_offset + symbol_table_len != string_table_offset)
+ if (symtab_offset + symtab_len != strtab_offset)
errx(1,
"internal error: inconsistent symbol table length: %d vs %s",
- symbol_table_offset + symbol_table_len, string_table_offset);
+ symtab_offset + symtab_len, strtab_offset);
- lseek(outdesc, string_table_offset, 0);
+ if (fseek(outstream, strtab_offset, SEEK_SET) != 0)
+ err(1, "write_syms: fseek");
strtab_size = md_swap_long(strtab_size);
- mywrite(&strtab_size, sizeof(int), 1, outdesc);
+ mywrite(&strtab_size, sizeof(int), 1, outstream);
}
@@ -3507,10 +3617,11 @@ write_file_syms(entry, syms_written_addr)
/* All the symbols are now in BUF; write them. */
- lseek(outdesc, symbol_table_offset + symbol_table_len, 0);
+ if (fseek(outstream, symtab_offset + symtab_len, SEEK_SET) != 0)
+ err(1, "write local symbols: fseek");
md_swapout_symbols(buf, bufp - buf);
- mywrite(buf, bufp - buf, sizeof(struct nlist), outdesc);
- symbol_table_len += sizeof(struct nlist) * (bufp - buf);
+ mywrite(buf, bufp - buf, sizeof(struct nlist), outstream);
+ symtab_len += sizeof(struct nlist) * (bufp - buf);
/*
* Write the string-table data for the symbols just written, using
@@ -3546,18 +3657,11 @@ mywrite(buf, count, eltsize, fd)
void *buf;
int count;
int eltsize;
- int fd;
+ FILE *fd;
{
- register int val;
- register int bytes = count * eltsize;
-
- while (bytes > 0) {
- val = write(fd, buf, bytes);
- if (val <= 0)
- err(1, "write: %s", output_filename);
- buf += val;
- bytes -= val;
- }
+
+ if (fwrite(buf, eltsize, count, fd) != count)
+ err(1, "write");
}
static void
@@ -3565,10 +3669,10 @@ cleanup()
{
struct stat statbuf;
- if (outdesc <= 0)
+ if (outstream == 0)
return;
- if (fstat(outdesc, &statbuf) == 0) {
+ if (fstat(fileno(outstream), &statbuf) == 0) {
if (S_ISREG(statbuf.st_mode))
(void)unlink(output_filename);
}
@@ -3580,8 +3684,8 @@ cleanup()
*/
void
padfile(padding, fd)
- int padding;
- int fd;
+ int padding;
+ FILE *fd;
{
register char *buf;
if (padding <= 0)
diff --git a/gnu/usr.bin/ld/ld.h b/gnu/usr.bin/ld/ld.h
index 58e5c1e..6b4b7f5 100644
--- a/gnu/usr.bin/ld/ld.h
+++ b/gnu/usr.bin/ld/ld.h
@@ -1,5 +1,5 @@
/*
- * $Id: ld.h,v 1.11 1994/06/15 22:39:46 rich Exp $
+ * $Id: ld.h,v 1.12 1994/12/23 22:30:42 nate Exp $
*/
/*-
* This code is derived from software copyrighted by the Free Software
@@ -151,6 +151,16 @@ extern int netzmagic;
#define CHECK_GOT_RELOC(r) ((r)->r_pcrel)
+#define RELOC_INIT_SEGMENT_RELOC(r)
+
+#endif
+
+#ifndef MAX_GOTOFF
+#define MAX_GOTOFF (LONG_MAX)
+#endif
+
+#ifndef MIN_GOTOFF
+#define MIN_GOTOFF (LONG_MIN)
#endif
/*
@@ -309,7 +319,6 @@ extern int netzmagic;
#ifndef __GNU_STAB__
-
/* Line number for the data section. This is to be used to describe
the source location of a variable declaration. */
#ifndef N_DSLINE
@@ -321,9 +330,10 @@ extern int netzmagic;
#ifndef N_BSLINE
#define N_BSLINE (N_SLINE+N_BSS-N_TEXT)
#endif
-
#endif /* not __GNU_STAB__ */
-
+
+#define N_ISWEAK(p) (N_BIND(p) & BIND_WEAK)
+
typedef struct localsymbol {
struct nzlist nzlist; /* n[z]list from file */
@@ -337,7 +347,7 @@ typedef struct localsymbol {
#define LS_L_SYMBOL 1 /* Local symbol starts with an `L' */
#define LS_WRITE 2 /* Symbol goes in output symtable */
#define LS_RENAME 4 /* xlat name to `<file>.<name>' */
-#define LS_GOTSLOTCLAIMED 8 /* This symbol has a GOT entry */
+#define LS_HASGOTSLOT 8 /* This symbol has a GOT entry */
#define LS_WARNING 16 /* Second part of a N_WARNING duo */
} localsymbol_t;
@@ -388,14 +398,15 @@ typedef struct glosym {
long flags;
-#define GS_DEFINED 1 /* Symbol has definition (notyetused)*/
-#define GS_REFERENCED 2 /* Symbol is referred to by something
+#define GS_DEFINED 0x1 /* Symbol has definition (notyetused)*/
+#define GS_REFERENCED 0x2 /* Symbol is referred to by something
interesting */
-#define GS_TRACE 4 /* Symbol will be traced */
-#define GS_JMPSLOTCLAIMED 8 /* */
-#define GS_GOTSLOTCLAIMED 0x10 /* Some state bits concerning */
+#define GS_TRACE 0x4 /* Symbol will be traced */
+#define GS_HASJMPSLOT 0x8 /* */
+#define GS_HASGOTSLOT 0x10 /* Some state bits concerning */
#define GS_CPYRELOCRESERVED 0x20 /* entries in GOT and PLT tables */
#define GS_CPYRELOCCLAIMED 0x40 /* */
+#define GS_WEAK 0x80 /* Symbol is weakly defined */
} symbol;
@@ -415,6 +426,9 @@ extern symbol *symtab[];
/* # of global symbols referenced and not defined. */
extern int undefined_global_sym_count;
+/* # of weak symbols referenced and not defined. */
+extern int undefined_weak_sym_count;
+
/* # of undefined symbols referenced by shared objects */
extern int undefined_shobj_sym_count;
@@ -575,7 +589,7 @@ extern int link_mode;
#define SHAREABLE 8 /* Build a shared object */
#define SILLYARCHIVE 16 /* Process .sa companions, if any */
-extern int outdesc; /* Output file descriptor. */
+extern FILE *outstream; /* Output file. */
extern struct exec outheader; /* Output file header. */
extern int magic; /* Output file magic. */
extern int oldmagic;
@@ -601,8 +615,8 @@ int file_open __P((struct file_entry *));
void each_file __P((void (*)(), void *));
void each_full_file __P((void (*)(), void *));
unsigned long check_each_file __P((unsigned long (*)(), void *));
-void mywrite __P((void *, int, int, int));
-void padfile __P((int,int));
+void mywrite __P((void *, int, int, FILE *));
+void padfile __P((int, FILE *));
/* In warnings.c: */
void perror_name __P((char *));
diff --git a/gnu/usr.bin/ld/lib.c b/gnu/usr.bin/ld/lib.c
index 737b526..25512bb 100644
--- a/gnu/usr.bin/ld/lib.c
+++ b/gnu/usr.bin/ld/lib.c
@@ -1,5 +1,5 @@
/*
- * $Id: lib.c,v 1.10 1994/06/15 22:39:49 rich Exp $ - library routines
+ * $Id: lib.c,v 1.11 1994/12/23 22:30:45 nate Exp $ - library routines
*/
#include <sys/param.h>
@@ -260,6 +260,12 @@ symdef_library(fd, entry, member_length)
* be satisfied are 'common' references. This
* prevents some problems with name pollution (e.g. a
* global common 'utime' linked to a function).
+ *
+ * If we're not forcing the archive in then we don't
+ * need to bother if: we've never heard of the symbol,
+ * or if it is already defined. The last clause causes
+ * archive members to be searched for definitions
+ * satisfying undefined shared object symbols.
*/
if (!(link_mode & FORCEARCHIVE) &&
(!sp || sp->defined ||
@@ -501,6 +507,9 @@ subfile_wanted_p(entry)
sp->defined = type;
continue;
}
+ if (sp->flags & GS_WEAK)
+ /* Weak symbols don't pull archive members */
+ continue;
if (write_map) {
print_file_name(entry, stdout);
fprintf(stdout, " needed due to %s\n", sp->name);
@@ -542,8 +551,19 @@ subfile_wanted_p(entry)
* a common; ignore it.
*/
continue;
+
+ if (N_ISWEAK(&lsp->nzlist.nlist))
+ /* Weak symbols don't pull archive members */
+ continue;
}
+ /*
+ * At this point, either the new symbol is a common
+ * and the shared object reference is undefined --
+ * in which case we note the common -- or the shared
+ * object reference has a definition -- in which case
+ * the library member takes precedence.
+ */
if (iscommon) {
/*
* New symbol is common, just takes its
@@ -565,8 +585,9 @@ subfile_wanted_p(entry)
if (write_map) {
print_file_name(entry, stdout);
fprintf(stdout,
- " needed due to shared lib ref %s\n",
- sp->name);
+ " needed due to shared lib ref %s (%d)\n",
+ sp->name,
+ lsp ? lsp->nzlist.nlist.n_type : -1);
}
return 1;
}
diff --git a/gnu/usr.bin/ld/rrs.c b/gnu/usr.bin/ld/rrs.c
index 93ad89b..2d1b3bc 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.12 1994/06/15 22:39:52 rich Exp $
+ * $Id: rrs.c,v 1.13 1994/12/23 22:30:48 nate Exp $
*/
#include <sys/param.h>
@@ -64,8 +64,8 @@ static int reserved_rrs_relocs;
static int claimed_rrs_relocs;
static int discarded_rrs_relocs;
-static int number_of_gotslots;
-static int number_of_jmpslots;
+static int number_of_gotslots = 1;
+static int number_of_jmpslots = 1;
static int number_of_rrs_hash_entries;
static int number_of_rrs_symbols;
static int rrs_strtab_size;
@@ -73,10 +73,14 @@ static int rrs_symbol_size;
static int current_jmpslot_offset;
static int current_got_offset;
+static int got_origin;
static int current_reloc_offset;
static int current_hash_index;
int number_of_shobjs;
+/* Convert a GOT offset into a table entry */
+#define GOTP(off) ((got_t *)((long)rrs_got + got_origin + (off)))
+
struct shobj {
struct shobj *next;
struct file_entry *entry;
@@ -125,9 +129,10 @@ RRS data segment:
| |
| sdt |
| |
- +-------------------+ <-- _GLOBAL_OFFSET_TABLE_ (sdt_got)
+ +-------------------+ <-- sdt_got
| |
- | _GOT_ |
+ | _GOT_ | <-- _GLOBAL_OFFSET_TABLE_
+ | | ( == sdt_got + got_origin)
| |
+-------------------+ <-- sdt_plt
| |
@@ -137,37 +142,12 @@ RRS data segment:
*/
/*
- * Initialize RRS
- */
-
-void
-init_rrs()
-{
- reserved_rrs_relocs = 0;
- claimed_rrs_relocs = 0;
- discarded_rrs_relocs = 0;
-
- number_of_rrs_symbols = 0;
- rrs_strtab_size = 0;
-
- /* First jmpslot reserved for run-time binder */
- current_jmpslot_offset = sizeof(jmpslot_t);
- number_of_jmpslots = 1;
-
- /* First gotslot reserved for __DYNAMIC */
- current_got_offset = sizeof(got_t);
- number_of_gotslots = 1;
-
- current_reloc_offset = 0;
-}
-
-/*
* Add NAME to the list of needed run-time objects.
* Return 1 if ENTRY was added to the list.
*/
int
rrs_add_shobj(entry)
-struct file_entry *entry;
+ struct file_entry *entry;
{
struct shobj **p;
@@ -184,8 +164,8 @@ struct file_entry *entry;
void
alloc_rrs_reloc(entry, sp)
-struct file_entry *entry;
-symbol *sp;
+ struct file_entry *entry;
+ symbol *sp;
{
#ifdef DEBUG
printf("alloc_rrs_reloc: %s in %s\n", sp->name, get_file_name(entry));
@@ -195,8 +175,8 @@ printf("alloc_rrs_reloc: %s in %s\n", sp->name, get_file_name(entry));
void
alloc_rrs_segment_reloc(entry, r)
-struct file_entry *entry;
-struct relocation_info *r;
+ struct file_entry *entry;
+ struct relocation_info *r;
{
#ifdef DEBUG
printf("alloc_rrs_segment_reloc at %#x in %s\n",
@@ -207,30 +187,31 @@ printf("alloc_rrs_segment_reloc at %#x in %s\n",
void
alloc_rrs_jmpslot(entry, sp)
-struct file_entry *entry;
-symbol *sp;
+ struct file_entry *entry;
+ symbol *sp;
{
- if (sp->jmpslot_offset == -1) {
- sp->jmpslot_offset = current_jmpslot_offset;
- current_jmpslot_offset += sizeof(jmpslot_t);
- number_of_jmpslots++;
- reserved_rrs_relocs++;
- }
+ if (sp->flags & GS_HASJMPSLOT)
+ return;
+
+ sp->flags |= GS_HASJMPSLOT;
+ number_of_jmpslots++;
+ reserved_rrs_relocs++;
}
void
alloc_rrs_gotslot(entry, r, lsp)
-struct file_entry *entry;
-struct relocation_info *r;
-struct localsymbol *lsp;
+ struct file_entry *entry;
+ struct relocation_info *r;
+ struct localsymbol *lsp;
{
symbol *sp = lsp->symbol;
if (!RELOC_EXTERN_P(r)) {
if (sp != NULL) {
- warnx("%s: relocation for internal symbol expected at %#x",
- get_file_name(entry), RELOC_ADDRESS(r));
+ warnx("%s: relocation for internal symbol "
+ "expected at %#x",
+ get_file_name(entry), RELOC_ADDRESS(r));
return;
}
@@ -238,38 +219,37 @@ struct localsymbol *lsp;
/* No need for a GOT slot */
return;
- if (lsp->gotslot_offset == -1) {
- lsp->gotslot_offset = current_got_offset;
- current_got_offset += sizeof(got_t);
- number_of_gotslots++;
- reserved_rrs_relocs++;
- }
+ if (lsp->flags & LS_HASGOTSLOT)
+ return;
+
+ lsp->flags |= LS_HASGOTSLOT;
} else {
if (sp == NULL) {
- warnx("%s: relocation must refer to global symbol at %#x",
- get_file_name(entry), RELOC_ADDRESS(r));
+ warnx("%s: relocation must refer "
+ "to global symbol at %#x",
+ get_file_name(entry), RELOC_ADDRESS(r));
return;
}
if (sp->alias)
sp = sp->alias;
- if (sp->gotslot_offset == -1) {
- sp->gotslot_offset = current_got_offset;
- current_got_offset += sizeof(got_t);
- number_of_gotslots++;
- reserved_rrs_relocs++;
- }
+ if (sp->flags & GS_HASGOTSLOT)
+ return;
+
+ sp->flags |= GS_HASGOTSLOT;
}
+ number_of_gotslots++;
+ reserved_rrs_relocs++;
}
void
alloc_rrs_cpy_reloc(entry, sp)
-struct file_entry *entry;
-symbol *sp;
+ struct file_entry *entry;
+ symbol *sp;
{
if (sp->flags & GS_CPYRELOCRESERVED)
return;
@@ -302,10 +282,10 @@ rrs_next_reloc()
*/
int
claim_rrs_reloc(entry, rp, sp, relocation)
-struct file_entry *entry;
-struct relocation_info *rp;
-symbol *sp;
-long *relocation;
+ struct file_entry *entry;
+ struct relocation_info *rp;
+ symbol *sp;
+ long *relocation;
{
struct relocation_info *r = rrs_next_reloc();
@@ -322,7 +302,7 @@ printf("claim_rrs_reloc: %s in %s\n", sp->name, get_file_name(entry));
if (link_mode & SYMBOLIC) {
if (!sp->defined)
warnx("Cannot reduce symbol \"%s\" in %s",
- sp->name, get_file_name(entry));
+ sp->name, get_file_name(entry));
RELOC_EXTERN_P(r) = 0;
*relocation += sp->value;
(void) md_make_reloc(rp, r, RELTYPE_RELATIVE);
@@ -338,28 +318,31 @@ printf("claim_rrs_reloc: %s in %s\n", sp->name, get_file_name(entry));
*/
long
claim_rrs_jmpslot(entry, rp, sp, addend)
-struct file_entry *entry;
-struct relocation_info *rp;
-symbol *sp;
-long addend;
+ struct file_entry *entry;
+ struct relocation_info *rp;
+ symbol *sp;
+ long addend;
{
struct relocation_info *r;
- if (sp->flags & GS_JMPSLOTCLAIMED)
+ if (!(sp->flags & GS_HASJMPSLOT))
+ errx(1, "internal error: "
+ "%s: claim_rrs_jmpslot: %s: no reservation",
+ get_file_name(entry),
+ sp->name);
+
+ if (sp->jmpslot_offset != -1)
return rrs_sdt.sdt_plt + sp->jmpslot_offset;
+ sp->jmpslot_offset = current_jmpslot_offset;
+ current_jmpslot_offset += sizeof(jmpslot_t);
+
#ifdef DEBUG
printf("claim_rrs_jmpslot: %s: %s(%d) -> offset %x\n",
get_file_name(entry),
sp->name, sp->rrs_symbolnum, sp->jmpslot_offset);
#endif
- if (sp->jmpslot_offset == -1)
- errx(1,
- "internal error: %s: claim_rrs_jmpslot: %s: jmpslot_offset == -1\n",
- get_file_name(entry),
- sp->name);
-
if ((link_mode & SYMBOLIC) || rrs_section_type == RRS_PARTIAL) {
if (!sp->defined)
warnx("Cannot reduce symbol \"%s\" in %s",
@@ -370,7 +353,6 @@ printf("claim_rrs_jmpslot: %s: %s(%d) -> offset %x\n",
sp->value);
if (rrs_section_type == RRS_PARTIAL || !JMPSLOT_NEEDS_RELOC) {
/* PLT is self-contained */
- sp->flags |= GS_JMPSLOTCLAIMED;
discarded_rrs_relocs++;
return rrs_sdt.sdt_plt + sp->jmpslot_offset;
}
@@ -384,7 +366,6 @@ printf("claim_rrs_jmpslot: %s: %s(%d) -> offset %x\n",
* Install a run-time relocation for this PLT entry.
*/
r = rrs_next_reloc();
- sp->flags |= GS_JMPSLOTCLAIMED;
RELOC_SYMBOL(r) = sp->rrs_symbolnum;
@@ -408,10 +389,10 @@ printf("claim_rrs_jmpslot: %s: %s(%d) -> offset %x\n",
*/
long
claim_rrs_gotslot(entry, rp, lsp, addend)
-struct file_entry *entry;
-struct relocation_info *rp;
-struct localsymbol *lsp;
-long addend;
+ struct file_entry *entry;
+ struct relocation_info *rp;
+ struct localsymbol *lsp;
+ long addend;
{
struct relocation_info *r;
symbol *sp = lsp->symbol;
@@ -424,28 +405,42 @@ long addend;
if (sp->alias)
sp = sp->alias;
-#ifdef DEBUG
-printf("claim_rrs_gotslot: %s(%d,%#x) slot offset %#x, addend %#x\n",
- sp->name, sp->rrs_symbolnum, sp->value, sp->gotslot_offset, addend);
-#endif
- if (sp->gotslot_offset == -1)
- errx(1,
- "internal error: %s: claim_rrs_gotslot: %s: gotslot_offset == -1\n",
+ if (!(sp->flags & GS_HASGOTSLOT))
+ errx(1, "internal error: "
+ "%s: claim_rrs_gotslot: %s: no reservation",
get_file_name(entry), sp->name);
- if (sp->flags & GS_GOTSLOTCLAIMED) {
-#ifdef DEBUG
- if (*(long *)((long)rrs_got + sp->gotslot_offset) != addend +
- (!(link_mode & SHAREABLE) || (link_mode & SYMBOLIC))
- ?sp->value:0)
- errx(1, "%s: %s: gotslot at %#x is multiple valued\n",
+ if (sp->gotslot_offset != -1) {
+#ifdef DIAGNOSTIC
+ if (*GOTP(sp->gotslot_offset) != addend +
+ ((!(link_mode & SHAREABLE) || (link_mode & SYMBOLIC))
+ ? sp->value : 0))
+ errx(1, "%s: %s: gotslot at %#x is multiple valued, "
+ "*got = %#x, addend = %#x, sp->value = %#x",
get_file_name(entry), sp->name,
- sp->gotslot_offset);
+ sp->gotslot_offset,
+ *GOTP(sp->gotslot_offset), addend, sp->value);
#endif
/* This symbol already passed here before. */
return sp->gotslot_offset;
}
+ if (current_got_offset == 0)
+ /* GOT offset 0 is reserved */
+ current_got_offset += sizeof(got_t);
+
+ if (current_got_offset > MAX_GOTOFF)
+ errx(1, "%s: GOT overflow on symbol `%s' at %#x",
+ get_file_name(entry), sp->name, RELOC_ADDRESS(rp));
+
+ sp->gotslot_offset = current_got_offset;
+ current_got_offset += sizeof(got_t);
+
+#ifdef DEBUG
+printf("claim_rrs_gotslot: %s(%d,%#x) slot offset %#x, addend %#x\n",
+ sp->name, sp->rrs_symbolnum, sp->value, sp->gotslot_offset, addend);
+#endif
+
if (sp->defined &&
(!(link_mode & SHAREABLE) || (link_mode & SYMBOLIC))) {
@@ -453,8 +448,7 @@ printf("claim_rrs_gotslot: %s(%d,%#x) slot offset %#x, addend %#x\n",
* Reduce to just a base-relative translation.
*/
- *(got_t *)((long)rrs_got + sp->gotslot_offset) =
- sp->value + addend;
+ *GOTP(sp->gotslot_offset) = sp->value + addend;
reloc_type = RELTYPE_RELATIVE;
} else if ((link_mode & SYMBOLIC) || rrs_section_type == RRS_PARTIAL) {
@@ -464,7 +458,7 @@ printf("claim_rrs_gotslot: %s(%d,%#x) slot offset %#x, addend %#x\n",
* so again all symbols must be known.
*/
warnx("Cannot reduce symbol \"%s\" in %s",
- sp->name, get_file_name(entry));
+ sp->name, get_file_name(entry));
} else {
@@ -472,7 +466,7 @@ printf("claim_rrs_gotslot: %s(%d,%#x) slot offset %#x, addend %#x\n",
* This gotslot will be updated with symbol value at run-time.
*/
- *(got_t *)((long)rrs_got + sp->gotslot_offset) = addend;
+ *GOTP(sp->gotslot_offset) = addend;
}
if (rrs_section_type == RRS_PARTIAL) {
@@ -483,9 +477,8 @@ printf("claim_rrs_gotslot: %s(%d,%#x) slot offset %#x, addend %#x\n",
*/
if (!sp->defined)
warnx("Cannot reduce symbol \"%s\" in %s",
- sp->name, get_file_name(entry));
+ sp->name, get_file_name(entry));
discarded_rrs_relocs++;
- sp->flags |= GS_GOTSLOTCLAIMED;
return sp->gotslot_offset;
}
@@ -498,8 +491,7 @@ printf("claim_rrs_gotslot: %s(%d,%#x) slot offset %#x, addend %#x\n",
* as no symbol need be looked up at run-time.
*/
r = rrs_next_reloc();
- sp->flags |= GS_GOTSLOTCLAIMED;
- r->r_address = rrs_sdt.sdt_got + sp->gotslot_offset;
+ r->r_address = got_symbol->value + sp->gotslot_offset;
RELOC_SYMBOL(r) = sp->rrs_symbolnum;
RELOC_EXTERN_P(r) = !(reloc_type == RELTYPE_RELATIVE);
md_make_gotreloc(rp, r, reloc_type);
@@ -515,40 +507,50 @@ printf("claim_rrs_gotslot: %s(%d,%#x) slot offset %#x, addend %#x\n",
*/
long
claim_rrs_internal_gotslot(entry, rp, lsp, addend)
-struct file_entry *entry;
-struct relocation_info *rp;
-struct localsymbol *lsp;
-long addend;
+ struct file_entry *entry;
+ struct relocation_info *rp;
+ struct localsymbol *lsp;
+ long addend;
{
struct relocation_info *r;
addend += lsp->nzlist.nz_value;
if (!RELOC_STATICS_THROUGH_GOT_P(r))
- return addend - rrs_sdt.sdt_got;
-
-#ifdef DEBUG
-printf("claim_rrs_internal_gotslot: %s: slot offset %#x, addend = %#x\n",
- get_file_name(entry), lsp->gotslot_offset, addend);
-#endif
+ return addend - got_symbol->value;
- if (lsp->gotslot_offset == -1)
- errx(1,
- "internal error: %s: claim_rrs_internal_gotslot at %#x: slot_offset == -1\n",
+ if (!(lsp->flags & LS_HASGOTSLOT))
+ errx(1, "internal error: "
+ "%s: claim_rrs_internal_gotslot at %#x: no reservation",
get_file_name(entry), RELOC_ADDRESS(rp));
- if (lsp->flags & LS_GOTSLOTCLAIMED) {
- /* Already done */
- if (addend != *(long *)((long)rrs_got + lsp->gotslot_offset))
- errx(1, "%s: gotslot at %#x is multiple valued\n",
+ if (lsp->gotslot_offset != -1) {
+ /* Already claimed */
+ if (*GOTP(lsp->gotslot_offset) != addend)
+ errx(1, "%s: gotslot at %#x is multiple valued",
get_file_name(entry), lsp->gotslot_offset);
return lsp->gotslot_offset;
}
- *(long *)((long)rrs_got + lsp->gotslot_offset) = addend;
+ if (current_got_offset == 0)
+ /* GOT offset 0 is reserved */
+ current_got_offset += sizeof(got_t);
+
+ if (current_got_offset > MAX_GOTOFF)
+ errx(1, "%s: GOT overflow for relocation at %#x",
+ get_file_name(entry), RELOC_ADDRESS(rp));
+
+ lsp->gotslot_offset = current_got_offset;
+ current_got_offset += sizeof(got_t);
+
+ *GOTP(lsp->gotslot_offset) = addend;
+
+#ifdef DEBUG
+printf("claim_rrs_internal_gotslot: %s: slot offset %#x, addend = %#x\n",
+ get_file_name(entry), lsp->gotslot_offset, addend);
+#endif
if (rrs_section_type == RRS_PARTIAL) {
- lsp->flags |= LS_GOTSLOTCLAIMED;
discarded_rrs_relocs++;
return lsp->gotslot_offset;
}
@@ -557,8 +559,7 @@ printf("claim_rrs_internal_gotslot: %s: slot offset %#x, addend = %#x\n",
* Relocation entry needed for this static GOT entry.
*/
r = rrs_next_reloc();
- lsp->flags |= LS_GOTSLOTCLAIMED;
- r->r_address = rrs_sdt.sdt_got + lsp->gotslot_offset;
+ r->r_address = got_symbol->value + lsp->gotslot_offset;
RELOC_EXTERN_P(r) = 0;
md_make_gotreloc(rp, r, RELTYPE_RELATIVE);
return lsp->gotslot_offset;
@@ -566,9 +567,9 @@ printf("claim_rrs_internal_gotslot: %s: slot offset %#x, addend = %#x\n",
void
claim_rrs_cpy_reloc(entry, rp, sp)
-struct file_entry *entry;
-struct relocation_info *rp;
-symbol *sp;
+ struct file_entry *entry;
+ struct relocation_info *rp;
+ symbol *sp;
{
struct relocation_info *r;
@@ -576,8 +577,8 @@ symbol *sp;
return;
if (!(sp->flags & GS_CPYRELOCRESERVED))
- errx(1,
- "internal error: %s: claim_cpy_reloc: %s: no reservation\n",
+ errx(1, "internal error: "
+ "%s: claim_cpy_reloc: %s: no reservation",
get_file_name(entry), sp->name);
#ifdef DEBUG
@@ -595,8 +596,8 @@ printf("claim_rrs_copy: %s: %s -> %x\n",
void
claim_rrs_segment_reloc(entry, rp)
-struct file_entry *entry;
-struct relocation_info *rp;
+ struct file_entry *entry;
+ struct relocation_info *rp;
{
struct relocation_info *r = rrs_next_reloc();
@@ -618,8 +619,8 @@ printf("claim_rrs_segment_reloc: %s at %#x\n",
*/
void
rrs_insert_hash(cp, index)
-char *cp;
-int index;
+ char *cp;
+ int index;
{
int hashval = 0;
struct rrs_hash *hp;
@@ -699,6 +700,8 @@ consider_rrs_section_lengths()
if (rrs_section_type == RRS_NONE) {
got_symbol->defined = 0;
+ if (reserved_rrs_relocs > 0)
+ errx(1, "internal error: empty RRS has reservations");
return;
}
@@ -781,7 +784,8 @@ consider_rrs_section_lengths()
if (rrs_sdt.sdt_buckets < 4)
rrs_sdt.sdt_buckets = 4;
- number_of_rrs_hash_entries = rrs_sdt.sdt_buckets + number_of_rrs_symbols;
+ number_of_rrs_hash_entries = rrs_sdt.sdt_buckets +
+ number_of_rrs_symbols;
rrs_hashtab = (struct rrs_hash *)xmalloc(
number_of_rrs_hash_entries * sizeof(struct rrs_hash));
for (n = 0; n < rrs_sdt.sdt_buckets; n++)
@@ -838,11 +842,32 @@ relocate_rrs_addresses()
dynamic_symbol->value = 0;
+ /*
+ * Get ready to allocate linkage table offsets.
+ * First jmpslot is reserved for the run-time binder
+ * GOT entry at offset 0 is reserved for `__DYNAMIC'.
+ */
+ current_jmpslot_offset = sizeof(jmpslot_t);
+ current_got_offset = 0;
+
+ if (1 /* Not "-fPIC" seen */) {
+ int gotsize = number_of_gotslots * sizeof(got_t);
+
+ if (gotsize + MIN_GOTOFF - (int)sizeof(got_t) > MAX_GOTOFF)
+ warnx("Global Offset Table overflow");
+ if (gotsize > MAX_GOTOFF)
+ /* Position at "two-complements" origin */
+ current_got_offset += MIN_GOTOFF;
+ }
+
+ got_origin = -current_got_offset;
+
if (rrs_section_type == RRS_NONE)
return;
if (rrs_section_type == RRS_PARTIAL) {
- got_symbol->value = rrs_sdt.sdt_got = rrs_data_start;
+ rrs_sdt.sdt_got = rrs_data_start;
+ got_symbol->value = rrs_sdt.sdt_got + got_origin;
rrs_sdt.sdt_plt = rrs_sdt.sdt_got +
number_of_gotslots * sizeof(got_t);
return;
@@ -889,12 +914,11 @@ relocate_rrs_addresses()
rrs_sdt.sdt_filler2 = 0;
/*
- * Assign addresses to _GLOBAL_OFFSET_TABLE_ and __DYNAMIC
- * &__DYNAMIC is also in the first GOT entry.
+ * Assign addresses to _GLOBAL_OFFSET_TABLE_ and __DYNAMIC.
+ * The value `&__DYNAMIC' is in the GOT table at offset 0.
*/
- got_symbol->value = rrs_sdt.sdt_got;
-
- *rrs_got = dynamic_symbol->value = rrs_data_start;
+ got_symbol->value = rrs_sdt.sdt_got + got_origin;
+ *GOTP(0) = dynamic_symbol->value = rrs_data_start;
}
@@ -907,36 +931,37 @@ write_rrs_data()
return;
pos = rrs_data_start + (N_DATOFF(outheader) - DATA_START(outheader));
- if (lseek(outdesc, pos, L_SET) != pos)
- err(1, "write_rrs_data: lseek");
+ if (fseek(outstream, pos, SEEK_SET) != 0)
+ err(1, "write_rrs_data: fseek");
if (rrs_section_type == RRS_PARTIAL) {
/*
* Only a GOT and PLT are needed.
*/
md_swapout_got(rrs_got, number_of_gotslots);
- mywrite(rrs_got, number_of_gotslots, sizeof(got_t), outdesc);
+ mywrite(rrs_got, number_of_gotslots, sizeof(got_t), outstream);
md_swapout_jmpslot(rrs_plt, number_of_jmpslots);
- mywrite(rrs_plt, number_of_jmpslots, sizeof(jmpslot_t), outdesc);
+ mywrite(rrs_plt, number_of_jmpslots,
+ sizeof(jmpslot_t), outstream);
return;
}
md_swapout__dynamic(&rrs_dyn);
- mywrite(&rrs_dyn, 1, sizeof(struct _dynamic), outdesc);
+ mywrite(&rrs_dyn, 1, sizeof(struct _dynamic), outstream);
md_swapout_so_debug(&rrs_so_debug);
- mywrite(&rrs_so_debug, 1, sizeof(struct so_debug), outdesc);
+ mywrite(&rrs_so_debug, 1, sizeof(struct so_debug), outstream);
md_swapout_section_dispatch_table(&rrs_sdt);
- mywrite(&rrs_sdt, 1, sizeof(struct section_dispatch_table), outdesc);
+ mywrite(&rrs_sdt, 1, sizeof(struct section_dispatch_table), outstream);
md_swapout_got(rrs_got, number_of_gotslots);
- mywrite(rrs_got, number_of_gotslots, sizeof(got_t), outdesc);
+ mywrite(rrs_got, number_of_gotslots, sizeof(got_t), outstream);
md_swapout_jmpslot(rrs_plt, number_of_jmpslots);
- mywrite(rrs_plt, number_of_jmpslots, sizeof(jmpslot_t), outdesc);
+ mywrite(rrs_plt, number_of_jmpslots, sizeof(jmpslot_t), outstream);
}
void
@@ -949,23 +974,24 @@ write_rrs_text()
int offset = 0;
struct shobj *shp;
struct sod *sodp;
+ int bind;
if (rrs_section_type == RRS_PARTIAL)
return;
pos = rrs_text_start + (N_TXTOFF(outheader) - TEXT_START(outheader));
- if (lseek(outdesc, pos, L_SET) != pos)
- err(1, "write_rrs_text: lseek");
+ if (fseek(outstream, pos, SEEK_SET) != 0)
+ err(1, "write_rrs_text: fseek");
/* Write relocation records */
md_swapout_reloc(rrs_reloc, reserved_rrs_relocs);
mywrite(rrs_reloc, reserved_rrs_relocs,
- sizeof(struct relocation_info), outdesc);
+ sizeof(struct relocation_info), outstream);
/* Write the RRS symbol hash tables */
md_swapout_rrs_hash(rrs_hashtab, number_of_rrs_hash_entries);
mywrite(rrs_hashtab, number_of_rrs_hash_entries,
- sizeof(struct rrs_hash), outdesc);
+ sizeof(struct rrs_hash), outstream);
/*
* Determine size of an RRS symbol entry, allocate space
@@ -1028,8 +1054,8 @@ write_rrs_text()
if ((long)nlp - (long)rrs_symbols >=
number_of_rrs_symbols * rrs_symbol_size)
- errx(1,
- "internal error: rrs symbols exceed allocation %d ",
+ errx(1, "internal error: "
+ "rrs symbols exceed allocation %d",
number_of_rrs_symbols);
nlp->nz_desc = 0;
@@ -1037,6 +1063,8 @@ write_rrs_text()
if (LD_VERSION_NZLIST_P(soversion))
nlp->nz_size = 0;
+ bind = (sp->flags & GS_WEAK) ? BIND_WEAK : 0;
+
if (sp->defined > 1) {
/* defined with known type */
if (!(link_mode & SHAREABLE) &&
@@ -1049,7 +1077,7 @@ write_rrs_text()
*/
nlp->nz_type = sp->alias->defined;
nlp->nz_value = sp->alias->value;
- nlp->nz_other = N_OTHER(0, sp->alias->aux);
+ nlp->nz_other = N_OTHER(bind, sp->alias->aux);
} else if (sp->defined == N_SIZE) {
/*
* Make sure this symbol isn't going
@@ -1060,35 +1088,38 @@ write_rrs_text()
} else {
nlp->nz_type = sp->defined;
nlp->nz_value = sp->value;
- nlp->nz_other = N_OTHER(0, sp->aux);
+ nlp->nz_other = N_OTHER(bind, sp->aux);
}
if (LD_VERSION_NZLIST_P(soversion))
nlp->nz_size = sp->size;
} else if (sp->common_size) {
/*
- * a common definition
+ * A common definition.
*/
nlp->nz_type = N_UNDF | N_EXT;
nlp->nz_value = sp->common_size;
+ nlp->nz_other = N_OTHER(bind, 0);
} else if (!sp->defined) {
/* undefined */
nlp->nz_type = N_UNDF | N_EXT;
nlp->nz_value = 0;
if (sp->so_defined && sp->jmpslot_offset != -1) {
/*
- * Define a "weak" function symbol.
+ * A PLT entry. The auxiliary type -- which
+ * must be AUX_FUNC -- is used by the run-time
+ * linker to unambiguously resolve function
+ * address references.
*/
if (sp->aux != AUX_FUNC)
errx(1, "%s: non-function jmpslot",
- sp->name);
- nlp->nz_other = N_OTHER(0, sp->aux);
+ sp->name);
+ nlp->nz_other = N_OTHER(bind, sp->aux);
nlp->nz_value =
rrs_sdt.sdt_plt + sp->jmpslot_offset;
}
} else
- errx(1,
- "internal error: %s defined in mysterious way",
- sp->name);
+ errx(1, "internal error: %s defined in mysterious way",
+ sp->name);
/* Set symbol's name */
nlp->nz_strx = offset;
@@ -1103,7 +1134,7 @@ write_rrs_text()
int t = (nlp->nz_type == N_INDR + N_EXT);
INCR_NLP(nlp);
- nlp->nz_type = N_UNDF + t?N_EXT:0;
+ nlp->nz_type = N_UNDF + (t ? N_EXT : 0);
nlp->nz_un.n_strx = offset;
nlp->nz_value = 0;
nlp->nz_other = 0;
@@ -1118,8 +1149,8 @@ write_rrs_text()
} END_EACH_SYMBOL;
if (MALIGN(offset) != rrs_strtab_size)
- errx(1,
- "internal error: inconsistent RRS string table length: %d, expected %d",
+ errx(1, "internal error: "
+ "inconsistent RRS string table length: %d, expected %d",
offset, rrs_strtab_size);
/* Write the symbol table */
@@ -1127,10 +1158,10 @@ write_rrs_text()
md_swapout_symbols(rrs_symbols, number_of_rrs_symbols);
else
md_swapout_zsymbols(rrs_symbols, number_of_rrs_symbols);
- mywrite(rrs_symbols, symsize, 1, outdesc);
+ mywrite(rrs_symbols, symsize, 1, outstream);
/* Write the strings */
- mywrite(rrs_strtab, rrs_strtab_size, 1, outdesc);
+ mywrite(rrs_strtab, rrs_strtab_size, 1, outstream);
/*
* Write the names of the shared objects needed at run-time
@@ -1161,12 +1192,12 @@ write_rrs_text()
}
if (i < number_of_shobjs)
- errx(1,
- "internal error: # of link objects less then expected %d",
+ errx(1, "internal error: "
+ "# of link objects less then expected %d",
number_of_shobjs);
md_swapout_sod(sodp, number_of_shobjs);
- mywrite(sodp, number_of_shobjs, sizeof(struct sod), outdesc);
+ mywrite(sodp, number_of_shobjs, sizeof(struct sod), outstream);
for (i = 0, shp = rrs_shobjs; shp; i++, shp = shp->next) {
char *name = shp->entry->local_sym_name;
@@ -1175,7 +1206,7 @@ write_rrs_text()
name += 2;
}
- mywrite(name, strlen(name) + 1, 1, outdesc);
+ mywrite(name, strlen(name) + 1, 1, outstream);
}
}
@@ -1188,8 +1219,8 @@ write_rrs()
*/
if (rrs_section_type == RRS_NONE) {
if (reserved_rrs_relocs > 1)
- errx(1,
- "internal error: RRS relocs in static program: %d",
+ errx(1, "internal error: "
+ "RRS relocs in static program: %d",
reserved_rrs_relocs-1);
return;
}
@@ -1202,8 +1233,8 @@ printf("rrs_relocs: reserved %d claimed %d discarded %d, gotslots %d jmpslots %d
/* Final consistency check */
if (claimed_rrs_relocs + discarded_rrs_relocs != reserved_rrs_relocs) {
- errx(1,
- "internal error: reserved relocs(%d) != claimed(%d) + discarded(%d)",
+ errx(1, "internal error: "
+ "reserved relocs(%d) != claimed(%d) + discarded(%d)",
reserved_rrs_relocs,
claimed_rrs_relocs,
discarded_rrs_relocs);
diff --git a/gnu/usr.bin/ld/rtld/Makefile b/gnu/usr.bin/ld/rtld/Makefile
index d8c9165..7c81145 100644
--- a/gnu/usr.bin/ld/rtld/Makefile
+++ b/gnu/usr.bin/ld/rtld/Makefile
@@ -1,10 +1,9 @@
-# $Id: Makefile,v 1.12 1994/08/28 18:48:32 bde Exp $
+# $Id: Makefile,v 1.13 1994/09/18 19:41:38 swallace Exp $
PROG= ld.so
SRCS= mdprologue.S rtld.c malloc.c shlib.c etc.c md.c
NOMAN= noman
LDDIR?= $(.CURDIR)/..
-#PICFLAG=-pic
PICFLAG=-fpic
CFLAGS+=-I$(LDDIR) -I$(.CURDIR) -I$(LDDIR)/$(MACHINE) $(PICFLAG) -DRTLD
LDFLAGS+=-Bshareable -Bsymbolic -assert nosymbolic
@@ -14,18 +13,9 @@ LDADD+= -lc_pic -lgcc_pic
BINDIR= /usr/libexec
INSTALLFLAGS+= -fschg
-.SUFFIXES: .S
-
.PATH: $(LDDIR) $(LDDIR)/$(MACHINE)
$(PROG): ${OBJS} ${DPADD}
- $(LD) -o $(PROG) $(LDFLAGS) $(OBJS) $(LDDESTDIR) $(LDADD)
-
-.S.o:
-.if defined(DESTDIR)
- ${CPP} -I${DESTDIR}/usr/include ${.IMPSRC} | ${AS} ${ASFLAGS} -o ${.TARGET} -
-.else
- ${CPP} ${.IMPSRC} | ${AS} ${ASFLAGS} -o ${.TARGET} -
-.endif
+ $(LD) -o $(PROG) $(LDFLAGS) $(OBJS) $(LDADD)
.include <bsd.prog.mk>
diff --git a/gnu/usr.bin/ld/rtld/malloc.c b/gnu/usr.bin/ld/rtld/malloc.c
index b5c54f8..0d94200 100644
--- a/gnu/usr.bin/ld/rtld/malloc.c
+++ b/gnu/usr.bin/ld/rtld/malloc.c
@@ -33,7 +33,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)malloc.c 5.11 (Berkeley) 2/23/91";*/
-static char *rcsid = "$Id: malloc.c,v 1.1 1994/02/13 20:44:09 jkh Exp $";
+static char *rcsid = "$Id: malloc.c,v 1.2 1994/06/15 22:41:13 rich Exp $";
#endif /* LIBC_SCCS and not lint */
/*
@@ -72,8 +72,7 @@ static int findbucket();
/*
* Pre-allocate mmap'ed pages
*/
-#define getpagesize() NBPG
-#define NPOOLPAGES (32*1024/NBPG)
+#define NPOOLPAGES (32*1024/pagesz)
static caddr_t pagepool_start, pagepool_end;
static int morepages();
diff --git a/gnu/usr.bin/ld/rtld/rtld.c b/gnu/usr.bin/ld/rtld/rtld.c
index 6332911..c2e6021 100644
--- a/gnu/usr.bin/ld/rtld/rtld.c
+++ b/gnu/usr.bin/ld/rtld/rtld.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: rtld.c,v 1.20 1995/01/12 19:12:29 joerg Exp $
+ * $Id: rtld.c,v 1.21 1995/02/07 13:33:42 jkh Exp $
*/
#include <sys/param.h>
@@ -38,9 +38,8 @@
#include <sys/resource.h>
#include <sys/errno.h>
#include <sys/mman.h>
-#ifndef BSD
+#ifndef MAP_COPY
#define MAP_COPY MAP_PRIVATE
-#define MAP_ANON 0
#endif
#include <err.h>
#include <fcntl.h>
@@ -58,8 +57,19 @@
#include "ld.h"
-#ifndef BSD /* Need do better than this */
-#define NEED_DEV_ZERO 1
+#ifndef MAP_ANON
+#define MAP_ANON 0
+#define anon_open() do { \
+ if ((anon_fd = open("/dev/zero", O_RDWR, 0)) == -1) \
+ err("open: %s", "/dev/zero"); \
+} while (0)
+#define anon_close() do { \
+ (void)close(anon_fd); \
+ anon_fd = -1; \
+} while (0)
+#else
+#define anon_open()
+#define anon_close()
#endif
/*
@@ -135,6 +145,7 @@ static int careful;
static char __main_progname[] = "main";
static char *main_progname = __main_progname;
static char us[] = "/usr/libexec/ld.so";
+static int anon_fd = -1;
struct so_map *link_map_head, *main_map;
struct so_map **link_map_tail = &link_map_head;
@@ -166,14 +177,15 @@ static void init_map __P((struct so_map *, char *));
static char *rtfindlib __P((char *, int, int, int *));
void binder_entry __P((void));
long binder __P((jmpslot_t *));
-static void maphints __P((void));
-static void unmaphints __P((void));
static struct nzlist *lookup __P((char *, struct so_map **, int));
static inline struct rt_symbol *lookup_rts __P((char *));
static struct rt_symbol *enter_rts __P((char *, long, int, caddr_t,
long, struct so_map *));
static void generror __P((char *, ...));
+static void maphints __P((void));
+static void unmaphints __P((void));
+
static inline int
strcmp (register const char *s1, register const char *s2)
{
@@ -251,6 +263,7 @@ struct _dynamic *dp;
if (getenv("LD_NOSTD_PATH") == NULL)
std_search_path();
+ anon_open();
/* Load required objects into the process address space */
load_objects(crtp, dp);
@@ -301,11 +314,12 @@ struct _dynamic *dp;
ddp->dd_sym_loaded = 1;
}
- /* Forget hints so that hints file can go away if it is unlinked */
+ /* Close the hints file */
unmaphints();
/* Close our file descriptor */
(void)close(crtp->crt_ldfd);
+ anon_close();
return 0;
}
@@ -511,9 +525,9 @@ again:
return NULL;
}
- if ((addr = mmap(0, hdr.a_text + hdr.a_data,
- PROT_READ|PROT_EXEC,
- MAP_COPY, fd, 0)) == (caddr_t)-1) {
+ if ((addr = mmap(0, hdr.a_text + hdr.a_data + hdr.a_bss,
+ PROT_READ|PROT_EXEC,
+ MAP_COPY, fd, 0)) == (caddr_t)-1) {
generror ("mmap failed for \"%s\" : %s",
path, strerror (errno));
(void)close(fd);
@@ -528,29 +542,17 @@ again:
return NULL;
}
- (void)close(fd);
-
- fd = -1;
-#ifdef NEED_DEV_ZERO
- if ((fd = open("/dev/zero", O_RDWR, 0)) == -1) {
- generror ("open failed for \"/dev/zero\" : %s",
- strerror (errno));
- return NULL;
- }
-#endif
- if (hdr.a_bss && mmap(addr + hdr.a_text + hdr.a_data, hdr.a_bss,
- PROT_READ|PROT_WRITE|PROT_EXEC,
- MAP_ANON|MAP_FIXED|MAP_COPY,
- fd, hdr.a_text + hdr.a_data) == (caddr_t)-1) {
+ if (mmap(addr + hdr.a_text + hdr.a_data, hdr.a_bss,
+ PROT_READ|PROT_WRITE|PROT_EXEC,
+ MAP_ANON|MAP_COPY|MAP_FIXED,
+ anon_fd, 0) == (caddr_t)-1) {
generror ("mmap failed for \"%s\" : %s",
path, strerror (errno));
(void)close(fd);
return NULL;
- }
+ }
-#ifdef NEED_DEV_ZERO
- close(fd);
-#endif
+ (void)close(fd);
/* Assume _DYNAMIC is the first data item */
dp = (struct _dynamic *)(addr+hdr.a_text);
@@ -634,7 +636,7 @@ caddr_t addr;
if (getenv("LD_SUPPRESS_WARNINGS") == NULL &&
getenv("LD_WARN_NON_PURE_CODE") != NULL)
- warnx("ld.so: warning: non pure code in %s at %x (%s)\n",
+ warnx("warning: non pure code in %s at %x (%s)",
smp->som_path, r->r_address, sym);
if (smp->som_write == 0 &&
@@ -884,7 +886,7 @@ lookup(name, src_map, strong)
* Search all maps for a definition of NAME
*/
for (smp = link_map_head; smp; smp = smp->som_next) {
- int buckets = LD_BUCKETS(smp->som_dynamic);
+ int buckets;
long hashval;
struct rrs_hash *hp;
char *cp;
@@ -896,10 +898,13 @@ lookup(name, src_map, strong)
char *stringbase;
int symsize;
- if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
+ if (*src_map && smp != *src_map)
continue;
- if (*src_map && smp != *src_map)
+ if ((buckets = LD_BUCKETS(smp->som_dynamic)) == 0)
+ continue;
+
+ if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
continue;
restart:
@@ -1042,8 +1047,9 @@ binder(jsp)
}
+static int hfd;
+static long hsize;
static struct hints_header *hheader;
-static long hmsize;
static struct hints_bucket *hbuckets;
static char *hstrtab;
@@ -1053,52 +1059,47 @@ static char *hstrtab;
maphints __P((void))
{
caddr_t addr;
- long msize;
- int fd;
- if ((fd = open(_PATH_LD_HINTS, O_RDONLY, 0)) == -1) {
+ if ((hfd = open(_PATH_LD_HINTS, O_RDONLY, 0)) == -1) {
hheader = (struct hints_header *)-1;
return;
}
- msize = PAGSIZ;
- addr = mmap(0, msize, PROT_READ, MAP_COPY, fd, 0);
+ hsize = PAGSIZ;
+ addr = mmap(0, hsize, PROT_READ, MAP_COPY, hfd, 0);
if (addr == (caddr_t)-1) {
- close(fd);
+ close(hfd);
hheader = (struct hints_header *)-1;
return;
}
hheader = (struct hints_header *)addr;
if (HH_BADMAG(*hheader)) {
- munmap(addr, msize);
- close(fd);
+ munmap(addr, hsize);
+ close(hfd);
hheader = (struct hints_header *)-1;
return;
}
if (hheader->hh_version != LD_HINTS_VERSION_1) {
- munmap(addr, msize);
- close(fd);
+ munmap(addr, hsize);
+ close(hfd);
hheader = (struct hints_header *)-1;
return;
}
- hmsize = msize;
- if (hheader->hh_ehints > msize) {
- hmsize = hheader->hh_ehints;
- if (mmap(addr+msize, hheader->hh_ehints - msize,
+ if (hheader->hh_ehints > hsize) {
+ if (mmap(addr+hsize, hheader->hh_ehints - hsize,
PROT_READ, MAP_COPY|MAP_FIXED,
- fd, msize) != (caddr_t)(addr+msize)) {
+ hfd, hsize) != (caddr_t)(addr+hsize)) {
- munmap((caddr_t)hheader, msize);
- close(fd);
+ munmap((caddr_t)hheader, hsize);
+ close(hfd);
hheader = (struct hints_header *)-1;
return;
}
}
- close(fd);
hbuckets = (struct hints_bucket *)(addr + hheader->hh_hashtab);
hstrtab = (char *)(addr + hheader->hh_strtab);
@@ -1107,8 +1108,10 @@ maphints __P((void))
static void
unmaphints()
{
+
if (HINTS_VALID) {
- munmap((caddr_t)hheader, hmsize);
+ munmap((caddr_t)hheader, hsize);
+ close(hfd);
hheader = NULL;
}
}
@@ -1404,4 +1407,3 @@ char *fmt;
(void)write(1, buf, strlen(buf));
va_end(ap);
}
-
diff --git a/gnu/usr.bin/ld/shlib.c b/gnu/usr.bin/ld/shlib.c
index 058689a..38cb2d1 100644
--- a/gnu/usr.bin/ld/shlib.c
+++ b/gnu/usr.bin/ld/shlib.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: shlib.c,v 1.10 1994/12/23 22:30:51 nate Exp $
+ * $Id: shlib.c,v 1.11 1995/01/05 02:36:29 swallace Exp $
*/
#include <sys/param.h>
@@ -54,7 +54,7 @@ char *strsep();
* Standard directories to search for files specified by -l.
*/
#ifndef STANDARD_SEARCH_DIRS
-#define STANDARD_SEARCH_DIRS "/usr/lib", "/usr/X11R6/lib", "/usr/local/lib"
+#define STANDARD_SEARCH_DIRS "/usr/lib", "/usr/local/lib"
#endif
/*
diff --git a/gnu/usr.bin/ld/sparc/md.h b/gnu/usr.bin/ld/sparc/md.h
index 3545d97..f83c1ff 100644
--- a/gnu/usr.bin/ld/sparc/md.h
+++ b/gnu/usr.bin/ld/sparc/md.h
@@ -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: md.h,v 1.5 1993/12/02 01:03:47 jkh Exp $
+ * $Id: md.h,v 1.6 1994/02/13 20:43:07 jkh Exp $
*/
/*
@@ -106,11 +106,21 @@
#define RELOC_STATICS_THROUGH_GOT_P(r) (1)
#define JMPSLOT_NEEDS_RELOC (1)
+/*
+ * Define the range of usable Global Offset Table offsets
+ * when using sparc 13 bit relocation types (-4096 - 4092).
+ */
+#define MAX_GOTSIZE (8192)
+#define MAX_GOTOFF (4092)
+#define MIN_GOTOFF (-4096)
+
#define CHECK_GOT_RELOC(r) \
((r)->r_type == RELOC_PC10 || (r)->r_type == RELOC_PC22)
#define md_got_reloc(r) (-(r)->r_address)
+#define RELOC_INIT_SEGMENT_RELOC(r) ((r)->r_type = RELOC_32)
+
#ifdef SUN_COMPAT
/*
* Sun plays games with `r_addend'
diff --git a/gnu/usr.bin/ld/sparc/mdprologue.S b/gnu/usr.bin/ld/sparc/mdprologue.S
index 0d006d0..d3236a3 100644
--- a/gnu/usr.bin/ld/sparc/mdprologue.S
+++ b/gnu/usr.bin/ld/sparc/mdprologue.S
@@ -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: mdprologue.S,v 1.2 1993/11/09 04:19:36 paul Exp $
+ * $Id: mdprologue.S,v 1.3 1994/02/13 20:43:13 jkh Exp $
*/
/*
@@ -56,7 +56,7 @@ L.2B:
add %i1, %fp, %i1 ! if so, adjust to absolute address
1:
ld [%i1], %o3 ! load base address (crtp->crt_ba)
- ld [%l7], %o2 ! get rtld's __DYNAMIC address
+ ld [%l7], %o2 ! get __DYNAMIC address
! from 1st GOT entry
add %o2, %o3, %o2 ! relocate and make it 3rd arg.
@@ -94,7 +94,7 @@ _binder_entry:
restore ! get rid of our context
jmp %g1 ! and go.
- restore ! and the jmpslot's
+ restore ! and the jmpslot context
nop
.seg "data" ! [internal]
diff --git a/gnu/usr.bin/ld/warnings.c b/gnu/usr.bin/ld/warnings.c
index 0479344..3c65a22 100644
--- a/gnu/usr.bin/ld/warnings.c
+++ b/gnu/usr.bin/ld/warnings.c
@@ -1,5 +1,5 @@
/*
- * $Id: warnings.c,v 1.8 1994/06/15 22:40:00 rich Exp $
+ * $Id: warnings.c,v 1.9 1994/12/23 22:30:57 nate Exp $
*/
#include <sys/param.h>
@@ -25,6 +25,8 @@
#include "ld.h"
+static int reported_undefineds;
+
/*
* Print the filename of ENTRY on OUTFILE (a stdio stream),
* and then a newline.
@@ -101,18 +103,21 @@ print_symbols(outfile)
fprintf(outfile, "\nGlobal symbols:\n\n");
FOR_EACH_SYMBOL(i, sp) {
- if (sp->defined == (N_UNDF|N_EXT))
- fprintf(outfile, " %s: common, length %#x\n",
- sp->name, sp->common_size);
+ fprintf(outfile, " %s: ", sp->name);
if (!(sp->flags & GS_REFERENCED))
- fprintf(outfile, " %s: unreferenced\n", sp->name);
+ fprintf(outfile, "unreferenced");
else if (sp->so_defined)
- fprintf(outfile, " %s: sodefined\n", sp->name);
+ fprintf(outfile, "sodefined");
else if (!sp->defined)
- fprintf(outfile, " %s: undefined\n", sp->name);
+ fprintf(outfile, "undefined");
+ else if (sp->defined == (N_UNDF|N_EXT))
+ fprintf(outfile, "common: size %#x", sp->common_size);
else
- fprintf(outfile, " %s: %#x, size %#x\n",
- sp->name, sp->value, sp->size);
+ fprintf(outfile, "type %d, value %#x, size %#x",
+ sp->defined, sp->value, sp->size);
+ if (sp->alias)
+ fprintf(outfile, ", aliased to %s", sp->alias->name);
+ fprintf(outfile, "\n");
} END_EACH_SYMBOL;
each_file(list_file_locals, (void *)outfile);
@@ -463,10 +468,11 @@ do_relocation_warnings(entry, data_segment, outfile, nlist_bitvector)
/* Mark as being noted by relocation warning pass. */
SET_BIT(nlist_bitvector, lsp - start_of_syms);
+ if (g->undef_refs == 0)
+ reported_undefineds++;
if (g->undef_refs >= MAX_UREFS_PRINTED)
/* Listed too many */
continue;
-
/* Undefined symbol which we should mention */
if (++(g->undef_refs) == MAX_UREFS_PRINTED) {
@@ -632,10 +638,28 @@ do_file_warnings (entry, outfile)
line_number = -1;
break;
- default:
-warnx("Unexpected multiple definitions of symbol `%s', type %#x\n", g->name, np->n_type);
+ case N_SIZE | N_EXT:
+ errfmt =
+ "Size element definition of symbol `%s' (multiply defined)";
+ line_number = -1;
+ break;
+
+ case N_INDR | N_EXT:
+ errfmt =
+ "Alias definition of symbol `%s' (multiply defined)";
+ line_number = -1;
+ break;
+
+ case N_UNDF | N_EXT:
/* Don't print out multiple defs at references.*/
continue;
+
+ default:
+ warnx("%s: unexpected multiple definitions "
+ "of symbol `%s', type %#x",
+ get_file_name(entry),
+ g->name, np->n_type);
+ break;
}
} else if (BIT_SET_P(nlist_bitvector, i)) {
@@ -643,9 +667,10 @@ warnx("Unexpected multiple definitions of symbol `%s', type %#x\n", g->name, np-
} else if (list_unresolved_refs &&
!g->defined && !g->so_defined) {
+ if (g->undef_refs == 0)
+ reported_undefineds++;
if (g->undef_refs >= MAX_UREFS_PRINTED)
continue;
-
if (++(g->undef_refs) == MAX_UREFS_PRINTED)
errfmt = "More undefined `%s' refs follow";
else
@@ -656,7 +681,7 @@ warnx("Unexpected multiple definitions of symbol `%s', type %#x\n", g->name, np-
g->def_lsp->entry->flags & E_SECONDCLASS) {
fprintf(outfile,
"%s: Undefined symbol `%s' referenced (use %s ?)\n",
- entry->filename,
+ get_file_name(entry),
g->name,
g->def_lsp->entry->local_sym_name);
continue;
@@ -678,7 +703,7 @@ warnx("Unexpected multiple definitions of symbol `%s', type %#x\n", g->name, np-
continue;
if (line_number == -1)
- fprintf(outfile, "%s: ", entry->filename);
+ fprintf(outfile, "%s: ", get_file_name(entry));
else
fprintf(outfile, "%s:%d: ", file_name, line_number);
@@ -698,8 +723,11 @@ int
do_warnings(outfile)
FILE *outfile;
{
+
list_unresolved_refs = !relocatable_output &&
- (undefined_global_sym_count || undefined_shobj_sym_count);
+ ( (undefined_global_sym_count - undefined_weak_sym_count) > 0
+ || undefined_shobj_sym_count
+ );
list_multiple_defs = multiple_def_count != 0;
if (!(list_unresolved_refs ||
@@ -714,6 +742,14 @@ do_warnings(outfile)
each_file(do_file_warnings, (void *)outfile);
+ if (list_unresolved_refs &&
+ reported_undefineds !=
+ (undefined_global_sym_count - undefined_weak_sym_count))
+ warnx("Spurious undefined symbols: "
+ "# undefined symbols %d, reported %d",
+ (undefined_global_sym_count - undefined_weak_sym_count),
+ reported_undefineds);
+
if (list_unresolved_refs || list_multiple_defs)
return 0;
OpenPOWER on IntegriCloud