This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: PATCH: Preserve segment physical address only if needed
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