[PATCH] gold: save file mtime in .gnu_incremental_inputs (version 2)

Mikolaj Zalewski mikolajz@google.com
Tue Jun 23 22:15:00 GMT 2009


  In this patch I use st_mtime. However, it should be easy to plug
st_mtim for system that support it - only File_read::mtime() needs to
be changed. As I'd expect that struct timespec is also not portable,
I've defined a custom one for gold.

Mikołaj

2009-06-23  Mikolaj Zalewski  <mikolajz@google.com>

       * fileread.cc (File_read::get_mtime): New method.
       * fileread.h (Timespec): New structure.
       (File_read::get_mtime): New method.
       * incremental.cc
(Incremental_inputs_entry_data::timestamp_usec): Renamed from
timestamp_nsec.
       (Incremental_inputs_entry_write::timestamp_sec): Fix argument
to Elf_Xword.
       (Incremental_inputs_entry_write::timestamp_usec): Renamed from
timestamp_nsec.
       (Incremental_inputs::report_archive): Save mtime; style fix.
       (Incremental_inputs::report_obejct): Save mtime; style fix.
       (Incremental_inputs::report_script): Save mtime; style fix.
       (Incremental_inputs::finalize_inputs): Style fix.
       (Incremental_inputs::finalize): Style fix.
       (Incremental_inputs::create_input_section_data): Store inputs mtime.
       * incremental.h (Incremental_inputs::report_script): Add mtime argument.
       (Incremental_inputs::Input_info::Input_info): Intialize only
one union member.
       (Incremental_inputs::Input_info::archive): Move to nameless union.
       (Incremental_inputs::Input_info::obejct): Move to nameless union.
       (Incremental_inputs::Input_info::script): Move to nameless union.
       (Incremental_inputs::mtime): New field.
       * script.cc (read_input_script): Pass file mtime to Incremental_input.
       * script.h (Script_info::inputs): Style fix.
-------------- next part --------------
From aee584cf558c99aee109bf3d7a256248f8c72a47 Mon Sep 17 00:00:00 2001
From: Mikolaj Zalewski <mikolajz@puchatek.dom>
Date: Mon, 22 Jun 2009 23:05:32 +0200
Subject: [PATCH] gold: save file mtime in .gnu_incremental_inputs

---
 gold/fileread.cc    |   16 ++++++++++++++++
 gold/fileread.h     |   22 ++++++++++++++++++++++
 gold/incremental.cc |   33 +++++++++++++++++++--------------
 gold/incremental.h  |   32 ++++++++++++++++++++------------
 gold/script.cc      |    5 ++++-
 gold/script.h       |    2 +-
 6 files changed, 82 insertions(+), 28 deletions(-)

diff --git a/gold/fileread.cc b/gold/fileread.cc
index a183bd6..10199fe 100644
--- a/gold/fileread.cc
+++ b/gold/fileread.cc
@@ -767,6 +767,22 @@ Input_file::will_search_for() const
 	      || this->input_argument_->extra_search_path() != NULL));
 }
 
+// Return the file last modification time.  Calls gold_fatal if the stat
+// system call failed.
+
+Timespec
+File_read::get_mtime()
+{
+  struct stat file_stat;
+  this->reopen_descriptor();
+  
+  if (fstat(this->descriptor_, &file_stat) == -1)
+    gold_fatal(_("couldn't stat file %s"), this->name_.c_str());
+  // TODO: do a configure check if st_mtim is present and get the
+  // nanoseconds part if it is.
+  return Timespec(file_stat.st_mtime, 0);
+}
+
 // Open the file.
 
 // If the filename is not absolute, we assume it is in the current
