Skip to content

Commit d70d6fa

Browse files
author
bjjwwang
committed
Read the comments in PullRequest (vibe-kanban 78898480)
#1789 Could you read comments in this PR?
1 parent bbb2c39 commit d70d6fa

File tree

3 files changed

+78
-32
lines changed

3 files changed

+78
-32
lines changed

svf/include/Util/Options.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -268,9 +268,10 @@ class Options
268268
// float precision for symbolic abstraction
269269
static const Option<u32_t> AEPrecision;
270270

271-
/// If true, analyze from all entry points (functions without callers)
272-
/// instead of only from main. Useful for library code without main function.
273-
static const Option<bool> AEMultiEntry;
271+
/// Comma-separated list of function names to use as analysis entry points.
272+
/// If empty (default), all functions without callers are used as entry points.
273+
/// Example: -ae-entry-funcs="main,init,setup"
274+
static const Option<std::string> AEEntryFuncs;
274275
};
275276
} // namespace SVF
276277

svf/lib/AE/Svfexe/AbstractInterpretation.cpp

Lines changed: 70 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "WPA/Andersen.h"
3636
#include <cmath>
3737
#include <deque>
38+
#include <sstream>
3839

3940
using namespace SVF;
4041
using namespace SVFUtil;
@@ -163,13 +164,47 @@ void AbstractInterpretation::initWTO()
163164
}
164165
}
165166

166-
/// Collect all entry point functions (functions without callers)
167+
/// Parse comma-separated function names from the -ae-entry-funcs option
168+
static Set<std::string> parseEntryFuncNames()
169+
{
170+
Set<std::string> funcNames;
171+
const std::string& entryFuncsStr = Options::AEEntryFuncs();
172+
173+
if (entryFuncsStr.empty())
174+
return funcNames;
175+
176+
std::stringstream ss(entryFuncsStr);
177+
std::string funcName;
178+
while (std::getline(ss, funcName, ','))
179+
{
180+
// Trim whitespace from function name
181+
size_t start = funcName.find_first_not_of(" \t");
182+
size_t end = funcName.find_last_not_of(" \t");
183+
if (start != std::string::npos && end != std::string::npos)
184+
{
185+
funcNames.insert(funcName.substr(start, end - start + 1));
186+
}
187+
else if (!funcName.empty())
188+
{
189+
funcNames.insert(funcName);
190+
}
191+
}
192+
return funcNames;
193+
}
194+
195+
/// Collect entry point functions for analysis.
196+
/// If -ae-entry-funcs is specified, only those functions are used.
197+
/// Otherwise, all functions without callers are collected as entry points.
167198
/// Uses a deque to allow efficient insertion at front for prioritizing main()
168199
std::deque<const FunObjVar*> AbstractInterpretation::collectProgEntryFuns()
169200
{
170201
std::deque<const FunObjVar*> entryFunctions;
171202
const CallGraph* callGraph = svfir->getCallGraph();
172203

204+
// Check if user specified explicit entry functions
205+
Set<std::string> specifiedFuncs = parseEntryFuncNames();
206+
bool hasSpecifiedFuncs = !specifiedFuncs.empty();
207+
173208
for (auto it = callGraph->begin(); it != callGraph->end(); ++it)
174209
{
175210
const CallGraphNode* cgNode = it->second;
@@ -179,8 +214,20 @@ std::deque<const FunObjVar*> AbstractInterpretation::collectProgEntryFuns()
179214
if (fun->isDeclaration())
180215
continue;
181216

182-
// Check if function has no callers (entry point)
183-
if (cgNode->getInEdges().empty())
217+
bool shouldInclude = false;
218+
219+
if (hasSpecifiedFuncs)
220+
{
221+
// Use only functions specified by -ae-entry-funcs
222+
shouldInclude = specifiedFuncs.count(fun->getName()) > 0;
223+
}
224+
else
225+
{
226+
// Default: use functions without callers (entry points)
227+
shouldInclude = cgNode->getInEdges().empty();
228+
}
229+
230+
if (shouldInclude)
184231
{
185232
// If main exists, put it first for priority using deque's push_front
186233
if (fun->getName() == "main")
@@ -194,6 +241,23 @@ std::deque<const FunObjVar*> AbstractInterpretation::collectProgEntryFuns()
194241
}
195242
}
196243

244+
// Warn if specified functions were not found
245+
if (hasSpecifiedFuncs)
246+
{
247+
Set<std::string> foundFuncs;
248+
for (const FunObjVar* fun : entryFunctions)
249+
{
250+
foundFuncs.insert(fun->getName());
251+
}
252+
for (const std::string& name : specifiedFuncs)
253+
{
254+
if (foundFuncs.count(name) == 0)
255+
{
256+
SVFUtil::errs() << "Warning: Specified entry function '" << name << "' not found\n";
257+
}
258+
}
259+
}
260+
197261
return entryFunctions;
198262
}
199263

@@ -203,34 +267,15 @@ void AbstractInterpretation::clearAbstractTrace()
203267
abstractTrace.clear();
204268
}
205269

206-
/// Program entry - analyze from main if exists, otherwise analyze from all entry points
270+
/// Program entry - analyze from all entry points (multi-entry analysis is the default)
207271
void AbstractInterpretation::analyse()
208272
{
209273
initWTO();
210274
// handle Global ICFGNode of SVFModule
211275
handleGlobalNode();
212276

213-
// If -ae-multientry is set, always use multi-entry analysis
214-
if (Options::AEMultiEntry())
215-
{
216-
SVFUtil::outs() << "Multi-entry analysis enabled, analyzing from all entry points...\n";
217-
analyzeFromAllProgEntries();
218-
return;
219-
}
220-
221-
// Default behavior: start from main if exists
222-
if (const CallGraphNode* cgn = svfir->getCallGraph()->getCallGraphNode("main"))
223-
{
224-
// Use worklist-based function handling instead of recursive WTO component handling
225-
const ICFGNode* mainEntry = icfg->getFunEntryICFGNode(cgn->getFunction());
226-
handleFunction(mainEntry);
227-
}
228-
else
229-
{
230-
// No main function found, analyze from all entry points (library code)
231-
SVFUtil::outs() << "No main function found, analyzing from all entry points...\n";
232-
analyzeFromAllProgEntries();
233-
}
277+
// Always use multi-entry analysis from all entry points
278+
analyzeFromAllProgEntries();
234279
}
235280

236281
/// Analyze all entry points (functions without callers) - for whole-program analysis without main

svf/lib/Util/Options.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -832,10 +832,10 @@ const Option<u32_t> Options::AEPrecision(
832832
0
833833
);
834834

835-
const Option<bool> Options::AEMultiEntry(
836-
"ae-multientry",
837-
"Analyze from all entry points (functions without callers) instead of only main. Useful for library code.",
838-
false
835+
const Option<std::string> Options::AEEntryFuncs(
836+
"ae-entry-funcs",
837+
"Comma-separated list of function names to use as analysis entry points. If empty, all functions without callers are used.",
838+
""
839839
);
840840

841841
} // namespace SVF.

0 commit comments

Comments
 (0)