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>