summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPer Fogelstrom <pefo@cvs.openbsd.org>2002-10-23 12:38:30 +0000
committerPer Fogelstrom <pefo@cvs.openbsd.org>2002-10-23 12:38:30 +0000
commitdb0dfc1e5e65b8f62e7ee1c09359956563d37ec3 (patch)
treed425f8772f69efaa117ec5b738e45de077e76777
parent45e5a93b6f8946f30d58f6e53d1c6ab1d84c4b62 (diff)
mips archdep stuff update while waiting for ok on mi
-rw-r--r--libexec/ld.so/mips/Makefile.inc5
-rw-r--r--libexec/ld.so/mips/archdep.h61
-rw-r--r--libexec/ld.so/mips/ldasm.S47
-rw-r--r--libexec/ld.so/mips/rtld_machine.c39
-rw-r--r--libexec/ld.so/mips/syscall.h130
5 files changed, 221 insertions, 61 deletions
diff --git a/libexec/ld.so/mips/Makefile.inc b/libexec/ld.so/mips/Makefile.inc
new file mode 100644
index 00000000000..5b440950a9f
--- /dev/null
+++ b/libexec/ld.so/mips/Makefile.inc
@@ -0,0 +1,5 @@
+# $OpenBSD: Makefile.inc,v 1.1 2002/10/23 12:38:29 pefo Exp $
+
+# CFLAGS += -fpic -msoft-float
+# ADDR=-Tdata 8000
+# ELF_LDFLAGS+=${ADDR}
diff --git a/libexec/ld.so/mips/archdep.h b/libexec/ld.so/mips/archdep.h
index f25c00f51dd..929325909b7 100644
--- a/libexec/ld.so/mips/archdep.h
+++ b/libexec/ld.so/mips/archdep.h
@@ -1,7 +1,7 @@
-/* $OpenBSD: archdep.h,v 1.3 2002/05/24 03:44:37 deraadt Exp $ */
+/* $OpenBSD: archdep.h,v 1.4 2002/10/23 12:38:29 pefo Exp $ */
/*
- * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
+ * Copyright (c) 1998-2002 Opsycon AB, Sweden.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -13,8 +13,7 @@
* 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.
+ * This product includes software developed by 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.
*
@@ -35,7 +34,11 @@
#ifndef _MIPS_ARCHDEP_H_
#define _MIPS_ARCHDEP_H_
+#include <link.h>
+#include <machine/reloc.h>
+
#include "syscall.h"
+#include "resolve.h"
#include "util.h"
#define DL_MALLOC_ALIGN 4 /* Arch constraint or otherwise */
@@ -45,4 +48,54 @@
#define RELTYPE Elf32_Rel
#define RELSIZE sizeof(Elf32_Rel)
+static inline void
+RELOC_REL(Elf_Rel *r, const Elf_Sym *s, Elf_Addr *p, unsigned long v)
+{
+}
+
+static inline void
+RELOC_RELA(Elf32_Rela *r, const Elf32_Sym *s, Elf32_Addr *p, unsigned long v)
+{
+ _dl_exit(20);
+}
+
+struct elf_object;
+
+static inline void
+RELOC_GOT(struct elf_object *dynld, long loff)
+{
+ Elf32_Addr *gotp;
+ int i, n;
+ const Elf_Sym *sp;
+
+ /* Do all local gots */
+ gotp = dynld->dyn.pltgot;
+ n = dynld->Dyn.info[DT_MIPS_LOCAL_GOTNO - DT_LOPROC + DT_NUM];
+
+ for (i = ((gotp[1] & 0x80000000) ? 2 : 1); i < n; i++) {
+ gotp[i] += loff;
+ }
+ gotp += n;
+
+ /* Do symbol referencing gots. There should be no global... */
+ n = dynld->Dyn.info[DT_MIPS_SYMTABNO - DT_LOPROC + DT_NUM] -
+ dynld->Dyn.info[DT_MIPS_GOTSYM - DT_LOPROC + DT_NUM];
+ sp = dynld->dyn.symtab;
+ sp += dynld->Dyn.info[DT_MIPS_GOTSYM - DT_LOPROC + DT_NUM];
+
+ while (n--) {
+ if (sp->st_shndx == SHN_UNDEF ||
+ sp->st_shndx == SHN_COMMON) {
+ _dl_exit(6);
+ } else if (ELF32_ST_TYPE(sp->st_info) == STT_FUNC) {
+ *gotp += loff;
+ } else {
+ *gotp = sp->st_value + loff;
+ }
+ gotp++;
+ sp++;
+ }
+ dynld->status |= STAT_GOT_DONE;
+}
+
#endif /* _MIPS_ARCHDEP_H_ */
diff --git a/libexec/ld.so/mips/ldasm.S b/libexec/ld.so/mips/ldasm.S
index e4216d38b7f..9d5b9a503a8 100644
--- a/libexec/ld.so/mips/ldasm.S
+++ b/libexec/ld.so/mips/ldasm.S
@@ -1,7 +1,7 @@
-/* $OpenBSD: ldasm.S,v 1.2 2002/05/24 03:44:38 deraadt Exp $ */
+/* $OpenBSD: ldasm.S,v 1.3 2002/10/23 12:38:29 pefo Exp $ */
/*
- * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
+ * Copyright (c) 1998-2002 Opsycon AB, Sweden.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -13,8 +13,7 @@
* 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.
+ * This product includes software developed by 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.
*
@@ -34,27 +33,55 @@
#include <machine/asm.h>
+/* Stack at this stage is:
+ * struct stack {
+ * int kargc;
+ * char *kargv[1]; size depends on kargc
+ * char kargstr[1]; size varies
+ * char kenvstr[1]; size varies
+ * };
+ */
+
LEAF(_dl_start) /* Not really LEAF, but we simplify */
- addu sp, -16 # Some space.
+ addu sp, -64 # Some space.
.cprestore 12
la a1, 1f
bgezal zero, 1f
1:
- subu a1, ra
- addu a0, sp, 16 # Get stack pointer.
+ subu s0, ra, a1 # This is the load offset
+ addu a0, sp, 64 # Where stack info is.
+ addu a1, sp, 16 # Where fast AUX info will be.
+ la t9, _dl_boot_bind
+ addu t9, s0
+ jalr t9 # Relocate ourself.
+
+ lw a3, 64(sp) # argc
+ addu a0, sp, 68 # argv
+ addi a1, a0, 4
+ sll a3, a3, 2
+ addu a1, a3
+ addu a3, sp, 16 # Where fast AUX info will be.
+ move a2, s0 # Load offset
jal _dl_boot # Go do the linking.
- addu sp, 16 # Restore stack pointer.
+ addu sp, 64 # Restore stack pointer.
move t9, v0 # Entry address from _dl_boot.
j t9 # Go execute the 'real' program.
-
-
END(_dl_start)
+LEAF(_dl__syscall)
+ li v0, 0 # Indirect syscall.
+ bne a3, zero, 1f
+ j ra
+1:
+ li v0, -1
+ j ra
+END(_dl__syscall)
.globl _dl_rt_resolve
.ent _dl_rt_resolve, 0
_dl_rt_resolve:
+/* XXX Fix when lazy binding works */
.end _dl_rt_resolve
diff --git a/libexec/ld.so/mips/rtld_machine.c b/libexec/ld.so/mips/rtld_machine.c
index 19865eb154d..fd8b178bd2e 100644
--- a/libexec/ld.so/mips/rtld_machine.c
+++ b/libexec/ld.so/mips/rtld_machine.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: rtld_machine.c,v 1.6 2002/07/07 08:54:50 jufi Exp $ */
+/* $OpenBSD: rtld_machine.c,v 1.7 2002/10/23 12:38:29 pefo Exp $ */
/*
- * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
+ * Copyright (c) 1998-2002 Opsycon AB, Sweden.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -13,8 +13,7 @@
* 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.
+ * This product includes software developed by 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.
*
@@ -59,9 +58,10 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz)
for (i = 0; i < numrel; i++, relocs++) {
Elf32_Addr r_addr = relocs->r_offset + loff;
- Elf32_Addr ooff;
+ Elf32_Addr ooff = 0;
const Elf32_Sym *sym, *this;
const char *symn;
+ int type;
if (ELF32_R_SYM(relocs->r_info) == 0xffffff)
continue;
@@ -70,11 +70,14 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz)
sym += ELF32_R_SYM(relocs->r_info);
this = sym;
symn = object->dyn.strtab + sym->st_name;
+ type = ELF32_R_TYPE(relocs->r_info);
if (ELF32_R_SYM(relocs->r_info) &&
!(ELF32_ST_BIND(sym->st_info) == STB_LOCAL &&
ELF32_ST_TYPE (sym->st_info) == STT_NOTYPE)) {
- ooff = _dl_find_symbol(symn, _dl_objects, &this, 0, 1);
+ ooff = _dl_find_symbol(symn, _dl_objects, &this,
+ SYM_SEARCH_ALL | SYM_NOWARNNOTFOUND | SYM_PLT,
+ sym->st_size);
if (!this && ELF32_ST_BIND(sym->st_info) == STB_GLOBAL) {
_dl_printf("%s: can't resolve reference '%s'\n",
_dl_progname, symn);
@@ -88,9 +91,10 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz)
if (ELF32_ST_BIND(sym->st_info) == STB_LOCAL &&
(ELF32_ST_TYPE(sym->st_info) == STT_SECTION ||
ELF32_ST_TYPE(sym->st_info) == STT_NOTYPE) ) {
- *(u_int32_t *)r_addr += loff;
- } else if (this)
+ *(u_int32_t *)r_addr += loff + sym->st_value;
+ } else if (this) {
*(u_int32_t *)r_addr += this->st_value + ooff;
+ }
break;
case R_MIPS_NONE:
@@ -126,15 +130,15 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
const Elf32_Sym *this;
const char *strt;
+ if (object->status & STAT_GOT_DONE)
+ return;
+
lazy = 0; /* XXX Fix ld before enabling lazy */
loff = object->load_offs;
strt = object->dyn.strtab;
gotp = object->dyn.pltgot;
n = object->Dyn.info[DT_MIPS_LOCAL_GOTNO - DT_LOPROC + DT_NUM];
- if (object->status & STAT_GOT_DONE)
- return;
-
/*
* Set up pointers for run time (lazy) resolving.
*/
@@ -143,9 +147,7 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
gotp[1] = (int)object | 0x80000000;
}
- /*
- * First do all local references.
- */
+ /* First do all local references. */
for (i = ((gotp[1] & 0x80000000) ? 2 : 1); i < n; i++) {
gotp[i] += loff;
}
@@ -164,11 +166,12 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
while (n--) {
if (symp->st_shndx == SHN_UNDEF &&
ELF32_ST_TYPE(symp->st_info) == STT_FUNC) {
-_dl_printf("undef: %s = %X\n", strt + symp->st_name, symp->st_value);
if (symp->st_value == 0 || !lazy) {
this = 0;
ooff = _dl_find_symbol(strt + symp->st_name,
- _dl_objects, &this, 0, 1);
+ _dl_objects, &this,
+ SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND|SYM_PLT,
+ symp->st_size);
if (this)
*gotp = this->st_value + ooff;
} else
@@ -177,7 +180,9 @@ _dl_printf("undef: %s = %X\n", strt + symp->st_name, symp->st_value);
symp->st_shndx == SHN_UNDEF) {
this = 0;
ooff = _dl_find_symbol(strt + symp->st_name,
- _dl_objects, &this, 0, 1);
+ _dl_objects, &this,
+ SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND|SYM_PLT,
+ symp->st_size);
if (this)
*gotp = this->st_value + ooff;
} else if (ELF32_ST_TYPE(symp->st_info) == STT_FUNC) {
diff --git a/libexec/ld.so/mips/syscall.h b/libexec/ld.so/mips/syscall.h
index 46b6ce28706..59252c9a82f 100644
--- a/libexec/ld.so/mips/syscall.h
+++ b/libexec/ld.so/mips/syscall.h
@@ -1,7 +1,7 @@
-/* $OpenBSD: syscall.h,v 1.9 2002/07/24 04:11:10 deraadt Exp $ */
+/* $OpenBSD: syscall.h,v 1.10 2002/10/23 12:38:29 pefo Exp $ */
/*
- * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
+ * Copyright (c) 1998-2002 Opsycon AB, Sweden.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -13,8 +13,7 @@
* 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.
+ * This product includes software developed by 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.
*
@@ -38,6 +37,8 @@
#include <sys/syscall.h>
+extern long _dl__syscall(quad_t val, ...);
+
#ifndef _dl_MAX_ERRNO
#define _dl_MAX_ERRNO 4096
#endif
@@ -54,7 +55,9 @@ _dl_exit (int status)
{
register int __status __asm__ ("$2");
- __asm__ volatile ("move $4,%2\n\t"
+ __asm__ volatile (
+ "move $2,%1\n\t"
+ "move $4,%2\n\t"
"syscall"
: "=r" (__status)
: "0" (SYS_exit), "r" (status)
@@ -69,7 +72,9 @@ _dl_open (const char* addr, int flags)
{
register int status __asm__ ("$2");
- __asm__ volatile ("move $4,%2\n\t"
+ __asm__ volatile (
+ "move $2,%1\n\t"
+ "move $4,%2\n\t"
"move $5,%3\n\t"
"syscall\n\t"
"beq $7,$0,1f\n\t"
@@ -87,7 +92,9 @@ _dl_close (int fd)
{
register int status __asm__ ("$2");
- __asm__ volatile ("move $4,%2\n\t"
+ __asm__ volatile (
+ "move $2,%1\n\t"
+ "move $4,%2\n\t"
"syscall\n\t"
"beq $7,$0,1f\n\t"
"li $2,-1\n\t"
@@ -104,7 +111,9 @@ _dl_write (int fd, const char* buf, size_t len)
{
register ssize_t status __asm__ ("$2");
- __asm__ volatile ("move $4,%2\n\t"
+ __asm__ volatile (
+ "move $2,%1\n\t"
+ "move $4,%2\n\t"
"move $5,%3\n\t"
"move $6,%4\n\t"
"syscall\n\t"
@@ -123,7 +132,9 @@ _dl_read (int fd, const char* buf, size_t len)
{
register ssize_t status __asm__ ("$2");
- __asm__ volatile ("move $4,%2\n\t"
+ __asm__ volatile (
+ "move $2,%1\n\t"
+ "move $4,%2\n\t"
"move $5,%3\n\t"
"move $6,%4\n\t"
"syscall\n\t"
@@ -142,12 +153,14 @@ _dl_mmap (void *addr, size_t size, int prot, int flags, int fd, off_t f_offset)
{
register void * malloc_buffer __asm__ ("$2");
- __asm__ volatile ("addiu $29,-40\n\t"
+ __asm__ volatile (
+ "move $2,%1\n\t"
+ "addiu $29,-40\n\t"
"move $6,%2\n\t"
"move $7,%3\n\t"
"sw %4,16($29)\n\t"
"sw %5,20($29)\n\t"
-#ifdef MIPSEL
+#ifdef __MIPSEL__
"li $4,197\n\t"
"li $5,0\n\t"
"sw %6,24($29)\n\t"
@@ -155,7 +168,7 @@ _dl_mmap (void *addr, size_t size, int prot, int flags, int fd, off_t f_offset)
"sw %7,32($29)\n\t"
"sw $0,36($29)\n\t"
#endif
-#ifdef MIPSEB
+#ifdef __MIPSEB__
"li $4,0\n\t"
"li $5,197\n\t"
"sw %6,24($29)\n\t"
@@ -178,7 +191,9 @@ _dl_munmap (const void* addr, size_t len)
{
register int status __asm__ ("$2");
- __asm__ volatile ("move $4,%2\n\t"
+ __asm__ volatile (
+ "move $2,%1\n\t"
+ "move $4,%2\n\t"
"move $5,%3\n\t"
"syscall\n\t"
"beq $7,$0,1f\n\t"
@@ -196,7 +211,9 @@ _dl_mprotect (const void *addr, size_t size, int prot)
{
register int status __asm__ ("$2");
- __asm__ volatile ("move $4,%2\n\t"
+ __asm__ volatile (
+ "move $2,%1\n\t"
+ "move $4,%2\n\t"
"move $5,%3\n\t"
"move $6,%4\n\t"
"syscall"
@@ -212,7 +229,9 @@ _dl_stat (const char *addr, struct stat *sb)
{
register int status __asm__ ("$2");
- __asm__ volatile ("move $4,%2\n\t"
+ __asm__ volatile (
+ "move $2,%1\n\t"
+ "move $4,%2\n\t"
"move $5,%3\n\t"
"syscall"
: "=r" (status)
@@ -222,32 +241,83 @@ _dl_stat (const char *addr, struct stat *sb)
return status;
}
-/*
- * Not an actual syscall, but we need something in assembly to say
- * whether this is OK or not.
- */
extern inline int
-_dl_suid_ok (void)
+_dl_fstat (const int fd, struct stat *sb)
{
- unsigned int uid, euid, gid, egid;
+ register int status __asm__ ("$2");
- __asm__ volatile ("move $2,%1; syscall; move %0,$2"
- : "=r" (uid) : "r" (SYS_getuid)
+ __asm__ volatile (
+ "move $2,%1\n\t"
+ "move $4,%2\n\t"
+ "move $5,%3\n\t"
+ "syscall"
+ : "=r" (status)
+ : "0" (SYS_fstat), "r" (fd), "r" (sb)
: "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9",
"$10","$11","$12","$13","$14","$15","$24","$25");
- __asm__ volatile ("move $2,%1; syscall; move %0,$2"
- : "=r" (euid) : "r" (SYS_geteuid)
+ return status;
+}
+
+extern inline ssize_t
+_dl_fcntl (int fd, int cmd, int flag)
+{
+ register int status __asm__ ("$2");
+
+ __asm__ volatile (
+ "move $2,%1\n\t"
+ "move $4,%2\n\t"
+ "move $5,%3\n\t"
+ "move $6,%4\n\t"
+ "syscall\n\t"
+ "beq $7,$0,1f\n\t"
+ "li $2,-1\n\t"
+ "1:"
+ : "=r" (status)
+ : "0" (SYS_fcntl), "r" (fd), "r" (cmd), "r" (flag)
: "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9",
"$10","$11","$12","$13","$14","$15","$24","$25");
- __asm__ volatile ("move $2,%1; syscall; move %0,$2"
- : "=r" (gid) : "r" (SYS_getgid)
+ return status;
+}
+
+extern inline ssize_t
+_dl_getdirentries (int fd, char *buf, int nbytes, long *basep)
+{
+ register int status __asm__ ("$2");
+
+ __asm__ volatile ("move $2,%1\n\t"
+ "move $4,%2\n\t"
+ "move $5,%3\n\t"
+ "move $6,%4\n\t"
+ "move $7,%5\n\t"
+ "syscall\n\t"
+ "beq $7,$0,1f\n\t"
+ "li $2,-1\n\t"
+ "1:"
+ : "=r" (status)
+ : "0" (SYS_getdirentries), "r" (fd), "r" (buf), "r" (nbytes), "r" (basep)
: "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9",
"$10","$11","$12","$13","$14","$15","$24","$25");
- __asm__ volatile ("move $2,%1; syscall; move %0,$2"
- : "=r" (egid) : "r" (SYS_getegid)
+ return status;
+}
+
+extern inline int
+_dl_issetugid (void)
+{
+ register int status __asm__ ("$2");
+
+ __asm__ volatile (
+ "move $2,%1\n\t"
+ "syscall"
+ : "=r" (status)
+ : "0" (SYS_issetugid)
: "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9",
"$10","$11","$12","$13","$14","$15","$24","$25");
+ return status;
+}
- return (uid == euid && gid == egid);
+extern inline off_t
+_dl_lseek (int fd, off_t offset, int whence)
+{
+ return _dl__syscall((quad_t)SYS_lseek, fd, 0, offset, whence);
}
#endif /*__DL_SYSCALL_H__*/