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]

Re: Zero p_paddr confuses BFD


Some more fixes related to PR 2995 and PR 6473.  I'd left
rewrite_elf_program_header alone because it had a loop to clear
p_paddr_valid at the end of the function, but that doesn't stop
p_vaddr_offset being set.

	PR 2995, PR 6473
	* elf.c (rewrite_elf_program_header): Rather than clearing
	p_paddr_valid at end, don't set it in the first place.  Delete
	comment no longer relevant.  When not p_paddr_valid, don't set
	paddr from vaddr, and don't set p_vaddr_offset.

Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.443
diff -u -p -r1.443 elf.c
--- bfd/elf.c	1 May 2008 17:06:52 -0000	1.443
+++ bfd/elf.c	2 May 2008 10:03:53 -0000
@@ -5056,6 +5056,7 @@ rewrite_elf_program_header (bfd *ibfd, b
   unsigned int i;
   unsigned int num_segments;
   bfd_boolean phdr_included = FALSE;
+  bfd_boolean p_paddr_valid;
   bfd_vma maxpagesize;
   struct elf_segment_map *phdr_adjust_seg = NULL;
   unsigned int phdr_adjust_num = 0;
@@ -5184,6 +5185,20 @@ rewrite_elf_program_header (bfd *ibfd, b
   for (section = ibfd->sections; section != NULL; section = section->next)
     section->segment_mark = FALSE;
 
+  /* The Solaris linker creates program headers in which all the
+     p_paddr fields are zero.  When we try to objcopy or strip such a
+     file, we get confused.  Check for this case, and if we find it
+     don't set the p_paddr_valid fields.  */
+  p_paddr_valid = FALSE;
+  for (i = 0, segment = elf_tdata (ibfd)->phdr;
+       i < num_segments;
+       i++, segment++)
+    if (segment->p_paddr != 0)
+      {
+	p_paddr_valid = TRUE;
+	break;
+      }
+
   /* Scan through the segments specified in the program header
      of the input BFD.  For this first scan we look for overlaps
      in the loadable segments.  These can be created by weird
@@ -5319,7 +5334,7 @@ rewrite_elf_program_header (bfd *ibfd, b
       if (!first_section || first_section->output_section != NULL)
 	{
 	  map->p_paddr = segment->p_paddr;
-	  map->p_paddr_valid = 1;
+	  map->p_paddr_valid = p_paddr_valid;
 	}
 
       /* Determine if this segment contains the ELF file header
@@ -5386,8 +5401,6 @@ rewrite_elf_program_header (bfd *ibfd, b
 	 pointers that we are interested in.  As these sections get assigned
 	 to a segment, they are removed from this array.  */
 
-      /* Gcc 2.96 miscompiles this code on mips. Don't do casting here
-	 to work around this long long bug.  */
       sections = bfd_malloc2 (section_count, sizeof (asection *));
       if (sections == NULL)
 	return FALSE;
@@ -5422,7 +5435,7 @@ rewrite_elf_program_header (bfd *ibfd, b
 		 We try to catch that case here, and set it to the
 		 correct value.  Note - some backends require that
 		 p_paddr be left as zero.  */
-	      if (segment->p_paddr == 0
+	      if (!p_paddr_valid
 		  && segment->p_vaddr != 0
 		  && !bed->want_p_paddr_set_to_zero
 		  && isec == 0
@@ -5480,9 +5493,11 @@ rewrite_elf_program_header (bfd *ibfd, b
 	  *pointer_to_map = map;
 	  pointer_to_map = &map->next;
 
-	  if (!bed->want_p_paddr_set_to_zero
+	  if (p_paddr_valid
+	      && !bed->want_p_paddr_set_to_zero
 	      && matching_lma != map->p_paddr
-	      && !map->includes_filehdr && !map->includes_phdrs)
+	      && !map->includes_filehdr
+	      && !map->includes_phdrs)
 	    /* There is some padding before the first section in the
 	       segment.  So, we must account for that in the output
 	       segment's vma.  */
@@ -5634,7 +5649,7 @@ rewrite_elf_program_header (bfd *ibfd, b
 	      map->p_flags = segment->p_flags;
 	      map->p_flags_valid = 1;
 	      map->p_paddr = suggested_lma;
-	      map->p_paddr_valid = 1;
+	      map->p_paddr_valid = p_paddr_valid;
 	      map->includes_filehdr = 0;
 	      map->includes_phdrs = 0;
 	    }
@@ -5644,17 +5659,6 @@ rewrite_elf_program_header (bfd *ibfd, b
       free (sections);
     }
 
-  /* The Solaris linker creates program headers in which all the
-     p_paddr fields are zero.  When we try to objcopy or strip such a
-     file, we get confused.  Check for this case, and if we find it
-     reset the p_paddr_valid fields.  */
-  for (map = map_first; map != NULL; map = map->next)
-    if (map->p_paddr != 0)
-      break;
-  if (map == NULL)
-    for (map = map_first; map != NULL; map = map->next)
-      map->p_paddr_valid = 0;
-
   elf_tdata (obfd)->segment_map = map_first;
 
   /* If we had to estimate the number of program headers that were

-- 
Alan Modra
Australia Development Lab, IBM


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