boost::any InstructionListModel::data(const Wt::WModelIndex &index, int role) const { ASSERT_require(index.isValid()); ASSERT_require(index.row()>=0 && (size_t)index.row() < insns_.size()); SgAsmInstruction *insn = insns_[index.row()]; if (Wt::DisplayRole == role) { switch (index.column()) { case C_ADDR: { return Wt::WString(StringUtility::addrToString(insn->get_address())); } case C_BYTES: { std::string s; for (size_t i=0; i<insn->get_raw_bytes().size(); ++i) { uint8_t byte = insn->get_raw_bytes()[i]; char buf[32]; sprintf(buf, "%02x", byte); s += std::string(i?" ":"") + buf; } return Wt::WString(s); } case C_CHARS: { std::string s; for (size_t i=0; i<insn->get_raw_bytes().size(); ++i) { char ch = insn->get_raw_bytes()[i]; s += std::string(i?" ":"") + (isgraph(ch) ? std::string(1, ch) : std::string(" ")); } return Wt::WString(s); } case C_STACKDELTA: { int64_t delta = insn->get_stackDelta(); if (delta == SgAsmInstruction::INVALID_STACK_DELTA) return Wt::WString(""); std::string s = (delta >= 0 ? "+" : "") + boost::lexical_cast<std::string>(delta); return Wt::WString(s); } case C_NAME: { return Wt::WString(unparseMnemonic(insn)); } case C_ARGS: { std::string s; const RegisterDictionary *regs = ctx_.partitioner.instructionProvider().registerDictionary(); const SgAsmExpressionPtrList &operands = insn->get_operandList()->get_operands(); for (size_t i=0; i<operands.size(); ++i) s += (i?", ":"") + unparseExpression(operands[i], NULL, regs); return Wt::WString(s); } case C_COMMENT: { return Wt::WString(insn->get_comment()); } default: ASSERT_not_reachable("invalid column number"); } } return boost::any(); }
/**************************************************** * process operand tuples. * Handles all expressions to be added to the instructions. ****************************************************/ void RoseBin_DB_IDAPRO::process_operand_tuples_query(MYSQL* conn, MYSQL_RES* res_set) { // get the functions rememberOperandStrings.clear(); // Not needed right now char* q = (char*)"SELECT * FROM operand_tuples_1 order by operand_id desc"; if (RoseBin_support::DEBUG_MODE()) cout << "\n>> QUERY:: " << q << "\n" << endl; res_set = process_query(conn,q); if (res_set == NULL) { print_problemWithResults(conn); } else { map < int, vector < SgAsmExpression* > > tmp_instruction_map; // tmp_instruction_map.clear(); MYSQL_ROW row; long address=0; int operand_id=-1; int position =-1; while ((row = mysql_fetch_row(res_set))!=NULL) { for (unsigned int i=0; i<mysql_num_fields(res_set);i++) { char* ret=(char*)""; if (row[i] ==NULL) { ret = (char*)"<NULL>"; if (i==0) address = -1; if (i==1) operand_id = -1; if (i==2) position = -1; } else { ret= row[i]; if (i==0) address = atoi(ret); if (i==1) operand_id = atoi(ret); if (i==2) position = atoi(ret); } } //cerr << " >>>>>>>>>> position : " << position; // if this would have to be saved in a map, it would need to be a multimap!! //if (RoseBin_support::DEBUG_MODE()) { ostringstream addrhex; addrhex << hex << setw(8) << address ; //cout<< "\n\n----------------------------------------------------------------" << endl; if (operand_id % 5000 == 0) { cout << ">> creating operand_tuple : address: " << addrhex.str() << " " << address << " - operand_id: " << operand_id << " - position:" << position << endl; } //} // get the expr_id for the operand_id SgAsmExpression* binExp=NULL; //string operand_str=(char*)""; if (operand_id>=0) { // operand_str = rememberOperandStrings.find(operand_id) != rememberOperandStrings.end() ? rememberOperandStrings[operand_id] : ""; //if (RoseBin_support::DEBUG_MODE()) //cout << ">>>> operand_str: " << operand_str << endl; ROSE_ASSERT (operand_id < (int)rememberExpressionTree_ROOT.size()); int expr_id_root = rememberExpressionTree_ROOT[operand_id]; ROSE_ASSERT (operand_id < (int)rememberExpressionTree_ParentChild.size()); map <int, vector<int> > subTree = rememberExpressionTree_ParentChild[operand_id]; rememberExpressionTree_ROOT.resize(operand_id + 1); rememberExpressionTree_ParentChild.resize(operand_id + 1); ROSE_ASSERT (expr_id_root < (int)rememberExpressionTree.size()); exprTreeType exprTree = rememberExpressionTree[expr_id_root]; string typeOfOperand = resolveType(&exprTree); #if 0 // print multimapsolveRe if (RoseBin_support::DEBUG_MODE()) { multimap<int,int>::iterator it = subTree.begin(); for (; it!=subTree.end();++it) { int f=it->first; int s=it->second; cout << " mm : " << f << "," << s << endl; } } #endif binExp = buildROSE->resolveRecursivelyExpression(address,expr_id_root, subTree, typeOfOperand, &rememberExpressionTree, operand_id, &rememberSubstitution, &rememberComments); } // if operand // should save for each instruction, a list of operands and their position // and add the operand later on to the instruction // map < address, map < pos, binExp > > vector<SgAsmExpression*>& currentOperands = tmp_instruction_map[address]; if (position >= (int)currentOperands.size()) currentOperands.resize(position + 1); currentOperands[position] = binExp; #if 0 map <int, map <int, SgAsmExpression*> >::iterator tmpIt = tmp_instruction_map.find(address); bool found=false; if (tmpIt!=tmp_instruction_map.end()) found=true; if (found) { //cerr << " found position: " << position << endl; // I do not want to add an address into tmp if not in (side effect!) map <int, SgAsmExpression*> tmp_map = tmp_instruction_map[address]; tmp_map[position] = binExp; tmp_instruction_map[address] = tmp_map; } else { // first time visit //cerr << " notfound position: " << position << endl; map <int, SgAsmExpression*> tmp_map; tmp_map[position] = binExp; tmp_instruction_map[address] = tmp_map; } #endif } // while // get basic_block and append this instruction if (RoseBin_support::DEBUG_MODE()) cout << "\n\n> appending operandList to instruction. " << endl; rose_hash::unordered_map <uint64_t, SgAsmInstruction* >::iterator blockIt; int count = 0; cerr << "Instruction count: " << rememberInstructions.size() << endl; for (blockIt=rememberInstructions.begin();blockIt!=rememberInstructions.end();++blockIt) { ++count; if (count % 1000 == 0) cout << "Adding operands to instruction " << count << endl; int inst_address = blockIt->first; SgAsmInstruction* remInstr = blockIt->second; map<int, vector< SgAsmExpression*> >::iterator it = tmp_instruction_map.find(inst_address); if (it != tmp_instruction_map.end()) { // Skip for instructions without operands vector < SgAsmExpression*>& exprList_forInst = it->second; int sizeList = exprList_forInst.size(); // find each element separately for (int i=0; i<sizeList; i++) { SgAsmExpression* binExp = exprList_forInst[i]; #if 0 map <int, SgAsmExpression*>::iterator it = exprList_forInst.find(i); // get the elements in order!! this is important. SgAsmExpression* binExp = it->second; #endif remInstr->get_operandList()->append_operand(binExp); binExp->set_parent(remInstr->get_operandList()); exprTreeType exprTree = buildROSE->getDebugHelp(binExp); if (RoseBin_support::DEBUG_MODE()) cout << ">> append operand (to instruction): binExp: " <<binExp << " - sym: " <<exprTree.symbol << " - immedi: " << exprTree.immediate << endl; } tmp_instruction_map.erase(it); } } } // if (res_set==NULL) checkError(conn,res_set); }