diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2002-07-29 15:20:39 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2002-07-29 15:20:39 +0000 |
commit | 16dacd1ad611f98bca67fc5e5ef16dce99346f17 (patch) | |
tree | befbcc7f83c8c2a73aa07328be17b9956ac87476 /libexec | |
parent | 980731f68574e02d9d3952d76805b1ada65d7085 (diff) |
Bunch of cleanups and one last bugfix that seems to make things work.
Mark COPY relocations as needing to resolve the destination symbol.
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/ld.so/sparc/ldasm.S | 4 | ||||
-rw-r--r-- | libexec/ld.so/sparc/rtld_machine.c | 98 |
2 files changed, 51 insertions, 51 deletions
diff --git a/libexec/ld.so/sparc/ldasm.S b/libexec/ld.so/sparc/ldasm.S index f85465667e3..a003cee0025 100644 --- a/libexec/ld.so/sparc/ldasm.S +++ b/libexec/ld.so/sparc/ldasm.S @@ -1,4 +1,4 @@ -/* $OpenBSD: ldasm.S,v 1.3 2002/07/27 15:35:55 art Exp $ */ +/* $OpenBSD: ldasm.S,v 1.4 2002/07/29 15:20:38 art Exp $ */ /* * Copyright (c) 2001 Jason L. Wright (jason@thought.net) @@ -104,7 +104,7 @@ _dl_start: call _dl_boot ! _dl_boot(argv,envp,loff,dynp,dl_data) mov 0, %o3 ! dynp = 0 - add %sp, DL_DATA_SIZE, %sp ! restore stack + add %sp, DL_DATA_SIZE, %sp ! restore stack jmp %o0 mov %l1, %g1 ! restore ps_strings diff --git a/libexec/ld.so/sparc/rtld_machine.c b/libexec/ld.so/sparc/rtld_machine.c index 2ff19519864..9c462341a23 100644 --- a/libexec/ld.so/sparc/rtld_machine.c +++ b/libexec/ld.so/sparc/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.2 2002/07/27 16:56:01 art Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.3 2002/07/29 15:20:38 art Exp $ */ /* * Copyright (c) 1999 Dale Rahn @@ -98,7 +98,7 @@ static int reloc_target_flags[] = { _RF_S|_RF_A|_RF_P| _RF_SZ(32) | _RF_RS(0), /* PC10 */ _RF_S|_RF_A|_RF_P| _RF_SZ(32) | _RF_RS(10), /* PC22 */ _RF_A|_RF_P| _RF_SZ(32) | _RF_RS(2), /* WPLT30 */ - _RF_SZ(32) | _RF_RS(0), /* COPY */ + _RF_S| _RF_SZ(32) | _RF_RS(0), /* COPY */ _RF_S|_RF_A| _RF_SZ(32) | _RF_RS(0), /* GLOB_DAT */ _RF_SZ(32) | _RF_RS(0), /* JMP_SLOT */ _RF_A| _RF_B| _RF_SZ(32) | _RF_RS(0), /* RELATIVE */ @@ -127,7 +127,6 @@ static int reloc_target_flags[] = { #define RELOC_RESOLVE_SYMBOL(t) ((reloc_target_flags[t] & _RF_S) != 0) #define RELOC_PC_RELATIVE(t) ((reloc_target_flags[t] & _RF_P) != 0) -#define RELOC_BASE_RELATIVE(t) ((reloc_target_flags[t] & _RF_B) != 0) #define RELOC_USE_ADDEND(t) ((reloc_target_flags[t] & _RF_A) != 0) #define RELOC_TARGET_SIZE(t) ((reloc_target_flags[t] >> 8) & 0xff) #define RELOC_VALUE_RIGHTSHIFT(t) (reloc_target_flags[t] & 0xff) @@ -157,7 +156,31 @@ static int reloc_target_bitmask[] = { }; #define RELOC_VALUE_BITMASK(t) (reloc_target_bitmask[t]) -void _dl_reloc_plt(Elf_Word *where, Elf_Addr value); +static inline void +_dl_reloc_plt(Elf_Addr *where, Elf_Addr value) +{ + /* + * At the PLT entry pointed at by `where', we now construct + * a direct transfer to the now fully resolved function + * address. The resulting code in the jump slot is: + * + * sethi %hi(roffset), %g1 + * sethi %hi(addr), %g1 + * jmp %g1+%lo(addr) + * + * We write the third instruction first, since that leaves the + * previous `b,a' at the second word in place. Hence the whole + * PLT slot can be atomically change to the new sequence by + * writing the `sethi' instruction at word 2. + */ +#define SETHI 0x03000000 +#define JMP 0x81c06000 +#define NOP 0x01000000 + where[2] = JMP | (value & 0x000003ff); + where[1] = SETHI | ((value >> 10) & 0x003fffff); + __asm __volatile("iflush %0+8" : : "r" (where)); + __asm __volatile("iflush %0+4" : : "r" (where)); +} int _dl_md_reloc(elf_object_t *object, int rel, int relasz) @@ -188,8 +211,8 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz) } for (i = 0; i < numrela; i++, relas++) { - Elf_Addr *where, value, ooff, mask; - Elf_Word type; + Elf_Addr *where, ooff; + Elf_Word type, value, mask; const Elf_Sym *sym, *this; const char *symn; @@ -203,6 +226,11 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz) where = (Elf_Addr *)(relas->r_offset + loff); + if (type == R_TYPE(RELATIVE)) { + *where += (Elf_Addr)(loff + relas->r_addend); + continue; + } + if (RELOC_USE_ADDEND(type)) value = relas->r_addend; else @@ -220,13 +248,14 @@ _dl_md_reloc(elf_object_t *object, int rel, int relasz) value += loff; } else { this = NULL; - ooff = _dl_find_symbol(symn, _dl_objects, - &this, 0, 1); + ooff = _dl_find_symbol(symn, + _dl_objects, &this, 0, 1); if (this == NULL) { resolve_failed: _dl_printf("%s: %s: can't resolve " "reference '%s'\n", - _dl_progname, object->load_name, + _dl_progname, + object->load_name, symn); fails++; continue; @@ -250,7 +279,7 @@ resolve_failed: } if (type == R_TYPE(JMP_SLOT)) { - _dl_reloc_plt((Elf_Word *)where, value); + _dl_reloc_plt(where, value); continue; } @@ -273,8 +302,6 @@ resolve_failed: if (RELOC_PC_RELATIVE(type)) value -= (Elf_Addr)where; - if (RELOC_BASE_RELATIVE(type)) - value += loff + *where; mask = RELOC_VALUE_BITMASK(type); value >>= RELOC_VALUE_RIGHTSHIFT(type); @@ -283,7 +310,6 @@ resolve_failed: /* We ignore alignment restrictions here */ *where &= ~mask; *where |= value; - } /* reprotect the unprotected segments */ @@ -298,42 +324,17 @@ resolve_failed: return (fails); } -void -_dl_reloc_plt(Elf_Word *where, Elf_Addr value) -{ - /* - * At the PLT entry pointed at by `where', we now construct - * a direct transfer to the now fully resolved function - * address. The resulting code in the jump slot is: - * - * sethi %hi(roffset), %g1 - * sethi %hi(addr), %g1 - * jmp %g1+%lo(addr) - * - * We write the third instruction first, since that leaves the - * previous `b,a' at the second word in place. Hence the whole - * PLT slot can be atomically change to the new sequence by - * writing the `sethi' instruction at word 2. - */ -#define SETHI 0x03000000 -#define JMP 0x81c06000 -#define NOP 0x01000000 - where[2] = JMP | (value & 0x000003ff); - where[1] = SETHI | ((value >> 10) & 0x003fffff); - __asm __volatile("iflush %0+8" : : "r" (where)); - __asm __volatile("iflush %0+4" : : "r" (where)); -} - /* * Resolve a symbol at run-time. */ -void * +Elf_Addr _dl_bind(elf_object_t *object, Elf_Word reloff) { - Elf_RelA *rela; - Elf_Addr *addr, ooff; const Elf_Sym *sym, *this; + Elf_Addr *addr, ooff; const char *symn; + Elf_Addr value; + Elf_RelA *rela; rela = (Elf_RelA *)(object->Dyn.info[DT_JMPREL] + reloff); @@ -341,8 +342,6 @@ _dl_bind(elf_object_t *object, Elf_Word reloff) sym += ELF_R_SYM(rela->r_info); symn = object->dyn.strtab + sym->st_name; -DL_DEB(("_dl_bind %s\n", symn)); - addr = (Elf_Addr *)(object->load_offs + rela->r_offset); ooff = _dl_find_symbol(symn, _dl_objects, &this, 0, 1); if (this == NULL) { @@ -350,9 +349,11 @@ DL_DEB(("_dl_bind %s\n", symn)); *((int *)0) = 0; /* XXX */ } - _dl_reloc_plt(addr, ooff + this->st_value); + value = ooff + this->st_value; + + _dl_reloc_plt(addr, value); - return (void *)ooff + this->st_value; + return (value); } void @@ -372,7 +373,7 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) * PLTGOT is the PLT on the sparc. * The first entry holds the call the dynamic linker. * We construct a `call' sequence that transfers - * to `_rtld_bind_start()'. + * to `_dl_bind_start()'. * The second entry holds the object identification. * Note: each PLT entry is three words long. */ @@ -381,8 +382,7 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) #define NOP 0x01000000 pltgot[0] = SAVE; pltgot[1] = CALL | - ((Elf_Addr)&_dl_bind_start - - (Elf_Addr)&pltgot[1]) >> 2; + ((Elf_Addr)&_dl_bind_start - (Elf_Addr)&pltgot[1]) >> 2; pltgot[2] = NOP; pltgot[3] = (Elf_Addr) object; } |