diff options
Diffstat (limited to 'lld/MachO/SymbolTable.cpp')
| -rw-r--r-- | lld/MachO/SymbolTable.cpp | 46 |
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. |
