Summary: | do_lookup_x returns undefined symbol entry | ||
---|---|---|---|
Product: | glibc | Reporter: | H.J. Lu <hjl.tools> |
Component: | dynamic-link | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | NEW --- | ||
Severity: | normal | Flags: | fweimer:
security-
|
Priority: | P2 | ||
Version: | 2.18 | ||
Target Milestone: | --- | ||
Host: | Target: | ||
Build: | Last reconfirmed: |
Description
H.J. Lu
2013-01-17 20:23:40 UTC
/* Nested routine to check whether the symbol matches. */ const ElfW(Sym) * __attribute_noinline__ check_match (const ElfW(Sym) *sym) { unsigned int stt = ELFW(ST_TYPE) (sym->st_info); assert (ELF_RTYPE_CLASS_PLT == 1); if (__builtin_expect ((sym->st_value == 0 /* No value. */ && stt != STT_TLS) || (type_class & (sym->st_shndx == SHN_UNDEF)), 0)) return NULL; Should we remove "type_class &"? The reason it works for GNU hash table is GNU hash table only contains defined symbols. It only happens with size relocation against TLS symbol: [hjl@gnu-6 sized-tls-2]$ readelf -r dynamic Relocation section '.rela.text' at offset 0x4d0 contains 1 entries: Offset Info Type Sym. Value Sym. Name + Addend 000000400604 000300000020 R_X86_64_SIZE32 0000000000000000 bar + 0 Relocation section '.rela.got' at offset 0x4e8 contains 2 entries: Offset Info Type Sym. Value Sym. Name + Addend 000000600b18 000300000012 R_X86_64_TPOFF64 0000000000000000 bar + 0 000000600b20 000500000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0 We don't consider R_X86_64_SIZE32 as ELF_RTYPE_CLASS_PLT class. We can check STT_TLS instead of TLS relocations for relocations against TLS symbols. I checked in a patch to resolve size relocation against non-empty TLS symbol at link-time: http://sourceware.org/ml/binutils/2013-01/msg00309.html (In reply to comment #4) > I checked in a patch to resolve size relocation against non-empty > TLS symbol at link-time: > > http://sourceware.org/ml/binutils/2013-01/msg00309.html I reverted this patch: http://sourceware.org/ml/binutils/2013-02/msg00073.html [hjl@gnu-6 pr15030]$ cat m.c #include <stdio.h> extern __thread char bar[]; extern char size_of_bar asm ("bar@SIZE"); extern void set_bar (int, int); int main () { set_bar (1, 20); if (10 == (long) &size_of_bar && bar[1] == 20) printf ("OK\n"); else printf ("BAD\n"); return 0; } [hjl@gnu-6 pr15030]$ cat b.c __thread char bar[10]; void set_bar (int i, int v) { bar[i] = v; } [hjl@gnu-6 pr15030]$ make gcc -B./ -g -O2 -c -o m.o m.c gcc -B./ -g -O2 -fPIC -c -o b.o b.c gcc -B./ -shared -o b.so b.o gcc -B./ -o x m.o b.so -Wl,-R,. -Wl,--hash-style=gnu gcc -B./ -o x1 m.o b.so -Wl,-R,. -Wl,--hash-style=sysv ./x1 BAD ./x OK [hjl@gnu-6 pr15030]$ |