Stop readekf and objdump from aggressively following links.
authorNick Clifton <nickc@redhat.com>
Fri, 20 May 2022 15:55:36 +0000 (16:55 +0100)
committerNick Clifton <nickc@redhat.com>
Fri, 20 May 2022 15:55:36 +0000 (16:55 +0100)
* dwarf.c (dwarf_select_sections_by_names): Return zero if no
sections were selected.
(dwarf_select_sections_by_letters): Likewise.
* dwarf.h: (dwarf_select_sections_by_names): Update prototype.
(dwarf_select_sections_by_letters): Update prototype.
* objdump.c (might_need_separate_debug_info): New function.
(dump_bfd): Call new function before attempting to load separate
debug info files.
(main): Do not enable dwarf section dumping for -WK or -WN.
* readelf.c (parse_args): Do not enable dwarf section dumping for
-wK or -wN.
(might_need_separate_debug_info): New function.
(process_object): Call new function before attempting to load
separate debug info files.
* testsuite/binutils-all/debuginfo.exp: Expect -WE and -wE
debuginfod tests to pass.
* testsuite/binutils-all/objdump.Wk: Add extra regexps.
* testsuite/binutils-all/readelf.k: Add extra regexps.

binutils/ChangeLog
binutils/dwarf.c
binutils/dwarf.h
binutils/objdump.c
binutils/readelf.c
binutils/testsuite/binutils-all/debuginfod.exp
binutils/testsuite/binutils-all/objdump.Wk
binutils/testsuite/binutils-all/readelf.k

index e5b973d08d94e10baa8050cfd67d5c9f0eba66b5..6a8f1b587de37628e9c9c90e211f5eeca582dd81 100644 (file)
@@ -1,3 +1,24 @@
+2022-05-20  Nick Clifton  <nickc@redhat.com>
+
+       * dwarf.c (dwarf_select_sections_by_names): Return zero if no
+       sections were selected.
+       (dwarf_select_sections_by_letters): Likewise.
+       * dwarf.h: (dwarf_select_sections_by_names): Update prototype.
+       (dwarf_select_sections_by_letters): Update prototype.
+       * objdump.c (might_need_separate_debug_info): New function.
+       (dump_bfd): Call new function before attempting to load separate
+       debug info files.
+       (main): Do not enable dwarf section dumping for -WK or -WN.
+       * readelf.c (parse_args): Do not enable dwarf section dumping for
+       -wK or -wN.
+       (might_need_separate_debug_info): New function.
+       (process_object): Call new function before attempting to load
+       separate debug info files.
+       * testsuite/binutils-all/debuginfo.exp: Expect -WE and -wE
+       debuginfod tests to pass.
+       * testsuite/binutils-all/objdump.Wk: Add extra regexps.
+       * testsuite/binutils-all/readelf.k: Add extra regexps.
+
 2022-05-19  Nick Clifton  <nickc@redhat.com>
 
        * dlltool.c (run): Initialise errmsg_fmt.
index e61c63a06012715208d80889927ee3b9144a0fab..7de6f28161f291e54ba320aa6aca67f9da593667 100644 (file)
@@ -12062,7 +12062,11 @@ free_debug_memory (void)
   free_dwo_info ();
 }
 
-void
+/* Enable display of specific DWARF sections as determined by the comma
+   separated strings in NAMES.  Returns non-zero if any displaying was
+   enabled.  */
+
+int
 dwarf_select_sections_by_names (const char *names)
 {
   typedef struct
@@ -12115,6 +12119,7 @@ dwarf_select_sections_by_names (const char *names)
     };
 
   const char *p;
+  int result = 0;
 
   p = names;
   while (*p)
@@ -12129,6 +12134,7 @@ dwarf_select_sections_by_names (const char *names)
              && (p[len] == ',' || p[len] == '\0'))
            {
              * entry->variable = entry->val;
+             result |= entry->val;
 
              /* The --debug-dump=frames-interp option also
                 enables the --debug-dump=frames option.  */
@@ -12151,48 +12157,82 @@ dwarf_select_sections_by_names (const char *names)
       if (*p == ',')
        p++;
     }
+
+  return result;
 }
 
