1//===- MachOFormat.h - Mach-O Format Structures And Constants ---*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file declares various structures and constants which are platform
11// independent and can be shared by any client which wishes to interact with
12// Mach object files.
13//
14// The definitions here are purposely chosen to match the LLVM style as opposed
15// to following the platform specific definition of the format.
16//
17// On a Mach system, see the <mach-o/...> includes for more information, in
18// particular <mach-o/loader.h>.
19//
20//===----------------------------------------------------------------------===//
21
22#ifndef LLVM_OBJECT_MACHOFORMAT_H
23#define LLVM_OBJECT_MACHOFORMAT_H
24
25#include "llvm/Support/DataTypes.h"
26
27namespace llvm {
28namespace object {
29
30/// General Mach platform information.
31namespace mach {
32  /// @name CPU Type and Subtype Information
33  /// {
34
35  /// \brief Capability bits used in CPU type encoding.
36  enum CPUTypeFlagsMask {
37    CTFM_ArchMask =  0xFF000000,
38    CTFM_ArchABI64 = 0x01000000
39  };
40
41  /// \brief Machine type IDs used in CPU type encoding.
42  enum CPUTypeMachine {
43    CTM_i386      = 7,
44    CTM_x86_64    = CTM_i386 | CTFM_ArchABI64,
45    CTM_ARM       = 12,
46    CTM_SPARC     = 14,
47    CTM_PowerPC   = 18,
48    CTM_PowerPC64 = CTM_PowerPC | CTFM_ArchABI64
49  };
50
51  /// \brief Capability bits used in CPU subtype encoding.
52  enum CPUSubtypeFlagsMask {
53    CSFM_SubtypeMask =  0xFF000000,
54    CSFM_SubtypeLib64 = 0x80000000
55  };
56
57  /// \brief ARM Machine Subtypes.
58  enum CPUSubtypeARM {
59    CSARM_ALL    = 0,
60    CSARM_V4T    = 5,
61    CSARM_V6     = 6,
62    CSARM_V5TEJ  = 7,
63    CSARM_XSCALE = 8,
64    CSARM_V7     = 9,
65    CSARM_V7F    = 10,
66    CSARM_V7S    = 11,
67    CSARM_V7K    = 12
68  };
69
70  /// \brief PowerPC Machine Subtypes.
71  enum CPUSubtypePowerPC {
72    CSPPC_ALL = 0
73  };
74
75  /// \brief SPARC Machine Subtypes.
76  enum CPUSubtypeSPARC {
77    CSSPARC_ALL = 0
78  };
79
80  /// \brief x86 Machine Subtypes.
81  enum CPUSubtypeX86 {
82    CSX86_ALL = 3
83  };
84
85  /// @}
86
87} // end namespace mach
88
89/// Format information for Mach object files.
90namespace macho {
91  /// \brief Constants for structure sizes.
92  enum StructureSizes {
93    Header32Size = 28,
94    Header64Size = 32,
95    SegmentLoadCommand32Size = 56,
96    SegmentLoadCommand64Size = 72,
97    Section32Size = 68,
98    Section64Size = 80,
99    SymtabLoadCommandSize = 24,
100    DysymtabLoadCommandSize = 80,
101    Nlist32Size = 12,
102    Nlist64Size = 16,
103    RelocationInfoSize = 8,
104    LinkeditLoadCommandSize = 16
105  };
106
107  /// \brief Constants for header magic field.
108  enum HeaderMagic {
109    HM_Object32 = 0xFEEDFACE,  ///< 32-bit mach object file
110    HM_Object64 = 0xFEEDFACF,  ///< 64-bit mach object file
111    HM_Universal = 0xCAFEBABE  ///< Universal object file
112  };
113
114  /// \brief Header common to all Mach object files.
115  struct Header {
116    uint32_t Magic;
117    uint32_t CPUType;
118    uint32_t CPUSubtype;
119    uint32_t FileType;
120    uint32_t NumLoadCommands;
121    uint32_t SizeOfLoadCommands;
122    uint32_t Flags;
123  };
124
125  /// \brief Extended header for 64-bit object files.
126  struct Header64Ext {
127    uint32_t Reserved;
128  };
129
130  // See <mach-o/loader.h>.
131  enum HeaderFileType {
132    HFT_Object = 0x1
133  };
134
135  enum HeaderFlags {
136    HF_SubsectionsViaSymbols = 0x2000
137  };
138
139  enum LoadCommandType {
140    LCT_Segment = 0x1,
141    LCT_Symtab = 0x2,
142    LCT_Dysymtab = 0xb,
143    LCT_Segment64 = 0x19,
144    LCT_UUID = 0x1b,
145    LCT_CodeSignature = 0x1d,
146    LCT_SegmentSplitInfo = 0x1e,
147    LCT_FunctionStarts = 0x26,
148    LCT_DataInCode = 0x29
149  };
150
151  /// \brief Load command structure.
152  struct LoadCommand {
153    uint32_t Type;
154    uint32_t Size;
155  };
156
157  /// @name Load Command Structures
158  /// @{
159
160  struct SegmentLoadCommand {
161    uint32_t Type;
162    uint32_t Size;
163    char Name[16];
164    uint32_t VMAddress;
165    uint32_t VMSize;
166    uint32_t FileOffset;
167    uint32_t FileSize;
168    uint32_t MaxVMProtection;
169    uint32_t InitialVMProtection;
170    uint32_t NumSections;
171    uint32_t Flags;
172  };
173
174  struct Segment64LoadCommand {
175    uint32_t Type;
176    uint32_t Size;
177    char Name[16];
178    uint64_t VMAddress;
179    uint64_t VMSize;
180    uint64_t FileOffset;
181    uint64_t FileSize;
182    uint32_t MaxVMProtection;
183    uint32_t InitialVMProtection;
184    uint32_t NumSections;
185    uint32_t Flags;
186  };
187
188  struct SymtabLoadCommand {
189    uint32_t Type;
190    uint32_t Size;
191    uint32_t SymbolTableOffset;
192    uint32_t NumSymbolTableEntries;
193    uint32_t StringTableOffset;
194    uint32_t StringTableSize;
195  };
196
197  struct DysymtabLoadCommand {
198    uint32_t Type;
199    uint32_t Size;
200
201    uint32_t LocalSymbolsIndex;
202    uint32_t NumLocalSymbols;
203
204    uint32_t ExternalSymbolsIndex;
205    uint32_t NumExternalSymbols;
206
207    uint32_t UndefinedSymbolsIndex;
208    uint32_t NumUndefinedSymbols;
209
210    uint32_t TOCOffset;
211    uint32_t NumTOCEntries;
212
213    uint32_t ModuleTableOffset;
214    uint32_t NumModuleTableEntries;
215
216    uint32_t ReferenceSymbolTableOffset;
217    uint32_t NumReferencedSymbolTableEntries;
218
219    uint32_t IndirectSymbolTableOffset;
220    uint32_t NumIndirectSymbolTableEntries;
221
222    uint32_t ExternalRelocationTableOffset;
223    uint32_t NumExternalRelocationTableEntries;
224
225    uint32_t LocalRelocationTableOffset;
226    uint32_t NumLocalRelocationTableEntries;
227  };
228
229  struct LinkeditDataLoadCommand {
230    uint32_t Type;
231    uint32_t Size;
232    uint32_t DataOffset;
233    uint32_t DataSize;
234  };
235
236  /// @}
237  /// @name Section Data
238  /// @{
239
240  struct Section {
241    char Name[16];
242    char SegmentName[16];
243    uint32_t Address;
244    uint32_t Size;
245    uint32_t Offset;
246    uint32_t Align;
247    uint32_t RelocationTableOffset;
248    uint32_t NumRelocationTableEntries;
249    uint32_t Flags;
250    uint32_t Reserved1;
251    uint32_t Reserved2;
252  };
253  struct Section64 {
254    char Name[16];
255    char SegmentName[16];
256    uint64_t Address;
257    uint64_t Size;
258    uint32_t Offset;
259    uint32_t Align;
260    uint32_t RelocationTableOffset;
261    uint32_t NumRelocationTableEntries;
262    uint32_t Flags;
263    uint32_t Reserved1;
264    uint32_t Reserved2;
265    uint32_t Reserved3;
266  };
267
268  /// @}
269  /// @name Symbol Table Entries
270  /// @{
271
272  struct SymbolTableEntry {
273    uint32_t StringIndex;
274    uint8_t Type;
275    uint8_t SectionIndex;
276    uint16_t Flags;
277    uint32_t Value;
278  };
279  // Despite containing a uint64_t, this structure is only 4-byte aligned within
280  // a MachO file.
281#pragma pack(push)
282#pragma pack(4)
283  struct Symbol64TableEntry {
284    uint32_t StringIndex;
285    uint8_t Type;
286    uint8_t SectionIndex;
287    uint16_t Flags;
288    uint64_t Value;
289  };
290#pragma pack(pop)
291
292  /// @}
293  /// @name Data-in-code Table Entry
294  /// @{
295
296  // See <mach-o/loader.h>.
297  enum DataRegionType { Data = 1, JumpTable8, JumpTable16, JumpTable32 };
298  struct DataInCodeTableEntry {
299    uint32_t Offset;  /* from mach_header to start of data region */
300    uint16_t Length;  /* number of bytes in data region */
301    uint16_t Kind;    /* a DataRegionType value  */
302  };
303
304  /// @}
305  /// @name Indirect Symbol Table
306  /// @{
307
308  struct IndirectSymbolTableEntry {
309    uint32_t Index;
310  };
311
312  /// @}
313  /// @name Relocation Data
314  /// @{
315
316  struct RelocationEntry {
317    uint32_t Word0;
318    uint32_t Word1;
319  };
320
321  /// @}
322
323  // See <mach-o/nlist.h>.
324  enum SymbolTypeType {
325    STT_Undefined = 0x00,
326    STT_Absolute  = 0x02,
327    STT_Section   = 0x0e
328  };
329
330  enum SymbolTypeFlags {
331    // If any of these bits are set, then the entry is a stab entry number (see
332    // <mach-o/stab.h>. Otherwise the other masks apply.
333    STF_StabsEntryMask = 0xe0,
334
335    STF_TypeMask       = 0x0e,
336    STF_External       = 0x01,
337    STF_PrivateExtern  = 0x10
338  };
339
340  /// IndirectSymbolFlags - Flags for encoding special values in the indirect
341  /// symbol entry.
342  enum IndirectSymbolFlags {
343    ISF_Local    = 0x80000000,
344    ISF_Absolute = 0x40000000
345  };
346
347  /// RelocationFlags - Special flags for addresses.
348  enum RelocationFlags {
349    RF_Scattered = 0x80000000
350  };
351
352  /// Common relocation info types.
353  enum RelocationInfoType {
354    RIT_Vanilla             = 0,
355    RIT_Pair                = 1,
356    RIT_Difference          = 2
357  };
358
359  /// Generic relocation info types, which are shared by some (but not all)
360  /// platforms.
361  enum RelocationInfoType_Generic {
362    RIT_Generic_PreboundLazyPointer = 3,
363    RIT_Generic_LocalDifference     = 4,
364    RIT_Generic_TLV                 = 5
365  };
366
367  /// X86_64 uses its own relocation types.
368  enum RelocationInfoTypeX86_64 {
369    // Note that x86_64 doesn't even share the common relocation types.
370    RIT_X86_64_Unsigned   = 0,
371    RIT_X86_64_Signed     = 1,
372    RIT_X86_64_Branch     = 2,
373    RIT_X86_64_GOTLoad    = 3,
374    RIT_X86_64_GOT        = 4,
375    RIT_X86_64_Subtractor = 5,
376    RIT_X86_64_Signed1    = 6,
377    RIT_X86_64_Signed2    = 7,
378    RIT_X86_64_Signed4    = 8,
379    RIT_X86_64_TLV        = 9
380  };
381
382  /// ARM uses its own relocation types.
383  enum RelocationInfoTypeARM {
384    RIT_ARM_LocalDifference = 3,
385    RIT_ARM_PreboundLazyPointer = 4,
386    RIT_ARM_Branch24Bit = 5,
387    RIT_ARM_ThumbBranch22Bit = 6,
388    RIT_ARM_ThumbBranch32Bit = 7,
389    RIT_ARM_Half = 8,
390    RIT_ARM_HalfDifference = 9
391
392  };
393
394} // end namespace macho
395
396} // end namespace object
397} // end namespace llvm
398
399#endif
400