1 /* .eh_frame section optimization.
2 Copyright 2001, 2002, 2003 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
29 static bfd_vma read_unsigned_leb128
30 PARAMS ((bfd
*, char *, unsigned int *));
31 static bfd_signed_vma read_signed_leb128
32 PARAMS ((bfd
*, char *, unsigned int *));
33 static int get_DW_EH_PE_width
35 static bfd_vma read_value
36 PARAMS ((bfd
*, bfd_byte
*, int, int));
37 static void write_value
38 PARAMS ((bfd
*, bfd_byte
*, bfd_vma
, int));
39 static int cie_compare
40 PARAMS ((struct cie
*, struct cie
*));
41 static int vma_compare
42 PARAMS ((const PTR a
, const PTR b
));
44 /* Helper function for reading uleb128 encoded data. */
47 read_unsigned_leb128 (abfd
, buf
, bytes_read_ptr
)
48 bfd
*abfd ATTRIBUTE_UNUSED
;
50 unsigned int *bytes_read_ptr
;
53 unsigned int num_read
;
62 byte
= bfd_get_8 (abfd
, (bfd_byte
*) buf
);
65 result
|= (((bfd_vma
) byte
& 0x7f) << shift
);
69 * bytes_read_ptr
= num_read
;
73 /* Helper function for reading sleb128 encoded data. */
76 read_signed_leb128 (abfd
, buf
, bytes_read_ptr
)
77 bfd
*abfd ATTRIBUTE_UNUSED
;
79 unsigned int * bytes_read_ptr
;
91 byte
= bfd_get_8 (abfd
, (bfd_byte
*) buf
);
94 result
|= (((bfd_vma
) byte
& 0x7f) << shift
);
99 result
|= (((bfd_vma
) -1) << (shift
- 7)) << 7;
100 * bytes_read_ptr
= num_read
;
104 #define read_uleb128(VAR, BUF) \
107 (VAR) = read_unsigned_leb128 (abfd, buf, &leb128_tmp); \
108 (BUF) += leb128_tmp; \
112 #define read_sleb128(VAR, BUF) \
115 (VAR) = read_signed_leb128 (abfd, buf, &leb128_tmp); \
116 (BUF) += leb128_tmp; \
120 /* Return 0 if either encoding is variable width, or not yet known to bfd. */
123 int get_DW_EH_PE_width (encoding
, ptr_size
)
124 int encoding
, ptr_size
;
126 /* DW_EH_PE_ values of 0x60 and 0x70 weren't defined at the time .eh_frame
128 if ((encoding
& 0x60) == 0x60)
131 switch (encoding
& 7)
133 case DW_EH_PE_udata2
: return 2;
134 case DW_EH_PE_udata4
: return 4;
135 case DW_EH_PE_udata8
: return 8;
136 case DW_EH_PE_absptr
: return ptr_size
;
144 #define get_DW_EH_PE_signed(encoding) (((encoding) & DW_EH_PE_signed) != 0)
146 /* Read a width sized value from memory. */
149 read_value (abfd
, buf
, width
, is_signed
)
161 value
= bfd_get_signed_16 (abfd
, buf
);
163 value
= bfd_get_16 (abfd
, buf
);
167 value
= bfd_get_signed_32 (abfd
, buf
);
169 value
= bfd_get_32 (abfd
, buf
);
173 value
= bfd_get_signed_64 (abfd
, buf
);
175 value
= bfd_get_64 (abfd
, buf
);
185 /* Store a width sized value to memory. */
188 write_value (abfd
, buf
, value
, width
)
196 case 2: bfd_put_16 (abfd
, value
, buf
); break;
197 case 4: bfd_put_32 (abfd
, value
, buf
); break;
198 case 8: bfd_put_64 (abfd
, value
, buf
); break;
199 default: BFD_FAIL ();
203 /* Return zero if C1 and C2 CIEs can be merged. */
206 int cie_compare (c1
, c2
)
209 if (c1
->hdr
.length
== c2
->hdr
.length
210 && c1
->version
== c2
->version
211 && strcmp (c1
->augmentation
, c2
->augmentation
) == 0
212 && strcmp (c1
->augmentation
, "eh") != 0
213 && c1
->code_align
== c2
->code_align
214 && c1
->data_align
== c2
->data_align
215 && c1
->ra_column
== c2
->ra_column
216 && c1
->augmentation_size
== c2
->augmentation_size
217 && c1
->personality
== c2
->personality
218 && c1
->per_encoding
== c2
->per_encoding
219 && c1
->lsda_encoding
== c2
->lsda_encoding
220 && c1
->fde_encoding
== c2
->fde_encoding
221 && (c1
->initial_insn_length
222 == c2
->initial_insn_length
)
223 && memcmp (c1
->initial_instructions
,
224 c2
->initial_instructions
,
225 c1
->initial_insn_length
) == 0)
231 /* This function is called for each input file before the .eh_frame
232 section is relocated. It discards duplicate CIEs and FDEs for discarded
233 functions. The function returns TRUE iff any entries have been
237 _bfd_elf_discard_section_eh_frame (abfd
, info
, sec
,
238 reloc_symbol_deleted_p
, cookie
)
240 struct bfd_link_info
*info
;
242 bfd_boolean (*reloc_symbol_deleted_p
) PARAMS ((bfd_vma
, PTR
));
243 struct elf_reloc_cookie
*cookie
;
245 bfd_byte
*ehbuf
= NULL
, *buf
;
246 bfd_byte
*last_cie
, *last_fde
;
247 struct cie_header hdr
;
249 struct elf_link_hash_table
*htab
;
250 struct eh_frame_hdr_info
*hdr_info
;
251 struct eh_frame_sec_info
*sec_info
= NULL
;
252 unsigned int leb128_tmp
;
253 unsigned int cie_usage_count
, last_cie_ndx
, i
, offset
;
254 unsigned int make_relative
, make_lsda_relative
;
255 bfd_size_type new_size
;
256 unsigned int ptr_size
;
258 if (sec
->_raw_size
== 0)
260 /* This file does not contain .eh_frame information. */
264 if ((sec
->output_section
!= NULL
265 && bfd_is_abs_section (sec
->output_section
)))
267 /* At least one of the sections is being discarded from the
268 link, so we should just ignore them. */
272 htab
= elf_hash_table (info
);
273 hdr_info
= &htab
->eh_info
;
275 /* Read the frame unwind information from abfd. */
277 ehbuf
= (bfd_byte
*) bfd_malloc (sec
->_raw_size
);
281 if (! bfd_get_section_contents (abfd
, sec
, ehbuf
, (bfd_vma
) 0,
285 if (sec
->_raw_size
>= 4
286 && bfd_get_32 (abfd
, ehbuf
) == 0
287 && cookie
->rel
== cookie
->relend
)
289 /* Empty .eh_frame section. */
294 /* If .eh_frame section size doesn't fit into int, we cannot handle
295 it (it would need to use 64-bit .eh_frame format anyway). */
296 if (sec
->_raw_size
!= (unsigned int) sec
->_raw_size
)
299 ptr_size
= (elf_elfheader (abfd
)->e_ident
[EI_CLASS
]
300 == ELFCLASS64
) ? 8 : 4;
304 memset (&cie
, 0, sizeof (cie
));
306 new_size
= sec
->_raw_size
;
307 make_relative
= hdr_info
->last_cie
.make_relative
;
308 make_lsda_relative
= hdr_info
->last_cie
.make_lsda_relative
;
309 sec_info
= bfd_zmalloc (sizeof (struct eh_frame_sec_info
)
310 + 99 * sizeof (struct eh_cie_fde
));
311 if (sec_info
== NULL
)
313 sec_info
->alloced
= 100;
315 #define ENSURE_NO_RELOCS(buf) \
316 if (cookie->rel < cookie->relend \
317 && (cookie->rel->r_offset \
318 < (bfd_size_type) ((buf) - ehbuf)) \
319 && cookie->rel->r_info != 0) \
322 #define SKIP_RELOCS(buf) \
323 while (cookie->rel < cookie->relend \
324 && (cookie->rel->r_offset \
325 < (bfd_size_type) ((buf) - ehbuf))) \
328 #define GET_RELOC(buf) \
329 ((cookie->rel < cookie->relend \
330 && (cookie->rel->r_offset \
331 == (bfd_size_type) ((buf) - ehbuf))) \
332 ? cookie->rel : NULL)
338 if (sec_info
->count
== sec_info
->alloced
)
340 sec_info
= bfd_realloc (sec_info
,
341 sizeof (struct eh_frame_sec_info
)
342 + (sec_info
->alloced
+ 99)
343 * sizeof (struct eh_cie_fde
));
344 if (sec_info
== NULL
)
347 memset (&sec_info
->entry
[sec_info
->alloced
], 0,
348 100 * sizeof (struct eh_cie_fde
));
349 sec_info
->alloced
+= 100;
353 /* If we are at the end of the section, we still need to decide
354 on whether to output or discard last encountered CIE (if any). */
355 if ((bfd_size_type
) (buf
- ehbuf
) == sec
->_raw_size
)
356 hdr
.id
= (unsigned int) -1;
359 if ((bfd_size_type
) (buf
+ 4 - ehbuf
) > sec
->_raw_size
)
360 /* No space for CIE/FDE header length. */
363 hdr
.length
= bfd_get_32 (abfd
, buf
);
364 if (hdr
.length
== 0xffffffff)
365 /* 64-bit .eh_frame is not supported. */
368 if ((bfd_size_type
) (buf
- ehbuf
) + hdr
.length
> sec
->_raw_size
)
369 /* CIE/FDE not contained fully in this .eh_frame input section. */
372 sec_info
->entry
[sec_info
->count
].offset
= last_fde
- ehbuf
;
373 sec_info
->entry
[sec_info
->count
].size
= 4 + hdr
.length
;
377 /* CIE with length 0 must be only the last in the section. */
378 if ((bfd_size_type
) (buf
- ehbuf
) < sec
->_raw_size
)
380 ENSURE_NO_RELOCS (buf
);
382 /* Now just finish last encountered CIE processing and break
384 hdr
.id
= (unsigned int) -1;
388 hdr
.id
= bfd_get_32 (abfd
, buf
);
390 if (hdr
.id
== (unsigned int) -1)
395 if (hdr
.id
== 0 || hdr
.id
== (unsigned int) -1)
397 unsigned int initial_insn_length
;
400 if (last_cie
!= NULL
)
402 /* Now check if this CIE is identical to the last CIE,
403 in which case we can remove it provided we adjust
404 all FDEs. Also, it can be removed if we have removed
405 all FDEs using it. */
406 if ((!info
->relocateable
407 && cie_compare (&cie
, &hdr_info
->last_cie
) == 0)
408 || cie_usage_count
== 0)
410 new_size
-= cie
.hdr
.length
+ 4;
411 sec_info
->entry
[last_cie_ndx
].removed
= 1;
412 sec_info
->entry
[last_cie_ndx
].sec
= hdr_info
->last_cie_sec
;
413 sec_info
->entry
[last_cie_ndx
].new_offset
414 = hdr_info
->last_cie_offset
;
418 hdr_info
->last_cie
= cie
;
419 hdr_info
->last_cie_sec
= sec
;
420 hdr_info
->last_cie_offset
= last_cie
- ehbuf
;
421 sec_info
->entry
[last_cie_ndx
].make_relative
423 sec_info
->entry
[last_cie_ndx
].make_lsda_relative
424 = cie
.make_lsda_relative
;
425 sec_info
->entry
[last_cie_ndx
].per_encoding_relative
426 = (cie
.per_encoding
& 0x70) == DW_EH_PE_pcrel
;
430 if (hdr
.id
== (unsigned int) -1)
433 last_cie_ndx
= sec_info
->count
;
434 sec_info
->entry
[sec_info
->count
].cie
= 1;
437 memset (&cie
, 0, sizeof (cie
));
439 cie
.version
= *buf
++;
441 /* Cannot handle unknown versions. */
442 if (cie
.version
!= 1)
444 if (strlen (buf
) > sizeof (cie
.augmentation
) - 1)
447 strcpy (cie
.augmentation
, buf
);
448 buf
= strchr (buf
, '\0') + 1;
449 ENSURE_NO_RELOCS (buf
);
450 if (buf
[0] == 'e' && buf
[1] == 'h')
452 /* GCC < 3.0 .eh_frame CIE */
453 /* We cannot merge "eh" CIEs because __EXCEPTION_TABLE__
454 is private to each CIE, so we don't need it for anything.
459 read_uleb128 (cie
.code_align
, buf
);
460 read_sleb128 (cie
.data_align
, buf
);
461 /* Note - in DWARF2 the return address column is an unsigned byte.
462 In DWARF3 it is a ULEB128. We are following DWARF3. For most
463 ports this will not matter as the value will be less than 128.
464 For the others (eg FRV, SH, MMIX, IA64) they need a fixed GCC
465 which conforms to the DWARF3 standard. */
466 read_uleb128 (cie
.ra_column
, buf
);
467 ENSURE_NO_RELOCS (buf
);
468 cie
.lsda_encoding
= DW_EH_PE_omit
;
469 cie
.fde_encoding
= DW_EH_PE_omit
;
470 cie
.per_encoding
= DW_EH_PE_omit
;
471 aug
= cie
.augmentation
;
472 if (aug
[0] != 'e' || aug
[1] != 'h')
477 read_uleb128 (cie
.augmentation_size
, buf
);
478 ENSURE_NO_RELOCS (buf
);
485 cie
.lsda_encoding
= *buf
++;
486 ENSURE_NO_RELOCS (buf
);
487 if (get_DW_EH_PE_width (cie
.lsda_encoding
, ptr_size
) == 0)
491 cie
.fde_encoding
= *buf
++;
492 ENSURE_NO_RELOCS (buf
);
493 if (get_DW_EH_PE_width (cie
.fde_encoding
, ptr_size
) == 0)
500 cie
.per_encoding
= *buf
++;
501 per_width
= get_DW_EH_PE_width (cie
.per_encoding
,
505 if ((cie
.per_encoding
& 0xf0) == DW_EH_PE_aligned
)
507 + ((buf
- ehbuf
+ per_width
- 1)
508 & ~((bfd_size_type
) per_width
- 1)));
509 ENSURE_NO_RELOCS (buf
);
510 /* Ensure we have a reloc here, against
512 if (GET_RELOC (buf
) != NULL
)
514 unsigned long r_symndx
;
518 r_symndx
= ELF64_R_SYM (cookie
->rel
->r_info
);
521 r_symndx
= ELF32_R_SYM (cookie
->rel
->r_info
);
522 if (r_symndx
>= cookie
->locsymcount
)
524 struct elf_link_hash_entry
*h
;
526 r_symndx
-= cookie
->extsymoff
;
527 h
= cookie
->sym_hashes
[r_symndx
];
529 while (h
->root
.type
== bfd_link_hash_indirect
530 || h
->root
.type
== bfd_link_hash_warning
)
531 h
= (struct elf_link_hash_entry
*)
542 /* Unrecognized augmentation. Better bail out. */
547 /* For shared libraries, try to get rid of as many RELATIVE relocs
550 && (cie
.fde_encoding
& 0xf0) == DW_EH_PE_absptr
)
551 cie
.make_relative
= 1;
554 && (cie
.lsda_encoding
& 0xf0) == DW_EH_PE_absptr
)
555 cie
.make_lsda_relative
= 1;
557 /* If FDE encoding was not specified, it defaults to
559 if (cie
.fde_encoding
== DW_EH_PE_omit
)
560 cie
.fde_encoding
= DW_EH_PE_absptr
;
562 initial_insn_length
= cie
.hdr
.length
- (buf
- last_fde
- 4);
563 if (initial_insn_length
<= 50)
565 cie
.initial_insn_length
= initial_insn_length
;
566 memcpy (cie
.initial_instructions
, buf
, initial_insn_length
);
568 buf
+= initial_insn_length
;
569 ENSURE_NO_RELOCS (buf
);
574 /* Ensure this FDE uses the last CIE encountered. */
576 || hdr
.id
!= (unsigned int) (buf
- 4 - last_cie
))
579 ENSURE_NO_RELOCS (buf
);
580 if (GET_RELOC (buf
) == NULL
)
581 /* This should not happen. */
583 if ((*reloc_symbol_deleted_p
) (buf
- ehbuf
, cookie
))
585 /* This is a FDE against a discarded section. It should
587 new_size
-= hdr
.length
+ 4;
588 sec_info
->entry
[sec_info
->count
].removed
= 1;
593 && (((cie
.fde_encoding
& 0xf0) == DW_EH_PE_absptr
594 && cie
.make_relative
== 0)
595 || (cie
.fde_encoding
& 0xf0) == DW_EH_PE_aligned
))
597 /* If a shared library uses absolute pointers
598 which we cannot turn into PC relative,
599 don't create the binary search table,
600 since it is affected by runtime relocations. */
601 hdr_info
->table
= FALSE
;
604 hdr_info
->fde_count
++;
606 if (cie
.lsda_encoding
!= DW_EH_PE_omit
)
611 buf
+= 2 * get_DW_EH_PE_width (cie
.fde_encoding
, ptr_size
);
612 if (cie
.augmentation
[0] == 'z')
613 read_uleb128 (dummy
, buf
);
614 /* If some new augmentation data is added before LSDA
615 in FDE augmentation area, this need to be adjusted. */
616 sec_info
->entry
[sec_info
->count
].lsda_offset
= (buf
- aug
);
618 buf
= last_fde
+ 4 + hdr
.length
;
622 sec_info
->entry
[sec_info
->count
].fde_encoding
= cie
.fde_encoding
;
623 sec_info
->entry
[sec_info
->count
].lsda_encoding
= cie
.lsda_encoding
;
627 elf_section_data (sec
)->sec_info
= sec_info
;
628 sec
->sec_info_type
= ELF_INFO_TYPE_EH_FRAME
;
630 /* Ok, now we can assign new offsets. */
633 for (i
= 0; i
< sec_info
->count
; i
++)
635 if (! sec_info
->entry
[i
].removed
)
637 sec_info
->entry
[i
].new_offset
= offset
;
638 offset
+= sec_info
->entry
[i
].size
;
639 if (sec_info
->entry
[i
].cie
)
642 make_relative
= sec_info
->entry
[i
].make_relative
;
643 make_lsda_relative
= sec_info
->entry
[i
].make_lsda_relative
;
647 sec_info
->entry
[i
].make_relative
= make_relative
;
648 sec_info
->entry
[i
].make_lsda_relative
= make_lsda_relative
;
649 sec_info
->entry
[i
].per_encoding_relative
= 0;
652 else if (sec_info
->entry
[i
].cie
&& sec_info
->entry
[i
].sec
== sec
)
654 /* Need to adjust new_offset too. */
655 BFD_ASSERT (sec_info
->entry
[last_cie_ndx
].offset
656 == sec_info
->entry
[i
].new_offset
);
657 sec_info
->entry
[i
].new_offset
658 = sec_info
->entry
[last_cie_ndx
].new_offset
;
661 if (hdr_info
->last_cie_sec
== sec
)
663 BFD_ASSERT (sec_info
->entry
[last_cie_ndx
].offset
664 == hdr_info
->last_cie_offset
);
665 hdr_info
->last_cie_offset
= sec_info
->entry
[last_cie_ndx
].new_offset
;
668 /* FIXME: Currently it is not possible to shrink sections to zero size at
669 this point, so build a fake minimal CIE. */
673 /* Shrink the sec as needed. */
674 sec
->_cooked_size
= new_size
;
675 if (sec
->_cooked_size
== 0)
676 sec
->flags
|= SEC_EXCLUDE
;
679 return new_size
!= sec
->_raw_size
;
686 hdr_info
->table
= FALSE
;
687 hdr_info
->last_cie
.hdr
.length
= 0;
691 /* This function is called for .eh_frame_hdr section after
692 _bfd_elf_discard_section_eh_frame has been called on all .eh_frame
693 input sections. It finalizes the size of .eh_frame_hdr section. */
696 _bfd_elf_discard_section_eh_frame_hdr (abfd
, info
)
698 struct bfd_link_info
*info
;
700 struct elf_link_hash_table
*htab
;
701 struct eh_frame_hdr_info
*hdr_info
;
704 htab
= elf_hash_table (info
);
705 hdr_info
= &htab
->eh_info
;
706 sec
= hdr_info
->hdr_sec
;
710 sec
->_cooked_size
= EH_FRAME_HDR_SIZE
;
712 sec
->_cooked_size
+= 4 + hdr_info
->fde_count
* 8;
714 /* Request program headers to be recalculated. */
715 elf_tdata (abfd
)->program_header_size
= 0;
716 elf_tdata (abfd
)->eh_frame_hdr
= sec
;
720 /* This function is called from size_dynamic_sections.
721 It needs to decide whether .eh_frame_hdr should be output or not,
722 because later on it is too late for calling _bfd_strip_section_from_output,
723 since dynamic symbol table has been sized. */
726 _bfd_elf_maybe_strip_eh_frame_hdr (info
)
727 struct bfd_link_info
*info
;
731 struct elf_link_hash_table
*htab
;
732 struct eh_frame_hdr_info
*hdr_info
;
734 htab
= elf_hash_table (info
);
735 hdr_info
= &htab
->eh_info
;
736 if (hdr_info
->hdr_sec
== NULL
)
739 if (bfd_is_abs_section (hdr_info
->hdr_sec
->output_section
))
741 hdr_info
->hdr_sec
= NULL
;
746 if (info
->eh_frame_hdr
)
747 for (abfd
= info
->input_bfds
; abfd
!= NULL
; abfd
= abfd
->link_next
)
749 /* Count only sections which have at least a single CIE or FDE.
750 There cannot be any CIE or FDE <= 8 bytes. */
751 o
= bfd_get_section_by_name (abfd
, ".eh_frame");
752 if (o
&& o
->_raw_size
> 8 && !bfd_is_abs_section (o
->output_section
))
758 _bfd_strip_section_from_output (info
, hdr_info
->hdr_sec
);
759 hdr_info
->hdr_sec
= NULL
;
763 hdr_info
->table
= TRUE
;
767 /* Adjust an address in the .eh_frame section. Given OFFSET within
768 SEC, this returns the new offset in the adjusted .eh_frame section,
769 or -1 if the address refers to a CIE/FDE which has been removed
770 or to offset with dynamic relocation which is no longer needed. */
773 _bfd_elf_eh_frame_section_offset (output_bfd
, sec
, offset
)
774 bfd
*output_bfd ATTRIBUTE_UNUSED
;
778 struct eh_frame_sec_info
*sec_info
;
779 unsigned int lo
, hi
, mid
;
781 if (sec
->sec_info_type
!= ELF_INFO_TYPE_EH_FRAME
)
783 sec_info
= (struct eh_frame_sec_info
*)
784 elf_section_data (sec
)->sec_info
;
786 if (offset
>= sec
->_raw_size
)
787 return offset
- (sec
->_cooked_size
- sec
->_raw_size
);
790 hi
= sec_info
->count
;
795 if (offset
< sec_info
->entry
[mid
].offset
)
798 >= sec_info
->entry
[mid
].offset
+ sec_info
->entry
[mid
].size
)
804 BFD_ASSERT (lo
< hi
);
806 /* FDE or CIE was removed. */
807 if (sec_info
->entry
[mid
].removed
)
810 /* If converting to DW_EH_PE_pcrel, there will be no need for run-time
811 relocation against FDE's initial_location field. */
812 if (sec_info
->entry
[mid
].make_relative
813 && ! sec_info
->entry
[mid
].cie
814 && offset
== sec_info
->entry
[mid
].offset
+ 8)
817 /* If converting LSDA pointers to DW_EH_PE_pcrel, there will be no need
818 for run-time relocation against LSDA field. */
819 if (sec_info
->entry
[mid
].make_lsda_relative
820 && ! sec_info
->entry
[mid
].cie
821 && (offset
== (sec_info
->entry
[mid
].offset
+ 8
822 + sec_info
->entry
[mid
].lsda_offset
)))
825 return (offset
+ sec_info
->entry
[mid
].new_offset
826 - sec_info
->entry
[mid
].offset
);
829 /* Write out .eh_frame section. This is called with the relocated
833 _bfd_elf_write_section_eh_frame (abfd
, info
, sec
, contents
)
835 struct bfd_link_info
*info
;
839 struct eh_frame_sec_info
*sec_info
;
840 struct elf_link_hash_table
*htab
;
841 struct eh_frame_hdr_info
*hdr_info
;
844 unsigned int leb128_tmp
;
845 unsigned int cie_offset
= 0;
846 unsigned int ptr_size
;
848 ptr_size
= (elf_elfheader (sec
->owner
)->e_ident
[EI_CLASS
]
849 == ELFCLASS64
) ? 8 : 4;
851 if (sec
->sec_info_type
!= ELF_INFO_TYPE_EH_FRAME
)
852 return bfd_set_section_contents (abfd
, sec
->output_section
,
854 (file_ptr
) sec
->output_offset
,
856 sec_info
= (struct eh_frame_sec_info
*)
857 elf_section_data (sec
)->sec_info
;
858 htab
= elf_hash_table (info
);
859 hdr_info
= &htab
->eh_info
;
860 if (hdr_info
->table
&& hdr_info
->array
== NULL
)
862 = bfd_malloc (hdr_info
->fde_count
* sizeof(*hdr_info
->array
));
863 if (hdr_info
->array
== NULL
)
867 for (i
= 0; i
< sec_info
->count
; ++i
)
869 if (sec_info
->entry
[i
].removed
)
871 if (sec_info
->entry
[i
].cie
)
873 /* If CIE is removed due to no remaining FDEs referencing it
874 and there were no CIEs kept before it, sec_info->entry[i].sec
876 if (sec_info
->entry
[i
].sec
== NULL
)
880 cie_offset
= sec_info
->entry
[i
].new_offset
;
881 cie_offset
+= (sec_info
->entry
[i
].sec
->output_section
->vma
882 + sec_info
->entry
[i
].sec
->output_offset
883 - sec
->output_section
->vma
884 - sec
->output_offset
);
890 if (sec_info
->entry
[i
].cie
)
893 cie_offset
= sec_info
->entry
[i
].new_offset
;
894 if (sec_info
->entry
[i
].make_relative
895 || sec_info
->entry
[i
].make_lsda_relative
896 || sec_info
->entry
[i
].per_encoding_relative
)
900 unsigned int dummy
, per_width
, per_encoding
;
902 /* Need to find 'R' or 'L' augmentation's argument and modify
904 action
= (sec_info
->entry
[i
].make_relative
? 1 : 0)
905 | (sec_info
->entry
[i
].make_lsda_relative
? 2 : 0)
906 | (sec_info
->entry
[i
].per_encoding_relative
? 4 : 0);
907 buf
= contents
+ sec_info
->entry
[i
].offset
;
908 /* Skip length, id and version. */
911 buf
= strchr (buf
, '\0') + 1;
912 read_uleb128 (dummy
, buf
);
913 read_sleb128 (dummy
, buf
);
914 read_uleb128 (dummy
, buf
);
917 read_uleb128 (dummy
, buf
);
927 BFD_ASSERT (*buf
== sec_info
->entry
[i
].lsda_encoding
);
928 *buf
|= DW_EH_PE_pcrel
;
934 per_encoding
= *buf
++;
935 per_width
= get_DW_EH_PE_width (per_encoding
,
937 BFD_ASSERT (per_width
!= 0);
938 BFD_ASSERT (((per_encoding
& 0x70) == DW_EH_PE_pcrel
)
939 == sec_info
->entry
[i
].per_encoding_relative
);
940 if ((per_encoding
& 0xf0) == DW_EH_PE_aligned
)
942 + ((buf
- contents
+ per_width
- 1)
943 & ~((bfd_size_type
) per_width
- 1)));
948 value
= read_value (abfd
, buf
, per_width
,
951 value
+= (sec_info
->entry
[i
].offset
952 - sec_info
->entry
[i
].new_offset
);
953 write_value (abfd
, buf
, value
, per_width
);
961 BFD_ASSERT (*buf
== sec_info
->entry
[i
].fde_encoding
);
962 *buf
|= DW_EH_PE_pcrel
;
972 else if (sec_info
->entry
[i
].size
> 4)
975 bfd_vma value
= 0, address
;
978 buf
= contents
+ sec_info
->entry
[i
].offset
;
982 sec_info
->entry
[i
].new_offset
+ 4 - cie_offset
, buf
);
984 width
= get_DW_EH_PE_width (sec_info
->entry
[i
].fde_encoding
,
986 address
= value
= read_value (abfd
, buf
, width
,
988 (sec_info
->entry
[i
].fde_encoding
));
991 switch (sec_info
->entry
[i
].fde_encoding
& 0xf0)
993 case DW_EH_PE_indirect
:
994 case DW_EH_PE_textrel
:
995 BFD_ASSERT (hdr_info
== NULL
);
997 case DW_EH_PE_datarel
:
999 asection
*got
= bfd_get_section_by_name (abfd
, ".got");
1001 BFD_ASSERT (got
!= NULL
);
1002 address
+= got
->vma
;
1005 case DW_EH_PE_pcrel
:
1006 value
+= (sec_info
->entry
[i
].offset
1007 - sec_info
->entry
[i
].new_offset
);
1008 address
+= (sec
->output_section
->vma
+ sec
->output_offset
1009 + sec_info
->entry
[i
].offset
+ 8);
1012 if (sec_info
->entry
[i
].make_relative
)
1013 value
-= (sec
->output_section
->vma
+ sec
->output_offset
1014 + sec_info
->entry
[i
].new_offset
+ 8);
1015 write_value (abfd
, buf
, value
, width
);
1020 hdr_info
->array
[hdr_info
->array_count
].initial_loc
= address
;
1021 hdr_info
->array
[hdr_info
->array_count
++].fde
1022 = (sec
->output_section
->vma
+ sec
->output_offset
1023 + sec_info
->entry
[i
].new_offset
);
1026 if ((sec_info
->entry
[i
].lsda_encoding
& 0xf0) == DW_EH_PE_pcrel
1027 || sec_info
->entry
[i
].make_lsda_relative
)
1029 buf
+= sec_info
->entry
[i
].lsda_offset
;
1030 width
= get_DW_EH_PE_width (sec_info
->entry
[i
].lsda_encoding
,
1032 value
= read_value (abfd
, buf
, width
,
1034 (sec_info
->entry
[i
].lsda_encoding
));
1037 if ((sec_info
->entry
[i
].lsda_encoding
& 0xf0)
1039 value
+= (sec_info
->entry
[i
].offset
1040 - sec_info
->entry
[i
].new_offset
);
1041 else if (sec_info
->entry
[i
].make_lsda_relative
)
1042 value
-= (sec
->output_section
->vma
+ sec
->output_offset
1043 + sec_info
->entry
[i
].new_offset
+ 8
1044 + sec_info
->entry
[i
].lsda_offset
);
1045 write_value (abfd
, buf
, value
, width
);
1050 /* Terminating FDE must be at the end of .eh_frame section only. */
1051 BFD_ASSERT (i
== sec_info
->count
- 1);
1053 BFD_ASSERT (p
== contents
+ sec_info
->entry
[i
].new_offset
);
1054 memmove (p
, contents
+ sec_info
->entry
[i
].offset
,
1055 sec_info
->entry
[i
].size
);
1056 p
+= sec_info
->entry
[i
].size
;
1059 /* FIXME: Once _bfd_elf_discard_section_eh_frame will be able to
1060 shrink sections to zero size, this won't be needed any more. */
1061 if (p
== contents
&& sec
->_cooked_size
== 16)
1063 bfd_put_32 (abfd
, 12, p
); /* Fake CIE length */
1064 bfd_put_32 (abfd
, 0, p
+ 4); /* Fake CIE id */
1065 p
[8] = 1; /* Fake CIE version */
1066 memset (p
+ 9, 0, 7); /* Fake CIE augmentation, 3xleb128
1067 and 3xDW_CFA_nop as pad */
1071 BFD_ASSERT ((bfd_size_type
) (p
- contents
) == sec
->_cooked_size
);
1073 return bfd_set_section_contents (abfd
, sec
->output_section
,
1074 contents
, (file_ptr
) sec
->output_offset
,
1078 /* Helper function used to sort .eh_frame_hdr search table by increasing
1079 VMA of FDE initial location. */
1086 struct eh_frame_array_ent
*p
= (struct eh_frame_array_ent
*) a
;
1087 struct eh_frame_array_ent
*q
= (struct eh_frame_array_ent
*) b
;
1088 if (p
->initial_loc
> q
->initial_loc
)
1090 if (p
->initial_loc
< q
->initial_loc
)
1095 /* Write out .eh_frame_hdr section. This must be called after
1096 _bfd_elf_write_section_eh_frame has been called on all input
1098 .eh_frame_hdr format:
1099 ubyte version (currently 1)
1100 ubyte eh_frame_ptr_enc (DW_EH_PE_* encoding of pointer to start of
1102 ubyte fde_count_enc (DW_EH_PE_* encoding of total FDE count
1103 number (or DW_EH_PE_omit if there is no
1104 binary search table computed))
1105 ubyte table_enc (DW_EH_PE_* encoding of binary search table,
1106 or DW_EH_PE_omit if not present.
1107 DW_EH_PE_datarel is using address of
1108 .eh_frame_hdr section start as base)
1109 [encoded] eh_frame_ptr (pointer to start of .eh_frame section)
1110 optionally followed by:
1111 [encoded] fde_count (total number of FDEs in .eh_frame section)
1112 fde_count x [encoded] initial_loc, fde
1113 (array of encoded pairs containing
1114 FDE initial_location field and FDE address,
1115 sorted by increasing initial_loc) */
1118 _bfd_elf_write_section_eh_frame_hdr (abfd
, info
)
1120 struct bfd_link_info
*info
;
1122 struct elf_link_hash_table
*htab
;
1123 struct eh_frame_hdr_info
*hdr_info
;
1126 asection
*eh_frame_sec
;
1129 htab
= elf_hash_table (info
);
1130 hdr_info
= &htab
->eh_info
;
1131 sec
= hdr_info
->hdr_sec
;
1135 size
= EH_FRAME_HDR_SIZE
;
1136 if (hdr_info
->array
&& hdr_info
->array_count
== hdr_info
->fde_count
)
1137 size
+= 4 + hdr_info
->fde_count
* 8;
1138 contents
= bfd_malloc (size
);
1139 if (contents
== NULL
)
1142 eh_frame_sec
= bfd_get_section_by_name (abfd
, ".eh_frame");
1143 if (eh_frame_sec
== NULL
)
1146 memset (contents
, 0, EH_FRAME_HDR_SIZE
);
1147 contents
[0] = 1; /* Version */
1148 contents
[1] = DW_EH_PE_pcrel
| DW_EH_PE_sdata4
; /* .eh_frame offset */
1149 if (hdr_info
->array
&& hdr_info
->array_count
== hdr_info
->fde_count
)
1151 contents
[2] = DW_EH_PE_udata4
; /* FDE count encoding */
1152 contents
[3] = DW_EH_PE_datarel
| DW_EH_PE_sdata4
; /* search table enc */
1156 contents
[2] = DW_EH_PE_omit
;
1157 contents
[3] = DW_EH_PE_omit
;
1159 bfd_put_32 (abfd
, eh_frame_sec
->vma
- sec
->output_section
->vma
- 4,
1161 if (contents
[2] != DW_EH_PE_omit
)
1165 bfd_put_32 (abfd
, hdr_info
->fde_count
, contents
+ EH_FRAME_HDR_SIZE
);
1166 qsort (hdr_info
->array
, hdr_info
->fde_count
, sizeof (*hdr_info
->array
),
1168 for (i
= 0; i
< hdr_info
->fde_count
; i
++)
1171 hdr_info
->array
[i
].initial_loc
1172 - sec
->output_section
->vma
,
1173 contents
+ EH_FRAME_HDR_SIZE
+ i
* 8 + 4);
1175 hdr_info
->array
[i
].fde
- sec
->output_section
->vma
,
1176 contents
+ EH_FRAME_HDR_SIZE
+ i
* 8 + 8);
1180 return bfd_set_section_contents (abfd
, sec
->output_section
,
1181 contents
, (file_ptr
) sec
->output_offset
,