aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2022-07-27 20:11:54 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-02-08 19:04:48 +0000
commit972a253a57b6f144b0e4a3e2080a2a0076ec55a0 (patch)
treea8aeeb0997a0a52500f1fa0644244206cf71df94 /contrib/llvm-project/llvm/lib/ExecutionEngine/Orc
parentfcaf7f8644a9988098ac6be2165bce3ea4786e91 (diff)
parent08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff)
Diffstat (limited to 'contrib/llvm-project/llvm/lib/ExecutionEngine/Orc')
-rw-r--r--contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/ObjectFileInterface.cpp38
1 files changed, 31 insertions, 7 deletions
diff --git a/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/ObjectFileInterface.cpp b/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/ObjectFileInterface.cpp
index 356b81b4f1c5..3de15db3f1c6 100644
--- a/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/ObjectFileInterface.cpp
+++ b/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/ObjectFileInterface.cpp
@@ -150,16 +150,39 @@ static Expected<MaterializationUnit::Interface>
getCOFFObjectFileSymbolInfo(ExecutionSession &ES,
const object::COFFObjectFile &Obj) {
MaterializationUnit::Interface I;
-
+ std::vector<Optional<object::coff_aux_section_definition>> ComdatDefs(
+ Obj.getNumberOfSections() + 1);
for (auto &Sym : Obj.symbols()) {
Expected<uint32_t> SymFlagsOrErr = Sym.getFlags();
if (!SymFlagsOrErr)
// TODO: Test this error.
return SymFlagsOrErr.takeError();
- // Skip symbols not defined in this object file.
- if (*SymFlagsOrErr & object::BasicSymbolRef::SF_Undefined)
- continue;
+ // Handle comdat symbols
+ auto COFFSym = Obj.getCOFFSymbol(Sym);
+ bool IsWeak = false;
+ if (auto *Def = COFFSym.getSectionDefinition()) {
+ auto Sec = Obj.getSection(COFFSym.getSectionNumber());
+ if (!Sec)
+ return Sec.takeError();
+ if (((*Sec)->Characteristics & COFF::IMAGE_SCN_LNK_COMDAT) &&
+ Def->Selection != COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
+ ComdatDefs[COFFSym.getSectionNumber()] = *Def;
+ continue;
+ }
+ }
+ if (!COFF::isReservedSectionNumber(COFFSym.getSectionNumber()) &&
+ ComdatDefs[COFFSym.getSectionNumber()]) {
+ auto Def = ComdatDefs[COFFSym.getSectionNumber()];
+ if (Def->Selection != COFF::IMAGE_COMDAT_SELECT_NODUPLICATES) {
+ IsWeak = true;
+ }
+ ComdatDefs[COFFSym.getSectionNumber()] = None;
+ } else {
+ // Skip symbols not defined in this object file.
+ if (*SymFlagsOrErr & object::BasicSymbolRef::SF_Undefined)
+ continue;
+ }
// Skip symbols that are not global.
if (!(*SymFlagsOrErr & object::BasicSymbolRef::SF_Global))
@@ -180,12 +203,13 @@ getCOFFObjectFileSymbolInfo(ExecutionSession &ES,
if (!SymFlags)
return SymFlags.takeError();
*SymFlags |= JITSymbolFlags::Exported;
- auto COFFSym = Obj.getCOFFSymbol(Sym);
// Weak external is always a function
- if (COFFSym.isWeakExternal()) {
+ if (COFFSym.isWeakExternal())
*SymFlags |= JITSymbolFlags::Callable;
- }
+
+ if (IsWeak)
+ *SymFlags |= JITSymbolFlags::Weak;
I.SymbolFlags[ES.intern(*Name)] = std::move(*SymFlags);
}