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
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));
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 /* Read a width sized value from memory. */
147 read_value (abfd
, buf
, width
)
156 case 2: value
= bfd_get_16 (abfd
, buf
); break;
157 case 4: value
= bfd_get_32 (abfd
, buf
); break;
158 case 8: value
= bfd_get_64 (abfd
, buf
); break;
159 default: BFD_FAIL (); return 0;
165 /* Store a width sized value to memory. */
168 write_value (abfd
, buf
, value
, width
)
176 case 2: bfd_put_16 (abfd
, value
, buf
); break;
177 case 4: bfd_put_32 (abfd
, value
, buf
); break;
178 case 8: bfd_put_64 (abfd
, value
, buf
); break;
179 default: BFD_FAIL ();
183 /* Return zero if C1 and C2 CIEs can be merged. */
186 int cie_compare (c1
, c2
)
189 if (c1
->hdr
.length
== c2
->hdr
.length
190 && c1
->version
== c2
->version
191 && strcmp (c1
->augmentation
, c2
->augmentation
) == 0
192 && strcmp (c1
->augmentation
, "eh") != 0
193 && c1
->code_align
== c2
->code_align
194 && c1
->data_align
== c2
->data_align
195 && c1
->ra_column
== c2
->ra_column
196 && c1
->augmentation_size
== c2
->augmentation_size
197 && c1
->personality
== c2
->personality
198 && c1
->per_encoding
== c2
->per_encoding
199 && c1
->lsda_encoding
== c2
->lsda_encoding
200 && c1
->fde_encoding
== c2
->fde_encoding
201 && (c1
->initial_insn_length
202 == c2
->initial_insn_length
)
203 && memcmp (c1
->initial_instructions
,
204 c2
->initial_instructions
,
205 c1
->initial_insn_length
) == 0)
211 /* This function is called for each input file before the .eh_frame
212 section is relocated. It discards duplicate CIEs and FDEs for discarded
213 functions. The function returns true iff any entries have been
217 _bfd_elf_discard_section_eh_frame (abfd
, info
, sec
,
218 reloc_symbol_deleted_p
, cookie
)
220 struct bfd_link_info
*info
;
222 boolean (*reloc_symbol_deleted_p
) PARAMS ((bfd_vma
, PTR
));
223 struct elf_reloc_cookie
*cookie
;
225 bfd_byte
*ehbuf
= NULL
, *buf
;
226 bfd_byte
*last_cie
, *last_fde
;
227 struct cie_header hdr
;
229 struct elf_link_hash_table
*htab
;
230 struct eh_frame_hdr_info
*hdr_info
;
231 struct eh_frame_sec_info
*sec_info
= NULL
;
232 unsigned int leb128_tmp
;
233 unsigned int cie_usage_count
, last_cie_ndx
, i
, offset
;
234 unsigned int make_relative
, make_lsda_relative
;
235 bfd_size_type new_size
;
236 unsigned int ptr_size
;
238 if (sec
->_raw_size
== 0)
240 /* This file does not contain .eh_frame information. */
244 if ((sec
->output_section
!= NULL
245 && bfd_is_abs_section (sec
->output_section
)))
247 /* At least one of the sections is being discarded from the
248 link, so we should just ignore them. */
252 htab
= elf_hash_table (info
);
253 hdr_info
= &htab
->eh_info
;
255 /* Read the frame unwind information from abfd. */
257 ehbuf
= (bfd_byte
*) bfd_malloc (sec
->_raw_size
);
261 if (! bfd_get_section_contents (abfd
, sec
, ehbuf
, (bfd_vma
) 0,
265 if (sec
->_raw_size
>= 4
266 && bfd_get_32 (abfd
, ehbuf
) == 0
267 && cookie
->rel
== cookie
->relend
)
269 /* Empty .eh_frame section. */
274 /* If .eh_frame section size doesn't fit into int, we cannot handle
275 it (it would need to use 64-bit .eh_frame format anyway). */
276 if (sec
->_raw_size
!= (unsigned int) sec
->_raw_size
)
279 ptr_size
= (elf_elfheader (abfd
)->e_ident
[EI_CLASS
]
280 == ELFCLASS64
) ? 8 : 4;
284 memset (&cie
, 0, sizeof (cie
));
286 new_size
= sec
->_raw_size
;
287 make_relative
= hdr_info
->last_cie
.make_relative
;
288 make_lsda_relative
= hdr_info
->last_cie
.make_lsda_relative
;
289 sec_info
= bfd_zmalloc (sizeof (struct eh_frame_sec_info
)
290 + 99 * sizeof (struct eh_cie_fde
));
291 if (sec_info
== NULL
)
293 sec_info
->alloced
= 100;
295 #define ENSURE_NO_RELOCS(buf) \
296 if (cookie->rel < cookie->relend \
297 && (cookie->rel->r_offset \
298 < (bfd_size_type) ((buf) - ehbuf))) \
301 #define SKIP_RELOCS(buf) \
302 while (cookie->rel < cookie->relend \
303 && (cookie->rel->r_offset \
304 < (bfd_size_type) ((buf) - ehbuf))) \
307 #define GET_RELOC(buf) \
308 ((cookie->rel < cookie->relend \
309 && (cookie->rel->r_offset \
310 == (bfd_size_type) ((buf) - ehbuf))) \
311 ? cookie->rel : NULL)
317 if (sec_info
->count
== sec_info
->alloced
)
319 sec_info
= bfd_realloc (sec_info
,
320 sizeof (struct eh_frame_sec_info
)
321 + (sec_info
->alloced
+ 99)
322 * sizeof (struct eh_cie_fde
));
323 if (sec_info
== NULL
)
326 memset (&sec_info
->entry
[sec_info
->alloced
], 0,
327 100 * sizeof (struct eh_cie_fde
));
328 sec_info
->alloced
+= 100;
332 /* If we are at the end of the section, we still need to decide
333 on whether to output or discard last encountered CIE (if any). */
334 if ((bfd_size_type
) (buf
- ehbuf
) == sec
->_raw_size
)
335 hdr
.id
= (unsigned int) -1;
338 if ((bfd_size_type
) (buf
+ 4 - ehbuf
) > sec
->_raw_size
)
339 /* No space for CIE/FDE header length. */
342 hdr
.length
= bfd_get_32 (abfd
, buf
);
343 if (hdr
.length
== 0xffffffff)
344 /* 64-bit .eh_frame is not supported. */
347 if ((bfd_size_type
) (buf
- ehbuf
) + hdr
.length
> sec
->_raw_size
)
348 /* CIE/FDE not contained fully in this .eh_frame input section. */
351 sec_info
->entry
[sec_info
->count
].offset
= last_fde
- ehbuf
;
352 sec_info
->entry
[sec_info
->count
].size
= 4 + hdr
.length
;
356 /* CIE with length 0 must be only the last in the section. */
357 if ((bfd_size_type
) (buf
- ehbuf
) < sec
->_raw_size
)
359 ENSURE_NO_RELOCS (buf
);
361 /* Now just finish last encountered CIE processing and break
363 hdr
.id
= (unsigned int) -1;
367 hdr
.id
= bfd_get_32 (abfd
, buf
);
369 if (hdr
.id
== (unsigned int) -1)
374 if (hdr
.id
== 0 || hdr
.id
== (unsigned int) -1)
376 unsigned int initial_insn_length
;
379 if (last_cie
!= NULL
)
381 /* Now check if this CIE is identical to last CIE, in which case
382 we can remove it, provided we adjust all FDEs.
383 Also, it can be removed if we have removed all FDEs using
385 if (cie_compare (&cie
, &hdr_info
->last_cie
) == 0
386 || cie_usage_count
== 0)
388 new_size
-= cie
.hdr
.length
+ 4;
389 sec_info
->entry
[last_cie_ndx
].removed
= 1;
390 sec_info
->entry
[last_cie_ndx
].sec
= hdr_info
->last_cie_sec
;
391 sec_info
->entry
[last_cie_ndx
].new_offset
392 = hdr_info
->last_cie_offset
;
396 hdr_info
->last_cie
= cie
;
397 hdr_info
->last_cie_sec
= sec
;
398 hdr_info
->last_cie_offset
= last_cie
- ehbuf
;
399 sec_info
->entry
[last_cie_ndx
].make_relative
401 sec_info
->entry
[last_cie_ndx
].make_lsda_relative
402 = cie
.make_lsda_relative
;
403 sec_info
->entry
[last_cie_ndx
].per_encoding_relative
404 = (cie
.per_encoding
& 0x70) == DW_EH_PE_pcrel
;
408 if (hdr
.id
== (unsigned int) -1)
411 last_cie_ndx
= sec_info
->count
;
412 sec_info
->entry
[sec_info
->count
].cie
= 1;
415 memset (&cie
, 0, sizeof (cie
));
417 cie
.version
= *buf
++;
419 /* Cannot handle unknown versions. */
420 if (cie
.version
!= 1)
422 if (strlen (buf
) > sizeof (cie
.augmentation
) - 1)
425 strcpy (cie
.augmentation
, buf
);
426 buf
= strchr (buf
, '\0') + 1;
427 ENSURE_NO_RELOCS (buf
);
428 if (buf
[0] == 'e' && buf
[1] == 'h')
430 /* GCC < 3.0 .eh_frame CIE */
431 /* We cannot merge "eh" CIEs because __EXCEPTION_TABLE__
432 is private to each CIE, so we don't need it for anything.
437 read_uleb128 (cie
.code_align
, buf
);
438 read_sleb128 (cie
.data_align
, buf
);
439 /* Note - in DWARF2 the return address column is an unsigned byte.
440 In DWARF3 it is a ULEB128. We are following DWARF3. For most
441 ports this will not matter as the value will be less than 128.
442 For the others (eg FRV, SH, MMIX, IA64) they need a fixed GCC
443 which conforms to the DWARF3 standard. */
444 read_uleb128 (cie
.ra_column
, buf
);
445 ENSURE_NO_RELOCS (buf
);
446 cie
.lsda_encoding
= DW_EH_PE_omit
;
447 cie
.fde_encoding
= DW_EH_PE_omit
;
448 cie
.per_encoding
= DW_EH_PE_omit
;
449 aug
= cie
.augmentation
;
450 if (aug
[0] != 'e' || aug
[1] != 'h')
455 read_uleb128 (cie
.augmentation_size
, buf
);
456 ENSURE_NO_RELOCS (buf
);
463 cie
.lsda_encoding
= *buf
++;
464 ENSURE_NO_RELOCS (buf
);
465 if (get_DW_EH_PE_width (cie
.lsda_encoding
, ptr_size
) == 0)
469 cie
.fde_encoding
= *buf
++;
470 ENSURE_NO_RELOCS (buf
);
471 if (get_DW_EH_PE_width (cie
.fde_encoding
, ptr_size
) == 0)
478 cie
.per_encoding
= *buf
++;
479 per_width
= get_DW_EH_PE_width (cie
.per_encoding
,
483 if ((cie
.per_encoding
& 0xf0) == DW_EH_PE_aligned
)
485 + ((buf
- ehbuf
+ per_width
- 1)
486 & ~((bfd_size_type
) per_width
- 1)));
487 ENSURE_NO_RELOCS (buf
);
488 /* Ensure we have a reloc here, against
490 if (GET_RELOC (buf
) != NULL
)
492 unsigned long r_symndx
;
496 r_symndx
= ELF64_R_SYM (cookie
->rel
->r_info
);
499 r_symndx
= ELF32_R_SYM (cookie
->rel
->r_info
);
500 if (r_symndx
>= cookie
->locsymcount
)
502 struct elf_link_hash_entry
*h
;
504 r_symndx
-= cookie
->extsymoff
;
505 h
= cookie
->sym_hashes
[r_symndx
];
507 while (h
->root
.type
== bfd_link_hash_indirect
508 || h
->root
.type
== bfd_link_hash_warning
)
509 h
= (struct elf_link_hash_entry
*)
520 /* Unrecognized augmentation. Better bail out. */
525 /* For shared libraries, try to get rid of as many RELATIVE relocs
528 && (cie
.fde_encoding
& 0xf0) == DW_EH_PE_absptr
)
529 cie
.make_relative
= 1;
532 && (cie
.lsda_encoding
& 0xf0) == DW_EH_PE_absptr
)
533 cie
.make_lsda_relative
= 1;
535 /* If FDE encoding was not specified, it defaults to
537 if (cie
.fde_encoding
== DW_EH_PE_omit
)
538 cie
.fde_encoding
= DW_EH_PE_absptr
;
540 initial_insn_length
= cie
.hdr
.length
- (buf
- last_fde
- 4);
541 if (initial_insn_length
<= 50)
543 cie
.initial_insn_length
= initial_insn_length
;
544 memcpy (cie
.initial_instructions
, buf
, initial_insn_length
);
546 buf
+= initial_insn_length
;
547 ENSURE_NO_RELOCS (buf
);
552 /* Ensure this FDE uses the last CIE encountered. */
554 || hdr
.id
!= (unsigned int) (buf
- 4 - last_cie
))
557 ENSURE_NO_RELOCS (buf
);
558 if (GET_RELOC (buf
) == NULL
)
559 /* This should not happen. */
561 if ((*reloc_symbol_deleted_p
) (buf
- ehbuf
, cookie
))
563 /* This is a FDE against discarded section, it should
565 new_size
-= hdr
.length
+ 4;
566 sec_info
->entry
[sec_info
->count
].removed
= 1;
571 && (((cie
.fde_encoding
& 0xf0) == DW_EH_PE_absptr
572 && cie
.make_relative
== 0)
573 || (cie
.fde_encoding
& 0xf0) == DW_EH_PE_aligned
))
575 /* If shared library uses absolute pointers
576 which we cannot turn into PC relative,
577 don't create the binary search table,
578 since it is affected by runtime relocations. */
579 hdr_info
->table
= false;
582 hdr_info
->fde_count
++;
584 if (cie
.lsda_encoding
!= DW_EH_PE_omit
)
589 buf
+= 2 * get_DW_EH_PE_width (cie
.fde_encoding
, ptr_size
);
590 if (cie
.augmentation
[0] == 'z')
591 read_uleb128 (dummy
, buf
);
592 /* If some new augmentation data is added before LSDA
593 in FDE augmentation area, this need to be adjusted. */
594 sec_info
->entry
[sec_info
->count
].lsda_offset
= (buf
- aug
);
596 buf
= last_fde
+ 4 + hdr
.length
;
600 sec_info
->entry
[sec_info
->count
].fde_encoding
= cie
.fde_encoding
;
601 sec_info
->entry
[sec_info
->count
].lsda_encoding
= cie
.lsda_encoding
;
605 elf_section_data (sec
)->sec_info
= sec_info
;
606 elf_section_data (sec
)->sec_info_type
= ELF_INFO_TYPE_EH_FRAME
;
608 /* Ok, now we can assign new offsets. */
611 for (i
= 0; i
< sec_info
->count
; i
++)
613 if (! sec_info
->entry
[i
].removed
)
615 sec_info
->entry
[i
].new_offset
= offset
;
616 offset
+= sec_info
->entry
[i
].size
;
617 if (sec_info
->entry
[i
].cie
)
620 make_relative
= sec_info
->entry
[i
].make_relative
;
621 make_lsda_relative
= sec_info
->entry
[i
].make_lsda_relative
;
625 sec_info
->entry
[i
].make_relative
= make_relative
;
626 sec_info
->entry
[i
].make_lsda_relative
= make_lsda_relative
;
627 sec_info
->entry
[i
].per_encoding_relative
= 0;
630 else if (sec_info
->entry
[i
].cie
&& sec_info
->entry
[i
].sec
== sec
)
632 /* Need to adjust new_offset too. */
633 BFD_ASSERT (sec_info
->entry
[last_cie_ndx
].offset
634 == sec_info
->entry
[i
].new_offset
);
635 sec_info
->entry
[i
].new_offset
636 = sec_info
->entry
[last_cie_ndx
].new_offset
;
639 if (hdr_info
->last_cie_sec
== sec
)
641 BFD_ASSERT (sec_info
->entry
[last_cie_ndx
].offset
642 == hdr_info
->last_cie_offset
);
643 hdr_info
->last_cie_offset
= sec_info
->entry
[last_cie_ndx
].new_offset
;
646 /* FIXME: Currently it is not possible to shrink sections to zero size at
647 this point, so build a fake minimal CIE. */
651 /* Shrink the sec as needed. */
652 sec
->_cooked_size
= new_size
;
653 if (sec
->_cooked_size
== 0)
654 sec
->flags
|= SEC_EXCLUDE
;
657 return new_size
!= sec
->_raw_size
;
664 hdr_info
->table
= false;
665 hdr_info
->last_cie
.hdr
.length
= 0;
669 /* This function is called for .eh_frame_hdr section after
670 _bfd_elf_discard_section_eh_frame has been called on all .eh_frame
671 input sections. It finalizes the size of .eh_frame_hdr section. */
674 _bfd_elf_discard_section_eh_frame_hdr (abfd
, info
)
676 struct bfd_link_info
*info
;
678 struct elf_link_hash_table
*htab
;
679 struct eh_frame_hdr_info
*hdr_info
;
682 htab
= elf_hash_table (info
);
683 hdr_info
= &htab
->eh_info
;
684 sec
= hdr_info
->hdr_sec
;
688 sec
->_cooked_size
= EH_FRAME_HDR_SIZE
;
690 sec
->_cooked_size
+= 4 + hdr_info
->fde_count
* 8;
692 /* Request program headers to be recalculated. */
693 elf_tdata (abfd
)->program_header_size
= 0;
694 elf_tdata (abfd
)->eh_frame_hdr
= sec
;
698 /* This function is called from size_dynamic_sections.
699 It needs to decide whether .eh_frame_hdr should be output or not,
700 because later on it is too late for calling _bfd_strip_section_from_output,
701 since dynamic symbol table has been sized. */
704 _bfd_elf_maybe_strip_eh_frame_hdr (info
)
705 struct bfd_link_info
*info
;
709 struct elf_link_hash_table
*htab
;
710 struct eh_frame_hdr_info
*hdr_info
;
712 htab
= elf_hash_table (info
);
713 hdr_info
= &htab
->eh_info
;
714 if (hdr_info
->hdr_sec
== NULL
)
717 if (bfd_is_abs_section (hdr_info
->hdr_sec
->output_section
))
719 hdr_info
->hdr_sec
= NULL
;
724 if (info
->eh_frame_hdr
)
725 for (abfd
= info
->input_bfds
; abfd
!= NULL
; abfd
= abfd
->link_next
)
727 /* Count only sections which have at least a single CIE or FDE.
728 There cannot be any CIE or FDE <= 8 bytes. */
729 o
= bfd_get_section_by_name (abfd
, ".eh_frame");
730 if (o
&& o
->_raw_size
> 8 && !bfd_is_abs_section (o
->output_section
))
736 _bfd_strip_section_from_output (info
, hdr_info
->hdr_sec
);
737 hdr_info
->hdr_sec
= NULL
;
741 hdr_info
->table
= true;
745 /* Adjust an address in the .eh_frame section. Given OFFSET within
746 SEC, this returns the new offset in the adjusted .eh_frame section,
747 or -1 if the address refers to a CIE/FDE which has been removed
748 or to offset with dynamic relocation which is no longer needed. */
751 _bfd_elf_eh_frame_section_offset (output_bfd
, sec
, offset
)
752 bfd
*output_bfd ATTRIBUTE_UNUSED
;
756 struct eh_frame_sec_info
*sec_info
;
757 unsigned int lo
, hi
, mid
;
759 if (elf_section_data (sec
)->sec_info_type
!= ELF_INFO_TYPE_EH_FRAME
)
761 sec_info
= (struct eh_frame_sec_info
*)
762 elf_section_data (sec
)->sec_info
;
764 if (offset
>= sec
->_raw_size
)
765 return offset
- (sec
->_cooked_size
- sec
->_raw_size
);
768 hi
= sec_info
->count
;
773 if (offset
< sec_info
->entry
[mid
].offset
)
776 >= sec_info
->entry
[mid
].offset
+ sec_info
->entry
[mid
].size
)
782 BFD_ASSERT (lo
< hi
);
784 /* FDE or CIE was removed. */
785 if (sec_info
->entry
[mid
].removed
)
788 /* If converting to DW_EH_PE_pcrel, there will be no need for run-time
789 relocation against FDE's initial_location field. */
790 if (sec_info
->entry
[mid
].make_relative
791 && ! sec_info
->entry
[mid
].cie
792 && offset
== sec_info
->entry
[mid
].offset
+ 8)
795 /* If converting LSDA pointers to DW_EH_PE_pcrel, there will be no need
796 for run-time relocation against LSDA field. */
797 if (sec_info
->entry
[mid
].make_lsda_relative
798 && ! sec_info
->entry
[mid
].cie
799 && (offset
== (sec_info
->entry
[mid
].offset
+ 8
800 + sec_info
->entry
[mid
].lsda_offset
)))
803 return (offset
+ sec_info
->entry
[mid
].new_offset
804 - sec_info
->entry
[mid
].offset
);
807 /* Write out .eh_frame section. This is called with the relocated
811 _bfd_elf_write_section_eh_frame (abfd
, info
, sec
, contents
)
813 struct bfd_link_info
*info
;
817 struct eh_frame_sec_info
*sec_info
;
818 struct elf_link_hash_table
*htab
;
819 struct eh_frame_hdr_info
*hdr_info
;
822 unsigned int leb128_tmp
;
823 unsigned int cie_offset
= 0;
824 unsigned int ptr_size
;
826 ptr_size
= (elf_elfheader (sec
->owner
)->e_ident
[EI_CLASS
]
827 == ELFCLASS64
) ? 8 : 4;
829 if (elf_section_data (sec
)->sec_info_type
!= ELF_INFO_TYPE_EH_FRAME
)
830 return bfd_set_section_contents (abfd
, sec
->output_section
,
832 (file_ptr
) sec
->output_offset
,
834 sec_info
= (struct eh_frame_sec_info
*)
835 elf_section_data (sec
)->sec_info
;
836 htab
= elf_hash_table (info
);
837 hdr_info
= &htab
->eh_info
;
838 if (hdr_info
->table
&& hdr_info
->array
== NULL
)
840 = bfd_malloc (hdr_info
->fde_count
* sizeof(*hdr_info
->array
));
841 if (hdr_info
->array
== NULL
)
845 for (i
= 0; i
< sec_info
->count
; ++i
)
847 if (sec_info
->entry
[i
].removed
)
849 if (sec_info
->entry
[i
].cie
)
851 /* If CIE is removed due to no remaining FDEs referencing it
852 and there were no CIEs kept before it, sec_info->entry[i].sec
854 if (sec_info
->entry
[i
].sec
== NULL
)
858 cie_offset
= sec_info
->entry
[i
].new_offset
;
859 cie_offset
+= (sec_info
->entry
[i
].sec
->output_section
->vma
860 + sec_info
->entry
[i
].sec
->output_offset
861 - sec
->output_section
->vma
862 - sec
->output_offset
);
868 if (sec_info
->entry
[i
].cie
)
871 cie_offset
= sec_info
->entry
[i
].new_offset
;
872 if (sec_info
->entry
[i
].make_relative
873 || sec_info
->entry
[i
].make_lsda_relative
874 || sec_info
->entry
[i
].per_encoding_relative
)
878 unsigned int dummy
, per_width
, per_encoding
;
880 /* Need to find 'R' or 'L' augmentation's argument and modify
882 action
= (sec_info
->entry
[i
].make_relative
? 1 : 0)
883 | (sec_info
->entry
[i
].make_lsda_relative
? 2 : 0)
884 | (sec_info
->entry
[i
].per_encoding_relative
? 4 : 0);
885 buf
= contents
+ sec_info
->entry
[i
].offset
;
886 /* Skip length, id and version. */
889 buf
= strchr (buf
, '\0') + 1;
890 read_uleb128 (dummy
, buf
);
891 read_sleb128 (dummy
, buf
);
892 read_uleb128 (dummy
, buf
);
895 read_uleb128 (dummy
, buf
);
905 BFD_ASSERT (*buf
== sec_info
->entry
[i
].lsda_encoding
);
906 *buf
|= DW_EH_PE_pcrel
;
912 per_encoding
= *buf
++;
913 per_width
= get_DW_EH_PE_width (per_encoding
,
915 BFD_ASSERT (per_width
!= 0);
916 BFD_ASSERT (((per_encoding
& 0x70) == DW_EH_PE_pcrel
)
917 == sec_info
->entry
[i
].per_encoding_relative
);
918 if ((per_encoding
& 0xf0) == DW_EH_PE_aligned
)
920 + ((buf
- contents
+ per_width
- 1)
921 & ~((bfd_size_type
) per_width
- 1)));
926 value
= read_value (abfd
, buf
, per_width
);
927 value
+= (sec_info
->entry
[i
].offset
928 - sec_info
->entry
[i
].new_offset
);
929 write_value (abfd
, buf
, value
, per_width
);
937 BFD_ASSERT (*buf
== sec_info
->entry
[i
].fde_encoding
);
938 *buf
|= DW_EH_PE_pcrel
;
948 else if (sec_info
->entry
[i
].size
> 4)
951 bfd_vma value
= 0, address
;
954 buf
= contents
+ sec_info
->entry
[i
].offset
;
958 sec_info
->entry
[i
].new_offset
+ 4 - cie_offset
, buf
);
960 width
= get_DW_EH_PE_width (sec_info
->entry
[i
].fde_encoding
,
962 address
= value
= read_value (abfd
, buf
, width
);
965 switch (sec_info
->entry
[i
].fde_encoding
& 0xf0)
967 case DW_EH_PE_indirect
:
968 case DW_EH_PE_textrel
:
969 BFD_ASSERT (hdr_info
== NULL
);
971 case DW_EH_PE_datarel
:
973 asection
*got
= bfd_get_section_by_name (abfd
, ".got");
975 BFD_ASSERT (got
!= NULL
);
980 value
+= (sec_info
->entry
[i
].offset
981 - sec_info
->entry
[i
].new_offset
);
982 address
+= (sec
->output_section
->vma
+ sec
->output_offset
983 + sec_info
->entry
[i
].offset
+ 8);
986 if (sec_info
->entry
[i
].make_relative
)
987 value
-= (sec
->output_section
->vma
+ sec
->output_offset
988 + sec_info
->entry
[i
].new_offset
+ 8);
989 write_value (abfd
, buf
, value
, width
);
994 hdr_info
->array
[hdr_info
->array_count
].initial_loc
= address
;
995 hdr_info
->array
[hdr_info
->array_count
++].fde
996 = (sec
->output_section
->vma
+ sec
->output_offset
997 + sec_info
->entry
[i
].new_offset
);
1000 if ((sec_info
->entry
[i
].lsda_encoding
& 0xf0) == DW_EH_PE_pcrel
1001 || sec_info
->entry
[i
].make_lsda_relative
)
1003 buf
+= sec_info
->entry
[i
].lsda_offset
;
1004 width
= get_DW_EH_PE_width (sec_info
->entry
[i
].lsda_encoding
,
1006 value
= read_value (abfd
, buf
, width
);
1009 if ((sec_info
->entry
[i
].lsda_encoding
& 0xf0)
1011 value
+= (sec_info
->entry
[i
].offset
1012 - sec_info
->entry
[i
].new_offset
);
1013 else if (sec_info
->entry
[i
].make_lsda_relative
)
1014 value
-= (sec
->output_section
->vma
+ sec
->output_offset
1015 + sec_info
->entry
[i
].new_offset
+ 8
1016 + sec_info
->entry
[i
].lsda_offset
);
1017 write_value (abfd
, buf
, value
, width
);
1022 /* Terminating FDE must be at the end of .eh_frame section only. */
1023 BFD_ASSERT (i
== sec_info
->count
- 1);
1025 BFD_ASSERT (p
== contents
+ sec_info
->entry
[i
].new_offset
);
1026 memmove (p
, contents
+ sec_info
->entry
[i
].offset
,
1027 sec_info
->entry
[i
].size
);
1028 p
+= sec_info
->entry
[i
].size
;
1031 /* FIXME: Once _bfd_elf_discard_section_eh_frame will be able to
1032 shrink sections to zero size, this won't be needed any more. */
1033 if (p
== contents
&& sec
->_cooked_size
== 16)
1035 bfd_put_32 (abfd
, 12, p
); /* Fake CIE length */
1036 bfd_put_32 (abfd
, 0, p
+ 4); /* Fake CIE id */
1037 p
[8] = 1; /* Fake CIE version */
1038 memset (p
+ 9, 0, 7); /* Fake CIE augmentation, 3xleb128
1039 and 3xDW_CFA_nop as pad */
1043 BFD_ASSERT ((bfd_size_type
) (p
- contents
) == sec
->_cooked_size
);
1045 return bfd_set_section_contents (abfd
, sec
->output_section
,
1046 contents
, (file_ptr
) sec
->output_offset
,
1050 /* Helper function used to sort .eh_frame_hdr search table by increasing
1051 VMA of FDE initial location. */
1058 struct eh_frame_array_ent
*p
= (struct eh_frame_array_ent
*) a
;
1059 struct eh_frame_array_ent
*q
= (struct eh_frame_array_ent
*) b
;
1060 if (p
->initial_loc
> q
->initial_loc
)
1062 if (p
->initial_loc
< q
->initial_loc
)
1067 /* Write out .eh_frame_hdr section. This must be called after
1068 _bfd_elf_write_section_eh_frame has been called on all input
1070 .eh_frame_hdr format:
1071 ubyte version (currently 1)
1072 ubyte eh_frame_ptr_enc (DW_EH_PE_* encoding of pointer to start of
1074 ubyte fde_count_enc (DW_EH_PE_* encoding of total FDE count
1075 number (or DW_EH_PE_omit if there is no
1076 binary search table computed))
1077 ubyte table_enc (DW_EH_PE_* encoding of binary search table,
1078 or DW_EH_PE_omit if not present.
1079 DW_EH_PE_datarel is using address of
1080 .eh_frame_hdr section start as base)
1081 [encoded] eh_frame_ptr (pointer to start of .eh_frame section)
1082 optionally followed by:
1083 [encoded] fde_count (total number of FDEs in .eh_frame section)
1084 fde_count x [encoded] initial_loc, fde
1085 (array of encoded pairs containing
1086 FDE initial_location field and FDE address,
1087 sorted by increasing initial_loc) */
1090 _bfd_elf_write_section_eh_frame_hdr (abfd
, info
)
1092 struct bfd_link_info
*info
;
1094 struct elf_link_hash_table
*htab
;
1095 struct eh_frame_hdr_info
*hdr_info
;
1098 asection
*eh_frame_sec
;
1101 htab
= elf_hash_table (info
);
1102 hdr_info
= &htab
->eh_info
;
1103 sec
= hdr_info
->hdr_sec
;
1107 size
= EH_FRAME_HDR_SIZE
;
1108 if (hdr_info
->array
&& hdr_info
->array_count
== hdr_info
->fde_count
)
1109 size
+= 4 + hdr_info
->fde_count
* 8;
1110 contents
= bfd_malloc (size
);
1111 if (contents
== NULL
)
1114 eh_frame_sec
= bfd_get_section_by_name (abfd
, ".eh_frame");
1115 if (eh_frame_sec
== NULL
)
1118 memset (contents
, 0, EH_FRAME_HDR_SIZE
);
1119 contents
[0] = 1; /* Version */
1120 contents
[1] = DW_EH_PE_pcrel
| DW_EH_PE_sdata4
; /* .eh_frame offset */
1121 if (hdr_info
->array
&& hdr_info
->array_count
== hdr_info
->fde_count
)
1123 contents
[2] = DW_EH_PE_udata4
; /* FDE count encoding */
1124 contents
[3] = DW_EH_PE_datarel
| DW_EH_PE_sdata4
; /* search table enc */
1128 contents
[2] = DW_EH_PE_omit
;
1129 contents
[3] = DW_EH_PE_omit
;
1131 bfd_put_32 (abfd
, eh_frame_sec
->vma
- sec
->output_section
->vma
- 4,
1133 if (contents
[2] != DW_EH_PE_omit
)
1137 bfd_put_32 (abfd
, hdr_info
->fde_count
, contents
+ EH_FRAME_HDR_SIZE
);
1138 qsort (hdr_info
->array
, hdr_info
->fde_count
, sizeof (*hdr_info
->array
),
1140 for (i
= 0; i
< hdr_info
->fde_count
; i
++)
1143 hdr_info
->array
[i
].initial_loc
1144 - sec
->output_section
->vma
,
1145 contents
+ EH_FRAME_HDR_SIZE
+ i
* 8 + 4);
1147 hdr_info
->array
[i
].fde
- sec
->output_section
->vma
,
1148 contents
+ EH_FRAME_HDR_SIZE
+ i
* 8 + 8);
1152 return bfd_set_section_contents (abfd
, sec
->output_section
,
1153 contents
, (file_ptr
) sec
->output_offset
,