[llvm] r231902 - InstrProf: Teach llvm-cov to handle universal binaries when given -arch

Justin Bogner mail at justinbogner.com
Tue Mar 10 19:30:52 PDT 2015


Author: bogner
Date: Tue Mar 10 21:30:51 2015
New Revision: 231902

URL: http://llvm.org/viewvc/llvm-project?rev=231902&view=rev
Log:
InstrProf: Teach llvm-cov to handle universal binaries when given -arch

Added:
    llvm/trunk/test/tools/llvm-cov/Inputs/universal-binary   (with props)
    llvm/trunk/test/tools/llvm-cov/Inputs/universal-binary.proftext
    llvm/trunk/test/tools/llvm-cov/universal-binary.c
Modified:
    llvm/trunk/include/llvm/ProfileData/CoverageMapping.h
    llvm/trunk/include/llvm/ProfileData/CoverageMappingReader.h
    llvm/trunk/lib/ProfileData/CoverageMapping.cpp
    llvm/trunk/lib/ProfileData/CoverageMappingReader.cpp
    llvm/trunk/tools/llvm-cov/CodeCoverage.cpp

Modified: llvm/trunk/include/llvm/ProfileData/CoverageMapping.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/CoverageMapping.h?rev=231902&r1=231901&r2=231902&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ProfileData/CoverageMapping.h (original)
+++ llvm/trunk/include/llvm/ProfileData/CoverageMapping.h Tue Mar 10 21:30:51 2015
@@ -18,6 +18,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/Triple.h"
 #include "llvm/ADT/iterator.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorOr.h"
@@ -408,7 +409,8 @@ public:
 
   /// \brief Load the coverage mapping from the given files.
   static ErrorOr<std::unique_ptr<CoverageMapping>>
-  load(StringRef ObjectFilename, StringRef ProfileFilename);
+  load(StringRef ObjectFilename, StringRef ProfileFilename,
+       Triple::ArchType Arch = Triple::ArchType::UnknownArch);
 
   /// \brief The number of functions that couldn't have their profiles mapped.
   ///

Modified: llvm/trunk/include/llvm/ProfileData/CoverageMappingReader.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/CoverageMappingReader.h?rev=231902&r1=231901&r2=231902&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ProfileData/CoverageMappingReader.h (original)
+++ llvm/trunk/include/llvm/ProfileData/CoverageMappingReader.h Tue Mar 10 21:30:51 2015
@@ -17,6 +17,7 @@
 
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/ProfileData/CoverageMapping.h"
 #include "llvm/ProfileData/InstrProf.h"
@@ -175,7 +176,8 @@ private:
 
 public:
   static ErrorOr<std::unique_ptr<BinaryCoverageReader>>
-  create(std::unique_ptr<MemoryBuffer> &ObjectBuffer);
+  create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
+         Triple::ArchType Arch = Triple::ArchType::UnknownArch);
 
   std::error_code readNextRecord(CoverageMappingRecord &Record) override;
 };

Modified: llvm/trunk/lib/ProfileData/CoverageMapping.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/CoverageMapping.cpp?rev=231902&r1=231901&r2=231902&view=diff
==============================================================================
--- llvm/trunk/lib/ProfileData/CoverageMapping.cpp (original)
+++ llvm/trunk/lib/ProfileData/CoverageMapping.cpp Tue Mar 10 21:30:51 2015
@@ -217,12 +217,13 @@ CoverageMapping::load(CoverageMappingRea
 }
 
 ErrorOr<std::unique_ptr<CoverageMapping>>
