[compiler-rt] r286290 - [asan/win] Add init hooks to .CRT$XLAB

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 8 17:27:01 PST 2016


If someone could pacify the overzealous lint check that doesn't run on
Windows, I'd appreciate it, I'm on a train. Thanks!

Sent from phone

On Nov 8, 2016 4:06 PM, "Juergen Ributzka" <juergen at ributzka.de> wrote:

> Hi Reid,
>
> could you please take a look at this bot:  http://lab.llvm.org:
> 8080/green/job/clang-stage2-configure-Rlto_check/9576/
> consoleFull#-15796076f80f5c9c-2aaa-47fb-b15d-be39b7128d72 ?
>
> This is failing the SanitizerLintCheck.
>
> Thanks
>
> Cheers,
> Juergen
>
> On Nov 8, 2016, at 12:45 PM, Reid Kleckner via llvm-commits <
> llvm-commits at lists.llvm.org> wrote:
>
> Author: rnk
> Date: Tue Nov  8 14:45:45 2016
> New Revision: 286290
>
> URL: http://llvm.org/viewvc/llvm-project?rev=286290&view=rev
> Log:
> [asan/win] Add init hooks to .CRT$XLAB
>
> Summary:
> User applications may register hooks in the .CRT$XL* callback list,
> which is called very early by the loader. This is very common in
> Chromium:
> https://cs.chromium.org/search/?q=CRT.XL&sq=package:chromium&type=cs
>
> This has flown under the radar for a long time because the loader
> appears to catch exceptions originating from these callbacks. It's a
> real problem when you're debugging an asan application, though, since it
> makes the program crash early.
>
> The solution is to add our own callback to this list, and sort it very
> early in the list like we do elsewhere. Also add a test with such an
> instrumented callback, and test that it gets called with asan.
>
> Reviewers: etienneb
>
> Subscribers: llvm-commits, kubabrecka
>
> Differential Revision: https://reviews.llvm.org/D26404
>
> Added:
>    compiler-rt/trunk/test/asan/TestCases/Windows/tls_init.cc
> Modified:
>    compiler-rt/trunk/lib/asan/asan_win.cc
>    compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc
>    compiler-rt/trunk/lib/asan/asan_win_dynamic_runtime_thunk.cc
>
> Modified: compiler-rt/trunk/lib/asan/asan_win.cc
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/
> asan/asan_win.cc?rev=286290&r1=286289&r2=286290&view=diff
> ============================================================
> ==================
> --- compiler-rt/trunk/lib/asan/asan_win.cc (original)
> +++ compiler-rt/trunk/lib/asan/asan_win.cc Tue Nov  8 14:45:45 2016
> @@ -343,9 +343,23 @@ int __asan_set_seh_filter() {
> // immediately after the CRT runs. This way, our exception filter is called
> // first and we can delegate to their filter if appropriate.
> #pragma section(".CRT$XCAB", long, read)  // NOLINT
> -__declspec(allocate(".CRT$XCAB"))
> -    int (*__intercept_seh)() = __asan_set_seh_filter;
> +__declspec(allocate(".CRT$XCAB")) int (*__intercept_seh)() =
> +    __asan_set_seh_filter;
> +
> +// Piggyback on the TLS initialization callback directory to initialize
> asan as
> +// early as possible. Initializers in .CRT$XL* are called directly by
> ntdll,
> +// which run before the CRT. Users also add code to .CRT$XLC, so it's
> important
> +// to run our initializers first.
> +static void NTAPI asan_thread_init(void *module, DWORD reason, void
> *reserved) {
> +  if (reason == DLL_PROCESS_ATTACH) __asan_init();
> +}
> +
> +#pragma section(".CRT$XLAB", long, read)  // NOLINT
> +__declspec(allocate(".CRT$XLAB")) void (NTAPI *__asan_tls_init)(
> +    void *, unsigned long, void *) = asan_thread_init;
> #endif
> +
> +
> // }}}
> }  // namespace __asan
>
>
> Modified: compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/
> asan/asan_win_dll_thunk.cc?rev=286290&r1=286289&r2=286290&view=diff
> ============================================================
> ==================
> --- compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc (original)
> +++ compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc Tue Nov  8 14:45:45
> 2016
> @@ -456,4 +456,19 @@ static int call_asan_init() {
> #pragma section(".CRT$XIB", long, read)  // NOLINT
> __declspec(allocate(".CRT$XIB")) int (*__asan_preinit)() = call_asan_init;
>
> +#ifdef _M_IX86
> +#define NTAPI __stdcall
> +#else
> +#define NTAPI
> +#endif
> +
> +static void NTAPI asan_thread_init(void *mod, unsigned long reason,
> +                                   void *reserved) {
> +  if (reason == /*DLL_PROCESS_ATTACH=*/1) __asan_init();
> +}
> +
> +#pragma section(".CRT$XLAB", long, read)  // NOLINT
> +__declspec(allocate(".CRT$XLAB")) void (NTAPI *__asan_tls_init)(
> +    void *, unsigned long, void *) = asan_thread_init;
> +
> #endif // ASAN_DLL_THUNK
>
> Modified: compiler-rt/trunk/lib/asan/asan_win_dynamic_runtime_thunk.cc
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/
> asan/asan_win_dynamic_runtime_thunk.cc?rev=286290&r1=286289&
> r2=286290&view=diff
> ============================================================
> ==================
> --- compiler-rt/trunk/lib/asan/asan_win_dynamic_runtime_thunk.cc
> (original)
> +++ compiler-rt/trunk/lib/asan/asan_win_dynamic_runtime_thunk.cc Tue Nov
>  8 14:45:45 2016
> @@ -33,6 +33,7 @@
> #pragma section(".CRT$XCAB", long, read)  // NOLINT
> #pragma section(".CRT$XTW", long, read)  // NOLINT
> #pragma section(".CRT$XTY", long, read)  // NOLINT
> +#pragma section(".CRT$XLAB", long, read)  // NOLINT
>
> ////////////////////////////////////////////////////////////
> ////////////////////
> // Define a copy of __asan_option_detect_stack_use_after_return that
> should be
> @@ -61,9 +62,17 @@ static int InitializeClonedVariables() {
>   return 0;
> }
>
> -// Our cloned variables must be initialized before C/C++ constructors.
> -__declspec(allocate(".CRT$XIB"))
> -int (*__asan_initialize_cloned_variables)() = InitializeClonedVariables;
> +static void NTAPI asan_thread_init(void *mod, unsigned long reason, void
> *reserved) {
> +  if (reason == DLL_PROCESS_ATTACH) InitializeClonedVariables();
> +}
> +
> +// Our cloned variables must be initialized before C/C++ constructors.
> If TLS
> +// is used, our .CRT$XLAB initializer will run first. If not, our .CRT$XIB
> +// initializer is needed as a backup.
> +__declspec(allocate(".CRT$XIB")) int (*__asan_initialize_cloned_variables)()
> =
> +    InitializeClonedVariables;
> +__declspec(allocate(".CRT$XLAB")) void (NTAPI *__asan_tls_init)(
> +    void *, unsigned long, void *) = asan_thread_init;
>
> ////////////////////////////////////////////////////////////
> ////////////////////
> // For some reason, the MD CRT doesn't call the C/C++ terminators during
> on DLL
>
> Added: compiler-rt/trunk/test/asan/TestCases/Windows/tls_init.cc
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/
> test/asan/TestCases/Windows/tls_init.cc?rev=286290&view=auto
> ============================================================
> ==================
> --- compiler-rt/trunk/test/asan/TestCases/Windows/tls_init.cc (added)
> +++ compiler-rt/trunk/test/asan/TestCases/Windows/tls_init.cc Tue Nov  8
> 14:45:45 2016
> @@ -0,0 +1,51 @@
> +// RUN: %clang_cl_asan %s -Fe%t.exe
> +// RUN: %run %t.exe | FileCheck %s
> +
> +// CHECK: my_thread_callback
> +// CHECK: ran_before_main: 1
> +
> +#include <windows.h>
> +#include <stdio.h>
> +#include <string.h>
> +
> +#pragma comment (lib, "dbghelp")
> +
> +static bool ran_before_main = false;
> +
> +extern "C" void __asan_init(void);
> +
> +static void NTAPI /*__attribute__((no_sanitize_address))*/
> +my_thread_callback(PVOID module, DWORD reason, PVOID reserved) {
> +  ran_before_main = true;
> +  static const char str[] = "my_thread_callback\n";
> +
> +  // Fail the test if we aren't called for the expected reason or we
> can't write
> +  // stdout.
> +  if (reason != DLL_PROCESS_ATTACH)
> +    return;
> +  HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
> +  if (!out || out == INVALID_HANDLE_VALUE)
> +    return;
> +
> +  DWORD written = 0;
> +  WriteFile(out, &str[0], sizeof(str), &written, NULL);
> +}
> +
> +extern "C" {
> +#pragma const_seg(".CRT$XLC")
> +extern const PIMAGE_TLS_CALLBACK p_thread_callback;
> +const PIMAGE_TLS_CALLBACK p_thread_callback = my_thread_callback;
> +#pragma const_seg()
> +}
> +
> +#ifdef _WIN64
> +#pragma comment(linker, "/INCLUDE:_tls_used")
> +#pragma comment(linker, "/INCLUDE:p_thread_callback")
> +#else
> +#pragma comment(linker, "/INCLUDE:__tls_used")
> +#pragma comment(linker, "/INCLUDE:_p_thread_callback")
> +#endif
> +
> +int main() {
> +  printf("ran_before_main: %d\n", ran_before_main);
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20161108/841e02fb/attachment.html>


More information about the llvm-commits mailing list