LLVM API Documentation

CoverageMappingReader.cpp
Go to the documentation of this file.
00001 //=-- CoverageMappingReader.cpp - Code coverage mapping reader ----*- C++ -*-=//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file contains support for reading coverage mapping data for
00011 // instrumentation based coverage.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "llvm/ProfileData/CoverageMappingReader.h"
00016 #include "llvm/ADT/DenseSet.h"
00017 #include "llvm/Object/ObjectFile.h"
00018 #include "llvm/Support/LEB128.h"
00019 
00020 using namespace llvm;
00021 using namespace coverage;
00022 using namespace object;
00023 
00024 void CoverageMappingIterator::increment() {
00025   // Check if all the records were read or if an error occurred while reading
00026   // the next record.
00027   if (Reader->readNextRecord(Record))
00028     *this = CoverageMappingIterator();
00029 }
00030 
00031 std::error_code RawCoverageReader::readULEB128(uint64_t &Result) {
00032   if (Data.size() < 1)
00033     return error(instrprof_error::truncated);
00034   unsigned N = 0;
00035   Result = decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
00036   if (N > Data.size())
00037     return error(instrprof_error::malformed);
00038   Data = Data.substr(N);
00039   return success();
00040 }
00041 
00042 std::error_code RawCoverageReader::readIntMax(uint64_t &Result,
00043                                               uint64_t MaxPlus1) {
00044   if (auto Err = readULEB128(Result))
00045     return Err;
00046   if (Result >= MaxPlus1)
00047     return error(instrprof_error::malformed);
00048   return success();
00049 }
00050 
00051 std::error_code RawCoverageReader::readSize(uint64_t &Result) {
00052   if (auto Err = readULEB128(Result))
00053     return Err;
00054   // Sanity check the number.
00055   if (Result > Data.size())
00056     return error(instrprof_error::malformed);
00057   return success();
00058 }
00059 
00060 std::error_code RawCoverageReader::readString(StringRef &Result) {
00061   uint64_t Length;
00062   if (auto Err = readSize(Length))
00063     return Err;
00064   Result = Data.substr(0, Length);
00065   Data = Data.substr(Length);
00066   return success();
00067 }
00068 
00069 std::error_code RawCoverageFilenamesReader::read() {
00070   uint64_t NumFilenames;
00071   if (auto Err = readSize(NumFilenames))
00072     return Err;
00073   for (size_t I = 0; I < NumFilenames; ++I) {
00074     StringRef Filename;
00075     if (auto Err = readString(Filename))
00076       return Err;
00077     Filenames.push_back(Filename);
00078   }
00079   return success();
00080 }
00081 
00082 std::error_code RawCoverageMappingReader::decodeCounter(unsigned Value,
00083                                                         Counter &C) {
00084   auto Tag = Value & Counter::EncodingTagMask;
00085   switch (Tag) {
00086   case Counter::Zero:
00087     C = Counter::getZero();
00088     return success();
00089   case Counter::CounterValueReference:
00090     C = Counter::getCounter(Value >> Counter::EncodingTagBits);
00091     return success();
00092   default:
00093     break;
00094   }
00095   Tag -= Counter::Expression;
00096   switch (Tag) {
00097   case CounterExpression::Subtract:
00098   case CounterExpression::Add: {
00099     auto ID = Value >> Counter::EncodingTagBits;
00100     if (ID >= Expressions.size())
00101       return error(instrprof_error::malformed);
00102     Expressions[ID].Kind = CounterExpression::ExprKind(Tag);
00103     C = Counter::getExpression(ID);
00104     break;
00105   }
00106   default:
00107     return error(instrprof_error::malformed);
00108   }
00109   return success();
00110 }
00111 
00112 std::error_code RawCoverageMappingReader::readCounter(Counter &C) {
00113   uint64_t EncodedCounter;
00114   if (auto Err =
00115           readIntMax(EncodedCounter, std::numeric_limits<unsigned>::max()))
00116     return Err;
00117   if (auto Err = decodeCounter(EncodedCounter, C))
00118     return Err;
00119   return success();
00120 }
00121 
00122 static const unsigned EncodingExpansionRegionBit = 1
00123                                                    << Counter::EncodingTagBits;
00124 
00125 /// \brief Read the sub-array of regions for the given inferred file id.
00126 /// \param NumFileIDs the number of file ids that are defined for this
00127 /// function.
00128 std::error_code RawCoverageMappingReader::readMappingRegionsSubArray(
00129     std::vector<CounterMappingRegion> &MappingRegions, unsigned InferredFileID,
00130     size_t NumFileIDs) {
00131   uint64_t NumRegions;
00132   if (auto Err = readSize(NumRegions))
00133     return Err;
00134   unsigned LineStart = 0;
00135   for (size_t I = 0; I < NumRegions; ++I) {
00136     Counter C;
00137     CounterMappingRegion::RegionKind Kind = CounterMappingRegion::CodeRegion;
00138 
00139     // Read the combined counter + region kind.
00140     uint64_t EncodedCounterAndRegion;
00141     if (auto Err = readIntMax(EncodedCounterAndRegion,
00142                               std::numeric_limits<unsigned>::max()))
00143       return Err;
00144     unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask;
00145     uint64_t ExpandedFileID = 0;
00146     if (Tag != Counter::Zero) {
00147       if (auto Err = decodeCounter(EncodedCounterAndRegion, C))
00148         return Err;
00149     } else {
00150       // Is it an expansion region?
00151       if (EncodedCounterAndRegion & EncodingExpansionRegionBit) {
00152         Kind = CounterMappingRegion::ExpansionRegion;
00153         ExpandedFileID = EncodedCounterAndRegion >>
00154                          Counter::EncodingCounterTagAndExpansionRegionTagBits;
00155         if (ExpandedFileID >= NumFileIDs)
00156           return error(instrprof_error::malformed);
00157       } else {
00158         switch (EncodedCounterAndRegion >>
00159                 Counter::EncodingCounterTagAndExpansionRegionTagBits) {
00160         case CounterMappingRegion::CodeRegion:
00161           // Don't do anything when we have a code region with a zero counter.
00162           break;
00163         case CounterMappingRegion::SkippedRegion:
00164           Kind = CounterMappingRegion::SkippedRegion;
00165           break;
00166         default:
00167           return error(instrprof_error::malformed);
00168         }
00169       }
00170     }
00171 
00172     // Read the source range.
00173     uint64_t LineStartDelta, CodeBeforeColumnStart, NumLines, ColumnEnd;
00174     if (auto Err =
00175             readIntMax(LineStartDelta, std::numeric_limits<unsigned>::max()))
00176       return Err;
00177     if (auto Err = readULEB128(CodeBeforeColumnStart))
00178       return Err;
00179     bool HasCodeBefore = CodeBeforeColumnStart & 1;
00180     uint64_t ColumnStart = CodeBeforeColumnStart >>
00181                            CounterMappingRegion::EncodingHasCodeBeforeBits;
00182     if (ColumnStart > std::numeric_limits<unsigned>::max())
00183       return error(instrprof_error::malformed);
00184     if (auto Err = readIntMax(NumLines, std::numeric_limits<unsigned>::max()))
00185       return Err;
00186     if (auto Err = readIntMax(ColumnEnd, std::numeric_limits<unsigned>::max()))
00187       return Err;
00188     LineStart += LineStartDelta;
00189     // Adjust the column locations for the empty regions that are supposed to
00190     // cover whole lines. Those regions should be encoded with the
00191     // column range (1 -> std::numeric_limits<unsigned>::max()), but because
00192     // the encoded std::numeric_limits<unsigned>::max() is several bytes long,
00193     // we set the column range to (0 -> 0) to ensure that the column start and
00194     // column end take up one byte each.
00195     // The std::numeric_limits<unsigned>::max() is used to represent a column
00196     // position at the end of the line without knowing the length of that line.
00197     if (ColumnStart == 0 && ColumnEnd == 0) {
00198       ColumnStart = 1;
00199       ColumnEnd = std::numeric_limits<unsigned>::max();
00200     }
00201     MappingRegions.push_back(CounterMappingRegion(
00202         C, InferredFileID, LineStart, ColumnStart, LineStart + NumLines,
00203         ColumnEnd, HasCodeBefore, Kind));
00204     MappingRegions.back().ExpandedFileID = ExpandedFileID;
00205   }
00206   return success();
00207 }
00208 
00209 std::error_code RawCoverageMappingReader::read(CoverageMappingRecord &Record) {
00210 
00211   // Read the virtual file mapping.
00212   llvm::SmallVector<unsigned, 8> VirtualFileMapping;
00213   uint64_t NumFileMappings;
00214   if (auto Err = readSize(NumFileMappings))
00215     return Err;
00216   for (size_t I = 0; I < NumFileMappings; ++I) {
00217     uint64_t FilenameIndex;
00218     if (auto Err = readIntMax(FilenameIndex, TranslationUnitFilenames.size()))
00219       return Err;
00220     VirtualFileMapping.push_back(FilenameIndex);
00221   }
00222 
00223   // Construct the files using unique filenames and virtual file mapping.
00224   for (auto I : VirtualFileMapping) {
00225     Filenames.push_back(TranslationUnitFilenames[I]);
00226   }
00227 
00228   // Read the expressions.
00229   uint64_t NumExpressions;
00230   if (auto Err = readSize(NumExpressions))
00231     return Err;
00232   // Create an array of dummy expressions that get the proper counters
00233   // when the expressions are read, and the proper kinds when the counters
00234   // are decoded.
00235   Expressions.resize(
00236       NumExpressions,
00237       CounterExpression(CounterExpression::Subtract, Counter(), Counter()));
00238   for (size_t I = 0; I < NumExpressions; ++I) {
00239     if (auto Err = readCounter(Expressions[I].LHS))
00240       return Err;
00241     if (auto Err = readCounter(Expressions[I].RHS))
00242       return Err;
00243   }
00244 
00245   // Read the mapping regions sub-arrays.
00246   for (unsigned InferredFileID = 0, S = VirtualFileMapping.size();
00247        InferredFileID < S; ++InferredFileID) {
00248     if (auto Err = readMappingRegionsSubArray(MappingRegions, InferredFileID,
00249                                               VirtualFileMapping.size()))
00250       return Err;
00251   }
00252 
00253   // Set the counters for the expansion regions.
00254   // i.e. Counter of expansion region = counter of the first region
00255   // from the expanded file.
00256   // Perform multiple passes to correctly propagate the counters through
00257   // all the nested expansion regions.
00258   SmallVector<CounterMappingRegion *, 8> FileIDExpansionRegionMapping;
00259   FileIDExpansionRegionMapping.resize(VirtualFileMapping.size(), nullptr);
00260   for (unsigned Pass = 1, S = VirtualFileMapping.size(); Pass < S; ++Pass) {
00261     for (auto &R : MappingRegions) {
00262       if (R.Kind != CounterMappingRegion::ExpansionRegion)
00263         continue;
00264       assert(!FileIDExpansionRegionMapping[R.ExpandedFileID]);
00265       FileIDExpansionRegionMapping[R.ExpandedFileID] = &R;
00266     }
00267     for (auto &R : MappingRegions) {
00268       if (FileIDExpansionRegionMapping[R.FileID]) {
00269         FileIDExpansionRegionMapping[R.FileID]->Count = R.Count;
00270         FileIDExpansionRegionMapping[R.FileID] = nullptr;
00271       }
00272     }
00273   }
00274 
00275   Record.FunctionName = FunctionName;
00276   Record.Filenames = Filenames;
00277   Record.Expressions = Expressions;
00278   Record.MappingRegions = MappingRegions;
00279   return success();
00280 }
00281 
00282 ObjectFileCoverageMappingReader::ObjectFileCoverageMappingReader(
00283     StringRef FileName)
00284     : CurrentRecord(0) {
00285   auto File = llvm::object::ObjectFile::createObjectFile(FileName);
00286   if (!File)
00287     error(File.getError());
00288   else
00289     Object = std::move(File.get());
00290 }
00291 
00292 namespace {
00293 /// \brief The coverage mapping data for a single function.
00294 /// It points to the function's name.
00295 template <typename IntPtrT> struct CoverageMappingFunctionRecord {
00296   IntPtrT FunctionNamePtr;
00297   uint32_t FunctionNameSize;
00298   uint32_t CoverageMappingSize;
00299   uint64_t FunctionHash;
00300 };
00301 
00302 /// \brief The coverage mapping data for a single translation unit.
00303 /// It points to the array of function coverage mapping records and the encoded
00304 /// filenames array.
00305 template <typename IntPtrT> struct CoverageMappingTURecord {
00306   uint32_t FunctionRecordsSize;
00307   uint32_t FilenamesSize;
00308   uint32_t CoverageMappingsSize;
00309   uint32_t Version;
00310 };
00311 
00312 /// \brief A helper structure to access the data from a section
00313 /// in an object file.
00314 struct SectionData {
00315   StringRef Data;
00316   uint64_t Address;
00317 
00318   std::error_code load(SectionRef &Section) {
00319     if (auto Err = Section.getContents(Data))
00320       return Err;
00321     return Section.getAddress(Address);
00322   }
00323 
00324   std::error_code get(uint64_t Pointer, size_t Size, StringRef &Result) {
00325     if (Pointer < Address)
00326       return instrprof_error::malformed;
00327     auto Offset = Pointer - Address;
00328     if (Offset + Size > Data.size())
00329       return instrprof_error::malformed;
00330     Result = Data.substr(Pointer - Address, Size);
00331     return instrprof_error::success;
00332   }
00333 };
00334 }
00335 
00336 template <typename T>
00337 std::error_code readCoverageMappingData(
00338     SectionData &ProfileNames, StringRef Data,
00339     std::vector<ObjectFileCoverageMappingReader::ProfileMappingRecord> &Records,
00340     std::vector<StringRef> &Filenames) {
00341   llvm::DenseSet<T> UniqueFunctionMappingData;
00342 
00343   // Read the records in the coverage data section.
00344   while (!Data.empty()) {
00345     if (Data.size() < sizeof(CoverageMappingTURecord<T>))
00346       return instrprof_error::malformed;
00347     auto TU = reinterpret_cast<const CoverageMappingTURecord<T> *>(Data.data());
00348     Data = Data.substr(sizeof(CoverageMappingTURecord<T>));
00349     switch (TU->Version) {
00350     case CoverageMappingVersion1:
00351       break;
00352     default:
00353       return instrprof_error::unsupported_version;
00354     }
00355     auto Version = CoverageMappingVersion(TU->Version);
00356 
00357     // Get the function records.
00358     auto FunctionRecords =
00359         reinterpret_cast<const CoverageMappingFunctionRecord<T> *>(Data.data());
00360     if (Data.size() <
00361         sizeof(CoverageMappingFunctionRecord<T>) * TU->FunctionRecordsSize)
00362       return instrprof_error::malformed;
00363     Data = Data.substr(sizeof(CoverageMappingFunctionRecord<T>) *
00364                        TU->FunctionRecordsSize);
00365 
00366     // Get the filenames.
00367     if (Data.size() < TU->FilenamesSize)
00368       return instrprof_error::malformed;
00369     auto RawFilenames = Data.substr(0, TU->FilenamesSize);
00370     Data = Data.substr(TU->FilenamesSize);
00371     size_t FilenamesBegin = Filenames.size();
00372     RawCoverageFilenamesReader Reader(RawFilenames, Filenames);
00373     if (auto Err = Reader.read())
00374       return Err;
00375 
00376     // Get the coverage mappings.
00377     if (Data.size() < TU->CoverageMappingsSize)
00378       return instrprof_error::malformed;
00379     auto CoverageMappings = Data.substr(0, TU->CoverageMappingsSize);
00380     Data = Data.substr(TU->CoverageMappingsSize);
00381 
00382     for (unsigned I = 0; I < TU->FunctionRecordsSize; ++I) {
00383       auto &MappingRecord = FunctionRecords[I];
00384 
00385       // Get the coverage mapping.
00386       if (CoverageMappings.size() < MappingRecord.CoverageMappingSize)
00387         return instrprof_error::malformed;
00388       auto Mapping =
00389           CoverageMappings.substr(0, MappingRecord.CoverageMappingSize);
00390       CoverageMappings =
00391           CoverageMappings.substr(MappingRecord.CoverageMappingSize);
00392 
00393       // Ignore this record if we already have a record that points to the same
00394       // function name.
00395       // This is useful to ignore the redundant records for the functions
00396       // with ODR linkage.
00397       if (UniqueFunctionMappingData.count(MappingRecord.FunctionNamePtr))
00398         continue;
00399       UniqueFunctionMappingData.insert(MappingRecord.FunctionNamePtr);
00400       StringRef FunctionName;
00401       if (auto Err =
00402               ProfileNames.get(MappingRecord.FunctionNamePtr,
00403                                MappingRecord.FunctionNameSize, FunctionName))
00404         return Err;
00405       Records.push_back(ObjectFileCoverageMappingReader::ProfileMappingRecord(
00406           Version, FunctionName, MappingRecord.FunctionHash, Mapping,
00407           FilenamesBegin, Filenames.size() - FilenamesBegin));
00408     }
00409   }
00410 
00411   return instrprof_error::success;
00412 }
00413 
00414 static const char *TestingFormatMagic = "llvmcovmtestdata";
00415 
00416 static std::error_code decodeTestingFormat(StringRef Data,
00417                                            SectionData &ProfileNames,
00418                                            StringRef &CoverageMapping) {
00419   Data = Data.substr(StringRef(TestingFormatMagic).size());
00420   if (Data.size() < 1)
00421     return instrprof_error::truncated;
00422   unsigned N = 0;
00423   auto ProfileNamesSize =
00424       decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
00425   if (N > Data.size())
00426     return instrprof_error::malformed;
00427   Data = Data.substr(N);
00428   if (Data.size() < 1)
00429     return instrprof_error::truncated;
00430   N = 0;
00431   ProfileNames.Address =
00432       decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
00433   if (N > Data.size())
00434     return instrprof_error::malformed;
00435   Data = Data.substr(N);
00436   if (Data.size() < ProfileNamesSize)
00437     return instrprof_error::malformed;
00438   ProfileNames.Data = Data.substr(0, ProfileNamesSize);
00439   CoverageMapping = Data.substr(ProfileNamesSize);
00440   return instrprof_error::success;
00441 }
00442 
00443 ObjectFileCoverageMappingReader::ObjectFileCoverageMappingReader(
00444     std::unique_ptr<MemoryBuffer> &ObjectBuffer, sys::fs::file_magic Type)
00445     : CurrentRecord(0) {
00446   if (ObjectBuffer->getBuffer().startswith(TestingFormatMagic)) {
00447     // This is a special format used for testing.
00448     SectionData ProfileNames;
00449     StringRef CoverageMapping;
00450     if (auto Err = decodeTestingFormat(ObjectBuffer->getBuffer(), ProfileNames,
00451                                        CoverageMapping)) {
00452       error(Err);
00453       return;
00454     }
00455     error(readCoverageMappingData<uint64_t>(ProfileNames, CoverageMapping,
00456                                             MappingRecords, Filenames));
00457     Object = OwningBinary<ObjectFile>(std::unique_ptr<ObjectFile>(),
00458                                       std::move(ObjectBuffer));
00459     return;
00460   }
00461 
00462   auto File = object::ObjectFile::createObjectFile(
00463       ObjectBuffer->getMemBufferRef(), Type);
00464   if (!File)
00465     error(File.getError());
00466   else
00467     Object = OwningBinary<ObjectFile>(std::move(File.get()),
00468                                       std::move(ObjectBuffer));
00469 }
00470 
00471 std::error_code ObjectFileCoverageMappingReader::readHeader() {
00472   ObjectFile *OF = Object.getBinary().get();
00473   if (!OF)
00474     return getError();
00475   auto BytesInAddress = OF->getBytesInAddress();
00476   if (BytesInAddress != 4 && BytesInAddress != 8)
00477     return error(instrprof_error::malformed);
00478 
00479   // Look for the sections that we are interested in.
00480   int FoundSectionCount = 0;
00481   SectionRef ProfileNames, CoverageMapping;
00482   for (const auto &Section : OF->sections()) {
00483     StringRef Name;
00484     if (auto Err = Section.getName(Name))
00485       return Err;
00486     if (Name == "__llvm_prf_names") {
00487       ProfileNames = Section;
00488     } else if (Name == "__llvm_covmap") {
00489       CoverageMapping = Section;
00490     } else
00491       continue;
00492     ++FoundSectionCount;
00493   }
00494   if (FoundSectionCount != 2)
00495     return error(instrprof_error::bad_header);
00496 
00497   // Get the contents of the given sections.
00498   StringRef Data;
00499   if (auto Err = CoverageMapping.getContents(Data))
00500     return Err;
00501   SectionData ProfileNamesData;
00502   if (auto Err = ProfileNamesData.load(ProfileNames))
00503     return Err;
00504 
00505   // Load the data from the found sections.
00506   std::error_code Err;
00507   if (BytesInAddress == 4)
00508     Err = readCoverageMappingData<uint32_t>(ProfileNamesData, Data,
00509                                             MappingRecords, Filenames);
00510   else
00511     Err = readCoverageMappingData<uint64_t>(ProfileNamesData, Data,
00512                                             MappingRecords, Filenames);
00513   if (Err)
00514     return error(Err);
00515 
00516   return success();
00517 }
00518 
00519 std::error_code
00520 ObjectFileCoverageMappingReader::readNextRecord(CoverageMappingRecord &Record) {
00521   if (CurrentRecord >= MappingRecords.size())
00522     return error(instrprof_error::eof);
00523 
00524   FunctionsFilenames.clear();
00525   Expressions.clear();
00526   MappingRegions.clear();
00527   auto &R = MappingRecords[CurrentRecord];
00528   RawCoverageMappingReader Reader(
00529       R.FunctionName, R.CoverageMapping,
00530       makeArrayRef(Filenames.data() + R.FilenamesBegin, R.FilenamesSize),
00531       FunctionsFilenames, Expressions, MappingRegions);
00532   if (auto Err = Reader.read(Record))
00533     return Err;
00534   Record.FunctionHash = R.FunctionHash;
00535   ++CurrentRecord;
00536   return success();
00537 }