summaryrefslogtreecommitdiffstats
path: root/bfd/elf32-spu.c
diff options
context:
space:
mode:
authorUlrich Weigand <uweigand@de.ibm.com>2009-05-14 15:26:36 +0000
committerUlrich Weigand <uweigand@de.ibm.com>2009-05-14 15:26:36 +0000
commit452de53c120bef76efb636cc404b23d4170907c8 (patch)
treefd55e9c67c3ba06ffe3a2babdfac9f2cec85474d /bfd/elf32-spu.c
parentd342a8b15740545c4584db1957abaf12040ba646 (diff)
downloadppe42-binutils-452de53c120bef76efb636cc404b23d4170907c8.tar.gz
ppe42-binutils-452de53c120bef76efb636cc404b23d4170907c8.zip
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.
Diffstat (limited to 'bfd/elf32-spu.c')
-rw-r--r--bfd/elf32-spu.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/bfd/elf32-spu.c b/bfd/elf32-spu.c
index 838f6fc44e..0443e5e7d9 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;
}
OpenPOWER on IntegriCloud