forked from HexHive/FuzzGen
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpreprocessor.h
275 lines (219 loc) · 11.1 KB
/
preprocessor.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
// ------------------------------------------------------------------------------------------------
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* ___ ___ ___ ___ ___ ___ ___
* /\__\ /\ \ /\__\ /\__\ /\__\ /\__\ /\ \
* /:/ _/_ \:\ \ /::| | /::| | /:/ _/_ /:/ _/_ \:\ \
* /:/ /\__\ \:\ \ /:/:| | /:/:| | /:/ /\ \ /:/ /\__\ \:\ \
* /:/ /:/ / ___ \:\ \ /:/|:| |__ /:/|:| |__ /:/ /::\ \ /:/ /:/ _/_ _____\:\ \
* /:/_/:/ / /\ \ \:\__\ /:/ |:| /\__\ /:/ |:| /\__\ /:/__\/\:\__\ /:/_/:/ /\__\ /::::::::\__\
* \:\/:/ / \:\ \ /:/ / \/__|:|/:/ / \/__|:|/:/ / \:\ \ /:/ / \:\/:/ /:/ / \:\~~\~~\/__/
* \::/__/ \:\ /:/ / |:/:/ / |:/:/ / \:\ /:/ / \::/_/:/ / \:\ \
* \:\ \ \:\/:/ / |::/ / |::/ / \:\/:/ / \:\/:/ / \:\ \
* \:\__\ \::/ / |:/ / |:/ / \::/ / \::/ / \:\__\
* \/__/ \/__/ |/__/ |/__/ \/__/ \/__/ \/__/
*
* FuzzGen - Automatic Fuzzer Generation
*
*
*
* preprocessor.h
*
* Header file for preprocessor.cpp
*
*/
// ------------------------------------------------------------------------------------------------
#ifndef LIBRARY_PREPROCESSOR_H
#define LIBRARY_PREPROCESSOR_H
#include "clang/Frontend/CompilerInstance.h" // clang includes
#include "clang/Frontend/FrontendActions.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/GlobalDecl.h"
#include "clang/AST/Mangle.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/AST/AST.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Type.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Signals.h"
#include <iostream> // c++ includes
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <stdio.h> // c includes (for file locks)
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <time.h>
#include <linux/limits.h>
/* MACROs */
#define CURRENT_VERSION "v3.1" // fuzzgen preprocessor current version
#define DEFAULT_META_FILENAME "lib.meta" // default output file for metadata
using namespace clang;
using namespace clang::tooling;
using namespace llvm;
using namespace std;
/* banner string to put on top of metadata file */
const string banner = R"(#
# ___ ___ ___ ___ ___ ___ ___
# /\__\ /\ \ /\__\ /\__\ /\__\ /\__\ /\ \
# /:/ _/_ \:\ \ /::| | /::| | /:/ _/_ /:/ _/_ \:\ \
# /:/ /\__\ \:\ \ /:/:| | /:/:| | /:/ /\ \ /:/ /\__\ \:\ \
# /:/ /:/ / ___ \:\ \ /:/|:| |__ /:/|:| |__ /:/ /::\ \ /:/ /:/ _/_ _____\:\ \
# /:/_/:/ / /\ \ \:\__\ /:/ |:| /\__\ /:/ |:| /\__\ /:/__\/\:\__\ /:/_/:/ /\__\ /::::::::\__\
# \:\/:/ / \:\ \ /:/ / \/__|:|/:/ / \/__|:|/:/ / \:\ \ /:/ / \:\/:/ /:/ / \:\~~\~~\/__/
# \::/__/ \:\ /:/ / |:/:/ / |:/:/ / \:\ /:/ / \::/_/:/ / \:\ \
# \:\ \ \:\/:/ / |::/ / |::/ / \:\/:/ / \:\/:/ / \:\ \
# \:\__\ \::/ / |:/ / |:/ / \::/ / \::/ / \:\__\
# \/__/ \/__/ |/__/ |/__/ \/__/ \/__/ \/__/
#
# FuzzGen - Automatic Fuzzer Generation
#)";
// ------------------------------------------------------------------------------------------------
// Recursively visit nodes from AST and analyze the "important" ones.
//
class Visitor : public RecursiveASTVisitor<Visitor> {
public:
/* class constructor */
Visitor(SourceManager &, set<string> &, set<string> &, map<string, set<string>> &,
map<uint64_t, vector<string>> &, map<uint64_t, string> &, map<string, set<string>> &,
map<string, set<string>> &, map<string, vector<string>> &, string);
/* callback when a function declaration is encountered */
bool VisitFunctionDecl(FunctionDecl *);
/* callback when a variable declaration is encountered */
bool VisitVarDecl(VarDecl *);
/* callback when a struct declaration is encountered */
bool VisitRecordDecl(RecordDecl *);
/* callback when a struct field is encountered */
bool VisitFieldDecl(FieldDecl *);
/* callback when a typedef declaration is encountered */
bool VisitTypedefDecl(TypedefDecl *);
/* callback when a enum declaration is encountered */
bool VisitEnumDecl(EnumDecl *);
/* callback when a statement is encounterned */
bool VisitStmt(Stmt *);
private:
SourceManager &srcMgr; // source manager object
set<string> &funHdrs, &gloHdrs; // store headers for each function
map<string, set<string>> &arrRefs; // store array arguments for each function
map<uint64_t, vector<string>> &strFlds; // store struct fields
map<uint64_t, string> &strAddrs; // store struct object addresses
map<string, set<string>> &signParams; // store signed parameters
map<string, set<string>> &constParams; // store constant parameters
map<string, vector<string>> ¶mNames; // store parameter names
string curFun, curMod; // current function and module names
map<string, int> param; // current function parameters
string libroot; // library root directory
/* push a global declaration to the globals table */
bool pushGlobal(NamedDecl *, string="");
/* check whether a qualified type is signed or not */
bool isUnsignedTy(QualType, string &);
};
// ------------------------------------------------------------------------------------------------
// Intermediate class that is actually a wrapper for the AST visitor.
//
class ASTProcessor : public ASTConsumer {
public:
/* class constructor */
ASTProcessor(set<string> &, set<string> &, map<string, set<string>> &,
map<uint64_t, vector<string>> &, map<uint64_t, string> &,
map<string, set<string>> &, map<string, set<string>> &,
map<string, vector<string>> &, string);
/* after the entire translation unit's AST has been parsed, this callback is invoked */
void HandleTranslationUnit(ASTContext& context) override;
private:
set<string> &funHdrs, &gloHdrs;
map<string, set<string>> &arrRefs;
map<uint64_t, vector<string>> &strFlds;
map<uint64_t, string> &strAddrs;
map<string, set<string>> &signParams;
map<string, set<string>> &constParams;
map<string, vector<string>> ¶mNames;
string libroot; // library root directory
};
// ------------------------------------------------------------------------------------------------
// Find all dependencies between #include directives.
//
class IncludesProcessor : public PPCallbacks {
public:
/* class constructor */
IncludesProcessor(CompilerInstance &, map<string, vector<string>> &, string);
protected:
/* callback that is invoked when an #include (or #import) is encountered */
virtual void InclusionDirective(SourceLocation, const Token &, StringRef, bool, CharSourceRange,
const FileEntry *, StringRef, StringRef, const clang::Module *,
SrcMgr::CharacteristicKind) override;
private:
CompilerInstance &compInst; // compiler instance from ASTFrontendAction
map<string, vector<string>> &incDeps; // include dependencies reference
string libroot; // library root directory
};
// ------------------------------------------------------------------------------------------------
// Catch diagnostic messages generated during compilation. As each file is processed individually,
// there will be #include dependencies, so many errors will be created. Here we are only interested
// in syntax analysis, so we don't care if compilation fails at later steps. To prevent these
// errors from flooding the terminal, we add a hook to catch n' kill them.
//
class FuzzGenDiagnosticConsumer : public clang::DiagnosticConsumer {
public:
/* hook to handle a diagnostic message */
void HandleDiagnostic(DiagnosticsEngine::Level, const Diagnostic &) override {
/* Don't do anything */
}
};
// ------------------------------------------------------------------------------------------------
// Main class for the clang plugin.
//
class FuzzGenPreprocessor : public ASTFrontendAction {
public:
/* class constructor */
FuzzGenPreprocessor();
protected:
/* create the AST consumer object */
unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &, StringRef) override;
/* callback before input processing */
bool BeginSourceFileAction (CompilerInstance &) override;
/* callback after input processing */
void EndSourceFileAction() override;
private:
set<string> funHdrs, // function:header entries
gloHdrs; // global symbol:header entries
map<string, set<string>> arrRefs; // function:[array parameter]+ entries
map<string, vector<string>> incDeps; // function:[array parameter]+ entries
map<uint64_t, vector<string>> strFlds; // RecordDecl address:struct fields
map<uint64_t, string> strAddrs; // RecordDecl address:struct name
map<string, set<string>> signParams; // function:[signed parameter]+ entries
map<string, set<string>> constParams; // function:[constant parameter]+ entries
map<string, vector<string>> paramNames; // function parameter names
string outfile; // metadata filename
string libroot; // library root directory
};
// ------------------------------------------------------------------------------------------------
#endif