* elf.c (assign_file_positions_for_load_sections): Retrieve
	maxpagesize from m->p_align if it is valid.  Set p_vaddr,
	p_paddr and p_align earlier.  Revert 2006-05-19 change to p_align.
	(copy_elf_program_header): Copy p_align.  Set p_align_valid.
include/elf/
	* internal.h (elf_segment_map): Add p_align and p_align_valid.
This commit is contained in:
Alan Modra
2006-05-27 00:47:45 +00:00
parent 6a8d9e540a
commit 3f570048d7
4 changed files with 64 additions and 28 deletions

View File

@ -1,3 +1,11 @@
2006-05-27 Alan Modra <amodra@bigpond.net.au>
H.J. Lu <hongjiu.lu@intel.com>
* elf.c (assign_file_positions_for_load_sections): Retrieve
maxpagesize from m->p_align if it is valid. Set p_vaddr,
p_paddr and p_align earlier. Revert 2006-05-19 change to p_align.
(copy_elf_program_header): Copy p_align. Set p_align_valid.
2006-05-26 H.J. Lu <hongjiu.lu@intel.com> 2006-05-26 H.J. Lu <hongjiu.lu@intel.com>
* elf64-x86-64.c (ELF_MINPAGESIZE): Changed to 0x1000. * elf64-x86-64.c (ELF_MINPAGESIZE): Changed to 0x1000.

View File

