elfthread-local-storage

Understanding ELF TBSS and TDATA section loading


My elf file's sections are as follows

      Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .text             PROGBITS         fffffffff7e020b0  000000b0
       0000000000074f50  0000000000000000  AX       0     0     16
  [ 2] .rodata           PROGBITS         fffffffff7e77000  00075000
       0000000000014000  0000000000000000  AM       0     0     16
  [ 3] .eh_frame_hdr     PROGBITS         fffffffff7e8b000  00089000
       000000000000000c  0000000000000000   A       0     0     4
  [ 4] .data             PROGBITS         fffffffff7e8b010  00089010
       0000000000001ff0  0000000000000000  WA       0     0     16
  [ 5] .bss              NOBITS           fffffffff7e8d000  0008b000
       0000000000014000  0000000000000000  WA       0     0     4096
  [ 6] .got              PROGBITS         fffffffff7ea1000  0009f000
       0000000000001000  0000000000000000  WA       0     0     8
  [ 7] .tdata            PROGBITS         fffffffff7ea2000  000a0000
       000000000000b000  0000000000000000 WAT       0     0     8
  [ 8] .tbss             NOBITS           fffffffff7ead000  000ab000
       000000000000012a  0000000000000000 WAT       0     0     8
  [ 9] .debug_abbrev     PROGBITS         0000000000000000  000ab000
       000000000001a8d4  0000000000000000           0     0     1
  [10] .debug_info       PROGBITS         0000000000000000  000c58d4
       000000000016c624  0000000000000000           0     0     1
  [11] .debug_aranges    PROGBITS         0000000000000000  00231ef8
       0000000000024130  0000000000000000           0     0     1
  [12] .debug_ranges     PROGBITS         0000000000000000  00256028
       000000000004bfa0  0000000000000000           0     0     1
  [13] .debug_str        PROGBITS         0000000000000000  002a1fc8
       0000000000123ecd  0000000000000001  MS       0     0     1
  [14] .debug_pubnames   PROGBITS         0000000000000000  003c5e95
       000000000005da3c  0000000000000000           0     0     1
  [15] .debug_pubtypes   PROGBITS         0000000000000000  004238d1
       00000000000a1e07  0000000000000000           0     0     1
  [16] .debug_frame      PROGBITS         0000000000000000  004c56d8
       0000000000056c10  0000000000000000           0     0     8
  [17] .debug_line       PROGBITS         0000000000000000  0051c2e8
       00000000000b5c55  0000000000000000           0     0     1
  [18] .debug_loc        PROGBITS         0000000000000000  005d1f3d
       000000000000628c  0000000000000000           0     0     1
  [19] .symtab           SYMTAB           0000000000000000  005d81d0
       0000000000015a20  0000000000000018          21   2565     8
  [20] .shstrtab         STRTAB           0000000000000000  005edbf0
       00000000000000da  0000000000000000           0     0     1
  [21] .strtab           STRTAB           0000000000000000  005edcca
       000000000004783e  0000000000000000           0     0     1

and the program headers are

Elf file type is EXEC (Executable file)
Entry point 0xfffffffff7e39be0
There are 2 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000000000 0xfffffffff7e02000 0x0000000000000000
                 0x00000000000ab000 0x00000000000ab12a  RWE    0x1000
  TLS            0x00000000000a0000 0xfffffffff7ea2000 0x00000000000a0000
                 0x000000000000b000 0x000000000000b12a  RW     0x8

 Section to Segment mapping:
  Segment Sections...
   00     .text .rodata .eh_frame_hdr .data .bss .got .tdata
   01     .tdata .tbss

The TLS section's total size is as expected being the size of tdata + tbss sections. From the TLS handling document, i expect that tdata and tbss sections will be right before the fs register's pointed value and thus the total size would be 0xb12a.

But one of the variables which use thread_local have an offset of fs - 0xb130 which is outside of the expected TLS size. I am trying to understand why the variable is not offset to at-most 0xb12a but more than that?


Solution

  • Although the size of TLS here is 0xb12a. The alignment of 0x8 will make the TLS pointer move to 0xb130 which is the address of variable observed here.