Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing internal symbols from C static library

I'm working on some embedded code that is shipped as a static library. We would like to remove all internal symbols from the library and keep only the API symbols visible.

Here's an example of what we want to do: imagine that you have a file called internal.c and one called api.c that look like that:

/* internal.c */

int fibonacci(int n)
{
    /* Compute the nth Fibonacci number and return it */
}


/* api.c */

#include "internal.h"
#include <stdio.h>

void print_fibonacci(n)
{
    printf("Fibonacci(%d): %d\n", n, fibonacci(n));
}

The user should only have access to the print_fibonacci function while all internal symbols such as the fibonacci function should be resolved before shipping. That means that the user should be able to define his own function called fibonacci without having to worry about conflicts with the library.

We already tried internal linkage by using ld --relocatable, but we can't seem to remove the symbols afterwards using objcopy. Is this feasible at all?

Thanks for the help!

Edit: The user-defined fibonacci function should not replace the library-defined function, they should just be able to coexist. Basically I'm looking for a solution to solve naming conflicts.

like image 529
Olivier Desenfans Avatar asked Jul 31 '14 11:07

Olivier Desenfans


People also ask

How do you remove symbols from a static library?

Strip. If you still see symbols that shouldn't be in there in the file when checking your build product using nm , you may have to call strip -r -S -x on your library, which will remove debug symbols and “local” symbols.

Do static libraries have symbols?

A .o file inside a library might contain symbols (functions, variables etc.) that are not used by your program. At link time, a static library can have unresolved symbols in it, as long as you don't need the unresolved symbols, and you don't need any symbol that is in a .o file that contains an unresolved symbol.

How to dynamically link a library in C?

Dynamic linking and Dynamic Libraries Dynamic Linking doesn't require the code to be copied, it is done by just placing name of the library in the binary file. The actual linking happens when the program is run, when both the binary file and the library are in memory.


1 Answers

Static libraries are essentially a bunch of object files. All object files in a static library are treated as if they were provided individually by the linker. Generally, it is not possible to make the linker treat some symbols as internal, the linker simply does not have enough information to do so.

Here are a couple of strategies to solve these issues:

  • Construct a separate name space for non-public functions in your library. For instance, your fibonacci function can be placed in an internal name space libfoo_internal_fibonacci. If you're desparate, you can use macros in your internal header files like this:

    #define fibonacci INTERNAL_PREFIX ## fibonacci
    

    This would allow you to change the prefix arbitrarily on compile time. I suggest to not do that as it makes debugging harder. If you can cope with longer internal names, this would be a good strategy.

  • Make all internal functions static and merge translation units so that each internal function is only used by one translation unit. This might solve your problem but it makes the resulting programs larger: Most linkers can either take an object as a whole or not take it at all. You might end up with lots of dead code in the program if the linker has to include huge object files if you want to use just a single function.

  • Turn your library into a shared library and use mapfiles or a different mechanism to specify which symbols are supposed to be exported. This is the best option in my opinion but it's not totally portable and perhaps you really want your library to remain static.

like image 120
fuz Avatar answered Oct 16 '22 11:10

fuz