@ -4111,6 +4111,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
Elf_Internal_Phdr *phdrs; Elf_Internal_Phdr *phdrs;
Elf_Internal_Phdr *p; Elf_Internal_Phdr *p;
file_ptr off, voff; file_ptr off, voff;
bfd_size_type maxpagesize;
unsigned int count; unsigned int count;
unsigned int alloc; unsigned int alloc;
unsigned int i; unsigned int i;
@ -4196,6 +4197,10 @@ assign_file_positions_for_load_sections (bfd *abfd,
if (phdrs == NULL) if (phdrs == NULL)
return FALSE; return FALSE;
maxpagesize = 1;
if ((abfd->flags & D_PAGED) != 0)
maxpagesize = bed->maxpagesize;
off = bed->s->sizeof_ehdr; off = bed->s->sizeof_ehdr;
off += alloc * bed->s->sizeof_phdr; off += alloc * bed->s->sizeof_phdr;
@ -4227,6 +4232,39 @@ assign_file_positions_for_load_sections (bfd *abfd,
p->p_type = m->p_type; p->p_type = m->p_type;
p->p_flags = m->p_flags; p->p_flags = m->p_flags;
if (m->count == 0)
p->p_vaddr = 0;
else
p->p_vaddr = m->sections[0]->vma;
if (m->p_paddr_valid)
p->p_paddr = m->p_paddr;
else if (m->count == 0)
p->p_paddr = 0;
else
p->p_paddr = m->sections[0]->lma;
if (p->p_type == PT_LOAD
&& (abfd->flags & D_PAGED) != 0)
{
/* p_align in demand paged PT_LOAD segments effectively stores
the maximum page size. When copying an executable with
objcopy, we set m->p_align from the input file. Use this
value for maxpagesize rather than bed->maxpagesize, which
may be different. Note that we use maxpagesize for PT_TLS
segment alignment later in this function, so we are relying
on at least one PT_LOAD segment appearing before a PT_TLS
segment. */
if (m->p_align_valid)
maxpagesize = m->p_align;
p->p_align = maxpagesize;
}
else if (m->count == 0)
p->p_align = 1 << bed->s->log_file_align;
else
p->p_align = 0;
if (p->p_type == PT_LOAD if (p->p_type == PT_LOAD
&& m->count > 0) && m->count > 0)
{ {
@ -4244,8 +4282,8 @@ assign_file_positions_for_load_sections (bfd *abfd,
} }
align = (bfd_size_type) 1 << align_power; align = (bfd_size_type) 1 << align_power;
if ((abfd->flags & D_PAGED) != 0 && bed->maxpagesize > align) if (align < maxpagesize)
align = bed->maxpagesize; align = maxpagesize;
adjust = vma_page_aligned_bias (m->sections[0]->vma, off, align); adjust = vma_page_aligned_bias (m->sections[0]->vma, off, align);
off += adjust; off += adjust;
@ -4286,26 +4324,6 @@ assign_file_positions_for_load_sections (bfd *abfd,
return FALSE; return FALSE;
} }
if (m->count == 0)
p->p_vaddr = 0;
else
p->p_vaddr = m->sections[0]->vma;
if (m->p_paddr_valid)
p->p_paddr = m->p_paddr;
else if (m->count == 0)
p->p_paddr = 0;
else
p->p_paddr = m->sections[0]->lma;
if (p->p_type == PT_LOAD
&& (abfd->flags & D_PAGED) != 0)
p->p_align = bed->maxpagesize;
else if (m->count == 0)
p->p_align = 1 << bed->s->log_file_align;
else
p->p_align = 0;
p->p_offset = 0; p->p_offset = 0;
p->p_filesz = 0; p->p_filesz = 0;
p->p_memsz = 0; p->p_memsz = 0;
@ -4386,7 +4404,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
sec = *secpp; sec = *secpp;
flags = sec->flags; flags = sec->flags;
align = 1 << bfd_get_section_alignment (abfd, sec); align = (bfd_size_type) 1 << bfd_get_section_alignment (abfd, sec);
if (p->p_type == PT_LOAD if (p->p_type == PT_LOAD
|| p->p_type == PT_TLS) || p->p_type == PT_TLS)
@ -4416,8 +4434,8 @@ assign_file_positions_for_load_sections (bfd *abfd,
/* The section VMA must equal the file position /* The section VMA must equal the file position
modulo the page size. */ modulo the page size. */
bfd_size_type page = align; bfd_size_type page = align;
if ((abfd->flags & D_PAGED) != 0 && bed->maxpagesize > page) if (page < maxpagesize)
page = bed->maxpagesize; page = maxpagesize;
adjust = vma_page_aligned_bias (sec->vma, adjust = vma_page_aligned_bias (sec->vma,
p->p_vaddr + p->p_memsz, p->p_vaddr + p->p_memsz,
page); page);
@ -4494,8 +4512,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
if (align > p->p_align if (align > p->p_align
&& (p->p_type != PT_LOAD && (p->p_type != PT_LOAD
|| (abfd->flags & D_PAGED) == 0 || (abfd->flags & D_PAGED) == 0))
|| ((p->p_vaddr - p->p_offset) & (align - 1)) == 0))
p->p_align = align; p->p_align = align;
} }
@ -5800,6 +5817,8 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
map->p_flags_valid = 1; map->p_flags_valid = 1;
map->p_paddr = segment->p_paddr; map->p_paddr = segment->p_paddr;
map->p_paddr_valid = 1; 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 /* Determine if this segment contains the ELF file header
and if it contains the program headers themselves. */ and if it contains the program headers themselves. */

View File

@ -1,3 +1,7 @@
2006-05-27 H.J. Lu <hongjiu.lu@intel.com>
* internal.h (struct elf_segment_map): Add p_align and p_align_valid.
2006-05-24 Carlos O'Donell <carlos@systemhalted.org> 2006-05-24 Carlos O'Donell <carlos@systemhalted.org>
Randolph Chung <randolph@tausq.org> Randolph Chung <randolph@tausq.org>
* hppa.h (R_PARISC_TLS_GD21L, R_PARISC_TLS_GD14R, R_PARISC_TLS_GDCALL, * hppa.h (R_PARISC_TLS_GD21L, R_PARISC_TLS_GD14R, R_PARISC_TLS_GDCALL,

View File

@ -1,6 +1,6 @@
/* ELF support for BFD. /* ELF support for BFD.
Copyright 1991, 1992, 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002, Copyright 1991, 1992, 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002,
2003 Free Software Foundation, Inc. 2003, 2006 Free Software Foundation, Inc.
Written by Fred Fish @ Cygnus Support, from information published Written by Fred Fish @ Cygnus Support, from information published
in "UNIX System V Release 4, Programmers Guide: ANSI C and in "UNIX System V Release 4, Programmers Guide: ANSI C and
@ -235,12 +235,17 @@ struct elf_segment_map
unsigned long p_flags; unsigned long p_flags;
/* Program segment physical address. */ /* Program segment physical address. */
bfd_vma p_paddr; bfd_vma p_paddr;
/* Program segment alignment. */
bfd_vma p_align;
/* Whether the p_flags field is valid; if not, the flags are based /* Whether the p_flags field is valid; if not, the flags are based
on the section flags. */ on the section flags. */
unsigned int p_flags_valid : 1; unsigned int p_flags_valid : 1;
/* Whether the p_paddr field is valid; if not, the physical address /* Whether the p_paddr field is valid; if not, the physical address
is based on the section lma values. */ is based on the section lma values. */
unsigned int p_paddr_valid : 1; unsigned int p_paddr_valid : 1;
/* Whether the p_align field is valid; if not, PT_LOAD segment
alignment is based on the default maximum page size. */
unsigned int p_align_valid : 1;
/* Whether this segment includes the file header. */ /* Whether this segment includes the file header. */
unsigned int includes_filehdr : 1; unsigned int includes_filehdr : 1;
/* Whether this segment includes the program headers. */ /* Whether this segment includes the program headers. */