Skip to content

Commit

Permalink
fix: switch state
Browse files Browse the repository at this point in the history
  • Loading branch information
hwk2077 committed Sep 15, 2023
1 parent 790977b commit aefd653
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 63 deletions.
10 changes: 7 additions & 3 deletions libs2ecore/src/S2EExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down
137 changes: 79 additions & 58 deletions libs2eplugins/src/s2e/Plugins/Searchers/ValidPathSearcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<S2EExecutionState *>(current);
getDebugStream() << "[start stateID: " << m_curState->getID() << "] "
<< "\n";
m_searcherActive = true;
}

for (auto it : removedStates) {
S2EExecutionState *removedState = dynamic_cast<S2EExecutionState *>(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);
}
}
}
Expand All @@ -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,
Expand Down Expand Up @@ -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;
Expand All @@ -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();
}
}

Expand All @@ -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;
Expand All @@ -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";
Expand Down Expand Up @@ -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
6 changes: 4 additions & 2 deletions libs2eplugins/src/s2e/Plugins/Searchers/ValidPathSearcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,18 @@ class ValidPathSearcher : public Plugin, public klee::Searcher {
bool m_selfSwitch;
bool m_searcherActive;

std::map<uint32_t, std::map<uint32_t, std::vector<S2EExecutionState *>>> m_forkStateItems;
std::map<uint32_t, std::map<uint32_t, std::vector<uint32_t>>> m_forkStates;
std::map<uint32_t, StateItem> m_idStateMap;
std::map<uint32_t, uint32_t> 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<S2EExecutionState *> &newStates,
const std::vector<klee::ref<klee::Expr>> &newConditions);
Expand Down

0 comments on commit aefd653

Please sign in to comment.