Mercurial > hg > CbC > CbC_gcc
comparison gcc/lto/lto-coff.h @ 63:b7f97abdc517 gcc-4.6-20100522
update gcc from gcc-4.5.0 to gcc-4.6
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 24 May 2010 12:47:05 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
56:3c8a44c06a95 | 63:b7f97abdc517 |
---|---|
1 /* LTO routines for COFF object files. | |
2 Copyright 2009 Free Software Foundation, Inc. | |
3 Contributed by Dave Korn. | |
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_COFF_H | |
22 #define LTO_COFF_H | |
23 | |
24 /* Rather than implementing a libcoff to match libelf, or attempting to | |
25 integrate libbfd into GCC, this file is a self-contained (and very | |
26 minimal) COFF format object file reader/writer. The generated files | |
27 will contain a COFF header, a number of COFF section headers, the | |
28 section data itself, and a trailing string table for section names. */ | |
29 | |
30 /* Alignment of sections in a COFF object file. | |
31 | |
32 The LTO writer uses zlib compression on the data that it streams into | |
33 LTO sections in the output object file. Because these streams don't | |
34 have any embedded size information, the section in the object file must | |
35 be exactly sized to the data emitted; any trailing padding bytes will | |
36 be interpreted as partial and/or corrupt compressed data. | |
37 | |
38 This is easy enough to do on COFF targets (with binutils 2.20.1 or | |
39 above) because we can specify 1-byte alignment for the LTO sections. | |
40 They are then emitted precisely-sized and byte-packed into the object | |
41 and the reader is happy when it parses them later. This is currently | |
42 implemented in the x86/windows backed in i386_pe_asm_named_section() | |
43 in config/i386/winnt.c by detecting the LTO section name prefix, | |
44 | |
45 That would be sufficient, but for one thing. At the start of the LTO | |
46 data is a header struct with (currently) a couple of version numbers and | |
47 some type info; see struct lto_header in lto-streamer.h. If the sections | |
48 are byte-packed, this header will not necessarily be correctly-aligned | |
49 when it is read back into memory. | |
50 | |
51 On x86 targets, which are currently the only LTO-COFF targets, misaligned | |
52 memory accesses aren't problematic (okay, inefficient, but not worth | |
53 worrying about two half-word memory reads per section in the context of | |
54 everything else the compiler has to do at the time!), but RISC targets may | |
55 fail on trying to access the header struct. In this case, it will be | |
56 necessary to enable (preferably in a target-dependent fashion, but a few | |
57 bytes of padding are hardly an important issue if it comes down to it) the | |
58 COFF_ALIGNMENT macros below. | |
59 | |
60 As currently implemented, this will emit padding to the necessary number | |
61 of bytes after each LTO section. These bytes will constitute 'gaps' in | |
62 the object file structure, as they won't be covered by any section header. | |
63 This hasn't yet been tested, because no such RISC LTO-COFF target yet | |
64 exists. If it causes problems further down the toolchain, it will be | |
65 necessary to adapt the code to emit additional section headers for these | |
66 padding bytes, but the odds are that it will "just work". | |
67 | |
68 */ | |
69 | |
70 #if 0 | |
71 #define COFF_ALIGNMENT (4) | |
72 #define COFF_ALIGNMENTM1 (COFF_ALIGNMENT - 1) | |
73 #define COFF_ALIGN(x) (((x) + COFF_ALIGNMENTM1) & ~COFF_ALIGNMENTM1) | |
74 #else | |
75 #define COFF_ALIGNMENT (1) | |
76 #define COFF_ALIGN(x) (x) | |
77 #endif | |
78 | |
79 /* COFF header machine codes. */ | |
80 | |
81 #define IMAGE_FILE_MACHINE_I386 (0x014c) | |
82 #define IMAGE_FILE_MACHINE_AMD64 (0x8664) | |
83 | |
84 /* Known header magics for validation, as an array initialiser. */ | |
85 | |
86 #define COFF_KNOWN_MACHINES \ | |
87 { IMAGE_FILE_MACHINE_I386, \ | |
88 IMAGE_FILE_MACHINE_AMD64/*, ... add more here when working. */ } | |
89 | |
90 /* COFF object file header, section and symbol flags and types. These are | |
91 currently specific to PE-COFF, which is the only LTO-COFF format at the | |
92 time of writing. Maintainers adding support for new COFF formats will | |
93 need to make these into target macros of some kind. */ | |
94 | |
95 /* COFF header characteristics. */ | |
96 | |
97 #define IMAGE_FILE_EXECUTABLE_IMAGE (1 << 1) | |
98 #define IMAGE_FILE_32BIT_MACHINE (1 << 8) | |
99 #define IMAGE_FILE_SYSTEM (1 << 12) | |
100 #define IMAGE_FILE_DLL (1 << 13) | |
101 | |
102 /* Desired characteristics (for validation). */ | |
103 | |
104 #define COFF_CHARACTERISTICS \ | |
105 (IMAGE_FILE_32BIT_MACHINE) | |
106 | |
107 /* Unwanted characteristics (for validation). */ | |
108 | |
109 #define COFF_NOT_CHARACTERISTICS \ | |
110 (IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_SYSTEM | IMAGE_FILE_DLL) | |
111 | |
112 /* Section flags. LTO emits byte-aligned read-only loadable data sections. */ | |
113 | |
114 #define IMAGE_SCN_CNT_INITIALIZED_DATA (1 << 6) | |
115 #define IMAGE_SCN_CNT_UNINITIALIZED_DATA (1 << 7) | |
116 #define IMAGE_SCN_ALIGN_1BYTES (0x1 << 20) | |
117 #define IMAGE_SCN_MEM_DISCARDABLE (1 << 25) | |
118 #define IMAGE_SCN_MEM_SHARED (1 << 28) | |
119 #define IMAGE_SCN_MEM_READ (1 << 30) | |
120 | |
121 #define COFF_SECTION_CHARACTERISTICS \ | |
122 (IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_1BYTES | \ | |
123 IMAGE_SCN_MEM_DISCARDABLE | IMAGE_SCN_MEM_SHARED | IMAGE_SCN_MEM_READ) | |
124 | |
125 /* Symbol-related constants. */ | |
126 | |
127 #define IMAGE_SYM_DEBUG (-2) | |
128 #define IMAGE_SYM_TYPE_NULL (0) | |
129 #define IMAGE_SYM_DTYPE_NULL (0) | |
130 #define IMAGE_SYM_CLASS_STATIC (3) | |
131 #define IMAGE_SYM_CLASS_FILE (103) | |
132 | |
133 #define IMAGE_SYM_TYPE \ | |
134 ((IMAGE_SYM_DTYPE_NULL << 4) | IMAGE_SYM_TYPE_NULL) | |
135 | |
136 /* Size of a COFF symbol in bytes. */ | |
137 | |
138 #define COFF_SYMBOL_SIZE (18) | |
139 | |
140 /* On-disk file structures. */ | |
141 | |
142 struct Coff_header | |
143 { | |
144 unsigned char Machine[2]; | |
145 unsigned char NumberOfSections[2]; | |
146 unsigned char TimeDateStamp[4]; | |
147 unsigned char PointerToSymbolTable[4]; | |
148 unsigned char NumberOfSymbols[4]; | |
149 unsigned char SizeOfOptionalHeader[2]; | |
150 unsigned char Characteristics[2]; | |
151 }; | |
152 typedef struct Coff_header Coff_header; | |
153 | |
154 struct Coff_section | |
155 { | |
156 unsigned char Name[8]; | |
157 unsigned char VirtualSize[4]; | |
158 unsigned char VirtualAddress[4]; | |
159 unsigned char SizeOfRawData[4]; | |
160 unsigned char PointerToRawData[4]; | |
161 unsigned char PointerToRelocations[4]; | |
162 unsigned char PointerToLinenumbers[4]; | |
163 unsigned char NumberOfRelocations[2]; | |
164 unsigned char NumberOfLinenumbers[2]; | |
165 unsigned char Characteristics[4]; | |
166 }; | |
167 typedef struct Coff_section Coff_section; | |
168 | |
169 struct Coff_symbol | |
170 { | |
171 unsigned char Name[8]; | |
172 unsigned char Value[4]; | |
173 unsigned char SectionNumber[2]; | |
174 unsigned char Type[2]; | |
175 unsigned char StorageClass[1]; | |
176 unsigned char NumberOfAuxSymbols[1]; | |
177 }; | |
178 typedef struct Coff_symbol Coff_symbol; | |
179 | |
180 struct Coff_aux_sym_file | |
181 { | |
182 unsigned char FileName[18]; | |
183 }; | |
184 typedef struct Coff_aux_sym_file Coff_aux_sym_file; | |
185 | |
186 struct Coff_aux_sym_section | |
187 { | |
188 unsigned char Length[4]; | |
189 unsigned char NumberOfRelocations[2]; | |
190 unsigned char NumberOfLineNumbers[2]; | |
191 unsigned char Checksum[4]; | |
192 unsigned char Number[2]; | |
193 unsigned char Selection[1]; | |
194 unsigned char Unused[3]; | |
195 }; | |
196 typedef struct Coff_aux_sym_section Coff_aux_sym_section; | |
197 | |
198 /* Accessor macros for the above structures. */ | |
199 | |
200 #define COFF_GET(struc,memb) \ | |
201 ((COFFENDIAN ? get_be : get_le) (&(struc)->memb[0], sizeof ((struc)->memb))) | |
202 | |
203 #define COFF_PUT(struc,memb,val) \ | |
204 ((COFFENDIAN ? put_be : put_le) (&(struc)->memb[0], sizeof ((struc)->memb), val)) | |
205 | |
206 #define COFF_PUT_NDXSZ(struc,memb,val,ndx,sz) \ | |
207 ((COFFENDIAN ? put_be : put_le) (&(struc)->memb[ndx], sz, val)) | |
208 | |
209 /* In-memory file structures. */ | |
210 | |
211 /* Forward declared structs. */ | |
212 | |
213 struct lto_coff_data; | |
214 struct lto_coff_section; | |
215 struct lto_coff_file; | |
216 | |
217 /* Section data in output files is made of these. */ | |
218 | |
219 struct lto_coff_data | |
220 { | |
221 /* Pointer to data block. */ | |
222 void *d_buf; | |
223 | |
224 /* Size of data block. */ | |
225 ssize_t d_size; | |
226 | |
227 /* Next data block for this section. */ | |
228 struct lto_coff_data *next; | |
229 }; | |
230 typedef struct lto_coff_data lto_coff_data; | |
231 | |
232 /* This struct tracks the data for a section. */ | |
233 | |
234 struct lto_coff_section | |
235 { | |
236 /* Singly-linked list of section's data blocks. */ | |
237 lto_coff_data *data_chain; | |
238 | |
239 /* Offset in string table of name. */ | |
240 size_t strtab_offs; | |
241 | |
242 /* Section type: 0 = real, 1 = dummy. */ | |
243 size_t type; | |
244 | |
245 /* Section name. */ | |
246 const char *name; | |
247 | |
248 #if COFF_ALIGNMENT > 1 | |
249 /* Number of trailing padding bytes needed. */ | |
250 ssize_t pad_needed; | |
251 #endif | |
252 | |
253 /* Raw section header data. */ | |
254 Coff_section coffsec; | |
255 | |
256 /* Next section for this file. */ | |
257 struct lto_coff_section *next; | |
258 }; | |
259 typedef struct lto_coff_section lto_coff_section; | |
260 | |
261 /* A COFF file. */ | |
262 | |
263 struct lto_coff_file | |
264 { | |
265 /* The base information. */ | |
266 lto_file base; | |
267 | |
268 /* Common file members: */ | |
269 | |
270 /* The system file descriptor for the file. */ | |
271 int fd; | |
272 | |
273 /* The file's overall header. */ | |
274 Coff_header coffhdr; | |
275 | |
276 /* All sections in a singly-linked list. */ | |
277 lto_coff_section *section_chain; | |
278 | |
279 /* Readable file members: */ | |
280 | |
281 /* File total size. */ | |
282 off_t file_size; | |
283 | |
284 /* String table file offset, relative to base.offset. */ | |
285 off_t strtab_offs; | |
286 | |
287 /* Writable file members: */ | |
288 | |
289 /* The currently active section. */ | |
290 lto_coff_section *scn; | |
291 | |
292 /* The output stream for section header names. */ | |
293 struct lto_output_stream *shstrtab_stream; | |
294 | |
295 /* Linked list of data which must be freed *after* the file has been | |
296 closed. This is an annoying limitation of libelf. Which has been | |
297 faithfully reproduced here. */ | |
298 struct lto_char_ptr_base *data; | |
299 }; | |
300 typedef struct lto_coff_file lto_coff_file; | |
301 | |
302 /* Data hunk iterator. */ | |
303 | |
304 #define COFF_FOR_ALL_DATA(sec,var) \ | |
305 for (var = sec->data_chain; var; var = var->next) | |
306 | |
307 /* Section list iterator. */ | |
308 | |
309 #define COFF_FOR_ALL_SECTIONS(file,var) \ | |
310 for (var = file->section_chain; var; var = var->next) | |
311 | |
312 /* Very simple endian-ness layer. */ | |
313 | |
314 #ifndef COFFENDIAN | |
315 #define COFFENDIAN (BYTES_BIG_ENDIAN) | |
316 #endif | |
317 | |
318 static inline unsigned int | |
319 get_2_le (const unsigned char *ptr) | |
320 { | |
321 return ptr[0] | (ptr[1] << 8); | |
322 } | |
323 | |
324 static inline unsigned int | |
325 get_4_le (const unsigned char *ptr) | |
326 { | |
327 return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24); | |
328 } | |
329 | |
330 static inline unsigned int | |
331 get_2_be (const unsigned char *ptr) | |
332 { | |
333 return ptr[1] | (ptr[0] << 8); | |
334 } | |
335 | |
336 static inline unsigned int | |
337 get_4_be (const unsigned char *ptr) | |
338 { | |
339 return ptr[3] | (ptr[2] << 8) | (ptr[1] << 16) | (ptr[0] << 24); | |
340 } | |
341 | |
342 static inline unsigned int | |
343 get_be (const unsigned char *ptr, size_t size) | |
344 { | |
345 gcc_assert (size == 4 || size == 2); | |
346 return (size == 2) ? get_2_be (ptr) : get_4_be (ptr); | |
347 } | |
348 | |
349 static inline unsigned int | |
350 get_le (const unsigned char *ptr, size_t size) | |
351 { | |
352 gcc_assert (size == 4 || size == 2); | |
353 return (size == 2) ? get_2_le (ptr) : get_4_le (ptr); | |
354 } | |
355 | |
356 static inline void | |
357 put_2_le (unsigned char *ptr, unsigned int data) | |
358 { | |
359 ptr[0] = data & 0xff; | |
360 ptr[1] = (data >> 8) & 0xff; | |
361 } | |
362 | |
363 static inline void | |
364 put_4_le (unsigned char *ptr, unsigned int data) | |
365 { | |
366 ptr[0] = data & 0xff; | |
367 ptr[1] = (data >> 8) & 0xff; | |
368 ptr[2] = (data >> 16) & 0xff; | |
369 ptr[3] = (data >> 24) & 0xff; | |
370 } | |
371 | |
372 static inline void | |
373 put_2_be (unsigned char *ptr, unsigned int data) | |
374 { | |
375 ptr[1] = data & 0xff; | |
376 ptr[0] = (data >> 8) & 0xff; | |
377 } | |
378 | |
379 static inline void | |
380 put_4_be (unsigned char *ptr, unsigned int data) | |
381 { | |
382 ptr[3] = data & 0xff; | |
383 ptr[2] = (data >> 8) & 0xff; | |
384 ptr[1] = (data >> 16) & 0xff; | |
385 ptr[0] = (data >> 24) & 0xff; | |
386 } | |
387 | |
388 static inline void | |
389 put_le (unsigned char *ptr, size_t size, unsigned int data) | |
390 { | |
391 gcc_assert (size == 4 || size == 2); | |
392 (void) (size == 2 ? put_2_le : put_4_le) (ptr, data); | |
393 } | |
394 | |
395 static inline void | |
396 put_be (unsigned char *ptr, size_t size, unsigned int data) | |
397 { | |
398 gcc_assert (size == 4 || size == 2); | |
399 (void) (size == 2 ? put_2_be : put_4_be) (ptr, data); | |
400 } | |
401 | |
402 /* We use this for putting the string table size. */ | |
403 | |
404 #define COFF_PUT4(ptr, data) \ | |
405 ((COFFENDIAN ? put_4_be : put_4_le) (ptr, data)) | |
406 | |
407 | |
408 #endif /* LTO_COFF_H */ |