-void
+/* Enable display of specific DWARF sections as determined by the characters
+   in LETTERS.  Returns non-zero if any displaying was enabled.  */
+
+int
 dwarf_select_sections_by_letters (const char *letters)
 {
-  unsigned int lindex = 0;
+  typedef struct
+  {
+    const char   letter;
+    int *        variable;
+    int          val;
+    bool         cont;
+  }
+  debug_dump_letter_opts;
 
-  while (letters[lindex])
-    switch (letters[lindex++])
-      {
-      case 'A':        do_debug_addr = 1; break;
-      case 'a':        do_debug_abbrevs = 1; break;
-      case 'c':        do_debug_cu_index = 1; break;
+  static const debug_dump_letter_opts letter_table [] =
+    {
+      { 'A', & do_debug_addr, 1, false},
+      { 'a', & do_debug_abbrevs, 1, false },
+      { 'c', & do_debug_cu_index, 1, false },
 #ifdef HAVE_LIBDEBUGINFOD
-      case 'D': use_debuginfod = 1; break;
-      case 'E': use_debuginfod = 0; break;
+      { 'D', & use_debuginfod, 1, false },
+      { 'E', & use_debuginfod, 0, false },
 #endif
-      case 'F':        do_debug_frames_interp = 1; /* Fall through.  */
-      case 'f':        do_debug_frames = 1; break;
-      case 'g':        do_gdb_index = 1; break;
-      case 'i':        do_debug_info = 1; break;
-      case 'K': do_follow_links = 1; break;
-      case 'N': do_follow_links = 0; break;
-      case 'k':        do_debug_links = 1; break;
-      case 'l':        do_debug_lines |= FLAG_DEBUG_LINES_RAW; break;
-      case 'L':        do_debug_lines |= FLAG_DEBUG_LINES_DECODED; break;
-      case 'm': do_debug_macinfo = 1; break;
-      case 'O':        do_debug_str_offsets = 1; break;
-      case 'o':        do_debug_loc = 1; break;
-      case 'p':        do_debug_pubnames = 1; break;
-      case 'R':        do_debug_ranges = 1; break;
-      case 'r':        do_debug_aranges = 1; break;
-      case 's':        do_debug_str = 1; break;
-      case 'T': do_trace_aranges = 1; break;
-      case 't': do_debug_pubtypes = 1; break;
-      case 'U': do_trace_info = 1; break;
-      case 'u': do_trace_abbrevs = 1; break;
+      { 'F', & do_debug_frames_interp, 1, true }, /* Note the fall through.  */
+      { 'f', & do_debug_frames, 1, false },
+      { 'g', & do_gdb_index, 1, false },
+      { 'i', & do_debug_info, 1, false },
+      { 'K', & do_follow_links, 1, false },
+      { 'k', & do_debug_links, 1, false },
+      { 'L', & do_debug_lines, FLAG_DEBUG_LINES_DECODED, false },
+      { 'l', & do_debug_lines, FLAG_DEBUG_LINES_RAW, false },
+      { 'm', & do_debug_macinfo, 1, false },
+      { 'N', & do_follow_links, 0, false },
+      { 'O', & do_debug_str_offsets, 1, false },
+      { 'o', & do_debug_loc, 1, false },
+      { 'p', & do_debug_pubnames, 1, false },
+      { 'R', & do_debug_ranges, 1, false },
+      { 'r', & do_debug_aranges, 1, false },
+      { 's', & do_debug_str, 1, false },
+      { 'T', & do_trace_aranges, 1, false },
+      { 't', & do_debug_pubtypes, 1, false },
+      { 'U', & do_trace_info, 1, false },
+      { 'u', & do_trace_abbrevs, 1, false },
+      { 0, NULL, 0, false }
+    };
 
-      default:
-       warn (_("Unrecognized debug option '%s'\n"), letters);
-       break;
-      }
+  int result = 0;
+
+  while (* letters)
+    {
+      const debug_dump_letter_opts * entry;
+
+      for (entry = letter_table; entry->letter; entry++)
+       {
+         if (entry->letter == * letters)
+           {
+             * entry->variable |= entry->val;
+             result |= entry->val;
+
+             if (! entry->cont)
+               break;
+           }
+       }
+
+      if (entry->letter == 0)
+       warn (_("Unrecognized debug letter option '%c'\n"), * letters);
+
+      letters ++;
+    }
+
+  return result;
 }
 
 void
