diff options
-rw-r--r-- | base/debug_on_start.h | 19 | ||||
-rw-r--r-- | base/logging.h | 3 | ||||
-rw-r--r-- | base/message_loop_unittest.cc | 23 | ||||
-rw-r--r-- | base/pe_image.cc | 11 | ||||
-rw-r--r-- | base/pe_image.h | 4 | ||||
-rw-r--r-- | base/thread.cc | 2 | ||||
-rw-r--r-- | base/thread_local_storage_win.cc | 30 | ||||
-rw-r--r-- | base/win_util.cc | 2 |
8 files changed, 80 insertions, 14 deletions
diff --git a/base/debug_on_start.h b/base/debug_on_start.h index 87afe9b..b260122 100644 --- a/base/debug_on_start.h +++ b/base/debug_on_start.h @@ -62,14 +62,29 @@ class DebugOnStart { // theory it should be called before any user created global variable // initialization code and CRT initialization code. // Note: See VC\crt\src\defsects.inc and VC\crt\src\crt0.c for reference. +#ifdef _WIN64 -// "Fix" the data section. +// "Fix" the segment. On x64, the .CRT segment is merged into the .rdata segment +// so it constains const data only. +#pragma const_seg(push, ".CRT$XIB") +// Declare the pointer so the CRT will find it. +extern const DebugOnStart::PIFV debug_on_start; +DECLSPEC_SELECTANY const DebugOnStart::PIFV debug_on_start = + &DebugOnStart::Init; +// Fix back the segment. +#pragma const_seg(pop) + +#else // _WIN64 + +// "Fix" the segment. On x86, the .CRT segment is merged into the .data segment +// so it constains non-const data only. #pragma data_seg(push, ".CRT$XIB") // Declare the pointer so the CRT will find it. DECLSPEC_SELECTANY DebugOnStart::PIFV debug_on_start = &DebugOnStart::Init; -// Fix back the data segment. +// Fix back the segment. #pragma data_seg(pop) +#endif // _WIN64 #endif // _WIN32 #endif // BASE_DEBUG_ON_START_H__ diff --git a/base/logging.h b/base/logging.h index 615b1e0..40c176f 100644 --- a/base/logging.h +++ b/base/logging.h @@ -480,7 +480,8 @@ class LogMessage { LogSeverity severity_; std::ostringstream stream_; - int message_start_; // offset of the start of the message (past prefix info). + size_t message_start_; // Offset of the start of the message (past prefix + // info). DISALLOW_EVIL_CONSTRUCTORS(LogMessage); }; diff --git a/base/message_loop_unittest.cc b/base/message_loop_unittest.cc index 374a618..6c71c5b0 100644 --- a/base/message_loop_unittest.cc +++ b/base/message_loop_unittest.cc @@ -201,10 +201,22 @@ class CrasherTask : public Task { ::SetUnhandledExceptionFilter(&BadExceptionHandler); // Generate a SEH fault. We do it in asm to make sure we know how to undo // the damage. + +#if defined(_M_IX86) + __asm { mov eax, dword ptr [CrasherTask::bad_array_] mov byte ptr [eax], 66 } + +#elif defined(_M_X64) + + bad_array_[0] = 66; + +#elif + +#endif + MessageLoop::current()->Quit(); } // Points the bad array to a valid memory location. @@ -229,7 +241,17 @@ LONG WINAPI HandleCrasherTaskException(EXCEPTION_POINTERS *ex_info) { return EXCEPTION_EXECUTE_HANDLER; CrasherTask::FixError(); + +#if defined(_M_IX86) + ex_info->ContextRecord->Eip -= 5; + +#elif defined(_M_X64) + + ex_info->ContextRecord->Rip -= 5; + +#endif + return EXCEPTION_CONTINUE_EXECUTION; } @@ -267,6 +289,7 @@ TEST(MessageLoopTest, CrasherNasty) { ::SetUnhandledExceptionFilter(old_SEH_filter); } + TEST(MessageLoopTest, Nesting) { int depth = 100; MessageLoop::current()->PostTask(FROM_HERE, new NestingTest(&depth)); diff --git a/base/pe_image.cc b/base/pe_image.cc index b50bca5..d060903 100644 --- a/base/pe_image.cc +++ b/base/pe_image.cc @@ -32,6 +32,13 @@ #include "base/pe_image.h" +#ifdef _WIN64 +#error This code is not tested on x64. Please make sure all the base unit tests\ + pass before doing any real work. The current unit tests don't test the\ + differences between 32- and 64-bits implementations. Bugs may slip through.\ + You need to improve the coverage before continuing. +#endif + // Structure to perform imports enumerations. struct EnumAllImportsStorage { PEImage::EnumImportsFunction callback; @@ -539,14 +546,14 @@ bool PEImage::ImageAddrToOnDiskOffset(LPVOID address, return true; } -PVOID PEImage::RVAToAddr(DWORD rva) const { +PVOID PEImage::RVAToAddr(DWORD_PTR rva) const { if (rva == 0) return NULL; return reinterpret_cast<char*>(module_) + rva; } -PVOID PEImageAsData::RVAToAddr(DWORD rva) const { +PVOID PEImageAsData::RVAToAddr(DWORD_PTR rva) const { if (rva == 0) return NULL; diff --git a/base/pe_image.h b/base/pe_image.h index a8ff941..225376d 100644 --- a/base/pe_image.h +++ b/base/pe_image.h @@ -230,7 +230,7 @@ class PEImage { bool VerifyMagic() const; // Converts an rva value to the appropriate address. - virtual PVOID RVAToAddr(DWORD rva) const; + virtual PVOID RVAToAddr(DWORD_PTR rva) const; // Converts an rva value to an offset on disk. // Returns true on success. @@ -250,7 +250,7 @@ class PEImageAsData : public PEImage { public: explicit PEImageAsData(HMODULE hModule) : PEImage(hModule) {} - virtual PVOID RVAToAddr(DWORD rva) const; + virtual PVOID RVAToAddr(DWORD_PTR rva) const; }; inline bool PEImage::IsOrdinal(LPCSTR name) { diff --git a/base/thread.cc b/base/thread.cc index 6908b9f..cec558b 100644 --- a/base/thread.cc +++ b/base/thread.cc @@ -138,7 +138,7 @@ void Thread::SetThreadName(const char* name, DWORD tid) { __try { RaiseException(MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(DWORD), - reinterpret_cast<DWORD*>(&info)); + reinterpret_cast<DWORD_PTR *>(&info)); } __except(EXCEPTION_CONTINUE_EXECUTION) { } } diff --git a/base/thread_local_storage_win.cc b/base/thread_local_storage_win.cc index 7fba9ef..4d56b08 100644 --- a/base/thread_local_storage_win.cc +++ b/base/thread_local_storage_win.cc @@ -27,10 +27,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include <windows.h> - #include "base/thread_local_storage.h" +#include <windows.h> + #include "base/logging.h" // In order to make TLS destructors work, we need to keep function @@ -144,10 +144,20 @@ void ThreadLocalStorage::ThreadExit() { // This magic is from http://www.codeproject.com/threads/tls.asp // and it works for VC++ 7.0 and later. +#ifdef _WIN64 + +// This makes the linker create the TLS directory if it's not already +// there. (e.g. if __declspec(thread) is not used). +#pragma comment(linker, "/INCLUDE:_tls_used") + +#else // _WIN64 + // This makes the linker create the TLS directory if it's not already // there. (e.g. if __declspec(thread) is not used). #pragma comment(linker, "/INCLUDE:__tls_used") +#endif // _WIN64 + // Static callback function to call with each thread termination. void NTAPI OnThreadExit(PVOID module, DWORD reason, PVOID reserved) { @@ -157,9 +167,6 @@ void NTAPI OnThreadExit(PVOID module, DWORD reason, PVOID reserved) ThreadLocalStorage::ThreadExit(); } -// Note: .CRT section get merged with .rdata on x64 so it should be constant -// data. -// // .CRT$XLA to .CRT$XLZ is an array of PIMAGE_TLS_CALLBACK pointers that are // called automatically by the OS loader code (not the CRT) when the module is // loaded and on thread creation. They are NOT called if the module has been @@ -170,8 +177,21 @@ void NTAPI OnThreadExit(PVOID module, DWORD reason, PVOID reserved) // implicitly loaded. // // See VC\crt\src\tlssup.c for reference. +#ifdef _WIN64 + +// .CRT section is merged with .rdata on x64 so it must be constant data. +#pragma const_seg(".CRT$XLB") +const PIMAGE_TLS_CALLBACK p_thread_callback = OnThreadExit; + +// Reset the default section. +#pragma const_seg() + +#else // _WIN64 + #pragma data_seg(".CRT$XLB") PIMAGE_TLS_CALLBACK p_thread_callback = OnThreadExit; // Reset the default section. #pragma data_seg() + +#endif // _WIN64
\ No newline at end of file diff --git a/base/win_util.cc b/base/win_util.cc index 478a5a6..a5b46f5 100644 --- a/base/win_util.cc +++ b/base/win_util.cc @@ -345,7 +345,7 @@ bool UserAccountControlIsEnabled() { // If the ASSERT below fails, please install Visual Studio 2005 Service Pack 1. // extern char VisualStudio2005ServicePack1Detection[10]; -COMPILE_ASSERT(sizeof(&VisualStudio2005ServicePack1Detection) == 4, +COMPILE_ASSERT(sizeof(&VisualStudio2005ServicePack1Detection) == sizeof(void*), VS2005SP1Detect); // // Chrome requires at least Service Pack 1 for Visual Studio 2005. |