PR 22843: ld, gold: Add --dependency-file option.
authorRoland McGrath <mcgrathr@google.com>
Tue, 23 Jun 2020 19:01:24 +0000 (12:01 -0700)
committerRoland McGrath <mcgrathr@google.com>
Tue, 23 Jun 2020 19:01:24 +0000 (12:01 -0700)
gold/
* options.h (class General_options): Add --dependency-file option.
* fileread.cc (File_read::files_read): New static variable.
(File_read::open): Add the file to the files_read list.
(File_read::record_file_read): New static member function.
(File_read::write_dependency_file): New static member function.
* fileread.h (class File_read): Declare them.
* layout.cc (Layout::read_layout_from_file): Call record_file_read.
(Close_task_runner::run): Call write_dependency_file if
--dependency-file was passed.

ld/
* NEWS: Note --dependency-file.
* ld.texi (Options): Document --dependency-file.
* ldlex.h (enum option_values): Add OPTION_DEPENDENCY_FILE.
* ld.h (ld_config_type): New member dependency_file.
* lexsup.c (ld_options, parse_args): Parse --dependency-file.
* ldmain.c (struct dependency_file): New type.
(dependency_files, dependency_files_tail): New static variables.
(track_dependency_files): New function.
(write_dependency_file): New function.
(main): Call it when --dependency-file was passed.
* ldfile.c (ldfile_try_open_bfd): Call track_dependency_files.
(ldfile_open_command_file_1): Likewise.
* ldelf.c (ldelf_try_needed): Likewise.
* pe-dll.c (pe_implied_import_dll): Likewise.

16 files changed:
gold/ChangeLog
gold/fileread.cc
gold/fileread.h
gold/layout.cc
gold/options.h
ld/ChangeLog
ld/NEWS
ld/ld.h
ld/ld.texi
ld/ldelf.c
ld/ldfile.c
ld/ldlex.h
ld/ldmain.c
ld/ldmain.h
ld/lexsup.c
ld/pe-dll.c

index f4679f9a6468b81e7aff8fa50bf43db780505074..4d524d7f5acf4a037581210797da793f21ea2fd4 100644 (file)
@@ -1,3 +1,16 @@
+2020-06-23  Roland McGrath  <mcgrathr@google.com>
+
+       PR 22843
+       * options.h (class General_options): Add --dependency-file option.
+       * fileread.cc (File_read::files_read): New static variable.
+       (File_read::open): Add the file to the files_read list.
+       (File_read::record_file_read): New static member function.
+       (File_read::write_dependency_file): New static member function.
+       * fileread.h (class File_read): Declare them.
+       * layout.cc (Layout::read_layout_from_file): Call record_file_read.
+       (Close_task_runner::run): Call write_dependency_file if
+       --dependency-file was passed.
+
 2020-06-18  Fangrui Song  <i@maskray.me>
 
        PR gold/26039
index bebe0aba8d08132b4cba10d4ccc696d5f0475f13..f5ca719360d68dee9a851556d76831fb6c637fa2 100644 (file)
@@ -124,6 +124,7 @@ static Initialize_lock file_counts_initialize_lock(&file_counts_lock);
 unsigned long long File_read::total_mapped_bytes;
 unsigned long long File_read::current_mapped_bytes;
 unsigned long long File_read::maximum_mapped_bytes;
+std::vector<std::string> File_read::files_read;
 
 // Class File_read::View.
 
@@ -211,6 +212,8 @@ File_read::open(const Task* task, const std::string& name)
       gold_debug(DEBUG_FILES, "Attempt to open %s succeeded",
                 this->name_.c_str());
       this->token_.add_writer(task);
+      Hold_optional_lock hl(file_counts_lock);
+      record_file_read(this->name_);
     }
 
   return this->descriptor_ >= 0;
@@ -1138,4 +1141,31 @@ Input_file::open_binary(const Task* task, const std::string& name)
                          binary_to_elf.converted_size());
 }
 
