xtime_get unsafe on Windows for IA64

The implementation of the boost::xtime_get() function in libs/thread/src/xtime.cpp includes the following code for Windows: #if defined(BOOST_HAS_FTIME) FILETIME ft; ... const boost::uint64_t TIMESPEC_TO_FILETIME_OFFSET = ((boost::uint64_t)27111902UL << 32) + (boost::uint64_t)3577643008UL; xtp->sec = (int)((*(__int64*)&ft - TIMESPEC_TO_FILETIME_OFFSET) / 10000000); xtp->nsec = (int)((*(__int64*)&ft - TIMESPEC_TO_FILETIME_OFFSET - ((__int64)xtp->sec * (__int64)10000000)) * 100); return clock_type; #elif ... (This is reformatted slightly so that Outlook doesn't screw it up.) The pointer casts are not safe because although the representations of FILETIME and __int64 are compatible, FILETIME is only 32-bit- aligned whereas __int64 must be 64-bit-aligned on IA64 (in some processor modes). One can instead use union { FILETIME ft; __int64 i64; } and read out i64, though I'm not sure this code should be unconditionally using __int64 anyway. There is a longer explanation at <http://weblogs.asp.net/oldnewthing/archive/2004/08/25/220195.aspx>. Ben.

Ben Hutchings wrote:
The implementation of the boost::xtime_get() function in libs/thread/src/xtime.cpp includes the following code for Windows:
#if defined(BOOST_HAS_FTIME) FILETIME ft; ... const boost::uint64_t TIMESPEC_TO_FILETIME_OFFSET = ((boost::uint64_t)27111902UL << 32) + (boost::uint64_t)3577643008UL; xtp->sec = (int)((*(__int64*)&ft - TIMESPEC_TO_FILETIME_OFFSET) / 10000000); xtp->nsec = (int)((*(__int64*)&ft - TIMESPEC_TO_FILETIME_OFFSET - ((__int64)xtp->sec * (__int64)10000000)) * 100); return clock_type; #elif ...
(This is reformatted slightly so that Outlook doesn't screw it up.)
The pointer casts are not safe because although the representations of FILETIME and __int64 are compatible, FILETIME is only 32-bit- aligned whereas __int64 must be 64-bit-aligned on IA64 (in some processor modes).
One can instead use union { FILETIME ft; __int64 i64; } and read out i64, though I'm not sure this code should be unconditionally using __int64 anyway. There is a longer explanation at <http://weblogs.asp.net/oldnewthing/archive/2004/08/25/220195.aspx>.
How about this instead: const boost::uint64_t TIMESPEC_TO_FILETIME_OFFSET = (static_cast<boost::uint64_t>(27111902UL) << 32) + 3577643008UL; const boost::uint64_t ft64 = (static_cast<boost::uint64_t>(ft.dwHighDateTime) << 32) + ft.dwLowDateTime; xtp->sec = static_cast<int>( (ft64 - TIMESPEC_TO_FILETIME_OFFSET) / 10000000 ); xtp->nsec = static_cast<int>(( ft64 - TIMESPEC_TO_FILETIME_OFFSET - (static_cast<boost::uint64_t>(xtp->sec) * 10000000) ) * 100 ); ? Mike
participants (2)
-
Ben Hutchings
-
Michael Glassford