1

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:

  • without 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   
  • with 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  

Indeed it seems the functions are inlined when using -O3

user1934513
  • 693
  • 4
  • 21
  • Wholly tangential to your question — but, for the code shown, you should use `int main(void)` since you pay no heed to the command line arguments. The `const` in the version you're using isn't explicitly sanctioned by the standard, though it probably does no harm. – Jonathan Leffler Jul 28 '19 at 23:14
  • It would be worth identifying which version of GCC you're using, and which version of `ld` (`gcc --version` and `ld --version` should produce the information), and which platform you're working on. You might also note that there isn't a prototype in sight for any of the functions except `main()`. You've declared the functions, but not specified the argument list. Use an explicit `(void)` argument list in declarations and definitions to indicate "no arguments". What you've said is "undefined but not variadic (no `, ...`) argument list". – Jonathan Leffler Jul 28 '19 at 23:21
  • 1
    Your explanation might be easier if you represented the terminal session in the question: `$ gcc -c nothing.c` — `$ gcc -shared nothing.o -o libnothing.so` — …error message… — `$ gcc -c -O3 nothing.c` — `$gcc -shared nothing.o -o libnothing.so` — `$` (emphasizing 'no error message' for the last command). And if you can't type the 4 commands as shown, then you know there was something amiss. – Jonathan Leffler Jul 28 '19 at 23:24

2 Answers2

4

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.

  • Thanks for the hint. One quick question. In this article ( https://cseweb.ucsd.edu/~gbournou/CSE131/the_inside_story_on_shared_libraries_and_dynamic_loading.pdf ) at page 7 it states that shared libraries can be built without fpic if you need extra performance. How is it possible to do that since ld will always complain that it needs the -fpic flag? – user1934513 Jul 29 '19 at 05:43
1

No, -O3 does not turn on -fPIC.
Here is the a list of flags turned on by the different optimization levels.
https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

Niklas1
  • 148
  • 2
  • 10