[LLVMdev] [lld] TBSS wrong size

Shankar Easwaram shankarke at gmail.com
Wed Jun 3 07:13:42 PDT 2015


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?




More information about the llvm-dev mailing list