[PATCH] Fix initialization-order bug in llvm::support::TimeValue

Alexey Samsonov samsonov at google.com
Wed Feb 13 06:09:09 PST 2013


Hi chandlerc,

TimeValue::now() is explicitly called during dynamic
initialization in lib/Support/Process.cpp. It reads the field of
global object PosixZeroTime, which is not guaranteed to be initialized
at this point. This error makes every single LLVM binary built
with "-fsanitize=address,init-order" to fail (in fact, LLVM tree can't
even be built).

http://llvm-reviews.chandlerc.com/D403

Files:
  lib/Support/Unix/TimeValue.inc
  lib/Support/TimeValue.cpp
  include/llvm/Support/TimeValue.h

Index: lib/Support/Unix/TimeValue.inc
===================================================================
--- lib/Support/Unix/TimeValue.inc
+++ lib/Support/Unix/TimeValue.inc
@@ -48,7 +48,8 @@
   }
 
   return TimeValue(
-    static_cast<TimeValue::SecondsType>( the_time.tv_sec + PosixZeroTime.seconds_ ),
+    static_cast<TimeValue::SecondsType>( the_time.tv_sec +
+      posix_zero_time_seconds_ ),
     static_cast<TimeValue::NanoSecondsType>( the_time.tv_usec *
       NANOSECONDS_PER_MICROSECOND ) );
 }
Index: lib/Support/TimeValue.cpp
===================================================================
--- lib/Support/TimeValue.cpp
+++ lib/Support/TimeValue.cpp
@@ -17,11 +17,16 @@
 namespace llvm {
 using namespace sys;
 
+const TimeValue::SecondsType
+  TimeValue::posix_zero_time_seconds_ = -946684800;
+const TimeValue::SecondsType
+  TimeValue::win32_zero_time_seconds_ = -12591158400ULL;
+
 const TimeValue TimeValue::MinTime       = TimeValue ( INT64_MIN,0 );
 const TimeValue TimeValue::MaxTime       = TimeValue ( INT64_MAX,0 );
 const TimeValue TimeValue::ZeroTime      = TimeValue ( 0,0 );
-const TimeValue TimeValue::PosixZeroTime = TimeValue ( -946684800,0 );
-const TimeValue TimeValue::Win32ZeroTime = TimeValue ( -12591158400ULL,0 );
+const TimeValue TimeValue::PosixZeroTime = TimeValue ( posix_zero_time_seconds_,0 );
+const TimeValue TimeValue::Win32ZeroTime = TimeValue ( win32_zero_time_seconds_,0 );
 
 void
 TimeValue::normalize( void ) {
Index: include/llvm/Support/TimeValue.h
===================================================================
--- include/llvm/Support/TimeValue.h
+++ include/llvm/Support/TimeValue.h
@@ -240,31 +240,31 @@
     /// Posix, correcting for the difference in Posix zero time.
     /// @brief Convert to unix time (100 nanoseconds since 12:00:00a Jan 1,1970)
     uint64_t toPosixTime() const {
-      uint64_t result = seconds_ - PosixZeroTime.seconds_;
+      uint64_t result = seconds_ - posix_zero_time_seconds_;
       result += nanos_ / NANOSECONDS_PER_POSIX_TICK;
       return result;
     }
 
     /// Converts the TimeValue into the corresponding number of seconds
     /// since the epoch (00:00:00 Jan 1,1970).
     uint64_t toEpochTime() const {
-      return seconds_ - PosixZeroTime.seconds_;
+      return seconds_ - posix_zero_time_seconds_;
     }
 
     /// Converts the TimeValue into the corresponding number of "ticks" for
     /// Win32 platforms, correcting for the difference in Win32 zero time.
     /// @brief Convert to windows time (seconds since 12:00:00a Jan 1, 1601)
     uint64_t toWin32Time() const {
-      uint64_t result = seconds_ - Win32ZeroTime.seconds_;
+      uint64_t result = seconds_ - win32_zero_time_seconds_;
       result += nanos_ / NANOSECONDS_PER_WIN32_TICK;
       return result;
     }
 
     /// Provides the seconds and nanoseconds as results in its arguments after
     /// correction for the Posix zero time.
     /// @brief Convert to timespec time (ala POSIX.1b)
     void getTimespecTime( uint64_t& seconds, uint32_t& nanos ) const {
-      seconds = seconds_ - PosixZeroTime.seconds_;
+      seconds = seconds_ - posix_zero_time_seconds_;
       nanos = nanos_;
     }
 
@@ -331,16 +331,16 @@
     /// TimeValue and assigns that value to \p this.
     /// @brief Convert seconds form PosixTime to TimeValue
     void fromEpochTime( SecondsType seconds ) {
-      seconds_ = seconds + PosixZeroTime.seconds_;
+      seconds_ = seconds + posix_zero_time_seconds_;
       nanos_ = 0;
       this->normalize();
     }
 
     /// Converts the \p win32Time argument from Windows FILETIME to the
     /// corresponding TimeValue and assigns that value to \p this.
     /// @brief Convert seconds form Windows FILETIME to TimeValue
     void fromWin32Time( uint64_t win32Time ) {
-      this->seconds_ = win32Time / 10000000 + Win32ZeroTime.seconds_;
+      this->seconds_ = win32Time / 10000000 + win32_zero_time_seconds_;
       this->nanos_ = NanoSecondsType(win32Time  % 10000000) * 100;
     }
 
@@ -360,6 +360,9 @@
     /// Store the values as a <timeval>.
     SecondsType      seconds_;///< Stores the seconds part of the TimeVal
     NanoSecondsType  nanos_;  ///< Stores the nanoseconds part of the TimeVal
+
+    static const SecondsType posix_zero_time_seconds_;
+    static const SecondsType win32_zero_time_seconds_;
   /// @}
 
   };
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D403.1.patch
Type: text/x-patch
Size: 4369 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130213/dadc9edd/attachment.bin>


More information about the llvm-commits mailing list