This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hi! I saw the GDB testcase gdb.threads/tls.exp failing to build due to the following assertion at the end of sh_elf_finish_dynamic_sections: 7395 if (htab->srelgot) 7396 BFD_ASSERT (htab->srelgot->reloc_count * sizeof (Elf32_External_Rela) 7397 == htab->srelgot->size); (gdb) print htab->srelgot->reloc_count $2 = 0 (gdb) print htab->srelgot->size $3 = 12 I distilled this C++/pthread test case into the following minimal arrangement: $ cat < tls.c int _start (void) { extern __thread int x; return x; } $ cat < tls2.c __thread int x; $ $ROOT/install/bin/*-gcc -O2 -c tls.c tls2.c $ $ROOT/install/bin/*-gcc -O2 -o null.o -c -x c /dev/null $ $ROOT/install/bin/*-ld -o tls3.so -shared null.o $ $ROOT/install/bin/*-ld -o tls tls.o tls2.o tls3.so [...]/sh-linux-gnu-ld: BFD (GNU Binutils) 2.22.52.20120315 assertion fail [...]/bfd/elf32-sh.c:7397 That is, we need a __thread variable that is referenced from another compilation unit; these two are linked into an executable; and we need a (dummy) SO in order to trigger creation of the .dynamic section, etc. What happens is the following. GCC will emit x as TLS IE. Called from sh_elf_size_dynamic_sections, in allocate_dynrelocs the the linker will therefore make a reservation in line 3111: 3098 dyn = htab->root.dynamic_sections_created; 3099 if (!dyn) 3100 { 3101 /* No dynamic relocations required. */ 3102 if (htab->fdpic_p && !info->shared 3103 && h->root.type != bfd_link_hash_undefweak 3104 && (got_type == GOT_NORMAL || got_type == GOT_FUNCDESC)) 3105 htab->srofixup->size += 4; 3106 } 3107 /* R_SH_TLS_IE_32 needs one dynamic relocation if dynamic, 3108 R_SH_TLS_GD needs one if local symbol and two if global. */ 3109 else if ((got_type == GOT_TLS_GD && h->dynindx == -1) 3110 || got_type == GOT_TLS_IE) 3111 htab->srelgot->size += sizeof (Elf32_External_Rela); (This is also where the (dummy) SO comes into play: otherwise Âdyn == NULLÂ.) Back in sh_elf_size_dynamic_sections, Âsrelgot->size != 0Â (Âsizeof (Elf32_External_Rela) == 12Â), thus memory for this section will be allocated (using bfd_zalloc). Later on, in sh_elf_relocate_section, the linker recognizes that TLS IE can here be optimized into TLS LE, and does so; the relocation slot is now not needed anymore (so srelgot->reloc_count is not incremented), but it is not reclaimed/the size reservation remains (and due to using zalloc, it's a R_SH_NONE), and thus the assertion is triggered. Expectedly, weakening the assertion into using <= instead of == makes the problem go away, but the empty slot in .rela.dyn remains (12 bytes wasted). Or, instead, should the srelgot->size reservations be un-done as the TLS optimizations are done (there may be other such cases, I didn't check)? Can this actually be done at this stage? Or, should there be another cleanup pass after the TLS optimizations have been done? Or, should one of the existing passes in fact be catching this case, too? Due to my lack of experience with BFD'S innards combined with its rather monstrous appearance, I can't really tell which is preferable. But I'm willing to learn. GrÃÃe, Thomas
Attachment:
pgp00000.pgp
Description: PGP signature
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |