aboutsummaryrefslogtreecommitdiff
path: root/lld/MachO/SymbolTable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/MachO/SymbolTable.cpp')
-rw-r--r--lld/MachO/SymbolTable.cpp46
1 files changed, 42 insertions, 4 deletions
diff --git a/lld/MachO/SymbolTable.cpp b/lld/MachO/SymbolTable.cpp
index 283edf24ab06..825242f2cc72 100644
--- a/lld/MachO/SymbolTable.cpp
+++ b/lld/MachO/SymbolTable.cpp
@@ -150,10 +150,48 @@ Defined *SymbolTable::addDefined(StringRef name, InputFile *file,
overridesWeakDef = !isWeakDef && dysym->isWeakDef();
dysym->unreference();
} else if (auto *undef = dyn_cast<Undefined>(s)) {
- // Preserve the original bitcode file name (instead of using the object
- // file name).
- if (undef->wasBitcodeSymbol)
- file = undef->getFile();
+ if (undef->wasBitcodeSymbol) {
+ auto objFile = dyn_cast<ObjFile>(file);
+ if (!objFile) {
+ // The file must be a native object file, as opposed to potentially
+ // being another bitcode file. A situation arises when some symbols
+ // are defined thru `module asm` and thus they are not present in the
+ // bitcode's symbol table. Consider bitcode modules `A`, `B`, and `C`.
+ // LTO compiles only `A` and `C`, since there's no explicit symbol
+ // reference to `B` other than a symbol from `A` via `module asm`.
+ // After LTO is finished, the missing symbol now appears in the
+ // resulting object file for `A`, which prematurely resolves another
+ // prevailing symbol with `B` that hasn't been compiled, instead of
+ // the resulting object for `C`. Consequently, an incorrect
+ // relocation is generated for the prevailing symbol.
+ assert(isa<BitcodeFile>(file) && "Bitcode file is expected.");
+ std::string message =
+ "The pending prevailing symbol(" + name.str() +
+ ") in the bitcode file(" + toString(undef->getFile()) +
+ ") is overridden by a non-native object (from bitcode): " +
+ toString(file);
+ error(message);
+ } else if (!objFile->builtFromBitcode) {
+ // Ideally, this should be an object file compiled from a bitcode
+ // file. However, this might not hold true if a LC linker option is
+ // used. In case LTO internalizes a prevailing hidden weak symbol,
+ // there's a situation where an unresolved prevailing symbol might be
+ // linked with the corresponding one from a native library, which is
+ // loaded later after LTO. Although this could potentially result in
+ // an ODR violation, we choose to permit this scenario as a warning.
+ std::string message = "The pending prevailing symbol(" + name.str() +
+ ") in the bitcode file(" +
+ toString(undef->getFile()) +
+ ") is overridden by a post-processed native "
+ "object (from native archive): " +
+ toString(file);
+ warn(message);
+ } else {
+ // Preserve the original bitcode file name (instead of using the
+ // object file name).
+ file = undef->getFile();
+ }
+ }
}
// Defined symbols take priority over other types of symbols, so in case
// of a name conflict, we fall through to the replaceSymbol() call below.