[v3] Add support for recording minimal symbols in AIX for non DWARF compiled library function record.

Message ID 20260323043445.21520-2-akamath996@gmail.com
State New
Headers
Series [v3] Add support for recording minimal symbols in AIX for non DWARF compiled library function record. |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gdb_check--master-arm success Test passed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 success Test passed

Commit Message

Aditya Vidyadhar Kamath March 23, 2026, 4:34 a.m. UTC
  From: Aditya Vidyadhar Kamath <aditya.kamath1@ibm.com>

Commit 1dfd89c739 (gdb: Remove stabs support from XCOFF inferiors) removed STABS handling from xcoffread.c.
While removing full symtab and compunit_symtab construction is appropriate when DWARF is available,
the change also removed recording of minimal symbols, which still provide value for XCOFF binaries that lack DWARF.

On AIX, system libraries such as libc and libpthread are built with STABS debug information up to AIX 7.3 TL4.
As a result, current GDB master is unable to record even minimal symbols for these libraries, leading to missing function names (e.g. printf) in common debugging scenarios.

Consider the example below,
# cat ~/gdb_tests/main.c 
#include <stdio.h>
#include "libx.h"

int main() {
        printf ("lib_func() = %d \n", lib_func());
        return 0;
}

# cat ~/gdb_tests/libx.c
int g_in_lib = 777;

int lib_func() {
        return g_in_lib + 1;
}

# cat ~/gdb_tests/libx.h
int lib_func();

We build libx and then link it to main.

When we compile this in GDB in AIX today in master branch we get,

Reading symbols from //gdb_tests/main...
(gdb) b main
Breakpoint 1 at 0x10000530: file //gdb_tests/main.c, line 5.
(gdb) r
Starting program: /gdb_tests/main

Breakpoint 1, main () at //gdb_tests/main.c:5
5           printf ("lib_func() = %d \n", lib_func());
(gdb) call printf()
No symbol "printf" in current context.
(gdb)

The issue is Without minimal symbols:
 - Functions from system libraries are not visible in backtraces.
 - Calls such as call printf() fail with no symbol in current context.
 - This affects not only stepping, but also basic usability of backtraces on AIX systems without DWARF-enabled system libraries.
 - Even when full debug information is unavailable, minimal symbols are still sufficient to:
 - Identify function entry/exit points.
 - Display meaningful backtraces involving system libraries.

This patch restores recording of minimal symbols in xcoffread.c, while keeping the removal of:
 - STABS-based symtabs
 - compunit_symtabs

The below function (read_xcoff_minimal_symbols) ensures that:
 - record_minimal_symbol() is still invoked where appropriate.
 - No attempt is made to rebuild full debug information from STABS.
 - DWARF remains the sole source for full debugging information when available.
This keeps the original intent of the STABS removal intact, while restoring essential functionality for non-DWARF XCOFF binaries.

After applying the patch we get,
GNU gdb (GDB) 18.0.50.20260316-git
Copyright (C) 2026 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "powerpc64-ibm-aix7.2.0.0".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.

+------------------------------------------------------------------------------+
| Find the GDB manual online at:                                               |
| http://www.gnu.org/software/gdb/documentation/.                              |
| For help, type "help".                                                       |
| Type "apropos word" to search for commands related to "word".                |
+------------------------------------------------------------------------------+

Reading symbols from //gdb_tests/main...
(gdb) b main
Breakpoint 1 at 0x10000530: file //gdb_tests/main.c, line 5.
(gdb) n
The program is not being run.
(gdb) r
Starting program: /gdb_tests/main

Breakpoint 1, main () at //gdb_tests/main.c:5
5           printf ("lib_func() = %d \n", lib_func());
(gdb) call (int)printf ("lib_func() = %d \n", lib_func())
lib_func() = 778
$1 = 18
(gdb)
---
 gdb/xcoffread.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 87 insertions(+)
  

Comments

Tom Tromey March 23, 2026, 6:32 p.m. UTC | #1
>>>>> Aditya Vidyadhar Kamath <akamath996@gmail.com> writes:

> +  gdb::array_view<asymbol *> symbol_table
> +    = gdb_bfd_canonicalize_symtab (abfd, false);
> +  /* Get the number of symbols we need.  */
> +  int number_of_symbols = symbol_table.size();

Space before paren.

> +  /* Return on error.  */
> +  if (number_of_symbols < 0)
> +      return;

number_of_symbols can never be < 0.

Maybe it should check == 0, but in this case the 'return' is also
indented incorrectly.

This is ok with these nits fixed up, thank you.
Approved-By: Tom Tromey <tom@tromey.com>

Tom
  
Aditya Kamath March 24, 2026, 3:34 a.m. UTC | #2
Thanks Tom.

I have made the three changes suggested and pushed the commit.

https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=def4f24d4385800ae5a96c6701d1dbe1f340e43c

Have a great day ahead.

Thanks and regards,
Aditya.

From: Tom Tromey <tom@tromey.com>
Date: Tuesday, 24 March 2026 at 12:02 AM
To: Aditya Vidyadhar Kamath <akamath996@gmail.com>
Cc: Ulrich Weigand <Ulrich.Weigand@de.ibm.com>, simon.marchi@polymtl.ca <simon.marchi@polymtl.ca>, tom@tromey.com <tom@tromey.com>, gdb-patches@sourceware.org <gdb-patches@sourceware.org>, Aditya Kamath <Aditya.Kamath1@ibm.com>, SANGAMESH MALLAYYA <sangamesh.swamy@in.ibm.com>
Subject: [EXTERNAL] Re: [PATCH v3] Add support for recording minimal symbols in AIX for non DWARF compiled library function record.

