diff options
-rw-r--r-- | libexec/ld.so/Makefile | 18 | ||||
-rw-r--r-- | libexec/ld.so/alpha/ldasm.S | 28 | ||||
-rw-r--r-- | libexec/ld.so/alpha/syscall.h | 18 | ||||
-rw-r--r-- | libexec/ld.so/dir.c | 269 | ||||
-rw-r--r-- | libexec/ld.so/dir.h | 38 | ||||
-rw-r--r-- | libexec/ld.so/library.c | 308 | ||||
-rw-r--r-- | libexec/ld.so/loader.c | 40 | ||||
-rw-r--r-- | libexec/ld.so/mips/syscall.h | 7 | ||||
-rw-r--r-- | libexec/ld.so/powerpc/archdep.h | 3 | ||||
-rw-r--r-- | libexec/ld.so/powerpc/rtld_machine.c | 9 | ||||
-rw-r--r-- | libexec/ld.so/powerpc/syscall.h | 80 | ||||
-rw-r--r-- | libexec/ld.so/sod.c | 11 | ||||
-rw-r--r-- | libexec/ld.so/sod.h | 36 | ||||
-rw-r--r-- | libexec/ld.so/sparc64/archdep.h | 4 | ||||
-rw-r--r-- | libexec/ld.so/sparc64/ldasm.S | 62 | ||||
-rw-r--r-- | libexec/ld.so/sparc64/rtld_machine.c | 4 | ||||
-rw-r--r-- | libexec/ld.so/sparc64/syscall.h | 19 |
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__*/ |