mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-27 04:52:05 +08:00
8388016d7f
After the previous patch, on Fedora 27 (glibc 2.26), if you try calling strlen in the inferior, you now get: (top-gdb) p strlen ("hello") '__strlen_avx2' has unknown return type; cast the call to its declared return type This is correct, because __strlen_avx2 is written in assembly. We can improve on this though -- if the final ifunc resolved/target function has no debug info, but the ifunc _resolver_ does have debug info, we can try extracting the final function's type from the type that the resolver returns. E.g.,: typedef size_t (*strlen_t) (const char*); size_t my_strlen (const char *) { /* some implementation */ } strlen_t strlen_resolver (unsigned long hwcap) { return my_strlen; } extern size_t strlen (const char *s); __typeof (strlen) strlen __attribute__ ((ifunc ("strlen_resolver"))); In the strlen example above, the resolver returns strlen_t, which is a typedef for pointer to a function that returns size_t. "strlen_t" is the type of both the user-visible "strlen", and of the the target function that implements it. This patch teaches GDB to extract that type. This is done for actual inferior function calls (in infcall.c), and for ptype (in eval_call). By the time we get to either of these places, we've already lost the original symbol/minsym, and only have values and types to work with. Hence the changes to c-exp.y and evaluate_var_msym_value, to ensure that we propagate the ifunc minsymbol's info. The change to make ifunc symbols have no/unknown return type exposes a latent problem -- gdb.compile/compile-ifunc.exp calls a no-debug-info function, but we did not warn about it. The test is fixed by this commit too. gdb/ChangeLog: 2018-04-26 Pedro Alves <palves@redhat.com> * blockframe.c (find_gnu_ifunc_target_type): New function. (find_function_type): New. * eval.c (evaluate_var_msym_value): For GNU ifunc types, always return a value with a memory address. (eval_call): For calls to GNU ifunc functions, try to find the type of the target function from the type that the resolver returns. * gdbtypes.c (objfile_type): Don't install a return type for ifunc symbols. * infcall.c (find_function_return_type): Delete. (find_function_addr): Add 'function_type' parameter. For calls to GNU ifunc functions, try to find the type of the target function from the type that the resolver returns, and return it via FUNCTION_TYPE. (call_function_by_hand_dummy): Adjust to use the function type returned by find_function_addr. (find_function_addr): Add 'function_type' parameter and move description here. * symtab.h (find_function_type, find_gnu_ifunc_target_type): New declarations. gdb/testsuite/ChangeLog: 2018-04-26 Pedro Alves <palves@redhat.com> * gdb.compile/compile-ifunc.exp: Also expect "function has unknown return type" warnings.
63 lines
1.9 KiB
Plaintext
63 lines
1.9 KiB
Plaintext
# Copyright 2015-2018 Free Software Foundation, Inc.
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
standard_testfile
|
|
|
|
with_test_prefix "nodebug" {
|
|
|
|
if { [prepare_for_testing "failed to prepare" "$testfile-nodebug" $srcfile {}] } {
|
|
return -1
|
|
}
|
|
|
|
if ![runto_main] {
|
|
return -1
|
|
}
|
|
|
|
# This binary has no debug information, so force the language to C in case
|
|
# GDB happened to see real asm code when it stopped at the entry point
|
|
# when talking to a remote target, like gdbserver. This guarantees the
|
|
# feature check below will work.
|
|
gdb_test_no_output "set language c" ""
|
|
|
|
if {[skip_compile_feature_tests]} {
|
|
untested "compile command not supported (could not find libcc1 shared library?)"
|
|
return -1
|
|
}
|
|
|
|
gdb_test "compile code resultvar = gnu_ifunc (10);" \
|
|
[multi_line \
|
|
"warning: variable has unknown type; assuming int" \
|
|
"warning: function has unknown return type; assuming int"]
|
|
|
|
gdb_test "p (int) resultvar" " = 11"
|
|
|
|
}
|
|
|
|
with_test_prefix "debug" {
|
|
|
|
if { [prepare_for_testing "failed to prepare" "$testfile-debug" $srcfile] } {
|
|
return -1
|
|
}
|
|
|
|
if ![runto_main] {
|
|
return -1
|
|
}
|
|
# gnu_ifunc (10): error: too many arguments to function 'gnu_ifunc'
|
|
gdb_test "compile code resultvar = gnu_ifunc_alias (10);" \
|
|
"warning: function has unknown return type; assuming int"
|
|
gdb_test "p resultvar" " = 11"
|
|
|
|
}
|