From 9a83a5533e5c082e2555505e7290456e4eb6afcb Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Sat, 24 Apr 2010 01:05:25 +0000 Subject: [PATCH] include/elf/ * internal.h (ELF_SECTION_SIZE): Protect macro args with parentheses. Invert logic to clarify test for .tbss. (ELF_IS_SECTION_IN_SEGMENT): Rename to.. (ELF_SECTION_IN_SEGMENT_1): ..this. Add check_vma param. Protect macro args with parentheses. (ELF_SECTION_IN_SEGMENT): Define. (ELF_IS_SECTION_IN_SEGMENT_FILE): Delete. (ELF_IS_SECTION_IN_SEGMENT_MEMORY): Delete. bfd/ * elf.c: Replace use of ELF_IS_SECTION_IN_SEGMENT and ELF_IS_SECTION_IN_SEGMENT_FILE with ELF_SECTION_IN_SEGMENT throughout file. (assign_file_positions_for_load_sections): Modify section in segment warning to ignore overlay vmas. * elf32-spu.c (spu_elf_object_p): Replace use of ELF_IS_SECTION_IN_SEGMENT_MEMORY with ELF_SECTION_IN_SEGMENT. binutils/ * readelf.c (process_program_headers): Replace use of ELF_IS_SECTION_IN_SEGMENT_MEMORY with ELF_SECTION_IN_SEGMENT. --- bfd/ChangeLog | 10 ++++++++ bfd/elf.c | 55 ++++++++++++++++++++++++++++-------------- bfd/elf32-spu.c | 3 ++- binutils/ChangeLog | 5 ++++ binutils/readelf.c | 3 ++- include/elf/ChangeLog | 11 +++++++++ include/elf/internal.h | 52 ++++++++++++++++++--------------------- 7 files changed, 90 insertions(+), 49 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index c8d6b3cf7f6..89ecc400c6b 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2010-04-23 Alan Modra + + * elf.c: Replace use of ELF_IS_SECTION_IN_SEGMENT and + ELF_IS_SECTION_IN_SEGMENT_FILE with ELF_SECTION_IN_SEGMENT + throughout file. + (assign_file_positions_for_load_sections): Modify section in + segment warning to ignore overlay vmas. + * elf32-spu.c (spu_elf_object_p): Replace use of + ELF_IS_SECTION_IN_SEGMENT_MEMORY with ELF_SECTION_IN_SEGMENT. + 2010-04-22 Nick Clifton * po/bfd.pot: Updated by the Translation project. diff --git a/bfd/elf.c b/bfd/elf.c index 0ffc2d08895..a5a24c52997 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -978,7 +978,7 @@ _bfd_elf_make_section_from_shdr (bfd *abfd, for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++) { if (phdr->p_type == PT_LOAD - && ELF_IS_SECTION_IN_SEGMENT (hdr, phdr)) + && ELF_SECTION_IN_SEGMENT (hdr, phdr)) { if ((flags & SEC_LOAD) == 0) newsect->lma = (phdr->p_paddr @@ -4552,22 +4552,38 @@ assign_file_positions_for_load_sections (bfd *abfd, /* Check that all sections are in a PT_LOAD segment. Don't check funky gdb generated core files. */ if (p->p_type == PT_LOAD && bfd_get_format (abfd) != bfd_core) - for (i = 0, secpp = m->sections; i < m->count; i++, secpp++) - { - Elf_Internal_Shdr *this_hdr; - asection *sec; - - sec = *secpp; - this_hdr = &(elf_section_data(sec)->this_hdr); - if (this_hdr->sh_size != 0 - && !ELF_IS_SECTION_IN_SEGMENT_FILE (this_hdr, p)) + { + bfd_boolean check_vma = TRUE; + + for (i = 1; i < m->count; i++) + if (m->sections[i]->vma == m->sections[i - 1]->vma + && ELF_SECTION_SIZE (&(elf_section_data (m->sections[i]) + ->this_hdr), p) != 0 + && ELF_SECTION_SIZE (&(elf_section_data (m->sections[i - 1]) + ->this_hdr), p) != 0) { - (*_bfd_error_handler) - (_("%B: section `%A' can't be allocated in segment %d"), - abfd, sec, j); - print_segment_map (m); + /* Looks like we have overlays packed into the segment. */ + check_vma = FALSE; + break; } - } + + for (i = 0; i < m->count; i++) + { + Elf_Internal_Shdr *this_hdr; + asection *sec; + + 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)) + { + (*_bfd_error_handler) + (_("%B: section `%A' can't be allocated in segment %d"), + abfd, sec, j); + print_segment_map (m); + } + } + } } elf_tdata (abfd)->next_file_pos = off; @@ -5837,7 +5853,8 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd) section = section->next) { this_hdr = &(elf_section_data(section)->this_hdr); - if (ELF_IS_SECTION_IN_SEGMENT_FILE (this_hdr, segment)) + if (this_hdr->sh_size != 0 + && ELF_SECTION_IN_SEGMENT (this_hdr, segment)) { if (!first_section) first_section = lowest_section = section; @@ -5916,7 +5933,8 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd) section = section->next) { this_hdr = &(elf_section_data(section)->this_hdr); - if (ELF_IS_SECTION_IN_SEGMENT_FILE (this_hdr, segment)) + if (this_hdr->sh_size != 0 + && ELF_SECTION_IN_SEGMENT (this_hdr, segment)) { map->sections[isec++] = section->output_section; if (isec == section_count) @@ -5993,7 +6011,8 @@ 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 (ELF_IS_SECTION_IN_SEGMENT_FILE (this_hdr, segment)) + if (this_hdr->sh_size != 0 + && 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/bfd/elf32-spu.c b/bfd/elf32-spu.c index b29b35c2430..bf1adba1447 100644 --- a/bfd/elf32-spu.c +++ b/bfd/elf32-spu.c @@ -272,7 +272,8 @@ spu_elf_object_p (bfd *abfd) { Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[j]; - if (ELF_IS_SECTION_IN_SEGMENT_MEMORY (shdr, phdr)) + if (ELF_SECTION_SIZE (shdr, phdr) != 0 + && ELF_SECTION_IN_SEGMENT (shdr, phdr)) { asection *sec = shdr->bfd_section; spu_elf_section_data (sec)->u.o.ovl_index = num_ovl; diff --git a/binutils/ChangeLog b/binutils/ChangeLog index b5a36f693ef..734e22019ee 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,8 @@ +2010-04-23 Alan Modra + + * readelf.c (process_program_headers): Replace use of + ELF_IS_SECTION_IN_SEGMENT_MEMORY with ELF_SECTION_IN_SEGMENT. + 2010-04-22 Nick Clifton * po/binutils.pot: Updated by the Translation project. diff --git a/binutils/readelf.c b/binutils/readelf.c index 2c66211669c..6e368c55080 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -3850,7 +3850,8 @@ process_program_headers (FILE * file) for (j = 1; j < elf_header.e_shnum; j++, section++) { - if (ELF_IS_SECTION_IN_SEGMENT_MEMORY (section, segment)) + if (ELF_SECTION_SIZE (section, segment) != 0 + && ELF_SECTION_IN_SEGMENT (section, segment)) printf ("%s ", SECTION_NAME (section)); } diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog index 49be1e16b13..b65c881d25f 100644 --- a/include/elf/ChangeLog +++ b/include/elf/ChangeLog @@ -1,3 +1,14 @@ +2010-04-23 Alan Modra + + * internal.h (ELF_SECTION_SIZE): Protect macro args with parentheses. + Invert logic to clarify test for .tbss. + (ELF_IS_SECTION_IN_SEGMENT): Rename to.. + (ELF_SECTION_IN_SEGMENT_1): ..this. Add check_vma param. Protect + macro args with parentheses. + (ELF_SECTION_IN_SEGMENT): Define. + (ELF_IS_SECTION_IN_SEGMENT_FILE): Delete. + (ELF_IS_SECTION_IN_SEGMENT_MEMORY): Delete. + 2010-04-15 Matthew Gretton-Dann * arm.h (Tag_FP_arch, Tag_ABI_align_needed, Tag_ABI_align_preserved, diff --git a/include/elf/internal.h b/include/elf/internal.h index 06e726675ce..1dd336dd6da 100644 --- a/include/elf/internal.h +++ b/include/elf/internal.h @@ -292,42 +292,36 @@ 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_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) + ((!(((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_IS_SECTION_IN_SEGMENT(sec_hdr, segment) \ - (((((sec_hdr->sh_flags & SHF_TLS) != 0) \ - && (segment->p_type == PT_TLS \ - || segment->p_type == PT_GNU_RELRO \ - || segment->p_type == PT_LOAD)) \ - || ((sec_hdr->sh_flags & SHF_TLS) == 0 \ - && segment->p_type != PT_TLS \ - && segment->p_type != PT_PHDR)) \ +#define ELF_SECTION_IN_SEGMENT_1(sec_hdr, segment, check_vma) \ + ((((((sec_hdr)->sh_flags & SHF_TLS) != 0) \ + && ((segment)->p_type == PT_TLS \ + || (segment)->p_type == PT_GNU_RELRO \ + || (segment)->p_type == PT_LOAD)) \ + || (((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. */ \ - && (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))) \ + && ((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. */ \ - && ((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)))) - -/* Decide if the given sec_hdr is in the given segment in file. */ -#define ELF_IS_SECTION_IN_SEGMENT_FILE(sec_hdr, segment) \ - (sec_hdr->sh_size > 0 \ - && ELF_IS_SECTION_IN_SEGMENT (sec_hdr, segment)) - -/* Decide if the given sec_hdr is in the given segment in memory. */ -#define ELF_IS_SECTION_IN_SEGMENT_MEMORY(sec_hdr, segment) \ - (ELF_SECTION_SIZE(sec_hdr, segment) > 0 \ - && ELF_IS_SECTION_IN_SEGMENT (sec_hdr, 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)))) + +#define ELF_SECTION_IN_SEGMENT(sec_hdr, segment) \ + (ELF_SECTION_IN_SEGMENT_1 (sec_hdr, segment, 1)) #endif /* _ELF_INTERNAL_H */ -- 2.30.2