On 12/30/18, ron(a)ronnatalie.com <ron(a)ronnatalie.com> wrote:
Yes, it pretty much has to be this way as it is a
single pass process and
the ar format is simple.
Early ld only made a single pass over each library on the command
line? Interesting. Most linkers (all modern ones?) make repeated
passes over a library until a pass doesn't resolve any symbols; only
then does the linker go on to the next library or object module on the
command line. A single pass link makes some sense, though, on a
resource-constrained system--it's easier to implement, and a
multi-pass link has O(N**2) worst-case behavior.
ranlib greatly speeds up the link process, but early implementations
of ranlib had a problem (I would call it a bug): they indexed common
symbols as well as globals. Common symbol semantics require that if
an undefined external resolves against a common symbol, that in itself
is not enough to cause the object module to be loaded. So even with
ranlib it's necessary for the linker to process the symbol table of
each module that gets a hit when the ranlib index is processed, and to
ignore instances where the resolution is against a common symbol. ld
had a bug in this area that caused common symbol sizes to be maximized
improperly, and one of the stdio modules had a dependency on this bug.
Later versions of UNIX didn't have this bug; I don't know whether it
was ld or the stdio module that was fixed (I suspect the latter).
-Paul W.