Mercurial > hg > CbC > CbC_gcc
comparison gcc/lto/lto-elf.c @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | |
children | b7f97abdc517 |
comparison
equal
deleted
inserted
replaced
52:c156f1bd5cd9 | 55:77e2b8dfacca |
---|---|
1 /* LTO routines for ELF object files. | |
2 Copyright 2009 Free Software Foundation, Inc. | |
3 Contributed by CodeSourcery, Inc. | |
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 #include "config.h" | |
22 #include "system.h" | |
23 #include "coretypes.h" | |
24 #include "toplev.h" | |
25 #include <gelf.h> | |
26 #include "lto.h" | |
27 #include "tm.h" | |
28 #include "libiberty.h" | |
29 #include "ggc.h" | |
30 #include "lto-streamer.h" | |
31 | |
32 | |
33 /* Initialize FILE, an LTO file object for FILENAME. */ | |
34 static void | |
35 lto_file_init (lto_file *file, const char *filename, off_t offset) | |
36 { | |
37 file->filename = filename; | |
38 file->offset = offset; | |
39 } | |
40 | |
41 /* An ELF file. */ | |
42 struct lto_elf_file | |
43 { | |
44 /* The base information. */ | |
45 lto_file base; | |
46 | |
47 /* The system file descriptor for the file. */ | |
48 int fd; | |
49 | |
50 /* The libelf descriptor for the file. */ | |
51 Elf *elf; | |
52 | |
53 /* Section number of string table used for section names. */ | |
54 size_t sec_strtab; | |
55 | |
56 /* Writable file members. */ | |
57 | |
58 /* The currently active section. */ | |
59 Elf_Scn *scn; | |
60 | |
61 /* The output stream for section header names. */ | |
62 struct lto_output_stream *shstrtab_stream; | |
63 | |
64 /* Linked list of data which must be freed *after* the file has been | |
65 closed. This is an annoying limitation of libelf. */ | |
66 struct lto_char_ptr_base *data; | |
67 }; | |
68 typedef struct lto_elf_file lto_elf_file; | |
69 | |
70 /* Stores executable header attributes which must be shared by all ELF files. | |
71 This is used for validating input files and populating output files. */ | |
72 static struct { | |
73 bool initialized; | |
74 /* 32 or 64 bits? */ | |
75 size_t bits; | |
76 unsigned char elf_ident[EI_NIDENT]; | |
77 Elf64_Half elf_machine; | |
78 } cached_file_attrs; | |
79 | |
80 | |
81 /* Return the section header for SECTION. The return value is never | |
82 NULL. Call lto_elf_free_shdr to release the memory allocated. */ | |
83 | |
84 static Elf64_Shdr * | |
85 lto_elf_get_shdr (Elf_Scn *section) | |
86 { | |
87 Elf64_Shdr *shdr; | |
88 | |
89 switch (cached_file_attrs.bits) | |
90 { | |
91 case 32: | |
92 { | |
93 Elf32_Shdr *shdr32; | |
94 | |
95 /* Read the 32-bit section header. */ | |
96 shdr32 = elf32_getshdr (section); | |
97 if (!shdr32) | |
98 fatal_error ("could not read section header: %s", elf_errmsg (0)); | |
99 | |
100 /* Transform it into a 64-bit section header. */ | |
101 shdr = XNEW (Elf64_Shdr); | |
102 shdr->sh_name = shdr32->sh_name; | |
103 shdr->sh_type = shdr32->sh_type; | |
104 shdr->sh_flags = shdr32->sh_flags; | |
105 shdr->sh_addr = shdr32->sh_addr; | |
106 shdr->sh_offset = shdr32->sh_offset; | |
107 shdr->sh_size = shdr32->sh_size; | |
108 shdr->sh_link = shdr32->sh_link; | |
109 shdr->sh_info = shdr32->sh_info; | |
110 shdr->sh_addralign = shdr32->sh_addralign; | |
111 shdr->sh_entsize = shdr32->sh_entsize; | |
112 break; | |
113 } | |
114 break; | |
115 | |
116 case 64: | |
117 shdr = elf64_getshdr (section); | |
118 if (!shdr) | |
119 fatal_error ("could not read section header: %s", elf_errmsg (0)); | |
120 break; | |
121 | |
122 default: | |
123 gcc_unreachable (); | |
124 } | |
125 | |
126 return shdr; | |
127 } | |
128 | |
129 /* Free SHDR, previously allocated by lto_elf_get_shdr. */ | |
130 static void | |
131 lto_elf_free_shdr (Elf64_Shdr *shdr) | |
132 { | |
133 if (cached_file_attrs.bits != 64) | |
134 free (shdr); | |
135 } | |
136 | |
137 | |
138 /* Returns a hash code for P. */ | |
139 | |
140 static hashval_t | |
141 hash_name (const void *p) | |
142 { | |
143 const struct lto_section_slot *ds = (const struct lto_section_slot *) p; | |
144 return (hashval_t) htab_hash_string (ds->name); | |
145 } | |
146 | |
147 | |
148 /* Returns nonzero if P1 and P2 are equal. */ | |
149 | |
150 static int | |
151 eq_name (const void *p1, const void *p2) | |
152 { | |
153 const struct lto_section_slot *s1 = | |
154 (const struct lto_section_slot *) p1; | |
155 const struct lto_section_slot *s2 = | |
156 (const struct lto_section_slot *) p2; | |
157 | |
158 return strcmp (s1->name, s2->name) == 0; | |
159 } | |
160 | |
161 | |
162 /* Build a hash table whose key is the section names and whose data is | |
163 the start and size of each section in the .o file. */ | |
164 | |
165 htab_t | |
166 lto_elf_build_section_table (lto_file *lto_file) | |
167 { | |
168 lto_elf_file *elf_file = (lto_elf_file *)lto_file; | |
169 htab_t section_hash_table; | |
170 Elf_Scn *section; | |
171 size_t base_offset; | |
172 | |
173 section_hash_table = htab_create (37, hash_name, eq_name, free); | |
174 | |
175 base_offset = elf_getbase (elf_file->elf); | |
176 for (section = elf_getscn (elf_file->elf, 0); | |
177 section; | |
178 section = elf_nextscn (elf_file->elf, section)) | |
179 { | |
180 Elf64_Shdr *shdr; | |
181 const char *name; | |
182 size_t offset; | |
183 char *new_name; | |
184 void **slot; | |
185 struct lto_section_slot s_slot; | |
186 | |
187 /* Get the name of this section. */ | |
188 shdr = lto_elf_get_shdr (section); | |
189 offset = shdr->sh_name; | |
190 name = elf_strptr (elf_file->elf, | |
191 elf_file->sec_strtab, | |
192 offset); | |
193 | |
194 /* Only put lto stuff into the symtab. */ | |
195 if (strncmp (name, LTO_SECTION_NAME_PREFIX, | |
196 strlen (LTO_SECTION_NAME_PREFIX)) != 0) | |
197 { | |
198 lto_elf_free_shdr (shdr); | |
199 continue; | |
200 } | |
201 | |
202 new_name = XNEWVEC (char, strlen (name) + 1); | |
203 strcpy (new_name, name); | |
204 s_slot.name = new_name; | |
205 slot = htab_find_slot (section_hash_table, &s_slot, INSERT); | |
206 if (*slot == NULL) | |
207 { | |
208 struct lto_section_slot *new_slot = XNEW (struct lto_section_slot); | |
209 | |
210 new_slot->name = new_name; | |
211 /* The offset into the file for this section. */ | |
212 new_slot->start = base_offset + shdr->sh_offset; | |
213 new_slot->len = shdr->sh_size; | |
214 *slot = new_slot; | |
215 } | |
216 else | |
217 { | |
218 error ("two or more sections for %s:", new_name); | |
219 return NULL; | |
220 } | |
221 | |
222 lto_elf_free_shdr (shdr); | |
223 } | |
224 | |
225 return section_hash_table; | |
226 } | |
227 | |
228 | |
229 /* Initialize the section header of section SCN. SH_NAME is the section name | |
230 as an index into the section header string table. SH_TYPE is the section | |
231 type, an SHT_* macro from libelf headers. */ | |
232 | |
233 #define DEFINE_INIT_SHDR(BITS) \ | |
234 static void \ | |
235 init_shdr##BITS (Elf_Scn *scn, size_t sh_name, size_t sh_type) \ | |
236 { \ | |
237 Elf##BITS##_Shdr *shdr; \ | |
238 \ | |
239 shdr = elf##BITS##_getshdr (scn); \ | |
240 if (!shdr) \ | |
241 { \ | |
242 if (BITS == 32) \ | |
243 fatal_error ("elf32_getshdr() failed: %s", elf_errmsg (-1)); \ | |
244 else \ | |
245 fatal_error ("elf64_getshdr() failed: %s", elf_errmsg (-1)); \ | |
246 } \ | |
247 \ | |
248 shdr->sh_name = sh_name; \ | |
249 shdr->sh_type = sh_type; \ | |
250 shdr->sh_addralign = POINTER_SIZE / BITS_PER_UNIT; \ | |
251 shdr->sh_flags = 0; \ | |
252 shdr->sh_entsize = 0; \ | |
253 } | |
254 | |
255 DEFINE_INIT_SHDR (32) | |
256 DEFINE_INIT_SHDR (64) | |
257 | |
258 static bool first_data_block; | |
259 | |
260 /* Begin a new ELF section named NAME with type TYPE in the current output | |
261 file. TYPE is an SHT_* macro from the libelf headers. */ | |
262 | |
263 static void | |
264 lto_elf_begin_section_with_type (const char *name, size_t type) | |
265 { | |
266 lto_elf_file *file; | |
267 Elf_Scn *scn; | |
268 size_t sh_name; | |
269 | |
270 /* Grab the current output file and do some basic assertion checking. */ | |
271 file = (lto_elf_file *) lto_get_current_out_file (), | |
272 gcc_assert (file); | |
273 gcc_assert (file->elf); | |
274 gcc_assert (!file->scn); | |
275 | |
276 /* Create a new section. */ | |
277 scn = elf_newscn (file->elf); | |
278 if (!scn) | |
279 fatal_error ("could not create a new ELF section: %s", elf_errmsg (-1)); | |
280 file->scn = scn; | |
281 | |
282 /* Add a string table entry and record the offset. */ | |
283 gcc_assert (file->shstrtab_stream); | |
284 sh_name = file->shstrtab_stream->total_size; | |
285 lto_output_data_stream (file->shstrtab_stream, name, strlen (name) + 1); | |
286 | |
287 /* Initialize the section header. */ | |
288 switch (cached_file_attrs.bits) | |
289 { | |
290 case 32: | |
291 init_shdr32 (scn, sh_name, type); | |
292 break; | |
293 | |
294 case 64: | |
295 init_shdr64 (scn, sh_name, type); | |
296 break; | |
297 | |
298 default: | |
299 gcc_unreachable (); | |
300 } | |
301 | |
302 first_data_block = true; | |
303 } | |
304 | |
305 | |
306 /* Begin a new ELF section named NAME in the current output file. */ | |
307 | |
308 void | |
309 lto_elf_begin_section (const char *name) | |
310 { | |
311 lto_elf_begin_section_with_type (name, SHT_PROGBITS); | |
312 } | |
313 | |
314 | |
315 /* Append DATA of length LEN to the current output section. BASE is a pointer | |
316 to the output page containing DATA. It is freed once the output file has | |
317 been written. */ | |
318 | |
319 void | |
320 lto_elf_append_data (const void *data, size_t len, void *block) | |
321 { | |
322 lto_elf_file *file; | |
323 Elf_Data *elf_data; | |
324 struct lto_char_ptr_base *base = (struct lto_char_ptr_base *) block; | |
325 | |
326 /* Grab the current output file and do some basic assertion checking. */ | |
327 file = (lto_elf_file *) lto_get_current_out_file (); | |
328 gcc_assert (file); | |
329 gcc_assert (file->scn); | |
330 | |
331 elf_data = elf_newdata (file->scn); | |
332 if (!elf_data) | |
333 fatal_error ("could not append data to ELF section: %s", elf_errmsg (-1)); | |
334 | |
335 if (first_data_block) | |
336 { | |
337 elf_data->d_align = POINTER_SIZE / BITS_PER_UNIT; | |
338 first_data_block = false; | |
339 } | |
340 else | |
341 elf_data->d_align = 1; | |
342 elf_data->d_buf = CONST_CAST (void *, data); | |
343 elf_data->d_off = 0LL; | |
344 elf_data->d_size = len; | |
345 elf_data->d_type = ELF_T_BYTE; | |
346 elf_data->d_version = EV_CURRENT; | |
347 | |
348 base->ptr = (char *)file->data; | |
349 file->data = base; | |
350 } | |
351 | |
352 | |
353 /* End the current output section. This just does some assertion checking | |
354 and sets the current output file's scn member to NULL. */ | |
355 | |
356 void | |
357 lto_elf_end_section (void) | |
358 { | |
359 lto_elf_file *file; | |
360 | |
361 /* Grab the current output file and validate some basic assertions. */ | |
362 file = (lto_elf_file *) lto_get_current_out_file (); | |
363 gcc_assert (file); | |
364 gcc_assert (file->scn); | |
365 | |
366 file->scn = NULL; | |
367 } | |
368 | |
369 | |
370 /* Validate's ELF_FILE's executable header and, if cached_file_attrs is | |
371 uninitialized, caches the architecture. */ | |
372 | |
373 #define DEFINE_VALIDATE_EHDR(BITS) \ | |
374 static bool \ | |
375 validate_ehdr##BITS (lto_elf_file *elf_file) \ | |
376 { \ | |
377 Elf##BITS##_Ehdr *elf_header; \ | |
378 \ | |
379 elf_header = elf##BITS##_getehdr (elf_file->elf); \ | |
380 if (!elf_header) \ | |
381 { \ | |
382 error ("could not read ELF header: %s", elf_errmsg (0)); \ | |
383 return false; \ | |
384 } \ | |
385 \ | |
386 if (elf_header->e_type != ET_REL) \ | |
387 { \ | |
388 error ("not a relocatable ELF object file"); \ | |
389 return false; \ | |
390 } \ | |
391 \ | |
392 if (!cached_file_attrs.initialized) \ | |
393 cached_file_attrs.elf_machine = elf_header->e_machine; \ | |
394 \ | |
395 if (cached_file_attrs.elf_machine != elf_header->e_machine) \ | |
396 { \ | |
397 error ("inconsistent file architecture detected"); \ | |
398 return false; \ | |
399 } \ | |
400 \ | |
401 return true; \ | |
402 } | |
403 | |
404 DEFINE_VALIDATE_EHDR (32) | |
405 DEFINE_VALIDATE_EHDR (64) | |
406 | |
407 | |
408 /* Validate's ELF_FILE's executable header and, if cached_file_attrs is | |
409 uninitialized, caches the results. Also records the section header string | |
410 table's section index. Returns true on success or false on failure. */ | |
411 | |
412 static bool | |
413 validate_file (lto_elf_file *elf_file) | |
414 { | |
415 const char *elf_ident; | |
416 | |
417 /* Some aspects of the libelf API are dependent on whether the | |
418 object file is a 32-bit or 64-bit file. Determine which kind of | |
419 file this is now. */ | |
420 elf_ident = elf_getident (elf_file->elf, NULL); | |
421 if (!elf_ident) | |
422 { | |
423 error ("could not read ELF identification information: %s", | |
424 elf_errmsg (0)); | |
425 return false; | |
426 | |
427 } | |
428 | |
429 if (!cached_file_attrs.initialized) | |
430 { | |
431 switch (elf_ident[EI_CLASS]) | |
432 { | |
433 case ELFCLASS32: | |
434 cached_file_attrs.bits = 32; | |
435 break; | |
436 | |
437 case ELFCLASS64: | |
438 cached_file_attrs.bits = 64; | |
439 break; | |
440 | |
441 default: | |
442 error ("unsupported ELF file class"); | |
443 return false; | |
444 } | |
445 | |
446 memcpy (cached_file_attrs.elf_ident, elf_ident, | |
447 sizeof cached_file_attrs.elf_ident); | |
448 } | |
449 | |
450 if (memcmp (elf_ident, cached_file_attrs.elf_ident, | |
451 sizeof cached_file_attrs.elf_ident)) | |
452 return false; | |
453 | |
454 /* Check that the input file is a relocatable object file with the correct | |
455 architecture. */ | |
456 switch (cached_file_attrs.bits) | |
457 { | |
458 case 32: | |
459 if (!validate_ehdr32 (elf_file)) | |
460 return false; | |
461 break; | |
462 | |
463 case 64: | |
464 if (!validate_ehdr64 (elf_file)) | |
465 return false; | |
466 break; | |
467 | |
468 default: | |
469 gcc_unreachable (); | |
470 } | |
471 | |
472 /* Read the string table used for section header names. */ | |
473 if (elf_getshdrstrndx (elf_file->elf, &elf_file->sec_strtab) == -1) | |
474 { | |
475 error ("could not locate ELF string table: %s", elf_errmsg (0)); | |
476 return false; | |
477 } | |
478 | |
479 cached_file_attrs.initialized = true; | |
480 return true; | |
481 } | |
482 | |
483 | |
484 /* Helper functions used by init_ehdr. Initialize ELF_FILE's executable | |
485 header using cached data from previously read files. */ | |
486 | |
487 #define DEFINE_INIT_EHDR(BITS) \ | |
488 static void \ | |
489 init_ehdr##BITS (lto_elf_file *elf_file) \ | |
490 { \ | |
491 Elf##BITS##_Ehdr *ehdr; \ | |
492 \ | |
493 gcc_assert (cached_file_attrs.bits); \ | |
494 \ | |
495 ehdr = elf##BITS##_newehdr (elf_file->elf); \ | |
496 if (!ehdr) \ | |
497 { \ | |
498 if (BITS == 32) \ | |
499 fatal_error ("elf32_newehdr() failed: %s", elf_errmsg (-1)); \ | |
500 else \ | |
501 fatal_error ("elf64_newehdr() failed: %s", elf_errmsg (-1)); \ | |
502 } \ | |
503 \ | |
504 memcpy (ehdr->e_ident, cached_file_attrs.elf_ident, \ | |
505 sizeof cached_file_attrs.elf_ident); \ | |
506 ehdr->e_type = ET_REL; \ | |
507 ehdr->e_version = EV_CURRENT; \ | |
508 ehdr->e_machine = cached_file_attrs.elf_machine; \ | |
509 } | |
510 | |
511 DEFINE_INIT_EHDR (32) | |
512 DEFINE_INIT_EHDR (64) | |
513 | |
514 | |
515 /* Initialize ELF_FILE's executable header using cached data from previously | |
516 read files. */ | |
517 | |
518 static void | |
519 init_ehdr (lto_elf_file *elf_file) | |
520 { | |
521 switch (cached_file_attrs.bits) | |
522 { | |
523 case 32: | |
524 init_ehdr32 (elf_file); | |
525 break; | |
526 | |
527 case 64: | |
528 init_ehdr64 (elf_file); | |
529 break; | |
530 | |
531 default: | |
532 gcc_unreachable (); | |
533 } | |
534 } | |
535 | |
536 /* Open ELF file FILENAME. If WRITABLE is true, the file is opened for write | |
537 and, if necessary, created. Otherwise, the file is opened for reading. | |
538 Returns the opened file. */ | |
539 | |
540 lto_file * | |
541 lto_elf_file_open (const char *filename, bool writable) | |
542 { | |
543 lto_elf_file *elf_file; | |
544 lto_file *result = NULL; | |
545 off_t offset; | |
546 off_t header_offset; | |
547 const char *offset_p; | |
548 char *fname; | |
549 | |
550 offset_p = strchr (filename, '@'); | |
551 if (!offset_p) | |
552 { | |
553 fname = xstrdup (filename); | |
554 offset = 0; | |
555 header_offset = 0; | |
556 } | |
557 else | |
558 { | |
559 fname = (char *) xmalloc (offset_p - filename + 1); | |
560 memcpy (fname, filename, offset_p - filename); | |
561 fname[offset_p - filename] = '\0'; | |
562 offset_p += 3; /* skip the @0x */ | |
563 offset = lto_parse_hex (offset_p); | |
564 /* elf_rand expects the offset to point to the ar header, not the | |
565 object itself. Subtract the size of the ar header (60 bytes). | |
566 We don't uses sizeof (struct ar_hd) to avoid including ar.h */ | |
567 header_offset = offset - 60; | |
568 } | |
569 | |
570 /* Set up. */ | |
571 elf_file = XCNEW (lto_elf_file); | |
572 result = (lto_file *) elf_file; | |
573 lto_file_init (result, fname, offset); | |
574 elf_file->fd = -1; | |
575 | |
576 /* Open the file. */ | |
577 elf_file->fd = open (fname, writable ? O_WRONLY|O_CREAT : O_RDONLY, 0666); | |
578 if (elf_file->fd == -1) | |
579 { | |
580 error ("could not open file %s", fname); | |
581 goto fail; | |
582 } | |
583 | |
584 /* Initialize the ELF library. */ | |
585 if (elf_version (EV_CURRENT) == EV_NONE) | |
586 { | |
587 error ("ELF library is older than that used when building GCC"); | |
588 goto fail; | |
589 } | |
590 | |
591 /* Open the ELF file descriptor. */ | |
592 elf_file->elf = elf_begin (elf_file->fd, writable ? ELF_C_WRITE : ELF_C_READ, | |
593 NULL); | |
594 if (!elf_file->elf) | |
595 { | |
596 error ("could not open ELF file: %s", elf_errmsg (0)); | |
597 goto fail; | |
598 } | |
599 | |
600 if (offset != 0) | |
601 { | |
602 Elf *e; | |
603 off_t t = elf_rand (elf_file->elf, header_offset); | |
604 if (t != header_offset) | |
605 { | |
606 error ("could not seek in archive"); | |
607 goto fail; | |
608 } | |
609 | |
610 e = elf_begin (elf_file->fd, ELF_C_READ, elf_file->elf); | |
611 if (e == NULL) | |
612 { | |
613 error("could not find archive member"); | |
614 goto fail; | |
615 } | |
616 elf_end (elf_file->elf); | |
617 elf_file->elf = e; | |
618 } | |
619 | |
620 if (writable) | |
621 { | |
622 init_ehdr (elf_file); | |
623 elf_file->shstrtab_stream = XCNEW (struct lto_output_stream); | |
624 /* Output an empty string to the section header table. This becomes the | |
625 name of the initial NULL section. */ | |
626 lto_output_1_stream (elf_file->shstrtab_stream, '\0'); | |
627 } | |
628 else | |
629 if (!validate_file (elf_file)) | |
630 goto fail; | |
631 | |
632 return result; | |
633 | |
634 fail: | |
635 if (result) | |
636 lto_elf_file_close (result); | |
637 return NULL; | |
638 } | |
639 | |
640 | |
641 /* Close ELF file FILE and clean up any associated data structures. If FILE | |
642 was opened for writing, the file's ELF data is written at this time, and | |
643 any cached data buffers are freed. */ | |
644 | |
645 void | |
646 lto_elf_file_close (lto_file *file) | |
647 { | |
648 lto_elf_file *elf_file = (lto_elf_file *) file; | |
649 struct lto_char_ptr_base *cur, *tmp; | |
650 | |
651 /* Write the ELF section header string table. */ | |
652 if (elf_file->shstrtab_stream) | |
653 { | |
654 size_t strtab; | |
655 GElf_Ehdr *ehdr_p, ehdr_buf; | |
656 lto_file *old_file = lto_set_current_out_file (file); | |
657 | |
658 lto_elf_begin_section_with_type (".shstrtab", SHT_STRTAB); | |
659 ehdr_p = gelf_getehdr (elf_file->elf, &ehdr_buf); | |
660 if (ehdr_p == NULL) | |
661 fatal_error ("gelf_getehdr() failed: %s", elf_errmsg (-1)); | |
662 strtab = elf_ndxscn (elf_file->scn); | |
663 if (strtab < SHN_LORESERVE) | |
664 ehdr_p->e_shstrndx = strtab; | |
665 else | |
666 { | |
667 GElf_Shdr *shdr_p, shdr_buf; | |
668 Elf_Scn *scn_p = elf_getscn (elf_file->elf, 0); | |
669 if (scn_p == NULL) | |
670 fatal_error ("elf_getscn() failed: %s", elf_errmsg (-1)); | |
671 shdr_p = gelf_getshdr (scn_p, &shdr_buf); | |
672 if (shdr_p == NULL) | |
673 fatal_error ("gelf_getshdr() failed: %s", elf_errmsg (-1)); | |
674 shdr_p->sh_link = strtab; | |
675 if (gelf_update_shdr (scn_p, shdr_p) == 0) | |
676 fatal_error ("gelf_update_shdr() failed: %s", elf_errmsg (-1)); | |
677 ehdr_p->e_shstrndx = SHN_XINDEX; | |
678 } | |
679 if (gelf_update_ehdr (elf_file->elf, ehdr_p) == 0) | |
680 fatal_error ("gelf_update_ehdr() failed: %s", elf_errmsg (-1)); | |
681 lto_write_stream (elf_file->shstrtab_stream); | |
682 lto_elf_end_section (); | |
683 | |
684 lto_set_current_out_file (old_file); | |
685 free (elf_file->shstrtab_stream); | |
686 | |
687 if (elf_update (elf_file->elf, ELF_C_WRITE) < 0) | |
688 fatal_error ("elf_update() failed: %s", elf_errmsg (-1)); | |
689 } | |
690 | |
691 if (elf_file->elf) | |
692 elf_end (elf_file->elf); | |
693 if (elf_file->fd != -1) | |
694 close (elf_file->fd); | |
695 | |
696 /* Free any ELF data buffers. */ | |
697 cur = elf_file->data; | |
698 while (cur) | |
699 { | |
700 tmp = cur; | |
701 cur = (struct lto_char_ptr_base *) cur->ptr; | |
702 free (tmp); | |
703 } | |
704 | |
705 free (file); | |
706 } | |
707 | |
708 | |
709 /* The current output file. */ | |
710 static lto_file *current_out_file; | |
711 | |
712 | |
713 /* Sets the current output file to FILE. Returns the old output file or | |
714 NULL. */ | |
715 | |
716 lto_file * | |
717 lto_set_current_out_file (lto_file *file) | |
718 { | |
719 lto_file *old_file = current_out_file; | |
720 current_out_file = file; | |
721 return old_file; | |
722 } | |
723 | |
724 | |
725 /* Returns the current output file. */ | |
726 | |
727 lto_file * | |
728 lto_get_current_out_file (void) | |
729 { | |
730 return current_out_file; | |
731 } |