[PATCH v5 2/2] gdb: Keep original IFUNC return type when target type is unknown

Muhammad Kamran <[email protected]>
Newsgroups gmane.comp.gdb.patches
Message-ID <[email protected]>
When find_function_addr resolves a GNU IFUNC, it tries to replace the
original function type with the resolved target type, or with the type
returned by the resolver.  If neither source provides a useful return
type, keep the return type from the original function value.

This matters for internal inferior calls such as
find_function_in_inferior ("malloc"), where GDB creates a synthetic
function type with a known fallback return type.

Remove the guard from the IFUNC inferior-call test so the no-debug
resolver/no-debug target variants are tested too.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=34330
---
 gdb/infcall.c                        | 12 ++++++++++--
 gdb/testsuite/gdb.base/gnu-ifunc.exp |  7 -------
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/gdb/infcall.c b/gdb/infcall.c
index e6b24ff5310..4c40f6cb06e 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -395,6 +395,9 @@ find_function_addr (struct value *function,
 	     FUNCTION_TYPE have been asked for.  */
 	  if (retval_type != NULL || function_type != NULL)
 	    {
+	      /* Default to original function type's return type.  Target type
+		 replaces this only if it provides a usable return type.  */
+	      value_type = ftype->target_type ();
 	      type *target_ftype = find_function_type (funaddr);
 	      /* If we don't have debug info for the target function,
 		 see if we can instead extract the target function's
@@ -403,8 +406,13 @@ find_function_addr (struct value *function,
 		target_ftype = find_gnu_ifunc_target_type (resolver_addr);
 	      if (target_ftype != NULL)
 		{
-		  value_type = check_typedef (target_ftype)->target_type ();
-		  ftype = target_ftype;
+		  type *target_value_type
+		    = check_typedef (target_ftype)->target_type ();
+		  if (target_value_type != nullptr)
+		    {
+		      value_type = target_value_type;
+		      ftype = target_ftype;
+		    }
 		}
 	    }
 	}
diff --git a/gdb/testsuite/gdb.base/gnu-ifunc.exp b/gdb/testsuite/gdb.base/gnu-ifunc.exp
index d146a197776..ab992bc2363 100644
--- a/gdb/testsuite/gdb.base/gnu-ifunc.exp
+++ b/gdb/testsuite/gdb.base/gnu-ifunc.exp
@@ -448,13 +448,6 @@ proc_with_prefix test_inferior_call {resolver_attr resolver_debug final_debug} {
        return
     }
 
-    # Without debug info for both the resolver and the resolved target,
-    # find_function_addr currently loses the synthetic return type after
-    # resolving the IFUNC.
-    if {!$resolver_debug && !$final_debug} {
-	unsupported "internal call resolves IFUNC malloc"
-	return
-    }
     gdb_test "print (get_string (\"hello-ifunc\"), str_in_arena ())" \
 	" = 1" \
 	"internal call resolves IFUNC malloc"
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.