summaryrefslogtreecommitdiff
path: root/libexec/ld.so
diff options
context:
space:
mode:
Diffstat (limited to 'libexec/ld.so')
-rw-r--r--libexec/ld.so/Makefile21
-rw-r--r--libexec/ld.so/alpha/archdep.h165
-rw-r--r--libexec/ld.so/alpha/ldasm.S176
-rw-r--r--libexec/ld.so/alpha/rtld_machine.c401
-rw-r--r--libexec/ld.so/alpha/syscall.h80
-rw-r--r--libexec/ld.so/ldconfig/Makefile3
-rw-r--r--libexec/ld.so/ldd/Makefile3
-rw-r--r--libexec/ld.so/ldd/ldd.c36
-rw-r--r--libexec/ld.so/loader.c48
-rw-r--r--libexec/ld.so/test/Makefile7
-rw-r--r--libexec/ld.so/test/dltest.c6
11 files changed, 906 insertions, 40 deletions
diff --git a/libexec/ld.so/Makefile b/libexec/ld.so/Makefile
index 3410535349f..cb546787b0e 100644
--- a/libexec/ld.so/Makefile
+++ b/libexec/ld.so/Makefile
@@ -1,13 +1,6 @@
-# $OpenBSD: Makefile,v 1.3 2000/09/17 17:50:57 deraadt Exp $
+# $OpenBSD: Makefile,v 1.4 2001/05/14 22:18:19 niklas Exp $
SUBDIR=libdl ldconfig ldd
-#CFLAGS =
-.if (${MACHINE_ARCH} == "powerpc")
-CFLAGS += -fpic -msoft-float
-.endif
-CFLAGS += -I${.CURDIR} -DNO_UNDERSCORE -DVERBOSE_DLINKER \
- -DUSE_CACHE -D__PIC__ -I${.CURDIR}/${MACHINE_ARCH}
-#CFLAGS += -g
VPATH=${.CURDIR}/../../lib/libc/string:${.CURDIR}/../../sys/lib/libsa
NOMAN=
@@ -17,6 +10,18 @@ OBJS+= strchr.o
PROG= ld.so
MAN= ld.so.8
BINDIR=/usr/libexec
+CFLAGS += -Werror
+.if (${MACHINE_ARCH} == "powerpc")
+CFLAGS += -fpic -msoft-float
+.endif
+.if (${MACHINE_ARCH} == "alpha")
+CFLAGS += -fpic -mno-fp-regs
+LIBCSRCDIR=${.CURDIR}/../../lib/libc
+.include "${LIBCSRCDIR}/arch/alpha/Makefile.inc"
+.endif
+CFLAGS += -I${.CURDIR} -DNO_UNDERSCORE -DVERBOSE_DLINKER \
+ -DUSE_CACHE -D__PIC__ -I${.CURDIR}/${MACHINE_ARCH}
+CFLAGS += -g -DDL_PRINTF_DEBUG
INSTALL_STRIP=
.PATH: ${.CURDIR}/${MACHINE_ARCH}
diff --git a/libexec/ld.so/alpha/archdep.h b/libexec/ld.so/alpha/archdep.h
new file mode 100644
index 00000000000..49846926455
--- /dev/null
+++ b/libexec/ld.so/alpha/archdep.h
@@ -0,0 +1,165 @@
+/* $OpenBSD: archdep.h,v 1.1 2001/05/14 22:18:20 niklas Exp $ */
+
+/*
+ * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed under OpenBSD by
+ * Per Fogelstrom, Opsycon AB, Sweden.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef _ALPHA_ARCHDEP_H_
+#define _ALPHA_ARCHDEP_H_
+
+#define DL_MALLOC_ALIGN 8 /* Arch constraint or otherwise */
+
+#define MACHID EM_ALPHA_EXP /* ELF e_machine ID value checked */
+
+#define RELTYPE Elf64_Rela
+#define RELSIZE sizeof(Elf64_Rela)
+
+#include <elf_abi.h>
+#include <machine/reloc.h>
+
+int _dl_write __P((int, const char *, int));
+
+/*
+ * The following functions are declared inline so they can
+ * be used before bootstrap linking has been finished.
+ */
+static inline void
+_dl_dcbf(Elf64_Addr *addr)
+{
+}
+
+static inline void
+_dl_wrstderr(const char *s)
+{
+ while(*s) {
+ _dl_write(2, s, 1);
+ s++;
+ }
+}
+
+static inline void *
+_dl_memset(void *p, const char v, size_t c)
+{
+ char *ip = p;
+
+ while(c--)
+ *ip++ = v;
+ return(p);
+}
+
+static inline int
+_dl_strlen(const char *p)
+{
+ const char *s = p;
+
+ while(*s != '\0')
+ s++;
+ return(s - p);
+}
+
+static inline char *
+_dl_strcpy(char *d, const char *s)
+{
+ char *rd = d;
+
+ while((*d++ = *s++) != '\0');
+
+ return(rd);
+}
+
+static inline int
+_dl_strncmp(const char *d, const char *s, int c)
+{
+ while(c-- && *d && *d == *s) {
+ d++;
+ s++;
+ };
+ if(c < 0) {
+ return(0);
+ }
+ return(*d - *s);
+}
+
+static inline int
+_dl_strcmp(const char *d, const char *s)
+{
+ while(*d && *d == *s) {
+ d++;
+ s++;
+ }
+ return(*d - *s);
+}
+
+static inline const char *
+_dl_strchr(const char *p, const int c)
+{
+ while(*p) {
+ if(*p == c) {
+ return(p);
+ }
+ p++;
+ }
+ return(0);
+}
+
+static inline void
+RELOC_RELA(Elf64_Rela *r,
+ const Elf64_Sym *s, Elf64_Addr *p, int v)
+{
+ if(ELF64_R_TYPE((r)->r_info) == RELOC_RELATIVE) {
+ if((ELF64_ST_BIND((s)->st_info) == STB_LOCAL) &&
+ ((ELF64_ST_TYPE((s)->st_info) == STT_SECTION) ||
+ (ELF64_ST_TYPE((s)->st_info) == STT_NOTYPE)) ) {
+ *(p) = (v) + (r)->r_addend;
+ } else {
+ *(p) = (v) + (s)->st_value + (r)->r_addend;
+ }
+ } else if(ELF64_R_TYPE((r)->r_info) == RELOC_JMP_SLOT) {
+ Elf64_Addr val = (v) + (s)->st_value + (r)->r_addend -
+ (Elf64_Addr)(p);
+ if (((val & 0xfe000000) != 0) &&
+ ((val & 0xfe000000) != 0xfe000000))
+ {
+ /* invalid offset */
+ _dl_exit(20);
+ }
+ val &= ~0xfc000000;
+ val |= 0x48000000;
+ *(p) = val;
+ _dl_dcbf(p);
+ } else if(ELF64_R_TYPE((r)->r_info) == RELOC_GLOB_DAT) {
+ *(p) = (v) + (s)->st_value + (r)->r_addend;
+ } else {
+ /* error */
+ }
+}
+
+#endif /* _ALPHA_ARCHDEP_H_ */
diff --git a/libexec/ld.so/alpha/ldasm.S b/libexec/ld.so/alpha/ldasm.S
new file mode 100644
index 00000000000..0e2cac14f85
--- /dev/null
+++ b/libexec/ld.so/alpha/ldasm.S
@@ -0,0 +1,176 @@
+/* $OpenBSD: ldasm.S,v 1.1 2001/05/14 22:18:20 niklas Exp $ */
+
+/*
+ * Copyright (c) 2001 Niklas Hallqvist
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed under OpenBSD by
+ * Niklas Hallqvist.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <machine/asm.h>
+#include <machine/pal.h>
+#include <sys/syscall.h>
+
+#define AUX_entry 9
+
+ .extern _GLOBAL_OFFSET_TABLE_
+
+/* Not really a leaf... but we are special. */
+LEAF_NOPROFILE(_dl_start, 0)
+ .set noreorder
+ lda sp, (-8 - ((AUX_entry + 1) * 8))(sp)
+ br pv, L1
+L1:
+ LDGP(pv)
+ ldiq t2, L1
+ subq pv, t2, t2
+ lda t0, _GLOBAL_OFFSET_TABLE_
+ addq t0, t2, t0
+ lda t1, _DYNAMIC
+ addq t1, t2, t1
+L2: cmpult t0, t1, t3
+ beq t3, L3
+ ldq t3, 0(t0)
+ addq t3, t2, t3
+ stq t3, 0(t0)
+ lda t0, 8(t0)
+ br L2
+L3:
+ mov a0, s0
+ mov t2, a1 /* relocation displacement */
+ mov a1, s1
+ ldq a2, 0(a0) /* argc */
+ lda a3, 8(a0) /* argv */
+ mov a3, s3
+ lda t3, 1(a2)
+ sll t3, 3, t3
+ addq a3, t3, a4 /* envp */
+ mov a4, s4
+ mov t1, a5 /* dynamic */
+ mov a5, s5
+ lda s2, 8(sp)
+ stq s2, 0(sp) /* dl_link */
+ CALL(_dl_boot_bind)
+ mov s3, a0
+ mov s4, a1
+ mov s1, a2
+ mov s5, a3
+ mov s2, a4
+ CALL(_dl_boot)
+ mov s0, a0
+ mov v0, pv
+ jsr ra, (pv)
+END(_dl_start)
+
+/*
+ * In reality these are not leaves, but they are stubs which does not need
+ * further register saving.
+ */
+
+LEAF_NOPROFILE(_dl_exit, 1)
+ ldiq v0, SYS_exit
+ call_pal PAL_OSF1_callsys
+ RET
+END(_dl_exit)
+
+LEAF_NOPROFILE(_dl_open, 2)
+ ldiq v0, SYS_open
+ call_pal PAL_OSF1_callsys
+ RET
+END(_dl_open)
+
+LEAF_NOPROFILE(_dl_close, 1)
+ ldiq v0, SYS_close
+ call_pal PAL_OSF1_callsys
+ RET
+END(_dl_close)
+
+LEAF_NOPROFILE(_dl_write, 3)
+ ldiq v0, SYS_write
+ call_pal PAL_OSF1_callsys
+ RET
+END(_dl_write)
+
+LEAF_NOPROFILE(_dl_read, 3)
+ ldiq v0, SYS_read
+ call_pal PAL_OSF1_callsys
+ RET
+END(_dl_exit)
+
+LEAF_NOPROFILE(_dl_mmap, 6)
+ lda sp, -8(sp)
+ stq a5, 0(sp)
+ ldiq v0, SYS_mmap
+ call_pal PAL_OSF1_callsys
+ lda sp, 8(sp)
+ RET
+END(_dl_mmap)
+
+LEAF_NOPROFILE(_dl_munmap, 2)
+ ldiq v0, SYS_munmap
+ call_pal PAL_OSF1_callsys
+ RET
+END(_dl_munmap)
+
+LEAF_NOPROFILE(_dl_mprotect, 3)
+ ldiq v0, SYS_mprotect
+ call_pal PAL_OSF1_callsys
+ RET
+END(_dl_mprotect)
+
+LEAF_NOPROFILE(_dl_getuid, 0)
+ ldiq v0, SYS_getuid
+ call_pal PAL_OSF1_callsys
+ RET
+END(_dl_getuid)
+
+LEAF_NOPROFILE(_dl_geteuid, 0)
+ ldiq v0, SYS_geteuid
+ call_pal PAL_OSF1_callsys
+ RET
+END(_dl_geteuid)
+
+LEAF_NOPROFILE(_dl_getgid, 0)
+ ldiq v0, SYS_getgid
+ call_pal PAL_OSF1_callsys
+ RET
+END(_dl_getgid)
+
+LEAF_NOPROFILE(_dl_getegid, 0)
+ ldiq v0, SYS_getegid
+ call_pal PAL_OSF1_callsys
+ RET
+END(_dl_getegid)
+
+#ifdef USE_CACHE
+LEAF_NOPROFILE(_dl_stat, 2)
+ ldiq v0, SYS_stat
+ call_pal PAL_OSF1_callsys
+ RET
+END(_dl_stat)
+#endif
diff --git a/libexec/ld.so/alpha/rtld_machine.c b/libexec/ld.so/alpha/rtld_machine.c
new file mode 100644
index 00000000000..3ce9c1dc4d0
--- /dev/null
+++ b/libexec/ld.so/alpha/rtld_machine.c
@@ -0,0 +1,401 @@
+/* $OpenBSD: rtld_machine.c,v 1.1 2001/05/14 22:18:21 niklas Exp $ */
+
+/*
+ * Copyright (c) 1999 Dale Rahn
+ * Copyright (c) 2001 Niklas Hallqvist
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed under OpenBSD by
+ * Dale Rahn.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#define _DYN_LOADER
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+
+#include <machine/elf_machdep.h>
+
+#include <nlist.h>
+#include <link.h>
+
+#include "syscall.h"
+#include "archdep.h"
+#include "resolve.h"
+
+void
+_dl_bcopy(void *src, void *dest, int size)
+{
+ unsigned char *psrc, *pdest;
+ int i;
+ psrc = src;
+ pdest = dest;
+ for (i = 0; i < size; i++) {
+ pdest[i] = psrc[i];
+ }
+}
+
+int
+_dl_md_reloc(elf_object_t *object, int rel, int relasz)
+{
+ int i;
+ int numrela;
+ int fails = 0;
+ Elf64_Addr loff;
+ Elf64_Rela *relas;
+ /* for jmp table relocations */
+ Elf64_Addr *pltcall;
+ Elf64_Addr *plttable;
+
+ Elf64_Addr * first_rela;
+
+ loff = object->load_offs;
+ numrela = object->Dyn.info[relasz] / sizeof(Elf64_Rela);
+ relas = (Elf64_Rela *)(object->Dyn.info[rel]);
+
+#ifdef DL_PRINTF_DEBUG
+_dl_printf("loff 0x%lx object relocation size %x, numrela %x\n", loff,
+ object->Dyn.info[relasz], numrela);
+#endif
+
+ if((object->status & STAT_RELOC_DONE) || !relas) {
+ return(0);
+ }
+ /* for plt relocation usage */
+ if (object->Dyn.info[DT_JMPREL] != 0) {
+ /* resolver stub not set up */
+ Elf64_Addr val;
+
+ first_rela = (Elf64_Addr *)
+ (((Elf64_Rela *)(object->Dyn.info[DT_JMPREL]))->r_offset
+ + loff);
+ /* Need to construct table to do jumps */
+ pltcall = (Elf64_Addr *)(first_rela) - 12;
+#ifdef DL_PRINTF_DEBUG
+_dl_printf("creating pltcall at %p\n", pltcall);
+_dl_printf("md_reloc( jumprel %p\n", first_rela );
+#endif
+ plttable = (Elf64_Addr *)
+ ((Elf64_Addr)first_rela) + (2 *
+ (object->Dyn.info[DT_PLTRELSZ]/sizeof(Elf64_Rela))
+ );
+
+#ifdef DL_PRINTF_DEBUG
+_dl_printf("md_reloc: plttbl size %x\n",
+ (object->Dyn.info[DT_PLTRELSZ]/sizeof(Elf64_Rela))
+);
+_dl_printf("md_reloc: plttable %p\n", plttable);
+#endif
+ } else {
+ first_rela = NULL;
+ }
+
+ for(i = 0; i < numrela; i++, relas++) {
+ Elf64_Addr *r_addr = (Elf64_Addr *)(relas->r_offset + loff);
+ Elf64_Addr ooff;
+ const Elf64_Sym *sym, *this;
+ const char *symn;
+
+#if 0
+_dl_printf("%d offset 0x%lx info 0x%lx addend 0x%lx\n", i, relas->r_offset, relas->r_info, relas->r_addend);
+#endif
+
+ if(ELF64_R_SYM(relas->r_info) == 0xffffff) {
+ continue;
+ }
+
+ sym = object->dyn.symtab;
+ sym += ELF64_R_SYM(relas->r_info);
+ this = sym;
+ symn = object->dyn.strtab + sym->st_name;
+
+ if(ELF64_R_SYM(relas->r_info) &&
+ !(ELF64_ST_BIND(sym->st_info) == STB_LOCAL &&
+ ELF64_ST_TYPE (sym->st_info) == STT_NOTYPE)) {
+
+ ooff = _dl_find_symbol(symn, _dl_objects, &this, 0, 1);
+ if(!this && ELF64_ST_BIND(sym->st_info) == STB_GLOBAL) {
+ _dl_printf("%s:"
+ " %s :can't resolve reference '%s'\n",
+ _dl_progname, object->load_name,
+ symn);
+ fails++;
+ }
+
+ }
+
+#if 0
+_dl_printf("reloc %d\n", ELF64_R_TYPE(relas->r_info));
+#endif
+ switch(ELF64_R_TYPE(relas->r_info)) {
+#if 1
+ case R_TYPE(REFQUAD):
+ if(ELF64_ST_BIND(sym->st_info) == STB_LOCAL &&
+ (ELF64_ST_TYPE(sym->st_info) == STT_SECTION ||
+ ELF64_ST_TYPE(sym->st_info) == STT_NOTYPE) ) {
+ *r_addr = ooff + relas->r_addend;
+ } else {
+ *r_addr = ooff + this->st_value +
+ relas->r_addend;
+ }
+ break;
+#endif
+ case R_TYPE(RELATIVE):
+#if 0
+_dl_printf("sym info %d r_addr %p relas %p\n", sym->st_info, r_addr, relas);
+#endif
+ if(ELF64_ST_BIND(sym->st_info) == STB_LOCAL &&
+ (ELF64_ST_TYPE(sym->st_info) == STT_SECTION ||
+ ELF64_ST_TYPE(sym->st_info) == STT_NOTYPE) ) {
+#if 0
+_dl_printf("addend 0x%lx\n", relas->r_addend);
+_dl_printf("*r_addr 0x%lx\n", *r_addr);
+#endif
+ *r_addr = loff + relas->r_addend;
+#if 0
+_dl_printf("*r_addr 0x%lx\n", *r_addr);
+#endif
+
+#ifdef DL_PRINTF_DEBUG
+_dl_printf("rel1 r_addr %p val %lx loff %lx ooff %lx addend %lx\n", r_addr,
+loff + relas->r_addend, loff, ooff, relas->r_addend);
+#endif
+
+ } else {
+#if 0
+_dl_printf("this %p\n", this);
+#endif
+ *r_addr = loff + this->st_value +
+ relas->r_addend;
+ }
+ break;
+ case R_TYPE(JMP_SLOT):
+ {
+ Elf64_Addr val = ooff + this->st_value +
+ relas->r_addend - (Elf64_Addr)r_addr;
+ if (!(((val & 0xfe000000) == 0x00000000) ||
+ ((val & 0xfe000000) == 0xfe000000)))
+ {
+ int index;
+#ifdef DL_PRINTF_DEBUG
+_dl_printf(" ooff %lx, sym val %lx, addend %lx"
+ " r_addr %lx symn [%s] -> %x\n",
+ ooff, this->st_value, relas->r_addend,
+ r_addr, symn, val);
+#endif
+ /* if offset is > RELOC_24 deal with it */
+ index = (r_addr - first_rela) >> 1;
+
+ if (index > (2 << 14)) {
+
+ /* addis r11,r11,.PLTtable@ha*/
+ val = (index*4 >> 16) +
+ ((index*4 & 0x00008000) >> 15);
+ r_addr[0] = 0x3d600000 | val;
+ val = (Elf64_Addr)pltcall -
+ (Elf64_Addr)&r_addr[2];
+ r_addr[1] = 0x396b0000 | val;
+ val &= ~0xfc000000;
+ val |= 0x48000000;
+ r_addr[2] = val;
+
+ } else {
+#ifdef DL_PRINTF_DEBUG
+ _dl_printf(" index %d, pltcall %x r_addr %lx\n",
+ index, pltcall, r_addr);
+#endif
+
+ r_addr[0] = 0x39600000 | (index * 4);
+ val = (Elf64_Addr)pltcall -
+ (Elf64_Addr)&r_addr[1];
+ val &= ~0xfc000000;
+ val |= 0x48000000;
+ r_addr[1] = val;
+
+ }
+ _dl_dcbf(r_addr);
+ _dl_dcbf(&r_addr[2]);
+ val= ooff + this->st_value +
+ relas->r_addend;
+#ifdef DL_PRINTF_DEBUG
+ _dl_printf(" symn [%s] val 0x%x\n", symn, val);
+#endif
+ plttable[index] = val;
+ } else {
+ /* if the offset is small enough,
+ * branch directy to the dest
+ */
+ val &= ~0xfc000000;
+ val |= 0x48000000;
+ *r_addr = val;
+ _dl_dcbf(r_addr);
+ }
+ }
+
+ break;
+ case R_TYPE(GLOB_DAT):
+ *r_addr = ooff + this->st_value + relas->r_addend;
+ break;
+#if 0
+#ifdef DL_PRINTF_DEBUG
+ /* should not be supported ??? */
+ case RELOC_REL24:
+ {
+ Elf64_Addr val = ooff + this->st_value +
+ relas->r_addend - (Elf64_Addr)r_addr;
+ if ((val & 0xfe000000 != 0) &&
+ (val & 0xfe000000 != 0xfe000000))
+ {
+ /* invalid offset */
+ _dl_exit(20);
+ }
+ val &= ~0xfc000003;
+ val |= (*r_addr & 0xfc000003);
+ *r_addr = val;
+
+ _dl_dcbf(r_addr);
+ }
+#endif
+ break;
+ case RELOC_REL14_TAKEN:
+ /* val |= 1 << (31-10) XXX? */
+ case RELOC_REL14:
+ case RELOC_REL14_NTAKEN:
+ {
+ Elf64_Addr val = ooff + this->st_value +
+ relas->r_addend - (Elf64_Addr)r_addr;
+ if (((val & 0xffff8000) != 0) &&
+ ((val & 0xffff8000) != 0xffff8000))
+ {
+ /* invalid offset */
+ _dl_exit(20);
+ }
+ val &= ~0xffff0003;
+ val |= (*r_addr & 0xffff0003);
+ *r_addr = val;
+#ifdef DL_PRINTF_DEBUG
+ _dl_printf("rel 14 %lx val %lx\n",
+ r_addr, val);
+#endif
+
+ _dl_dcbf(r_addr);
+ }
+ break;
+#endif
+ case R_TYPE(COPY):
+#ifdef DL_PRINTF_DEBUG
+ _dl_printf("copy r_addr %lx, sym %x [%s] size %d val %lx\n",
+ r_addr, sym, symn, sym->st_size,
+ (ooff + this->st_value+
+ relas->r_addend)
+
+ );
+#endif
+{
+ /* we need to find a symbol, that is not in the current object,
+ * start looking at the beginning of the list, searching all objects
+ * but _not_ the current object, first one found wins.
+ */
+ elf_object_t *cobj;
+ const Elf64_Sym *cpysrc = NULL;
+ Elf64_Addr src_loff;
+ int size;
+ for (cobj = _dl_objects;
+ cobj != NULL && cpysrc == NULL;
+ cobj = cobj->next)
+ {
+ if (object != cobj) {
+
+ /* only look in this object */
+ src_loff = _dl_find_symbol(symn, cobj,
+ &cpysrc, 1, 1);
+ }
+ }
+ if (cpysrc == NULL) {
+ _dl_printf("symbol not found [%s] \n", symn);
+ } else {
+ size = sym->st_size;
+ if (sym->st_size != cpysrc->st_size) {
+ _dl_printf("symbols size differ [%s] \n", symn);
+ size = sym->st_size < cpysrc->st_size ?
+ sym->st_size : cpysrc->st_size;
+ }
+#ifdef DL_PRINTF_DEBUG
+_dl_printf(" found other symbol at %x size %d\n",
+ src_loff + cpysrc->st_value, cpysrc->st_size);
+#endif
+ _dl_bcopy((void *)(src_loff + cpysrc->st_value),
+ (void *)(ooff + this->st_value+ relas->r_addend),
+ size);
+ }
+}
+ break;
+ case R_TYPE(NONE):
+ break;
+
+ default:
+ _dl_printf("%s:"
+ " %s: unsupported relocation '%s' %d at %lx\n",
+ _dl_progname, object->load_name, symn,
+ ELF64_R_TYPE(relas->r_info), r_addr );
+ _dl_exit(1);
+ }
+ }
+ object->status |= STAT_RELOC_DONE;
+#if 0
+_dl_printf("<\n");
+#endif
+ return(fails);
+}
+
+/*
+ * Relocate the Global Offset Table (GOT). Currently we don't
+ * do lazy evaluation here because the GNU linker doesn't
+ * follow the ABI spec which says that if an external symbol
+ * is referenced by other relocations than CALL16 and 26 it
+ * should not be given a stub and have a zero value in the
+ * symbol table. By not doing so, we can't use pointers to
+ * external functions and use them in comparitions...
+ */
+void
+_dl_md_reloc_got(elf_object_t *object, int lazy)
+{
+ /* relocations all done via rela relocations above */
+}
+
+/* should not be defined here, but is is 32 for all powerpc 603-G4 */
+#define CACHELINESIZE 32
+void
+_dl_syncicache(char *from, size_t len)
+{
+ int l = len;
+ unsigned int off = 0;
+
+ while (off < len) {
+ off += CACHELINESIZE;
+ }
+}
diff --git a/libexec/ld.so/alpha/syscall.h b/libexec/ld.so/alpha/syscall.h
new file mode 100644
index 00000000000..02ddf74ff33
--- /dev/null
+++ b/libexec/ld.so/alpha/syscall.h
@@ -0,0 +1,80 @@
+/* $OpenBSD: syscall.h,v 1.1 2001/05/14 22:18:22 niklas Exp $ */
+
+/*
+ * Copyright (c) 2001 Niklas Hallqvist
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed under OpenBSD by
+ * Niklas Hallqvist.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifdef USE_CACHE
+#include <sys/stat.h>
+#endif
+
+#ifndef _dl_MAX_ERRNO
+#define _dl_MAX_ERRNO 4096
+#endif
+#define _dl_check_error(__res) \
+ ((int) __res < 0 && (int) __res >= -_dl_MAX_ERRNO)
+
+int _dl_close __P((int));
+int _dl_exit __P((int));
+int _dl_getegid __P((void));
+int _dl_geteuid __P((void));
+int _dl_getgid __P((void));
+int _dl_getuid __P((void));
+long _dl_mmap __P((void *, unsigned int, unsigned int, unsigned int, int,
+ off_t));
+int _dl_mprotect __P((const void *, int, int));
+int _dl_munmap __P((const void*, unsigned int));
+int _dl_open __P((const char*, unsigned int));
+void _dl_printf __P((const char *, ...));
+int _dl_read __P((int, const char*, int));
+#ifdef USE_CACHE
+int _dl_stat __P((const char *, struct stat *));
+#endif
+int _dl_write __P((int, const char*, int));
+
+/*
+ * Not an actual syscall, but we need something in assembly to say
+ * whether this is OK or not.
+ */
+
+static inline int
+_dl_suid_ok (void)
+{
+ unsigned int uid, euid, gid, egid;
+
+ uid = _dl_getuid();
+ euid = _dl_geteuid();
+ gid = _dl_getgid();
+ egid = _dl_getegid();
+ return (uid == euid && gid == egid);
+}
+
+#include <elf_abi.h>
diff --git a/libexec/ld.so/ldconfig/Makefile b/libexec/ld.so/ldconfig/Makefile
index 0b938006e3f..66454b75d5a 100644
--- a/libexec/ld.so/ldconfig/Makefile
+++ b/libexec/ld.so/ldconfig/Makefile
@@ -1,9 +1,10 @@
-# $OpenBSD: Makefile,v 1.1 2000/06/13 03:40:14 rahnds Exp $
+# $OpenBSD: Makefile,v 1.2 2001/05/14 22:18:22 niklas Exp $
# $NetBSD: Makefile,v 1.10 1995/03/06 04:24:41 cgd Exp $
PROG= ldconfig
SRCS= ldconfig.c shlib.c etc.c
LDDIR?= $(.CURDIR)/..
+CFLAGS+=-Werror
#CFLAGS+=-I$(.CURDIR) -I$(LDDIR)/$(MACHINE_ARCH)
LDSTATIC=-static
BINDIR= /sbin
diff --git a/libexec/ld.so/ldd/Makefile b/libexec/ld.so/ldd/Makefile
index b0ed6f7af69..ed14c54f7cb 100644
--- a/libexec/ld.so/ldd/Makefile
+++ b/libexec/ld.so/ldd/Makefile
@@ -1,8 +1,9 @@
-# $OpenBSD: Makefile,v 1.1 2000/09/17 17:50:57 deraadt Exp $
+# $OpenBSD: Makefile,v 1.2 2001/05/14 22:18:22 niklas Exp $
PROG= ldd
SRCS= ldd.c
MAN= ldd.1
+CFLAGS+=-Werror
BINDIR= /usr/bin
diff --git a/libexec/ld.so/ldd/ldd.c b/libexec/ld.so/ldd/ldd.c
index 5a3bb37c96a..a6fc9453839 100644
--- a/libexec/ld.so/ldd/ldd.c
+++ b/libexec/ld.so/ldd/ldd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldd.c,v 1.2 2001/05/11 15:50:14 art Exp $ */
+/* $OpenBSD: ldd.c,v 1.3 2001/05/14 22:18:23 niklas Exp $ */
/*
* Copyright (c) 1993 Paul Kranenburg
@@ -176,18 +176,18 @@ main(argc, argv)
int
readsoneeded(FILE *infile, int dyncheck)
{
- Elf32_Ehdr *epnt;
- Elf32_Phdr *ppnt;
+ Elf_Ehdr *epnt;
+ Elf_Phdr *ppnt;
int i;
int isdynamic = 0;
char *header;
- unsigned int dynamic_addr = 0;
- unsigned int dynamic_size = 0;
+ unsigned long dynamic_addr = 0;
+ unsigned long dynamic_size = 0;
int strtab_val = 0;
int soname_val = 0;
- int loadaddr = -1;
- int loadbase = 0;
- Elf32_Dyn *dpnt;
+ long loadaddr = -1;
+ long loadbase = 0;
+ Elf_Dyn *dpnt;
struct stat st;
char *res = NULL;
@@ -197,13 +197,13 @@ readsoneeded(FILE *infile, int dyncheck)
if (header == MAP_FAILED)
return -1;
- epnt = (Elf32_Ehdr *)header;
- if ((int)(epnt+1) > (int)(header + st.st_size))
+ epnt = (Elf_Ehdr *)header;
+ if ((u_long)(epnt+1) > (u_long)(header + st.st_size))
goto skip;
- ppnt = (Elf32_Phdr *)&header[epnt->e_phoff];
- if ((int)ppnt < (int)header ||
- (int)(ppnt+epnt->e_phnum) > (int)(header + st.st_size))
+ ppnt = (Elf_Phdr *)&header[epnt->e_phoff];
+ if ((u_long)ppnt < (u_long)header ||
+ (u_long)(ppnt+epnt->e_phnum) > (u_long)(header + st.st_size))
goto skip;
for (i = 0; i < epnt->e_phnum; i++) {
@@ -217,10 +217,10 @@ readsoneeded(FILE *infile, int dyncheck)
ppnt++;
}
- dpnt = (Elf32_Dyn *) &header[dynamic_addr];
- dynamic_size = dynamic_size / sizeof(Elf32_Dyn);
- if ((int)dpnt < (int)header ||
- (int)(dpnt+dynamic_size) > (int)(header + st.st_size))
+ dpnt = (Elf_Dyn *) &header[dynamic_addr];
+ dynamic_size = dynamic_size / sizeof(Elf_Dyn);
+ if ((u_long)dpnt < (u_long)header ||
+ (u_long)(dpnt+dynamic_size) > (u_long)(header + st.st_size))
goto skip;
while (dpnt->d_tag != DT_NULL) {
@@ -235,7 +235,7 @@ readsoneeded(FILE *infile, int dyncheck)
if (!strtab_val)
goto skip;
- dpnt = (Elf32_Dyn *) &header[dynamic_addr];
+ dpnt = (Elf_Dyn *) &header[dynamic_addr];
while (dpnt->d_tag != DT_NULL) {
if (dpnt->d_tag == DT_NEEDED) {
isdynamic = 1;
diff --git a/libexec/ld.so/loader.c b/libexec/ld.so/loader.c
index d9aced351bb..5c85b1d7e4b 100644
--- a/libexec/ld.so/loader.c
+++ b/libexec/ld.so/loader.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: loader.c,v 1.8 2001/05/12 10:39:54 art Exp $ */
+/* $OpenBSD: loader.c,v 1.9 2001/05/14 22:18:19 niklas Exp $ */
/*
* Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -54,7 +54,7 @@
*/
static void *_dl_malloc_base;
static void *_dl_malloc_pool = 0;
-static long *_dl_malloc_free = 0;
+static long *_dl_malloc_free = 0;
const char *_dl_progname;
int _dl_pagesz;
@@ -140,6 +140,13 @@ _dl_boot(const char **argv, const char **envp, const long loff,
struct elf_object *exe_obj; /* Pointer to executable object */
struct elf_object *dyn_obj; /* Pointer to executable object */
struct r_debug * debug_map;
+#ifdef __mips__
+ struct r_debug **map_link; /* Where to put pointer for gdb */
+#endif /* __mips__ */
+
+#if 0
+_dl_printf("%p %p 0x%lx %p %p\n", argv, envp, loff, dynp, dl_data);
+#endif
/*
* Get paths to various things we are going to use.
@@ -302,6 +309,9 @@ _dl_boot(const char **argv, const char **envp, const long loff,
if (_dl_traceld) {
_dl_exit(0);
}
+#if 0
+_dl_printf("0x%lx\n", dl_data[AUX_entry]);
+#endif
return(dl_data[AUX_entry]);
}
@@ -316,10 +326,20 @@ _dl_boot_bind(const long sp, const long loff, int argc, const char **argv,
AuxInfo *auxstack;
struct elf_object dynld; /* Resolver data for the loader */
-#ifdef __mips__
- struct r_debug *debug_map; /* Dynamic objects map for gdb */
- struct r_debug **map_link; /* Where to put pointer for gdb */
-#endif /* __mips__ */
+
+#if 0
+_dl_printf("0x%lx 0x%lx %d %p %p %p %p\n", sp, loff, argc, argv, envp, dynamicp, dl_data);
+ _dl_printf("%p 0x%lx 0x%lx 0x%lx 0x%lx\n", &((long *)sp)[0], ((long *)sp)[0], ((long *)sp)[1], ((long *)sp)[2], ((long *)sp)[3]);
+ _dl_printf("%p 0x%lx 0x%lx 0x%lx 0x%lx\n", &((long *)sp)[4], ((long *)sp)[4], ((long *)sp)[5], ((long *)sp)[6], ((long *)sp)[7]);
+ _dl_printf("%p 0x%lx 0x%lx 0x%lx 0x%lx\n", &((long *)sp)[8], ((long *)sp)[8], ((long *)sp)[9], ((long *)sp)[10], ((long *)sp)[11]);
+ _dl_printf("%p 0x%lx 0x%lx 0x%lx 0x%lx\n", &((long *)sp)[12], ((long *)sp)[12], ((long *)sp)[13], ((long *)sp)[14], ((long *)sp)[15]);
+ _dl_printf("%p 0x%lx 0x%lx 0x%lx 0x%lx\n", &((long *)sp)[16], ((long *)sp)[16], ((long *)sp)[17], ((long *)sp)[18], ((long *)sp)[19]);
+ _dl_printf("%p 0x%lx 0x%lx 0x%lx 0x%lx\n", &((long *)sp)[20], ((long *)sp)[20], ((long *)sp)[21], ((long *)sp)[22], ((long *)sp)[23]);
+ _dl_printf("%p 0x%lx 0x%lx 0x%lx 0x%lx\n", &((long *)sp)[24], ((long *)sp)[24], ((long *)sp)[25], ((long *)sp)[26], ((long *)sp)[27]);
+ _dl_printf("%p 0x%lx 0x%lx 0x%lx 0x%lx\n", &((long *)sp)[28], ((long *)sp)[28], ((long *)sp)[29], ((long *)sp)[30], ((long *)sp)[31]);
+ _dl_printf("%p 0x%lx 0x%lx 0x%lx 0x%lx\n", &((long *)sp)[32], ((long *)sp)[32], ((long *)sp)[33], ((long *)sp)[34], ((long *)sp)[35]);
+ _dl_printf("XXX 0x%lx\n", ((long *)sp)[23]);
+#endif
/*
* Scan argument and environment vectors. Find dynamic
@@ -341,13 +361,29 @@ _dl_boot_bind(const long sp, const long loff, int argc, const char **argv,
auxstack = (AuxInfo *)stack;
+#if 0
+ _dl_printf("XXX 0x%lx\n", ((long *)sp)[23]);
+_dl_printf("---\n");
+#endif
while(auxstack->au_id != AUX_null) {
+#if 0
+ _dl_printf("XXX %p 0x%lx\n", &((long *)sp)[23], ((long *)sp)[23]);
+ _dl_printf("XXX %p 0x%lx\n", &auxstack->au_v, auxstack->au_v);
+_dl_printf("%p 0x%lx 0x%lx %d 0x%lx\n", auxstack, ((long *)auxstack)[0], ((long *)auxstack)[1], auxstack->au_id, auxstack->au_v);
+#endif
if(auxstack->au_id <= AUX_entry) {
dl_data[auxstack->au_id] = auxstack->au_v;
}
auxstack++;
}
+#if 0
+_dl_printf("---\n");
+ _dl_printf("0x%lx 0x%lx 0x%lx 0x%lx\n", dl_data[0], dl_data[1], dl_data[2], dl_data[3]);
+ _dl_printf("0x%lx 0x%lx 0x%lx 0x%lx\n", dl_data[4], dl_data[5], dl_data[6], dl_data[7]);
+ _dl_printf("0x%lx 0x%lx 0x%lx 0x%lx\n", dl_data[8], dl_data[9], dl_data[10], dl_data[11]);
+#endif
+
/*
* We need to do 'selfreloc' in case the code were'nt
* loaded at the address it was linked to.
diff --git a/libexec/ld.so/test/Makefile b/libexec/ld.so/test/Makefile
index fdf5114fcc6..d5dbc4c2e57 100644
--- a/libexec/ld.so/test/Makefile
+++ b/libexec/ld.so/test/Makefile
@@ -1,12 +1,13 @@
-# $OpenBSD: Makefile,v 1.3 2000/10/13 05:15:17 drahn Exp $
+# $OpenBSD: Makefile,v 1.4 2001/05/14 22:18:23 niklas Exp $
DIR=/usr/src/libexec/ld.so/obj/ld.so
-.if (${MACHINE_ARCH} == "powerpc")
+.if (${MACHINE_ARCH} != "mips")
#necssary to build the shared objects. not necessary for dltest but
#doesn't hurt
CFLAGS += -fpic
.endif
CFLAGS += -g
+CFLAGS += -I${.CURDIR}/.. -I${.CURDIR}/../${MACHINE_ARCH}
LDFLAGS += -Wl,--export-dynamic -Wl,-dynamic-linker -Wl,${DIR}
#LDFLAGS += -Wl,--export-dynamic
@@ -43,7 +44,7 @@ libB.so: B.o
$(CC) -shared -o $@ B.o
CCtest: libA.so libB.so tst.o
- g++ ${LDFLAGS} -o $@ tst.o -L . -lB -lA
+ g++ ${LDFLAGS} -o $@ tst.o libB.so libA.so
.include <bsd.prog.mk>
.include <bsd.subdir.mk>
diff --git a/libexec/ld.so/test/dltest.c b/libexec/ld.so/test/dltest.c
index 7d722b43188..ccac4337177 100644
--- a/libexec/ld.so/test/dltest.c
+++ b/libexec/ld.so/test/dltest.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dltest.c,v 1.2 2001/01/28 19:34:29 niklas Exp $ */
+/* $OpenBSD: dltest.c,v 1.3 2001/05/14 22:18:23 niklas Exp $ */
#include <stdio.h>
#include <stdlib.h>
@@ -8,8 +8,8 @@
#include <elf_abi.h>
#include <machine/reloc.h>
#include <nlist.h>
-#include "../powerpc/archdep.h"
-#include "../resolve.h"
+#include "archdep.h"
+#include "resolve.h"
typedef void (*func_t)(const char *);