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
00013
00014
00015
00016
00017
00018
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
00029 if (addr < sortedAddresses[first].address){
00030 return numberOfLineInfos;
00031 } else if (addr > sortedAddresses[last].address){
00032 return sortedAddresses[last].index;
00033 }
00034
00035
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
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
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
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
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
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
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
00257 for (uint32_t i = 0; i < numberOfFunctions; i++){
00258 functions[i]->setParent(files, numberOfFiles);
00259 }
00260
00261
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
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
00332
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
00344
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
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
00517
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
00566
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
00581
00582
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
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
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
00624
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
00640
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
00657
00658
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
00673
00674
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
00690
00691
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
00710
00711
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
00740
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
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
00785 for (uint32_t i = 0; i < numberOfFiles-1; i++){
00786 if (files[i]->isSourceFile()){
00787
00788
00789 uint32_t j = i+1;
00790 while (!files[j]->isSourceFile()){
00791 j++;
00792 }
00793
00794
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
00808
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
00823
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
00836
00837
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
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
00890
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
00953
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
00993
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