summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpefo <pefo@openbsd.org>2004-09-21 08:40:45 +0000
committerpefo <pefo@openbsd.org>2004-09-21 08:40:45 +0000
commitdceadf5515b5152d68cb7d6f4b9567d696348626 (patch)
tree08b781d353e764b56922c9f174e1ac3965fc5055
parentMake RM7K get L3 cache from config reg. cleanup (diff)
downloadwireguard-openbsd-dceadf5515b5152d68cb7d6f4b9567d696348626.tar.xz
wireguard-openbsd-dceadf5515b5152d68cb7d6f4b9567d696348626.zip
ELF64 and got ro prot
-rw-r--r--libexec/ld.so/mips64/archdep.h21
-rw-r--r--libexec/ld.so/mips64/ldasm.S7
-rw-r--r--libexec/ld.so/mips64/rtld_machine.c60
3 files changed, 41 insertions, 47 deletions
diff --git a/libexec/ld.so/mips64/archdep.h b/libexec/ld.so/mips64/archdep.h
index dd5b113d4ae..8700f711a0f 100644
--- a/libexec/ld.so/mips64/archdep.h
+++ b/libexec/ld.so/mips64/archdep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: archdep.h,v 1.2 2004/09/09 17:47:43 pefo Exp $ */
+/* $OpenBSD: archdep.h,v 1.3 2004/09/21 08:40:45 pefo Exp $ */
/*
* Copyright (c) 1998-2002 Opsycon AB, Sweden.
@@ -35,19 +35,13 @@
#include "resolve.h"
#include "util.h"
-#define RTLD_PROTECT_PLT
-
-#define DL_MALLOC_ALIGN 16 /* Arch constraint or otherwise */
+#define DL_MALLOC_ALIGN 8 /* Arch constraint or otherwise */
#define MACHID EM_MIPS /* ELF e_machine ID value checked */
-//static inline void
-//RELOC_REL(Elf_Rel *r, const Elf_Sym *s, Elf_Addr *p, unsigned long v)
-//{
-//}
#define RELOC_REL(relp, symp, adrp, val) \
do { \
- if (ELF64_R_TYPE(relp->r_info) == R_MIPS_REL32_64) { \
+ if (ELF64_R_TYPE(relp->r_info) == R_MIPS_REL32_64) { \
if (ELF64_R_SYM(rp->r_info) != 0) \
*adrp = symp->st_value + val; \
else \
@@ -57,11 +51,10 @@ do { \
} \
} while (0)
-static inline void
-RELOC_RELA(Elf64_Rela *r, const Elf64_Sym *s, Elf64_Addr *p, unsigned long v)
-{
- _dl_exit(20);
-}
+#define RELOC_RELA(rela, sym, ptr, val) \
+do { \
+ _dl_exit(20); /* We don't do RELA now */ \
+} while(0)
struct elf_object;
diff --git a/libexec/ld.so/mips64/ldasm.S b/libexec/ld.so/mips64/ldasm.S
index d6d7319aeb5..148b24ade06 100644
--- a/libexec/ld.so/mips64/ldasm.S
+++ b/libexec/ld.so/mips64/ldasm.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldasm.S,v 1.2 2004/09/09 17:47:43 pefo Exp $ */
+/* $OpenBSD: ldasm.S,v 1.3 2004/09/21 08:40:45 pefo Exp $ */
/*
* Copyright (c) 1998-2002 Opsycon AB, Sweden.
@@ -53,10 +53,13 @@ LEAF(_dl_start, FRAMESZ) /* Not really LEAF, but we simplify */
# This is a hack to change protection of .rodata so it
# can be relocated. A better way to find the location
# of .rodata should probably be used.
+ # We know that .rodata is aligned on 0x100000 and is at
+ # most 64 k in size.
li v0, SYS_mprotect
or a0, ra, 0xfff
xor a0, 0xfff
- li a1, 0x8000
+ PTR_ADDU a0, 0x10000
+ li a1, 0x10000
li a2, 7 /* (PROT_READ|PROT_WRITE|PROT_EXEC) */
syscall
diff --git a/libexec/ld.so/mips64/rtld_machine.c b/libexec/ld.so/mips64/rtld_machine.c
index 96754eb326a..99d838a9e60 100644
--- a/libexec/ld.so/mips64/rtld_machine.c
+++ b/libexec/ld.so/mips64/rtld_machine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtld_machine.c,v 1.2 2004/09/09 17:47:43 pefo Exp $ */
+/* $OpenBSD: rtld_machine.c,v 1.3 2004/09/21 08:40:45 pefo Exp $ */
/*
* Copyright (c) 1998-2004 Opsycon AB, Sweden.
@@ -44,7 +44,10 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz)
int fails = 0;
struct load_list *load_list;
Elf64_Addr loff;
+ Elf64_Addr ooff;
+ Elf64_Addr got_start, got_end;
Elf64_Rel *relocs;
+ const Elf64_Sym *sym, *this;
loff = object->load_offs;
numrel = object->Dyn.info[relsz] / sizeof(Elf64_Rel);
@@ -66,18 +69,32 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz)
load_list = load_list->next;
}
+ /* XXX We need the got limits to know if reloc is in got. */
+ /* XXX Relocs against the got should not include the STUB address! */
+ this = NULL;
+ got_start = 0;
+ got_end = 0;
+ ooff = _dl_find_symbol("__got_start", object, &this, NULL,
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object);
+ if (this != NULL)
+ got_start = ooff + this->st_value;
+
+ this = NULL;
+ ooff = _dl_find_symbol("__got_end", object, &this, NULL,
+ SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object);
+ if (this != NULL)
+ got_end = ooff + this->st_value;
DL_DEB(("relocating %d\n", numrel));
for (i = 0; i < numrel; i++, relocs++) {
Elf64_Addr r_addr = relocs->r_offset + loff;
- Elf64_Addr ooff = 0;
- const Elf64_Sym *sym, *this;
const char *symn;
int type;
if (ELF64_R_SYM(relocs->r_info) == 0xffffff)
continue;
+ ooff = 0;
sym = object->dyn.symtab;
sym += ELF64_R_SYM(relocs->r_info);
this = sym;
@@ -104,16 +121,15 @@ _dl_md_reloc(elf_object_t *object, int rel, int relsz)
(ELF64_ST_TYPE(sym->st_info) == STT_SECTION ||
ELF64_ST_TYPE(sym->st_info) == STT_NOTYPE) ) {
*(u_int64_t *)r_addr += loff + sym->st_value;
- } else if (this) {
+ } else if (this && ((long)r_addr & 7)) {
/* XXX Handle non aligned relocs. .eh_frame
* XXX in libstdc++ seems to have them... */
- if (((long)r_addr & 7)) {
- u_int64_t robj;
- _dl_bcopy((char *)r_addr, &robj, sizeof(robj));
- robj += this->st_value + ooff;
- _dl_bcopy(&robj, (char *)r_addr, sizeof(robj));
- } else
- *(u_int64_t *)r_addr += this->st_value + ooff;
+ u_int64_t robj;
+ _dl_bcopy((char *)r_addr, &robj, sizeof(robj));
+ robj += this->st_value + ooff;
+ _dl_bcopy(&robj, (char *)r_addr, sizeof(robj));
+ } else if (this) {
+ *(u_int64_t *)r_addr += this->st_value + ooff;
}
break;
@@ -153,7 +169,6 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
Elf64_Addr loff;
Elf64_Addr ooff;
Elf64_Addr *gotp;
- Elf64_Addr plt_addr;
const Elf64_Sym *symp;
const Elf64_Sym *this;
const char *strt;
@@ -179,7 +194,6 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
/* First do all local references. */
for (i = ((gotp[1] & 0x0000000080000000) ? 2 : 1); i < n; i++) {
gotp[i] += loff;
- DL_DEB(("got: '%p' = %x\n", &gotp[i], gotp[i]));
}
gotp += n;
@@ -189,7 +203,6 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
n = object->Dyn.info[DT_MIPS_SYMTABNO - DT_LOPROC + DT_NUM] -
object->Dyn.info[DT_MIPS_GOTSYM - DT_LOPROC + DT_NUM];
- plt_addr = 0;
this = NULL;
object->plt_size = 0;
object->got_size = 0;
@@ -202,19 +215,7 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
ooff = _dl_find_symbol("__got_end", object, &this, NULL,
SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object);
if (this != NULL)
- object->got_size = ooff + this->st_value - object->got_addr;
-
- this = NULL;
- ooff = _dl_find_symbol("__plt_start", object, &this, NULL,
- SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object);
- if (this != NULL)
- object->plt_start = ooff + this->st_value;
-
- this = NULL;
- ooff = _dl_find_symbol("__plt_end", object, &this, NULL,
- SYM_SEARCH_SELF|SYM_NOWARNNOTFOUND|SYM_PLT, 0, object);
- if (this != NULL)
- object->plt_size = ooff + this->st_value - plt_addr;
+ object->got_size = ooff + this->st_value - object->got_start;
/*
* Then do all global references according to the ABI.
@@ -223,7 +224,6 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
while (n--) {
if (symp->st_shndx == SHN_UNDEF &&
ELF64_ST_TYPE(symp->st_info) == STT_FUNC) {
- DL_DEB(("got: '%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,
@@ -253,10 +253,8 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
}
object->status |= STAT_GOT_DONE;
+ DL_DEB(("got: %x, %x\n", object->got_start, object->got_size));
if (object->got_size != 0)
_dl_mprotect((void*)object->got_start, object->got_size,
PROT_READ);
- if (object->plt_size != 0)
- _dl_mprotect((void*)object->plt_start, object->plt_size,
- PROT_READ|PROT_EXEC);
}