diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/Mangling.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/Mangling.cpp | 173 |
1 files changed, 137 insertions, 36 deletions
diff --git a/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/Mangling.cpp b/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/Mangling.cpp index 14b22880ab7e..7b21e6a684ca 100644 --- a/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/Mangling.cpp +++ b/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/Mangling.cpp @@ -7,9 +7,11 @@ //===----------------------------------------------------------------------===// #include "llvm/ExecutionEngine/Orc/Mangling.h" +#include "llvm/ExecutionEngine/Orc/ELFNixPlatform.h" #include "llvm/ExecutionEngine/Orc/MachOPlatform.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Mangler.h" +#include "llvm/Object/ELFObjectFile.h" #include "llvm/Object/MachO.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Debug.h" @@ -83,17 +85,29 @@ void IRSymbolMapper::add(ExecutionSession &ES, const ManglingOptions &MO, } } -Expected<std::pair<SymbolFlagsMap, SymbolStringPtr>> -getObjectSymbolInfo(ExecutionSession &ES, MemoryBufferRef ObjBuffer) { - auto Obj = object::ObjectFile::createObjectFile(ObjBuffer); +static SymbolStringPtr addInitSymbol(SymbolFlagsMap &SymbolFlags, + ExecutionSession &ES, + StringRef ObjFileName) { + SymbolStringPtr InitSymbol; + size_t Counter = 0; - if (!Obj) - return Obj.takeError(); + do { + std::string InitSymString; + raw_string_ostream(InitSymString) + << "$." << ObjFileName << ".__inits." << Counter++; + InitSymbol = ES.intern(InitSymString); + } while (SymbolFlags.count(InitSymbol)); - bool IsMachO = isa<object::MachOObjectFile>(Obj->get()); + SymbolFlags[InitSymbol] = JITSymbolFlags::MaterializationSideEffectsOnly; + return InitSymbol; +} +static Expected<std::pair<SymbolFlagsMap, SymbolStringPtr>> +getMachOObjectFileSymbolInfo(ExecutionSession &ES, + const object::MachOObjectFile &Obj) { SymbolFlagsMap SymbolFlags; - for (auto &Sym : (*Obj)->symbols()) { + + for (auto &Sym : Obj.symbols()) { Expected<uint32_t> SymFlagsOrErr = Sym.getFlags(); if (!SymFlagsOrErr) // TODO: Test this error. @@ -123,48 +137,135 @@ getObjectSymbolInfo(ExecutionSession &ES, MemoryBufferRef ObjBuffer) { return SymFlags.takeError(); // Strip the 'exported' flag from MachO linker-private symbols. - if (IsMachO && Name->startswith("l")) + if (Name->startswith("l")) *SymFlags &= ~JITSymbolFlags::Exported; SymbolFlags[InternedName] = std::move(*SymFlags); } SymbolStringPtr InitSymbol; + for (auto &Sec : Obj.sections()) { + auto SecType = Obj.getSectionType(Sec); + if ((SecType & MachO::SECTION_TYPE) == MachO::S_MOD_INIT_FUNC_POINTERS) { + InitSymbol = addInitSymbol(SymbolFlags, ES, Obj.getFileName()); + break; + } + auto SegName = Obj.getSectionFinalSegmentName(Sec.getRawDataRefImpl()); + auto SecName = cantFail(Obj.getSectionName(Sec.getRawDataRefImpl())); + if (MachOPlatform::isInitializerSection(SegName, SecName)) { + InitSymbol = addInitSymbol(SymbolFlags, ES, Obj.getFileName()); + break; + } + } - size_t Counter = 0; - auto AddInitSymbol = [&]() { - while (true) { - std::string InitSymString; - raw_string_ostream(InitSymString) - << "$." << ObjBuffer.getBufferIdentifier() << ".__inits." - << Counter++; - InitSymbol = ES.intern(InitSymString); - if (SymbolFlags.count(InitSymbol)) + return std::make_pair(std::move(SymbolFlags), std::move(InitSymbol)); +} + +static Expected<std::pair<SymbolFlagsMap, SymbolStringPtr>> +getELFObjectFileSymbolInfo(ExecutionSession &ES, + const object::ELFObjectFileBase &Obj) { + SymbolFlagsMap SymbolFlags; + 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; + + // Skip symbols that are not global. + if (!(*SymFlagsOrErr & object::BasicSymbolRef::SF_Global)) + continue; + + // Skip symbols that have type SF_File. + if (auto SymType = Sym.getType()) { + if (*SymType == object::SymbolRef::ST_File) continue; - SymbolFlags[InitSymbol] = JITSymbolFlags::MaterializationSideEffectsOnly; - return; - } - }; - - if (IsMachO) { - auto &MachOObj = cast<object::MachOObjectFile>(*Obj->get()); - for (auto &Sec : MachOObj.sections()) { - auto SecType = MachOObj.getSectionType(Sec); - if ((SecType & MachO::SECTION_TYPE) == MachO::S_MOD_INIT_FUNC_POINTERS) { - AddInitSymbol(); - break; - } - auto SegName = - MachOObj.getSectionFinalSegmentName(Sec.getRawDataRefImpl()); - auto SecName = cantFail(MachOObj.getSectionName(Sec.getRawDataRefImpl())); - if (MachOPlatform::isInitializerSection(SegName, SecName)) { - AddInitSymbol(); + } else + return SymType.takeError(); + + auto Name = Sym.getName(); + if (!Name) + return Name.takeError(); + auto InternedName = ES.intern(*Name); + auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym); + if (!SymFlags) + return SymFlags.takeError(); + + // ELF STB_GNU_UNIQUE should map to Weak for ORC. + if (Sym.getBinding() == ELF::STB_GNU_UNIQUE) + *SymFlags |= JITSymbolFlags::Weak; + + SymbolFlags[InternedName] = std::move(*SymFlags); + } + + SymbolStringPtr InitSymbol; + for (auto &Sec : Obj.sections()) { + if (auto SecName = Sec.getName()) { + if (ELFNixPlatform::isInitializerSection(*SecName)) { + InitSymbol = addInitSymbol(SymbolFlags, ES, Obj.getFileName()); break; } } } - return std::make_pair(std::move(SymbolFlags), std::move(InitSymbol)); + return std::make_pair(std::move(SymbolFlags), InitSymbol); +} + +Expected<std::pair<SymbolFlagsMap, SymbolStringPtr>> +getGenericObjectFileSymbolInfo(ExecutionSession &ES, + const object::ObjectFile &Obj) { + SymbolFlagsMap SymbolFlags; + 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; + + // Skip symbols that are not global. + if (!(*SymFlagsOrErr & object::BasicSymbolRef::SF_Global)) + continue; + + // Skip symbols that have type SF_File. + if (auto SymType = Sym.getType()) { + if (*SymType == object::SymbolRef::ST_File) + continue; + } else + return SymType.takeError(); + + auto Name = Sym.getName(); + if (!Name) + return Name.takeError(); + auto InternedName = ES.intern(*Name); + auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym); + if (!SymFlags) + return SymFlags.takeError(); + + SymbolFlags[InternedName] = std::move(*SymFlags); + } + + return std::make_pair(std::move(SymbolFlags), nullptr); +} + +Expected<std::pair<SymbolFlagsMap, SymbolStringPtr>> +getObjectSymbolInfo(ExecutionSession &ES, MemoryBufferRef ObjBuffer) { + auto Obj = object::ObjectFile::createObjectFile(ObjBuffer); + + if (!Obj) + return Obj.takeError(); + + if (auto *MachOObj = dyn_cast<object::MachOObjectFile>(Obj->get())) + return getMachOObjectFileSymbolInfo(ES, *MachOObj); + else if (auto *ELFObj = dyn_cast<object::ELFObjectFileBase>(Obj->get())) + return getELFObjectFileSymbolInfo(ES, *ELFObj); + + return getGenericObjectFileSymbolInfo(ES, **Obj); } } // End namespace orc. |
