I'm afraid not.
The compiled binary file has been processed through relocation phase by the linker, which associate each symbol reference in the code with a run-time address.
You can do a simple experiment to find out the differences, here is a program which output 'Hello World':
// main.c
#include <stdio.h>
int main()
{
printf("Hello World!");
return 0;
}
Using gcc -c
you can compile the source code into a relocatable object:
$ gcc -c main.o
$ readelf -s main.o
Symbol table '.symtab' contains 10 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 FILE LOCAL DEFAULT ABS main.c
2: 00000000 0 SECTION LOCAL DEFAULT 1
3: 00000000 0 SECTION LOCAL DEFAULT 3
4: 00000000 0 SECTION LOCAL DEFAULT 4
5: 00000000 0 SECTION LOCAL DEFAULT 5
6: 00000000 0 SECTION LOCAL DEFAULT 7
7: 00000000 0 SECTION LOCAL DEFAULT 6
8: 00000000 29 FUNC GLOBAL DEFAULT 1 main
9: 00000000 0 NOTYPE GLOBAL DEFAULT UND printf
You can see from here the value of function main is 0x0, which means it has not yet been relocated and can be linked with others.
But when you compile the file with gcc
command, to generated an executable one:
$ gcc main.c
$ readelf -s a.out | grep main
2: 00000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.0 (2)
39: 00000000 0 FILE LOCAL DEFAULT ABS main.c
51: 00000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@@GLIBC_
62: 080483c4 29 FUNC GLOBAL DEFAULT 13 main
Now you can see the address of function main has been relocated to 0x80483c4, which is the runtime address of the function code. The generate a.out
can no longer get linked with others, since there may be runtime address violation to do so.
Generally speaking the relocation phase cannot be reverted, because some symbol information get lost after the phase.
For more details I suggest you to read the Linking chapter in the book Computer System: A Programmer's Prospective, which covers a lot in linking and relocation.