/* 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;
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 ();
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)
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 *);
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
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)
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;
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);
}
#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='
{ "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='
--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"
));
'
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