Ver Fonte

nios2: allow threads and shared libraries with uClibc-ng

nios2 was pinned to static-libs-only without threads whenever the C
library is uClibc-ng:

	select ADK_TARGET_SUPPORTS_THREADS if ADK_TARGET_LIB_GLIBC
	select ADK_TARGET_SUPPORTS_NPTL if ADK_TARGET_LIB_GLIBC
	select ADK_TARGET_USE_STATIC_LIBS_ONLY if ADK_TARGET_LIB_UCLIBC_NG

which matched reality: uClibc-ng's nios2 dynamic linker never worked.  A
dynamically linked binary died before its first syscall, and uClibc-ng's
own commit adding that code says so ("Only static linking is supported
for now. More debugging and analyzing for ld.so, TLS and NPTL is
required.", 2016).

Six defects, each hiding the next, none of them ever executed because the
only nios2 test target is static:

  - elf_machine_relative() never advanced the relocation pointer, walked
    a RELA table as Elf32_Rel, and added the load offset instead of
    assigning the addend, so the loader's own GOT stayed zeroed
  - crt1.S left app_init/app_fini unset; after exec the kernel hands over
    zeroed registers, ld.so does not, so __uClibc_main() called whatever
    the loader had left in r7
  - the loader jumped to the program without putting _dl_fini in r4,
    where crt1.S picks up rtld_fini
  - elfinterp.c had no TLS relocations at all (DTPMOD/DTPREL/TPREL)
  - createthread.c passed pd + 1 as the thread pointer instead of
    pd + TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE, which nios2 needs like
    powerpc and mips
  - crti.S did not establish r22, the GOT register the code gcc puts
    between crti and crtn relies on, so dlopen crashed in _init

With those fixed, a dynamically linked nios2 program runs, loads shared
libraries, creates threads and dlopens modules.  NPTL additionally needs
libgcc_s.so.1, which pthread_cancel_init() dlopens, and that exists only
if the toolchain may build shared libraries -- hence dropping the
static-only line rather than just the threads condition.

Threads and shared linking on nios2 are not finished: dlopen of a library
that resolves symbols against libc still faults, and two TLS tests fail
to link.  This only stops openadk from forbidding the combination, so the
remaining work can be done at all.

Signed-off-by: Ramin Moussavi <ramin.moussavi@yacoub.de>
Signed-off-by: Waldemar Brodkorb <wbx@openadk.org>
ramin há 2 semanas atrás
pai
commit
86489be4b2
1 ficheiros alterados com 2 adições e 3 exclusões
  1. 2 3
      target/config/Config.in.cpu

+ 2 - 3
target/config/Config.in.cpu

@@ -1047,10 +1047,9 @@ config ADK_TARGET_CPU_NDS32
 # nios2
 config ADK_TARGET_CPU_NIOS2
 	bool "nios2"
-	select ADK_TARGET_SUPPORTS_THREADS if ADK_TARGET_LIB_GLIBC
-	select ADK_TARGET_SUPPORTS_NPTL if ADK_TARGET_LIB_GLIBC
+	select ADK_TARGET_SUPPORTS_THREADS
+	select ADK_TARGET_SUPPORTS_NPTL
 	select ADK_TARGET_WITH_MMU
-	select ADK_TARGET_USE_STATIC_LIBS_ONLY if ADK_TARGET_LIB_UCLIBC_NG
 	depends on ADK_TARGET_ARCH_NIOS2
 
 # openrisc