aboutsummaryrefslogtreecommitdiff
path: root/gdb/infcmd.c
diff options
context:
space:
mode:
authorLancelot SIX <lancelot.six@amd.com>2022-01-17 06:13:39 -0500
committerLancelot SIX <lancelot.six@amd.com>2022-02-15 09:52:37 +0000
commit0b35f123c200522998a81335dc218551ca7b3d92 (patch)
tree9f964fa813c131514c01b362d233e2f5e1066207 /gdb/infcmd.c
parente6b3636709a19303859cb886f5212d5092837b27 (diff)
downloadgdb-0b35f123c200522998a81335dc218551ca7b3d92.zip
gdb-0b35f123c200522998a81335dc218551ca7b3d92.tar.gz
gdb-0b35f123c200522998a81335dc218551ca7b3d92.tar.bz2
gdb: Respect the DW_CC_nocall attribute
It is possible for a compiler to optimize a function in a such ways that the function does not follow the calling convention of the target. In such situation, the compiler can use the DW_AT_calling_convention attribute with the value DW_CC_nocall to tell the debugger that it is unsafe to call the function. The DWARF5 standard states, in 3.3.1.1: > If the value of the calling convention attribute is the constant > DW_CC_nocall, the subroutine does not obey standard calling > conventions, and it may not be safe for the debugger to call this > subroutine. Non standard calling convention can affect GDB's assumptions in multiple ways, including how arguments are passed to the function, how values are returned, and so on. For this reason, it is unsafe for GDB to try to do the following operations on a function with marked with DW_CC_nocall: - call / print an expression requiring the function to be evaluated, - inspect the value a function returns using the 'finish' command, - force the value returned by a function using the 'return' command. This patch ensures that if a command which relies on GDB's knowledge of the target's calling convention is used on a function marked nocall, GDB prints an appropriate message to the user and does not proceed with the operation which is unreliable. Note that it is still possible for someone to use a vendor specific value for the DW_AT_calling_convention attribute for example to indicate the use of an alternative calling convention. This commit does not prevent this, and target dependent code can be adjusted if one wanted to support multiple calling conventions. Tested on x86_64-Linux, with no regression observed. Change-Id: I72970dae68234cb83edbc0cf71aa3d6002a4a540
Diffstat (limited to 'gdb/infcmd.c')
-rw-r--r--gdb/infcmd.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 1dc4e36..465c8f3 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -1457,6 +1457,15 @@ get_return_value (struct symbol *func_symbol, struct value *function)
= check_typedef (TYPE_TARGET_TYPE (func_symbol->type ()));
gdb_assert (value_type->code () != TYPE_CODE_VOID);
+ if (is_nocall_function (check_typedef (::value_type (function))))
+ {
+ warning (_("Function '%s' does not follow the target calling "
+ "convention, cannot determine its returned value."),
+ func_symbol->print_name ());
+
+ return nullptr;
+ }
+
/* FIXME: 2003-09-27: When returning from a nested inferior function
call, it's possible (with no help from the architecture vector)
to locate and return/print a "struct return" value. This is just