bfd/
authorAlan Modra <amodra@gmail.com>
Wed, 10 Dec 2008 13:36:41 +0000 (13:36 +0000)
committerAlan Modra <amodra@gmail.com>
Wed, 10 Dec 2008 13:36:41 +0000 (13:36 +0000)
* elf32-spu.h (struct spu_elf_params): Add num_regions.
* elf32-spu.c (spu_elf_auto_overlay): Handle multiple overlay regions.
ld/
* emultempl/spuelf.em (params): Init new field.
(OPTION_SPU_NUM_REGIONS): Define.
(PARSE_AND_LIST_LONGOPTS, PARSE_AND_LIST_OPTIONS): Add --num-regions.
(PARSE_AND_LIST_ARGS_CASES): Handle --num-regions.

bfd/ChangeLog
bfd/elf32-spu.c
bfd/elf32-spu.h
ld/ChangeLog
ld/emultempl/spuelf.em

index ebb847b7016ac4c92a4c638b0fc3f4ce35885efd..704a418843cf27bd42f76825d2c6745cedd177e8 100644 (file)
@@ -1,3 +1,8 @@
+2008-12-10  Alan Modra  <amodra@bigpond.net.au>
+
+       * elf32-spu.h (struct spu_elf_params): Add num_regions.
+       * elf32-spu.c (spu_elf_auto_overlay): Handle multiple overlay regions.
+
 2008-12-10  Alan Modra  <amodra@bigpond.net.au>
 
        * elf32-spu.g (struct spu_elf_params, enum _ovly_flavour): New.
index 3908ecd125c44fa2e76dbfbbbfc9333d9779ea50..447aa8da0a0deb4aa7b07ef75084fbb3a2a0427d 100644 (file)
@@ -3444,8 +3444,9 @@ spu_elf_auto_overlay (struct bfd_link_info *info)
   unsigned int fixed_size, lo, hi;
   struct spu_link_hash_table *htab;
   unsigned int base, i, count, bfd_count;
-  int ovlynum;
+  unsigned int region, ovlynum;
   asection **ovly_sections, **ovly_p;
+  unsigned int *ovly_map;
   FILE *script;
   unsigned int total_overlay_size, overlay_size;
   struct elf_link_hash_entry *h;
@@ -3625,20 +3626,17 @@ spu_elf_auto_overlay (struct bfd_link_info *info)
   if (!for_each_node (collect_overlays, info, &ovly_p, TRUE))
     goto err_exit;
   count = (size_t) (ovly_p - ovly_sections) / 2;
-
-  script = (*htab->params->spu_elf_open_overlay_script) ();
-
-  if (fprintf (script, "SECTIONS\n{\n OVERLAY :\n {\n") <= 0)
-    goto file_err;
+  ovly_map = bfd_malloc (count * sizeof (*ovly_map));
+  if (ovly_map == NULL)
+    goto err_exit;
 
   memset (&dummy_caller, 0, sizeof (dummy_caller));
