Module Name: src Committed By: matt Date: Tue Mar 15 07:40:53 UTC 2011
Modified Files: src/libexec/ld.elf_so/arch/mips: mips_reloc.c Log Message: Add support for the MIPS TLS reloc types in shared libraries. To generate a diff of this commit: cvs rdiff -u -r1.60 -r1.61 src/libexec/ld.elf_so/arch/mips/mips_reloc.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/libexec/ld.elf_so/arch/mips/mips_reloc.c diff -u src/libexec/ld.elf_so/arch/mips/mips_reloc.c:1.60 src/libexec/ld.elf_so/arch/mips/mips_reloc.c:1.61 --- src/libexec/ld.elf_so/arch/mips/mips_reloc.c:1.60 Fri Sep 24 15:20:52 2010 +++ src/libexec/ld.elf_so/arch/mips/mips_reloc.c Tue Mar 15 07:40:52 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: mips_reloc.c,v 1.60 2010/09/24 15:20:52 matt Exp $ */ +/* $NetBSD: mips_reloc.c,v 1.61 2011/03/15 07:40:52 matt Exp $ */ /* * Copyright 1997 Michael L. Hitch <mhi...@montana.edu> @@ -30,11 +30,12 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: mips_reloc.c,v 1.60 2010/09/24 15:20:52 matt Exp $"); +__RCSID("$NetBSD: mips_reloc.c,v 1.61 2011/03/15 07:40:52 matt Exp $"); #endif /* not lint */ #include <sys/types.h> #include <sys/endian.h> +#include <sys/tls.h> #include <stdlib.h> #include <string.h> @@ -375,6 +376,79 @@ break; } +#if ELFSIZE == 64 + case R_TYPE(TLS_DTPMOD64): +#else + case R_TYPE(TLS_DTPMOD32): +#endif + { + Elf_Addr old = load_ptr(where, ELFSIZE / 8); + Elf_Addr val = old; + + def = _rtld_find_symdef(r_symndx, obj, &defobj, false); + if (def == NULL) + return -1; + + val += (Elf_Addr)defobj->tlsindex; + + store_ptr(where, val, ELFSIZE / 8); + rdbg(("DTPMOD %s in %s --> %p in %s", + obj->strtab + obj->symtab[r_symndx].st_name, + obj->path, (void *)old, defobj->path)); + break; + } + +#if ELFSIZE == 64 + case R_TYPE(TLS_DTPREL64): +#else + case R_TYPE(TLS_DTPREL32): +#endif + { + Elf_Addr old = load_ptr(where, ELFSIZE / 8); + Elf_Addr val = old; + + def = _rtld_find_symdef(r_symndx, obj, &defobj, false); + if (def == NULL) + return -1; + + if (!defobj->tls_done && _rtld_tls_offset_allocate(obj)) + return -1; + + val += (Elf_Addr)def->st_value - TLS_DTV_OFFSET; + store_ptr(where, val, ELFSIZE / 8); + + rdbg(("DTPREL %s in %s --> %p in %s", + obj->strtab + obj->symtab[r_symndx].st_name, + obj->path, (void *)old, defobj->path)); + break; + } + +#if ELFSIZE == 64 + case R_TYPE(TLS_TPREL64): +#else + case R_TYPE(TLS_TPREL32): +#endif + { + Elf_Addr old = load_ptr(where, ELFSIZE / 8); + Elf_Addr val = old; + + def = _rtld_find_symdef(r_symndx, obj, &defobj, false); + if (def == NULL) + return -1; + + if (!defobj->tls_done && _rtld_tls_offset_allocate(obj)) + return -1; + + val += (Elf_Addr)(def->st_value + defobj->tlsoffset + - TLS_TP_OFFSET); + store_ptr(where, val, ELFSIZE / 8); + + rdbg(("TPREL %s in %s --> %p in %s", + obj->strtab + obj->symtab[r_symndx].st_name, + obj->path, (void *)*where, defobj->path)); + break; + } + default: rdbg(("sym = %lu, type = %lu, offset = %p, " "contents = %p, symbol = %s",