Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions include/phasar/PhasarLLVM/ControlFlow/ExternCallbackModel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/******************************************************************************
* Copyright (c) 2026 Fabian Schiebel.
* All rights reserved. This program and the accompanying materials are made
* available under the terms of LICENSE.txt.
*
* Contributors:
* Fabian Schiebel and others
*****************************************************************************/

#ifndef PHASAR_PHASARLLVM_CONTROLFLOW_EXTERNCALLBACKMODEL_H
#define PHASAR_PHASARLLVM_CONTROLFLOW_EXTERNCALLBACKMODEL_H

#include "llvm/ADT/StringRef.h"
#include "llvm/IR/Function.h"

namespace psr {
class LLVMProjectIRDB;

/// \brief Provides utilities to model calls through known external callback
/// brokers.
///
/// The inserted model keeps the original broker call and adds a regular call to
/// the callback argument, so later analyses still see an ordinary call-site.
class ExternCallbackModel {
public:
static constexpr llvm::StringLiteral ModelPrefix = "__psrExternCallbackModel";

/// Rewrites all supported external callback call-sites in \p IRDB.
///
/// \returns the number of rewritten call-sites.
static size_t rewriteCalls(LLVMProjectIRDB &IRDB);

/// Returns true, if a function was generated by the ExternCallbackModel.
[[nodiscard]] static bool isPhasarGenerated(const llvm::Function &F) noexcept;
};
} // namespace psr

#endif // PHASAR_PHASARLLVM_CONTROLFLOW_EXTERNCALLBACKMODEL_H
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ class Resolver;
/// Constructs a call-graph using the given CGResolver to resolve indirect
/// calls.
///
/// This overload does not mutate the IRDB. Use
/// buildLLVMBasedCallGraphWithExternCallbackModels() if PhASAR should insert
/// its model functions first.
///
/// Uses a fixpoint iteration, if
/// `CGResolver.mutatesHelperAnalysisInformation()` returns true and the
/// soundness S is not Soundness::Unsound.
Expand All @@ -40,9 +44,24 @@ buildLLVMBasedCallGraph(const LLVMProjectIRDB &IRDB, Resolver &CGResolver,
llvm::ArrayRef<const llvm::Function *> EntryPoints,
Soundness S = Soundness::Soundy);

/// May insert model functions for known external callback brokers before the
/// call-graph is built.
/// If CGResolver owns helper-analysis state that should include generated model
/// functions, rewrite the IRDB before constructing that state or use a CGType
/// overload.
[[nodiscard]] LLVMBasedCallGraph
buildLLVMBasedCallGraphWithExternCallbackModels(
LLVMProjectIRDB &IRDB, Resolver &CGResolver,
llvm::ArrayRef<const llvm::Function *> EntryPoints,
Soundness S = Soundness::Soundy);

/// Constructs a call-graph using the given CGResolver to resolve indirect
/// calls.
///
/// This overload does not mutate the IRDB. Use
/// buildLLVMBasedCallGraphWithExternCallbackModels() if PhASAR should insert
/// its model functions first.
///
/// Uses a fixpoint iteration, if
/// `CGResolver.mutatesHelperAnalysisInformation()` returns true and the
/// soundness S is not Soundness::Unsound.
Expand All @@ -59,6 +78,27 @@ buildLLVMBasedCallGraph(const LLVMProjectIRDB &IRDB, Resolver &CGResolver,
llvm::ArrayRef<std::string> EntryPoints,
Soundness S = Soundness::Soundy);

/// May insert model functions for known external callback brokers before the
/// call-graph is built.
/// If CGResolver owns helper-analysis state that should include generated model
/// functions, rewrite the IRDB before constructing that state or use a CGType
/// overload.
[[nodiscard]] LLVMBasedCallGraph
buildLLVMBasedCallGraphWithExternCallbackModels(
LLVMProjectIRDB &IRDB, Resolver &CGResolver,
llvm::ArrayRef<std::string> EntryPoints, Soundness S = Soundness::Soundy);

