15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Windows doesn't support pthread_key_create's destr_function, and in fact 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it's a bit tricky to get code to run when a thread exits. This is 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cargo-cult magic from http://www.codeproject.com/threads/tls.asp. 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We are trying to be compatible with both a LoadLibrary style invocation, as 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// well as static linking. This code only needs to be included if we use 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LoadLibrary, but it hooks into the "standard" set of TLS callbacks that are 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// provided for static linking. 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This code is deliberately written to match the style of calls seen in 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// base/threading/thread_local_storage_win.cc. Please keep the two in sync if 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// coding conventions are changed. 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WARNING: Do *NOT* try to include this in the construction of the base 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// library, even though it potentially drives code in 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// base/threading/thread_local_storage_win.cc. If you do, some users will end 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// up getting duplicate definition of DllMain() in some of their later links. 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Force a reference to _tls_used to make the linker create the TLS directory 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if it's not already there (that is, even if __declspec(thread) is not used). 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Force a reference to p_thread_callback_dllmain_typical_entry to prevent whole 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// program optimization from discarding the variables. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h> 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/win_util.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Indicate if another service is scanning the callbacks. When this becomes 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// set to true, then DllMain() will stop supporting the callback service. This 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// value is set to true the first time any of our callbacks are called, as that 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// shows that some other service is handling callbacks. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool linker_notifications_are_active = false; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This will be our mostly no-op callback that we'll list. We won't 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// deliberately call it, and if it is called, that means we don't need to do any 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of the callbacks anymore. We expect such a call to arrive via a 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THREAD_ATTACH message, long before we'd have to perform our THREAD_DETACH 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// callbacks. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void NTAPI on_callback(PVOID h, DWORD reason, PVOID reserved); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _WIN64 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma comment(linker, "/INCLUDE:_tls_used") 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma comment(linker, "/INCLUDE:p_thread_callback_dllmain_typical_entry") 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else // _WIN64 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma comment(linker, "/INCLUDE:__tls_used") 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma comment(linker, "/INCLUDE:_p_thread_callback_dllmain_typical_entry") 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // _WIN64 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 57010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Explicitly depend on VC\crt\src\tlssup.c variables 58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// to bracket the list of TLS callbacks. 59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)extern "C" PIMAGE_TLS_CALLBACK __xl_a, __xl_z; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// extern "C" suppresses C++ name mangling so we know the symbol names for the 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// linker /INCLUDE:symbol pragmas above. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern "C" { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _WIN64 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// .CRT section is merged with .rdata on x64 so it must be constant data. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma data_seg(push, old_seg) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use a typical possible name in the .CRT$XL? list of segments. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma const_seg(".CRT$XLB") 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// When defining a const variable, it must have external linkage to be sure the 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// linker doesn't discard it. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const PIMAGE_TLS_CALLBACK p_thread_callback_dllmain_typical_entry; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const PIMAGE_TLS_CALLBACK p_thread_callback_dllmain_typical_entry = on_callback; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma data_seg(pop, old_seg) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else // _WIN64 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma data_seg(push, old_seg) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use a typical possible name in the .CRT$XL? list of segments. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma data_seg(".CRT$XLB") 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PIMAGE_TLS_CALLBACK p_thread_callback_dllmain_typical_entry = on_callback; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma data_seg(pop, old_seg) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // _WIN64 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // extern "C" 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 87b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Custom crash code to get a unique entry in crash reports. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NOINLINE static void CrashOnProcessDetach() { 89b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) *static_cast<volatile int*>(0) = 0x356; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make DllMain call the listed callbacks. This way any third parties that are 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// linked in will also be called. 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BOOL WINAPI DllMain(PVOID h, DWORD reason, PVOID reserved) { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (DLL_PROCESS_DETACH == reason && base::win::ShouldCrashOnProcessDetach()) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CrashOnProcessDetach(); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (DLL_THREAD_DETACH != reason && DLL_PROCESS_DETACH != reason) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; // We won't service THREAD_ATTACH calls. 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (linker_notifications_are_active) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; // Some other service is doing this work. 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (PIMAGE_TLS_CALLBACK* it = &__xl_a; it < &__xl_z; ++it) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*it == NULL || *it == on_callback) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; // Don't bother to call our own callback. 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*it)(h, reason, reserved); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void NTAPI on_callback(PVOID h, DWORD reason, PVOID reserved) { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do nothing. We were just a place holder in the list used to test that we 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // call all items. 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we are called, it means that some other system is scanning the callbacks 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and we don't need to do so in DllMain(). 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) linker_notifications_are_active = true; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: If some other routine some how plays this same game... we could both 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // decide not to do the scanning <sigh>, but this trick should suppress 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // duplicate calls on Vista, where the runtime takes care of the callbacks, 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and allow us to do the callbacks on XP, where we are currently devoid of 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // callbacks (due to an explicit LoadLibrary call). 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 124