[PATCH] D58661: [llvm-cov] Fix llvm-cov on Windows and un-XFAIL test

Reid Kleckner via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 25 17:59:09 PST 2019


rnk created this revision.
rnk added a reviewer: vsk.
Herald added subscribers: Sanitizers, hiraditya.
Herald added projects: Sanitizers, LLVM.

The llvm-cov tool needs to be able to find coverage names in the
executable, so the .lprfn and .lcovmap sections cannot be merged into
.rdata.

Also, the linker merges .lprfn$M into .lprfn, so llvm-cov needs to
handle that when looking up sections. It has to support running on both
relocatable object files and linked PE files.

Lastly, when loading .lprfn from a PE file, llvm-cov needs to skip the
leading zero byte added by the profile runtime.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D58661

Files:
  compiler-rt/lib/profile/InstrProfilingPlatformWindows.c
  compiler-rt/test/profile/instrprof-merging.cpp
  llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp


Index: llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
===================================================================
--- llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
+++ llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
@@ -22,6 +22,7 @@
 #include "llvm/Object/Error.h"
 #include "llvm/Object/MachOUniversal.h"
 #include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/COFF.h"
 #include "llvm/ProfileData/InstrProf.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Debug.h"
@@ -350,6 +351,13 @@
   if (auto EC = Section.getContents(Data))
     return errorCodeToError(EC);
   Address = Section.getAddress();
+
+  // If this is a linked PE/COFF file, then we have to skip over the null byte
+  // that is allocated in the .lprfn$A section in the LLVM profiling runtime.
+  const ObjectFile *Obj = Section.getObject();
+  if (isa<COFFObjectFile>(Obj) && !Obj->isRelocatableObject())
+    Data = Data.drop_front(1);
+
   return Error::success();
 }
 
@@ -616,11 +624,20 @@
 }
 
 static Expected<SectionRef> lookupSection(ObjectFile &OF, StringRef Name) {
+  // On COFF, the object file section name may end in "$M". This tells the
+  // linker to sort these sections between "$A" and "$Z". The linker removes the
+  // dollar and everything after it in the final binary. Do the same to match.
+  bool IsCOFF = isa<COFFObjectFile>(OF);
+  auto stripSuffix = [IsCOFF](StringRef N) {
+    return IsCOFF ? N.split('$').first : N;
+  };
+  Name = stripSuffix(Name);
+
   StringRef FoundName;
   for (const auto &Section : OF.sections()) {
     if (auto EC = Section.getName(FoundName))
       return errorCodeToError(EC);
-    if (FoundName == Name)
+    if (stripSuffix(FoundName) == Name)
       return Section;
   }
   return make_error<CoverageMapError>(coveragemap_error::no_data_found);
Index: compiler-rt/test/profile/instrprof-merging.cpp
===================================================================
--- compiler-rt/test/profile/instrprof-merging.cpp
+++ compiler-rt/test/profile/instrprof-merging.cpp
@@ -21,9 +21,6 @@
 //    and prefer it over others.) When only limited coverage information is
 //    available (just from one binary), don't try to guess any region counts.
 
-// FIXME: Fails with: "Failed to load coverage: No coverage data found"
-// XFAIL: windows
-
 struct A {
   A() {}    // V1: [[@LINE]]{{ *}}|{{ *}}1
             // V1-ONLY: [[@LINE+1]]{{ *}}|{{ *}}|
Index: compiler-rt/lib/profile/InstrProfilingPlatformWindows.c
===================================================================
--- compiler-rt/lib/profile/InstrProfilingPlatformWindows.c
+++ compiler-rt/lib/profile/InstrProfilingPlatformWindows.c
@@ -16,9 +16,9 @@
 #pragma comment(linker, "/MERGE:.lprfd=.data")
 #pragma comment(linker, "/MERGE:.lprfv=.data")
 #pragma comment(linker, "/MERGE:.lprfnd=.data")
-/* Merge read-only sections into .rdata. */
-#pragma comment(linker, "/MERGE:.lprfn=.rdata")
-#pragma comment(linker, "/MERGE:.lcovmap=.rdata")
+/* Do *NOT* merge .lprfn and .lcovmap into .rdata. llvm-cov must be able to find
+ * after the fact.
+ */
 
 /* Allocate read-only section bounds. */
 #pragma section(".lprfn$A", read)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D58661.188287.patch
Type: text/x-patch
Size: 3176 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190226/2479569c/attachment.bin>


More information about the llvm-commits mailing list