index ccce2461c811e34a0ce457ac8bb9d6778d205e01..040e674c6ce6507174e5cfd87689b3d741599155 100644 (file)
@@ -250,8 +250,8 @@ extern void *open_debug_file (const char *);
 
 extern void free_debug_memory (void);
 
-extern void dwarf_select_sections_by_names (const char *);
-extern void dwarf_select_sections_by_letters (const char *);
+extern int dwarf_select_sections_by_names (const char *);
+extern int dwarf_select_sections_by_letters (const char *);
 extern void dwarf_select_sections_all (void);
 
 extern unsigned int * find_cu_tu_set (void *, unsigned int);
index 060a136efa44c167360276f4cfc29b18640460ba..f585c1b8d186891b162340fa4fd99e66d3b0980a 100644 (file)
@@ -5188,6 +5188,26 @@ sign_extend_address (bfd *abfd ATTRIBUTE_UNUSED,
   return (((vma & ((mask << 1) - 1)) ^ mask) - mask);
 }
 
+static bool
+might_need_separate_debug_info (bool is_mainfile)
+{
+  /* We do not follow links from debug info files.  */
+  if (! is_mainfile)
+    return false;
+
+  /* Since do_follow_links might be enabled by default, only treat it as an
+     indication that separate files should be loaded if setting it was a
+     deliberate user action.  */
+  if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
+    return true;
+  
+  if (process_links || dump_symtab || dump_debugging
+      || dump_dwarf_section_info)
+    return true;
+
+  return false;  
+}
+
 /* Dump selected contents of ABFD.  */
 
 static void
@@ -5202,16 +5222,8 @@ dump_bfd (bfd *abfd, bool is_mainfile)
   else
     byte_get = NULL;
 
-  /* Load any separate debug information files.
-     We do this now and without checking do_follow_links because separate
-     debug info files may contain symbol tables that we will need when
-     displaying information about the main file.  Any memory allocated by
-     load_separate_debug_files will be released when we call
-     free_debug_memory below.
-
-     The test on is_mainfile is there because the chain of separate debug
-     info files is a global variable shared by all invocations of dump_bfd.  */
-  if (byte_get != NULL && is_mainfile)
+  /* Load any separate debug information files.  */
+  if (byte_get != NULL && might_need_separate_debug_info (is_mainfile))
     {
       load_separate_debug_files (abfd, bfd_get_filename (abfd));
 
@@ -5783,20 +5795,30 @@ main (int argc, char **argv)
          do_follow_links = true;
          break;
        case 'W':
-         dump_dwarf_section_info = true;
          seenflag = true;
          if (optarg)
-           dwarf_select_sections_by_letters (optarg);
+           {
+             if (dwarf_select_sections_by_letters (optarg))
+               dump_dwarf_section_info = true;
+           }
          else
-           dwarf_select_sections_all ();
+           {
+             dump_dwarf_section_info = true;
+             dwarf_select_sections_all ();
+           }
          break;
        case OPTION_DWARF:
-         dump_dwarf_section_info = true;
          seenflag = true;
          if (optarg)
-           dwarf_select_sections_by_names (optarg);
+           {
+             if (dwarf_select_sections_by_names (optarg))
+               dump_dwarf_section_info = true;
+           }
          else
-           dwarf_select_sections_all ();
+           {
+             dwarf_select_sections_all ();
+             dump_dwarf_section_info = true;
+           }
          break;
        case OPTION_DWARF_DEPTH:
          {
index d45e09207880d0fa7c314108e0f64997feb9dd20..c35bfc123669a9d1aca98ee7702a55be47864d2e 100644 (file)
@@ -5526,31 +5526,39 @@ parse_args (struct dump_data *dumpdata, int argc, char ** argv)
          decompress_dumps = true;
          break;
        case 'w':
-         do_dump = true;
-         dump_any_debugging = true;
          if (optarg == NULL)
            {
              do_debugging = true;
+             do_dump = true;
+             dump_any_debugging = true;
              dwarf_select_sections_all ();
            }
          else
            {
              do_debugging = false;
-             dwarf_select_sections_by_letters (optarg);
+             if (dwarf_select_sections_by_letters (optarg))
+               {
+                 do_dump = true;
+                 dump_any_debugging = true;
+               }
            }
          break;
        case OPTION_DEBUG_DUMP:
-         do_dump = true;
-         dump_any_debugging = true;
          if (optarg == NULL)
            {
+             do_dump = true;
              do_debugging = true;
+             dump_any_debugging = true;
              dwarf_select_sections_all ();
            }
          else
            {
              do_debugging = false;
-             dwarf_select_sections_by_names (optarg);
+             if (dwarf_select_sections_by_names (optarg))
+               {
+                 do_dump = true;
+                 dump_any_debugging = true;
+               }
            }
          break;
        case OPTION_DWARF_DEPTH:
@@ -22252,6 +22260,26 @@ initialise_dump_sects (Filedata * filedata)
     }
 }
 
