LLVM  16.0.0git
ELFLinkGraphBuilder.h
Go to the documentation of this file.
1 //===------- ELFLinkGraphBuilder.h - ELF LinkGraph builder ------*- C++ -*-===//
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 // Generic ELF LinkGraph building code.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H
14 #define LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H
15 
17 #include "llvm/Object/ELF.h"
18 #include "llvm/Support/Debug.h"
19 #include "llvm/Support/Error.h"
21 
22 #define DEBUG_TYPE "jitlink"
23 
24 namespace llvm {
25 namespace jitlink {
26 
27 /// Common link-graph building code shared between all ELFFiles.
29 public:
30  ELFLinkGraphBuilderBase(std::unique_ptr<LinkGraph> G) : G(std::move(G)) {}
31  virtual ~ELFLinkGraphBuilderBase();
32 
33 protected:
35  return llvm::is_contained(DwarfSectionNames, SectionName);
36  }
37 
39  if (!CommonSection)
40  CommonSection = &G->createSection(
41  CommonSectionName, orc::MemProt::Read | orc::MemProt::Write);
42  return *CommonSection;
43  }
44 
45  std::unique_ptr<LinkGraph> G;
46 
47 private:
48  static StringRef CommonSectionName;
49  static ArrayRef<const char *> DwarfSectionNames;
50 
51  Section *CommonSection = nullptr;
52 };
53 
54 /// Ling-graph building code that's specific to the given ELFT, but common
55 /// across all architectures.
56 template <typename ELFT>
59 
60 public:
62  StringRef FileName,
63  LinkGraph::GetEdgeKindNameFunction GetEdgeKindName);
64 
65  /// Attempt to construct and return the LinkGraph.
67 
68  /// Call to derived class to handle relocations. These require
69  /// architecture specific knowledge to map to JITLink edge kinds.
70  virtual Error addRelocations() = 0;
71 
72 protected:
73  using ELFSectionIndex = unsigned;
74  using ELFSymbolIndex = unsigned;
75 
76  bool isRelocatable() const {
77  return Obj.getHeader().e_type == llvm::ELF::ET_REL;
78  }
79 
80  void setGraphBlock(ELFSectionIndex SecIndex, Block *B) {
81  assert(!GraphBlocks.count(SecIndex) && "Duplicate section at index");
82  GraphBlocks[SecIndex] = B;
83  }
84 
86  auto I = GraphBlocks.find(SecIndex);
87  if (I == GraphBlocks.end())
88  return nullptr;
89  return I->second;
90  }
91 
92  void setGraphSymbol(ELFSymbolIndex SymIndex, Symbol &Sym) {
93  assert(!GraphSymbols.count(SymIndex) && "Duplicate symbol at index");
94  GraphSymbols[SymIndex] = &Sym;
95  }
96 
98  auto I = GraphSymbols.find(SymIndex);
99  if (I == GraphSymbols.end())
100  return nullptr;
101  return I->second;
102  }
103 
105  getSymbolLinkageAndScope(const typename ELFT::Sym &Sym, StringRef Name);
106 
107  Error prepare();
110 
111  /// Traverse all matching ELFT::Rela relocation records in the given section.
112  /// The handler function Func should be callable with this signature:
113  /// Error(const typename ELFT::Rela &,
114  /// const typename ELFT::Shdr &, Section &)
115  ///
116  template <typename RelocHandlerMethod>
117  Error forEachRelaRelocation(const typename ELFT::Shdr &RelSect,
118  RelocHandlerMethod &&Func,
119  bool ProcessDebugSections = false);
120 
121  /// Traverse all matching ELFT::Rel relocation records in the given section.
122  /// The handler function Func should be callable with this signature:
123  /// Error(const typename ELFT::Rel &,
124  /// const typename ELFT::Shdr &, Section &)
125  ///
126  template <typename RelocHandlerMethod>
127  Error forEachRelRelocation(const typename ELFT::Shdr &RelSect,
128  RelocHandlerMethod &&Func,
129  bool ProcessDebugSections = false);
130 
131  /// Traverse all matching rela relocation records in the given section.
132  /// Convenience wrapper to allow passing a member function for the handler.
133  ///
134  template <typename ClassT, typename RelocHandlerMethod>
135  Error forEachRelaRelocation(const typename ELFT::Shdr &RelSect,
136  ClassT *Instance, RelocHandlerMethod &&Method,
137  bool ProcessDebugSections = false) {
138  return forEachRelaRelocation(
139  RelSect,
140  [Instance, Method](const auto &Rel, const auto &Target, auto &GS) {
141  return (Instance->*Method)(Rel, Target, GS);
142  },
143  ProcessDebugSections);
144  }
145 
146  /// Traverse all matching rel relocation records in the given section.
147  /// Convenience wrapper to allow passing a member function for the handler.
148  ///
149  template <typename ClassT, typename RelocHandlerMethod>
150  Error forEachRelRelocation(const typename ELFT::Shdr &RelSect,
151  ClassT *Instance, RelocHandlerMethod &&Method,
152  bool ProcessDebugSections = false) {
153  return forEachRelRelocation(
154  RelSect,
155  [Instance, Method](const auto &Rel, const auto &Target, auto &GS) {
156  return (Instance->*Method)(Rel, Target, GS);
157  },
158  ProcessDebugSections);
159  }
160 
161  const ELFFile &Obj;
162 
163  typename ELFFile::Elf_Shdr_Range Sections;
164  const typename ELFFile::Elf_Shdr *SymTabSec = nullptr;
166 
167  // Maps ELF section indexes to LinkGraph Blocks.
168  // Only SHF_ALLOC sections will have graph blocks.
171  DenseMap<const typename ELFFile::Elf_Shdr *,
174 };
175 
176 template <typename ELFT>
178  const ELFFile &Obj, Triple TT, StringRef FileName,
179  LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)
180  : ELFLinkGraphBuilderBase(std::make_unique<LinkGraph>(
181  FileName.str(), Triple(std::move(TT)), ELFT::Is64Bits ? 8 : 4,
182  support::endianness(ELFT::TargetEndianness),
183  std::move(GetEdgeKindName))),
184  Obj(Obj) {
185  LLVM_DEBUG(
186  { dbgs() << "Created ELFLinkGraphBuilder for \"" << FileName << "\""; });
187 }
188 
189 template <typename ELFT>
191  if (!isRelocatable())
192  return make_error<JITLinkError>("Object is not a relocatable ELF file");
193 
194  if (auto Err = prepare())
195  return std::move(Err);
196 
197  if (auto Err = graphifySections())
198  return std::move(Err);
199 
200  if (auto Err = graphifySymbols())
201  return std::move(Err);
202 
203  if (auto Err = addRelocations())
204  return std::move(Err);
205 
206  return std::move(G);
207 }
208 
209 template <typename ELFT>
212  const typename ELFT::Sym &Sym, StringRef Name) {
213  Linkage L = Linkage::Strong;
215 
216  switch (Sym.getBinding()) {
217  case ELF::STB_LOCAL:
218  S = Scope::Local;
219  break;
220  case ELF::STB_GLOBAL:
221  // Nothing to do here.
222  break;
223  case ELF::STB_WEAK:
224  case ELF::STB_GNU_UNIQUE:
225  L = Linkage::Weak;
226  break;
227  default:
228  return make_error<StringError>(
229  "Unrecognized symbol binding " +
230  Twine(static_cast<int>(Sym.getBinding())) + " for " + Name,
232  }
233 
234  switch (Sym.getVisibility()) {
235  case ELF::STV_DEFAULT:
236  case ELF::STV_PROTECTED:
237  // FIXME: Make STV_DEFAULT symbols pre-emptible? This probably needs
238  // Orc support.
239  // Otherwise nothing to do here.
240  break;
241  case ELF::STV_HIDDEN:
242  // Default scope -> Hidden scope. No effect on local scope.
243  if (S == Scope::Default)
244  S = Scope::Hidden;
245  break;
246  case ELF::STV_INTERNAL:
247  return make_error<StringError>(
248  "Unrecognized symbol visibility " +
249  Twine(static_cast<int>(Sym.getVisibility())) + " for " + Name,
251  }
252 
253  return std::make_pair(L, S);
254 }
255 
256 template <typename ELFT> Error ELFLinkGraphBuilder<ELFT>::prepare() {
257  LLVM_DEBUG(dbgs() << " Preparing to build...\n");
258 
259  // Get the sections array.
260  if (auto SectionsOrErr = Obj.sections())
261  Sections = *SectionsOrErr;
262  else
263  return SectionsOrErr.takeError();
264 
265  // Get the section string table.
266  if (auto SectionStringTabOrErr = Obj.getSectionStringTable(Sections))
267  SectionStringTab = *SectionStringTabOrErr;
268  else
269  return SectionStringTabOrErr.takeError();
270 
271  // Get the SHT_SYMTAB section.
272  for (auto &Sec : Sections) {
273  if (Sec.sh_type == ELF::SHT_SYMTAB) {
274  if (!SymTabSec)
275  SymTabSec = &Sec;
276  else
277  return make_error<JITLinkError>("Multiple SHT_SYMTAB sections in " +
278  G->getName());
279  }
280 
281  // Extended table.
282  if (Sec.sh_type == ELF::SHT_SYMTAB_SHNDX) {
283  uint32_t SymtabNdx = Sec.sh_link;
284  if (SymtabNdx >= Sections.size())
285  return make_error<JITLinkError>("sh_link is out of bound");
286 
287  auto ShndxTable = Obj.getSHNDXTable(Sec);
288  if (!ShndxTable)
289  return ShndxTable.takeError();
290 
291  ShndxTables.insert({&Sections[SymtabNdx], *ShndxTable});
292  }
293  }
294 
295  return Error::success();
296 }
297 
299  LLVM_DEBUG(dbgs() << " Creating graph sections...\n");
300 
301  // For each section...
302  for (ELFSectionIndex SecIndex = 0; SecIndex != Sections.size(); ++SecIndex) {
303 
304  auto &Sec = Sections[SecIndex];
305 
306  // Start by getting the section name.
307  auto Name = Obj.getSectionName(Sec, SectionStringTab);
308  if (!Name)
309  return Name.takeError();
310 
311  // If the name indicates that it's a debug section then skip it: We don't
312  // support those yet.
313  if (isDwarfSection(*Name)) {
314  LLVM_DEBUG({
315  dbgs() << " " << SecIndex << ": \"" << *Name
316  << "\" is a debug section: "
317  "No graph section will be created.\n";
318  });
319  continue;
320  }
321 
322  // Skip non-SHF_ALLOC sections
323  if (!(Sec.sh_flags & ELF::SHF_ALLOC)) {
324  LLVM_DEBUG({
325  dbgs() << " " << SecIndex << ": \"" << *Name
326  << "\" is not an SHF_ALLOC section: "
327  "No graph section will be created.\n";
328  });
329  continue;
330  }
331 
332  LLVM_DEBUG({
333  dbgs() << " " << SecIndex << ": Creating section for \"" << *Name
334  << "\"\n";
335  });
336 
337  // Get the section's memory protection flags.
338  orc::MemProt Prot;
339  if (Sec.sh_flags & ELF::SHF_EXECINSTR)
340  Prot = orc::MemProt::Read | orc::MemProt::Exec;
341  else
342  Prot = orc::MemProt::Read | orc::MemProt::Write;
343 
344  // Look for existing sections first.
345  auto *GraphSec = G->findSectionByName(*Name);
346  if (!GraphSec)
347  GraphSec = &G->createSection(*Name, Prot);
348  assert(GraphSec->getMemProt() == Prot && "MemProt should match");
349 
350  Block *B = nullptr;
351  if (Sec.sh_type != ELF::SHT_NOBITS) {
352  auto Data = Obj.template getSectionContentsAsArray<char>(Sec);
353  if (!Data)
354  return Data.takeError();
355 
356  B = &G->createContentBlock(*GraphSec, *Data,
357  orc::ExecutorAddr(Sec.sh_addr),
358  Sec.sh_addralign, 0);
359  } else
360  B = &G->createZeroFillBlock(*GraphSec, Sec.sh_size,
361  orc::ExecutorAddr(Sec.sh_addr),
362  Sec.sh_addralign, 0);
363 
364  setGraphBlock(SecIndex, B);
365  }
366 
367  return Error::success();
368 }
369 
371  LLVM_DEBUG(dbgs() << " Creating graph symbols...\n");
372 
373  // No SYMTAB -- Bail out early.
374  if (!SymTabSec)
375  return Error::success();
376 
377  // Get the section content as a Symbols array.
378  auto Symbols = Obj.symbols(SymTabSec);
379  if (!Symbols)
380  return Symbols.takeError();
381 
382  // Get the string table for this section.
383  auto StringTab = Obj.getStringTableForSymtab(*SymTabSec, Sections);
384  if (!StringTab)
385  return StringTab.takeError();
386 
387  LLVM_DEBUG({
388  StringRef SymTabName;
389 
390  if (auto SymTabNameOrErr = Obj.getSectionName(*SymTabSec, SectionStringTab))
391  SymTabName = *SymTabNameOrErr;
392  else {
393  dbgs() << "Could not get ELF SHT_SYMTAB section name for logging: "
394  << toString(SymTabNameOrErr.takeError()) << "\n";
395  SymTabName = "<SHT_SYMTAB section with invalid name>";
396  }
397 
398  dbgs() << " Adding symbols from symtab section \"" << SymTabName
399  << "\"\n";
400  });
401 
402  for (ELFSymbolIndex SymIndex = 0; SymIndex != Symbols->size(); ++SymIndex) {
403  auto &Sym = (*Symbols)[SymIndex];
404 
405  // Check symbol type.
406  switch (Sym.getType()) {
407  case ELF::STT_FILE:
408  LLVM_DEBUG({
409  if (auto Name = Sym.getName(*StringTab))
410  dbgs() << " " << SymIndex << ": Skipping STT_FILE symbol \""
411  << *Name << "\"\n";
412  else {
413  dbgs() << "Could not get STT_FILE symbol name: "
414  << toString(Name.takeError()) << "\n";
415  dbgs() << " " << SymIndex
416  << ": Skipping STT_FILE symbol with invalid name\n";
417  }
418  });
419  continue;
420  break;
421  }
422 
423  // Get the symbol name.
424  auto Name = Sym.getName(*StringTab);
425  if (!Name)
426  return Name.takeError();
427 
428  // Handle common symbols specially.
429  if (Sym.isCommon()) {
430  Symbol &GSym = G->addDefinedSymbol(
431  G->createZeroFillBlock(getCommonSection(), Sym.st_size,
432  orc::ExecutorAddr(), Sym.getValue(), 0),
433  0, *Name, Sym.st_size, Linkage::Strong, Scope::Default, false, false);
434  setGraphSymbol(SymIndex, GSym);
435  continue;
436  }
437 
438  if (Sym.isDefined() &&
439  (Sym.getType() == ELF::STT_NOTYPE || Sym.getType() == ELF::STT_FUNC ||
440  Sym.getType() == ELF::STT_OBJECT ||
441  Sym.getType() == ELF::STT_SECTION || Sym.getType() == ELF::STT_TLS)) {
442 
443  // Map Visibility and Binding to Scope and Linkage:
444  Linkage L;
445  Scope S;
446  if (auto LSOrErr = getSymbolLinkageAndScope(Sym, *Name))
447  std::tie(L, S) = *LSOrErr;
448  else
449  return LSOrErr.takeError();
450 
451  // Handle extended tables.
452  unsigned Shndx = Sym.st_shndx;
453  if (Shndx == ELF::SHN_XINDEX) {
454  auto ShndxTable = ShndxTables.find(SymTabSec);
455  if (ShndxTable == ShndxTables.end())
456  continue;
457  auto NdxOrErr = object::getExtendedSymbolTableIndex<ELFT>(
458  Sym, SymIndex, ShndxTable->second);
459  if (!NdxOrErr)
460  return NdxOrErr.takeError();
461  Shndx = *NdxOrErr;
462  }
463  if (auto *B = getGraphBlock(Shndx)) {
464  LLVM_DEBUG({
465  dbgs() << " " << SymIndex
466  << ": Creating defined graph symbol for ELF symbol \"" << *Name
467  << "\"\n";
468  });
469 
470  // In RISCV, temporary symbols (Used to generate dwarf, eh_frame
471  // sections...) will appear in object code's symbol table, and LLVM does
472  // not use names on these temporary symbols (RISCV gnu toolchain uses
473  // names on these temporary symbols). If the symbol is unnamed, add an
474  // anonymous symbol.
475  auto &GSym =
476  Name->empty()
477  ? G->addAnonymousSymbol(*B, Sym.getValue(), Sym.st_size,
478  false, false)
479  : G->addDefinedSymbol(*B, Sym.getValue(), *Name, Sym.st_size, L,
480  S, Sym.getType() == ELF::STT_FUNC, false);
481  setGraphSymbol(SymIndex, GSym);
482  }
483  } else if (Sym.isUndefined() && Sym.isExternal()) {
484  LLVM_DEBUG({
485  dbgs() << " " << SymIndex
486  << ": Creating external graph symbol for ELF symbol \"" << *Name
487  << "\"\n";
488  });
489 
490  if (Sym.getBinding() != ELF::STB_GLOBAL &&
491  Sym.getBinding() != ELF::STB_WEAK)
492  return make_error<StringError>(
493  "Invalid symbol binding " +
494  Twine(static_cast<int>(Sym.getBinding())) +
495  " for external symbol " + *Name,
497 
498  // If L is Linkage::Weak that means this is a weakly referenced symbol.
499  auto &GSym = G->addExternalSymbol(*Name, Sym.st_size,
500  Sym.getBinding() == ELF::STB_WEAK);
501  setGraphSymbol(SymIndex, GSym);
502  } else {
503  LLVM_DEBUG({
504  dbgs() << " " << SymIndex
505  << ": Not creating graph symbol for ELF symbol \"" << *Name
506  << "\" with unrecognized type\n";
507  });
508  }
509  }
510 
511  return Error::success();
512 }
513 
514 template <typename ELFT>
515 template <typename RelocHandlerFunction>
517  const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func,
518  bool ProcessDebugSections) {
519  // Only look into sections that store relocation entries.
520  if (RelSect.sh_type != ELF::SHT_RELA)
521  return Error::success();
522 
523  // sh_info contains the section header index of the target (FixupSection),
524  // which is the section to which all relocations in RelSect apply.
525  auto FixupSection = Obj.getSection(RelSect.sh_info);
526  if (!FixupSection)
527  return FixupSection.takeError();
528 
529  // Target sections have names in valid ELF object files.
530  Expected<StringRef> Name = Obj.getSectionName(**FixupSection);
531  if (!Name)
532  return Name.takeError();
533  LLVM_DEBUG(dbgs() << " " << *Name << ":\n");
534 
535  // Consider skipping these relocations.
536  if (!ProcessDebugSections && isDwarfSection(*Name)) {
537  LLVM_DEBUG(dbgs() << " skipped (dwarf section)\n\n");
538  return Error::success();
539  }
540 
541  // Lookup the link-graph node corresponding to the target section name.
542  auto *BlockToFix = getGraphBlock(RelSect.sh_info);
543  if (!BlockToFix)
544  return make_error<StringError>(
545  "Refencing a section that wasn't added to the graph: " + *Name,
547 
548  auto RelEntries = Obj.relas(RelSect);
549  if (!RelEntries)
550  return RelEntries.takeError();
551 
552  // Let the callee process relocation entries one by one.
553  for (const typename ELFT::Rela &R : *RelEntries)
554  if (Error Err = Func(R, **FixupSection, *BlockToFix))
555  return Err;
556 
557  LLVM_DEBUG(dbgs() << "\n");
558  return Error::success();
559 }
560 
561 template <typename ELFT>
562 template <typename RelocHandlerFunction>
564  const typename ELFT::Shdr &RelSect, RelocHandlerFunction &&Func,
565  bool ProcessDebugSections) {
566  // Only look into sections that store relocation entries.
567  if (RelSect.sh_type != ELF::SHT_REL)
568  return Error::success();
569 
570  // sh_info contains the section header index of the target (FixupSection),
571  // which is the section to which all relocations in RelSect apply.
572  auto FixupSection = Obj.getSection(RelSect.sh_info);
573  if (!FixupSection)
574  return FixupSection.takeError();
575 
576  // Target sections have names in valid ELF object files.
577  Expected<StringRef> Name = Obj.getSectionName(**FixupSection);
578  if (!Name)
579  return Name.takeError();
580  LLVM_DEBUG(dbgs() << " " << *Name << ":\n");
581 
582  // Consider skipping these relocations.
583  if (!ProcessDebugSections && isDwarfSection(*Name)) {
584  LLVM_DEBUG(dbgs() << " skipped (dwarf section)\n\n");
585  return Error::success();
586  }
587 
588  // Lookup the link-graph node corresponding to the target section name.
589  auto *BlockToFix = getGraphBlock(RelSect.sh_info);
590  if (!BlockToFix)
591  return make_error<StringError>(
592  "Refencing a section that wasn't added to the graph: " + *Name,
594 
595  auto RelEntries = Obj.rels(RelSect);
596  if (!RelEntries)
597  return RelEntries.takeError();
598 
599  // Let the callee process relocation entries one by one.
600  for (const typename ELFT::Rel &R : *RelEntries)
601  if (Error Err = Func(R, **FixupSection, *BlockToFix))
602  return Err;
603 
604  LLVM_DEBUG(dbgs() << "\n");
605  return Error::success();
606 }
607 
608 } // end namespace jitlink
609 } // end namespace llvm
610 
611 #undef DEBUG_TYPE
612 
613 #endif // LIB_EXECUTIONENGINE_JITLINK_ELFLINKGRAPHBUILDER_H
llvm::orc::ExecutorAddr
Represents an address in the executor process.
Definition: ExecutorAddress.h:31
llvm::ELF::STT_TLS
@ STT_TLS
Definition: ELF.h:1235
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::ELF::STB_GLOBAL
@ STB_GLOBAL
Definition: ELF.h:1218
llvm::ELF::SHF_EXECINSTR
@ SHF_EXECINSTR
Definition: ELF.h:1067
llvm::Target
Target - Wrapper for Target specific information.
Definition: TargetRegistry.h:149
Error.h
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
llvm::orc::ExecutorAddr::getValue
uint64_t getValue() const
Definition: ExecutorAddress.h:105
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:140
llvm::ELF::SHT_NOBITS
@ SHT_NOBITS
Definition: ELF.h:987
llvm::ELF::STT_NOTYPE
@ STT_NOTYPE
Definition: ELF.h:1229
llvm::ELF::SHT_SYMTAB
@ SHT_SYMTAB
Definition: ELF.h:981
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
llvm::wasm::toString
llvm::StringRef toString(WasmSymbolType type)
Definition: Wasm.cpp:11
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::ELF::STV_HIDDEN
@ STV_HIDDEN
Definition: ELF.h:1249
llvm::RISCVFenceField::R
@ R
Definition: RISCVBaseInfo.h:265
llvm::ELF::STT_FUNC
@ STT_FUNC
Definition: ELF.h:1231
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::ELF::STV_PROTECTED
@ STV_PROTECTED
Definition: ELF.h:1250
llvm::ELF::STB_GNU_UNIQUE
@ STB_GNU_UNIQUE
Definition: ELF.h:1220
llvm::orc::MemProt::Read
@ Read
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
FormatVariadic.h
G
const DataFlowGraph & G
Definition: RDFGraph.cpp:200
llvm::ELF::STT_SECTION
@ STT_SECTION
Definition: ELF.h:1232
llvm::orc::MemProt
MemProt
Describes Read/Write/Exec permissions for memory.
Definition: MemoryFlags.h:27
ELF.h
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
Definition: DenseMap.h:714
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::is_contained
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
Definition: STLExtras.h:1843
llvm::ELF::SHF_ALLOC
@ SHF_ALLOC
Definition: ELF.h:1064
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::move
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1836
llvm::ArrayRef< const char * >
llvm::X86AS::GS
@ GS
Definition: X86.h:199
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm::ELF::SHN_XINDEX
@ SHN_XINDEX
Definition: ELF.h:973
uint32_t
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::object::ELFFile::getHeader
const Elf_Ehdr & getHeader() const
Definition: ELF.h:191
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
std
Definition: BitVector.h:851
llvm::inconvertibleErrorCode
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:79
llvm::SectionName
Definition: DWARFSection.h:21
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
llvm::TargetStackID::Default
@ Default
Definition: TargetFrameLowering.h:28
llvm::ELF::ET_REL
@ ET_REL
Definition: ELF.h:116
llvm::ELF::STV_INTERNAL
@ STV_INTERNAL
Definition: ELF.h:1248
llvm::ELF::SHT_RELA
@ SHT_RELA
Definition: ELF.h:983
llvm::ELF::STB_WEAK
@ STB_WEAK
Definition: ELF.h:1219
llvm::ELF::SHT_SYMTAB_SHNDX
@ SHT_SYMTAB_SHNDX
Definition: ELF.h:995
support
Reimplement select in terms of SEL *We would really like to support but we need to prove that the add doesn t need to overflow between the two bit chunks *Implement pre post increment support(e.g. PR935) *Implement smarter const ant generation for binops with large immediates. A few ARMv6T2 ops should be pattern matched
Definition: README.txt:10
llvm::ELF::STB_LOCAL
@ STB_LOCAL
Definition: ELF.h:1217
llvm::ELF::STV_DEFAULT
@ STV_DEFAULT
Definition: ELF.h:1247
llvm::support::endianness
endianness
Definition: Endian.h:27
isDwarfSection
static bool isDwarfSection(const MCObjectFileInfo *FI, const MCSection *Section)
Definition: NVPTXTargetStreamer.cpp:45
llvm::ELF::STT_FILE
@ STT_FILE
Definition: ELF.h:1233
llvm::ELF::STT_OBJECT
@ STT_OBJECT
Definition: ELF.h:1230
llvm::ELF::SHT_REL
@ SHT_REL
Definition: ELF.h:988
llvm::object::ELFFile
Definition: ELF.h:95
Debug.h
Shdr
Elf_Shdr Shdr
Definition: ELFObjHandler.cpp:78
llvm::orc::MemProt::Write
@ Write