From feff40a5200f8c08dd7d81deae8fa1d52e32675e Mon Sep 17 00:00:00 2001 From: clc5q <clc5q@git.zephyr-software.com> Date: Fri, 22 Feb 2008 03:29:46 +0000 Subject: [PATCH] Restructured code into SMPProgram module; fixed shl/shr instructions in SMPUsesFlags. --- SMPBasicBlock.cpp | 4 + SMPDataFlowAnalysis.cpp | 10 ++- SMPStaticAnalyzer.cpp | 181 +++------------------------------------- SMPStaticAnalyzer.h | 2 + 4 files changed, 25 insertions(+), 172 deletions(-) diff --git a/SMPBasicBlock.cpp b/SMPBasicBlock.cpp index 9fd09080..9191aa31 100644 --- a/SMPBasicBlock.cpp +++ b/SMPBasicBlock.cpp @@ -29,6 +29,7 @@ #include "SMPFunction.h" #define SMP_DEBUG_DATAFLOW 0 +#define SMP_DEBUG_OPTIMIZATIONS 1 // Basic block number 0 is the top of the CFG lattice. #define SMP_TOP_BLOCK 0 @@ -590,7 +591,10 @@ void SMPBasicBlock::MarkDeadRegs(void) { } } else if (this->MyFunc->IsGlobalName(FlagsOp)) { + ; +#if SMP_DEBUG_OPTIMIZATIONS msg("Global EFLAGS in %s\n", this->MyFunc->GetFuncName()); +#endif } else { // EFLAGS are not locally used, but not global either; they are dead here qstrncat(DeadString, " EFLAGS", sizeof(DeadString) - 1); diff --git a/SMPDataFlowAnalysis.cpp b/SMPDataFlowAnalysis.cpp index 4b4c3d45..1775db67 100644 --- a/SMPDataFlowAnalysis.cpp +++ b/SMPDataFlowAnalysis.cpp @@ -1270,6 +1270,10 @@ void InitSMPUsesFlags(void) { (void) memset(SMPUsesFlags, false, sizeof(SMPUsesFlags)); SMPUsesFlags[NN_null] = true; // Unknown Operation +#if 1 +SMPUsesFlags[NN_aaa] = true; // ASCII adjust after addition +SMPUsesFlags[NN_aas] = true; // ASCII adjust after subtraction +#endif SMPUsesFlags[NN_adc] = true; // Add with Carry SMPUsesFlags[NN_into] = true; // Call to Interrupt Procedure if Overflow Flag = 1 SMPUsesFlags[NN_ja] = true; // Jump if Above (CF=0 & ZF=0) @@ -1320,9 +1324,11 @@ SMPUsesFlags[NN_pushfd] = true; // Push Flags Register onto the Sta SMPUsesFlags[NN_pushfq] = true; // Push Flags Register onto the Stack (use64) SMPUsesFlags[NN_repe] = true; // Repeat String Operation while ZF=1 SMPUsesFlags[NN_repne] = true; // Repeat String Operation while ZF=0 +#if 0 SMPUsesFlags[NN_sahf] = true; // Store AH into Flags Register SMPUsesFlags[NN_shl] = true; // Shift Logical Left SMPUsesFlags[NN_shr] = true; // Shift Logical Right +#endif SMPUsesFlags[NN_sbb] = true; // Integer Subtraction with Borrow SMPUsesFlags[NN_seta] = true; // Set Byte if Above (CF=0 & ZF=0) SMPUsesFlags[NN_setae] = true; // Set Byte if Above or Equal (CF=0) @@ -1365,7 +1371,9 @@ SMPUsesFlags[NN_stos] = true; // Store String // SMPUsesFlags[NN_cpuid] = true; // Get CPU ID +#if 0 SMPUsesFlags[NN_cmpxchg8b] = true; // Compare and Exchange Eight Bytes +#endif // // Pentium Pro instructions @@ -1397,7 +1405,7 @@ SMPUsesFlags[NN_fcmovnbe] = true; // Floating Move if Not Below or Eq SMPUsesFlags[NN_fcmovnu] = true; // Floating Move if Not Unordered // -// FPP instructuions +// FPP instructions // diff --git a/SMPStaticAnalyzer.cpp b/SMPStaticAnalyzer.cpp index 8a8a8573..1f2264c3 100644 --- a/SMPStaticAnalyzer.cpp +++ b/SMPStaticAnalyzer.cpp @@ -25,6 +25,7 @@ #include "SMPStaticAnalyzer.h" #include "SMPDataFlowAnalysis.h" +#include "SMPProgram.h" #include "SMPFunction.h" #include "SMPInstr.h" @@ -60,7 +61,7 @@ int OptCount[LAST_OPT_CATEGORY + 1]; int AnnotationCount[LAST_OPT_CATEGORY + 1]; // The types of data objects based on their first operand flags. -static char *DataTypes[] = { "VOID", "NUMHEX", "NUMDEC", "CHAR", +char *DataTypes[] = { "VOID", "NUMHEX", "NUMDEC", "CHAR", "SEG", "OFFSET", "NUMBIN", "NUMOCT", "ENUM", "FORCED", "STRUCTOFFSET", "STACKVAR", "NUMFLOAT", "UNKNOWN", "UNKNOWN", "UNKNOWN", 0}; @@ -172,10 +173,6 @@ void IDAP_term(void) { void IDAP_run(int arg) { segment_t *seg; - char buf[MAXSTR]; - ea_t ea; - flags_t ObjFlags; - bool ReadOnlyFlag; FILE *SymsFile; SMPFunction *CurrFunc = NULL; bool FuncsDumped = false; @@ -227,183 +224,25 @@ void IDAP_run(int arg) { FixupIDB(); #endif - // First, examine the data segments and print info about static - // data, such as name/address/size. Do the same for functions in - // code segments. - // Loop through all segments. - for (int SegIndex = 0; SegIndex < get_segm_qty(); ++SegIndex) { - char SegName[MAXSTR]; - seg = getnseg(SegIndex); - ssize_t SegNameSize = get_segm_name(seg, SegName, sizeof(SegName) - 1); - - // We are only interested in the data segments of type - // SEG_DATA, SEG_BSS and SEG_COMM. - if ((seg->type == SEG_DATA) || (seg->type == SEG_BSS) - || (seg->type == SEG_COMM)) { - // Loop through each of the segments we are interested in, - // examining all data objects (effective addresses). - ReadOnlyFlag = ((seg->perm & SEGPERM_READ) && (!(seg->perm & SEGPERM_WRITE))); -#if SMP_DEBUG - msg("Starting data segment of type %d", seg->type); - if (SegNameSize > 0) - msg(" SegName: %s\n", SegName); - else - msg("\n"); - if (ReadOnlyFlag) { - msg("Read-only data segment.\n"); - } -#endif - ea = seg->startEA; - while (ea < seg->endEA) { - ObjFlags = get_flags_novalue(ea); - // Only process head bytes of data objects, i.e. isData(). - if (isData(ObjFlags)) { - // Compute the size of the data object. - ea_t NextEA = ea; - do { - NextEA = nextaddr(NextEA); - } while ((NextEA < seg->endEA) && (!isHead(get_flags_novalue(NextEA)))); - size_t ObjSize = (size_t) (NextEA - ea); - // Get the data object name using its address. - char *TrueName = get_true_name(BADADDR, ea, buf, sizeof(buf)); - if (NULL == TrueName) { - qstrncpy(buf, "SMP_dummy0", 12); - } - // Output the name, address, size, and type info. - if (ReadOnlyFlag) { - qfprintf(SymsFile, - "%x %d OBJECT GLOBAL %s %s RO\n", ea, ObjSize, - buf, DataTypes[get_optype_flags0(ObjFlags) >> 20]); - } - else { - qfprintf(SymsFile, - "%x %d OBJECT GLOBAL %s %s RW\n", ea, ObjSize, - buf, DataTypes[get_optype_flags0(ObjFlags) >> 20]); - } - // Move on to next data object - ea = NextEA; - } - else { - ea = nextaddr(ea); - } - } // end while (ea < seg->endEA) - } // end if (seg->type == SEG_DATA ...) - else if (seg->type == SEG_CODE) { -#if SMP_DEBUG - msg("Starting code segment"); - if (SegNameSize > 0) - msg(" SegName: %s\n", SegName); - else - msg("\n"); -#endif -#if SMP_DEBUG2 - if (!FuncsDumped) { - for (size_t FuncIndex = 0; FuncIndex < get_func_qty(); ++FuncIndex) { - func_t *FuncInfo = getn_func(FuncIndex); - get_func_name(FuncInfo->startEA, FuncName, MAXSTR-1); - msg("FuncName dump: %s\n", FuncName); - } - for (size_t ChunkIndex = 0; ChunkIndex < get_fchunk_qty(); ++ChunkIndex) { - func_t *ChunkInfo = getn_fchunk((int) ChunkIndex); - get_func_name(ChunkInfo->startEA, FuncName, MAXSTR-1); - if (0 == strcmp(FuncName, "fflush")) { - msg("fflush chunk: address %x", ChunkInfo->startEA); - if (is_func_tail(ChunkInfo)) - msg(" TAIL\n"); - else - msg(" ENTRY\n"); - } - else if ((0x81498f0 < ChunkInfo->startEA) - && (0x8149cb6 > ChunkInfo->startEA)) { - msg("Missing fflush chunk: %s %x", - FuncName, ChunkInfo->startEA); - if (is_func_tail(ChunkInfo)) - msg(" TAIL\n"); - else - msg(" ENTRY\n"); - } - } // end for (size_t ChunkIndex = ...) - func_t *FuncInfo = get_func(0x8149be0); - if (NULL == FuncInfo) - msg("No func at 0x8149be0\n"); - else { - get_func_name(FuncInfo->startEA, FuncName, MAXSTR-1); - msg("Func at 0x8149be0: %s\n", FuncName); - } - FuncsDumped = true; - } -#endif - for (size_t FuncIndex = 0; FuncIndex < get_func_qty(); ++FuncIndex) { - func_t *FuncInfo = getn_func(FuncIndex); - - // If more than one SEG_CODE segment, only process - // functions within the current segment. Don't know - // if multiple code segments are possible, but - // get_func_qty() is for the whole program, not just - // the current segment. - if (FuncInfo->startEA < seg->startEA) { - // Already processed this func in earlier segment. - continue; - } - else if (FuncInfo->startEA >= seg->endEA) { -#if SMP_DEBUG2 - get_func_name(FuncInfo->startEA, FuncName, MAXSTR-1); - msg("Skipping function until we reach its segment: %s\n", - FuncName); -#endif - break; - } - - // Create a function object. - if (NULL != CurrFunc){ - delete CurrFunc; - CurrFunc = NULL; - } - CurrFunc = new SMPFunction(FuncInfo); - - -#if SMP_BINARY_DEBUG - if (FuncsProcessed++ > SMP_DEBUG_COUNT) { - get_func_name(FuncInfo->startEA, FuncName, MAXSTR-1); - msg("Debug termination. FuncName = %s \n", FuncName); - msg("Function startEA: %x endEA: %x \n", - FuncInfo->startEA, - FuncInfo->endEA); - break; - } -#endif -#if SMP_BINARY_DEBUG - if (FuncsProcessed > SMP_DEBUG_COUNT) { - get_func_name(FuncInfo->startEA, FuncName, MAXSTR-1); - msg("Final FuncName: %s \n", FuncName); - SMPBinaryDebug = true; - } -#endif - CurrFunc->Analyze(); - CurrFunc->EmitAnnotations(SymsFile); - delete CurrFunc; - CurrFunc = NULL; - } // end for (size_t FuncIndex = 0; ...) + SMPProgram *CurrProg = new SMPProgram(); + CurrProg->Analyze(); + CurrProg->EmitAnnotations(SymsFile); #if SMP_FIND_ORPHANS + for (int SegIndex = 0; SegIndex < get_segm_qty(); ++SegIndex) { + seg = getnseg(SegIndex); + if (seg->type == SEG_CODE) FindOrphanedCode(seg, SymsFile); + } #endif - } // end else if (seg->type === SEG_CODE) - else { -#if SMP_DEBUG - msg("Not processing segment of type %d SegName: %s\n", - seg->type, SegName); -#endif - } - } // end for (int SegIndex = 0; ... ) - for (int OptType = 0; OptType <= LAST_OPT_CATEGORY; ++OptType) { msg("Optimization Category Count %d: %d Annotations: %d\n", OptType, OptCount[OptType], AnnotationCount[OptType]); } qfclose(SymsFile); + delete CurrProg; return; } // end IDAP_run() diff --git a/SMPStaticAnalyzer.h b/SMPStaticAnalyzer.h index 3d5f6d44..a2785f12 100644 --- a/SMPStaticAnalyzer.h +++ b/SMPStaticAnalyzer.h @@ -12,4 +12,6 @@ extern int OptCategory[]; extern int OptCount[LAST_OPT_CATEGORY + 1]; extern int AnnotationCount[LAST_OPT_CATEGORY + 1]; +extern char *DataTypes[]; + #endif -- GitLab