compiler,runtime: 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 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
This commit is contained in:
Cherry Zhang 2019-02-15 23:22:29 +00:00 committed by Ian Lance Taylor
parent 9695618899
commit fba70f605e
8 changed files with 35 additions and 22 deletions

View 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

View 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

View 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.

View 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.

View 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*,

View 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());

View 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.

View 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*)