+void
+File_read::record_file_read(const std::string& name)
+{
+  File_read::files_read.push_back(name);
+}
+
+void
+File_read::write_dependency_file(const char* dependency_file_name,
+                                const char* output_file_name)
+{
+  FILE *depfile = fopen(dependency_file_name, "w");
+
+  fprintf(depfile, "%s:", output_file_name);
+  for (std::vector<std::string>::const_iterator it = files_read.begin();
+       it != files_read.end();
+       ++it)
+    fprintf(depfile, " \\\n  %s", it->c_str());
+  fprintf(depfile, "\n");
+
+  for (std::vector<std::string>::const_iterator it = files_read.begin();
+       it != files_read.end();
+       ++it)
+    fprintf(depfile, "\n%s:\n", it->c_str());
+
+  fclose(depfile);
+}
+
 } // End namespace gold.
index cf92367c2caa3933793d1e03a6262d277ed3faae..2120135dea0c8fbd3463c5b5abfd72d90db061a7 100644 (file)
@@ -207,6 +207,15 @@ class File_read
   static void
   print_stats();
 
+  // Write the dependency file listing all files read.
+  static void
+  write_dependency_file(const char* dependency_file_name,
+                       const char* output_file_name);
+
+  // Record that a file was read.  File_read::open does this.
+  static void
+  record_file_read(const std::string& name);
+
   // Return the open file descriptor (for plugins).
   int
   descriptor()
@@ -214,7 +223,7 @@ class File_read
     this->reopen_descriptor();
     return this->descriptor_;
   }
-  
+
   // Return the file last modification time.  Calls gold_fatal if the stat
   // system call failed.
   Timespec
@@ -247,6 +256,9 @@ class File_read
   // --stats.
   static unsigned long long maximum_mapped_bytes;
 
