summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libexec/ld.so/Makefile18
-rw-r--r--libexec/ld.so/alpha/ldasm.S28
-rw-r--r--libexec/ld.so/alpha/syscall.h18
-rw-r--r--libexec/ld.so/dir.c269
-rw-r--r--libexec/ld.so/dir.h38
-rw-r--r--libexec/ld.so/library.c308
-rw-r--r--libexec/ld.so/loader.c40
-rw-r--r--libexec/ld.so/mips/syscall.h7
-rw-r--r--libexec/ld.so/powerpc/archdep.h3
-rw-r--r--libexec/ld.so/powerpc/rtld_machine.c9
-rw-r--r--libexec/ld.so/powerpc/syscall.h80
-rw-r--r--libexec/ld.so/sod.c11
-rw-r--r--libexec/ld.so/sod.h36
-rw-r--r--libexec/ld.so/sparc64/archdep.h4
-rw-r--r--libexec/ld.so/sparc64/ldasm.S62
-rw-r--r--libexec/ld.so/sparc64/rtld_machine.c4
-rw-r--r--libexec/ld.so/sparc64/syscall.h19
17 files changed, 822 insertions, 132 deletions
diff --git a/libexec/ld.so/Makefile b/libexec/ld.so/Makefile
index 4f4a37bf7aa..e0f1c1b1128 100644
--- a/libexec/ld.so/Makefile
+++ b/libexec/ld.so/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.14 2002/05/25 02:46:09 drahn Exp $
+# $OpenBSD: Makefile,v 1.15 2002/07/12 20:18:30 drahn Exp $
SUBDIR=ldconfig ldd
VPATH=${.CURDIR}/../../lib/libc/string:${.CURDIR}/../../sys/lib/libsa
@@ -7,8 +7,10 @@ NOMAN=
SRCS= ldasm.S loader.c library.c resolve.c dlfcn.c dl_printf.c rtld_machine.c
SRCS+= util.c
SRCS+= sod.c strsep.c strtol.c
+SRCS+= dir.c
PROG= ld.so
MAN= ld.so.8
+
.if (${MACHINE_ARCH} == "sparc64")
CFLAGS += -fpic -msoft-float
AFLAGS += -fpic
@@ -17,24 +19,24 @@ AFLAGS += -fpic
CFLAGS += -fpic -msoft-float
.endif
.if (${MACHINE_ARCH} == "alpha")
-CFLAGS += -Werror -Wall -Wno-uninitialized
CFLAGS += -fpic -mno-fp-regs
LIBCSRCDIR=${.CURDIR}/../../lib/libc
.include "${LIBCSRCDIR}/arch/alpha/Makefile.inc"
.endif
+
+#CFLAGS += -Werror -Wall -Wno-uninitialized
+CFLAGS += -Werror -Wall
CFLAGS += -I${.CURDIR} -DNO_UNDERSCORE -DVERBOSE_DLINKER \
- -DUSE_CACHE -D__PIC__ -I${.CURDIR}/${MACHINE_ARCH}
-#CFLAGS += -g -DDL_PRINTF_DEBUG
+ -D__PIC__ -I${.CURDIR}/${MACHINE_ARCH} \
+ -Dstrsep=_dl_strsep -Dstrtol=_dl_strtol
INSTALL_STRIP=
.PATH: ${.CURDIR}/${MACHINE_ARCH}
+ELF_LDFLAGS=--shared -Bsymbolic # using GNU ld
.if (${MACHINE_ARCH} == "powerpc")
-#ADDR=-Ttext 21860000 -Tdata 21863000
ADDR=-Tdata 8000
-ELF_LDFLAGS=--shared -Bsymbolic ${ADDR} # using GNU ld
-.else
-ELF_LDFLAGS=--shared -Bsymbolic # using GNU ld
+ELF_LDFLAGS+=${ADDR} # using GNU ld
.endif
$(PROG):
diff --git a/libexec/ld.so/alpha/ldasm.S b/libexec/ld.so/alpha/ldasm.S
index db58dce0ac6..56f04962486 100644
--- a/libexec/ld.so/alpha/ldasm.S
+++ b/libexec/ld.so/alpha/ldasm.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldasm.S,v 1.7 2002/05/24 04:17:00 deraadt Exp $ */
+/* $OpenBSD: ldasm.S,v 1.8 2002/07/12 20:18:30 drahn Exp $ */
/*
* Copyright (c) 2001 Niklas Hallqvist
@@ -264,10 +264,32 @@ LEAF_NOPROFILE(_dl_issetugid, 0)
RET
END(_dl_issetugid)
-#ifdef USE_CACHE
LEAF_NOPROFILE(_dl_stat, 2)
ldiq v0, SYS_stat
call_pal PAL_OSF1_callsys
RET
END(_dl_stat)
-#endif
+
+LEAF_NOPROFILE(_dl__syscall, 3)
+ ldiq v0, SYS___syscall
+ call_pal PAL_OSF1_callsys
+ RET
+END(_dl__syscall)
+
+LEAF_NOPROFILE(_dl_fstat, 2)
+ ldiq v0, SYS_fstat
+ call_pal PAL_OSF1_callsys
+ RET
+END(_dl_fstat)
+
+LEAF_NOPROFILE(_dl_fcntl, 3)
+ ldiq v0, SYS_fcntl
+ call_pal PAL_OSF1_callsys
+ RET
+END(_dl_fcntl)
+
+LEAF_NOPROFILE(_dl_getdirentries, 4)
+ ldiq v0, SYS_getdirentries
+ call_pal PAL_OSF1_callsys
+ RET
+END(_dl_getdirentries)
diff --git a/libexec/ld.so/alpha/syscall.h b/libexec/ld.so/alpha/syscall.h
index 06f257da9b5..9ca72fa02bf 100644
--- a/libexec/ld.so/alpha/syscall.h
+++ b/libexec/ld.so/alpha/syscall.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: syscall.h,v 1.5 2002/03/17 00:22:04 art Exp $ */
+/* $OpenBSD: syscall.h,v 1.6 2002/07/12 20:18:30 drahn Exp $ */
/*
* Copyright (c) 2001 Niklas Hallqvist
@@ -34,9 +34,8 @@
#ifndef __DL_SYSCALL_H__
#define __DL_SYSCALL_H__
-#ifdef USE_CACHE
#include <sys/stat.h>
-#endif
+#include <sys/syscall.h>
#ifndef _dl_MAX_ERRNO
#define _dl_MAX_ERRNO 4096
@@ -52,10 +51,17 @@ int _dl_mprotect(const void *, int, int);
int _dl_munmap(const void*, unsigned int);
int _dl_open(const char*, unsigned int);
int _dl_read(int, const char*, int);
-#ifdef USE_CACHE
int _dl_stat(const char *, struct stat *);
-#endif
int _dl_write(int, const char*, int);
+int _dl_fstat(int, struct stat *);
+int _dl_fcntl(int, int, ...);
+int _dl_getdirentries(int, char*, int, long *);
+long _dl__syscall(quad_t, ...);
+
+static inline off_t
+_dl_lseek(int fildes, off_t offset, int whence)
+{
+ return _dl__syscall((quad_t)SYS_lseek, fildes, 0, offset, whence);
+}
-#include <elf_abi.h>
#endif /*__DL_SYSCALL_H__*/
diff --git a/libexec/ld.so/dir.c b/libexec/ld.so/dir.c
new file mode 100644
index 00000000000..f314ed3acbf
--- /dev/null
+++ b/libexec/ld.so/dir.c
@@ -0,0 +1,269 @@
+/* $OpenBSD: dir.c,v 1.1 2002/07/12 20:18:30 drahn Exp $ */
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = ": opendir.c,v 1.6 1998/08/15 08:10:14 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <syscall.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+
+#include <dirent.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "util.h"
+#include "archdep.h"
+
+long _dl_telldir(const DIR *dirp);
+void _dl_seekdir(DIR *dirp, long loc);
+
+
+/*
+ * Open a directory.
+ */
+DIR *
+_dl_opendir(name)
+ const char *name;
+{
+ DIR *dirp;
+ int fd;
+ struct stat sb;
+ int incr;
+
+ int flags = DTF_HIDEW|DTF_NODUP;
+
+ if ((fd = _dl_open(name, O_RDONLY | O_NONBLOCK)) == -1)
+ return (NULL);
+ if (_dl_fstat(fd, &sb) || !S_ISDIR(sb.st_mode)) {
+ _dl_close(fd);
+ return (NULL);
+ }
+ if (_dl_fcntl(fd, F_SETFD, FD_CLOEXEC) == -1 ||
+ (dirp = (DIR *)_dl_malloc(sizeof(DIR))) == NULL) {
+ _dl_close(fd);
+ return (NULL);
+ }
+
+ /*
+ * If the machine's page size is an exact multiple of DIRBLKSIZ,
+ * use a buffer that is cluster boundary aligned.
+ * Hopefully this can be a big win someday by allowing page trades
+ * to user space to be done by getdirentries()
+ * - not done in ld.so.
+ */
+ incr = DIRBLKSIZ;
+
+ /* UNION mount support removed */
+
+ dirp->dd_len = incr;
+ dirp->dd_buf = _dl_malloc(dirp->dd_len);
+ if (dirp->dd_buf == NULL) {
+ _dl_free(dirp);
+ _dl_close (fd);
+ return (NULL);
+ }
+ dirp->dd_seek = 0;
+ flags &= ~DTF_REWIND;
+
+ dirp->dd_loc = 0;
+ dirp->dd_fd = fd;
+ dirp->dd_flags = flags;
+
+ /*
+ * Set up seek point for rewinddir.
+ */
+ dirp->dd_rewind = _dl_telldir(dirp);
+
+ return (dirp);
+}
+
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$ closedir.c,v 1.3 1998/11/20 11:18:37 d Exp $";
+#endif /* LIBC_SCCS and not lint */
+/*
+ * close a directory.
+ */
+int
+_dl_closedir(dirp)
+ DIR *dirp;
+{
+ int fd;
+ int ret;
+
+ _dl_seekdir(dirp, dirp->dd_rewind); /* free seekdir storage */
+ fd = dirp->dd_fd;
+ dirp->dd_fd = -1;
+ dirp->dd_loc = 0;
+ _dl_free((void *)dirp->dd_buf);
+ _dl_free((void *)dirp);
+ ret = _dl_close(fd);
+ return (ret);
+}
+
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$ readdir.c,v 1.5 2001/05/17 20:20:36 rees Exp $";
+#endif /* LIBC_SCCS and not lint */
+/*
+ * get next entry in a directory.
+ */
+struct dirent *
+_dl_readdir(dirp)
+ DIR *dirp;
+{
+ struct dirent *dp;
+
+ for (;;) {
+ if (dirp->dd_loc >= dirp->dd_size) {
+ if (dirp->dd_flags & __DTF_READALL)
+ return (NULL);
+ dirp->dd_loc = 0;
+ }
+ if (dirp->dd_loc == 0 && !(dirp->dd_flags & __DTF_READALL)) {
+ dirp->dd_size = _dl_getdirentries(dirp->dd_fd,
+ dirp->dd_buf, dirp->dd_len, &dirp->dd_seek);
+ if (dirp->dd_size <= 0)
+ return (NULL);
+ }
+ dp = (struct dirent *)(dirp->dd_buf + dirp->dd_loc);
+ if ((long)dp & 03) /* bogus pointer check */
+ return (NULL);
+ if (dp->d_reclen <= 0 ||
+ dp->d_reclen > dirp->dd_len + 1 - dirp->dd_loc)
+ return (NULL);
+ dirp->dd_loc += dp->d_reclen;
+ if (dp->d_ino == 0)
+ continue;
+ if (dp->d_type == DT_WHT && (dirp->dd_flags & DTF_HIDEW))
+ continue;
+ return (dp);
+ }
+}
+
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$ telldir.c,v 1.2 1996/08/19 08:26:35 tholo Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * The option SINGLEUSE may be defined to say that a telldir
+ * cookie may be used only once before it is freed. This option
+ * is used to avoid having memory usage grow without bound.
+ */
+#define SINGLEUSE
+
+/*
+ * One of these structures is malloced to describe the current directory
+ * position each time telldir is called. It records the current magic
+ * cookie returned by getdirentries and the offset within the buffer
+ * associated with that return value.
+ */
+struct ddloc {
+ struct ddloc *loc_next;/* next structure in list */
+ long loc_index; /* key associated with structure */
+ long loc_seek; /* magic cookie returned by getdirentries */
+ long loc_loc; /* offset of entry in buffer */
+};
+
+#define NDIRHASH 32 /* Num of hash lists, must be a power of 2 */
+#define LOCHASH(i) ((i)&(NDIRHASH-1))
+
+static long dd_loccnt; /* Index of entry for sequential readdir's */
+static struct ddloc *dd_hash[NDIRHASH]; /* Hash list heads for ddlocs */
+
+/*
+ * return a pointer into a directory
+ */
+long
+_dl_telldir(dirp)
+ const DIR *dirp;
+{
+ int index;
+ struct ddloc *lp;
+
+ if ((lp = (struct ddloc *)_dl_malloc(sizeof(struct ddloc))) == NULL)
+ return (-1);
+ index = dd_loccnt++;
+ lp->loc_index = index;
+ lp->loc_seek = dirp->dd_seek;
+ lp->loc_loc = dirp->dd_loc;
+ lp->loc_next = dd_hash[LOCHASH(index)];
+ dd_hash[LOCHASH(index)] = lp;
+ return (index);
+}
+
+/*
+ * seek to an entry in a directory.
+ * Only values returned by "telldir" should be passed to seekdir.
+ */
+void
+_dl_seekdir(dirp, loc)
+ DIR *dirp;
+ long loc;
+{
+ struct ddloc *lp;
+ struct ddloc **prevlp;
+ struct dirent *dp;
+
+ prevlp = &dd_hash[LOCHASH(loc)];
+ lp = *prevlp;
+ while (lp != NULL) {
+ if (lp->loc_index == loc)
+ break;
+ prevlp = &lp->loc_next;
+ lp = lp->loc_next;
+ }
+ if (lp == NULL)
+ return;
+ if (lp->loc_loc == dirp->dd_loc && lp->loc_seek == dirp->dd_seek)
+ goto found;
+ _dl_lseek(dirp->dd_fd, (off_t)lp->loc_seek, SEEK_SET);
+ dirp->dd_seek = lp->loc_seek;
+ dirp->dd_loc = 0;
+ while (dirp->dd_loc < lp->loc_loc) {
+ dp = _dl_readdir(dirp);
+ if (dp == NULL)
+ break;
+ }
+found:
+#ifdef SINGLEUSE
+ *prevlp = lp->loc_next;
+ _dl_free((caddr_t)lp);
+#endif
+}
diff --git a/libexec/ld.so/dir.h b/libexec/ld.so/dir.h
new file mode 100644
index 00000000000..15b87551f0f
--- /dev/null
+++ b/libexec/ld.so/dir.h
@@ -0,0 +1,38 @@
+/* $OpenBSD: dir.h,v 1.1 2002/07/12 20:18:30 drahn Exp $ */
+
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+DIR *_dl_opendir(const char *name);
+int _dl_closedir(DIR *dirp);
+struct dirent *_dl_readdir(DIR *dirp);
diff --git a/libexec/ld.so/library.c b/libexec/ld.so/library.c
index 5eb86c9c54b..ec75bcd1b55 100644
--- a/libexec/ld.so/library.c
+++ b/libexec/ld.so/library.c
@@ -1,6 +1,7 @@
-/* $OpenBSD: library.c,v 1.15 2002/06/05 19:34:44 art Exp $ */
+/* $OpenBSD: library.c,v 1.16 2002/07/12 20:18:30 drahn Exp $ */
/*
+ * Copyright (c) 2002 Dale Rahn
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
*
* Redistribution and use in source and binary forms, with or without
@@ -36,119 +37,287 @@
#include <sys/types.h>
#include <sys/syslimits.h>
+#include <sys/param.h>
#include <fcntl.h>
#include <nlist.h>
#include <link.h>
#include <sys/mman.h>
+#include <dirent.h>
#include "syscall.h"
#include "archdep.h"
#include "resolve.h"
+#include "dir.h"
+#include "sod.h"
+
+#define DEFAULT_PATH "/usr/lib"
#define PFLAGS(X) ((((X) & PF_R) ? PROT_READ : 0) | \
(((X) & PF_W) ? PROT_WRITE : 0) | \
(((X) & PF_X) ? PROT_EXEC : 0))
-elf_object_t *_dl_tryload_shlib(const char *libname, int type);
-void _dl_build_sod(const char *name, struct sod *sodp);
-char *_dl_findhint(char *name, int major, int minor, char *prefered_path);
+static elf_object_t *_dl_tryload_shlib(const char *libname, int type);
+
+/*
+ * _dl_match_file()
+ *
+ * This fucntion determines if a given name matches what is specified
+ * in a struct sod. The major must match exactly, and the minor must
+ * be same or larger.
+ *
+ * sodp is updated with the minor if this matches.
+ */
+
+int
+_dl_match_file(struct sod *sodp, char *name, int namelen)
+{
+ int match;
+ struct sod lsod;
+ char *lname;
+
+ lname = name;
+ if (sodp->sod_library) {
+ if (_dl_strncmp(name, "lib", 3)) {
+ return 0;
+ }
+ lname += 3;
+ }
+ if (_dl_strncmp(lname, (char *)sodp->sod_name,
+ _dl_strlen((char *)sodp->sod_name))) {
+ return 0;
+ }
+
+ _dl_build_sod(name, &lsod);
+
+ match = 0;
+ if ((_dl_strcmp((char *)lsod.sod_name, (char *)sodp->sod_name) == 0) &&
+ (lsod.sod_library == sodp->sod_library) &&
+ (sodp->sod_major == lsod.sod_major) &&
+ ((sodp->sod_minor == -1) ||
+ (lsod.sod_minor >= sodp->sod_minor))) {
+ match = 1;
+
+ /* return version matched */
+ sodp->sod_minor = lsod.sod_minor;
+ }
+ _dl_free((char *)lsod.sod_name);
+
+ return match;
+}
+
+char _dl_hint_store[MAXPATHLEN];
+
+char *
+_dl_find_shlib(struct sod *sodp, const char *searchpath, int nohints)
+{
+ int len;
+ char *hint;
+ char lp[PATH_MAX + 10];
+ char *path;
+ const char *pp;
+ DIR *dd;
+ struct dirent *dp;
+ int match;
+
+ /* if we are to search default directories, and hints
+ * are not to be used, search the standard path from ldconfig
+ * (_dl_hint_search_path) or use the default path
+ */
+ if (nohints)
+ goto nohints;
+
+ if (searchpath == NULL) {
+ /* search 'standard' locations, find any match in the hints */
+ hint = _dl_findhint((char *)sodp->sod_name, sodp->sod_major,
+ sodp->sod_minor, NULL);
+ if (hint)
+ return hint;
+ } else {
+ /* search hints requesting matches for only
+ * the searchpath directories,
+ */
+ pp = searchpath;
+ while (pp) {
+ path = lp;
+ while (path < lp + PATH_MAX &&
+ *pp && *pp != ':' && *pp != ';')
+ *path++ = *pp++;
+ *path = 0;
+
+ hint = _dl_findhint((char *)sodp->sod_name,
+ sodp->sod_major, sodp->sod_minor, lp);
+ if (hint != NULL)
+ return hint;
+
+ if (*pp) /* Try curdir if ':' at end */
+ pp++;
+ else
+ pp = 0;
+ }
+ }
+ /*
+ * For each directory in the searchpath, read the directory
+ * entries looking for a match to sod. filename compare is
+ * done by _dl_match_file()
+ */
+nohints:
+ if (searchpath == NULL) {
+ if (_dl_hint_search_path != NULL)
+ searchpath = _dl_hint_search_path;
+ else
+ searchpath = DEFAULT_PATH;
+ }
+ pp = searchpath;
+ while (pp) {
+ path = lp;
+ while (path < lp + PATH_MAX && *pp && *pp != ':' && *pp != ';')
+ *path++ = *pp++;
+ *path = 0;
+
+ if ((dd = _dl_opendir(lp)) != NULL) {
+ match = 0;
+ while ((dp = _dl_readdir(dd)) != NULL) {
+ if (_dl_match_file(sodp, dp->d_name,
+ dp->d_namlen)) {
+ /* When a match is found, sodp is
+ * updated with the minor found.
+ * We continue looking at this
+ * directory, thus this will find
+ * the largest matching library
+ * in this directory.
+ * we save off the d_name now
+ * so that it doesn't have to be
+ * recreated from the hint.
+ */
+
+ match = 1;
+ len = _dl_strlcpy(_dl_hint_store, lp,
+ MAXPATHLEN);
+ if (lp[len-1] != '/') {
+ _dl_hint_store[len] = '/';
+ len++;
+ }
+ _dl_strlcpy(&_dl_hint_store[len],
+ dp->d_name, MAXPATHLEN-len);
+ }
+ }
+ _dl_closedir(dd);
+ if (match)
+ return (_dl_hint_store);
+ }
+
+ if (*pp) /* Try curdir if ':' at end */
+ pp++;
+ else
+ pp = 0;
+ }
+ return NULL;
+}
/*
* Load a shared object. Search order is:
* If the name contains a '/' use the name exactly as is. (only)
* try the LD_LIBRARY_PATH specification (if present)
+ * search hints for match in LD_LIBRARY_PATH dirs
+ * this will only match specific libary version.
+ * search LD_LIBRARY_PATH dirs for match.
+ * this will find largest minor version in first dir found.
* check DT_RPATH paths, (if present)
- * check /var/run/ld.so.hints cache
- * last look in /usr/lib.
+ * search hints for match in DT_RPATH dirs
+ * this will only match specific libary version.
+ * search DT_RPATH dirs for match.
+ * this will find largest minor version in first dir found.
+ * last look in default search directory, either as specified
+ * by ldconfig or default to '/usr/lib'
*/
elf_object_t *
_dl_load_shlib(const char *libname, elf_object_t *parent, int type)
{
- char lp[PATH_MAX + 10], *hint, *path = lp;
elf_object_t *object;
- const char *pp;
- struct sod sodp;
+ struct sod sod;
+ struct sod req_sod;
+ char *hint;
+ int try_any_minor;
+ int ignore_hints;
+
+ try_any_minor = 0;
+ ignore_hints = 0;
if (_dl_strchr(libname, '/')) {
object = _dl_tryload_shlib(libname, type);
return(object);
}
+
+ _dl_build_sod(libname, &sod);
+ req_sod = sod;
+
+again:
/*
* No '/' in name. Scan the known places, LD_LIBRARY_PATH first.
*/
- pp = _dl_libpath;
- while (pp) {
- const char *ln = libname;
-
- path = lp;
- while (path < lp + PATH_MAX && *pp && *pp != ':' && *pp != ';')
- *path++ = *pp++;
- /* Insert '/' */
- if (path != lp && *(path - 1) != '/')
- *path++ = '/';
-
- while (path < lp + PATH_MAX && (*path++ = *ln++))
- ;
- if (path < lp + PATH_MAX) {
- object = _dl_tryload_shlib(lp, type);
- if (object)
- return(object);
+ if (_dl_libpath != NULL) {
+ hint = _dl_find_shlib(&req_sod, _dl_libpath, ignore_hints);
+ if (hint != NULL) {
+ if (req_sod.sod_minor < sod.sod_minor)
+ _dl_printf("warning: lib%s.so.%d.%d: "
+ "minor version >= %d expected, "
+ "using it anyway",
+ sod.sod_name, sod.sod_major,
+ sod.sod_minor, req_sod.sod_minor);
+ object = _dl_tryload_shlib(hint, type);
+ if (object != NULL) {
+ _dl_free((char *)sod.sod_name);
+ return (object);
+ }
}
- if (*pp) /* Try curdir if ':' at end */
- pp++;
- else
- pp = 0;
}
/*
* Check DT_RPATH.
*/
- pp = parent->dyn.rpath;
- while (pp) {
- const char *ln = libname;
-
- path = lp;
- while (path < lp + PATH_MAX && *pp && *pp != ':')
- *path++ = *pp++;
-
- /* Make sure '/' after dir path */
- if (*(path - 1) != '/')
- *path++ = '/';
-
- while (path < lp + PATH_MAX && (*path++ = *ln++))
- ;
- if (path < lp + PATH_MAX) {
- object = _dl_tryload_shlib(lp, type);
- if (object)
- return(object);
+ if (parent->dyn.rpath != NULL) {
+ hint = _dl_find_shlib(&req_sod, parent->dyn.rpath,
+ ignore_hints);
+ if (hint != NULL) {
+ if (req_sod.sod_minor < sod.sod_minor)
+ _dl_printf("warning: lib%s.so.%d.%d: "
+ "minor version >= %d expected, "
+ "using it anyway",
+ sod.sod_name, sod.sod_major,
+ sod.sod_minor, req_sod.sod_minor);
+ object = _dl_tryload_shlib(hint, type);
+ if (object != NULL) {
+ _dl_free((char *)sod.sod_name);
+ return (object);
+ }
}
- if (*pp) /* Try curdir if ':' at end */
- pp++;
- else
- pp = 0;
}
- _dl_build_sod(libname, &sodp);
- if ((hint = _dl_findhint((char *)sodp.sod_name, sodp.sod_major,
- sodp.sod_minor, NULL)) != NULL) {
+ /* check 'standard' locations */
+ hint = _dl_find_shlib(&req_sod, NULL, ignore_hints);
+ if (hint != NULL) {
+ if (req_sod.sod_minor < sod.sod_minor)
+ _dl_printf("warning: lib%s.so.%d.%d: "
+ "minor version >= %d expected, "
+ "using it anyway",
+ sod.sod_name, sod.sod_major,
+ sod.sod_minor, req_sod.sod_minor);
object = _dl_tryload_shlib(hint, type);
- return(object);
+ if (object != NULL) {
+ _dl_free((char *)sod.sod_name);
+ return(object);
+ }
}
- /*
- * Check '/usr/lib'
- */
- _dl_strlcpy(lp, "/usr/lib/", sizeof(lp));
- path = lp + sizeof("/usr/lib/") - 1;
- while (path < lp + PATH_MAX && (*path++ = *libname++))
- ;
- if (path < lp + PATH_MAX) {
- object = _dl_tryload_shlib(lp, type);
- if (object)
- return(object);
+ if (try_any_minor == 0) {
+ try_any_minor = 1;
+ ignore_hints = 1;
+ req_sod.sod_minor = -1;
+ goto again;
}
+ _dl_free((char *)sod.sod_name);
_dl_errno = DL_NOT_FOUND;
return(0);
}
@@ -165,10 +334,13 @@ _dl_load_list_free(struct load_list *load_list)
}
}
+void _dl_run_dtors(elf_object_t *object);
+
void
_dl_unload_shlib(elf_object_t *object)
{
if (--object->refcount == 0) {
+ _dl_run_dtors(object);
_dl_load_list_free(object->load_list);
_dl_munmap((void *)object->load_addr, object->load_size);
_dl_remove_object(object);
@@ -176,7 +348,7 @@ _dl_unload_shlib(elf_object_t *object)
}
-elf_object_t *
+static elf_object_t *
_dl_tryload_shlib(const char *libname, int type)
{
int libfile, i, align = _dl_pagesz - 1;
diff --git a/libexec/ld.so/loader.c b/libexec/ld.so/loader.c
index 54fd97d995e..9a4648f2c4f 100644
--- a/libexec/ld.so/loader.c
+++ b/libexec/ld.so/loader.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: loader.c,v 1.37 2002/07/07 08:54:50 jufi Exp $ */
+/* $OpenBSD: loader.c,v 1.38 2002/07/12 20:18:30 drahn Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -38,11 +38,13 @@
#include <sys/mman.h>
#include <sys/exec.h>
#include <nlist.h>
+#include <string.h>
#include <link.h>
#include "syscall.h"
#include "archdep.h"
#include "resolve.h"
+#include "sod.h"
/*
* Local decls.
@@ -62,6 +64,8 @@ char *_dl_showmap;
struct r_debug *_dl_debug_map;
+void _dl_dopreload(char *paths);
+
void
_dl_debug_state(void)
{
@@ -90,6 +94,29 @@ _dl_dtors(void)
_dl_run_dtors(_dl_objects->next);
}
+void
+_dl_dopreload(paths)
+ char *paths;
+{
+ char *cp, *dp;
+
+ dp = paths = _dl_strdup(paths);
+ if (dp == NULL) {
+ _dl_printf("preload: out of memory");
+ _dl_exit(1);
+ }
+
+ while ((cp = _dl_strsep(&dp, ":")) != NULL) {
+ if (_dl_load_shlib(cp, _dl_objects, OBJTYPE_LIB) == 0) {
+ _dl_printf("%s: can't load library '%s'\n",
+ _dl_progname, cp);
+ _dl_exit(4);
+ }
+ }
+ _dl_free(paths);
+ return;
+}
+
/*
* This is the dynamic loader entrypoint. When entering here, depending
* on architecture type, the stack and registers are set up according
@@ -139,7 +166,6 @@ _dl_boot(const char **argv, char **envp, const long loff,
_dl_debug = NULL;
_dl_unsetenv("LD_DEBUG", envp);
}
-
}
_dl_progname = argv[0];
@@ -150,6 +176,7 @@ _dl_boot(const char **argv, char **envp, const long loff,
DL_DEB(("rtld loading: '%s'\n", _dl_progname));
+ exe_obj = NULL;
/*
* Examine the user application and set up object information.
*/
@@ -165,6 +192,9 @@ _dl_boot(const char **argv, char **envp, const long loff,
phdp++;
}
+ if (_dl_preload != NULL)
+ _dl_dopreload(_dl_preload);
+
/*
* Now, pick up and 'load' all libraries requierd. Start
* with the first on the list and then do whatever gets
@@ -202,7 +232,8 @@ _dl_boot(const char **argv, char **envp, const long loff,
* Everything should be in place now for doing the relocation
* and binding. Call _dl_rtld to do the job. Fingers crossed.
*/
- _dl_rtld(_dl_objects);
+ if (_dl_traceld == NULL)
+ _dl_rtld(_dl_objects);
/*
* The first object is the executable itself,
@@ -232,13 +263,13 @@ _dl_boot(const char **argv, char **envp, const long loff,
}
}
-
/*
* Finally make something to help gdb when poking around in the code.
*/
#ifdef __mips__
map_link = (struct r_debug **)(exe_obj->Dyn.info[DT_MIPS_RLD_MAP - DT_LOPROC + DT_NUM]);
#else
+ map_link = NULL;
for (dynp = exe_obj->load_dyn; dynp->d_tag; dynp++) {
if (dynp->d_tag == DT_DEBUG) {
map_link = (struct r_debug **)&dynp->d_un.d_ptr;
@@ -246,7 +277,6 @@ _dl_boot(const char **argv, char **envp, const long loff,
}
}
if (dynp->d_tag != DT_DEBUG) {
- map_link = NULL;
DL_DEB(("failed to mark DTDEBUG\n"));
}
#endif
diff --git a/libexec/ld.so/mips/syscall.h b/libexec/ld.so/mips/syscall.h
index 216c72e0da6..896fd7efe67 100644
--- a/libexec/ld.so/mips/syscall.h
+++ b/libexec/ld.so/mips/syscall.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: syscall.h,v 1.5 2002/07/07 08:54:50 jufi Exp $ */
+/* $OpenBSD: syscall.h,v 1.6 2002/07/12 20:18:30 drahn Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -34,9 +34,7 @@
#ifndef __DL_SYSCALL_H__
#define __DL_SYSCALL_H__
-#ifdef USE_CACHE
#include <sys/stat.h>
-#endif
#include <sys/syscall.h>
@@ -210,7 +208,6 @@ _dl_mprotect (const void *addr, int size, int prot)
return status;
}
-#ifdef USE_CACHE
extern inline int
_dl_stat (const char *addr, struct stat *sb)
{
@@ -226,8 +223,6 @@ _dl_stat (const char *addr, struct stat *sb)
return status;
}
-#endif
-
/*
* Not an actual syscall, but we need something in assembly to say
* whether this is OK or not.
diff --git a/libexec/ld.so/powerpc/archdep.h b/libexec/ld.so/powerpc/archdep.h
index 15d1da02aed..fe20594845a 100644
--- a/libexec/ld.so/powerpc/archdep.h
+++ b/libexec/ld.so/powerpc/archdep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: archdep.h,v 1.7 2002/05/24 04:17:01 deraadt Exp $ */
+/* $OpenBSD: archdep.h,v 1.8 2002/07/12 20:18:30 drahn Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -57,6 +57,7 @@
* The following functions are declared inline so they can
* be used before bootstrap linking has been finished.
*/
+
static inline void
_dl_dcbf(Elf32_Addr *addr)
{
diff --git a/libexec/ld.so/powerpc/rtld_machine.c b/libexec/ld.so/powerpc/rtld_machine.c
index 999818782f4..fb88fcd70fc 100644
--- a/libexec/ld.so/powerpc/rtld_machine.c
+++ b/libexec/ld.so/powerpc/rtld_machine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtld_machine.c,v 1.11 2002/07/07 08:54:50 jufi Exp $ */
+/* $OpenBSD: rtld_machine.c,v 1.12 2002/07/12 20:18:30 drahn Exp $ */
/*
* Copyright (c) 1999 Dale Rahn
@@ -81,6 +81,9 @@ _dl_printf("object relocation size %x, numrela %x\n",
if (relas == NULL)
return(0);
+ pltcall = NULL;
+ plttable = NULL;
+
/* for plt relocation usage */
if (object->Dyn.info[DT_JMPREL] != 0) {
/* resolver stub not set up */
@@ -145,6 +148,8 @@ _dl_printf("object relocation size %x, numrela %x\n",
this = sym;
symn = object->dyn.strtab + sym->st_name;
+ ooff = 0;
+
if (ELF32_R_SYM(relas->r_info) &&
!(ELF32_ST_BIND(sym->st_info) == STB_LOCAL &&
ELF32_ST_TYPE (sym->st_info) == STT_NOTYPE)) {
@@ -344,6 +349,8 @@ _dl_dcbf(r_addr);
const Elf32_Sym *cpysrc = NULL;
Elf32_Addr src_loff;
int size;
+
+ src_loff = 0;
for (cobj = _dl_objects; cobj != NULL && cpysrc == NULL;
cobj = cobj->next) {
if (object != cobj) {
diff --git a/libexec/ld.so/powerpc/syscall.h b/libexec/ld.so/powerpc/syscall.h
index 5abbec8a737..fd5f5b2ae73 100644
--- a/libexec/ld.so/powerpc/syscall.h
+++ b/libexec/ld.so/powerpc/syscall.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: syscall.h,v 1.8 2002/07/07 08:54:50 jufi Exp $ */
+/* $OpenBSD: syscall.h,v 1.9 2002/07/12 20:18:30 drahn Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -34,12 +34,13 @@
#ifndef __DL_SYSCALL_H__
#define __DL_SYSCALL_H__
-#ifdef USE_CACHE
#include <sys/stat.h>
-#endif
#include <sys/syscall.h>
+
+static off_t _dl_lseek(int, off_t, int);
+
#ifndef _dl_MAX_ERRNO
#define _dl_MAX_ERRNO 4096
#endif
@@ -145,7 +146,7 @@ _dl_read (int fd, const char* buf, int len)
#define STRINGIFY(x) #x
#define XSTRINGIFY(x) STRINGIFY(x)
-int _dl__syscall(quad_t val, ...);
+long _dl__syscall(quad_t val, ...);
__asm__(".align 2\n\t"
".type _dl__syscall,@function\n"
"_dl__syscall:\n\t"
@@ -157,7 +158,7 @@ __asm__(".align 2\n\t"
"1:\n\t"
"blr");
-static int
+static inline int
_dl_mmap (void *addr, unsigned int len, unsigned int prot,
unsigned int flags, int fd, off_t offset)
{
@@ -204,7 +205,6 @@ _dl_mprotect (const void *addr, int size, int prot)
return status;
}
-#ifdef USE_CACHE
static inline int
_dl_stat (const char *addr, struct stat *sb)
{
@@ -224,7 +224,66 @@ _dl_stat (const char *addr, struct stat *sb)
return status;
}
-#endif
+static inline int
+_dl_fstat (int fd, struct stat *sb)
+{
+ register int status __asm__ ("3");
+
+ __asm__ volatile ("mr 0,%1\n\t"
+ "mr 3,%2\n\t"
+ "mr 4,%3\n\t"
+ "sc\n\t"
+ "cmpwi 0, 0\n\t"
+ "beq 1f\n\t"
+ "li 3,-1\n\t"
+ "1:"
+ : "=r" (status)
+ : "r" (SYS_fstat), "r" (fd), "r" (sb)
+ : "0", "3", "4");
+ return status;
+}
+
+static inline int
+_dl_fcntl (int fd, int cmd, int flag)
+{
+ register int status __asm__ ("3");
+
+ __asm__ volatile ("mr 0,%1\n\t"
+ "mr 3,%2\n\t"
+ "mr 4,%3\n\t"
+ "mr 5,%4\n\t"
+ "sc\n\t"
+ "cmpwi 0, 0\n\t"
+ "beq 1f\n\t"
+ "li 3,-1\n\t"
+ "1:"
+ : "=r" (status)
+ : "r" (SYS_fcntl), "r" (fd), "r" (cmd), "r"(flag)
+ : "0", "3", "4", "5");
+ return status;
+}
+
+static inline int
+_dl_getdirentries(int fd, char *buf, int nbytes, long *basep)
+{
+ register int status __asm__ ("3");
+
+ __asm__ volatile ("mr 0,%1\n\t"
+ "mr 3,%2\n\t"
+ "mr 4,%3\n\t"
+ "mr 5,%4\n\t"
+ "mr 6,%5\n\t"
+ "sc\n\t"
+ "cmpwi 0, 0\n\t"
+ "beq 1f\n\t"
+ "li 3,-1\n\t"
+ "1:"
+ : "=r" (status)
+ : "r" (SYS_getdirentries), "r" (fd), "r" (buf), "r"(nbytes),
+ "r" (basep)
+ : "0", "3", "4", "5", "6");
+ return status;
+}
static inline int
_dl_issetugid()
@@ -242,5 +301,10 @@ _dl_issetugid()
: "0", "3");
return status;
}
-#include <elf_abi.h>
+
+static inline off_t
+_dl_lseek(int fildes, off_t offset, int whence)
+{
+ return _dl__syscall((quad_t)SYS_lseek, fildes, 0, offset, whence);
+}
#endif /*__DL_SYSCALL_H__*/
diff --git a/libexec/ld.so/sod.c b/libexec/ld.so/sod.c
index 5abc8cbecf5..1d36627acbf 100644
--- a/libexec/ld.so/sod.c
+++ b/libexec/ld.so/sod.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sod.c,v 1.13 2002/05/27 23:37:25 deraadt Exp $ */
+/* $OpenBSD: sod.c,v 1.14 2002/07/12 20:18:30 drahn Exp $ */
/*
* Copyright (c) 1993 Paul Kranenburg
@@ -46,6 +46,7 @@
#include "archdep.h"
#include "util.h"
+#include "sod.h"
#define PAGSIZ __LDPGSZ
int _dl_hinthash(char *cp, int vmajor, int vminor);
@@ -85,6 +86,7 @@ _dl_build_sod(name, sodp)
/* default */
major = minor = -1;
+ realname = NULL;
/* loop through name - parse skipping name */
for (tuplet = 0; (tok = strsep(&cp, ".")) != NULL; tuplet++) {
switch (tuplet) {
@@ -114,6 +116,9 @@ _dl_build_sod(name, sodp)
goto backout;
}
}
+ if (realname == NULL) {
+ goto backout;
+ }
cp = (char *)sodp->sod_name;
sodp->sod_name = (long)_dl_strdup(realname);
_dl_free(cp);
@@ -132,7 +137,7 @@ static long hsize;
static struct hints_header *hheader = NULL;
static struct hints_bucket *hbuckets;
static char *hstrtab;
-static char *hint_search_path = "";
+char *_dl_hint_search_path = NULL;
#define HINTS_VALID (hheader != NULL && hheader != (struct hints_header *)-1)
@@ -185,7 +190,7 @@ _dl_maphints()
hbuckets = (struct hints_bucket *)(addr + hheader->hh_hashtab);
hstrtab = (char *)(addr + hheader->hh_strtab);
if (hheader->hh_version >= LD_HINTS_VERSION_2)
- hint_search_path = hstrtab + hheader->hh_dirlist;
+ _dl_hint_search_path = hstrtab + hheader->hh_dirlist;
/* close the file descriptor, leaving the hints mapped */
_dl_close(hfd);
diff --git a/libexec/ld.so/sod.h b/libexec/ld.so/sod.h
new file mode 100644
index 00000000000..c4bf491d82c
--- /dev/null
+++ b/libexec/ld.so/sod.h
@@ -0,0 +1,36 @@
+/* $OpenBSD: sod.h,v 1.1 2002/07/12 20:18:30 drahn Exp $ */
+
+/*
+ * Copyright (c) 1993 Paul Kranenburg
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Paul Kranenburg.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+void _dl_build_sod(const char *name, struct sod *sodp);
+char *_dl_findhint(char *name, int major, int minor, char *prefered_path);
+extern char *_dl_hint_search_path;
diff --git a/libexec/ld.so/sparc64/archdep.h b/libexec/ld.so/sparc64/archdep.h
index 6ced3ab80b3..756e7f07f56 100644
--- a/libexec/ld.so/sparc64/archdep.h
+++ b/libexec/ld.so/sparc64/archdep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: archdep.h,v 1.8 2002/05/24 03:44:38 deraadt Exp $ */
+/* $OpenBSD: archdep.h,v 1.9 2002/07/12 20:18:30 drahn Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -53,7 +53,7 @@ static inline long
_dl_mmap(void *addr, unsigned int len, unsigned int prot,
unsigned int flags, int fd, off_t offset)
{
- return(_dl___syscall((quad_t)SYS_mmap, addr, len, prot,
+ return(_dl__syscall((quad_t)SYS_mmap, addr, len, prot,
flags, fd, 0, offset));
}
diff --git a/libexec/ld.so/sparc64/ldasm.S b/libexec/ld.so/sparc64/ldasm.S
index bcff6965088..eda57732c0e 100644
--- a/libexec/ld.so/sparc64/ldasm.S
+++ b/libexec/ld.so/sparc64/ldasm.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldasm.S,v 1.11 2002/05/24 04:17:01 deraadt Exp $ */
+/* $OpenBSD: ldasm.S,v 1.12 2002/07/12 20:18:30 drahn Exp $ */
/* $NetBSD: rtld_start.S,v 1.5 2001/08/14 22:17:48 eeh Exp $ */
/*
@@ -219,7 +219,7 @@ _dl_bind_start_1: # (x, y)
.type _dl_close,@function
_dl_close:
mov SYS_close | SYSCALL_G2RFLAG, %g1 ! call sys_close
- add %o7, 8, %g2 ! just return on sucess
+ add %o7, 8, %g2 ! just return on success
t ST_SYSCALL ! off to wonderland
retl
sub %g0, %o0, %o0 ! error: result = -errno
@@ -231,7 +231,7 @@ _dl_close:
.type _dl_exit,@function
_dl_exit:
mov SYS_exit | SYSCALL_G2RFLAG, %g1 ! call sys_exit
- add %o7, 8, %g2 ! just return on sucess
+ add %o7, 8, %g2 ! just return on success
t ST_SYSCALL ! off to wonderland
retl
sub %g0, %o0, %o0 ! error: result = -errno
@@ -251,11 +251,11 @@ _dl_issetugid:
.section ".text"
.align 4
- .global _dl___syscall
- .type _dl___syscall,@function
-_dl___syscall:
+ .global _dl__syscall
+ .type _dl__syscall,@function
+_dl__syscall:
mov SYS___syscall | SYSCALL_G2RFLAG, %g1 ! call sys_exit
- add %o7, 8, %g2 ! just return on sucess
+ add %o7, 8, %g2 ! just return on success
t ST_SYSCALL ! off to wonderland
retl
sub %g0, %o0, %o0 ! error: result = -errno
@@ -267,7 +267,7 @@ _dl___syscall:
.type _dl_munmap,@function
_dl_munmap:
mov SYS_munmap | SYSCALL_G2RFLAG, %g1 ! calling sys_mmap
- add %o7, 8, %g2 ! just return on sucess
+ add %o7, 8, %g2 ! just return on success
t ST_SYSCALL ! off to wonderland
retl
sub %g0, %o0, %o0 ! error: result = -errno
@@ -279,7 +279,7 @@ _dl_munmap:
.type _dl_mprotect,@function
_dl_mprotect:
mov SYS_mprotect | SYSCALL_G2RFLAG, %g1 ! calling sys_mprotect
- add %o7, 8, %g2 ! just return on sucess
+ add %o7, 8, %g2 ! just return on success
t ST_SYSCALL ! off to wonderland
retl
sub %g0, %o0, %o0 ! error: result = -errno
@@ -291,7 +291,7 @@ _dl_mprotect:
.type _dl_open,@function
_dl_open:
mov SYS_open | SYSCALL_G2RFLAG, %g1 ! calling sys_open
- add %o7, 8, %g2 ! just return on sucess
+ add %o7, 8, %g2 ! just return on success
t ST_SYSCALL ! off to wonderland
retl
sub %g0, %o0, %o0 ! error: result = -errno
@@ -303,7 +303,7 @@ _dl_open:
.type _dl_read,@function
_dl_read:
mov SYS_read | SYSCALL_G2RFLAG, %g1 ! calling sys_read
- add %o7, 8, %g2 ! just return on sucess
+ add %o7, 8, %g2 ! just return on success
t ST_SYSCALL ! off to wonderland
retl
sub %g0, %o0, %o0 ! error: result = -errno
@@ -315,7 +315,7 @@ _dl_read:
.type _dl_write,@function
_dl_write:
mov SYS_write | SYSCALL_G2RFLAG, %g1 ! calling sys_write
- add %o7, 8, %g2 ! just return on sucess
+ add %o7, 8, %g2 ! just return on success
t ST_SYSCALL ! off to wonderland
retl
sub %g0, %o0, %o0 ! error: result = -errno
@@ -327,7 +327,43 @@ _dl_write:
.type _dl_stat,@function
_dl_stat:
mov SYS_stat | SYSCALL_G2RFLAG, %g1 ! call sys_stat
- add %o7, 8, %g2 ! just return on sucess
+ add %o7, 8, %g2 ! just return on success
t ST_SYSCALL ! off to wonderland
retl
sub %g0, %o0, %o0 ! error: result = -errno
+
+
+ .section ".text"
+ .align 4
+ .globl _dl_fstat
+ .type _dl_fstat,@function
+_dl_fstat:
+ mov SYS_fstat | SYSCALL_G2RFLAG, %g1 ! call sys_fstat
+ add %o7, 8, %g2 ! just return on success
+ t ST_SYSCALL ! off to wonderland
+ retl
+ sub %g0, %o0, %o0 ! error: result = -errno
+
+
+ .section ".text"
+ .align 4
+ .globl _dl_fcntl
+ .type _dl_fcntl,@function
+_dl_fcntl:
+ mov SYS_fcntl | SYSCALL_G2RFLAG, %g1 ! call sys_fstat
+ add %o7, 8, %g2 ! just return on success
+ t ST_SYSCALL ! off to wonderland
+ retl
+ sub %g0, %o0, %o0 ! error: result = -errno
+
+
+ .section ".text"
+ .align 4
+ .globl _dl_getdirentries
+ .type _dl_getdirentries,@function
+_dl_getdirentries:
+ mov SYS_getdirentries | SYSCALL_G2RFLAG, %g1 ! call sys_fstat
+ add %o7, 8, %g2 ! just return on success
+ t ST_SYSCALL ! off to wonderland
+ retl
+ sub %g0, %o0, %o0 ! error: result = -errno
diff --git a/libexec/ld.so/sparc64/rtld_machine.c b/libexec/ld.so/sparc64/rtld_machine.c
index 7122082b885..bfc20126dc4 100644
--- a/libexec/ld.so/sparc64/rtld_machine.c
+++ b/libexec/ld.so/sparc64/rtld_machine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtld_machine.c,v 1.16 2002/06/05 23:13:55 art Exp $ */
+/* $OpenBSD: rtld_machine.c,v 1.17 2002/07/12 20:18:30 drahn Exp $ */
/*
* Copyright (c) 1999 Dale Rahn
@@ -264,6 +264,8 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz)
else
value = 0;
+ sym = NULL;
+ symn = NULL;
if (RELOC_RESOLVE_SYMBOL(type)) {
sym = object->dyn.symtab;
sym += ELF_R_SYM(relas->r_info);
diff --git a/libexec/ld.so/sparc64/syscall.h b/libexec/ld.so/sparc64/syscall.h
index 9cc0b69ba14..045b15e1bcc 100644
--- a/libexec/ld.so/sparc64/syscall.h
+++ b/libexec/ld.so/sparc64/syscall.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: syscall.h,v 1.5 2002/03/17 00:22:04 art Exp $ */
+/* $OpenBSD: syscall.h,v 1.6 2002/07/12 20:18:30 drahn Exp $ */
/*
* Copyright (c) 2001 Niklas Hallqvist
@@ -35,9 +35,8 @@
#ifndef __DL_SYSCALL_H__
#define __DL_SYSCALL_H__
-#ifdef USE_CACHE
+#include <sys/syscall.h>
#include <sys/stat.h>
-#endif
#ifndef _dl_MAX_ERRNO
#define _dl_MAX_ERRNO 4096
@@ -48,15 +47,21 @@
int _dl_close(int);
int _dl_exit(int);
int _dl_issetugid(void);
-long _dl___syscall(quad_t, ...);
+long _dl__syscall(quad_t, ...);
int _dl_mprotect(const void *, int, int);
int _dl_munmap(const void*, unsigned int);
int _dl_open(const char*, unsigned int);
int _dl_read(int, const char*, int);
-#ifdef USE_CACHE
int _dl_stat(const char *, struct stat *);
-#endif
int _dl_write(int, const char*, int);
+int _dl_fstat(int, struct stat *);
+int _dl_fcntl(int, int, ...);
+int _dl_getdirentries(int, char*, int, long *);
+
+static inline off_t
+_dl_lseek(int fildes, off_t offset, int whence)
+{
+ return _dl__syscall((quad_t)SYS_lseek, fildes, 0, offset, whence);
+}
-#include <elf_abi.h>
#endif /*__DL_SYSCALL_H__*/