* Makefile.am: Add eelf32_spu.o rule.
[deliverable/binutils-gdb.git] / ld / emultempl / spuelf.em
index 2dd34ea7877a30fd2d59914fb80dd4f52030ca83..252b90f10461324e92b788fbf05a1ae45c920c8c 100644 (file)
@@ -34,6 +34,12 @@ static int non_overlay_stubs = 0;
 /* Whether to emit symbols for stubs.  */
 static int emit_stub_syms = 0;
 
+/* Non-zero to perform stack space analysis.  */
+static int stack_analysis = 0;
+
+/* Whether to emit symbols with stack requirements for each function.  */
+static int emit_stack_syms = 0;
+
 /* Range of valid addresses for loadable sections.  */
 static bfd_vma local_store_lo = 0;
 static bfd_vma local_store_hi = 0x3ffff;
@@ -70,7 +76,8 @@ spu_after_open (void)
   if (is_spu_target ()
       && !link_info.relocatable
       && link_info.input_bfds != NULL
-      && !spu_elf_create_sections (output_bfd, &link_info))
+      && !spu_elf_create_sections (output_bfd, &link_info,
+                                  stack_analysis, emit_stack_syms))
     einfo ("%X%P: can not create note section: %E\n");
 
   gld${EMULATION_NAME}_after_open ();
@@ -187,7 +194,7 @@ spu_before_allocation (void)
          asection *stub, *ovtab;
 
          if (!spu_elf_size_stubs (output_bfd, &link_info, non_overlay_stubs,
-                                  &stub, &ovtab, &toe))
+                                  stack_analysis, &stub, &ovtab, &toe))
            einfo ("%X%P: can not size overlay stubs: %E\n");
 
          if (stub != NULL)
@@ -257,6 +264,29 @@ static void clean_tmp (void)
     unlink (tmp_file_list->name);
 }
 
+static const char *
+base_name (const char *path)
+{
+  const char *file = strrchr (path, '/');
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+  {
+    char *bslash = strrchr (path, '\\');
+
+    if (file == NULL || (bslash != NULL && bslash > file))
+      file = bslash;
+    if (file == NULL
+       && path[0] != '\0'
+       && path[1] == ':')
+      file = path + 1;
+  }
+#endif
+  if (file == NULL)
+    file = path;
+  else
+    ++file;
+  return file;
+}
+
 /* This function is called when building a ppc32 or ppc64 executable
    to handle embedded spu images.  */
 extern bfd_boolean embedded_spu_file (lang_input_statement_type *, const char *);
@@ -275,6 +305,7 @@ embedded_spu_file (lang_input_statement_type *entry, const char *flags)
   union lang_statement_union **old_stat_tail;
   union lang_statement_union **old_file_tail;
   union lang_statement_union *new_ent;
