Bug 5618

Summary: uClibc build is broken: undefined reference to `__emutls_get_address' in function `__syscall_error'
Product: uClibc Reporter: Douglas <dougmencken>
Component: ThreadsAssignee: unassigned
Status: NEW ---    
Severity: major CC: buildroot, uclibc-cvs
Priority: P5    
Version: unspecified   
Target Milestone: ---   
Hardware: All   
OS: Linux   
Host: Target:
Build:
Attachments: config-uclibc

Description Douglas 2012-10-21 11:00:40 UTC
I'm trying to build current git master (uclibc-v0.9.34-rc3-784-g6a76edd). That's what I've got with make V=2:

----------------------------------------
$ make V=2
    make -C extra/locale locale_headers
    make[1]: Nothing to be done for `locale_headers'.
    rm -f lib/libc.so lib/libc.so.0 lib/libuClibc-0.9.34-git.so
    gcc -Wl,-EB -shared -Wl,--warn-common -Wl,--warn-once -Wl,-z,combreloc -Wl,-z,relro -Wl,--hash-style=gnu -Wl,-z,defs -Wl,-s   -Wl,-init,__uClibc_init  -Wl,-soname=libc.so.0 -nostdlib -o lib/libuClibc-0.9.34-git.so  -Wl,--whole-archive libc/libc_so.a -Wl,--no-whole-archive ./lib/interp.os ./lib/ld-uClibc.so.0 ./lib/uclibc_nonshared.a /usr/lib/gcc/powerpc32-gnu-linux-uclibc/4.8.0/libgcc.a
    libc/libc_so.a(__syscall_error.os): In function `__syscall_error':
    __syscall_error.c:(.text+0x20): undefined reference to `__emutls_get_address'
    collect2: error: ld returned 1 exit status
    make: *** [lib/libc.so] Error 1
----------------------------------------
Comment 1 Mike Frysinger 2012-11-17 20:47:01 UTC
please post your .config as an attachment
Comment 2 Douglas 2012-11-21 17:19:22 UTC
(In reply to comment #1)
> please post your .config as an attachment

My config is here — http://manulix.wikidot.com/files:uclibc-config
Comment 3 Douglas 2012-11-21 18:04:21 UTC
Created attachment 4658 [details]
config-uclibc
Comment 4 Douglas 2013-03-05 19:09:21 UTC
I still have the same problem with both release 0.9.33.2 and git master (0.9.34-rc3-907-g60c1fe7).
Comment 5 Douglas 2013-03-05 19:57:10 UTC
To re-produce this issue, you need to build uClibc under uClibc system natively (with native toolchain).

I found that "Using thread local storage requires **manually linking** to TLS emutls, via -lgcc_s (-lgcc_s.so.1)."

$ readelf -h -d -s /usr/lib/libgcc_s.so.1 | grep "emutls_get_addres"
   157: 0001277c   452 FUNC    GLOBAL DEFAULT    9 __emutls_get_address@@GCC_4.3.0
   376: 0001277c   452 FUNC    GLOBAL DEFAULT    9 __emutls_get_address

Editing Rules.mak as the following

--- evil/Rules.mak
+++ good/Rules.mak
@@ -720,6 +720,8 @@ else
 DOMULTI:=n
 endif

+LDFLAGS += -lgcc_s
+
 ifneq ($(strip $(UCLIBC_EXTRA_LDFLAGS)),"")
 LDFLAGS += $(call qstrip,$(UCLIBC_EXTRA_LDFLAGS))
 endif

makes me succeed a little further. Now I got:

  AS libpthread/nptl/sysdeps/pthread/pt-crtn.o
  LD libpthread-0.9.34-git.so
libpthread/nptl/libpthread_so.a(pthread_mutex_cond_lock.oS): In function `__pthread_mutex_cond_lock_full':
(.text.unlikely+0x2bc): undefined reference to `__emutls_get_address'
Comment 6 Douglas 2013-03-05 20:25:52 UTC
I can report successful build. The full patch is:

$ cat link_with_gcc_s.patch 
--- evil/Rules.mak
+++ good/Rules.mak
@@ -720,6 +720,8 @@ else
 DOMULTI:=n
 endif
 
+LDFLAGS += -lgcc_s
+
 ifneq ($(strip $(UCLIBC_EXTRA_LDFLAGS)),"")
 LDFLAGS += $(call qstrip,$(UCLIBC_EXTRA_LDFLAGS))
 endif
--- evil/test/Rules.mak
+++ good/test/Rules.mak
@@ -76,7 +76,7 @@ CFLAGS         += $(OPTIMIZATION) $(CPU_CFLAGS) $(XWARNINGS)
 # Just adding -Os for now.
 HOST_CFLAGS    += $(XCOMMON_CFLAGS) -Os $(XWARNINGS) -std=gnu99
 
-LDFLAGS        := $(CPU_LDFLAGS-y) -Wl,-z,now
+LDFLAGS        := $(CPU_LDFLAGS-y) -Wl,-z,now -lgcc_s
 ifeq ($(DODEBUG),y)
 	CFLAGS        += -g
 	HOST_CFLAGS   += -g
--- evil/libpthread/nptl/Makefile.in
+++ good/libpthread/nptl/Makefile.in
@@ -138,6 +138,8 @@ HEADERCLEAN_libpthread/nptl:
 CLEAN_libpthread/nptl:
 	$(do_rm) $(addprefix $(libpthread_OUT)/*., o os oS a)
 
+LDFLAGS-libpthread.so += -lgcc_s
+
 ifeq ($(PTHREADS_DEBUG_SUPPORT),y)
 LDFLAGS-libpthread.so += $(LDFLAGS_NOSTRIP) -Wl,-z,defs
 else