daily update
[binutils.git] / bfd / elf-eh-frame.c
blobb6d2d2f8087375ad6f04bb4f11121e8dfb086418
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;
67 unsigned char per_encoding_relative : 1;
70 struct eh_frame_sec_info
72 unsigned int count;
73 unsigned int alloced;
74 struct eh_cie_fde entry[1];
77 struct eh_frame_array_ent
79 bfd_vma initial_loc;
80 bfd_vma fde;
83 struct eh_frame_hdr_info
85 struct cie last_cie;
86 asection *last_cie_sec;
87 unsigned int last_cie_offset;
88 unsigned int fde_count, array_count;
89 struct eh_frame_array_ent *array;
90 /* TRUE if .eh_frame_hdr should contain the sorted search table.
91 We build it if we successfully read all .eh_frame input sections
92 and recognize them. */
93 boolean table;
94 boolean strip;
97 static bfd_vma read_unsigned_leb128
98 PARAMS ((bfd *, char *, unsigned int *));
99 static bfd_signed_vma read_signed_leb128
100 PARAMS ((bfd *, char *, unsigned int *));
101 static int get_DW_EH_PE_width
102 PARAMS ((int, int));
103 static bfd_vma read_value
104 PARAMS ((bfd *, bfd_byte *, int));
105 static void write_value
106 PARAMS ((bfd *, bfd_byte *, bfd_vma, int));
107 static int cie_compare
108 PARAMS ((struct cie *, struct cie *));
109 static int vma_compare
110 PARAMS ((const PTR a, const PTR b));
112 /* Helper function for reading uleb128 encoded data. */
114 static bfd_vma
115 read_unsigned_leb128 (abfd, buf, bytes_read_ptr)
116 bfd *abfd ATTRIBUTE_UNUSED;
117 char *buf;
118 unsigned int *bytes_read_ptr;
120 bfd_vma result;
121 unsigned int num_read;
122 int shift;
123 unsigned char byte;
125 result = 0;
126 shift = 0;
127 num_read = 0;
130 byte = bfd_get_8 (abfd, (bfd_byte *) buf);
131 buf ++;
132 num_read ++;
133 result |= (((bfd_vma) byte & 0x7f) << shift);
134 shift += 7;
136 while (byte & 0x80);
137 * bytes_read_ptr = num_read;
138 return result;
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;
146 char *buf;
147 unsigned int * bytes_read_ptr;
149 bfd_vma result;
150 int shift;
151 int num_read;
152 unsigned char byte;
154 result = 0;
155 shift = 0;
156 num_read = 0;
159 byte = bfd_get_8 (abfd, (bfd_byte *) buf);
160 buf ++;
161 num_read ++;
162 result |= (((bfd_vma) byte & 0x7f) << shift);
163 shift += 7;
165 while (byte & 0x80);
166 if (byte & 0x40)
167 result |= (((bfd_vma) -1) << (shift - 7)) << 7;
168 * bytes_read_ptr = num_read;
169 return result;
172 #define read_uleb128(VAR, BUF) \
173 do \
175 (VAR) = read_unsigned_leb128 (abfd, buf, &leb128_tmp); \
176 (BUF) += leb128_tmp; \
178 while (0)
180 #define read_sleb128(VAR, BUF) \
181 do \
183 (VAR) = read_signed_leb128 (abfd, buf, &leb128_tmp); \
184 (BUF) += leb128_tmp; \
186 while (0)
188 /* Return 0 if either encoding is variable width, or not yet known to bfd. */
190 static
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
195 was added to bfd. */
196 if ((encoding & 0x60) == 0x60)
197 return 0;
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;
205 default:
206 break;
209 return 0;
212 /* Read a width sized value from memory. */
214 static bfd_vma
215 read_value (abfd, buf, width)
216 bfd *abfd;
217 bfd_byte *buf;
218 int width;
220 bfd_vma value;
222 switch (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;
230 return value;
233 /* Store a width sized value to memory. */
235 static void
236 write_value (abfd, buf, value, width)
237 bfd *abfd;
238 bfd_byte *buf;
239 bfd_vma value;
240 int width;
242 switch (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. */
253 static
254 int cie_compare (c1, c2)
255 struct cie *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)
274 return 0;
276 return 1;
279 /* This function is called for each input file before the .eh_frame
280 section is relocated. It discards duplicate CIEs and FDEs for discarded
281 functions. The function returns true iff any entries have been
282 deleted. */
284 boolean
285 _bfd_elf_discard_section_eh_frame (abfd, info, sec, ehdrsec,
286 reloc_symbol_deleted_p, cookie)
287 bfd *abfd;
288 struct bfd_link_info *info;
289 asection *sec, *ehdrsec;
290 boolean (*reloc_symbol_deleted_p) PARAMS ((bfd_vma, PTR));
291 struct elf_reloc_cookie *cookie;
293 bfd_byte *ehbuf = NULL, *buf;
294 bfd_byte *last_cie, *last_fde;
295 struct cie_header hdr;
296 struct cie cie;
297 struct eh_frame_hdr_info *hdr_info;
298 struct eh_frame_sec_info *sec_info = NULL;
299 unsigned int leb128_tmp;
300 unsigned int cie_usage_count, last_cie_ndx, i, offset;
301 unsigned int make_relative, make_lsda_relative;
302 Elf_Internal_Rela *rel;
303 bfd_size_type new_size;
304 unsigned int ptr_size;
306 if (sec->_raw_size == 0)
308 /* This file does not contain .eh_frame information. */
309 return false;
312 if ((sec->output_section != NULL
313 && bfd_is_abs_section (sec->output_section)))
315 /* At least one of the sections is being discarded from the
316 link, so we should just ignore them. */
317 return false;
320 BFD_ASSERT (elf_section_data (ehdrsec)->sec_info_type
321 == ELF_INFO_TYPE_EH_FRAME_HDR);
322 hdr_info = (struct eh_frame_hdr_info *)
323 elf_section_data (ehdrsec)->sec_info;
325 /* Read the frame unwind information from abfd. */
327 ehbuf = (bfd_byte *) bfd_malloc (sec->_raw_size);
328 if (ehbuf == NULL)
329 goto free_no_table;
331 if (! bfd_get_section_contents (abfd, sec, ehbuf, (bfd_vma) 0,
332 sec->_raw_size))
333 goto free_no_table;
335 if (sec->_raw_size >= 4
336 && bfd_get_32 (abfd, ehbuf) == 0
337 && cookie->rel == cookie->relend)
339 /* Empty .eh_frame section. */
340 free (ehbuf);
341 return false;
344 /* If .eh_frame section size doesn't fit into int, we cannot handle
345 it (it would need to use 64-bit .eh_frame format anyway). */
346 if (sec->_raw_size != (unsigned int) sec->_raw_size)
347 goto free_no_table;
349 ptr_size = (elf_elfheader (abfd)->e_ident[EI_CLASS]
350 == ELFCLASS64) ? 8 : 4;
351 buf = ehbuf;
352 last_cie = NULL;
353 last_cie_ndx = 0;
354 memset (&cie, 0, sizeof (cie));
355 cie_usage_count = 0;
356 new_size = sec->_raw_size;
357 make_relative = hdr_info->last_cie.make_relative;
358 make_lsda_relative = hdr_info->last_cie.make_lsda_relative;
359 sec_info = bfd_zmalloc (sizeof (struct eh_frame_sec_info)
360 + 99 * sizeof (struct eh_cie_fde));
361 if (sec_info == NULL)
362 goto free_no_table;
363 sec_info->alloced = 100;
365 #define ENSURE_NO_RELOCS(buf) \
366 if (cookie->rel < cookie->relend \
367 && (cookie->rel->r_offset \
368 < (bfd_size_type) ((buf) - ehbuf))) \
369 goto free_no_table
371 #define SKIP_RELOCS(buf) \
372 while (cookie->rel < cookie->relend \
373 && (cookie->rel->r_offset \
374 < (bfd_size_type) ((buf) - ehbuf))) \
375 cookie->rel++
377 #define GET_RELOC(buf) \
378 ((cookie->rel < cookie->relend \
379 && (cookie->rel->r_offset \
380 == (bfd_size_type) ((buf) - ehbuf))) \
381 ? cookie->rel : NULL)
383 for (;;)
385 unsigned char *aug;
387 if (sec_info->count == sec_info->alloced)
389 sec_info = bfd_realloc (sec_info,
390 sizeof (struct eh_frame_sec_info)
391 + (sec_info->alloced + 99)
392 * sizeof (struct eh_cie_fde));
393 if (sec_info == NULL)
394 goto free_no_table;
396 memset (&sec_info->entry[sec_info->alloced], 0,
397 100 * sizeof (struct eh_cie_fde));
398 sec_info->alloced += 100;
401 last_fde = buf;
402 /* If we are at the end of the section, we still need to decide
403 on whether to output or discard last encountered CIE (if any). */
404 if ((bfd_size_type) (buf - ehbuf) == sec->_raw_size)
405 hdr.id = (unsigned int) -1;
406 else
408 if ((bfd_size_type) (buf + 4 - ehbuf) > sec->_raw_size)
409 /* No space for CIE/FDE header length. */
410 goto free_no_table;
412 hdr.length = bfd_get_32 (abfd, buf);
413 if (hdr.length == 0xffffffff)
414 /* 64-bit .eh_frame is not supported. */
415 goto free_no_table;
416 buf += 4;
417 if ((bfd_size_type) (buf - ehbuf) + hdr.length > sec->_raw_size)
418 /* CIE/FDE not contained fully in this .eh_frame input section. */
419 goto free_no_table;
421 sec_info->entry[sec_info->count].offset = last_fde - ehbuf;
422 sec_info->entry[sec_info->count].size = 4 + hdr.length;
424 if (hdr.length == 0)
426 /* CIE with length 0 must be only the last in the section. */
427 if ((bfd_size_type) (buf - ehbuf) < sec->_raw_size)
428 goto free_no_table;
429 ENSURE_NO_RELOCS (buf);
430 sec_info->count++;
431 /* Now just finish last encountered CIE processing and break
432 the loop. */
433 hdr.id = (unsigned int) -1;
435 else
437 hdr.id = bfd_get_32 (abfd, buf);
438 buf += 4;
439 if (hdr.id == (unsigned int) -1)
440 goto free_no_table;
444 if (hdr.id == 0 || hdr.id == (unsigned int) -1)
446 unsigned int initial_insn_length;
448 /* CIE */
449 if (last_cie != NULL)
451 /* Now check if this CIE is identical to last CIE, in which case
452 we can remove it, provided we adjust all FDEs.
453 Also, it can be removed if we have removed all FDEs using
454 that. */
455 if (cie_compare (&cie, &hdr_info->last_cie) == 0
456 || cie_usage_count == 0)
458 new_size -= cie.hdr.length + 4;
459 sec_info->entry[last_cie_ndx].removed = 1;
460 sec_info->entry[last_cie_ndx].sec = hdr_info->last_cie_sec;
461 sec_info->entry[last_cie_ndx].new_offset
462 = hdr_info->last_cie_offset;
464 else
466 hdr_info->last_cie = cie;
467 hdr_info->last_cie_sec = sec;
468 hdr_info->last_cie_offset = last_cie - ehbuf;
469 sec_info->entry[last_cie_ndx].make_relative
470 = cie.make_relative;
471 sec_info->entry[last_cie_ndx].make_lsda_relative
472 = cie.make_lsda_relative;
473 sec_info->entry[last_cie_ndx].per_encoding_relative
474 = (cie.per_encoding & 0x70) == DW_EH_PE_pcrel;
478 if (hdr.id == (unsigned int) -1)
479 break;
481 last_cie_ndx = sec_info->count;
482 sec_info->entry[sec_info->count].cie = 1;
484 cie_usage_count = 0;
485 memset (&cie, 0, sizeof (cie));
486 cie.hdr = hdr;
487 cie.version = *buf++;
489 /* Cannot handle unknown versions. */
490 if (cie.version != 1)
491 goto free_no_table;
492 if (strlen (buf) > sizeof (cie.augmentation) - 1)
493 goto free_no_table;
495 strcpy (cie.augmentation, buf);
496 buf = strchr (buf, '\0') + 1;
497 ENSURE_NO_RELOCS (buf);
498 if (buf[0] == 'e' && buf[1] == 'h')
500 /* GCC < 3.0 .eh_frame CIE */
501 /* We cannot merge "eh" CIEs because __EXCEPTION_TABLE__
502 is private to each CIE, so we don't need it for anything.
503 Just skip it. */
504 buf += ptr_size;
505 SKIP_RELOCS (buf);
507 read_uleb128 (cie.code_align, buf);
508 read_sleb128 (cie.data_align, buf);
509 /* Note - in DWARF2 the return address column is an unsigned byte.
510 In DWARF3 it is a ULEB128. We are following DWARF3. For most
511 ports this will not matter as the value will be less than 128.
512 For the others (eg FRV, SH, MMIX, IA64) they need a fixed GCC
513 which conforms to the DWARF3 standard. */
514 read_uleb128 (cie.ra_column, buf);
515 ENSURE_NO_RELOCS (buf);
516 cie.lsda_encoding = DW_EH_PE_omit;
517 cie.fde_encoding = DW_EH_PE_omit;
518 cie.per_encoding = DW_EH_PE_omit;
519 aug = cie.augmentation;
520 if (aug[0] != 'e' || aug[1] != 'h')
522 if (*aug == 'z')
524 aug++;
525 read_uleb128 (cie.augmentation_size, buf);
526 ENSURE_NO_RELOCS (buf);
529 while (*aug != '\0')
530 switch (*aug++)
532 case 'L':
533 cie.lsda_encoding = *buf++;
534 ENSURE_NO_RELOCS (buf);
535 if (get_DW_EH_PE_width (cie.lsda_encoding, ptr_size) == 0)
536 goto free_no_table;
537 break;
538 case 'R':
539 cie.fde_encoding = *buf++;
540 ENSURE_NO_RELOCS (buf);
541 if (get_DW_EH_PE_width (cie.fde_encoding, ptr_size) == 0)
542 goto free_no_table;
543 break;
544 case 'P':
546 int per_width;
548 cie.per_encoding = *buf++;
549 per_width = get_DW_EH_PE_width (cie.per_encoding,
550 ptr_size);
551 if (per_width == 0)
552 goto free_no_table;
553 if ((cie.per_encoding & 0xf0) == DW_EH_PE_aligned)
554 buf = (ehbuf
555 + ((buf - ehbuf + per_width - 1)
556 & ~((bfd_size_type) per_width - 1)));
557 ENSURE_NO_RELOCS (buf);
558 rel = GET_RELOC (buf);
559 /* Ensure we have a reloc here, against
560 a global symbol. */
561 if (rel != NULL)
563 unsigned long r_symndx;
565 #ifdef BFD64
566 if (ptr_size == 8)
567 r_symndx = ELF64_R_SYM (cookie->rel->r_info);
568 else
569 #endif
570 r_symndx = ELF32_R_SYM (cookie->rel->r_info);
571 if (r_symndx >= cookie->locsymcount)
573 struct elf_link_hash_entry *h;
575 r_symndx -= cookie->extsymoff;
576 h = cookie->sym_hashes[r_symndx];
578 while (h->root.type == bfd_link_hash_indirect
579 || h->root.type == bfd_link_hash_warning)
580 h = (struct elf_link_hash_entry *)
581 h->root.u.i.link;
583 cie.personality = h;
585 cookie->rel++;
587 buf += per_width;
589 break;
590 default:
591 /* Unrecognized augmentation. Better bail out. */
592 goto free_no_table;
596 /* For shared libraries, try to get rid of as many RELATIVE relocs
597 as possible. */
598 if (info->shared
599 && (cie.fde_encoding & 0xf0) == DW_EH_PE_absptr)
600 cie.make_relative = 1;
602 if (info->shared
603 && (cie.lsda_encoding & 0xf0) == DW_EH_PE_absptr)
604 cie.make_lsda_relative = 1;
606 /* If FDE encoding was not specified, it defaults to
607 DW_EH_absptr. */
608 if (cie.fde_encoding == DW_EH_PE_omit)
609 cie.fde_encoding = DW_EH_PE_absptr;
611 initial_insn_length = cie.hdr.length - (buf - last_fde - 4);
612 if (initial_insn_length <= 50)
614 cie.initial_insn_length = initial_insn_length;
615 memcpy (cie.initial_instructions, buf, initial_insn_length);
617 buf += initial_insn_length;
618 ENSURE_NO_RELOCS (buf);
619 last_cie = last_fde;
621 else
623 /* Ensure this FDE uses the last CIE encountered. */
624 if (last_cie == NULL
625 || hdr.id != (unsigned int) (buf - 4 - last_cie))
626 goto free_no_table;
628 ENSURE_NO_RELOCS (buf);
629 rel = GET_RELOC (buf);
630 if (rel == NULL)
631 /* This should not happen. */
632 goto free_no_table;
633 if ((*reloc_symbol_deleted_p) (buf - ehbuf, cookie))
635 /* This is a FDE against discarded section, it should
636 be deleted. */
637 new_size -= hdr.length + 4;
638 sec_info->entry[sec_info->count].removed = 1;
639 memset (rel, 0, sizeof (*rel));
641 else
643 if (info->shared
644 && (((cie.fde_encoding & 0xf0) == DW_EH_PE_absptr
645 && cie.make_relative == 0)
646 || (cie.fde_encoding & 0xf0) == DW_EH_PE_aligned))
648 /* If shared library uses absolute pointers
649 which we cannot turn into PC relative,
650 don't create the binary search table,
651 since it is affected by runtime relocations. */
652 hdr_info->table = false;
654 cie_usage_count++;
655 hdr_info->fde_count++;
657 cookie->rel = rel;
658 if (cie.lsda_encoding != DW_EH_PE_omit)
660 unsigned int dummy;
662 aug = buf;
663 buf += 2 * get_DW_EH_PE_width (cie.fde_encoding, ptr_size);
664 if (cie.augmentation[0] == 'z')
665 read_uleb128 (dummy, buf);
666 /* If some new augmentation data is added before LSDA
667 in FDE augmentation area, this need to be adjusted. */
668 sec_info->entry[sec_info->count].lsda_offset = (buf - aug);
670 buf = last_fde + 4 + hdr.length;
671 SKIP_RELOCS (buf);
674 sec_info->entry[sec_info->count].fde_encoding = cie.fde_encoding;
675 sec_info->entry[sec_info->count].lsda_encoding = cie.lsda_encoding;
676 sec_info->count++;
679 elf_section_data (sec)->sec_info = sec_info;
680 elf_section_data (sec)->sec_info_type = ELF_INFO_TYPE_EH_FRAME;
682 /* Ok, now we can assign new offsets. */
683 offset = 0;
684 last_cie_ndx = 0;
685 for (i = 0; i < sec_info->count; i++)
687 if (! sec_info->entry[i].removed)
689 sec_info->entry[i].new_offset = offset;
690 offset += sec_info->entry[i].size;
691 if (sec_info->entry[i].cie)
693 last_cie_ndx = i;
694 make_relative = sec_info->entry[i].make_relative;
695 make_lsda_relative = sec_info->entry[i].make_lsda_relative;
697 else
699 sec_info->entry[i].make_relative = make_relative;
700 sec_info->entry[i].make_lsda_relative = make_lsda_relative;
701 sec_info->entry[i].per_encoding_relative = 0;
704 else if (sec_info->entry[i].cie && sec_info->entry[i].sec == sec)
706 /* Need to adjust new_offset too. */
707 BFD_ASSERT (sec_info->entry[last_cie_ndx].offset
708 == sec_info->entry[i].new_offset);
709 sec_info->entry[i].new_offset
710 = sec_info->entry[last_cie_ndx].new_offset;
713 if (hdr_info->last_cie_sec == sec)
715 BFD_ASSERT (sec_info->entry[last_cie_ndx].offset
716 == hdr_info->last_cie_offset);
717 hdr_info->last_cie_offset = sec_info->entry[last_cie_ndx].new_offset;
720 /* FIXME: Currently it is not possible to shrink sections to zero size at
721 this point, so build a fake minimal CIE. */
722 if (new_size == 0)
723 new_size = 16;
725 /* Shrink the sec as needed. */
726 sec->_cooked_size = new_size;
727 if (sec->_cooked_size == 0)
728 sec->flags |= SEC_EXCLUDE;
730 free (ehbuf);
731 return new_size != sec->_raw_size;
733 free_no_table:
734 if (ehbuf)
735 free (ehbuf);
736 if (sec_info)
737 free (sec_info);
738 hdr_info->table = false;
739 hdr_info->last_cie.hdr.length = 0;
740 return false;
743 /* This function is called for .eh_frame_hdr section after
744 _bfd_elf_discard_section_eh_frame has been called on all .eh_frame
745 input sections. It finalizes the size of .eh_frame_hdr section. */
747 boolean
748 _bfd_elf_discard_section_eh_frame_hdr (abfd, info, sec)
749 bfd *abfd;
750 struct bfd_link_info *info;
751 asection *sec;
753 struct eh_frame_hdr_info *hdr_info;
754 unsigned int ptr_size;
756 ptr_size = (elf_elfheader (abfd)->e_ident[EI_CLASS]
757 == ELFCLASS64) ? 8 : 4;
759 if ((elf_section_data (sec)->sec_info_type
760 != ELF_INFO_TYPE_EH_FRAME_HDR)
761 || ! info->eh_frame_hdr)
763 _bfd_strip_section_from_output (info, sec);
764 return false;
767 hdr_info = (struct eh_frame_hdr_info *)
768 elf_section_data (sec)->sec_info;
769 if (hdr_info->strip)
770 return false;
771 sec->_cooked_size = EH_FRAME_HDR_SIZE;
772 if (hdr_info->table)
773 sec->_cooked_size += 4 + hdr_info->fde_count * 8;
775 /* Request program headers to be recalculated. */
776 elf_tdata (abfd)->program_header_size = 0;
777 elf_tdata (abfd)->eh_frame_hdr = true;
778 return true;
781 /* This function is called from size_dynamic_sections.
782 It needs to decide whether .eh_frame_hdr should be output or not,
783 because later on it is too late for calling _bfd_strip_section_from_output,
784 since dynamic symbol table has been sized. */
786 boolean
787 _bfd_elf_maybe_strip_eh_frame_hdr (info)
788 struct bfd_link_info *info;
790 asection *sec, *o;
791 bfd *abfd;
792 struct eh_frame_hdr_info *hdr_info;
794 sec = bfd_get_section_by_name (elf_hash_table (info)->dynobj, ".eh_frame_hdr");
795 if (sec == NULL || bfd_is_abs_section (sec->output_section))
796 return true;
798 hdr_info
799 = bfd_zmalloc (sizeof (struct eh_frame_hdr_info));
800 if (hdr_info == NULL)
801 return false;
803 elf_section_data (sec)->sec_info = hdr_info;
804 elf_section_data (sec)->sec_info_type = ELF_INFO_TYPE_EH_FRAME_HDR;
806 abfd = NULL;
807 if (info->eh_frame_hdr)
808 for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
810 /* Count only sections which have at least a single CIE or FDE.
811 There cannot be any CIE or FDE <= 8 bytes. */
812 o = bfd_get_section_by_name (abfd, ".eh_frame");
813 if (o && o->_raw_size > 8 && !bfd_is_abs_section (o->output_section))
814 break;
817 if (abfd == NULL)
819 _bfd_strip_section_from_output (info, sec);
820 hdr_info->strip = true;
822 else
823 hdr_info->table = true;
824 return true;
827 /* Adjust an address in the .eh_frame section. Given OFFSET within
828 SEC, this returns the new offset in the adjusted .eh_frame section,
829 or -1 if the address refers to a CIE/FDE which has been removed
830 or to offset with dynamic relocation which is no longer needed. */
832 bfd_vma
833 _bfd_elf_eh_frame_section_offset (output_bfd, sec, offset)
834 bfd *output_bfd ATTRIBUTE_UNUSED;
835 asection *sec;
836 bfd_vma offset;
838 struct eh_frame_sec_info *sec_info;
839 unsigned int lo, hi, mid;
841 if (elf_section_data (sec)->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
842 return offset;
843 sec_info = (struct eh_frame_sec_info *)
844 elf_section_data (sec)->sec_info;
846 if (offset >= sec->_raw_size)
847 return offset - (sec->_cooked_size - sec->_raw_size);
849 lo = 0;
850 hi = sec_info->count;
851 mid = 0;
852 while (lo < hi)
854 mid = (lo + hi) / 2;
855 if (offset < sec_info->entry[mid].offset)
856 hi = mid;
857 else if (offset
858 >= sec_info->entry[mid].offset + sec_info->entry[mid].size)
859 lo = mid + 1;
860 else
861 break;
864 BFD_ASSERT (lo < hi);
866 /* FDE or CIE was removed. */
867 if (sec_info->entry[mid].removed)
868 return (bfd_vma) -1;
870 /* If converting to DW_EH_PE_pcrel, there will be no need for run-time
871 relocation against FDE's initial_location field. */
872 if (sec_info->entry[mid].make_relative
873 && ! sec_info->entry[mid].cie
874 && offset == sec_info->entry[mid].offset + 8)
875 return (bfd_vma) -2;
877 /* If converting LSDA pointers to DW_EH_PE_pcrel, there will be no need
878 for run-time relocation against LSDA field. */
879 if (sec_info->entry[mid].make_lsda_relative
880 && ! sec_info->entry[mid].cie
881 && (offset
882 == (sec_info->entry[mid].offset + 8
883 + sec_info->entry[mid].lsda_offset)))
884 return (bfd_vma) -2;
886 return (offset + sec_info->entry[mid].new_offset
887 - sec_info->entry[mid].offset);
890 /* Write out .eh_frame section. This is called with the relocated
891 contents. */
893 boolean
894 _bfd_elf_write_section_eh_frame (abfd, sec, ehdrsec, contents)
895 bfd *abfd;
896 asection *sec, *ehdrsec;
897 bfd_byte *contents;
899 struct eh_frame_sec_info *sec_info;
900 struct eh_frame_hdr_info *hdr_info;
901 unsigned int i;
902 bfd_byte *p, *buf;
903 unsigned int leb128_tmp;
904 unsigned int cie_offset = 0;
905 unsigned int ptr_size;
907 ptr_size = (elf_elfheader (sec->owner)->e_ident[EI_CLASS]
908 == ELFCLASS64) ? 8 : 4;
910 if (elf_section_data (sec)->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
911 return bfd_set_section_contents (abfd, sec->output_section,
912 contents,
913 (file_ptr) sec->output_offset,
914 sec->_raw_size);
915 sec_info = (struct eh_frame_sec_info *)
916 elf_section_data (sec)->sec_info;
917 hdr_info = NULL;
918 if (ehdrsec
919 && (elf_section_data (ehdrsec)->sec_info_type
920 == ELF_INFO_TYPE_EH_FRAME_HDR))
922 hdr_info = (struct eh_frame_hdr_info *)
923 elf_section_data (ehdrsec)->sec_info;
924 if (hdr_info->table && hdr_info->array == NULL)
925 hdr_info->array
926 = bfd_malloc (hdr_info->fde_count * sizeof(*hdr_info->array));
927 if (hdr_info->array == NULL)
928 hdr_info = NULL;
931 p = contents;
932 for (i = 0; i < sec_info->count; ++i)
934 if (sec_info->entry[i].removed)
936 if (sec_info->entry[i].cie)
938 /* If CIE is removed due to no remaining FDEs referencing it
939 and there were no CIEs kept before it, sec_info->entry[i].sec
940 will be zero. */
941 if (sec_info->entry[i].sec == NULL)
942 cie_offset = 0;
943 else
945 cie_offset = sec_info->entry[i].new_offset;
946 cie_offset += (sec_info->entry[i].sec->output_section->vma
947 + sec_info->entry[i].sec->output_offset
948 - sec->output_section->vma
949 - sec->output_offset);
952 continue;
955 if (sec_info->entry[i].cie)
957 /* CIE */
958 cie_offset = sec_info->entry[i].new_offset;
959 if (sec_info->entry[i].make_relative
960 || sec_info->entry[i].make_lsda_relative
961 || sec_info->entry[i].per_encoding_relative)
963 unsigned char *aug;
964 unsigned int action;
965 unsigned int dummy, per_width, per_encoding;
967 /* Need to find 'R' or 'L' augmentation's argument and modify
968 DW_EH_PE_* value. */
969 action = (sec_info->entry[i].make_relative ? 1 : 0)
970 | (sec_info->entry[i].make_lsda_relative ? 2 : 0)
971 | (sec_info->entry[i].per_encoding_relative ? 4 : 0);
972 buf = contents + sec_info->entry[i].offset;
973 /* Skip length, id and version. */
974 buf += 9;
975 aug = buf;
976 buf = strchr (buf, '\0') + 1;
977 read_uleb128 (dummy, buf);
978 read_sleb128 (dummy, buf);
979 read_uleb128 (dummy, buf);
980 if (*aug == 'z')
982 read_uleb128 (dummy, buf);
983 aug++;
986 while (action)
987 switch (*aug++)
989 case 'L':
990 if (action & 2)
992 BFD_ASSERT (*buf == sec_info->entry[i].lsda_encoding);
993 *buf |= DW_EH_PE_pcrel;
994 action &= ~2;
996 buf++;
997 break;
998 case 'P':
999 per_encoding = *buf++;
1000 per_width = get_DW_EH_PE_width (per_encoding,
1001 ptr_size);
1002 BFD_ASSERT (per_width != 0);
1003 BFD_ASSERT (((per_encoding & 0x70) == DW_EH_PE_pcrel)
1004 == sec_info->entry[i].per_encoding_relative);
1005 if ((per_encoding & 0xf0) == DW_EH_PE_aligned)
1006 buf = (contents
1007 + ((buf - contents + per_width - 1)
1008 & ~((bfd_size_type) per_width - 1)));
1009 if (action & 4)
1011 bfd_vma value;
1013 value = read_value (abfd, buf, per_width);
1014 value += (sec_info->entry[i].offset
1015 - sec_info->entry[i].new_offset);
1016 write_value (abfd, buf, value, per_width);
1017 action &= ~4;
1019 buf += per_width;
1020 break;
1021 case 'R':
1022 if (action & 1)
1024 BFD_ASSERT (*buf == sec_info->entry[i].fde_encoding);
1025 *buf |= DW_EH_PE_pcrel;
1026 action &= ~1;
1028 buf++;
1029 break;
1030 default:
1031 BFD_FAIL ();
1035 else if (sec_info->entry[i].size > 4)
1037 /* FDE */
1038 bfd_vma value = 0, address;
1039 unsigned int width;
1041 buf = contents + sec_info->entry[i].offset;
1042 /* Skip length. */
1043 buf += 4;
1044 bfd_put_32 (abfd,
1045 sec_info->entry[i].new_offset + 4 - cie_offset, buf);
1046 buf += 4;
1047 width = get_DW_EH_PE_width (sec_info->entry[i].fde_encoding,
1048 ptr_size);
1049 address = value = read_value (abfd, buf, width);
1050 if (value)
1052 switch (sec_info->entry[i].fde_encoding & 0xf0)
1054 case DW_EH_PE_indirect:
1055 case DW_EH_PE_textrel:
1056 BFD_ASSERT (hdr_info == NULL);
1057 break;
1058 case DW_EH_PE_datarel:
1060 asection *got = bfd_get_section_by_name (abfd, ".got");
1062 BFD_ASSERT (got != NULL);
1063 address += got->vma;
1065 break;
1066 case DW_EH_PE_pcrel:
1067 value += (sec_info->entry[i].offset
1068 - sec_info->entry[i].new_offset);
1069 address += (sec->output_section->vma + sec->output_offset
1070 + sec_info->entry[i].offset + 8);
1071 break;
1073 if (sec_info->entry[i].make_relative)
1074 value -= (sec->output_section->vma + sec->output_offset
1075 + sec_info->entry[i].new_offset + 8);
1076 write_value (abfd, buf, value, width);
1079 if (hdr_info)
1081 hdr_info->array[hdr_info->array_count].initial_loc = address;
1082 hdr_info->array[hdr_info->array_count++].fde
1083 = (sec->output_section->vma + sec->output_offset
1084 + sec_info->entry[i].new_offset);
1087 if ((sec_info->entry[i].lsda_encoding & 0xf0) == DW_EH_PE_pcrel
1088 || sec_info->entry[i].make_lsda_relative)
1090 buf += sec_info->entry[i].lsda_offset;
1091 width = get_DW_EH_PE_width (sec_info->entry[i].lsda_encoding,
1092 ptr_size);
1093 value = read_value (abfd, buf, width);
1094 if (value)
1096 if ((sec_info->entry[i].lsda_encoding & 0xf0)
1097 == DW_EH_PE_pcrel)
1098 value += (sec_info->entry[i].offset
1099 - sec_info->entry[i].new_offset);
1100 else if (sec_info->entry[i].make_lsda_relative)
1101 value -= (sec->output_section->vma + sec->output_offset
1102 + sec_info->entry[i].new_offset + 8
1103 + sec_info->entry[i].lsda_offset);
1104 write_value (abfd, buf, value, width);
1108 else
1109 /* Terminating FDE must be at the end of .eh_frame section only. */
1110 BFD_ASSERT (i == sec_info->count - 1);
1112 BFD_ASSERT (p == contents + sec_info->entry[i].new_offset);
1113 memmove (p, contents + sec_info->entry[i].offset,
1114 sec_info->entry[i].size);
1115 p += sec_info->entry[i].size;
1118 /* FIXME: Once _bfd_elf_discard_section_eh_frame will be able to
1119 shrink sections to zero size, this won't be needed any more. */
1120 if (p == contents && sec->_cooked_size == 16)
1122 bfd_put_32 (abfd, 12, p); /* Fake CIE length */
1123 bfd_put_32 (abfd, 0, p + 4); /* Fake CIE id */
1124 p[8] = 1; /* Fake CIE version */
1125 memset (p + 9, 0, 7); /* Fake CIE augmentation, 3xleb128
1126 and 3xDW_CFA_nop as pad */
1127 p += 16;
1130 BFD_ASSERT ((bfd_size_type) (p - contents) == sec->_cooked_size);
1132 return bfd_set_section_contents (abfd, sec->output_section,
1133 contents, (file_ptr) sec->output_offset,
1134 sec->_cooked_size);
1137 /* Helper function used to sort .eh_frame_hdr search table by increasing
1138 VMA of FDE initial location. */
1140 static int
1141 vma_compare (a, b)
1142 const PTR a;
1143 const PTR b;
1145 struct eh_frame_array_ent *p = (struct eh_frame_array_ent *) a;
1146 struct eh_frame_array_ent *q = (struct eh_frame_array_ent *) b;
1147 if (p->initial_loc > q->initial_loc)
1148 return 1;
1149 if (p->initial_loc < q->initial_loc)
1150 return -1;
1151 return 0;
1154 /* Write out .eh_frame_hdr section. This must be called after
1155 _bfd_elf_write_section_eh_frame has been called on all input
1156 .eh_frame sections.
1157 .eh_frame_hdr format:
1158 ubyte version (currently 1)
1159 ubyte eh_frame_ptr_enc (DW_EH_PE_* encoding of pointer to start of
1160 .eh_frame section)
1161 ubyte fde_count_enc (DW_EH_PE_* encoding of total FDE count
1162 number (or DW_EH_PE_omit if there is no
1163 binary search table computed))
1164 ubyte table_enc (DW_EH_PE_* encoding of binary search table,
1165 or DW_EH_PE_omit if not present.
1166 DW_EH_PE_datarel is using address of
1167 .eh_frame_hdr section start as base)
1168 [encoded] eh_frame_ptr (pointer to start of .eh_frame section)
1169 optionally followed by:
1170 [encoded] fde_count (total number of FDEs in .eh_frame section)
1171 fde_count x [encoded] initial_loc, fde
1172 (array of encoded pairs containing
1173 FDE initial_location field and FDE address,
1174 sorted by increasing initial_loc) */
1176 boolean
1177 _bfd_elf_write_section_eh_frame_hdr (abfd, sec)
1178 bfd *abfd;
1179 asection *sec;
1181 struct eh_frame_hdr_info *hdr_info;
1182 unsigned int ptr_size;
1183 bfd_byte *contents;
1184 asection *eh_frame_sec;
1185 bfd_size_type size;
1187 ptr_size = (elf_elfheader (sec->owner)->e_ident[EI_CLASS]
1188 == ELFCLASS64) ? 8 : 4;
1190 BFD_ASSERT (elf_section_data (sec)->sec_info_type
1191 == ELF_INFO_TYPE_EH_FRAME_HDR);
1192 hdr_info = (struct eh_frame_hdr_info *)
1193 elf_section_data (sec)->sec_info;
1194 if (hdr_info->strip)
1195 return true;
1197 size = EH_FRAME_HDR_SIZE;
1198 if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
1199 size += 4 + hdr_info->fde_count * 8;
1200 contents = bfd_malloc (size);
1201 if (contents == NULL)
1202 return false;
1204 eh_frame_sec = bfd_get_section_by_name (abfd, ".eh_frame");
1205 if (eh_frame_sec == NULL)
1206 return false;
1208 memset (contents, 0, EH_FRAME_HDR_SIZE);
1209 contents[0] = 1; /* Version */
1210 contents[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4; /* .eh_frame offset */
1211 if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
1213 contents[2] = DW_EH_PE_udata4; /* FDE count encoding */
1214 contents[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4; /* search table enc */
1216 else
1218 contents[2] = DW_EH_PE_omit;
1219 contents[3] = DW_EH_PE_omit;
1221 bfd_put_32 (abfd, eh_frame_sec->vma - sec->output_section->vma - 4,
1222 contents + 4);
1223 if (contents[2] != DW_EH_PE_omit)
1225 unsigned int i;
1227 bfd_put_32 (abfd, hdr_info->fde_count, contents + EH_FRAME_HDR_SIZE);
1228 qsort (hdr_info->array, hdr_info->fde_count, sizeof (*hdr_info->array),
1229 vma_compare);
1230 for (i = 0; i < hdr_info->fde_count; i++)
1232 bfd_put_32 (abfd,
1233 hdr_info->array[i].initial_loc
1234 - sec->output_section->vma,
1235 contents + EH_FRAME_HDR_SIZE + i * 8 + 4);
1236 bfd_put_32 (abfd,
1237 hdr_info->array[i].fde - sec->output_section->vma,
1238 contents + EH_FRAME_HDR_SIZE + i * 8 + 8);
1242 return bfd_set_section_contents (abfd, sec->output_section,
1243 contents, (file_ptr) sec->output_offset,
1244 sec->_cooked_size);