[RFC] PR64703, glibc sysdeps/powerpc/powerpc64/dl-machine.h miscompile
Alan Modra
amodra@gmail.com
Thu Jan 29 15:06:00 GMT 2015
Here is the completed patch. Bootstrapped and regression tested
powerpc64-linux. Is this OK to apply? If not now, then when gcc is
in stage1 again?
gcc/
PR target/64703
* target.def (has_function_descriptors): New hook.
* doc/tm.texi.in: Add TARGET_HAS_FUNCTION_DESCRIPTORS.
* doc/tc.texi: Regenerate.
* tree-ssa-alias.c (pt_solution_includes_base): New function,
extracted from..
(ref_maybe_used_by_call_p_1): ..here. Handle potential memory
reference by indirect calls on targets using function descriptors.
* config/rs6000/rs6000.c (TARGET_HAS_FUNCTION_DESCRIPTORS): Define.
(rs6000_has_function_descriptors): New function.
gcc/testsuite/
* gcc.target/powerpc/pr64703.c: New.
Index: gcc/target.def
===================================================================
--- gcc/target.def (revision 220025)
+++ gcc/target.def (working copy)
@@ -2821,6 +2821,15 @@ The default value of this hook is based on target'
bool, (void),
default_has_ifunc_p)
+/* True if target defines the address of a function as that of a
+ function descriptor. */
+DEFHOOK
+(has_function_descriptors,
+ "True if target has function descriptors and defines the address\n\
+of a function as that of a function descriptor.",
+ bool, (void),
+ hook_bool_void_false)
+
/* True if it is OK to do sibling call optimization for the specified
call expression EXP. DECL will be the called function, or NULL if
this is an indirect call. */
Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in (revision 220025)
+++ gcc/doc/tm.texi.in (working copy)
@@ -8175,6 +8175,8 @@ and the associated definitions of those functions.
@hook TARGET_HAS_IFUNC_P
+@hook TARGET_HAS_FUNCTION_DESCRIPTORS
+
@hook TARGET_ATOMIC_ALIGN_FOR_MODE
@hook TARGET_ATOMIC_ASSIGN_EXPAND_FENV
Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi (revision 220025)
+++ gcc/doc/tm.texi (working copy)
@@ -11510,6 +11510,11 @@ The support includes the assembler, linker and dyn
The default value of this hook is based on target's libc.
@end deftypefn
+@deftypefn {Target Hook} bool TARGET_HAS_FUNCTION_DESCRIPTORS (void)
+True if target has function descriptors and defines the address
+of a function as that of a function descriptor.
+@end deftypefn
+
@deftypefn {Target Hook} {unsigned int} TARGET_ATOMIC_ALIGN_FOR_MODE (machine_mode @var{mode})
If defined, this function returns an appropriate alignment in bits for an atomic object of machine_mode @var{mode}. If 0 is returned then the default alignment for the specified mode is used.
@end deftypefn
Index: gcc/tree-ssa-alias.c
===================================================================
--- gcc/tree-ssa-alias.c (revision 220025)
+++ gcc/tree-ssa-alias.c (working copy)
@@ -1532,6 +1532,25 @@ refs_output_dependent_p (tree store1, tree store2)
return refs_may_alias_p_1 (&r1, &r2, false);
}
+/* Return true if the points-to solution *PT includes the object BASE. */
+
+static bool
+pt_solution_includes_base (struct pt_solution *pt, tree base)
+{
+ if (DECL_P (base))
+ return pt_solution_includes (pt, base);
+
+ if ((TREE_CODE (base) == MEM_REF
+ || TREE_CODE (base) == TARGET_MEM_REF)
+ && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
+ {
+ struct ptr_info_def *pi = SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0));
+ if (pi)
+ return pt_solutions_intersect (pt, &pi->pt);
+ }
+ return true;
+}
+
/* If the call CALL may use the memory reference REF return true,
otherwise return false. */
@@ -1542,6 +1561,22 @@ ref_maybe_used_by_call_p_1 (gcall *call, ao_ref *r
unsigned i;
int flags = gimple_call_flags (call);
+ callee = gimple_call_fn (call);
+ if (callee && TREE_CODE (callee) == SSA_NAME
+ && targetm.has_function_descriptors ())
+ {
+ /* Handle indirect call. When a target defines the address of a
+ function as that of a function descriptor, then dereferencing
+ a function pointer implicitly references memory. */
+ struct ptr_info_def *pi = SSA_NAME_PTR_INFO (callee);
+ if (pi)
+ {
+ base = ao_ref_base (ref);
+ if (pt_solution_includes_base (&pi->pt, base))
+ return true;
+ }
+ }
+
/* Const functions without a static chain do not implicitly use memory. */
if (!gimple_call_chain (call)
&& (flags & (ECF_CONST|ECF_NOVOPS)))
@@ -1564,7 +1599,7 @@ ref_maybe_used_by_call_p_1 (gcall *call, ao_ref *r
&& !is_global_var (base))
goto process_args;
- callee = gimple_call_fndecl (call);
+ callee = gimple_call_addr_fndecl (callee);
/* Handle those builtin functions explicitly that do not act as
escape points. See tree-ssa-structalias.c:find_func_aliases
@@ -1803,23 +1838,7 @@ ref_maybe_used_by_call_p_1 (gcall *call, ao_ref *r
}
/* Check if the base variable is call-used. */
- if (DECL_P (base))
- {
- if (pt_solution_includes (gimple_call_use_set (call), base))
- return true;
- }
- else if ((TREE_CODE (base) == MEM_REF
- || TREE_CODE (base) == TARGET_MEM_REF)
- && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
- {
- struct ptr_info_def *pi = SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0));
- if (!pi)
- return true;
-
- if (pt_solutions_intersect (gimple_call_use_set (call), &pi->pt))
- return true;
- }
- else
+ if (pt_solution_includes_base (gimple_call_use_set (call), base))
return true;
/* Inspect call arguments for passed-by-value aliases. */
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c (revision 220025)
+++ gcc/config/rs6000/rs6000.c (working copy)
@@ -1490,6 +1490,9 @@ static const struct attribute_spec rs6000_attribut
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
+#undef TARGET_HAS_FUNCTION_DESCRIPTORS
+#define TARGET_HAS_FUNCTION_DESCRIPTORS rs6000_has_function_descriptors
+
#undef TARGET_FUNCTION_OK_FOR_SIBCALL
#define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
@@ -22099,6 +22102,14 @@ rs6000_return_addr (int count, rtx frame)
return get_hard_reg_initial_val (Pmode, LR_REGNO);
}
+/* Return true if we use function descriptors. */
+
+static bool
+rs6000_has_function_descriptors (void)
+{
+ return DEFAULT_ABI == ABI_AIX;
+}
+
/* Say whether a function is a candidate for sibcall handling or not. */
static bool
Index: gcc/testsuite/gcc.target/powerpc/pr64703.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr64703.c (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/pr64703.c (working copy)
@@ -0,0 +1,36 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-options "-O2 -mabi=elfv1" } */
+/* { dg-final { scan-assembler "std .\*,112\\(1\\)" } } */
+/* { dg-final { scan-assembler "std .\*,120\\(1\\)" } } */
+/* { dg-final { scan-assembler "std .\*,128\\(1\\)" } } */
+/* { dg-final { scan-assembler "addi .\*,1,112" } } */
+
+/* Testcase taken from glibc, powerpc64 dl-machine.h. */
+
+typedef struct {
+ unsigned long fd_func;
+ unsigned long fd_toc;
+ unsigned long fd_aux;
+} Elf64_FuncDesc;
+
+extern unsigned long dl_hwcap;
+
+unsigned long
+resolve_ifunc (unsigned long value, unsigned long adjust)
+{
+ Elf64_FuncDesc opd;
+
+ if (adjust)
+ {
+ Elf64_FuncDesc *func = (Elf64_FuncDesc *) value;
+ opd.fd_func = func->fd_func + adjust;
+ opd.fd_toc = func->fd_toc + adjust;
+ opd.fd_aux = func->fd_aux;
+ value = (unsigned long) &opd;
+ }
+#if 0
+ __asm__ ("#%0" : : "r" (value));
+#endif
+ return ((unsigned long (*) (unsigned long)) value) (dl_hwcap);
+}
--
Alan Modra
Australia Development Lab, IBM
More information about the Gcc-patches
mailing list