-CoverageMapping::load(StringRef ObjectFilename, StringRef ProfileFilename) {
+CoverageMapping::load(StringRef ObjectFilename, StringRef ProfileFilename,
+                      Triple::ArchType Arch) {
   auto CounterMappingBuff = MemoryBuffer::getFileOrSTDIN(ObjectFilename);
   if (std::error_code EC = CounterMappingBuff.getError())
     return EC;
   auto CoverageReaderOrErr =
-      BinaryCoverageReader::create(CounterMappingBuff.get());
+      BinaryCoverageReader::create(CounterMappingBuff.get(), Arch);
   if (std::error_code EC = CoverageReaderOrErr.getError())
     return EC;
   auto CoverageReader = std::move(CoverageReaderOrErr.get());

Modified: llvm/trunk/lib/ProfileData/CoverageMappingReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/CoverageMappingReader.cpp?rev=231902&r1=231901&r2=231902&view=diff
==============================================================================
--- llvm/trunk/lib/ProfileData/CoverageMappingReader.cpp (original)
+++ llvm/trunk/lib/ProfileData/CoverageMappingReader.cpp Tue Mar 10 21:30:51 2015
@@ -14,6 +14,7 @@
 
 #include "llvm/ProfileData/CoverageMappingReader.h"
 #include "llvm/ADT/DenseSet.h"
+#include "llvm/Object/MachOUniversal.h"
 #include "llvm/Object/ObjectFile.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/LEB128.h"
@@ -444,11 +445,31 @@ static std::error_code loadTestingFormat
 static std::error_code loadBinaryFormat(MemoryBufferRef ObjectBuffer,
                                         SectionData &ProfileNames,
                                         StringRef &CoverageMapping,
-                                        uint8_t &BytesInAddress) {
-  auto ObjectFileOrErr = object::ObjectFile::createObjectFile(ObjectBuffer);
-  if (std::error_code EC = ObjectFileOrErr.getError())
+                                        uint8_t &BytesInAddress,
+                                        Triple::ArchType Arch) {
+  auto BinOrErr = object::createBinary(ObjectBuffer);
+  if (std::error_code EC = BinOrErr.getError())
     return EC;
-  auto OF = std::move(ObjectFileOrErr.get());
+  auto Bin = std::move(BinOrErr.get());
+  std::unique_ptr<ObjectFile> OF;
+  if (auto *Universal = dyn_cast<object::MachOUniversalBinary>(Bin.get())) {
+    // If we have a universal binary, try to look up the object for the
+    // appropriate architecture.
+    auto ObjectFileOrErr = Universal->getObjectForArch(Arch);
+    if (std::error_code EC = ObjectFileOrErr.getError())
+      return EC;
+    OF = std::move(ObjectFileOrErr.get());
+  } else if (isa<object::ObjectFile>(Bin.get())) {
+    // For any other object file, upcast and take ownership.
+    OF.reset(cast<object::ObjectFile>(Bin.release()));
+    // If we've asked for a particular arch, make sure they match.
+    if (Arch != Triple::ArchType::UnknownArch && OF->getArch() != Arch)
+      return object_error::arch_not_found;
+  } else
+    // We can only handle object files.
+    return instrprof_error::malformed;
+
+  // The coverage uses native pointer sizes for the object it's written in.
   BytesInAddress = OF->getBytesInAddress();
 
   // Look for the sections that we are interested in.
@@ -479,7 +500,8 @@ static std::error_code loadBinaryFormat(
 }
 
 ErrorOr<std::unique_ptr<BinaryCoverageReader>>
-BinaryCoverageReader::create(std::unique_ptr<MemoryBuffer> &ObjectBuffer) {
+BinaryCoverageReader::create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
+                             Triple::ArchType Arch) {
   std::unique_ptr<BinaryCoverageReader> Reader(new BinaryCoverageReader());
 
   SectionData Profile;
@@ -492,7 +514,7 @@ BinaryCoverageReader::create(std::unique
                            BytesInAddress);
   else
     EC = loadBinaryFormat(ObjectBuffer->getMemBufferRef(), Profile, Coverage,
-                          BytesInAddress);
+                          BytesInAddress, Arch);
   if (EC)
     return EC;
 

Added: llvm/trunk/test/tools/llvm-cov/Inputs/universal-binary
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-cov/Inputs/universal-binary?rev=231902&view=auto
==============================================================================
Binary files llvm/trunk/test/tools/llvm-cov/Inputs/universal-binary (added) and llvm/trunk/test/tools/llvm-cov/Inputs/universal-binary Tue Mar 10 21:30:51 2015 differ

Propchange: llvm/trunk/test/tools/llvm-cov/Inputs/universal-binary
------------------------------------------------------------------------------
    svn:executable = *

Added: llvm/trunk/test/tools/llvm-cov/Inputs/universal-binary.proftext
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-cov/Inputs/universal-binary.proftext?rev=231902&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-cov/Inputs/universal-binary.proftext (added)
+++ llvm/trunk/test/tools/llvm-cov/Inputs/universal-binary.proftext Tue Mar 10 21:30:51 2015
@@ -0,0 +1,4 @@
+main
+0x0
+1
+100

Added: llvm/trunk/test/tools/llvm-cov/universal-binary.c
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-cov/universal-binary.c?rev=231902&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-cov/universal-binary.c (added)
+++ llvm/trunk/test/tools/llvm-cov/universal-binary.c Tue Mar 10 21:30:51 2015
@@ -0,0 +1,13 @@
+// The coverage reader should be able to handle universal binaries
+
+//CHECK: 100| @[[LINE+1]]| int main
+int main(int argc, const char *argv[]) {}
+
+// RUN: llvm-profdata merge %S/Inputs/universal-binary.proftext -o %t.profdata
+// RUN: llvm-cov show %S/Inputs/universal-binary -instr-profile %t.profdata -no-colors -filename-equivalence %s -arch x86_64 | FileCheck %s
+
+// RUN: not llvm-cov show %S/Inputs/universal-binary -instr-profile %t.profdata -no-colors -filename-equivalence %s -arch i386 2>&1 | FileCheck --check-prefix=WRONG-ARCH %s
+// WRONG-ARCH: Failed to load coverage
+
+// llvm-cov doesn't work on big endian yet
+// XFAIL: powerpc64-, s390x, mips-, mips64-, sparc

Modified: llvm/trunk/tools/llvm-cov/CodeCoverage.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-cov/CodeCoverage.cpp?rev=231902&r1=231901&r2=231902&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-cov/CodeCoverage.cpp (original)
+++ llvm/trunk/tools/llvm-cov/CodeCoverage.cpp Tue Mar 10 21:30:51 2015
@@ -20,6 +20,7 @@
 #include "SourceCoverageView.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
 #include "llvm/ProfileData/CoverageMapping.h"
 #include "llvm/ProfileData/InstrProfReader.h"
 #include "llvm/Support/CommandLine.h"
@@ -87,6 +88,7 @@ public:
       LoadedSourceFiles;
   bool CompareFilenamesOnly;
   StringMap<std::string> RemappedFilenames;
+  llvm::Triple::ArchType CoverageArch;
 };
 }
 
@@ -193,7 +195,8 @@ CodeCoverageTool::createSourceFileView(S
 }
 
 std::unique_ptr<CoverageMapping> CodeCoverageTool::load() {
-  auto CoverageOrErr = CoverageMapping::load(ObjectFilename, PGOFilename);
+  auto CoverageOrErr = CoverageMapping::load(ObjectFilename, PGOFilename,
+                                             CoverageArch);
   if (std::error_code EC = CoverageOrErr.getError()) {
     colored_ostream(errs(), raw_ostream::RED)
         << "error: Failed to load coverage: " << EC.message();
@@ -242,6 +245,9 @@ int CodeCoverageTool::run(Command Cmd, i
       cl::desc(
           "File with the profile data obtained after an instrumented run"));
 
+  cl::opt<std::string> Arch(
+      "arch", cl::desc("architecture of the coverage mapping binary"));
+
   cl::opt<bool> DebugDump("dump", cl::Optional,
                           cl::desc("Show internal debug dump"));
 
@@ -322,6 +328,16 @@ int CodeCoverageTool::run(Command Cmd, i
       Filters.push_back(std::unique_ptr<CoverageFilter>(StatFilterer));
     }
 
+    if (Arch.empty())
+      CoverageArch = llvm::Triple::ArchType::UnknownArch;
+    else {
+      CoverageArch = Triple(Arch).getArch();
+      if (CoverageArch == llvm::Triple::ArchType::UnknownArch) {
+        errs() << "error: Unknown architecture: " << Arch << "\n";
+        return 1;
+      }
+    }
+
     for (const auto &File : InputSourceFiles) {
       SmallString<128> Path(File);
       if (!CompareFilenamesOnly)





More information about the llvm-commits mailing list