From f4638467331c33e2f9dd00c12c175a9eb47351c8 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Tue, 20 Jul 2010 14:08:32 +0000 Subject: [PATCH] include/elf/ * internal.h (ELF_TBSS_SPECIAL): New macro, extracted from.. (ELF_SECTION_SIZE): ..here. (ELF_SECTION_IN_SEGMENT_1): Add "strict" arg. (ELF_SECTION_IN_SEGMENT_STRICT): New macro. bfd/ * elf.c (assign_file_positions_for_load_sections): Check that zero size sections are allocated in segments too. (assign_file_positions_for_non_load_sections): Warn if zero size alloc sections are found here. (copy_elf_program_header): Don't drop zero size sections from segment map. (copy_private_bfd_data): Check for changes in zero size sections. binutils/ * readelf.c (process_program_headers): Don't ignore all zero size sections. ld/testsuite/ * ld-powerpc/tlsexe.r: Update. * ld-powerpc/tlsexetoc.r: Update. * ld-powerpc/tlsso.r: Update. * ld-powerpc/tlstocso.r: Update. --- bfd/ChangeLog | 10 +++++++ bfd/elf.c | 25 +++++++---------- binutils/ChangeLog | 5 ++++ binutils/readelf.c | 4 +-- include/elf/ChangeLog | 7 +++++ include/elf/internal.h | 54 ++++++++++++++++++++++++------------- ld/testsuite/ChangeLog | 7 +++++ ld/testsuite/ld-powerpc/tlsexe.r | 2 +- ld/testsuite/ld-powerpc/tlsexetoc.r | 2 +- ld/testsuite/ld-powerpc/tlsso.r | 2 +- ld/testsuite/ld-powerpc/tlstocso.r | 2 +- 11 files changed, 81 insertions(+), 39 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index a6dd0d8..aa36284 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2010-07-20 Alan Modra + + * elf.c (assign_file_positions_for_load_sections): Check that + zero size sections are allocated in segments too. + (assign_file_positions_for_non_load_sections): Warn if zero + size alloc sections are found here. + (copy_elf_program_header): Don't drop zero size sections from + segment map. + (copy_private_bfd_data): Check for changes in zero size sections. + 2010-07-17 Alan Modra * elf.c (_bfd_elf_map_sections_to_segments): Force new segment diff --git a/bfd/elf.c b/bfd/elf.c index 63f0260..e7651ba 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -4589,8 +4589,7 @@ assign_file_positions_for_load_sections (bfd *abfd, sec = m->sections[i]; this_hdr = &(elf_section_data(sec)->this_hdr); - if (this_hdr->sh_size != 0 - && !ELF_SECTION_IN_SEGMENT_1 (this_hdr, p, check_vma)) + if (!ELF_SECTION_IN_SEGMENT_1 (this_hdr, p, check_vma, 0)) { (*_bfd_error_handler) (_("%B: section `%A' can't be allocated in segment %d"), @@ -4640,13 +4639,12 @@ assign_file_positions_for_non_load_sections (bfd *abfd, BFD_ASSERT (hdr->sh_offset == hdr->bfd_section->filepos); else if ((hdr->sh_flags & SHF_ALLOC) != 0) { - if (hdr->sh_size != 0) - ((*_bfd_error_handler) - (_("%B: warning: allocated section `%s' not in segment"), - abfd, - (hdr->bfd_section == NULL - ? "*unknown*" - : hdr->bfd_section->name))); + (*_bfd_error_handler) + (_("%B: warning: allocated section `%s' not in segment"), + abfd, + (hdr->bfd_section == NULL + ? "*unknown*" + : hdr->bfd_section->name)); /* We don't need to page align empty sections. */ if ((abfd->flags & D_PAGED) != 0 && hdr->sh_size != 0) off += vma_page_aligned_bias (hdr->sh_addr, off, @@ -5868,8 +5866,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd) section = section->next) { this_hdr = &(elf_section_data(section)->this_hdr); - if (this_hdr->sh_size != 0 - && ELF_SECTION_IN_SEGMENT (this_hdr, segment)) + if (ELF_SECTION_IN_SEGMENT (this_hdr, segment)) { if (!first_section) first_section = lowest_section = section; @@ -5948,8 +5945,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd) section = section->next) { this_hdr = &(elf_section_data(section)->this_hdr); - if (this_hdr->sh_size != 0 - && ELF_SECTION_IN_SEGMENT (this_hdr, segment)) + if (ELF_SECTION_IN_SEGMENT (this_hdr, segment)) { map->sections[isec++] = section->output_section; if (isec == section_count) @@ -6026,8 +6022,7 @@ copy_private_bfd_data (bfd *ibfd, bfd *obfd) /* Check if this section is covered by the segment. */ this_hdr = &(elf_section_data(section)->this_hdr); - if (this_hdr->sh_size != 0 - && ELF_SECTION_IN_SEGMENT (this_hdr, segment)) + if (ELF_SECTION_IN_SEGMENT (this_hdr, segment)) { /* FIXME: Check if its output section is changed or removed. What else do we need to check? */ diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 18c06c5..8e3ecb6 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,8 @@ +2010-07-20 Alan Modra + + * readelf.c (process_program_headers): Don't ignore all zero size + sections. + 2010-07-19 Andreas Schwab * readelf.c (process_section_headers): Update key to flags. diff --git a/binutils/readelf.c b/binutils/readelf.c index 883c482..447932c 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -3889,8 +3889,8 @@ process_program_headers (FILE * file) for (j = 1; j < elf_header.e_shnum; j++, section++) { - if (ELF_SECTION_SIZE (section, segment) != 0 - && ELF_SECTION_IN_SEGMENT (section, segment)) + if (!ELF_TBSS_SPECIAL (section, segment) + && ELF_SECTION_IN_SEGMENT_STRICT (section, segment)) printf ("%s ", SECTION_NAME (section)); } diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog index 8a8e118..edd9b48 100644 --- a/include/elf/ChangeLog +++ b/include/elf/ChangeLog @@ -1,3 +1,10 @@ +2010-07-20 Alan Modra + + * internal.h (ELF_TBSS_SPECIAL): New macro, extracted from.. + (ELF_SECTION_SIZE): ..here. + (ELF_SECTION_IN_SEGMENT_1): Add "strict" arg. + (ELF_SECTION_IN_SEGMENT_STRICT): New macro. + 2010-06-25 Alan Modra * ppc64.h (R_PPC64_LO_DS_OPT): Define. diff --git a/include/elf/internal.h b/include/elf/internal.h index 1dd336d..6998ae0 100644 --- a/include/elf/internal.h +++ b/include/elf/internal.h @@ -291,37 +291,55 @@ struct elf_segment_map /* .tbss is special. It doesn't contribute memory space to normal segments and it doesn't take file space in normal segments. */ +#define ELF_TBSS_SPECIAL(sec_hdr, segment) \ + (((sec_hdr)->sh_flags & SHF_TLS) != 0 \ + && (sec_hdr)->sh_type == SHT_NOBITS \ + && (segment)->p_type != PT_TLS) + #define ELF_SECTION_SIZE(sec_hdr, segment) \ - ((!(((sec_hdr)->sh_flags & SHF_TLS) != 0 \ - && (sec_hdr)->sh_type == SHT_NOBITS) \ - || (segment)->p_type == PT_TLS) ? (sec_hdr)->sh_size : 0) - -/* Decide if the given sec_hdr is in the given segment. PT_TLS segment - contains only SHF_TLS sections. Only PT_LOAD, PT_GNU_RELRO and - and PT_TLS segments can contain SHF_TLS sections. */ -#define ELF_SECTION_IN_SEGMENT_1(sec_hdr, segment, check_vma) \ - ((((((sec_hdr)->sh_flags & SHF_TLS) != 0) \ + (ELF_TBSS_SPECIAL(sec_hdr, segment) ? 0 : (sec_hdr)->sh_size) + +/* Decide if the section SEC_HDR is in SEGMENT. If CHECK_VMA, then + VMAs are checked for alloc sections. If STRICT, then a zero size + section won't match at the end of a segment, unless the segment + is also zero size. */ +#define ELF_SECTION_IN_SEGMENT_1(sec_hdr, segment, check_vma, strict) \ + ((/* Only PT_LOAD, PT_GNU_RELRO and PT_TLS segments can contain \ + SHF_TLS sections. */ \ + ((((sec_hdr)->sh_flags & SHF_TLS) != 0) \ && ((segment)->p_type == PT_TLS \ || (segment)->p_type == PT_GNU_RELRO \ || (segment)->p_type == PT_LOAD)) \ + /* PT_TLS segment contains only SHF_TLS sections, PT_PHDR no \ + sections at all. */ \ || (((sec_hdr)->sh_flags & SHF_TLS) == 0 \ && (segment)->p_type != PT_TLS \ && (segment)->p_type != PT_PHDR)) \ - /* Any section besides one of type SHT_NOBITS must have a file \ - offset within the segment. */ \ + /* Any section besides one of type SHT_NOBITS must have file \ + offsets within the segment. */ \ && ((sec_hdr)->sh_type == SHT_NOBITS \ || ((bfd_vma) (sec_hdr)->sh_offset >= (segment)->p_offset \ - && ((sec_hdr)->sh_offset + ELF_SECTION_SIZE(sec_hdr, segment) \ - <= (segment)->p_offset + (segment)->p_filesz))) \ - /* SHF_ALLOC sections must have VMAs within the segment. Be \ - careful about segments right at the end of memory. */ \ + && (!(strict) \ + || ((sec_hdr)->sh_offset - (segment)->p_offset \ + <= (segment)->p_filesz - 1)) \ + && (((sec_hdr)->sh_offset - (segment)->p_offset \ + + ELF_SECTION_SIZE(sec_hdr, segment)) \ + <= (segment)->p_filesz))) \ + /* SHF_ALLOC sections must have VMAs within the segment. */ \ && (!(check_vma) \ || ((sec_hdr)->sh_flags & SHF_ALLOC) == 0 \ || ((sec_hdr)->sh_addr >= (segment)->p_vaddr \ - && ((sec_hdr)->sh_addr - (segment)->p_vaddr \ - + ELF_SECTION_SIZE(sec_hdr, segment) <= (segment)->p_memsz)))) + && (!(strict) \ + || ((sec_hdr)->sh_addr - (segment)->p_vaddr \ + <= (segment)->p_memsz - 1)) \ + && (((sec_hdr)->sh_addr - (segment)->p_vaddr \ + + ELF_SECTION_SIZE(sec_hdr, segment)) \ + <= (segment)->p_memsz)))) #define ELF_SECTION_IN_SEGMENT(sec_hdr, segment) \ - (ELF_SECTION_IN_SEGMENT_1 (sec_hdr, segment, 1)) + (ELF_SECTION_IN_SEGMENT_1 (sec_hdr, segment, 1, 0)) + +#define ELF_SECTION_IN_SEGMENT_STRICT(sec_hdr, segment) \ + (ELF_SECTION_IN_SEGMENT_1 (sec_hdr, segment, 1, 1)) #endif /* _ELF_INTERNAL_H */ diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 4691310..6ec6d55 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,5 +1,12 @@ 2010-07-20 Alan Modra + * ld-powerpc/tlsexe.r: Update. + * ld-powerpc/tlsexetoc.r: Update. + * ld-powerpc/tlsso.r: Update. + * ld-powerpc/tlstocso.r: Update. + +2010-07-20 Alan Modra + * ld-powerpc/vxworks-relax.s: Add branches to match expected output. * ld-powerpc/vxworks-relax-2.s: Likewise. * ld-powerpc/vxworks1-lib.rd: Reorder reloc sections. diff --git a/ld/testsuite/ld-powerpc/tlsexe.r b/ld/testsuite/ld-powerpc/tlsexe.r index db43d87..68b36bb 100644 --- a/ld/testsuite/ld-powerpc/tlsexe.r +++ b/ld/testsuite/ld-powerpc/tlsexe.r @@ -47,7 +47,7 @@ Program Headers: +0+ + +01 +\.interp +02 +\.interp \.hash \.dynsym \.dynstr \.rela\.dyn \.rela\.plt \.text - +03 +\.tdata \.dynamic \.got \.plt + +03 +\.tdata \.dynamic (\.branch_lt |)\.got \.plt +04 +\.dynamic +05 +\.tdata \.tbss diff --git a/ld/testsuite/ld-powerpc/tlsexetoc.r b/ld/testsuite/ld-powerpc/tlsexetoc.r index 82426ac..8ba8503 100644 --- a/ld/testsuite/ld-powerpc/tlsexetoc.r +++ b/ld/testsuite/ld-powerpc/tlsexetoc.r @@ -47,7 +47,7 @@ Program Headers: +0+ + +01 +\.interp +02 +\.interp \.hash \.dynsym \.dynstr \.rela\.dyn \.rela\.plt \.text - +03 +\.tdata \.dynamic \.got \.plt + +03 +\.tdata \.dynamic (\.branch_lt |)\.got \.plt +04 +\.dynamic +05 +\.tdata \.tbss diff --git a/ld/testsuite/ld-powerpc/tlsso.r b/ld/testsuite/ld-powerpc/tlsso.r index fa792f3..99c3659 100644 --- a/ld/testsuite/ld-powerpc/tlsso.r +++ b/ld/testsuite/ld-powerpc/tlsso.r @@ -40,7 +40,7 @@ Program Headers: Section to Segment mapping: +Segment Sections\.\.\. +0+ +\.hash \.dynsym \.dynstr \.rela\.dyn \.rela\.plt \.text - +01 +\.tdata \.dynamic \.got \.plt + +01 +\.tdata \.dynamic (\.branch_lt |)\.got \.plt +02 +\.dynamic +03 +\.tdata \.tbss diff --git a/ld/testsuite/ld-powerpc/tlstocso.r b/ld/testsuite/ld-powerpc/tlstocso.r index 21ddeee..d04cf70 100644 --- a/ld/testsuite/ld-powerpc/tlstocso.r +++ b/ld/testsuite/ld-powerpc/tlstocso.r @@ -40,7 +40,7 @@ Program Headers: Section to Segment mapping: +Segment Sections\.\.\. +0+ +\.hash \.dynsym \.dynstr \.rela\.dyn \.rela\.plt \.text - +01 +\.tdata \.dynamic \.got \.plt + +01 +\.tdata \.dynamic (\.branch_lt |)\.got \.plt +02 +\.dynamic +03 +\.tdata \.tbss -- 2.7.4