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. */
25 #include "elf/dwarf2.h"
27 #define EH_FRAME_HDR_SIZE 8
37 struct cie_header hdr
;
38 unsigned char version
;
39 unsigned char augmentation
[20];
40 unsigned int code_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];
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;
70 struct eh_frame_sec_info
74 struct eh_cie_fde entry
[1];
77 struct eh_frame_array_ent
83 struct eh_frame_hdr_info
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. */
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
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
));
112 /* Helper function for reading uleb128 encoded data. */
115 read_unsigned_leb128 (abfd
, buf
, bytes_read_ptr
)
116 bfd
*abfd ATTRIBUTE_UNUSED
;
118 unsigned int *bytes_read_ptr
;
121 unsigned int num_read
;
130 byte
= bfd_get_8 (abfd
, (bfd_byte
*) buf
);
133 result
|= (((bfd_vma
) byte
& 0x7f) << shift
);
137 * bytes_read_ptr
= num_read
;
141 /* Helper function for reading sleb128 encoded data. */
143 static bfd_signed_vma
144 read_signed_leb128 (abfd
, buf
, bytes_read_ptr
)
145 bfd
*abfd ATTRIBUTE_UNUSED
;
147 unsigned int * bytes_read_ptr
;
159 byte
= bfd_get_8 (abfd
, (bfd_byte
*) buf
);
162 result
|= (((bfd_vma
) byte
& 0x7f) << shift
);
167 result
|= (((bfd_vma
) -1) << (shift
- 7)) << 7;
168 * bytes_read_ptr
= num_read
;
172 #define read_uleb128(VAR, BUF) \
175 (VAR) = read_unsigned_leb128 (abfd, buf, &leb128_tmp); \
176 (BUF) += leb128_tmp; \
180 #define read_sleb128(VAR, BUF) \
183 (VAR) = read_signed_leb128 (abfd, buf, &leb128_tmp); \
184 (BUF) += leb128_tmp; \
188 /* Return 0 if either encoding is variable width, or not yet known to bfd. */
191 int get_DW_EH_PE_width (encoding
, ptr_size
)
192 int encoding
, ptr_size
;
194 /* DW_EH_PE_ values of 0x60 and 0x70 weren't defined at the time .eh_frame
196 if ((encoding
& 0x60) == 0x60)
199 switch (encoding
& 7)
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
;
212 /* Read a width sized value from memory. */
215 read_value (abfd
, buf
, width
)
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;
233 /* Store a width sized value to memory. */
236 write_value (abfd
, buf
, value
, width
)
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 ();
251 /* Return zero if C1 and C2 CIEs can be merged. */
254 int cie_compare (c1
, c2
)
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)
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
285 _bfd_elf_discard_section_eh_frame (abfd
, info
, sec
, ehdrsec
,
286 reloc_symbol_deleted_p
, cookie
)
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
;
293 bfd_byte
*ehbuf
= NULL
, *buf
;
294 bfd_byte
*last_cie
, *last_fde
;
295 struct cie_header hdr
;
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
;
305 if (sec
->_raw_size
== 0)
307 /* This file does not contain .eh_frame information. */
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. */
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
);
330 if (! bfd_get_section_contents (abfd
, sec
, ehbuf
, (bfd_vma
) 0,
334 if (sec
->_raw_size
>= 4
335 && bfd_get_32 (abfd
, ehbuf
) == 0
336 && cookie
->rel
== cookie
->relend
)
338 /* Empty .eh_frame section. */
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
)
348 ptr_size
= (elf_elfheader (abfd
)->e_ident
[EI_CLASS
]
349 == ELFCLASS64
) ? 8 : 4;
353 memset (&cie
, 0, sizeof (cie
));
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
)
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))) \
370 #define SKIP_RELOCS(buf) \
371 while (cookie->rel < cookie->relend \
372 && (cookie->rel->r_offset \
373 < (bfd_size_type) ((buf) - ehbuf))) \
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)
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
)
395 memset (&sec_info
->entry
[sec_info
->alloced
], 0,
396 100 * sizeof (struct eh_cie_fde
));
397 sec_info
->alloced
+= 100;
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;
407 if ((bfd_size_type
) (buf
+ 4 - ehbuf
) > sec
->_raw_size
)
408 /* No space for CIE/FDE header length. */
411 hdr
.length
= bfd_get_32 (abfd
, buf
);
412 if (hdr
.length
== 0xffffffff)
413 /* 64-bit .eh_frame is not supported. */
416 if ((bfd_size_type
) (buf
- ehbuf
) + hdr
.length
> sec
->_raw_size
)
417 /* CIE/FDE not contained fully in this .eh_frame input section. */
420 sec_info
->entry
[sec_info
->count
].offset
= last_fde
- ehbuf
;
421 sec_info
->entry
[sec_info
->count
].size
= 4 + hdr
.length
;
425 /* CIE with length 0 must be only the last in the section. */
426 if ((bfd_size_type
) (buf
- ehbuf
) < sec
->_raw_size
)
428 ENSURE_NO_RELOCS (buf
);
430 /* Now just finish last encountered CIE processing and break
432 hdr
.id
= (unsigned int) -1;
436 hdr
.id
= bfd_get_32 (abfd
, buf
);
438 if (hdr
.id
== (unsigned int) -1)
443 if (hdr
.id
== 0 || hdr
.id
== (unsigned int) -1)
445 unsigned int initial_insn_length
;
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
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
;
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
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
;
477 if (hdr
.id
== (unsigned int) -1)
480 last_cie_ndx
= sec_info
->count
;
481 sec_info
->entry
[sec_info
->count
].cie
= 1;
484 memset (&cie
, 0, sizeof (cie
));
486 cie
.version
= *buf
++;
488 /* Cannot handle unknown versions. */
489 if (cie
.version
!= 1)
491 if (strlen (buf
) > sizeof (cie
.augmentation
) - 1)
494 strcpy (cie
.augmentation
, buf
);
495 buf
= strchr (buf
, '\0') + 1;
496 ENSURE_NO_RELOCS (buf
);
497 if (buf
[0] == 'e' && buf
[1] == 'h')
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.
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')
524 read_uleb128 (cie
.augmentation_size
, buf
);
525 ENSURE_NO_RELOCS (buf
);
532 cie
.lsda_encoding
= *buf
++;
533 ENSURE_NO_RELOCS (buf
);
534 if (get_DW_EH_PE_width (cie
.lsda_encoding
, ptr_size
) == 0)
538 cie
.fde_encoding
= *buf
++;
539 ENSURE_NO_RELOCS (buf
);
540 if (get_DW_EH_PE_width (cie
.fde_encoding
, ptr_size
) == 0)
547 cie
.per_encoding
= *buf
++;
548 per_width
= get_DW_EH_PE_width (cie
.per_encoding
,
552 if ((cie
.per_encoding
& 0xf0) == DW_EH_PE_aligned
)
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
559 if (GET_RELOC (buf
) != NULL
)
561 unsigned long r_symndx
;
565 r_symndx
= ELF64_R_SYM (cookie
->rel
->r_info
);
568 r_symndx
= ELF32_R_SYM (cookie
->rel
->r_info
);
569 if (r_symndx
>= cookie
->locsymcount
)
571 struct elf_link_hash_entry
*h
;
573 r_symndx
-= cookie
->extsymoff
;
574 h
= cookie
->sym_hashes
[r_symndx
];
576 while (h
->root
.type
== bfd_link_hash_indirect
577 || h
->root
.type
== bfd_link_hash_warning
)
578 h
= (struct elf_link_hash_entry
*)
589 /* Unrecognized augmentation. Better bail out. */
594 /* For shared libraries, try to get rid of as many RELATIVE relocs
597 && (cie
.fde_encoding
& 0xf0) == DW_EH_PE_absptr
)
598 cie
.make_relative
= 1;
601 && (cie
.lsda_encoding
& 0xf0) == DW_EH_PE_absptr
)
602 cie
.make_lsda_relative
= 1;
604 /* If FDE encoding was not specified, it defaults to
606 if (cie
.fde_encoding
== DW_EH_PE_omit
)
607 cie
.fde_encoding
= DW_EH_PE_absptr
;
609 initial_insn_length
= cie
.hdr
.length
- (buf
- last_fde
- 4);
610 if (initial_insn_length
<= 50)
612 cie
.initial_insn_length
= initial_insn_length
;
613 memcpy (cie
.initial_instructions
, buf
, initial_insn_length
);
615 buf
+= initial_insn_length
;
616 ENSURE_NO_RELOCS (buf
);
621 /* Ensure this FDE uses the last CIE encountered. */
623 || hdr
.id
!= (unsigned int) (buf
- 4 - last_cie
))
626 ENSURE_NO_RELOCS (buf
);
627 if (GET_RELOC (buf
) == NULL
)
628 /* This should not happen. */
630 if ((*reloc_symbol_deleted_p
) (buf
- ehbuf
, cookie
))
632 /* This is a FDE against discarded section, it should
634 new_size
-= hdr
.length
+ 4;
635 sec_info
->entry
[sec_info
->count
].removed
= 1;
640 && (((cie
.fde_encoding
& 0xf0) == DW_EH_PE_absptr
641 && cie
.make_relative
== 0)
642 || (cie
.fde_encoding
& 0xf0) == DW_EH_PE_aligned
))
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;
651 hdr_info
->fde_count
++;
653 if (cie
.lsda_encoding
!= DW_EH_PE_omit
)
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
);
665 buf
= last_fde
+ 4 + hdr
.length
;
669 sec_info
->entry
[sec_info
->count
].fde_encoding
= cie
.fde_encoding
;
670 sec_info
->entry
[sec_info
->count
].lsda_encoding
= cie
.lsda_encoding
;
674 elf_section_data (sec
)->sec_info
= sec_info
;
675 elf_section_data (sec
)->sec_info_type
= ELF_INFO_TYPE_EH_FRAME
;
677 /* Ok, now we can assign new offsets. */
680 for (i
= 0; i
< sec_info
->count
; i
++)
682 if (! sec_info
->entry
[i
].removed
)
684 sec_info
->entry
[i
].new_offset
= offset
;
685 offset
+= sec_info
->entry
[i
].size
;
686 if (sec_info
->entry
[i
].cie
)
689 make_relative
= sec_info
->entry
[i
].make_relative
;
690 make_lsda_relative
= sec_info
->entry
[i
].make_lsda_relative
;
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;
699 else if (sec_info
->entry
[i
].cie
&& sec_info
->entry
[i
].sec
== sec
)
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
;
708 if (hdr_info
->last_cie_sec
== sec
)
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
;
715 /* FIXME: Currently it is not possible to shrink sections to zero size at
716 this point, so build a fake minimal CIE. */
720 /* Shrink the sec as needed. */
721 sec
->_cooked_size
= new_size
;
722 if (sec
->_cooked_size
== 0)
723 sec
->flags
|= SEC_EXCLUDE
;
726 return new_size
!= sec
->_raw_size
;
733 hdr_info
->table
= false;
734 hdr_info
->last_cie
.hdr
.length
= 0;
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. */
743 _bfd_elf_discard_section_eh_frame_hdr (abfd
, info
, sec
)
745 struct bfd_link_info
*info
;
748 struct eh_frame_hdr_info
*hdr_info
;
750 if ((elf_section_data (sec
)->sec_info_type
751 != ELF_INFO_TYPE_EH_FRAME_HDR
)
752 || ! info
->eh_frame_hdr
)
754 _bfd_strip_section_from_output (info
, sec
);
758 hdr_info
= (struct eh_frame_hdr_info
*)
759 elf_section_data (sec
)->sec_info
;
762 sec
->_cooked_size
= EH_FRAME_HDR_SIZE
;
764 sec
->_cooked_size
+= 4 + hdr_info
->fde_count
* 8;
766 /* Request program headers to be recalculated. */
767 elf_tdata (abfd
)->program_header_size
= 0;
768 elf_tdata (abfd
)->eh_frame_hdr
= true;
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. */
778 _bfd_elf_maybe_strip_eh_frame_hdr (info
)
779 struct bfd_link_info
*info
;
783 struct eh_frame_hdr_info
*hdr_info
;
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
))
790 = bfd_zmalloc (sizeof (struct eh_frame_hdr_info
));
791 if (hdr_info
== NULL
)
794 elf_section_data (sec
)->sec_info
= hdr_info
;
795 elf_section_data (sec
)->sec_info_type
= ELF_INFO_TYPE_EH_FRAME_HDR
;
798 if (info
->eh_frame_hdr
)
799 for (abfd
= info
->input_bfds
; abfd
!= NULL
; abfd
= abfd
->link_next
)
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
))
810 _bfd_strip_section_from_output (info
, sec
);
811 hdr_info
->strip
= true;
814 hdr_info
->table
= true;
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. */
824 _bfd_elf_eh_frame_section_offset (output_bfd
, sec
, offset
)
825 bfd
*output_bfd ATTRIBUTE_UNUSED
;
829 struct eh_frame_sec_info
*sec_info
;
830 unsigned int lo
, hi
, mid
;
832 if (elf_section_data (sec
)->sec_info_type
!= ELF_INFO_TYPE_EH_FRAME
)
834 sec_info
= (struct eh_frame_sec_info
*)
835 elf_section_data (sec
)->sec_info
;
837 if (offset
>= sec
->_raw_size
)
838 return offset
- (sec
->_cooked_size
- sec
->_raw_size
);
841 hi
= sec_info
->count
;
846 if (offset
< sec_info
->entry
[mid
].offset
)
849 >= sec_info
->entry
[mid
].offset
+ sec_info
->entry
[mid
].size
)
855 BFD_ASSERT (lo
< hi
);
857 /* FDE or CIE was removed. */
858 if (sec_info
->entry
[mid
].removed
)
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)
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
873 == (sec_info
->entry
[mid
].offset
+ 8
874 + sec_info
->entry
[mid
].lsda_offset
)))
877 return (offset
+ sec_info
->entry
[mid
].new_offset
878 - sec_info
->entry
[mid
].offset
);
881 /* Write out .eh_frame section. This is called with the relocated
885 _bfd_elf_write_section_eh_frame (abfd
, sec
, ehdrsec
, contents
)
887 asection
*sec
, *ehdrsec
;
890 struct eh_frame_sec_info
*sec_info
;
891 struct eh_frame_hdr_info
*hdr_info
;
894 unsigned int leb128_tmp
;
895 unsigned int cie_offset
= 0;
896 unsigned int ptr_size
;
898 ptr_size
= (elf_elfheader (sec
->owner
)->e_ident
[EI_CLASS
]
899 == ELFCLASS64
) ? 8 : 4;
901 if (elf_section_data (sec
)->sec_info_type
!= ELF_INFO_TYPE_EH_FRAME
)
902 return bfd_set_section_contents (abfd
, sec
->output_section
,
904 (file_ptr
) sec
->output_offset
,
906 sec_info
= (struct eh_frame_sec_info
*)
907 elf_section_data (sec
)->sec_info
;
910 && (elf_section_data (ehdrsec
)->sec_info_type
911 == ELF_INFO_TYPE_EH_FRAME_HDR
))
913 hdr_info
= (struct eh_frame_hdr_info
*)
914 elf_section_data (ehdrsec
)->sec_info
;
915 if (hdr_info
->table
&& hdr_info
->array
== NULL
)
917 = bfd_malloc (hdr_info
->fde_count
* sizeof(*hdr_info
->array
));
918 if (hdr_info
->array
== NULL
)
923 for (i
= 0; i
< sec_info
->count
; ++i
)
925 if (sec_info
->entry
[i
].removed
)
927 if (sec_info
->entry
[i
].cie
)
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
932 if (sec_info
->entry
[i
].sec
== NULL
)
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
);
946 if (sec_info
->entry
[i
].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
)
956 unsigned int dummy
, per_width
, per_encoding
;
958 /* Need to find 'R' or 'L' augmentation's argument and modify
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. */
967 buf
= strchr (buf
, '\0') + 1;
968 read_uleb128 (dummy
, buf
);
969 read_sleb128 (dummy
, buf
);
970 read_uleb128 (dummy
, buf
);
973 read_uleb128 (dummy
, buf
);
983 BFD_ASSERT (*buf
== sec_info
->entry
[i
].lsda_encoding
);
984 *buf
|= DW_EH_PE_pcrel
;
990 per_encoding
= *buf
++;
991 per_width
= get_DW_EH_PE_width (per_encoding
,
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
)
998 + ((buf
- contents
+ per_width
- 1)
999 & ~((bfd_size_type
) per_width
- 1)));
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
);
1015 BFD_ASSERT (*buf
== sec_info
->entry
[i
].fde_encoding
);
1016 *buf
|= DW_EH_PE_pcrel
;
1026 else if (sec_info
->entry
[i
].size
> 4)
1029 bfd_vma value
= 0, address
;
1032 buf
= contents
+ sec_info
->entry
[i
].offset
;
1036 sec_info
->entry
[i
].new_offset
+ 4 - cie_offset
, buf
);
1038 width
= get_DW_EH_PE_width (sec_info
->entry
[i
].fde_encoding
,
1040 address
= value
= read_value (abfd
, buf
, width
);
1043 switch (sec_info
->entry
[i
].fde_encoding
& 0xf0)
1045 case DW_EH_PE_indirect
:
1046 case DW_EH_PE_textrel
:
1047 BFD_ASSERT (hdr_info
== NULL
);
1049 case DW_EH_PE_datarel
:
1051 asection
*got
= bfd_get_section_by_name (abfd
, ".got");
1053 BFD_ASSERT (got
!= NULL
);
1054 address
+= got
->vma
;
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);
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
);
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
);
1078 if ((sec_info
->entry
[i
].lsda_encoding
& 0xf0) == DW_EH_PE_pcrel
1079 || sec_info
->entry
[i
].make_lsda_relative
)
1081 buf
+= sec_info
->entry
[i
].lsda_offset
;
1082 width
= get_DW_EH_PE_width (sec_info
->entry
[i
].lsda_encoding
,
1084 value
= read_value (abfd
, buf
, width
);
1087 if ((sec_info
->entry
[i
].lsda_encoding
& 0xf0)
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
);
1100 /* Terminating FDE must be at the end of .eh_frame section only. */
1101 BFD_ASSERT (i
== sec_info
->count
- 1);
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
;
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)
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 */
1121 BFD_ASSERT ((bfd_size_type
) (p
- contents
) == sec
->_cooked_size
);
1123 return bfd_set_section_contents (abfd
, sec
->output_section
,
1124 contents
, (file_ptr
) sec
->output_offset
,
1128 /* Helper function used to sort .eh_frame_hdr search table by increasing
1129 VMA of FDE initial location. */
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
)
1140 if (p
->initial_loc
< q
->initial_loc
)
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
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
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) */
1168 _bfd_elf_write_section_eh_frame_hdr (abfd
, sec
)
1172 struct eh_frame_hdr_info
*hdr_info
;
1174 asection
*eh_frame_sec
;
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
)
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
)
1191 eh_frame_sec
= bfd_get_section_by_name (abfd
, ".eh_frame");
1192 if (eh_frame_sec
== NULL
)
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
)
1200 contents
[2] = DW_EH_PE_udata4
; /* FDE count encoding */
1201 contents
[3] = DW_EH_PE_datarel
| DW_EH_PE_sdata4
; /* search table enc */
1205 contents
[2] = DW_EH_PE_omit
;
1206 contents
[3] = DW_EH_PE_omit
;
1208 bfd_put_32 (abfd
, eh_frame_sec
->vma
- sec
->output_section
->vma
- 4,
1210 if (contents
[2] != DW_EH_PE_omit
)
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
),
1217 for (i
= 0; i
< hdr_info
->fde_count
; i
++)
1220 hdr_info
->array
[i
].initial_loc
1221 - sec
->output_section
->vma
,
1222 contents
+ EH_FRAME_HDR_SIZE
+ i
* 8 + 4);
1224 hdr_info
->array
[i
].fde
- sec
->output_section
->vma
,
1225 contents
+ EH_FRAME_HDR_SIZE
+ i
* 8 + 8);
1229 return bfd_set_section_contents (abfd
, sec
->output_section
,
1230 contents
, (file_ptr
) sec
->output_offset
,