Pre-link static binaries/remove

Thomas Richter thomas.richter@iis.fraunhofer.de
Tue Nov 11 12:22:33 GMT 2025


Hi Simon,

>> is there a possibility to remove from a static library (not from 
>> a .so) all symbols marked as "visibility ("hidden")"?
> 
> No, because these symbols are still required while linking against the 
> static library.
> 
> Typically, libraries will have internal functions that are not visible 
> to users, and these are called from different externally visible 
> functions. The internal and external functions would then be defined in 
> different translation units, to allow removing unused functions, but the 
> reference to the internal function from the translation unit containing 
> the symbol that is referenced by the external program will still need to 
> be resolved.
> 
> Because that internal function is not externally visible, it will be 
> declared with "hidden" visibility, but it cannot be removed before 
> internal references are resolved. The symbol will not be copied to the 
> dynamic symbol tables, so if you call "strip" on the final executable, 
> the symbol will be removed from the final output.
So please excuse my ignorance. From what I understand, the static 
library is just a collection of objects resulting from the compilation 
units of the source. Got it. However, that's why I'm asking whether some 
sort of pre-linking is possible, namely to collect all the (individual) 
objects, merge them in a single object, create from that a single object 
in the link library, and while doing so, resolve all the "internal" 
symbols between the units.

So consider I have two compilation units resulting in a.o and b.o.
a.o has an "external" symbol foo(), but calls into an internal 
("hidden") symbol bar() in b.o.

Clearly, as long as a.o and b.o exist as independent objects in the 
final library, bar() cannot be removed. It will be removed in the final 
step when creating a .so. However, would it be possible to merge a.o and 
b.o into "merged.o" - a single unit - and by doing so, resolve the call 
of "bar()" already by replacing it by a "relative branch" from one part 
of the unit to another.

I'm asking this question because I know the answer from another (albeit 
ancient) platform ("amiga hunk format") where of course the same problem 
appears, and there, at least, "pre-linking" is a possibility which 
merges the hunks ("compilation units") into one common unit, and by 
doing so, resolves all symbols between the hunks such that they could be 
removed.

So I hope I was making myself clear.

Thanks,
	Thomas



More information about the Binutils mailing list