summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/debug_on_start.h19
-rw-r--r--base/logging.h3
-rw-r--r--base/message_loop_unittest.cc23
-rw-r--r--base/pe_image.cc11
-rw-r--r--base/pe_image.h4
-rw-r--r--base/thread.cc2
-rw-r--r--base/thread_local_storage_win.cc30
-rw-r--r--base/win_util.cc2
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.