LLVM  14.0.0git
Mangling.cpp
Go to the documentation of this file.
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 
12 #include "llvm/IR/Constants.h"
13 #include "llvm/IR/Mangler.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 
25  : ES(ES), DL(DL) {}
26 
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 
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());
83  if (SymbolToDefinition)
84  (*SymbolToDefinition)[MangledName] = G;
85  }
86 }
87 
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 
102  return InitSymbol;
103 }
104 
107  const object::MachOObjectFile &Obj) {
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);
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 
166  const object::ELFObjectFileBase &Obj) {
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 
219  const object::ObjectFile &Obj) {
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 
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.
llvm::orc::IRSymbolMapper::add
static void add(ExecutionSession &ES, const ManglingOptions &MO, ArrayRef< GlobalValue * > GVs, SymbolFlagsMap &SymbolFlags, SymbolNameToDefinitionMap *SymbolToDefinition=nullptr)
Add mangled symbols for the given GlobalValues to SymbolFlags.
Definition: Mangling.cpp:36
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
llvm::DataLayout
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:113
ELFNixPlatform.h
llvm::ELF::STB_GNU_UNIQUE
@ STB_GNU_UNIQUE
Definition: ELF.h:1147
llvm::raw_string_ostream
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:625
llvm::orc::IRSymbolMapper::SymbolNameToDefinitionMap
std::map< SymbolStringPtr, GlobalValue * > SymbolNameToDefinitionMap
Definition: Mangling.h:45
llvm::orc::SymbolStringPtr
Pointer to a pooled string representing a symbol name.
Definition: SymbolStringPool.h:50
llvm::orc::MangleAndInterner::MangleAndInterner
MangleAndInterner(ExecutionSession &ES, const DataLayout &DL)
Definition: Mangling.cpp:24
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
llvm::object::SymbolRef::ST_File
@ ST_File
Definition: ObjectFile.h:175
llvm::orc::getObjectSymbolInfo
Expected< std::pair< SymbolFlagsMap, SymbolStringPtr > > getObjectSymbolInfo(ExecutionSession &ES, MemoryBufferRef ObjBuffer)
Returns a SymbolFlagsMap for the object file represented by the given buffer, or an error if the buff...
Definition: Mangling.cpp:257
llvm::JITSymbolFlags
Flags for symbols in the JIT.
Definition: JITSymbol.h:74
llvm::MemoryBufferRef
Definition: MemoryBufferRef.h:22
llvm::MachO::SymbolFlags
SymbolFlags
Symbol flags.
Definition: Symbol.h:25
llvm::ArrayRef::empty
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:158
llvm::object::ObjectFile::symbols
symbol_iterator_range symbols() const
Definition: ObjectFile.h:314
MachO.h
llvm::object::ELFObjectFileBase
Definition: ELFObjectFile.h:49
llvm::orc::getELFObjectFileSymbolInfo
static Expected< std::pair< SymbolFlagsMap, SymbolStringPtr > > getELFObjectFileSymbolInfo(ExecutionSession &ES, const object::ELFObjectFileBase &Obj)
Definition: Mangling.cpp:165
Constants.h
llvm::JITSymbolFlags::MaterializationSideEffectsOnly
@ MaterializationSideEffectsOnly
Definition: JITSymbol.h:87
llvm::Mangler::getNameWithPrefix
void getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, bool CannotUsePrivateLabel) const
Print the appropriate prefix and the specified global variable's name.
Definition: Mangler.cpp:119
llvm::orc::ExecutionSession::intern
SymbolStringPtr intern(StringRef SymName)
Add a symbol name to the SymbolStringPool and return a pointer to it.
Definition: Core.h:1393
llvm::orc::MachOPlatform::isInitializerSection
static bool isInitializerSection(StringRef SegName, StringRef SectName)
Returns true if the given section name is an initializer section.
Definition: MachOPlatform.cpp:261
llvm::object::MachOObjectFile
Definition: MachO.h:262
llvm::object::MachOObjectFile::getSectionType
unsigned getSectionType(SectionRef Sec) const
Definition: MachOObjectFile.cpp:1769
G
const DataFlowGraph & G
Definition: RDFGraph.cpp:202
llvm::orc::ELFNixPlatform::isInitializerSection
static bool isInitializerSection(StringRef SecName)
Returns true if the given section name is an initializer section.
Definition: ELFNixPlatform.cpp:213
llvm::MachO::S_MOD_INIT_FUNC_POINTERS
@ S_MOD_INIT_FUNC_POINTERS
S_MOD_INIT_FUNC_POINTERS - Section with only function pointers for initialization.
Definition: MachO.h:145
llvm::orc::addInitSymbol
static SymbolStringPtr addInitSymbol(SymbolFlagsMap &SymbolFlags, ExecutionSession &ES, StringRef ObjFileName)
Definition: Mangling.cpp:88
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::DenseMap< SymbolStringPtr, JITSymbolFlags >
llvm::object::BasicSymbolRef::SF_Undefined
@ SF_Undefined
Definition: SymbolicFile.h:108
llvm::object::ObjectFile::createObjectFile
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
Definition: ObjectFile.cpp:186
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ObjectFile.h
llvm::MachO::SECTION_TYPE
@ SECTION_TYPE
Definition: MachO.h:112
llvm::orc::getMachOObjectFileSymbolInfo
static Expected< std::pair< SymbolFlagsMap, SymbolStringPtr > > getMachOObjectFileSymbolInfo(ExecutionSession &ES, const object::MachOObjectFile &Obj)
Definition: Mangling.cpp:106
Mangler.h
llvm::orc::IRSymbolMapper::ManglingOptions::EmulatedTLS
bool EmulatedTLS
Definition: Mangling.h:42
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::JITSymbolFlags::Weak
@ Weak
Definition: JITSymbol.h:82
llvm::object::ELFObjectFileBase::symbols
elf_symbol_iterator_range symbols() const
Definition: ELFObjectFile.h:228
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
llvm::object::ObjectFile
This class is the base class for all object file types.
Definition: ObjectFile.h:228
MachOPlatform.h
llvm::cantFail
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition: Error.h:747
llvm::orc::MangleAndInterner::operator()
SymbolStringPtr operator()(StringRef Name)
Definition: Mangling.cpp:27
getParent
static const Function * getParent(const Value *V)
Definition: BasicAliasAnalysis.cpp:870
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
ELFObjectFile.h
llvm::orc::getGenericObjectFileSymbolInfo
Expected< std::pair< SymbolFlagsMap, SymbolStringPtr > > getGenericObjectFileSymbolInfo(ExecutionSession &ES, const object::ObjectFile &Obj)
Definition: Mangling.cpp:218
llvm::orc::MangleAndInterner
Mangles symbol names then uniques them in the context of an ExecutionSession.
Definition: Mangling.h:26
llvm::orc::IRSymbolMapper::ManglingOptions
Definition: Mangling.h:41
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
Mangling.h
llvm::orc::ExecutionSession
An ExecutionSession represents a running JIT program.
Definition: Core.h:1346
llvm::sampleprof::SecType
SecType
Definition: SampleProf.h:121
llvm::JITSymbolFlags::fromGlobalValue
static JITSymbolFlags fromGlobalValue(const GlobalValue &GV)
Construct a JITSymbolFlags value based on the flags of the given global value.
Definition: JITSymbol.cpp:22
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition: Error.h:599
llvm::object::Binary::getFileName
StringRef getFileName() const
Definition: Binary.cpp:42
llvm::object::MachOObjectFile::getSectionFinalSegmentName
StringRef getSectionFinalSegmentName(DataRefImpl Sec) const
Definition: MachOObjectFile.cpp:4209
llvm::object::BasicSymbolRef::SF_Global
@ SF_Global
Definition: SymbolicFile.h:109
llvm::JITSymbolFlags::fromObjectSymbol
static Expected< JITSymbolFlags > fromObjectSymbol(const object::SymbolRef &Symbol)
Construct a JITSymbolFlags value based on the flags of the given libobject symbol.
Definition: JITSymbol.cpp:69
llvm::object::ObjectFile::sections
section_iterator_range sections() const
Definition: ObjectFile.h:322
llvm::object::MachOObjectFile::getSectionName
Expected< StringRef > getSectionName(DataRefImpl Sec) const override
Definition: MachOObjectFile.cpp:1912
Debug.h