1 //===----------- Mangling.cpp -- Name Mangling Utilities for ORC ----------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/ExecutionEngine/Orc/Mangling.h" 10 #include "llvm/IR/Constants.h" 11 #include "llvm/IR/Mangler.h" 12 #include "llvm/Object/MachO.h" 13 #include "llvm/Object/ObjectFile.h" 14 #include "llvm/Support/Debug.h" 15 16 #define DEBUG_TYPE "orc" 17 18 namespace llvm { 19 namespace orc { 20 21 MangleAndInterner::MangleAndInterner(ExecutionSession &ES, const DataLayout &DL) 22 : ES(ES), DL(DL) {} 23 24 SymbolStringPtr MangleAndInterner::operator()(StringRef Name) { 25 std::string MangledName; 26 { 27 raw_string_ostream MangledNameStream(MangledName); 28 Mangler::getNameWithPrefix(MangledNameStream, Name, DL); 29 } 30 return ES.intern(MangledName); 31 } 32 33 void IRSymbolMapper::add(ExecutionSession &ES, const ManglingOptions &MO, 34 ArrayRef<GlobalValue *> GVs, 35 SymbolFlagsMap &SymbolFlags, 36 SymbolNameToDefinitionMap *SymbolToDefinition) { 37 if (GVs.empty()) 38 return; 39 40 MangleAndInterner Mangle(ES, GVs[0]->getParent()->getDataLayout()); 41 for (auto *G : GVs) { 42 assert(G && "GVs cannot contain null elements"); 43 if (!G->hasName() || G->isDeclaration() || G->hasLocalLinkage() || 44 G->hasAvailableExternallyLinkage() || G->hasAppendingLinkage()) 45 continue; 46 47 if (G->isThreadLocal() && MO.EmulatedTLS) { 48 auto *GV = cast<GlobalVariable>(G); 49 50 auto Flags = JITSymbolFlags::fromGlobalValue(*GV); 51 52 auto EmuTLSV = Mangle(("__emutls_v." + GV->getName()).str()); 53 SymbolFlags[EmuTLSV] = Flags; 54 if (SymbolToDefinition) 55 (*SymbolToDefinition)[EmuTLSV] = GV; 56 57 // If this GV has a non-zero initializer we'll need to emit an 58 // __emutls.t symbol too. 59 if (GV->hasInitializer()) { 60 const auto *InitVal = GV->getInitializer(); 61 62 // Skip zero-initializers. 63 if (isa<ConstantAggregateZero>(InitVal)) 64 continue; 65 const auto *InitIntValue = dyn_cast<ConstantInt>(InitVal); 66 if (InitIntValue && InitIntValue->isZero()) 67 continue; 68 69 auto EmuTLST = Mangle(("__emutls_t." + GV->getName()).str()); 70 SymbolFlags[EmuTLST] = Flags; 71 if (SymbolToDefinition) 72 (*SymbolToDefinition)[EmuTLST] = GV; 73 } 74 continue; 75 } 76 77 // Otherwise we just need a normal linker mangling. 78 auto MangledName = Mangle(G->getName()); 79 SymbolFlags[MangledName] = JITSymbolFlags::fromGlobalValue(*G); 80 if (SymbolToDefinition) 81 (*SymbolToDefinition)[MangledName] = G; 82 } 83 } 84 85 Expected<std::pair<SymbolFlagsMap, SymbolStringPtr>> 86 getObjectSymbolInfo(ExecutionSession &ES, MemoryBufferRef ObjBuffer) { 87 auto Obj = object::ObjectFile::createObjectFile(ObjBuffer); 88 89 if (!Obj) 90 return Obj.takeError(); 91 92 SymbolFlagsMap SymbolFlags; 93 for (auto &Sym : (*Obj)->symbols()) { 94 // Skip symbols not defined in this object file. 95 if (Sym.getFlags() & object::BasicSymbolRef::SF_Undefined) 96 continue; 97 98 // Skip symbols that are not global. 99 if (!(Sym.getFlags() & object::BasicSymbolRef::SF_Global)) 100 continue; 101 102 auto Name = Sym.getName(); 103 if (!Name) 104 return Name.takeError(); 105 auto InternedName = ES.intern(*Name); 106 auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym); 107 if (!SymFlags) 108 return SymFlags.takeError(); 109 SymbolFlags[InternedName] = std::move(*SymFlags); 110 } 111 112 SymbolStringPtr InitSymbol; 113 114 if (auto *MachOObj = dyn_cast<object::MachOObjectFile>(Obj->get())) { 115 for (auto &Sec : MachOObj->sections()) { 116 auto SecType = MachOObj->getSectionType(Sec); 117 if ((SecType & MachO::SECTION_TYPE) == MachO::S_MOD_INIT_FUNC_POINTERS) { 118 std::string InitSymString; 119 raw_string_ostream(InitSymString) 120 << "$." << ObjBuffer.getBufferIdentifier() << ".__inits"; 121 InitSymbol = ES.intern(InitSymString); 122 break; 123 } 124 } 125 } 126 127 return std::make_pair(std::move(SymbolFlags), std::move(InitSymbol)); 128 } 129 130 } // End namespace orc. 131 } // End namespace llvm. 132