From f940f0c417d196f037763e0425873ba2e0acf475 Mon Sep 17 00:00:00 2001 From: Alexey Samsonov Date: Tue, 19 Feb 2013 11:35:39 +0000 Subject: [PATCH] Fix initialization-order bug in llvm::Support::TimeValue. TimeValue::now() is explicitly called during module initialization of lib/Support/Process.cpp. It reads the field of global object PosixZeroTime, which is not guaranteed to be initialized at this point. Found by AddressSanitizer with -fsanitize=init-order option. llvm-svn: 175509 --- llvm/include/llvm/Support/TimeValue.h | 15 +++++++++------ llvm/lib/Support/TimeValue.cpp | 9 +++++++-- llvm/lib/Support/Unix/TimeValue.inc | 3 ++- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/llvm/include/llvm/Support/TimeValue.h b/llvm/include/llvm/Support/TimeValue.h index fbf6171..4b48b84 100644 --- a/llvm/include/llvm/Support/TimeValue.h +++ b/llvm/include/llvm/Support/TimeValue.h @@ -240,7 +240,7 @@ namespace sys { /// 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_ - PosixZeroTimeSeconds; result += nanos_ / NANOSECONDS_PER_POSIX_TICK; return result; } @@ -248,14 +248,14 @@ namespace sys { /// 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_ - PosixZeroTimeSeconds; } /// 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_ - Win32ZeroTimeSeconds; result += nanos_ / NANOSECONDS_PER_WIN32_TICK; return result; } @@ -264,7 +264,7 @@ namespace sys { /// 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_ - PosixZeroTimeSeconds; nanos = nanos_; } @@ -331,7 +331,7 @@ namespace sys { /// 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 + PosixZeroTimeSeconds; nanos_ = 0; this->normalize(); } @@ -340,7 +340,7 @@ namespace sys { /// 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 + Win32ZeroTimeSeconds; this->nanos_ = NanoSecondsType(win32Time % 10000000) * 100; } @@ -360,6 +360,9 @@ namespace sys { /// Store the values as a . SecondsType seconds_;///< Stores the seconds part of the TimeVal NanoSecondsType nanos_; ///< Stores the nanoseconds part of the TimeVal + + static const SecondsType PosixZeroTimeSeconds; + static const SecondsType Win32ZeroTimeSeconds; /// @} }; diff --git a/llvm/lib/Support/TimeValue.cpp b/llvm/lib/Support/TimeValue.cpp index 1a0f7bc..bd8af17 100644 --- a/llvm/lib/Support/TimeValue.cpp +++ b/llvm/lib/Support/TimeValue.cpp @@ -17,11 +17,16 @@ namespace llvm { using namespace sys; +const TimeValue::SecondsType + TimeValue::PosixZeroTimeSeconds = -946684800; +const TimeValue::SecondsType + TimeValue::Win32ZeroTimeSeconds = -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 ( PosixZeroTimeSeconds,0 ); +const TimeValue TimeValue::Win32ZeroTime = TimeValue ( Win32ZeroTimeSeconds,0 ); void TimeValue::normalize( void ) { diff --git a/llvm/lib/Support/Unix/TimeValue.inc b/llvm/lib/Support/Unix/TimeValue.inc index 5cf5a9d..df8558b 100644 --- a/llvm/lib/Support/Unix/TimeValue.inc +++ b/llvm/lib/Support/Unix/TimeValue.inc @@ -48,7 +48,8 @@ TimeValue TimeValue::now() { } return TimeValue( - static_cast( the_time.tv_sec + PosixZeroTime.seconds_ ), + static_cast( the_time.tv_sec + + PosixZeroTimeSeconds ), static_cast( the_time.tv_usec * NANOSECONDS_PER_MICROSECOND ) ); } -- 2.7.4