diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2022-07-27 20:11:54 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-02-08 19:04:48 +0000 |
commit | 972a253a57b6f144b0e4a3e2080a2a0076ec55a0 (patch) | |
tree | a8aeeb0997a0a52500f1fa0644244206cf71df94 /contrib/llvm-project/llvm/lib/ExecutionEngine/Orc | |
parent | fcaf7f8644a9988098ac6be2165bce3ea4786e91 (diff) | |
parent | 08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/ExecutionEngine/Orc')
-rw-r--r-- | contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/ObjectFileInterface.cpp | 38 |
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); } |