diff options
author | Per Fogelstrom <pefo@cvs.openbsd.org> | 2002-10-23 12:38:30 +0000 |
---|---|---|
committer | Per Fogelstrom <pefo@cvs.openbsd.org> | 2002-10-23 12:38:30 +0000 |
commit | db0dfc1e5e65b8f62e7ee1c09359956563d37ec3 (patch) | |
tree | d425f8772f69efaa117ec5b738e45de077e76777 | |
parent | 45e5a93b6f8946f30d58f6e53d1c6ab1d84c4b62 (diff) |
mips archdep stuff update while waiting for ok on mi
-rw-r--r-- | libexec/ld.so/mips/Makefile.inc | 5 | ||||
-rw-r--r-- | libexec/ld.so/mips/archdep.h | 61 | ||||
-rw-r--r-- | libexec/ld.so/mips/ldasm.S | 47 | ||||
-rw-r--r-- | libexec/ld.so/mips/rtld_machine.c | 39 | ||||
-rw-r--r-- | libexec/ld.so/mips/syscall.h | 130 |
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__*/ |