On Monday 17 September 2007 13:48, Simon Marlow wrote:
> When you generate a non-PIC object file, references to external functions
> will go through the PLT (a table of jump instructions, or it might be more
> complicated than that and support lazy resolution).  So when you use
> dlsym() you're getting the real address of the function, but the static
> binding is pointing to an entry in the PLT.  I guess the -fPIC version is
> doing the indirection at the point of the symbol reference.  [...]

I thought about this as well, but things seem to be a bit more complicated. My 
example wasn't chosen very well, so let's repeat it with the *real* problem, 
which is a reference to data, not a reference to a funtion:

-------- strange.c -----------------------------------------
#include <dlfcn.h>
#include <stdio.h>

// cut-n-paste from freeglut, used in
// #define GLUT_BITMAP_8_BY_13 ((void *) &glutBitmap8By13)

extern void* glutBitmap8By13;

int main(void) {
  void *handle = dlopen("libglut.so", RTLD_NOW | RTLD_GLOBAL);
  printf("%p    %p\n", dlsym(handle, "glutBitmap8By13"), &glutBitmap8By13);
  return dlclose(handle);
}
------------------------------------------------------------

The above results in the same behaviour, even though we reference data now, so 
I guess a PLT or something like that can't be the reason:

------------------------------------------------------------
[EMAIL PROTECTED]:~> gcc strange.c -ldl -lglut && ./a.out
0x2af96db92f00    0x601040
[EMAIL PROTECTED]:~> gcc strange.c -ldl -lglut -fpic && ./a.out
0x2b8fd4596f00    0x2b8fd4596f00
------------------------------------------------------------

Let's look at the code and the relocations, first for the non-PIC case:

------------------------------------------------------------
[EMAIL PROTECTED]:~> gcc -c strange.c
[EMAIL PROTECTED]:~> objdump --disassemble strange.o

strange.o:     file format elf64-x86-64

Disassembly of section .text:

0000000000000000 <main>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   48 83 ec 10             sub    $0x10,%rsp
   8:   be 02 01 00 00          mov    $0x102,%esi
   d:   bf 00 00 00 00          mov    $0x0,%edi
  12:   e8 00 00 00 00          callq  17 <main+0x17>
  17:   48 89 45 f8             mov    %rax,0xfffffffffffffff8(%rbp)
  1b:   48 8b 7d f8             mov    0xfffffffffffffff8(%rbp),%rdi
  1f:   be 00 00 00 00          mov    $0x0,%esi
  24:   e8 00 00 00 00          callq  29 <main+0x29>
  29:   48 89 c6                mov    %rax,%rsi
  2c:   ba 00 00 00 00          mov    $0x0,%edx
  31:   bf 00 00 00 00          mov    $0x0,%edi
  36:   b8 00 00 00 00          mov    $0x0,%eax
  3b:   e8 00 00 00 00          callq  40 <main+0x40>
  40:   48 8b 7d f8             mov    0xfffffffffffffff8(%rbp),%rdi
  44:   e8 00 00 00 00          callq  49 <main+0x49>
  49:   c9                      leaveq 
  4a:   c3                      retq   
[EMAIL PROTECTED]:~> readelf --relocs strange.o

Relocation section '.rela.text' at offset 0x670 contains 8 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + 
Addend
00000000000e  00050000000a R_X86_64_32       0000000000000000 .rodata + 0
000000000013  000a00000002 R_X86_64_PC32     0000000000000000 dlopen + 
fffffffffffffffc
000000000020  00050000000a R_X86_64_32       0000000000000000 .rodata + b
000000000025  000b00000002 R_X86_64_PC32     0000000000000000 dlsym + 
fffffffffffffffc
00000000002d  000c0000000a R_X86_64_32       0000000000000000 glutBitmap8By13 
+ 0
000000000032  00050000000a R_X86_64_32       0000000000000000 .rodata + 1b
00000000003c  000d00000002 R_X86_64_PC32     0000000000000000 printf + 
fffffffffffffffc
000000000045  000e00000002 R_X86_64_PC32     0000000000000000 dlclose + 
fffffffffffffffc

