From 191739597c6d380692885cfdd8dd8aa4f31f029d Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Mon, 31 Oct 2016 18:05:44 +0100 Subject: microblaze: add NPTL/TLS support from GNU libc Not perfect, but a starting point. Some tests of the test suite are failing. --- ldso/ldso/microblaze/dl-debug.h | 8 ++++++++ ldso/ldso/microblaze/dl-startup.h | 3 --- ldso/ldso/microblaze/dl-sysdep.h | 28 ++++++++++++++-------------- ldso/ldso/microblaze/elfinterp.c | 22 ++++++++++++---------- 4 files changed, 34 insertions(+), 27 deletions(-) (limited to 'ldso') 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 . */ -/* Use reloca */ #define ELF_USES_RELOCA #include - /* 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); -- cgit v1.2.3