Compile fix after removing deprecated SymtabAPI methods.
[dyninst.git] / symtabAPI / src / Symtab-lookup.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 /* Lookup functions defined in class Symtab. Separated to reduce file size and classify. */
32
33
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <assert.h>
38 #include <string.h>
39 #include <vector>
40 #include <algorithm>
41
42 #include "common/h/Timer.h"
43 #include "common/h/debugOstream.h"
44 #include "common/h/serialize.h"
45 #include "common/h/pathName.h"
46
47 #include "Serialization.h"
48 #include "Symtab.h"
49 #include "Module.h"
50 #include "Collections.h"
51 #include "Function.h"
52 #include "Variable.h"
53 #include "annotations.h"
54
55 #include "symtabAPI/src/Object.h"
56
57 using namespace Dyninst;
58 using namespace Dyninst::SymtabAPI;
59 using namespace std;
60
61 extern SymtabError serr;
62
63 bool regexEquiv( const std::string &str,const std::string &them, bool checkCase );
64 bool pattern_match( const char *p, const char *s, bool checkCase );
65
66 std::vector<Symbol *> *Symtab::findSymbolByOffset(Offset o)
67 {
68         //Symbol *s = NULL;
69         dyn_hash_map<Offset, std::vector<Symbol *> >::iterator iter;
70         iter = symsByOffset.find(o);
71         if (iter == symsByOffset.end()) return NULL;
72         return &(iter->second);
73 }
74
75 bool Symtab::findSymbol(std::vector<Symbol *> &ret, const std::string& name,
76                         Symbol::SymbolType sType, NameType nameType,
77                         bool isRegex, bool checkCase, bool includeUndefined)
78 {
79
80     unsigned old_size = ret.size();
81
82     std::vector<Symbol *> candidates;
83
84     if (!isRegex) {
85         // Easy case
86         if (nameType & mangledName) {
87            candidates.insert(candidates.end(), symsByMangledName[name].begin(), symsByMangledName[name].end());
88            if (includeUndefined) candidates.insert(candidates.end(), 
89                                                    undefDynSymsByMangledName[name].begin(), 
90                                                    undefDynSymsByMangledName[name].end());
91         }
92         if (nameType & prettyName) {
93            candidates.insert(candidates.end(), symsByPrettyName[name].begin(), symsByPrettyName[name].end());
94            if (includeUndefined) candidates.insert(candidates.end(), 
95                                                    undefDynSymsByPrettyName[name].begin(), 
96                                                    undefDynSymsByPrettyName[name].end());
97         }
98         if (nameType & typedName) {
99            candidates.insert(candidates.end(), symsByTypedName[name].begin(), symsByTypedName[name].end());
100            if (includeUndefined) candidates.insert(candidates.end(), 
101                                                    undefDynSymsByTypedName[name].begin(), 
102                                                    undefDynSymsByTypedName[name].end());
103         }
104     }
105     else {
106         // Build the regex list of symbols
107         // We need to iterate over every single symbol. Ugh.
108        if (includeUndefined) {
109           cerr << "Warning: regex search of undefined symbols is not supported" << endl;
110        }
111
112        for (unsigned i = 0; i < everyDefinedSymbol.size(); i++) {
113           if (nameType & mangledName) {
114              if (regexEquiv(name, everyDefinedSymbol[i]->getMangledName(), checkCase))
115                 candidates.push_back(everyDefinedSymbol[i]);
116
117           }
118           if (nameType & prettyName) {
119              if (regexEquiv(name, everyDefinedSymbol[i]->getPrettyName(), checkCase))
120                 candidates.push_back(everyDefinedSymbol[i]);
121           }
122           if (nameType & typedName) {
123              if (regexEquiv(name, everyDefinedSymbol[i]->getTypedName(), checkCase))
124                 candidates.push_back(everyDefinedSymbol[i]);
125           }
126        }
127     }
128
129     std::set<Symbol *> matches;
130
131     for (std::vector<Symbol *>::iterator iter = candidates.begin();
132          iter != candidates.end(); ++iter) {
133        if (sType == Symbol::ST_UNKNOWN ||
134            sType == Symbol::ST_NOTYPE ||
135            sType == (*iter)->getType()) {
136           matches.insert(*iter);
137        }
138     }
139     ret.insert(ret.end(), matches.begin(), matches.end());
140
141     if (ret.size() == old_size) {
142         serr = No_Such_Symbol;
143         return false;
144     }
145     else {
146         return true;
147     }
148 }
149
150 bool Symtab::getAllSymbols(std::vector<Symbol *> &ret)
151 {
152     ret = everyDefinedSymbol;
153
154     // add undefined symbols
155     std::vector<Symbol *> temp;
156     std::vector<Symbol *>::iterator it;
157     getAllUndefinedSymbols(temp);
158     for (it = temp.begin(); it != temp.end(); it++)
159         ret.push_back(*it);
160
161     if(ret.size() > 0)
162         return true;
163     serr = No_Such_Symbol;
164     return false;
165 }
166
167 bool Symtab::getAllSymbolsByType(std::vector<Symbol *> &ret, Symbol::SymbolType sType)
168 {
169     if (sType == Symbol::ST_UNKNOWN)
170         return getAllSymbols(ret);
171
172     unsigned old_size = ret.size();
173     // Filter by the given type
174     for (unsigned i = 0; i < everyDefinedSymbol.size(); i++) {
175         if (everyDefinedSymbol[i]->getType() == sType)
176             ret.push_back(everyDefinedSymbol[i]);
177     }
178     // add undefined symbols
179     std::vector<Symbol *> temp;
180     getAllUndefinedSymbols(temp);
181     for (unsigned i = 0; i < temp.size(); i++) {
182         if (temp[i]->getType() == sType)
183             ret.push_back(temp[i]);
184     }
185
186     if (ret.size() > old_size) {
187         return true;
188     }
189     else {
190         serr = No_Such_Symbol;
191         return false;
192     }
193 }
194
195 bool Symtab::getAllDefinedSymbols(std::vector<Symbol *> &ret)
196 {
197     ret = everyDefinedSymbol;
198
199     if(ret.size() > 0)
200         return true;
201     serr = No_Such_Symbol;
202     return false;
203 }
204  
205 bool Symtab::getAllUndefinedSymbols(std::vector<Symbol *> &ret){
206     unsigned size = ret.size();
207     ret.insert(ret.end(), undefDynSyms.begin(), undefDynSyms.end());
208     if(ret.size()>size)
209         return true;
210     serr = No_Such_Symbol;
211     return false;
212 }
213
214 bool Symtab::findFuncByEntryOffset(Function *&ret, const Offset entry)
215 {
216     /* XXX
217      *
218      * When working with relocatable files, a symbol is not uniquely identified
219      * by its offset; it is uniquely identified by its Region and its offset.
220      * This discrepancy is not taken into account here.
221      */
222     if (funcsByOffset.find(entry) != funcsByOffset.end()) {
223         ret = funcsByOffset[entry];
224         return true;
225     }
226     serr = No_Such_Function;
227     return false;
228 }
229
230 bool sort_by_func_ptr(const Function *a, const Function *b) {
231     return a < b;
232 }
233
234 bool Symtab::findFunctionsByName(std::vector<Function *> &ret, const std::string name,
235                                  NameType nameType, bool isRegex, bool checkCase) {
236     std::vector<Symbol *> funcSyms;
237     if (!findSymbol(funcSyms, name, Symbol::ST_FUNCTION, nameType, isRegex, checkCase))
238         return false;
239
240     std::vector<Function *> unsortedFuncs;
241     for (unsigned i = 0; i < funcSyms.size(); i++) 
242     {
243         if (doNotAggregate(funcSyms[i])) continue;
244         if (!funcSyms[i]->getFunction())
245         {
246             fprintf(stderr, "%s[%d]:  WARNING:  internal inconsistency\n", FILE__, __LINE__);
247             fprintf(stderr, "%s[%d]:  WARNING:  %s is %s a function\n", FILE__, __LINE__, name.c_str(), funcSyms[i]->isFunction() ? "" : "not");
248             fprintf(stderr, "%s[%d]:  WARNING:  %s is %s a variable\n", FILE__, __LINE__, name.c_str(), funcSyms[i]->isVariable() ? "" : "not");
249             continue;
250         }
251         unsortedFuncs.push_back(funcSyms[i]->getFunction());
252     }
253
254     std::sort(unsortedFuncs.begin(), unsortedFuncs.end(), sort_by_func_ptr);
255     std::vector<Function *>::iterator endIter;
256     endIter = std::unique(unsortedFuncs.begin(), unsortedFuncs.end());
257     for (std::vector<Function *>::iterator iter = unsortedFuncs.begin();
258          iter != endIter;
259          iter++)
260         ret.push_back(*iter);
261
262     return true;
263 }
264
265 bool Symtab::getAllFunctions(std::vector<Function *> &ret) {
266     ret = everyFunction;
267     return (ret.size() > 0);
268 }
269
270 bool Symtab::findVariableByOffset(Variable *&ret, const Offset offset) {
271
272     /* XXX
273      *
274      * See comment in findFuncByOffset about uniqueness of symbols in
275      * relocatable files -- this discrepancy applies here as well.
276      */
277     if (varsByOffset.find(offset) != varsByOffset.end()) {
278         ret = varsByOffset[offset];
279         return true;
280     }
281     serr = No_Such_Variable;
282     return false;
283 }
284
285 static bool sort_by_var_ptr(const Variable * a, const Variable *b) {
286     return a < b;
287 }
288
289 bool Symtab::findVariablesByName(std::vector<Variable *> &ret, const std::string name,
290                                  NameType nameType, bool isRegex, bool checkCase) {
291     std::vector<Symbol *> varSyms;
292     if (!findSymbol(varSyms, name, Symbol::ST_OBJECT, nameType, isRegex, checkCase))
293         return false;
294
295     std::vector<Variable *> unsortedVars;
296     for (unsigned i = 0; i < varSyms.size(); i++) {
297         if (doNotAggregate(varSyms[i])) continue;
298         unsortedVars.push_back(varSyms[i]->getVariable());
299     }
300
301     std::sort(unsortedVars.begin(), unsortedVars.end(), sort_by_var_ptr);
302     std::vector<Variable *>::iterator endIter;
303     endIter = std::unique(unsortedVars.begin(), unsortedVars.end());
304     for (std::vector<Variable *>::iterator iter = unsortedVars.begin();
305          iter != endIter;
306          iter++)
307         ret.push_back(*iter);
308
309     return true;
310 }
311
312 bool Symtab::getAllVariables(std::vector<Variable *> &ret) 
313 {
314     ret = everyVariable;
315     return (ret.size() > 0);
316 }
317
318 bool Symtab::getAllModules(std::vector<Module *> &ret)
319 {
320     if (_mods.size() >0 )
321     {
322         ret = _mods;
323         return true;
324     }   
325
326     serr = No_Such_Module;
327     return false;
328 }
329
330 bool Symtab::findModuleByOffset(Module *&ret, Offset off)
331 {   
332    //  this should be a hash, really
333    for (unsigned int i = 0; i < _mods.size(); ++i) 
334    {
335       Module *mod = _mods[i];
336
337       if (off == mod->addr()) 
338       {
339           ret = mod;
340           return true;
341       }
342    } 
343    return false;
344 }
345
346 bool Symtab::findModuleByName(Module *&ret, const std::string name)
347 {
348    dyn_hash_map<std::string, Module *>::iterator loc;
349    loc = modsByFullName.find(name);
350
351    if (loc != modsByFullName.end()) 
352    {
353       ret = loc->second;
354       return true;
355    }
356
357    std::string tmp = extract_pathname_tail(name);
358
359    loc = modsByFileName.find(tmp);
360
361    if (loc != modsByFileName.end()) 
362    {
363       ret = loc->second;
364       return true;
365    }
366
367    serr = No_Such_Module;
368    ret = NULL;
369    return false;
370 }
371
372 bool Symtab::getAllRegions(std::vector<Region *>&ret)
373 {
374    if (regions_.size() > 0)
375    {
376       ret = regions_;
377       return true;
378    }
379
380    return false;
381 }
382
383 bool Symtab::getCodeRegions(std::vector<Region *>&ret)
384 {
385    if (codeRegions_.size() > 0)
386    {
387       ret = codeRegions_;
388       return true;
389    }
390
391    return false;
392 }
393
394 bool Symtab::getDataRegions(std::vector<Region *>&ret)
395 {
396    if (dataRegions_.size() > 0)
397    {
398       ret = dataRegions_;
399       return true;
400    }
401    return false;
402 }
403
404
405 bool Symtab::getAllNewRegions(std::vector<Region *>&ret)
406 {
407    std::vector<Region *> *retp = NULL;
408
409    if (!getAnnotation(retp, UserRegionsAnno))
410    {
411       return false;
412    }
413
414    if (!retp)
415    {
416       return false;
417    }
418
419    ret = *retp;
420
421    return true;
422 }
423
424 bool Symtab::getAllExceptions(std::vector<ExceptionBlock *> &exceptions)
425 {
426    if (excpBlocks.size()>0)
427    {
428       exceptions = excpBlocks;
429       return true;
430    }    
431
432    return false;
433 }
434
435
436 bool Symtab::findException(ExceptionBlock &excp, Offset addr)
437 {
438    for (unsigned i=0; i<excpBlocks.size(); i++)
439    {
440       if (excpBlocks[i]->contains(addr))
441       {
442          excp = *(excpBlocks[i]);
443          return true;
444       } 
445    }
446
447    return false;
448 }
449
450 /**
451  * Returns true if the Address range addr -> addr+size contains
452  * a catch block, with excp pointing to the appropriate block
453  **/
454 bool Symtab::findCatchBlock(ExceptionBlock &excp, Offset addr, unsigned size)
455 {
456     int min = 0;
457     int max = excpBlocks.size();
458     int cur = -1, last_cur;
459
460     if (max == 0)
461         return false;
462
463     //Binary search through vector for address
464     while (true)
465     {
466         last_cur = cur;
467         cur = (min + max) / 2;
468     
469         if (last_cur == cur)
470             return false;
471
472         Offset curAddr = excpBlocks[cur]->catchStart();
473         if ((curAddr <= addr && curAddr+size > addr) ||
474             (size == 0 && curAddr == addr))
475         {
476             //Found it
477             excp = *(excpBlocks[cur]);
478             return true;
479         }
480         if (addr < curAddr)
481             max = cur;
482         else if (addr > curAddr)
483             min = cur;
484     }
485 }
486  
487 bool Symtab::findRegionByEntry(Region *&ret, const Offset offset)
488 {
489     if(regionsByEntryAddr.find(offset) != regionsByEntryAddr.end())
490     {
491         ret = regionsByEntryAddr[offset];
492         return true;
493     }
494     serr = No_Such_Region;
495     return false;
496 }
497
498 /* Similar to binary search in isCode with the exception that here we
499  * search to the end of regions without regards to whether they have
500  * corresponding raw data on disk, and searches all regions.  
501  *
502  * regions_ elements that start at address 0 may overlap, ELF binaries
503  * have 0 address iff they are not loadable, but xcoff places loadable
504  * sections at address 0, including .text and .data
505  */
506 Region *Symtab::findEnclosingRegion(const Offset where)
507 {
508     int first = 0; 
509     int last = regions_.size() - 1;
510     while (last >= first) {
511         Region *curreg = regions_[(first + last) / 2];
512         if (where >= curreg->getMemOffset()
513             && where < (curreg->getMemOffset()
514                         + curreg->getMemSize())) {
515             return curreg;
516         }
517         else if (where < curreg->getMemOffset()) {
518             last = ((first + last) / 2) - 1;
519         }
520         else {/* where >= (cursec->getSecAddr()
521                            + cursec->getSecSize()) */
522             first = ((first + last) / 2) + 1;
523         }
524     }
525     return NULL;
526 }
527
528 bool Symtab::findRegion(Region *&ret, const std::string secName)
529 {
530     for(unsigned index=0;index<regions_.size();index++)
531     {
532         if(regions_[index]->getRegionName() == secName)
533         {
534             ret = regions_[index];
535             return true;
536         }
537     }
538     serr = No_Such_Region;
539     return false;
540 }
541
542
543 bool Symtab::findRegion(Region *&ret, const Offset addr, const unsigned long size)
544 {
545    ret = NULL;
546    for(unsigned index=0;index<regions_.size();index++) {
547       if(regions_[index]->getMemOffset() == addr && regions_[index]->getMemSize() == size) {
548          if (ret) {
549 #if 0
550             cerr << "Error: region inconsistency" << endl;
551             cerr << "\t" << ret->getRegionName() << " @ "
552                  << hex << ret->getRegionAddr() << "/" << ret->getDiskSize() << endl;
553             cerr << "\t" << regions_[index]->getRegionName() << " @ "
554                  << regions_[index]->getRegionAddr() << "/" << regions_[index]->getDiskSize() << dec << endl;
555 #endif
556             assert(addr == 0); // Two regions with the same address and size, with non-zero address,
557             // is incorrect parsing of symbol table. 
558             serr = Multiple_Region_Matches;
559             return false;
560          }
561          ret = regions_[index];
562       }
563    }
564    if (ret) return true;
565    serr = No_Such_Region;
566    return false;
567 }
568
569 ///////////////////////// REGEX //////////////////////
570
571 // Use POSIX regular expression pattern matching to check if std::string s matches
572 // the pattern in this std::string
573 bool regexEquiv( const std::string &str,const std::string &them, bool checkCase ) 
574 {
575    const char *str_ = str.c_str();
576    const char *s = them.c_str();
577    // Would this work under NT?  I don't know.
578    //#if !defined(os_windows)
579     return pattern_match(str_, s, checkCase);
580
581 }
582
583 // This function will match string s against pattern p.
584 // Asterisks match 0 or more wild characters, and a question
585 // mark matches exactly one wild character.  In other words,
586 // the asterisk is the equivalent of the regex ".*" and the
587 // question mark is the equivalent of "."
588
589 bool
590 pattern_match( const char *p, const char *s, bool checkCase ) {
591    //const char *p = ptrn;
592    //char *s = str;
593
594     while ( true ) {
595         // If at the end of the pattern, it matches if also at the end of the string
596         if( *p == '\0' )
597             return ( *s == '\0' );
598
599         // Process a '*'
600         if( *p == MULTIPLE_WILDCARD_CHARACTER ) {
601             ++p;
602
603             // If at the end of the pattern, it matches
604             if( *p == '\0' )
605                 return true;
606
607             // Try to match the remaining pattern for each remaining substring of s
608             for(; *s != '\0'; ++s )
609                 if( pattern_match( p, s, checkCase ) )
610                     return true;
611             // Failed
612             return false;
613         }
614
615         // If at the end of the string (and at this point, not of the pattern), it fails
616         if( *s == '\0' )
617             return false;
618
619         // Check if this character matches
620         bool matchChar = false;
621         if( *p == WILDCARD_CHARACTER || *p == *s )
622             matchChar = true;
623         else if( !checkCase ) {
624             if( *p >= 'A' && *p <= 'Z' && *s == ( *p + ( 'a' - 'A' ) ) )
625                 matchChar = true;
626             else if( *p >= 'a' && *p <= 'z' && *s == ( *p - ( 'a' - 'A' ) ) )
627                 matchChar = true;
628         }
629
630         if( matchChar ) {
631             ++p;
632             ++s;
633             continue;
634         }
635
636         // Did not match
637         return false;
638     }
639 }
640
641 struct Dyninst::SymtabAPI::SymbolCompareByAddr
642 {
643     bool operator()(Function *a, Function *b)
644     {
645        return (a->offset_ < b->offset_);
646     }
647 };
648
649 bool Symtab::getContainingFunction(Offset offset, Function* &func)
650 {
651    if (!isCode(offset)) {
652       return false;
653    }
654    if (everyFunction.size() && !sorted_everyFunction)
655    {
656       std::sort(everyFunction.begin(), everyFunction.end(),
657                 SymbolCompareByAddr());
658       sorted_everyFunction = true;
659    }
660    
661    unsigned low = 0;
662    unsigned high = everyFunction.size();
663    unsigned last_mid = high+1;
664    unsigned mid;
665    if (!high) return false;
666    for (;;)
667    {
668       mid = (low + high) / 2;
669       if (last_mid == mid)
670          break;
671       last_mid = mid;
672       Offset cur = everyFunction[mid]->getOffset();
673       if (cur > offset) {
674          high = mid;
675          continue;
676       }
677       if (cur < offset) {
678          low = mid;
679          continue;
680       }
681       if (cur == offset) {
682          func = everyFunction[mid];
683          return true;
684       }
685    }
686
687    if ((everyFunction[low]->getOffset() <= offset) &&
688        ((low+1 == everyFunction.size()) || 
689         (everyFunction[low+1]->getOffset() > offset)))
690    {
691          func = everyFunction[low];
692          return true;
693    }
694    return false;
695 }
696
697 Module *Symtab::getDefaultModule() {
698     Module *mod = NULL;
699     // TODO: automatically pick the module that contains this address?
700     // For now, DEFAULT_MODULE or (if we have only one) that one.
701     if (_mods.size() == 1)
702         return _mods[0];
703     else {
704         if (!findModuleByName(mod, "DEFAULT_MODULE"))
705             return NULL;
706     }
707     return mod;
708 }
709
710 unsigned Function::getSize() {
711    if (functionSize_)
712       return functionSize_;
713    for (unsigned i=0; i<symbols_.size(); i++) {
714       if (symbols_[i]->getSize()) { 
715          functionSize_ = symbols_[i]->getSize();;
716          return functionSize_;
717       }
718    }
719
720    Symtab *symtab = getFirstSymbol()->getSymtab();
721    if (symtab->everyFunction.size() && !symtab->sorted_everyFunction)
722    {
723       std::sort(symtab->everyFunction.begin(), symtab->everyFunction.end(),
724                 SymbolCompareByAddr());
725       symtab->sorted_everyFunction = true;
726    }
727
728    Offset offset = getOffset();
729    unsigned low = 0;
730    unsigned high = symtab->everyFunction.size();
731    unsigned last_mid = high+1;
732    unsigned mid;
733    for (;;)
734    {
735       mid = (low + high) / 2;
736       if (last_mid == mid)
737          return 0;
738       last_mid = mid;
739       Offset cur = symtab->everyFunction[mid]->getOffset();
740       if (cur > offset) {
741          high = mid;
742          continue;
743       }
744       if (cur < offset) {
745          low = mid;
746          continue;
747       }
748       if (cur == offset) {
749          if (mid + 1 >= symtab->everyFunction.size())
750             return 0;
751          Function *next_func = symtab->everyFunction[mid+1];
752          functionSize_ = next_func->getOffset() - getOffset();
753          return functionSize_;
754       }
755    }
756 }
757
758 Dyninst::Offset Symtab::fileToDiskOffset(Dyninst::Offset fileOffset) const {
759    for (unsigned j = 0; j < regions_.size(); ++j) {
760       if (regions_[j]->getFileOffset() <= fileOffset &&
761           ((regions_[j]->getFileOffset() + regions_[j]->getDiskSize()) > fileOffset)) {
762          return fileOffset - regions_[j]->getFileOffset() + regions_[j]->getDiskOffset();
763       }
764    }
765    return (Dyninst::Offset) -1;
766 }
767
768 Dyninst::Offset Symtab::fileToMemOffset(Dyninst::Offset fileOffset) const {
769    for (unsigned j = 0; j < regions_.size(); ++j) {
770       if (regions_[j]->getFileOffset() <= fileOffset &&
771           ((regions_[j]->getFileOffset() + regions_[j]->getDiskSize()) > fileOffset)) {
772          return fileOffset - regions_[j]->getFileOffset() + regions_[j]->getMemOffset();
773       }
774    }
775    return (Dyninst::Offset) -1;
776 }