srcanamdw/appdep/src/appdep_getters.cpp
changeset 0 509e4801c378
equal deleted inserted replaced
-1:000000000000 0:509e4801c378
       
     1 /*
       
     2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Utility functions for getting data via 3rd party tools
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "appdep.hpp"
       
    20 
       
    21 // ----------------------------------------------------------------------------------------------------------
       
    22 // Note that in C/C++ code \ has been replaced with \\ and " with \".
       
    23 // ----------------------------------------------------------------------------------------------------------
       
    24 
       
    25 void GetImportTableWithPetran(const string& petran_location, binary_info& b_info)
       
    26 {
       
    27     vector<dependency> deps;
       
    28     vector<string> tempVector;
       
    29 
       
    30     // init defaults
       
    31     b_info.binary_format = UNKNOWN;
       
    32     b_info.uid1 = UNKNOWN;
       
    33     b_info.uid2 = UNKNOWN;
       
    34     b_info.uid3 = UNKNOWN;
       
    35     b_info.secureid = NOT_VALID;
       
    36     b_info.vendorid = NOT_VALID;
       
    37     b_info.capabilities = 0;
       
    38     b_info.min_heap_size = 0;
       
    39     b_info.max_heap_size = 0;
       
    40     b_info.stack_size = 0;
       
    41 
       
    42     // execute petran
       
    43     string cmd;
       
    44 
       
    45     if (_cl_use_gcce || _cl_use_rvct)
       
    46         cmd = petran_location + " -dump hi \"" + b_info.directory + b_info.filename + "\" " + CERR_TO_NULL;
       
    47     else
       
    48         cmd = petran_location + " \"" + b_info.directory + b_info.filename + "\" " + CERR_TO_NULL;
       
    49 
       
    50     //cerr << cmd << endl;
       
    51     ExecuteCommand(cmd, tempVector);
       
    52 
       
    53     // get binary format, assuming it's the first line which begings with EPOC
       
    54     for (unsigned int j=0; j<tempVector.size() && j<100; j++)
       
    55     {
       
    56         boost::regex re("^(EPOC.+)");
       
    57         boost::cmatch matches;
       
    58         if (boost::regex_match(tempVector.at(j).c_str(), matches, re))
       
    59         {
       
    60             string ms1(matches[1].first, matches[1].second);
       
    61             TrimAll(ms1);
       
    62             b_info.binary_format = ms1;
       
    63             break;
       
    64         }
       
    65     }
       
    66 
       
    67     // get uids
       
    68     for (unsigned int j=0; j<tempVector.size() && j<100; j++)
       
    69     {
       
    70         boost::regex re("^Uids:\\s+(\\S+)\\s+(\\S+)\\s+(\\S+).+");
       
    71         boost::cmatch matches;
       
    72         if (boost::regex_match(tempVector.at(j).c_str(), matches, re))
       
    73         {
       
    74             string ms1(matches[1].first, matches[1].second);
       
    75             string ms2(matches[2].first, matches[2].second);
       
    76             string ms3(matches[3].first, matches[3].second);
       
    77             b_info.uid1 = "0x"+ms1;
       
    78             b_info.uid2 = "0x"+ms2;
       
    79             b_info.uid3 = "0x"+ms3;
       
    80             break;
       
    81         }
       
    82     }
       
    83 
       
    84     // get secure id
       
    85     for (unsigned int j=0; j<tempVector.size() && j<100; j++)
       
    86     {
       
    87         boost::regex re("^Secure\\sID:\\s+(\\S+)");
       
    88         boost::cmatch matches;
       
    89         if (boost::regex_match(tempVector.at(j).c_str(), matches, re))
       
    90         {
       
    91             string ms1(matches[1].first, matches[1].second);
       
    92             b_info.secureid = "0x"+ms1;
       
    93             break;
       
    94         }
       
    95     }
       
    96 
       
    97     // get vendor id
       
    98     for (unsigned int j=0; j<tempVector.size() && j<100; j++)
       
    99     {
       
   100         boost::regex re("^Vendor\\sID:\\s+(\\S+)");
       
   101         boost::cmatch matches;
       
   102         if (boost::regex_match(tempVector.at(j).c_str(), matches, re))
       
   103         {
       
   104             string ms1(matches[1].first, matches[1].second);
       
   105             b_info.vendorid = "0x"+ms1;
       
   106             break;
       
   107         }
       
   108     }
       
   109 
       
   110     // get capabilities
       
   111     for (unsigned int j=0; j<tempVector.size() && j<100; j++)
       
   112     {
       
   113         boost::regex re("^Capabilities:\\s+\\S+\\s+(\\S+)");
       
   114         boost::cmatch matches;
       
   115         if (boost::regex_match(tempVector.at(j).c_str(), matches, re))
       
   116         {
       
   117             string ms1(matches[1].first, matches[1].second);
       
   118             b_info.capabilities = Str2Int("0x"+ms1);
       
   119             break;
       
   120         }
       
   121     }
       
   122 
       
   123     // get min heap size
       
   124     for (unsigned int j=0; j<tempVector.size() && j<100; j++)
       
   125     {
       
   126         boost::regex re("^Min\\sHeap\\sSize:\\s+(\\S+)");
       
   127         boost::cmatch matches;
       
   128         if (boost::regex_match(tempVector.at(j).c_str(), matches, re))
       
   129         {
       
   130             string ms1(matches[1].first, matches[1].second);
       
   131             b_info.min_heap_size = Str2Int("0x"+ms1);
       
   132             break;
       
   133         }
       
   134     }
       
   135 
       
   136     // get max heap size
       
   137     for (unsigned int j=0; j<tempVector.size() && j<100; j++)
       
   138     {
       
   139         boost::regex re("^Max\\sHeap\\sSize:\\s+(\\S+)");
       
   140         boost::cmatch matches;
       
   141         if (boost::regex_match(tempVector.at(j).c_str(), matches, re))
       
   142         {
       
   143             string ms1(matches[1].first, matches[1].second);
       
   144             b_info.max_heap_size = Str2Int("0x"+ms1);
       
   145             break;
       
   146         }
       
   147     }
       
   148 
       
   149     // get stack size
       
   150     for (unsigned int j=0; j<tempVector.size() && j<100; j++)
       
   151     {
       
   152         boost::regex re("^Stack\\sSize:\\s+(\\S+)");
       
   153         boost::cmatch matches;
       
   154         if (boost::regex_match(tempVector.at(j).c_str(), matches, re))
       
   155         {
       
   156             string ms1(matches[1].first, matches[1].second);
       
   157             b_info.stack_size = Str2Int("0x"+ms1);
       
   158             break;
       
   159         }
       
   160     }
       
   161 
       
   162     // finally get the dependency information
       
   163     for (unsigned int j=0; j<tempVector.size(); j++)
       
   164     {
       
   165         // first find where the import table begins, example:
       
   166         // Offset of import address table (relative to code section): 00005660
       
   167         if (tempVector.at(j).find("Offset of import", 0) != string::npos)
       
   168         {
       
   169             // continue looping
       
   170             while (j<tempVector.size()-1)
       
   171             {
       
   172                 j++;
       
   173 
       
   174                 // now find denpendency entry, examples:
       
   175                 // 68 imports from euser{000a0000}[100039e5].dll
       
   176                 // 1 imports from COMMONENGINE[100058fe].DLL
       
   177                 // 3 imports from drtrvct2_2{000a0000}.dll
       
   178                 // 27 imports from libdbus-utils{000a0000}[20010154].dll
       
   179                 boost::regex re1("^(\\d+)\\simports\\sfrom\\s([\\w\\-]+)\\S*(\\.\\w+).*");
       
   180                 boost::cmatch matches1;
       
   181                 if (boost::regex_match(tempVector.at(j).c_str(), matches1, re1))
       
   182                 {
       
   183                     // match found
       
   184                     string ms1(matches1[1].first, matches1[1].second); // number in the beginning
       
   185                     string ms2(matches1[2].first, matches1[2].second); // first part of filename
       
   186                     string ms3(matches1[3].first, matches1[3].second); // extension of filename
       
   187 
       
   188                     unsigned int number_of_imports = Str2Int(ms1);
       
   189                     vector<import> imps; // imports
       
   190                     string filename = ms2+ms3;
       
   191 
       
   192                     // get position of the filename in import libaries
       
   193                     int lib_pos = -1;
       
   194                     for (unsigned int x=0; x<_all_import_library_infos.size(); x++)
       
   195                     {
       
   196                         if (StringICmpFileNamesWithoutExtension(_all_import_library_infos.at(x).filename, filename) == 0)
       
   197                         {
       
   198                             lib_pos = x;
       
   199                             break;
       
   200                         }
       
   201                     }
       
   202 
       
   203 
       
   204                     // read ordinal numbers
       
   205                     for (unsigned int k=0; k<number_of_imports; k++)
       
   206                     {
       
   207                         j++;
       
   208 
       
   209                         import imp;
       
   210                         imp.is_vtable = false;
       
   211                         imp.vtable_offset = 0;
       
   212 
       
   213                         string ordinal_data = tempVector.at(j);
       
   214                         TrimAll(ordinal_data);
       
   215 
       
   216                         // check if it's virtual data
       
   217                         string::size_type pos = ordinal_data.find(" offset by", 0);
       
   218 
       
   219                         if (pos == string::npos)
       
   220                         {
       
   221                             // regular entry, just get the ordinal number
       
   222                             imp.funcpos = Str2Int(ordinal_data);
       
   223                             imp.is_vtable = false;
       
   224                             imp.vtable_offset = 0;
       
   225                         }
       
   226                         else
       
   227                         {
       
   228                             // this is a virtual table entry
       
   229                             imp.funcpos = Str2Int(ordinal_data.substr(0, pos));
       
   230                             imp.is_vtable = true;
       
   231                             imp.vtable_offset = Str2Int(ordinal_data.substr(pos+11, ordinal_data.length()-pos-1));
       
   232                         }
       
   233 
       
   234                         // get the function name
       
   235                         if (lib_pos >= 0)
       
   236                         {
       
   237                             if (imp.funcpos-1 < _all_import_library_infos.at(lib_pos).symbol_table.size())
       
   238                                 imp.funcname = _all_import_library_infos.at(lib_pos).symbol_table.at(imp.funcpos-1);
       
   239                             else
       
   240                                 imp.funcname = "BC break: This ordinal position is not in the import library!";
       
   241                         }
       
   242                         else
       
   243                         {
       
   244                             imp.funcname = "Import library not found!";
       
   245                         }
       
   246 
       
   247                         // Checking for possible duplicate imported function ordinals.
       
   248                         import compare[] = { imp };
       
   249                         vector<import>::iterator it = find_first_of(imps.begin(), imps.end(), compare, compare+1, ImportFunctionsHasSameOrdinal);
       
   250                         if(it == imps.end())
       
   251                         {
       
   252                             // No duplicate detected. Appending ordinal data to the array.
       
   253                             imps.push_back(imp);
       
   254                         }
       
   255 
       
   256                     }
       
   257 
       
   258                     // append to the vector
       
   259 
       
   260                     dependency dep;
       
   261                     dep.filename = filename;
       
   262                     dep.imports = imps;
       
   263 
       
   264                     deps.push_back( dep );
       
   265 
       
   266                 }
       
   267             }
       
   268 
       
   269             break; //for (int j=0; j<tempVector.size(); j++)
       
   270         }
       
   271 
       
   272     } // for (int j=0; j<tempVector.size(); j++)
       
   273 
       
   274     // store the dependencies array
       
   275     b_info.dependencies = deps;
       
   276 
       
   277 }
       
   278 
       
   279 // ----------------------------------------------------------------------------------------------------------
       
   280 
       
   281 bool ImportFunctionsHasSameOrdinal(import imp1, import imp2)
       
   282 {
       
   283     return (imp1.funcpos == imp2.funcpos);
       
   284 }
       
   285 
       
   286 // ----------------------------------------------------------------------------------------------------------
       
   287 
       
   288 void GetSymbolTableWithNM(const string& nm_location, const string& lib_directory, const string& lib_name, vector<string>& symbol_table)
       
   289 {
       
   290     symbol_table.clear();
       
   291     vector<string> tempVector;
       
   292     vector<ordinal> ordinals;
       
   293 
       
   294     // execute nm
       
   295     string cmd = nm_location + " --demangle \"" + lib_directory + lib_name + "\"";
       
   296     ExecuteCommand(cmd, tempVector);
       
   297 
       
   298 
       
   299     // parse the results of the command
       
   300     for (unsigned int j=0; j<tempVector.size(); j++)
       
   301     {
       
   302         // first check if we have found the beginning of a block
       
   303 
       
   304         boost::cmatch matches1;
       
   305         boost::cmatch matches2;
       
   306         boost::cmatch matches3;
       
   307 
       
   308         bool match1 = false;
       
   309         bool match2 = false;
       
   310         bool match3 = false;
       
   311 
       
   312         // Symbian OS 6.1 LIB file, example: ds00001.o:
       
   313         boost::regex re1("^ds(\\d+)\\.o\\:");
       
   314         match1 = boost::regex_match(tempVector.at(j).c_str(), matches1, re1);
       
   315 
       
   316         if (!match1)
       
   317         {
       
   318             // Symbian OS 7.x-8.x LIB file, example: C:/DOCUME~1/mattlait/LOCALS~1/Temp/1/d1000s_00001.o:
       
   319             boost::regex re2("^\\S*s_(\\d+)\\.o\\:");
       
   320             match2 = boost::regex_match(tempVector.at(j).c_str(), matches2, re2);
       
   321 
       
   322             if (!match2)
       
   323             {
       
   324                 // Symbian OS 9.x LIB file, example: AGENTDIALOG{000a0000}-14.o:
       
   325                 boost::regex re3("^\\S*\\{000a0000\\}-(\\d+)\\.o\\:");
       
   326                 match3 = boost::regex_match(tempVector.at(j).c_str(), matches3, re3);
       
   327             }
       
   328         }
       
   329 
       
   330         if (match1 || match2 || match3)
       
   331         {
       
   332             // now get the ordinal number
       
   333             string ordNum;
       
   334 
       
   335             if (match1)
       
   336                 {
       
   337                 string ms(matches1[1].first, matches1[1].second);
       
   338                 ordNum = ms;
       
   339                 }
       
   340             else if (match2)
       
   341                 {
       
   342                 string ms(matches2[1].first, matches2[1].second);
       
   343                 ordNum = ms;
       
   344                 }
       
   345             else if (match3)
       
   346                 {
       
   347                 string ms(matches3[1].first, matches3[1].second);
       
   348                 ordNum = ms;
       
   349                 }
       
   350 
       
   351             // now start looking for the line with the export name
       
   352             // eg: 00000000 T CUserActivityManager::RunL(void)
       
   353             while (j<tempVector.size()-1)
       
   354             {
       
   355                 j++;
       
   356 
       
   357                 boost::regex re4("^\\d+\\sT\\s(.*)$");
       
   358                 boost::cmatch matches4;
       
   359 
       
   360                 if (boost::regex_match(tempVector.at(j).c_str(), matches4, re4))
       
   361                 {
       
   362                     // now we have a full entry
       
   363                     string ms(matches4[1].first, matches4[1].second);
       
   364 
       
   365                     // append to the ordinal list
       
   366                     ordinals.push_back(ordinal(Str2Int(ordNum), ms));
       
   367 
       
   368                     break;
       
   369                 }
       
   370             }
       
   371         } // (match1 || match2)
       
   372     } // for (int j=0; j<tempVector.size(); j++)
       
   373 
       
   374     // convert the ordinal list into a symbol table
       
   375     ConvertOrdinalListIntoSymbolTable(ordinals, symbol_table, lib_directory+lib_name);
       
   376 }
       
   377 
       
   378 // ----------------------------------------------------------------------------------------------------------
       
   379 
       
   380 void GetSymbolTableWithReadelf(const string& readelf_location, const string& cfilt_location, const string& lib_directory, const string& lib_name, vector<string>& symbol_table)
       
   381 {
       
   382     symbol_table.clear();
       
   383     vector<string> tempVector;
       
   384     vector<ordinal> ordinals;
       
   385 
       
   386     // execute readelf
       
   387     // note: 2>NUL is used here to redirect standard error output to NULL since readelf seems to output lots of unwanted warning messages
       
   388     string cmd = readelf_location + " -s -W \"" + lib_directory + lib_name + "\" " + CERR_TO_NULL;
       
   389     ExecuteCommand(cmd, tempVector);
       
   390 
       
   391 
       
   392     // parse the results of the command
       
   393     for (unsigned int j=0; j<tempVector.size(); j++)
       
   394     {
       
   395         boost::cmatch matches1;
       
   396 
       
   397         // example:
       
   398         //     1: 00000000     4 NOTYPE  GLOBAL DEFAULT    1 _ZN13CSpdiaControl10DrawShadowER9CWindowGcRK5TSize@@SpdCtrl{000a0000}[10005986].dll
       
   399         boost::regex re1("^\\s*(\\d+)\\:.+GLOBAL.+\\d+\\s+(.*)\\@\\@.*");
       
   400 
       
   401         if (boost::regex_match(tempVector.at(j).c_str(), matches1, re1))
       
   402         {
       
   403             // match found
       
   404             string ms1(matches1[1].first, matches1[1].second);
       
   405             string ms2(matches1[2].first, matches1[2].second);
       
   406 
       
   407             // append to the ordinal list
       
   408             ordinals.push_back(ordinal(Str2Int(ms1), ms2));
       
   409         }
       
   410 
       
   411     } // for (int j=0; j<tempVector.size(); j++)
       
   412 
       
   413     // convert the ordinal list into a symbol table
       
   414     ConvertOrdinalListIntoSymbolTable(ordinals, symbol_table, lib_directory+lib_name);
       
   415 
       
   416     // finally demangle all function names since it's not done in this case automatically
       
   417     DemangleOrdinalsInSymbolTable(cfilt_location, symbol_table);
       
   418 }
       
   419 
       
   420 // ----------------------------------------------------------------------------------------------------------
       
   421 
       
   422 void GetSymbolTableWithArmar(const string& armar_location, const string& cfilt_location, const string& lib_directory, const string& lib_name, vector<string>& symbol_table)
       
   423 {
       
   424     symbol_table.clear();
       
   425     vector<string> tempVector;
       
   426     vector<ordinal> ordinals;
       
   427 
       
   428     // execute armar
       
   429     string cmd = armar_location + " --zs \"" + lib_directory + lib_name + "\"";
       
   430     ExecuteCommand(cmd, tempVector);
       
   431 
       
   432     // parse the results of the command
       
   433     for (unsigned int j=0; j<tempVector.size(); j++)
       
   434     {
       
   435         // find the entries, example:
       
   436         // _ZN13TAgnWeeklyRptC1Ev from AGNMODEL{000a0000}-187.o at offset 158366
       
   437         boost::regex re1("(\\S*)\\s+from\\s.*-(\\d+)\\.o.*");
       
   438         boost::cmatch matches1;
       
   439 
       
   440         if (boost::regex_match(tempVector.at(j).c_str(), matches1, re1))
       
   441         {
       
   442             // match found
       
   443             string ms1(matches1[2].first, matches1[2].second);
       
   444             string ms2(matches1[1].first, matches1[1].second);
       
   445 
       
   446             // append to the ordinal list
       
   447             ordinals.push_back(ordinal(Str2Int(ms1), ms2));
       
   448         }
       
   449 
       
   450     } // for (int j=0; j<tempVector.size(); j++)
       
   451 
       
   452     // convert the ordinal list into a symbol table
       
   453     ConvertOrdinalListIntoSymbolTable(ordinals, symbol_table, lib_directory+lib_name);
       
   454 
       
   455     // finally demangle all function names since it's not done in this case automatically
       
   456     DemangleOrdinalsInSymbolTable(cfilt_location, symbol_table);
       
   457 }
       
   458 
       
   459 // ----------------------------------------------------------------------------------------------------------
       
   460 
       
   461 void GetSymbolTableWithFromelf(const string& fromelf_location, const string& cfilt_location, const string& lib_directory, const string& lib_name, vector<string>& symbol_table)
       
   462 {
       
   463     symbol_table.clear();
       
   464     vector<string> tempVector;
       
   465     vector<ordinal> ordinals;
       
   466 
       
   467     // execute fromelf
       
   468     string cmd = fromelf_location + " -s \"" + lib_directory + lib_name + "\"";
       
   469     ExecuteCommand(cmd, tempVector);
       
   470 
       
   471     // parse the results of the command
       
   472     for (unsigned int j=0; j<tempVector.size(); j++)
       
   473     {
       
   474         // first find the start of the symbol table
       
   475         // ** Section #5 '.version' (SHT_GNU_versym)
       
   476         boost::regex re1("^.*(SHT_GNU_versym).*");
       
   477         boost::cmatch matches1;
       
   478 
       
   479         if (boost::regex_match(tempVector.at(j).c_str(), matches1, re1))
       
   480         {
       
   481             //int previous_ordinal = 0;
       
   482 
       
   483             while (j<tempVector.size()-1)
       
   484             {
       
   485                 j++;
       
   486 
       
   487                 // now find the entries, examples:
       
   488                 //         7   _ZNK17CPbkContactEngine9FsSessionEv           2 PbkEng{000a0000}[101f4cce].dll
       
   489                 //         8   _ZN17CPbkContactEngine19CreateEmptyContactLEv
       
   490                 //                                                           2 PbkEng{000a0000}[101f4cce].dll
       
   491                 // notice that line can be spread to two lines so make sure we don't accidentally get a wrong line
       
   492 
       
   493                 // first parse out any unwanted lines
       
   494                 boost::regex re2("^\\s*\\d+\\s+\\S+\\.\\w+$");
       
   495                 boost::cmatch matches2;
       
   496                 if (boost::regex_match(tempVector.at(j).c_str(), matches2, re2))
       
   497                 {
       
   498                     continue;
       
   499                 }
       
   500 
       
   501                 // now it should be the wanted line
       
   502                 boost::regex re3("^\\s*(\\d+)\\s*(\\S*).*");
       
   503                 boost::cmatch matches3;
       
   504 
       
   505                 if (boost::regex_match(tempVector.at(j).c_str(), matches3, re3))
       
   506                 {
       
   507 
       
   508                     // match found
       
   509                     string ms1(matches3[1].first, matches3[1].second);
       
   510                     string ms2(matches3[2].first, matches3[2].second);
       
   511 
       
   512                     // append to the ordinal list
       
   513                     ordinals.push_back(ordinal(Str2Int(ms1), ms2));
       
   514                 }
       
   515 
       
   516             } //while (j<tempVector.size())
       
   517 
       
   518 
       
   519         } //if (boost::regex_match(tempVector.at(j).c_str(), matches1, re1))
       
   520 
       
   521     } // for (int j=0; j<tempVector.size(); j++)
       
   522 
       
   523     // convert the ordinal list into a symbol table
       
   524     ConvertOrdinalListIntoSymbolTable(ordinals, symbol_table, lib_directory+lib_name);
       
   525 
       
   526     // finally demangle all function names since it's not done in this case automatically
       
   527     DemangleOrdinalsInSymbolTable(cfilt_location, symbol_table);
       
   528 }
       
   529 
       
   530 // ----------------------------------------------------------------------------------------------------------
       
   531 
       
   532 void ConvertOrdinalListIntoSymbolTable(const vector<ordinal>& ordinals, vector<string>& symbol_table, const string& lib_path)
       
   533 {
       
   534     // remove any invalid ordinals from the list
       
   535     vector<ordinal> ordinalVectorCopy;
       
   536     ordinalVectorCopy.reserve(ordinals.size());
       
   537 
       
   538     for (unsigned int i=0; i<ordinals.size(); i++)
       
   539     {
       
   540         if (ordinals.at(i).funcpos <= 0 && ordinals.at(i).funcpos > 32000)
       
   541         {
       
   542             cerr << "Error: Invalid ordinal " << ordinals.at(i).funcname << " @ " << Int2Str(ordinals.at(i).funcpos) << endl;
       
   543         }
       
   544         else
       
   545         {
       
   546             ordinalVectorCopy.push_back(ordinals.at(i));
       
   547         }
       
   548     }
       
   549 
       
   550     // sort the ordinal list
       
   551     sort(ordinalVectorCopy.begin(), ordinalVectorCopy.end(), OrdinalCompare);
       
   552 
       
   553     // now check that there are no missing ordinals in the list
       
   554     unsigned int previous_ordnumber = 0;
       
   555     unsigned int current_ordnumber = 1;
       
   556     for (unsigned int i=0; i<ordinalVectorCopy.size(); i++)
       
   557     {
       
   558         // get the current ordinal number
       
   559         current_ordnumber = ordinalVectorCopy.at(i).funcpos;
       
   560 
       
   561         // the current ordinal number obviously should be one bigger than the previous one
       
   562         if ( current_ordnumber != previous_ordnumber+1 )
       
   563         {
       
   564             // append a dummy ordinal to the list
       
   565             ordinalVectorCopy.insert(ordinalVectorCopy.begin()+i, ordinal(i+1, "UnknownOrdinal-"+Int2Str(i+1)));
       
   566             current_ordnumber = i+1;
       
   567         }
       
   568 
       
   569         // remember the previous ordinal number
       
   570         previous_ordnumber = current_ordnumber;
       
   571 
       
   572         // if the ordinal list is corrupted, it may lead to an infinite loop
       
   573         if (i>25000)
       
   574         {
       
   575             cerr << endl << "Something went horribly wrong when trying to parse " << lib_path << ". Aborting." << endl;
       
   576             exit(10);
       
   577         }
       
   578     }
       
   579 
       
   580     // finally copy data from the ordinal list to the symbol table
       
   581     if (symbol_table.size() < ordinalVectorCopy.size())
       
   582     {
       
   583         symbol_table.reserve(ordinalVectorCopy.size());
       
   584     }
       
   585     for (unsigned int i=0; i<ordinalVectorCopy.size(); i++)
       
   586     {
       
   587         symbol_table.push_back( ordinalVectorCopy.at(i).funcname );
       
   588     }
       
   589 }
       
   590 
       
   591 // ----------------------------------------------------------------------------------------------------------
       
   592 
       
   593 void DemangleOrdinalsInSymbolTable(const string& cfilt_location, vector<string>& symbol_table)
       
   594 {
       
   595     ofstream f(_tempfile_location.c_str(), ios::trunc);
       
   596     if (f.is_open())
       
   597     {
       
   598         // create a temp file which contain all the function names
       
   599         for (unsigned int k=0; k<symbol_table.size(); k++)
       
   600         {
       
   601             f << symbol_table.at(k) << endl;
       
   602         }
       
   603         f.close();
       
   604 
       
   605         // execute cfilt
       
   606         vector<string> cfilt_result_set;
       
   607         string cmd = cfilt_location + " < " + _tempfile_location;
       
   608         ExecuteCommand(cmd, cfilt_result_set);
       
   609 
       
   610         // check that all functions exist and then replace the symbol table with demangled functions
       
   611         if (cfilt_result_set.size() == symbol_table.size())
       
   612         {
       
   613             symbol_table = cfilt_result_set;
       
   614         }
       
   615     }
       
   616     else
       
   617     {
       
   618         f.close();
       
   619     }
       
   620 }
       
   621 
       
   622 // ----------------------------------------------------------------------------------------------------------
       
   623 
       
   624 bool OrdinalCompare(const ordinal& left, const ordinal& right)
       
   625 {
       
   626     return left.funcpos < right.funcpos;
       
   627 }
       
   628 
       
   629 // ----------------------------------------------------------------------------------------------------------
       
   630 
       
   631