5
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
6
// ===----------------------------------------------------------------------===//
7
7
//
8
- // This is a utility class used to parse user-provided text files with
9
- // "special case lists" for code sanitizers. Such files are used to
10
- // define an "ABI list" for DataFlowSanitizer and allow/exclusion lists for
11
- // sanitizers like AddressSanitizer or UndefinedBehaviorSanitizer.
12
- //
13
- // Empty lines and lines starting with "#" are ignored. Sections are defined
14
- // using a '[section_name]' header and can be used to specify sanitizers the
15
- // entries below it apply to. Section names are regular expressions, and
16
- // entries without a section header match all sections (e.g. an '[*]' header
17
- // is assumed.)
18
- // The remaining lines should have the form:
19
- // prefix:wildcard_expression[=category]
20
- // If category is not specified, it is assumed to be empty string.
21
- // Definitions of "prefix" and "category" are sanitizer-specific. For example,
22
- // sanitizer exclusion support prefixes "src", "mainfile", "fun" and "global".
23
- // Wildcard expressions define, respectively, source files, main files,
24
- // functions or globals which shouldn't be instrumented.
25
- // Examples of categories:
26
- // "functional": used in DFSan to list functions with pure functional
27
- // semantics.
28
- // "init": used in ASan exclusion list to disable initialization-order bugs
29
- // detection for certain globals or source files.
30
- // Full special case list file example:
31
- // ---
32
- // [address]
33
- // # Excluded items:
34
- // fun:*_ZN4base6subtle*
35
- // global:*global_with_bad_access_or_initialization*
36
- // global:*global_with_initialization_issues*=init
37
- // type:*Namespace::ClassName*=init
38
- // src:file_with_tricky_code.cc
39
- // src:ignore-global-initializers-issues.cc=init
40
- // mainfile:main_file.cc
41
- //
42
- // [dataflow]
43
- // # Functions with pure functional semantics:
44
- // fun:cos=functional
45
- // fun:sin=functional
46
- // ---
47
- // Note that the wild card is in fact an llvm::Regex, but * is automatically
48
- // replaced with .*
8
+ // This file implements a Special Case List for code sanitizers.
49
9
//
50
10
// ===----------------------------------------------------------------------===//
51
11
52
12
#ifndef LLVM_SUPPORT_SPECIALCASELIST_H
53
13
#define LLVM_SUPPORT_SPECIALCASELIST_H
54
14
55
15
#include " llvm/ADT/StringMap.h"
16
+ #include " llvm/Support/GlobPattern.h"
56
17
#include " llvm/Support/Regex.h"
57
18
#include < memory>
58
19
#include < string>
@@ -66,6 +27,45 @@ namespace vfs {
66
27
class FileSystem ;
67
28
}
68
29
30
+ // / This is a utility class used to parse user-provided text files with
31
+ // / "special case lists" for code sanitizers. Such files are used to
32
+ // / define an "ABI list" for DataFlowSanitizer and allow/exclusion lists for
33
+ // / sanitizers like AddressSanitizer or UndefinedBehaviorSanitizer.
34
+ // /
35
+ // / Empty lines and lines starting with "#" are ignored. Sections are defined
36
+ // / using a '[section_name]' header and can be used to specify sanitizers the
37
+ // / entries below it apply to. Section names are globs, and
38
+ // / entries without a section header match all sections (e.g. an '[*]' header
39
+ // / is assumed.)
40
+ // / The remaining lines should have the form:
41
+ // / prefix:glob_pattern[=category]
42
+ // / If category is not specified, it is assumed to be empty string.
43
+ // / Definitions of "prefix" and "category" are sanitizer-specific. For example,
44
+ // / sanitizer exclusion support prefixes "src", "mainfile", "fun" and "global".
45
+ // / "glob_pattern" defines source files, main files, functions or globals which
46
+ // / shouldn't be instrumented.
47
+ // / Examples of categories:
48
+ // / "functional": used in DFSan to list functions with pure functional
49
+ // / semantics.
50
+ // / "init": used in ASan exclusion list to disable initialization-order bugs
51
+ // / detection for certain globals or source files.
52
+ // / Full special case list file example:
53
+ // / ---
54
+ // / [address]
55
+ // / # Excluded items:
56
+ // / fun:*_ZN4base6subtle*
57
+ // / global:*global_with_bad_access_or_initialization*
58
+ // / global:*global_with_initialization_issues*=init
59
+ // / type:*Namespace::ClassName*=init
60
+ // / src:file_with_tricky_code.cc
61
+ // / src:ignore-global-initializers-issues.cc=init
62
+ // / mainfile:main_file.cc
63
+ // /
64
+ // / [dataflow]
65
+ // / # Functions with pure functional semantics:
66
+ // / fun:cos=functional
67
+ // / fun:sin=functional
68
+ // / ---
69
69
class SpecialCaseList {
70
70
public:
71
71
// / Parses the special case list entries from files. On failure, returns
@@ -88,7 +88,7 @@ class SpecialCaseList {
88
88
// / \code
89
89
// / @Prefix:<E>=@Category
90
90
// / \endcode
91
- // / where @Query satisfies wildcard expression <E> in a given @Section.
91
+ // / where @Query satisfies the glob <E> in a given @Section.
92
92
bool inSection (StringRef Section, StringRef Prefix, StringRef Query,
93
93
StringRef Category = StringRef()) const ;
94
94
@@ -97,7 +97,7 @@ class SpecialCaseList {
97
97
// / \code
98
98
// / @Prefix:<E>=@Category
99
99
// / \endcode
100
- // / where @Query satisfies wildcard expression <E> in a given @Section.
100
+ // / where @Query satisfies the glob <E> in a given @Section.
101
101
// / Returns zero if there is no exclusion entry corresponding to this
102
102
// / expression.
103
103
unsigned inSectionBlame (StringRef Section, StringRef Prefix, StringRef Query,
@@ -114,36 +114,36 @@ class SpecialCaseList {
114
114
SpecialCaseList (SpecialCaseList const &) = delete ;
115
115
SpecialCaseList &operator =(SpecialCaseList const &) = delete ;
116
116
117
- // / Represents a set of regular expressions. Regular expressions which are
118
- // / "literal" (i.e. no regex metacharacters) are stored in Strings. The
119
- // / reason for doing so is efficiency; StringMap is much faster at matching
120
- // / literal strings than Regex.
117
+ // / Represents a set of globs and their line numbers
121
118
class Matcher {
122
119
public:
123
- bool insert (std::string Regexp , unsigned LineNumber, std::string &REError );
120
+ Error insert (StringRef Pattern , unsigned LineNumber, bool UseRegex );
124
121
// Returns the line number in the source file that this query matches to.
125
122
// Returns zero if no match is found.
126
123
unsigned match (StringRef Query) const ;
127
124
128
125
private:
129
- StringMap<unsigned > Strings ;
126
+ StringMap<std::pair<GlobPattern, unsigned >> Globs ;
130
127
std::vector<std::pair<std::unique_ptr<Regex>, unsigned >> RegExes;
131
128
};
132
129
133
130
using SectionEntries = StringMap<StringMap<Matcher>>;
134
131
135
132
struct Section {
136
133
Section (std::unique_ptr<Matcher> M) : SectionMatcher(std::move(M)){};
134
+ Section () : Section(std::make_unique<Matcher>()) {}
137
135
138
136
std::unique_ptr<Matcher> SectionMatcher;
139
137
SectionEntries Entries;
140
138
};
141
139
142
- std::vector<Section> Sections;
140
+ StringMap<Section> Sections;
141
+
142
+ Expected<Section *> addSection (StringRef SectionStr, unsigned LineNo,
143
+ bool UseGlobs = true );
143
144
144
145
// / Parses just-constructed SpecialCaseList entries from a memory buffer.
145
- bool parse (const MemoryBuffer *MB, StringMap<size_t > &SectionsMap,
146
- std::string &Error);
146
+ bool parse (const MemoryBuffer *MB, std::string &Error);
147
147
148
148
// Helper method for derived classes to search by Prefix, Query, and Category
149
149
// once they have already resolved a section entry.
0 commit comments