void CallReplace::instrument(){ uint32_t temp32; uint64_t temp64; LineInfoFinder* lineInfoFinder = NULL; if (hasLineInformation()){ lineInfoFinder = getLineInfoFinder(); } InstrumentationPoint* p = addInstrumentationPoint(getProgramEntryBlock(), programEntry, InstrumentationMode_tramp, FlagsProtectionMethod_full, InstLocation_prior); ASSERT(p); if (!p->getInstBaseAddress()){ PRINT_ERROR("Cannot find an instrumentation point at the exit function"); } p = addInstrumentationPoint(getProgramExitBlock(), programExit, InstrumentationMode_tramp, FlagsProtectionMethod_full, InstLocation_prior); ASSERT(p); if (!p->getInstBaseAddress()){ PRINT_ERROR("Cannot find an instrumentation point at the exit function"); } uint64_t siteIndex = reserveDataOffset(sizeof(uint32_t)); programEntry->addArgument(siteIndex); Vector<X86Instruction*> myInstPoints; Vector<uint32_t> myInstList; Vector<LineInfo*> myLineInfos; for (uint32_t i = 0; i < getNumberOfExposedInstructions(); i++){ X86Instruction* instruction = getExposedInstruction(i); ASSERT(instruction->getContainer()->isFunction()); Function* function = (Function*)instruction->getContainer(); if (instruction->isFunctionCall()){ Symbol* functionSymbol = getElfFile()->lookupFunctionSymbol(instruction->getTargetAddress()); if (functionSymbol){ //PRINT_INFOR("looking for function %s", functionSymbol->getSymbolName()); uint32_t funcIdx = searchFileList(functionList, functionSymbol->getSymbolName()); if (funcIdx < (*functionList).size()){ BasicBlock* bb = function->getBasicBlockAtAddress(instruction->getBaseAddress()); ASSERT(bb->containsCallToRange(0,-1)); ASSERT(instruction->getSizeInBytes() == Size__uncond_jump); myInstPoints.append(instruction); myInstList.append(funcIdx); LineInfo* li = NULL; if (lineInfoFinder){ li = lineInfoFinder->lookupLineInfo(bb); } myLineInfos.append(li); } } } } ASSERT(myInstPoints.size() == myInstList.size()); ASSERT(myLineInfos.size() == myInstList.size()); uint64_t fileNames = reserveDataOffset(sizeof(char*) * myInstList.size()); uint64_t lineNumbers = reserveDataOffset(sizeof(uint32_t) * myInstList.size()); for (uint32_t i = 0; i < myInstList.size(); i++){ uint32_t line = 0; char* fname = NOSTRING; if (myLineInfos[i]){ line = myLineInfos[i]->GET(lr_line); fname = myLineInfos[i]->getFileName(); } uint64_t filenameaddr = getInstDataAddress() + reserveDataOffset(strlen(fname) + 1); initializeReservedData(getInstDataAddress() + fileNames + i*sizeof(char*), sizeof(char*), &filenameaddr); initializeReservedData(filenameaddr, strlen(fname), fname); initializeReservedData(getInstDataAddress() + lineNumbers + i*sizeof(uint32_t), sizeof(uint32_t), &line); } programEntry->addArgument(fileNames); programEntry->addArgument(lineNumbers); for (uint32_t i = 0; i < myInstPoints.size(); i++){ PRINT_INFOR("(site %d) %#llx: replacing call %s -> %s in function %s", i, myInstPoints[i]->getBaseAddress(), getFunctionName(myInstList[i]), getWrapperName(myInstList[i]), myInstPoints[i]->getContainer()->getName()); InstrumentationPoint* pt = addInstrumentationPoint(myInstPoints[i], functionWrappers[myInstList[i]], InstrumentationMode_tramp, FlagsProtectionMethod_none, InstLocation_replace); if (getElfFile()->is64Bit()){ pt->addPrecursorInstruction(X86InstructionFactory64::emitMoveRegToMem(X86_REG_CX, getInstDataAddress() + getRegStorageOffset())); pt->addPrecursorInstruction(X86InstructionFactory64::emitMoveImmToReg(i, X86_REG_CX)); pt->addPrecursorInstruction(X86InstructionFactory64::emitMoveRegToMem(X86_REG_CX, getInstDataAddress() + siteIndex)); pt->addPrecursorInstruction(X86InstructionFactory64::emitMoveMemToReg(getInstDataAddress() + getRegStorageOffset(), X86_REG_CX, true)); } else { pt->addPrecursorInstruction(X86InstructionFactory32::emitMoveRegToMem(X86_REG_CX, getInstDataAddress() + getRegStorageOffset())); pt->addPrecursorInstruction(X86InstructionFactory32::emitMoveImmToReg(i, X86_REG_CX)); pt->addPrecursorInstruction(X86InstructionFactory32::emitMoveRegToMem(X86_REG_CX, getInstDataAddress() + siteIndex)); pt->addPrecursorInstruction(X86InstructionFactory32::emitMoveMemToReg(getInstDataAddress() + getRegStorageOffset(), X86_REG_CX)); } } }
void FlowGraph::computeDefUseDist(){ uint32_t fcnt = function->getNumberOfInstructions(); std::pebil_map_type<uint64_t, X86Instruction*> imap; std::pebil_map_type<uint64_t, BasicBlock*> bmap; std::pebil_map_type<uint64_t, LinkedList<X86Instruction::ReachingDefinition*>*> alliuses; std::pebil_map_type<uint64_t, LinkedList<X86Instruction::ReachingDefinition*>*> allidefs; for (uint32_t i = 0; i < basicBlocks.size(); i++){ BasicBlock* bb = basicBlocks[i]; for (uint32_t j = 0; j < bb->getNumberOfInstructions(); j++){ X86Instruction* x = bb->getInstruction(j); for (uint32_t k = 0; k < x->getSizeInBytes(); k++){ ASSERT(imap.count(x->getBaseAddress() + k) == 0); ASSERT(bmap.count(x->getBaseAddress() + k) == 0); imap[x->getBaseAddress() + k] = x; bmap[x->getBaseAddress() + k] = bb; } ASSERT(alliuses.count(x->getBaseAddress()) == 0); ASSERT(allidefs.count(x->getBaseAddress()) == 0); alliuses[x->getBaseAddress()] = x->getUses(); allidefs[x->getBaseAddress()] = x->getDefs(); } } // For each loop for (uint32_t i = 0; i < loops.size(); ++i) { BasicBlock** allLoopBlocks = new BasicBlock*[loops[i]->getNumberOfBlocks()]; loops[i]->getAllBlocks(allLoopBlocks); uint64_t loopLeader = loops[i]->getHead()->getBaseAddress(); // For each block for (uint32_t j = 0; j < loops[i]->getNumberOfBlocks(); ++j){ BasicBlock* bb = allLoopBlocks[j]; // For each instruction for (uint32_t k = 0; k < bb->getNumberOfInstructions(); ++k){ X86Instruction* ins = bb->getInstruction(k); // Skip the instruction if it can't define anything if (!ins->isIntegerOperation() && !ins->isFloatPOperation() && !ins->isMoveOperation()) { continue; } ASSERT(!ins->usesControlTarget()); singleDefUse(this, ins, bb, loops[i], imap, bmap, alliuses, allidefs, k, loopLeader, fcnt); } } delete[] allLoopBlocks; } // handle all non-loop blocks for (uint32_t i = 0; i < getNumberOfBasicBlocks(); i++){ BasicBlock* bb = basicBlocks[i]; if (!isBlockInLoop(bb->getIndex())){ for (uint32_t k = 0; k < bb->getNumberOfInstructions(); ++k){ X86Instruction* ins = bb->getInstruction(k); if (!ins->isIntegerOperation() && !ins->isFloatPOperation() && !ins->isMoveOperation()) { continue; } ASSERT(!ins->usesControlTarget()); singleDefUse(this, ins, bb, NULL, imap, bmap, alliuses, allidefs, k, 0, fcnt); } } } for (uint32_t i = 0; i < basicBlocks.size(); i++){ BasicBlock* bb = basicBlocks[i]; for (uint32_t j = 0; j < bb->getNumberOfInstructions(); j++){ X86Instruction* x = bb->getInstruction(j); uint64_t addr = x->getBaseAddress(); ASSERT(alliuses.count(addr) == 1); LinkedList<X86Instruction::ReachingDefinition*>* l = alliuses[addr]; alliuses.erase(addr); while (!l->empty()){ delete l->shift(); } delete l; ASSERT(allidefs.count(addr) == 1); l = allidefs[addr]; allidefs.erase(addr); while (!l->empty()){ delete l->shift(); } delete l; } } ASSERT(alliuses.size() == 0); ASSERT(allidefs.size() == 0); }
void TauFunctionTrace::instrument(){ //InstrumentationTool::instrument(); LineInfoFinder* lineInfoFinder = NULL; if (hasLineInformation()){ lineInfoFinder = getLineInfoFinder(); } InstrumentationPoint* p; uint64_t nameAddr = reserveDataOffset(sizeof(uint64_t)); uint64_t fileAddr = reserveDataOffset(sizeof(uint64_t)); uint64_t lineAddr = reserveDataOffset(sizeof(uint32_t)); uint64_t siteIndexAddr = reserveDataOffset(sizeof(uint32_t)); uint32_t site = functionEntry->addConstantArgument(); ASSERT(site == functionExit->addConstantArgument()); std::pebil_map_type<uint64_t, ControlInfo> functions; std::vector<uint64_t> orderedfuncs; uint32_t sequenceId = 0; if (doIntro){ // go over all functions and intrument entries/exits for (uint32_t i = 0; i < getNumberOfExposedFunctions(); i++){ Function* function = getExposedFunction(i); uint64_t addr = function->getBaseAddress(); if (instrumentList && !instrumentList->functionMatches(function->getName())){ continue; } if (!strcmp(function->getName(), "_fini")){ continue; } BasicBlock* entryBlock = function->getFlowGraph()->getEntryBlock(); Vector<BasicBlock*>* exitPoints = function->getFlowGraph()->getExitBlocks(); std::string c; c.append(function->getName()); if (c == "_start"){ exitPoints->append(getProgramExitBlock()); PRINT_INFOR("Special case: inserting exit for _start inside _fini since control generally doesn't reach its exit"); } ASSERT(functions.count(addr) == 0 && "Multiple functions have the same base address?"); PRINT_INFOR("[FUNCTION index=%d] internal instrumentation: %s", sequenceId, function->getName()); ControlInfo f = ControlInfo(); f.name = c; f.file = ""; f.line = 0; f.index = sequenceId++; f.baseaddr = addr; f.type = ControlType_Function; LineInfo* li = NULL; if (lineInfoFinder){ li = lineInfoFinder->lookupLineInfo(addr); } if (li){ f.file.append(li->getFileName()); f.line = li->GET(lr_line); } functions[addr] = f; orderedfuncs.push_back(addr); InstrumentationPoint* prior = addInstrumentationPoint(entryBlock->getLeader(), functionEntry, InstrumentationMode_tramp, InstLocation_prior); prior->setPriority(InstPriority_custom3); assignStoragePrior(prior, f.index, site); for (uint32_t j = 0; j < exitPoints->size(); j++){ InstrumentationPoint* after = addInstrumentationPoint((*exitPoints)[j]->getExitInstruction(), functionExit, InstrumentationMode_tramp, InstLocation_prior); after->setPriority(InstPriority_custom5); if (c == "_start" && j == exitPoints->size() - 1){ after->setPriority(InstPriority_custom6); } assignStoragePrior(after, f.index, site); } delete exitPoints; } } else { // go over all instructions. when we find a call, instrument it for (uint32_t i = 0; i < getNumberOfExposedInstructions(); i++){ X86Instruction* x = getExposedInstruction(i); ASSERT(x->getContainer()->isFunction()); Function* function = (Function*)x->getContainer(); if (x->isFunctionCall()){ uint64_t addr = x->getTargetAddress(); Symbol* functionSymbol = getElfFile()->lookupFunctionSymbol(addr); if (functionSymbol){ if (instrumentList && !instrumentList->functionMatches(functionSymbol->getSymbolName())){ continue; } ASSERT(x->getSizeInBytes() == Size__uncond_jump); std::string c; c.append(functionSymbol->getSymbolName()); if (functions.count(addr) == 0){ PRINT_INFOR("[FUNCTION index=%d] call site instrumentation: %#lx(%s) -> %s", sequenceId, addr, function->getName(), functionSymbol->getSymbolName()); ControlInfo f = ControlInfo(); f.name = c; f.file = ""; f.line = 0; f.index = sequenceId++; f.baseaddr = addr; f.type = ControlType_Function; LineInfo* li = NULL; if (lineInfoFinder){ li = lineInfoFinder->lookupLineInfo(addr); } if (li){ f.file.append(li->getFileName()); f.line = li->GET(lr_line); } functions[addr] = f; orderedfuncs.push_back(addr); } uint32_t idx = functions[addr].index; Base* exitpoint = (Base*)x; if (c == "__libc_start_main"){ PRINT_INFOR("Special case: inserting exit for __libc_start_main inside _fini since this call generally doesn't return"); exitpoint = (Base*)getProgramExitBlock(); } InstrumentationPoint* prior = addInstrumentationPoint(x, functionEntry, InstrumentationMode_tramp, InstLocation_prior); InstrumentationPoint* after = addInstrumentationPoint(exitpoint, functionExit, InstrumentationMode_tramp, InstLocation_after); assignStoragePrior(prior, idx, site); assignStoragePrior(after, idx, site); } } } } // set up argument passing for function registration functionRegister->addArgument(nameAddr); functionRegister->addArgument(fileAddr); functionRegister->addArgument(lineAddr); uint32_t siteReg = functionRegister->addConstantArgument(); // go over every function that was found, insert a registration call at program start for (std::vector<uint64_t>::iterator it = orderedfuncs.begin(); it != orderedfuncs.end(); it++){ uint64_t addr = *it; ControlInfo f = functions[addr]; ASSERT(f.baseaddr == addr); InstrumentationPoint* p = addInstrumentationPoint(getProgramEntryBlock(), functionRegister, InstrumentationMode_tramp); p->setPriority(InstPriority_custom1); const char* cstring = f.name.c_str(); uint64_t storage = reserveDataOffset(strlen(cstring) + 1); initializeReservedData(getInstDataAddress() + storage, strlen(cstring), (void*)cstring); assignStoragePrior(p, getInstDataAddress() + storage, getInstDataAddress() + nameAddr, X86_REG_CX, getInstDataAddress() + getRegStorageOffset()); const char* cstring2 = f.file.c_str(); if (f.file == ""){ assignStoragePrior(p, NULL, getInstDataAddress() + fileAddr, X86_REG_CX, getInstDataAddress() + getRegStorageOffset()); } else { storage = reserveDataOffset(strlen(cstring2) + 1); initializeReservedData(getInstDataAddress() + storage, strlen(cstring2), (void*)cstring2); assignStoragePrior(p, getInstDataAddress() + storage, getInstDataAddress() + fileAddr, X86_REG_CX, getInstDataAddress() + getRegStorageOffset()); } assignStoragePrior(p, f.line, getInstDataAddress() + lineAddr, X86_REG_CX, getInstDataAddress() + getRegStorageOffset()); assignStoragePrior(p, f.index, siteReg); } if (!instrumentList){ return; } // instrument loops std::pebil_map_type<uint64_t, ControlInfo> loops; std::vector<uint64_t> orderedloops; loopRegister->addArgument(nameAddr); loopRegister->addArgument(fileAddr); loopRegister->addArgument(lineAddr); ASSERT(siteReg == loopRegister->addConstantArgument()); for (uint32_t i = 0; i < getNumberOfExposedFunctions(); i++){ Function* function = getExposedFunction(i); FlowGraph* flowgraph = function->getFlowGraph(); if (!instrumentList->loopMatches(function->getName())){ continue; } for (uint32_t j = 0; j < flowgraph->getNumberOfLoops(); j++){ Loop* loop = flowgraph->getLoop(j); uint32_t depth = flowgraph->getLoopDepth(loop); BasicBlock* head = loop->getHead(); uint64_t addr = head->getBaseAddress(); // only want outer-most (depth == 1) loops if (depth != 1){ continue; } BasicBlock** allLoopBlocks = new BasicBlock*[loop->getNumberOfBlocks()]; loop->getAllBlocks(allLoopBlocks); // reject any loop that contains an indirect branch since it is difficult to guarantee that we will find all exits bool badLoop = false; for (uint32_t k = 0; k < loop->getNumberOfBlocks() && !badLoop; k++){ BasicBlock* bb = allLoopBlocks[k]; if (bb->getExitInstruction()->isIndirectBranch()){ badLoop = true; } } if (badLoop){ PRINT_WARN(20, "Loop at %#lx in %s contains an indirect branch so we can't guarantee that all exits will be found. skipping!", addr, function->getName()); delete[] allLoopBlocks; continue; } std::string c; c.append(function->getName()); uint32_t entryc = 0; Vector<LoopPoint*>* points = NULL; // if addr already exists, it means that two loops share a head and we are going to merge them logically here if (loops.count(addr) == 0){ ControlInfo f = ControlInfo(); f.name = c; f.file = ""; f.line = 0; f.index = sequenceId++; f.baseaddr = addr; f.type = ControlType_Loop; points = new Vector<LoopPoint*>(); f.info = points; LineInfo* li = NULL; if (lineInfoFinder){ li = lineInfoFinder->lookupLineInfo(addr); } if (li){ f.file.append(li->getFileName()); f.line = li->GET(lr_line); } loops[addr] = f; orderedloops.push_back(addr); // find entries into this loop for (uint32_t k = 0; k < head->getNumberOfSources(); k++){ BasicBlock* source = head->getSourceBlock(k); if (!loop->isBlockIn(source->getIndex())){ LoopPoint* lp = new LoopPoint(); points->append(lp); lp->flowgraph = flowgraph; lp->source = source; lp->target = NULL; lp->entry = true; lp->interpose = false; if (source->getBaseAddress() + source->getNumberOfBytes() != head->getBaseAddress()){ lp->interpose = true; lp->target = head; } entryc++; } } } ControlInfo f = loops[addr]; points = f.info; // find exits from this loop uint32_t exitc = 0; for (uint32_t k = 0; k < loop->getNumberOfBlocks(); k++){ BasicBlock* bb = allLoopBlocks[k]; if (bb->endsWithReturn()){ LoopPoint* lp = new LoopPoint(); points->append(lp); lp->flowgraph = flowgraph; lp->source = bb; lp->target = NULL; lp->entry = false; lp->interpose = false; exitc++; } for (uint32_t m = 0; m < bb->getNumberOfTargets(); m++){ BasicBlock* target = bb->getTargetBlock(m); if (!loop->isBlockIn(target->getIndex())){ LoopPoint* lp = new LoopPoint(); points->append(lp); lp->flowgraph = flowgraph; lp->source = bb; lp->target = NULL; lp->entry = false; lp->interpose = false; if (target->getBaseAddress() != bb->getBaseAddress() + bb->getNumberOfBytes()){ lp->interpose = true; lp->target = target; } exitc++; } } } PRINT_INFOR("[LOOP index=%d] loop instrumentation %#lx(%s) has %d entries and %d exits", sequenceId-1, addr, function->getName(), entryc, exitc); delete[] allLoopBlocks; } } // go over every loop that was found, insert a registration call at program start // [source_addr -> [target_addr -> interposed]] std::pebil_map_type<uint64_t, std::pebil_map_type<uint64_t, BasicBlock*> > idone; for (std::vector<uint64_t>::iterator it = orderedloops.begin(); it != orderedloops.end(); it++){ uint64_t addr = *it; ControlInfo f = loops[addr]; ASSERT(f.baseaddr == addr); InstrumentationPoint* p = addInstrumentationPoint(getProgramEntryBlock(), loopRegister, InstrumentationMode_tramp); p->setPriority(InstPriority_custom2); const char* cstring = f.name.c_str(); uint64_t storage = reserveDataOffset(strlen(cstring) + 1); initializeReservedData(getInstDataAddress() + storage, strlen(cstring), (void*)cstring); assignStoragePrior(p, getInstDataAddress() + storage, getInstDataAddress() + nameAddr, X86_REG_CX, getInstDataAddress() + getRegStorageOffset()); const char* cstring2 = f.file.c_str(); if (f.file == ""){ assignStoragePrior(p, NULL, getInstDataAddress() + fileAddr, X86_REG_CX, getInstDataAddress() + getRegStorageOffset()); } else { storage = reserveDataOffset(strlen(cstring2) + 1); initializeReservedData(getInstDataAddress() + storage, strlen(cstring2), (void*)cstring2); assignStoragePrior(p, getInstDataAddress() + storage, getInstDataAddress() + fileAddr, X86_REG_CX, getInstDataAddress() + getRegStorageOffset()); } assignStoragePrior(p, f.line, getInstDataAddress() + lineAddr, X86_REG_CX, getInstDataAddress() + getRegStorageOffset()); assignStoragePrior(p, f.index, siteReg); // now add instrumentation for each loop entry/exit Vector<LoopPoint*>* v = (Vector<LoopPoint*>*)f.info; for (uint32_t i = 0; i < v->size(); i++){ LoopPoint* lp = (*v)[i]; ASSERT(lp->flowgraph && lp->source); BasicBlock* bb = lp->source; if (lp->interpose){ ASSERT(lp->target); if (idone.count(lp->source->getBaseAddress()) == 0){ idone[lp->source->getBaseAddress()] = std::pebil_map_type<uint64_t, BasicBlock*>(); } if (idone[lp->source->getBaseAddress()].count(lp->target->getBaseAddress()) == 0){ idone[lp->source->getBaseAddress()][lp->target->getBaseAddress()] = initInterposeBlock(lp->flowgraph, lp->source->getIndex(), lp->target->getIndex()); } bb = idone[lp->source->getBaseAddress()][lp->target->getBaseAddress()]; } else { ASSERT(lp->target == NULL); } Base* pt = (Base*)bb; InstLocations loc = InstLocation_prior; // if exit block falls through, we must place the instrumentation point at the very end of the block if (!lp->entry && !lp->interpose){ pt = (Base*)bb->getExitInstruction(); if (!bb->getExitInstruction()->isReturn()){ loc = InstLocation_after; } } InstrumentationFunction* inf = functionExit; if (lp->entry){ inf = functionEntry; } InstrumentationPoint* p = addInstrumentationPoint(pt, inf, InstrumentationMode_tramp, loc); p->setPriority(InstPriority_custom4); assignStoragePrior(p, f.index, site); delete lp; } delete v; } }
inline void singleDefUse(FlowGraph* fg, X86Instruction* ins, BasicBlock* bb, Loop* loop, std::pebil_map_type<uint64_t, X86Instruction*>& ipebil_map_type, std::pebil_map_type<uint64_t, BasicBlock*>& bpebil_map_type, std::pebil_map_type<uint64_t, LinkedList<X86Instruction::ReachingDefinition*>*>& alliuses, std::pebil_map_type<uint64_t, LinkedList<X86Instruction::ReachingDefinition*>*>& allidefs, int k, uint64_t loopLeader, uint32_t fcnt){ // Get defintions for this instruction: ins LinkedList<X86Instruction::ReachingDefinition*>* idefs = ins->getDefs(); LinkedList<X86Instruction::ReachingDefinition*>* allDefs = idefs; // Skip instruction if it doesn't define anything if (idefs == NULL) { return; } if (idefs->empty()) { delete idefs; return; } set<LinkedList<X86Instruction::ReachingDefinition*>*> allDefLists; allDefLists.insert(idefs); PriorityQueue<struct path*, uint32_t> paths = PriorityQueue<struct path*, uint32_t>(); bool blockTouched[fg->getFunction()->getNumberOfBasicBlocks()]; bzero(&blockTouched, sizeof(bool) * fg->getFunction()->getNumberOfBasicBlocks()); // Initialize worklist with the path from this instruction // Only take paths inside the loop. Since the definitions are in a loop, uses in the loop will be most relevant. if (k == bb->getNumberOfInstructions() - 1){ ASSERT(ins->controlFallsThrough()); if (bb->getNumberOfTargets() > 0){ ASSERT(bb->getNumberOfTargets() == 1); if (flowsInDefUseScope(bb->getTargetBlock(0), loop)){ // Path flows to the first instruction of the next block paths.insert(new path(bb->getTargetBlock(0)->getLeader(), idefs), 1); } } } else { // path flows to the next instruction in this block paths.insert(new path(bb->getInstruction(k+1), idefs), 1); } // while there are paths in worklist while (!paths.isEmpty()) { // take the shortest path in list uint32_t currDist; struct path* p = paths.deleteMin(&currDist); X86Instruction* cand = p->ins; idefs = p->defs; delete p; LinkedList<X86Instruction::ReachingDefinition*>* i2uses, *i2defs, *newdefs; i2uses = alliuses[cand->getBaseAddress()]; // Check if any of idefs is used if(i2uses != NULL && anyDefsAreUsed(idefs, i2uses)){ // Check if use is shortest uint32_t duDist; duDist = trueDefUseDist(currDist, fcnt); if (!ins->getDefUseDist() || ins->getDefUseDist() > duDist) { ins->setDefUseDist(duDist); } // If dist has increased beyond size of function, we must be looping? if (currDist > fcnt) { ins->setDefXIter(); break; } // Stop searching along this path continue; } // Check if any defines are overwritten i2defs = allidefs[cand->getBaseAddress()]; newdefs = removeInvalidated(idefs, i2defs); // If all definitions killed, stop searching along this path if (newdefs == NULL) continue; allDefLists.insert(newdefs); // end of block that is a branch if (cand->usesControlTarget() && !cand->isCall()){ BasicBlock* tgtBlock = bpebil_map_type[cand->getTargetAddress()]; if (tgtBlock && !blockTouched[tgtBlock->getIndex()] && flowsInDefUseScope(tgtBlock, loop)){ blockTouched[tgtBlock->getIndex()] = true; if (tgtBlock->getBaseAddress() == loopLeader){ paths.insert(new path(tgtBlock->getLeader(), newdefs), loopXDefUseDist(currDist + 1, fcnt)); } else { paths.insert(new path(tgtBlock->getLeader(), newdefs), currDist + 1); } } } // non-branching control if (cand->controlFallsThrough()){ BasicBlock* tgtBlock = bpebil_map_type[cand->getBaseAddress() + cand->getSizeInBytes()]; if (tgtBlock && flowsInDefUseScope(tgtBlock, loop)){ X86Instruction* ftTarget = ipebil_map_type[cand->getBaseAddress() + cand->getSizeInBytes()]; if (ftTarget){ if (ftTarget->isLeader()){ if (!blockTouched[tgtBlock->getIndex()]){ blockTouched[tgtBlock->getIndex()] = true; if (ftTarget->getBaseAddress() == loopLeader){ paths.insert(new path(ftTarget, newdefs), loopXDefUseDist(currDist + 1, fcnt)); } else { paths.insert(new path(ftTarget, newdefs), currDist + 1); } } } else { paths.insert(new path(ftTarget, newdefs), currDist + 1); } } } } } if (!paths.isEmpty()){ ins->setDefUseDist(0); } while (!paths.isEmpty()){ delete paths.deleteMin(NULL); } while (!allDefs->empty()){ delete allDefs->shift(); } for(set<LinkedList<X86Instruction::ReachingDefinition*>*>::iterator it = allDefLists.begin(); it != allDefLists.end(); ++it){ delete *it; } }