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/ExecutionEngine/Orc/ELFNixPlatform.h" 11 #include "llvm/ExecutionEngine/Orc/MachOPlatform.h" 12 #include "llvm/IR/Constants.h" 13 #include "llvm/IR/Mangler.h" 14 #include "llvm/Object/ELFObjectFile.h" 15 #include "llvm/Object/MachO.h" 16 #include "llvm/Object/ObjectFile.h" 17 #include "llvm/Support/Debug.h" 18 19 #define DEBUG_TYPE "orc" 20 21 namespace llvm { 22 namespace orc { 23 24 MangleAndInterner::MangleAndInterner(ExecutionSession &ES, const DataLayout &DL) 25 : ES(ES), DL(DL) {} 26 27 SymbolStringPtr MangleAndInterner::operator()(StringRef Name) { 28 std::string MangledName; 29 { 30 raw_string_ostream MangledNameStream(MangledName); 31 Mangler::getNameWithPrefix(MangledNameStream, Name, DL); 32 } 33 return ES.intern(MangledName); 34 } 35 36 void IRSymbolMapper::add(ExecutionSession &ES, const ManglingOptions &MO, 37 ArrayRef<GlobalValue *> GVs, 38 SymbolFlagsMap &SymbolFlags, 39 SymbolNameToDefinitionMap *SymbolToDefinition) { 40 if (GVs.empty()) 41 return; 42 43 MangleAndInterner Mangle(ES, GVs[0]->getParent()->getDataLayout()); 44 for (auto *G : GVs) { 45 assert(G && "GVs cannot contain null elements"); 46 if (!G->hasName() || G->isDeclaration() || G->hasLocalLinkage() || 47 G->hasAvailableExternallyLinkage() || G->hasAppendingLinkage()) 48 continue; 49 50 if (G->isThreadLocal() && MO.EmulatedTLS) { 51 auto *GV = cast<GlobalVariable>(G); 52 53 auto Flags = JITSymbolFlags::fromGlobalValue(*GV); 54 55 auto EmuTLSV = Mangle(("__emutls_v." + GV->getName()).str()); 56 SymbolFlags[EmuTLSV] = Flags; 57 if (SymbolToDefinition) 58 (*SymbolToDefinition)[EmuTLSV] = GV; 59 60 // If this GV has a non-zero initializer we'll need to emit an 61 // __emutls.t symbol too. 62 if (GV->hasInitializer()) { 63 const auto *InitVal = GV->getInitializer(); 64 65 // Skip zero-initializers. 66 if (isa<ConstantAggregateZero>(InitVal)) 67 continue; 68 const auto *InitIntValue = dyn_cast<ConstantInt>(InitVal); 69 if (InitIntValue && InitIntValue->isZero()) 70 continue; 71 72 auto EmuTLST = Mangle(("__emutls_t." + GV->getName()).str()); 73 SymbolFlags[EmuTLST] = Flags; 74 if (SymbolToDefinition) 75 (*SymbolToDefinition)[EmuTLST] = GV; 76 } 77 continue; 78 } 79 80 // Otherwise we just need a normal linker mangling. 81 auto MangledName = Mangle(G->getName()); 82 SymbolFlags[MangledName] = JITSymbolFlags::fromGlobalValue(*G); 83 if (SymbolToDefinition) 84 (*SymbolToDefinition)[MangledName] = G; 85 } 86 } 87 88 static SymbolStringPtr addInitSymbol(SymbolFlagsMap &SymbolFlags, 89 ExecutionSession &ES, 90 StringRef ObjFileName) { 91 SymbolStringPtr InitSymbol; 92 size_t Counter = 0; 93 94 do { 95 std::string InitSymString; 96 raw_string_ostream(InitSymString) 97 << "$." << ObjFileName << ".__inits." << Counter++; 98 InitSymbol = ES.intern(InitSymString); 99 } while (SymbolFlags.count(InitSymbol)); 100 101 SymbolFlags[InitSymbol] = JITSymbolFlags::MaterializationSideEffectsOnly; 102 return InitSymbol; 103 } 104 105 static Expected<MaterializationUnit::Interface> 106 getMachOObjectFileSymbolInfo(ExecutionSession &ES, 107 const object::MachOObjectFile &Obj) { 108 SymbolFlagsMap SymbolFlags; 109 110 for (auto &Sym : Obj.symbols()) { 111 Expected<uint32_t> SymFlagsOrErr = Sym.getFlags(); 112 if (!SymFlagsOrErr) 113 // TODO: Test this error. 114 return SymFlagsOrErr.takeError(); 115 116 // Skip symbols not defined in this object file. 117 if (*SymFlagsOrErr & object::BasicSymbolRef::SF_Undefined) 118 continue; 119 120 // Skip symbols that are not global. 121 if (!(*SymFlagsOrErr & object::BasicSymbolRef::SF_Global)) 122 continue; 123 124 // Skip symbols that have type SF_File. 125 if (auto SymType = Sym.getType()) { 126 if (*SymType == object::SymbolRef::ST_File) 127 continue; 128 } else 129 return SymType.takeError(); 130 131 auto Name = Sym.getName(); 132 if (!Name) 133 return Name.takeError(); 134 auto InternedName = ES.intern(*Name); 135 auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym); 136 if (!SymFlags) 137 return SymFlags.takeError(); 138 139 // Strip the 'exported' flag from MachO linker-private symbols. 140 if (Name->startswith("l")) 141 *SymFlags &= ~JITSymbolFlags::Exported; 142 143 SymbolFlags[InternedName] = std::move(*SymFlags); 144 } 145 146 SymbolStringPtr InitSymbol; 147 for (auto &Sec : Obj.sections()) { 148 auto SecType = Obj.getSectionType(Sec); 149 if ((SecType & MachO::SECTION_TYPE) == MachO::S_MOD_INIT_FUNC_POINTERS) { 150 InitSymbol = addInitSymbol(SymbolFlags, ES, Obj.getFileName()); 151 break; 152 } 153 auto SegName = Obj.getSectionFinalSegmentName(Sec.getRawDataRefImpl()); 154 auto SecName = cantFail(Obj.getSectionName(Sec.getRawDataRefImpl())); 155 if (MachOPlatform::isInitializerSection(SegName, SecName)) { 156 InitSymbol = addInitSymbol(SymbolFlags, ES, Obj.getFileName()); 157 break; 158 } 159 } 160 161 return MaterializationUnit::Interface(std::move(SymbolFlags), 162 std::move(InitSymbol)); 163 } 164 165 static Expected<MaterializationUnit::Interface> 166 getELFObjectFileSymbolInfo(ExecutionSession &ES, 167 const object::ELFObjectFileBase &Obj) { 168 SymbolFlagsMap SymbolFlags; 169 for (auto &Sym : Obj.symbols()) { 170 Expected<uint32_t> SymFlagsOrErr = Sym.getFlags(); 171 if (!SymFlagsOrErr) 172 // TODO: Test this error. 173 return SymFlagsOrErr.takeError(); 174 175 // Skip symbols not defined in this object file. 176 if (*SymFlagsOrErr & object::BasicSymbolRef::SF_Undefined) 177 continue; 178 179 // Skip symbols that are not global. 180 if (!(*SymFlagsOrErr & object::BasicSymbolRef::SF_Global)) 181 continue; 182 183 // Skip symbols that have type SF_File. 184 if (auto SymType = Sym.getType()) { 185 if (*SymType == object::SymbolRef::ST_File) 186 continue; 187 } else 188 return SymType.takeError(); 189 190 auto Name = Sym.getName(); 191 if (!Name) 192 return Name.takeError(); 193 auto InternedName = ES.intern(*Name); 194 auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym); 195 if (!SymFlags) 196 return SymFlags.takeError(); 197 198 // ELF STB_GNU_UNIQUE should map to Weak for ORC. 199 if (Sym.getBinding() == ELF::STB_GNU_UNIQUE) 200 *SymFlags |= JITSymbolFlags::Weak; 201 202 SymbolFlags[InternedName] = std::move(*SymFlags); 203 } 204 205 SymbolStringPtr InitSymbol; 206 for (auto &Sec : Obj.sections()) { 207 if (auto SecName = Sec.getName()) { 208 if (ELFNixPlatform::isInitializerSection(*SecName)) { 209 InitSymbol = addInitSymbol(SymbolFlags, ES, Obj.getFileName()); 210 break; 211 } 212 } 213 } 214 215 return MaterializationUnit::Interface(std::move(SymbolFlags), 216 std::move(InitSymbol)); 217 } 218 219 Expected<MaterializationUnit::Interface> 220 getGenericObjectFileSymbolInfo(ExecutionSession &ES, 221 const object::ObjectFile &Obj) { 222 SymbolFlagsMap SymbolFlags; 223 for (auto &Sym : Obj.symbols()) { 224 Expected<uint32_t> SymFlagsOrErr = Sym.getFlags(); 225 if (!SymFlagsOrErr) 226 // TODO: Test this error. 227 return SymFlagsOrErr.takeError(); 228 229 // Skip symbols not defined in this object file. 230 if (*SymFlagsOrErr & object::BasicSymbolRef::SF_Undefined) 231 continue; 232 233 // Skip symbols that are not global. 234 if (!(*SymFlagsOrErr & object::BasicSymbolRef::SF_Global)) 235 continue; 236 237 // Skip symbols that have type SF_File. 238 if (auto SymType = Sym.getType()) { 239 if (*SymType == object::SymbolRef::ST_File) 240 continue; 241 } else 242 return SymType.takeError(); 243 244 auto Name = Sym.getName(); 245 if (!Name) 246 return Name.takeError(); 247 auto InternedName = ES.intern(*Name); 248 auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym); 249 if (!SymFlags) 250 return SymFlags.takeError(); 251 252 SymbolFlags[InternedName] = std::move(*SymFlags); 253 } 254 255 return MaterializationUnit::Interface(std::move(SymbolFlags), nullptr); 256 } 257 258 Expected<MaterializationUnit::Interface> 259 getObjectInterface(ExecutionSession &ES, MemoryBufferRef ObjBuffer) { 260 auto Obj = object::ObjectFile::createObjectFile(ObjBuffer); 261 262 if (!Obj) 263 return Obj.takeError(); 264 265 if (auto *MachOObj = dyn_cast<object::MachOObjectFile>(Obj->get())) 266 return getMachOObjectFileSymbolInfo(ES, *MachOObj); 267 else if (auto *ELFObj = dyn_cast<object::ELFObjectFileBase>(Obj->get())) 268 return getELFObjectFileSymbolInfo(ES, *ELFObj); 269 270 return getGenericObjectFileSymbolInfo(ES, **Obj); 271 } 272 273 } // End namespace orc. 274 } // End namespace llvm. 275