Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:46

0001 //===- MarkupFilter.h -------------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 ///
0009 /// \file
0010 /// This file declares a filter that replaces symbolizer markup with
0011 /// human-readable expressions.
0012 ///
0013 //===----------------------------------------------------------------------===//
0014 
0015 #ifndef LLVM_DEBUGINFO_SYMBOLIZE_MARKUPFILTER_H
0016 #define LLVM_DEBUGINFO_SYMBOLIZE_MARKUPFILTER_H
0017 
0018 #include "llvm/ADT/DenseMap.h"
0019 #include "llvm/DebugInfo/Symbolize/Markup.h"
0020 #include "llvm/Object/BuildID.h"
0021 #include "llvm/Support/WithColor.h"
0022 #include "llvm/Support/raw_ostream.h"
0023 #include <map>
0024 
0025 namespace llvm {
0026 namespace symbolize {
0027 
0028 class LLVMSymbolizer;
0029 
0030 /// Filter to convert parsed log symbolizer markup elements into human-readable
0031 /// text.
0032 class MarkupFilter {
0033 public:
0034   MarkupFilter(raw_ostream &OS, LLVMSymbolizer &Symbolizer,
0035                std::optional<bool> ColorsEnabled = std::nullopt);
0036 
0037   /// Filters a line containing symbolizer markup and writes the human-readable
0038   /// results to the output stream.
0039   ///
0040   /// Invalid or unimplemented markup elements are removed. Some output may be
0041   /// deferred until future filter() or finish() call.
0042   void filter(std::string &&InputLine);
0043 
0044   /// Records that the input stream has ended and writes any deferred output.
0045   void finish();
0046 
0047 private:
0048   struct Module {
0049     uint64_t ID;
0050     std::string Name;
0051     SmallVector<uint8_t> BuildID;
0052   };
0053 
0054   struct MMap {
0055     uint64_t Addr;
0056     uint64_t Size;
0057     const Module *Mod;
0058     std::string Mode; // Lowercase
0059     uint64_t ModuleRelativeAddr;
0060 
0061     bool contains(uint64_t Addr) const;
0062     uint64_t getModuleRelativeAddr(uint64_t Addr) const;
0063   };
0064 
0065   // An informational module line currently being constructed. As many mmap
0066   // elements as possible are folded into one ModuleInfo line.
0067   struct ModuleInfoLine {
0068     const Module *Mod;
0069 
0070     SmallVector<const MMap *> MMaps = {};
0071   };
0072 
0073   // The semantics of a possible program counter value.
0074   enum class PCType {
0075     // The address is a return address and must be adjusted to point to the call
0076     // itself.
0077     ReturnAddress,
0078     // The address is the precise location in the code and needs no adjustment.
0079     PreciseCode,
0080   };
0081 
0082   bool tryContextualElement(const MarkupNode &Node,
0083                             const SmallVector<MarkupNode> &DeferredNodes);
0084   bool tryMMap(const MarkupNode &Element,
0085                const SmallVector<MarkupNode> &DeferredNodes);
0086   bool tryReset(const MarkupNode &Element,
0087                 const SmallVector<MarkupNode> &DeferredNodes);
0088   bool tryModule(const MarkupNode &Element,
0089                  const SmallVector<MarkupNode> &DeferredNodes);
0090 
0091   void beginModuleInfoLine(const Module *M);
0092   void endAnyModuleInfoLine();
0093 
0094   void filterNode(const MarkupNode &Node);
0095 
0096   bool tryPresentation(const MarkupNode &Node);
0097   bool trySymbol(const MarkupNode &Node);
0098   bool tryPC(const MarkupNode &Node);
0099   bool tryBackTrace(const MarkupNode &Node);
0100   bool tryData(const MarkupNode &Node);
0101 
0102   bool trySGR(const MarkupNode &Node);
0103 
0104   void highlight();
0105   void highlightValue();
0106   void restoreColor();
0107   void resetColor();
0108 
0109   void printRawElement(const MarkupNode &Element);
0110   void printValue(Twine Value);
0111 
0112   std::optional<Module> parseModule(const MarkupNode &Element) const;
0113   std::optional<MMap> parseMMap(const MarkupNode &Element) const;
0114 
0115   std::optional<uint64_t> parseAddr(StringRef Str) const;
0116   std::optional<uint64_t> parseModuleID(StringRef Str) const;
0117   std::optional<uint64_t> parseSize(StringRef Str) const;
0118   object::BuildID parseBuildID(StringRef Str) const;
0119   std::optional<std::string> parseMode(StringRef Str) const;
0120   std::optional<PCType> parsePCType(StringRef Str) const;
0121   std::optional<uint64_t> parseFrameNumber(StringRef Str) const;
0122 
0123   bool checkTag(const MarkupNode &Node) const;
0124   bool checkNumFields(const MarkupNode &Element, size_t Size) const;
0125   bool checkNumFieldsAtLeast(const MarkupNode &Element, size_t Size) const;
0126   void warnNumFieldsAtMost(const MarkupNode &Element, size_t Size) const;
0127 
0128   void reportTypeError(StringRef Str, StringRef TypeName) const;
0129   void reportLocation(StringRef::iterator Loc) const;
0130 
0131   const MMap *getOverlappingMMap(const MMap &Map) const;
0132   const MMap *getContainingMMap(uint64_t Addr) const;
0133 
0134   uint64_t adjustAddr(uint64_t Addr, PCType Type) const;
0135 
0136   StringRef lineEnding() const;
0137 
0138   raw_ostream &OS;
0139   LLVMSymbolizer &Symbolizer;
0140   const bool ColorsEnabled;
0141 
0142   MarkupParser Parser;
0143 
0144   // Current line being filtered.
0145   std::string Line;
0146 
0147   // A module info line currently being built. This incorporates as much mmap
0148   // information as possible before being emitted.
0149   std::optional<ModuleInfoLine> MIL;
0150 
0151   // SGR state.
0152   std::optional<raw_ostream::Colors> Color;
0153   bool Bold = false;
0154 
0155   // Map from Module ID to Module.
0156   DenseMap<uint64_t, std::unique_ptr<Module>> Modules;
0157 
0158   // Ordered map from starting address to mmap.
0159   std::map<uint64_t, MMap> MMaps;
0160 };
0161 
0162 } // end namespace symbolize
0163 } // end namespace llvm
0164 
0165 #endif // LLVM_DEBUGINFO_SYMBOLIZE_MARKUPFILTER_H