00001 #ifndef _Function_h_ 00002 #define _Function_h_ 00003 00004 class Symbol; 00005 class SymbolTable; 00006 class AddressIterator; 00007 class Function; 00008 class FlowGraph; 00009 class BasicBlock; 00010 class Instruction; 00011 class Operand; 00012 00013 #include <Base.h> 00014 #include <BitSet.h> 00015 #include <LinkedList.h> 00016 #include <Instruction.h> 00017 #include <SectHeader.h> 00018 #include <RawSection.h> 00019 00020 class MemoryOperation { 00021 private: 00022 Instruction instruction; 00023 uint32_t offset; 00024 BasicBlock* basicBlock; 00025 uint32_t index; 00026 HashCode hashCode; 00027 public: 00028 MemoryOperation(Instruction insn,uint64_t addr,BasicBlock* bb,uint32_t idx); 00029 ~MemoryOperation() {} 00030 bool isDForm(); 00031 bool isDsForm(); 00032 bool isXForm(); 00033 void print(); 00034 Operand getAddressOperand1(); 00035 Operand getAddressOperand2(); 00036 HashCode getHashCode() { return hashCode; } 00037 BasicBlock* getBasicBlock() { return basicBlock; } 00038 uint32_t getIndex() { return index; } 00039 uint64_t getInsnAddr(); 00040 Instruction getInstruction() { return instruction; } 00041 }; 00042 00043 class BasicBlock { 00044 private: 00045 const static uint32_t EntryMask = 0x1; 00046 const static uint32_t ExitMask = 0x2; 00047 const static uint32_t TraceMask = 0x4; 00048 const static uint32_t JumpTableMask = 0x8; 00049 const static uint32_t NoPathMask = 0x10; 00050 00051 protected: 00052 00053 FlowGraph* flowGraph; 00054 uint32_t index; 00055 00056 uint64_t baseAddress; 00057 uint32_t sizeInBytes; 00058 00059 uint32_t flags; 00060 00061 HashCode hashCode; 00062 00063 uint32_t numOfMemoryOps; 00064 MemoryOperation** memoryOps; 00065 uint32_t numOfFloatPOps; 00066 00067 uint32_t numOfSources; 00068 BasicBlock** sources; 00069 uint32_t numOfTargets; 00070 BasicBlock** targets; 00071 00072 BasicBlock* immDominatedBy; 00073 public: 00074 BasicBlock(FlowGraph* cfg,uint64_t addr) 00075 : flowGraph(cfg),index(0),baseAddress(addr), 00076 sizeInBytes(0),flags(0), 00077 numOfMemoryOps(0),numOfFloatPOps(0), 00078 numOfSources(0),sources(NULL),numOfTargets(0),targets(),immDominatedBy(NULL) {} 00079 00080 ~BasicBlock() {} 00081 00082 bool inRange(uint64_t addr) { return ((baseAddress <= addr) && (addr < (baseAddress+sizeInBytes))); } 00083 AddressIterator getInstructionIterator(); 00084 00085 FlowGraph* getFlowGraph() { return flowGraph; } 00086 uint32_t getIndex() { return index; } 00087 uint64_t getBaseAddress() { return baseAddress; } 00088 uint32_t getSizeInBytes() { return sizeInBytes; } 00089 00090 void print(); 00091 00092 RawSection* getRawSection(); 00093 00094 void setEntry() { flags |= EntryMask; } 00095 void setExit() { flags |= ExitMask; } 00096 void setTrace() { flags |= TraceMask; } 00097 void setJumpTable() { flags |= JumpTableMask;} 00098 void setNoPath() { flags |= NoPathMask; } 00099 00100 bool isEntry() { return (flags & EntryMask); } 00101 bool isExit() { return (flags & ExitMask); } 00102 bool isTrace() { return (flags & TraceMask); } 00103 bool isJumpTable() { return (flags & JumpTableMask); } 00104 bool isNoPath() { return (flags & NoPathMask); } 00105 00106 void setIndex(uint32_t idx); 00107 00108 void setSizeInBytes(uint32_t size) { sizeInBytes = size; } 00109 00110 void addEdge(BasicBlock* to); 00111 00112 XCoffFile* getXCoffFile(); 00113 00114 void findMemoryFloatOps(); 00115 00116 uint32_t getInstructionCount() { return (sizeInBytes/sizeof(PowerPCInstruction)); } 00117 00118 HashCode getHashCode() { return hashCode; } 00119 00120 void setSources(uint32_t n,BasicBlock** arr) { numOfSources = n; sources = arr; } 00121 void setTargets(uint32_t n,BasicBlock** arr) { numOfTargets = n; targets = arr; } 00122 00123 uint32_t getNumOfMemoryOps() { return numOfMemoryOps; } 00124 uint32_t getNumOfFloatPOps() { return numOfFloatPOps; } 00125 MemoryOperation* getMemoryOp(uint32_t idx) { 00126 if(idx < numOfMemoryOps) 00127 return memoryOps[idx]; 00128 return NULL; 00129 } 00130 00131 bool findFirstInstPoint(uint64_t* addr); 00132 00133 uint32_t getNumOfSources() { return numOfSources; } 00134 uint32_t getNumOfTargets() { return numOfTargets; } 00135 BasicBlock* getSourceBlock(uint32_t idx) { ASSERT(idx >= 0 && idx < numOfSources); return sources[idx]; } 00136 BasicBlock* getTargetBlock(uint32_t idx) { ASSERT(idx >= 0 && idx < numOfTargets); return targets[idx]; } 00137 00138 bool isDominatedBy(BasicBlock* bb); 00139 BasicBlock* getImmDominator() { return immDominatedBy; } 00140 void setImmDominator(BasicBlock* bb) { immDominatedBy = bb; } 00141 }; 00142 00143 class FlowGraph { 00144 protected: 00145 00146 Function* function; 00147 00148 uint32_t numOfBasicBlocks; 00149 BasicBlock** basicBlocks; 00151 uint32_t numberOfLoops; 00152 Loop** loops; 00153 00154 public: 00155 FlowGraph(Function* f) : function(f),numOfBasicBlocks(0),basicBlocks(NULL),numberOfLoops(0),loops(NULL) {} 00156 ~FlowGraph() {} 00157 00158 RawSection* getRawSection(); 00159 void print(); 00160 uint32_t getIndex(); 00161 Function* getFunction() { return function; } 00162 00163 void assignSequenceNumbers(); 00164 uint32_t initializeAllBlocks(BasicBlock** blockArr,BasicBlock* traceBlock,uint32_t arrCount); 00165 00166 XCoffFile* getXCoffFile(); 00167 00168 void findMemoryFloatOps(); 00169 00170 BasicBlock** getAllBlocks() { return basicBlocks; } 00171 uint32_t getAllBlocks(BasicBlock** arr); 00172 00173 BitSet<BasicBlock*>* newBitSet(); 00174 00175 BasicBlock* getBlock(uint32_t idx) { return (idx < numOfBasicBlocks ? basicBlocks[idx] : NULL); } 00176 00177 uint32_t getNumOfBasicBlocks() { return numOfBasicBlocks; } 00178 uint32_t getNumOfMemoryOps(); 00179 uint32_t getNumOfFloatPOps(); 00180 BasicBlock* getEntryBlock(); 00181 Loop* getLoop(uint32_t idx) { ASSERT(idx >= 0 && idx < numberOfLoops); return loops[idx]; } 00182 uint32_t getNumberOfLoops() { return numberOfLoops; } 00183 void buildLoops(); 00184 void printInnerLoops(); 00185 00186 void depthFirstSearch(BasicBlock* root,BitSet<BasicBlock*>* visitedSet,bool set, 00187 BitSet<BasicBlock*>* completedSet=NULL,LinkedList<BasicBlock*>* backEdges=NULL); 00188 void setImmDominatorBlocks(BasicBlock* root=NULL); 00189 }; 00190 00191 class Function { 00192 protected: 00193 RawSection* rawSection; 00194 uint32_t index; 00195 00196 uint32_t numOfAllSymbols; 00197 Symbol** allSymbols; 00198 00199 uint64_t baseAddress; 00200 uint32_t sizeInBytes; 00201 00202 uint32_t insnSizeInBytes; 00203 00204 FlowGraph* flowGraph; 00205 00206 HashCode hashCode; 00207 00208 public: 00209 00210 Function(uint32_t idx,uint32_t symCount,Symbol** symbols,RawSection* sect); 00211 ~Function() { delete[] allSymbols; } 00212 00213 void updateSize(uint64_t size) { sizeInBytes = size; } 00214 void updateInstructionSize(); 00215 00216 AddressIterator getAddressIterator(); 00217 AddressIterator getInstructionIterator(); 00218 00219 uint32_t getIndex() { return index; } 00220 00221 RawSection* getRawSection() { return rawSection; } 00222 FlowGraph* getFlowGraph(); 00223 void generateCFG(); 00224 00225 uint32_t getSize() { return sizeInBytes; } 00226 uint32_t getInstructionSize() { return insnSizeInBytes; } 00227 00228 bool instructionInRange(uint64_t addr) { 00229 return ((baseAddress <= addr) && (addr < (baseAddress+insnSizeInBytes))); 00230 } 00231 00232 uint64_t getBaseAddress() { return baseAddress; } 00233 00234 uint32_t getInstructionCount() { return (insnSizeInBytes/sizeof(PowerPCInstruction)); } 00235 uint32_t getInstructionIndex(uint64_t addr) { return ((addr-baseAddress)/sizeof(PowerPCInstruction)); } 00236 00237 void print(); 00238 00239 void parseJumpTable(AddressIterator ait, 00240 BasicBlock** allBlocks,BasicBlock* currBlock=NULL, 00241 LinkedList<uint32_t>* tgtEdgeBags=NULL, 00242 LinkedList<uint32_t>* srcEdgeBags=NULL); 00243 00244 bool getJumpTableInformation(uint64_t* jumpTableAddr,uint32_t* jumpTableEntryCount, 00245 AddressIterator ait); 00246 00247 XCoffFile* getXCoffFile(); 00248 00249 void findMemoryFloatOps(); 00250 00251 HashCode getHashCode() { return hashCode; } 00252 00253 BasicBlock* getBlock(uint32_t idx) { return (flowGraph ? flowGraph->getBlock(idx) : NULL); } 00254 00255 bool isAnySymbolA(char* name); 00256 00257 uint32_t getNumOfAllSymbols() { return numOfAllSymbols; } 00258 uint32_t getAllSymbolNames(char* buffer,uint32_t len,bool onlyFirst); 00259 00260 void buildLoops() { if (flowGraph) flowGraph->buildLoops(); } 00261 00262 }; 00263 00264 #endif