ld seems to disregard section relative specifiers on symbols

Julian Waters tanksherman27@gmail.com
Thu Sep 5 12:58:51 GMT 2024


Hi all,

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?

best regards,
Julian
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://sourceware.org/pipermail/binutils/attachments/20240905/de50a3fb/attachment.htm>


More information about the Binutils mailing list