compiler,runtime: use __builtin_dwarf_cfa for getcallersp
authorCherry Zhang <cherryyz@google.com>
Fri, 15 Feb 2019 23:22:29 +0000 (23:22 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Fri, 15 Feb 2019 23:22:29 +0000 (23:22 +0000)
    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 AMD64, __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 CL changes it 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 (a new version of CL 159098).

    Reviewed-on: https://go-review.googlesource.com/c/162905

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

From-SVN: r268952

gcc/go/ChangeLog
gcc/go/go-gcc.cc
gcc/go/gofrontend/MERGE
gcc/go/gofrontend/expressions.cc
gcc/go/gofrontend/expressions.h
gcc/go/gofrontend/gogo.cc
gcc/go/gofrontend/gogo.h
libgo/runtime/runtime.h

index cb69c8cfb9bff678c91bb4ffbe0e37121928a05d..e1efc14359cfde914f40cdf0450706db488ad146 100644 (file)
@@ -1,3 +1,8 @@
+2019-02-15  Cherry Zhang  <cherryyz@google.com>
+
+       * go-gcc.cc (Gcc_backend::Gcc_backend): Define __builtin_dwarf_cfa
+       instead of __builtin_frame_address.
+
 2019-02-14  Ian Lance Taylor  <iant@golang.org>
 
        * go-backend.c (go_imported_unsafe): Update
index d781ef5b3b2d2166bf61f8b401a10db7472551a2..daa1ab2af49f52d94d89b49b00ffb8ddb12fafcb 100644 (file)
@@ -735,8 +735,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 4de68b6abd7973388299acfa6c4a244add3f447c..d9ee0bad8693e1803fbbc46012629581270d99e6 100644 (file)
@@ -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 d46c7543bd906918814491a9d136844a366ba5ec..1576613c42396ed32b34714c9f77256e34d19dd7 100644 (file)
@@ -9903,17 +9903,18 @@ Call_expression::do_lower(Gogo* gogo, Named_object* function,
              && 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* gogo, Named_object* function,
   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 db40d8d0d213c6e7571ea47a627007b678e709cf..86d950bc880514e649ce03e840508025708e6840 100644 (file)
@@ -2356,7 +2356,7 @@ class Call_expression : public Expression
   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 9bd25facbff470b23e9bbc16ef5e054d9fde76ce..757758e14fa42bb71ac5bf38656e701847c1d006 100644 (file)
@@ -4511,7 +4511,7 @@ Build_recover_thunks::can_recover_arg(Location location)
   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 e4a1415269610f09cdfcdaae61db9611eeadfd13..b850ceabe9b8a993fb652292875ac36e86038578 100644 (file)
@@ -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 a6135b04820e061446f7a8fba40e606ea704464e..97b1f114c5688b2cef31b8ae1411daf8b3948823 100644 (file)
@@ -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*)