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
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
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
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 }