diff options
| author | Rui Ueyama <ruiu@google.com> | 2013-11-20 20:51:55 +0000 |
|---|---|---|
| committer | Rui Ueyama <ruiu@google.com> | 2013-11-20 20:51:55 +0000 |
| commit | 70f11d7589738186588427ec8134e411ac43bad4 (patch) | |
| tree | 72b5c2d51ead83d36cddf9deef99f7c8bcc9a813 /lld/lib/Core/Resolver.cpp | |
| parent | f9329ff650fa252606c65977405189dc46e5d66f (diff) | |
| download | bcm5719-llvm-70f11d7589738186588427ec8134e411ac43bad4.tar.gz bcm5719-llvm-70f11d7589738186588427ec8134e411ac43bad4.zip | |
Fix Weak External symbol handling.
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
Diffstat (limited to 'lld/lib/Core/Resolver.cpp')
| -rw-r--r-- | lld/lib/Core/Resolver.cpp | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/lld/lib/Core/Resolver.cpp b/lld/lib/Core/Resolver.cpp index 5d9db38bec5..cdacc64a7eb 100644 --- a/lld/lib/Core/Resolver.cpp +++ b/lld/lib/Core/Resolver.cpp @@ -83,6 +83,16 @@ void Resolver::handleFile(const File &file) { for (const UndefinedAtom *undefAtom : file.undefined()) { doUndefinedAtom(*undefAtom); resolverState |= StateNewUndefinedAtoms; + + // If the undefined symbol has an alternative name, try to resolve the + // symbol with the name to give it a second chance. This feature is used for + // COFF "weak external" symbol. + if (!_symbolTable.isDefined(undefAtom->name())) { + if (const UndefinedAtom *fallbackAtom = undefAtom->fallback()) { + doUndefinedAtom(*fallbackAtom); + _symbolTable.addReplacement(undefAtom, fallbackAtom); + } + } } for (const SharedLibraryAtom *shlibAtom : file.sharedLibrary()) { doSharedLibraryAtom(*shlibAtom); @@ -108,15 +118,6 @@ Resolver::forEachUndefines(UndefCallback callback, bool searchForOverrides) { // load for previous undefine may also have loaded this undefine if (!_symbolTable.isDefined(undefName)) callback(undefName, false); - // If the undefined symbol has an alternative name, try to resolve the - // symbol with the name to give it a second chance. This feature is used - // for COFF "weak external" symbol. - if (!_symbolTable.isDefined(undefName)) { - if (const UndefinedAtom *fallbackUndefAtom = undefAtom->fallback()) { - _symbolTable.addReplacement(undefAtom, fallbackUndefAtom); - _symbolTable.add(*fallbackUndefAtom); - } - } } // search libraries for overrides of common symbols if (searchForOverrides) { |

