|
|
|||
File indexing completed on 2026-05-10 08:44:34
0001 //===-- SpecialCaseList.h - special case list for sanitizers ----*- 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 // This file implements a Special Case List for code sanitizers. 0009 // 0010 //===----------------------------------------------------------------------===// 0011 0012 #ifndef LLVM_SUPPORT_SPECIALCASELIST_H 0013 #define LLVM_SUPPORT_SPECIALCASELIST_H 0014 0015 #include "llvm/ADT/StringMap.h" 0016 #include "llvm/Support/GlobPattern.h" 0017 #include "llvm/Support/Regex.h" 0018 #include <memory> 0019 #include <string> 0020 #include <vector> 0021 0022 namespace llvm { 0023 class MemoryBuffer; 0024 class StringRef; 0025 0026 namespace vfs { 0027 class FileSystem; 0028 } 0029 0030 /// This is a utility class used to parse user-provided text files with 0031 /// "special case lists" for code sanitizers. Such files are used to 0032 /// define an "ABI list" for DataFlowSanitizer and allow/exclusion lists for 0033 /// sanitizers like AddressSanitizer or UndefinedBehaviorSanitizer. 0034 /// 0035 /// Empty lines and lines starting with "#" are ignored. Sections are defined 0036 /// using a '[section_name]' header and can be used to specify sanitizers the 0037 /// entries below it apply to. Section names are globs, and 0038 /// entries without a section header match all sections (e.g. an '[*]' header 0039 /// is assumed.) 0040 /// The remaining lines should have the form: 0041 /// prefix:glob_pattern[=category] 0042 /// If category is not specified, it is assumed to be empty string. 0043 /// Definitions of "prefix" and "category" are sanitizer-specific. For example, 0044 /// sanitizer exclusion support prefixes "src", "mainfile", "fun" and "global". 0045 /// "glob_pattern" defines source files, main files, functions or globals which 0046 /// shouldn't be instrumented. 0047 /// Examples of categories: 0048 /// "functional": used in DFSan to list functions with pure functional 0049 /// semantics. 0050 /// "init": used in ASan exclusion list to disable initialization-order bugs 0051 /// detection for certain globals or source files. 0052 /// Full special case list file example: 0053 /// --- 0054 /// [address] 0055 /// # Excluded items: 0056 /// fun:*_ZN4base6subtle* 0057 /// global:*global_with_bad_access_or_initialization* 0058 /// global:*global_with_initialization_issues*=init 0059 /// type:*Namespace::ClassName*=init 0060 /// src:file_with_tricky_code.cc 0061 /// src:ignore-global-initializers-issues.cc=init 0062 /// mainfile:main_file.cc 0063 /// 0064 /// [dataflow] 0065 /// # Functions with pure functional semantics: 0066 /// fun:cos=functional 0067 /// fun:sin=functional 0068 /// --- 0069 class SpecialCaseList { 0070 public: 0071 /// Parses the special case list entries from files. On failure, returns 0072 /// 0 and writes an error message to string. 0073 static std::unique_ptr<SpecialCaseList> 0074 create(const std::vector<std::string> &Paths, llvm::vfs::FileSystem &FS, 0075 std::string &Error); 0076 /// Parses the special case list from a memory buffer. On failure, returns 0077 /// 0 and writes an error message to string. 0078 static std::unique_ptr<SpecialCaseList> create(const MemoryBuffer *MB, 0079 std::string &Error); 0080 /// Parses the special case list entries from files. On failure, reports a 0081 /// fatal error. 0082 static std::unique_ptr<SpecialCaseList> 0083 createOrDie(const std::vector<std::string> &Paths, llvm::vfs::FileSystem &FS); 0084 0085 ~SpecialCaseList(); 0086 0087 /// Returns true, if special case list contains a line 0088 /// \code 0089 /// @Prefix:<E>=@Category 0090 /// \endcode 0091 /// where @Query satisfies the glob <E> in a given @Section. 0092 bool inSection(StringRef Section, StringRef Prefix, StringRef Query, 0093 StringRef Category = StringRef()) const; 0094 0095 /// Returns the line number corresponding to the special case list entry if 0096 /// the special case list contains a line 0097 /// \code 0098 /// @Prefix:<E>=@Category 0099 /// \endcode 0100 /// where @Query satisfies the glob <E> in a given @Section. 0101 /// Returns zero if there is no exclusion entry corresponding to this 0102 /// expression. 0103 unsigned inSectionBlame(StringRef Section, StringRef Prefix, StringRef Query, 0104 StringRef Category = StringRef()) const; 0105 0106 protected: 0107 // Implementations of the create*() functions that can also be used by derived 0108 // classes. 0109 bool createInternal(const std::vector<std::string> &Paths, 0110 vfs::FileSystem &VFS, std::string &Error); 0111 bool createInternal(const MemoryBuffer *MB, std::string &Error); 0112 0113 SpecialCaseList() = default; 0114 SpecialCaseList(SpecialCaseList const &) = delete; 0115 SpecialCaseList &operator=(SpecialCaseList const &) = delete; 0116 0117 /// Represents a set of globs and their line numbers 0118 class Matcher { 0119 public: 0120 Error insert(StringRef Pattern, unsigned LineNumber, bool UseRegex); 0121 // Returns the line number in the source file that this query matches to. 0122 // Returns zero if no match is found. 0123 unsigned match(StringRef Query) const; 0124 0125 StringMap<std::pair<GlobPattern, unsigned>> Globs; 0126 std::vector<std::pair<std::unique_ptr<Regex>, unsigned>> RegExes; 0127 }; 0128 0129 using SectionEntries = StringMap<StringMap<Matcher>>; 0130 0131 struct Section { 0132 Section(std::unique_ptr<Matcher> M) : SectionMatcher(std::move(M)){}; 0133 Section() : Section(std::make_unique<Matcher>()) {} 0134 0135 std::unique_ptr<Matcher> SectionMatcher; 0136 SectionEntries Entries; 0137 }; 0138 0139 StringMap<Section> Sections; 0140 0141 Expected<Section *> addSection(StringRef SectionStr, unsigned LineNo, 0142 bool UseGlobs = true); 0143 0144 /// Parses just-constructed SpecialCaseList entries from a memory buffer. 0145 bool parse(const MemoryBuffer *MB, std::string &Error); 0146 0147 // Helper method for derived classes to search by Prefix, Query, and Category 0148 // once they have already resolved a section entry. 0149 unsigned inSectionBlame(const SectionEntries &Entries, StringRef Prefix, 0150 StringRef Query, StringRef Category) const; 0151 }; 0152 0153 } // namespace llvm 0154 0155 #endif // LLVM_SUPPORT_SPECIALCASELIST_H
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|