FreeBSD/contrib/binutils/bfd/elflink.c
/* Read and swap the relocs for a section O.  They may have been
   cached.  If the EXTERNAL_RELOCS and INTERNAL_RELOCS arguments are
   not NULL, they are used as buffers to read into.  They are known to
   be large enough.  If the INTERNAL_RELOCS relocs argument is NULL,
   the return value is allocated using either malloc or bfd_alloc,
   according to the KEEP_MEMORY argument.  If O has two relocation
   sections (both REL and RELA relocations), then the REL_HDR
   relocations will appear first in INTERNAL_RELOCS, followed by the
   REL_HDR2 relocations.  */
Read and swap the relocs for a section O.  They may have been
cached.  If the EXTERNAL_RELOCS and INTERNAL_RELOCS arguments are
not NULL, they are used as buffers to read into.  They are known to
be large enough.  If the INTERNAL_RELOCS relocs argument is NULL,
the return value is allocated using either malloc or bfd_alloc,
according to the KEEP_MEMORY argument.  If O has two relocation
sections (both REL and RELA relocations), then the REL_HDR
relocations will appear first in INTERNAL_RELOCS, followed by the
REL_HDR2 relocations.
Read and swap the relocs for a section O . They may have been cached . If the EXTERNAL_RELOCS and INTERNAL_RELOCS arguments are not NULL they are used as buffers to read into . They are known to be large enough . If the INTERNAL_RELOCS relocs argument is NULL the return value is allocated using either malloc or bfd_alloc according to the KEEP_MEMORY argument . If O has two relocation sections ( both REL and RELA relocations ) then the REL_HDR relocations will appear first in INTERNAL_RELOCS followed by the REL_HDR2 relocations .
Elf_Internal_Rela *
_bfd_elf_link_read_relocs (bfd *abfd,
			   asection *o,
			   void *external_relocs,
			   Elf_Internal_Rela *internal_relocs,
			   bfd_boolean keep_memory)
{
  Elf_Internal_Shdr *rel_hdr;
  void *alloc1 = NULL;
  Elf_Internal_Rela *alloc2 = NULL;
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  if (elf_section_data (o)->relocs != NULL)
    return elf_section_data (o)->relocs;
  if (o->reloc_count == 0)
    return NULL;
  rel_hdr = &elf_section_data (o)->rel_hdr;
  if (internal_relocs == NULL)
    {
      bfd_size_type size;
      size = o->reloc_count;
      size *= bed->s->int_rels_per_ext_rel * sizeof (Elf_Internal_Rela);
      if (keep_memory)
	internal_relocs = bfd_alloc (abfd, size);
      else
	internal_relocs = alloc2 = bfd_malloc (size);
      if (internal_relocs == NULL)
	goto error_return;
    }
  if (external_relocs == NULL)
    {
      bfd_size_type size = rel_hdr->sh_size;
      if (elf_section_data (o)->rel_hdr2)
	size += elf_section_data (o)->rel_hdr2->sh_size;
      alloc1 = bfd_malloc (size);
      if (alloc1 == NULL)
	goto error_return;
      external_relocs = alloc1;
    }
  if (!elf_link_read_relocs_from_section (abfd, o, rel_hdr,
					  external_relocs,
					  internal_relocs))
    goto error_return;
  if (elf_section_data (o)->rel_hdr2
      && (!elf_link_read_relocs_from_section
	  (abfd, o,
	   elf_section_data (o)->rel_hdr2,
	   ((bfd_byte *) external_relocs) + rel_hdr->sh_size,
	   internal_relocs + (NUM_SHDR_ENTRIES (rel_hdr)
			      * bed->s->int_rels_per_ext_rel))))
    goto error_return;
  if (keep_memory)
    elf_section_data (o)->relocs = internal_relocs;
  if (alloc1 != NULL)
    free (alloc1);
  return internal_relocs;
 error_return:
  if (alloc1 != NULL)
    free (alloc1);
  if (alloc2 != NULL)
    free (alloc2);
  return NULL;
}
Elf_Internal_Rela * _bfd_elf_link_read_relocs ( bfd * abfd , asection * o , void * external_relocs , Elf_Internal_Rela * internal_relocs , bfd_boolean keep_memory ) { Elf_Internal_Shdr * rel_hdr ; void * alloc1 = NULL ; Elf_Internal_Rela * alloc2 = NULL ; const struct elf_backend_data * bed = get_elf_backend_data ( abfd ) ; if ( elf_section_data ( o ) -> relocs != NULL ) return elf_section_data ( o ) -> relocs ; if ( o -> reloc_count == 0 ) return NULL ; rel_hdr = & elf_section_data ( o ) -> rel_hdr ; if ( internal_relocs == NULL ) { bfd_size_type size ; size = o -> reloc_count ; size *= bed -> s -> int_rels_per_ext_rel * sizeof ( Elf_Internal_Rela ) ; if ( keep_memory ) internal_relocs = bfd_alloc ( abfd , size ) ; else internal_relocs = alloc2 = bfd_malloc ( size ) ; if ( internal_relocs == NULL ) goto error_return ; } if ( external_relocs == NULL ) { bfd_size_type size = rel_hdr -> sh_size ; if ( elf_section_data ( o ) -> rel_hdr2 ) size += elf_section_data ( o ) -> rel_hdr2 -> sh_size ; alloc1 = bfd_malloc ( size ) ; if ( alloc1 == NULL ) goto error_return ; external_relocs = alloc1 ; } if ( ! elf_link_read_relocs_from_section ( abfd , o , rel_hdr , external_relocs , internal_relocs ) ) goto error_return ; if ( elf_section_data ( o ) -> rel_hdr2 && ( ! elf_link_read_relocs_from_section ( abfd , o , elf_section_data ( o ) -> rel_hdr2 , ( ( bfd_byte * ) external_relocs ) + rel_hdr -> sh_size , internal_relocs + ( NUM_SHDR_ENTRIES ( rel_hdr ) * bed -> s -> int_rels_per_ext_rel ) ) ) ) goto error_return ; if ( keep_memory ) elf_section_data ( o ) -> relocs = internal_relocs ; if ( alloc1 != NULL ) free ( alloc1 ) ; return internal_relocs ; error_return : if ( alloc1 != NULL ) free ( alloc1 ) ; if ( alloc2 != NULL ) free ( alloc2 ) ; return NULL ; }
Read and swap the relocs for a section O.
Read and swap the relocs for a section O .
/* Cache the results for next time, if we can.  */ /* Don't free alloc2, since if it was allocated we are passing it
     back (under the name of internal_relocs).  */