d5f4cc5ad490636f6564b1156098de88f9bf090f
[deliverable/binutils-gdb.git] / bfd / elf-eh-frame.c
1 /* .eh_frame section optimization.
2 Copyright 2001, 2002 Free Software Foundation, Inc.
3 Written by Jakub Jelinek <jakub@redhat.com>.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21 #include "bfd.h"
22 #include "sysdep.h"
23 #include "libbfd.h"
24 #include "elf-bfd.h"
25 #include "elf/dwarf2.h"
26
27 #define EH_FRAME_HDR_SIZE 8
28
29 struct cie_header
30 {
31 unsigned int length;
32 unsigned int id;
33 };
34
35 struct cie
36 {
37 struct cie_header hdr;
38 unsigned char version;
39 unsigned char augmentation[20];
40 unsigned int code_align;
41 int data_align;
42 unsigned int ra_column;
43 unsigned int augmentation_size;
44 struct elf_link_hash_entry *personality;
45 unsigned char per_encoding;
46 unsigned char lsda_encoding;
47 unsigned char fde_encoding;
48 unsigned char initial_insn_length;
49 unsigned char make_relative;
50 unsigned char make_lsda_relative;
51 unsigned char initial_instructions[50];
52 };
53
54 struct eh_cie_fde
55 {
56 unsigned int offset;
57 unsigned int size;
58 asection *sec;
59 unsigned int new_offset;
60 unsigned char fde_encoding;
61 unsigned char lsda_encoding;
62 unsigned char lsda_offset;
63 unsigned char cie : 1;
64 unsigned char removed : 1;
65 unsigned char make_relative : 1;
66 unsigned char make_lsda_relative : 1;
67 unsigned char per_encoding_relative : 1;
68 };
69
70 struct eh_frame_sec_info
71 {
72 unsigned int count;
73 unsigned int alloced;
74 struct eh_cie_fde entry[1];
75 };
76
77 struct eh_frame_array_ent
78 {
79 bfd_vma initial_loc;
80 bfd_vma fde;
81 };
82
83 struct eh_frame_hdr_info
84 {
85 struct cie last_cie;
86 asection *last_cie_sec;
87 unsigned int last_cie_offset;
88 unsigned int fde_count, array_count;
89 struct eh_frame_array_ent *array;
90 /* TRUE if .eh_frame_hdr should contain the sorted search table.
91 We build it if we successfully read all .eh_frame input sections
92 and recognize them. */
93 boolean table;
94 boolean strip;
95 };
96
97 static bfd_vma read_unsigned_leb128
98 PARAMS ((bfd *, char *, unsigned int *));
99 static bfd_signed_vma read_signed_leb128
100 PARAMS ((bfd *, char *, unsigned int *));
101 static int get_DW_EH_PE_width
102 PARAMS ((int, int));
103 static bfd_vma read_value
104 PARAMS ((bfd *, bfd_byte *, int));
105 static void write_value
106 PARAMS ((bfd *, bfd_byte *, bfd_vma, int));
107 static int cie_compare
108 PARAMS ((struct cie *, struct cie *));
109 static int vma_compare
110 PARAMS ((const PTR a, const PTR b));
111
112 /* Helper function for reading uleb128 encoded data. */
113
114 static bfd_vma
115 read_unsigned_leb128 (abfd, buf, bytes_read_ptr)
116 bfd *abfd ATTRIBUTE_UNUSED;
117 char *buf;
118 unsigned int *bytes_read_ptr;
119 {
120 bfd_vma result;
121 unsigned int num_read;
122 int shift;
123 unsigned char byte;
124
125 result = 0;
126 shift = 0;
127 num_read = 0;
128 do
129 {
130 byte = bfd_get_8 (abfd, (bfd_byte *) buf);
131 buf ++;
132 num_read ++;
133 result |= (((bfd_vma) byte & 0x7f) << shift);
134 shift += 7;
135 }
136 while (byte & 0x80);
137 * bytes_read_ptr = num_read;
138 return result;
139 }
140
141 /* Helper function for reading sleb128 encoded data. */
142
143 static bfd_signed_vma
144 read_signed_leb128 (abfd, buf, bytes_read_ptr)
145 bfd *abfd ATTRIBUTE_UNUSED;
146 char *buf;
147 unsigned int * bytes_read_ptr;
148 {
149 bfd_vma result;
150 int shift;
151 int num_read;
152 unsigned char byte;
153
154 result = 0;
155 shift = 0;
156 num_read = 0;
157 do
158 {
159 byte = bfd_get_8 (abfd, (bfd_byte *) buf);
160 buf ++;
161 num_read ++;
162 result |= (((bfd_vma) byte & 0x7f) << shift);
163 shift += 7;
164 }
165 while (byte & 0x80);
166 if (byte & 0x40)
167 result |= (((bfd_vma) -1) << (shift - 7)) << 7;
168 * bytes_read_ptr = num_read;
169 return result;
170 }
171
172 #define read_uleb128(VAR, BUF) \
173 do \
174 { \
175 (VAR) = read_unsigned_leb128 (abfd, buf, &leb128_tmp); \
176 (BUF) += leb128_tmp; \
177 } \
178 while (0)
179
180 #define read_sleb128(VAR, BUF) \
181 do \
182 { \
183 (VAR) = read_signed_leb128 (abfd, buf, &leb128_tmp); \
184 (BUF) += leb128_tmp; \
185 } \
186 while (0)
187
188 /* Return 0 if either encoding is variable width, or not yet known to bfd. */
189
190 static
191 int get_DW_EH_PE_width (encoding, ptr_size)
192 int encoding, ptr_size;
193 {
194 /* DW_EH_PE_ values of 0x60 and 0x70 weren't defined at the time .eh_frame
195 was added to bfd. */
196 if ((encoding & 0x60) == 0x60)
197 return 0;
198
199 switch (encoding & 7)
200 {
201 case DW_EH_PE_udata2: return 2;
202 case DW_EH_PE_udata4: return 4;
203 case DW_EH_PE_udata8: return 8;
204 case DW_EH_PE_absptr: return ptr_size;
205 default:
206 break;
207 }
208
209 return 0;
210 }
211
212 /* Read a width sized value from memory. */
213
214 static bfd_vma
215 read_value (abfd, buf, width)
216 bfd *abfd;
217 bfd_byte *buf;
218 int width;
219 {
220 bfd_vma value;
221
222 switch (width)
223 {
224 case 2: value = bfd_get_16 (abfd, buf); break;
225 case 4: value = bfd_get_32 (abfd, buf); break;
226 case 8: value = bfd_get_64 (abfd, buf); break;
227 default: BFD_FAIL (); return 0;
228 }
229
230 return value;
231 }
232
233 /* Store a width sized value to memory. */
234
235 static void
236 write_value (abfd, buf, value, width)
237 bfd *abfd;
238 bfd_byte *buf;
239 bfd_vma value;
240 int width;
241 {
242 switch (width)
243 {
244 case 2: bfd_put_16 (abfd, value, buf); break;
245 case 4: bfd_put_32 (abfd, value, buf); break;
246 case 8: bfd_put_64 (abfd, value, buf); break;
247 default: BFD_FAIL ();
248 }
249 }
250
251 /* Return zero if C1 and C2 CIEs can be merged. */
252
253 static
254 int cie_compare (c1, c2)
255 struct cie *c1, *c2;
256 {
257 if (c1->hdr.length == c2->hdr.length
258 && c1->version == c2->version
259 && strcmp (c1->augmentation, c2->augmentation) == 0
260 && strcmp (c1->augmentation, "eh") != 0
261 && c1->code_align == c2->code_align
262 && c1->data_align == c2->data_align
263 && c1->ra_column == c2->ra_column
264 && c1->augmentation_size == c2->augmentation_size
265 && c1->personality == c2->personality
266 && c1->per_encoding == c2->per_encoding
267 && c1->lsda_encoding == c2->lsda_encoding
268 && c1->fde_encoding == c2->fde_encoding
269 && (c1->initial_insn_length
270 == c2->initial_insn_length)
271 && memcmp (c1->initial_instructions,
272 c2->initial_instructions,
273 c1->initial_insn_length) == 0)
274 return 0;
275
276 return 1;
277 }
278
279 /* This function is called for each input file before the .eh_frame
280 section is relocated. It discards duplicate CIEs and FDEs for discarded
281 functions. The function returns true iff any entries have been
282 deleted. */
283
284 boolean
285 _bfd_elf_discard_section_eh_frame (abfd, info, sec, ehdrsec,
286 reloc_symbol_deleted_p, cookie)
287 bfd *abfd;
288 struct bfd_link_info *info;
289 asection *sec, *ehdrsec;
290 boolean (*reloc_symbol_deleted_p) PARAMS ((bfd_vma, PTR));
291 struct elf_reloc_cookie *cookie;
292 {
293 bfd_byte *ehbuf = NULL, *buf;
294 bfd_byte *last_cie, *last_fde;
295 struct cie_header hdr;
296 struct cie cie;
297 struct eh_frame_hdr_info *hdr_info;
298 struct eh_frame_sec_info *sec_info = NULL;
299 unsigned int leb128_tmp;
300 unsigned int cie_usage_count, last_cie_ndx, i, offset;
301 unsigned int make_relative, make_lsda_relative;
302 bfd_size_type new_size;
303 unsigned int ptr_size;
304
305 if (sec->_raw_size == 0)
306 {
307 /* This file does not contain .eh_frame information. */
308 return false;
309 }
310
311 if ((sec->output_section != NULL
312 && bfd_is_abs_section (sec->output_section)))
313 {
314 /* At least one of the sections is being discarded from the
315 link, so we should just ignore them. */
316 return false;
317 }
318
319 BFD_ASSERT (elf_section_data (ehdrsec)->sec_info_type
320 == ELF_INFO_TYPE_EH_FRAME_HDR);
321 hdr_info = (struct eh_frame_hdr_info *)
322 elf_section_data (ehdrsec)->sec_info;
323
324 /* Read the frame unwind information from abfd. */
325
326 ehbuf = (bfd_byte *) bfd_malloc (sec->_raw_size);
327 if (ehbuf == NULL)
328 goto free_no_table;
329
330 if (! bfd_get_section_contents (abfd, sec, ehbuf, (bfd_vma) 0,
331 sec->_raw_size))
332 goto free_no_table;
333
334 if (sec->_raw_size >= 4
335 && bfd_get_32 (abfd, ehbuf) == 0
336 && cookie->rel == cookie->relend)
337 {
338 /* Empty .eh_frame section. */
339 free (ehbuf);
340 return false;
341 }
342
343 /* If .eh_frame section size doesn't fit into int, we cannot handle
344 it (it would need to use 64-bit .eh_frame format anyway). */
345 if (sec->_raw_size != (unsigned int) sec->_raw_size)
346 goto free_no_table;
347
348 ptr_size = (elf_elfheader (abfd)->e_ident[EI_CLASS]
349 == ELFCLASS64) ? 8 : 4;
350 buf = ehbuf;
351 last_cie = NULL;
352 last_cie_ndx = 0;
353 memset (&cie, 0, sizeof (cie));
354 cie_usage_count = 0;
355 new_size = sec->_raw_size;
356 make_relative = hdr_info->last_cie.make_relative;
357 make_lsda_relative = hdr_info->last_cie.make_lsda_relative;
358 sec_info = bfd_zmalloc (sizeof (struct eh_frame_sec_info)
359 + 99 * sizeof (struct eh_cie_fde));
360 if (sec_info == NULL)
361 goto free_no_table;
362 sec_info->alloced = 100;
363
364 #define ENSURE_NO_RELOCS(buf) \
365 if (cookie->rel < cookie->relend \
366 && (cookie->rel->r_offset \
367 < (bfd_size_type) ((buf) - ehbuf))) \
368 goto free_no_table
369
370 #define SKIP_RELOCS(buf) \
371 while (cookie->rel < cookie->relend \
372 && (cookie->rel->r_offset \
373 < (bfd_size_type) ((buf) - ehbuf))) \
374 cookie->rel++
375
376 #define GET_RELOC(buf) \
377 ((cookie->rel < cookie->relend \
378 && (cookie->rel->r_offset \
379 == (bfd_size_type) ((buf) - ehbuf))) \
380 ? cookie->rel : NULL)
381
382 for (;;)
383 {
384 unsigned char *aug;
385
386 if (sec_info->count == sec_info->alloced)
387 {
388 sec_info = bfd_realloc (sec_info,
389 sizeof (struct eh_frame_sec_info)
390 + (sec_info->alloced + 99)
391 * sizeof (struct eh_cie_fde));
392 if (sec_info == NULL)
393 goto free_no_table;
394
395 memset (&sec_info->entry[sec_info->alloced], 0,
396 100 * sizeof (struct eh_cie_fde));
397 sec_info->alloced += 100;
398 }
399
400 last_fde = buf;
401 /* If we are at the end of the section, we still need to decide
402 on whether to output or discard last encountered CIE (if any). */
403 if ((bfd_size_type) (buf - ehbuf) == sec->_raw_size)
404 hdr.id = (unsigned int) -1;
405 else
406 {
407 if ((bfd_size_type) (buf + 4 - ehbuf) > sec->_raw_size)
408 /* No space for CIE/FDE header length. */
409 goto free_no_table;
410
411 hdr.length = bfd_get_32 (abfd, buf);
412 if (hdr.length == 0xffffffff)
413 /* 64-bit .eh_frame is not supported. */
414 goto free_no_table;
415 buf += 4;
416 if ((bfd_size_type) (buf - ehbuf) + hdr.length > sec->_raw_size)
417 /* CIE/FDE not contained fully in this .eh_frame input section. */
418 goto free_no_table;
419
420 sec_info->entry[sec_info->count].offset = last_fde - ehbuf;
421 sec_info->entry[sec_info->count].size = 4 + hdr.length;
422
423 if (hdr.length == 0)
424 {
425 /* CIE with length 0 must be only the last in the section. */
426 if ((bfd_size_type) (buf - ehbuf) < sec->_raw_size)
427 goto free_no_table;
428 ENSURE_NO_RELOCS (buf);
429 sec_info->count++;
430 /* Now just finish last encountered CIE processing and break
431 the loop. */
432 hdr.id = (unsigned int) -1;
433 }
434 else
435 {
436 hdr.id = bfd_get_32 (abfd, buf);
437 buf += 4;
438 if (hdr.id == (unsigned int) -1)
439 goto free_no_table;
440 }
441 }
442
443 if (hdr.id == 0 || hdr.id == (unsigned int) -1)
444 {
445 unsigned int initial_insn_length;
446
447 /* CIE */
448 if (last_cie != NULL)
449 {
450 /* Now check if this CIE is identical to last CIE, in which case
451 we can remove it, provided we adjust all FDEs.
452 Also, it can be removed if we have removed all FDEs using
453 that. */
454 if (cie_compare (&cie, &hdr_info->last_cie) == 0
455 || cie_usage_count == 0)
456 {
457 new_size -= cie.hdr.length + 4;
458 sec_info->entry[last_cie_ndx].removed = 1;
459 sec_info->entry[last_cie_ndx].sec = hdr_info->last_cie_sec;
460 sec_info->entry[last_cie_ndx].new_offset
461 = hdr_info->last_cie_offset;
462 }
463 else
464 {
465 hdr_info->last_cie = cie;
466 hdr_info->last_cie_sec = sec;
467 hdr_info->last_cie_offset = last_cie - ehbuf;
468 sec_info->entry[last_cie_ndx].make_relative
469 = cie.make_relative;
470 sec_info->entry[last_cie_ndx].make_lsda_relative
471 = cie.make_lsda_relative;
472 sec_info->entry[last_cie_ndx].per_encoding_relative
473 = (cie.per_encoding & 0x70) == DW_EH_PE_pcrel;
474 }
475 }
476
477 if (hdr.id == (unsigned int) -1)
478 break;
479
480 last_cie_ndx = sec_info->count;
481 sec_info->entry[sec_info->count].cie = 1;
482
483 cie_usage_count = 0;
484 memset (&cie, 0, sizeof (cie));
485 cie.hdr = hdr;
486 cie.version = *buf++;
487
488 /* Cannot handle unknown versions. */
489 if (cie.version != 1)
490 goto free_no_table;
491 if (strlen (buf) > sizeof (cie.augmentation) - 1)
492 goto free_no_table;
493
494 strcpy (cie.augmentation, buf);
495 buf = strchr (buf, '\0') + 1;
496 ENSURE_NO_RELOCS (buf);
497 if (buf[0] == 'e' && buf[1] == 'h')
498 {
499 /* GCC < 3.0 .eh_frame CIE */
500 /* We cannot merge "eh" CIEs because __EXCEPTION_TABLE__
501 is private to each CIE, so we don't need it for anything.
502 Just skip it. */
503 buf += ptr_size;
504 SKIP_RELOCS (buf);
505 }
506 read_uleb128 (cie.code_align, buf);
507 read_sleb128 (cie.data_align, buf);
508 /* Note - in DWARF2 the return address column is an unsigned byte.
509 In DWARF3 it is a ULEB128. We are following DWARF3. For most
510 ports this will not matter as the value will be less than 128.
511 For the others (eg FRV, SH, MMIX, IA64) they need a fixed GCC
512 which conforms to the DWARF3 standard. */
513 read_uleb128 (cie.ra_column, buf);
514 ENSURE_NO_RELOCS (buf);
515 cie.lsda_encoding = DW_EH_PE_omit;
516 cie.fde_encoding = DW_EH_PE_omit;
517 cie.per_encoding = DW_EH_PE_omit;
518 aug = cie.augmentation;
519 if (aug[0] != 'e' || aug[1] != 'h')
520 {
521 if (*aug == 'z')
522 {
523 aug++;
524 read_uleb128 (cie.augmentation_size, buf);
525 ENSURE_NO_RELOCS (buf);
526 }
527
528 while (*aug != '\0')
529 switch (*aug++)
530 {
531 case 'L':
532 cie.lsda_encoding = *buf++;
533 ENSURE_NO_RELOCS (buf);
534 if (get_DW_EH_PE_width (cie.lsda_encoding, ptr_size) == 0)
535 goto free_no_table;
536 break;
537 case 'R':
538 cie.fde_encoding = *buf++;
539 ENSURE_NO_RELOCS (buf);
540 if (get_DW_EH_PE_width (cie.fde_encoding, ptr_size) == 0)
541 goto free_no_table;
542 break;
543 case 'P':
544 {
545 int per_width;
546
547 cie.per_encoding = *buf++;
548 per_width = get_DW_EH_PE_width (cie.per_encoding,
549 ptr_size);
550 if (per_width == 0)
551 goto free_no_table;
552 if ((cie.per_encoding & 0xf0) == DW_EH_PE_aligned)
553 buf = (ehbuf
554 + ((buf - ehbuf + per_width - 1)
555 & ~((bfd_size_type) per_width - 1)));
556 ENSURE_NO_RELOCS (buf);
557 /* Ensure we have a reloc here, against
558 a global symbol. */
559 if (GET_RELOC (buf) != NULL)
560 {
561 unsigned long r_symndx;
562
563 #ifdef BFD64
564 if (ptr_size == 8)
565 r_symndx = ELF64_R_SYM (cookie->rel->r_info);
566 else
567 #endif
568 r_symndx = ELF32_R_SYM (cookie->rel->r_info);
569 if (r_symndx >= cookie->locsymcount)
570 {
571 struct elf_link_hash_entry *h;
572
573 r_symndx -= cookie->extsymoff;
574 h = cookie->sym_hashes[r_symndx];
575
576 while (h->root.type == bfd_link_hash_indirect
577 || h->root.type == bfd_link_hash_warning)
578 h = (struct elf_link_hash_entry *)
579 h->root.u.i.link;
580
581 cie.personality = h;
582 }
583 cookie->rel++;
584 }
585 buf += per_width;
586 }
587 break;
588 default:
589 /* Unrecognized augmentation. Better bail out. */
590 goto free_no_table;
591 }
592 }
593
594 /* For shared libraries, try to get rid of as many RELATIVE relocs
595 as possible. */
596 if (info->shared
597 && (cie.fde_encoding & 0xf0) == DW_EH_PE_absptr)
598 cie.make_relative = 1;
599
600 if (info->shared
601 && (cie.lsda_encoding & 0xf0) == DW_EH_PE_absptr)
602 cie.make_lsda_relative = 1;
603
604 /* If FDE encoding was not specified, it defaults to
605 DW_EH_absptr. */
606 if (cie.fde_encoding == DW_EH_PE_omit)
607 cie.fde_encoding = DW_EH_PE_absptr;
608
609 initial_insn_length = cie.hdr.length - (buf - last_fde - 4);
610 if (initial_insn_length <= 50)
611 {
612 cie.initial_insn_length = initial_insn_length;
613 memcpy (cie.initial_instructions, buf, initial_insn_length);
614 }
615 buf += initial_insn_length;
616 ENSURE_NO_RELOCS (buf);
617 last_cie = last_fde;
618 }
619 else
620 {
621 /* Ensure this FDE uses the last CIE encountered. */
622 if (last_cie == NULL
623 || hdr.id != (unsigned int) (buf - 4 - last_cie))
624 goto free_no_table;
625
626 ENSURE_NO_RELOCS (buf);
627 if (GET_RELOC (buf) == NULL)
628 /* This should not happen. */
629 goto free_no_table;
630 if ((*reloc_symbol_deleted_p) (buf - ehbuf, cookie))
631 {
632 /* This is a FDE against discarded section, it should
633 be deleted. */
634 new_size -= hdr.length + 4;
635 sec_info->entry[sec_info->count].removed = 1;
636 }
637 else
638 {
639 if (info->shared
640 && (((cie.fde_encoding & 0xf0) == DW_EH_PE_absptr
641 && cie.make_relative == 0)
642 || (cie.fde_encoding & 0xf0) == DW_EH_PE_aligned))
643 {
644 /* If shared library uses absolute pointers
645 which we cannot turn into PC relative,
646 don't create the binary search table,
647 since it is affected by runtime relocations. */
648 hdr_info->table = false;
649 }
650 cie_usage_count++;
651 hdr_info->fde_count++;
652 }
653 if (cie.lsda_encoding != DW_EH_PE_omit)
654 {
655 unsigned int dummy;
656
657 aug = buf;
658 buf += 2 * get_DW_EH_PE_width (cie.fde_encoding, ptr_size);
659 if (cie.augmentation[0] == 'z')
660 read_uleb128 (dummy, buf);
661 /* If some new augmentation data is added before LSDA
662 in FDE augmentation area, this need to be adjusted. */
663 sec_info->entry[sec_info->count].lsda_offset = (buf - aug);
664 }
665 buf = last_fde + 4 + hdr.length;
666 SKIP_RELOCS (buf);
667 }
668
669 sec_info->entry[sec_info->count].fde_encoding = cie.fde_encoding;
670 sec_info->entry[sec_info->count].lsda_encoding = cie.lsda_encoding;
671 sec_info->count++;
672 }
673
674 elf_section_data (sec)->sec_info = sec_info;
675 elf_section_data (sec)->sec_info_type = ELF_INFO_TYPE_EH_FRAME;
676
677 /* Ok, now we can assign new offsets. */
678 offset = 0;
679 last_cie_ndx = 0;
680 for (i = 0; i < sec_info->count; i++)
681 {
682 if (! sec_info->entry[i].removed)
683 {
684 sec_info->entry[i].new_offset = offset;
685 offset += sec_info->entry[i].size;
686 if (sec_info->entry[i].cie)
687 {
688 last_cie_ndx = i;
689 make_relative = sec_info->entry[i].make_relative;
690 make_lsda_relative = sec_info->entry[i].make_lsda_relative;
691 }
692 else
693 {
694 sec_info->entry[i].make_relative = make_relative;
695 sec_info->entry[i].make_lsda_relative = make_lsda_relative;
696 sec_info->entry[i].per_encoding_relative = 0;
697 }
698 }
699 else if (sec_info->entry[i].cie && sec_info->entry[i].sec == sec)
700 {
701 /* Need to adjust new_offset too. */
702 BFD_ASSERT (sec_info->entry[last_cie_ndx].offset
703 == sec_info->entry[i].new_offset);
704 sec_info->entry[i].new_offset
705 = sec_info->entry[last_cie_ndx].new_offset;
706 }
707 }
708 if (hdr_info->last_cie_sec == sec)
709 {
710 BFD_ASSERT (sec_info->entry[last_cie_ndx].offset
711 == hdr_info->last_cie_offset);
712 hdr_info->last_cie_offset = sec_info->entry[last_cie_ndx].new_offset;
713 }
714
715 /* FIXME: Currently it is not possible to shrink sections to zero size at
716 this point, so build a fake minimal CIE. */
717 if (new_size == 0)
718 new_size = 16;
719
720 /* Shrink the sec as needed. */
721 sec->_cooked_size = new_size;
722 if (sec->_cooked_size == 0)
723 sec->flags |= SEC_EXCLUDE;
724
725 free (ehbuf);
726 return new_size != sec->_raw_size;
727
728 free_no_table:
729 if (ehbuf)
730 free (ehbuf);
731 if (sec_info)
732 free (sec_info);
733 hdr_info->table = false;
734 hdr_info->last_cie.hdr.length = 0;
735 return false;
736 }
737
738 /* This function is called for .eh_frame_hdr section after
739 _bfd_elf_discard_section_eh_frame has been called on all .eh_frame
740 input sections. It finalizes the size of .eh_frame_hdr section. */
741
742 boolean
743 _bfd_elf_discard_section_eh_frame_hdr (abfd, info, sec)
744 bfd *abfd;
745 struct bfd_link_info *info;
746 asection *sec;
747 {
748 struct eh_frame_hdr_info *hdr_info;
749
750 if ((elf_section_data (sec)->sec_info_type
751 != ELF_INFO_TYPE_EH_FRAME_HDR)
752 || ! info->eh_frame_hdr)
753 {
754 _bfd_strip_section_from_output (info, sec);
755 return false;
756 }
757
758 hdr_info = (struct eh_frame_hdr_info *)
759 elf_section_data (sec)->sec_info;
760 if (hdr_info->strip)
761 return false;
762 sec->_cooked_size = EH_FRAME_HDR_SIZE;
763 if (hdr_info->table)
764 sec->_cooked_size += 4 + hdr_info->fde_count * 8;
765
766 /* Request program headers to be recalculated. */
767 elf_tdata (abfd)->program_header_size = 0;
768 elf_tdata (abfd)->eh_frame_hdr = true;
769 return true;
770 }
771
772 /* This function is called from size_dynamic_sections.
773 It needs to decide whether .eh_frame_hdr should be output or not,
774 because later on it is too late for calling _bfd_strip_section_from_output,
775 since dynamic symbol table has been sized. */
776
777 boolean
778 _bfd_elf_maybe_strip_eh_frame_hdr (info)
779 struct bfd_link_info *info;
780 {
781 asection *sec, *o;
782 bfd *abfd;
783 struct eh_frame_hdr_info *hdr_info;
784
785 sec = bfd_get_section_by_name (elf_hash_table (info)->dynobj, ".eh_frame_hdr");
786 if (sec == NULL || bfd_is_abs_section (sec->output_section))
787 return true;
788
789 hdr_info
790 = bfd_zmalloc (sizeof (struct eh_frame_hdr_info));
791 if (hdr_info == NULL)
792 return false;
793
794 elf_section_data (sec)->sec_info = hdr_info;
795 elf_section_data (sec)->sec_info_type = ELF_INFO_TYPE_EH_FRAME_HDR;
796
797 abfd = NULL;
798 if (info->eh_frame_hdr)
799 for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
800 {
801 /* Count only sections which have at least a single CIE or FDE.
802 There cannot be any CIE or FDE <= 8 bytes. */
803 o = bfd_get_section_by_name (abfd, ".eh_frame");
804 if (o && o->_raw_size > 8 && !bfd_is_abs_section (o->output_section))
805 break;
806 }
807
808 if (abfd == NULL)
809 {
810 _bfd_strip_section_from_output (info, sec);
811 hdr_info->strip = true;
812 }
813 else
814 hdr_info->table = true;
815 return true;
816 }
817
818 /* Adjust an address in the .eh_frame section. Given OFFSET within
819 SEC, this returns the new offset in the adjusted .eh_frame section,
820 or -1 if the address refers to a CIE/FDE which has been removed
821 or to offset with dynamic relocation which is no longer needed. */
822
823 bfd_vma
824 _bfd_elf_eh_frame_section_offset (output_bfd, sec, offset)
825 bfd *output_bfd ATTRIBUTE_UNUSED;
826 asection *sec;
827 bfd_vma offset;
828 {
829 struct eh_frame_sec_info *sec_info;
830 unsigned int lo, hi, mid;
831
832 if (elf_section_data (sec)->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
833 return offset;
834 sec_info = (struct eh_frame_sec_info *)
835 elf_section_data (sec)->sec_info;
836
837 if (offset >= sec->_raw_size)
838 return offset - (sec->_cooked_size - sec->_raw_size);
839
840 lo = 0;
841 hi = sec_info->count;
842 mid = 0;
843 while (lo < hi)
844 {
845 mid = (lo + hi) / 2;
846 if (offset < sec_info->entry[mid].offset)
847 hi = mid;
848 else if (offset
849 >= sec_info->entry[mid].offset + sec_info->entry[mid].size)
850 lo = mid + 1;
851 else
852 break;
853 }
854
855 BFD_ASSERT (lo < hi);
856
857 /* FDE or CIE was removed. */
858 if (sec_info->entry[mid].removed)
859 return (bfd_vma) -1;
860
861 /* If converting to DW_EH_PE_pcrel, there will be no need for run-time
862 relocation against FDE's initial_location field. */
863 if (sec_info->entry[mid].make_relative
864 && ! sec_info->entry[mid].cie
865 && offset == sec_info->entry[mid].offset + 8)
866 return (bfd_vma) -2;
867
868 /* If converting LSDA pointers to DW_EH_PE_pcrel, there will be no need
869 for run-time relocation against LSDA field. */
870 if (sec_info->entry[mid].make_lsda_relative
871 && ! sec_info->entry[mid].cie
872 && (offset
873 == (sec_info->entry[mid].offset + 8
874 + sec_info->entry[mid].lsda_offset)))
875 return (bfd_vma) -2;
876
877 return (offset + sec_info->entry[mid].new_offset
878 - sec_info->entry[mid].offset);
879 }
880
881 /* Write out .eh_frame section. This is called with the relocated
882 contents. */
883
884 boolean
885 _bfd_elf_write_section_eh_frame (abfd, sec, ehdrsec, contents)
886 bfd *abfd;
887 asection *sec, *ehdrsec;
888 bfd_byte *contents;
889 {
890 struct eh_frame_sec_info *sec_info;
891 struct eh_frame_hdr_info *hdr_info;
892 unsigned int i;
893 bfd_byte *p, *buf;
894 unsigned int leb128_tmp;
895 unsigned int cie_offset = 0;
896 unsigned int ptr_size;
897
898 ptr_size = (elf_elfheader (sec->owner)->e_ident[EI_CLASS]
899 == ELFCLASS64) ? 8 : 4;
900
901 if (elf_section_data (sec)->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
902 return bfd_set_section_contents (abfd, sec->output_section,
903 contents,
904 (file_ptr) sec->output_offset,
905 sec->_raw_size);
906 sec_info = (struct eh_frame_sec_info *)
907 elf_section_data (sec)->sec_info;
908 hdr_info = NULL;
909 if (ehdrsec
910 && (elf_section_data (ehdrsec)->sec_info_type
911 == ELF_INFO_TYPE_EH_FRAME_HDR))
912 {
913 hdr_info = (struct eh_frame_hdr_info *)
914 elf_section_data (ehdrsec)->sec_info;
915 if (hdr_info->table && hdr_info->array == NULL)
916 hdr_info->array
917 = bfd_malloc (hdr_info->fde_count * sizeof(*hdr_info->array));
918 if (hdr_info->array == NULL)
919 hdr_info = NULL;
920 }
921
922 p = contents;
923 for (i = 0; i < sec_info->count; ++i)
924 {
925 if (sec_info->entry[i].removed)
926 {
927 if (sec_info->entry[i].cie)
928 {
929 /* If CIE is removed due to no remaining FDEs referencing it
930 and there were no CIEs kept before it, sec_info->entry[i].sec
931 will be zero. */
932 if (sec_info->entry[i].sec == NULL)
933 cie_offset = 0;
934 else
935 {
936 cie_offset = sec_info->entry[i].new_offset;
937 cie_offset += (sec_info->entry[i].sec->output_section->vma
938 + sec_info->entry[i].sec->output_offset
939 - sec->output_section->vma
940 - sec->output_offset);
941 }
942 }
943 continue;
944 }
945
946 if (sec_info->entry[i].cie)
947 {
948 /* CIE */
949 cie_offset = sec_info->entry[i].new_offset;
950 if (sec_info->entry[i].make_relative
951 || sec_info->entry[i].make_lsda_relative
952 || sec_info->entry[i].per_encoding_relative)
953 {
954 unsigned char *aug;
955 unsigned int action;
956 unsigned int dummy, per_width, per_encoding;
957
958 /* Need to find 'R' or 'L' augmentation's argument and modify
959 DW_EH_PE_* value. */
960 action = (sec_info->entry[i].make_relative ? 1 : 0)
961 | (sec_info->entry[i].make_lsda_relative ? 2 : 0)
962 | (sec_info->entry[i].per_encoding_relative ? 4 : 0);
963 buf = contents + sec_info->entry[i].offset;
964 /* Skip length, id and version. */
965 buf += 9;
966 aug = buf;
967 buf = strchr (buf, '\0') + 1;
968 read_uleb128 (dummy, buf);
969 read_sleb128 (dummy, buf);
970 read_uleb128 (dummy, buf);
971 if (*aug == 'z')
972 {
973 read_uleb128 (dummy, buf);
974 aug++;
975 }
976
977 while (action)
978 switch (*aug++)
979 {
980 case 'L':
981 if (action & 2)
982 {
983 BFD_ASSERT (*buf == sec_info->entry[i].lsda_encoding);
984 *buf |= DW_EH_PE_pcrel;
985 action &= ~2;
986 }
987 buf++;
988 break;
989 case 'P':
990 per_encoding = *buf++;
991 per_width = get_DW_EH_PE_width (per_encoding,
992 ptr_size);
993 BFD_ASSERT (per_width != 0);
994 BFD_ASSERT (((per_encoding & 0x70) == DW_EH_PE_pcrel)
995 == sec_info->entry[i].per_encoding_relative);
996 if ((per_encoding & 0xf0) == DW_EH_PE_aligned)
997 buf = (contents
998 + ((buf - contents + per_width - 1)
999 & ~((bfd_size_type) per_width - 1)));
1000 if (action & 4)
1001 {
1002 bfd_vma value;
1003
1004 value = read_value (abfd, buf, per_width);
1005 value += (sec_info->entry[i].offset
1006 - sec_info->entry[i].new_offset);
1007 write_value (abfd, buf, value, per_width);
1008 action &= ~4;
1009 }
1010 buf += per_width;
1011 break;
1012 case 'R':
1013 if (action & 1)
1014 {
1015 BFD_ASSERT (*buf == sec_info->entry[i].fde_encoding);
1016 *buf |= DW_EH_PE_pcrel;
1017 action &= ~1;
1018 }
1019 buf++;
1020 break;
1021 default:
1022 BFD_FAIL ();
1023 }
1024 }
1025 }
1026 else if (sec_info->entry[i].size > 4)
1027 {
1028 /* FDE */
1029 bfd_vma value = 0, address;
1030 unsigned int width;
1031
1032 buf = contents + sec_info->entry[i].offset;
1033 /* Skip length. */
1034 buf += 4;
1035 bfd_put_32 (abfd,
1036 sec_info->entry[i].new_offset + 4 - cie_offset, buf);
1037 buf += 4;
1038 width = get_DW_EH_PE_width (sec_info->entry[i].fde_encoding,
1039 ptr_size);
1040 address = value = read_value (abfd, buf, width);
1041 if (value)
1042 {
1043 switch (sec_info->entry[i].fde_encoding & 0xf0)
1044 {
1045 case DW_EH_PE_indirect:
1046 case DW_EH_PE_textrel:
1047 BFD_ASSERT (hdr_info == NULL);
1048 break;
1049 case DW_EH_PE_datarel:
1050 {
1051 asection *got = bfd_get_section_by_name (abfd, ".got");
1052
1053 BFD_ASSERT (got != NULL);
1054 address += got->vma;
1055 }
1056 break;
1057 case DW_EH_PE_pcrel:
1058 value += (sec_info->entry[i].offset
1059 - sec_info->entry[i].new_offset);
1060 address += (sec->output_section->vma + sec->output_offset
1061 + sec_info->entry[i].offset + 8);
1062 break;
1063 }
1064 if (sec_info->entry[i].make_relative)
1065 value -= (sec->output_section->vma + sec->output_offset
1066 + sec_info->entry[i].new_offset + 8);
1067 write_value (abfd, buf, value, width);
1068 }
1069
1070 if (hdr_info)
1071 {
1072 hdr_info->array[hdr_info->array_count].initial_loc = address;
1073 hdr_info->array[hdr_info->array_count++].fde
1074 = (sec->output_section->vma + sec->output_offset
1075 + sec_info->entry[i].new_offset);
1076 }
1077
1078 if ((sec_info->entry[i].lsda_encoding & 0xf0) == DW_EH_PE_pcrel
1079 || sec_info->entry[i].make_lsda_relative)
1080 {
1081 buf += sec_info->entry[i].lsda_offset;
1082 width = get_DW_EH_PE_width (sec_info->entry[i].lsda_encoding,
1083 ptr_size);
1084 value = read_value (abfd, buf, width);
1085 if (value)
1086 {
1087 if ((sec_info->entry[i].lsda_encoding & 0xf0)
1088 == DW_EH_PE_pcrel)
1089 value += (sec_info->entry[i].offset
1090 - sec_info->entry[i].new_offset);
1091 else if (sec_info->entry[i].make_lsda_relative)
1092 value -= (sec->output_section->vma + sec->output_offset
1093 + sec_info->entry[i].new_offset + 8
1094 + sec_info->entry[i].lsda_offset);
1095 write_value (abfd, buf, value, width);
1096 }
1097 }
1098 }
1099 else
1100 /* Terminating FDE must be at the end of .eh_frame section only. */
1101 BFD_ASSERT (i == sec_info->count - 1);
1102
1103 BFD_ASSERT (p == contents + sec_info->entry[i].new_offset);
1104 memmove (p, contents + sec_info->entry[i].offset,
1105 sec_info->entry[i].size);
1106 p += sec_info->entry[i].size;
1107 }
1108
1109 /* FIXME: Once _bfd_elf_discard_section_eh_frame will be able to
1110 shrink sections to zero size, this won't be needed any more. */
1111 if (p == contents && sec->_cooked_size == 16)
1112 {
1113 bfd_put_32 (abfd, 12, p); /* Fake CIE length */
1114 bfd_put_32 (abfd, 0, p + 4); /* Fake CIE id */
1115 p[8] = 1; /* Fake CIE version */
1116 memset (p + 9, 0, 7); /* Fake CIE augmentation, 3xleb128
1117 and 3xDW_CFA_nop as pad */
1118 p += 16;
1119 }
1120
1121 BFD_ASSERT ((bfd_size_type) (p - contents) == sec->_cooked_size);
1122
1123 return bfd_set_section_contents (abfd, sec->output_section,
1124 contents, (file_ptr) sec->output_offset,
1125 sec->_cooked_size);
1126 }
1127
1128 /* Helper function used to sort .eh_frame_hdr search table by increasing
1129 VMA of FDE initial location. */
1130
1131 static int
1132 vma_compare (a, b)
1133 const PTR a;
1134 const PTR b;
1135 {
1136 struct eh_frame_array_ent *p = (struct eh_frame_array_ent *) a;
1137 struct eh_frame_array_ent *q = (struct eh_frame_array_ent *) b;
1138 if (p->initial_loc > q->initial_loc)
1139 return 1;
1140 if (p->initial_loc < q->initial_loc)
1141 return -1;
1142 return 0;
1143 }
1144
1145 /* Write out .eh_frame_hdr section. This must be called after
1146 _bfd_elf_write_section_eh_frame has been called on all input
1147 .eh_frame sections.
1148 .eh_frame_hdr format:
1149 ubyte version (currently 1)
1150 ubyte eh_frame_ptr_enc (DW_EH_PE_* encoding of pointer to start of
1151 .eh_frame section)
1152 ubyte fde_count_enc (DW_EH_PE_* encoding of total FDE count
1153 number (or DW_EH_PE_omit if there is no
1154 binary search table computed))
1155 ubyte table_enc (DW_EH_PE_* encoding of binary search table,
1156 or DW_EH_PE_omit if not present.
1157 DW_EH_PE_datarel is using address of
1158 .eh_frame_hdr section start as base)
1159 [encoded] eh_frame_ptr (pointer to start of .eh_frame section)
1160 optionally followed by:
1161 [encoded] fde_count (total number of FDEs in .eh_frame section)
1162 fde_count x [encoded] initial_loc, fde
1163 (array of encoded pairs containing
1164 FDE initial_location field and FDE address,
1165 sorted by increasing initial_loc) */
1166
1167 boolean
1168 _bfd_elf_write_section_eh_frame_hdr (abfd, sec)
1169 bfd *abfd;
1170 asection *sec;
1171 {
1172 struct eh_frame_hdr_info *hdr_info;
1173 bfd_byte *contents;
1174 asection *eh_frame_sec;
1175 bfd_size_type size;
1176
1177 BFD_ASSERT (elf_section_data (sec)->sec_info_type
1178 == ELF_INFO_TYPE_EH_FRAME_HDR);
1179 hdr_info = (struct eh_frame_hdr_info *)
1180 elf_section_data (sec)->sec_info;
1181 if (hdr_info->strip)
1182 return true;
1183
1184 size = EH_FRAME_HDR_SIZE;
1185 if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
1186 size += 4 + hdr_info->fde_count * 8;
1187 contents = bfd_malloc (size);
1188 if (contents == NULL)
1189 return false;
1190
1191 eh_frame_sec = bfd_get_section_by_name (abfd, ".eh_frame");
1192 if (eh_frame_sec == NULL)
1193 return false;
1194
1195 memset (contents, 0, EH_FRAME_HDR_SIZE);
1196 contents[0] = 1; /* Version */
1197 contents[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4; /* .eh_frame offset */
1198 if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
1199 {
1200 contents[2] = DW_EH_PE_udata4; /* FDE count encoding */
1201 contents[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4; /* search table enc */
1202 }
1203 else
1204 {
1205 contents[2] = DW_EH_PE_omit;
1206 contents[3] = DW_EH_PE_omit;
1207 }
1208 bfd_put_32 (abfd, eh_frame_sec->vma - sec->output_section->vma - 4,
1209 contents + 4);
1210 if (contents[2] != DW_EH_PE_omit)
1211 {
1212 unsigned int i;
1213
1214 bfd_put_32 (abfd, hdr_info->fde_count, contents + EH_FRAME_HDR_SIZE);
1215 qsort (hdr_info->array, hdr_info->fde_count, sizeof (*hdr_info->array),
1216 vma_compare);
1217 for (i = 0; i < hdr_info->fde_count; i++)
1218 {
1219 bfd_put_32 (abfd,
1220 hdr_info->array[i].initial_loc
1221 - sec->output_section->vma,
1222 contents + EH_FRAME_HDR_SIZE + i * 8 + 4);
1223 bfd_put_32 (abfd,
1224 hdr_info->array[i].fde - sec->output_section->vma,
1225 contents + EH_FRAME_HDR_SIZE + i * 8 + 8);
1226 }
1227 }
1228
1229 return bfd_set_section_contents (abfd, sec->output_section,
1230 contents, (file_ptr) sec->output_offset,
1231 sec->_cooked_size);
1232 }
This page took 0.054272 seconds and 4 git commands to generate.