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

/users/u3/mtikir/PMaCInstrumentor_v1601/src/Base.C

Go to the documentation of this file.
00001 #include <Base.h>
00002 #include <XCoffFile.h>
00003 #include <BinaryFile.h>
00004 #include <SectHeader.h>
00005 #include <Instruction.h>
00006 #include <RawSection.h>
00007 #include <strings.h>
00008 #include <Generate.h>
00009 #include <Instruction.h>
00010 
00011 char* VersionTag::tag = "revision REVISION";
00012 
00013 extern uint64_t nextAlignAddressHalfWord(uint64_t addr){
00014     addr += (addr % 2 ? 2 : 0);
00015     addr >>= 1;
00016     addr <<= 1;
00017     return addr;
00018 }
00019 extern uint64_t nextAlignAddressWord(uint64_t addr){
00020     addr += (addr % 4 ? 4 : 0);
00021     addr >>= 2;
00022     addr <<= 2;
00023     return addr;
00024 }
00025 extern uint64_t nextAlignAddressDouble(uint64_t addr){
00026     addr += (addr % 8 ? 8 : 0);
00027     addr >>= 3;
00028     addr <<= 3;
00029     return addr;
00030 }
00031 
00032 HashCode::HashCode(uint32_t s){
00033     entry.bits = INVALID_FIELD;
00034     if(validSection(s)){
00035         entry.fields.section  = s;
00036         entry.fields.function = INVALID_FIELD;
00037         entry.fields.block    = INVALID_FIELD;
00038         entry.fields.memop    = INVALID_FIELD;
00039     }
00040 }
00041 
00042 HashCode::HashCode(uint32_t s,uint32_t f){
00043     entry.bits = INVALID_FIELD;
00044     if(validSection(s) && validFunction(f)){
00045         entry.fields.section  = s;
00046         entry.fields.function = ++f;
00047         entry.fields.block    = INVALID_FIELD;
00048         entry.fields.memop    = INVALID_FIELD;
00049     }
00050 }
00051 
00052 HashCode::HashCode(uint32_t s,uint32_t f,uint32_t b){
00053     entry.bits = INVALID_FIELD;
00054     if(validSection(s) && validFunction(f) && validBlock(b)){
00055         entry.fields.section  = s;
00056         entry.fields.function = ++f;
00057         entry.fields.block    = ++b;
00058         entry.fields.memop    = INVALID_FIELD;
00059     }
00060 }
00061 
00062 HashCode::HashCode(uint32_t s,uint32_t f,uint32_t b,uint32_t m){
00063     entry.bits = INVALID_FIELD;
00064     if(validSection(s) && validFunction(f) && validBlock(b) && validMemop(m)){
00065         entry.fields.section  = s;
00066         entry.fields.function = ++f;
00067         entry.fields.block    = ++b;
00068         entry.fields.memop    = ++m;
00069     }
00070 }
00071 
00072 uint32_t BaseGen::setFileOffset(uint32_t offset){ 
00073     if(!sizeInBytes){
00074         return offset;
00075     }
00076     fileOffset = (uint32_t)nextAlignAddressHalfWord(offset); 
00077     return (fileOffset+sizeInBytes); 
00078 }
00079 
00080 #define PAGE_MASK 0xfff
00081 uint32_t RawSectionGen::setFileOffset(uint32_t offset){
00082 
00083     if(!sizeInBytes){
00084         return offset;
00085     }
00086 
00087     if(rawSection->IS_SECT_TYPE(TEXT) || 
00088        rawSection->IS_SECT_TYPE(DATA))
00089     {
00090         uint64_t currFilePointer = offset;
00091         uint64_t prevFilePointer = rawSection->getSectHeader()->GET(s_scnptr);
00092 
00093         uint64_t currRemainder = PAGE_MASK & currFilePointer;
00094         uint64_t prevRemainder = PAGE_MASK & prevFilePointer;
00095 
00096         if(currRemainder > prevRemainder){
00097             currFilePointer += (PAGE_MASK+1);
00098         }
00099         currFilePointer = (currFilePointer & ~PAGE_MASK) | (prevFilePointer & PAGE_MASK);
00100 
00101         DEBUG(
00102             uint64_t virtualAddress = rawSection->getSectHeader()->GET(s_vaddr);
00103             ASSERT((virtualAddress & PAGE_MASK) == (currFilePointer & PAGE_MASK));
00104         );
00105 
00106         offset = (uint32_t)currFilePointer; 
00107 
00108         fileOffset = offset; 
00109         return (fileOffset+sizeInBytes); 
00110     } 
00111 
00112     return BaseGen::setFileOffset(offset);
00113 }
00114 
00115 void BaseGen::initInstrumentationBuffer(XCoffFileGen* xCoffGen){
00116     Base* parsedBase = getParsedBase();
00117     uint32_t bufferSize = parsedBase->getInstrumentationSize(xCoffGen);
00118     if(!bufferSize){
00119         return;
00120     }
00121     sizeInBytes = bufferSize;
00122     instBuffer = new char[sizeInBytes];
00123     bzero(instBuffer,sizeInBytes);
00124 }
00125 
00126 void BaseGen::instrument(XCoffFileGen* xCoffGen){
00127     Base* parsedBase = getParsedBase();
00128 
00129     uint32_t bufferSize = parsedBase->getInstrumentationSize(xCoffGen);
00130     ASSERT((!bufferSize || (sizeInBytes == bufferSize)) && 
00131            "FATAL : The buffer size is not same as instrumentation");
00132     ASSERT((!bufferSize || !hasInvalidFileOffset()) && 
00133            "FATAL : The buffer size is not same as instrumentation");
00134 
00135     parsedBase->instrument(instBuffer,xCoffGen,this);
00136 }
00137 
00138 void BaseGen::dump(BinaryOutputFile* bf){
00139     if(sizeInBytes){
00140         ASSERT(instBuffer && "FATAL : the non-zero size segment but the buffer is not allocated");
00141         bf->copyBytes(instBuffer,sizeInBytes,fileOffset);
00142     }
00143 }
00144 
00145 void BaseGen::printOffsetMapping(){
00146     Base* parsedBase = getParsedBase();
00147     PRINT_INFOR("%30s OFFSET (%d -- %d) SIZE(%d -- %d)",
00148         parsedBase->briefName(),
00149         getFileOffset(),parsedBase->getFileOffset(),
00150         getSizeInBytes(),parsedBase->getSizeInBytes());
00151 
00152 }
00153 
00154 void BaseGen::verifyIdentical(char* origFileName,char* instFileName){
00155 
00156     FILE* origFile = NULL;
00157     FILE* instFile = NULL;
00158 
00159     origFile = fopen(origFileName,"r");
00160     instFile = fopen(instFileName,"r");
00161 
00162     if(!origFile || !instFile){
00163         PRINT_ERROR("One of the original and instrumented file can not be opened");
00164         return;
00165     }
00166 
00167     Base* parsedBase = getParsedBase();
00168     ASSERT((getFileOffset() == parsedBase->getFileOffset()) && 
00169            "FATAL : Idemtical inst should have same offsets");
00170 
00171     if(hasInvalidFileOffset())
00172         return;
00173 
00174     ASSERT(getSizeInBytes() == parsedBase->getSizeInBytes());
00175 
00176     uint32_t startOffset = getFileOffset();
00177     uint32_t endOffset = startOffset + getSizeInBytes();
00178 
00179     int32_t check1 = fseek(origFile,startOffset,SEEK_SET);
00180     int32_t check2 = fseek(instFile,startOffset,SEEK_SET);
00181     if(check1 || check2){
00182         PRINT_ERROR("Original or Instrumented file can not be seeked");
00183     }
00184 
00185     for(;startOffset<endOffset;startOffset += sizeof(uint32_t)){
00186         bool fatalDiff = false;
00187 
00188         uint32_t word1 = 0x0;
00189         uint32_t word2 = 0x0;
00190         char* ptr1 = (char*)&word1;
00191         char* ptr2 = (char*)&word2;
00192 
00193         check1 = fread(ptr1,sizeof(uint32_t),1,origFile);
00194         check2 = fread(ptr2,sizeof(uint32_t),1,instFile);
00195 
00196         if((check1 || check2) && (((uint32_t)check1 != 1) || ((uint32_t)check2 != 1))){
00197             PRINT_ERROR("Original or Instrumented file can not be read");
00198         }
00199 
00200         uint32_t remainder = endOffset-startOffset;
00201         if(remainder < sizeof(uint32_t)){
00202             for(uint32_t j=0;j<remainder;j++,ptr1++,ptr2++){
00203                 fatalDiff = fatalDiff || (*ptr1 != *ptr2);
00204             }
00205         } else {
00206             fatalDiff = (word1 != word2);
00207         }
00208 
00209         if(fatalDiff){
00210             PRINT_DEBUG("---- %24s --> %9d -- %#10x %#10x %d",
00211                 parsedBase->briefName(),startOffset,word1,word2,
00212                 (remainder < sizeof(uint32_t) ? remainder : sizeof(uint32_t)));
00213             ASSERT(0 && "FATAL: the instrumented and original files differ even it is identical");
00214         }
00215     }
00216 
00217     fclose(origFile);
00218     fclose(instFile);
00219 }
00220 
00221 bool Base::includesFileOffset(uint32_t offset){
00222     if(hasInvalidFileOffset())
00223         return false;
00224     uint32_t begin = getFileOffset();
00225     uint32_t end = begin + getSizeInBytes();
00226     return ((begin <= offset) && (offset < end));
00227 }
00228 
00229 bool BaseGen::includesFileOffset(uint32_t offset){
00230     if(hasInvalidFileOffset())
00231         return false;
00232     uint32_t begin = getFileOffset();
00233     uint32_t end = begin + getSizeInBytes();
00234     return ((begin <= offset) && (offset < end));
00235 }
00236 
00237 uint32_t BaseGen::convertFileOffset(uint32_t oldOffset){
00238      Base* parsedBase = getParsedBase();
00239      if(!parsedBase->includesFileOffset(oldOffset))
00240         return oldOffset;
00241      uint32_t diff = oldOffset - parsedBase->getFileOffset();
00242      uint32_t newOffset = getFileOffset() + diff;
00243      PRINT_DEBUG("Converting file offsets from %9d ----> %9d",oldOffset,newOffset)
00244      return newOffset;
00245 }
00246 
00247 void BaseGen::writeHalfWord(uint32_t offset,uint16_t value){
00248     if(offset >= sizeInBytes){
00249         return;
00250         }
00251     if((offset+sizeof(uint16_t)) > sizeInBytes){
00252         return;
00253         }
00254     if(!instBuffer)
00255         return;
00256     memcpy(instBuffer+offset,&value,sizeof(uint16_t));
00257 }
00258 void BaseGen::writeWord(uint32_t offset,uint32_t value){
00259     if(offset >= sizeInBytes)
00260         return;
00261     if((offset+sizeof(uint32_t)) > sizeInBytes)
00262         return;
00263     if(!instBuffer)
00264         return;
00265     memcpy(instBuffer+offset,&value,sizeof(uint32_t));
00266 }
00267 void BaseGen::writeDouble(uint32_t offset,uint64_t value){
00268     if(offset >= sizeInBytes)
00269         return;
00270     if((offset+sizeof(uint64_t)) > sizeInBytes)
00271         return;
00272     if(!instBuffer)
00273         return;
00274     memcpy(instBuffer+offset,&value,sizeof(uint64_t));
00275 }
00276 void BaseGen::writeInstructions(uint32_t offset,uint32_t insnCount,Instruction* insnBuffer){
00277     for (uint32_t i = 0; i < insnCount; i++, offset += sizeof(uint32_t)){
00278         writeWord(offset,insnBuffer[i].bits());
00279     }
00280     DEBUG_MORE(
00281         PRINT_INFOR("Total number of Instructions is %d",insnCount);
00282         for (uint32_t i = 0; i < insnCount; i++){
00283             insnBuffer[i].print(offset + (sizeof(uint32_t)*i),true);
00284         }
00285     );
00286 }
00287 void BaseGen::writeString(uint32_t offset,char* buff,uint32_t len){
00288     if (offset >= sizeInBytes)
00289         return;
00290     if ((offset+len) > sizeInBytes)
00291         return;
00292     if (!instBuffer)
00293         return;
00294     memcpy(instBuffer+offset,buff,len);
00295 }
00296 
00297 #include <time.h>
00298 #include <sys/time.h>
00299 #include <sys/timers.h>
00300 
00301 double timer(){
00302         struct timespec time_record;;
00303         getclock(TIMEOFDAY,&time_record);
00304         return ((double)time_record.tv_sec+((double)time_record.tv_nsec) * 1.0e-9);
00305 
00306 }
00307 
00308 

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