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/StringMap.h"
20#include "llvm/Support/Regex.h"
21#include <memory>
22#include <string>
23#include <utility>
24#include <variant>
25#include <vector>
26
27namespace llvm {
28class MemoryBuffer;
29class StringRef;
30
31namespace vfs {
32class FileSystem;
33}
34
35/// This is a utility class used to parse user-provided text files with
36/// "special case lists" for code sanitizers. Such files are used to
37/// define an "ABI list" for DataFlowSanitizer and allow/exclusion lists for
38/// sanitizers like AddressSanitizer or UndefinedBehaviorSanitizer.
39///
40/// Empty lines and lines starting with "#" are ignored. Sections are defined
41/// using a '[section_name]' header and can be used to specify sanitizers the
42/// entries below it apply to. Section names are globs, and
43/// entries without a section header match all sections (e.g. an '[*]' header
44/// is assumed.)
45/// The remaining lines should have the form:
46/// prefix:glob_pattern[=category]
47/// If category is not specified, it is assumed to be empty string.
48/// Definitions of "prefix" and "category" are sanitizer-specific. For example,
49/// sanitizer exclusion support prefixes "src", "mainfile", "fun" and "global".
50/// "glob_pattern" defines source files, main files, functions or globals which
51/// shouldn't be instrumented.
52/// Examples of categories:
53/// "functional": used in DFSan to list functions with pure functional
54/// semantics.
55/// "init": used in ASan exclusion list to disable initialization-order bugs
56/// detection for certain globals or source files.
57/// Full special case list file example:
58/// ---
59/// [address]
60/// # Excluded items:
61/// fun:*_ZN4base6subtle*
62/// global:*global_with_bad_access_or_initialization*
63/// global:*global_with_initialization_issues*=init
64/// type:*Namespace::ClassName*=init
65/// src:file_with_tricky_code.cc
66/// src:ignore-global-initializers-issues.cc=init
67/// mainfile:main_file.cc
68///
69/// [dataflow]
70/// # Functions with pure functional semantics:
71/// fun:cos=functional
72/// fun:sin=functional
73/// ---
75public:
76 static constexpr std::pair<unsigned, unsigned> NotFound = {0, 0};
77 /// Parses the special case list entries from files. On failure, returns
78 /// 0 and writes an error message to string.
79 LLVM_ABI static std::unique_ptr<SpecialCaseList>
80 create(const std::vector<std::string> &Paths, llvm::vfs::FileSystem &FS,
81 std::string &Error);
82 /// Parses the special case list from a memory buffer. On failure, returns
83 /// 0 and writes an error message to string.
84 LLVM_ABI static std::unique_ptr<SpecialCaseList>
85 create(const MemoryBuffer *MB, std::string &Error);
86 /// Parses the special case list entries from files. On failure, reports a
87 /// fatal error.
88 LLVM_ABI static std::unique_ptr<SpecialCaseList>
89 createOrDie(const std::vector<std::string> &Paths, llvm::vfs::FileSystem &FS);
90
92
93 /// Returns true, if special case list contains a line
94 /// \code
95 /// @Prefix:<E>=@Category
96 /// \endcode
97 /// where @Query satisfies the glob <E> in a given @Section.
99 StringRef Category = StringRef()) const;
100
101 /// Returns the file index and the line number <FileIdx, LineNo> corresponding
102 /// to the special case list entry if the special case list contains a line
103 /// \code
104 /// @Prefix:<E>=@Category
105 /// \endcode
106 /// where @Query satisfies the glob <E> in a given @Section.
107 /// Returns (zero, zero) if there is no exclusion entry corresponding to this
108 /// expression.
109 LLVM_ABI std::pair<unsigned, unsigned>
111 StringRef Category = StringRef()) const;
112
113protected:
114 // Implementations of the create*() functions that can also be used by derived
115 // classes.
116 LLVM_ABI bool createInternal(const std::vector<std::string> &Paths,
117 vfs::FileSystem &VFS, std::string &Error);
118 LLVM_ABI bool createInternal(const MemoryBuffer *MB, std::string &Error,
119 bool OrderBySize = false);
120
121 SpecialCaseList() = default;
124
125private:
126 // Lagacy v1 matcher.
127 class RegexMatcher {
128 public:
129 LLVM_ABI Error insert(StringRef Pattern, unsigned LineNumber);
130 LLVM_ABI void preprocess(bool BySize);
131
132 LLVM_ABI void
133 match(StringRef Query,
134 llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const;
135
136 struct Reg {
138 : Name(Name), LineNo(LineNo), Rg(std::move(Rg)) {}
140 unsigned LineNo;
142 };
143
144 std::vector<Reg> RegExes;
145 };
146
147 class GlobMatcher {
148 public:
149 LLVM_ABI Error insert(StringRef Pattern, unsigned LineNumber);
150 LLVM_ABI void preprocess(bool BySize);
151
152 LLVM_ABI void
153 match(StringRef Query,
154 llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const;
155
163
164 std::vector<GlobMatcher::Glob> Globs;
165 };
166
167 /// Represents a set of patterns and their line numbers
168 class Matcher {
169 public:
170 LLVM_ABI Matcher(bool UseGlobs, bool RemoveDotSlash);
171
172 LLVM_ABI Error insert(StringRef Pattern, unsigned LineNumber);
173 LLVM_ABI void preprocess(bool BySize);
174
175 LLVM_ABI void
176 match(StringRef Query,
177 llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const;
178
179 LLVM_ABI bool matchAny(StringRef Query) const {
180 bool R = false;
181 match(Query, [&](StringRef, unsigned) { R = true; });
182 return R;
183 }
184
185 std::variant<RegexMatcher, GlobMatcher> M;
186 bool RemoveDotSlash;
187 };
188
189 using SectionEntries = StringMap<StringMap<Matcher>>;
190
191protected:
192 struct Section {
193 Section(StringRef Str, unsigned FileIdx, bool UseGlobs)
194 : SectionMatcher(UseGlobs, /*RemoveDotSlash=*/false), SectionStr(Str),
195 FileIdx(FileIdx) {}
196
197 Section(Section &&) = default;
198
200 SectionEntries Entries;
201 std::string SectionStr;
202 unsigned FileIdx;
203
204 // Helper method to search by Prefix, Query, and Category. Returns
205 // 1-based line number on which rule is defined, or 0 if there is no match.
206 LLVM_ABI unsigned getLastMatch(StringRef Prefix, StringRef Query,
207 StringRef Category) const;
208
209 // Helper method to search by Prefix, Query, and Category. Returns
210 // matching rule, or empty string if there is no match.
212 StringRef Category) const;
213
214 private:
215 friend class SpecialCaseList;
216 LLVM_ABI void preprocess(bool OrderBySize);
217 LLVM_ABI const SpecialCaseList::Matcher *
218 findMatcher(StringRef Prefix, StringRef Category) const;
219 };
220
221 ArrayRef<const Section> sections() const { return Sections; }
222
223private:
224 BumpPtrAllocator StrAlloc;
225 std::vector<Section> Sections;
226
228 unsigned FileIdx, unsigned LineNo,
229 bool UseGlobs);
230
231 /// Parses just-constructed SpecialCaseList entries from a memory buffer.
232 LLVM_ABI bool parse(unsigned FileIdx, const MemoryBuffer *MB,
233 std::string &Error, bool OrderBySize);
234};
235
236} // namespace llvm
237
238#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)
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...
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.
bool match(Val *V, const Pattern &P)
This is an optimization pass for GlobalISel generic memory operations.
BumpPtrAllocatorImpl BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:383
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
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