summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gnu/usr.bin/ld/etc.c54
-rw-r--r--gnu/usr.bin/ld/i386/md-static-funcs.c4
-rw-r--r--gnu/usr.bin/ld/i386/md.c65
-rw-r--r--gnu/usr.bin/ld/i386/md.h98
-rw-r--r--gnu/usr.bin/ld/ld.133
-rw-r--r--gnu/usr.bin/ld/ld.1aout33
-rw-r--r--gnu/usr.bin/ld/ld.c903
-rw-r--r--gnu/usr.bin/ld/ld.h637
-rw-r--r--gnu/usr.bin/ld/ldconfig/Makefile10
-rw-r--r--gnu/usr.bin/ld/ldconfig/ldconfig.82
-rw-r--r--gnu/usr.bin/ld/ldconfig/ldconfig.c36
-rw-r--r--gnu/usr.bin/ld/ldd/ldd.12
-rw-r--r--gnu/usr.bin/ld/ldd/ldd.c5
-rw-r--r--gnu/usr.bin/ld/lib.c244
-rw-r--r--gnu/usr.bin/ld/rrs.c258
-rw-r--r--gnu/usr.bin/ld/rtld/Makefile20
-rw-r--r--gnu/usr.bin/ld/rtld/rtld.c1024
-rw-r--r--gnu/usr.bin/ld/shlib.c40
-rw-r--r--gnu/usr.bin/ld/sparc/md.c76
-rw-r--r--gnu/usr.bin/ld/sparc/md.h65
-rw-r--r--gnu/usr.bin/ld/sparc/mdprologue.S4
-rw-r--r--gnu/usr.bin/ld/symbol.c70
-rw-r--r--gnu/usr.bin/ld/warnings.c58
-rw-r--r--gnu/usr.bin/ld/xbits.c65
-rw-r--r--libexec/rtld-aout/Makefile20
-rw-r--r--libexec/rtld-aout/i386/md-static-funcs.c4
-rw-r--r--libexec/rtld-aout/i386/md.c65
-rw-r--r--libexec/rtld-aout/i386/md.h98
-rw-r--r--libexec/rtld-aout/rtld.c1024
-rw-r--r--libexec/rtld-aout/shlib.c40
-rw-r--r--sbin/ldconfig/Makefile10
-rw-r--r--sbin/ldconfig/ldconfig.82
-rw-r--r--sbin/ldconfig/ldconfig.c36
-rw-r--r--usr.bin/ldd/ldd.12
-rw-r--r--usr.bin/ldd/ldd.c5
35 files changed, 2838 insertions, 2274 deletions
diff --git a/gnu/usr.bin/ld/etc.c b/gnu/usr.bin/ld/etc.c
index 22fdfd8..2ddd50a 100644
--- a/gnu/usr.bin/ld/etc.c
+++ b/gnu/usr.bin/ld/etc.c
@@ -1,5 +1,5 @@
/*
- * $Id: etc.c,v 1.5 1993/12/04 00:52:55 jkh Exp $
+ * $Id: etc.c,v 1.6 1993/12/11 11:58:22 jkh Exp $
*/
#include <sys/param.h>
@@ -48,6 +48,7 @@ error(fmt, va_alist)
va_end(ap);
}
+void (*fatal_cleanup_hook)__P((void));
/*
* Report a fatal error.
*/
@@ -72,8 +73,8 @@ fatal(fmt, va_alist)
(void)fprintf(stderr, "\n");
va_end(ap);
- if (outdesc >= 0)
- unlink(output_filename);
+ if (fatal_cleanup_hook)
+ (*fatal_cleanup_hook)();
exit(1);
}
@@ -148,50 +149,3 @@ xrealloc(ptr, size)
return result;
}
-
-
-
-/* These must move */
-
-#ifndef RTLD
-/*
- * Output COUNT*ELTSIZE bytes of data at BUF to the descriptor DESC.
- */
-void
-mywrite (buf, count, eltsize, desc)
- char *buf;
- int count;
- int eltsize;
- int desc;
-{
- register int val;
- register int bytes = count * eltsize;
-
- while (bytes > 0) {
- val = write (desc, buf, bytes);
- if (val <= 0)
- perror(output_filename);
- buf += val;
- bytes -= val;
- }
-}
-
-/*
- * Output PADDING zero-bytes to descriptor OUTDESC.
- * PADDING may be negative; in that case, do nothing.
- */
-
-void
-padfile (padding, outdesc)
- int padding;
- int outdesc;
-{
- register char *buf;
- if (padding <= 0)
- return;
-
- buf = (char *) alloca (padding);
- bzero (buf, padding);
- mywrite (buf, padding, 1, outdesc);
-}
-#endif
diff --git a/gnu/usr.bin/ld/i386/md-static-funcs.c b/gnu/usr.bin/ld/i386/md-static-funcs.c
index 2cd0768..4741685 100644
--- a/gnu/usr.bin/ld/i386/md-static-funcs.c
+++ b/gnu/usr.bin/ld/i386/md-static-funcs.c
@@ -1,8 +1,10 @@
-
/*
+ * $Id: md-static-funcs.c,v 1.2 1993/12/08 10:14:44 pk Exp $
+ *
* Called by ld.so when onanating.
* This *must* be a static function, so it is not called through a jmpslot.
*/
+
static void
md_relocate_simple(r, relocation, addr)
struct relocation_info *r;
diff --git a/gnu/usr.bin/ld/i386/md.c b/gnu/usr.bin/ld/i386/md.c
index f78c6cc..311a5f6 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.7 1994/01/03 18:35:35 davidg Exp $
+ * $Id: md.c,v 1.8 1994/01/19 15:00:37 davidg Exp $
*/
#include <sys/param.h>
@@ -41,8 +41,6 @@
#include "ld.h"
-int netzmagic = 0;
-
/*
* Get relocation addend corresponding to relocation record RP
* from address ADDR
@@ -90,29 +88,6 @@ unsigned char *addr;
}
/*
- * Initialize (output) exec header such that useful values are
- * obtained from subsequent N_*() macro evaluations.
- */
-void
-md_init_header(hp, magic, flags)
-struct exec *hp;
-int magic, flags;
-{
- if (!netzmagic && (magic == ZMAGIC)) {
- hp->a_midmag = magic;
- } else {
- if (netzmagic)
- N_SETMAGIC_NET((*hp), magic, MID_I386, flags);
- else
- N_SETMAGIC((*hp), magic, MID_I386, flags);
- }
-
- /* TEXT_START depends on the value of outheader.a_entry. */
- if (!(link_mode & SHAREABLE)) /*WAS: if (entry_symbol) */
- hp->a_entry = PAGSIZ;
-}
-
-/*
* Machine dependent part of claim_rrs_reloc().
* Set RRS relocation type.
*/
@@ -251,9 +226,45 @@ long *savep;
*(char *)where = TRAP;
}
-#ifdef NEED_SWAP
+#ifndef RTLD
+
+#ifdef FreeBSD
+int netzmagic;
+#endif
/*
+ * Initialize (output) exec header such that useful values are
+ * obtained from subsequent N_*() macro evaluations.
+ */
+void
+md_init_header(hp, magic, flags)
+struct exec *hp;
+int magic, flags;
+{
+#ifdef NetBSD
+ if (oldmagic || magic == QMAGIC)
+ hp->a_midmag = magic;
+ else
+ N_SETMAGIC((*hp), magic, MID_I386, flags);
+#endif
+#ifdef FreeBSD
+ if (oldmagic)
+ hp->a_midmag = magic;
+ else if (netzmagic)
+ N_SETMAGIC_NET((*hp), magic, MID_I386, flags);
+ else
+ N_SETMAGIC((*hp), magic, MID_I386, flags);
+#endif
+
+ /* TEXT_START depends on the value of outheader.a_entry. */
+ if (!(link_mode & SHAREABLE)) /*WAS: if (entry_symbol) */
+ hp->a_entry = PAGSIZ;
+}
+#endif /* RTLD */
+
+
+#ifdef NEED_SWAP
+/*
* Byte swap routines for cross-linking.
*/
diff --git a/gnu/usr.bin/ld/i386/md.h b/gnu/usr.bin/ld/i386/md.h
index 7286a74..bbb28f2 100644
--- a/gnu/usr.bin/ld/i386/md.h
+++ b/gnu/usr.bin/ld/i386/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.7 1994/01/03 18:35:36 davidg Exp $
+ * $Id: md.h,v 1.8 1994/01/19 15:00:37 davidg Exp $
*/
@@ -45,17 +45,41 @@
#define PAGSIZ 4096
#endif
-#define N_SET_FLAG(ex,f) (netzmagic ? \
- N_SETMAGIC_NET(ex,N_GETMAGIC_NET(ex), MID_MACHINE, \
- N_GETFLAG_NET(ex)|(f)) : \
- N_GETMAGIC(ex) == ZMAGIC ? \
- N_SETMAGIC(ex,ZMAGIC,0,N_GETFLAG(ex)|(f)) : \
- N_SETMAGIC(ex,N_GETMAGIC(ex), MID_MACHINE, \
- N_GETFLAG(ex)|(f)))
-
-#define N_IS_DYNAMIC(ex) ((N_GETMAGIC_NET(ex) == ZMAGIC) ? \
- ((N_GETFLAG_NET(ex) & EX_DYNAMIC)) : \
- ((N_GETFLAG(ex) & EX_DYNAMIC)))
+#if defined(NetBSD) || defined(CROSS_LINKER)
+
+#define N_SET_FLAG(ex,f) (oldmagic || N_GETMAGIC(ex)==QMAGIC ? (0) : \
+ N_SETMAGIC(ex, \
+ N_GETMAGIC(ex), \
+ MID_MACHINE, \
+ N_GETFLAG(ex)|(f)))
+
+#define N_IS_DYNAMIC(ex) ((N_GETFLAG(ex) & EX_DYNAMIC))
+
+#define N_BADMID(ex) \
+ (N_GETMID(ex) != 0 && N_GETMID(ex) != MID_MACHINE)
+
+#endif
+
+/*
+ * FreeBSD does it differently
+ */
+#ifdef FreeBSD
+#define N_SET_FLAG(ex,f) (oldmagic ? (0) : \
+ (netzmagic == 0 ? \
+ N_SETMAGIC(ex, \
+ N_GETMAGIC(ex), \
+ MID_MACHINE, \
+ N_GETFLAG(ex)|(f)) : \
+ N_SETMAGIC_NET(ex, \
+ N_GETMAGIC_NET(ex), \
+ MID_MACHINE, \
+ N_GETFLAG_NET(ex)|(f)) ))
+
+#define N_IS_DYNAMIC(ex) ((N_GETMAGIC_NET(ex) == ZMAGIC) ? \
+ ((N_GETFLAG_NET(ex) & EX_DYNAMIC)) : \
+ ((N_GETFLAG(ex) & EX_DYNAMIC) ))
+#define N_BADMID(ex) 0
+#endif
/*
* Should be handled by a.out.h ?
@@ -101,16 +125,16 @@ typedef struct jmpslot {
#define md_swapout_zsymbols(s,n)
#define md_swapin_reloc(r,n)
#define md_swapout_reloc(r,n)
-#define md_swapin_link_dynamic(l)
-#define md_swapout_link_dynamic(l)
-#define md_swapin_link_dynamic_2(l)
-#define md_swapout_link_dynamic_2(l)
-#define md_swapin_ld_debug(d)
-#define md_swapout_ld_debug(d)
+#define md_swapin__dynamic(l)
+#define md_swapout__dynamic(l)
+#define md_swapin_section_dispatch_table(l)
+#define md_swapout_section_dispatch_table(l)
+#define md_swapin_so_debug(d)
+#define md_swapout_so_debug(d)
#define md_swapin_rrs_hash(f,n)
#define md_swapout_rrs_hash(f,n)
-#define md_swapin_link_object(l,n)
-#define md_swapout_link_object(l,n)
+#define md_swapin_sod(l,n)
+#define md_swapout_sod(l,n)
#define md_swapout_jmpslot(j,n)
#define md_swapout_got(g,n)
#define md_swapin_ranlib_hdr(h,n)
@@ -130,23 +154,23 @@ void md_swapin_reloc __P((struct relocation_info *, int));
void md_swapout_reloc __P((struct relocation_info *, int));
void md_swapout_jmpslot __P((jmpslot_t *, int));
-#define md_swapin_symbols(s,n) swap_symbols(s,n)
-#define md_swapout_symbols(s,n) swap_symbols(s,n)
-#define md_swapin_zsymbols(s,n) swap_zsymbols(s,n)
-#define md_swapout_zsymbols(s,n) swap_zsymbols(s,n)
-#define md_swapin_link_dynamic(l) swap_link_dynamic(l)
-#define md_swapout_link_dynamic(l) swap_link_dynamic(l)
-#define md_swapin_link_dynamic_2(l) swap_link_dynamic_2(l)
-#define md_swapout_link_dynamic_2(l) swap_link_dynamic_2(l)
-#define md_swapin_ld_debug(d) swap_ld_debug(d)
-#define md_swapout_ld_debug(d) swap_ld_debug(d)
-#define md_swapin_rrs_hash(f,n) swap_rrs_hash(f,n)
-#define md_swapout_rrs_hash(f,n) swap_rrs_hash(f,n)
-#define md_swapin_link_object(l,n) swapin_link_object(l,n)
-#define md_swapout_link_object(l,n) swapout_link_object(l,n)
-#define md_swapout_got(g,n) swap_longs((long*)(g),n)
-#define md_swapin_ranlib_hdr(h,n) swap_ranlib_hdr(h,n)
-#define md_swapout_ranlib_hdr(h,n) swap_ranlib_hdr(h,n)
+#define md_swapin_symbols(s,n) swap_symbols(s,n)
+#define md_swapout_symbols(s,n) swap_symbols(s,n)
+#define md_swapin_zsymbols(s,n) swap_zsymbols(s,n)
+#define md_swapout_zsymbols(s,n) swap_zsymbols(s,n)
+#define md_swapin__dynamic(l) swap__dynamic(l)
+#define md_swapout__dynamic(l) swap__dynamic(l)
+#define md_swapin_section_dispatch_table(l) swap_section_dispatch_table(l)
+#define md_swapout_section_dispatch_table(l) swap_section_dispatch_table(l)
+#define md_swapin_so_debug(d) swap_so_debug(d)
+#define md_swapout_so_debug(d) swap_so_debug(d)
+#define md_swapin_rrs_hash(f,n) swap_rrs_hash(f,n)
+#define md_swapout_rrs_hash(f,n) swap_rrs_hash(f,n)
+#define md_swapin_sod(l,n) swapin_sod(l,n)
+#define md_swapout_sod(l,n) swapout_sod(l,n)
+#define md_swapout_got(g,n) swap_longs((long*)(g),n)
+#define md_swapin_ranlib_hdr(h,n) swap_ranlib_hdr(h,n)
+#define md_swapout_ranlib_hdr(h,n) swap_ranlib_hdr(h,n)
#define md_swap_short(x) ( (((x) >> 8) & 0xff) | (((x) & 0xff) << 8) )
diff --git a/gnu/usr.bin/ld/ld.1 b/gnu/usr.bin/ld/ld.1
index 06855d8..3295282 100644
--- a/gnu/usr.bin/ld/ld.1
+++ b/gnu/usr.bin/ld/ld.1
@@ -14,7 +14,7 @@
.\" must display the following acknowledgement:
.\" This product includes software developed by Paul Kranenburg.
.\" 3. The name of the author may not be used to endorse or promote products
-.\" derived from this software withough specific prior written permission
+.\" derived from this software without 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
@@ -27,11 +27,11 @@
.\" (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: ld.1,v 1.3 1994/01/03 23:52:35 jkh Exp $
+.\" $Id: ld.1,v 1.5 1994/01/29 02:03:04 jtc Exp $
.\"
.Dd October 14, 1993
.Dt LD 8
-.Os FreeBSD
+.Os FreeBSD 1.1
.Sh NAME
.Nm ld
.Nd link editor
@@ -69,7 +69,7 @@ The options are as follows:
.It Fl A Ar symbol-file
The the symbol-file is taken as a base for link-editing the object files
on the command line.
-.It \-assert Ar keyword
+.It Fl a\&ssert Ar keyword
This option has currently no effect. It is here for compatibility with
SunOS ld. All conditions which would cause a Sun assertion to fail will
currently always cause error or warning messages from
@@ -85,7 +85,7 @@ found a traditional archive is looked for.
This options can appear anywhere on the command line and is complementary
to -Bstatic.
.It Fl B Ar static
-The counterpart of -Bdynamic. This options turns off dynamic linking for
+The counterpart of -Bdynamic. This option turns off dynamic linking for
all library specifiers until a -Bdynamic is once again given. Any explicitly
mentioned shared object encountered on the command line while this option is
in effect is flagged as an error.
@@ -170,27 +170,30 @@ Discard local symbols in the input files that start with the letter
.Dq L
.It Fl x
Discard all local symbols in the input files.
-.It Fl y symbol
+.It Fl y Ar symbol
Trace the manipulations inflicted on
.Ar symbol
-.It Fl Z
-Make a NetBSD 0.9 ZMAGIC output file.
.It Fl z
-Make a ZMAGIC output file. This is the older 386BSD / FreeBSD 1.0 format.
+Make a NetBSD 0.9 ZMAGIC output file.
.Sh FILES
-
.Sh SEE ALSO
.Xr ldconfig 1 ,
.Xr link 5
-.Sh BUGS
-Spurious
-.Dq undefined symbols errors
-may be reported for symbols originating in shared libraries. This occurs
-when there is also at least one genuine undefined symbol to report.
.Sh CAVEATS
An entry point must now explicitly be given if the output is intended to be
a normal executable program. This was not the case for the previous version of
.Nm ld\&.
+.Sh BUGS
+Shared objects are not properly checked for undefined symbols.
+.Pp
+Cascading of shared object defeats the
+.Dq -Bstatic
+option.
+.Pp
+All shared objects presented to
+.Nm ld
+are marked for run-time loading in the output file, even if no symbols
+are needed from them.
.Sh HISTORY
The shared library model employed by
.Nm ld
diff --git a/gnu/usr.bin/ld/ld.1aout b/gnu/usr.bin/ld/ld.1aout
index 06855d8..3295282 100644
--- a/gnu/usr.bin/ld/ld.1aout
+++ b/gnu/usr.bin/ld/ld.1aout
@@ -14,7 +14,7 @@
.\" must display the following acknowledgement:
.\" This product includes software developed by Paul Kranenburg.
.\" 3. The name of the author may not be used to endorse or promote products
-.\" derived from this software withough specific prior written permission
+.\" derived from this software without 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
@@ -27,11 +27,11 @@
.\" (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: ld.1,v 1.3 1994/01/03 23:52:35 jkh Exp $
+.\" $Id: ld.1,v 1.5 1994/01/29 02:03:04 jtc Exp $
.\"
.Dd October 14, 1993
.Dt LD 8
-.Os FreeBSD
+.Os FreeBSD 1.1
.Sh NAME
.Nm ld
.Nd link editor
@@ -69,7 +69,7 @@ The options are as follows:
.It Fl A Ar symbol-file
The the symbol-file is taken as a base for link-editing the object files
on the command line.
-.It \-assert Ar keyword
+.It Fl a\&ssert Ar keyword
This option has currently no effect. It is here for compatibility with
SunOS ld. All conditions which would cause a Sun assertion to fail will
currently always cause error or warning messages from
@@ -85,7 +85,7 @@ found a traditional archive is looked for.
This options can appear anywhere on the command line and is complementary
to -Bstatic.
.It Fl B Ar static
-The counterpart of -Bdynamic. This options turns off dynamic linking for
+The counterpart of -Bdynamic. This option turns off dynamic linking for
all library specifiers until a -Bdynamic is once again given. Any explicitly
mentioned shared object encountered on the command line while this option is
in effect is flagged as an error.
@@ -170,27 +170,30 @@ Discard local symbols in the input files that start with the letter
.Dq L
.It Fl x
Discard all local symbols in the input files.
-.It Fl y symbol
+.It Fl y Ar symbol
Trace the manipulations inflicted on
.Ar symbol
-.It Fl Z
-Make a NetBSD 0.9 ZMAGIC output file.
.It Fl z
-Make a ZMAGIC output file. This is the older 386BSD / FreeBSD 1.0 format.
+Make a NetBSD 0.9 ZMAGIC output file.
.Sh FILES
-
.Sh SEE ALSO
.Xr ldconfig 1 ,
.Xr link 5
-.Sh BUGS
-Spurious
-.Dq undefined symbols errors
-may be reported for symbols originating in shared libraries. This occurs
-when there is also at least one genuine undefined symbol to report.
.Sh CAVEATS
An entry point must now explicitly be given if the output is intended to be
a normal executable program. This was not the case for the previous version of
.Nm ld\&.
+.Sh BUGS
+Shared objects are not properly checked for undefined symbols.
+.Pp
+Cascading of shared object defeats the
+.Dq -Bstatic
+option.
+.Pp
+All shared objects presented to
+.Nm ld
+are marked for run-time loading in the output file, even if no symbols
+are needed from them.
.Sh HISTORY
The shared library model employed by
.Nm ld
diff --git a/gnu/usr.bin/ld/ld.c b/gnu/usr.bin/ld/ld.c
index ad6f9a6..1d63c82 100644
--- a/gnu/usr.bin/ld/ld.c
+++ b/gnu/usr.bin/ld/ld.c
@@ -32,7 +32,7 @@ static char sccsid[] = "@(#)ld.c 6.10 (Berkeley) 5/22/91";
Set, indirect, and warning symbol features added by Randy Smith. */
/*
- * $Id: ld.c,v 1.18 1994/01/03 18:35:14 davidg Exp $
+ * $Id: ld.c,v 1.19 1994/01/19 15:00:27 davidg Exp $
*/
/* Define how to initialize system-dependent header fields. */
@@ -55,17 +55,18 @@ static char sccsid[] = "@(#)ld.c 6.10 (Berkeley) 5/22/91";
#include "ld.h"
-#ifndef DEFAULT_SOVERSION
-#define DEFAULT_SOVERSION LD_VERSION_BSD
-#endif
-
-int building_shared_object;
+/* Vector of entries for input files specified by arguments.
+ These are all the input files except for members of specified libraries. */
+struct file_entry *file_table;
+int number_of_files;
-/* 1 => write relocation into output file so can re-input it later. */
+/* 1 => write relocation into output file so can re-input it later. */
int relocatable_output;
-/* Non zero means to create the output executable. */
-/* Cleared by nonfatal errors. */
+/* 1 => building a shared object, set by `-Bshareable'. */
+int building_shared_object;
+
+/* 1 => create the output executable. */
int make_executable;
/* Force the executable to be output, even if there are non-fatal errors */
@@ -81,9 +82,72 @@ int force_alias_definition;
if `relocatable_output'. */
int pic_code_seen;
+/* 1 => segments must be page aligned (ZMAGIC, QMAGIC) */
+int page_align_segments;
+
/* 1 => data segment must be page aligned, even if `-n' or `-N' */
int page_align_data;
+/* Version number to put in __DYNAMIC (set by -V) */
+int soversion;
+
+int text_size; /* total size of text. */
+int text_start; /* start of text */
+int text_pad; /* clear space between text and data */
+int data_size; /* total size of data. */
+int data_start; /* start of data */
+int data_pad; /* part of bss segment as part of data */
+
+int bss_size; /* total size of bss. */
+int bss_start; /* start of bss */
+
+int text_reloc_size; /* total size of text relocation. */
+int data_reloc_size; /* total size of data relocation. */
+
+int rrs_section_type; /* What's in the RRS section */
+int rrs_text_size; /* Size of RRS text additions */
+int rrs_text_start; /* Location of above */
+int rrs_data_size; /* Size of RRS data additions */
+int rrs_data_start; /* Location of above */
+
+/* Specifications of start and length of the area reserved at the end
+ of the data segment for the set vectors. Computed in 'digest_symbols' */
+int set_sect_start; /* start of set element vectors */
+int set_sect_size; /* size of above */
+
+int link_mode; /* Current link mode */
+
+/*
+ * When loading the text and data, we can avoid doing a close
+ * and another open between members of the same library.
+ *
+ * These two variables remember the file that is currently open.
+ * Both are zero if no file is open.
+ *
+ * See `each_file' and `file_close'.
+ */
+struct file_entry *input_file;
+int input_desc;
+
+/* The name of the file to write; "a.out" by default. */
+char *output_filename; /* Output file name. */
+int outdesc; /* Output file descriptor. */
+struct exec outheader; /* Output file header. */
+int magic; /* Output file magic. */
+int oldmagic;
+int relocatable_output; /* `-r'-ed output */
+
+symbol *entry_symbol;
+int entry_offset;
+
+int page_size; /* Size of a page (machine dependent) */
+
+/* Keep a list of any symbols referenced from the command line (so
+ that error messages for these guys can be generated). This list is
+ zero terminated. */
+struct glosym **cmdline_references;
+int cl_refs_allocated;
+
/*
* Which symbols should be stripped (omitted from the output): none, all, or
* debugger symbols.
@@ -100,11 +164,33 @@ enum {
DISCARD_NONE, DISCARD_ALL, DISCARD_L
} discard_locals;
-/* Nonzero means print names of input files as processed. */
-int trace_files;
+int global_sym_count; /* # of nlist entries for global symbols */
+int size_sym_count; /* # of N_SIZE nlist entries for output
+ (relocatable_output only) */
+int local_sym_count; /* # of nlist entries for local symbols. */
+int non_L_local_sym_count; /* # of nlist entries for non-L symbols */
+int debugger_sym_count; /* # of nlist entries for debugger info. */
+int undefined_global_sym_count; /* # of global symbols referenced and
+ not defined. */
+int undefined_shobj_sym_count; /* # of undefined symbols referenced
+ by shared objects */
+int multiple_def_count; /* # of multiply defined symbols. */
+int defined_global_sym_count; /* # of defined global symbols. */
+int common_defined_global_count; /* # of common symbols. */
+
+int special_sym_count; /* # of linker defined symbols. */
+ /* XXX - Currently, only __DYNAMIC and _G_O_T_ go here if required,
+ * perhaps _etext, _edata and _end should go here too.
+ */
+int global_alias_count; /* # of aliased symbols */
+int set_symbol_count; /* # of N_SET* symbols. */
+int set_vector_count; /* # of set vectors in output. */
+int warning_count; /* # of warning symbols encountered. */
-/* Magic number to use for the output file, set by switch. */
-int magic;
+struct string_list_element *set_element_prefixes;
+
+int trace_files; /* print names of input files as processed (`-t'). */
+int write_map; /* write a load map (`-M') */
/*
* `text-start' address is normally this much plus a page boundary.
@@ -137,6 +223,7 @@ int setv_fill_count;
static void decode_option __P((char *, char *));
static void decode_command __P((int, char **));
static int classify_arg __P((char *));
+static void load_symbols __P((void));
static void enter_global_ref __P((struct localsymbol *,
char *, struct file_entry *));
static void digest_symbols __P((void));
@@ -144,6 +231,7 @@ static void digest_pass1 __P((void)), digest_pass2 __P((void));
static void consider_file_section_lengths __P((struct file_entry *));
static void relocate_file_addresses __P((struct file_entry *));
static void consider_relocation __P((struct file_entry *, int));
+static void consider_local_symbols __P((struct file_entry *));
static void perform_relocation __P((char *, int,
struct relocation_info *, int,
struct file_entry *, int));
@@ -151,7 +239,15 @@ static void copy_text __P((struct file_entry *));
static void copy_data __P((struct file_entry *));
static void coptxtrel __P((struct file_entry *));
static void copdatrel __P((struct file_entry *));
+static void write_output __P((void));
+static void write_header __P((void));
+static void write_text __P((void));
+static void write_data __P((void));
+static void write_rel __P((void));
+static void write_syms __P((void));
static void assign_symbolnums __P((struct file_entry *, int *));
+static void myfatal __P((void));
+
int
main(argc, argv)
@@ -189,6 +285,7 @@ main(argc, argv)
data_pad = 0;
text_pad = 0;
+ page_align_segments = 0;
page_align_data = 0;
/* Initialize the data about options. */
@@ -251,6 +348,9 @@ main(argc, argv)
* of system and on the output format selected.
*/
+ if (magic == ZMAGIC || magic == QMAGIC)
+ page_align_segments = 1;
+
md_init_header(&outheader, magic, 0);
text_size = sizeof(struct exec);
@@ -430,15 +530,15 @@ decode_command(argc, argv)
fatal("-A specified before an input file other than the first");
p->filename = string;
p->local_sym_name = string;
- p->just_syms_flag = 1;
+ p->flags |= E_JUST_SYMS;
p++;
}
if (argv[i][1] == 'l') {
p->filename = string;
p->local_sym_name = concat("-l", string, "");
- p->search_dirs_flag = 1;
+ p->flags |= E_SEARCH_DIRS;
if (link_mode & DYNAMIC && !relocatable_output)
- p->search_dynamic_flag = 1;
+ p->flags |= E_SEARCH_DYNAMIC;
p++;
}
i += code - 1;
@@ -446,8 +546,8 @@ decode_command(argc, argv)
/* Now check some option settings for consistency. */
- if ((magic != OMAGIC)
- && (text_start - text_start_alignment) & (page_size - 1))
+ if (page_align_segments
+ && (text_start - text_start_alignment) & (page_size - 1))
fatal("-T argument not multiple of page size, with sharable output");
/* Append the standard search directories to the user-specified ones. */
@@ -456,9 +556,9 @@ decode_command(argc, argv)
void
add_cmdline_ref(sp)
- struct glosym *sp;
+ symbol *sp;
{
- struct glosym **ptr;
+ symbol **ptr;
for (ptr = cmdline_references;
ptr < cmdline_references + cl_refs_allocated && *ptr;
@@ -474,7 +574,7 @@ add_cmdline_ref(sp)
ptr = cmdline_references + diff;
}
*ptr++ = sp;
- *ptr = (struct glosym *) 0;
+ *ptr = (symbol *) 0;
}
int
@@ -505,7 +605,6 @@ static void
decode_option(swt, arg)
register char *swt, *arg;
{
- /* We get Bstatic from gcc on suns. */
if (!strcmp(swt + 1, "Bstatic"))
return;
if (!strcmp(swt + 1, "Bdynamic"))
@@ -558,9 +657,10 @@ decode_option(swt, arg)
case 'e':
entry_symbol = getsym(arg);
- if (!entry_symbol->defined && !entry_symbol->referenced)
+ if (!entry_symbol->defined &&
+ !(entry_symbol->flags & GS_REFERENCED))
undefined_global_sym_count++;
- entry_symbol->referenced = 1;
+ entry_symbol->flags |= GS_REFERENCED;
add_cmdline_ref(entry_symbol);
return;
@@ -579,19 +679,9 @@ decode_option(swt, arg)
magic = OMAGIC;
return;
-#ifdef NMAGIC
case 'n':
magic = NMAGIC;
return;
-#endif
-
- case 'Q':
- magic = QMAGIC;
- return;
- case 'Z':
- magic = ZMAGIC;
- netzmagic = 1;
- return;
case 'o':
output_filename = arg;
@@ -601,6 +691,12 @@ decode_option(swt, arg)
page_align_data = 1;
return;
+#ifdef QMAGIC
+ case 'Q':
+ magic = QMAGIC;
+ return;
+#endif
+
case 'r':
relocatable_output = 1;
magic = OMAGIC;
@@ -628,9 +724,9 @@ decode_option(swt, arg)
{
register symbol *sp = getsym(arg);
- if (!sp->defined && !sp->referenced)
+ if (!sp->defined && !(sp->flags & GS_REFERENCED))
undefined_global_sym_count++;
- sp->referenced = 1;
+ sp->flags |= GS_REFERENCED;
add_cmdline_ref(sp);
}
return;
@@ -652,12 +748,17 @@ decode_option(swt, arg)
case 'y':
{
register symbol *sp = getsym(&swt[2]);
- sp->trace = 1;
+ sp->flags |= GS_TRACE;
}
return;
case 'z':
magic = ZMAGIC;
+ oldmagic = 0;
+ return;
+
+ case 'Z':
+ magic = oldmagic = ZMAGIC;
return;
default:
@@ -686,15 +787,15 @@ each_file(function, arg)
register struct file_entry *entry = &file_table[i];
register struct file_entry *subentry;
- if (entry->scrapped)
+ if (entry->flags & E_SCRAPPED)
continue;
- if (!entry->library_flag)
+ if (!(entry->flags & E_IS_LIBRARY))
(*function) (entry, arg);
subentry = entry->subfiles;
for (; subentry; subentry = subentry->chain) {
- if (subentry->scrapped)
+ if (subentry->flags & E_SCRAPPED)
continue;
(*function) (subentry, arg);
}
@@ -702,15 +803,15 @@ each_file(function, arg)
#ifdef SUN_COMPAT
if (entry->silly_archive) {
- if (!entry->is_dynamic)
+ if (!(entry->flags & E_DYNAMIC))
error("Silly");
- if (!entry->silly_archive->library_flag)
+ if (!(entry->silly_archive->flags & E_IS_LIBRARY))
error("Sillier");
subentry = entry->silly_archive->subfiles;
for (; subentry; subentry = subentry->chain) {
- if (subentry->scrapped)
+ if (subentry->flags & E_SCRAPPED)
continue;
(*function) (subentry, arg);
}
@@ -738,12 +839,12 @@ check_each_file(function, arg)
for (i = 0; i < number_of_files; i++) {
register struct file_entry *entry = &file_table[i];
- if (entry->scrapped)
+ if (entry->flags & E_SCRAPPED)
continue;
- if (entry->library_flag) {
+ if (entry->flags & E_IS_LIBRARY) {
register struct file_entry *subentry = entry->subfiles;
for (; subentry; subentry = subentry->chain) {
- if (subentry->scrapped)
+ if (subentry->flags & E_SCRAPPED)
continue;
if (return_val = (*function) (subentry, arg))
return return_val;
@@ -767,35 +868,35 @@ each_full_file(function, arg)
register struct file_entry *entry = &file_table[i];
register struct file_entry *subentry;
- if (entry->scrapped || entry->just_syms_flag)
+ if (entry->flags & (E_SCRAPPED | E_JUST_SYMS))
continue;
#ifdef SUN_COMPAT
if (entry->silly_archive) {
- if (!entry->is_dynamic)
+ if (!(entry->flags & E_DYNAMIC))
error("Silly");
- if (!entry->silly_archive->library_flag)
+ if (!(entry->silly_archive->flags & E_IS_LIBRARY))
error("Sillier");
subentry = entry->silly_archive->subfiles;
for (; subentry; subentry = subentry->chain) {
- if (subentry->scrapped)
+ if (subentry->flags & E_SCRAPPED)
continue;
(*function) (subentry, arg);
}
}
#endif
- if (entry->is_dynamic)
+ if (entry->flags & E_DYNAMIC)
continue;
- if (!entry->library_flag)
+ if (!(entry->flags & E_IS_LIBRARY))
(*function) (entry, arg);
subentry = entry->subfiles;
for (; subentry; subentry = subentry->chain) {
- if (subentry->scrapped)
+ if (subentry->flags & E_SCRAPPED)
continue;
(*function) (subentry, arg);
}
@@ -824,7 +925,7 @@ file_open (entry)
{
register int desc;
- if (entry->superfile && entry->superfile->library_flag)
+ if (entry->superfile && (entry->superfile->flags & E_IS_LIBRARY))
return file_open (entry->superfile);
if (entry == input_file)
@@ -832,7 +933,7 @@ file_open (entry)
if (input_file) file_close ();
- if (entry->search_dirs_flag) {
+ if (entry->flags & E_SEARCH_DIRS) {
desc = findlib(entry);
} else
desc = open (entry->filename, O_RDONLY, 0);
@@ -853,8 +954,8 @@ text_offset (entry)
{
return entry->starting_offset + N_TXTOFF (entry->header);
}
-
-/* Medium-level input routines for rel files. */
+
+/*---------------------------------------------------------------------------*/
/*
* Read a file's header into the proper place in the file_entry. DESC is the
@@ -865,8 +966,7 @@ read_header (desc, entry)
int desc;
register struct file_entry *entry;
{
- register int len;
- struct exec *loc = (struct exec *) &entry->header;
+ register int len, mid;
if (lseek (desc, entry->starting_offset, L_SET) !=
entry->starting_offset)
@@ -878,10 +978,13 @@ read_header (desc, entry)
md_swapin_exec_hdr(&entry->header);
- if (N_BADMAG (*loc))
+ if (N_BADMAG (entry->header))
fatal_with_file ("bad magic number in ", entry);
- entry->header_read_flag = 1;
+ if (N_BADMID(entry->header))
+ fatal_with_file ("non-native input file ", entry);
+
+ entry->flags |= E_HEADER_VALID;
}
/*
@@ -899,7 +1002,7 @@ read_entry_symbols (desc, entry)
struct nlist *np;
int i;
- if (!entry->header_read_flag)
+ if (!(entry->flags & E_HEADER_VALID))
read_header (desc, entry);
np = (struct nlist *) alloca (entry->header.a_syms);
@@ -921,11 +1024,9 @@ read_entry_symbols (desc, entry)
entry->symbols[i].nzlist.nz_size = 0;
entry->symbols[i].symbol = NULL;
entry->symbols[i].next = NULL;
+ entry->symbols[i].entry = entry;
entry->symbols[i].gotslot_offset = -1;
- entry->symbols[i].gotslot_claimed = 0;
- entry->symbols[i].write = 0;
- entry->symbols[i].is_L_symbol = 0;
- entry->symbols[i].rename = 0;
+ entry->symbols[i].flags = 0;
}
entry->strings_offset = N_STROFF(entry->header) +
@@ -949,7 +1050,7 @@ read_entry_strings (desc, entry)
{
int buffer;
- if (!entry->header_read_flag || !entry->strings_offset)
+ if (!(entry->flags & E_HEADER_VALID) || !entry->strings_offset)
fatal_with_file("internal error: cannot read string table for ",
entry);
@@ -963,14 +1064,6 @@ read_entry_strings (desc, entry)
return;
}
-/* DEAD - Read in all of the relocation information */
-
-void
-read_relocation ()
-{
- each_full_file (read_entry_relocation, 0);
-}
-
/* Read in the relocation sections of ENTRY if necessary */
void
@@ -1026,23 +1119,24 @@ read_entry_relocation (desc, entry)
}
}
-
-/* Read in the symbols of all input files. */
-
+/*---------------------------------------------------------------------------*/
-void
+/*
+ * Read in the symbols of all input files.
+ */
+static void
load_symbols ()
{
register int i;
- if (trace_files) fprintf (stderr, "Loading symbols:\n\n");
+ if (trace_files)
+ fprintf(stderr, "Loading symbols:\n\n");
- for (i = 0; i < number_of_files; i++) {
- register struct file_entry *entry = &file_table[i];
- read_file_symbols (entry);
- }
+ for (i = 0; i < number_of_files; i++)
+ read_file_symbols(&file_table[i]);
- if (trace_files) fprintf (stderr, "\n");
+ if (trace_files)
+ fprintf (stderr, "\n");
}
/*
@@ -1068,18 +1162,18 @@ read_file_symbols (entry)
md_swapin_exec_hdr(&hdr);
if (!N_BADMAG (hdr)) {
- if (N_IS_DYNAMIC(hdr)) {
+ if (N_IS_DYNAMIC(hdr) && !(entry->flags & E_JUST_SYMS)) {
if (relocatable_output) {
fatal_with_file(
"-r and shared objects currently not supported ",
entry);
return;
}
- entry->is_dynamic = 1;
+ entry->flags |= E_DYNAMIC;
if (entry->superfile || rrs_add_shobj(entry))
read_shared_object(desc, entry);
else
- entry->scrapped = 1;
+ entry->flags |= E_SCRAPPED;
} else {
read_entry_symbols (desc, entry);
entry->strings = (char *) alloca (entry->string_size);
@@ -1096,14 +1190,17 @@ read_file_symbols (entry)
strncmp (armag, ARMAG, SARMAG))
fatal_with_file(
"malformed input file (not rel or archive) ", entry);
- entry->library_flag = 1;
+ entry->flags |= E_IS_LIBRARY;
search_library (desc, entry);
}
file_close ();
}
-
-/* Enter the external symbol defs and refs of ENTRY in the hash table. */
+
+
+/*
+ * Enter the external symbol defs and refs of ENTRY in the hash table.
+ */
void
enter_file_symbols (entry)
@@ -1160,7 +1257,7 @@ enter_file_symbols (entry)
p->n_un.n_strx + entry->strings, entry);
} else if (p->n_un.n_strx &&
(p->n_un.n_strx + entry->strings)[0] == LPREFIX)
- lsp->is_L_symbol = 1;
+ lsp->flags |= LS_L_SYMBOL;
}
}
@@ -1190,9 +1287,9 @@ enter_global_ref (lsp, name, entry)
register struct nzlist *nzp = &lsp->nzlist;
register symbol *sp = getsym (name);
register int type = nzp->nz_type;
- int oldref = sp->referenced;
+ int oldref = (sp->flags & GS_REFERENCED);
int olddef = sp->defined;
- int com = sp->defined && sp->max_common_size;
+ int com = sp->defined && sp->common_size;
if (type == (N_INDR | N_EXT)) {
sp->alias = getsym(entry->strings + (lsp + 1)->nzlist.nz_strx);
@@ -1208,7 +1305,7 @@ enter_global_ref (lsp, name, entry)
}
}
- if (entry->is_dynamic) {
+ if (entry->flags & E_DYNAMIC) {
lsp->next = sp->sorefs;
sp->sorefs = lsp;
@@ -1223,11 +1320,17 @@ enter_global_ref (lsp, name, entry)
if (oldref)
undefined_global_sym_count--;
common_defined_global_count++;
- sp->max_common_size = nzp->nz_value;
+ sp->common_size = nzp->nz_value;
sp->defined = N_UNDF | N_EXT;
- } else if (com && sp->max_common_size < nzp->nz_value) {
- sp->max_common_size = nzp->nz_value;
+ } else if (com && sp->common_size < nzp->nz_value) {
+ sp->common_size = nzp->nz_value;
}
+ } else if (type != (N_UNDF | N_EXT) && !oldref) {
+ /*
+ * This is an ex common...
+ */
+ sp->common_size = 0;
+ sp->defined = 0;
}
/*
@@ -1244,10 +1347,10 @@ enter_global_ref (lsp, name, entry)
sp->refs = lsp;
lsp->symbol = sp;
- sp->referenced = 1;
+ sp->flags |= GS_REFERENCED;
if (sp == dynamic_symbol || sp == got_symbol) {
- if (type != (N_UNDF | N_EXT) && !entry->just_syms_flag)
+ if (type != (N_UNDF | N_EXT) && !(entry->flags & E_JUST_SYMS))
fatal("Linker reserved symbol %s defined as type %x ",
name, type);
return;
@@ -1281,33 +1384,38 @@ enter_global_ref (lsp, name, entry)
* First definition and it's common.
*/
common_defined_global_count++;
- sp->max_common_size = nzp->nz_value;
+ sp->common_size = nzp->nz_value;
} else if (com && type != (N_UNDF | N_EXT)) {
/*
* It used to be common and we're defining
* it as something else.
*/
common_defined_global_count--;
- sp->max_common_size = 0;
+ sp->common_size = 0;
} else if (com && type == (N_UNDF | N_EXT)
- && sp->max_common_size < nzp->nz_value)
+ && sp->common_size < nzp->nz_value)
/*
* It used to be common and this is a new common entry
* to which we need to pay attention.
*/
- sp->max_common_size = nzp->nz_value;
+ sp->common_size = nzp->nz_value;
if (SET_ELEMENT_P(type) && (!olddef || com))
set_vector_count++;
- } else if (!oldref)
+ } else if (!oldref && !com)
+ /*
+ * An unreferenced symbol can already be defined
+ * as common by shared objects.
+ */
undefined_global_sym_count++;
- if (sp == end_symbol && entry->just_syms_flag && !T_flag_specified)
+ if (sp == end_symbol && (entry->flags & E_JUST_SYMS) &&
+ !T_flag_specified)
text_start = nzp->nz_value;
- if (sp->trace) {
+ if (sp->flags & GS_TRACE) {
register char *reftype;
switch (type & N_TYPE) {
case N_UNDF:
@@ -1343,7 +1451,7 @@ enter_global_ref (lsp, name, entry)
}
/*
- * This return 0 if the given file entry's symbol table does *not* contain
+ * This returns 0 if the given file entry's symbol table does *not* contain
* the nlist point entry, and it returns the files entry pointer (cast to
* unsigned long) if it does.
*/
@@ -1391,7 +1499,6 @@ contains_symbol (entry, np)
*
*/
-
static void
digest_symbols ()
{
@@ -1419,6 +1526,8 @@ digest_symbols ()
each_full_file(consider_relocation, 0); /* Text */
each_full_file(consider_relocation, 1); /* Data */
+ each_file(consider_local_symbols, 0);
+
/*
* Compute total size of sections.
* RRS data is the first output data section, RRS text is the last
@@ -1437,7 +1546,7 @@ digest_symbols ()
* the padding in the text segment size.
*/
- if (magic == ZMAGIC || magic == QMAGIC || page_align_data) {
+ if (page_align_segments || page_align_data) {
int text_end = text_size + N_TXTOFF(outheader);
text_pad = PALIGN(text_end, page_size) - text_end;
text_size += text_pad;
@@ -1490,7 +1599,7 @@ printf("bssstart = %#x, bsssize = %#x\n",
if (specified_data_size && specified_data_size > data_size)
data_pad = specified_data_size - data_size;
- if (magic == ZMAGIC || magic == QMAGIC)
+ if (page_align_segments)
data_pad = PALIGN(data_pad + data_size, page_size) - data_size;
bss_size -= data_pad;
@@ -1506,10 +1615,10 @@ printf("bssstart = %#x, bsssize = %#x\n",
global_sym_count = defined_global_sym_count +
undefined_global_sym_count;
- if (dynamic_symbol->referenced)
+ if (dynamic_symbol->flags & GS_REFERENCED)
global_sym_count++;
- if (got_symbol->referenced)
+ if (got_symbol->flags & GS_REFERENCED)
global_sym_count++;
if (relocatable_output || building_shared_object)
@@ -1529,12 +1638,15 @@ debug symbols: %d, set_symbols %d\n",
#endif
}
+/*
+ * Determine the definition of each global symbol.
+ */
static void
digest_pass1()
{
/*
- * Now, for each symbol, verify that it is defined globally at most
+ * For each symbol, verify that it is defined globally at most
* once within relocatable files (except when building a shared lib).
* and set the `defined' field if there is a definition.
*
@@ -1546,7 +1658,7 @@ digest_pass1()
struct localsymbol *lsp;
int defs = 0;
- if (!sp->referenced) {
+ if (!(sp->flags & GS_REFERENCED)) {
#if 0
/* Check for undefined symbols in shared objects */
int type;
@@ -1580,7 +1692,7 @@ digest_pass1()
sp->value =
setv_fill_count++ * sizeof(long);
} else if ((sp->defined & N_TYPE) != N_SETV) {
- sp->multiply_defined = 1;
+ sp->mult_defs = 1;
multiple_def_count++;
}
/* Keep count and remember symbol */
@@ -1588,6 +1700,12 @@ digest_pass1()
set_vectors[setv_fill_count++] = (long)p;
if (building_shared_object) {
struct relocation_info reloc;
+
+ /*
+ * Make sure to relocate the contents
+ * of this set vector.
+ */
+ bzero(&reloc, sizeof(reloc));
RELOC_ADDRESS(&reloc) =
setv_fill_count * sizeof(long);
alloc_rrs_segment_reloc(NULL, &reloc);
@@ -1598,12 +1716,14 @@ digest_pass1()
&& (type & N_TYPE) != N_SIZE) {
/* non-common definition */
if (defs++ && sp->value != p->n_value
- && entry_symbol) {
- sp->multiply_defined = 1;
+ && entry_symbol/*XXX*/) {
+ sp->mult_defs = 1;
multiple_def_count++;
}
sp->def_nlist = p;
+ lsp->entry->flags |= E_SYMBOLS_USED;
sp->defined = type;
+ sp->aux = N_AUX(p);
}
}
@@ -1645,15 +1765,17 @@ digest_pass1()
&& (type & N_TYPE) != N_FN) {
/* non-common definition */
sp->def_nlist = p;
+ lsp->entry->flags |= E_SYMBOLS_USED;
sp->so_defined = type;
- if (sp->referenced)
+ sp->aux = N_AUX(p);
+ if (sp->flags & GS_REFERENCED)
undefined_global_sym_count--;
else
- sp->referenced = 1;
+ sp->flags |= GS_REFERENCED;
#ifdef DEBUG
printf("shr: %s gets defined to %x with value %x\n", sp->name, type, sp->value);
#endif
- if (sp->alias && !sp->alias->referenced) {
+ if (sp->alias && !(sp->alias->flags & GS_REFERENCED)) {
sp = sp->alias;
goto again;
}
@@ -1668,159 +1790,10 @@ doesn't match actual (%d)",
set_sect_size/sizeof(long), setv_fill_count);
}
-static void
-digest_pass2()
-{
- /*
- * Assign each symbol its final value.
- * If not -r'ing, allocate common symbols in the BSS section.
- */
-
- FOR_EACH_SYMBOL(i, sp) {
- int size;
- int align = sizeof(int);
-
- if (!sp->referenced)
- continue;
-
- if (sp->alias &&
- (relocatable_output || building_shared_object ||
- (sp->alias->defined && !sp->alias->so_defined)))
- /*
- * The alias points at a defined symbol, so it
- * must itself be counted as one too, in order to
- * compute the correct number of symbol table entries.
- */
- defined_global_sym_count++;
-
- if ((sp->defined & N_TYPE) == N_SETV) {
- /*
- * Set length word at front of vector and zero byte
- * at end. Reverse the vector itself to put it in
- * file order.
- */
- unsigned long i, tmp;
- unsigned long length_word_index =
- sp->value / sizeof(long);
-
- /* Relocate symbol value */
- sp->value += set_sect_start;
-
- set_vectors[length_word_index] = sp->setv_count;
-
- /*
- * Relocate vector to final address.
- */
- for (i = 0; i < sp->setv_count; i++) {
- struct nlist *p = (struct nlist *)
- set_vectors[1+i+length_word_index];
-
- set_vectors[1+i+length_word_index] = p->n_value;
- if (building_shared_object) {
- struct relocation_info reloc;
- RELOC_ADDRESS(&reloc) =
- (1 + i + length_word_index) *
- sizeof(long)
- + set_sect_start;
- RELOC_TYPE(&reloc) =
- (sp->defined & N_TYPE);
- claim_rrs_segment_reloc(NULL, &reloc);
- }
- }
-
- /*
- * Reverse the vector.
- */
- for (i = 1; i < (sp->setv_count - 1)/2 + 1; i++) {
-
- tmp = set_vectors[length_word_index + i];
- set_vectors[length_word_index + i] =
- set_vectors[length_word_index + sp->setv_count + 1 - i];
- set_vectors[length_word_index + sp->setv_count + 1 - i] = tmp;
- }
-
- /* Clear terminating entry */
- set_vectors[length_word_index + sp->setv_count + 1] = 0;
- continue;
- }
-
-
- if (sp->defined && sp->def_nlist &&
- ((sp->defined & ~N_EXT) != N_SETV))
- sp->value = sp->def_nlist->n_value;
-
- if (building_shared_object && !(link_mode & SYMBOLIC))
- /* No common allocation in shared objects */
- continue;
-
- if ((size = sp->max_common_size) != 0) {
- /*
- * It's a common.
- */
- if (sp->defined != (N_UNDF + N_EXT))
- fatal("%s: common isn't", sp->name);
-
- } else if ((size = sp->size) != 0 && sp->defined == N_SIZE) {
- /*
- * It's data from shared object with size info.
- */
- if (!sp->so_defined)
- fatal("%s: Bogus N_SIZE item", sp->name);
-
- } else
- /*
- * It's neither
- */
- continue;
-
-
- if (relocatable_output && !force_common_definition) {
- sp->defined = 0;
- undefined_global_sym_count++;
- defined_global_sym_count--;
- continue;
- }
-
- /*
- * Round up to nearest sizeof (int). I don't know whether
- * this is necessary or not (given that alignment is taken
- * care of later), but it's traditional, so I'll leave it in.
- * Note that if this size alignment is ever removed, ALIGN
- * above will have to be initialized to 1 instead of sizeof
- * (int).
- */
-
- size = PALIGN(size, sizeof(int));
-
- while (!(size & align))
- align <<= 1;
-
- align = align > MAX_ALIGNMENT ?
- MAX_ALIGNMENT : align;
-
- bss_size = PALIGN(bss_size + data_size + rrs_data_start, align)
- - (data_size + rrs_data_start);
-
- sp->value = rrs_data_start + data_size + bss_size;
- if (sp->defined == (N_UNDF | N_EXT))
- sp->defined = N_BSS | N_EXT;
- else {
- sp->so_defined = 0;
- defined_global_sym_count++;
- }
- bss_size += size;
- if (write_map)
- printf("Allocating %s %s: %x at %x\n",
- sp->defined==(N_BSS|N_EXT)?"common":"data",
- sp->name, size, sp->value);
-
- } END_EACH_SYMBOL;
-}
-
/*
- * Scan relocation info in ENTRY for contributions to the dynamic section of
- * the output file.
+ * Scan relocation info in ENTRY for contributions to the RRS section
+ * of the output file.
*/
static void
consider_relocation (entry, dataseg)
@@ -1848,7 +1821,7 @@ consider_relocation (entry, dataseg)
if (RELOC_BASEREL_P(reloc)) {
pic_code_seen = 1;
if (!RELOC_EXTERN_P(reloc))
- lsp->rename = 1;
+ lsp->flags |= LS_RENAME;
}
continue;
}
@@ -1939,39 +1912,20 @@ consider_relocation (entry, dataseg)
continue;
}
- /*
- * Only allocate an alias for function calls. Use
- * sp->size here as a heuristic to discriminate
- * between function definitions and data residing
- * in the text segment.
- * NOTE THAT THE COMPILER MUST NOT GENERATE ".size"
- * DIRECTIVES FOR FUNCTIONS.
- * In the future we might go for ".type" directives.
- */
- if (force_alias_definition && sp->size == 0 &&
- sp->so_defined == N_TEXT + N_EXT) {
+ if (force_alias_definition && sp->so_defined &&
+ sp->aux == AUX_FUNC) {
/* Call to shared library procedure */
alloc_rrs_jmpslot(entry, sp);
-#define EXPERIMENTAL
-#ifdef EXPERIMENTAL
- if (!RELOC_PCREL_P(reloc)) {
-#ifdef DEBUG
-printf("%s: FUNC flag set\n", sp->name);
-#endif
- sp->aux = RRS_FUNC;
- }
-#endif
- } else if (sp->size &&
- (sp->so_defined == N_DATA + N_EXT ||
- sp->so_defined == N_TEXT + N_EXT)) {
+ } else if (sp->size && sp->so_defined &&
+ sp->aux == AUX_OBJECT) {
/* Reference to shared library data */
alloc_rrs_cpy_reloc(entry, sp);
sp->defined = N_SIZE;
- } else if (!sp->defined && sp->max_common_size == 0)
+ } else if (!sp->defined && sp->common_size == 0)
alloc_rrs_reloc(entry, sp);
} else {
@@ -1988,6 +1942,76 @@ printf("%s: FUNC flag set\n", sp->name);
}
/*
+ * Determine the disposition of each local symbol.
+ */
+static void
+consider_local_symbols(entry)
+ register struct file_entry *entry;
+{
+ register struct localsymbol *lsp, *lspend;
+
+ if (entry->flags & E_DYNAMIC)
+ return;
+
+ lspend = entry->symbols + entry->nsymbols;
+
+ /*
+ * For each symbol determine whether it should go
+ * in the output symbol table.
+ */
+
+ for (lsp = entry->symbols; lsp < lspend; lsp++) {
+ register struct nlist *p = &lsp->nzlist.nlist;
+ register int type = p->n_type;
+
+ if (type == N_WARNING)
+ continue;
+
+ if (SET_ELEMENT_P (type)) {
+ /*
+ * This occurs even if global. These types of
+ * symbols are never written globally, though
+ * they are stored globally.
+ */
+ if (relocatable_output)
+ lsp->flags |= LS_WRITE;
+
+ } else if (!(type & (N_STAB | N_EXT))) {
+
+ /*
+ * Ordinary local symbol
+ */
+ if ((lsp->flags & LS_RENAME) || (
+ discard_locals != DISCARD_ALL &&
+ !(discard_locals == DISCARD_L &&
+ (lsp->flags & LS_L_SYMBOL))) ) {
+
+ lsp->flags |= LS_WRITE;
+ local_sym_count++;
+ }
+
+ } else if (!(type & N_EXT)) {
+
+ /*
+ * Debugger symbol
+ */
+ if (strip_symbols == STRIP_NONE) {
+ lsp->flags |= LS_WRITE;
+ debugger_sym_count++;
+ }
+ }
+ }
+
+ /*
+ * Count one for the local symbol that we generate,
+ * whose name is the file's name (usually) and whose address
+ * is the start of the file's text.
+ */
+ if (discard_locals != DISCARD_ALL)
+ local_sym_count++;
+}
+
+/*
* Accumulate the section sizes of input file ENTRY into the section sizes of
* the output file.
*/
@@ -1995,8 +2019,6 @@ static void
consider_file_section_lengths (entry)
register struct file_entry *entry;
{
- if (entry->just_syms_flag)
- return;
entry->text_start_address = text_size;
/* If there were any vectors, we need to chop them off */
@@ -2013,9 +2035,7 @@ consider_file_section_lengths (entry)
/*
* Determine where the sections of ENTRY go into the output file,
* whose total section sizes are already known.
- * Also relocate the addresses of the file's local and debugger symbols
- * and determine which of the local symbols will make it into the
- * output symbol table.
+ * Also relocate the addresses of the file's local and debugger symbols.
*/
static void
relocate_file_addresses (entry)
@@ -2072,57 +2092,165 @@ printf("%s: datastart: %#x, bss %#x\n", get_file_name(entry),
break;
}
- /*
- * See if this symbol should be in the output symbol table.
- */
+ }
- if (type == N_WARNING)
+}
+
+/*
+ * Assign a value to each global symbol.
+ */
+static void
+digest_pass2()
+{
+ FOR_EACH_SYMBOL(i, sp) {
+ int size;
+ int align = sizeof(int);
+
+ if (!(sp->flags & GS_REFERENCED))
continue;
- if (SET_ELEMENT_P (type)) {
+ if (sp->alias &&
+ (relocatable_output || building_shared_object ||
+ (sp->alias->defined && !sp->alias->so_defined)))
/*
- * This occurs even if global. These types of
- * symbols are never written globally, though
- * they are stored globally.
+ * The alias points at a defined symbol, so it
+ * must itself be counted as one too, in order to
+ * compute the correct number of symbol table entries.
*/
- lsp->write = relocatable_output;
+ defined_global_sym_count++;
- } else if (!(type & (N_STAB | N_EXT))) {
+ if ((sp->defined & N_TYPE) == N_SETV) {
+ /*
+ * Set length word at front of vector and zero byte
+ * at end. Reverse the vector itself to put it in
+ * file order.
+ */
+ unsigned long i, *p, *q;
+ unsigned long length_word_index =
+ sp->value / sizeof(long);
+
+ /* Relocate symbol value */
+ sp->value += set_sect_start;
+
+ set_vectors[length_word_index] = sp->setv_count;
/*
- * Ordinary local symbol
+ * Relocate vector to final address.
*/
- lsp->write = (lsp->rename || (
- discard_locals != DISCARD_ALL &&
- !(discard_locals == DISCARD_L &&
- lsp->is_L_symbol)));
- if (lsp->write)
- local_sym_count++;
+ for (i = 0; i < sp->setv_count; i++) {
+ struct nlist *p = (struct nlist *)
+ set_vectors[1+i+length_word_index];
- } else if (!(type & N_EXT)) {
+ set_vectors[1+i+length_word_index] = p->n_value;
+ if (building_shared_object) {
+ struct relocation_info reloc;
+
+ bzero(&reloc, sizeof(reloc));
+ RELOC_ADDRESS(&reloc) =
+ (1 + i + length_word_index) *
+ sizeof(long)
+ + set_sect_start;
+ RELOC_TYPE(&reloc) =
+ (p->n_type - (N_SETA - N_ABS)) & N_TYPE;
+ claim_rrs_segment_reloc(NULL, &reloc);
+ }
+ }
/*
- * Debugger symbol
+ * Reverse the vector.
*/
- lsp->write = (strip_symbols == STRIP_NONE);
- if (lsp->write)
- debugger_sym_count++;
+ p = &set_vectors[length_word_index + 1];
+ q = &set_vectors[length_word_index + sp->setv_count];
+ while (p < q) {
+ unsigned long tmp = *p;
+ *p++ = *q;
+ *q-- = tmp;
+ }
+ /* Clear terminating entry */
+ set_vectors[length_word_index + sp->setv_count + 1] = 0;
+ continue;
}
- }
- /*
- * Count one for the local symbol that we generate,
- * whose name is the file's name (usually) and whose address
- * is the start of the file's text.
- */
- if (discard_locals != DISCARD_ALL)
- local_sym_count++;
+ if (sp->defined && sp->def_nlist &&
+ ((sp->defined & ~N_EXT) != N_SETV))
+ sp->value = sp->def_nlist->n_value;
+
+ /*
+ * If not -r'ing, allocate common symbols in the BSS section.
+ */
+ if (building_shared_object && !(link_mode & SYMBOLIC))
+ /* No common allocation in shared objects */
+ continue;
+
+ if ((size = sp->common_size) != 0) {
+ /*
+ * It's a common.
+ */
+ if (sp->defined != (N_UNDF + N_EXT))
+ fatal("%s: common isn't", sp->name);
+
+ } else if ((size = sp->size) != 0 && sp->defined == N_SIZE) {
+ /*
+ * It's data from shared object with size info.
+ */
+ if (!sp->so_defined)
+ fatal("%s: Bogus N_SIZE item", sp->name);
+
+ } else
+ /*
+ * It's neither
+ */
+ continue;
+
+
+ if (relocatable_output && !force_common_definition) {
+ sp->defined = 0;
+ undefined_global_sym_count++;
+ defined_global_sym_count--;
+ continue;
+ }
+
+ /*
+ * Round up to nearest sizeof (int). I don't know whether
+ * this is necessary or not (given that alignment is taken
+ * care of later), but it's traditional, so I'll leave it in.
+ * Note that if this size alignment is ever removed, ALIGN
+ * above will have to be initialized to 1 instead of sizeof
+ * (int).
+ */
+
+ size = PALIGN(size, sizeof(int));
+
+ while (!(size & align))
+ align <<= 1;
+
+ align = align > MAX_ALIGNMENT ? MAX_ALIGNMENT : align;
+
+ bss_size = PALIGN(bss_size + data_size + rrs_data_start, align)
+ - (data_size + rrs_data_start);
+
+ sp->value = rrs_data_start + data_size + bss_size;
+ if (sp->defined == (N_UNDF | N_EXT))
+ sp->defined = N_BSS | N_EXT;
+ else {
+ sp->so_defined = 0;
+ defined_global_sym_count++;
+ }
+ bss_size += size;
+ if (write_map)
+ printf("Allocating %s %s: %x at %x\n",
+ sp->defined==(N_BSS|N_EXT)?"common":"data",
+ sp->name, size, sp->value);
+
+ } END_EACH_SYMBOL;
}
-
-/* Write the output file */
+
+/* -------------------------------------------------------------------*/
+
+/* Write the output file */
void
write_output ()
{
@@ -2138,6 +2266,8 @@ write_output ()
if (outdesc < 0)
perror_name (output_filename);
+ fatal_cleanup_hook = myfatal;
+
if (fstat (outdesc, &statbuf) < 0)
perror_name (output_filename);
@@ -2176,6 +2306,9 @@ write_header ()
{
int flags = (rrs_section_type == RRS_FULL) ? EX_DYNAMIC : 0;
+ if (oldmagic && (flags & EX_DYNAMIC))
+ error("Cannot set flag in old magic headers\n");
+
N_SET_FLAG (outheader, flags);
outheader.a_text = text_size;
@@ -2339,7 +2472,7 @@ copy_data (entry)
mywrite (bytes, 1, entry->header.a_data, outdesc);
}
-
+
/*
* Relocate ENTRY's text or data section contents. DATA is the address of the
* contents, in core. DATA_SIZE is the length of the contents. PC_RELOCATION
@@ -2347,6 +2480,10 @@ copy_data (entry)
* and its address in the input file. RELOC is the address of the
* relocation info, in core. NRELOC says how many there are.
*/
+
+/* HACK: md.c may need access to this */
+int pc_relocation;
+
void
perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
char *data;
@@ -2356,12 +2493,13 @@ perform_relocation(data, data_size, reloc, nreloc, entry, dataseg)
struct file_entry *entry;
int dataseg;
{
- register struct relocation_info *r = reloc;
- struct relocation_info *end = reloc + nreloc;
- text_relocation = entry->text_start_address;
- data_relocation = entry->data_start_address - entry->header.a_text;
- bss_relocation = entry->bss_start_address -
+ register struct relocation_info *r = reloc;
+ struct relocation_info *end = reloc + nreloc;
+
+ int text_relocation = entry->text_start_address;
+ int data_relocation = entry->data_start_address - entry->header.a_text;
+ int bss_relocation = entry->bss_start_address -
entry->header.a_text - entry->header.a_data;
pc_relocation = dataseg?
entry->data_start_address - entry->header.a_text:
@@ -2616,10 +2754,10 @@ write_rel ()
/* BLECH - Assign number 0 to __DYNAMIC (!! Sun compatibility) */
- if (dynamic_symbol->referenced)
+ if (dynamic_symbol->flags & GS_REFERENCED)
dynamic_symbol->symbolnum = count++;
FOR_EACH_SYMBOL(i, sp) {
- if (sp != dynamic_symbol && sp->referenced) {
+ if (sp != dynamic_symbol && (sp->flags & GS_REFERENCED)) {
sp->symbolnum = count++;
if (sp->size)
count++;
@@ -2664,7 +2802,7 @@ assign_symbolnums(entry, countp)
n++;
for (lsp = entry->symbols; lsp < lspend; lsp++) {
- if (lsp->write)
+ if (lsp->flags & LS_WRITE)
lsp->symbolnum = n++;
}
*countp = n;
@@ -2729,10 +2867,11 @@ coptxtrel(entry)
* If we aren't going to be adding in the
* value in memory on the next pass of the
* loader, then we need to add it in from the
- * relocation entry. Otherwise the work we
+ * relocation entry, unless the symbol remains
+ * external in our output. Otherwise the work we
* did in this pass is lost.
*/
- if (!RELOC_MEMORY_ADD_P(r))
+ if (!RELOC_MEMORY_ADD_P(r) && !RELOC_EXTERN_P(r))
RELOC_ADD_EXTRA(r) += sp->value;
#endif
} else
@@ -2794,7 +2933,7 @@ copdatrel(entry)
symtype = sp->defined & N_TYPE;
- if (!pic_code_seen && (force_common_definition ||
+ if (!pic_code_seen && ( symtype == N_BSS ||
symtype == N_DATA ||
symtype == N_TEXT ||
symtype == N_ABS)) {
@@ -2939,7 +3078,7 @@ write_syms()
* If defined (ie. not relocatable_output), make it look
* like an internal symbol.
*/
- if (dynamic_symbol->referenced) {
+ if (dynamic_symbol->flags & GS_REFERENCED) {
nl.n_other = 0;
nl.n_desc = 0;
nl.n_type = dynamic_symbol->defined;
@@ -2961,7 +3100,7 @@ write_syms()
/* Already dealt with above */
continue;
- if (!sp->referenced)
+ if (!(sp->flags & GS_REFERENCED))
/* Came from shared object but was not used */
continue;
@@ -3009,6 +3148,7 @@ write_syms()
*/
nl.n_type = sp->alias->defined;
nl.n_value = sp->alias->value;
+ nl.n_other = N_OTHER(0, sp->alias->aux);
} else {
if (sp->defined == N_SIZE)
nl.n_type = N_DATA | N_EXT;
@@ -3019,9 +3159,10 @@ write_syms()
fatal("%s: N_INDR has value %#x",
sp->name, sp->value);
nl.n_value = sp->value;
+ nl.n_other = N_OTHER(0, sp->aux);
}
- } else if (sp->max_common_size) {
+ } else if (sp->common_size) {
/*
* defined as common but not allocated,
* happens only with -r and not -d, write out
@@ -3032,7 +3173,7 @@ write_syms()
* undefined in digest_symbols.
*/
nl.n_type = N_UNDF | N_EXT;
- nl.n_value = sp->max_common_size;
+ nl.n_value = sp->common_size;
} else if (!sp->defined) {
/* undefined -- legit only if -r */
nl.n_type = N_UNDF | N_EXT;
@@ -3053,6 +3194,9 @@ write_syms()
*bufp++ = nl;
syms_written++;
+ /*
+ * Write second symbol of an alias pair.
+ */
if (nl.n_type == N_INDR + N_EXT) {
if (sp->alias == NULL)
fatal("internal error: alias in hyperspace");
@@ -3066,6 +3210,9 @@ write_syms()
syms_written++;
}
+ /*
+ * Write N_SIZE symbol for a symbol with a known size.
+ */
if (relocatable_output && sp->size) {
nl.n_type = N_SIZE + N_EXT;
nl.n_un.n_strx = assign_string_table_index(sp->name);
@@ -3144,7 +3291,7 @@ write_file_syms(entry, syms_written_addr)
register struct nlist *bufp = buf;
- if (entry->is_dynamic)
+ if (entry->flags & E_DYNAMIC)
return;
/*
@@ -3168,9 +3315,6 @@ write_file_syms(entry, syms_written_addr)
nl.n_other = 0;
*bufp++ = nl;
(*syms_written_addr)++;
-#if 0
- entry->local_syms_offset = *syms_written_addr * sizeof(struct nlist);
-#endif
}
/* Read the file's string table. */
@@ -3185,12 +3329,12 @@ write_file_syms(entry, syms_written_addr)
register int write = 0;
char *name;
- if (! lsp->write)
+ if (!(lsp->flags & LS_WRITE))
continue;
if (p->n_un.n_strx == 0)
name = NULL;
- else if (lsp->rename == 0)
+ else if (!(lsp->flags & LS_RENAME))
name = p->n_un.n_strx + entry->strings;
else {
char *cp = p->n_un.n_strx + entry->strings;
@@ -3229,3 +3373,50 @@ write_file_syms(entry, syms_written_addr)
write_string_table();
entry->strings = 0; /* Since it will disappear anyway. */
}
+
+/*
+ * Output COUNT*ELTSIZE bytes of data at BUF to the descriptor DESC.
+ */
+void
+mywrite (buf, count, eltsize, desc)
+ void *buf;
+ int count;
+ int eltsize;
+ int desc;
+{
+ register int val;
+ register int bytes = count * eltsize;
+
+ while (bytes > 0) {
+ val = write (desc, buf, bytes);
+ if (val <= 0)
+ perror(output_filename);
+ buf += val;
+ bytes -= val;
+ }
+}
+
+static void
+myfatal()
+{
+ if (outdesc > 0)
+ unlink(output_filename);
+}
+
+/*
+ * Output PADDING zero-bytes to descriptor OUTDESC.
+ * PADDING may be negative; in that case, do nothing.
+ */
+void
+padfile (padding, outdesc)
+ int padding;
+ int outdesc;
+{
+ register char *buf;
+ if (padding <= 0)
+ return;
+
+ buf = (char *) alloca (padding);
+ bzero (buf, padding);
+ mywrite (buf, padding, 1, outdesc);
+}
diff --git a/gnu/usr.bin/ld/ld.h b/gnu/usr.bin/ld/ld.h
index 1cee37a..a43eac8 100644
--- a/gnu/usr.bin/ld/ld.h
+++ b/gnu/usr.bin/ld/ld.h
@@ -1,4 +1,6 @@
-/* $Id: ld.h,v 1.8 1993/12/11 11:58:26 jkh Exp $ */
+/*
+ * $Id: ld.h,v 1.8 1994/01/28 20:56:24 pk Exp $
+ */
/*-
* This code is derived from software copyrighted by the Free Software
* Foundation.
@@ -29,6 +31,10 @@
#define alloca __builtin_alloca
#endif
+#ifdef __FreeBSD__
+#define FreeBSD
+#endif
+
#include "md.h"
#include "link.h"
@@ -41,23 +47,21 @@
/* Align to machine dependent boundary */
#define MALIGN(x) PALIGN(x,MAX_ALIGNMENT)
-/* Size of a page; obtained from the operating system. */
-
-int page_size;
-
/* Name this program was invoked by. */
+char *progname;
-char *progname;
-
/* System dependencies */
/* Define this to specify the default executable format. */
#ifndef DEFAULT_MAGIC
+#ifdef FreeBSD
#define DEFAULT_MAGIC QMAGIC
+extern int netzmagic;
+#else
+#define DEFAULT_MAGIC ZMAGIC
+#endif
#endif
-
-extern netzmagic;
/*
@@ -181,7 +185,7 @@ extern netzmagic;
#ifndef DATA_START
#define DATA_START(x) N_DATADDR(x)
#endif
-
+
/* If a this type of symbol is encountered, its name is a warning
message to print each time the symbol referenced by the next symbol
table entry is referenced.
@@ -330,6 +334,22 @@ extern netzmagic;
#endif /* not __GNU_STAB__ */
+
+typedef struct localsymbol {
+ struct nzlist nzlist; /* n[z]list from file */
+ struct glosym *symbol; /* Corresponding global symbol,
+ if any */
+ struct localsymbol *next; /* List of definitions */
+ struct file_entry *entry; /* Backpointer to file */
+ long gotslot_offset; /* Position in GOT, if any */
+ int symbolnum; /* Position in output nlist */
+ int flags;
+#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 */
+} localsymbol_t;
+
/* Symbol table */
/*
@@ -340,225 +360,102 @@ extern netzmagic;
*/
typedef struct glosym {
- /* Pointer to next symbol in this symbol's hash bucket. */
- struct glosym *link;
- /* Name of this symbol. */
- char *name;
- /* Value of this symbol as a global symbol. */
- long value;
- /*
- * Chain of external 'nlist's in files for this symbol, both defs and
- * refs.
- */
- struct localsymbol *refs;
- /*
- * Any warning message that might be associated with this symbol from
- * an N_WARNING symbol encountered.
- */
- char *warning;
- /*
- * Nonzero means definitions of this symbol as common have been seen,
- * and the value here is the largest size specified by any of them.
- */
- int max_common_size;
- /*
- * For relocatable_output, records the index of this global sym in
- * the symbol table to be written, with the first global sym given
- * index 0.
- */
- int symbolnum;
- /*
- * For dynamically linked output, records the index in the RRS
- * symbol table.
- */
- int rrs_symbolnum;
- /*
- * Nonzero means a definition of this global symbol is known to
- * exist. Library members should not be loaded on its account.
- */
- char defined;
- /*
- * Nonzero means a reference to this global symbol has been seen in a
- * file that is surely being loaded. A value higher than 1 is the
- * n_type code for the symbol's definition.
- */
- char referenced;
- /*
- * A count of the number of undefined references printed for a
- * specific symbol. If a symbol is unresolved at the end of
- * digest_symbols (and the loading run is supposed to produce
- * relocatable output) do_file_warnings keeps track of how many
- * unresolved reference error messages have been printed for each
- * symbol here. When the number hits MAX_UREFS_PRINTED, messages
- * stop.
- */
- unsigned char undef_refs;
- /*
- * 1 means that this symbol has multiple definitions. 2 means that
- * it has multiple definitions, and some of them are set elements,
- * one of which has been printed out already.
- */
- unsigned char multiply_defined;
- /* Nonzero means print a message at all refs or defs of this symbol */
- char trace;
-
- /*
- * For symbols of type N_INDR, this points at the real symbol.
- */
- struct glosym *alias;
-
- /*
- * Count number of elements in set vector if symbol is of type N_SETV
- */
- int setv_count;
-
- /* Dynamic lib support */
-
- /*
- * Nonzero means a definition of this global symbol has been found
- * in a shared object. These symbols do not go into the symbol
- * section of the resulting a.out file. They *do* go into the
- * dynamic link information segment.
- */
- char so_defined;
-
- /* Size of symbol as determined by N_SIZE symbols in object files */
- int size;
-
- /* Auxialiary info to put in the `nz_other' field of the
- * RRS symbol table. Used by the run-time linker to resolve
- * references to function addresses from within shared objects.
- */
- int aux;
-#define RRS_FUNC 2
-
- /*
- * Chain of external 'nlist's in shared objects for this symbol, both
- * defs and refs.
- */
- struct localsymbol *sorefs;
+ struct glosym *link; /* Next symbol hash bucket. */
+ char *name; /* Name of this symbol. */
+ long value; /* Value of this symbol */
+ localsymbol_t *refs; /* Chain of local symbols from object
+ files pertaining to this global
+ symbol */
+ localsymbol_t *sorefs;/* Same for local symbols from shared
+ object files. */
+
+ char *warning; /* message, from N_WARNING nlists */
+ int common_size; /* Common size */
+ int symbolnum; /* Symbol index in output symbol table */
+ int rrs_symbolnum; /* Symbol index in RRS symbol table */
+
+ struct nlist *def_nlist; /* The local symbol that gave this
+ global symbol its definition */
+
+ char defined; /* Definition of this symbol */
+ char so_defined; /* Definition of this symbol in a shared
+ object. These go into the RRS symbol table */
+ u_char undef_refs; /* Count of number of "undefined"
+ messages printed for this symbol */
+ u_char mult_defs; /* Same for "multiply defined" symbols */
+ struct glosym *alias; /* For symbols of type N_INDR, this
+ points at the real symbol. */
+ int setv_count; /* Number of elements in N_SETV symbols */
+ int size; /* Size of this symbol (either from N_SIZE
+ symbols or a from shared object's RRS */
+ int aux; /* Auxiliary type information conveyed in
+ the `n_other' field of nlists */
/* The offset into one of the RRS tables, -1 if not used */
- long jmpslot_offset;
- char jmpslot_claimed;
+ long jmpslot_offset;
+ long gotslot_offset;
- long gotslot_offset;
- char gotslot_claimed;
+ long flags;
- char cpyreloc_reserved;
- char cpyreloc_claimed;
+#define GS_DEFINED 1 /* Symbol has definition (notyetused)*/
+#define GS_REFERENCED 2 /* 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_CPYRELOCRESERVED 0x20 /* entries in GOT and PLT tables */
+#define GS_CPYRELOCCLAIMED 0x40 /* */
- /* The local symbol that gave this global symbol its definition */
- struct nlist *def_nlist;
} symbol;
/* Number of buckets in symbol hash table */
-#define TABSIZE 1009
+#define SYMTABSIZE 1009
-/* The symbol hash table: a vector of TABSIZE pointers to struct glosym. */
-symbol *symtab[TABSIZE];
+/* The symbol hash table: a vector of SYMTABSIZE pointers to struct glosym. */
+extern symbol *symtab[];
#define FOR_EACH_SYMBOL(i,sp) { \
int i; \
- for (i = 0; i < TABSIZE; i++) { \
+ for (i = 0; i < SYMTABSIZE; i++) { \
register symbol *sp; \
for (sp = symtab[i]; sp; sp = sp->link)
#define END_EACH_SYMBOL }}
-/* Number of symbols in symbol hash table. */
-int num_hash_tab_syms;
-
-/* Count number of nlist entries for global symbols */
-int global_sym_count;
-
-/* Count number of N_SIZE nlist entries for output (relocatable_output only) */
-int size_sym_count;
-
-/* Count the number of nlist entries that are for local symbols.
- This count and the three following counts
- are incremented as as symbols are entered in the symbol table. */
-int local_sym_count;
-
-/* Count number of nlist entries that are for local symbols
- whose names don't start with L. */
-int non_L_local_sym_count;
-
-/* Count the number of nlist entries for debugger info. */
-int debugger_sym_count;
-
-/* Count the number of global symbols referenced and not defined. */
-int undefined_global_sym_count;
-
-/* Count the number of symbols referenced from shared objects and not defined */
-int undefined_shobj_sym_count;
-
-/* Count the number of global symbols multiply defined. */
-int multiple_def_count;
-
-/* Count the number of defined global symbols.
- Each symbol is counted only once
- regardless of how many different nlist entries refer to it,
- since the output file will need only one nlist entry for it.
- This count is computed by `digest_symbols';
- it is undefined while symbols are being loaded. */
-int defined_global_sym_count;
-
-/* Count the number of symbols defined through common declarations.
- This count is kept in symdef_library, linear_library, and
- enter_global_ref. It is incremented when the defined flag is set
- in a symbol because of a common definition, and decremented when
- the symbol is defined "for real" (ie. by something besides a common
- definition). */
-int common_defined_global_count;
-
-/* Count the number of linker defined symbols.
- XXX - Currently, only __DYNAMIC and _G_O_T_ go here if required,
- perhaps _etext, _edata and _end should go here too */
-int special_sym_count;
-
-/* Count number of aliased symbols */
-int global_alias_count;
-
-/* Count number of set element type symbols and the number of separate
- vectors which these symbols will fit into */
-int set_symbol_count;
-int set_vector_count;
-
-/* Define a linked list of strings which define symbols which should
- be treated as set elements even though they aren't. Any symbol
- with a prefix matching one of these should be treated as a set
- element.
-
- This is to make up for deficiencies in many assemblers which aren't
- willing to pass any stabs through to the loader which they don't
- understand. */
-struct string_list_element {
- char *str;
- struct string_list_element *next;
-};
+/* # of global symbols referenced and not defined. */
+extern int undefined_global_sym_count;
-struct string_list_element *set_element_prefixes;
+/* # of undefined symbols referenced by shared objects */
+extern int undefined_shobj_sym_count;
-/* Count the number of warning symbols encountered. */
-int warning_count;
+/* # of multiply defined symbols. */
+extern int multiple_def_count;
-/* 1 => write load map. */
-int write_map;
+/* # of common symbols. */
+extern int common_defined_global_count;
-/* 1 => write relocation into output file so can re-input it later. */
-int relocatable_output;
+/* # of warning symbols encountered. */
+extern int warning_count;
-/* Nonzero means ptr to symbol entry for symbol to use as start addr.
- -e sets this. */
-symbol *entry_symbol;
+/*
+ * Define a linked list of strings which define symbols which should be
+ * treated as set elements even though they aren't. Any symbol with a prefix
+ * matching one of these should be treated as a set element.
+ *
+ * This is to make up for deficiencies in many assemblers which aren't willing
+ * to pass any stabs through to the loader which they don't understand.
+ */
+struct string_list_element {
+ char *str;
+ struct string_list_element *next;
+};
-symbol *edata_symbol; /* the symbol _edata */
-symbol *etext_symbol; /* the symbol _etext */
-symbol *end_symbol; /* the symbol _end */
-symbol *got_symbol; /* the symbol __GLOBAL_OFFSET_TABLE_ */
-symbol *dynamic_symbol; /* the symbol __DYNAMIC */
+extern symbol *entry_symbol; /* the entry symbol, if any */
+extern symbol *edata_symbol; /* the symbol _edata */
+extern symbol *etext_symbol; /* the symbol _etext */
+extern symbol *end_symbol; /* the symbol _end */
+extern symbol *got_symbol; /* the symbol __GLOBAL_OFFSET_TABLE_ */
+extern symbol *dynamic_symbol; /* the symbol __DYNAMIC */
-
/*
* Each input file, and each library member ("subfile") being loaded, has a
* `file_entry' structure for it.
@@ -573,160 +470,82 @@ symbol *dynamic_symbol; /* the symbol __DYNAMIC */
*/
struct file_entry {
- /* Name of this file. */
- char *filename;
-
+ char *filename; /* Name of this file. */
/*
* Name to use for the symbol giving address of text start Usually
* the same as filename, but for a file spec'd with -l this is the -l
* switch itself rather than the filename.
*/
- char *local_sym_name;
-
- /* Describe the layout of the contents of the file */
-
- /* The file's a.out header. */
- struct exec header;
-#if 0
- /* Offset in file of GDB symbol segment, or 0 if there is none. */
- int symseg_offset;
-#endif
-
- /* Describe data from the file loaded into core */
-
+ char *local_sym_name;
+ struct exec header; /* The file's a.out header. */
+ localsymbol_t *symbols; /* Symbol table of the file. */
+ int nsymbols; /* Number of symbols in above array. */
+ int string_size; /* Size in bytes of string table. */
+ char *strings; /* Pointer to the string table when
+ in core, NULL otherwise */
+ int strings_offset; /* Offset of string table,
+ (normally N_STROFF() + 4) */
/*
- * Symbol table of the file.
- * We need access to the global symbol early, ie. before
- * symbols are asssigned there final values. gotslot_offset is
- * here because GOT entries may be generated for local symbols.
+ * Next two used only if `relocatable_output' or if needed for
+ * output of undefined reference line numbers.
*/
- struct localsymbol {
- struct nzlist nzlist;
- struct glosym *symbol;
- struct localsymbol *next;
- long gotslot_offset;
- char gotslot_claimed;
- char write;
- char is_L_symbol;
- char rename;
- int symbolnum;
- } *symbols;
-
- /* Number of symbols in above array. */
- int nsymbols;
-
- /* Size in bytes of string table. */
- int string_size;
+ struct relocation_info *textrel; /* Text relocations */
+ int ntextrel; /* # of text relocations */
+ struct relocation_info *datarel; /* Data relocations */
+ int ndatarel; /* # of data relocations */
/*
- * Pointer to the string table. The string table is not kept in core
- * all the time, but when it is in core, its address is here.
+ * Relation of this file's segments to the output file.
*/
- char *strings;
-
- /* Offset of string table (normally N_STROFF() + 4) */
- int strings_offset;
-
- /* Next two used only if `relocatable_output' or if needed for */
- /* output of undefined reference line numbers. */
-
- /* Text reloc info saved by `write_text' for `coptxtrel'. */
- struct relocation_info *textrel;
- int ntextrel;
-
- /* Data reloc info saved by `write_data' for `copdatrel'. */
- struct relocation_info *datarel;
- int ndatarel;
-
- /* Relation of this file's segments to the output file */
-
- /* Start of this file's text seg in the output file core image. */
- int text_start_address;
-
- /* Start of this file's data seg in the output file core image. */
- int data_start_address;
-
- /* Start of this file's bss seg in the output file core image. */
- int bss_start_address;
-#if 0
- /*
- * Offset in bytes in the output file symbol table of the first local
- * symbol for this file. Set by `write_file_symbols'.
- */
- int local_syms_offset;
-#endif
-
- /* For library members only */
-
- /* For a library, points to chain of entries for the library members. */
- struct file_entry *subfiles;
-
- /*
- * For a library member, offset of the member within the archive.
- * Zero for files that are not library members.
- */
- int starting_offset;
-
- /* Size of contents of this file, if library member. */
- int total_size;
-
- /* For library member, points to the library's own entry. */
- struct file_entry *superfile;
-
- /* For library member, points to next entry for next member. */
- struct file_entry *chain;
-
+ int text_start_address; /* Start of this file's text segment
+ in the output file core image. */
+ int data_start_address; /* Start of this file's data segment
+ in the output file core image. */
+ int bss_start_address; /* Start of this file's bss segment
+ in the output file core image. */
+ struct file_entry *subfiles; /* For a library, points to chain of
+ entries for the library members. */
+ struct file_entry *superfile; /* For library member, points to the
+ library's own entry. */
+ struct file_entry *chain; /* For library member, points to next
+ entry for next member. */
+ int starting_offset; /* For a library member, offset of the
+ member within the archive. Zero for
+ files that are not library members.*/
+ int total_size; /* Size of contents of this file,
+ if library member. */
#ifdef SUN_COMPAT
- /* For shared libraries which have a .sa companion */
- struct file_entry *silly_archive;
+ struct file_entry *silly_archive;/* For shared libraries which have
+ a .sa companion */
#endif
-
- /* 1 if file is a library. */
- char library_flag;
-
- /* 1 if file's header has been read into this structure. */
- char header_read_flag;
-
- /* 1 means search a set of directories for this file. */
- char search_dirs_flag;
-
- /*
- * 1 means this is base file of incremental load. Do not load this
- * file's text or data. Also default text_start to after this file's
- * bss.
- */
- char just_syms_flag;
-
- /* 1 means search for dynamic libraries (dependent on -B switch) */
- char search_dynamic_flag;
-
- /* version numbers of selected shared library */
- int lib_major, lib_minor;
-
- /* This entry is a shared object */
- char is_dynamic;
-
- /* 1 if this entry is not a major player anymore */
- char scrapped;
+ int lib_major, lib_minor; /* Version numbers of a shared object */
+
+ int flags;
+#define E_IS_LIBRARY 1 /* File is a an archive */
+#define E_HEADER_VALID 2 /* File's header has been read */
+#define E_SEARCH_DIRS 4 /* Search directories for file */
+#define E_SEARCH_DYNAMIC 8 /* Search for shared libs allowed */
+#define E_JUST_SYMS 0x10 /* File is used for incremental load */
+#define E_DYNAMIC 0x20 /* File is a shared object */
+#define E_SCRAPPED 0x40 /* Ignore this file */
+#define E_SYMBOLS_USED 0x80 /* Symbols from this entry were used */
};
-typedef struct localsymbol localsymbol_t;
+/*
+ * Section start addresses.
+ */
+extern int text_size; /* total size of text. */
+extern int text_start; /* start of text */
+extern int text_pad; /* clear space between text and data */
+extern int data_size; /* total size of data. */
+extern int data_start; /* start of data */
+extern int data_pad; /* part of bss segment within data */
-/* Vector of entries for input files specified by arguments.
- These are all the input files except for members of specified libraries. */
-struct file_entry *file_table;
+extern int bss_size; /* total size of bss. */
+extern int bss_start; /* start of bss */
-/* Length of that vector. */
-int number_of_files;
-
-/* Current link mode */
-#define DYNAMIC 1 /* Consider shared libraries */
-#define SYMBOLIC 2 /* Force symbolic resolution */
-#define FORCEARCHIVE 4 /* Force inclusion of all members
- of archives */
-#define SHAREABLE 8 /* Build a shared object */
-#define SILLYARCHIVE 16 /* Process .sa companions, if any */
-int link_mode;
+extern int text_reloc_size; /* total size of text relocation. */
+extern int data_reloc_size; /* total size of data relocation. */
/*
* Runtime Relocation Section (RRS).
@@ -735,115 +554,57 @@ int link_mode;
* static linking), or can just exist of GOT and PLT entries (in case of
* statically linked PIC code).
*/
-
-int rrs_section_type;
+extern int rrs_section_type; /* What's in the RRS section */
#define RRS_NONE 0
#define RRS_PARTIAL 1
#define RRS_FULL 2
-
-int rrs_text_size;
-int rrs_data_size;
-int rrs_text_start;
-int rrs_data_start;
+extern int rrs_text_size; /* Size of RRS text additions */
+extern int rrs_text_start; /* Location of above */
+extern int rrs_data_size; /* Size of RRS data additions */
+extern int rrs_data_start; /* Location of above */
/* Version number to put in __DYNAMIC (set by -V) */
-int soversion;
-
-/* When loading the text and data, we can avoid doing a close
- and another open between members of the same library.
-
- These two variables remember the file that is currently open.
- Both are zero if no file is open.
-
- See `each_file' and `file_close'. */
-
-struct file_entry *input_file;
-int input_desc;
-
-/* The name of the file to write; "a.out" by default. */
-
-char *output_filename;
-
-/* Descriptor for writing that file with `mywrite'. */
-
-int outdesc;
-
-/* Header for that file (filled in by `write_header'). */
-
-struct exec outheader;
-
-/* The following are computed by `digest_symbols'. */
-
-int text_size; /* total size of text of all input files. */
-int data_size; /* total size of data of all input files. */
-int bss_size; /* total size of bss of all input files. */
-int text_reloc_size; /* total size of text relocation of all input files. */
-int data_reloc_size; /* total size of data relocation of all input files. */
-
-/* Relocation offsets set by perform_relocation(). Defined globaly here
- because some of the RRS routines need access to them */
-int text_relocation;
-int data_relocation;
-int bss_relocation;
-int pc_relocation;
-
-/* Specifications of start and length of the area reserved at the end
- of the data segment for the set vectors. Computed in 'digest_symbols' */
-int set_sect_start;
-int set_sect_size;
-
-/* Amount of cleared space to leave between the text and data segments. */
-int text_pad;
-
-/* Amount of bss segment to include as part of the data segment. */
-int data_pad;
+extern int soversion;
+#ifndef DEFAULT_SOVERSION
+#define DEFAULT_SOVERSION LD_VERSION_BSD
+#endif
+extern int pc_relocation; /* Current PC reloc value */
-/* Record most of the command options. */
+extern int number_of_shobjs; /* # of shared objects linked in */
-/* Address we assume the text section will be loaded at.
- We relocate symbols and text and data for this, but we do not
- write any padding in the output file for it. */
-int text_start;
+/* Current link mode */
+extern int link_mode;
+#define DYNAMIC 1 /* Consider shared libraries */
+#define SYMBOLIC 2 /* Force symbolic resolution */
+#define FORCEARCHIVE 4 /* Force inclusion of all members
+ of archives */
+#define SHAREABLE 8 /* Build a shared object */
+#define SILLYARCHIVE 16 /* Process .sa companions, if any */
-/* Offset of default entry-pc within the text section. */
-int entry_offset;
+extern int outdesc; /* Output file descriptor. */
+extern struct exec outheader; /* Output file header. */
+extern int magic; /* Output file magic. */
+extern int oldmagic;
+extern int relocatable_output;
-/* Address we decide the data section will be loaded at. */
-int data_start;
-int bss_start;
+/* Size of a page. */
+extern int page_size;
-/* Keep a list of any symbols referenced from the command line (so
- that error messages for these guys can be generated). This list is
- zero terminated. */
-struct glosym **cmdline_references;
-int cl_refs_allocated;
+extern char **search_dirs; /* Directories to search for libraries. */
+extern int n_search_dirs; /* Length of above. */
-/*
- * Actual vector of directories to search; this contains those specified with
- * -L plus the standard ones.
- */
-char **search_dirs;
+extern int write_map; /* write a load map (`-M') */
-/* Length of the vector `search_dirs'. */
-int n_search_dirs;
+extern void (*fatal_cleanup_hook)__P((void));
-void load_symbols __P((void));
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));
-void write_data __P((void));
-void write_rel __P((void));
-void write_syms __P((void));
-void write_symsegs __P((void));
-void mywrite ();
+void mywrite __P((void *, int, int, int));
/* In warnings.c: */
void perror_name __P((char *));
@@ -917,10 +678,10 @@ void swap_longs __P((long *, int));
void swap_symbols __P((struct nlist *, int));
void swap_zsymbols __P((struct nzlist *, int));
void swap_ranlib_hdr __P((struct ranlib *, int));
-void swap_link_dynamic __P((struct link_dynamic *));
-void swap_link_dynamic_2 __P((struct link_dynamic_2 *));
-void swap_ld_debug __P((struct ld_debug *));
-void swapin_link_object __P((struct link_object *, int));
-void swapout_link_object __P((struct link_object *, int));
+void swap__dynamic __P((struct link_dynamic *));
+void swap_section_dispatch_table __P((struct section_dispatch_table *));
+void swap_so_debug __P((struct so_debug *));
+void swapin_sod __P((struct sod *, int));
+void swapout_sod __P((struct sod *, int));
void swapout_fshash __P((struct fshash *, int));
#endif
diff --git a/gnu/usr.bin/ld/ldconfig/Makefile b/gnu/usr.bin/ld/ldconfig/Makefile
index d27f9b7..f565cf1 100644
--- a/gnu/usr.bin/ld/ldconfig/Makefile
+++ b/gnu/usr.bin/ld/ldconfig/Makefile
@@ -1,12 +1,12 @@
-# $Id: Makefile,v 1.4 1993/11/09 20:39:46 paul Exp $
+# $Id: Makefile,v 1.7 1993/12/10 05:10:22 mycroft Exp $
PROG= ldconfig
SRCS= ldconfig.c shlib.c etc.c
LDDIR?= $(.CURDIR)/..
-LDFLAGS += -static
-CFLAGS += -I$(LDDIR) -I$(.CURDIR) -I$(LDDIR)/$(MACHINE) -O
-BINDIR= /sbin
-MAN8 = ldconfig.8
+CFLAGS+=-I$(LDDIR) -I$(.CURDIR) -I$(LDDIR)/$(MACHINE)
+LDSTATIC=-static
+BINDIR= /sbin
+MAN8= ldconfig.8
.PATH: $(LDDIR) $(LDDIR)/$(MACHINE)
diff --git a/gnu/usr.bin/ld/ldconfig/ldconfig.8 b/gnu/usr.bin/ld/ldconfig/ldconfig.8
index 78439e5..170b618 100644
--- a/gnu/usr.bin/ld/ldconfig/ldconfig.8
+++ b/gnu/usr.bin/ld/ldconfig/ldconfig.8
@@ -1,6 +1,6 @@
.Dd October 3, 1993
.Dt LDCONFIG 8
-.Os FreeBSD
+.Os FreeBSD 1.1
.Sh NAME
.Nm ldconfig
.Nd configure the shared library cache
diff --git a/gnu/usr.bin/ld/ldconfig/ldconfig.c b/gnu/usr.bin/ld/ldconfig/ldconfig.c
index 899539d..fafe176 100644
--- a/gnu/usr.bin/ld/ldconfig/ldconfig.c
+++ b/gnu/usr.bin/ld/ldconfig/ldconfig.c
@@ -14,7 +14,7 @@
* 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
+ * derived from this software without 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
@@ -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: ldconfig.c,v 1.2 1993/11/09 04:19:22 paul Exp $
+ * $Id: ldconfig.c,v 1.4 1993/12/02 01:03:16 jkh Exp $
*/
#include <sys/param.h>
@@ -72,7 +72,7 @@ struct shlib_list {
static struct shlib_list *shlib_head = NULL, **shlib_tail = &shlib_head;
static void enter __P((char *, char *, char *, int *, int));
-static int dodir __P((char *));
+static int dodir __P((char *, int));
static int build_hints __P((void));
int
@@ -114,10 +114,10 @@ char *argv[];
std_search_dirs(NULL);
for (i = 0; i < n_search_dirs; i++)
- rval |= dodir(search_dirs[i]);
+ rval |= dodir(search_dirs[i], 1);
for (i = optind; i < argc; i++)
- rval |= dodir(argv[i]);
+ rval |= dodir(argv[i], 0);
rval |= build_hints();
@@ -125,8 +125,9 @@ char *argv[];
}
int
-dodir(dir)
+dodir(dir, silent)
char *dir;
+int silent;
{
DIR *dd;
struct dirent *dp;
@@ -134,7 +135,8 @@ char *dir;
int dewey[MAXDEWEY], ndewey;
if ((dd = opendir(dir)) == NULL) {
- perror(dir);
+ if (!silent || errno != ENOENT)
+ perror(dir);
return -1;
}
@@ -314,16 +316,26 @@ build_hints()
return -1;
}
- mywrite(&hdr, 1, sizeof(struct hints_header), fd);
- mywrite(blist, hdr.hh_nbucket, sizeof(struct hints_bucket), fd);
- mywrite(strtab, strtab_sz, 1, fd);
-
+ if (write(fd, &hdr, sizeof(struct hints_header)) !=
+ sizeof(struct hints_header)) {
+ perror(_PATH_LD_HINTS);
+ return -1;
+ }
+ if (write(fd, blist, hdr.hh_nbucket * sizeof(struct hints_bucket)) !=
+ hdr.hh_nbucket * sizeof(struct hints_bucket)) {
+ perror(_PATH_LD_HINTS);
+ return -1;
+ }
+ if (write(fd, strtab, strtab_sz) != strtab_sz) {
+ perror(_PATH_LD_HINTS);
+ return -1;
+ }
if (close(fd) != 0) {
perror(_PATH_LD_HINTS);
return -1;
}
- /* Now, install real file */
+ /* Install it */
if (unlink(_PATH_LD_HINTS) != 0 && errno != ENOENT) {
perror(_PATH_LD_HINTS);
return -1;
diff --git a/gnu/usr.bin/ld/ldd/ldd.1 b/gnu/usr.bin/ld/ldd/ldd.1
index 0c3b5e4..f5a6aba 100644
--- a/gnu/usr.bin/ld/ldd/ldd.1
+++ b/gnu/usr.bin/ld/ldd/ldd.1
@@ -1,6 +1,6 @@
.Dd October 22, 1993
.Dt LDD 1
-.Os FreeBSD
+.Os FreeBSD 1.1
.Sh NAME
.Nm ldd
.Nd list dynamic object dependencies
diff --git a/gnu/usr.bin/ld/ldd/ldd.c b/gnu/usr.bin/ld/ldd/ldd.c
index 65b0bc1..7fba989 100644
--- a/gnu/usr.bin/ld/ldd/ldd.c
+++ b/gnu/usr.bin/ld/ldd/ldd.c
@@ -14,7 +14,7 @@
* 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
+ * derived from this software without 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
@@ -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: ldd.c,v 1.3 1993/10/31 14:54:29 pk Exp $
+ * $Id: ldd.c,v 1.2 1993/11/09 04:19:27 paul Exp $
*/
#include <sys/param.h>
@@ -107,6 +107,7 @@ char *argv[];
(void)close(fd);
printf("%s:\n", *argv);
+ fflush(stdout);
switch (fork()) {
case -1:
diff --git a/gnu/usr.bin/ld/lib.c b/gnu/usr.bin/ld/lib.c
index eaa0f55..78d337e 100644
--- a/gnu/usr.bin/ld/lib.c
+++ b/gnu/usr.bin/ld/lib.c
@@ -1,5 +1,5 @@
/*
- * $Id: lib.c,v 1.7 1993/12/11 11:58:27 jkh Exp $ - library routines
+ * $Id: lib.c,v 1.8 1993/12/22 23:28:11 jkh Exp $ - library routines
*/
#include <sys/param.h>
@@ -19,13 +19,11 @@
#include "ld.h"
-char **search_dirs;
-
-/* Length of the vector `search_dirs'. */
-int n_search_dirs;
-
-struct file_entry *decode_library_subfile();
-void linear_library(), symdef_library();
+static void linear_library __P((int, struct file_entry *));
+static void symdef_library __P((int, struct file_entry *, int));
+static struct file_entry *decode_library_subfile __P((int,
+ struct file_entry *,
+ int, int *));
/*
* Search the library ENTRY, already open on descriptor DESC. This means
@@ -69,7 +67,7 @@ search_library(desc, entry)
* We store the length of the member into *LENGTH_LOC.
*/
-struct file_entry *
+static struct file_entry *
decode_library_subfile(desc, library_entry, subfile_offset, length_loc)
int desc;
struct file_entry *library_entry;
@@ -113,12 +111,10 @@ decode_library_subfile(desc, library_entry, subfile_offset, length_loc)
* 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]))) {
+ if (strncmp(hdr1.ar_name, AR_EFMT1, sizeof(AR_EFMT1) - 1) == 0 &&
+ isdigit(hdr1.ar_name[sizeof(AR_EFMT1) - 1])) {
- namelen = atoi(&hdr1.ar_name[3]);
+ namelen = atoi(&hdr1.ar_name[sizeof(AR_EFMT1) - 1]);
name = (char *)xmalloc(namelen + 1);
if (read(desc, name, namelen) != namelen)
fatal_with_file(
@@ -143,10 +139,8 @@ decode_library_subfile(desc, library_entry, subfile_offset, length_loc)
subentry->subfiles = 0;
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->flags = 0;
subentry->total_size = content_length;
(*length_loc) = member_length;
@@ -154,7 +148,7 @@ decode_library_subfile(desc, library_entry, subfile_offset, length_loc)
return subentry;
}
-int subfile_wanted_p();
+static int subfile_wanted_p __P((struct file_entry *));
/*
* Search a library that has a __.SYMDEF member. DESC is a descriptor on
@@ -163,7 +157,7 @@ int subfile_wanted_p();
* length of the __.SYMDEF data.
*/
-void
+static void
symdef_library(desc, entry, member_length)
int desc;
struct file_entry *entry;
@@ -172,7 +166,7 @@ symdef_library(desc, entry, member_length)
int *symdef_data = (int *) xmalloc(member_length);
register struct ranlib *symdef_base;
char *sym_name_base;
- int number_of_symdefs;
+ int nsymdefs;
int length_of_strings;
int not_finished;
int bytes_read;
@@ -184,24 +178,24 @@ symdef_library(desc, entry, member_length)
if (bytes_read != member_length)
fatal_with_file("malformatted __.SYMDEF in ", entry);
- number_of_symdefs = md_swap_long(*symdef_data) / sizeof(struct ranlib);
- if (number_of_symdefs < 0 ||
- number_of_symdefs * sizeof(struct ranlib) + 2 * sizeof(int) > member_length)
+ nsymdefs = md_swap_long(*symdef_data) / sizeof(struct ranlib);
+ if (nsymdefs < 0 ||
+ nsymdefs * sizeof(struct ranlib) + 2 * sizeof(int) > member_length)
fatal_with_file("malformatted __.SYMDEF in ", entry);
symdef_base = (struct ranlib *) (symdef_data + 1);
- length_of_strings = md_swap_long(*(int *) (symdef_base + number_of_symdefs));
+ length_of_strings = md_swap_long(*(int *) (symdef_base + nsymdefs));
if (length_of_strings < 0
- || number_of_symdefs * sizeof(struct ranlib) + length_of_strings
+ || nsymdefs * sizeof(struct ranlib) + length_of_strings
+ 2 * sizeof(int) > member_length)
fatal_with_file("malformatted __.SYMDEF in ", entry);
- sym_name_base = sizeof(int) + (char *) (symdef_base + number_of_symdefs);
+ sym_name_base = sizeof(int) + (char *) (symdef_base + nsymdefs);
/* Check all the string indexes for validity. */
- md_swapin_ranlib_hdr(symdef_base, number_of_symdefs);
- for (i = 0; i < number_of_symdefs; i++) {
+ md_swapin_ranlib_hdr(symdef_base, nsymdefs);
+ for (i = 0; i < nsymdefs; i++) {
register int index = symdef_base[i].ran_un.ran_strx;
if (index < 0 || index >= length_of_strings
|| (index && *(sym_name_base + index - 1)))
@@ -224,7 +218,7 @@ symdef_library(desc, entry, member_length)
* symbols.
*/
- for (i = 0; (i < number_of_symdefs &&
+ for (i = 0; (i < nsymdefs &&
((link_mode & FORCEARCHIVE) ||
undefined_global_sym_count ||
common_defined_global_count)); i++) {
@@ -256,8 +250,9 @@ symdef_library(desc, entry, member_length)
* global common 'utime' linked to a function).
*/
if (!(link_mode & FORCEARCHIVE) &&
- (!sp || sp->defined ||
- (!sp->referenced && !sp->sorefs)) )
+ (!sp || sp->defined ||
+ (!(sp->flags & GS_REFERENCED) &&
+ !sp->sorefs)))
continue;
/*
@@ -277,10 +272,11 @@ symdef_library(desc, entry, member_length)
entry, offset, &junk);
if (subentry == 0)
fatal(
- "invalid offset for %s in symbol table of %s",
+ "invalid offset for %s in symbol table of %s",
sym_name_base
+ symdef_base[i].ran_un.ran_strx,
entry->filename);
+
read_entry_symbols(desc, subentry);
subentry->strings = (char *)
malloc(subentry->string_size);
@@ -320,7 +316,7 @@ symdef_library(desc, entry, member_length)
* waste time on them.
*/
- for (j = 0; j < number_of_symdefs; j++) {
+ for (j = 0; j < nsymdefs; j++) {
if (symdef_base[j].ran_off == offset)
symdef_base[j].ran_un.ran_strx = -1;
}
@@ -343,7 +339,7 @@ symdef_library(desc, entry, member_length)
* DESC is the descriptor it is open on.
*/
-void
+static void
linear_library(desc, entry)
int desc;
struct file_entry *entry;
@@ -354,11 +350,11 @@ linear_library(desc, entry)
while ((link_mode & FORCEARCHIVE) ||
undefined_global_sym_count || common_defined_global_count) {
- int member_length;
- register struct file_entry *subentry;
+ int member_length;
+ register struct file_entry *subentry;
- subentry = decode_library_subfile(desc, entry, this_subfile_offset,
- &member_length);
+ subentry = decode_library_subfile(desc, entry,
+ this_subfile_offset, &member_length);
if (!subentry)
return;
@@ -395,7 +391,7 @@ linear_library(desc, entry)
* core, but not entered. Return nonzero if we ought to load this member.
*/
-int
+static int
subfile_wanted_p(entry)
struct file_entry *entry;
{
@@ -408,9 +404,9 @@ subfile_wanted_p(entry)
for (lsp = entry->symbols; lsp < lspend; lsp++) {
register struct nlist *p = &lsp->nzlist.nlist;
- register int type = p->n_type;
- register char *name = p->n_un.n_strx + entry->strings;
- register symbol *sp = getsym_soft(name);
+ register int type = p->n_type;
+ register char *name = p->n_un.n_strx + entry->strings;
+ register symbol *sp = getsym_soft(name);
/*
* If the symbol has an interesting definition, we could
@@ -437,7 +433,7 @@ subfile_wanted_p(entry)
dollar_cond = 1;
if (!sp)
continue;
- if (sp->referenced) {
+ if (sp->flags & SP_REFERENCED) {
if (write_map) {
print_file_name(entry, stdout);
fprintf(stdout, " needed due to $-conditional %s\n", name);
@@ -461,7 +457,7 @@ subfile_wanted_p(entry)
* common reference (see explanation above in
* symdef_library()).
*/
- if (sp->referenced && !sp->defined) {
+ if ((sp->flags & GS_REFERENCED) && !sp->defined) {
/*
* This is a symbol we are looking for. It
* is either not yet defined or defined as a
@@ -482,11 +478,11 @@ subfile_wanted_p(entry)
* If it didn't used to be common, up
* the count of common symbols.
*/
- if (!sp->max_common_size)
+ if (!sp->common_size)
common_defined_global_count++;
- if (sp->max_common_size < p->n_value)
- sp->max_common_size = p->n_value;
+ if (sp->common_size < p->n_value)
+ sp->common_size = p->n_value;
if (!sp->defined)
undefined_global_sym_count--;
sp->defined = type;
@@ -498,22 +494,59 @@ subfile_wanted_p(entry)
}
return 1;
} else {
+ /*
+ * Check for undefined symbols or commons
+ * in shared objects.
+ */
struct localsymbol *lsp;
- int defs = 0;
+ int wascommon = sp->defined && sp->common_size;
+ int iscommon = type == (N_UNDF|N_EXT) && p->n_value;
+
+ if (wascommon) {
+ /*
+ * sp was defined as common by shared object.
+ */
+ if (iscommon && p->n_value < sp->common_size)
+ sp->common_size = p->n_value;
+ continue;
+ }
- /* 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;
+ int type = lsp->nzlist.nlist.n_type;
if ( (type & N_EXT) &&
(type & N_STAB) == 0 &&
type != (N_UNDF | N_EXT))
- break; /* We need it */
+ break; /* We don't need it */
+ }
+ if (lsp != NULL) {
+ /* There's a real definition */
+ if (iscommon)
+ /*
+ * But this member wants it to be
+ * a common; ignore it.
+ continue;
+ }
+
+ if (iscommon) {
+ /*
+ * New symbol is common, just takes its
+ * size, but don't load.
+ */
+ sp->common_size = p->n_value;
+ sp->defined = type;
+ continue;
}
- if (lsp != NULL)
- continue; /* We don't need it */
+
+ /*
+ * THIS STILL MISSES the case where one shared
+ * object defines a common and the next defines
+ * more strongly; fix this someday by making
+ * `struct glosym' and enter_global_ref() more
+ * symmetric.
+ */
if (write_map) {
print_file_name(entry, stdout);
@@ -535,13 +568,13 @@ read_shared_object (desc, entry)
struct file_entry *entry;
int desc;
{
- struct link_dynamic dyn;
- struct link_dynamic_2 dyn2;
- struct nlist *np;
- struct nzlist *nzp;
- int n, i, has_nz = 0;
+ struct _dynamic dyn;
+ struct section_dispatch_table sdt;
+ struct nlist *np;
+ struct nzlist *nzp;
+ int n, i, has_nz = 0;
- if (!entry->header_read_flag)
+ if (!(entry->flags & E_HEADER_VALID))
read_header (desc, entry);
/* Read DYNAMIC structure (first in data segment) */
@@ -552,10 +585,10 @@ read_shared_object (desc, entry)
fatal_with_file (
"premature eof in data segment of ", entry);
}
- md_swapin_link_dynamic(&dyn);
+ md_swapin__dynamic(&dyn);
/* Check version */
- switch (dyn.ld_version) {
+ switch (dyn.d_version) {
default:
fatal_with_file( "unsupported _DYNAMIC version ", entry);
break;
@@ -566,26 +599,29 @@ read_shared_object (desc, entry)
break;
}
- /* Read link_dynamic_2 struct (from data segment) */
+ /* Read Section Dispatch Table (from data segment) */
lseek (desc,
- text_offset(entry) + dyn.ld_un.ld_2,
+ text_offset(entry) + (long)dyn.d_un.d_sdt -
+ (DATA_START(entry->header) - N_DATOFF(entry->header)),
L_SET);
- if (read(desc, &dyn2, sizeof dyn2) != sizeof dyn2) {
+ if (read(desc, &sdt, sizeof sdt) != sizeof sdt) {
fatal_with_file( "premature eof in data segment of ", entry);
}
- md_swapin_link_dynamic_2(&dyn2);
+ md_swapin_section_dispatch_table(&sdt);
/* Read symbols (text segment) */
- n = dyn2.ld_strings - dyn2.ld_symbols;
+ n = sdt.sdt_strings - sdt.sdt_nzlist;
entry->nsymbols = n /
(has_nz ? sizeof(struct nzlist) : sizeof(struct nlist));
nzp = (struct nzlist *)(np = (struct nlist *) alloca (n));
entry->symbols = (struct localsymbol *)
xmalloc(entry->nsymbols * sizeof(struct localsymbol));
- lseek(desc, text_offset (entry) + dyn2.ld_symbols, L_SET);
+ lseek(desc, text_offset(entry) + (long)sdt.sdt_nzlist -
+ (TEXT_START(entry->header) - N_TXTOFF(entry->header)),
+ L_SET);
if (read(desc, (char *)nzp, n) != n) {
fatal_with_file(
- "premature eof while reading dyn syms ", entry);
+ "premature eof while reading object symbols ", entry);
}
if (has_nz)
md_swapin_zsymbols(nzp, entry->nsymbols);
@@ -602,21 +638,21 @@ read_shared_object (desc, entry)
}
entry->symbols[i].symbol = NULL;
entry->symbols[i].next = NULL;
+ entry->symbols[i].entry = entry;
entry->symbols[i].gotslot_offset = -1;
- entry->symbols[i].gotslot_claimed = 0;
- entry->symbols[i].write = 0;
- entry->symbols[i].is_L_symbol = 0;
- entry->symbols[i].rename = 0;
+ entry->symbols[i].flags = 0;
}
/* Read strings (text segment) */
- n = entry->string_size = dyn2.ld_str_sz;
+ n = entry->string_size = sdt.sdt_str_sz;
entry->strings = (char *) alloca(n);
- entry->strings_offset = text_offset (entry) + dyn2.ld_strings;
- lseek(desc, entry->strings_offset, L_SET);
+ entry->strings_offset = text_offset(entry) + sdt.sdt_strings;
+ lseek(desc, entry->strings_offset -
+ (TEXT_START(entry->header) - N_TXTOFF(entry->header)),
+ L_SET);
if (read(desc, entry->strings, n) != n) {
fatal_with_file(
- "premature eof while reading dyn strings ", entry);
+ "premature eof while reading object strings ", entry);
}
enter_file_symbols (entry);
entry->strings = 0;
@@ -624,39 +660,43 @@ read_shared_object (desc, entry)
/*
* Load any subsidiary shared objects.
*/
- if (dyn2.ld_need) {
- struct link_object lobj;
+ if (sdt.sdt_sods) {
+ struct sod sod;
off_t offset;
- struct file_entry *subentry, *prev = NULL;
+ struct file_entry *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;
+ offset = (off_t)sdt.sdt_sods;
while (1) {
+ struct file_entry *subentry;
char *libname, name[MAXPATHLEN]; /*XXX*/
- lseek(desc, offset, L_SET);
- if (read(desc, &lobj, sizeof(lobj)) != sizeof(lobj)) {
+ subentry = (struct file_entry *)
+ xmalloc(sizeof(struct file_entry));
+ bzero(subentry, sizeof(struct file_entry));
+ subentry->superfile = entry;
+
+ lseek(desc, offset -
+ (TEXT_START(entry->header) - N_TXTOFF(entry->header)),
+ L_SET);
+ if (read(desc, &sod, sizeof(sod)) != sizeof(sod)) {
fatal_with_file(
- "premature eof while reading link objects ",
+ "premature eof while reading sod ",
entry);
}
- md_swapin_link_object(&lobj, 1);
- (void)lseek(desc, (off_t)lobj.lo_name, L_SET);
+ md_swapin_sod(&sod, 1);
+ (void)lseek(desc, (off_t)sod.sod_name -
+ (TEXT_START(entry->header) - N_TXTOFF(entry->header)),
+ 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;
+ if (sod.sod_library) {
+ int sod_major = sod.sod_major;
+ int sod_minor = sod.sod_minor;
libname = findshlib(name,
- &lo_major, &lo_minor, 0);
+ &sod_major, &sod_minor, 0);
if (libname == NULL)
fatal("no shared -l%s.%d.%d available",
- name, lobj.lo_major, lobj.lo_minor);
+ name, sod.sod_major, sod.sod_minor);
subentry->filename = libname;
subentry->local_sym_name = concat("-l", name, "");
} else {
@@ -671,7 +711,7 @@ read_shared_object (desc, entry)
entry->subfiles = subentry;
prev = subentry;
desc = file_open(entry);
- if ((offset = (off_t)lobj.lo_next) == 0)
+ if ((offset = (off_t)sod.sod_next) == 0)
break;
}
}
@@ -719,7 +759,7 @@ read_shared_object (desc, entry)
subentry->superfile = entry;
subentry->filename = sa_name;
subentry->local_sym_name = sa_name;
- subentry->library_flag = 1;
+ subentry->flags |= E_IS_LIBRARY;
search_library(file_open(subentry), subentry);
out:
;
@@ -740,7 +780,7 @@ struct file_entry *p;
int major = -1, minor = -1;
char *cp, *fname = NULL;
- if (p->search_dynamic_flag == 0)
+ if (!(p->flags & E_SEARCH_DYNAMIC))
goto dot_a;
fname = findshlib(p->filename, &major, &minor, 1);
@@ -749,13 +789,13 @@ struct file_entry *p;
p->filename = fname;
p->lib_major = major;
p->lib_minor = minor;
- p->search_dirs_flag = 0;
+ p->flags &= ~E_SEARCH_DIRS;
return desc;
}
free (fname);
dot_a:
- p->search_dynamic_flag = 0;
+ p->flags &= ~E_SEARCH_DYNAMIC;
if (cp = strrchr(p->filename, '/')) {
*cp++ = '\0';
fname = concat(concat(p->filename, "/lib", cp), ".a", "");
@@ -769,7 +809,7 @@ dot_a:
desc = open (string, O_RDONLY, 0);
if (desc > 0) {
p->filename = string;
- p->search_dirs_flag = 0;
+ p->flags &= ~E_SEARCH_DIRS;
break;
}
free (string);
diff --git a/gnu/usr.bin/ld/rrs.c b/gnu/usr.bin/ld/rrs.c
index 6de17b9..6c042d9 100644
--- a/gnu/usr.bin/ld/rrs.c
+++ b/gnu/usr.bin/ld/rrs.c
@@ -14,7 +14,7 @@
* 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
+ * derived from this software without 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
@@ -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.9 1993/12/04 00:53:00 jkh Exp $
+ * $Id: rrs.c,v 1.10 1993/12/11 11:58:28 jkh Exp $
*/
#include <sys/param.h>
@@ -48,9 +48,9 @@
#include "ld.h"
-static struct link_dynamic rrs_dyn; /* defined in link.h */
-static struct ld_debug rrs_ld_debug; /* defined in link.h */
-static struct link_dynamic_2 rrs_dyn2; /* defined in link.h */
+static struct _dynamic rrs_dyn; /* defined in link.h */
+static struct so_debug rrs_so_debug; /* defined in link.h */
+static struct section_dispatch_table rrs_sdt; /* defined in link.h */
static got_t *rrs_got;
static jmpslot_t *rrs_plt; /* defined in md.h */
static struct relocation_info *rrs_reloc;
@@ -73,7 +73,7 @@ static int current_jmpslot_offset;
static int current_got_offset;
static int current_reloc_offset;
static int current_hash_index;
-static int number_of_shobjs;
+int number_of_shobjs;
struct shobj {
struct shobj *next;
@@ -82,29 +82,29 @@ struct shobj {
/*
RRS text segment:
- +-------------------+ <-- ld_rel (rrs_text_start)
+ +-------------------+ <-- sdt_rel (rrs_text_start)
| |
| relocation |
| |
- +-------------------+ <-- <link_dynamic_2>.ld_hash
+ +-------------------+ <-- <sdt>.sdt_hash
| |
| hash buckets |
| |
- +-------------------+ <-- <link_dynamic_2>.ld_stab
+ +-------------------+ <-- <sdt>.sdt_nzlist
| |
| symbols |
| |
- +-------------------+ <-- <link_dynamic_2>.ld_strings
+ +-------------------+ <-- <sdt>.sdt_strings
| |
| strings |
| |
- +-------------------+ <-- <link_dynamic_2>.ld_need
+ +-------------------+ <-- <sdt>.sdt_sods
| |
| shobjs |
| |
+-------------------+
| |
- | shobjs strings | <-- <shobj>.lo_name
+ | shobjs strings | <-- <shobj>.sod_name
| |
+-------------------+
@@ -113,21 +113,21 @@ RRS data segment:
+-------------------+ <-- __DYNAMIC (rrs_data_start)
| |
- | link_dymamic |
+ | _dymamic |
| |
- +-------------------+ <-- __DYNAMIC.ldd
+ +-------------------+ <-- __DYNAMIC.d_debug
| |
- | ld_debug |
+ | so_debug |
| |
- +-------------------+ <-- __DYNAMIC.ld_un.ld_2
+ +-------------------+ <-- __DYNAMIC.d_un.d_sdt
| |
- | link_dymamic_2 |
+ | sdt |
| |
- +-------------------+ <-- _GLOBAL_OFFSET_TABLE_ (ld_got)
+ +-------------------+ <-- _GLOBAL_OFFSET_TABLE_ (sdt_got)
| |
| _GOT_ |
| |
- +-------------------+ <-- ld_plt
+ +-------------------+ <-- sdt_plt
| |
| PLT |
| |
@@ -280,12 +280,12 @@ alloc_rrs_cpy_reloc(entry, sp)
struct file_entry *entry;
symbol *sp;
{
- if (sp->cpyreloc_reserved)
+ if (sp->flags & GS_CPYRELOCRESERVED)
return;
#ifdef DEBUG
printf("alloc_rrs_copy: %s in %s\n", sp->name, get_file_name(entry));
#endif
- sp->cpyreloc_reserved = 1;
+ sp->flags |= GS_CPYRELOCRESERVED;
reserved_rrs_relocs++;
}
@@ -318,11 +318,11 @@ long *relocation;
{
struct relocation_info *r = rrs_next_reloc();
-#ifdef DEBUG
if (rp->r_address < text_start + text_size)
error("%s: RRS text relocation at %#x for \"%s\"",
get_file_name(entry), rp->r_address, sp->name);
+#ifdef DEBUG
printf("claim_rrs_reloc: %s in %s\n", sp->name, get_file_name(entry));
#endif
r->r_address = rp->r_address;
@@ -354,8 +354,8 @@ long addend;
{
struct relocation_info *r;
- if (sp->jmpslot_claimed)
- return rrs_dyn2.ld_plt + sp->jmpslot_offset;
+ if (sp->flags & GS_JMPSLOTCLAIMED)
+ return rrs_sdt.sdt_plt + sp->jmpslot_offset;
#ifdef DEBUG
printf("claim_rrs_jmpslot: %s: %s(%d) -> offset %x (textreloc %#x)\n",
@@ -375,30 +375,30 @@ printf("claim_rrs_jmpslot: %s: %s(%d) -> offset %x (textreloc %#x)\n",
sp->name, get_file_name(entry));
md_fix_jmpslot( rrs_plt + sp->jmpslot_offset/sizeof(jmpslot_t),
- rrs_dyn2.ld_plt + sp->jmpslot_offset,
+ rrs_sdt.sdt_plt + sp->jmpslot_offset,
sp->value);
if (!JMPSLOT_NEEDS_RELOC) {
- return rrs_dyn2.ld_plt + sp->jmpslot_offset;
+ return rrs_sdt.sdt_plt + sp->jmpslot_offset;
}
} else {
- md_make_jmpslot( rrs_plt + sp->jmpslot_offset/sizeof(jmpslot_t),
+ md_make_jmpslot(rrs_plt + sp->jmpslot_offset/sizeof(jmpslot_t),
sp->jmpslot_offset,
claimed_rrs_relocs);
}
if (rrs_section_type == RRS_PARTIAL)
/* PLT is self-contained */
- return rrs_dyn2.ld_plt + sp->jmpslot_offset;
+ return rrs_sdt.sdt_plt + sp->jmpslot_offset;
/*
* Install a run-time relocation for this PLT entry.
*/
r = rrs_next_reloc();
- sp->jmpslot_claimed = 1;
+ sp->flags |= GS_JMPSLOTCLAIMED;
RELOC_SYMBOL(r) = sp->rrs_symbolnum;
- r->r_address = (long)rrs_dyn2.ld_plt + sp->jmpslot_offset;
+ r->r_address = (long)rrs_sdt.sdt_plt + sp->jmpslot_offset;
if (link_mode & SYMBOLIC) {
RELOC_EXTERN_P(r) = 0;
@@ -408,7 +408,7 @@ printf("claim_rrs_jmpslot: %s: %s(%d) -> offset %x (textreloc %#x)\n",
md_make_jmpreloc(rp, r, 0);
}
- return rrs_dyn2.ld_plt + sp->jmpslot_offset;
+ return rrs_sdt.sdt_plt + sp->jmpslot_offset;
}
/*
@@ -443,7 +443,7 @@ printf("claim_rrs_gotslot: %s(%d) slot offset %#x, addend %#x\n",
"internal error: %s: claim_rrs_gotslot: %s: gotslot_offset == -1\n",
get_file_name(entry), sp->name);
- if (sp->gotslot_claimed)
+ if (sp->flags & GS_GOTSLOTCLAIMED)
/* This symbol already passed here before. */
return sp->gotslot_offset;
@@ -497,8 +497,8 @@ printf("claim_rrs_gotslot: %s(%d) slot offset %#x, addend %#x\n",
* as no symbol need be looked up at run-time.
*/
r = rrs_next_reloc();
- sp->gotslot_claimed = 1;
- r->r_address = rrs_dyn2.ld_got + sp->gotslot_offset;
+ sp->flags |= GS_GOTSLOTCLAIMED;
+ r->r_address = rrs_sdt.sdt_got + sp->gotslot_offset;
RELOC_SYMBOL(r) = sp->rrs_symbolnum;
RELOC_EXTERN_P(r) = !(reloc_type == RELTYPE_RELATIVE);
md_make_gotreloc(rp, r, reloc_type);
@@ -524,7 +524,7 @@ long addend;
addend += lsp->nzlist.nz_value;
if (!RELOC_STATICS_THROUGH_GOT_P(r))
- return addend - rrs_dyn2.ld_got;
+ return addend - rrs_sdt.sdt_got;
#ifdef DEBUG
printf("claim_rrs_internal_gotslot: %s: slot offset %#x, addend = %#x\n",
@@ -536,7 +536,7 @@ printf("claim_rrs_internal_gotslot: %s: slot offset %#x, addend = %#x\n",
"internal error: %s: claim_rrs_internal_gotslot at %#x: slot_offset == -1\n",
get_file_name(entry), RELOC_ADDRESS(rp));
- if (lsp->gotslot_claimed)
+ if (lsp->flags & LS_GOTSLOTCLAIMED)
/* Already done */
return lsp->gotslot_offset;
@@ -549,8 +549,8 @@ 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->gotslot_claimed = 1;
- r->r_address = rrs_dyn2.ld_got + lsp->gotslot_offset;
+ lsp->flags |= LS_GOTSLOTCLAIMED;
+ r->r_address = rrs_sdt.sdt_got + lsp->gotslot_offset;
RELOC_EXTERN_P(r) = 0;
md_make_gotreloc(rp, r, RELTYPE_RELATIVE);
return lsp->gotslot_offset;
@@ -564,10 +564,10 @@ symbol *sp;
{
struct relocation_info *r;
- if (sp->cpyreloc_claimed)
+ if (sp->flags & GS_CPYRELOCCLAIMED)
return;
- if (!sp->cpyreloc_reserved)
+ if (!(sp->flags & GS_CPYRELOCRESERVED))
fatal("internal error: %s: claim_cpy_reloc: %s: no reservation\n",
get_file_name(entry), sp->name);
@@ -577,7 +577,7 @@ printf("claim_rrs_copy: %s: %s -> %x\n",
#endif
r = rrs_next_reloc();
- sp->cpyreloc_claimed = 1;
+ sp->flags |= GS_CPYRELOCCLAIMED;
r->r_address = rp->r_address;
RELOC_SYMBOL(r) = sp->rrs_symbolnum;
RELOC_EXTERN_P(r) = RELOC_EXTERN_P(rp);
@@ -617,7 +617,7 @@ int index;
for (; *cp; cp++)
hashval = (hashval << 1) + *cp;
- hashval = (hashval & 0x7fffffff) % rrs_dyn2.ld_buckets;
+ hashval = (hashval & 0x7fffffff) % rrs_sdt.sdt_buckets;
/* Get to the bucket */
hp = rrs_hashtab + hashval;
@@ -651,11 +651,27 @@ void
consider_rrs_section_lengths()
{
int n;
- struct shobj *shp;
+ struct shobj *shp, **shpp;
int symbolsize;
- /* First, determine what of the RRS we want */
+#ifdef notyet
+/* We run into trouble with this as long as shared object symbols
+ are not checked for definitions */
+ /*
+ * First, determine the real number of shared objects we need.
+ */
+ for (shpp = &rrs_shobjs; *shpp; shpp = &(*shpp)->next) {
+ while (*shpp && !((*shpp)->entry->flags & E_SYMBOLS_USED)) {
+ if (--number_of_shobjs < 0)
+ fatal("internal error: number_of_shobjs < 0");
+ *shpp = (*shpp)->next;
+ }
+ if (*shpp == NULL)
+ break;
+ }
+#endif
+ /* First, determine what of the RRS we want */
if (relocatable_output)
rrs_section_type = RRS_NONE;
else if (link_mode & SHAREABLE)
@@ -685,13 +701,14 @@ consider_rrs_section_lengths()
* from crt0), as this is the method used to determine whether the
* run-time linker must be called.
*/
- if (!(link_mode & SHAREABLE) && !dynamic_symbol->referenced)
+ if (!(link_mode & SHAREABLE) &&
+ !(dynamic_symbol->flags & GS_REFERENCED))
fatal("No reference to __DYNAMIC");
- dynamic_symbol->referenced = 1;
+ dynamic_symbol->flags |= GS_REFERENCED;
if (number_of_gotslots > 1)
- got_symbol->referenced = 1;
+ got_symbol->flags |= GS_REFERENCED;
/* Next, allocate relocs, got and plt */
@@ -722,7 +739,7 @@ consider_rrs_section_lengths()
*/
dynamic_symbol->rrs_symbolnum = number_of_rrs_symbols++;
FOR_EACH_SYMBOL(i ,sp) {
- if (sp->referenced) {
+ if (sp->flags & GS_REFERENCED) {
rrs_strtab_size += 1 + strlen(sp->name);
if (sp != dynamic_symbol)
sp->rrs_symbolnum = number_of_rrs_symbols++;
@@ -743,16 +760,16 @@ consider_rrs_section_lengths()
* Now that we know how many RRS symbols there are going to be,
* allocate and initialize the RRS symbol hash table.
*/
- rrs_dyn2.ld_buckets = number_of_rrs_symbols/4;
- if (rrs_dyn2.ld_buckets < 4)
- rrs_dyn2.ld_buckets = 4;
+ rrs_sdt.sdt_buckets = number_of_rrs_symbols/4;
+ if (rrs_sdt.sdt_buckets < 4)
+ rrs_sdt.sdt_buckets = 4;
- number_of_rrs_hash_entries = rrs_dyn2.ld_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_dyn2.ld_buckets; n++)
+ for (n = 0; n < rrs_sdt.sdt_buckets; n++)
rrs_hashtab[n].rh_symbolnum = -1;
- current_hash_index = rrs_dyn2.ld_buckets;
+ current_hash_index = rrs_sdt.sdt_buckets;
/*
* Get symbols into hash table now, so we can fine tune the size
@@ -760,7 +777,7 @@ consider_rrs_section_lengths()
* to the number of hash link slots actually used.
*/
FOR_EACH_SYMBOL(i ,sp) {
- if (sp->referenced)
+ if (sp->flags & GS_REFERENCED)
rrs_insert_hash(sp->name, sp->rrs_symbolnum);
} END_EACH_SYMBOL;
number_of_rrs_hash_entries = current_hash_index;
@@ -768,9 +785,9 @@ consider_rrs_section_lengths()
/*
* Calculate RRS section sizes.
*/
- rrs_data_size = sizeof(struct link_dynamic);
- rrs_data_size += sizeof(struct ld_debug);
- rrs_data_size += sizeof(struct link_dynamic_2);
+ rrs_data_size = sizeof(struct _dynamic);
+ rrs_data_size += sizeof(struct so_debug);
+ rrs_data_size += sizeof(struct section_dispatch_table);
rrs_data_size += number_of_gotslots * sizeof(got_t);
rrs_data_size += number_of_jmpslots * sizeof(jmpslot_t);
rrs_data_size = MALIGN(rrs_data_size);
@@ -790,7 +807,7 @@ consider_rrs_section_lengths()
if (*name == '-' && *(name+1) == 'l')
name += 2;
- rrs_text_size += sizeof(struct link_object);
+ rrs_text_size += sizeof(struct sod);
rrs_text_size += 1 + strlen(name);
}
@@ -808,8 +825,8 @@ relocate_rrs_addresses()
return;
if (rrs_section_type == RRS_PARTIAL) {
- got_symbol->value = rrs_dyn2.ld_got = rrs_data_start;
- rrs_dyn2.ld_plt = rrs_dyn2.ld_got +
+ got_symbol->value = rrs_sdt.sdt_got = rrs_data_start;
+ rrs_sdt.sdt_plt = rrs_sdt.sdt_got +
number_of_gotslots * sizeof(got_t);
return;
}
@@ -817,48 +834,48 @@ relocate_rrs_addresses()
/*
* RRS data relocations.
*/
- rrs_dyn.ld_version = soversion;
- rrs_dyn.ldd = (struct ld_debug *)
- (rrs_data_start + sizeof(struct link_dynamic));
- rrs_dyn.ld_un.ld_2 = (struct link_dynamic_2 *)
- ((long)rrs_dyn.ldd + sizeof(struct ld_debug));
+ rrs_dyn.d_version = soversion;
+ rrs_dyn.d_debug = (struct so_debug *)
+ (rrs_data_start + sizeof(struct _dynamic));
+ rrs_dyn.d_un.d_sdt = (struct section_dispatch_table *)
+ ((long)rrs_dyn.d_debug + sizeof(struct so_debug));
- rrs_dyn2.ld_got = (long)rrs_dyn.ld_un.ld_2 +
- sizeof(struct link_dynamic_2);
- rrs_dyn2.ld_plt = rrs_dyn2.ld_got + number_of_gotslots*sizeof(got_t);
+ rrs_sdt.sdt_got = (long)rrs_dyn.d_un.d_sdt +
+ sizeof(struct section_dispatch_table);
+ rrs_sdt.sdt_plt = rrs_sdt.sdt_got + number_of_gotslots*sizeof(got_t);
/*
* RRS text relocations.
*/
- rrs_dyn2.ld_rel = rrs_text_start;
+ rrs_sdt.sdt_rel = rrs_text_start;
/*
* Sun BUG compatibility alert.
* Main program's RRS text values are relative to TXTADDR? WHY??
*/
#ifdef SUN_COMPAT
if (soversion == LD_VERSION_SUN && !(link_mode & SHAREABLE))
- rrs_dyn2.ld_rel -= N_TXTADDR(outheader);
+ rrs_sdt.sdt_rel -= N_TXTADDR(outheader);
#endif
- rrs_dyn2.ld_hash = rrs_dyn2.ld_rel +
+ rrs_sdt.sdt_hash = rrs_sdt.sdt_rel +
reserved_rrs_relocs * sizeof(struct relocation_info);
- rrs_dyn2.ld_symbols = rrs_dyn2.ld_hash +
+ rrs_sdt.sdt_nzlist = rrs_sdt.sdt_hash +
number_of_rrs_hash_entries * sizeof(struct rrs_hash);
- rrs_dyn2.ld_strings = rrs_dyn2.ld_symbols +
+ rrs_sdt.sdt_strings = rrs_sdt.sdt_nzlist +
number_of_rrs_symbols * rrs_symbol_size;
- rrs_dyn2.ld_str_sz = rrs_strtab_size;
- rrs_dyn2.ld_text_sz = text_size;
- rrs_dyn2.ld_plt_sz = number_of_jmpslots * sizeof(jmpslot_t);
+ rrs_sdt.sdt_str_sz = rrs_strtab_size;
+ rrs_sdt.sdt_text_sz = text_size;
+ rrs_sdt.sdt_plt_sz = number_of_jmpslots * sizeof(jmpslot_t);
- rrs_dyn2.ld_need = rrs_shobjs ? rrs_dyn2.ld_strings+rrs_strtab_size : 0;
- rrs_dyn2.ld_stab_hash = 0;
- rrs_dyn2.ld_rules = 0;
+ rrs_sdt.sdt_sods = rrs_shobjs ? rrs_sdt.sdt_strings+rrs_strtab_size : 0;
+ rrs_sdt.sdt_filler1 = 0;
+ rrs_sdt.sdt_filler2 = 0;
/*
* Assign addresses to _GLOBAL_OFFSET_TABLE_ and __DYNAMIC
* &__DYNAMIC is also in the first GOT entry.
*/
- got_symbol->value = rrs_dyn2.ld_got;
+ got_symbol->value = rrs_sdt.sdt_got;
*rrs_got = dynamic_symbol->value = rrs_data_start;
@@ -896,14 +913,14 @@ write_rrs_data()
return;
}
- md_swapout_link_dynamic(&rrs_dyn);
- mywrite(&rrs_dyn, 1, sizeof(struct link_dynamic), outdesc);
+ md_swapout__dynamic(&rrs_dyn);
+ mywrite(&rrs_dyn, 1, sizeof(struct _dynamic), outdesc);
- md_swapout_ld_debug(&rrs_ld_debug);
- mywrite(&rrs_ld_debug, 1, sizeof(struct ld_debug), outdesc);
+ md_swapout_so_debug(&rrs_so_debug);
+ mywrite(&rrs_so_debug, 1, sizeof(struct so_debug), outdesc);
- md_swapout_link_dynamic_2(&rrs_dyn2);
- mywrite(&rrs_dyn2, 1, sizeof(struct link_dynamic_2), outdesc);
+ md_swapout_section_dispatch_table(&rrs_sdt);
+ mywrite(&rrs_sdt, 1, sizeof(struct section_dispatch_table), outdesc);
md_swapout_got(rrs_got, number_of_gotslots);
mywrite(rrs_got, number_of_gotslots, sizeof(got_t), outdesc);
@@ -921,7 +938,7 @@ write_rrs_text()
struct nzlist *nlp;
int offset = 0;
struct shobj *shp;
- struct link_object *lo;
+ struct sod *sodp;
if (rrs_section_type == RRS_PARTIAL)
return;
@@ -967,7 +984,7 @@ write_rrs_text()
*/
FOR_EACH_SYMBOL(i, sp) {
- if (!sp->referenced || sp == dynamic_symbol)
+ if (!(sp->flags & GS_REFERENCED) || sp == dynamic_symbol)
continue;
if ((long)nlp - (long)rrs_symbols >=
@@ -993,6 +1010,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);
} else if (sp->defined == N_SIZE) {
/*
* Make sure this symbol isn't going
@@ -1003,47 +1021,36 @@ write_rrs_text()
} else {
nlp->nz_type = sp->defined;
nlp->nz_value = sp->value;
+ nlp->nz_other = N_OTHER(0, sp->aux);
}
if (LD_VERSION_NZLIST_P(soversion))
nlp->nz_size = sp->size;
- } else if (sp->max_common_size) {
+ } else if (sp->common_size) {
/*
* a common definition
*/
nlp->nz_type = N_UNDF | N_EXT;
- nlp->nz_value = sp->max_common_size;
+ nlp->nz_value = sp->common_size;
} 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.
+ */
+ if (sp->aux != AUX_FUNC)
+ fatal("%s: non-function jmpslot",
+ sp->name);
+ nlp->nz_other = N_OTHER(0, sp->aux);
+ nlp->nz_value =
+ rrs_sdt.sdt_plt + sp->jmpslot_offset;
+ }
} else
fatal(
"internal error: %s defined in mysterious way",
sp->name);
- /* Handle auxialiary type qualifiers */
- switch (sp->aux) {
- case 0:
- break;
- case RRS_FUNC:
- if (sp->so_defined != (N_TEXT+N_EXT))
- fatal("internal error: %s: other but not text",
- sp->name);
- if (sp->jmpslot_offset == -1)
- fatal(
- "internal error: %s has no jmpslot but other",
- sp->name);
- nlp->nz_other = sp->aux;
- nlp->nz_value =
- rrs_dyn2.ld_plt + sp->jmpslot_offset;
- break;
- default:
- fatal(
- "internal error: %s: unsupported other value: %x",
- sp->name, sp->aux);
- break;
- }
-
/* Set symbol's name */
nlp->nz_strx = offset;
strcpy(rrs_strtab + offset, sp->name);
@@ -1089,9 +1096,8 @@ write_rrs_text()
/*
* Write the names of the shared objects needed at run-time
*/
- pos = rrs_dyn2.ld_need + number_of_shobjs * sizeof(struct link_object);
- lo = (struct link_object *)alloca(
- number_of_shobjs * sizeof(struct link_object));
+ pos = rrs_sdt.sdt_sods + number_of_shobjs * sizeof(struct sod);
+ sodp = (struct sod *)alloca( number_of_shobjs * sizeof(struct sod));
for (i = 0, shp = rrs_shobjs; shp; i++, shp = shp->next) {
char *name = shp->entry->local_sym_name;
@@ -1100,27 +1106,27 @@ write_rrs_text()
fatal("internal error: # of link objects exceeds %d",
number_of_shobjs);
- lo[i].lo_name = pos;
- lo[i].lo_major = shp->entry->lib_major;
- lo[i].lo_minor = shp->entry->lib_minor;
+ sodp[i].sod_name = pos;
+ sodp[i].sod_major = shp->entry->lib_major;
+ sodp[i].sod_minor = shp->entry->lib_minor;
if (*name == '-' && *(name+1) == 'l') {
name += 2;
- lo[i].lo_library = 1;
+ sodp[i].sod_library = 1;
} else
- lo[i].lo_library = 0;
+ sodp[i].sod_library = 0;
pos += 1 + strlen(name);
- lo[i].lo_next = (i == number_of_shobjs - 1) ? 0 :
- (rrs_dyn2.ld_need + (i+1)*sizeof(struct link_object));
+ sodp[i].sod_next = (i == number_of_shobjs - 1) ? 0 :
+ (rrs_sdt.sdt_sods + (i+1)*sizeof(struct sod));
}
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);
+ md_swapout_sod(sodp, number_of_shobjs);
+ mywrite(sodp, number_of_shobjs, sizeof(struct sod), outdesc);
for (i = 0, shp = rrs_shobjs; shp; i++, shp = shp->next) {
char *name = shp->entry->local_sym_name;
diff --git a/gnu/usr.bin/ld/rtld/Makefile b/gnu/usr.bin/ld/rtld/Makefile
index 1a76c51..0fbf2b2 100644
--- a/gnu/usr.bin/ld/rtld/Makefile
+++ b/gnu/usr.bin/ld/rtld/Makefile
@@ -1,25 +1,25 @@
-# $Id: Makefile,v 1.7 1993/12/11 21:05:59 jkh Exp $
+# $Id: Makefile,v 1.8 1994/01/28 21:01:20 pk Exp $
PROG= ld.so
-SRCS= mdprologue.S sbrk.c rtld.c shlib.c etc.c md.c
+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) -O $(PICFLAG) -DRTLD
-LDFLAGS = -Bshareable -Bsymbolic -assert nosymbolic -Z
-LIBS = -lc_pic -lgcc_pic
+CFLAGS+=-I$(LDDIR) -I$(.CURDIR) -I$(LDDIR)/$(MACHINE) $(PICFLAG) -DRTLD
+LDFLAGS+=-Bshareable -Bsymbolic -assert nosymbolic
+ASFLAGS+=-k
+LDADD+= -lc_pic
BINDIR= /usr/libexec
-ASFLAGS = -k
-
-.PATH: $(LDDIR) $(LDDIR)/$(MACHINE)
.SUFFIXES: .S
+.PATH: $(LDDIR) $(LDDIR)/$(MACHINE)
+
$(PROG):
- $(LD) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIBS) $(LDADD)
+ $(LD) -o $(PROG) $(LDFLAGS) $(OBJS) $(LDADD)
.S.o:
- $(CPP) $(.IMPSRC) | $(AS) $(ASFLAGS) -o $(.TARGET) -
+ ${CPP} ${.IMPSRC} | ${AS} ${ASFLAGS} -o ${.TARGET} -
.include <bsd.prog.mk>
diff --git a/gnu/usr.bin/ld/rtld/rtld.c b/gnu/usr.bin/ld/rtld/rtld.c
index e02fef6..72ab49e 100644
--- a/gnu/usr.bin/ld/rtld/rtld.c
+++ b/gnu/usr.bin/ld/rtld/rtld.c
@@ -14,7 +14,7 @@
* 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
+ * derived from this software without 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
@@ -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.13 1994/01/12 23:16:19 jkh Exp $
+ * $Id: rtld.c,v 1.14 1994/01/14 11:47:00 jkh Exp $
*/
#include <machine/vmparam.h>
@@ -39,6 +39,7 @@
#include <sys/file.h>
#include <sys/time.h>
#include <sys/resource.h>
+#include <sys/errno.h>
#include <sys/mman.h>
#ifndef BSD
#define MAP_COPY MAP_PRIVATE
@@ -62,92 +63,115 @@
#endif
/*
- * Loader private data, hung off link_map->lm_lpd
+ * Loader private data, hung off <so_map>->som_spd
*/
-struct lm_private {
- int lpd_version;
- struct link_map *lpd_parent;
+struct somap_private {
+ int spd_version;
+ struct so_map *spd_parent;
+ int spd_refcount;
+ int spd_flags;
+#define RTLD_MAIN 1
+#define RTLD_RTLD 2
+#define RTLD_DL 4
+
#ifdef SUN_COMPAT
- long lpd_offset; /* Correction for Sun main programs */
+ long spd_offset; /* Correction for Sun main programs */
#endif
};
+#define LM_PRIVATE(smp) ((struct somap_private *)(smp)->som_spd)
+
#ifdef SUN_COMPAT
-#define LM_OFFSET(lmp) (((struct lm_private *)((lmp)->lm_lpd))->lpd_offset)
+#define LM_OFFSET(smp) (LM_PRIVATE(smp)->spd_offset)
#else
-#define LM_OFFSET(lmp) (0)
+#define LM_OFFSET(smp) (0)
#endif
-/* Base address for link_dynamic_2 entries */
-#define LM_LDBASE(lmp) (lmp->lm_addr + LM_OFFSET(lmp))
+/* Base address for section_dispatch_table entries */
+#define LM_LDBASE(smp) (smp->som_addr + LM_OFFSET(smp))
/* Start of text segment */
-#define LM_TXTADDR(lmp) (lmp->lm_addr == (caddr_t)0 ? PAGSIZ : 0)
+#define LM_TXTADDR(smp) (smp->som_addr == (caddr_t)0 ? PAGSIZ : 0)
/* Start of run-time relocation_info */
-#define LM_REL(lmp) ((struct relocation_info *) \
- (lmp->lm_addr + LM_OFFSET(lmp) + LD_REL((lmp)->lm_ld)))
+#define LM_REL(smp) ((struct relocation_info *) \
+ (smp->som_addr + LM_OFFSET(smp) + LD_REL((smp)->som_dynamic)))
/* Start of symbols */
-#define LM_SYMBOL(lmp, i) ((struct nzlist *) \
- (lmp->lm_addr + LM_OFFSET(lmp) + LD_SYMBOL((lmp)->lm_ld) + \
- i * (LD_VERSION_NZLIST_P(lmp->lm_ld->ld_version) ? \
- sizeof(struct nzlist) : sizeof(struct nlist))))
+#define LM_SYMBOL(smp, i) ((struct nzlist *) \
+ (smp->som_addr + LM_OFFSET(smp) + LD_SYMBOL((smp)->som_dynamic) + \
+ i * (LD_VERSION_NZLIST_P(smp->som_dynamic->d_version) ? \
+ sizeof(struct nzlist) : sizeof(struct nlist))))
/* Start of hash table */
-#define LM_HASH(lmp) ((struct rrs_hash *) \
- (lmp->lm_addr + LM_OFFSET(lmp) + LD_HASH((lmp)->lm_ld)))
+#define LM_HASH(smp) ((struct rrs_hash *) \
+ ((smp)->som_addr + LM_OFFSET(smp) + LD_HASH((smp)->som_dynamic)))
/* Start of strings */
-#define LM_STRINGS(lmp) ((char *) \
- (lmp->lm_addr + LM_OFFSET(lmp) + LD_STRINGS((lmp)->lm_ld)))
+#define LM_STRINGS(smp) ((char *) \
+ ((smp)->som_addr + LM_OFFSET(smp) + LD_STRINGS((smp)->som_dynamic)))
/* End of text */
-#define LM_ETEXT(lmp) ((char *) \
- (lmp->lm_addr + LM_TXTADDR(lmp) + LD_TEXTSZ((lmp)->lm_ld)))
+#define LM_ETEXT(smp) ((char *) \
+ ((smp)->som_addr + LM_TXTADDR(smp) + LD_TEXTSZ((smp)->som_dynamic)))
/* PLT is in data segment, so don't use LM_OFFSET here */
-#define LM_PLT(lmp) ((jmpslot_t *) \
- (lmp->lm_addr + LD_PLT((lmp)->lm_ld)))
+#define LM_PLT(smp) ((jmpslot_t *) \
+ ((smp)->som_addr + LD_PLT((smp)->som_dynamic)))
/* Parent of link map */
-#define LM_PARENT(lmp) (((struct lm_private *)((lmp)->lm_lpd))->lpd_parent)
+#define LM_PARENT(smp) (LM_PRIVATE(smp)->spd_parent)
char **environ;
int errno;
-uid_t uid, euid;
-gid_t gid, egid;
-int careful;
+static uid_t uid, euid;
+static gid_t gid, egid;
+static int careful;
+static char *main_progname = "main";
-struct link_map *link_map_head, *main_map;
-struct link_map **link_map_tail = &link_map_head;
+struct so_map *link_map_head, *main_map;
+struct so_map **link_map_tail = &link_map_head;
struct rt_symbol *rt_symbol_head;
-static int dlopen(), dlclose(), dlsym();
+static void *dlopen __P((char *, int));
+static int dlclose __P((void *));
+static void *dlsym __P((void *, char *));
+static int dlctl __P((void *, int, void *));
static struct ld_entry ld_entry = {
- dlopen, dlclose, dlsym
+ dlopen, dlclose, dlsym, dlctl
};
-void xprintf __P((char *, ...));
+ void xprintf __P((char *, ...));
static void init_brk __P((void));
-static void load_maps __P((struct crt_ldso *));
-static void map_object __P((struct link_object *, struct link_map *));
-static void alloc_link_map __P(( char *, struct link_object *,
- struct link_map *, caddr_t,
- struct link_dynamic *));
-static void check_text_reloc __P(( struct relocation_info *,
- struct link_map *,
+static void load_objects __P(( struct crt_ldso *,
+ struct _dynamic *));
+static struct so_map *map_object __P((struct sod *, struct so_map *));
+static struct so_map *alloc_link_map __P(( char *, struct sod *,
+ struct so_map *, caddr_t,
+ struct _dynamic *));
+static void inline check_text_reloc __P(( struct relocation_info *,
+ struct so_map *,
caddr_t));
-static void reloc_maps __P((void));
-static void reloc_copy __P((void));
-static void init_maps __P((void));
+static void reloc_map __P((struct so_map *));
+static void reloc_copy __P((struct so_map *));
+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 struct nzlist *lookup __P((char *, struct link_map **, int));
-static struct rt_symbol *lookup_rts __P((char *));
-static struct rt_symbol *enter_rts __P((char *, long, int, caddr_t, long));
+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 inline int
+strcmp (register const char *s1, register const char *s2)
+{
+ while (*s1 == *s2++)
+ if (*s1++ == 0)
+ return (0);
+ return (*(unsigned char *)s1 - *(unsigned char *)--s2);
+}
#include "md-static-funcs.c"
@@ -155,34 +179,36 @@ static struct rt_symbol *enter_rts __P((char *, long, int, caddr_t, long));
* Called from assembler stub that has set up crtp (passed from crt0)
* and dp (our __DYNAMIC).
*/
-void
+int
rtld(version, crtp, dp)
int version;
struct crt_ldso *crtp;
-struct link_dynamic *dp;
+struct _dynamic *dp;
{
int n;
int nreloc; /* # of ld.so relocations */
struct relocation_info *reloc;
char **envp;
- struct ld_debug *ldp;
+ struct so_debug *ddp;
+ struct so_map *smp;
/* Check version */
- if (version != CRT_VERSION_BSD && version != CRT_VERSION_SUN)
- return;
+ if ( version != CRT_VERSION_BSD_2 &&
+ version != CRT_VERSION_BSD_3 &&
+ version != CRT_VERSION_SUN)
+ return -1;
/* Fixup __DYNAMIC structure */
- (long)dp->ld_un.ld_2 += crtp->crt_ba;
+ (long)dp->d_un.d_sdt += crtp->crt_ba;
- /* Be careful not to use .div routine from library */
+ /* Divide by hand to avoid possible use of library division routine */
for ( nreloc = 0, n = LD_RELSZ(dp);
n > 0;
n -= sizeof(struct relocation_info) ) nreloc++;
/* Relocate ourselves */
- for ( reloc = (struct relocation_info *)
- (dp->ld_un.ld_2->ld_rel + crtp->crt_ba);
+ for ( reloc = (struct relocation_info *)(LD_REL(dp) + crtp->crt_ba);
nreloc;
nreloc--, reloc++) {
@@ -192,6 +218,8 @@ struct link_dynamic *dp;
}
progname = "ld.so";
+ if (version >= CRT_VERSION_BSD_3)
+ main_progname = crtp->crt_prog;
/* Setup out (private) environ variable */
environ = crtp->crt_ep;
@@ -212,89 +240,134 @@ struct link_dynamic *dp;
std_search_dirs(getenv("LD_LIBRARY_PATH"));
/* Load required objects into the process address space */
- load_maps(crtp);
+ load_objects(crtp, dp);
/* Relocate all loaded objects according to their RRS segments */
- reloc_maps();
- reloc_copy();
- init_maps();
+ for (smp = link_map_head; smp; smp = smp->som_next) {
+ if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
+ continue;
+ reloc_map(smp);
+ }
+
+ /* Copy any relocated initialized data. */
+ for (smp = link_map_head; smp; smp = smp->som_next) {
+ if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
+ continue;
+ reloc_copy(smp);
+ }
+
+ /* Call any object initialization routines. */
+ for (smp = link_map_head; smp; smp = smp->som_next) {
+ if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
+ continue;
+ init_map(smp, ".init");
+ }
/* Fill in some field in main's __DYNAMIC structure */
- crtp->crt_dp->ld_entry = &ld_entry;
+ crtp->crt_dp->d_entry = &ld_entry;
+ crtp->crt_dp->d_un.d_sdt->sdt_loaded = link_map_head->som_next;
- ldp = crtp->crt_dp->ldd;
- ldp->ldd_cp = rt_symbol_head;
- if (ldp->ldd_in_debugger) {
+ ddp = crtp->crt_dp->d_debug;
+ ddp->dd_cc = rt_symbol_head;
+ if (ddp->dd_in_debugger) {
caddr_t addr = (caddr_t)((long)crtp->crt_bp & (~(PAGSIZ - 1)));
/* Set breakpoint for the benefit of debuggers */
if (mprotect(addr, PAGSIZ,
PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
perror("mprotect"),
- fatal("Cannot set breakpoint\n");
+ fatal("Cannot set breakpoint (%s)\n", main_progname);
}
- md_set_breakpoint(crtp->crt_bp, &ldp->ldd_bp_inst);
+ md_set_breakpoint(crtp->crt_bp, &ddp->dd_bpt_shadow);
if (mprotect(addr, PAGSIZ, PROT_READ|PROT_EXEC) == -1) {
perror("mprotect");
}
- ldp->ldd_bp_addr = crtp->crt_bp;
+ ddp->dd_bpt_addr = crtp->crt_bp;
if (link_map_head)
- ldp->ldd_sym_loaded = 1;
+ ddp->dd_sym_loaded = 1;
}
- crtp->crt_dp->ld_un.ld_2->ld_loaded = link_map_head->lm_next;
+
/* Close our file descriptor */
(void)close(crtp->crt_ldfd);
+ return 0;
}
static void
-load_maps(crtp)
+load_objects(crtp, dp)
struct crt_ldso *crtp;
+struct _dynamic *dp;
{
- struct link_map *lmp;
- int tracing = (int)getenv("LD_TRACE_LOADED_OBJECTS");
+ struct so_map *smp;
+ int tracing = (int)getenv("LD_TRACE_LOADED_OBJECTS");
/* Handle LD_PRELOAD's here */
/* Make an entry for the main program */
- alloc_link_map("main", (struct link_object *)0, (struct link_map *)0,
+ smp = alloc_link_map(main_progname, (struct sod *)0, (struct so_map *)0,
(caddr_t)0, crtp->crt_dp);
+ LM_PRIVATE(smp)->spd_refcount++;
+ LM_PRIVATE(smp)->spd_flags |= RTLD_MAIN;
- for (lmp = link_map_head; lmp; lmp = lmp->lm_next) {
- struct link_object *lop;
- long next = 0;
+ /* Make an entry for ourselves */
+ smp = alloc_link_map("/usr/libexec/ld.so", (struct sod *)0, (struct so_map *)0,
+ (caddr_t)crtp->crt_ba, dp);
+ LM_PRIVATE(smp)->spd_refcount++;
+ LM_PRIVATE(smp)->spd_flags |= RTLD_RTLD;
- if (lmp->lm_ld)
- next = LD_NEED(lmp->lm_ld);
+ for (smp = link_map_head; smp; smp = smp->som_next) {
+ struct sod *sodp;
+ long next = 0;
+
+ if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
+ continue;
+
+ if (smp->som_dynamic)
+ next = LD_NEED(smp->som_dynamic);
while (next) {
- lop = (struct link_object *) (LM_LDBASE(lmp) + next);
- map_object(lop, lmp);
- next = lop->lo_next;
+ struct so_map *newmap;
+
+ sodp = (struct sod *)(LM_LDBASE(smp) + next);
+ if ((newmap = map_object(sodp, smp)) == NULL) {
+ if (!tracing) {
+ char *name = (char *)
+ (sodp->sod_name + LM_LDBASE(smp));
+ char *fmt = sodp->sod_library ?
+ "%s: lib%s.so.%d.%d: %s\n" :
+ "%s: %s: %s\n";
+ fatal(fmt, main_progname, name,
+ sodp->sod_major,
+ sodp->sod_minor,
+ strerror(errno));
+ }
+ newmap = alloc_link_map(NULL, sodp, smp, 0, 0);
+ }
+ LM_PRIVATE(newmap)->spd_refcount++;
+ next = sodp->sod_next;
}
}
if (! tracing)
return;
- for (lmp = link_map_head; lmp; lmp = lmp->lm_next) {
- struct link_object *lop;
- char *name, *path;
+ for (smp = link_map_head; smp; smp = smp->som_next) {
+ struct sod *sodp;
+ char *name, *path;
- if ((lop = lmp->lm_lop) == NULL)
+ if ((sodp = smp->som_sod) == NULL)
continue;
+ name = sodp->sod_name + LM_LDBASE(LM_PARENT(smp));
- name = lop->lo_name + LM_LDBASE(LM_PARENT(lmp));
-
- if ((path = lmp->lm_name) == NULL)
+ if ((path = smp->som_path) == NULL)
path = "not found";
- if (lop->lo_library)
+ if (sodp->sod_library)
printf("\t-l%s.%d => %s (%#x)\n", name,
- lop->lo_major, path, lmp->lm_addr);
+ sodp->sod_major, path, smp->som_addr);
else
- printf("\t%s => %s (%#x)\n", name, path, lmp->lm_addr);
+ printf("\t%s => %s (%#x)\n", name, path, smp->som_addr);
}
exit(0);
@@ -304,94 +377,120 @@ struct crt_ldso *crtp;
* Allocate a new link map for an shared object NAME loaded at ADDR as a
* result of the presence of link object LOP in the link map PARENT.
*/
-static void
-alloc_link_map(name, lop, parent, addr, dp)
-char *name;
-struct link_map *parent;
-struct link_object *lop;
-caddr_t addr;
-struct link_dynamic *dp;
+ static struct so_map *
+alloc_link_map(path, sodp, parent, addr, dp)
+ char *path;
+ struct sod *sodp;
+ struct so_map *parent;
+ caddr_t addr;
+ struct _dynamic *dp;
{
- struct link_map *lmp;
- struct lm_private *lmpp;
+ struct so_map *smp;
+ struct somap_private *smpp;
- lmpp = (struct lm_private *)xmalloc(sizeof(struct lm_private));
- lmp = (struct link_map *)xmalloc(sizeof(struct link_map));
- lmp->lm_next = NULL;
- *link_map_tail = lmp;
- link_map_tail = &lmp->lm_next;
+ smpp = (struct somap_private *)xmalloc(sizeof(struct somap_private));
+ smp = (struct so_map *)xmalloc(sizeof(struct so_map));
+ smp->som_next = NULL;
+ *link_map_tail = smp;
+ link_map_tail = &smp->som_next;
- lmp->lm_addr = addr;
- lmp->lm_name = name;
- lmp->lm_lop = lop;
- lmp->lm_ld = dp;
- lmp->lm_lpd = (caddr_t)lmpp;
+ smp->som_addr = addr;
+ smp->som_path = path;
+ smp->som_sod = sodp;
+ smp->som_dynamic = dp;
+ smp->som_spd = (caddr_t)smpp;
-/*XXX*/ if (addr == 0) main_map = lmp;
+/*XXX*/ if (addr == 0) main_map = smp;
- lmpp->lpd_parent = parent;
+ smpp->spd_refcount = 0;
+ smpp->spd_flags = 0;
+ smpp->spd_parent = parent;
#ifdef SUN_COMPAT
- lmpp->lpd_offset =
- (addr == 0 && dp->ld_version == LD_VERSION_SUN) ? PAGSIZ : 0;
+ smpp->spd_offset =
+ (addr==0 && dp && dp->d_version==LD_VERSION_SUN) ? PAGSIZ : 0;
#endif
+ return smp;
}
/*
* Map object identified by link object LOP which was found
* in link map LMP.
*/
-static void
-map_object(lop, lmp)
-struct link_object *lop;
-struct link_map *lmp;
+ static struct so_map *
+map_object(sodp, smp)
+ struct sod *sodp;
+ struct so_map *smp;
{
- struct link_dynamic *dp;
- char *path, *name = (char *)(lop->lo_name + LM_LDBASE(lmp));
+ struct _dynamic *dp;
+ char *path, *name = (char *)(sodp->sod_name + LM_LDBASE(smp));
int fd;
caddr_t addr;
struct exec hdr;
int usehints = 0;
+ struct so_map *p;
- if (lop->lo_library) {
+ if (sodp->sod_library) {
usehints = 1;
again:
- path = rtfindlib(name, lop->lo_major, lop->lo_minor, &usehints);
- if (path == NULL)
- fatal("Cannot find lib%s.so.%d.%d\n",
- name, lop->lo_major, lop->lo_minor);
+ path = rtfindlib(name, sodp->sod_major,
+ sodp->sod_minor, &usehints);
+ if (path == NULL) {
+ errno = ENOENT;
+ return NULL;
+ }
} else {
+ if (careful && *name != '/') {
+ errno = EACCES;
+ return NULL;
+ }
path = name;
}
- fd = open(path, O_RDONLY, 0);
- if (fd == -1) {
+ /* Check if already loaded */
+ for (p = link_map_head; p; p = p->som_next)
+ if (p->som_path && strcmp(p->som_path, path) == 0)
+ break;
+
+ if (p != NULL)
+ return p;
+
+ if ((fd = open(path, O_RDONLY, 0)) == -1) {
if (usehints) {
usehints = 0;
goto again;
}
- fatal("%s not found", path);
+ return NULL;
}
if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
- fatal("%s: Cannot read exec header", path);
+ (void)close(fd);
+ /*errno = x;*/
+ return NULL;
}
- if (N_BADMAG(hdr))
- fatal("%s: Incorrect format", path);
+ if (N_BADMAG(hdr)) {
+ (void)close(fd);
+ errno = EFTYPE;
+ return NULL;
+ }
if ((addr = mmap(0, hdr.a_text + hdr.a_data,
PROT_READ|PROT_EXEC,
- MAP_FILE|MAP_COPY, fd, 0)) == (caddr_t)-1)
- fatal("Cannot map %s text\n", path);
+ MAP_FILE|MAP_COPY, fd, 0)) == (caddr_t)-1) {
+ (void)close(fd);
+ return NULL;
+ }
if (mmap(addr + hdr.a_text, hdr.a_data,
- PROT_READ|PROT_WRITE,
+ PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_FILE|MAP_FIXED|MAP_COPY,
- fd, hdr.a_text) == (caddr_t)-1)
- fatal("Cannot map %s data", path);
+ fd, hdr.a_text) == (caddr_t)-1) {
+ (void)close(fd);
+ return NULL;
+ }
- close(fd);
+ (void)close(fd);
fd = -1;
#ifdef NEED_DEV_ZERO
@@ -399,213 +498,282 @@ again:
perror("/dev/zero");
#endif
if (hdr.a_bss && mmap(addr + hdr.a_text + hdr.a_data, hdr.a_bss,
- PROT_READ|PROT_WRITE,
+ PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_ANON|MAP_FIXED|MAP_COPY,
fd, hdr.a_text + hdr.a_data) == (caddr_t)-1)
- fatal("Cannot map %s bss", path);
+ return NULL;
#ifdef NEED_DEV_ZERO
close(fd);
#endif
/* Assume _DYNAMIC is the first data item */
- dp = (struct link_dynamic *)(addr+hdr.a_text);
+ dp = (struct _dynamic *)(addr+hdr.a_text);
/* Fixup __DYNAMIC structure */
- (long)dp->ld_un.ld_2 += (long)addr;
-
- alloc_link_map(path, lop, lmp, addr, dp);
+ (long)dp->d_un.d_sdt += (long)addr;
+ return alloc_link_map(path, sodp, smp, addr, dp);
}
-static void
-reloc_maps()
+static void inline
+check_text_reloc(r, smp, addr)
+struct relocation_info *r;
+struct so_map *smp;
+caddr_t addr;
{
- struct link_map *lmp;
-
- for (lmp = link_map_head; lmp; lmp = lmp->lm_next) {
-
- struct link_dynamic *dp = lmp->lm_ld;
- struct relocation_info *r = LM_REL(lmp);
- struct relocation_info *rend = r + LD_RELSZ(dp)/sizeof(*r);
-
- if (LD_PLTSZ(dp))
- md_fix_jmpslot(LM_PLT(lmp),
- (long)LM_PLT(lmp), (long)binder_entry);
-
- for (; r < rend; r++) {
- char *sym;
- caddr_t addr = lmp->lm_addr + r->r_address;
-
- check_text_reloc(r, lmp, addr);
+ char *sym;
- if (RELOC_EXTERN_P(r)) {
- struct link_map *src_map = NULL;
- struct nzlist *p, *np;
- long relocation = md_get_addend(r, addr);
+ if (addr >= LM_ETEXT(smp))
+ return;
- if (RELOC_LAZY_P(r))
- continue;
+ if (RELOC_EXTERN_P(r))
+ sym = LM_STRINGS(smp) +
+ LM_SYMBOL(smp, RELOC_SYMBOL(r))->nz_strx;
+ else
+ sym = "";
- p = LM_SYMBOL(lmp,RELOC_SYMBOL(r));
- if (p->nz_type == (N_SETV + N_EXT))
- src_map = lmp;
+ if (getenv("LD_WARN_NON_PURE_CODE") != NULL)
+ fprintf(stderr,
+ "ld.so: warning: non pure code in %s at %x (%s)\n",
+ smp->som_path, r->r_address, sym);
- sym = LM_STRINGS(lmp) + p->nz_strx;
+ if (smp->som_write == 0 &&
+ mprotect(smp->som_addr + LM_TXTADDR(smp),
+ LD_TEXTSZ(smp->som_dynamic),
+ PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
- np = lookup(sym, &src_map, 0/*XXX-jumpslots!*/);
- if (np == NULL)
- fatal("Undefined symbol \"%s\" in %s\n",
- sym, lmp->lm_name);
+ perror("mprotect"),
+ fatal("Cannot enable writes to %s:%s\n",
+ main_progname, smp->som_path);
+ }
- /*
- * Found symbol definition.
- * If it's in a link map, adjust value
- * according to the load address of that map.
- * Otherwise it's a run-time allocated common
- * whose value is already up-to-date.
- */
- relocation += np->nz_value;
- if (src_map)
- relocation += (long)src_map->lm_addr;
+ smp->som_write = 1;
+}
- if (RELOC_PCREL_P(r))
- relocation -= (long)lmp->lm_addr;
+static void
+reloc_map(smp)
+ struct so_map *smp;
+{
+ struct _dynamic *dp = smp->som_dynamic;
+ struct relocation_info *r = LM_REL(smp);
+ struct relocation_info *rend = r + LD_RELSZ(dp)/sizeof(*r);
+ long symbolbase = (long)LM_SYMBOL(smp, 0);
+ char *stringbase = LM_STRINGS(smp);
+ int symsize = LD_VERSION_NZLIST_P(dp->d_version) ?
+ sizeof(struct nzlist) :
+ sizeof(struct nlist);
+
+ if (LD_PLTSZ(dp))
+ md_fix_jmpslot(LM_PLT(smp),
+ (long)LM_PLT(smp), (long)binder_entry);
+
+ for (; r < rend; r++) {
+ char *sym;
+ caddr_t addr = smp->som_addr + r->r_address;
+
+ check_text_reloc(r, smp, addr);
+
+ if (RELOC_EXTERN_P(r)) {
+ struct so_map *src_map = NULL;
+ struct nzlist *p, *np;
+ long relocation = md_get_addend(r, addr);
+
+ if (RELOC_LAZY_P(r))
+ continue;
- if (RELOC_COPY_P(r) && src_map) {
-#if DEBUG
-xprintf("RELOCATE(%s) copy: from %s at %#x(%#x+%#x) to %s at %#x, reloc = %#x, size %d\n",
-lmp->lm_name, src_map->lm_name, src_map->lm_addr + np->nz_value,
-src_map->lm_addr, np->nz_value, sym, addr, relocation, np->nz_size);
-#endif
- (void)enter_rts(sym,
- (long)addr,
- N_DATA + N_EXT,
- src_map->lm_addr + np->nz_value,
- np->nz_size);
- continue;
- }
-#if DEBUG
-if (sym[2]=='_'&&(sym[3]=='C'||sym[3]=='D')&&sym[4]=='T')
-xprintf("RELOCATE(%s) external: %s at %#x, reloc = %#x in %s\n",
-lmp->lm_name, sym, addr, relocation, src_map?src_map->lm_name:"(NUL)");
-#endif
- md_relocate(r, relocation, addr, 0);
+ p = (struct nzlist *)
+ (symbolbase + symsize * RELOC_SYMBOL(r));
+
+ if (p->nz_type == (N_SETV + N_EXT))
+ src_map = smp;
+
+ sym = stringbase + p->nz_strx;
+
+ np = lookup(sym, &src_map, 0/*XXX-jumpslots!*/);
+ if (np == NULL)
+ fatal("Undefined symbol \"%s\" in %s:%s\n",
+ sym, main_progname, smp->som_path);
+
+ /*
+ * Found symbol definition.
+ * If it's in a link map, adjust value
+ * according to the load address of that map.
+ * Otherwise it's a run-time allocated common
+ * whose value is already up-to-date.
+ */
+ relocation += np->nz_value;
+ if (src_map)
+ relocation += (long)src_map->som_addr;
+
+ if (RELOC_PCREL_P(r))
+ relocation -= (long)smp->som_addr;
+
+ if (RELOC_COPY_P(r) && src_map) {
+ (void)enter_rts(sym,
+ (long)addr,
+ N_DATA + N_EXT,
+ src_map->som_addr + np->nz_value,
+ np->nz_size, src_map);
+ continue;
+ }
+ md_relocate(r, relocation, addr, 0);
- } else {
-#if DEBUG
-xprintf("RELOCATE(%s) internal at %#x, reloc = %#x\n", lmp->lm_name, addr, md_get_rt_segment_addend(r,addr));
-#endif
- md_relocate(r,
+ } else {
+ md_relocate(r,
#ifdef SUN_COMPAT
- md_get_rt_segment_addend(r, addr)
+ md_get_rt_segment_addend(r, addr)
#else
- md_get_addend(r, addr)
+ md_get_addend(r, addr)
#endif
- + (long)lmp->lm_addr, addr, 0);
- }
-
+ + (long)smp->som_addr, addr, 0);
}
- if (lmp->lm_rwt) {
- if (mprotect(lmp->lm_addr + LM_TXTADDR(lmp),
- LD_TEXTSZ(lmp->lm_ld),
+ }
+
+ if (smp->som_write) {
+ if (mprotect(smp->som_addr + LM_TXTADDR(smp),
+ LD_TEXTSZ(smp->som_dynamic),
PROT_READ|PROT_EXEC) == -1) {
- perror("mprotect"),
- fatal("Cannot disable writes to %s\n", lmp->lm_name);
- }
- lmp->lm_rwt = 0;
+ perror("mprotect"),
+ fatal("Cannot disable writes to %s:%s\n",
+ main_progname, smp->som_path);
}
-
+ smp->som_write = 0;
}
}
static void
-reloc_copy()
+reloc_copy(smp)
+ struct so_map *smp;
{
struct rt_symbol *rtsp;
for (rtsp = rt_symbol_head; rtsp; rtsp = rtsp->rt_next)
- if (rtsp->rt_sp->nz_type == N_DATA + N_EXT) {
-#ifdef DEBUG
-xprintf("reloc_copy: from %#x to %#x, size %d\n",
-rtsp->rt_srcaddr, rtsp->rt_sp->nz_value, rtsp->rt_sp->nz_size);
-#endif
+ if ((rtsp->rt_smp == NULL || rtsp->rt_smp == smp) &&
+ rtsp->rt_sp->nz_type == N_DATA + N_EXT) {
bcopy(rtsp->rt_srcaddr, (caddr_t)rtsp->rt_sp->nz_value,
rtsp->rt_sp->nz_size);
}
}
static void
-check_text_reloc(r, lmp, addr)
-struct relocation_info *r;
-struct link_map *lmp;
-caddr_t addr;
+init_map(smp, sym)
+ struct so_map *smp;
+ char *sym;
{
- char *sym;
+ struct so_map *src_map = smp;
+ struct nzlist *np;
- if (addr >= LM_ETEXT(lmp))
- return;
+ np = lookup(sym, &src_map, 1);
+ if (np)
+ (*(void (*)())(src_map->som_addr + np->nz_value))();
+}
- if (RELOC_EXTERN_P(r))
- sym = LM_STRINGS(lmp) +
- LM_SYMBOL(lmp, RELOC_SYMBOL(r))->nz_strx;
- else
- sym = "";
+/*
+ * Run-time common symbol table.
+ */
-#ifdef DEBUG
- fprintf(stderr, "ld.so: warning: non pure code in %s at %x (%s)\n",
- lmp->lm_name, r->r_address, sym);
-#endif
+#define RTC_TABSIZE 57
+static struct rt_symbol *rt_symtab[RTC_TABSIZE];
- if (lmp->lm_rwt == 0 &&
- mprotect(lmp->lm_addr + LM_TXTADDR(lmp),
- LD_TEXTSZ(lmp->lm_ld),
- PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
+/*
+ * Compute hash value for run-time symbol table
+ */
+ static int inline
+hash_string(key)
+ char *key;
+{
+ register char *cp;
+ register int k;
- perror("mprotect"),
- fatal("Cannot enable writes to %s\n", lmp->lm_name);
- }
+ cp = key;
+ k = 0;
+ while (*cp)
+ k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
- lmp->lm_rwt = 1;
+ return k;
}
-static void
-init_maps()
+/*
+ * Lookup KEY in the run-time common symbol table.
+ */
+
+ static inline struct rt_symbol *
+lookup_rts(key)
+ char *key;
{
- struct link_map *lmp, *src_map;
- struct nzlist *np;
- void (*func)();
+ register int hashval;
+ register struct rt_symbol *rtsp;
- for (lmp = link_map_head; lmp; lmp = lmp->lm_next) {
- src_map = lmp;
- np = lookup("___init", &src_map, 1);
-#if DEBUG
-if (np)
-xprintf("Calling __init in %s at %#x\n", src_map->lm_name, np->nz_value+src_map->lm_addr);
-#endif
- if (np) {
- func = (void (*)())(src_map->lm_addr + np->nz_value);
- (*func)();
- }
- }
+ /* Determine which bucket. */
+
+ hashval = hash_string(key) % RTC_TABSIZE;
+
+ /* Search the bucket. */
+
+ for (rtsp = rt_symtab[hashval]; rtsp; rtsp = rtsp->rt_link)
+ if (strcmp(key, rtsp->rt_sp->nz_name) == 0)
+ return rtsp;
+
+ return NULL;
}
+ static struct rt_symbol *
+enter_rts(name, value, type, srcaddr, size, smp)
+ char *name;
+ long value;
+ int type;
+ caddr_t srcaddr;
+ long size;
+ struct so_map *smp;
+{
+ register int hashval;
+ register struct rt_symbol *rtsp, **rpp;
+
+ /* Determine which bucket */
+ hashval = hash_string(name) % RTC_TABSIZE;
+
+ /* Find end of bucket */
+ for (rpp = &rt_symtab[hashval]; *rpp; rpp = &(*rpp)->rt_link)
+ ;
+
+ /* Allocate new common symbol */
+ rtsp = (struct rt_symbol *)malloc(sizeof(struct rt_symbol));
+ rtsp->rt_sp = (struct nzlist *)malloc(sizeof(struct nzlist));
+ rtsp->rt_sp->nz_name = strdup(name);
+ rtsp->rt_sp->nz_value = value;
+ rtsp->rt_sp->nz_type = type;
+ rtsp->rt_sp->nz_size = size;
+ rtsp->rt_srcaddr = srcaddr;
+ rtsp->rt_smp = smp;
+ rtsp->rt_link = NULL;
+
+ /* Link onto linear list as well */
+ rtsp->rt_next = rt_symbol_head;
+ rt_symbol_head = rtsp;
+
+ *rpp = rtsp;
+
+ return rtsp;
+}
+
+
/*
* Lookup NAME in the link maps. The link map producing a definition
* is returned in SRC_MAP. If SRC_MAP is not NULL on entry the search is
* confined to that map. If STRONG is set, the symbol returned must
* have a proper type (used by binder()).
*/
-static struct nzlist *
+ static struct nzlist *
lookup(name, src_map, strong)
-char *name;
-struct link_map **src_map; /* IN/OUT */
-int strong;
+ char *name;
+ struct so_map **src_map; /* IN/OUT */
+ int strong;
{
long common_size = 0;
- struct link_map *lmp;
+ struct so_map *smp;
struct rt_symbol *rtsp;
if ((rtsp = lookup_rts(name)) != NULL)
@@ -614,14 +782,23 @@ int strong;
/*
* Search all maps for a definition of NAME
*/
- for (lmp = link_map_head; lmp; lmp = lmp->lm_next) {
- int buckets = LD_BUCKETS(lmp->lm_ld);
+ for (smp = link_map_head; smp; smp = smp->som_next) {
+ int buckets = LD_BUCKETS(smp->som_dynamic);
long hashval = 0;
struct rrs_hash *hp;
char *cp;
struct nzlist *np;
- if (*src_map && lmp != *src_map)
+ /* Some local caching */
+ long symbolbase;
+ struct rrs_hash *hashbase;
+ char *stringbase;
+ int symsize;
+
+ if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
+ continue;
+
+ if (*src_map && smp != *src_map)
continue;
/*
@@ -632,20 +809,27 @@ int strong;
hashval = (hashval & 0x7fffffff) % buckets;
- hp = LM_HASH(lmp) + hashval;
+ hashbase = LM_HASH(smp);
+ hp = hashbase + hashval;
if (hp->rh_symbolnum == -1)
/* Nothing in this bucket */
continue;
+ symbolbase = (long)LM_SYMBOL(smp, 0);
+ stringbase = LM_STRINGS(smp);
+ symsize = LD_VERSION_NZLIST_P(smp->som_dynamic->d_version)?
+ sizeof(struct nzlist) :
+ sizeof(struct nlist);
while (hp) {
- np = LM_SYMBOL(lmp, hp->rh_symbolnum);
- cp = LM_STRINGS(lmp) + np->nz_strx;
+ np = (struct nzlist *)
+ (symbolbase + hp->rh_symbolnum * symsize);
+ cp = stringbase + np->nz_strx;
if (strcmp(cp, name) == 0)
break;
if (hp->rh_next == 0)
hp = NULL;
else
- hp = LM_HASH(lmp) + hp->rh_next;
+ hp = hashbase + hp->rh_next;
}
if (hp == NULL)
/* Nothing in this bucket */
@@ -660,7 +844,7 @@ int strong;
continue;
if (np->nz_type == N_UNDF+N_EXT && np->nz_value != 0) {
- if (np->nz_other == RRS_FUNC) {
+ if (np->nz_other == AUX_FUNC) {
/* It's a weak function definition */
if (strong)
continue;
@@ -672,7 +856,7 @@ int strong;
}
}
- *src_map = lmp;
+ *src_map = smp;
return np;
}
@@ -684,7 +868,7 @@ int strong;
* It's a common, enter into run-time common symbol table.
*/
rtsp = enter_rts(name, (long)calloc(1, common_size),
- N_UNDF + N_EXT, 0, common_size);
+ N_UNDF + N_EXT, 0, common_size, NULL);
#if DEBUG
xprintf("Allocating common: %s size %d at %#x\n", name, common_size, rtsp->rt_sp->nz_value);
@@ -698,11 +882,11 @@ xprintf("Allocating common: %s size %d at %#x\n", name, common_size, rtsp->rt_sp
* This routine is called from the jumptable to resolve
* procedure calls to shared objects.
*/
-long
+ long
binder(jsp)
-jmpslot_t *jsp;
+ jmpslot_t *jsp;
{
- struct link_map *lmp, *src_map = NULL;
+ struct so_map *smp, *src_map = NULL;
long addr;
char *sym;
struct nzlist *np;
@@ -711,133 +895,47 @@ jmpslot_t *jsp;
/*
* Find the PLT map that contains JSP.
*/
- for (lmp = link_map_head; lmp; lmp = lmp->lm_next) {
- if (LM_PLT(lmp) < jsp &&
- jsp < LM_PLT(lmp) + LD_PLTSZ(lmp->lm_ld)/sizeof(*jsp))
+ for (smp = link_map_head; smp; smp = smp->som_next) {
+ if (LM_PLT(smp) < jsp &&
+ jsp < LM_PLT(smp) + LD_PLTSZ(smp->som_dynamic)/sizeof(*jsp))
break;
}
- if (lmp == NULL)
+ if (smp == NULL)
fatal("Call to binder from unknown location: %#x\n", jsp);
index = jsp->reloc_index & JMPSLOT_RELOC_MASK;
/* Get the local symbol this jmpslot refers to */
- sym = LM_STRINGS(lmp) +
- LM_SYMBOL(lmp,RELOC_SYMBOL(&LM_REL(lmp)[index]))->nz_strx;
+ sym = LM_STRINGS(smp) +
+ LM_SYMBOL(smp,RELOC_SYMBOL(&LM_REL(smp)[index]))->nz_strx;
np = lookup(sym, &src_map, 1);
if (np == NULL)
- fatal("Undefined symbol \"%s\" called from %s at %#x", sym,
- lmp->lm_name, jsp);
+ fatal("Undefined symbol \"%s\" called from %s:%s at %#x",
+ sym, main_progname, smp->som_path, jsp);
/* Fixup jmpslot so future calls transfer directly to target */
addr = np->nz_value;
if (src_map)
- addr += (long)src_map->lm_addr;
+ addr += (long)src_map->som_addr;
md_fix_jmpslot(jsp, (long)jsp, addr);
#if DEBUG
-xprintf(" BINDER: %s located at = %#x in %s\n", sym, addr, src_map->lm_name);
+xprintf(" BINDER: %s located at = %#x in %s\n", sym, addr, src_map->som_path);
#endif
return addr;
}
-/*
- * Run-time common symbol table.
- */
-
-#define RTC_TABSIZE 57
-static struct rt_symbol *rt_symtab[RTC_TABSIZE];
-
-/*
- * Compute hash value for run-time symbol table
- */
-static int
-hash_string(key)
- char *key;
-{
- register char *cp;
- register int k;
-
- cp = key;
- k = 0;
- while (*cp)
- k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
-
- return k;
-}
-
-/*
- * Lookup KEY in the run-time common symbol table.
- */
-
-static struct rt_symbol *
-lookup_rts(key)
- char *key;
-{
- register int hashval;
- register struct rt_symbol *rtsp;
-
- /* Determine which bucket. */
-
- hashval = hash_string(key) % RTC_TABSIZE;
-
- /* Search the bucket. */
-
- for (rtsp = rt_symtab[hashval]; rtsp; rtsp = rtsp->rt_link)
- if (strcmp(key, rtsp->rt_sp->nz_name) == 0)
- return rtsp;
-
- return NULL;
-}
-
-static struct rt_symbol *
-enter_rts(name, value, type, srcaddr, size)
- char *name;
- long value;
- int type;
- caddr_t srcaddr;
- long size;
-{
- register int hashval;
- register struct rt_symbol *rtsp, **rpp;
-
- /* Determine which bucket */
- hashval = hash_string(name) % RTC_TABSIZE;
-
- /* Find end of bucket */
- for (rpp = &rt_symtab[hashval]; *rpp; rpp = &(*rpp)->rt_link)
- ;
-
- /* Allocate new common symbol */
- rtsp = (struct rt_symbol *)malloc(sizeof(struct rt_symbol));
- rtsp->rt_sp = (struct nzlist *)malloc(sizeof(struct nzlist));
- rtsp->rt_sp->nz_name = strdup(name);
- rtsp->rt_sp->nz_value = value;
- rtsp->rt_sp->nz_type = type;
- rtsp->rt_sp->nz_size = size;
- rtsp->rt_srcaddr = srcaddr;
- rtsp->rt_link = NULL;
-
- /* Link onto linear list as well */
- rtsp->rt_next = rt_symbol_head;
- rt_symbol_head = rtsp;
-
- *rpp = rtsp;
-
- return rtsp;
-}
-
static struct hints_header *hheader;
static struct hints_bucket *hbuckets;
static char *hstrtab;
#define HINTS_VALID (hheader != NULL && hheader != (struct hints_header *)-1)
-static void
+ static void
maphints()
{
caddr_t addr;
@@ -886,10 +984,10 @@ maphints()
hstrtab = (char *)(addr + hheader->hh_strtab);
}
-int
+ int
hinthash(cp, vmajor, vminor)
-char *cp;
-int vmajor, vminor;
+ char *cp;
+ int vmajor, vminor;
{
int k = 0;
@@ -905,11 +1003,11 @@ int vmajor, vminor;
#undef major
#undef minor
-static char *
+ static char *
findhint(name, major, minor, preferred_path)
-char *name;
-int major, minor;
-char *preferred_path;
+ char *name;
+ int major, minor;
+ char *preferred_path;
{
struct hints_bucket *bp;
@@ -949,11 +1047,11 @@ char *preferred_path;
return NULL;
}
-static char *
+ static char *
rtfindlib(name, major, minor, usehints)
-char *name;
-int major, minor;
-int *usehints;
+ char *name;
+ int major, minor;
+ int *usehints;
{
char *hint;
char *cp, *ld_path = getenv("LD_LIBRARY_PATH");
@@ -988,29 +1086,131 @@ int *usehints;
return (char *)findshlib(name, &major, &minor, 0);
}
-static int
+static struct somap_private dlmap_private = {
+ 0,
+ (struct so_map *)0,
+ 0,
+#ifdef SUN_COMPAT
+ 0,
+#endif
+};
+
+static struct so_map dlmap = {
+ (caddr_t)0,
+ "internal",
+ (struct so_map *)0,
+ (struct sod *)0,
+ (caddr_t)0,
+ (u_int)0,
+ (struct _dynamic *)0,
+ (caddr_t)&dlmap_private
+};
+static int dlerrno;
+
+ static void *
dlopen(name, mode)
-char *name;
-int mode;
+ char *name;
+ int mode;
{
- xprintf("dlopen(%s, %x)\n", name, mode);
- return -1;
+ struct sod *sodp;
+ struct so_map *smp;
+
+ /*
+ * A NULL argument returns the current set of mapped objects.
+ */
+ if (name == NULL)
+ return link_map_head;
+
+ if ((sodp = (struct sod *)malloc(sizeof(struct sod))) == NULL) {
+ dlerrno = ENOMEM;
+ return NULL;
+ }
+
+ sodp->sod_name = (long)name;
+ sodp->sod_library = 0;
+ sodp->sod_major = sodp->sod_minor = 0;
+
+ if ((smp = map_object(sodp, &dlmap)) == NULL) {
+#ifdef DEBUG
+xprintf("%s: %s\n", name, strerror(errno));
+#endif
+ dlerrno = errno;
+ return NULL;
+ }
+ if (LM_PRIVATE(smp)->spd_refcount++ == 0) {
+ LM_PRIVATE(smp)->spd_flags |= RTLD_DL;
+ reloc_map(smp);
+ reloc_copy(smp);
+ init_map(smp, ".init");
+ init_map(smp, "_init");
+ }
+
+ return smp;
}
-static int
+ static int
dlclose(fd)
-int fd;
+ void *fd;
{
- xprintf("dlclose(%d)\n", fd);
- return -1;
+ struct so_map *smp = (struct so_map *)fd;
+
+#ifdef DEBUG
+xprintf("dlclose(%s): refcount = %d\n", smp->som_path, LM_PRIVATE(smp)->spd_refcount);
+#endif
+ if (--LM_PRIVATE(smp)->spd_refcount != 0)
+ return 0;
+
+ /* Dismantle shared object map and descriptor */
+ init_map(smp, "_fini");
+#if 0
+ unmap_object(smp);
+ free(smp->som_sod);
+ free(smp);
+#endif
+
+ return 0;
}
-static int
+ static void *
dlsym(fd, sym)
-int fd;
-char *sym;
+ void *fd;
+ char *sym;
{
- xprintf("dlsym(%d, %s)\n", fd, sym);
+ struct so_map *smp = (struct so_map *)fd, *src_map = NULL;
+ struct nzlist *np;
+ long addr;
+
+ /*
+ * Restrict search to passed map if dlopen()ed.
+ */
+ if (LM_PRIVATE(smp)->spd_flags & RTLD_DL)
+ src_map = smp;
+
+ np = lookup(sym, &src_map, 1);
+ if (np == NULL)
+ return NULL;
+
+ /* Fixup jmpslot so future calls transfer directly to target */
+ addr = np->nz_value;
+ if (src_map)
+ addr += (long)src_map->som_addr;
+
+ return (void *)addr;
+}
+
+ static int
+dlctl(fd, cmd, arg)
+ void *fd, *arg;
+ int cmd;
+{
+ switch (cmd) {
+ case DL_GETERRNO:
+ *(int *)arg = dlerrno;
+ return 0;
+ default:
+ dlerrno = EOPNOTSUPP;
+ return -1;
+ }
return 0;
}
diff --git a/gnu/usr.bin/ld/shlib.c b/gnu/usr.bin/ld/shlib.c
index 0bfc373..38ec051 100644
--- a/gnu/usr.bin/ld/shlib.c
+++ b/gnu/usr.bin/ld/shlib.c
@@ -1,5 +1,33 @@
/*
- * $Id: shlib.c,v 1.6 1993/12/11 11:58:29 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 without 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: shlib.c,v 1.9 1994/01/29 02:03:15 jtc Exp $
*/
#include <sys/param.h>
@@ -25,14 +53,20 @@ char *strsep();
* Standard directories to search for files specified by -l.
*/
#ifndef STANDARD_SEARCH_DIRS
-#define STANDARD_SEARCH_DIRS "/usr/lib"
+#define STANDARD_SEARCH_DIRS "/usr/lib", "/usr/X386/lib", "/usr/local/lib"
#endif
+/*
+ * Actual vector of library search directories,
+ * including `-L'ed and LD_LIBARAY_PATH spec'd ones.
+ */
+char **search_dirs;
+int n_search_dirs;
+
char *standard_search_dirs[] = {
STANDARD_SEARCH_DIRS
};
-int n_search_dirs;
void
add_search_dir(name)
diff --git a/gnu/usr.bin/ld/sparc/md.c b/gnu/usr.bin/ld/sparc/md.c
index 3ae54e3..15281cc 100644
--- a/gnu/usr.bin/ld/sparc/md.c
+++ b/gnu/usr.bin/ld/sparc/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.6 1993/12/08 10:29:02 pk Exp $
+ * $Id: md.c,v 1.6 1993/12/11 12:02:10 jkh Exp $
*/
#include <sys/param.h>
@@ -109,6 +109,7 @@ int relocatable_output;
{
register unsigned long mask;
+#ifndef RTLD
if (relocatable_output) {
/*
* Non-PC relative relocations which are absolute or
@@ -129,6 +130,7 @@ int relocatable_output;
RELOC_ADD_EXTRA(r) -= pc_relocation;
return;
}
+#endif
relocation >>= RELOC_VALUE_RIGHTSHIFT(r);
@@ -167,33 +169,7 @@ int relocatable_output;
}
}
-/*
- * Initialize (output) exec header such that useful values are
- * obtained from subsequent N_*() macro evaluations.
- */
-void
-md_init_header(hp, magic, flags)
-struct exec *hp;
-int magic, flags;
-{
-#ifdef NetBSD
- N_SETMAGIC((*hp), magic, MID_MACHINE, flags);
-
- /* TEXT_START depends on the value of outheader.a_entry. */
- if (!(link_mode & SHAREABLE)) /*WAS: if (entry_symbol) */
- hp->a_entry = PAGSIZ;
-#else
- hp->a_magic = magic;
- hp->a_machtype = M_SPARC;
- hp->a_toolversion = 1;
- hp->a_dynamic = ((flags) & EX_DYNAMIC);
-
- /* SunOS 4.1 N_TXTADDR depends on the value of outheader.a_entry. */
- if (!(link_mode & SHAREABLE)) /*WAS: if (entry_symbol) */
- hp->a_entry = N_PAGSIZ(*hp);
-#endif
-}
-
+#ifndef RTLD
/*
* Machine dependent part of claim_rrs_reloc().
* On the Sparc the relocation offsets are stored in the r_addend member.
@@ -224,6 +200,7 @@ int type;
return 1;
}
+#endif
/*
* Set up a transfer from jmpslot at OFFSET (relative to the PLT table)
@@ -327,3 +304,46 @@ long *savep;
*(long *)where = TRAP;
}
+#ifndef RTLD
+/*
+ * Initialize (output) exec header such that useful values are
+ * obtained from subsequent N_*() macro evaluations.
+ */
+void
+md_init_header(hp, magic, flags)
+struct exec *hp;
+int magic, flags;
+{
+#ifdef NetBSD
+ N_SETMAGIC((*hp), magic, MID_MACHINE, flags);
+
+ /* TEXT_START depends on the value of outheader.a_entry. */
+ if (!(link_mode & SHAREABLE)) /*WAS: if (entry_symbol) */
+ hp->a_entry = PAGSIZ;
+#else
+ hp->a_magic = magic;
+ hp->a_machtype = M_SPARC;
+ hp->a_toolversion = 1;
+ hp->a_dynamic = ((flags) & EX_DYNAMIC);
+
+ /* SunOS 4.1 N_TXTADDR depends on the value of outheader.a_entry. */
+ if (!(link_mode & SHAREABLE)) /*WAS: if (entry_symbol) */
+ hp->a_entry = N_PAGSIZ(*hp);
+#endif
+}
+
+/*
+ * Check for acceptable foreign machine Ids
+ */
+int
+md_midcompat(hp)
+struct exec *hp;
+{
+#ifdef NetBSD
+#define SUN_M_SPARC 3
+ return (((md_swap_long(hp->a_midmag)&0x00ff0000) >> 16) == SUN_M_SPARC);
+#else
+ return hp->a_machtype == M_SPARC;
+#endif
+}
+#endif /* RTLD */
diff --git a/gnu/usr.bin/ld/sparc/md.h b/gnu/usr.bin/ld/sparc/md.h
index c3e9064..3545d97 100644
--- a/gnu/usr.bin/ld/sparc/md.h
+++ b/gnu/usr.bin/ld/sparc/md.h
@@ -14,7 +14,7 @@
* 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
+ * derived from this software without 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
@@ -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.3 1993/11/22 19:05:31 jkh Exp $
+ * $Id: md.h,v 1.5 1993/12/02 01:03:47 jkh Exp $
*/
/*
@@ -44,6 +44,13 @@
MID_MACHINE, N_GETFLAG(ex)|(f))
#define N_IS_DYNAMIC(ex) ((N_GETFLAG(ex) & EX_DYNAMIC))
+/*
+ * Should be handled by a.out.h ?
+ */
+#define N_ADJUST(ex) (((ex).a_entry < PAGSIZ) ? -PAGSIZ : 0)
+#define TEXT_START(ex) (N_TXTADDR(ex) + N_ADJUST(ex))
+#define DATA_START(ex) (N_DATADDR(ex) + N_ADJUST(ex))
+
#else
/* Get the SunOS a.out and relocation nomenclature */
@@ -60,6 +67,10 @@
#define r_symbolnum r_index
#endif /* NetBSD */
+#define N_BADMID(ex) \
+ (N_GETMID(ex) != 0 && N_GETMID(ex) != MID_MACHINE && \
+ !md_midcompat(&(ex)))
+
/* Sparc (Sun 4) macros */
#define RELOC_ADDRESS(r) ((r)->r_address)
#define RELOC_EXTERN_P(r) ((r)->r_extern)
@@ -139,16 +150,16 @@ typedef struct jmpslot {
#define md_swapout_zsymbols(s,n)
#define md_swapin_reloc(r,n)
#define md_swapout_reloc(r,n)
-#define md_swapin_link_dynamic(l)
-#define md_swapout_link_dynamic(l)
-#define md_swapin_link_dynamic_2(l)
-#define md_swapout_link_dynamic_2(l)
-#define md_swapin_ld_debug(d)
-#define md_swapout_ld_debug(d)
+#define md_swapin__dynamic(l)
+#define md_swapout__dynamic(l)
+#define md_swapin_section_dispatch_table(l)
+#define md_swapout_section_dispatch_table(l)
+#define md_swapin_so_debug(d)
+#define md_swapout_so_debug(d)
#define md_swapin_rrs_hash(f,n)
#define md_swapout_rrs_hash(f,n)
-#define md_swapin_link_object(l,n)
-#define md_swapout_link_object(l,n)
+#define md_swapin_sod(l,n)
+#define md_swapout_sod(l,n)
#define md_swapout_jmpslot(j,n)
#define md_swapout_got(g,n)
#define md_swapin_ranlib_hdr(h,n)
@@ -168,23 +179,23 @@ void md_swapin_reloc __P((struct relocation_info *, int));
void md_swapout_reloc __P((struct relocation_info *, int));
void md_swapout_jmpslot __P((jmpslot_t *, int));
-#define md_swapin_symbols(s,n) swap_symbols(s,n)
-#define md_swapout_symbols(s,n) swap_symbols(s,n)
-#define md_swapin_zsymbols(s,n) swap_zsymbols(s,n)
-#define md_swapout_zsymbols(s,n) swap_zsymbols(s,n)
-#define md_swapin_link_dynamic(l) swap_link_dynamic(l)
-#define md_swapout_link_dynamic(l) swap_link_dynamic(l)
-#define md_swapin_link_dynamic_2(l) swap_link_dynamic_2(l)
-#define md_swapout_link_dynamic_2(l) swap_link_dynamic_2(l)
-#define md_swapin_ld_debug(d) swap_ld_debug(d)
-#define md_swapout_ld_debug(d) swap_ld_debug(d)
-#define md_swapin_rrs_hash(f,n) swap_rrs_hash(f,n)
-#define md_swapout_rrs_hash(f,n) swap_rrs_hash(f,n)
-#define md_swapin_link_object(l,n) swapin_link_object(l,n)
-#define md_swapout_link_object(l,n) swapout_link_object(l,n)
-#define md_swapout_got(g,n) swap_longs((long*)(g),n)
-#define md_swapin_ranlib_hdr(h,n) swap_ranlib_hdr(h,n)
-#define md_swapout_ranlib_hdr(h,n) swap_ranlib_hdr(h,n)
+#define md_swapin_symbols(s,n) swap_symbols(s,n)
+#define md_swapout_symbols(s,n) swap_symbols(s,n)
+#define md_swapin_zsymbols(s,n) swap_zsymbols(s,n)
+#define md_swapout_zsymbols(s,n) swap_zsymbols(s,n)
+#define md_swapin__dynamic(l) swap__dynamic(l)
+#define md_swapout__dynamic(l) swap__dynamic(l)
+#define md_swapin_section_dispatch_table(l) swap_section_dispatch_table(l)
+#define md_swapout_section_dispatch_table(l) swap_section_dispatch_table(l)
+#define md_swapin_so_debug(d) swap_so_debug(d)
+#define md_swapout_so_debug(d) swap_so_debug(d)
+#define md_swapin_rrs_hash(f,n) swap_rrs_hash(f,n)
+#define md_swapout_rrs_hash(f,n) swap_rrs_hash(f,n)
+#define md_swapin_sod(l,n) swapin_sod(l,n)
+#define md_swapout_sod(l,n) swapout_sod(l,n)
+#define md_swapout_got(g,n) swap_longs((long*)(g),n)
+#define md_swapin_ranlib_hdr(h,n) swap_ranlib_hdr(h,n)
+#define md_swapout_ranlib_hdr(h,n) swap_ranlib_hdr(h,n)
#define md_swap_short(x) ( (((x) >> 8) & 0xff) | (((x) & 0xff) << 8) )
diff --git a/gnu/usr.bin/ld/sparc/mdprologue.S b/gnu/usr.bin/ld/sparc/mdprologue.S
index 8ad60b0..0d006d0 100644
--- a/gnu/usr.bin/ld/sparc/mdprologue.S
+++ b/gnu/usr.bin/ld/sparc/mdprologue.S
@@ -14,7 +14,7 @@
* 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
+ * derived from this software without 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
@@ -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.1 1993/10/16 21:54:36 pk Exp $
+ * $Id: mdprologue.S,v 1.2 1993/11/09 04:19:36 paul Exp $
*/
/*
diff --git a/gnu/usr.bin/ld/symbol.c b/gnu/usr.bin/ld/symbol.c
index d789a3a..af182a9 100644
--- a/gnu/usr.bin/ld/symbol.c
+++ b/gnu/usr.bin/ld/symbol.c
@@ -1,5 +1,5 @@
/*
- * $Id: symbol.c,v 1.2 1993/11/09 04:19:04 paul Exp $ - symbol table routines
+ * $Id: symbol.c,v 1.3 1993/11/22 19:04:45 jkh Exp $ - symbol table routines
*/
/* Create the symbol table entries for `etext', `edata' and `end'. */
@@ -15,6 +15,15 @@
#include "ld.h"
+symbol *symtab[SYMTABSIZE]; /* The symbol table. */
+int num_hash_tab_syms; /* Number of symbols in symbol hash table. */
+
+symbol *edata_symbol; /* the symbol _edata */
+symbol *etext_symbol; /* the symbol _etext */
+symbol *end_symbol; /* the symbol _end */
+symbol *got_symbol; /* the symbol __GLOBAL_OFFSET_TABLE_ */
+symbol *dynamic_symbol; /* the symbol __DYNAMIC */
+
void
symtab_init (relocatable_output)
int relocatable_output;
@@ -22,36 +31,40 @@ int relocatable_output;
/*
* Put linker reserved symbols into symbol table.
*/
+#ifndef nounderscore
+#define ETEXT_SYM "_etext"
+#define EDATA_SYM "_edata"
+#define END_SYM "_end"
+#define DYN_SYM "__DYNAMIC"
+#define GOT_SYM "__GLOBAL_OFFSET_TABLE_"
+#else
+#define ETEXT_SYM "etext"
+#define EDATA_SYM "edata"
+#define END_SYM "end"
+#define DYN_SYM "_DYNAMIC"
+#define GOT_SYM "_GLOBAL_OFFSET_TABLE_"
+#endif
- dynamic_symbol = getsym ("__DYNAMIC");
+ dynamic_symbol = getsym (DYN_SYM);
dynamic_symbol->defined = relocatable_output?N_UNDF:(N_DATA | N_EXT);
- dynamic_symbol->referenced = 0;
- dynamic_symbol->value = 0;
- got_symbol = getsym ("__GLOBAL_OFFSET_TABLE_");
+ got_symbol = getsym (GOT_SYM);
got_symbol->defined = N_DATA | N_EXT;
- got_symbol->referenced = 0;
- got_symbol->value = 0;
if (relocatable_output)
return;
-#ifndef nounderscore
- edata_symbol = getsym ("_edata");
- etext_symbol = getsym ("_etext");
- end_symbol = getsym ("_end");
-#else
- edata_symbol = getsym ("edata");
- etext_symbol = getsym ("etext");
- end_symbol = getsym ("end");
-#endif
- edata_symbol->defined = N_DATA | N_EXT;
+ etext_symbol = getsym (ETEXT_SYM);
+ edata_symbol = getsym (EDATA_SYM);
+ end_symbol = getsym (END_SYM);
+
etext_symbol->defined = N_TEXT | N_EXT;
+ edata_symbol->defined = N_DATA | N_EXT;
end_symbol->defined = N_BSS | N_EXT;
- edata_symbol->referenced = 1;
- etext_symbol->referenced = 1;
- end_symbol->referenced = 1;
+ etext_symbol->flags |= GS_REFERENCED;
+ edata_symbol->flags |= GS_REFERENCED;
+ end_symbol->flags |= GS_REFERENCED;
}
/* Compute the hash code for symbol name KEY. */
@@ -82,7 +95,7 @@ getsym(key)
register symbol *bp;
/* Determine the proper bucket. */
- hashval = hash_string (key) % TABSIZE;
+ hashval = hash_string (key) % SYMTABSIZE;
/* Search the bucket. */
for (bp = symtab[hashval]; bp; bp = bp->link)
@@ -91,17 +104,15 @@ getsym(key)
/* Nothing was found; create a new symbol table entry. */
bp = (symbol *) xmalloc (sizeof (symbol));
- bp->refs = 0;
bp->name = (char *) xmalloc (strlen (key) + 1);
strcpy (bp->name, key);
+ bp->refs = 0;
bp->defined = 0;
- bp->referenced = 0;
- bp->trace = 0;
bp->value = 0;
- bp->max_common_size = 0;
+ bp->common_size = 0;
bp->warning = 0;
bp->undef_refs = 0;
- bp->multiply_defined = 0;
+ bp->mult_defs = 0;
bp->alias = 0;
bp->setv_count = 0;
bp->symbolnum = 0;
@@ -114,10 +125,7 @@ getsym(key)
bp->def_nlist = 0;
bp->jmpslot_offset = -1;
bp->gotslot_offset = -1;
- bp->jmpslot_claimed = 0;
- bp->gotslot_claimed = 0;
- bp->cpyreloc_reserved = 0;
- bp->cpyreloc_claimed = 0;
+ bp->flags = 0;
/* Add the entry to the bucket. */
bp->link = symtab[hashval];
@@ -139,7 +147,7 @@ getsym_soft (key)
/* Determine which bucket. */
- hashval = hash_string (key) % TABSIZE;
+ hashval = hash_string (key) % SYMTABSIZE;
/* Search the bucket. */
diff --git a/gnu/usr.bin/ld/warnings.c b/gnu/usr.bin/ld/warnings.c
index 210be24..d98516a 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/12/22 23:28:12 jkh Exp $
+ * $Id: warnings.c,v 1.5 1994/01/12 23:14:07 jkh Exp $
*/
#include <sys/param.h>
@@ -47,6 +47,10 @@ print_file_name (entry, outfile)
struct file_entry *entry;
FILE *outfile;
{
+ if (entry == NULL) {
+ fprintf (outfile, "NULL");
+ }
+
if (entry->superfile) {
print_file_name (entry->superfile, outfile);
fprintf (outfile, "(%s)", entry->filename);
@@ -65,7 +69,7 @@ get_file_name (entry)
char *result, *supfile;
if (entry == NULL) {
- return (xmalloc("NULL"));
+ return (char *)strdup("NULL");
}
if (entry->superfile) {
@@ -155,30 +159,24 @@ void
print_symbols(outfile)
FILE *outfile;
{
- register int i;
-
fprintf(outfile, "\nFiles:\n\n");
-
each_file(describe_file_sections, outfile);
fprintf(outfile, "\nGlobal symbols:\n\n");
-
- for (i = 0; i < TABSIZE; i++) {
- register symbol *sp;
- for (sp = symtab[i]; sp; sp = sp->link) {
- if (sp->defined == (N_UNDF|N_EXT))
- fprintf(outfile, " %s: common, length %#x\n",
- sp->name, sp->max_common_size);
- if (!sp->referenced)
- fprintf(outfile, " %s: unreferenced\n",
- sp->name);
- else if (!sp->defined)
- fprintf(outfile, " %s: undefined\n", sp->name);
- else
- fprintf(outfile, " %s: %#x, size %#x\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);
+ if (!(sp->flags & GS_REFERENCED))
+ fprintf(outfile, " %s: unreferenced\n", sp->name);
+ else if (sp->so_defined)
+ fprintf(outfile, " %s: sodefined\n", 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);
- }
- }
+ } END_EACH_SYMBOL;
each_file(list_file_locals, outfile);
}
@@ -190,7 +188,7 @@ describe_file_sections(entry, outfile)
{
fprintf(outfile, " ");
print_file_name(entry, outfile);
- if (entry->just_syms_flag || entry->is_dynamic)
+ if (entry->flags & (E_JUST_SYMS | E_DYNAMIC))
fprintf(outfile, " symbols only\n", 0);
else
fprintf(outfile, " text %x(%x), data %x(%x), bss %x(%x) hex\n",
@@ -602,7 +600,7 @@ do_file_warnings (entry, outfile)
read_entry_strings (desc, entry);
}
- if (! entry->is_dynamic) {
+ if (!(entry->flags & E_DYNAMIC)) {
/* Do text warnings based on a scan through the relocation info. */
do_relocation_warnings (entry, 0, outfile, nlist_bitvector);
@@ -618,7 +616,7 @@ do_file_warnings (entry, outfile)
for (i = 0; i < number_of_syms; i++) {
struct nlist *s;
- struct glosym *g;
+ symbol *g;
g = entry->symbols[i].symbol;
s = &entry->symbols[i].nzlist.nlist;
@@ -626,14 +624,14 @@ do_file_warnings (entry, outfile)
if (!(s->n_type & N_EXT))
continue;
- if (!g->referenced) {
+ if (!(g->flags & GS_REFERENCED)) {
#if 0
/* Check for undefined shobj symbols */
struct localsymbol *lsp;
register int type;
- for (lsp = g->dynrefs; lsp; lsp = lsp->next) {
- type = lsp->nlist.n_type;
+ for (lsp = g->sorefs; lsp; lsp = lsp->next) {
+ type = lsp->nzlist.nz_type;
if ((type & N_EXT) &&
type != (N_UNDF | N_EXT)) {
break;
@@ -651,7 +649,7 @@ do_file_warnings (entry, outfile)
dont_allow_symbol_name = 0;
- if (list_multiple_defs && g->multiply_defined) {
+ if (list_multiple_defs && g->mult_defs) {
errfmt = "Definition of symbol %s (multiply defined)";
switch (s->n_type) {
@@ -669,13 +667,13 @@ do_file_warnings (entry, outfile)
case N_SETT | N_EXT:
case N_SETD | N_EXT:
case N_SETB | N_EXT:
- if (g->multiply_defined == 2)
+ if (g->mult_defs == 2)
continue;
errfmt = "First set element definition of symbol %s (multiply defined)";
break;
default:
-printf("Multiple def: %s, type %#x\n", g->name, s->n_type);
+printf("multiply defined: %s, type %#x\n", g->name, s->n_type);
/* Don't print out multiple defs at references.*/
continue;
}
diff --git a/gnu/usr.bin/ld/xbits.c b/gnu/usr.bin/ld/xbits.c
index 4f85db1..6374beb 100644
--- a/gnu/usr.bin/ld/xbits.c
+++ b/gnu/usr.bin/ld/xbits.c
@@ -14,7 +14,7 @@
* 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
+ * derived from this software without 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
@@ -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: xbits.c,v 1.1 1993/10/16 21:52:37 pk Exp $
+ * $Id: xbits.c,v 1.2 1993/11/09 04:19:08 paul Exp $
*/
/*
@@ -96,60 +96,61 @@ int n;
}
void
-swap_link_dynamic(dp)
-struct link_dynamic *dp;
+swap__dynamic(dp)
+struct _dynamic *dp;
{
- dp->ld_version = md_swap_long(dp->ld_version);
- dp->ldd = (struct ld_debug *)md_swap_long((long)dp->ldd);
- dp->ld_un.ld_2 = (struct link_dynamic_2 *)md_swap_long((long)dp->ld_un.ld_2);
- dp->ld_entry = (struct ld_entry *)md_swap_long((long)dp->ld_entry);
+ dp->d_version = md_swap_long(dp->d_version);
+ dp->d_debug = (struct so_debug *)md_swap_long((long)dp->d_debug);
+ dp->d_un.d_sdt = (struct section_dispatch_table *)
+ md_swap_long((long)dp->d_un.d_sdt);
+ dp->d_entry = (struct ld_entry *)md_swap_long((long)dp->d_entry);
}
void
-swap_link_dynamic_2(ldp)
-struct link_dynamic_2 *ldp;
+swap_section_dispatch_table(sdp)
+struct section_dispatch_table *sdp;
{
- swap_longs((long *)ldp, sizeof(*ldp)/sizeof(long));
+ swap_longs((long *)sdp, sizeof(*sdp)/sizeof(long));
}
void
-swap_ld_debug(lddp)
-struct ld_debug *lddp;
+swap_so_debug(ddp)
+struct so_debug *ddp;
{
- swap_longs((long *)lddp, sizeof(*lddp)/sizeof(long));
+ swap_longs((long *)ddp, sizeof(*ddp)/sizeof(long));
}
void
-swapin_link_object(lop, n)
-struct link_object *lop;
+swapin_sod(sodp, n)
+struct sod *sodp;
int n;
{
unsigned long bits;
- for (; n; n--, lop++) {
- lop->lo_name = md_swap_long(lop->lo_name);
- lop->lo_major = md_swap_short(lop->lo_major);
- lop->lo_minor = md_swap_short(lop->lo_minor);
- lop->lo_next = md_swap_long(lop->lo_next);
- bits = ((unsigned long *)lop)[1];
- lop->lo_library = ((bits >> 24) & 1);
+ for (; n; n--, sodp++) {
+ sodp->sod_name = md_swap_long(sodp->sod_name);
+ sodp->sod_major = md_swap_short(sodp->sod_major);
+ sodp->sod_minor = md_swap_short(sodp->sod_minor);
+ sodp->sod_next = md_swap_long(sodp->sod_next);
+ bits = ((unsigned long *)sodp)[1];
+ sodp->sod_library = ((bits >> 24) & 1);
}
}
void
-swapout_link_object(lop, n)
-struct link_object *lop;
+swapout_sod(sodp, n)
+struct sod *sodp;
int n;
{
unsigned long bits;
- for (; n; n--, lop++) {
- lop->lo_name = md_swap_long(lop->lo_name);
- lop->lo_major = md_swap_short(lop->lo_major);
- lop->lo_minor = md_swap_short(lop->lo_minor);
- lop->lo_next = md_swap_long(lop->lo_next);
- bits = (unsigned long)(lop->lo_library) << 24;
- ((unsigned long *)lop)[1] = bits;
+ for (; n; n--, sodp++) {
+ sodp->sod_name = md_swap_long(sodp->sod_name);
+ sodp->sod_major = md_swap_short(sodp->sod_major);
+ sodp->sod_minor = md_swap_short(sodp->sod_minor);
+ sodp->sod_next = md_swap_long(sodp->sod_next);
+ bits = (unsigned long)(sodp->sod_library) << 24;
+ ((unsigned long *)sodp)[1] = bits;
}
}
diff --git a/libexec/rtld-aout/Makefile b/libexec/rtld-aout/Makefile
index 1a76c51..0fbf2b2 100644
--- a/libexec/rtld-aout/Makefile
+++ b/libexec/rtld-aout/Makefile
@@ -1,25 +1,25 @@
-# $Id: Makefile,v 1.7 1993/12/11 21:05:59 jkh Exp $
+# $Id: Makefile,v 1.8 1994/01/28 21:01:20 pk Exp $
PROG= ld.so
-SRCS= mdprologue.S sbrk.c rtld.c shlib.c etc.c md.c
+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) -O $(PICFLAG) -DRTLD
-LDFLAGS = -Bshareable -Bsymbolic -assert nosymbolic -Z
-LIBS = -lc_pic -lgcc_pic
+CFLAGS+=-I$(LDDIR) -I$(.CURDIR) -I$(LDDIR)/$(MACHINE) $(PICFLAG) -DRTLD
+LDFLAGS+=-Bshareable -Bsymbolic -assert nosymbolic
+ASFLAGS+=-k
+LDADD+= -lc_pic
BINDIR= /usr/libexec
-ASFLAGS = -k
-
-.PATH: $(LDDIR) $(LDDIR)/$(MACHINE)
.SUFFIXES: .S
+.PATH: $(LDDIR) $(LDDIR)/$(MACHINE)
+
$(PROG):
- $(LD) -o $(PROG) $(LDFLAGS) $(OBJS) $(LIBS) $(LDADD)
+ $(LD) -o $(PROG) $(LDFLAGS) $(OBJS) $(LDADD)
.S.o:
- $(CPP) $(.IMPSRC) | $(AS) $(ASFLAGS) -o $(.TARGET) -
+ ${CPP} ${.IMPSRC} | ${AS} ${ASFLAGS} -o ${.TARGET} -
.include <bsd.prog.mk>
diff --git a/libexec/rtld-aout/i386/md-static-funcs.c b/libexec/rtld-aout/i386/md-static-funcs.c
index 2cd0768..4741685 100644
--- a/libexec/rtld-aout/i386/md-static-funcs.c
+++ b/libexec/rtld-aout/i386/md-static-funcs.c
@@ -1,8 +1,10 @@
-
/*
+ * $Id: md-static-funcs.c,v 1.2 1993/12/08 10:14:44 pk Exp $
+ *
* Called by ld.so when onanating.
* This *must* be a static function, so it is not called through a jmpslot.
*/
+
static void
md_relocate_simple(r, relocation, addr)
struct relocation_info *r;
diff --git a/libexec/rtld-aout/i386/md.c b/libexec/rtld-aout/i386/md.c
index f78c6cc..311a5f6 100644
--- a/libexec/rtld-aout/i386/md.c
+++ b/libexec/rtld-aout/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.7 1994/01/03 18:35:35 davidg Exp $
+ * $Id: md.c,v 1.8 1994/01/19 15:00:37 davidg Exp $
*/
#include <sys/param.h>
@@ -41,8 +41,6 @@
#include "ld.h"
-int netzmagic = 0;
-
/*
* Get relocation addend corresponding to relocation record RP
* from address ADDR
@@ -90,29 +88,6 @@ unsigned char *addr;
}
/*
- * Initialize (output) exec header such that useful values are
- * obtained from subsequent N_*() macro evaluations.
- */
-void
-md_init_header(hp, magic, flags)
-struct exec *hp;
-int magic, flags;
-{
- if (!netzmagic && (magic == ZMAGIC)) {
- hp->a_midmag = magic;
- } else {
- if (netzmagic)
- N_SETMAGIC_NET((*hp), magic, MID_I386, flags);
- else
- N_SETMAGIC((*hp), magic, MID_I386, flags);
- }
-
- /* TEXT_START depends on the value of outheader.a_entry. */
- if (!(link_mode & SHAREABLE)) /*WAS: if (entry_symbol) */
- hp->a_entry = PAGSIZ;
-}
-
-/*
* Machine dependent part of claim_rrs_reloc().
* Set RRS relocation type.
*/
@@ -251,9 +226,45 @@ long *savep;
*(char *)where = TRAP;
}
-#ifdef NEED_SWAP
+#ifndef RTLD
+
+#ifdef FreeBSD
+int netzmagic;
+#endif
/*
+ * Initialize (output) exec header such that useful values are
+ * obtained from subsequent N_*() macro evaluations.
+ */
+void
+md_init_header(hp, magic, flags)
+struct exec *hp;
+int magic, flags;
+{
+#ifdef NetBSD
+ if (oldmagic || magic == QMAGIC)
+ hp->a_midmag = magic;
+ else
+ N_SETMAGIC((*hp), magic, MID_I386, flags);
+#endif
+#ifdef FreeBSD
+ if (oldmagic)
+ hp->a_midmag = magic;
+ else if (netzmagic)
+ N_SETMAGIC_NET((*hp), magic, MID_I386, flags);
+ else
+ N_SETMAGIC((*hp), magic, MID_I386, flags);
+#endif
+
+ /* TEXT_START depends on the value of outheader.a_entry. */
+ if (!(link_mode & SHAREABLE)) /*WAS: if (entry_symbol) */
+ hp->a_entry = PAGSIZ;
+}
+#endif /* RTLD */
+
+
+#ifdef NEED_SWAP
+/*
* Byte swap routines for cross-linking.
*/
diff --git a/libexec/rtld-aout/i386/md.h b/libexec/rtld-aout/i386/md.h
index 7286a74..bbb28f2 100644
--- a/libexec/rtld-aout/i386/md.h
+++ b/libexec/rtld-aout/i386/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.7 1994/01/03 18:35:36 davidg Exp $
+ * $Id: md.h,v 1.8 1994/01/19 15:00:37 davidg Exp $
*/
@@ -45,17 +45,41 @@
#define PAGSIZ 4096
#endif
-#define N_SET_FLAG(ex,f) (netzmagic ? \
- N_SETMAGIC_NET(ex,N_GETMAGIC_NET(ex), MID_MACHINE, \
- N_GETFLAG_NET(ex)|(f)) : \
- N_GETMAGIC(ex) == ZMAGIC ? \
- N_SETMAGIC(ex,ZMAGIC,0,N_GETFLAG(ex)|(f)) : \
- N_SETMAGIC(ex,N_GETMAGIC(ex), MID_MACHINE, \
- N_GETFLAG(ex)|(f)))
-
-#define N_IS_DYNAMIC(ex) ((N_GETMAGIC_NET(ex) == ZMAGIC) ? \
- ((N_GETFLAG_NET(ex) & EX_DYNAMIC)) : \
- ((N_GETFLAG(ex) & EX_DYNAMIC)))
+#if defined(NetBSD) || defined(CROSS_LINKER)
+
+#define N_SET_FLAG(ex,f) (oldmagic || N_GETMAGIC(ex)==QMAGIC ? (0) : \
+ N_SETMAGIC(ex, \
+ N_GETMAGIC(ex), \
+ MID_MACHINE, \
+ N_GETFLAG(ex)|(f)))
+
+#define N_IS_DYNAMIC(ex) ((N_GETFLAG(ex) & EX_DYNAMIC))
+
+#define N_BADMID(ex) \
+ (N_GETMID(ex) != 0 && N_GETMID(ex) != MID_MACHINE)
+
+#endif
+
+/*
+ * FreeBSD does it differently
+ */
+#ifdef FreeBSD
+#define N_SET_FLAG(ex,f) (oldmagic ? (0) : \
+ (netzmagic == 0 ? \
+ N_SETMAGIC(ex, \
+ N_GETMAGIC(ex), \
+ MID_MACHINE, \
+ N_GETFLAG(ex)|(f)) : \
+ N_SETMAGIC_NET(ex, \
+ N_GETMAGIC_NET(ex), \
+ MID_MACHINE, \
+ N_GETFLAG_NET(ex)|(f)) ))
+
+#define N_IS_DYNAMIC(ex) ((N_GETMAGIC_NET(ex) == ZMAGIC) ? \
+ ((N_GETFLAG_NET(ex) & EX_DYNAMIC)) : \
+ ((N_GETFLAG(ex) & EX_DYNAMIC) ))
+#define N_BADMID(ex) 0
+#endif
/*
* Should be handled by a.out.h ?
@@ -101,16 +125,16 @@ typedef struct jmpslot {
#define md_swapout_zsymbols(s,n)
#define md_swapin_reloc(r,n)
#define md_swapout_reloc(r,n)
-#define md_swapin_link_dynamic(l)
-#define md_swapout_link_dynamic(l)
-#define md_swapin_link_dynamic_2(l)
-#define md_swapout_link_dynamic_2(l)
-#define md_swapin_ld_debug(d)
-#define md_swapout_ld_debug(d)
+#define md_swapin__dynamic(l)
+#define md_swapout__dynamic(l)
+#define md_swapin_section_dispatch_table(l)
+#define md_swapout_section_dispatch_table(l)
+#define md_swapin_so_debug(d)
+#define md_swapout_so_debug(d)
#define md_swapin_rrs_hash(f,n)
#define md_swapout_rrs_hash(f,n)
-#define md_swapin_link_object(l,n)
-#define md_swapout_link_object(l,n)
+#define md_swapin_sod(l,n)
+#define md_swapout_sod(l,n)
#define md_swapout_jmpslot(j,n)
#define md_swapout_got(g,n)
#define md_swapin_ranlib_hdr(h,n)
@@ -130,23 +154,23 @@ void md_swapin_reloc __P((struct relocation_info *, int));
void md_swapout_reloc __P((struct relocation_info *, int));
void md_swapout_jmpslot __P((jmpslot_t *, int));
-#define md_swapin_symbols(s,n) swap_symbols(s,n)
-#define md_swapout_symbols(s,n) swap_symbols(s,n)
-#define md_swapin_zsymbols(s,n) swap_zsymbols(s,n)
-#define md_swapout_zsymbols(s,n) swap_zsymbols(s,n)
-#define md_swapin_link_dynamic(l) swap_link_dynamic(l)
-#define md_swapout_link_dynamic(l) swap_link_dynamic(l)
-#define md_swapin_link_dynamic_2(l) swap_link_dynamic_2(l)
-#define md_swapout_link_dynamic_2(l) swap_link_dynamic_2(l)
-#define md_swapin_ld_debug(d) swap_ld_debug(d)
-#define md_swapout_ld_debug(d) swap_ld_debug(d)
-#define md_swapin_rrs_hash(f,n) swap_rrs_hash(f,n)
-#define md_swapout_rrs_hash(f,n) swap_rrs_hash(f,n)
-#define md_swapin_link_object(l,n) swapin_link_object(l,n)
-#define md_swapout_link_object(l,n) swapout_link_object(l,n)
-#define md_swapout_got(g,n) swap_longs((long*)(g),n)
-#define md_swapin_ranlib_hdr(h,n) swap_ranlib_hdr(h,n)
-#define md_swapout_ranlib_hdr(h,n) swap_ranlib_hdr(h,n)
+#define md_swapin_symbols(s,n) swap_symbols(s,n)
+#define md_swapout_symbols(s,n) swap_symbols(s,n)
+#define md_swapin_zsymbols(s,n) swap_zsymbols(s,n)
+#define md_swapout_zsymbols(s,n) swap_zsymbols(s,n)
+#define md_swapin__dynamic(l) swap__dynamic(l)
+#define md_swapout__dynamic(l) swap__dynamic(l)
+#define md_swapin_section_dispatch_table(l) swap_section_dispatch_table(l)
+#define md_swapout_section_dispatch_table(l) swap_section_dispatch_table(l)
+#define md_swapin_so_debug(d) swap_so_debug(d)
+#define md_swapout_so_debug(d) swap_so_debug(d)
+#define md_swapin_rrs_hash(f,n) swap_rrs_hash(f,n)
+#define md_swapout_rrs_hash(f,n) swap_rrs_hash(f,n)
+#define md_swapin_sod(l,n) swapin_sod(l,n)
+#define md_swapout_sod(l,n) swapout_sod(l,n)
+#define md_swapout_got(g,n) swap_longs((long*)(g),n)
+#define md_swapin_ranlib_hdr(h,n) swap_ranlib_hdr(h,n)
+#define md_swapout_ranlib_hdr(h,n) swap_ranlib_hdr(h,n)
#define md_swap_short(x) ( (((x) >> 8) & 0xff) | (((x) & 0xff) << 8) )
diff --git a/libexec/rtld-aout/rtld.c b/libexec/rtld-aout/rtld.c
index e02fef6..72ab49e 100644
--- a/libexec/rtld-aout/rtld.c
+++ b/libexec/rtld-aout/rtld.c
@@ -14,7 +14,7 @@
* 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
+ * derived from this software without 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
@@ -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.13 1994/01/12 23:16:19 jkh Exp $
+ * $Id: rtld.c,v 1.14 1994/01/14 11:47:00 jkh Exp $
*/
#include <machine/vmparam.h>
@@ -39,6 +39,7 @@
#include <sys/file.h>
#include <sys/time.h>
#include <sys/resource.h>
+#include <sys/errno.h>
#include <sys/mman.h>
#ifndef BSD
#define MAP_COPY MAP_PRIVATE
@@ -62,92 +63,115 @@
#endif
/*
- * Loader private data, hung off link_map->lm_lpd
+ * Loader private data, hung off <so_map>->som_spd
*/
-struct lm_private {
- int lpd_version;
- struct link_map *lpd_parent;
+struct somap_private {
+ int spd_version;
+ struct so_map *spd_parent;
+ int spd_refcount;
+ int spd_flags;
+#define RTLD_MAIN 1
+#define RTLD_RTLD 2
+#define RTLD_DL 4
+
#ifdef SUN_COMPAT
- long lpd_offset; /* Correction for Sun main programs */
+ long spd_offset; /* Correction for Sun main programs */
#endif
};
+#define LM_PRIVATE(smp) ((struct somap_private *)(smp)->som_spd)
+
#ifdef SUN_COMPAT
-#define LM_OFFSET(lmp) (((struct lm_private *)((lmp)->lm_lpd))->lpd_offset)
+#define LM_OFFSET(smp) (LM_PRIVATE(smp)->spd_offset)
#else
-#define LM_OFFSET(lmp) (0)
+#define LM_OFFSET(smp) (0)
#endif
-/* Base address for link_dynamic_2 entries */
-#define LM_LDBASE(lmp) (lmp->lm_addr + LM_OFFSET(lmp))
+/* Base address for section_dispatch_table entries */
+#define LM_LDBASE(smp) (smp->som_addr + LM_OFFSET(smp))
/* Start of text segment */
-#define LM_TXTADDR(lmp) (lmp->lm_addr == (caddr_t)0 ? PAGSIZ : 0)
+#define LM_TXTADDR(smp) (smp->som_addr == (caddr_t)0 ? PAGSIZ : 0)
/* Start of run-time relocation_info */
-#define LM_REL(lmp) ((struct relocation_info *) \
- (lmp->lm_addr + LM_OFFSET(lmp) + LD_REL((lmp)->lm_ld)))
+#define LM_REL(smp) ((struct relocation_info *) \
+ (smp->som_addr + LM_OFFSET(smp) + LD_REL((smp)->som_dynamic)))
/* Start of symbols */
-#define LM_SYMBOL(lmp, i) ((struct nzlist *) \
- (lmp->lm_addr + LM_OFFSET(lmp) + LD_SYMBOL((lmp)->lm_ld) + \
- i * (LD_VERSION_NZLIST_P(lmp->lm_ld->ld_version) ? \
- sizeof(struct nzlist) : sizeof(struct nlist))))
+#define LM_SYMBOL(smp, i) ((struct nzlist *) \
+ (smp->som_addr + LM_OFFSET(smp) + LD_SYMBOL((smp)->som_dynamic) + \
+ i * (LD_VERSION_NZLIST_P(smp->som_dynamic->d_version) ? \
+ sizeof(struct nzlist) : sizeof(struct nlist))))
/* Start of hash table */
-#define LM_HASH(lmp) ((struct rrs_hash *) \
- (lmp->lm_addr + LM_OFFSET(lmp) + LD_HASH((lmp)->lm_ld)))
+#define LM_HASH(smp) ((struct rrs_hash *) \
+ ((smp)->som_addr + LM_OFFSET(smp) + LD_HASH((smp)->som_dynamic)))
/* Start of strings */
-#define LM_STRINGS(lmp) ((char *) \
- (lmp->lm_addr + LM_OFFSET(lmp) + LD_STRINGS((lmp)->lm_ld)))
+#define LM_STRINGS(smp) ((char *) \
+ ((smp)->som_addr + LM_OFFSET(smp) + LD_STRINGS((smp)->som_dynamic)))
/* End of text */
-#define LM_ETEXT(lmp) ((char *) \
- (lmp->lm_addr + LM_TXTADDR(lmp) + LD_TEXTSZ((lmp)->lm_ld)))
+#define LM_ETEXT(smp) ((char *) \
+ ((smp)->som_addr + LM_TXTADDR(smp) + LD_TEXTSZ((smp)->som_dynamic)))
/* PLT is in data segment, so don't use LM_OFFSET here */
-#define LM_PLT(lmp) ((jmpslot_t *) \
- (lmp->lm_addr + LD_PLT((lmp)->lm_ld)))
+#define LM_PLT(smp) ((jmpslot_t *) \
+ ((smp)->som_addr + LD_PLT((smp)->som_dynamic)))
/* Parent of link map */
-#define LM_PARENT(lmp) (((struct lm_private *)((lmp)->lm_lpd))->lpd_parent)
+#define LM_PARENT(smp) (LM_PRIVATE(smp)->spd_parent)
char **environ;
int errno;
-uid_t uid, euid;
-gid_t gid, egid;
-int careful;
+static uid_t uid, euid;
+static gid_t gid, egid;
+static int careful;
+static char *main_progname = "main";
-struct link_map *link_map_head, *main_map;
-struct link_map **link_map_tail = &link_map_head;
+struct so_map *link_map_head, *main_map;
+struct so_map **link_map_tail = &link_map_head;
struct rt_symbol *rt_symbol_head;
-static int dlopen(), dlclose(), dlsym();
+static void *dlopen __P((char *, int));
+static int dlclose __P((void *));
+static void *dlsym __P((void *, char *));
+static int dlctl __P((void *, int, void *));
static struct ld_entry ld_entry = {
- dlopen, dlclose, dlsym
+ dlopen, dlclose, dlsym, dlctl
};
-void xprintf __P((char *, ...));
+ void xprintf __P((char *, ...));
static void init_brk __P((void));
-static void load_maps __P((struct crt_ldso *));
-static void map_object __P((struct link_object *, struct link_map *));
-static void alloc_link_map __P(( char *, struct link_object *,
- struct link_map *, caddr_t,
- struct link_dynamic *));
-static void check_text_reloc __P(( struct relocation_info *,
- struct link_map *,
+static void load_objects __P(( struct crt_ldso *,
+ struct _dynamic *));
+static struct so_map *map_object __P((struct sod *, struct so_map *));
+static struct so_map *alloc_link_map __P(( char *, struct sod *,
+ struct so_map *, caddr_t,
+ struct _dynamic *));
+static void inline check_text_reloc __P(( struct relocation_info *,
+ struct so_map *,
caddr_t));
-static void reloc_maps __P((void));
-static void reloc_copy __P((void));
-static void init_maps __P((void));
+static void reloc_map __P((struct so_map *));
+static void reloc_copy __P((struct so_map *));
+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 struct nzlist *lookup __P((char *, struct link_map **, int));
-static struct rt_symbol *lookup_rts __P((char *));
-static struct rt_symbol *enter_rts __P((char *, long, int, caddr_t, long));
+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 inline int
+strcmp (register const char *s1, register const char *s2)
+{
+ while (*s1 == *s2++)
+ if (*s1++ == 0)
+ return (0);
+ return (*(unsigned char *)s1 - *(unsigned char *)--s2);
+}
#include "md-static-funcs.c"
@@ -155,34 +179,36 @@ static struct rt_symbol *enter_rts __P((char *, long, int, caddr_t, long));
* Called from assembler stub that has set up crtp (passed from crt0)
* and dp (our __DYNAMIC).
*/
-void
+int
rtld(version, crtp, dp)
int version;
struct crt_ldso *crtp;
-struct link_dynamic *dp;
+struct _dynamic *dp;
{
int n;
int nreloc; /* # of ld.so relocations */
struct relocation_info *reloc;
char **envp;
- struct ld_debug *ldp;
+ struct so_debug *ddp;
+ struct so_map *smp;
/* Check version */
- if (version != CRT_VERSION_BSD && version != CRT_VERSION_SUN)
- return;
+ if ( version != CRT_VERSION_BSD_2 &&
+ version != CRT_VERSION_BSD_3 &&
+ version != CRT_VERSION_SUN)
+ return -1;
/* Fixup __DYNAMIC structure */
- (long)dp->ld_un.ld_2 += crtp->crt_ba;
+ (long)dp->d_un.d_sdt += crtp->crt_ba;
- /* Be careful not to use .div routine from library */
+ /* Divide by hand to avoid possible use of library division routine */
for ( nreloc = 0, n = LD_RELSZ(dp);
n > 0;
n -= sizeof(struct relocation_info) ) nreloc++;
/* Relocate ourselves */
- for ( reloc = (struct relocation_info *)
- (dp->ld_un.ld_2->ld_rel + crtp->crt_ba);
+ for ( reloc = (struct relocation_info *)(LD_REL(dp) + crtp->crt_ba);
nreloc;
nreloc--, reloc++) {
@@ -192,6 +218,8 @@ struct link_dynamic *dp;
}
progname = "ld.so";
+ if (version >= CRT_VERSION_BSD_3)
+ main_progname = crtp->crt_prog;
/* Setup out (private) environ variable */
environ = crtp->crt_ep;
@@ -212,89 +240,134 @@ struct link_dynamic *dp;
std_search_dirs(getenv("LD_LIBRARY_PATH"));
/* Load required objects into the process address space */
- load_maps(crtp);
+ load_objects(crtp, dp);
/* Relocate all loaded objects according to their RRS segments */
- reloc_maps();
- reloc_copy();
- init_maps();
+ for (smp = link_map_head; smp; smp = smp->som_next) {
+ if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
+ continue;
+ reloc_map(smp);
+ }
+
+ /* Copy any relocated initialized data. */
+ for (smp = link_map_head; smp; smp = smp->som_next) {
+ if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
+ continue;
+ reloc_copy(smp);
+ }
+
+ /* Call any object initialization routines. */
+ for (smp = link_map_head; smp; smp = smp->som_next) {
+ if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
+ continue;
+ init_map(smp, ".init");
+ }
/* Fill in some field in main's __DYNAMIC structure */
- crtp->crt_dp->ld_entry = &ld_entry;
+ crtp->crt_dp->d_entry = &ld_entry;
+ crtp->crt_dp->d_un.d_sdt->sdt_loaded = link_map_head->som_next;
- ldp = crtp->crt_dp->ldd;
- ldp->ldd_cp = rt_symbol_head;
- if (ldp->ldd_in_debugger) {
+ ddp = crtp->crt_dp->d_debug;
+ ddp->dd_cc = rt_symbol_head;
+ if (ddp->dd_in_debugger) {
caddr_t addr = (caddr_t)((long)crtp->crt_bp & (~(PAGSIZ - 1)));
/* Set breakpoint for the benefit of debuggers */
if (mprotect(addr, PAGSIZ,
PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
perror("mprotect"),
- fatal("Cannot set breakpoint\n");
+ fatal("Cannot set breakpoint (%s)\n", main_progname);
}
- md_set_breakpoint(crtp->crt_bp, &ldp->ldd_bp_inst);
+ md_set_breakpoint(crtp->crt_bp, &ddp->dd_bpt_shadow);
if (mprotect(addr, PAGSIZ, PROT_READ|PROT_EXEC) == -1) {
perror("mprotect");
}
- ldp->ldd_bp_addr = crtp->crt_bp;
+ ddp->dd_bpt_addr = crtp->crt_bp;
if (link_map_head)
- ldp->ldd_sym_loaded = 1;
+ ddp->dd_sym_loaded = 1;
}
- crtp->crt_dp->ld_un.ld_2->ld_loaded = link_map_head->lm_next;
+
/* Close our file descriptor */
(void)close(crtp->crt_ldfd);
+ return 0;
}
static void
-load_maps(crtp)
+load_objects(crtp, dp)
struct crt_ldso *crtp;
+struct _dynamic *dp;
{
- struct link_map *lmp;
- int tracing = (int)getenv("LD_TRACE_LOADED_OBJECTS");
+ struct so_map *smp;
+ int tracing = (int)getenv("LD_TRACE_LOADED_OBJECTS");
/* Handle LD_PRELOAD's here */
/* Make an entry for the main program */
- alloc_link_map("main", (struct link_object *)0, (struct link_map *)0,
+ smp = alloc_link_map(main_progname, (struct sod *)0, (struct so_map *)0,
(caddr_t)0, crtp->crt_dp);
+ LM_PRIVATE(smp)->spd_refcount++;
+ LM_PRIVATE(smp)->spd_flags |= RTLD_MAIN;
- for (lmp = link_map_head; lmp; lmp = lmp->lm_next) {
- struct link_object *lop;
- long next = 0;
+ /* Make an entry for ourselves */
+ smp = alloc_link_map("/usr/libexec/ld.so", (struct sod *)0, (struct so_map *)0,
+ (caddr_t)crtp->crt_ba, dp);
+ LM_PRIVATE(smp)->spd_refcount++;
+ LM_PRIVATE(smp)->spd_flags |= RTLD_RTLD;
- if (lmp->lm_ld)
- next = LD_NEED(lmp->lm_ld);
+ for (smp = link_map_head; smp; smp = smp->som_next) {
+ struct sod *sodp;
+ long next = 0;
+
+ if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
+ continue;
+
+ if (smp->som_dynamic)
+ next = LD_NEED(smp->som_dynamic);
while (next) {
- lop = (struct link_object *) (LM_LDBASE(lmp) + next);
- map_object(lop, lmp);
- next = lop->lo_next;
+ struct so_map *newmap;
+
+ sodp = (struct sod *)(LM_LDBASE(smp) + next);
+ if ((newmap = map_object(sodp, smp)) == NULL) {
+ if (!tracing) {
+ char *name = (char *)
+ (sodp->sod_name + LM_LDBASE(smp));
+ char *fmt = sodp->sod_library ?
+ "%s: lib%s.so.%d.%d: %s\n" :
+ "%s: %s: %s\n";
+ fatal(fmt, main_progname, name,
+ sodp->sod_major,
+ sodp->sod_minor,
+ strerror(errno));
+ }
+ newmap = alloc_link_map(NULL, sodp, smp, 0, 0);
+ }
+ LM_PRIVATE(newmap)->spd_refcount++;
+ next = sodp->sod_next;
}
}
if (! tracing)
return;
- for (lmp = link_map_head; lmp; lmp = lmp->lm_next) {
- struct link_object *lop;
- char *name, *path;
+ for (smp = link_map_head; smp; smp = smp->som_next) {
+ struct sod *sodp;
+ char *name, *path;
- if ((lop = lmp->lm_lop) == NULL)
+ if ((sodp = smp->som_sod) == NULL)
continue;
+ name = sodp->sod_name + LM_LDBASE(LM_PARENT(smp));
- name = lop->lo_name + LM_LDBASE(LM_PARENT(lmp));
-
- if ((path = lmp->lm_name) == NULL)
+ if ((path = smp->som_path) == NULL)
path = "not found";
- if (lop->lo_library)
+ if (sodp->sod_library)
printf("\t-l%s.%d => %s (%#x)\n", name,
- lop->lo_major, path, lmp->lm_addr);
+ sodp->sod_major, path, smp->som_addr);
else
- printf("\t%s => %s (%#x)\n", name, path, lmp->lm_addr);
+ printf("\t%s => %s (%#x)\n", name, path, smp->som_addr);
}
exit(0);
@@ -304,94 +377,120 @@ struct crt_ldso *crtp;
* Allocate a new link map for an shared object NAME loaded at ADDR as a
* result of the presence of link object LOP in the link map PARENT.
*/
-static void
-alloc_link_map(name, lop, parent, addr, dp)
-char *name;
-struct link_map *parent;
-struct link_object *lop;
-caddr_t addr;
-struct link_dynamic *dp;
+ static struct so_map *
+alloc_link_map(path, sodp, parent, addr, dp)
+ char *path;
+ struct sod *sodp;
+ struct so_map *parent;
+ caddr_t addr;
+ struct _dynamic *dp;
{
- struct link_map *lmp;
- struct lm_private *lmpp;
+ struct so_map *smp;
+ struct somap_private *smpp;
- lmpp = (struct lm_private *)xmalloc(sizeof(struct lm_private));
- lmp = (struct link_map *)xmalloc(sizeof(struct link_map));
- lmp->lm_next = NULL;
- *link_map_tail = lmp;
- link_map_tail = &lmp->lm_next;
+ smpp = (struct somap_private *)xmalloc(sizeof(struct somap_private));
+ smp = (struct so_map *)xmalloc(sizeof(struct so_map));
+ smp->som_next = NULL;
+ *link_map_tail = smp;
+ link_map_tail = &smp->som_next;
- lmp->lm_addr = addr;
- lmp->lm_name = name;
- lmp->lm_lop = lop;
- lmp->lm_ld = dp;
- lmp->lm_lpd = (caddr_t)lmpp;
+ smp->som_addr = addr;
+ smp->som_path = path;
+ smp->som_sod = sodp;
+ smp->som_dynamic = dp;
+ smp->som_spd = (caddr_t)smpp;
-/*XXX*/ if (addr == 0) main_map = lmp;
+/*XXX*/ if (addr == 0) main_map = smp;
- lmpp->lpd_parent = parent;
+ smpp->spd_refcount = 0;
+ smpp->spd_flags = 0;
+ smpp->spd_parent = parent;
#ifdef SUN_COMPAT
- lmpp->lpd_offset =
- (addr == 0 && dp->ld_version == LD_VERSION_SUN) ? PAGSIZ : 0;
+ smpp->spd_offset =
+ (addr==0 && dp && dp->d_version==LD_VERSION_SUN) ? PAGSIZ : 0;
#endif
+ return smp;
}
/*
* Map object identified by link object LOP which was found
* in link map LMP.
*/
-static void
-map_object(lop, lmp)
-struct link_object *lop;
-struct link_map *lmp;
+ static struct so_map *
+map_object(sodp, smp)
+ struct sod *sodp;
+ struct so_map *smp;
{
- struct link_dynamic *dp;
- char *path, *name = (char *)(lop->lo_name + LM_LDBASE(lmp));
+ struct _dynamic *dp;
+ char *path, *name = (char *)(sodp->sod_name + LM_LDBASE(smp));
int fd;
caddr_t addr;
struct exec hdr;
int usehints = 0;
+ struct so_map *p;
- if (lop->lo_library) {
+ if (sodp->sod_library) {
usehints = 1;
again:
- path = rtfindlib(name, lop->lo_major, lop->lo_minor, &usehints);
- if (path == NULL)
- fatal("Cannot find lib%s.so.%d.%d\n",
- name, lop->lo_major, lop->lo_minor);
+ path = rtfindlib(name, sodp->sod_major,
+ sodp->sod_minor, &usehints);
+ if (path == NULL) {
+ errno = ENOENT;
+ return NULL;
+ }
} else {
+ if (careful && *name != '/') {
+ errno = EACCES;
+ return NULL;
+ }
path = name;
}
- fd = open(path, O_RDONLY, 0);
- if (fd == -1) {
+ /* Check if already loaded */
+ for (p = link_map_head; p; p = p->som_next)
+ if (p->som_path && strcmp(p->som_path, path) == 0)
+ break;
+
+ if (p != NULL)
+ return p;
+
+ if ((fd = open(path, O_RDONLY, 0)) == -1) {
if (usehints) {
usehints = 0;
goto again;
}
- fatal("%s not found", path);
+ return NULL;
}
if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
- fatal("%s: Cannot read exec header", path);
+ (void)close(fd);
+ /*errno = x;*/
+ return NULL;
}
- if (N_BADMAG(hdr))
- fatal("%s: Incorrect format", path);
+ if (N_BADMAG(hdr)) {
+ (void)close(fd);
+ errno = EFTYPE;
+ return NULL;
+ }
if ((addr = mmap(0, hdr.a_text + hdr.a_data,
PROT_READ|PROT_EXEC,
- MAP_FILE|MAP_COPY, fd, 0)) == (caddr_t)-1)
- fatal("Cannot map %s text\n", path);
+ MAP_FILE|MAP_COPY, fd, 0)) == (caddr_t)-1) {
+ (void)close(fd);
+ return NULL;
+ }
if (mmap(addr + hdr.a_text, hdr.a_data,
- PROT_READ|PROT_WRITE,
+ PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_FILE|MAP_FIXED|MAP_COPY,
- fd, hdr.a_text) == (caddr_t)-1)
- fatal("Cannot map %s data", path);
+ fd, hdr.a_text) == (caddr_t)-1) {
+ (void)close(fd);
+ return NULL;
+ }
- close(fd);
+ (void)close(fd);
fd = -1;
#ifdef NEED_DEV_ZERO
@@ -399,213 +498,282 @@ again:
perror("/dev/zero");
#endif
if (hdr.a_bss && mmap(addr + hdr.a_text + hdr.a_data, hdr.a_bss,
- PROT_READ|PROT_WRITE,
+ PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_ANON|MAP_FIXED|MAP_COPY,
fd, hdr.a_text + hdr.a_data) == (caddr_t)-1)
- fatal("Cannot map %s bss", path);
+ return NULL;
#ifdef NEED_DEV_ZERO
close(fd);
#endif
/* Assume _DYNAMIC is the first data item */
- dp = (struct link_dynamic *)(addr+hdr.a_text);
+ dp = (struct _dynamic *)(addr+hdr.a_text);
/* Fixup __DYNAMIC structure */
- (long)dp->ld_un.ld_2 += (long)addr;
-
- alloc_link_map(path, lop, lmp, addr, dp);
+ (long)dp->d_un.d_sdt += (long)addr;
+ return alloc_link_map(path, sodp, smp, addr, dp);
}
-static void
-reloc_maps()
+static void inline
+check_text_reloc(r, smp, addr)
+struct relocation_info *r;
+struct so_map *smp;
+caddr_t addr;
{
- struct link_map *lmp;
-
- for (lmp = link_map_head; lmp; lmp = lmp->lm_next) {
-
- struct link_dynamic *dp = lmp->lm_ld;
- struct relocation_info *r = LM_REL(lmp);
- struct relocation_info *rend = r + LD_RELSZ(dp)/sizeof(*r);
-
- if (LD_PLTSZ(dp))
- md_fix_jmpslot(LM_PLT(lmp),
- (long)LM_PLT(lmp), (long)binder_entry);
-
- for (; r < rend; r++) {
- char *sym;
- caddr_t addr = lmp->lm_addr + r->r_address;
-
- check_text_reloc(r, lmp, addr);
+ char *sym;
- if (RELOC_EXTERN_P(r)) {
- struct link_map *src_map = NULL;
- struct nzlist *p, *np;
- long relocation = md_get_addend(r, addr);
+ if (addr >= LM_ETEXT(smp))
+ return;
- if (RELOC_LAZY_P(r))
- continue;
+ if (RELOC_EXTERN_P(r))
+ sym = LM_STRINGS(smp) +
+ LM_SYMBOL(smp, RELOC_SYMBOL(r))->nz_strx;
+ else
+ sym = "";
- p = LM_SYMBOL(lmp,RELOC_SYMBOL(r));
- if (p->nz_type == (N_SETV + N_EXT))
- src_map = lmp;
+ if (getenv("LD_WARN_NON_PURE_CODE") != NULL)
+ fprintf(stderr,
+ "ld.so: warning: non pure code in %s at %x (%s)\n",
+ smp->som_path, r->r_address, sym);
- sym = LM_STRINGS(lmp) + p->nz_strx;
+ if (smp->som_write == 0 &&
+ mprotect(smp->som_addr + LM_TXTADDR(smp),
+ LD_TEXTSZ(smp->som_dynamic),
+ PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
- np = lookup(sym, &src_map, 0/*XXX-jumpslots!*/);
- if (np == NULL)
- fatal("Undefined symbol \"%s\" in %s\n",
- sym, lmp->lm_name);
+ perror("mprotect"),
+ fatal("Cannot enable writes to %s:%s\n",
+ main_progname, smp->som_path);
+ }
- /*
- * Found symbol definition.
- * If it's in a link map, adjust value
- * according to the load address of that map.
- * Otherwise it's a run-time allocated common
- * whose value is already up-to-date.
- */
- relocation += np->nz_value;
- if (src_map)
- relocation += (long)src_map->lm_addr;
+ smp->som_write = 1;
+}
- if (RELOC_PCREL_P(r))
- relocation -= (long)lmp->lm_addr;
+static void
+reloc_map(smp)
+ struct so_map *smp;
+{
+ struct _dynamic *dp = smp->som_dynamic;
+ struct relocation_info *r = LM_REL(smp);
+ struct relocation_info *rend = r + LD_RELSZ(dp)/sizeof(*r);
+ long symbolbase = (long)LM_SYMBOL(smp, 0);
+ char *stringbase = LM_STRINGS(smp);
+ int symsize = LD_VERSION_NZLIST_P(dp->d_version) ?
+ sizeof(struct nzlist) :
+ sizeof(struct nlist);
+
+ if (LD_PLTSZ(dp))
+ md_fix_jmpslot(LM_PLT(smp),
+ (long)LM_PLT(smp), (long)binder_entry);
+
+ for (; r < rend; r++) {
+ char *sym;
+ caddr_t addr = smp->som_addr + r->r_address;
+
+ check_text_reloc(r, smp, addr);
+
+ if (RELOC_EXTERN_P(r)) {
+ struct so_map *src_map = NULL;
+ struct nzlist *p, *np;
+ long relocation = md_get_addend(r, addr);
+
+ if (RELOC_LAZY_P(r))
+ continue;
- if (RELOC_COPY_P(r) && src_map) {
-#if DEBUG
-xprintf("RELOCATE(%s) copy: from %s at %#x(%#x+%#x) to %s at %#x, reloc = %#x, size %d\n",
-lmp->lm_name, src_map->lm_name, src_map->lm_addr + np->nz_value,
-src_map->lm_addr, np->nz_value, sym, addr, relocation, np->nz_size);
-#endif
- (void)enter_rts(sym,
- (long)addr,
- N_DATA + N_EXT,
- src_map->lm_addr + np->nz_value,
- np->nz_size);
- continue;
- }
-#if DEBUG
-if (sym[2]=='_'&&(sym[3]=='C'||sym[3]=='D')&&sym[4]=='T')
-xprintf("RELOCATE(%s) external: %s at %#x, reloc = %#x in %s\n",
-lmp->lm_name, sym, addr, relocation, src_map?src_map->lm_name:"(NUL)");
-#endif
- md_relocate(r, relocation, addr, 0);
+ p = (struct nzlist *)
+ (symbolbase + symsize * RELOC_SYMBOL(r));
+
+ if (p->nz_type == (N_SETV + N_EXT))
+ src_map = smp;
+
+ sym = stringbase + p->nz_strx;
+
+ np = lookup(sym, &src_map, 0/*XXX-jumpslots!*/);
+ if (np == NULL)
+ fatal("Undefined symbol \"%s\" in %s:%s\n",
+ sym, main_progname, smp->som_path);
+
+ /*
+ * Found symbol definition.
+ * If it's in a link map, adjust value
+ * according to the load address of that map.
+ * Otherwise it's a run-time allocated common
+ * whose value is already up-to-date.
+ */
+ relocation += np->nz_value;
+ if (src_map)
+ relocation += (long)src_map->som_addr;
+
+ if (RELOC_PCREL_P(r))
+ relocation -= (long)smp->som_addr;
+
+ if (RELOC_COPY_P(r) && src_map) {
+ (void)enter_rts(sym,
+ (long)addr,
+ N_DATA + N_EXT,
+ src_map->som_addr + np->nz_value,
+ np->nz_size, src_map);
+ continue;
+ }
+ md_relocate(r, relocation, addr, 0);
- } else {
-#if DEBUG
-xprintf("RELOCATE(%s) internal at %#x, reloc = %#x\n", lmp->lm_name, addr, md_get_rt_segment_addend(r,addr));
-#endif
- md_relocate(r,
+ } else {
+ md_relocate(r,
#ifdef SUN_COMPAT
- md_get_rt_segment_addend(r, addr)
+ md_get_rt_segment_addend(r, addr)
#else
- md_get_addend(r, addr)
+ md_get_addend(r, addr)
#endif
- + (long)lmp->lm_addr, addr, 0);
- }
-
+ + (long)smp->som_addr, addr, 0);
}
- if (lmp->lm_rwt) {
- if (mprotect(lmp->lm_addr + LM_TXTADDR(lmp),
- LD_TEXTSZ(lmp->lm_ld),
+ }
+
+ if (smp->som_write) {
+ if (mprotect(smp->som_addr + LM_TXTADDR(smp),
+ LD_TEXTSZ(smp->som_dynamic),
PROT_READ|PROT_EXEC) == -1) {
- perror("mprotect"),
- fatal("Cannot disable writes to %s\n", lmp->lm_name);
- }
- lmp->lm_rwt = 0;
+ perror("mprotect"),
+ fatal("Cannot disable writes to %s:%s\n",
+ main_progname, smp->som_path);
}
-
+ smp->som_write = 0;
}
}
static void
-reloc_copy()
+reloc_copy(smp)
+ struct so_map *smp;
{
struct rt_symbol *rtsp;
for (rtsp = rt_symbol_head; rtsp; rtsp = rtsp->rt_next)
- if (rtsp->rt_sp->nz_type == N_DATA + N_EXT) {
-#ifdef DEBUG
-xprintf("reloc_copy: from %#x to %#x, size %d\n",
-rtsp->rt_srcaddr, rtsp->rt_sp->nz_value, rtsp->rt_sp->nz_size);
-#endif
+ if ((rtsp->rt_smp == NULL || rtsp->rt_smp == smp) &&
+ rtsp->rt_sp->nz_type == N_DATA + N_EXT) {
bcopy(rtsp->rt_srcaddr, (caddr_t)rtsp->rt_sp->nz_value,
rtsp->rt_sp->nz_size);
}
}
static void
-check_text_reloc(r, lmp, addr)
-struct relocation_info *r;
-struct link_map *lmp;
-caddr_t addr;
+init_map(smp, sym)
+ struct so_map *smp;
+ char *sym;
{
- char *sym;
+ struct so_map *src_map = smp;
+ struct nzlist *np;
- if (addr >= LM_ETEXT(lmp))
- return;
+ np = lookup(sym, &src_map, 1);
+ if (np)
+ (*(void (*)())(src_map->som_addr + np->nz_value))();
+}
- if (RELOC_EXTERN_P(r))
- sym = LM_STRINGS(lmp) +
- LM_SYMBOL(lmp, RELOC_SYMBOL(r))->nz_strx;
- else
- sym = "";
+/*
+ * Run-time common symbol table.
+ */
-#ifdef DEBUG
- fprintf(stderr, "ld.so: warning: non pure code in %s at %x (%s)\n",
- lmp->lm_name, r->r_address, sym);
-#endif
+#define RTC_TABSIZE 57
+static struct rt_symbol *rt_symtab[RTC_TABSIZE];
- if (lmp->lm_rwt == 0 &&
- mprotect(lmp->lm_addr + LM_TXTADDR(lmp),
- LD_TEXTSZ(lmp->lm_ld),
- PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
+/*
+ * Compute hash value for run-time symbol table
+ */
+ static int inline
+hash_string(key)
+ char *key;
+{
+ register char *cp;
+ register int k;
- perror("mprotect"),
- fatal("Cannot enable writes to %s\n", lmp->lm_name);
- }
+ cp = key;
+ k = 0;
+ while (*cp)
+ k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
- lmp->lm_rwt = 1;
+ return k;
}
-static void
-init_maps()
+/*
+ * Lookup KEY in the run-time common symbol table.
+ */
+
+ static inline struct rt_symbol *
+lookup_rts(key)
+ char *key;
{
- struct link_map *lmp, *src_map;
- struct nzlist *np;
- void (*func)();
+ register int hashval;
+ register struct rt_symbol *rtsp;
- for (lmp = link_map_head; lmp; lmp = lmp->lm_next) {
- src_map = lmp;
- np = lookup("___init", &src_map, 1);
-#if DEBUG
-if (np)
-xprintf("Calling __init in %s at %#x\n", src_map->lm_name, np->nz_value+src_map->lm_addr);
-#endif
- if (np) {
- func = (void (*)())(src_map->lm_addr + np->nz_value);
- (*func)();
- }
- }
+ /* Determine which bucket. */
+
+ hashval = hash_string(key) % RTC_TABSIZE;
+
+ /* Search the bucket. */
+
+ for (rtsp = rt_symtab[hashval]; rtsp; rtsp = rtsp->rt_link)
+ if (strcmp(key, rtsp->rt_sp->nz_name) == 0)
+ return rtsp;
+
+ return NULL;
}
+ static struct rt_symbol *
+enter_rts(name, value, type, srcaddr, size, smp)
+ char *name;
+ long value;
+ int type;
+ caddr_t srcaddr;
+ long size;
+ struct so_map *smp;
+{
+ register int hashval;
+ register struct rt_symbol *rtsp, **rpp;
+
+ /* Determine which bucket */
+ hashval = hash_string(name) % RTC_TABSIZE;
+
+ /* Find end of bucket */
+ for (rpp = &rt_symtab[hashval]; *rpp; rpp = &(*rpp)->rt_link)
+ ;
+
+ /* Allocate new common symbol */
+ rtsp = (struct rt_symbol *)malloc(sizeof(struct rt_symbol));
+ rtsp->rt_sp = (struct nzlist *)malloc(sizeof(struct nzlist));
+ rtsp->rt_sp->nz_name = strdup(name);
+ rtsp->rt_sp->nz_value = value;
+ rtsp->rt_sp->nz_type = type;
+ rtsp->rt_sp->nz_size = size;
+ rtsp->rt_srcaddr = srcaddr;
+ rtsp->rt_smp = smp;
+ rtsp->rt_link = NULL;
+
+ /* Link onto linear list as well */
+ rtsp->rt_next = rt_symbol_head;
+ rt_symbol_head = rtsp;
+
+ *rpp = rtsp;
+
+ return rtsp;
+}
+
+
/*
* Lookup NAME in the link maps. The link map producing a definition
* is returned in SRC_MAP. If SRC_MAP is not NULL on entry the search is
* confined to that map. If STRONG is set, the symbol returned must
* have a proper type (used by binder()).
*/
-static struct nzlist *
+ static struct nzlist *
lookup(name, src_map, strong)
-char *name;
-struct link_map **src_map; /* IN/OUT */
-int strong;
+ char *name;
+ struct so_map **src_map; /* IN/OUT */
+ int strong;
{
long common_size = 0;
- struct link_map *lmp;
+ struct so_map *smp;
struct rt_symbol *rtsp;
if ((rtsp = lookup_rts(name)) != NULL)
@@ -614,14 +782,23 @@ int strong;
/*
* Search all maps for a definition of NAME
*/
- for (lmp = link_map_head; lmp; lmp = lmp->lm_next) {
- int buckets = LD_BUCKETS(lmp->lm_ld);
+ for (smp = link_map_head; smp; smp = smp->som_next) {
+ int buckets = LD_BUCKETS(smp->som_dynamic);
long hashval = 0;
struct rrs_hash *hp;
char *cp;
struct nzlist *np;
- if (*src_map && lmp != *src_map)
+ /* Some local caching */
+ long symbolbase;
+ struct rrs_hash *hashbase;
+ char *stringbase;
+ int symsize;
+
+ if (LM_PRIVATE(smp)->spd_flags & RTLD_RTLD)
+ continue;
+
+ if (*src_map && smp != *src_map)
continue;
/*
@@ -632,20 +809,27 @@ int strong;
hashval = (hashval & 0x7fffffff) % buckets;
- hp = LM_HASH(lmp) + hashval;
+ hashbase = LM_HASH(smp);
+ hp = hashbase + hashval;
if (hp->rh_symbolnum == -1)
/* Nothing in this bucket */
continue;
+ symbolbase = (long)LM_SYMBOL(smp, 0);
+ stringbase = LM_STRINGS(smp);
+ symsize = LD_VERSION_NZLIST_P(smp->som_dynamic->d_version)?
+ sizeof(struct nzlist) :
+ sizeof(struct nlist);
while (hp) {
- np = LM_SYMBOL(lmp, hp->rh_symbolnum);
- cp = LM_STRINGS(lmp) + np->nz_strx;
+ np = (struct nzlist *)
+ (symbolbase + hp->rh_symbolnum * symsize);
+ cp = stringbase + np->nz_strx;
if (strcmp(cp, name) == 0)
break;
if (hp->rh_next == 0)
hp = NULL;
else
- hp = LM_HASH(lmp) + hp->rh_next;
+ hp = hashbase + hp->rh_next;
}
if (hp == NULL)
/* Nothing in this bucket */
@@ -660,7 +844,7 @@ int strong;
continue;
if (np->nz_type == N_UNDF+N_EXT && np->nz_value != 0) {
- if (np->nz_other == RRS_FUNC) {
+ if (np->nz_other == AUX_FUNC) {
/* It's a weak function definition */
if (strong)
continue;
@@ -672,7 +856,7 @@ int strong;
}
}
- *src_map = lmp;
+ *src_map = smp;
return np;
}
@@ -684,7 +868,7 @@ int strong;
* It's a common, enter into run-time common symbol table.
*/
rtsp = enter_rts(name, (long)calloc(1, common_size),
- N_UNDF + N_EXT, 0, common_size);
+ N_UNDF + N_EXT, 0, common_size, NULL);
#if DEBUG
xprintf("Allocating common: %s size %d at %#x\n", name, common_size, rtsp->rt_sp->nz_value);
@@ -698,11 +882,11 @@ xprintf("Allocating common: %s size %d at %#x\n", name, common_size, rtsp->rt_sp
* This routine is called from the jumptable to resolve
* procedure calls to shared objects.
*/
-long
+ long
binder(jsp)
-jmpslot_t *jsp;
+ jmpslot_t *jsp;
{
- struct link_map *lmp, *src_map = NULL;
+ struct so_map *smp, *src_map = NULL;
long addr;
char *sym;
struct nzlist *np;
@@ -711,133 +895,47 @@ jmpslot_t *jsp;
/*
* Find the PLT map that contains JSP.
*/
- for (lmp = link_map_head; lmp; lmp = lmp->lm_next) {
- if (LM_PLT(lmp) < jsp &&
- jsp < LM_PLT(lmp) + LD_PLTSZ(lmp->lm_ld)/sizeof(*jsp))
+ for (smp = link_map_head; smp; smp = smp->som_next) {
+ if (LM_PLT(smp) < jsp &&
+ jsp < LM_PLT(smp) + LD_PLTSZ(smp->som_dynamic)/sizeof(*jsp))
break;
}
- if (lmp == NULL)
+ if (smp == NULL)
fatal("Call to binder from unknown location: %#x\n", jsp);
index = jsp->reloc_index & JMPSLOT_RELOC_MASK;
/* Get the local symbol this jmpslot refers to */
- sym = LM_STRINGS(lmp) +
- LM_SYMBOL(lmp,RELOC_SYMBOL(&LM_REL(lmp)[index]))->nz_strx;
+ sym = LM_STRINGS(smp) +
+ LM_SYMBOL(smp,RELOC_SYMBOL(&LM_REL(smp)[index]))->nz_strx;
np = lookup(sym, &src_map, 1);
if (np == NULL)
- fatal("Undefined symbol \"%s\" called from %s at %#x", sym,
- lmp->lm_name, jsp);
+ fatal("Undefined symbol \"%s\" called from %s:%s at %#x",
+ sym, main_progname, smp->som_path, jsp);
/* Fixup jmpslot so future calls transfer directly to target */
addr = np->nz_value;
if (src_map)
- addr += (long)src_map->lm_addr;
+ addr += (long)src_map->som_addr;
md_fix_jmpslot(jsp, (long)jsp, addr);
#if DEBUG
-xprintf(" BINDER: %s located at = %#x in %s\n", sym, addr, src_map->lm_name);
+xprintf(" BINDER: %s located at = %#x in %s\n", sym, addr, src_map->som_path);
#endif
return addr;
}
-/*
- * Run-time common symbol table.
- */
-
-#define RTC_TABSIZE 57
-static struct rt_symbol *rt_symtab[RTC_TABSIZE];
-
-/*
- * Compute hash value for run-time symbol table
- */
-static int
-hash_string(key)
- char *key;
-{
- register char *cp;
- register int k;
-
- cp = key;
- k = 0;
- while (*cp)
- k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
-
- return k;
-}
-
-/*
- * Lookup KEY in the run-time common symbol table.
- */
-
-static struct rt_symbol *
-lookup_rts(key)
- char *key;
-{
- register int hashval;
- register struct rt_symbol *rtsp;
-
- /* Determine which bucket. */
-
- hashval = hash_string(key) % RTC_TABSIZE;
-
- /* Search the bucket. */
-
- for (rtsp = rt_symtab[hashval]; rtsp; rtsp = rtsp->rt_link)
- if (strcmp(key, rtsp->rt_sp->nz_name) == 0)
- return rtsp;
-
- return NULL;
-}
-
-static struct rt_symbol *
-enter_rts(name, value, type, srcaddr, size)
- char *name;
- long value;
- int type;
- caddr_t srcaddr;
- long size;
-{
- register int hashval;
- register struct rt_symbol *rtsp, **rpp;
-
- /* Determine which bucket */
- hashval = hash_string(name) % RTC_TABSIZE;
-
- /* Find end of bucket */
- for (rpp = &rt_symtab[hashval]; *rpp; rpp = &(*rpp)->rt_link)
- ;
-
- /* Allocate new common symbol */
- rtsp = (struct rt_symbol *)malloc(sizeof(struct rt_symbol));
- rtsp->rt_sp = (struct nzlist *)malloc(sizeof(struct nzlist));
- rtsp->rt_sp->nz_name = strdup(name);
- rtsp->rt_sp->nz_value = value;
- rtsp->rt_sp->nz_type = type;
- rtsp->rt_sp->nz_size = size;
- rtsp->rt_srcaddr = srcaddr;
- rtsp->rt_link = NULL;
-
- /* Link onto linear list as well */
- rtsp->rt_next = rt_symbol_head;
- rt_symbol_head = rtsp;
-
- *rpp = rtsp;
-
- return rtsp;
-}
-
static struct hints_header *hheader;
static struct hints_bucket *hbuckets;
static char *hstrtab;
#define HINTS_VALID (hheader != NULL && hheader != (struct hints_header *)-1)
-static void
+ static void
maphints()
{
caddr_t addr;
@@ -886,10 +984,10 @@ maphints()
hstrtab = (char *)(addr + hheader->hh_strtab);
}
-int
+ int
hinthash(cp, vmajor, vminor)
-char *cp;
-int vmajor, vminor;
+ char *cp;
+ int vmajor, vminor;
{
int k = 0;
@@ -905,11 +1003,11 @@ int vmajor, vminor;
#undef major
#undef minor
-static char *
+ static char *
findhint(name, major, minor, preferred_path)
-char *name;
-int major, minor;
-char *preferred_path;
+ char *name;
+ int major, minor;
+ char *preferred_path;
{
struct hints_bucket *bp;
@@ -949,11 +1047,11 @@ char *preferred_path;
return NULL;
}
-static char *
+ static char *
rtfindlib(name, major, minor, usehints)
-char *name;
-int major, minor;
-int *usehints;
+ char *name;
+ int major, minor;
+ int *usehints;
{
char *hint;
char *cp, *ld_path = getenv("LD_LIBRARY_PATH");
@@ -988,29 +1086,131 @@ int *usehints;
return (char *)findshlib(name, &major, &minor, 0);
}
-static int
+static struct somap_private dlmap_private = {
+ 0,
+ (struct so_map *)0,
+ 0,
+#ifdef SUN_COMPAT
+ 0,
+#endif
+};
+
+static struct so_map dlmap = {
+ (caddr_t)0,
+ "internal",
+ (struct so_map *)0,
+ (struct sod *)0,
+ (caddr_t)0,
+ (u_int)0,
+ (struct _dynamic *)0,
+ (caddr_t)&dlmap_private
+};
+static int dlerrno;
+
+ static void *
dlopen(name, mode)
-char *name;
-int mode;
+ char *name;
+ int mode;
{
- xprintf("dlopen(%s, %x)\n", name, mode);
- return -1;
+ struct sod *sodp;
+ struct so_map *smp;
+
+ /*
+ * A NULL argument returns the current set of mapped objects.
+ */
+ if (name == NULL)
+ return link_map_head;
+
+ if ((sodp = (struct sod *)malloc(sizeof(struct sod))) == NULL) {
+ dlerrno = ENOMEM;
+ return NULL;
+ }
+
+ sodp->sod_name = (long)name;
+ sodp->sod_library = 0;
+ sodp->sod_major = sodp->sod_minor = 0;
+
+ if ((smp = map_object(sodp, &dlmap)) == NULL) {
+#ifdef DEBUG
+xprintf("%s: %s\n", name, strerror(errno));
+#endif
+ dlerrno = errno;
+ return NULL;
+ }
+ if (LM_PRIVATE(smp)->spd_refcount++ == 0) {
+ LM_PRIVATE(smp)->spd_flags |= RTLD_DL;
+ reloc_map(smp);
+ reloc_copy(smp);
+ init_map(smp, ".init");
+ init_map(smp, "_init");
+ }
+
+ return smp;
}
-static int
+ static int
dlclose(fd)
-int fd;
+ void *fd;
{
- xprintf("dlclose(%d)\n", fd);
- return -1;
+ struct so_map *smp = (struct so_map *)fd;
+
+#ifdef DEBUG
+xprintf("dlclose(%s): refcount = %d\n", smp->som_path, LM_PRIVATE(smp)->spd_refcount);
+#endif
+ if (--LM_PRIVATE(smp)->spd_refcount != 0)
+ return 0;
+
+ /* Dismantle shared object map and descriptor */
+ init_map(smp, "_fini");
+#if 0
+ unmap_object(smp);
+ free(smp->som_sod);
+ free(smp);
+#endif
+
+ return 0;
}
-static int
+ static void *
dlsym(fd, sym)
-int fd;
-char *sym;
+ void *fd;
+ char *sym;
{
- xprintf("dlsym(%d, %s)\n", fd, sym);
+ struct so_map *smp = (struct so_map *)fd, *src_map = NULL;
+ struct nzlist *np;
+ long addr;
+
+ /*
+ * Restrict search to passed map if dlopen()ed.
+ */
+ if (LM_PRIVATE(smp)->spd_flags & RTLD_DL)
+ src_map = smp;
+
+ np = lookup(sym, &src_map, 1);
+ if (np == NULL)
+ return NULL;
+
+ /* Fixup jmpslot so future calls transfer directly to target */
+ addr = np->nz_value;
+ if (src_map)
+ addr += (long)src_map->som_addr;
+
+ return (void *)addr;
+}
+
+ static int
+dlctl(fd, cmd, arg)
+ void *fd, *arg;
+ int cmd;
+{
+ switch (cmd) {
+ case DL_GETERRNO:
+ *(int *)arg = dlerrno;
+ return 0;
+ default:
+ dlerrno = EOPNOTSUPP;
+ return -1;
+ }
return 0;
}
diff --git a/libexec/rtld-aout/shlib.c b/libexec/rtld-aout/shlib.c
index 0bfc373..38ec051 100644
--- a/libexec/rtld-aout/shlib.c
+++ b/libexec/rtld-aout/shlib.c
@@ -1,5 +1,33 @@
/*
- * $Id: shlib.c,v 1.6 1993/12/11 11:58:29 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 without 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: shlib.c,v 1.9 1994/01/29 02:03:15 jtc Exp $
*/
#include <sys/param.h>
@@ -25,14 +53,20 @@ char *strsep();
* Standard directories to search for files specified by -l.
*/
#ifndef STANDARD_SEARCH_DIRS
-#define STANDARD_SEARCH_DIRS "/usr/lib"
+#define STANDARD_SEARCH_DIRS "/usr/lib", "/usr/X386/lib", "/usr/local/lib"
#endif
+/*
+ * Actual vector of library search directories,
+ * including `-L'ed and LD_LIBARAY_PATH spec'd ones.
+ */
+char **search_dirs;
+int n_search_dirs;
+
char *standard_search_dirs[] = {
STANDARD_SEARCH_DIRS
};
-int n_search_dirs;
void
add_search_dir(name)
diff --git a/sbin/ldconfig/Makefile b/sbin/ldconfig/Makefile
index d27f9b7..f565cf1 100644
--- a/sbin/ldconfig/Makefile
+++ b/sbin/ldconfig/Makefile
@@ -1,12 +1,12 @@
-# $Id: Makefile,v 1.4 1993/11/09 20:39:46 paul Exp $
+# $Id: Makefile,v 1.7 1993/12/10 05:10:22 mycroft Exp $
PROG= ldconfig
SRCS= ldconfig.c shlib.c etc.c
LDDIR?= $(.CURDIR)/..
-LDFLAGS += -static
-CFLAGS += -I$(LDDIR) -I$(.CURDIR) -I$(LDDIR)/$(MACHINE) -O
-BINDIR= /sbin
-MAN8 = ldconfig.8
+CFLAGS+=-I$(LDDIR) -I$(.CURDIR) -I$(LDDIR)/$(MACHINE)
+LDSTATIC=-static
+BINDIR= /sbin
+MAN8= ldconfig.8
.PATH: $(LDDIR) $(LDDIR)/$(MACHINE)
diff --git a/sbin/ldconfig/ldconfig.8 b/sbin/ldconfig/ldconfig.8
index 78439e5..170b618 100644
--- a/sbin/ldconfig/ldconfig.8
+++ b/sbin/ldconfig/ldconfig.8
@@ -1,6 +1,6 @@
.Dd October 3, 1993
.Dt LDCONFIG 8
-.Os FreeBSD
+.Os FreeBSD 1.1
.Sh NAME
.Nm ldconfig
.Nd configure the shared library cache
diff --git a/sbin/ldconfig/ldconfig.c b/sbin/ldconfig/ldconfig.c
index 899539d..fafe176 100644
--- a/sbin/ldconfig/ldconfig.c
+++ b/sbin/ldconfig/ldconfig.c
@@ -14,7 +14,7 @@
* 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
+ * derived from this software without 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
@@ -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: ldconfig.c,v 1.2 1993/11/09 04:19:22 paul Exp $
+ * $Id: ldconfig.c,v 1.4 1993/12/02 01:03:16 jkh Exp $
*/
#include <sys/param.h>
@@ -72,7 +72,7 @@ struct shlib_list {
static struct shlib_list *shlib_head = NULL, **shlib_tail = &shlib_head;
static void enter __P((char *, char *, char *, int *, int));
-static int dodir __P((char *));
+static int dodir __P((char *, int));
static int build_hints __P((void));
int
@@ -114,10 +114,10 @@ char *argv[];
std_search_dirs(NULL);
for (i = 0; i < n_search_dirs; i++)
- rval |= dodir(search_dirs[i]);
+ rval |= dodir(search_dirs[i], 1);
for (i = optind; i < argc; i++)
- rval |= dodir(argv[i]);
+ rval |= dodir(argv[i], 0);
rval |= build_hints();
@@ -125,8 +125,9 @@ char *argv[];
}
int
-dodir(dir)
+dodir(dir, silent)
char *dir;
+int silent;
{
DIR *dd;
struct dirent *dp;
@@ -134,7 +135,8 @@ char *dir;
int dewey[MAXDEWEY], ndewey;
if ((dd = opendir(dir)) == NULL) {
- perror(dir);
+ if (!silent || errno != ENOENT)
+ perror(dir);
return -1;
}
@@ -314,16 +316,26 @@ build_hints()
return -1;
}
- mywrite(&hdr, 1, sizeof(struct hints_header), fd);
- mywrite(blist, hdr.hh_nbucket, sizeof(struct hints_bucket), fd);
- mywrite(strtab, strtab_sz, 1, fd);
-
+ if (write(fd, &hdr, sizeof(struct hints_header)) !=
+ sizeof(struct hints_header)) {
+ perror(_PATH_LD_HINTS);
+ return -1;
+ }
+ if (write(fd, blist, hdr.hh_nbucket * sizeof(struct hints_bucket)) !=
+ hdr.hh_nbucket * sizeof(struct hints_bucket)) {
+ perror(_PATH_LD_HINTS);
+ return -1;
+ }
+ if (write(fd, strtab, strtab_sz) != strtab_sz) {
+ perror(_PATH_LD_HINTS);
+ return -1;
+ }
if (close(fd) != 0) {
perror(_PATH_LD_HINTS);
return -1;
}
- /* Now, install real file */
+ /* Install it */
if (unlink(_PATH_LD_HINTS) != 0 && errno != ENOENT) {
perror(_PATH_LD_HINTS);
return -1;
diff --git a/usr.bin/ldd/ldd.1 b/usr.bin/ldd/ldd.1
index 0c3b5e4..f5a6aba 100644
--- a/usr.bin/ldd/ldd.1
+++ b/usr.bin/ldd/ldd.1
@@ -1,6 +1,6 @@
.Dd October 22, 1993
.Dt LDD 1
-.Os FreeBSD
+.Os FreeBSD 1.1
.Sh NAME
.Nm ldd
.Nd list dynamic object dependencies
diff --git a/usr.bin/ldd/ldd.c b/usr.bin/ldd/ldd.c
index 65b0bc1..7fba989 100644
--- a/usr.bin/ldd/ldd.c
+++ b/usr.bin/ldd/ldd.c
@@ -14,7 +14,7 @@
* 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
+ * derived from this software without 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
@@ -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: ldd.c,v 1.3 1993/10/31 14:54:29 pk Exp $
+ * $Id: ldd.c,v 1.2 1993/11/09 04:19:27 paul Exp $
*/
#include <sys/param.h>
@@ -107,6 +107,7 @@ char *argv[];
(void)close(fd);
printf("%s:\n", *argv);
+ fflush(stdout);
switch (fork()) {
case -1:
OpenPOWER on IntegriCloud