aboutsummaryrefslogtreecommitdiff
path: root/ld/emultempl
diff options
context:
space:
mode:
Diffstat (limited to 'ld/emultempl')
-rw-r--r--ld/emultempl/ppc64elf.em66
1 files changed, 60 insertions, 6 deletions
diff --git a/ld/emultempl/ppc64elf.em b/ld/emultempl/ppc64elf.em
index 9c352ee..5b637e1 100644
--- a/ld/emultempl/ppc64elf.em
+++ b/ld/emultempl/ppc64elf.em
@@ -1,5 +1,5 @@
# This shell script emits a C file. -*- C -*-
-# Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+# Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
# Free Software Foundation, Inc.
#
# This file is part of the GNU Binutils.
@@ -64,6 +64,12 @@ static int no_toc_sort = 0;
/* Set if PLT call stubs should load r11. */
static int plt_static_chain = ${DEFAULT_PLT_STATIC_CHAIN-0};
+/* Set if PLT call stubs need to be thread safe on power7+. */
+static int plt_thread_safe = -1;
+
+/* Set if individual PLT call stubs should be aligned. */
+static int plt_stub_align = 0;
+
/* Whether to emit symbols for stubs. */
static int emit_stub_syms = -1;
@@ -379,7 +385,8 @@ ppc_add_stub_section (const char *stub_sec_name, asection *input_section)
stub_sec = bfd_make_section_anyway_with_flags (stub_file->the_bfd,
stub_sec_name, flags);
if (stub_sec == NULL
- || !bfd_set_section_alignment (stub_file->the_bfd, stub_sec, 5))
+ || !bfd_set_section_alignment (stub_file->the_bfd, stub_sec,
+ plt_stub_align > 5 ? plt_stub_align : 5))
goto err_ret;
output_section = input_section->output_section;
@@ -504,7 +511,9 @@ gld${EMULATION_NAME}_after_allocation (void)
einfo ("%P: .init/.fini fragments use differing TOC pointers\n");
/* Call into the BFD backend to do the real work. */
- if (!ppc64_elf_size_stubs (&link_info, group_size, plt_static_chain))
+ if (!ppc64_elf_size_stubs (&link_info, group_size,
+ plt_static_chain, plt_thread_safe,
+ plt_stub_align))
einfo ("%X%P: can not size stub section: %E\n");
}
}
@@ -649,7 +658,11 @@ 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_STUBSYMS (OPTION_NO_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_DOTSYMS (OPTION_NO_STUBSYMS + 1)
#define OPTION_NO_DOTSYMS (OPTION_DOTSYMS + 1)
@@ -666,6 +679,10 @@ 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 },
@@ -691,10 +708,22 @@ PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'
choose suitable defaults.\n"
));
fprintf (file, _("\
- --plt-static-chain PLT call stubs should load r11.\n"
+ --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-static-chain PLT call stubs should not load r11. (default)\n"
+ --no-plt-align Dont'\''t align individual PLT call stubs.\n"
));
fprintf (file, _("\
--emit-stub-syms Label linker stubs with a symbol.\n"
@@ -753,6 +782,31 @@ PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
plt_static_chain = 0;
break;
+ case OPTION_PLT_THREAD_SAFE:
+ plt_thread_safe = 1;
+ break;
+
+ case OPTION_NO_PLT_THREAD_SAFE:
+ 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:
emit_stub_syms = 1;
break;