Skip to content
Snippets Groups Projects
Commit 9c32ac79 authored by clc5q's avatar clc5q
Browse files

29-NOV-2007 snapshot.

parent 487dbd4f
Branches
Tags
No related merge requests found
......@@ -3,6 +3,9 @@
/README.txt -text
/SMP-analyze.sh -text
/SMP.idc -text
/SMPDataFlowAnalysis.cpp -text
/SMPDataFlowAnalysis.h -text
/SMPStaticAnalyzer.cpp -text
/SMPStaticAnalyzer.h -text
/makefile -text
/plugin.script -text
This diff is collapsed.
#ifndef SMPDATAFLOWANALYSIS_H
#define SMPDATAFLOWANALYSIS_H 1
// SMPDataFlowAnalysis.h
//
// This header defines the interfaces needed for analyzing instructions,
// basic blocks, and functions, performing live variable analysis,
// putting code into SSA form, etc.
#include <list>
#include <vector>
#include <cstddef>
#include <pro.h>
#include <ida.hpp>
#include <ua.hpp>
#include <intel.hpp>
using namespace std;
class SMPFunction;
class SMPBasicBlock;
class SMPInstr;
class DefOrUseList;
// SMP will operate on a doubly linked list of instructions, which
// will be grouped into basic blocks. We will include info about each
// instruction that can not all be obtained easily in IDA Pro, and
// is not all obtained easily from one place in IDA Pro. This
// information will include all that we need to perform data flow
// analyses. Because the LABEL and CASE could be applied to other
// kinds of instructions during analysis, we define the enum values
// as non-overlapping bits. This type might be stored as an int
// in the future as a result of this design decision.
enum SMPitype {
DEFAULT = 0, // most instructions in middle of basic block
LABEL = 1, // instr also has a label (can be jump target)
CASE = 2, // instr also has case label (is inside switch)
JUMP = 4, // unconditional branch
COND_BRANCH = 8, // conditional branch
INDIR_JUMP = 16, // indirect unconditional branch,
CALL = 32, // direct call
INDIR_CALL = 64, // indirect call
RETURN = 128, // function return
HALT = 256 // execution stops
};
// A primary goal of data flow analysis in SMP will be to identify
// operands as numeric or pointer type. If an instruction definitely
// produces a numeric result, an annotation could inform the mmStrata
// run time monitor to simply record 'numeric' for the result register
// and otherwise do nothing. This could greatly cut down the overhead
// at run time. If the result register already has an mmStrata metadata
// type of numeric, then the annotation could tell mmStrata to do nothing
// at all, which is even better. In order to emit these annotations, we
// will track all operands in a function as to their basic SMP types.
enum SMPOperandType { // What type is a given register or memory operand?
UNINIT, // Operand type not yet analyzed
NUMERIC, // Definitely holds non-pointer value (char, int, etc.)
POINTER, // Definitely holds an address
UNKNOWN // Might hold an address, might not (Bad!)
};
// Same class is used for both a DEF list and a USE list.
class DefOrUseList {
public:
DefOrUseList(void);
void SetRef(op_t Ref, SMPOperandType Type = UNINIT);
op_t GetRef(size_t index) const;
SMPOperandType GetRefType(size_t index) const;
inline size_t GetSize(void) const { return (size_t) Refs.size(); };
private:
vector<op_t> Refs; // Defined or used operand
vector<SMPOperandType> Types; // indices coupled to Refs
}; // end class DefOrUseList
class SMPInstr {
public:
// Default constructor
SMPInstr(ea_t addr);
// Fill in basic data for instruction.
void Analyze(void);
inline ea_t GetAddr(void) const { return address; };
inline char *GetDisasm(void) { return disasm; };
int operator==(const SMPInstr &rhs) const;
int operator<(const SMPInstr &rhs) const;
int operator!=(const SMPInstr &rhs) const;
inline insn_t GetCmd(void) const { return SMPcmd; };
inline void SetCmd(insn_t cmd) { SMPcmd = cmd; return; };
// Does instruction write to memory?
bool HasDestMemoryOperand(void) const;
// Does instruction read from memory?
bool HasSourceMemoryOperand(void) const;
bool IsSecondSrcOperandNumeric(flags_t F) const;
bool IsBasicBlockTerminator(void) const;
inline bool IsJumpTarget(void) const { return JumpTarget; };
bool MDIsPushInstr(void) const;
bool MDIsPopInstr(void) const;
bool MDIsReturnInstr(void) const;
bool MDIsFrameAllocInstr(asize_t LocSize) const;
bool MDIsFrameDeallocInstr(bool UseFP, asize_t LocSize) const;
int GetOptType(void) const;
inline SMPitype GetDataFlowType(void) const { return type; };
void PrintOperands(void) const;
char *DestString(int OptType);
void AnnotateStackConstants(bool UseFP, FILE *AnnotFile);
private:
SMPitype type; // Data flow analysis category
int OptType; // Optimization category (see OptCategory[])
ea_t address; // Code address for 1st byte of instruction
bool analyzed; // Has instr been analyzed yet, setting type
// and DEF and USE lists?
bool JumpTarget; // Is Instr the target of any jumps or branches?
insn_t SMPcmd; // copy of 'cmd' for this instruction
ulong features; // Canonical features for SMPcmd
char disasm[MAXSTR]; // Disassembly text of instruction
DefOrUseList Defs; // Definitions list
DefOrUseList Uses; // Uses list
void BuildSMPDefUseLists(void); // Build DEF and USE lists for instruction
void MDFixupDefUseLists(void); // Machine-dependent ad hoc fixes
}; // end class SMPInstr
// Class defining basic blocks.
class SMPBasicBlock {
public:
SMPBasicBlock(list<SMPInstr>::iterator FirstInstr, list<SMPInstr>::iterator LastInstr);
void LinkToPred(SMPBasicBlock *Predecessor);
inline bool HasIndirectJump(void) const { return IndirectJump; };
inline bool HasReturn(void) const { return Returns; };
inline bool IsShared(void) const { return SharedTailChunk; };
inline void SetShared(void) { SharedTailChunk = true; };
inline list<SMPInstr>::iterator GetFirstInstr(void) const { return FirstInstr; };
inline list<SMPInstr>::iterator GetLastInstr(void) const { return LastInstr; };
void Analyze();
private:
list<SMPInstr>::iterator FirstInstr;
list<SMPInstr>::iterator LastInstr;
list<SMPBasicBlock> Predecessors;
list<SMPBasicBlock> Successors;
bool IndirectJump; // contains an indirect jump instruction
bool Returns; // contains a return instruction
bool SharedTailChunk; // is part of a code chunk shared among functions
};
// Class encapsulating all that the SMP static analyzer cares to know
// about a function.
class SMPFunction {
public:
SMPFunction(func_t *Info); // Default constructor
void Analyze(void); // Analyze all instructions in function
void EmitAnnotations(FILE *AnnotFile);
inline bool HasIndirectCalls(void) const { return IndirectCalls; };
inline const char *GetFuncName(void) const { return FuncName; };
private:
func_t *FuncInfo;
list<SMPInstr> Instrs;
list<SMPBasicBlock> Blocks;
bool UseFP; // Does function use a frame pointer?
bool StaticFunc; // Is function declared static?
bool IndirectCalls; // Does function make indirect calls?
char FuncName[MAXSTR];
size_t Size; // Function size in code bytes
asize_t LocalVarsSize; // size of local vars region of stack frame
ushort CalleeSavedRegsSize; // stack size of callee pushed regs
int RetAddrSize; // size of return address on stack (4 for most machines)
asize_t IncomingArgsSize; // size of incoming args on stack
ea_t LocalVarsAllocInstr; // address of instr that allocates stack frame
ea_t LocalVarsDeallocInstr; // address of epilogue instr that deallocs frame
void SetStackFrameInfo(void);
bool MDFixFrameInfo(void);
void EmitStackFrameAnnotations(FILE *AnnotFile, list<SMPInstr>::iterator Instr);
}; // end class SMPFunction
// Initialization routine for DFA category.
void InitDFACategory(void);
bool IsDestMemoryOperand(insn_t);
bool IsSrcMemoryOperand(insn_t);
#endif
#ifndef SMPSTATICANALYZER_H
#define SMPSTATICANALYZER_H 1
#include <intel.hpp>
#define LAST_OPT_CATEGORY 9
extern int OptCategory[];
// Keep statistics on how many instructions we saw in each optimization
// category, and how many optimizing annotations were emitted for
// each category.
extern int OptCount[LAST_OPT_CATEGORY + 1];
extern int AnnotationCount[LAST_OPT_CATEGORY + 1];
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment