X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=ld%2Femultempl%2Fspuelf.em;h=3266f65e21db802ca541f9f327df4d1ecaae0b1e;hb=628e8859461e0af7dcae8357032b19ccfe611ff6;hp=2dd34ea7877a30fd2d59914fb80dd4f52030ca83;hpb=dc27aea4b88283415703ab781476f49b4caa65fd;p=deliverable%2Fbinutils-gdb.git diff --git a/ld/emultempl/spuelf.em b/ld/emultempl/spuelf.em index 2dd34ea787..3266f65e21 100644 --- a/ld/emultempl/spuelf.em +++ b/ld/emultempl/spuelf.em @@ -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,9 @@ 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; + const char *prefix; + size_t prefix_len; if (entry->the_bfd->format != bfd_object || strcmp (entry->the_bfd->xvec->name, "elf32-spu") != 0 @@ -283,23 +316,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 +343,42 @@ 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"; + prefix = base_name (program_name); + prefix_len = strlen (prefix); + if (prefix_len > 2 + && (prefix[prefix_len - 2] == 'l' + || prefix[prefix_len - 2] == 'L') + && (prefix[prefix_len - 1] == 'd' + || prefix[prefix_len - 1] == 'D')) + { + cmd[0] = xmalloc (prefix_len + 7); + memcpy (cmd[0], prefix, prefix_len - 2); + memcpy (cmd[0] + prefix_len - 2, "embedspu", 9); + } + else + { + prefix_len = 0; + cmd[0] = "embedspu"; + } cmd[1] = flags; cmd[2] = handle; cmd[3] = entry->the_bfd->filename; @@ -347,6 +397,11 @@ embedded_spu_file (lang_input_statement_type *entry, const char *flags) if (pid == 0) { execvp (cmd[0], (char *const *) cmd); + if (prefix_len != 0) + { + cmd[0] = "embedspu"; + execvp (cmd[0], (char *const *) cmd); + } perror (cmd[0]); _exit (127); } @@ -396,6 +451,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 +461,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 +471,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 +507,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