lol lol
lol lol

Reputation: 491

Why shared library linked with static library behaves like it was linked with dynamic one?

It is unclear to me why final shared .so library calls functions from the static .a library as:

callq  1050 <add@plt>

I expect to see there something like:

callq  115b <add>

Let me explain by example.

Suppose we have following files.

int add(int a, int b)
{
    return a+b;
}
extern int add(int a, int b);

int use_add_from_shared_library_1(int a, int b)
{
    return add(a, b);
}

int main() { return 0; }

Lets compile static library (for the convenience):

CC=gcc;
${CC} -c -fPIC static_library.c -o static_library.o;
ar rcs libstatic_library.a static_library.o;

Now lets compile shared library and link to it previously compiled static library:

CC=gcc;
${CC} -c -fPIC shared_library.c -o shared_library.o;
${CC} -shared shared_library.o -L./ -lstatic_library -o shared_library.so;

There will be no errors. However, "objdump" of the shared library will contain the disassembler code:

$ objdump -dS shared_library.so | grep "callq" | grep "add";
    1135:   e8 16 ff ff ff          callq  1050 <add@plt>

P.S. Single-shell example:

echo '
int add(int a, int b)
{
    return a+b;
}
' \
  > static_library.c; \
\
echo '
extern int add(int a, int b);

int use_add_from_shared_library_1(int a, int b)
{
    return add(a, b);
}

int main() { return 0; }
' \
  > shared_library.c; \
\
CC=gcc; \
\
${CC} -c -fPIC static_library.c -o static_library.o; \
ar rcs libstatic_library.a static_library.o; \
\
${CC} -c -fPIC shared_library.c -o shared_library.o; \
${CC} -shared shared_library.o -L./ -lstatic_library -o shared_library.so; \
\
objdump -dS shared_library.so | grep "callq" | grep "add";

Upvotes: 0

Views: 1629

Answers (1)

John Bollinger
John Bollinger

Reputation: 180201

Shared libraries and static libraries are very different beasts.

A static library is literally an archive file, similar to a .tar file, whose contents are object files. Typically these are augmented with an index of the external symbols defined in the object files. During static linking, the linker extracts some or all of those object files from the library and links those with any other specified objects, pretty much as if the extracted object files had been specified directly. There is no inherent distinction between external symbols based on which object provided them, or on whether that object was drawn from a (static) library.

Shared libraries are integrated objects, very much along the lines of programs. They can be executable programs. There are no individual object files within. In shared-library formats that feature position-independent code, all external symbols provided by the library must be position-independent.

When you link a static library into a shared one, you are asking the linker to include the contents of some or all of the object files from the static library in the resulting shared library. That's the only way it can work. The external symbols resolved from the static library will be external symbols in the shared one, too, so references to them need to be relative, including from other functions in the shared lib.

Upvotes: 1

Related Questions