diff mbox series

Go patch committed: Use __builtin_dwarf_cfa for getcallersp

Message ID CAOyqgcUjtVxqnP-6Z7CLexfEhStMNG=qoXs2wOxRdoHm8ayyUA@mail.gmail.com
State New
Headers show
Series Go patch committed: Use __builtin_dwarf_cfa for getcallersp | expand

Commit Message

Ian Lance Taylor Feb. 15, 2019, 11:22 p.m. UTC
This patch by Cherry Zhang changes the Go compiler and runtime to use
__builtin_dwarf_cfa for getcallersp.  Currently, the compiler lowers
runtime.getcallersp to __builtin_frame_address(1).  In the C side of
the runtime, getcallersp is defined as __builtin_frame_address(0).
They don't match.  Further, neither of them actually returns the
caller's SP.  On x86_64, __builtin_frame_address(0) just returns the
frame pointer.  __builtin_frame_address(1) returns the memory content
where the frame pointer points to, which is typically the caller's
frame pointer but can also be garbage if the frame pointer is not
enabled.

This patch changes getcallersp to use __builtin_dwarf_cfa(), which
returns the caller's SP at the call site.  This matches the SP we get
from unwinding the stack.

Currently getcallersp is not used for anything real. It will be used
for precise stack scan.

Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu.  Committed
to mainline.

Ian


2019-02-15  Cherry Zhang  <cherryyz@google.com>

* go-gcc.cc (Gcc_backend::Gcc_backend): Define __builtin_dwarf_cfa
instead of __builtin_frame_address.
diff mbox series

Patch

Index: gcc/go/go-gcc.cc
===================================================================
--- gcc/go/go-gcc.cc	(revision 268369)
+++ gcc/go/go-gcc.cc	(working copy)
@@ -734,8 +734,9 @@  Gcc_backend::Gcc_backend()
   this->define_builtin(BUILT_IN_RETURN_ADDRESS, "__builtin_return_address",
 		       NULL, t, false, false);
 
-  // The runtime calls __builtin_frame_address for runtime.getcallersp.
-  this->define_builtin(BUILT_IN_FRAME_ADDRESS, "__builtin_frame_address",
+  // The runtime calls __builtin_dwarf_cfa for runtime.getcallersp.
+  t = build_function_type_list(ptr_type_node, NULL_TREE);
+  this->define_builtin(BUILT_IN_DWARF_CFA, "__builtin_dwarf_cfa",
 		       NULL, t, false, false);
 
   // The runtime calls __builtin_extract_return_addr when recording
Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE	(revision 268948)
+++ gcc/go/gofrontend/MERGE	(working copy)
@@ -1,4 +1,4 @@ 
-1a74b8a22b2ff7f430729aa87ecb8cea7b5cdd70
+9605c2efd99aa9c744652a9153e208e0653b8596
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
Index: gcc/go/gofrontend/expressions.cc
===================================================================
--- gcc/go/gofrontend/expressions.cc	(revision 268923)
+++ gcc/go/gofrontend/expressions.cc	(working copy)
@@ -9903,17 +9903,18 @@  Call_expression::do_lower(Gogo* gogo, Na
 	      && n == "getcallerpc")
 	    {
 	      static Named_object* builtin_return_address;
+              int arg = 0;
 	      return this->lower_to_builtin(&builtin_return_address,
 					    "__builtin_return_address",
-					    0);
+					    &arg);
 	    }
 	  else if ((this->args_ == NULL || this->args_->size() == 0)
 		   && n == "getcallersp")
 	    {
-	      static Named_object* builtin_frame_address;
-	      return this->lower_to_builtin(&builtin_frame_address,
-					    "__builtin_frame_address",
-					    1);
+	      static Named_object* builtin_dwarf_cfa;
+	      return this->lower_to_builtin(&builtin_dwarf_cfa,
+					    "__builtin_dwarf_cfa",
+					    NULL);
 	    }
 	}
     }
@@ -10031,21 +10032,24 @@  Call_expression::lower_varargs(Gogo* gog
   this->varargs_are_lowered_ = true;
 }
 
