From 24f7a40d8f2735012e3619d626adf9c8dd392710 Mon Sep 17 00:00:00 2001 From: Bill Williams Date: Mon, 10 Jul 2017 13:55:58 -0500 Subject: [PATCH] Clean up a bunch of data races reported by Cilkscreen and add per-block locks (probably bad for space, but we'll do the big redesign if we need it). --- common/src/string-regex.C | 1 - dataflowAPI/src/liveness.C | 2 + dataflowAPI/src/slicing.C | 10 +- dataflowAPI/src/stackanalysis.C | 9 ++ instructionAPI/src/InstructionDecoderImpl.C | 16 +-- parseAPI/h/CFG.h | 11 +- parseAPI/h/CodeSource.h | 2 +- parseAPI/src/BoundFactCalculator.C | 1 + parseAPI/src/CFGModifier.C | 1 + parseAPI/src/CodeObject.C | 2 + parseAPI/src/Function.C | 81 +++++++------ parseAPI/src/IA_x86.C | 4 +- parseAPI/src/IA_x86Details.C | 1 + parseAPI/src/IndirectAnalyzer.C | 1 + parseAPI/src/JumpTableIndexPred.C | 1 + parseAPI/src/ParseData.C | 4 +- parseAPI/src/ParseData.h | 2 +- parseAPI/src/Parser.C | 121 +++++++++----------- parseAPI/src/Parser.h | 36 +++--- parseAPI/src/ParserDetails.C | 90 +++++++-------- parseAPI/src/ParserDetails.h | 8 +- parseAPI/src/SymtabCodeSource.C | 17 +-- parseAPI/src/ThunkData.C | 2 + 23 files changed, 218 insertions(+), 205 deletions(-) diff --git a/common/src/string-regex.C b/common/src/string-regex.C index fe7f600464..6496c4f3df 100644 --- a/common/src/string-regex.C +++ b/common/src/string-regex.C @@ -38,7 +38,6 @@ #include #endif -#include /* This doesn't actually belong here. */ void dedemangle( char * demangled, char * result ) diff --git a/dataflowAPI/src/liveness.C b/dataflowAPI/src/liveness.C index 90ce6151fe..60a41da240 100644 --- a/dataflowAPI/src/liveness.C +++ b/dataflowAPI/src/liveness.C @@ -101,6 +101,7 @@ const bitArray& LivenessAnalyzer::getLivenessOut(Block *block, bitArray &allRegs // OUT(X) = UNION(IN(Y)) for all successors Y of X + boost::lock_guard g(*block); const Block::edgelist & target_edges = block -> targets(); liveness_cerr << "getLivenessOut for block [" << hex << block->start() << "," << block->end() << "]" << dec << endl; @@ -587,6 +588,7 @@ void *LivenessAnalyzer::getPtrToInstruction(Block *block, Address addr) const{ } bool LivenessAnalyzer::isExitBlock(Block *block) { + boost::lock_guard g(*block); const Block::edgelist & trgs = block->targets(); bool interprocEdge = false; diff --git a/dataflowAPI/src/slicing.C b/dataflowAPI/src/slicing.C index 3f9437355d..960c764770 100644 --- a/dataflowAPI/src/slicing.C +++ b/dataflowAPI/src/slicing.C @@ -671,6 +671,7 @@ Slicer::getSuccessors( // case may produce multiple new frames, but it // will not transform any of them (besides changing // the location) + boost::lock_guard g(*cand.loc.block); const Block::edgelist & targets = cand.loc.block->targets(); Block::edgelist::const_iterator eit = targets.begin(); @@ -806,6 +807,8 @@ Slicer::getPredecessors( // We force finalizing if necessary //cand.loc.func->num_blocks(); SingleContextOrInterproc epred(cand.loc.func, true, true); + boost::lock_guard g(*cand.loc.block); + const Block::edgelist & sources = cand.loc.block->sources(); std::for_each(boost::make_filter_iterator(epred, sources.begin(), sources.end()), boost::make_filter_iterator(epred, sources.end(), sources.end()), @@ -836,6 +839,7 @@ Slicer::handleCall( ParseAPI::Block * callee = NULL; ParseAPI::Edge * funlink = NULL; bool widen = false; + boost::lock_guard g(*cur.loc.block); const Block::edgelist & targets = cur.loc.block->targets(); Block::edgelist::const_iterator eit = targets.begin(); @@ -1029,7 +1033,8 @@ Slicer::handleReturn( // Find successor ParseAPI::Block * retBlock = NULL; - + boost::lock_guard g(*cur.loc.block); + const Block::edgelist & targets = cur.loc.block->targets(); Block::edgelist::const_iterator eit = targets.begin(); for(; eit != targets.end(); ++eit) { @@ -1079,6 +1084,7 @@ Slicer::handleReturnDetails( static bool EndsWithConditionalJump(ParseAPI::Block *b) { bool cond = false; + boost::lock_guard g(*b); for (auto eit = b->targets().begin(); eit != b->targets().end(); ++eit) if ((*eit)->type() == COND_TAKEN) cond = true; return cond; @@ -1323,6 +1329,7 @@ Address SliceNode::addr() const { bool containsCall(ParseAPI::Block *block) { // We contain a call if the out-edges include // either a CALL or a CALL_FT edge + boost::lock_guard g(*block); const Block::edgelist &targets = block->targets(); Block::edgelist::const_iterator eit = targets.begin(); for (; eit != targets.end(); ++eit) { @@ -1335,6 +1342,7 @@ bool containsCall(ParseAPI::Block *block) { bool containsRet(ParseAPI::Block *block) { // We contain a call if the out-edges include // either a CALL or a CALL_FT edge + boost::lock_guard g(*block); const Block::edgelist &targets = block->targets(); Block::edgelist::const_iterator eit = targets.begin(); for (; eit != targets.end(); ++eit) { diff --git a/dataflowAPI/src/stackanalysis.C b/dataflowAPI/src/stackanalysis.C index 90bb9b13ea..496aaae57f 100644 --- a/dataflowAPI/src/stackanalysis.C +++ b/dataflowAPI/src/stackanalysis.C @@ -264,6 +264,7 @@ void StackAnalysis::summarizeBlocks(bool verbose) { } // Add blocks reachable from this one to the work stack + boost::lock_guard g(*block); const Block::edgelist &targs = block->targets(); std::for_each( boost::make_filter_iterator(epred, targs.begin(), targs.end()), @@ -338,6 +339,7 @@ void StackAnalysis::fixpoint(bool verbose) { } // Step 4: push all children on the worklist. + boost::lock_guard g(*block); const Block::edgelist &outEdges = block->targets(); std::for_each( boost::make_filter_iterator(epred2, outEdges.begin(), outEdges.end()), @@ -365,6 +367,7 @@ void getRetAndTailCallBlocks(Function *func, std::set &retBlocks) { Block *currBlock = workstack.top(); workstack.pop(); + boost::lock_guard g(*currBlock); const Block::edgelist &targs = currBlock->targets(); for (auto iter = targs.begin(); iter != targs.end(); iter++) { Edge *currEdge = *iter; @@ -492,6 +495,7 @@ void StackAnalysis::summaryFixpoint() { (*blockEffects)[block].accumulate(input, blockSummaryOutputs[block]); // Step 4: push all children on the worklist. + boost::lock_guard g(*block); const Block::edgelist &outEdges = block->targets(); std::for_each( boost::make_filter_iterator(epred2, outEdges.begin(), outEdges.end()), @@ -2453,6 +2457,7 @@ bool StackAnalysis::handleNormalCall(Instruction::Ptr insn, Block *block, if (off != block->lastInsnAddr()) return false; Address calledAddr = 0; + boost::lock_guard g(*block); const Block::edgelist &outs = block->targets(); for (auto eit = outs.begin(); eit != outs.end(); eit++) { Edge *edge = *eit; @@ -2623,6 +2628,7 @@ bool StackAnalysis::handleNormalCall(Instruction::Ptr insn, Block *block, bool StackAnalysis::handleJump(Instruction::Ptr insn, Block *block, Offset off, TransferFuncs &xferFuncs, TransferSet &funcSummary) { Address calledAddr = 0; + boost::lock_guard g(*block); const Block::edgelist &outs = block->targets(); for (auto eit = outs.begin(); eit != outs.end(); eit++) { Edge *edge = *eit; @@ -2876,6 +2882,8 @@ void StackAnalysis::meetInputs(Block *block, AbslocState &blockInput, intra_nosink_nocatch epred2; stackanalysis_printf("\t ... In edges: "); + boost::lock_guard g(*block); + const Block::edgelist & inEdges = block->sources(); std::for_each( boost::make_filter_iterator(epred2, inEdges.begin(), inEdges.end()), @@ -2893,6 +2901,7 @@ void StackAnalysis::meetSummaryInputs(Block *block, TransferSet &blockInput, TransferSet &input) { input.clear(); intra_nosink_nocatch epred2; + boost::lock_guard g(*block); const Block::edgelist & inEdges = block->sources(); std::for_each( diff --git a/instructionAPI/src/InstructionDecoderImpl.C b/instructionAPI/src/InstructionDecoderImpl.C index 5e75f28141..788c572000 100644 --- a/instructionAPI/src/InstructionDecoderImpl.C +++ b/instructionAPI/src/InstructionDecoderImpl.C @@ -74,23 +74,9 @@ namespace Dyninst case Arch_aarch64: return Ptr(new InstructionDecoder_aarch64(a)); default: + assert(0); return Ptr(); } -// static TLS_VAR std::map impls; -// if(impls.empty()) -// { -// impls[Arch_x86] = Ptr(new InstructionDecoder_x86(Arch_x86)); -// impls[Arch_x86_64] = Ptr(new InstructionDecoder_x86(Arch_x86_64)); -// impls[Arch_ppc32] = Ptr(new InstructionDecoder_power(Arch_ppc32)); -// impls[Arch_ppc64] = Ptr(new InstructionDecoder_power(Arch_ppc64)); -// impls[Arch_aarch64] = Ptr(new InstructionDecoder_aarch64(Arch_aarch64)); -// } -// std::map::const_iterator foundImpl = impls.find(a); -// if(foundImpl == impls.end()) -// { -// return Ptr(); -// } -// return foundImpl->second; } Expression::Ptr InstructionDecoderImpl::makeAddExpression(Expression::Ptr lhs, Expression::Ptr rhs, Result_Type resultType) diff --git a/parseAPI/h/CFG.h b/parseAPI/h/CFG.h index d20ce79b3a..0e11d1eeca 100644 --- a/parseAPI/h/CFG.h +++ b/parseAPI/h/CFG.h @@ -285,9 +285,11 @@ class Function; }; class CodeRegion; + class PARSER_EXPORT Block : - public Dyninst::SimpleInterval, - public allocatable { + public Dyninst::SimpleInterval, + public allocatable, + public boost::lockable_adapter { friend class CFGModifier; friend class Parser; public: @@ -381,16 +383,19 @@ class PARSER_EXPORT Block : inline void Block::addSource(Edge * e) { + boost::lock_guard g(*this); _srclist.push_back(e); } inline void Block::addTarget(Edge * e) { + boost::lock_guard g(*this); _trglist.push_back(e); } inline void Block::removeTarget(Edge * e) { + boost::lock_guard g(*this); for(unsigned i=0;i<_trglist.size();++i) { if(_trglist[i] == e) { _trglist[i] = _trglist.back(); @@ -401,6 +406,8 @@ inline void Block::removeTarget(Edge * e) } inline void Block::removeSource(Edge * e) { + + boost::lock_guard g(*this); for(unsigned i=0;i<_srclist.size();++i) { if(_srclist[i] == e) { _srclist[i] = _srclist.back(); diff --git a/parseAPI/h/CodeSource.h b/parseAPI/h/CodeSource.h index e7e7651e36..eec63560ae 100644 --- a/parseAPI/h/CodeSource.h +++ b/parseAPI/h/CodeSource.h @@ -244,7 +244,7 @@ class PARSER_EXPORT SymtabCodeRegion : public CodeRegion { SymtabAPI::Region * symRegion() const { return _region; } }; -class PARSER_EXPORT SymtabCodeSource : public CodeSource { +class PARSER_EXPORT SymtabCodeSource : public CodeSource, public boost::lockable_adapter { private: SymtabAPI::Symtab * _symtab; bool owns_symtab; diff --git a/parseAPI/src/BoundFactCalculator.C b/parseAPI/src/BoundFactCalculator.C index 0cba042e69..eb520b24ae 100644 --- a/parseAPI/src/BoundFactCalculator.C +++ b/parseAPI/src/BoundFactCalculator.C @@ -48,6 +48,7 @@ static void BuildEdgeFromVirtualEntry(SliceNode::Ptr virtualEntry, } if (visit.find(curBlock) != visit.end()) return; visit.insert(curBlock); + boost::lock_guard g(*curBlock); for (auto eit = curBlock->targets().begin(); eit != curBlock->targets().end(); ++eit) if ((*eit)->type() != CALL && (*eit)->type() != RET) { BuildEdgeFromVirtualEntry(virtualEntry, (*eit)->trg(), targetMap, visit, slice); diff --git a/parseAPI/src/CFGModifier.C b/parseAPI/src/CFGModifier.C index 1b4f99e24f..955e02dc7e 100644 --- a/parseAPI/src/CFGModifier.C +++ b/parseAPI/src/CFGModifier.C @@ -66,6 +66,7 @@ bool CFGModifier::redirect(Edge *edge, Block *target) { // if the source block has a sink edge of the same type, remove this edge bool hasSink = false; if (linkToSink) { + boost::lock_guard g(*edge->src()); const Block::edgelist & trgs = edge->src()->targets(); for (Block::edgelist::const_iterator titer = trgs.begin(); titer != trgs.end(); titer++) { if ((*titer)->sinkEdge() && (*titer)->type() == edge->type()) { diff --git a/parseAPI/src/CodeObject.C b/parseAPI/src/CodeObject.C index 2ab2e56205..9760ed3278 100644 --- a/parseAPI/src/CodeObject.C +++ b/parseAPI/src/CodeObject.C @@ -229,6 +229,7 @@ CodeObject::parseNewEdges( vector & worklist ) // don't add edges that already exist // (this could happen because of shared code) bool edgeExists = false; + boost::lock_guard g(*worklist[idx].source); const Block::edgelist & existingTs = worklist[idx].source->targets(); for (Block::edgelist::const_iterator tit = existingTs.begin(); tit != existingTs.end(); @@ -251,6 +252,7 @@ CodeObject::parseNewEdges( vector & worklist ) fit != funcs.end(); fit++) { + boost::lock_guard g(*worklist[idx].source); const Block::edgelist & tedges = worklist[idx].source->targets(); for(Block::edgelist::const_iterator eit = tedges.begin(); eit != tedges.end(); diff --git a/parseAPI/src/Function.C b/parseAPI/src/Function.C index 38099cd190..f86f7da11f 100644 --- a/parseAPI/src/Function.C +++ b/parseAPI/src/Function.C @@ -133,7 +133,7 @@ Function::~Function() Function::blocklist Function::blocks() { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); if(!_cache_valid) finalize(); return blocklist(blocks_begin(), blocks_end()); @@ -144,7 +144,7 @@ Function::blocks() Function::const_blocklist Function::blocks() const { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); assert(_cache_valid); return const_blocklist(blocks_begin(), blocks_end()); @@ -153,7 +153,7 @@ Function::blocks() const const Function::edgelist & Function::callEdges() { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); if(!_cache_valid) finalize(); return _call_edge_list; @@ -161,7 +161,7 @@ Function::callEdges() { Function::const_blocklist Function::returnBlocks() { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); if (!_cache_valid) finalize(); return const_blocklist(ret_begin(), ret_end()); @@ -169,7 +169,7 @@ Function::returnBlocks() { Function::const_blocklist Function::exitBlocks() { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); if (!_cache_valid) finalize(); return const_blocklist(exit_begin(), exit_end()); @@ -179,7 +179,7 @@ Function::exitBlocks() { Function::const_blocklist Function::exitBlocks() const { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); assert(_cache_valid); return const_blocklist(exit_begin(), exit_end()); @@ -188,7 +188,7 @@ Function::exitBlocks() const { vector const& Function::extents() { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); if(!_cache_valid) finalize(); return _extents; @@ -197,7 +197,7 @@ Function::extents() void Function::finalize() { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); _extents.clear(); _exitBL.clear(); @@ -217,7 +217,7 @@ Function::finalize() Function::blocklist Function::blocks_int() { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); if(_cache_valid || !_entry) return blocklist(blocks_begin(), blocks_end()); @@ -250,6 +250,7 @@ Function::blocks_int() bool exit_func = false; bool found_call = false; bool found_call_ft = false; + boost::lock_guard g(*cur); if (cur->targets().empty()) exit_func = true; for (auto eit = cur->targets().begin(); eit != cur->targets().end(); ++eit) { @@ -394,16 +395,21 @@ Function::blocks_int() void Function::delayed_link_return(CodeObject * o, Block * retblk) { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); bool link_entry = false; - + Block::edgelist::const_iterator eit; dyn_hash_map linked; - Block::edgelist::const_iterator eit = retblk->targets().begin(); - for( ; eit != retblk->targets().end(); ++eit) { - Edge * e = *eit; - linked[e->trg()->start()] = true; + { + boost::lock_guard g(*retblk); + eit = retblk->targets().begin(); + for( ; eit != retblk->targets().end(); ++eit) { + Edge * e = *eit; + linked[e->trg()->start()] = true; + } + } + boost::lock_guard g2(*_entry); eit = _entry->sources().begin(); for( ; eit != _entry->sources().end(); ++eit) { Edge * e = *eit; @@ -436,7 +442,7 @@ Function::delayed_link_return(CodeObject * o, Block * retblk) void Function::add_block(Block *b) { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); ++b->_func_cnt; // block counts references _bmap[b->start()] = b; } @@ -450,7 +456,7 @@ Function::name() const bool Function::contains(Block *b) { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); if (b == NULL) return false; if(!_cache_valid) finalize(); @@ -461,7 +467,7 @@ Function::contains(Block *b) bool Function::contains(Block *b) const { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); if (b == NULL) return false; return HASHDEF(_bmap,b->start()); } @@ -469,7 +475,7 @@ Function::contains(Block *b) const void Function::setEntryBlock(Block *new_entry) { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); obj()->parser->move_func(this, new_entry->start(), new_entry->region()); _region = new_entry->region(); _start = new_entry->start(); @@ -478,7 +484,7 @@ void Function::setEntryBlock(Block *new_entry) void Function::set_retstatus(FuncReturnStatus rs) { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); // If we are changing the return status, update prev counter if (_rs != UNSET) { if (_rs == NORETURN) { @@ -504,7 +510,7 @@ void Function::set_retstatus(FuncReturnStatus rs) void Function::removeBlock(Block* dead) { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); _cache_valid = false; // specify replacement entry prior to deleting entry block, unless // deleting all blocks @@ -516,6 +522,7 @@ Function::removeBlock(Block* dead) } // remove dead block from _retBL and _call_edge_list + boost::lock_guard g2(*dead); const Block::edgelist & outs = dead->targets(); for (Block::edgelist::const_iterator oit = outs.begin(); outs.end() != oit; @@ -554,7 +561,7 @@ class ST_Predicates : public Slicer::Predicates {}; StackTamper Function::tampersStack(bool recalculate) { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); using namespace SymbolicEvaluation; using namespace InstructionAPI; @@ -678,7 +685,7 @@ void Function::destroy(Function *f) { } LoopTreeNode* Function::getLoopTree() const{ - boost::make_lock_guard(*this); + boost::lock_guard g(*this); if (_loop_root == NULL) { LoopAnalyzer la(this); la.createLoopHierarchy(); @@ -692,7 +699,7 @@ LoopTreeNode* Function::getLoopTree() const{ void Function::getLoopsByNestingLevel(vector& lbb, bool outerMostOnly) const { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); if (_loop_analyzed == false) { LoopAnalyzer la(this); la.analyzeLoops(); @@ -715,7 +722,7 @@ void Function::getLoopsByNestingLevel(vector& lbb, bool Function::getLoops(vector& lbb) const { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); getLoopsByNestingLevel(lbb, false); return true; } @@ -724,14 +731,14 @@ Function::getLoops(vector& lbb) const bool Function::getOuterLoops(vector& lbb) const { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); getLoopsByNestingLevel(lbb, true); return true; } Loop *Function::findLoop(const char *name) const { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); return getLoopTree()->findLoop(name); } @@ -745,7 +752,7 @@ Loop *Function::findLoop(const char *name) const //be called to process dominator related fields and methods. void Function::fillDominatorInfo() const { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); if (!isDominatorInfoReady) { dominatorCFG domcfg(this); domcfg.calcDominators(); @@ -755,7 +762,7 @@ void Function::fillDominatorInfo() const void Function::fillPostDominatorInfo() const { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); if (!isPostDominatorInfoReady) { dominatorCFG domcfg(this); domcfg.calcPostDominators(); @@ -764,7 +771,7 @@ void Function::fillPostDominatorInfo() const } bool Function::dominates(Block* A, Block *B) const { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); if (A == NULL || B == NULL) return false; if (A == B) return true; @@ -778,20 +785,20 @@ bool Function::dominates(Block* A, Block *B) const { } Block* Function::getImmediateDominator(Block *A) const { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); fillDominatorInfo(); return immediateDominator[A]; } void Function::getImmediateDominates(Block *A, set &imd) const { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); fillDominatorInfo(); if (immediateDominates[A] != NULL) imd.insert(immediateDominates[A]->begin(), immediateDominates[A]->end()); } void Function::getAllDominates(Block *A, set &d) const { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); fillDominatorInfo(); d.insert(A); if (immediateDominates[A] == NULL) return; @@ -801,7 +808,7 @@ void Function::getAllDominates(Block *A, set &d) const { } bool Function::postDominates(Block* A, Block *B) const { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); if (A == NULL || B == NULL) return false; if (A == B) return true; @@ -815,20 +822,20 @@ bool Function::postDominates(Block* A, Block *B) const { } Block* Function::getImmediatePostDominator(Block *A) const { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); fillPostDominatorInfo(); return immediatePostDominator[A]; } void Function::getImmediatePostDominates(Block *A, set &imd) const { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); fillPostDominatorInfo(); if (immediatePostDominates[A] != NULL) imd.insert(immediatePostDominates[A]->begin(), immediatePostDominates[A]->end()); } void Function::getAllPostDominates(Block *A, set &d) const { - boost::make_lock_guard(*this); + boost::lock_guard g(*this); fillPostDominatorInfo(); d.insert(A); if (immediatePostDominates[A] == NULL) return; diff --git a/parseAPI/src/IA_x86.C b/parseAPI/src/IA_x86.C index 4489ba54af..574d2b6af9 100644 --- a/parseAPI/src/IA_x86.C +++ b/parseAPI/src/IA_x86.C @@ -352,7 +352,9 @@ bool IA_IAPI::isTailCall(const Function *context, EdgeTypeEnum type, unsigned in if(prevInsn->isWritten(stackPtr[_isrc->getArch()])) { bool call_fallthrough = false; - if (_curBlk->start() == prevIter->first) { + boost::lock_guard g(*_curBlk); + + if (_curBlk->start() == prevIter->first) { for (auto eit = _curBlk->sources().begin(); eit != _curBlk->sources().end(); ++eit) { if ((*eit)->type() == CALL_FT) { call_fallthrough = true; diff --git a/parseAPI/src/IA_x86Details.C b/parseAPI/src/IA_x86Details.C index 1b71c606c7..387529068e 100644 --- a/parseAPI/src/IA_x86Details.C +++ b/parseAPI/src/IA_x86Details.C @@ -706,6 +706,7 @@ boost::tuple g(*curBlk); Block::edgelist::const_iterator tit = curBlk->targets().begin(); bool taken_hit = false; bool fallthrough_hit = false; diff --git a/parseAPI/src/IndirectAnalyzer.C b/parseAPI/src/IndirectAnalyzer.C index 7c113a99db..46a99a8871 100644 --- a/parseAPI/src/IndirectAnalyzer.C +++ b/parseAPI/src/IndirectAnalyzer.C @@ -105,6 +105,7 @@ void IndirectControlFlowAnalyzer::GetAllReachableBlock() { q.pop(); if (reachable.find(cur) != reachable.end()) continue; reachable.insert(cur); + boost::lock_guard g(*cur); for (auto eit = cur->sources().begin(); eit != cur->sources().end(); ++eit) if ((*eit)->intraproc()) q.push((*eit)->src()); diff --git a/parseAPI/src/JumpTableIndexPred.C b/parseAPI/src/JumpTableIndexPred.C index a634eab8d3..5707b20420 100644 --- a/parseAPI/src/JumpTableIndexPred.C +++ b/parseAPI/src/JumpTableIndexPred.C @@ -56,6 +56,7 @@ static void BuildEdgesAux(SliceNode::Ptr srcNode, if (visit.find(curBlock) != visit.end()) return; visit.insert(curBlock); + boost::lock_guard g(*curBlock); for (auto eit = curBlock->targets().begin(); eit != curBlock->targets().end(); ++eit) { // Xiaozhu: // Our current slicing code ignores tail calls diff --git a/parseAPI/src/ParseData.C b/parseAPI/src/ParseData.C index b4bdefd3e3..6f6af92a1d 100644 --- a/parseAPI/src/ParseData.C +++ b/parseAPI/src/ParseData.C @@ -62,13 +62,13 @@ ParseWorkElem * ParseFrame::mkWork( ParseWorkElem * ParseFrame::mkWork( ParseWorkBundle * b, Block *block, - const InsnAdapter::IA_IAPI &ah) + boost::shared_ptr ahPtr) { if(!b) { b = new ParseWorkBundle(); work_bundles.push_back(b); } - ParseWorkElem * ret = new ParseWorkElem(b,block,ah); + ParseWorkElem * ret = new ParseWorkElem(b,block,ahPtr); b->add( ret ); return ret; } diff --git a/parseAPI/src/ParseData.h b/parseAPI/src/ParseData.h index 9219f6ef65..e5c6ece567 100644 --- a/parseAPI/src/ParseData.h +++ b/parseAPI/src/ParseData.h @@ -88,7 +88,7 @@ class ParseFrame : public boost::lockable_adapter { ParseWorkElem * mkWork( ParseWorkBundle * b, Block* block, - const InsnAdapter::IA_IAPI &ah); + boost::shared_ptr ahPtr); void pushWork(ParseWorkElem * elem) { boost::lock_guard g(*this); diff --git a/parseAPI/src/Parser.C b/parseAPI/src/Parser.C index ad962406aa..157d4cc2a6 100644 --- a/parseAPI/src/Parser.C +++ b/parseAPI/src/Parser.C @@ -308,6 +308,7 @@ Parser::parse_edges( vector< ParseWorkElem * > & work_elems ) if (elem->order() == ParseWorkElem::call_fallthrough) { Edge *callEdge = NULL; + boost::lock_guard g(*src); Block::edgelist trgs = src->targets(); for (Block::edgelist::iterator eit = trgs.begin(); eit != trgs.end(); @@ -766,6 +767,7 @@ Parser::finalize(Function *f) eit != edges.end(); eit++) { + boost::lock_guard g(*(*eit)->src()); if (2 > (*eit)->src()->targets().size()) { Block *ft = _parse_data->findBlock((*eit)->src()->region(), (*eit)->src()->end()); @@ -1135,24 +1137,19 @@ Parser::parse_frame(ParseFrame & frame, bool recursive) { // Therefore, we need to check for every nop and first non-nop instruction after the call for catch blocks unsigned size = caller->region()->offset() + caller->region()->length() - caller->end(); - const unsigned char* bufferBegin = (const unsigned char *)(func->isrc()->getPtrToInstruction(caller->end())); + const unsigned char* bufferBegin = (const unsigned char *)(caller->region()->getPtrToInstruction(caller->end())); InstructionDecoder dec(bufferBegin,size,frame.codereg->getArch()); - if (!ahPtr) - ahPtr.reset(new InstructionAdapter_t(dec, caller->end(), func->obj(), - caller->region(), func->isrc(), NULL)); - else - ahPtr->reset(dec, caller->end(),func->obj(), - caller->region(), func->isrc(), NULL); - InstructionAdapter_t & ah = *ahPtr; + ahPtr.reset(new InstructionAdapter_t(dec, caller->end(), func->obj(), + caller->region(), func->isrc(), NULL)); bool found = false; - while (ah.getInstruction() && ah.isNop()) { - if (frame.codereg->findCatchBlock(ah.getAddr(),catchStart)) { + while (ahPtr->getInstruction() && ahPtr->isNop()) { + if (frame.codereg->findCatchBlock(ahPtr->getAddr(),catchStart)) { found = true; break; } - ah.advance(); + ahPtr->advance(); } - if (found || (ah.getInstruction() && frame.codereg->findCatchBlock(ah.getAddr(),catchStart))) { + if (found || (ahPtr->getInstruction() && frame.codereg->findCatchBlock(ahPtr->getAddr(),catchStart))) { parsing_printf("[%s] found post-return catch block %lx\n", FILE__,catchStart); // make an edge Edge * catch_edge = link_tempsink(caller,CATCH); @@ -1173,7 +1170,7 @@ Parser::parse_frame(ParseFrame & frame, bool recursive) { cur = leadersToBlock[work->target()]; } else if (work->order() == ParseWorkElem::resolve_jump_table) { // resume to resolve jump table - auto work_ah = work->ah(); + boost::shared_ptr work_ah = work->ah(); parsing_printf("... continue parse indirect jump at %lx\n", work_ah->getAddr()); Block *nextBlock = work->cur(); if (nextBlock->last() != work_ah->getAddr()) { @@ -1189,7 +1186,7 @@ Parser::parse_frame(ParseFrame & frame, bool recursive) { } } - ProcessCFInsn(frame,nextBlock,*work_ah); + ProcessCFInsn(frame,nextBlock,work_ah); continue; } // call fallthrough case where we have already checked that @@ -1272,23 +1269,17 @@ Parser::parse_frame(ParseFrame & frame, bool recursive) { (const unsigned char *)(func->isrc()->getPtrToInstruction(curAddr)); InstructionDecoder dec(bufferBegin,size,frame.codereg->getArch()); - if (!ahPtr) - ahPtr.reset(new InstructionAdapter_t(dec, curAddr, func->obj(), - cur->region(), func->isrc(), cur)); - else - ahPtr->reset(dec,curAddr,func->obj(), - cur->region(), func->isrc(), cur); - - InstructionAdapter_t & ah = *ahPtr; + ahPtr.reset(new InstructionAdapter_t(dec, curAddr, func->obj(), + cur->region(), func->isrc(), cur)); using boost::tuples::tie; tie(nextBlockAddr,nextBlock) = get_next_block( frame.curAddr, frame.codereg, _parse_data); - bool isNopBlock = ah.isNop(); + bool isNopBlock = ahPtr->isNop(); while(true) { - curAddr = ah.getAddr(); + curAddr = ahPtr->getAddr(); /** Check for straight-line fallthrough **/ if (curAddr == nextBlockAddr) { parsing_printf("[%s] straight-line parse into block at %lx\n", @@ -1296,10 +1287,10 @@ Parser::parse_frame(ParseFrame & frame, bool recursive) { if (frame.func->obj()->defensiveMode()) { mal_printf("straight-line parse into block at %lx\n",curAddr); } - ah.retreat(); - curAddr = ah.getAddr(); + ahPtr->retreat(); + curAddr = ahPtr->getAddr(); - end_block(cur,ah); + end_block(cur,ahPtr); pair newedge = add_edge(frame,frame.func,cur, nextBlockAddr,FALLTHROUGH,NULL); @@ -1346,7 +1337,7 @@ Parser::parse_frame(ParseFrame & frame, bool recursive) { // per-instruction callback notification ParseCallback::insn_details insn_det; - insn_det.insn = &ah; + insn_det.insn = ahPtr.get(); parsing_printf("[%s:%d] curAddr 0x%lx: %s \n", FILE__,__LINE__,curAddr, insn_det.insn->getInstruction()->format().c_str() ); @@ -1361,10 +1352,10 @@ Parser::parse_frame(ParseFrame & frame, bool recursive) { _pcb.instruction_cb(func,cur,curAddr,&insn_det); - if (isNopBlock && !ah.isNop()) { - ah.retreat(); + if (isNopBlock && !ahPtr->isNop()) { + ahPtr->retreat(); - end_block(cur,ah); + end_block(cur,ahPtr); pair newedge = add_edge(frame,frame.func,cur,curAddr,FALLTHROUGH,NULL); Block * targ = newedge.first; @@ -1391,39 +1382,39 @@ Parser::parse_frame(ParseFrame & frame, bool recursive) { /** Particular instruction handling (calls, branches, etc) **/ ++num_insns; - if(ah.hasCFT()) { + if(ahPtr->hasCFT()) { // if (false) { - if (ah.isIndirectJump()) { + if (ahPtr->isIndirectJump()) { // Create a work element to represent that // we will resolve the jump table later - end_block(cur,ah); - frame.pushWork( frame.mkWork( work->bundle(), cur, ah)); + end_block(cur,ahPtr); + frame.pushWork( frame.mkWork( work->bundle(), cur, ahPtr)); } else { - ProcessCFInsn(frame,cur,ah); + ProcessCFInsn(frame,cur,ahPtr); } break; } else if (func->_saves_fp && func->_no_stack_frame && - ah.isFrameSetupInsn()) { // isframeSetup is expensive + ahPtr->isFrameSetupInsn()) { // isframeSetup is expensive func->_no_stack_frame = false; - } else if (ah.isLeave()) { + } else if (ahPtr->isLeave()) { func->_no_stack_frame = false; - } else if ( ah.isAbort() ) { + } else if ( ahPtr->isAbort() ) { // 4. `abort-causing' instructions - end_block(cur,ah); + end_block(cur,ahPtr); //link(cur, _sink, DIRECT, true); break; - } else if ( ah.isInvalidInsn() ) { + } else if ( ahPtr->isInvalidInsn() ) { // 4. Invalid or `abort-causing' instructions - end_block(cur,ah); + end_block(cur,ahPtr); link(cur, _sink, DIRECT, true); break; - } else if ( ah.isInterruptOrSyscall() ) { + } else if ( ahPtr->isInterruptOrSyscall() ) { // 5. Raising instructions - end_block(cur,ah); + end_block(cur,ahPtr); pair newedge = - add_edge(frame,frame.func,cur,ah.getNextAddr(),FALLTHROUGH,NULL); + add_edge(frame,frame.func,cur,ahPtr->getNextAddr(),FALLTHROUGH,NULL); Block * targ = newedge.first; if (targ && !HASHDEF(visited,targ->start()) && @@ -1447,7 +1438,7 @@ Parser::parse_frame(ParseFrame & frame, bool recursive) { } break; } else if (unlikely(func->obj()->defensiveMode())) { - if (!_pcb.hasWeirdInsns(func) && ah.isGarbageInsn()) { + if (!_pcb.hasWeirdInsns(func) && ahPtr->isGarbageInsn()) { // add instrumentation at this addr so we can // extend the function if this really executes ParseCallback::default_details det( @@ -1456,27 +1447,27 @@ Parser::parse_frame(ParseFrame & frame, bool recursive) { true); _pcb.abruptEnd_cf(cur->lastInsnAddr(),cur,&det); _pcb.foundWeirdInsns(func); - end_block(cur,ah); + end_block(cur,ahPtr); // allow invalid instructions to end up as a sink node. link(cur, _sink, DIRECT, true); break; - } else if (ah.isNopJump()) { + } else if (ahPtr->isNopJump()) { // patch the jump to make it a nop, and re-set the // instruction adapter so we parse the instruction // as a no-op this time, allowing the subsequent // instruction to be parsed correctly - mal_printf("Nop jump at %lx, changing it to nop\n",ah.getAddr()); - _pcb.patch_nop_jump(ah.getAddr()); + mal_printf("Nop jump at %lx, changing it to nop\n",ahPtr->getAddr()); + _pcb.patch_nop_jump(ahPtr->getAddr()); unsigned bufsize = - func->region()->offset() + func->region()->length() - ah.getAddr(); + func->region()->offset() + func->region()->length() - ahPtr->getAddr(); const unsigned char* bufferBegin = (const unsigned char *) - (func->isrc()->getPtrToInstruction(ah.getAddr())); + (func->region()->getPtrToInstruction(ahPtr->getAddr())); dec = InstructionDecoder (bufferBegin, bufsize, frame.codereg->getArch()); - ah = InstructionAdapter_t(dec, curAddr, func->obj(), - func->region(), func->isrc(), cur); + ahPtr.reset(new InstructionAdapter_t(dec, curAddr, func->obj(), + func->region(), func->isrc(), cur)); } else { - entryID id = ah.getInstruction()->getOperation().getID(); + entryID id = ahPtr->getInstruction()->getOperation().getID(); switch (id) { case e_rdtsc: fprintf(stderr,"parsed bluepill insn rdtsc at %lx\n",curAddr); @@ -1493,25 +1484,25 @@ Parser::parse_frame(ParseFrame & frame, bool recursive) { } /** Check for overruns of valid address space **/ - if (!is_code(func,ah.getNextAddr())) { + if (!is_code(func,ahPtr->getNextAddr())) { parsing_printf("[%s] next insn %lx is invalid\n", - FILE__,ah.getNextAddr()); + FILE__,ahPtr->getNextAddr()); - end_block(cur,ah); + end_block(cur,ahPtr); // We need to tag the block with a sink edge link(cur, _sink, DIRECT, true); break; - } else if (!cur->region()->contains(ah.getNextAddr())) { + } else if (!cur->region()->contains(ahPtr->getNextAddr())) { parsing_printf("[%s] next address %lx is outside [%lx,%lx)\n", - FILE__,ah.getNextAddr(), + FILE__,ahPtr->getNextAddr(), cur->region()->offset(), cur->region()->offset()+cur->region()->length()); - end_block(cur,ah); + end_block(cur,ahPtr); // We need to tag the block with a sink edge link(cur, _sink, DIRECT, true); break; } - ah.advance(); + ahPtr->advance(); } } @@ -1548,10 +1539,10 @@ Parser::parse_frame(ParseFrame & frame, bool recursive) { } void -Parser::end_block(Block * b, InstructionAdapter_t & ah) +Parser::end_block(Block * b, boost::shared_ptr ahPtr) { - b->_lastInsn = ah.getAddr(); - b->updateEnd(ah.getNextAddr()); + b->_lastInsn = ahPtr->getAddr(); + b->updateEnd(ahPtr->getNextAddr()); record_block(b); } diff --git a/parseAPI/src/Parser.h b/parseAPI/src/Parser.h index 11a2f3b0cc..cd6e949013 100644 --- a/parseAPI/src/Parser.h +++ b/parseAPI/src/Parser.h @@ -164,7 +164,7 @@ class Parser { ParseFrame::Status frame_status(CodeRegion * cr, Address addr); /** CFG structure manipulations **/ - void end_block(Block *b, InstructionAdapter_t & ah); + void end_block(Block *b, boost::shared_ptr ah); Block * block_at(Function * owner, Address addr, Block * & split); @@ -198,26 +198,26 @@ class Parser { /* implementation of the parsing loop */ void ProcessUnresBranchEdge( - ParseFrame&, - Block*, - InstructionAdapter_t&, - Address target); + ParseFrame &, + Block *, + boost::shared_ptr, + Address target); void ProcessCallInsn( - ParseFrame&, - Block*, - InstructionAdapter_t&, - bool, - bool, - bool, - Address); + ParseFrame &, + Block *, + boost::shared_ptr, + bool, + bool, + bool, + Address); void ProcessReturnInsn( - ParseFrame&, - Block*, - InstructionAdapter_t&); + ParseFrame &, + Block *, + boost::shared_ptr); void ProcessCFInsn( - ParseFrame&, - Block*, - InstructionAdapter_t&); + ParseFrame &, + Block *, + boost::shared_ptr); void finalize(); void finalize_funcs(vector & funcs); diff --git a/parseAPI/src/ParserDetails.C b/parseAPI/src/ParserDetails.C index 436e848115..ebfc330840 100644 --- a/parseAPI/src/ParserDetails.C +++ b/parseAPI/src/ParserDetails.C @@ -322,15 +322,15 @@ Parser::tamper_post_processing(vector & work, ParseFrame *pf) */ inline void Parser::ProcessUnresBranchEdge( - ParseFrame & frame, - Block * cur, - InstructionAdapter_t & ah, - Address target) + ParseFrame &frame, + Block *cur, + boost::shared_ptr ahPtr, + Address target) { ParseCallback::interproc_details det; det.ibuf = (unsigned char*) - frame.func->isrc()->getPtrToInstruction(ah.getAddr()); - det.isize = ah.getSize(); + frame.func->isrc()->getPtrToInstruction(ahPtr->getAddr()); + det.isize = ahPtr->getSize(); if (((Address)-1) == target) { det.data.unres.target = 0; } else { @@ -340,7 +340,7 @@ void Parser::ProcessUnresBranchEdge( det.data.unres.target = target; bool valid; Address addr; - boost::tie(valid, addr) = ah.getCFT(); + boost::tie(valid, addr) = ahPtr->getCFT(); if (!valid) { det.data.unres.dynamic = true; det.data.unres.absolute_address = true; @@ -348,7 +348,7 @@ void Parser::ProcessUnresBranchEdge( det.data.unres.dynamic = false; det.data.unres.absolute_address = false; } - _pcb.interproc_cf(frame.func,cur,ah.getAddr(),&det); + _pcb.interproc_cf(frame.func,cur,ahPtr->getAddr(),&det); } /* @@ -356,20 +356,20 @@ void Parser::ProcessUnresBranchEdge( */ inline void Parser::ProcessReturnInsn( - ParseFrame & frame, - Block * cur, - InstructionAdapter_t & ah) + ParseFrame &frame, + Block *cur, + boost::shared_ptr ahPtr) { // returns always target the sink block link(cur,_sink,RET,true); ParseCallback::interproc_details det; det.ibuf = (unsigned char*) - frame.func->isrc()->getPtrToInstruction(ah.getAddr()); - det.isize = ah.getSize(); + frame.func->isrc()->getPtrToInstruction(ahPtr->getAddr()); + det.isize = ahPtr->getSize(); det.type = ParseCallback::interproc_details::ret; - _pcb.interproc_cf(frame.func, cur, ah.getAddr(),&det); + _pcb.interproc_cf(frame.func, cur, ahPtr->getAddr(),&det); } @@ -379,20 +379,20 @@ void Parser::ProcessReturnInsn( */ inline void Parser::ProcessCallInsn( - ParseFrame & frame, - Block * cur, - InstructionAdapter_t & ah, - bool isDynamic, - bool isAbsolute, - bool isResolved, - Address target) + ParseFrame &frame, + Block *cur, + boost::shared_ptr ahPtr, + bool isDynamic, + bool isAbsolute, + bool isResolved, + Address target) { ParseCallback::interproc_details det; det.ibuf = (unsigned char*) - frame.func->isrc()->getPtrToInstruction(ah.getAddr()); - det.isize = ah.getSize(); + frame.func->isrc()->getPtrToInstruction(ahPtr->getAddr()); + det.isize = ahPtr->getSize(); - if(ah.isCall()) { + if(ahPtr->isCall()) { det.data.call.absolute_address = isAbsolute; det.data.call.dynamic_call = isDynamic; det.data.call.target = target; @@ -404,13 +404,13 @@ void Parser::ProcessCallInsn( else det.type = ParseCallback::interproc_details::branch_interproc; - _pcb.interproc_cf(frame.func,cur,ah.getAddr(),&det); + _pcb.interproc_cf(frame.func,cur,ahPtr->getAddr(),&det); } void Parser::ProcessCFInsn( - ParseFrame & frame, - Block * cur, - InstructionAdapter_t & ah) + ParseFrame &frame, + Block *cur, + boost::shared_ptr ahPtr) { FuncReturnStatus insn_ret; Edges_t edges_out; @@ -418,13 +418,13 @@ void Parser::ProcessCFInsn( // terminate the block at this address - end_block(cur,ah); + end_block(cur,ahPtr); // Instruction adapter provides edge estimates from an instruction parsing_printf("Getting edges\n"); - ah.getNewEdges(edges_out, frame.func, cur, frame.num_insns, &plt_entries, frame.knownTargets); + ahPtr->getNewEdges(edges_out, frame.func, cur, frame.num_insns, &plt_entries, frame.knownTargets); parsing_printf("Returned %d edges\n", edges_out.size()); - if (unlikely(_obj.defensiveMode() && !ah.isCall() && edges_out.size())) { + if (unlikely(_obj.defensiveMode() && !ahPtr->isCall() && edges_out.size())) { // only parse branch edges that align with existing blocks bool hasUnalignedEdge = false; set tregs; @@ -482,7 +482,7 @@ void Parser::ProcessCFInsn( } } - insn_ret = ah.getReturnStatus(frame.func,frame.num_insns); + insn_ret = ahPtr->getReturnStatus(frame.func,frame.num_insns); // Update function return status if possible if(unlikely(insn_ret != UNSET && frame.func->_rs < RETURN)) @@ -490,13 +490,13 @@ void Parser::ProcessCFInsn( // Return instructions need extra processing if(insn_ret == RETURN) - ProcessReturnInsn(frame,cur,ah); + ProcessReturnInsn(frame,cur,ahPtr); - bool dynamic_call = ah.isDynamicCall(); - bool absolute_call = ah.isAbsoluteCall(); + bool dynamic_call = ahPtr->isDynamicCall(); + bool absolute_call = ahPtr->isAbsoluteCall(); // unresolved is true for indirect calls, unresolved indirect branches, // and later on is set set to true for transfers to bad addresses - bool has_unres = ah.hasUnresolvedControlFlow(frame.func,frame.num_insns); + bool has_unres = ahPtr->hasUnresolvedControlFlow(frame.func,frame.num_insns); parsing_printf("\t\t%d edges:\n",edges_out.size()); for(Edges_t::iterator curEdge = edges_out.begin(); @@ -525,7 +525,7 @@ void Parser::ProcessCFInsn( { // call callback resolvable_edge = resolvable_edge && !dynamic_call; - ProcessCallInsn(frame,cur,ah,dynamic_call, + ProcessCallInsn(frame,cur,ahPtr,dynamic_call, absolute_call,resolvable_edge,curEdge->first); if(resolvable_edge) { @@ -534,7 +534,7 @@ void Parser::ProcessCFInsn( else { newedge = link(cur,_sink,CALL,true); } - if(!ah.isCall()) { + if(!ahPtr->isCall()) { parsing_printf("Setting edge 0x%lx (0x%lx/0x%lx) to interproc\n", newedge, newedge->src()->start(), @@ -554,7 +554,7 @@ void Parser::ProcessCFInsn( newedge = link(cur,_sink,curEdge->second,true); } - if (ah.isTailCall(frame.func, curEdge->second, frame.num_insns, frame.knownTargets)) { + if (ahPtr->isTailCall(frame.func, curEdge->second, frame.num_insns, frame.knownTargets)) { tailcall = true; parsing_printf("Setting edge 0x%lx (0x%lx/0x%lx) to interproc (tail call)\n", newedge, @@ -568,7 +568,7 @@ void Parser::ProcessCFInsn( frame.work_bundles.push_back(bundle); } - verbose_log(ah.getAddr(),curEdge); + verbose_log(ahPtr->getAddr(),curEdge); parsing_printf("resolveable_edge: %d, tailcall: %d, target: %lx\n", resolvable_edge, tailcall, curEdge->first); ParseWorkElem * we = bundle->add( @@ -601,19 +601,19 @@ void Parser::ProcessCFInsn( } else if( unlikely(_obj.defensiveMode()) ) { - ProcessUnresBranchEdge(frame, cur, ah, curEdge->first); + ProcessUnresBranchEdge(frame, cur, ahPtr, curEdge->first); } } if (unlikely(has_unres && edges_out.empty())) { link(cur, _sink, INDIRECT, true); - ProcessUnresBranchEdge(frame, cur, ah, -1); + ProcessUnresBranchEdge(frame, cur, ahPtr, -1); } - if(ah.isDelaySlot()) - ah.advance(); + if(ahPtr->isDelaySlot()) + ahPtr->advance(); - if(!frame.func->_cleans_stack && ah.cleansStack()) { + if(!frame.func->_cleans_stack && ahPtr->cleansStack()) { frame.func->_cleans_stack = true; } } diff --git a/parseAPI/src/ParserDetails.h b/parseAPI/src/ParserDetails.h index f3194f0fb6..57670c22df 100644 --- a/parseAPI/src/ParserDetails.h +++ b/parseAPI/src/ParserDetails.h @@ -175,7 +175,7 @@ class ParseWorkElem // This work element is a continuation of // parsing jump tables - ParseWorkElem(ParseWorkBundle *bundle, Block *b, const InsnAdapter::IA_IAPI& ah) + ParseWorkElem(ParseWorkBundle *bundle, Block *b, boost::shared_ptr ah) : _bundle(bundle), _edge(NULL), _targ((Address)-1), @@ -184,7 +184,7 @@ class ParseWorkElem _order(resolve_jump_table), _call_processed(false), _cur(b), - _ah(new InsnAdapter::IA_IAPI(ah)){ + _ah(ah){ } ~ParseWorkElem() { @@ -204,7 +204,7 @@ class ParseWorkElem void mark_call() { _call_processed = true; } Block* cur() const { return _cur; } - InsnAdapter::IA_IAPI* ah() const { return _ah; } + boost::shared_ptr ah() const { return _ah; } /* * Note that compare treats the parse_work_order as `lowest is @@ -238,7 +238,7 @@ class ParseWorkElem // Data for continuing parsing jump tables Block* _cur; - InsnAdapter::IA_IAPI* _ah; + boost::shared_ptr _ah; }; // ParseWorkElem container diff --git a/parseAPI/src/SymtabCodeSource.C b/parseAPI/src/SymtabCodeSource.C index 1310f327dd..c65b362dc6 100644 --- a/parseAPI/src/SymtabCodeSource.C +++ b/parseAPI/src/SymtabCodeSource.C @@ -116,13 +116,8 @@ SymtabCodeRegion::getPtrToInstruction(const Address addr) const { if(!contains(addr)) return NULL; - if(isCode(addr)) - return (void*)((Address)_region->getPtrToRawData() + - addr - _region->getMemOffset()); - else if(isData(addr)) - return getPtrToData(addr); - else - return NULL; + return (void*)((Address)_region->getPtrToRawData() + + addr - _region->getMemOffset()); } void * @@ -130,11 +125,8 @@ SymtabCodeRegion::getPtrToData(const Address addr) const { if(!contains(addr)) return NULL; - if(isData(addr)) - return (void*)((Address)_region->getPtrToRawData() + - addr - _region->getMemOffset()); - else - return NULL; + return (void*)((Address)_region->getPtrToRawData() + + addr - _region->getMemOffset()); } unsigned int @@ -589,6 +581,7 @@ SymtabCodeSource::getTOC(Address addr) const inline CodeRegion * SymtabCodeSource::lookup_region(const Address addr) const { + boost::lock_guard g(*this); CodeRegion * ret = NULL; if(_lookup_cache && _lookup_cache->contains(addr)) ret = _lookup_cache; diff --git a/parseAPI/src/ThunkData.C b/parseAPI/src/ThunkData.C index a776cc3f70..f937b48ede 100644 --- a/parseAPI/src/ThunkData.C +++ b/parseAPI/src/ThunkData.C @@ -14,6 +14,7 @@ using namespace Dyninst::ParseAPI; void ReachFact::ReverseDFS(ParseAPI::Block *cur, set &visited) { if (visited.find(cur) != visited.end()) return; visited.insert(cur); + boost::lock_guard g(*cur); for (auto eit = cur->sources().begin(); eit != cur->sources().end(); ++eit) if ((*eit)->type() != CALL && (*eit)->type() != RET) ReverseDFS((*eit)->src(), visited); @@ -22,6 +23,7 @@ void ReachFact::ReverseDFS(ParseAPI::Block *cur, set &visited) void ReachFact::NaturalDFS(ParseAPI::Block *cur, set &visited) { if (visited.find(cur) != visited.end()) return; visited.insert(cur); + boost::lock_guard g(*cur); for (auto eit = cur->targets().begin(); eit != cur->targets().end(); ++eit) if ((*eit)->type() != CALL && (*eit)->type() != RET) NaturalDFS((*eit)->trg(), visited);