+  // Set of names of all files read.
+  static std::vector<std::string> files_read;
+
   // A view into the file.
   class View
   {
index 0c7be85240e4f49389581a4e0b23e98b307bf104..13e533aaf21393ac1717beab1aaeb73dc18f666f 100644 (file)
@@ -1183,11 +1183,11 @@ Layout::layout(Sized_relobj_file<size, big_endian>* object, unsigned int shndx,
       // All ".text.unlikely.*" sections can be moved to a unique
       // segment with --text-unlikely-segment option.
       bool text_unlikely_segment
-          = (parameters->options().text_unlikely_segment()
-             && is_prefix_of(".text.unlikely",
-                             object->section_name(shndx).c_str()));
+         = (parameters->options().text_unlikely_segment()
+            && is_prefix_of(".text.unlikely",
+                            object->section_name(shndx).c_str()));
       if (text_unlikely_segment)
-        {
+       {
          elfcpp::Elf_Xword flags
            = this->get_output_section_flags(shdr.get_sh_flags());
 
@@ -1196,11 +1196,11 @@ Layout::layout(Sized_relobj_file<size, big_endian>* object, unsigned int shndx,
                                                    &name_key);
          os = this->get_output_section(os_name, name_key, sh_type, flags,
                                        ORDER_INVALID, false);
-          // Map this output section to a unique segment.  This is done to
-          // separate "text" that is not likely to be executed from "text"
-          // that is likely executed.
+         // Map this output section to a unique segment.  This is done to
+         // separate "text" that is not likely to be executed from "text"
+         // that is likely executed.
          os->set_is_unique_segment();
-        }
+       }
       else
        {
          // Plugins can choose to place one or more subsets of sections in
@@ -1221,7 +1221,7 @@ Layout::layout(Sized_relobj_file<size, big_endian>* object, unsigned int shndx,
              // We know the name of the output section, directly call
              // get_output_section here by-passing choose_output_section.
              elfcpp::Elf_Xword flags
-               = this->get_output_section_flags(shdr.get_sh_flags());
+               = this->get_output_section_flags(shdr.get_sh_flags());
 
              const char* os_name = it->second->name;
              Stringpool::Key name_key;
@@ -1229,11 +1229,11 @@ Layout::layout(Sized_relobj_file<size, big_endian>* object, unsigned int shndx,
              os = this->get_output_section(os_name, name_key, sh_type, flags,
                                        ORDER_INVALID, false);
              if (!os->is_unique_segment())
-               {
-                 os->set_is_unique_segment();
-                 os->set_extra_segment_flags(it->second->flags);
-                 os->set_segment_alignment(it->second->align);
-               }
+               {
+                 os->set_is_unique_segment();
+                 os->set_extra_segment_flags(it->second->flags);
+                 os->set_segment_alignment(it->second->align);
+               }
            }
          }
       if (os == NULL)
@@ -2268,9 +2268,9 @@ Layout::layout_gnu_property(unsigned int note_type,
       const int size = parameters->target().get_size();
       const bool is_big_endian = parameters->target().is_big_endian();
       if (size == 32)
-        {
-          if (is_big_endian)
-            {
+       {
+         if (is_big_endian)
+           {
 #ifdef HAVE_TARGET_32_BIG
              parameters->sized_target<32, true>()->
                  record_gnu_property(note_type, pr_type, pr_datasz, pr_data,
@@ -2278,9 +2278,9 @@ Layout::layout_gnu_property(unsigned int note_type,
 #else
              gold_unreachable();
 #endif
-            }
-          else
-            {
+           }
+         else
+           {
 #ifdef HAVE_TARGET_32_LITTLE
              parameters->sized_target<32, false>()->
                  record_gnu_property(note_type, pr_type, pr_datasz, pr_data,
@@ -2288,12 +2288,12 @@ Layout::layout_gnu_property(unsigned int note_type,
 #else
              gold_unreachable();
 #endif
-            }
-        }
+           }
+       }
       else if (size == 64)
-        {
-          if (is_big_endian)
-            {
+       {
+         if (is_big_endian)
+           {
 #ifdef HAVE_TARGET_64_BIG
              parameters->sized_target<64, true>()->
                  record_gnu_property(note_type, pr_type, pr_datasz, pr_data,
@@ -2301,9 +2301,9 @@ Layout::layout_gnu_property(unsigned int note_type,
 #else
              gold_unreachable();
 #endif
-            }
-          else
-            {
+           }
+         else
+           {
 #ifdef HAVE_TARGET_64_LITTLE
              parameters->sized_target<64, false>()->
                  record_gnu_property(note_type, pr_type, pr_datasz, pr_data,
@@ -2311,10 +2311,10 @@ Layout::layout_gnu_property(unsigned int note_type,
 #else
              gold_unreachable();
 #endif
-            }
-        }
+           }
+       }
       else
-        gold_unreachable();
+       gold_unreachable();
       return;
     }
 
@@ -2922,6 +2922,8 @@ Layout::read_layout_from_file()
     gold_fatal(_("unable to open --section-ordering-file file %s: %s"),
               filename, strerror(errno));
 
+  File_read::record_file_read(filename);
+
   std::getline(in, line);   // this chops off the trailing \n, if any
   unsigned int position = 1;
   this->set_section_ordering_specified();
@@ -3299,7 +3301,7 @@ Layout::create_gnu_properties_note()
       write_sized_value(datasz, 4, p + 4, is_big_endian);
       memcpy(p + 8, prop->second.pr_data, datasz);
       if (aligned_datasz > datasz)
-        memset(p + 8 + datasz, 0, aligned_datasz - datasz);
+       memset(p + 8 + datasz, 0, aligned_datasz - datasz);
       p += 8 + aligned_datasz;
     }
   Output_section_data* posd = new Output_data_const(desc, descsz, 4);
@@ -6156,6 +6158,10 @@ Close_task_runner::run(Workqueue*, const Task*)
   if (this->options_->oformat_enum() != General_options::OBJECT_FORMAT_ELF)
     this->layout_->write_binary(this->of_);
 
+  if (this->options_->dependency_file())
+    File_read::write_dependency_file(this->options_->dependency_file(),
+                                    this->options_->output_file_name());
+
   this->of_->close();
 }
 
index f0e9fbddcd5f77d6a78a405dcc5ecdbe4f786f17..3c8d25a6628206188260b1272be464c6f0b036f7 100644 (file)
@@ -472,7 +472,7 @@ struct Struct_special : public Struct_var
   options::String_set::const_iterator                                    \
   varname__##_end() const                                                \
   { return this->varname__##_.value.end(); }                              \
-                                                                          \
+                                                                         \
   options::String_set::size_type                                          \
   varname__##_size() const                                                \
   { return this->varname__##_.value.size(); }                             \
@@ -800,6 +800,10 @@ class General_options
              N_("Do not demangle C++ symbols in log messages"),
              NULL);
 
+  DEFINE_string(dependency_file, options::TWO_DASHES, '\0', NULL,
+               N_("Write a dependency file listing all files read"),
+               N_("FILE"));
+
   DEFINE_bool(detect_odr_violations, options::TWO_DASHES, '\0', false,
              N_("Look for violations of the C++ One Definition Rule"),
              N_("Do not look for violations of the C++ One Definition Rule"));
@@ -1501,10 +1505,10 @@ class General_options
   DEFINE_uint64(stack_size, options::DASH_Z, '\0', 0,
                N_("Set PT_GNU_STACK segment p_memsz to SIZE"), N_("SIZE"));
   DEFINE_enum(start_stop_visibility, options::DASH_Z, '\0', "protected",
-              N_("ELF symbol visibility for synthesized "
-                 "__start_* and __stop_* symbols"),
-              ("[default,internal,hidden,protected]"),
-              {"default", "internal", "hidden", "protected"});
+             N_("ELF symbol visibility for synthesized "
+                "__start_* and __stop_* symbols"),
+             ("[default,internal,hidden,protected]"),
+             {"default", "internal", "hidden", "protected"});
   DEFINE_bool(text, options::DASH_Z, '\0', false,
              N_("Do not permit relocations in read-only segments"),
              N_("Permit relocations in read-only segments"));
index a2e3f62e9e76d59496636e58c83fee6035bc82ed..791795661a0ca14d3a55d165ae4d119dc899b98a 100644 (file)
@@ -1,3 +1,21 @@
+2020-06-23  Roland McGrath  <mcgrathr@google.com>
+
+       PR 22843
+       * NEWS: Note --dependency-file.
+       * ld.texi (Options): Document --dependency-file.
+       * ldlex.h (enum option_values): Add OPTION_DEPENDENCY_FILE.
+       * ld.h (ld_config_type): New member dependency_file.
+       * lexsup.c (ld_options, parse_args): Parse --dependency-file.
+       * ldmain.c (struct dependency_file): New type.
+       (dependency_files, dependency_files_tail): New static variables.
+       (track_dependency_files): New function.
+       (write_dependency_file): New function.
+       (main): Call it when --dependency-file was passed.
+       * ldfile.c (ldfile_try_open_bfd): Call track_dependency_files.
+       (ldfile_open_command_file_1): Likewise.
+       * ldelf.c (ldelf_try_needed): Likewise.
+       * pe-dll.c (pe_implied_import_dll): Likewise.
+
 2020-06-23  Alan Modra  <amodra@gmail.com>
 
        PR 26150
diff --git a/ld/NEWS b/ld/NEWS
index 6955937429ba76a09a43be8fe202863d4518f07e..4dd4f3c7528b9b0cd36c7bb220bb8014f0689294 100644 (file)
--- a/ld/NEWS
+++ b/ld/NEWS
 * Add ELF linker command-line option `-z start-stop-visibility=...' to control
   the visibility of synthetic `__start_SECNAME` and `__stop_SECNAME` symbols.
 
+* Add command-line option --dependency-file to write a Make-style dependency
+  file listing the input files consulted by the linker, like the files written
+  by the compiler's -M -MP options.
+
 Changes in 2.34:
 
 * The ld check for "PHDR segment not covered by LOAD segment" is more
diff --git a/ld/ld.h b/ld/ld.h
index 71fd7812677b177b9a9065317c61d2cae18d3e2d..1790dc81a66b61f1da393e054191045ece97516e 100644 (file)
--- a/ld/ld.h
+++ b/ld/ld.h
@@ -286,6 +286,8 @@ typedef struct
   char *map_filename;
   FILE *map_file;
 
+  char *dependency_file;
+
   unsigned int split_by_reloc;
   bfd_size_type split_by_file;
 
index ecdbf775eb3e9669e18b20634c99326beb7d4d0c..40b042de9b958690bf806e578b4e7f1f0a171687 100644 (file)
@@ -893,6 +893,21 @@ Use @var{output} as the name for the program produced by @command{ld}; if this
 option is not specified, the name @file{a.out} is used by default.  The
 script command @code{OUTPUT} can also specify the output file name.
 
+@kindex --dependency-file=@var{depfile}
+@cindex dependency file
+@item --dependency-file=@var{depfile}
+Write a @dfn{dependency file} to @var{depfile}.  This file contains a rule
+suitable for @code{make} describing the output file and all the input files
+that were read to produce it.  The output is similar to the compiler's
+output with @samp{-M -MP} (@pxref{Preprocessor Options,, Options
+Controlling the Preprocessor, gcc.info, Using the GNU Compiler
+Collection}).  Note that there is no option like the compiler's @samp{-MM},
+to exclude ``system files'' (which is not a well-specified concept in the
+linker, unlike ``system headers'' in the compiler).  So the output from
+@samp{--dependency-file} is always specific to the exact state of the
+installation where it was produced, and should not be copied into
+distributed makefiles without careful editing.
+
 @kindex -O @var{level}
 @cindex generating optimized output
 @item -O @var{level}
index 8f2167e8895ef3bdd5029ff2f5c247ad868c3617..6fa09cfe6f15f82d0f6c08d5197e213d69d0acca 100644 (file)
@@ -262,6 +262,8 @@ ldelf_try_needed (struct dt_needed *needed, int force, int is_linux)
       return FALSE;
     }
 
+  track_dependency_files (name);
+
   /* Linker needs to decompress sections.  */
   abfd->flags |= BFD_DECOMPRESS;
 
@@ -1065,7 +1067,7 @@ ldelf_after_open (int use_libpath, int native, int is_linux, int is_freebsd,
        }
       return;
     }
-  
+
   if (!link_info.traditional_format)
     {
       bfd *elfbfd = NULL;
index f3de2c2356a21fc85e3d54c55357dd240ebd3bf0..e39170b5d94d53b491f3536f80e9ed85ed533140 100644 (file)
@@ -142,6 +142,8 @@ ldfile_try_open_bfd (const char *attempt,
       return FALSE;
     }
 
+  track_dependency_files (attempt);
+
   /* Linker needs to decompress sections.  */
   entry->the_bfd->flags |= BFD_DECOMPRESS;
 
@@ -416,21 +418,21 @@ ldfile_open_file (lang_input_statement_type *entry)
       bfd_boolean found = FALSE;
 
       /* If extra_search_path is set, entry->filename is a relative path.
-         Search the directory of the current linker script before searching
-         other paths. */
+        Search the directory of the current linker script before searching
+        other paths. */
       if (entry->extra_search_path)
-        {
-          char *path = concat (entry->extra_search_path, slash, entry->filename,
-                               (const char *)0);
-          if (ldfile_try_open_bfd (path, entry))
-            {
-              entry->filename = path;
-              entry->flags.search_dirs = FALSE;
-              return;
-            }
+       {
+         char *path = concat (entry->extra_search_path, slash, entry->filename,
+                              (const char *)0);
+         if (ldfile_try_open_bfd (path, entry))
+           {
+             entry->filename = path;
+             entry->flags.search_dirs = FALSE;
+             return;
+           }
 
          free (path);
-        }
+       }
 
       /* Try to open <filename><suffix> or lib<filename><suffix>.a.  */
       for (arch = search_arch_head; arch != NULL; arch = arch->next)
@@ -675,6 +677,8 @@ ldfile_open_command_file_1 (const char *name, enum script_open_style open_how)
       return;
     }
 
+  track_dependency_files (name);
+
   lex_push_file (ldlex_input_stack, name, sysrooted);
 
   lineno = 1;
index 7868dca3499016b00c10bd36b31c4230b5522aec..5ea083ebeb302f7fb82c86b7f7c381a5d553edf3 100644 (file)
@@ -154,6 +154,7 @@ enum option_values
   OPTION_NO_PRINT_MAP_DISCARDED,
   OPTION_NON_CONTIGUOUS_REGIONS,
   OPTION_NON_CONTIGUOUS_REGIONS_WARNINGS,
+  OPTION_DEPENDENCY_FILE,
 };
 
 /* The initial parser states.  */
index 94a745ec31592175d9b10ae924df53879c59bcef..08be9030cb57e3835b6ba88b259caf5e7460e873 100644 (file)
@@ -160,6 +160,53 @@ static bfd_error_handler_type default_bfd_error_handler;
 
 struct bfd_link_info link_info;
 \f
+struct dependency_file
+{
+  struct dependency_file *next;
+  char *name;
+};
+
+static struct dependency_file *dependency_files, *dependency_files_tail;
+
+void
+track_dependency_files (const char *filename)
+{
+  struct dependency_file *dep
+    = (struct dependency_file *) xmalloc (sizeof (*dep));
+  dep->name = xstrdup (filename);
+  dep->next = NULL;
+  if (dependency_files == NULL)
+    dependency_files = dep;
+  else
+    dependency_files_tail->next = dep;
+  dependency_files_tail = dep;
+}
+
+static void
+write_dependency_file (void)
+{
+  FILE *out;
+  struct dependency_file *dep;
+
+  out = fopen (config.dependency_file, FOPEN_WT);
+  if (out == NULL)
+    {
+      einfo (_("%F%P: cannot open dependency file %s: %E\n"),
+            config.dependency_file);
+    }
+
+  fprintf (out, "%s:", output_filename);
+
+  for (dep = dependency_files; dep != NULL; dep = dep->next)
+    fprintf (out, " \\\n  %s", dep->name);
+
+  fprintf (out, "\n");
+  for (dep = dependency_files; dep != NULL; dep = dep->next)
+    fprintf (out, "\n%s:\n", dep->name);
+
+  fclose (out);
+}
+\f
 static void
 ld_cleanup (void)
 {
@@ -239,7 +286,7 @@ main (int argc, char **argv)
       /* is_sysrooted_pathname() relies on no trailing dirsep.  */
       if (ld_canon_sysroot_len > 0
          && IS_DIR_SEPARATOR (ld_canon_sysroot [ld_canon_sysroot_len - 1]))
-        ld_canon_sysroot [--ld_canon_sysroot_len] = '\0';
+       ld_canon_sysroot [--ld_canon_sysroot_len] = '\0';
     }
   else
     ld_canon_sysroot_len = -1;
@@ -481,6 +528,9 @@ main (int argc, char **argv)
   ldexp_finish ();
   lang_finish ();
 
+  if (config.dependency_file != NULL)
+    write_dependency_file ();
+
   /* Even if we're producing relocatable output, some non-fatal errors should
      be reported in the exit status.  (What non-fatal errors, if any, do we
      want to ignore for relocatable output?)  */
index 0f05821d1e8a1ecc11da8fed677831d71fa98a4e..ac7db5720d5729d95577fc97008fe95ba7fe5d1e 100644 (file)
@@ -58,5 +58,6 @@ extern void add_ysym (const char *);
 extern void add_wrap (const char *);
 extern void add_ignoresym (struct bfd_link_info *, const char *);
 extern void add_keepsyms_file (const char *);
+extern void track_dependency_files (const char *);
 
 #endif
index 65a945318520ce840b2bd27afab761c017d8a267..48c6eca99fd47e49f9538bdd49bb3ff13e8a4f5b 100644 (file)
@@ -111,6 +111,8 @@ static const struct ld_option ld_options[] =
     'c', N_("FILE"), N_("Read MRI format linker script"), TWO_DASHES },
   { {"dc", no_argument, NULL, 'd'},
     'd', NULL, N_("Force common symbols to be defined"), ONE_DASH },
+  { {"dependency-file", required_argument, NULL, OPTION_DEPENDENCY_FILE},
+    '\0', N_("FILE"), N_("Write dependency file"), TWO_DASHES },
   { {"dp", no_argument, NULL, 'd'},
     '\0', NULL, NULL, ONE_DASH },
   { {"force-group-allocation", no_argument, NULL,
@@ -1441,7 +1443,7 @@ parse_args (unsigned argc, char **argv)
              = lang_new_vers_pattern (NULL, xstrdup (optarg), NULL,
                                       FALSE);
            lang_append_dynamic_list (&export_list, expr);
-          }
+         }
          break;
        case OPTION_EXPORT_DYNAMIC_SYMBOL_LIST:
          /* This option indicates a small script that only specifies
@@ -1631,6 +1633,10 @@ parse_args (unsigned argc, char **argv)
        case OPTION_PRINT_MAP_DISCARDED:
          config.print_map_discarded = TRUE;
          break;
+
+       case OPTION_DEPENDENCY_FILE:
+         config.dependency_file = optarg;
+         break;
        }
     }
 
@@ -1906,14 +1912,14 @@ elf_shlib_list_options (FILE *file)
     }
   fprintf (file, _("\
   -P AUDITLIB, --depaudit=AUDITLIB\n" "\
-                              Specify a library to use for auditing dependencies\n"));
+                             Specify a library to use for auditing dependencies\n"));
   fprintf (file, _("\
   -z combreloc                Merge dynamic relocs into one section and sort\n"));
   fprintf (file, _("\
   -z nocombreloc              Don't merge dynamic relocs into one section\n"));
   fprintf (file, _("\
   -z global                   Make symbols in DSO available for subsequently\n\
-                               loaded objects\n"));
+                              loaded objects\n"));
   fprintf (file, _("\
   -z initfirst                Mark DSO to be initialized first at runtime\n"));
   fprintf (file, _("\
@@ -1936,7 +1942,7 @@ elf_shlib_list_options (FILE *file)
   -z now                      Mark object non-lazy runtime binding\n"));
   fprintf (file, _("\
   -z origin                   Mark object requiring immediate $ORIGIN\n\
-                                processing at runtime\n"));
+                               processing at runtime\n"));
 #if DEFAULT_LD_Z_RELRO
   fprintf (file, _("\
   -z relro                    Create RELRO program header (default)\n"));
@@ -1994,13 +2000,13 @@ elf_static_list_options (FILE *file)
   --build-id[=STYLE]          Generate build ID note\n"));
   fprintf (file, _("\
   --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi]\n\
-                              Compress DWARF debug sections using zlib\n"));
+                             Compress DWARF debug sections using zlib\n"));
 #ifdef DEFAULT_FLAG_COMPRESS_DEBUG
   fprintf (file, _("\
-                               Default: zlib-gabi\n"));
+                              Default: zlib-gabi\n"));
 #else
   fprintf (file, _("\
-                               Default: none\n"));
+                              Default: none\n"));
 #endif
   fprintf (file, _("\
   -z common-page-size=SIZE    Set common page size to SIZE\n"));
@@ -2025,7 +2031,7 @@ elf_plt_unwind_list_options (FILE *file)
   --ld-generated-unwind-info  Generate exception handling info for PLT\n"));
   fprintf (file, _("\
   --no-ld-generated-unwind-info\n\
-                              Don't generate exception handling info for PLT\n"));
+                             Don't generate exception handling info for PLT\n"));
 }
 
 static void
index f72b6583411847ee327049fb48917a0d8b887db8..3e8fe1be9b3071e59fa8f8250ea73509d1f44093 100644 (file)
@@ -3344,6 +3344,8 @@ pe_implied_import_dll (const char *filename)
       return FALSE;
     }
 
+  track_dependency_files (filename);
+
   /* PEI dlls seem to be bfd_objects.  */
   if (!bfd_check_format (dll, bfd_object))
     {