diff options
author | Alan Modra <amodra@gmail.com> | 2006-05-27 00:47:45 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2006-05-27 00:47:45 +0000 |
commit | 3f570048d764dc9730cfbcf0b84b707333124f1c (patch) | |
tree | 0d017bdf1842c38aff61b0603ecac2b06363d6f1 | |
parent | 6a8d9e540a2f870b5a9bbbc778d47aa50866d5ac (diff) | |
download | gdb-3f570048d764dc9730cfbcf0b84b707333124f1c.zip gdb-3f570048d764dc9730cfbcf0b84b707333124f1c.tar.gz gdb-3f570048d764dc9730cfbcf0b84b707333124f1c.tar.bz2 |
bfd/
* 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.
-rw-r--r-- | bfd/ChangeLog | 8 | ||||
-rw-r--r-- | bfd/elf.c | 73 | ||||
-rw-r--r-- | include/elf/ChangeLog | 4 | ||||
-rw-r--r-- | include/elf/internal.h | 7 |
4 files changed, 64 insertions, 28 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 2d72031..97302a7 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -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> * elf64-x86-64.c (ELF_MINPAGESIZE): Changed to 0x1000. @@ -4111,6 +4111,7 @@ assign_file_positions_for_load_sections (bfd *abfd, Elf_Internal_Phdr *phdrs; Elf_Internal_Phdr *p; file_ptr off, voff; + bfd_size_type maxpagesize; unsigned int count; unsigned int alloc; unsigned int i; @@ -4196,6 +4197,10 @@ assign_file_positions_for_load_sections (bfd *abfd, if (phdrs == NULL) return FALSE; + maxpagesize = 1; + if ((abfd->flags & D_PAGED) != 0) + maxpagesize = bed->maxpagesize; + off = bed->s->sizeof_ehdr; 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_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 && m->count > 0) { @@ -4244,8 +4282,8 @@ assign_file_positions_for_load_sections (bfd *abfd, } align = (bfd_size_type) 1 << align_power; - if ((abfd->flags & D_PAGED) != 0 && bed->maxpagesize > align) - align = bed->maxpagesize; + if (align < maxpagesize) + align = maxpagesize; adjust = vma_page_aligned_bias (m->sections[0]->vma, off, align); off += adjust; @@ -4286,26 +4324,6 @@ assign_file_positions_for_load_sections (bfd *abfd, 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_filesz = 0; p->p_memsz = 0; @@ -4386,7 +4404,7 @@ assign_file_positions_for_load_sections (bfd *abfd, sec = *secpp; 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 || 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 modulo the page size. */ bfd_size_type page = align; - if ((abfd->flags & D_PAGED) != 0 && bed->maxpagesize > page) - page = bed->maxpagesize; + if (page < maxpagesize) + page = maxpagesize; adjust = vma_page_aligned_bias (sec->vma, p->p_vaddr + p->p_memsz, page); @@ -4494,8 +4512,7 @@ assign_file_positions_for_load_sections (bfd *abfd, if (align > p->p_align && (p->p_type != PT_LOAD - || (abfd->flags & D_PAGED) == 0 - || ((p->p_vaddr - p->p_offset) & (align - 1)) == 0)) + || (abfd->flags & D_PAGED) == 0)) p->p_align = align; } @@ -5800,6 +5817,8 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd) 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. */ diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog index f88b413..fb3476c 100644 --- a/include/elf/ChangeLog +++ b/include/elf/ChangeLog @@ -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> Randolph Chung <randolph@tausq.org> * hppa.h (R_PARISC_TLS_GD21L, R_PARISC_TLS_GD14R, R_PARISC_TLS_GDCALL, diff --git a/include/elf/internal.h b/include/elf/internal.h index e4eba7d..ff27c88 100644 --- a/include/elf/internal.h +++ b/include/elf/internal.h @@ -1,6 +1,6 @@ /* ELF support for BFD. 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 in "UNIX System V Release 4, Programmers Guide: ANSI C and @@ -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, 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. */ unsigned int includes_filehdr : 1; /* Whether this segment includes the program headers. */ |