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<std::pair<SymbolFlagsMap, SymbolStringPtr>> 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 std::make_pair(std::move(SymbolFlags), std::move(InitSymbol)); 162 } 163 164 static Expected<std::pair<SymbolFlagsMap, SymbolStringPtr>> 165 getELFObjectFileSymbolInfo(ExecutionSession &ES, 166 const object::ELFObjectFileBase &Obj) { 167 SymbolFlagsMap SymbolFlags; 168 for (auto &Sym : Obj.symbols()) { 169 Expected<uint32_t> SymFlagsOrErr = Sym.getFlags(); 170 if (!SymFlagsOrErr) 171 // TODO: Test this error. 172 return SymFlagsOrErr.takeError(); 173 174 // Skip symbols not defined in this object file. 175 if (*SymFlagsOrErr & object::BasicSymbolRef::SF_Undefined) 176 continue; 177 178 // Skip symbols that are not global. 179 if (!(*SymFlagsOrErr & object::BasicSymbolRef::SF_Global)) 180 continue; 181 182 // Skip symbols that have type SF_File. 183 if (auto SymType = Sym.getType()) { 184 if (*SymType == object::SymbolRef::ST_File) 185 continue; 186 } else 187 return SymType.takeError(); 188 189 auto Name = Sym.getName(); 190 if (!Name) 191 return Name.takeError(); 192 auto InternedName = ES.intern(*Name); 193 auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym); 194 if (!SymFlags) 195 return SymFlags.takeError(); 196 197 // ELF STB_GNU_UNIQUE should map to Weak for ORC. 198 if (Sym.getBinding() == ELF::STB_GNU_UNIQUE) 199 *SymFlags |= JITSymbolFlags::Weak; 200 201 SymbolFlags[InternedName] = std::move(*SymFlags); 202 } 203 204 SymbolStringPtr InitSymbol; 205 for (auto &Sec : Obj.sections()) { 206 if (auto SecName = Sec.getName()) { 207 if (ELFNixPlatform::isInitializerSection(*SecName)) { 208 InitSymbol = addInitSymbol(SymbolFlags, ES, Obj.getFileName()); 209 break; 210 } 211 } 212 } 213 214 return std::make_pair(std::move(SymbolFlags), InitSymbol); 215 } 216 217 Expected<std::pair<SymbolFlagsMap, SymbolStringPtr>> 218 getGenericObjectFileSymbolInfo(ExecutionSession &ES, 219 const object::ObjectFile &Obj) { 220 SymbolFlagsMap SymbolFlags; 221 for (auto &Sym : Obj.symbols()) { 222 Expected<uint32_t> SymFlagsOrErr = Sym.getFlags(); 223 if (!SymFlagsOrErr) 224 // TODO: Test this error. 225 return SymFlagsOrErr.takeError(); 226 227 // Skip symbols not defined in this object file. 228 if (*SymFlagsOrErr & object::BasicSymbolRef::SF_Undefined) 229 continue; 230 231 // Skip symbols that are not global. 232 if (!(*SymFlagsOrErr & object::BasicSymbolRef::SF_Global)) 233 continue; 234 235 // Skip symbols that have type SF_File. 236 if (auto SymType = Sym.getType()) { 237 if (*SymType == object::SymbolRef::ST_File) 238 continue; 239 } else 240 return SymType.takeError(); 241 242 auto Name = Sym.getName(); 243 if (!Name) 244 return Name.takeError(); 245 auto InternedName = ES.intern(*Name); 246 auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym); 247 if (!SymFlags) 248 return SymFlags.takeError(); 249 250 SymbolFlags[InternedName] = std::move(*SymFlags); 251 } 252 253 return std::make_pair(std::move(SymbolFlags), nullptr); 254 } 255 256 Expected<std::pair<SymbolFlagsMap, SymbolStringPtr>> 257 getObjectSymbolInfo(ExecutionSession &ES, MemoryBufferRef ObjBuffer) { 258 auto Obj = object::ObjectFile::createObjectFile(ObjBuffer); 259 260 if (!Obj) 261 return Obj.takeError(); 262 263 if (auto *MachOObj = dyn_cast<object::MachOObjectFile>(Obj->get())) 264 return getMachOObjectFileSymbolInfo(ES, *MachOObj); 265 else if (auto *ELFObj = dyn_cast<object::ELFObjectFileBase>(Obj->get())) 266 return getELFObjectFileSymbolInfo(ES, *ELFObj); 267 268 return getGenericObjectFileSymbolInfo(ES, **Obj); 269 } 270 271 } // End namespace orc. 272 } // End namespace llvm. 273