From b111a23370a496efa8e941146c4533bd91da1aab Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Sun, 16 Feb 2025 23:49:57 +0900 Subject: [PATCH 01/10] Introduce CovMap in ObjectYAML --- llvm/include/llvm/ObjectYAML/CovMap.h | 385 +++++++ llvm/include/llvm/ObjectYAML/ELFYAML.h | 14 + llvm/include/llvm/ProfileData/InstrProf.h | 6 + llvm/lib/ObjectYAML/CMakeLists.txt | 3 + llvm/lib/ObjectYAML/CovMap.cpp | 977 ++++++++++++++++++ llvm/lib/ObjectYAML/ELFEmitter.cpp | 38 + llvm/lib/ObjectYAML/ELFYAML.cpp | 12 + llvm/lib/ProfileData/InstrProf.cpp | 23 +- .../Inputs/branch-c-general-single.yaml | 561 ++++++++-- .../Inputs/branch-logical-mixed-single.yaml | 145 ++- .../llvm-cov/Inputs/branch-macros-single.yaml | 242 ++++- .../Inputs/branch-templates-single.yaml | 119 ++- .../showLineExecutionCounts-single.yaml | 57 +- llvm/test/tools/llvm-cov/Inputs/yaml.makefile | 6 +- llvm/test/tools/obj2yaml/ELF/covmap.yaml | 160 +++ llvm/test/tools/obj2yaml/help.test | 1 + llvm/tools/obj2yaml/elf2yaml.cpp | 57 +- llvm/tools/obj2yaml/obj2yaml.cpp | 2 +- llvm/tools/obj2yaml/obj2yaml.h | 4 + .../llvm-project-overlay/llvm/BUILD.bazel | 2 + 20 files changed, 2602 insertions(+), 212 deletions(-) create mode 100644 llvm/include/llvm/ObjectYAML/CovMap.h create mode 100644 llvm/lib/ObjectYAML/CovMap.cpp create mode 100644 llvm/test/tools/obj2yaml/ELF/covmap.yaml diff --git a/llvm/include/llvm/ObjectYAML/CovMap.h b/llvm/include/llvm/ObjectYAML/CovMap.h new file mode 100644 index 0000000000000..fa9492fc1ee72 --- /dev/null +++ b/llvm/include/llvm/ObjectYAML/CovMap.h @@ -0,0 +1,385 @@ +//===- CovMap.h - ObjectYAML Interface for coverage map ---------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// - llvm::coverage::yaml +// +// Describes binary file formats and YAML structures of coverage map. +// +// - llvm::yaml +// +// Attachments for YAMLTraits. +// +// - llvm::covmap +// +// Provides YAML encoder and decoder for coverage map. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OBJECTYAML_COVMAP_H +#define LLVM_OBJECTYAML_COVMAP_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ObjectYAML/ELFYAML.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/YAMLTraits.h" +#include +#include +#include +#include + +namespace llvm { +class InstrProfSymtab; +class raw_ostream; +} // namespace llvm + +namespace llvm::coverage::yaml { + +/// This works like vector container but can be replaced with +/// MutableArrayRef. See also SequenceTraits. +template > class VectorOrRef { + using Ref = MutableArrayRef; + + /// Holds vector type initially. + std::variant Array; + +public: + // FIXME: Iterator impl is minimal easy. + using iterator = T *; + + iterator begin() { + if (auto *V = std::get_if(&Array)) + return &V->front(); + else + return &std::get(Array).front(); + } + + iterator end() { + if (auto *V = std::get_if(&Array)) + return &V->back() + 1; + else + return &std::get(Array).back() + 1; + } + + size_t size() const { + if (const auto *V = std::get_if(&Array)) + return V->size(); + else + return std::get(Array).size(); + } + + T &operator[](int Idx) { + if (auto *V = std::get_if(&Array)) + return (*V)[Idx]; + else + return std::get(Array)[Idx]; + } + + void resize(size_t Size) { std::get(Array).resize(Size); } + + VectorOrRef() = default; + + /// Initialize with MutableArrayRef. + VectorOrRef(Ref &&Tmp) : Array(std::move(Tmp)) {} +}; + +/// Options for Decoder. +struct DecoderParam { + bool Detailed; ///< Generate and show processed records. + bool Raw; ///< Show raw data oriented records. + bool dLoc; ///< Show raw dLoc (differential Loc). +}; + +struct DecoderContext; + +/// Base Counter, corresponding to coverage::Counter. +struct CounterTy { + enum TagTy : uint8_t { + Zero = 0, + Ref, + Sub, + Add, + }; + + /// Optional in detailed view, since most Tag can be determined from + /// other optional fields. + std::optional Tag; + + /// Internal use. + std::optional Val; + + std::optional RefOpt; + std::optional SubOpt; + std::optional AddOpt; + + virtual ~CounterTy() {} + + virtual void mapping(llvm::yaml::IO &IO); + + /// Holds Val for extensions. + Error decodeOrTag(DecoderContext &Data); + + /// Raise Error if Val isn't empty. + Error decode(DecoderContext &Data); + + void encode(raw_ostream &OS) const; +}; + +/// Holds a pair of both hands but doesn't hold ops(add or sub). +/// Ops is stored in CounterTy::Tag. +using ExpressionTy = std::array; + +/// {True, False} +using BranchTy = std::array; + +/// {ID, TrueID, FalseID} +/// Note: This has +1 offset unlike mcdc::ConditionID. +using MCDCBranchTy = std::array; + +struct DecisionTy { + uint64_t BIdx; ///< Bitmap index + uint64_t NC; ///< NumConds + + void mapping(llvm::yaml::IO &IO); + + Error decode(DecoderContext &Data); + + void encode(raw_ostream &OS) const; +}; + +/// {LineStart, ColumnStart, LineEnd, ColumnEnd} +using LocTy = std::array; + +/// +struct RecTy : CounterTy { + enum ExtTagTy : uint8_t { + Skip = 2, + Branch = 4, + Decision = 5, + MCDCBranch = 6, + }; + + /// This is optional in detailed view. + std::optional ExtTag; + + // Options for extensions. + std::optional Expansion; ///< Doesn't have ExtTag. + std::optional BranchOpt; ///< Optionally has MCDC. + std::optional MCDC; + std::optional DecisionOpt; + + /// True or None. + /// Stored in ColumnEnd:31. + std::optional isGap; + + std::optional Loc; ///< Absolute line numbers. + std::optional dLoc; ///< Differential line numbers. + + void mapping(llvm::yaml::IO &IO) override; + + Error decode(DecoderContext &Data); + + void encode(uint64_t &StartLoc, raw_ostream &OS) const; +}; + +/// {NumRecs, Recs...} +struct FileRecsTy { + std::optional Index; ///< Shown in detailed view. + std::optional Filename; ///< Resolved by FileIDs. + std::vector Recs; + + void mapping(llvm::yaml::IO &IO); +}; + +/// Key is FilenamesRef. +using CovMapByRefTy = llvm::DenseMap; + +/// An element of CovFun array. +struct CovFunTy { + std::optional NameRef; ///< Hash value of the symbol. + std::optional FuncName; ///< Resolved by symtab. + llvm::yaml::Hex64 FuncHash; ///< Signature of this function. + llvm::yaml::Hex64 FilenamesRef; ///< Pointer to CovMap + std::optional> FileIDs; ///< Resolved by CovMap + std::vector Expressions; + std::vector Files; ///< 2-dimension array of Recs. + + void mapping(llvm::yaml::IO &IO); + + /// Depends on CovMap and SymTab(IPSK_names) + Expected decode(CovMapByRefTy &CovMapByRef, InstrProfSymtab *SymTab, + const ArrayRef Content, uint64_t Offset, + const DecoderParam &Param, bool IsLE = true); + + void encode(raw_ostream &OS) const; +}; + +/// An element of CovMap array. +struct CovMapTy { + /// This is the key of CovMap but not present in the file + /// format. Calculate and store with Filenames. + llvm::yaml::Hex64 FilenamesRef; + + std::optional Version; + + /// Raw Filenames (and storage of Files) + std::optional> Filenames; + + /// Since Version5: Filenames[0] is the working directory (or + /// zero-length string). Note that indices in CovFun::FileIDs is + /// base on Filenames. (Then, +0, as WD, is not expected to appear) + std::optional WD; + /// This may be ArrayRef in Decoder since Filenames has been + /// filled. On the other hand in Encoder, this should be a vector + /// since YAML parser doesn't endorse references. + std::optional> Files; + + void mapping(llvm::yaml::IO &IO); + + bool useWD() const { return (!Version || *Version >= 4); } + StringRef getWD() const { return (WD ? *WD : StringRef()); } + + Expected decode(const ArrayRef Content, uint64_t Offset, + const DecoderParam &Param, bool IsLE = true); + + /// Generate Accumulated list with WD. + /// Returns a single element {WD} if AccFiles is not given. + std::vector + generateAccFilenames(const std::optional> &AccFilesOpt = + std::nullopt) const; + /// Regenerate Filenames with WD. + /// Use Files if it is not None. Or given AccFiles is used. + void + regenerateFilenames(const std::optional> &AccFilesOpt); + + /// Encode Filenames. This is mostly used just to obtain FilenamesRef. + std::pair encodeFilenames( + const std::optional> &AccFilesOpt = std::nullopt, + bool Compress = false) const; + + void encode(raw_ostream &OS) const; +}; + +} // namespace llvm::coverage::yaml + +namespace llvm::yaml { +template +struct SequenceTraits> { + static size_t size(IO &io, llvm::coverage::yaml::VectorOrRef &seq) { + return seq.size(); + } + static T &element(IO &, llvm::coverage::yaml::VectorOrRef &seq, + size_t index) { + if (index >= seq.size()) + seq.resize(index + 1); + return seq[index]; + } +}; +} // namespace llvm::yaml + +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::coverage::yaml::CovMapTy) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::coverage::yaml::CovFunTy) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::coverage::yaml::ExpressionTy) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::coverage::yaml::RecTy) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::coverage::yaml::FileRecsTy) +LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::coverage::yaml::CounterTy) + +#define LLVM_COVERAGE_YAML_ELEM_MAPPING(Ty) \ + namespace llvm::yaml { \ + template <> struct MappingTraits { \ + static void mapping(IO &IO, llvm::coverage::yaml::Ty &Obj) { \ + Obj.mapping(IO); \ + } \ + }; \ + } + +/// `Flow` is used for emission of a compact oneliner for RecTy. +#define LLVM_COVERAGE_YAML_ELEM_MAPPING_FLOW(Ty) \ + namespace llvm::yaml { \ + template <> struct MappingTraits { \ + static void mapping(IO &IO, llvm::coverage::yaml::Ty &Obj) { \ + Obj.mapping(IO); \ + (void)flow; \ + } \ + static const bool flow = true; \ + }; \ + } + +#define LLVM_COVERAGE_YAML_ENUM(Ty) \ + namespace llvm::yaml { \ + template <> struct ScalarEnumerationTraits { \ + static void enumeration(IO &IO, llvm::coverage::yaml::Ty &Value); \ + }; \ + } + +LLVM_COVERAGE_YAML_ENUM(CounterTy::TagTy) +LLVM_COVERAGE_YAML_ENUM(RecTy::ExtTagTy) +LLVM_COVERAGE_YAML_ELEM_MAPPING_FLOW(CounterTy) +LLVM_COVERAGE_YAML_ELEM_MAPPING_FLOW(DecisionTy) +LLVM_COVERAGE_YAML_ELEM_MAPPING_FLOW(RecTy) +LLVM_COVERAGE_YAML_ELEM_MAPPING(FileRecsTy) +LLVM_COVERAGE_YAML_ELEM_MAPPING(CovFunTy) +LLVM_COVERAGE_YAML_ELEM_MAPPING(CovMapTy) + +namespace llvm::covmap { + +class Decoder { +public: + virtual ~Decoder() {} + + /// Returns DecoderImpl. + static std::unique_ptr + get(const coverage::yaml::DecoderParam &Param); + + /// Called from the Sections loop in advance of the final dump. + /// Decoder predecodes Names and CovMap, and captures Contents of + /// CovFuns. + virtual Error + acquire(uint64_t Offset, unsigned AddressAlign, StringRef Name, + std::function>()> getSectionContents) = 0; + + /// Called before the final dump after `acquire`. + /// Decode contents partially and resolve names. + virtual Error fixup() = 0; + + /// Create an ELFYAML object. This just puts predecoded data in + /// `fixup`. + virtual Expected + make(uint64_t Offset, StringRef Name, + std::function dumpCommonSection) = 0; + + /// Suppress emission of CovMap unless enabled. + static bool enabled; +}; + +class Encoder { +public: + virtual ~Encoder() {} + + /// Returns EncoderImpl. + static std::unique_ptr get(); + + /// Called from the Sections loop. + virtual void collect(ELFYAML::Chunk *Chunk) = 0; + + /// Resolves names along DecoderParam in advance of Emitter. It'd be + /// too late to resolve sections in Emitter since they are immutable + /// then. + virtual void fixup() = 0; +}; + +/// Returns whether Name is interested. +bool nameMatches(StringRef Name); + +/// Returns a new ELFYAML Object. +std::unique_ptr make_unique(StringRef Name); + +} // namespace llvm::covmap + +#endif // LLVM_OBJECTYAML_COVMAP_H diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h index dfdfa055d65fa..2dc1a861077c3 100644 --- a/llvm/include/llvm/ObjectYAML/ELFYAML.h +++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h @@ -229,6 +229,7 @@ struct Chunk { DependentLibraries, CallGraphProfile, BBAddrMap, + CovMapBase, // Special chunks. SpecialChunksStart, @@ -398,6 +399,19 @@ struct RawContentSection : Section { std::optional> ContentBuf; }; +struct CovMapSectionBase : Section { + std::optional Info; + + CovMapSectionBase() : Section(ChunkKind::CovMapBase) {} + + virtual void mapping(yaml::IO &IO) = 0; + virtual Error encode(raw_ostream &OS) const = 0; + + static bool classof(const Chunk *S) { + return S->Kind == ChunkKind::CovMapBase; + } +}; + struct NoBitsSection : Section { NoBitsSection() : Section(ChunkKind::NoBits) {} diff --git a/llvm/include/llvm/ProfileData/InstrProf.h b/llvm/include/llvm/ProfileData/InstrProf.h index 7133c0c6a302c..e20424da3cac2 100644 --- a/llvm/include/llvm/ProfileData/InstrProf.h +++ b/llvm/include/llvm/ProfileData/InstrProf.h @@ -545,6 +545,12 @@ class InstrProfSymtab { /// This method is a wrapper to \c readAndDecodeStrings method. Error create(StringRef NameStrings); + // PrfNames is nested array. + using PrfNamesTy = SmallVector; + using PrfNamesChunksTy = SmallVector; + + Expected createAndGetList(ArrayRef Content); + /// Initialize symtab states with function names and vtable names. \c /// FuncNameStrings is a string composed of one or more encoded function name /// strings, and \c VTableNameStrings composes of one or more encoded vtable diff --git a/llvm/lib/ObjectYAML/CMakeLists.txt b/llvm/lib/ObjectYAML/CMakeLists.txt index b36974d47d9f8..11054a1e91388 100644 --- a/llvm/lib/ObjectYAML/CMakeLists.txt +++ b/llvm/lib/ObjectYAML/CMakeLists.txt @@ -7,6 +7,7 @@ add_llvm_component_library(LLVMObjectYAML CodeViewYAMLTypes.cpp COFFEmitter.cpp COFFYAML.cpp + CovMap.cpp DWARFEmitter.cpp DWARFYAML.cpp DXContainerEmitter.cpp @@ -34,7 +35,9 @@ add_llvm_component_library(LLVMObjectYAML LINK_COMPONENTS BinaryFormat + Coverage Object + ProfileData Support TargetParser DebugInfoCodeView diff --git a/llvm/lib/ObjectYAML/CovMap.cpp b/llvm/lib/ObjectYAML/CovMap.cpp new file mode 100644 index 0000000000000..12c03a651668c --- /dev/null +++ b/llvm/lib/ObjectYAML/CovMap.cpp @@ -0,0 +1,977 @@ +//===- CovMap.cpp - ObjectYAML Interface for coverage map -----------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Implementations of CovMap, encoder, decoder. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ObjectYAML/CovMap.h" +#include "llvm/ADT/MapVector.h" +#include "llvm/ObjectYAML/ELFYAML.h" +#include "llvm/ProfileData/Coverage/CoverageMapping.h" +#include "llvm/ProfileData/Coverage/CoverageMappingReader.h" +#include "llvm/ProfileData/Coverage/CoverageMappingWriter.h" +#include "llvm/ProfileData/InstrProf.h" +#include "llvm/Support/Alignment.h" +#include "llvm/Support/DataExtractor.h" +#include "llvm/Support/LEB128.h" +#include "llvm/Support/MD5.h" +#include "llvm/Support/YAMLTraits.h" +#include + +#define COVMAP_V3 + +using namespace llvm; +using namespace llvm::coverage::yaml; +using namespace llvm::covmap; + +bool Decoder::enabled; + +// DataExtractor w/ single Cursor +struct coverage::yaml::DecoderContext : DataExtractor, + DataExtractor::Cursor, + DecoderParam { + uint64_t LineStart = 0; + + DecoderContext(const ArrayRef Content, const DecoderParam &Param, + bool IsLE) + : DataExtractor(Content, IsLE, /*AddressSize=*/0), + DataExtractor::Cursor(0), DecoderParam(Param) {} + + bool eof() { return DataExtractor::eof(*this); } + uint32_t getU32() { return DataExtractor::getU32(*this); } + uint64_t getU64() { return DataExtractor::getU64(*this); } + Expected getULEB128() { + uint64_t Result = DataExtractor::getULEB128(*this); + if (!*this) + return takeError(); + return Result; + } + StringRef getBytes(size_t sz) { return DataExtractor::getBytes(*this, sz); } +}; + +void CounterTy::encode(raw_ostream &OS) const { + std::pair C; + if (RefOpt) + C = {Ref, *RefOpt}; + else if (SubOpt) + C = {Sub, *SubOpt}; + else if (AddOpt) + C = {Add, *AddOpt}; + else if (Tag && *Tag == Zero) + C = {Zero, 0u}; + else if (Tag && Val) + C = {*Tag, *Val}; + else + llvm_unreachable("Null value cannot be met"); + + encodeULEB128(C.first | (C.second << 2), OS); +} + +Error CounterTy::decodeOrTag(DecoderContext &Data) { + auto COrErr = Data.getULEB128(); + if (!COrErr) + return COrErr.takeError(); + auto T = static_cast(*COrErr & 0x03); + auto V = (*COrErr >> 2); + if (T == Zero) { + if (V == 0) + Tag = Zero; // w/o Val + else + Val = V; // w/o Tag + } else { + if (Data.Raw) { + Tag = T; + Val = V; + } else { + switch (T) { + case Zero: + llvm_unreachable("Zero should be handled in advance"); + case Ref: + RefOpt = V; + break; + case Sub: + SubOpt = V; + break; + case Add: + AddOpt = V; + break; + } + } + } + + return Error::success(); +} + +Error CounterTy::decode(DecoderContext &Data) { + if (auto E = decodeOrTag(Data)) + return E; + if (!this->Tag && this->Val) + return make_error( + coveragemap_error::malformed, + "Counter::Zero shouldn't have the Val: 0x" + + Twine::utohexstr(*this->Val)); + return Error::success(); +} + +void DecisionTy::encode(raw_ostream &OS) const { + encodeULEB128(BIdx, OS); + encodeULEB128(NC, OS); +} + +Error DecisionTy::decode(DecoderContext &Data) { + auto BIdxOrErr = Data.getULEB128(); + if (!BIdxOrErr) + return BIdxOrErr.takeError(); + BIdx = *BIdxOrErr; + + auto NCOrErr = Data.getULEB128(); + if (!NCOrErr) + return NCOrErr.takeError(); + NC = *NCOrErr; + + return Error::success(); +} + +void RecTy::encode(uint64_t &StartLoc, raw_ostream &OS) const { + if (Expansion) { + encodeULEB128(4 + (*Expansion << 3), OS); + } else if (ExtTag && *ExtTag == Skip) { + encodeULEB128(2 << 3, OS); + } else if (DecisionOpt) { + assert(!ExtTag || *ExtTag == Decision); + encodeULEB128(5 << 3, OS); + DecisionOpt->encode(OS); + } else if (MCDC) { + assert(!ExtTag || *ExtTag == MCDCBranch); + assert(BranchOpt); + encodeULEB128(6 << 3, OS); + (*BranchOpt)[0].encode(OS); + (*BranchOpt)[1].encode(OS); + encodeULEB128((*MCDC)[0], OS); + encodeULEB128((*MCDC)[1], OS); + encodeULEB128((*MCDC)[2], OS); + } else if (BranchOpt) { + assert(!ExtTag || *ExtTag == Branch); + encodeULEB128(4 << 3, OS); + (*BranchOpt)[0].encode(OS); + (*BranchOpt)[1].encode(OS); + } else { + // Non-tag CounterTy + CounterTy::encode(OS); + } + + assert((!isGap || *isGap) && "Don't set isGap=false"); + uint32_t Gap = (isGap ? (1u << 31) : 0u); + if (Loc) { + encodeULEB128((*Loc)[0] - StartLoc, OS); + encodeULEB128((*Loc)[1], OS); + encodeULEB128((*Loc)[2] - (*Loc)[0], OS); + encodeULEB128((*Loc)[3] | Gap, OS); + StartLoc = (*Loc)[0]; + } else { + encodeULEB128((*dLoc)[0], OS); + encodeULEB128((*dLoc)[1], OS); + encodeULEB128((*dLoc)[2], OS); + encodeULEB128((*dLoc)[3] | Gap, OS); + } +} + +Error RecTy::decode(DecoderContext &Data) { + auto getU16 = [&]() -> Expected { + auto ValOrErr = Data.getULEB128(); + if (!ValOrErr) + return ValOrErr.takeError(); + if (*ValOrErr > 0x7FFF + 1) + return make_error(coveragemap_error::malformed, + "MC/DC index is out of range: 0x" + + Twine::utohexstr(*ValOrErr)); + return static_cast(*ValOrErr); + }; + + auto decodeBranch = [&]() -> Error { + auto &B = BranchOpt.emplace(); + if (auto E = B[0].decode(Data)) + return E; + if (auto E = B[1].decode(Data)) + return E; + return Error::success(); + }; + + // Decode tagged CounterTy + if (auto E = CounterTy::decodeOrTag(Data)) + return E; + if (!this->Val || this->Tag) { + // Compatible to CounterTy + } else if (*this->Val & 1u) { + Expansion = (*this->Val >> 1); + this->Val.reset(); + } else { + auto Tag = *this->Val >> 1; + this->Val.reset(); + switch (Tag) { + case Skip: + ExtTag = Skip; // w/o Val + break; + case Decision: + if (auto E = DecisionOpt.emplace().decode(Data)) + return E; + if (Data.Raw) + ExtTag = Decision; + break; + case Branch: + if (auto E = decodeBranch()) + return E; + if (Data.Raw) + ExtTag = Branch; + break; + case MCDCBranch: { + if (auto E = decodeBranch()) + return E; + auto I0OrErr = getU16(); + if (!I0OrErr) + return I0OrErr.takeError(); + auto I1OrErr = getU16(); + if (!I1OrErr) + return I1OrErr.takeError(); + auto I2OrErr = getU16(); + if (!I2OrErr) + return I2OrErr.takeError(); + MCDC = {*I0OrErr, *I1OrErr, *I2OrErr}; + if (Data.Raw) + ExtTag = MCDCBranch; + break; + } + default: + return make_error( + coveragemap_error::malformed, + "Record doesn't have an valid Tag: 0x" + Twine::utohexstr(Tag)); + } + } + + // Decode Loc + auto LSDeltaOrErr = Data.getULEB128(); + if (!LSDeltaOrErr) + return LSDeltaOrErr.takeError(); + Data.LineStart += *LSDeltaOrErr; + + auto CSOrErr = Data.getULEB128(); + if (!CSOrErr) + return CSOrErr.takeError(); + + auto NLOrErr = Data.getULEB128(); + if (!NLOrErr) + return NLOrErr.takeError(); + auto LineEnd = Data.LineStart + *NLOrErr; + + auto CEOrErr = Data.getULEB128(); + if (!CEOrErr) + return CEOrErr.takeError(); + auto ColumnEnd = *CEOrErr; + + // Gap is set in ColumnEnd:31 + if (ColumnEnd & (1u << 31)) + isGap = true; + ColumnEnd &= ((1u << 31) - 1); + + dLoc = {*LSDeltaOrErr, *CSOrErr, *NLOrErr, ColumnEnd}; + Loc = {Data.LineStart, *CSOrErr, LineEnd, ColumnEnd}; + + return Error::success(); +} + +void CovFunTy::encode(raw_ostream &OS) const { + // Encode Body in advance since DataSize should be known. + std::string Body; + raw_string_ostream SS(Body); + + assert(FileIDs); + encodeULEB128(FileIDs->size(), SS); + for (auto I : *FileIDs) + encodeULEB128(I, SS); + + encodeULEB128(Expressions.size(), SS); + for (const auto &[LHS, RHS] : Expressions) { + LHS.encode(SS); + RHS.encode(SS); + } + + for (const auto &File : Files) { + encodeULEB128(File.Recs.size(), SS); + uint64_t StartLoc = 0; + for (const auto &Rec : File.Recs) + Rec.encode(StartLoc, SS); + } + + // Emit the Header + uint64_t NameRef = (this->NameRef ? static_cast(*this->NameRef) + : MD5Hash(*this->FuncName)); + uint32_t DataSize = Body.size(); + /* this->FuncHash */ + char CoverageMapping = 0; // dummy + /* this->FilenamesRef */ + +#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Initializer) \ + if (sizeof(Name) > 1) { \ + Type t = Name; \ + OS << StringRef(reinterpret_cast(&t), sizeof(t)); \ + } +#include "llvm/ProfileData/InstrProfData.inc" + + // Emit the body. + OS << std::move(Body); +} + +std::vector CovMapTy::generateAccFilenames( + const std::optional> &AccFilesOpt) const { + std::vector Result; + if (useWD()) + Result.push_back(getWD().str()); + // Returns {WD} if AccFiles is None. + if (AccFilesOpt) { + for (auto &Filename : *AccFilesOpt) + Result.push_back(Filename.str()); + } + return Result; +} + +void CovMapTy::regenerateFilenames( + const std::optional> &AccFilesOpt) { + assert(!this->Filenames); + if (this->Files) { + auto &CovMapFilenames = this->Filenames.emplace(generateAccFilenames()); + assert(CovMapFilenames.size() <= 1); + for (auto &&File : *this->Files) + CovMapFilenames.push_back(std::move(File)); + } else { + // Encode Accfiles, that comes from CovFun. + this->Filenames = generateAccFilenames(AccFilesOpt); + } +} + +std::pair +CovMapTy::encodeFilenames(const std::optional> &AccFilesOpt, + bool Compress) const { + ArrayRef TempFilenames; + std::vector AccFilenames; // Storage + + if (AccFilesOpt) { + AccFilenames = generateAccFilenames(AccFilesOpt); + TempFilenames = AccFilenames; + } else { + assert(this->Filenames); + TempFilenames = ArrayRef(*this->Filenames); + } + + std::string FilenamesBlob; + llvm::raw_string_ostream OS(FilenamesBlob); + CoverageFilenamesSectionWriter(TempFilenames).write(OS, Compress); + + return {llvm::IndexedInstrProf::ComputeHash(FilenamesBlob), FilenamesBlob}; +} + +Expected CovFunTy::decode(CovMapByRefTy &CovMapByRef, + InstrProfSymtab *Symtab, + const ArrayRef Content, + uint64_t Offset, const DecoderParam &Param, + bool IsLE) { + DecoderContext Data(Content, Param, IsLE); + Data.seek(Offset); + + uint32_t DataSize; + [[maybe_unused]] char CoverageMapping; // Ignored + +#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Initializer) \ + if (sizeof(Type) == sizeof(uint64_t)) \ + Name = Data.getU64(); \ + else if (sizeof(Type) == sizeof(uint32_t)) \ + Name = Data.getU32(); \ + else \ + assert(sizeof(Type) == sizeof(CoverageMapping) && "Unknown type"); + +#include "llvm/ProfileData/InstrProfData.inc" + + if (!Data) + return Data.takeError(); + + if (Data.Detailed) + FuncName = Symtab->getFuncOrVarNameIfDefined(*NameRef); + + if (!Data.Raw) + NameRef.reset(); + + [[maybe_unused]] auto ExpectedEndOffset = Data.tell() + DataSize; + + // Decode body. + assert(CovMapByRef.contains(this->FilenamesRef)); + auto &CovMap = *CovMapByRef[this->FilenamesRef]; + FileIDs.emplace(); + + auto NumFilesOrErr = Data.getULEB128(); + if (!NumFilesOrErr) + return NumFilesOrErr.takeError(); + for (unsigned I = 0, E = *NumFilesOrErr; I != E; ++I) { + if (auto IDOrErr = Data.getULEB128()) + FileIDs->push_back(*IDOrErr); + else + return IDOrErr.takeError(); + } + + auto NumExprOrErr = Data.getULEB128(); + if (!NumExprOrErr) + return NumExprOrErr.takeError(); + Expressions.resize(*NumExprOrErr); + for (auto &[LHS, RHS] : Expressions) { + if (auto E = LHS.decode(Data)) + return std::move(E); + if (auto E = RHS.decode(Data)) + return std::move(E); + } + + for (unsigned FileIdx = 0; FileIdx != *NumFilesOrErr; ++FileIdx) { + auto NumRegionsOrErr = Data.getULEB128(); + if (!NumRegionsOrErr) + return NumRegionsOrErr.takeError(); + auto &File = Files.emplace_back(); + if (Data.Detailed) { + File.Index = FileIdx; // Sequential number. + File.Filename = (*CovMap.Filenames)[(*FileIDs)[FileIdx]]; + } + + // Decode subarray. + Data.LineStart = 0; + for (unsigned I = 0; I != *NumRegionsOrErr; ++I) { + auto &Rec = File.Recs.emplace_back(); + if (auto E = Rec.decode(Data)) + return std::move(E); + + // Hide either Loc or dLoc. + if (!Data.Detailed || Data.dLoc) + Rec.Loc.reset(); + else if (!Data.Raw) + Rec.dLoc.reset(); + } + } + + // Hide FileIDs. + if (!Data.Raw) + FileIDs.reset(); + + assert(Data.tell() == ExpectedEndOffset); + return Data.tell(); +} + +void CovMapTy::encode(raw_ostream &OS) const { + auto [FilenamesRef, FilenamesBlob] = encodeFilenames(); + + uint32_t NRecords = 0; + uint32_t FilenamesSize = FilenamesBlob.size(); + uint32_t CoverageSize = 0; + uint32_t Version = + (this->Version ? *this->Version : INSTR_PROF_COVMAP_VERSION); + struct { +#define COVMAP_HEADER(Type, LLVMType, Name, Initializer) Type Name; +#include "llvm/ProfileData/InstrProfData.inc" + } CovMapHeader = { +#define COVMAP_HEADER(Type, LLVMType, Name, Initializer) Name, +#include "llvm/ProfileData/InstrProfData.inc" + }; + StringRef HeaderBytes(reinterpret_cast(&CovMapHeader), + sizeof(CovMapHeader)); + OS << HeaderBytes; + + // llvm_covmap's alignment + FilenamesBlob.resize(llvm::alignTo(FilenamesBlob.size(), sizeof(uint32_t))); + OS << FilenamesBlob; +} + +Expected CovMapTy::decode(const ArrayRef Content, + uint64_t Offset, const DecoderParam &Param, + bool IsLE) { + DecoderContext Data(Content, Param, IsLE); + Data.seek(Offset); + +#define COVMAP_HEADER(Type, LLVMType, Name, Initializer) \ + static_assert(sizeof(Type) == sizeof(uint32_t)); \ + Type Name = Data.getU32(); +#include "llvm/ProfileData/InstrProfData.inc" + if (!Data) + return Data.takeError(); + assert(NRecords == 0); + // +1: uint32_t FilenamesSize; + assert(CoverageSize == 0); + this->Version = Version; + + // Decode Body -- Filenames. + StringRef FnBlob = Data.getBytes(FilenamesSize); + if (!Data) + return Data.takeError(); + this->FilenamesRef = MD5Hash(FnBlob); + this->Filenames.emplace(); + if (auto E = RawCoverageFilenamesReader(FnBlob, *this->Filenames) + .read(static_cast(Version))) + return E; + + if (Param.Detailed && useWD()) { + assert(this->Filenames->size() >= 1); + auto FilenamesI = this->Filenames->begin(); + StringRef WD = *FilenamesI++; + if (!WD.empty()) + this->WD = WD; + // Use Filenames as a storage. + this->Files.emplace( + MutableArrayRef(&*FilenamesI, &*this->Filenames->end())); + } + + Offset = Data.tell(); + return Offset; +} + +void CounterTy::mapping(llvm::yaml::IO &IO) { + IO.mapOptional("Tag", Tag); + IO.mapOptional("Val", Val); + IO.mapOptional("Ref", RefOpt); + IO.mapOptional("Sub", SubOpt); + IO.mapOptional("Add", AddOpt); +} + +void DecisionTy::mapping(llvm::yaml::IO &IO) { + IO.mapRequired("BIdx", BIdx); + IO.mapRequired("NCond", NC); +} + +void RecTy::mapping(llvm::yaml::IO &IO) { + IO.mapOptional("Loc", Loc); + IO.mapOptional("dLoc", dLoc); + IO.mapOptional("isGap", isGap); + CounterTy::mapping(IO); + IO.mapOptional("ExtTag", ExtTag); + IO.mapOptional("Expansion", Expansion); + IO.mapOptional("Branch", BranchOpt); + IO.mapOptional("MCDC", MCDC); + IO.mapOptional("Decision", DecisionOpt); +} + +void FileRecsTy::mapping(llvm::yaml::IO &IO) { + IO.mapOptional("Index", Index); + IO.mapOptional("Filename", Filename); + IO.mapRequired("Regions", Recs); +} + +void CovFunTy::mapping(llvm::yaml::IO &IO) { + IO.mapOptional("NameRef", NameRef); + IO.mapOptional("FuncName", FuncName); + IO.mapRequired("FuncHash", FuncHash); + IO.mapRequired("FilenamesRef", FilenamesRef); + IO.mapOptional("FileIDs", FileIDs); + IO.mapRequired("Expressions", Expressions); + IO.mapRequired("Files", Files); +} + +void CovMapTy::mapping(llvm::yaml::IO &IO) { + IO.mapRequired("FilenamesRef", FilenamesRef); + IO.mapOptional("Version", Version); + + if (!WD && !Files) + // Suppress this regardless of (Detailed && Raw). + // Since it is obviously redundant. + IO.mapOptional("Filenames", Filenames); + + IO.mapOptional("WD", WD); + IO.mapOptional("Files", Files); +} + +#define ECase(N, X) IO.enumCase(Value, #X, N::X) + +void llvm::yaml::ScalarEnumerationTraits::enumeration( + llvm::yaml::IO &IO, CounterTy::TagTy &Value) { + ECase(CounterTy, Zero); + ECase(CounterTy, Ref); + ECase(CounterTy, Sub); + ECase(CounterTy, Add); +} + +void llvm::yaml::ScalarEnumerationTraits::enumeration( + llvm::yaml::IO &IO, RecTy::ExtTagTy &Value) { + ECase(RecTy, Skip); + ECase(RecTy, Branch); + ECase(RecTy, Decision); + ECase(RecTy, MCDCBranch); +} + +namespace { + +struct PrfNamesSection : ELFYAML::CovMapSectionBase { + InstrProfSymtab::PrfNamesChunksTy PrfNames; + + PrfNamesSection() { Name = "__llvm_prf_names"; } + static bool nameMatches(StringRef Name) { return Name == "__llvm_prf_names"; } + static bool classof(const Chunk *S) { + return (isa(S) && nameMatches(S->Name)); + } + + void mapping(llvm::yaml::IO &IO) override { + IO.mapOptional("PrfNames", PrfNames); + } + + Error encode(raw_ostream &OS) const override { + for (const auto &Names : PrfNames) { + std::string Result; + if (auto E = + collectGlobalObjectNameStrings(Names, + /*doCompression=*/false, Result)) + return E; + OS << Result; + } + return Error::success(); + } +}; + +struct CovMapSection : ELFYAML::CovMapSectionBase { + std::vector CovMaps; + + CovMapSection() { Name = "__llvm_covmap"; } + static bool nameMatches(StringRef Name) { return Name == "__llvm_covmap"; } + static bool classof(const Chunk *S) { + return (isa(S) && nameMatches(S->Name)); + } + + void mapping(llvm::yaml::IO &IO) override { + IO.mapOptional("CovMap", CovMaps); + } + + Error decode(ArrayRef Blob, unsigned AddressAlign, + const DecoderParam &Param) { + uint64_t Offset = 0; + + while (true) { + Offset = llvm::alignTo(Offset, AddressAlign); + if (Offset >= Blob.size()) { + break; + } + auto &CovMap = CovMaps.emplace_back(); + auto Result = CovMap.decode(Blob, Offset, Param); + if (!Result) { + return Result.takeError(); + } + Offset = *Result; + } + + return Error::success(); + } + + Error encode(raw_ostream &OS) const override { + auto BaseOffset = OS.tell(); + for (const auto &CovMap : CovMaps) { + OS.write_zeros(llvm::offsetToAlignment(OS.tell() - BaseOffset, + llvm::Align(AddressAlign.value))); + CovMap.encode(OS); + } + return Error::success(); + } +}; + +struct CovFunSection : ELFYAML::CovMapSectionBase { + std::vector CovFuns; + + CovFunSection() { Name = "__llvm_covfun"; } + static bool nameMatches(StringRef Name) { + return Name.starts_with("__llvm_covfun"); + } + static bool classof(const Chunk *S) { + return (isa(S) && nameMatches(S->Name)); + } + + void mapping(llvm::yaml::IO &IO) override { + IO.mapOptional("CovFun", CovFuns); + } + + static Expected> decode(CovMapByRefTy &CovMapByRef, + InstrProfSymtab *Symtab, + ArrayRef CovFunA, + unsigned AddressAlign, + const DecoderParam &Param) { + std::vector CovFuns; + uint64_t Offset = 0; + + while (true) { + Offset = llvm::alignTo(Offset, AddressAlign); + if (Offset >= CovFunA.size()) + break; + + auto &CovFun = CovFuns.emplace_back(); + auto Result = CovFun.decode(CovMapByRef, Symtab, CovFunA, Offset, Param); + if (!Result) + return Result.takeError(); + + Offset = *Result; + } + + return std::move(CovFuns); + } + + Error encode(raw_ostream &OS) const override { + auto BaseOffset = OS.tell(); + for (auto [I, CovFun] : enumerate(CovFuns)) { + OS.write_zeros(llvm::offsetToAlignment(OS.tell() - BaseOffset, + llvm::Align(AddressAlign.value))); + CovFun.encode(OS); + } + return Error::success(); + } +}; + +class CovMapFilenamesResolver { + DenseMap> FilenamesByCovMap; + std::vector UnresolvedCovFuns; + +protected: + CovMapByRefTy CovMapByRef; + std::vector TempCovMaps; // For Decoder + +public: + void collectCovMap(std::vector &CovMaps) { + for (auto &CovMap : CovMaps) + CovMapByRef[CovMap.FilenamesRef] = &CovMap; + } + + void moveAndCollectCovMap(std::vector &&CovMaps) { + TempCovMaps = std::move(CovMaps); + collectCovMap(TempCovMaps); + } + + void collectCovFunFilenames(std::vector &CovFuns) { + for (auto &CovFun : CovFuns) { + auto &Filenames = FilenamesByCovMap[CovFun.FilenamesRef]; + for (const auto &File : CovFun.Files) { + if (!File.Filename) + goto skip; + Filenames.insert(*File.Filename); + } + UnresolvedCovFuns.push_back(&CovFun); + skip:; + } + } + + void decMayeResetFilenames(std::vector &CovMaps) { + for (auto &CovMap : CovMaps) { + auto FilenamesI = FilenamesByCovMap.find(CovMap.FilenamesRef); + if (FilenamesI == FilenamesByCovMap.end()) + continue; + + // Calculate FilenamesRef with Filenames from CovFuns. + // If matches, hide Filenames from CovMap. + auto [AccFilenamesRef, _] = + CovMap.encodeFilenames(FilenamesI->second.getArrayRef()); + if (CovMap.FilenamesRef == AccFilenamesRef) { + CovMap.Files.reset(); + CovMap.Filenames.reset(); // FilenamesI has been invalidated. + } + } + } + + void encFixup() { + for (auto &[_, CovMap] : CovMapByRef) { + auto FilenamesI = FilenamesByCovMap.find(CovMap->FilenamesRef); + if (FilenamesI != FilenamesByCovMap.end()) { + // Check Filenames satisfies covfuns + DenseSet FilenamesSet; + if (CovMap->Files) { + for (const auto &Filename : *CovMap->Files) + FilenamesSet.insert(Filename); + } else if (CovMap->Filenames) { + for (const auto &Filename : *CovMap->Filenames) + FilenamesSet.insert(Filename); + } + + for (const auto &Filename : FilenamesI->second) { + if (!FilenamesSet.contains(Filename)) { + // If not, regenerate Filenames. + CovMap->Files.reset(); + CovMap->Filenames.reset(); + break; + } + } + } + + if (!CovMap->Filenames) { + // Regenerate. + // Use Files if exists. + // Use CovFuns (FilenamesI) otherwise. + assert(CovMap->Files || FilenamesI != FilenamesByCovMap.end()); + CovMap->regenerateFilenames( + CovMap->Files ? std::nullopt : FilenamesI->second.getArrayRef()); + } + auto [FilenamesRef, FilenamesBlob] = CovMap->encodeFilenames(); + assert(CovMap->FilenamesRef == FilenamesRef); + } + + // Fill FileIDs + for (auto *CovFun : UnresolvedCovFuns) { + assert(CovMapByRef[CovFun->FilenamesRef]); + assert(CovMapByRef[CovFun->FilenamesRef]->Filenames); + const auto &CovMapFilenames = + *CovMapByRef[CovFun->FilenamesRef]->Filenames; + auto &FileIDs = CovFun->FileIDs.emplace(); + for (const auto &File : CovFun->Files) { + auto I = std::find(CovMapFilenames.begin(), CovMapFilenames.end(), + File.Filename); + assert(I != CovMapFilenames.end()); + FileIDs.push_back(std::distance(CovMapFilenames.begin(), I)); + } + assert(CovFun->Files.size() == FileIDs.size()); + } + } +}; + +class DecoderImpl : public Decoder, CovMapFilenamesResolver { + DecoderParam Param; + + std::unique_ptr ProfileNames; + + InstrProfSymtab::PrfNamesChunksTy PrfNames; + + MapVector, unsigned>> CovFunBlobs; + DenseMap> TempCovFuns; + +public: + DecoderImpl(const DecoderParam &Param) + : Param(Param), ProfileNames(std::make_unique()) { + enabled = (Param.Detailed || Param.Raw); + } + + Error acquire(uint64_t Offset, unsigned AddressAlign, StringRef Name, + std::function>()> getSectionContents) + override { + // Don't register anything. + if (!enabled) + return Error::success(); + + if (PrfNamesSection::nameMatches(Name)) { + auto ContentOrErr = getSectionContents(); + if (!ContentOrErr) + return ContentOrErr.takeError(); + // Decode PrfNames in advance since CovFun depends on it. + auto PrfNamesOrErr = ProfileNames->createAndGetList(*ContentOrErr); + if (!PrfNamesOrErr) + return PrfNamesOrErr.takeError(); + PrfNames = std::move(*PrfNamesOrErr); + } else if (CovMapSection::nameMatches(Name)) { + auto ContentOrErr = getSectionContents(); + if (!ContentOrErr) + return ContentOrErr.takeError(); + + // Decode CovMaps in advance, since only CovMap knows its Version. + // CovMaps is restored (into CovMapSection) later. + auto TempCovMap = std::make_unique(); + if (auto E = TempCovMap->decode(*ContentOrErr, AddressAlign, Param)) + return E; + moveAndCollectCovMap(std::move(TempCovMap->CovMaps)); + } else if (CovFunSection::nameMatches(Name)) { + auto ContentOrErr = getSectionContents(); + if (!ContentOrErr) + return ContentOrErr.takeError(); + + // Will be decoded after CovMap is met. + CovFunBlobs[Offset] = {*ContentOrErr, AddressAlign}; + } + + return Error::success(); + } + + Error fixup() override { + // Decode CovFun(s) with predecoded PrfNames and CovMap. + for (const auto &[Offset, CovFunBlob] : CovFunBlobs) { + auto CovFunsOrErr = + CovFunSection::decode(CovMapByRef, ProfileNames.get(), + CovFunBlob.first, CovFunBlob.second, Param); + if (!CovFunsOrErr) + return CovFunsOrErr.takeError(); + TempCovFuns[Offset] = std::move(*CovFunsOrErr); + collectCovFunFilenames(TempCovFuns[Offset]); + } + return Error::success(); + } + + Expected + make(uint64_t Offset, StringRef Name, + std::function dumpCommonSection) override { + if (PrfNamesSection::nameMatches(Name)) { + auto S = std::make_unique(); + if (Error E = dumpCommonSection(*S)) + return std::move(E); + S->PrfNames = std::move(PrfNames); + return S.release(); + } else if (CovMapSection::nameMatches(Name)) { + auto S = std::make_unique(); + if (Error E = dumpCommonSection(*S)) + return std::move(E); + + // Store predecoded CovMaps. + S->CovMaps = std::move(TempCovMaps); + + // Hide Filenames if it is reproducible from CovFuns. + if (Param.Detailed) + decMayeResetFilenames(S->CovMaps); + + return S.release(); + } else if (CovFunSection::nameMatches(Name)) { + auto S = std::make_unique(); + if (Error E = dumpCommonSection(*S)) + return std::move(E); + + assert(S->CovFuns.empty()); + assert(TempCovFuns.contains(Offset)); + S->CovFuns = std::move(TempCovFuns[Offset]); + + return S.release(); + } + + llvm_unreachable("Name didn't match"); + } +}; + +class EncoderImpl : public Encoder, CovMapFilenamesResolver { +public: + void collect(ELFYAML::Chunk *Chunk) override { + if (auto S = dyn_cast(Chunk)) { + collectCovMap(S->CovMaps); + } else if (auto S = dyn_cast(Chunk)) { + collectCovFunFilenames(S->CovFuns); + } + } + + void fixup() override { encFixup(); } +}; +} // namespace + +std::unique_ptr Decoder::get(const DecoderParam &Param) { + return std::make_unique(Param); +} + +std::unique_ptr Encoder::get() { + return std::make_unique(); +} + +bool covmap::nameMatches(StringRef Name) { + return (PrfNamesSection::nameMatches(Name) || + CovMapSection::nameMatches(Name) || CovFunSection::nameMatches(Name)); +} + +std::unique_ptr covmap::make_unique(StringRef Name) { + if (PrfNamesSection::nameMatches(Name)) + return std::make_unique(); + else if (CovMapSection::nameMatches(Name)) + return std::make_unique(); + else if (CovFunSection::nameMatches(Name)) + return std::make_unique(); + + return nullptr; +} + +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::InstrProfSymtab::PrfNamesTy) diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp index 9ae76a71ede5e..75b5833983872 100644 --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -18,6 +18,7 @@ #include "llvm/BinaryFormat/ELF.h" #include "llvm/MC/StringTableBuilder.h" #include "llvm/Object/ELFTypes.h" +#include "llvm/ObjectYAML/CovMap.h" #include "llvm/ObjectYAML/DWARFEmitter.h" #include "llvm/ObjectYAML/DWARFYAML.h" #include "llvm/ObjectYAML/ELFYAML.h" @@ -66,6 +67,13 @@ class ContiguousBlobAccumulator { uint64_t getOffset() const { return InitialOffset + OS.tell(); } void writeBlobToStream(raw_ostream &Out) const { Out << OS.str(); } + uint64_t checkAndTell(uint64_t Base) { + uint64_t Offset = OS.tell() - Base; + if (checkLimit(Offset)) + return Offset; + return 0; + } + Error takeLimitError() { // Request to write 0 bytes to check we did not reach the limit. checkLimit(0); @@ -308,6 +316,9 @@ template class ELFState { void writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::CallGraphProfileSection &Section, ContiguousBlobAccumulator &CBA); + void writeSectionContent(Elf_Shdr &SHeader, + const ELFYAML::CovMapSectionBase &Section, + ContiguousBlobAccumulator &CBA); void writeFill(ELFYAML::Fill &Fill, ContiguousBlobAccumulator &CBA); @@ -761,6 +772,13 @@ void ELFState::initSectionHeaders(std::vector &SHeaders, // valid SHN_UNDEF entry since SHT_NULL == 0. SHeaders.resize(Doc.getSections().size()); + auto CovMapEncoder = covmap::Encoder::get(); + for (auto &Chunk : Doc.Chunks) { + if (isa(Chunk.get())) + CovMapEncoder->collect(Chunk.get()); + } + CovMapEncoder->fixup(); + for (const std::unique_ptr &D : Doc.Chunks) { if (ELFYAML::Fill *S = dyn_cast(D.get())) { S->Offset = alignToOffset(CBA, /*Align=*/1, S->Offset); @@ -894,6 +912,8 @@ void ELFState::initSectionHeaders(std::vector &SHeaders, writeSectionContent(SHeader, *S, CBA); } else if (auto S = dyn_cast(Sec)) { writeSectionContent(SHeader, *S, CBA); + } else if (auto S = dyn_cast(Sec)) { + writeSectionContent(SHeader, *S, CBA); } else { llvm_unreachable("Unknown section type"); } @@ -1903,6 +1923,24 @@ void ELFState::writeSectionContent(Elf_Shdr &SHeader, Section.HashValues->size() * 4; } +template +void ELFState::writeSectionContent( + Elf_Shdr &SHeader, const ELFYAML::CovMapSectionBase &Section, + ContiguousBlobAccumulator &CBA) { + if (Section.Info) + SHeader.sh_info = *Section.Info; + + if (Section.Content) + return; + + auto &OS = *CBA.getRawOS(0); + auto BaseOffset = OS.tell(); + if (auto E = Section.encode(OS)) + reportError(std::move(E)); + + SHeader.sh_size = CBA.checkAndTell(BaseOffset); +} + template void ELFState::writeFill(ELFYAML::Fill &Fill, ContiguousBlobAccumulator &CBA) { diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp index 539834fc8d4db..9f4c3ba5d3b76 100644 --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -15,6 +15,7 @@ #include "llvm/ADT/MapVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/BinaryFormat/ELF.h" +#include "llvm/ObjectYAML/CovMap.h" #include "llvm/Support/ARMEHABI.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" @@ -1425,6 +1426,12 @@ static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) { IO.mapOptional("Info", Section.Info); } +static void sectionMapping(IO &IO, ELFYAML::CovMapSectionBase &Section) { + commonSectionMapping(IO, Section); + Section.mapping(IO); + IO.mapOptional("Info", Section.Info); +} + static void sectionMapping(IO &IO, ELFYAML::BBAddrMapSection &Section) { commonSectionMapping(IO, Section); IO.mapOptional("Content", Section.Content); @@ -1734,11 +1741,16 @@ void MappingTraits>::mapping( if (ELFYAML::StackSizesSection::nameMatches(Name)) Section = std::make_unique(); else + Section = covmap::make_unique(Name); + + if (!Section) Section = std::make_unique(); } if (auto S = dyn_cast(Section.get())) sectionMapping(IO, *S); + else if (auto S = dyn_cast(Section.get())) + sectionMapping(IO, *S); else sectionMapping(IO, *cast(Section.get())); } diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp index 819ddd02a24ce..93714a5a05a0d 100644 --- a/llvm/lib/ProfileData/InstrProf.cpp +++ b/llvm/lib/ProfileData/InstrProf.cpp @@ -535,9 +535,9 @@ Error InstrProfSymtab::addVTableWithName(GlobalVariable &VTable, /// \c NameStrings is a string composed of one of more possibly encoded /// sub-strings. The substrings are separated by 0 or more zero bytes. This /// method decodes the string and calls `NameCallback` for each substring. -static Error -readAndDecodeStrings(StringRef NameStrings, - std::function NameCallback) { +static Error readAndDecodeStrings( + StringRef NameStrings, std::function NameCallback, + std::function ChunkCallback = [](bool) {}) { const uint8_t *P = NameStrings.bytes_begin(); const uint8_t *EndP = NameStrings.bytes_end(); while (P < EndP) { @@ -567,6 +567,7 @@ readAndDecodeStrings(StringRef NameStrings, P += UncompressedSize; } // Now parse the name strings. + ChunkCallback(IsCompressed); SmallVector Names; NameStrings.split(Names, getInstrProfNameSeparator()); for (StringRef &Name : Names) @@ -585,6 +586,22 @@ Error InstrProfSymtab::create(StringRef NameStrings) { std::bind(&InstrProfSymtab::addFuncName, this, std::placeholders::_1)); } +Expected +InstrProfSymtab::createAndGetList(ArrayRef Content) { + PrfNamesChunksTy Result; + PrfNamesTy *ArrayP = nullptr; + if (auto E = readAndDecodeStrings( + StringRef(reinterpret_cast(Content.data()), + Content.size()), + [&](StringRef Name) { + ArrayP->emplace_back(Name.str()); + return addFuncName(Name); + }, + [&](bool IsCompressed) { ArrayP = &Result.emplace_back(); })) + return E; + return Result; +} + Error InstrProfSymtab::create(StringRef FuncNameStrings, StringRef VTableNameStrings) { if (Error E = readAndDecodeStrings(FuncNameStrings, diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml b/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml index 9d23dcb67ad2a..7d7f714353a88 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml +++ b/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml @@ -11,72 +11,525 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: D7878914FBE99B074D000000D136449C106D04004C551E9517F40F4F0101000D010715080205020F0016090018001B0D001C009D808080080D001D0104110203040215000A000F19001001858080800819010500081D01030202210006000825001000181001010001 + CovFun: + - FuncName: simple_loops + FuncHash: 0x46D109C4436D1 + FilenamesRef: 0x4F0FF417951E554C + Expressions: [] + Files: + - Index: 0 + Filename: branch-c-general.c + Regions: + - { dLoc: [ 7, 21, 8, 2 ], Ref: 0 } + - { dLoc: [ 2, 15, 0, 22 ], Ref: 1 } + - { dLoc: [ 0, 24, 0, 27 ], Ref: 2 } + - { dLoc: [ 0, 28, 0, 29 ], isGap: true, Ref: 3 } + - { dLoc: [ 0, 29, 1, 4 ], Ref: 3 } + - { dLoc: [ 2, 3, 4, 2 ], Ref: 4 } + - { dLoc: [ 0, 10, 0, 15 ], Ref: 5 } + - { dLoc: [ 0, 16, 1, 5 ], isGap: true, Ref: 6 } + - { dLoc: [ 1, 5, 0, 8 ], Ref: 6 } + - { dLoc: [ 1, 3, 2, 2 ], Ref: 7 } + - { dLoc: [ 0, 6, 0, 8 ], Ref: 8 } + - { dLoc: [ 0, 16, 0, 24 ], Ref: 9 } + - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } - Name: '__llvm_covfun (1)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 83AD05A5F1438E68EA00000052D33558163C11444C551E9517F40F4F010100260111150E02050113001A09001C001F0D002000A1808080080D00210B040D0109000E15000F009080808008150010020615010B000C21000D008E8080800821000E0010310106008C8080800831000C04063100100015290016009780808008290017020629010B000C35000D008E8080800835000E00102D0106008C808080082D000C02062D010B000C3D000D008E808080083D000E0010100201005B1D010502041D0009000A1D0009000F4D000E000F45001000918080800845001100134901050104490009000A490009000F5D000E000F55001000918080800855001100131002010001 + CovFun: + - FuncName: conditionals + FuncHash: 0x44113C165835D352 + FilenamesRef: 0x4F0FF417951E554C + Expressions: [] + Files: + - Index: 0 + Filename: branch-c-general.c + Regions: + - { dLoc: [ 17, 21, 14, 2 ], Ref: 0 } + - { dLoc: [ 1, 19, 0, 26 ], Ref: 1 } + - { dLoc: [ 0, 28, 0, 31 ], Ref: 2 } + - { dLoc: [ 0, 32, 0, 33 ], isGap: true, Ref: 3 } + - { dLoc: [ 0, 33, 11, 4 ], Ref: 3 } + - { dLoc: [ 1, 9, 0, 14 ], Ref: 3 } + - { dLoc: [ 0, 15, 0, 16 ], isGap: true, Ref: 5 } + - { dLoc: [ 0, 16, 2, 6 ], Ref: 5 } + - { dLoc: [ 1, 11, 0, 12 ], Ref: 5 } + - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 8 } + - { dLoc: [ 0, 14, 0, 16 ], Ref: 8 } + - { dLoc: [ 1, 6, 0, 12 ], isGap: true, Ref: 12 } + - { dLoc: [ 0, 12, 4, 6 ], Ref: 12 } + - { dLoc: [ 0, 16, 0, 21 ], Ref: 12 } + - { dLoc: [ 0, 22, 0, 23 ], isGap: true, Ref: 10 } + - { dLoc: [ 0, 23, 2, 6 ], Ref: 10 } + - { dLoc: [ 1, 11, 0, 12 ], Ref: 10 } + - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 13 } + - { dLoc: [ 0, 14, 0, 16 ], Ref: 13 } + - { dLoc: [ 1, 6, 0, 12 ], isGap: true, Ref: 11 } + - { dLoc: [ 0, 12, 2, 6 ], Ref: 11 } + - { dLoc: [ 1, 11, 0, 12 ], Ref: 11 } + - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 15 } + - { dLoc: [ 0, 14, 0, 16 ], Ref: 15 } + - { dLoc: [ 2, 1, 0, 98 ], ExtTag: Skip } + - { dLoc: [ 1, 5, 2, 4 ], Ref: 7 } + - { dLoc: [ 0, 9, 0, 10 ], Ref: 7 } + - { dLoc: [ 0, 9, 0, 15 ], Ref: 7 } + - { dLoc: [ 0, 14, 0, 15 ], Ref: 19 } + - { dLoc: [ 0, 16, 0, 17 ], isGap: true, Ref: 17 } + - { dLoc: [ 0, 17, 0, 19 ], Ref: 17 } + - { dLoc: [ 1, 5, 1, 4 ], Ref: 18 } + - { dLoc: [ 0, 9, 0, 10 ], Ref: 18 } + - { dLoc: [ 0, 9, 0, 15 ], Ref: 18 } + - { dLoc: [ 0, 14, 0, 15 ], Ref: 23 } + - { dLoc: [ 0, 16, 0, 17 ], isGap: true, Ref: 21 } + - { dLoc: [ 0, 17, 0, 19 ], Ref: 21 } + - { dLoc: [ 2, 1, 0, 1 ], ExtTag: Skip } - Name: '__llvm_covfun (2)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 0449C70428C57369F80000003D5C2D0E4B13F9274C551E9517F40F4F01010028012114180210020100010101070008050009008A8080800805000A000C100101000109010313020D000A00111100120093808080081100130604110209000F190010018780808008190107000C1D000D0185808080081D010502041D0009000E21000F018780808008210107000F15010402838080800810010100011501030B021500070008290009008A8080800829000A000C10010100012D010309023100060504310109000F3D00100187808080083D0107000D41000E028780808008410207000A35010C0013390015028380808008100101000139010302023900070008490009008A8080800849000A000C1001010001 + CovFun: + - FuncName: early_exits + FuncHash: 0x27F9134B0E2D5C3D + FilenamesRef: 0x4F0FF417951E554C + Expressions: [] + Files: + - Index: 0 + Filename: branch-c-general.c + Regions: + - { dLoc: [ 33, 20, 24, 2 ], Ref: 0 } + - { dLoc: [ 2, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 7, 0, 8 ], Ref: 0 } + - { dLoc: [ 0, 9, 0, 10 ], isGap: true, Ref: 1 } + - { dLoc: [ 0, 10, 0, 12 ], Ref: 1 } + - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 3, 19, 2 ], Ref: 2 } + - { dLoc: [ 0, 10, 0, 17 ], Ref: 3 } + - { dLoc: [ 0, 18, 0, 19 ], isGap: true, Ref: 4 } + - { dLoc: [ 0, 19, 6, 4 ], Ref: 4 } + - { dLoc: [ 2, 9, 0, 15 ], Ref: 4 } + - { dLoc: [ 0, 16, 1, 7 ], isGap: true, Ref: 6 } + - { dLoc: [ 1, 7, 0, 12 ], Ref: 6 } + - { dLoc: [ 0, 13, 1, 5 ], isGap: true, Ref: 7 } + - { dLoc: [ 1, 5, 2, 4 ], Ref: 7 } + - { dLoc: [ 0, 9, 0, 14 ], Ref: 7 } + - { dLoc: [ 0, 15, 1, 7 ], isGap: true, Ref: 8 } + - { dLoc: [ 1, 7, 0, 15 ], Ref: 8 } + - { dLoc: [ 1, 4, 2, 3 ], isGap: true, Ref: 5 } + - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 3, 11, 2 ], Ref: 5 } + - { dLoc: [ 0, 7, 0, 8 ], Ref: 5 } + - { dLoc: [ 0, 9, 0, 10 ], isGap: true, Ref: 10 } + - { dLoc: [ 0, 10, 0, 12 ], Ref: 10 } + - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 3, 9, 2 ], Ref: 11 } + - { dLoc: [ 0, 6, 5, 4 ], Ref: 12 } + - { dLoc: [ 1, 9, 0, 15 ], Ref: 12 } + - { dLoc: [ 0, 16, 1, 7 ], isGap: true, Ref: 15 } + - { dLoc: [ 1, 7, 0, 13 ], Ref: 15 } + - { dLoc: [ 0, 14, 2, 7 ], isGap: true, Ref: 16 } + - { dLoc: [ 2, 7, 0, 10 ], Ref: 16 } + - { dLoc: [ 1, 12, 0, 19 ], Ref: 13 } + - { dLoc: [ 0, 21, 2, 3 ], isGap: true, Ref: 14 } + - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 3, 2, 2 ], Ref: 14 } + - { dLoc: [ 0, 7, 0, 8 ], Ref: 14 } + - { dLoc: [ 0, 9, 0, 10 ], isGap: true, Ref: 18 } + - { dLoc: [ 0, 10, 0, 12 ], Ref: 18 } + - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } - Name: '__llvm_covfun (3)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 55947829059F255EB80100001B9C495D3463E1D04C551E9517F40F4F01010046013B0E2F02100201000105010F001409001600190D001A009B808080080D001B040400011402858080800810010100230001050104000009000A15000B008C8080800815000C000E11010402818080800810010100011D010126021D01070008210009008A8080800821000A000C1001010001250103000D25000E0283808080081001010001000103210229000A000B2D000C008D808080082D000D03043501030204350109000A39000B008C8080800839000C000E1002010001310103000D31000E0181808080084101011B024501011A024901011902490207000C4D000D0185808080084D0105000F5100100283808080081001010001510103140255000A000F5900100091808080085900110A04610103090400011006918080800869010501110001120185808080086D0105011200011301858080800871010501115D030402838080800810010100015D0103080275000F0015790017001A7D001B009C808080087D001C0604000115028580808008100101003F0001050304000009000A8501000B008C808080088501000C000E8D01010302048D010109000A9101000B008C808080089101000C000E1002010001 + CovFun: + - FuncName: jumps + FuncHash: 0xD0E163345D499C1B + FilenamesRef: 0x4F0FF417951E554C + Expressions: [] + Files: + - Index: 0 + Filename: branch-c-general.c + Regions: + - { dLoc: [ 59, 14, 47, 2 ], Ref: 0 } + - { dLoc: [ 2, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 15, 0, 20 ], Ref: 1 } + - { dLoc: [ 0, 22, 0, 25 ], Ref: 2 } + - { dLoc: [ 0, 26, 0, 27 ], isGap: true, Ref: 3 } + - { dLoc: [ 0, 27, 4, 4 ], Ref: 3 } + - { dLoc: [ 1, 20, 2, 5 ], isGap: true, Tag: Zero } + - { dLoc: [ 1, 1, 0, 35 ], ExtTag: Skip } + - { dLoc: [ 1, 5, 1, 4 ], Tag: Zero } + - { dLoc: [ 0, 9, 0, 10 ], Tag: Zero } + - { dLoc: [ 0, 11, 0, 12 ], isGap: true, Ref: 5 } + - { dLoc: [ 0, 12, 0, 14 ], Ref: 5 } + - { dLoc: [ 1, 4, 2, 1 ], isGap: true, Ref: 4 } + - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 1, 38, 2 ], Ref: 7 } + - { dLoc: [ 1, 7, 0, 8 ], Ref: 7 } + - { dLoc: [ 0, 9, 0, 10 ], isGap: true, Ref: 8 } + - { dLoc: [ 0, 10, 0, 12 ], Ref: 8 } + - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 3, 0, 13 ], Ref: 9 } + - { dLoc: [ 0, 14, 2, 3 ], isGap: true, Ref: 9 } + - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 3, 33, 2 ], Tag: Zero } + - { dLoc: [ 0, 10, 0, 11 ], Ref: 10 } + - { dLoc: [ 0, 12, 0, 13 ], isGap: true, Ref: 11 } + - { dLoc: [ 0, 13, 3, 4 ], Ref: 11 } + - { dLoc: [ 1, 3, 2, 4 ], Ref: 13 } + - { dLoc: [ 1, 9, 0, 10 ], Ref: 13 } + - { dLoc: [ 0, 11, 0, 12 ], isGap: true, Ref: 14 } + - { dLoc: [ 0, 12, 0, 14 ], Ref: 14 } + - { dLoc: [ 2, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 3, 0, 13 ], Ref: 12 } + - { dLoc: [ 0, 14, 1, 1 ], isGap: true, Ref: 12 } + - { dLoc: [ 1, 1, 27, 2 ], Ref: 16 } + - { dLoc: [ 1, 1, 26, 2 ], Ref: 17 } + - { dLoc: [ 1, 1, 25, 2 ], Ref: 18 } + - { dLoc: [ 2, 7, 0, 12 ], Ref: 18 } + - { dLoc: [ 0, 13, 1, 5 ], isGap: true, Ref: 19 } + - { dLoc: [ 1, 5, 0, 15 ], Ref: 19 } + - { dLoc: [ 0, 16, 2, 3 ], isGap: true, Ref: 20 } + - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 3, 20, 2 ], Ref: 20 } + - { dLoc: [ 0, 10, 0, 15 ], Ref: 21 } + - { dLoc: [ 0, 16, 0, 17 ], isGap: true, Ref: 22 } + - { dLoc: [ 0, 17, 10, 4 ], Ref: 22 } + - { dLoc: [ 1, 3, 9, 4 ], Ref: 24 } + - { dLoc: [ 1, 16, 6, 17 ], isGap: true, Tag: Zero } + - { dLoc: [ 1, 5, 1, 17 ], Ref: 26 } + - { dLoc: [ 1, 18, 1, 5 ], isGap: true, Tag: Zero } + - { dLoc: [ 1, 5, 1, 18 ], Ref: 27 } + - { dLoc: [ 1, 19, 1, 5 ], isGap: true, Tag: Zero } + - { dLoc: [ 1, 5, 1, 17 ], Ref: 28 } + - { dLoc: [ 3, 4, 2, 3 ], isGap: true, Ref: 23 } + - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 3, 8, 2 ], Ref: 23 } + - { dLoc: [ 0, 15, 0, 21 ], Ref: 29 } + - { dLoc: [ 0, 23, 0, 26 ], Ref: 30 } + - { dLoc: [ 0, 27, 0, 28 ], isGap: true, Ref: 31 } + - { dLoc: [ 0, 28, 6, 4 ], Ref: 31 } + - { dLoc: [ 1, 21, 2, 5 ], isGap: true, Tag: Zero } + - { dLoc: [ 1, 1, 0, 63 ], ExtTag: Skip } + - { dLoc: [ 1, 5, 3, 4 ], Tag: Zero } + - { dLoc: [ 0, 9, 0, 10 ], Tag: Zero } + - { dLoc: [ 0, 11, 0, 12 ], isGap: true, Ref: 33 } + - { dLoc: [ 0, 12, 0, 14 ], Ref: 33 } + - { dLoc: [ 1, 3, 2, 4 ], Ref: 35 } + - { dLoc: [ 1, 9, 0, 10 ], Ref: 35 } + - { dLoc: [ 0, 11, 0, 12 ], isGap: true, Ref: 36 } + - { dLoc: [ 0, 12, 0, 14 ], Ref: 36 } + - { dLoc: [ 2, 1, 0, 1 ], ExtTag: Skip } - Name: '__llvm_covfun (4)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 7129CA3C268292BF4D0100003E688383C9A099004C551E9517F40F4F01010035016C112502100201011C000217028A80808008090103010A05020402838080800810010100620501031C020D003F0046110048004B15004C00CD8080800815004D1704000119148F80808008210105130F21010B000C25000D008E8080800825000E001010010100152D0105100F2D010B000C31000D008E8080800831000E0010350107000C35000D0185808080083901050D0F39010B000C3D000D008E808080083D000E0010410107000F4100100185808080084501050A0F45010B000C49000D008E8080800849000E00104D0107080F000012039180808008550107021155010D000E59000F00908080800859001000125D010900115101080285808080081001010001610105020F61010B0017650018018980808008650109000F1902040383808080081001010121190203020219000700116D00120093808080086D001300151001010001 + CovFun: + - FuncName: switches + FuncHash: 0x99A0C98383683E + FilenamesRef: 0x4F0FF417951E554C + Expressions: [] + Files: + - Index: 0 + Filename: branch-c-general.c + Regions: + - { dLoc: [ 108, 17, 37, 2 ], Ref: 0 } + - { dLoc: [ 2, 1, 1, 28 ], ExtTag: Skip } + - { dLoc: [ 2, 23, 2, 10 ], isGap: true, Tag: Zero } + - { dLoc: [ 1, 3, 1, 10 ], Ref: 2 } + - { dLoc: [ 2, 4, 2, 3 ], isGap: true, Ref: 1 } + - { dLoc: [ 1, 1, 0, 100 ], ExtTag: Skip } + - { dLoc: [ 1, 3, 28, 2 ], Ref: 1 } + - { dLoc: [ 0, 63, 0, 70 ], Ref: 3 } + - { dLoc: [ 0, 72, 0, 75 ], Ref: 4 } + - { dLoc: [ 0, 76, 0, 77 ], isGap: true, Ref: 5 } + - { dLoc: [ 0, 77, 23, 4 ], Ref: 5 } + - { dLoc: [ 1, 25, 20, 15 ], isGap: true, Tag: Zero } + - { dLoc: [ 1, 5, 19, 15 ], Ref: 8 } + - { dLoc: [ 1, 11, 0, 12 ], Ref: 8 } + - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 9 } + - { dLoc: [ 0, 14, 0, 16 ], Ref: 9 } + - { dLoc: [ 1, 1, 0, 21 ], ExtTag: Skip } + - { dLoc: [ 1, 5, 16, 15 ], Ref: 11 } + - { dLoc: [ 1, 11, 0, 12 ], Ref: 11 } + - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 12 } + - { dLoc: [ 0, 14, 0, 16 ], Ref: 12 } + - { dLoc: [ 1, 7, 0, 12 ], Ref: 13 } + - { dLoc: [ 0, 13, 1, 5 ], isGap: true, Ref: 13 } + - { dLoc: [ 1, 5, 13, 15 ], Ref: 14 } + - { dLoc: [ 1, 11, 0, 12 ], Ref: 14 } + - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 15 } + - { dLoc: [ 0, 14, 0, 16 ], Ref: 15 } + - { dLoc: [ 1, 7, 0, 15 ], Ref: 16 } + - { dLoc: [ 0, 16, 1, 5 ], isGap: true, Ref: 16 } + - { dLoc: [ 1, 5, 10, 15 ], Ref: 17 } + - { dLoc: [ 1, 11, 0, 12 ], Ref: 17 } + - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 18 } + - { dLoc: [ 0, 14, 0, 16 ], Ref: 18 } + - { dLoc: [ 1, 7, 8, 15 ], Ref: 19 } + - { dLoc: [ 0, 18, 3, 17 ], isGap: true, Tag: Zero } + - { dLoc: [ 1, 7, 2, 17 ], Ref: 21 } + - { dLoc: [ 1, 13, 0, 14 ], Ref: 21 } + - { dLoc: [ 0, 15, 0, 16 ], isGap: true, Ref: 22 } + - { dLoc: [ 0, 16, 0, 18 ], Ref: 22 } + - { dLoc: [ 1, 9, 0, 17 ], Ref: 23 } + - { dLoc: [ 1, 8, 2, 5 ], isGap: true, Ref: 20 } + - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 5, 2, 15 ], Ref: 24 } + - { dLoc: [ 1, 11, 0, 23 ], Ref: 24 } + - { dLoc: [ 0, 24, 1, 9 ], isGap: true, Ref: 25 } + - { dLoc: [ 1, 9, 0, 15 ], Ref: 25 } + - { dLoc: [ 2, 4, 3, 3 ], isGap: true, Ref: 6 } + - { dLoc: [ 1, 1, 1, 33 ], ExtTag: Skip } + - { dLoc: [ 2, 3, 2, 2 ], Ref: 6 } + - { dLoc: [ 0, 7, 0, 17 ], Ref: 6 } + - { dLoc: [ 0, 18, 0, 19 ], isGap: true, Ref: 27 } + - { dLoc: [ 0, 19, 0, 21 ], Ref: 27 } + - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } - Name: '__llvm_covfun (5)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 3F4D1C6E6087417B32010000D6FF56B8865A69B64C551E9517F40F4F01010031019301131F02050113001909001B001E0D001F00A0808080080D00201C04000115198C80808008190105180C19010B000C1D000D008E808080081D000E00101001010015250105150C25010B000C29000D008E8080800829000E00102D0107000C2D000D018580808008310105120C31010B000C35000D008E8080800835000E0010390107000C39000D03858080800810010101013D02050D0C3D010B000C41000D008E8080800841000E0010450107000C45000D0185808080084901050A0C49010B000C4D000D008E808080084D000E0010510107000C51000D0385808080081001010101550205050C55010B000C59000D008E8080800859000E00105D0107000C5D000D018580808008610105020C61010B000C65000D008E8080800865000E0010690107000C1003010001 + CovFun: + - FuncName: big_switch + FuncHash: 0xB6695A86B856FFD6 + FilenamesRef: 0x4F0FF417951E554C + Expressions: [] + Files: + - Index: 0 + Filename: branch-c-general.c + Regions: + - { dLoc: [ 147, 19, 31, 2 ], Ref: 0 } + - { dLoc: [ 1, 19, 0, 25 ], Ref: 1 } + - { dLoc: [ 0, 27, 0, 30 ], Ref: 2 } + - { dLoc: [ 0, 31, 0, 32 ], isGap: true, Ref: 3 } + - { dLoc: [ 0, 32, 28, 4 ], Ref: 3 } + - { dLoc: [ 1, 21, 25, 12 ], isGap: true, Tag: Zero } + - { dLoc: [ 1, 5, 24, 12 ], Ref: 6 } + - { dLoc: [ 1, 11, 0, 12 ], Ref: 6 } + - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 7 } + - { dLoc: [ 0, 14, 0, 16 ], Ref: 7 } + - { dLoc: [ 1, 1, 0, 21 ], ExtTag: Skip } + - { dLoc: [ 1, 5, 21, 12 ], Ref: 9 } + - { dLoc: [ 1, 11, 0, 12 ], Ref: 9 } + - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 10 } + - { dLoc: [ 0, 14, 0, 16 ], Ref: 10 } + - { dLoc: [ 1, 7, 0, 12 ], Ref: 11 } + - { dLoc: [ 0, 13, 1, 5 ], isGap: true, Ref: 11 } + - { dLoc: [ 1, 5, 18, 12 ], Ref: 12 } + - { dLoc: [ 1, 11, 0, 12 ], Ref: 12 } + - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 13 } + - { dLoc: [ 0, 14, 0, 16 ], Ref: 13 } + - { dLoc: [ 1, 7, 0, 12 ], Ref: 14 } + - { dLoc: [ 0, 13, 3, 5 ], isGap: true, Ref: 14 } + - { dLoc: [ 1, 1, 1, 1 ], ExtTag: Skip } + - { dLoc: [ 2, 5, 13, 12 ], Ref: 15 } + - { dLoc: [ 1, 11, 0, 12 ], Ref: 15 } + - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 16 } + - { dLoc: [ 0, 14, 0, 16 ], Ref: 16 } + - { dLoc: [ 1, 7, 0, 12 ], Ref: 17 } + - { dLoc: [ 0, 13, 1, 5 ], isGap: true, Ref: 17 } + - { dLoc: [ 1, 5, 10, 12 ], Ref: 18 } + - { dLoc: [ 1, 11, 0, 12 ], Ref: 18 } + - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 19 } + - { dLoc: [ 0, 14, 0, 16 ], Ref: 19 } + - { dLoc: [ 1, 7, 0, 12 ], Ref: 20 } + - { dLoc: [ 0, 13, 3, 5 ], isGap: true, Ref: 20 } + - { dLoc: [ 1, 1, 1, 1 ], ExtTag: Skip } + - { dLoc: [ 2, 5, 5, 12 ], Ref: 21 } + - { dLoc: [ 1, 11, 0, 12 ], Ref: 21 } + - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 22 } + - { dLoc: [ 0, 14, 0, 16 ], Ref: 22 } + - { dLoc: [ 1, 7, 0, 12 ], Ref: 23 } + - { dLoc: [ 0, 13, 1, 5 ], isGap: true, Ref: 23 } + - { dLoc: [ 1, 5, 2, 12 ], Ref: 24 } + - { dLoc: [ 1, 11, 0, 12 ], Ref: 24 } + - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 25 } + - { dLoc: [ 0, 14, 0, 16 ], Ref: 25 } + - { dLoc: [ 1, 7, 0, 12 ], Ref: 26 } + - { dLoc: [ 3, 1, 0, 1 ], ExtTag: Skip } - Name: '__llvm_covfun (6)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 59A48AA8899AA3587200000091E33C8FF36C04004C551E9517F40F4F0101001501B4011A0C02050213001A09001C001F0D002000A1808080080D002108040D0109000E1500120013100101005D0D0109000E1D00120013100101005D0D0109000E0D000900172D0012001725001B001C10010100630D0109000E0D000900173D0012001735001B001C1002010063 + CovFun: + - FuncName: boolean_operators + FuncHash: 0x46CF38F3CE391 + FilenamesRef: 0x4F0FF417951E554C + Expressions: [] + Files: + - Index: 0 + Filename: branch-c-general.c + Regions: + - { dLoc: [ 180, 26, 12, 2 ], Ref: 0 } + - { dLoc: [ 2, 19, 0, 26 ], Ref: 1 } + - { dLoc: [ 0, 28, 0, 31 ], Ref: 2 } + - { dLoc: [ 0, 32, 0, 33 ], isGap: true, Ref: 3 } + - { dLoc: [ 0, 33, 8, 4 ], Ref: 3 } + - { dLoc: [ 1, 9, 0, 14 ], Ref: 3 } + - { dLoc: [ 0, 18, 0, 19 ], Ref: 5 } + - { dLoc: [ 1, 1, 0, 100 ], ExtTag: Skip } + - { dLoc: [ 1, 9, 0, 14 ], Ref: 3 } + - { dLoc: [ 0, 18, 0, 19 ], Ref: 7 } + - { dLoc: [ 1, 1, 0, 100 ], ExtTag: Skip } + - { dLoc: [ 1, 9, 0, 14 ], Ref: 3 } + - { dLoc: [ 0, 9, 0, 23 ], Ref: 3 } + - { dLoc: [ 0, 18, 0, 23 ], Ref: 11 } + - { dLoc: [ 0, 27, 0, 28 ], Ref: 9 } + - { dLoc: [ 1, 1, 0, 113 ], ExtTag: Skip } + - { dLoc: [ 1, 9, 0, 14 ], Ref: 3 } + - { dLoc: [ 0, 9, 0, 23 ], Ref: 3 } + - { dLoc: [ 0, 18, 0, 23 ], Ref: 15 } + - { dLoc: [ 0, 27, 0, 28 ], Ref: 13 } + - { dLoc: [ 2, 1, 0, 113 ], ExtTag: Skip } - Name: '__llvm_covfun (7)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: F5953D044B505D139E0000005FD132562FE71EAC4C551E9517F40F4F0101001D01C201150D02100201000111010A000B11000A001511000F0015090016018580808008090105000810010100010D0103070225000A001125000A001C250015001C1D001D0185808080081D01050008100101000121010304023D001100123D0011001C3D0016001C31001E002135002200231001010061390103020255000A001155000A001C550015001C49001E00214D002200231001010061 + CovFun: + - FuncName: boolop_loops + FuncHash: 0xAC1EE72F5632D15F + FilenamesRef: 0x4F0FF417951E554C + Expressions: [] + Files: + - Index: 0 + Filename: branch-c-general.c + Regions: + - { dLoc: [ 194, 21, 13, 2 ], Ref: 0 } + - { dLoc: [ 2, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 10, 0, 11 ], Ref: 4 } + - { dLoc: [ 0, 10, 0, 21 ], Ref: 4 } + - { dLoc: [ 0, 15, 0, 21 ], Ref: 4 } + - { dLoc: [ 0, 22, 1, 5 ], isGap: true, Ref: 2 } + - { dLoc: [ 1, 5, 0, 8 ], Ref: 2 } + - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 3, 7, 2 ], Ref: 3 } + - { dLoc: [ 0, 10, 0, 17 ], Ref: 9 } + - { dLoc: [ 0, 10, 0, 28 ], Ref: 9 } + - { dLoc: [ 0, 21, 0, 28 ], Ref: 9 } + - { dLoc: [ 0, 29, 1, 5 ], isGap: true, Ref: 7 } + - { dLoc: [ 1, 5, 0, 8 ], Ref: 7 } + - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 3, 4, 2 ], Ref: 8 } + - { dLoc: [ 0, 17, 0, 18 ], Ref: 15 } + - { dLoc: [ 0, 17, 0, 28 ], Ref: 15 } + - { dLoc: [ 0, 22, 0, 28 ], Ref: 15 } + - { dLoc: [ 0, 30, 0, 33 ], Ref: 12 } + - { dLoc: [ 0, 34, 0, 35 ], Ref: 13 } + - { dLoc: [ 1, 1, 0, 104 ], ExtTag: Skip } + - { dLoc: [ 1, 3, 2, 2 ], Ref: 14 } + - { dLoc: [ 0, 10, 0, 17 ], Ref: 21 } + - { dLoc: [ 0, 10, 0, 28 ], Ref: 21 } + - { dLoc: [ 0, 21, 0, 28 ], Ref: 21 } + - { dLoc: [ 0, 30, 0, 33 ], Ref: 18 } + - { dLoc: [ 0, 34, 0, 35 ], Ref: 19 } + - { dLoc: [ 1, 1, 0, 104 ], ExtTag: Skip } - Name: '__llvm_covfun (8)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 20E5C369BDF15C7940000000D0D60000000000004C551E9517F40F4F0101000B01D1011D0702100201000101010B001109001300948080800809001400150D001800191001010001050103020205000B000C01001000111001010001 + CovFun: + - FuncName: conditional_operator + FuncHash: 0xD6D0 + FilenamesRef: 0x4F0FF417951E554C + Expressions: [] + Files: + - Index: 0 + Filename: branch-c-general.c + Regions: + - { dLoc: [ 209, 29, 7, 2 ], Ref: 0 } + - { dLoc: [ 2, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 11, 0, 17 ], Ref: 0 } + - { dLoc: [ 0, 19, 0, 20 ], isGap: true, Ref: 2 } + - { dLoc: [ 0, 20, 0, 21 ], Ref: 2 } + - { dLoc: [ 0, 24, 0, 25 ], Ref: 3 } + - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 3, 2, 2 ], Ref: 1 } + - { dLoc: [ 0, 11, 0, 12 ], Ref: 1 } + - { dLoc: [ 0, 16, 0, 17 ], Ref: 0 } + - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } - Name: '__llvm_covfun (9)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 7DE8E7C47096EB425200000092EAF0986287F0784C551E9517F40F4F0101000D01DA01170B02050113001909001B001E0D001F00A0808080080D002009041502080606100101024D15030B00102100110092808080082100120017250018018780808008250107010619010E0013 + CovFun: + - FuncName: do_fallthrough + FuncHash: 0x78F0876298F0EA92 + FilenamesRef: 0x4F0FF417951E554C + Expressions: [] + Files: + - Index: 0 + Filename: branch-c-general.c + Regions: + - { dLoc: [ 218, 23, 11, 2 ], Ref: 0 } + - { dLoc: [ 1, 19, 0, 25 ], Ref: 1 } + - { dLoc: [ 0, 27, 0, 30 ], Ref: 2 } + - { dLoc: [ 0, 31, 0, 32 ], isGap: true, Ref: 3 } + - { dLoc: [ 0, 32, 9, 4 ], Ref: 3 } + - { dLoc: [ 2, 8, 6, 6 ], Ref: 5 } + - { dLoc: [ 1, 1, 2, 77 ], ExtTag: Skip } + - { dLoc: [ 3, 11, 0, 16 ], Ref: 5 } + - { dLoc: [ 0, 17, 0, 18 ], isGap: true, Ref: 8 } + - { dLoc: [ 0, 18, 0, 23 ], Ref: 8 } + - { dLoc: [ 0, 24, 1, 7 ], isGap: true, Ref: 9 } + - { dLoc: [ 1, 7, 1, 6 ], Ref: 9 } + - { dLoc: [ 1, 14, 0, 19 ], Ref: 6 } - Name: '__llvm_covfun (10)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: FAD58DE7366495DB0A00000018000000000000004C551E9517F40F4F0101000101F501280F02 + CovFun: + - FuncName: main + FuncHash: 0x18 + FilenamesRef: 0x4F0FF417951E554C + Expressions: [] + Files: + - Index: 0 + Filename: branch-c-general.c + Regions: + - { dLoc: [ 245, 40, 15, 2 ], Ref: 0 } - Name: '__llvm_covfun (11)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 4CB4F49D6737EBF922000000D1460000000000004C551E9517F40F4F0101000501E7011B0302050113001909001B001E0D001F00A0808080080D00200104 + CovFun: + - FuncName: 'branch-c-general.c:static_func' + FuncHash: 0x46D1 + FilenamesRef: 0x4F0FF417951E554C + Expressions: [] + Files: + - Index: 0 + Filename: branch-c-general.c + Regions: + - { dLoc: [ 231, 27, 3, 2 ], Ref: 0 } + - { dLoc: [ 1, 19, 0, 25 ], Ref: 1 } + - { dLoc: [ 0, 27, 0, 30 ], Ref: 2 } + - { dLoc: [ 0, 31, 0, 32 ], isGap: true, Ref: 3 } + - { dLoc: [ 0, 32, 1, 4 ], Ref: 3 } - Name: __llvm_covmap Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 0000000017000000000000000600000002140000126272616E63682D632D67656E6572616C2E6300 + CovMap: + - FilenamesRef: 0x4F0FF417951E554C + Version: 6 - Name: __llvm_prf_names Type: SHT_PROGBITS Flags: [ SHF_ALLOC, SHF_GNU_RETAIN ] AddressAlign: 0x1 - Content: A6010073696D706C655F6C6F6F707301636F6E646974696F6E616C73016561726C795F6578697473016A756D7073017377697463686573016269675F73776974636801626F6F6C65616E5F6F70657261746F727301626F6F6C6F705F6C6F6F707301636F6E646974696F6E616C5F6F70657261746F7201646F5F66616C6C7468726F756768016D61696E016272616E63682D632D67656E6572616C2E633A7374617469635F66756E63 + PrfNames: + - - simple_loops + - conditionals + - early_exits + - jumps + - switches + - big_switch + - boolean_operators + - boolop_loops + - conditional_operator + - do_fallthrough + - main + - 'branch-c-general.c:static_func' - Type: SectionHeaderTable Sections: - Name: .strtab @@ -94,84 +547,4 @@ Sections: - Name: '__llvm_covfun (11)' - Name: __llvm_covmap - Name: __llvm_prf_names - - Name: .symtab -Symbols: - - Name: __llvm_covmap - Type: STT_SECTION - Section: __llvm_covmap - - Name: __llvm_prf_names - Type: STT_SECTION - Section: __llvm_prf_names - - Name: __covrec_79BE9FB148987D7u - Type: STT_OBJECT - Section: __llvm_covfun - Binding: STB_WEAK - Size: 0x69 - Other: [ STV_HIDDEN ] - - Name: __covrec_688E43F1A505AD83u - Type: STT_OBJECT - Section: '__llvm_covfun (1)' - Binding: STB_WEAK - Size: 0x106 - Other: [ STV_HIDDEN ] - - Name: __covrec_6973C52804C74904u - Type: STT_OBJECT - Section: '__llvm_covfun (2)' - Binding: STB_WEAK - Size: 0x114 - Other: [ STV_HIDDEN ] - - Name: __covrec_5E259F0529789455u - Type: STT_OBJECT - Section: '__llvm_covfun (3)' - Binding: STB_WEAK - Size: 0x1D4 - Other: [ STV_HIDDEN ] - - Name: __covrec_BF9282263CCA2971u - Type: STT_OBJECT - Section: '__llvm_covfun (4)' - Binding: STB_WEAK - Size: 0x169 - Other: [ STV_HIDDEN ] - - Name: __covrec_7B4187606E1C4D3Fu - Type: STT_OBJECT - Section: '__llvm_covfun (5)' - Binding: STB_WEAK - Size: 0x14E - Other: [ STV_HIDDEN ] - - Name: __covrec_58A39A89A88AA459u - Type: STT_OBJECT - Section: '__llvm_covfun (6)' - Binding: STB_WEAK - Size: 0x8E - Other: [ STV_HIDDEN ] - - Name: __covrec_135D504B043D95F5u - Type: STT_OBJECT - Section: '__llvm_covfun (7)' - Binding: STB_WEAK - Size: 0xBA - Other: [ STV_HIDDEN ] - - Name: __covrec_795CF1BD69C3E520u - Type: STT_OBJECT - Section: '__llvm_covfun (8)' - Binding: STB_WEAK - Size: 0x5C - Other: [ STV_HIDDEN ] - - Name: __covrec_42EB9670C4E7E87Du - Type: STT_OBJECT - Section: '__llvm_covfun (9)' - Binding: STB_WEAK - Size: 0x6E - Other: [ STV_HIDDEN ] - - Name: __covrec_DB956436E78DD5FAu - Type: STT_OBJECT - Section: '__llvm_covfun (10)' - Binding: STB_WEAK - Size: 0x26 - Other: [ STV_HIDDEN ] - - Name: __covrec_F9EB37679DF4B44Cu - Type: STT_OBJECT - Section: '__llvm_covfun (11)' - Binding: STB_WEAK - Size: 0x3E - Other: [ STV_HIDDEN ] ... diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed-single.yaml b/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed-single.yaml index 56f3d4955f4d9..9ea346722b915 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed-single.yaml +++ b/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed-single.yaml @@ -11,22 +11,139 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: F0A0ED2C305C0BB32D02000089B21C19C99E86758F2950E06FBD46E8010100600108194302100701000101010C000E01000C010E01000C020E01000C030E01000C040E25010C000E1D010C000E15010C000E0D010C000E05010C000E100101000101010C000E01000C010E01000C020E01000C030E01000C040E4D010C000E45010C000E3D010C000E35010C000E2D010C000E100101000101010C011001000C031001000C051001000C071001000C091001000D000F69010D000F65010C011065000D000F71010D000F61010C011061000D000F79010D000F5D010C01105D000D000F8101010D000F59010C011059000D000F8901010D000F55010C011055000D000F9101010D000F100101000101010C011001000C031001000C051001000C071001000C091001000D000FAD01010D000FA901010C0110A901000D000FB501010D000FA501010C0110A501000D000FBD01010D000FA101010C0110A101000D000FC501010D000F9D01010C01109D01000D000FCD01010D000F9901010C01109901000D000FD501010D000F10010100010101070008DD010009018580808008DD0101050016E1010017028580808008E101020500161001010001E50101030E02E50100070008E9010009018580808008E90101050016ED010017028580808008ED01020500161001010001F10101030902F10100070008F5010009018580808008F50101050016F9010017028580808008F901020500161001010001FD0101030402FD01000700088102000901858080800881020105001685020017028580808008850202050016 + CovFun: + - FuncName: _Z4funcii + FuncHash: 0x75869EC9191CB289 + FilenamesRef: 0xE846BD6FE050298F + Expressions: [] + Files: + - Index: 0 + Filename: branch-logical-mixed.cpp + Regions: + - { dLoc: [ 8, 25, 67, 2 ], Ref: 0 } + - { dLoc: [ 7, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 12, 0, 14 ], Ref: 0 } + - { dLoc: [ 0, 12, 1, 14 ], Ref: 0 } + - { dLoc: [ 0, 12, 2, 14 ], Ref: 0 } + - { dLoc: [ 0, 12, 3, 14 ], Ref: 0 } + - { dLoc: [ 0, 12, 4, 14 ], Ref: 0 } + - { dLoc: [ 1, 12, 0, 14 ], Ref: 9 } + - { dLoc: [ 1, 12, 0, 14 ], Ref: 7 } + - { dLoc: [ 1, 12, 0, 14 ], Ref: 5 } + - { dLoc: [ 1, 12, 0, 14 ], Ref: 3 } + - { dLoc: [ 1, 12, 0, 14 ], Ref: 1 } + - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 12, 0, 14 ], Ref: 0 } + - { dLoc: [ 0, 12, 1, 14 ], Ref: 0 } + - { dLoc: [ 0, 12, 2, 14 ], Ref: 0 } + - { dLoc: [ 0, 12, 3, 14 ], Ref: 0 } + - { dLoc: [ 0, 12, 4, 14 ], Ref: 0 } + - { dLoc: [ 1, 12, 0, 14 ], Ref: 19 } + - { dLoc: [ 1, 12, 0, 14 ], Ref: 17 } + - { dLoc: [ 1, 12, 0, 14 ], Ref: 15 } + - { dLoc: [ 1, 12, 0, 14 ], Ref: 13 } + - { dLoc: [ 1, 12, 0, 14 ], Ref: 11 } + - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 12, 1, 16 ], Ref: 0 } + - { dLoc: [ 0, 12, 3, 16 ], Ref: 0 } + - { dLoc: [ 0, 12, 5, 16 ], Ref: 0 } + - { dLoc: [ 0, 12, 7, 16 ], Ref: 0 } + - { dLoc: [ 0, 12, 9, 16 ], Ref: 0 } + - { dLoc: [ 0, 13, 0, 15 ], Ref: 0 } + - { dLoc: [ 1, 13, 0, 15 ], Ref: 26 } + - { dLoc: [ 1, 12, 1, 16 ], Ref: 25 } + - { dLoc: [ 0, 13, 0, 15 ], Ref: 25 } + - { dLoc: [ 1, 13, 0, 15 ], Ref: 28 } + - { dLoc: [ 1, 12, 1, 16 ], Ref: 24 } + - { dLoc: [ 0, 13, 0, 15 ], Ref: 24 } + - { dLoc: [ 1, 13, 0, 15 ], Ref: 30 } + - { dLoc: [ 1, 12, 1, 16 ], Ref: 23 } + - { dLoc: [ 0, 13, 0, 15 ], Ref: 23 } + - { dLoc: [ 1, 13, 0, 15 ], Ref: 32 } + - { dLoc: [ 1, 12, 1, 16 ], Ref: 22 } + - { dLoc: [ 0, 13, 0, 15 ], Ref: 22 } + - { dLoc: [ 1, 13, 0, 15 ], Ref: 34 } + - { dLoc: [ 1, 12, 1, 16 ], Ref: 21 } + - { dLoc: [ 0, 13, 0, 15 ], Ref: 21 } + - { dLoc: [ 1, 13, 0, 15 ], Ref: 36 } + - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 12, 1, 16 ], Ref: 0 } + - { dLoc: [ 0, 12, 3, 16 ], Ref: 0 } + - { dLoc: [ 0, 12, 5, 16 ], Ref: 0 } + - { dLoc: [ 0, 12, 7, 16 ], Ref: 0 } + - { dLoc: [ 0, 12, 9, 16 ], Ref: 0 } + - { dLoc: [ 0, 13, 0, 15 ], Ref: 0 } + - { dLoc: [ 1, 13, 0, 15 ], Ref: 43 } + - { dLoc: [ 1, 12, 1, 16 ], Ref: 42 } + - { dLoc: [ 0, 13, 0, 15 ], Ref: 42 } + - { dLoc: [ 1, 13, 0, 15 ], Ref: 45 } + - { dLoc: [ 1, 12, 1, 16 ], Ref: 41 } + - { dLoc: [ 0, 13, 0, 15 ], Ref: 41 } + - { dLoc: [ 1, 13, 0, 15 ], Ref: 47 } + - { dLoc: [ 1, 12, 1, 16 ], Ref: 40 } + - { dLoc: [ 0, 13, 0, 15 ], Ref: 40 } + - { dLoc: [ 1, 13, 0, 15 ], Ref: 49 } + - { dLoc: [ 1, 12, 1, 16 ], Ref: 39 } + - { dLoc: [ 0, 13, 0, 15 ], Ref: 39 } + - { dLoc: [ 1, 13, 0, 15 ], Ref: 51 } + - { dLoc: [ 1, 12, 1, 16 ], Ref: 38 } + - { dLoc: [ 0, 13, 0, 15 ], Ref: 38 } + - { dLoc: [ 1, 13, 0, 15 ], Ref: 53 } + - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 7, 0, 8 ], Ref: 0 } + - { dLoc: [ 0, 9, 1, 5 ], isGap: true, Ref: 55 } + - { dLoc: [ 1, 5, 0, 22 ], Ref: 55 } + - { dLoc: [ 0, 23, 2, 5 ], isGap: true, Ref: 56 } + - { dLoc: [ 2, 5, 0, 22 ], Ref: 56 } + - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 3, 14, 2 ], Ref: 57 } + - { dLoc: [ 0, 7, 0, 8 ], Ref: 57 } + - { dLoc: [ 0, 9, 1, 5 ], isGap: true, Ref: 58 } + - { dLoc: [ 1, 5, 0, 22 ], Ref: 58 } + - { dLoc: [ 0, 23, 2, 5 ], isGap: true, Ref: 59 } + - { dLoc: [ 2, 5, 0, 22 ], Ref: 59 } + - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 3, 9, 2 ], Ref: 60 } + - { dLoc: [ 0, 7, 0, 8 ], Ref: 60 } + - { dLoc: [ 0, 9, 1, 5 ], isGap: true, Ref: 61 } + - { dLoc: [ 1, 5, 0, 22 ], Ref: 61 } + - { dLoc: [ 0, 23, 2, 5 ], isGap: true, Ref: 62 } + - { dLoc: [ 2, 5, 0, 22 ], Ref: 62 } + - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 3, 4, 2 ], Ref: 63 } + - { dLoc: [ 0, 7, 0, 8 ], Ref: 63 } + - { dLoc: [ 0, 9, 1, 5 ], isGap: true, Ref: 64 } + - { dLoc: [ 1, 5, 0, 22 ], Ref: 64 } + - { dLoc: [ 0, 23, 2, 5 ], isGap: true, Ref: 65 } + - { dLoc: [ 2, 5, 0, 22 ], Ref: 65 } - Name: '__llvm_covfun (1)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: FAD58DE7366495DB0900000018000000000000008F2950E06FBD46E801010001014F010402 + CovFun: + - FuncName: main + FuncHash: 0x18 + FilenamesRef: 0xE846BD6FE050298F + Expressions: [] + Files: + - Index: 0 + Filename: branch-logical-mixed.cpp + Regions: + - { dLoc: [ 79, 1, 4, 2 ], Ref: 0 } - Name: __llvm_covmap Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 000000001D0000000000000006000000021A0000186272616E63682D6C6F676963616C2D6D697865642E637070000000 + CovMap: + - FilenamesRef: 0xE846BD6FE050298F + Version: 6 - Name: __llvm_prf_names Type: SHT_PROGBITS Flags: [ SHF_ALLOC, SHF_GNU_RETAIN ] AddressAlign: 0x1 - Content: 0E005F5A3466756E636969016D61696E + PrfNames: + - - _Z4funcii + - main - Type: SectionHeaderTable Sections: - Name: .strtab @@ -34,24 +151,4 @@ Sections: - Name: '__llvm_covfun (1)' - Name: __llvm_covmap - Name: __llvm_prf_names - - Name: .symtab -Symbols: - - Name: __llvm_covmap - Type: STT_SECTION - Section: __llvm_covmap - - Name: __llvm_prf_names - Type: STT_SECTION - Section: __llvm_prf_names - - Name: __covrec_B30B5C302CEDA0F0u - Type: STT_OBJECT - Section: __llvm_covfun - Binding: STB_WEAK - Size: 0x249 - Other: [ STV_HIDDEN ] - - Name: __covrec_DB956436E78DD5FAu - Type: STT_OBJECT - Section: '__llvm_covfun (1)' - Binding: STB_WEAK - Size: 0x25 - Other: [ STV_HIDDEN ] ... diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.yaml b/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.yaml index 5c5f62b11863b..00a085c3e660f 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.yaml +++ b/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.yaml @@ -11,27 +11,233 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: F0A0ED2C305C0BB33F010000D238C8100334540693E696313ECE8F5D15010101010101010101010101010101010101010101001501101911020C010C0011140015001A100101005C1C010C0011100101006224010C001210010100682C010C0012100101006E34010C0012100101007401010A000B01000A001001000A001501000A001A45000F00103D00140015350019001A2D001E001F10010104550201050F001701000F00170105060F00170301070F001F3C00100015440019001E014C0910001501540A100016015C0B1000160201050F001701000F0017010D060F00170301070F001F64001000156C0019001E017409100015017C0A1000160201050F001701000F00170115060F00170301070F001F8401001000158C010019001E019401091000150201050F001701000F0017011D060F00170301070F001F9C0100100015A4010019001E0201050F001701000F00170125060F0017 + CovFun: + - FuncName: _Z4funcii + FuncHash: 0x654340310C838D2 + FilenamesRef: 0x5D8FCE3E3196E693 + Expressions: [] + Files: + - Index: 0 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 16, 25, 17, 2 ], Ref: 0 } + - { dLoc: [ 1, 12, 0, 17 ], Expansion: 1 } + - { dLoc: [ 0, 21, 0, 26 ], Expansion: 2 } + - { dLoc: [ 1, 1, 0, 92 ], ExtTag: Skip } + - { dLoc: [ 1, 12, 0, 17 ], Expansion: 3 } + - { dLoc: [ 1, 1, 0, 98 ], ExtTag: Skip } + - { dLoc: [ 1, 12, 0, 18 ], Expansion: 4 } + - { dLoc: [ 1, 1, 0, 104 ], ExtTag: Skip } + - { dLoc: [ 1, 12, 0, 18 ], Expansion: 5 } + - { dLoc: [ 1, 1, 0, 110 ], ExtTag: Skip } + - { dLoc: [ 1, 12, 0, 18 ], Expansion: 6 } + - { dLoc: [ 1, 1, 0, 116 ], ExtTag: Skip } + - { dLoc: [ 1, 10, 0, 11 ], Ref: 0 } + - { dLoc: [ 0, 10, 0, 16 ], Ref: 0 } + - { dLoc: [ 0, 10, 0, 21 ], Ref: 0 } + - { dLoc: [ 0, 10, 0, 26 ], Ref: 0 } + - { dLoc: [ 0, 15, 0, 16 ], Ref: 17 } + - { dLoc: [ 0, 20, 0, 21 ], Ref: 15 } + - { dLoc: [ 0, 25, 0, 26 ], Ref: 13 } + - { dLoc: [ 0, 30, 0, 31 ], Ref: 11 } + - { dLoc: [ 1, 1, 4, 85 ], ExtTag: Skip } + - Index: 1 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 5, 15, 0, 23 ], Ref: 0 } + - { dLoc: [ 0, 15, 0, 23 ], Ref: 0 } + - Index: 2 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 6, 15, 0, 23 ], Ref: 1 } + - Index: 3 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 7, 15, 0, 31 ], Ref: 0 } + - { dLoc: [ 0, 16, 0, 21 ], Expansion: 7 } + - { dLoc: [ 0, 25, 0, 30 ], Expansion: 8 } + - Index: 4 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 9, 16, 0, 21 ], Expansion: 9 } + - Index: 5 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 10, 16, 0, 22 ], Expansion: 10 } + - Index: 6 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 11, 16, 0, 22 ], Expansion: 11 } + - Index: 7 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 5, 15, 0, 23 ], Ref: 0 } + - { dLoc: [ 0, 15, 0, 23 ], Ref: 0 } + - Index: 8 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 6, 15, 0, 23 ], Ref: 3 } + - Index: 9 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 7, 15, 0, 31 ], Ref: 0 } + - { dLoc: [ 0, 16, 0, 21 ], Expansion: 12 } + - { dLoc: [ 0, 25, 0, 30 ], Expansion: 13 } + - Index: 10 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 9, 16, 0, 21 ], Expansion: 14 } + - Index: 11 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 10, 16, 0, 22 ], Expansion: 15 } + - Index: 12 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 5, 15, 0, 23 ], Ref: 0 } + - { dLoc: [ 0, 15, 0, 23 ], Ref: 0 } + - Index: 13 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 6, 15, 0, 23 ], Ref: 5 } + - Index: 14 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 7, 15, 0, 31 ], Ref: 0 } + - { dLoc: [ 0, 16, 0, 21 ], Expansion: 16 } + - { dLoc: [ 0, 25, 0, 30 ], Expansion: 17 } + - Index: 15 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 9, 16, 0, 21 ], Expansion: 18 } + - Index: 16 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 5, 15, 0, 23 ], Ref: 0 } + - { dLoc: [ 0, 15, 0, 23 ], Ref: 0 } + - Index: 17 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 6, 15, 0, 23 ], Ref: 7 } + - Index: 18 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 7, 15, 0, 31 ], Ref: 0 } + - { dLoc: [ 0, 16, 0, 21 ], Expansion: 19 } + - { dLoc: [ 0, 25, 0, 30 ], Expansion: 20 } + - Index: 19 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 5, 15, 0, 23 ], Ref: 0 } + - { dLoc: [ 0, 15, 0, 23 ], Ref: 0 } + - Index: 20 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 6, 15, 0, 23 ], Ref: 9 } - Name: '__llvm_covfun (1)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: B01D983FC67363959E000000039B9E2C8DB865C493E696313ECE8F5D0D01010101010101010101010101000401241A07020C010E0014140018001D1001010365011C0B1000160405080F002624001000152C0018001D3400200025013C0A1000160305070F001F44001000154C0019001E0119060F0017011D050F00170154091000150205050F001705000F00170121060F00170401070F001F01000F001F5C00100015640019001E0201050F001701000F0017010D060F0017 + CovFun: + - FuncName: _Z5func2ii + FuncHash: 0xC465B88D2C9E9B03 + FilenamesRef: 0x5D8FCE3E3196E693 + Expressions: [] + Files: + - Index: 0 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 36, 26, 7, 2 ], Ref: 0 } + - { dLoc: [ 1, 14, 0, 20 ], Expansion: 1 } + - { dLoc: [ 0, 24, 0, 29 ], Expansion: 2 } + - { dLoc: [ 1, 1, 3, 108 ], ExtTag: Skip } + - Index: 1 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 11, 16, 0, 22 ], Expansion: 3 } + - Index: 2 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 8, 15, 0, 38 ], Ref: 1 } + - { dLoc: [ 0, 16, 0, 21 ], Expansion: 4 } + - { dLoc: [ 0, 24, 0, 29 ], Expansion: 5 } + - { dLoc: [ 0, 32, 0, 37 ], Expansion: 6 } + - Index: 3 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 10, 16, 0, 22 ], Expansion: 7 } + - Index: 4 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 7, 15, 0, 31 ], Ref: 1 } + - { dLoc: [ 0, 16, 0, 21 ], Expansion: 8 } + - { dLoc: [ 0, 25, 0, 30 ], Expansion: 9 } + - Index: 5 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 6, 15, 0, 23 ], Ref: 6 } + - Index: 6 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 5, 15, 0, 23 ], Ref: 7 } + - Index: 7 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 9, 16, 0, 21 ], Expansion: 10 } + - Index: 8 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 5, 15, 0, 23 ], Ref: 1 } + - { dLoc: [ 0, 15, 0, 23 ], Ref: 1 } + - Index: 9 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 6, 15, 0, 23 ], Ref: 8 } + - Index: 10 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 7, 15, 0, 31 ], Ref: 0 } + - { dLoc: [ 0, 15, 0, 31 ], Ref: 0 } + - { dLoc: [ 0, 16, 0, 21 ], Expansion: 11 } + - { dLoc: [ 0, 25, 0, 30 ], Expansion: 12 } + - Index: 11 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 5, 15, 0, 23 ], Ref: 0 } + - { dLoc: [ 0, 15, 0, 23 ], Ref: 0 } + - Index: 12 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 6, 15, 0, 23 ], Ref: 3 } - Name: '__llvm_covfun (2)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: FAD58DE7366495DB09000000180000000000000093E696313ECE8F5D01010001012F010502 + CovFun: + - FuncName: main + FuncHash: 0x18 + FilenamesRef: 0x5D8FCE3E3196E693 + Expressions: [] + Files: + - Index: 0 + Filename: branch-macros.cpp + Regions: + - { dLoc: [ 47, 1, 5, 2 ], Ref: 0 } - Name: __llvm_covmap Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 0000000016000000000000000600000002130000116272616E63682D6D6163726F732E6370700000 + CovMap: + - FilenamesRef: 0x5D8FCE3E3196E693 + Version: 6 - Name: __llvm_prf_names Type: SHT_PROGBITS Flags: [ SHF_ALLOC, SHF_GNU_RETAIN ] AddressAlign: 0x1 - Content: 19005F5A3466756E636969015F5A3566756E63326969016D61696E + PrfNames: + - - _Z4funcii + - _Z5func2ii + - main - Type: SectionHeaderTable Sections: - Name: .strtab @@ -40,30 +246,4 @@ Sections: - Name: '__llvm_covfun (2)' - Name: __llvm_covmap - Name: __llvm_prf_names - - Name: .symtab -Symbols: - - Name: __llvm_covmap - Type: STT_SECTION - Section: __llvm_covmap - - Name: __llvm_prf_names - Type: STT_SECTION - Section: __llvm_prf_names - - Name: __covrec_B30B5C302CEDA0F0u - Type: STT_OBJECT - Section: __llvm_covfun - Binding: STB_WEAK - Size: 0x15B - Other: [ STV_HIDDEN ] - - Name: __covrec_956373C63F981DB0u - Type: STT_OBJECT - Section: '__llvm_covfun (1)' - Binding: STB_WEAK - Size: 0xBA - Other: [ STV_HIDDEN ] - - Name: __covrec_DB956436E78DD5FAu - Type: STT_OBJECT - Section: '__llvm_covfun (2)' - Binding: STB_WEAK - Size: 0x25 - Other: [ STV_HIDDEN ] ... diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-templates-single.yaml b/llvm/test/tools/llvm-cov/Inputs/branch-templates-single.yaml index d4ede6db448e6..03e918953cdc9 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-templates-single.yaml +++ b/llvm/test/tools/llvm-cov/Inputs/branch-templates-single.yaml @@ -11,32 +11,107 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: FAD58DE7366495DB5100000058242991A444920226ED9A40DAABBC6B0101000D011D0C090201010700130500140185808080080501050016090103060209000700170D00180185808080080D01050016110103040211000700171500180185808080081501050016190103010B + CovFun: + - FuncName: main + FuncHash: 0x29244A491292458 + FilenamesRef: 0x6BBCABDA409AED26 + Expressions: [] + Files: + - Index: 0 + Filename: branch-templates.cpp + Regions: + - { dLoc: [ 29, 12, 9, 2 ], Ref: 0 } + - { dLoc: [ 1, 7, 0, 19 ], Ref: 0 } + - { dLoc: [ 0, 20, 1, 5 ], isGap: true, Ref: 1 } + - { dLoc: [ 1, 5, 0, 22 ], Ref: 1 } + - { dLoc: [ 1, 3, 6, 2 ], Ref: 2 } + - { dLoc: [ 0, 7, 0, 23 ], Ref: 2 } + - { dLoc: [ 0, 24, 1, 5 ], isGap: true, Ref: 3 } + - { dLoc: [ 1, 5, 0, 22 ], Ref: 3 } + - { dLoc: [ 1, 3, 4, 2 ], Ref: 4 } + - { dLoc: [ 0, 7, 0, 23 ], Ref: 4 } + - { dLoc: [ 0, 24, 1, 5 ], isGap: true, Ref: 5 } + - { dLoc: [ 1, 5, 0, 22 ], Ref: 5 } + - { dLoc: [ 1, 3, 1, 11 ], Ref: 6 } - Name: '__llvm_covfun (1)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 5427717259E0E43E38000000113661920200000026ED9A40DAABBC6B01010008010D0F06020101060007050008018580808008050105000D09000E028580808008090205000D0D000E0183808080080D01030102 + CovFun: + - FuncName: _Z4funcIiEiT_ + FuncHash: 0x292613611 + FilenamesRef: 0x6BBCABDA409AED26 + Expressions: [] + Files: + - Index: 0 + Filename: branch-templates.cpp + Regions: + - { dLoc: [ 13, 15, 6, 2 ], Ref: 0 } + - { dLoc: [ 1, 6, 0, 7 ], Ref: 0 } + - { dLoc: [ 0, 8, 1, 5 ], isGap: true, Ref: 1 } + - { dLoc: [ 1, 5, 0, 13 ], Ref: 1 } + - { dLoc: [ 0, 14, 2, 5 ], isGap: true, Ref: 2 } + - { dLoc: [ 2, 5, 0, 13 ], Ref: 2 } + - { dLoc: [ 0, 14, 1, 3 ], isGap: true, Ref: 3 } + - { dLoc: [ 1, 3, 1, 2 ], Ref: 3 } - Name: '__llvm_covfun (2)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 4B7E22082F0551AA38000000113661920200000026ED9A40DAABBC6B01010008010D0F06020101060007050008018580808008050105000D09000E028580808008090205000D0D000E0183808080080D01030102 + CovFun: + - FuncName: _Z4funcIbEiT_ + FuncHash: 0x292613611 + FilenamesRef: 0x6BBCABDA409AED26 + Expressions: [] + Files: + - Index: 0 + Filename: branch-templates.cpp + Regions: + - { dLoc: [ 13, 15, 6, 2 ], Ref: 0 } + - { dLoc: [ 1, 6, 0, 7 ], Ref: 0 } + - { dLoc: [ 0, 8, 1, 5 ], isGap: true, Ref: 1 } + - { dLoc: [ 1, 5, 0, 13 ], Ref: 1 } + - { dLoc: [ 0, 14, 2, 5 ], isGap: true, Ref: 2 } + - { dLoc: [ 2, 5, 0, 13 ], Ref: 2 } + - { dLoc: [ 0, 14, 1, 3 ], isGap: true, Ref: 3 } + - { dLoc: [ 1, 3, 1, 2 ], Ref: 3 } - Name: '__llvm_covfun (3)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: AC1440BC3DA3E41A38000000113661920200000026ED9A40DAABBC6B01010008010D0F06020101060007050008018580808008050105000D09000E028580808008090205000D0D000E0183808080080D01030102 + CovFun: + - FuncName: _Z4funcIfEiT_ + FuncHash: 0x292613611 + FilenamesRef: 0x6BBCABDA409AED26 + Expressions: [] + Files: + - Index: 0 + Filename: branch-templates.cpp + Regions: + - { dLoc: [ 13, 15, 6, 2 ], Ref: 0 } + - { dLoc: [ 1, 6, 0, 7 ], Ref: 0 } + - { dLoc: [ 0, 8, 1, 5 ], isGap: true, Ref: 1 } + - { dLoc: [ 1, 5, 0, 13 ], Ref: 1 } + - { dLoc: [ 0, 14, 2, 5 ], isGap: true, Ref: 2 } + - { dLoc: [ 2, 5, 0, 13 ], Ref: 2 } + - { dLoc: [ 0, 14, 1, 3 ], isGap: true, Ref: 3 } + - { dLoc: [ 1, 3, 1, 2 ], Ref: 3 } - Name: __llvm_covmap Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 0000000019000000000000000600000002160000146272616E63682D74656D706C617465732E637070000000 + CovMap: + - FilenamesRef: 0x6BBCABDA409AED26 + Version: 6 - Name: __llvm_prf_names Type: SHT_PROGBITS Flags: [ SHF_ALLOC, SHF_GNU_RETAIN ] AddressAlign: 0x1 - Content: 2E006D61696E015F5A3466756E6349694569545F015F5A3466756E6349624569545F015F5A3466756E6349664569545F + PrfNames: + - - main + - _Z4funcIiEiT_ + - _Z4funcIbEiT_ + - _Z4funcIfEiT_ - Type: SectionHeaderTable Sections: - Name: .strtab @@ -46,36 +121,4 @@ Sections: - Name: '__llvm_covfun (3)' - Name: __llvm_covmap - Name: __llvm_prf_names - - Name: .symtab -Symbols: - - Name: __llvm_covmap - Type: STT_SECTION - Section: __llvm_covmap - - Name: __llvm_prf_names - Type: STT_SECTION - Section: __llvm_prf_names - - Name: __covrec_DB956436E78DD5FAu - Type: STT_OBJECT - Section: __llvm_covfun - Binding: STB_WEAK - Size: 0x6D - Other: [ STV_HIDDEN ] - - Name: __covrec_3EE4E05972712754u - Type: STT_OBJECT - Section: '__llvm_covfun (1)' - Binding: STB_WEAK - Size: 0x54 - Other: [ STV_HIDDEN ] - - Name: __covrec_AA51052F08227E4Bu - Type: STT_OBJECT - Section: '__llvm_covfun (2)' - Binding: STB_WEAK - Size: 0x54 - Other: [ STV_HIDDEN ] - - Name: __covrec_1AE4A33DBC4014ACu - Type: STT_OBJECT - Section: '__llvm_covfun (3)' - Binding: STB_WEAK - Size: 0x54 - Other: [ STV_HIDDEN ] ... diff --git a/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.yaml b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.yaml index 84b184023f082..cd82f4437ae55 100644 --- a/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.yaml +++ b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.yaml @@ -11,35 +11,58 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: FAD58DE7366495DB9A0000006733DBEA42F87ED3C60E0B951FF3509D0101001A01060C130210020100010101070008050009008A8080800805000A0204090204008A8080800809000A020410030100010D01030A02110013001A15001C001F19002000A180808008190021020410030100011D010306021D0007000D25000F0090808080082500100015290018001D2101030502210007000D31000F018980808008310109000E350109000E10010100012D0103000B + CovFun: + - FuncName: main + FuncHash: 0xD37EF842EADB3367 + FilenamesRef: 0x9D50F31F950B0EC6 + Expressions: [] + Files: + - Index: 0 + Filename: showLineExecutionCounts.cpp + Regions: + - { dLoc: [ 6, 12, 19, 2 ], Ref: 0 } + - { dLoc: [ 2, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 7, 0, 8 ], Ref: 0 } + - { dLoc: [ 0, 9, 0, 10 ], isGap: true, Ref: 1 } + - { dLoc: [ 0, 10, 2, 4 ], Ref: 1 } + - { dLoc: [ 2, 4, 0, 10 ], isGap: true, Ref: 2 } + - { dLoc: [ 0, 10, 2, 4 ], Ref: 2 } + - { dLoc: [ 3, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 3, 10, 2 ], Ref: 3 } + - { dLoc: [ 0, 19, 0, 26 ], Ref: 4 } + - { dLoc: [ 0, 28, 0, 31 ], Ref: 5 } + - { dLoc: [ 0, 32, 0, 33 ], isGap: true, Ref: 6 } + - { dLoc: [ 0, 33, 2, 4 ], Ref: 6 } + - { dLoc: [ 3, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 3, 6, 2 ], Ref: 7 } + - { dLoc: [ 0, 7, 0, 13 ], Ref: 7 } + - { dLoc: [ 0, 15, 0, 16 ], isGap: true, Ref: 9 } + - { dLoc: [ 0, 16, 0, 21 ], Ref: 9 } + - { dLoc: [ 0, 24, 0, 29 ], Ref: 10 } + - { dLoc: [ 1, 3, 5, 2 ], Ref: 8 } + - { dLoc: [ 0, 7, 0, 13 ], Ref: 8 } + - { dLoc: [ 0, 15, 1, 9 ], isGap: true, Ref: 12 } + - { dLoc: [ 1, 9, 0, 14 ], Ref: 12 } + - { dLoc: [ 1, 9, 0, 14 ], Ref: 13 } + - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } + - { dLoc: [ 1, 3, 0, 11 ], Ref: 11 } - Name: __llvm_covmap Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 00000000200000000000000006000000021D00001B73686F774C696E65457865637574696F6E436F756E74732E637070 + CovMap: + - FilenamesRef: 0x9D50F31F950B0EC6 + Version: 6 - Name: __llvm_prf_names Type: SHT_PROGBITS Flags: [ SHF_ALLOC, SHF_GNU_RETAIN ] AddressAlign: 0x1 - Content: 04006D61696E + PrfNames: + - - main - Type: SectionHeaderTable Sections: - Name: .strtab - Name: __llvm_covfun - Name: __llvm_covmap - Name: __llvm_prf_names - - Name: .symtab -Symbols: - - Name: __llvm_covmap - Type: STT_SECTION - Section: __llvm_covmap - - Name: __llvm_prf_names - Type: STT_SECTION - Section: __llvm_prf_names - - Name: __covrec_DB956436E78DD5FAu - Type: STT_OBJECT - Section: __llvm_covfun - Binding: STB_WEAK - Size: 0xB6 - Other: [ STV_HIDDEN ] ... diff --git a/llvm/test/tools/llvm-cov/Inputs/yaml.makefile b/llvm/test/tools/llvm-cov/Inputs/yaml.makefile index 2a256f0cffc0b..449542cee5477 100644 --- a/llvm/test/tools/llvm-cov/Inputs/yaml.makefile +++ b/llvm/test/tools/llvm-cov/Inputs/yaml.makefile @@ -2,7 +2,7 @@ # # Usage: # cd /path/to/llvm-project/llvm/test/tools/llvm-cov/Inputs -# PATH=/path/to/build/bin:$PATH make -f yaml.makefile +# PATH=/path/to/build/bin:$PATH make -f yaml.makefile *.yaml CFLAGS_COVMAP = -fcoverage-compilation-dir=. \ -mllvm -runtime-counter-relocation=true \ @@ -34,11 +34,11 @@ CFLAGS_MCDC = -fcoverage-mcdc --only-section=__llvm_covfun \ --only-section=__llvm_covmap \ --only-section=__llvm_prf_names \ - --strip-unneeded \ + --strip-all \ $< $@ %.yaml: %.covmap.o - obj2yaml $< > $@ + obj2yaml --covmap --covmap-dloc $< > $@ %.exe: %.o clang++ -fprofile-instr-generate $^ -o $@ diff --git a/llvm/test/tools/obj2yaml/ELF/covmap.yaml b/llvm/test/tools/obj2yaml/ELF/covmap.yaml new file mode 100644 index 0000000000000..52d067a8354a1 --- /dev/null +++ b/llvm/test/tools/obj2yaml/ELF/covmap.yaml @@ -0,0 +1,160 @@ +# RUN: yaml2obj %s -o %t.o +# RUN: obj2yaml %t.o | tee %t.plain.yaml | FileCheck %s --check-prefixes=CHECK,PLAIN +# RUN: obj2yaml --covmap-raw %t.o | tee %t.raw.yaml | FileCheck %s --check-prefixes=CHECK,COVMAP,RAWONLY,RAW,DLOC +# RUN: obj2yaml --covmap --covmap-raw %t.o | tee %t.mixed.yaml | FileCheck %s --check-prefixes=CHECK,COVMAP,RAW,DET,LOC,DLOC +# RUN: obj2yaml --covmap --covmap-dloc %t.o | tee %t.dloc.yaml | FileCheck %s --check-prefixes=CHECK,COVMAP,DET,DETONLY,DLOC +# RUN: obj2yaml --covmap %t.o | tee %t.covmap.yaml | FileCheck %s --check-prefixes=CHECK,COVMAP,DET,DETONLY,LOC +# RUN: sed -E '/^(#.*)?$/d' %s | diff -au %t.covmap.yaml - +# RUN: yaml2obj %t.plain.yaml -o - | cmp %t.o - +# RUN: yaml2obj %t.raw.yaml -o - | cmp %t.o - +# RUN: yaml2obj %t.mixed.yaml -o - | cmp %t.o - +# RUN: yaml2obj %t.dloc.yaml -o - | cmp %t.o - +# RUN: yaml2obj %t.covmap.yaml -o - | cmp %t.o - + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + OSABI: ELFOSABI_GNU + Type: ET_REL + Machine: EM_X86_64 + SectionHeaderStringTable: .strtab +Sections: +# CHECK: __llvm_covfun + - Name: __llvm_covfun + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 +# PLAIN: Content: +# COVMAP: CovFun: + CovFun: +# RAW:- NameRef: 0xA72DB7A33048E6A3 + - FuncName: _Z4funci +# COVMAP: FuncHash: 0xAFC772D567676299 + FuncHash: 0xAFC772D567676299 + FilenamesRef: 0x70DA2CAFD8CE198E +# COVMAP: Expressions: + Expressions: +# RAW: - [ { Tag: Ref, Val: 0 }, { Tag: Ref, Val: 1 } ] + - [ { Ref: 0 }, { Ref: 1 } ] + - [ { Add: 0 }, { Ref: 2 } ] + - [ { Add: 0 }, { Ref: 2 } ] + - [ { Add: 0 }, { Ref: 2 } ] + - [ { Ref: 0 }, { Ref: 2 } ] + - [ { Ref: 0 }, { Ref: 2 } ] + - [ { Ref: 0 }, { Ref: 2 } ] + - [ { Add: 0 }, { Ref: 5 } ] +# COVMAP: Files: + Files: +# DET: - Index: 0 + - Index: 0 +# DET: Filename: func.cpp + Filename: func.cpp +# COVMAP: Regions: + Regions: +# LOC: Loc: [ 3, 17, 14, 2 ] +# DLOC: dLoc: [ 3, 17, 11, 2 ] +# RAW: Tag: Ref, Val: 0 +# DETONLY: Ref: 0 + - { Loc: [ 3, 17, 14, 2 ], Ref: 0 } +# LOC: Loc: [ 6, 6, 11, 4 ] +# DLOC dLoc: [ 3, 6, 5, 4 ] +# RAW: Tag: Add, Val: 0 +# DETONLY: Add: 0 + - { Loc: [ 6, 6, 11, 4 ], Add: 0 } +# COVMAP: Expansion: 1 + - { Loc: [ 7, 9, 7, 13 ], Expansion: 1 } +# COVMAP: isGap: true +# RAW: Tag: Ref, Val: 2 +# DETONLY: Ref: 2 + - { Loc: [ 7, 23, 8, 7 ], isGap: true, Ref: 2 } + - { Loc: [ 8, 7, 8, 16 ], Ref: 2 } +# COVMAP: isGap: true +# RAW: Tag: Sub, Val: 3 +# DETONLY: Sub: 3 + - { Loc: [ 8, 17, 10, 5 ], isGap: true, Sub: 3 } +# COVMAP: ExtTag: Skip + - { Loc: [ 9, 1, 9, 1 ], ExtTag: Skip } + - { Loc: [ 10, 5, 11, 4 ], Sub: 3 } + - { Loc: [ 11, 12, 11, 17 ], Sub: 3 } +# RAW: ExtTag: Branch, Branch: [ { Tag: Ref, Val: 1 }, { Tag: Sub, Val: 6 } ] } +# DETONLY: Branch: [ { Ref: 1 }, { Sub: 6 } ] + - { Loc: [ 11, 12, 11, 17 ], Branch: [ { Ref: 1 }, { Sub: 6 } ] } + - { Loc: [ 11, 19, 12, 3 ], isGap: true, Sub: 6 } + - { Loc: [ 12, 3, 12, 11 ], Sub: 6 } + - { Loc: [ 12, 12, 13, 3 ], isGap: true, Tag: Zero } +# LOC: Loc: [ 13, 3, 13, 12 ] +# DLOC: dLoc: [ 1, 3, 0, 12 ] +# COVMAP: Tag: Zero + - { Loc: [ 13, 3, 13, 12 ], Tag: Zero } +# DET: - Index: 1 + - Index: 1 +# DET: Filename: func.cpp + Filename: func.cpp +# COVMAP: Regions: + Regions: + - { Loc: [ 1, 17, 1, 41 ], Add: 0 } + - { Loc: [ 1, 18, 1, 32 ], Add: 0 } +# RAW: ExtTag: Decision +# COVMAP: Decision: { BIdx: 5, NCond: 3 } } + - { Loc: [ 1, 18, 1, 40 ], Decision: { BIdx: 5, NCond: 3 } } + - { Loc: [ 1, 19, 1, 22 ], Add: 0 } +# RAW: ExtTag: MCDCBranch +# RAW: Branch: [ { Tag: Sub, Val: 7 }, { Tag: Ref, Val: 5 } ] +# DETONLY: Branch: [ { Sub: 7 }, { Ref: 5 } ] +# COVMAP: MCDC: [ 1, 2, 3 ] + - { Loc: [ 1, 19, 1, 22 ], Branch: [ { Sub: 7 }, { Ref: 5 } ], MCDC: [ 1, 2, 3 ] } + - { Loc: [ 1, 26, 1, 31 ], Ref: 5 } + - { Loc: [ 1, 26, 1, 31 ], Branch: [ { Tag: Zero }, { Ref: 6 } ], MCDC: [ 3, 2, 0 ] } + - { Loc: [ 1, 36, 1, 40 ], Ref: 3 } + - { Loc: [ 1, 36, 1, 40 ], Branch: [ { Ref: 4 }, { Tag: Zero } ], MCDC: [ 2, 0, 0 ] } +# CHECK: __llvm_covmap + - Name: __llvm_covmap + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 +# PLAIN: Content: +# COVMAP: CovMap: + CovMap: +# COVMAP: - FilenamesRef: 0x70DA2CAFD8CE198E + - FilenamesRef: 0x70DA2CAFD8CE198E +# COVMAP: Version: + Version: 6 +# RAWONLY: Filenames: +# RAWONLY: - '' +# RAWONLY: - func.cpp +# CHECK: __llvm_prf_names + - Name: __llvm_prf_names + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_GNU_RETAIN ] + AddressAlign: 0x1 +# PLAIN-NOT: CovFun: +# PLAIN-NOT: CovMap: +# PLAIN-NOT: PrfNames: +# PLAIN: Content: +# CovMap: ProfNames + PrfNames: +# CovMap: - - _Z4funci + - - _Z4funci + - Type: SectionHeaderTable + Sections: + - Name: .strtab + - Name: __llvm_covfun + - Name: __llvm_covmap + - Name: __llvm_prf_names +... + +# #define EXPR(x) (((x) || false) && true) +# +# int func(int a) { +# int r = 0; +# int i = 0; +# do { +# if (EXPR(30 <= i)) +# return -1; +# +# r += i++; +# } while (i < a); +# return r; +# return -1; +# } diff --git a/llvm/test/tools/obj2yaml/help.test b/llvm/test/tools/obj2yaml/help.test index 72e8e75b7d158..4f85a255f904d 100644 --- a/llvm/test/tools/obj2yaml/help.test +++ b/llvm/test/tools/obj2yaml/help.test @@ -7,5 +7,6 @@ # CHECK: OVERVIEW: Dump a YAML description from an object file # CHECK: USAGE: obj2yaml{{(.exe)?}} [options] {{$}} # CHECK: OPTIONS: +# CATEG: ELF Options: # CATEG: Generic Options: # CATEG: obj2yaml Options: diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp index b1c8032ea2192..39f50fb05ef6d 100644 --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -11,8 +11,10 @@ #include "llvm/ADT/Twine.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/Object/ELFObjectFile.h" +#include "llvm/ObjectYAML/CovMap.h" #include "llvm/ObjectYAML/DWARFYAML.h" #include "llvm/ObjectYAML/ELFYAML.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/DataExtractor.h" #include "llvm/Support/Errc.h" #include "llvm/Support/ErrorHandling.h" @@ -21,6 +23,18 @@ using namespace llvm; +cl::OptionCategory ELFCat("ELF Options"); + +static cl::opt + CovMapDetailed("covmap", cl::desc("Dump detailed YAML in Coverage Map."), + cl::cat(ELFCat)); +static cl::opt CovMapRaw("covmap-raw", + cl::desc("Dump raw YAML in Coverage Map."), + cl::cat(ELFCat)); +static cl::opt CovMapDLoc("covmap-dloc", + cl::desc("Prefer dLoc thatn absolute Loc."), + cl::cat(ELFCat)); + namespace { template @@ -97,6 +111,8 @@ class ELFDumper { dumpStackSizesSection(const Elf_Shdr *Shdr); Expected dumpBBAddrMapSection(const Elf_Shdr *Shdr); + Expected dumpCovMap(const Elf_Shdr *Shdr, StringRef Name, + covmap::Decoder *CovMapDecoder); Expected dumpPlaceholderSection(const Elf_Shdr *Shdr); @@ -580,6 +596,31 @@ ELFDumper::dumpSections() { return Error::success(); }; + coverage::yaml::DecoderParam Param; + Param.Detailed = CovMapDetailed; + Param.Raw = CovMapRaw; + Param.dLoc = CovMapDLoc; + auto CovMapDecoder = covmap::Decoder::get(Param); + if (covmap::Decoder::enabled) { + // Look up covmap-related sections. + for (const auto &Sec : Sections) { + if (Sec.sh_type != ELF::SHT_PROGBITS) + continue; + + auto NameOrErr = Obj.getSectionName(Sec); + if (!NameOrErr) + return NameOrErr.takeError(); + + if (auto E = CovMapDecoder->acquire( + Sec.sh_offset, Sec.sh_addralign, *NameOrErr, + [&] { return Obj.getSectionContents(Sec); })) + return std::move(E); + } + + if (auto E = CovMapDecoder->fixup()) + return std::move(E); + } + auto GetDumper = [this](unsigned Type) -> std::function(const Elf_Shdr *)> { if (Obj.getHeader().e_machine == ELF::EM_ARM && Type == ELF::SHT_ARM_EXIDX) @@ -661,6 +702,10 @@ ELFDumper::dumpSections() { if (Error E = Add(dumpStackSizesSection(&Sec))) return std::move(E); continue; + } else if (covmap::Decoder::enabled && covmap::nameMatches(*NameOrErr)) { + if (Error E = Add(dumpCovMap(&Sec, *NameOrErr, CovMapDecoder.get()))) + return std::move(E); + continue; } } @@ -1662,6 +1707,15 @@ ELFDumper::dumpMipsABIFlags(const Elf_Shdr *Shdr) { return S.release(); } +template +Expected +ELFDumper::dumpCovMap(const Elf_Shdr *Shdr, StringRef Name, + covmap::Decoder *CovMapDecoder) { + return CovMapDecoder->make(Shdr->sh_offset, Name, [&](ELFYAML::Section &S) { + return dumpCommonSection(Shdr, S); + }); +} + template static Error elf2yaml(raw_ostream &Out, const object::ELFFile &Obj, std::unique_ptr DWARFCtx) { @@ -1671,7 +1725,8 @@ static Error elf2yaml(raw_ostream &Out, const object::ELFFile &Obj, return YAMLOrErr.takeError(); std::unique_ptr YAML(YAMLOrErr.get()); - yaml::Output Yout(Out); + yaml::Output Yout(Out, nullptr, /*WrapColumn*/ + (covmap::Decoder::enabled ? 160 : 70)); Yout << *YAML; return Error::success(); diff --git a/llvm/tools/obj2yaml/obj2yaml.cpp b/llvm/tools/obj2yaml/obj2yaml.cpp index 63c8cc55ee2d4..ecc9f7eed49ff 100644 --- a/llvm/tools/obj2yaml/obj2yaml.cpp +++ b/llvm/tools/obj2yaml/obj2yaml.cpp @@ -101,7 +101,7 @@ static void reportError(StringRef Input, Error Err) { int main(int argc, char *argv[]) { InitLLVM X(argc, argv); - cl::HideUnrelatedOptions(Cat); + cl::HideUnrelatedOptions({&Cat, &ELFCat}); cl::ParseCommandLineOptions( argc, argv, "Dump a YAML description from an object file", nullptr, nullptr, /*LongOptionsUseDoubleDash=*/true); diff --git a/llvm/tools/obj2yaml/obj2yaml.h b/llvm/tools/obj2yaml/obj2yaml.h index 03d7db5317acd..8a10be085eefc 100644 --- a/llvm/tools/obj2yaml/obj2yaml.h +++ b/llvm/tools/obj2yaml/obj2yaml.h @@ -16,11 +16,15 @@ #include "llvm/Object/Minidump.h" #include "llvm/Object/Wasm.h" #include "llvm/Object/XCOFFObjectFile.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/MemoryBufferRef.h" #include "llvm/Support/raw_ostream.h" #include enum RawSegments : unsigned { none = 0, data = 1, linkedit = 1 << 1 }; + +extern llvm::cl::OptionCategory ELFCat; + std::error_code coff2yaml(llvm::raw_ostream &Out, const llvm::object::COFFObjectFile &Obj); llvm::Error elf2yaml(llvm::raw_ostream &Out, diff --git a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel index 2f50dfb1c5802..10ef327e02b9a 100644 --- a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel @@ -1124,9 +1124,11 @@ cc_library( copts = llvm_copts, deps = [ ":BinaryFormat", + ":Coverage", ":DebugInfoCodeView", ":MC", ":Object", + ":ProfileData", ":Support", ":TargetParser", ], From 5aac44a3baf2c9abccd95fde5a7d01d380b02736 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 17 Feb 2025 21:43:59 +0900 Subject: [PATCH 02/10] Reformat. --- llvm/lib/ObjectYAML/ELFYAML.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp index 9f4c3ba5d3b76..0b7cead2d6d19 100644 --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -20,8 +20,8 @@ #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MipsABIFlags.h" -#include "llvm/Support/YAMLTraits.h" #include "llvm/Support/WithColor.h" +#include "llvm/Support/YAMLTraits.h" #include #include #include From e0efeaa04e1b3770473134dc540f6e716178ab67 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 17 Feb 2025 21:47:47 +0900 Subject: [PATCH 03/10] Prune else --- llvm/include/llvm/ObjectYAML/CovMap.h | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/llvm/include/llvm/ObjectYAML/CovMap.h b/llvm/include/llvm/ObjectYAML/CovMap.h index fa9492fc1ee72..e7a03a632e3e4 100644 --- a/llvm/include/llvm/ObjectYAML/CovMap.h +++ b/llvm/include/llvm/ObjectYAML/CovMap.h @@ -56,29 +56,25 @@ template > class VectorOrRef { iterator begin() { if (auto *V = std::get_if(&Array)) return &V->front(); - else - return &std::get(Array).front(); + return &std::get(Array).front(); } iterator end() { if (auto *V = std::get_if(&Array)) return &V->back() + 1; - else - return &std::get(Array).back() + 1; + return &std::get(Array).back() + 1; } size_t size() const { if (const auto *V = std::get_if(&Array)) return V->size(); - else - return std::get(Array).size(); + return std::get(Array).size(); } T &operator[](int Idx) { if (auto *V = std::get_if(&Array)) return (*V)[Idx]; - else - return std::get(Array)[Idx]; + return std::get(Array)[Idx]; } void resize(size_t Size) { std::get(Array).resize(Size); } From ad569f76579985cd7df2a9db4022fb5ffdc2d70e Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 17 Feb 2025 21:49:59 +0900 Subject: [PATCH 04/10] --covmap-dloc --- llvm/tools/obj2yaml/elf2yaml.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp index 39f50fb05ef6d..9f21c2b67a858 100644 --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -32,7 +32,7 @@ static cl::opt CovMapRaw("covmap-raw", cl::desc("Dump raw YAML in Coverage Map."), cl::cat(ELFCat)); static cl::opt CovMapDLoc("covmap-dloc", - cl::desc("Prefer dLoc thatn absolute Loc."), + cl::desc("Prefer dLoc over absolute Loc."), cl::cat(ELFCat)); namespace { From f21cb946a2f10eda966e1d94d1611b7aec30f167 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 17 Feb 2025 22:12:31 +0900 Subject: [PATCH 05/10] Workaround "Unsupported: 'diff': option -a not recognized" --- llvm/test/tools/obj2yaml/ELF/covmap.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/test/tools/obj2yaml/ELF/covmap.yaml b/llvm/test/tools/obj2yaml/ELF/covmap.yaml index 52d067a8354a1..838e85ca0c9a0 100644 --- a/llvm/test/tools/obj2yaml/ELF/covmap.yaml +++ b/llvm/test/tools/obj2yaml/ELF/covmap.yaml @@ -4,7 +4,7 @@ # RUN: obj2yaml --covmap --covmap-raw %t.o | tee %t.mixed.yaml | FileCheck %s --check-prefixes=CHECK,COVMAP,RAW,DET,LOC,DLOC # RUN: obj2yaml --covmap --covmap-dloc %t.o | tee %t.dloc.yaml | FileCheck %s --check-prefixes=CHECK,COVMAP,DET,DETONLY,DLOC # RUN: obj2yaml --covmap %t.o | tee %t.covmap.yaml | FileCheck %s --check-prefixes=CHECK,COVMAP,DET,DETONLY,LOC -# RUN: sed -E '/^(#.*)?$/d' %s | diff -au %t.covmap.yaml - +# RUN: sed -E '/^(#.*)?$/d' %s | diff -c %t.covmap.yaml - # RUN: yaml2obj %t.plain.yaml -o - | cmp %t.o - # RUN: yaml2obj %t.raw.yaml -o - | cmp %t.o - # RUN: yaml2obj %t.mixed.yaml -o - | cmp %t.o - From e1586c723b271c0fba26494a44126a84394449a2 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Tue, 18 Feb 2025 09:20:27 +0900 Subject: [PATCH 06/10] Update covmap.yaml: What's DIFF.EXE on buildkite? --- llvm/test/tools/obj2yaml/ELF/covmap.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/test/tools/obj2yaml/ELF/covmap.yaml b/llvm/test/tools/obj2yaml/ELF/covmap.yaml index 838e85ca0c9a0..fc77a3d02f909 100644 --- a/llvm/test/tools/obj2yaml/ELF/covmap.yaml +++ b/llvm/test/tools/obj2yaml/ELF/covmap.yaml @@ -4,7 +4,7 @@ # RUN: obj2yaml --covmap --covmap-raw %t.o | tee %t.mixed.yaml | FileCheck %s --check-prefixes=CHECK,COVMAP,RAW,DET,LOC,DLOC # RUN: obj2yaml --covmap --covmap-dloc %t.o | tee %t.dloc.yaml | FileCheck %s --check-prefixes=CHECK,COVMAP,DET,DETONLY,DLOC # RUN: obj2yaml --covmap %t.o | tee %t.covmap.yaml | FileCheck %s --check-prefixes=CHECK,COVMAP,DET,DETONLY,LOC -# RUN: sed -E '/^(#.*)?$/d' %s | diff -c %t.covmap.yaml - +# RUN: sed -E '/^(#.*)?$/d' %s | diff %t.covmap.yaml - # RUN: yaml2obj %t.plain.yaml -o - | cmp %t.o - # RUN: yaml2obj %t.raw.yaml -o - | cmp %t.o - # RUN: yaml2obj %t.mixed.yaml -o - | cmp %t.o - From 9adb206f80bf81de157b7cd09c895935d699955b Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Tue, 18 Feb 2025 12:57:29 +0900 Subject: [PATCH 07/10] Make endian::big capable --- llvm/include/llvm/ObjectYAML/CovMap.h | 21 +++-- llvm/include/llvm/ObjectYAML/ELFYAML.h | 2 +- llvm/lib/ObjectYAML/CovMap.cpp | 73 +++++++++-------- llvm/lib/ObjectYAML/ELFEmitter.cpp | 4 +- llvm/test/tools/obj2yaml/ELF/covmap-be.yaml | 90 +++++++++++++++++++++ llvm/tools/obj2yaml/elf2yaml.cpp | 2 +- 6 files changed, 149 insertions(+), 43 deletions(-) create mode 100644 llvm/test/tools/obj2yaml/ELF/covmap-be.yaml diff --git a/llvm/include/llvm/ObjectYAML/CovMap.h b/llvm/include/llvm/ObjectYAML/CovMap.h index e7a03a632e3e4..0c760d7510890 100644 --- a/llvm/include/llvm/ObjectYAML/CovMap.h +++ b/llvm/include/llvm/ObjectYAML/CovMap.h @@ -27,6 +27,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ObjectYAML/ELFYAML.h" +#include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include "llvm/Support/YAMLTraits.h" #include @@ -211,9 +212,9 @@ struct CovFunTy { /// Depends on CovMap and SymTab(IPSK_names) Expected decode(CovMapByRefTy &CovMapByRef, InstrProfSymtab *SymTab, const ArrayRef Content, uint64_t Offset, - const DecoderParam &Param, bool IsLE = true); + endianness Endianness, const DecoderParam &Param); - void encode(raw_ostream &OS) const; + void encode(raw_ostream &OS, endianness Endianness) const; }; /// An element of CovMap array. @@ -242,7 +243,7 @@ struct CovMapTy { StringRef getWD() const { return (WD ? *WD : StringRef()); } Expected decode(const ArrayRef Content, uint64_t Offset, - const DecoderParam &Param, bool IsLE = true); + endianness Endianness, const DecoderParam &Param); /// Generate Accumulated list with WD. /// Returns a single element {WD} if AccFiles is not given. @@ -259,7 +260,7 @@ struct CovMapTy { const std::optional> &AccFilesOpt = std::nullopt, bool Compress = false) const; - void encode(raw_ostream &OS) const; + void encode(raw_ostream &OS, endianness Endianness) const; }; } // namespace llvm::coverage::yaml @@ -326,12 +327,16 @@ LLVM_COVERAGE_YAML_ELEM_MAPPING(CovMapTy) namespace llvm::covmap { class Decoder { +protected: + endianness Endianness; + public: + Decoder(endianness Endianness) : Endianness(Endianness) {} virtual ~Decoder() {} /// Returns DecoderImpl. static std::unique_ptr - get(const coverage::yaml::DecoderParam &Param); + get(endianness Endianness, const coverage::yaml::DecoderParam &Param); /// Called from the Sections loop in advance of the final dump. /// Decoder predecodes Names and CovMap, and captures Contents of @@ -355,11 +360,15 @@ class Decoder { }; class Encoder { +protected: + endianness Endianness; + public: + Encoder(endianness Endianness) : Endianness(Endianness) {} virtual ~Encoder() {} /// Returns EncoderImpl. - static std::unique_ptr get(); + static std::unique_ptr get(endianness Endianness); /// Called from the Sections loop. virtual void collect(ELFYAML::Chunk *Chunk) = 0; diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h index 2dc1a861077c3..e9bb7621b20d9 100644 --- a/llvm/include/llvm/ObjectYAML/ELFYAML.h +++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h @@ -405,7 +405,7 @@ struct CovMapSectionBase : Section { CovMapSectionBase() : Section(ChunkKind::CovMapBase) {} virtual void mapping(yaml::IO &IO) = 0; - virtual Error encode(raw_ostream &OS) const = 0; + virtual Error encode(raw_ostream &OS, endianness Endianness) const = 0; static bool classof(const Chunk *S) { return S->Kind == ChunkKind::CovMapBase; diff --git a/llvm/lib/ObjectYAML/CovMap.cpp b/llvm/lib/ObjectYAML/CovMap.cpp index 12c03a651668c..0bc5164e22def 100644 --- a/llvm/lib/ObjectYAML/CovMap.cpp +++ b/llvm/lib/ObjectYAML/CovMap.cpp @@ -19,6 +19,7 @@ #include "llvm/ProfileData/InstrProf.h" #include "llvm/Support/Alignment.h" #include "llvm/Support/DataExtractor.h" +#include "llvm/Support/Endian.h" #include "llvm/Support/LEB128.h" #include "llvm/Support/MD5.h" #include "llvm/Support/YAMLTraits.h" @@ -285,7 +286,7 @@ Error RecTy::decode(DecoderContext &Data) { return Error::success(); } -void CovFunTy::encode(raw_ostream &OS) const { +void CovFunTy::encode(raw_ostream &OS, endianness Endianness) const { // Encode Body in advance since DataSize should be known. std::string Body; raw_string_ostream SS(Body); @@ -318,7 +319,7 @@ void CovFunTy::encode(raw_ostream &OS) const { #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Initializer) \ if (sizeof(Name) > 1) { \ - Type t = Name; \ + Type t = support::endian::byte_swap(Name, Endianness); \ OS << StringRef(reinterpret_cast(&t), sizeof(t)); \ } #include "llvm/ProfileData/InstrProfData.inc" @@ -378,9 +379,9 @@ CovMapTy::encodeFilenames(const std::optional> &AccFilesOpt, Expected CovFunTy::decode(CovMapByRefTy &CovMapByRef, InstrProfSymtab *Symtab, const ArrayRef Content, - uint64_t Offset, const DecoderParam &Param, - bool IsLE) { - DecoderContext Data(Content, Param, IsLE); + uint64_t Offset, endianness Endianness, + const DecoderParam &Param) { + DecoderContext Data(Content, Param, (Endianness == endianness::little)); Data.seek(Offset); uint32_t DataSize; @@ -466,7 +467,7 @@ Expected CovFunTy::decode(CovMapByRefTy &CovMapByRef, return Data.tell(); } -void CovMapTy::encode(raw_ostream &OS) const { +void CovMapTy::encode(raw_ostream &OS, endianness Endianness) const { auto [FilenamesRef, FilenamesBlob] = encodeFilenames(); uint32_t NRecords = 0; @@ -478,7 +479,8 @@ void CovMapTy::encode(raw_ostream &OS) const { #define COVMAP_HEADER(Type, LLVMType, Name, Initializer) Type Name; #include "llvm/ProfileData/InstrProfData.inc" } CovMapHeader = { -#define COVMAP_HEADER(Type, LLVMType, Name, Initializer) Name, +#define COVMAP_HEADER(Type, LLVMType, Name, Initializer) \ + support::endian::byte_swap(Name, Endianness), #include "llvm/ProfileData/InstrProfData.inc" }; StringRef HeaderBytes(reinterpret_cast(&CovMapHeader), @@ -491,9 +493,9 @@ void CovMapTy::encode(raw_ostream &OS) const { } Expected CovMapTy::decode(const ArrayRef Content, - uint64_t Offset, const DecoderParam &Param, - bool IsLE) { - DecoderContext Data(Content, Param, IsLE); + uint64_t Offset, endianness Endianness, + const DecoderParam &Param) { + DecoderContext Data(Content, Param, (Endianness == endianness::little)); Data.seek(Offset); #define COVMAP_HEADER(Type, LLVMType, Name, Initializer) \ @@ -619,7 +621,7 @@ struct PrfNamesSection : ELFYAML::CovMapSectionBase { IO.mapOptional("PrfNames", PrfNames); } - Error encode(raw_ostream &OS) const override { + Error encode(raw_ostream &OS, endianness Endianness) const override { for (const auto &Names : PrfNames) { std::string Result; if (auto E = @@ -646,7 +648,7 @@ struct CovMapSection : ELFYAML::CovMapSectionBase { } Error decode(ArrayRef Blob, unsigned AddressAlign, - const DecoderParam &Param) { + endianness Endianness, const DecoderParam &Param) { uint64_t Offset = 0; while (true) { @@ -655,7 +657,7 @@ struct CovMapSection : ELFYAML::CovMapSectionBase { break; } auto &CovMap = CovMaps.emplace_back(); - auto Result = CovMap.decode(Blob, Offset, Param); + auto Result = CovMap.decode(Blob, Offset, Endianness, Param); if (!Result) { return Result.takeError(); } @@ -665,12 +667,12 @@ struct CovMapSection : ELFYAML::CovMapSectionBase { return Error::success(); } - Error encode(raw_ostream &OS) const override { + Error encode(raw_ostream &OS, endianness Endianness) const override { auto BaseOffset = OS.tell(); for (const auto &CovMap : CovMaps) { OS.write_zeros(llvm::offsetToAlignment(OS.tell() - BaseOffset, llvm::Align(AddressAlign.value))); - CovMap.encode(OS); + CovMap.encode(OS, Endianness); } return Error::success(); } @@ -691,11 +693,10 @@ struct CovFunSection : ELFYAML::CovMapSectionBase { IO.mapOptional("CovFun", CovFuns); } - static Expected> decode(CovMapByRefTy &CovMapByRef, - InstrProfSymtab *Symtab, - ArrayRef CovFunA, - unsigned AddressAlign, - const DecoderParam &Param) { + static Expected> + decode(CovMapByRefTy &CovMapByRef, InstrProfSymtab *Symtab, + ArrayRef CovFunA, unsigned AddressAlign, + endianness Endianness, const DecoderParam &Param) { std::vector CovFuns; uint64_t Offset = 0; @@ -705,7 +706,8 @@ struct CovFunSection : ELFYAML::CovMapSectionBase { break; auto &CovFun = CovFuns.emplace_back(); - auto Result = CovFun.decode(CovMapByRef, Symtab, CovFunA, Offset, Param); + auto Result = CovFun.decode(CovMapByRef, Symtab, CovFunA, Offset, + Endianness, Param); if (!Result) return Result.takeError(); @@ -715,12 +717,12 @@ struct CovFunSection : ELFYAML::CovMapSectionBase { return std::move(CovFuns); } - Error encode(raw_ostream &OS) const override { + Error encode(raw_ostream &OS, endianness Endianness) const override { auto BaseOffset = OS.tell(); for (auto [I, CovFun] : enumerate(CovFuns)) { OS.write_zeros(llvm::offsetToAlignment(OS.tell() - BaseOffset, llvm::Align(AddressAlign.value))); - CovFun.encode(OS); + CovFun.encode(OS, Endianness); } return Error::success(); } @@ -840,8 +842,9 @@ class DecoderImpl : public Decoder, CovMapFilenamesResolver { DenseMap> TempCovFuns; public: - DecoderImpl(const DecoderParam &Param) - : Param(Param), ProfileNames(std::make_unique()) { + DecoderImpl(endianness Endianness, const DecoderParam &Param) + : Decoder(Endianness), Param(Param), + ProfileNames(std::make_unique()) { enabled = (Param.Detailed || Param.Raw); } @@ -869,7 +872,8 @@ class DecoderImpl : public Decoder, CovMapFilenamesResolver { // Decode CovMaps in advance, since only CovMap knows its Version. // CovMaps is restored (into CovMapSection) later. auto TempCovMap = std::make_unique(); - if (auto E = TempCovMap->decode(*ContentOrErr, AddressAlign, Param)) + if (auto E = TempCovMap->decode(*ContentOrErr, AddressAlign, Endianness, + Param)) return E; moveAndCollectCovMap(std::move(TempCovMap->CovMaps)); } else if (CovFunSection::nameMatches(Name)) { @@ -887,9 +891,9 @@ class DecoderImpl : public Decoder, CovMapFilenamesResolver { Error fixup() override { // Decode CovFun(s) with predecoded PrfNames and CovMap. for (const auto &[Offset, CovFunBlob] : CovFunBlobs) { - auto CovFunsOrErr = - CovFunSection::decode(CovMapByRef, ProfileNames.get(), - CovFunBlob.first, CovFunBlob.second, Param); + auto CovFunsOrErr = CovFunSection::decode( + CovMapByRef, ProfileNames.get(), CovFunBlob.first, CovFunBlob.second, + Endianness, Param); if (!CovFunsOrErr) return CovFunsOrErr.takeError(); TempCovFuns[Offset] = std::move(*CovFunsOrErr); @@ -938,6 +942,8 @@ class DecoderImpl : public Decoder, CovMapFilenamesResolver { class EncoderImpl : public Encoder, CovMapFilenamesResolver { public: + EncoderImpl(endianness Endianness) : Encoder(Endianness) {} + void collect(ELFYAML::Chunk *Chunk) override { if (auto S = dyn_cast(Chunk)) { collectCovMap(S->CovMaps); @@ -950,12 +956,13 @@ class EncoderImpl : public Encoder, CovMapFilenamesResolver { }; } // namespace -std::unique_ptr Decoder::get(const DecoderParam &Param) { - return std::make_unique(Param); +std::unique_ptr Decoder::get(endianness Endianness, + const DecoderParam &Param) { + return std::make_unique(Endianness, Param); } -std::unique_ptr Encoder::get() { - return std::make_unique(); +std::unique_ptr Encoder::get(endianness Endianness) { + return std::make_unique(Endianness); } bool covmap::nameMatches(StringRef Name) { diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp index 75b5833983872..d13ab60822a02 100644 --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -772,7 +772,7 @@ void ELFState::initSectionHeaders(std::vector &SHeaders, // valid SHN_UNDEF entry since SHT_NULL == 0. SHeaders.resize(Doc.getSections().size()); - auto CovMapEncoder = covmap::Encoder::get(); + auto CovMapEncoder = covmap::Encoder::get(ELFT::Endianness); for (auto &Chunk : Doc.Chunks) { if (isa(Chunk.get())) CovMapEncoder->collect(Chunk.get()); @@ -1935,7 +1935,7 @@ void ELFState::writeSectionContent( auto &OS = *CBA.getRawOS(0); auto BaseOffset = OS.tell(); - if (auto E = Section.encode(OS)) + if (auto E = Section.encode(OS, ELFT::Endianness)) reportError(std::move(E)); SHeader.sh_size = CBA.checkAndTell(BaseOffset); diff --git a/llvm/test/tools/obj2yaml/ELF/covmap-be.yaml b/llvm/test/tools/obj2yaml/ELF/covmap-be.yaml new file mode 100644 index 0000000000000..ec1352b40a9cc --- /dev/null +++ b/llvm/test/tools/obj2yaml/ELF/covmap-be.yaml @@ -0,0 +1,90 @@ +# RUN: yaml2obj %s -o %t.o +# RUN: obj2yaml %t.o > %t.plain.yaml +# RUN: obj2yaml --covmap-raw %t.o > %t.raw.yaml +# RUN: obj2yaml --covmap --covmap-raw %t.o > %t.mixed.yaml +# RUN: obj2yaml --covmap --covmap-dloc %t.o > %t.dloc.yaml +# RUN: obj2yaml --covmap %t.o > %t.covmap.yaml +# RUN: sed -E '/^(#.*)?$/d' %s | diff %t.covmap.yaml - +# RUN: yaml2obj %t.plain.yaml -o - | cmp %t.o - +# RUN: yaml2obj %t.raw.yaml -o - | cmp %t.o - +# RUN: yaml2obj %t.mixed.yaml -o - | cmp %t.o - +# RUN: yaml2obj %t.dloc.yaml -o - | cmp %t.o - +# RUN: yaml2obj %t.covmap.yaml -o - | cmp %t.o - + +# FIXME: This is synthetically created. s/ELFDATA2LSB/ELF2DATAMSB/ s/EM_X86_64/EM_PPC64/ +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2MSB + OSABI: ELFOSABI_GNU + Type: ET_REL + Machine: EM_PPC64 + SectionHeaderStringTable: .strtab +Sections: + - Name: __llvm_covfun + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + CovFun: + - FuncName: _Z4funci + FuncHash: 0xAFC772D567676299 + FilenamesRef: 0x70DA2CAFD8CE198E + Expressions: + - [ { Ref: 0 }, { Ref: 1 } ] + - [ { Add: 0 }, { Ref: 2 } ] + - [ { Add: 0 }, { Ref: 2 } ] + - [ { Add: 0 }, { Ref: 2 } ] + - [ { Ref: 0 }, { Ref: 2 } ] + - [ { Ref: 0 }, { Ref: 2 } ] + - [ { Ref: 0 }, { Ref: 2 } ] + - [ { Add: 0 }, { Ref: 5 } ] + Files: + - Index: 0 + Filename: func.cpp + Regions: + - { Loc: [ 3, 17, 14, 2 ], Ref: 0 } + - { Loc: [ 6, 6, 11, 4 ], Add: 0 } + - { Loc: [ 7, 9, 7, 13 ], Expansion: 1 } + - { Loc: [ 7, 23, 8, 7 ], isGap: true, Ref: 2 } + - { Loc: [ 8, 7, 8, 16 ], Ref: 2 } + - { Loc: [ 8, 17, 10, 5 ], isGap: true, Sub: 3 } + - { Loc: [ 9, 1, 9, 1 ], ExtTag: Skip } + - { Loc: [ 10, 5, 11, 4 ], Sub: 3 } + - { Loc: [ 11, 12, 11, 17 ], Sub: 3 } + - { Loc: [ 11, 12, 11, 17 ], Branch: [ { Ref: 1 }, { Sub: 6 } ] } + - { Loc: [ 11, 19, 12, 3 ], isGap: true, Sub: 6 } + - { Loc: [ 12, 3, 12, 11 ], Sub: 6 } + - { Loc: [ 12, 12, 13, 3 ], isGap: true, Tag: Zero } + - { Loc: [ 13, 3, 13, 12 ], Tag: Zero } + - Index: 1 + Filename: func.cpp + Regions: + - { Loc: [ 1, 17, 1, 41 ], Add: 0 } + - { Loc: [ 1, 18, 1, 32 ], Add: 0 } + - { Loc: [ 1, 18, 1, 40 ], Decision: { BIdx: 5, NCond: 3 } } + - { Loc: [ 1, 19, 1, 22 ], Add: 0 } + - { Loc: [ 1, 19, 1, 22 ], Branch: [ { Sub: 7 }, { Ref: 5 } ], MCDC: [ 1, 2, 3 ] } + - { Loc: [ 1, 26, 1, 31 ], Ref: 5 } + - { Loc: [ 1, 26, 1, 31 ], Branch: [ { Tag: Zero }, { Ref: 6 } ], MCDC: [ 3, 2, 0 ] } + - { Loc: [ 1, 36, 1, 40 ], Ref: 3 } + - { Loc: [ 1, 36, 1, 40 ], Branch: [ { Ref: 4 }, { Tag: Zero } ], MCDC: [ 2, 0, 0 ] } + - Name: __llvm_covmap + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + CovMap: + - FilenamesRef: 0x70DA2CAFD8CE198E + Version: 6 + - Name: __llvm_prf_names + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_GNU_RETAIN ] + AddressAlign: 0x1 + PrfNames: + - - _Z4funci + - Type: SectionHeaderTable + Sections: + - Name: .strtab + - Name: __llvm_covfun + - Name: __llvm_covmap + - Name: __llvm_prf_names +... diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp index 9f21c2b67a858..1bb298fee9d82 100644 --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -600,7 +600,7 @@ ELFDumper::dumpSections() { Param.Detailed = CovMapDetailed; Param.Raw = CovMapRaw; Param.dLoc = CovMapDLoc; - auto CovMapDecoder = covmap::Decoder::get(Param); + auto CovMapDecoder = covmap::Decoder::get(ELFT::Endianness, Param); if (covmap::Decoder::enabled) { // Look up covmap-related sections. for (const auto &Sec : Sections) { From 4e1cfc2d923f0a9355bc6dcd18d19764b3014982 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 3 Mar 2025 12:24:15 +0900 Subject: [PATCH 08/10] yaml2obj --- llvm/include/llvm/ObjectYAML/CovMap.h | 139 +---- llvm/include/llvm/ProfileData/InstrProf.h | 6 - llvm/lib/ObjectYAML/CovMap.cpp | 535 +---------------- llvm/lib/ProfileData/InstrProf.cpp | 23 +- .../Inputs/branch-c-general-single.yaml | 561 +++--------------- .../Inputs/branch-logical-mixed-single.yaml | 145 +---- .../llvm-cov/Inputs/branch-macros-single.yaml | 242 +------- .../Inputs/branch-templates-single.yaml | 119 ++-- .../showLineExecutionCounts-single.yaml | 57 +- llvm/test/tools/llvm-cov/Inputs/yaml.makefile | 6 +- llvm/test/tools/obj2yaml/ELF/covmap-be.yaml | 9 - llvm/test/tools/obj2yaml/ELF/covmap.yaml | 9 - llvm/test/tools/obj2yaml/help.test | 1 - llvm/tools/obj2yaml/elf2yaml.cpp | 57 +- llvm/tools/obj2yaml/obj2yaml.cpp | 2 +- llvm/tools/obj2yaml/obj2yaml.h | 4 - 16 files changed, 238 insertions(+), 1677 deletions(-) diff --git a/llvm/include/llvm/ObjectYAML/CovMap.h b/llvm/include/llvm/ObjectYAML/CovMap.h index 0c760d7510890..3a0b86435d490 100644 --- a/llvm/include/llvm/ObjectYAML/CovMap.h +++ b/llvm/include/llvm/ObjectYAML/CovMap.h @@ -16,7 +16,7 @@ // // - llvm::covmap // -// Provides YAML encoder and decoder for coverage map. +// Provides YAML encoder for coverage map. // //===----------------------------------------------------------------------===// @@ -24,77 +24,23 @@ #define LLVM_OBJECTYAML_COVMAP_H #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ObjectYAML/ELFYAML.h" #include "llvm/Support/Endian.h" -#include "llvm/Support/Error.h" #include "llvm/Support/YAMLTraits.h" +#include #include #include #include -#include +#include +#include namespace llvm { -class InstrProfSymtab; class raw_ostream; } // namespace llvm namespace llvm::coverage::yaml { -/// This works like vector container but can be replaced with -/// MutableArrayRef. See also SequenceTraits. -template > class VectorOrRef { - using Ref = MutableArrayRef; - - /// Holds vector type initially. - std::variant Array; - -public: - // FIXME: Iterator impl is minimal easy. - using iterator = T *; - - iterator begin() { - if (auto *V = std::get_if(&Array)) - return &V->front(); - return &std::get(Array).front(); - } - - iterator end() { - if (auto *V = std::get_if(&Array)) - return &V->back() + 1; - return &std::get(Array).back() + 1; - } - - size_t size() const { - if (const auto *V = std::get_if(&Array)) - return V->size(); - return std::get(Array).size(); - } - - T &operator[](int Idx) { - if (auto *V = std::get_if(&Array)) - return (*V)[Idx]; - return std::get(Array)[Idx]; - } - - void resize(size_t Size) { std::get(Array).resize(Size); } - - VectorOrRef() = default; - - /// Initialize with MutableArrayRef. - VectorOrRef(Ref &&Tmp) : Array(std::move(Tmp)) {} -}; - -/// Options for Decoder. -struct DecoderParam { - bool Detailed; ///< Generate and show processed records. - bool Raw; ///< Show raw data oriented records. - bool dLoc; ///< Show raw dLoc (differential Loc). -}; - -struct DecoderContext; - /// Base Counter, corresponding to coverage::Counter. struct CounterTy { enum TagTy : uint8_t { @@ -119,12 +65,6 @@ struct CounterTy { virtual void mapping(llvm::yaml::IO &IO); - /// Holds Val for extensions. - Error decodeOrTag(DecoderContext &Data); - - /// Raise Error if Val isn't empty. - Error decode(DecoderContext &Data); - void encode(raw_ostream &OS) const; }; @@ -145,8 +85,6 @@ struct DecisionTy { void mapping(llvm::yaml::IO &IO); - Error decode(DecoderContext &Data); - void encode(raw_ostream &OS) const; }; @@ -180,8 +118,6 @@ struct RecTy : CounterTy { void mapping(llvm::yaml::IO &IO) override; - Error decode(DecoderContext &Data); - void encode(uint64_t &StartLoc, raw_ostream &OS) const; }; @@ -194,9 +130,6 @@ struct FileRecsTy { void mapping(llvm::yaml::IO &IO); }; -/// Key is FilenamesRef. -using CovMapByRefTy = llvm::DenseMap; - /// An element of CovFun array. struct CovFunTy { std::optional NameRef; ///< Hash value of the symbol. @@ -209,11 +142,6 @@ struct CovFunTy { void mapping(llvm::yaml::IO &IO); - /// Depends on CovMap and SymTab(IPSK_names) - Expected decode(CovMapByRefTy &CovMapByRef, InstrProfSymtab *SymTab, - const ArrayRef Content, uint64_t Offset, - endianness Endianness, const DecoderParam &Param); - void encode(raw_ostream &OS, endianness Endianness) const; }; @@ -235,16 +163,13 @@ struct CovMapTy { /// This may be ArrayRef in Decoder since Filenames has been /// filled. On the other hand in Encoder, this should be a vector /// since YAML parser doesn't endorse references. - std::optional> Files; + std::optional> Files; void mapping(llvm::yaml::IO &IO); bool useWD() const { return (!Version || *Version >= 4); } StringRef getWD() const { return (WD ? *WD : StringRef()); } - Expected decode(const ArrayRef Content, uint64_t Offset, - endianness Endianness, const DecoderParam &Param); - /// Generate Accumulated list with WD. /// Returns a single element {WD} if AccFiles is not given. std::vector @@ -265,21 +190,6 @@ struct CovMapTy { } // namespace llvm::coverage::yaml -namespace llvm::yaml { -template -struct SequenceTraits> { - static size_t size(IO &io, llvm::coverage::yaml::VectorOrRef &seq) { - return seq.size(); - } - static T &element(IO &, llvm::coverage::yaml::VectorOrRef &seq, - size_t index) { - if (index >= seq.size()) - seq.resize(index + 1); - return seq[index]; - } -}; -} // namespace llvm::yaml - LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::coverage::yaml::CovMapTy) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::coverage::yaml::CovFunTy) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::coverage::yaml::ExpressionTy) @@ -326,39 +236,6 @@ LLVM_COVERAGE_YAML_ELEM_MAPPING(CovMapTy) namespace llvm::covmap { -class Decoder { -protected: - endianness Endianness; - -public: - Decoder(endianness Endianness) : Endianness(Endianness) {} - virtual ~Decoder() {} - - /// Returns DecoderImpl. - static std::unique_ptr - get(endianness Endianness, const coverage::yaml::DecoderParam &Param); - - /// Called from the Sections loop in advance of the final dump. - /// Decoder predecodes Names and CovMap, and captures Contents of - /// CovFuns. - virtual Error - acquire(uint64_t Offset, unsigned AddressAlign, StringRef Name, - std::function>()> getSectionContents) = 0; - - /// Called before the final dump after `acquire`. - /// Decode contents partially and resolve names. - virtual Error fixup() = 0; - - /// Create an ELFYAML object. This just puts predecoded data in - /// `fixup`. - virtual Expected - make(uint64_t Offset, StringRef Name, - std::function dumpCommonSection) = 0; - - /// Suppress emission of CovMap unless enabled. - static bool enabled; -}; - class Encoder { protected: endianness Endianness; @@ -373,8 +250,8 @@ class Encoder { /// Called from the Sections loop. virtual void collect(ELFYAML::Chunk *Chunk) = 0; - /// Resolves names along DecoderParam in advance of Emitter. It'd be - /// too late to resolve sections in Emitter since they are immutable + /// Resolves names from CovFuns in advance of Emitter. It'd be too + /// late to resolve sections in Emitter since they are immutable /// then. virtual void fixup() = 0; }; @@ -383,7 +260,7 @@ class Encoder { bool nameMatches(StringRef Name); /// Returns a new ELFYAML Object. -std::unique_ptr make_unique(StringRef Name); +std::unique_ptr make_unique(StringRef Name); } // namespace llvm::covmap diff --git a/llvm/include/llvm/ProfileData/InstrProf.h b/llvm/include/llvm/ProfileData/InstrProf.h index e20424da3cac2..7133c0c6a302c 100644 --- a/llvm/include/llvm/ProfileData/InstrProf.h +++ b/llvm/include/llvm/ProfileData/InstrProf.h @@ -545,12 +545,6 @@ class InstrProfSymtab { /// This method is a wrapper to \c readAndDecodeStrings method. Error create(StringRef NameStrings); - // PrfNames is nested array. - using PrfNamesTy = SmallVector; - using PrfNamesChunksTy = SmallVector; - - Expected createAndGetList(ArrayRef Content); - /// Initialize symtab states with function names and vtable names. \c /// FuncNameStrings is a string composed of one or more encoded function name /// strings, and \c VTableNameStrings composes of one or more encoded vtable diff --git a/llvm/lib/ObjectYAML/CovMap.cpp b/llvm/lib/ObjectYAML/CovMap.cpp index 0bc5164e22def..7662284caee76 100644 --- a/llvm/lib/ObjectYAML/CovMap.cpp +++ b/llvm/lib/ObjectYAML/CovMap.cpp @@ -6,24 +6,30 @@ // //===----------------------------------------------------------------------===// // -// Implementations of CovMap, encoder, decoder. +// Implementations of CovMap and encoder. // //===----------------------------------------------------------------------===// #include "llvm/ObjectYAML/CovMap.h" -#include "llvm/ADT/MapVector.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ObjectYAML/ELFYAML.h" -#include "llvm/ProfileData/Coverage/CoverageMapping.h" -#include "llvm/ProfileData/Coverage/CoverageMappingReader.h" #include "llvm/ProfileData/Coverage/CoverageMappingWriter.h" #include "llvm/ProfileData/InstrProf.h" #include "llvm/Support/Alignment.h" -#include "llvm/Support/DataExtractor.h" #include "llvm/Support/Endian.h" #include "llvm/Support/LEB128.h" #include "llvm/Support/MD5.h" #include "llvm/Support/YAMLTraits.h" +#include "llvm/Support/raw_ostream.h" +#include #include +#include +#include +#include +#include +#include #define COVMAP_V3 @@ -31,31 +37,6 @@ using namespace llvm; using namespace llvm::coverage::yaml; using namespace llvm::covmap; -bool Decoder::enabled; - -// DataExtractor w/ single Cursor -struct coverage::yaml::DecoderContext : DataExtractor, - DataExtractor::Cursor, - DecoderParam { - uint64_t LineStart = 0; - - DecoderContext(const ArrayRef Content, const DecoderParam &Param, - bool IsLE) - : DataExtractor(Content, IsLE, /*AddressSize=*/0), - DataExtractor::Cursor(0), DecoderParam(Param) {} - - bool eof() { return DataExtractor::eof(*this); } - uint32_t getU32() { return DataExtractor::getU32(*this); } - uint64_t getU64() { return DataExtractor::getU64(*this); } - Expected getULEB128() { - uint64_t Result = DataExtractor::getULEB128(*this); - if (!*this) - return takeError(); - return Result; - } - StringRef getBytes(size_t sz) { return DataExtractor::getBytes(*this, sz); } -}; - void CounterTy::encode(raw_ostream &OS) const { std::pair C; if (RefOpt) @@ -74,71 +55,11 @@ void CounterTy::encode(raw_ostream &OS) const { encodeULEB128(C.first | (C.second << 2), OS); } -Error CounterTy::decodeOrTag(DecoderContext &Data) { - auto COrErr = Data.getULEB128(); - if (!COrErr) - return COrErr.takeError(); - auto T = static_cast(*COrErr & 0x03); - auto V = (*COrErr >> 2); - if (T == Zero) { - if (V == 0) - Tag = Zero; // w/o Val - else - Val = V; // w/o Tag - } else { - if (Data.Raw) { - Tag = T; - Val = V; - } else { - switch (T) { - case Zero: - llvm_unreachable("Zero should be handled in advance"); - case Ref: - RefOpt = V; - break; - case Sub: - SubOpt = V; - break; - case Add: - AddOpt = V; - break; - } - } - } - - return Error::success(); -} - -Error CounterTy::decode(DecoderContext &Data) { - if (auto E = decodeOrTag(Data)) - return E; - if (!this->Tag && this->Val) - return make_error( - coveragemap_error::malformed, - "Counter::Zero shouldn't have the Val: 0x" + - Twine::utohexstr(*this->Val)); - return Error::success(); -} - void DecisionTy::encode(raw_ostream &OS) const { encodeULEB128(BIdx, OS); encodeULEB128(NC, OS); } -Error DecisionTy::decode(DecoderContext &Data) { - auto BIdxOrErr = Data.getULEB128(); - if (!BIdxOrErr) - return BIdxOrErr.takeError(); - BIdx = *BIdxOrErr; - - auto NCOrErr = Data.getULEB128(); - if (!NCOrErr) - return NCOrErr.takeError(); - NC = *NCOrErr; - - return Error::success(); -} - void RecTy::encode(uint64_t &StartLoc, raw_ostream &OS) const { if (Expansion) { encodeULEB128(4 + (*Expansion << 3), OS); @@ -183,109 +104,6 @@ void RecTy::encode(uint64_t &StartLoc, raw_ostream &OS) const { } } -Error RecTy::decode(DecoderContext &Data) { - auto getU16 = [&]() -> Expected { - auto ValOrErr = Data.getULEB128(); - if (!ValOrErr) - return ValOrErr.takeError(); - if (*ValOrErr > 0x7FFF + 1) - return make_error(coveragemap_error::malformed, - "MC/DC index is out of range: 0x" + - Twine::utohexstr(*ValOrErr)); - return static_cast(*ValOrErr); - }; - - auto decodeBranch = [&]() -> Error { - auto &B = BranchOpt.emplace(); - if (auto E = B[0].decode(Data)) - return E; - if (auto E = B[1].decode(Data)) - return E; - return Error::success(); - }; - - // Decode tagged CounterTy - if (auto E = CounterTy::decodeOrTag(Data)) - return E; - if (!this->Val || this->Tag) { - // Compatible to CounterTy - } else if (*this->Val & 1u) { - Expansion = (*this->Val >> 1); - this->Val.reset(); - } else { - auto Tag = *this->Val >> 1; - this->Val.reset(); - switch (Tag) { - case Skip: - ExtTag = Skip; // w/o Val - break; - case Decision: - if (auto E = DecisionOpt.emplace().decode(Data)) - return E; - if (Data.Raw) - ExtTag = Decision; - break; - case Branch: - if (auto E = decodeBranch()) - return E; - if (Data.Raw) - ExtTag = Branch; - break; - case MCDCBranch: { - if (auto E = decodeBranch()) - return E; - auto I0OrErr = getU16(); - if (!I0OrErr) - return I0OrErr.takeError(); - auto I1OrErr = getU16(); - if (!I1OrErr) - return I1OrErr.takeError(); - auto I2OrErr = getU16(); - if (!I2OrErr) - return I2OrErr.takeError(); - MCDC = {*I0OrErr, *I1OrErr, *I2OrErr}; - if (Data.Raw) - ExtTag = MCDCBranch; - break; - } - default: - return make_error( - coveragemap_error::malformed, - "Record doesn't have an valid Tag: 0x" + Twine::utohexstr(Tag)); - } - } - - // Decode Loc - auto LSDeltaOrErr = Data.getULEB128(); - if (!LSDeltaOrErr) - return LSDeltaOrErr.takeError(); - Data.LineStart += *LSDeltaOrErr; - - auto CSOrErr = Data.getULEB128(); - if (!CSOrErr) - return CSOrErr.takeError(); - - auto NLOrErr = Data.getULEB128(); - if (!NLOrErr) - return NLOrErr.takeError(); - auto LineEnd = Data.LineStart + *NLOrErr; - - auto CEOrErr = Data.getULEB128(); - if (!CEOrErr) - return CEOrErr.takeError(); - auto ColumnEnd = *CEOrErr; - - // Gap is set in ColumnEnd:31 - if (ColumnEnd & (1u << 31)) - isGap = true; - ColumnEnd &= ((1u << 31) - 1); - - dLoc = {*LSDeltaOrErr, *CSOrErr, *NLOrErr, ColumnEnd}; - Loc = {Data.LineStart, *CSOrErr, LineEnd, ColumnEnd}; - - return Error::success(); -} - void CovFunTy::encode(raw_ostream &OS, endianness Endianness) const { // Encode Body in advance since DataSize should be known. std::string Body; @@ -376,97 +194,6 @@ CovMapTy::encodeFilenames(const std::optional> &AccFilesOpt, return {llvm::IndexedInstrProf::ComputeHash(FilenamesBlob), FilenamesBlob}; } -Expected CovFunTy::decode(CovMapByRefTy &CovMapByRef, - InstrProfSymtab *Symtab, - const ArrayRef Content, - uint64_t Offset, endianness Endianness, - const DecoderParam &Param) { - DecoderContext Data(Content, Param, (Endianness == endianness::little)); - Data.seek(Offset); - - uint32_t DataSize; - [[maybe_unused]] char CoverageMapping; // Ignored - -#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Initializer) \ - if (sizeof(Type) == sizeof(uint64_t)) \ - Name = Data.getU64(); \ - else if (sizeof(Type) == sizeof(uint32_t)) \ - Name = Data.getU32(); \ - else \ - assert(sizeof(Type) == sizeof(CoverageMapping) && "Unknown type"); - -#include "llvm/ProfileData/InstrProfData.inc" - - if (!Data) - return Data.takeError(); - - if (Data.Detailed) - FuncName = Symtab->getFuncOrVarNameIfDefined(*NameRef); - - if (!Data.Raw) - NameRef.reset(); - - [[maybe_unused]] auto ExpectedEndOffset = Data.tell() + DataSize; - - // Decode body. - assert(CovMapByRef.contains(this->FilenamesRef)); - auto &CovMap = *CovMapByRef[this->FilenamesRef]; - FileIDs.emplace(); - - auto NumFilesOrErr = Data.getULEB128(); - if (!NumFilesOrErr) - return NumFilesOrErr.takeError(); - for (unsigned I = 0, E = *NumFilesOrErr; I != E; ++I) { - if (auto IDOrErr = Data.getULEB128()) - FileIDs->push_back(*IDOrErr); - else - return IDOrErr.takeError(); - } - - auto NumExprOrErr = Data.getULEB128(); - if (!NumExprOrErr) - return NumExprOrErr.takeError(); - Expressions.resize(*NumExprOrErr); - for (auto &[LHS, RHS] : Expressions) { - if (auto E = LHS.decode(Data)) - return std::move(E); - if (auto E = RHS.decode(Data)) - return std::move(E); - } - - for (unsigned FileIdx = 0; FileIdx != *NumFilesOrErr; ++FileIdx) { - auto NumRegionsOrErr = Data.getULEB128(); - if (!NumRegionsOrErr) - return NumRegionsOrErr.takeError(); - auto &File = Files.emplace_back(); - if (Data.Detailed) { - File.Index = FileIdx; // Sequential number. - File.Filename = (*CovMap.Filenames)[(*FileIDs)[FileIdx]]; - } - - // Decode subarray. - Data.LineStart = 0; - for (unsigned I = 0; I != *NumRegionsOrErr; ++I) { - auto &Rec = File.Recs.emplace_back(); - if (auto E = Rec.decode(Data)) - return std::move(E); - - // Hide either Loc or dLoc. - if (!Data.Detailed || Data.dLoc) - Rec.Loc.reset(); - else if (!Data.Raw) - Rec.dLoc.reset(); - } - } - - // Hide FileIDs. - if (!Data.Raw) - FileIDs.reset(); - - assert(Data.tell() == ExpectedEndOffset); - return Data.tell(); -} - void CovMapTy::encode(raw_ostream &OS, endianness Endianness) const { auto [FilenamesRef, FilenamesBlob] = encodeFilenames(); @@ -492,48 +219,6 @@ void CovMapTy::encode(raw_ostream &OS, endianness Endianness) const { OS << FilenamesBlob; } -Expected CovMapTy::decode(const ArrayRef Content, - uint64_t Offset, endianness Endianness, - const DecoderParam &Param) { - DecoderContext Data(Content, Param, (Endianness == endianness::little)); - Data.seek(Offset); - -#define COVMAP_HEADER(Type, LLVMType, Name, Initializer) \ - static_assert(sizeof(Type) == sizeof(uint32_t)); \ - Type Name = Data.getU32(); -#include "llvm/ProfileData/InstrProfData.inc" - if (!Data) - return Data.takeError(); - assert(NRecords == 0); - // +1: uint32_t FilenamesSize; - assert(CoverageSize == 0); - this->Version = Version; - - // Decode Body -- Filenames. - StringRef FnBlob = Data.getBytes(FilenamesSize); - if (!Data) - return Data.takeError(); - this->FilenamesRef = MD5Hash(FnBlob); - this->Filenames.emplace(); - if (auto E = RawCoverageFilenamesReader(FnBlob, *this->Filenames) - .read(static_cast(Version))) - return E; - - if (Param.Detailed && useWD()) { - assert(this->Filenames->size() >= 1); - auto FilenamesI = this->Filenames->begin(); - StringRef WD = *FilenamesI++; - if (!WD.empty()) - this->WD = WD; - // Use Filenames as a storage. - this->Files.emplace( - MutableArrayRef(&*FilenamesI, &*this->Filenames->end())); - } - - Offset = Data.tell(); - return Offset; -} - void CounterTy::mapping(llvm::yaml::IO &IO) { IO.mapOptional("Tag", Tag); IO.mapOptional("Val", Val); @@ -578,12 +263,7 @@ void CovFunTy::mapping(llvm::yaml::IO &IO) { void CovMapTy::mapping(llvm::yaml::IO &IO) { IO.mapRequired("FilenamesRef", FilenamesRef); IO.mapOptional("Version", Version); - - if (!WD && !Files) - // Suppress this regardless of (Detailed && Raw). - // Since it is obviously redundant. - IO.mapOptional("Filenames", Filenames); - + IO.mapOptional("Filenames", Filenames); IO.mapOptional("WD", WD); IO.mapOptional("Files", Files); } @@ -609,7 +289,8 @@ void llvm::yaml::ScalarEnumerationTraits::enumeration( namespace { struct PrfNamesSection : ELFYAML::CovMapSectionBase { - InstrProfSymtab::PrfNamesChunksTy PrfNames; + using PrfNamesTy = SmallVector; + SmallVector PrfNames; PrfNamesSection() { Name = "__llvm_prf_names"; } static bool nameMatches(StringRef Name) { return Name == "__llvm_prf_names"; } @@ -647,26 +328,6 @@ struct CovMapSection : ELFYAML::CovMapSectionBase { IO.mapOptional("CovMap", CovMaps); } - Error decode(ArrayRef Blob, unsigned AddressAlign, - endianness Endianness, const DecoderParam &Param) { - uint64_t Offset = 0; - - while (true) { - Offset = llvm::alignTo(Offset, AddressAlign); - if (Offset >= Blob.size()) { - break; - } - auto &CovMap = CovMaps.emplace_back(); - auto Result = CovMap.decode(Blob, Offset, Endianness, Param); - if (!Result) { - return Result.takeError(); - } - Offset = *Result; - } - - return Error::success(); - } - Error encode(raw_ostream &OS, endianness Endianness) const override { auto BaseOffset = OS.tell(); for (const auto &CovMap : CovMaps) { @@ -693,30 +354,6 @@ struct CovFunSection : ELFYAML::CovMapSectionBase { IO.mapOptional("CovFun", CovFuns); } - static Expected> - decode(CovMapByRefTy &CovMapByRef, InstrProfSymtab *Symtab, - ArrayRef CovFunA, unsigned AddressAlign, - endianness Endianness, const DecoderParam &Param) { - std::vector CovFuns; - uint64_t Offset = 0; - - while (true) { - Offset = llvm::alignTo(Offset, AddressAlign); - if (Offset >= CovFunA.size()) - break; - - auto &CovFun = CovFuns.emplace_back(); - auto Result = CovFun.decode(CovMapByRef, Symtab, CovFunA, Offset, - Endianness, Param); - if (!Result) - return Result.takeError(); - - Offset = *Result; - } - - return std::move(CovFuns); - } - Error encode(raw_ostream &OS, endianness Endianness) const override { auto BaseOffset = OS.tell(); for (auto [I, CovFun] : enumerate(CovFuns)) { @@ -733,8 +370,7 @@ class CovMapFilenamesResolver { std::vector UnresolvedCovFuns; protected: - CovMapByRefTy CovMapByRef; - std::vector TempCovMaps; // For Decoder + DenseMap CovMapByRef; public: void collectCovMap(std::vector &CovMaps) { @@ -742,11 +378,6 @@ class CovMapFilenamesResolver { CovMapByRef[CovMap.FilenamesRef] = &CovMap; } - void moveAndCollectCovMap(std::vector &&CovMaps) { - TempCovMaps = std::move(CovMaps); - collectCovMap(TempCovMaps); - } - void collectCovFunFilenames(std::vector &CovFuns) { for (auto &CovFun : CovFuns) { auto &Filenames = FilenamesByCovMap[CovFun.FilenamesRef]; @@ -760,23 +391,6 @@ class CovMapFilenamesResolver { } } - void decMayeResetFilenames(std::vector &CovMaps) { - for (auto &CovMap : CovMaps) { - auto FilenamesI = FilenamesByCovMap.find(CovMap.FilenamesRef); - if (FilenamesI == FilenamesByCovMap.end()) - continue; - - // Calculate FilenamesRef with Filenames from CovFuns. - // If matches, hide Filenames from CovMap. - auto [AccFilenamesRef, _] = - CovMap.encodeFilenames(FilenamesI->second.getArrayRef()); - if (CovMap.FilenamesRef == AccFilenamesRef) { - CovMap.Files.reset(); - CovMap.Filenames.reset(); // FilenamesI has been invalidated. - } - } - } - void encFixup() { for (auto &[_, CovMap] : CovMapByRef) { auto FilenamesI = FilenamesByCovMap.find(CovMap->FilenamesRef); @@ -831,115 +445,6 @@ class CovMapFilenamesResolver { } }; -class DecoderImpl : public Decoder, CovMapFilenamesResolver { - DecoderParam Param; - - std::unique_ptr ProfileNames; - - InstrProfSymtab::PrfNamesChunksTy PrfNames; - - MapVector, unsigned>> CovFunBlobs; - DenseMap> TempCovFuns; - -public: - DecoderImpl(endianness Endianness, const DecoderParam &Param) - : Decoder(Endianness), Param(Param), - ProfileNames(std::make_unique()) { - enabled = (Param.Detailed || Param.Raw); - } - - Error acquire(uint64_t Offset, unsigned AddressAlign, StringRef Name, - std::function>()> getSectionContents) - override { - // Don't register anything. - if (!enabled) - return Error::success(); - - if (PrfNamesSection::nameMatches(Name)) { - auto ContentOrErr = getSectionContents(); - if (!ContentOrErr) - return ContentOrErr.takeError(); - // Decode PrfNames in advance since CovFun depends on it. - auto PrfNamesOrErr = ProfileNames->createAndGetList(*ContentOrErr); - if (!PrfNamesOrErr) - return PrfNamesOrErr.takeError(); - PrfNames = std::move(*PrfNamesOrErr); - } else if (CovMapSection::nameMatches(Name)) { - auto ContentOrErr = getSectionContents(); - if (!ContentOrErr) - return ContentOrErr.takeError(); - - // Decode CovMaps in advance, since only CovMap knows its Version. - // CovMaps is restored (into CovMapSection) later. - auto TempCovMap = std::make_unique(); - if (auto E = TempCovMap->decode(*ContentOrErr, AddressAlign, Endianness, - Param)) - return E; - moveAndCollectCovMap(std::move(TempCovMap->CovMaps)); - } else if (CovFunSection::nameMatches(Name)) { - auto ContentOrErr = getSectionContents(); - if (!ContentOrErr) - return ContentOrErr.takeError(); - - // Will be decoded after CovMap is met. - CovFunBlobs[Offset] = {*ContentOrErr, AddressAlign}; - } - - return Error::success(); - } - - Error fixup() override { - // Decode CovFun(s) with predecoded PrfNames and CovMap. - for (const auto &[Offset, CovFunBlob] : CovFunBlobs) { - auto CovFunsOrErr = CovFunSection::decode( - CovMapByRef, ProfileNames.get(), CovFunBlob.first, CovFunBlob.second, - Endianness, Param); - if (!CovFunsOrErr) - return CovFunsOrErr.takeError(); - TempCovFuns[Offset] = std::move(*CovFunsOrErr); - collectCovFunFilenames(TempCovFuns[Offset]); - } - return Error::success(); - } - - Expected - make(uint64_t Offset, StringRef Name, - std::function dumpCommonSection) override { - if (PrfNamesSection::nameMatches(Name)) { - auto S = std::make_unique(); - if (Error E = dumpCommonSection(*S)) - return std::move(E); - S->PrfNames = std::move(PrfNames); - return S.release(); - } else if (CovMapSection::nameMatches(Name)) { - auto S = std::make_unique(); - if (Error E = dumpCommonSection(*S)) - return std::move(E); - - // Store predecoded CovMaps. - S->CovMaps = std::move(TempCovMaps); - - // Hide Filenames if it is reproducible from CovFuns. - if (Param.Detailed) - decMayeResetFilenames(S->CovMaps); - - return S.release(); - } else if (CovFunSection::nameMatches(Name)) { - auto S = std::make_unique(); - if (Error E = dumpCommonSection(*S)) - return std::move(E); - - assert(S->CovFuns.empty()); - assert(TempCovFuns.contains(Offset)); - S->CovFuns = std::move(TempCovFuns[Offset]); - - return S.release(); - } - - llvm_unreachable("Name didn't match"); - } -}; - class EncoderImpl : public Encoder, CovMapFilenamesResolver { public: EncoderImpl(endianness Endianness) : Encoder(Endianness) {} @@ -956,11 +461,6 @@ class EncoderImpl : public Encoder, CovMapFilenamesResolver { }; } // namespace -std::unique_ptr Decoder::get(endianness Endianness, - const DecoderParam &Param) { - return std::make_unique(Endianness, Param); -} - std::unique_ptr Encoder::get(endianness Endianness) { return std::make_unique(Endianness); } @@ -970,7 +470,8 @@ bool covmap::nameMatches(StringRef Name) { CovMapSection::nameMatches(Name) || CovFunSection::nameMatches(Name)); } -std::unique_ptr covmap::make_unique(StringRef Name) { +std::unique_ptr +covmap::make_unique(StringRef Name) { if (PrfNamesSection::nameMatches(Name)) return std::make_unique(); else if (CovMapSection::nameMatches(Name)) @@ -981,4 +482,4 @@ std::unique_ptr covmap::make_unique(StringRef Name) { return nullptr; } -LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::InstrProfSymtab::PrfNamesTy) +LLVM_YAML_IS_SEQUENCE_VECTOR(PrfNamesSection::PrfNamesTy) diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp index 93714a5a05a0d..819ddd02a24ce 100644 --- a/llvm/lib/ProfileData/InstrProf.cpp +++ b/llvm/lib/ProfileData/InstrProf.cpp @@ -535,9 +535,9 @@ Error InstrProfSymtab::addVTableWithName(GlobalVariable &VTable, /// \c NameStrings is a string composed of one of more possibly encoded /// sub-strings. The substrings are separated by 0 or more zero bytes. This /// method decodes the string and calls `NameCallback` for each substring. -static Error readAndDecodeStrings( - StringRef NameStrings, std::function NameCallback, - std::function ChunkCallback = [](bool) {}) { +static Error +readAndDecodeStrings(StringRef NameStrings, + std::function NameCallback) { const uint8_t *P = NameStrings.bytes_begin(); const uint8_t *EndP = NameStrings.bytes_end(); while (P < EndP) { @@ -567,7 +567,6 @@ static Error readAndDecodeStrings( P += UncompressedSize; } // Now parse the name strings. - ChunkCallback(IsCompressed); SmallVector Names; NameStrings.split(Names, getInstrProfNameSeparator()); for (StringRef &Name : Names) @@ -586,22 +585,6 @@ Error InstrProfSymtab::create(StringRef NameStrings) { std::bind(&InstrProfSymtab::addFuncName, this, std::placeholders::_1)); } -Expected -InstrProfSymtab::createAndGetList(ArrayRef Content) { - PrfNamesChunksTy Result; - PrfNamesTy *ArrayP = nullptr; - if (auto E = readAndDecodeStrings( - StringRef(reinterpret_cast(Content.data()), - Content.size()), - [&](StringRef Name) { - ArrayP->emplace_back(Name.str()); - return addFuncName(Name); - }, - [&](bool IsCompressed) { ArrayP = &Result.emplace_back(); })) - return E; - return Result; -} - Error InstrProfSymtab::create(StringRef FuncNameStrings, StringRef VTableNameStrings) { if (Error E = readAndDecodeStrings(FuncNameStrings, diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml b/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml index 7d7f714353a88..9d23dcb67ad2a 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml +++ b/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml @@ -11,525 +11,72 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - CovFun: - - FuncName: simple_loops - FuncHash: 0x46D109C4436D1 - FilenamesRef: 0x4F0FF417951E554C - Expressions: [] - Files: - - Index: 0 - Filename: branch-c-general.c - Regions: - - { dLoc: [ 7, 21, 8, 2 ], Ref: 0 } - - { dLoc: [ 2, 15, 0, 22 ], Ref: 1 } - - { dLoc: [ 0, 24, 0, 27 ], Ref: 2 } - - { dLoc: [ 0, 28, 0, 29 ], isGap: true, Ref: 3 } - - { dLoc: [ 0, 29, 1, 4 ], Ref: 3 } - - { dLoc: [ 2, 3, 4, 2 ], Ref: 4 } - - { dLoc: [ 0, 10, 0, 15 ], Ref: 5 } - - { dLoc: [ 0, 16, 1, 5 ], isGap: true, Ref: 6 } - - { dLoc: [ 1, 5, 0, 8 ], Ref: 6 } - - { dLoc: [ 1, 3, 2, 2 ], Ref: 7 } - - { dLoc: [ 0, 6, 0, 8 ], Ref: 8 } - - { dLoc: [ 0, 16, 0, 24 ], Ref: 9 } - - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } + Content: D7878914FBE99B074D000000D136449C106D04004C551E9517F40F4F0101000D010715080205020F0016090018001B0D001C009D808080080D001D0104110203040215000A000F19001001858080800819010500081D01030202210006000825001000181001010001 - Name: '__llvm_covfun (1)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - CovFun: - - FuncName: conditionals - FuncHash: 0x44113C165835D352 - FilenamesRef: 0x4F0FF417951E554C - Expressions: [] - Files: - - Index: 0 - Filename: branch-c-general.c - Regions: - - { dLoc: [ 17, 21, 14, 2 ], Ref: 0 } - - { dLoc: [ 1, 19, 0, 26 ], Ref: 1 } - - { dLoc: [ 0, 28, 0, 31 ], Ref: 2 } - - { dLoc: [ 0, 32, 0, 33 ], isGap: true, Ref: 3 } - - { dLoc: [ 0, 33, 11, 4 ], Ref: 3 } - - { dLoc: [ 1, 9, 0, 14 ], Ref: 3 } - - { dLoc: [ 0, 15, 0, 16 ], isGap: true, Ref: 5 } - - { dLoc: [ 0, 16, 2, 6 ], Ref: 5 } - - { dLoc: [ 1, 11, 0, 12 ], Ref: 5 } - - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 8 } - - { dLoc: [ 0, 14, 0, 16 ], Ref: 8 } - - { dLoc: [ 1, 6, 0, 12 ], isGap: true, Ref: 12 } - - { dLoc: [ 0, 12, 4, 6 ], Ref: 12 } - - { dLoc: [ 0, 16, 0, 21 ], Ref: 12 } - - { dLoc: [ 0, 22, 0, 23 ], isGap: true, Ref: 10 } - - { dLoc: [ 0, 23, 2, 6 ], Ref: 10 } - - { dLoc: [ 1, 11, 0, 12 ], Ref: 10 } - - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 13 } - - { dLoc: [ 0, 14, 0, 16 ], Ref: 13 } - - { dLoc: [ 1, 6, 0, 12 ], isGap: true, Ref: 11 } - - { dLoc: [ 0, 12, 2, 6 ], Ref: 11 } - - { dLoc: [ 1, 11, 0, 12 ], Ref: 11 } - - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 15 } - - { dLoc: [ 0, 14, 0, 16 ], Ref: 15 } - - { dLoc: [ 2, 1, 0, 98 ], ExtTag: Skip } - - { dLoc: [ 1, 5, 2, 4 ], Ref: 7 } - - { dLoc: [ 0, 9, 0, 10 ], Ref: 7 } - - { dLoc: [ 0, 9, 0, 15 ], Ref: 7 } - - { dLoc: [ 0, 14, 0, 15 ], Ref: 19 } - - { dLoc: [ 0, 16, 0, 17 ], isGap: true, Ref: 17 } - - { dLoc: [ 0, 17, 0, 19 ], Ref: 17 } - - { dLoc: [ 1, 5, 1, 4 ], Ref: 18 } - - { dLoc: [ 0, 9, 0, 10 ], Ref: 18 } - - { dLoc: [ 0, 9, 0, 15 ], Ref: 18 } - - { dLoc: [ 0, 14, 0, 15 ], Ref: 23 } - - { dLoc: [ 0, 16, 0, 17 ], isGap: true, Ref: 21 } - - { dLoc: [ 0, 17, 0, 19 ], Ref: 21 } - - { dLoc: [ 2, 1, 0, 1 ], ExtTag: Skip } + Content: 83AD05A5F1438E68EA00000052D33558163C11444C551E9517F40F4F010100260111150E02050113001A09001C001F0D002000A1808080080D00210B040D0109000E15000F009080808008150010020615010B000C21000D008E8080800821000E0010310106008C8080800831000C04063100100015290016009780808008290017020629010B000C35000D008E8080800835000E00102D0106008C808080082D000C02062D010B000C3D000D008E808080083D000E0010100201005B1D010502041D0009000A1D0009000F4D000E000F45001000918080800845001100134901050104490009000A490009000F5D000E000F55001000918080800855001100131002010001 - Name: '__llvm_covfun (2)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - CovFun: - - FuncName: early_exits - FuncHash: 0x27F9134B0E2D5C3D - FilenamesRef: 0x4F0FF417951E554C - Expressions: [] - Files: - - Index: 0 - Filename: branch-c-general.c - Regions: - - { dLoc: [ 33, 20, 24, 2 ], Ref: 0 } - - { dLoc: [ 2, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 7, 0, 8 ], Ref: 0 } - - { dLoc: [ 0, 9, 0, 10 ], isGap: true, Ref: 1 } - - { dLoc: [ 0, 10, 0, 12 ], Ref: 1 } - - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 3, 19, 2 ], Ref: 2 } - - { dLoc: [ 0, 10, 0, 17 ], Ref: 3 } - - { dLoc: [ 0, 18, 0, 19 ], isGap: true, Ref: 4 } - - { dLoc: [ 0, 19, 6, 4 ], Ref: 4 } - - { dLoc: [ 2, 9, 0, 15 ], Ref: 4 } - - { dLoc: [ 0, 16, 1, 7 ], isGap: true, Ref: 6 } - - { dLoc: [ 1, 7, 0, 12 ], Ref: 6 } - - { dLoc: [ 0, 13, 1, 5 ], isGap: true, Ref: 7 } - - { dLoc: [ 1, 5, 2, 4 ], Ref: 7 } - - { dLoc: [ 0, 9, 0, 14 ], Ref: 7 } - - { dLoc: [ 0, 15, 1, 7 ], isGap: true, Ref: 8 } - - { dLoc: [ 1, 7, 0, 15 ], Ref: 8 } - - { dLoc: [ 1, 4, 2, 3 ], isGap: true, Ref: 5 } - - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 3, 11, 2 ], Ref: 5 } - - { dLoc: [ 0, 7, 0, 8 ], Ref: 5 } - - { dLoc: [ 0, 9, 0, 10 ], isGap: true, Ref: 10 } - - { dLoc: [ 0, 10, 0, 12 ], Ref: 10 } - - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 3, 9, 2 ], Ref: 11 } - - { dLoc: [ 0, 6, 5, 4 ], Ref: 12 } - - { dLoc: [ 1, 9, 0, 15 ], Ref: 12 } - - { dLoc: [ 0, 16, 1, 7 ], isGap: true, Ref: 15 } - - { dLoc: [ 1, 7, 0, 13 ], Ref: 15 } - - { dLoc: [ 0, 14, 2, 7 ], isGap: true, Ref: 16 } - - { dLoc: [ 2, 7, 0, 10 ], Ref: 16 } - - { dLoc: [ 1, 12, 0, 19 ], Ref: 13 } - - { dLoc: [ 0, 21, 2, 3 ], isGap: true, Ref: 14 } - - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 3, 2, 2 ], Ref: 14 } - - { dLoc: [ 0, 7, 0, 8 ], Ref: 14 } - - { dLoc: [ 0, 9, 0, 10 ], isGap: true, Ref: 18 } - - { dLoc: [ 0, 10, 0, 12 ], Ref: 18 } - - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } + Content: 0449C70428C57369F80000003D5C2D0E4B13F9274C551E9517F40F4F01010028012114180210020100010101070008050009008A8080800805000A000C100101000109010313020D000A00111100120093808080081100130604110209000F190010018780808008190107000C1D000D0185808080081D010502041D0009000E21000F018780808008210107000F15010402838080800810010100011501030B021500070008290009008A8080800829000A000C10010100012D010309023100060504310109000F3D00100187808080083D0107000D41000E028780808008410207000A35010C0013390015028380808008100101000139010302023900070008490009008A8080800849000A000C1001010001 - Name: '__llvm_covfun (3)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - CovFun: - - FuncName: jumps - FuncHash: 0xD0E163345D499C1B - FilenamesRef: 0x4F0FF417951E554C - Expressions: [] - Files: - - Index: 0 - Filename: branch-c-general.c - Regions: - - { dLoc: [ 59, 14, 47, 2 ], Ref: 0 } - - { dLoc: [ 2, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 15, 0, 20 ], Ref: 1 } - - { dLoc: [ 0, 22, 0, 25 ], Ref: 2 } - - { dLoc: [ 0, 26, 0, 27 ], isGap: true, Ref: 3 } - - { dLoc: [ 0, 27, 4, 4 ], Ref: 3 } - - { dLoc: [ 1, 20, 2, 5 ], isGap: true, Tag: Zero } - - { dLoc: [ 1, 1, 0, 35 ], ExtTag: Skip } - - { dLoc: [ 1, 5, 1, 4 ], Tag: Zero } - - { dLoc: [ 0, 9, 0, 10 ], Tag: Zero } - - { dLoc: [ 0, 11, 0, 12 ], isGap: true, Ref: 5 } - - { dLoc: [ 0, 12, 0, 14 ], Ref: 5 } - - { dLoc: [ 1, 4, 2, 1 ], isGap: true, Ref: 4 } - - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 1, 38, 2 ], Ref: 7 } - - { dLoc: [ 1, 7, 0, 8 ], Ref: 7 } - - { dLoc: [ 0, 9, 0, 10 ], isGap: true, Ref: 8 } - - { dLoc: [ 0, 10, 0, 12 ], Ref: 8 } - - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 3, 0, 13 ], Ref: 9 } - - { dLoc: [ 0, 14, 2, 3 ], isGap: true, Ref: 9 } - - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 3, 33, 2 ], Tag: Zero } - - { dLoc: [ 0, 10, 0, 11 ], Ref: 10 } - - { dLoc: [ 0, 12, 0, 13 ], isGap: true, Ref: 11 } - - { dLoc: [ 0, 13, 3, 4 ], Ref: 11 } - - { dLoc: [ 1, 3, 2, 4 ], Ref: 13 } - - { dLoc: [ 1, 9, 0, 10 ], Ref: 13 } - - { dLoc: [ 0, 11, 0, 12 ], isGap: true, Ref: 14 } - - { dLoc: [ 0, 12, 0, 14 ], Ref: 14 } - - { dLoc: [ 2, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 3, 0, 13 ], Ref: 12 } - - { dLoc: [ 0, 14, 1, 1 ], isGap: true, Ref: 12 } - - { dLoc: [ 1, 1, 27, 2 ], Ref: 16 } - - { dLoc: [ 1, 1, 26, 2 ], Ref: 17 } - - { dLoc: [ 1, 1, 25, 2 ], Ref: 18 } - - { dLoc: [ 2, 7, 0, 12 ], Ref: 18 } - - { dLoc: [ 0, 13, 1, 5 ], isGap: true, Ref: 19 } - - { dLoc: [ 1, 5, 0, 15 ], Ref: 19 } - - { dLoc: [ 0, 16, 2, 3 ], isGap: true, Ref: 20 } - - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 3, 20, 2 ], Ref: 20 } - - { dLoc: [ 0, 10, 0, 15 ], Ref: 21 } - - { dLoc: [ 0, 16, 0, 17 ], isGap: true, Ref: 22 } - - { dLoc: [ 0, 17, 10, 4 ], Ref: 22 } - - { dLoc: [ 1, 3, 9, 4 ], Ref: 24 } - - { dLoc: [ 1, 16, 6, 17 ], isGap: true, Tag: Zero } - - { dLoc: [ 1, 5, 1, 17 ], Ref: 26 } - - { dLoc: [ 1, 18, 1, 5 ], isGap: true, Tag: Zero } - - { dLoc: [ 1, 5, 1, 18 ], Ref: 27 } - - { dLoc: [ 1, 19, 1, 5 ], isGap: true, Tag: Zero } - - { dLoc: [ 1, 5, 1, 17 ], Ref: 28 } - - { dLoc: [ 3, 4, 2, 3 ], isGap: true, Ref: 23 } - - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 3, 8, 2 ], Ref: 23 } - - { dLoc: [ 0, 15, 0, 21 ], Ref: 29 } - - { dLoc: [ 0, 23, 0, 26 ], Ref: 30 } - - { dLoc: [ 0, 27, 0, 28 ], isGap: true, Ref: 31 } - - { dLoc: [ 0, 28, 6, 4 ], Ref: 31 } - - { dLoc: [ 1, 21, 2, 5 ], isGap: true, Tag: Zero } - - { dLoc: [ 1, 1, 0, 63 ], ExtTag: Skip } - - { dLoc: [ 1, 5, 3, 4 ], Tag: Zero } - - { dLoc: [ 0, 9, 0, 10 ], Tag: Zero } - - { dLoc: [ 0, 11, 0, 12 ], isGap: true, Ref: 33 } - - { dLoc: [ 0, 12, 0, 14 ], Ref: 33 } - - { dLoc: [ 1, 3, 2, 4 ], Ref: 35 } - - { dLoc: [ 1, 9, 0, 10 ], Ref: 35 } - - { dLoc: [ 0, 11, 0, 12 ], isGap: true, Ref: 36 } - - { dLoc: [ 0, 12, 0, 14 ], Ref: 36 } - - { dLoc: [ 2, 1, 0, 1 ], ExtTag: Skip } + Content: 55947829059F255EB80100001B9C495D3463E1D04C551E9517F40F4F01010046013B0E2F02100201000105010F001409001600190D001A009B808080080D001B040400011402858080800810010100230001050104000009000A15000B008C8080800815000C000E11010402818080800810010100011D010126021D01070008210009008A8080800821000A000C1001010001250103000D25000E0283808080081001010001000103210229000A000B2D000C008D808080082D000D03043501030204350109000A39000B008C8080800839000C000E1002010001310103000D31000E0181808080084101011B024501011A024901011902490207000C4D000D0185808080084D0105000F5100100283808080081001010001510103140255000A000F5900100091808080085900110A04610103090400011006918080800869010501110001120185808080086D0105011200011301858080800871010501115D030402838080800810010100015D0103080275000F0015790017001A7D001B009C808080087D001C0604000115028580808008100101003F0001050304000009000A8501000B008C808080088501000C000E8D01010302048D010109000A9101000B008C808080089101000C000E1002010001 - Name: '__llvm_covfun (4)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - CovFun: - - FuncName: switches - FuncHash: 0x99A0C98383683E - FilenamesRef: 0x4F0FF417951E554C - Expressions: [] - Files: - - Index: 0 - Filename: branch-c-general.c - Regions: - - { dLoc: [ 108, 17, 37, 2 ], Ref: 0 } - - { dLoc: [ 2, 1, 1, 28 ], ExtTag: Skip } - - { dLoc: [ 2, 23, 2, 10 ], isGap: true, Tag: Zero } - - { dLoc: [ 1, 3, 1, 10 ], Ref: 2 } - - { dLoc: [ 2, 4, 2, 3 ], isGap: true, Ref: 1 } - - { dLoc: [ 1, 1, 0, 100 ], ExtTag: Skip } - - { dLoc: [ 1, 3, 28, 2 ], Ref: 1 } - - { dLoc: [ 0, 63, 0, 70 ], Ref: 3 } - - { dLoc: [ 0, 72, 0, 75 ], Ref: 4 } - - { dLoc: [ 0, 76, 0, 77 ], isGap: true, Ref: 5 } - - { dLoc: [ 0, 77, 23, 4 ], Ref: 5 } - - { dLoc: [ 1, 25, 20, 15 ], isGap: true, Tag: Zero } - - { dLoc: [ 1, 5, 19, 15 ], Ref: 8 } - - { dLoc: [ 1, 11, 0, 12 ], Ref: 8 } - - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 9 } - - { dLoc: [ 0, 14, 0, 16 ], Ref: 9 } - - { dLoc: [ 1, 1, 0, 21 ], ExtTag: Skip } - - { dLoc: [ 1, 5, 16, 15 ], Ref: 11 } - - { dLoc: [ 1, 11, 0, 12 ], Ref: 11 } - - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 12 } - - { dLoc: [ 0, 14, 0, 16 ], Ref: 12 } - - { dLoc: [ 1, 7, 0, 12 ], Ref: 13 } - - { dLoc: [ 0, 13, 1, 5 ], isGap: true, Ref: 13 } - - { dLoc: [ 1, 5, 13, 15 ], Ref: 14 } - - { dLoc: [ 1, 11, 0, 12 ], Ref: 14 } - - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 15 } - - { dLoc: [ 0, 14, 0, 16 ], Ref: 15 } - - { dLoc: [ 1, 7, 0, 15 ], Ref: 16 } - - { dLoc: [ 0, 16, 1, 5 ], isGap: true, Ref: 16 } - - { dLoc: [ 1, 5, 10, 15 ], Ref: 17 } - - { dLoc: [ 1, 11, 0, 12 ], Ref: 17 } - - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 18 } - - { dLoc: [ 0, 14, 0, 16 ], Ref: 18 } - - { dLoc: [ 1, 7, 8, 15 ], Ref: 19 } - - { dLoc: [ 0, 18, 3, 17 ], isGap: true, Tag: Zero } - - { dLoc: [ 1, 7, 2, 17 ], Ref: 21 } - - { dLoc: [ 1, 13, 0, 14 ], Ref: 21 } - - { dLoc: [ 0, 15, 0, 16 ], isGap: true, Ref: 22 } - - { dLoc: [ 0, 16, 0, 18 ], Ref: 22 } - - { dLoc: [ 1, 9, 0, 17 ], Ref: 23 } - - { dLoc: [ 1, 8, 2, 5 ], isGap: true, Ref: 20 } - - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 5, 2, 15 ], Ref: 24 } - - { dLoc: [ 1, 11, 0, 23 ], Ref: 24 } - - { dLoc: [ 0, 24, 1, 9 ], isGap: true, Ref: 25 } - - { dLoc: [ 1, 9, 0, 15 ], Ref: 25 } - - { dLoc: [ 2, 4, 3, 3 ], isGap: true, Ref: 6 } - - { dLoc: [ 1, 1, 1, 33 ], ExtTag: Skip } - - { dLoc: [ 2, 3, 2, 2 ], Ref: 6 } - - { dLoc: [ 0, 7, 0, 17 ], Ref: 6 } - - { dLoc: [ 0, 18, 0, 19 ], isGap: true, Ref: 27 } - - { dLoc: [ 0, 19, 0, 21 ], Ref: 27 } - - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } + Content: 7129CA3C268292BF4D0100003E688383C9A099004C551E9517F40F4F01010035016C112502100201011C000217028A80808008090103010A05020402838080800810010100620501031C020D003F0046110048004B15004C00CD8080800815004D1704000119148F80808008210105130F21010B000C25000D008E8080800825000E001010010100152D0105100F2D010B000C31000D008E8080800831000E0010350107000C35000D0185808080083901050D0F39010B000C3D000D008E808080083D000E0010410107000F4100100185808080084501050A0F45010B000C49000D008E8080800849000E00104D0107080F000012039180808008550107021155010D000E59000F00908080800859001000125D010900115101080285808080081001010001610105020F61010B0017650018018980808008650109000F1902040383808080081001010121190203020219000700116D00120093808080086D001300151001010001 - Name: '__llvm_covfun (5)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - CovFun: - - FuncName: big_switch - FuncHash: 0xB6695A86B856FFD6 - FilenamesRef: 0x4F0FF417951E554C - Expressions: [] - Files: - - Index: 0 - Filename: branch-c-general.c - Regions: - - { dLoc: [ 147, 19, 31, 2 ], Ref: 0 } - - { dLoc: [ 1, 19, 0, 25 ], Ref: 1 } - - { dLoc: [ 0, 27, 0, 30 ], Ref: 2 } - - { dLoc: [ 0, 31, 0, 32 ], isGap: true, Ref: 3 } - - { dLoc: [ 0, 32, 28, 4 ], Ref: 3 } - - { dLoc: [ 1, 21, 25, 12 ], isGap: true, Tag: Zero } - - { dLoc: [ 1, 5, 24, 12 ], Ref: 6 } - - { dLoc: [ 1, 11, 0, 12 ], Ref: 6 } - - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 7 } - - { dLoc: [ 0, 14, 0, 16 ], Ref: 7 } - - { dLoc: [ 1, 1, 0, 21 ], ExtTag: Skip } - - { dLoc: [ 1, 5, 21, 12 ], Ref: 9 } - - { dLoc: [ 1, 11, 0, 12 ], Ref: 9 } - - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 10 } - - { dLoc: [ 0, 14, 0, 16 ], Ref: 10 } - - { dLoc: [ 1, 7, 0, 12 ], Ref: 11 } - - { dLoc: [ 0, 13, 1, 5 ], isGap: true, Ref: 11 } - - { dLoc: [ 1, 5, 18, 12 ], Ref: 12 } - - { dLoc: [ 1, 11, 0, 12 ], Ref: 12 } - - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 13 } - - { dLoc: [ 0, 14, 0, 16 ], Ref: 13 } - - { dLoc: [ 1, 7, 0, 12 ], Ref: 14 } - - { dLoc: [ 0, 13, 3, 5 ], isGap: true, Ref: 14 } - - { dLoc: [ 1, 1, 1, 1 ], ExtTag: Skip } - - { dLoc: [ 2, 5, 13, 12 ], Ref: 15 } - - { dLoc: [ 1, 11, 0, 12 ], Ref: 15 } - - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 16 } - - { dLoc: [ 0, 14, 0, 16 ], Ref: 16 } - - { dLoc: [ 1, 7, 0, 12 ], Ref: 17 } - - { dLoc: [ 0, 13, 1, 5 ], isGap: true, Ref: 17 } - - { dLoc: [ 1, 5, 10, 12 ], Ref: 18 } - - { dLoc: [ 1, 11, 0, 12 ], Ref: 18 } - - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 19 } - - { dLoc: [ 0, 14, 0, 16 ], Ref: 19 } - - { dLoc: [ 1, 7, 0, 12 ], Ref: 20 } - - { dLoc: [ 0, 13, 3, 5 ], isGap: true, Ref: 20 } - - { dLoc: [ 1, 1, 1, 1 ], ExtTag: Skip } - - { dLoc: [ 2, 5, 5, 12 ], Ref: 21 } - - { dLoc: [ 1, 11, 0, 12 ], Ref: 21 } - - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 22 } - - { dLoc: [ 0, 14, 0, 16 ], Ref: 22 } - - { dLoc: [ 1, 7, 0, 12 ], Ref: 23 } - - { dLoc: [ 0, 13, 1, 5 ], isGap: true, Ref: 23 } - - { dLoc: [ 1, 5, 2, 12 ], Ref: 24 } - - { dLoc: [ 1, 11, 0, 12 ], Ref: 24 } - - { dLoc: [ 0, 13, 0, 14 ], isGap: true, Ref: 25 } - - { dLoc: [ 0, 14, 0, 16 ], Ref: 25 } - - { dLoc: [ 1, 7, 0, 12 ], Ref: 26 } - - { dLoc: [ 3, 1, 0, 1 ], ExtTag: Skip } + Content: 3F4D1C6E6087417B32010000D6FF56B8865A69B64C551E9517F40F4F01010031019301131F02050113001909001B001E0D001F00A0808080080D00201C04000115198C80808008190105180C19010B000C1D000D008E808080081D000E00101001010015250105150C25010B000C29000D008E8080800829000E00102D0107000C2D000D018580808008310105120C31010B000C35000D008E8080800835000E0010390107000C39000D03858080800810010101013D02050D0C3D010B000C41000D008E8080800841000E0010450107000C45000D0185808080084901050A0C49010B000C4D000D008E808080084D000E0010510107000C51000D0385808080081001010101550205050C55010B000C59000D008E8080800859000E00105D0107000C5D000D018580808008610105020C61010B000C65000D008E8080800865000E0010690107000C1003010001 - Name: '__llvm_covfun (6)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - CovFun: - - FuncName: boolean_operators - FuncHash: 0x46CF38F3CE391 - FilenamesRef: 0x4F0FF417951E554C - Expressions: [] - Files: - - Index: 0 - Filename: branch-c-general.c - Regions: - - { dLoc: [ 180, 26, 12, 2 ], Ref: 0 } - - { dLoc: [ 2, 19, 0, 26 ], Ref: 1 } - - { dLoc: [ 0, 28, 0, 31 ], Ref: 2 } - - { dLoc: [ 0, 32, 0, 33 ], isGap: true, Ref: 3 } - - { dLoc: [ 0, 33, 8, 4 ], Ref: 3 } - - { dLoc: [ 1, 9, 0, 14 ], Ref: 3 } - - { dLoc: [ 0, 18, 0, 19 ], Ref: 5 } - - { dLoc: [ 1, 1, 0, 100 ], ExtTag: Skip } - - { dLoc: [ 1, 9, 0, 14 ], Ref: 3 } - - { dLoc: [ 0, 18, 0, 19 ], Ref: 7 } - - { dLoc: [ 1, 1, 0, 100 ], ExtTag: Skip } - - { dLoc: [ 1, 9, 0, 14 ], Ref: 3 } - - { dLoc: [ 0, 9, 0, 23 ], Ref: 3 } - - { dLoc: [ 0, 18, 0, 23 ], Ref: 11 } - - { dLoc: [ 0, 27, 0, 28 ], Ref: 9 } - - { dLoc: [ 1, 1, 0, 113 ], ExtTag: Skip } - - { dLoc: [ 1, 9, 0, 14 ], Ref: 3 } - - { dLoc: [ 0, 9, 0, 23 ], Ref: 3 } - - { dLoc: [ 0, 18, 0, 23 ], Ref: 15 } - - { dLoc: [ 0, 27, 0, 28 ], Ref: 13 } - - { dLoc: [ 2, 1, 0, 113 ], ExtTag: Skip } + Content: 59A48AA8899AA3587200000091E33C8FF36C04004C551E9517F40F4F0101001501B4011A0C02050213001A09001C001F0D002000A1808080080D002108040D0109000E1500120013100101005D0D0109000E1D00120013100101005D0D0109000E0D000900172D0012001725001B001C10010100630D0109000E0D000900173D0012001735001B001C1002010063 - Name: '__llvm_covfun (7)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - CovFun: - - FuncName: boolop_loops - FuncHash: 0xAC1EE72F5632D15F - FilenamesRef: 0x4F0FF417951E554C - Expressions: [] - Files: - - Index: 0 - Filename: branch-c-general.c - Regions: - - { dLoc: [ 194, 21, 13, 2 ], Ref: 0 } - - { dLoc: [ 2, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 10, 0, 11 ], Ref: 4 } - - { dLoc: [ 0, 10, 0, 21 ], Ref: 4 } - - { dLoc: [ 0, 15, 0, 21 ], Ref: 4 } - - { dLoc: [ 0, 22, 1, 5 ], isGap: true, Ref: 2 } - - { dLoc: [ 1, 5, 0, 8 ], Ref: 2 } - - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 3, 7, 2 ], Ref: 3 } - - { dLoc: [ 0, 10, 0, 17 ], Ref: 9 } - - { dLoc: [ 0, 10, 0, 28 ], Ref: 9 } - - { dLoc: [ 0, 21, 0, 28 ], Ref: 9 } - - { dLoc: [ 0, 29, 1, 5 ], isGap: true, Ref: 7 } - - { dLoc: [ 1, 5, 0, 8 ], Ref: 7 } - - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 3, 4, 2 ], Ref: 8 } - - { dLoc: [ 0, 17, 0, 18 ], Ref: 15 } - - { dLoc: [ 0, 17, 0, 28 ], Ref: 15 } - - { dLoc: [ 0, 22, 0, 28 ], Ref: 15 } - - { dLoc: [ 0, 30, 0, 33 ], Ref: 12 } - - { dLoc: [ 0, 34, 0, 35 ], Ref: 13 } - - { dLoc: [ 1, 1, 0, 104 ], ExtTag: Skip } - - { dLoc: [ 1, 3, 2, 2 ], Ref: 14 } - - { dLoc: [ 0, 10, 0, 17 ], Ref: 21 } - - { dLoc: [ 0, 10, 0, 28 ], Ref: 21 } - - { dLoc: [ 0, 21, 0, 28 ], Ref: 21 } - - { dLoc: [ 0, 30, 0, 33 ], Ref: 18 } - - { dLoc: [ 0, 34, 0, 35 ], Ref: 19 } - - { dLoc: [ 1, 1, 0, 104 ], ExtTag: Skip } + Content: F5953D044B505D139E0000005FD132562FE71EAC4C551E9517F40F4F0101001D01C201150D02100201000111010A000B11000A001511000F0015090016018580808008090105000810010100010D0103070225000A001125000A001C250015001C1D001D0185808080081D01050008100101000121010304023D001100123D0011001C3D0016001C31001E002135002200231001010061390103020255000A001155000A001C550015001C49001E00214D002200231001010061 - Name: '__llvm_covfun (8)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - CovFun: - - FuncName: conditional_operator - FuncHash: 0xD6D0 - FilenamesRef: 0x4F0FF417951E554C - Expressions: [] - Files: - - Index: 0 - Filename: branch-c-general.c - Regions: - - { dLoc: [ 209, 29, 7, 2 ], Ref: 0 } - - { dLoc: [ 2, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 11, 0, 17 ], Ref: 0 } - - { dLoc: [ 0, 19, 0, 20 ], isGap: true, Ref: 2 } - - { dLoc: [ 0, 20, 0, 21 ], Ref: 2 } - - { dLoc: [ 0, 24, 0, 25 ], Ref: 3 } - - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 3, 2, 2 ], Ref: 1 } - - { dLoc: [ 0, 11, 0, 12 ], Ref: 1 } - - { dLoc: [ 0, 16, 0, 17 ], Ref: 0 } - - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } + Content: 20E5C369BDF15C7940000000D0D60000000000004C551E9517F40F4F0101000B01D1011D0702100201000101010B001109001300948080800809001400150D001800191001010001050103020205000B000C01001000111001010001 - Name: '__llvm_covfun (9)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - CovFun: - - FuncName: do_fallthrough - FuncHash: 0x78F0876298F0EA92 - FilenamesRef: 0x4F0FF417951E554C - Expressions: [] - Files: - - Index: 0 - Filename: branch-c-general.c - Regions: - - { dLoc: [ 218, 23, 11, 2 ], Ref: 0 } - - { dLoc: [ 1, 19, 0, 25 ], Ref: 1 } - - { dLoc: [ 0, 27, 0, 30 ], Ref: 2 } - - { dLoc: [ 0, 31, 0, 32 ], isGap: true, Ref: 3 } - - { dLoc: [ 0, 32, 9, 4 ], Ref: 3 } - - { dLoc: [ 2, 8, 6, 6 ], Ref: 5 } - - { dLoc: [ 1, 1, 2, 77 ], ExtTag: Skip } - - { dLoc: [ 3, 11, 0, 16 ], Ref: 5 } - - { dLoc: [ 0, 17, 0, 18 ], isGap: true, Ref: 8 } - - { dLoc: [ 0, 18, 0, 23 ], Ref: 8 } - - { dLoc: [ 0, 24, 1, 7 ], isGap: true, Ref: 9 } - - { dLoc: [ 1, 7, 1, 6 ], Ref: 9 } - - { dLoc: [ 1, 14, 0, 19 ], Ref: 6 } + Content: 7DE8E7C47096EB425200000092EAF0986287F0784C551E9517F40F4F0101000D01DA01170B02050113001909001B001E0D001F00A0808080080D002009041502080606100101024D15030B00102100110092808080082100120017250018018780808008250107010619010E0013 - Name: '__llvm_covfun (10)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - CovFun: - - FuncName: main - FuncHash: 0x18 - FilenamesRef: 0x4F0FF417951E554C - Expressions: [] - Files: - - Index: 0 - Filename: branch-c-general.c - Regions: - - { dLoc: [ 245, 40, 15, 2 ], Ref: 0 } + Content: FAD58DE7366495DB0A00000018000000000000004C551E9517F40F4F0101000101F501280F02 - Name: '__llvm_covfun (11)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - CovFun: - - FuncName: 'branch-c-general.c:static_func' - FuncHash: 0x46D1 - FilenamesRef: 0x4F0FF417951E554C - Expressions: [] - Files: - - Index: 0 - Filename: branch-c-general.c - Regions: - - { dLoc: [ 231, 27, 3, 2 ], Ref: 0 } - - { dLoc: [ 1, 19, 0, 25 ], Ref: 1 } - - { dLoc: [ 0, 27, 0, 30 ], Ref: 2 } - - { dLoc: [ 0, 31, 0, 32 ], isGap: true, Ref: 3 } - - { dLoc: [ 0, 32, 1, 4 ], Ref: 3 } + Content: 4CB4F49D6737EBF922000000D1460000000000004C551E9517F40F4F0101000501E7011B0302050113001909001B001E0D001F00A0808080080D00200104 - Name: __llvm_covmap Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - CovMap: - - FilenamesRef: 0x4F0FF417951E554C - Version: 6 + Content: 0000000017000000000000000600000002140000126272616E63682D632D67656E6572616C2E6300 - Name: __llvm_prf_names Type: SHT_PROGBITS Flags: [ SHF_ALLOC, SHF_GNU_RETAIN ] AddressAlign: 0x1 - PrfNames: - - - simple_loops - - conditionals - - early_exits - - jumps - - switches - - big_switch - - boolean_operators - - boolop_loops - - conditional_operator - - do_fallthrough - - main - - 'branch-c-general.c:static_func' + Content: A6010073696D706C655F6C6F6F707301636F6E646974696F6E616C73016561726C795F6578697473016A756D7073017377697463686573016269675F73776974636801626F6F6C65616E5F6F70657261746F727301626F6F6C6F705F6C6F6F707301636F6E646974696F6E616C5F6F70657261746F7201646F5F66616C6C7468726F756768016D61696E016272616E63682D632D67656E6572616C2E633A7374617469635F66756E63 - Type: SectionHeaderTable Sections: - Name: .strtab @@ -547,4 +94,84 @@ Sections: - Name: '__llvm_covfun (11)' - Name: __llvm_covmap - Name: __llvm_prf_names + - Name: .symtab +Symbols: + - Name: __llvm_covmap + Type: STT_SECTION + Section: __llvm_covmap + - Name: __llvm_prf_names + Type: STT_SECTION + Section: __llvm_prf_names + - Name: __covrec_79BE9FB148987D7u + Type: STT_OBJECT + Section: __llvm_covfun + Binding: STB_WEAK + Size: 0x69 + Other: [ STV_HIDDEN ] + - Name: __covrec_688E43F1A505AD83u + Type: STT_OBJECT + Section: '__llvm_covfun (1)' + Binding: STB_WEAK + Size: 0x106 + Other: [ STV_HIDDEN ] + - Name: __covrec_6973C52804C74904u + Type: STT_OBJECT + Section: '__llvm_covfun (2)' + Binding: STB_WEAK + Size: 0x114 + Other: [ STV_HIDDEN ] + - Name: __covrec_5E259F0529789455u + Type: STT_OBJECT + Section: '__llvm_covfun (3)' + Binding: STB_WEAK + Size: 0x1D4 + Other: [ STV_HIDDEN ] + - Name: __covrec_BF9282263CCA2971u + Type: STT_OBJECT + Section: '__llvm_covfun (4)' + Binding: STB_WEAK + Size: 0x169 + Other: [ STV_HIDDEN ] + - Name: __covrec_7B4187606E1C4D3Fu + Type: STT_OBJECT + Section: '__llvm_covfun (5)' + Binding: STB_WEAK + Size: 0x14E + Other: [ STV_HIDDEN ] + - Name: __covrec_58A39A89A88AA459u + Type: STT_OBJECT + Section: '__llvm_covfun (6)' + Binding: STB_WEAK + Size: 0x8E + Other: [ STV_HIDDEN ] + - Name: __covrec_135D504B043D95F5u + Type: STT_OBJECT + Section: '__llvm_covfun (7)' + Binding: STB_WEAK + Size: 0xBA + Other: [ STV_HIDDEN ] + - Name: __covrec_795CF1BD69C3E520u + Type: STT_OBJECT + Section: '__llvm_covfun (8)' + Binding: STB_WEAK + Size: 0x5C + Other: [ STV_HIDDEN ] + - Name: __covrec_42EB9670C4E7E87Du + Type: STT_OBJECT + Section: '__llvm_covfun (9)' + Binding: STB_WEAK + Size: 0x6E + Other: [ STV_HIDDEN ] + - Name: __covrec_DB956436E78DD5FAu + Type: STT_OBJECT + Section: '__llvm_covfun (10)' + Binding: STB_WEAK + Size: 0x26 + Other: [ STV_HIDDEN ] + - Name: __covrec_F9EB37679DF4B44Cu + Type: STT_OBJECT + Section: '__llvm_covfun (11)' + Binding: STB_WEAK + Size: 0x3E + Other: [ STV_HIDDEN ] ... diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed-single.yaml b/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed-single.yaml index 9ea346722b915..56f3d4955f4d9 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed-single.yaml +++ b/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed-single.yaml @@ -11,139 +11,22 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - CovFun: - - FuncName: _Z4funcii - FuncHash: 0x75869EC9191CB289 - FilenamesRef: 0xE846BD6FE050298F - Expressions: [] - Files: - - Index: 0 - Filename: branch-logical-mixed.cpp - Regions: - - { dLoc: [ 8, 25, 67, 2 ], Ref: 0 } - - { dLoc: [ 7, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 12, 0, 14 ], Ref: 0 } - - { dLoc: [ 0, 12, 1, 14 ], Ref: 0 } - - { dLoc: [ 0, 12, 2, 14 ], Ref: 0 } - - { dLoc: [ 0, 12, 3, 14 ], Ref: 0 } - - { dLoc: [ 0, 12, 4, 14 ], Ref: 0 } - - { dLoc: [ 1, 12, 0, 14 ], Ref: 9 } - - { dLoc: [ 1, 12, 0, 14 ], Ref: 7 } - - { dLoc: [ 1, 12, 0, 14 ], Ref: 5 } - - { dLoc: [ 1, 12, 0, 14 ], Ref: 3 } - - { dLoc: [ 1, 12, 0, 14 ], Ref: 1 } - - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 12, 0, 14 ], Ref: 0 } - - { dLoc: [ 0, 12, 1, 14 ], Ref: 0 } - - { dLoc: [ 0, 12, 2, 14 ], Ref: 0 } - - { dLoc: [ 0, 12, 3, 14 ], Ref: 0 } - - { dLoc: [ 0, 12, 4, 14 ], Ref: 0 } - - { dLoc: [ 1, 12, 0, 14 ], Ref: 19 } - - { dLoc: [ 1, 12, 0, 14 ], Ref: 17 } - - { dLoc: [ 1, 12, 0, 14 ], Ref: 15 } - - { dLoc: [ 1, 12, 0, 14 ], Ref: 13 } - - { dLoc: [ 1, 12, 0, 14 ], Ref: 11 } - - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 12, 1, 16 ], Ref: 0 } - - { dLoc: [ 0, 12, 3, 16 ], Ref: 0 } - - { dLoc: [ 0, 12, 5, 16 ], Ref: 0 } - - { dLoc: [ 0, 12, 7, 16 ], Ref: 0 } - - { dLoc: [ 0, 12, 9, 16 ], Ref: 0 } - - { dLoc: [ 0, 13, 0, 15 ], Ref: 0 } - - { dLoc: [ 1, 13, 0, 15 ], Ref: 26 } - - { dLoc: [ 1, 12, 1, 16 ], Ref: 25 } - - { dLoc: [ 0, 13, 0, 15 ], Ref: 25 } - - { dLoc: [ 1, 13, 0, 15 ], Ref: 28 } - - { dLoc: [ 1, 12, 1, 16 ], Ref: 24 } - - { dLoc: [ 0, 13, 0, 15 ], Ref: 24 } - - { dLoc: [ 1, 13, 0, 15 ], Ref: 30 } - - { dLoc: [ 1, 12, 1, 16 ], Ref: 23 } - - { dLoc: [ 0, 13, 0, 15 ], Ref: 23 } - - { dLoc: [ 1, 13, 0, 15 ], Ref: 32 } - - { dLoc: [ 1, 12, 1, 16 ], Ref: 22 } - - { dLoc: [ 0, 13, 0, 15 ], Ref: 22 } - - { dLoc: [ 1, 13, 0, 15 ], Ref: 34 } - - { dLoc: [ 1, 12, 1, 16 ], Ref: 21 } - - { dLoc: [ 0, 13, 0, 15 ], Ref: 21 } - - { dLoc: [ 1, 13, 0, 15 ], Ref: 36 } - - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 12, 1, 16 ], Ref: 0 } - - { dLoc: [ 0, 12, 3, 16 ], Ref: 0 } - - { dLoc: [ 0, 12, 5, 16 ], Ref: 0 } - - { dLoc: [ 0, 12, 7, 16 ], Ref: 0 } - - { dLoc: [ 0, 12, 9, 16 ], Ref: 0 } - - { dLoc: [ 0, 13, 0, 15 ], Ref: 0 } - - { dLoc: [ 1, 13, 0, 15 ], Ref: 43 } - - { dLoc: [ 1, 12, 1, 16 ], Ref: 42 } - - { dLoc: [ 0, 13, 0, 15 ], Ref: 42 } - - { dLoc: [ 1, 13, 0, 15 ], Ref: 45 } - - { dLoc: [ 1, 12, 1, 16 ], Ref: 41 } - - { dLoc: [ 0, 13, 0, 15 ], Ref: 41 } - - { dLoc: [ 1, 13, 0, 15 ], Ref: 47 } - - { dLoc: [ 1, 12, 1, 16 ], Ref: 40 } - - { dLoc: [ 0, 13, 0, 15 ], Ref: 40 } - - { dLoc: [ 1, 13, 0, 15 ], Ref: 49 } - - { dLoc: [ 1, 12, 1, 16 ], Ref: 39 } - - { dLoc: [ 0, 13, 0, 15 ], Ref: 39 } - - { dLoc: [ 1, 13, 0, 15 ], Ref: 51 } - - { dLoc: [ 1, 12, 1, 16 ], Ref: 38 } - - { dLoc: [ 0, 13, 0, 15 ], Ref: 38 } - - { dLoc: [ 1, 13, 0, 15 ], Ref: 53 } - - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 7, 0, 8 ], Ref: 0 } - - { dLoc: [ 0, 9, 1, 5 ], isGap: true, Ref: 55 } - - { dLoc: [ 1, 5, 0, 22 ], Ref: 55 } - - { dLoc: [ 0, 23, 2, 5 ], isGap: true, Ref: 56 } - - { dLoc: [ 2, 5, 0, 22 ], Ref: 56 } - - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 3, 14, 2 ], Ref: 57 } - - { dLoc: [ 0, 7, 0, 8 ], Ref: 57 } - - { dLoc: [ 0, 9, 1, 5 ], isGap: true, Ref: 58 } - - { dLoc: [ 1, 5, 0, 22 ], Ref: 58 } - - { dLoc: [ 0, 23, 2, 5 ], isGap: true, Ref: 59 } - - { dLoc: [ 2, 5, 0, 22 ], Ref: 59 } - - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 3, 9, 2 ], Ref: 60 } - - { dLoc: [ 0, 7, 0, 8 ], Ref: 60 } - - { dLoc: [ 0, 9, 1, 5 ], isGap: true, Ref: 61 } - - { dLoc: [ 1, 5, 0, 22 ], Ref: 61 } - - { dLoc: [ 0, 23, 2, 5 ], isGap: true, Ref: 62 } - - { dLoc: [ 2, 5, 0, 22 ], Ref: 62 } - - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 3, 4, 2 ], Ref: 63 } - - { dLoc: [ 0, 7, 0, 8 ], Ref: 63 } - - { dLoc: [ 0, 9, 1, 5 ], isGap: true, Ref: 64 } - - { dLoc: [ 1, 5, 0, 22 ], Ref: 64 } - - { dLoc: [ 0, 23, 2, 5 ], isGap: true, Ref: 65 } - - { dLoc: [ 2, 5, 0, 22 ], Ref: 65 } + Content: F0A0ED2C305C0BB32D02000089B21C19C99E86758F2950E06FBD46E8010100600108194302100701000101010C000E01000C010E01000C020E01000C030E01000C040E25010C000E1D010C000E15010C000E0D010C000E05010C000E100101000101010C000E01000C010E01000C020E01000C030E01000C040E4D010C000E45010C000E3D010C000E35010C000E2D010C000E100101000101010C011001000C031001000C051001000C071001000C091001000D000F69010D000F65010C011065000D000F71010D000F61010C011061000D000F79010D000F5D010C01105D000D000F8101010D000F59010C011059000D000F8901010D000F55010C011055000D000F9101010D000F100101000101010C011001000C031001000C051001000C071001000C091001000D000FAD01010D000FA901010C0110A901000D000FB501010D000FA501010C0110A501000D000FBD01010D000FA101010C0110A101000D000FC501010D000F9D01010C01109D01000D000FCD01010D000F9901010C01109901000D000FD501010D000F10010100010101070008DD010009018580808008DD0101050016E1010017028580808008E101020500161001010001E50101030E02E50100070008E9010009018580808008E90101050016ED010017028580808008ED01020500161001010001F10101030902F10100070008F5010009018580808008F50101050016F9010017028580808008F901020500161001010001FD0101030402FD01000700088102000901858080800881020105001685020017028580808008850202050016 - Name: '__llvm_covfun (1)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - CovFun: - - FuncName: main - FuncHash: 0x18 - FilenamesRef: 0xE846BD6FE050298F - Expressions: [] - Files: - - Index: 0 - Filename: branch-logical-mixed.cpp - Regions: - - { dLoc: [ 79, 1, 4, 2 ], Ref: 0 } + Content: FAD58DE7366495DB0900000018000000000000008F2950E06FBD46E801010001014F010402 - Name: __llvm_covmap Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - CovMap: - - FilenamesRef: 0xE846BD6FE050298F - Version: 6 + Content: 000000001D0000000000000006000000021A0000186272616E63682D6C6F676963616C2D6D697865642E637070000000 - Name: __llvm_prf_names Type: SHT_PROGBITS Flags: [ SHF_ALLOC, SHF_GNU_RETAIN ] AddressAlign: 0x1 - PrfNames: - - - _Z4funcii - - main + Content: 0E005F5A3466756E636969016D61696E - Type: SectionHeaderTable Sections: - Name: .strtab @@ -151,4 +34,24 @@ Sections: - Name: '__llvm_covfun (1)' - Name: __llvm_covmap - Name: __llvm_prf_names + - Name: .symtab +Symbols: + - Name: __llvm_covmap + Type: STT_SECTION + Section: __llvm_covmap + - Name: __llvm_prf_names + Type: STT_SECTION + Section: __llvm_prf_names + - Name: __covrec_B30B5C302CEDA0F0u + Type: STT_OBJECT + Section: __llvm_covfun + Binding: STB_WEAK + Size: 0x249 + Other: [ STV_HIDDEN ] + - Name: __covrec_DB956436E78DD5FAu + Type: STT_OBJECT + Section: '__llvm_covfun (1)' + Binding: STB_WEAK + Size: 0x25 + Other: [ STV_HIDDEN ] ... diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.yaml b/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.yaml index 00a085c3e660f..5c5f62b11863b 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.yaml +++ b/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.yaml @@ -11,233 +11,27 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - CovFun: - - FuncName: _Z4funcii - FuncHash: 0x654340310C838D2 - FilenamesRef: 0x5D8FCE3E3196E693 - Expressions: [] - Files: - - Index: 0 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 16, 25, 17, 2 ], Ref: 0 } - - { dLoc: [ 1, 12, 0, 17 ], Expansion: 1 } - - { dLoc: [ 0, 21, 0, 26 ], Expansion: 2 } - - { dLoc: [ 1, 1, 0, 92 ], ExtTag: Skip } - - { dLoc: [ 1, 12, 0, 17 ], Expansion: 3 } - - { dLoc: [ 1, 1, 0, 98 ], ExtTag: Skip } - - { dLoc: [ 1, 12, 0, 18 ], Expansion: 4 } - - { dLoc: [ 1, 1, 0, 104 ], ExtTag: Skip } - - { dLoc: [ 1, 12, 0, 18 ], Expansion: 5 } - - { dLoc: [ 1, 1, 0, 110 ], ExtTag: Skip } - - { dLoc: [ 1, 12, 0, 18 ], Expansion: 6 } - - { dLoc: [ 1, 1, 0, 116 ], ExtTag: Skip } - - { dLoc: [ 1, 10, 0, 11 ], Ref: 0 } - - { dLoc: [ 0, 10, 0, 16 ], Ref: 0 } - - { dLoc: [ 0, 10, 0, 21 ], Ref: 0 } - - { dLoc: [ 0, 10, 0, 26 ], Ref: 0 } - - { dLoc: [ 0, 15, 0, 16 ], Ref: 17 } - - { dLoc: [ 0, 20, 0, 21 ], Ref: 15 } - - { dLoc: [ 0, 25, 0, 26 ], Ref: 13 } - - { dLoc: [ 0, 30, 0, 31 ], Ref: 11 } - - { dLoc: [ 1, 1, 4, 85 ], ExtTag: Skip } - - Index: 1 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 5, 15, 0, 23 ], Ref: 0 } - - { dLoc: [ 0, 15, 0, 23 ], Ref: 0 } - - Index: 2 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 6, 15, 0, 23 ], Ref: 1 } - - Index: 3 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 7, 15, 0, 31 ], Ref: 0 } - - { dLoc: [ 0, 16, 0, 21 ], Expansion: 7 } - - { dLoc: [ 0, 25, 0, 30 ], Expansion: 8 } - - Index: 4 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 9, 16, 0, 21 ], Expansion: 9 } - - Index: 5 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 10, 16, 0, 22 ], Expansion: 10 } - - Index: 6 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 11, 16, 0, 22 ], Expansion: 11 } - - Index: 7 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 5, 15, 0, 23 ], Ref: 0 } - - { dLoc: [ 0, 15, 0, 23 ], Ref: 0 } - - Index: 8 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 6, 15, 0, 23 ], Ref: 3 } - - Index: 9 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 7, 15, 0, 31 ], Ref: 0 } - - { dLoc: [ 0, 16, 0, 21 ], Expansion: 12 } - - { dLoc: [ 0, 25, 0, 30 ], Expansion: 13 } - - Index: 10 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 9, 16, 0, 21 ], Expansion: 14 } - - Index: 11 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 10, 16, 0, 22 ], Expansion: 15 } - - Index: 12 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 5, 15, 0, 23 ], Ref: 0 } - - { dLoc: [ 0, 15, 0, 23 ], Ref: 0 } - - Index: 13 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 6, 15, 0, 23 ], Ref: 5 } - - Index: 14 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 7, 15, 0, 31 ], Ref: 0 } - - { dLoc: [ 0, 16, 0, 21 ], Expansion: 16 } - - { dLoc: [ 0, 25, 0, 30 ], Expansion: 17 } - - Index: 15 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 9, 16, 0, 21 ], Expansion: 18 } - - Index: 16 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 5, 15, 0, 23 ], Ref: 0 } - - { dLoc: [ 0, 15, 0, 23 ], Ref: 0 } - - Index: 17 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 6, 15, 0, 23 ], Ref: 7 } - - Index: 18 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 7, 15, 0, 31 ], Ref: 0 } - - { dLoc: [ 0, 16, 0, 21 ], Expansion: 19 } - - { dLoc: [ 0, 25, 0, 30 ], Expansion: 20 } - - Index: 19 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 5, 15, 0, 23 ], Ref: 0 } - - { dLoc: [ 0, 15, 0, 23 ], Ref: 0 } - - Index: 20 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 6, 15, 0, 23 ], Ref: 9 } + Content: F0A0ED2C305C0BB33F010000D238C8100334540693E696313ECE8F5D15010101010101010101010101010101010101010101001501101911020C010C0011140015001A100101005C1C010C0011100101006224010C001210010100682C010C0012100101006E34010C0012100101007401010A000B01000A001001000A001501000A001A45000F00103D00140015350019001A2D001E001F10010104550201050F001701000F00170105060F00170301070F001F3C00100015440019001E014C0910001501540A100016015C0B1000160201050F001701000F0017010D060F00170301070F001F64001000156C0019001E017409100015017C0A1000160201050F001701000F00170115060F00170301070F001F8401001000158C010019001E019401091000150201050F001701000F0017011D060F00170301070F001F9C0100100015A4010019001E0201050F001701000F00170125060F0017 - Name: '__llvm_covfun (1)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - CovFun: - - FuncName: _Z5func2ii - FuncHash: 0xC465B88D2C9E9B03 - FilenamesRef: 0x5D8FCE3E3196E693 - Expressions: [] - Files: - - Index: 0 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 36, 26, 7, 2 ], Ref: 0 } - - { dLoc: [ 1, 14, 0, 20 ], Expansion: 1 } - - { dLoc: [ 0, 24, 0, 29 ], Expansion: 2 } - - { dLoc: [ 1, 1, 3, 108 ], ExtTag: Skip } - - Index: 1 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 11, 16, 0, 22 ], Expansion: 3 } - - Index: 2 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 8, 15, 0, 38 ], Ref: 1 } - - { dLoc: [ 0, 16, 0, 21 ], Expansion: 4 } - - { dLoc: [ 0, 24, 0, 29 ], Expansion: 5 } - - { dLoc: [ 0, 32, 0, 37 ], Expansion: 6 } - - Index: 3 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 10, 16, 0, 22 ], Expansion: 7 } - - Index: 4 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 7, 15, 0, 31 ], Ref: 1 } - - { dLoc: [ 0, 16, 0, 21 ], Expansion: 8 } - - { dLoc: [ 0, 25, 0, 30 ], Expansion: 9 } - - Index: 5 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 6, 15, 0, 23 ], Ref: 6 } - - Index: 6 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 5, 15, 0, 23 ], Ref: 7 } - - Index: 7 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 9, 16, 0, 21 ], Expansion: 10 } - - Index: 8 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 5, 15, 0, 23 ], Ref: 1 } - - { dLoc: [ 0, 15, 0, 23 ], Ref: 1 } - - Index: 9 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 6, 15, 0, 23 ], Ref: 8 } - - Index: 10 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 7, 15, 0, 31 ], Ref: 0 } - - { dLoc: [ 0, 15, 0, 31 ], Ref: 0 } - - { dLoc: [ 0, 16, 0, 21 ], Expansion: 11 } - - { dLoc: [ 0, 25, 0, 30 ], Expansion: 12 } - - Index: 11 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 5, 15, 0, 23 ], Ref: 0 } - - { dLoc: [ 0, 15, 0, 23 ], Ref: 0 } - - Index: 12 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 6, 15, 0, 23 ], Ref: 3 } + Content: B01D983FC67363959E000000039B9E2C8DB865C493E696313ECE8F5D0D01010101010101010101010101000401241A07020C010E0014140018001D1001010365011C0B1000160405080F002624001000152C0018001D3400200025013C0A1000160305070F001F44001000154C0019001E0119060F0017011D050F00170154091000150205050F001705000F00170121060F00170401070F001F01000F001F5C00100015640019001E0201050F001701000F0017010D060F0017 - Name: '__llvm_covfun (2)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - CovFun: - - FuncName: main - FuncHash: 0x18 - FilenamesRef: 0x5D8FCE3E3196E693 - Expressions: [] - Files: - - Index: 0 - Filename: branch-macros.cpp - Regions: - - { dLoc: [ 47, 1, 5, 2 ], Ref: 0 } + Content: FAD58DE7366495DB09000000180000000000000093E696313ECE8F5D01010001012F010502 - Name: __llvm_covmap Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - CovMap: - - FilenamesRef: 0x5D8FCE3E3196E693 - Version: 6 + Content: 0000000016000000000000000600000002130000116272616E63682D6D6163726F732E6370700000 - Name: __llvm_prf_names Type: SHT_PROGBITS Flags: [ SHF_ALLOC, SHF_GNU_RETAIN ] AddressAlign: 0x1 - PrfNames: - - - _Z4funcii - - _Z5func2ii - - main + Content: 19005F5A3466756E636969015F5A3566756E63326969016D61696E - Type: SectionHeaderTable Sections: - Name: .strtab @@ -246,4 +40,30 @@ Sections: - Name: '__llvm_covfun (2)' - Name: __llvm_covmap - Name: __llvm_prf_names + - Name: .symtab +Symbols: + - Name: __llvm_covmap + Type: STT_SECTION + Section: __llvm_covmap + - Name: __llvm_prf_names + Type: STT_SECTION + Section: __llvm_prf_names + - Name: __covrec_B30B5C302CEDA0F0u + Type: STT_OBJECT + Section: __llvm_covfun + Binding: STB_WEAK + Size: 0x15B + Other: [ STV_HIDDEN ] + - Name: __covrec_956373C63F981DB0u + Type: STT_OBJECT + Section: '__llvm_covfun (1)' + Binding: STB_WEAK + Size: 0xBA + Other: [ STV_HIDDEN ] + - Name: __covrec_DB956436E78DD5FAu + Type: STT_OBJECT + Section: '__llvm_covfun (2)' + Binding: STB_WEAK + Size: 0x25 + Other: [ STV_HIDDEN ] ... diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-templates-single.yaml b/llvm/test/tools/llvm-cov/Inputs/branch-templates-single.yaml index 03e918953cdc9..d4ede6db448e6 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-templates-single.yaml +++ b/llvm/test/tools/llvm-cov/Inputs/branch-templates-single.yaml @@ -11,107 +11,32 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - CovFun: - - FuncName: main - FuncHash: 0x29244A491292458 - FilenamesRef: 0x6BBCABDA409AED26 - Expressions: [] - Files: - - Index: 0 - Filename: branch-templates.cpp - Regions: - - { dLoc: [ 29, 12, 9, 2 ], Ref: 0 } - - { dLoc: [ 1, 7, 0, 19 ], Ref: 0 } - - { dLoc: [ 0, 20, 1, 5 ], isGap: true, Ref: 1 } - - { dLoc: [ 1, 5, 0, 22 ], Ref: 1 } - - { dLoc: [ 1, 3, 6, 2 ], Ref: 2 } - - { dLoc: [ 0, 7, 0, 23 ], Ref: 2 } - - { dLoc: [ 0, 24, 1, 5 ], isGap: true, Ref: 3 } - - { dLoc: [ 1, 5, 0, 22 ], Ref: 3 } - - { dLoc: [ 1, 3, 4, 2 ], Ref: 4 } - - { dLoc: [ 0, 7, 0, 23 ], Ref: 4 } - - { dLoc: [ 0, 24, 1, 5 ], isGap: true, Ref: 5 } - - { dLoc: [ 1, 5, 0, 22 ], Ref: 5 } - - { dLoc: [ 1, 3, 1, 11 ], Ref: 6 } + Content: FAD58DE7366495DB5100000058242991A444920226ED9A40DAABBC6B0101000D011D0C090201010700130500140185808080080501050016090103060209000700170D00180185808080080D01050016110103040211000700171500180185808080081501050016190103010B - Name: '__llvm_covfun (1)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - CovFun: - - FuncName: _Z4funcIiEiT_ - FuncHash: 0x292613611 - FilenamesRef: 0x6BBCABDA409AED26 - Expressions: [] - Files: - - Index: 0 - Filename: branch-templates.cpp - Regions: - - { dLoc: [ 13, 15, 6, 2 ], Ref: 0 } - - { dLoc: [ 1, 6, 0, 7 ], Ref: 0 } - - { dLoc: [ 0, 8, 1, 5 ], isGap: true, Ref: 1 } - - { dLoc: [ 1, 5, 0, 13 ], Ref: 1 } - - { dLoc: [ 0, 14, 2, 5 ], isGap: true, Ref: 2 } - - { dLoc: [ 2, 5, 0, 13 ], Ref: 2 } - - { dLoc: [ 0, 14, 1, 3 ], isGap: true, Ref: 3 } - - { dLoc: [ 1, 3, 1, 2 ], Ref: 3 } + Content: 5427717259E0E43E38000000113661920200000026ED9A40DAABBC6B01010008010D0F06020101060007050008018580808008050105000D09000E028580808008090205000D0D000E0183808080080D01030102 - Name: '__llvm_covfun (2)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - CovFun: - - FuncName: _Z4funcIbEiT_ - FuncHash: 0x292613611 - FilenamesRef: 0x6BBCABDA409AED26 - Expressions: [] - Files: - - Index: 0 - Filename: branch-templates.cpp - Regions: - - { dLoc: [ 13, 15, 6, 2 ], Ref: 0 } - - { dLoc: [ 1, 6, 0, 7 ], Ref: 0 } - - { dLoc: [ 0, 8, 1, 5 ], isGap: true, Ref: 1 } - - { dLoc: [ 1, 5, 0, 13 ], Ref: 1 } - - { dLoc: [ 0, 14, 2, 5 ], isGap: true, Ref: 2 } - - { dLoc: [ 2, 5, 0, 13 ], Ref: 2 } - - { dLoc: [ 0, 14, 1, 3 ], isGap: true, Ref: 3 } - - { dLoc: [ 1, 3, 1, 2 ], Ref: 3 } + Content: 4B7E22082F0551AA38000000113661920200000026ED9A40DAABBC6B01010008010D0F06020101060007050008018580808008050105000D09000E028580808008090205000D0D000E0183808080080D01030102 - Name: '__llvm_covfun (3)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - CovFun: - - FuncName: _Z4funcIfEiT_ - FuncHash: 0x292613611 - FilenamesRef: 0x6BBCABDA409AED26 - Expressions: [] - Files: - - Index: 0 - Filename: branch-templates.cpp - Regions: - - { dLoc: [ 13, 15, 6, 2 ], Ref: 0 } - - { dLoc: [ 1, 6, 0, 7 ], Ref: 0 } - - { dLoc: [ 0, 8, 1, 5 ], isGap: true, Ref: 1 } - - { dLoc: [ 1, 5, 0, 13 ], Ref: 1 } - - { dLoc: [ 0, 14, 2, 5 ], isGap: true, Ref: 2 } - - { dLoc: [ 2, 5, 0, 13 ], Ref: 2 } - - { dLoc: [ 0, 14, 1, 3 ], isGap: true, Ref: 3 } - - { dLoc: [ 1, 3, 1, 2 ], Ref: 3 } + Content: AC1440BC3DA3E41A38000000113661920200000026ED9A40DAABBC6B01010008010D0F06020101060007050008018580808008050105000D09000E028580808008090205000D0D000E0183808080080D01030102 - Name: __llvm_covmap Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - CovMap: - - FilenamesRef: 0x6BBCABDA409AED26 - Version: 6 + Content: 0000000019000000000000000600000002160000146272616E63682D74656D706C617465732E637070000000 - Name: __llvm_prf_names Type: SHT_PROGBITS Flags: [ SHF_ALLOC, SHF_GNU_RETAIN ] AddressAlign: 0x1 - PrfNames: - - - main - - _Z4funcIiEiT_ - - _Z4funcIbEiT_ - - _Z4funcIfEiT_ + Content: 2E006D61696E015F5A3466756E6349694569545F015F5A3466756E6349624569545F015F5A3466756E6349664569545F - Type: SectionHeaderTable Sections: - Name: .strtab @@ -121,4 +46,36 @@ Sections: - Name: '__llvm_covfun (3)' - Name: __llvm_covmap - Name: __llvm_prf_names + - Name: .symtab +Symbols: + - Name: __llvm_covmap + Type: STT_SECTION + Section: __llvm_covmap + - Name: __llvm_prf_names + Type: STT_SECTION + Section: __llvm_prf_names + - Name: __covrec_DB956436E78DD5FAu + Type: STT_OBJECT + Section: __llvm_covfun + Binding: STB_WEAK + Size: 0x6D + Other: [ STV_HIDDEN ] + - Name: __covrec_3EE4E05972712754u + Type: STT_OBJECT + Section: '__llvm_covfun (1)' + Binding: STB_WEAK + Size: 0x54 + Other: [ STV_HIDDEN ] + - Name: __covrec_AA51052F08227E4Bu + Type: STT_OBJECT + Section: '__llvm_covfun (2)' + Binding: STB_WEAK + Size: 0x54 + Other: [ STV_HIDDEN ] + - Name: __covrec_1AE4A33DBC4014ACu + Type: STT_OBJECT + Section: '__llvm_covfun (3)' + Binding: STB_WEAK + Size: 0x54 + Other: [ STV_HIDDEN ] ... diff --git a/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.yaml b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.yaml index cd82f4437ae55..84b184023f082 100644 --- a/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.yaml +++ b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.yaml @@ -11,58 +11,35 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - CovFun: - - FuncName: main - FuncHash: 0xD37EF842EADB3367 - FilenamesRef: 0x9D50F31F950B0EC6 - Expressions: [] - Files: - - Index: 0 - Filename: showLineExecutionCounts.cpp - Regions: - - { dLoc: [ 6, 12, 19, 2 ], Ref: 0 } - - { dLoc: [ 2, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 7, 0, 8 ], Ref: 0 } - - { dLoc: [ 0, 9, 0, 10 ], isGap: true, Ref: 1 } - - { dLoc: [ 0, 10, 2, 4 ], Ref: 1 } - - { dLoc: [ 2, 4, 0, 10 ], isGap: true, Ref: 2 } - - { dLoc: [ 0, 10, 2, 4 ], Ref: 2 } - - { dLoc: [ 3, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 3, 10, 2 ], Ref: 3 } - - { dLoc: [ 0, 19, 0, 26 ], Ref: 4 } - - { dLoc: [ 0, 28, 0, 31 ], Ref: 5 } - - { dLoc: [ 0, 32, 0, 33 ], isGap: true, Ref: 6 } - - { dLoc: [ 0, 33, 2, 4 ], Ref: 6 } - - { dLoc: [ 3, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 3, 6, 2 ], Ref: 7 } - - { dLoc: [ 0, 7, 0, 13 ], Ref: 7 } - - { dLoc: [ 0, 15, 0, 16 ], isGap: true, Ref: 9 } - - { dLoc: [ 0, 16, 0, 21 ], Ref: 9 } - - { dLoc: [ 0, 24, 0, 29 ], Ref: 10 } - - { dLoc: [ 1, 3, 5, 2 ], Ref: 8 } - - { dLoc: [ 0, 7, 0, 13 ], Ref: 8 } - - { dLoc: [ 0, 15, 1, 9 ], isGap: true, Ref: 12 } - - { dLoc: [ 1, 9, 0, 14 ], Ref: 12 } - - { dLoc: [ 1, 9, 0, 14 ], Ref: 13 } - - { dLoc: [ 1, 1, 0, 1 ], ExtTag: Skip } - - { dLoc: [ 1, 3, 0, 11 ], Ref: 11 } + Content: FAD58DE7366495DB9A0000006733DBEA42F87ED3C60E0B951FF3509D0101001A01060C130210020100010101070008050009008A8080800805000A0204090204008A8080800809000A020410030100010D01030A02110013001A15001C001F19002000A180808008190021020410030100011D010306021D0007000D25000F0090808080082500100015290018001D2101030502210007000D31000F018980808008310109000E350109000E10010100012D0103000B - Name: __llvm_covmap Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - CovMap: - - FilenamesRef: 0x9D50F31F950B0EC6 - Version: 6 + Content: 00000000200000000000000006000000021D00001B73686F774C696E65457865637574696F6E436F756E74732E637070 - Name: __llvm_prf_names Type: SHT_PROGBITS Flags: [ SHF_ALLOC, SHF_GNU_RETAIN ] AddressAlign: 0x1 - PrfNames: - - - main + Content: 04006D61696E - Type: SectionHeaderTable Sections: - Name: .strtab - Name: __llvm_covfun - Name: __llvm_covmap - Name: __llvm_prf_names + - Name: .symtab +Symbols: + - Name: __llvm_covmap + Type: STT_SECTION + Section: __llvm_covmap + - Name: __llvm_prf_names + Type: STT_SECTION + Section: __llvm_prf_names + - Name: __covrec_DB956436E78DD5FAu + Type: STT_OBJECT + Section: __llvm_covfun + Binding: STB_WEAK + Size: 0xB6 + Other: [ STV_HIDDEN ] ... diff --git a/llvm/test/tools/llvm-cov/Inputs/yaml.makefile b/llvm/test/tools/llvm-cov/Inputs/yaml.makefile index 449542cee5477..2a256f0cffc0b 100644 --- a/llvm/test/tools/llvm-cov/Inputs/yaml.makefile +++ b/llvm/test/tools/llvm-cov/Inputs/yaml.makefile @@ -2,7 +2,7 @@ # # Usage: # cd /path/to/llvm-project/llvm/test/tools/llvm-cov/Inputs -# PATH=/path/to/build/bin:$PATH make -f yaml.makefile *.yaml +# PATH=/path/to/build/bin:$PATH make -f yaml.makefile CFLAGS_COVMAP = -fcoverage-compilation-dir=. \ -mllvm -runtime-counter-relocation=true \ @@ -34,11 +34,11 @@ CFLAGS_MCDC = -fcoverage-mcdc --only-section=__llvm_covfun \ --only-section=__llvm_covmap \ --only-section=__llvm_prf_names \ - --strip-all \ + --strip-unneeded \ $< $@ %.yaml: %.covmap.o - obj2yaml --covmap --covmap-dloc $< > $@ + obj2yaml $< > $@ %.exe: %.o clang++ -fprofile-instr-generate $^ -o $@ diff --git a/llvm/test/tools/obj2yaml/ELF/covmap-be.yaml b/llvm/test/tools/obj2yaml/ELF/covmap-be.yaml index ec1352b40a9cc..b97782153192b 100644 --- a/llvm/test/tools/obj2yaml/ELF/covmap-be.yaml +++ b/llvm/test/tools/obj2yaml/ELF/covmap-be.yaml @@ -1,15 +1,6 @@ # RUN: yaml2obj %s -o %t.o # RUN: obj2yaml %t.o > %t.plain.yaml -# RUN: obj2yaml --covmap-raw %t.o > %t.raw.yaml -# RUN: obj2yaml --covmap --covmap-raw %t.o > %t.mixed.yaml -# RUN: obj2yaml --covmap --covmap-dloc %t.o > %t.dloc.yaml -# RUN: obj2yaml --covmap %t.o > %t.covmap.yaml -# RUN: sed -E '/^(#.*)?$/d' %s | diff %t.covmap.yaml - # RUN: yaml2obj %t.plain.yaml -o - | cmp %t.o - -# RUN: yaml2obj %t.raw.yaml -o - | cmp %t.o - -# RUN: yaml2obj %t.mixed.yaml -o - | cmp %t.o - -# RUN: yaml2obj %t.dloc.yaml -o - | cmp %t.o - -# RUN: yaml2obj %t.covmap.yaml -o - | cmp %t.o - # FIXME: This is synthetically created. s/ELFDATA2LSB/ELF2DATAMSB/ s/EM_X86_64/EM_PPC64/ --- !ELF diff --git a/llvm/test/tools/obj2yaml/ELF/covmap.yaml b/llvm/test/tools/obj2yaml/ELF/covmap.yaml index fc77a3d02f909..9ec8987c6f93d 100644 --- a/llvm/test/tools/obj2yaml/ELF/covmap.yaml +++ b/llvm/test/tools/obj2yaml/ELF/covmap.yaml @@ -1,15 +1,6 @@ # RUN: yaml2obj %s -o %t.o # RUN: obj2yaml %t.o | tee %t.plain.yaml | FileCheck %s --check-prefixes=CHECK,PLAIN -# RUN: obj2yaml --covmap-raw %t.o | tee %t.raw.yaml | FileCheck %s --check-prefixes=CHECK,COVMAP,RAWONLY,RAW,DLOC -# RUN: obj2yaml --covmap --covmap-raw %t.o | tee %t.mixed.yaml | FileCheck %s --check-prefixes=CHECK,COVMAP,RAW,DET,LOC,DLOC -# RUN: obj2yaml --covmap --covmap-dloc %t.o | tee %t.dloc.yaml | FileCheck %s --check-prefixes=CHECK,COVMAP,DET,DETONLY,DLOC -# RUN: obj2yaml --covmap %t.o | tee %t.covmap.yaml | FileCheck %s --check-prefixes=CHECK,COVMAP,DET,DETONLY,LOC -# RUN: sed -E '/^(#.*)?$/d' %s | diff %t.covmap.yaml - # RUN: yaml2obj %t.plain.yaml -o - | cmp %t.o - -# RUN: yaml2obj %t.raw.yaml -o - | cmp %t.o - -# RUN: yaml2obj %t.mixed.yaml -o - | cmp %t.o - -# RUN: yaml2obj %t.dloc.yaml -o - | cmp %t.o - -# RUN: yaml2obj %t.covmap.yaml -o - | cmp %t.o - --- !ELF FileHeader: diff --git a/llvm/test/tools/obj2yaml/help.test b/llvm/test/tools/obj2yaml/help.test index 4f85a255f904d..72e8e75b7d158 100644 --- a/llvm/test/tools/obj2yaml/help.test +++ b/llvm/test/tools/obj2yaml/help.test @@ -7,6 +7,5 @@ # CHECK: OVERVIEW: Dump a YAML description from an object file # CHECK: USAGE: obj2yaml{{(.exe)?}} [options] {{$}} # CHECK: OPTIONS: -# CATEG: ELF Options: # CATEG: Generic Options: # CATEG: obj2yaml Options: diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp index 1bb298fee9d82..b1c8032ea2192 100644 --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -11,10 +11,8 @@ #include "llvm/ADT/Twine.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/Object/ELFObjectFile.h" -#include "llvm/ObjectYAML/CovMap.h" #include "llvm/ObjectYAML/DWARFYAML.h" #include "llvm/ObjectYAML/ELFYAML.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Support/DataExtractor.h" #include "llvm/Support/Errc.h" #include "llvm/Support/ErrorHandling.h" @@ -23,18 +21,6 @@ using namespace llvm; -cl::OptionCategory ELFCat("ELF Options"); - -static cl::opt - CovMapDetailed("covmap", cl::desc("Dump detailed YAML in Coverage Map."), - cl::cat(ELFCat)); -static cl::opt CovMapRaw("covmap-raw", - cl::desc("Dump raw YAML in Coverage Map."), - cl::cat(ELFCat)); -static cl::opt CovMapDLoc("covmap-dloc", - cl::desc("Prefer dLoc over absolute Loc."), - cl::cat(ELFCat)); - namespace { template @@ -111,8 +97,6 @@ class ELFDumper { dumpStackSizesSection(const Elf_Shdr *Shdr); Expected dumpBBAddrMapSection(const Elf_Shdr *Shdr); - Expected dumpCovMap(const Elf_Shdr *Shdr, StringRef Name, - covmap::Decoder *CovMapDecoder); Expected dumpPlaceholderSection(const Elf_Shdr *Shdr); @@ -596,31 +580,6 @@ ELFDumper::dumpSections() { return Error::success(); }; - coverage::yaml::DecoderParam Param; - Param.Detailed = CovMapDetailed; - Param.Raw = CovMapRaw; - Param.dLoc = CovMapDLoc; - auto CovMapDecoder = covmap::Decoder::get(ELFT::Endianness, Param); - if (covmap::Decoder::enabled) { - // Look up covmap-related sections. - for (const auto &Sec : Sections) { - if (Sec.sh_type != ELF::SHT_PROGBITS) - continue; - - auto NameOrErr = Obj.getSectionName(Sec); - if (!NameOrErr) - return NameOrErr.takeError(); - - if (auto E = CovMapDecoder->acquire( - Sec.sh_offset, Sec.sh_addralign, *NameOrErr, - [&] { return Obj.getSectionContents(Sec); })) - return std::move(E); - } - - if (auto E = CovMapDecoder->fixup()) - return std::move(E); - } - auto GetDumper = [this](unsigned Type) -> std::function(const Elf_Shdr *)> { if (Obj.getHeader().e_machine == ELF::EM_ARM && Type == ELF::SHT_ARM_EXIDX) @@ -702,10 +661,6 @@ ELFDumper::dumpSections() { if (Error E = Add(dumpStackSizesSection(&Sec))) return std::move(E); continue; - } else if (covmap::Decoder::enabled && covmap::nameMatches(*NameOrErr)) { - if (Error E = Add(dumpCovMap(&Sec, *NameOrErr, CovMapDecoder.get()))) - return std::move(E); - continue; } } @@ -1707,15 +1662,6 @@ ELFDumper::dumpMipsABIFlags(const Elf_Shdr *Shdr) { return S.release(); } -template -Expected -ELFDumper::dumpCovMap(const Elf_Shdr *Shdr, StringRef Name, - covmap::Decoder *CovMapDecoder) { - return CovMapDecoder->make(Shdr->sh_offset, Name, [&](ELFYAML::Section &S) { - return dumpCommonSection(Shdr, S); - }); -} - template static Error elf2yaml(raw_ostream &Out, const object::ELFFile &Obj, std::unique_ptr DWARFCtx) { @@ -1725,8 +1671,7 @@ static Error elf2yaml(raw_ostream &Out, const object::ELFFile &Obj, return YAMLOrErr.takeError(); std::unique_ptr YAML(YAMLOrErr.get()); - yaml::Output Yout(Out, nullptr, /*WrapColumn*/ - (covmap::Decoder::enabled ? 160 : 70)); + yaml::Output Yout(Out); Yout << *YAML; return Error::success(); diff --git a/llvm/tools/obj2yaml/obj2yaml.cpp b/llvm/tools/obj2yaml/obj2yaml.cpp index ecc9f7eed49ff..63c8cc55ee2d4 100644 --- a/llvm/tools/obj2yaml/obj2yaml.cpp +++ b/llvm/tools/obj2yaml/obj2yaml.cpp @@ -101,7 +101,7 @@ static void reportError(StringRef Input, Error Err) { int main(int argc, char *argv[]) { InitLLVM X(argc, argv); - cl::HideUnrelatedOptions({&Cat, &ELFCat}); + cl::HideUnrelatedOptions(Cat); cl::ParseCommandLineOptions( argc, argv, "Dump a YAML description from an object file", nullptr, nullptr, /*LongOptionsUseDoubleDash=*/true); diff --git a/llvm/tools/obj2yaml/obj2yaml.h b/llvm/tools/obj2yaml/obj2yaml.h index 8a10be085eefc..03d7db5317acd 100644 --- a/llvm/tools/obj2yaml/obj2yaml.h +++ b/llvm/tools/obj2yaml/obj2yaml.h @@ -16,15 +16,11 @@ #include "llvm/Object/Minidump.h" #include "llvm/Object/Wasm.h" #include "llvm/Object/XCOFFObjectFile.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Support/MemoryBufferRef.h" #include "llvm/Support/raw_ostream.h" #include enum RawSegments : unsigned { none = 0, data = 1, linkedit = 1 << 1 }; - -extern llvm::cl::OptionCategory ELFCat; - std::error_code coff2yaml(llvm::raw_ostream &Out, const llvm::object::COFFObjectFile &Obj); llvm::Error elf2yaml(llvm::raw_ostream &Out, From d4dcaa8c2b9b51b4e8c08811de5f828db6bd66a3 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Fri, 7 Mar 2025 12:26:07 +0900 Subject: [PATCH 09/10] encraw --- llvm/include/llvm/ObjectYAML/CovMap.h | 78 +------ llvm/lib/ObjectYAML/CovMap.cpp | 217 ++------------------ llvm/lib/ObjectYAML/ELFEmitter.cpp | 7 - llvm/test/tools/obj2yaml/ELF/covmap-be.yaml | 76 +++---- llvm/test/tools/obj2yaml/ELF/covmap.yaml | 123 ++++------- 5 files changed, 107 insertions(+), 394 deletions(-) diff --git a/llvm/include/llvm/ObjectYAML/CovMap.h b/llvm/include/llvm/ObjectYAML/CovMap.h index 3a0b86435d490..cb2953eb27f7e 100644 --- a/llvm/include/llvm/ObjectYAML/CovMap.h +++ b/llvm/include/llvm/ObjectYAML/CovMap.h @@ -23,7 +23,6 @@ #ifndef LLVM_OBJECTYAML_COVMAP_H #define LLVM_OBJECTYAML_COVMAP_H -#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" #include "llvm/ObjectYAML/ELFYAML.h" #include "llvm/Support/Endian.h" @@ -33,6 +32,7 @@ #include #include #include +#include #include namespace llvm { @@ -50,16 +50,8 @@ struct CounterTy { Add, }; - /// Optional in detailed view, since most Tag can be determined from - /// other optional fields. - std::optional Tag; - - /// Internal use. - std::optional Val; - - std::optional RefOpt; - std::optional SubOpt; - std::optional AddOpt; + TagTy Tag; + uint64_t Val; virtual ~CounterTy() {} @@ -113,8 +105,7 @@ struct RecTy : CounterTy { /// Stored in ColumnEnd:31. std::optional isGap; - std::optional Loc; ///< Absolute line numbers. - std::optional dLoc; ///< Differential line numbers. + LocTy dLoc; ///< Differential line numbers. void mapping(llvm::yaml::IO &IO) override; @@ -123,8 +114,6 @@ struct RecTy : CounterTy { /// {NumRecs, Recs...} struct FileRecsTy { - std::optional Index; ///< Shown in detailed view. - std::optional Filename; ///< Resolved by FileIDs. std::vector Recs; void mapping(llvm::yaml::IO &IO); @@ -132,11 +121,10 @@ struct FileRecsTy { /// An element of CovFun array. struct CovFunTy { - std::optional NameRef; ///< Hash value of the symbol. - std::optional FuncName; ///< Resolved by symtab. - llvm::yaml::Hex64 FuncHash; ///< Signature of this function. - llvm::yaml::Hex64 FilenamesRef; ///< Pointer to CovMap - std::optional> FileIDs; ///< Resolved by CovMap + llvm::yaml::Hex64 NameRef; ///< Hash value of the symbol. + llvm::yaml::Hex64 FuncHash; ///< Signature of this function. + llvm::yaml::Hex64 FilenamesRef; ///< Pointer to CovMap + std::vector FileIDs; ///< Resolved by CovMap std::vector Expressions; std::vector Files; ///< 2-dimension array of Recs. @@ -151,39 +139,15 @@ struct CovMapTy { /// format. Calculate and store with Filenames. llvm::yaml::Hex64 FilenamesRef; - std::optional Version; + uint32_t Version; /// Raw Filenames (and storage of Files) - std::optional> Filenames; - - /// Since Version5: Filenames[0] is the working directory (or - /// zero-length string). Note that indices in CovFun::FileIDs is - /// base on Filenames. (Then, +0, as WD, is not expected to appear) - std::optional WD; - /// This may be ArrayRef in Decoder since Filenames has been - /// filled. On the other hand in Encoder, this should be a vector - /// since YAML parser doesn't endorse references. - std::optional> Files; + std::vector Filenames; void mapping(llvm::yaml::IO &IO); - bool useWD() const { return (!Version || *Version >= 4); } - StringRef getWD() const { return (WD ? *WD : StringRef()); } - - /// Generate Accumulated list with WD. - /// Returns a single element {WD} if AccFiles is not given. - std::vector - generateAccFilenames(const std::optional> &AccFilesOpt = - std::nullopt) const; - /// Regenerate Filenames with WD. - /// Use Files if it is not None. Or given AccFiles is used. - void - regenerateFilenames(const std::optional> &AccFilesOpt); - /// Encode Filenames. This is mostly used just to obtain FilenamesRef. - std::pair encodeFilenames( - const std::optional> &AccFilesOpt = std::nullopt, - bool Compress = false) const; + std::pair encodeFilenames(bool Compress = false) const; void encode(raw_ostream &OS, endianness Endianness) const; }; @@ -236,26 +200,6 @@ LLVM_COVERAGE_YAML_ELEM_MAPPING(CovMapTy) namespace llvm::covmap { -class Encoder { -protected: - endianness Endianness; - -public: - Encoder(endianness Endianness) : Endianness(Endianness) {} - virtual ~Encoder() {} - - /// Returns EncoderImpl. - static std::unique_ptr get(endianness Endianness); - - /// Called from the Sections loop. - virtual void collect(ELFYAML::Chunk *Chunk) = 0; - - /// Resolves names from CovFuns in advance of Emitter. It'd be too - /// late to resolve sections in Emitter since they are immutable - /// then. - virtual void fixup() = 0; -}; - /// Returns whether Name is interested. bool nameMatches(StringRef Name); diff --git a/llvm/lib/ObjectYAML/CovMap.cpp b/llvm/lib/ObjectYAML/CovMap.cpp index 7662284caee76..643caaf5df3d9 100644 --- a/llvm/lib/ObjectYAML/CovMap.cpp +++ b/llvm/lib/ObjectYAML/CovMap.cpp @@ -11,8 +11,6 @@ //===----------------------------------------------------------------------===// #include "llvm/ObjectYAML/CovMap.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ObjectYAML/ELFYAML.h" #include "llvm/ProfileData/Coverage/CoverageMappingWriter.h" @@ -20,13 +18,10 @@ #include "llvm/Support/Alignment.h" #include "llvm/Support/Endian.h" #include "llvm/Support/LEB128.h" -#include "llvm/Support/MD5.h" #include "llvm/Support/YAMLTraits.h" #include "llvm/Support/raw_ostream.h" -#include #include #include -#include #include #include #include @@ -38,21 +33,7 @@ using namespace llvm::coverage::yaml; using namespace llvm::covmap; void CounterTy::encode(raw_ostream &OS) const { - std::pair C; - if (RefOpt) - C = {Ref, *RefOpt}; - else if (SubOpt) - C = {Sub, *SubOpt}; - else if (AddOpt) - C = {Add, *AddOpt}; - else if (Tag && *Tag == Zero) - C = {Zero, 0u}; - else if (Tag && Val) - C = {*Tag, *Val}; - else - llvm_unreachable("Null value cannot be met"); - - encodeULEB128(C.first | (C.second << 2), OS); + encodeULEB128(Tag | (Val << 2), OS); } void DecisionTy::encode(raw_ostream &OS) const { @@ -90,18 +71,10 @@ void RecTy::encode(uint64_t &StartLoc, raw_ostream &OS) const { assert((!isGap || *isGap) && "Don't set isGap=false"); uint32_t Gap = (isGap ? (1u << 31) : 0u); - if (Loc) { - encodeULEB128((*Loc)[0] - StartLoc, OS); - encodeULEB128((*Loc)[1], OS); - encodeULEB128((*Loc)[2] - (*Loc)[0], OS); - encodeULEB128((*Loc)[3] | Gap, OS); - StartLoc = (*Loc)[0]; - } else { - encodeULEB128((*dLoc)[0], OS); - encodeULEB128((*dLoc)[1], OS); - encodeULEB128((*dLoc)[2], OS); - encodeULEB128((*dLoc)[3] | Gap, OS); - } + encodeULEB128(dLoc[0], OS); + encodeULEB128(dLoc[1], OS); + encodeULEB128(dLoc[2], OS); + encodeULEB128(dLoc[3] | Gap, OS); } void CovFunTy::encode(raw_ostream &OS, endianness Endianness) const { @@ -109,9 +82,8 @@ void CovFunTy::encode(raw_ostream &OS, endianness Endianness) const { std::string Body; raw_string_ostream SS(Body); - assert(FileIDs); - encodeULEB128(FileIDs->size(), SS); - for (auto I : *FileIDs) + encodeULEB128(FileIDs.size(), SS); + for (auto I : FileIDs) encodeULEB128(I, SS); encodeULEB128(Expressions.size(), SS); @@ -128,12 +100,11 @@ void CovFunTy::encode(raw_ostream &OS, endianness Endianness) const { } // Emit the Header - uint64_t NameRef = (this->NameRef ? static_cast(*this->NameRef) - : MD5Hash(*this->FuncName)); + uint64_t NameRef = this->NameRef; uint32_t DataSize = Body.size(); - /* this->FuncHash */ + uint64_t FuncHash = this->FuncHash; char CoverageMapping = 0; // dummy - /* this->FilenamesRef */ + uint64_t FilenamesRef = this->FilenamesRef; #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Initializer) \ if (sizeof(Name) > 1) { \ @@ -146,50 +117,11 @@ void CovFunTy::encode(raw_ostream &OS, endianness Endianness) const { OS << std::move(Body); } -std::vector CovMapTy::generateAccFilenames( - const std::optional> &AccFilesOpt) const { - std::vector Result; - if (useWD()) - Result.push_back(getWD().str()); - // Returns {WD} if AccFiles is None. - if (AccFilesOpt) { - for (auto &Filename : *AccFilesOpt) - Result.push_back(Filename.str()); - } - return Result; -} - -void CovMapTy::regenerateFilenames( - const std::optional> &AccFilesOpt) { - assert(!this->Filenames); - if (this->Files) { - auto &CovMapFilenames = this->Filenames.emplace(generateAccFilenames()); - assert(CovMapFilenames.size() <= 1); - for (auto &&File : *this->Files) - CovMapFilenames.push_back(std::move(File)); - } else { - // Encode Accfiles, that comes from CovFun. - this->Filenames = generateAccFilenames(AccFilesOpt); - } -} - std::pair -CovMapTy::encodeFilenames(const std::optional> &AccFilesOpt, - bool Compress) const { - ArrayRef TempFilenames; - std::vector AccFilenames; // Storage - - if (AccFilesOpt) { - AccFilenames = generateAccFilenames(AccFilesOpt); - TempFilenames = AccFilenames; - } else { - assert(this->Filenames); - TempFilenames = ArrayRef(*this->Filenames); - } - +CovMapTy::encodeFilenames(bool Compress) const { std::string FilenamesBlob; llvm::raw_string_ostream OS(FilenamesBlob); - CoverageFilenamesSectionWriter(TempFilenames).write(OS, Compress); + CoverageFilenamesSectionWriter(this->Filenames).write(OS, Compress); return {llvm::IndexedInstrProf::ComputeHash(FilenamesBlob), FilenamesBlob}; } @@ -200,8 +132,7 @@ void CovMapTy::encode(raw_ostream &OS, endianness Endianness) const { uint32_t NRecords = 0; uint32_t FilenamesSize = FilenamesBlob.size(); uint32_t CoverageSize = 0; - uint32_t Version = - (this->Version ? *this->Version : INSTR_PROF_COVMAP_VERSION); + uint32_t Version = this->Version; struct { #define COVMAP_HEADER(Type, LLVMType, Name, Initializer) Type Name; #include "llvm/ProfileData/InstrProfData.inc" @@ -220,11 +151,8 @@ void CovMapTy::encode(raw_ostream &OS, endianness Endianness) const { } void CounterTy::mapping(llvm::yaml::IO &IO) { - IO.mapOptional("Tag", Tag); - IO.mapOptional("Val", Val); - IO.mapOptional("Ref", RefOpt); - IO.mapOptional("Sub", SubOpt); - IO.mapOptional("Add", AddOpt); + IO.mapRequired("Tag", Tag); + IO.mapRequired("Val", Val); } void DecisionTy::mapping(llvm::yaml::IO &IO) { @@ -233,8 +161,7 @@ void DecisionTy::mapping(llvm::yaml::IO &IO) { } void RecTy::mapping(llvm::yaml::IO &IO) { - IO.mapOptional("Loc", Loc); - IO.mapOptional("dLoc", dLoc); + IO.mapRequired("dLoc", dLoc); IO.mapOptional("isGap", isGap); CounterTy::mapping(IO); IO.mapOptional("ExtTag", ExtTag); @@ -245,27 +172,22 @@ void RecTy::mapping(llvm::yaml::IO &IO) { } void FileRecsTy::mapping(llvm::yaml::IO &IO) { - IO.mapOptional("Index", Index); - IO.mapOptional("Filename", Filename); IO.mapRequired("Regions", Recs); } void CovFunTy::mapping(llvm::yaml::IO &IO) { - IO.mapOptional("NameRef", NameRef); - IO.mapOptional("FuncName", FuncName); + IO.mapRequired("NameRef", NameRef); IO.mapRequired("FuncHash", FuncHash); IO.mapRequired("FilenamesRef", FilenamesRef); - IO.mapOptional("FileIDs", FileIDs); + IO.mapRequired("FileIDs", FileIDs); IO.mapRequired("Expressions", Expressions); IO.mapRequired("Files", Files); } void CovMapTy::mapping(llvm::yaml::IO &IO) { IO.mapRequired("FilenamesRef", FilenamesRef); - IO.mapOptional("Version", Version); - IO.mapOptional("Filenames", Filenames); - IO.mapOptional("WD", WD); - IO.mapOptional("Files", Files); + IO.mapRequired("Version", Version); + IO.mapRequired("Filenames", Filenames); } #define ECase(N, X) IO.enumCase(Value, #X, N::X) @@ -364,107 +286,8 @@ struct CovFunSection : ELFYAML::CovMapSectionBase { return Error::success(); } }; - -class CovMapFilenamesResolver { - DenseMap> FilenamesByCovMap; - std::vector UnresolvedCovFuns; - -protected: - DenseMap CovMapByRef; - -public: - void collectCovMap(std::vector &CovMaps) { - for (auto &CovMap : CovMaps) - CovMapByRef[CovMap.FilenamesRef] = &CovMap; - } - - void collectCovFunFilenames(std::vector &CovFuns) { - for (auto &CovFun : CovFuns) { - auto &Filenames = FilenamesByCovMap[CovFun.FilenamesRef]; - for (const auto &File : CovFun.Files) { - if (!File.Filename) - goto skip; - Filenames.insert(*File.Filename); - } - UnresolvedCovFuns.push_back(&CovFun); - skip:; - } - } - - void encFixup() { - for (auto &[_, CovMap] : CovMapByRef) { - auto FilenamesI = FilenamesByCovMap.find(CovMap->FilenamesRef); - if (FilenamesI != FilenamesByCovMap.end()) { - // Check Filenames satisfies covfuns - DenseSet FilenamesSet; - if (CovMap->Files) { - for (const auto &Filename : *CovMap->Files) - FilenamesSet.insert(Filename); - } else if (CovMap->Filenames) { - for (const auto &Filename : *CovMap->Filenames) - FilenamesSet.insert(Filename); - } - - for (const auto &Filename : FilenamesI->second) { - if (!FilenamesSet.contains(Filename)) { - // If not, regenerate Filenames. - CovMap->Files.reset(); - CovMap->Filenames.reset(); - break; - } - } - } - - if (!CovMap->Filenames) { - // Regenerate. - // Use Files if exists. - // Use CovFuns (FilenamesI) otherwise. - assert(CovMap->Files || FilenamesI != FilenamesByCovMap.end()); - CovMap->regenerateFilenames( - CovMap->Files ? std::nullopt : FilenamesI->second.getArrayRef()); - } - auto [FilenamesRef, FilenamesBlob] = CovMap->encodeFilenames(); - assert(CovMap->FilenamesRef == FilenamesRef); - } - - // Fill FileIDs - for (auto *CovFun : UnresolvedCovFuns) { - assert(CovMapByRef[CovFun->FilenamesRef]); - assert(CovMapByRef[CovFun->FilenamesRef]->Filenames); - const auto &CovMapFilenames = - *CovMapByRef[CovFun->FilenamesRef]->Filenames; - auto &FileIDs = CovFun->FileIDs.emplace(); - for (const auto &File : CovFun->Files) { - auto I = std::find(CovMapFilenames.begin(), CovMapFilenames.end(), - File.Filename); - assert(I != CovMapFilenames.end()); - FileIDs.push_back(std::distance(CovMapFilenames.begin(), I)); - } - assert(CovFun->Files.size() == FileIDs.size()); - } - } -}; - -class EncoderImpl : public Encoder, CovMapFilenamesResolver { -public: - EncoderImpl(endianness Endianness) : Encoder(Endianness) {} - - void collect(ELFYAML::Chunk *Chunk) override { - if (auto S = dyn_cast(Chunk)) { - collectCovMap(S->CovMaps); - } else if (auto S = dyn_cast(Chunk)) { - collectCovFunFilenames(S->CovFuns); - } - } - - void fixup() override { encFixup(); } -}; } // namespace -std::unique_ptr Encoder::get(endianness Endianness) { - return std::make_unique(Endianness); -} - bool covmap::nameMatches(StringRef Name) { return (PrfNamesSection::nameMatches(Name) || CovMapSection::nameMatches(Name) || CovFunSection::nameMatches(Name)); diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp index d13ab60822a02..e55daa72b3cee 100644 --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -772,13 +772,6 @@ void ELFState::initSectionHeaders(std::vector &SHeaders, // valid SHN_UNDEF entry since SHT_NULL == 0. SHeaders.resize(Doc.getSections().size()); - auto CovMapEncoder = covmap::Encoder::get(ELFT::Endianness); - for (auto &Chunk : Doc.Chunks) { - if (isa(Chunk.get())) - CovMapEncoder->collect(Chunk.get()); - } - CovMapEncoder->fixup(); - for (const std::unique_ptr &D : Doc.Chunks) { if (ELFYAML::Fill *S = dyn_cast(D.get())) { S->Offset = alignToOffset(CBA, /*Align=*/1, S->Offset); diff --git a/llvm/test/tools/obj2yaml/ELF/covmap-be.yaml b/llvm/test/tools/obj2yaml/ELF/covmap-be.yaml index b97782153192b..465808442fb7c 100644 --- a/llvm/test/tools/obj2yaml/ELF/covmap-be.yaml +++ b/llvm/test/tools/obj2yaml/ELF/covmap-be.yaml @@ -17,48 +17,45 @@ Sections: Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 CovFun: - - FuncName: _Z4funci + - NameRef: 0xA72DB7A33048E6A3 FuncHash: 0xAFC772D567676299 FilenamesRef: 0x70DA2CAFD8CE198E + FileIDs: [ 1, 1 ] Expressions: - - [ { Ref: 0 }, { Ref: 1 } ] - - [ { Add: 0 }, { Ref: 2 } ] - - [ { Add: 0 }, { Ref: 2 } ] - - [ { Add: 0 }, { Ref: 2 } ] - - [ { Ref: 0 }, { Ref: 2 } ] - - [ { Ref: 0 }, { Ref: 2 } ] - - [ { Ref: 0 }, { Ref: 2 } ] - - [ { Add: 0 }, { Ref: 5 } ] + - [ { Tag: Ref, Val: 0 }, { Tag: Ref, Val: 1 } ] + - [ { Tag: Add, Val: 0 }, { Tag: Ref, Val: 2 } ] + - [ { Tag: Add, Val: 0 }, { Tag: Ref, Val: 2 } ] + - [ { Tag: Add, Val: 0 }, { Tag: Ref, Val: 2 } ] + - [ { Tag: Ref, Val: 0 }, { Tag: Ref, Val: 2 } ] + - [ { Tag: Ref, Val: 0 }, { Tag: Ref, Val: 2 } ] + - [ { Tag: Ref, Val: 0 }, { Tag: Ref, Val: 2 } ] + - [ { Tag: Add, Val: 0 }, { Tag: Ref, Val: 5 } ] Files: - - Index: 0 - Filename: func.cpp - Regions: - - { Loc: [ 3, 17, 14, 2 ], Ref: 0 } - - { Loc: [ 6, 6, 11, 4 ], Add: 0 } - - { Loc: [ 7, 9, 7, 13 ], Expansion: 1 } - - { Loc: [ 7, 23, 8, 7 ], isGap: true, Ref: 2 } - - { Loc: [ 8, 7, 8, 16 ], Ref: 2 } - - { Loc: [ 8, 17, 10, 5 ], isGap: true, Sub: 3 } - - { Loc: [ 9, 1, 9, 1 ], ExtTag: Skip } - - { Loc: [ 10, 5, 11, 4 ], Sub: 3 } - - { Loc: [ 11, 12, 11, 17 ], Sub: 3 } - - { Loc: [ 11, 12, 11, 17 ], Branch: [ { Ref: 1 }, { Sub: 6 } ] } - - { Loc: [ 11, 19, 12, 3 ], isGap: true, Sub: 6 } - - { Loc: [ 12, 3, 12, 11 ], Sub: 6 } - - { Loc: [ 12, 12, 13, 3 ], isGap: true, Tag: Zero } - - { Loc: [ 13, 3, 13, 12 ], Tag: Zero } - - Index: 1 - Filename: func.cpp - Regions: - - { Loc: [ 1, 17, 1, 41 ], Add: 0 } - - { Loc: [ 1, 18, 1, 32 ], Add: 0 } - - { Loc: [ 1, 18, 1, 40 ], Decision: { BIdx: 5, NCond: 3 } } - - { Loc: [ 1, 19, 1, 22 ], Add: 0 } - - { Loc: [ 1, 19, 1, 22 ], Branch: [ { Sub: 7 }, { Ref: 5 } ], MCDC: [ 1, 2, 3 ] } - - { Loc: [ 1, 26, 1, 31 ], Ref: 5 } - - { Loc: [ 1, 26, 1, 31 ], Branch: [ { Tag: Zero }, { Ref: 6 } ], MCDC: [ 3, 2, 0 ] } - - { Loc: [ 1, 36, 1, 40 ], Ref: 3 } - - { Loc: [ 1, 36, 1, 40 ], Branch: [ { Ref: 4 }, { Tag: Zero } ], MCDC: [ 2, 0, 0 ] } + - Regions: + - { dLoc: [ 3, 17, 11, 2 ], Tag: Ref, Val: 0 } + - { dLoc: [ 3, 6, 5, 4 ], Tag: Add, Val: 0 } + - { dLoc: [ 1, 9, 0, 13 ], Tag: Zero, Val: 3, Expansion: 1 } + - { dLoc: [ 0, 23, 1, 7 ], isGap: true, Tag: Ref, Val: 2 } + - { dLoc: [ 1, 7, 0, 16 ], Tag: Ref, Val: 2 } + - { dLoc: [ 0, 17, 2, 5 ], isGap: true, Tag: Sub, Val: 3 } + - { dLoc: [ 1, 1, 0, 1 ], Tag: Zero, Val: 4, ExtTag: Skip } + - { dLoc: [ 1, 5, 1, 4 ], Tag: Sub, Val: 3 } + - { dLoc: [ 1, 12, 0, 17 ], Tag: Sub, Val: 3 } + - { dLoc: [ 0, 12, 0, 17 ], Tag: Zero, Val: 8, ExtTag: Branch, Branch: [ { Tag: Ref, Val: 1 }, { Tag: Sub, Val: 6 } ] } + - { dLoc: [ 0, 19, 1, 3 ], isGap: true, Tag: Sub, Val: 6 } + - { dLoc: [ 1, 3, 0, 11 ], Tag: Sub, Val: 6 } + - { dLoc: [ 0, 12, 1, 3 ], isGap: true, Tag: Zero, Val: 0 } + - { dLoc: [ 1, 3, 0, 12 ], Tag: Zero, Val: 0 } + - Regions: + - { dLoc: [ 1, 17, 0, 41 ], Tag: Add, Val: 0 } + - { dLoc: [ 0, 18, 0, 32 ], Tag: Add, Val: 0 } + - { dLoc: [ 0, 18, 0, 40 ], Tag: Zero, Val: 10, ExtTag: Decision, Decision: { BIdx: 5, NCond: 3 } } + - { dLoc: [ 0, 19, 0, 22 ], Tag: Add, Val: 0 } + - { dLoc: [ 0, 19, 0, 22 ], Tag: Zero, Val: 12, ExtTag: MCDCBranch, Branch: [ { Tag: Sub, Val: 7 }, { Tag: Ref, Val: 5 } ], MCDC: [ 1, 2, 3 ] } + - { dLoc: [ 0, 26, 0, 31 ], Tag: Ref, Val: 5 } + - { dLoc: [ 0, 26, 0, 31 ], Tag: Zero, Val: 12, ExtTag: MCDCBranch, Branch: [ { Tag: Zero, Val: 0 }, { Tag: Ref, Val: 6 } ], MCDC: [ 3, 2, 0 ] } + - { dLoc: [ 0, 36, 0, 40 ], Tag: Ref, Val: 3 } + - { dLoc: [ 0, 36, 0, 40 ], Tag: Zero, Val: 12, ExtTag: MCDCBranch, Branch: [ { Tag: Ref, Val: 4 }, { Tag: Zero, Val: 0 } ], MCDC: [ 2, 0, 0 ] } - Name: __llvm_covmap Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] @@ -66,6 +63,9 @@ Sections: CovMap: - FilenamesRef: 0x70DA2CAFD8CE198E Version: 6 + Filenames: + - '' + - func.cpp - Name: __llvm_prf_names Type: SHT_PROGBITS Flags: [ SHF_ALLOC, SHF_GNU_RETAIN ] diff --git a/llvm/test/tools/obj2yaml/ELF/covmap.yaml b/llvm/test/tools/obj2yaml/ELF/covmap.yaml index 9ec8987c6f93d..8edd884849cc5 100644 --- a/llvm/test/tools/obj2yaml/ELF/covmap.yaml +++ b/llvm/test/tools/obj2yaml/ELF/covmap.yaml @@ -17,103 +17,58 @@ Sections: Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 # PLAIN: Content: -# COVMAP: CovFun: CovFun: -# RAW:- NameRef: 0xA72DB7A33048E6A3 - - FuncName: _Z4funci -# COVMAP: FuncHash: 0xAFC772D567676299 + - NameRef: 0xA72DB7A33048E6A3 FuncHash: 0xAFC772D567676299 FilenamesRef: 0x70DA2CAFD8CE198E -# COVMAP: Expressions: + FileIDs: [ 1, 1 ] Expressions: -# RAW: - [ { Tag: Ref, Val: 0 }, { Tag: Ref, Val: 1 } ] - - [ { Ref: 0 }, { Ref: 1 } ] - - [ { Add: 0 }, { Ref: 2 } ] - - [ { Add: 0 }, { Ref: 2 } ] - - [ { Add: 0 }, { Ref: 2 } ] - - [ { Ref: 0 }, { Ref: 2 } ] - - [ { Ref: 0 }, { Ref: 2 } ] - - [ { Ref: 0 }, { Ref: 2 } ] - - [ { Add: 0 }, { Ref: 5 } ] -# COVMAP: Files: + - [ { Tag: Ref, Val: 0 }, { Tag: Ref, Val: 1 } ] + - [ { Tag: Add, Val: 0 }, { Tag: Ref, Val: 2 } ] + - [ { Tag: Add, Val: 0 }, { Tag: Ref, Val: 2 } ] + - [ { Tag: Add, Val: 0 }, { Tag: Ref, Val: 2 } ] + - [ { Tag: Ref, Val: 0 }, { Tag: Ref, Val: 2 } ] + - [ { Tag: Ref, Val: 0 }, { Tag: Ref, Val: 2 } ] + - [ { Tag: Ref, Val: 0 }, { Tag: Ref, Val: 2 } ] + - [ { Tag: Add, Val: 0 }, { Tag: Ref, Val: 5 } ] Files: -# DET: - Index: 0 - - Index: 0 -# DET: Filename: func.cpp - Filename: func.cpp -# COVMAP: Regions: - Regions: -# LOC: Loc: [ 3, 17, 14, 2 ] -# DLOC: dLoc: [ 3, 17, 11, 2 ] -# RAW: Tag: Ref, Val: 0 -# DETONLY: Ref: 0 - - { Loc: [ 3, 17, 14, 2 ], Ref: 0 } -# LOC: Loc: [ 6, 6, 11, 4 ] -# DLOC dLoc: [ 3, 6, 5, 4 ] -# RAW: Tag: Add, Val: 0 -# DETONLY: Add: 0 - - { Loc: [ 6, 6, 11, 4 ], Add: 0 } -# COVMAP: Expansion: 1 - - { Loc: [ 7, 9, 7, 13 ], Expansion: 1 } -# COVMAP: isGap: true -# RAW: Tag: Ref, Val: 2 -# DETONLY: Ref: 2 - - { Loc: [ 7, 23, 8, 7 ], isGap: true, Ref: 2 } - - { Loc: [ 8, 7, 8, 16 ], Ref: 2 } -# COVMAP: isGap: true -# RAW: Tag: Sub, Val: 3 -# DETONLY: Sub: 3 - - { Loc: [ 8, 17, 10, 5 ], isGap: true, Sub: 3 } -# COVMAP: ExtTag: Skip - - { Loc: [ 9, 1, 9, 1 ], ExtTag: Skip } - - { Loc: [ 10, 5, 11, 4 ], Sub: 3 } - - { Loc: [ 11, 12, 11, 17 ], Sub: 3 } -# RAW: ExtTag: Branch, Branch: [ { Tag: Ref, Val: 1 }, { Tag: Sub, Val: 6 } ] } -# DETONLY: Branch: [ { Ref: 1 }, { Sub: 6 } ] - - { Loc: [ 11, 12, 11, 17 ], Branch: [ { Ref: 1 }, { Sub: 6 } ] } - - { Loc: [ 11, 19, 12, 3 ], isGap: true, Sub: 6 } - - { Loc: [ 12, 3, 12, 11 ], Sub: 6 } - - { Loc: [ 12, 12, 13, 3 ], isGap: true, Tag: Zero } -# LOC: Loc: [ 13, 3, 13, 12 ] -# DLOC: dLoc: [ 1, 3, 0, 12 ] -# COVMAP: Tag: Zero - - { Loc: [ 13, 3, 13, 12 ], Tag: Zero } -# DET: - Index: 1 - - Index: 1 -# DET: Filename: func.cpp - Filename: func.cpp -# COVMAP: Regions: - Regions: - - { Loc: [ 1, 17, 1, 41 ], Add: 0 } - - { Loc: [ 1, 18, 1, 32 ], Add: 0 } -# RAW: ExtTag: Decision -# COVMAP: Decision: { BIdx: 5, NCond: 3 } } - - { Loc: [ 1, 18, 1, 40 ], Decision: { BIdx: 5, NCond: 3 } } - - { Loc: [ 1, 19, 1, 22 ], Add: 0 } -# RAW: ExtTag: MCDCBranch -# RAW: Branch: [ { Tag: Sub, Val: 7 }, { Tag: Ref, Val: 5 } ] -# DETONLY: Branch: [ { Sub: 7 }, { Ref: 5 } ] -# COVMAP: MCDC: [ 1, 2, 3 ] - - { Loc: [ 1, 19, 1, 22 ], Branch: [ { Sub: 7 }, { Ref: 5 } ], MCDC: [ 1, 2, 3 ] } - - { Loc: [ 1, 26, 1, 31 ], Ref: 5 } - - { Loc: [ 1, 26, 1, 31 ], Branch: [ { Tag: Zero }, { Ref: 6 } ], MCDC: [ 3, 2, 0 ] } - - { Loc: [ 1, 36, 1, 40 ], Ref: 3 } - - { Loc: [ 1, 36, 1, 40 ], Branch: [ { Ref: 4 }, { Tag: Zero } ], MCDC: [ 2, 0, 0 ] } + - Regions: + - { dLoc: [ 3, 17, 11, 2 ], Tag: Ref, Val: 0 } + - { dLoc: [ 3, 6, 5, 4 ], Tag: Add, Val: 0 } + - { dLoc: [ 1, 9, 0, 13 ], Tag: Zero, Val: 3, Expansion: 1 } + - { dLoc: [ 0, 23, 1, 7 ], isGap: true, Tag: Ref, Val: 2 } + - { dLoc: [ 1, 7, 0, 16 ], Tag: Ref, Val: 2 } + - { dLoc: [ 0, 17, 2, 5 ], isGap: true, Tag: Sub, Val: 3 } + - { dLoc: [ 1, 1, 0, 1 ], Tag: Zero, Val: 4, ExtTag: Skip } + - { dLoc: [ 1, 5, 1, 4 ], Tag: Sub, Val: 3 } + - { dLoc: [ 1, 12, 0, 17 ], Tag: Sub, Val: 3 } + - { dLoc: [ 0, 12, 0, 17 ], Tag: Zero, Val: 8, ExtTag: Branch, Branch: [ { Tag: Ref, Val: 1 }, { Tag: Sub, Val: 6 } ] } + - { dLoc: [ 0, 19, 1, 3 ], isGap: true, Tag: Sub, Val: 6 } + - { dLoc: [ 1, 3, 0, 11 ], Tag: Sub, Val: 6 } + - { dLoc: [ 0, 12, 1, 3 ], isGap: true, Tag: Zero, Val: 0 } + - { dLoc: [ 1, 3, 0, 12 ], Tag: Zero, Val: 0 } + - Regions: + - { dLoc: [ 1, 17, 0, 41 ], Tag: Add, Val: 0 } + - { dLoc: [ 0, 18, 0, 32 ], Tag: Add, Val: 0 } + - { dLoc: [ 0, 18, 0, 40 ], Tag: Zero, Val: 10, ExtTag: Decision, Decision: { BIdx: 5, NCond: 3 } } + - { dLoc: [ 0, 19, 0, 22 ], Tag: Add, Val: 0 } + - { dLoc: [ 0, 19, 0, 22 ], Tag: Zero, Val: 12, ExtTag: MCDCBranch, Branch: [ { Tag: Sub, Val: 7 }, { Tag: Ref, Val: 5 } ], MCDC: [ 1, 2, 3 ] } + - { dLoc: [ 0, 26, 0, 31 ], Tag: Ref, Val: 5 } + - { dLoc: [ 0, 26, 0, 31 ], Tag: Zero, Val: 12, ExtTag: MCDCBranch, Branch: [ { Tag: Zero, Val: 0 }, { Tag: Ref, Val: 6 } ], MCDC: [ 3, 2, 0 ] } + - { dLoc: [ 0, 36, 0, 40 ], Tag: Ref, Val: 3 } + - { dLoc: [ 0, 36, 0, 40 ], Tag: Zero, Val: 12, ExtTag: MCDCBranch, Branch: [ { Tag: Ref, Val: 4 }, { Tag: Zero, Val: 0 } ], MCDC: [ 2, 0, 0 ] } # CHECK: __llvm_covmap - Name: __llvm_covmap Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 # PLAIN: Content: -# COVMAP: CovMap: CovMap: -# COVMAP: - FilenamesRef: 0x70DA2CAFD8CE198E - FilenamesRef: 0x70DA2CAFD8CE198E -# COVMAP: Version: Version: 6 -# RAWONLY: Filenames: -# RAWONLY: - '' -# RAWONLY: - func.cpp + Filenames: + - '' + - func.cpp # CHECK: __llvm_prf_names - Name: __llvm_prf_names Type: SHT_PROGBITS @@ -123,9 +78,7 @@ Sections: # PLAIN-NOT: CovMap: # PLAIN-NOT: PrfNames: # PLAIN: Content: -# CovMap: ProfNames PrfNames: -# CovMap: - - _Z4funci - - _Z4funci - Type: SectionHeaderTable Sections: From 82ffad17371bb4b7bb841577a876784a0aac1b24 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Sat, 15 Mar 2025 13:00:09 +0900 Subject: [PATCH 10/10] Reflect feedbacks --- llvm/include/llvm/ObjectYAML/CovMap.h | 5 +++-- llvm/lib/ObjectYAML/CovMap.cpp | 5 ++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/llvm/include/llvm/ObjectYAML/CovMap.h b/llvm/include/llvm/ObjectYAML/CovMap.h index cb2953eb27f7e..913cb6060f7a8 100644 --- a/llvm/include/llvm/ObjectYAML/CovMap.h +++ b/llvm/include/llvm/ObjectYAML/CovMap.h @@ -83,7 +83,8 @@ struct DecisionTy { /// {LineStart, ColumnStart, LineEnd, ColumnEnd} using LocTy = std::array; -/// +/// Region record. +/// CounterTy is enhanced if Tag is Zero and Val is not zero. struct RecTy : CounterTy { enum ExtTagTy : uint8_t { Skip = 2, @@ -109,7 +110,7 @@ struct RecTy : CounterTy { void mapping(llvm::yaml::IO &IO) override; - void encode(uint64_t &StartLoc, raw_ostream &OS) const; + void encode(raw_ostream &OS) const; }; /// {NumRecs, Recs...} diff --git a/llvm/lib/ObjectYAML/CovMap.cpp b/llvm/lib/ObjectYAML/CovMap.cpp index 643caaf5df3d9..3ad809f61bb0a 100644 --- a/llvm/lib/ObjectYAML/CovMap.cpp +++ b/llvm/lib/ObjectYAML/CovMap.cpp @@ -41,7 +41,7 @@ void DecisionTy::encode(raw_ostream &OS) const { encodeULEB128(NC, OS); } -void RecTy::encode(uint64_t &StartLoc, raw_ostream &OS) const { +void RecTy::encode(raw_ostream &OS) const { if (Expansion) { encodeULEB128(4 + (*Expansion << 3), OS); } else if (ExtTag && *ExtTag == Skip) { @@ -94,9 +94,8 @@ void CovFunTy::encode(raw_ostream &OS, endianness Endianness) const { for (const auto &File : Files) { encodeULEB128(File.Recs.size(), SS); - uint64_t StartLoc = 0; for (const auto &Rec : File.Recs) - Rec.encode(StartLoc, SS); + Rec.encode(SS); } // Emit the Header