[compiler-rt] r351714 - [libFuzzer][MSVC] Make Sanitizer Coverage MSVC-compatible

Jonathan Metzman via llvm-commits llvm-commits at lists.llvm.org
Sun Jan 20 18:15:29 PST 2019


Author: metzman
Date: Sun Jan 20 18:15:29 2019
New Revision: 351714

URL: http://llvm.org/viewvc/llvm-project?rev=351714&view=rev
Log:
[libFuzzer][MSVC] Make Sanitizer Coverage MSVC-compatible

Summary:
Make Sanitizer Coverage work when compiled work when compiler-rt
is compiled with MSVC.

The previous solution did not work for MSVC because MSVC tried to
align the .SCOV$CZ section even though we used
__declspec(align(1)) on its only symbol:
__stop___sancov_cntrs.
Because the counter array is composed
of 1 byte elements, it does not always end on an 8 or 4 byte
boundary. This means that padding was sometimes added to
added to align the next section, .SCOV$CZ.
Use a different strategy now: instead of only instructing
the compiler not to align the symbol, make the section
one byte long by making its only symbol a uint8_t, so that
the linker won't try to align it.

Reviewers: morehouse, rnk

Reviewed By: rnk

Subscribers: kubamracek

Differential Revision: https://reviews.llvm.org/D56866

Modified:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_win_sections.cc

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_win_sections.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_win_sections.cc?rev=351714&r1=351713&r2=351714&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_win_sections.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_win_sections.cc Sun Jan 20 18:15:29 2019
@@ -26,35 +26,40 @@
 #include "sanitizer_platform.h"
 #if SANITIZER_WINDOWS
 #include <stdint.h>
-extern "C" {
-// The Guard array and counter array should both be merged into the .data
-// section to reduce the number of PE sections However, because PCTable is
-// constant it should be merged with the .rdata section.
-#pragma section(".SCOV$GA", read, write)  // NOLINT
-// Use align(1) to avoid adding any padding that will mess up clients trying to
-// determine the start and end of the array.
-__declspec(allocate(".SCOV$GA")) __declspec(align(1)) uint64_t
-    __start___sancov_guards = 0;
-#pragma section(".SCOV$GZ", read, write)  // NOLINT
-__declspec(allocate(".SCOV$GZ")) __declspec(align(1)) uint64_t
-    __stop___sancov_guards = 0;
 
+extern "C" {
+// Use uint64_t so the linker won't need to add any padding if it tries to word
+// align the start of the 8-bit counters array. The array will always start 8
+// bytes after __start_sancov_cntrs.
 #pragma section(".SCOV$CA", read, write)  // NOLINT
-__declspec(allocate(".SCOV$CA")) __declspec(align(1)) uint64_t
-    __start___sancov_cntrs = 0;
+__declspec(allocate(".SCOV$CA")) uint64_t __start___sancov_cntrs = 0;
+
+// Even though we said not to align __stop__sancov_cntrs (using the "align"
+// declspec), MSVC's linker may try to align the section, .SCOV$CZ, containing
+// it. This can cause a mismatch between the number of PCs and counters since
+// each PCTable element is 8 bytes (unlike counters which are 1 byte) so no
+// padding would be added to align .SCOVP$Z, However, if .SCOV$CZ section is 1
+// byte, the linker won't try to align it on an 8-byte boundary, so use a
+// uint8_t for __stop_sancov_cntrs.
 #pragma section(".SCOV$CZ", read, write)  // NOLINT
-__declspec(allocate(".SCOV$CZ")) __declspec(align(1)) uint64_t
+__declspec(allocate(".SCOV$CZ")) __declspec(align(1)) uint8_t
     __stop___sancov_cntrs = 0;
 
+#pragma section(".SCOV$GA", read, write)  // NOLINT
+__declspec(allocate(".SCOV$GA")) uint64_t __start___sancov_guards = 0;
+#pragma section(".SCOV$GZ", read, write)  // NOLINT
+__declspec(allocate(".SCOV$GZ")) __declspec(align(1)) uint8_t
+    __stop___sancov_guards = 0;
+
+// The guard array and counter array should both be merged into the .data
+// section to reduce the number of PE sections. However, because PCTable is
+// constant it should be merged with the .rdata section.
 #pragma comment(linker, "/MERGE:.SCOV=.data")
 
-// Use uint64_t so there won't be any issues if the linker tries to word align
-// the pc array.
 #pragma section(".SCOVP$A", read)  // NOLINT
-__declspec(allocate(".SCOVP$A")) __declspec(align(1)) uint64_t
-    __start___sancov_pcs = 0;
+__declspec(allocate(".SCOVP$A")) uint64_t __start___sancov_pcs = 0;
 #pragma section(".SCOVP$Z", read)  // NOLINT
-__declspec(allocate(".SCOVP$Z")) __declspec(align(1)) uint64_t
+__declspec(allocate(".SCOVP$Z")) __declspec(align(1)) uint8_t
     __stop___sancov_pcs = 0;
 
 #pragma comment(linker, "/MERGE:.SCOVP=.rdata")




More information about the llvm-commits mailing list