diff --git a/gold/fileread.h b/gold/fileread.h
index 4d19824..920a4da 100644
--- a/gold/fileread.h
+++ b/gold/fileread.h
@@ -35,6 +35,23 @@
 namespace gold
 {
 
+// Since not all system supports stat.st_mtim and struct timespec,
+// we define our own structure and fill the nanoseconds if we can.
+
+struct Timespec
+{
+  Timespec()
+    : seconds(0), nanoseconds(0)
+  { }
+
+  Timespec(time_t a_seconds, int a_nanoseconds)
+    : seconds(a_seconds), nanoseconds(a_nanoseconds)
+  { }
+
+  time_t seconds;
+  int nanoseconds;
+};
+
 class Position_dependent_options;
 class Input_file_argument;
 class Dirsearch;
@@ -190,6 +207,11 @@ 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
+  get_mtime();
 
  private:
   // This class may not be copied.
diff --git a/gold/incremental.cc b/gold/incremental.cc
index 7d30c37..e3df264 100644
--- a/gold/incremental.cc
+++ b/gold/incremental.cc
@@ -24,6 +24,7 @@
 #include "elfcpp.h"
 #include "output.h"
 #include "incremental.h"
+#include "archive.h"
 
 using elfcpp::Convert;
 
@@ -65,7 +66,7 @@ struct Incremental_inputs_entry_data
   elfcpp::Elf_Xword timestamp_sec;
 
   // Nano-second part of timestamp (if supported).
-  elfcpp::Elf_Word timestamp_usec;
+  elfcpp::Elf_Word timestamp_nsec;
 
   // Type of the input entry.
   elfcpp::Elf_Half input_type;
@@ -129,12 +130,12 @@ class Incremental_inputs_entry_write
   { this->p_->data_offset = Convert<32, big_endian>::convert_host(v); }
 
   void
-  put_timestamp_sec(elfcpp::Elf_Word v)
-  { this->p_->timestamp_sec = Convert<32, big_endian>::convert_host(v); }
+  put_timestamp_sec(elfcpp::Elf_Xword v)
+  { this->p_->timestamp_sec = Convert<64, big_endian>::convert_host(v); }
 
   void
-  put_timestamp_usec(elfcpp::Elf_Word v)
-  { this->p_->timestamp_usec = Convert<32, big_endian>::convert_host(v); }
+  put_timestamp_nsec(elfcpp::Elf_Word v)
+  { this->p_->timestamp_nsec = Convert<32, big_endian>::convert_host(v); }
 
   void
   put_input_type(elfcpp::Elf_Word v)
@@ -197,7 +198,8 @@ Incremental_inputs::report_archive(const Input_argument* input,
   Input_info info;
   info.type = INCREMENTAL_INPUT_ARCHIVE;
   info.archive = archive;
-  inputs_map_.insert(std::make_pair(input, info));
+  info.mtime = archive->file().get_mtime();
+  this->inputs_map_.insert(std::make_pair(input, info));
 }
 
 // Record that the input argument INPUT is an object OBJ.  This is
@@ -214,7 +216,8 @@ Incremental_inputs::report_object(const Input_argument* input,
 	       ? INCREMENTAL_INPUT_SHARED_LIBRARY
 	       : INCREMENTAL_INPUT_OBJECT);
   info.object = obj;
-  inputs_map_.insert(std::make_pair(input, info));
+  info.mtime = obj->input_file()->file().get_mtime();
+  this->inputs_map_.insert(std::make_pair(input, info));
 }
 
 // Record that the input argument INPUT is an script SCRIPT.  This is
