ld seems to disregard section relative specifiers on symbols

Jan Beulich jbeulich@suse.com
Fri Sep 6 13:17:14 GMT 2024


On 05.09.2024 14:58, Julian Waters wrote:
> Take the following program compiled to an object file by gcc as an example:
> 
> asm (".section .tls$, \"dw\"" "\n\t"
>          ".align 4"                     "\n"
>          "local:"                        "\n\t"
>          ".long 2");
> 
> extern "C" long sectionrelative() noexcept;
> asm (".text"                                        "\n"
>          "sectionrelative:"                       "\n\t"
>          "movl $local@secrel32, %eax" "\n\t"
>          "ret");
> 
> int main() {
>     printf("%lx\n", sectionrelative());
> }
> 
> When linking with different linkers and running the resulting program, one
> will get different results returned from the sectionrelative() method:
> 
> Linked by ld:
> # ./a.exe
> ecc0008
> 
> Linked by clang lld:
> $ ./a.exe
> 8
> 
> clang's lld correctly patches the code to use section relative offsets in
> this instance, because the @secrel specifier was requested, while ld
> incorrectly patches the address to be the absolute value. This appears to
> be strictly an ld bug, because compiling with gcc or assembling with as and
> then linking with clang lld yields the correct section relative offset of
> 8. This bug is a significant showstopper in the recent attempts to add TLS
> support on Windows to gcc, so I'm invested in having it fixed. Is there any
> hint as to why ld is ignoring the @secrel modifier?

I think I can confirm the behavior, yet I'll need to find some more time to
also explain (and then hopefully fix) it.

Jan


More information about the Binutils mailing list