-  overlay_size = htab->local_store - fixed_size;
+  overlay_size = (htab->local_store - fixed_size) / htab->params->num_regions;
   base = 0;
   ovlynum = 0;
   while (base < count)
     {
       unsigned int size = 0;
-      unsigned int j;
 
       for (i = base; i < count; i++)
        {
@@ -3741,90 +3739,127 @@ spu_elf_auto_overlay (struct bfd_link_info *info)
          goto err_exit;
        }
 
-      if (fprintf (script, "  .ovly%d {\n", ++ovlynum) <= 0)
+      while (dummy_caller.call_list != NULL)
+       {
+         struct call_info *call = dummy_caller.call_list;
+         dummy_caller.call_list = call->next;
+         free (call);
+       }
+
+      ++ovlynum;
+      while (base < i)
+       ovly_map[base++] = ovlynum;
+    }
+
+  script = htab->params->spu_elf_open_overlay_script ();
+
+  if (fprintf (script, "SECTIONS\n{\n") <= 0)
+    goto file_err;
+
+  for (region = 1; region <= htab->params->num_regions; region++)
+    {
+      ovlynum = region;
+      base = 0;
+      while (base < count && ovly_map[base] < ovlynum)
+       base++;
+
+      if (base == count)
+       break;
+
+      if (fprintf (script, " OVERLAY :\n {\n") <= 0)
        goto file_err;
-      for (j = base; j < i; j++)
+
+      while (base < count)
        {
-         asection *sec = ovly_sections[2 * j];
-
-         if (fprintf (script, "   %s%c%s (%s)\n",
-                      (sec->owner->my_archive != NULL
-                       ? sec->owner->my_archive->filename : ""),
-                      info->path_separator,
-                      sec->owner->filename,
-                      sec->name) <= 0)
+         unsigned int j;
+         
+         if (fprintf (script, "  .ovly%u {\n", ovlynum) <= 0)
            goto file_err;
-         if (sec->segment_mark)
+
+         for (j = base; j < count && ovly_map[j] == ovlynum; j++)
            {
-             struct call_info *call = find_pasted_call (sec);
-             while (call != NULL)
+             asection *sec = ovly_sections[2 * j];
+
+             if (fprintf (script, "   %s%c%s (%s)\n",
+                          (sec->owner->my_archive != NULL
+                           ? sec->owner->my_archive->filename : ""),
+                          info->path_separator,
+                          sec->owner->filename,
+                          sec->name) <= 0)
+               goto file_err;
+             if (sec->segment_mark)
                {
-                 struct function_info *call_fun = call->fun;
-                 sec = call_fun->sec;
-                 if (fprintf (script, "   %s%c%s (%s)\n",
-                              (sec->owner->my_archive != NULL
-                               ? sec->owner->my_archive->filename : ""),
-                              info->path_separator,
-                              sec->owner->filename,
-                              sec->name) <= 0)
-                   goto file_err;
-                 for (call = call_fun->call_list; call; call = call->next)
-                   if (call->is_pasted)
-                     break;
+                 struct call_info *call = find_pasted_call (sec);
+                 while (call != NULL)
+                   {
+                     struct function_info *call_fun = call->fun;
+                     sec = call_fun->sec;
+                     if (fprintf (script, "   %s%c%s (%s)\n",
+                                  (sec->owner->my_archive != NULL
+                                   ? sec->owner->my_archive->filename : ""),
+                                  info->path_separator,
+                                  sec->owner->filename,
+                                  sec->name) <= 0)
+                       goto file_err;
+                     for (call = call_fun->call_list; call; call = call->next)
+                       if (call->is_pasted)
+                         break;
+                   }
                }
            }
-       }
 
-      for (j = base; j < i; j++)
-       {
-         asection *sec = ovly_sections[2 * j + 1];
-         if (sec != NULL
-             && fprintf (script, "   %s%c%s (%s)\n",
-                         (sec->owner->my_archive != NULL
-                          ? sec->owner->my_archive->filename : ""),
-                         info->path_separator,
-                         sec->owner->filename,
-                         sec->name) <= 0)
-           goto file_err;
-
-         sec = ovly_sections[2 * j];
-         if (sec->segment_mark)
+         for (j = base; j < count && ovly_map[j] == ovlynum; j++)
            {
-             struct call_info *call = find_pasted_call (sec);
-             while (call != NULL)
+             asection *sec = ovly_sections[2 * j + 1];
+             if (sec != NULL
+                 && fprintf (script, "   %s%c%s (%s)\n",
+                             (sec->owner->my_archive != NULL
+                              ? sec->owner->my_archive->filename : ""),
+                             info->path_separator,
+                             sec->owner->filename,
+                             sec->name) <= 0)
+               goto file_err;
+
+             sec = ovly_sections[2 * j];
+             if (sec->segment_mark)
                {
-                 struct function_info *call_fun = call->fun;
-                 sec = call_fun->rodata;
-                 if (sec != NULL
-                     && fprintf (script, "   %s%c%s (%s)\n",
-                                 (sec->owner->my_archive != NULL
-                                  ? sec->owner->my_archive->filename : ""),
-                                 info->path_separator,
-                                 sec->owner->filename,
-                                 sec->name) <= 0)
-                   goto file_err;
-                 for (call = call_fun->call_list; call; call = call->next)
-                   if (call->is_pasted)
-                     break;
+                 struct call_info *call = find_pasted_call (sec);
+                 while (call != NULL)
+                   {
+                     struct function_info *call_fun = call->fun;
+                     sec = call_fun->rodata;
+                     if (sec != NULL
+                         && fprintf (script, "   %s%c%s (%s)\n",
+                                     (sec->owner->my_archive != NULL
+                                      ? sec->owner->my_archive->filename : ""),
+                                     info->path_separator,
+                                     sec->owner->filename,
+                                     sec->name) <= 0)
+                       goto file_err;
+                     for (call = call_fun->call_list; call; call = call->next)
+                       if (call->is_pasted)
+                         break;
+                   }
                }
            }
-       }
 
-      if (fprintf (script, "  }\n") <= 0)
-       goto file_err;
+         if (fprintf (script, "  }\n") <= 0)
+           goto file_err;
 
-      while (dummy_caller.call_list != NULL)
-       {
-         struct call_info *call = dummy_caller.call_list;
-         dummy_caller.call_list = call->next;
-         free (call);
+         base = j;
+         ovlynum += htab->params->num_regions;
+         while (base < count && ovly_map[base] < ovlynum)
+           base++;
        }
 
-      base = i;
+      if (fprintf (script, " }\n") <= 0)
+       goto file_err;
     }
+
+  free (ovly_map);
   free (ovly_sections);
 
