blob: 72d441b24d065c554669b93804e61f1b89e44ed9 [file] [log] [blame]
Lang Hames11c8dfa52019-04-20 17:10:34 +00001//===----- MachOAtomGraphBuilder.h - MachO AtomGraph 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 AtomGraph building code.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LIB_EXECUTIONENGINE_JITLINK_MACHOATOMGRAPHBUILDER_H
14#define LIB_EXECUTIONENGINE_JITLINK_MACHOATOMGRAPHBUILDER_H
15
16#include "llvm/ExecutionEngine/JITLink/JITLink.h"
17
18#include "JITLinkGeneric.h"
19
20#include "llvm/Object/MachO.h"
21
22namespace llvm {
23namespace jitlink {
24
25class MachOAtomGraphBuilder {
26public:
27 virtual ~MachOAtomGraphBuilder();
28 Expected<std::unique_ptr<AtomGraph>> buildGraph();
29
30protected:
31 using OffsetToAtomMap = std::map<JITTargetAddress, DefinedAtom *>;
32
33 class MachOSection {
34 public:
35 MachOSection() = default;
36
Lang Hamesb0cecfc2019-05-10 22:24:37 +000037 /// Create a MachO section with the given address and alignment.
Lang Hames11c8dfa52019-04-20 17:10:34 +000038 MachOSection(Section &GenericSection, JITTargetAddress Address,
Lang Hamesb0cecfc2019-05-10 22:24:37 +000039 unsigned Alignment)
Lang Hames11c8dfa52019-04-20 17:10:34 +000040 : Address(Address), GenericSection(&GenericSection),
Lang Hames11c8dfa52019-04-20 17:10:34 +000041 Alignment(Alignment) {}
42
43 /// Create a section without address, content or size (used for common
44 /// symbol sections).
45 MachOSection(Section &GenericSection) : GenericSection(&GenericSection) {}
46
47 Section &getGenericSection() const {
48 assert(GenericSection && "Section is null");
49 return *GenericSection;
50 }
51
52 StringRef getName() const {
53 assert(GenericSection && "No generic section attached");
54 return GenericSection->getName();
55 }
56
Lang Hamesb0cecfc2019-05-10 22:24:37 +000057 MachOSection &setContent(StringRef Content) {
58 assert(!ContentPtr && !Size && "Content/zeroFill already set");
59 ContentPtr = Content.data();
60 Size = Content.size();
61 return *this;
62 }
63
64 MachOSection &setZeroFill(uint64_t Size) {
Lang Hames23085ec2019-05-12 22:26:33 +000065 assert(!ContentPtr && !this->Size && "Content/zeroFill already set");
Lang Hamesb0cecfc2019-05-10 22:24:37 +000066 this->Size = Size;
67 return *this;
68 }
69
Lang Hames11c8dfa52019-04-20 17:10:34 +000070 bool isZeroFill() const { return !ContentPtr; }
71
72 bool empty() const { return getSize() == 0; }
73
74 size_t getSize() const { return Size; }
75
76 StringRef getContent() const {
77 assert(ContentPtr && "getContent() called on zero-fill section");
Lang Hamesb3d60732019-05-10 22:51:03 +000078 return {ContentPtr, static_cast<size_t>(Size)};
Lang Hames11c8dfa52019-04-20 17:10:34 +000079 }
80
81 JITTargetAddress getAddress() const { return Address; }
82
83 unsigned getAlignment() const { return Alignment; }
84
Lang Hamesb0cecfc2019-05-10 22:24:37 +000085 MachOSection &setNoDeadStrip(bool NoDeadStrip) {
86 this->NoDeadStrip = NoDeadStrip;
87 return *this;
88 }
89
90 bool isNoDeadStrip() const { return NoDeadStrip; }
91
Lang Hames11c8dfa52019-04-20 17:10:34 +000092 private:
93 JITTargetAddress Address = 0;
94 Section *GenericSection = nullptr;
95 const char *ContentPtr = nullptr;
Lang Hamesb0cecfc2019-05-10 22:24:37 +000096 uint64_t Size = 0;
Lang Hames11c8dfa52019-04-20 17:10:34 +000097 unsigned Alignment = 0;
Lang Hamesb0cecfc2019-05-10 22:24:37 +000098 bool NoDeadStrip = false;
Lang Hames11c8dfa52019-04-20 17:10:34 +000099 };
100
101 using CustomAtomizeFunction = std::function<Error(MachOSection &S)>;
102
103 MachOAtomGraphBuilder(const object::MachOObjectFile &Obj);
104
105 AtomGraph &getGraph() const { return *G; }
106
107 const object::MachOObjectFile &getObject() const { return Obj; }
108
109 void addCustomAtomizer(StringRef SectionName, CustomAtomizeFunction Atomizer);
110
111 virtual Error addRelocations() = 0;
112
Lang Hames0d8ae1e2019-05-07 22:56:40 +0000113 /// Returns true if Atom A and Atom B are at a fixed offset from one another
114 /// (i.e. if they're part of the same alt-entry chain).
115 bool areLayoutLocked(const Atom &A, const Atom &B);
116
Lang Hames11c8dfa52019-04-20 17:10:34 +0000117private:
118 static unsigned getPointerSize(const object::MachOObjectFile &Obj);
119 static support::endianness getEndianness(const object::MachOObjectFile &Obj);
120
121 MachOSection &getCommonSection();
122
123 Error parseSections();
124 Error addNonCustomAtoms();
125 Error addAtoms();
126
127 const object::MachOObjectFile &Obj;
128 std::unique_ptr<AtomGraph> G;
Lang Hames0d8ae1e2019-05-07 22:56:40 +0000129 DenseMap<const DefinedAtom *, const DefinedAtom *> AltEntryStarts;
Lang Hames11c8dfa52019-04-20 17:10:34 +0000130 DenseMap<unsigned, MachOSection> Sections;
131 StringMap<CustomAtomizeFunction> CustomAtomizeFunctions;
132 Optional<MachOSection> CommonSymbolsSection;
133};
134
135} // end namespace jitlink
136} // end namespace llvm
137
138#endif // LIB_EXECUTIONENGINE_JITLINK_MACHOATOMGRAPHBUILDER_H