/**************************************************** * traverse the binary AST to test if all nodes are there ****************************************************/ void RoseFile::visit(SgNode* node) { SgAsmFunction* funcDecl= isSgAsmFunction(node); SgAsmInstruction* instr= isSgAsmInstruction(node); //SgAsmBlock* block= isSgAsmBlock(node); nodes++; //cerr << " traversing node " << binNode << endl; if (funcDecl) { trav_funcs++; // should have a parent SgAsmBlock* glob = isSgAsmBlock(funcDecl->get_parent()); if (glob==NULL) { int address = funcDecl->get_address(); ostringstream addrhex; addrhex << hex << setw(8) << address ; //cerr << " func with no global :: " << addrhex.str() << " " << address << endl; } // ROSE_ASSERT(glob); } /* if (block) { trav_blocks++; SgAsmFunction* func = isSgAsmFunction(block->get_parent()); int address = block->get_address(); ostringstream addrhex; addrhex << hex << setw(8) << address ; //if (func==NULL) { //cerr << trav_blocks << " block with no function :: " << addrhex.str() << " " << address << endl; //} else //cerr << trav_blocks << " block with no function :: " << addrhex.str() << " " << address << endl; //ROSE_ASSERT(func); } */ if (isSgAsmMemoryReferenceExpression(node)) { SgAsmMemoryReferenceExpression* n = isSgAsmMemoryReferenceExpression(node); // cerr << "Found a SgAsmMemoryReferenceExpression" << endl; ROSE_ASSERT(n->get_type()); } if (instr) { trav_inst++; SgAsmFunction* ins = isSgAsmFunction(instr->get_parent()); if (ins==NULL) { int address = ins->get_address(); ostringstream addrhex; addrhex << hex << setw(8) << address ; cerr << " ERROR :: instr with no parent function :: " << addrhex.str() << " " << address << endl; } //ROSE_ASSERT(ins); } SgAsmNode* asmNode = isSgAsmNode(node); if (asmNode) if (asmNode->get_parent()==NULL) { if (!isSgAsmBlock(asmNode)) { cerr << " PARENT == NULL :: " << asmNode->class_name() << endl; ROSE_ASSERT(asmNode->get_parent()); } } }
std::string unparseX86Expression(SgAsmExpression *expr, const AsmUnparser::LabelMap *labels, bool leaMode) { std::string result = ""; if (expr == NULL) return "BOGUS:NULL"; switch (expr->variantT()) { case V_SgAsmBinaryAdd: result = unparseX86Expression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, false) + " + " + unparseX86Expression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, false); break; case V_SgAsmBinarySubtract: result = unparseX86Expression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, false) + " - " + unparseX86Expression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, false); break; case V_SgAsmBinaryMultiply: result = unparseX86Expression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, false) + "*" + unparseX86Expression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, false); break; case V_SgAsmMemoryReferenceExpression: { SgAsmMemoryReferenceExpression* mr = isSgAsmMemoryReferenceExpression(expr); if (!leaMode) { result += x86TypeToPtrName(mr->get_type()) + " PTR " + (mr->get_segment() ? unparseX86Expression(mr->get_segment(), labels, false) + ":" : ""); } result += "[" + unparseX86Expression(mr->get_address(), labels, false) + "]"; break; } case V_SgAsmx86RegisterReferenceExpression: { SgAsmx86RegisterReferenceExpression* rr = isSgAsmx86RegisterReferenceExpression(expr); result = unparseX86Register(rr->get_descriptor()); break; } case V_SgAsmByteValueExpression: case V_SgAsmWordValueExpression: case V_SgAsmDoubleWordValueExpression: case V_SgAsmQuadWordValueExpression: case V_SgAsmIntegerValueExpression: { SgAsmIntegerValueExpression *ival = isSgAsmIntegerValueExpression(expr); assert(ival!=NULL); uint64_t value = ival->get_absolute_value(); // not sign extended result = StringUtility::addrToString(value, ival->get_significant_bits(), true/*signed*/); // Optional label. Prefer a label supplied by the caller's LabelMap, but not for single-byte constants. If // there's no caller-supplied label, then consider whether the value expression is relative to some other IR node. std::string label; if (ival->get_significant_bits()>8) label =x86ValToLabel(value, labels); if (label.empty()) label = ival->get_label(); if (!label.empty()) result += "<" + label + ">"; break; } default: { std::cerr << "Unhandled expression kind " << expr->class_name() << std::endl; ROSE_ASSERT (false); } } if (expr->get_replacement() != "") { result += " <" + expr->get_replacement() + ">"; } #if 0 if (expr->get_bit_size()>0) { result += " <@" + StringUtility::numberToString(expr->get_bit_offset()) + "+" + StringUtility::numberToString(expr->get_bit_size()) + ">"; } #endif return result; }
std::string unparseX86Expression(SgAsmExpression *expr, const AsmUnparser::LabelMap *labels, const RegisterDictionary *registers, bool leaMode) { std::string result = ""; if (expr == NULL) return "BOGUS:NULL"; switch (expr->variantT()) { case V_SgAsmBinaryAdd: result = unparseX86Expression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, registers, false) + " + " + unparseX86Expression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, registers, false); break; case V_SgAsmBinarySubtract: result = unparseX86Expression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, registers, false) + " - " + unparseX86Expression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, registers, false); break; case V_SgAsmBinaryMultiply: result = unparseX86Expression(isSgAsmBinaryExpression(expr)->get_lhs(), labels, registers, false) + "*" + unparseX86Expression(isSgAsmBinaryExpression(expr)->get_rhs(), labels, registers, false); break; case V_SgAsmMemoryReferenceExpression: { SgAsmMemoryReferenceExpression* mr = isSgAsmMemoryReferenceExpression(expr); if (!leaMode) { result += x86TypeToPtrName(mr->get_type()) + " " + (mr->get_segment() ? unparseX86Expression(mr->get_segment(), labels, registers, false) + ":" : ""); } result += "[" + unparseX86Expression(mr->get_address(), labels, registers, false) + "]"; break; } case V_SgAsmDirectRegisterExpression: { SgAsmInstruction *insn = SageInterface::getEnclosingNode<SgAsmInstruction>(expr); SgAsmDirectRegisterExpression* rr = isSgAsmDirectRegisterExpression(expr); result = unparseX86Register(insn, rr->get_descriptor(), registers); break; } case V_SgAsmIndirectRegisterExpression: { SgAsmInstruction *insn = SageInterface::getEnclosingNode<SgAsmInstruction>(expr); SgAsmIndirectRegisterExpression* rr = isSgAsmIndirectRegisterExpression(expr); result = unparseX86Register(insn, rr->get_descriptor(), registers); if (!result.empty() && '0'==result[result.size()-1]) result = result.substr(0, result.size()-1); result += "(" + StringUtility::numberToString(rr->get_index()) + ")"; break; } case V_SgAsmIntegerValueExpression: { SgAsmIntegerValueExpression *ival = isSgAsmIntegerValueExpression(expr); ASSERT_not_null(ival); uint64_t value = ival->get_absoluteValue(); // not sign extended // If the value looks like it might be an address, then don't bother showing the decimal form. if ((32==ival->get_significantBits() || 64==ival->get_significantBits()) && value > 0x0000ffff && value < 0xffff0000) { result = StringUtility::addrToString(value, ival->get_significantBits()); } else { result = StringUtility::signedToHex2(value, ival->get_significantBits()); } // Optional label. Prefer a label supplied by the caller's LabelMap, but not for single-byte constants. If // there's no caller-supplied label, then consider whether the value expression is relative to some other IR node. if (expr->get_comment().empty()) { std::string label; if (label.empty() && ival->get_significantBits()>8) label =x86ValToLabel(value, labels); if (label.empty()) label = ival->get_label(); result = StringUtility::appendAsmComment(result, label); } break; } default: { ASSERT_not_reachable("invalid x86 expression: " + expr->class_name()); } } result = StringUtility::appendAsmComment(result, expr->get_replacement()); result = StringUtility::appendAsmComment(result, expr->get_comment()); return result; }
/**************************************************** * 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; }