fpic和O3优化标志

时间:2019-07-28 23:03:05

标签: c gcc compiler-optimization fpic

我正在尝试编译使用libnothing.so的main.c。这是源代码:

main.c

#include "nothing.h"

int main(void)
{
    doAlmostNothing();
    return 0;
}

没事。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);

首先,我不编译任何东西。c没有fpic:gcc -c nothing.c在构建.so /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

时,我会收到此错误: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   $0x2d,-0x4(%rbp)
       b:   8b 45 fc                mov    -0x4(%rbp),%eax
       e:   83 c0 01                add    $0x1,%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   $0x2d,-0x4(%rsp)
       7:   00 
       8:   8b 44 24 fc             mov    -0x4(%rsp),%eax
       c:   83 c0 01                add    $0x1,%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   $0x2d,-0x4(%rsp)
      37:   00 
      38:   8b 44 24 fc             mov    -0x4(%rsp),%eax
      3c:   83 c0 01                add    $0x1,%eax
      3f:   89 44 24 fc             mov    %eax,-0x4(%rsp)
      43:   c3                      retq  

实际上,使用-O3时似乎内联了函数

2 个答案:

答案 0 :(得分:3)

否,只是函数doNothing被内联,因此没有模块内函数调用。

relocation type表示使用符号扩展的32位指针进行的绝对功能或数据访问,即基本上在虚拟内存的前2 GiB之内。使用-O3进行编译时,所有函数调用都已内联,因此不需要使用重定位的调用。

答案 1 :(得分:1)

否,-O3无法打开-fPIC
这是由不同的优化级别启用的标志的列表。
https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html