Hi, Yes, ldd is generating wrong tbss size. It is just considering one tbss section and not calculating all sections from all objects. The following example on x86_64 shows the issue: --- t0.c --- #include <stdio.h> extern __thread int t0; extern __thread int t1; extern __thread int t2; extern __thread int t3; __thread int t4; __thread int t5; __thread int t6; __thread int t7; int main () { t4 = 1; t5 = 2; t6 = 3; t7 = 4; printf ("%i %i %i %i\n", t0, t1, t2, t3); printf ("%i %i %i %i\n", t4, t5, t6, t7); return 0; } --- t1.c --- __thread int t0; __thread int t1; __thread int t2; __thread int t3; ------------- If you build with lld you will see: $ ./t-lld 1 1 1 1 1 2 3 4 Because t{4,5,6,7} space is not taking in consideration. In fact if you check the resulting tbss for the test: [15] .tbss NOBITS 0000000000401000 00001000 0000000000000010 0000000000000000 WAT 0 0 4 Its size is just 0x10 (4 int), where it should be 0x20 (8 ints). On 02-06-2015 21:14, Shankar Easwaram wrote:> Are you saying it generates wrong section size? Tbss is very special and I checked the behavior on X86_64 to model it. It does not account for virtual address increase as libc allocates it. > > >> On Jun 2, 2015, at 17:20, Adhemerval Zanella <adhemerval.zanella at linaro.org> wrote: >> >> Hi, >> >> I am tracking some TLS issues with lld and found that it is >> generating wrong tbss size for case where multiple modules >> have non initialized threads variables. For instance: >> >> -- t0.c -- >> >> __thread int x0; >> __thread int x1; >> __thread int x2; >> >> extern __thread int e0; >> extern __thread int e1; >> extern __thread int e2; >> extern __thread int e3; >> >> int foo0 () >> { >> return x0; >> } >> >> int main () >> { >> return x0; >> } >> >> -- t1.c -- >> >> __thread int e0; >> __thread int e1; >> __thread int e2; >> __thread int e3; >> >> --- >> >> lld is generating (for aarch64): >> >> [14] .tbss NOBITS 0000000000401000 00001000 >> 0000000000000010 0000000000000000 WAT 0 0 4 >> >> Where is just taking in consideration the largest tbss segment, not all >> from all objects. ld generates a correct output: >> >> [17] .tbss NOBITS 0000000000410dec 00000dec >> 000000000000001c 0000000000000000 WAT 0 0 4 >> >> My initial idea is that 'lib/ReaderWriter/ELF/SegmentChunks.cpp' / >> Segment<ELFT>::assignVirtualAddress is setting wrong slice values, however >> playing with this I could not find a correct logic to handle the TBSS. >> >> Any ideas where lld is possible messing the TBSS segments sizes?
Ah this is a nasty bug. You might want to checkout if some of the TLS variables are allocated elsewhere? It cannot just disappear from the output.> On Jun 3, 2015, at 08:16, Adhemerval Zanella <adhemerval.zanella at linaro.org> wrote: > > Hi, > > Yes, ldd is generating wrong tbss size. It is just considering one tbss section > and not calculating all sections from all objects. The following example on > x86_64 shows the issue: > > --- t0.c --- > > #include <stdio.h> > > extern __thread int t0; > extern __thread int t1; > extern __thread int t2; > extern __thread int t3; > > __thread int t4; > __thread int t5; > __thread int t6; > __thread int t7; > > int main () > { > t4 = 1; > t5 = 2; > t6 = 3; > t7 = 4; > > printf ("%i %i %i %i\n", t0, t1, t2, t3); > printf ("%i %i %i %i\n", t4, t5, t6, t7); > > return 0; > } > > --- t1.c --- > > __thread int t0; > __thread int t1; > __thread int t2; > __thread int t3; > > ------------- > > If you build with lld you will see: > > $ ./t-lld > 1 1 1 1 > 1 2 3 4 > > Because t{4,5,6,7} space is not taking in consideration. In fact if you > check the resulting tbss for the test: > > [15] .tbss NOBITS 0000000000401000 00001000 > 0000000000000010 0000000000000000 WAT 0 0 4 > > Its size is just 0x10 (4 int), where it should be 0x20 (8 ints). > > >> On 02-06-2015 21:14, Shankar Easwaram wrote: >> Are you saying it generates wrong section size? Tbss is very special and I checked the behavior on X86_64 to model it. It does not account for virtual address increase as libc allocates it. >> >> >>> On Jun 2, 2015, at 17:20, Adhemerval Zanella <adhemerval.zanella at linaro.org> wrote: >>> >>> Hi, >>> >>> I am tracking some TLS issues with lld and found that it is >>> generating wrong tbss size for case where multiple modules >>> have non initialized threads variables. For instance: >>> >>> -- t0.c -- >>> >>> __thread int x0; >>> __thread int x1; >>> __thread int x2; >>> >>> extern __thread int e0; >>> extern __thread int e1; >>> extern __thread int e2; >>> extern __thread int e3; >>> >>> int foo0 () >>> { >>> return x0; >>> } >>> >>> int main () >>> { >>> return x0; >>> } >>> >>> -- t1.c -- >>> >>> __thread int e0; >>> __thread int e1; >>> __thread int e2; >>> __thread int e3; >>> >>> --- >>> >>> lld is generating (for aarch64): >>> >>> [14] .tbss NOBITS 0000000000401000 00001000 >>> 0000000000000010 0000000000000000 WAT 0 0 4 >>> >>> Where is just taking in consideration the largest tbss segment, not all >>> from all objects. ld generates a correct output: >>> >>> [17] .tbss NOBITS 0000000000410dec 00000dec >>> 000000000000001c 0000000000000000 WAT 0 0 4 >>> >>> My initial idea is that 'lib/ReaderWriter/ELF/SegmentChunks.cpp' / >>> Segment<ELFT>::assignVirtualAddress is setting wrong slice values, however >>> playing with this I could not find a correct logic to handle the TBSS. >>> >>> Any ideas where lld is possible messing the TBSS segments sizes?
May not be a bug. It may have been placed in .tdata instead. have a look at the symbol table to see where these variables are. On Wed, Jun 3, 2015 at 3:13 PM, Shankar Easwaram <shankarke at gmail.com> wrote:> Ah this is a nasty bug. You might want to checkout if some of the TLS variables are allocated elsewhere? It cannot just disappear from the output. > > >> On Jun 3, 2015, at 08:16, Adhemerval Zanella <adhemerval.zanella at linaro.org> wrote: >> >> Hi, >> >> Yes, ldd is generating wrong tbss size. It is just considering one tbss section >> and not calculating all sections from all objects. The following example on >> x86_64 shows the issue: >> >> --- t0.c --- >> >> #include <stdio.h> >> >> extern __thread int t0; >> extern __thread int t1; >> extern __thread int t2; >> extern __thread int t3; >> >> __thread int t4; >> __thread int t5; >> __thread int t6; >> __thread int t7; >> >> int main () >> { >> t4 = 1; >> t5 = 2; >> t6 = 3; >> t7 = 4; >> >> printf ("%i %i %i %i\n", t0, t1, t2, t3); >> printf ("%i %i %i %i\n", t4, t5, t6, t7); >> >> return 0; >> } >> >> --- t1.c --- >> >> __thread int t0; >> __thread int t1; >> __thread int t2; >> __thread int t3; >> >> ------------- >> >> If you build with lld you will see: >> >> $ ./t-lld >> 1 1 1 1 >> 1 2 3 4 >> >> Because t{4,5,6,7} space is not taking in consideration. In fact if you >> check the resulting tbss for the test: >> >> [15] .tbss NOBITS 0000000000401000 00001000 >> 0000000000000010 0000000000000000 WAT 0 0 4 >> >> Its size is just 0x10 (4 int), where it should be 0x20 (8 ints). >> >> >>> On 02-06-2015 21:14, Shankar Easwaram wrote: >>> Are you saying it generates wrong section size? Tbss is very special and I checked the behavior on X86_64 to model it. It does not account for virtual address increase as libc allocates it. >>> >>> >>>> On Jun 2, 2015, at 17:20, Adhemerval Zanella <adhemerval.zanella at linaro.org> wrote: >>>> >>>> Hi, >>>> >>>> I am tracking some TLS issues with lld and found that it is >>>> generating wrong tbss size for case where multiple modules >>>> have non initialized threads variables. For instance: >>>> >>>> -- t0.c -- >>>> >>>> __thread int x0; >>>> __thread int x1; >>>> __thread int x2; >>>> >>>> extern __thread int e0; >>>> extern __thread int e1; >>>> extern __thread int e2; >>>> extern __thread int e3; >>>> >>>> int foo0 () >>>> { >>>> return x0; >>>> } >>>> >>>> int main () >>>> { >>>> return x0; >>>> } >>>> >>>> -- t1.c -- >>>> >>>> __thread int e0; >>>> __thread int e1; >>>> __thread int e2; >>>> __thread int e3; >>>> >>>> --- >>>> >>>> lld is generating (for aarch64): >>>> >>>> [14] .tbss NOBITS 0000000000401000 00001000 >>>> 0000000000000010 0000000000000000 WAT 0 0 4 >>>> >>>> Where is just taking in consideration the largest tbss segment, not all >>>> from all objects. ld generates a correct output: >>>> >>>> [17] .tbss NOBITS 0000000000410dec 00000dec >>>> 000000000000001c 0000000000000000 WAT 0 0 4 >>>> >>>> My initial idea is that 'lib/ReaderWriter/ELF/SegmentChunks.cpp' / >>>> Segment<ELFT>::assignVirtualAddress is setting wrong slice values, however >>>> playing with this I could not find a correct logic to handle the TBSS. >>>> >>>> Any ideas where lld is possible messing the TBSS segments sizes? > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
It looks like TBSS size is wrong.The bug is in the function Segment<ELFT>::assignVirtualAddress as you pointed. On Wed, Jun 3, 2015 at 9:13 AM, Shankar Easwaram <shankarke at gmail.com> wrote:> Ah this is a nasty bug. You might want to checkout if some of the TLS > variables are allocated elsewhere? It cannot just disappear from the output. > > > > On Jun 3, 2015, at 08:16, Adhemerval Zanella < > adhemerval.zanella at linaro.org> wrote: > > > > Hi, > > > > Yes, ldd is generating wrong tbss size. It is just considering one tbss > section > > and not calculating all sections from all objects. The following > example on > > x86_64 shows the issue: > > > > --- t0.c --- > > > > #include <stdio.h> > > > > extern __thread int t0; > > extern __thread int t1; > > extern __thread int t2; > > extern __thread int t3; > > > > __thread int t4; > > __thread int t5; > > __thread int t6; > > __thread int t7; > > > > int main () > > { > > t4 = 1; > > t5 = 2; > > t6 = 3; > > t7 = 4; > > > > printf ("%i %i %i %i\n", t0, t1, t2, t3); > > printf ("%i %i %i %i\n", t4, t5, t6, t7); > > > > return 0; > > } > > > > --- t1.c --- > > > > __thread int t0; > > __thread int t1; > > __thread int t2; > > __thread int t3; > > > > ------------- > > > > If you build with lld you will see: > > > > $ ./t-lld > > 1 1 1 1 > > 1 2 3 4 > > > > Because t{4,5,6,7} space is not taking in consideration. In fact if you > > check the resulting tbss for the test: > > > > [15] .tbss NOBITS 0000000000401000 00001000 > > 0000000000000010 0000000000000000 WAT 0 0 4 > > > > Its size is just 0x10 (4 int), where it should be 0x20 (8 ints). > > > > > >> On 02-06-2015 21:14, Shankar Easwaram wrote: > >> Are you saying it generates wrong section size? Tbss is very special > and I checked the behavior on X86_64 to model it. It does not account for > virtual address increase as libc allocates it. > >> > >> > >>> On Jun 2, 2015, at 17:20, Adhemerval Zanella < > adhemerval.zanella at linaro.org> wrote: > >>> > >>> Hi, > >>> > >>> I am tracking some TLS issues with lld and found that it is > >>> generating wrong tbss size for case where multiple modules > >>> have non initialized threads variables. For instance: > >>> > >>> -- t0.c -- > >>> > >>> __thread int x0; > >>> __thread int x1; > >>> __thread int x2; > >>> > >>> extern __thread int e0; > >>> extern __thread int e1; > >>> extern __thread int e2; > >>> extern __thread int e3; > >>> > >>> int foo0 () > >>> { > >>> return x0; > >>> } > >>> > >>> int main () > >>> { > >>> return x0; > >>> } > >>> > >>> -- t1.c -- > >>> > >>> __thread int e0; > >>> __thread int e1; > >>> __thread int e2; > >>> __thread int e3; > >>> > >>> --- > >>> > >>> lld is generating (for aarch64): > >>> > >>> [14] .tbss NOBITS 0000000000401000 00001000 > >>> 0000000000000010 0000000000000000 WAT 0 0 4 > >>> > >>> Where is just taking in consideration the largest tbss segment, not all > >>> from all objects. ld generates a correct output: > >>> > >>> [17] .tbss NOBITS 0000000000410dec 00000dec > >>> 000000000000001c 0000000000000000 WAT 0 0 4 > >>> > >>> My initial idea is that 'lib/ReaderWriter/ELF/SegmentChunks.cpp' / > >>> Segment<ELFT>::assignVirtualAddress is setting wrong slice values, > however > >>> playing with this I could not find a correct logic to handle the TBSS. > >>> > >>> Any ideas where lld is possible messing the TBSS segments sizes? >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150603/ea8b9dbe/attachment.html>