diff options
author | Dale Rahn <drahn@cvs.openbsd.org> | 2001-03-30 01:35:22 +0000 |
---|---|---|
committer | Dale Rahn <drahn@cvs.openbsd.org> | 2001-03-30 01:35:22 +0000 |
commit | 3cce29673e509737c9de72c84989642c9564e292 (patch) | |
tree | c26b82ebd9e02b5190b0f5ccfdb0da035f4611d7 /libexec/ld.so/powerpc | |
parent | 01237d63b727bd16f83cc6170dca9c942469a206 (diff) |
Add infrastructure to allow mapping of text sections which are normally
RO, RW while ld.so is working. And then the information to set the
sections back to RO (or appropriate mode).
PowerPC now supports the typical NON-PIC relocations in ld.so.
I do not know how well this will work with large shared libraries.
I seem to recall a possible problem with large data where data is
located in a different shared library.
Diffstat (limited to 'libexec/ld.so/powerpc')
-rw-r--r-- | libexec/ld.so/powerpc/rtld_machine.c | 83 |
1 files changed, 69 insertions, 14 deletions
diff --git a/libexec/ld.so/powerpc/rtld_machine.c b/libexec/ld.so/powerpc/rtld_machine.c index 299bfeae120..b044e0ce591 100644 --- a/libexec/ld.so/powerpc/rtld_machine.c +++ b/libexec/ld.so/powerpc/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.3 2000/10/06 17:39:30 rahnds Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.4 2001/03/30 01:35:21 drahn Exp $ */ /* * Copyright (c) 1999 Dale Rahn @@ -35,6 +35,7 @@ #define _DYN_LOADER #include <sys/types.h> +#include <sys/mman.h> #include <nlist.h> #include <link.h> @@ -61,6 +62,7 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz) int i; int numrela; int fails = 0; + load_list_t *load_list; Elf32_Addr loff; Elf32_Rela *relas; /* for jmp table relocations */ @@ -120,6 +122,19 @@ _dl_printf("md_reloc: plttable %x\n", plttable); first_rela = NULL; } + /* + * Change protection of all write protected segments in the object + * so we can do relocations such as REL24, REL16 etc. After + * relocation restore protection. + */ + load_list = object->load_list; + while(load_list != NULL) { + _dl_mprotect(load_list->start, load_list->size, + load_list->prot|PROT_WRITE); + load_list = load_list->next; + } + + for(i = 0; i < numrela; i++, relas++) { Elf32_Addr *r_addr = (Elf32_Addr *)(relas->r_offset + loff); Elf32_Addr ooff; @@ -246,26 +261,61 @@ _dl_printf(" ooff %x, sym val %x, addend %x" case RELOC_GLOB_DAT: *r_addr = ooff + this->st_value + relas->r_addend; break; -#ifdef DL_PRINTF_DEBUG +#if 1 /* should not be supported ??? */ case RELOC_REL24: - { + { Elf32_Addr val = ooff + this->st_value + relas->r_addend - (Elf32_Addr)r_addr; if ((val & 0xfe000000 != 0) && - (val & 0xfe000000 != 0xfe000000)) - { + (val & 0xfe000000 != 0xfe000000)) { /* invalid offset */ _dl_exit(20); } val &= ~0xfc000003; val |= (*r_addr & 0xfc000003); *r_addr = val; - + +_dl_dcbf(r_addr); + } + break; +#endif +#if 1 + case RELOC_16_LO: + { + Elf32_Addr val; + + val = loff + relas->r_addend; + *(Elf32_Half *)r_addr = val; + _dl_dcbf(r_addr); - } + } + break; #endif - break; +#if 1 + case RELOC_16_HI: + { + Elf32_Addr val; + + val = loff + relas->r_addend; + *(Elf32_Half *)r_addr = (val >> 16); + + _dl_dcbf(r_addr); + } + break; +#endif +#if 1 + case RELOC_16_HA: + { + Elf32_Addr val; + + val = loff + relas->r_addend; + *(Elf32_Half *)r_addr = ((val + 0x8000) >> 16); + + _dl_dcbf(r_addr); + } + break; +#endif case RELOC_REL14_TAKEN: /* val |= 1 << (31-10) XXX? */ case RELOC_REL14: @@ -350,6 +400,11 @@ _dl_printf(" found other symbol at %x size %d\n", } } object->status |= STAT_RELOC_DONE; + load_list = object->load_list; + while(load_list != NULL) { + _dl_mprotect(load_list->start, load_list->size, load_list->prot); + load_list = load_list->next; + } return(fails); } @@ -373,16 +428,16 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) void _dl_syncicache(char *from, size_t len) { - int l = len; unsigned int off = 0; + int l = len + ((int)from & (CACHELINESIZE-1)); - while (off < len) { - asm volatile ("dcbst %1,%0" :: "r"(from), "r"(off)); + while (off < l) { + asm volatile ("dcbst %1,%0" :: "r"(from), "r"(off)); asm volatile ("sync"); - asm volatile ("icbi 0,%0" :: "r"(from), "r"(off)); + asm volatile ("icbi %1, %0" :: "r"(from), "r"(off)); asm volatile ("sync"); asm volatile ("isync"); - off += CACHELINESIZE; - } + off += CACHELINESIZE; + } } |