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

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

Go to the documentation of this file.
00001 #include <LineInfoFinder.h>
00002 #include <SymbolTable.h>
00003 #include <XCoffFile.h>
00004 #include <BinaryFile.h>
00005 #include <Auxilary.h>
00006 #include <SectHeader.h>
00007 #include <StringTable.h>
00008 
00009 #define TEST_ALL
00010 #ifdef TEST_ALL
00011 #define TEST_ALL_ADDRESS
00012 //#define TEST_ALL_ADDRESS_OUT
00013 //#define TEST_GET_FUNCTION_NAME
00014 //#define TEST_GET_FILE_NAME
00015 //#define TEST_GET_LINE_NUMBER_IN_FUNCTION
00016 //#define TEST_GET_LINE_NUMBER_IN_FILE
00017 //#define TEST_GET_ADDRESS_BY_FUNCTION
00018 //#define TEST_GET_ADDRESS_BY_FILE
00019 #endif
00020 
00021 
00022 uint32_t LineInfoFinder::getLineInfoIndexOfPreviousAddr(uint64_t addr){
00023     uint32_t first = 0;
00024     uint32_t mid;
00025     uint32_t last = numberOfLineAddresses - 1;
00026 
00027 
00028         /* check to see if addr can be found in sortedAddresses */
00029     if (addr < sortedAddresses[first].address){
00030         return numberOfLineInfos;
00031     } else if (addr > sortedAddresses[last].address){
00032         return sortedAddresses[last].index;
00033     }
00034 
00035         /* do a binary searh on sortedAddresses to find the address */
00036     while (first <= last){
00037         mid = (first + last) / 2;
00038         if (addr > sortedAddresses[mid].address){
00039             first = mid + 1;
00040         } else if (addr < sortedAddresses[mid].address){
00041             last = mid - 1;
00042         } else {
00043             return sortedAddresses[mid].index;
00044         }
00045     }
00046     while (sortedAddresses[last].address > addr){
00047         last--;
00048     }
00049     return sortedAddresses[last].index;
00050 }
00051 
00052 
00053 
00054     /* returns some index in the lineInfoTable whose address is addr */
00055 uint32_t LineInfoFinder::getLineInfoIndexOfAddr(uint64_t addr){
00056     uint32_t first = 0;
00057     uint32_t mid;
00058     uint32_t last = numberOfLineAddresses - 1;
00059 
00060         /* do a binary searh on sortedAddresses to find the address */
00061     while (first <= last){
00062         mid = (first + last) / 2;
00063         if (addr > sortedAddresses[mid].address){
00064             first = mid + 1;
00065         } else if (addr < sortedAddresses[mid].address){
00066             last = mid - 1;
00067         } else {
00068             return sortedAddresses[mid].index;
00069         }
00070     }
00071     return numberOfLineInfos;
00072 }
00073 
00074 
00075 void LineInfoFinder::commandLineTest(){
00076     uint32_t choice = 1;
00077     uint32_t idx;
00078     uint64_t address;
00079 
00080     printf("**************************************************\n");
00081     printf("Command Line Test of LineInfoFinder\n");
00082     printf("\t0: quit\n");
00083     printf("\t1: print number of line infos\n");
00084     printf("\t2: print an address\n");
00085     printf("\t3: get the nearest address\n");
00086     printf("\t4: print info for an address\n");
00087     printf("\t5: print lineInfoTable\n");
00088     printf("\t6: print symbolTable\n");
00089     printf("**************************************************\n\n");
00090 
00091     while(choice != 0) {
00092         printf("Enter choice > ");
00093         fscanf(stdin, "%d", &choice);
00094         if (choice == 0){
00095         } else if (choice == 1){
00096             printf("There are %d lineInfos\n", lineInfoTable->getNumberOfLineInfos());
00097         } else if (choice == 2){
00098             printf("Enter an index > ");
00099             fscanf(stdin, "%d", &idx);
00100             if (idx < lineInfoTable->getNumberOfLineInfos() && lineInfoTable->getLineInfo(idx)->GET(l_lnno)){
00101                 printf("lineInfoTable[%d] has address %#llx\n", idx, lineInfoTable->getLineInfo(idx)->GET(l_paddr));
00102             } else {
00103                 printf("lineInfoTable[%d] has no address\n", idx);
00104             }
00105         } else if (choice == 3){
00106             printf("Enter an address > ");
00107             fscanf(stdin, "%llx", &address);
00108             idx = getLineInfoIndexOfPreviousAddr(address);
00109             printf("idx is %d\n", idx);
00110             printf("The nearest address to %#llx is %#llx at index %d\n", address, lineInfoTable->getLineInfo(idx)->GET(l_paddr), idx);
00111         } else if (choice == 4){
00112             printf("Enter an address > ");
00113             fscanf(stdin, "%llx", &address);
00114             printf("address %#llx is at line %d in function %s, line %d in file %s\n", 
00115                 address, getLineNumberInFunction(address), getFunctionName(address), getLineNumberInFile(address), 
00116                 getFileName(address));        
00117        
00118         } else if (choice == 5){
00119             printLineInfoTable();
00120         } else if (choice == 6){
00121             printSymbolTable();
00122         } else {
00123         }
00124     }
00125 }
00126 
00127 
00128     /* converts a file offset into an index into lineInfoTable */
00129 uint32_t LineInfoFinder::getLineInfoIndex(uint64_t fileOffset){
00130     uint64_t lineInfoSize;
00131     if (is64Bit){
00132         lineInfoSize = (uint64_t)LINESZ_64;
00133     } else {
00134         lineInfoSize = (uint64_t)LINESZ;
00135     }
00136     ASSERT(((fileOffset - lineInfoPointer) % lineInfoSize) == 0);
00137     return ((fileOffset - lineInfoPointer) / lineInfoSize);
00138 }
00139 
00140 
00141 LineInfoFinder::LineInfoFinder(uint32_t idx, XCoffFile* xCoffFile) {
00142     uint32_t numberOfLocalFunctions;
00143     uint32_t currentSourceFile;
00144     SymbolBase* tmpSymbol;
00145     uint32_t* parentIndices;
00146     uint32_t* fileIndices;
00147     uint32_t symbolClass;
00148 
00149     lineInfoTable = xCoffFile->getLineInfoTable(idx);
00150     symbolTable = xCoffFile->getSymbolTable();
00151     stringTable = xCoffFile->getStringTable();
00152     lineInfoPointer = lineInfoTable->getXCoffFile()->getSectHeader(idx)->GET(s_lnnoptr);
00153     is64Bit = xCoffFile->is64Bit();
00154 
00155     numberOfLineInfos = lineInfoTable->getNumberOfLineInfos();
00156     lineInfos = new LineInfo*[numberOfLineInfos];
00157     lineInfoLineNumbers = new uint32_t[numberOfLineInfos];
00158     lineInfoAddresses = new uint64_t[numberOfLineInfos];
00159     numberOfLineAddresses = 0;
00160     for (uint32_t i = 0; i < numberOfLineInfos; i++){
00161         lineInfos[i] = lineInfoTable->getLineInfo(i);
00162         lineInfoLineNumbers[i] = lineInfos[i]->GET(l_lnno);
00163         lineInfoAddresses[i] = lineInfos[i]->GET(l_paddr);
00164         if (lineInfoLineNumbers[i]){
00165             numberOfLineAddresses++;
00166         } else {
00167             numberOfLineInfoFunctions++;
00168         }
00169     }
00170 
00171     sortedAddresses = new struct idx_addr[numberOfLineAddresses];
00172     lineInfoFunctions = new struct idx_symndx[numberOfLineInfoFunctions];
00173     numberOfLineAddresses = 0;
00174     numberOfLineInfoFunctions = 0;
00175 
00176     for (uint32_t i = 0; i < numberOfLineInfos; i++){
00177         if (lineInfoLineNumbers[i]){
00178             sortedAddresses[numberOfLineAddresses].index = i;
00179             sortedAddresses[numberOfLineAddresses].address = lineInfoAddresses[i];
00180             numberOfLineAddresses++;
00181         } else {
00182             lineInfoFunctions[numberOfLineInfoFunctions].index = i;
00183             lineInfoFunctions[numberOfLineInfoFunctions].symndx = lineInfoTable->getLineInfo(i)->GET(l_symndx);
00184             numberOfLineInfoFunctions++;
00185         }
00186     }
00187 
00188     qsort(&sortedAddresses[0], numberOfLineAddresses, sizeof(struct idx_addr), compare_idx_addr);
00189 
00190     numberOfFiles = 0;
00191     numberOfFunctions = 0;
00192 
00193         /* count the number of files and functions in the symbol table */
00194     for (uint32_t i = 0; i < symbolTable->getNumberOfSymbols(); i++){
00195         tmpSymbol = symbolTable->getSymbol(i);
00196         if (!tmpSymbol->isAuxilary()){
00197             symbolClass = ((Symbol*)tmpSymbol)->GET(n_sclass);
00198             if (symbolClass == C_FILE){
00199                 numberOfFiles++;
00200             }
00201             else if (symbolClass == C_BINCL){
00202                 numberOfFiles++;
00203             }
00204             else if (symbolClass == C_FUN){
00205                 numberOfFunctions++;
00206             }
00207         }
00208     }
00209 
00210     files = new FileFinder*[numberOfFiles];
00211     functions = new FunctionFinder*[numberOfFunctions];
00212     numberOfFiles = 0;
00213     numberOfFunctions = 0;
00214 
00215         /* initialize each entry of files[] and functions[] */
00216     for (uint32_t i = 0; i < symbolTable->getNumberOfSymbols(); i++){
00217         tmpSymbol = symbolTable->getSymbol(i);
00218         if (!tmpSymbol->isAuxilary()){
00219             symbolClass = ((Symbol*)tmpSymbol)->GET(n_sclass);
00220             if (symbolClass == C_FILE){
00221                 files[numberOfFiles] = new SourceFileFinder(symbolTable, lineInfoTable, stringTable, i);
00222                 currentSourceFile = numberOfFiles;
00223                 numberOfFiles++;
00224             }
00225             else if (symbolClass == C_BINCL){
00226                 files[numberOfFiles] = new IncludeFileFinder(symbolTable, lineInfoTable, stringTable, i,
00227                         getLineInfoIndex(((Symbol*)tmpSymbol)->GET(n_value)),
00228                         getLineInfoIndex(((Symbol*)symbolTable->getSymbol(i+1))->GET(n_value)));
00229                 numberOfFiles++;
00230             }
00231             else if (symbolClass == C_FUN){
00232                 functions[numberOfFunctions] = new FunctionFinder(symbolTable, lineInfoTable, stringTable, i, lineInfoFunctions, numberOfLineInfoFunctions);
00233                 numberOfFunctions++;
00234             }
00235         }
00236     }
00237 
00238         /* find out which files and addresses are from include files */
00239     isIncludeFile = new uint16_t[(numberOfFiles/sizeof(uint16_t))+1];
00240     isIncludeFile2 = new bool[numberOfFiles];
00241     isAddressFromIncludeFile = new uint16_t[(numberOfLineInfos/sizeof(uint16_t))+1];
00242     isAddressFromIncludeFile2 = new bool[numberOfLineInfos];
00243     for (uint32_t i = 0; i < numberOfFiles; i++){
00244         if (files[i]->isIncludeFile()){
00245             SET_IS_INCL_FILE_BIT(i);
00246             isIncludeFile2[i] = true;
00247             for (uint32_t j = ((IncludeFileFinder*)files[i])->getLineInfoIndex(); j <= ((IncludeFileFinder*)files[i])->getEndLineInfoIndex(); j++){
00248                 SET_IS_INCL_ADDR_BIT(j);
00249                 isAddressFromIncludeFile2[j] = true;
00250             }
00251         } else {
00252         }
00253     }
00254 
00255 
00256         /* now that all entries of files[] are initialized, find parent files for each function */
00257     for (uint32_t i = 0; i < numberOfFunctions; i++){
00258         functions[i]->setParent(files, numberOfFiles);
00259     }
00260 
00261         /* collect symbol indices for all files and all function parents */
00262     parentIndices = new uint32_t[numberOfFunctions];
00263     fileIndices = new uint32_t[numberOfFiles];
00264     for (uint32_t i = 0; i < numberOfFunctions; i++){
00265         parentIndices[i] = functions[i]->getParentFile()->getSymbolIndex();
00266     }
00267     for (uint32_t i = 0; i < numberOfFiles; i++){
00268         fileIndices[i] = files[i]->getSymbolIndex();
00269     }
00270 
00271         /* now that all entries of functions[] have parent files, find member functions for each file */
00272     for (uint32_t i = 0; i < numberOfFiles; i++){
00273         numberOfLocalFunctions = 0;
00274 
00275         for (uint32_t j = 0; j < numberOfFunctions; j++){
00276             if (parentIndices[j] == fileIndices[i]){
00277                 numberOfLocalFunctions++;
00278             } 
00279         }
00280 
00281         files[i]->setNumberOfFunctions(numberOfLocalFunctions);
00282         numberOfLocalFunctions = 0;
00283 
00284         for (uint32_t j = 0; j < numberOfFunctions; j++){
00285             if (parentIndices[j] == fileIndices[i]){
00286                 files[i]->addFunction(functions[j],numberOfLocalFunctions);
00287                 numberOfLocalFunctions++;
00288             }
00289         }
00290     }
00291 }
00292 
00293 
00294 LineInfoFinder::~LineInfoFinder(){
00295     delete lineInfos;
00296     delete lineInfoLineNumbers;
00297     delete lineInfoAddresses;
00298     delete isIncludeFile;
00299     delete isAddressFromIncludeFile;
00300     delete sortedAddresses;
00301     delete files;
00302     delete functions;
00303 }
00304 
00305 
00306 void LineInfoFinder::printFiles(){
00307     PRINT_INFOR("***********");
00308     PRINT_INFOR("There are %d source files in the symbol table", numberOfFiles);
00309     PRINT_INFOR("***********");
00310     for (uint32_t i = 0; i < numberOfFiles; i++){
00311         files[i]->print();
00312     }
00313 }
00314 
00315 
00316 void LineInfoFinder::printFunctions(){
00317     PRINT_INFOR("***********");
00318     PRINT_INFOR("There are %d functions in the symbol table", numberOfFunctions);
00319     PRINT_INFOR("***********");
00320     for (uint32_t i = 0; i < numberOfFunctions; i++){
00321         functions[i]->print();
00322     }
00323 }
00324 
00325 
00326 bool LineInfoFinder::testLineInfoFinder(){
00327     uint64_t address;
00328     char* fName;
00329 
00330 #ifdef TEST_ALL_ADDRESS
00331 //    printLineInfoTable();
00332 //    printSymbolTable();
00333 
00334     PRINT_INFOR("***********");
00335     PRINT_INFOR("*********** Testing  getLineNumberInFunction, getFunctionName, getLineNumberInFile, getFileName");
00336     PRINT_INFOR("***********");
00337 
00338     for (uint32_t i = 0; i < numberOfLineInfos; i++){
00339         if (lineInfoLineNumbers[i]){
00340             address = lineInfoAddresses[i];
00341             ASSERT(isAddressInLineInfoTable(address));
00342 /*
00343             PRINT_INFOR("LineInfoTable[%d]: address %#llx is at line %d in function %s, include %d", i, address, getLineNumberInFunction(address), 
00344                 getFunctionName(address), GET_IS_INCL_ADDR_BIT(i));
00345 */
00346             PRINT_INFOR("LineInfoTable[%d]: address %#llx is at line %d in function %s, line %d in file %s, include %d", i, address, getLineNumberInFunction(address), 
00347                 getFunctionName(address), getLineNumberInFile(address), getFileName(address), GET_IS_INCL_ADDR_BIT(i));
00348 
00349 #ifdef TEST_ALL_ADDRESS_OUT
00350             if (getLineInfoIndexOfPreviousAddr(address-4) < numberOfLineInfos){
00351                 PRINT_INFOR("\taddress %#llx -> %#llx is at line %d in function %s, line %d in file %s", 
00352                     address-4, lineInfoTable->getLineInfo(getLineInfoIndexOfPreviousAddr(address-4))->GET(l_paddr), 
00353                     getLineNumberInFunction(address-4), getFunctionName(address-4), getLineNumberInFile(address-4), 
00354                     getFileName(address-4));
00355             }
00356             if (getLineInfoIndexOfPreviousAddr(address+4) < numberOfLineInfos){
00357                 PRINT_INFOR("\taddress %#llx -> %#llx is at line %d in function %s, line %d in file %s", 
00358                     address+4, lineInfoTable->getLineInfo(getLineInfoIndexOfPreviousAddr(address+4))->GET(l_paddr), 
00359                     getLineNumberInFunction(address+4), getFunctionName(address+4), getLineNumberInFile(address+4), 
00360                     getFileName(address+4));
00361             }
00362 #endif
00363         }
00364     }
00365 #endif
00366 
00367 #ifdef TEST_GET_FUNCTION_NAME
00368     PRINT_INFOR("***********");
00369     PRINT_INFOR("*********** Testing getFunctionName");
00370     PRINT_INFOR("***********");
00371 
00372     for (uint32_t i = 0; i < numberOfLineInfos; i++){
00373         if (lineInfoLineNumbers[i])){
00374             address = lineInfoAddresses[i];
00375             ASSERT(isAddressInLineInfoTable(address));
00376             fName = getFunctionName(address);
00377             PRINT_INFOR("Address %#llx is in function %s", address, fName);
00378         }
00379     }
00380 #endif
00381 
00382 #ifdef TEST_GET_FILE_NAME
00383     PRINT_INFOR("***********");
00384     PRINT_INFOR("*********** Testing getFileName");
00385     PRINT_INFOR("***********");
00386 
00387     for (uint32_t i = 0; i < numberOfLineInfos; i++){
00388         if (lineInfoLineNumbers[i])){
00389             address = lineInfoAddresses[i];
00390             ASSERT(isAddressInLineInfoTable(address));
00391             fName = getFileName(address);
00392             PRINT_INFOR("Address %#llx is in file %s", address, fName);
00393         }
00394     }
00395 #endif
00396 
00397 #ifdef TEST_GET_LINE_NUMBER_IN_FUNCTION
00398     PRINT_INFOR("***********");
00399     PRINT_INFOR("*********** Testing getLineNumberInFunction");
00400     PRINT_INFOR("***********");
00401 
00402     for (uint32_t i = 0; i < numberOfLineInfos; i++){
00403         if (lineInfoLineNumbers[i])){
00404             address = lineInfoAddresses[i];
00405             ASSERT(isAddressInLineInfoTable(address));
00406             PRINT_INFOR("Address %#llx has line %d", address, getLineNumberInFunction(address));
00407         }
00408     }
00409 #endif
00410 
00411 #ifdef TEST_GET_LINE_NUMBER_IN_FILE
00412     PRINT_INFOR("***********");
00413     PRINT_INFOR("*********** Testing getLineNumberInFile");
00414     PRINT_INFOR("***********");
00415 
00416     for (uint32_t i = 0; i < numberOfLineInfos; i++){
00417         if (lineInfoLineNumbers[i])){
00418             address = lineInfoAddresses[i];
00419             ASSERT(isAddressInLineInfoTable(address));
00420             PRINT_INFOR("Address %#llx has line %d", address, getLineNumberInFile(address));
00421         }
00422     }
00423 #endif
00424 
00425 
00426 #ifdef TEST_GET_ADDRESS_BY_FUNCTION
00427     PRINT_INFOR("***********");
00428     PRINT_INFOR("*********** Testing getAddressByFunction");
00429     PRINT_INFOR("***********");
00430 
00431     char* fcnName;
00432     bool isOldFcnName;
00433     char** uniqueFcnNames = new char*[numberOfFunctions];
00434     uint32_t nextFcn = 0;
00435 
00436     for (uint32_t i = 0; i < numberOfFunctions; i++){
00437         PRINT_INFOR("About to examine function %d", i);
00438         fcnName = functions[i]->getName();
00439         PRINT_INFOR("Examining function %s", fcnName);
00440         isOldFcnName = false;
00441         for (uint32_t j = 0; j < numberOfFunctions; j++){
00442             if (!strcmp(uniqueFcnNames[j],fcnName)){
00443                 isOldFcnName = true;
00444             }
00445         }
00446         if (!isOldFcnName){
00447             uniqueFcnNames[nextFcn] = fcnName;
00448             nextFcn++;
00449             for (uint32_t j = 0; j < MAX_LINE_TEST; j++){
00450                 ASSERT(isFunctionNameInSymbolTable(functions[i]->getName()));
00451                 if (isLineInFunction(j, functions[i]->getName())){
00452                     address = getAddressByFunction(j,functions[i]->getName());
00453                     PRINT_INFOR("\tFunctionFinder %s at line %d in file %s, line %d -- address %#llx", functions[i]->getName(), functions[i]->getFirstLine(),
00454                             functions[i]->getParentFile()->getName(), j, address);
00455                     address = getAddressByFunction(j,functions[i]->getName(),address);
00456                     while (address != 0){
00457                         PRINT_INFOR("\t\taddress %#llx", address);
00458                         address = getAddressByFunction(j,functions[i]->getName(),address);
00459                     }
00460                 }
00461             }
00462         }
00463     }
00464 #endif
00465 #ifdef TEST_GET_ADDRESS_BY_FILE
00466     PRINT_INFOR("***********");
00467     PRINT_INFOR("*********** Testing getAddressByFile");
00468     PRINT_INFOR("***********");
00469 
00470     char* fileName;
00471     bool isOldFileName;
00472     char** uniqueFileNames = new char*[numberOfFiles];
00473     uint32_t nextFile = 0;
00474 
00475     for (uint32_t i = 0; i < numberOfFiles; i++){
00476         fileName = files[i]->getName();
00477         isOldFileName = false;
00478         for (uint32_t j = 0; j < numberOfFiles; j++){
00479             if (!strcmp(uniqueFileNames[j],fileName)){
00480                 isOldFileName = true;
00481             }
00482         }
00483         if (!isOldFileName){
00484             uniqueFileNames[nextFile] = fileName;
00485             nextFile++;
00486             for (uint32_t j = 0; j < MAX_LINE_TEST; j++){
00487                 ASSERT(isFileNameInSymbolTable(files[i]->getName()));
00488                 if (isLineInFile(j, files[i]->getName())){
00489                     address = getAddressByFile(j,files[i]->getName());
00490                     PRINT_INFOR("\tFile %s, line %d -- address %#llx", files[i]->getName(), j, address);
00491                     address = getAddressByFile(j,files[i]->getName(),address);
00492                     while (address != 0){
00493                         PRINT_INFOR("\t\taddress %#llx", address);
00494                         address = getAddressByFile(j,files[i]->getName(),address);
00495                     }
00496                 }
00497             }
00498         }
00499     }
00500 #endif
00501 
00502     return true;
00503 }
00504 
00505 
00506 char* LineInfoFinder::getFileName(uint64_t addr) { 
00507 
00508         /* search every include file for this address */
00509     for (uint32_t i = 0; i < numberOfFiles; i++){
00510         if (GET_IS_INCL_FILE_BIT(i)){
00511             if (((IncludeFileFinder*)files[i])->containsAddress(addr)){
00512                 return files[i]->getName();
00513             }
00514         }
00515     }
00516         /* address is not part of an include file, so use the header in
00517            lineInfoTable to look up the function */
00518     return getFileNameOfFunction(getFunctionName(addr)); 
00519 }
00520 
00521 
00522 void LineInfoFinder::printFunctionSymbols(){
00523     for (uint32_t i = 0; i < numberOfLineInfos; i++){
00524         if (!lineInfoLineNumbers[i]){
00525             symbolTable->printSymbol(lineInfos[i]->GET(l_symndx)); 
00526         }
00527     }
00528     return;
00529 }
00530 
00531 
00532 void LineInfoFinder::printFileSymbols(){
00533     for (uint32_t i = 0; i < symbolTable->getNumberOfSymbols(); i++){
00534         if (!symbolTable->getSymbol(i)->isAuxilary() && ((Symbol*)symbolTable->getSymbol(i))->GET(n_sclass) == C_FILE){
00535             symbolTable->printSymbol(i);
00536         }
00537     }
00538     return;
00539 }
00540 
00541 
00542 void LineInfoFinder::printSymbolTable(){
00543     for (uint32_t i = 0; i < symbolTable->getNumberOfSymbols(); i++){
00544         if (!symbolTable->getSymbol(i)->isAuxilary()){
00545             symbolTable->printSymbol(i);
00546         }
00547     }
00548     return;
00549 }
00550 
00551 
00552 void LineInfoFinder::printLineInfoTable(){
00553     for (uint32_t i = 0; i < numberOfLineInfos; i++){
00554         if(lineInfoLineNumbers[i]){
00555             PRINT_INFOR("\tLNN [%3d] (lnn %9d)(adr %#llx)",i,lineInfoLineNumbers[i],lineInfoAddresses[i]);
00556         } else {
00557             PRINT_INFOR("\tLNN [%3d] (fcn bgn)(sym %9d)",i,lineInfos[i]->GET(l_symndx));
00558         }
00559     }
00560 }
00561 
00562 
00563 char* LineInfoFinder::getFileNameOfFunction(char* fcnName){
00564 
00565         /* look in the list of functions for this fcnName, then return
00566            the name of the parent file of that function */
00567     for (uint32_t i = 0; i < numberOfFunctions; i++){
00568         if(!strcmp(fcnName,functions[i]->getName())){
00569             return functions[i]->getParentFile()->getName();
00570         }
00571     }
00572     return NULL;
00573 }
00574 
00575 
00576 char* LineInfoFinder::getFunctionName(uint64_t addr){
00577     uint32_t previousFunctionIndex;
00578     uint32_t addrIndex;
00579 
00580         /* find the address, then go backwards in the lineInfoTable until a function entry
00581            is found. when this occurs, follow the pointer to the symbol table to get the
00582            function name */
00583     addrIndex = getLineInfoIndexOfPreviousAddr(addr);
00584     if (addrIndex == numberOfLineInfos){
00585         return NULL;
00586     }
00587     previousFunctionIndex = addrIndex - 1;
00588     for (; previousFunctionIndex >= 0; previousFunctionIndex--){
00589         if (!lineInfoLineNumbers[previousFunctionIndex]){
00590             return symbolTable->getSymbolName(lineInfos[previousFunctionIndex]->GET(l_symndx));
00591         }
00592     }
00593     return NULL;
00594 }
00595 
00596 
00597 bool LineInfoFinder::isFunctionNameInSymbolTable(char* fcnName){
00598 
00599         /* scan function list to see if this fcnName is found */
00600     for (uint32_t i = 0; i < numberOfFunctions; i++){
00601         if (!strcmp(functions[i]->getName(),fcnName)){
00602             return true;
00603         }
00604     }
00605     return false;
00606 }
00607 
00608 
00609 bool LineInfoFinder::isFileNameInSymbolTable(char* fileName){
00610 
00611         /* scan file list to see if this fileName is found */
00612     for (uint32_t i = 0; i < numberOfFiles; i++){
00613         if (!strcmp(files[i]->getName(),fileName)){
00614             return true;
00615         }
00616     }
00617     return false;
00618 }
00619 
00620 
00621 bool LineInfoFinder::isLineInFunction(uint32_t lineno, char* fcnName) {
00622 
00623         /* scan function list to find this fcnName, then see if that function
00624            has the given lineno */
00625     for (uint32_t i = 0; i < numberOfFunctions; i++){
00626         if (!strcmp(functions[i]->getName(),fcnName)){
00627             if (functions[i]->containsLineNumber(lineno)){
00628                 return true;
00629             }
00630         }
00631     }
00632     return false;
00633 }
00634 
00635 
00636 bool LineInfoFinder::isLineInFile(uint32_t lineno, char* fileName) {
00637     uint32_t effectiveLine;
00638 
00639         /* scan function list to see if some function's parent file is named
00640            fileName, then see if that file contains the given lineno */
00641     for (uint32_t i = 0; i < numberOfFunctions; i++){
00642         if (!strcmp(functions[i]->getParentFile()->getName(),fileName)){
00643             effectiveLine = lineno - functions[i]->getFirstLine() + 1;
00644             if (functions[i]->containsLineNumber(effectiveLine)){
00645                 return true;
00646             }
00647         }
00648     }
00649 
00650     return false;
00651 }
00652 
00653 
00654 uint64_t LineInfoFinder::getAddressByFunction(uint32_t lineno, char* fcnName) {
00655 
00656         /* scan function list to find this fcnName, see if that function
00657            has the given lineno, then return the first address associated with 
00658            that lineno */
00659     for (uint32_t i = 0; i < numberOfFunctions; i++){
00660         if (!strcmp(functions[i]->getName(),fcnName)){
00661             if (functions[i]->containsLineNumber(lineno)){
00662                 return functions[i]->getAddressByLineNumber(lineno);
00663             }
00664         }
00665     }
00666     return 0;
00667 }
00668 
00669 
00670 uint64_t LineInfoFinder::getAddressByFunction(uint32_t lineno, char* fcnName, uint64_t addr) {
00671 
00672         /* scan function list to find this fcnName, see if that function
00673            has the given lineno, then return the first address greater than 
00674            addr associated with that lineno */
00675     for (uint32_t i = 0; i < numberOfFunctions; i++){
00676         if (!strcmp(functions[i]->getName(),fcnName)){
00677             if (functions[i]->containsLineNumber(lineno)){
00678                 return functions[i]->getAddressByLineNumber(lineno, addr);
00679             }
00680         }
00681     }
00682     return 0;
00683 }
00684 
00685 
00686 uint64_t LineInfoFinder::getAddressByFile(uint32_t lineno, char* fileName) {
00687     uint32_t effectiveLine;
00688 
00689         /* scan function list to see if some function's parent file is named
00690            fileName, see if that file contains the given lineno, then return
00691            the first address associated with that lineno */
00692     for (uint32_t i = 0; i < numberOfFunctions; i++){
00693         if (!strcmp(functions[i]->getParentFile()->getName(),fileName)){
00694             effectiveLine = lineno - functions[i]->getFirstLine() + 1;
00695             if (functions[i]->containsLineNumber(effectiveLine)){
00696                 return functions[i]->getAddressByLineNumber(effectiveLine);
00697             }
00698         }
00699     }
00700 
00701     return 0;
00702 }
00703 
00704 
00705 uint64_t LineInfoFinder::getAddressByFile(uint32_t lineno, char* fileName, uint64_t addr) {
00706     uint32_t effectiveLine;
00707     uint64_t address;
00708 
00709         /* scan function list to see if some function's parent file is named
00710            fileName, see if that file contains the given lineno, then return
00711            the first address greater than addr associated with that lineno */
00712     for (uint32_t i = 0; i < numberOfFunctions; i++){
00713         if (!strcmp(functions[i]->getParentFile()->getName(),fileName)){
00714             effectiveLine = lineno - functions[i]->getFirstLine() + 1;
00715             if (functions[i]->containsLineNumber(effectiveLine)){
00716                 address = functions[i]->getAddressByLineNumber(effectiveLine, addr);
00717                 if (address != 0){
00718                     return address;
00719                 }
00720             }
00721         }
00722     }
00723 
00724     return 0;
00725 }
00726 
00727 
00728 bool LineInfoFinder::isAddressInLineInfoTable(uint64_t addr){
00729     uint32_t addrIndex = getLineInfoIndexOfAddr(addr);
00730     if (addrIndex == numberOfLineInfos){
00731         return false;
00732     }
00733     return true;
00734 }
00735 
00736 
00737 uint32_t LineInfoFinder::getLineNumberInFile(uint64_t addr){
00738 
00739         /* scan function list to find the function that contains addr, then
00740            return the appropriately modified line number for addr */
00741     for (uint32_t i = 0; i < numberOfFunctions; i++){
00742         if (functionContainsAddress(i, addr)){
00743             if (GET_IS_INCL_ADDR_BIT(getLineInfoIndexOfPreviousAddr(addr))){
00744                 return getLineNumberInFunction(addr);
00745             } else {
00746                 return functions[i]->getFirstLine() + getLineNumberInFunction(addr) - 1;
00747             }
00748         }
00749     }
00750     return 0;
00751 }
00752 
00753 
00754 uint32_t LineInfoFinder::getLineNumberInFunction(uint64_t addr){
00755     uint32_t addrIndex = getLineInfoIndexOfPreviousAddr(addr);
00756     if (addrIndex >= numberOfLineInfos){
00757         return 0;
00758     }
00759     return lineInfoLineNumbers[addrIndex];
00760 }
00761 
00762 
00763 bool LineInfoFinder::functionContainsAddress(uint32_t idx, uint64_t addr){
00764     uint32_t lineIndex = getLineInfoIndexOfPreviousAddr(addr);
00765     if (lineIndex > functions[idx]->getBeginLineInfoIndex() && lineIndex < functions[idx]->getEndLineInfoIndex()){
00766         return true;
00767     }
00768     return false;
00769 }
00770 
00771 
00772 FileFinder* FunctionFinder::setParent(FileFinder** files, uint32_t numberOfFiles){
00773 
00774         /* scan the file list to see if this function belongs to an include file */
00775     for (uint32_t i = 0; i < numberOfFiles; i++){
00776         if (files[i]->isIncludeFile()){
00777             if (((IncludeFileFinder*)files[i])->getLineInfoIndex() == beginLineInfoIndex){
00778                 parentFile = files[i];
00779                 return parentFile;
00780             }
00781         }
00782     }
00783 
00784         /* scan the file list to see which source file this function belongs to */
00785     for (uint32_t i = 0; i < numberOfFiles-1; i++){
00786         if (files[i]->isSourceFile()){
00787 
00788                 /* find the next source file in the symbol table */
00789             uint32_t j = i+1;
00790             while (!files[j]->isSourceFile()){
00791                 j++;
00792             }
00793 
00794                 /* see if the next source file occurs after this function in the symbol table */
00795             if (files[j]->getSymbolIndex() > lineInfoTable->getLineInfo(beginLineInfoIndex)->GET(l_symndx)){
00796                 parentFile = files[i];
00797                 return parentFile;
00798             }
00799         }
00800     }
00801     return 0;
00802 }
00803 
00804 
00805 bool FunctionFinder::containsLineNumber(uint32_t lineno){
00806 
00807         /* scan this function's section of the lineInfoTable to see if lineno
00808            can be found */
00809     for (uint32_t i = beginLineInfoIndex + 1; i < endLineInfoIndex; i++){
00810         if (lineInfoTable->getLineInfo(i)->GET(l_lnno)){
00811             if (lineInfoTable->getLineInfo(i)->GET(l_lnno) == lineno){
00812                 return true;
00813             }
00814         }
00815     }
00816     return false;
00817 }
00818 
00819 
00820 uint64_t FunctionFinder::getAddressByLineNumber(uint32_t lineno){
00821 
00822         /* scan this function's section of the lineInfoTable to see if lineno
00823            can be found. if so, retturn the first address associated with that lineno */
00824     for (uint32_t i = beginLineInfoIndex; i < endLineInfoIndex; i++){
00825         if (lineInfoTable->getLineInfo(i)->GET(l_lnno) == lineno){
00826             return lineInfoTable->getLineInfo(i)->GET(l_paddr);
00827         }
00828     }
00829     return 0;
00830 }
00831 
00832 
00833 uint64_t FunctionFinder::getAddressByLineNumber(uint32_t lineno, uint64_t addr){
00834 
00835         /* scan this function's section of the lineInfoTable to see if lineno
00836            can be found. if so, return the first address greater than addr 
00837            associated with that lineno */
00838     for (uint32_t i = beginLineInfoIndex; i < endLineInfoIndex; i++){
00839         if (lineInfoTable->getLineInfo(i)->GET(l_lnno) == lineno){
00840             if (lineInfoTable->getLineInfo(i)->GET(l_paddr) > addr){
00841                 return lineInfoTable->getLineInfo(i)->GET(l_paddr);
00842             }
00843         }
00844     }
00845     return 0;
00846 }
00847 
00848 
00849 void FunctionFinder::print(){
00850     if (fromIncludeFile){
00851     } else {
00852         PRINT_INFOR("FunctionFinder %s, LineInfoTable range [%d, %d), firstline %d, parent file %s", 
00853                 functionName, beginLineInfoIndex, endLineInfoIndex, firstLine, parentFile->getName());
00854     }
00855 }
00856 
00857 
00858 FunctionFinder::FunctionFinder(SymbolTable* symTable, LineInfoTable* linTable, StringTable* strTable, uint32_t idx,
00859 struct idx_symndx* lineInfoFunctions, uint32_t numberOfLineInfoFunctions){
00860     uint32_t symbolClass;
00861     uint32_t numberOfLineInfos = linTable->getNumberOfLineInfos();
00862     uint32_t extSymbolIndex;
00863     uint32_t functionSymbolIndex;
00864     uint32_t lastLine;
00865     uint32_t beginFcnSymbolIndex;
00866     uint32_t endFcnSymbolIndex;
00867     char* fName;
00868 
00869     symbolTable = symTable;
00870     lineInfoTable = linTable;
00871     stringTable = strTable;
00872 
00873     functionSymbolIndex = idx;
00874 
00875         /* go backwards in the symbol table to look for the EXT symbol for this function */
00876     for (int32_t i = idx; i > 0; i--){
00877         if (!symbolTable->getSymbol(i)->isAuxilary()){
00878             symbolClass = ((Symbol*)symbolTable->getSymbol(i))->GET(n_sclass);
00879             if (symbolClass == C_EXT || symbolClass == C_HIDEXT || symbolClass == C_WEAKEXT){
00880                 extSymbolIndex = i;
00881                 i = 0;
00882             }
00883         }
00884     }
00885 
00886     functionName = symbolTable->getSymbolName(extSymbolIndex);
00887 
00888 
00889         /* go forwards in the symbol table to look for the begin FCN and end FCN symbols
00890            for this function */
00891 
00892     for (uint32_t i = functionSymbolIndex; i < symbolTable->getNumberOfSymbols(); i++){
00893         if (!symbolTable->getSymbol(i)->isAuxilary() && ((Symbol*)symbolTable->getSymbol(i))->GET(n_sclass) == C_FCN){
00894             fName = symbolTable->getSymbolName(i);
00895             if (!strcmp(fName,C_FCN_BEGIN_NAME)){
00896                 beginFcnSymbolIndex = i;
00897                 firstLine = ((Auxilary*)symbolTable->getSymbol(i+1))->GET_A(x_lnno,x_misc);
00898             }
00899             if (!strcmp(fName,C_FCN_END_NAME)){
00900                 endFcnSymbolIndex = i;
00901                 lastLine = ((Auxilary*)symbolTable->getSymbol(i+1))->GET_A(x_lnno,x_misc);
00902                 i = symbolTable->getNumberOfSymbols();
00903             }
00904             free(fName);
00905         }                
00906     }
00907 
00908     for (uint32_t i = 0; i < numberOfLineInfoFunctions; i++){
00909         if (lineInfoFunctions[i].symndx == extSymbolIndex){
00910             beginLineInfoIndex = lineInfoFunctions[i].index;
00911             if (i == numberOfLineInfoFunctions - 1){
00912                 endLineInfoIndex = numberOfLineInfos;
00913             } else {
00914                 endLineInfoIndex = lineInfoFunctions[i+1].index;
00915             }
00916             i = numberOfLineInfoFunctions;
00917         }
00918     }
00919 }
00920 
00921 
00922 FunctionFinder::~FunctionFinder(){
00923     free(functionName);
00924 }
00925 
00926 
00927 
00928 
00929 uint32_t FileFinder::setNumberOfFunctions(uint32_t numberFunctions){
00930     numberOfFunctions = numberFunctions;
00931     memberFunctions = new FunctionFinder*[numberOfFunctions];
00932     return numberOfFunctions;
00933 }
00934 
00935 
00936 uint32_t FileFinder::addFunction(FunctionFinder* child, uint32_t idx){
00937     memberFunctions[idx] = child;
00938     return idx;
00939 }
00940 
00941 
00942 SourceFileFinder::SourceFileFinder(SymbolTable* symTable, LineInfoTable* linTable, StringTable* strTable, uint32_t idx){
00943     uint32_t auxNameLen;
00944     symbolTable = symTable;
00945     lineInfoTable = linTable;
00946     stringTable = strTable;
00947     includeFile = false;
00948     fileType = FILE_TYPE_SOURCE;
00949     
00950     char* fName = symbolTable->getSymbolName(idx);
00951 
00952         /* see if the symbol for this file in a generic fashion. if so, the next
00953            symbol contains the name for this file */
00954     if (!strcmp(fName, CPP_GENERIC_FILE_SYM_NAME)){
00955         cppNameScheme = true;
00956         nameIndex = idx + CPP_FILE_FORWARD_OFFSET_TO_NAME;
00957         free(fName);
00958         Auxilary* auxEntry = (Auxilary*)symbolTable->getSymbol(nameIndex);
00959         if (auxEntry->GET_A(x_zeroes, x_file) == 0){
00960             auxNameLen = strlen(stringTable->getString(auxEntry->GET_A(x_offset, x_file))); 
00961             fileName = new char[auxNameLen];            
00962             strcpy(fileName, stringTable->getString(auxEntry->GET_A(x_offset, x_file)));
00963         } else {
00964             auxNameLen = strlen(auxEntry->GET_A(x_fname, x_file));
00965             fileName = new char[auxNameLen];
00966             strcpy(fileName, auxEntry->GET_A(x_fname, x_file));
00967         }
00968     } else {
00969         cppNameScheme = false;
00970         nameIndex = idx;
00971         fileName = fName;
00972     }
00973     symbolIndex = idx;
00974 }
00975 
00976 
00977 SourceFileFinder::~SourceFileFinder(){
00978     free(fileName);
00979 }
00980 
00981 
00982 void SourceFileFinder::print(){
00983     PRINT_INFOR("Source File %s, index %d, cppNameScheme %d, nameIndex %d", fileName, symbolIndex, cppNameScheme, nameIndex);
00984     for (uint32_t i = 0; i < numberOfFunctions; i++){
00985         PRINT_INFOR("\tMember function %s", memberFunctions[i]->getName());
00986     }
00987 }
00988 
00989 
00990 bool IncludeFileFinder::containsAddress(uint64_t addr){
00991 
00992         /* scan this include file's section of the lineInfoTable to see
00993            if addr can be found */
00994     for (uint32_t i = lineInfoIndex; i < endLineInfoIndex + 1; i++){
00995         if (lineInfoTable->getLineInfo(i)->GET(l_paddr)){
00996             if (lineInfoTable->getLineInfo(i)->GET(l_paddr) == addr){
00997                 return true;
00998             }
00999         }
01000     }
01001     return false;
01002 }
01003 
01004 
01005 void IncludeFileFinder::print(){
01006     PRINT_INFOR("Include File %s, symbol index %d, line info indices [%d,%d]", fileName, symbolIndex, lineInfoIndex, endLineInfoIndex);
01007     for (uint32_t i = 0; i < numberOfFunctions; i++){
01008         PRINT_INFOR("\tMember function %s", memberFunctions[i]->getName());
01009     }
01010 }
01011 
01012 
01013 IncludeFileFinder::IncludeFileFinder(SymbolTable* symTable, LineInfoTable* linTable, StringTable* strTable, uint32_t idx, uint32_t linIndex, uint32_t
01014 endLinIndex){
01015     symbolIndex = idx;
01016     lineInfoIndex = linIndex;
01017     endLineInfoIndex = endLinIndex;
01018     symbolTable = symTable;
01019     lineInfoTable = linTable;
01020     stringTable = strTable;
01021     includeFile = true;
01022     fileName = symbolTable->getSymbolName(idx);
01023     fileType = FILE_TYPE_INCLUDE;
01024 }
01025 
01026 
01027 IncludeFileFinder::~IncludeFileFinder(){
01028     free(fileName);
01029 }
01030 
01031 int32_t compare_idx_addr(const void* a, const void* b){
01032     return ( (*(struct idx_addr*)a).address - (*(struct idx_addr*)b).address);
01033 }
01034 
01035 

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