AddrLookup.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 #include "symtabAPI/h/Symtab.h"
00032 #include "symtabAPI/h/Symbol.h"
00033 #include "symtabAPI/h/AddrLookup.h"
00034 #include "symtabAPI/h/SymtabReader.h"
00035 
00036 #include "common/h/addrtranslate.h"
00037 
00038 
00039 #include <vector>
00040 #include <algorithm>
00041 #include <string>
00042 
00043 using namespace Dyninst;
00044 using namespace Dyninst::SymtabAPI;
00045 using namespace std;
00046 
00047 dyn_hash_map<string, std::vector<Symbol *> > AddressLookup::syms;
00048 
00049 AddressLookup *AddressLookup::createAddressLookup(PID pid, ProcessReader *reader)
00050 {
00051    AddressTranslate *trans = AddressTranslate::createAddressTranslator(pid, reader, getSymtabReaderFactory());
00052 
00053    if (!trans)
00054       return NULL;
00055    AddressLookup *ar = new AddressLookup(trans);
00056 
00057    if (!ar)
00058       return NULL;
00059    return ar;
00060 }
00061 
00062 AddressLookup *AddressLookup::createAddressLookup(ProcessReader *reader)
00063 {
00064    AddressTranslate *trans = AddressTranslate::createAddressTranslator(reader, getSymtabReaderFactory());
00065    if (!trans) {
00066       return NULL;
00067    }
00068    AddressLookup *ar = new AddressLookup(trans);
00069    if (!ar) {
00070       return NULL;
00071    }
00072    return ar;
00073 }
00074 
00075 AddressLookup *AddressLookup::createAddressLookup(const std::vector<LoadedLibrary> &/*name_addrs*/)
00076 {
00077    assert(0); //TODO Implement
00078    return NULL;
00079 }
00080 
00081 bool AddressLookup::getAddress(Symtab *tab, Offset off, Address &addr)
00082 {
00083    LoadedLib *ll = getLoadedLib(tab);
00084    if (!ll)
00085       return false;
00086    addr = ll->offToAddress(off);
00087    return true;
00088 }
00089 
00090 bool AddressLookup::getAddress(Symtab *tab, Symbol *sym, Address &addr)
00091 {
00092    LoadedLib *ll = getLoadedLib(tab);
00093    if (!ll)
00094       return false;
00095    addr = symToAddress(ll, sym);
00096    return true;
00097 }
00098 
00099 bool sort_by_addr(const Symbol* a, const Symbol* b)
00100 {
00101    return a->getOffset() < b->getOffset();
00102 }
00103 
00104 vector<Symbol *> *AddressLookup::getSymsVector(LoadedLib *lib)
00105 {
00106    string str = lib->getName();
00107    if (syms.find(str) != syms.end()) {
00108       return &(syms[str]);
00109    }
00110    
00111    Symtab *tab = getSymtab(lib);
00112    
00113    if (!tab) {
00114       return NULL;
00115    }
00116 
00117    vector<Symbol *> &symbols = syms[str];
00118    tab->getAllSymbolsByType(symbols, Symbol::ST_UNKNOWN);
00119    std::sort(symbols.begin(), symbols.end(), sort_by_addr);
00120 
00121    return &(syms[str]);
00122 }
00123 
00124 bool AddressLookup::getOffset(Address addr, Symtab* &tab, Offset &off)
00125 {
00126    LoadedLib *lib;
00127    bool result;
00128 
00129    result = translator->getLibAtAddress(addr, lib);
00130    if (!result || !lib) {
00131       return false;
00132    }
00133 
00134    off = lib->addrToOffset(addr);
00135    tab = getSymtab(lib);
00136    return true;
00137 }
00138 
00139 bool AddressLookup::getOffset(Address addr, LoadedLibrary &ll, Offset &off)
00140 {
00141    LoadedLib *lib;
00142    bool result;
00143 
00144    result = translator->getLibAtAddress(addr, lib);
00145    if (!result || !lib) {
00146       return false;
00147    }
00148 
00149    off = lib->addrToOffset(addr);
00150    ll.name = lib->getName();
00151    ll.codeAddr = lib->getCodeLoadAddr();
00152    ll.dataAddr = lib->getDataLoadAddr();
00153    return true;
00154 }
00155 
00156 bool AddressLookup::getSymbol(Address addr, Symbol* &sym, Symtab* &tab, bool close)
00157 {
00158    LoadedLib *lib;
00159    bool result;
00160 
00161    result = translator->getLibAtAddress(addr, lib);
00162    if (!result || !lib) {
00163       return false;
00164    }
00165 
00166    tab = getSymtab(lib);
00167    vector<Symbol *> *symbols = getSymsVector(lib);
00168    if (!symbols) {
00169       return false;
00170    }
00171    
00172    unsigned min = 0;
00173    unsigned max = symbols->size();
00174    unsigned mid, last_mid;
00175    last_mid = max+1;
00176 
00177    Symbol *closest = NULL;
00178    unsigned long closest_dist = 0;
00179 
00180    addr -= lib->addrToOffset(addr);
00181 
00182    for (;;) {
00183       mid = (min + max) / 2;
00184       if (mid == last_mid)
00185          break;
00186       last_mid = mid;
00187       
00188       Offset cur_off = (*symbols)[mid]->getOffset();
00189       
00190       if (addr == cur_off) {
00191          sym = (*symbols)[mid];
00192          return true;
00193       }
00194       if (addr < cur_off) {
00195          max = mid;
00196          continue;
00197       }
00198       if (close && (!closest || closest_dist > (cur_off - addr)))
00199       {
00200          closest_dist = cur_off - addr;
00201          closest = (*symbols)[mid];
00202       }
00203       if (addr > cur_off) {
00204          min = mid;
00205          continue;
00206       }
00207    }
00208 
00209    if (close && closest)
00210    {
00211       sym = (*symbols)[mid];
00212       return true;
00213    }
00214 
00215    return false;
00216 }
00217 
00218 bool AddressLookup::getAllSymtabs(std::vector<Symtab *> &tabs)
00219 {
00220    vector<LoadedLib *> libs;
00221    bool result = translator->getLibs(libs);
00222    if (!result)
00223       return false;
00224 
00225    for (unsigned i=0; i<libs.size(); i++)
00226    {
00227       Symtab *symt = getSymtab(libs[i]);
00228       if (symt)
00229          tabs.push_back(symt);
00230    }
00231 
00232    return true;
00233 }
00234 
00235 bool AddressLookup::getLoadAddress(Symtab* sym, Address &load_addr)
00236 {
00237    LoadedLib *ll = getLoadedLib(sym);
00238    if (!ll)
00239       return false;
00240    load_addr = ll->getCodeLoadAddr();
00241    return true;
00242 }
00243 
00244 bool AddressLookup::getDataLoadAddress(Symtab* sym, Address &load_addr)
00245 {
00246    LoadedLib *ll = getLoadedLib(sym);
00247    if (!ll)
00248       return false;
00249    load_addr = ll->getDataLoadAddr();
00250    return true;
00251 }
00252 
00253 bool AddressLookup::getLoadAddresses(std::vector<LoadedLibrary> &name_addrs)
00254 {
00255    vector<LoadedLib *> libs;
00256    bool result = translator->getLibs(libs);
00257    if (!result)
00258       return false;
00259 
00260    for (unsigned i=0; i<libs.size(); i++)
00261    {
00262       LoadedLibrary l;
00263       libs[i]->getOutputs(l.name, l.codeAddr, l.dataAddr);
00264       name_addrs.push_back(l);
00265    }
00266 
00267    return true;
00268 }
00269 
00270 Address AddressLookup::getLibraryTrapAddrSysV()
00271 {
00272    return translator->getLibraryTrapAddrSysV();
00273 }
00274 
00275 AddressLookup::AddressLookup(AddressTranslate *at) :
00276    translator(at)
00277 {
00278 }
00279 
00280 AddressLookup::~AddressLookup()
00281 {
00282 }
00283 
00284 bool AddressLookup::refresh()
00285 {
00286    return translator->refresh();
00287 }
00288 
00289 bool AddressLookup::getExecutable(LoadedLibrary &lib)
00290 {
00291    LoadedLib *llib = translator->getExecutable();
00292    if (!llib)
00293       return false;
00294    llib->getOutputs(lib.name, lib.codeAddr, lib.dataAddr);
00295    return true;
00296 }
00297 
00298 Dyninst::Address AddressLookup::symToAddress(LoadedLib *ll, Symbol *sym)
00299 {
00300    return ll->getCodeLoadAddr() + sym->getOffset();
00301 }
00302 
00303 LoadedLib *AddressLookup::getLoadedLib(Symtab *sym)
00304 {
00305    std::map<Symtab *, LoadedLib *>::iterator i = sym_to_ll.find(sym);
00306    if (i != sym_to_ll.end()) {
00307       return i->second;
00308    }
00309    
00310    vector<LoadedLib *> libs;
00311    translator->getLibs(libs);
00312    for (vector<LoadedLib *>::iterator i = libs.begin(); i != libs.end(); i++) {
00313       LoadedLib *ll = *i;
00314       if (sym->file() == ll->getName() || 
00315           sym->name() == ll->getName())
00316       {
00317          ll_to_sym[ll] = sym;
00318          sym_to_ll[sym] = ll;
00319          return ll;
00320       }
00321    }
00322    return NULL;
00323 }
00324 
00325 Symtab *AddressLookup::getSymtab(LoadedLib *ll)
00326 {
00327    std::map<LoadedLib *, Symtab *>::iterator i = ll_to_sym.find(ll);
00328    if (i != ll_to_sym.end()) {
00329       return i->second;
00330    }
00331    
00332    Symtab *sym;
00333    bool result = Symtab::openFile(sym, ll->getName());
00334    if (!result) {
00335       return NULL;
00336    }
00337    ll_to_sym[ll] = sym;
00338    sym_to_ll[sym] = ll;
00339    return sym;
00340 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 12 Jul 2013 for SymtabAPI by  doxygen 1.6.1