From 452de53c120bef76efb636cc404b23d4170907c8 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Thu, 14 May 2009 15:26:36 +0000 Subject: bfd/ * elf32-spu.c (spu_elf_modify_segment_map): Move all PF_OVERLAY segments first amongst the program headers. ld/testsuite/ * ld-spu/icache.d: Update file offsets. * ld-spu/ovl.d: Likewise. * ld-spu/ovl1.d: Likewise. --- bfd/elf32-spu.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) (limited to 'bfd/elf32-spu.c') diff --git a/bfd/elf32-spu.c b/bfd/elf32-spu.c index 838f6fc..0443e5e 100644 --- a/bfd/elf32-spu.c +++ b/bfd/elf32-spu.c @@ -5045,7 +5045,8 @@ static bfd_boolean spu_elf_modify_segment_map (bfd *abfd, struct bfd_link_info *info) { asection *toe, *s; - struct elf_segment_map *m; + struct elf_segment_map *m, *m_overlay; + struct elf_segment_map **p, **p_overlay; unsigned int i; if (info == NULL) @@ -5092,6 +5093,37 @@ spu_elf_modify_segment_map (bfd *abfd, struct bfd_link_info *info) break; } + + /* Some SPU ELF loaders ignore the PF_OVERLAY flag and just load all + PT_LOAD segments. This can cause the .ovl.init section to be + overwritten with the contents of some overlay segment. To work + around this issue, we ensure that all PF_OVERLAY segments are + sorted first amongst the program headers; this ensures that even + with a broken loader, the .ovl.init section (which is not marked + as PF_OVERLAY) will be placed into SPU local store on startup. */ + + /* Move all overlay segments onto a separate list. */ + p = &elf_tdata (abfd)->segment_map; + p_overlay = &m_overlay; + while (*p != NULL) + { + if ((*p)->p_type == PT_LOAD && (*p)->count == 1 + && spu_elf_section_data ((*p)->sections[0])->u.o.ovl_index != 0) + { + struct elf_segment_map *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_tdata (abfd)->segment_map; + elf_tdata (abfd)->segment_map = m_overlay; + return TRUE; } -- cgit v1.1