NetBSD re-synchronization of the source tree

This brings our tree to NetBSD 7.0, as found on -current on the
10-10-2015.

This updates:
 - LLVM to 3.6.1
 - GCC to GCC 5.1
 - Replace minix/commands/zdump with usr.bin/zdump
 - external/bsd/libelf has moved to /external/bsd/elftoolchain/
 - Import ctwm
 - Drop sprintf from libminc

Change-Id: I149836ac18e9326be9353958bab9b266efb056f0
This commit is contained in:
2016-01-13 20:32:14 +01:00
parent 8933525b85
commit 0a6a1f1d05
32425 changed files with 2998492 additions and 1342217 deletions
+1
View File
@@ -7,6 +7,7 @@ SUBDIR= \
fingerd ftpd getty \
ld.elf_so \
rshd \
+7 -3
View File
@@ -1,21 +1,25 @@
# $NetBSD: Makefile,v 1.63 2011/08/14 11:46:28 christos Exp $
# $NetBSD: Makefile,v 1.64 2015/01/25 15:53:49 christos Exp $
# @(#)Makefile 8.2 (Berkeley) 4/4/94
.include <bsd.own.mk>
PROG= ftpd
SRCS= cmds.c conf.c ftpd.c ftpcmd.y logutmp.c logwtmp.c popen.c
.ifdef __MINIX
.if defined(__MINIX)
WARNS= # BJG too many warnings with clang right now
CPPFLAGS+=-I${.CURDIR}
.else
CPPFLAGS+=-I${.CURDIR} -DSUPPORT_UTMP -DSUPPORT_UTMPX -DLOGIN_CAP
.endif
.endif # defined(__MINIX)
DPADD+= ${LIBCRYPT} ${LIBUTIL}
LDADD+= -lcrypt -lutil
MAN= ftpd.conf.5 ftpusers.5 ftpd.8
MLINKS= ftpusers.5 ftpchroot.5
SRCS+= pfilter.c
LDADD+= -lblacklist
DPADD+= ${LIBBLACKLIST}
.if defined(NO_INTERNAL_LS)
CPPFLAGS+=-DNO_INTERNAL_LS
.else
+5 -3
View File
@@ -1,4 +1,4 @@
/* $NetBSD: cmds.c,v 1.33 2013/07/03 14:15:47 christos Exp $ */
/* $NetBSD: cmds.c,v 1.34 2015/08/10 07:32:49 shm Exp $ */
/*
* Copyright (c) 1999-2009 The NetBSD Foundation, Inc.
@@ -90,7 +90,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: cmds.c,v 1.33 2013/07/03 14:15:47 christos Exp $");
__RCSID("$NetBSD: cmds.c,v 1.34 2015/08/10 07:32:49 shm Exp $");
#endif /* not lint */
#include <sys/param.h>
@@ -249,8 +249,10 @@ mlsd(const char *path)
goto mlsdperror;
dout = dataconn("MLSD", (off_t)-1, "w");
if (dout == NULL)
if (dout == NULL) {
(void) closedir(dirp);
return;
}
memset(&f, 0, sizeof(f));
f.stat = &sb;
+3 -3
View File
@@ -1,4 +1,4 @@
/* $NetBSD: ftpcmd.y,v 1.93 2011/09/16 16:13:17 plunky Exp $ */
/* $NetBSD: ftpcmd.y,v 1.94 2015/08/10 07:45:50 shm Exp $ */
/*-
* Copyright (c) 1997-2009 The NetBSD Foundation, Inc.
@@ -72,7 +72,7 @@
#if 0
static char sccsid[] = "@(#)ftpcmd.y 8.3 (Berkeley) 4/6/94";
#else
__RCSID("$NetBSD: ftpcmd.y,v 1.93 2011/09/16 16:13:17 plunky Exp $");
__RCSID("$NetBSD: ftpcmd.y,v 1.94 2015/08/10 07:45:50 shm Exp $");
#endif
#endif /* not lint */
@@ -193,7 +193,7 @@ cmd
| PASS SP password CRLF
{
pass($3);
memset($3, 0, strlen($3));
explicit_memset($3, 0, strlen($3));
free($3);
}
+20 -20
View File
@@ -1,4 +1,4 @@
/* $NetBSD: ftpd.c,v 1.200 2013/07/31 19:50:47 christos Exp $ */
/* $NetBSD: ftpd.c,v 1.202 2015/08/10 07:32:49 shm Exp $ */
/*
* Copyright (c) 1997-2009 The NetBSD Foundation, Inc.
@@ -97,7 +97,7 @@ __COPYRIGHT("@(#) Copyright (c) 1985, 1988, 1990, 1992, 1993, 1994\
#if 0
static char sccsid[] = "@(#)ftpd.c 8.5 (Berkeley) 4/28/95";
#else
__RCSID("$NetBSD: ftpd.c,v 1.200 2013/07/31 19:50:47 christos Exp $");
__RCSID("$NetBSD: ftpd.c,v 1.202 2015/08/10 07:32:49 shm Exp $");
#endif
#endif /* not lint */
@@ -165,6 +165,8 @@ __RCSID("$NetBSD: ftpd.c,v 1.200 2013/07/31 19:50:47 christos Exp $");
#include <security/pam_appl.h>
#endif
#include "pfilter.h"
#define GLOBAL
#include "extern.h"
#include "pathnames.h"
@@ -264,8 +266,8 @@ static enum send_status
#if !defined(__minix)
static enum send_status
send_data_with_mmap(int, int, const struct stat *, int);
static void logrusage(const struct rusage *, const struct rusage *);
#endif /* !defined(__minix) */
static void logrusage(const struct rusage *, const struct rusage *);
static void logout_utmp(void);
int main(int, char *[]);
@@ -473,6 +475,8 @@ main(int argc, char *argv[])
if (EMPTYSTR(confdir))
confdir = _DEFAULT_CONFDIR;
pfilter_open();
if (dowtmp) {
#ifdef SUPPORT_UTMPX
ftpd_initwtmpx();
@@ -1409,6 +1413,7 @@ do_pass(int pass_checked, int pass_rval, const char *passwd)
if (rval) {
reply(530, "%s", rval == 2 ? "Password expired." :
"Login incorrect.");
pfilter_notify(1, rval == 2 ? "exppass" : "badpass");
if (logging) {
syslog(LOG_NOTICE,
"FTP LOGIN FAILED FROM %s", remoteloghost);
@@ -1452,6 +1457,7 @@ do_pass(int pass_checked, int pass_rval, const char *passwd)
*remote_ip = 0;
remote_ip[sizeof(remote_ip) - 1] = 0;
if (!auth_hostok(lc, remotehost, remote_ip)) {
pfilter_notify(1, "bannedhost");
syslog(LOG_INFO|LOG_AUTH,
"FTP LOGIN FAILED (HOST) as %s: permission denied.",
pw->pw_name);
@@ -1608,8 +1614,8 @@ do_pass(int pass_checked, int pass_rval, const char *passwd)
setsid();
#if !defined(__minix)
setlogin(pw->pw_name);
#endif
#endif /* !defined(__minix) */
#endif
if (dropprivs ||
(curclass.type != CLASS_REAL &&
ntohs(ctrl_addr.su_port) > IPPORT_RESERVED + 1)) {
@@ -1694,9 +1700,7 @@ retrieve(const char *argv[], const char *name)
int (*closefunc)(FILE *) = NULL;
int dolog, sendrv, closerv, stderrfd, isconversion, isdata, isls;
struct timeval start, finish, td, *tdp;
#if !defined(__minix)
struct rusage rusage_before, rusage_after;
#endif /* !defined(__minix) */
const char *dispname;
const char *error;
@@ -1777,25 +1781,19 @@ retrieve(const char *argv[], const char *name)
if (dout == NULL)
goto done;
#if !defined(__minix)
(void)getrusage(RUSAGE_SELF, &rusage_before);
#endif /* !defined(__minix) */
(void)gettimeofday(&start, NULL);
sendrv = send_data(fin, dout, &st, isdata);
(void)gettimeofday(&finish, NULL);
#if !defined(__minix)
(void)getrusage(RUSAGE_SELF, &rusage_after);
#endif /* !defined(__minix) */
closedataconn(dout); /* close now to affect timing stats */
timersub(&finish, &start, &td);
tdp = &td;
done:
if (dolog) {
logxfer("get", byte_count, name, NULL, tdp, error);
#if !defined(__minix)
if (tdp != NULL)
logrusage(&rusage_before, &rusage_after);
#endif /* !defined(__minix) */
}
closerv = (*closefunc)(fin);
if (sendrv == 0) {
@@ -2243,14 +2241,14 @@ send_data_with_mmap(int filefd, int netfd, const struct stat *st, int isdata)
goto try_read;
return (SS_FILE_ERROR);
}
#ifndef __minix
#if !defined(__minix)
(void) madvise(win, mapsize, MADV_SEQUENTIAL);
#endif
#endif /* !defined(__minix) */
error = write_data(netfd, win, mapsize, &bufrem, &then,
isdata);
#ifndef __minix
#if !defined(__minix)
(void) madvise(win, mapsize, MADV_DONTNEED);
#endif
#endif /* !defined(__minix) */
munmap(win, mapsize);
if (urgflag && handleoobcmd())
return (SS_ABORTED);
@@ -3500,8 +3498,10 @@ send_file_list(const char *whichf)
while ((dir = readdir(dirp)) != NULL) {
char nbuf[MAXPATHLEN];
if (urgflag && handleoobcmd())
if (urgflag && handleoobcmd()) {
(void) closedir(dirp);
goto cleanup_send_file_list;
}
if (ISDOTDIR(dir->d_name) || ISDOTDOTDIR(dir->d_name))
continue;
@@ -3524,8 +3524,10 @@ send_file_list(const char *whichf)
if (dout == NULL) {
dout = dataconn("file list", (off_t)-1,
"w");
if (dout == NULL)
if (dout == NULL) {
(void) closedir(dirp);
goto cleanup_send_file_list;
}
transflag = 1;
}
p = nbuf;
@@ -3672,7 +3674,6 @@ logxfer(const char *command, off_t bytes, const char *file1, const char *file2,
}
}
#if !defined(__minix)
/*
* Log the resource usage.
*
@@ -3697,7 +3698,6 @@ logrusage(const struct rusage *rusage_before,
rusage_after->ru_majflt - rusage_before->ru_majflt,
rusage_after->ru_nswap - rusage_before->ru_nswap);
}
#endif /* !defined(__minix) */
/*
* Determine if `password' is valid for user given in `pw'.
+3 -4
View File
@@ -1,4 +1,4 @@
/* $NetBSD: logwtmp.c,v 1.25 2006/09/23 16:03:50 xtraeme Exp $ */
/* $NetBSD: logwtmp.c,v 1.27 2015/08/09 20:34:24 shm Exp $ */
/*
* Copyright (c) 1988, 1993
@@ -36,7 +36,7 @@
#if 0
static char sccsid[] = "@(#)logwtmp.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: logwtmp.c,v 1.25 2006/09/23 16:03:50 xtraeme Exp $");
__RCSID("$NetBSD: logwtmp.c,v 1.27 2015/08/09 20:34:24 shm Exp $");
#endif
#endif /* not lint */
@@ -124,13 +124,12 @@ ftpd_logwtmpx(const char *line, const char *name, const char *host,
if (fdx < 0)
return;
if (fstat(fdx, &buf) == 0) {
(void)memset(&ut, 0, sizeof(ut));
(void)strncpy(ut.ut_line, line, sizeof(ut.ut_line));
(void)strncpy(ut.ut_name, name, sizeof(ut.ut_name));
(void)strncpy(ut.ut_host, host, sizeof(ut.ut_host));
if (haddr)
(void)memcpy(&ut.ut_ss, &haddr->si_su, haddr->su_len);
else
(void)memset(&ut.ut_ss, 0, sizeof(ut.ut_ss));
ut.ut_type = utx_type;
if (WIFEXITED(status))
ut.ut_exit.e_exit = (uint16_t)WEXITSTATUS(status);
+24
View File
@@ -0,0 +1,24 @@
#include <stdio.h>
#include <blacklist.h>
#include "pfilter.h"
static struct blacklist *blstate;
void
pfilter_open(void)
{
if (blstate == NULL)
blstate = blacklist_open();
}
void
pfilter_notify(int what, const char *msg)
{
pfilter_open();
if (blstate == NULL)
return;
blacklist_r(blstate, what, 0, msg);
}
+2
View File
@@ -0,0 +1,2 @@
void pfilter_open(void);
void pfilter_notify(int, const char *);
+5 -1
View File
@@ -304,16 +304,20 @@ main(int argc, char *argv[], char *envp[])
if (argc > 1)
tname = argv[1];
for (;;) {
#if !defined(__minix)
int off;
#endif /* !defined(__minix) */
rval = 0;
gettable(tname, tabent);
if (OPset || EPset || APset)
APset++, OPset++, EPset++;
setdefaults();
#if !defined(__minix)
off = 0;
#endif /* !defined(__minix) */
(void)tcflush(0, TCIOFLUSH); /* clear out the crap */
#ifndef __minix
#if !defined(__minix)
(void)ioctl(0, FIONBIO, &off); /* turn off non-blocking mode */
(void)ioctl(0, FIOASYNC, &off); /* ditto for async mode */
#endif /* !defined(__minix) */
-1
View File
@@ -458,7 +458,6 @@ compatflags(long flags)
CLR(cflag, HUPCL);
else
SET(cflag, HUPCL);
#if !defined(__minix)
if (ISSET(flags, CRTKIL))
SET(lflag, ECHOKE);
+2 -2
View File
@@ -1,4 +1,4 @@
.\" $NetBSD: ttys.5,v 1.18 2012/04/21 12:27:28 roy Exp $
.\" $NetBSD: ttys.5,v 1.20 2015/02/12 07:32:09 aymeric Exp $
.\"
.\" Copyright (c) 1985, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -199,7 +199,7 @@ program must be run for changes in those flags to take effect on the devices.
# root login on console at 1200 baud
console "/usr/libexec/getty std.1200" vt100 on secure
# dialup at 1200 baud, no root logins
ttyd0 "/usr/libexec/getty d1200" dialup on # 555-1234
tty00 "/usr/libexec/getty d1200" dialup on # 555-1234
# Mike's terminal: hp2621
ttyh0 "/usr/libexec/getty std.9600" hp2621-nl on # 457 Evans
# John's terminal: vt100
+10 -6
View File
@@ -1,8 +1,8 @@
# $NetBSD: Makefile,v 1.125 2013/11/16 17:14:06 skrll Exp $
# $NetBSD: Makefile,v 1.129 2014/09/19 17:43:33 matt Exp $
#
# NOTE: when changing ld.so, ensure that ldd still compiles.
#
#MINIX:
USE_BITCODE=no
WARNS?=4
@@ -28,14 +28,17 @@ ARCHSUBDIR= ${MACHINE_CPU}
.endif
M= ${.CURDIR}/arch/${ARCHSUBDIR}
.if ((${LDELFSO_MACHINE_ARCH} == "alpha") || \
.if ((${MACHINE_CPU} == "aarch64") || \
(${LDELFSO_MACHINE_ARCH} == "alpha") || \
(${MACHINE_CPU} == "arm") || \
(${LDELFSO_MACHINE_ARCH} == "coldfire") || \
(${LDELFSO_MACHINE_ARCH} == "hppa") || \
(${LDELFSO_MACHINE_ARCH} == "i386") || \
(${LDELFSO_MACHINE_ARCH} == "m68k") || \
(${MACHINE_CPU} == "mips") || \
(${LDELFSO_MACHINE_ARCH} == "powerpc") || \
(${MACHINE_CPU} == "or1k") || \
(${MACHINE_CPU} == "powerpc") || \
(${MACHINE_CPU} == "riscv") || \
(${MACHINE_CPU} == "sh3") || \
(${LDELFSO_MACHINE_ARCH} == "sparc") || \
(${LDELFSO_MACHINE_ARCH} == "sparc64") || \
@@ -46,9 +49,10 @@ M= ${.CURDIR}/arch/${ARCHSUBDIR}
LDFLAGS+= ${${ACTIVE_CC} == "clang":? -Wl,-Bsymbolic : -symbolic} \
-shared -nostartfiles -nodefaultlibs
.if defined(__MINIX) && ${HAVE_GOLD:Uno} == "no"
LDFLAGS+= -Wl,-static
LDFLAGS+= -Wl,-static
.endif
LDFLAGS+= -Wl,--warn-shared-textrel
LDFLAGS+= -Wl,-Map=${.TARGET}.map
COPTS+= -fvisibility=hidden
@@ -90,7 +94,7 @@ errlist_concat.h: ${NETBSDSRCDIR}/lib/libc/gen/errlist.awk ${NETBSDSRCDIR}/sys/s
xprintf.c: errlist_concat.h
CLEANFILES+= errlist_concat.h
CLEANFILES+= errlist_concat.h ${PROG}.map
BINDIR= ${SHLINKINSTALLDIR}
-6
View File
@@ -1,6 +0,0 @@
$NetBSD: README,v 1.11 2006/11/24 22:52:16 wiz Exp $
TO DO:
* Support for coexistence of 32-bit and 64-bit ELF on platforms that can
do that.
@@ -0,0 +1,12 @@
# $NetBSD: Makefile.inc,v 1.1 2014/08/10 05:47:37 matt Exp $
SRCS+= rtld_start.S mdreloc.c
# XXX Should not be in CPPFLAGS!
CPPFLAGS+= -fpic
CPPFLAGS+= -DELFSIZE=64
CPPFLAGS+= -DHAVE_INITFINI_ARRAY
CPPFLAGS+= -DELF_NOTE_MARCH_DESC=\"${LDELFSO_MACHINE_ARCH}\"
LDFLAGS+= -Wl,-e,_rtld_start
+269
View File
@@ -0,0 +1,269 @@
/* $NetBSD: mdreloc.c,v 1.2 2014/08/25 20:40:52 joerg Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matt Thomas of 3am Software Foundry.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mdreloc.c,v 1.2 2014/08/25 20:40:52 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
#include <string.h>
#include "debug.h"
#include "rtld.h"
void _rtld_bind_start(void);
void _rtld_relocate_nonplt_self(Elf_Dyn *, Elf_Addr);
caddr_t _rtld_bind(const Obj_Entry *, Elf_Word);
void
_rtld_setup_pltgot(const Obj_Entry *obj)
{
obj->pltgot[1] = (Elf_Addr) obj;
obj->pltgot[2] = (Elf_Addr) &_rtld_bind_start;
}
void
_rtld_relocate_nonplt_self(Elf_Dyn *dynp, Elf_Addr relocbase)
{
const Elf_Rel *rel = 0, *rellim;
Elf_Addr relsz = 0;
Elf_Addr *where;
for (; dynp->d_tag != DT_NULL; dynp++) {
switch (dynp->d_tag) {
case DT_REL:
rel = (const Elf_Rel *)(relocbase + dynp->d_un.d_ptr);
break;
case DT_RELSZ:
relsz = dynp->d_un.d_val;
break;
}
}
rellim = (const Elf_Rel *)((const uint8_t *)rel + relsz);
for (; rel < rellim; rel++) {
where = (Elf_Addr *)(relocbase + rel->r_offset);
*where += (Elf_Addr)relocbase;
}
}
int
_rtld_relocate_nonplt_objects(Obj_Entry *obj)
{
for (const Elf_Rela *rela = obj->rela; rela < obj->relalim; rela++) {
Elf_Addr *where;
const Elf_Sym *def;
const Obj_Entry *defobj;
unsigned long symnum;
Elf_Addr addend;
where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
symnum = ELF_R_SYM(rela->r_info);
addend = rela->r_addend;
switch (ELF_R_TYPE(rela->r_info)) {
case R_TYPE(NONE):
break;
case R_TYPE(ABS64): /* word B + S + A */
case R_TYPE(GLOB_DAT): /* word B + S */
def = _rtld_find_symdef(symnum, obj, &defobj, false);
if (def == NULL)
return -1;
*where = addend + (Elf_Addr)defobj->relocbase +
def->st_value;
rdbg(("ABS64/GLOB_DAT %s in %s --> %p @ %p in %s",
obj->strtab + obj->symtab[symnum].st_name,
obj->path, (void *)tmp, where, defobj->path));
break;
case R_TYPE(RELATIVE): /* word B + A */
*where = addend + (Elf_Addr)obj->relocbase;
rdbg(("RELATIVE in %s --> %p", obj->path,
(void *)tmp));
break;
case R_TYPE(COPY):
/*
* These are deferred until all other relocations have
* been done. All we do here is make sure that the
* COPY relocation is not in a shared library. They
* are allowed only in executable files.
*/
if (obj->isdynamic) {
_rtld_error(
"%s: Unexpected R_COPY relocation in shared library",
obj->path);
return -1;
}
rdbg(("COPY (avoid in main)"));
break;
case R_TLS_TYPE(TLS_DTPREL):
def = _rtld_find_symdef(symnum, obj, &defobj, false);
if (def == NULL)
return -1;
*where = addend + (Elf_Addr)(def->st_value);
rdbg(("TLS_DTPOFF32 %s in %s --> %p",
obj->strtab + obj->symtab[symnum].st_name,
obj->path, (void *)tmp));
break;
case R_TLS_TYPE(TLS_DTPMOD):
def = _rtld_find_symdef(symnum, obj, &defobj, false);
if (def == NULL)
return -1;
*where = (Elf_Addr)(defobj->tlsindex);
rdbg(("TLS_DTPMOD %s in %s --> %p",
obj->strtab + obj->symtab[symnum].st_name,
obj->path, (void *)tmp));
break;
case R_TLS_TYPE(TLS_TPREL):
def = _rtld_find_symdef(symnum, obj, &defobj, false);
if (def == NULL)
return -1;
if (!defobj->tls_done &&
_rtld_tls_offset_allocate(obj))
return -1;
*where = (Elf_Addr)def->st_value + defobj->tlsoffset +
sizeof(struct tls_tcb);
rdbg(("TLS_TPOFF32 %s in %s --> %p",
obj->strtab + obj->symtab[symnum].st_name,
obj->path, (void *)tmp));
break;
default:
rdbg(("sym = %lu, type = %lu, offset = %p, "
"contents = %p, symbol = %s",
symnum, (u_long)ELF_R_TYPE(rela->r_info),
(void *)rela->r_offset, *where,
obj->strtab + obj->symtab[symnum].st_name));
_rtld_error("%s: Unsupported relocation type %ld "
"in non-PLT relocations",
obj->path, (u_long) ELF_R_TYPE(rela->r_info));
return -1;
}
}
return 0;
}
int
_rtld_relocate_plt_lazy(const Obj_Entry *obj)
{
if (!obj->relocbase)
return 0;
for (const Elf_Rel *rel = obj->pltrel; rel < obj->pltrellim; rel++) {
Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
assert(ELF_R_TYPE(rel->r_info) == R_TYPE(JUMP_SLOT));
/* Just relocate the GOT slots pointing into the PLT */
*where += (Elf_Addr)obj->relocbase;
rdbg(("fixup !main in %s --> %p", obj->path, (void *)*where));
}
return 0;
}
static int
_rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rel *rel,
Elf_Addr *tp)
{
Elf_Addr *where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
Elf_Addr new_value;
const Elf_Sym *def;
const Obj_Entry *defobj;
unsigned long info = rel->r_info;
assert(ELF_R_TYPE(info) == R_TYPE(JUMP_SLOT));
def = _rtld_find_plt_symdef(ELF_R_SYM(info), obj, &defobj, tp != NULL);
if (__predict_false(def == NULL))
return -1;
if (__predict_false(def == &_rtld_sym_zero))
return 0;
if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
if (tp == NULL)
return 0;
new_value = _rtld_resolve_ifunc(defobj, def);
} else {
new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
}
rdbg(("bind now/fixup in %s --> old=%p new=%p",
defobj->strtab + def->st_name, (void *)*where, (void *)new_value));
if (*where != new_value)
*where = new_value;
if (tp)
*tp = new_value;
return 0;
}
caddr_t
_rtld_bind(const Obj_Entry *obj, Elf_Word reloff)
{
const Elf_Rel *rel = obj->pltrel + reloff;
Elf_Addr new_value = 0; /* XXX gcc */
_rtld_shared_enter();
int err = _rtld_relocate_plt_object(obj, rel, &new_value);
if (err)
_rtld_die();
_rtld_shared_exit();
return (caddr_t)new_value;
}
int
_rtld_relocate_plt_objects(const Obj_Entry *obj)
{
const Elf_Rel *rel;
int err = 0;
for (rel = obj->pltrel; rel < obj->pltrellim; rel++) {
err = _rtld_relocate_plt_object(obj, rel, NULL);
if (err)
break;
}
return err;
}
+108
View File
@@ -0,0 +1,108 @@
/* $NetBSD: rtld_start.S,v 1.1 2014/08/10 05:47:37 matt Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matt Thomas of 3am Software Foundry.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 <machine/asm.h>
RCSID("$NetBSD: rtld_start.S,v 1.1 2014/08/10 05:47:37 matt Exp $")
/*
* void _rtld_start(void (*cleanup)(void), const Obj_Entry *obj,
* struct ps_strings *ps_strings);
*
* X0 = NULL
* X1 = NULL
* X2 = ps_strings
* X30 (LR) = 0
* X29 (FP) = 0
*/
ENTRY_NP(_rtld_start)
mov x24, x2 /* save ps_strings */
#if 1
adrp x1, _PROCEDURE_LINKAGE_TABLE_ /* load _DYNAMIC offset from GOT */
ldr x1, [x1, #:got_lo12:_PROCEDURE_LINKAGE_TABLE_]
#else
adrp x1, :got:_DYNAMIC /* load _DYNAMIC offset from GOT */
ldr x1, [x1, #:got_lo12:_DYNAMIC]
#endif
adrp x0, _DYNAMIC /* get &_DYNAMIC */
add x0, x0, #:lo12:_DYNAMIC
sub x25, x0, x1 /* relocbase = &_DYNAMIC - GOT:_DYNAMIC */
mov x1, x25 /* pass as 2nd argument */
bl _rtld_relocate_nonplt_self
sub sp, sp, #16 /* reserve space for returns */
mov x0, sp /* pointer to reserved space */
mov x1, x25 /* pass relocbase */
bl _rtld
mov x17, x0 /* save entry point */
ldp x0, x1, [sp], #16 /* pop cleanup & obj_main */
mov x2, x24 /* restore ps_strings */
br x17 /* call saved entry point */
END(_rtld_start)
/*
* Upon entry from plt0 entry:
* X17 = &PLTGOT[n]
* X16 = &PLTGOT[2]
*/
ENTRY_NP(_rtld_bind_start)
sub sp, sp, #96 /* reserve stack space */
stp x29, x30, [sp, #80] /* save FP & LR */
add x29, sp, #80 /* get new FP */
str x24, [sp, #64] /* save caller-saved register */
stp x6, x7, [sp, #48] /* save arguments */
stp x4, x5, [sp, #32] /* save arguments */
stp x2, x3, [sp, #16] /* save arguments */
stp x0, x1, [sp, #0] /* save arguments */
sub x16, x16, #16 /* adjust to &PLTGOT[0] */
mov x24, x17 /* preserve across _rtld_bind */
sub x1, x17, x16 /* x1 = &PLTGOT[N] - &PLTGOT[2] */
lsr x1, x1, #3 /* x1 = N - 2 */
ldr x0, [x16, #8] /* get obj ptr from &PLTGOT[1] */
bl _rtld_bind
str x0, [x24] /* save address in PLTGOT[N] */
mov x17, x0 /* save address */
ldp x0, x1, [sp, #0] /* restore arguments */
ldp x2, x3, [sp, #16] /* restore arguments */
ldp x4, x5, [sp, #32] /* restore arguments */
ldp x6, x7, [sp, #48] /* restore arguments */
ldr x24, [sp, #64] /* save caller-saved register */
ldp x29, x30, [sp, #80] /* restore FP & LR */
add sp, sp, #96 /* reclaim stack */
br x17 /* call bound function */
END(_rtld_bind_start)
+9 -3
View File
@@ -1,4 +1,4 @@
/* $NetBSD: alpha_reloc.c,v 1.40 2011/03/31 15:30:31 skrll Exp $ */
/* $NetBSD: alpha_reloc.c,v 1.41 2014/08/25 20:40:52 joerg Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -62,7 +62,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: alpha_reloc.c,v 1.40 2011/03/31 15:30:31 skrll Exp $");
__RCSID("$NetBSD: alpha_reloc.c,v 1.41 2014/08/25 20:40:52 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -376,7 +376,13 @@ _rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rela *rela,
if (__predict_false(def == &_rtld_sym_zero))
return 0;
new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
if (tp == NULL)
return 0;
new_value = _rtld_resolve_ifunc(defobj, def);
} else {
new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
}
rdbg(("bind now/fixup in %s --> old=%p new=%p",
defobj->strtab + def->st_name, (void *)*where, (void *)new_value));
+5 -1
View File
@@ -29,12 +29,14 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: find_exidx.c,v 1.3 2013/05/03 10:27:06 skrll Exp $");
__RCSID("$NetBSD: find_exidx.c,v 1.4 2014/08/10 23:35:27 matt Exp $");
#endif /* not lint */
#include "debug.h"
#include "rtld.h"
#if defined(__ARM_EABI__) && !defined(__ARM_DWARF_EH__)
_Unwind_Ptr
__gnu_Unwind_Find_exidx(_Unwind_Ptr pc, int * pcount)
{
@@ -84,3 +86,5 @@ __gnu_Unwind_Find_exidx(_Unwind_Ptr pc, int * pcount)
*pcount = count;
return start;
}
#endif
+11 -5
View File
@@ -1,8 +1,8 @@
/* $NetBSD: mdreloc.c,v 1.37 2011/11/18 16:10:03 joerg Exp $ */
/* $NetBSD: mdreloc.c,v 1.38 2014/08/25 20:40:52 joerg Exp $ */
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mdreloc.c,v 1.37 2011/11/18 16:10:03 joerg Exp $");
__RCSID("$NetBSD: mdreloc.c,v 1.38 2014/08/25 20:40:52 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -179,7 +179,7 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
rdbg(("COPY (avoid in main)"));
break;
#if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
#if defined(__minix) && defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
case R_TYPE(TLS_DTPOFF32):
def = _rtld_find_symdef(symnum, obj, &defobj, false);
if (def == NULL)
@@ -232,7 +232,7 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
obj->strtab + obj->symtab[symnum].st_name,
obj->path, (void *)tmp));
break;
#endif
#endif /* defined(__minix) && defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II) */
default:
rdbg(("sym = %lu, type = %lu, offset = %p, "
@@ -288,7 +288,13 @@ _rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rel *rel,
if (__predict_false(def == &_rtld_sym_zero))
return 0;
new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
if (tp == NULL)
return 0;
new_value = _rtld_resolve_ifunc(defobj, def);
} else {
new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
}
/* Set the Thumb bit, if needed. */
if (ELF_ST_TYPE(def->st_info) == STT_ARM_TFUNC)
new_value |= 1;
+30 -38
View File
@@ -1,4 +1,4 @@
/* $NetBSD: rtld_start.S,v 1.11 2012/08/13 02:53:25 matt Exp $ */
/* $NetBSD: rtld_start.S,v 1.12 2013/12/03 00:19:56 matt Exp $ */
/*-
* Copyright (c) 1998, 2002 The NetBSD Foundation, Inc.
@@ -31,55 +31,51 @@
#include <machine/asm.h>
RCSID("$NetBSD: rtld_start.S,v 1.11 2012/08/13 02:53:25 matt Exp $")
RCSID("$NetBSD: rtld_start.S,v 1.12 2013/12/03 00:19:56 matt Exp $")
.text
.align 0
.globl _rtld_start
.type _rtld_start,%function
_rtld_start:
ENTRY_NP(_rtld_start)
sub sp, sp, #8 /* make room for obj_main & exit proc */
mov r4, r0 /* save ps_strings */
movs r4, r0 /* save ps_strings */
ldr sl, .L2
ldr r5, .L2+4
ldr r0, .L2+8
.L1:
add sl, pc, sl
ldr r5, [sl, r5]
ldr r0, [sl, r0]
sub r1, sl, r5 /* relocbase */
add r0, r1, r0 /* &_DYNAMIC */
ldr r6, .Lgot
ldr r5, .Ldynamic
add r6, r6, pc /* r6 = &GOT[0]; pc = &LPIC1; */
adds r0, r6, r5 /* arg0 = &_DYNAMIC */
.LPIC1:
ldr r5, [r6] /* GOT[0] = &_DYNAMIC */
subs r5, r0, r5 /* relocbase = GOT[0] - &_DYNAMIC */
movs r1, r5 /* arg1 = relocabase */
bl _rtld_relocate_nonplt_self
sub r1, sl, r5 /* relocbase */
movs r1, r5 /* relocbase */
mov r0, sp /* sp */
bl _rtld /* call the shared loader */
mov r3, r0 /* save entry point */
movs r3, r0 /* save entry point */
#ifdef __thumb__
ldr r2, [sp, #0] /* pop r2 = cleanup */
ldr r1, [sp, #4] /* pop r1 = obj_main */
add sp, sp, #8
#else
ldr r2, [sp], #4 /* pop r2 = cleanup */
ldr r1, [sp], #4 /* pop r1 = obj_main */
mov r0, r4 /* restore ps_strings */
#ifdef _ARM_ARCH_4T
bx r3 /* jump to the entry point */
#else
mov pc, r3 /* jump to the entry point */
#endif
.L2:
.word _GLOBAL_OFFSET_TABLE_ - (.L1+8)
.word _GLOBAL_OFFSET_TABLE_(GOT)
.word _DYNAMIC(GOT)
movs r0, r4 /* restore ps_strings */
RETr(r3)
.align 0
.globl _rtld_bind_start
.type _rtld_bind_start,%function
.Lgot:
.word _GLOBAL_OFFSET_TABLE_ - .LPIC1
.Ldynamic:
.word _DYNAMIC(GOTOFF)
END(_rtld_start)
/*
* stack[0] = RA
* ip = &GOT[n+3]
* lr = &GOT[2]
*/
_rtld_bind_start:
ARM_ENTRY_NP(_rtld_bind_start)
stmdb sp!,{r0-r4,sl,fp} /* 8 byte aligned (lr already saved) */
sub r1, ip, lr /* r1 = 4 * (n + 1) */
@@ -95,9 +91,5 @@ _rtld_bind_start:
mov ip, r0 /* save new address */
ldmia sp!,{r0-r4,sl,fp,lr} /* restore the stack */
#ifdef _ARM_ARCH_4T
bx ip /* jump to the new address */
#else
mov pc, ip /* jump to the new address */
#endif
RETr(ip) /* jump to the new address */
END(_rtld_bind_start)
+41 -5
View File
@@ -1,4 +1,4 @@
/* $NetBSD: hppa_reloc.c,v 1.42 2012/01/06 10:38:57 skrll Exp $ */
/* $NetBSD: hppa_reloc.c,v 1.43 2014/08/25 20:40:52 joerg Exp $ */
/*-
* Copyright (c) 2002, 2004 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: hppa_reloc.c,v 1.42 2012/01/06 10:38:57 skrll Exp $");
__RCSID("$NetBSD: hppa_reloc.c,v 1.43 2014/08/25 20:40:52 joerg Exp $");
#endif /* not lint */
#include <stdlib.h>
@@ -656,9 +656,19 @@ _rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rela *rela,
if (__predict_false(def == &_rtld_sym_zero))
return 0;
func_pc = (Elf_Addr)(defobj->relocbase + def->st_value +
rela->r_addend);
func_sl = (Elf_Addr)(defobj->pltgot);
if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
if (tp == NULL)
return 0;
Elf_Addr ptr = _rtld_resolve_ifunc(defobj, def);
assert(RTLD_IS_PLABEL(ptr));
hppa_plabel *label = RTLD_GET_PLABEL(ptr);
func_pc = label->hppa_plabel_pc;
func_sl = label->hppa_plabel_sl;
} else {
func_pc = (Elf_Addr)(defobj->relocbase + def->st_value +
rela->r_addend);
func_sl = (Elf_Addr)(defobj->pltgot);
}
rdbg(("bind now/fixup in %s --> old=(%p,%p) new=(%p,%p)",
defobj->strtab + def->st_name,
@@ -710,3 +720,29 @@ _rtld_relocate_plt_objects(const Obj_Entry *obj)
}
return 0;
}
void
_rtld_call_function_void(const Obj_Entry *obj, Elf_Addr ptr)
{
volatile hppa_plabel plabel;
void (*f)(void);
plabel.hppa_plabel_pc = (Elf_Addr)ptr;
plabel.hppa_plabel_sl = (Elf_Addr)(obj->pltgot);
f = (void (*)(void))RTLD_MAKE_PLABEL(&plabel);
f();
}
Elf_Addr
_rtld_call_function_addr(const Obj_Entry *obj, Elf_Addr ptr)
{
volatile hppa_plabel plabel;
Elf_Addr (*f)(void);
plabel.hppa_plabel_pc = (Elf_Addr)ptr;
plabel.hppa_plabel_sl = (Elf_Addr)(obj->pltgot);
f = (Elf_Addr (*)(void))RTLD_MAKE_PLABEL(&plabel);
return f();
}
+14 -7
View File
@@ -1,8 +1,8 @@
/* $NetBSD: mdreloc.c,v 1.35 2012/11/07 07:24:46 apb Exp $ */
/* $NetBSD: mdreloc.c,v 1.37 2014/08/31 20:06:22 joerg Exp $ */
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mdreloc.c,v 1.35 2012/11/07 07:24:46 apb Exp $");
__RCSID("$NetBSD: mdreloc.c,v 1.37 2014/08/31 20:06:22 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -120,7 +120,7 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
rdbg(("COPY (avoid in main)"));
break;
#if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
#if defined(__minix) && defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
case R_TYPE(TLS_TPOFF):
def = _rtld_find_symdef(symnum, obj, &defobj, false);
if (def == NULL)
@@ -176,7 +176,7 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
obj->path, (void *)*where));
break;
#endif
#endif /* defined(__minix) && defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II) */
default:
rdbg(("sym = %lu, type = %lu, offset = %p, "
@@ -232,7 +232,14 @@ _rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rel *rel,
if (__predict_false(def == &_rtld_sym_zero))
return 0;
target = (Elf_Addr)(defobj->relocbase + def->st_value);
if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
if (tp == NULL)
return 0;
target = _rtld_resolve_ifunc(defobj, def);
} else {
target = (Elf_Addr)(defobj->relocbase + def->st_value);
}
rdbg(("bind now/fixup in %s --> old=%p new=%p",
defobj->strtab + def->st_name, (void *)*where,
(void *)target));
@@ -276,7 +283,7 @@ _rtld_relocate_plt_objects(const Obj_Entry *obj)
return err;
}
#if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
#if defined(__minix) && defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
/*
* i386 specific GNU variant of __tls_get_addr using register based
* argument passing.
@@ -298,4 +305,4 @@ ___tls_get_addr(void *arg_)
return _rtld_tls_get_addr(tcb, idx, offset);
}
#endif
#endif /* defined(__minix) && defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II) */
+11 -5
View File
@@ -1,13 +1,13 @@
/* $NetBSD: mdreloc.c,v 1.29 2011/11/22 15:25:28 joerg Exp $ */
/* $NetBSD: mdreloc.c,v 1.30 2014/08/25 20:40:52 joerg Exp $ */
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mdreloc.c,v 1.29 2011/11/22 15:25:28 joerg Exp $");
__RCSID("$NetBSD: mdreloc.c,v 1.30 2014/08/25 20:40:52 joerg Exp $");
#endif /* not lint */
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mdreloc.c,v 1.29 2011/11/22 15:25:28 joerg Exp $");
__RCSID("$NetBSD: mdreloc.c,v 1.30 2014/08/25 20:40:52 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -223,8 +223,14 @@ _rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rela *rela,
return 0;
assert(rela->r_addend == 0);
new_value = (Elf_Addr)(defobj->relocbase + def->st_value +
rela->r_addend);
if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
if (tp == NULL)
return 0;
new_value = _rtld_resolve_ifunc(defobj, def);
} else {
new_value = (Elf_Addr)(defobj->relocbase + def->st_value +
rela->r_addend);
}
rdbg(("bind now/fixup in %s --> old=%p new=%p",
defobj->strtab + def->st_name, (void *)*where, (void *)new_value));
if (*where != new_value)
+1 -1
View File
@@ -1,4 +1,4 @@
/* $NetBSD: rtld_start.S,v 1.10 2013/07/18 21:57:42 matt Exp $ */
/* $NetBSD: rtld_start.S,v 1.11 2014/03/18 18:20:38 riastradh Exp $ */
/*-
* Copyright (c) 1999, 2002, 2003 The NetBSD Foundation, Inc.
+9 -3
View File
@@ -1,4 +1,4 @@
/* $NetBSD: mips_reloc.c,v 1.62 2011/03/25 18:07:05 joerg Exp $ */
/* $NetBSD: mips_reloc.c,v 1.63 2014/08/25 20:40:52 joerg Exp $ */
/*
* Copyright 1997 Michael L. Hitch <mhitch@montana.edu>
@@ -30,7 +30,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mips_reloc.c,v 1.62 2011/03/25 18:07:05 joerg Exp $");
__RCSID("$NetBSD: mips_reloc.c,v 1.63 2014/08/25 20:40:52 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -487,7 +487,13 @@ _rtld_relocate_plt_object(const Obj_Entry *obj, Elf_Word sym, Elf_Addr *tp)
if (__predict_false(def == &_rtld_sym_zero))
return 0;
new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
if (tp == NULL)
return 0;
new_value = _rtld_resolve_ifunc(defobj, def);
} else {
new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
}
rdbg(("bind now/fixup in %s --> new=%p",
defobj->strtab + def->st_name, (void *)new_value));
got[obj->local_gotno + sym - obj->gotsym] = new_value;
+10
View File
@@ -0,0 +1,10 @@
# $NetBSD: Makefile.inc,v 1.1 2014/09/03 19:34:26 matt Exp $
SRCS+= mdreloc.c
LDFLAGS+= -Wl,-e,_rtld_start
CPPFLAGS+= -fPIC
SRCS+= rtld_start.S
CPPFLAGS+= -DELFSIZE=32
#LDFLAGS+= -Wl,--script,${.CURDIR}/arch/powerpc/ld.so.script
+293
View File
@@ -0,0 +1,293 @@
/* $NetBSD: mdreloc.c,v 1.1 2014/09/03 19:34:26 matt Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matt Thomas of 3am Software Foundry.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mdreloc.c,v 1.1 2014/09/03 19:34:26 matt Exp $");
#endif /* not lint */
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <machine/cpu.h>
#include "debug.h"
#include "rtld.h"
void _rtld_bind_start(void);
Elf_Addr _rtld_bind(const Obj_Entry *, Elf_Word);
void _rtld_relocate_nonplt_self(Elf_Dyn *, Elf_Addr);
static int _rtld_relocate_plt_object(const Obj_Entry *,
const Elf_Rela *, int, Elf_Addr *);
/*
* The OR1k PLT format is simple.
*/
void
_rtld_setup_pltgot(const Obj_Entry *obj)
{
obj->pltgot[1] = (Elf_Addr) obj;
obj->pltgot[2] = (Elf_Addr) _rtld_bind_start;
dbg(("obj %s plt pltgot=%p start=%p obj=%p",
obj->path, obj->pltgot,
(void *) obj->pltgot[1], (void *) obj->pltgot[2]));
}
void
_rtld_relocate_nonplt_self(Elf_Dyn *dynp, Elf_Addr relocbase)
{
const Elf_Rela *rela = 0, *relalim;
Elf_Addr relasz = 0;
Elf_Addr *where;
for (; dynp->d_tag != DT_NULL; dynp++) {
switch (dynp->d_tag) {
case DT_RELA:
rela = (const Elf_Rela *)(relocbase + dynp->d_un.d_ptr);
break;
case DT_RELASZ:
relasz = dynp->d_un.d_val;
break;
}
}
relalim = (const Elf_Rela *)((const uint8_t *)rela + relasz);
for (; rela < relalim; rela++) {
where = (Elf_Addr *)(relocbase + rela->r_offset);
*where = (Elf_Addr)(relocbase + rela->r_addend);
}
}
int
_rtld_relocate_nonplt_objects(Obj_Entry *obj)
{
const Elf_Rela *rela;
for (rela = obj->rela; rela < obj->relalim; rela++) {
Elf_Addr *where;
const Elf_Sym *def;
const Obj_Entry *defobj;
Elf_Addr tmp;
unsigned long symnum;
where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
symnum = ELF_R_SYM(rela->r_info);
switch (ELF_R_TYPE(rela->r_info)) {
#if 1 /* XXX Should not be necessary. */
case R_TYPE(JMP_SLOT):
#endif
case R_TYPE(NONE):
break;
case R_TYPE(32): /* <address> S + A */
case R_TYPE(GLOB_DAT): /* <address> S + A */
def = _rtld_find_symdef(symnum, obj, &defobj, false);
if (def == NULL)
return -1;
tmp = (Elf_Addr)(defobj->relocbase + def->st_value +
rela->r_addend);
if (*where != tmp)
*where = tmp;
rdbg(("32/GLOB_DAT %s in %s --> %p in %s",
obj->strtab + obj->symtab[symnum].st_name,
obj->path, (void *)*where, defobj->path));
break;
case R_TYPE(RELATIVE): /* <address> B + A */
*where = (Elf_Addr)(obj->relocbase + rela->r_addend);
rdbg(("RELATIVE in %s --> %p", obj->path,
(void *)*where));
break;
case R_TYPE(COPY):
/*
* These are deferred until all other relocations have
* been done. All we do here is make sure that the
* COPY relocation is not in a shared library. They
* are allowed only in executable files.
*/
if (obj->isdynamic) {
_rtld_error(
"%s: Unexpected R_COPY relocation in shared library",
obj->path);
return -1;
}
rdbg(("COPY (avoid in main)"));
break;
case R_TYPE(TLS_DTPMOD):
def = _rtld_find_symdef(symnum, obj, &defobj, false);
if (def == NULL)
return -1;
*where = (Elf_Addr)defobj->tlsindex;
rdbg(("DTPMOD32 %s in %s --> %p in %s",
obj->strtab + obj->symtab[symnum].st_name,
obj->path, (void *)*where, defobj->path));
break;
case R_TYPE(TLS_DTPOFF):
def = _rtld_find_symdef(symnum, obj, &defobj, false);
if (def == NULL)
return -1;
if (!defobj->tls_done && _rtld_tls_offset_allocate(obj))
return -1;
*where = (Elf_Addr)(def->st_value + rela->r_addend
- TLS_DTV_OFFSET);
rdbg(("DTPOFF %s in %s --> %p in %s",
obj->strtab + obj->symtab[symnum].st_name,
obj->path, (void *)*where, defobj->path));
break;
case R_TYPE(TLS_TPOFF):
def = _rtld_find_symdef(symnum, obj, &defobj, false);
if (def == NULL)
return -1;
if (!defobj->tls_done && _rtld_tls_offset_allocate(obj))
return -1;
*where = (Elf_Addr)(def->st_value + rela->r_addend
+ defobj->tlsoffset - TLS_TP_OFFSET);
rdbg(("TPREL %s in %s --> %p in %s",
obj->strtab + obj->symtab[symnum].st_name,
obj->path, (void *)*where, defobj->path));
break;
default:
rdbg(("sym = %lu, type = %lu, offset = %p, "
"addend = %p, contents = %p, symbol = %s",
symnum, (u_long)ELF_R_TYPE(rela->r_info),
(void *)rela->r_offset, (void *)rela->r_addend,
(void *)*where,
obj->strtab + obj->symtab[symnum].st_name));
_rtld_error("%s: Unsupported relocation type %ld "
"in non-PLT relocations",
obj->path, (u_long) ELF_R_TYPE(rela->r_info));
return -1;
}
}
return 0;
}
int
_rtld_relocate_plt_lazy(const Obj_Entry *obj)
{
const Elf_Rela *rela;
int reloff;
for (rela = obj->pltrela, reloff = 0;
rela < obj->pltrelalim;
rela++, reloff++) {
Elf_Word *where = (Elf_Word *)(obj->relocbase + rela->r_offset);
assert(ELF_R_TYPE(rela->r_info) == R_TYPE(JMP_SLOT));
/*
* For now, simply treat then as relative.
*/
*where += (Elf_Addr)obj->relocbase;
}
return 0;
}
static int
_rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rela *rela, int reloff, Elf_Addr *tp)
{
Elf_Word *where = (Elf_Word *)(obj->relocbase + rela->r_offset);
Elf_Addr value;
const Elf_Sym *def;
const Obj_Entry *defobj;
unsigned long info = rela->r_info;
assert(ELF_R_TYPE(info) == R_TYPE(JMP_SLOT));
def = _rtld_find_plt_symdef(ELF_R_SYM(info), obj, &defobj, tp != NULL);
if (__predict_false(def == NULL))
return -1;
if (__predict_false(def == &_rtld_sym_zero))
return 0;
value = (Elf_Addr)(defobj->relocbase + def->st_value);
rdbg(("bind now/fixup in %s --> new=%p",
defobj->strtab + def->st_name, (void *)value));
/*
* Simply replace the entry in GOT with the
* address of the routine.
*/
assert(where >= (Elf_Word *)obj->pltgot);
assert(where < (Elf_Word *)obj->pltgot + (obj->pltrelalim - obj->pltrela));
*where = value;
if (tp)
*tp = value;
return 0;
}
Elf_Addr
_rtld_bind(const Obj_Entry *obj, Elf_Word reloff)
{
const Elf_Rela *rela = obj->pltrela + reloff;
Elf_Addr new_value;
int err;
new_value = 0; /* XXX gcc */
_rtld_shared_enter();
err = _rtld_relocate_plt_object(obj, rela, reloff, &new_value);
if (err)
_rtld_die();
_rtld_shared_exit();
return new_value;
}
int
_rtld_relocate_plt_objects(const Obj_Entry *obj)
{
const Elf_Rela *rela;
int reloff;
for (rela = obj->pltrela, reloff = 0; rela < obj->pltrelalim; rela++, reloff++) {
if (_rtld_relocate_plt_object(obj, rela, reloff, NULL) < 0)
return -1;
}
return 0;
}
+118
View File
@@ -0,0 +1,118 @@
/* $NetBSD: rtld_start.S,v 1.1 2014/09/03 19:34:26 matt Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matt Thomas of 3am Software Foundry.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 <machine/asm.h>
.globl _rtld_start
.globl _rtld
#define CF_LEN (3*__SIZEOF_POINTER__)
#define CF_OBJ (2*__SIZEOF_POINTER__)
#define CF_CLEANUP (1*__SIZEOF_POINTER__)
/*
* void ___start(void (*cleanup)(void), const Obj_Entry *obj,
* struct ps_strings *ps_strings);
*/
ENTRY_NP(_rtld_start)
l.sw CF_LEN(r1), r1 # reserve some stack space
#if 0
l.ori r26, r3, 0 # obj (should be 0)
l.ori r28, r4, 0 # cleanup (should be 0)
#endif
l.ori r30, r5, 0 # ps_strings
l.addi r1, r1, -CF_LEN
PIC_GOTSETUP(r16)
l.movhi r3, gotoffhi(_DYNAMIC) # get _DYNAMIC gotoff address
l.ori r3, r3, gotofflo(_DYNAMIC)
l.lwz r7, 0(r16) # get base-relative &_DYNAMIC
l.add r3, r3, r16 # r3 = _DYNAMIC actual address
l.sub r24, r3, r7 # r24 = relocbase
l.ori r4, r24, 0 # r4 = relocbase
l.jal _C_LABEL(_rtld_relocate_nonplt_self)
l.nop
l.addi r3, r1, CF_CLEANUP
l.ori r4, r24, 0 # r4 = relocbase
l.jal _C_LABEL(_rtld) # _start = _rtld(sp, relocbase)
l.nop
l.lwz r3, CF_OBJ(r1) # obj
l.lwz r4, CF_CLEANUP(r1) # cleanup
l.ori r5, r30, 0 # ps_strings
l.addi r1, r1, CF_LEN # pop stack
l.jalr r11 # _start(obj, cleanup, ps_strings)
l.ori r13, r0, 1 # _exit()
l.sys 0
END(_rtld_start)
.globl _rtld_bind
/*
* r11 = rela offset
* r12 = GOT[1] (&obj)
* r15 = GOT[2] (&_rtld_bind_start)
*/
ENTRY_NP(_rtld_bind_start)
l.sw -4(r1), r9 # save lr
l.sw -8(r1), r8 # save arg5
l.sw -12(r1), r7 # save arg4
l.sw -16(r1), r6 # save arg3
l.sw -20(r1), r5 # save arg2
l.sw -24(r1), r4 # save arg1
l.sw -28(r1), r3 # save arg0
l.sw -32(r1), r1 # establish stack frame
l.addi r1, r1, -32
l.ori r3, r12, 0 # obj
l.ori r4, r11, 0 # reloff
l.jal _C_LABEL(_rtld_bind) # _rtld_bind(obj, reloff)
l.nop
l.addi r1, r1, 32 # pop stack frame
l.lwz r3, -28(r1) # restore arg0
l.lwz r4, -24(r1) # restore arg1
l.lwz r5, -20(r1) # restore arg2
l.lwz r6, -16(r1) # restore arg3
l.lwz r7, -12(r1) # restore arg4
l.lwz r8, -8(r1) # restore arg5
l.lwz r9, -4(r1) # restore lr
l.jr r11 # jump to routine
l.nop
END(_rtld_bind_start)
+12 -8
View File
@@ -1,11 +1,15 @@
# $NetBSD: Makefile.inc,v 1.12 2011/10/26 15:56:58 chs Exp $
SRCS+= rtld_start.S ppc_reloc.c
# XXX Should not be in CPPFLAGS!
CPPFLAGS+= -fpic
CPPFLAGS+= -DELFSIZE=32
# $NetBSD: Makefile.inc,v 1.15 2014/08/15 09:40:07 matt Exp $
SRCS+= ppc_reloc.c
LDFLAGS+= -Wl,-e,_rtld_start
CPPFLAGS+= -fPIC
.if ${LDELFSO_MACHINE_ARCH} == "powerpc64"
SRCS+= rtld_start64.S
CPPFLAGS+= -DELFSIZE=64
.else
SRCS+= rtld_start.S
CPPFLAGS+= -DELFSIZE=32
LDFLAGS+= -Wl,--script,${.CURDIR}/arch/powerpc/ld.so.script
.endif
+1 -1
View File
@@ -1,6 +1,6 @@
OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc",
"elf32-powerpc")
OUTPUT_ARCH(powerpc)
OUTPUT_ARCH(powerpc:common)
ENTRY(_start)
/* Do we need any of these for elf?
__DYNAMIC = 0; */
+100 -38
View File
@@ -1,4 +1,4 @@
/* $NetBSD: ppc_reloc.c,v 1.49 2011/03/25 18:07:06 joerg Exp $ */
/* $NetBSD: ppc_reloc.c,v 1.53 2014/08/25 20:40:52 joerg Exp $ */
/*-
* Copyright (C) 1998 Tsubai Masanari
@@ -30,7 +30,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: ppc_reloc.c,v 1.49 2011/03/25 18:07:06 joerg Exp $");
__RCSID("$NetBSD: ppc_reloc.c,v 1.53 2014/08/25 20:40:52 joerg Exp $");
#endif /* not lint */
#include <stdarg.h>
@@ -46,19 +46,37 @@ __RCSID("$NetBSD: ppc_reloc.c,v 1.49 2011/03/25 18:07:06 joerg Exp $");
void _rtld_powerpc_pltcall(Elf_Word);
void _rtld_powerpc_pltresolve(Elf_Word, Elf_Word);
#define ha(x) ((((u_int32_t)(x) & 0x8000) ? \
((u_int32_t)(x) + 0x10000) : (u_int32_t)(x)) >> 16)
#define l(x) ((u_int32_t)(x) & 0xffff)
#define __u64(x) ((uint64_t)(x))
#define __u32(x) ((uint32_t)(x))
#define __ha48 __u64(0xffffffff8000)
#define __ha32 __u64(0xffff8000)
#define __ha16 __u32(0x8000)
#define __ha(x,n) ((((x) >> (n)) + (((x) & __ha##n) == __ha##n)) & 0xffff)
#define __hi(x,n) (((x) >> (n)) & 0xffff)
#ifdef __LP64
#define highesta(x) __ha(__u64(x), 48)
#define highest(x) __hi(__u64(x), 48)
#define higher(x) __ha(__u64(x), 32)
#define higher(x) __hi(__u64(x), 32)
#endif
#define ha(x) __ha(__u32(x), 16)
#define hi(x) __hi(__u32(x), 16)
#define lo(x) (__u32(x) & 0xffff)
#ifdef _LP64
/* function descriptor for _rtld_bind_start */
extern const uint64_t _rtld_bind_start[3];
#else
void _rtld_bind_bssplt_start(void);
void _rtld_bind_secureplt_start(void);
#endif
Elf_Addr _rtld_bind(const Obj_Entry *, Elf_Word);
void _rtld_relocate_nonplt_self(Elf_Dyn *, Elf_Addr);
caddr_t _rtld_bind(const Obj_Entry *, Elf_Word);
static int _rtld_relocate_plt_object(const Obj_Entry *,
const Elf_Rela *, int, Elf_Addr *);
/*
* The PPC PLT format consists of three sections:
* The PPC32 PLT format consists of three sections:
* (1) The "pltcall" and "pltresolve" glue code. This is always 18 words.
* (2) The code part of the PLT entries. There are 2 words per entry for
* up to 8192 entries, then 4 words per entry for any additional entries.
@@ -67,15 +85,19 @@ static int _rtld_relocate_plt_object(const Obj_Entry *,
* per entry).
*/
/*
* Setup the plt glue routines (for bss-plt).
*/
#define PLTCALL_SIZE 20
#define PLTRESOLVE_SIZE 24
void
_rtld_setup_pltgot(const Obj_Entry *obj)
{
#ifdef _LP64
/*
* For powerpc64, just copy the function descriptor to pltgot[0].
*/
if (obj->pltgot != NULL) {
obj->pltgot[0] = (Elf_Addr) _rtld_bind_start[0];
obj->pltgot[1] = (Elf_Addr) _rtld_bind_start[1];
obj->pltgot[2] = (Elf_Addr) obj;
}
#else
/*
* Secure-PLT is much more sane.
*/
@@ -86,6 +108,12 @@ _rtld_setup_pltgot(const Obj_Entry *obj)
obj->path, obj->gotptr,
(void *) obj->gotptr[1], (void *) obj->gotptr[2]));
} else {
/*
* Setup the plt glue routines (for bss-plt).
*/
#define BSSPLTCALL_SIZE 20
#define BSSPLTRESOLVE_SIZE 24
Elf_Word *pltcall, *pltresolve;
Elf_Word *jmptab;
int N = obj->pltrelalim - obj->pltrela;
@@ -101,17 +129,17 @@ _rtld_setup_pltgot(const Obj_Entry *obj)
pltcall = obj->pltgot;
jmptab = pltcall + 18 + N * 2;
memcpy(pltcall, _rtld_powerpc_pltcall, PLTCALL_SIZE);
memcpy(pltcall, _rtld_powerpc_pltcall, BSSPLTCALL_SIZE);
pltcall[1] |= ha(jmptab);
pltcall[2] |= l(jmptab);
pltcall[2] |= lo(jmptab);
pltresolve = obj->pltgot + 8;
memcpy(pltresolve, _rtld_powerpc_pltresolve, PLTRESOLVE_SIZE);
memcpy(pltresolve, _rtld_powerpc_pltresolve, BSSPLTRESOLVE_SIZE);
pltresolve[0] |= ha(_rtld_bind_bssplt_start);
pltresolve[1] |= l(_rtld_bind_bssplt_start);
pltresolve[1] |= lo(_rtld_bind_bssplt_start);
pltresolve[3] |= ha(obj);
pltresolve[4] |= l(obj);
pltresolve[4] |= lo(obj);
/*
* Invalidate the icache for only the code part of the PLT
@@ -119,6 +147,7 @@ _rtld_setup_pltgot(const Obj_Entry *obj)
*/
__syncicache(pltcall, (char *)jmptab - (char *)pltcall);
}
#endif
}
void
@@ -167,8 +196,12 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
case R_TYPE(NONE):
break;
case R_TYPE(32): /* word32 S + A */
case R_TYPE(GLOB_DAT): /* word32 S + A */
#ifdef _LP64
case R_TYPE(ADDR64): /* <address> S + A */
#else
case R_TYPE(ADDR32): /* <address> S + A */
#endif
case R_TYPE(GLOB_DAT): /* <address> S + A */
def = _rtld_find_symdef(symnum, obj, &defobj, false);
if (def == NULL)
return -1;
@@ -182,7 +215,7 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
obj->path, (void *)*where, defobj->path));
break;
case R_TYPE(RELATIVE): /* word32 B + A */
case R_TYPE(RELATIVE): /* <address> B + A */
*where = (Elf_Addr)(obj->relocbase + rela->r_addend);
rdbg(("RELATIVE in %s --> %p", obj->path,
(void *)*where));
@@ -204,7 +237,7 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
rdbg(("COPY (avoid in main)"));
break;
case R_TYPE(DTPMOD32):
case R_TYPE(DTPMOD):
def = _rtld_find_symdef(symnum, obj, &defobj, false);
if (def == NULL)
return -1;
@@ -215,7 +248,7 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
obj->path, (void *)*where, defobj->path));
break;
case R_TYPE(DTPREL32):
case R_TYPE(DTPREL):
def = _rtld_find_symdef(symnum, obj, &defobj, false);
if (def == NULL)
return -1;
@@ -230,7 +263,7 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
obj->path, (void *)*where, defobj->path));
break;
case R_TYPE(TPREL32):
case R_TYPE(TPREL):
def = _rtld_find_symdef(symnum, obj, &defobj, false);
if (def == NULL)
return -1;
@@ -264,6 +297,12 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
int
_rtld_relocate_plt_lazy(const Obj_Entry *obj)
{
#ifdef _LP64
/*
* For PowerPC64, the plt stubs handle an empty function descriptor
* so there's nothing to do.
*/
#else
Elf_Addr * const pltresolve = obj->pltgot + 8;
const Elf_Rela *rela;
int reloff;
@@ -288,9 +327,9 @@ _rtld_relocate_plt_lazy(const Obj_Entry *obj)
*where++ = 0x39600000 | reloff;
} else {
/* lis r11,ha(reloff) */
/* addi r11,l(reloff) */
/* addi r11,lo(reloff) */
*where++ = 0x3d600000 | ha(reloff);
*where++ = 0x396b0000 | l(reloff);
*where++ = 0x396b0000 | lo(reloff);
}
/* b pltresolve */
distance = (Elf_Addr)pltresolve - (Elf_Addr)where;
@@ -305,6 +344,7 @@ _rtld_relocate_plt_lazy(const Obj_Entry *obj)
/* __syncicache(where - 3, 12); */
}
}
#endif /* !_LP64 */
return 0;
}
@@ -316,7 +356,6 @@ _rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rela *rela, int reloff
Elf_Addr value;
const Elf_Sym *def;
const Obj_Entry *defobj;
int distance;
unsigned long info = rela->r_info;
assert(ELF_R_TYPE(info) == R_TYPE(JMP_SLOT));
@@ -327,20 +366,38 @@ _rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rela *rela, int reloff
if (__predict_false(def == &_rtld_sym_zero))
return 0;
value = (Elf_Addr)(defobj->relocbase + def->st_value);
distance = value - (Elf_Addr)where;
if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
if (tp == NULL)
return 0;
value = _rtld_resolve_ifunc(defobj, def);
} else {
value = (Elf_Addr)(defobj->relocbase + def->st_value);
}
rdbg(("bind now/fixup in %s --> new=%p",
defobj->strtab + def->st_name, (void *)value));
#ifdef _LP64
/*
* For PowerPC64 we simply replace the function descriptor in the
* PLTGOT with the one from source object.
*/
assert(where >= (Elf_Word *)obj->pltgot);
assert(where < (Elf_Word *)obj->pltgot + (obj->pltrelalim - obj->pltrela));
const Elf_Addr * const fdesc = (Elf_Addr *) value;
where[0] = fdesc[0];
where[1] = fdesc[1];
where[2] = fdesc[2];
#else
ptrdiff_t distance = value - (Elf_Addr)where;
if (obj->gotptr != NULL) {
/*
* For Secure-PLT we simply replace the entry in GOT with the address
* of the routine.
* For Secure-PLT we simply replace the entry in GOT with the
* address of the routine.
*/
assert(where >= (Elf_Word *)obj->pltgot);
assert(where < (Elf_Word *)obj->pltgot + (obj->pltrelalim - obj->pltrela));
*where = value;
} else if (abs(distance) < 32*1024*1024) { /* inside 32MB? */
} else if (labs(distance) < 32*1024*1024) { /* inside 32MB? */
/* b value # branch directly */
*where = 0x48000000 | (distance & 0x03fffffc);
__syncicache(where, 4);
@@ -363,18 +420,18 @@ _rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rela *rela, int reloff
} else {
#ifdef notyet
/* lis r11,ha(value) */
/* addi r11,l(value) */
/* addi r11,lo(value) */
/* mtctr r11 */
/* bctr */
*where++ = 0x3d600000 | ha(value);
*where++ = 0x396b0000 | l(value);
*where++ = 0x396b0000 | lo(value);
*where++ = 0x7d6903a6;
*where++ = 0x4e800420;
#else
/* lis r11,ha(reloff) */
/* addi r11,l(reloff) */
/* addi r11,lo(reloff) */
*where++ = 0x3d600000 | ha(reloff);
*where++ = 0x396b0000 | l(reloff);
*where++ = 0x396b0000 | lo(reloff);
#endif
}
/* b pltcall */
@@ -382,13 +439,14 @@ _rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rela *rela, int reloff
*where++ = 0x48000000 | (distance & 0x03fffffc);
__syncicache(where - 3, 12);
}
#endif /* _LP64 */
if (tp)
*tp = value;
return 0;
}
caddr_t
Elf_Addr
_rtld_bind(const Obj_Entry *obj, Elf_Word reloff)
{
const Elf_Rela *rela = obj->pltrela + reloff;
@@ -403,7 +461,11 @@ _rtld_bind(const Obj_Entry *obj, Elf_Word reloff)
_rtld_die();
_rtld_shared_exit();
return (caddr_t)new_value;
#ifdef _LP64
return obj->glink;
#else
return new_value;
#endif
}
int
@@ -0,0 +1,128 @@
/* $NetBSD: rtld_start64.S,v 1.2 2014/03/06 19:19:40 matt Exp $ */
/*-
* Copyright (C) 1998 Tsubai Masanari
* Portions copyright 2002 Charles M. Hannum <root@ihack.net>
* 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. 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.
*/
#include <machine/asm.h>
.globl _rtld_relocate_nonplt_self
.globl _rtld
.text
ENTRY_NOPROFILE(_rtld_start)
mr %r23,%r3 // argc
mr %r24,%r4 // argv
mr %r25,%r5 // envp
/* mr %r26,%r6 // obj (always 0) */
/* mr %r27,%r7 // cleanup (always 0) */
mr %r28,%r8 // ps_strings
li %r0,0
stdu %r0,-64(%r1) // terminate stack chain
std %r2,40(%r1) // save TOC
std %r0,16(%r1) // ditto
bcl 20,31,1f
1: mflr %r30
ld %r3,0(%r2) // TOC[0] = &TOC
sub %r29,%r2,%r3 // compute relocbase
addis %r3,%r3,_DYNAMIC-1b@ha // get _DYNAMIC actual address
addi %r3,%r3,_DYNAMIC-1b@l
mr %r4,%r29 // r4 = relocbase
CALL(_rtld_relocate_nonplt_self)
addi %r3,%r1,48 // sp = <local variable space>
mr %r4,%r29 // r4 = relocbase
CALL(_rtld) // _start = _rtld(sp, relocbase)
ld %r0,0(%r3) // func address
ld %r2,8(%r3) // TOC address
ld %r11,16(%r3) // environment pointer
mtctr %r0 // so we can call it.
mr %r3,%r23 // argc
mr %r4,%r24 // argv
mr %r5,%r25 // envp
ld %r6,56(%r1) // obj = <localvar>[1]
ld %r7,48(%r1) // cleanup = <localvar>[0]
mr %r8,%r28 // ps_strings
bctrl // _start(argc, argv, envp, obj, cleanup, ps_strings)
nop
li %r0,1 // _exit()
sc
END(_rtld_start)
.globl _rtld_bind
/*
* %r0 has the index of the rela, %r12 has a pointer to the plt entry.
*/
ENTRY_NOPROFILE(_rtld_bind_start)
std %r3,-72(%r1) // save argument register
std %r4,-64(%r1) // save argument register
std %r5,-56(%r1) // save argument register
std %r6,-48(%r1) // save argument register
std %r7,-40(%r1) // save argument register
std %r8,-32(%r1) // save argument register
std %r9,-24(%r1) // save argument register
std %r10,-16(%r1) // save argument register
std %r31,-8(%r1) // save register
stdu %r1,-(48+80)(%r1) // create back chain
mflr %r10
std %r10,16(%r1) // save LR
mfcr %r9
std %r9,8(%r1) // save CR to be safe
mr %r31, %r12 // save this across bind call
mr %r3, %r11 // obj
mr %r4, %r0 // reloff
CALL(_rtld_bind) // _rtld_bind(obj, reloff)
mtctr %r3
mr %r12,%r31 // restore r12
ld %r0,8(%r1) // get saved CR
mtcr %r0 // restore it
ld %r0,16(%r1) // get saved LR
mtlr %r0 // restore it
addi %r1,%r1,(48+80) // adjust stack
ld %r3,-72(%r1) // restore argument register
ld %r4,-64(%r1) // restore argument register
ld %r5,-56(%r1) // restore argument register
ld %r6,-48(%r1) // restore argument register
ld %r7,-40(%r1) // restore argument register
ld %r8,-32(%r1) // restore argument register
ld %r9,-24(%r1) // restore argument register
ld %r10,-16(%r1) // restore argument register
ld %r31,-8(%r1) // restore register
bctr
END(_rtld_bind_start)
+15
View File
@@ -0,0 +1,15 @@
# $NetBSD: Makefile.inc,v 1.1 2014/09/19 17:36:25 matt Exp $
SRCS+= rtld_start.S mdreloc.c
# XXX Should not be in CPPFLAGS!
CPPFLAGS+= -fpic
.if ${LDELFSO_MACHINE_ARCH} == "riscv64"
CPPFLAGS+= -DELFSIZE=64
.else
CPPFLAGS+= -DELFSIZE=32
.endif
CPPFLAGS+= -DHAVE_INITFINI_ARRAY
LDFLAGS+= -Wl,-e,_rtld_start
+258
View File
@@ -0,0 +1,258 @@
/* $NetBSD: mdreloc.c,v 1.2 2015/03/27 23:14:53 matt Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matt Thomas of 3am Software Foundry.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mdreloc.c,v 1.2 2015/03/27 23:14:53 matt Exp $");
#endif /* not lint */
#include <sys/types.h>
#include <sys/endian.h>
#include <sys/tls.h>
#include <stdlib.h>
#include <string.h>
#include "debug.h"
#include "rtld.h"
void _rtld_bind_start(void);
void _rtld_relocate_nonplt_self(Elf_Dyn *, Elf_Addr);
void *_rtld_bind(const Obj_Entry *, Elf_Word);
void
_rtld_setup_pltgot(const Obj_Entry *obj)
{
obj->pltgot[0] = (Elf_Addr) &_rtld_bind_start;
obj->pltgot[1] = (Elf_Addr) obj;
}
void
_rtld_relocate_nonplt_self(Elf_Dyn *dynp, Elf_Addr relocbase)
{
const Elf_Rela *rela = NULL, *relalim;
Elf_Addr relasz = 0;
for (; dynp->d_tag != DT_NULL; dynp++) {
switch (dynp->d_tag) {
case DT_RELA:
rela = (const Elf_Rela *)(relocbase + dynp->d_un.d_ptr);
break;
case DT_RELASZ:
relasz = dynp->d_un.d_val;
break;
}
}
relalim = (const Elf_Rela *)((uintptr_t)rela + relasz);
for (; rela < relalim; rela++) {
Elf_Word r_type = ELF_R_TYPE(rela->r_info);
Elf_Addr *where = (Elf_Addr *)(relocbase + rela->r_offset);
switch (r_type) {
case R_TYPE(RELATIVE): {
Elf_Addr val = relocbase + rela->r_addend;
*where = val;
rdbg(("RELATIVE/L(%p) -> %p in <self>",
where, (void *)val));
break;
}
case R_TYPE(NONE):
break;
default:
abort();
}
}
}
int
_rtld_relocate_nonplt_objects(Obj_Entry *obj)
{
const Elf_Rela *rela;
const Elf_Sym *def;
const Obj_Entry *defobj;
for (rela = obj->rela; rela < obj->relalim; rela++) {
Elf_Addr * const where =
(Elf_Addr *)(obj->relocbase + rela->r_offset);
const Elf_Word r_symndx = ELF_R_SYM(rela->r_info);
const Elf_Word r_type = ELF_R_TYPE(rela->r_info);
switch (r_type) {
case R_TYPE(NONE):
break;
case R_TYPE(RELATIVE): {
def = obj->symtab + r_symndx;
Elf_Addr val = (Elf_Addr)obj->relocbase + rela->r_addend;
rdbg(("RELATIVE(%p) -> %p (%s) in %s",
where, (void *)val,
obj->strtab + def->st_name, obj->path));
*where = val;
break;
}
case R_TYPESZ(ADDR): {
def = _rtld_find_symdef(r_symndx, obj, &defobj, false);
if (def == NULL)
return -1;
Elf_Addr val = (Elf_Addr)defobj->relocbase + rela->r_addend;
*where = val;
rdbg(("ADDR %s in %s --> %p in %s",
obj->strtab + obj->symtab[r_symndx].st_name,
obj->path, (void *)val, defobj->path));
break;
}
case R_TYPESZ(TLS_DTPMOD): {
def = _rtld_find_symdef(r_symndx, obj, &defobj, false);
if (def == NULL)
return -1;
Elf_Addr val = (Elf_Addr)defobj->tlsindex + rela->r_addend;
*where = val;
rdbg(("DTPMOD %s in %s --> %p in %s",
obj->strtab + obj->symtab[r_symndx].st_name,
obj->path, (void *)val, defobj->path));
break;
}
case R_TYPESZ(TLS_DTPREL): {
Elf_Addr old = *where;
Elf_Addr val = old;
def = _rtld_find_symdef(r_symndx, obj, &defobj, false);
if (def == NULL)
return -1;
if (!defobj->tls_done && _rtld_tls_offset_allocate(obj))
return -1;
val = (Elf_Addr)def->st_value - TLS_DTV_OFFSET;
*where = val;
rdbg(("DTPREL %s in %s --> %p in %s",
obj->strtab + obj->symtab[r_symndx].st_name,
obj->path, (void *)val, defobj->path));
break;
}
default:
rdbg(("sym = %lu, type = %lu, offset = %p, "
"addend = %p, contents = %p, symbol = %s",
(u_long)r_symndx, (u_long)r_type,
(void *)rela->r_offset, (void *)rela->r_addend,
(void *)load_ptr(where, sizeof(Elf_Addr)),
obj->strtab + obj->symtab[r_symndx].st_name));
_rtld_error("%s: Unsupported relocation type %ld "
"in non-PLT relocations",
obj->path, (u_long)r_type);
return -1;
}
}
return 0;
}
int
_rtld_relocate_plt_lazy(const Obj_Entry *obj)
{
/* PLT fixups were done above in the GOT relocation. */
return 0;
}
static int
_rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rel *rel,
Elf_Addr *tp)
{
const Obj_Entry *defobj;
Elf_Addr new_value;
assert(ELF_R_TYPE(rel->r_info) == R_TYPE(JMP_SLOT));
const Elf_Sym *def = _rtld_find_plt_symdef(ELF_R_SYM(rel->r_info),
obj, &defobj, tp != NULL);
if (__predict_false(def == NULL))
return -1;
if (__predict_false(def == &_rtld_sym_zero))
return -1;
if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
if (tp == NULL)
return 0;
new_value = _rtld_resolve_ifunc(defobj, def);
} else {
new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
}
rdbg(("bind now/fixup in %s --> new=%p",
defobj->strtab + def->st_name, (void *)new_value));
*(Elf_Addr *)(obj->relocbase + rel->r_offset) = new_value;
if (tp)
*tp = new_value;
return 0;
}
void *
_rtld_bind(const Obj_Entry *obj, Elf_Word reloff)
{
const Elf_Rel *pltrel = (const Elf_Rel *)(obj->pltrel + reloff);
Elf_Addr new_value;
int err;
_rtld_shared_enter();
err = _rtld_relocate_plt_object(obj, pltrel, &new_value);
if (err)
_rtld_die();
_rtld_shared_exit();
return (caddr_t)new_value;
}
int
_rtld_relocate_plt_objects(const Obj_Entry *obj)
{
for (const Elf_Rel *rel = obj->pltrel; rel < obj->pltrellim; rel++) {
if (_rtld_relocate_plt_object(obj, rel, NULL) < 0)
return -1;
}
return 0;
}
+116
View File
@@ -0,0 +1,116 @@
/* $NetBSD: rtld_start.S,v 1.2 2015/03/27 23:14:53 matt Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matt Thomas of 3am Software Foundry.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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 <machine/asm.h>
.globl _C_LABEL(_rtld_relocate_nonplt_self)
.globl _C_LABEL(_rtld)
/*
* void
* ___start(void (*cleanup)(void),
* const Obj_Entry *obj,
* struct ps_strings *ps_strings)
*/
ENTRY(_rtld_start)
move s0, sp # save stack pointer
addi sp, sp, -4*__SIZEOF_POINTER__
# adjust stack pointer
# -> 2*PTR_SIZE(sp) for atexit
# -> 3*PTR_SIZE(sp) for obj_main
move s1, a2 # save ps_strings pointer
.L0: auipc gp, %pcrel_hi(_GLOBAL_OFFSET_TABLE_)
PTR_L t0, %pcrel_lo(.L0)(gp) # &_DYNAMIC
.L1: auipc a0, %pcrel_hi(_DYNAMIC)
addi a0, a0, %pcrel_lo(.L1)
sub s2, a0, t0 # save for _rtld
move a1, s2
call _C_LABEL(_rtld_relocate_nonplt_self)
move a1, s2 # relocbase
addi a0, sp, 2*__SIZEOF_POINTER__ # sp
call _C_LABEL(_rtld) # a0 = _rtld(sp, relocbase)
mv t0, a0
PTR_L a0, 2*__SIZEOF_POINTER__(sp) # cleanup function
PTR_L a1, 3*__SIZEOF_POINTER__(sp) # obj_main entry
move a2, s1 # restore ps_strings
move sp, s0 # readjust stack
move s0, zero # break stack chain
jr t0 # _start(cleanup, obj_main, ps_strings);
END(_rtld_start)
#define XCALLFRAME_SIZ (12*SZREG)
#define XCALLFRAME_RA (8*SZREG)
#define XCALLFRAME_A7 (7*SZREG)
#define XCALLFRAME_A6 (6*SZREG)
#define XCALLFRAME_A5 (5*SZREG)
#define XCALLFRAME_A4 (4*SZREG)
#define XCALLFRAME_A3 (3*SZREG)
#define XCALLFRAME_A2 (2*SZREG)
#define XCALLFRAME_A1 (1*SZREG)
#define XCALLFRAME_A0 (0*SZREG)
/*
* t0 = obj pointer
* t1 = reloc offset
*/
ENTRY_NP(_rtld_bind_start)
addi sp, sp, -XCALLFRAME_SIZ // save arguments on stack
REG_S a0, XCALLFRAME_A0(sp)
REG_S a1, XCALLFRAME_A1(sp)
REG_S a2, XCALLFRAME_A2(sp)
REG_S a3, XCALLFRAME_A3(sp)
REG_S a4, XCALLFRAME_A4(sp)
REG_S a5, XCALLFRAME_A5(sp)
REG_S a6, XCALLFRAME_A6(sp)
REG_S a7, XCALLFRAME_A7(sp)
REG_S ra, XCALLFRAME_RA(sp)
mv a0, t0 /* object from got.plt[1] */
mv a1, t1 /* reloc offset */
call _C_LABEL(_rtld_bind)
mv t0, a0 /* save function pointer */
REG_L a0, XCALLFRAME_A0(sp)
REG_L a1, XCALLFRAME_A1(sp)
REG_L a2, XCALLFRAME_A2(sp)
REG_L a3, XCALLFRAME_A3(sp)
REG_L a4, XCALLFRAME_A4(sp)
REG_L a5, XCALLFRAME_A5(sp)
REG_L a6, XCALLFRAME_A6(sp)
REG_L a7, XCALLFRAME_A7(sp)
REG_L ra, XCALLFRAME_RA(sp)
addi sp, sp, XCALLFRAME_SIZ
jr t0
END(_rtld_bind_start)
+10 -4
View File
@@ -1,13 +1,13 @@
/* $NetBSD: mdreloc.c,v 1.30 2011/03/25 18:07:06 joerg Exp $ */
/* $NetBSD: mdreloc.c,v 1.31 2014/08/25 20:40:52 joerg Exp $ */
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mdreloc.c,v 1.30 2011/03/25 18:07:06 joerg Exp $");
__RCSID("$NetBSD: mdreloc.c,v 1.31 2014/08/25 20:40:52 joerg Exp $");
#endif /* not lint */
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mdreloc.c,v 1.30 2011/03/25 18:07:06 joerg Exp $");
__RCSID("$NetBSD: mdreloc.c,v 1.31 2014/08/25 20:40:52 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -282,7 +282,13 @@ _rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rela *rela, Elf_Addr *
if (__predict_false(def == &_rtld_sym_zero))
return 0;
new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
if (tp == NULL)
return 0;
new_value = _rtld_resolve_ifunc(defobj, def);
} else {
new_value = (Elf_Addr)(defobj->relocbase + def->st_value);
}
rdbg(("bind now/fixup in %s --> old=%p new=%p",
defobj->strtab + def->st_name, (void *)*where, (void *)new_value));
if (*where != new_value)
+9 -3
View File
@@ -1,4 +1,4 @@
/* $NetBSD: mdreloc.c,v 1.47 2011/03/31 12:47:01 nakayama Exp $ */
/* $NetBSD: mdreloc.c,v 1.48 2014/08/25 20:40:52 joerg Exp $ */
/*-
* Copyright (c) 1999, 2002 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mdreloc.c,v 1.47 2011/03/31 12:47:01 nakayama Exp $");
__RCSID("$NetBSD: mdreloc.c,v 1.48 2014/08/25 20:40:52 joerg Exp $");
#endif /* not lint */
#include <errno.h>
@@ -448,7 +448,13 @@ _rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rela *rela, Elf_Addr *
if (__predict_false(def == &_rtld_sym_zero))
return 0;
value = (Elf_Addr)(defobj->relocbase + def->st_value);
if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
if (tp == NULL)
return 0;
value = _rtld_resolve_ifunc(defobj, def);
} else {
value = (Elf_Addr)(defobj->relocbase + def->st_value);
}
rdbg(("bind now/fixup in %s --> new=%p",
defobj->strtab + def->st_name, (void *)value));
+20 -14
View File
@@ -1,4 +1,4 @@
/* $NetBSD: mdreloc.c,v 1.55 2013/10/03 10:45:57 martin Exp $ */
/* $NetBSD: mdreloc.c,v 1.57 2014/08/25 20:40:53 joerg Exp $ */
/*-
* Copyright (c) 2000 Eduardo Horvath.
@@ -32,7 +32,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mdreloc.c,v 1.55 2013/10/03 10:45:57 martin Exp $");
__RCSID("$NetBSD: mdreloc.c,v 1.57 2014/08/25 20:40:53 joerg Exp $");
#endif /* not lint */
#include <errno.h>
@@ -170,7 +170,7 @@ static const long reloc_target_bitmask[] = {
_BM(10), _BM(13), _BM(22), /* GOT10, GOT13, GOT22 */
_BM(10), _BM(22), /* _PC10, _PC22 */
_BM(30), 0, /* _WPLT30, _COPY */
_BM(32), _BM(32), _BM(32), /* _GLOB_DAT, JMP_SLOT, _RELATIVE */
-1, _BM(32), -1, /* _GLOB_DAT, JMP_SLOT, _RELATIVE */
_BM(32), _BM(32), /* _UA32, PLT32 */
_BM(22), _BM(10), /* _HIPLT22, LOPLT10 */
_BM(32), _BM(22), _BM(10), /* _PCPLT32, _PCPLT22, _PCPLT10 */
@@ -192,18 +192,18 @@ static const long reloc_target_bitmask[] = {
/*
* Instruction templates:
*/
#define BAA 0x10400000 /* ba,a %xcc, 0 */
#define BAA 0x30680000 /* ba,a %xcc, 0 */
#define SETHI 0x03000000 /* sethi %hi(0), %g1 */
#define JMP 0x81c06000 /* jmpl %g1+%lo(0), %g0 */
#define NOP 0x01000000 /* sethi %hi(0), %g0 */
#define OR 0x82806000 /* or %g1, 0, %g1 */
#define XOR 0x82c06000 /* xor %g1, 0, %g1 */
#define MOV71 0x8283a000 /* or %o7, 0, %g1 */
#define MOV17 0x9c806000 /* or %g1, 0, %o7 */
#define OR 0x82106000 /* or %g1, 0, %g1 */
#define XOR 0x82186000 /* xor %g1, 0, %g1 */
#define MOV71 0x8213e000 /* or %o7, 0, %g1 */
#define MOV17 0x9e106000 /* or %g1, 0, %o7 */
#define CALL 0x40000000 /* call 0 */
#define SLLX 0x8b407000 /* sllx %g1, 0, %g1 */
#define SLLX 0x83287000 /* sllx %g1, 0, %g1 */
#define SETHIG5 0x0b000000 /* sethi %hi(0), %g5 */
#define ORG5 0x82804005 /* or %g1, %g5, %g1 */
#define ORG5 0x82104005 /* or %g1, %g5, %g1 */
/* %hi(v)/%lo(v) with variable shift */
@@ -602,9 +602,15 @@ _rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rela *rela,
if (__predict_false(def == &_rtld_sym_zero))
return 0;
value = (Elf_Addr)(defobj->relocbase + def->st_value);
rdbg(("bind now/fixup in %s --> new=%p",
defobj->strtab + def->st_name, (void *)value));
if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
if (tp == NULL)
return 0;
value = _rtld_resolve_ifunc(defobj, def);
} else {
value = (Elf_Addr)(defobj->relocbase + def->st_value);
}
rdbg(("bind now/fixup in %s at %p --> new=%p",
defobj->strtab + def->st_name, (void*)where, (void *)value));
/*
* At the PLT entry pointed at by `where', we now construct a direct
@@ -696,7 +702,7 @@ _rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rela *rela,
*
*/
where[3] = JMP;
where[2] = XOR | ((~value) & 0x00001fff);
where[2] = XOR | (value & 0x00003ff) | 0x1c00;
where[1] = SETHI | HIVAL(~value, 10);
__asm volatile("iflush %0+12" : : "r" (where));
__asm volatile("iflush %0+8" : : "r" (where));
+14 -7
View File
@@ -1,13 +1,13 @@
/* $NetBSD: mdreloc.c,v 1.28 2011/03/25 18:07:07 joerg Exp $ */
/* $NetBSD: mdreloc.c,v 1.30 2014/08/25 20:40:53 joerg Exp $ */
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mdreloc.c,v 1.28 2011/03/25 18:07:07 joerg Exp $");
__RCSID("$NetBSD: mdreloc.c,v 1.30 2014/08/25 20:40:53 joerg Exp $");
#endif /* not lint */
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mdreloc.c,v 1.28 2011/03/25 18:07:07 joerg Exp $");
__RCSID("$NetBSD: mdreloc.c,v 1.30 2014/08/25 20:40:53 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -142,7 +142,8 @@ _rtld_relocate_plt_lazy(const Obj_Entry *obj)
/* Just relocate the GOT slots pointing into the PLT */
*where += (Elf_Addr)obj->relocbase;
rdbg(("fixup !main in %s --> %p", obj->path, (void *)*where));
rdbg(("lazy fixup pltgot %p in %s --> %p", where, obj->path,
(void *)*where));
}
return 0;
@@ -165,9 +166,15 @@ _rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rela *rela, Elf_Addr *
if (__predict_false(def == &_rtld_sym_zero))
return 0;
new_value = (Elf_Addr)(defobj->relocbase + def->st_value +
rela->r_addend);
rdbg(("bind now/fixup in %s --> old=%p new=%p",
if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
if (tp == NULL)
return 0;
new_value = _rtld_resolve_ifunc(defobj, def);
} else {
new_value = (Elf_Addr)(defobj->relocbase + def->st_value +
rela->r_addend);
}
rdbg(("bind now/fixup pltgot %p in %s --> old=%p new=%p", where,
defobj->strtab + def->st_name, (void *)*where, (void *)new_value));
if (*where != new_value)
*where = new_value;
+218 -18
View File
@@ -1,4 +1,4 @@
/* $NetBSD: rtld_start.S,v 1.16 2003/03/02 22:03:40 mycroft Exp $ */
/* $NetBSD: rtld_start.S,v 1.24 2014/08/17 16:57:37 matt Exp $ */
/*
* Copyright 1996 Matt Thomas <matt@3am-software.com>
@@ -53,26 +53,226 @@ ENTRY(_rtld_start, 0)
movq (%sp)+,%r7 /* grab cleanup and obj_main into %r7/%r8 */
jmp 2(%r0) /* jump to entry point + 2 */
END(_rtld_start)
/*
* Lazy binding entry point, called via PLT.
*
* Note: Some functions rely on there not being an additional call frame;
* hence the `optimization' to avoid the callg opportunistically.
* Lazy binding entry point, called via PLT via JMP into pltgot[1].
* SP+4: address to relocation offset
* SP+0: obj entry points
*/
ALTENTRY(_rtld_bind_start)
pushr $0x3f /* save R0-R5 */
movq 24(%sp),%r0 /* get addresses of plt.got & reloc index */
pushl (%r1) /* push relocation index */
pushl %r1 /* need to preserve r1 */
movq -8(%fp),%r0 /* get addresses of plt.got & reloc index */
pushl (%r1) /* push relocation offset */
pushl %r0 /* push address of obj entry */
calls $2,_rtld_bind
movl %r0,28(%sp) /* save return address onto stack */
bicw3 6(%fp),(%r0),%r0/* does the entry mask save any additional regs */
popr $0x3f /* restore R0-R5 (cond flags not modified) */
bneq 4f /* yes? do it the hard way */
addl2 $4,%sp /* no? skip past plt.got on stack */
addl2 $2,(%sp) /* skip past the mask */
rsb /* and jump to it */
4: addl2 $4,%sp
callg (%ap),*(%sp)+ /* return value from _rtld_bind() == actual */
ret
/*
* This code checks to see if we got called via a call{s,g} $n,*pcrel32
* This is by far the most common case (a call indirectly via the PLT).
*/
subl3 $7,16(%fp),%r1 /* return address */
bicb3 $1,(%r1),%r2 /* fetch opcode of instruction */
cmpb $0xfa,%r2 /* is it calls/callg */
jneq 20f /* no it isn't */
cmpb $0xff,2(%r1) /* and deferred 32-bit PC displacement? */
jneq 20f /* no it isn't */
/*
* This makes sure the longword with the PLT's address has been updated
* to point to the routine's address. If it hasn't, then returning
* would put us in an infinite loop. Instead we punt and fake up a
* callframe.
*/
movl 3(%r1),%r3 /* get displacement */
addl2 16(%fp),%r3 /* add ending location */
cmpl (%r3),%r0 /* does it contain the routine address? */
#ifdef DEBUG
jneq 30f /* no it doesn't, die */
#else
jneq 20f /* no it doesn't, go fake a new callframe */
#endif
11: movl %r1,16(%fp) /* backup to the calls/callg */
jbc $29,4(%fp),12f /* skip if this was a callg */
clrl (%ap) /* clear argument count */
12: movl (%sp)+,%r1 /* restore r1 */
ret /* return and redo the call */
#if 1
20:
/*
* Since the calling standard says only r6-r11 should be saved,
* that simplies things for us. That means we can use r0-r5 as
* temporaries without worrying about preserving them. This means
* can hold the current fixed callframe in r2-r5 as we build the
* callframe without having to worry about overwriting the existing
* callframe.
*/
extzv $0,$12,(%r0),%r1/* get routine's save mask */
bitw $0x3f,%r1 /* does the routine use r0-r5? */
jneq 30f /* yes, that sucks */
jbc $29,4(%fp),27f /* handle callg */
movq 4(%fp),%r2 /* fetch callframe status & saved AP */
movq 12(%fp),%r4 /* fetch callframe saved FP & PC */
insv %r1,$16,$12,%r2 /* update save mask */
movl (%sp)+,%fp /* use fp to keep saved r1 */
movl %ap,%sp /* reset stack to top of callframe */
22: pushr %r1 /* push registers */
movq %r4,-(%sp) /* push callframe saved FP & PC */
movq %r2,-(%sp) /* push callframe status & saved AP */
pushl $0 /* push condition handler */
movl %fp,%r1 /* restore r1 */
movl %sp,%fp /* sp == fp now */
#if 1
jmp 2(%r0) /* jump past entry mask */
#else
/*
* More correct but IV/DV are never set so ignore doing this for now.
*/
movpsl -(%sp) /* push PSL */
clrb (%sp) /* clear user flags */
jbc $14,(%r0),24f /* IV need to be set? */
bisb2 $0x20,(%sp) /* yes, set it. */
24: jbc $15,(%r0),25f /* DV need to be set? */
bisb2 $0x80,(%sp) /* yes, set it. */
25: pushab 2(%r0) /* push address of first instruction */
rei /* and go to it (updating PSW) */
#endif
/*
* Count how many registers are being used for callg.
*/
27: movl $0x32212110,%r3 /* bit counts */
extzv $6,$3,%r1,%r2 /* extract bits 6-8 */
ashl $2,%r2,%r2 /* shift by 2 */
extzv %r2,$4,%r3,%r4 /* extract count */
extzv $9,$3,%r1,%r2 /* extract bits 9-11 */
ashl $2,%r2,%r2 /* shift by 2 */
extzv %r2,$4,%r3,%r5 /* extract count */
movq 4(%fp),%r2 /* fetch callframe status & saved AP */
insv %r1,$16,$12,%r2 /* update save mask */
addl3 %r4,%r5,%r1 /* add counts and discard them */
movq 12(%fp),%r4 /* fetch callframe saved FP & PC */
moval 20(%fp)[%r1],%sp/* pop callframe */
extzv $16,$12,%r2,%r1 /* get save mask back */
jbr 22b /* now build the new callframe */
30:
calls $0,_C_LABEL(_rtld_die)
#else
/*
* Check to see if called via call? $n,w^off(reg)
*/
20: addl2 $2,%r1 /* 16-bit displacement */
bicb3 $1,(%r1),%r2 /* fetch opcode of instruction */
cmpb $0xfa,%r2 /* is it calls/callg */
jneq 30f /* no it isn't */
bicb3 $0x1f,2(%r1),%r3/* extract addressing mode */
cmpb $0xc0,%r3 /* 16-bit displacement? */
jeql 11b /* yes, redo the call */
halt
/*
* Check to see if called via call? $n,b^off(reg)
*/
30: incl %r1 /* 8-bit displacement */
bicb3 $1,(%r1),%r2 /* fetch opcode of instruction */
cmpb $0xfa,%r2 /* is it calls/callg */
jneq 40f /* no it isn't */
bicb3 $0x1f,2(%r1),%r3/* extract addressing mode */
cmpb $0xa0,%r3 /* 8-bit displacement? */
jeql 11b /* yes, redo the call */
halt
/*
* Check to see if called via call? $n,(reg)
*/
40: incl %r1 /* no displacement */
bicb3 $1,(%r1),%r2 /* fetch opcode of instruction */
cmpb $0xfa,%r2 /* is it calls/callg */
jeql 41f /* yes it is */
halt /* no, die die die */
41: bicb3 $0x0f,2(%r1),%r2/* extract addressing mode */
bicb3 $0xf0,2(%r1),%r3/* extract register */
extzv $0,$12,6(%fp),%r4/* extract saved mask */
cmpb $0x60,%r2 /* register deferred? */
jeql 42f /* yes, deal with it */
cmpb $0x90,%r2 /* autoincrement deferred? */
jeql 70f /* yes, deal with it */
halt /* no, die die die */
42: cmpw %r4,$0xffc /* did we save r2-r11? */
jneq 50f /* no, deal with it */
jbc %r3,%r4,43f /* is the register in the saved mask? */
/*
* We saved r2-r11, so it's easy to replace the saved register with
* the right value by indexing into saved register (offset by 8).
*/
movl %r0,(20-8)(%fp)[%r3] /* replace address in saved registers */
jbr 11b /* go back and redo call */
/*
* Must have been called via r0 or r1 which are saved locally.
* So move the routine address in the appropriate slot on the stack.
*/
43: movl %r0,(%sp)[%r3]
jbr 11b /* go back and redo call */
50: jbs %r3,%r4,60f /* is the register in the saved mask? */
jbs %r3,$0x3f,43b /* is it r0-r5? */
/*
* The register used for the call was not saved so we need to move
* the new function address into it so the re-call will use the new
* address.
*/
pushl %r0 /* save function address on the stack */
ashl %r5,$1,%r0 /* create a bitmask for the register */
popr %r0 /* pop it off the stack. */
jbr 11b /* and redo the call */
60: clrl %r2 /* starting offset into saved registers */
clrl %r5 /* start with register 0 */
61: cmpl %r2,%r3 /* is the register to save? */
jneq 62f /* no, advance to next */
movl %r0,20(%fp)[%r5]/* yes, save return address in saved reg */
jbr 11b /* and return the call */
62: jbc %r5,%r4,63f /* is this register saved? */
incl %r5 /* yes, account for it */
63: incl %r2 /* increment register number */
jbr 61b /* and loop */
70: cmpb %r3,$12
blss 71f
halt
71: cmpw %r4,$0xffc /* did we save r2-r11? */
jneq 72f /* no, deal with it */
subl2 $4,(20-8)(%fp)[%r3] /* backup incremented register */
jbr 11b /* and redo the call.
72: jbs %r3,%r4,80f
jbs %r3,%3f,74f
ashl %r5,$1,%r0 /* create a bitmask for the register */
pushr %r0 /* pop it off the stack. */
subl2 $4,(%sp) /* backup incremented register */
popr %r0 /* pop it off the stack. */
jbr 11b /* and redo the call.
73: subl2 %4,(%sp)[%r3] /* backup incremented register */
jbr 11b /* and redo the call.
80: clrl %r2 /* starting offset into saved registers */
clrl %r5 /* start with register 0 */
81: cmpl %r2,%r3 /* is the register to save? */
jneq 82f /* no, advance to next */
subl $4,20(%fp)[%r5] /* yes, backup incremented register */
jbr 11b /* and return the call */
82: jbc %r5,%r4,83f /* is this register saved? */
incl %r5 /* yes, account for it */
83: incl %r2 /* increment register number */
jbr 81b /* and loop */
#endif
END(_rtld_bind_start)
+11 -4
View File
@@ -1,4 +1,4 @@
/* $NetBSD: mdreloc.c,v 1.40 2011/03/25 18:07:07 joerg Exp $ */
/* $NetBSD: mdreloc.c,v 1.41 2014/08/25 20:40:53 joerg Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -68,7 +68,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: mdreloc.c,v 1.40 2011/03/25 18:07:07 joerg Exp $");
__RCSID("$NetBSD: mdreloc.c,v 1.41 2014/08/25 20:40:53 joerg Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -313,8 +313,15 @@ _rtld_relocate_plt_object(const Obj_Entry *obj, const Elf_Rela *rela, Elf_Addr *
if (__predict_false(def == &_rtld_sym_zero))
return 0;
new_value = (Elf_Addr)(defobj->relocbase + def->st_value +
rela->r_addend);
if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
if (tp == NULL)
return 0;
new_value = _rtld_resolve_ifunc(defobj, def);
} else {
new_value = (Elf_Addr)(defobj->relocbase + def->st_value +
rela->r_addend);
}
rdbg(("bind now/fixup in %s --> old=%p new=%p",
defobj->strtab + def->st_name, (void *)*where, (void *)new_value));
if (*where != new_value)
+19 -16
View File
@@ -1,4 +1,4 @@
/* $NetBSD: headers.c,v 1.52 2013/08/03 13:17:05 skrll Exp $ */
/* $NetBSD: headers.c,v 1.59 2014/08/26 21:20:05 joerg Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: headers.c,v 1.52 2013/08/03 13:17:05 skrll Exp $");
__RCSID("$NetBSD: headers.c,v 1.59 2014/08/26 21:20:05 joerg Exp $");
#endif /* not lint */
#include <err.h>
@@ -74,7 +74,9 @@ _rtld_digest_dynamic(const char *execname, Obj_Entry *obj)
bool use_pltrela = false;
Elf_Addr relsz = 0, relasz = 0;
Elf_Addr pltrel = 0, pltrelsz = 0;
#ifdef RTLD_LOADER
Elf_Addr init = 0, fini = 0;
#endif
dbg(("headers: digesting PT_DYNAMIC at %p", obj->dynamic));
for (dynp = obj->dynamic; dynp->d_tag != DT_NULL; ++dynp) {
@@ -227,13 +229,15 @@ _rtld_digest_dynamic(const char *execname, Obj_Entry *obj)
break;
case DT_INIT:
#ifdef RTLD_LOADER
init = dynp->d_un.d_ptr;
#endif
break;
#ifdef HAVE_INITFINI_ARRAY
case DT_INIT_ARRAY:
obj->init_array =
(fptr_t *)(obj->relocbase + dynp->d_un.d_ptr);
(Elf_Addr *)(obj->relocbase + dynp->d_un.d_ptr);
dbg(("headers: DT_INIT_ARRAY at %p",
obj->init_array));
break;
@@ -246,13 +250,15 @@ _rtld_digest_dynamic(const char *execname, Obj_Entry *obj)
#endif
case DT_FINI:
#ifdef RTLD_LOADER
fini = dynp->d_un.d_ptr;
#endif
break;
#ifdef HAVE_INITFINI_ARRAY
case DT_FINI_ARRAY:
obj->fini_array =
(fptr_t *)(obj->relocbase + dynp->d_un.d_ptr);
(Elf_Addr *)(obj->relocbase + dynp->d_un.d_ptr);
dbg(("headers: DT_FINI_ARRAY at %p",
obj->fini_array));
break;
@@ -298,9 +304,15 @@ _rtld_digest_dynamic(const char *execname, Obj_Entry *obj)
break;
#endif
#ifdef __powerpc__
#ifdef _LP64
case DT_PPC64_GLINK:
obj->glink = (Elf_Addr)(uintptr_t)obj->relocbase + dynp->d_un.d_ptr;
break;
#else
case DT_PPC_GOT:
obj->gotptr = (Elf_Addr *)(obj->relocbase + dynp->d_un.d_ptr);
break;
#endif
#endif
case DT_FLAGS_1:
obj->z_now =
@@ -339,20 +351,11 @@ _rtld_digest_dynamic(const char *execname, Obj_Entry *obj)
obj->relalim = obj->pltrela;
}
#if defined(RTLD_LOADER) && defined(__HAVE_FUNCTION_DESCRIPTORS)
#ifdef RTLD_LOADER
if (init != 0)
obj->init = (void (*)(void))
_rtld_function_descriptor_alloc(obj, NULL, init);
obj->init = (Elf_Addr) obj->relocbase + init;
if (fini != 0)
obj->fini = (void (*)(void))
_rtld_function_descriptor_alloc(obj, NULL, fini);
#else
if (init != 0)
obj->init = (void (*)(void))
(obj->relocbase + init);
if (fini != 0)
obj->fini = (void (*)(void))
(obj->relocbase + fini);
obj->fini = (Elf_Addr) obj->relocbase + fini;
#endif
if (dyn_rpath != NULL) {
+6 -1
View File
@@ -1,4 +1,4 @@
.\" $NetBSD: ld.elf_so.1,v 1.15 2010/12/17 08:50:26 wiz Exp $
.\" $NetBSD: ld.elf_so.1,v 1.16 2015/07/03 10:19:29 joerg Exp $
.\"
.\" Copyright (c) 2001 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -89,6 +89,11 @@ The list of default paths which is set to
.Pa /usr/lib .
.El
.Pp
Dynamic loading via
.Xr dlopen 3
uses the DT_RPATH entries of the main binary, independently of which object
the call came from.
.Pp
.Nm
will expand the following variables if present in the paths:
.Bl -tag -width $PLATFORM
+6 -6
View File
@@ -1,4 +1,4 @@
/* $NetBSD: map_object.c,v 1.52 2013/08/03 13:17:05 skrll Exp $ */
/* $NetBSD: map_object.c,v 1.53 2014/10/30 07:53:41 martin Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -34,7 +34,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: map_object.c,v 1.52 2013/08/03 13:17:05 skrll Exp $");
__RCSID("$NetBSD: map_object.c,v 1.53 2014/10/30 07:53:41 martin Exp $");
#endif /* not lint */
#include <errno.h>
@@ -104,10 +104,10 @@ _rtld_map_object(const char *path, int fd, const struct stat *sb)
#endif
Elf_Addr phdr_vaddr;
size_t phdr_memsz;
#if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
#if defined(__minix) && (defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II))
caddr_t gap_addr;
size_t gap_size;
#endif
#endif /* defined(__minix) */
int i;
#ifdef RTLD_LOADER
Elf_Addr clear_vaddr;
@@ -140,7 +140,7 @@ _rtld_map_object(const char *path, int fd, const struct stat *sb)
#else
_rtld_error("%s: read error: %s", path, xstrerror(errno));
goto bad;
#endif
#endif /* defined(__minix) */
}
/* Make sure the file is valid */
if (memcmp(ELFMAG, ehdr->e_ident, SELFMAG) != 0) {
@@ -468,10 +468,10 @@ _rtld_obj_free(Obj_Entry *obj)
}
if (!obj->phdr_loaded)
xfree((void *)(uintptr_t)obj->phdr);
xfree(obj);
#ifdef COMBRELOC
_rtld_combreloc_reset(obj);
#endif
xfree(obj);
}
Obj_Entry *
+38 -9
View File
@@ -1,4 +1,4 @@
/* $NetBSD: map_object.c,v 1.52 2013/08/03 13:17:05 skrll Exp $ */
/* $NetBSD: map_object.c,v 1.53 2014/10/30 07:53:41 martin Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -34,7 +34,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: map_object.c,v 1.52 2013/08/03 13:17:05 skrll Exp $");
__RCSID("$NetBSD: map_object.c,v 1.53 2014/10/30 07:53:41 martin Exp $");
#endif /* not lint */
#include <errno.h>
@@ -49,16 +49,13 @@ __RCSID("$NetBSD: map_object.c,v 1.52 2013/08/03 13:17:05 skrll Exp $");
#include "debug.h"
#include "rtld.h"
#if defined(__minix)
#define MINIXVERBOSE 0
#if MINIXVERBOSE
#include <stdio.h>
#endif
static int protflags(int); /* Elf flags -> mmap protection */
#define EA_UNDEF (~(Elf_Addr)0)
static void Pread(void *addr, size_t size, int fd, off_t off)
{
int s;
@@ -73,6 +70,20 @@ static void Pread(void *addr, size_t size, int fd, off_t off)
}
/* minix-without-mmap version of _rtld_map_object() */
#else
static int protflags(int); /* Elf flags -> mmap protection */
#endif /* defined(__minix) */
#define EA_UNDEF (~(Elf_Addr)0)
/*
* Map a shared object into memory. The argument is a file descriptor,
* which must be open on the object and positioned at its beginning.
*
* The return value is a pointer to a newly-allocated Obj_Entry structure
* for the shared object. Returns NULL on failure.
*/
Obj_Entry *
_rtld_map_object_fallback(const char *path, int fd, const struct stat *sb)
{
@@ -88,30 +99,38 @@ _rtld_map_object_fallback(const char *path, int fd, const struct stat *sb)
int nsegs;
caddr_t mapbase = MAP_FAILED;
size_t mapsize = 0;
#if !defined(__minix)
int mapflags;
#endif /* !defined(__minix) */
Elf_Off base_offset;
#if !defined(__minix)
#ifdef MAP_ALIGNED
Elf_Addr base_alignment;
#endif
#endif /* !defined(__minix) */
Elf_Addr base_vaddr;
Elf_Addr base_vlimit;
Elf_Addr text_vlimit;
#if !defined(__minix)
int text_flags;
#endif /* !defined(__minix) */
caddr_t base_addr;
Elf_Off data_offset;
Elf_Addr data_vaddr;
Elf_Addr data_vlimit;
#if !defined(__minix)
int data_flags;
#endif /* !defined(__minix) */
caddr_t data_addr;
#if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
Elf_Addr tls_vaddr = 0; /* Noise GCC */
#endif
Elf_Addr phdr_vaddr;
size_t phdr_memsz;
#if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
#if defined(__minix) && (defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II))
caddr_t gap_addr;
size_t gap_size;
#endif
#endif /* defined(__minix) */
int i;
#ifdef RTLD_LOADER
Elf_Addr clear_vaddr;
@@ -271,18 +290,24 @@ _rtld_map_object_fallback(const char *path, int fd, const struct stat *sb)
* and unmap the gaps left by padding to alignment.
*/
#if !defined(__minix)
#ifdef MAP_ALIGNED
base_alignment = segs[0]->p_align;
#endif
#endif /* !defined(__minix) */
base_offset = round_down(segs[0]->p_offset);
base_vaddr = round_down(segs[0]->p_vaddr);
base_vlimit = round_up(segs[1]->p_vaddr + segs[1]->p_memsz);
text_vlimit = round_up(segs[0]->p_vaddr + segs[0]->p_memsz);
#if !defined(__minix)
text_flags = protflags(segs[0]->p_flags);
#endif /* !defined(__minix) */
data_offset = round_down(segs[1]->p_offset);
data_vaddr = round_down(segs[1]->p_vaddr);
data_vlimit = round_up(segs[1]->p_vaddr + segs[1]->p_filesz);
#if !defined(__minix)
data_flags = protflags(segs[1]->p_flags);
#endif /* !defined(__minix) */
#ifdef RTLD_LOADER
clear_vaddr = segs[1]->p_vaddr + segs[1]->p_filesz;
#endif
@@ -344,6 +369,7 @@ _rtld_map_object_fallback(const char *path, int fd, const struct stat *sb)
/*
* Calculate log2 of the base section alignment.
*/
#if !defined(__minix)
mapflags = 0;
#ifdef MAP_ALIGNED
if (base_alignment > _rtld_pagesz) {
@@ -353,6 +379,7 @@ _rtld_map_object_fallback(const char *path, int fd, const struct stat *sb)
mapflags = MAP_ALIGNED(log2);
}
#endif
#endif /* defined(__minix) */
#ifdef RTLD_LOADER
base_addr = obj->isdynamic ? NULL : (caddr_t)base_vaddr;
@@ -406,7 +433,7 @@ _rtld_map_object_fallback(const char *path, int fd, const struct stat *sb)
xstrerror(errno));
goto bad;
}
#endif
#endif /* defined(__minix) */
#ifdef RTLD_LOADER
/* Clear any BSS in the last page of the data segment. */
@@ -450,6 +477,7 @@ bad:
return NULL;
}
#if !defined(__minix)
/*
* Given a set of ELF protection flags, return the corresponding protection
* flags for MMAP.
@@ -475,3 +503,4 @@ protflags(int elfflags)
#endif /* defined(__minix) */
return prot;
}
#endif /* defined(__minix) */
+15 -3
View File
@@ -1,4 +1,4 @@
/* $NetBSD: reloc.c,v 1.106 2012/01/06 10:38:56 skrll Exp $ */
/* $NetBSD: reloc.c,v 1.107 2014/08/25 20:40:52 joerg Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -39,7 +39,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: reloc.c,v 1.106 2012/01/06 10:38:56 skrll Exp $");
__RCSID("$NetBSD: reloc.c,v 1.107 2014/08/25 20:40:52 joerg Exp $");
#endif /* not lint */
#include <err.h>
@@ -186,7 +186,6 @@ _rtld_relocate_objects(Obj_Entry *first, bool bind_now)
dbg(("doing non-PLT relocations"));
if (_rtld_relocate_nonplt_objects(obj) < 0)
ok = 0;
#if !defined(__minix)
if (obj->textrel) { /* Re-protected the text segment. */
if (mprotect(obj->mapbase, obj->textsize,
@@ -231,3 +230,16 @@ _rtld_relocate_objects(Obj_Entry *first, bool bind_now)
return 0;
}
Elf_Addr
_rtld_resolve_ifunc(const Obj_Entry *obj, const Elf_Sym *def)
{
Elf_Addr target;
_rtld_shared_exit();
target = _rtld_call_function_addr(obj,
(Elf_Addr)obj->relocbase + def->st_value);
_rtld_shared_enter();
return target;
}
+50 -29
View File
@@ -1,4 +1,4 @@
/* $NetBSD: rtld.c,v 1.171 2013/11/20 07:18:23 skrll Exp $ */
/* $NetBSD: rtld.c,v 1.177 2015/04/06 09:34:15 yamt Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: rtld.c,v 1.171 2013/11/20 07:18:23 skrll Exp $");
__RCSID("$NetBSD: rtld.c,v 1.177 2015/04/06 09:34:15 yamt Exp $");
#endif /* not lint */
#include <sys/param.h>
@@ -49,9 +49,7 @@ __RCSID("$NetBSD: rtld.c,v 1.171 2013/11/20 07:18:23 skrll Exp $");
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#if !defined(__minix)
#include <lwp.h>
#endif /* !defined(__minix) */
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -140,25 +138,25 @@ static void _rtld_unref_dag(Obj_Entry *);
static Obj_Entry *_rtld_obj_from_addr(const void *);
static inline void
_rtld_call_initfini_function(fptr_t func, sigset_t *mask)
_rtld_call_initfini_function(const Obj_Entry *obj, Elf_Addr func, sigset_t *mask)
{
_rtld_exclusive_exit(mask);
(*func)();
_rtld_call_function_void(obj, func);
_rtld_exclusive_enter(mask);
}
static void
_rtld_call_fini_function(Obj_Entry *obj, sigset_t *mask, u_int cur_objgen)
{
if (obj->fini_arraysz == 0 && (obj->fini == NULL || obj->fini_called)) {
return;
}
if (obj->fini != NULL && !obj->fini_called) {
if (obj->fini_arraysz == 0 && (obj->fini == 0 || obj->fini_called))
return;
if (obj->fini != 0 && !obj->fini_called) {
dbg (("calling fini function %s at %p%s", obj->path,
(void *)obj->fini,
obj->z_initfirst ? " (DF_1_INITFIRST)" : ""));
obj->fini_called = 1;
_rtld_call_initfini_function(obj->fini, mask);
_rtld_call_initfini_function(obj, obj->fini, mask);
}
#ifdef HAVE_INITFINI_ARRAY
/*
@@ -168,12 +166,12 @@ _rtld_call_fini_function(Obj_Entry *obj, sigset_t *mask, u_int cur_objgen)
* the loop.
*/
while (obj->fini_arraysz > 0 && _rtld_objgen == cur_objgen) {
fptr_t fini = *obj->fini_array++;
Elf_Addr fini = *obj->fini_array++;
obj->fini_arraysz--;
dbg (("calling fini array function %s at %p%s", obj->path,
(void *)fini,
obj->z_initfirst ? " (DF_1_INITFIRST)" : ""));
_rtld_call_initfini_function(fini, mask);
_rtld_call_initfini_function(obj, fini, mask);
}
#endif /* HAVE_INITFINI_ARRAY */
}
@@ -234,15 +232,15 @@ restart:
static void
_rtld_call_init_function(Obj_Entry *obj, sigset_t *mask, u_int cur_objgen)
{
if (obj->init_arraysz == 0 && (obj->init_called || obj->init == NULL)) {
if (obj->init_arraysz == 0 && (obj->init_called || obj->init == 0))
return;
}
if (!obj->init_called && obj->init != NULL) {
if (!obj->init_called && obj->init != 0) {
dbg (("calling init function %s at %p%s",
obj->path, (void *)obj->init,
obj->z_initfirst ? " (DF_1_INITFIRST)" : ""));
obj->init_called = 1;
_rtld_call_initfini_function(obj->init, mask);
_rtld_call_initfini_function(obj, obj->init, mask);
}
#ifdef HAVE_INITFINI_ARRAY
@@ -253,12 +251,12 @@ _rtld_call_init_function(Obj_Entry *obj, sigset_t *mask, u_int cur_objgen)
* the loop.
*/
while (obj->init_arraysz > 0 && _rtld_objgen == cur_objgen) {
fptr_t init = *obj->init_array++;
Elf_Addr init = *obj->init_array++;
obj->init_arraysz--;
dbg (("calling init_array function %s at %p%s",
obj->path, (void *)init,
obj->z_initfirst ? " (DF_1_INITFIRST)" : ""));
_rtld_call_initfini_function(init, mask);
_rtld_call_initfini_function(obj, init, mask);
}
#endif /* HAVE_INITFINI_ARRAY */
}
@@ -562,7 +560,10 @@ _rtld(Elf_Addr *sp, Elf_Addr relocbase)
*oenvp++ = *env;
}
} else if (strncmp(*env, bind_var, LEN(bind_var)) == 0) {
ld_bind_now = *env + LEN(bind_var);
if (_rtld_trust) {
ld_bind_now = *env + LEN(bind_var);
*oenvp++ = *env;
}
} else if (strncmp(*env, path_var, LEN(path_var)) == 0) {
if (_rtld_trust) {
ld_library_path = *env + LEN(path_var);
@@ -1177,6 +1178,17 @@ do_dlsym(void *handle, const char *name, const Ver_Entry *ventry, void *retaddr)
if (def != NULL) {
void *p;
if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
#ifdef __HAVE_FUNCTION_DESCRIPTORS
lookup_mutex_exit();
_rtld_shared_enter();
#endif
p = (void *)_rtld_resolve_ifunc(defobj, def);
_rtld_shared_exit();
return p;
}
#ifdef __HAVE_FUNCTION_DESCRIPTORS
if (ELF_ST_TYPE(def->st_info) == STT_FUNC) {
p = (void *)_rtld_function_descriptor_alloc(defobj,
@@ -1259,7 +1271,7 @@ dladdr(const void *addr, Dl_info *info)
obj = _rtld_obj_from_addr(addr);
if (obj == NULL) {
_rtld_error("No shared object contains address");
lookup_mutex_enter();
lookup_mutex_exit();
return 0;
}
info->dli_fname = obj->path;
@@ -1421,6 +1433,9 @@ _rtld_error(const char *fmt,...)
void
_rtld_debug_state(void)
{
#if defined(__hppa__)
__asm volatile("nop" ::: "memory");
#endif
/* Prevent optimizer from removing calls to this function */
__insn_barrier();
@@ -1537,6 +1552,7 @@ _rtld_shared_enter(void)
/* Yes, so increment use counter */
if (atomic_cas_uint(&_rtld_mutex, cur, cur + 1) != cur)
continue;
membar_enter();
return;
}
/*
@@ -1554,9 +1570,11 @@ _rtld_shared_enter(void)
/*
* Check for race against _rtld_exclusive_exit before sleeping.
*/
membar_sync();
if ((_rtld_mutex & RTLD_EXCLUSIVE_MASK) ||
_rtld_waiter_exclusive)
_lwp_park(NULL, 0, __UNVOLATILE(&_rtld_mutex), NULL);
_lwp_park(CLOCK_REALTIME, 0, NULL, 0,
__UNVOLATILE(&_rtld_mutex), NULL);
/* Try to remove us from the waiter list. */
atomic_cas_uint(&_rtld_waiter_shared, self, 0);
if (waiter)
@@ -1580,12 +1598,12 @@ _rtld_shared_exit(void)
* Wakeup LWPs waiting for an exclusive lock if this is the last
* LWP on the shared lock.
*/
membar_exit();
if (atomic_dec_uint_nv(&_rtld_mutex))
return;
membar_sync();
if ((waiter = _rtld_waiter_exclusive) != 0)
_lwp_unpark(waiter, __UNVOLATILE(&_rtld_mutex));
membar_exit();
}
void
@@ -1600,19 +1618,21 @@ _rtld_exclusive_enter(sigset_t *mask)
sigdelset(&blockmask, SIGTRAP); /* Allow the debugger */
sigprocmask(SIG_BLOCK, &blockmask, mask);
membar_enter();
for (;;) {
if (atomic_cas_uint(&_rtld_mutex, 0, locked_value) == 0)
if (atomic_cas_uint(&_rtld_mutex, 0, locked_value) == 0) {
membar_enter();
break;
}
waiter = atomic_swap_uint(&_rtld_waiter_exclusive, self);
membar_sync();
cur = _rtld_mutex;
if (cur == locked_value) {
_rtld_error("dead lock detected");
_rtld_die();
}
if (cur)
_lwp_park(NULL, 0, __UNVOLATILE(&_rtld_mutex), NULL);
_lwp_park(CLOCK_REALTIME, 0, NULL, 0,
__UNVOLATILE(&_rtld_mutex), NULL);
atomic_cas_uint(&_rtld_waiter_exclusive, self, 0);
if (waiter)
_lwp_unpark(waiter, __UNVOLATILE(&_rtld_mutex));
@@ -1624,14 +1644,15 @@ _rtld_exclusive_exit(sigset_t *mask)
{
lwpid_t waiter;
membar_exit();
_rtld_mutex = 0;
membar_sync();
if ((waiter = _rtld_waiter_exclusive) != 0)
_lwp_unpark(waiter, __UNVOLATILE(&_rtld_mutex));
if ((waiter = _rtld_waiter_shared) != 0)
_lwp_unpark(waiter, __UNVOLATILE(&_rtld_mutex));
membar_exit();
sigprocmask(SIG_SETMASK, mask, NULL);
}
#endif /* !defined(__minix) */
+30 -9
View File
@@ -1,4 +1,4 @@
/* $NetBSD: rtld.h,v 1.116 2013/05/09 15:38:14 christos Exp $ */
/* $NetBSD: rtld.h,v 1.124 2014/09/19 17:43:33 matt Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -48,7 +48,7 @@
#if defined(_RTLD_SOURCE)
#ifdef __ARM_EABI__
#if defined(__ARM_EABI__) && !defined(__ARM_DWARF_EH__)
#include "unwind.h"
#endif
@@ -179,7 +179,7 @@ typedef struct Struct_Obj_Entry {
const Elf_Sym *symtab; /* Symbol table */
const char *strtab; /* String table */
unsigned long strsize; /* Size in bytes of string table */
#ifdef __mips__
#if defined(__mips__) || defined(__riscv__)
Elf_Word local_gotno; /* Number of local GOT entries */
Elf_Word symtabno; /* Number of dynamic symbols */
Elf_Word gotsym; /* First dynamic symbol in GOT */
@@ -193,8 +193,8 @@ typedef struct Struct_Obj_Entry {
Search_Path *rpaths; /* Search path specified in object */
Needed_Entry *needed; /* Shared objects needed by this (%) */
fptr_t init; /* Initialization function to call */
fptr_t fini; /* Termination function to call */
Elf_Addr init; /* Initialization function to call */
Elf_Addr fini; /* Termination function to call */
/*
* BACKWARDS COMPAT Entry points for dlopen() and friends.
@@ -259,8 +259,12 @@ typedef struct Struct_Obj_Entry {
* object we know about. */
#ifdef __powerpc__
#ifdef _LP64
Elf_Addr glink; /* global linkage */
#else
Elf_Addr *gotptr; /* GOT table (secure-plt only) */
#endif
#endif
#if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
/* Thread Local Storage support for this module */
@@ -284,9 +288,9 @@ typedef struct Struct_Obj_Entry {
int vertabnum; /* Number of entries in vertab */
/* init_array/fini_array */
fptr_t *init_array; /* start of init array */
Elf_Addr *init_array; /* start of init array */
size_t init_arraysz; /* # of entries in it */
fptr_t *fini_array; /* start of fini array */
Elf_Addr *fini_array; /* start of fini array */
size_t fini_arraysz; /* # of entries in it */
#ifdef __ARM_EABI__
void *exidx_start;
@@ -322,7 +326,7 @@ extern Elf_Sym _rtld_sym_zero;
/* Flags to be passed into _rtld_symlook_ family of functions. */
#define SYMLOOK_IN_PLT 0x01 /* Lookup for PLT symbol */
#define SYMLOOK_DLSYM 0x02 /* Return newes versioned symbol.
#define SYMLOOK_DLSYM 0x02 /* Return newest versioned symbol.
Used by dlsym. */
/* Flags for _rtld_load_object() and friends. */
@@ -348,7 +352,7 @@ __dso_public int dl_iterate_phdr(int (*)(struct dl_phdr_info *, size_t, void *),
__dso_public void *_dlauxinfo(void) __pure;
#ifdef __ARM_EABI__
#if defined(__ARM_EABI__) && !defined(__ARM_DWARF_EH__)
/*
* This is used by libgcc to find the start and length of the exception table
* associated with a PC.
@@ -400,6 +404,7 @@ int _rtld_relocate_nonplt_objects(Obj_Entry *);
int _rtld_relocate_plt_lazy(const Obj_Entry *);
int _rtld_relocate_plt_objects(const Obj_Entry *);
void _rtld_setup_pltgot(const Obj_Entry *);
Elf_Addr _rtld_resolve_ifunc(const Obj_Entry *, const Elf_Sym *);
/* search.c */
Obj_Entry *_rtld_load_library(const char *, const Obj_Entry *, int);
@@ -473,12 +478,28 @@ Obj_Entry *_rtld_map_object_fallback(const char *, int, const struct stat *);
void _rtld_obj_free(Obj_Entry *);
Obj_Entry *_rtld_obj_new(void);
#ifdef RTLD_LOADER
/* function descriptors */
#ifdef __HAVE_FUNCTION_DESCRIPTORS
Elf_Addr _rtld_function_descriptor_alloc(const Obj_Entry *,
const Elf_Sym *, Elf_Addr);
const void *_rtld_function_descriptor_function(const void *);
void _rtld_call_function_void(const Obj_Entry *, Elf_Addr);
Elf_Addr _rtld_call_function_addr(const Obj_Entry *, Elf_Addr);
#else
static inline void
_rtld_call_function_void(const Obj_Entry *obj, Elf_Addr addr)
{
((void (*)(void))addr)();
}
static inline Elf_Addr
_rtld_call_function_addr(const Obj_Entry *obj, Elf_Addr addr)
{
return ((Elf_Addr(*)(void))addr)();
}
#endif /* __HAVE_FUNCTION_DESCRIPTORS */
#endif /* RTLD_LOADER */
#endif /* _RTLD_SOURCE */
+4 -4
View File
@@ -1,4 +1,4 @@
/* $NetBSD: symbol.c,v 1.63 2013/05/03 10:27:05 skrll Exp $ */
/* $NetBSD: symbol.c,v 1.65 2014/08/10 23:35:26 matt Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: symbol.c,v 1.63 2013/05/03 10:27:05 skrll Exp $");
__RCSID("$NetBSD: symbol.c,v 1.65 2014/08/10 23:35:26 matt Exp $");
#endif /* not lint */
#include <err.h>
@@ -101,7 +101,7 @@ _rtld_is_exported(const Elf_Sym *def)
(fptr_t)___tls_get_addr,
#endif
#endif
#ifdef __ARM_EABI__
#if defined(__ARM_EABI__) && !defined(__ARM_DWARF_EH__)
(fptr_t)__gnu_Unwind_Find_exidx, /* for gcc EHABI */
#endif
NULL
@@ -260,7 +260,7 @@ _rtld_symlook_obj(const char *name, unsigned long hash,
rdbg(("check \"%s\" vs \"%s\" in %s", name, strp, obj->path));
if (name[1] != strp[1] || strcmp(name, strp))
continue;
#ifdef __mips__
#if defined(__mips__) || defined(__vax__)
if (symp->st_shndx == SHN_UNDEF)
continue;
#else
+7 -10
View File
@@ -1,4 +1,4 @@
/* $NetBSD: sysident.h,v 1.16 2013/09/10 16:35:10 matt Exp $ */
/* $NetBSD: sysident.h,v 1.17 2014/01/12 19:36:08 joerg Exp $ */
/*
* Copyright (c) 1997 Christopher G. Demetriou
@@ -63,7 +63,7 @@
#define __S(x) __STRING(x)
__asm(
".section\t\".note.netbsd.ident\", \"a\"\n"
".pushsection\t\".note.netbsd.ident\", \"a\"\n"
"\t.p2align\t2\n\n"
"\t.long\t" __S(ELF_NOTE_NETBSD_NAMESZ) "\n"
@@ -72,12 +72,11 @@ __asm(
"\t.ascii\t" __S(ELF_NOTE_NETBSD_NAME) "\n"
"\t.long\t" __S(__NetBSD_Version__) "\n\n"
"\t.previous\n"
"\t.p2align\t2\n"
"\t.popsection\n"
);
__asm(
".section\t\".note.netbsd.pax\", \"a\"\n"
".pushsection\t\".note.netbsd.pax\", \"a\"\n"
"\t.p2align\t2\n\n"
"\t.long\t" __S(ELF_NOTE_PAX_NAMESZ) "\n"
@@ -86,13 +85,12 @@ __asm(
"\t.ascii\t" __S(ELF_NOTE_PAX_NAME) "\n"
"\t.long\t" __S(0) "\n\n"
"\t.previous\n"
"\t.p2align\t2\n"
"\t.popsection\n"
);
#ifdef ELF_NOTE_MARCH_DESC
__asm(
".section\t\".note.netbsd.march\", \"a\"\n"
".pushsection\t\".note.netbsd.march\", \"a\"\n"
"\t.p2align\t2\n\n"
"\t.long\t" __S(ELF_NOTE_MARCH_NAMESZ) "\n"
@@ -102,7 +100,6 @@ __asm(
"1:\t.asciz\t" __S(ELF_NOTE_MARCH_DESC) "\n"
"2:\n"
"\t.previous\n"
"\t.p2align\t2\n"
"\t.popsection\n"
);
#endif
+2 -9
View File
@@ -1,4 +1,4 @@
/* $NetBSD: tls.c,v 1.9 2013/10/21 19:14:15 joerg Exp $ */
/* $NetBSD: tls.c,v 1.10 2014/12/14 23:49:17 chs Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: tls.c,v 1.9 2013/10/21 19:14:15 joerg Exp $");
__RCSID("$NetBSD: tls.c,v 1.10 2014/12/14 23:49:17 chs Exp $");
#include <sys/param.h>
#include <sys/ucontext.h>
@@ -106,13 +106,6 @@ _rtld_tls_initial_allocation(void)
tcb = _rtld_tls_allocate_locked();
#ifdef __HAVE___LWP_SETTCB
__lwp_settcb(tcb);
#ifdef __powerpc__
/*
* Save the tcb pointer so that libc can retrieve it. Older
* crt0 will obliterate r2 so there is code in libc to restore it.
*/
_lwp_setprivate(tcb);
#endif
#else
_lwp_setprivate(tcb);
#endif
+1 -1
View File
@@ -1,4 +1,4 @@
.\" $NetBSD: makewhatis.8,v 1.13 2013/07/20 21:39:57 wiz Exp $
.\" $NetBSD: makewhatis.8,v 1.14 2014/03/18 18:20:38 riastradh Exp $
.\"
.\" Copyright (c) 1997, 2002 The NetBSD Foundation, Inc.
.\" All rights reserved.
+4 -4
View File
@@ -147,9 +147,9 @@ __dead static void usage(void);
#define OPTIONS "aLln"
extern int __check_rhosts_file;
extern char *__rcmd_errstr; /* syslog hook from libc/net/rcmd.c. */
#ifdef USE_PAM
#if defined(__minix) && defined(USE_PAM)
static const char incorrect[] = "Login incorrect.";
#endif
#endif /* defined(__minix) && defined(USE_PAM) */
int
main(int argc, char *argv[])
@@ -578,10 +578,10 @@ doit(struct sockaddr *fromp, struct sockaddr *localp)
/* should set s nbio! */
do {
#ifdef __minix
#if defined(__minix)
if (set[0].events == 0 && set[1].events == 0)
break;
#endif /* __minix */
#endif /* defined(__minix) */
if (poll(set, 2, INFTIM) < 0)
break;
if (set[0].revents & POLLIN) {