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