>>>>> Aditya Vidyadhar Kamath <akamath996@gmail.com> writes:

> +  gdb::array_view<asymbol *> symbol_table
> +    = gdb_bfd_canonicalize_symtab (abfd, false);
> +  /* Get the number of symbols we need.  */
> +  int number_of_symbols = symbol_table.size();

Space before paren.

> +  /* Return on error.  */
> +  if (number_of_symbols < 0)
> +      return;

number_of_symbols can never be < 0.

Maybe it should check == 0, but in this case the 'return' is also
indented incorrectly.

This is ok with these nits fixed up, thank you.
Approved-By: Tom Tromey <tom@tromey.com>

Tom
  

Patch

diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c
index b3d9bb97b62..f8021ef7793 100644
--- a/gdb/xcoffread.c
+++ b/gdb/xcoffread.c
@@ -28,6 +28,7 @@ 
 #include "xcoffread.h"
 
 #include "symtab.h"
+#include "minsyms.h"
 #include "gdbtypes.h"
 #include "symfile.h"
 #include "objfiles.h"
@@ -232,6 +233,87 @@  xcoff_get_toc_offset (objfile *objfile)
   return 0;
 }
 
+/* This function is used to read minimal sysmbols from the XCOFF STABS
+   symbol table. This function needs to be called when a library (like
+   libc) in AIX is compiled using xlc whose debug format is STABS.
+   When STABS debug information is not available, then in the backtrace
+   or other GDB features the STABS compiled functions like (printf)
+   will not be seen. Though we no longer support STABS debug, this
+   function records minimal symbol or information needed to show
+   such functions in backtrace.  */
+
+static void
+read_xcoff_minimal_symbols (objfile *objfile)
+{
+  bfd *abfd = objfile->obfd.get ();
+
+  gdb::array_view<asymbol *> symbol_table
+    = gdb_bfd_canonicalize_symtab (abfd, false);
+  /* Get the number of symbols we need.  */
+  int number_of_symbols = symbol_table.size();
+
+  /* Return on error.  */
+  if (number_of_symbols < 0)
+      return;
+
+  minimal_symbol_reader reader (objfile);
+  for (int i = 0; i < number_of_symbols; i++)
+    {
+      asymbol *sym = symbol_table[i];
+      flagword sym_flags = sym->flags;
+      CORE_ADDR sym_value = bfd_asymbol_value (sym);
+      asection *sym_section = bfd_asymbol_section (sym);
+      enum minimal_symbol_type ms_type = mst_unknown;
+      const char *sym_name = bfd_asymbol_name (sym);
+
+      /* Skip undefined sections if any.  */
+      if (sym_section == bfd_und_section_ptr)
+	continue;
+
+      /* Skip undefined, special symbols and debugging symbols.  */
+      if (sym_flags & (BSF_DEBUGGING | BSF_SECTION_SYM))
+	continue;
+
+      /* We need to pass ms_type when we record. So find the symbol type.  */
+
+      /* If this is an object file.  */
+      if (sym_flags & BSF_OBJECT)
+	{
+	  /* Code section.  */
+	  if (sym_section && (bfd_section_flags (sym_section) & SEC_CODE))
+	    ms_type = mst_text;
+	  /* Data section.  */
+	  else if (sym_section && (bfd_section_flags (sym_section) & SEC_DATA))
+	    ms_type = mst_data;
+	  /* BSS section.  */
+	  else if (sym_section && (bfd_section_flags (sym_section) & SEC_ALLOC))
+	    ms_type = mst_bss;
+	  else
+	    ms_type = mst_unknown;
+	}
+      /* Check for symbols marked as functions explicitly.  */
+      else if (sym_flags & BSF_FUNCTION)
+	  ms_type = mst_text;
+      /* Section Based Guess. Code or Data or BSS. */
+      else if (sym_section)
+	{
+	  if (bfd_section_flags (sym_section) & SEC_CODE)
+	    ms_type = mst_text;
+	  else if (bfd_section_flags (sym_section) & SEC_DATA)
+	    ms_type = mst_data;
+	  else if (bfd_section_flags (sym_section) & SEC_ALLOC)
+	    ms_type = mst_bss;
+	}
+
+      /* Add the symbol if it's global or weak */
+      if ((sym_flags & (BSF_GLOBAL | BSF_WEAK)) && sym_name && *sym_name)
+	reader.record_with_info (sym_name, unrelocated_addr (sym_value), ms_type,
+				   gdb_bfd_section_index (abfd, sym_section));
+    }
+
+  reader.install ();
+}
+
 /* Read the XCOFF symbol table.  The only thing we are interested in is the TOC
    offset value.  */
 
@@ -240,6 +322,11 @@  xcoff_symfile_read (objfile *objfile, symfile_add_flags symfile_flags)
 {
   xcoff_find_toc_offset (objfile);
 
+  /* Read minimal symbols from the STABS symbol table of an XCOFF binary
+     This makes sure we see functions from libc given libraries link to
+     it and libc in AIX may not be DWARF compiled. . */
+  read_xcoff_minimal_symbols (objfile);
+
   /* DWARF2 sections.  */
   dwarf2_initialize_objfile (objfile, &dwarf2_xcoff_names);
 }