diff options
author | Lancelot SIX <lancelot.six@amd.com> | 2022-01-17 06:13:39 -0500 |
---|---|---|
committer | Lancelot SIX <lancelot.six@amd.com> | 2022-02-15 09:52:37 +0000 |
commit | 0b35f123c200522998a81335dc218551ca7b3d92 (patch) | |
tree | 9f964fa813c131514c01b362d233e2f5e1066207 /gdb/infcmd.c | |
parent | e6b3636709a19303859cb886f5212d5092837b27 (diff) | |
download | gdb-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.c | 9 |
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 |