LLVM  14.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  };
81 
83 
85  LinkGraph::GetEdgeKindNameFunction GetEdgeKindName);
86 
87  LinkGraph &getGraph() const { return *G; }
88 
89  const object::MachOObjectFile &getObject() const { return Obj; }
90 
92  SectionParserFunction Parse);
93 
94  virtual Error addRelocations() = 0;
95 
96  /// Create a symbol.
97  template <typename... ArgTs>
99  NormalizedSymbol *Sym = reinterpret_cast<NormalizedSymbol *>(
100  Allocator.Allocate<NormalizedSymbol>());
101  new (Sym) NormalizedSymbol(std::forward<ArgTs>(Args)...);
102  return *Sym;
103  }
104 
105  /// Index is zero-based (MachO section indexes are usually one-based) and
106  /// assumed to be in-range. Client is responsible for checking.
108  auto I = IndexToSection.find(Index);
109  assert(I != IndexToSection.end() && "No section recorded at index");
110  return I->second;
111  }
112 
113  /// Try to get the section at the given index. Will return an error if the
114  /// given index is out of range, or if no section has been added for the given
115  /// index.
117  auto I = IndexToSection.find(Index);
118  if (I == IndexToSection.end())
119  return make_error<JITLinkError>("No section recorded for index " +
120  formatv("{0:d}", Index));
121  return I->second;
122  }
123 
124  /// Try to get the symbol at the given index. Will return an error if the
125  /// given index is out of range, or if no symbol has been added for the given
126  /// index.
128  if (Index >= IndexToSymbol.size())
129  return make_error<JITLinkError>("Symbol index out of range");
130  auto *Sym = IndexToSymbol[Index];
131  if (!Sym)
132  return make_error<JITLinkError>("No symbol at index " +
133  formatv("{0:d}", Index));
134  return *Sym;
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  auto I = AddrToCanonicalSymbol.upper_bound(Address);
141  if (I == AddrToCanonicalSymbol.begin())
142  return nullptr;
143  return std::prev(I)->second;
144  }
145 
146  /// Returns the symbol with the highest address not greater than the search
147  /// address, or an error if no such symbol exists.
149  auto *Sym = getSymbolByAddress(Address);
150  if (Sym)
151  if (Address < Sym->getAddress() + Sym->getSize())
152  return *Sym;
153  return make_error<JITLinkError>("No symbol covering address " +
154  formatv("{0:x16}", Address));
155  }
156 
157  static Linkage getLinkage(uint16_t Desc);
158  static Scope getScope(StringRef Name, uint8_t Type);
159  static bool isAltEntry(const NormalizedSymbol &NSym);
160 
161  static bool isDebugSection(const NormalizedSection &NSec);
162  static bool isZeroFillSection(const NormalizedSection &NSec);
163 
167  getObject().getRelocation(RelItr->getRawDataRefImpl());
169  RI.r_address = ARI.r_word0;
170  RI.r_symbolnum = ARI.r_word1 & 0xffffff;
171  RI.r_pcrel = (ARI.r_word1 >> 24) & 1;
172  RI.r_length = (ARI.r_word1 >> 25) & 3;
173  RI.r_extern = (ARI.r_word1 >> 27) & 1;
174  RI.r_type = (ARI.r_word1 >> 28);
175  return RI;
176  }
177 
178 private:
179  static unsigned getPointerSize(const object::MachOObjectFile &Obj);
180  static support::endianness getEndianness(const object::MachOObjectFile &Obj);
181 
182  void setCanonicalSymbol(Symbol &Sym) {
183  auto *&CanonicalSymEntry = AddrToCanonicalSymbol[Sym.getAddress()];
184  // There should be no symbol at this address, or, if there is,
185  // it should be a zero-sized symbol from an empty section (which
186  // we can safely override).
187  assert((!CanonicalSymEntry || CanonicalSymEntry->getSize() == 0) &&
188  "Duplicate canonical symbol at address");
189  CanonicalSymEntry = &Sym;
190  }
191 
192  Section &getCommonSection();
193  void addSectionStartSymAndBlock(Section &GraphSec, uint64_t Address,
194  const char *Data, uint64_t Size,
195  uint32_t Alignment, bool IsLive);
196 
197  Error createNormalizedSections();
198  Error createNormalizedSymbols();
199 
200  /// Create graph blocks and symbols for externals, absolutes, commons and
201  /// all defined symbols in sections without custom parsers.
202  Error graphifyRegularSymbols();
203 
204  /// Create and return a graph symbol for the given normalized symbol.
205  ///
206  /// NSym's GraphSymbol member will be updated to point at the newly created
207  /// symbol.
208  Symbol &createStandardGraphSymbol(NormalizedSymbol &Sym, Block &B,
209  size_t Size, bool IsText,
210  bool IsNoDeadStrip, bool IsCanonical);
211 
212  /// Create graph blocks and symbols for all sections.
213  Error graphifySectionsWithCustomParsers();
214 
215  /// Graphify cstring section.
216  Error graphifyCStringSection(NormalizedSection &NSec,
217  std::vector<NormalizedSymbol *> NSyms);
218 
219  // Put the BumpPtrAllocator first so that we don't free any of the underlying
220  // memory until the Symbol/Addressable destructors have been run.
222 
223  const object::MachOObjectFile &Obj;
224  std::unique_ptr<LinkGraph> G;
225 
227  Section *CommonSection = nullptr;
228 
230  std::map<JITTargetAddress, Symbol *> AddrToCanonicalSymbol;
231  StringMap<SectionParserFunction> CustomSectionParserFunctions;
232 };
233 
234 /// A pass to split up __LD,__compact_unwind sections.
236 public:
237  CompactUnwindSplitter(StringRef CompactUnwindSectionName)
238  : CompactUnwindSectionName(CompactUnwindSectionName) {}
240 
241 private:
242  StringRef CompactUnwindSectionName;
243 };
244 
245 } // end namespace jitlink
246 } // end namespace llvm
247 
248 #endif // LIB_EXECUTIONENGINE_JITLINK_MACHOLINKGRAPHBUILDER_H
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
getPointerSize
static uint64_t getPointerSize(const Value *V, const DataLayout &DL, const TargetLibraryInfo &TLI, const Function *F)
Definition: DeadStoreElimination.cpp:312
llvm
This file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
llvm::MachO::any_relocation_info
Definition: MachO.h:975
llvm::MachO::relocation_info::r_length
uint32_t r_length
Definition: MachO.h:959
llvm::lltok::Error
@ Error
Definition: LLToken.h:21
llvm::MachO::relocation_info::r_address
int32_t r_address
Definition: MachO.h:958
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:45
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:42
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
MachO.h
llvm::ARMBuildAttrs::Section
@ Section
Legacy Tags.
Definition: ARMBuildAttributes.h:78
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:250
llvm::MachO::any_relocation_info::r_word1
uint32_t r_word1
Definition: MachO.h:976
llvm::object::MachOObjectFile::getRelocation
MachO::any_relocation_info getRelocation(DataRefImpl Rel) const
Definition: MachOObjectFile.cpp:4424
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
StringMap.h
llvm::StringMap< SectionParserFunction >
llvm::object::MachOObjectFile
Definition: MachO.h:262
G
const DataFlowGraph & G
Definition: RDFGraph.cpp:202
llvm::MachO::relocation_info
Definition: MachO.h:957
Index
uint32_t Index
Definition: ELFObjHandler.cpp:84
uint64_t
llvm::MachO::relocation_info::r_type
uint32_t r_type
Definition: MachO.h:960
llvm::MachO::relocation_info::r_extern
uint32_t r_extern
Definition: MachO.h:959
llvm::BumpPtrAllocatorImpl
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:67
llvm::MachO::any_relocation_info::r_word0
uint32_t r_word0
Definition: MachO.h:976
llvm::DenseMap
Definition: DenseMap.h:714
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::HighlightColor::Address
@ Address
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::object::content_iterator
Definition: SymbolicFile.h:67
function
print Print MemDeps of function
Definition: MemDepPrinter.cpp:83
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
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:52
uint16_t
llvm::SectionName
Definition: DWARFSection.h:21
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
EHFrameSupportImpl.h
llvm::ARMBuildAttrs::Symbol
@ Symbol
Definition: ARMBuildAttributes.h:79
Allocator
Basic Register Allocator
Definition: RegAllocBasic.cpp:146
llvm::support::endianness
endianness
Definition: Endian.h:27
llvm::MachO::relocation_info::r_pcrel
uint32_t r_pcrel
Definition: MachO.h:959
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:389
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
JITLinkGeneric.h
llvm::MachO::relocation_info::r_symbolnum
uint32_t r_symbolnum
Definition: MachO.h:959