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

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

Go to the documentation of this file.
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 

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