===================================================================
@@ -1087,6 +1087,11 @@ fdbg-cnt=
Common RejectNegative Joined Var(common_deferred_options) Defer
-fdbg-cnt=<counter>:<limit>[,<counter>:<limit>,...] Set the debug counter limit.
+fno-plt=
+Common RejectNegative Joined Var(common_deferred_options) Defer
+-fno-plt=<symbol1> Avoid going through the PLT when calling the specified function.
+Allow multiple instances of this option with different function names.
+
fdebug-prefix-map=
Common Joined RejectNegative Var(common_deferred_options) Defer
Map one directory name to another in debug information
===================================================================
@@ -25282,6 +25282,25 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx call
return call;
}
+extern htab_t avoid_plt_fnsymbol_names_tab;
+/* If the function referenced by call_op is to a external function
+ and calls via PLT must be avoided as specified by -fno-plt=, then
+ return true. */
+
+static int
+avoid_plt_to_call(rtx call_op)
+{
+ const char *name;
+ if (GET_CODE (call_op) != SYMBOL_REF
+ || SYMBOL_REF_LOCAL_P (call_op)
+ || avoid_plt_fnsymbol_names_tab == NULL)
+ return 0;
+ name = XSTR (call_op, 0);
+ if (htab_find_slot (avoid_plt_fnsymbol_names_tab, name, NO_INSERT) != NULL)
+ return 1;
+ return 0;
+}
+
/* Output the assembly for a call instruction. */
const char *
@@ -25294,7 +25313,12 @@ ix86_output_call_insn (rtx insn, rtx call_op)
if (SIBLING_CALL_P (insn))
{
if (direct_p)
- xasm = "jmp\t%P0";
+ {
+ if (avoid_plt_to_call (call_op))
+ xasm = "jmp\t*%p0@GOTPCREL(%%rip)";
+ else
+ xasm = "jmp\t%P0";
+ }
/* SEH epilogue detection requires the indirect branch case
to include REX.W. */
else if (TARGET_SEH)
@@ -25346,9 +25370,15 @@ ix86_output_call_insn (rtx insn, rtx call_op)
}
if (direct_p)
- xasm = "call\t%P0";
+ {
+ if (avoid_plt_to_call (call_op))
+ xasm = "call\t*%p0@GOTPCREL(%%rip)";
+ else
+ xasm = "call\t%P0";
+ }
else
xasm = "call\t%A0";
+
output_asm_insn (xasm, &call_op);
===================================================================
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3. If not see
#include "xregex.h"
#include "attribs.h"
#include "stringpool.h"
+#include "hash-table.h"
typedef const char *const_char_p; /* For DEF_VEC_P. */
@@ -420,6 +421,17 @@ decode_options (struct gcc_options *opts, struct g
finish_options (opts, opts_set, loc);
}
+/* Helper function for the hash table that compares the
+ existing entry (S1) with the given string (S2). */
+
+static int
+htab_str_eq (const void *s1, const void *s2)
+{
+ return !strcmp ((const char *)s1, (const char *) s2);
+}
+
+htab_t avoid_plt_fnsymbol_names_tab = NULL;
+
/* Process common options that have been deferred until after the
handlers have been called for all options. */
@@ -539,6 +551,15 @@ handle_common_deferred_options (void)
stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (opt->arg));
break;
+ case OPT_fno_plt_:
+ void **slot;
+ if (avoid_plt_fnsymbol_names_tab == NULL)
+ avoid_plt_fnsymbol_names_tab = htab_create (10, htab_hash_string,
+ htab_str_eq, NULL);
+ slot = htab_find_slot (avoid_plt_fnsymbol_names_tab, opt->arg, INSERT);
+ *slot = (void *)opt->arg;
+ break;
+
default:
gcc_unreachable ();
}