From aefd65335537da9e30984ecf5af4bb825b613c18 Mon Sep 17 00:00:00 2001 From: hwk2077 Date: Tue, 12 Sep 2023 16:50:02 +0800 Subject: [PATCH] fix: switch state --- libs2ecore/src/S2EExecutor.cpp | 10 +- .../Plugins/Searchers/ValidPathSearcher.cpp | 137 ++++++++++-------- .../s2e/Plugins/Searchers/ValidPathSearcher.h | 6 +- 3 files changed, 90 insertions(+), 63 deletions(-) diff --git a/libs2ecore/src/S2EExecutor.cpp b/libs2ecore/src/S2EExecutor.cpp index fc023a4d..f9e78c7a 100644 --- a/libs2ecore/src/S2EExecutor.cpp +++ b/libs2ecore/src/S2EExecutor.cpp @@ -818,10 +818,10 @@ void S2EExecutor::stateSwitchTimerCallback(void *opaque) { void S2EExecutor::validPathSearcherStateSwitchCallback(void *opaque) { S2EExecutor *c = (S2EExecutor *) opaque; - // assert(env->current_tb == nullptr); + assert(env->current_tb == nullptr); if (g_s2e_state) { - // c->doLoadBalancing(); + c->doLoadBalancing(); S2EExecutionState *nextState = c->selectNextState(g_s2e_state); if (nextState) { g_s2e_state = nextState; @@ -830,9 +830,9 @@ void S2EExecutor::validPathSearcherStateSwitchCallback(void *opaque) { return; } } + libcpu_mod_timer(c->m_stateSwitchTimer, libcpu_get_clock_ms(host_clock) + 100); } - void S2EExecutor::initializeStateSwitchTimer() { m_stateSwitchTimer = libcpu_new_timer_ms(host_clock, &stateSwitchTimerCallback, this); libcpu_mod_timer(m_stateSwitchTimer, libcpu_get_clock_ms(host_clock) + 100); @@ -1928,7 +1928,11 @@ void S2EExecutor::setupTimersHandler() { bool S2EExecutor::suspendState(S2EExecutionState *state) { if (searcher) { searcher->removeState(state, nullptr); + g_s2e->getDebugStream() << "[states' size " << getStatesCount() << "] " + << "\n"; size_t r = states.erase(state); + g_s2e->getDebugStream() << "[states' size " << getStatesCount() << "] " + << "\n"; assert(r == 1); return true; } diff --git a/libs2eplugins/src/s2e/Plugins/Searchers/ValidPathSearcher.cpp b/libs2eplugins/src/s2e/Plugins/Searchers/ValidPathSearcher.cpp index a682904e..8c1ac8cf 100644 --- a/libs2eplugins/src/s2e/Plugins/Searchers/ValidPathSearcher.cpp +++ b/libs2eplugins/src/s2e/Plugins/Searchers/ValidPathSearcher.cpp @@ -49,13 +49,20 @@ klee::ExecutionState &ValidPathSearcher::selectState() { void ValidPathSearcher::update(klee::ExecutionState *current, const klee::StateSet &addedStates, const klee::StateSet &removedStates) { + if (!m_searcherActive) { + m_curState = dynamic_cast(current); + getDebugStream() << "[start stateID: " << m_curState->getID() << "] " + << "\n"; + m_searcherActive = true; + } + for (auto it : removedStates) { S2EExecutionState *removedState = dynamic_cast(it); auto found = m_idStateMap.find(removedState->getID()); if (found != m_idStateMap.end()) { - found->second.flag = INVALID; getDebugStream() << "[invalid stateID: " << found->second.state->getID() << "] " << "\n"; + m_idStateMap.erase(found); } } } @@ -76,15 +83,27 @@ void ValidPathSearcher::onStateFork(S2EExecutionState *state, const std::vector< getDebugStream() << "onStateFork" << '\n'; const uint32_t forkPC = state->regs()->getPc(); - getDebugStream() << "[forkPC: " << hexval(forkPC) << "] " - << "[stateID: " << hexval(state->getID()) << "] " - << "[new stateID: " << newStates[0]->getID() << "] " - << "[new stateID: " << newStates[1]->getID() << "] " + const uint32_t id0 = newStates[0]->getID(); + const uint32_t id1 = newStates[1]->getID(); + getDebugStream() << "[callerPC: " << hexval(m_callerPC) << "] " + << "[forkPC: " << hexval(forkPC) << "] " + << "[stateID: " << state->getID() << "] " + << "\n" + << "\t\t[new stateID: " << id0 << "] " + << "[condition: " << newConditions[0] << "] " + << "\n" + << "\t\t[new stateID: " << id1 << "] " + << "[condition: " << newConditions[1] << "] " << "\n"; - insertToForkStates(m_callerPC, forkPC, newStates[0]); - insertToForkStates(m_callerPC, forkPC, newStates[1]); + + m_forkStates[m_callerPC][forkPC].push_back(id0); + m_forkStates[m_callerPC][forkPC].push_back(id1); + m_idStateMap[id0] = {newStates[0], forkPC, UNVISITED, 0}; + m_idStateMap[id1] = {newStates[1], forkPC, UNVISITED, 0}; m_idStateMap[state->getID()].flag = VALID; - m_searcherActive = true; + // m_searcherActive = true; +// printForkStates(); +// printStateItems(); } void ValidPathSearcher::onTranslateBlockEnd(ExecutionSignal *signal, S2EExecutionState *state, TranslationBlock *tb, @@ -115,6 +134,9 @@ void ValidPathSearcher::onARMFunctionReturn(S2EExecutionState *state, uint32_t p << "\n"; m_curState = state; m_returnPC = pcReturn; + getDebugStream() << "[caller pc: " << hexval(m_functionCalRetMap[pcReturn]) << "] " + << "[return pc: " << hexval(pcReturn) << "] " + << "\n"; if (!m_searcherActive) { return; @@ -123,26 +145,11 @@ void ValidPathSearcher::onARMFunctionReturn(S2EExecutionState *state, uint32_t p // m_selfSwitch = true; if (m_selfSwitch) { - getDebugStream() << "[states' size " << s2e()->getExecutor()->getStatesCount() << "] " - << "\n"; - - if (g_s2e_state) { - S2EExecutionState *nextState = s2e()->getExecutor()->selectNextState(g_s2e_state); - if (nextState) { - g_s2e_state = nextState; - - } else { - // Do not reschedule the timer anymore - return; - } - } - getDebugStream() << "[states' size " << s2e()->getExecutor()->getStatesCount() << "] " - << "\n"; - - // s2e()->getExecutor()->selectSearcherState(m_curState) - // s2e()->getExecutor()->selectNextState(m_curState); - // s2e()->getExecutor()->suspendState(m_curState); - // s2e()->getExecutor()->setCpuExitRequest(); + // getDebugStream() << "[states' size " << s2e()->getExecutor()->getStatesCount() << "] " + // << "\n"; + env->current_tb = nullptr; + s2e()->getExecutor()->validPathSearcherStateSwitchCallback(s2e()->getExecutor()); + s2e()->getExecutor()->setCpuExitRequest(); } } @@ -157,21 +164,6 @@ void ValidPathSearcher::initConnection() { onARMFunctionConn->onARMFunctionReturnEvent.connect(sigc::mem_fun(*this, &ValidPathSearcher::onARMFunctionReturn)); } -bool ValidPathSearcher::insertToForkStates(const uint32_t callerPC, const uint32_t forkPC, S2EExecutionState *state) { - const auto &foundSameCallerPC = m_forkStateItems.find(callerPC); - if (foundSameCallerPC != m_forkStateItems.end()) { - const auto &foundSameForkPC = foundSameCallerPC->second.find(forkPC); - if (foundSameForkPC != foundSameCallerPC->second.end()) { - if (foundSameForkPC->second.size() >= 2) { - return false; - } - } - } - m_forkStateItems[callerPC][forkPC].push_back(state); - m_idStateMap[state->getID()] = {state, forkPC, UNVISITED, 0}; - return true; -} - bool ValidPathSearcher::selectSelfSwitchedState() { const uint32_t callerPC = m_functionCalRetMap[m_returnPC]; const uint32_t forkPC = m_idStateMap[m_curState->getID()].forkPC; @@ -180,21 +172,21 @@ bool ValidPathSearcher::selectSelfSwitchedState() { << "[forkPC: " << hexval(forkPC) << "] " << "\n"; - for (auto &it : m_forkStateItems[callerPC][forkPC]) { - const int id = it->getID(); - if (m_curState->getID() != id && m_idStateMap[id].flag != INVALID) { - if (m_idStateMap[id].switchCnt >= MAX_SWITCH_CNT) { - m_idStateMap[id].flag = INVALID; - continue; - } - m_idStateMap[id].switchCnt++; - m_idStateMap[id].flag = VALID; - m_curState = m_idStateMap[id].state; - getDebugStream() << "[new self-switched StateID: " << m_curState->getID() << "] " - << "\n"; - return true; - } - } +// for (auto &it : m_forkStates[callerPC][forkPC]) { +// const int id = it->getID(); +// if (m_curState->getID() != id && m_idStateMap[id].flag != INVALID) { +// if (m_idStateMap[id].switchCnt >= MAX_SWITCH_CNT) { +// m_idStateMap[id].flag = INVALID; +// continue; +// } +// m_idStateMap[id].switchCnt++; +// m_idStateMap[id].flag = VALID; +// m_curState = m_idStateMap[id].state; +// getDebugStream() << "[new self-switched StateID: " << m_curState->getID() << "] " +// << "\n"; +// return true; +// } +// } getDebugStream() << "no option for self switch" << "\n"; @@ -236,5 +228,34 @@ bool ValidPathSearcher::selectValidState() { return false; } +void ValidPathSearcher::printForkStates() { + getDebugStream() << "printForkStates" + << "\n"; + for (const auto &it : m_forkStates) { + getDebugStream() << "[callerPC: " << hexval(it.first) << "] " + << "\n"; + for (const auto &it2 : it.second) { + getDebugStream() << "\t[forkPC: " << hexval(it2.first) << "] " + << "\n"; + for (const auto &it3 : it2.second) { + getDebugStream() << "\t\t[stateID: " << it3 << "] " + << "\n"; + } + } + } +} + +void ValidPathSearcher::printStateItems() { + getDebugStream() << "printStateMap" + << "\n"; + for (const auto &it : m_idStateMap) { + getDebugStream() << "[stateID: " << it.second.state->getID() << "] " + << "[forkPC: " << hexval(it.second.forkPC) << "] " + << "[flag: " << it.second.flag << "] " + << "[switchCnt: " << it.second.switchCnt << "] " + << "\n"; + } +} + } // namespace plugins } // namespace s2e diff --git a/libs2eplugins/src/s2e/Plugins/Searchers/ValidPathSearcher.h b/libs2eplugins/src/s2e/Plugins/Searchers/ValidPathSearcher.h index 2309f310..b953791e 100644 --- a/libs2eplugins/src/s2e/Plugins/Searchers/ValidPathSearcher.h +++ b/libs2eplugins/src/s2e/Plugins/Searchers/ValidPathSearcher.h @@ -62,16 +62,18 @@ class ValidPathSearcher : public Plugin, public klee::Searcher { bool m_selfSwitch; bool m_searcherActive; - std::map>> m_forkStateItems; + std::map>> m_forkStates; std::map m_idStateMap; std::map m_functionCalRetMap; void initConnection(); - bool insertToForkStates(const uint32_t callerPC, const uint32_t forkPC, S2EExecutionState *state); bool selectSelfSwitchedState(); bool selectUnvisitedState(); bool selectValidState(); + void printForkStates(); + void printStateItems(); + // callbacks void onStateFork(S2EExecutionState *state, const std::vector &newStates, const std::vector> &newConditions);