svn commit: branches/uClibc-nptl/ldso/ldso/arm
kraj at uclibc.org
kraj at uclibc.org
Thu Jul 10 01:19:06 UTC 2008
Author: kraj
Date: 2008-07-09 18:19:04 -0700 (Wed, 09 Jul 2008)
New Revision: 22733
Log:
Handle ARM TLS relocations
Modified:
branches/uClibc-nptl/ldso/ldso/arm/dl-sysdep.h
branches/uClibc-nptl/ldso/ldso/arm/elfinterp.c
branches/uClibc-nptl/ldso/ldso/arm/resolve.S
Changeset:
Modified: branches/uClibc-nptl/ldso/ldso/arm/dl-sysdep.h
===================================================================
--- branches/uClibc-nptl/ldso/ldso/arm/dl-sysdep.h 2008-07-10 01:16:18 UTC (rev 22732)
+++ branches/uClibc-nptl/ldso/ldso/arm/dl-sysdep.h 2008-07-10 01:19:04 UTC (rev 22733)
@@ -5,6 +5,9 @@
* Copyright (C) 2000-2004 by Erik Andersen <andersen at codepoet.org>
*/
+#ifndef _ARCH_DL_SYSDEP
+#define _ARCH_DL_SYSDEP
+
/* Define this if the system uses RELOCA. */
#undef ELF_USES_RELOCA
#include <elf.h>
@@ -60,12 +63,16 @@
#define ADDR_ALIGN 0xfff
#define OFFS_ALIGN 0x7ffff000
-/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
- PLT entries should not be allowed to define the value.
+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
+ TLS variable, so undefined references should not be allowed to
+ define the value.
+
ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
of the main executable's symbols, as for a COPY reloc. */
-#define elf_machine_type_class(type) \
- ((((type) == R_ARM_JUMP_SLOT) * ELF_RTYPE_CLASS_PLT) \
+#define elf_machine_type_class(type) \
+ ((((type) == R_ARM_JUMP_SLOT || (type) == R_ARM_TLS_DTPMOD32 \
+ || (type) == R_ARM_TLS_DTPOFF32 || (type) == R_ARM_TLS_TPOFF32) \
+ * ELF_RTYPE_CLASS_PLT) \
| (((type) == R_ARM_COPY) * ELF_RTYPE_CLASS_COPY))
/* Return the link-time address of _DYNAMIC. Conveniently, this is the
@@ -140,3 +147,4 @@
*reloc_addr += load_off;
} while (--relative_count);
}
+#endif /* !_ARCH_DL_SYSDEP */
Modified: branches/uClibc-nptl/ldso/ldso/arm/elfinterp.c
===================================================================
--- branches/uClibc-nptl/ldso/ldso/arm/elfinterp.c 2008-07-10 01:16:18 UTC (rev 22732)
+++ branches/uClibc-nptl/ldso/ldso/arm/elfinterp.c 2008-07-10 01:19:04 UTC (rev 22733)
@@ -78,7 +78,7 @@
/* Get the address of the GOT entry */
new_addr = _dl_find_hash(symname, tpnt->symbol_scope,
- tpnt, ELF_RTYPE_CLASS_PLT);
+ tpnt, ELF_RTYPE_CLASS_PLT, NULL);
if (unlikely(!new_addr)) {
_dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
_dl_progname, symname);
@@ -196,28 +196,41 @@
int symtab_index;
unsigned long *reloc_addr;
unsigned long symbol_addr;
+ const Elf32_Sym *def = 0;
+ struct elf_resolve *def_mod = 0;
int goof = 0;
- reloc_addr = (unsigned long *) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);
+ reloc_addr = (unsigned long *) (tpnt->loadaddr
+ + (unsigned long) rpnt->r_offset);
+
reloc_type = ELF32_R_TYPE(rpnt->r_info);
symtab_index = ELF32_R_SYM(rpnt->r_info);
symbol_addr = 0;
if (symtab_index) {
+ def = _dl_find_hash(strtab + symtab[symtab_index].st_name,
+ scope, tpnt,
+ elf_machine_type_class(reloc_type),
+ &def_mod);
- symbol_addr = (unsigned long) _dl_find_hash(strtab + symtab[symtab_index].st_name,
- scope, tpnt, elf_machine_type_class(reloc_type));
-
+ if (def)
+ symbol_addr = def->st_value + def_mod->loadaddr;
/*
* We want to allow undefined references to weak symbols - this might
* have been intentional. We should not be linking local symbols
* here, so all bases should be covered.
*/
- if (!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK) {
- _dl_dprintf (2, "%s: can't resolve symbol '%s'\n",
- _dl_progname, strtab + symtab[symtab_index].st_name);
- _dl_exit (1);
+ else if (ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK) {
+ /* This may be non-fatal if called from dlopen. */
+ return 1;
+
}
+ } else {
+ /* Relocs against STN_UNDEF are usually treated as using a
+ symbol value of zero, and using the module containing the
+ reloc itself. */
+ def = &symtab[symtab_index];
+ def_mod = tpnt;
}
#if defined (__SUPPORT_LD_DEBUG__)
@@ -273,6 +286,20 @@
_dl_memcpy((void *) reloc_addr,
(void *) symbol_addr, symtab[symtab_index].st_size);
break;
+#if USE_TLS
+ case R_ARM_TLS_DTPMOD32:
+ *reloc_addr = def_mod->l_tls_modid;
+ break;
+
+ case R_ARM_TLS_DTPOFF32:
+ *reloc_addr += def->st_value;
+ break;
+
+ case R_ARM_TLS_TPOFF32:
+ CHECK_STATIC_TLS ((struct link_map *) def_mod);
+ *reloc_addr += (def->st_value + def_mod->l_tls_offset);
+ break;
+#endif
default:
return -1; /*call _dl_exit(1) */
}
Modified: branches/uClibc-nptl/ldso/ldso/arm/resolve.S
===================================================================
--- branches/uClibc-nptl/ldso/ldso/arm/resolve.S 2008-07-10 01:16:18 UTC (rev 22732)
+++ branches/uClibc-nptl/ldso/ldso/arm/resolve.S 2008-07-10 01:19:04 UTC (rev 22733)
@@ -95,6 +95,10 @@
#include <features.h>
+#define sl r10
+#define fp r11
+#define ip r12
+
.text
.align 4 @ 16 byte boundary and there are 32 bytes below (arm case)
#if !defined(__thumb__) || defined(__thumb2__)
More information about the uClibc-cvs
mailing list