void generate_NOT( quad *quad ){ quad->taddress = nextInstructionLabel(); instruction *t = InitInstruction(); instruction *t1 = InitInstruction(); instruction *t2 = InitInstruction(); instruction *t3 = InitInstruction(); t->opcode = jeq_v; make_operand( quad->arg1, t->arg1 ); make_booloperand( t->arg2, 1 ); t->result->type = label_a; t->result->val = nextInstructionLabel()+3; emitVmarg( t ); t1->opcode = assign_v; make_booloperand( t1->arg1, 1 ); //reset_operand( t->arg2 ); make_operand( quad->result, t1->result ); emitVmarg( t1 ); t2->opcode = jump_v; //reset_operand( t1->arg1 ); //reset_operand( t1->arg2 ); t2->result->type = label_a; t2->result->val = nextInstructionLabel()+2; emitVmarg( t2 ); t2->opcode = assign_v; make_booloperand( t2->arg1, 0 ); reset_operand( t2->arg2 ); make_operand( quad->result, t2->result ); emitVmarg( t2 ); }
void generate_AND( quad *quad ){ instruction *t = InitInstruction(); instruction *t1 = InitInstruction(); instruction *t2 = InitInstruction(); instruction *t3 = InitInstruction(); instruction *t4 = InitInstruction(); quad->taddress = nextInstructionLabel(); t->opcode = jeq_v; make_operand( quad->arg1, t->arg1 ); make_booloperand( t->arg2, 0); t->result->type = label_a; t->result->val = nextInstructionLabel()+4; emitVmarg( t ); t1->opcode = jeq_v; make_operand(quad->arg2,t1->arg1); make_booloperand(t1->arg2,0); t1->result = make_vmarg(); (t1->result)->val = nextInstructionLabel()+3; (t1->result)->type = label_a; emitVmarg( t1 ); t2->opcode = assign_v; make_booloperand(t2->arg1,1); t2->arg2 = reset_operand(); make_operand(quad->result,t2->result); t2->srcLine = quad->line; emitVmarg(t2); t3->opcode = jump_v; t3->arg1 = reset_operand(); t3->arg2 = reset_operand(); t3->result = make_vmarg(); (t3->result)->type = label_a; (t3->result)->val = nextInstructionLabel()+2; t3->srcLine = quad->line; emitVmarg(t3); t4->opcode = assign_v; make_booloperand(t4->arg1,0); t4->arg2 = reset_operand(); make_operand(quad->result,t4->result); t4->srcLine = quad->line; emitVmarg(t4); return; }
// If Decode = FALSE, only the following fields are valid: // Instruction->Length, Instruction->Address, Instruction->Prefixes, Instruction->PrefixCount, // Instruction->OpcodeBytes, Instruction->Instruction->OpcodeLength, Instruction->Groups, // Instruction->Type, Instruction->OperandCount // // If Disassemble = TRUE, then Instruction->String is valid (also requires Decode = TRUE) // // WARNING: This will overwrite the previously obtained instruction INSTRUCTION *GetInstruction(DISASSEMBLER *Disassembler, U64 VirtualAddress, U8 *Address, U32 Flags) { if (Disassembler->Initialized != DISASSEMBLER_INITIALIZED) { assert(0); return NULL; } assert(Address); InitInstruction(&Disassembler->Instruction, Disassembler); Disassembler->Instruction.Address = Address; Disassembler->Instruction.VirtualAddressDelta = VirtualAddress - (U64)Address; if (!Disassembler->Functions->GetInstruction(&Disassembler->Instruction, Address, Flags)) { assert(Disassembler->Instruction.Address == Address); assert(Disassembler->Instruction.Length < MAX_INSTRUCTION_LENGTH); // Save the address that failed, in case the lower-level disassembler didn't Disassembler->Instruction.Address = Address; Disassembler->Instruction.ErrorOccurred = TRUE; return NULL; } return &Disassembler->Instruction; }
void generate_CALL( quad* quad ){ quad->taddress = nextInstructionLabel(); ///print///printf("QUAD FUNC NUM: %d",quad->line ); instruction *t = malloc( sizeof( instruction ) ); t->result = malloc(sizeof(vmarg)); t->opcode = call_v; make_operand( quad->result, t->result ); reset_operand(t->arg1); reset_operand(t->arg2); t->srcLine = quad->line; t->result->val = FindFunctionUser((quad->result->sym)->name,deepestFunctionScope); if (t->result->val == -1){ if(isLibFunction((quad->result->sym)->name)){ int check = FindLibFunction((quad->result->sym)->name); if (check == -1){ instruction *t1 =(instruction *) InitInstruction(); expr * e = malloc(sizeof(expr)); e->type = libraryfunc_e; e->sym =createS( (quad->result->sym)->name, 0, 0, (quad->result->sym)->name, 0, 0, "lib_func", 1,currscopespace(),currscopeoffset()); make_operand(e,t1->arg1); } t->result->val = FindLibFunction((quad->result->sym)->name); t->result->type = libfunc_a; emitVmarg( t ); } } else { emitVmarg( t ); } return; }
int CVPParser::Parse(const char *str) { int i,iline = 0; bool inProgram = false; std::stringstream input(str); struct nvfx_src none = nvfx_src(nvfx_reg(NVFXSR_NONE,0)); while(!input.eof()) { char line[256]; opcode *opc = NULL; struct nvfx_insn *insn = NULL; input.getline(line,255); iline++; for(i=0; i<256; i++) { char c = line[i]; if(c=='\n' || c=='\r' || c==';') c = 0; if(c=='\t') c = ' '; line[i] = c; if(c==0) break; } if(line[0]=='#') { ParseComment(line); continue; } if(!inProgram) { if(strncmp(line,"!!VP2.0",7)==0) inProgram = true; else if(strncmp(line,"!!ARBvp1.0",10)==0) inProgram = true; continue; } char *label = NULL; char *col_ptr = NULL; char *opcode = NULL; char *ptr = line; if((col_ptr = strstr((char*)ptr,":"))!=NULL) { int j = 0; bool valid = true; while((ptr+j)<col_ptr) { if(j==0 && !(isLetter(ptr[j]) || ptr[j]=='_')) valid = false; if(!(isLetter(ptr[j]) || isDigit(ptr[j]) || ptr[j]=='_')) valid = false; j++; } if(valid) { label = strtok(ptr,":\x20"); ptr = col_ptr + 1; } } opcode = strtok(ptr," "); if(label) { jmpdst d; strcpy(d.ident,label); d.location = m_nInstructions; m_lIdent.push_back(d); } if(opcode) { char *param_str = SkipSpaces(strtok(NULL,"\0")); if(strcasecmp(opcode,"OPTION")==0) { if(strncasecmp(param_str,"NV_vertex_program3",18)==0) m_nOption |= NV_OPTION_VP3; continue; } else if(strcasecmp(opcode,"PARAM")==0) continue; else if(strcasecmp(opcode,"TEMP")==0) continue; else { opc = FindOpcode(opcode); insn = &m_pInstructions[m_nInstructions]; if(!opc) continue; InitInstruction(insn,opc->opcode); if(opc->opcode==OPCODE_END) { m_nInstructions++; break; } char *opc_ext = opcode + strlen(opc->mnemonic); if(m_nOption&(NV_OPTION_VP2|NV_OPTION_VP3)) { if(opc_ext[0]=='C') { insn->cc_update = TRUE; if(m_nOption&NV_OPTION_VP3 && (opc_ext[1]=='0' || opc_ext[1]=='1')) { switch(opc_ext[1]) { case '0': insn->cc_update_reg = 0; break; case '1': insn->cc_update_reg = 1; break; } opc_ext++; } opc_ext++; } } if(opc_ext[0]=='_') { if(strncasecmp(opc_ext,"_sat",4)==0) insn->sat = TRUE; } ParseInstruction(insn,opc,param_str); m_nInstructions++; } } } for(std::list<jmpdst>::iterator r=m_lJmpDst.begin(); r!=m_lJmpDst.end(); r++) { bool found = false; for(std::list<jmpdst>::iterator i=m_lIdent.begin(); i!=m_lIdent.end(); i++) { if(strcmp(r->ident,i->ident)==0) { found = true; m_pInstructions[r->location].dst = nvfx_reg(NVFXSR_RELOCATED,i->location); break; } } if(found==false) { fprintf(stderr,"Identifier \'%s\' not found.\n",r->ident); exit(EXIT_FAILURE); } } return 0; }
/* * 获取单个函数帧 * 使用IsProcEnd函数鉴别末尾,不处理中间遇到的CALL指令 */ __INLINE__ PPROCEDURE __INTERNAL_FUNC__ GetProcFrame(__memory pMem, __memory pStart, __integer iBlockMaxSize, PPROGRAM pParents) { PPROCEDURE pProcedure = InitProcedure(pParents); PX86INSTRUCTION pInstructionPrev = NULL, *pInstructionPoint = &(pProcedure->pInstruction); __address ImageBase = pParents->ImageBase; __offset ofOffset = 0; __integer iContinueSize = 0, iInstCount = 0; __bool bPredictProcEnd = FALSE;//是否启用预测函数结尾 ud_t ud_obj; ud_init(&ud_obj); ud_set_mode(&ud_obj, 32); ud_set_input_buffer(&ud_obj, pStart, iBlockMaxSize); ud_set_syntax(&ud_obj, UD_SYN_INTEL); /* * 预测结尾分析 * 可以在为遍历完指令流时,预先知道函数的末尾 */ // 获取整个函数框架 while (ud_disassemble(&ud_obj)) { __memory pCurrent = pStart + ofOffset; // 如果是未知指令,则记录它的数量 if (ud_obj.mnemonic == UD_Iinvalid) (pProcedure->iInvalidOpcodeCount)++; *pInstructionPoint = InitInstruction(pProcedure, pInstructionPrev); AnalyzeInstructionPass1(&ud_obj, pMem, ImageBase, pCurrent, ofOffset, *pInstructionPoint); pInstructionPrev = *pInstructionPoint; // 判断是否到达函数末尾,常规分析 if (IsProcEnd(&ud_obj, pProcedure->pInstruction, *pInstructionPoint, &bPredictProcEnd, &iContinueSize)) { ofOffset += ud_obj.inp_ctr; iInstCount++; goto _end_while; } /* * 如果进入这里则说明当前指令必定是ret指令 */ if (bPredictProcEnd) { // 将反汇编的缓冲区长度设置为 // 从当前指令到预测出的函数结尾 __memory pRetNextInstruction = (*pInstructionPoint)->pCurrFileAddress + ud_obj.inp_ctr;//得到ret指令下一条指令的位置 ofOffset += ud_obj.inp_ctr;//将当前指令的长度加入偏移值内 ud_set_input_buffer(&ud_obj, pRetNextInstruction, (size_t)iContinueSize);//ud_obj会重新初始化 pInstructionPoint = &((*pInstructionPoint)->pNext); iInstCount++; bPredictProcEnd = FALSE; continue;//直接进入下一轮 } // 移动指针 pInstructionPoint = &((*pInstructionPoint)->pNext); ofOffset += ud_obj.inp_ctr; iInstCount++; }/* end while */ _end_while: // 填充函数基本信息 pProcedure->addrMemoryStartAddress = pParents->ImageBase + AnalyzerRaw2Rva(pMem, (__integer)(pStart - pMem)); pProcedure->pFileStartAddress = pStart; pProcedure->iSize = (__integer)ofOffset; pProcedure->iInstCount = iInstCount; pProcedure->pInstructionJmp = GetInstructionJmpListHeader(pProcedure); return pProcedure; }
int CFPParser::Parse(const char *str) { int i,iline = 0; bool inProgram = false; std::stringstream input(str); while(!input.eof()) { char line[256]; struct nvfx_insn *insn = NULL; input.getline(line,255); iline++; for(i=0;i<256;i++) { char c = line[i]; if(c=='\n' || c=='\r' || c==';') c = 0; if(c=='\t') c = ' '; line[i] = c; if(c==0) break; } if(line[0]=='#') { ParseComment(line); continue; } if(!inProgram) { if(strncmp(line,"!!FP2.0",7)==0) inProgram = true; else if(strncmp(line,"!!ARBfp1.0",10)==0) inProgram = true; continue; } char *label = NULL; char *col_ptr = NULL; char *opcode = NULL; char *ptr = line; if((col_ptr = strstr((char*)ptr,":"))!=NULL) { int j = 0; bool valid = true; while((ptr+j)<col_ptr) { if(j==0 && !(isLetter(ptr[j]) || ptr[j]=='_')) valid = false; if(!(isLetter(ptr[j]) || isDigit(ptr[j]) || ptr[j]=='_')) valid = false; j++; } if(valid) { label = strtok(ptr,":\x20"); ptr = col_ptr + 1; } } opcode = strtok(ptr," "); if(opcode) { char *param_str = SkipSpaces(strtok(NULL,"\0")); if(strcasecmp(opcode,"OPTION")==0) { if(strncasecmp(param_str,"NV_fragment_program2",20)==0) m_nOption |= NV_OPTION_FP2; continue; } else if(strcasecmp(opcode,"PARAM")==0) continue; else if(strcasecmp(opcode,"TEMP")==0) continue; else if(strcasecmp(opcode,"OUTPUT")==0) { ParseOutput(param_str); continue; } else { struct _opcode opc = FindOpcode(opcode); insn = &m_pInstructions[m_nInstructions]; if(opc.opcode>=MAX_OPCODE) continue; InitInstruction(insn,opc.opcode); if(opc.opcode==OPCODE_END) { m_nInstructions++; break; } ParseInstruction(insn,&opc,param_str); m_nInstructions++; } } } return 0; }