diff options
| author | Rui Ueyama <ruiu@google.com> | 2013-09-12 19:14:05 +0000 |
|---|---|---|
| committer | Rui Ueyama <ruiu@google.com> | 2013-09-12 19:14:05 +0000 |
| commit | e5416ec2d21854f34801c33ef567072d3e647f6f (patch) | |
| tree | f216f2c3028f202636221ce64abf9cf5a3dbfeb3 /lld/lib/Core/Resolver.cpp | |
| parent | 1e2e3ea584121f523aa4118f383927ed6b73246c (diff) | |
| download | bcm5719-llvm-e5416ec2d21854f34801c33ef567072d3e647f6f.tar.gz bcm5719-llvm-e5416ec2d21854f34801c33ef567072d3e647f6f.zip | |
Add a fallback mechanism for undefined atom.
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
Diffstat (limited to 'lld/lib/Core/Resolver.cpp')
| -rw-r--r-- | lld/lib/Core/Resolver.cpp | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/lld/lib/Core/Resolver.cpp b/lld/lib/Core/Resolver.cpp index d56f7d1067f..716f0d48d53 100644 --- a/lld/lib/Core/Resolver.cpp +++ b/lld/lib/Core/Resolver.cpp @@ -198,7 +198,7 @@ void Resolver::resolveUndefines() { undefineGenCount = _symbolTable.size(); std::vector<const UndefinedAtom *> undefines; _symbolTable.undefines(undefines); - for ( const Atom *undefAtom : undefines ) { + for (const UndefinedAtom *undefAtom : undefines) { StringRef undefName = undefAtom->name(); // load for previous undefine may also have loaded this undefine if (!_symbolTable.isDefined(undefName)) { @@ -208,6 +208,13 @@ void Resolver::resolveUndefines() { false, // dataSymbolOnly *this); } + // 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 (const UndefinedAtom *fallbackUndefAtom = undefAtom->fallback()) { + _symbolTable.addReplacement(undefAtom, fallbackUndefAtom); + _symbolTable.add(*fallbackUndefAtom); + } } // search libraries for overrides of common symbols if (searchArchives || searchSharedLibs) { |

