mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-22 15:47:37 +00:00
Changes from Paul Kranenburg which bring us into sync with his sources:
handling of errors through the standard err() and warn() more fixes for Geoff Rehmet's NULL pointer bug. fixes NULL pointer bugs when linking mono and nested X servers. supports a `-nostdlib' option. accept object files without a symbol table don't attempt dynamic linking when `-A' is given a few variable names have chaged (desc -> fd), and the formatting has changed which should make it much easier to track his sources. I tested 'make world' for /usr/src and X twice with these changes.
This commit is contained in:
parent
33d04130bd
commit
699e1b82fb
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=1741
@ -1,151 +1,66 @@
|
||||
/*
|
||||
* $Id: etc.c,v 1.6 1993/12/11 11:58:22 jkh Exp $
|
||||
* $Id: etc.c,v 1.7 1994/02/13 20:41:05 jkh Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <err.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/time.h>
|
||||
#include <fcntl.h>
|
||||
#include <ar.h>
|
||||
#include <ranlib.h>
|
||||
#include <a.out.h>
|
||||
#include <stab.h>
|
||||
#include <string.h>
|
||||
#if __STDC__
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
|
||||
#include "ld.h"
|
||||
|
||||
/*
|
||||
* Report a nonfatal error.
|
||||
* Like malloc but get fatal error if memory is exhausted.
|
||||
*/
|
||||
|
||||
void
|
||||
#if __STDC__
|
||||
error(char *fmt, ...)
|
||||
#else
|
||||
error(fmt, va_alist)
|
||||
char *fmt;
|
||||
va_dcl
|
||||
#endif
|
||||
void *
|
||||
xmalloc(size)
|
||||
size_t size;
|
||||
{
|
||||
va_list ap;
|
||||
#if __STDC__
|
||||
va_start(ap, fmt);
|
||||
#else
|
||||
va_start(ap);
|
||||
#endif
|
||||
(void)fprintf(stderr, "%s: ", progname);
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
(void)fprintf(stderr, "\n");
|
||||
va_end(ap);
|
||||
register void *result = (void *)malloc(size);
|
||||
|
||||
if (!result)
|
||||
errx(1, "virtual memory exhausted");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void (*fatal_cleanup_hook)__P((void));
|
||||
/*
|
||||
* Report a fatal error.
|
||||
* Like realloc but get fatal error if memory is exhausted.
|
||||
*/
|
||||
|
||||
void
|
||||
#if __STDC__
|
||||
fatal(char *fmt, ...)
|
||||
#else
|
||||
fatal(fmt, va_alist)
|
||||
char *fmt;
|
||||
va_dcl
|
||||
#endif
|
||||
void *
|
||||
xrealloc(ptr, size)
|
||||
void *ptr;
|
||||
size_t size;
|
||||
{
|
||||
va_list ap;
|
||||
#if __STDC__
|
||||
va_start(ap, fmt);
|
||||
#else
|
||||
va_start(ap);
|
||||
#endif
|
||||
(void)fprintf(stderr, "%s: ", progname);
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
(void)fprintf(stderr, "\n");
|
||||
va_end(ap);
|
||||
register void *result;
|
||||
|
||||
if (fatal_cleanup_hook)
|
||||
(*fatal_cleanup_hook)();
|
||||
exit(1);
|
||||
if (ptr == NULL)
|
||||
result = (void *)malloc(size);
|
||||
else
|
||||
result = (void *)realloc(ptr, size);
|
||||
|
||||
if (!result)
|
||||
errx(1, "virtual memory exhausted");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return a newly-allocated string whose contents concatenate
|
||||
* the strings S1, S2, S3.
|
||||
*/
|
||||
|
||||
char *
|
||||
concat(s1, s2, s3)
|
||||
const char *s1, *s2, *s3;
|
||||
{
|
||||
register int len1 = strlen (s1),
|
||||
len2 = strlen (s2),
|
||||
len3 = strlen (s3);
|
||||
register int len1 = strlen(s1),
|
||||
len2 = strlen(s2),
|
||||
len3 = strlen(s3);
|
||||
|
||||
register char *result = (char *) xmalloc (len1 + len2 + len3 + 1);
|
||||
register char *result = (char *)xmalloc(len1 + len2 + len3 + 1);
|
||||
|
||||
strcpy (result, s1);
|
||||
strcpy (result + len1, s2);
|
||||
strcpy (result + len1 + len2, s3);
|
||||
strcpy(result, s1);
|
||||
strcpy(result + len1, s2);
|
||||
strcpy(result + len1 + len2, s3);
|
||||
result[len1 + len2 + len3] = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Parse the string ARG using scanf format FORMAT, and return the result.
|
||||
If it does not parse, report fatal error
|
||||
generating the error message using format string ERROR and ARG as arg. */
|
||||
|
||||
int
|
||||
parse(arg, format, error)
|
||||
char *arg, *format, *error;
|
||||
{
|
||||
int x;
|
||||
if (1 != sscanf (arg, format, &x))
|
||||
fatal (error, arg);
|
||||
return x;
|
||||
}
|
||||
|
||||
/* Like malloc but get fatal error if memory is exhausted. */
|
||||
|
||||
void *
|
||||
xmalloc(size)
|
||||
int size;
|
||||
{
|
||||
register void *result = (void *)malloc (size);
|
||||
|
||||
if (!result)
|
||||
fatal ("virtual memory exhausted", 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Like realloc but get fatal error if memory is exhausted. */
|
||||
|
||||
void *
|
||||
xrealloc(ptr, size)
|
||||
void *ptr;
|
||||
int size;
|
||||
{
|
||||
register void *result;
|
||||
|
||||
if (ptr == NULL)
|
||||
result = (void *)malloc (size);
|
||||
else
|
||||
result = (void *)realloc (ptr, size);
|
||||
|
||||
if (!result)
|
||||
fatal ("virtual memory exhausted", 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -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,13 +27,14 @@
|
||||
* (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.8 1994/01/19 15:00:37 davidg Exp $
|
||||
* $Id: md.c,v 1.9 1994/02/13 20:42:09 jkh Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <a.out.h>
|
||||
#include <stab.h>
|
||||
@ -53,14 +54,13 @@ unsigned char *addr;
|
||||
switch (RELOC_TARGET_SIZE(rp)) {
|
||||
case 0:
|
||||
return get_byte(addr);
|
||||
break;
|
||||
case 1:
|
||||
return get_short(addr);
|
||||
break;
|
||||
case 2:
|
||||
return get_long(addr);
|
||||
break;
|
||||
}
|
||||
errx(1, "Unsupported relocation size: %x", RELOC_TARGET_SIZE(rp));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -71,20 +71,20 @@ md_relocate(rp, relocation, addr, relocatable_output)
|
||||
struct relocation_info *rp;
|
||||
long relocation;
|
||||
unsigned char *addr;
|
||||
int relocatable_output;
|
||||
{
|
||||
switch (RELOC_TARGET_SIZE(rp)) {
|
||||
case 0:
|
||||
put_byte(addr, relocation);
|
||||
break;
|
||||
return;
|
||||
case 1:
|
||||
put_short(addr, relocation);
|
||||
break;
|
||||
return;
|
||||
case 2:
|
||||
put_long(addr, relocation);
|
||||
break;
|
||||
default:
|
||||
fatal("Unsupported relocation size: %x", RELOC_TARGET_SIZE(rp));
|
||||
return;
|
||||
}
|
||||
errx(1, "Unsupported relocation size: %x", RELOC_TARGET_SIZE(rp));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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.8 1994/01/19 15:00:37 davidg Exp $
|
||||
* $Id: md.h,v 1.9 1994/02/13 20:42:11 jkh Exp $
|
||||
*/
|
||||
|
||||
|
||||
|
@ -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.2 1993/11/09 04:19:18 paul Exp $
|
||||
* $Id: mdprologue.S,v 1.3 1993/12/10 10:16:00 jkh Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -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: ld.1,v 1.5 1994/02/13 20:41:22 jkh Exp $
|
||||
.\" $Id: ld.1,v 1.6 1994/03/09 14:28:02 davidg Exp $
|
||||
.\"
|
||||
.Dd October 14, 1993
|
||||
.Dt LD 8
|
||||
@ -103,6 +103,11 @@ Force all members of archives to be loaded, whether or not such members
|
||||
contribute a definition to any plain object files. Useful for making a
|
||||
shared library from an archive of PIC objects without having to unpack
|
||||
the archive.
|
||||
.It Fl B Ar silly
|
||||
Search for
|
||||
.Em \.sa
|
||||
silly archive companions of shared objects. Useful for compatibility with
|
||||
version 3 shared objects.
|
||||
.It Fl D Ar data-size
|
||||
Set the size of the data segment. For sanity's sake, this should be larger
|
||||
than the cumulative data sizes of the input files.
|
||||
|
@ -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: ld.1,v 1.5 1994/02/13 20:41:22 jkh Exp $
|
||||
.\" $Id: ld.1,v 1.6 1994/03/09 14:28:02 davidg Exp $
|
||||
.\"
|
||||
.Dd October 14, 1993
|
||||
.Dt LD 8
|
||||
@ -103,6 +103,11 @@ Force all members of archives to be loaded, whether or not such members
|
||||
contribute a definition to any plain object files. Useful for making a
|
||||
shared library from an archive of PIC objects without having to unpack
|
||||
the archive.
|
||||
.It Fl B Ar silly
|
||||
Search for
|
||||
.Em \.sa
|
||||
silly archive companions of shared objects. Useful for compatibility with
|
||||
version 3 shared objects.
|
||||
.It Fl D Ar data-size
|
||||
Set the size of the data segment. For sanity's sake, this should be larger
|
||||
than the cumulative data sizes of the input files.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: ld.h,v 1.8 1994/01/28 20:56:24 pk Exp $
|
||||
* $Id: ld.h,v 1.10 1994/02/13 20:41:34 jkh Exp $
|
||||
*/
|
||||
/*-
|
||||
* This code is derived from software copyrighted by the Free Software
|
||||
@ -47,13 +47,7 @@
|
||||
/* Align to machine dependent boundary */
|
||||
#define MALIGN(x) PALIGN(x,MAX_ALIGNMENT)
|
||||
|
||||
/* Name this program was invoked by. */
|
||||
char *progname;
|
||||
|
||||
/* System dependencies */
|
||||
|
||||
/* Define this to specify the default executable format. */
|
||||
|
||||
#ifndef DEFAULT_MAGIC
|
||||
#ifdef FreeBSD
|
||||
#define DEFAULT_MAGIC QMAGIC
|
||||
@ -596,20 +590,24 @@ extern int n_search_dirs; /* Length of above. */
|
||||
|
||||
extern int write_map; /* write a load map (`-M') */
|
||||
|
||||
extern void (*fatal_cleanup_hook)__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 *));
|
||||
int set_element_prefixed_p __P((char *));
|
||||
int text_offset __P((struct file_entry *));
|
||||
int file_open __P((struct file_entry *));
|
||||
void each_file __P((void (*)(), void *));
|
||||
void each_full_file __P((void (*)(), void *));
|
||||
unsigned long check_each_file __P((unsigned long (*)(), void *));
|
||||
void mywrite __P((void *, int, int, int));
|
||||
void padfile __P((int,int));
|
||||
|
||||
/* In warnings.c: */
|
||||
void perror_name __P((char *));
|
||||
void perror_file __P((struct file_entry *));
|
||||
void fatal_with_file __P((char *, struct file_entry *, ...));
|
||||
void print_symbols __P((FILE *));
|
||||
char *get_file_name __P((struct file_entry *));
|
||||
void print_file_name __P((struct file_entry *, FILE *));
|
||||
@ -617,13 +615,9 @@ void prline_file_name __P((struct file_entry *, FILE *));
|
||||
int do_warnings __P((FILE *));
|
||||
|
||||
/* In etc.c: */
|
||||
void *xmalloc __P((int));
|
||||
void *xrealloc __P((void *, int));
|
||||
void fatal __P((char *, ...));
|
||||
void error __P((char *, ...));
|
||||
void padfile __P((int,int));
|
||||
void *xmalloc __P((size_t));
|
||||
void *xrealloc __P((void *, size_t));
|
||||
char *concat __P((const char *, const char *, const char *));
|
||||
int parse __P((char *, char *, char *));
|
||||
|
||||
/* In symbol.c: */
|
||||
void symtab_init __P((int));
|
||||
@ -637,7 +631,10 @@ int findlib __P((struct file_entry *));
|
||||
/* In shlib.c: */
|
||||
char *findshlib __P((char *, int *, int *, int));
|
||||
void add_search_dir __P((char *));
|
||||
void std_search_dirs __P((char *));
|
||||
void add_search_path __P((char *));
|
||||
void std_search_path __P((void));
|
||||
int getdewey __P((int[], char *));
|
||||
int cmpndewey __P((int[], int, int[], int));
|
||||
|
||||
/* In rrs.c: */
|
||||
void init_rrs __P((void));
|
||||
@ -654,6 +651,9 @@ long claim_rrs_gotslot __P((struct file_entry *, struct relocation_info *, struc
|
||||
long claim_rrs_internal_gotslot __P((struct file_entry *, struct relocation_info *, struct localsymbol *, long));
|
||||
void claim_rrs_cpy_reloc __P((struct file_entry *, struct relocation_info *, symbol *));
|
||||
void claim_rrs_segment_reloc __P((struct file_entry *, struct relocation_info *));
|
||||
void consider_rrs_section_lengths __P((void));
|
||||
void relocate_rrs_addresses __P((void));
|
||||
void write_rrs __P((void));
|
||||
|
||||
/* In <md>.c */
|
||||
void md_init_header __P((struct exec *, int, int));
|
||||
@ -665,6 +665,7 @@ int md_make_reloc __P((struct relocation_info *, struct relocation_info *, int))
|
||||
void md_make_jmpreloc __P((struct relocation_info *, struct relocation_info *, int));
|
||||
void md_make_gotreloc __P((struct relocation_info *, struct relocation_info *, int));
|
||||
void md_make_copyreloc __P((struct relocation_info *, struct relocation_info *));
|
||||
void md_set_breakpoint __P((long, long *));
|
||||
|
||||
#ifdef NEED_SWAP
|
||||
void md_swapin_exec_hdr __P((struct exec *));
|
||||
|
@ -62,6 +62,8 @@ Do not scan
|
||||
.Sq /usr/lib
|
||||
,
|
||||
.Sq /usr/X386/lib
|
||||
,
|
||||
.Sq /usr/X11R6/lib
|
||||
and
|
||||
.Sq /usr/local/lib
|
||||
for shared libraries.
|
||||
|
@ -27,26 +27,27 @@
|
||||
* (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.5 1994/02/13 20:42:30 jkh Exp $
|
||||
* $Id: ldconfig.c,v 1.6 1994/06/05 19:04:11 ats Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/resource.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <ar.h>
|
||||
#include <ranlib.h>
|
||||
#include <a.out.h>
|
||||
#include <stab.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ld.h"
|
||||
|
||||
@ -74,6 +75,7 @@ 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 *, int));
|
||||
static int build_hints __P((void));
|
||||
static int listhints __P((void));
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
@ -111,7 +113,7 @@ char *argv[];
|
||||
return listhints();
|
||||
|
||||
if (!nostd)
|
||||
std_search_dirs(NULL);
|
||||
std_search_path();
|
||||
|
||||
for (i = 0; i < n_search_dirs; i++)
|
||||
rval |= dodir(search_dirs[i], 1);
|
||||
@ -349,7 +351,7 @@ build_hints()
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
listhints()
|
||||
{
|
||||
int fd;
|
||||
@ -375,7 +377,8 @@ listhints()
|
||||
|
||||
hdr = (struct hints_header *)addr;
|
||||
if (HH_BADMAG(*hdr)) {
|
||||
fprintf(stderr, "%s: Bad magic: %d\n");
|
||||
fprintf(stderr, "%s: Bad magic: %o\n",
|
||||
_PATH_LD_HINTS, hdr->hh_magic);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -27,29 +27,30 @@
|
||||
* (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.2 1993/11/09 04:19:27 paul Exp $
|
||||
* $Id: ldd.c,v 1.3 1994/02/13 20:42:43 jkh Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/wait.h>
|
||||
#include <a.out.h>
|
||||
|
||||
static char *progname;
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void
|
||||
usage()
|
||||
{
|
||||
fprintf(stderr, "Usage: %s <filename> ...\n", progname);
|
||||
extern char *__progname;
|
||||
|
||||
fprintf(stderr, "Usage: %s <filename> ...\n", __progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
@ -57,20 +58,14 @@ main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int rval = 0;
|
||||
int rval;
|
||||
int c;
|
||||
extern int optind;
|
||||
|
||||
if ((progname = strrchr(argv[0], '/')) == NULL)
|
||||
progname = argv[0];
|
||||
else
|
||||
progname++;
|
||||
|
||||
while ((c = getopt(argc, argv, "")) != EOF) {
|
||||
switch (c) {
|
||||
default:
|
||||
usage();
|
||||
exit(1);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
@ -78,27 +73,29 @@ char *argv[];
|
||||
|
||||
if (argc <= 0) {
|
||||
usage();
|
||||
exit(1);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/* ld.so magic */
|
||||
setenv("LD_TRACE_LOADED_OBJECTS", "", 1);
|
||||
|
||||
rval = 0;
|
||||
while (argc--) {
|
||||
int fd;
|
||||
struct exec hdr;
|
||||
int status;
|
||||
|
||||
if ((fd = open(*argv, O_RDONLY, 0)) < 0) {
|
||||
perror(*argv);
|
||||
warn("%s", *argv);
|
||||
rval |= 1;
|
||||
argv++;
|
||||
continue;
|
||||
}
|
||||
if (read(fd, &hdr, sizeof hdr) != sizeof hdr ||
|
||||
!(N_GETFLAG(hdr) & EX_DYNAMIC)) {
|
||||
fprintf(stderr, "%s: not a dynamic executable\n",
|
||||
*argv);
|
||||
!(N_GETFLAG(hdr) & EX_DYNAMIC) ||
|
||||
hdr.a_entry < __LDPGSZ) {
|
||||
|
||||
warnx("%s: not a dynamic executable", *argv);
|
||||
(void)close(fd);
|
||||
rval |= 1;
|
||||
argv++;
|
||||
@ -111,14 +108,13 @@ char *argv[];
|
||||
|
||||
switch (fork()) {
|
||||
case -1:
|
||||
perror("fork");
|
||||
exit(1);
|
||||
err(1, "fork");
|
||||
break;
|
||||
default:
|
||||
if (wait(&status) <= 0)
|
||||
perror("wait");
|
||||
|
||||
if (WIFSIGNALED(status)) {
|
||||
if (wait(&status) <= 0) {
|
||||
warn("wait");
|
||||
rval |= 1;
|
||||
} else if (WIFSIGNALED(status)) {
|
||||
fprintf(stderr, "%s: signal %d\n",
|
||||
*argv, WTERMSIG(status));
|
||||
rval |= 1;
|
||||
@ -129,7 +125,7 @@ char *argv[];
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
rval != execl(*argv, *argv, NULL) != 0;
|
||||
rval |= execl(*argv, *argv, NULL) != 0;
|
||||
perror(*argv);
|
||||
_exit(1);
|
||||
}
|
||||
|
@ -1,14 +1,16 @@
|
||||
/*
|
||||
* $Id: lib.c,v 1.8 1993/12/22 23:28:11 jkh Exp $ - library routines
|
||||
* $Id: lib.c,v 1.9 1994/02/13 20:41:37 jkh Exp $ - library routines
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/time.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <ar.h>
|
||||
#include <ranlib.h>
|
||||
@ -16,6 +18,7 @@
|
||||
#include <stab.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "ld.h"
|
||||
|
||||
@ -26,15 +29,15 @@ static struct file_entry *decode_library_subfile __P((int,
|
||||
int, int *));
|
||||
|
||||
/*
|
||||
* Search the library ENTRY, already open on descriptor DESC. This means
|
||||
* Search the library ENTRY, already open on descriptor FD. This means
|
||||
* deciding which library members to load, making a chain of `struct
|
||||
* file_entry' for those members, and entering their global symbols in the
|
||||
* hash table.
|
||||
*/
|
||||
|
||||
void
|
||||
search_library(desc, entry)
|
||||
int desc;
|
||||
search_library(fd, entry)
|
||||
int fd;
|
||||
struct file_entry *entry;
|
||||
{
|
||||
int member_length;
|
||||
@ -45,7 +48,7 @@ search_library(desc, entry)
|
||||
return;
|
||||
|
||||
/* Examine its first member, which starts SARMAG bytes in. */
|
||||
subentry = decode_library_subfile(desc, entry, SARMAG, &member_length);
|
||||
subentry = decode_library_subfile(fd, entry, SARMAG, &member_length);
|
||||
if (!subentry)
|
||||
return;
|
||||
|
||||
@ -55,21 +58,21 @@ search_library(desc, entry)
|
||||
/* Search via __.SYMDEF if that exists, else linearly. */
|
||||
|
||||
if (!strcmp(name, "__.SYMDEF"))
|
||||
symdef_library(desc, entry, member_length);
|
||||
symdef_library(fd, entry, member_length);
|
||||
else
|
||||
linear_library(desc, entry);
|
||||
linear_library(fd, entry);
|
||||
}
|
||||
|
||||
/*
|
||||
* Construct and return a file_entry for a library member. The library's
|
||||
* file_entry is library_entry, and the library is open on DESC.
|
||||
* file_entry is library_entry, and the library is open on FD.
|
||||
* SUBFILE_OFFSET is the byte index in the library of this member's header.
|
||||
* We store the length of the member into *LENGTH_LOC.
|
||||
*/
|
||||
|
||||
static struct file_entry *
|
||||
decode_library_subfile(desc, library_entry, subfile_offset, length_loc)
|
||||
int desc;
|
||||
decode_library_subfile(fd, library_entry, subfile_offset, length_loc)
|
||||
int fd;
|
||||
struct file_entry *library_entry;
|
||||
int subfile_offset;
|
||||
int *length_loc;
|
||||
@ -82,17 +85,20 @@ decode_library_subfile(desc, library_entry, subfile_offset, length_loc)
|
||||
struct ar_hdr hdr1;
|
||||
register struct file_entry *subentry;
|
||||
|
||||
lseek(desc, subfile_offset, 0);
|
||||
lseek(fd, subfile_offset, 0);
|
||||
|
||||
bytes_read = read(desc, &hdr1, sizeof hdr1);
|
||||
bytes_read = read(fd, &hdr1, sizeof hdr1);
|
||||
if (!bytes_read)
|
||||
return 0; /* end of archive */
|
||||
|
||||
if (sizeof hdr1 != bytes_read)
|
||||
fatal_with_file("malformed library archive ", library_entry);
|
||||
errx(1, "%s: malformed library archive",
|
||||
get_file_name(library_entry));
|
||||
|
||||
if (sscanf(hdr1.ar_size, "%d", &member_length) != 1)
|
||||
fatal_with_file("malformatted header of archive member in ", library_entry);
|
||||
errx(1, "%s: malformatted header of archive member: %.*s",
|
||||
get_file_name(library_entry),
|
||||
sizeof(hdr1.ar_name), hdr1.ar_name);
|
||||
|
||||
subentry = (struct file_entry *) xmalloc(sizeof(struct file_entry));
|
||||
bzero(subentry, sizeof(struct file_entry));
|
||||
@ -116,10 +122,10 @@ decode_library_subfile(desc, library_entry, subfile_offset, length_loc)
|
||||
|
||||
namelen = atoi(&hdr1.ar_name[sizeof(AR_EFMT1) - 1]);
|
||||
name = (char *)xmalloc(namelen + 1);
|
||||
if (read(desc, name, namelen) != namelen)
|
||||
fatal_with_file(
|
||||
"malformatted header of archive member in ",
|
||||
library_entry);
|
||||
if (read(fd, name, namelen) != namelen)
|
||||
errx(1, "%s: malformatted archive member: %.*s",
|
||||
get_file_name(library_entry),
|
||||
sizeof(hdr1.ar_name), hdr1.ar_name);
|
||||
name[namelen] = 0;
|
||||
content_length -= namelen;
|
||||
starting_offset += namelen;
|
||||
@ -134,14 +140,16 @@ decode_library_subfile(desc, library_entry, subfile_offset, length_loc)
|
||||
|
||||
subentry->filename = name;
|
||||
subentry->local_sym_name = name;
|
||||
subentry->starting_offset = starting_offset;
|
||||
subentry->superfile = library_entry;
|
||||
subentry->total_size = content_length;
|
||||
#if 0
|
||||
subentry->symbols = 0;
|
||||
subentry->strings = 0;
|
||||
subentry->subfiles = 0;
|
||||
subentry->starting_offset = starting_offset;
|
||||
subentry->superfile = library_entry;
|
||||
subentry->chain = 0;
|
||||
subentry->flags = 0;
|
||||
subentry->total_size = content_length;
|
||||
#endif
|
||||
|
||||
(*length_loc) = member_length;
|
||||
|
||||
@ -151,15 +159,15 @@ decode_library_subfile(desc, library_entry, subfile_offset, length_loc)
|
||||
static int subfile_wanted_p __P((struct file_entry *));
|
||||
|
||||
/*
|
||||
* Search a library that has a __.SYMDEF member. DESC is a descriptor on
|
||||
* Search a library that has a __.SYMDEF member. FD is a descriptor on
|
||||
* which the library is open. The file pointer is assumed to point at the
|
||||
* __.SYMDEF data. ENTRY is the library's file_entry. MEMBER_LENGTH is the
|
||||
* length of the __.SYMDEF data.
|
||||
*/
|
||||
|
||||
static void
|
||||
symdef_library(desc, entry, member_length)
|
||||
int desc;
|
||||
symdef_library(fd, entry, member_length)
|
||||
int fd;
|
||||
struct file_entry *entry;
|
||||
int member_length;
|
||||
{
|
||||
@ -174,14 +182,16 @@ symdef_library(desc, entry, member_length)
|
||||
struct file_entry *prev = 0;
|
||||
int prev_offset = 0;
|
||||
|
||||
bytes_read = read(desc, symdef_data, member_length);
|
||||
bytes_read = read(fd, symdef_data, member_length);
|
||||
if (bytes_read != member_length)
|
||||
fatal_with_file("malformatted __.SYMDEF in ", entry);
|
||||
errx(1, "%s: malformatted __.SYMDEF",
|
||||
get_file_name(entry));
|
||||
|
||||
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);
|
||||
errx(1, "%s: malformatted __.SYMDEF",
|
||||
get_file_name(entry));
|
||||
|
||||
symdef_base = (struct ranlib *) (symdef_data + 1);
|
||||
length_of_strings = md_swap_long(*(int *) (symdef_base + nsymdefs));
|
||||
@ -189,7 +199,8 @@ symdef_library(desc, entry, member_length)
|
||||
if (length_of_strings < 0
|
||||
|| nsymdefs * sizeof(struct ranlib) + length_of_strings
|
||||
+ 2 * sizeof(int) > member_length)
|
||||
fatal_with_file("malformatted __.SYMDEF in ", entry);
|
||||
errx(1, "%s: malformatted __.SYMDEF",
|
||||
get_file_name(entry));
|
||||
|
||||
sym_name_base = sizeof(int) + (char *) (symdef_base + nsymdefs);
|
||||
|
||||
@ -199,7 +210,8 @@ symdef_library(desc, entry, member_length)
|
||||
register int index = symdef_base[i].ran_un.ran_strx;
|
||||
if (index < 0 || index >= length_of_strings
|
||||
|| (index && *(sym_name_base + index - 1)))
|
||||
fatal_with_file("malformatted __.SYMDEF in ", entry);
|
||||
errx(1, "%s: malformatted __.SYMDEF",
|
||||
get_file_name(entry));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -268,19 +280,19 @@ symdef_library(desc, entry, member_length)
|
||||
* Read the symbol table of the archive member.
|
||||
*/
|
||||
|
||||
subentry = decode_library_subfile(desc,
|
||||
subentry = decode_library_subfile(fd,
|
||||
entry, offset, &junk);
|
||||
if (subentry == 0)
|
||||
fatal(
|
||||
errx(1,
|
||||
"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);
|
||||
read_entry_symbols(fd, subentry);
|
||||
subentry->strings = (char *)
|
||||
malloc(subentry->string_size);
|
||||
read_entry_strings(desc, subentry);
|
||||
alloca(subentry->string_size);
|
||||
read_entry_strings(fd, subentry);
|
||||
|
||||
/*
|
||||
* Now scan the symbol table and decide whether to
|
||||
@ -289,6 +301,7 @@ symdef_library(desc, entry, member_length)
|
||||
|
||||
if (!(link_mode & FORCEARCHIVE) &&
|
||||
!subfile_wanted_p(subentry)) {
|
||||
if (subentry->symbols)
|
||||
free(subentry->symbols);
|
||||
free(subentry);
|
||||
} else {
|
||||
@ -301,7 +314,7 @@ symdef_library(desc, entry, member_length)
|
||||
|
||||
not_finished = 1;
|
||||
|
||||
read_entry_relocation(desc, subentry);
|
||||
read_entry_relocation(fd, subentry);
|
||||
enter_file_symbols(subentry);
|
||||
|
||||
if (prev)
|
||||
@ -320,28 +333,27 @@ symdef_library(desc, entry, member_length)
|
||||
if (symdef_base[j].ran_off == offset)
|
||||
symdef_base[j].ran_un.ran_strx = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We'll read the strings again if we need them
|
||||
* again.
|
||||
* We'll read the strings again
|
||||
* if we need them.
|
||||
*/
|
||||
free(subentry->strings);
|
||||
subentry->strings = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(symdef_data);
|
||||
}
|
||||
|
||||
/*
|
||||
* Search a library that has no __.SYMDEF. ENTRY is the library's file_entry.
|
||||
* DESC is the descriptor it is open on.
|
||||
* FD is the descriptor it is open on.
|
||||
*/
|
||||
|
||||
static void
|
||||
linear_library(desc, entry)
|
||||
int desc;
|
||||
linear_library(fd, entry)
|
||||
int fd;
|
||||
struct file_entry *entry;
|
||||
{
|
||||
register struct file_entry *prev = 0;
|
||||
@ -353,22 +365,23 @@ linear_library(desc, entry)
|
||||
int member_length;
|
||||
register struct file_entry *subentry;
|
||||
|
||||
subentry = decode_library_subfile(desc, entry,
|
||||
subentry = decode_library_subfile(fd, entry,
|
||||
this_subfile_offset, &member_length);
|
||||
|
||||
if (!subentry)
|
||||
return;
|
||||
|
||||
read_entry_symbols(desc, subentry);
|
||||
subentry->strings = (char *) alloca(subentry->string_size);
|
||||
read_entry_strings(desc, subentry);
|
||||
read_entry_symbols(fd, subentry);
|
||||
subentry->strings = (char *)alloca(subentry->string_size);
|
||||
read_entry_strings(fd, subentry);
|
||||
|
||||
if (!(link_mode & FORCEARCHIVE) &&
|
||||
!subfile_wanted_p(subentry)) {
|
||||
if (subentry->symbols)
|
||||
free(subentry->symbols);
|
||||
free(subentry);
|
||||
} else {
|
||||
read_entry_relocation(desc, subentry);
|
||||
read_entry_relocation(fd, subentry);
|
||||
enter_file_symbols(subentry);
|
||||
|
||||
if (prev)
|
||||
@ -527,6 +540,7 @@ subfile_wanted_p(entry)
|
||||
/*
|
||||
* But this member wants it to be
|
||||
* a common; ignore it.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -550,7 +564,9 @@ subfile_wanted_p(entry)
|
||||
|
||||
if (write_map) {
|
||||
print_file_name(entry, stdout);
|
||||
fprintf(stdout, " needed due to shared lib ref %s\n", sp->name);
|
||||
fprintf(stdout,
|
||||
" needed due to shared lib ref %s\n",
|
||||
sp->name);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -561,12 +577,12 @@ subfile_wanted_p(entry)
|
||||
|
||||
/*
|
||||
* Read the symbols of dynamic entity ENTRY into core. Assume it is already
|
||||
* open, on descriptor DESC.
|
||||
* open, on descriptor FD.
|
||||
*/
|
||||
void
|
||||
read_shared_object (desc, entry)
|
||||
read_shared_object(fd, entry)
|
||||
struct file_entry *entry;
|
||||
int desc;
|
||||
int fd;
|
||||
{
|
||||
struct _dynamic dyn;
|
||||
struct section_dispatch_table sdt;
|
||||
@ -575,22 +591,23 @@ read_shared_object (desc, entry)
|
||||
int n, i, has_nz = 0;
|
||||
|
||||
if (!(entry->flags & E_HEADER_VALID))
|
||||
read_header (desc, entry);
|
||||
read_header(fd, entry);
|
||||
|
||||
/* Read DYNAMIC structure (first in data segment) */
|
||||
lseek (desc,
|
||||
text_offset (entry) + entry->header.a_text,
|
||||
L_SET);
|
||||
if (read(desc, &dyn, sizeof dyn) != sizeof dyn) {
|
||||
fatal_with_file (
|
||||
"premature eof in data segment of ", entry);
|
||||
if (lseek(fd, text_offset(entry) + entry->header.a_text, L_SET) ==
|
||||
(off_t)-1)
|
||||
err(1, "%s: lseek", get_file_name(entry));
|
||||
if (read(fd, &dyn, sizeof dyn) != sizeof dyn) {
|
||||
errx(1, "%s: premature EOF reading _dynamic",
|
||||
get_file_name(entry));
|
||||
}
|
||||
md_swapin__dynamic(&dyn);
|
||||
|
||||
/* Check version */
|
||||
switch (dyn.d_version) {
|
||||
default:
|
||||
fatal_with_file( "unsupported _DYNAMIC version ", entry);
|
||||
errx(1, "%s: unsupported _DYNAMIC version: %d",
|
||||
get_file_name(entry), dyn.d_version);
|
||||
break;
|
||||
case LD_VERSION_SUN:
|
||||
break;
|
||||
@ -600,29 +617,33 @@ read_shared_object (desc, entry)
|
||||
}
|
||||
|
||||
/* Read Section Dispatch Table (from data segment) */
|
||||
lseek (desc,
|
||||
if (lseek(fd,
|
||||
text_offset(entry) + (long)dyn.d_un.d_sdt -
|
||||
(DATA_START(entry->header) - N_DATOFF(entry->header)),
|
||||
L_SET);
|
||||
if (read(desc, &sdt, sizeof sdt) != sizeof sdt) {
|
||||
fatal_with_file( "premature eof in data segment of ", entry);
|
||||
}
|
||||
L_SET) == (off_t)-1)
|
||||
err(1, "%s: lseek", get_file_name(entry));
|
||||
if (read(fd, &sdt, sizeof sdt) != sizeof sdt)
|
||||
errx(1, "%s: premature EOF reading sdt",
|
||||
get_file_name(entry));
|
||||
md_swapin_section_dispatch_table(&sdt);
|
||||
|
||||
/* Read symbols (text segment) */
|
||||
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));
|
||||
nzp = (struct nzlist *)(np = (struct nlist *)alloca (n));
|
||||
entry->symbols = (struct localsymbol *)
|
||||
xmalloc(entry->nsymbols * sizeof(struct localsymbol));
|
||||
lseek(desc, text_offset(entry) + (long)sdt.sdt_nzlist -
|
||||
|
||||
if (lseek(fd,
|
||||
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 object symbols ", entry);
|
||||
}
|
||||
L_SET) == (off_t)-1)
|
||||
err(1, "%s: lseek", get_file_name(entry));
|
||||
if (read(fd, (char *)nzp, n) != n)
|
||||
errx(1, "%s: premature EOF reading symbols ",
|
||||
get_file_name(entry));
|
||||
|
||||
if (has_nz)
|
||||
md_swapin_zsymbols(nzp, entry->nsymbols);
|
||||
else
|
||||
@ -645,15 +666,16 @@ read_shared_object (desc, entry)
|
||||
|
||||
/* Read strings (text segment) */
|
||||
n = entry->string_size = sdt.sdt_str_sz;
|
||||
entry->strings = (char *) alloca(n);
|
||||
entry->strings = (char *)alloca(n);
|
||||
entry->strings_offset = text_offset(entry) + sdt.sdt_strings;
|
||||
lseek(desc, entry->strings_offset -
|
||||
if (lseek(fd,
|
||||
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 object strings ", entry);
|
||||
}
|
||||
L_SET) == (off_t)-1)
|
||||
err(1, "%s: lseek", get_file_name(entry));
|
||||
if (read(fd, entry->strings, n) != n)
|
||||
errx(1, "%s: premature EOF reading strings",
|
||||
get_file_name(entry));
|
||||
enter_file_symbols (entry);
|
||||
entry->strings = 0;
|
||||
|
||||
@ -675,19 +697,21 @@ read_shared_object (desc, 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 sod ",
|
||||
entry);
|
||||
}
|
||||
if (lseek(fd,
|
||||
offset - (TEXT_START(entry->header) -
|
||||
N_TXTOFF(entry->header)),
|
||||
L_SET) == (off_t)-1)
|
||||
err(1, "%s: lseek", get_file_name(entry));
|
||||
if (read(fd, &sod, sizeof(sod)) != sizeof(sod))
|
||||
errx(1, "%s: premature EOF reding sod",
|
||||
get_file_name(entry));
|
||||
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 (lseek(fd,
|
||||
(off_t)sod.sod_name - (TEXT_START(entry->header) -
|
||||
N_TXTOFF(entry->header)),
|
||||
L_SET) == (off_t)-1)
|
||||
err(1, "%s: lseek", get_file_name(entry));
|
||||
(void)read(fd, name, sizeof(name)); /*XXX*/
|
||||
if (sod.sod_library) {
|
||||
int sod_major = sod.sod_major;
|
||||
int sod_minor = sod.sod_minor;
|
||||
@ -695,7 +719,7 @@ read_shared_object (desc, entry)
|
||||
libname = findshlib(name,
|
||||
&sod_major, &sod_minor, 0);
|
||||
if (libname == NULL)
|
||||
fatal("no shared -l%s.%d.%d available",
|
||||
errx(1,"no shared -l%s.%d.%d available",
|
||||
name, sod.sod_major, sod.sod_minor);
|
||||
subentry->filename = libname;
|
||||
subentry->local_sym_name = concat("-l", name, "");
|
||||
@ -710,7 +734,7 @@ read_shared_object (desc, entry)
|
||||
else
|
||||
entry->subfiles = subentry;
|
||||
prev = subentry;
|
||||
desc = file_open(entry);
|
||||
fd = file_open(entry);
|
||||
if ((offset = (off_t)sod.sod_next) == 0)
|
||||
break;
|
||||
}
|
||||
@ -746,7 +770,7 @@ read_shared_object (desc, entry)
|
||||
(void)read(fd, armag, SARMAG);
|
||||
(void)close(fd);
|
||||
if (strncmp(armag, ARMAG, SARMAG) != 0) {
|
||||
error("%s: malformed silly archive",
|
||||
warnx("%s: malformed silly archive",
|
||||
get_file_name(entry));
|
||||
goto out;
|
||||
}
|
||||
@ -774,9 +798,8 @@ int
|
||||
findlib(p)
|
||||
struct file_entry *p;
|
||||
{
|
||||
int desc;
|
||||
int i;
|
||||
int len;
|
||||
int fd = -1;
|
||||
int major = -1, minor = -1;
|
||||
char *cp, *fname = NULL;
|
||||
|
||||
@ -785,14 +808,14 @@ struct file_entry *p;
|
||||
|
||||
fname = findshlib(p->filename, &major, &minor, 1);
|
||||
|
||||
if (fname && (desc = open (fname, O_RDONLY, 0)) > 0) {
|
||||
if (fname && (fd = open(fname, O_RDONLY, 0)) > 0) {
|
||||
p->filename = fname;
|
||||
p->lib_major = major;
|
||||
p->lib_minor = minor;
|
||||
p->flags &= ~E_SEARCH_DIRS;
|
||||
return desc;
|
||||
return fd;
|
||||
}
|
||||
free (fname);
|
||||
(void)free(fname);
|
||||
|
||||
dot_a:
|
||||
p->flags &= ~E_SEARCH_DYNAMIC;
|
||||
@ -804,16 +827,17 @@ struct file_entry *p;
|
||||
fname = concat("lib", p->filename, ".a");
|
||||
|
||||
for (i = 0; i < n_search_dirs; i++) {
|
||||
register char *string
|
||||
= concat (search_dirs[i], "/", fname);
|
||||
desc = open (string, O_RDONLY, 0);
|
||||
if (desc > 0) {
|
||||
p->filename = string;
|
||||
register char *path
|
||||
= concat(search_dirs[i], "/", fname);
|
||||
fd = open(path, O_RDONLY, 0);
|
||||
if (fd > 0) {
|
||||
p->filename = path;
|
||||
p->flags &= ~E_SEARCH_DIRS;
|
||||
break;
|
||||
}
|
||||
free (string);
|
||||
(void)free(path);
|
||||
}
|
||||
return desc;
|
||||
(void)free(fname);
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
@ -27,24 +27,25 @@
|
||||
* (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.10 1993/12/11 11:58:28 jkh Exp $
|
||||
* $Id: rrs.c,v 1.11 1994/02/13 20:41:40 jkh Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <ar.h>
|
||||
#include <ranlib.h>
|
||||
#include <a.out.h>
|
||||
#include <stab.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include "ld.h"
|
||||
|
||||
@ -228,7 +229,7 @@ struct localsymbol *lsp;
|
||||
if (!RELOC_EXTERN_P(r)) {
|
||||
|
||||
if (sp != NULL) {
|
||||
error("%s: relocation for internal symbol expected at %#x",
|
||||
warnx("%s: relocation for internal symbol expected at %#x",
|
||||
get_file_name(entry), RELOC_ADDRESS(r));
|
||||
return;
|
||||
}
|
||||
@ -253,7 +254,7 @@ struct localsymbol *lsp;
|
||||
} else {
|
||||
|
||||
if (sp == NULL) {
|
||||
error("%s: relocation must refer to global symbol at %#x",
|
||||
warnx("%s: relocation must refer to global symbol at %#x",
|
||||
get_file_name(entry), RELOC_ADDRESS(r));
|
||||
return;
|
||||
}
|
||||
@ -296,7 +297,7 @@ rrs_next_reloc()
|
||||
|
||||
r = rrs_reloc + claimed_rrs_relocs++;
|
||||
if (claimed_rrs_relocs > reserved_rrs_relocs)
|
||||
fatal("internal error: RRS relocs exceed allocation %d",
|
||||
errx(1, "internal error: RRS relocs exceed allocation %d",
|
||||
reserved_rrs_relocs);
|
||||
return r;
|
||||
}
|
||||
@ -319,7 +320,7 @@ long *relocation;
|
||||
struct relocation_info *r = rrs_next_reloc();
|
||||
|
||||
if (rp->r_address < text_start + text_size)
|
||||
error("%s: RRS text relocation at %#x for \"%s\"",
|
||||
warnx("%s: RRS text relocation at %#x for \"%s\"",
|
||||
get_file_name(entry), rp->r_address, sp->name);
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -330,7 +331,7 @@ printf("claim_rrs_reloc: %s in %s\n", sp->name, get_file_name(entry));
|
||||
|
||||
if (link_mode & SYMBOLIC) {
|
||||
if (!sp->defined)
|
||||
error("Cannot reduce symbol \"%s\" in %s",
|
||||
warnx("Cannot reduce symbol \"%s\" in %s",
|
||||
sp->name, get_file_name(entry));
|
||||
RELOC_EXTERN_P(r) = 0;
|
||||
*relocation += sp->value;
|
||||
@ -358,20 +359,20 @@ long addend;
|
||||
return rrs_sdt.sdt_plt + sp->jmpslot_offset;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("claim_rrs_jmpslot: %s: %s(%d) -> offset %x (textreloc %#x)\n",
|
||||
printf("claim_rrs_jmpslot: %s: %s(%d) -> offset %x\n",
|
||||
get_file_name(entry),
|
||||
sp->name, sp->rrs_symbolnum, sp->jmpslot_offset, text_relocation);
|
||||
sp->name, sp->rrs_symbolnum, sp->jmpslot_offset);
|
||||
#endif
|
||||
|
||||
if (sp->jmpslot_offset == -1)
|
||||
fatal(
|
||||
errx(1,
|
||||
"internal error: %s: claim_rrs_jmpslot: %s: jmpslot_offset == -1\n",
|
||||
get_file_name(entry),
|
||||
sp->name);
|
||||
|
||||
if ((link_mode & SYMBOLIC) || rrs_section_type == RRS_PARTIAL) {
|
||||
if (!sp->defined)
|
||||
error("Cannot reduce symbol \"%s\" in %s",
|
||||
warnx("Cannot reduce symbol \"%s\" in %s",
|
||||
sp->name, get_file_name(entry));
|
||||
|
||||
md_fix_jmpslot( rrs_plt + sp->jmpslot_offset/sizeof(jmpslot_t),
|
||||
@ -439,7 +440,7 @@ printf("claim_rrs_gotslot: %s(%d) slot offset %#x, addend %#x\n",
|
||||
sp->name, sp->rrs_symbolnum, sp->gotslot_offset, addend);
|
||||
#endif
|
||||
if (sp->gotslot_offset == -1)
|
||||
fatal(
|
||||
errx(1,
|
||||
"internal error: %s: claim_rrs_gotslot: %s: gotslot_offset == -1\n",
|
||||
get_file_name(entry), sp->name);
|
||||
|
||||
@ -464,7 +465,7 @@ printf("claim_rrs_gotslot: %s(%d) slot offset %#x, addend %#x\n",
|
||||
* RRS_PARTIAL: we don't link against shared objects,
|
||||
* so again all symbols must be known.
|
||||
*/
|
||||
error("Cannot reduce symbol \"%s\" in %s",
|
||||
warnx("Cannot reduce symbol \"%s\" in %s",
|
||||
sp->name, get_file_name(entry));
|
||||
|
||||
} else {
|
||||
@ -483,7 +484,7 @@ printf("claim_rrs_gotslot: %s(%d) slot offset %#x, addend %#x\n",
|
||||
* NOTE: RRS_PARTIAL implies !SHAREABLE.
|
||||
*/
|
||||
if (!sp->defined)
|
||||
error("Cannot reduce symbol \"%s\" in %s",
|
||||
warnx("Cannot reduce symbol \"%s\" in %s",
|
||||
sp->name, get_file_name(entry));
|
||||
return sp->gotslot_offset;
|
||||
}
|
||||
@ -532,7 +533,7 @@ printf("claim_rrs_internal_gotslot: %s: slot offset %#x, addend = %#x\n",
|
||||
#endif
|
||||
|
||||
if (lsp->gotslot_offset == -1)
|
||||
fatal(
|
||||
errx(1,
|
||||
"internal error: %s: claim_rrs_internal_gotslot at %#x: slot_offset == -1\n",
|
||||
get_file_name(entry), RELOC_ADDRESS(rp));
|
||||
|
||||
@ -568,7 +569,8 @@ symbol *sp;
|
||||
return;
|
||||
|
||||
if (!(sp->flags & GS_CPYRELOCRESERVED))
|
||||
fatal("internal error: %s: claim_cpy_reloc: %s: no reservation\n",
|
||||
errx(1,
|
||||
"internal error: %s: claim_cpy_reloc: %s: no reservation\n",
|
||||
get_file_name(entry), sp->name);
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -652,7 +654,6 @@ consider_rrs_section_lengths()
|
||||
{
|
||||
int n;
|
||||
struct shobj *shp, **shpp;
|
||||
int symbolsize;
|
||||
|
||||
#ifdef notyet
|
||||
/* We run into trouble with this as long as shared object symbols
|
||||
@ -663,7 +664,7 @@ consider_rrs_section_lengths()
|
||||
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");
|
||||
errx(1, "internal error: number_of_shobjs < 0");
|
||||
*shpp = (*shpp)->next;
|
||||
}
|
||||
if (*shpp == NULL)
|
||||
@ -703,7 +704,7 @@ consider_rrs_section_lengths()
|
||||
*/
|
||||
if (!(link_mode & SHAREABLE) &&
|
||||
!(dynamic_symbol->flags & GS_REFERENCED))
|
||||
fatal("No reference to __DYNAMIC");
|
||||
errx(1, "No reference to __DYNAMIC");
|
||||
|
||||
dynamic_symbol->flags |= GS_REFERENCED;
|
||||
|
||||
@ -891,21 +892,21 @@ write_rrs_data()
|
||||
|
||||
pos = rrs_data_start + (N_DATOFF(outheader) - DATA_START(outheader));
|
||||
if (lseek(outdesc, pos, L_SET) != pos)
|
||||
fatal("write_rrs_data: cant position in output file");
|
||||
err(1, "write_rrs_data: lseek");
|
||||
|
||||
if (rrs_section_type == RRS_PARTIAL) {
|
||||
/*
|
||||
* Only a GOT and PLT are needed.
|
||||
*/
|
||||
if (number_of_gotslots <= 1)
|
||||
fatal("write_rrs_data: # gotslots <= 1");
|
||||
errx(1, "write_rrs_data: # gotslots <= 1");
|
||||
|
||||
md_swapout_got(rrs_got, number_of_gotslots);
|
||||
mywrite(rrs_got, number_of_gotslots,
|
||||
sizeof(got_t), outdesc);
|
||||
|
||||
if (number_of_jmpslots <= 1)
|
||||
fatal("write_rrs_data: # jmpslots <= 1");
|
||||
errx(1, "write_rrs_data: # jmpslots <= 1");
|
||||
|
||||
md_swapout_jmpslot(rrs_plt, number_of_jmpslots);
|
||||
mywrite(rrs_plt, number_of_jmpslots,
|
||||
@ -945,7 +946,7 @@ write_rrs_text()
|
||||
|
||||
pos = rrs_text_start + (N_TXTOFF(outheader) - TEXT_START(outheader));
|
||||
if (lseek(outdesc, pos, L_SET) != pos)
|
||||
fatal("write_rrs_text: cant position in output file");
|
||||
err(1, "write_rrs_text: lseek");
|
||||
|
||||
/* Write relocation records */
|
||||
md_swapout_reloc(rrs_reloc, reserved_rrs_relocs);
|
||||
@ -989,7 +990,7 @@ write_rrs_text()
|
||||
|
||||
if ((long)nlp - (long)rrs_symbols >=
|
||||
number_of_rrs_symbols * rrs_symbol_size)
|
||||
fatal(
|
||||
errx(1,
|
||||
"internal error: rrs symbols exceed allocation %d ",
|
||||
number_of_rrs_symbols);
|
||||
|
||||
@ -1040,14 +1041,14 @@ write_rrs_text()
|
||||
* Define a "weak" function symbol.
|
||||
*/
|
||||
if (sp->aux != AUX_FUNC)
|
||||
fatal("%s: non-function jmpslot",
|
||||
errx(1, "%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(
|
||||
errx(1,
|
||||
"internal error: %s defined in mysterious way",
|
||||
sp->name);
|
||||
|
||||
@ -1079,7 +1080,7 @@ write_rrs_text()
|
||||
} END_EACH_SYMBOL;
|
||||
|
||||
if (MALIGN(offset) != rrs_strtab_size)
|
||||
fatal(
|
||||
errx(1,
|
||||
"internal error: inconsistent RRS string table length: %d, expected %d",
|
||||
offset, rrs_strtab_size);
|
||||
|
||||
@ -1103,7 +1104,7 @@ write_rrs_text()
|
||||
char *name = shp->entry->local_sym_name;
|
||||
|
||||
if (i >= number_of_shobjs)
|
||||
fatal("internal error: # of link objects exceeds %d",
|
||||
errx(1, "internal error: # of link objects exceeds %d",
|
||||
number_of_shobjs);
|
||||
|
||||
sodp[i].sod_name = pos;
|
||||
@ -1122,7 +1123,8 @@ write_rrs_text()
|
||||
}
|
||||
|
||||
if (i < number_of_shobjs)
|
||||
fatal("internal error: # of link objects less then expected %d",
|
||||
errx(1,
|
||||
"internal error: # of link objects less then expected %d",
|
||||
number_of_shobjs);
|
||||
|
||||
md_swapout_sod(sodp, number_of_shobjs);
|
||||
@ -1148,7 +1150,7 @@ write_rrs()
|
||||
*/
|
||||
if (rrs_section_type == RRS_NONE) {
|
||||
if (reserved_rrs_relocs > 1)
|
||||
fatal(
|
||||
errx(1,
|
||||
"internal error: RRS relocs in static program: %d",
|
||||
reserved_rrs_relocs-1);
|
||||
return;
|
||||
@ -1159,14 +1161,17 @@ printf("rrs_relocs %d, gotslots %d, jmpslots %d\n",
|
||||
reserved_rrs_relocs, number_of_gotslots-1, number_of_jmpslots-1);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* Must fix this check: misses out when linking PIC code but no
|
||||
shared object involved: reserved relocs are never claimed!
|
||||
*/
|
||||
if (claimed_rrs_relocs != reserved_rrs_relocs) {
|
||||
/*
|
||||
fatal("internal error: reserved relocs(%d) != claimed(%d)",
|
||||
errx(1, "internal error: reserved relocs(%d) != claimed(%d)",
|
||||
reserved_rrs_relocs, claimed_rrs_relocs);
|
||||
*/
|
||||
printf("FIX:internal error: reserved relocs(%d) != claimed(%d)\n",
|
||||
reserved_rrs_relocs, claimed_rrs_relocs);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Write the RRS segments. */
|
||||
write_rrs_text ();
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)malloc.c 5.11 (Berkeley) 2/23/91";*/
|
||||
static char *rcsid = "$Id: malloc.c,v 1.1 1994/01/28 21:01:22 pk Exp $";
|
||||
static char *rcsid = "$Id: malloc.c,v 1.1 1994/02/13 20:44:09 jkh Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/*
|
||||
@ -48,6 +48,7 @@ static char *rcsid = "$Id: malloc.c,v 1.1 1994/01/28 21:01:22 pk Exp $";
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <err.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
@ -460,7 +461,7 @@ int n;
|
||||
caddr_t addr = (caddr_t)
|
||||
(((int)pagepool_start + pagesz - 1) & ~(pagesz - 1));
|
||||
if (munmap(addr, pagepool_end - addr) != 0)
|
||||
perror("munmap");
|
||||
warn("morepages: munmap %p", addr);
|
||||
}
|
||||
|
||||
offset = (int)pagepool_start - ((int)pagepool_start & ~(pagesz - 1));
|
||||
|
@ -27,13 +27,10 @@
|
||||
* (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.15 1994/02/13 20:42:53 jkh Exp $
|
||||
* $Id: rtld.c,v 1.16 1994/04/13 20:52:40 ats Exp $
|
||||
*/
|
||||
|
||||
#include <machine/vmparam.h>
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
@ -43,13 +40,16 @@
|
||||
#include <sys/mman.h>
|
||||
#ifndef BSD
|
||||
#define MAP_COPY MAP_PRIVATE
|
||||
#define MAP_FILE 0
|
||||
#define MAP_ANON 0
|
||||
#endif
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <a.out.h>
|
||||
#include <stab.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#if __STDC__
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
@ -123,34 +123,37 @@ struct somap_private {
|
||||
#define LM_PARENT(smp) (LM_PRIVATE(smp)->spd_parent)
|
||||
|
||||
char **environ;
|
||||
char *__progname;
|
||||
int errno;
|
||||
|
||||
static uid_t uid, euid;
|
||||
static gid_t gid, egid;
|
||||
static int careful;
|
||||
static char *main_progname = "main";
|
||||
static char __main_progname[] = "main";
|
||||
static char *main_progname = __main_progname;
|
||||
static char us[] = "/usr/libexec/ld.so";
|
||||
|
||||
struct so_map *link_map_head, *main_map;
|
||||
struct so_map **link_map_tail = &link_map_head;
|
||||
struct rt_symbol *rt_symbol_head;
|
||||
|
||||
void *dlopen __P((char *, int));
|
||||
int dlclose __P((void *));
|
||||
void *dlsym __P((void *, char *));
|
||||
int dlctl __P((void *, int, void *));
|
||||
static void *__dlopen __P((char *, int));
|
||||
static int __dlclose __P((void *));
|
||||
static void *__dlsym __P((void *, char *));
|
||||
static int __dlctl __P((void *, int, void *));
|
||||
|
||||
struct ld_entry ld_entry = {
|
||||
dlopen, dlclose, dlsym, dlctl
|
||||
static struct ld_entry ld_entry = {
|
||||
__dlopen, __dlclose, __dlsym, __dlctl
|
||||
};
|
||||
|
||||
void xprintf __P((char *, ...));
|
||||
static void init_brk __P((void));
|
||||
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 *,
|
||||
static inline void check_text_reloc __P(( struct relocation_info *,
|
||||
struct so_map *,
|
||||
caddr_t));
|
||||
static void reloc_map __P((struct so_map *));
|
||||
@ -188,7 +191,6 @@ struct _dynamic *dp;
|
||||
int n;
|
||||
int nreloc; /* # of ld.so relocations */
|
||||
struct relocation_info *reloc;
|
||||
char **envp;
|
||||
struct so_debug *ddp;
|
||||
struct so_map *smp;
|
||||
|
||||
@ -217,7 +219,7 @@ struct _dynamic *dp;
|
||||
md_relocate_simple(reloc, crtp->crt_ba, addr);
|
||||
}
|
||||
|
||||
progname = "ld.so";
|
||||
__progname = "ld.so";
|
||||
if (version >= CRT_VERSION_BSD_3)
|
||||
main_progname = crtp->crt_prog;
|
||||
|
||||
@ -237,7 +239,10 @@ struct _dynamic *dp;
|
||||
}
|
||||
|
||||
/* Setup directory search */
|
||||
std_search_dirs(getenv("LD_LIBRARY_PATH"));
|
||||
add_search_path(getenv("LD_RUN_PATH"));
|
||||
add_search_path(getenv("LD_LIBRARY_PATH"));
|
||||
if (getenv("LD_NOSTD_PATH") == NULL)
|
||||
std_search_path();
|
||||
|
||||
/* Load required objects into the process address space */
|
||||
load_objects(crtp, dp);
|
||||
@ -275,12 +280,12 @@ struct _dynamic *dp;
|
||||
/* Set breakpoint for the benefit of debuggers */
|
||||
if (mprotect(addr, PAGSIZ,
|
||||
PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
|
||||
perror("mprotect"),
|
||||
fatal("Cannot set breakpoint (%s)\n", main_progname);
|
||||
err(1, "Cannot set breakpoint (%s)", main_progname);
|
||||
}
|
||||
md_set_breakpoint(crtp->crt_bp, &ddp->dd_bpt_shadow);
|
||||
md_set_breakpoint((long)crtp->crt_bp, (long *)&ddp->dd_bpt_shadow);
|
||||
if (mprotect(addr, PAGSIZ, PROT_READ|PROT_EXEC) == -1) {
|
||||
perror("mprotect");
|
||||
err(1, "Cannot re-protect breakpoint (%s)",
|
||||
main_progname);
|
||||
}
|
||||
|
||||
ddp->dd_bpt_addr = crtp->crt_bp;
|
||||
@ -311,7 +316,7 @@ struct _dynamic *dp;
|
||||
LM_PRIVATE(smp)->spd_flags |= RTLD_MAIN;
|
||||
|
||||
/* Make an entry for ourselves */
|
||||
smp = alloc_link_map("/usr/libexec/ld.so", (struct sod *)0, (struct so_map *)0,
|
||||
smp = alloc_link_map(us, (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;
|
||||
@ -335,12 +340,11 @@ struct _dynamic *dp;
|
||||
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,
|
||||
"%s: lib%s.so.%d.%d" :
|
||||
"%s: %s";
|
||||
err(1, fmt, main_progname, name,
|
||||
sodp->sod_major,
|
||||
sodp->sod_minor,
|
||||
strerror(errno));
|
||||
sodp->sod_minor);
|
||||
}
|
||||
newmap = alloc_link_map(NULL, sodp, smp, 0, 0);
|
||||
}
|
||||
@ -364,17 +368,17 @@ struct _dynamic *dp;
|
||||
path = "not found";
|
||||
|
||||
if (sodp->sod_library)
|
||||
printf("\t-l%s.%d => %s (%#x)\n", name,
|
||||
printf("\t-l%s.%d => %s (%p)\n", name,
|
||||
sodp->sod_major, path, smp->som_addr);
|
||||
else
|
||||
printf("\t%s => %s (%#x)\n", name, path, smp->som_addr);
|
||||
printf("\t%s => %s (%p)\n", name, path, smp->som_addr);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a new link map for an shared object NAME loaded at ADDR as a
|
||||
* Allocate a new link map for shared object NAME loaded at ADDR as a
|
||||
* result of the presence of link object LOP in the link map PARENT.
|
||||
*/
|
||||
static struct so_map *
|
||||
@ -395,7 +399,7 @@ alloc_link_map(path, sodp, parent, addr, dp)
|
||||
link_map_tail = &smp->som_next;
|
||||
|
||||
smp->som_addr = addr;
|
||||
smp->som_path = path;
|
||||
smp->som_path = strdup(path);
|
||||
smp->som_sod = sodp;
|
||||
smp->som_dynamic = dp;
|
||||
smp->som_spd = (caddr_t)smpp;
|
||||
@ -482,6 +486,7 @@ map_object(sodp, smp)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (mmap(addr + hdr.a_text, hdr.a_data,
|
||||
PROT_READ|PROT_WRITE|PROT_EXEC,
|
||||
MAP_FILE|MAP_FIXED|MAP_COPY,
|
||||
@ -489,13 +494,19 @@ map_object(sodp, smp)
|
||||
(void)close(fd);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
if (mprotect(addr + hdr.a_text, hdr.a_data,
|
||||
PROT_READ|PROT_WRITE|PROT_EXEC) != 0) {
|
||||
(void)close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(void)close(fd);
|
||||
|
||||
fd = -1;
|
||||
#ifdef NEED_DEV_ZERO
|
||||
if ((fd = open("/dev/zero", O_RDWR, 0)) == -1)
|
||||
perror("/dev/zero");
|
||||
warn("open: %s", "/dev/zero");
|
||||
#endif
|
||||
if (hdr.a_bss && mmap(addr + hdr.a_text + hdr.a_data, hdr.a_bss,
|
||||
PROT_READ|PROT_WRITE|PROT_EXEC,
|
||||
@ -516,7 +527,7 @@ map_object(sodp, smp)
|
||||
return alloc_link_map(path, sodp, smp, addr, dp);
|
||||
}
|
||||
|
||||
static void inline
|
||||
static inline void
|
||||
check_text_reloc(r, smp, addr)
|
||||
struct relocation_info *r;
|
||||
struct so_map *smp;
|
||||
@ -543,8 +554,7 @@ caddr_t addr;
|
||||
LD_TEXTSZ(smp->som_dynamic),
|
||||
PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
|
||||
|
||||
perror("mprotect"),
|
||||
fatal("Cannot enable writes to %s:%s\n",
|
||||
err(1, "Cannot enable writes to %s:%s",
|
||||
main_progname, smp->som_path);
|
||||
}
|
||||
|
||||
@ -592,7 +602,7 @@ reloc_map(smp)
|
||||
|
||||
np = lookup(sym, &src_map, 0/*XXX-jumpslots!*/);
|
||||
if (np == NULL)
|
||||
fatal("Undefined symbol \"%s\" in %s:%s\n",
|
||||
errx(1, "Undefined symbol \"%s\" in %s:%s\n",
|
||||
sym, main_progname, smp->som_path);
|
||||
|
||||
/*
|
||||
@ -636,8 +646,7 @@ reloc_map(smp)
|
||||
LD_TEXTSZ(smp->som_dynamic),
|
||||
PROT_READ|PROT_EXEC) == -1) {
|
||||
|
||||
perror("mprotect"),
|
||||
fatal("Cannot disable writes to %s:%s\n",
|
||||
err(1, "Cannot disable writes to %s:%s\n",
|
||||
main_progname, smp->som_path);
|
||||
}
|
||||
smp->som_write = 0;
|
||||
@ -681,7 +690,7 @@ static struct rt_symbol *rt_symtab[RTC_TABSIZE];
|
||||
/*
|
||||
* Compute hash value for run-time symbol table
|
||||
*/
|
||||
static int inline
|
||||
static inline int
|
||||
hash_string(key)
|
||||
char *key;
|
||||
{
|
||||
@ -784,7 +793,7 @@ lookup(name, src_map, strong)
|
||||
*/
|
||||
for (smp = link_map_head; smp; smp = smp->som_next) {
|
||||
int buckets = LD_BUCKETS(smp->som_dynamic);
|
||||
long hashval = 0;
|
||||
long hashval;
|
||||
struct rrs_hash *hp;
|
||||
char *cp;
|
||||
struct nzlist *np;
|
||||
@ -801,10 +810,11 @@ lookup(name, src_map, strong)
|
||||
if (*src_map && smp != *src_map)
|
||||
continue;
|
||||
|
||||
restart:
|
||||
/*
|
||||
* Compute bucket in which the symbol might be found.
|
||||
*/
|
||||
for (cp = name; *cp; cp++)
|
||||
for (hashval = 0, cp = name; *cp; cp++)
|
||||
hashval = (hashval << 1) + *cp;
|
||||
|
||||
hashval = (hashval & 0x7fffffff) % buckets;
|
||||
@ -838,6 +848,15 @@ lookup(name, src_map, strong)
|
||||
/*
|
||||
* We have a symbol with the name we're looking for.
|
||||
*/
|
||||
if (np->nz_type == N_INDR+N_EXT) {
|
||||
/*
|
||||
* Next symbol gives the aliased name. Restart
|
||||
* search with new name and confine to this map.
|
||||
*/
|
||||
name = stringbase + (++np)->nz_strx;
|
||||
*src_map = smp;
|
||||
goto restart;
|
||||
}
|
||||
|
||||
if (np->nz_value == 0)
|
||||
/* It's not a definition */
|
||||
@ -902,7 +921,7 @@ binder(jsp)
|
||||
}
|
||||
|
||||
if (smp == NULL)
|
||||
fatal("Call to binder from unknown location: %#x\n", jsp);
|
||||
errx(1, "Call to binder from unknown location: %#x\n", jsp);
|
||||
|
||||
index = jsp->reloc_index & JMPSLOT_RELOC_MASK;
|
||||
|
||||
@ -912,7 +931,7 @@ binder(jsp)
|
||||
|
||||
np = lookup(sym, &src_map, 1);
|
||||
if (np == NULL)
|
||||
fatal("Undefined symbol \"%s\" called from %s:%s at %#x",
|
||||
errx(1, "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 */
|
||||
@ -1074,13 +1093,17 @@ rtfindlib(name, major, minor, usehints)
|
||||
if (hint)
|
||||
return hint;
|
||||
}
|
||||
} else {
|
||||
/* No LD_LIBRARY_PATH, check default */
|
||||
hint = findhint(name, major, minor, NULL);
|
||||
/* Not found in hints, try directory search */
|
||||
hint = (char *)findshlib(name, &major, &minor, 0);
|
||||
if (hint)
|
||||
return hint;
|
||||
}
|
||||
|
||||
/* No LD_LIBRARY_PATH or lib not found in there; check default */
|
||||
hint = findhint(name, major, minor, NULL);
|
||||
if (hint)
|
||||
return hint;
|
||||
|
||||
/* No hints available for name */
|
||||
*usehints = 0;
|
||||
return (char *)findshlib(name, &major, &minor, 0);
|
||||
@ -1107,8 +1130,8 @@ static struct so_map dlmap = {
|
||||
};
|
||||
static int dlerrno;
|
||||
|
||||
void *
|
||||
dlopen(name, mode)
|
||||
static void *
|
||||
__dlopen(name, mode)
|
||||
char *name;
|
||||
int mode;
|
||||
{
|
||||
@ -1126,7 +1149,7 @@ dlopen(name, mode)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sodp->sod_name = (long)name;
|
||||
sodp->sod_name = (long)strdup(name);
|
||||
sodp->sod_library = 0;
|
||||
sodp->sod_major = sodp->sod_minor = 0;
|
||||
|
||||
@ -1148,8 +1171,8 @@ xprintf("%s: %s\n", name, strerror(errno));
|
||||
return smp;
|
||||
}
|
||||
|
||||
int
|
||||
dlclose(fd)
|
||||
static int
|
||||
__dlclose(fd)
|
||||
void *fd;
|
||||
{
|
||||
struct so_map *smp = (struct so_map *)fd;
|
||||
@ -1164,6 +1187,7 @@ xprintf("dlclose(%s): refcount = %d\n", smp->som_path, LM_PRIVATE(smp)->spd_refc
|
||||
init_map(smp, "_fini");
|
||||
#if 0
|
||||
unmap_object(smp);
|
||||
free(smp->som_sod->sod_name);
|
||||
free(smp->som_sod);
|
||||
free(smp);
|
||||
#endif
|
||||
@ -1171,8 +1195,8 @@ xprintf("dlclose(%s): refcount = %d\n", smp->som_path, LM_PRIVATE(smp)->spd_refc
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *
|
||||
dlsym(fd, sym)
|
||||
static void *
|
||||
__dlsym(fd, sym)
|
||||
void *fd;
|
||||
char *sym;
|
||||
{
|
||||
@ -1198,8 +1222,8 @@ dlsym(fd, sym)
|
||||
return (void *)addr;
|
||||
}
|
||||
|
||||
int
|
||||
dlctl(fd, cmd, arg)
|
||||
static int
|
||||
__dlctl(fd, cmd, arg)
|
||||
void *fd, *arg;
|
||||
int cmd;
|
||||
{
|
||||
|
@ -27,7 +27,7 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: shlib.c,v 1.9 1994/01/29 02:03:15 jtc Exp $
|
||||
* $Id: shlib.c,v 1.8 1994/02/13 20:41:43 jkh Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -37,6 +37,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/time.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
@ -53,7 +54,7 @@ char *strsep();
|
||||
* Standard directories to search for files specified by -l.
|
||||
*/
|
||||
#ifndef STANDARD_SEARCH_DIRS
|
||||
#define STANDARD_SEARCH_DIRS "/usr/lib", "/usr/X386/lib", "/usr/local/lib"
|
||||
#define STANDARD_SEARCH_DIRS "/usr/lib", "/usr/X11R6/lib", "/usr/X386/lib", "/usr/local/lib"
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -73,25 +74,32 @@ add_search_dir(name)
|
||||
char *name;
|
||||
{
|
||||
n_search_dirs++;
|
||||
search_dirs = (char **)xrealloc(search_dirs,
|
||||
n_search_dirs * sizeof(char *));
|
||||
search_dirs = (char **)
|
||||
xrealloc(search_dirs, n_search_dirs * sizeof(char *));
|
||||
search_dirs[n_search_dirs - 1] = strdup(name);
|
||||
}
|
||||
|
||||
void
|
||||
std_search_dirs(paths)
|
||||
char *paths;
|
||||
add_search_path(path)
|
||||
char *path;
|
||||
{
|
||||
char *cp;
|
||||
int i, n;
|
||||
register char *cp;
|
||||
|
||||
if (path == NULL)
|
||||
return;
|
||||
|
||||
if (paths != NULL)
|
||||
/* Add search directories from `paths' */
|
||||
while ((cp = strsep(&paths, ":")) != NULL) {
|
||||
while ((cp = strsep(&path, ":")) != NULL) {
|
||||
add_search_dir(cp);
|
||||
if (paths)
|
||||
*(paths-1) = ':';
|
||||
if (path)
|
||||
*(path-1) = ':';
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
std_search_path()
|
||||
{
|
||||
int i, n;
|
||||
|
||||
/* Append standard search directories */
|
||||
n = sizeof standard_search_dirs / sizeof standard_search_dirs[0];
|
||||
@ -137,7 +145,7 @@ cmpndewey(d1, n1, d2, n2)
|
||||
int d1[], d2[];
|
||||
int n1, n2;
|
||||
{
|
||||
int i;
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < n1 && i < n2; i++) {
|
||||
if (d1[i] < d2[i])
|
||||
@ -154,6 +162,9 @@ int n1, n2;
|
||||
|
||||
if (i == n2)
|
||||
return 1;
|
||||
|
||||
errx(1, "cmpndewey: cant happen");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -200,7 +211,7 @@ int do_dot_a;
|
||||
continue;
|
||||
|
||||
while ((dp = readdir(dd)) != NULL) {
|
||||
int n, j, might_take_it = 0;
|
||||
int n, might_take_it = 0;
|
||||
|
||||
if (do_dot_a && path == NULL &&
|
||||
dp->d_namlen == len + 2 &&
|
||||
|
@ -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,15 +27,16 @@
|
||||
* (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/11 12:02:10 jkh Exp $
|
||||
* $Id: md.c,v 1.7 1994/02/13 20:43:03 jkh Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <a.out.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <a.out.h>
|
||||
#include <stab.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -165,7 +166,8 @@ int relocatable_output;
|
||||
*(u_long *) (addr) |= relocation;
|
||||
break;
|
||||
default:
|
||||
fatal( "Unimplemented relocation field length in");
|
||||
errx(1, "Unimplemented relocation field length: %d",
|
||||
RELOC_TARGET_SIZE(r));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,16 +1,16 @@
|
||||
/*
|
||||
* $Id: symbol.c,v 1.3 1993/11/22 19:04:45 jkh Exp $ - symbol table routines
|
||||
* $Id: symbol.c,v 1.4 1994/02/13 20:41:46 jkh Exp $ - symbol table routines
|
||||
*/
|
||||
|
||||
/* Create the symbol table entries for `etext', `edata' and `end'. */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <a.out.h>
|
||||
#include <stab.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ld.h"
|
||||
@ -25,8 +25,8 @@ symbol *got_symbol; /* the symbol __GLOBAL_OFFSET_TABLE_ */
|
||||
symbol *dynamic_symbol; /* the symbol __DYNAMIC */
|
||||
|
||||
void
|
||||
symtab_init (relocatable_output)
|
||||
int relocatable_output;
|
||||
symtab_init(relocatable_output)
|
||||
int relocatable_output;
|
||||
{
|
||||
/*
|
||||
* Put linker reserved symbols into symbol table.
|
||||
@ -45,18 +45,18 @@ int relocatable_output;
|
||||
#define GOT_SYM "_GLOBAL_OFFSET_TABLE_"
|
||||
#endif
|
||||
|
||||
dynamic_symbol = getsym (DYN_SYM);
|
||||
dynamic_symbol = getsym(DYN_SYM);
|
||||
dynamic_symbol->defined = relocatable_output?N_UNDF:(N_DATA | N_EXT);
|
||||
|
||||
got_symbol = getsym (GOT_SYM);
|
||||
got_symbol = getsym(GOT_SYM);
|
||||
got_symbol->defined = N_DATA | N_EXT;
|
||||
|
||||
if (relocatable_output)
|
||||
return;
|
||||
|
||||
etext_symbol = getsym (ETEXT_SYM);
|
||||
edata_symbol = getsym (EDATA_SYM);
|
||||
end_symbol = getsym (END_SYM);
|
||||
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;
|
||||
@ -67,7 +67,9 @@ int relocatable_output;
|
||||
end_symbol->flags |= GS_REFERENCED;
|
||||
}
|
||||
|
||||
/* Compute the hash code for symbol name KEY. */
|
||||
/*
|
||||
* Compute the hash code for symbol name KEY.
|
||||
*/
|
||||
|
||||
int
|
||||
hash_string (key)
|
||||
@ -84,8 +86,10 @@ hash_string (key)
|
||||
return k;
|
||||
}
|
||||
|
||||
/* Get the symbol table entry for the global symbol named KEY.
|
||||
Create one if there is none. */
|
||||
/*
|
||||
* Get the symbol table entry for the global symbol named KEY.
|
||||
* Create one if there is none.
|
||||
*/
|
||||
|
||||
symbol *
|
||||
getsym(key)
|
||||
@ -95,16 +99,16 @@ getsym(key)
|
||||
register symbol *bp;
|
||||
|
||||
/* Determine the proper bucket. */
|
||||
hashval = hash_string (key) % SYMTABSIZE;
|
||||
hashval = hash_string(key) % SYMTABSIZE;
|
||||
|
||||
/* Search the bucket. */
|
||||
for (bp = symtab[hashval]; bp; bp = bp->link)
|
||||
if (! strcmp (key, bp->name))
|
||||
if (strcmp(key, bp->name) == 0)
|
||||
return bp;
|
||||
|
||||
/* Nothing was found; create a new symbol table entry. */
|
||||
bp = (symbol *) xmalloc (sizeof (symbol));
|
||||
bp->name = (char *) xmalloc (strlen (key) + 1);
|
||||
bp = (symbol *)xmalloc(sizeof(symbol));
|
||||
bp->name = (char *)xmalloc(strlen(key) + 1);
|
||||
strcpy (bp->name, key);
|
||||
bp->refs = 0;
|
||||
bp->defined = 0;
|
||||
@ -146,13 +150,11 @@ getsym_soft (key)
|
||||
register symbol *bp;
|
||||
|
||||
/* Determine which bucket. */
|
||||
|
||||
hashval = hash_string (key) % SYMTABSIZE;
|
||||
hashval = hash_string(key) % SYMTABSIZE;
|
||||
|
||||
/* Search the bucket. */
|
||||
|
||||
for (bp = symtab[hashval]; bp; bp = bp->link)
|
||||
if (! strcmp (key, bp->name))
|
||||
if (strcmp(key, bp->name) == 0)
|
||||
return bp;
|
||||
|
||||
return 0;
|
||||
|
@ -1,15 +1,16 @@
|
||||
/*
|
||||
* $Id: warnings.c,v 1.6 1994/02/13 20:41:48 jkh Exp $
|
||||
* $Id: warnings.c,v 1.7 1994/06/14 12:45:41 csgr Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/errno.h>
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <ar.h>
|
||||
#include <ranlib.h>
|
||||
@ -73,83 +74,19 @@ get_file_name (entry)
|
||||
}
|
||||
|
||||
if (entry->superfile) {
|
||||
supfile = get_file_name (entry->superfile);
|
||||
result = (char *) xmalloc (strlen(supfile)
|
||||
+ strlen(entry->filename) + 3);
|
||||
sprintf (result, "%s(%s)", supfile, entry->filename);
|
||||
free (supfile);
|
||||
supfile = get_file_name(entry->superfile);
|
||||
result = (char *)
|
||||
xmalloc(strlen(supfile) + strlen(entry->filename) + 3);
|
||||
(void)sprintf(result, "%s(%s)", supfile, entry->filename);
|
||||
free(supfile);
|
||||
|
||||
} else {
|
||||
result = (char *) xmalloc (strlen (entry->filename) + 1);
|
||||
strcpy (result, entry->filename);
|
||||
result = (char *)xmalloc(strlen(entry->filename) + 1);
|
||||
strcpy(result, entry->filename);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Report a fatal error. The error message is STRING followed by the
|
||||
* filename of ENTRY.
|
||||
*/
|
||||
void
|
||||
#if __STDC__
|
||||
fatal_with_file (char *fmt, struct file_entry *entry, ...)
|
||||
#else
|
||||
fatal_with_file (fmt, entry, va_alist)
|
||||
char *fmt;
|
||||
struct file_entry *entry;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list ap;
|
||||
#if __STDC__
|
||||
va_start(ap, fmt);
|
||||
#else
|
||||
va_start(ap);
|
||||
#endif
|
||||
(void)fprintf(stderr, "%s: ", progname);
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
print_file_name (entry, stderr);
|
||||
(void)fprintf(stderr, "\n");
|
||||
|
||||
va_end(ap);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Report a fatal error using the message for the last failed system call,
|
||||
* followed by the string NAME.
|
||||
*/
|
||||
void
|
||||
perror_name (name)
|
||||
char *name;
|
||||
{
|
||||
char *s;
|
||||
|
||||
if (errno < sys_nerr)
|
||||
s = concat ("", sys_errlist[errno], " for %s");
|
||||
else
|
||||
s = "cannot open %s";
|
||||
fatal (s, name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Report a fatal error using the message for the last failed system call,
|
||||
* followed by the name of file ENTRY.
|
||||
*/
|
||||
void
|
||||
perror_file (entry)
|
||||
struct file_entry *entry;
|
||||
{
|
||||
char *s;
|
||||
|
||||
if (errno < sys_nerr)
|
||||
s = concat ("", sys_errlist[errno], " for ");
|
||||
else
|
||||
s = "cannot open ";
|
||||
fatal_with_file (s, entry);
|
||||
}
|
||||
|
||||
|
||||
/* Print a complete or partial map of the output file. */
|
||||
|
||||
static void describe_file_sections __P((struct file_entry *, FILE *));
|
||||
@ -160,7 +97,7 @@ print_symbols(outfile)
|
||||
FILE *outfile;
|
||||
{
|
||||
fprintf(outfile, "\nFiles:\n\n");
|
||||
each_file(describe_file_sections, outfile);
|
||||
each_file(describe_file_sections, (void *)outfile);
|
||||
|
||||
fprintf(outfile, "\nGlobal symbols:\n\n");
|
||||
FOR_EACH_SYMBOL(i, sp) {
|
||||
@ -178,7 +115,7 @@ print_symbols(outfile)
|
||||
sp->name, sp->value, sp->size);
|
||||
} END_EACH_SYMBOL;
|
||||
|
||||
each_file(list_file_locals, outfile);
|
||||
each_file(list_file_locals, (void *)outfile);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -189,7 +126,7 @@ describe_file_sections(entry, outfile)
|
||||
fprintf(outfile, " ");
|
||||
print_file_name(entry, outfile);
|
||||
if (entry->flags & (E_JUST_SYMS | E_DYNAMIC))
|
||||
fprintf(outfile, " symbols only\n", 0);
|
||||
fprintf(outfile, " symbols only\n");
|
||||
else
|
||||
fprintf(outfile, " text %x(%x), data %x(%x), bss %x(%x) hex\n",
|
||||
entry->text_start_address, entry->header.a_text,
|
||||
@ -255,7 +192,7 @@ struct line_debug_entry
|
||||
relation between the two relocation entries. Used by qsort. */
|
||||
|
||||
static int
|
||||
relocation_entries_relation (rel1, rel2)
|
||||
relocation_entries_relation(rel1, rel2)
|
||||
struct relocation_info *rel1, *rel2;
|
||||
{
|
||||
return RELOC_ADDRESS(rel1) - RELOC_ADDRESS(rel2);
|
||||
@ -269,7 +206,7 @@ relocation_entries_relation (rel1, rel2)
|
||||
state_pointer[1].sym == 0, this routine should not be called. */
|
||||
|
||||
static int
|
||||
next_debug_entry (use_data_symbols, state_pointer)
|
||||
next_debug_entry(use_data_symbols, state_pointer)
|
||||
register int use_data_symbols;
|
||||
/* Next must be passed by reference! */
|
||||
struct line_debug_entry state_pointer[3];
|
||||
@ -397,12 +334,12 @@ address_to_line(address, state_pointer)
|
||||
/* Next must be passed by reference! */
|
||||
struct line_debug_entry state_pointer[3];
|
||||
{
|
||||
struct line_debug_entry
|
||||
*current = state_pointer, *next = state_pointer + 1;
|
||||
struct line_debug_entry *tmp_pointer;
|
||||
|
||||
struct line_debug_entry *current, *next, *tmp_pointer;
|
||||
int use_data_symbols;
|
||||
|
||||
current = state_pointer;
|
||||
next = state_pointer + 1;
|
||||
|
||||
if (next->sym)
|
||||
use_data_symbols =
|
||||
(next->sym->nzlist.nlist.n_type & N_TYPE) == N_DATA;
|
||||
@ -419,6 +356,7 @@ address_to_line(address, state_pointer)
|
||||
state_pointer[2] = tmp_pointer[2];
|
||||
free(tmp_pointer);
|
||||
}
|
||||
|
||||
/* If we're still in a bad way, return -1, meaning invalid line. */
|
||||
if (current->sym->nzlist.nlist.n_value > address)
|
||||
return -1;
|
||||
@ -426,6 +364,7 @@ address_to_line(address, state_pointer)
|
||||
while (next->sym
|
||||
&& next->sym->nzlist.nlist.n_value <= address
|
||||
&& next_debug_entry(use_data_symbols, state_pointer));
|
||||
|
||||
return current->line;
|
||||
}
|
||||
|
||||
@ -486,7 +425,7 @@ do_relocation_warnings(entry, data_segment, outfile, nlist_bitvector)
|
||||
for (reloc = reloc_start;
|
||||
reloc < (reloc_start + reloc_size);
|
||||
reloc++) {
|
||||
register struct localsymbol *s;
|
||||
register struct localsymbol *lsp;
|
||||
register symbol *g;
|
||||
|
||||
/*
|
||||
@ -496,7 +435,7 @@ do_relocation_warnings(entry, data_segment, outfile, nlist_bitvector)
|
||||
if (!RELOC_EXTERN_P(reloc))
|
||||
continue;
|
||||
|
||||
s = &entry->symbols[RELOC_SYMBOL(reloc)];
|
||||
lsp = &entry->symbols[RELOC_SYMBOL(reloc)];
|
||||
|
||||
/*
|
||||
* Local symbols shouldn't ever be used by relocation info,
|
||||
@ -507,17 +446,24 @@ do_relocation_warnings(entry, data_segment, outfile, nlist_bitvector)
|
||||
* assembler would have caught it otherwise), so we can
|
||||
* ignore these cases.
|
||||
*/
|
||||
if (!(s->nzlist.nz_type & N_EXT))
|
||||
|
||||
if ((g = lsp->symbol) == NULL)
|
||||
continue;
|
||||
|
||||
g = s->symbol;
|
||||
if (!(lsp->nzlist.nz_type & N_EXT) &&
|
||||
!SET_ELEMENT_P(lsp->nzlist.nz_type)) {
|
||||
warnx("internal error: `%s' N_EXT not set", g->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
errmsg = 0;
|
||||
|
||||
if (!g->defined && !g->so_defined && list_unresolved_refs) { /* Reference */
|
||||
if (!g->defined && !g->so_defined && list_unresolved_refs) {
|
||||
/* Mark as being noted by relocation warning pass. */
|
||||
SET_BIT(nlist_bitvector, s - start_of_syms);
|
||||
SET_BIT(nlist_bitvector, lsp - start_of_syms);
|
||||
|
||||
if (g->undef_refs >= MAX_UREFS_PRINTED) /* Listed too many */
|
||||
if (g->undef_refs >= MAX_UREFS_PRINTED)
|
||||
/* Listed too many */
|
||||
continue;
|
||||
|
||||
/* Undefined symbol which we should mention */
|
||||
@ -526,7 +472,8 @@ do_relocation_warnings(entry, data_segment, outfile, nlist_bitvector)
|
||||
errfmt = "More undefined symbol %s refs follow";
|
||||
invalidate_line_number = 1;
|
||||
} else {
|
||||
errfmt = "Undefined symbol %s referenced from %s segment";
|
||||
errfmt =
|
||||
"Undefined symbol `%s' referenced from %s segment";
|
||||
invalidate_line_number = 0;
|
||||
}
|
||||
} else { /* Defined */
|
||||
@ -535,7 +482,7 @@ do_relocation_warnings(entry, data_segment, outfile, nlist_bitvector)
|
||||
continue;
|
||||
|
||||
/* Mark as being noted by relocation warning pass. */
|
||||
SET_BIT(nlist_bitvector, s - start_of_syms);
|
||||
SET_BIT(nlist_bitvector, lsp - start_of_syms);
|
||||
|
||||
errfmt = 0;
|
||||
errmsg = g->warning;
|
||||
@ -548,8 +495,9 @@ do_relocation_warnings(entry, data_segment, outfile, nlist_bitvector)
|
||||
char *nm;
|
||||
|
||||
nm = g->name;
|
||||
errmsg = (char *) xmalloc(strlen(errfmt) + strlen(nm) + 1);
|
||||
sprintf(errmsg, errfmt, nm, data_segment ? "data" : "text");
|
||||
errmsg = (char *)
|
||||
xmalloc(strlen(errfmt) + strlen(nm) + 1);
|
||||
sprintf(errmsg, errfmt, nm, data_segment?"data":"text");
|
||||
if (nm != g->name)
|
||||
free(nm);
|
||||
}
|
||||
@ -595,24 +543,25 @@ do_file_warnings (entry, outfile)
|
||||
if (!entry->strings) {
|
||||
int desc;
|
||||
|
||||
entry->strings = (char *) alloca (entry->string_size);
|
||||
desc = file_open (entry);
|
||||
read_entry_strings (desc, entry);
|
||||
entry->strings = (char *)alloca(entry->string_size);
|
||||
desc = file_open(entry);
|
||||
read_entry_strings(desc, entry);
|
||||
}
|
||||
|
||||
if (!(entry->flags & E_DYNAMIC)) {
|
||||
/* Do text warnings based on a scan through the relocation info. */
|
||||
do_relocation_warnings (entry, 0, outfile, nlist_bitvector);
|
||||
/* Do text warnings based on a scan through the reloc info. */
|
||||
do_relocation_warnings(entry, 0, outfile, nlist_bitvector);
|
||||
|
||||
/* Do data warnings based on a scan through the relocation info. */
|
||||
do_relocation_warnings (entry, 1, outfile, nlist_bitvector);
|
||||
/* Do data warnings based on a scan through the reloc info. */
|
||||
do_relocation_warnings(entry, 1, outfile, nlist_bitvector);
|
||||
}
|
||||
|
||||
/* Scan through all of the nlist entries in this file and pick up
|
||||
anything that the scan through the relocation stuff didn't. */
|
||||
|
||||
text_scan = init_debug_scan (0, entry);
|
||||
data_scan = init_debug_scan (1, entry);
|
||||
/*
|
||||
* Scan through all of the nlist entries in this file and pick up
|
||||
* anything that the scan through the relocation stuff didn't.
|
||||
*/
|
||||
text_scan = init_debug_scan(0, entry);
|
||||
data_scan = init_debug_scan(1, entry);
|
||||
|
||||
for (i = 0; i < number_of_syms; i++) {
|
||||
struct nlist *s;
|
||||
@ -630,9 +579,14 @@ do_file_warnings (entry, outfile)
|
||||
if(g == NULL)
|
||||
continue;
|
||||
|
||||
if (!(s->n_type & N_EXT))
|
||||
if (g == NULL)
|
||||
continue;
|
||||
|
||||
if (!(s->n_type & N_EXT) && !SET_ELEMENT_P(s->n_type)) {
|
||||
warnx("internal error: `%s' N_EXT not set", g->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(g->flags & GS_REFERENCED)) {
|
||||
#if 0
|
||||
/* Check for undefined shobj symbols */
|
||||
@ -659,16 +613,18 @@ do_file_warnings (entry, outfile)
|
||||
dont_allow_symbol_name = 0;
|
||||
|
||||
if (list_multiple_defs && g->mult_defs) {
|
||||
errfmt = "Definition of symbol %s (multiply defined)";
|
||||
errfmt = "Definition of symbol `%s' (multiply defined)";
|
||||
switch (s->n_type) {
|
||||
|
||||
case N_TEXT | N_EXT:
|
||||
line_number = address_to_line (s->n_value, text_scan);
|
||||
line_number =
|
||||
address_to_line(s->n_value, text_scan);
|
||||
file_name = text_scan[0].filename;
|
||||
break;
|
||||
|
||||
case N_DATA | N_EXT:
|
||||
line_number = address_to_line (s->n_value, data_scan);
|
||||
line_number =
|
||||
address_to_line(s->n_value, data_scan);
|
||||
file_name = data_scan[0].filename;
|
||||
break;
|
||||
|
||||
@ -678,7 +634,9 @@ do_file_warnings (entry, outfile)
|
||||
case N_SETB | N_EXT:
|
||||
if (g->mult_defs == 2)
|
||||
continue;
|
||||
errfmt = "First set element definition of symbol %s (multiply defined)";
|
||||
errfmt =
|
||||
"First set element definition of symbol %s (multiply defined)";
|
||||
line_number = -1;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -687,9 +645,11 @@ printf("multiply defined: %s, type %#x\n", g->name, s->n_type);
|
||||
continue;
|
||||
}
|
||||
|
||||
} else if (BIT_SET_P (nlist_bitvector, i)) {
|
||||
} else if (BIT_SET_P(nlist_bitvector, i)) {
|
||||
continue;
|
||||
} else if (list_unresolved_refs && !g->defined && !g->so_defined) {
|
||||
} else if (list_unresolved_refs &&
|
||||
!g->defined && !g->so_defined) {
|
||||
|
||||
if (g->undef_refs >= MAX_UREFS_PRINTED)
|
||||
continue;
|
||||
|
||||
@ -705,8 +665,8 @@ printf("multiply defined: %s, type %#x\n", g->name, s->n_type);
|
||||
* do a reference. The second is if it's the reference
|
||||
* used by the warning stabs itself.
|
||||
*/
|
||||
if (s->n_type != (N_EXT | N_UNDF)
|
||||
|| (i && (s-1)->n_type == N_WARNING))
|
||||
if (s->n_type != (N_EXT | N_UNDF) ||
|
||||
(i && (s-1)->n_type == N_WARNING))
|
||||
continue;
|
||||
|
||||
errfmt = g->warning;
|
||||
@ -716,19 +676,19 @@ printf("multiply defined: %s, type %#x\n", g->name, s->n_type);
|
||||
continue;
|
||||
|
||||
if (line_number == -1)
|
||||
fprintf (outfile, "%s: ", entry->filename);
|
||||
fprintf(outfile, "%s: ", entry->filename);
|
||||
else
|
||||
fprintf (outfile, "%s:%d: ", file_name, line_number);
|
||||
fprintf(outfile, "%s:%d: ", file_name, line_number);
|
||||
|
||||
if (dont_allow_symbol_name)
|
||||
fprintf (outfile, "%s", errfmt);
|
||||
fprintf(outfile, "%s", errfmt);
|
||||
else
|
||||
fprintf (outfile, errfmt, g->name);
|
||||
fprintf(outfile, errfmt, g->name);
|
||||
|
||||
fputc ('\n', outfile);
|
||||
fputc('\n', outfile);
|
||||
}
|
||||
free (text_scan);
|
||||
free (data_scan);
|
||||
free(text_scan);
|
||||
free(data_scan);
|
||||
entry->strings = 0; /* Since it will dissapear anyway. */
|
||||
}
|
||||
|
||||
@ -747,9 +707,9 @@ do_warnings(outfile)
|
||||
return 1;
|
||||
|
||||
if (entry_symbol && !entry_symbol->defined)
|
||||
fprintf (outfile, "Undefined entry symbol %s\n",
|
||||
fprintf(outfile, "Undefined entry symbol %s\n",
|
||||
entry_symbol->name);
|
||||
each_file (do_file_warnings, outfile);
|
||||
each_file(do_file_warnings, (void *)outfile);
|
||||
|
||||
if (list_unresolved_refs || list_multiple_defs)
|
||||
return 0;
|
||||
|
@ -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,13 +27,14 @@
|
||||
* (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.8 1994/01/19 15:00:37 davidg Exp $
|
||||
* $Id: md.c,v 1.9 1994/02/13 20:42:09 jkh Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <a.out.h>
|
||||
#include <stab.h>
|
||||
@ -53,14 +54,13 @@ unsigned char *addr;
|
||||
switch (RELOC_TARGET_SIZE(rp)) {
|
||||
case 0:
|
||||
return get_byte(addr);
|
||||
break;
|
||||
case 1:
|
||||
return get_short(addr);
|
||||
break;
|
||||
case 2:
|
||||
return get_long(addr);
|
||||
break;
|
||||
}
|
||||
errx(1, "Unsupported relocation size: %x", RELOC_TARGET_SIZE(rp));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -71,20 +71,20 @@ md_relocate(rp, relocation, addr, relocatable_output)
|
||||
struct relocation_info *rp;
|
||||
long relocation;
|
||||
unsigned char *addr;
|
||||
int relocatable_output;
|
||||
{
|
||||
switch (RELOC_TARGET_SIZE(rp)) {
|
||||
case 0:
|
||||
put_byte(addr, relocation);
|
||||
break;
|
||||
return;
|
||||
case 1:
|
||||
put_short(addr, relocation);
|
||||
break;
|
||||
return;
|
||||
case 2:
|
||||
put_long(addr, relocation);
|
||||
break;
|
||||
default:
|
||||
fatal("Unsupported relocation size: %x", RELOC_TARGET_SIZE(rp));
|
||||
return;
|
||||
}
|
||||
errx(1, "Unsupported relocation size: %x", RELOC_TARGET_SIZE(rp));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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.8 1994/01/19 15:00:37 davidg Exp $
|
||||
* $Id: md.h,v 1.9 1994/02/13 20:42:11 jkh Exp $
|
||||
*/
|
||||
|
||||
|
||||
|
@ -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.2 1993/11/09 04:19:18 paul Exp $
|
||||
* $Id: mdprologue.S,v 1.3 1993/12/10 10:16:00 jkh Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -27,13 +27,10 @@
|
||||
* (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.15 1994/02/13 20:42:53 jkh Exp $
|
||||
* $Id: rtld.c,v 1.16 1994/04/13 20:52:40 ats Exp $
|
||||
*/
|
||||
|
||||
#include <machine/vmparam.h>
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
@ -43,13 +40,16 @@
|
||||
#include <sys/mman.h>
|
||||
#ifndef BSD
|
||||
#define MAP_COPY MAP_PRIVATE
|
||||
#define MAP_FILE 0
|
||||
#define MAP_ANON 0
|
||||
#endif
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <a.out.h>
|
||||
#include <stab.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#if __STDC__
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
@ -123,34 +123,37 @@ struct somap_private {
|
||||
#define LM_PARENT(smp) (LM_PRIVATE(smp)->spd_parent)
|
||||
|
||||
char **environ;
|
||||
char *__progname;
|
||||
int errno;
|
||||
|
||||
static uid_t uid, euid;
|
||||
static gid_t gid, egid;
|
||||
static int careful;
|
||||
static char *main_progname = "main";
|
||||
static char __main_progname[] = "main";
|
||||
static char *main_progname = __main_progname;
|
||||
static char us[] = "/usr/libexec/ld.so";
|
||||
|
||||
struct so_map *link_map_head, *main_map;
|
||||
struct so_map **link_map_tail = &link_map_head;
|
||||
struct rt_symbol *rt_symbol_head;
|
||||
|
||||
void *dlopen __P((char *, int));
|
||||
int dlclose __P((void *));
|
||||
void *dlsym __P((void *, char *));
|
||||
int dlctl __P((void *, int, void *));
|
||||
static void *__dlopen __P((char *, int));
|
||||
static int __dlclose __P((void *));
|
||||
static void *__dlsym __P((void *, char *));
|
||||
static int __dlctl __P((void *, int, void *));
|
||||
|
||||
struct ld_entry ld_entry = {
|
||||
dlopen, dlclose, dlsym, dlctl
|
||||
static struct ld_entry ld_entry = {
|
||||
__dlopen, __dlclose, __dlsym, __dlctl
|
||||
};
|
||||
|
||||
void xprintf __P((char *, ...));
|
||||
static void init_brk __P((void));
|
||||
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 *,
|
||||
static inline void check_text_reloc __P(( struct relocation_info *,
|
||||
struct so_map *,
|
||||
caddr_t));
|
||||
static void reloc_map __P((struct so_map *));
|
||||
@ -188,7 +191,6 @@ struct _dynamic *dp;
|
||||
int n;
|
||||
int nreloc; /* # of ld.so relocations */
|
||||
struct relocation_info *reloc;
|
||||
char **envp;
|
||||
struct so_debug *ddp;
|
||||
struct so_map *smp;
|
||||
|
||||
@ -217,7 +219,7 @@ struct _dynamic *dp;
|
||||
md_relocate_simple(reloc, crtp->crt_ba, addr);
|
||||
}
|
||||
|
||||
progname = "ld.so";
|
||||
__progname = "ld.so";
|
||||
if (version >= CRT_VERSION_BSD_3)
|
||||
main_progname = crtp->crt_prog;
|
||||
|
||||
@ -237,7 +239,10 @@ struct _dynamic *dp;
|
||||
}
|
||||
|
||||
/* Setup directory search */
|
||||
std_search_dirs(getenv("LD_LIBRARY_PATH"));
|
||||
add_search_path(getenv("LD_RUN_PATH"));
|
||||
add_search_path(getenv("LD_LIBRARY_PATH"));
|
||||
if (getenv("LD_NOSTD_PATH") == NULL)
|
||||
std_search_path();
|
||||
|
||||
/* Load required objects into the process address space */
|
||||
load_objects(crtp, dp);
|
||||
@ -275,12 +280,12 @@ struct _dynamic *dp;
|
||||
/* Set breakpoint for the benefit of debuggers */
|
||||
if (mprotect(addr, PAGSIZ,
|
||||
PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
|
||||
perror("mprotect"),
|
||||
fatal("Cannot set breakpoint (%s)\n", main_progname);
|
||||
err(1, "Cannot set breakpoint (%s)", main_progname);
|
||||
}
|
||||
md_set_breakpoint(crtp->crt_bp, &ddp->dd_bpt_shadow);
|
||||
md_set_breakpoint((long)crtp->crt_bp, (long *)&ddp->dd_bpt_shadow);
|
||||
if (mprotect(addr, PAGSIZ, PROT_READ|PROT_EXEC) == -1) {
|
||||
perror("mprotect");
|
||||
err(1, "Cannot re-protect breakpoint (%s)",
|
||||
main_progname);
|
||||
}
|
||||
|
||||
ddp->dd_bpt_addr = crtp->crt_bp;
|
||||
@ -311,7 +316,7 @@ struct _dynamic *dp;
|
||||
LM_PRIVATE(smp)->spd_flags |= RTLD_MAIN;
|
||||
|
||||
/* Make an entry for ourselves */
|
||||
smp = alloc_link_map("/usr/libexec/ld.so", (struct sod *)0, (struct so_map *)0,
|
||||
smp = alloc_link_map(us, (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;
|
||||
@ -335,12 +340,11 @@ struct _dynamic *dp;
|
||||
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,
|
||||
"%s: lib%s.so.%d.%d" :
|
||||
"%s: %s";
|
||||
err(1, fmt, main_progname, name,
|
||||
sodp->sod_major,
|
||||
sodp->sod_minor,
|
||||
strerror(errno));
|
||||
sodp->sod_minor);
|
||||
}
|
||||
newmap = alloc_link_map(NULL, sodp, smp, 0, 0);
|
||||
}
|
||||
@ -364,17 +368,17 @@ struct _dynamic *dp;
|
||||
path = "not found";
|
||||
|
||||
if (sodp->sod_library)
|
||||
printf("\t-l%s.%d => %s (%#x)\n", name,
|
||||
printf("\t-l%s.%d => %s (%p)\n", name,
|
||||
sodp->sod_major, path, smp->som_addr);
|
||||
else
|
||||
printf("\t%s => %s (%#x)\n", name, path, smp->som_addr);
|
||||
printf("\t%s => %s (%p)\n", name, path, smp->som_addr);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a new link map for an shared object NAME loaded at ADDR as a
|
||||
* Allocate a new link map for shared object NAME loaded at ADDR as a
|
||||
* result of the presence of link object LOP in the link map PARENT.
|
||||
*/
|
||||
static struct so_map *
|
||||
@ -395,7 +399,7 @@ alloc_link_map(path, sodp, parent, addr, dp)
|
||||
link_map_tail = &smp->som_next;
|
||||
|
||||
smp->som_addr = addr;
|
||||
smp->som_path = path;
|
||||
smp->som_path = strdup(path);
|
||||
smp->som_sod = sodp;
|
||||
smp->som_dynamic = dp;
|
||||
smp->som_spd = (caddr_t)smpp;
|
||||
@ -482,6 +486,7 @@ map_object(sodp, smp)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (mmap(addr + hdr.a_text, hdr.a_data,
|
||||
PROT_READ|PROT_WRITE|PROT_EXEC,
|
||||
MAP_FILE|MAP_FIXED|MAP_COPY,
|
||||
@ -489,13 +494,19 @@ map_object(sodp, smp)
|
||||
(void)close(fd);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
if (mprotect(addr + hdr.a_text, hdr.a_data,
|
||||
PROT_READ|PROT_WRITE|PROT_EXEC) != 0) {
|
||||
(void)close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(void)close(fd);
|
||||
|
||||
fd = -1;
|
||||
#ifdef NEED_DEV_ZERO
|
||||
if ((fd = open("/dev/zero", O_RDWR, 0)) == -1)
|
||||
perror("/dev/zero");
|
||||
warn("open: %s", "/dev/zero");
|
||||
#endif
|
||||
if (hdr.a_bss && mmap(addr + hdr.a_text + hdr.a_data, hdr.a_bss,
|
||||
PROT_READ|PROT_WRITE|PROT_EXEC,
|
||||
@ -516,7 +527,7 @@ map_object(sodp, smp)
|
||||
return alloc_link_map(path, sodp, smp, addr, dp);
|
||||
}
|
||||
|
||||
static void inline
|
||||
static inline void
|
||||
check_text_reloc(r, smp, addr)
|
||||
struct relocation_info *r;
|
||||
struct so_map *smp;
|
||||
@ -543,8 +554,7 @@ caddr_t addr;
|
||||
LD_TEXTSZ(smp->som_dynamic),
|
||||
PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
|
||||
|
||||
perror("mprotect"),
|
||||
fatal("Cannot enable writes to %s:%s\n",
|
||||
err(1, "Cannot enable writes to %s:%s",
|
||||
main_progname, smp->som_path);
|
||||
}
|
||||
|
||||
@ -592,7 +602,7 @@ reloc_map(smp)
|
||||
|
||||
np = lookup(sym, &src_map, 0/*XXX-jumpslots!*/);
|
||||
if (np == NULL)
|
||||
fatal("Undefined symbol \"%s\" in %s:%s\n",
|
||||
errx(1, "Undefined symbol \"%s\" in %s:%s\n",
|
||||
sym, main_progname, smp->som_path);
|
||||
|
||||
/*
|
||||
@ -636,8 +646,7 @@ reloc_map(smp)
|
||||
LD_TEXTSZ(smp->som_dynamic),
|
||||
PROT_READ|PROT_EXEC) == -1) {
|
||||
|
||||
perror("mprotect"),
|
||||
fatal("Cannot disable writes to %s:%s\n",
|
||||
err(1, "Cannot disable writes to %s:%s\n",
|
||||
main_progname, smp->som_path);
|
||||
}
|
||||
smp->som_write = 0;
|
||||
@ -681,7 +690,7 @@ static struct rt_symbol *rt_symtab[RTC_TABSIZE];
|
||||
/*
|
||||
* Compute hash value for run-time symbol table
|
||||
*/
|
||||
static int inline
|
||||
static inline int
|
||||
hash_string(key)
|
||||
char *key;
|
||||
{
|
||||
@ -784,7 +793,7 @@ lookup(name, src_map, strong)
|
||||
*/
|
||||
for (smp = link_map_head; smp; smp = smp->som_next) {
|
||||
int buckets = LD_BUCKETS(smp->som_dynamic);
|
||||
long hashval = 0;
|
||||
long hashval;
|
||||
struct rrs_hash *hp;
|
||||
char *cp;
|
||||
struct nzlist *np;
|
||||
@ -801,10 +810,11 @@ lookup(name, src_map, strong)
|
||||
if (*src_map && smp != *src_map)
|
||||
continue;
|
||||
|
||||
restart:
|
||||
/*
|
||||
* Compute bucket in which the symbol might be found.
|
||||
*/
|
||||
for (cp = name; *cp; cp++)
|
||||
for (hashval = 0, cp = name; *cp; cp++)
|
||||
hashval = (hashval << 1) + *cp;
|
||||
|
||||
hashval = (hashval & 0x7fffffff) % buckets;
|
||||
@ -838,6 +848,15 @@ lookup(name, src_map, strong)
|
||||
/*
|
||||
* We have a symbol with the name we're looking for.
|
||||
*/
|
||||
if (np->nz_type == N_INDR+N_EXT) {
|
||||
/*
|
||||
* Next symbol gives the aliased name. Restart
|
||||
* search with new name and confine to this map.
|
||||
*/
|
||||
name = stringbase + (++np)->nz_strx;
|
||||
*src_map = smp;
|
||||
goto restart;
|
||||
}
|
||||
|
||||
if (np->nz_value == 0)
|
||||
/* It's not a definition */
|
||||
@ -902,7 +921,7 @@ binder(jsp)
|
||||
}
|
||||
|
||||
if (smp == NULL)
|
||||
fatal("Call to binder from unknown location: %#x\n", jsp);
|
||||
errx(1, "Call to binder from unknown location: %#x\n", jsp);
|
||||
|
||||
index = jsp->reloc_index & JMPSLOT_RELOC_MASK;
|
||||
|
||||
@ -912,7 +931,7 @@ binder(jsp)
|
||||
|
||||
np = lookup(sym, &src_map, 1);
|
||||
if (np == NULL)
|
||||
fatal("Undefined symbol \"%s\" called from %s:%s at %#x",
|
||||
errx(1, "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 */
|
||||
@ -1074,13 +1093,17 @@ rtfindlib(name, major, minor, usehints)
|
||||
if (hint)
|
||||
return hint;
|
||||
}
|
||||
} else {
|
||||
/* No LD_LIBRARY_PATH, check default */
|
||||
hint = findhint(name, major, minor, NULL);
|
||||
/* Not found in hints, try directory search */
|
||||
hint = (char *)findshlib(name, &major, &minor, 0);
|
||||
if (hint)
|
||||
return hint;
|
||||
}
|
||||
|
||||
/* No LD_LIBRARY_PATH or lib not found in there; check default */
|
||||
hint = findhint(name, major, minor, NULL);
|
||||
if (hint)
|
||||
return hint;
|
||||
|
||||
/* No hints available for name */
|
||||
*usehints = 0;
|
||||
return (char *)findshlib(name, &major, &minor, 0);
|
||||
@ -1107,8 +1130,8 @@ static struct so_map dlmap = {
|
||||
};
|
||||
static int dlerrno;
|
||||
|
||||
void *
|
||||
dlopen(name, mode)
|
||||
static void *
|
||||
__dlopen(name, mode)
|
||||
char *name;
|
||||
int mode;
|
||||
{
|
||||
@ -1126,7 +1149,7 @@ dlopen(name, mode)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sodp->sod_name = (long)name;
|
||||
sodp->sod_name = (long)strdup(name);
|
||||
sodp->sod_library = 0;
|
||||
sodp->sod_major = sodp->sod_minor = 0;
|
||||
|
||||
@ -1148,8 +1171,8 @@ xprintf("%s: %s\n", name, strerror(errno));
|
||||
return smp;
|
||||
}
|
||||
|
||||
int
|
||||
dlclose(fd)
|
||||
static int
|
||||
__dlclose(fd)
|
||||
void *fd;
|
||||
{
|
||||
struct so_map *smp = (struct so_map *)fd;
|
||||
@ -1164,6 +1187,7 @@ xprintf("dlclose(%s): refcount = %d\n", smp->som_path, LM_PRIVATE(smp)->spd_refc
|
||||
init_map(smp, "_fini");
|
||||
#if 0
|
||||
unmap_object(smp);
|
||||
free(smp->som_sod->sod_name);
|
||||
free(smp->som_sod);
|
||||
free(smp);
|
||||
#endif
|
||||
@ -1171,8 +1195,8 @@ xprintf("dlclose(%s): refcount = %d\n", smp->som_path, LM_PRIVATE(smp)->spd_refc
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *
|
||||
dlsym(fd, sym)
|
||||
static void *
|
||||
__dlsym(fd, sym)
|
||||
void *fd;
|
||||
char *sym;
|
||||
{
|
||||
@ -1198,8 +1222,8 @@ dlsym(fd, sym)
|
||||
return (void *)addr;
|
||||
}
|
||||
|
||||
int
|
||||
dlctl(fd, cmd, arg)
|
||||
static int
|
||||
__dlctl(fd, cmd, arg)
|
||||
void *fd, *arg;
|
||||
int cmd;
|
||||
{
|
||||
|
@ -27,7 +27,7 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: shlib.c,v 1.9 1994/01/29 02:03:15 jtc Exp $
|
||||
* $Id: shlib.c,v 1.8 1994/02/13 20:41:43 jkh Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -37,6 +37,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/time.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
@ -53,7 +54,7 @@ char *strsep();
|
||||
* Standard directories to search for files specified by -l.
|
||||
*/
|
||||
#ifndef STANDARD_SEARCH_DIRS
|
||||
#define STANDARD_SEARCH_DIRS "/usr/lib", "/usr/X386/lib", "/usr/local/lib"
|
||||
#define STANDARD_SEARCH_DIRS "/usr/lib", "/usr/X11R6/lib", "/usr/X386/lib", "/usr/local/lib"
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -73,25 +74,32 @@ add_search_dir(name)
|
||||
char *name;
|
||||
{
|
||||
n_search_dirs++;
|
||||
search_dirs = (char **)xrealloc(search_dirs,
|
||||
n_search_dirs * sizeof(char *));
|
||||
search_dirs = (char **)
|
||||
xrealloc(search_dirs, n_search_dirs * sizeof(char *));
|
||||
search_dirs[n_search_dirs - 1] = strdup(name);
|
||||
}
|
||||
|
||||
void
|
||||
std_search_dirs(paths)
|
||||
char *paths;
|
||||
add_search_path(path)
|
||||
char *path;
|
||||
{
|
||||
char *cp;
|
||||
int i, n;
|
||||
register char *cp;
|
||||
|
||||
if (path == NULL)
|
||||
return;
|
||||
|
||||
if (paths != NULL)
|
||||
/* Add search directories from `paths' */
|
||||
while ((cp = strsep(&paths, ":")) != NULL) {
|
||||
while ((cp = strsep(&path, ":")) != NULL) {
|
||||
add_search_dir(cp);
|
||||
if (paths)
|
||||
*(paths-1) = ':';
|
||||
if (path)
|
||||
*(path-1) = ':';
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
std_search_path()
|
||||
{
|
||||
int i, n;
|
||||
|
||||
/* Append standard search directories */
|
||||
n = sizeof standard_search_dirs / sizeof standard_search_dirs[0];
|
||||
@ -137,7 +145,7 @@ cmpndewey(d1, n1, d2, n2)
|
||||
int d1[], d2[];
|
||||
int n1, n2;
|
||||
{
|
||||
int i;
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < n1 && i < n2; i++) {
|
||||
if (d1[i] < d2[i])
|
||||
@ -154,6 +162,9 @@ int n1, n2;
|
||||
|
||||
if (i == n2)
|
||||
return 1;
|
||||
|
||||
errx(1, "cmpndewey: cant happen");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -200,7 +211,7 @@ int do_dot_a;
|
||||
continue;
|
||||
|
||||
while ((dp = readdir(dd)) != NULL) {
|
||||
int n, j, might_take_it = 0;
|
||||
int n, might_take_it = 0;
|
||||
|
||||
if (do_dot_a && path == NULL &&
|
||||
dp->d_namlen == len + 2 &&
|
||||
|
@ -62,6 +62,8 @@ Do not scan
|
||||
.Sq /usr/lib
|
||||
,
|
||||
.Sq /usr/X386/lib
|
||||
,
|
||||
.Sq /usr/X11R6/lib
|
||||
and
|
||||
.Sq /usr/local/lib
|
||||
for shared libraries.
|
||||
|
@ -27,26 +27,27 @@
|
||||
* (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.5 1994/02/13 20:42:30 jkh Exp $
|
||||
* $Id: ldconfig.c,v 1.6 1994/06/05 19:04:11 ats Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/resource.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <ar.h>
|
||||
#include <ranlib.h>
|
||||
#include <a.out.h>
|
||||
#include <stab.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ld.h"
|
||||
|
||||
@ -74,6 +75,7 @@ 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 *, int));
|
||||
static int build_hints __P((void));
|
||||
static int listhints __P((void));
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
@ -111,7 +113,7 @@ char *argv[];
|
||||
return listhints();
|
||||
|
||||
if (!nostd)
|
||||
std_search_dirs(NULL);
|
||||
std_search_path();
|
||||
|
||||
for (i = 0; i < n_search_dirs; i++)
|
||||
rval |= dodir(search_dirs[i], 1);
|
||||
@ -349,7 +351,7 @@ build_hints()
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
listhints()
|
||||
{
|
||||
int fd;
|
||||
@ -375,7 +377,8 @@ listhints()
|
||||
|
||||
hdr = (struct hints_header *)addr;
|
||||
if (HH_BADMAG(*hdr)) {
|
||||
fprintf(stderr, "%s: Bad magic: %d\n");
|
||||
fprintf(stderr, "%s: Bad magic: %o\n",
|
||||
_PATH_LD_HINTS, hdr->hh_magic);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -27,29 +27,30 @@
|
||||
* (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.2 1993/11/09 04:19:27 paul Exp $
|
||||
* $Id: ldd.c,v 1.3 1994/02/13 20:42:43 jkh Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/wait.h>
|
||||
#include <a.out.h>
|
||||
|
||||
static char *progname;
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void
|
||||
usage()
|
||||
{
|
||||
fprintf(stderr, "Usage: %s <filename> ...\n", progname);
|
||||
extern char *__progname;
|
||||
|
||||
fprintf(stderr, "Usage: %s <filename> ...\n", __progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
@ -57,20 +58,14 @@ main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int rval = 0;
|
||||
int rval;
|
||||
int c;
|
||||
extern int optind;
|
||||
|
||||
if ((progname = strrchr(argv[0], '/')) == NULL)
|
||||
progname = argv[0];
|
||||
else
|
||||
progname++;
|
||||
|
||||
while ((c = getopt(argc, argv, "")) != EOF) {
|
||||
switch (c) {
|
||||
default:
|
||||
usage();
|
||||
exit(1);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
@ -78,27 +73,29 @@ char *argv[];
|
||||
|
||||
if (argc <= 0) {
|
||||
usage();
|
||||
exit(1);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/* ld.so magic */
|
||||
setenv("LD_TRACE_LOADED_OBJECTS", "", 1);
|
||||
|
||||
rval = 0;
|
||||
while (argc--) {
|
||||
int fd;
|
||||
struct exec hdr;
|
||||
int status;
|
||||
|
||||
if ((fd = open(*argv, O_RDONLY, 0)) < 0) {
|
||||
perror(*argv);
|
||||
warn("%s", *argv);
|
||||
rval |= 1;
|
||||
argv++;
|
||||
continue;
|
||||
}
|
||||
if (read(fd, &hdr, sizeof hdr) != sizeof hdr ||
|
||||
!(N_GETFLAG(hdr) & EX_DYNAMIC)) {
|
||||
fprintf(stderr, "%s: not a dynamic executable\n",
|
||||
*argv);
|
||||
!(N_GETFLAG(hdr) & EX_DYNAMIC) ||
|
||||
hdr.a_entry < __LDPGSZ) {
|
||||
|
||||
warnx("%s: not a dynamic executable", *argv);
|
||||
(void)close(fd);
|
||||
rval |= 1;
|
||||
argv++;
|
||||
@ -111,14 +108,13 @@ char *argv[];
|
||||
|
||||
switch (fork()) {
|
||||
case -1:
|
||||
perror("fork");
|
||||
exit(1);
|
||||
err(1, "fork");
|
||||
break;
|
||||
default:
|
||||
if (wait(&status) <= 0)
|
||||
perror("wait");
|
||||
|
||||
if (WIFSIGNALED(status)) {
|
||||
if (wait(&status) <= 0) {
|
||||
warn("wait");
|
||||
rval |= 1;
|
||||
} else if (WIFSIGNALED(status)) {
|
||||
fprintf(stderr, "%s: signal %d\n",
|
||||
*argv, WTERMSIG(status));
|
||||
rval |= 1;
|
||||
@ -129,7 +125,7 @@ char *argv[];
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
rval != execl(*argv, *argv, NULL) != 0;
|
||||
rval |= execl(*argv, *argv, NULL) != 0;
|
||||
perror(*argv);
|
||||
_exit(1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user