+if grep -q 'ld_elf32_spu_emulation' ldemul-list.h; then
+ fragment <<EOF
+/* Special handling for embedded SPU executables. */
+extern bfd_boolean embedded_spu_file (lang_input_statement_type *, const char *);
+static bfd_boolean gld${EMULATION_NAME}_load_symbols (lang_input_statement_type *);
+
+static bfd_boolean
+ppc64_recognized_file (lang_input_statement_type *entry)
+{
+ if (embedded_spu_file (entry, "-m64"))
+ return TRUE;
+
+ return gld${EMULATION_NAME}_load_symbols (entry);
+}
+EOF
+LDEMUL_RECOGNIZED_FILE=ppc64_recognized_file
+fi
+
+# Define some shell vars to insert bits of code into the standard elf
+# parse_args and list_options functions.
+#
+PARSE_AND_LIST_PROLOGUE=${PARSE_AND_LIST_PROLOGUE}'
+#define OPTION_STUBGROUP_SIZE 321
+#define OPTION_PLT_STATIC_CHAIN (OPTION_STUBGROUP_SIZE + 1)
+#define OPTION_NO_PLT_STATIC_CHAIN (OPTION_PLT_STATIC_CHAIN + 1)
+#define OPTION_PLT_THREAD_SAFE (OPTION_NO_PLT_STATIC_CHAIN + 1)
+#define OPTION_NO_PLT_THREAD_SAFE (OPTION_PLT_THREAD_SAFE + 1)
+#define OPTION_PLT_ALIGN (OPTION_NO_PLT_THREAD_SAFE + 1)
+#define OPTION_NO_PLT_ALIGN (OPTION_PLT_ALIGN + 1)
+#define OPTION_STUBSYMS (OPTION_NO_PLT_ALIGN + 1)
+#define OPTION_NO_STUBSYMS (OPTION_STUBSYMS + 1)
+#define OPTION_SAVRES (OPTION_NO_STUBSYMS + 1)
+#define OPTION_NO_SAVRES (OPTION_SAVRES + 1)
+#define OPTION_DOTSYMS (OPTION_NO_SAVRES + 1)
+#define OPTION_NO_DOTSYMS (OPTION_DOTSYMS + 1)
+#define OPTION_NO_TLS_OPT (OPTION_NO_DOTSYMS + 1)
+#define OPTION_NO_TLS_GET_ADDR_OPT (OPTION_NO_TLS_OPT + 1)
+#define OPTION_NO_OPD_OPT (OPTION_NO_TLS_GET_ADDR_OPT + 1)
+#define OPTION_NO_TOC_OPT (OPTION_NO_OPD_OPT + 1)
+#define OPTION_NO_MULTI_TOC (OPTION_NO_TOC_OPT + 1)
+#define OPTION_NO_TOC_SORT (OPTION_NO_MULTI_TOC + 1)
+#define OPTION_NON_OVERLAPPING_OPD (OPTION_NO_TOC_SORT + 1)
+'
+
+PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
+ { "stub-group-size", required_argument, NULL, OPTION_STUBGROUP_SIZE },
+ { "plt-static-chain", no_argument, NULL, OPTION_PLT_STATIC_CHAIN },
+ { "no-plt-static-chain", no_argument, NULL, OPTION_NO_PLT_STATIC_CHAIN },
+ { "plt-thread-safe", no_argument, NULL, OPTION_PLT_THREAD_SAFE },
+ { "no-plt-thread-safe", no_argument, NULL, OPTION_NO_PLT_THREAD_SAFE },
+ { "plt-align", optional_argument, NULL, OPTION_PLT_ALIGN },
+ { "no-plt-align", no_argument, NULL, OPTION_NO_PLT_ALIGN },
+ { "emit-stub-syms", no_argument, NULL, OPTION_STUBSYMS },
+ { "no-emit-stub-syms", no_argument, NULL, OPTION_NO_STUBSYMS },
+ { "dotsyms", no_argument, NULL, OPTION_DOTSYMS },
+ { "no-dotsyms", no_argument, NULL, OPTION_NO_DOTSYMS },
+ { "save-restore-funcs", no_argument, NULL, OPTION_SAVRES },
+ { "no-save-restore-funcs", no_argument, NULL, OPTION_NO_SAVRES },
+ { "no-tls-optimize", no_argument, NULL, OPTION_NO_TLS_OPT },
+ { "no-tls-get-addr-optimize", no_argument, NULL, OPTION_NO_TLS_GET_ADDR_OPT },
+ { "no-opd-optimize", no_argument, NULL, OPTION_NO_OPD_OPT },
+ { "no-toc-optimize", no_argument, NULL, OPTION_NO_TOC_OPT },
+ { "no-multi-toc", no_argument, NULL, OPTION_NO_MULTI_TOC },
+ { "no-toc-sort", no_argument, NULL, OPTION_NO_TOC_SORT },
+ { "non-overlapping-opd", no_argument, NULL, OPTION_NON_OVERLAPPING_OPD },
+'
+
+PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'
+ fprintf (file, _("\
+ --stub-group-size=N Maximum size of a group of input sections that\n\
+ can be handled by one stub section. A negative\n\
+ value locates all stubs before their branches\n\
+ (with a group size of -N), while a positive\n\
+ value allows two groups of input sections, one\n\
+ before, and one after each stub section.\n\
+ Values of +/-1 indicate the linker should\n\
+ choose suitable defaults.\n"
+ ));
+ fprintf (file, _("\
+ --plt-static-chain PLT call stubs should load r11.${DEFAULT_PLT_STATIC_CHAIN- (default)}\n"
+ ));
+ fprintf (file, _("\
+ --no-plt-static-chain PLT call stubs should not load r11.${DEFAULT_PLT_STATIC_CHAIN+ (default)}\n"
+ ));
+ fprintf (file, _("\
+ --plt-thread-safe PLT call stubs with load-load barrier.\n"
+ ));
+ fprintf (file, _("\
+ --no-plt-thread-safe PLT call stubs without barrier.\n"
+ ));
+ fprintf (file, _("\
+ --plt-align [=<align>] Align PLT call stubs to fit cache lines.\n"
+ ));
+ fprintf (file, _("\
+ --no-plt-align Dont'\''t align individual PLT call stubs.\n"
+ ));
+ fprintf (file, _("\
+ --emit-stub-syms Label linker stubs with a symbol.\n"
+ ));
+ fprintf (file, _("\
+ --no-emit-stub-syms Don'\''t label linker stubs with a symbol.\n"
+ ));
+ fprintf (file, _("\
+ --dotsyms For every version pattern \"foo\" in a version\n\
+ script, add \".foo\" so that function code\n\
+ symbols are treated the same as function\n\
+ descriptor symbols. Defaults to on.\n"
+ ));
+ fprintf (file, _("\
+ --no-dotsyms Don'\''t do anything special in version scripts.\n"
+ ));
+ fprintf (file, _("\
+ --save-restore-funcs Provide register save and restore routines used\n\
+ by gcc -Os code. Defaults to on for normal\n\
+ final link, off for ld -r.\n"
+ ));
+ fprintf (file, _("\
+ --no-save-restore-funcs Don'\''t provide these routines.\n"
+ ));
+ fprintf (file, _("\
+ --no-tls-optimize Don'\''t try to optimize TLS accesses.\n"
+ ));
+ fprintf (file, _("\
+ --no-tls-get-addr-optimize Don'\''t use a special __tls_get_addr call.\n"
+ ));
+ fprintf (file, _("\
+ --no-opd-optimize Don'\''t optimize the OPD section.\n"
+ ));
+ fprintf (file, _("\
+ --no-toc-optimize Don'\''t optimize the TOC section.\n"
+ ));
+ fprintf (file, _("\
+ --no-multi-toc Disallow automatic multiple toc sections.\n"
+ ));
+ fprintf (file, _("\
+ --no-toc-sort Don'\''t sort TOC and GOT sections.\n"
+ ));
+ fprintf (file, _("\
+ --non-overlapping-opd Canonicalize .opd, so that there are no\n\
+ overlapping .opd entries.\n"
+ ));
+'
+
+PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
+ case OPTION_STUBGROUP_SIZE:
+ {
+ const char *end;
+ params.group_size = bfd_scan_vma (optarg, &end, 0);
+ if (*end)
+ einfo (_("%P%F: invalid number `%s'\''\n"), optarg);
+ }
+ break;
+
+ case OPTION_PLT_STATIC_CHAIN:
+ params.plt_static_chain = 1;
+ break;
+
+ case OPTION_NO_PLT_STATIC_CHAIN:
+ params.plt_static_chain = 0;
+ break;
+
+ case OPTION_PLT_THREAD_SAFE:
+ params.plt_thread_safe = 1;
+ break;
+
+ case OPTION_NO_PLT_THREAD_SAFE:
+ params.plt_thread_safe = 0;
+ break;
+
+ case OPTION_PLT_ALIGN:
+ if (optarg != NULL)
+ {
+ char *end;
+ unsigned long val = strtoul (optarg, &end, 0);
+ if (*end || val > 8)
+ einfo (_("%P%F: invalid --plt-align `%s'\''\n"), optarg);
+ plt_stub_align = val;
+ }
+ else
+ plt_stub_align = 5;
+ break;
+
+ case OPTION_NO_PLT_ALIGN:
+ plt_stub_align = 0;
+ break;
+
+ case OPTION_STUBSYMS:
+ params.emit_stub_syms = 1;
+ break;
+
+ case OPTION_NO_STUBSYMS:
+ params.emit_stub_syms = 0;
+ break;
+
+ case OPTION_DOTSYMS:
+ dotsyms = 1;
+ break;
+
+ case OPTION_NO_DOTSYMS:
+ dotsyms = 0;
+ break;
+
+ case OPTION_SAVRES:
+ params.save_restore_funcs = 1;
+ break;
+
+ case OPTION_NO_SAVRES:
+ params.save_restore_funcs = 0;
+ break;
+
+ case OPTION_NO_TLS_OPT:
+ no_tls_opt = 1;
+ break;
+
+ case OPTION_NO_TLS_GET_ADDR_OPT:
+ params.no_tls_get_addr_opt = 1;
+ break;
+
+ case OPTION_NO_OPD_OPT:
+ no_opd_opt = 1;
+ break;
+
+ case OPTION_NO_TOC_OPT:
+ no_toc_opt = 1;
+ break;
+
+ case OPTION_NO_MULTI_TOC:
+ params.no_multi_toc = 1;
+ break;
+
+ case OPTION_NO_TOC_SORT:
+ no_toc_sort = 1;
+ break;
+
+ case OPTION_NON_OVERLAPPING_OPD:
+ params.non_overlapping_opd = 1;
+ break;
+
+ case OPTION_TRADITIONAL_FORMAT:
+ no_tls_opt = 1;
+ params.no_tls_get_addr_opt = 1;
+ no_opd_opt = 1;
+ no_toc_opt = 1;
+ params.no_multi_toc = 1;
+ no_toc_sort = 1;
+ params.plt_static_chain = 1;
+ return FALSE;
+'
+