[lld] TBSS wrong size

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;

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.

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;

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.

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.

It looks like TBSS size is wrong.The bug is in the function Segment::assignVirtualAddress as you pointed.