Skip to content
Snippets Groups Projects
SMPFunction.cpp 84.8 KiB
Newer Older

	// For each successor in the dominator tree, recurse.
	list<int>::iterator ChildIter;
	for (ChildIter = this->DomTree[BlockNumber].second.begin();
		ChildIter != this->DomTree[BlockNumber].second.end();
		++ChildIter) {
			this->SSARename(*ChildIter);
	}
	if (DumpFlag) msg("Finished recursion.\n");

	// Pop off all SSAStack entries pushed during this block. I.e. for each global name,
	//  pop its SSAStack once per DEF and once per phi function in this block.
	for (CurrPhi = CurrBlock->GetFirstPhi(); CurrPhi != CurrBlock->GetLastPhi(); ++CurrPhi) {
		GlobalNameIndex = CurrPhi->GetIndex();
		this->SSAStack.at((size_t) GlobalNameIndex).pop_back();
	}
	if (DumpFlag) msg("Popped off entries due to phi functions.\n");
	for (CurrInst = CurrBlock->GetFirstInstr(); CurrInst != CurrBlock->GetLastInstr(); ++CurrInst) {
		size_t RefIndex;
		for (RefIndex = 0; RefIndex < (*CurrInst)->NumDefs(); ++RefIndex) {
			DefOrUse CurrDef = (*CurrInst)->GetDef(RefIndex);
			// See if Def is a global name.
			set<op_t, LessOp>::iterator GlobIter = this->GlobalNames.find(CurrDef.GetOp());
			if (GlobIter != this->GlobalNames.end()) { // found it
				unsigned int GlobIndex = ExtractGlobalIndex(*GlobIter);
				this->SSAStack.at((size_t) GlobIndex).pop_back();
			}
		} //  end for all DEFs
	} // end for all instructions
	if (DumpFlag) msg("Popped off entries due to instructions.\n");

	return;
} // end of SMPFunction::SSARename()

// Main driver of SSA subscript renumbering.
void SMPFunction::SSARenumber(void) {
	if (0 >= this->GlobalNames.size())
		return;  // no names to renumber

	// Initialize stacks and counters of SSA numbers.
	size_t GlobIndex;
	for (GlobIndex = 0; GlobIndex < this->GlobalNames.size(); ++GlobIndex) {
		list<int> DummyList;
		this->SSACounter.push_back(0);
		this->SSAStack.push_back(DummyList);
	}
	// Recurse through the dominator tree starting with node 0.
	this->SSARename(0);
	return;
}

// Emit all annotations for the function, including all per-instruction
//  annotations.
void SMPFunction::EmitAnnotations(FILE *AnnotFile) {
	// Emit annotation for the function as a whole.
	if (this->StaticFunc) {
		qfprintf(AnnotFile,	"%x %d FUNC LOCAL  %s ", this->FuncInfo.startEA,
			this->Size, this->FuncName);
	}
	else {
		qfprintf(AnnotFile,	"%x %d FUNC GLOBAL %s ", this->FuncInfo.startEA,
			this->Size, this->FuncName);
	}
	if (this->UseFP) {
		qfprintf(AnnotFile, "USEFP ");
	}
	else {
		qfprintf(AnnotFile, "NOFP ");
	}
	if (this->FuncInfo.does_return()) {
		qfprintf(AnnotFile, "\n");
	}
	else {
		qfprintf(AnnotFile, "NORET \n");
	}

	// Loop through all instructions in the function.
	// Output optimization annotations for those
	//  instructions that do not require full computation
	//  of their memory metadata by the Memory Monitor SDT.
	list<SMPInstr>::iterator CurrInst;
	bool AllocSeen = false; // Reached LocalVarsAllocInstr yet?
	bool DeallocTrigger = false;
	for (CurrInst = Instrs.begin(); CurrInst != Instrs.end(); ++CurrInst) {
		ea_t addr = CurrInst->GetAddr();
		if (this->LocalVarsAllocInstr == addr) {
			AllocSeen = true;
			this->EmitStackFrameAnnotations(AnnotFile, CurrInst);
		}
		// If this is the instruction which deallocated space
		//  for local variables, we set a flag to remind us to 
		//  emit an annotation on the next instruction.
		// mmStrata wants the instruction AFTER the
		//  deallocating instruction, so that it processes
		//  the deallocation after it happens. It inserts
		//  instrumentation before an instruction, not
		//  after, so it will insert the deallocating
		//  instrumentation before the first POP of callee-saved regs,
		//  if there are any, or before the return, otherwise.
		if (addr == LocalVarsDeallocInstr) {
			DeallocTrigger = true;
		}
		else if (DeallocTrigger) { // Time for annotation
			qfprintf(AnnotFile,	"%x %d DEALLOC STACK esp - %d %s\n", addr,
				LocalVarsSize, LocalVarsSize, CurrInst->GetDisasm());
			DeallocTrigger = false;
		}

		CurrInst->EmitAnnotations(this->UseFP, AllocSeen, AnnotFile);
	}  // end for (ea_t addr = FuncInfo.startEA; ...)
	return;
} // end of SMPFunction::EmitAnnotations()

// Debug output dump.
void SMPFunction::Dump(void) {
	list<SMPBasicBlock>::iterator CurrBlock;
	msg("Debug dump for function: %s\n", this->GetFuncName());
	for (size_t index = 0; index < this->IDom.size(); ++index) {
		msg("IDOM for %d: %d\n", index, this->IDom.at(index));
	}
	for (size_t index = 0; index < this->DomTree.size(); ++index) {
		msg("DomTree for %d: ", index);
		list<int>::iterator DomIter;
		for (DomIter = this->DomTree.at(index).second.begin();
			DomIter != this->DomTree.at(index).second.end();
			++DomIter) {
				msg("%d ", *DomIter);
		}
		msg("\n");
	}
	msg("Global names: \n");
	set<op_t, LessOp>::iterator NameIter;
	for (NameIter = this->GlobalNames.begin(); NameIter != this->GlobalNames.end(); ++NameIter) {
		msg("index: %d ", ExtractGlobalIndex(*NameIter));
		PrintListOperand(*NameIter);
		msg("\n");
	}
	msg("Blocks each name is defined in: \n");
	for (size_t index = 0; index < this->BlocksDefinedIn.size(); ++index) {
		msg("Name index: %d Blocks: ", index);
		list<int>::iterator BlockIter;
		for (BlockIter = this->BlocksDefinedIn.at(index).begin();
			BlockIter != this->BlocksDefinedIn.at(index).end();
			++BlockIter) {
			msg("%d ", *BlockIter);
		}
		msg("\n");
	}
	for (CurrBlock = this->Blocks.begin(); CurrBlock != this->Blocks.end(); ++CurrBlock) {
		// Dump out the function number and data flow sets before the instructions.
		CurrBlock->Dump();
	}
	return;
} // end of SMPFunction::Dump()