+  lang_input_statement_type *search;
 
   if (entry->the_bfd->format != bfd_object
       || strcmp (entry->the_bfd->xvec->name, "elf32-spu") != 0
@@ -283,23 +314,7 @@ embedded_spu_file (lang_input_statement_type *entry, const char *flags)
     return FALSE;
 
   /* Use the filename as the symbol marking the program handle struct.  */
-  sym = strrchr (entry->the_bfd->filename, '/');
-#ifdef HAVE_DOS_BASED_FILE_SYSTEM
-  {
-    char *bslash = strrchr (entry->the_bfd->filename, '\\');
-
-    if (sym == NULL || (bslash != NULL && bslash > sym))
-      sym = bslash;
-    if (sym == NULL
-       && entry->the_bfd->filename[0] != '\0'
-       && entry->the_bfd->filename[1] == ':')
-      sym = entry->the_bfd->filename + 1;
-  }
-#endif
-  if (sym == NULL)
-    sym = entry->the_bfd->filename;
-  else
-    ++sym;
+  sym = base_name (entry->the_bfd->filename);
 
   handle = xstrdup (sym);
   for (p = handle; *p; ++p)
@@ -326,9 +341,26 @@ embedded_spu_file (lang_input_statement_type *entry, const char *flags)
     return FALSE;
   close (fd);
 
+  for (search = (lang_input_statement_type *) input_file_chain.head;
+       search != NULL;
+       search = (lang_input_statement_type *) search->next_real_file)
+    {
+      const char *infile = base_name (search->filename);
+
+      if (infile != NULL
+         && strncmp (infile, "crtbegin", 8) == 0)
+       {
+         if (infile[8] == 'S')
+           flags = concat (flags, " -fPIC", NULL);
+         else if (infile[8] == 'T')
+           flags = concat (flags, " -fpie", NULL);
+         break;
+       }
+    }
+
   /* Use fork() and exec() rather than system() so that we don't
      need to worry about quoting args.  */
-  cmd[0] = "embedspu";
+  cmd[0] = EMBEDSPU;
   cmd[1] = flags;
   cmd[2] = handle;
   cmd[3] = entry->the_bfd->filename;
@@ -347,6 +379,11 @@ embedded_spu_file (lang_input_statement_type *entry, const char *flags)
   if (pid == 0)
     {
       execvp (cmd[0], (char *const *) cmd);
+      if (strcmp ("embedspu", EMBEDSPU) != 0)
+       {
+         cmd[0] = "embedspu";
+         execvp (cmd[0], (char *const *) cmd);
+       }
       perror (cmd[0]);
       _exit (127);
     }
@@ -396,6 +433,8 @@ PARSE_AND_LIST_PROLOGUE='
 #define OPTION_SPU_STUB_SYMS           (OPTION_SPU_NO_OVERLAYS + 1)
 #define OPTION_SPU_NON_OVERLAY_STUBS   (OPTION_SPU_STUB_SYMS + 1)
 #define OPTION_SPU_LOCAL_STORE         (OPTION_SPU_NON_OVERLAY_STUBS + 1)
+#define OPTION_SPU_STACK_ANALYSIS      (OPTION_SPU_LOCAL_STORE + 1)
+#define OPTION_SPU_STACK_SYMS          (OPTION_SPU_STACK_ANALYSIS + 1)
 '
 
 PARSE_AND_LIST_LONGOPTS='
@@ -404,6 +443,8 @@ PARSE_AND_LIST_LONGOPTS='
   { "emit-stub-syms", no_argument, NULL, OPTION_SPU_STUB_SYMS },
   { "extra-overlay-stubs", no_argument, NULL, OPTION_SPU_NON_OVERLAY_STUBS },
   { "local-store", required_argument, NULL, OPTION_SPU_LOCAL_STORE },
+  { "stack-analysis", no_argument, NULL, OPTION_SPU_STACK_ANALYSIS },
+  { "emit-stack-syms", no_argument, NULL, OPTION_SPU_STACK_SYMS },
 '
 
 PARSE_AND_LIST_OPTIONS='
@@ -412,7 +453,9 @@ PARSE_AND_LIST_OPTIONS='
   --no-overlays         No overlay handling.\n\
   --emit-stub-syms      Add symbols on overlay call stubs.\n\
   --extra-overlay-stubs Add stubs on all calls out of overlay regions.\n\
-  --local-store=lo:hi   Valid address range.\n"
+  --local-store=lo:hi   Valid address range.\n\
+  --stack-analysis      Estimate maximum stack requirement.\n\
+  --emit-stack-syms     Add __stack_func giving stack needed for each func.\n"
                   ));
 '
 
@@ -446,6 +489,14 @@ PARSE_AND_LIST_ARGS_CASES='
        einfo (_("%P%F: invalid --local-store address range `%s'\''\n"), optarg);
       }
       break;
+
+    case OPTION_SPU_STACK_ANALYSIS:
+      stack_analysis = 1;
+      break;
+
+    case OPTION_SPU_STACK_SYMS:
+      emit_stack_syms = 1;
+      break;
 '
 
 LDEMUL_AFTER_OPEN=spu_after_open
This page took 0.027308 seconds and 4 git commands to generate.