* elf-eh-frame.c (_bfd_elf_eh_frame_section_offset): Avoid
[deliverable/binutils-gdb.git] / bfd / elf-eh-frame.c
1 /* .eh_frame section optimization.
2 Copyright 2001, 2002 Free Software Foundation, Inc.
3 Written by Jakub Jelinek <jakub@redhat.com>.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
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.
11
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.
16
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. */
20
21 #include "bfd.h"
22 #include "sysdep.h"
23 #include "libbfd.h"
24 #include "elf-bfd.h"
25 #include "elf/dwarf2.h"
26
27 #define EH_FRAME_HDR_SIZE 8
28
29 struct cie_header
30 {
31 unsigned int length;
32 unsigned int id;
33 };
34
35 struct cie
36 {
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];
52 };
53
54 struct eh_cie_fde
55 {
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 };
68
69 struct eh_frame_sec_info
70 {
71 unsigned int count;
72 unsigned int alloced;
73 struct eh_cie_fde entry[1];
74 };
75
76 struct eh_frame_array_ent
77 {
78 bfd_vma initial_loc;
79 bfd_vma fde;
80 };
81
82 struct eh_frame_hdr_info
83 {
84 struct cie last_cie;
85 asection *last_cie_sec;
86 unsigned int last_cie_offset;
87 unsigned int fde_count, array_count;
88 struct eh_frame_array_ent *array;
89 /* TRUE if .eh_frame_hdr should contain the sorted search table.
90 We build it if we successfully read all .eh_frame input sections
91 and recognize them. */
92 boolean table;
93 boolean strip;
94 };
95
96 static bfd_vma read_unsigned_leb128
97 PARAMS ((bfd *, char *, unsigned int *));
98 static bfd_signed_vma read_signed_leb128
99 PARAMS ((bfd *, char *, unsigned int *));
100 static int get_DW_EH_PE_width
101 PARAMS ((int, int));
102 static bfd_vma read_value
103 PARAMS ((bfd *, bfd_byte *, int));
104 static void write_value
105 PARAMS ((bfd *, bfd_byte *, bfd_vma, int));
106 static int cie_compare
107 PARAMS ((struct cie *, struct cie *));
108 static int vma_compare
109 PARAMS ((const PTR a, const PTR b));
110
111 /* Helper function for reading uleb128 encoded data. */
112
113 static bfd_vma
114 read_unsigned_leb128 (abfd, buf, bytes_read_ptr)
115 bfd *abfd ATTRIBUTE_UNUSED;
116 char *buf;
117 unsigned int *bytes_read_ptr;
118 {
119 bfd_vma result;
120 unsigned int num_read;
121 int shift;
122 unsigned char byte;
123
124 result = 0;
125 shift = 0;
126 num_read = 0;
127 do
128 {
129 byte = bfd_get_8 (abfd, (bfd_byte *) buf);
130 buf ++;
131 num_read ++;
132 result |= (((bfd_vma) byte & 0x7f) << shift);
133 shift += 7;
134 }
135 while (byte & 0x80);
136 * bytes_read_ptr = num_read;
137 return result;
138 }
139
140 /* Helper function for reading sleb128 encoded data. */
141
142 static bfd_signed_vma
143 read_signed_leb128 (abfd, buf, bytes_read_ptr)
144 bfd *abfd ATTRIBUTE_UNUSED;
145 char *buf;
146 unsigned int * bytes_read_ptr;
147 {
148 bfd_vma result;
149 int shift;
150 int num_read;
151 unsigned char byte;
152
153 result = 0;
154 shift = 0;
155 num_read = 0;
156 do
157 {
158 byte = bfd_get_8 (abfd, (bfd_byte *) buf);
159 buf ++;
160 num_read ++;
161 result |= (((bfd_vma) byte & 0x7f) << shift);
162 shift += 7;
163 }
164 while (byte & 0x80);
165 if (byte & 0x40)
166 result |= (((bfd_vma) -1) << (shift - 7)) << 7;
167 * bytes_read_ptr = num_read;
168 return result;
169 }
170
171 #define read_uleb128(VAR, BUF) \
172 do \
173 { \
174 (VAR) = read_unsigned_leb128 (abfd, buf, &leb128_tmp); \
175 (BUF) += leb128_tmp; \
176 } \
177 while (0)
178
179 #define read_sleb128(VAR, BUF) \
180 do \
181 { \
182 (VAR) = read_signed_leb128 (abfd, buf, &leb128_tmp); \
183 (BUF) += leb128_tmp; \
184 } \
185 while (0)
186
187 /* Return 0 if either encoding is variable width, or not yet known to bfd. */
188
189 static
190 int get_DW_EH_PE_width (encoding, ptr_size)
191 int encoding, ptr_size;
192 {
193 /* DW_EH_PE_ values of 0x60 and 0x70 weren't defined at the time .eh_frame
194 was added to bfd. */
195 if ((encoding & 0x60) == 0x60)
196 return 0;
197
198 switch (encoding & 7)
199 {
200 case DW_EH_PE_udata2: return 2;
201 case DW_EH_PE_udata4: return 4;
202 case DW_EH_PE_udata8: return 8;
203 case DW_EH_PE_absptr: return ptr_size;
204 default:
205 break;
206 }
207
208 return 0;
209 }
210
211 /* Read a width sized value from memory. */
212
213 static bfd_vma
214 read_value (abfd, buf, width)
215 bfd *abfd;
216 bfd_byte *buf;
217 int width;
218 {
219 bfd_vma value;
220
221 switch (width)
222 {
223 case 2: value = bfd_get_16 (abfd, buf); break;
224 case 4: value = bfd_get_32 (abfd, buf); break;
225 case 8: value = bfd_get_64 (abfd, buf); break;
226 default: BFD_FAIL (); return 0;
227 }
228
229 return value;
230 }
231
232 /* Store a width sized value to memory. */
233
234 static void
235 write_value (abfd, buf, value, width)
236 bfd *abfd;
237 bfd_byte *buf;
238 bfd_vma value;
239 int width;
240 {
241 switch (width)
242 {
243 case 2: bfd_put_16 (abfd, value, buf); break;
244 case 4: bfd_put_32 (abfd, value, buf); break;
245 case 8: bfd_put_64 (abfd, value, buf); break;
246 default: BFD_FAIL ();
247 }
248 }
249
250 /* Return zero if C1 and C2 CIEs can be merged. */
251
252 static
253 int cie_compare (c1, c2)
254 struct cie *c1, *c2;
255 {
256 if (c1->hdr.length == c2->hdr.length
257 && c1->version == c2->version
258 && strcmp (c1->augmentation, c2->augmentation) == 0
259 && strcmp (c1->augmentation, "eh") != 0
260 && c1->code_align == c2->code_align
261 && c1->data_align == c2->data_align
262 && c1->ra_column == c2->ra_column
263 && c1->augmentation_size == c2->augmentation_size
264 && c1->personality == c2->personality
265 && c1->per_encoding == c2->per_encoding
266 && c1->lsda_encoding == c2->lsda_encoding
267 && c1->fde_encoding == c2->fde_encoding
268 && (c1->initial_insn_length
269 == c2->initial_insn_length)
270 && memcmp (c1->initial_instructions,
271 c2->initial_instructions,
272 c1->initial_insn_length) == 0)
273 return 0;
274
275 return 1;
276 }
277
278 /* This function is called for each input file before the .eh_frame
279 section is relocated. It discards duplicate CIEs and FDEs for discarded
280 functions. The function returns true iff any entries have been
281 deleted. */
282
283 boolean
284 _bfd_elf_discard_section_eh_frame (abfd, info, sec, ehdrsec,
285 reloc_symbol_deleted_p, cookie)
286 bfd *abfd;
287 struct bfd_link_info *info;
288 asection *sec, *ehdrsec;
289 boolean (*reloc_symbol_deleted_p) (bfd_vma, PTR);
290 struct elf_reloc_cookie *cookie;
291 {
292 bfd_byte *ehbuf = NULL, *buf;
293 bfd_byte *last_cie, *last_fde;
294 struct cie_header hdr;
295 struct cie cie;
296 struct eh_frame_hdr_info *hdr_info;
297 struct eh_frame_sec_info *sec_info = NULL;
298 unsigned int leb128_tmp;
299 unsigned int cie_usage_count, last_cie_ndx, i, offset;
300 unsigned int make_relative, make_lsda_relative;
301 Elf_Internal_Rela *rel;
302 bfd_size_type new_size;
303 unsigned int ptr_size;
304
305 if (sec->_raw_size == 0)
306 {
307 /* This file does not contain .eh_frame information. */
308 return false;
309 }
310
311 if ((sec->output_section != NULL
312 && bfd_is_abs_section (sec->output_section)))
313 {
314 /* At least one of the sections is being discarded from the
315 link, so we should just ignore them. */
316 return false;
317 }
318
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;
323
324 /* Read the frame unwind information from abfd. */
325
326 ehbuf = (bfd_byte *) bfd_malloc (sec->_raw_size);
327 if (ehbuf == NULL)
328 goto free_no_table;
329
330 if (! bfd_get_section_contents (abfd, sec, ehbuf, (bfd_vma) 0,
331 sec->_raw_size))
332 goto free_no_table;
333
334 if (sec->_raw_size >= 4
335 && bfd_get_32 (abfd, ehbuf) == 0
336 && cookie->rel == cookie->relend)
337 {
338 /* Empty .eh_frame section. */
339 free (ehbuf);
340 return false;
341 }
342
343 /* If .eh_frame section size doesn't fit into int, we cannot handle
344 it (it would need to use 64-bit .eh_frame format anyway). */
345 if (sec->_raw_size != (unsigned int) sec->_raw_size)
346 goto free_no_table;
347
348 ptr_size = (elf_elfheader (abfd)->e_ident[EI_CLASS]
349 == ELFCLASS64) ? 8 : 4;
350 buf = ehbuf;
351 last_cie = NULL;
352 last_cie_ndx = 0;
353 memset (&cie, 0, sizeof (cie));
354 cie_usage_count = 0;
355 new_size = sec->_raw_size;
356 make_relative = hdr_info->last_cie.make_relative;
357 make_lsda_relative = hdr_info->last_cie.make_lsda_relative;
358 sec_info = bfd_zmalloc (sizeof (struct eh_frame_sec_info)
359 + 99 * sizeof (struct eh_cie_fde));
360 if (sec_info == NULL)
361 goto free_no_table;
362 sec_info->alloced = 100;
363
364 #define ENSURE_NO_RELOCS(buf) \
365 if (cookie->rel < cookie->relend \
366 && (cookie->rel->r_offset \
367 < (bfd_size_type) ((buf) - ehbuf))) \
368 goto free_no_table
369
370 #define SKIP_RELOCS(buf) \
371 while (cookie->rel < cookie->relend \
372 && (cookie->rel->r_offset \
373 < (bfd_size_type) ((buf) - ehbuf))) \
374 cookie->rel++
375
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)
381
382 for (;;)
383 {
384 unsigned char *aug;
385
386 if (sec_info->count == sec_info->alloced)
387 {
388 sec_info = bfd_realloc (sec_info,
389 sizeof (struct eh_frame_sec_info)
390 + (sec_info->alloced + 99)
391 * sizeof (struct eh_cie_fde));
392 if (sec_info == NULL)
393 goto free_no_table;
394
395 memset (&sec_info->entry[sec_info->alloced], 0,
396 100 * sizeof (struct eh_cie_fde));
397 sec_info->alloced += 100;
398 }
399
400 last_fde = buf;
401 /* If we are at the end of the section, we still need to decide
402 on whether to output or discard last encountered CIE (if any). */
403 if ((bfd_size_type) (buf - ehbuf) == sec->_raw_size)
404 hdr.id = (unsigned int) -1;
405 else
406 {
407 if ((bfd_size_type) (buf + 4 - ehbuf) > sec->_raw_size)
408 /* No space for CIE/FDE header length. */
409 goto free_no_table;
410
411 hdr.length = bfd_get_32 (abfd, buf);
412 if (hdr.length == 0xffffffff)
413 /* 64-bit .eh_frame is not supported. */
414 goto free_no_table;
415 buf += 4;
416 if ((buf - ehbuf) + hdr.length > sec->_raw_size)
417 /* CIE/FDE not contained fully in this .eh_frame input section. */
418 goto free_no_table;
419
420 sec_info->entry[sec_info->count].offset = last_fde - ehbuf;
421 sec_info->entry[sec_info->count].size = 4 + hdr.length;
422
423 if (hdr.length == 0)
424 {
425 /* CIE with length 0 must be only the last in the section. */
426 if ((bfd_size_type) (buf - ehbuf) < sec->_raw_size)
427 goto free_no_table;
428 ENSURE_NO_RELOCS (buf);
429 sec_info->count++;
430 /* Now just finish last encountered CIE processing and break
431 the loop. */
432 hdr.id = (unsigned int) -1;
433 }
434 else
435 {
436 hdr.id = bfd_get_32 (abfd, buf);
437 buf += 4;
438 if (hdr.id == (unsigned int) -1)
439 goto free_no_table;
440 }
441 }
442
443 if (hdr.id == 0 || hdr.id == (unsigned int) -1)
444 {
445 unsigned int initial_insn_length;
446
447 /* CIE */
448 if (last_cie != NULL)
449 {
450 /* Now check if this CIE is identical to last CIE, in which case
451 we can remove it, provided we adjust all FDEs.
452 Also, it can be removed if we have removed all FDEs using
453 that. */
454 if (cie_compare (&cie, &hdr_info->last_cie) == 0
455 || cie_usage_count == 0)
456 {
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;
462 }
463 else
464 {
465 hdr_info->last_cie = cie;
466 hdr_info->last_cie_sec = sec;
467 hdr_info->last_cie_offset = last_cie - ehbuf;
468 sec_info->entry[last_cie_ndx].make_relative
469 = cie.make_relative;
470 sec_info->entry[last_cie_ndx].make_lsda_relative
471 = cie.make_lsda_relative;
472 }
473 }
474
475 if (hdr.id == (unsigned int) -1)
476 break;
477
478 last_cie_ndx = sec_info->count;
479 sec_info->entry[sec_info->count].cie = 1;
480
481 cie_usage_count = 0;
482 memset (&cie, 0, sizeof (cie));
483 cie.hdr = hdr;
484 cie.version = *buf++;
485
486 /* Cannot handle unknown versions. */
487 if (cie.version != 1)
488 goto free_no_table;
489 if (strlen (buf) > sizeof (cie.augmentation) - 1)
490 goto free_no_table;
491
492 strcpy (cie.augmentation, buf);
493 buf = strchr (buf, '\0') + 1;
494 ENSURE_NO_RELOCS (buf);
495 if (buf[0] == 'e' && buf[1] == 'h')
496 {
497 /* GCC < 3.0 .eh_frame CIE */
498 /* We cannot merge "eh" CIEs because __EXCEPTION_TABLE__
499 is private to each CIE, so we don't need it for anything.
500 Just skip it. */
501 buf += ptr_size;
502 SKIP_RELOCS (buf);
503 }
504 read_uleb128 (cie.code_align, buf);
505 read_sleb128 (cie.data_align, buf);
506 read_uleb128 (cie.ra_column, buf);
507 ENSURE_NO_RELOCS (buf);
508 cie.lsda_encoding = DW_EH_PE_omit;
509 cie.fde_encoding = DW_EH_PE_omit;
510 cie.per_encoding = DW_EH_PE_omit;
511 aug = cie.augmentation;
512 if (aug[0] != 'e' || aug[1] != 'h')
513 {
514 if (*aug == 'z')
515 {
516 aug++;
517 read_uleb128 (cie.augmentation_size, buf);
518 ENSURE_NO_RELOCS (buf);
519 }
520
521 while (*aug != '\0')
522 switch (*aug++)
523 {
524 case 'L':
525 cie.lsda_encoding = *buf++;
526 ENSURE_NO_RELOCS (buf);
527 if (get_DW_EH_PE_width (cie.lsda_encoding, ptr_size) == 0)
528 goto free_no_table;
529 break;
530 case 'R':
531 cie.fde_encoding = *buf++;
532 ENSURE_NO_RELOCS (buf);
533 if (get_DW_EH_PE_width (cie.fde_encoding, ptr_size) == 0)
534 goto free_no_table;
535 break;
536 case 'P':
537 {
538 int per_width;
539
540 cie.per_encoding = *buf++;
541 per_width = get_DW_EH_PE_width (cie.per_encoding,
542 ptr_size);
543 if (per_width == 0)
544 goto free_no_table;
545 if ((cie.per_encoding & 0xf0) == DW_EH_PE_aligned)
546 buf = (ehbuf
547 + ((buf - ehbuf + per_width - 1)
548 & ~((bfd_size_type) per_width - 1)));
549 ENSURE_NO_RELOCS (buf);
550 rel = GET_RELOC (buf);
551 /* Ensure we have a reloc here, against
552 a global symbol. */
553 if (rel != NULL)
554 {
555 unsigned long r_symndx;
556
557 #ifdef BFD64
558 if (ptr_size == 8)
559 r_symndx = ELF64_R_SYM (cookie->rel->r_info);
560 else
561 #endif
562 r_symndx = ELF32_R_SYM (cookie->rel->r_info);
563 if (r_symndx >= cookie->locsymcount)
564 {
565 struct elf_link_hash_entry *h;
566
567 r_symndx -= cookie->extsymoff;
568 h = cookie->sym_hashes[r_symndx];
569
570 while (h->root.type == bfd_link_hash_indirect
571 || h->root.type == bfd_link_hash_warning)
572 h = (struct elf_link_hash_entry *)
573 h->root.u.i.link;
574
575 cie.personality = h;
576 }
577 cookie->rel++;
578 }
579 buf += per_width;
580 }
581 break;
582 default:
583 /* Unrecognized augmentation. Better bail out. */
584 goto free_no_table;
585 }
586 }
587
588 /* For shared libraries, try to get rid of as many RELATIVE relocs
589 as possible.
590 FIXME: For this to work, ELF backends need to perform the
591 relocation if omitting dynamic relocs, not skip it. */
592 if (0
593 && info->shared
594 && (cie.fde_encoding & 0xf0) == DW_EH_PE_absptr)
595 cie.make_relative = 1;
596
597 if (0
598 && info->shared
599 && (cie.lsda_encoding & 0xf0) == DW_EH_PE_absptr)
600 cie.make_lsda_relative = 1;
601
602 /* If FDE encoding was not specified, it defaults to
603 DW_EH_absptr. */
604 if (cie.fde_encoding == DW_EH_PE_omit)
605 cie.fde_encoding = DW_EH_PE_absptr;
606
607 initial_insn_length = cie.hdr.length - (buf - last_fde - 4);
608 if (initial_insn_length <= 50)
609 {
610 cie.initial_insn_length = initial_insn_length;
611 memcpy (cie.initial_instructions, buf, initial_insn_length);
612 }
613 buf += initial_insn_length;
614 ENSURE_NO_RELOCS (buf);
615 last_cie = last_fde;
616 }
617 else
618 {
619 /* Ensure this FDE uses the last CIE encountered. */
620 if (last_cie == NULL
621 || hdr.id != (unsigned int) (buf - 4 - last_cie))
622 goto free_no_table;
623
624 ENSURE_NO_RELOCS (buf);
625 rel = GET_RELOC (buf);
626 if (rel == NULL)
627 /* This should not happen. */
628 goto free_no_table;
629 if ((*reloc_symbol_deleted_p) (buf - ehbuf, cookie))
630 {
631 cookie->rel = rel;
632 /* This is a FDE against discarded section, it should
633 be deleted. */
634 new_size -= hdr.length + 4;
635 sec_info->entry[sec_info->count].removed = 1;
636 }
637 else
638 {
639 cie_usage_count++;
640 hdr_info->fde_count++;
641 }
642 cookie->rel = rel;
643 if (cie.lsda_encoding != DW_EH_PE_omit)
644 {
645 unsigned int dummy;
646
647 aug = buf;
648 buf += 2 * get_DW_EH_PE_width (cie.fde_encoding, ptr_size);
649 if (cie.augmentation[0] == 'z')
650 read_uleb128 (dummy, buf);
651 /* If some new augmentation data is added before LSDA
652 in FDE augmentation area, this need to be adjusted. */
653 sec_info->entry[sec_info->count].lsda_offset = (buf - aug);
654 }
655 buf = last_fde + 4 + hdr.length;
656 SKIP_RELOCS (buf);
657 }
658
659 sec_info->entry[sec_info->count].fde_encoding = cie.fde_encoding;
660 sec_info->entry[sec_info->count].lsda_encoding = cie.lsda_encoding;
661 sec_info->count++;
662 }
663
664 elf_section_data (sec)->sec_info = sec_info;
665 elf_section_data (sec)->sec_info_type = ELF_INFO_TYPE_EH_FRAME;
666
667 /* Ok, now we can assign new offsets. */
668 offset = 0;
669 last_cie_ndx = 0;
670 for (i = 0; i < sec_info->count; i++)
671 {
672 if (! sec_info->entry[i].removed)
673 {
674 sec_info->entry[i].new_offset = offset;
675 offset += sec_info->entry[i].size;
676 if (sec_info->entry[i].cie)
677 {
678 last_cie_ndx = i;
679 make_relative = sec_info->entry[i].make_relative;
680 make_lsda_relative = sec_info->entry[i].make_lsda_relative;
681 }
682 else
683 {
684 sec_info->entry[i].make_relative = make_relative;
685 sec_info->entry[i].make_lsda_relative = make_lsda_relative;
686 }
687 }
688 else if (sec_info->entry[i].cie && sec_info->entry[i].sec == sec)
689 {
690 /* Need to adjust new_offset too. */
691 BFD_ASSERT (sec_info->entry[last_cie_ndx].offset
692 == sec_info->entry[i].new_offset);
693 sec_info->entry[i].new_offset
694 = sec_info->entry[last_cie_ndx].new_offset;
695 }
696 }
697 if (hdr_info->last_cie_sec == sec)
698 {
699 BFD_ASSERT (sec_info->entry[last_cie_ndx].offset
700 == hdr_info->last_cie_offset);
701 hdr_info->last_cie_offset = sec_info->entry[last_cie_ndx].new_offset;
702 }
703
704 /* FIXME: Currently it is not possible to shrink sections to zero size at
705 this point, so build a fake minimal CIE. */
706 if (new_size == 0)
707 new_size = 16;
708
709 /* Shrink the sec as needed. */
710 sec->_cooked_size = new_size;
711 if (sec->_cooked_size == 0)
712 sec->flags |= SEC_EXCLUDE;
713
714 free (ehbuf);
715 return new_size != sec->_raw_size;
716
717 free_no_table:
718 if (ehbuf)
719 free (ehbuf);
720 if (sec_info)
721 free (sec_info);
722 hdr_info->table = false;
723 hdr_info->last_cie.hdr.length = 0;
724 return false;
725 }
726
727 /* This function is called for .eh_frame_hdr section after
728 _bfd_elf_discard_section_eh_frame has been called on all .eh_frame
729 input sections. It finalizes the size of .eh_frame_hdr section. */
730
731 boolean
732 _bfd_elf_discard_section_eh_frame_hdr (abfd, info, sec)
733 bfd *abfd;
734 struct bfd_link_info *info;
735 asection *sec;
736 {
737 struct eh_frame_hdr_info *hdr_info;
738 unsigned int ptr_size;
739
740 ptr_size = (elf_elfheader (abfd)->e_ident[EI_CLASS]
741 == ELFCLASS64) ? 8 : 4;
742
743 if ((elf_section_data (sec)->sec_info_type
744 != ELF_INFO_TYPE_EH_FRAME_HDR)
745 || ! info->eh_frame_hdr)
746 {
747 _bfd_strip_section_from_output (info, sec);
748 return false;
749 }
750
751 hdr_info = (struct eh_frame_hdr_info *)
752 elf_section_data (sec)->sec_info;
753 if (hdr_info->strip)
754 return false;
755 sec->_cooked_size = EH_FRAME_HDR_SIZE;
756 if (hdr_info->table)
757 sec->_cooked_size += 4 + hdr_info->fde_count * 8;
758
759 /* Request program headers to be recalculated. */
760 elf_tdata (abfd)->program_header_size = 0;
761 elf_tdata (abfd)->eh_frame_hdr = true;
762 return true;
763 }
764
765 /* This function is called from size_dynamic_sections.
766 It needs to decide whether .eh_frame_hdr should be output or not,
767 because later on it is too late for calling _bfd_strip_section_from_output,
768 since dynamic symbol table has been sized. */
769
770 boolean
771 _bfd_elf_maybe_strip_eh_frame_hdr (info)
772 struct bfd_link_info *info;
773 {
774 asection *sec, *o;
775 bfd *abfd;
776 struct eh_frame_hdr_info *hdr_info;
777
778 sec = bfd_get_section_by_name (elf_hash_table (info)->dynobj, ".eh_frame_hdr");
779 if (sec == NULL)
780 return true;
781
782 hdr_info
783 = bfd_zmalloc (sizeof (struct eh_frame_hdr_info));
784 if (hdr_info == NULL)
785 return false;
786
787 elf_section_data (sec)->sec_info = hdr_info;
788 elf_section_data (sec)->sec_info_type = ELF_INFO_TYPE_EH_FRAME_HDR;
789
790 abfd = NULL;
791 if (info->eh_frame_hdr)
792 for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
793 {
794 /* Count only sections which have at least a single CIE or FDE.
795 There cannot be any CIE or FDE <= 8 bytes. */
796 o = bfd_get_section_by_name (abfd, ".eh_frame");
797 if (o && o->_raw_size > 8)
798 break;
799 }
800
801 if (abfd == NULL)
802 {
803 _bfd_strip_section_from_output (info, sec);
804 hdr_info->strip = true;
805 }
806 else
807 hdr_info->table = true;
808 return true;
809 }
810
811 /* Adjust an address in the .eh_frame section. Given OFFSET within
812 SEC, this returns the new offset in the adjusted .eh_frame section,
813 or -1 if the address refers to a CIE/FDE which has been removed
814 or to offset with dynamic relocation which is no longer needed. */
815
816 bfd_vma
817 _bfd_elf_eh_frame_section_offset (output_bfd, sec, offset)
818 bfd *output_bfd ATTRIBUTE_UNUSED;
819 asection *sec;
820 bfd_vma offset;
821 {
822 struct eh_frame_sec_info *sec_info;
823 unsigned int lo, hi, mid;
824
825 if (elf_section_data (sec)->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
826 return offset;
827 sec_info = (struct eh_frame_sec_info *)
828 elf_section_data (sec)->sec_info;
829
830 if (offset >= sec->_raw_size)
831 return offset - (sec->_cooked_size - sec->_raw_size);
832
833 lo = 0;
834 hi = sec_info->count;
835 mid = 0;
836 while (lo < hi)
837 {
838 mid = (lo + hi) / 2;
839 if (offset < sec_info->entry[mid].offset)
840 hi = mid;
841 else if (offset
842 >= sec_info->entry[mid].offset + sec_info->entry[mid].size)
843 lo = mid + 1;
844 else
845 break;
846 }
847
848 BFD_ASSERT (lo < hi);
849
850 /* FDE or CIE was removed. */
851 if (sec_info->entry[mid].removed)
852 return (bfd_vma) -1;
853
854 /* If converting to DW_EH_PE_pcrel, there will be no need for run-time
855 relocation against FDE's initial_location field. */
856 if (sec_info->entry[mid].make_relative
857 && ! sec_info->entry[mid].cie
858 && offset == sec_info->entry[mid].offset + 8)
859 return (bfd_vma) -1;
860
861 /* If converting LSDA pointers to DW_EH_PE_pcrel, there will be no need
862 for run-time relocation against LSDA field. */
863 if (sec_info->entry[mid].make_lsda_relative
864 && ! sec_info->entry[mid].cie
865 && (offset
866 == (sec_info->entry[mid].offset + 8
867 + sec_info->entry[mid].lsda_offset)))
868 return (bfd_vma) -1;
869
870 return (offset + sec_info->entry[mid].new_offset
871 - sec_info->entry[mid].offset);
872 }
873
874 /* Write out .eh_frame section. This is called with the relocated
875 contents. */
876
877 boolean
878 _bfd_elf_write_section_eh_frame (abfd, sec, ehdrsec, contents)
879 bfd *abfd;
880 asection *sec, *ehdrsec;
881 bfd_byte *contents;
882 {
883 struct eh_frame_sec_info *sec_info;
884 struct eh_frame_hdr_info *hdr_info;
885 unsigned int i;
886 bfd_byte *p, *buf;
887 unsigned int leb128_tmp;
888 unsigned int cie_offset = 0;
889 unsigned int ptr_size;
890
891 ptr_size = (elf_elfheader (sec->owner)->e_ident[EI_CLASS]
892 == ELFCLASS64) ? 8 : 4;
893
894 if (elf_section_data (sec)->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
895 return bfd_set_section_contents (abfd, sec->output_section,
896 contents,
897 (file_ptr) sec->output_offset,
898 sec->_raw_size);
899 sec_info = (struct eh_frame_sec_info *)
900 elf_section_data (sec)->sec_info;
901 hdr_info = NULL;
902 if (ehdrsec
903 && (elf_section_data (ehdrsec)->sec_info_type
904 == ELF_INFO_TYPE_EH_FRAME_HDR))
905 {
906 hdr_info = (struct eh_frame_hdr_info *)
907 elf_section_data (ehdrsec)->sec_info;
908 if (hdr_info->table && hdr_info->array == NULL)
909 hdr_info->array
910 = bfd_malloc (hdr_info->fde_count * sizeof(*hdr_info->array));
911 if (hdr_info->array == NULL)
912 hdr_info = NULL;
913 }
914
915 p = contents;
916 for (i = 0; i < sec_info->count; ++i)
917 {
918 if (sec_info->entry[i].removed)
919 {
920 if (sec_info->entry[i].cie)
921 {
922 /* If CIE is removed due to no remaining FDEs referencing it
923 and there were no CIEs kept before it, sec_info->entry[i].sec
924 will be zero. */
925 if (sec_info->entry[i].sec == NULL)
926 cie_offset = 0;
927 else
928 {
929 cie_offset = sec_info->entry[i].new_offset;
930 cie_offset += (sec_info->entry[i].sec->output_section->vma
931 + sec_info->entry[i].sec->output_offset
932 - sec->output_section->vma
933 - sec->output_offset);
934 }
935 }
936 continue;
937 }
938
939 if (sec_info->entry[i].cie)
940 {
941 /* CIE */
942 cie_offset = sec_info->entry[i].new_offset;
943 if (sec_info->entry[i].make_relative
944 || sec_info->entry[i].make_lsda_relative)
945 {
946 unsigned char *aug;
947 unsigned int action;
948 unsigned int dummy, per_width, per_encoding;
949
950 /* Need to find 'R' or 'L' augmentation's argument and modify
951 DW_EH_PE_* value. */
952 action = (sec_info->entry[i].make_relative ? 1 : 0)
953 | (sec_info->entry[i].make_lsda_relative ? 2 : 0);
954 buf = contents + sec_info->entry[i].offset;
955 /* Skip length, id and version. */
956 buf += 9;
957 aug = buf;
958 buf = strchr (buf, '\0') + 1;
959 read_uleb128 (dummy, buf);
960 read_sleb128 (dummy, buf);
961 read_uleb128 (dummy, buf);
962 if (*aug == 'z')
963 {
964 read_uleb128 (dummy, buf);
965 aug++;
966 }
967
968 while (action)
969 switch (*aug++)
970 {
971 case 'L':
972 if (action & 2)
973 {
974 BFD_ASSERT (*buf == sec_info->entry[i].lsda_encoding);
975 *buf |= DW_EH_PE_pcrel;
976 action &= ~2;
977 }
978 buf++;
979 break;
980 case 'P':
981 per_encoding = *buf++;
982 per_width = get_DW_EH_PE_width (per_encoding,
983 ptr_size);
984 BFD_ASSERT (per_width != 0);
985 if ((per_encoding & 0xf0) == DW_EH_PE_aligned)
986 buf = (contents
987 + ((buf - contents + per_width - 1)
988 & ~((bfd_size_type) per_width - 1)));
989 buf += per_width;
990 break;
991 case 'R':
992 if (action & 1)
993 {
994 BFD_ASSERT (*buf == sec_info->entry[i].fde_encoding);
995 *buf |= DW_EH_PE_pcrel;
996 action &= ~1;
997 }
998 buf++;
999 break;
1000 default:
1001 BFD_FAIL ();
1002 }
1003 }
1004 }
1005 else
1006 {
1007 /* FDE */
1008 bfd_vma value = 0, address;
1009 unsigned int width;
1010
1011 buf = contents + sec_info->entry[i].offset;
1012 /* Skip length. */
1013 buf += 4;
1014 bfd_put_32 (abfd,
1015 sec_info->entry[i].new_offset + 4 - cie_offset, buf);
1016 buf += 4;
1017 width = get_DW_EH_PE_width (sec_info->entry[i].fde_encoding,
1018 ptr_size);
1019 address = value = read_value (abfd, buf, width);
1020 if (value)
1021 {
1022 switch (sec_info->entry[i].fde_encoding & 0xf0)
1023 {
1024 case DW_EH_PE_indirect:
1025 case DW_EH_PE_textrel:
1026 BFD_ASSERT (hdr_info == NULL);
1027 break;
1028 case DW_EH_PE_datarel:
1029 {
1030 asection *got = bfd_get_section_by_name (abfd, ".got");
1031
1032 BFD_ASSERT (got != NULL);
1033 address += got->vma;
1034 }
1035 break;
1036 case DW_EH_PE_pcrel:
1037 value += (sec_info->entry[i].offset
1038 - sec_info->entry[i].new_offset);
1039 address += (sec->output_section->vma + sec->output_offset
1040 + sec_info->entry[i].offset + 8);
1041 break;
1042 }
1043 if (sec_info->entry[i].make_relative)
1044 value -= (sec->output_section->vma + sec->output_offset
1045 + sec_info->entry[i].new_offset + 8);
1046 write_value (abfd, buf, value, width);
1047 }
1048
1049 if (hdr_info)
1050 {
1051 hdr_info->array[hdr_info->array_count].initial_loc = address;
1052 hdr_info->array[hdr_info->array_count++].fde
1053 = (sec->output_section->vma + sec->output_offset
1054 + sec_info->entry[i].new_offset);
1055 }
1056
1057 if ((sec_info->entry[i].lsda_encoding & 0xf0) == DW_EH_PE_pcrel
1058 || sec_info->entry[i].make_lsda_relative)
1059 {
1060 buf += sec_info->entry[i].lsda_offset;
1061 width = get_DW_EH_PE_width (sec_info->entry[i].lsda_encoding,
1062 ptr_size);
1063 value = read_value (abfd, buf, width);
1064 if (value)
1065 {
1066 if ((sec_info->entry[i].lsda_encoding & 0xf0)
1067 == DW_EH_PE_pcrel)
1068 value += (sec_info->entry[i].offset
1069 - sec_info->entry[i].new_offset);
1070 else if (sec_info->entry[i].make_lsda_relative)
1071 value -= (sec->output_section->vma + sec->output_offset
1072 + sec_info->entry[i].new_offset + 8
1073 + sec_info->entry[i].lsda_offset);
1074 write_value (abfd, buf, value, width);
1075 }
1076 }
1077 }
1078
1079 BFD_ASSERT (p == contents + sec_info->entry[i].new_offset);
1080 memmove (p, contents + sec_info->entry[i].offset,
1081 sec_info->entry[i].size);
1082 p += sec_info->entry[i].size;
1083 }
1084
1085 /* FIXME: Once _bfd_elf_discard_section_eh_frame will be able to
1086 shrink sections to zero size, this won't be needed any more. */
1087 if (p == contents && sec->_cooked_size == 16)
1088 {
1089 bfd_put_32 (abfd, 12, p); /* Fake CIE length */
1090 bfd_put_32 (abfd, 0, p + 4); /* Fake CIE id */
1091 p[8] = 1; /* Fake CIE version */
1092 memset (p + 9, 0, 7); /* Fake CIE augmentation, 3xleb128
1093 and 3xDW_CFA_nop as pad */
1094 p += 16;
1095 }
1096
1097 BFD_ASSERT ((bfd_size_type) (p - contents) == sec->_cooked_size);
1098
1099 return bfd_set_section_contents (abfd, sec->output_section,
1100 contents, (file_ptr) sec->output_offset,
1101 sec->_cooked_size);
1102 }
1103
1104 /* Helper function used to sort .eh_frame_hdr search table by increasing
1105 VMA of FDE initial location. */
1106
1107 static int
1108 vma_compare (a, b)
1109 const PTR a;
1110 const PTR b;
1111 {
1112 struct eh_frame_array_ent *p = (struct eh_frame_array_ent *) a;
1113 struct eh_frame_array_ent *q = (struct eh_frame_array_ent *) b;
1114 if (p->initial_loc > q->initial_loc)
1115 return 1;
1116 if (p->initial_loc < q->initial_loc)
1117 return -1;
1118 return 0;
1119 }
1120
1121 /* Write out .eh_frame_hdr section. This must be called after
1122 _bfd_elf_write_section_eh_frame has been called on all input
1123 .eh_frame sections.
1124 .eh_frame_hdr format:
1125 ubyte version (currently 1)
1126 ubyte eh_frame_ptr_enc (DW_EH_PE_* encoding of pointer to start of
1127 .eh_frame section)
1128 ubyte fde_count_enc (DW_EH_PE_* encoding of total FDE count
1129 number (or DW_EH_PE_omit if there is no
1130 binary search table computed))
1131 ubyte table_enc (DW_EH_PE_* encoding of binary search table,
1132 or DW_EH_PE_omit if not present.
1133 DW_EH_PE_datarel is using address of
1134 .eh_frame_hdr section start as base)
1135 [encoded] eh_frame_ptr (pointer to start of .eh_frame section)
1136 optionally followed by:
1137 [encoded] fde_count (total number of FDEs in .eh_frame section)
1138 fde_count x [encoded] initial_loc, fde
1139 (array of encoded pairs containing
1140 FDE initial_location field and FDE address,
1141 sorted by increasing initial_loc) */
1142
1143 boolean
1144 _bfd_elf_write_section_eh_frame_hdr (abfd, sec)
1145 bfd *abfd;
1146 asection *sec;
1147 {
1148 struct eh_frame_hdr_info *hdr_info;
1149 unsigned int ptr_size;
1150 bfd_byte *contents;
1151 asection *eh_frame_sec;
1152 bfd_size_type size;
1153
1154 ptr_size = (elf_elfheader (sec->owner)->e_ident[EI_CLASS]
1155 == ELFCLASS64) ? 8 : 4;
1156
1157 BFD_ASSERT (elf_section_data (sec)->sec_info_type
1158 == ELF_INFO_TYPE_EH_FRAME_HDR);
1159 hdr_info = (struct eh_frame_hdr_info *)
1160 elf_section_data (sec)->sec_info;
1161 if (hdr_info->strip)
1162 return true;
1163
1164 size = EH_FRAME_HDR_SIZE;
1165 if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
1166 size += 4 + hdr_info->fde_count * 8;
1167 contents = bfd_malloc (size);
1168 if (contents == NULL)
1169 return false;
1170
1171 eh_frame_sec = bfd_get_section_by_name (abfd, ".eh_frame");
1172 if (eh_frame_sec == NULL)
1173 return false;
1174
1175 memset (contents, 0, EH_FRAME_HDR_SIZE);
1176 contents[0] = 1; /* Version */
1177 contents[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4; /* .eh_frame offset */
1178 if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
1179 {
1180 contents[2] = DW_EH_PE_udata4; /* FDE count encoding */
1181 contents[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4; /* search table enc */
1182 }
1183 else
1184 {
1185 contents[2] = DW_EH_PE_omit;
1186 contents[3] = DW_EH_PE_omit;
1187 }
1188 bfd_put_32 (abfd, eh_frame_sec->vma - sec->output_section->vma - 4,
1189 contents + 4);
1190 if (contents[2] != DW_EH_PE_omit)
1191 {
1192 unsigned int i;
1193
1194 bfd_put_32 (abfd, hdr_info->fde_count, contents + EH_FRAME_HDR_SIZE);
1195 qsort (hdr_info->array, hdr_info->fde_count, sizeof (*hdr_info->array),
1196 vma_compare);
1197 for (i = 0; i < hdr_info->fde_count; i++)
1198 {
1199 bfd_put_32 (abfd,
1200 hdr_info->array[i].initial_loc
1201 - sec->output_section->vma,
1202 contents + EH_FRAME_HDR_SIZE + i * 8 + 4);
1203 bfd_put_32 (abfd,
1204 hdr_info->array[i].fde - sec->output_section->vma,
1205 contents + EH_FRAME_HDR_SIZE + i * 8 + 8);
1206 }
1207 }
1208
1209 return bfd_set_section_contents (abfd, sec->output_section,
1210 contents, (file_ptr) sec->output_offset,
1211 sec->_cooked_size);
1212 }
This page took 0.057399 seconds and 5 git commands to generate.