PATCH: Preserve segment physical address only if needed

H. J. Lu hjl@lucon.org
Fri Nov 24 17:19:00 GMT 2006


On Fri, Nov 24, 2006 at 06:44:09AM -0800, H. J. Lu wrote:
> On Thu, Nov 23, 2006 at 10:15:57PM -0800, H. J. Lu wrote:
> > On Fri, Nov 24, 2006 at 11:27:56AM +1030, Alan Modra wrote:
> > > On Thu, Nov 23, 2006 at 03:38:39PM -0800, H. J. Lu wrote:
> > > > I meant to say "segment physical address". The test is to check if the
> > > > first section isn't removed. If it isn't removed, we will preserve
> > > > segment physical address by setting
> > > > 
> > > > 	map->p_paddr = segment->p_paddr;
> > > > 	map->p_paddr_valid = 1;
> > > > 
> > > > The first section isn't removed only if first_section == NULL or
> > > > first_section->output_section != NULL.
> > > 
> > > Hmm, OK, that makes some sort of sense.  For the first part of your
> > > patch, can you explain why you didn't use something like
> > > 
> > >       for (section = ibfd->sections, section_count = 0;
> > > 	   section != NULL;
> > > 	   section = section->next)
> > > 	if (INCLUDE_SECTION_IN_SEGMENT (section, segment, bed)
> > > 	  {
> > > 	    ++section_count;
> > > 	    if (first_section == NULL)
> > > 	      first_section = section;
> > > 	  }
> > 
> > INCLUDE_SECTION_IN_SEGMENT has
> > 
> > 	&& section->output_section != NULL 
> > 
> > This will set first_section to the first section in the output
> > segment, which isn't the first section in the input segment if it
> > has been removed. What we need to know is if the first section in the
> > input segment has been removed or not. Here is the updated comment.
> > 
> > 
> 
> We don't need to preserve segmentphysical address in the output
> segment even if the first section in the corresponding input segment
> isn't aligned with the input segment.
> 
> 

It is cleaner to add IS_SECTION_IN_INPUT_SEGMENT to check if a
section is in input segment.


H.J.
-----
2006-11-23  H.J. Lu  <hongjiu.lu@intel.com>

	* elf.c (IS_SECTION_IN_INPUT_SEGMENT): New.
	(INCLUDE_SECTION_IN_SEGMENT): Use IS_SECTION_IN_INPUT_SEGMENT.
	(rewrite_elf_program_header): Don't preserve segment physical
	address in the output segment if the first section in the
	corresponding input segment is removed.

--- bfd/elf.c.strip	2006-11-23 07:55:03.000000000 -0800
+++ bfd/elf.c	2006-11-24 09:13:53.000000000 -0800
@@ -5291,13 +5291,12 @@ rewrite_elf_program_header (bfd *ibfd, b
        7. SHF_TLS sections are only in PT_TLS or PT_LOAD segments.
        8. PT_DYNAMIC should not contain empty sections at the beginning
           (with the possible exception of .dynamic).  */
-#define INCLUDE_SECTION_IN_SEGMENT(section, segment, bed)		\
+#define IS_SECTION_IN_INPUT_SEGMENT(section, segment, bed)		\
   ((((segment->p_paddr							\
       ? IS_CONTAINED_BY_LMA (section, segment, segment->p_paddr)	\
       : IS_CONTAINED_BY_VMA (section, segment))				\
      && (section->flags & SEC_ALLOC) != 0)				\
     || IS_COREFILE_NOTE (segment, section))				\
-   && section->output_section != NULL					\
    && segment->p_type != PT_GNU_STACK					\
    && (segment->p_type != PT_TLS					\
        || (section->flags & SEC_THREAD_LOCAL))				\
@@ -5313,6 +5312,12 @@ rewrite_elf_program_header (bfd *ibfd, b
            == 0))							\
    && ! section->segment_mark)
 
+/* If the output section of a section in the input segment is NULL,
+   it is removed from the corresponding output segment.   */
+#define INCLUDE_SECTION_IN_SEGMENT(section, segment, bed)		\
+  (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed)		\
+   && section->output_section != NULL)
+
   /* Returns TRUE iff seg1 starts after the end of seg2.  */
 #define SEGMENT_AFTER_SEGMENT(seg1, seg2, field)			\
   (seg1->field >= SEGMENT_END (seg2, seg2->field))
@@ -5427,16 +5432,27 @@ rewrite_elf_program_header (bfd *ibfd, b
       bfd_vma       suggested_lma;
       unsigned int  j;
       bfd_size_type amt;
+      asection *    first_section;
 
       if (segment->p_type == PT_NULL)
 	continue;
 
+      first_section = NULL;
       /* Compute how many sections might be placed into this segment.  */
       for (section = ibfd->sections, section_count = 0;
 	   section != NULL;
 	   section = section->next)
-	if (INCLUDE_SECTION_IN_SEGMENT (section, segment, bed))
-	  ++section_count;
+	{
+	  /* Find the first section in the input segment, which may be
+	     removed from the corresponding output segment.   */
+	  if (IS_SECTION_IN_INPUT_SEGMENT (section, segment, bed))
+	    {
+	      if (first_section == NULL)
+		first_section = section;
+	      if (section->output_section != NULL)
+		++section_count;
+	    }
+	}
 
       /* Allocate a segment map big enough to contain
 	 all of the sections we have selected.  */
@@ -5452,8 +5468,14 @@ rewrite_elf_program_header (bfd *ibfd, b
       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;
+      /* If the first section in the input segment is removed, there is
+	 no need to preserve segment physical address in the corresponding
+	 output segment.  */
+      if (first_section->output_section != NULL)
+	{
+	  map->p_paddr = segment->p_paddr;
+	  map->p_paddr_valid = 1;
+	}
 
       /* Determine if this segment contains the ELF file header
 	 and if it contains the program headers themselves.  */
@@ -5783,6 +5805,7 @@ rewrite_elf_program_header (bfd *ibfd, b
 #undef IS_CONTAINED_BY_LMA
 #undef IS_COREFILE_NOTE
 #undef IS_SOLARIS_PT_INTERP
+#undef IS_SECTION_IN_INPUT_SEGMENT
 #undef INCLUDE_SECTION_IN_SEGMENT
 #undef SEGMENT_AFTER_SEGMENT
 #undef SEGMENT_OVERLAPS



More information about the Binutils mailing list