LLVM API Documentation
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 }