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