FreeBSD/contrib/binutils/bfd/elflink.c
/* Read and swap the relocs from the section indicated by SHDR.  This
   may be either a REL or a RELA section.  The relocations are
   translated into RELA relocations and stored in INTERNAL_RELOCS,
   which should have already been allocated to contain enough space.
   The EXTERNAL_RELOCS are a buffer where the external form of the
   relocations should be stored.

   Returns FALSE if something goes wrong.  */
Read and swap the relocs from the section indicated by SHDR.  This
may be either a REL or a RELA section.  The relocations are
translated into RELA relocations and stored in INTERNAL_RELOCS,
which should have already been allocated to contain enough space.
The EXTERNAL_RELOCS are a buffer where the external form of the
relocations should be stored.

Returns FALSE if something goes wrong.
Read and swap the relocs from the section indicated by SHDR . This may be either a REL or a RELA section . The relocations are translated into RELA relocations and stored in INTERNAL_RELOCS which should have already been allocated to contain enough space . The EXTERNAL_RELOCS are a buffer where the external form of the relocations should be stored . Returns FALSE if something goes wrong .
static bfd_boolean
elf_link_read_relocs_from_section (bfd *abfd,
				   asection *sec,
				   Elf_Internal_Shdr *shdr,
				   void *external_relocs,
				   Elf_Internal_Rela *internal_relocs)
{
  const struct elf_backend_data *bed;
  void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *);
  const bfd_byte *erela;
  const bfd_byte *erelaend;
  Elf_Internal_Rela *irela;
  Elf_Internal_Shdr *symtab_hdr;
  size_t nsyms;
  if (bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0)
    return FALSE;
  if (bfd_bread (external_relocs, shdr->sh_size, abfd) != shdr->sh_size)
    return FALSE;
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
  nsyms = symtab_hdr->sh_size / symtab_hdr->sh_entsize;
  bed = get_elf_backend_data (abfd);
  if (shdr->sh_entsize == bed->s->sizeof_rel)
    swap_in = bed->s->swap_reloc_in;
  else if (shdr->sh_entsize == bed->s->sizeof_rela)
    swap_in = bed->s->swap_reloca_in;
  else
    {
      bfd_set_error (bfd_error_wrong_format);
      return FALSE;
    }
  erela = external_relocs;
  erelaend = erela + shdr->sh_size;
  irela = internal_relocs;
  while (erela < erelaend)
    {
      bfd_vma r_symndx;
      (*swap_in) (abfd, erela, irela);
      r_symndx = ELF32_R_SYM (irela->r_info);
      if (bed->s->arch_size == 64)
	r_symndx >>= 24;
      if ((size_t) r_symndx >= nsyms)
	{
	  (*_bfd_error_handler)
	    (_("%B: bad reloc symbol index (0x%lx >= 0x%lx)"
	       " for offset 0x%lx in section `%A'"),
	     abfd, sec,
	     (unsigned long) r_symndx, (unsigned long) nsyms, irela->r_offset);
	  bfd_set_error (bfd_error_bad_value);
	  return FALSE;
	}
      irela += bed->s->int_rels_per_ext_rel;
      erela += shdr->sh_entsize;
    }
  return TRUE;
}
static bfd_boolean elf_link_read_relocs_from_section ( bfd * abfd , asection * sec , Elf_Internal_Shdr * shdr , void * external_relocs , Elf_Internal_Rela * internal_relocs ) { const struct elf_backend_data * bed ; void ( * swap_in ) ( bfd * , const bfd_byte * , Elf_Internal_Rela * ) ; const bfd_byte * erela ; const bfd_byte * erelaend ; Elf_Internal_Rela * irela ; Elf_Internal_Shdr * symtab_hdr ; size_t nsyms ; if ( bfd_seek ( abfd , shdr -> sh_offset , SEEK_SET ) != 0 ) return FALSE ; if ( bfd_bread ( external_relocs , shdr -> sh_size , abfd ) != shdr -> sh_size ) return FALSE ; symtab_hdr = & elf_tdata ( abfd ) -> symtab_hdr ; nsyms = symtab_hdr -> sh_size / symtab_hdr -> sh_entsize ; bed = get_elf_backend_data ( abfd ) ; if ( shdr -> sh_entsize == bed -> s -> sizeof_rel ) swap_in = bed -> s -> swap_reloc_in ; else if ( shdr -> sh_entsize == bed -> s -> sizeof_rela ) swap_in = bed -> s -> swap_reloca_in ; else { bfd_set_error ( bfd_error_wrong_format ) ; return FALSE ; } erela = external_relocs ; erelaend = erela + shdr -> sh_size ; irela = internal_relocs ; while ( erela < erelaend ) { bfd_vma r_symndx ; ( * swap_in ) ( abfd , erela , irela ) ; r_symndx = ELF32_R_SYM ( irela -> r_info ) ; if ( bed -> s -> arch_size == 64 ) r_symndx >>= 24 ; if ( ( size_t ) r_symndx >= nsyms ) { ( * _bfd_error_handler ) ( _ ( " " " " ) , abfd , sec , ( unsigned long ) r_symndx , ( unsigned long ) nsyms , irela -> r_offset ) ; bfd_set_error ( bfd_error_bad_value ) ; return FALSE ; } irela += bed -> s -> int_rels_per_ext_rel ; erela += shdr -> sh_entsize ; } return TRUE ; }
Read and swap the relocs from the section indicated by SHDR.
Read and swap the relocs from the section indicated by SHDR .
/* Position ourselves at the start of the section.  */ /* Read the relocations.  */ /* Convert the external relocations to the internal format.  */