ExtendedException::ExtendedException(const char *fmt, ...) { va_list ap; va_start(ap, fmt); format(fmt, ap); va_end(ap); if (RuntimeOption::InjectedStackTrace) { m_bt = ArrayPtr(new Array(FrameInjection::GetBacktrace(false, true))); } }
void RebuildFunc(SYMBOL *sym) { OpcodeInfo thisOp; SYMBOL *ref; uchar *ip, *ip_end, *ip_last; int real_ip; char str[256]; if (!sym) return; RebuildEmit("\n//****************************************\n"); RebuildEmit("// Function: %s\n", sym->Name); RebuildEmit("//****************************************\n\n"); #if 0 //OLD if (strcmp(sym->Name, Code_EntryPoint) == 0) { RebuildEmit(".global %s\n", sym->Name); RebuildEmit(".func %s\n", sym->Name); } else { RebuildEmit(".func %s_%d\n", sym->Name, sym->LocalScope); } #else //New if (strcmp(sym->Name, Code_EntryPoint) == 0) { RebuildEmit(".global %s\n", sym->Name); RebuildEmit(".func %s, %d, %s\n", sym->Name, sym->Params, RebuildRetType(sym->RetType) ); } else { RebuildEmit(".func %s_%d, %d, %s\n", sym->Name, sym->LocalScope, sym->Params, RebuildRetType(sym->RetType)); } #endif ip_end = (uchar *) ArrayPtr(&CodeMemArray, sym->EndIP); ip = (uchar *) ArrayPtr(&CodeMemArray, sym->Value); real_ip = sym->Value; while(1) { ip_last = ip; if (ip > ip_end) break; // Print labels ref = (SYMBOL *) ArrayGet(&CodeLabelArray, real_ip); if (ref) { if (ref->LabelType == label_Local) RebuildEmit("%s_%d:\n", ref->Name, ref->LocalScope); } RebuildEmitStabs(real_ip); // Peeper(ip, ip_end); if (ArgSkipElim == 0) if (ArrayGet(&CodeTouchArray, real_ip) == 0) RebuildEmit("// "); CaseRef = 0; ip = DecodeOpcode(&thisOp, ip); DecodeAsmString(&thisOp, str, 1); RebuildEmit("\t%s", str); // DecodeAsmString(&thisOp, str, 0); // Sanity testing // CodeSanityChecker(thisOp.rip, str); if (ArgDebugRebuild) { int len = 4 + strlen(str); str[0] = 0; while(len < 40) { RebuildEmit(" ", str); len++; } RebuildEmit("; 0x%x - ", real_ip); DisassembleFromSource(real_ip, str); RebuildEmit("%s", str); } RebuildEmit("\n"); // Check for case statement, which need case data after them if (CaseRef) { RebuildEmit(".data\n"); Rebuild_Data(CaseRef); RebuildEmit(".code\n"); } real_ip += (ip - ip_last); } }
void RebuildCppFunc(SYMBOL *sym, int isproto) { OpcodeInfo thisOp; SYMBOL *ref; uchar *ip, *ip_end, *ip_last; int real_ip; // char str[256]; if (!sym) return; // Say no returns yet ReturnCount = 0; // Enumerate this functions labels, unless we're generating a proto if (isproto == 0) EnumerateFunctionLabels(sym); ThisFunctionRegs = FunctionRegUsage(sym); ThisFunctionRetType = sym->RetType; if (ThisFunctionRegs == -1) return; RebuildCppProlog(sym, isproto); // if we're generating a proto return if (isproto) return; ip_end = (uchar *) ArrayPtr(&CodeMemArray, sym->EndIP); ip = (uchar *) ArrayPtr(&CodeMemArray, sym->Value); real_ip = sym->Value; while(1) { ip_last = ip; if (ip > ip_end) break; // Print labels ref = (SYMBOL *) ArrayGet(&CodeLabelArray, real_ip); if (ref) { if (ref->LabelType == label_Local) { #ifdef Cpp_DEBUG RebuildEmit("// %s_%d:\n", ref->Name, ref->LocalScope); #endif RebuildEmit("label_%d:;\n", ref->LabelEnum); } } if (ArrayGet(&CodeTouchArray, real_ip) == 0) RebuildEmit("// "); CaseRef = 0; ip = DecodeOpcode(&thisOp, ip); ThisFunctionExit = 0; if (ip > ip_end) ThisFunctionExit = 1; RebuildCppInst(&thisOp); // DecodeAsmString(&thisOp, str); // RebuildEmit("\t%s", str); #ifdef CPP_DEBUG { int len = 4 + strlen(str); str[0] = 0; while(len < 40) { RebuildEmit(" ", str); len++; } DisassembleFromSource(real_ip, str); RebuildEmit(";%s", str); } #endif // RebuildEmit("\n"); // Check for case statement, which need case data after them /* if (CaseRef) { RebuildEmit(".data\n"); Rebuild_Data(CaseRef); RebuildEmit(".code\n"); } */ real_ip += (ip - ip_last); } RebuildCppEpilog(sym); }
ExtendedException::ExtendedException(const std::string &msg) { m_msg = msg; if (RuntimeOption::InjectedStackTrace) { m_bt = ArrayPtr(new Array(FrameInjection::GetBacktrace(false, true))); } }
ExtendedException::ExtendedException() : Exception() { if (RuntimeOption::InjectedStackTrace) { m_bt = ArrayPtr(new Array(FrameInjection::GetBacktrace(false, true))); } }
ArrayPtr ArrayPtr::operator - ( int _numPositions ) const { return ArrayPtr( *this ) -= _numPositions; }
int FunctionRegAnalyse(SYMBOL *sym, FuncProp *fp) { OpcodeInfo thisOp; uchar *ip, *ip_end; int params,n; fp->src_reg = 0; fp->dst_reg = 0; fp->assign_reg = 0; fp->uninit_reg = 0; // Make sure we have a valid symbol if (!sym) return -1; // Make sure the symbol is a function if (sym->Type != SECT_code) return -1; // Get the start and end of the function in the code array ip_end = (uchar *) ArrayPtr(&CodeMemArray, sym->EndIP); ip = (uchar *) ArrayPtr(&CodeMemArray, sym->Value); // Set up the parameter regs params = sym->Params; for (n=0;n<params;n++) { fp->assign_reg |= REGBIT(REG_i0 + n); } // Scan the function #ifdef AFDEBUG printf("\n"); #endif while(1) { if (ip > ip_end) break; #ifdef AFDEBUG { char buf[2560]; buf[0] = 0; DisassembleFromSource(ip - CodeMemArray.array, buf); printf("%s\n", buf); } #endif ip = DecodeOpcode(&thisOp, ip); // Ignor push and pop if (thisOp.op == _PUSH) continue; if (thisOp.op == _POP) continue; //----------------------------------------- // Deal with syscalls // for some strange reason rd is the syscallId which will // tag unused registers as used for void functions //----------------------------------------- if(thisOp.op == _SYSCALL) { FunctionReg_Syscall(&thisOp, fp); } // Check for a dest reg else if (thisOp.flags & fetch_d) { if (thisOp.rd < 32) { // Since this is a dst regs we say its initialized fp->assign_reg |= REGBIT(thisOp.rd); // Say this reg was used as a dst reg fp->dst_reg |= REGBIT(thisOp.rd); } } // Check for a source reg if (thisOp.flags & fetch_s) { if (thisOp.rs < 32) { // check if this reg was assigned previously, if it was'nt it is uninitialized before use int is_assigned = fp->assign_reg & REGBIT(thisOp.rs); if (!is_assigned) fp->uninit_reg |= REGBIT(thisOp.rs); fp->src_reg |= REGBIT(thisOp.rs); } } //----------------------------------------- // Deal with immediate calls //----------------------------------------- // Add the call parameters to the used list if (thisOp.op == _CALLI) { FunctionReg_Calli(&thisOp, fp); } //----------------------------------------- // Deal with register calls //----------------------------------------- // Add the call parameters to the used list if (thisOp.op == _CALL) { FunctionReg_CallReg(&thisOp, fp); } } #ifdef AFDEBUG printf("\n"); printf(" rrrrrrrrrrrrrrrriiiiddddddddfrsz\n"); printf(" fedcba9876543210321076543210rtpr\n"); printf("src_reg = %s\n", Bin32(fp->src_reg)); printf("dst_reg = %s\n", Bin32(fp->dst_reg)); printf("assign_reg = %s\n", Bin32(fp->assign_reg)); printf("uninit_reg = %s\n", Bin32(fp->uninit_reg)); if (fp->uninit_reg) printf(""); #endif // Make sure zr is never uninitialized fp->uninit_reg &= ~REGBIT(REG_zero); // Make a composit of which reg's were used fp->reg_used = fp->src_reg | fp->dst_reg; return fp->reg_used; }