[LLVMdev] [lld] TBSS wrong size

Adhemerval Zanella adhemerval.zanella at linaro.org
Wed Jun 3 06:16:12 PDT 2015


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