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