fpic 和 O3 优化标志
fpic and O3 optimization flags
我正在尝试编译使用 libnothing.so 的 main.c。这是源代码:
main.c
#include "nothing.h"
int main(void)
{
doAlmostNothing();
return 0;
}
nothing.c
#include "nothing.h"
void doNothingStatic(void) {
volatile int x = 45;
x++;
}
void doNothing(void) {}
void doAlmostNothing(void)
{
doNothingStatic();
doNothing();
}
nothing.h
void doAlmostNothing(void);
首先,我在没有 fpic 的情况下像这样编译 nothing.c:gcc -c nothing.c
我会得到这个错误:/usr/bin/ld: nothing.o: relocation R_X86_64_PC32 against symbol doNothing can not be used when making a shared object; recompile with -fPIC
在构建 .so gcc -shared nothing.o -o libnothing.so
时
但是如果我使用 O3 gcc -c -O3 nothing.c
编译它,我就不会再收到重定位错误了。
-O3 是否默认添加 fpic?
编辑
我按照评论中的建议通过添加 void 对代码进行了一些更改,从 doNothingStatic 中删除了 static 并在其中添加了一些虚拟工作。
这是 运行 命令时的控制台输出:
bil@bil-VirtualBox:~/Documents/test/linking$ gcc-7 -c nothing.c
bil@bil-VirtualBox:~/Documents/test/linking$ gcc-7 -shared nothing.o -o nothing.so
/usr/bin/ld: nothing.o: relocation R_X86_64_PC32 against symbol `doNothingStatic' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
bil@bil-VirtualBox:~/Documents/test/linking$ gcc-7 -c -O3 nothing.c
bil@bil-VirtualBox:~/Documents/test/linking$ gcc-7 -shared nothing.o -o libnothing.so
bil@bil-VirtualBox:~/Documents/test/linking$ ls
libnothing.so main main.c main.o nothing.c nothing.h nothing.o libnothing.so
我也看了objdump提供的程序集:
- 没有 O3:
nothing.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <doNothingStatic>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: c7 45 fc 2d 00 00 00 movl [=14=]x2d,-0x4(%rbp)
b: 8b 45 fc mov -0x4(%rbp),%eax
e: 83 c0 01 add [=14=]x1,%eax
11: 89 45 fc mov %eax,-0x4(%rbp)
14: 90 nop
15: 5d pop %rbp
16: c3 retq
0000000000000017 <doNothing>:
17: 55 push %rbp
18: 48 89 e5 mov %rsp,%rbp
1b: 90 nop
1c: 5d pop %rbp
1d: c3 retq
000000000000001e <doAlmostNothing>:
1e: 55 push %rbp
1f: 48 89 e5 mov %rsp,%rbp
22: e8 00 00 00 00 callq 27 <doAlmostNothing+0x9>
27: e8 00 00 00 00 callq 2c <doAlmostNothing+0xe>
2c: 90 nop
2d: 5d pop %rbp
2e: c3 retq
- 与 O3
nothing.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <doNothingStatic>:
0: c7 44 24 fc 2d 00 00 movl [=15=]x2d,-0x4(%rsp)
7: 00
8: 8b 44 24 fc mov -0x4(%rsp),%eax
c: 83 c0 01 add [=15=]x1,%eax
f: 89 44 24 fc mov %eax,-0x4(%rsp)
13: c3 retq
14: 66 90 xchg %ax,%ax
16: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
1d: 00 00 00
0000000000000020 <doNothing>:
20: f3 c3 repz retq
22: 0f 1f 40 00 nopl 0x0(%rax)
26: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
2d: 00 00 00
0000000000000030 <doAlmostNothing>:
30: c7 44 24 fc 2d 00 00 movl [=15=]x2d,-0x4(%rsp)
37: 00
38: 8b 44 24 fc mov -0x4(%rsp),%eax
3c: 83 c0 01 add [=15=]x1,%eax
3f: 89 44 24 fc mov %eax,-0x4(%rsp)
43: c3 retq
确实,当使用 -O3
时,函数似乎是内联的
不,只是函数 doNothing
是内联的,因此没有剩余的模块内函数调用。
relocation type 表示使用符号扩展的 32 位指针的绝对函数或数据访问,即基本上是前 2 GiB 虚拟内存中的某些内容。当使用 -O3
编译时,所有函数调用都是内联的,因此不需要使用重定位的调用。
否,-O3
未开启 -fPIC
。
这是不同优化级别打开的标志列表。
https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
我正在尝试编译使用 libnothing.so 的 main.c。这是源代码:
main.c
#include "nothing.h"
int main(void)
{
doAlmostNothing();
return 0;
}
nothing.c
#include "nothing.h"
void doNothingStatic(void) {
volatile int x = 45;
x++;
}
void doNothing(void) {}
void doAlmostNothing(void)
{
doNothingStatic();
doNothing();
}
nothing.h
void doAlmostNothing(void);
首先,我在没有 fpic 的情况下像这样编译 nothing.c:gcc -c nothing.c
我会得到这个错误:/usr/bin/ld: nothing.o: relocation R_X86_64_PC32 against symbol doNothing can not be used when making a shared object; recompile with -fPIC
在构建 .so gcc -shared nothing.o -o libnothing.so
但是如果我使用 O3 gcc -c -O3 nothing.c
编译它,我就不会再收到重定位错误了。
-O3 是否默认添加 fpic?
编辑
我按照评论中的建议通过添加 void 对代码进行了一些更改,从 doNothingStatic 中删除了 static 并在其中添加了一些虚拟工作。
这是 运行 命令时的控制台输出:
bil@bil-VirtualBox:~/Documents/test/linking$ gcc-7 -c nothing.c
bil@bil-VirtualBox:~/Documents/test/linking$ gcc-7 -shared nothing.o -o nothing.so
/usr/bin/ld: nothing.o: relocation R_X86_64_PC32 against symbol `doNothingStatic' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
bil@bil-VirtualBox:~/Documents/test/linking$ gcc-7 -c -O3 nothing.c
bil@bil-VirtualBox:~/Documents/test/linking$ gcc-7 -shared nothing.o -o libnothing.so
bil@bil-VirtualBox:~/Documents/test/linking$ ls
libnothing.so main main.c main.o nothing.c nothing.h nothing.o libnothing.so
我也看了objdump提供的程序集:
- 没有 O3:
nothing.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <doNothingStatic>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: c7 45 fc 2d 00 00 00 movl [=14=]x2d,-0x4(%rbp)
b: 8b 45 fc mov -0x4(%rbp),%eax
e: 83 c0 01 add [=14=]x1,%eax
11: 89 45 fc mov %eax,-0x4(%rbp)
14: 90 nop
15: 5d pop %rbp
16: c3 retq
0000000000000017 <doNothing>:
17: 55 push %rbp
18: 48 89 e5 mov %rsp,%rbp
1b: 90 nop
1c: 5d pop %rbp
1d: c3 retq
000000000000001e <doAlmostNothing>:
1e: 55 push %rbp
1f: 48 89 e5 mov %rsp,%rbp
22: e8 00 00 00 00 callq 27 <doAlmostNothing+0x9>
27: e8 00 00 00 00 callq 2c <doAlmostNothing+0xe>
2c: 90 nop
2d: 5d pop %rbp
2e: c3 retq
- 与 O3
nothing.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <doNothingStatic>:
0: c7 44 24 fc 2d 00 00 movl [=15=]x2d,-0x4(%rsp)
7: 00
8: 8b 44 24 fc mov -0x4(%rsp),%eax
c: 83 c0 01 add [=15=]x1,%eax
f: 89 44 24 fc mov %eax,-0x4(%rsp)
13: c3 retq
14: 66 90 xchg %ax,%ax
16: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
1d: 00 00 00
0000000000000020 <doNothing>:
20: f3 c3 repz retq
22: 0f 1f 40 00 nopl 0x0(%rax)
26: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
2d: 00 00 00
0000000000000030 <doAlmostNothing>:
30: c7 44 24 fc 2d 00 00 movl [=15=]x2d,-0x4(%rsp)
37: 00
38: 8b 44 24 fc mov -0x4(%rsp),%eax
3c: 83 c0 01 add [=15=]x1,%eax
3f: 89 44 24 fc mov %eax,-0x4(%rsp)
43: c3 retq
确实,当使用 -O3
时,函数似乎是内联的不,只是函数 doNothing
是内联的,因此没有剩余的模块内函数调用。
relocation type 表示使用符号扩展的 32 位指针的绝对函数或数据访问,即基本上是前 2 GiB 虚拟内存中的某些内容。当使用 -O3
编译时,所有函数调用都是内联的,因此不需要使用重定位的调用。
否,-O3
未开启 -fPIC
。
这是不同优化级别打开的标志列表。
https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html