From: Cherry Zhang Date: Fri, 15 Feb 2019 23:22:29 +0000 (+0000) Subject: compiler,runtime: use __builtin_dwarf_cfa for getcallersp X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=fba70f605e759144eeebfaabcf12756906578d59;p=gcc.git 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 --- diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index cb69c8cfb9b..e1efc14359c 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,8 @@ +2019-02-15 Cherry Zhang + + * go-gcc.cc (Gcc_backend::Gcc_backend): Define __builtin_dwarf_cfa + instead of __builtin_frame_address. + 2019-02-14 Ian Lance Taylor * go-backend.c (go_imported_unsafe): Update diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc index d781ef5b3b2..daa1ab2af49 100644 --- a/gcc/go/go-gcc.cc +++ b/gcc/go/go-gcc.cc @@ -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 diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 4de68b6abd7..d9ee0bad869 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -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. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index d46c7543bd9..1576613c423 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -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. diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h index db40d8d0d21..86d950bc880 100644 --- a/gcc/go/gofrontend/expressions.h +++ b/gcc/go/gofrontend/expressions.h @@ -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*, diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 9bd25facbff..757758e14fa 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -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()); diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h index e4a14152696..b850ceabe9b 100644 --- a/gcc/go/gofrontend/gogo.h +++ b/gcc/go/gofrontend/gogo.h @@ -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. diff --git a/libgo/runtime/runtime.h b/libgo/runtime/runtime.h index a6135b04820..97b1f114c56 100644 --- a/libgo/runtime/runtime.h +++ b/libgo/runtime/runtime.h @@ -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*)