summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Metzman <metzman@chromium.org>2019-01-21 02:15:29 +0000
committerJonathan Metzman <metzman@chromium.org>2019-01-21 02:15:29 +0000
commitdd467f4f431ece145b41486c5b822d51a68d37a6 (patch)
treedf5bed78a4007c06747d3282d3d5b4988aef0c89
parenta35df433bf7bf27940d1464441f497c3e8623a35 (diff)
downloadbcm5719-llvm-dd467f4f431ece145b41486c5b822d51a68d37a6.tar.gz
bcm5719-llvm-dd467f4f431ece145b41486c5b822d51a68d37a6.zip
[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 llvm-svn: 351714
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_coverage_win_sections.cc45
1 files changed, 25 insertions, 20 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_coverage_win_sections.cc b/compiler-rt/lib/sanitizer_common/sanitizer_coverage_win_sections.cc
index 00c416743fb..403d46c8c4f 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_coverage_win_sections.cc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_coverage_win_sections.cc
@@ -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")
OpenPOWER on IntegriCloud