Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

/users/u3/mtikir/PMaCInstrumentor_v1601/tools/BasicBlockCounter.C

Go to the documentation of this file.
00001 #include <SectHeader.h>
00002 #include <Iterator.h>
00003 #include <Function.h>
00004 #include <LineInfoFinder.h>
00005 #include <XCoffFile.h>
00006 #include <BasicBlockCounter.h>
00007 
00008 BasicBlockCounter::BasicBlockCounter(XCoffFile* xcoff,char* extension,uint32_t phaseNo)
00009     : CommonMethods(xcoff,extension,phaseNo,1,NULL)
00010 {
00011 }
00012 
00013 void BasicBlockCounter::selectInstrumentationPoints(char* inpFile){
00014     
00015     terminationBlock = findTerminationBlock();
00016     ASSERT(terminationBlock && "FATAL : There is no exit block");
00017 
00018     uint32_t allBlocksCount = xcoffFile->getNumberOfBlocks();
00019 
00020     bool insertAppExitBlock = true;
00021 
00022     if (allBlocksCount){
00023         blocksToInstrument = new BasicBlock*[allBlocksCount];
00024         xcoffFile->getAllBlocks(blocksToInstrument);
00025 
00026         for (uint32_t i = 0; i < allBlocksCount; i++){
00027             BasicBlock* bb = blocksToInstrument[i];
00028             if (filterBlockForInst(bb)){
00029                 PRINT_DEBUG("Filtering basic block %#12llx",bb->getHashCode().getValue());
00030                 numOfBlocksFiltered++;
00031                 continue;
00032             }
00033             if (insertAppExitBlock && (bb == terminationBlock)){
00034                 PRINT_INFOR("The exit block sequence id will be %#x",numberOfInstPoints);
00035                 insertAppExitBlock = false;
00036             }
00037             blocksToInstrument[numberOfInstPoints++] = bb;
00038         }
00039     } else {
00040         PRINT_ERROR("There is no basic block identified in the executable yet, is executable parsed");
00041     }
00042 
00043     if (!numberOfInstPoints){
00044         PRINT_ERROR("There is no basic block passed the filter");
00045     }
00046 
00047     if (insertAppExitBlock){
00048         blocksToInstrument[numberOfInstPoints++] = terminationBlock;
00049     }
00050 
00051     PRINT_INFOR("**** Number of basic blocks considered in instrumentation %d ******",numberOfInstPoints);
00052 }
00053 
00054 uint32_t BasicBlockCounter::byteCountForInst(uint32_t instPointIdx,uint64_t instStubAddress,TextSection* textSect){
00055     BasicBlock* block = blocksToInstrument[instPointIdx];
00056 
00057     uint64_t instPointAddress = 0;
00058 
00059     if(!block->findFirstInstPoint(&instPointAddress))
00060         return 0;
00061 
00062     ASSERT(textSect->inRange(instPointAddress));
00063 
00064     if(!Instruction::isInJumpInsnRange(instPointAddress,instStubAddress))
00065         return 0;
00066 
00067     int32_t blockCounterOffset = getDataOffsetForInst(instPointIdx);
00068     bool isApplicationExit = (block == terminationBlock);
00069 
00070     uint32_t minInsnCount = 8;
00071     uint32_t tocUpdateInsnCount = 0;
00072     uint32_t indexAccessInsnCount = 0;
00073     uint32_t exitInsnCount = 0;
00074 
00075     if(tocXorUpdateVal){
00076         tocUpdateInsnCount += 2;
00077         if(SECOND_HALFWORD(tocXorUpdateVal)){
00078             tocUpdateInsnCount += 2;
00079         }
00080     }
00081     if(!Instruction::isInLoadOffsetInsnRange(blockCounterOffset)){
00082         indexAccessInsnCount += 4;
00083     }
00084     if(isApplicationExit){
00085         tocUpdateInsnCount *= 2;
00086         exitInsnCount = 11;
00087     }
00088     uint32_t insnCount = minInsnCount + tocUpdateInsnCount + 
00089                          indexAccessInsnCount + exitInsnCount;
00090 
00091     return (insnCount*sizeof(uint32_t));
00092 }
00093 
00094 uint32_t BasicBlockCounter::generateCodeForInst(uint32_t instPointIdx,
00095                                                     uint64_t instStubAddress,TextSection* textSect,
00096                                                     BaseGen* gen,uint32_t genBufferOffset)
00097 {
00098     ASSERT(gen->getParsedBase() == (Base*)textSect);
00099     BasicBlock* block = blocksToInstrument[instPointIdx];
00100     ASSERT(block);
00101     ASSERT(extendedDataSize && dataBufferEntryCount);
00102 
00103     uint64_t instPointAddress = 0;
00104 
00105     if(!block->findFirstInstPoint(&instPointAddress)){
00106         PRINT_INFOR("Basic Block %#18llx does not have suitable location for inst",
00107                     block->getHashCode().getValue());
00108         return 0;
00109     }
00110     ASSERT(textSect->inRange(instPointAddress));
00111 
00112     if(!Instruction::isInJumpInsnRange(instPointAddress,instStubAddress)){
00113         PRINT_INFOR("Basic Block %#18llx can not be instrumented due to branch offset limit",
00114                     block->getHashCode().getValue());
00115         return 0;
00116     }
00117 
00118     AddressIterator ait = block->getInstructionIterator();
00119     ait.skipTo(instPointAddress);
00120     Instruction origInsn = textSect->readInstruction(&ait);
00121 
00122     bool isApplicationExit = (block == terminationBlock);
00123 
00124     uint32_t savedReg = 31;
00125     uint32_t scratchReg = 30;
00126     ASSERT(savedReg > LAST_VOLATILE_REG);
00127     ASSERT(scratchReg > LAST_VOLATILE_REG);
00128 
00129     int32_t savedRegSaveOffset   = getGPRSaveOffset(savedReg);
00130     int32_t scratchRegSaveOffset = getGPRSaveOffset(scratchReg);
00131     int32_t blockCounterOffset   = getDataOffsetForInst(instPointIdx);
00132 
00133     uint32_t maxInsnCount = (maxByteCountPerInst() / sizeof(uint32_t));
00134 
00135     uint32_t insnCount = 0;
00136     Instruction* insnBuffer = new Instruction[maxInsnCount];
00137 
00138     insnBuffer[insnCount++] = origInsn;
00139 
00140     updateTOCRegister(insnBuffer,&insnCount);
00141 
00142     insnBuffer[insnCount++] = Instruction::generateStoreDouble(savedReg,REG_TOC,savedRegSaveOffset);
00143 
00144     bool oneWordCounter = (sizeof(uint32_t) == bytesPerBufferEntry());
00145 
00146     if(!Instruction::isInLoadOffsetInsnRange(blockCounterOffset)){
00147         insnBuffer[insnCount++] = Instruction::generateStoreDouble(scratchReg,REG_TOC,scratchRegSaveOffset);
00148         insnBuffer[insnCount++] = Instruction::generateLoad32BitHigh(scratchReg,blockCounterOffset);
00149         insnBuffer[insnCount++] = Instruction::generateLoad32BitLow(scratchReg,blockCounterOffset);
00150         if(oneWordCounter){
00151             insnBuffer[insnCount++] = Instruction::generateLoadWordIndx(savedReg,REG_TOC,scratchReg);
00152         } else {
00153             insnBuffer[insnCount++] = Instruction::generateLoadDoubleIndx(savedReg,REG_TOC,scratchReg);
00154         }
00155 
00156         insnBuffer[insnCount++] = Instruction::generateIncrement(savedReg,1);
00157         if(oneWordCounter){
00158             insnBuffer[insnCount++] = Instruction::generateStoreWordIndx(savedReg,REG_TOC,scratchReg);
00159         } else {
00160             insnBuffer[insnCount++] = Instruction::generateStoreDoubleIndx(savedReg,REG_TOC,scratchReg);
00161         }
00162         insnBuffer[insnCount++] = Instruction::generateLoadDouble(scratchReg,REG_TOC,scratchRegSaveOffset);
00163     } else {
00164         if(oneWordCounter){
00165             insnBuffer[insnCount++] = Instruction::generateLoadWord(savedReg,REG_TOC,blockCounterOffset);
00166         } else {
00167             insnBuffer[insnCount++] = Instruction::generateLoadDouble(savedReg,REG_TOC,blockCounterOffset);
00168         }
00169         insnBuffer[insnCount++] = Instruction::generateIncrement(savedReg,1);
00170         if(oneWordCounter){
00171             insnBuffer[insnCount++] = Instruction::generateStoreWord(savedReg,REG_TOC,blockCounterOffset);
00172         } else {
00173             insnBuffer[insnCount++] = Instruction::generateStoreDouble(savedReg,REG_TOC,blockCounterOffset);
00174         }
00175     }
00176 
00177     if(isApplicationExit){
00178         insnBuffer[insnCount++] = Instruction::generateStoreDouble(scratchReg,REG_TOC,scratchRegSaveOffset);
00179 
00180         generateFuncCallFull(insnBuffer,&insnCount,savedReg,instStubAddress,libraryFuncStubAddrs[0]);
00181 
00182         insnBuffer[insnCount++] = Instruction::generateLoadDouble(scratchReg,REG_TOC,scratchRegSaveOffset);
00183     }
00184 
00185     insnBuffer[insnCount++] = Instruction::generateLoadDouble(savedReg,REG_TOC,savedRegSaveOffset);
00186 
00187     updateTOCRegister(insnBuffer,&insnCount);
00188 
00189     uint64_t fromAddr = instStubAddress + (insnCount * sizeof(uint32_t));
00190     uint64_t toAddr   = instPointAddress + sizeof(uint32_t);
00191     insnBuffer[insnCount++] = Instruction::generateJumpInsn(fromAddr,toAddr);
00192     insnBuffer[insnCount++] = Instruction(instPointIdx);
00193 
00194     ASSERT(insnCount <= maxInsnCount);
00195 
00196     gen->writeInstructions(genBufferOffset,insnCount,insnBuffer);
00197 
00198     delete[] insnBuffer;
00199 
00200     fromAddr = instPointAddress;
00201     toAddr   = instStubAddress;
00202     Instruction origJumpToStub = Instruction::generateJumpInsn(fromAddr,toAddr);
00203     gen->writeWord(instPointAddress-textSect->getSectHeader()->GET(s_vaddr),origJumpToStub.bits());
00204 
00205     return (insnCount*sizeof(uint32_t));
00206 }
00207 
00208 bool BasicBlockCounter::filterBlockForInst(BasicBlock* bb){
00209     if(!bb)
00210         return true;
00211     if(bb->isTrace() || bb->isJumpTable())
00212         return true;
00213     if((bb->getNumOfMemoryOps() == 0) &&
00214        (bb->getNumOfFloatPOps() == 0))
00215        return true;
00216     return false;
00217 }
00218 
00219 void BasicBlockCounter::getSharedLibraryPathAndObj(char** path,char** name,char** obj){
00220     *path = getPathToInstLib();
00221     *obj  = "";
00222     if(xcoffFile->is64Bit()){
00223         *name = "libcntrFunc_64.a";
00224     } else {
00225         *name = "libcntrFunc.a";
00226     }
00227     ASSERT(path && name && obj);
00228 }
00229 
00230 void BasicBlockCounter::initializeReservedData(DataSection* dataSect,BaseGen* gen){
00231     gen->writeString(commentAddress-dataSect->getSectHeader()->GET(s_vaddr),
00232                      sharedLibraryInfoStr,strlen(sharedLibraryInfoStr) + 1);
00233 }

Generated on Mon Jan 28 11:08:33 2008 for PMaCInstrumentor by doxygen 1.3.5