]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Ada import functions not in index
authorTom Tromey <tom@tromey.com>
Thu, 2 Jan 2025 20:40:27 +0000 (13:40 -0700)
committerTom Tromey <tom@tromey.com>
Wed, 10 Sep 2025 22:05:27 +0000 (16:05 -0600)
The cooked index does not currently contain entries for Ada import
functions.  This means that whether or not these are visible to
"break" depends on which CUs were previously expanded -- clearly a
bug.

This patch fixes the issue.  I think the comments in the patch explain
the fix reasonably well.

Perhaps one to-do item here is to change GNAT to use
DW_TAG_imported_declaration for these imports.  This may eventually
let us remove some of the current hacks.

This version includes a fix from Simon to initialize the new member.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32511
Acked-By: Simon Marchi <simon.marchi@efficios.com>
gdb/dwarf2/abbrev.c
gdb/dwarf2/abbrev.h
gdb/dwarf2/cooked-indexer.c
gdb/dwarf2/read.c
gdb/dwarf2/read.h
gdb/testsuite/gdb.ada/import.exp

index 5cfff69cc3b5c8f71bcd38ce5a641f9939b4a6d9..e3c268e7c474340af12c9eed63ddd8b91b957441 100644 (file)
@@ -108,6 +108,8 @@ abbrev_table::read (struct dwarf2_section_info *section,
       cur_abbrev->has_children = read_1_byte (abfd, abbrev_ptr);
       abbrev_ptr += 1;
 
+      cur_abbrev->maybe_ada_import = false;
+
       unsigned int size = 0;
       unsigned int sibling_offset = -1;
       bool is_csize = true;
@@ -242,7 +244,12 @@ abbrev_table::read (struct dwarf2_section_info *section,
        }
       else if (has_hardcoded_declaration
               && (cur_abbrev->tag != DW_TAG_variable || !has_external))
-       cur_abbrev->interesting = false;
+       {
+         cur_abbrev->interesting = false;
+         if (cur_abbrev->tag == DW_TAG_subprogram && has_name
+             && has_linkage_name)
+           cur_abbrev->maybe_ada_import = true;
+       }
       else if (!tag_interesting_for_index (cur_abbrev->tag))
        cur_abbrev->interesting = false;
       else
index 6fc61b101e9355f6a1183e6500b4d3833e79260c..a36bb8c1ba639e4836f2fb99efeb97a0e4512454 100644 (file)
@@ -51,6 +51,14 @@ struct abbrev_info
   /* True if the DIE has children.  */
   bool has_children;
   bool interesting;
+  /* In Ada, an imported subprogram DIE will be marked as a
+     declaration, but will have both a name and a linkage name.  This
+     declaration may be the only spot where that name is associated
+     with an object, so it has to show up in the index.  But, because
+     abbrevs are CU-independent, we can't check the language when
+     computing them and instead we keep a separate flag to indicate
+     that the scanner should check this DIE.  */
+  bool maybe_ada_import;
   unsigned short size_if_constant;
   unsigned short sibling_offset;
   /* Number of attributes.  */
index d4557c45c29c83a935f221c34ee6d21e57b16592..ef883259032392e0090a78a7174706418c28f951 100644 (file)
@@ -20,6 +20,7 @@
 #include "dwarf2/cooked-indexer.h"
 #include "dwarf2/cooked-index-worker.h"
 #include "dwarf2/error.h"
+#include "dwarf2/read.h"
 
 /* See cooked-indexer.h.  */
 
@@ -297,7 +298,7 @@ cooked_indexer::scan_attributes (dwarf2_per_cu *scanning_per_cu,
           || abbrev->tag == DW_TAG_namespace)
          && abbrev->has_children)
        *flags |= IS_TYPE_DECLARATION;
