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

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

Go to the documentation of this file.
00001 #include <Base.h>
00002 #include <Instruction.h>
00003 #include <FileHeader.h>
00004 #include <AOutHeader.h>
00005 #include <SectHeader.h>
00006 #include <RawSection.h>
00007 #include <SymbolTable.h>
00008 #include <StringTable.h>
00009 #include <RelocationTable.h>
00010 #include <LineInfoTable.h>
00011 #include <XCoffFile.h>
00012 #include <Iterator.h>
00013 #include <BinaryFile.h>
00014 #include <Generate.h>
00015 #include <Function.h>
00016 #include <LineInfoFinder.h>
00017 
00018 XCoffFileGen::XCoffFileGen(XCoffFile* xcoff,char* extension,uint32_t phaseNo,char* inpFile) 
00019     : xcoffFile(xcoff),inputFileName(inpFile),outputFileName(NULL),fileExtension(NULL),phaseIndex(0),
00020       numberOfSections(0),
00021       instrumentedFileSize(0),
00022       numberOfInstPoints(0),extendedDataSize(0),dataBufferEntryCount(0),pathToInstLibraries(NULL)
00023 {
00024 
00025     ASSERT(xcoffFile && "FATAL : The Gen class requires a non-null value");
00026 
00027     fileExtension = extension;
00028     phaseIndex = phaseNo;
00029     outputFileName = new char[__MAX_STRING_SIZE];
00030     if(!phaseIndex){
00031         sprintf(outputFileName,"%s.%s",xcoffFile->getXCoffFileName(),fileExtension);
00032     } else {
00033         sprintf(outputFileName,"%s.phase.%d.%s",xcoffFile->getXCoffFileName(),phaseIndex,fileExtension);
00034     }
00035 
00036     fileHeaderGen = new FileHeaderGen(xcoffFile->getFileHeader());
00037     aOutHeaderGen = new AOutHeaderGen(xcoffFile->getAOutHeader());
00038 
00039     numberOfSections = xcoffFile->getNumberOfSections();
00040 
00041     sectHeadersGen = new SectHeaderGen*[numberOfSections+1];
00042     rawSectionsGen = new RawSectionGen*[numberOfSections+1];
00043     relocationTablesGen = new RelocationTableGen*[numberOfSections+1];
00044     lineInfoTablesGen = new LineInfoTableGen*[numberOfSections+1];
00045 
00046     for(uint32_t i=1;i<=numberOfSections;i++){
00047         sectHeadersGen[i] = NULL;
00048         rawSectionsGen[i] = NULL;
00049         relocationTablesGen[i] = NULL;
00050         lineInfoTablesGen[i] = NULL;
00051     }
00052 
00053     for(uint32_t i=1;i<=numberOfSections;i++){
00054         sectHeadersGen[i] = new SectHeaderGen(xcoffFile->getSectHeader(i));
00055         rawSectionsGen[i] = new RawSectionGen(xcoffFile->getRawSection(i));
00056         if(xcoffFile->getRelocationTable(i)){
00057             relocationTablesGen[i] = new RelocationTableGen(xcoffFile->getRelocationTable(i));
00058         }
00059         if(xcoffFile->getLineInfoTable(i)){
00060             lineInfoTablesGen[i] = new LineInfoTableGen(xcoffFile->getLineInfoTable(i));
00061         }
00062     }
00063 
00064     symbolTableGen = new SymbolTableGen(xcoffFile->getSymbolTable());
00065     stringTableGen = new StringTableGen(xcoffFile->getStringTable());
00066 
00067     pathToInstLibraries = new char[2+strlen("lib")+1];
00068     sprintf(pathToInstLibraries,"./lib");
00069 }
00070 
00071 uint32_t XCoffFileGen::getNumberOfAllFunctions(){ 
00072     return (xcoffFile ? xcoffFile->getNumberOfFunctions() : 0); 
00073 }
00074 uint32_t XCoffFileGen::getNumberOfAllBlocks(){ 
00075     return (xcoffFile ? xcoffFile->getNumberOfBlocks() : 0); 
00076 }
00077 uint32_t XCoffFileGen::getNumberOfAllMemoryOps(){ 
00078     return (xcoffFile ? xcoffFile->getNumberOfMemoryOps() : 0); 
00079 }
00080 uint32_t XCoffFileGen::getNumberOfAllFloatPOps(){ 
00081     return (xcoffFile ? xcoffFile->getNumberOfFloatPOps() : 0); 
00082 }
00083 uint32_t XCoffFileGen::getNumberOfAllObjects(){
00084     uint32_t ret = 0;
00085     if(fileHeaderGen) ret++;
00086     if(aOutHeaderGen) ret++;
00087     for(uint32_t i=1;i<=numberOfSections;i++){
00088         if(sectHeadersGen[i]) ret++;
00089         if(rawSectionsGen[i] && !rawSectionsGen[i]->hasInvalidFileOffset()) ret++;
00090         if(relocationTablesGen[i]) ret++;
00091         if(lineInfoTablesGen[i]) ret++;
00092     }
00093     if(symbolTableGen) ret++;
00094     if(stringTableGen) ret++;
00095     return ret;
00096 }
00097 uint32_t XCoffFileGen::getAllObjects(BaseGen** arr,uint32_t s){
00098     if(!arr || !s) return 0;
00099 
00100     uint32_t numOfAllObjects = getNumberOfAllObjects();
00101     if(numOfAllObjects > s){
00102         numOfAllObjects = s;
00103     }
00104 
00105     uint32_t idx = 0;
00106 
00107     if(idx == numOfAllObjects) return idx;
00108     if(fileHeaderGen) arr[idx++] = (BaseGen*)fileHeaderGen;
00109 
00110     if(idx == numOfAllObjects) return idx;
00111     if(aOutHeaderGen) arr[idx++] = (BaseGen*)aOutHeaderGen;
00112 
00113     for(uint32_t i=1;i<=numberOfSections;i++){
00114         if(idx == numOfAllObjects) return idx;
00115         if(sectHeadersGen[i]) arr[idx++] = (BaseGen*)sectHeadersGen[i];
00116 
00117         if(idx == numOfAllObjects) return idx;
00118         if(rawSectionsGen[i] && !rawSectionsGen[i]->hasInvalidFileOffset())
00119              arr[idx++] = (BaseGen*)rawSectionsGen[i];
00120 
00121         if(idx == numOfAllObjects) return idx;
00122         if(relocationTablesGen[i]) arr[idx++] = (BaseGen*)relocationTablesGen[i];
00123 
00124         if(idx == numOfAllObjects) return idx;
00125         if(lineInfoTablesGen[i]) arr[idx++] = (BaseGen*)lineInfoTablesGen[i];
00126     }
00127     if(idx == numOfAllObjects) return idx;
00128     if(symbolTableGen) arr[idx++] = (BaseGen*)symbolTableGen;
00129 
00130     if(idx == numOfAllObjects) return idx;
00131     if(stringTableGen) arr[idx++] = (BaseGen*)stringTableGen;
00132 
00133     return numOfAllObjects;
00134 }
00135 uint32_t XCoffFileGen::getSymbolTableOffsetForInst() {
00136     if(symbolTableGen && !symbolTableGen->hasInvalidFileOffset()){
00137         return symbolTableGen->getFileOffset();
00138     }
00139     return 0;
00140 }
00141 
00142 uint32_t XCoffFileGen::getRawSectionSizeForInst(uint32_t idx){
00143     if(idx <= numberOfSections){
00144         return rawSectionsGen[idx]->getSizeInBytes();
00145     }
00146     return 0;
00147 }
00148 
00149 uint32_t XCoffFileGen::getRawSectionOffsetForInst(uint32_t idx){
00150     if(idx <= numberOfSections){
00151         if(!rawSectionsGen[idx]->hasInvalidFileOffset()){
00152             return rawSectionsGen[idx]->getFileOffset();
00153         }
00154     }
00155     return 0;
00156 }
00157 uint32_t XCoffFileGen::getRelocOffsetForInst(uint32_t idx){
00158     if(idx <= numberOfSections){
00159         if(relocationTablesGen[idx]){
00160             if(!relocationTablesGen[idx]->hasInvalidFileOffset()){
00161                 return relocationTablesGen[idx]->getFileOffset();
00162             }
00163         }
00164     }
00165     return 0;
00166 }
00167 uint32_t XCoffFileGen::getLineInfoOffsetForInst(uint32_t idx){
00168     if(idx <= numberOfSections){
00169         if(lineInfoTablesGen[idx]){
00170             if(!lineInfoTablesGen[idx]->hasInvalidFileOffset()){
00171                 return lineInfoTablesGen[idx]->getFileOffset();
00172             }
00173         }
00174     }
00175     return 0;
00176 }
00177 uint64_t XCoffFileGen::getNewBSSSectionVAddressForInst(){
00178     uint16_t dataSectionIndex =  xcoffFile->getDataSectionIndex();
00179     uint64_t dataVAddr = xcoffFile->getDataSectionVAddr();
00180     /* uint16_t bssSectionIndex =  xcoffFile->getBSSSectionIndex(); */
00181     uint64_t bssVAddr = xcoffFile->getBSSSectionVAddr();
00182 
00183     PRINT_DEBUG("The original DATA address is %#18llx",dataVAddr);
00184     PRINT_DEBUG("The original BSS address is %#18llx",bssVAddr);
00185     if(dataVAddr < bssVAddr){
00186         ASSERT(getRawSectionSizeForInst(dataSectionIndex) && 
00187                "FATAL : The text section does not have any data");
00188         bssVAddr = (dataVAddr + getRawSectionSizeForInst(dataSectionIndex));
00189         bssVAddr = nextAlignAddressWord(bssVAddr);
00190     }
00191     PRINT_DEBUG("The new BSS address is %#18llx",bssVAddr);
00192     return bssVAddr;
00193 }
00194 
00195 void XCoffFileGen::instrument(){
00196 
00197     selectInstrumentationPoints(inputFileName);
00198     printInstrumentationPoints();
00199     reserveDataForInstrumentation();
00200 
00201     inst_step1_allocateBuffers();
00202     inst_step2_setFileOffsets();
00203     inst_step3_instrumentInBuffer();
00204     inst_step4_updateBSSCSectionEntries();
00205 }
00206 
00207 void XCoffFileGen::inst_step1_allocateBuffers(){
00208     fileHeaderGen->initInstrumentationBuffer(this);    
00209     aOutHeaderGen->initInstrumentationBuffer(this);    
00210     for(uint32_t i=1;i<=numberOfSections;i++){
00211         sectHeadersGen[i]->initInstrumentationBuffer(this);    
00212         rawSectionsGen[i]->initInstrumentationBuffer(this);
00213         if(relocationTablesGen[i]){
00214             relocationTablesGen[i]->initInstrumentationBuffer(this);    
00215         }
00216         if(lineInfoTablesGen[i]){
00217             lineInfoTablesGen[i]->initInstrumentationBuffer(this);    
00218         }
00219     }
00220     symbolTableGen->initInstrumentationBuffer(this);    
00221     stringTableGen->initInstrumentationBuffer(this);    
00222 }
00223 
00224 void XCoffFileGen::inst_step2_setFileOffsets(){
00225 
00226     instrumentedFileSize = 0;
00227 
00228     instrumentedFileSize = fileHeaderGen->setFileOffset(instrumentedFileSize);
00229     fileHeaderGen->printOffsetMapping();
00230     instrumentedFileSize = aOutHeaderGen->setFileOffset(instrumentedFileSize);
00231     aOutHeaderGen->printOffsetMapping();
00232 
00233     for(uint32_t i=1;i<=numberOfSections;i++){
00234         instrumentedFileSize = sectHeadersGen[i]->setFileOffset(instrumentedFileSize);
00235         sectHeadersGen[i]->printOffsetMapping();
00236     }
00237     for(uint32_t i=1;i<=numberOfSections;i++){
00238         instrumentedFileSize = rawSectionsGen[i]->setFileOffset(instrumentedFileSize);
00239         rawSectionsGen[i]->printOffsetMapping();
00240     }
00241     for(uint32_t i=1;i<=numberOfSections;i++){
00242         if(relocationTablesGen[i]){
00243             instrumentedFileSize = relocationTablesGen[i]->setFileOffset(instrumentedFileSize);
00244             relocationTablesGen[i]->printOffsetMapping();
00245         }
00246     }
00247     for(uint32_t i=1;i<=numberOfSections;i++){
00248         if(lineInfoTablesGen[i]){
00249             instrumentedFileSize = lineInfoTablesGen[i]->setFileOffset(instrumentedFileSize);
00250             lineInfoTablesGen[i]->printOffsetMapping();
00251         }
00252     }
00253 
00254     instrumentedFileSize = symbolTableGen->setFileOffset(instrumentedFileSize);
00255     symbolTableGen->printOffsetMapping();
00256     instrumentedFileSize = stringTableGen->setFileOffset(instrumentedFileSize);
00257     stringTableGen->printOffsetMapping();
00258 
00259     PRINT_DEBUG("Bytes written in the instrumented executable is %d",instrumentedFileSize);
00260 }
00261 
00262 void XCoffFileGen::inst_step3_instrumentInBuffer(){
00263     fileHeaderGen->instrument(this);    
00264     aOutHeaderGen->instrument(this);    
00265     for(uint32_t i=1;i<=numberOfSections;i++){
00266         sectHeadersGen[i]->instrument(this);    
00267         rawSectionsGen[i]->instrument(this);
00268         if(relocationTablesGen[i]){
00269             relocationTablesGen[i]->instrument(this);    
00270         }
00271         if(lineInfoTablesGen[i]){
00272             lineInfoTablesGen[i]->instrument(this);    
00273         }
00274     }
00275     symbolTableGen->instrument(this);    
00276     stringTableGen->instrument(this);    
00277 }
00278 
00279 void XCoffFileGen::inst_step4_updateBSSCSectionEntries(){
00280 
00281     uint32_t updatedBSSCount = 0;
00282 
00283 //#define CHECK_FOR_SYMBOL
00284 #ifdef CHECK_FOR_SYMBOL
00285     uint32_t numberOfSymbols = xcoffFile->getSymbolTable()->getNumberOfSymbols();
00286     Symbol** symbols = new Symbol*[numberOfSymbols];
00287     uint32_t bssSymCount = xcoffFile->getSymbolTable()->filterSortBSSSymbols(symbols,numberOfSymbols);
00288     PRINT_INFOR("%d symbols found in BSS for updateBSSCSectionEntries step4",bssSymCount);
00289 
00290     DEBUG(
00291         for(uint32_t i=0;i<bssSymCount;i++){
00292             xcoffFile->getSymbolTable()->printSymbol(symbols[i]);
00293         }
00294     );
00295 #endif
00296 
00297     RawSectionGen* tocSectionGen = rawSectionsGen[xcoffFile->getTOCSectionIndex()];
00298     RawSection* tocSection = xcoffFile->getTOCSection();
00299     ASSERT(tocSection && "FATAL : The TOC section is missing");
00300     uint64_t tocSectionBeginAddress = tocSection->getSectHeader()->GET(s_vaddr);
00301     RawSection* bssSection = xcoffFile->getBSSSection();
00302     if(!bssSection)
00303         return;
00304 
00305     ASSERT(bssSection->IS_SECT_TYPE(BSS) && "FATAL : Looked for BSS but got something else");
00306 
00307     uint64_t oldBSSAddr = xcoffFile->getBSSSectionVAddr();
00308     uint64_t newBSSAddr = getNewBSSSectionVAddressForInst();
00309 
00310     AddressIterator ait = tocSection->getAddressIterator();
00311     PRINT_DEBUG("The TOC address is %#18llx in section at %#18llx",
00312             xcoffFile->getTOCAddress(),tocSectionBeginAddress);
00313     ait.skipTo(xcoffFile->getTOCAddress());
00314     while(ait.hasMore()){
00315         uint64_t address = *ait;
00316         uint64_t value = tocSection->readBytes(&ait);
00317         if(bssSection->inRange(value)){
00318 
00319 #ifdef CHECK_FOR_SYMBOL
00320             /* check value whether the symbol table has it */
00321             void* checkRes = bsearch(&value,symbols,bssSymCount,sizeof(Symbol*),searchSymbolValue);
00322             if(!checkRes){
00323                 PRINT_DEBUG("----->NOT   %#18llx -- %#18llx",address,value);
00324             } else {
00325                 PRINT_DEBUG("-----<FOUND %#18llx -- %#18llx",address,value);
00326 #endif
00327                 updatedBSSCount++;
00328                 uint64_t newValue = (value-oldBSSAddr) + newBSSAddr;
00329                 PRINT_DEBUG("Updating Data Section entry %#18llx from %#18llx to %#18llx",
00330                             address,value,newValue);
00331                 if(ait.isWord()){
00332                     tocSectionGen->writeWord(address-tocSectionBeginAddress,newValue);
00333                 } else if(ait.isDouble()){
00334                     tocSectionGen->writeDouble(address-tocSectionBeginAddress,newValue);
00335                 }
00336 #ifdef CHECK_FOR_SYMBOL
00337             }
00338 #endif
00339         }
00340         ait++;
00341     }
00342 
00343     PRINT_INFOR("%d updates are applied for BSS for updateBSSCSectionEntries step4",updatedBSSCount);
00344 
00345 #ifdef CHECK_FOR_SYMBOL
00346     delete[] symbols;
00347 #endif
00348 
00349     LoaderSection* ldrSection = (LoaderSection*)xcoffFile->getLoaderSection();
00350     uint32_t rlcCount = ldrSection->getRelocationCount();
00351     if(rlcCount){
00352         uint64_t* addrs = new uint64_t[rlcCount];
00353         uint32_t bssRlcCount = ldrSection->getBSSRelocations(addrs);
00354         PRINT_INFOR("There are %d relocations in loader section for BSS section",bssRlcCount);
00355         for(uint32_t i=0;i<bssRlcCount;i++){
00356             uint64_t address = addrs[i];
00357             if((address >= xcoffFile->getTOCAddress()) ||
00358                (address < tocSectionBeginAddress))
00359             {
00360                 continue;
00361             }
00362             ait.skipTo(address);
00363             uint64_t value = tocSection->readBytes(&ait);
00364             if(bssSection->inRange(value)){
00365                 uint64_t newValue = (value-oldBSSAddr) + newBSSAddr;
00366                 if(ait.isWord()){
00367                     tocSectionGen->writeWord(address-tocSectionBeginAddress,newValue);
00368                 } else if(ait.isDouble()){
00369                     tocSectionGen->writeDouble(address-tocSectionBeginAddress,newValue);
00370                 }
00371                 PRINT_DEBUG("Found %#llx at %#llx for BSS entry and updated with %#llx",value,address,newValue);
00372             }
00373         }
00374         delete[] addrs;
00375     }
00376 }
00377 
00378 uint32_t XCoffFileGen::dump(){
00379     binaryOutputFile.open(outputFileName);
00380     if(!binaryOutputFile){
00381         PRINT_ERROR("The output file can not be opened %s",outputFileName);
00382     }
00383 
00384     fileHeaderGen->dump(&binaryOutputFile);
00385     aOutHeaderGen->dump(&binaryOutputFile);
00386 
00387     for(uint32_t i=1;i<=numberOfSections;i++){
00388         sectHeadersGen[i]->dump(&binaryOutputFile);
00389     }
00390     for(uint32_t i=1;i<=numberOfSections;i++){
00391         rawSectionsGen[i]->dump(&binaryOutputFile);
00392     }
00393     for(uint32_t i=1;i<=numberOfSections;i++){
00394         if(relocationTablesGen[i]){
00395             relocationTablesGen[i]->dump(&binaryOutputFile);
00396         }
00397     }
00398     for(uint32_t i=1;i<=numberOfSections;i++){
00399         if(lineInfoTablesGen[i]){
00400             lineInfoTablesGen[i]->dump(&binaryOutputFile);
00401         }
00402     }
00403 
00404     symbolTableGen->dump(&binaryOutputFile);
00405     stringTableGen->dump(&binaryOutputFile);
00406 
00407     uint32_t ret = binaryOutputFile.alreadyWritten();
00408 
00409     ASSERT(binaryOutputFile.alreadyWritten() == getInstrumentedFileSize());
00410 
00411     binaryOutputFile.close();
00412 
00413     char sysCommand[__MAX_STRING_SIZE];
00414     sprintf(sysCommand,"chmod a+x %s",outputFileName);
00415     system(sysCommand);
00416 
00417     return ret;
00418 }
00419 
00420 uint32_t XCoffFileGen::generateStubForAllLibraryCalls(uint32_t genBufferOffset,BaseGen* gen){
00421 
00422     uint64_t textSectionStartAddr = xcoffFile->getTextSectionVAddr();
00423 
00424     for (uint32_t i = 0; i < getNumOfSharedLibFuncs(); i++){
00425         uint64_t addr = genBufferOffset + textSectionStartAddr;
00426         setAddrOfSharedLibFuncWrapper(i,addr);
00427         PRINT_INFOR("**** Function Begin addr     is %#18llx (%lld)  -- %s genoffset %#9x***",
00428             addr, addr-textSectionStartAddr, getSharedLibFuncName(i),genBufferOffset);
00429         genBufferOffset += generateSharedLibFuncWrapper(i, getSharedLibFuncAddrLocation(i), genBufferOffset, gen);
00430     }
00431 
00432     return byteCountForSharedLibFuncWrappers();
00433 }
00434 
00435 void XCoffFileGen::setPathToInstLib(char* libPathTop) { 
00436     if(libPathTop){
00437         if(pathToInstLibraries) delete[] pathToInstLibraries;
00438         pathToInstLibraries = new char[strlen(libPathTop)+strlen("lib")+2];
00439         sprintf(pathToInstLibraries,"%s/lib",libPathTop);
00440     }
00441     PRINT_INFOR("Top directory to shared lib is set to %s",pathToInstLibraries);
00442 }

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