blob: 6fb8211dcea64a8bf97ef89ec10ff74242648083 [file] [log] [blame]
Nick Kledzik2458bec2014-07-16 19:49:02 +00001//===- lib/FileFormat/MachO/ArchHandler.h ---------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "MachONormalizedFile.h"
Nick Kledzik7e9808f2014-07-23 00:51:37 +000011#include "Atoms.h"
Nick Kledzik2458bec2014-07-16 19:49:02 +000012
13#include "lld/Core/LLVM.h"
14#include "lld/Core/Reference.h"
15#include "lld/Core/Simple.h"
16#include "lld/ReaderWriter/MachOLinkingContext.h"
17
18#include "llvm/ADT/Triple.h"
19
20#ifndef LLD_READER_WRITER_MACHO_ARCH_HANDLER_H
21#define LLD_READER_WRITER_MACHO_ARCH_HANDLER_H
22
23namespace lld {
24namespace mach_o {
25
26///
27/// The ArchHandler class handles all architecture specific aspects of
28/// mach-o linking.
29///
30class ArchHandler {
31public:
32 virtual ~ArchHandler();
33
34 /// There is no public interface to subclasses of ArchHandler, so this
35 /// is the only way to instantiate an ArchHandler.
36 static std::unique_ptr<ArchHandler> create(MachOLinkingContext::Arch arch);
37
38 /// Get (arch specific) kind strings used by Registry.
39 virtual const Registry::KindStrings *kindStrings() = 0;
40
41 /// Convert mach-o Arch to Reference::KindArch.
42 virtual Reference::KindArch kindArch() = 0;
43
44 /// Used by StubPass to update References to shared library functions
45 /// to be references to a stub.
46 virtual bool isCallSite(const Reference &) = 0;
47
48 /// Used by GOTPass to locate GOT References
49 virtual bool isGOTAccess(const Reference &, bool &canBypassGOT) {
50 return false;
51 }
52
53 /// Used by GOTPass to update GOT References
54 virtual void updateReferenceToGOT(const Reference *, bool targetIsNowGOT) {}
55
56 /// Used by normalizedFromAtoms() to know where to generated rebasing and
57 /// binding info in final executables.
58 virtual bool isPointer(const Reference &) = 0;
59
60 /// Used by normalizedFromAtoms() to know where to generated lazy binding
61 /// info in final executables.
62 virtual bool isLazyPointer(const Reference &);
63
64 /// Returns true if the specified relocation is paired to the next relocation.
65 virtual bool isPairedReloc(const normalized::Relocation &) = 0;
66
67 /// Prototype for a helper function. Given a sectionIndex and address,
68 /// finds the atom and offset with that atom of that address.
69 typedef std::function<std::error_code (uint32_t sectionIndex, uint64_t addr,
70 const lld::Atom **, Reference::Addend *)>
71 FindAtomBySectionAndAddress;
72
73 /// Prototype for a helper function. Given a symbolIndex, finds the atom
74 /// representing that symbol.
75 typedef std::function<std::error_code (uint32_t symbolIndex,
76 const lld::Atom **)> FindAtomBySymbolIndex;
77
78 /// Analyzes a relocation from a .o file and returns the info
79 /// (kind, target, addend) needed to instantiate a Reference.
80 /// Two helper functions are passed as parameters to find the target atom
81 /// given a symbol index or address.
82 virtual std::error_code
83 getReferenceInfo(const normalized::Relocation &reloc,
84 const DefinedAtom *inAtom,
85 uint32_t offsetInAtom,
86 uint64_t fixupAddress, bool swap,
87 FindAtomBySectionAndAddress atomFromAddress,
88 FindAtomBySymbolIndex atomFromSymbolIndex,
89 Reference::KindValue *kind,
90 const lld::Atom **target,
91 Reference::Addend *addend) = 0;
92
93 /// Analyzes a pair of relocations from a .o file and returns the info
94 /// (kind, target, addend) needed to instantiate a Reference.
95 /// Two helper functions are passed as parameters to find the target atom
96 /// given a symbol index or address.
97 virtual std::error_code
98 getPairReferenceInfo(const normalized::Relocation &reloc1,
99 const normalized::Relocation &reloc2,
100 const DefinedAtom *inAtom,
101 uint32_t offsetInAtom,
102 uint64_t fixupAddress, bool swap,
103 FindAtomBySectionAndAddress atomFromAddress,
104 FindAtomBySymbolIndex atomFromSymbolIndex,
105 Reference::KindValue *kind,
106 const lld::Atom **target,
107 Reference::Addend *addend) = 0;
108
Nick Kledzik2d432352014-07-17 23:16:21 +0000109 /// Prototype for a helper function. Given an atom, finds the symbol table
110 /// index for it in the output file.
111 typedef std::function<uint32_t (const Atom &atom)> FindSymbolIndexForAtom;
112
113 /// Prototype for a helper function. Given an atom, finds the index
114 /// of the section that will contain the atom.
115 typedef std::function<uint32_t (const Atom &atom)> FindSectionIndexForAtom;
116
117 /// Prototype for a helper function. Given an atom, finds the address
118 /// assigned to it in the output file.
119 typedef std::function<uint64_t (const Atom &atom)> FindAddressForAtom;
120
121 /// Some architectures require local symbols on anonymous atoms.
122 virtual bool needsLocalSymbolInRelocatableFile(const DefinedAtom *atom) {
123 return false;
124 }
125
126 /// Copy raw content then apply all fixup References on an Atom.
127 virtual void generateAtomContent(const DefinedAtom &atom, bool relocatable,
128 FindAddressForAtom findAddress,
129 uint8_t *atomContentBuffer) = 0;
130
131 /// Used in -r mode to convert a Reference to a mach-o relocation.
132 virtual void appendSectionRelocations(const DefinedAtom &atom,
133 uint64_t atomSectionOffset,
134 const Reference &ref,
135 FindSymbolIndexForAtom,
136 FindSectionIndexForAtom,
137 FindAddressForAtom,
138 normalized::Relocations&) = 0;
139
Nick Kledzik7e9808f2014-07-23 00:51:37 +0000140 /// Add arch-specific References.
141 virtual void addAdditionalReferences(MachODefinedAtom &atom) { }
142
143 /// Only relevant for 32-bit arm archs.
144 virtual bool isThumbFunction(const DefinedAtom &atom) { return false; }
Nick Kledzik2458bec2014-07-16 19:49:02 +0000145
146 struct ReferenceInfo {
147 Reference::KindArch arch;
148 uint16_t kind;
149 uint32_t offset;
150 int32_t addend;
151 };
152
153 /// Table of architecture specific information for creating stubs.
154 struct StubInfo {
155 const char* binderSymbolName;
156 ReferenceInfo lazyPointerReferenceToHelper;
157 ReferenceInfo lazyPointerReferenceToFinal;
158 ReferenceInfo nonLazyPointerReferenceToBinder;
159 uint8_t codeAlignment;
160
161 uint32_t stubSize;
162 uint8_t stubBytes[16];
163 ReferenceInfo stubReferenceToLP;
164
165 uint32_t stubHelperSize;
166 uint8_t stubHelperBytes[16];
167 ReferenceInfo stubHelperReferenceToImm;
168 ReferenceInfo stubHelperReferenceToHelperCommon;
169
170 uint32_t stubHelperCommonSize;
171 uint8_t stubHelperCommonBytes[36];
172 ReferenceInfo stubHelperCommonReferenceToCache;
173 ReferenceInfo stubHelperCommonReferenceToBinder;
174 };
175
176 virtual const StubInfo &stubInfo() = 0;
177
178protected:
179 ArchHandler();
180
181 static std::unique_ptr<mach_o::ArchHandler> create_x86_64();
182 static std::unique_ptr<mach_o::ArchHandler> create_x86();
183 static std::unique_ptr<mach_o::ArchHandler> create_arm();
184
185 // Handy way to pack mach-o r_type and other bit fields into one 16-bit value.
186 typedef uint16_t RelocPattern;
187 enum {
188 rScattered = 0x8000,
189 rPcRel = 0x4000,
190 rExtern = 0x2000,
191 rLength1 = 0x0000,
192 rLength2 = 0x0100,
193 rLength4 = 0x0200,
Nick Kledzikb78ad892014-07-22 23:07:49 +0000194 rLength8 = 0x0300,
195 rLenArmLo = rLength1,
196 rLenArmHi = rLength2,
197 rLenThmbLo = rLength4,
198 rLenThmbHi = rLength8
Nick Kledzik2458bec2014-07-16 19:49:02 +0000199 };
Nick Kledzik2d432352014-07-17 23:16:21 +0000200 /// Extract RelocPattern from normalized mach-o relocation.
Nick Kledzik2458bec2014-07-16 19:49:02 +0000201 static RelocPattern relocPattern(const normalized::Relocation &reloc);
Nick Kledzik2d432352014-07-17 23:16:21 +0000202 /// Create normalized Relocation initialized from pattern.
203 static normalized::Relocation relocFromPattern(RelocPattern pattern);
204 /// One liner to add a relocation.
205 static void appendReloc(normalized::Relocations &relocs, uint32_t offset,
206 uint32_t symbol, uint32_t value,
207 RelocPattern pattern);
208
Nick Kledzik2458bec2014-07-16 19:49:02 +0000209
210 static int16_t readS16(bool swap, const uint8_t *addr);
211 static int32_t readS32(bool swap, const uint8_t *addr);
212 static uint32_t readU32(bool swap, const uint8_t *addr);
213 static int64_t readS64(bool swap, const uint8_t *addr);
214};
215
216} // namespace mach_o
217} // namespace lld
218
219#endif // LLD_READER_WRITER_MACHO_ARCH_HANDLER_H