diff options
author | 2004-09-21 08:40:45 +0000 | |
---|---|---|
committer | 2004-09-21 08:40:45 +0000 | |
commit | dceadf5515b5152d68cb7d6f4b9567d696348626 (patch) | |
tree | 08b781d353e764b56922c9f174e1ac3965fc5055 | |
parent | Make RM7K get L3 cache from config reg. cleanup (diff) | |
download | wireguard-openbsd-dceadf5515b5152d68cb7d6f4b9567d696348626.tar.xz wireguard-openbsd-dceadf5515b5152d68cb7d6f4b9567d696348626.zip |
ELF64 and got ro prot
-rw-r--r-- | libexec/ld.so/mips64/archdep.h | 21 | ||||
-rw-r--r-- | libexec/ld.so/mips64/ldasm.S | 7 | ||||
-rw-r--r-- | libexec/ld.so/mips64/rtld_machine.c | 60 |
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); } |