[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