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