[PATCH] ldso: fix x86_64 R_X86_64_TPOFF64 and R_X86_64_DTPOFF64 relocations

Roman I Khimov khimov at altell.ru
Tue May 4 12:41:24 UTC 2010


В сообщении от Вторник 04 мая 2010 16:37:35 автор Joakim Tjernlund написал:
> > 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?

Well, that's why there are testcases included. This fixes both.

Started with R_X86_64_TPOFF64 as it was used in libpthread to reach errno from 
assembler routines (asm snippet above, .c sources used __errno_location()) and 
as the address got via relocation was different from the one returned by 
__errno_location(), we've had two errno-s and random breakage in applications 
or libc code that tried to use that (R_X86_64_TPOFF64 fixed 7 nptl tests for 
me).

Then I've also checked R_X86_64_DTPOFF64 just out of curiosity (h_errno in 
libpthread resolved with it) and discovered that it also has a problem.


More information about the uClibc mailing list