blob: 8642ce3c0d94affd0189206d3ca3cff1fa14e1fc [file] [log] [blame]
Alexander Shaposhnikovd911ed12019-02-02 00:38:07 +00001//===- Object.h - Mach-O object file model ----------------------*- C++ -*-===//
2//
Chandler Carruth127252b2019-02-11 08:25:19 +00003// 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
Alexander Shaposhnikovd911ed12019-02-02 00:38:07 +00006//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_OBJCOPY_MACHO_OBJECT_H
10#define LLVM_OBJCOPY_MACHO_OBJECT_H
11
12#include "llvm/ADT/Optional.h"
13#include "llvm/ADT/StringRef.h"
14#include "llvm/BinaryFormat/MachO.h"
Seiya Nutaf923d9b2019-06-21 00:21:50 +000015#include "llvm/MC/StringTableBuilder.h"
Alexander Shaposhnikovd911ed12019-02-02 00:38:07 +000016#include "llvm/ObjectYAML/DWARFYAML.h"
17#include "llvm/Support/YAMLTraits.h"
18#include <cstdint>
19#include <string>
20#include <vector>
21
22namespace llvm {
23namespace objcopy {
24namespace macho {
25
26struct MachHeader {
27 uint32_t Magic;
28 uint32_t CPUType;
29 uint32_t CPUSubType;
30 uint32_t FileType;
31 uint32_t NCmds;
32 uint32_t SizeOfCmds;
33 uint32_t Flags;
34 uint32_t Reserved = 0;
35};
36
Seiya Nutaf923d9b2019-06-21 00:21:50 +000037struct RelocationInfo;
Alexander Shaposhnikovd911ed12019-02-02 00:38:07 +000038struct Section {
Seiya Nutab728e532019-06-08 01:22:54 +000039 std::string Sectname;
40 std::string Segname;
Seiya Nuta7f19dd12019-10-28 15:40:37 +090041 // CanonicalName is a string formatted as “<Segname>,<Sectname>".
42 std::string CanonicalName;
Alexander Shaposhnikovd911ed12019-02-02 00:38:07 +000043 uint64_t Addr;
44 uint64_t Size;
45 uint32_t Offset;
46 uint32_t Align;
47 uint32_t RelOff;
48 uint32_t NReloc;
49 uint32_t Flags;
50 uint32_t Reserved1;
51 uint32_t Reserved2;
52 uint32_t Reserved3;
53
54 StringRef Content;
Seiya Nutaf923d9b2019-06-21 00:21:50 +000055 std::vector<RelocationInfo> Relocations;
Seiya Nutab728e532019-06-08 01:22:54 +000056
57 MachO::SectionType getType() const {
58 return static_cast<MachO::SectionType>(Flags & MachO::SECTION_TYPE);
59 }
60
61 bool isVirtualSection() const {
62 return (getType() == MachO::S_ZEROFILL ||
63 getType() == MachO::S_GB_ZEROFILL ||
64 getType() == MachO::S_THREAD_LOCAL_ZEROFILL);
65 }
Alexander Shaposhnikovd911ed12019-02-02 00:38:07 +000066};
67
68struct LoadCommand {
69 // The type MachO::macho_load_command is defined in llvm/BinaryFormat/MachO.h
70 // and it is a union of all the structs corresponding to various load
71 // commands.
72 MachO::macho_load_command MachOLoadCommand;
73
74 // The raw content of the payload of the load command (located right after the
75 // corresponding struct). In some cases it is either empty or can be
76 // copied-over without digging into its structure.
Alexander Shaposhnikov7d83c292019-11-06 17:04:04 -080077 ArrayRef<uint8_t> Payload;
Alexander Shaposhnikovd911ed12019-02-02 00:38:07 +000078
79 // Some load commands can contain (inside the payload) an array of sections,
80 // though the contents of the sections are stored separately. The struct
81 // Section describes only sections' metadata and where to find the
82 // corresponding content inside the binary.
83 std::vector<Section> Sections;
84};
85
Seiya Nutaf923d9b2019-06-21 00:21:50 +000086// A symbol information. Fields which starts with "n_" are same as them in the
87// nlist.
88struct SymbolEntry {
89 std::string Name;
Seiya Nuta9bbf2a12019-10-31 13:51:11 +090090 bool Referenced = false;
Seiya Nutaf923d9b2019-06-21 00:21:50 +000091 uint32_t Index;
Alexander Shaposhnikovd911ed12019-02-02 00:38:07 +000092 uint8_t n_type;
93 uint8_t n_sect;
94 uint16_t n_desc;
95 uint64_t n_value;
Seiya Nuta552bcb82019-08-19 21:05:31 +000096
97 bool isExternalSymbol() const {
98 return n_type & ((MachO::N_EXT | MachO::N_PEXT));
99 }
100
101 bool isLocalSymbol() const { return !isExternalSymbol(); }
102
103 bool isUndefinedSymbol() const {
104 return (n_type & MachO::N_TYPE) == MachO::N_UNDF;
105 }
Alexander Shaposhnikovd911ed12019-02-02 00:38:07 +0000106};
107
108/// The location of the symbol table inside the binary is described by LC_SYMTAB
109/// load command.
110struct SymbolTable {
Seiya Nutaf923d9b2019-06-21 00:21:50 +0000111 std::vector<std::unique_ptr<SymbolEntry>> Symbols;
112
113 const SymbolEntry *getSymbolByIndex(uint32_t Index) const;
Seiya Nuta9bbf2a12019-10-31 13:51:11 +0900114 SymbolEntry *getSymbolByIndex(uint32_t Index);
115 void removeSymbols(
116 function_ref<bool(const std::unique_ptr<SymbolEntry> &)> ToRemove);
Alexander Shaposhnikovd911ed12019-02-02 00:38:07 +0000117};
118
Seiya Nuta1e589f62019-10-30 15:12:17 +0900119struct IndirectSymbolEntry {
120 // The original value in an indirect symbol table. Higher bits encode extra
121 // information (INDIRECT_SYMBOL_LOCAL and INDIRECT_SYMBOL_ABS).
122 uint32_t OriginalIndex;
123 /// The Symbol referenced by this entry. It's None if the index is
124 /// INDIRECT_SYMBOL_LOCAL or INDIRECT_SYMBOL_ABS.
Seiya Nuta9bbf2a12019-10-31 13:51:11 +0900125 Optional<SymbolEntry *> Symbol;
Seiya Nuta1e589f62019-10-30 15:12:17 +0900126
Seiya Nuta9bbf2a12019-10-31 13:51:11 +0900127 IndirectSymbolEntry(uint32_t OriginalIndex, Optional<SymbolEntry *> Symbol)
Seiya Nuta1e589f62019-10-30 15:12:17 +0900128 : OriginalIndex(OriginalIndex), Symbol(Symbol) {}
129};
130
Seiya Nuta552bcb82019-08-19 21:05:31 +0000131struct IndirectSymbolTable {
Seiya Nuta1e589f62019-10-30 15:12:17 +0900132 std::vector<IndirectSymbolEntry> Symbols;
Seiya Nuta552bcb82019-08-19 21:05:31 +0000133};
134
Alexander Shaposhnikovd911ed12019-02-02 00:38:07 +0000135/// The location of the string table inside the binary is described by LC_SYMTAB
136/// load command.
137struct StringTable {
138 std::vector<std::string> Strings;
139};
140
Seiya Nutaf923d9b2019-06-21 00:21:50 +0000141struct RelocationInfo {
142 const SymbolEntry *Symbol;
143 // True if Info is a scattered_relocation_info.
144 bool Scattered;
145 MachO::any_relocation_info Info;
146};
147
Alexander Shaposhnikovd911ed12019-02-02 00:38:07 +0000148/// The location of the rebase info inside the binary is described by
149/// LC_DYLD_INFO load command. Dyld rebases an image whenever dyld loads it at
150/// an address different from its preferred address. The rebase information is
151/// a stream of byte sized opcodes whose symbolic names start with
152/// REBASE_OPCODE_. Conceptually the rebase information is a table of tuples:
153/// <seg-index, seg-offset, type>
154/// The opcodes are a compressed way to encode the table by only
155/// encoding when a column changes. In addition simple patterns
156/// like "every n'th offset for m times" can be encoded in a few
157/// bytes.
158struct RebaseInfo {
159 // At the moment we do not parse this info (and it is simply copied over),
160 // but the proper support will be added later.
161 ArrayRef<uint8_t> Opcodes;
162};
163
164/// The location of the bind info inside the binary is described by
165/// LC_DYLD_INFO load command. Dyld binds an image during the loading process,
166/// if the image requires any pointers to be initialized to symbols in other
167/// images. The bind information is a stream of byte sized opcodes whose
168/// symbolic names start with BIND_OPCODE_. Conceptually the bind information is
169/// a table of tuples: <seg-index, seg-offset, type, symbol-library-ordinal,
170/// symbol-name, addend> The opcodes are a compressed way to encode the table by
171/// only encoding when a column changes. In addition simple patterns like for
172/// runs of pointers initialized to the same value can be encoded in a few
173/// bytes.
174struct BindInfo {
175 // At the moment we do not parse this info (and it is simply copied over),
176 // but the proper support will be added later.
177 ArrayRef<uint8_t> Opcodes;
178};
179
180/// The location of the weak bind info inside the binary is described by
181/// LC_DYLD_INFO load command. Some C++ programs require dyld to unique symbols
182/// so that all images in the process use the same copy of some code/data. This
183/// step is done after binding. The content of the weak_bind info is an opcode
184/// stream like the bind_info. But it is sorted alphabetically by symbol name.
185/// This enable dyld to walk all images with weak binding information in order
186/// and look for collisions. If there are no collisions, dyld does no updating.
187/// That means that some fixups are also encoded in the bind_info. For
188/// instance, all calls to "operator new" are first bound to libstdc++.dylib
189/// using the information in bind_info. Then if some image overrides operator
190/// new that is detected when the weak_bind information is processed and the
191/// call to operator new is then rebound.
192struct WeakBindInfo {
193 // At the moment we do not parse this info (and it is simply copied over),
194 // but the proper support will be added later.
195 ArrayRef<uint8_t> Opcodes;
196};
197
198/// The location of the lazy bind info inside the binary is described by
199/// LC_DYLD_INFO load command. Some uses of external symbols do not need to be
200/// bound immediately. Instead they can be lazily bound on first use. The
201/// lazy_bind contains a stream of BIND opcodes to bind all lazy symbols. Normal
202/// use is that dyld ignores the lazy_bind section when loading an image.
203/// Instead the static linker arranged for the lazy pointer to initially point
204/// to a helper function which pushes the offset into the lazy_bind area for the
205/// symbol needing to be bound, then jumps to dyld which simply adds the offset
206/// to lazy_bind_off to get the information on what to bind.
207struct LazyBindInfo {
208 ArrayRef<uint8_t> Opcodes;
209};
210
211/// The location of the export info inside the binary is described by
212/// LC_DYLD_INFO load command. The symbols exported by a dylib are encoded in a
213/// trie. This is a compact representation that factors out common prefixes. It
214/// also reduces LINKEDIT pages in RAM because it encodes all information (name,
215/// address, flags) in one small, contiguous range. The export area is a stream
216/// of nodes. The first node sequentially is the start node for the trie. Nodes
217/// for a symbol start with a uleb128 that is the length of the exported symbol
218/// information for the string so far. If there is no exported symbol, the node
219/// starts with a zero byte. If there is exported info, it follows the length.
220/// First is a uleb128 containing flags. Normally, it is followed by
221/// a uleb128 encoded offset which is location of the content named
222/// by the symbol from the mach_header for the image. If the flags
223/// is EXPORT_SYMBOL_FLAGS_REEXPORT, then following the flags is
224/// a uleb128 encoded library ordinal, then a zero terminated
225/// UTF8 string. If the string is zero length, then the symbol
226/// is re-export from the specified dylib with the same name.
227/// If the flags is EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER, then following
228/// the flags is two uleb128s: the stub offset and the resolver offset.
229/// The stub is used by non-lazy pointers. The resolver is used
230/// by lazy pointers and must be called to get the actual address to use.
231/// After the optional exported symbol information is a byte of
232/// how many edges (0-255) that this node has leaving it,
233/// followed by each edge.
234/// Each edge is a zero terminated UTF8 of the addition chars
235/// in the symbol, followed by a uleb128 offset for the node that
236/// edge points to.
237struct ExportInfo {
238 ArrayRef<uint8_t> Trie;
239};
240
Seiya Nuta552bcb82019-08-19 21:05:31 +0000241struct LinkData {
242 ArrayRef<uint8_t> Data;
243};
244
Alexander Shaposhnikovd911ed12019-02-02 00:38:07 +0000245struct Object {
246 MachHeader Header;
247 std::vector<LoadCommand> LoadCommands;
248
249 SymbolTable SymTable;
250 StringTable StrTable;
251
252 RebaseInfo Rebases;
253 BindInfo Binds;
254 WeakBindInfo WeakBinds;
255 LazyBindInfo LazyBinds;
256 ExportInfo Exports;
Seiya Nuta552bcb82019-08-19 21:05:31 +0000257 IndirectSymbolTable IndirectSymTable;
258 LinkData DataInCode;
259 LinkData FunctionStarts;
Alexander Shaposhnikovd911ed12019-02-02 00:38:07 +0000260
261 /// The index of LC_SYMTAB load command if present.
262 Optional<size_t> SymTabCommandIndex;
263 /// The index of LC_DYLD_INFO or LC_DYLD_INFO_ONLY load command if present.
264 Optional<size_t> DyLdInfoCommandIndex;
Seiya Nuta552bcb82019-08-19 21:05:31 +0000265 /// The index LC_DYSYMTAB load comamnd if present.
266 Optional<size_t> DySymTabCommandIndex;
267 /// The index LC_DATA_IN_CODE load comamnd if present.
268 Optional<size_t> DataInCodeCommandIndex;
269 /// The index LC_FUNCTION_STARTS load comamnd if present.
270 Optional<size_t> FunctionStartsCommandIndex;
Seiya Nuta7f19dd12019-10-28 15:40:37 +0900271
272 void removeSections(function_ref<bool(const Section &)> ToRemove);
Alexander Shaposhnikovd911ed12019-02-02 00:38:07 +0000273};
274
275} // end namespace macho
276} // end namespace objcopy
277} // end namespace llvm
278
279#endif // LLVM_OBJCOPY_MACHO_OBJECT_H