[PATCH] ldso: fix x86_64 R_X86_64_TPOFF64 and R_X86_64_DTPOFF64 relocations

Joakim Tjernlund joakim.tjernlund at transmode.se
Tue May 4 12:37:35 UTC 2010


>
> R_X86_64_TPOFF64 revealed by trivial testcase:
> ===================================================================
>  #include <stdio.h>
>  #include <errno.h>
>
> int main() {
>         void *a = &errno;
>
>         printf("errno addr: %llx\n", a);
>         __asm__("movq    errno at gottpoff(%%rip), %0;\n"
>                 "add    %%fs:0x0,%0;" : "=r"(a) );
>         printf("got errno addr: %llx\n", a);
>
>         return 0;
> }
> ===================================================================
>
> The addresses application got with R_X86_64_TPOFF64 was different than the once libc
> internal __errno_location returned.
>
> R_X86_64_DTPOFF64 testcase is even simpler than that:
> ===================================================================
>  #include <stdio.h>
>  #include <errno.h>
>  #include <netdb.h>
>  #undef h_errno
>
> extern __thread int h_errno;
>
> int main() {
>         printf("h_errno addr: %llx\n", &h_errno);
>         printf("__h_errno_location addr: %llx\n", __h_errno_location());
>         return 0;
> }
> ===================================================================
>
> but needs to be linked with "-lpthread". This way we've got h_errno relocation via
> R_X86_64_TPOFF64 in application and h_errno relocation via R_X86_64_DTPOFF64 in
> libpthread which has its own __h_errno_location() (probably we can kill it later?).
> And addresses were different again.
>
> The problem is that both relocations resolve symbols in external modules and thus
> should use symbol_addr instead of sym->st_value.

Last I looked this does not match glibc, are you sure this is the correct fix?

    Jocke



More information about the uClibc mailing list