Symtab-lookup.C

Go to the documentation of this file.
00001 /*
00002  * See the dyninst/COPYRIGHT file for copyright information.
00003  * 
00004  * We provide the Paradyn Tools (below described as "Paradyn")
00005  * on an AS IS basis, and do not warrant its validity or performance.
00006  * We reserve the right to update, modify, or discontinue this
00007  * software at any time.  We shall have no obligation to supply such
00008  * updates or modifications or any other form of support to you.
00009  * 
00010  * By your use of Paradyn, you understand and agree that we (or any
00011  * other person or entity with proprietary rights in Paradyn) are
00012  * under no obligation to provide either maintenance services,
00013  * update services, notices of latent defects, or correction of
00014  * defects for Paradyn.
00015  * 
00016  * This library is free software; you can redistribute it and/or
00017  * modify it under the terms of the GNU Lesser General Public
00018  * License as published by the Free Software Foundation; either
00019  * version 2.1 of the License, or (at your option) any later version.
00020  * 
00021  * This library is distributed in the hope that it will be useful,
00022  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00024  * Lesser General Public License for more details.
00025  * 
00026  * You should have received a copy of the GNU Lesser General Public
00027  * License along with this library; if not, write to the Free Software
00028  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00029  */
00030 
00031 /* Lookup functions defined in class Symtab. Separated to reduce file size and classify. */
00032 
00033 
00034 
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <assert.h>
00038 #include <string.h>
00039 #include <vector>
00040 #include <algorithm>
00041 
00042 #include "common/h/Timer.h"
00043 #include "common/h/debugOstream.h"
00044 #include "common/h/serialize.h"
00045 #include "common/h/pathName.h"
00046 
00047 #include "Serialization.h"
00048 #include "Symtab.h"
00049 #include "Module.h"
00050 #include "Collections.h"
00051 #include "Function.h"
00052 #include "Variable.h"
00053 #include "annotations.h"
00054 
00055 #include "symtabAPI/src/Object.h"
00056 
00057 using namespace Dyninst;
00058 using namespace Dyninst::SymtabAPI;
00059 using namespace std;
00060 
00061 extern SymtabError serr;
00062 
00063 bool regexEquiv( const std::string &str,const std::string &them, bool checkCase );
00064 bool pattern_match( const char *p, const char *s, bool checkCase );
00065 
00066 std::vector<Symbol *> *Symtab::findSymbolByOffset(Offset o)
00067 {
00068     //Symbol *s = NULL;
00069     dyn_hash_map<Offset, std::vector<Symbol *> >::iterator iter;
00070     iter = symsByOffset.find(o);
00071     if (iter == symsByOffset.end()) return NULL;
00072     return &(iter->second);
00073 }
00074 
00075 bool Symtab::findSymbol(std::vector<Symbol *> &ret, const std::string& name,
00076                         Symbol::SymbolType sType, NameType nameType,
00077                         bool isRegex, bool checkCase, bool includeUndefined)
00078 {
00079 
00080     unsigned old_size = ret.size();
00081 
00082     std::vector<Symbol *> candidates;
00083 
00084     if (!isRegex) {
00085         // Easy case
00086         if (nameType & mangledName) {
00087            candidates.insert(candidates.end(), symsByMangledName[name].begin(), symsByMangledName[name].end());
00088            if (includeUndefined) candidates.insert(candidates.end(), 
00089                                                    undefDynSymsByMangledName[name].begin(), 
00090                                                    undefDynSymsByMangledName[name].end());
00091         }
00092         if (nameType & prettyName) {
00093            candidates.insert(candidates.end(), symsByPrettyName[name].begin(), symsByPrettyName[name].end());
00094            if (includeUndefined) candidates.insert(candidates.end(), 
00095                                                    undefDynSymsByPrettyName[name].begin(), 
00096                                                    undefDynSymsByPrettyName[name].end());
00097         }
00098         if (nameType & typedName) {
00099            candidates.insert(candidates.end(), symsByTypedName[name].begin(), symsByTypedName[name].end());
00100            if (includeUndefined) candidates.insert(candidates.end(), 
00101                                                    undefDynSymsByTypedName[name].begin(), 
00102                                                    undefDynSymsByTypedName[name].end());
00103         }
00104     }
00105     else {
00106         // Build the regex list of symbols
00107         // We need to iterate over every single symbol. Ugh.
00108        if (includeUndefined) {
00109           cerr << "Warning: regex search of undefined symbols is not supported" << endl;
00110        }
00111 
00112        for (unsigned i = 0; i < everyDefinedSymbol.size(); i++) {
00113           if (nameType & mangledName) {
00114              if (regexEquiv(name, everyDefinedSymbol[i]->getMangledName(), checkCase))
00115                 candidates.push_back(everyDefinedSymbol[i]);
00116 
00117           }
00118           if (nameType & prettyName) {
00119              if (regexEquiv(name, everyDefinedSymbol[i]->getPrettyName(), checkCase))
00120                 candidates.push_back(everyDefinedSymbol[i]);
00121           }
00122           if (nameType & typedName) {
00123              if (regexEquiv(name, everyDefinedSymbol[i]->getTypedName(), checkCase))
00124                 candidates.push_back(everyDefinedSymbol[i]);
00125           }
00126        }
00127     }
00128 
00129     std::set<Symbol *> matches;
00130 
00131     for (std::vector<Symbol *>::iterator iter = candidates.begin();
00132          iter != candidates.end(); ++iter) {
00133        if (sType == Symbol::ST_UNKNOWN ||
00134            sType == Symbol::ST_NOTYPE ||
00135            sType == (*iter)->getType()) {
00136           matches.insert(*iter);
00137        }
00138     }
00139     ret.insert(ret.end(), matches.begin(), matches.end());
00140 
00141     if (ret.size() == old_size) {
00142         serr = No_Such_Symbol;
00143         return false;
00144     }
00145     else {
00146         return true;
00147     }
00148 }
00149 
00150 bool Symtab::getAllSymbols(std::vector<Symbol *> &ret)
00151 {
00152     ret = everyDefinedSymbol;
00153 
00154     // add undefined symbols
00155     std::vector<Symbol *> temp;
00156     std::vector<Symbol *>::iterator it;
00157     getAllUndefinedSymbols(temp);
00158     for (it = temp.begin(); it != temp.end(); it++)
00159         ret.push_back(*it);
00160 
00161     if(ret.size() > 0)
00162         return true;
00163     serr = No_Such_Symbol;
00164     return false;
00165 }
00166 
00167 bool Symtab::getAllSymbolsByType(std::vector<Symbol *> &ret, Symbol::SymbolType sType)
00168 {
00169     if (sType == Symbol::ST_UNKNOWN)
00170         return getAllSymbols(ret);
00171 
00172     unsigned old_size = ret.size();
00173     // Filter by the given type
00174     for (unsigned i = 0; i < everyDefinedSymbol.size(); i++) {
00175         if (everyDefinedSymbol[i]->getType() == sType)
00176             ret.push_back(everyDefinedSymbol[i]);
00177     }
00178     // add undefined symbols
00179     std::vector<Symbol *> temp;
00180     getAllUndefinedSymbols(temp);
00181     for (unsigned i = 0; i < temp.size(); i++) {
00182         if (temp[i]->getType() == sType)
00183             ret.push_back(temp[i]);
00184     }
00185 
00186     if (ret.size() > old_size) {
00187         return true;
00188     }
00189     else {
00190         serr = No_Such_Symbol;
00191         return false;
00192     }
00193 }
00194 
00195 bool Symtab::getAllDefinedSymbols(std::vector<Symbol *> &ret)
00196 {
00197     ret = everyDefinedSymbol;
00198 
00199     if(ret.size() > 0)
00200         return true;
00201     serr = No_Such_Symbol;
00202     return false;
00203 }
00204  
00205 bool Symtab::getAllUndefinedSymbols(std::vector<Symbol *> &ret){
00206     unsigned size = ret.size();
00207     ret.insert(ret.end(), undefDynSyms.begin(), undefDynSyms.end());
00208     if(ret.size()>size)
00209         return true;
00210     serr = No_Such_Symbol;
00211     return false;
00212 }
00213 
00214 bool Symtab::findFuncByEntryOffset(Function *&ret, const Offset entry)
00215 {
00216     /* XXX
00217      *
00218      * When working with relocatable files, a symbol is not uniquely identified
00219      * by its offset; it is uniquely identified by its Region and its offset.
00220      * This discrepancy is not taken into account here.
00221      */
00222     if (funcsByOffset.find(entry) != funcsByOffset.end()) {
00223         ret = funcsByOffset[entry];
00224         return true;
00225     }
00226     serr = No_Such_Function;
00227     return false;
00228 }
00229 
00230 bool sort_by_func_ptr(const Function *a, const Function *b) {
00231     return a < b;
00232 }
00233 
00234 bool Symtab::findFunctionsByName(std::vector<Function *> &ret, const std::string name,
00235                                  NameType nameType, bool isRegex, bool checkCase) {
00236     std::vector<Symbol *> funcSyms;
00237     if (!findSymbol(funcSyms, name, Symbol::ST_FUNCTION, nameType, isRegex, checkCase)) {
00238       return false;
00239     }
00240     std::vector<Function *> unsortedFuncs;
00241     for (unsigned i = 0; i < funcSyms.size(); i++) 
00242     {
00243       if (doNotAggregate(funcSyms[i])) {
00244     continue;
00245       }
00246       if (!funcSyms[i]->getFunction())
00247         {
00248       fprintf(stderr, "%s[%d]:  WARNING:  internal inconsistency\n", FILE__, __LINE__);
00249       fprintf(stderr, "%s[%d]:  WARNING:  %s is %s a function\n", FILE__, __LINE__, name.c_str(), funcSyms[i]->isFunction() ? "" : "not");
00250       fprintf(stderr, "%s[%d]:  WARNING:  %s is %s a variable\n", FILE__, __LINE__, name.c_str(), funcSyms[i]->isVariable() ? "" : "not");
00251       continue;
00252         }
00253       unsortedFuncs.push_back(funcSyms[i]->getFunction());
00254     }
00255     std::sort(unsortedFuncs.begin(), unsortedFuncs.end(), sort_by_func_ptr);
00256     std::vector<Function *>::iterator endIter;
00257     endIter = std::unique(unsortedFuncs.begin(), unsortedFuncs.end());
00258     for (std::vector<Function *>::iterator iter = unsortedFuncs.begin();
00259          iter != endIter;
00260          iter++)
00261         ret.push_back(*iter);
00262 
00263     return true;
00264 }
00265 
00266 bool Symtab::getAllFunctions(std::vector<Function *> &ret) {
00267     ret = everyFunction;
00268     return (ret.size() > 0);
00269 }
00270 
00271 bool Symtab::findVariableByOffset(Variable *&ret, const Offset offset) {
00272 
00273     /* XXX
00274      *
00275      * See comment in findFuncByOffset about uniqueness of symbols in
00276      * relocatable files -- this discrepancy applies here as well.
00277      */
00278     if (varsByOffset.find(offset) != varsByOffset.end()) {
00279         ret = varsByOffset[offset];
00280         return true;
00281     }
00282     serr = No_Such_Variable;
00283     return false;
00284 }
00285 
00286 static bool sort_by_var_ptr(const Variable * a, const Variable *b) {
00287     return a < b;
00288 }
00289 
00290 bool Symtab::findVariablesByName(std::vector<Variable *> &ret, const std::string name,
00291                                  NameType nameType, bool isRegex, bool checkCase) {
00292     std::vector<Symbol *> varSyms;
00293     if (!findSymbol(varSyms, name, Symbol::ST_OBJECT, nameType, isRegex, checkCase))
00294         return false;
00295 
00296     std::vector<Variable *> unsortedVars;
00297     for (unsigned i = 0; i < varSyms.size(); i++) {
00298         if (doNotAggregate(varSyms[i])) continue;
00299         unsortedVars.push_back(varSyms[i]->getVariable());
00300     }
00301 
00302     std::sort(unsortedVars.begin(), unsortedVars.end(), sort_by_var_ptr);
00303     std::vector<Variable *>::iterator endIter;
00304     endIter = std::unique(unsortedVars.begin(), unsortedVars.end());
00305     for (std::vector<Variable *>::iterator iter = unsortedVars.begin();
00306          iter != endIter;
00307          iter++)
00308         ret.push_back(*iter);
00309 
00310     return true;
00311 }
00312 
00313 bool Symtab::getAllVariables(std::vector<Variable *> &ret) 
00314 {
00315     ret = everyVariable;
00316     return (ret.size() > 0);
00317 }
00318 
00319 bool Symtab::getAllModules(std::vector<Module *> &ret)
00320 {
00321     if (_mods.size() >0 )
00322     {
00323         ret = _mods;
00324         return true;
00325     }   
00326 
00327     serr = No_Such_Module;
00328     return false;
00329 }
00330 
00331 bool Symtab::findModuleByOffset(Module *&ret, Offset off)
00332 {   
00333    //  this should be a hash, really
00334    for (unsigned int i = 0; i < _mods.size(); ++i) 
00335    {
00336       Module *mod = _mods[i];
00337 
00338       if (off == mod->addr()) 
00339       {
00340           ret = mod;
00341           return true;
00342       }
00343    } 
00344    return false;
00345 }
00346 
00347 bool Symtab::findModuleByName(Module *&ret, const std::string name)
00348 {
00349    dyn_hash_map<std::string, Module *>::iterator loc;
00350    loc = modsByFullName.find(name);
00351 
00352    if (loc != modsByFullName.end()) 
00353    {
00354       ret = loc->second;
00355       return true;
00356    }
00357 
00358    std::string tmp = extract_pathname_tail(name);
00359 
00360    loc = modsByFileName.find(tmp);
00361 
00362    if (loc != modsByFileName.end()) 
00363    {
00364       ret = loc->second;
00365       return true;
00366    }
00367 
00368    serr = No_Such_Module;
00369    ret = NULL;
00370    return false;
00371 }
00372 
00373 bool Symtab::getAllRegions(std::vector<Region *>&ret)
00374 {
00375    if (regions_.size() > 0)
00376    {
00377       ret = regions_;
00378       return true;
00379    }
00380 
00381    return false;
00382 }
00383 
00384 bool Symtab::getCodeRegions(std::vector<Region *>&ret)
00385 {
00386    if (codeRegions_.size() > 0)
00387    {
00388       ret = codeRegions_;
00389       return true;
00390    }
00391 
00392    return false;
00393 }
00394 
00395 bool Symtab::getDataRegions(std::vector<Region *>&ret)
00396 {
00397    if (dataRegions_.size() > 0)
00398    {
00399       ret = dataRegions_;
00400       return true;
00401    }
00402    return false;
00403 }
00404 
00405 
00406 bool Symtab::getAllNewRegions(std::vector<Region *>&ret)
00407 {
00408    std::vector<Region *> *retp = NULL;
00409 
00410    if (!getAnnotation(retp, UserRegionsAnno))
00411    {
00412       return false;
00413    }
00414 
00415    if (!retp)
00416    {
00417       return false;
00418    }
00419 
00420    ret = *retp;
00421 
00422    return true;
00423 }
00424 
00425 bool Symtab::getAllExceptions(std::vector<ExceptionBlock *> &exceptions)
00426 {
00427    if (excpBlocks.size()>0)
00428    {
00429       exceptions = excpBlocks;
00430       return true;
00431    }    
00432 
00433    return false;
00434 }
00435 
00436 
00437 bool Symtab::findException(ExceptionBlock &excp, Offset addr)
00438 {
00439    for (unsigned i=0; i<excpBlocks.size(); i++)
00440    {
00441       if (excpBlocks[i]->contains(addr))
00442       {
00443          excp = *(excpBlocks[i]);
00444          return true;
00445       } 
00446    }
00447 
00448    return false;
00449 }
00450 
00451 /**
00452  * Returns true if the Address range addr -> addr+size contains
00453  * a catch block, with excp pointing to the appropriate block
00454  **/
00455 bool Symtab::findCatchBlock(ExceptionBlock &excp, Offset addr, unsigned size)
00456 {
00457     int min = 0;
00458     int max = excpBlocks.size();
00459     int cur = -1, last_cur;
00460 
00461     if (max == 0)
00462         return false;
00463 
00464     //Binary search through vector for address
00465     while (true)
00466     {
00467         last_cur = cur;
00468         cur = (min + max) / 2;
00469     
00470         if (last_cur == cur)
00471             return false;
00472 
00473         Offset curAddr = excpBlocks[cur]->catchStart();
00474         if ((curAddr <= addr && curAddr+size > addr) ||
00475             (size == 0 && curAddr == addr))
00476         {
00477             //Found it
00478             excp = *(excpBlocks[cur]);
00479             return true;
00480         }
00481         if (addr < curAddr)
00482             max = cur;
00483         else if (addr > curAddr)
00484             min = cur;
00485     }
00486 }
00487  
00488 bool Symtab::findRegionByEntry(Region *&ret, const Offset offset)
00489 {
00490     if(regionsByEntryAddr.find(offset) != regionsByEntryAddr.end())
00491     {
00492         ret = regionsByEntryAddr[offset];
00493         return true;
00494     }
00495     serr = No_Such_Region;
00496     return false;
00497 }
00498 
00499 /* Similar to binary search in isCode with the exception that here we
00500  * search to the end of regions without regards to whether they have
00501  * corresponding raw data on disk, and searches all regions.  
00502  *
00503  * regions_ elements that start at address 0 may overlap, ELF binaries
00504  * have 0 address iff they are not loadable, but xcoff places loadable
00505  * sections at address 0, including .text and .data
00506  */
00507 Region *Symtab::findEnclosingRegion(const Offset where)
00508 {
00509     int first = 0; 
00510     int last = regions_.size() - 1;
00511     while (last >= first) {
00512         Region *curreg = regions_[(first + last) / 2];
00513         if (where >= curreg->getMemOffset()
00514             && where < (curreg->getMemOffset()
00515                         + curreg->getMemSize())) {
00516             return curreg;
00517         }
00518         else if (where < curreg->getMemOffset()) {
00519             last = ((first + last) / 2) - 1;
00520         }
00521         else {/* where >= (cursec->getSecAddr()
00522                            + cursec->getSecSize()) */
00523             first = ((first + last) / 2) + 1;
00524         }
00525     }
00526     return NULL;
00527 }
00528 
00529 bool Symtab::findRegion(Region *&ret, const std::string secName)
00530 {
00531     for(unsigned index=0;index<regions_.size();index++)
00532     {
00533         if(regions_[index]->getRegionName() == secName)
00534         {
00535             ret = regions_[index];
00536             return true;
00537         }
00538     }
00539     serr = No_Such_Region;
00540     return false;
00541 }
00542 
00543 
00544 bool Symtab::findRegion(Region *&ret, const Offset addr, const unsigned long size)
00545 {
00546    ret = NULL;
00547    for(unsigned index=0;index<regions_.size();index++) {
00548       if(regions_[index]->getMemOffset() == addr && regions_[index]->getMemSize() == size) {
00549          if (ret) {
00550 #if 0
00551             cerr << "Error: region inconsistency" << endl;
00552             cerr << "\t" << ret->getRegionName() << " @ "
00553                  << hex << ret->getMemOffset() << "/" << ret->getMemSize() 
00554          << ", type " << Region::regionType2Str(ret->getRegionType()) << endl;
00555             cerr << "\t" << regions_[index]->getRegionName() << " @ "
00556                  << regions_[index]->getMemOffset() << "/" << regions_[index]->getMemSize() 
00557          << ", type " << Region::regionType2Str(regions_[index]->getRegionType()) << endl;
00558 #endif
00559        assert((addr == 0) ||
00560           (ret->getRegionType() == Region::RT_BSS) ||
00561           (regions_[index]->getRegionType() == Region::RT_BSS));
00562 
00563         // Probably don't want bss
00564         if (ret->getRegionType() == Region::RT_BSS) {
00565           ret = regions_[index];
00566         }
00567 
00568 
00569             serr = Multiple_Region_Matches;
00570             return false;
00571          }
00572          ret = regions_[index];
00573       }
00574    }
00575    if (ret) return true;
00576    serr = No_Such_Region;
00577    return false;
00578 }
00579 
00580 ///////////////////////// REGEX //////////////////////
00581 
00582 // Use POSIX regular expression pattern matching to check if std::string s matches
00583 // the pattern in this std::string
00584 bool regexEquiv( const std::string &str,const std::string &them, bool checkCase ) 
00585 {
00586    const char *str_ = str.c_str();
00587    const char *s = them.c_str();
00588    // Would this work under NT?  I don't know.
00589    //#if !defined(os_windows)
00590     return pattern_match(str_, s, checkCase);
00591 
00592 }
00593 
00594 // This function will match string s against pattern p.
00595 // Asterisks match 0 or more wild characters, and a question
00596 // mark matches exactly one wild character.  In other words,
00597 // the asterisk is the equivalent of the regex ".*" and the
00598 // question mark is the equivalent of "."
00599 
00600 bool
00601 pattern_match( const char *p, const char *s, bool checkCase ) {
00602    //const char *p = ptrn;
00603    //char *s = str;
00604 
00605     while ( true ) {
00606         // If at the end of the pattern, it matches if also at the end of the string
00607         if( *p == '\0' )
00608             return ( *s == '\0' );
00609 
00610         // Process a '*'
00611         if( *p == MULTIPLE_WILDCARD_CHARACTER ) {
00612             ++p;
00613 
00614             // If at the end of the pattern, it matches
00615             if( *p == '\0' )
00616                 return true;
00617 
00618             // Try to match the remaining pattern for each remaining substring of s
00619             for(; *s != '\0'; ++s )
00620                 if( pattern_match( p, s, checkCase ) )
00621                     return true;
00622             // Failed
00623             return false;
00624         }
00625 
00626         // If at the end of the string (and at this point, not of the pattern), it fails
00627         if( *s == '\0' )
00628             return false;
00629 
00630         // Check if this character matches
00631         bool matchChar = false;
00632         if( *p == WILDCARD_CHARACTER || *p == *s )
00633             matchChar = true;
00634         else if( !checkCase ) {
00635             if( *p >= 'A' && *p <= 'Z' && *s == ( *p + ( 'a' - 'A' ) ) )
00636                 matchChar = true;
00637             else if( *p >= 'a' && *p <= 'z' && *s == ( *p - ( 'a' - 'A' ) ) )
00638                 matchChar = true;
00639         }
00640 
00641         if( matchChar ) {
00642             ++p;
00643             ++s;
00644             continue;
00645         }
00646 
00647         // Did not match
00648         return false;
00649     }
00650 }
00651 
00652 struct Dyninst::SymtabAPI::SymbolCompareByAddr
00653 {
00654     bool operator()(Function *a, Function *b)
00655     {
00656        return (a->offset_ < b->offset_);
00657     }
00658 };
00659 
00660 bool Symtab::getContainingFunction(Offset offset, Function* &func)
00661 {
00662    if (!isCode(offset)) {
00663       return false;
00664    }
00665    if (everyFunction.size() && !sorted_everyFunction)
00666    {
00667       std::sort(everyFunction.begin(), everyFunction.end(),
00668                 SymbolCompareByAddr());
00669       sorted_everyFunction = true;
00670    }
00671    
00672    unsigned low = 0;
00673    unsigned high = everyFunction.size();
00674    unsigned last_mid = high+1;
00675    unsigned mid;
00676    if (!high) return false;
00677    for (;;)
00678    {
00679       mid = (low + high) / 2;
00680       if (last_mid == mid)
00681          break;
00682       last_mid = mid;
00683       Offset cur = everyFunction[mid]->getOffset();
00684       if (cur > offset) {
00685          high = mid;
00686          continue;
00687       }
00688       if (cur < offset) {
00689          low = mid;
00690          continue;
00691       }
00692       if (cur == offset) {
00693          func = everyFunction[mid];
00694          return true;
00695       }
00696    }
00697 
00698    if ((everyFunction[low]->getOffset() <= offset) &&
00699        ((low+1 == everyFunction.size()) || 
00700         (everyFunction[low+1]->getOffset() > offset)))
00701    {
00702          func = everyFunction[low];
00703          return true;
00704    }
00705    return false;
00706 }
00707 
00708 Module *Symtab::getDefaultModule() {
00709     Module *mod = NULL;
00710     // TODO: automatically pick the module that contains this address?
00711     // For now, DEFAULT_MODULE or (if we have only one) that one.
00712     if (_mods.size() == 1)
00713         return _mods[0];
00714     else {
00715         if (!findModuleByName(mod, "DEFAULT_MODULE"))
00716             return NULL;
00717     }
00718     return mod;
00719 }
00720 
00721 unsigned Function::getSize() {
00722    if (functionSize_)
00723       return functionSize_;
00724    for (unsigned i=0; i<symbols_.size(); i++) {
00725       if (symbols_[i]->getSize()) { 
00726          functionSize_ = symbols_[i]->getSize();;
00727          return functionSize_;
00728       }
00729    }
00730 
00731    Symtab *symtab = getFirstSymbol()->getSymtab();
00732    if (symtab->everyFunction.size() && !symtab->sorted_everyFunction)
00733    {
00734       std::sort(symtab->everyFunction.begin(), symtab->everyFunction.end(),
00735                 SymbolCompareByAddr());
00736       symtab->sorted_everyFunction = true;
00737    }
00738 
00739    Offset offset = getOffset();
00740    unsigned low = 0;
00741    unsigned high = symtab->everyFunction.size();
00742    unsigned last_mid = high+1;
00743    unsigned mid;
00744    for (;;)
00745    {
00746       mid = (low + high) / 2;
00747       if (last_mid == mid)
00748          return 0;
00749       last_mid = mid;
00750       Offset cur = symtab->everyFunction[mid]->getOffset();
00751       if (cur > offset) {
00752          high = mid;
00753          continue;
00754       }
00755       if (cur < offset) {
00756          low = mid;
00757          continue;
00758       }
00759       if (cur == offset) {
00760          if (mid + 1 >= symtab->everyFunction.size())
00761             return 0;
00762          Function *next_func = symtab->everyFunction[mid+1];
00763          functionSize_ = next_func->getOffset() - getOffset();
00764          return functionSize_;
00765       }
00766    }
00767 }
00768 
00769 Dyninst::Offset Symtab::fileToDiskOffset(Dyninst::Offset fileOffset) const {
00770    for (unsigned j = 0; j < regions_.size(); ++j) {
00771       if (regions_[j]->getFileOffset() <= fileOffset &&
00772           ((regions_[j]->getFileOffset() + regions_[j]->getDiskSize()) > fileOffset)) {
00773          return fileOffset - regions_[j]->getFileOffset() + regions_[j]->getDiskOffset();
00774       }
00775    }
00776    return (Dyninst::Offset) -1;
00777 }
00778 
00779 Dyninst::Offset Symtab::fileToMemOffset(Dyninst::Offset fileOffset) const {
00780    for (unsigned j = 0; j < regions_.size(); ++j) {
00781       if (regions_[j]->getFileOffset() <= fileOffset &&
00782           ((regions_[j]->getFileOffset() + regions_[j]->getDiskSize()) > fileOffset)) {
00783          return fileOffset - regions_[j]->getFileOffset() + regions_[j]->getMemOffset();
00784       }
00785    }
00786    return (Dyninst::Offset) -1;
00787 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1