首页 > 解决方案 > fpic 和 O3 优化标志

问题描述

我正在尝试编译使用 libnothing.so 的 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();
}

什么都没有

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 中删除静态并在其中添加一些虚拟工作。

这是运行命令时的控制台输出:

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 提供的程序集:

    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   
    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 时似乎函数是内联的

标签: cgcccompiler-optimizationfpic

解决方案


不,只是函数doNothing被内联了,因此没有剩下的模块内函数调用。

定位类型是指使用符号扩展的 32 位指针的绝对函数或数据访问,即基本上在虚拟内存的前 2 GiB 内。当编译时-O3所有函数调用都被内联,因此不需要使用重定位的调用。


推荐阅读