-      else
+      else if (!is_ada_import_or_export (reader->cu (), *name, *linkage_name))
        {
          *linkage_name = nullptr;
          *name = nullptr;
@@ -506,7 +507,8 @@ cooked_indexer::index_dies (cutu_reader *reader,
       /* If a DIE parent is a DW_TAG_subprogram, then the DIE is only
         interesting if it's a DW_TAG_subprogram or a DW_TAG_entry_point.  */
       bool die_interesting
-       = (abbrev->interesting
+       = ((abbrev->interesting
+           || (m_language == language_ada && abbrev->maybe_ada_import))
           && (parent_entry == nullptr
               || parent_entry->tag != DW_TAG_subprogram
               || abbrev->tag == DW_TAG_subprogram
index c76086fbc0496251cd5424d2b216a59bf500b776..69b1330bdf46f9183c4c86ce7635ed4f7bad5c58 100644 (file)
@@ -981,9 +981,6 @@ static void queue_comp_unit (dwarf2_per_cu *per_cu,
 
 static void process_queue (dwarf2_per_objfile *per_objfile);
 
-static bool is_ada_import_or_export (dwarf2_cu *cu, const char *name,
-                                    const char *linkagename);
-
 /* Class, the destructor of which frees all allocated queue entries.  This
    will only have work to do if an error was thrown while processing the
    dwarf.  If no error was thrown then the queue entries should have all
@@ -15977,14 +15974,14 @@ add_ada_export_symbol (struct symbol *orig, const char *new_name,
   add_symbol_to_list (copy, list_to_add);
 }
 
-/* A helper function that decides if a given symbol is an Ada Pragma
-   Import or Pragma Export.  */
+/* See read.h.  */
 
-static bool
+bool
 is_ada_import_or_export (dwarf2_cu *cu, const char *name,
                         const char *linkagename)
 {
   return (cu->lang () == language_ada
+         && name != nullptr
          && linkagename != nullptr
          && !streq (name, linkagename)
          /* The following exclusions are necessary because symbols
index b9be5419e5d971a5ffe10492d41548aae46e1687..469e68ac0deb500d29b9a967151a45c50433b62b 100644 (file)
@@ -1382,4 +1382,10 @@ extern struct dwarf2_section_info *get_debug_line_section
 extern void dwarf2_start_subfile (dwarf2_cu *cu, const file_entry &fe,
                                  const line_header &lh);
 
+/* A helper function that decides if a given symbol is an Ada Pragma
+   Import or Pragma Export.  */
+
+extern bool is_ada_import_or_export (dwarf2_cu *cu, const char *name,
+                                    const char *linkagename);
+
 #endif /* GDB_DWARF2_READ_H */
index ab3a1c9002bb02d9a00f3e12edbfc0a27cd29d0c..51ce7faab793aaa14cca10a55eb80ec9f0b50930 100644 (file)
@@ -54,6 +54,9 @@ gdb_test "print pkg.imported_var_ada" " = 42"
 gdb_test "print pkg.exported_var_ada" " = 99"
 gdb_test "print exported_var_ada" " = 99"
 
+gdb_breakpoint "local_imported_func" message
+gdb_test "print copy" " = 42"
+
 # This passes with gcc 10 but fails with gcc 9.  With gcc 9, we have:
 #   <1><1659>: Abbrev Number: 4 (DW_TAG_subprogram)
 #      <165a>   DW_AT_external    : 1
@@ -76,19 +79,16 @@ gdb_test "print exported_var_ada" " = 99"
 # The fact that things start to work when adding the DW_AT_declaration is
 # consistent with what is described in commit ff9baa5f1c5, so xfail this
 # (without pinpointing it to a specific gcc PR or commit).
-if { [gcc_major_version] < 10 } {
-    setup_xfail *-*-*
-}
-gdb_breakpoint "pkg.imported_func_ada" message
-gdb_breakpoint "imported_func" message
-if { [gcc_major_version] < 10 } {
-    setup_xfail *-*-*
+foreach func {"pkg.imported_func_ada" "imported_func"} {
+    clean_restart $testfile
+    if { [gcc_major_version] < 10 } {
+       setup_xfail *-*-*
+    }
+    gdb_breakpoint $func message
 }
-gdb_breakpoint "imported_func_ada" message
 
-gdb_breakpoint "local_imported_func" message
-gdb_breakpoint "pkg.exported_func_ada" message
-gdb_breakpoint "exported_func_ada" message
-gdb_breakpoint "exported_func" message
-
-gdb_test "print copy" " = 42"
+foreach func {"imported_func_ada" "pkg.exported_func_ada" \
+                 "exported_func_ada" "exported_func"} {
+    clean_restart $testfile
+    gdb_breakpoint $func message
+}