LLVM 22.0.0git
SpecialCaseList.h
Go to the documentation of this file.
1//===-- SpecialCaseList.h - special case list for sanitizers ----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//===----------------------------------------------------------------------===//
7//
8// This file implements a Special Case List for code sanitizers.
9//
10//===----------------------------------------------------------------------===//
11
12#ifndef LLVM_SUPPORT_SPECIALCASELIST_H
13#define LLVM_SUPPORT_SPECIALCASELIST_H
14
15#include "llvm/ADT/ArrayRef.h"
16#include "llvm/ADT/RadixTree.h"
18#include "llvm/ADT/StringMap.h"
23#include "llvm/Support/Regex.h"
24#include <memory>
25#include <string>
26#include <utility>
27#include <variant>
28#include <vector>
29
30namespace llvm {
31class MemoryBuffer;
32class StringRef;
33
34namespace vfs {
35class FileSystem;
36}
37
38/// This is a utility class used to parse user-provided text files with
39/// "special case lists" for code sanitizers. Such files are used to
40/// define an "ABI list" for DataFlowSanitizer and allow/exclusion lists for
41/// sanitizers like AddressSanitizer or UndefinedBehaviorSanitizer.
42///
43/// Empty lines and lines starting with "#" are ignored. Sections are defined
44/// using a '[section_name]' header and can be used to specify sanitizers the
45/// entries below it apply to. Section names are globs, and
46/// entries without a section header match all sections (e.g. an '[*]' header
47/// is assumed.)
48/// The remaining lines should have the form:
49/// prefix:glob_pattern[=category]
50/// If category is not specified, it is assumed to be empty string.
51/// Definitions of "prefix" and "category" are sanitizer-specific. For example,
52/// sanitizer exclusion support prefixes "src", "mainfile", "fun" and "global".
53/// "glob_pattern" defines source files, main files, functions or globals which
54/// shouldn't be instrumented.
55/// Examples of categories:
56/// "functional": used in DFSan to list functions with pure functional
57/// semantics.
58/// "init": used in ASan exclusion list to disable initialization-order bugs
59/// detection for certain globals or source files.
60/// Full special case list file example:
61/// ---
62/// [address]
63/// # Excluded items:
64/// fun:*_ZN4base6subtle*
65/// global:*global_with_bad_access_or_initialization*
66/// global:*global_with_initialization_issues*=init
67/// type:*Namespace::ClassName*=init
68/// src:file_with_tricky_code.cc
69/// src:ignore-global-initializers-issues.cc=init
70/// mainfile:main_file.cc
71///
72/// [dataflow]
73/// # Functions with pure functional semantics:
74/// fun:cos=functional
75/// fun:sin=functional
76/// ---
78public:
79 static constexpr std::pair<unsigned, unsigned> NotFound = {0, 0};
80 /// Parses the special case list entries from files. On failure, returns
81 /// 0 and writes an error message to string.
82 LLVM_ABI static std::unique_ptr<SpecialCaseList>
83 create(const std::vector<std::string> &Paths, llvm::vfs::FileSystem &FS,
84 std::string &Error);
85 /// Parses the special case list from a memory buffer. On failure, returns
86 /// 0 and writes an error message to string.
87 LLVM_ABI static std::unique_ptr<SpecialCaseList>
88 create(const MemoryBuffer *MB, std::string &Error);
89 /// Parses the special case list entries from files. On failure, reports a
90 /// fatal error.
91 LLVM_ABI static std::unique_ptr<SpecialCaseList>
92 createOrDie(const std::vector<std::string> &Paths, llvm::vfs::FileSystem &FS);
93
95
96 /// Returns true, if special case list contains a line
97 /// \code
98 /// @Prefix:<E>=@Category
99 /// \endcode
100 /// where @Query satisfies the glob <E> in a given @Section.
102 StringRef Category = StringRef()) const;
103
104 /// Returns the file index and the line number <FileIdx, LineNo> corresponding
105 /// to the special case list entry if the special case list contains a line
106 /// \code
107 /// @Prefix:<E>=@Category
108 /// \endcode
109 /// where @Query satisfies the glob <E> in a given @Section.
110 /// Returns (zero, zero) if there is no exclusion entry corresponding to this
111 /// expression.
112 LLVM_ABI std::pair<unsigned, unsigned>
114 StringRef Category = StringRef()) const;
115
116protected:
117 // Implementations of the create*() functions that can also be used by derived
118 // classes.
119 LLVM_ABI bool createInternal(const std::vector<std::string> &Paths,
120 vfs::FileSystem &VFS, std::string &Error);
121 LLVM_ABI bool createInternal(const MemoryBuffer *MB, std::string &Error,
122 bool OrderBySize = false);
123
124 SpecialCaseList() = default;
127
128private:
129 // Lagacy v1 matcher.
130 class RegexMatcher {
131 public:
132 LLVM_ABI Error insert(StringRef Pattern, unsigned LineNumber);
133 LLVM_ABI void preprocess(bool BySize);
134
135 LLVM_ABI void
136 match(StringRef Query,
137 llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const;
138
139 struct Reg {
141 : Name(Name), LineNo(LineNo), Rg(std::move(Rg)) {}
143 unsigned LineNo;
145 };
146
147 std::vector<Reg> RegExes;
148 };
149
150 class GlobMatcher {
151 public:
152 LLVM_ABI Error insert(StringRef Pattern, unsigned LineNumber);
153 LLVM_ABI void preprocess(bool BySize);
154
155 LLVM_ABI void
156 match(StringRef Query,
157 llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const;
158
166
167 std::vector<GlobMatcher::Glob> Globs;
168
172 PrefixSuffixToGlob;
173
176 SubstrToGlob;
177 };
178
179 /// Represents a set of patterns and their line numbers
180 class Matcher {
181 public:
182 LLVM_ABI Matcher(bool UseGlobs, bool RemoveDotSlash);
183
184 LLVM_ABI Error insert(StringRef Pattern, unsigned LineNumber);
185 LLVM_ABI void preprocess(bool BySize);
186
187 LLVM_ABI void
188 match(StringRef Query,
189 llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const;
190
191 LLVM_ABI bool matchAny(StringRef Query) const {
192 bool R = false;
193 match(Query, [&](StringRef, unsigned) { R = true; });
194 return R;
195 }
196
197 std::variant<RegexMatcher, GlobMatcher> M;
198 bool RemoveDotSlash;
199 };
200
201 using SectionEntries = StringMap<StringMap<Matcher>>;
202
203protected:
204 struct Section {
205 Section(StringRef Str, unsigned FileIdx, bool UseGlobs)
206 : SectionMatcher(UseGlobs, /*RemoveDotSlash=*/false), SectionStr(Str),
207 FileIdx(FileIdx) {}
208
209 Section(Section &&) = default;
210
212 SectionEntries Entries;
213 std::string SectionStr;
214 unsigned FileIdx;
215
216 // Helper method to search by Prefix, Query, and Category. Returns
217 // 1-based line number on which rule is defined, or 0 if there is no match.
218 LLVM_ABI unsigned getLastMatch(StringRef Prefix, StringRef Query,
219 StringRef Category) const;
220
221 // Helper method to search by Prefix, Query, and Category. Returns
222 // matching rule, or empty string if there is no match.
224 StringRef Category) const;
225
226 private:
227 friend class SpecialCaseList;
228 LLVM_ABI void preprocess(bool OrderBySize);
229 LLVM_ABI const SpecialCaseList::Matcher *
230 findMatcher(StringRef Prefix, StringRef Category) const;
231 };
232
233 ArrayRef<const Section> sections() const { return Sections; }
234
235private:
236 BumpPtrAllocator StrAlloc;
237 std::vector<Section> Sections;
238
240 unsigned FileIdx, unsigned LineNo,
241 bool UseGlobs);
242
243 /// Parses just-constructed SpecialCaseList entries from a memory buffer.
244 LLVM_ABI bool parse(unsigned FileIdx, const MemoryBuffer *MB,
245 std::string &Error, bool OrderBySize);
246};
247
248} // namespace llvm
249
250#endif // LLVM_SUPPORT_SPECIALCASELIST_H
This file defines the StringMap class.
This file defines the BumpPtrAllocator interface.
#define LLVM_ABI
Definition Compiler.h:213
static llvm::Error parse(DataExtractor &Data, uint64_t BaseAddr, LineEntryCallback const &Callback)
Definition LineTable.cpp:54
static Error addSection(const NewSectionInfo &NewSection, Object &Obj)
This file defines the SmallVector class.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:41
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
Tagged union holding either a T or a Error.
Definition Error.h:485
This class implements a glob pattern matcher similar to the one found in bash, but with some key diff...
Definition GlobPattern.h:52
This interface provides simple read-only access to a block of memory, and provides simple methods for...
A Radix Tree implementation.
Definition RadixTree.h:71
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
ArrayRef< const Section > sections() const
SpecialCaseList & operator=(SpecialCaseList const &)=delete
SpecialCaseList(SpecialCaseList const &)=delete
static constexpr std::pair< unsigned, unsigned > NotFound
LLVM_ABI std::pair< unsigned, unsigned > inSectionBlame(StringRef Section, StringRef Prefix, StringRef Query, StringRef Category=StringRef()) const
Returns the file index and the line number <FileIdx, LineNo> corresponding to the special case list e...
LLVM_ABI bool createInternal(const std::vector< std::string > &Paths, vfs::FileSystem &VFS, std::string &Error)
static LLVM_ABI std::unique_ptr< SpecialCaseList > createOrDie(const std::vector< std::string > &Paths, llvm::vfs::FileSystem &FS)
Parses the special case list entries from files.
static LLVM_ABI std::unique_ptr< SpecialCaseList > create(const std::vector< std::string > &Paths, llvm::vfs::FileSystem &FS, std::string &Error)
Parses the special case list entries from files.
LLVM_ABI ~SpecialCaseList()
LLVM_ABI bool inSection(StringRef Section, StringRef Prefix, StringRef Query, StringRef Category=StringRef()) const
Returns true, if special case list contains a line.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
An efficient, type-erasing, non-owning reference to a callable.
The virtual file system interface.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
bool match(Val *V, const Pattern &P)
This is an optimization pass for GlobalISel generic memory operations.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1867
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:383
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:867
Glob(StringRef Name, unsigned LineNo, GlobPattern &&Pattern)
Reg(StringRef Name, unsigned LineNo, Regex &&Rg)
Section(StringRef Str, unsigned FileIdx, bool UseGlobs)
LLVM_ABI StringRef getLongestMatch(StringRef Prefix, StringRef Query, StringRef Category) const
Section(Section &&)=default
LLVM_ABI unsigned getLastMatch(StringRef Prefix, StringRef Query, StringRef Category) const