2 * See the dyninst/COPYRIGHT file for copyright information.
4 * We provide the Paradyn Tools (below described as "Paradyn")
5 * on an AS IS basis, and do not warrant its validity or performance.
6 * We reserve the right to update, modify, or discontinue this
7 * software at any time. We shall have no obligation to supply such
8 * updates or modifications or any other form of support to you.
10 * By your use of Paradyn, you understand and agree that we (or any
11 * other person or entity with proprietary rights in Paradyn) are
12 * under no obligation to provide either maintenance services,
13 * update services, notices of latent defects, or correction of
14 * defects for Paradyn.
16 * This library is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU Lesser General Public
18 * License as published by the Free Software Foundation; either
19 * version 2.1 of the License, or (at your option) any later version.
21 * This library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * Lesser General Public License for more details.
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
31 #include "symtabAPI/h/Symtab.h"
32 #include "symtabAPI/h/Symbol.h"
33 #include "symtabAPI/h/AddrLookup.h"
34 #include "symtabAPI/h/SymtabReader.h"
36 #include "common/h/addrtranslate.h"
43 using namespace Dyninst;
44 using namespace Dyninst::SymtabAPI;
47 dyn_hash_map<string, std::vector<Symbol *> > AddressLookup::syms;
49 AddressLookup *AddressLookup::createAddressLookup(PID pid, ProcessReader *reader)
51 AddressTranslate *trans = AddressTranslate::createAddressTranslator(pid, reader, getSymtabReaderFactory());
55 AddressLookup *ar = new AddressLookup(trans);
62 AddressLookup *AddressLookup::createAddressLookup(ProcessReader *reader)
64 AddressTranslate *trans = AddressTranslate::createAddressTranslator(reader, getSymtabReaderFactory());
68 AddressLookup *ar = new AddressLookup(trans);
75 AddressLookup *AddressLookup::createAddressLookup(const std::vector<LoadedLibrary> &/*name_addrs*/)
77 assert(0); //TODO Implement
81 bool AddressLookup::getAddress(Symtab *tab, Offset off, Address &addr)
83 LoadedLib *ll = getLoadedLib(tab);
86 addr = ll->offToAddress(off);
90 bool AddressLookup::getAddress(Symtab *tab, Symbol *sym, Address &addr)
92 LoadedLib *ll = getLoadedLib(tab);
95 addr = symToAddress(ll, sym);
99 bool sort_by_addr(const Symbol* a, const Symbol* b)
101 return a->getOffset() < b->getOffset();
104 vector<Symbol *> *AddressLookup::getSymsVector(LoadedLib *lib)
106 string str = lib->getName();
107 if (syms.find(str) != syms.end()) {
111 Symtab *tab = getSymtab(lib);
117 vector<Symbol *> &symbols = syms[str];
118 tab->getAllSymbolsByType(symbols, Symbol::ST_UNKNOWN);
119 std::sort(symbols.begin(), symbols.end(), sort_by_addr);
124 bool AddressLookup::getOffset(Address addr, Symtab* &tab, Offset &off)
129 result = translator->getLibAtAddress(addr, lib);
130 if (!result || !lib) {
134 off = lib->addrToOffset(addr);
135 tab = getSymtab(lib);
139 bool AddressLookup::getOffset(Address addr, LoadedLibrary &ll, Offset &off)
144 result = translator->getLibAtAddress(addr, lib);
145 if (!result || !lib) {
149 off = lib->addrToOffset(addr);
150 ll.name = lib->getName();
151 ll.codeAddr = lib->getCodeLoadAddr();
152 ll.dataAddr = lib->getDataLoadAddr();
156 bool AddressLookup::getSymbol(Address addr, Symbol* &sym, Symtab* &tab, bool close)
161 result = translator->getLibAtAddress(addr, lib);
162 if (!result || !lib) {
166 tab = getSymtab(lib);
167 vector<Symbol *> *symbols = getSymsVector(lib);
173 unsigned max = symbols->size();
174 unsigned mid, last_mid;
177 Symbol *closest = NULL;
178 unsigned long closest_dist = 0;
180 addr -= lib->addrToOffset(addr);
183 mid = (min + max) / 2;
188 Offset cur_off = (*symbols)[mid]->getOffset();
190 if (addr == cur_off) {
191 sym = (*symbols)[mid];
194 if (addr < cur_off) {
198 if (close && (!closest || closest_dist > (cur_off - addr)))
200 closest_dist = cur_off - addr;
201 closest = (*symbols)[mid];
203 if (addr > cur_off) {
209 if (close && closest)
211 sym = (*symbols)[mid];
218 bool AddressLookup::getAllSymtabs(std::vector<Symtab *> &tabs)
220 vector<LoadedLib *> libs;
221 bool result = translator->getLibs(libs);
225 for (unsigned i=0; i<libs.size(); i++)
227 Symtab *symt = getSymtab(libs[i]);
229 tabs.push_back(symt);
235 bool AddressLookup::getLoadAddress(Symtab* sym, Address &load_addr)
237 LoadedLib *ll = getLoadedLib(sym);
240 load_addr = ll->getCodeLoadAddr();
244 bool AddressLookup::getDataLoadAddress(Symtab* sym, Address &load_addr)
246 LoadedLib *ll = getLoadedLib(sym);
249 load_addr = ll->getDataLoadAddr();
253 bool AddressLookup::getLoadAddresses(std::vector<LoadedLibrary> &name_addrs)
255 vector<LoadedLib *> libs;
256 bool result = translator->getLibs(libs);
260 for (unsigned i=0; i<libs.size(); i++)
263 libs[i]->getOutputs(l.name, l.codeAddr, l.dataAddr);
264 name_addrs.push_back(l);
270 Address AddressLookup::getLibraryTrapAddrSysV()
272 return translator->getLibraryTrapAddrSysV();
275 AddressLookup::AddressLookup(AddressTranslate *at) :
280 AddressLookup::~AddressLookup()
284 bool AddressLookup::refresh()
286 return translator->refresh();
289 bool AddressLookup::getExecutable(LoadedLibrary &lib)
291 LoadedLib *llib = translator->getExecutable();
294 llib->getOutputs(lib.name, lib.codeAddr, lib.dataAddr);
298 Dyninst::Address AddressLookup::symToAddress(LoadedLib *ll, Symbol *sym)
300 return ll->getCodeLoadAddr() + sym->getOffset();
303 LoadedLib *AddressLookup::getLoadedLib(Symtab *sym)
305 std::map<Symtab *, LoadedLib *>::iterator i = sym_to_ll.find(sym);
306 if (i != sym_to_ll.end()) {
310 vector<LoadedLib *> libs;
311 translator->getLibs(libs);
312 for (vector<LoadedLib *>::iterator i = libs.begin(); i != libs.end(); i++) {
314 if (sym->file() == ll->getName() ||
315 sym->name() == ll->getName())
325 Symtab *AddressLookup::getSymtab(LoadedLib *ll)
327 std::map<LoadedLib *, Symtab *>::iterator i = ll_to_sym.find(ll);
328 if (i != ll_to_sym.end()) {
333 bool result = Symtab::openFile(sym, ll->getName());