当前位置: 技术问答>linux和unix
用gcc怎么编译出真正的位置无关的代码?
来源: 互联网 发布时间:2016-04-10
本文导语: -fPIC选项编译出来的也是固定到某个地址了,加载器加载的时候再重定位,如下 但是我想编译一个库,指定一个基地址,也就是我想让代码加载到的地址,怎么编译呢? 谢谢 test13.so: file format pei-i386 Disa...
-fPIC选项编译出来的也是固定到某个地址了,加载器加载的时候再重定位,如下
但是我想编译一个库,指定一个基地址,也就是我想让代码加载到的地址,怎么编译呢?
谢谢
test13.so: file format pei-i386
Disassembly of section .text:
10001000 :
10001000: 55 push %ebp
10001001: 89 e5 mov %esp,%ebp
10001003: 83 ec 08 sub $0x8,%esp
10001006: 83 c4 f8 add $0xfffffff8,%esp
10001009: 8b 45 0c mov 0xc(%ebp),%eax
1000100c: 50 push %eax
1000100d: 8b 45 08 mov 0x8(%ebp),%eax
10001010: 50 push %eax
10001011: e8 16 00 00 00 call 1000102c
10001016: 83 c4 10 add $0x10,%esp
10001019: 8b 45 08 mov 0x8(%ebp),%eax
1000101c: 8b 4d 0c mov 0xc(%ebp),%ecx
1000101f: 8d 14 01 lea (%ecx,%eax,1),%edx
10001022: 89 d0 mov %edx,%eax
10001024: eb 02 jmp 10001028
10001026: 89 f6 mov %esi,%esi
10001028: 89 ec mov %ebp,%esp
1000102a: 5d pop %ebp
1000102b: c3 ret
1000102c :
1000102c: 55 push %ebp
1000102d: 89 e5 mov %esp,%ebp
1000102f: 83 ec 24 sub $0x24,%esp
10001032: 53 push %ebx
10001033: 8b 45 08 mov 0x8(%ebp),%eax
10001036: 89 45 fc mov %eax,0xfffffffc(%ebp)
10001039: 8d 5d 0c lea 0xc(%ebp),%ebx
1000103c: 8b 45 fc mov 0xfffffffc(%ebp),%eax
1000103f: 99 cltd
10001040: f7 3b idivl (%ebx)
10001042: 89 c1 mov %eax,%ecx
10001044: 89 c8 mov %ecx,%eax
10001046: eb 00 jmp 10001048
10001048: 8b 5d d8 mov 0xffffffd8(%ebp),%ebx
1000104b: 89 ec mov %ebp,%esp
1000104d: 5d pop %ebp
1000104e: c3 ret
1000104f: 90 nop
但是我想编译一个库,指定一个基地址,也就是我想让代码加载到的地址,怎么编译呢?
谢谢
test13.so: file format pei-i386
Disassembly of section .text:
10001000 :
10001000: 55 push %ebp
10001001: 89 e5 mov %esp,%ebp
10001003: 83 ec 08 sub $0x8,%esp
10001006: 83 c4 f8 add $0xfffffff8,%esp
10001009: 8b 45 0c mov 0xc(%ebp),%eax
1000100c: 50 push %eax
1000100d: 8b 45 08 mov 0x8(%ebp),%eax
10001010: 50 push %eax
10001011: e8 16 00 00 00 call 1000102c
10001016: 83 c4 10 add $0x10,%esp
10001019: 8b 45 08 mov 0x8(%ebp),%eax
1000101c: 8b 4d 0c mov 0xc(%ebp),%ecx
1000101f: 8d 14 01 lea (%ecx,%eax,1),%edx
10001022: 89 d0 mov %edx,%eax
10001024: eb 02 jmp 10001028
10001026: 89 f6 mov %esi,%esi
10001028: 89 ec mov %ebp,%esp
1000102a: 5d pop %ebp
1000102b: c3 ret
1000102c :
1000102c: 55 push %ebp
1000102d: 89 e5 mov %esp,%ebp
1000102f: 83 ec 24 sub $0x24,%esp
10001032: 53 push %ebx
10001033: 8b 45 08 mov 0x8(%ebp),%eax
10001036: 89 45 fc mov %eax,0xfffffffc(%ebp)
10001039: 8d 5d 0c lea 0xc(%ebp),%ebx
1000103c: 8b 45 fc mov 0xfffffffc(%ebp),%eax
1000103f: 99 cltd
10001040: f7 3b idivl (%ebx)
10001042: 89 c1 mov %eax,%ecx
10001044: 89 c8 mov %ecx,%eax
10001046: eb 00 jmp 10001048
10001048: 8b 5d d8 mov 0xffffffd8(%ebp),%ebx
1000104b: 89 ec mov %ebp,%esp
1000104d: 5d pop %ebp
1000104e: c3 ret
1000104f: 90 nop
|
lz的例子是在Windows下面的吧?“pei-i386”. Windows下面PE格式都是先设定一个再重定位。
Linux下面就是要么通过PC偏移量(代码段),要么通过GOT指针(%ebx)间接访问movl (%ebx + offset), %eax
Linux/x86_64全部都是PC偏移量访问,因为x86_64支持了类似mov (%pc + offset), %eax这样的指令。
Linux下面就是要么通过PC偏移量(代码段),要么通过GOT指针(%ebx)间接访问movl (%ebx + offset), %eax
Linux/x86_64全部都是PC偏移量访问,因为x86_64支持了类似mov (%pc + offset), %eax这样的指令。