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 <[email protected]>
@@ -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",