00001 #include <Instruction.h> 00002 #include <FileHeader.h> 00003 #include <AOutHeader.h> 00004 #include <SectHeader.h> 00005 #include <RawSection.h> 00006 #include <SymbolTable.h> 00007 #include <StringTable.h> 00008 #include <RelocationTable.h> 00009 #include <LineInfoTable.h> 00010 #include <XCoffFile.h> 00011 #include <Iterator.h> 00012 #include <BinaryFile.h> 00013 #include <Function.h> 00014 00015 TIMER( 00016 extern double cfg_s1; 00017 extern double cfg_s2; 00018 extern double cfg_s3; 00019 extern double cfg_s4; 00020 extern double cfg_s5; 00021 ); 00022 00023 #define ISXCOFF64(__a) ((0x01ef == (__a)) || (0x01f7 == (__a))) 00024 #define ISXCOFF32(__a) (0x01df == (__a)) 00025 00026 DEBUG( 00027 uint32_t readBytes = 0; 00028 ); 00029 00030 #include <BitSet.h> 00031 void XCoffFile::testBitSet(){ 00032 PRINT_INFOR("Testing BitSet functionality"); 00033 BitSet<BasicBlock*>** foo = new BitSet<BasicBlock*>*[3]; 00034 00035 foo[0] = new BitSet<BasicBlock*>(23); 00036 foo[1] = new BitSet<BasicBlock*>(23); 00037 foo[0]->print(); 00038 foo[0]->setall(); 00039 foo[0]->print(); 00040 00041 foo[0]->remove(0); 00042 foo[0]->remove(1); 00043 foo[1]->insert(1); 00044 foo[1]->insert(3); 00045 00046 foo[0]->print(); 00047 foo[1]->print(); 00048 00049 *foo[0] |= *foo[1]; 00050 00051 foo[0]->print(); 00052 foo[1]->print(); 00053 } 00054 00055 00056 void XCoffFile::parse(){ 00057 00058 TIMER(double t1 = timer()); 00059 00060 binaryInputFile.readFileInMemory(xcoffFileName); 00061 00062 uint16_t magic = 0x0; 00063 if(!binaryInputFile.copyBytes(&magic,sizeof(uint16_t))){ 00064 PRINT_ERROR("The magic number can not be read\n"); 00065 } 00066 00067 if(ISXCOFF64(magic)){ 00068 PRINT_INFOR("The executable is 64-bit"); 00069 is64BitFlag = true; 00070 } else if(ISXCOFF32(magic)){ 00071 PRINT_INFOR("The executable is 32-bit"); 00072 } else { 00073 PRINT_ERROR("The magic number is not a valid one [%#x]",magic); 00074 } 00075 00076 PRINT_INFOR("Parsing the executable"); 00077 readFileHeader(); 00078 readAuxilaryHeader(); 00079 readSectionHeaders(); 00080 readRawSectionData(); 00081 00082 DebugSection* debugRawSect = NULL; 00083 for(uint32_t i=1;i<=numberOfSections;i++){ 00084 if(rawSections[i] && rawSections[i]->IS_SECT_TYPE(DEBUG)){ 00085 ASSERT(!debugRawSect && "FATAL: Why are there more than one debug raw data"); 00086 debugRawSect = (DebugSection*)(rawSections[i]); 00087 } 00088 } 00089 readSymbolStringTable(debugRawSect); 00090 00091 for(uint32_t i=1;i<=numberOfSections;i++){ 00092 rawSections[i]->setSymbolTable(symbolTable); 00093 } 00094 00095 readRelocLineInfoTable(); 00096 00097 TIMER(double t2 = timer();PRINT_INFOR("___timer: Parsing Step I parse XCoff : %.2f",t2-t1);t1=t2); 00098 00099 findFunctions(); 00100 00101 TIMER(t2 = timer();PRINT_INFOR("___timer: Parsing Step II findFunctions : %.2f",t2-t1);t1=t2); 00102 00103 generateCFGs(); 00104 00105 TIMER(t2 = timer();PRINT_INFOR("___timer: Parsing Step III generateCFGs : %.2f",t2-t1);t1=t2); 00106 TIMER(PRINT_INFOR(" ___timer: CFG Step I basic blocks : %.6f",cfg_s1)); 00107 TIMER(PRINT_INFOR(" ___timer: CFG Step I Edges : %.6f",cfg_s2)); 00108 TIMER(PRINT_INFOR(" ___timer: CFG Step I Graph : %.6f",cfg_s3)); 00109 TIMER(PRINT_INFOR(" ___timer: CFG Step I Unreachable : %.6f",cfg_s4)); 00110 TIMER(PRINT_INFOR(" ___timer: CFG Step I Dominator : %.6f",cfg_s5)); 00111 00112 findMemoryFloatOps(); 00113 00114 TIMER(t2 = timer();PRINT_INFOR("___timer: Parsing Step IV memoryFloatOp : %.2f",t2-t1);t1=t2); 00115 00116 for(uint32_t i=1;i<=numberOfSections;i++){ 00117 numberOfFunctions += rawSections[i]->getNumberOfFunctions(); 00118 numberOfBlocks += rawSections[i]->getNumberOfBlocks(); 00119 numberOfMemoryOps += rawSections[i]->getNumberOfMemoryOps(); 00120 numberOfFloatPOps += rawSections[i]->getNumberOfFloatPOps(); 00121 } 00122 } 00123 00124 void XCoffFile::readFileHeader() { 00125 PRINT_INFOR("Parsing the header"); 00126 if(is64Bit()){ 00127 fileHeader = new FileHeader64(); 00128 } else { 00129 fileHeader = new FileHeader32(); 00130 } 00131 ASSERT(fileHeader); 00132 fileHeader->read(&binaryInputFile); 00133 DEBUG( 00134 readBytes += fileHeader->getSizeInBytes(); 00135 ASSERT(binaryInputFile.alreadyRead() == readBytes); 00136 ); 00137 } 00138 00139 void XCoffFile::readAuxilaryHeader(){ 00140 PRINT_INFOR("Parsing the auxilary header"); 00141 if(is64Bit()){ 00142 aOutHeader = new AOutHeader64(); 00143 } else { 00144 aOutHeader = new AOutHeader32(); 00145 } 00146 ASSERT(aOutHeader); 00147 aOutHeader->read(&binaryInputFile); 00148 DEBUG( 00149 readBytes += aOutHeader->getSizeInBytes(); 00150 ASSERT(binaryInputFile.alreadyRead() == readBytes); 00151 ); 00152 textSectionIndex = aOutHeader->GET(o_sntext); 00153 dataSectionIndex = aOutHeader->GET(o_sndata); 00154 bssSectionIndex = aOutHeader->GET(o_snbss); 00155 loaderSectionIndex = aOutHeader->GET(o_snloader); 00156 tocSectionIndex = aOutHeader->GET(o_sntoc); 00157 entrySectionIndex = aOutHeader->GET(o_snentry); 00158 } 00159 00160 void XCoffFile::readSectionHeaders(){ 00161 PRINT_INFOR("Parsing the section headers"); 00162 numberOfSections = fileHeader->GET(f_nscns); 00163 ASSERT(numberOfSections && "FATAL : This file has no sections!!!!!"); 00164 sectHeaders = new SectHeader*[numberOfSections + 1]; 00165 ASSERT(sectHeaders); 00166 00167 sectHeaders[0] = NULL; 00168 for(uint32_t i=1;i<=numberOfSections;i++){ 00169 if(is64Bit()){ 00170 sectHeaders[i] = new SectHeader64(i); 00171 } else { 00172 sectHeaders[i] = new SectHeader32(i); 00173 } 00174 ASSERT(sectHeaders[i]); 00175 sectHeaders[i]->read(&binaryInputFile); 00176 DEBUG( 00177 readBytes += sectHeaders[i]->getSizeInBytes(); 00178 ASSERT(binaryInputFile.alreadyRead() == readBytes); 00179 ); 00180 } 00181 } 00182 00183 void XCoffFile::processOverflowSections(){ 00184 PRINT_INFOR("Processing the overflow sections"); 00185 for(uint32_t i=1;i<=numberOfSections;i++){ 00186 if(sectHeaders[i]->IS_SECT_TYPE(OVRFLO)){ 00187 uint32_t whichSection = sectHeaders[i]->GET(s_nreloc); 00188 ASSERT((whichSection <= numberOfSections) && "FATAL : Which section is this??\n"); 00189 ASSERT(!sectHeaders[whichSection]->getOverFlowSection() && "FATAL : More than 1 overflow??\n"); 00190 sectHeaders[whichSection]->setOverFlowSection(sectHeaders[i]); 00191 } 00192 } 00193 } 00194 00195 void XCoffFile::readRawSectionData(){ 00196 00197 PRINT_INFOR("Parsing the raw section data"); 00198 00199 rawSections = new RawSection*[numberOfSections + 1]; 00200 ASSERT(rawSections); 00201 00202 rawSections[0] = NULL; 00203 for(uint32_t i=1;i<=numberOfSections;i++){ 00204 rawSections[i] = RawSection::newRawSection(sectHeaders[i],this); 00205 if(rawSections[i]){ 00206 rawSections[i]->read(&binaryInputFile); 00207 } 00208 } 00209 } 00210 00211 void XCoffFile::readSymbolStringTable(DebugSection* debugRawSect){ 00212 00213 PRINT_INFOR("Parsing the string and symbol tables"); 00214 00215 uint32_t numberOfSyms = fileHeader->GET(f_nsyms); 00216 if(numberOfSyms){ 00217 char* startPtr = fileHeader->getSymbolTablePtr(); 00218 ASSERT(startPtr && "FATAL : Somehow the symbol table exists but the data does not"); 00219 00220 char* stringTablePtr = startPtr + (numberOfSyms * Size__NN_bit_SymbolTable_Entry); 00221 if(binaryInputFile.isInBuffer(stringTablePtr)){ 00222 stringTable = new StringTable(stringTablePtr); 00223 stringTable->read(&binaryInputFile); 00224 } else { 00225 ASSERT(NULL && "FATAL : Some how the string table does not exist"); 00226 } 00227 00228 symbolTable = new SymbolTable(startPtr,numberOfSyms,this); 00229 symbolTable->setStringTable(stringTable); 00230 symbolTable->setDebugSection(debugRawSect); 00231 symbolTable->read(&binaryInputFile); 00232 } else { 00233 ASSERT(numberOfSyms && "FATAL : At this moment we can not handle executables with no symbol table"); 00234 } 00235 } 00236 00237 void XCoffFile::readRelocLineInfoTable(){ 00238 00239 PRINT_INFOR("Parsing the LineInformation and Relocation tables"); 00240 00241 processOverflowSections(); 00242 00243 for(uint32_t i=1;i<=numberOfSections;i++){ 00244 RelocationTable* relocationTable = sectHeaders[i]->readRelocTable(&binaryInputFile,this); 00245 if(relocationTable){ 00246 relocationTable->setSymbolTable(symbolTable); 00247 } 00248 LineInfoTable* lineInfoTable = sectHeaders[i]->readLineInfoTable(&binaryInputFile,this); 00249 if(lineInfoTable){ 00250 lineInfoTable->setSymbolTable(symbolTable); 00251 } 00252 } 00253 } 00254 00255 void XCoffFile::briefPrint() 00256 { 00257 if(fileHeader) 00258 fileHeader->print(); 00259 if(aOutHeader) 00260 aOutHeader->print(); 00261 for(uint32_t i=1;i<=numberOfSections;i++){ 00262 sectHeaders[i]->print(); 00263 } 00264 } 00265 00266 void XCoffFile::print(){ 00267 00268 if(fileHeader) fileHeader->print(); 00269 if(aOutHeader) aOutHeader->print(); 00270 for(uint32_t i=1;i<=numberOfSections;i++){ 00271 sectHeaders[i]->print(); 00272 rawSections[i]->print(); 00273 } 00274 for(uint32_t i=1;i<=numberOfSections;i++){ 00275 if(sectHeaders[i]->getRelocationTable()) 00276 sectHeaders[i]->getRelocationTable()->print(); 00277 if(sectHeaders[i]->getLineInfoTable()) 00278 sectHeaders[i]->getLineInfoTable()->print(); 00279 } 00280 if(symbolTable) symbolTable->print(); 00281 if(stringTable) stringTable->print(); 00282 } 00283 00284 void XCoffFile::displaySymbols(){ 00285 00286 ASSERT(rawSections && "FATAL : Raw data is not read"); 00287 ASSERT(symbolTable && "FATAL : Symbol table is missing"); 00288 00289 uint32_t numberOfSymbols = symbolTable->getNumberOfSymbols(); 00290 Symbol** addressSymbols = new Symbol*[numberOfSymbols]; 00291 numberOfSymbols = symbolTable->filterSortAddressSymbols(addressSymbols,numberOfSymbols); 00292 00293 if(numberOfSymbols){ 00294 for(uint32_t i=1;i<=numberOfSections;i++){ 00295 if(!rawSections[i]->IS_SECT_TYPE(OVRFLO)){ 00296 rawSections[i]->displaySymbols(addressSymbols,numberOfSymbols); 00297 } 00298 } 00299 } 00300 delete[] addressSymbols; 00301 } 00302 00303 void XCoffFile::findFunctions(){ 00304 ASSERT(symbolTable && "FATAL : Symbol table is missing"); 00305 ASSERT(rawSections && "FATAL : Raw data is not read"); 00306 for(uint32_t i=1;i<=numberOfSections;i++){ 00307 rawSections[i]->findFunctions(); 00308 } 00309 } 00310 00311 void XCoffFile::generateCFGs(){ 00312 ASSERT(rawSections && "FATAL : Raw data is not read"); 00313 for(uint32_t i=1;i<=numberOfSections;i++){ 00314 rawSections[i]->generateCFGs(); 00315 } 00316 } 00317 00318 void XCoffFile::findMemoryFloatOps(){ 00319 ASSERT(rawSections && "FATAL : Raw data is not read"); 00320 for(uint32_t i=1;i<=numberOfSections;i++){ 00321 rawSections[i]->findMemoryFloatOps(); 00322 } 00323 } 00324 00325 RawSection* XCoffFile::findRawSection(uint64_t addr){ 00326 ASSERT(rawSections && "FATAL : Raw data is not read"); 00327 for(uint32_t i=1;i<=numberOfSections;i++){ 00328 if(rawSections[i]->inRange(addr)) 00329 return rawSections[i]; 00330 } 00331 return NULL; 00332 } 00333 00334 uint64_t XCoffFile::getTOCAddress(){ 00335 return aOutHeader->GET(o_toc); 00336 } 00337 00338 uint64_t XCoffFile::readTOC(int32_t offset){ 00339 RawSection* tocSection = rawSections[tocSectionIndex]; 00340 ASSERT(tocSection && "FATAL: TOC is missing"); 00341 AddressIterator ait = tocSection->getAddressIterator(); 00342 uint64_t tocAddr = aOutHeader->GET(o_toc); 00343 tocAddr += offset; 00344 ait.skipTo(tocAddr); 00345 return tocSection->readBytes(&ait); 00346 } 00347 00348 RawSection* XCoffFile::getBSSSection(){ 00349 if(bssSectionIndex) 00350 return rawSections[bssSectionIndex]; 00351 return NULL; 00352 } 00353 00354 RawSection* XCoffFile::getLoaderSection(){ 00355 if(loaderSectionIndex) 00356 return rawSections[loaderSectionIndex]; 00357 return NULL; 00358 } 00359 00360 RawSection* XCoffFile::getTOCSection(){ 00361 return rawSections[tocSectionIndex]; 00362 } 00363 00364 BasicBlock* XCoffFile::findBasicBlock(HashCode* hashCode){ 00365 ASSERT(hashCode->isBlock() && "FATAL: The given hashcode for the block is incorrect"); 00366 00367 uint32_t sectionNo = hashCode->getSection(); 00368 uint32_t functionNo = hashCode->getFunction(); 00369 uint32_t blockNo = hashCode->getBlock(); 00370 00371 if(sectionNo >= numberOfSections) 00372 return NULL; 00373 00374 Function* func = rawSections[sectionNo]->getFunction(functionNo); 00375 if(!func) 00376 return NULL; 00377 00378 return func->getBlock(blockNo); 00379 } 00380 00381 uint32_t XCoffFile::getAllBlocks(BasicBlock** arr){ 00382 uint32_t ret = 0; 00383 for(uint32_t i=1;i<=numberOfSections;i++){ 00384 uint32_t n = rawSections[i]->getAllBlocks(arr); 00385 arr += n; 00386 ret += n; 00387 } 00388 return ret; 00389 } 00390 00391 RelocationTable* XCoffFile::getRelocationTable(uint32_t idx){ 00392 return sectHeaders[idx]->getRelocationTable(); 00393 } 00394 LineInfoTable* XCoffFile::getLineInfoTable(uint32_t idx){ 00395 return sectHeaders[idx]->getLineInfoTable(); 00396 } 00397 uint32_t XCoffFile::getFileSize() { 00398 return binaryInputFile.getSize(); 00399 } 00400 uint64_t XCoffFile::getDataSectionVAddr(){ 00401 return sectHeaders[dataSectionIndex]->GET(s_vaddr); 00402 } 00403 uint32_t XCoffFile::getDataSectionSize(){ 00404 return sectHeaders[dataSectionIndex]->GET(s_size); 00405 } 00406 uint64_t XCoffFile::getBSSSectionVAddr(){ 00407 if(bssSectionIndex) 00408 return sectHeaders[bssSectionIndex]->GET(s_vaddr); 00409 return 0; 00410 } 00411 uint64_t XCoffFile::getTextSectionVAddr(){ 00412 return sectHeaders[textSectionIndex]->GET(s_vaddr); 00413 } 00414 00415 void XCoffFile::setLineInfoFinder(){ 00416 PRINT_INFOR("Building LineInfoFinders"); 00417 for (uint32_t i = 1; i <= numberOfSections; i++){ 00418 rawSections[i]->buildLineInfoFinder(); 00419 } 00420 } 00421 00422 void XCoffFile::findLoops(){ 00423 PRINT_INFOR("Finding Loops"); 00424 for (uint32_t i = 1; i <= numberOfSections; i++){ 00425 rawSections[i]->buildLoops(); 00426 } 00427 } 00428