Fix ld --just-symbols
[deliverable/binutils-gdb.git] / bfd / elf-eh-frame.c
CommitLineData
65765700 1/* .eh_frame section optimization.
c68836a9 2 Copyright 2001, 2002 Free Software Foundation, Inc.
65765700
JJ
3 Written by Jakub Jelinek <jakub@redhat.com>.
4
5This file is part of BFD, the Binary File Descriptor library.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, 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
29struct cie_header
30{
31 unsigned int length;
32 unsigned int id;
33};
34
35struct 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;
9e2a4898 50 unsigned char make_lsda_relative;
65765700
JJ
51 unsigned char initial_instructions[50];
52};
53
54struct 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;
9e2a4898
JJ
61 unsigned char lsda_encoding;
62 unsigned char lsda_offset;
65765700
JJ
63 unsigned char cie : 1;
64 unsigned char removed : 1;
65 unsigned char make_relative : 1;
9e2a4898 66 unsigned char make_lsda_relative : 1;
09ae86c2 67 unsigned char per_encoding_relative : 1;
65765700
JJ
68};
69
70struct eh_frame_sec_info
71{
72 unsigned int count;
73 unsigned int alloced;
74 struct eh_cie_fde entry[1];
75};
76
77struct eh_frame_array_ent
78{
79 bfd_vma initial_loc;
80 bfd_vma fde;
81};
82
83struct 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;
68f69152 94 boolean strip;
65765700
JJ
95};
96
97static bfd_vma read_unsigned_leb128
98 PARAMS ((bfd *, char *, unsigned int *));
99static bfd_signed_vma read_signed_leb128
100 PARAMS ((bfd *, char *, unsigned int *));
101static int get_DW_EH_PE_width
102 PARAMS ((int, int));
9e2a4898
JJ
103static bfd_vma read_value
104 PARAMS ((bfd *, bfd_byte *, int));
105static void write_value
106 PARAMS ((bfd *, bfd_byte *, bfd_vma, int));
65765700
JJ
107static int cie_compare
108 PARAMS ((struct cie *, struct cie *));
109static int vma_compare
110 PARAMS ((const PTR a, const PTR b));
111
112/* Helper function for reading uleb128 encoded data. */
113
114static bfd_vma
115read_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
143static bfd_signed_vma
144read_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) \
173do \
174 { \
175 (VAR) = read_unsigned_leb128 (abfd, buf, &leb128_tmp); \
176 (BUF) += leb128_tmp; \
177 } \
178while (0)
179
180#define read_sleb128(VAR, BUF) \
181do \
182 { \
183 (VAR) = read_signed_leb128 (abfd, buf, &leb128_tmp); \
184 (BUF) += leb128_tmp; \
185 } \
186while (0)
187
188/* Return 0 if either encoding is variable width, or not yet known to bfd. */
189
190static
191int 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
9e2a4898
JJ
212/* Read a width sized value from memory. */
213
214static bfd_vma
215read_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
235static void
236write_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
65765700
JJ
251/* Return zero if C1 and C2 CIEs can be merged. */
252
253static
254int 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
284boolean
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;
68f69152 298 struct eh_frame_sec_info *sec_info = NULL;
65765700 299 unsigned int leb128_tmp;
9e2a4898
JJ
300 unsigned int cie_usage_count, last_cie_ndx, i, offset;
301 unsigned int make_relative, make_lsda_relative;
65765700
JJ
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
68f69152
JJ
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
65765700
JJ
325 /* Read the frame unwind information from abfd. */
326
327 ehbuf = (bfd_byte *) bfd_malloc (sec->_raw_size);
68f69152
JJ
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;
65765700
JJ
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
65765700
JJ
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)
68f69152 347 goto free_no_table;
65765700
JJ
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;
9e2a4898 358 make_lsda_relative = hdr_info->last_cie.make_lsda_relative;
65765700
JJ
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;
9e2a4898
JJ
471 sec_info->entry[last_cie_ndx].make_lsda_relative
472 = cie.make_lsda_relative;
09ae86c2
JJ
473 sec_info->entry[last_cie_ndx].per_encoding_relative
474 = (cie.per_encoding & 0x70) == DW_EH_PE_pcrel;
65765700
JJ
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
0bb2d96a
JJ
592 as possible. */
593 if (info->shared
65765700
JJ
594 && (cie.fde_encoding & 0xf0) == DW_EH_PE_absptr)
595 cie.make_relative = 1;
596
0bb2d96a 597 if (info->shared
9e2a4898
JJ
598 && (cie.lsda_encoding & 0xf0) == DW_EH_PE_absptr)
599 cie.make_lsda_relative = 1;
600
65765700
JJ
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 {
0bb2d96a 638 if (info->shared
af40ce3c
JJ
639 && (((cie.fde_encoding & 0xf0) == DW_EH_PE_absptr
640 && cie.make_relative == 0)
641 || (cie.fde_encoding & 0xf0) == DW_EH_PE_aligned))
0bb2d96a
JJ
642 {
643 /* If shared library uses absolute pointers
644 which we cannot turn into PC relative,
645 don't create the binary search table,
646 since it is affected by runtime relocations. */
647 hdr_info->table = false;
648 }
65765700
JJ
649 cie_usage_count++;
650 hdr_info->fde_count++;
651 }
652 cookie->rel = rel;
9e2a4898
JJ
653 if (cie.lsda_encoding != DW_EH_PE_omit)
654 {
655 unsigned int dummy;
656
657 aug = buf;
658 buf += 2 * get_DW_EH_PE_width (cie.fde_encoding, ptr_size);
659 if (cie.augmentation[0] == 'z')
660 read_uleb128 (dummy, buf);
661 /* If some new augmentation data is added before LSDA
662 in FDE augmentation area, this need to be adjusted. */
663 sec_info->entry[sec_info->count].lsda_offset = (buf - aug);
664 }
65765700
JJ
665 buf = last_fde + 4 + hdr.length;
666 SKIP_RELOCS (buf);
667 }
668
669 sec_info->entry[sec_info->count].fde_encoding = cie.fde_encoding;
9e2a4898 670 sec_info->entry[sec_info->count].lsda_encoding = cie.lsda_encoding;
65765700
JJ
671 sec_info->count++;
672 }
673
674 elf_section_data (sec)->sec_info = sec_info;
675 elf_section_data (sec)->sec_info_type = ELF_INFO_TYPE_EH_FRAME;
676
677 /* Ok, now we can assign new offsets. */
678 offset = 0;
679 last_cie_ndx = 0;
680 for (i = 0; i < sec_info->count; i++)
681 {
682 if (! sec_info->entry[i].removed)
683 {
684 sec_info->entry[i].new_offset = offset;
685 offset += sec_info->entry[i].size;
686 if (sec_info->entry[i].cie)
687 {
688 last_cie_ndx = i;
689 make_relative = sec_info->entry[i].make_relative;
9e2a4898 690 make_lsda_relative = sec_info->entry[i].make_lsda_relative;
65765700
JJ
691 }
692 else
9e2a4898
JJ
693 {
694 sec_info->entry[i].make_relative = make_relative;
695 sec_info->entry[i].make_lsda_relative = make_lsda_relative;
09ae86c2 696 sec_info->entry[i].per_encoding_relative = 0;
9e2a4898 697 }
65765700
JJ
698 }
699 else if (sec_info->entry[i].cie && sec_info->entry[i].sec == sec)
700 {
701 /* Need to adjust new_offset too. */
702 BFD_ASSERT (sec_info->entry[last_cie_ndx].offset
703 == sec_info->entry[i].new_offset);
704 sec_info->entry[i].new_offset
705 = sec_info->entry[last_cie_ndx].new_offset;
706 }
707 }
708 if (hdr_info->last_cie_sec == sec)
709 {
710 BFD_ASSERT (sec_info->entry[last_cie_ndx].offset
711 == hdr_info->last_cie_offset);
712 hdr_info->last_cie_offset = sec_info->entry[last_cie_ndx].new_offset;
713 }
714
a5eb27e6
JJ
715 /* FIXME: Currently it is not possible to shrink sections to zero size at
716 this point, so build a fake minimal CIE. */
717 if (new_size == 0)
718 new_size = 16;
719
65765700 720 /* Shrink the sec as needed. */
65765700
JJ
721 sec->_cooked_size = new_size;
722 if (sec->_cooked_size == 0)
723 sec->flags |= SEC_EXCLUDE;
724
68f69152 725 free (ehbuf);
65765700
JJ
726 return new_size != sec->_raw_size;
727
728free_no_table:
68f69152
JJ
729 if (ehbuf)
730 free (ehbuf);
65765700
JJ
731 if (sec_info)
732 free (sec_info);
733 hdr_info->table = false;
734 hdr_info->last_cie.hdr.length = 0;
735 return false;
736}
737
738/* This function is called for .eh_frame_hdr section after
739 _bfd_elf_discard_section_eh_frame has been called on all .eh_frame
740 input sections. It finalizes the size of .eh_frame_hdr section. */
741
742boolean
743_bfd_elf_discard_section_eh_frame_hdr (abfd, info, sec)
744 bfd *abfd;
745 struct bfd_link_info *info;
746 asection *sec;
747{
748 struct eh_frame_hdr_info *hdr_info;
749 unsigned int ptr_size;
750
751 ptr_size = (elf_elfheader (abfd)->e_ident[EI_CLASS]
752 == ELFCLASS64) ? 8 : 4;
753
754 if ((elf_section_data (sec)->sec_info_type
755 != ELF_INFO_TYPE_EH_FRAME_HDR)
756 || ! info->eh_frame_hdr)
757 {
758 _bfd_strip_section_from_output (info, sec);
759 return false;
760 }
761
762 hdr_info = (struct eh_frame_hdr_info *)
763 elf_section_data (sec)->sec_info;
68f69152
JJ
764 if (hdr_info->strip)
765 return false;
65765700
JJ
766 sec->_cooked_size = EH_FRAME_HDR_SIZE;
767 if (hdr_info->table)
768 sec->_cooked_size += 4 + hdr_info->fde_count * 8;
769
770 /* Request program headers to be recalculated. */
771 elf_tdata (abfd)->program_header_size = 0;
772 elf_tdata (abfd)->eh_frame_hdr = true;
773 return true;
774}
775
68f69152
JJ
776/* This function is called from size_dynamic_sections.
777 It needs to decide whether .eh_frame_hdr should be output or not,
778 because later on it is too late for calling _bfd_strip_section_from_output,
779 since dynamic symbol table has been sized. */
780
781boolean
782_bfd_elf_maybe_strip_eh_frame_hdr (info)
783 struct bfd_link_info *info;
784{
785 asection *sec, *o;
786 bfd *abfd;
787 struct eh_frame_hdr_info *hdr_info;
788
789 sec = bfd_get_section_by_name (elf_hash_table (info)->dynobj, ".eh_frame_hdr");
2d653fc7 790 if (sec == NULL || bfd_is_abs_section (sec->output_section))
68f69152
JJ
791 return true;
792
793 hdr_info
794 = bfd_zmalloc (sizeof (struct eh_frame_hdr_info));
795 if (hdr_info == NULL)
796 return false;
797
798 elf_section_data (sec)->sec_info = hdr_info;
799 elf_section_data (sec)->sec_info_type = ELF_INFO_TYPE_EH_FRAME_HDR;
800
801 abfd = NULL;
802 if (info->eh_frame_hdr)
803 for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
804 {
805 /* Count only sections which have at least a single CIE or FDE.
806 There cannot be any CIE or FDE <= 8 bytes. */
807 o = bfd_get_section_by_name (abfd, ".eh_frame");
2d653fc7 808 if (o && o->_raw_size > 8 && !bfd_is_abs_section (o->output_section))
68f69152
JJ
809 break;
810 }
811
812 if (abfd == NULL)
813 {
814 _bfd_strip_section_from_output (info, sec);
815 hdr_info->strip = true;
816 }
817 else
818 hdr_info->table = true;
819 return true;
820}
821
65765700
JJ
822/* Adjust an address in the .eh_frame section. Given OFFSET within
823 SEC, this returns the new offset in the adjusted .eh_frame section,
824 or -1 if the address refers to a CIE/FDE which has been removed
825 or to offset with dynamic relocation which is no longer needed. */
826
827bfd_vma
828_bfd_elf_eh_frame_section_offset (output_bfd, sec, offset)
829 bfd *output_bfd ATTRIBUTE_UNUSED;
830 asection *sec;
831 bfd_vma offset;
832{
833 struct eh_frame_sec_info *sec_info;
834 unsigned int lo, hi, mid;
835
836 if (elf_section_data (sec)->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
837 return offset;
838 sec_info = (struct eh_frame_sec_info *)
839 elf_section_data (sec)->sec_info;
840
841 if (offset >= sec->_raw_size)
842 return offset - (sec->_cooked_size - sec->_raw_size);
843
844 lo = 0;
845 hi = sec_info->count;
846 mid = 0;
847 while (lo < hi)
848 {
849 mid = (lo + hi) / 2;
850 if (offset < sec_info->entry[mid].offset)
851 hi = mid;
852 else if (offset
853 >= sec_info->entry[mid].offset + sec_info->entry[mid].size)
854 lo = mid + 1;
855 else
856 break;
857 }
858
859 BFD_ASSERT (lo < hi);
860
861 /* FDE or CIE was removed. */
862 if (sec_info->entry[mid].removed)
863 return (bfd_vma) -1;
864
865 /* If converting to DW_EH_PE_pcrel, there will be no need for run-time
866 relocation against FDE's initial_location field. */
867 if (sec_info->entry[mid].make_relative
868 && ! sec_info->entry[mid].cie
869 && offset == sec_info->entry[mid].offset + 8)
0bb2d96a 870 return (bfd_vma) -2;
65765700 871
9e2a4898
JJ
872 /* If converting LSDA pointers to DW_EH_PE_pcrel, there will be no need
873 for run-time relocation against LSDA field. */
874 if (sec_info->entry[mid].make_lsda_relative
875 && ! sec_info->entry[mid].cie
876 && (offset
877 == (sec_info->entry[mid].offset + 8
878 + sec_info->entry[mid].lsda_offset)))
0bb2d96a 879 return (bfd_vma) -2;
9e2a4898 880
c68836a9
AM
881 return (offset + sec_info->entry[mid].new_offset
882 - sec_info->entry[mid].offset);
65765700
JJ
883}
884
885/* Write out .eh_frame section. This is called with the relocated
886 contents. */
887
888boolean
889_bfd_elf_write_section_eh_frame (abfd, sec, ehdrsec, contents)
890 bfd *abfd;
891 asection *sec, *ehdrsec;
892 bfd_byte *contents;
893{
894 struct eh_frame_sec_info *sec_info;
895 struct eh_frame_hdr_info *hdr_info;
896 unsigned int i;
897 bfd_byte *p, *buf;
898 unsigned int leb128_tmp;
899 unsigned int cie_offset = 0;
900 unsigned int ptr_size;
901
902 ptr_size = (elf_elfheader (sec->owner)->e_ident[EI_CLASS]
903 == ELFCLASS64) ? 8 : 4;
904
905 if (elf_section_data (sec)->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
906 return bfd_set_section_contents (abfd, sec->output_section,
907 contents,
908 (file_ptr) sec->output_offset,
909 sec->_raw_size);
910 sec_info = (struct eh_frame_sec_info *)
911 elf_section_data (sec)->sec_info;
912 hdr_info = NULL;
913 if (ehdrsec
914 && (elf_section_data (ehdrsec)->sec_info_type
915 == ELF_INFO_TYPE_EH_FRAME_HDR))
916 {
917 hdr_info = (struct eh_frame_hdr_info *)
918 elf_section_data (ehdrsec)->sec_info;
919 if (hdr_info->table && hdr_info->array == NULL)
920 hdr_info->array
921 = bfd_malloc (hdr_info->fde_count * sizeof(*hdr_info->array));
922 if (hdr_info->array == NULL)
923 hdr_info = NULL;
924 }
925
926 p = contents;
927 for (i = 0; i < sec_info->count; ++i)
928 {
929 if (sec_info->entry[i].removed)
930 {
931 if (sec_info->entry[i].cie)
932 {
a3aa38ee
JJ
933 /* If CIE is removed due to no remaining FDEs referencing it
934 and there were no CIEs kept before it, sec_info->entry[i].sec
935 will be zero. */
936 if (sec_info->entry[i].sec == NULL)
937 cie_offset = 0;
938 else
939 {
940 cie_offset = sec_info->entry[i].new_offset;
941 cie_offset += (sec_info->entry[i].sec->output_section->vma
942 + sec_info->entry[i].sec->output_offset
943 - sec->output_section->vma
944 - sec->output_offset);
945 }
65765700
JJ
946 }
947 continue;
948 }
a3aa38ee 949
65765700
JJ
950 if (sec_info->entry[i].cie)
951 {
952 /* CIE */
953 cie_offset = sec_info->entry[i].new_offset;
9e2a4898 954 if (sec_info->entry[i].make_relative
09ae86c2
JJ
955 || sec_info->entry[i].make_lsda_relative
956 || sec_info->entry[i].per_encoding_relative)
65765700
JJ
957 {
958 unsigned char *aug;
9e2a4898 959 unsigned int action;
65765700
JJ
960 unsigned int dummy, per_width, per_encoding;
961
9e2a4898 962 /* Need to find 'R' or 'L' augmentation's argument and modify
65765700 963 DW_EH_PE_* value. */
9e2a4898 964 action = (sec_info->entry[i].make_relative ? 1 : 0)
09ae86c2
JJ
965 | (sec_info->entry[i].make_lsda_relative ? 2 : 0)
966 | (sec_info->entry[i].per_encoding_relative ? 4 : 0);
65765700
JJ
967 buf = contents + sec_info->entry[i].offset;
968 /* Skip length, id and version. */
969 buf += 9;
970 aug = buf;
971 buf = strchr (buf, '\0') + 1;
972 read_uleb128 (dummy, buf);
973 read_sleb128 (dummy, buf);
974 read_uleb128 (dummy, buf);
975 if (*aug == 'z')
976 {
977 read_uleb128 (dummy, buf);
978 aug++;
979 }
980
9e2a4898 981 while (action)
65765700
JJ
982 switch (*aug++)
983 {
984 case 'L':
9e2a4898
JJ
985 if (action & 2)
986 {
987 BFD_ASSERT (*buf == sec_info->entry[i].lsda_encoding);
988 *buf |= DW_EH_PE_pcrel;
989 action &= ~2;
990 }
65765700
JJ
991 buf++;
992 break;
993 case 'P':
994 per_encoding = *buf++;
995 per_width = get_DW_EH_PE_width (per_encoding,
996 ptr_size);
997 BFD_ASSERT (per_width != 0);
09ae86c2
JJ
998 BFD_ASSERT (((per_encoding & 0x70) == DW_EH_PE_pcrel)
999 == sec_info->entry[i].per_encoding_relative);
65765700
JJ
1000 if ((per_encoding & 0xf0) == DW_EH_PE_aligned)
1001 buf = (contents
1002 + ((buf - contents + per_width - 1)
1003 & ~((bfd_size_type) per_width - 1)));
09ae86c2
JJ
1004 if (action & 4)
1005 {
1006 bfd_vma value;
1007
1008 value = read_value (abfd, buf, per_width);
1009 value += (sec_info->entry[i].offset
1010 - sec_info->entry[i].new_offset);
1011 write_value (abfd, buf, value, per_width);
1012 action &= ~4;
1013 }
65765700
JJ
1014 buf += per_width;
1015 break;
9e2a4898
JJ
1016 case 'R':
1017 if (action & 1)
1018 {
1019 BFD_ASSERT (*buf == sec_info->entry[i].fde_encoding);
1020 *buf |= DW_EH_PE_pcrel;
1021 action &= ~1;
1022 }
1023 buf++;
1024 break;
65765700
JJ
1025 default:
1026 BFD_FAIL ();
1027 }
65765700
JJ
1028 }
1029 }
af40ce3c 1030 else if (sec_info->entry[i].size > 4)
65765700
JJ
1031 {
1032 /* FDE */
1033 bfd_vma value = 0, address;
9e2a4898 1034 unsigned int width;
65765700
JJ
1035
1036 buf = contents + sec_info->entry[i].offset;
1037 /* Skip length. */
1038 buf += 4;
1039 bfd_put_32 (abfd,
1040 sec_info->entry[i].new_offset + 4 - cie_offset, buf);
1041 buf += 4;
9e2a4898
JJ
1042 width = get_DW_EH_PE_width (sec_info->entry[i].fde_encoding,
1043 ptr_size);
1044 address = value = read_value (abfd, buf, width);
1045 if (value)
65765700 1046 {
9e2a4898
JJ
1047 switch (sec_info->entry[i].fde_encoding & 0xf0)
1048 {
1049 case DW_EH_PE_indirect:
1050 case DW_EH_PE_textrel:
1051 BFD_ASSERT (hdr_info == NULL);
1052 break;
1053 case DW_EH_PE_datarel:
1054 {
1055 asection *got = bfd_get_section_by_name (abfd, ".got");
1056
1057 BFD_ASSERT (got != NULL);
1058 address += got->vma;
1059 }
1060 break;
1061 case DW_EH_PE_pcrel:
1062 value += (sec_info->entry[i].offset
1063 - sec_info->entry[i].new_offset);
1064 address += (sec->output_section->vma + sec->output_offset
1065 + sec_info->entry[i].offset + 8);
1066 break;
1067 }
1068 if (sec_info->entry[i].make_relative)
1069 value -= (sec->output_section->vma + sec->output_offset
65765700 1070 + sec_info->entry[i].new_offset + 8);
9e2a4898 1071 write_value (abfd, buf, value, width);
65765700
JJ
1072 }
1073
1074 if (hdr_info)
1075 {
1076 hdr_info->array[hdr_info->array_count].initial_loc = address;
1077 hdr_info->array[hdr_info->array_count++].fde
1078 = (sec->output_section->vma + sec->output_offset
1079 + sec_info->entry[i].new_offset);
1080 }
9e2a4898
JJ
1081
1082 if ((sec_info->entry[i].lsda_encoding & 0xf0) == DW_EH_PE_pcrel
1083 || sec_info->entry[i].make_lsda_relative)
1084 {
1085 buf += sec_info->entry[i].lsda_offset;
1086 width = get_DW_EH_PE_width (sec_info->entry[i].lsda_encoding,
1087 ptr_size);
1088 value = read_value (abfd, buf, width);
1089 if (value)
1090 {
1091 if ((sec_info->entry[i].lsda_encoding & 0xf0)
1092 == DW_EH_PE_pcrel)
1093 value += (sec_info->entry[i].offset
1094 - sec_info->entry[i].new_offset);
1095 else if (sec_info->entry[i].make_lsda_relative)
1096 value -= (sec->output_section->vma + sec->output_offset
1097 + sec_info->entry[i].new_offset + 8
1098 + sec_info->entry[i].lsda_offset);
1099 write_value (abfd, buf, value, width);
1100 }
1101 }
65765700 1102 }
af40ce3c
JJ
1103 else
1104 /* Terminating FDE must be at the end of .eh_frame section only. */
1105 BFD_ASSERT (i == sec_info->count - 1);
65765700
JJ
1106
1107 BFD_ASSERT (p == contents + sec_info->entry[i].new_offset);
1108 memmove (p, contents + sec_info->entry[i].offset,
1109 sec_info->entry[i].size);
1110 p += sec_info->entry[i].size;
1111 }
1112
a5eb27e6
JJ
1113 /* FIXME: Once _bfd_elf_discard_section_eh_frame will be able to
1114 shrink sections to zero size, this won't be needed any more. */
1115 if (p == contents && sec->_cooked_size == 16)
1116 {
1117 bfd_put_32 (abfd, 12, p); /* Fake CIE length */
1118 bfd_put_32 (abfd, 0, p + 4); /* Fake CIE id */
1119 p[8] = 1; /* Fake CIE version */
1120 memset (p + 9, 0, 7); /* Fake CIE augmentation, 3xleb128
1121 and 3xDW_CFA_nop as pad */
1122 p += 16;
1123 }
1124
65765700
JJ
1125 BFD_ASSERT ((bfd_size_type) (p - contents) == sec->_cooked_size);
1126
1127 return bfd_set_section_contents (abfd, sec->output_section,
1128 contents, (file_ptr) sec->output_offset,
1129 sec->_cooked_size);
1130}
1131
1132/* Helper function used to sort .eh_frame_hdr search table by increasing
1133 VMA of FDE initial location. */
1134
1135static int
1136vma_compare (a, b)
1137 const PTR a;
1138 const PTR b;
1139{
1140 struct eh_frame_array_ent *p = (struct eh_frame_array_ent *) a;
1141 struct eh_frame_array_ent *q = (struct eh_frame_array_ent *) b;
1142 if (p->initial_loc > q->initial_loc)
1143 return 1;
1144 if (p->initial_loc < q->initial_loc)
1145 return -1;
1146 return 0;
1147}
1148
1149/* Write out .eh_frame_hdr section. This must be called after
1150 _bfd_elf_write_section_eh_frame has been called on all input
1151 .eh_frame sections.
1152 .eh_frame_hdr format:
1153 ubyte version (currently 1)
1154 ubyte eh_frame_ptr_enc (DW_EH_PE_* encoding of pointer to start of
1155 .eh_frame section)
1156 ubyte fde_count_enc (DW_EH_PE_* encoding of total FDE count
1157 number (or DW_EH_PE_omit if there is no
1158 binary search table computed))
1159 ubyte table_enc (DW_EH_PE_* encoding of binary search table,
1160 or DW_EH_PE_omit if not present.
1161 DW_EH_PE_datarel is using address of
1162 .eh_frame_hdr section start as base)
1163 [encoded] eh_frame_ptr (pointer to start of .eh_frame section)
1164 optionally followed by:
1165 [encoded] fde_count (total number of FDEs in .eh_frame section)
1166 fde_count x [encoded] initial_loc, fde
1167 (array of encoded pairs containing
1168 FDE initial_location field and FDE address,
1169 sorted by increasing initial_loc) */
1170
1171boolean
1172_bfd_elf_write_section_eh_frame_hdr (abfd, sec)
1173 bfd *abfd;
1174 asection *sec;
1175{
1176 struct eh_frame_hdr_info *hdr_info;
1177 unsigned int ptr_size;
1178 bfd_byte *contents;
1179 asection *eh_frame_sec;
1180 bfd_size_type size;
1181
1182 ptr_size = (elf_elfheader (sec->owner)->e_ident[EI_CLASS]
1183 == ELFCLASS64) ? 8 : 4;
1184
1185 BFD_ASSERT (elf_section_data (sec)->sec_info_type
1186 == ELF_INFO_TYPE_EH_FRAME_HDR);
1187 hdr_info = (struct eh_frame_hdr_info *)
1188 elf_section_data (sec)->sec_info;
57a72197
JJ
1189 if (hdr_info->strip)
1190 return true;
1191
65765700
JJ
1192 size = EH_FRAME_HDR_SIZE;
1193 if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
1194 size += 4 + hdr_info->fde_count * 8;
1195 contents = bfd_malloc (size);
1196 if (contents == NULL)
1197 return false;
1198
1199 eh_frame_sec = bfd_get_section_by_name (abfd, ".eh_frame");
1200 if (eh_frame_sec == NULL)
1201 return false;
1202
1203 memset (contents, 0, EH_FRAME_HDR_SIZE);
1204 contents[0] = 1; /* Version */
1205 contents[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4; /* .eh_frame offset */
1206 if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
1207 {
1208 contents[2] = DW_EH_PE_udata4; /* FDE count encoding */
1209 contents[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4; /* search table enc */
1210 }
1211 else
1212 {
1213 contents[2] = DW_EH_PE_omit;
1214 contents[3] = DW_EH_PE_omit;
1215 }
1216 bfd_put_32 (abfd, eh_frame_sec->vma - sec->output_section->vma - 4,
1217 contents + 4);
1218 if (contents[2] != DW_EH_PE_omit)
1219 {
1220 unsigned int i;
1221
1222 bfd_put_32 (abfd, hdr_info->fde_count, contents + EH_FRAME_HDR_SIZE);
1223 qsort (hdr_info->array, hdr_info->fde_count, sizeof (*hdr_info->array),
1224 vma_compare);
1225 for (i = 0; i < hdr_info->fde_count; i++)
1226 {
1227 bfd_put_32 (abfd,
1228 hdr_info->array[i].initial_loc
1229 - sec->output_section->vma,
1230 contents + EH_FRAME_HDR_SIZE + i * 8 + 4);
1231 bfd_put_32 (abfd,
1232 hdr_info->array[i].fde - sec->output_section->vma,
1233 contents + EH_FRAME_HDR_SIZE + i * 8 + 8);
1234 }
1235 }
1236
1237 return bfd_set_section_contents (abfd, sec->output_section,
1238 contents, (file_ptr) sec->output_offset,
1239 sec->_cooked_size);
1240}
This page took 0.094976 seconds and 4 git commands to generate.