More ppc32_bgp changes
[dyninst.git] / dyninstAPI / src / symtab.C
1 /*
2  * Copyright (c) 1996-2009 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <assert.h>
36 #include <string>
37 #include <fstream>
38
39 #include "symtab.h"
40 #include "common/h/arch.h"
41 #include "instPoint.h"
42 #include "parRegion.h"
43 #include "util.h"
44 #include "inst.h"
45 #include "debug.h"
46 #include "function.h"
47 #include "Parsing.h"
48
49 #include "common/h/Timer.h"
50 #include "common/h/debugOstream.h"
51 #include "common/h/pathName.h"
52 #include "common/h/MappedFile.h"
53
54 #include "dyninstAPI/h/BPatch_flowGraph.h"
55 #include "dynutil/h/util.h"
56
57 #include "symtabAPI/h/Function.h"
58
59 #include "parseAPI/h/InstructionSource.h"
60 #include "parseAPI/h/CodeObject.h"
61 #include "parseAPI/h/CFG.h"
62
63 #if defined(TIMED_PARSE)
64 #include <sys/time.h>
65 #endif
66
67 #if defined( USES_DWARF_DEBUG )
68 #include "dwarf.h"
69 #include "libdwarf.h"
70 #endif
71
72 #if defined(i386_unknown_nt4_0)
73 #include <dbghelp.h>
74 #include <cvconst.h>
75 #endif
76
77 #if defined(os_vxworks)
78 #include "dyninstAPI/src/vxworks.h"
79 #endif
80
81 AnnotationClass<image_variable> ImageVariableUpPtrAnno("ImageVariableUpPtrAnno");
82 AnnotationClass<image_func> ImageFuncUpPtrAnno("ImageFuncUpPtrAnno");
83 pdvector<image*> allImages;
84
85 using namespace std;
86 using namespace Dyninst;
87 using namespace Dyninst::ParseAPI;
88
89 using Dyninst::SymtabAPI::Symtab;
90 using Dyninst::SymtabAPI::Symbol;
91 using Dyninst::SymtabAPI::Region;
92 using Dyninst::SymtabAPI::Variable;
93 using Dyninst::SymtabAPI::Module;
94
95 string fileDescriptor::emptyString(string(""));
96 fileDescriptor::fileDescriptor() {
97     // This shouldn't be called... must be public for pdvector, though
98 }
99
100 bool fileDescriptor::IsEqual(const fileDescriptor &fd) const {
101     // Don't test isShared, only file name and addresses
102     bool file_match_ = false;
103
104     // Annoying... we often get "foo vs ./foo" or such. So consider it a match
105     // if either file name is prefixed by the other; we don't get trailing crud.
106     string::size_type len1 = file_.length();
107     string::size_type len2 = fd.file_.length();
108   
109     if(((len1>=len2) && (file_.substr(len1-len2,len2) == fd.file_))
110        || ((len2>len1) && (fd.file_.substr(len2-len1,len1) == file_)))
111         file_match_ = true;   
112 #if defined(os_linux)
113     struct stat buf1;
114     struct stat buf2;
115     if (!stat(file_.c_str(),&buf1)
116         && !stat(fd.file_.c_str(),&buf2)
117         && buf1.st_ino == buf2.st_ino) {
118         file_match_ = true;
119     }
120 #endif  
121     bool addr_match = ((code_ == fd.code_ && data_ == fd.data_) ||
122                        (dynamic_ && dynamic_ == fd.dynamic_));
123     if (file_match_ &&
124         (addr_match) &&
125         (member_ == fd.member_) &&
126         (pid_ == fd.pid_))
127         return true;
128     else
129         return false;
130 }
131
132 void fileDescriptor::setLoadAddr(Address a) 
133
134    loadAddr_ = a; 
135    code_ += a;
136    data_ += a;
137 }
138
139 // only for non-files
140 unsigned char* fileDescriptor::rawPtr()
141 {
142
143 #if defined(os_windows)
144
145     return rawPtr_;
146
147 #else
148
149     return NULL;
150
151 #endif
152
153 }
154
155
156 // All debug_ostream vrbles are defined in process.C (for no particular reason)
157 extern unsigned enable_pd_sharedobj_debug;
158
159 int codeBytesSeen = 0;
160
161 #if defined(ppc32_linux) || defined(ppc32_bgp)
162
163 #include <dataflowAPI/h/slicing.h>
164 #include <dataflowAPI/h/SymEval.h>
165 #include <dataflowAPI/h/AbslocInterface.h>
166 #include <dataflowAPI/h/Absloc.h>
167 #include <dynutil/h/AST.h>
168
169 namespace {
170     /* On PPC GLIBC (32 & 64 bit) the address of main is in a structure
171        located in either .data or .rodata, depending on whether the 
172        binary is PIC. The structure has the following format:
173
174         struct 
175         {
176             void * // "small data area base"
177             main   // pointer to main
178             init   // pointer to init
179             fini   // pointer to fini
180         }
181
182         This structure is passed in GR8 as an argument to libc_start_main.
183
184         Annoyingly, the value in GR8 is computed in several different ways,
185         depending on how GLIBC was compiled.
186
187         This code follows the i386 linux version closely otherwise.
188     */
189
190     class Default_Predicates : public Slicer::Predicates {};
191
192     /* This visitor is capable of simplifying constant value computations
193        that involve additions and concatenations (lis instruction). This
194        is sufficient to handle the startup struct address calculation in
195        GLIBC that we have seen; if additional variants are introduced
196        (refer to start.S in glibc or equivalently to the compiled library)
197        this visitor should be expanded to handle any new operations */
198         
199     class SimpleArithVisitor : public ASTVisitor {
200
201         using ASTVisitor::visit;
202
203         virtual ASTPtr visit(AST * a) {return a->ptr();};
204         virtual ASTPtr visit(DataflowAPI::BottomAST *a) {return a->ptr(); };
205         virtual ASTPtr visit(DataflowAPI::ConstantAST *c) {return c->ptr();};
206         virtual ASTPtr visit(DataflowAPI::VariableAST *v) {return v->ptr();};
207
208         virtual AST::Ptr visit(DataflowAPI::RoseAST * r) {
209             using namespace DataflowAPI;
210
211             AST::Children newKids;
212             for(unsigned i=0;i<r->numChildren();++i) {
213                 newKids.push_back(r->child(i)->accept(this));
214             }
215
216             switch(r->val().op) {
217                 case ROSEOperation::addOp:
218                     assert(newKids.size() == 2);
219                     if(newKids[0]->getID() == AST::V_ConstantAST &&
220                        newKids[1]->getID() == AST::V_ConstantAST)
221                     {
222                         ConstantAST::Ptr c1 = ConstantAST::convert(newKids[0]);
223                         ConstantAST::Ptr c2 = ConstantAST::convert(newKids[1]);
224                         return ConstantAST::create(
225                             Constant(c1->val().val+c2->val().val));
226                     }
227                     break;
228                 case ROSEOperation::concatOp:
229                     assert(newKids.size() == 2);
230                     if(newKids[0]->getID() == AST::V_ConstantAST &&
231                        newKids[1]->getID() == AST::V_ConstantAST)
232                     {
233                         ConstantAST::Ptr c1 = ConstantAST::convert(newKids[0]);
234                         ConstantAST::Ptr c2 = ConstantAST::convert(newKids[1]);
235                         unsigned long result = c1->val().val;
236                         result |= (c2->val().val << c2->val().size);
237                         return ConstantAST::create(result);
238                     }
239                     break;
240                 default:
241                     startup_printf("%s[%d] unhandled operation in simplification\n",FILE__,__LINE__);
242             }
243         
244             return RoseAST::create(r->val(), newKids);
245         }
246     };
247
248     struct libc_startup_info {
249         void * sda;
250         void * main_addr;
251         void * init_addr;
252         void * fini_addr;
253     };
254
255     /*
256      * b ends with a call to libc_start_main. We are looking for the
257      * value in GR8, which is the address of a structure that contains
258      * the address to main
259      */
260     Address evaluate_main_address(Symtab * linkedFile, Function * f, Block *b)
261     {
262         using namespace DataflowAPI;
263         using namespace InstructionAPI;
264         // looking for the *last* instruction in the block
265         // that defines GR8
266     
267         Instruction::Ptr r8_def;
268         Address r8_def_addr;
269     
270         InstructionDecoder dec(
271             b->region()->getPtrToInstruction(b->start()),
272             b->end()-b->start(),
273             b->region()->getArch());
274
275         RegisterAST::Ptr r8( new RegisterAST(ppc32::r8) );
276
277         Address cur_addr = b->start();
278         while(Instruction::Ptr cur = dec.decode()) {
279             if(cur->isWritten(r8)) {
280                 r8_def = cur;
281                 r8_def_addr = cur_addr;  
282             }
283             cur_addr += cur->size();
284         }
285         if(!r8_def)
286             return 0;
287
288         // Get all of the assignments that happen in this instruction
289         AssignmentConverter conv(true);
290         vector<Assignment::Ptr> assigns;
291         conv.convert(r8_def,r8_def_addr,f,assigns);
292
293         // find the one we care about (r8)
294         vector<Assignment::Ptr>::iterator ait = assigns.begin();
295         for( ; ait != assigns.end(); ++ait) {
296             AbsRegion & outReg = (*ait)->out();
297             Absloc const& loc = outReg.absloc();
298             if(loc.reg() == r8->getID())
299                 break;
300         }
301         if(ait == assigns.end()) {
302             return 0;
303         }
304
305         // Slice back to the definition of R8, and, if possible, simplify
306         // to a constant
307         Slicer slc(*ait,b,f);
308         Default_Predicates preds;
309         Graph::Ptr slg = slc.backwardSlice(preds);
310         SymEval::Result_t sl_res;
311         SymEval::expand(slg,sl_res);
312         AST::Ptr calculation = sl_res[*ait];
313         SimpleArithVisitor visit; 
314         AST::Ptr simplified = calculation->accept(&visit);
315         //printf("after simplification:\n%s\n",simplified->format().c_str());
316         if(simplified->getID() == AST::V_ConstantAST) { 
317             ConstantAST::Ptr cp = ConstantAST::convert(simplified);
318             Address ss_addr = cp->val().val;
319
320             // need a pointer to the image data
321             SymtabAPI::Region * dreg = linkedFile->findEnclosingRegion(ss_addr);
322         
323             if(dreg) {
324                 struct libc_startup_info * si =
325                     (struct libc_startup_info *)(
326                         ((Address)dreg->getPtrToRawData()) + 
327                         ss_addr - (Address)dreg->getRegionAddr());
328                 return (Address)si->main_addr;
329             }
330         }
331
332         return 0;
333     }
334 }
335 #endif
336
337 /* 
338  * Search for the Main Symbols in the list of symbols, Only in case
339  * if the file is a shared object. If not present add them to the
340  * list
341  */
342 void image::findMain()
343 {
344 #if defined(ppc32_linux) || defined(ppc32_bgp)
345     using namespace Dyninst::InstructionAPI;
346
347     if(!desc_.isSharedObject())
348     {
349         bool foundMain = false;
350         bool foundStart = false;
351         bool foundFini = false;
352         //check if 'main' is in allsymbols
353         vector <SymtabAPI::Function *> funcs;
354         if (linkedFile->findFunctionsByName(funcs, "main") ||
355             linkedFile->findFunctionsByName(funcs, "_main"))
356             foundMain = true;
357         else if (linkedFile->findFunctionsByName(funcs, "_start"))
358             foundStart = true;
359         else if (linkedFile->findFunctionsByName(funcs, "_fini"))
360             foundFini = true;
361     
362         Region *textsec = NULL;
363         bool foundText = linkedFile->findRegion(textsec, ".text");
364         if (foundText == false) {
365             return;
366         }
367         
368         if( !foundMain )
369         {
370             logLine("No main symbol found: attempting to create symbol for main\n");
371             const unsigned char* p;
372             p = (( const unsigned char * ) textsec->getPtrToRawData());
373
374             Address mainAddress = 0;
375
376                 bool parseInAllLoadableRegions = (BPatch_normalMode != mode_);
377                 SymtabCodeSource scs(linkedFile, filt, parseInAllLoadableRegions);
378             CodeObject tco(&scs,NULL,NULL,false);
379
380             tco.parse(textsec->getRegionAddr(),false);
381             set<CodeRegion *> regions;
382             scs.findRegions(textsec->getRegionAddr(),regions);
383             if(regions.empty()) {
384                 // express puzzlement
385                 return;
386             }
387             SymtabCodeRegion * reg = 
388                 static_cast<SymtabCodeRegion*>(*regions.begin());
389             Function * func = 
390                 tco.findFuncByEntry(reg,textsec->getRegionAddr());
391             if(!func) {
392                 // again, puzzlement
393                 return;
394             }
395
396             Function::edgelist & calls = func->callEdges();
397             if(calls.size() != 1) {
398                 startup_printf("%s[%d] _start has unexpected number (%d) of"
399                                " call edges, bailing on findMain()\n",
400                     FILE__,__LINE__,calls.size());
401                 return; 
402             }
403             Function::edgelist::iterator cit = calls.begin();
404             Block * b = (*cit)->src();
405
406             mainAddress = evaluate_main_address(linkedFile,func,b);
407             if(0 == mainAddress || !scs.isValidAddress(mainAddress)) {
408                 startup_printf("%s[%d] failed to find main\n",FILE__,__LINE__);
409                 return;
410             } else {
411                 startup_printf("%s[%d] found main at %lx\n",
412                     FILE__,__LINE__,mainAddress);
413             }
414                 Symbol *newSym= new Symbol( "main", 
415                                             Symbol::ST_FUNCTION,
416                                             Symbol::SL_GLOBAL, 
417                                             Symbol::SV_DEFAULT, 
418                                             mainAddress,
419                                             linkedFile->getDefaultModule(),
420                                             textsec, 
421                                             0 );
422                 linkedFile->addSymbol(newSym);          
423         }
424     }
425 #elif defined(i386_unknown_linux2_0) \
426 || defined(x86_64_unknown_linux2_4) /* Blind duplication - Ray */ \
427 || defined(i386_unknown_solaris2_5) \
428 || (defined(os_freebsd) \
429     && (defined(arch_x86) || defined(arch_x86_64)))
430     if(!desc_.isSharedObject())
431     {
432         bool foundMain = false;
433         bool foundStart = false;
434         bool foundFini = false;
435         //check if 'main' is in allsymbols
436         vector <SymtabAPI::Function *> funcs;
437         if (linkedFile->findFunctionsByName(funcs, "main") ||
438             linkedFile->findFunctionsByName(funcs, "_main"))
439             foundMain = true;
440         else if (linkedFile->findFunctionsByName(funcs, "_start"))
441             foundStart = true;
442         else if (linkedFile->findFunctionsByName(funcs, "_fini"))
443             foundFini = true;
444     
445         Region *textsec = NULL;
446         bool foundText = linkedFile->findRegion(textsec, ".text");
447         if (foundText == false) {
448             return;
449         }
450         
451         if( !foundMain )
452         {
453             logLine( "No main symbol found: creating symbol for main\n" );
454
455             //find and add main to allsymbols
456             const unsigned char* p;
457                                    
458             p = (( const unsigned char * ) textsec->getPtrToRawData());
459
460             switch(linkedFile->getAddressWidth()) {
461                 case 4:
462                     // 32-bit...
463                     startup_printf("%s[%u]:  setting 32-bit mode\n",
464                         FILE__,__LINE__);
465                     ia32_set_mode_64(false);
466                     break;
467                 case 8:
468                     startup_printf("%s[%u]:  setting 64-bit mode\n",
469                         FILE__,__LINE__);
470                     ia32_set_mode_64(true);
471                     break;
472                 default:
473                     assert(0 && "Illegal address width");
474                     break;
475             }
476
477             instruction insn;
478             insn.setInstruction( p );
479             Address mainAddress = 0;
480
481             // Create a temporary SymtabCodeSource that we can use for parsing. 
482             // We're going to throw it away when we're done so that we can re-sync
483             // with the new symbols we're going to add shortly. 
484             bool parseInAllLoadableRegions = (BPatch_normalMode != mode_);
485             SymtabCodeSource scs(linkedFile, filt, parseInAllLoadableRegions);
486
487 #if !defined(os_freebsd)
488             const unsigned char *lastP = 0;
489             while( !insn.isCall() )
490             {
491                 lastP = p;
492                 p += insn.size();
493                 insn.setInstruction( p );
494             }
495
496             // We _really_ can't handle a call with nothing before it....
497             assert(lastP);
498
499             // FIXME: this assumes that the instruction immediately before the call sets
500             // the main address - this may not be true.
501             instruction preCall;
502             preCall.setInstruction(lastP);
503
504             mainAddress = get_immediate_operand(&preCall);
505 #else
506             // Heuristic: main is the target of the 4th call in the text section
507             using namespace Dyninst::InstructionAPI;
508
509             unsigned bytesSeen = 0, numCalls = 0;
510             InstructionDecoder decoder(p, textsec->getRegionSize(), scs.getArch());
511
512             Instruction::Ptr curInsn = decoder.decode();
513             while( numCalls < 4 && curInsn && curInsn->isValid() &&
514                    bytesSeen < textsec->getRegionSize())
515             {
516                 InsnCategory category = curInsn->getCategory();
517                 if( category == c_CallInsn ) {
518                     numCalls++;
519                 }
520
521                 if( numCalls < 4 ) {
522                     bytesSeen += curInsn->size();
523                     curInsn = decoder.decode();
524                 }
525             }
526
527             if( numCalls != 4 ) {
528                 logLine("heuristic for finding global constructor function failed\n");
529             }else{
530                 Address callAddress = textsec->getRegionAddr() + bytesSeen;
531                 RegisterAST thePC = RegisterAST(Dyninst::MachRegister::getPC(scs.getArch()));
532
533                 Expression::Ptr callTarget = curInsn->getControlFlowTarget();
534
535                 if( callTarget.get() ) {
536                     callTarget->bind(&thePC, Result(s64, callAddress));
537                     Result actualTarget = callTarget->eval();
538                     if( actualTarget.defined ) {
539                         mainAddress = actualTarget.convert<Address>();
540                     }
541                 }
542             }
543 #endif
544
545             if(!mainAddress || !scs.isValidAddress(mainAddress)) {
546                 startup_printf("%s[%u]:  invalid main address 0x%lx\n",
547                     FILE__, __LINE__, mainAddress);   
548             } else {
549                 startup_printf("%s[%u]:  set main address to 0x%lx\n",
550                     FILE__,__LINE__,mainAddress);
551             }
552
553             /* Note: creating a symbol for main at the invalid address 
554                anyway, because there is guard code for this later in the
555                process and otherwise we end up in a weird "this is not an
556                a.out" path.
557
558                findMain, like all important utility functions, should have
559                a way of gracefully indicating that it has failed. It should
560                not return void. NR
561             */
562
563             Region *pltsec;
564             if((linkedFile->findRegion(pltsec, ".plt")) && pltsec->isOffsetInRegion(mainAddress))
565             {
566                 //logLine( "No static symbol for function main\n" );
567                 Symbol *newSym = new Symbol("DYNINST_pltMain", 
568                                             Symbol::ST_FUNCTION, 
569                                             Symbol::SL_GLOBAL,
570                                             Symbol::SV_DEFAULT,
571                                             mainAddress,
572                                             linkedFile->getDefaultModule(),
573                                             textsec, 
574                                             0 );
575                 linkedFile->addSymbol( newSym );
576            }
577            else
578            {
579                 Symbol *newSym= new Symbol( "main", 
580                                             Symbol::ST_FUNCTION,
581                                             Symbol::SL_GLOBAL, 
582                                             Symbol::SV_DEFAULT, 
583                                             mainAddress,
584                                             linkedFile->getDefaultModule(),
585                                             textsec, 
586                                             0 );
587                 linkedFile->addSymbol(newSym);          
588             }
589         }
590         if( !foundStart )
591         {
592             Symbol *startSym = new Symbol( "_start",
593                                            Symbol::ST_FUNCTION,
594                                            Symbol::SL_GLOBAL,
595                                            Symbol::SV_DEFAULT, 
596                                            textsec->getRegionAddr(),
597                                            linkedFile->getDefaultModule(),
598                                            textsec,
599                                            0 );
600             //cout << "sim for start!" << endl;
601         
602             linkedFile->addSymbol(startSym);            
603         }
604         if( !foundFini )
605         {
606           Region *finisec = NULL;
607           if (linkedFile->findRegion(finisec,".fini")) {
608             Symbol *finiSym = new Symbol( "_fini",
609                                           Symbol::ST_FUNCTION,
610                                           Symbol::SL_GLOBAL, 
611                                           Symbol::SV_DEFAULT, 
612                                           finisec->getRegionAddr(),
613                                           linkedFile->getDefaultModule(),
614                                           finisec, 
615                                           0 );
616             linkedFile->addSymbol(finiSym);     
617           }     
618         }
619     }
620
621     Region *dynamicsec;
622     vector < Symbol *>syms;
623     if(linkedFile->findRegion(dynamicsec, ".dynamic")==true)
624     {
625         if(linkedFile->findSymbol(syms,
626                                   "_DYNAMIC",
627                                   Symbol::ST_UNKNOWN,
628                                   SymtabAPI::mangledName)==false)
629         {
630             Symbol *newSym = new Symbol( "_DYNAMIC", 
631                                         Symbol::ST_OBJECT, 
632                                          Symbol::SL_GLOBAL, 
633                                          Symbol::SV_DEFAULT,
634                                          dynamicsec->getRegionAddr(), 
635                                          linkedFile->getDefaultModule(),
636                                          dynamicsec, 
637                                          0 );
638             linkedFile->addSymbol(newSym);
639         }
640     }
641     
642 #elif defined(rs6000_ibm_aix4_1) || defined(rs6000_ibm_aix5_1)
643    
644    bool foundMain = false;
645    vector <SymtabAPI::Function *> funcs;
646    if (linkedFile->findFunctionsByName(funcs, "main") ||
647        linkedFile->findFunctionsByName(funcs, "usla_main"))
648        foundMain = true;
649
650    Region *sec = NULL;
651    bool found = linkedFile->findRegion(sec, ".text");   
652
653    if( !foundMain && linkedFile->isExec() && found )
654    {
655        //we havent found a symbol for main therefore we have to parse _start
656        //to find the address of main
657
658        //last two calls in _start are to main and exit
659        //find the end of _start then back up to find the target addresses
660        //for exit and main
661       
662        int c;
663        int calls = 0;
664        Word *code_ptr_ = (Word *) sec->getPtrToRawData();
665        
666        for( c = 0; code_ptr_[ c ] != 0; c++ );
667
668        instruction i;
669        while( c > 0 )
670        {
671            i.setInstruction((codeBuf_t*)(&code_ptr_[ c ]));
672
673            if(IFORM_LK(i) && 
674               ((IFORM_OP(i) == Bop) || (BFORM_OP(i) == BCop) ||
675                ((XLFORM_OP(i) == BCLRop) && 
676                 ((XLFORM_XO(i) == 16) || (XLFORM_XO(i) == 528)))))
677            {
678                calls++;
679                if( calls == 2 )
680                    break;
681            }
682            c--;
683        }
684        
685        Offset currAddr = sec->getRegionAddr() + c * instruction::size();
686        Offset mainAddr = 0;
687        
688        if( ( IFORM_OP(i) == Bop ) || ( BFORM_OP(i) == BCop ) )
689        {
690            int disp = 0;
691            if(IFORM_OP(i) == Bop)
692            {
693                disp = IFORM_LI(i);
694            }
695            else if(BFORM_OP(i) == BCop)
696            {
697                disp = BFORM_BD(i);
698            }
699
700            disp <<= 2;
701
702            if(IFORM_AA(i))
703            {
704                mainAddr = (Offset)disp;
705            }
706            else
707                mainAddr = (Offset)( currAddr + disp );      
708        }  
709        
710        Symbol *sym = new Symbol( "main", 
711                                  Symbol::ST_FUNCTION,
712                                  Symbol::SL_GLOBAL,
713                                  Symbol::SV_DEFAULT, 
714                                  mainAddr,
715                                  linkedFile->getDefaultModule(),
716                                  sec);
717        linkedFile->addSymbol(sym);
718       
719    
720        //since we are here make up a sym for _start as well
721
722        Symbol *sym1 = new Symbol( "__start", 
723                                   Symbol::ST_FUNCTION,
724                                   Symbol::SL_GLOBAL, 
725                                   Symbol::SV_DEFAULT, 
726                                   sec->getRegionAddr(), 
727                                   linkedFile->getDefaultModule(),
728                                   sec);
729        linkedFile->addSymbol(sym1);
730    }
731
732 #elif defined(i386_unknown_nt4_0)
733
734 #define NUMBER_OF_MAIN_POSSIBILITIES 7
735    char main_function_names[NUMBER_OF_MAIN_POSSIBILITIES][20] = {
736        "main",
737        "DYNINST_pltMain",
738        "_main",
739        "WinMain",
740        "_WinMain",
741        "wWinMain",
742        "_wWinMain"};
743    
744    if(linkedFile->isExec()) {
745        vector <Symbol *>syms;
746        vector<SymtabAPI::Function *> funcs;
747        Address eAddr = linkedFile->getEntryOffset();
748        
749        bool found_main = false;
750        for (unsigned i=0; i<NUMBER_OF_MAIN_POSSIBILITIES; i++) {
751            if(linkedFile->findFunctionsByName(funcs, main_function_names[i])) {
752                found_main = true;
753                break;
754            }
755        }
756        if (!found_main) {
757            syms.clear();
758            if(!linkedFile->findSymbol(syms,"start",Symbol::ST_UNKNOWN, SymtabAPI::mangledName)) {
759                //use 'start' for mainCRTStartup.
760                Symbol *startSym = new Symbol( "start", 
761                                               Symbol::ST_FUNCTION,
762                                               Symbol::SL_GLOBAL, 
763                                               Symbol::SV_DEFAULT, 
764                                               eAddr ,
765                                               linkedFile->getDefaultModule(),
766                                               NULL,
767                                               UINT_MAX );
768                linkedFile->addSymbol(startSym);
769            }
770            syms.clear();
771            if(!linkedFile->findSymbol(syms,"winStart",Symbol::ST_UNKNOWN, SymtabAPI::mangledName)) {
772                //make up a func name for the start of the text section
773                Symbol *sSym = new Symbol( "winStart", 
774                                           Symbol::ST_FUNCTION,
775                                           Symbol::SL_GLOBAL,
776                                           Symbol::SV_DEFAULT, 
777                                           imageOffset_,
778                                           linkedFile->getDefaultModule(),
779                                           NULL, 
780                                           UINT_MAX );
781                linkedFile->addSymbol(sSym);
782            }
783            syms.clear();
784            if(!linkedFile->findSymbol(syms,"winFini",Symbol::ST_UNKNOWN, SymtabAPI::mangledName)) {
785                //make up one for the end of the text section
786                Symbol *fSym = new Symbol( "winFini", 
787                                           Symbol::ST_FUNCTION,
788                                           Symbol::SL_GLOBAL, 
789                                           Symbol::SV_DEFAULT, 
790                                           imageOffset_ + linkedFile->imageLength() - 1, 
791                                           linkedFile->getDefaultModule(),
792                                           NULL, 
793                                           UINT_MAX );
794                linkedFile->addSymbol(fSym);
795            }
796            // add entry point as main given that nothing else was found
797            startup_printf("[%s:%u] - findmain could not find symbol "
798                           "for main, using binary entry point %x\n",
799                           __FILE__, __LINE__, eAddr);
800            linkedFile->addSymbol(new Symbol("main",
801                                             Symbol::ST_FUNCTION, 
802                                             Symbol::SL_GLOBAL, 
803                                             Symbol::SV_DEFAULT,
804                                             eAddr,
805                                             linkedFile->getDefaultModule()));
806        }
807    }
808 #endif
809 }
810
811 /*
812  * We do a search for a "main" symbol (a couple of variants), and
813  * if found we flag this image as the executable (a.out). 
814  */
815 bool image::determineImageType()
816 {
817 #if defined(TIMED_PARSE)
818   struct timeval starttime;
819   gettimeofday(&starttime, NULL);
820 #endif
821
822   //Checking "main" function names in same order as in the inst-*.C files
823   vector <SymtabAPI::Function *>funcs;
824   if (linkedFile->findFunctionsByName(funcs,"main")       ||
825       linkedFile->findFunctionsByName(funcs,"_main")     
826 #if defined(os_windows)
827       || linkedFile->findFunctionsByName(funcs,"WinMain")   ||
828       linkedFile->findFunctionsByName(funcs,"_WinMain")  ||
829       linkedFile->findFunctionsByName(funcs,"wWinMain")  ||
830       linkedFile->findFunctionsByName(funcs,"_wWinMain") 
831 #endif
832       ) {
833       is_a_out = true;
834   }
835   else
836       is_a_out = false;
837   
838   // Checking for libdyninstRT (DYNINSTinit())
839   if (linkedFile->findFunctionsByName(funcs, "DYNINSTinit") ||
840       linkedFile->findFunctionsByName(funcs, "_DYNINSTinit"))
841       is_libdyninstRT = true;
842   else
843       is_libdyninstRT = false;
844    
845 #if defined(TIMED_PARSE)
846   struct timeval endtime;
847   gettimeofday(&endtime, NULL);
848   unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
849   unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
850   unsigned long difftime = lendtime - lstarttime;
851   double dursecs = difftime/(1000 );
852   cout << __FILE__ << ":" << __LINE__ <<": determineImageType took "<<dursecs <<" msecs" << endl;
853 #endif
854   return true;
855 }
856
857 bool image::getInferiorHeaps(vector<pair<string,Address> > &codeHeaps,
858                              vector<pair<string,Address> > &dataHeaps) {
859     if ((codeHeaps_.size() == 0) &&
860         (dataHeaps_.size() == 0)) return false;
861
862     for (unsigned i = 0; i < codeHeaps_.size(); i++) {
863         codeHeaps.push_back(codeHeaps_[i]);
864     }
865
866     for (unsigned i = 0; i < dataHeaps_.size(); i++) {
867         dataHeaps.push_back(dataHeaps_[i]);
868     }
869     return true;
870 }
871
872 bool image::addSymtabVariables()
873 {
874    /* Eventually we'll have to do this on all platforms (because we'll retrieve
875     * the type information here).
876     */
877    
878 #if defined(TIMED_PARSE)
879    struct timeval starttime;
880    gettimeofday(&starttime, NULL);
881 #endif
882
883    std::string mangledName; 
884
885    vector<Variable *> allVars;
886
887    linkedFile->getAllVariables(allVars); 
888
889    for (vector<Variable *>::iterator varIter = allVars.begin();
890         varIter != allVars.end(); 
891         varIter++) {
892        Variable *symVar = *varIter;
893
894        parsing_printf("New variable, mangled %s, module %s...\n",
895                       symVar->getAllMangledNames()[0].c_str(),
896                       symVar->getFirstSymbol()->getModuleName().c_str());
897        pdmodule *use = getOrCreateModule(symVar->getModule());
898
899        assert(use);
900        image_variable *var = new image_variable(symVar, use);
901        if (!var->svar()->addAnnotation(var, ImageVariableUpPtrAnno)) {
902            fprintf(stderr, "%s[%d]: failed to add annotation here\n", FILE__, __LINE__);
903            return false;
904        }
905
906        // If this is a Dyninst dynamic heap placeholder, add it to the
907        // list of inferior heaps...
908        string compString = "DYNINSTstaticHeap";
909        if (!var->symTabName().compare(0, compString.size(), compString)) {
910            dataHeaps_.push_back(pair<string,Address>(var->symTabName(), var->getOffset()));
911        }
912
913        exportedVariables.push_back(var);
914        everyUniqueVariable.push_back(var);
915        varsByAddr[var->getOffset()] = var;
916    }
917
918 #if defined(TIMED_PARSE)
919    struct timeval endtime;
920    gettimeofday(&endtime, NULL);
921    unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
922    unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
923    unsigned long difftime = lendtime - lstarttime;
924    double dursecs = difftime/(1000 );
925    cout << __FILE__ << ":" << __LINE__ <<": addSymtabVariables took "<<dursecs <<" msecs" << endl;
926 #endif
927
928    return true;
929 }
930
931 pdmodule *image::findModule(const string &name, bool wildcard)
932 {
933    pdmodule *found = NULL;
934    //cerr << "image::findModule " << name << " , " << find_if_excluded
935    //     << " called" << endl;
936
937    if (!wildcard) {
938       if (modsByFileName.find(name) != modsByFileName.end()) {
939          //cerr << " (image::findModule) found module in modsByFileName" << endl;
940          found = modsByFileName[name];
941       }
942       else if (modsByFullName.find(name) != modsByFullName.end()) {
943          //cerr << " (image::findModule) found module in modsByFullName" << endl;
944          found = modsByFullName[name];
945       }
946    }
947    else {
948       //  if we want a substring, have to iterate over all module names
949       //  this is ok b/c there are not usually more than a handful or so
950       //
951       dyn_hash_map <string, pdmodule *>::iterator mi;
952       string str; pdmodule *mod;
953       std::string pds = name.c_str();
954
955       for(mi = modsByFileName.begin(); mi != modsByFileName.end() ; mi++)
956       {
957          str = mi->first;
958          mod = mi->second;
959          if (wildcardEquiv(pds, mod->fileName()) ||
960                wildcardEquiv(pds, mod->fullName())) {
961             found = mod; 
962             break;
963          }
964       }
965    }
966
967    //cerr << " (image::findModule) did not find module, returning NULL" << endl;
968    if (found) {
969       // Just-in-time...
970       //if (parseState_ == symtab)
971       //analyzeImage();
972       return found;
973    }
974
975    return NULL;
976 }
977
978 image_instPoint *
979 image::getInstPoint(Address addr)
980 {
981     analyzeIfNeeded();
982     instp_map_t::iterator iit = inst_pts_.find(addr);
983     if(iit != inst_pts_.end())
984         return iit->second;
985     return NULL;
986 }
987 void
988 image::getInstPoints(Address start, Address end,
989     pdvector<image_instPoint *> & points)
990 {
991     analyzeIfNeeded();
992     instp_map_t::iterator iit = inst_pts_.lower_bound(start);
993     while(iit != inst_pts_.end() && iit->second->offset() < end) {
994         points.push_back(iit->second);
995         ++iit;
996     }
997 }
998 bool
999 image::addInstPoint(image_instPoint *p)
1000 {
1001     if(inst_pts_.find(p->offset()) != inst_pts_.end()) {   
1002         parsing_printf("  attempt to add duplicate instpoint at %lx\n",
1003             p->offset());
1004         return false;
1005     }
1006     inst_pts_[p->offset()] = p;
1007     return true;
1008 }
1009
1010 CodeObject::funclist &
1011 image::getAllFunctions()
1012 {
1013     analyzeIfNeeded();
1014     return codeObject()->funcs();
1015 }
1016
1017 const pdvector<image_variable*> &image::getAllVariables()
1018 {
1019     analyzeIfNeeded();
1020     return everyUniqueVariable;
1021 }
1022
1023 const pdvector<image_variable*> &image::getExportedVariables() const { return exportedVariables; }
1024
1025 const pdvector<image_variable*> &image::getCreatedVariables()
1026 {
1027   analyzeIfNeeded();
1028   return createdVariables;
1029 }
1030
1031 bool image::getModules(vector<pdmodule *> &mods) 
1032 {
1033     bool ret = false;
1034    pdvector<pdmodule *> toReturn;
1035     for (map<Module *, pdmodule *>::const_iterator iter = mods_.begin();
1036          iter != mods_.end(); iter++) {
1037         ret = true;
1038         mods.push_back(iter->second);
1039     }
1040     return ret;
1041 }
1042
1043 // identify module name from symbol address (binary search)
1044 // based on module tags found in file format (ELF/COFF)
1045 void image::findModByAddr (const Symbol *lookUp, vector<Symbol *> &mods,
1046                            string &modName, Address &modAddr, 
1047                            const string &defName)
1048 {
1049   if (mods.size() == 0) {
1050     modAddr = 0;
1051     modName = defName;
1052     return;
1053   }
1054
1055   Address symAddr = lookUp->getAddr();
1056   int index;
1057   int start = 0;
1058   int end = mods.size() - 1;
1059   int last = end;
1060   bool found = false;
1061   while ((start <= end) && !found) {
1062     index = (start+end)/2;
1063     if ((index == last) ||
1064         ((mods[index]->getAddr() <= symAddr) && 
1065          (mods[index+1]->getAddr() > symAddr))) {
1066       modName = mods[index]->getName().c_str();
1067       modAddr = mods[index]->getAddr();      
1068       found = true;
1069     } else if (symAddr < mods[index]->getAddr()) {
1070       end = index - 1;
1071     } else {
1072       start = index + 1;
1073     }
1074   }
1075   if (!found) { 
1076     // must be (start > end)
1077     modAddr = 0;
1078     modName = defName;
1079   }
1080 }
1081
1082 unsigned int int_addrHash(const Address& addr) {
1083   return (unsigned int)addr;
1084 }
1085
1086 /*
1087  * load an executable:
1088  *   1.) parse symbol table and identify rotuines.
1089  *   2.) scan executable to identify inst points.
1090  *
1091  *  offset is normally zero except on CM-5 where we have two images in one
1092  *    file.  The offset passed to parseImage is the logical offset (0/1), not
1093  *    the physical point in the file.  This makes it faster to "parse" multiple
1094  *    copies of the same image since we don't have to stat and read to find the
1095  *    physical offset. 
1096  */
1097
1098 image *image::parseImage(fileDescriptor &desc, 
1099                          BPatch_hybridMode mode, 
1100                          bool parseGaps)
1101 {
1102   /*
1103    * Check to see if we have parsed this image before. We will
1104    * consider it a match if the filename matches (Our code is now able
1105    * to cache the parsing results even if a library is loaded at a
1106    * different address for the second time).
1107    */
1108   unsigned numImages = allImages.size();
1109   
1110   // AIX: it's possible that we're reparsing a file with better information
1111   // about it. If so, yank the old one out of the images vector -- replace
1112   // it, basically.
1113   for (unsigned u=0; u<numImages; u++) {
1114       if (desc.isSameFile(allImages[u]->desc())) {
1115          if (allImages[u]->getObject()->canBeShared()) {
1116             // We reference count...
1117             startup_printf("%s[%d]: returning pre-parsed image\n", FILE__, __LINE__);
1118             return allImages[u]->clone();
1119          }
1120       }
1121   }
1122
1123   stats_parse.startTimer(PARSE_SYMTAB_TIMER);
1124
1125   /*
1126    * load the symbol table. (This is the a.out format specific routine).
1127    */
1128   
1129   bool err=false;
1130
1131 #if defined(TIMED_PARSE)
1132   struct timeval starttime;
1133   gettimeofday(&starttime, NULL);
1134 #endif
1135
1136   startup_printf("%s[%d]:  about to create image\n", FILE__, __LINE__);
1137   image *ret = new image(desc, err, mode, parseGaps); 
1138   startup_printf("%s[%d]:  created image\n", FILE__, __LINE__);
1139
1140   if(desc.isSharedObject()) 
1141       startup_printf("%s[%d]: processing shared object\n", FILE__, __LINE__);
1142   else  
1143       startup_printf("%s[%d]: processing executable object\n", FILE__, __LINE__);
1144       
1145
1146 #if defined(TIMED_PARSE)
1147   struct timeval endtime;
1148   gettimeofday(&endtime, NULL);
1149   unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
1150   unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
1151   unsigned long difftime = lendtime - lstarttime;
1152   double dursecs = difftime/(1000 );
1153   cout << __FILE__ << ":" << __LINE__ <<": parsing image "<< desc.file().c_str() <<" took "<<dursecs <<" msecs" << endl;
1154 #endif
1155
1156   if (err || !ret) {
1157      if (ret) {
1158          startup_printf("%s[%d]: error in processing, deleting image and returning\n",
1159                         FILE__, __LINE__);
1160          delete ret;
1161      }
1162      else {
1163         fprintf(stderr, "Failed to allocate memory for parsing %s!\n", 
1164                 desc.file().c_str());
1165      }
1166      stats_parse.stopTimer(PARSE_SYMTAB_TIMER);
1167      return NULL;
1168   }
1169
1170   allImages.push_back(ret);
1171
1172   // start tracking new blocks after initial parse
1173   if ( BPatch_exploratoryMode == mode ||
1174        BPatch_defensiveMode == mode ) 
1175   {
1176       ret->trackNewBlocks_ = true;
1177   }
1178
1179   // define all modules.
1180
1181   statusLine("ready"); // this shouldn't be here, right? (cuz we're not done, right?)
1182   stats_parse.stopTimer(PARSE_SYMTAB_TIMER);
1183
1184   return ret;
1185 }
1186
1187 /*
1188  * Remove a parsed executable from the global list. Used if the old handle
1189  * is no longer valid.
1190  */
1191 void image::removeImage(image *img)
1192 {
1193
1194   // Here's a question... do we want to actually delete images?
1195   // Pro: free up memory. Con: we'd just have to parse them again...
1196   // I guess the question is "how often do we serially open files".
1197   /* int refCount = */ img->destroy();
1198   
1199
1200   /*
1201     // We're not deleting when the refcount hits 0, so we may as well
1202     // keep the vector. It's a time/memory problem. 
1203   if (refCount == 0) {
1204     pdvector<image*> newImages;
1205     // It's gone... remove from image vector
1206     for (unsigned i = 0; i < allImages.size(); i++) {
1207       if (allImages[i] != img)
1208         newImages.push_back(allImages[i]);
1209     }
1210     allImages = newImages;
1211   }
1212   */
1213 }
1214
1215 void image::removeImage(const string file)
1216 {
1217   image *img = NULL;
1218   for (unsigned i = 0; i < allImages.size(); i++) {
1219     if (allImages[i]->file() == file)
1220       img = allImages[i];
1221   }
1222   // removeImage plays with the allImages vector... so do this
1223   // outside the for loop.
1224   if (img) image::removeImage(img);
1225 }
1226
1227 void image::removeImage(fileDescriptor &desc)
1228 {
1229   image *img = NULL;
1230   for (unsigned i = 0; i < allImages.size(); i++) {
1231     // Never bothered to implement a != operator
1232     if (allImages[i]->desc() == desc)
1233       img = allImages[i];
1234   }
1235   if (img) image::removeImage(img);
1236 }
1237
1238 int image::destroy() {
1239     refCount--;
1240     if (refCount == 0) {
1241         if (!desc().isSharedObject()) {
1242             // a.out... destroy it
1243             //delete this;
1244             return 0;
1245         }
1246     }
1247     if (refCount < 0)
1248         assert(0 && "NEGATIVE REFERENCE COUNT FOR IMAGE!");
1249     return refCount; 
1250 }
1251
1252 void image::removeInstPoint(image_instPoint *p)
1253 {
1254     instp_map_t::iterator iit = inst_pts_.find(p->offset());
1255     if(iit != inst_pts_.end())
1256         inst_pts_.erase(iit);
1257 }
1258
1259 void image::deleteFunc(image_func *func)
1260 {
1261     // Remove the function's points, but not points that are shared
1262     // with other functions since they might not be going away. 
1263     vector<FuncExtent *>::const_iterator eit = func->extents().begin();
1264     set<ParseAPI::Function *> pt_funcs;
1265     for( ; eit != func->extents().end(); ++eit) {
1266         FuncExtent * fe = *eit;
1267         pdvector<image_instPoint *> pts;
1268         getInstPoints(fe->start(),fe->end(),pts);
1269         for(unsigned i=0;i<pts.size();++i) {
1270             image_instPoint *p = pts[i];
1271             findFuncs(p->offset(), pt_funcs);
1272             if ( 1 == pt_funcs.size() )
1273                 removeInstPoint(p);
1274             pt_funcs.clear();
1275         }
1276     }
1277     // Remove the function's entry point whether it is shared or not
1278     image_instPoint *p = getInstPoint(func->getOffset());
1279     if (p) 
1280         removeInstPoint(p);
1281
1282     // remove the function from symtabAPI
1283     SymtabAPI::Function *sym_func =NULL;
1284     getObject()->findFuncByEntryOffset(sym_func, func->getOffset());
1285     if (sym_func) 
1286         getObject()->deleteFunction(sym_func);
1287
1288     // tell the parseAPI to remove the func from its datastructures
1289     // and delete the function
1290     codeObject()->deleteFunc(func);
1291
1292 }
1293
1294 extern void codeBytesUpdateCB(void *objCB, Region *reg, Address addr);
1295 void image::call_codeBytesUpdateCB(Region *reg, Address addr)
1296 {
1297     assert(BPatch_normalMode != mode_);
1298     codeBytesUpdateCB(cb_arg0_, reg, addr + desc().loadAddr());
1299 }
1300
1301
1302 #if 0   // FIXME ensure all necessary functionality preserved
1303 // Enter a function in all the appropriate tables
1304 void image::enterFunctionInTables(image_func *func) {
1305     if (!func) return;
1306
1307     parsing_printf("[%s:%u] entering function at %lx (%s) in tables\n",
1308         FILE__,__LINE__,func->getOffset(),func->symTabName().c_str());
1309
1310     funcsByEntryAddr[func->getOffset()] = func;
1311    
1312     // XXX the origin & meaning of the following comment is unknown; preserving.
1313     // TODO: out-of-line insertion here
1314     if(func->get_size()) {
1315         funcsByRange.insert(func);
1316     }
1317
1318     // This has already been done for symtab functions
1319     if(func->src() != HINT) {
1320         Symbol *sym = func->getSymtabFunction()->getFirstSymbol();
1321         getObject()->addSymbol(sym);
1322     }
1323    
1324     if(func->src() == HINT)
1325         exportedFunctions.push_back(func);
1326     else
1327         createdFunctions.push_back(func);
1328 }  
1329 #endif
1330
1331 void image::analyzeIfNeeded() {
1332   if (parseState_ == symtab) {
1333       parsing_printf("ANALYZING IMAGE %s\n",
1334               file().c_str());
1335       analyzeImage();
1336   }
1337 }
1338
1339 void image::analyzeImage() {
1340 #if defined(TIMED_PARSE)
1341     struct timeval starttime;
1342     gettimeofday(&starttime, NULL);
1343 #endif
1344
1345     stats_parse.startTimer(PARSE_ANALYZE_TIMER);
1346
1347 // FIXME necessary?
1348 #if defined(arch_x86_64)
1349     ia32_set_mode_64(getObject()->getAddressWidth() == 8);
1350 #endif
1351
1352     assert(parseState_ < analyzed);
1353     if(parseState_ < symtab){
1354         fprintf(stderr, "Error: attempt to analyze incomplete image\n");
1355         goto done;
1356     }
1357     parseState_ = analyzing;
1358
1359     obj_->parse();
1360
1361 #if defined(os_solaris) || defined(os_aix)
1362   {
1363   image_parRegion *parReg;
1364   int currentSectionNum = 0;
1365
1366   // Most of the time there will be no parallel regions in an image, so nothing will happen.
1367   // If there is a parallel region we examine it individually 
1368   for (unsigned i = 0; i < parallelRegions.size(); i++)
1369     {
1370       parReg = parallelRegions[i];
1371       if (parReg == NULL)
1372     continue;
1373       else
1374     {
1375       // Every parallel region has the image_func that contains the
1376       //   region associated with it 
1377             image_func * imf = const_cast<image_func*>(parReg->getAssociatedFunc());
1378       
1379       // Returns pointers to all potential image_funcs that correspond
1380       //   to what could be the parent OpenMP function for the region 
1381       const pdvector<image_func *> *prettyNames =
1382         findFuncVectorByPretty(imf->calcParentFunc(imf, parallelRegions));
1383       
1384       //There may be more than one (or none) functions with that name, we take the first 
1385       // This function gives us all the information about the parallel region by getting
1386       // information for the parallel region parent function  
1387       if (prettyNames->size() > 0)
1388         imf->parseOMP(parReg, (*prettyNames)[0], currentSectionNum);
1389       else
1390         continue;
1391     }
1392     }
1393   }
1394   /**************************/
1395   /* END OpenMP Parsing Code */
1396   /**************************/
1397
1398 #endif
1399
1400 #if defined(cap_stripped_binaries)
1401    {
1402        vector<CodeRegion *>::const_iterator rit = cs_->regions().begin();
1403        for( ; rit != cs_->regions().end(); ++rit)
1404        {
1405         SymtabCodeRegion * scr = static_cast<SymtabCodeRegion*>(*rit);
1406         if(parseGaps_ && scr->symRegion()->isText()) {
1407             obj_->parseGaps(scr);
1408         }
1409        } 
1410    }
1411 #endif // cap_stripped_binaries
1412     
1413     parseState_ = analyzed;
1414   done:
1415     stats_parse.stopTimer(PARSE_ANALYZE_TIMER); 
1416
1417 #if defined(TIMED_PARSE)
1418     struct timeval endtime;
1419     gettimeofday(&endtime, NULL);
1420     unsigned long lstarttime = starttime.tv_sec * 1000*1000+starttime.tv_usec;
1421     unsigned long lendtime = endtime.tv_sec * 1000*1000+endtime.tv_usec;
1422     unsigned long difftime = lendtime - lstarttime;
1423     double dursecs = difftime/(1000 );
1424     cout << __FILE__ << ":" << __LINE__ <<": analyzeImage of " << name_ << " took "<<dursecs <<" msecs" << endl;
1425 #endif
1426 }
1427
1428 // Constructor for the image object. The fileDescriptor simply
1429 // wraps (in the normal case) the object name and a relocation
1430 // address (0 for a.out file). On the following platforms, we
1431 // are handling a special case:
1432 //   AIX: objects can possibly have a name like /lib/libc.so:shr.o
1433 //          since libraries are archives
1434 //        Both text and data sections have a relocation address
1435
1436
1437 image::image(fileDescriptor &desc, 
1438              bool &err, 
1439              BPatch_hybridMode mode, 
1440              bool parseGaps) :
1441    desc_(desc),
1442    activelyParsing(addrHash4),
1443    is_libdyninstRT(false),
1444    is_a_out(false),
1445    main_call_addr_(0),
1446    nativeCompiler(false),    
1447    obj_(NULL),
1448    cs_(NULL),
1449    img_fact_(NULL),
1450    parse_cb_(NULL),
1451    nextBlockID_(0),
1452    pltFuncs(NULL),
1453    varsByAddr(addrHash4),
1454    trackNewBlocks_(false),
1455    refCount(1),
1456    parseState_(unparsed),
1457    parseGaps_(parseGaps),
1458    mode_(mode),
1459    arch(Dyninst::Arch_none)
1460 {
1461
1462 #if defined(os_aix)
1463    archive = NULL;
1464    string file = desc_.file().c_str();
1465    SymtabAPI::SymtabError serr = SymtabAPI::Not_An_Archive;
1466
1467    startup_printf("%s[%d]:  opening file %s (or archive)\n", FILE__, __LINE__, file.c_str());
1468    if (!SymtabAPI::Archive::openArchive(archive, file))
1469    {
1470       err = true;
1471       if (archive->getLastError() != serr) {
1472          startup_printf("%s[%d]:  opened archive\n", FILE__, __LINE__);
1473          return;
1474       }
1475       else
1476       {
1477          startup_printf("%s[%d]:  opening file (not archive)\n", FILE__, __LINE__);
1478          if (!SymtabAPI::Symtab::openFile(linkedFile, file)) 
1479          {
1480             startup_printf("%s[%d]:  opening file (not archive) failed\n", FILE__, __LINE__);
1481             err = true;
1482             return;
1483          }
1484          startup_printf("%s[%d]:  opened file\n", FILE__, __LINE__);
1485       }
1486    }
1487    else
1488    {
1489       assert (archive);
1490       startup_printf("%s[%d]:  getting member\n", FILE__, __LINE__);
1491       string member = std::string(desc_.member());
1492       if (member == fileDescriptor::emptyString) {
1493          fprintf(stderr, "%s[%d]:  WARNING:  not asking for unnamed member\n", FILE__, __LINE__);
1494       }
1495       else {
1496          if (!archive->getMember(linkedFile, member))
1497          {
1498             startup_printf("%s[%d]:  getting member failed\n", FILE__, __LINE__);
1499             err = true;
1500             return;
1501          }
1502          startup_printf("%s[%d]:  got member\n", FILE__, __LINE__);
1503       }
1504    }
1505    startup_printf("%s[%d]:  opened file %s (or archive)\n", FILE__, __LINE__, file.c_str());
1506 #elif defined(os_linux) || defined(os_solaris) || defined(os_freebsd)
1507    string file = desc_.file().c_str();
1508    if( desc_.member().empty() ) {
1509        startup_printf("%s[%d]:  opening file %s\n", FILE__, __LINE__, file.c_str());
1510        if( !SymtabAPI::Symtab::openFile(linkedFile, file) ) {
1511            err = true;
1512            return;
1513        }
1514    }else{
1515        startup_printf("%s[%d]: opening archive member: %s(%s)\n", FILE__, __LINE__, file.c_str(),
1516                desc_.member().c_str());
1517
1518        if( SymtabAPI::Archive::openArchive(archive, file) ) {
1519            if( !archive->getMember(linkedFile, const_cast<std::string&>(desc_.member())) ) {
1520                err = true;
1521                return;
1522            }
1523        }else{
1524            err = true;
1525            return;
1526        }
1527    }
1528 #elif defined(os_vxworks)
1529    string file = desc_.file();
1530    startup_printf("%s[%d]: opening file %s\n", FILE__, __LINE__, file.c_str());
1531    if( !Symtab::openFile(linkedFile, file) ) {
1532        startup_printf("%s[%d]: %s unavailable. Building info from target.\n",
1533                       FILE__, __LINE__, file.c_str());
1534        MappedFile *mf = MappedFile::createMappedFile(file);
1535        linkedFile = new Symtab::Symtab(mf);
1536    }
1537
1538    // Fill in remaining unknown information from remote target.
1539    fixup_offsets(file, linkedFile);
1540
1541 #else
1542    string file = desc_.file();
1543    startup_printf("%s[%d]: opening file %s\n", FILE__, __LINE__, file.c_str());
1544    if(desc.rawPtr()) {
1545        linkedFile = new SymtabAPI::Symtab((char*)desc.rawPtr(), desc.length(), err);
1546    } 
1547    else if(!SymtabAPI::Symtab::openFile(linkedFile, file)) 
1548    {
1549       err = true;
1550       return;
1551    }
1552 #endif
1553
1554    err = false;
1555
1556    // fix isSharedObject flag in file descriptor
1557    desc.setIsShared(!linkedFile->isExec());
1558    desc_.setIsShared(!linkedFile->isExec());
1559
1560    name_ = extract_pathname_tail(string(desc.file().c_str()));
1561
1562    //   fprintf(stderr,"img name %s\n",name_.c_str());
1563    pathname_ = desc.file().c_str();
1564
1565    // initialize (data members) codeOffset_, dataOffset_,
1566    //  codeLen_, dataLen_.
1567
1568    imageOffset_ = linkedFile->imageOffset();
1569    dataOffset_ = linkedFile->dataOffset();
1570
1571    imageLen_ = linkedFile->imageLength();
1572    dataLen_ = linkedFile->dataLength();
1573
1574    /*
1575     * When working with ELF .o's, it is a possibility that the region
1576     * which is referred to by imageOffset(), imageLength() could have a zero
1577     * length. This is okay for .o's
1578     */
1579
1580    // if unable to parse object file (somehow??), try to
1581    //  notify user/calling process + return....    
1582    if (!imageLen_ && 
1583        linkedFile->getObjectType() != SymtabAPI::obj_RelocatableFile)
1584     {
1585       string msg = string("Parsing problem with executable file: ") + desc.file();
1586       statusLine(msg.c_str());
1587       msg += "\n";
1588       logLine(msg.c_str());
1589       err = true;
1590       return;
1591    }
1592
1593    // Initialize ParseAPI 
1594    filt = NULL;
1595
1596    /** Optionally eliminate some hints in which Dyninst is not
1597        interested **/
1598    struct filt_heap : SymtabCodeSource::hint_filt {
1599         bool operator()(SymtabAPI::Function * f) {
1600             return f->getModule()->fullName() == "DYNINSTheap";
1601         }
1602     } nuke_heap;
1603     filt = &nuke_heap;
1604
1605    //Now add Main and Dynamic Symbols if they are not present
1606    startup_printf("%s[%d]:  before findMain\n", FILE__, __LINE__);
1607    findMain();
1608
1609
1610    bool parseInAllLoadableRegions = (BPatch_normalMode != mode_);
1611    cs_ = new SymtabCodeSource(linkedFile,filt,parseInAllLoadableRegions);
1612    // XXX FIXME having this static member in instPointBase
1613    //     prevents support of multiple architectures simultaneously
1614    instPointBase::setArch(cs_->getArch(), (getObject()->getAddressWidth() == 8));
1615
1616    // Continue ParseAPI init
1617    img_fact_ = new DynCFGFactory(this);
1618    parse_cb_ = new DynParseCallback(this);
1619    obj_ = new CodeObject(cs_,img_fact_,parse_cb_,BPatch_defensiveMode == mode);
1620
1621    string msg;
1622    // give user some feedback....
1623    msg = string("Parsing object file: ") + desc.file();
1624
1625    statusLine(msg.c_str());
1626
1627
1628    // look for `main' or something similar to recognize a.outs
1629    startup_printf("%s[%d]:  before determineImageType\n", FILE__, __LINE__);
1630    determineImageType();
1631    if (isDyninstRTLib()) { // don't parse gaps in the runtime library
1632        parseGaps_ = false;
1633    }
1634             
1635    // And symtab variables
1636    addSymtabVariables();
1637
1638    parseState_ = symtab;
1639 }
1640
1641 image::~image() 
1642 {
1643     unsigned i;
1644
1645     for (map<Module *, pdmodule *>::iterator iter = mods_.begin();
1646          iter != mods_.end(); iter++) {
1647         delete (iter->second);
1648     }
1649
1650     for (i = 0; i < everyUniqueVariable.size(); i++) {
1651         delete everyUniqueVariable[i];
1652     }
1653     everyUniqueVariable.clear();
1654     createdVariables.clear();
1655     exportedVariables.clear();
1656
1657    
1658     for (i = 0; i < parallelRegions.size(); i++)
1659       delete parallelRegions[i];
1660     parallelRegions.clear();
1661
1662     // free instPoints
1663     instp_map_t::iterator iit = inst_pts_.begin();
1664     for( ; iit != inst_pts_.end(); ++iit) {
1665         delete iit->second;
1666     }
1667     
1668     // Finally, remove us from the image list.
1669     for (i = 0; i < allImages.size(); i++) {
1670         if (allImages[i] == this)
1671             VECTOR_ERASE(allImages,i,i);
1672     }
1673
1674     if (pltFuncs) {
1675        delete pltFuncs;
1676        pltFuncs = NULL;
1677     }
1678
1679     if(obj_) delete obj_;
1680     if(cs_) delete cs_;
1681     if(img_fact_) delete img_fact_;
1682     if(parse_cb_) delete parse_cb_;
1683
1684     if (linkedFile) { SymtabAPI::Symtab::closeSymtab(linkedFile); }
1685 #if defined (os_aix)
1686     //fprintf(stderr, "%s[%d]:  IMAGE DTOR:  archive = %p\n", FILE__, __LINE__, archive);
1687     if (archive) delete archive;
1688 #endif
1689 }
1690
1691 bool pdmodule::findFunction( const std::string &name, pdvector<image_func *> &found ) {
1692     if (findFunctionByMangled(name, found))
1693         return true;
1694     return findFunctionByPretty(name, found);
1695 }
1696
1697 bool pdmodule::findFunctionByMangled( const std::string &name,
1698                                       pdvector<image_func *> &found)
1699 {
1700     // For efficiency sake, we grab the image vector and strip out the
1701     // functions we want.
1702     // We could also keep them all in modules and ditch the image-wide search; 
1703     // the problem is that BPatch goes by module and internal goes by image. 
1704     unsigned orig_size = found.size();
1705     
1706     const pdvector<image_func *> *obj_funcs = imExec()->findFuncVectorByMangled(name.c_str());
1707     if (!obj_funcs) {
1708         return false;
1709     }
1710     for (unsigned i = 0; i < obj_funcs->size(); i++) {
1711         if ((*obj_funcs)[i]->pdmod() == this)
1712             found.push_back((*obj_funcs)[i]);
1713     }
1714     if (found.size() > orig_size) {
1715         //exec()->analyzeIfNeeded();
1716         return true;
1717     }
1718     
1719     return false;
1720 }
1721
1722
1723 bool pdmodule::findFunctionByPretty( const std::string &name,
1724                                      pdvector<image_func *> &found)
1725 {
1726     // For efficiency sake, we grab the image vector and strip out the
1727     // functions we want.
1728     // We could also keep them all in modules and ditch the image-wide search; 
1729     // the problem is that BPatch goes by module and internal goes by image. 
1730     unsigned orig_size = found.size();
1731     
1732     const pdvector<image_func *> *obj_funcs = imExec()->findFuncVectorByPretty(name);
1733     if (!obj_funcs) {
1734         return false;
1735     }
1736     for (unsigned i = 0; i < obj_funcs->size(); i++) {
1737         if ((*obj_funcs)[i]->pdmod() == this)
1738             found.push_back((*obj_funcs)[i]);
1739     }
1740     if (found.size() > orig_size) {
1741         //exec()->analyzeIfNeeded();
1742         return true;
1743     }
1744     
1745     return false;
1746 }
1747
1748 void pdmodule::dumpMangled(std::string &prefix) const
1749 {
1750   cerr << fileName() << "::dumpMangled("<< prefix << "): " << endl;
1751
1752   CodeObject::funclist & allFuncs = imExec()->getAllFunctions();
1753   CodeObject::funclist::iterator fit = allFuncs.begin();
1754   for( ; fit != allFuncs.end(); ++fit) {
1755       image_func * pdf = (image_func*)*fit;
1756       if (pdf->pdmod() != this) continue;
1757
1758       if( ! strncmp( pdf->symTabName().c_str(), prefix.c_str(), strlen( prefix.c_str() ) ) ) {
1759           cerr << pdf->symTabName() << " ";
1760       }
1761       else {
1762           // bperr( "%s is not a prefix of %s\n", prefix, pdf->symTabName().c_str() );
1763       }
1764   }
1765   cerr << endl;
1766 }
1767
1768 image_func *image::addFunction(Address functionEntryAddr, const char *fName)
1769  {
1770      set<CodeRegion *> regions;
1771      CodeRegion * region;
1772      codeObject()->cs()->findRegions(functionEntryAddr,regions);
1773      if(regions.empty()) {
1774         parsing_printf("[%s:%d] refusing to create function in nonexistent "
1775                        "region at %lx\n",
1776             FILE__,__LINE__,functionEntryAddr);
1777         return NULL;
1778      }
1779      region = *(regions.begin()); // XXX pick one, throwing up hands. 
1780
1781      pdmodule *mod = getOrCreateModule(linkedFile->getDefaultModule());
1782
1783      // copy or create function name
1784      char funcName[32];
1785      if (fName) {
1786          snprintf( funcName, 32, "%s", fName);
1787      } else {
1788          snprintf( funcName, 32, "entry_%lx", functionEntryAddr);       
1789      }
1790      Symbol *funcSym = new Symbol(funcName,
1791                                   Symbol::ST_FUNCTION,
1792                                   Symbol::SL_GLOBAL, 
1793                                   Symbol::SV_DEFAULT,
1794                                   functionEntryAddr, 
1795                                   mod->mod(),
1796                                   NULL,
1797                                   UINT_MAX);
1798      // create function stub, update datastructures
1799      if (!linkedFile->addSymbol( funcSym )) {
1800          return NULL;
1801      }
1802      
1803      // Adding the symbol finds or creates a Function object...
1804      assert(funcSym->getFunction());
1805
1806      // Parse, but not recursively
1807      codeObject()->parse(functionEntryAddr, false); 
1808
1809      image_func * func = static_cast<image_func*>(
1810             codeObject()->findFuncByEntry(region,functionEntryAddr));
1811
1812      if(NULL == func) {
1813         parsing_printf("[%s:%d] failed to create function at %lx\n",
1814             FILE__,__LINE__,functionEntryAddr);
1815         return NULL;
1816      }
1817
1818      if (!func->getSymtabFunction()->addAnnotation(func, ImageFuncUpPtrAnno))
1819      {
1820         fprintf(stderr, "%s[%d]: failed to add annotation here\n", FILE__, __LINE__);
1821         return NULL;
1822      }
1823
1824      // If this is a Dyninst dynamic heap placeholder, add it to the
1825      // list of inferior heaps...
1826      string compString = "DYNINSTstaticHeap";
1827      if (!func->symTabName().compare(0, compString.size(), compString)) {
1828          codeHeaps_.push_back(pair<string, Address>(func->symTabName(), func->getOffset()));
1829      }
1830
1831      func->addSymTabName( funcName ); 
1832      func->addPrettyName( funcName );
1833      // funcsByEntryAddr[func->getOffset()] = func;
1834      //createdFunctions.push_back(func);
1835
1836      return func;
1837 }
1838
1839 const string &pdmodule::fileName() const
1840 {
1841     return mod_->fileName();
1842 }
1843
1844 const string &pdmodule::fullName() const
1845 {
1846     return mod_->fullName();
1847 }
1848
1849 SymtabAPI::supportedLanguages 
1850 pdmodule::language() const
1851 {
1852     return mod_->language();
1853 }
1854
1855 Address pdmodule::addr() const
1856 {
1857     return mod_->addr();
1858 }
1859
1860 bool pdmodule::isShared() const
1861 {
1862     return mod_->isShared();
1863 }
1864
1865 Module *pdmodule::mod()
1866 {
1867     return mod_;
1868 }
1869
1870 pdmodule *image::getOrCreateModule(Module *mod) {
1871     if (mods_.find(mod) != mods_.end())
1872         return mods_[mod];
1873
1874     pdmodule *pdmod = new pdmodule(mod, this);
1875
1876     mods_[mod] = pdmod;
1877     modsByFileName[pdmod->fileName()] = pdmod;
1878     modsByFullName[pdmod->fullName()] = pdmod;
1879     
1880     return pdmod;
1881 }
1882
1883 namespace {
1884     /* 
1885      * See ParseAPI::SymtabCodeSource::lookup_region for 
1886      * details about this
1887      */  
1888     CodeRegion * aix_region_hack(set<CodeRegion *> regs,Address addr)
1889     {
1890         set<CodeRegion*>::iterator rit = regs.begin();
1891         for( ; rit != regs.end(); ++rit) {
1892             CodeRegion * tmp = *rit;
1893             if(tmp->isCode(addr))
1894                 return tmp;
1895         }
1896         return *regs.begin();
1897     }
1898 };
1899
1900
1901 /*********************************************************************/
1902 /**** Function lookup (by name or address) routines               ****/
1903 /****                                                             ****/
1904 /**** Overlapping region objects MUST NOT use these routines(+)   ****/
1905 /*********************************************************************/
1906 /*
1907  * (+) that is, except on AIX which is just /different/
1908  */
1909
1910 int
1911 image::findFuncs(const Address offset, set<Function *> & funcs) {
1912     analyzeIfNeeded();
1913
1914     set<CodeRegion *> match;
1915     int cnt = cs_->findRegions(offset,match);
1916     if(cnt == 0)
1917         return 0;
1918     else if(cnt == 1)
1919         return obj_->findFuncs(*match.begin(),offset,funcs);
1920
1921 #if !defined(os_aix)
1922         fprintf(stderr,"[%s:%d] image::findFuncs(offset) called on "
1923                        "overlapping-region object\n",
1924             FILE__,__LINE__);
1925         assert(0);
1926         return 0;
1927 #else
1928     CodeRegion * single = aix_region_hack(match,offset);
1929     return obj_->findFuncs(single,offset,funcs);
1930 #endif 
1931 }
1932
1933 image_func *image::findFuncByEntry(const Address &entry) {
1934     analyzeIfNeeded();
1935
1936     set<CodeRegion *> match;
1937     int cnt = cs_->findRegions(entry,match);
1938     if(cnt == 0)
1939         return 0;
1940     else if(cnt == 1)
1941         return (image_func*)obj_->findFuncByEntry(*match.begin(),entry);
1942
1943 #if !defined(os_aix)
1944     fprintf(stderr,"[%s:%d] image::findFuncByEntry(entry) called on "
1945                    "overlapping-region object\n",
1946         FILE__,__LINE__);
1947     assert(0);
1948     return 0;
1949 #else
1950     CodeRegion * single = aix_region_hack(match,entry);
1951     return (image_func*)obj_->findFuncByEntry(single,entry);
1952 #endif 
1953 }
1954
1955 int 
1956 image::findBlocksByAddr(const Address addr, set<ParseAPI::Block *> & blocks ) 
1957 {
1958     analyzeIfNeeded();
1959
1960     set<CodeRegion *> match;
1961     int cnt = cs_->findRegions(addr,match);
1962     if(cnt == 0)
1963         return 0;
1964     else if(cnt == 1)
1965         return obj_->findBlocks(*match.begin(),addr,blocks);
1966
1967 #if !defined(os_aix)
1968         fprintf(stderr,"[%s:%d] image::findBlocks(offset) called on "
1969                        "overlapping-region object\n",
1970             FILE__,__LINE__);
1971         assert(0);
1972         return 0;
1973 #else
1974     CodeRegion * single = aix_region_hack(match,addr);
1975     return obj_->findBlocks(single,addr,blocks);
1976 #endif
1977 }
1978
1979 // Return the vector of functions associated with a pretty (demangled) name
1980 // Very well might be more than one!
1981
1982 const pdvector<image_func *> *image::findFuncVectorByPretty(const std::string &name) {
1983     //Have to change here
1984     pdvector<image_func *>* res = new pdvector<image_func *>;
1985     vector<SymtabAPI::Function *> funcs;
1986     linkedFile->findFunctionsByName(funcs, name.c_str(), SymtabAPI::prettyName);
1987
1988     for(unsigned index=0; index < funcs.size(); index++)
1989     {
1990         SymtabAPI::Function *symFunc = funcs[index];
1991         image_func *imf = NULL;
1992         
1993         if (!symFunc->getAnnotation(imf, ImageFuncUpPtrAnno)) {
1994             fprintf(stderr, "%s[%d]:  failed to getAnnotations here [%s]\n", FILE__, __LINE__,name.c_str());
1995             return NULL;
1996         }
1997         
1998         if (imf) {
1999             res->push_back(imf);
2000         }
2001
2002
2003     }           
2004     if(res->size())     
2005         return res;         
2006     else {
2007         delete res;
2008         return NULL;
2009     }
2010 }
2011
2012 // Return the vector of functions associated with a mangled name
2013 // Very well might be more than one! -- multiple static functions in different .o files
2014
2015 const pdvector <image_func *> *image::findFuncVectorByMangled(const std::string &name)
2016 {
2017     pdvector<image_func *>* res = new pdvector<image_func *>;
2018
2019     vector<SymtabAPI::Function *> funcs;
2020     linkedFile->findFunctionsByName(funcs, name.c_str(), SymtabAPI::mangledName);
2021
2022     for(unsigned index=0; index < funcs.size(); index++) {
2023         SymtabAPI::Function *symFunc = funcs[index];
2024         image_func *imf = NULL;
2025         
2026         if (!symFunc->getAnnotation(imf, ImageFuncUpPtrAnno)) {
2027             fprintf(stderr, "%s[%d]:  failed to getAnnotations here [%s]\n", FILE__, __LINE__, name.c_str());
2028             return NULL;
2029         }
2030         
2031         if (imf) {
2032             res->push_back(imf);
2033         }
2034
2035     }       
2036     if(res->size()) 
2037         return res;         
2038     else {
2039         delete res;
2040         return NULL;
2041     }   
2042 }
2043
2044 const pdvector <image_variable *> *image::findVarVectorByPretty(const std::string &name)
2045 {
2046     pdvector<image_variable *>* res = new pdvector<image_variable *>;
2047
2048     vector<Variable *> vars;
2049     linkedFile->findVariablesByName(vars, name.c_str(), SymtabAPI::prettyName);
2050     
2051     for (unsigned index=0; index < vars.size(); index++) {
2052         Variable *symVar = vars[index];
2053         image_variable *imv = NULL;
2054         
2055         if (!symVar->getAnnotation(imv, ImageVariableUpPtrAnno)) {
2056             fprintf(stderr, "%s[%d]:  failed to getAnnotations here\n", FILE__, __LINE__);
2057             return NULL;
2058         }
2059
2060        if (imv) {
2061            res->push_back(imv);
2062        }
2063     }       
2064     if(res->size())     
2065         return res;         
2066     else {
2067         delete res;
2068         return NULL;
2069     }
2070 }
2071
2072 const pdvector <image_variable *> *image::findVarVectorByMangled(const std::string &name)
2073 {
2074     //    fprintf(stderr,"findVariableVectorByPretty %s\n",name.c_str());
2075 #ifdef IBM_BPATCH_COMPAT_STAB_DEBUG
2076     bperr( "%s[%d]:  inside findVariableVectorByPretty\n", FILE__, __LINE__);
2077 #endif
2078     pdvector<image_variable *>* res = new pdvector<image_variable *>;
2079
2080     vector<Variable *> vars;
2081     linkedFile->findVariablesByName(vars, name.c_str(), SymtabAPI::mangledName);
2082     
2083     for (unsigned index=0; index < vars.size(); index++) {
2084         Variable *symVar = vars[index];
2085         image_variable *imv = NULL;
2086         
2087         if (!symVar->getAnnotation(imv, ImageVariableUpPtrAnno)) {
2088             fprintf(stderr, "%s[%d]:  failed to getAnnotations here\n", FILE__, __LINE__);
2089             return NULL;
2090         }
2091
2092         if (imv) {
2093             res->push_back(imv);
2094         }
2095     }       
2096     if(res->size())     
2097         return res;         
2098     else {
2099         delete res;
2100         return NULL;
2101     }
2102   /*
2103   if (varsByMangled.defines(name)) {
2104       //analyzeIfNeeded();
2105       return varsByMangled[name];
2106   }
2107   return NULL;*/
2108 }
2109
2110 bool pdmodule::getFunctions(pdvector<image_func *> &funcs)  {
2111     unsigned curFuncSize = funcs.size();
2112
2113     CodeObject::funclist & allFuncs = imExec()->getAllFunctions();
2114     CodeObject::funclist::iterator fit = allFuncs.begin();
2115     for( ; fit != allFuncs.end(); ++fit) {
2116         image_func *f = (image_func*)*fit;
2117         if (f->pdmod() == this)
2118             funcs.push_back(f);
2119     }
2120   
2121     return (funcs.size() > curFuncSize);
2122 } /* end getFunctions() */
2123
2124 /* Instrumentable-only, by the last version's source. */
2125 bool pdmodule::getVariables(pdvector<image_variable *> &vars)  {
2126     pdvector<image_variable *> allVars = imExec()->getAllVariables();
2127     unsigned curVarSize = vars.size();
2128
2129     for (unsigned i = 0; i < allVars.size(); i++) {
2130         if (allVars[i]->pdmod() == this)
2131             vars.push_back(allVars[i]);
2132     }
2133   
2134     return (vars.size() > curVarSize);
2135 } /* end getFunctions() */
2136
2137 /*
2138 void *image::getPtrToDataInText( Address offset ) const {
2139     if( isData(offset) ) { return NULL; }
2140     if( ! isCode(offset) ) { return NULL; }
2141         
2142     Region *reg = linkedFile->findEnclosingRegion(offset);
2143     if(reg != NULL) {
2144         return (void*) ((Address)reg->getPtrToRawData() + offset 
2145                         - reg->getRegionAddr());
2146     }
2147     return NULL;
2148 } *//* end getPtrToDataInText() */
2149     
2150 bool image::getExecCodeRanges(std::vector<std::pair<Address, Address> > &ranges)
2151 {
2152    std::vector<Region *> regions;
2153    bool result = linkedFile->getCodeRegions(regions);
2154    if (!result)
2155       return false;
2156    Address cur_start = 0, cur_end = (Address)(-1);
2157    bool found_something = false;
2158    fprintf(stderr, "\n");
2159    for (std::vector<Region *>::iterator i = regions.begin(); i != regions.end(); i++)
2160    {
2161       Region *r = *i;
2162       if (!r->isStandardCode() && !codeObject()->defensiveMode())
2163          continue;
2164       if (!found_something) {
2165          cur_start = r->getDiskOffset();
2166          cur_end = cur_start + r->getDiskSize();
2167          found_something = true;
2168          continue;
2169       }
2170
2171       if (r->getDiskOffset() <= cur_end) {
2172          cur_end = r->getDiskOffset() + r->getDiskSize();
2173       }
2174       else {
2175          ranges.push_back(std::pair<Address, Address>(cur_start, cur_end));
2176          cur_start = r->getDiskOffset();
2177          cur_end = cur_start + r->getDiskSize();
2178       }
2179    }
2180    if (!found_something) {
2181       return false;
2182    }
2183    ranges.push_back(std::pair<Address, Address>(cur_start, cur_end));
2184    return true;
2185 }
2186
2187 Symbol *image::symbol_info(const std::string& symbol_name) {
2188    vector< Symbol *> symbols;
2189    if(!(linkedFile->findSymbol(symbols,symbol_name.c_str(),Symbol::ST_UNKNOWN, SymtabAPI::anyName))) 
2190        return false;
2191
2192    return symbols[0];
2193 }
2194
2195 bool image::findSymByPrefix(const std::string &prefix, pdvector<Symbol *> &ret) {
2196     unsigned start;
2197     vector <Symbol *>found;     
2198     std::string reg = prefix+std::string("*");
2199     if(!linkedFile->findSymbol(found, reg.c_str(), Symbol::ST_UNKNOWN, SymtabAPI::anyName, true))
2200         return false;
2201     for(start=0;start< found.size();start++)
2202                 ret.push_back(found[start]);
2203         return true;    
2204 }
2205
2206 dictionary_hash<Address, std::string> *image::getPltFuncs()
2207 {
2208    bool result;
2209    if (pltFuncs)
2210       return pltFuncs;
2211
2212
2213    vector<SymtabAPI::relocationEntry> fbt;
2214    result = getObject()->getFuncBindingTable(fbt);
2215    if (!result)
2216       return NULL;
2217
2218    pltFuncs = new dictionary_hash<Address, std::string>(addrHash);
2219    assert(pltFuncs);
2220    for(unsigned k = 0; k < fbt.size(); k++) {
2221 #if defined(os_vxworks)
2222        if (fbt[k].target_addr() == 0) {
2223            (*pltFuncs)[fbt[k].rel_addr()] = fbt[k].name().c_str();
2224        }
2225 #else
2226       (*pltFuncs)[fbt[k].target_addr()] = fbt[k].name().c_str();
2227 #endif
2228    }
2229    return pltFuncs;
2230 }
2231
2232 image_variable* image::createImageVariable(Offset offset, std::string name, int size, pdmodule *mod)
2233 {
2234     // What to do here?
2235     if (varsByAddr.defines(offset))
2236         return varsByAddr[offset];
2237
2238     Variable *sVar = getObject()->createVariable(name, offset, size, mod->mod());
2239
2240     image_variable *ret = new image_variable(sVar, mod);
2241
2242     extern AnnotationClass<image_variable> ImageVariableUpPtrAnno;
2243     if (!sVar->addAnnotation(ret, ImageVariableUpPtrAnno)) {
2244         fprintf(stderr, "%s[%d]:  failed to add annotation here\n", FILE__, __LINE__);
2245     }
2246
2247     createdVariables.push_back(ret);
2248     everyUniqueVariable.push_back(ret);
2249     varsByAddr[offset] = ret;
2250     return ret;
2251 }
2252
2253
2254 const set<image_basicBlock*> & image::getSplitBlocks() const
2255 {
2256     return splitBlocks_;
2257 }
2258 void image::clearSplitBlocks()
2259 {
2260     splitBlocks_.clear();
2261 }
2262 const vector<image_basicBlock*> & image::getNewBlocks() const
2263 {
2264     return newBlocks_;
2265 }
2266 void image::clearNewBlocks()
2267 {
2268     newBlocks_.clear();
2269 }
2270