From 3271a81418b2396c04dc040163a579cddcd23e2e Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Tue, 19 Dec 2006 08:49:38 +0000 Subject: [PATCH] bfd/ * elf.c (assign_file_positions_for_load_sections): Adjust p_vaddr by p_vaddr_offset. Copy alignment & use if it is valid. (rewrite_elf_program_headers): Cope with leading padding in a segment that does not contain file or program headers. (copy_elf_program_header): Likewise. include/elf/ * internal.h (struct elf_segment_map): Add p_vaddr_offset field. --- bfd/ChangeLog | 9 ++++++++ bfd/elf.c | 50 +++++++++++++++++++++++++++++++----------- include/elf/ChangeLog | 4 ++++ include/elf/internal.h | 2 ++ 4 files changed, 52 insertions(+), 13 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 61e028148b8..d350378b590 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2006-12-19 Nathan Sidwell + + * elf.c (assign_file_positions_for_load_sections): Adjust p_vaddr + by p_vaddr_offset. Copy alignment & use if it is valid. + (rewrite_elf_program_headers): Cope with leading padding in a + segment that does not contain file or program headers. + (copy_elf_program_header): Likewise. + 2006-12-15 Mark Kettenis * config.bfd: (sh*-*-openbsd*): Add target. @@ -57,6 +65,7 @@ * elf64-alpha.c (elf64_alpha_merge_symbol_attribute): New function. (elf_backend_merge_symbol_attribute): Define. +>>>>>>> 1.3701 2006-12-04 Jan Beulich * elflink.c (_bfd_elf_link_create_dynamic_sections): Don't create diff --git a/bfd/elf.c b/bfd/elf.c index 943db786bbc..c8fcbb560cb 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -4326,7 +4326,7 @@ assign_file_positions_for_load_sections (bfd *abfd, if (m->count == 0) p->p_vaddr = 0; else - p->p_vaddr = m->sections[0]->vma; + p->p_vaddr = m->sections[0]->vma - m->p_vaddr_offset; if (m->p_paddr_valid) p->p_paddr = m->p_paddr; @@ -4353,6 +4353,8 @@ assign_file_positions_for_load_sections (bfd *abfd, } else if (m->count == 0) p->p_align = 1 << bed->s->log_file_align; + else if (m->p_align_valid) + p->p_align = m->p_align; else p->p_align = 0; @@ -4363,18 +4365,22 @@ assign_file_positions_for_load_sections (bfd *abfd, bfd_vma adjust; unsigned int align_power = 0; - for (i = 0, secpp = m->sections; i < m->count; i++, secpp++) + if (m->p_align_valid) + align = p->p_align; + else { - unsigned int secalign; - - secalign = bfd_get_section_alignment (abfd, *secpp); - if (secalign > align_power) - align_power = secalign; + for (i = 0, secpp = m->sections; i < m->count; i++, secpp++) + { + unsigned int secalign; + + secalign = bfd_get_section_alignment (abfd, *secpp); + if (secalign > align_power) + align_power = secalign; + } + align = (bfd_size_type) 1 << align_power; + if (align < maxpagesize) + align = maxpagesize; } - align = (bfd_size_type) 1 << align_power; - - if (align < maxpagesize) - align = maxpagesize; adjust = vma_page_aligned_bias (m->sections[0]->vma, off, align); off += adjust; @@ -4605,6 +4611,7 @@ assign_file_positions_for_load_sections (bfd *abfd, if (p->p_type == PT_GNU_RELRO) p->p_align = 1; else if (align > p->p_align + && !m->p_align_valid && (p->p_type != PT_LOAD || (abfd->flags & D_PAGED) == 0)) p->p_align = align; @@ -5581,7 +5588,14 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd) map->count = section_count; *pointer_to_map = map; pointer_to_map = &map->next; - + + if (matching_lma != map->p_paddr + && !map->includes_filehdr && !map->includes_phdrs) + /* There is some padding before the first section in the + segment. So, we must account for that in the output + segment's vma. */ + map->p_vaddr_offset = matching_lma - map->p_paddr; + free (sections); continue; } @@ -5800,6 +5814,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd) unsigned int section_count; bfd_size_type amt; Elf_Internal_Shdr *this_hdr; + bfd_vma first_lma = 0; /* FIXME: Do we need to copy PT_NULL segment? */ if (segment->p_type == PT_NULL) @@ -5812,7 +5827,11 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd) { this_hdr = &(elf_section_data(section)->this_hdr); if (ELF_IS_SECTION_IN_SEGMENT_FILE (this_hdr, segment)) - section_count++; + { + if (!section_count || section->lma < first_lma) + first_lma = section->lma; + section_count++; + } } /* Allocate a segment map big enough to contain @@ -5834,6 +5853,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd) map->p_paddr_valid = 1; map->p_align = segment->p_align; map->p_align_valid = 1; + map->p_vaddr_offset = 0; /* Determine if this segment contains the ELF file header and if it contains the program headers themselves. */ @@ -5853,6 +5873,10 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd) phdr_included = TRUE; } + if (!map->includes_phdrs && !map->includes_filehdr) + /* There is some other padding before the first section. */ + map->p_vaddr_offset = first_lma - segment->p_paddr; + if (section_count != 0) { unsigned int isec = 0; diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog index 6481c7bc6ad..0c857ae0c6c 100644 --- a/include/elf/ChangeLog +++ b/include/elf/ChangeLog @@ -1,3 +1,7 @@ +2006-12-19 Nathan Sidwell + + * internal.h (struct elf_segment_map): Add p_vaddr_offset field. + 2006-12-07 Kazu Hirata * m68k.h (EF_M68K_ISA_MASK, EF_M68K_ISA_A_NODIV, diff --git a/include/elf/internal.h b/include/elf/internal.h index d368a3fa6e7..f2161ff9d8e 100644 --- a/include/elf/internal.h +++ b/include/elf/internal.h @@ -235,6 +235,8 @@ struct elf_segment_map unsigned long p_flags; /* Program segment physical address. */ bfd_vma p_paddr; + /* Program segment virtual address offset from section vma. */ + bfd_vma p_vaddr_offset; /* Program segment alignment. */ bfd_vma p_align; /* Whether the p_flags field is valid; if not, the flags are based -- 2.30.2