[binutils-gdb/gdb-18-branch] gdb: Keep original IFUNC return type when target type is unknown

Andrew Burgess via Gdb-cvs <[email protected]>
Newsgroups gmane.comp.gdb.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=66969bad2e1ae0973dd8dee14af565b94fef427f

commit 66969bad2e1ae0973dd8dee14af565b94fef427f
Author: Muhammad Kamran <[email protected]>
Date:   Tue Aug 11 13:12:19 2026 +0000

    gdb: Keep original IFUNC return type when target type is unknown
    
    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
    Reviewed-By: Kevin Buettner <[email protected]>
    Approved-By: Andrew Burgess <[email protected]>

Diff:
---
 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"
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.