void ControlFlowAnalysis::Functions() { typedef std::pair<BasicBlock*, UintSet*> DelayedBlock; std::vector<DelayedBlock> delayedBlocks; for(auto & it : _blocks) { BasicBlock* block = &it.second; UintSet* parents = findParents(block->start); if(!block->function) { if(!parents || _functionStarts.count(block->start)) //no parents = function start { uint functionStart = block->start; block->function = functionStart; UintSet functionBlocks; functionBlocks.insert(functionStart); _functions[functionStart] = functionBlocks; } else //in function { uint function = findFunctionStart(block, parents); if(!function) //this happens with loops sometimes delayedBlocks.push_back(DelayedBlock(block, parents)); else block->function = function; } } else DebugBreak(); //this should not happen } int delayedCount = (int)delayedBlocks.size(); dprintf("%u/%u delayed blocks...\n", delayedCount, _blocks.size()); int resolved = 0; for(auto & delayedBlock : delayedBlocks) { BasicBlock* block = delayedBlock.first; UintSet* parents = delayedBlock.second; uint function = findFunctionStart(block, parents); if(!function) { continue; /*dprintf("unresolved block %s\n", blockToString(block).c_str()); if(parents) { dprintf("parents:\n"); for(auto parent : *parents) dprintf(" %s\n", blockToString(findBlock(parent)).c_str()); } else dprintf("parents: null"); dprintf("left: %s\n", blockToString(findBlock(block->left)).c_str()); dprintf("right: %s\n", blockToString(findBlock(block->right)).c_str()); return;*/ } block->function = function; resolved++; } dprintf("%u/%u delayed blocks resolved (%u/%u still left, probably unreferenced functions)\n", resolved, delayedCount, delayedCount - resolved, _blocks.size()); dprintf("%u functions found!\n", _functions.size()); }
std::string make_temp_fname (const char* tmpdir, const char* prefix) { // if directory not passed in, guess one std::string tn = temp_dir (tmpdir);; // if prefix not passed in, use default if (!prefix) prefix = DEFAULT_TEMP_FILE_PREFIX; // get temp directory listing StrVec dircontent = listdir (tn); // find all entries matching prefix and having numeric postfix, get list of numbers UintSet postfixes; unsigned prefix_len = prefix ? strlen (prefix) : 0; for (StrVec::iterator ii = dircontent.begin (); ii != dircontent.end (); ii ++) { // check if prefix matches if (prefix_len && (ii->substr (0, prefix_len) != prefix)) continue; // check if postfix is numeric and get the number unsigned number = 0; std::string::iterator sitr; for (sitr = ii->begin () + prefix_len; sitr != ii->end (); sitr ++) { number *= 10; if (!isdigit (*sitr)) break; else number += *sitr - '0'; } if (sitr != ii->end ()) continue; // store number to postfixes set postfixes.insert (number); } // now retrieve the numbers using first gap // make a set for quick presence check unsigned prev = 0; for (UintSet::iterator nitr = postfixes.begin (); nitr != postfixes.end (); nitr ++) if (prev + 1 < *nitr) break; // found the gap in sequence else prev = *nitr; if (prev == std::numeric_limits<unsigned>::max ()) // just for sanity :) ers << "No more temp file names available for prefix " << (prefix ? prefix : "") << " in directory " << tn << Throw; // prev + 1 is the right number std::ostringstream name (tn, std::ios::out | std::ios::app); name << PATH_SEPARATOR; if (prefix) name << prefix; name << prev + 1; return name.str (); }
void ControlFlowAnalysis::insertParent(uint child, uint parent) { if(!child || !parent) return; auto found = _parentMap.find(child); if(found == _parentMap.end()) { UintSet parents; parents.insert(parent); _parentMap[child] = parents; } else found->second.insert(parent); }