cpp: Use #pragma once instead of #ifndef guards
[ghc.git] / rts / linker / MachOTypes.h
1 #pragma once
2
3 #if defined(OBJFORMAT_MACHO)
4
5 #include "ghcplatform.h"
6
7 #include <mach-o/loader.h>
8
9 #if x86_64_HOST_ARCH || powerpc64_HOST_ARCH \
10 || aarch64_HOST_ARCH || arm64_HOST_ARCH
11 typedef struct mach_header_64 MachOHeader;
12 typedef struct segment_command_64 MachOSegmentCommand;
13 typedef struct section_64 MachOSection;
14 typedef struct nlist_64 MachONList;
15 #elif i386_HOST_ARCH || powerpc_HOST_ARCH || arm_HOST_ARCH
16 typedef struct mach_header MachOHeader;
17 typedef struct segment_command MachOSegmentCommand;
18 typedef struct section MachOSection;
19 typedef struct nlist MachONList;
20 #else
21 #error Unknown Darwin architecture
22 #endif
23 typedef struct load_command MachOLoadCommand;
24 typedef struct symtab_command MachOSymtabCommand;
25 typedef struct dysymtab_command MachODsymtabCommand;
26 typedef struct relocation_info MachORelocationInfo;
27 typedef struct scattered_relocation_info MachOScatteredRelocationInfo;
28
29 /* Dealing with nlist symbol entries can become
30 * painful. We'll have our own Symbol struct that
31 * mirrors the symbol from the nlist and can carry
32 * some more information (like addr).
33 */
34 typedef struct _MachOSymbol {
35 SymbolName * name; /* the name of the symbol. */
36 SymbolAddr * addr; /* the final resting place of the symbol */
37 void * got_addr; /* address of the got slot for this symbol, if any */
38 MachONList * nlist; /* the nlist symbol entry */
39 } MachOSymbol;
40
41 typedef struct _ObjectCodeFormatInfo {
42 // while we have the image
43 // we can store some pointers
44 // into it, so we don't have
45 // recompute them each time.
46 /* the object header */
47 MachOHeader *header;
48 MachOSymtabCommand *symCmd;
49 MachOSegmentCommand *segCmd;
50 MachODsymtabCommand *dsymCmd;
51 /* points to the first nlist in the image */
52 MachONList *nlist;
53 /* points to the names offset in the image */
54 char *names;
55
56 /* points to the start of the sections */
57 MachOSection *macho_sections;
58
59 /* A richer nlist type */
60 MachOSymbol *macho_symbols;
61 size_t n_macho_symbols;
62
63 /* pointer to the global offset table */
64 void *got_start;
65 size_t got_size;
66 } ObjectCodeFormatInfo;
67
68 /* When loading sections of the macho
69 * into different pages, such that the
70 * pages can be marked r+x for text and
71 * r+w for data, relocation may need
72 * to be done indirectly, as the symbol
73 * is not within reach of the of the
74 * call site. E.g. B/BL instructions on
75 * aarch64 have +-128mb relative
76 * range. When pages are mmap'd they
77 * may end up at random positions.
78 *
79 * Hence we reserve space for the stub
80 * slots right after the text section
81 *
82 * .----------. - page start
83 * | |
84 * | __TEXT |
85 * | |
86 * |----------|
87 * | Stubs |
88 * '----------'
89 *
90 * Therefore, unless the __TEXT section
91 * grows beyond 128mb-|Stubs|, we can
92 * always reach the corresponding stub
93 * for a symbol.
94 *
95 * Stubs will be rendered as
96 * - 8 bytes: target address
97 * - 4 bytes: relative load at -8bytes
98 instruction
99 * - 4 bytes: branch instruction
100 *
101 * These are very similar to the SymbolExtras
102 * below. However the SymbolExtras are allocated
103 * per ObjectCode and not per Section.
104 *
105 * TODO: Merge SymbolExtras and Stubs.
106 */
107 typedef
108 struct _Stub {
109 void * addr;
110 void * target;
111 struct _Stub * next;
112 }
113 Stub;
114
115 typedef struct _SectionFormatInfo {
116 /*
117 * The following fields are relevant for stubs next to sections only.
118 */
119 void * stub_offset;
120 size_t stub_size;
121 size_t nstubs;
122 Stub * stubs;
123
124 /*
125 * The following fields make working with mach-o objects much easier.
126 */
127 MachOSection * macho_section;
128 MachORelocationInfo * relocation_info;
129 } SectionFormatInfo;
130
131 #endif /* OBJECTFORMAT_MACHO */