bfd/
authorUlrich Weigand <uweigand@de.ibm.com>
Thu, 14 May 2009 15:26:36 +0000 (15:26 +0000)
committerUlrich Weigand <uweigand@de.ibm.com>
Thu, 14 May 2009 15:26:36 +0000 (15:26 +0000)
* 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/ChangeLog
bfd/elf32-spu.c
ld/testsuite/ChangeLog
ld/testsuite/ld-spu/icache1.d
ld/testsuite/ld-spu/ovl.d
ld/testsuite/ld-spu/ovl2.d

index edaf9c862e21b8bd6f8d599df98d445677e41a8e..63e22006d24753d3bb08c7627cfa6042424cb843 100644 (file)
@@ -1,3 +1,8 @@
+2009-05-14  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * elf32-spu.c (spu_elf_modify_segment_map): Move all PF_OVERLAY
+       segments first amongst the program headers.
+
 2009-05-14  Ulrich Weigand  <uweigand@de.ibm.com>
 
        * elf32-spu.c (spu_elf_relocate_section): Only encode overlay index
index 838f6fc44e5c4e51504ffd2c5208f98f4c991fff..0443e5e7d9fe108c8e1bceaf2ac9e6a9e82caf6b 100644 (file)
@@ -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;
 }
 
index 766525cde954c373e5fdd1b62984363bc88a9c2a..845a99733e92979ed7df3f200fbbd911be588c37 100644 (file)
@@ -1,3 +1,9 @@
+2009-05-14  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * ld-spu/icache.d: Update file offsets.
+       * ld-spu/ovl.d: Likewise.
+       * ld-spu/ovl1.d: Likewise.
+
 2009-05-14  Alan Modra  <amodra@bigpond.net.au>
 
        * ld-spu/icache1.d: Update for changed overlay manager placement.
index bad3274fb78181d5a2252ab295970dd023fac914..2089294650b8cc507a8b503df79743e90bf45353 100644 (file)
@@ -8,7 +8,7 @@
 Disassembly of section .ovl.init:
 00000800 <__icache_fileoff>:
 .*     00 00 00 00.*
-.*     00 00 07 00.*
+.*     00 00 02 00.*
        \.\.\.
 
 Disassembly of section \.ovly1:
index f33d4140b36ddfd33b6bde309ff09f0867c4979f..cbf7573a642e5208c901b8773ec5ea7e29d9fc5b 100644 (file)
@@ -151,12 +151,12 @@ Disassembly of section .data:
  450:  00 00 04 00 .*
  454:  00 00 00 20 .*
 # 458: 00 00 03 40 .*
- 458:  00 00 03 90 .*
+ 458:  00 00 01 00 .*
  45c:  00 00 00 01 .*
  460:  00 00 04 00 .*
  464:  00 00 00 40 .*
 # 468: 00 00 03 60 .*
- 468:  00 00 03 b0 .*
+ 468:  00 00 01 20 .*
  46c:  00 00 00 01 .*
 
 00000470 <_ovly_buf_table>:
index 6206e4941f505becfa93868e07dfb3a9e2f425e6..b1e344c456a47a0992850cf2ed44a0ee0a0be74d 100644 (file)
@@ -104,12 +104,12 @@ Disassembly of section \.data:
 .*00 00 04 00 .*
 .*00 00 00 20 .*
 #.*00 00 03 10 .*
-.*00 00 03 60 .*
+.*00 00 01 00 .*
 .*00 00 00 01 .*
 .*00 00 04 00 .*
 .*00 00 00 20 .*
 #.*00 00 03 20 .*
-.*00 00 03 80 .*
+.*00 00 01 20 .*
 .*00 00 00 01 .*
 
 00000450 <_ovly_buf_table>: