FreeBSD/contrib/binutils/bfd/elf.c
/* Read and convert symbols to internal format.
   SYMCOUNT specifies the number of symbols to read, starting from
   symbol SYMOFFSET.  If any of INTSYM_BUF, EXTSYM_BUF or EXTSHNDX_BUF
   are non-NULL, they are used to store the internal symbols, external
   symbols, and symbol section index extensions, respectively.  */
Read and convert symbols to internal format.
SYMCOUNT specifies the number of symbols to read, starting from
symbol SYMOFFSET.  If any of INTSYM_BUF, EXTSYM_BUF or EXTSHNDX_BUF
are non-NULL, they are used to store the internal symbols, external
symbols, and symbol section index extensions, respectively.
Read and convert symbols to internal format . SYMCOUNT specifies the number of symbols to read starting from symbol SYMOFFSET . If any of INTSYM_BUF EXTSYM_BUF or EXTSHNDX_BUF are non - NULL they are used to store the internal symbols external symbols and symbol section index extensions respectively .
Elf_Internal_Sym *
bfd_elf_get_elf_syms (bfd *ibfd,
		      Elf_Internal_Shdr *symtab_hdr,
		      size_t symcount,
		      size_t symoffset,
		      Elf_Internal_Sym *intsym_buf,
		      void *extsym_buf,
		      Elf_External_Sym_Shndx *extshndx_buf)
{
  Elf_Internal_Shdr *shndx_hdr;
  void *alloc_ext;
  const bfd_byte *esym;
  Elf_External_Sym_Shndx *alloc_extshndx;
  Elf_External_Sym_Shndx *shndx;
  Elf_Internal_Sym *isym;
  Elf_Internal_Sym *isymend;
  const struct elf_backend_data *bed;
  size_t extsym_size;
  bfd_size_type amt;
  file_ptr pos;
  if (symcount == 0)
    return intsym_buf;
  shndx_hdr = NULL;
  if (symtab_hdr == &elf_tdata (ibfd)->symtab_hdr)
    shndx_hdr = &elf_tdata (ibfd)->symtab_shndx_hdr;
  alloc_ext = NULL;
  alloc_extshndx = NULL;
  bed = get_elf_backend_data (ibfd);
  extsym_size = bed->s->sizeof_sym;
  amt = symcount * extsym_size;
  pos = symtab_hdr->sh_offset + symoffset * extsym_size;
  if (extsym_buf == NULL)
    {
      alloc_ext = bfd_malloc2 (symcount, extsym_size);
      extsym_buf = alloc_ext;
    }
  if (extsym_buf == NULL
      || bfd_seek (ibfd, pos, SEEK_SET) != 0
      || bfd_bread (extsym_buf, amt, ibfd) != amt)
    {
      intsym_buf = NULL;
      goto out;
    }
  if (shndx_hdr == NULL || shndx_hdr->sh_size == 0)
    extshndx_buf = NULL;
  else
    {
      amt = symcount * sizeof (Elf_External_Sym_Shndx);
      pos = shndx_hdr->sh_offset + symoffset * sizeof (Elf_External_Sym_Shndx);
      if (extshndx_buf == NULL)
	{
	  alloc_extshndx = bfd_malloc2 (symcount,
					sizeof (Elf_External_Sym_Shndx));
	  extshndx_buf = alloc_extshndx;
	}
      if (extshndx_buf == NULL
	  || bfd_seek (ibfd, pos, SEEK_SET) != 0
	  || bfd_bread (extshndx_buf, amt, ibfd) != amt)
	{
	  intsym_buf = NULL;
	  goto out;
	}
    }
  if (intsym_buf == NULL)
    {
      intsym_buf = bfd_malloc2 (symcount, sizeof (Elf_Internal_Sym));
      if (intsym_buf == NULL)
	goto out;
    }
  isymend = intsym_buf + symcount;
  for (esym = extsym_buf, isym = intsym_buf, shndx = extshndx_buf;
       isym < isymend;
       esym += extsym_size, isym++, shndx = shndx != NULL ? shndx + 1 : NULL)
    if (!(*bed->s->swap_symbol_in) (ibfd, esym, shndx, isym))
      {
	symoffset += (esym - (bfd_byte *) extsym_buf) / extsym_size;
	(*_bfd_error_handler) (_("%B symbol number %lu references "
				 "nonexistent SHT_SYMTAB_SHNDX section"),
			       ibfd, (unsigned long) symoffset);
	intsym_buf = NULL;
	goto out;
      }
 out:
  if (alloc_ext != NULL)
    free (alloc_ext);
  if (alloc_extshndx != NULL)
    free (alloc_extshndx);
  return intsym_buf;
}
Elf_Internal_Sym * bfd_elf_get_elf_syms ( bfd * ibfd , Elf_Internal_Shdr * symtab_hdr , size_t symcount , size_t symoffset , Elf_Internal_Sym * intsym_buf , void * extsym_buf , Elf_External_Sym_Shndx * extshndx_buf ) { Elf_Internal_Shdr * shndx_hdr ; void * alloc_ext ; const bfd_byte * esym ; Elf_External_Sym_Shndx * alloc_extshndx ; Elf_External_Sym_Shndx * shndx ; Elf_Internal_Sym * isym ; Elf_Internal_Sym * isymend ; const struct elf_backend_data * bed ; size_t extsym_size ; bfd_size_type amt ; file_ptr pos ; if ( symcount == 0 ) return intsym_buf ; shndx_hdr = NULL ; if ( symtab_hdr == & elf_tdata ( ibfd ) -> symtab_hdr ) shndx_hdr = & elf_tdata ( ibfd ) -> symtab_shndx_hdr ; alloc_ext = NULL ; alloc_extshndx = NULL ; bed = get_elf_backend_data ( ibfd ) ; extsym_size = bed -> s -> sizeof_sym ; amt = symcount * extsym_size ; pos = symtab_hdr -> sh_offset + symoffset * extsym_size ; if ( extsym_buf == NULL ) { alloc_ext = bfd_malloc2 ( symcount , extsym_size ) ; extsym_buf = alloc_ext ; } if ( extsym_buf == NULL || bfd_seek ( ibfd , pos , SEEK_SET ) != 0 || bfd_bread ( extsym_buf , amt , ibfd ) != amt ) { intsym_buf = NULL ; goto out ; } if ( shndx_hdr == NULL || shndx_hdr -> sh_size == 0 ) extshndx_buf = NULL ; else { amt = symcount * sizeof ( Elf_External_Sym_Shndx ) ; pos = shndx_hdr -> sh_offset + symoffset * sizeof ( Elf_External_Sym_Shndx ) ; if ( extshndx_buf == NULL ) { alloc_extshndx = bfd_malloc2 ( symcount , sizeof ( Elf_External_Sym_Shndx ) ) ; extshndx_buf = alloc_extshndx ; } if ( extshndx_buf == NULL || bfd_seek ( ibfd , pos , SEEK_SET ) != 0 || bfd_bread ( extshndx_buf , amt , ibfd ) != amt ) { intsym_buf = NULL ; goto out ; } } if ( intsym_buf == NULL ) { intsym_buf = bfd_malloc2 ( symcount , sizeof ( Elf_Internal_Sym ) ) ; if ( intsym_buf == NULL ) goto out ; } isymend = intsym_buf + symcount ; for ( esym = extsym_buf , isym = intsym_buf , shndx = extshndx_buf ; isym < isymend ; esym += extsym_size , isym ++ , shndx = shndx != NULL ? shndx + 1 : NULL ) if ( ! ( * bed -> s -> swap_symbol_in ) ( ibfd , esym , shndx , isym ) ) { symoffset += ( esym - ( bfd_byte * ) extsym_buf ) / extsym_size ; ( * _bfd_error_handler ) ( _ ( " " " " ) , ibfd , ( unsigned long ) symoffset ) ; intsym_buf = NULL ; goto out ; } out : if ( alloc_ext != NULL ) free ( alloc_ext ) ; if ( alloc_extshndx != NULL ) free ( alloc_extshndx ) ; return intsym_buf ; }
Read and convert symbols to internal format.
Read and convert symbols to internal format .
/* Normal syms might have section extension entries.  */ /* Read the symbols.  */ /* Convert the symbols to internal form.  */