Hi,

On Mon, 18 Dec 2017, Nancy wrote:

> tls.c:
> __thread int i=10;
> 
> $gcc -g -c -save-temps tls.c
> $readelf -r tls.o
> Relocation section '.rela.debug_info' at offset 0x2d0 contains 6 entries:
>   Offset          Info           Type           Sym. Value    Sym. Name + 
> Addend
> 000000000006  00070000000a R_X86_64_32       0000000000000000 .debug_abbrev + > 0
> 00000000000c  000a0000000a R_X86_64_32       0000000000000000 .debug_str + 11
> 000000000011  000a0000000a R_X86_64_32       0000000000000000 .debug_str + 3f
> 000000000015  000a0000000a R_X86_64_32       0000000000000000 .debug_str + 0
> 000000000019  00090000000a R_X86_64_32       0000000000000000 .debug_line + 0
> 000000000028  000d00000015 R_X86_64_DTPOFF32 0000000000000000 i + 0
> 
> Relocation section '.rela.debug_aranges' at offset 0x360 contains 1 entries:
>   Offset          Info           Type           Sym. Value    Sym. Name + 
> Addend
> 000000000006  00060000000a R_X86_64_32       0000000000000000 .debug_info + 0
> 
> I can't find any code in cc1 or as that generate R_X86_64_DTPOFF32 in
> .rela.debug_info section. Did I miss something?

To expand on what Nathan said: the debug info needs to refer to the 
location of the variable 'i' somehow, and as it's a TLS variable that 
location is thread specific as well, and so the normal data relocations 
can't be used.  So the dwarf info contains a location expression that uses 
this relocation and a GNU extension to push the tls address into the 
expression stack.  See e.g. the verbose asm output for the above file, the 
DIE for 'i' will contain something like this:

        .uleb128 0x2    # (DIE (0x1d) DW_TAG_variable)
        .ascii "i\0"    # DW_AT_name
        .byte   0x1     # DW_AT_decl_file (x.c)
        .byte   0x1     # DW_AT_decl_line
        .long   0x31    # DW_AT_type
                        # DW_AT_external
        .uleb128 0xa    # DW_AT_location
        .byte   0xe     # DW_OP_const8u
        .long   i@dtpoff, 0
        .byte   0xe0    # DW_OP_GNU_push_tls_address

The 'i@dtpoff' is the field that causes the DTPOFF32 relocation to be 
created by the assembler.


Ciao,
Michael.

Reply via email to