Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

link failed glibc-2.7: libc_pic.os: __libc_resp accessed both as normal and thread local symbol #2291

Closed Quuxplusone closed 6 years ago

Quuxplusone commented 16 years ago
Bugzilla Link PR2137
Status RESOLVED FIXED
Importance P normal
Reported by Török Edwin (edwin+bugs@etorok.eu)
Reported on 2008-03-11 08:07:32 -0700
Last modified on 2018-11-07 00:22:26 -0800
Version unspecified
Hardware PC Linux
CC anton@korobeynikov.info, llvm-bugs@lists.llvm.org
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
llvm-gcc4.2 is now able to _compile_ all of glibc (as I stated in a previous
bugreport), however I get a link failure:

make[2]: Leaving directory `/home/edwin/glibc-2.7/build-tree/glibc-2.7/elf'
/home/edwin/llvm/install/bin/llvm-gcc   -shared -static-libgcc -Wl,-O1  -Wl,-
z,defs -Wl,-dynamic-linker=/lib/ld-linux.so.2  -B/home/edwin/glibc-2.7/build-
tree/i386-libc/csu/  -Wl,--version-script=/home/edwin/glibc-2.7/build-tree/i386-
libc/libc.map -Wl,-soname=libc.so.6 -Wl,-z,combreloc -Wl,-z,relro -Wl,--hash-
style=both -nostdlib -nostartfiles -e __libc_main -L/home/edwin/glibc-2.7/build-
tree/i386-libc -L/home/edwin/glibc-2.7/build-tree/i386-libc/math -
L/home/edwin/glibc-2.7/build-tree/i386-libc/elf -L/home/edwin/glibc-2.7/build-
tree/i386-libc/dlfcn -L/home/edwin/glibc-2.7/build-tree/i386-libc/nss -
L/home/edwin/glibc-2.7/build-tree/i386-libc/nis -L/home/edwin/glibc-2.7/build-
tree/i386-libc/rt -L/home/edwin/glibc-2.7/build-tree/i386-libc/resolv -
L/home/edwin/glibc-2.7/build-tree/i386-libc/crypt -L/home/edwin/glibc-2.7/build-
tree/i386-libc/nptl -Wl,-rpath-link=/home/edwin/glibc-2.7/build-tree/i386-
libc:/home/edwin/glibc-2.7/build-tree/i386-libc/math:/home/edwin/glibc-
2.7/build-tree/i386-libc/elf:/home/edwin/glibc-2.7/build-tree/i386-
libc/dlfcn:/home/edwin/glibc-2.7/build-tree/i386-libc/nss:/home/edwin/glibc-
2.7/build-tree/i386-libc/nis:/home/edwin/glibc-2.7/build-tree/i386-
libc/rt:/home/edwin/glibc-2.7/build-tree/i386-libc/resolv:/home/edwin/glibc-
2.7/build-tree/i386-libc/crypt:/home/edwin/glibc-2.7/build-tree/i386-libc/nptl -
o /home/edwin/glibc-2.7/build-tree/i386-libc/libc.so -T /home/edwin/glibc-
2.7/build-tree/i386-libc/shlib.lds /home/edwin/glibc-2.7/build-tree/i386-
libc/csu/abi-note.o /home/edwin/glibc-2.7/build-tree/i386-libc/elf/soinit.os
/home/edwin/glibc-2.7/build-tree/i386-libc/libc_pic.os /home/edwin/glibc-
2.7/build-tree/i386-libc/elf/sofini.os /home/edwin/glibc-2.7/build-tree/i386-
libc/elf/interp.os /home/edwin/glibc-2.7/build-tree/i386-libc/elf/ld.so -lgcc
/usr/bin/ld: /home/edwin/glibc-2.7/build-tree/i386-libc/libc_pic.os:
`__libc_resp' accessed both as normal and thread local symbol
/home/edwin/glibc-2.7/build-tree/i386-libc/libc_pic.os: could not read symbols:
File format not recognized
collect2: ld returned 1 exit status
make[1]: *** [/home/edwin/glibc-2.7/build-tree/i386-libc/libc.so] Error 1
make[1]: Leaving directory `/home/edwin/glibc-2.7/build-tree/glibc-2.7'
make: *** [all] Error 2

__libc_resp related things I found in the sources:
#define __resp __libc_resp

#if USE__THREAD
#undef __Resp
__thread struct __res_state *__resp = &_res;
extern __thread struct __res_state *__libc_resp
 __attribute__((alias ("__resp"))) attribute_hidden;
#endif

$ readelf -a libc_pic.os|grep resp:
000af232  00189a12 R_386_TLS_GD      00000004   __libc_resp
000afb20  00189a12 R_386_TLS_GD      00000004   __libc_resp
000d8b47  00189a03 R_386_GOT32       00000004   __libc_resp
000d8b5a  00189a03 R_386_GOT32       00000004   __libc_resp
000d8b6f  00189a03 R_386_GOT32       00000004   __libc_resp
000d8b9c  00189a03 R_386_GOT32       00000004   __libc_resp
000d8c03  00189a03 R_386_GOT32       00000004   __libc_resp
000d8c2c  00189a03 R_386_GOT32       00000004   __libc_resp
000d8d73  00189a12 R_386_TLS_GD      00000004   __libc_resp
000da2b5  00189a12 R_386_TLS_GD      00000004   __libc_resp
000da4c5  00189a12 R_386_TLS_GD      00000004   __libc_resp
000da923  00189a12 R_386_TLS_GD      00000004   __libc_resp
000daa1d  00189a12 R_386_TLS_GD      00000004   __libc_resp
000daaf9  00189a12 R_386_TLS_GD      00000004   __libc_resp
000dacb6  00189a12 R_386_TLS_GD      00000004   __libc_resp
000dae5d  00189a12 R_386_TLS_GD      00000004   __libc_resp
000df8fd  00189a12 R_386_TLS_GD      00000004   __libc_resp
000e0b7d  00189a12 R_386_TLS_GD      00000004   __libc_resp
000e134d  00189a12 R_386_TLS_GD      00000004   __libc_resp
000fc38a  00189a12 R_386_TLS_GD      00000004   __libc_resp
000000aa  00189a12 R_386_TLS_GD      00000004   __libc_resp
000000c0  00189a12 R_386_TLS_GD      00000004   __libc_resp
  6298: 00000004     4 TLS     GLOBAL DEFAULT   70 __libc_resp
  7696: 00000004     4 TLS     GLOBAL DEFAULT   70 __resp

I guess that R_386_GOT32 and R_386_TLS_GD conflict, how can I find out _why_
some symbols are R_386_GOT32, and others are R_386_TLS_GD?
Quuxplusone commented 16 years ago

Is this x86-32 or x86-64 build?

Quuxplusone commented 16 years ago
(In reply to comment #1)
> Is this x86-32 or x86-64 build?
>

My glibc build test is x86-32.
Quuxplusone commented 16 years ago
Ok. Looks like some weirdness in PIC handling mixed with TLS stuff.

1. What if you disable threads?
2. Could you please provide some reduction?
Quuxplusone commented 16 years ago
(In reply to comment #3)
> Ok. Looks like some weirdness in PIC handling mixed with TLS stuff.
>
> 1. What if you disable threads?

I am trying that now.

> 2. Could you please provide some reduction?
>

Ok, the problem is in resolv/res_libc.c itself.
Here is a reduced testcase (the order of #define, use of _res, etc. matters!):

struct __res_state{int id};
# define attribute_hidden __attribute__ ((visibility ("hidden")))
#define _res (*__resp)
#define __resp __libc_resp
# define attribute_tls_model_ie __attribute__ ((tls_model ("initial-exec")))
extern __thread struct __res_state *__resp attribute_tls_model_ie;
int foo()
{
    _res.id=0;
}
int bar()
{
    _res.id=1;
}
#undef _res
struct __res_state _res __attribute__((section (".bss")));
#undef __resp
__thread struct __res_state *__resp = &_res;
extern __thread struct __res_state *__libc_resp
  __attribute__ ((alias ("__resp"))) attribute_hidden;

Compile as llvm-gcc -fPIC -c foo.c -o foo.o && readelf -a foo.o

Here is what llvm generates:
Relocation section '.rel.text' at offset 0x3d0 contains 4 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
0000000d  0000070a R_386_GOTPC       00000000   _GLOBAL_OFFSET_TABLE_
00000013  00000803 R_386_GOT32       00000000   __libc_resp
0000003d  0000070a R_386_GOTPC       00000000   _GLOBAL_OFFSET_TABLE_
00000043  00000803 R_386_GOT32       00000000   __libc_resp

Here is what gcc generates:
00000004  00000b02 R_386_PC32        00000000   __i686.get_pc_thunk.cx
0000000a  00000c0a R_386_GOTPC       00000000   _GLOBAL_OFFSET_TABLE_
00000010  00000d10 R_386_TLS_GOTIE   00000000   __libc_resp
00000023  00000b02 R_386_PC32        00000000   __i686.get_pc_thunk.cx
00000029  00000c0a R_386_GOTPC       00000000   _GLOBAL_OFFSET_TABLE_
0000002f  00000d10 R_386_TLS_GOTIE   00000000   __libc_resp
Quuxplusone commented 16 years ago
(In reply to comment #4)
> (In reply to comment #3)
> > Ok. Looks like some weirdness in PIC handling mixed with TLS stuff.
> >
> > 1. What if you disable threads?
>
> I am trying that now.
>

There is a semi-random code generator crash (when building with thread
support), see #2138, but on an entirely different file.

I am not sure if building without threads is even possible. I tried --without-
__thread, disable nptl, disable tls (--without-tls), --disable-sanity-checks,
yet it still wants to compile libc-tls.c (and it fails because I disabled
threads).
If I tell it to use linuxthreads instead of nptl it fails with some missing
headers.
Quuxplusone commented 16 years ago

Ok. It seems some extra care should be added to codegen with PIC+TLS

Quuxplusone commented 16 years ago
Actually, two problems here:

1. Alias should be printed as hidden
2. Aliasee is thread local, but alias is definitely not. Extra care should be
added in this case.
Quuxplusone commented 16 years ago
Fixed in:
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20080310/059590.html

Testcase here:
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20080310/059591.html

Current TLS implementation for PIC is far from ideal, but hope the stuff will
work.

PS: This is really nasty alias usage :)
Quuxplusone commented 16 years ago
(In reply to comment #8)
> Fixed in:
> http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-
20080310/059590.html
>
> Testcase here:
> http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-
20080310/059591.html
>
> Current TLS implementation for PIC is far from ideal, but hope the stuff will
> work.

Thanks, I no longer get this linker error

>
> PS: This is really nasty alias usage :)
>

There are more nasty linking problems in glibc-2.7/csu/, opening a new bug.