This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: PATCH: Preserve ELF program header
On Fri, May 26, 2006 at 01:19:21PM +0930, Alan Modra wrote:
> On Thu, May 25, 2006 at 07:30:23PM -0700, H. J. Lu wrote:
> > On Fri, May 26, 2006 at 10:21:00AM +0930, Alan Modra wrote:
> > > I don't see the need for m->p_vaddr and m->p_vaddr_valid. How can you
> > > get into a situation where m->sections[0]->vma or 0 is not the right
> > > initialisation for p->p_vaddr?
> > >
> >
> > Here is an x86 example, which is generated with 2MB maximum page size.
> > Due to
> >
> > TEXT_START_ADDR=0x08048000
> >
> > We got p->p_vaddr != m->sections[0]->vma to satisfy 2MB alignment.
>
> Sure. Obviously you need to subtract off space for the headers then
> align. I'm thinking that you can do this by modifying the assignments
> to "align" in the function, particularly places that set "align" from
> "bed->maxpagesize" to instead use your m->p_align. After all, the
> problem you are trying to solve is one where alignment due to
> bed->maxpagesize changes.
>
Here is the updated patch.
H.J.
----
bfd/
2006-05-25 H.J. Lu <hongjiu.lu@intel.com>
* elf.c (assign_file_positions_for_load_sections): Align
segment and set p->p_align with m->p_align if it is valid.
(copy_elf_program_header): Copy p_align. Set p_align_valid to 1.
include/elf/
2006-05-25 H.J. Lu <hongjiu.lu@intel.com>
* internal.h (elf_segment_map): Add p_align and p_align_valid.
--- binutils/bfd/elf.c.phdr 2006-05-25 21:11:34.000000000 -0700
+++ binutils/bfd/elf.c 2006-05-25 21:26:44.000000000 -0700
@@ -4244,8 +4244,13 @@ assign_file_positions_for_load_sections
}
align = (bfd_size_type) 1 << align_power;
- if ((abfd->flags & D_PAGED) != 0 && bed->maxpagesize > align)
- align = bed->maxpagesize;
+ if ((abfd->flags & D_PAGED) != 0)
+ {
+ if (m->p_align_valid)
+ align = m->p_align;
+ else if (bed->maxpagesize > align)
+ align = bed->maxpagesize;
+ }
adjust = vma_page_aligned_bias (m->sections[0]->vma, off, align);
off += adjust;
@@ -4298,7 +4303,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)
@@ -5800,6 +5807,8 @@ 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_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.phdr 2006-02-10 08:59:44.000000000 -0800
+++ binutils/include/elf/internal.h 2006-05-25 21:22:19.000000000 -0700
@@ -235,12 +235,17 @@ struct elf_segment_map
unsigned long p_flags;
/* Program segment physical address. */
bfd_vma p_paddr;
+ /* 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_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. */