-// Return a call to __builtin_return_address or __builtin_frame_address.
+// Return a call to __builtin_return_address or __builtin_dwarf_cfa.
 
 Expression*
 Call_expression::lower_to_builtin(Named_object** pno, const char* name,
-				  int arg)
+				  int* arg)
 {
   if (*pno == NULL)
-    *pno = Gogo::declare_builtin_rf_address(name);
+    *pno = Gogo::declare_builtin_rf_address(name, arg != NULL);
 
   Location loc = this->location();
 
   Expression* fn = Expression::make_func_reference(*pno, NULL, loc);
-  Expression* a = Expression::make_integer_ul(arg, NULL, loc);
   Expression_list *args = new Expression_list();
-  args->push_back(a);
+  if (arg != NULL)
+    {
+      Expression* a = Expression::make_integer_ul(*arg, NULL, loc);
+      args->push_back(a);
+    }
   Expression* call = Expression::make_call(fn, args, false, loc);
 
   // The builtin functions return void*, but the Go functions return uintptr.
Index: gcc/go/gofrontend/expressions.h
===================================================================
--- gcc/go/gofrontend/expressions.h	(revision 268369)
+++ gcc/go/gofrontend/expressions.h	(working copy)
@@ -2356,7 +2356,7 @@  class Call_expression : public Expressio
   check_argument_type(int, const Type*, const Type*, Location, bool);
 
   Expression*
-  lower_to_builtin(Named_object**, const char*, int);
+  lower_to_builtin(Named_object**, const char*, int*);
 
   Expression*
   interface_method_function(Interface_field_reference_expression*,
Index: gcc/go/gofrontend/gogo.cc
===================================================================
--- gcc/go/gofrontend/gogo.cc	(revision 268923)
+++ gcc/go/gofrontend/gogo.cc	(working copy)
@@ -4511,7 +4511,7 @@  Build_recover_thunks::can_recover_arg(Lo
   static Named_object* builtin_return_address;
   if (builtin_return_address == NULL)
     builtin_return_address =
-      Gogo::declare_builtin_rf_address("__builtin_return_address");
+      Gogo::declare_builtin_rf_address("__builtin_return_address", true);
 
   Type* uintptr_type = Type::lookup_integer_type("uintptr");
   static Named_object* can_recover;
@@ -4565,16 +4565,19 @@  Gogo::build_recover_thunks()
 }
 
 // Return a declaration for __builtin_return_address or
-// __builtin_frame_address.
+// __builtin_dwarf_cfa.
 
 Named_object*
-Gogo::declare_builtin_rf_address(const char* name)
+Gogo::declare_builtin_rf_address(const char* name, bool hasarg)
 {
   const Location bloc = Linemap::predeclared_location();
 
   Typed_identifier_list* param_types = new Typed_identifier_list();
-  Type* uint32_type = Type::lookup_integer_type("uint32");
-  param_types->push_back(Typed_identifier("l", uint32_type, bloc));
+  if (hasarg)
+    {
+      Type* uint32_type = Type::lookup_integer_type("uint32");
+      param_types->push_back(Typed_identifier("l", uint32_type, bloc));
+    }
 
   Typed_identifier_list* return_types = new Typed_identifier_list();
   Type* voidptr_type = Type::make_pointer_type(Type::make_void_type());
Index: gcc/go/gofrontend/gogo.h
===================================================================
--- gcc/go/gofrontend/gogo.h	(revision 268891)
+++ gcc/go/gofrontend/gogo.h	(working copy)
@@ -737,9 +737,9 @@  class Gogo
   build_recover_thunks();
 
   // Return a declaration for __builtin_return_address or
-  // __builtin_frame_address.
+  // __builtin_dwarf_cfa.
   static Named_object*
-  declare_builtin_rf_address(const char* name);
+  declare_builtin_rf_address(const char* name, bool hasarg);
 
   // Simplify statements which might use thunks: go and defer
   // statements.
Index: libgo/runtime/runtime.h
===================================================================
--- libgo/runtime/runtime.h	(revision 268923)
+++ libgo/runtime/runtime.h	(working copy)
@@ -268,7 +268,7 @@  void*	runtime_sysAlloc(uintptr, uint64*)
 void	runtime_sysFree(void*, uintptr, uint64*)
   __asm__ (GOSYM_PREFIX "runtime.sysFree");
 void	runtime_mprofinit(void);
-#define runtime_getcallersp() __builtin_frame_address(0)
+#define runtime_getcallersp() __builtin_dwarf_cfa()
 void	runtime_mcall(FuncVal*)
   __asm__ (GOSYM_PREFIX "runtime.mcall");
 int32	runtime_timediv(int64, int32, int32*)