The fallback atom was used only when it's searching for a symbol in a library;
if an undefined symbol was not found in a library, the LLD looked for its
fallback symbol in the library.
Although it worked in most cases, because symbols with fallbacks usually occur
only in OLDNAMES.LIB (a standard library), that behavior was incompatible with
link.exe. This patch fixes the issue so that the semantics is the same as
MSVC's link.exe
The new (and correct, I believe) behavior is this:
- If there's no definition for an undefined atom, replace the undefined atom
with its fallback and then proceed (e.g. look in the next file or stop
linking as usual.)
Weak External symbols are underspecified in the Microsoft PE/COFF spec. However,
as long as I observed the behavior of link.exe, this seems to be what we want
for compatibility.
Differential Revision: http://llvm-reviews.chandlerc.com/D2162
llvm-svn: 195269
We can add multiple undefined atoms having the same name to the symbol table.
If such atoms are added, the symbol table compares their canBeNull attributes,
and select one having a stronger constraint. If their canBeNulls are the same,
the choice is arbitrary. Currently it choose the existing one.
This patch changes the preference, so that the symbol table choose the new one
if the new atom has a greater canBeNull or a fallback atom. This shouldn't
change the behavior except the case described below.
A new undefined atom may have a new fallback atom attribute. By choosing the new
atom, we can update the fallback atom during Core Linking. PE/COFF actually need
that. For example, _lseek is an alias for __lseek on Windows. One of an object
file in OLDNAMES.LIB has an undefined atom for _lseek with the fallback to
__lseek. When the linker tries to resolve _read, it supposed to read the file
from OLDNAMES.LIB and use the new fallback from the file. Currently LLD cannot
handle such case because duplicate undefined atoms with the same attributes are
ignored.
Differential Revision: http://llvm-reviews.chandlerc.com/D2161
llvm-svn: 194777
This patch fixes a bug in r190608. The results of a comparison function
passed to std::sort must be transitive, which is, if a < b and b < c, and if
a != b, a < c must be also true. CompareAtoms::compare did not actually
guarantee the transitivity. As a result the sort results were sometimes just
wrong.
Consider there are three atoms, X, Y, and Z, whose file ordinals are 1, 2, 3,
respectively. Z has a property "layout-after X". In this case, all the
following conditionals become true:
X < Y because X's ordinal is less than Y's
Y < Z because Y's ordinal is less than Z's
Z < X because of the layout-after relationship
This is not of course transitive. The reason why this happened is because
we used follow-on relationships for comparison if two atoms falls in the same
follow-on chain, but we used each atom's properties if they did not. This patch
fixes the issue by using follow-on root atoms for comparison to get consistent
results.
Differential Revision: http://llvm-reviews.chandlerc.com/D1980
llvm-svn: 193029
In COFF, an undefined symbol can have up to one alternative name. If a symbol
is resolved by its regular name, then it's linked normally. If a symbol is not
found in any input files, all references to the regular name are resolved using
the alternative name. If the alternative name is not found, it's a link error.
This mechanism is called "weak externals".
To support this mechanism, I added a new member function fallback() to undefined
atom. If an undefined atom has the second name, fallback() returns a new undefined
atom that should be used instead of the original one to resolve undefines. If it
does not have the second name, the function returns nullptr.
Differential Revision: http://llvm-reviews.chandlerc.com/D1550
llvm-svn: 190625