cgcccompiler-optimizationfpic

fpic and O3 optimization flags


I'm trying to compile main.c which uses libnothing.so. Here is the source code:

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);

First I compile nothing.c like this without fpic: gcc -c nothing.c I'll get this error: /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 when building the .so gcc -shared nothing.o -o libnothing.so

But if I compile it using O3 gcc -c -O3 nothing.c I don't get the relocation error anymore.

Is -O3 adding fpic by default ?

EDIT

I changed a bit the code by adding void as suggested in the comments, removed static from doNothingStatic and add some dummy work in it.

Here is the console output when running the commands:

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

I also looked on the assembly that objdump provides:

    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  

Indeed it seems the functions are inlined when using -O3


Solution

  • No, it is just that the function doNothing was inlined and thus there were no intra-module function calls left.

    The relocation type means an absolute function or data access using a sign-extended 32-bit pointer, i.e. basically something within the first 2 GiB of virtual memory. When compiled with -O3 all function calls were inlined and therefore the calls using the relocations are not needed.