Relocation section '.rela.eh_frame' at offset 0x730 contains 1 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + 
Addend
000000000020  00020000000a R_X86_64_32       0000000000000000 .text + 0
------------------------------------------------------------

Note that glutBitmap8By13 is referenced via a R_X86_64_32 relocation. The same 
again for PIC:

------------------------------------------------------------
[EMAIL PROTECTED]:~> gcc -c -fpic strange.c
[EMAIL PROTECTED]:~> objdump --disassemble strange.o

strange.o:     file format elf64-x86-64

Disassembly of section .text:

0000000000000000 <main>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   48 83 ec 10             sub    $0x10,%rsp
   8:   be 02 01 00 00          mov    $0x102,%esi
   d:   48 8d 3d 00 00 00 00    lea    0(%rip),%rdi        # 14 <main+0x14>
  14:   e8 00 00 00 00          callq  19 <main+0x19>
  19:   48 89 45 f8             mov    %rax,0xfffffffffffffff8(%rbp)
  1d:   48 8b 7d f8             mov    0xfffffffffffffff8(%rbp),%rdi
  21:   48 8d 35 00 00 00 00    lea    0(%rip),%rsi        # 28 <main+0x28>
  28:   e8 00 00 00 00          callq  2d <main+0x2d>
  2d:   48 89 c6                mov    %rax,%rsi
  30:   48 8b 15 00 00 00 00    mov    0(%rip),%rdx        # 37 <main+0x37>
  37:   48 8d 3d 00 00 00 00    lea    0(%rip),%rdi        # 3e <main+0x3e>
  3e:   b8 00 00 00 00          mov    $0x0,%eax
  43:   e8 00 00 00 00          callq  48 <main+0x48>
  48:   48 8b 7d f8             mov    0xfffffffffffffff8(%rbp),%rdi
  4c:   e8 00 00 00 00          callq  51 <main+0x51>
  51:   c9                      leaveq 
  52:   c3                      retq   
[EMAIL PROTECTED]:~> readelf --relocs strange.o

Relocation section '.rela.text' at offset 0x6a8 contains 8 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + 
Addend
000000000010  000500000002 R_X86_64_PC32     0000000000000000 .rodata + 
fffffffffffffffc
000000000015  000b00000004 R_X86_64_PLT32    0000000000000000 dlopen + 
fffffffffffffffc
000000000024  000500000002 R_X86_64_PC32     0000000000000000 .rodata + 7
000000000029  000c00000004 R_X86_64_PLT32    0000000000000000 dlsym + 
fffffffffffffffc
000000000033  000d00000009 R_X86_64_GOTPCREL 0000000000000000 glutBitmap8By13 
+ fffffffffffffffc
00000000003a  000500000002 R_X86_64_PC32     0000000000000000 .rodata + 17
000000000044  000e00000004 R_X86_64_PLT32    0000000000000000 printf + 
fffffffffffffffc
00000000004d  000f00000004 R_X86_64_PLT32    0000000000000000 dlclose + 
fffffffffffffffc

Relocation section '.rela.eh_frame' at offset 0x768 contains 1 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + 
Addend
000000000020  000200000002 R_X86_64_PC32     0000000000000000 .text + 0
------------------------------------------------------------

Now we get a R_X86_64_GOTPCREL and things work as expected. Alas, our GHC 
Linker can't handle such a relocation, and somehow this has to work even in 
the non-PIC case. What we currently do in x86_64_high_symbol for the 
R_X86_64_32 relocation is completely wrong for data references, and this is 
even mentioned in the comment.

Still clueless,
   S.

_______________________________________________
Cvs-ghc mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/cvs-ghc

Reply via email to