void normalizeInstructionInSubTree(SgNode* topNode ){ vector<SgAsmx86Instruction*> insns; FindInstructionsVisitor vis; AstQueryNamespace::querySubTree(topNode, std::bind2nd( vis, &insns )); for(std::vector<SgAsmx86Instruction*>::iterator iItr = insns.begin(); iItr != insns.end(); ++iItr) { SgAsmx86Instruction* insn = *iItr; SgAsmExpressionPtrList& operands = getOperands(insn); // Add to total for this variant // Add to total for each kind of operand size_t operandCount = operands.size(); for (size_t i = 0; i < operandCount; ++i) { SgAsmExpression* operand = operands[i]; SgAsmExpression* newOperand; if( isSgAsmMemoryReferenceExpression(operand) ) { SgAsmMemoryReferenceExpression* memRefExp = new SgAsmMemoryReferenceExpression; SgAsmWordValueExpression* wordVal = new SgAsmWordValueExpression; wordVal->set_value(0); memRefExp->set_segment(wordVal); memRefExp->set_address(wordVal); memRefExp->set_type(new SgAsmTypeWord); newOperand = memRefExp; }else if(isSgAsmRegisterReferenceExpression(operand) ){ SgAsmx86RegisterReferenceExpression* regRef = new SgAsmx86RegisterReferenceExpression; regRef->get_descriptor().set_major(x86_regclass_mm); regRef->get_descriptor().set_minor(0); newOperand = regRef; }else{ SgAsmWordValueExpression* wordVal = new SgAsmWordValueExpression; wordVal->set_value(0); newOperand = wordVal; } newOperand->set_parent(operand->get_parent()); DeleteSgTree(operands[i]); operands[i]=newOperand; } //std::cout << "Unparsed: " <<unparseX86Instruction(insn)<< std::endl; } };
SgAsmMemoryReferenceExpression* makeMemoryReference(SgAsmExpression* addr, SgAsmExpression* segment, SgAsmType* t) { SgAsmMemoryReferenceExpression* r = new SgAsmMemoryReferenceExpression(addr); addr->set_parent(r); if (segment) { r->set_segment(segment); segment->set_parent(r); } if (t) r->set_type(t); return r; }
/**************************************************** * create a BinaryNode ****************************************************/ SgAsmExpression* RoseBin_IDAPRO_buildTree::convertBinaryNode(exprTreeType* expt, list<SgAsmExpression*> *children, const string& typeOfOperandIn) { string typeOfOperand = typeOfOperandIn; SgAsmExpression* binNode=NULL; int sizeOfList = children->size(); bool isLeaf = false; if (sizeOfList==0) isLeaf = true; if (RoseBin_support::DEBUG_MODE()) { ostringstream addrhex; addrhex << hex << setw(8) << expt->immediate ; cout << "\n>> convert binNode: expr_id: " << expt->id << endl; cout << " isLeaf: " << RoseBin_support::resBool(isLeaf) << " symbol: " << expt->symbol << " immedi: " << expt->immediate << " hex: " << addrhex.str() << endl; } if (expt->expr_type==4) { // this is a operator if (RoseBin_support::DEBUG_MODE()) cout << " its a operator ... " << expt->symbol << endl; string symbol = RoseBin_support::str_to_upper(expt->symbol); if (symbol=="CS" || symbol=="DS" || symbol=="SS" || symbol=="ES" || symbol == "FS" || symbol=="GS") { // we need the child information to build this if (sizeOfList!=1) { //cerr << " a reference expression can only take one child! " <<endl; list<SgAsmExpression*>::iterator childList = children->begin(); for (; childList!=children->end();++childList) { SgAsmExpression* child = *childList; exprTreeType exprTree = debugHelpMap[child]; //cout << " children are : " << child << " -- " << exprTree.symbol << endl; } abort(); } SgAsmExpression* child = *(children->begin()); ROSE_ASSERT(RoseAssemblyLanguage==x86); RegisterDescriptor regDesc; resolveRegisterX86(symbol, ®Desc); if (isSgAsmMemoryReferenceExpression(child)) { binNode = new SgAsmx86RegisterReferenceExpression(regDesc); isSgAsmx86RegisterReferenceExpression(binNode)->set_type(getRegisterType(regDesc)); isSgAsmMemoryReferenceExpression(child)->set_segment(binNode); binNode->set_parent(child); binNode=child; } else { binNode = child; // do nothing // if we have a jump case, we have a value only and no RegRef } #if 0 // resolve the register information if (RoseAssemblyLanguage==x86) { SgAsmRegisterReferenceExpression::x86_register_enum registerSg = SgAsmRegisterReferenceExpression::undefined_general_register; SgAsmRegisterReferenceExpression::x86_position_in_register_enum regSize = SgAsmRegisterReferenceExpression::undefined_position_in_register; resolveRegisterX86(symbol, ®isterSg, ®Size); // binNode = new SgAsmRegisterReferenceExpression(registerSg, regSize); binNode = new SgAsmRegisterReferenceExpression(); (isSgAsmRegisterReferenceExpression(binNode))->set_x86_register_code(registerSg); (isSgAsmRegisterReferenceExpression(binNode))->set_x86_position_in_register_code(regSize); } else if (RoseAssemblyLanguage==arm) { SgAsmRegisterReferenceExpression::arm_register_enum registerSg = SgAsmRegisterReferenceExpression::undefined_arm_register; SgAsmRegisterReferenceExpression::arm_position_in_register_enum regSize = SgAsmRegisterReferenceExpression::undefined_arm_position_in_register; resolveRegisterX86(symbol, ®isterSg, ®Size); // binNode = new SgAsmRegisterReferenceExpression(registerSg, regSize); binNode = new SgAsmRegisterReferenceExpression(); (isSgAsmRegisterReferenceExpression(binNode))->set_arm_register_code(registerSg); (isSgAsmRegisterReferenceExpression(binNode))->set_arm_position_in_register_code(regSize); } // the child could be the expression to an address, e.g. ss:[ebp] // todo : dont know how to change this right now. Affected by AST structure change //isSgAsmRegisterReferenceExpression(binNode)->set_segment(child); rememberOffset = isSgAsmRegisterReferenceExpression(binNode); if (child==NULL) { cerr << "adding no child to RegisterReference " << endl; } child->set_parent(binNode); #endif } else if (expt->symbol=="+") { list<SgAsmExpression*>::iterator childList = children->begin(); int count=0; if (children->size()==1) { // the add has only one child SgAsmExpression* child = *(children->begin()); if (child) { binNode = child; // child->set_parent(previousExp); // if (isSgAsmMemoryReferenceExpression(previousExp)) // isSgAsmMemoryReferenceExpression(previousExp)->set_address(child); // changed on 16Jan08 //if (isSgAsmRegisterReferenceExpression(previousExp)) // isSgAsmRegisterReferenceExpression(previousExp)->set_offset(child); } } else { binNode = new SgAsmBinaryAdd(); for (; childList!=children->end();++childList) { SgAsmExpression* child = *childList; if (child) { if (count==0) isSgAsmBinaryAdd(binNode)->set_lhs(child); else isSgAsmBinaryAdd(binNode)->set_rhs(child); child->set_parent(binNode); } count++; } } } else if (expt->symbol=="-") { binNode = new SgAsmBinarySubtract(); list<SgAsmExpression*>::iterator childList = children->begin(); int count=0; for (; childList!=children->end();++childList) { SgAsmExpression* child = *childList; if (count==0) isSgAsmBinarySubtract(binNode)->set_lhs(child); else isSgAsmBinarySubtract(binNode)->set_rhs(child); count++; child->set_parent(binNode); } } else if (expt->symbol=="*") { binNode = new SgAsmBinaryMultiply(); list<SgAsmExpression*>::iterator childList = children->begin(); int count=0; for (; childList!=children->end();++childList) { SgAsmExpression* child = *childList; if (count==0) isSgAsmBinaryMultiply(binNode)->set_lhs(child); else isSgAsmBinaryMultiply(binNode)->set_rhs(child); count++; child->set_parent(binNode); } } else if (expt->symbol=="/") { binNode = new SgAsmBinaryDivide(); list<SgAsmExpression*>::iterator childList = children->begin(); int count=0; for (; childList!=children->end();++childList) { SgAsmExpression* child = *childList; if (count==0) isSgAsmBinaryDivide(binNode)->set_lhs(child); else isSgAsmBinaryDivide(binNode)->set_rhs(child); count++; child->set_parent(binNode); } } else if (expt->symbol=="[") { // the child is the expression that constitutes the address , e.g. [ebp] SgAsmExpression* child = *(children->begin()); // the child is another expression, like +, - , ... ROSE_ASSERT(child); binNode = new SgAsmMemoryReferenceExpression(); isSgAsmMemoryReferenceExpression(binNode)->set_type(SgAsmTypeQuadWord::createType()); ROSE_ASSERT (binNode->get_type()); isSgAsmMemoryReferenceExpression(binNode)->set_address(child); child->set_parent(binNode); // isSgAsmMemoryReferenceExpression(binNode)->set_offset(rememberOffset); //rememberOffset->set_parent(binNode); //rememberOffset=NULL; } else if (expt->symbol=="b4" || expt->symbol=="b2" || expt->symbol=="b1" || expt->symbol=="b6" || expt->symbol=="b8") { // since b4, b2, b1 are types and no nodes, // we return the binNode of the child binNode = *(children->begin()); if (isSgAsmMemoryReferenceExpression(binNode)) { SgAsmMemoryReferenceExpression* memRefT = isSgAsmMemoryReferenceExpression(binNode); if (expt->symbol=="b1") memRefT->set_type(SgAsmTypeByte::createType()); else if (expt->symbol=="b2") memRefT->set_type(SgAsmTypeWord::createType()); else if (expt->symbol=="b4") memRefT->set_type(SgAsmTypeDoubleWord::createType()); else if (expt->symbol=="b6") memRefT->set_type(SgAsmTypeByte::createType()); // FIXME else if (expt->symbol=="b8") memRefT->set_type(SgAsmTypeQuadWord::createType()); ROSE_ASSERT (memRefT->get_type()); } } else { cerr << "ERROR:: FIXME:: symbol not resolved " << expt->symbol << endl; // temp solution for arm. tps (09/17/07) binNode = new SgAsmIntegerValueExpression('5', 8); // ascii for 5 // exit(0); } } else if (expt->expr_type==2) { // its a value if (RoseBin_support::DEBUG_MODE()) cout << " its a value... resolving type: --- " << typeOfOperand << " --- " ; // fixme .. temporary fix for DB issue if (typeOfOperand=="BYTE") typeOfOperand="WORD"; if (typeOfOperand=="WORD") typeOfOperand="DWORD"; if (typeOfOperand=="BYTE") { binNode = SageBuilderAsm::makeByteValue(expt->immediate); } else if (typeOfOperand=="WORD") { binNode = SageBuilderAsm::makeWordValue(expt->immediate); } else if (typeOfOperand=="DWORD") { binNode = SageBuilderAsm::makeDWordValue(expt->immediate); } else if (typeOfOperand=="QWORD") { binNode = SageBuilderAsm::makeQWordValue(expt->immediate); } else if (typeOfOperand=="SFLOAT") { binNode = new SgAsmSingleFloatValueExpression(); isSgAsmSingleFloatValueExpression(binNode)->set_value(expt->immediate); } else if (typeOfOperand=="DFLOAT") { binNode = SageBuilderAsm::makeQWordValue(expt->immediate); } else { cerr << "ERROR :: unhandled type of value: " << typeOfOperand << " val: " << RoseBin_support::ToString(expt->immediate) << endl; // exit(0); // creating defualt for now binNode = SageBuilderAsm::makeDWordValue(expt->immediate); } if (RoseBin_support::DEBUG_MODE()) cout << typeOfOperand << endl; //printExprNode(*expt); } else if (expt->expr_type==1) { // register if (RoseBin_support::DEBUG_MODE()) cout << " its a register .... " << endl; if (RoseAssemblyLanguage==x86) { RegisterDescriptor regDesc; string symbol = RoseBin_support::str_to_upper(expt->symbol); resolveRegisterX86(symbol, ®Desc); //binNode = new SgAsmRegisterReferenceExpression(registerSg, regSize); binNode = new SgAsmx86RegisterReferenceExpression(regDesc); isSgAsmx86RegisterReferenceExpression(binNode)->set_type(getRegisterType(regDesc)); } else if (RoseAssemblyLanguage==arm) { RegisterDescriptor regDesc; string symbol = RoseBin_support::str_to_upper(expt->symbol); resolveRegisterX86(symbol, ®Desc); // binNode = new SgAsmRegisterReferenceExpression(registerSg, regSize); binNode = new SgAsmArmRegisterReferenceExpression(regDesc); // todo : find out types for ARM } } else { cerr << " ERROR ... buildTree ... wrong type " << endl; RoseBin_support::printExprNode(*expt); exit(0); } return binNode; }