@@ -223,6 +226,7 @@ Incremental_inputs::report_object(const Input_argument* input,
 
 void
 Incremental_inputs::report_script(const Input_argument* input,
+                                  Timespec mtime,
                                   Script_info* script)
 {
   Hold_lock hl(*this->lock_);
@@ -230,7 +234,8 @@ Incremental_inputs::report_script(const Input_argument* input,
   Input_info info;
   info.type = INCREMENTAL_INPUT_SCRIPT;
   info.script = script;
-  inputs_map_.insert(std::make_pair(input, info));
+  info.mtime = mtime;
+  this->inputs_map_.insert(std::make_pair(input, info));
 }
 
 // Compute indexes in the order in which the inputs should appear in
@@ -255,9 +260,9 @@ Incremental_inputs::finalize_inputs(
           continue;
         }
 
-      Inputs_info_map::iterator it = inputs_map_.find(&(*p));
+      Inputs_info_map::iterator it = this->inputs_map_.find(&(*p));
       // TODO: turn it into an assert when the code will be more stable.
-      if (it == inputs_map_.end())
+      if (it == this->inputs_map_.end())
         {
           gold_error("internal error: %s: incremental build info not provided",
 		     (p->is_file() ? p->file().name() : "[group]"));
@@ -286,8 +291,8 @@ Incremental_inputs::finalize()
   finalize_inputs(this->inputs_->begin(), this->inputs_->end(), &index);
 
   // Sanity check.
-  for (Inputs_info_map::const_iterator p = inputs_map_.begin();
-       p != inputs_map_.end();
+  for (Inputs_info_map::const_iterator p = this->inputs_map_.begin();
+       p != this->inputs_map_.end();
        ++p)
     {
       gold_assert(p->second.filename_key != 0);
@@ -364,8 +369,8 @@ Incremental_inputs::sized_create_inputs_section_data()
       // an out-of-bounds offset for future version of gold to reject
       // such an incremental_inputs section.
       entry.put_data_offset(0xffffffff);
-      entry.put_timestamp_sec(0);
-      entry.put_timestamp_usec(0);
+      entry.put_timestamp_sec(it->second.mtime.seconds);
+      entry.put_timestamp_nsec(it->second.mtime.nanoseconds);
       entry.put_input_type(it->second.type);
       entry.put_reserved(0);
     }
diff --git a/gold/incremental.h b/gold/incremental.h
index ed074ae..4342dcc 100644
--- a/gold/incremental.h
+++ b/gold/incremental.h
@@ -28,6 +28,7 @@
 
 #include "stringpool.h"
 #include "workqueue.h"
+#include "fileread.h"
 
 namespace gold
 {
@@ -79,7 +80,8 @@ class Incremental_inputs
 
   // Record that the input argument INPUT is to an script SCRIPT.
   void
-  report_script(const Input_argument* input, Script_info* script);
+  report_script(const Input_argument* input, Timespec mtime,
+                Script_info* script);
 
   // Prepare for layout.  Called from Layout::finalize.
   void
@@ -114,28 +116,34 @@ class Incremental_inputs
   struct Input_info
   {
     Input_info()
-      : type(INCREMENTAL_INPUT_INVALID), archive(NULL), object(NULL),
-        script(NULL), filename_key(0), index(0)
+      : type(INCREMENTAL_INPUT_INVALID), archive(NULL), filename_key(0),
+        index(0)
     { }
 
     // Type of the file pointed by this argument.
     Incremental_input_type type;
 
-    // Present if type == INCREMENTAL_INPUT_ARCHIVE.
-    Archive* archive;
-
-    // Present if type == INCREMENTAL_INPUT_OBJECT or
-    // INCREMENTAL_INPUT_SHARED_LIBRARY.
-    Object* object;
-
-    // Present if type == INCREMENTAL_INPUT_SCRIPT.
-    Script_info* script;
+    union
+    {
+      // Present if type == INCREMENTAL_INPUT_ARCHIVE.
+      Archive* archive;
+  
+      // Present if type == INCREMENTAL_INPUT_OBJECT or
+      // INCREMENTAL_INPUT_SHARED_LIBRARY.
+      Object* object;
+  
+      // Present if type == INCREMENTAL_INPUT_SCRIPT.
+      Script_info* script;
+    };
 
     // Key of the filename string in the section stringtable.
     Stringpool::Key filename_key;
 
     // Position of the entry information in the output section.
     unsigned int index;
+    
+    // Last modification time of the file.
+    Timespec mtime;
   };
 
   typedef std::map<const Input_argument*, Input_info> Inputs_info_map;
diff --git a/gold/script.cc b/gold/script.cc
index 86ce13b..9dcde20 100644
--- a/gold/script.cc
+++ b/gold/script.cc
@@ -1420,7 +1420,10 @@ read_input_script(Workqueue* workqueue, Symbol_table* symtab, Layout* layout,
       // Like new Read_symbols(...) above, we rely on close.inputs()
       // getting leaked by closure.
       Script_info* info = new Script_info(closure.inputs());
-      layout->incremental_inputs()->report_script(input_argument, info);
+      layout->incremental_inputs()->report_script(
+          input_argument,
+          input_file->file().get_mtime(),
+          info);
     }
   *used_next_blocker = true;
 
diff --git a/gold/script.h b/gold/script.h
index 781d24d..755bb79 100644
--- a/gold/script.h
+++ b/gold/script.h
@@ -397,7 +397,7 @@ class Script_info
   // Returns the input files included because of this script.
   Input_arguments*
   inputs()
-  { return inputs_; }
+  { return this->inputs_; }
 
  private:
   Input_arguments* inputs_;
-- 
1.4.4.2



More information about the Binutils mailing list