From fa6c912a756fb6af0e1461580d905bb2cd469dc6 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Tue, 26 Feb 2019 02:30:00 +0000 Subject: [PATCH] [llvm-cov] Fix llvm-cov on Windows and un-XFAIL test Summary: 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. Reviewers: vsk Subscribers: hiraditya, #sanitizers, llvm-commits Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D58661 llvm-svn: 354840 --- .../Coverage/CoverageMappingReader.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/ProfileData/Coverage/CoverageMappingReader.cpp b/lib/ProfileData/Coverage/CoverageMappingReader.cpp index af09a611570..3724329e132 100644 --- a/lib/ProfileData/Coverage/CoverageMappingReader.cpp +++ b/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 @@ Error InstrProfSymtab::create(SectionRef &Section) { 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(Obj) && !Obj->isRelocatableObject()) + Data = Data.drop_front(1); + return Error::success(); } @@ -616,11 +624,20 @@ static Error loadTestingFormat(StringRef Data, InstrProfSymtab &ProfileNames, } static Expected 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(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(coveragemap_error::no_data_found);