Added --identify option to dlltool.
[binutils-gdb.git] / bfd / elf.c
index cb7d2fc3e447b50da53ad3958cc6bd5d8a9968d0..4525faab3b404623a7241785400caca31cc54d28 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -4158,6 +4158,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
   bfd_size_type maxpagesize;
   unsigned int alloc;
   unsigned int i, j;
+  bfd_vma header_pad = 0;
 
   if (link_info == NULL
       && !_bfd_elf_map_sections_to_segments (abfd, link_info))
@@ -4165,7 +4166,11 @@ assign_file_positions_for_load_sections (bfd *abfd,
 
   alloc = 0;
   for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
-    ++alloc;
+    {
+      ++alloc;
+      if (m->header_size)
+       header_pad = m->header_size;
+    }
 
   elf_elfheader (abfd)->e_phoff = bed->s->sizeof_ehdr;
   elf_elfheader (abfd)->e_phentsize = bed->s->sizeof_phdr;
@@ -4183,7 +4188,21 @@ assign_file_positions_for_load_sections (bfd *abfd,
       return TRUE;
     }
 
-  phdrs = bfd_alloc2 (abfd, alloc, sizeof (Elf_Internal_Phdr));
+  /* We're writing the size in elf_tdata (abfd)->program_header_size,
+     see assign_file_positions_except_relocs, so make sure we have
+     that amount allocated, with trailing space cleared.
+     The variable alloc contains the computed need, while elf_tdata
+     (abfd)->program_header_size contains the size used for the
+     layout.
+     See ld/emultempl/elf-generic.em:gld${EMULATION_NAME}_map_segments
+     where the layout is forced to according to a larger size in the
+     last iterations for the testcase ld-elf/header.  */
+  BFD_ASSERT (elf_tdata (abfd)->program_header_size % bed->s->sizeof_phdr
+             == 0);
+  phdrs = bfd_zalloc2 (abfd,
+                      (elf_tdata (abfd)->program_header_size
+                       / bed->s->sizeof_phdr),
+                      sizeof (Elf_Internal_Phdr));
   elf_tdata (abfd)->phdr = phdrs;
   if (phdrs == NULL)
     return FALSE;
@@ -4194,6 +4213,11 @@ assign_file_positions_for_load_sections (bfd *abfd,
 
   off = bed->s->sizeof_ehdr;
   off += alloc * bed->s->sizeof_phdr;
+  if (header_pad < (bfd_vma) off)
+    header_pad = 0;
+  else
+    header_pad -= off;
+  off += header_pad;
 
   for (m = elf_tdata (abfd)->segment_map, p = phdrs, j = 0;
        m != NULL;
@@ -4381,6 +4405,11 @@ assign_file_positions_for_load_sections (bfd *abfd,
 
          p->p_filesz += alloc * bed->s->sizeof_phdr;
          p->p_memsz += alloc * bed->s->sizeof_phdr;
+         if (m->count)
+           {
+             p->p_filesz += header_pad;
+             p->p_memsz += header_pad;
+           }
        }
 
       if (p->p_type == PT_LOAD
@@ -5863,6 +5892,10 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
            phdr_included = TRUE;
        }
 
+      if (map->includes_filehdr && first_section)
+       /* We need to keep the space used by the headers fixed.  */
+       map->header_size = first_section->vma - segment->p_vaddr;
+      
       if (!map->includes_phdrs
          && !map->includes_filehdr
          && map->p_paddr_valid)