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