10eae32dcSDimitry Andric //===------ ObjectFileInterface.cpp - MU interface utils for objects ------===// 20eae32dcSDimitry Andric // 30eae32dcSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40eae32dcSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50eae32dcSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60eae32dcSDimitry Andric // 70eae32dcSDimitry Andric //===----------------------------------------------------------------------===// 80eae32dcSDimitry Andric 90eae32dcSDimitry Andric #include "llvm/ExecutionEngine/Orc/ObjectFileInterface.h" 100eae32dcSDimitry Andric #include "llvm/ExecutionEngine/Orc/ELFNixPlatform.h" 110eae32dcSDimitry Andric #include "llvm/ExecutionEngine/Orc/MachOPlatform.h" 120eae32dcSDimitry Andric #include "llvm/Object/ELFObjectFile.h" 130eae32dcSDimitry Andric #include "llvm/Object/MachO.h" 140eae32dcSDimitry Andric #include "llvm/Object/ObjectFile.h" 150eae32dcSDimitry Andric #include "llvm/Support/Debug.h" 160eae32dcSDimitry Andric 170eae32dcSDimitry Andric #define DEBUG_TYPE "orc" 180eae32dcSDimitry Andric 190eae32dcSDimitry Andric namespace llvm { 200eae32dcSDimitry Andric namespace orc { 210eae32dcSDimitry Andric 220eae32dcSDimitry Andric void addInitSymbol(MaterializationUnit::Interface &I, ExecutionSession &ES, 230eae32dcSDimitry Andric StringRef ObjFileName) { 240eae32dcSDimitry Andric assert(!I.InitSymbol && "I already has an init symbol"); 250eae32dcSDimitry Andric size_t Counter = 0; 260eae32dcSDimitry Andric 270eae32dcSDimitry Andric do { 280eae32dcSDimitry Andric std::string InitSymString; 290eae32dcSDimitry Andric raw_string_ostream(InitSymString) 300eae32dcSDimitry Andric << "$." << ObjFileName << ".__inits." << Counter++; 310eae32dcSDimitry Andric I.InitSymbol = ES.intern(InitSymString); 320eae32dcSDimitry Andric } while (I.SymbolFlags.count(I.InitSymbol)); 330eae32dcSDimitry Andric 340eae32dcSDimitry Andric I.SymbolFlags[I.InitSymbol] = JITSymbolFlags::MaterializationSideEffectsOnly; 350eae32dcSDimitry Andric } 360eae32dcSDimitry Andric 370eae32dcSDimitry Andric static Expected<MaterializationUnit::Interface> 380eae32dcSDimitry Andric getMachOObjectFileSymbolInfo(ExecutionSession &ES, 390eae32dcSDimitry Andric const object::MachOObjectFile &Obj) { 400eae32dcSDimitry Andric MaterializationUnit::Interface I; 410eae32dcSDimitry Andric 420eae32dcSDimitry Andric for (auto &Sym : Obj.symbols()) { 430eae32dcSDimitry Andric Expected<uint32_t> SymFlagsOrErr = Sym.getFlags(); 440eae32dcSDimitry Andric if (!SymFlagsOrErr) 450eae32dcSDimitry Andric // TODO: Test this error. 460eae32dcSDimitry Andric return SymFlagsOrErr.takeError(); 470eae32dcSDimitry Andric 480eae32dcSDimitry Andric // Skip symbols not defined in this object file. 490eae32dcSDimitry Andric if (*SymFlagsOrErr & object::BasicSymbolRef::SF_Undefined) 500eae32dcSDimitry Andric continue; 510eae32dcSDimitry Andric 520eae32dcSDimitry Andric // Skip symbols that are not global. 530eae32dcSDimitry Andric if (!(*SymFlagsOrErr & object::BasicSymbolRef::SF_Global)) 540eae32dcSDimitry Andric continue; 550eae32dcSDimitry Andric 560eae32dcSDimitry Andric // Skip symbols that have type SF_File. 570eae32dcSDimitry Andric if (auto SymType = Sym.getType()) { 580eae32dcSDimitry Andric if (*SymType == object::SymbolRef::ST_File) 590eae32dcSDimitry Andric continue; 600eae32dcSDimitry Andric } else 610eae32dcSDimitry Andric return SymType.takeError(); 620eae32dcSDimitry Andric 630eae32dcSDimitry Andric auto Name = Sym.getName(); 640eae32dcSDimitry Andric if (!Name) 650eae32dcSDimitry Andric return Name.takeError(); 660eae32dcSDimitry Andric auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym); 670eae32dcSDimitry Andric if (!SymFlags) 680eae32dcSDimitry Andric return SymFlags.takeError(); 690eae32dcSDimitry Andric 700eae32dcSDimitry Andric // Strip the 'exported' flag from MachO linker-private symbols. 710eae32dcSDimitry Andric if (Name->startswith("l")) 720eae32dcSDimitry Andric *SymFlags &= ~JITSymbolFlags::Exported; 730eae32dcSDimitry Andric 74*81ad6265SDimitry Andric I.SymbolFlags[ES.intern(*Name)] = std::move(*SymFlags); 750eae32dcSDimitry Andric } 760eae32dcSDimitry Andric 770eae32dcSDimitry Andric for (auto &Sec : Obj.sections()) { 780eae32dcSDimitry Andric auto SecType = Obj.getSectionType(Sec); 790eae32dcSDimitry Andric if ((SecType & MachO::SECTION_TYPE) == MachO::S_MOD_INIT_FUNC_POINTERS) { 800eae32dcSDimitry Andric addInitSymbol(I, ES, Obj.getFileName()); 810eae32dcSDimitry Andric break; 820eae32dcSDimitry Andric } 830eae32dcSDimitry Andric auto SegName = Obj.getSectionFinalSegmentName(Sec.getRawDataRefImpl()); 840eae32dcSDimitry Andric auto SecName = cantFail(Obj.getSectionName(Sec.getRawDataRefImpl())); 850eae32dcSDimitry Andric if (MachOPlatform::isInitializerSection(SegName, SecName)) { 860eae32dcSDimitry Andric addInitSymbol(I, ES, Obj.getFileName()); 870eae32dcSDimitry Andric break; 880eae32dcSDimitry Andric } 890eae32dcSDimitry Andric } 900eae32dcSDimitry Andric 910eae32dcSDimitry Andric return I; 920eae32dcSDimitry Andric } 930eae32dcSDimitry Andric 940eae32dcSDimitry Andric static Expected<MaterializationUnit::Interface> 950eae32dcSDimitry Andric getELFObjectFileSymbolInfo(ExecutionSession &ES, 960eae32dcSDimitry Andric const object::ELFObjectFileBase &Obj) { 970eae32dcSDimitry Andric MaterializationUnit::Interface I; 980eae32dcSDimitry Andric 990eae32dcSDimitry Andric for (auto &Sym : Obj.symbols()) { 1000eae32dcSDimitry Andric Expected<uint32_t> SymFlagsOrErr = Sym.getFlags(); 1010eae32dcSDimitry Andric if (!SymFlagsOrErr) 1020eae32dcSDimitry Andric // TODO: Test this error. 1030eae32dcSDimitry Andric return SymFlagsOrErr.takeError(); 1040eae32dcSDimitry Andric 1050eae32dcSDimitry Andric // Skip symbols not defined in this object file. 1060eae32dcSDimitry Andric if (*SymFlagsOrErr & object::BasicSymbolRef::SF_Undefined) 1070eae32dcSDimitry Andric continue; 1080eae32dcSDimitry Andric 1090eae32dcSDimitry Andric // Skip symbols that are not global. 1100eae32dcSDimitry Andric if (!(*SymFlagsOrErr & object::BasicSymbolRef::SF_Global)) 1110eae32dcSDimitry Andric continue; 1120eae32dcSDimitry Andric 1130eae32dcSDimitry Andric // Skip symbols that have type SF_File. 1140eae32dcSDimitry Andric if (auto SymType = Sym.getType()) { 1150eae32dcSDimitry Andric if (*SymType == object::SymbolRef::ST_File) 1160eae32dcSDimitry Andric continue; 1170eae32dcSDimitry Andric } else 1180eae32dcSDimitry Andric return SymType.takeError(); 1190eae32dcSDimitry Andric 1200eae32dcSDimitry Andric auto Name = Sym.getName(); 1210eae32dcSDimitry Andric if (!Name) 1220eae32dcSDimitry Andric return Name.takeError(); 123*81ad6265SDimitry Andric 1240eae32dcSDimitry Andric auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym); 1250eae32dcSDimitry Andric if (!SymFlags) 1260eae32dcSDimitry Andric return SymFlags.takeError(); 1270eae32dcSDimitry Andric 1280eae32dcSDimitry Andric // ELF STB_GNU_UNIQUE should map to Weak for ORC. 1290eae32dcSDimitry Andric if (Sym.getBinding() == ELF::STB_GNU_UNIQUE) 1300eae32dcSDimitry Andric *SymFlags |= JITSymbolFlags::Weak; 1310eae32dcSDimitry Andric 132*81ad6265SDimitry Andric I.SymbolFlags[ES.intern(*Name)] = std::move(*SymFlags); 1330eae32dcSDimitry Andric } 1340eae32dcSDimitry Andric 1350eae32dcSDimitry Andric SymbolStringPtr InitSymbol; 1360eae32dcSDimitry Andric for (auto &Sec : Obj.sections()) { 1370eae32dcSDimitry Andric if (auto SecName = Sec.getName()) { 1380eae32dcSDimitry Andric if (ELFNixPlatform::isInitializerSection(*SecName)) { 1390eae32dcSDimitry Andric addInitSymbol(I, ES, Obj.getFileName()); 1400eae32dcSDimitry Andric break; 1410eae32dcSDimitry Andric } 1420eae32dcSDimitry Andric } 1430eae32dcSDimitry Andric } 1440eae32dcSDimitry Andric 1450eae32dcSDimitry Andric return I; 1460eae32dcSDimitry Andric } 1470eae32dcSDimitry Andric 1480eae32dcSDimitry Andric Expected<MaterializationUnit::Interface> 1490eae32dcSDimitry Andric getGenericObjectFileSymbolInfo(ExecutionSession &ES, 1500eae32dcSDimitry Andric const object::ObjectFile &Obj) { 1510eae32dcSDimitry Andric MaterializationUnit::Interface I; 1520eae32dcSDimitry Andric 1530eae32dcSDimitry Andric for (auto &Sym : Obj.symbols()) { 1540eae32dcSDimitry Andric Expected<uint32_t> SymFlagsOrErr = Sym.getFlags(); 1550eae32dcSDimitry Andric if (!SymFlagsOrErr) 1560eae32dcSDimitry Andric // TODO: Test this error. 1570eae32dcSDimitry Andric return SymFlagsOrErr.takeError(); 1580eae32dcSDimitry Andric 1590eae32dcSDimitry Andric // Skip symbols not defined in this object file. 1600eae32dcSDimitry Andric if (*SymFlagsOrErr & object::BasicSymbolRef::SF_Undefined) 1610eae32dcSDimitry Andric continue; 1620eae32dcSDimitry Andric 1630eae32dcSDimitry Andric // Skip symbols that are not global. 1640eae32dcSDimitry Andric if (!(*SymFlagsOrErr & object::BasicSymbolRef::SF_Global)) 1650eae32dcSDimitry Andric continue; 1660eae32dcSDimitry Andric 1670eae32dcSDimitry Andric // Skip symbols that have type SF_File. 1680eae32dcSDimitry Andric if (auto SymType = Sym.getType()) { 1690eae32dcSDimitry Andric if (*SymType == object::SymbolRef::ST_File) 1700eae32dcSDimitry Andric continue; 1710eae32dcSDimitry Andric } else 1720eae32dcSDimitry Andric return SymType.takeError(); 1730eae32dcSDimitry Andric 1740eae32dcSDimitry Andric auto Name = Sym.getName(); 1750eae32dcSDimitry Andric if (!Name) 1760eae32dcSDimitry Andric return Name.takeError(); 177*81ad6265SDimitry Andric 1780eae32dcSDimitry Andric auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym); 1790eae32dcSDimitry Andric if (!SymFlags) 1800eae32dcSDimitry Andric return SymFlags.takeError(); 1810eae32dcSDimitry Andric 182*81ad6265SDimitry Andric I.SymbolFlags[ES.intern(*Name)] = std::move(*SymFlags); 1830eae32dcSDimitry Andric } 1840eae32dcSDimitry Andric 1850eae32dcSDimitry Andric return I; 1860eae32dcSDimitry Andric } 1870eae32dcSDimitry Andric 1880eae32dcSDimitry Andric Expected<MaterializationUnit::Interface> 1890eae32dcSDimitry Andric getObjectFileInterface(ExecutionSession &ES, MemoryBufferRef ObjBuffer) { 1900eae32dcSDimitry Andric auto Obj = object::ObjectFile::createObjectFile(ObjBuffer); 1910eae32dcSDimitry Andric 1920eae32dcSDimitry Andric if (!Obj) 1930eae32dcSDimitry Andric return Obj.takeError(); 1940eae32dcSDimitry Andric 1950eae32dcSDimitry Andric if (auto *MachOObj = dyn_cast<object::MachOObjectFile>(Obj->get())) 1960eae32dcSDimitry Andric return getMachOObjectFileSymbolInfo(ES, *MachOObj); 1970eae32dcSDimitry Andric else if (auto *ELFObj = dyn_cast<object::ELFObjectFileBase>(Obj->get())) 1980eae32dcSDimitry Andric return getELFObjectFileSymbolInfo(ES, *ELFObj); 1990eae32dcSDimitry Andric 2000eae32dcSDimitry Andric return getGenericObjectFileSymbolInfo(ES, **Obj); 2010eae32dcSDimitry Andric } 2020eae32dcSDimitry Andric 2030eae32dcSDimitry Andric } // End namespace orc. 2040eae32dcSDimitry Andric } // End namespace llvm. 205