+static bool
+might_need_separate_debug_info (Filedata * filedata)
+{
+  /* Debuginfo files do not need further separate file loading.  */
+  if (filedata->file_header.e_shstrndx == SHN_UNDEF)
+    return false;
+
+  /* Since do_follow_links might be enabled by default, only treat it as an
+     indication that separate files should be loaded if setting it was a
+     deliberate user action.  */
+  if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
+    return true;
+  
+  if (process_links || do_syms || do_unwind 
+      || dump_any_debugging || do_dump || do_debugging)
+    return true;
+
+  return false;
+}
+
 /* Process one ELF object file according to the command line options.
    This file may actually be stored in an archive.  The file is
    positioned at the start of the ELF object.  Returns TRUE if no
@@ -22335,7 +22363,7 @@ process_object (Filedata * filedata)
   if (! process_version_sections (filedata))
     res = false;
 
-  if (filedata->file_header.e_shstrndx != SHN_UNDEF)
+  if (might_need_separate_debug_info (filedata))
     have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
   else
     have_separate_files = false;
index f5935ad0348869021933a3580059a61278692745..d0e6db23f34aec456195be3a55de97d3de521ea0 100644 (file)
@@ -189,7 +189,7 @@ if { [regexp ".*DEBUGINFOD.*" $conf_objdump] } {
     test_fetch_debugaltlink $OBJDUMP "-Wk"
 
     set test "disabling debuginfod access"
-    setup_xfail *-*-*
+    setup_xfail *-*-*
     test_fetch_debuglink $OBJDUMP "-W -WE"
     set test "debuginfod"
 
@@ -202,7 +202,7 @@ if { [regexp ".*DEBUGINFOD.*" $conf_readelf] } {
     test_fetch_debugaltlink $READELF "-wk"
 
     set test "disabling debuginfod access"
-    setup_xfail *-*-*
+    setup_xfail *-*-*
     test_fetch_debuglink $READELF "-w -wE"
     set test "debuginfod"
 
index 35472328fc213c42a8be0f9762c1ee7510647a05..b0d7b1a91f9cc2b38ec8308b5d64db656b89caf1 100644 (file)
@@ -1,8 +1,9 @@
+#...
 tmpdir/debuglink\.o:     file format .*
-Contents of the \.gnu_debuglink section:
+Contents of the \.gnu_debuglink section.*
   Separate debug info file: this_is_a_debuglink\.debug
   CRC value: 0x12345678
-Contents of the \.gnu_debugaltlink section:
+Contents of the \.gnu_debugaltlink section.*
   Separate debug info file: linkdebug\.debug
   Build-ID \(0x18 bytes\):
  00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff 01 23 45 67 89 ab cd ef
index fe0334211872a1dc3ebbdc6d8bae2aa85f54a220..c2d03a0e4775f281d06a038a5fcc3b89f6540e5a 100644 (file)
@@ -1,7 +1,8 @@
-Contents of the \.gnu_debuglink section:
+#...
+Contents of the \.gnu_debuglink section.*
   Separate debug info file: this_is_a_debuglink\.debug
   CRC value: 0x12345678
-Contents of the \.gnu_debugaltlink section:
+Contents of the \.gnu_debugaltlink section.*
   Separate debug info file: linkdebug\.debug
   Build-ID \(0x18 bytes\):
  00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff 01 23 45 67 89 ab cd ef