AddrLookup.C
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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> &)
00076 {
00077 assert(0);
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 }