Description
I'm working on standalone arc testing for picolibc. One of the tests checks to make sure TLS offsets and relocations work correctly for values that require larger alignment. I discovered that the relocations generated in the output file don't match the positions of the values within the TLS segment. With this bug present, TLS cannot be used on arc.
I've managed to reproduce this in a stand-alone test case.
Source code:
__thread int data_var = 12;
__attribute__((__aligned__(128))) __thread int data_var_128 = 128;
__thread int bss_var;
__attribute__((__aligned__(256))) __thread int bss_var_256;
int __start(void)
{
return data_var + data_var_128 + bss_var + bss_var_256;
}
Compile command:
$ arc-zephyr-elf-gcc -ffreestanding -nostdlib foo.c -mtp-regno=26
$ arc-zephyr-elf-objdump -St a.out
objdump output:
a.out: file format elf32-littlearc
SYMBOL TABLE:
00000100 l d .text 00000000 .text
00002200 l d .tdata 00000000 .tdata
00002300 l d .tbss 00000000 .tbss
00002300 l d .got 00000000 .got
0000230c l d .bss 00000000 .bss
0000230c l d .noinit 00000000 .noinit
00000000 l d .comment 00000000 .comment
00000000 l d .ARC.attributes 00000000 .ARC.attributes
00000000 l df *ABS* 00000000 foo.c
00000000 l df *ABS* 00000000
00002300 l O .got 00000000 _GLOBAL_OFFSET_TABLE_
00000100 g .text 00000000 __JLI_TABLE__
0000240c g .got 00000000 __SDATA_BEGIN__
00000000 g .tdata 00000004 data_var
00000100 g F .text 0000003c __start
00000200 g .tbss 00000004 bss_var_256
00000100 g .tbss 00000004 bss_var
0000230c g .got 00000000 __bss_start
00000080 g .tdata 00000004 data_var_128
0000230c g .got 00000000 _edata
0000230c g .bss 00000000 _end
Disassembly of section .text:
00000100 <__start>:
100: 1cfc b6c8 st.aw fp,[sp,-4]
104: 439b mov_s fp,sp
106: 2200 3f82 0000 0080 add r2,gp,0x80
10e: 4344 ld_s r3,[r2,0]
110: 2200 3f82 0000 0100 add r2,gp,0x100
118: 4244 ld_s r2,[r2,0]
11a: 635b add_s r3,r3,r2
11c: 2200 3f82 0000 0200 add r2,gp,0x200
124: 4244 ld_s r2,[r2,0]
126: 635b add_s r3,r3,r2
128: 2200 3f82 0000 0300 add r2,gp,0x300
130: 4244 ld_s r2,[r2,0]
132: 635a add_s r2,r3,r2
134: 4040 mov_s r0,r2
136: 1404 341b ld.ab fp,[sp,4]
13a: 7ee0 j_s [blink]
You can see that all of the TLS variables are referenced with incorrect offsets:
Actual offset Value in code Difference
data_var 00000000 0x80 0x80
data_var_128 00000080 0x100 0x80
bss_var 00000100 0x200 0x100
bss_var_256 00000200 0x300 0x100
If this required a computable offset to the TLS base address based on the TLS block alignment (as on ARM), that would be fixable in the linker script and/or TLS register setting code. However, the offsets of data_var
and data_var_128
are 0x80 while the offsets of bss_var
and bss_var_256
are 0x100.
Metadata
Metadata
Assignees
Type
Projects
Status