summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorwtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-23 01:48:08 +0000
committerwtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-23 01:48:08 +0000
commitce53c9e6d9b9211f853e0d6f426a12b0bab6a875 (patch)
treeb3442d07d630c501138f2dd159a74d9f85a7b0f5 /base
parent12a601cb8b1fdbbb630ab86063f9e6f36125027c (diff)
downloadchromium_src-ce53c9e6d9b9211f853e0d6f426a12b0bab6a875.zip
chromium_src-ce53c9e6d9b9211f853e0d6f426a12b0bab6a875.tar.gz
chromium_src-ce53c9e6d9b9211f853e0d6f426a12b0bab6a875.tar.bz2
Use the /INCLUDE:symbol linker option pragmas to force
references to the magic variables we added to the data segment for TLS callbacks. The references prevent whole program optimization from optimizing away those variables. This requires three changes: 1) the variables cannot be declared as static. 2) the variables must be declared extern "C" to suppress C++ name mangling. 3) the variables cannot have the same name. R=jar,maruel BUG=40663 TEST=none Review URL: http://codereview.chromium.org/1752004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@45405 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r--base/thread_local_storage_win.cc30
1 files changed, 19 insertions, 11 deletions
diff --git a/base/thread_local_storage_win.cc b/base/thread_local_storage_win.cc
index 361167e..7f8ea27 100644
--- a/base/thread_local_storage_win.cc
+++ b/base/thread_local_storage_win.cc
@@ -129,23 +129,24 @@ void ThreadLocalStorage::ThreadExit() {
// This magic is from http://www.codeproject.com/threads/tls.asp
// and it works for VC++ 7.0 and later.
+// Force a reference to _tls_used to make the linker create the TLS directory
+// if it's not already there. (e.g. if __declspec(thread) is not used).
+// Force a reference to p_thread_callback_base to prevent whole program
+// optimization from discarding the variable.
#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")
+#pragma comment(linker, "/INCLUDE:p_thread_callback_base")
#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")
+#pragma comment(linker, "/INCLUDE:_p_thread_callback_base")
#endif // _WIN64
// Static callback function to call with each thread termination.
-void NTAPI OnThreadExit(PVOID module, DWORD reason, PVOID reserved)
-{
+void NTAPI OnThreadExit(PVOID module, DWORD reason, PVOID reserved) {
// On XP SP0 & SP1, the DLL_PROCESS_ATTACH is never seen. It is sent on SP2+
// and on W2K and W2K3. So don't assume it is sent.
if (DLL_THREAD_DETACH == reason || DLL_PROCESS_DETACH == reason)
@@ -162,15 +163,21 @@ void NTAPI OnThreadExit(PVOID module, DWORD reason, PVOID reserved)
// implicitly loaded.
//
// See VC\crt\src\tlssup.c for reference.
+
+// extern "C" suppresses C++ name mangling so we know the symbol name for the
+// linker /INCLUDE:symbol pragma above.
+extern "C" {
+// The linker must not discard p_thread_callback_base. (We force a reference
+// to this variable with a linker /INCLUDE:symbol pragma to ensure that.) If
+// this variable is discarded, the OnThreadExit function will never be called.
#ifdef _WIN64
// .CRT section is merged with .rdata on x64 so it must be constant data.
#pragma const_seg(".CRT$XLB")
// When defining a const variable, it must have external linkage to be sure the
-// linker doesn't discard it. If this value is discarded, the OnThreadExit
-// function will never be called.
-extern const PIMAGE_TLS_CALLBACK p_thread_callback;
-const PIMAGE_TLS_CALLBACK p_thread_callback = OnThreadExit;
+// linker doesn't discard it.
+extern const PIMAGE_TLS_CALLBACK p_thread_callback_base;
+const PIMAGE_TLS_CALLBACK p_thread_callback_base = OnThreadExit;
// Reset the default section.
#pragma const_seg()
@@ -178,9 +185,10 @@ const PIMAGE_TLS_CALLBACK p_thread_callback = OnThreadExit;
#else // _WIN64
#pragma data_seg(".CRT$XLB")
-PIMAGE_TLS_CALLBACK p_thread_callback = OnThreadExit;
+PIMAGE_TLS_CALLBACK p_thread_callback_base = OnThreadExit;
// Reset the default section.
#pragma data_seg()
#endif // _WIN64
+} // extern "C"