diff options
| author | skrll <skrll@NetBSD.org> | 2011-03-31 15:30:31 +0000 |
|---|---|---|
| committer | skrll <skrll@NetBSD.org> | 2011-03-31 15:30:31 +0000 |
| commit | c22912f2bf9e9fa16e3e8e887dd53852f5e15560 (patch) | |
| tree | e284e7eb37ca6e7a24c509eaf6b8499e3d64fb71 /libexec | |
| parent | 630b42ec4b9623a558e9e722ef67ede494e95354 (diff) | |
Enable TLS for alpha - a 2nd class^Wtier system in pookaBSD^WNetBSD
alpha_reloc.c diff from joerg on port-alpha.
Diffstat (limited to 'libexec')
| -rw-r--r-- | libexec/ld.elf_so/arch/alpha/alpha_reloc.c | 63 |
1 files changed, 61 insertions, 2 deletions
diff --git a/libexec/ld.elf_so/arch/alpha/alpha_reloc.c b/libexec/ld.elf_so/arch/alpha/alpha_reloc.c index dbd29e35934..713eb8191c6 100644 --- a/libexec/ld.elf_so/arch/alpha/alpha_reloc.c +++ b/libexec/ld.elf_so/arch/alpha/alpha_reloc.c @@ -1,4 +1,4 @@ -/* $NetBSD: alpha_reloc.c,v 1.39 2011/03/25 18:07:04 joerg Exp $ */ +/* $NetBSD: alpha_reloc.c,v 1.40 2011/03/31 15:30:31 skrll Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -62,10 +62,11 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: alpha_reloc.c,v 1.39 2011/03/25 18:07:04 joerg Exp $"); +__RCSID("$NetBSD: alpha_reloc.c,v 1.40 2011/03/31 15:30:31 skrll Exp $"); #endif /* not lint */ #include <sys/types.h> +#include <sys/tls.h> #include <string.h> #include "rtld.h" @@ -261,6 +262,64 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj) rdbg(("COPY (avoid in main)")); break; + case R_TYPE(TPREL64): + def = _rtld_find_symdef(symnum, obj, &defobj, false); + if (def == NULL) + return -1; + + if (!defobj->tls_done && + _rtld_tls_offset_allocate(obj)) + return -1; + + tmp = (Elf64_Addr)(def->st_value + + sizeof(struct tls_tcb) + defobj->tlsoffset + + rela->r_addend); + + if (__predict_true(RELOC_ALIGNED_P(where))) + *where = tmp; + else + store_ptr(where, tmp); + + rdbg(("TPREL64 %s in %s --> %p", + obj->strtab + obj->symtab[symnum].st_name, + obj->path, (void *)*where)); + + break; + + case R_TYPE(DTPMOD64): + def = _rtld_find_symdef(symnum, obj, &defobj, false); + if (def == NULL) + return -1; + + tmp = (Elf64_Addr)defobj->tlsindex; + if (__predict_true(RELOC_ALIGNED_P(where))) + *where = tmp; + else + store_ptr(where, tmp); + + rdbg(("DTPMOD64 %s in %s --> %p", + obj->strtab + obj->symtab[symnum].st_name, + obj->path, (void *)*where)); + + break; + + case R_TYPE(DTPREL64): + def = _rtld_find_symdef(symnum, obj, &defobj, false); + if (def == NULL) + return -1; + + tmp = (Elf64_Addr)(def->st_value + rela->r_addend); + if (__predict_true(RELOC_ALIGNED_P(where))) + *where = tmp; + else + store_ptr(where, tmp); + + rdbg(("DTPREL64 %s in %s --> %p", + obj->strtab + obj->symtab[symnum].st_name, + obj->path, (void *)*where)); + + break; + default: rdbg(("sym = %lu, type = %lu, offset = %p, " "addend = %p, contents = %p, symbol = %s", |
