summaryrefslogtreecommitdiff
path: root/ldso/ldso
diff options
context:
space:
mode:
authorWaldemar Brodkorb <wbx@uclibc-ng.org>2016-10-31 18:05:44 +0100
committerWaldemar Brodkorb <wbx@uclibc-ng.org>2016-11-03 20:37:48 +0100
commit191739597c6d380692885cfdd8dd8aa4f31f029d (patch)
treeb3f05ce72f7a87433905698dd58371048c904812 /ldso/ldso
parent7825930078208462655e107677656c45014e91b4 (diff)
microblaze: add NPTL/TLS support from GNU libc
Not perfect, but a starting point. Some tests of the test suite are failing.
Diffstat (limited to 'ldso/ldso')
-rw-r--r--ldso/ldso/microblaze/dl-debug.h8
-rw-r--r--ldso/ldso/microblaze/dl-startup.h3
-rw-r--r--ldso/ldso/microblaze/dl-sysdep.h28
-rw-r--r--ldso/ldso/microblaze/elfinterp.c22
4 files changed, 34 insertions, 27 deletions
diff --git a/ldso/ldso/microblaze/dl-debug.h b/ldso/ldso/microblaze/dl-debug.h
index 6fd7bd59f..30b27bb2a 100644
--- a/ldso/ldso/microblaze/dl-debug.h
+++ b/ldso/ldso/microblaze/dl-debug.h
@@ -51,4 +51,12 @@ static const char * const _dl_reltypes_tab[] =
"R_MICROBLAZE_GOTOFF_64",
"R_MICROBLAZE_GOTOFF_32",
"R_MICROBLAZE_COPY",
+ "R_MICROBLAZE_TLS",
+ "R_MICROBLAZE_TLSGD",
+ "R_MICROBLAZE_TLSLD",
+ "R_MICROBLAZE_TLSDTPMOD32",
+ "R_MICROBLAZE_TLSDTPREL32",
+ "R_MICROBLAZE_TLSDTPREL64",
+ "R_MICROBLAZE_TLSGOTTPREL32",
+ "R_MICROBLAZE_TLSTPREL32",
};
diff --git a/ldso/ldso/microblaze/dl-startup.h b/ldso/ldso/microblaze/dl-startup.h
index ba15a87c3..720c53aab 100644
--- a/ldso/ldso/microblaze/dl-startup.h
+++ b/ldso/ldso/microblaze/dl-startup.h
@@ -78,9 +78,6 @@ _dl_start_user:\n\
*/
#define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long*) ARGS)+1)
-/* The ld.so library requires relocations */
-#define ARCH_NEEDS_BOOTSTRAP_RELOCS
-
static __always_inline
void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr,
unsigned long symbol_addr, unsigned long load_addr, attribute_unused Elf32_Sym *symtab)
diff --git a/ldso/ldso/microblaze/dl-sysdep.h b/ldso/ldso/microblaze/dl-sysdep.h
index b293d27cc..43200271e 100644
--- a/ldso/ldso/microblaze/dl-sysdep.h
+++ b/ldso/ldso/microblaze/dl-sysdep.h
@@ -1,5 +1,3 @@
-/* elf reloc code for the microblaze platform, based on glibc 2.3.6, dl-machine.h */
-
/*
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -15,37 +13,41 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-/* Use reloca */
#define ELF_USES_RELOCA
#include <elf.h>
-
/* Initialise the GOT */
-#define INIT_GOT(GOT_BASE,MODULE) \
-do { \
- GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \
- GOT_BASE[1] = (unsigned long) MODULE; \
+#define INIT_GOT(GOT_BASE,MODULE) \
+do { \
+ GOT_BASE[1] = (unsigned long) MODULE; \
+ GOT_BASE[2] = (unsigned long) _dl_linux_resolve; \
} while(0)
/* Here we define the magic numbers that this dynamic loader should accept */
-
#define MAGIC1 EM_MICROBLAZE
#undef MAGIC2
/* Used for error messages */
#define ELF_TARGET "microblaze"
+/* Need bootstrap relocations */
+#define ARCH_NEEDS_BOOTSTRAP_RELOCS
+
struct elf_resolve;
unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
#define elf_machine_type_class(type) \
- (((type) == R_MICROBLAZE_JUMP_SLOT) * ELF_RTYPE_CLASS_PLT \
+ (((type) == R_MICROBLAZE_JUMP_SLOT || \
+ (type) == R_MICROBLAZE_TLSDTPREL32 || \
+ (type) == R_MICROBLAZE_TLSDTPMOD32 || \
+ (type) == R_MICROBLAZE_TLSTPREL32) \
+ * ELF_RTYPE_CLASS_PLT \
| ((type) == R_MICROBLAZE_COPY) * ELF_RTYPE_CLASS_COPY)
/* Return the link-time address of _DYNAMIC. Conveniently, this is the
first element of the GOT. This must be inlined in a function which
uses global data. */
-static inline Elf32_Addr
+static __always_inline Elf32_Addr __attribute__ ((unused))
elf_machine_dynamic (void)
{
Elf32_Addr got_entry_0;
@@ -56,7 +58,6 @@ elf_machine_dynamic (void)
return got_entry_0;
}
-
/* Return the run-time load address of the shared object. */
static inline Elf32_Addr
elf_machine_load_address (void)
@@ -64,6 +65,7 @@ elf_machine_load_address (void)
/* Compute the difference between the runtime address of _DYNAMIC as seen
by a GOTOFF reference, and the link-time address found in the special
unrelocated first GOT entry. */
+
Elf32_Addr dyn;
__asm__ __volatile__ (
"addik %0,r20,_DYNAMIC@GOTOFF"
@@ -72,8 +74,6 @@ elf_machine_load_address (void)
return dyn - elf_machine_dynamic ();
}
-
-
static __always_inline void
elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
Elf32_Word relative_count)
diff --git a/ldso/ldso/microblaze/elfinterp.c b/ldso/ldso/microblaze/elfinterp.c
index 1f6aeffb7..33aef2f3e 100644
--- a/ldso/ldso/microblaze/elfinterp.c
+++ b/ldso/ldso/microblaze/elfinterp.c
@@ -214,16 +214,13 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope,
case R_MICROBLAZE_NONE:
case R_MICROBLAZE_64_NONE:
break;
-
case R_MICROBLAZE_64:
*reloc_addr = symbol_addr + rpnt->r_addend;
break;
-
case R_MICROBLAZE_32:
case R_MICROBLAZE_32_LO:
*reloc_addr = symbol_addr + rpnt->r_addend;
break;
-
case R_MICROBLAZE_32_PCREL:
case R_MICROBLAZE_32_PCREL_LO:
case R_MICROBLAZE_64_PCREL:
@@ -231,16 +228,25 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope,
case R_MICROBLAZE_SRW32:
*reloc_addr = symbol_addr + rpnt->r_addend;
break;
-
case R_MICROBLAZE_GLOB_DAT:
case R_MICROBLAZE_JUMP_SLOT:
*reloc_addr = symbol_addr + rpnt->r_addend;
break;
-/* Handled by elf_machine_relative */
case R_MICROBLAZE_REL:
*reloc_addr = (unsigned long)tpnt->loadaddr + rpnt->r_addend;
break;
-
+#if defined USE_TLS && USE_TLS
+ case R_MICROBLAZE_TLSDTPMOD32:
+ *reloc_addr = tls_tpnt->l_tls_modid;
+ break;
+ case R_MICROBLAZE_TLSDTPREL32:
+ *reloc_addr = symbol_addr;
+ break;
+ case R_MICROBLAZE_TLSTPREL32:
+ CHECK_STATIC_TLS ((struct link_map *) tls_tpnt);
+ *reloc_addr = tls_tpnt->l_tls_offset + symbol_addr + rpnt->r_addend;
+ break;
+#endif
case R_MICROBLAZE_COPY:
if (symbol_addr) {
#if defined (__SUPPORT_LD_DEBUG__)
@@ -250,7 +256,6 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope,
symname, sym_ref.sym->st_size,
symbol_addr, reloc_addr);
#endif
-
_dl_memcpy((char *)reloc_addr,
(char *)symbol_addr,
sym_ref.sym->st_size);
@@ -260,7 +265,6 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope,
_dl_dprintf(_dl_debug_file, "no symbol_addr to copy !?\n");
#endif
break;
-
default:
return -1; /* Calls _dl_exit(1). */
}
@@ -279,14 +283,12 @@ _dl_do_lazy_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope,
ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab)
{
int reloc_type;
- int symtab_index;
ElfW(Addr) *reloc_addr;
#if defined (__SUPPORT_LD_DEBUG__)
ElfW(Addr) old_val;
#endif
(void)scope;
- symtab_index = ELF_R_SYM(rpnt->r_info);
(void)strtab;
reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + rpnt->r_offset);