FreeBSD/contrib/binutils/bfd/elf.c
/* Copy ELF program header information.  */
Copy ELF program header information.
Copy ELF program header information .
static bfd_boolean
copy_elf_program_header (bfd *ibfd, bfd *obfd)
{
  Elf_Internal_Ehdr *iehdr;
  struct elf_segment_map *map;
  struct elf_segment_map *map_first;
  struct elf_segment_map **pointer_to_map;
  Elf_Internal_Phdr *segment;
  unsigned int i;
  unsigned int num_segments;
  bfd_boolean phdr_included = FALSE;
  iehdr = elf_elfheader (ibfd);
  map_first = NULL;
  pointer_to_map = &map_first;
  num_segments = elf_elfheader (ibfd)->e_phnum;
  for (i = 0, segment = elf_tdata (ibfd)->phdr;
       i < num_segments;
       i++, segment++)
    {
      asection *section;
      unsigned int section_count;
      bfd_size_type amt;
      Elf_Internal_Shdr *this_hdr;
      asection *first_section = NULL;
      if (segment->p_type == PT_NULL)
	continue;
      for (section = ibfd->sections, section_count = 0;
	   section != NULL;
	   section = section->next)
	{
	  this_hdr = &(elf_section_data(section)->this_hdr);
	  if (ELF_IS_SECTION_IN_SEGMENT_FILE (this_hdr, segment))
	    {
	      if (!first_section)
		first_section = section;
	      section_count++;
	    }
	}
      amt = sizeof (struct elf_segment_map);
      if (section_count != 0)
	amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
      map = bfd_zalloc (obfd, amt);
      if (map == NULL)
	return FALSE;
      map->next = NULL;
      map->p_type = segment->p_type;
      map->p_flags = segment->p_flags;
      map->p_flags_valid = 1;
      map->p_paddr = segment->p_paddr;
      map->p_paddr_valid = 1;
      map->p_align = segment->p_align;
      map->p_align_valid = 1;
      map->p_vaddr_offset = 0;
      map->includes_filehdr = (segment->p_offset == 0
			       && segment->p_filesz >= iehdr->e_ehsize);
      map->includes_phdrs = 0;
      if (! phdr_included || segment->p_type != PT_LOAD)
	{
	  map->includes_phdrs =
	    (segment->p_offset <= (bfd_vma) iehdr->e_phoff
	     && (segment->p_offset + segment->p_filesz
		 >= ((bfd_vma) iehdr->e_phoff
		     + iehdr->e_phnum * iehdr->e_phentsize)));
	  if (segment->p_type == PT_LOAD && map->includes_phdrs)
	    phdr_included = TRUE;
	}
      if (!map->includes_phdrs && !map->includes_filehdr)
	map->p_vaddr_offset = ((first_section ? first_section->lma : 0)
			       - segment->p_paddr);
      if (section_count != 0)
	{
	  unsigned int isec = 0;
	  for (section = first_section;
	       section != NULL;
	       section = section->next)
	    {
	      this_hdr = &(elf_section_data(section)->this_hdr);
	      if (ELF_IS_SECTION_IN_SEGMENT_FILE (this_hdr, segment))
		{
		  map->sections[isec++] = section->output_section;
		  if (isec == section_count)
		    break;
		}
	    }
	}
      map->count = section_count;
      *pointer_to_map = map;
      pointer_to_map = &map->next;
    }
  elf_tdata (obfd)->segment_map = map_first;
  return TRUE;
}
static bfd_boolean copy_elf_program_header ( bfd * ibfd , bfd * obfd ) { Elf_Internal_Ehdr * iehdr ; struct elf_segment_map * map ; struct elf_segment_map * map_first ; struct elf_segment_map * * pointer_to_map ; Elf_Internal_Phdr * segment ; unsigned int i ; unsigned int num_segments ; bfd_boolean phdr_included = FALSE ; iehdr = elf_elfheader ( ibfd ) ; map_first = NULL ; pointer_to_map = & map_first ; num_segments = elf_elfheader ( ibfd ) -> e_phnum ; for ( i = 0 , segment = elf_tdata ( ibfd ) -> phdr ; i < num_segments ; i ++ , segment ++ ) { asection * section ; unsigned int section_count ; bfd_size_type amt ; Elf_Internal_Shdr * this_hdr ; asection * first_section = NULL ; if ( segment -> p_type == PT_NULL ) continue ; for ( section = ibfd -> sections , section_count = 0 ; section != NULL ; section = section -> next ) { this_hdr = & ( elf_section_data ( section ) -> this_hdr ) ; if ( ELF_IS_SECTION_IN_SEGMENT_FILE ( this_hdr , segment ) ) { if ( ! first_section ) first_section = section ; section_count ++ ; } } amt = sizeof ( struct elf_segment_map ) ; if ( section_count != 0 ) amt += ( ( bfd_size_type ) section_count - 1 ) * sizeof ( asection * ) ; map = bfd_zalloc ( obfd , amt ) ; if ( map == NULL ) return FALSE ; map -> next = NULL ; map -> p_type = segment -> p_type ; map -> p_flags = segment -> p_flags ; map -> p_flags_valid = 1 ; map -> p_paddr = segment -> p_paddr ; map -> p_paddr_valid = 1 ; map -> p_align = segment -> p_align ; map -> p_align_valid = 1 ; map -> p_vaddr_offset = 0 ; map -> includes_filehdr = ( segment -> p_offset == 0 && segment -> p_filesz >= iehdr -> e_ehsize ) ; map -> includes_phdrs = 0 ; if ( ! phdr_included || segment -> p_type != PT_LOAD ) { map -> includes_phdrs = ( segment -> p_offset <= ( bfd_vma ) iehdr -> e_phoff && ( segment -> p_offset + segment -> p_filesz >= ( ( bfd_vma ) iehdr -> e_phoff + iehdr -> e_phnum * iehdr -> e_phentsize ) ) ) ; if ( segment -> p_type == PT_LOAD && map -> includes_phdrs ) phdr_included = TRUE ; } if ( ! map -> includes_phdrs && ! map -> includes_filehdr ) map -> p_vaddr_offset = ( ( first_section ? first_section -> lma : 0 ) - segment -> p_paddr ) ; if ( section_count != 0 ) { unsigned int isec = 0 ; for ( section = first_section ; section != NULL ; section = section -> next ) { this_hdr = & ( elf_section_data ( section ) -> this_hdr ) ; if ( ELF_IS_SECTION_IN_SEGMENT_FILE ( this_hdr , segment ) ) { map -> sections [ isec ++ ] = section -> output_section ; if ( isec == section_count ) break ; } } } map -> count = section_count ; * pointer_to_map = map ; pointer_to_map = & map -> next ; } elf_tdata ( obfd ) -> segment_map = map_first ; return TRUE ; }
Copy ELF program header information.
Copy ELF program header information .
/* FIXME: Do we need to copy PT_NULL segment?  */ /* Compute how many sections are in this segment.  */ /* Allocate a segment map big enough to contain
	 all of the sections we have selected.  */ /* Initialize the fields of the output segment map with the
	 input segment.  */ /* Determine if this segment contains the ELF file header
	 and if it contains the program headers themselves.  */ /* There is some other padding before the first section.  */