/// Kept for compatibility with LLVMBasedICFG. See the constructor of
/// LLVMBasedICFG::LLVMBasedICFG(LLVMProjectIRDB *, CallGraphAnalysisType,
/// llvm::ArrayRef<std::string>, DIBasedTypeHierarchy *, LLVMAliasInfoRef,
/// Soundness, bool) for more information.
[[nodiscard]] LLVMBasedCallGraph
buildLLVMBasedCallGraph(LLVMProjectIRDB &IRDB, CallGraphAnalysisType CGType,
llvm::ArrayRef<const llvm::Function *> EntryPoints,
DIBasedTypeHierarchy *TH, LLVMVFTableProvider &VTP,
LLVMAliasInfoRef PT = nullptr,
Soundness S = Soundness::Soundy);

/// Kept for compatibility with LLVMBasedICFG. See the constructor of
/// LLVMBasedICFG::LLVMBasedICFG(LLVMProjectIRDB *, CallGraphAnalysisType,
/// llvm::ArrayRef<std::string>, DIBasedTypeHierarchy *, LLVMAliasInfoRef,
Expand All @@ -70,6 +110,17 @@ buildLLVMBasedCallGraph(LLVMProjectIRDB &IRDB, CallGraphAnalysisType CGType,
LLVMAliasInfoRef PT = nullptr,
Soundness S = Soundness::Soundy);

/// Kept for compatibility with LLVMBasedICFG. See the constructor of
/// LLVMBasedICFG::LLVMBasedICFG(LLVMProjectIRDB *, CallGraphAnalysisType,
/// llvm::ArrayRef<std::string>, DIBasedTypeHierarchy *, LLVMAliasInfoRef,
/// Soundness, bool) for more information.
[[nodiscard]] LLVMBasedCallGraph
buildLLVMBasedCallGraph(LLVMProjectIRDB &IRDB, CallGraphAnalysisType CGType,
llvm::ArrayRef<std::string> EntryPoints,
DIBasedTypeHierarchy *TH, LLVMVFTableProvider &VTP,
LLVMAliasInfoRef PT = nullptr,
Soundness S = Soundness::Soundy);

/// Kept for compatibility with LLVMBasedICFG. See the constructor of
/// LLVMBasedICFG::LLVMBasedICFG(LLVMProjectIRDB *, CallGraphAnalysisType,
/// llvm::ArrayRef<std::string>, DIBasedTypeHierarchy *, LLVMAliasInfoRef,
Expand Down
7 changes: 6 additions & 1 deletion include/phasar/PhasarLLVM/ControlFlow/LLVMBasedICFG.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "phasar/ControlFlow/CallGraph.h"
#include "phasar/ControlFlow/CallGraphAnalysisType.h"
#include "phasar/ControlFlow/ICFGBase.h"
#include "phasar/PhasarLLVM/ControlFlow/ExternCallbackModel.h"
#include "phasar/PhasarLLVM/ControlFlow/GlobalCtorsDtorsModel.h"
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedCFG.h"
#include "phasar/PhasarLLVM/ControlFlow/LLVMBasedCallGraph.h"
Expand Down Expand Up @@ -74,6 +75,9 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
/// \param IncludeGlobals Properly include global constructors/destructors
/// into the ICFG, if true. Requires to generate artificial functions into the
/// IRDB. True by default
///
/// Note that LLVMBasedICFG may also insert model functions for known external
/// callback brokers, independent of IncludeGlobals.
explicit LLVMBasedICFG(LLVMProjectIRDB *IRDB, CallGraphAnalysisType CGType,
llvm::ArrayRef<std::string> EntryPoints = {},
DIBasedTypeHierarchy *TH = nullptr,
Expand Down Expand Up @@ -132,7 +136,8 @@ class LLVMBasedICFG : public LLVMBasedCFG, public ICFGBase<LLVMBasedICFG> {
/// Returns true, if a function was generated by phasar.
[[nodiscard]] static bool
isPhasarGenerated(const llvm::Function &F) noexcept {
return GlobalCtorsDtorsModel::isPhasarGenerated(F);
return GlobalCtorsDtorsModel::isPhasarGenerated(F) ||
ExternCallbackModel::isPhasarGenerated(F);
}

using CFGBase::print;
Expand Down
Loading
Loading