View | Details | Raw Unified | Return to bug 16345
Collapse All | Expand All

(-)a/bfd/elf-eh-frame.c (-23 / +127 lines)
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
- 

Return to bug 16345