1 |
288 |
jeremybenn |
/* LTO routines for Mach-O object files.
|
2 |
|
|
Copyright 2010 Free Software Foundation, Inc.
|
3 |
|
|
Contributed by Steven Bosscher.
|
4 |
|
|
|
5 |
|
|
This file is part of GCC.
|
6 |
|
|
|
7 |
|
|
GCC is free software; you can redistribute it and/or modify it under
|
8 |
|
|
the terms of the GNU General Public License as published by the Free
|
9 |
|
|
Software Foundation; either version 3, or (at your option) any later
|
10 |
|
|
version.
|
11 |
|
|
|
12 |
|
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
13 |
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
14 |
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
15 |
|
|
for more details.
|
16 |
|
|
|
17 |
|
|
You should have received a copy of the GNU General Public License
|
18 |
|
|
along with GCC; see the file COPYING3. If not see
|
19 |
|
|
<http://www.gnu.org/licenses/>. */
|
20 |
|
|
|
21 |
|
|
#ifndef LTO_MACH_O_H
|
22 |
|
|
#define LTO_MACH_O_H
|
23 |
|
|
|
24 |
|
|
/* On-disk file structures. */
|
25 |
|
|
|
26 |
|
|
/* Mach-O header (32 bits version). */
|
27 |
|
|
struct mach_o_header_32
|
28 |
|
|
{
|
29 |
|
|
unsigned char magic[4]; /* Magic number. */
|
30 |
|
|
unsigned char cputype[4]; /* CPU that this object is for. */
|
31 |
|
|
unsigned char cpusubtype[4]; /* CPU subtype. */
|
32 |
|
|
unsigned char filetype[4]; /* Type of file. */
|
33 |
|
|
unsigned char ncmds[4]; /* Number of load commands. */
|
34 |
|
|
unsigned char sizeofcmds[4]; /* Total size of load commands. */
|
35 |
|
|
unsigned char flags[4]; /* Flags for special featues. */
|
36 |
|
|
};
|
37 |
|
|
typedef struct mach_o_header_32 mach_o_header_32;
|
38 |
|
|
|
39 |
|
|
/* Mach-O header (64 bits version). */
|
40 |
|
|
struct mach_o_header_64
|
41 |
|
|
{
|
42 |
|
|
unsigned char magic[4]; /* Magic number. */
|
43 |
|
|
unsigned char cputype[4]; /* CPU that this object is for. */
|
44 |
|
|
unsigned char cpusubtype[4]; /* CPU subtype. */
|
45 |
|
|
unsigned char filetype[4]; /* Type of file. */
|
46 |
|
|
unsigned char ncmds[4]; /* Number of load commands. */
|
47 |
|
|
unsigned char sizeofcmds[4]; /* Total size of load commands. */
|
48 |
|
|
unsigned char flags[4]; /* Flags for special featues. */
|
49 |
|
|
unsigned char reserved[4]; /* Reserved. Duh. */
|
50 |
|
|
};
|
51 |
|
|
typedef struct mach_o_header_64 mach_o_header_64;
|
52 |
|
|
|
53 |
|
|
/* Magic number. */
|
54 |
|
|
#define MACH_O_MH_MAGIC 0xfeedface
|
55 |
|
|
#define MACH_O_MH_CIGAM 0xcefaedfe
|
56 |
|
|
#define MACH_O_MH_MAGIC_64 0xfeedfacf
|
57 |
|
|
#define MACH_O_MH_CIGAM_64 0xcffaedfe
|
58 |
|
|
|
59 |
|
|
/* Supported CPU types. */
|
60 |
|
|
#define MACH_O_CPU_TYPE_I386 7
|
61 |
|
|
#define MACH_O_CPU_TYPE_X86_64 7 + 0x1000000
|
62 |
|
|
#define MACH_O_CPU_TYPE_POWERPC 18
|
63 |
|
|
#define MACH_O_CPU_TYPE_POWERPC_64 18 + 0x1000000
|
64 |
|
|
|
65 |
|
|
/* Supported file types. */
|
66 |
|
|
#define MACH_O_MH_OBJECT 0x01
|
67 |
|
|
|
68 |
|
|
/* Mach-O load command data structure. */
|
69 |
|
|
struct mach_o_load_command
|
70 |
|
|
{
|
71 |
|
|
unsigned char cmd[4]; /* The type of load command. */
|
72 |
|
|
unsigned char cmdsize[4]; /* Size in bytes of load command data structure. */
|
73 |
|
|
};
|
74 |
|
|
typedef struct mach_o_load_command mach_o_load_command;
|
75 |
|
|
|
76 |
|
|
/* Supported load commands. We support only the segment load commands. */
|
77 |
|
|
#define MACH_O_LC_SEGMENT 0x01
|
78 |
|
|
#define MACH_O_LC_SEGMENT_64 0x19
|
79 |
|
|
|
80 |
|
|
/* LC_SEGMENT load command. */
|
81 |
|
|
struct mach_o_segment_command_32
|
82 |
|
|
{
|
83 |
|
|
unsigned char cmd[4]; /* The type of load command (LC_SEGMENT). */
|
84 |
|
|
unsigned char cmdsize[4]; /* Size in bytes of load command data structure. */
|
85 |
|
|
unsigned char segname[16]; /* Name of this segment. */
|
86 |
|
|
unsigned char vmaddr[4]; /* Virtual memory address of this segment. */
|
87 |
|
|
unsigned char vmsize[4]; /* Size there, in bytes. */
|
88 |
|
|
unsigned char fileoff[4]; /* Offset in bytes of the data to be mapped. */
|
89 |
|
|
unsigned char filesize[4]; /* Size in bytes on disk. */
|
90 |
|
|
unsigned char maxprot[4]; /* Maximum permitted vmem protection. */
|
91 |
|
|
unsigned char initprot[4]; /* Initial vmem protection. */
|
92 |
|
|
unsigned char nsects[4]; /* Number of sections in this segment. */
|
93 |
|
|
unsigned char flags[4]; /* Flags that affect the loading. */
|
94 |
|
|
};
|
95 |
|
|
typedef struct mach_o_segment_command_32 mach_o_segment_command_32;
|
96 |
|
|
|
97 |
|
|
/* LC_SEGMENT_64 load command. Only nsects matters for us, really. */
|
98 |
|
|
struct mach_o_segment_command_64
|
99 |
|
|
{
|
100 |
|
|
unsigned char cmd[4]; /* The type of load command (LC_SEGMENT_64). */
|
101 |
|
|
unsigned char cmdsize[4]; /* Size in bytes of load command data structure. */
|
102 |
|
|
unsigned char segname[16]; /* Name of this segment. */
|
103 |
|
|
unsigned char vmaddr[8]; /* Virtual memory address of this segment. */
|
104 |
|
|
unsigned char vmsize[8]; /* Size there, in bytes. */
|
105 |
|
|
unsigned char fileoff[8]; /* Offset in bytes of the data to be mapped. */
|
106 |
|
|
unsigned char filesize[8]; /* Size in bytes on disk. */
|
107 |
|
|
unsigned char maxprot[4]; /* Maximum permitted vmem protection. */
|
108 |
|
|
unsigned char initprot[4]; /* Initial vmem protection. */
|
109 |
|
|
unsigned char nsects[4]; /* Number of sections in this segment. */
|
110 |
|
|
unsigned char flags[4]; /* Flags that affect the loading. */
|
111 |
|
|
};
|
112 |
|
|
typedef struct mach_o_segment_command_64 mach_o_segment_command_64;
|
113 |
|
|
|
114 |
|
|
/* A Mach-O 32-bits section. */
|
115 |
|
|
struct mach_o_section_32
|
116 |
|
|
{
|
117 |
|
|
unsigned char sectname[16]; /* Section name. */
|
118 |
|
|
unsigned char segname[16]; /* Segment that the section belongs to. */
|
119 |
|
|
unsigned char addr[4]; /* Address of this section in memory. */
|
120 |
|
|
unsigned char size[4]; /* Size in bytes of this section. */
|
121 |
|
|
unsigned char offset[4]; /* File offset of this section. */
|
122 |
|
|
unsigned char align[4]; /* log2 of this section's alignment. */
|
123 |
|
|
unsigned char reloff[4]; /* File offset of this section's relocs. */
|
124 |
|
|
unsigned char nreloc[4]; /* Number of relocs for this section. */
|
125 |
|
|
unsigned char flags[4]; /* Section flags/attributes. */
|
126 |
|
|
unsigned char reserved1[4];
|
127 |
|
|
unsigned char reserved2[4];
|
128 |
|
|
};
|
129 |
|
|
typedef struct mach_o_section_32 mach_o_section_32;
|
130 |
|
|
|
131 |
|
|
/* A Mach-O 64-bits section. */
|
132 |
|
|
struct mach_o_section_64
|
133 |
|
|
{
|
134 |
|
|
unsigned char sectname[16]; /* Section name. */
|
135 |
|
|
unsigned char segname[16]; /* Segment that the section belongs to. */
|
136 |
|
|
unsigned char addr[8]; /* Address of this section in memory. */
|
137 |
|
|
unsigned char size[8]; /* Size in bytes of this section. */
|
138 |
|
|
unsigned char offset[4]; /* File offset of this section. */
|
139 |
|
|
unsigned char align[4]; /* log2 of this section's alignment. */
|
140 |
|
|
unsigned char reloff[4]; /* File offset of this section's relocs. */
|
141 |
|
|
unsigned char nreloc[4]; /* Number of relocs for this section. */
|
142 |
|
|
unsigned char flags[4]; /* Section flags/attributes. */
|
143 |
|
|
unsigned char reserved1[4];
|
144 |
|
|
unsigned char reserved2[4];
|
145 |
|
|
unsigned char reserved3[4];
|
146 |
|
|
};
|
147 |
|
|
typedef struct mach_o_section_64 mach_o_section_64;
|
148 |
|
|
|
149 |
|
|
/* Flags for Mach-O sections. LTO sections are marked with S_ATTR_DEBUG
|
150 |
|
|
to instruct the linker to ignore the sections. */
|
151 |
|
|
#define MACH_O_S_ATTR_DEBUG 0x02000000
|
152 |
|
|
|
153 |
|
|
/* In-memory file structures. */
|
154 |
|
|
|
155 |
|
|
/* Section data in output files is made of these. */
|
156 |
|
|
struct lto_mach_o_data_d
|
157 |
|
|
{
|
158 |
|
|
/* Pointer to data block. */
|
159 |
|
|
void *d_buf;
|
160 |
|
|
|
161 |
|
|
/* Size of data block. */
|
162 |
|
|
ssize_t d_size;
|
163 |
|
|
|
164 |
|
|
/* Next data block for this section. */
|
165 |
|
|
struct lto_mach_o_data_d *next;
|
166 |
|
|
};
|
167 |
|
|
typedef struct lto_mach_o_data_d *lto_mach_o_data;
|
168 |
|
|
|
169 |
|
|
/* This struct tracks the data for a section. */
|
170 |
|
|
struct lto_mach_o_section_d
|
171 |
|
|
{
|
172 |
|
|
/* Singly-linked list of section's data blocks. */
|
173 |
|
|
lto_mach_o_data data_chain;
|
174 |
|
|
|
175 |
|
|
/* Offset in string table of the section name. */
|
176 |
|
|
size_t strtab_offs;
|
177 |
|
|
|
178 |
|
|
/* Section name. */
|
179 |
|
|
const char *name;
|
180 |
|
|
|
181 |
|
|
/* Number of trailing padding bytes needed. */
|
182 |
|
|
ssize_t pad_needed;
|
183 |
|
|
|
184 |
|
|
/* Raw section header data. */
|
185 |
|
|
size_t section_size;
|
186 |
|
|
union {
|
187 |
|
|
struct {
|
188 |
|
|
char sectname[16];
|
189 |
|
|
char segname[16];
|
190 |
|
|
} section;
|
191 |
|
|
mach_o_section_32 section_32;
|
192 |
|
|
mach_o_section_64 section_64;
|
193 |
|
|
} u;
|
194 |
|
|
|
195 |
|
|
/* Next section for this file. */
|
196 |
|
|
struct lto_mach_o_section_d *next;
|
197 |
|
|
};
|
198 |
|
|
typedef struct lto_mach_o_section_d *lto_mach_o_section;
|
199 |
|
|
DEF_VEC_P (lto_mach_o_section);
|
200 |
|
|
DEF_VEC_ALLOC_P (lto_mach_o_section, heap);
|
201 |
|
|
|
202 |
|
|
/* A Mach-O file. */
|
203 |
|
|
struct lto_mach_o_file_d
|
204 |
|
|
{
|
205 |
|
|
/* The base information. */
|
206 |
|
|
lto_file base;
|
207 |
|
|
|
208 |
|
|
/* Common file members: */
|
209 |
|
|
|
210 |
|
|
/* The system file descriptor for the file. */
|
211 |
|
|
int fd;
|
212 |
|
|
|
213 |
|
|
/* The file's overall header. */
|
214 |
|
|
union {
|
215 |
|
|
/* We make use here of the fact that section_32 and section_64
|
216 |
|
|
have the same layout (except for section_64.reserved3). We
|
217 |
|
|
read the struct of proper size, but only address the first
|
218 |
|
|
member of this union. */
|
219 |
|
|
mach_o_header_64 header;
|
220 |
|
|
mach_o_header_32 header_32;
|
221 |
|
|
mach_o_header_64 header_64;
|
222 |
|
|
} u;
|
223 |
|
|
|
224 |
|
|
/* All sections in a varray. */
|
225 |
|
|
VEC(lto_mach_o_section, heap) *section_vec;
|
226 |
|
|
|
227 |
|
|
/* Readable file members: */
|
228 |
|
|
|
229 |
|
|
/* File total size. */
|
230 |
|
|
off_t file_size;
|
231 |
|
|
|
232 |
|
|
/* True if this file is open for writing. */
|
233 |
|
|
bool writable;
|
234 |
|
|
|
235 |
|
|
/* Section containing the __section_names section. */
|
236 |
|
|
lto_mach_o_section section_names_section;
|
237 |
|
|
|
238 |
|
|
/* Writable file members: */
|
239 |
|
|
|
240 |
|
|
/* The currently active section. */
|
241 |
|
|
lto_mach_o_section scn;
|
242 |
|
|
|
243 |
|
|
/* Linked list of data which must be freed *after* the file has been
|
244 |
|
|
closed. This is an annoying limitation of libelf. Which has been
|
245 |
|
|
faithfully reproduced here. */
|
246 |
|
|
struct lto_char_ptr_base *data;
|
247 |
|
|
};
|
248 |
|
|
typedef struct lto_mach_o_file_d lto_mach_o_file;
|
249 |
|
|
|
250 |
|
|
#endif /* LTO_MACH_O_H */
|
251 |
|
|
|