From e0c3dfa2eebcf862d45b05f363a81f57ca30dead Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Fri, 5 Oct 2018 23:35:01 +0930 Subject: [PATCH] SPU overlay headers Overlay PT_LOAD headers are moved early for reasons explained by comments in spu_elf_modify_segment_map. This patch fixes cases that shouldn't occur in sane SPU executables. * elf32-spu.c (spu_elf_modify_segment_map): Don't insert overlays before segment containing headers. --- bfd/ChangeLog | 5 +++++ bfd/elf32-spu.c | 38 +++++++++++++++++++++++++++----------- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 4e5eac1029b..1b51db7e7eb 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2018-10-08 Alan Modra + + * elf32-spu.c (spu_elf_modify_segment_map): Don't insert + overlays before segment containing headers. + 2018-10-08 Alan Modra * elf.c (make_mapping): Cope with zero size array at end of diff --git a/bfd/elf32-spu.c b/bfd/elf32-spu.c index bb3264f2361..033db9ca994 100644 --- a/bfd/elf32-spu.c +++ b/bfd/elf32-spu.c @@ -5231,7 +5231,7 @@ spu_elf_modify_segment_map (bfd *abfd, struct bfd_link_info *info) { asection *toe, *s; struct elf_segment_map *m, *m_overlay; - struct elf_segment_map **p, **p_overlay; + struct elf_segment_map **p, **p_overlay, **first_load; unsigned int i; if (info == NULL) @@ -5290,24 +5290,40 @@ spu_elf_modify_segment_map (bfd *abfd, struct bfd_link_info *info) /* Move all overlay segments onto a separate list. */ p = &elf_seg_map (abfd); p_overlay = &m_overlay; + m_overlay = NULL; + first_load = NULL; while (*p != NULL) { - if ((*p)->p_type == PT_LOAD && (*p)->count == 1 - && spu_elf_section_data ((*p)->sections[0])->u.o.ovl_index != 0) + if ((*p)->p_type == PT_LOAD) { - m = *p; - *p = m->next; - *p_overlay = m; - p_overlay = &m->next; - continue; + if (!first_load) + first_load = p; + if ((*p)->count == 1 + && spu_elf_section_data ((*p)->sections[0])->u.o.ovl_index != 0) + { + m = *p; + *p = m->next; + *p_overlay = m; + p_overlay = &m->next; + continue; + } } - p = &((*p)->next); } /* Re-insert overlay segments at the head of the segment map. */ - *p_overlay = elf_seg_map (abfd); - elf_seg_map (abfd) = m_overlay; + if (m_overlay != NULL) + { + p = first_load; + if (*p != NULL && (*p)->p_type == PT_LOAD && (*p)->includes_filehdr) + /* It doesn't really make sense for someone to include the ELF + file header into an spu image, but if they do the code that + assigns p_offset needs to see the segment containing the + header first. */ + p = &(*p)->next; + *p_overlay = *p; + *p = m_overlay; + } return TRUE; } -- 2.30.2