LLVM  16.0.0git
SpecialCaseList.cpp
Go to the documentation of this file.
1 //===-- SpecialCaseList.cpp - special case list for sanitizers ------------===//
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 //
9 // This is a utility class for instrumentation passes (like AddressSanitizer
10 // or ThreadSanitizer) to avoid instrumenting some functions or global
11 // variables, or to instrument some functions or global variables in a specific
12 // way, based on a user-supplied list.
13 //
14 //===----------------------------------------------------------------------===//
15 
17 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/Support/Regex.h"
21 #include <string>
22 #include <system_error>
23 #include <utility>
24 
25 #include <stdio.h>
26 namespace llvm {
27 
28 bool SpecialCaseList::Matcher::insert(std::string Regexp,
29  unsigned LineNumber,
30  std::string &REError) {
31  if (Regexp.empty()) {
32  REError = "Supplied regexp was blank";
33  return false;
34  }
35 
36  if (Regex::isLiteralERE(Regexp)) {
37  Strings[Regexp] = LineNumber;
38  return true;
39  }
40  Trigrams.insert(Regexp);
41 
42  // Replace * with .*
43  for (size_t pos = 0; (pos = Regexp.find('*', pos)) != std::string::npos;
44  pos += strlen(".*")) {
45  Regexp.replace(pos, strlen("*"), ".*");
46  }
47 
48  Regexp = (Twine("^(") + StringRef(Regexp) + ")$").str();
49 
50  // Check that the regexp is valid.
51  Regex CheckRE(Regexp);
52  if (!CheckRE.isValid(REError))
53  return false;
54 
55  RegExes.emplace_back(
56  std::make_pair(std::make_unique<Regex>(std::move(CheckRE)), LineNumber));
57  return true;
58 }
59 
61  auto It = Strings.find(Query);
62  if (It != Strings.end())
63  return It->second;
64  if (Trigrams.isDefinitelyOut(Query))
65  return false;
66  for (const auto &RegExKV : RegExes)
67  if (RegExKV.first->match(Query))
68  return RegExKV.second;
69  return 0;
70 }
71 
72 std::unique_ptr<SpecialCaseList>
73 SpecialCaseList::create(const std::vector<std::string> &Paths,
74  llvm::vfs::FileSystem &FS, std::string &Error) {
75  std::unique_ptr<SpecialCaseList> SCL(new SpecialCaseList());
76  if (SCL->createInternal(Paths, FS, Error))
77  return SCL;
78  return nullptr;
79 }
80 
81 std::unique_ptr<SpecialCaseList> SpecialCaseList::create(const MemoryBuffer *MB,
82  std::string &Error) {
83  std::unique_ptr<SpecialCaseList> SCL(new SpecialCaseList());
84  if (SCL->createInternal(MB, Error))
85  return SCL;
86  return nullptr;
87 }
88 
89 std::unique_ptr<SpecialCaseList>
90 SpecialCaseList::createOrDie(const std::vector<std::string> &Paths,
92  std::string Error;
93  if (auto SCL = create(Paths, FS, Error))
94  return SCL;
96 }
97 
98 bool SpecialCaseList::createInternal(const std::vector<std::string> &Paths,
99  vfs::FileSystem &VFS, std::string &Error) {
101  for (const auto &Path : Paths) {
103  VFS.getBufferForFile(Path);
104  if (std::error_code EC = FileOrErr.getError()) {
105  Error = (Twine("can't open file '") + Path + "': " + EC.message()).str();
106  return false;
107  }
108  std::string ParseError;
109  if (!parse(FileOrErr.get().get(), Sections, ParseError)) {
110  Error = (Twine("error parsing file '") + Path + "': " + ParseError).str();
111  return false;
112  }
113  }
114  return true;
115 }
116 
118  std::string &Error) {
120  if (!parse(MB, Sections, Error))
121  return false;
122  return true;
123 }
124 
126  StringMap<size_t> &SectionsMap,
127  std::string &Error) {
128  // Iterate through each line in the exclusion list file.
130  MB->getBuffer().split(Lines, '\n');
131 
132  unsigned LineNo = 1;
133  StringRef Section = "*";
134 
135  for (auto I = Lines.begin(), E = Lines.end(); I != E; ++I, ++LineNo) {
136  *I = I->trim();
137  // Ignore empty lines and lines starting with "#"
138  if (I->empty() || I->startswith("#"))
139  continue;
140 
141  // Save section names
142  if (I->startswith("[")) {
143  if (!I->endswith("]")) {
144  Error = (Twine("malformed section header on line ") + Twine(LineNo) +
145  ": " + *I).str();
146  return false;
147  }
148 
149  Section = I->slice(1, I->size() - 1);
150 
151  std::string REError;
152  Regex CheckRE(Section);
153  if (!CheckRE.isValid(REError)) {
154  Error =
155  (Twine("malformed regex for section ") + Section + ": '" + REError)
156  .str();
157  return false;
158  }
159 
160  continue;
161  }
162 
163  // Get our prefix and unparsed regexp.
164  std::pair<StringRef, StringRef> SplitLine = I->split(":");
165  StringRef Prefix = SplitLine.first;
166  if (SplitLine.second.empty()) {
167  // Missing ':' in the line.
168  Error = (Twine("malformed line ") + Twine(LineNo) + ": '" +
169  SplitLine.first + "'").str();
170  return false;
171  }
172 
173  std::pair<StringRef, StringRef> SplitRegexp = SplitLine.second.split("=");
174  std::string Regexp = std::string(SplitRegexp.first);
175  StringRef Category = SplitRegexp.second;
176 
177  // Create this section if it has not been seen before.
178  if (SectionsMap.find(Section) == SectionsMap.end()) {
179  std::unique_ptr<Matcher> M = std::make_unique<Matcher>();
180  std::string REError;
181  if (!M->insert(std::string(Section), LineNo, REError)) {
182  Error = (Twine("malformed section ") + Section + ": '" + REError).str();
183  return false;
184  }
185 
186  SectionsMap[Section] = Sections.size();
187  Sections.emplace_back(std::move(M));
188  }
189 
190  auto &Entry = Sections[SectionsMap[Section]].Entries[Prefix][Category];
191  std::string REError;
192  if (!Entry.insert(std::move(Regexp), LineNo, REError)) {
193  Error = (Twine("malformed regex in line ") + Twine(LineNo) + ": '" +
194  SplitLine.second + "': " + REError).str();
195  return false;
196  }
197  }
198  return true;
199 }
200 
202 
204  StringRef Query, StringRef Category) const {
205  return inSectionBlame(Section, Prefix, Query, Category);
206 }
207 
209  StringRef Query,
210  StringRef Category) const {
211  for (const auto &SectionIter : Sections)
212  if (SectionIter.SectionMatcher->match(Section)) {
213  unsigned Blame =
214  inSectionBlame(SectionIter.Entries, Prefix, Query, Category);
215  if (Blame)
216  return Blame;
217  }
218  return 0;
219 }
220 
222  StringRef Prefix, StringRef Query,
223  StringRef Category) const {
224  SectionEntries::const_iterator I = Entries.find(Prefix);
225  if (I == Entries.end()) return 0;
226  StringMap<Matcher>::const_iterator II = I->second.find(Category);
227  if (II == I->second.end()) return 0;
228 
229  return II->getValue().match(Query);
230 }
231 
232 } // namespace llvm
MemoryBuffer.h
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::SpecialCaseList::~SpecialCaseList
~SpecialCaseList()
llvm::SpecialCaseList::inSection
bool inSection(StringRef Section, StringRef Prefix, StringRef Query, StringRef Category=StringRef()) const
Returns true, if special case list contains a line.
Definition: SpecialCaseList.cpp:203
llvm::cl::Prefix
@ Prefix
Definition: CommandLine.h:161
llvm::SpecialCaseList::create
static 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.
Definition: SpecialCaseList.cpp:73
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1181
llvm::SpecialCaseList::createInternal
bool createInternal(const std::vector< std::string > &Paths, vfs::FileSystem &VFS, std::string &Error)
Definition: SpecialCaseList.cpp:98
llvm::SpecialCaseList::inSectionBlame
unsigned inSectionBlame(StringRef Section, StringRef Prefix, StringRef Query, StringRef Category=StringRef()) const
Returns the line number corresponding to the special case list entry if the special case list contain...
Definition: SpecialCaseList.cpp:208
llvm::StringMap::end
iterator end()
Definition: StringMap.h:204
llvm::StringMap::find
iterator find(StringRef Key)
Definition: StringMap.h:217
llvm::MemoryBuffer
This interface provides simple read-only access to a block of memory, and provides simple methods for...
Definition: MemoryBuffer.h:50
llvm::vfs::FileSystem::getBufferForFile
llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > getBufferForFile(const Twine &Name, int64_t FileSize=-1, bool RequiresNullTerminator=true, bool IsVolatile=false)
This is a convenience method that opens a file, gets its content and then closes the file.
Definition: VirtualFileSystem.cpp:119
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::StringMapConstIterator
Definition: StringMap.h:26
llvm::ErrorOr::getError
std::error_code getError() const
Definition: ErrorOr.h:153
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:145
llvm::SpecialCaseList::parse
bool parse(const MemoryBuffer *MB, StringMap< size_t > &SectionsMap, std::string &Error)
Parses just-constructed SpecialCaseList entries from a memory buffer.
Definition: SpecialCaseList.cpp:125
llvm::MemoryBuffer::getBuffer
StringRef getBuffer() const
Definition: MemoryBuffer.h:69
llvm::SpecialCaseList::Section
Definition: SpecialCaseList.h:137
llvm::StringMap
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:110
llvm::SpecialCaseList::Sections
std::vector< Section > Sections
Definition: SpecialCaseList.h:144
llvm::SpecialCaseList::Matcher::insert
bool insert(std::string Regexp, unsigned LineNumber, std::string &REError)
Definition: SpecialCaseList.cpp:28
llvm::TrigramIndex::insert
void insert(const std::string &Regex)
Inserts a new Regex into the index.
Definition: TrigramIndex.cpp:29
llvm::Regex::isLiteralERE
static bool isLiteralERE(StringRef Str)
If this function returns true, ^Str$ is an extended regular expression that matches Str and only Str.
Definition: Regex.cpp:212
llvm::SpecialCaseList::SpecialCaseList
SpecialCaseList()=default
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::SpecialCaseList::createOrDie
static std::unique_ptr< SpecialCaseList > createOrDie(const std::vector< std::string > &Paths, llvm::vfs::FileSystem &FS)
Parses the special case list entries from files.
Definition: SpecialCaseList.cpp:90
Regex.h
llvm::Regex::isValid
bool isValid(std::string &Error) const
isValid - returns the error encountered during regex compilation, if any.
Definition: Regex.cpp:72
llvm::X86AS::FS
@ FS
Definition: X86.h:200
llvm::SpecialCaseList::Matcher::match
unsigned match(StringRef Query) const
Definition: SpecialCaseList.cpp:60
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
VirtualFileSystem.h
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
llvm::vfs::FileSystem
The virtual file system interface.
Definition: VirtualFileSystem.h:268
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
SpecialCaseList.h
SmallVector.h
llvm::ErrorOr::get
reference get()
Definition: ErrorOr.h:150
llvm::ErrorOr
Represents either an error or a value T.
Definition: ErrorOr.h:56
llvm::Regex
Definition: Regex.h:28
llvm::StringRef::split
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:689