This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: Preserve ELF program header


When an ELF executable/shared object is created with different
maximum page size, strip may change ELF program header if it uses
different maximum page size. This patch preserves ELF program header
when copying executable/shared object.


H.J.
----
bfd/

2006-05-25  H.J. Lu  <hongjiu.lu@intel.com>

	* elf.c (assign_file_positions_for_load_sections): Set
	p->p_vaddr with m->p_vaddr if it is valid. Set p->p_align with
	m->p_align if it is valid. Adjust p->p_vaddr only if m->p_vaddr
	isn't valid.
	(copy_elf_program_header): Copy p_vaddr and p_align. Set
	p_vaddr_valid and p_align_valid to 1.

include/elf/

2006-05-25  H.J. Lu  <hongjiu.lu@intel.com>

	* internal.h (elf_segment_map): Add p_vaddr, p_align,
	p_vaddr_valid and p_align_valid.

--- binutils/bfd/elf.c.pagesize	2006-05-22 12:36:40.000000000 -0700
+++ binutils/bfd/elf.c	2006-05-22 16:24:05.000000000 -0700
@@ -4292,7 +4292,9 @@ assign_file_positions_for_load_sections 
 	  return FALSE;
 	}
 
-      if (m->count == 0)
+      if (m->p_vaddr_valid)
+	p->p_vaddr = m->p_vaddr;
+      else if (m->count == 0)
 	p->p_vaddr = 0;
       else
 	p->p_vaddr = m->sections[0]->vma;
@@ -4304,7 +4306,9 @@ assign_file_positions_for_load_sections 
       else
 	p->p_paddr = m->sections[0]->lma;
 
-      if (p->p_type == PT_LOAD
+      if (m->p_align_valid)
+	p->p_align = m->p_align;
+      else if (p->p_type == PT_LOAD
 	  && (abfd->flags & D_PAGED) != 0)
 	p->p_align = bed->maxpagesize;
       else if (m->count == 0)
@@ -4327,16 +4331,18 @@ assign_file_positions_for_load_sections 
 	    {
 	      BFD_ASSERT (p->p_type == PT_LOAD);
 
-	      if (p->p_vaddr < (bfd_vma) off)
+	      if (!m->p_vaddr_valid)
 		{
-		  (*_bfd_error_handler)
-		    (_("%B: Not enough room for program headers, try linking with -N"),
-		     abfd);
-		  bfd_set_error (bfd_error_bad_value);
-		  return FALSE;
+		  if (p->p_vaddr < (bfd_vma) off)
+		    {
+		      (*_bfd_error_handler)
+			(_("%B: Not enough room for program headers, try linking with -N"),
+			 abfd);
+		      bfd_set_error (bfd_error_bad_value);
+		      return FALSE;
+		    }
+		  p->p_vaddr -= off;
 		}
-
-	      p->p_vaddr -= off;
 	      if (! m->p_paddr_valid)
 		p->p_paddr -= off;
 	    }
@@ -5805,6 +5811,10 @@ copy_elf_program_header (bfd *ibfd, bfd 
       map->p_flags_valid = 1;
       map->p_paddr = segment->p_paddr;
       map->p_paddr_valid = 1;
+      map->p_vaddr = segment->p_vaddr;
+      map->p_vaddr_valid = 1;
+      map->p_align = segment->p_align;
+      map->p_align_valid = 1;
 
       /* Determine if this segment contains the ELF file header
 	 and if it contains the program headers themselves.  */
--- binutils/include/elf/internal.h	2006-05-22 12:47:06.000000000 -0700
+++ binutils/include/elf/internal.h	2006-05-22 12:47:06.000000000 -0700
@@ -235,12 +235,22 @@ struct elf_segment_map
   unsigned long p_flags;
   /* Program segment physical address.  */
   bfd_vma p_paddr;
+  /* Program segment virtual address.  */
+  bfd_vma p_vaddr;
+  /* Program segment alignment. */
+  bfd_vma p_align;
   /* Whether the p_flags field is valid; if not, the flags are based
      on the section flags.  */
   unsigned int p_flags_valid : 1;
   /* Whether the p_paddr field is valid; if not, the physical address
      is based on the section lma values.  */
   unsigned int p_paddr_valid : 1;
+  /* Whether the p_vaddr field is valid; if not, the virtual address
+     is based on the section vma values.  */
+  unsigned int p_vaddr_valid : 1;
+  /* Whether the p_align field is valid; if not, the segment alignment
+     is based on the default maximum page size.  */
+  unsigned int p_align_valid : 1;
   /* Whether this segment includes the file header.  */
   unsigned int includes_filehdr : 1;
   /* Whether this segment includes the program headers.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]