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