* 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.
+2010-04-23  Alan Modra  <amodra@gmail.com>
+
+       * 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  <nickc@redhat.com>
 
        * po/bfd.pot: Updated by the Translation project.
 
       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
       /* 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;
           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;
               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)
 
              /* 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?  */
 
              {
                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;
 
+2010-04-23  Alan Modra  <amodra@gmail.com>
+
+       * readelf.c (process_program_headers): Replace use of
+       ELF_IS_SECTION_IN_SEGMENT_MEMORY with ELF_SECTION_IN_SEGMENT.
+
 2010-04-22  Nick Clifton  <nickc@redhat.com>
 
        * po/binutils.pot: Updated by the Translation project.
 
 
          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));
            }
 
 
+2010-04-23  Alan Modra  <amodra@gmail.com>
+
+       * 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  <matthew.gretton-dann@arm.com>
 
        * arm.h (Tag_FP_arch, Tag_ABI_align_needed, Tag_ABI_align_preserved,
 
 /* .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 */