summaryrefslogtreecommitdiff
path: root/libexec/ld.so
diff options
context:
space:
mode:
authorKurt Miller <kurt@cvs.openbsd.org>2013-04-05 12:58:05 +0000
committerKurt Miller <kurt@cvs.openbsd.org>2013-04-05 12:58:05 +0000
commit1892e71c11ce0b9f666c92574ed7161d16dc08f8 (patch)
tree755a6b60e7d08a717e59ceed6909b1d2aeefdeeb /libexec/ld.so
parent84c7c115879a734ff013eca4de8f5ac17c120b9c (diff)
- Add ORIGIN, OSNAME, OSREL and PLATFORM substitution support for rpaths.
Improvements and okay matthew@, millert@, guenther@
Diffstat (limited to 'libexec/ld.so')
-rw-r--r--libexec/ld.so/Makefile5
-rw-r--r--libexec/ld.so/alpha/ldasm.S20
-rw-r--r--libexec/ld.so/alpha/syscall.h5
-rw-r--r--libexec/ld.so/amd64/ldasm.S5
-rw-r--r--libexec/ld.so/amd64/syscall.h5
-rw-r--r--libexec/ld.so/arm/ldasm.S5
-rw-r--r--libexec/ld.so/arm/syscall.h5
-rw-r--r--libexec/ld.so/dl_dirname.c70
-rw-r--r--libexec/ld.so/dl_realpath.c205
-rw-r--r--libexec/ld.so/dl_uname.c69
-rw-r--r--libexec/ld.so/hppa/ldasm.S20
-rw-r--r--libexec/ld.so/hppa/syscall.h5
-rw-r--r--libexec/ld.so/i386/ldasm.S5
-rw-r--r--libexec/ld.so/i386/syscall.h5
-rw-r--r--libexec/ld.so/loader.c7
-rw-r--r--libexec/ld.so/m68k/ldasm.S11
-rw-r--r--libexec/ld.so/m68k/syscall.h5
-rw-r--r--libexec/ld.so/m88k/ldasm.S11
-rw-r--r--libexec/ld.so/m88k/syscall.h5
-rw-r--r--libexec/ld.so/mips64/syscall.h65
-rw-r--r--libexec/ld.so/powerpc/syscall.h64
-rw-r--r--libexec/ld.so/resolve.c168
-rw-r--r--libexec/ld.so/resolve.h4
-rw-r--r--libexec/ld.so/sh/ldasm.S5
-rw-r--r--libexec/ld.so/sh/syscall.h5
-rw-r--r--libexec/ld.so/sparc/ldasm.S39
-rw-r--r--libexec/ld.so/sparc/syscall.h5
-rw-r--r--libexec/ld.so/sparc64/ldasm.S23
-rw-r--r--libexec/ld.so/sparc64/syscall.h5
-rw-r--r--libexec/ld.so/util.h24
30 files changed, 834 insertions, 41 deletions
diff --git a/libexec/ld.so/Makefile b/libexec/ld.so/Makefile
index 69eb5c23c71..a100c590c16 100644
--- a/libexec/ld.so/Makefile
+++ b/libexec/ld.so/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.42 2013/03/20 21:49:59 kurt Exp $
+# $OpenBSD: Makefile,v 1.43 2013/04/05 12:58:03 kurt Exp $
SUBDIR=ldconfig ldd
MAN= ld.so.1
@@ -16,6 +16,7 @@ VPATH=${.CURDIR}/../../lib/libc/string
SRCS= ldasm.S loader.c resolve.c dlfcn.c dl_printf.c rtld_machine.c path.c
SRCS+= util.c sod.c strsep.c strtol.c dir.c library_subr.c dl_prebind.c
+SRCS+= dl_realpath.c dl_uname.c dl_dirname.c strlcat.c strlen.c
.if (${MACHINE_ARCH} == "i386")
SRCS+= library_mquery.c
.else
@@ -29,7 +30,7 @@ SRCS+= library.c
DEBUG?= -g
CFLAGS += -Wall -Werror
CFLAGS += -I${.CURDIR} -I${.CURDIR}/${MACHINE_CPU} \
- -Dstrsep=_dl_strsep
+ -Dstrsep=_dl_strsep -Dstrlcat=_dl_strlcat -Dstrlen=_dl_strlen
CDIAGFLAGS=
INSTALL_STRIP=
diff --git a/libexec/ld.so/alpha/ldasm.S b/libexec/ld.so/alpha/ldasm.S
index 0806b4312e9..6264cd5f7f1 100644
--- a/libexec/ld.so/alpha/ldasm.S
+++ b/libexec/ld.so/alpha/ldasm.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldasm.S,v 1.18 2012/10/24 03:26:55 guenther Exp $ */
+/* $OpenBSD: ldasm.S,v 1.19 2013/04/05 12:58:03 kurt Exp $ */
/*
* Copyright (c) 2001 Niklas Hallqvist
@@ -307,3 +307,21 @@ LEAF_NOPROFILE(_dl_gettimeofday, 2)
RET
END(_dl_gettimeofday)
+LEAF_NOPROFILE(_dl_readlink, 3)
+ ldiq v0, SYS_readlink
+ call_pal PAL_OSF1_callsys
+ RET
+END(_dl_readlink)
+
+LEAF_NOPROFILE(_dl_lstat, 2)
+ ldiq v0, SYS_lstat
+ call_pal PAL_OSF1_callsys
+ RET
+END(_dl_lstat)
+
+LEAF_NOPROFILE(_dl_getcwd, 2)
+ ldiq v0, SYS___getcwd
+ call_pal PAL_OSF1_callsys
+ RET
+END(_dl_getcwd)
+
diff --git a/libexec/ld.so/alpha/syscall.h b/libexec/ld.so/alpha/syscall.h
index d7699c9449e..c5d48531659 100644
--- a/libexec/ld.so/alpha/syscall.h
+++ b/libexec/ld.so/alpha/syscall.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: syscall.h,v 1.18 2012/10/24 03:26:55 guenther Exp $ */
+/* $OpenBSD: syscall.h,v 1.19 2013/04/05 12:58:03 kurt Exp $ */
/*
* Copyright (c) 2001 Niklas Hallqvist
@@ -53,6 +53,9 @@ long _dl__syscall(quad_t, ...);
int _dl_sigprocmask(int, const sigset_t *, sigset_t *);
int _dl_sysctl(int *, u_int, void *, size_t *, void *, size_t);
int _dl_gettimeofday(struct timeval *tp, struct timezone *tzp);
+int _dl_readlink(const char *path, char *buf, size_t bufsiz);
+int _dl_lstat(const char *path, struct stat *sb);
+int _dl_getcwd(char *buf, size_t size);
static inline off_t
_dl_lseek(int fildes, off_t offset, int whence)
diff --git a/libexec/ld.so/amd64/ldasm.S b/libexec/ld.so/amd64/ldasm.S
index ec3d77b696f..54351727872 100644
--- a/libexec/ld.so/amd64/ldasm.S
+++ b/libexec/ld.so/amd64/ldasm.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldasm.S,v 1.10 2012/10/24 03:26:56 guenther Exp $ */
+/* $OpenBSD: ldasm.S,v 1.11 2013/04/05 12:58:03 kurt Exp $ */
/*
* Copyright (c) 2002,2004 Dale Rahn
@@ -95,6 +95,9 @@ DL_SYSCALL(mprotect)
DL_SYSCALL(munmap)
DL_SYSCALL(gettimeofday)
DL_SYSCALL(exit)
+DL_SYSCALL(readlink)
+DL_SYSCALL(lstat)
+DL_SYSCALL2(getcwd,__getcwd)
DL_SYSCALL2(_syscall,__syscall)
DL_SYSCALL2(sysctl,__sysctl)
diff --git a/libexec/ld.so/amd64/syscall.h b/libexec/ld.so/amd64/syscall.h
index b96dc87f530..9cf7dc62c14 100644
--- a/libexec/ld.so/amd64/syscall.h
+++ b/libexec/ld.so/amd64/syscall.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: syscall.h,v 1.6 2012/10/24 03:26:56 guenther Exp $ */
+/* $OpenBSD: syscall.h,v 1.7 2013/04/05 12:58:03 kurt Exp $ */
/*
* Copyright (c) 2001 Niklas Hallqvist
@@ -53,6 +53,9 @@ int _dl_getdirentries(int, char*, int, off_t *);
int _dl_sigprocmask(int, const sigset_t *, sigset_t *);
int _dl_sysctl(int *, u_int, void *, size_t *, void *, size_t);
int _dl_gettimeofday(struct timeval *tp, struct timezone *tzp);
+int _dl_readlink(const char *path, char *buf, size_t bufsiz);
+int _dl_lstat(const char *path, struct stat *sb);
+int _dl_getcwd(char *buf, size_t size);
static inline off_t
_dl_lseek(int fildes, off_t offset, int whence)
diff --git a/libexec/ld.so/arm/ldasm.S b/libexec/ld.so/arm/ldasm.S
index a6729bbcd97..6d3bcf08bf8 100644
--- a/libexec/ld.so/arm/ldasm.S
+++ b/libexec/ld.so/arm/ldasm.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldasm.S,v 1.8 2012/12/22 11:46:16 kettenis Exp $ */
+/* $OpenBSD: ldasm.S,v 1.9 2013/04/05 12:58:03 kurt Exp $ */
/*
* Copyright (c) 2004 Dale Rahn
@@ -114,6 +114,9 @@ DL_SYSCALL(write)
DL_SYSCALL(fstat)
DL_SYSCALL(fcntl)
DL_SYSCALL(gettimeofday)
+DL_SYSCALL(readlink)
+DL_SYSCALL(lstat)
+DL_SYSCALL2(getcwd,__getcwd)
DL_SYSCALL2(sysctl,__sysctl)
DL_SYSCALL(getdirentries)
diff --git a/libexec/ld.so/arm/syscall.h b/libexec/ld.so/arm/syscall.h
index 27347f7e992..b46b170782c 100644
--- a/libexec/ld.so/arm/syscall.h
+++ b/libexec/ld.so/arm/syscall.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: syscall.h,v 1.6 2012/10/24 03:26:56 guenther Exp $ */
+/* $OpenBSD: syscall.h,v 1.7 2013/04/05 12:58:03 kurt Exp $ */
/*
* Copyright (c) 2001 Niklas Hallqvist
@@ -53,6 +53,9 @@ int _dl_getdirentries(int, char*, int, off_t *);
int _dl_sigprocmask(int, const sigset_t *, sigset_t *);
int _dl_sysctl(int *, u_int, void *, size_t *, void *, size_t);
int _dl_gettimeofday(struct timeval *tp, struct timezone *tzp);
+int _dl_readlink(const char *path, char *buf, size_t bufsiz);
+int _dl_lstat(const char *path, struct stat *sb);
+int _dl_getcwd(char *buf, size_t size);
static inline off_t
_dl_lseek(int fildes, off_t offset, int whence)
diff --git a/libexec/ld.so/dl_dirname.c b/libexec/ld.so/dl_dirname.c
new file mode 100644
index 00000000000..6079ce9c1a2
--- /dev/null
+++ b/libexec/ld.so/dl_dirname.c
@@ -0,0 +1,70 @@
+/* $OpenBSD: dl_dirname.c,v 1.1 2013/04/05 12:58:03 kurt Exp $ */
+
+/*
+ * Copyright (c) 1997, 2004 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+
+#include "archdep.h"
+
+/*
+ * This file was copied from libc/stdlib/realpath.c and modified for ld.so's
+ * syscall method which returns -errno.
+ */
+
+char *
+_dl_dirname(const char *path)
+{
+ static char dname[MAXPATHLEN];
+ size_t len;
+ const char *endp;
+
+ /* Empty or NULL string gets treated as "." */
+ if (path == NULL || *path == '\0') {
+ dname[0] = '.';
+ dname[1] = '\0';
+ return (dname);
+ }
+
+ /* Strip any trailing slashes */
+ endp = path + strlen(path) - 1;
+ while (endp > path && *endp == '/')
+ endp--;
+
+ /* Find the start of the dir */
+ while (endp > path && *endp != '/')
+ endp--;
+
+ /* Either the dir is "/" or there are no slashes */
+ if (endp == path) {
+ dname[0] = *endp == '/' ? '/' : '.';
+ dname[1] = '\0';
+ return (dname);
+ } else {
+ /* Move forward past the separating slashes */
+ do {
+ endp--;
+ } while (endp > path && *endp == '/');
+ }
+
+ len = endp - path + 1;
+ if (len >= sizeof(dname)) {
+ return (NULL);
+ }
+ _dl_bcopy(path, dname, len);
+ dname[len] = '\0';
+ return (dname);
+}
diff --git a/libexec/ld.so/dl_realpath.c b/libexec/ld.so/dl_realpath.c
new file mode 100644
index 00000000000..b568da91abe
--- /dev/null
+++ b/libexec/ld.so/dl_realpath.c
@@ -0,0 +1,205 @@
+/* $OpenBSD: dl_realpath.c,v 1.1 2013/04/05 12:58:03 kurt Exp $ */
+/*
+ * Copyright (c) 2003 Constantin S. Svintsoff <kostik@iclub.nsu.ru>
+ *
+ * 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. The names of the authors 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 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 AUTHOR 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.
+ */
+
+#include <sys/types.h>
+#include <limits.h>
+#include "archdep.h"
+
+#define ENOENT -2
+
+/*
+ * This file was copied from libc/stdlib/realpath.c and modified for ld.so's
+ * syscall method which returns -errno.
+ */
+
+/*
+ * char *dl_realpath(const char *path, char resolved[PATH_MAX]);
+ *
+ * Find the real name of path, by removing all ".", ".." and symlink
+ * components. Returns (resolved) on success, or (NULL) on failure,
+ * in which case the path which caused trouble is left in (resolved).
+ */
+char *
+_dl_realpath(const char *path, char *resolved)
+{
+ struct stat sb;
+ const char *p, *s;
+ char *q;
+ size_t left_len, resolved_len;
+ unsigned symlinks;
+ int slen, mem_allocated, ret;
+ char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
+
+ if (path[0] == '\0') {
+ return (NULL);
+ }
+
+ if (resolved == NULL) {
+ resolved = _dl_malloc(PATH_MAX);
+ if (resolved == NULL)
+ return (NULL);
+ mem_allocated = 1;
+ } else
+ mem_allocated = 0;
+
+ symlinks = 0;
+ if (path[0] == '/') {
+ resolved[0] = '/';
+ resolved[1] = '\0';
+ if (path[1] == '\0')
+ return (resolved);
+ resolved_len = 1;
+ left_len = _dl_strlcpy(left, path + 1, sizeof(left));
+ } else {
+ if (_dl_getcwd(resolved, PATH_MAX) <= 0) {
+ if (mem_allocated)
+ _dl_free(resolved);
+ else
+ _dl_strlcpy(resolved, ".", PATH_MAX);
+ return (NULL);
+ }
+ resolved_len = _dl_strlen(resolved);
+ left_len = _dl_strlcpy(left, path, sizeof(left));
+ }
+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
+ goto err;
+ }
+
+ /*
+ * Iterate over path components in `left'.
+ */
+ while (left_len != 0) {
+ /*
+ * Extract the next path component and adjust `left'
+ * and its length.
+ */
+ p = _dl_strchr(left, '/');
+ s = p ? p : left + left_len;
+ if (s - left >= sizeof(next_token)) {
+ goto err;
+ }
+ _dl_bcopy(left, next_token, s - left);
+ next_token[s - left] = '\0';
+ left_len -= s - left;
+ if (p != NULL)
+ _dl_bcopy(s + 1, left, left_len + 1);
+ if (resolved[resolved_len - 1] != '/') {
+ if (resolved_len + 1 >= PATH_MAX) {
+ goto err;
+ }
+ resolved[resolved_len++] = '/';
+ resolved[resolved_len] = '\0';
+ }
+ if (next_token[0] == '\0')
+ continue;
+ else if (_dl_strcmp(next_token, ".") == 0)
+ continue;
+ else if (_dl_strcmp(next_token, "..") == 0) {
+ /*
+ * Strip the last path component except when we have
+ * single "/"
+ */
+ if (resolved_len > 1) {
+ resolved[resolved_len - 1] = '\0';
+ q = _dl_strrchr(resolved, '/') + 1;
+ *q = '\0';
+ resolved_len = q - resolved;
+ }
+ continue;
+ }
+
+ /*
+ * Append the next path component and lstat() it. If
+ * lstat() fails we still can return successfully if
+ * there are no more path components left.
+ */
+ resolved_len = _dl_strlcat(resolved, next_token, PATH_MAX);
+ if (resolved_len >= PATH_MAX) {
+ goto err;
+ }
+ if ((ret = _dl_lstat(resolved, &sb)) != 0) {
+ if (ret == ENOENT && p == NULL) {
+ return (resolved);
+ }
+ goto err;
+ }
+ if (S_ISLNK(sb.st_mode)) {
+ if (symlinks++ > SYMLOOP_MAX) {
+ goto err;
+ }
+ slen = _dl_readlink(resolved, symlink, sizeof(symlink) - 1);
+ if (slen < 0)
+ goto err;
+ symlink[slen] = '\0';
+ if (symlink[0] == '/') {
+ resolved[1] = 0;
+ resolved_len = 1;
+ } else if (resolved_len > 1) {
+ /* Strip the last path component. */
+ resolved[resolved_len - 1] = '\0';
+ q = _dl_strrchr(resolved, '/') + 1;
+ *q = '\0';
+ resolved_len = q - resolved;
+ }
+
+ /*
+ * If there are any path components left, then
+ * append them to symlink. The result is placed
+ * in `left'.
+ */
+ if (p != NULL) {
+ if (symlink[slen - 1] != '/') {
+ if (slen + 1 >= sizeof(symlink)) {
+ goto err;
+ }
+ symlink[slen] = '/';
+ symlink[slen + 1] = 0;
+ }
+ left_len = _dl_strlcat(symlink, left, sizeof(symlink));
+ if (left_len >= sizeof(left)) {
+ goto err;
+ }
+ }
+ left_len = _dl_strlcpy(left, symlink, sizeof(left));
+ }
+ }
+
+ /*
+ * Remove trailing slash except when the resolved pathname
+ * is a single "/".
+ */
+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
+ resolved[resolved_len - 1] = '\0';
+ return (resolved);
+
+err:
+ if (mem_allocated)
+ _dl_free(resolved);
+ return (NULL);
+}
diff --git a/libexec/ld.so/dl_uname.c b/libexec/ld.so/dl_uname.c
new file mode 100644
index 00000000000..1d35e2ad6b6
--- /dev/null
+++ b/libexec/ld.so/dl_uname.c
@@ -0,0 +1,69 @@
+/* $OpenBSD: dl_uname.c,v 1.1 2013/04/05 12:58:03 kurt Exp $ */
+/*
+ * Copyright (c) 1994
+ * 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. 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.
+ */
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/utsname.h>
+
+#include "archdep.h"
+
+/*
+ * This file was copied from libc/gen/uname.c and modified for ld.so's
+ * syscall method which returns -errno. Also KERN_OSVERSION is not retrieved
+ * since ld.so doesn't need it.
+ */
+
+int
+_dl_uname(struct utsname *name)
+{
+ int mib[2], rval;
+ size_t len;
+
+ rval = 0;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_OSTYPE;
+ len = sizeof(name->sysname);
+ if (_dl_sysctl(mib, 2, &name->sysname, &len, NULL, 0) < 0)
+ rval = -1;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_OSRELEASE;
+ len = sizeof(name->release);
+ if (_dl_sysctl(mib, 2, &name->release, &len, NULL, 0) < 0)
+ rval = -1;
+
+ mib[0] = CTL_HW;
+ mib[1] = HW_MACHINE;
+ len = sizeof(name->machine);
+ if (_dl_sysctl(mib, 2, &name->machine, &len, NULL, 0) < 0)
+ rval = -1;
+ return (rval);
+}
diff --git a/libexec/ld.so/hppa/ldasm.S b/libexec/ld.so/hppa/ldasm.S
index be3604d3fec..644b0ddfa60 100644
--- a/libexec/ld.so/hppa/ldasm.S
+++ b/libexec/ld.so/hppa/ldasm.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldasm.S,v 1.8 2012/10/27 08:30:35 kettenis Exp $ */
+/* $OpenBSD: ldasm.S,v 1.9 2013/04/05 12:58:03 kurt Exp $ */
/*
* Copyright (c) 2004 Michael Shalayeff
@@ -263,6 +263,24 @@ ENTRY(_dl_gettimeofday,0)
nop
EXIT(_dl_gettimeofday)
+ENTRY(_dl_readlink,0)
+ SYSCALL(readlink)
+ bv r0(rp)
+ nop
+EXIT(_dl_readlink)
+
+ENTRY(_dl_lstat,0)
+ SYSCALL(lstat)
+ bv r0(rp)
+ nop
+EXIT(_dl_lstat)
+
+ENTRY(_dl_getcwd,0)
+ SYSCALL(__getcwd)
+ bv r0(rp)
+ nop
+EXIT(_dl_getcwd)
+
ENTRY(_dl_sigprocmask,0)
stw arg2, HPPA_FRAME_ARG(2)(sp)
diff --git a/libexec/ld.so/hppa/syscall.h b/libexec/ld.so/hppa/syscall.h
index b96dc87f530..9cf7dc62c14 100644
--- a/libexec/ld.so/hppa/syscall.h
+++ b/libexec/ld.so/hppa/syscall.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: syscall.h,v 1.6 2012/10/24 03:26:56 guenther Exp $ */
+/* $OpenBSD: syscall.h,v 1.7 2013/04/05 12:58:03 kurt Exp $ */
/*
* Copyright (c) 2001 Niklas Hallqvist
@@ -53,6 +53,9 @@ int _dl_getdirentries(int, char*, int, off_t *);
int _dl_sigprocmask(int, const sigset_t *, sigset_t *);
int _dl_sysctl(int *, u_int, void *, size_t *, void *, size_t);
int _dl_gettimeofday(struct timeval *tp, struct timezone *tzp);
+int _dl_readlink(const char *path, char *buf, size_t bufsiz);
+int _dl_lstat(const char *path, struct stat *sb);
+int _dl_getcwd(char *buf, size_t size);
static inline off_t
_dl_lseek(int fildes, off_t offset, int whence)
diff --git a/libexec/ld.so/i386/ldasm.S b/libexec/ld.so/i386/ldasm.S
index dac6d208c87..149bbe76494 100644
--- a/libexec/ld.so/i386/ldasm.S
+++ b/libexec/ld.so/i386/ldasm.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldasm.S,v 1.12 2012/10/24 03:26:56 guenther Exp $ */
+/* $OpenBSD: ldasm.S,v 1.13 2013/04/05 12:58:03 kurt Exp $ */
/*
* Copyright (c) 2002 Dale Rahn
@@ -117,6 +117,9 @@ DL_SYSCALL(write)
DL_SYSCALL(fstat)
DL_SYSCALL(fcntl)
DL_SYSCALL(gettimeofday)
+DL_SYSCALL(readlink)
+DL_SYSCALL(lstat)
+DL_SYSCALL2(getcwd,__getcwd)
DL_SYSCALL2(sysctl,__sysctl)
DL_SYSCALL(getdirentries)
diff --git a/libexec/ld.so/i386/syscall.h b/libexec/ld.so/i386/syscall.h
index 9629dcb311b..68f72f6941e 100644
--- a/libexec/ld.so/i386/syscall.h
+++ b/libexec/ld.so/i386/syscall.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: syscall.h,v 1.10 2012/10/24 03:26:56 guenther Exp $ */
+/* $OpenBSD: syscall.h,v 1.11 2013/04/05 12:58:03 kurt Exp $ */
/*
* Copyright (c) 2001 Niklas Hallqvist
@@ -53,6 +53,9 @@ int _dl_getdirentries(int, char*, int, off_t *);
int _dl_sigprocmask(int, const sigset_t *, sigset_t *);
int _dl_sysctl(int *, u_int, void *, size_t *, void *, size_t);
int _dl_gettimeofday(struct timeval *tp, struct timezone *tzp);
+int _dl_readlink(const char *path, char *buf, size_t bufsiz);
+int _dl_lstat(const char *path, struct stat *sb);
+int _dl_getcwd(char *buf, size_t size);
static inline off_t
_dl_lseek(int fildes, off_t offset, int whence)
diff --git a/libexec/ld.so/loader.c b/libexec/ld.so/loader.c
index 8e6ac3ce016..fdda79de64c 100644
--- a/libexec/ld.so/loader.c
+++ b/libexec/ld.so/loader.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: loader.c,v 1.131 2013/03/20 21:49:59 kurt Exp $ */
+/* $OpenBSD: loader.c,v 1.132 2013/04/05 12:58:03 kurt Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -76,6 +76,8 @@ char *_dl_noprebind;
char *_dl_prebind_validate;
char *_dl_tracefmt1, *_dl_tracefmt2, *_dl_traceprog;
+int _dl_trust;
+
struct r_debug *_dl_debug_map;
void _dl_dopreload(char *paths);
@@ -230,7 +232,8 @@ _dl_setup_env(char **envp)
* Don't allow someone to change the search paths if he runs
* a suid program without credentials high enough.
*/
- if (_dl_issetugid()) { /* Zap paths if s[ug]id... */
+ _dl_trust = !_dl_issetugid();
+ if (!_dl_trust) { /* Zap paths if s[ug]id... */
if (_dl_libpath) {
_dl_free_path(_dl_libpath);
_dl_libpath = NULL;
diff --git a/libexec/ld.so/m68k/ldasm.S b/libexec/ld.so/m68k/ldasm.S
index 2b51a95b73f..59a647435ea 100644
--- a/libexec/ld.so/m68k/ldasm.S
+++ b/libexec/ld.so/m68k/ldasm.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldasm.S,v 1.2 2013/02/02 13:37:02 miod Exp $ */
+/* $OpenBSD: ldasm.S,v 1.3 2013/04/05 12:58:03 kurt Exp $ */
/*
* Copyright (c) 2006 Dale Rahn
@@ -176,6 +176,15 @@ DL_SYSCALL(fcntl)
DL_SYSCALL(gettimeofday)
rts
+DL_SYSCALL(readlink)
+ rts
+
+DL_SYSCALL(lstat)
+ rts
+
+DL_SYSCALL2(getcwd,__getcwd)
+ rts
+
DL_SYSCALL2(sysctl,__sysctl)
rts
diff --git a/libexec/ld.so/m68k/syscall.h b/libexec/ld.so/m68k/syscall.h
index 656445e3937..e635a3be102 100644
--- a/libexec/ld.so/m68k/syscall.h
+++ b/libexec/ld.so/m68k/syscall.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: syscall.h,v 1.1 2013/01/23 19:15:58 miod Exp $ */
+/* $OpenBSD: syscall.h,v 1.2 2013/04/05 12:58:03 kurt Exp $ */
/*
* Copyright (c) 2001 Niklas Hallqvist
@@ -53,6 +53,9 @@ int _dl_getdirentries(int, char*, int, off_t *);
int _dl_sigprocmask(int, const sigset_t *, sigset_t *);
int _dl_sysctl(int *, u_int, void *, size_t *, void *, size_t);
int _dl_gettimeofday(struct timeval *tp, struct timezone *tzp);
+int _dl_readlink(const char *path, char *buf, size_t bufsiz);
+int _dl_lstat(const char *path, struct stat *sb);
+int _dl_getcwd(char *buf, size_t size);
static inline off_t
_dl_lseek(int fildes, off_t offset, int whence)
diff --git a/libexec/ld.so/m88k/ldasm.S b/libexec/ld.so/m88k/ldasm.S
index 2e2f8382b87..3633da6a64f 100644
--- a/libexec/ld.so/m88k/ldasm.S
+++ b/libexec/ld.so/m88k/ldasm.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldasm.S,v 1.4 2013/01/26 20:40:42 miod Exp $ */
+/* $OpenBSD: ldasm.S,v 1.5 2013/04/05 12:58:03 kurt Exp $ */
/*
* Copyright (c) 2013 Miodrag Vallat.
@@ -197,6 +197,15 @@ DL_SYSCALL(fcntl)
DL_SYSCALL(gettimeofday)
jmp %r1
+DL_SYSCALL(readlink)
+ jmp %r1
+
+DL_SYSCALL(lstat)
+ jmp %r1
+
+DL_SYSCALL2(getcwd,__getcwd)
+ jmp %r1
+
DL_SYSCALL2(sysctl,__sysctl)
jmp %r1
diff --git a/libexec/ld.so/m88k/syscall.h b/libexec/ld.so/m88k/syscall.h
index dade9bbf74a..981c5d6e5ce 100644
--- a/libexec/ld.so/m88k/syscall.h
+++ b/libexec/ld.so/m88k/syscall.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: syscall.h,v 1.2 2013/01/23 19:01:44 miod Exp $ */
+/* $OpenBSD: syscall.h,v 1.3 2013/04/05 12:58:03 kurt Exp $ */
/*
* Copyright (c) 2001 Niklas Hallqvist
@@ -53,6 +53,9 @@ int _dl_getdirentries(int, char*, int, off_t *);
int _dl_sigprocmask(int, const sigset_t *, sigset_t *);
int _dl_sysctl(int *, u_int, void *, size_t *, void *, size_t);
int _dl_gettimeofday(struct timeval *tp, struct timezone *tzp);
+int _dl_readlink(const char *path, char *buf, size_t bufsiz);
+int _dl_lstat(const char *path, struct stat *sb);
+int _dl_getcwd(char *buf, size_t size);
static inline off_t
_dl_lseek(int fildes, off_t offset, int whence)
diff --git a/libexec/ld.so/mips64/syscall.h b/libexec/ld.so/mips64/syscall.h
index 51128092656..d0316c15ff1 100644
--- a/libexec/ld.so/mips64/syscall.h
+++ b/libexec/ld.so/mips64/syscall.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: syscall.h,v 1.8 2012/10/24 03:26:56 guenther Exp $ */
+/* $OpenBSD: syscall.h,v 1.9 2013/04/05 12:58:03 kurt Exp $ */
/*
* Copyright (c) 1998-2002 Opsycon AB, Sweden.
@@ -295,6 +295,7 @@ _dl_sigprocmask(int how, const sigset_t *set, sigset_t *oset)
return 0;
}
+
static inline int
_dl_sysctl(int *name, u_int namelen, void *oldp, size_t *oldplen, void *newp,
size_t newlen)
@@ -320,6 +321,7 @@ _dl_sysctl(int *name, u_int namelen, void *oldp, size_t *oldplen, void *newp,
"$10","$11","$12","$13","$14","$15","$24","$25");
return status;
}
+
extern inline int
_dl_gettimeofday(struct timeval* tp, struct timezone *tzp)
{
@@ -340,4 +342,65 @@ _dl_gettimeofday(struct timeval* tp, struct timezone *tzp)
return status;
}
+extern inline int
+_dl_readlink(const char *path, char *buf, size_t bufsiz)
+{
+ register int status __asm__ ("$2");
+
+ __asm__ volatile (
+ "move $4,%2\n\t"
+ "move $5,%3\n\t"
+ "move $6,%4\n\t"
+ "li $2,%1\n\t"
+ "syscall\n\t"
+ "beq $7,$0,1f\n\t"
+ "li $2,-1\n\t"
+ "1:"
+ : "=r" (status)
+ : "I" (SYS_readlink), "r" (path), "r" (buf), "r" (bufsiz)
+ : "memory", "$3", "$4", "$5", "$6", "$7", "$8", "$9",
+ "$10","$11","$12","$13","$14","$15","$24","$25");
+ return status;
+}
+
+extern inline int
+_dl_lstat(const char *path, struct stat *sb)
+{
+ register int status __asm__ ("$2");
+
+ __asm__ volatile (
+ "move $4,%2\n\t"
+ "move $5,%3\n\t"
+ "li $2,%1\n\t"
+ "syscall\n\t"
+ "beq $7,$0,1f\n\t"
+ "li $2,-1\n\t"
+ "1:"
+ : "=r" (status)
+ : "I" (SYS_lstat), "r" (path), "r" (sb)
+ : "memory", "$3", "$4", "$5", "$6", "$7", "$8", "$9",
+ "$10","$11","$12","$13","$14","$15","$24","$25");
+ return status;
+}
+
+static inline int
+_dl_getcwd(char *buf, size_t size)
+{
+ register int status __asm__ ("$2");
+
+ __asm__ volatile (
+ "move $4,%2\n\t"
+ "move $5,%3\n\t"
+ "li $2,%1\n\t"
+ "syscall\n\t"
+ "beq $7,$0,1f\n\t"
+ "li $2,-1\n\t"
+ "1:"
+ : "=r" (status)
+ : "I" (SYS___getcwd), "r" (buf), "r" (size)
+ : "memory", "$3", "$4", "$5", "$6", "$7", "$8", "$9",
+ "$10","$11","$12","$13","$14","$15","$24","$25");
+ return status;
+}
+
#endif /*__DL_SYSCALL_H__*/
diff --git a/libexec/ld.so/powerpc/syscall.h b/libexec/ld.so/powerpc/syscall.h
index 4d7b4bc16f9..3463d2a5d9f 100644
--- a/libexec/ld.so/powerpc/syscall.h
+++ b/libexec/ld.so/powerpc/syscall.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: syscall.h,v 1.24 2012/10/24 03:26:56 guenther Exp $ */
+/* $OpenBSD: syscall.h,v 1.25 2013/04/05 12:58:03 kurt Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -308,6 +308,7 @@ _dl_sigprocmask(int how, const sigset_t *set, sigset_t *oset)
return 0;
}
+
static inline int
_dl_sysctl(int *name, u_int namelen, void *oldp, size_t *oldplen, void *newp,
size_t newlen)
@@ -333,6 +334,7 @@ _dl_sysctl(int *name, u_int namelen, void *oldp, size_t *oldplen, void *newp,
: "memory", "0", "3", "4", "5", "6", "7", "8");
return status;
}
+
static inline int
_dl_gettimeofday(struct timeval *tp, struct timezone *tzp)
{
@@ -353,6 +355,66 @@ _dl_gettimeofday(struct timeval *tp, struct timezone *tzp)
return status;
}
+static inline int
+_dl_readlink(const char *path, char *buf, size_t bufsiz)
+{
+ register int status;
+
+ __asm__ volatile ("li 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:"
+ "mr %0,3\n\t"
+ : "=r" (status)
+ : "I" (SYS_readlink), "r" (path), "r" (buf), "r" (bufsiz)
+ : "memory", "0", "3", "4", "5");
+ return status;
+}
+
+static inline int
+_dl_lstat(const char *path, struct stat *sb)
+{
+ register int status;
+
+ __asm__ volatile ("li 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:"
+ "mr %0,3\n\t"
+ : "=r" (status)
+ : "I" (SYS_lstat), "r" (path), "r" (sb)
+ : "memory", "0", "3", "4" );
+ return status;
+}
+
+static inline int
+_dl_getcwd(char *buf, size_t size)
+{
+ register int status;
+
+ __asm__ volatile ("li 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:"
+ "mr %0,3\n\t"
+ : "=r" (status)
+ : "I" (SYS___getcwd), "r" (buf), "r" (size)
+ : "0", "3", "4");
+ return status;
+}
#endif /*__DL_SYSCALL_H__*/
diff --git a/libexec/ld.so/resolve.c b/libexec/ld.so/resolve.c
index f2ba69332dc..8a232c88a32 100644
--- a/libexec/ld.so/resolve.c
+++ b/libexec/ld.so/resolve.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: resolve.c,v 1.60 2013/03/20 21:49:59 kurt Exp $ */
+/* $OpenBSD: resolve.c,v 1.61 2013/04/05 12:58:03 kurt Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -30,6 +30,7 @@
#include <sys/types.h>
+#include <limits.h>
#include <nlist.h>
#include <link.h>
#include "syscall.h"
@@ -38,6 +39,11 @@
#include "resolve.h"
#include "dl_prebind.h"
+/* substitution types */
+typedef enum {
+ SUBST_UNKNOWN, SUBST_ORIGIN, SUBST_OSNAME, SUBST_OSREL, SUBST_PLATFORM
+} SUBST_TYPES;
+
elf_object_t *_dl_objects;
elf_object_t *_dl_last_object;
elf_object_t *_dl_loading_object;
@@ -75,6 +81,159 @@ _dl_add_object(elf_object_t *object)
}
/*
+ * Identify substitution sequence name.
+ */
+static int
+_dl_subst_name(const char *name, size_t siz) {
+ switch (siz) {
+ case 5:
+ if (_dl_strncmp(name, "OSREL", 5) == 0)
+ return SUBST_OSREL;
+ break;
+ case 6:
+ if (_dl_strncmp(name, "ORIGIN", 6) == 0)
+ return SUBST_ORIGIN;
+ if (_dl_strncmp(name, "OSNAME", 6) == 0)
+ return SUBST_OSNAME;
+ break;
+ case 8:
+ if (_dl_strncmp(name, "PLATFORM", 8) == 0)
+ return SUBST_PLATFORM;
+ break;
+ }
+
+ return (SUBST_UNKNOWN);
+}
+
+/*
+ * Perform $ORIGIN substitutions on path
+ */
+static void
+_dl_origin_subst_path(elf_object_t *object, const char *origin_path,
+ char **path)
+{
+ char tmp_path[PATH_MAX];
+ char *new_path, *tp;
+ const char *pp, *name, *value;
+ static struct utsname uts;
+ size_t value_len;
+ int skip_brace;
+
+ if (uts.sysname[0] == '\0') {
+ if (_dl_uname(&uts) != 0)
+ return;
+ }
+
+ tp = tmp_path;
+ pp = *path;
+
+ while (*pp != '\0' && (tp - tmp_path) < sizeof(tmp_path)) {
+
+ /* copy over chars up to but not including $ */
+ while (*pp != '\0' && *pp != '$' &&
+ (tp - tmp_path) < sizeof(tmp_path))
+ *tp++ = *pp++;
+
+ /* substitution sequence detected */
+ if (*pp == '$' && (tp - tmp_path) < sizeof(tmp_path)) {
+ pp++;
+
+ if ((skip_brace = (*pp == '{')))
+ pp++;
+
+ /* skip over name */
+ name = pp;
+ while (_dl_isalnum(*pp) || *pp == '_')
+ pp++;
+
+ switch (_dl_subst_name(name, pp - name)) {
+ case SUBST_ORIGIN:
+ value = origin_path;
+ break;
+ case SUBST_OSNAME:
+ value = uts.sysname;
+ break;
+ case SUBST_OSREL:
+ value = uts.release;
+ break;
+ case SUBST_PLATFORM:
+ value = uts.machine;
+ break;
+ default:
+ value = "";
+ }
+
+ value_len = _dl_strlen(value);
+ if (value_len >= sizeof(tmp_path) - (tp - tmp_path))
+ return;
+
+ _dl_bcopy(value, tp, value_len);
+ tp += value_len;
+
+ if (skip_brace && *pp == '}')
+ pp++;
+ }
+ }
+
+ /* no substitution made if result exceeds sizeof(tmp_path) */
+ if (tp - tmp_path >= sizeof(tmp_path))
+ return;
+
+ /* NULL terminate tmp_path */
+ *tp = '\0';
+
+ if (_dl_strcmp(tmp_path, *path) == 0)
+ return;
+
+ new_path = _dl_strdup(tmp_path);
+ if (new_path == NULL)
+ return;
+
+ DL_DEB(("orig_path %s\n", *path));
+ DL_DEB(("new_path %s\n", new_path));
+
+ _dl_free(*path);
+ *path = new_path;
+}
+
+/*
+ * Determine origin_path from object load_name. The origin_path argument
+ * must refer to a buffer capable of storing at least PATH_MAX characters.
+ * Returns 0 on success.
+ */
+static int
+_dl_origin_path(elf_object_t *object, char *origin_path)
+{
+ const char *dirname_path = _dl_dirname(object->load_name);
+
+ if (dirname_path == NULL)
+ return -1;
+
+ if (_dl_realpath(dirname_path, origin_path) == NULL)
+ return -1;
+
+ return 0;
+}
+
+/*
+ * Perform $ORIGIN substitutions on rpath
+ */
+static void
+_dl_origin_subst(elf_object_t *object)
+{
+ char origin_path[PATH_MAX];
+ char **pp;
+
+ if (_dl_origin_path(object, origin_path) != 0)
+ return;
+
+ /* perform path substitutions on each segment of rpath */
+ for (pp = object->rpath; *pp != NULL; pp++) {
+ _dl_origin_subst_path(object, origin_path, pp);
+ }
+}
+
+/*
* Initialize a new dynamic object.
*/
elf_object_t *
@@ -183,10 +342,13 @@ _dl_finalize_object(const char *objname, Elf_Dyn *dynp, Elf_Phdr *phdrp,
TAILQ_INIT(&object->grpsym_list);
TAILQ_INIT(&object->grpref_list);
- if (object->dyn.rpath)
+ if (object->dyn.rpath) {
object->rpath = _dl_split_path(object->dyn.rpath);
+ if ((object->obj_flags & DF_1_ORIGIN) && _dl_trust)
+ _dl_origin_subst(object);
+ }
- return(object);
+ return (object);
}
void
diff --git a/libexec/ld.so/resolve.h b/libexec/ld.so/resolve.h
index 9b566e62c11..3ebfe7061d5 100644
--- a/libexec/ld.so/resolve.h
+++ b/libexec/ld.so/resolve.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: resolve.h,v 1.66 2013/03/20 21:49:59 kurt Exp $ */
+/* $OpenBSD: resolve.h,v 1.67 2013/04/05 12:58:03 kurt Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -254,6 +254,8 @@ extern char *_dl_tracefmt2;
extern char *_dl_traceprog;
extern char *_dl_debug;
+extern int _dl_trust;
+
#define DL_DEB(P) do { if (_dl_debug) _dl_printf P ; } while (0)
#define DL_NOT_FOUND 1
diff --git a/libexec/ld.so/sh/ldasm.S b/libexec/ld.so/sh/ldasm.S
index 29dad9de690..09c11e6825d 100644
--- a/libexec/ld.so/sh/ldasm.S
+++ b/libexec/ld.so/sh/ldasm.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldasm.S,v 1.9 2012/11/01 10:25:33 kettenis Exp $ */
+/* $OpenBSD: ldasm.S,v 1.10 2013/04/05 12:58:03 kurt Exp $ */
/*
* Copyright (c) 2006 Dale Rahn
@@ -195,6 +195,9 @@ DL_SYSCALL(write)
DL_SYSCALL(fstat)
DL_SYSCALL(fcntl)
DL_SYSCALL(gettimeofday)
+DL_SYSCALL(readlink)
+DL_SYSCALL(lstat)
+DL_SYSCALL2(getcwd,__getcwd)
DL_SYSCALL2(sysctl,__sysctl)
DL_SYSCALL(getdirentries)
diff --git a/libexec/ld.so/sh/syscall.h b/libexec/ld.so/sh/syscall.h
index fddd0a820dd..7ef83f0871e 100644
--- a/libexec/ld.so/sh/syscall.h
+++ b/libexec/ld.so/sh/syscall.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: syscall.h,v 1.4 2012/10/24 03:26:56 guenther Exp $ */
+/* $OpenBSD: syscall.h,v 1.5 2013/04/05 12:58:03 kurt Exp $ */
/*
* Copyright (c) 2001 Niklas Hallqvist
@@ -53,6 +53,9 @@ int _dl_getdirentries(int, char*, int, off_t *);
int _dl_sigprocmask(int, const sigset_t *, sigset_t *);
int _dl_sysctl(int *, u_int, void *, size_t *, void *, size_t);
int _dl_gettimeofday(struct timeval *tp, struct timezone *tzp);
+int _dl_readlink(const char *path, char *buf, size_t bufsiz);
+int _dl_lstat(const char *path, struct stat *sb);
+int _dl_getcwd(char *buf, size_t size);
static inline off_t
_dl_lseek(int fildes, off_t offset, int whence)
diff --git a/libexec/ld.so/sparc/ldasm.S b/libexec/ld.so/sparc/ldasm.S
index 028b07dc5a3..cda4c8810d2 100644
--- a/libexec/ld.so/sparc/ldasm.S
+++ b/libexec/ld.so/sparc/ldasm.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldasm.S,v 1.18 2012/10/24 03:26:56 guenther Exp $ */
+/* $OpenBSD: ldasm.S,v 1.19 2013/04/05 12:58:03 kurt Exp $ */
/*
* Copyright (c) 2001 Jason L. Wright (jason@thought.net)
@@ -318,6 +318,43 @@ _dl_gettimeofday:
retl
sub %g0, %o0, %o0 ! error: result = -errno
+
+ .section ".text"
+ .align 4
+ .global _dl_readlink
+ .type _dl_readlink,@function
+_dl_readlink:
+ mov SYS_readlink | SYSCALL_G2RFLAG, %g1 ! calling sys_readlink
+ 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
+ .global _dl_lstat
+ .type _dl_lstat,@function
+_dl_lstat:
+ mov SYS_lstat | SYSCALL_G2RFLAG, %g1 ! calling sys_lstat
+ 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
+ .global _dl_getcwd
+ .type _dl_getcwd,@function
+_dl_getcwd:
+ mov SYS___getcwd | SYSCALL_G2RFLAG, %g1 ! calling sys_getcwd
+ add %o7, 8, %g2 ! just return on success
+ t ST_SYSCALL ! off to wonderland
+ retl
+ sub %g0, %o0, %o0 ! error: result = -errno
+
+
/*
* V8 sparc .{,u}{mul,div,rem} replacements.
* We try to mimic them 100%. Full 64 bit sources or outputs, and
diff --git a/libexec/ld.so/sparc/syscall.h b/libexec/ld.so/sparc/syscall.h
index 9335fe2c6c5..9e57c300d59 100644
--- a/libexec/ld.so/sparc/syscall.h
+++ b/libexec/ld.so/sparc/syscall.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: syscall.h,v 1.11 2012/10/24 03:26:56 guenther Exp $ */
+/* $OpenBSD: syscall.h,v 1.12 2013/04/05 12:58:03 kurt Exp $ */
/*
* Copyright (c) 2001 Niklas Hallqvist
@@ -53,6 +53,9 @@ int _dl_getdirentries(int, char*, int, off_t *);
int _dl_sigprocmask(int, const sigset_t *, sigset_t *);
int _dl_sysctl(int *, u_int, void *, size_t *, void *, size_t);
int _dl_gettimeofday(struct timeval *tp, struct timezone *tzp);
+int _dl_readlink(const char *path, char *buf, size_t bufsiz);
+int _dl_lstat(const char *path, struct stat *sb);
+int _dl_getcwd(char *buf, size_t size);
static inline off_t
_dl_lseek(int fildes, off_t offset, int whence)
diff --git a/libexec/ld.so/sparc64/ldasm.S b/libexec/ld.so/sparc64/ldasm.S
index f23719ea789..92721d86de6 100644
--- a/libexec/ld.so/sparc64/ldasm.S
+++ b/libexec/ld.so/sparc64/ldasm.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldasm.S,v 1.29 2012/10/24 03:26:56 guenther Exp $ */
+/* $OpenBSD: ldasm.S,v 1.30 2013/04/05 12:58:03 kurt Exp $ */
/* $NetBSD: rtld_start.S,v 1.5 2001/08/14 22:17:48 eeh Exp $ */
/*
@@ -315,3 +315,24 @@ _ENTRY(_dl_gettimeofday)
retl
sub %g0, %o0, %o0 ! error: result = -errno
+_ENTRY(_dl_readlink)
+ mov SYS_readlink | SYSCALL_G2RFLAG, %g1 ! calling sys_readlink
+ add %o7, 8, %g2 ! just return on success
+ t ST_SYSCALL ! off to wonderland
+ retl
+ sub %g0, %o0, %o0 ! error: result = -errno
+
+_ENTRY(_dl_lstat)
+ mov SYS_lstat | SYSCALL_G2RFLAG, %g1 ! calling sys_lstat
+ add %o7, 8, %g2 ! just return on success
+ t ST_SYSCALL ! off to wonderland
+ retl
+ sub %g0, %o0, %o0 ! error: result = -errno
+
+_ENTRY(_dl_getcwd)
+ mov SYS___getcwd | SYSCALL_G2RFLAG, %g1 ! calling sys___getcwd
+ 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/syscall.h b/libexec/ld.so/sparc64/syscall.h
index 91240a4a5f1..2b7c1192c57 100644
--- a/libexec/ld.so/sparc64/syscall.h
+++ b/libexec/ld.so/sparc64/syscall.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: syscall.h,v 1.18 2012/10/24 03:26:56 guenther Exp $ */
+/* $OpenBSD: syscall.h,v 1.19 2013/04/05 12:58:04 kurt Exp $ */
/*
* Copyright (c) 2001 Niklas Hallqvist
@@ -53,6 +53,9 @@ int _dl_getdirentries(int, char*, int, off_t *);
int _dl_sigprocmask(int, const sigset_t *, sigset_t *);
int _dl_sysctl(int *, u_int, void *, size_t *, void *, size_t);
int _dl_gettimeofday(struct timeval *tp, struct timezone *tzp);
+int _dl_readlink(const char *path, char *buf, size_t bufsiz);
+int _dl_lstat(const char *path, struct stat *sb);
+int _dl_getcwd(char *buf, size_t size);
static inline off_t
_dl_lseek(int fildes, off_t offset, int whence)
diff --git a/libexec/ld.so/util.h b/libexec/ld.so/util.h
index b2368ef54f3..45115aa7cce 100644
--- a/libexec/ld.so/util.h
+++ b/libexec/ld.so/util.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: util.h,v 1.22 2012/08/07 17:47:06 matthew Exp $ */
+/* $OpenBSD: util.h,v 1.23 2013/04/05 12:58:03 kurt Exp $ */
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
@@ -31,11 +31,14 @@
#ifndef __DL_UTIL_H__
#define __DL_UTIL_H__
+#include <sys/utsname.h>
#include <stdarg.h>
void *_dl_malloc(const size_t size);
void _dl_free(void *);
char *_dl_strdup(const char *);
+size_t _dl_strlen(const char *);
+size_t _dl_strlcat(char *dst, const char *src, size_t siz);
void _dl_printf(const char *fmt, ...);
void _dl_vprintf(const char *fmt, va_list ap);
void _dl_fdprintf(int, const char *fmt, ...);
@@ -43,6 +46,9 @@ void _dl_show_objects(void);
void _dl_randombuf(void *, size_t);
unsigned int _dl_random(void);
ssize_t _dl_write(int fd, const char* buf, size_t len);
+char * _dl_dirname(const char *path);
+char *_dl_realpath(const char *path, char *resolved);
+int _dl_uname(struct utsname *name);
long _dl_strtol(const char *nptr, char **endptr, int base);
@@ -87,16 +93,6 @@ _dl_bcopy(const void *src, void *dest, int size)
pdest[i] = psrc[i];
}
-static inline int
-_dl_strlen(const char *str)
-{
- const char *s;
-
- for (s = str; *s; ++s)
- ;
- return (s - str);
-}
-
static inline size_t
_dl_strlcpy(char *dst, const char *src, size_t siz)
{
@@ -189,4 +185,10 @@ _dl_strstr(const char *s, const char *find)
return ((char *)s);
}
+static inline int
+_dl_isalnum(const char c)
+{
+ return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9');
+}
+
#endif /*__DL_UTIL_H__*/