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",

Reply via email to