LLVM  16.0.0git
MachOLinkGraphBuilder.h
Go to the documentation of this file.
1 //===----- MachOLinkGraphBuilder.h - MachO 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 MachO LinkGraph building code.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LIB_EXECUTIONENGINE_JITLINK_MACHOLINKGRAPHBUILDER_H
14 #define LIB_EXECUTIONENGINE_JITLINK_MACHOLINKGRAPHBUILDER_H
15 
16 #include "llvm/ADT/DenseMap.h"
17 #include "llvm/ADT/StringMap.h"
19 #include "llvm/Object/MachO.h"
20 
21 #include "EHFrameSupportImpl.h"
22 #include "JITLinkGeneric.h"
23 
24 #include <list>
25 
26 namespace llvm {
27 namespace jitlink {
28 
30 public:
31  virtual ~MachOLinkGraphBuilder();
33 
34 protected:
35 
37  friend class MachOLinkGraphBuilder;
38 
39  private:
41  uint8_t Sect, uint16_t Desc, Linkage L, Scope S)
42  : Name(Name), Value(Value), Type(Type), Sect(Sect), Desc(Desc), L(L),
43  S(S) {
44  assert((!Name || !Name->empty()) && "Name must be none or non-empty");
45  }
46 
47  public:
48  NormalizedSymbol(const NormalizedSymbol &) = delete;
49  NormalizedSymbol &operator=(const NormalizedSymbol &) = delete;
52 
55  uint8_t Type = 0;
56  uint8_t Sect = 0;
60  Symbol *GraphSymbol = nullptr;
61  };
62 
63  // Normalized section representation. Section and segment names are guaranteed
64  // to be null-terminated, hence the extra bytes on SegName and SectName.
66  friend class MachOLinkGraphBuilder;
67 
68  private:
69  NormalizedSection() = default;
70 
71  public:
72  char SectName[17];
73  char SegName[17];
78  const char *Data = nullptr;
79  Section *GraphSection = nullptr;
80  std::map<orc::ExecutorAddr, Symbol *> CanonicalSymbols;
81  };
82 
84 
86  LinkGraph::GetEdgeKindNameFunction GetEdgeKindName);
87 
88  LinkGraph &getGraph() const { return *G; }
89 
90  const object::MachOObjectFile &getObject() const { return Obj; }
91 
93  SectionParserFunction Parse);
94 
95  virtual Error addRelocations() = 0;
96 
97  /// Create a symbol.
98  template <typename... ArgTs>
100  NormalizedSymbol *Sym = reinterpret_cast<NormalizedSymbol *>(
101  Allocator.Allocate<NormalizedSymbol>());
102  new (Sym) NormalizedSymbol(std::forward<ArgTs>(Args)...);
103  return *Sym;
104  }
105 
106  /// Index is zero-based (MachO section indexes are usually one-based) and
107  /// assumed to be in-range. Client is responsible for checking.
109  auto I = IndexToSection.find(Index);
110  assert(I != IndexToSection.end() && "No section recorded at index");
111  return I->second;
112  }
113 
114  /// Try to get the section at the given index. Will return an error if the
115  /// given index is out of range, or if no section has been added for the given
116  /// index.
118  auto I = IndexToSection.find(Index);
119  if (I == IndexToSection.end())
120  return make_error<JITLinkError>("No section recorded for index " +
121  formatv("{0:d}", Index));
122  return I->second;
123  }
124 
125  /// Try to get the symbol at the given index. Will return an error if the
126  /// given index is out of range, or if no symbol has been added for the given
127  /// index.
129  auto I = IndexToSymbol.find(Index);
130  if (I == IndexToSymbol.end())
131  return make_error<JITLinkError>("No symbol at index " +
132  formatv("{0:d}", Index));
133  assert(I->second && "Null symbol at index");
134  return *I->second;
135  }
136 
137  /// Returns the symbol with the highest address not greater than the search
138  /// address, or null if no such symbol exists.
140  orc::ExecutorAddr Address) {
141  auto I = NSec.CanonicalSymbols.upper_bound(Address);
142  if (I == NSec.CanonicalSymbols.begin())
143  return nullptr;
144  return std::prev(I)->second;
145  }
146 
147  /// Returns the symbol with the highest address not greater than the search
148  /// address, or an error if no such symbol exists.
150  orc::ExecutorAddr Address) {
151  auto *Sym = getSymbolByAddress(NSec, Address);
152  if (Sym)
153  if (Address <= Sym->getAddress() + Sym->getSize())
154  return *Sym;
155  return make_error<JITLinkError>("No symbol covering address " +
156  formatv("{0:x16}", Address));
157  }
158 
159  static Linkage getLinkage(uint16_t Desc);
160  static Scope getScope(StringRef Name, uint8_t Type);
161  static bool isAltEntry(const NormalizedSymbol &NSym);
162 
163  static bool isDebugSection(const NormalizedSection &NSec);
164  static bool isZeroFillSection(const NormalizedSection &NSec);
165 
169  getObject().getRelocation(RelItr->getRawDataRefImpl());
171  RI.r_address = ARI.r_word0;
172  RI.r_symbolnum = ARI.r_word1 & 0xffffff;
173  RI.r_pcrel = (ARI.r_word1 >> 24) & 1;
174  RI.r_length = (ARI.r_word1 >> 25) & 3;
175  RI.r_extern = (ARI.r_word1 >> 27) & 1;
176  RI.r_type = (ARI.r_word1 >> 28);
177  return RI;
178  }
179 
180 private:
181  static unsigned getPointerSize(const object::MachOObjectFile &Obj);
182  static support::endianness getEndianness(const object::MachOObjectFile &Obj);
183 
184  void setCanonicalSymbol(NormalizedSection &NSec, Symbol &Sym) {
185  auto *&CanonicalSymEntry = NSec.CanonicalSymbols[Sym.getAddress()];
186  // There should be no symbol at this address, or, if there is,
187  // it should be a zero-sized symbol from an empty section (which
188  // we can safely override).
189  assert((!CanonicalSymEntry || CanonicalSymEntry->getSize() == 0) &&
190  "Duplicate canonical symbol at address");
191  CanonicalSymEntry = &Sym;
192  }
193 
194  Section &getCommonSection();
195  void addSectionStartSymAndBlock(unsigned SecIndex, Section &GraphSec,
196  orc::ExecutorAddr Address, const char *Data,
198  uint32_t Alignment, bool IsLive);
199 
200  Error createNormalizedSections();
201  Error createNormalizedSymbols();
202 
203  /// Create graph blocks and symbols for externals, absolutes, commons and
204  /// all defined symbols in sections without custom parsers.
205  Error graphifyRegularSymbols();
206 
207  /// Create and return a graph symbol for the given normalized symbol.
208  ///
209  /// NSym's GraphSymbol member will be updated to point at the newly created
210  /// symbol.
211  Symbol &createStandardGraphSymbol(NormalizedSymbol &Sym, Block &B,
212  size_t Size, bool IsText,
213  bool IsNoDeadStrip, bool IsCanonical);
214 
215  /// Create graph blocks and symbols for all sections.
216  Error graphifySectionsWithCustomParsers();
217 
218  /// Graphify cstring section.
219  Error graphifyCStringSection(NormalizedSection &NSec,
220  std::vector<NormalizedSymbol *> NSyms);
221 
222  // Put the BumpPtrAllocator first so that we don't free any of the underlying
223  // memory until the Symbol/Addressable destructors have been run.
225 
226  const object::MachOObjectFile &Obj;
227  std::unique_ptr<LinkGraph> G;
228 
229  bool SubsectionsViaSymbols = false;
231  Section *CommonSection = nullptr;
232 
234  StringMap<SectionParserFunction> CustomSectionParserFunctions;
235 };
236 
237 /// A pass to split up __LD,__compact_unwind sections.
239 public:
240  CompactUnwindSplitter(StringRef CompactUnwindSectionName)
241  : CompactUnwindSectionName(CompactUnwindSectionName) {}
243 
244 private:
245  StringRef CompactUnwindSectionName;
246 };
247 
248 } // end namespace jitlink
249 } // end namespace llvm
250 
251 #endif // LIB_EXECUTIONENGINE_JITLINK_MACHOLINKGRAPHBUILDER_H
llvm::orc::ExecutorAddr
Represents an address in the executor process.
Definition: ExecutorAddress.h:31
getPointerSize
static uint64_t getPointerSize(const Value *V, const DataLayout &DL, const TargetLibraryInfo &TLI, const Function *F)
Definition: DeadStoreElimination.cpp:209
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::MachO::any_relocation_info
Definition: MachO.h:996
llvm::MachO::relocation_info::r_length
uint32_t r_length
Definition: MachO.h:980
llvm::lltok::Error
@ Error
Definition: LLToken.h:21
llvm::MachO::relocation_info::r_address
int32_t r_address
Definition: MachO.h:979
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
DenseMap.h
llvm::Optional
Definition: APInt.h:33
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
MachO.h
llvm::ARMBuildAttrs::Section
@ Section
Legacy Tags.
Definition: ARMBuildAttributes.h:82
llvm::formatv
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
Definition: FormatVariadic.h:251
llvm::MachO::any_relocation_info::r_word1
uint32_t r_word1
Definition: MachO.h:997
llvm::object::MachOObjectFile::getRelocation
MachO::any_relocation_info getRelocation(DataRefImpl Rel) const
Definition: MachOObjectFile.cpp:4751
llvm::dwarf::Index
Index
Definition: Dwarf.h:472
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::StringMap< SectionParserFunction >
llvm::object::MachOObjectFile
Definition: MachO.h:406
G
const DataFlowGraph & G
Definition: RDFGraph.cpp:200
llvm::MachO::relocation_info
Definition: MachO.h:978
uint64_t
llvm::MachO::relocation_info::r_type
uint32_t r_type
Definition: MachO.h:981
llvm::MachO::relocation_info::r_extern
uint32_t r_extern
Definition: MachO.h:980
llvm::BumpPtrAllocatorImpl
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:63
llvm::MachO::any_relocation_info::r_word0
uint32_t r_word0
Definition: MachO.h:997
llvm::DenseMap
Definition: DenseMap.h:714
I
#define I(x, y, z)
Definition: MD5.cpp:58
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::object::content_iterator
Definition: SymbolicFile.h:69
function
print Print MemDeps of function
Definition: MemDepPrinter.cpp:82
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
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::GraphProgram::Name
Name
Definition: GraphWriter.h:50
uint16_t
llvm::SectionName
Definition: DWARFSection.h:21
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
EHFrameSupportImpl.h
llvm::ARMBuildAttrs::Symbol
@ Symbol
Definition: ARMBuildAttributes.h:83
Allocator
Basic Register Allocator
Definition: RegAllocBasic.cpp:143
llvm::support::endianness
endianness
Definition: Endian.h:27
llvm::MachO::relocation_info::r_pcrel
uint32_t r_pcrel
Definition: MachO.h:980
StringMap.h
InlinePriorityMode::Size
@ Size
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:394
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
JITLinkGeneric.h
llvm::MachO::relocation_info::r_symbolnum
uint32_t r_symbolnum
Definition: MachO.h:980