Compile fix after removing deprecated SymtabAPI methods.
[dyninst.git] / symtabAPI / src / AddrLookup.C
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  * 
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.
9  * 
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.
15  * 
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.
20  * 
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.
25  * 
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
29  */
30
31 #include "symtabAPI/h/Symtab.h"
32 #include "symtabAPI/h/Symbol.h"
33 #include "symtabAPI/h/AddrLookup.h"
34 #include "symtabAPI/h/SymtabReader.h"
35
36 #include "common/h/addrtranslate.h"
37
38
39 #include <vector>
40 #include <algorithm>
41 #include <string>
42
43 using namespace Dyninst;
44 using namespace Dyninst::SymtabAPI;
45 using namespace std;
46
47 dyn_hash_map<string, std::vector<Symbol *> > AddressLookup::syms;
48
49 AddressLookup *AddressLookup::createAddressLookup(PID pid, ProcessReader *reader)
50 {
51    AddressTranslate *trans = AddressTranslate::createAddressTranslator(pid, reader, getSymtabReaderFactory());
52
53    if (!trans)
54       return NULL;
55    AddressLookup *ar = new AddressLookup(trans);
56
57    if (!ar)
58       return NULL;
59    return ar;
60 }
61
62 AddressLookup *AddressLookup::createAddressLookup(ProcessReader *reader)
63 {
64    AddressTranslate *trans = AddressTranslate::createAddressTranslator(reader, getSymtabReaderFactory());
65    if (!trans) {
66       return NULL;
67    }
68    AddressLookup *ar = new AddressLookup(trans);
69    if (!ar) {
70       return NULL;
71    }
72    return ar;
73 }
74
75 AddressLookup *AddressLookup::createAddressLookup(const std::vector<LoadedLibrary> &/*name_addrs*/)
76 {
77    assert(0); //TODO Implement
78    return NULL;
79 }
80
81 bool AddressLookup::getAddress(Symtab *tab, Offset off, Address &addr)
82 {
83    LoadedLib *ll = getLoadedLib(tab);
84    if (!ll)
85       return false;
86    addr = ll->offToAddress(off);
87    return true;
88 }
89
90 bool AddressLookup::getAddress(Symtab *tab, Symbol *sym, Address &addr)
91 {
92    LoadedLib *ll = getLoadedLib(tab);
93    if (!ll)
94       return false;
95    addr = symToAddress(ll, sym);
96    return true;
97 }
98
99 bool sort_by_addr(const Symbol* a, const Symbol* b)
100 {
101    return a->getOffset() < b->getOffset();
102 }
103
104 vector<Symbol *> *AddressLookup::getSymsVector(LoadedLib *lib)
105 {
106    string str = lib->getName();
107    if (syms.find(str) != syms.end()) {
108       return &(syms[str]);
109    }
110    
111    Symtab *tab = getSymtab(lib);
112    
113    if (!tab) {
114       return NULL;
115    }
116
117    vector<Symbol *> &symbols = syms[str];
118    tab->getAllSymbolsByType(symbols, Symbol::ST_UNKNOWN);
119    std::sort(symbols.begin(), symbols.end(), sort_by_addr);
120
121    return &(syms[str]);
122 }
123
124 bool AddressLookup::getOffset(Address addr, Symtab* &tab, Offset &off)
125 {
126    LoadedLib *lib;
127    bool result;
128
129    result = translator->getLibAtAddress(addr, lib);
130    if (!result || !lib) {
131       return false;
132    }
133
134    off = lib->addrToOffset(addr);
135    tab = getSymtab(lib);
136    return true;
137 }
138
139 bool AddressLookup::getOffset(Address addr, LoadedLibrary &ll, Offset &off)
140 {
141    LoadedLib *lib;
142    bool result;
143
144    result = translator->getLibAtAddress(addr, lib);
145    if (!result || !lib) {
146       return false;
147    }
148
149    off = lib->addrToOffset(addr);
150    ll.name = lib->getName();
151    ll.codeAddr = lib->getCodeLoadAddr();
152    ll.dataAddr = lib->getDataLoadAddr();
153    return true;
154 }
155
156 bool AddressLookup::getSymbol(Address addr, Symbol* &sym, Symtab* &tab, bool close)
157 {
158    LoadedLib *lib;
159    bool result;
160
161    result = translator->getLibAtAddress(addr, lib);
162    if (!result || !lib) {
163       return false;
164    }
165
166    tab = getSymtab(lib);
167    vector<Symbol *> *symbols = getSymsVector(lib);
168    if (!symbols) {
169       return false;
170    }
171    
172    unsigned min = 0;
173    unsigned max = symbols->size();
174    unsigned mid, last_mid;
175    last_mid = max+1;
176
177    Symbol *closest = NULL;
178    unsigned long closest_dist = 0;
179
180    addr -= lib->addrToOffset(addr);
181
182    for (;;) {
183       mid = (min + max) / 2;
184       if (mid == last_mid)
185          break;
186       last_mid = mid;
187       
188       Offset cur_off = (*symbols)[mid]->getOffset();
189       
190       if (addr == cur_off) {
191          sym = (*symbols)[mid];
192          return true;
193       }
194       if (addr < cur_off) {
195          max = mid;
196          continue;
197       }
198       if (close && (!closest || closest_dist > (cur_off - addr)))
199       {
200          closest_dist = cur_off - addr;
201          closest = (*symbols)[mid];
202       }
203       if (addr > cur_off) {
204          min = mid;
205          continue;
206       }
207    }
208
209    if (close && closest)
210    {
211       sym = (*symbols)[mid];
212       return true;
213    }
214
215    return false;
216 }
217
218 bool AddressLookup::getAllSymtabs(std::vector<Symtab *> &tabs)
219 {
220    vector<LoadedLib *> libs;
221    bool result = translator->getLibs(libs);
222    if (!result)
223       return false;
224
225    for (unsigned i=0; i<libs.size(); i++)
226    {
227       Symtab *symt = getSymtab(libs[i]);
228       if (symt)
229          tabs.push_back(symt);
230    }
231
232    return true;
233 }
234
235 bool AddressLookup::getLoadAddress(Symtab* sym, Address &load_addr)
236 {
237    LoadedLib *ll = getLoadedLib(sym);
238    if (!ll)
239       return false;
240    load_addr = ll->getCodeLoadAddr();
241    return true;
242 }
243
244 bool AddressLookup::getDataLoadAddress(Symtab* sym, Address &load_addr)
245 {
246    LoadedLib *ll = getLoadedLib(sym);
247    if (!ll)
248       return false;
249    load_addr = ll->getDataLoadAddr();
250    return true;
251 }
252
253 bool AddressLookup::getLoadAddresses(std::vector<LoadedLibrary> &name_addrs)
254 {
255    vector<LoadedLib *> libs;
256    bool result = translator->getLibs(libs);
257    if (!result)
258       return false;
259
260    for (unsigned i=0; i<libs.size(); i++)
261    {
262       LoadedLibrary l;
263       libs[i]->getOutputs(l.name, l.codeAddr, l.dataAddr);
264       name_addrs.push_back(l);
265    }
266
267    return true;
268 }
269
270 Address AddressLookup::getLibraryTrapAddrSysV()
271 {
272    return translator->getLibraryTrapAddrSysV();
273 }
274
275 AddressLookup::AddressLookup(AddressTranslate *at) :
276    translator(at)
277 {
278 }
279
280 AddressLookup::~AddressLookup()
281 {
282 }
283
284 bool AddressLookup::refresh()
285 {
286    return translator->refresh();
287 }
288
289 bool AddressLookup::getExecutable(LoadedLibrary &lib)
290 {
291    LoadedLib *llib = translator->getExecutable();
292    if (!llib)
293       return false;
294    llib->getOutputs(lib.name, lib.codeAddr, lib.dataAddr);
295    return true;
296 }
297
298 Dyninst::Address AddressLookup::symToAddress(LoadedLib *ll, Symbol *sym)
299 {
300    return ll->getCodeLoadAddr() + sym->getOffset();
301 }
302
303 LoadedLib *AddressLookup::getLoadedLib(Symtab *sym)
304 {
305    std::map<Symtab *, LoadedLib *>::iterator i = sym_to_ll.find(sym);
306    if (i != sym_to_ll.end()) {
307       return i->second;
308    }
309    
310    vector<LoadedLib *> libs;
311    translator->getLibs(libs);
312    for (vector<LoadedLib *>::iterator i = libs.begin(); i != libs.end(); i++) {
313       LoadedLib *ll = *i;
314       if (sym->file() == ll->getName() || 
315           sym->name() == ll->getName())
316       {
317          ll_to_sym[ll] = sym;
318          sym_to_ll[sym] = ll;
319          return ll;
320       }
321    }
322    return NULL;
323 }
324
325 Symtab *AddressLookup::getSymtab(LoadedLib *ll)
326 {
327    std::map<LoadedLib *, Symtab *>::iterator i = ll_to_sym.find(ll);
328    if (i != ll_to_sym.end()) {
329       return i->second;
330    }
331    
332    Symtab *sym;
333    bool result = Symtab::openFile(sym, ll->getName());
334    if (!result) {
335       return NULL;
336    }
337    ll_to_sym[ll] = sym;
338    sym_to_ll[sym] = ll;
339    return sym;
340 }