-  if (fprintf (script, " }\n}\nINSERT AFTER .text;\n") <= 0)
+  if (fprintf (script, "}\nINSERT BEFORE .text;\n") <= 0)
     goto file_err;
   if (fclose (script) != 0)
     goto file_err;
index 8cac3a33760bbcbb6d09448c5883f1d403a7f7a4..442dd5d3b2e830e142427f2cbca90f32b6d88858 100644 (file)
@@ -55,6 +55,7 @@ struct spu_elf_params
   bfd_vma local_store_hi;
 
   /* Control --auto-overlay feature.  */
+  unsigned int num_regions;
   unsigned int auto_overlay_fixed;
   unsigned int auto_overlay_reserved;
   int extra_stack_space;
index 864cba31f1c550c0d62e2abfc1d70783119390a6..b9588c36c1f00210b28002b7cde6dccc5c994268 100644 (file)
@@ -1,3 +1,10 @@
+2008-12-10  Alan Modra  <amodra@bigpond.net.au>
+
+       * emultempl/spuelf.em (params): Init new field.
+       (OPTION_SPU_NUM_REGIONS): Define.
+       (PARSE_AND_LIST_LONGOPTS, PARSE_AND_LIST_OPTIONS): Add --num-regions.
+       (PARSE_AND_LIST_ARGS_CASES): Handle --num-regions.
+
 2008-12-10  Alan Modra  <amodra@bigpond.net.au>
 
        * emultempl/spuelf.em (params): New var, used instead of various others.
index cb80c45cbf30f2ae75e0e6f09d9bf268af52cb2b..bfabb8b72ee68346f5a2148df38d5e2d52a43d4c 100644 (file)
@@ -39,7 +39,7 @@ static struct spu_elf_params params =
   &spu_elf_relink,
   0, ovly_normal, 0, 0, 0, 0,
   0, 0x3ffff,
-  0, 0, 2000
+  1, 0, 0, 2000
 };
   
 static char *auto_overlay_file = 0;
@@ -520,7 +520,8 @@ PARSE_AND_LIST_PROLOGUE='
 #define OPTION_SPU_AUTO_OVERLAY                (OPTION_SPU_STACK_SYMS + 1)
 #define OPTION_SPU_AUTO_RELINK         (OPTION_SPU_AUTO_OVERLAY + 1)
 #define OPTION_SPU_OVERLAY_RODATA      (OPTION_SPU_AUTO_RELINK + 1)
-#define OPTION_SPU_FIXED_SPACE         (OPTION_SPU_OVERLAY_RODATA + 1)
+#define OPTION_SPU_NUM_REGIONS         (OPTION_SPU_OVERLAY_RODATA + 1)
+#define OPTION_SPU_FIXED_SPACE         (OPTION_SPU_NUM_REGIONS + 1)
 #define OPTION_SPU_RESERVED_SPACE      (OPTION_SPU_FIXED_SPACE + 1)
 #define OPTION_SPU_EXTRA_STACK         (OPTION_SPU_RESERVED_SPACE + 1)
 #define OPTION_SPU_NO_AUTO_OVERLAY     (OPTION_SPU_EXTRA_STACK + 1)
@@ -537,6 +538,7 @@ PARSE_AND_LIST_LONGOPTS='
   { "auto-overlay", optional_argument, NULL, OPTION_SPU_AUTO_OVERLAY },
   { "auto-relink", no_argument, NULL, OPTION_SPU_AUTO_RELINK },
   { "overlay-rodata", no_argument, NULL, OPTION_SPU_OVERLAY_RODATA },
+  { "num-regions", required_argument, NULL, OPTION_SPU_NUM_REGIONS },
   { "fixed-space", required_argument, NULL, OPTION_SPU_FIXED_SPACE },
   { "reserved-space", required_argument, NULL, OPTION_SPU_RESERVED_SPACE },
   { "extra-stack-space", required_argument, NULL, OPTION_SPU_EXTRA_STACK },
@@ -557,6 +559,7 @@ PARSE_AND_LIST_OPTIONS='
   --auto-relink               Rerun linker using auto-overlay script.\n\
   --overlay-rodata            Place read-only data with associated function\n\
                               code in overlays.\n\
+  --num-regions               Number of overlay buffers (default 1).\n\
   --fixed-space=bytes         Local store for non-overlay code and data.\n\
   --reserved-space=bytes      Local store for stack and heap.  If not specified\n\
                               ld will estimate stack size and assume no heap.\n\
@@ -621,6 +624,16 @@ PARSE_AND_LIST_ARGS_CASES='
       params.auto_overlay |= 4;
       break;
 
+    case OPTION_SPU_NUM_REGIONS:
+      {
+       char *end;
+       params.num_regions = strtoul (optarg, &end, 0);
+       if (*end == 0)
+         break;
+       einfo (_("%P%F: invalid --num-regions `%s'\''\n"), optarg);
+      }
+      break;
+
     case OPTION_SPU_FIXED_SPACE:
       {
        char *end;