When adding BSF_WEAK flag, OR it in rather than replacing previously selected
[binutils.git] / bfd / elf-eh-frame.c
blob20cbfb22c8305a429bcd407168cd0297520b8cd6
1 /* .eh_frame section optimization.
2 Copyright 2001, 2002 Free Software Foundation, Inc.
3 Written by Jakub Jelinek <jakub@redhat.com>.
5 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
21 #include "bfd.h"
22 #include "sysdep.h"
23 #include "libbfd.h"
24 #include "elf-bfd.h"
25 #include "elf/dwarf2.h"
27 #define EH_FRAME_HDR_SIZE 8
29 struct cie_header
31 unsigned int length;
32 unsigned int id;
35 struct cie
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];
54 struct eh_cie_fde
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;
69 struct eh_frame_sec_info
71 unsigned int count;
72 unsigned int alloced;
73 struct eh_cie_fde entry[1];
76 struct eh_frame_array_ent
78 bfd_vma initial_loc;
79 bfd_vma fde;
82 struct eh_frame_hdr_info
84 struct cie last_cie;
85 asection *last_cie_sec;
86 unsigned int last_cie_offset;
87 unsigned int fde_count, array_count;
88 struct eh_frame_array_ent *array;
89 /* TRUE if .eh_frame_hdr should contain the sorted search table.
90 We build it if we successfully read all .eh_frame input sections
91 and recognize them. */
92 boolean table;
93 boolean strip;
96 static bfd_vma read_unsigned_leb128
97 PARAMS ((bfd *, char *, unsigned int *));
98 static bfd_signed_vma read_signed_leb128
99 PARAMS ((bfd *, char *, unsigned int *));
100 static int get_DW_EH_PE_width
101 PARAMS ((int, int));
102 static bfd_vma read_value
103 PARAMS ((bfd *, bfd_byte *, int));
104 static void write_value
105 PARAMS ((bfd *, bfd_byte *, bfd_vma, int));
106 static int cie_compare
107 PARAMS ((struct cie *, struct cie *));
108 static int vma_compare
109 PARAMS ((const PTR a, const PTR b));
111 /* Helper function for reading uleb128 encoded data. */
113 static bfd_vma
114 read_unsigned_leb128 (abfd, buf, bytes_read_ptr)
115 bfd *abfd ATTRIBUTE_UNUSED;
116 char *buf;
117 unsigned int *bytes_read_ptr;
119 bfd_vma result;
120 unsigned int num_read;
121 int shift;
122 unsigned char byte;
124 result = 0;
125 shift = 0;
126 num_read = 0;
129 byte = bfd_get_8 (abfd, (bfd_byte *) buf);
130 buf ++;
131 num_read ++;
132 result |= (((bfd_vma) byte & 0x7f) << shift);
133 shift += 7;
135 while (byte & 0x80);
136 * bytes_read_ptr = num_read;
137 return result;
140 /* Helper function for reading sleb128 encoded data. */
142 static bfd_signed_vma
143 read_signed_leb128 (abfd, buf, bytes_read_ptr)
144 bfd *abfd ATTRIBUTE_UNUSED;
145 char *buf;
146 unsigned int * bytes_read_ptr;
148 bfd_vma result;
149 int shift;
150 int num_read;
151 unsigned char byte;
153 result = 0;
154 shift = 0;
155 num_read = 0;
158 byte = bfd_get_8 (abfd, (bfd_byte *) buf);
159 buf ++;
160 num_read ++;
161 result |= (((bfd_vma) byte & 0x7f) << shift);
162 shift += 7;
164 while (byte & 0x80);
165 if (byte & 0x40)
166 result |= (((bfd_vma) -1) << (shift - 7)) << 7;
167 * bytes_read_ptr = num_read;
168 return result;
171 #define read_uleb128(VAR, BUF) \
172 do \
174 (VAR) = read_unsigned_leb128 (abfd, buf, &leb128_tmp); \
175 (BUF) += leb128_tmp; \
177 while (0)
179 #define read_sleb128(VAR, BUF) \
180 do \
182 (VAR) = read_signed_leb128 (abfd, buf, &leb128_tmp); \
183 (BUF) += leb128_tmp; \
185 while (0)
187 /* Return 0 if either encoding is variable width, or not yet known to bfd. */
189 static
190 int get_DW_EH_PE_width (encoding, ptr_size)
191 int encoding, ptr_size;
193 /* DW_EH_PE_ values of 0x60 and 0x70 weren't defined at the time .eh_frame
194 was added to bfd. */
195 if ((encoding & 0x60) == 0x60)
196 return 0;
198 switch (encoding & 7)
200 case DW_EH_PE_udata2: return 2;
201 case DW_EH_PE_udata4: return 4;
202 case DW_EH_PE_udata8: return 8;
203 case DW_EH_PE_absptr: return ptr_size;
204 default:
205 break;
208 return 0;
211 /* Read a width sized value from memory. */
213 static bfd_vma
214 read_value (abfd, buf, width)
215 bfd *abfd;
216 bfd_byte *buf;
217 int width;
219 bfd_vma value;
221 switch (width)
223 case 2: value = bfd_get_16 (abfd, buf); break;
224 case 4: value = bfd_get_32 (abfd, buf); break;
225 case 8: value = bfd_get_64 (abfd, buf); break;
226 default: BFD_FAIL (); return 0;
229 return value;
232 /* Store a width sized value to memory. */
234 static void
235 write_value (abfd, buf, value, width)
236 bfd *abfd;
237 bfd_byte *buf;
238 bfd_vma value;
239 int width;
241 switch (width)
243 case 2: bfd_put_16 (abfd, value, buf); break;
244 case 4: bfd_put_32 (abfd, value, buf); break;
245 case 8: bfd_put_64 (abfd, value, buf); break;
246 default: BFD_FAIL ();
250 /* Return zero if C1 and C2 CIEs can be merged. */
252 static
253 int cie_compare (c1, c2)
254 struct cie *c1, *c2;
256 if (c1->hdr.length == c2->hdr.length
257 && c1->version == c2->version
258 && strcmp (c1->augmentation, c2->augmentation) == 0
259 && strcmp (c1->augmentation, "eh") != 0
260 && c1->code_align == c2->code_align
261 && c1->data_align == c2->data_align
262 && c1->ra_column == c2->ra_column
263 && c1->augmentation_size == c2->augmentation_size
264 && c1->personality == c2->personality
265 && c1->per_encoding == c2->per_encoding
266 && c1->lsda_encoding == c2->lsda_encoding
267 && c1->fde_encoding == c2->fde_encoding
268 && (c1->initial_insn_length
269 == c2->initial_insn_length)
270 && memcmp (c1->initial_instructions,
271 c2->initial_instructions,
272 c1->initial_insn_length) == 0)
273 return 0;
275 return 1;
278 /* This function is called for each input file before the .eh_frame
279 section is relocated. It discards duplicate CIEs and FDEs for discarded
280 functions. The function returns true iff any entries have been
281 deleted. */
283 boolean
284 _bfd_elf_discard_section_eh_frame (abfd, info, sec, ehdrsec,
285 reloc_symbol_deleted_p, cookie)
286 bfd *abfd;
287 struct bfd_link_info *info;
288 asection *sec, *ehdrsec;
289 boolean (*reloc_symbol_deleted_p) (bfd_vma, PTR);
290 struct elf_reloc_cookie *cookie;
292 bfd_byte *ehbuf = NULL, *buf;
293 bfd_byte *last_cie, *last_fde;
294 struct cie_header hdr;
295 struct cie cie;
296 struct eh_frame_hdr_info *hdr_info;
297 struct eh_frame_sec_info *sec_info = NULL;
298 unsigned int leb128_tmp;
299 unsigned int cie_usage_count, last_cie_ndx, i, offset;
300 unsigned int make_relative, make_lsda_relative;
301 Elf_Internal_Rela *rel;
302 bfd_size_type new_size;
303 unsigned int ptr_size;
305 if (sec->_raw_size == 0)
307 /* This file does not contain .eh_frame information. */
308 return false;
311 if ((sec->output_section != NULL
312 && bfd_is_abs_section (sec->output_section)))
314 /* At least one of the sections is being discarded from the
315 link, so we should just ignore them. */
316 return false;
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;
324 /* Read the frame unwind information from abfd. */
326 ehbuf = (bfd_byte *) bfd_malloc (sec->_raw_size);
327 if (ehbuf == NULL)
328 goto free_no_table;
330 if (! bfd_get_section_contents (abfd, sec, ehbuf, (bfd_vma) 0,
331 sec->_raw_size))
332 goto free_no_table;
334 if (sec->_raw_size >= 4
335 && bfd_get_32 (abfd, ehbuf) == 0
336 && cookie->rel == cookie->relend)
338 /* Empty .eh_frame section. */
339 free (ehbuf);
340 return false;
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;
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;
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
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++
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)
382 for (;;)
384 unsigned char *aug;
386 if (sec_info->count == sec_info->alloced)
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;
395 memset (&sec_info->entry[sec_info->alloced], 0,
396 100 * sizeof (struct eh_cie_fde));
397 sec_info->alloced += 100;
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
407 if ((bfd_size_type) (buf + 4 - ehbuf) > sec->_raw_size)
408 /* No space for CIE/FDE header length. */
409 goto free_no_table;
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 ((buf - ehbuf) + hdr.length > sec->_raw_size)
417 /* CIE/FDE not contained fully in this .eh_frame input section. */
418 goto free_no_table;
420 sec_info->entry[sec_info->count].offset = last_fde - ehbuf;
421 sec_info->entry[sec_info->count].size = 4 + hdr.length;
423 if (hdr.length == 0)
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;
434 else
436 hdr.id = bfd_get_32 (abfd, buf);
437 buf += 4;
438 if (hdr.id == (unsigned int) -1)
439 goto free_no_table;
443 if (hdr.id == 0 || hdr.id == (unsigned int) -1)
445 unsigned int initial_insn_length;
447 /* CIE */
448 if (last_cie != NULL)
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)
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;
463 else
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;
475 if (hdr.id == (unsigned int) -1)
476 break;
478 last_cie_ndx = sec_info->count;
479 sec_info->entry[sec_info->count].cie = 1;
481 cie_usage_count = 0;
482 memset (&cie, 0, sizeof (cie));
483 cie.hdr = hdr;
484 cie.version = *buf++;
486 /* Cannot handle unknown versions. */
487 if (cie.version != 1)
488 goto free_no_table;
489 if (strlen (buf) > sizeof (cie.augmentation) - 1)
490 goto free_no_table;
492 strcpy (cie.augmentation, buf);
493 buf = strchr (buf, '\0') + 1;
494 ENSURE_NO_RELOCS (buf);
495 if (buf[0] == 'e' && buf[1] == 'h')
497 /* GCC < 3.0 .eh_frame CIE */
498 /* We cannot merge "eh" CIEs because __EXCEPTION_TABLE__
499 is private to each CIE, so we don't need it for anything.
500 Just skip it. */
501 buf += ptr_size;
502 SKIP_RELOCS (buf);
504 read_uleb128 (cie.code_align, buf);
505 read_sleb128 (cie.data_align, buf);
506 read_uleb128 (cie.ra_column, buf);
507 ENSURE_NO_RELOCS (buf);
508 cie.lsda_encoding = DW_EH_PE_omit;
509 cie.fde_encoding = DW_EH_PE_omit;
510 cie.per_encoding = DW_EH_PE_omit;
511 aug = cie.augmentation;
512 if (aug[0] != 'e' || aug[1] != 'h')
514 if (*aug == 'z')
516 aug++;
517 read_uleb128 (cie.augmentation_size, buf);
518 ENSURE_NO_RELOCS (buf);
521 while (*aug != '\0')
522 switch (*aug++)
524 case 'L':
525 cie.lsda_encoding = *buf++;
526 ENSURE_NO_RELOCS (buf);
527 if (get_DW_EH_PE_width (cie.lsda_encoding, ptr_size) == 0)
528 goto free_no_table;
529 break;
530 case 'R':
531 cie.fde_encoding = *buf++;
532 ENSURE_NO_RELOCS (buf);
533 if (get_DW_EH_PE_width (cie.fde_encoding, ptr_size) == 0)
534 goto free_no_table;
535 break;
536 case 'P':
538 int per_width;
540 cie.per_encoding = *buf++;
541 per_width = get_DW_EH_PE_width (cie.per_encoding,
542 ptr_size);
543 if (per_width == 0)
544 goto free_no_table;
545 if ((cie.per_encoding & 0xf0) == DW_EH_PE_aligned)
546 buf = (ehbuf
547 + ((buf - ehbuf + per_width - 1)
548 & ~((bfd_size_type) per_width - 1)));
549 ENSURE_NO_RELOCS (buf);
550 rel = GET_RELOC (buf);
551 /* Ensure we have a reloc here, against
552 a global symbol. */
553 if (rel != NULL)
555 unsigned long r_symndx;
557 #ifdef BFD64
558 if (ptr_size == 8)
559 r_symndx = ELF64_R_SYM (cookie->rel->r_info);
560 else
561 #endif
562 r_symndx = ELF32_R_SYM (cookie->rel->r_info);
563 if (r_symndx >= cookie->locsymcount)
565 struct elf_link_hash_entry *h;
567 r_symndx -= cookie->extsymoff;
568 h = cookie->sym_hashes[r_symndx];
570 while (h->root.type == bfd_link_hash_indirect
571 || h->root.type == bfd_link_hash_warning)
572 h = (struct elf_link_hash_entry *)
573 h->root.u.i.link;
575 cie.personality = h;
577 cookie->rel++;
579 buf += per_width;
581 break;
582 default:
583 /* Unrecognized augmentation. Better bail out. */
584 goto free_no_table;
588 /* For shared libraries, try to get rid of as many RELATIVE relocs
589 as possible. */
590 if (info->shared
591 && (cie.fde_encoding & 0xf0) == DW_EH_PE_absptr)
592 cie.make_relative = 1;
594 if (info->shared
595 && (cie.lsda_encoding & 0xf0) == DW_EH_PE_absptr)
596 cie.make_lsda_relative = 1;
598 /* If FDE encoding was not specified, it defaults to
599 DW_EH_absptr. */
600 if (cie.fde_encoding == DW_EH_PE_omit)
601 cie.fde_encoding = DW_EH_PE_absptr;
603 initial_insn_length = cie.hdr.length - (buf - last_fde - 4);
604 if (initial_insn_length <= 50)
606 cie.initial_insn_length = initial_insn_length;
607 memcpy (cie.initial_instructions, buf, initial_insn_length);
609 buf += initial_insn_length;
610 ENSURE_NO_RELOCS (buf);
611 last_cie = last_fde;
613 else
615 /* Ensure this FDE uses the last CIE encountered. */
616 if (last_cie == NULL
617 || hdr.id != (unsigned int) (buf - 4 - last_cie))
618 goto free_no_table;
620 ENSURE_NO_RELOCS (buf);
621 rel = GET_RELOC (buf);
622 if (rel == NULL)
623 /* This should not happen. */
624 goto free_no_table;
625 if ((*reloc_symbol_deleted_p) (buf - ehbuf, cookie))
627 cookie->rel = rel;
628 /* This is a FDE against discarded section, it should
629 be deleted. */
630 new_size -= hdr.length + 4;
631 sec_info->entry[sec_info->count].removed = 1;
633 else
635 if (info->shared
636 && (cie.fde_encoding & 0xf0) == DW_EH_PE_absptr
637 && cie.make_relative == 0)
639 /* If shared library uses absolute pointers
640 which we cannot turn into PC relative,
641 don't create the binary search table,
642 since it is affected by runtime relocations. */
643 hdr_info->table = false;
645 cie_usage_count++;
646 hdr_info->fde_count++;
648 cookie->rel = rel;
649 if (cie.lsda_encoding != DW_EH_PE_omit)
651 unsigned int dummy;
653 aug = buf;
654 buf += 2 * get_DW_EH_PE_width (cie.fde_encoding, ptr_size);
655 if (cie.augmentation[0] == 'z')
656 read_uleb128 (dummy, buf);
657 /* If some new augmentation data is added before LSDA
658 in FDE augmentation area, this need to be adjusted. */
659 sec_info->entry[sec_info->count].lsda_offset = (buf - aug);
661 buf = last_fde + 4 + hdr.length;
662 SKIP_RELOCS (buf);
665 sec_info->entry[sec_info->count].fde_encoding = cie.fde_encoding;
666 sec_info->entry[sec_info->count].lsda_encoding = cie.lsda_encoding;
667 sec_info->count++;
670 elf_section_data (sec)->sec_info = sec_info;
671 elf_section_data (sec)->sec_info_type = ELF_INFO_TYPE_EH_FRAME;
673 /* Ok, now we can assign new offsets. */
674 offset = 0;
675 last_cie_ndx = 0;
676 for (i = 0; i < sec_info->count; i++)
678 if (! sec_info->entry[i].removed)
680 sec_info->entry[i].new_offset = offset;
681 offset += sec_info->entry[i].size;
682 if (sec_info->entry[i].cie)
684 last_cie_ndx = i;
685 make_relative = sec_info->entry[i].make_relative;
686 make_lsda_relative = sec_info->entry[i].make_lsda_relative;
688 else
690 sec_info->entry[i].make_relative = make_relative;
691 sec_info->entry[i].make_lsda_relative = make_lsda_relative;
694 else if (sec_info->entry[i].cie && sec_info->entry[i].sec == sec)
696 /* Need to adjust new_offset too. */
697 BFD_ASSERT (sec_info->entry[last_cie_ndx].offset
698 == sec_info->entry[i].new_offset);
699 sec_info->entry[i].new_offset
700 = sec_info->entry[last_cie_ndx].new_offset;
703 if (hdr_info->last_cie_sec == sec)
705 BFD_ASSERT (sec_info->entry[last_cie_ndx].offset
706 == hdr_info->last_cie_offset);
707 hdr_info->last_cie_offset = sec_info->entry[last_cie_ndx].new_offset;
710 /* FIXME: Currently it is not possible to shrink sections to zero size at
711 this point, so build a fake minimal CIE. */
712 if (new_size == 0)
713 new_size = 16;
715 /* Shrink the sec as needed. */
716 sec->_cooked_size = new_size;
717 if (sec->_cooked_size == 0)
718 sec->flags |= SEC_EXCLUDE;
720 free (ehbuf);
721 return new_size != sec->_raw_size;
723 free_no_table:
724 if (ehbuf)
725 free (ehbuf);
726 if (sec_info)
727 free (sec_info);
728 hdr_info->table = false;
729 hdr_info->last_cie.hdr.length = 0;
730 return false;
733 /* This function is called for .eh_frame_hdr section after
734 _bfd_elf_discard_section_eh_frame has been called on all .eh_frame
735 input sections. It finalizes the size of .eh_frame_hdr section. */
737 boolean
738 _bfd_elf_discard_section_eh_frame_hdr (abfd, info, sec)
739 bfd *abfd;
740 struct bfd_link_info *info;
741 asection *sec;
743 struct eh_frame_hdr_info *hdr_info;
744 unsigned int ptr_size;
746 ptr_size = (elf_elfheader (abfd)->e_ident[EI_CLASS]
747 == ELFCLASS64) ? 8 : 4;
749 if ((elf_section_data (sec)->sec_info_type
750 != ELF_INFO_TYPE_EH_FRAME_HDR)
751 || ! info->eh_frame_hdr)
753 _bfd_strip_section_from_output (info, sec);
754 return false;
757 hdr_info = (struct eh_frame_hdr_info *)
758 elf_section_data (sec)->sec_info;
759 if (hdr_info->strip)
760 return false;
761 sec->_cooked_size = EH_FRAME_HDR_SIZE;
762 if (hdr_info->table)
763 sec->_cooked_size += 4 + hdr_info->fde_count * 8;
765 /* Request program headers to be recalculated. */
766 elf_tdata (abfd)->program_header_size = 0;
767 elf_tdata (abfd)->eh_frame_hdr = true;
768 return true;
771 /* This function is called from size_dynamic_sections.
772 It needs to decide whether .eh_frame_hdr should be output or not,
773 because later on it is too late for calling _bfd_strip_section_from_output,
774 since dynamic symbol table has been sized. */
776 boolean
777 _bfd_elf_maybe_strip_eh_frame_hdr (info)
778 struct bfd_link_info *info;
780 asection *sec, *o;
781 bfd *abfd;
782 struct eh_frame_hdr_info *hdr_info;
784 sec = bfd_get_section_by_name (elf_hash_table (info)->dynobj, ".eh_frame_hdr");
785 if (sec == NULL)
786 return true;
788 hdr_info
789 = bfd_zmalloc (sizeof (struct eh_frame_hdr_info));
790 if (hdr_info == NULL)
791 return false;
793 elf_section_data (sec)->sec_info = hdr_info;
794 elf_section_data (sec)->sec_info_type = ELF_INFO_TYPE_EH_FRAME_HDR;
796 abfd = NULL;
797 if (info->eh_frame_hdr)
798 for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
800 /* Count only sections which have at least a single CIE or FDE.
801 There cannot be any CIE or FDE <= 8 bytes. */
802 o = bfd_get_section_by_name (abfd, ".eh_frame");
803 if (o && o->_raw_size > 8)
804 break;
807 if (abfd == NULL)
809 _bfd_strip_section_from_output (info, sec);
810 hdr_info->strip = true;
812 else
813 hdr_info->table = true;
814 return true;
817 /* Adjust an address in the .eh_frame section. Given OFFSET within
818 SEC, this returns the new offset in the adjusted .eh_frame section,
819 or -1 if the address refers to a CIE/FDE which has been removed
820 or to offset with dynamic relocation which is no longer needed. */
822 bfd_vma
823 _bfd_elf_eh_frame_section_offset (output_bfd, sec, offset)
824 bfd *output_bfd ATTRIBUTE_UNUSED;
825 asection *sec;
826 bfd_vma offset;
828 struct eh_frame_sec_info *sec_info;
829 unsigned int lo, hi, mid;
831 if (elf_section_data (sec)->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
832 return offset;
833 sec_info = (struct eh_frame_sec_info *)
834 elf_section_data (sec)->sec_info;
836 if (offset >= sec->_raw_size)
837 return offset - (sec->_cooked_size - sec->_raw_size);
839 lo = 0;
840 hi = sec_info->count;
841 mid = 0;
842 while (lo < hi)
844 mid = (lo + hi) / 2;
845 if (offset < sec_info->entry[mid].offset)
846 hi = mid;
847 else if (offset
848 >= sec_info->entry[mid].offset + sec_info->entry[mid].size)
849 lo = mid + 1;
850 else
851 break;
854 BFD_ASSERT (lo < hi);
856 /* FDE or CIE was removed. */
857 if (sec_info->entry[mid].removed)
858 return (bfd_vma) -1;
860 /* If converting to DW_EH_PE_pcrel, there will be no need for run-time
861 relocation against FDE's initial_location field. */
862 if (sec_info->entry[mid].make_relative
863 && ! sec_info->entry[mid].cie
864 && offset == sec_info->entry[mid].offset + 8)
865 return (bfd_vma) -2;
867 /* If converting LSDA pointers to DW_EH_PE_pcrel, there will be no need
868 for run-time relocation against LSDA field. */
869 if (sec_info->entry[mid].make_lsda_relative
870 && ! sec_info->entry[mid].cie
871 && (offset
872 == (sec_info->entry[mid].offset + 8
873 + sec_info->entry[mid].lsda_offset)))
874 return (bfd_vma) -2;
876 return (offset + sec_info->entry[mid].new_offset
877 - sec_info->entry[mid].offset);
880 /* Write out .eh_frame section. This is called with the relocated
881 contents. */
883 boolean
884 _bfd_elf_write_section_eh_frame (abfd, sec, ehdrsec, contents)
885 bfd *abfd;
886 asection *sec, *ehdrsec;
887 bfd_byte *contents;
889 struct eh_frame_sec_info *sec_info;
890 struct eh_frame_hdr_info *hdr_info;
891 unsigned int i;
892 bfd_byte *p, *buf;
893 unsigned int leb128_tmp;
894 unsigned int cie_offset = 0;
895 unsigned int ptr_size;
897 ptr_size = (elf_elfheader (sec->owner)->e_ident[EI_CLASS]
898 == ELFCLASS64) ? 8 : 4;
900 if (elf_section_data (sec)->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
901 return bfd_set_section_contents (abfd, sec->output_section,
902 contents,
903 (file_ptr) sec->output_offset,
904 sec->_raw_size);
905 sec_info = (struct eh_frame_sec_info *)
906 elf_section_data (sec)->sec_info;
907 hdr_info = NULL;
908 if (ehdrsec
909 && (elf_section_data (ehdrsec)->sec_info_type
910 == ELF_INFO_TYPE_EH_FRAME_HDR))
912 hdr_info = (struct eh_frame_hdr_info *)
913 elf_section_data (ehdrsec)->sec_info;
914 if (hdr_info->table && hdr_info->array == NULL)
915 hdr_info->array
916 = bfd_malloc (hdr_info->fde_count * sizeof(*hdr_info->array));
917 if (hdr_info->array == NULL)
918 hdr_info = NULL;
921 p = contents;
922 for (i = 0; i < sec_info->count; ++i)
924 if (sec_info->entry[i].removed)
926 if (sec_info->entry[i].cie)
928 /* If CIE is removed due to no remaining FDEs referencing it
929 and there were no CIEs kept before it, sec_info->entry[i].sec
930 will be zero. */
931 if (sec_info->entry[i].sec == NULL)
932 cie_offset = 0;
933 else
935 cie_offset = sec_info->entry[i].new_offset;
936 cie_offset += (sec_info->entry[i].sec->output_section->vma
937 + sec_info->entry[i].sec->output_offset
938 - sec->output_section->vma
939 - sec->output_offset);
942 continue;
945 if (sec_info->entry[i].cie)
947 /* CIE */
948 cie_offset = sec_info->entry[i].new_offset;
949 if (sec_info->entry[i].make_relative
950 || sec_info->entry[i].make_lsda_relative)
952 unsigned char *aug;
953 unsigned int action;
954 unsigned int dummy, per_width, per_encoding;
956 /* Need to find 'R' or 'L' augmentation's argument and modify
957 DW_EH_PE_* value. */
958 action = (sec_info->entry[i].make_relative ? 1 : 0)
959 | (sec_info->entry[i].make_lsda_relative ? 2 : 0);
960 buf = contents + sec_info->entry[i].offset;
961 /* Skip length, id and version. */
962 buf += 9;
963 aug = buf;
964 buf = strchr (buf, '\0') + 1;
965 read_uleb128 (dummy, buf);
966 read_sleb128 (dummy, buf);
967 read_uleb128 (dummy, buf);
968 if (*aug == 'z')
970 read_uleb128 (dummy, buf);
971 aug++;
974 while (action)
975 switch (*aug++)
977 case 'L':
978 if (action & 2)
980 BFD_ASSERT (*buf == sec_info->entry[i].lsda_encoding);
981 *buf |= DW_EH_PE_pcrel;
982 action &= ~2;
984 buf++;
985 break;
986 case 'P':
987 per_encoding = *buf++;
988 per_width = get_DW_EH_PE_width (per_encoding,
989 ptr_size);
990 BFD_ASSERT (per_width != 0);
991 if ((per_encoding & 0xf0) == DW_EH_PE_aligned)
992 buf = (contents
993 + ((buf - contents + per_width - 1)
994 & ~((bfd_size_type) per_width - 1)));
995 buf += per_width;
996 break;
997 case 'R':
998 if (action & 1)
1000 BFD_ASSERT (*buf == sec_info->entry[i].fde_encoding);
1001 *buf |= DW_EH_PE_pcrel;
1002 action &= ~1;
1004 buf++;
1005 break;
1006 default:
1007 BFD_FAIL ();
1011 else
1013 /* FDE */
1014 bfd_vma value = 0, address;
1015 unsigned int width;
1017 buf = contents + sec_info->entry[i].offset;
1018 /* Skip length. */
1019 buf += 4;
1020 bfd_put_32 (abfd,
1021 sec_info->entry[i].new_offset + 4 - cie_offset, buf);
1022 buf += 4;
1023 width = get_DW_EH_PE_width (sec_info->entry[i].fde_encoding,
1024 ptr_size);
1025 address = value = read_value (abfd, buf, width);
1026 if (value)
1028 switch (sec_info->entry[i].fde_encoding & 0xf0)
1030 case DW_EH_PE_indirect:
1031 case DW_EH_PE_textrel:
1032 BFD_ASSERT (hdr_info == NULL);
1033 break;
1034 case DW_EH_PE_datarel:
1036 asection *got = bfd_get_section_by_name (abfd, ".got");
1038 BFD_ASSERT (got != NULL);
1039 address += got->vma;
1041 break;
1042 case DW_EH_PE_pcrel:
1043 value += (sec_info->entry[i].offset
1044 - sec_info->entry[i].new_offset);
1045 address += (sec->output_section->vma + sec->output_offset
1046 + sec_info->entry[i].offset + 8);
1047 break;
1049 if (sec_info->entry[i].make_relative)
1050 value -= (sec->output_section->vma + sec->output_offset
1051 + sec_info->entry[i].new_offset + 8);
1052 write_value (abfd, buf, value, width);
1055 if (hdr_info)
1057 hdr_info->array[hdr_info->array_count].initial_loc = address;
1058 hdr_info->array[hdr_info->array_count++].fde
1059 = (sec->output_section->vma + sec->output_offset
1060 + sec_info->entry[i].new_offset);
1063 if ((sec_info->entry[i].lsda_encoding & 0xf0) == DW_EH_PE_pcrel
1064 || sec_info->entry[i].make_lsda_relative)
1066 buf += sec_info->entry[i].lsda_offset;
1067 width = get_DW_EH_PE_width (sec_info->entry[i].lsda_encoding,
1068 ptr_size);
1069 value = read_value (abfd, buf, width);
1070 if (value)
1072 if ((sec_info->entry[i].lsda_encoding & 0xf0)
1073 == DW_EH_PE_pcrel)
1074 value += (sec_info->entry[i].offset
1075 - sec_info->entry[i].new_offset);
1076 else if (sec_info->entry[i].make_lsda_relative)
1077 value -= (sec->output_section->vma + sec->output_offset
1078 + sec_info->entry[i].new_offset + 8
1079 + sec_info->entry[i].lsda_offset);
1080 write_value (abfd, buf, value, width);
1085 BFD_ASSERT (p == contents + sec_info->entry[i].new_offset);
1086 memmove (p, contents + sec_info->entry[i].offset,
1087 sec_info->entry[i].size);
1088 p += sec_info->entry[i].size;
1091 /* FIXME: Once _bfd_elf_discard_section_eh_frame will be able to
1092 shrink sections to zero size, this won't be needed any more. */
1093 if (p == contents && sec->_cooked_size == 16)
1095 bfd_put_32 (abfd, 12, p); /* Fake CIE length */
1096 bfd_put_32 (abfd, 0, p + 4); /* Fake CIE id */
1097 p[8] = 1; /* Fake CIE version */
1098 memset (p + 9, 0, 7); /* Fake CIE augmentation, 3xleb128
1099 and 3xDW_CFA_nop as pad */
1100 p += 16;
1103 BFD_ASSERT ((bfd_size_type) (p - contents) == sec->_cooked_size);
1105 return bfd_set_section_contents (abfd, sec->output_section,
1106 contents, (file_ptr) sec->output_offset,
1107 sec->_cooked_size);
1110 /* Helper function used to sort .eh_frame_hdr search table by increasing
1111 VMA of FDE initial location. */
1113 static int
1114 vma_compare (a, b)
1115 const PTR a;
1116 const PTR b;
1118 struct eh_frame_array_ent *p = (struct eh_frame_array_ent *) a;
1119 struct eh_frame_array_ent *q = (struct eh_frame_array_ent *) b;
1120 if (p->initial_loc > q->initial_loc)
1121 return 1;
1122 if (p->initial_loc < q->initial_loc)
1123 return -1;
1124 return 0;
1127 /* Write out .eh_frame_hdr section. This must be called after
1128 _bfd_elf_write_section_eh_frame has been called on all input
1129 .eh_frame sections.
1130 .eh_frame_hdr format:
1131 ubyte version (currently 1)
1132 ubyte eh_frame_ptr_enc (DW_EH_PE_* encoding of pointer to start of
1133 .eh_frame section)
1134 ubyte fde_count_enc (DW_EH_PE_* encoding of total FDE count
1135 number (or DW_EH_PE_omit if there is no
1136 binary search table computed))
1137 ubyte table_enc (DW_EH_PE_* encoding of binary search table,
1138 or DW_EH_PE_omit if not present.
1139 DW_EH_PE_datarel is using address of
1140 .eh_frame_hdr section start as base)
1141 [encoded] eh_frame_ptr (pointer to start of .eh_frame section)
1142 optionally followed by:
1143 [encoded] fde_count (total number of FDEs in .eh_frame section)
1144 fde_count x [encoded] initial_loc, fde
1145 (array of encoded pairs containing
1146 FDE initial_location field and FDE address,
1147 sorted by increasing initial_loc) */
1149 boolean
1150 _bfd_elf_write_section_eh_frame_hdr (abfd, sec)
1151 bfd *abfd;
1152 asection *sec;
1154 struct eh_frame_hdr_info *hdr_info;
1155 unsigned int ptr_size;
1156 bfd_byte *contents;
1157 asection *eh_frame_sec;
1158 bfd_size_type size;
1160 ptr_size = (elf_elfheader (sec->owner)->e_ident[EI_CLASS]
1161 == ELFCLASS64) ? 8 : 4;
1163 BFD_ASSERT (elf_section_data (sec)->sec_info_type
1164 == ELF_INFO_TYPE_EH_FRAME_HDR);
1165 hdr_info = (struct eh_frame_hdr_info *)
1166 elf_section_data (sec)->sec_info;
1167 if (hdr_info->strip)
1168 return true;
1170 size = EH_FRAME_HDR_SIZE;
1171 if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
1172 size += 4 + hdr_info->fde_count * 8;
1173 contents = bfd_malloc (size);
1174 if (contents == NULL)
1175 return false;
1177 eh_frame_sec = bfd_get_section_by_name (abfd, ".eh_frame");
1178 if (eh_frame_sec == NULL)
1179 return false;
1181 memset (contents, 0, EH_FRAME_HDR_SIZE);
1182 contents[0] = 1; /* Version */
1183 contents[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4; /* .eh_frame offset */
1184 if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
1186 contents[2] = DW_EH_PE_udata4; /* FDE count encoding */
1187 contents[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4; /* search table enc */
1189 else
1191 contents[2] = DW_EH_PE_omit;
1192 contents[3] = DW_EH_PE_omit;
1194 bfd_put_32 (abfd, eh_frame_sec->vma - sec->output_section->vma - 4,
1195 contents + 4);
1196 if (contents[2] != DW_EH_PE_omit)
1198 unsigned int i;
1200 bfd_put_32 (abfd, hdr_info->fde_count, contents + EH_FRAME_HDR_SIZE);
1201 qsort (hdr_info->array, hdr_info->fde_count, sizeof (*hdr_info->array),
1202 vma_compare);
1203 for (i = 0; i < hdr_info->fde_count; i++)
1205 bfd_put_32 (abfd,
1206 hdr_info->array[i].initial_loc
1207 - sec->output_section->vma,
1208 contents + EH_FRAME_HDR_SIZE + i * 8 + 4);
1209 bfd_put_32 (abfd,
1210 hdr_info->array[i].fde - sec->output_section->vma,
1211 contents + EH_FRAME_HDR_SIZE + i * 8 + 8);
1215 return bfd_set_section_contents (abfd, sec->output_section,
1216 contents, (file_ptr) sec->output_offset,
1217 sec->_cooked_size);