diff --git a/SVF-osx/Release-build/bin/ae b/SVF-osx/Release-build/bin/ae index ed1ff673..dd43ac77 100755 Binary files a/SVF-osx/Release-build/bin/ae and b/SVF-osx/Release-build/bin/ae differ diff --git a/SVF-osx/Release-build/include/AE/Core/AbstractState.h b/SVF-osx/Release-build/include/AE/Core/AbstractState.h index 86041311..0848b649 100644 --- a/SVF-osx/Release-build/include/AE/Core/AbstractState.h +++ b/SVF-osx/Release-build/include/AE/Core/AbstractState.h @@ -95,6 +95,8 @@ class AbstractState // storeValue void storeValue(NodeID varId, AbstractValue val); + u32_t getAllocaInstByteSize(const AddrStmt *addr); + /// The physical address starts with 0x7f...... + idx static inline u32_t getVirtualMemAddress(u32_t idx) @@ -281,13 +283,14 @@ class AbstractState /// domain meet with other, important! other widen this. void meetWith(const AbstractState&other); - - /// Return int value from an expression if it is a numeral, otherwise return an approximate value - inline s32_t Interval2NumValue(const IntervalValue &e) const - { - //TODO: return concrete value; - return (s32_t) e.lb().getNumeral(); - } + /** + * if this NodeID in SVFIR is a pointer, get the pointee type + * e.g arr = (int*) malloc(10*sizeof(int)) + * getPointeeType(arr) -> return int + * we can set arr[0]='c', arr[1]='c', arr[2]='\0' + * @param call callnode of memset like api + */ + const SVFType* getPointeeElement(NodeID id); u32_t hash() const; @@ -395,7 +398,6 @@ class AbstractState _varToAbsVal.clear(); } - }; } diff --git a/SVF-osx/Release-build/include/AE/Svfexe/AEDetector.h b/SVF-osx/Release-build/include/AE/Svfexe/AEDetector.h new file mode 100644 index 00000000..9dca07d2 --- /dev/null +++ b/SVF-osx/Release-build/include/AE/Svfexe/AEDetector.h @@ -0,0 +1,322 @@ +//===- AEDetector.h -- Vulnerability Detectors---------------------------------// +// +// SVF: Static Value-Flow Analysis +// +// Copyright (C) <2013-> +// + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// +//===----------------------------------------------------------------------===// + + +// +// Created by Jiawei Wang on 2024/8/20. +// +#pragma once +#include +#include +#include "Util/SVFBugReport.h" + +namespace SVF +{ +/** + * @class AEDetector + * @brief Base class for all detectors. + */ +class AEDetector +{ +public: + /** + * @enum DetectorKind + * @brief Enumerates the types of detectors available. + */ + enum DetectorKind + { + BUF_OVERFLOW, ///< Detector for buffer overflow issues. + UNKNOWN, ///< Default type if the kind is not specified. + }; + + /** + * @brief Constructor initializes the detector kind to UNKNOWN. + */ + AEDetector(): kind(UNKNOWN) {} + + /** + * @brief Virtual destructor for safe polymorphic use. + */ + virtual ~AEDetector() = default; + + /** + * @brief Check if the detector is of the UNKNOWN kind. + * @param detector Pointer to the detector. + * @return True if the detector is of type UNKNOWN, false otherwise. + */ + static bool classof(const AEDetector* detector) + { + return detector->getKind() == AEDetector::UNKNOWN; + } + + /** + * @brief Pure virtual function for detecting issues within a node. + * @param as Reference to the abstract state. + * @param node Pointer to the ICFG node. + */ + virtual void detect(AbstractState& as, const ICFGNode* node) = 0; + + /** + * @brief Pure virtual function to report detected bugs. + */ + virtual void reportBug() = 0; + + /** + * @brief Get the kind of the detector. + * @return The kind of the detector. + */ + DetectorKind getKind() const + { + return kind; + } + +protected: + DetectorKind kind; ///< The kind of the detector. +}; + +/** + * @class AEException + * @brief Exception class for handling errors in Abstract Execution. + */ +class AEException : public std::exception +{ +public: + /** + * @brief Constructor initializes the exception with a message. + * @param message The error message. + */ + AEException(const std::string& message) + : msg_(message) {} + + /** + * @brief Provides the error message. + * @return The error message as a C-string. + */ + virtual const char* what() const throw() + { + return msg_.c_str(); + } + +private: + std::string msg_; ///< The error message. +}; + +/** + * @class BufOverflowDetector + * @brief Detector for identifying buffer overflow issues. + */ +class BufOverflowDetector : public AEDetector +{ + friend class AbstractInterpretation; +public: + /** + * @brief Constructor initializes the detector kind to BUF_OVERFLOW and sets up external API buffer overflow rules. + */ + BufOverflowDetector() + { + kind = BUF_OVERFLOW; + initExtAPIBufOverflowCheckRules(); + } + + /** + * @brief Destructor. + */ + ~BufOverflowDetector() = default; + + /** + * @brief Check if the detector is of the BUF_OVERFLOW kind. + * @param detector Pointer to the detector. + * @return True if the detector is of type BUF_OVERFLOW, false otherwise. + */ + static bool classof(const AEDetector* detector) + { + return detector->getKind() == AEDetector::BUF_OVERFLOW; + } + + /** + * @brief Updates the offset of a GEP object from its base. + * @param gepAddrs Address value for GEP. + * @param objAddrs Address value for the object. + * @param offset The interval value of the offset. + */ + void updateGepObjOffsetFromBase(AddressValue gepAddrs, + AddressValue objAddrs, + IntervalValue offset); + + /** + * @brief Detect buffer overflow issues within a node. + * @param as Reference to the abstract state. + * @param node Pointer to the ICFG node. + */ + void detect(AbstractState& as, const ICFGNode*); + + /** + * @brief Adds an offset to a GEP object. + * @param obj Pointer to the GEP object. + * @param offset The interval value of the offset. + */ + void addToGepObjOffsetFromBase(const GepObjVar* obj, const IntervalValue& offset) + { + gepObjOffsetFromBase[obj] = offset; + } + + /** + * @brief Checks if a GEP object has an associated offset. + * @param obj Pointer to the GEP object. + * @return True if the GEP object has an offset, false otherwise. + */ + bool hasGepObjOffsetFromBase(const GepObjVar* obj) const + { + return gepObjOffsetFromBase.find(obj) != gepObjOffsetFromBase.end(); + } + + /** + * @brief Retrieves the offset of a GEP object from its base. + * @param obj Pointer to the GEP object. + * @return The interval value of the offset. + */ + IntervalValue getGepObjOffsetFromBase(const GepObjVar* obj) const + { + if (hasGepObjOffsetFromBase(obj)) + return gepObjOffsetFromBase.at(obj); + else + assert(false && "GepObjVar not found in gepObjOffsetFromBase"); + } + + /** + * @brief Retrieves the access offset for a given object and GEP statement. + * @param as Reference to the abstract state. + * @param objId The ID of the object. + * @param gep Pointer to the GEP statement. + * @return The interval value of the access offset. + */ + IntervalValue getAccessOffset(AbstractState& as, NodeID objId, const GepStmt* gep); + + /** + * @brief Adds a bug to the reporter based on an exception. + * @param e The exception that was thrown. + * @param node Pointer to the ICFG node where the bug was detected. + */ + void addBugToReporter(const AEException& e, const ICFGNode* node) + { + const SVFInstruction* inst = nullptr; + + // Determine the instruction associated with the ICFG node + if (const CallICFGNode* call = SVFUtil::dyn_cast(node)) + { + inst = call->getCallSite(); // If the node is a call node, get the call site instruction + } + else + { + inst = node->getSVFStmts().back()->getInst(); // Otherwise, get the last instruction of the node's + // statements + } + + GenericBug::EventStack eventStack; + SVFBugEvent sourceInstEvent(SVFBugEvent::EventType::SourceInst, inst); + eventStack.push_back(sourceInstEvent); // Add the source instruction event to the event stack + + if (eventStack.empty()) + { + return; // If the event stack is empty, return early + } + + std::string loc = eventStack.back().getEventLoc(); // Get the location of the last event in the stack + + // Check if the bug at this location has already been reported + if (bugLoc.find(loc) != bugLoc.end()) + { + return; // If the bug location is already reported, return early + } + else + { + bugLoc.insert(loc); // Otherwise, mark this location as reported + } + + // Add the bug to the recorder with details from the event stack + recoder.addAbsExecBug(GenericBug::FULLBUFOVERFLOW, eventStack, 0, 0, 0, 0); + nodeToBugInfo[node] = e.what(); // Record the exception information for the node + } + + /** + * @brief Reports all detected buffer overflow bugs. + */ + void reportBug() + { + if (!nodeToBugInfo.empty()) + { + std::cerr << "######################Buffer Overflow (" + std::to_string(nodeToBugInfo.size()) + + " found)######################\n"; + std::cerr << "---------------------------------------------\n"; + for (const auto& it : nodeToBugInfo) + { + std::cerr << it.second << "\n---------------------------------------------\n"; + } + } + } + + /** + * @brief Initializes external API buffer overflow check rules. + */ + void initExtAPIBufOverflowCheckRules(); + + /** + * @brief Handles external API calls related to buffer overflow detection. + * @param as Reference to the abstract state. + * @param call Pointer to the call ICFG node. + */ + void detectExtAPI(AbstractState& as, const CallICFGNode *call); + + /** + * @brief Checks if memory can be safely accessed. + * @param as Reference to the abstract state. + * @param value Pointer to the SVF value. + * @param len The interval value representing the length of the memory access. + * @return True if the memory access is safe, false otherwise. + */ + bool canSafelyAccessMemory(AbstractState& as, const SVFValue *value, const IntervalValue &len); + +private: + /** + * @brief Detects buffer overflow in 'strcat' function calls. + * @param as Reference to the abstract state. + * @param call Pointer to the call ICFG node. + * @return True if a buffer overflow is detected, false otherwise. + */ + bool detectStrcat(AbstractState& as, const CallICFGNode *call); + + /** + * @brief Detects buffer overflow in 'strcpy' function calls. + * @param as Reference to the abstract state. + * @param call Pointer to the call ICFG node. + * @return True if a buffer overflow is detected, false otherwise. + */ + bool detectStrcpy(AbstractState& as, const CallICFGNode *call); + +private: + Map gepObjOffsetFromBase; ///< Maps GEP objects to their offsets from the base. + Map>> extAPIBufOverflowCheckRules; ///< Rules for checking buffer overflows in external APIs. + Set bugLoc; ///< Set of locations where bugs have been reported. + SVFBugReport recoder; ///< Recorder for abstract execution bugs. + Map nodeToBugInfo; ///< Maps ICFG nodes to bug information. +}; +} diff --git a/SVF-osx/Release-build/include/AE/Svfexe/AbstractInterpretation.h b/SVF-osx/Release-build/include/AE/Svfexe/AbstractInterpretation.h index 8b4d90ae..cba9ea99 100644 --- a/SVF-osx/Release-build/include/AE/Svfexe/AbstractInterpretation.h +++ b/SVF-osx/Release-build/include/AE/Svfexe/AbstractInterpretation.h @@ -27,11 +27,12 @@ // Xiao Cheng, Jiawei Wang and Yulei Sui. Precise Sparse Abstract Execution via Cross-Domain Interaction. // 46th International Conference on Software Engineering. (ICSE24) // - +#pragma once +#include "AE/Core/AbstractState.h" #include "AE/Core/ICFGWTO.h" +#include "AE/Svfexe/AEDetector.h" #include "Util/SVFBugReport.h" #include "WPA/Andersen.h" -#include "AE/Core/AbstractState.h" namespace SVF { @@ -41,12 +42,6 @@ class AEAPI; template class FILOWorkList; -enum class AEKind -{ - AbstractExecution, - BufOverflowChecker, -}; - /// AEStat: Statistic for AE class AEStat : public SVFStat { @@ -67,14 +62,12 @@ class AEStat : public SVFStat void finializeStat(); void performStat() override; - void reportBug(); public: AbstractInterpretation* _ae; s32_t count{0}; std::string memory_usage; std::string memUsage; - std::string bugStr; u32_t& getFunctionTrace() @@ -108,6 +101,7 @@ class AbstractInterpretation { friend class AEStat; friend class AEAPI; + friend class BufOverflowDetector; public: enum ExtAPIType { UNCLASSIFIED, MEMCPY, MEMSET, STRCPY, STRCAT }; @@ -123,14 +117,15 @@ class AbstractInterpretation /// Program entry void analyse(); - static bool classof(const AbstractInterpretation* ae) + static AbstractInterpretation& getAEInstance() { - return ae->getKind() == AEKind::AbstractExecution; + static AbstractInterpretation instance; + return instance; } - AEKind getKind() const + void addDetector(std::unique_ptr detector) { - return _kind; + detectors.push_back(std::move(detector)); } protected: @@ -233,13 +228,6 @@ class AbstractInterpretation */ virtual void initExtFunMap(); - /** - * get byte size of alloca inst - * - * @param addr Address Stmt like malloc/calloc/ALLOCA/StackAlloc - * @return the byte size e.g. int32_t a[10] -> return 40 - */ - u32_t getAllocaInstByteSize(AbstractState& as, const AddrStmt *addr); /** * get byte size of alloca inst @@ -259,16 +247,6 @@ class AbstractInterpretation */ IntervalValue getStrlen(AbstractState& as, const SVF::SVFValue *strValue); - /** - * get memory allocation size - * e.g arr = new int[10] - * .... - * memset(arr, 1, 10* sizeof(int)) - * when we trace the 'arr', we can get the alloc size [40, 40] - * @param value to be traced - * @return IntervalValue of allocation size - */ - IntervalValue traceMemoryAllocationSize(AbstractState& as, const SVFValue *value); /** * execute strcpy in abstract execution * e.g arr = new char[10] @@ -305,23 +283,9 @@ class AbstractInterpretation */ virtual void handleMemset(AbstractState& as, const SVFValue* dst, IntervalValue elem, IntervalValue len); - /** - * if this NodeID in SVFIR is a pointer, get the pointee type - * e.g arr = (int*) malloc(10*sizeof(int)) - * getPointeeType(arr) -> return int - * we can set arr[0]='c', arr[1]='c', arr[2]='\0' - * @param call callnode of memset like api - */ - const SVFType* getPointeeElement(AbstractState& as, NodeID id); void collectCheckPoint(); void checkPointAllSet(); - // helper functions for traceMemoryAllocationSize and canSafelyAccessMemory - void AccessMemoryViaRetNode(const CallICFGNode *callnode, SVF::FILOWorkList& worklist, Set& visited); - void AccessMemoryViaCopyStmt(const CopyStmt *copy, SVF::FILOWorkList& worklist, Set& visited); - void AccessMemoryViaLoadStmt(AbstractState& as, const LoadStmt *load, SVF::FILOWorkList& worklist, Set& visited); - void AccessMemoryViaCallArgs(const SVF::SVFArgument *arg, SVF::FILOWorkList& worklist, Set& visited); - void updateStateOnAddr(const AddrStmt *addr); @@ -349,20 +313,16 @@ class AbstractInterpretation /// protected data members, also used in subclasses - SVFIR* _svfir; + SVFIR* svfir; /// Execution State, used to store the Interval Value of every SVF variable - AEAPI* _api{nullptr}; + AEAPI* api{nullptr}; - ICFG* _icfg; - AEStat* _stat; - AEKind _kind; + ICFG* icfg; + AEStat* stat; - Set _bugLoc; - SVFBugReport _recoder; - std::vector _callSiteStack; - Map _nodeToBugInfo; - Map _funcToWTO; - Set _recursiveFuns; + std::vector callSiteStack; + Map funcToWTO; + Set recursiveFuns; private: // helper functions in handleCallSite @@ -379,29 +339,33 @@ class AbstractInterpretation AbstractState& getAbsStateFromTrace(const ICFGNode* node) { - const ICFGNode* repNode = _icfg->getRepNode(node); - if (_abstractTrace.count(repNode) == 0) + const ICFGNode* repNode = icfg->getRepNode(node); + if (abstractTrace.count(repNode) == 0) { assert(0 && "No preAbsTrace for this node"); } else { - return _abstractTrace[repNode]; + return abstractTrace[repNode]; } } bool hasAbsStateFromTrace(const ICFGNode* node) { - const ICFGNode* repNode = _icfg->getRepNode(node); - return _abstractTrace.count(repNode) != 0; + const ICFGNode* repNode = icfg->getRepNode(node); + return abstractTrace.count(repNode) != 0; } protected: // there data should be shared with subclasses - Map> _func_map; - Set _checkpoints; - Set _checkpoint_names; - Map _abstractTrace; // abstract states immediately after nodes - std::string _moduleName; + Map> func_map; + Set checkpoints; + Set checkpoint_names; + Map + abstractTrace; // abstract states immediately after nodes + std::string moduleName; + + std::vector> detectors; + }; } \ No newline at end of file diff --git a/SVF-osx/Release-build/include/AE/Svfexe/BufOverflowChecker.h b/SVF-osx/Release-build/include/AE/Svfexe/BufOverflowChecker.h deleted file mode 100644 index 733738d6..00000000 --- a/SVF-osx/Release-build/include/AE/Svfexe/BufOverflowChecker.h +++ /dev/null @@ -1,216 +0,0 @@ -//===- BufOverflowChecker.cpp -- BufOVerflowChecker Client for Abstract Execution---// -// -// SVF: Static Value-Flow Analysis -// -// Copyright (C) <2013-> -// - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. - -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . -// -//===----------------------------------------------------------------------===// - - -// -// Created by Jiawei Wang on 2024/1/12. -// The implementation is based on -// Xiao Cheng, Jiawei Wang and Yulei Sui. Precise Sparse Abstract Execution via Cross-Domain Interaction. -// 46th International Conference on Software Engineering. (ICSE24) -// - -#include "AE/Svfexe/AbstractInterpretation.h" - -namespace SVF -{ - -struct BufOverflowException: public std::exception -{ -public: - BufOverflowException(std::string msg, u32_t allocLb, - u32_t allocUb, u32_t accessLb, u32_t accessUb, const SVFValue* allocVal) : - _msg(msg), _allocLb(allocLb), _allocUb(allocUb), - _accessLb(accessLb), _accessUb(accessUb), _allocVar(allocVal) - { - } - - u32_t getAllocLb() const - { - return _allocLb; - } - - void setAllocLb(u32_t allocLb) - { - _allocLb = allocLb; - } - - u32_t getAllocUb() const - { - return _allocUb; - } - - void setAllocUb(u32_t allocUb) - { - _allocUb = allocUb; - } - - u32_t getAccessLb() const - { - return _accessLb; - } - - void setAccessLb(u32_t accessLb) - { - _accessLb = accessLb; - } - - u32_t getAccessUb() const - { - return _accessUb; - } - - void setAccessUb(u32_t accessUb) - { - _accessUb = accessUb; - } - - const SVFValue* getAllocVar() const - { - return _allocVar; - } - - const char* what() const noexcept override - { - return _msg.c_str(); - } - - -protected: - std::string _msg; - u32_t _allocLb, _allocUb, _accessLb, _accessUb; - const SVFValue* _allocVar; -}; - -class BufOverflowChecker: public AbstractInterpretation -{ -public: - BufOverflowChecker() : AbstractInterpretation() - { - initExtFunMap(); - _kind = AEKind::BufOverflowChecker; - initExtAPIBufOverflowCheckRules(); - } - - static bool classof(const AbstractInterpretation* ae) - { - return ae->getKind() == AEKind::BufOverflowChecker; - } - -protected: - /** - * the map of external function to its API type - * - * it initialize the ext apis about buffer overflow checking - */ - virtual void initExtFunMap() override; - - /** - * the map of ext apis of buffer overflow checking rules - * - * it initialize the rules of extapis about buffer overflow checking - * e.g. memcpy(dst, src, sz) -> we check allocSize(dst)>=sz and allocSize(src)>=sz - */ - void initExtAPIBufOverflowCheckRules(); - - /** - * handle external function call regarding buffer overflow checking - * e.g. memcpy(dst, src, sz) -> we check allocSize(dst)>=sz and allocSize(src)>=sz - * - * @param call call node whose callee is external function - */ - void handleExtAPI(const CallICFGNode *call) override; - /** - * detect buffer overflow from strcpy like apis - * e.g. strcpy(dst, src), if dst is shorter than src, we will throw buffer overflow - * - * @param call call node whose callee is strcpy-like external function - * @return true if the buffer overflow is detected - */ - bool detectStrcpy(const CallICFGNode *call); - /** - * detect buffer overflow from strcat like apis - * e.g. strcat(dst, src), if dst is shorter than src, we will throw buffer overflow - * - * @param call call node whose callee is strcpy-like external function - * @return true if the buffer overflow is detected - */ - bool detectStrcat(const CallICFGNode *call); - - /** - * detect buffer overflow by giving a var and a length - * e.g. int x[10]; x[10] = 1; - * we call canSafelyAccessMemory(x, 11 * sizeof(int)); - * - * @param value the value of the buffer overflow checkpoint - * @param len the length of the buffer overflow checkpoint - * @return true if the buffer overflow is detected - */ - bool canSafelyAccessMemory(const SVFValue *value, const IntervalValue &len, const ICFGNode *curNode); - -private: - /** - * handle SVF statement regarding buffer overflow checking - * - * @param stmt SVF statement - */ - virtual void handleSVFStatement(const SVFStmt *stmt) override; - - // TODO: will delete later - virtual void handleSingletonWTO(const ICFGSingletonWTO *icfgSingletonWto) override - { - AbstractInterpretation::handleSingletonWTO(icfgSingletonWto); - const ICFGNode* repNode = _icfg->getRepNode(icfgSingletonWto->getICFGNode()); - if (_abstractTrace.count(repNode) == 0) - { - return; - } - const std::vector& worklist_vec = _icfg->getSubNodes(icfgSingletonWto->getICFGNode()); - - for (auto it = worklist_vec.begin(); it != worklist_vec.end(); ++it) - { - const ICFGNode* curNode = *it; - detectBufOverflow(curNode); - } - } - - /** - * check buffer overflow at ICFGNode which is a checkpoint - * - * @param node ICFGNode - * @return true if the buffer overflow is detected - */ - bool detectBufOverflow(const ICFGNode *node); - - /** - * add buffer overflow bug to recoder - * - * @param e the exception that is thrown by BufOverflowChecker - * @param node ICFGNode that causes the exception - */ - void addBugToRecoder(const BufOverflowException& e, const ICFGNode* node); - -private: - Map _addrToGep; - Map>> _extAPIBufOverflowCheckRules; - -}; -} \ No newline at end of file diff --git a/SVF-osx/Release-build/include/AE/Svfexe/ICFGSimplification.h b/SVF-osx/Release-build/include/AE/Svfexe/ICFGSimplification.h deleted file mode 100644 index 9c846d42..00000000 --- a/SVF-osx/Release-build/include/AE/Svfexe/ICFGSimplification.h +++ /dev/null @@ -1,44 +0,0 @@ -//===- ICFGSimplification.h -- Simplify ICFG----------------------------------// -// -// SVF: Static Value-Flow Analysis -// -// Copyright (C) <2013-> -// - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. - -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . -// -//===----------------------------------------------------------------------===// - - -// -// Created by Jiawei Wang on 2024/2/25. -// -// The implementation is based on -// Xiao Cheng, Jiawei Wang and Yulei Sui. Precise Sparse Abstract Execution via Cross-Domain Interaction. -// 46th International Conference on Software Engineering. (ICSE24) -#include "Graphs/ICFG.h" - -namespace SVF -{ - -class ICFGSimplification -{ -public: - ICFGSimplification() = default; - - virtual ~ICFGSimplification() = default; - - static void mergeAdjacentNodes(ICFG* icfg); -}; -} \ No newline at end of file diff --git a/SVF-osx/Release-build/lib/libSvfCore.a b/SVF-osx/Release-build/lib/libSvfCore.a index 6058e5c9..d4b77de1 100644 Binary files a/SVF-osx/Release-build/lib/libSvfCore.a and b/SVF-osx/Release-build/lib/libSvfCore.a differ diff --git a/SVF-osx/Release-build/lib/libSvfLLVM.a b/SVF-osx/Release-build/lib/libSvfLLVM.a index 1862fb80..d35dce78 100644 Binary files a/SVF-osx/Release-build/lib/libSvfLLVM.a and b/SVF-osx/Release-build/lib/libSvfLLVM.a differ