Lines 457-462
_bfd_elf_begin_eh_frame_parsing (struct bfd_link_info *info)
Link Here
|
457 |
hdr_info->merge_cies = !info->relocatable; |
457 |
hdr_info->merge_cies = !info->relocatable; |
458 |
} |
458 |
} |
459 |
|
459 |
|
|
|
460 |
struct reloc_read_ops |
461 |
{ |
462 |
Elf_Internal_Rela * (*chk_relocs) (struct elf_reloc_cookie *, |
463 |
bfd_vma, bfd_vma); |
464 |
Elf_Internal_Rela * (*get_reloc) (struct elf_reloc_cookie *, bfd_vma); |
465 |
void (*skip_relocs) (struct elf_reloc_cookie *, bfd_vma, bfd_vma *); |
466 |
}; |
467 |
|
468 |
/* Implementation of the ENSURE_NO_RELOCS macro for ordered relocations. */ |
469 |
static Elf_Internal_Rela * |
470 |
_bfd_chk_relocs_ordered (struct elf_reloc_cookie *cookie, |
471 |
bfd_vma rels_offset ATTRIBUTE_UNUSED, |
472 |
bfd_vma offset) |
473 |
{ |
474 |
/* FIXME: octets_per_byte. */ |
475 |
if (cookie->rel < cookie->relend |
476 |
&& cookie->rel->r_offset < offset |
477 |
&& cookie->rel->r_info != 0) |
478 |
return cookie->rel; |
479 |
return NULL; |
480 |
} |
481 |
|
482 |
/* Implementation of the GET_RELOC macro for ordered relocations. */ |
483 |
static Elf_Internal_Rela * |
484 |
_bfd_get_reloc_ordered (struct elf_reloc_cookie *cookie, bfd_vma offset) |
485 |
{ |
486 |
/* FIXME: octets_per_byte. */ |
487 |
return cookie->rel < cookie->relend && cookie->rel->r_offset == offset |
488 |
? cookie->rel : NULL; |
489 |
} |
490 |
|
491 |
/* Implementation of the SKIP_RELOCS macro for ordered relocations. */ |
492 |
static void |
493 |
_bfd_skip_relocs_ordered (struct elf_reloc_cookie *cookie, bfd_vma offset, |
494 |
bfd_vma *rels_offset ATTRIBUTE_UNUSED) |
495 |
{ |
496 |
/* FIXME: octets_per_byte. */ |
497 |
while (cookie->rel < cookie->relend && cookie->rel->r_offset < offset) |
498 |
cookie->rel++; |
499 |
} |
500 |
|
501 |
static struct reloc_read_ops _bfd_eh_ordered_relocs = { |
502 |
.chk_relocs = _bfd_chk_relocs_ordered, |
503 |
.get_reloc = _bfd_get_reloc_ordered, |
504 |
.skip_relocs = _bfd_skip_relocs_ordered, |
505 |
}; |
506 |
|
507 |
/* Implementation of the ENSURE_NO_RELOCS macro for unordered relocations. */ |
508 |
static Elf_Internal_Rela * |
509 |
_bfd_chk_relocs_unordered (struct elf_reloc_cookie *cookie, |
510 |
bfd_vma rels_offset, bfd_vma offset) |
511 |
{ |
512 |
Elf_Internal_Rela *rel; |
513 |
|
514 |
/* FIXME: octets_per_byte. */ |
515 |
for (rel = cookie->rels; rel < cookie->relend; rel++) |
516 |
if (rel->r_offset >= rels_offset |
517 |
&& rel->r_offset < offset |
518 |
&& rel->r_info != 0) |
519 |
return rel; |
520 |
return NULL; |
521 |
} |
522 |
|
523 |
/* Implementation of the GET_RELOC macro for unordered relocations. */ |
524 |
static Elf_Internal_Rela * |
525 |
_bfd_get_reloc_unordered (struct elf_reloc_cookie *cookie, bfd_vma offset) |
526 |
{ |
527 |
Elf_Internal_Rela *rel; |
528 |
|
529 |
/* FIXME: octets_per_byte. */ |
530 |
for (rel = cookie->rels; rel < cookie->relend; rel++) |
531 |
if (rel->r_offset == offset) |
532 |
return rel; |
533 |
return NULL; |
534 |
} |
535 |
|
536 |
/* Implementation of the SKIP_RELOCS macro for unordered relocations. */ |
537 |
static void |
538 |
_bfd_skip_relocs_unordered (struct elf_reloc_cookie *cookie, bfd_vma offset, |
539 |
bfd_vma *rels_offset) |
540 |
{ |
541 |
Elf_Internal_Rela *rel, *best = NULL; |
542 |
bfd_vma best_offs = -1; |
543 |
|
544 |
/* FIXME: octets_per_byte. */ |
545 |
*rels_offset = offset; |
546 |
for (rel = cookie->rels; rel < cookie->relend; rel++) |
547 |
if (rel->r_offset >= offset && rel->r_offset - offset < best_offs) |
548 |
{ |
549 |
best = rel; |
550 |
best_offs = rel->r_offset - offset; |
551 |
} |
552 |
cookie->rel = best ? best : cookie->relend; |
553 |
} |
554 |
|
555 |
static struct reloc_read_ops _bfd_eh_unordered_relocs = { |
556 |
.chk_relocs = _bfd_chk_relocs_unordered, |
557 |
.get_reloc = _bfd_get_reloc_unordered, |
558 |
.skip_relocs = _bfd_skip_relocs_unordered, |
559 |
}; |
560 |
|
460 |
/* Try to parse .eh_frame section SEC, which belongs to ABFD. Store the |
561 |
/* Try to parse .eh_frame section SEC, which belongs to ABFD. Store the |
461 |
information in the section's sec_info field on success. COOKIE |
562 |
information in the section's sec_info field on success. COOKIE |
462 |
describes the relocations in SEC. */ |
563 |
describes the relocations in SEC. */ |
Lines 473-478
_bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
Link Here
|
473 |
|
574 |
|
474 |
bfd_byte *ehbuf = NULL, *buf, *end; |
575 |
bfd_byte *ehbuf = NULL, *buf, *end; |
475 |
bfd_byte *last_fde; |
576 |
bfd_byte *last_fde; |
|
|
577 |
bfd_size_type sec_info_size = 0; |
578 |
bfd_vma rels_offset = 0; |
476 |
struct eh_cie_fde *this_inf; |
579 |
struct eh_cie_fde *this_inf; |
477 |
unsigned int hdr_length, hdr_id; |
580 |
unsigned int hdr_length, hdr_id; |
478 |
unsigned int cie_count; |
581 |
unsigned int cie_count; |
Lines 484-489
_bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
Link Here
|
484 |
unsigned int num_cies; |
587 |
unsigned int num_cies; |
485 |
unsigned int num_entries; |
588 |
unsigned int num_entries; |
486 |
elf_gc_mark_hook_fn gc_mark_hook; |
589 |
elf_gc_mark_hook_fn gc_mark_hook; |
|
|
590 |
struct reloc_read_ops *rr_ops = NULL; |
487 |
|
591 |
|
488 |
htab = elf_hash_table (info); |
592 |
htab = elf_hash_table (info); |
489 |
hdr_info = &htab->eh_info; |
593 |
hdr_info = &htab->eh_info; |
Lines 552-588
_bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
Link Here
|
552 |
REQUIRE (skip_bytes (&buf, end, hdr_length - 4)); |
656 |
REQUIRE (skip_bytes (&buf, end, hdr_length - 4)); |
553 |
} |
657 |
} |
554 |
|
658 |
|
555 |
sec_info = (struct eh_frame_sec_info *) |
659 |
sec_info_size = sizeof (struct eh_frame_sec_info) |
556 |
bfd_zmalloc (sizeof (struct eh_frame_sec_info) |
660 |
+ (num_entries - 1) * sizeof (struct eh_cie_fde); |
557 |
+ (num_entries - 1) * sizeof (struct eh_cie_fde)); |
661 |
sec_info = (struct eh_frame_sec_info *) bfd_zmalloc (sec_info_size); |
558 |
REQUIRE (sec_info); |
662 |
REQUIRE (sec_info); |
559 |
|
663 |
|
560 |
/* We need to have a "struct cie" for each CIE in this section. */ |
664 |
/* We need to have a "struct cie" for each CIE in this section. */ |
561 |
local_cies = (struct cie *) bfd_zmalloc (num_cies * sizeof (*local_cies)); |
665 |
local_cies = (struct cie *) bfd_zmalloc (num_cies * sizeof (*local_cies)); |
562 |
REQUIRE (local_cies); |
666 |
REQUIRE (local_cies); |
563 |
|
667 |
|
564 |
/* FIXME: octets_per_byte. */ |
668 |
/* Start with the assumption that relocations are ordered by offset */ |
|
|
669 |
rr_ops = &_bfd_eh_ordered_relocs; |
670 |
|
565 |
#define ENSURE_NO_RELOCS(buf) \ |
671 |
#define ENSURE_NO_RELOCS(buf) \ |
566 |
REQUIRE (!(cookie->rel < cookie->relend \ |
672 |
REQUIRE (!(rr_ops->chk_relocs (cookie, rels_offset, \ |
567 |
&& (cookie->rel->r_offset \ |
673 |
(buf) - ehbuf))) |
568 |
< (bfd_size_type) ((buf) - ehbuf)) \ |
|
|
569 |
&& cookie->rel->r_info != 0)) |
570 |
|
674 |
|
571 |
/* FIXME: octets_per_byte. */ |
|
|
572 |
#define SKIP_RELOCS(buf) \ |
675 |
#define SKIP_RELOCS(buf) \ |
573 |
while (cookie->rel < cookie->relend \ |
676 |
(rr_ops->skip_relocs (cookie, (buf) - ehbuf, \ |
574 |
&& (cookie->rel->r_offset \ |
677 |
&rels_offset)) |
575 |
< (bfd_size_type) ((buf) - ehbuf))) \ |
|
|
576 |
cookie->rel++ |
577 |
|
678 |
|
578 |
/* FIXME: octets_per_byte. */ |
|
|
579 |
#define GET_RELOC(buf) \ |
679 |
#define GET_RELOC(buf) \ |
580 |
((cookie->rel < cookie->relend \ |
680 |
(rr_ops->get_reloc (cookie, (buf) - ehbuf)) |
581 |
&& (cookie->rel->r_offset \ |
|
|
582 |
== (bfd_size_type) ((buf) - ehbuf))) \ |
583 |
? cookie->rel : NULL) |
584 |
|
681 |
|
|
|
682 |
restart_reading: |
585 |
buf = ehbuf; |
683 |
buf = ehbuf; |
|
|
684 |
SKIP_RELOCS(buf); |
586 |
cie_count = 0; |
685 |
cie_count = 0; |
587 |
gc_mark_hook = get_elf_backend_data (abfd)->gc_mark_hook; |
686 |
gc_mark_hook = get_elf_backend_data (abfd)->gc_mark_hook; |
588 |
while ((bfd_size_type) (buf - ehbuf) != sec->size) |
687 |
while ((bfd_size_type) (buf - ehbuf) != sec->size) |
Lines 718-728
_bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
Link Here
|
718 |
REQUIRE (GET_RELOC (buf)); |
817 |
REQUIRE (GET_RELOC (buf)); |
719 |
cie->personality.reloc_index |
818 |
cie->personality.reloc_index |
720 |
= cookie->rel - cookie->rels; |
819 |
= cookie->rel - cookie->rels; |
721 |
/* Cope with MIPS-style composite relocations. */ |
|
|
722 |
do |
723 |
cookie->rel++; |
724 |
while (GET_RELOC (buf) != NULL); |
725 |
REQUIRE (skip_bytes (&buf, end, per_width)); |
820 |
REQUIRE (skip_bytes (&buf, end, per_width)); |
|
|
821 |
/* Cope with MIPS-style composite relocations. */ |
822 |
SKIP_RELOCS(buf); |
726 |
} |
823 |
} |
727 |
break; |
824 |
break; |
728 |
default: |
825 |
default: |
Lines 913-918
_bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
Link Here
|
913 |
goto success; |
1010 |
goto success; |
914 |
|
1011 |
|
915 |
free_no_table: |
1012 |
free_no_table: |
|
|
1013 |
if (rr_ops == &_bfd_eh_ordered_relocs) |
1014 |
{ |
1015 |
/* Perhaps, relocations are out of order. Retry with slower version |
1016 |
that does not require ordering. */ |
1017 |
rr_ops = &_bfd_eh_unordered_relocs; |
1018 |
memset(sec_info, 0, sec_info_size); |
1019 |
goto restart_reading; |
1020 |
} |
916 |
(*info->callbacks->einfo) |
1021 |
(*info->callbacks->einfo) |
917 |
(_("%P: error in %B(%A); no .eh_frame_hdr table will be created.\n"), |
1022 |
(_("%P: error in %B(%A); no .eh_frame_hdr table will be created.\n"), |
918 |
abfd, sec); |
1023 |
abfd, sec); |
919 |
- |
|
|