[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