I was wondering what exactly is stored in a .o or a .so file that results from compiling a C++ program. This post gives a quite good overview of the compilation process and the function of a .o file in it, and as far as I understand from this post, .a and .so files are just multiple .o files merged into a single file that is linked in a static (.a) or dynamic (.so) way.
But I wanted to check if I understand correctly what is stored in such a file. After compiling the following code
void f();
void f2(int);
const int X = 25;
void g() {
f();
f2(X);
}
void h() {
g();
}
I would expect to find the following items in the .o file:
- Machine code for
g()
, containing some placeholder addresses wheref()
andf2(int)
are called. - Machine code for
h()
, with no placeholders - Machine code for
X
, which would be just the number25
- Some kind of table that specifies at which addresses in the file the symbols
g()
,h()
andX
can be found - Another table that specifies which placeholders were used to refer to the undefined symbols
f()
andf2(int)
, which have to be resolved during linking.
Then a program like nm
would list all the symbol names from both tables.
I suppose that the compiler could optimize the call f2(X)
by calling f2(25)
instead, but it would still need to keep the symbol X in the .o file since there is no way to know if it will be used from a different .o file.
Would that be about correct? Is it the same for .a and .so files?
Thanks for your help!