blob: 37206dd9c60da6befdadc859f1535a275f3e5752 [file] [log] [blame]
Nick Kledzik30332b12013-10-08 00:43:34 +00001//===- lib/ReaderWriter/MachO/NormalizedFile.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///
11/// \file These data structures comprise the "normalized" view of
12/// mach-o object files. The normalized view is an in-memory only data structure
13/// which is always in native endianness and pointer size.
14///
15/// The normalized view easily converts to and from YAML using YAML I/O.
16///
17/// The normalized view converts to and from binary mach-o object files using
18/// the writeBinary() and readBinary() functions.
19///
20/// The normalized view converts to and from lld::Atoms using the
21/// normalizedToAtoms() and normalizedFromAtoms().
22///
23/// Overall, the conversion paths available look like:
24///
25/// +---------------+
26/// | binary mach-o |
27/// +---------------+
28/// ^
29/// |
30/// v
31/// +------------+ +------+
32/// | normalized | <-> | yaml |
33/// +------------+ +------+
34/// ^
35/// |
36/// v
37/// +-------+
38/// | Atoms |
39/// +-------+
40///
41
42#include "lld/Core/Error.h"
43#include "lld/Core/LLVM.h"
44#include "lld/ReaderWriter/MachOLinkingContext.h"
45
46#include "llvm/ADT/SmallString.h"
47#include "llvm/ADT/StringRef.h"
48#include "llvm/Support/ErrorOr.h"
49#include "llvm/Support/MachO.h"
50#include "llvm/Support/YAMLTraits.h"
51
52#ifndef LLD_READER_WRITER_MACHO_NORMALIZED_H_
53#define LLD_READER_WRITER_MACHO_NORMALIZED_H_
54
55using llvm::yaml::Hex64;
56using llvm::yaml::Hex32;
57using llvm::yaml::Hex8;
58using llvm::yaml::SequenceTraits;
59using llvm::MachO::HeaderFileType;
60using llvm::MachO::BindType;
61using llvm::MachO::RebaseType;
62using llvm::MachO::NListType;
63using llvm::MachO::RelocationInfoType;
64using llvm::MachO::SectionType;
65using llvm::MachO::LoadCommandType;
66using llvm::MachO::ExportSymbolKind;
67
68namespace lld {
69namespace mach_o {
70namespace normalized {
71
72
73/// The real mach-o relocation record is 8-bytes on disk and is
74/// encoded in one of two different bit-field patterns. This
75/// normalized form has the union of all possbile fields.
76struct Relocation {
77 Relocation() : offset(0), scattered(false),
78 type(llvm::MachO::GENERIC_RELOC_VANILLA),
79 length(0), pcRel(false), isExtern(false), value(0),
80 symbol(0) { }
81
82 Hex32 offset;
83 bool scattered;
84 RelocationInfoType type;
85 uint8_t length;
86 bool pcRel;
87 bool isExtern;
88 Hex32 value;
89 uint32_t symbol;
90};
91
92/// A typedef so that YAML I/O can treat this vector as a sequence.
93typedef std::vector<Relocation> Relocations;
94
95/// A typedef so that YAML I/O can process the raw bytes in a section.
96typedef std::vector<Hex8> ContentBytes;
97
98/// A typedef so that YAML I/O can treat indirect symbols as a flow sequence.
99typedef std::vector<uint32_t> IndirectSymbols;
100
101/// A typedef so that YAML I/O can encode/decode section attributes.
102LLVM_YAML_STRONG_TYPEDEF(uint32_t, SectionAttr);
103
104/// Mach-O has a 32-bit and 64-bit section record. This normalized form
105/// can support either kind.
106struct Section {
107 Section() : type(llvm::MachO::S_REGULAR),
108 attributes(0), alignment(0), address(0) { }
109
110 StringRef segmentName;
111 StringRef sectionName;
112 SectionType type;
113 SectionAttr attributes;
114 uint32_t alignment;
115 Hex64 address;
116 ContentBytes content;
117 Relocations relocations;
118 IndirectSymbols indirectSymbols;
119};
120
121
122/// A typedef so that YAML I/O can encode/decode the scope bits of an nlist.
123LLVM_YAML_STRONG_TYPEDEF(uint8_t, SymbolScope);
124
125/// A typedef so that YAML I/O can encode/decode the desc bits of an nlist.
126LLVM_YAML_STRONG_TYPEDEF(uint16_t, SymbolDesc);
127
128/// Mach-O has a 32-bit and 64-bit symbol table entry (nlist), and the symbol
129/// type and scope and mixed in the same n_type field. This normalized form
130/// works for any pointer size and separates out the type and scope.
131struct Symbol {
132 Symbol() : type(llvm::MachO::N_UNDF), scope(0), sect(0), desc(0), value(0) { }
133
134 StringRef name;
135 NListType type;
136 SymbolScope scope;
137 uint8_t sect;
138 SymbolDesc desc;
139 Hex64 value;
140};
141
142/// A typedef so that YAML I/O can (de/en)code the protection bits of a segment.
143LLVM_YAML_STRONG_TYPEDEF(uint32_t, VMProtect);
144
145/// Segments are only used in normalized final linked images (not in relocatable
146/// object files). They specify how a range of the file is loaded.
147struct Segment {
148 StringRef name;
149 Hex64 address;
150 Hex64 size;
151 VMProtect access;
152};
153
154/// Only used in normalized final linked images to specify on which dylibs
155/// it depends.
156struct DependentDylib {
157 StringRef path;
158 LoadCommandType kind;
159};
160
161/// A normalized rebasing entry. Only used in normalized final linked images.
162struct RebaseLocation {
163 Hex32 segOffset;
164 uint8_t segIndex;
165 RebaseType kind;
166};
167
168/// A normalized binding entry. Only used in normalized final linked images.
169struct BindLocation {
170 Hex32 segOffset;
171 uint8_t segIndex;
172 BindType kind;
173 bool canBeNull;
174 int ordinal;
175 StringRef symbolName;
176 Hex64 addend;
177};
178
179/// A typedef so that YAML I/O can encode/decode export flags.
180LLVM_YAML_STRONG_TYPEDEF(uint32_t, ExportFlags);
181
182/// A normalized export entry. Only used in normalized final linked images.
183struct Export {
184 StringRef name;
185 Hex64 offset;
186 ExportSymbolKind kind;
187 ExportFlags flags;
188 Hex32 otherOffset;
189 StringRef otherName;
190};
191
192
193/// A typedef so that YAML I/O can encode/decode mach_header.flags.
194LLVM_YAML_STRONG_TYPEDEF(uint32_t, FileFlags);
195
196///
197struct NormalizedFile {
198 NormalizedFile() : arch(MachOLinkingContext::arch_unknown),
199 fileType(llvm::MachO::MH_OBJECT),
200 flags(0),
201 hasUUID(false),
202 os(MachOLinkingContext::OS::unknown) { }
203
204 MachOLinkingContext::Arch arch;
205 HeaderFileType fileType;
206 FileFlags flags;
207 std::vector<Segment> segments; // Not used in object files.
208 std::vector<Section> sections;
209
210 // Symbols sorted by kind.
211 std::vector<Symbol> localSymbols;
212 std::vector<Symbol> globalSymbols;
213 std::vector<Symbol> undefinedSymbols;
214
215 // Maps to load commands with no LINKEDIT content (final linked images only).
216 std::vector<DependentDylib> dependentDylibs;
217 StringRef installName;
218 bool hasUUID;
219 std::vector<StringRef> rpaths;
220 Hex64 entryAddress;
221 MachOLinkingContext::OS os;
222 Hex64 sourceVersion;
223 Hex32 minOSverson;
224 Hex32 sdkVersion;
225
226 // Maps to load commands with LINKEDIT content (final linked images only).
227 std::vector<RebaseLocation> rebasingInfo;
228 std::vector<BindLocation> bindingInfo;
229 std::vector<BindLocation> weakBindingInfo;
230 std::vector<BindLocation> lazyBindingInfo;
231 std::vector<Export> exportInfo;
232
233 // TODO:
234 // code-signature
235 // split-seg-info
236 // function-starts
237 // data-in-code
238};
239
240
241/// Reads a mach-o file and produces an in-memory normalized view.
242ErrorOr<std::unique_ptr<NormalizedFile>>
243readBinary(std::unique_ptr<MemoryBuffer> &mb);
244
245/// Takes in-memory normalized view and writes a mach-o object file.
246error_code
247writeBinary(const NormalizedFile &file, StringRef path);
248
249size_t headerAndLoadCommandsSize(const NormalizedFile &file);
250
251
252/// Parses a yaml encoded mach-o file to produce an in-memory normalized view.
253ErrorOr<std::unique_ptr<NormalizedFile>>
254readYaml(std::unique_ptr<MemoryBuffer> &mb);
255
256/// Writes a yaml encoded mach-o files given an in-memory normalized view.
257error_code
258writeYaml(const NormalizedFile &file, llvm::raw_ostream &out);
259
260
261/// Takes in-memory normalized dylib or object and parses it into lld::File
262ErrorOr<std::unique_ptr<lld::File>>
263normalizedToAtoms(const NormalizedFile &normalizedFile);
264
265/// Takes atoms and generates a normalized macho-o view.
266ErrorOr<std::unique_ptr<NormalizedFile>>
267normalizedFromAtoms(const lld::File &atomFile, const MachOLinkingContext &ctxt);
268
269
270
271} // namespace normalized
272} // namespace mach_o
273} // namespace lld
274
275#endif // LLD_READER_WRITER_MACHO_NORMALIZED_H_
276
277
278
279