Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does gcc `-shared` option affect the output?

Technically, in terms of file content, what is the difference between the output of gcc -fPIC -shared src.c and gcc -fPIC src.c?

Assume that int main(int, char**) is defined in src.c so that both compilations succeed. But executing the a.out generated by gcc -shared src.c, as expected, gave the following error:

-bash: ./a_shared.out: cannot execute binary file

Even if there is a main function it it.

Also, how can I inspect the difference in the output files using tools like otool or objdump?

Thanks a lot.

like image 550
Dale Z Avatar asked Aug 01 '14 16:08

Dale Z


People also ask

What does shared do in gcc?

As per Difference between -shared and -Wl,-shared of the GCC options Passing -shared to GCC may enable or disable other flags at link time. As per my understanding if an executable has shared library, size of executable is very less. The executable will not run until the shared library is present and correctly linked.

Which option of gcc compiler provides the linking with shared libraries?

6. Which option of GCC compiler provides the linking with shared libraries? Explanation: None.

How does gcc compiler work?

After the file is preprocessed, gcc moves it to the compiler. The compiler turns each line in the preprocessed file into assembly language, which are instructions in English mnemonics that have strong one-to-one correspondence to the machine code that computers can read.

What option should be added to a gcc command in order to link in functions from a library?

Short answer: If you want to use functions from the math library in C, it's not enough to put #include<math. h> at the top of your source code. In addition, you must add the - lm flag to the gcc compiler command in order to use math functions in your C code.


2 Answers

As per https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html#Link-Options -shared option does the following

  • Produce a shared object which can then be linked with other objects to form an executable.

  • Not all systems support this option.

  • For predictable results, you must also specify the same set of options used for compilation (-fpic, -fPIC, or model suboptions) when you specify this linker option.

As per Difference between -shared and -Wl,-shared of the GCC options Passing -shared to GCC may enable or disable other flags at link time.

As per my understanding if an executable has shared library, size of executable is very less. The executable will not run until the shared library is present and correctly linked. Advantage of using shared library is that if we have a very big code base, we need not build the entire code always every time. We just need to rebuild the .so file and link it to executable. This saves a lot of time.

And in case for an executabe without shared library, executable size will be very large. For every code change entire code needs to be builded, which can be very time consuming.

like image 145
rohit Avatar answered Oct 17 '22 04:10

rohit


Shared libraries and executables use the same format: they are both loadable images. However,

  1. Shared libraries are usually position-independent, executables are often not. This affects code generation: for position-independent, you have to load globals or jump to functions using relative addresses.

  2. Executables have an "entry point" which is where execution starts. This is usually not main(), because main() is a function, and functions return, but execution should never return from the entry point.

Now, this doesn't answer the question about what -shared does. You can ask GCC by using the -v flag. Here are the differences on my system between an invocation without and with -shared.

Parameters for collect2 without -shared:

-dynamic-linker
/lib64/ld-linux-x86-64.so.2
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crt1.o
/usr/lib/gcc/x86_64-linux-gnu/4.7/crtbegin.o
/usr/lib/gcc/x86_64-linux-gnu/4.7/crtend.o

Parameters for collect2 with -shared:

-shared
/usr/lib/gcc/x86_64-linux-gnu/4.7/crtbeginS.o
/usr/lib/gcc/x86_64-linux-gnu/4.7/crtendS.o

Observations

It looks like code generation is not affected: you still have to use -fpic or -fPIC.

You can see that crt1.o (the "C runtime") is only included when linking the executable. Using nm, we can find out what it contains:

$ nm /usr/lib/x86_64-linux-gnu/crt1.o
0000000000000000 R _IO_stdin_used
0000000000000000 D __data_start
                 U __libc_csu_fini
                 U __libc_csu_init
                 U __libc_start_main
0000000000000000 T _start
0000000000000000 W data_start
                 U main

So you can see it seems to define something to do with stdin, as well as _start (which is the entry point), and it has an undefined reference to main.

I'm not sure what the rest of the files are, but at least you know how to find them and you can poke around, or look at the source code if you like.

like image 31
Dietrich Epp Avatar answered Oct 17 '22 02:10

Dietrich Epp