windows build fixes and some more work on symtab serialization
[dyninst.git] / symtabAPI / src / Object-elf.C
1 /*
2  * Copyright (c) 1996-2007 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 /************************************************************************
33  * $Id: Object-elf.C,v 1.54 2008/11/03 15:19:25 jaw Exp $
34  * Object-elf.C: Object class for ELF file format
35  ************************************************************************/
36
37 #include "Type.h"
38 #include "Variable.h"
39 #include "Symbol.h"
40 #include "Symtab.h"
41 #include "Object.h"
42
43 #include "emitElf.h"
44 #include "Module.h"
45 #include "Aggregate.h"
46 #include "Function.h"
47
48 #include "debug.h"
49
50 #if defined(x86_64_unknown_linux2_4) || defined(ia64_unknown_linux2_4) || defined(ppc64_linux)
51 #include "emitElf-64.h"
52 #endif
53
54 using namespace Dyninst;
55 using namespace Dyninst::SymtabAPI;
56 using namespace std;
57
58 #if !defined(_Object_elf_h_)
59 #error "Object-elf.h not #included"
60 #endif
61
62 #include <elf.h>
63 #include <stdio.h>
64 #include <algorithm>
65
66 #if defined(USES_DWARF_DEBUG)
67 #include "dwarf.h"
68 #include "libdwarf.h"
69 #endif
70
71 //#include "symutil.h"
72 #include "common/h/pathName.h"
73 #include "Collections.h"
74 #if defined(TIMED_PARSE)
75 #include <sys/time.h>
76 #endif
77 #include <iostream>
78 #include <iomanip>
79
80 #include <fstream>
81 #include <sys/stat.h>
82 #include <boost/crc.hpp>
83 #include <boost/assign/list_of.hpp>
84 #include <boost/assign/std/set.hpp>
85 #include <boost/assign/std/vector.hpp>
86
87 using boost::crc_32_type;
88 using namespace boost::assign;
89
90 #include <libgen.h>
91
92 // add some space to avoid looking for functions in data regions
93 #define EXTRA_SPACE 8
94
95 bool Object::truncateLineFilenames = true;
96     
97 string symt_current_func_name;
98 string symt_current_mangled_func_name;
99 Symbol *symt_current_func = NULL;
100
101 #if defined(os_solaris)
102 #include <dlfcn.h>
103 #define DLOPEN_MODE (RTLD_NOW | RTLD_GLOBAL)
104
105 int (*P_native_demangle)(const char *, char *, size_t);
106
107 void loadNativeDemangler() {
108
109     P_native_demangle = NULL;
110     void *hDemangler = dlopen("libdemangle.so", DLOPEN_MODE);
111     if (hDemangler != NULL)
112         P_native_demangle = (int (*) (const char *, char *, size_t))
113     dlsym(hDemangler, "cplus_demangle");
114 }
115                 
116 #endif
117
118 extern void print_symbols( std::vector< Symbol *>& allsymbols );
119 extern void print_symbol_map( dyn_hash_map< std::string, std::vector< Symbol *> > *symbols);
120
121 void (*dwarf_err_func)(const char *);   // error callback for dwarf errors
122
123 static bool pdelf_check_ehdr(Elf_X &elf)
124 {
125     // Elf header integrity check
126     return ((elf.e_type() == ET_EXEC || elf.e_type() == ET_DYN) &&
127             (elf.e_phoff() != 0) && (elf.e_shoff() != 0) &&
128             (elf.e_phnum() != 0) && (elf.e_shnum() != 0)) ;
129 }
130
131 const char *pdelf_get_shnames(Elf_X &elf)
132 {
133     const char *result = NULL;
134     size_t shstrndx = elf.e_shstrndx();
135
136     Elf_X_Shdr shstrscn = elf.get_shdr(shstrndx);
137     if (shstrscn.isValid()) {
138         Elf_X_Data shstrdata = shstrscn.get_data();
139         if (shstrdata.isValid())
140             result = shstrdata.get_string();
141     }
142     return result;
143 }
144
145 //
146 // SectionHeaderSortFunction
147 // 
148 // Compare function for use with the Vector<T> sort method.
149 //
150 struct  SectionHeaderSortFunction: public binary_function<Elf_X_Shdr *, Elf_X_Shdr *, bool> 
151 {
152         bool operator()(Elf_X_Shdr *hdr1, Elf_X_Shdr *hdr2) {
153                 return (hdr1->sh_addr() < hdr2->sh_addr()); 
154         }
155 };
156
157 Region::perm_t getSegmentPerms(unsigned long flags){
158     if(flags == 7)
159         return Region::RP_RWX;
160     else if(flags == 6)
161         return Region::RP_RW;
162     else if(flags == 5)
163         return Region::RP_RX;
164     else
165         return Region::RP_R;
166 }
167
168 Region::RegionType getSegmentType(unsigned long type, unsigned long flags)
169 {
170     if(type == PT_DYNAMIC)
171         return Region::RT_DYNAMIC;
172     if(flags == 7)
173         return Region::RT_TEXTDATA;
174     if(flags == 5)
175         return Region::RT_TEXT;
176     if(flags == 6)
177         return Region::RT_DATA;
178     return Region::RT_OTHER;
179 }
180
181 /* binary search to find the section starting at a particular address */
182 Elf_X_Shdr *Object::getRegionHdrByAddr(Offset addr) 
183 {
184     unsigned end = allRegionHdrs.size() - 1, start = 0;
185     unsigned mid = 0; 
186     while(start < end) {
187         mid = start + (end-start)/2;
188         if(allRegionHdrs[mid]->sh_addr() == addr)
189             return allRegionHdrs[mid];
190         else if(allRegionHdrs[mid]->sh_addr() < addr)
191             start = mid + 1;
192         else
193             end = mid;
194     }
195     if(allRegionHdrs[start]->sh_addr() == addr)
196         return allRegionHdrs[start];
197     return NULL;
198 }
199
200 /* Check if there is a section which belongs to the segment and update permissions of that section.
201  * Return value indicates whether the segment has to be added to the list of regions*/
202
203 bool Object::isRegionPresent(Offset segmentStart, Offset segmentSize, unsigned segPerms){
204     bool present = false;
205     for(unsigned i = 0; i < regions_.size() ;i++){
206         if((regions_[i]->getRegionAddr() >= segmentStart) && ((regions_[i]->getRegionAddr()+regions_[i]->getRegionSize()) <= (segmentStart+segmentSize))){
207             present = true;
208             regions_[i]->setRegionPermissions(getSegmentPerms(segPerms));
209         }
210
211     }
212     return present;
213 }
214
215 Region::perm_t getRegionPerms(unsigned long flags){
216     if((flags & SHF_WRITE) && !(flags & SHF_EXECINSTR))
217         return Region::RP_RW;
218     else if(!(flags & SHF_WRITE) && (flags & SHF_EXECINSTR))
219         return Region::RP_RX;
220     else if((flags & SHF_WRITE) && (flags & SHF_EXECINSTR))
221         return Region::RP_RWX;
222     else
223         return Region::RP_R;
224 }
225
226 Region::RegionType getRegionType(unsigned long type, unsigned long flags){
227     switch(type){
228         case SHT_SYMTAB:
229         case SHT_DYNSYM:
230             return Region::RT_SYMTAB;
231         case SHT_STRTAB:
232             return Region::RT_STRTAB;
233         case SHT_REL:
234             return Region::RT_REL;
235         case SHT_RELA:
236             return Region::RT_RELA;
237         case SHT_PROGBITS:
238             if((flags & SHF_EXECINSTR) && (flags & SHF_WRITE))
239                 return Region::RT_TEXTDATA;
240             else if(flags & SHF_EXECINSTR)
241                 return Region::RT_TEXT;
242             else
243                 return Region::RT_DATA;
244         case SHT_DYNAMIC:
245             return Region::RT_DYNAMIC;
246         case SHT_HASH:
247             return Region::RT_HASH;
248 #if !defined(os_solaris)            
249         case SHT_GNU_versym:
250             return Region::RT_SYMVERSIONS;
251         case SHT_GNU_verdef:
252             return Region::RT_SYMVERDEF;
253         case SHT_GNU_verneed:
254             return Region::RT_SYMVERNEEDED;
255 #endif
256         default:
257             return Region::RT_OTHER;
258     }
259 }
260
261 const char* EDITED_TEXT_NAME = ".edited.text";
262 // const char* INIT_NAME        = ".init";
263 const char *INTERP_NAME      = ".interp";
264 const char* FINI_NAME        = ".fini";
265 const char* TEXT_NAME        = ".text";
266 const char* BSS_NAME         = ".bss";
267 const char* SYMTAB_NAME      = ".symtab";
268 const char* STRTAB_NAME      = ".strtab";
269 const char* STAB_NAME        = ".stab";
270 const char* STABSTR_NAME     = ".stabstr";
271 const char* STAB_INDX_NAME   = ".stab.index";
272 const char* STABSTR_INDX_NAME= ".stab.indexstr";
273 const char* OPD_NAME         = ".opd"; // PPC64 Official Procedure Descriptors
274 // sections from dynamic executables and shared objects
275 const char* PLT_NAME         = ".plt";
276 #if ! defined( arch_ia64 )
277 const char* REL_PLT_NAME     = ".rela.plt"; // sparc-solaris
278 #else  
279 const char* REL_PLT_NAME     = ".rela.IA_64.pltoff";
280 #endif  
281 const char* REL_PLT_NAME2    = ".rel.plt";  // x86-solaris
282 const char* GOT_NAME         = ".got";
283 const char* DYNSYM_NAME      = ".dynsym";
284 const char* DYNSTR_NAME      = ".dynstr";
285 const char* DATA_NAME        = ".data";
286 const char* RO_DATA_NAME     = ".ro_data";  // mips
287 const char* DYNAMIC_NAME     = ".dynamic";
288 const char* EH_FRAME_NAME    = ".eh_frame";
289 const char* EXCEPT_NAME      = ".gcc_except_table";
290 const char* EXCEPT_NAME_ALT  = ".except_table";
291 const char* DEBUGLINK_NAME   = ".gnu_debuglink";
292 const char* BUILD_ID_NAME    = ".note.gnu.build-id";
293
294 set<string> debugInfoSections = list_of(string(SYMTAB_NAME))
295                                        (string(STRTAB_NAME));
296
297 // loaded_elf(): populate elf section pointers
298 // for EEL rewritten code, also populate "code_*_" members
299 bool Object::loaded_elf(Offset& txtaddr, Offset& dataddr,
300                         Elf_X_Shdr* &bssscnp,
301                         Elf_X_Shdr*& symscnp, Elf_X_Shdr*& strscnp, 
302                         Elf_X_Shdr*& stabscnp, Elf_X_Shdr*& stabstrscnp, 
303                         Elf_X_Shdr*& stabs_indxcnp, Elf_X_Shdr*& stabstrs_indxcnp, 
304                         Elf_X_Shdr*& rel_plt_scnp, Elf_X_Shdr*& plt_scnp, 
305                         Elf_X_Shdr*& opd_scnp, Elf_X_Shdr*& got_scnp, Elf_X_Shdr*& dynsym_scnp,
306                         Elf_X_Shdr*& dynstr_scnp, Elf_X_Shdr* &dynamic_scnp, 
307                         Elf_X_Shdr*& eh_frame, Elf_X_Shdr*& gcc_except, 
308                         Elf_X_Shdr *& interp_scnp, bool)
309 {
310    std::map<std::string, int> secnNameMap;
311    dwarf_err_func  = err_func_;
312    entryAddress_ = elfHdr.e_entry();
313
314    no_of_sections_ = elfHdr.e_shnum();
315
316    // ".shstrtab" section: string table for section header names
317    const char *shnames = pdelf_get_shnames(elfHdr);
318    if (shnames == NULL) {
319       fprintf(stderr, "[%s][%d]WARNING: .shstrtab section not found in ELF binary\n",__FILE__,__LINE__);
320       log_elferror(err_func_, ".shstrtab section");
321       //return false;
322    }
323
324    // initialize Object members
325
326    text_addr_ = 0; //ccw 23 jan 2002
327    text_size_ = 0; //for determining if a mutation
328    //falls within the text section 
329    //of a shared library
330
331    dynamic_addr_ = 0;
332    dynsym_addr_ = 0;
333    dynstr_addr_ = 0;
334    fini_addr_ = 0;
335    opd_addr_ = 0;
336    opd_size_ = 0;
337    got_addr_ = 0;
338    got_size_ = 0;
339    plt_addr_ = 0;
340    plt_size_ = 0;
341 #if defined (ppc32_linux)
342    plt_entry_size_ = 8;
343    rel_plt_entry_size_ = 8;
344 #else
345    plt_entry_size_ = 0;
346    rel_plt_entry_size_ = 0;
347 #endif
348    rel_plt_addr_ = 0;
349    rel_plt_size_ = 0;
350    rel_size_ = 0;
351    rel_entry_size_ = 0;
352    stab_off_ = 0;
353    stab_size_ = 0;
354    stabstr_off_ = 0;
355    stab_indx_off_ = 0;
356    stab_indx_size_ = 0;
357    stabstr_indx_off_ = 0;
358 #if defined(os_irix)
359    MIPS_stubs_addr_ = 0;
360    MIPS_stubs_off_ = 0;
361    MIPS_stubs_size_ = 0;
362    got_zero_index_ = -1;
363    dynsym_zero_index_ = -1;
364 #endif
365    dwarvenDebugInfo = false;
366
367    txtaddr = 0;
368
369    set<string> sectionsInOriginalBinary;
370    bool debugInfoValid = true;
371
372    if(mfForDebugInfo->getFD() != -1)
373       elfHdrForDebugInfo = Elf_X(mfForDebugInfo->getFD(), ELF_C_READ);
374    else 
375       elfHdrForDebugInfo = Elf_X((char *)mfForDebugInfo->base_addr(), mfForDebugInfo->size());
376    usesDebugFile = (mfForDebugInfo != mf);
377
378    if(!elfHdrForDebugInfo.isValid()) {
379       log_elferror(err_func_, "Elf header");
380       fprintf(stderr, "%s[%d]:  failing to parse line info due to elf prob\n", FILE__, __LINE__);
381       debugInfoValid = false;
382    }
383    else if(!pdelf_check_ehdr(elfHdrForDebugInfo)) {
384       fprintf(stderr, "%s[%d]:  Warning: Elf ehdr failed integrity check\n", FILE__, __LINE__);
385       log_elferror(err_func_, "ELF header failed integrity check");
386       debugInfoValid = false;
387    }
388
389
390    const char *shnamesForDebugInfo = pdelf_get_shnames(elfHdrForDebugInfo);
391    if (shnamesForDebugInfo == NULL) {
392       fprintf(stderr, "[%s][%d]WARNING: .shstrtab section not found in ELF binary\n",__FILE__,__LINE__);
393       log_elferror(err_func_, ".shstrtab section");
394       //return false;
395    }
396
397 #if defined(TIMED_PARSE)
398    struct timeval starttime;
399    gettimeofday(&starttime, NULL);
400 #endif
401
402    Elf_X_Shdr *scnp;
403
404    for (int i = 0; i < elfHdr.e_shnum() + elfHdrForDebugInfo.e_shnum(); ++i) {
405       const char *name;
406
407       if(i < elfHdr.e_shnum()) {
408          scnp = new Elf_X_Shdr( elfHdr.get_shdr(i) );
409          if (! scnp->isValid()) { // section is malformed
410             continue; 
411          } 
412          name = &shnames[scnp->sh_name()];
413          sectionsInOriginalBinary.insert(string(name));
414          
415          if(scnp->sh_flags() & SHF_ALLOC) {
416             DbgAddrConversion_t orig;
417             orig.name = std::string(name);
418             orig.orig_offset = scnp->sh_addr();
419             secnNameMap[orig.name] = DebugSectionMap.size();
420             DebugSectionMap.push_back(orig);
421          }
422       }
423       else {
424          if(mfForDebugInfo == mf)
425             break;
426          scnp = new Elf_X_Shdr(elfHdrForDebugInfo.get_shdr(i - elfHdr.e_shnum()));
427          if(! scnp->isValid()) {
428             continue;
429          }
430          name = &shnamesForDebugInfo[scnp->sh_name()];
431
432          std::string sname(name);
433          std::map<std::string, int>::iterator s = secnNameMap.find(sname);
434          if (s != secnNameMap.end()) {
435             int i = (*s).second;
436             DebugSectionMap[i].dbg_offset = scnp->sh_addr();
437             DebugSectionMap[i].dbg_size = scnp->sh_size();
438          }
439          scnp->setDebugFile(true);
440
441          if (scnp->sh_type() == SHT_NOBITS) {
442             delete scnp;
443             continue;
444          }
445       }
446
447
448       //If the section appears in the memory image of a process address is given by 
449       // sh_addr()
450       //otherwise this is zero and sh_offset() gives the offset to the first byte 
451       // in section.
452       if (!scnp->isFromDebugFile()) {
453          allRegionHdrs.push_back( scnp );
454          if(scnp->sh_flags() & SHF_ALLOC) {
455             Region *reg = new Region(i, name, scnp->sh_addr(), scnp->sh_size(), 
456                                      scnp->sh_addr(), scnp->sh_size(), 
457                                      (mem_image()+scnp->sh_offset()), 
458                                      getRegionPerms(scnp->sh_flags()), 
459                                      getRegionType(scnp->sh_type(), scnp->sh_flags()));
460             
461             regions_.push_back(reg);
462          }
463          else {
464             Region *reg = new Region(i, name, scnp->sh_addr(), scnp->sh_size(), 0, 0, 
465                                      (mem_image()+scnp->sh_offset()), 
466                                      getRegionPerms(scnp->sh_flags()), 
467                                      getRegionType(scnp->sh_type(), scnp->sh_flags()));
468             regions_.push_back(reg);
469          }
470       }
471
472       // section-specific processing
473       if (P_strcmp(name, EDITED_TEXT_NAME) == 0) {
474          // EEL rewritten executable
475          EEL = true;
476          if (txtaddr == 0)
477             txtaddr = scnp->sh_addr();
478          char *file_ptr = (char *)mf->base_addr();
479          code_ptr_ = (char *)(void*)&file_ptr[scnp->sh_offset() - EXTRA_SPACE];
480          code_off_ = scnp->sh_addr() - EXTRA_SPACE;
481          code_len_ = scnp->sh_size() + EXTRA_SPACE;
482       }
483       if (strcmp(name, TEXT_NAME) == 0) {
484          text_addr_ = scnp->sh_addr();
485          text_size_ = scnp->sh_size();
486
487          if (txtaddr == 0)
488             txtaddr = scnp->sh_addr();
489       }
490       /* The following sections help us find the PH entry that
491          encompasses the data region. */
492       else if (strcmp(name, DATA_NAME) == 0) {
493          dataddr = scnp->sh_addr();
494       }
495       else if (strcmp(name, RO_DATA_NAME) == 0) {
496          if (!dataddr) dataddr = scnp->sh_addr();
497       }
498       else if (strcmp(name, OPD_NAME) == 0) {
499          opd_scnp = scnp;
500          opd_addr_ = scnp->sh_addr();
501          opd_size_ = scnp->sh_size();
502       }
503       else if (strcmp(name, GOT_NAME) == 0) {
504          got_scnp = scnp;
505          got_addr_ = scnp->sh_addr();
506          got_size_ = scnp->sh_size();
507          if (!dataddr) dataddr = scnp->sh_addr();
508       }
509       else if (strcmp(name, BSS_NAME) == 0) {
510          bssscnp = scnp;
511          if (!dataddr) dataddr = scnp->sh_addr();
512       }
513       /* End data region search */
514       else if (strcmp( name, FINI_NAME) == 0) {
515          fini_addr_ = scnp->sh_addr();
516       }
517       else if (strcmp(name, SYMTAB_NAME) == 0) {
518          if (!symscnp)
519          symscnp = scnp;
520       }
521       else if (strcmp(name, STRTAB_NAME) == 0) {
522          if (!strscnp)
523          strscnp = scnp;
524       } else if (strcmp(name, STAB_INDX_NAME) == 0) {
525          stabs_indxcnp = scnp;
526          stab_indx_off_ = scnp->sh_offset();
527          stab_indx_size_ = scnp->sh_size();
528       } else if (strcmp(name, STABSTR_INDX_NAME) == 0) {
529          stabstrs_indxcnp = scnp;
530          stabstr_indx_off_ = scnp->sh_offset();
531       } else if (strcmp(name, STAB_NAME) == 0) {
532          stabscnp = scnp;
533          stab_off_ = scnp->sh_offset();
534          stab_size_ = scnp->sh_size();
535       } else if (strcmp(name, STABSTR_NAME) == 0) {
536          stabstrscnp = scnp;
537          stabstr_off_ = scnp->sh_offset();
538       } else if ((strcmp(name, REL_PLT_NAME) == 0) || 
539                  (strcmp(name, REL_PLT_NAME2) == 0)) {
540          rel_plt_scnp = scnp;
541          rel_plt_addr_ = scnp->sh_addr();
542          rel_plt_size_ = scnp->sh_size();
543          rel_plt_entry_size_ = scnp->sh_entsize();
544       }
545       else if (strcmp(name, PLT_NAME) == 0) {
546          plt_scnp = scnp;
547          plt_addr_ = scnp->sh_addr();
548          plt_size_ = scnp->sh_size();
549 #if defined(arch_x86)
550          //
551          // On x86, the GNU linker purposefully sets the PLT
552          // table entry size to an incorrect value to be
553          // compatible with the UnixWare linker.  (See the comment
554          // in the elf_i386_finish_dynamic_sections function of
555          // the BFD library.)  The GNU linker sets this value to 4,
556          // when it should be 16.
557          //
558          // I see no good way to determine this value from the
559          // ELF section header information.  We can either (a) hard-code
560          // the value that is used in the BFD library, or (b) compute
561          // it by dividing the size of the PLT by the number of entries
562          // we think should be in the PLT.  I'm not certain, but I
563          // believe the PLT and the .rel.plt section should have the
564          // same number of "real" entries (the x86 PLT has one extra entry
565          // at the beginning).
566          // 
567          // This code is applicable to any x86 system that uses the
568          // GNU linker.  We currently only support Linux on x86 - if
569          // we start supporting some other x86 OS that uses the GNU
570          // linker in the future, it should be enabled for that platform as well.
571          // Note that this problem does not affect the non-x86 platforms
572          // that might use the GNU linker.  For example, programs linked
573          // with gld on SPARC Solaris have the correct PLT entry size.
574          //
575          // Another potential headache in the future is if we support
576          // some other x86 platform that has both the GNU linker and
577          // some other linker.  (Does BSD fall into this category?)
578          // If the two linkers set the entry size differently, we may
579          // need to re-evaluate this code.
580          //
581          //plt_entry_size_ = plt_size_ / ((rel_plt_size_ / rel_plt_entry_size_) + 1);
582          plt_entry_size_ = 16;
583          assert( plt_entry_size_ == 16 );
584 #else
585
586          plt_entry_size_ = scnp->sh_entsize();
587 #if defined (ppc32_linux)
588          if (!plt_entry_size_)
589             plt_entry_size_ = 8;
590          else {
591             if (plt_entry_size_ != 8) 
592                fprintf(stderr, "%s[%d]:  weird plt_entry_size_ is %d, not 8\n", 
593                        FILE__, __LINE__, plt_entry_size_);
594          }
595 #endif
596 #endif
597       }
598       else if (strcmp(name, DYNSYM_NAME) == 0) {
599          is_dynamic_ = true;
600          dynsym_scnp = scnp;
601          dynsym_addr_ = scnp->sh_addr();
602       }
603       else if (strcmp(name, DYNSTR_NAME) == 0) {
604          dynstr_scnp = scnp;
605          dynstr_addr_ = scnp->sh_addr();
606       }
607       else if (strcmp(name, ".debug_info") == 0) {
608          dwarvenDebugInfo = true;
609       }
610       else if (strcmp(name, EH_FRAME_NAME) == 0) {
611          eh_frame = scnp;
612       }
613       else if ((strcmp(name, EXCEPT_NAME) == 0) || 
614                (strcmp(name, EXCEPT_NAME_ALT) == 0)) {
615          gcc_except = scnp;
616       }
617       else if (strcmp(name, INTERP_NAME) == 0) {
618          interp_scnp = scnp;
619       }
620       //TODO clean up this. it is ugly
621 #if defined(arch_ia64)
622       else if (strcmp(name, DYNAMIC_NAME) == 0) {
623          dynamic_scnp = scnp;
624          dynamic_addr_ = scnp->sh_addr();
625          Elf_X_Data data = scnp->get_data();
626          Elf_X_Dyn dyns = data.get_dyn();
627          for (unsigned i = 0; i < dyns.count(); ++i) {
628             switch(dyns.d_tag(i)) {
629                case DT_PLTGOT:
630                   this->gp = dyns.d_ptr(i);
631                   ///* DEBUG */ fprintf( stderr, "%s[%d]: GP = 0x%lx\n", __FILE__, __LINE__, this->gp );
632                   break;
633     
634                default:
635                             break;
636             } // switch
637          } // for
638       }
639 #else
640       else if (strcmp(name, DYNAMIC_NAME) == 0) {
641          dynamic_scnp = scnp;
642          dynamic_addr_ = scnp->sh_addr();
643       }
644 #endif /* ia64_unknown_linux2_4 */
645    }
646
647    if(!symscnp || !strscnp) {
648         isStripped = true;
649       if(dynsym_scnp && dynstr_scnp){
650          symscnp = dynsym_scnp;
651          strscnp = dynstr_scnp;
652       }
653    }
654
655    loadAddress_ = 0x0;
656 #if defined(os_linux)
657    /**
658     * If the virtual address of the first PT_LOAD element in the
659     * program table is 0, Linux loads the shared object into any
660     * free spot into the address space.  If the virtual address is
661     * non-zero, it gets loaded only at that address.
662     **/
663    for (unsigned i = 0; i < elfHdr.e_phnum() && !loadAddress_; ++i) {
664       Elf_X_Phdr phdr = elfHdr.get_phdr(i);
665
666       if (phdr.p_type() == PT_LOAD) {
667          loadAddress_ = phdr.p_vaddr();
668          break;
669       }
670    }
671 #endif  
672   
673
674    // sort the section headers by base address
675    sort(allRegionHdrs.begin(), allRegionHdrs.end(), SectionHeaderSortFunction());
676 #if defined(TIMED_PARSE)
677    struct timeval endtime;
678    gettimeofday(&endtime, NULL);
679    unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
680    unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
681    unsigned long difftime = lendtime - lstarttime;
682    double dursecs = difftime/(1000 );
683    cout << "main loop of loaded elf took "<<dursecs <<" msecs" << endl;
684 #endif
685
686    if (!dataddr || !symscnp || !strscnp) {
687       //    fprintf(stderr, "[%s][%d]WARNING: One or more of text/bss/symbol/string sections not found in ELF binary\n",__FILE__,__LINE__);
688       log_elferror(err_func_, "no text/bss/symbol/string section");
689       //return false;
690    }
691
692    //if (addressWidth_nbytes == 8) bperr( ">>> 64-bit loaded_elf() successful\n");
693    return true;
694 }
695
696 bool Object::is_offset_in_plt(Offset offset) const
697 {
698   return (offset > plt_addr_ && offset < plt_addr_ + plt_size_);
699 }
700
701 #if !defined(os_solaris)
702 void Object::parseDynamic(Elf_X_Shdr *&dyn_scnp, Elf_X_Shdr *&dynsym_scnp,
703                                                     Elf_X_Shdr *&dynstr_scnp)
704 {
705     Elf_X_Data data = dyn_scnp->get_data();
706     Elf_X_Dyn dyns = data.get_dyn();
707     Elf_X_Shdr *rel_scnp;
708     for (unsigned i = 0; i < dyns.count(); ++i) {
709         switch(dyns.d_tag(i)) {
710           case DT_REL:
711           case DT_RELA:
712                 /*found Relocation section*/
713                 rel_scnp = getRegionHdrByAddr(dyns.d_ptr(i));
714                 rel_size_ = rel_scnp->sh_size();
715                 rel_entry_size_ = rel_scnp->sh_entsize();
716                 get_relocationDyn_entries(rel_scnp, dynsym_scnp, dynstr_scnp);
717                 break;
718           default:
719                 break;
720         }
721     }
722 }
723 #else
724 void Object::parseDynamic(Elf_X_Shdr *&, Elf_X_Shdr *&,
725                           Elf_X_Shdr *&)
726 {
727 }
728 #endif
729
730 /* parse relocations for the sections represented by DT_REL/DT_RELA in
731  * the dynamic section. This section is the one we would want to emit
732  */
733 bool Object::get_relocationDyn_entries( Elf_X_Shdr *&rel_scnp,
734                                      Elf_X_Shdr *&dynsym_scnp, 
735                                      Elf_X_Shdr *&dynstr_scnp )
736 {
737         Elf_X_Data reldata = rel_scnp->get_data();
738         Elf_X_Data symdata = dynsym_scnp->get_data();
739         Elf_X_Data strdata = dynstr_scnp->get_data();
740         
741     if( reldata.isValid() && symdata.isValid() && strdata.isValid() ) {
742             Elf_X_Sym sym = symdata.get_sym();
743             Elf_X_Rel rel = reldata.get_rel();
744             Elf_X_Rela rela = reldata.get_rela();
745             const char *strs = strdata.get_string();
746
747             if (sym.isValid() && (rel.isValid() || rela.isValid()) && strs) {
748                 /* Iterate over the entries. */
749                 for( u_int i = 0; i < (rel_size_/rel_entry_size_); ++i ) {
750                         long offset;
751                 long addend;
752                         long index;
753                 unsigned long type;
754                 Region::RegionType rtype = Region::RT_REL;
755
756                     switch (reldata.d_type()) {
757                       case ELF_T_REL:
758                             offset = rel.r_offset(i);
759                     addend = 0;
760                         index = rel.R_SYM(i);
761                     type = rel.R_TYPE(i);
762                                 break;
763
764                           case ELF_T_RELA:
765                                 offset = rela.r_offset(i);
766                     addend = rela.r_addend(i);
767                                 index = rela.R_SYM(i);
768                     type = rela.R_TYPE(i);
769                     rtype = Region::RT_RELA;
770                                 break;
771
772                       default:
773                         // We should never reach this case.
774                         return false;
775                         };
776                         // /* DEBUG */ fprintf( stderr, "%s: relocation information for target 0x%lx\n", __FUNCTION__, next_plt_entry_addr );
777                     relocationEntry re( offset, string( &strs[ sym.st_name(index) ] ), NULL, type );
778                 re.setAddend(addend);
779                 re.setRegionType(rtype);
780                 if(symbols_.find(&strs[ sym.st_name(index)]) != symbols_.end()){
781                     vector<Symbol *> syms = symbols_[&strs[ sym.st_name(index)]];
782                     re.addDynSym(syms[0]);
783                 }
784
785                     relocation_table_.push_back(re);
786                 }
787                 return true;
788             }
789     }
790     return false;
791 }
792
793 bool Object::get_relocation_entries( Elf_X_Shdr *&rel_plt_scnp,
794                                      Elf_X_Shdr *&dynsym_scnp, 
795                                      Elf_X_Shdr *&dynstr_scnp )
796 {
797     if (rel_plt_size_ && rel_plt_addr_) {
798         Elf_X_Data reldata = rel_plt_scnp->get_data();
799         Elf_X_Data symdata = dynsym_scnp->get_data();
800         Elf_X_Data strdata = dynstr_scnp->get_data();
801
802         if( reldata.isValid() && symdata.isValid() && strdata.isValid() ) {
803             Offset next_plt_entry_addr = plt_addr_;
804
805 #if defined( ia64_unknown_linux2_4 ) 
806             unsigned int functionDescriptorCount = ( rel_plt_size_ / rel_plt_entry_size_ );
807             /* The IA-64 PLT contains 1 special entry, and two entries for each functionDescriptor
808                in the function descriptor table (.IA_64.pltoff, whose count we're deriving from
809                its relocation entries).  These entries are in two groups, the second of which is
810                sometimes separated from the first by 128 bits of zeroes.  The entries in the latter group
811                are call targets that makes an indirect jump using an FD table entry.  If the
812                function they want to call hasn't been linked yet, the FD will point to one of 
813                former group's entries, which will then jump to the first, special entry, in order
814                to invoke the linker.  The linker, after doing the link, will rewrite the FD to
815                point directly to the requested function. 
816
817                As we're only interested in call targets, skip the first group and the buffer entirely,
818                if it's present.
819             */
820             next_plt_entry_addr += (0x10 * 3) + (functionDescriptorCount * 0x10);
821
822             unsigned long long * bufferPtr = (unsigned long long*)(void *)const_cast<char *>(elf_vaddr_to_ptr(next_plt_entry_addr));
823             if( bufferPtr[0] == 0 && bufferPtr[1] == 0 ) { next_plt_entry_addr += 0x10; }
824
825 #elif defined(arch_x86) || defined(arch_x86_64)
826             next_plt_entry_addr += plt_entry_size_;  // 1st PLT entry is special
827 #elif defined (ppc32_linux)
828        //  Do not expect same parameters for ppc64_linux
829        if (!plt_entry_size_) {
830           fprintf(stderr, "%s[%d]:  FIXME:  plt_entry_size not established\n", FILE__, __LINE__);
831           plt_entry_size_ = 8;
832        }
833             next_plt_entry_addr += 9*plt_entry_size_;  // 1st 9 PLT entries are special
834        //fprintf(stderr, "%s[%d]:  skipping %d (6*%d) bytes initial plt\n", 
835        //        FILE__, __LINE__, 9*plt_entry_size_, plt_entry_size_);
836        //  actually this is just fudged to make the offset value 72, which is what binutils uses
837        //  Note that binutils makes the distinction between PLT_SLOT_SIZE (8), 
838        //  and PLT_ENTRY_SIZE (12).  PLT_SLOT_SIZE seems to be what we want, even though we also
839        //  have PLT_INITIAL_ENTRY_SIZE (72)
840        //  see binutils/bfd/elf32-ppc.c/h if more info is needed
841             //next_plt_entry_addr += 72;  // 1st 6 PLT entries art special
842
843 #elif defined(arch_power) && defined(arch_64bit) && defined(os_linux)
844        // PPC64 Linux Bug: PPC64 Linux binaries do not properly identify
845        // text PLT entries.  They only specify the data PLT within the GOT.
846        // By observation, the text PLT is placed at the beginning of the .text
847        // segment, and has 28 bytes of instructions per entry.
848        next_plt_entry_addr = text_addr_;
849
850        // Hacky Heuristic: GCC compilers produce either 24 or 28 byte text PLT
851        // entries.  28 byte text PLT entries begin with an addis (op 15) while
852        // the 24 byte version starts with a std instruction (op 62).
853        for (unsigned iter = 0; iter < regions_.size(); ++iter) {
854            if (regions_[iter]->getRegionName() == TEXT_NAME) {
855                unsigned char insn_byte = *((unsigned char *)regions_[iter]->getPtrToRawData());
856                insn_byte = insn_byte >> 2;
857
858                if (insn_byte == 15)
859                    plt_entry_size_ = 28;
860                else if (insn_byte != 62)
861                    fprintf(stderr, "*** Unknown text PLT opcode %d.  Assuming 24 byte entry size.\n", insn_byte);
862
863                break;
864            }
865        }
866
867 #else
868             next_plt_entry_addr += 4*(plt_entry_size_); //1st 4 entries are special
869 #endif
870
871             Elf_X_Sym sym = symdata.get_sym();
872             Elf_X_Rel rel = reldata.get_rel();
873             Elf_X_Rela rela = reldata.get_rela();
874             const char *strs = strdata.get_string();
875
876             if (sym.isValid() && (rel.isValid() || rela.isValid()) && strs) {
877                 /* Iterate over the entries. */
878                 for( u_int i = 0; i < (rel_plt_size_/rel_plt_entry_size_); ++i ) {
879                     long offset;
880             long addend;
881                     long index;
882             unsigned long type;
883             Region::RegionType rtype = Region::RT_REL;
884
885                     switch (reldata.d_type()) {
886                     case ELF_T_REL:
887                 offset = rel.r_offset(i);
888                 addend = 0;
889                 index = rel.R_SYM(i);
890                 type = rel.R_TYPE(i);
891                 break;
892
893                     case ELF_T_RELA:
894                 offset = rela.r_offset(i);
895                 addend = rela.r_addend(i);
896                 index = rela.R_SYM(i);
897                 type = rela.R_TYPE(i);
898                 rtype = Region::RT_RELA;
899                 break;
900
901                     default:
902                         // We should never reach this case.
903                         return false;
904                     };
905
906                     // /* DEBUG */ fprintf( stderr, "%s: relocation information for target 0x%lx\n", __FUNCTION__, next_plt_entry_addr );
907                     relocationEntry re( next_plt_entry_addr, offset, string( &strs[ sym.st_name(index) ] ), NULL, type );
908             re.setAddend(addend);
909             re.setRegionType(rtype);
910             if(symbols_.find(&strs[ sym.st_name(index)]) != symbols_.end()){
911                 vector<Symbol *> syms = symbols_[&strs[ sym.st_name(index)]];
912                 re.addDynSym(syms[0]);
913             }
914                     fbt_.push_back(re);
915
916 #if ! defined( arch_ia64 )
917                     next_plt_entry_addr += plt_entry_size_;
918 #else
919                     /* IA-64 headers don't declare a size, because it varies. */
920                     next_plt_entry_addr += 0x20;
921 #endif /* ia64_unknown_linux2_4 */
922                 }
923                 return true;
924             }
925         }
926     }
927     return false;
928 }
929
930 void Object::load_object(bool alloc_syms)
931 {
932    Elf_X_Shdr *bssscnp = 0;
933    Elf_X_Shdr *symscnp = 0;
934    Elf_X_Shdr *strscnp = 0;
935    Elf_X_Shdr *stabscnp = 0;
936    Elf_X_Shdr *stabstrscnp = 0;
937    Elf_X_Shdr *stabs_indxcnp = 0;
938    Elf_X_Shdr *stabstrs_indxcnp = 0;
939    Offset txtaddr = 0;
940    Offset dataddr = 0;
941    Elf_X_Shdr *rel_plt_scnp = 0;
942    Elf_X_Shdr *plt_scnp = 0; 
943    Elf_X_Shdr *opd_scnp = 0;
944    Elf_X_Shdr *got_scnp = 0;
945    Elf_X_Shdr *dynsym_scnp = 0;
946    Elf_X_Shdr *dynstr_scnp = 0;
947    Elf_X_Shdr *dynamic_scnp = 0;
948    Elf_X_Shdr *eh_frame_scnp = 0;
949    Elf_X_Shdr *gcc_except = 0;
950    Elf_X_Shdr *interp_scnp = 0;
951
952    { // binding contour (for "goto cleanup")
953
954       // initialize object (for failure detection)
955       code_ptr_ = 0;
956       code_off_ = 0;
957       code_len_ = 0;
958       data_ptr_ = 0;
959       data_off_ = 0;
960       data_len_ = 0;
961
962       // initialize "valid" regions of code and data segments
963       code_vldS_ = (Offset) -1;
964       code_vldE_ = 0;
965       data_vldS_ = (Offset) -1;
966       data_vldE_ = 0;
967
968       // And attempt to parse the ELF data structures in the file....
969       // EEL, added one more parameter
970
971       if (!loaded_elf(txtaddr, dataddr, bssscnp, symscnp, strscnp,
972                stabscnp, stabstrscnp, stabs_indxcnp, stabstrs_indxcnp,
973                rel_plt_scnp,plt_scnp,opd_scnp,got_scnp,dynsym_scnp,
974                dynstr_scnp, dynamic_scnp, eh_frame_scnp,gcc_except, interp_scnp, true)) 
975       {
976          goto cleanup;
977       }
978
979       addressWidth_nbytes = elfHdr.wordSize();
980
981       // find code and data segments....
982       find_code_and_data(elfHdr, txtaddr, dataddr);
983
984       if (elfHdr.e_type() != ET_REL) 
985       {
986          if (!code_ptr_ || !code_len_) 
987          {
988             //bpfatal( "no text segment\n");
989             goto cleanup;
990          }
991
992          if (!data_ptr_ || !data_len_) 
993          {
994             //bpfatal( "no data segment\n");
995             goto cleanup;
996          }
997       }
998       get_valid_memory_areas(elfHdr);
999
1000       //fprintf(stderr, "[%s:%u] - Exe Name\n", __FILE__, __LINE__);
1001
1002 #if defined(os_linux) && (defined(arch_x86) || defined(arch_x86_64))
1003       if (eh_frame_scnp != 0 && gcc_except != 0) 
1004       {
1005          find_catch_blocks(eh_frame_scnp, gcc_except, 
1006                            txtaddr, dataddr, catch_addrs_);
1007       }
1008 #endif
1009       if (interp_scnp)
1010          interpreter_name_ = (char *) interp_scnp->get_data().d_buf(); 
1011
1012       // global symbols are put in global_symbols. Later we read the
1013       // stab section to find the module to where they belong.
1014       // Experiment : lets try to be a bit more intelligent about
1015       // how we initially size the global_symbols table.  
1016       // dictionary_lite takes an initial # of bins (2nd param), 
1017       // a max bin load (3rd param), and a grow factor (4th param).
1018       // Leaving aside the grow factor, lets allocate an initial #
1019       // of bins = nsyms / max bin load.
1020
1021 #if defined(TIMED_PARSE)
1022       struct timeval starttime;
1023       gettimeofday(&starttime, NULL);
1024 #endif
1025       if (alloc_syms) 
1026       {
1027          // find symbol and string data
1028          string module = "DEFAULT_MODULE";
1029          string name   = "DEFAULT_NAME";
1030          Elf_X_Data symdata, strdata;
1031
1032          if (symscnp && strscnp)
1033          {
1034             symdata = symscnp->get_data();
1035             strdata = strscnp->get_data();
1036             parse_symbols(symdata, strdata, bssscnp, symscnp, opd_scnp, false, module);
1037          }   
1038
1039          no_of_symbols_ = nsymbols();
1040
1041          // try to resolve the module names of global symbols
1042          // Sun compiler stab.index section 
1043          fix_global_symbol_modules_static_stab(stabs_indxcnp, stabstrs_indxcnp);
1044
1045          // STABS format (.stab section)
1046          fix_global_symbol_modules_static_stab(stabscnp, stabstrscnp);
1047
1048          // DWARF format (.debug_info section)
1049          fix_global_symbol_modules_static_dwarf();
1050
1051          if (dynamic_addr_ && dynsym_scnp && dynstr_scnp)
1052          {
1053             symdata = dynsym_scnp->get_data();
1054             strdata = dynstr_scnp->get_data();
1055             parse_dynamicSymbols(dynamic_scnp, symdata, strdata, opd_scnp, false, module);
1056          }
1057
1058          //TODO
1059          //Have a hash on the symbol table. Iterate over dynamic symbol table to check if it exists
1060          //If yes set dynamic for the symbol ( How to distinguish between symbols only in symtab,
1061          //         symbols only in dynsymtab & symbols present in both).
1062          // Else add dynamic symbol to dictionary
1063          // (or) Have two sepearate dictionaries. Makes life easy!
1064          // Think about it today!!
1065
1066          //allsymbols = merge(allsymbols, alldynSymbols);
1067
1068 #if defined(TIMED_PARSE)
1069          struct timeval endtime;
1070          gettimeofday(&endtime, NULL);
1071          unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
1072          unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
1073          unsigned long difftime = lendtime - lstarttime;
1074          double dursecs = difftime/(1000);
1075          cout << "parsing/fixing/overriding elf took "<<dursecs <<" msecs" << endl;
1076 #endif
1077
1078          if (dynamic_addr_ && dynsym_scnp && dynstr_scnp) 
1079          {
1080             parseDynamic(dynamic_scnp, dynsym_scnp, dynstr_scnp);
1081          }
1082
1083          // populate "fbt_"
1084          if (rel_plt_scnp && dynsym_scnp && dynstr_scnp) 
1085          {
1086             if (!get_relocation_entries(rel_plt_scnp,dynsym_scnp,dynstr_scnp)) 
1087             {
1088                goto cleanup;
1089             }
1090          }
1091       }
1092
1093       //Set object type
1094       int e_type = elfHdr.e_type();
1095
1096       if (e_type == ET_DYN) 
1097       {
1098          obj_type_ = obj_SharedLib;
1099       }
1100       else if (e_type == ET_EXEC) 
1101       {
1102          obj_type_ = obj_Executable;
1103       }
1104
1105       return;
1106    } // end binding contour (for "goto cleanup2")
1107
1108 cleanup: 
1109    {
1110       /* NOTE: The file should NOT be munmap()ed.  The mapped file is
1111          used for function parsing (see dyninstAPI/src/symtab.C) */
1112
1113       fprintf(stderr, "%s[%d]:  failed to load elf object\n", FILE__, __LINE__);
1114    }
1115 }
1116
1117 void Object::load_shared_object(bool alloc_syms) 
1118 {
1119    Elf_X_Shdr *bssscnp = 0;
1120    Elf_X_Shdr *symscnp = 0;
1121    Elf_X_Shdr *strscnp = 0;
1122    Elf_X_Shdr *stabscnp = 0;
1123    Elf_X_Shdr *stabstrscnp = 0;
1124    Elf_X_Shdr *stabs_indxcnp = 0;
1125    Elf_X_Shdr *stabstrs_indxcnp = 0;
1126    Offset txtaddr = 0;
1127    Offset dataddr = 0;
1128    Elf_X_Shdr *rel_plt_scnp = 0;
1129    Elf_X_Shdr *plt_scnp = 0; 
1130    Elf_X_Shdr *opd_scnp = 0;
1131    Elf_X_Shdr *got_scnp = 0;
1132    Elf_X_Shdr *dynsym_scnp = 0;
1133    Elf_X_Shdr *dynstr_scnp = 0;
1134    Elf_X_Shdr *dynamic_scnp = 0;
1135    Elf_X_Shdr *eh_frame_scnp = 0;
1136    Elf_X_Shdr *gcc_except = 0;
1137    Elf_X_Shdr *interp_scnp = 0;
1138
1139    { // binding contour (for "goto cleanup2")
1140
1141       // initialize "valid" regions of code and data segments
1142       code_vldS_ = (Offset) -1;
1143       code_vldE_ = 0;
1144       data_vldS_ = (Offset) -1;
1145       data_vldE_ = 0;
1146
1147       if (!loaded_elf(txtaddr, dataddr, bssscnp, symscnp, strscnp,
1148                stabscnp, stabstrscnp, stabs_indxcnp, stabstrs_indxcnp,
1149                rel_plt_scnp, plt_scnp, opd_scnp, got_scnp, dynsym_scnp,
1150                dynstr_scnp, dynamic_scnp, eh_frame_scnp, gcc_except, interp_scnp))
1151          goto cleanup2;
1152
1153       addressWidth_nbytes = elfHdr.wordSize();
1154
1155       // find code and data segments....
1156       find_code_and_data(elfHdr, txtaddr, dataddr);
1157
1158       get_valid_memory_areas(elfHdr);
1159
1160 #if defined(os_linux) && (defined(arch_x86) || defined(arch_x86_64))
1161       //fprintf(stderr, "[%s:%u] - Mod Name is %s\n", __FILE__, __LINE__, name.c_str());
1162       if (eh_frame_scnp != 0 && gcc_except != 0) {
1163          find_catch_blocks(eh_frame_scnp, gcc_except, 
1164                            txtaddr, dataddr, catch_addrs_);
1165       }
1166 #endif
1167 #if defined(TIMED_PARSE)
1168       struct timeval starttime;
1169       gettimeofday(&starttime, NULL);
1170 #endif
1171
1172       if (alloc_syms) {
1173          // build symbol dictionary
1174          string module = mf->pathname();
1175          string name   = "DEFAULT_NAME";
1176
1177          Elf_X_Data symdata, strdata;
1178          if (symscnp && strscnp)
1179          {
1180             symdata = symscnp->get_data();
1181             strdata = strscnp->get_data();
1182             if (!symdata.isValid() || !strdata.isValid()) {
1183                log_elferror(err_func_, "locating symbol/string data");
1184                goto cleanup2;
1185             }
1186             bool result = parse_symbols(symdata, strdata, bssscnp, symscnp, opd_scnp, false, module);
1187             if (!result) {
1188                log_elferror(err_func_, "locating symbol/string data");
1189                goto cleanup2;
1190             }
1191          } 
1192
1193          no_of_symbols_ = nsymbols();
1194
1195          if (dynamic_addr_ && dynsym_scnp && dynstr_scnp)
1196          {
1197             symdata = dynsym_scnp->get_data();
1198             strdata = dynstr_scnp->get_data();
1199             parse_dynamicSymbols(dynamic_scnp, symdata, strdata, opd_scnp, false, module);
1200          }
1201
1202 #if defined(TIMED_PARSE)
1203          struct timeval endtime;
1204          gettimeofday(&endtime, NULL);
1205          unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
1206          unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
1207          unsigned long difftime = lendtime - lstarttime;
1208          double dursecs = difftime/(1000 * 1000);
1209          cout << "*INSERT SYMBOLS* elf took "<<dursecs <<" msecs" << endl;
1210          //cout << "parsing/fixing/overriding/insertion elf took "<<dursecs <<" msecs" << endl;
1211 #endif
1212          if(dynamic_addr_ && dynsym_scnp && dynstr_scnp) {
1213             parseDynamic(dynamic_scnp, dynsym_scnp, dynstr_scnp);
1214          }
1215
1216          if (rel_plt_scnp && dynsym_scnp && dynstr_scnp) {
1217             if (!get_relocation_entries(rel_plt_scnp,dynsym_scnp,dynstr_scnp)) { 
1218                goto cleanup2;
1219             }
1220          }
1221       }
1222
1223       //Set object type
1224       int e_type = elfHdr.e_type();
1225       if (e_type == ET_DYN) {
1226          obj_type_ = obj_SharedLib;
1227       }
1228       else if (e_type == ET_EXEC) {
1229          obj_type_ = obj_Executable;
1230       }
1231
1232    } // end binding contour (for "goto cleanup2")
1233
1234 cleanup2: 
1235    {
1236    }
1237 }
1238
1239 static Symbol::SymbolType pdelf_type(int elf_type)
1240 {
1241    switch (elf_type) {
1242       case STT_FILE:   return Symbol::ST_MODULE;
1243       case STT_SECTION:return Symbol::ST_SECTION;
1244       case STT_OBJECT: return Symbol::ST_OBJECT;
1245       case STT_TLS:    return Symbol::ST_OBJECT;  // TODO: new type for thread-local storage?
1246       case STT_FUNC:   return Symbol::ST_FUNCTION;
1247       case STT_NOTYPE: return Symbol::ST_NOTYPE;
1248    }
1249    return Symbol::ST_UNKNOWN;
1250 }
1251
1252 static Symbol::SymbolLinkage pdelf_linkage(int elf_binding)
1253 {
1254    switch (elf_binding) {
1255       case STB_LOCAL:  return Symbol::SL_LOCAL;
1256       case STB_WEAK:   return Symbol::SL_WEAK;
1257       case STB_GLOBAL: return Symbol::SL_GLOBAL;
1258    }
1259    return Symbol::SL_UNKNOWN;
1260 }
1261
1262 static Symbol::SymbolVisibility pdelf_visibility(int elf_visibility)
1263 {
1264    switch (elf_visibility) {
1265       case STV_DEFAULT:    return Symbol::SV_DEFAULT;
1266       case STV_INTERNAL:   return Symbol::SV_INTERNAL;
1267       case STV_HIDDEN:     return Symbol::SV_HIDDEN;
1268       case STV_PROTECTED:  return Symbol::SV_PROTECTED;
1269    }
1270    return Symbol::SV_UNKNOWN;
1271 }
1272
1273 //============================================================================
1274
1275 //#include "dyninstAPI/src/arch.h"
1276 //#include "dyninstAPI/src/inst.h"
1277 //#include "dyninstAPI/src/instPoint.h" // includes instPoint-x86.h
1278 //#include "dyninstAPI/src/instP.h" // class returnInstance
1279 //#include "dyninstAPI/src/rpcMgr.h"
1280
1281 //linear search
1282 bool lookUpSymbol( std::vector< Symbol *>& allsymbols, Offset& addr )
1283 {
1284    for( unsigned i = 0; i < allsymbols.size(); i++ )
1285    {
1286       if( allsymbols[ i ]->getAddr() == addr )
1287       {
1288          return true;
1289       }
1290    }
1291    return false;
1292 }
1293
1294 bool lookUpAddress( std::vector< Offset >& jumpTargets, Offset& addr )
1295 {
1296    for( unsigned i = 0; i < jumpTargets.size(); i++ )
1297    {
1298       if( jumpTargets[ i ] == addr )
1299       {
1300          return true;
1301       }
1302    }
1303    return false;
1304 }
1305
1306 //utitility function to print std::vector of symbols
1307 void printSyms( std::vector< Symbol *>& allsymbols )
1308 {
1309    for( unsigned i = 0; i < allsymbols.size(); i++ )
1310    {
1311       if( allsymbols[ i ]->getType() != Symbol::ST_FUNCTION )
1312       {
1313          continue;
1314       }
1315       cout << allsymbols[ i ] << endl;
1316    } 
1317
1318
1319
1320 // Official Procedure Descriptor handler
1321 //
1322 // Some platforms (PPC64 Linux libc v2.1) only produce function
1323 // symbols which point into the .opd section.  Find the actual
1324 // function address in .text, and fix the symbol.
1325
1326 void fix_opd_symbol(char *opdData, unsigned long opdStart,
1327                     unsigned long opdEnd, Symbol *sym)
1328 {
1329     if (!sym) return;
1330
1331     Symbol::SymbolType stype = sym->getType();
1332     Offset soffset = sym->getOffset();
1333
1334     if (stype == Symbol::ST_FUNCTION || stype == Symbol::ST_NOTYPE) {
1335         if (opdStart <= soffset && soffset < opdEnd) {
1336             // Now we know the symbol address falls within the
1337             // .opd section.  Find the actual address stored
1338             // in the .opd section descriptor.
1339             Offset newOffset = *(Offset *)(opdData + (soffset - opdStart));
1340
1341             // Stash the original address as a pointer address.
1342             sym->setPtrOffset(soffset);
1343
1344             // Update offset with 1st word in descriptor.
1345             sym->setOffset(newOffset);
1346             //fprintf(stderr, "%s: .opd addr (0x%lx) -> (0x%lx)\n",
1347             //        sname.c_str(), soffset, newOffset);
1348
1349             // Finally, if the symbol had no type, fix it.
1350             sym->setSymbolType(Symbol::ST_FUNCTION);
1351         }
1352     }
1353 }
1354
1355 // Libc section function handler
1356 //
1357 // Some versions of libc have internal memory handling functions
1358 // that only have NOTYPE symbols to represent them.  However,
1359 // these symbols do have corresponding regions of the same name.
1360
1361 void fix_libc_section_function_symbol(std::vector< Region *> *regions, Symbol *sym)
1362 {
1363     if (!regions || !sym) return;
1364
1365     if (sym->getType() == Symbol::ST_NOTYPE) {
1366         for (unsigned j = 0; j < regions->size(); ++j) {
1367             const char *regionName = (*regions)[j]->getRegionName().c_str();
1368             if ((*regions)[j]->isText() &&
1369                 strstr(regionName, "_libc_") &&
1370                 strstr(sym->getMangledName().c_str(), regionName) &&
1371                 (*regions)[j]->getMemOffset() == sym->getOffset()) {
1372
1373                 sym->setSymbolType(Symbol::ST_FUNCTION);
1374             }
1375         }
1376     }
1377 }
1378
1379 // parse_symbols(): populate "allsymbols"
1380 bool Object::parse_symbols(Elf_X_Data &symdata, Elf_X_Data &strdata,
1381                            Elf_X_Shdr* bssscnp,
1382                            Elf_X_Shdr* symscnp,
1383                            Elf_X_Shdr* opdscnp,
1384                            bool /*shared*/, string smodule)
1385 {
1386 #if defined(TIMED_PARSE)
1387    struct timeval starttime;
1388    gettimeofday(&starttime, NULL);
1389 #endif
1390
1391    if (!symdata.isValid() || !strdata.isValid()) {
1392       return false;
1393    }
1394
1395    unsigned long opdStart = 0;
1396    unsigned long opdEnd = 0;
1397    char *opdData = 0;
1398    if (opdscnp) {
1399        opdStart = opdscnp->sh_addr();
1400        opdEnd   = opdscnp->sh_addr() + opdscnp->sh_size();
1401        opdData  = (char *)opdscnp->get_data().d_buf();
1402    }
1403
1404    Elf_X_Sym syms = symdata.get_sym();
1405    const char *strs = strdata.get_string();
1406    if(syms.isValid()){
1407       for (unsigned i = 0; i < syms.count(); i++) {
1408          //If it is not a dynamic executable then we need undefined symbols
1409          //in symtab section so that we can resolve symbol references. So 
1410          //we parse & store undefined symbols only if there is no dynamic
1411          //symbol table
1412          //1/09: not so anymore--we want to preserve all symbols,
1413          //regardless of file type
1414       
1415          int etype = syms.ST_TYPE(i);
1416          int ebinding = syms.ST_BIND(i);
1417          int evisibility = syms.ST_VISIBILITY(i);
1418
1419          // resolve symbol elements
1420          string sname = &strs[ syms.st_name(i) ];
1421          Symbol::SymbolType stype = pdelf_type(etype);
1422          Symbol::SymbolLinkage slinkage = pdelf_linkage(ebinding);
1423          Symbol::SymbolVisibility svisibility = pdelf_visibility(evisibility);
1424          unsigned ssize = syms.st_size(i);
1425          unsigned secNumber = syms.st_shndx(i);
1426
1427          Offset soffset;
1428          if (symscnp->isFromDebugFile()) {
1429             Offset soffset_dbg = syms.st_value(i);
1430             if (soffset_dbg) {
1431                bool result = convertDebugOffset(soffset_dbg, soffset);
1432                if (!result) {
1433                   //Symbol does not match any section, can't convert
1434                   continue;
1435                }
1436             }
1437          }
1438          else {
1439             soffset = syms.st_value(i);
1440          }
1441
1442          /* icc BUG: Variables in BSS are categorized as ST_NOTYPE instead of 
1443             ST_OBJECT.  To fix this, we check if the symbol is in BSS and has 
1444             size > 0. If so, we can almost always say it is a variable and hence, 
1445             change the type from ST_NOTYPE to ST_OBJECT.
1446          */
1447
1448
1449          if (bssscnp) {
1450             Offset bssStart = Offset(bssscnp->sh_addr());
1451             Offset bssEnd = Offset (bssStart + bssscnp->sh_size()) ;
1452             
1453             if(( bssStart <= soffset) && ( soffset < bssEnd ) && (ssize > 0) && 
1454                (stype == Symbol::ST_NOTYPE)) 
1455             {
1456                stype = Symbol::ST_OBJECT;
1457             }
1458          }
1459
1460          // discard "dummy" symbol at beginning of file
1461          if (i==0 && sname == "" && soffset == (Offset)0)
1462             continue;
1463
1464          Region *sec;
1465          if(secNumber >= 1 && secNumber <= regions_.size())
1466             sec = regions_[secNumber];
1467          else
1468             sec = NULL;
1469          
1470          Symbol *newsym = new Symbol(sname, 
1471                                      stype,
1472                                      slinkage, 
1473                                      svisibility, 
1474                                      soffset,
1475                                      NULL,
1476                                      sec, 
1477                                      ssize,
1478                                      false,
1479                                      (secNumber == SHN_ABS));
1480          
1481          if (opdscnp)
1482              fix_opd_symbol(opdData, opdStart, opdEnd, newsym);
1483          fix_libc_section_function_symbol(&regions_, newsym);
1484
1485          symbols_[sname].push_back(newsym);
1486          symsByOffset_[newsym->getOffset()].push_back(newsym);
1487          symsToModules_[newsym] = smodule; 
1488 #if 0
1489          // register symbol in dictionary
1490          if ((etype == STT_FILE) && 
1491              (ebinding == STB_LOCAL) && 
1492              (shared) && 
1493              (sname == extract_pathname_tail(smodule))) {
1494             // symbols_[sname] = newsym; // special case
1495             symbols_[sname].push_back( newsym );
1496          } else {
1497             allsymbols.push_back(newsym); // normal case
1498          }
1499 #endif
1500       }
1501    } // syms.isValid()
1502 #if defined(TIMED_PARSE)
1503    struct timeval endtime;
1504    gettimeofday(&endtime, NULL);
1505    unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
1506    unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
1507    unsigned long difftime = lendtime - lstarttime;
1508    double dursecs = difftime/(1000 * 1000);
1509    cout << "parsing elf took "<<dursecs <<" secs" << endl;
1510 #endif
1511    return true;
1512 }
1513
1514 // parse_symbols(): populate "allsymbols"
1515 // Lazy parsing of dynamic symbol  & string tables
1516 // Parsing the dynamic symbols lazily would certainly 
1517 // not increase the overhead of the entire parse
1518 void Object::parse_dynamicSymbols (Elf_X_Shdr *&
1519 #if !defined(os_solaris)
1520                                    dyn_scnp
1521 #endif 
1522                                    , Elf_X_Data &symdata, 
1523                                    Elf_X_Data &strdata,
1524                                    Elf_X_Shdr* opdscnp,
1525                                    bool /*shared*/, 
1526                                    std::string smodule)
1527 {
1528 #if defined(TIMED_PARSE)
1529    struct timeval starttime;
1530    gettimeofday(&starttime, NULL);
1531 #endif
1532
1533    Elf_X_Sym syms = symdata.get_sym();
1534    const char *strs = strdata.get_string();
1535 #if !defined(os_solaris)
1536    Elf_X_Shdr *versymSec = NULL, *verneedSec = NULL, *verdefSec = NULL;
1537    Elf_X_Data data = dyn_scnp->get_data();
1538    Elf_X_Dyn dyns = data.get_dyn();
1539    unsigned verneednum = 0, verdefnum = 0;
1540    Elf_X_Versym symVersions;
1541    Elf_X_Verdef *symVersionDefs = NULL;
1542    Elf_X_Verneed *symVersionNeeds = NULL;
1543    for (unsigned i = 0; i < dyns.count(); ++i) {
1544       switch(dyns.d_tag(i)) {
1545          case DT_NEEDED:
1546             deps_.push_back(&strs[dyns.d_ptr(i)]);
1547             break;
1548          case DT_VERSYM:
1549                versymSec = getRegionHdrByAddr(dyns.d_ptr(i));
1550                break;
1551            case DT_VERNEED:
1552                verneedSec = getRegionHdrByAddr(dyns.d_ptr(i));
1553                break;
1554            case DT_VERDEF:
1555                verdefSec = getRegionHdrByAddr(dyns.d_ptr(i));
1556                break;
1557            case DT_VERNEEDNUM:
1558                verneednum = dyns.d_ptr(i);
1559                break;
1560            case DT_VERDEFNUM:
1561                verdefnum = dyns.d_ptr(i);
1562                break;
1563            default:
1564                break;
1565        }
1566    }
1567    if(versymSec)
1568        symVersions = versymSec->get_data().get_versyms();
1569    if(verdefSec)
1570        symVersionDefs = verdefSec->get_data().get_verDefSym();
1571    if(verneedSec)
1572        symVersionNeeds = verneedSec->get_data().get_verNeedSym();
1573     
1574    for(unsigned i = 0; i < verdefnum ;i++) {
1575        Elf_X_Verdaux *aux = symVersionDefs->get_aux();
1576        for(unsigned j=0; j< symVersionDefs->vd_cnt(); j++){
1577            versionMapping[symVersionDefs->vd_ndx()].push_back(&strs[aux->vda_name()]);
1578            Elf_X_Verdaux *auxnext = aux->get_next();
1579            delete aux;
1580            aux = auxnext;
1581        }
1582        Elf_X_Verdef *symVersionDefsnext = symVersionDefs->get_next();
1583        delete symVersionDefs;
1584        symVersionDefs = symVersionDefsnext;
1585    }
1586
1587    for(unsigned i = 0; i < verneednum; i++){
1588        Elf_X_Vernaux *aux = symVersionNeeds->get_aux();
1589        for(unsigned j=0; j< symVersionNeeds->vn_cnt(); j++){
1590            versionMapping[aux->vna_other()].push_back(&strs[aux->vna_name()]);
1591            versionFileNameMapping[aux->vna_other()] = &strs[symVersionNeeds->vn_file()];
1592            Elf_X_Vernaux *auxnext = aux->get_next();
1593            delete aux;
1594            aux = auxnext;
1595        }
1596        Elf_X_Verneed *symVersionNeedsnext = symVersionNeeds->get_next();
1597        delete symVersionNeeds;
1598        symVersionNeeds = symVersionNeedsnext;
1599    }
1600    
1601 #endif
1602
1603    unsigned long opdStart = 0;
1604    unsigned long opdEnd = 0;
1605    char *opdData = 0;
1606    if (opdscnp) {
1607        opdStart = opdscnp->sh_addr();
1608        opdEnd   = opdscnp->sh_addr() + opdscnp->sh_size();
1609        opdData  = (char *)opdscnp->get_data().d_buf();
1610    }
1611
1612   if(syms.isValid()) { 
1613    for (unsigned i = 0; i < syms.count(); i++) {
1614       int etype = syms.ST_TYPE(i);
1615       int ebinding = syms.ST_BIND(i);
1616       int evisibility = syms.ST_VISIBILITY(i);
1617       
1618       // resolve symbol elements
1619       string sname = &strs[ syms.st_name(i) ];
1620       Symbol::SymbolType stype = pdelf_type(etype);
1621       Symbol::SymbolLinkage slinkage = pdelf_linkage(ebinding);
1622       Symbol::SymbolVisibility svisibility = pdelf_visibility(evisibility);
1623       unsigned ssize = syms.st_size(i);
1624       Offset soffset = syms.st_value(i);
1625       unsigned secNumber = syms.st_shndx(i);
1626
1627       // discard "dummy" symbol at beginning of file
1628       if (i==0 && sname == "" && soffset == (Offset)0)
1629           continue;
1630
1631       /* 11/4/08: don't discard symbols with same name and address */
1632 #if 0
1633       if(symbols_.find(sname) != symbols_.end()) {
1634           vector<Symbol *> syms = symbols_[sname];
1635           for(unsigned j = 0; j < syms.size(); j++){
1636               if(syms[j]->getOffset() == soffset){
1637 #if !defined(os_solaris)
1638                   if(versymSec) {
1639                       if(versionFileNameMapping.find(symVersions.get(i)) != versionFileNameMapping.end())
1640                           syms[j]->setVersionFileName(versionFileNameMapping[symVersions.get(i)]);
1641                       if(versionMapping.find(symVersions.get(i)) != versionMapping.end())
1642                           syms[j]->setVersions(versionMapping[symVersions.get(i)]);
1643                   }
1644 #endif
1645               }
1646           }
1647           continue;
1648        }
1649 #endif
1650      
1651       Region *sec;
1652       if(secNumber >= 1 && secNumber <= regions_.size())
1653          sec = regions_[secNumber];
1654       else
1655          sec = NULL;            
1656
1657       Symbol *newsym = new Symbol(sname, 
1658                                   stype, 
1659                                   slinkage, 
1660                                   svisibility, 
1661                                   soffset, 
1662                                   NULL,
1663                                   sec, 
1664                                   ssize, 
1665                                   true,  // is dynamic
1666                                   (secNumber == SHN_ABS));
1667       
1668       if (opdscnp)
1669           fix_opd_symbol(opdData, opdStart, opdEnd, newsym);
1670       fix_libc_section_function_symbol(&regions_, newsym);
1671
1672 #if !defined(os_solaris)
1673       if(versymSec) {
1674           if(versionFileNameMapping.find(symVersions.get(i)) != versionFileNameMapping.end()) {
1675               //printf("version filename for %s: %s\n", sname.c_str(),
1676                   //versionFileNameMapping[symVersions.get(i)].c_str());
1677               newsym->setVersionFileName(versionFileNameMapping[symVersions.get(i)]);
1678           }
1679           if(versionMapping.find(symVersions.get(i)) != versionMapping.end()) {
1680               //printf("versions for %s: ", sname.c_str());
1681               //for (unsigned k=0; k < versionMapping[symVersions.get(i)].size(); k++)
1682                   //printf(" %s", versionMapping[symVersions.get(i)][k].c_str());
1683               newsym->setVersions(versionMapping[symVersions.get(i)]);
1684               //printf("\n");
1685           }
1686       }
1687 #endif
1688       // register symbol in dictionary
1689       symbols_[sname].push_back(newsym);
1690       symsByOffset_[newsym->getOffset()].push_back(newsym);
1691       symsToModules_[newsym] = smodule; 
1692    }
1693   }
1694
1695 #if defined(TIMED_PARSE)
1696     struct timeval endtime;
1697     gettimeofday(&endtime, NULL);
1698     unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
1699     unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
1700     unsigned long difftime = lendtime - lstarttime;
1701     double dursecs = difftime/(1000 * 1000);
1702     cout << "parsing elf took "<<dursecs <<" secs" << endl;
1703 #endif
1704 }
1705
1706 #if defined(USES_DWARF_DEBUG)
1707
1708 string Object::find_symbol(string name)
1709 {
1710   string name2;
1711
1712   // pass #1: unmodified
1713   name2 = name;
1714   if (symbols_.find(name2)!=symbols_.end()) return name2;
1715
1716   // pass #2: leading underscore (C)
1717   name2 = "_" + name;
1718   if (symbols_.find(name2)!=symbols_.end()) return name2;
1719
1720   // pass #3: trailing underscore (Fortran)
1721   name2 = name + "_";
1722   if (symbols_.find(name2)!=symbols_.end())
1723         return name2;
1724
1725   return "";
1726 }
1727
1728 #endif
1729
1730
1731 /********************************************************
1732  *
1733  * For object files only....
1734  *   read the .debug_info section to find the module of global symbols
1735  *   see documents...
1736  *   - "DWARF Debugging Information Format"
1737  *   - "A Consumer Libary Interface to DWARF"
1738  *
1739  ********************************************************/
1740
1741 #if defined(USES_DWARF_DEBUG)
1742
1743 void pd_dwarf_handler(Dwarf_Error error, Dwarf_Ptr /*userData*/)
1744 {
1745   if (error == NULL)
1746     return;
1747
1748   char *dwarf_msg = dwarf_errmsg(error);
1749   string str = string("DWARF Error: ")+ dwarf_msg;
1750   dwarf_err_func(str.c_str());
1751       
1752   //bperr( "DWARF error: %s\n", dwarf_msg);
1753 }
1754
1755 Dwarf_Signed declFileNo = 0;
1756 char ** declFileNoToName = NULL;
1757
1758 void Object::fixSymbolsInModule( Dwarf_Debug dbg, string & moduleName, Dwarf_Die dieEntry)
1759 {
1760 start: 
1761
1762    Dwarf_Half dieTag;
1763    int status = dwarf_tag( dieEntry, & dieTag, NULL );
1764
1765    assert( status == DW_DLV_OK );
1766
1767    string useModuleName = moduleName;
1768
1769    /* For debugging. */
1770    Dwarf_Off dieOffset;
1771    status = dwarf_die_CU_offset( dieEntry, & dieOffset, NULL );
1772    assert( status == DW_DLV_OK );
1773
1774    switch( dieTag ) {
1775       case DW_TAG_subprogram: 
1776       case DW_TAG_entry_point: 
1777          {
1778             /* Let's try ignoring artificial entries, hmm-kay? */
1779
1780             Dwarf_Bool isArtificial;
1781             status = dwarf_hasattr( dieEntry, DW_AT_artificial, & isArtificial, NULL );
1782             assert( status == DW_DLV_OK );
1783
1784             if ( isArtificial ) 
1785             {
1786                break; 
1787             }
1788
1789             /* Only entries with a PC must be defining declarations.  However,
1790                to avoid trying to decide in which module a DW_TAG_inlined_subroutine's
1791                DW_AT_abstract_origin belongs, we just insert the abstract origin itself. */
1792
1793             Dwarf_Bool hasLowPC;
1794             status = dwarf_hasattr( dieEntry, DW_AT_low_pc, & hasLowPC, NULL );
1795             assert( status == DW_DLV_OK );
1796
1797             Dwarf_Bool isAbstractOrigin;
1798             status = dwarf_hasattr( dieEntry, DW_AT_inline, & isAbstractOrigin, NULL );
1799             assert( status == DW_DLV_OK );
1800
1801             if ( ! hasLowPC && ! isAbstractOrigin ) 
1802             {
1803                break; 
1804             }
1805
1806             bool isDeclaredNotInlined = false;
1807
1808             /* Inline functions are "uninstrumentable", so leave them off the where axis. */
1809
1810             if ( isAbstractOrigin ) 
1811             {
1812                Dwarf_Attribute inlineAttribute;
1813                status = dwarf_attr( dieEntry, DW_AT_inline, & inlineAttribute, NULL );
1814                assert( status == DW_DLV_OK );
1815
1816                Dwarf_Unsigned inlineTag;
1817                status = dwarf_formudata( inlineAttribute, & inlineTag, NULL );
1818                assert( status == DW_DLV_OK );
1819
1820                if ( inlineTag == DW_INL_inlined || inlineTag == DW_INL_declared_inlined ) 
1821                {
1822                   break; 
1823                }
1824
1825                if ( inlineTag == DW_INL_declared_not_inlined ) 
1826                {
1827                   isDeclaredNotInlined = true; 
1828                }
1829
1830                dwarf_dealloc( dbg, inlineAttribute, DW_DLA_ATTR );
1831             }
1832
1833             /* If a DIE has a specification, the specification has its name
1834                and (optional) linkage name.  */
1835
1836             Dwarf_Attribute specificationAttribute;
1837             status = dwarf_attr(dieEntry, DW_AT_specification, &specificationAttribute, NULL);
1838
1839             assert( status != DW_DLV_ERROR );
1840
1841             Dwarf_Die nameEntry = dieEntry;
1842
1843             if ( status == DW_DLV_OK ) 
1844             {
1845                Dwarf_Off specificationOffset;
1846                status = dwarf_global_formref(specificationAttribute, &specificationOffset, NULL);
1847                assert( status == DW_DLV_OK );
1848
1849                status = dwarf_offdie( dbg, specificationOffset, & nameEntry, NULL );
1850                assert( status == DW_DLV_OK );
1851
1852                dwarf_dealloc( dbg, specificationAttribute, DW_DLA_ATTR );
1853             } /* end if the DIE has a specification. */
1854
1855             /* Ignore artificial entries. */
1856
1857             status = dwarf_hasattr( nameEntry, DW_AT_artificial, & isArtificial, NULL );
1858             assert( status == DW_DLV_OK );
1859
1860             if ( isArtificial ) 
1861             {
1862                break; 
1863             }
1864
1865             /* What's its name? */
1866             char * dieName = NULL;
1867             status = dwarf_diename( nameEntry, & dieName, NULL );
1868
1869             assert( status != DW_DLV_ERROR );
1870
1871             /* Prefer the linkage (symbol table) name. */
1872             Dwarf_Attribute linkageNameAttribute;
1873             status = dwarf_attr(nameEntry, DW_AT_MIPS_linkage_name, &linkageNameAttribute, NULL);
1874
1875             assert( status != DW_DLV_ERROR );
1876
1877             bool hasLinkageName = false;
1878
1879             if ( status == DW_DLV_OK ) 
1880             {
1881                dwarf_dealloc( dbg, dieName, DW_DLA_STRING );
1882                status = dwarf_formstring( linkageNameAttribute, & dieName, NULL );
1883                assert( status == DW_DLV_OK );
1884                hasLinkageName = true;
1885             }
1886
1887             /* Anonymous functions are useless to us. */
1888
1889             if ( dieName == NULL ) 
1890             {
1891                break;
1892             }
1893
1894             /* Try to find the corresponding global symbol name. */
1895
1896             Dwarf_Die declEntry = nameEntry;
1897
1898             std::vector<Symbol *> foundSymbols;
1899             
1900             string globalSymbol = find_symbol(dieName);
1901
1902             if (globalSymbol != "") {
1903                 foundSymbols = symbols_[globalSymbol];
1904             }
1905             else if ( globalSymbol == "" && ! hasLinkageName && isDeclaredNotInlined ) 
1906             {
1907                /* Then scan forward for its concrete instance. */
1908
1909                bool first = true;
1910                Dwarf_Die siblingDie = dieEntry;
1911
1912                while ( true ) 
1913                {
1914                   Dwarf_Die priorSibling = siblingDie;
1915                   status = dwarf_siblingof( dbg, siblingDie, & siblingDie, NULL );
1916                   assert( status != DW_DLV_ERROR );
1917
1918                   if ( ! first ) 
1919                   {
1920                      dwarf_dealloc( dbg, priorSibling, DW_DLA_DIE ); 
1921                   }
1922                   if ( status == DW_DLV_NO_ENTRY ) 
1923                   {
1924                      break; 
1925                   }
1926
1927                   Dwarf_Attribute abstractOriginAttr;
1928                   status = dwarf_attr(siblingDie, DW_AT_abstract_origin, &abstractOriginAttr, NULL);
1929
1930                   assert( status != DW_DLV_ERROR );
1931
1932                   /* Is its abstract origin the current dieEntry? */
1933
1934                   if ( status == DW_DLV_OK ) 
1935                   {
1936                      Dwarf_Off abstractOriginOffset;
1937                      status = dwarf_formref( abstractOriginAttr, & abstractOriginOffset, NULL );
1938                      assert( status == DW_DLV_OK );
1939
1940                      dwarf_dealloc( dbg, abstractOriginAttr, DW_DLA_ATTR );
1941
1942                      if ( abstractOriginOffset == dieOffset ) 
1943                      {
1944                         Dwarf_Addr lowPC;
1945                         status = dwarf_lowpc( siblingDie, & lowPC, NULL );
1946                         assert( status == DW_DLV_OK );
1947
1948                         // bperr( "Found function with pretty name '%s' inlined-not-declared at 0x%lx in module '%s'\n", dieName, (unsigned long)lowPC, useModuleName.c_str() );
1949
1950                         if ( symsByOffset_.find((Address)lowPC) != 
1951                              symsByOffset_.end()) {
1952                             foundSymbols = symsByOffset_[(Address)lowPC];
1953                         }
1954
1955                         dwarf_dealloc( dbg, siblingDie, DW_DLA_DIE );
1956                         break;
1957
1958                      } /* end if we've found _the_ concrete instance */
1959                   } /* end if we've found a concrete instance */
1960
1961                   first = false;
1962
1963                } /* end iteration. */
1964             } /* end if we're trying to do a by-address look up. */
1965
1966             if (foundSymbols.size()) {
1967                 /* If it's not specified, is an inlined function in the same
1968                    CU/namespace as its use. */
1969                 
1970                 if ( isDeclaredNotInlined && nameEntry != dieEntry ) {
1971                     /* Then the function's definition is where it was
1972                        declared, not wherever it happens to be referenced.
1973                        
1974                        Use the decl_file as the useModuleName, if available. */
1975                     
1976                     Dwarf_Attribute fileNoAttribute;
1977                     status = dwarf_attr( declEntry, DW_AT_decl_file, & fileNoAttribute, NULL );
1978                     assert( status != DW_DLV_ERROR );
1979                     
1980                     if ( status == DW_DLV_OK ) {
1981                         Dwarf_Unsigned fileNo;
1982                         status = dwarf_formudata( fileNoAttribute, & fileNo, NULL );
1983                         assert( status == DW_DLV_OK );
1984                         
1985                         dwarf_dealloc( dbg, fileNoAttribute, DW_DLA_ATTR );
1986                         
1987                         useModuleName = declFileNoToName[ fileNo - 1 ];
1988                         
1989                         // bperr( "Assuming declared-not-inlined function '%s' to be in module '%s'.\n", dieName, useModuleName.c_str() );
1990                         
1991                     } /* end if we have declaration file listed */
1992                     else {
1993                         /* This should never happen, but there's not much
1994                            we can do if it does. */
1995                     }
1996                 } /* end if isDeclaredNotInlined */
1997                 
1998                 if (foundSymbols.size() == 1) {
1999                     symsToModules_[foundSymbols[0]] = useModuleName;
2000                 }
2001                else {
2002                    for ( unsigned int i = 0; i < foundSymbols.size(); i++ ) {
2003                        if ( foundSymbols[ i ]->getLinkage() == Symbol::SL_GLOBAL ) {
2004                            symsToModules_[foundSymbols[i]] = useModuleName;
2005                        }
2006                    }
2007                }
2008             } /* end if we found the name in the global symbols */
2009             else if ( !isAbstractOrigin &&
2010                       (symbols_.find(dieName) != symbols_.end())) {
2011                 std::vector< Symbol *> & syms = symbols_[ dieName ];
2012
2013                /* If there's only one, apply regardless. */
2014
2015                 if ( syms.size() == 1 ) {
2016                     symsToModules_[syms[0]] = useModuleName;
2017                 }
2018                 else {
2019                     for ( unsigned int i = 0; i < syms.size(); i++ ) {
2020                         if ( syms[ i ]->getLinkage() == Symbol::SL_LOCAL ) {
2021                             symsToModules_[syms[i]] = useModuleName;
2022                         }
2023                     }
2024                 }
2025             } /* end if we think it's a local symbol */
2026             dwarf_dealloc( dbg, dieName, DW_DLA_STRING );
2027          } 
2028
2029          break;
2030
2031       case DW_TAG_variable:
2032       case DW_TAG_constant: 
2033          {
2034             /* Is this a declaration? */
2035
2036             Dwarf_Attribute declAttr;
2037             status = dwarf_attr( dieEntry, DW_AT_declaration, & declAttr, NULL );
2038             assert( status != DW_DLV_ERROR );
2039
2040             if ( status != DW_DLV_OK ) 
2041             { 
2042                break; 
2043             }
2044
2045             dwarf_dealloc( dbg, declAttr, DW_DLA_ATTR );
2046
2047             /* If a DIE has a specification, the specification has its name
2048                and (optional) linkage name.  */
2049
2050             Dwarf_Attribute specificationAttribute;
2051             status = dwarf_attr(dieEntry, DW_AT_specification, &specificationAttribute, NULL);
2052             assert( status != DW_DLV_ERROR );
2053
2054             Dwarf_Die nameEntry = dieEntry;
2055
2056             if ( status == DW_DLV_OK ) 
2057             {
2058                Dwarf_Off specificationOffset;
2059                status = dwarf_global_formref(specificationAttribute, &specificationOffset, NULL);
2060                assert( status == DW_DLV_OK );
2061
2062                dwarf_dealloc( dbg, specificationAttribute, DW_DLA_ATTR );
2063
2064                status = dwarf_offdie( dbg, specificationOffset, & nameEntry, NULL );
2065                assert( status == DW_DLV_OK );
2066
2067             } /* end if the DIE has a specification. */
2068
2069             /* What's its name? */
2070
2071             char * dieName = NULL;
2072             status = dwarf_diename( nameEntry, & dieName, NULL );
2073             assert( status != DW_DLV_ERROR );
2074
2075             /* Prefer the linkage (symbol table) name. */
2076
2077             Dwarf_Attribute linkageNameAttribute;
2078             status = dwarf_attr(nameEntry, DW_AT_MIPS_linkage_name, &linkageNameAttribute, NULL);
2079             assert( status != DW_DLV_ERROR );
2080
2081             if ( status == DW_DLV_OK ) 
2082             {
2083                dwarf_dealloc( dbg, dieName, DW_DLA_STRING );
2084                status = dwarf_formstring( linkageNameAttribute, & dieName, NULL );
2085                assert( status == DW_DLV_OK );
2086             }
2087
2088             /* Anonymous variables are useless to us. */
2089             if ( dieName == NULL ) 
2090             {
2091                break; 
2092             }
2093
2094             /* Update the module information. */
2095
2096             string symName = find_symbol(dieName);
2097
2098             if ( symName != "" ) 
2099             {
2100                 assert(symbols_.find(symName)!=symbols_.end());
2101
2102                /* We're assuming global variables. */
2103                std::vector< Symbol *> & syms = symbols_[ symName ];
2104
2105                /* If there's only one of symbol of that name, set it regardless. */
2106                if ( syms.size() == 1 ) {
2107                    symsToModules_[syms[0]] = useModuleName; 
2108                }
2109                else {
2110                   for ( unsigned int i = 0; i < syms.size(); i++ ) {
2111                       if ( syms[ i ]->getLinkage() == Symbol::SL_GLOBAL ) {
2112                           symsToModules_[syms[i]] = useModuleName;
2113                       }
2114                   }
2115                }
2116             }
2117
2118             // /* DEBUG */ fprintf( stderr, "%s[%d]: DWARF-derived module %s for symbols of name '%s'\n", __FILE__, __LINE__, useModuleName.c_str(), symName.c_str() );
2119
2120             dwarf_dealloc( dbg, dieName, DW_DLA_STRING );
2121
2122          } 
2123
2124          break;
2125
2126       default:
2127          /* If it's not a function or a variable, ignore it. */
2128          break;
2129    } /* end tag switch */
2130
2131    /* Recurse to its child, if any. */
2132
2133    Dwarf_Die childDwarf;
2134    status = dwarf_child( dieEntry, & childDwarf, NULL );
2135    assert( status != DW_DLV_ERROR );
2136
2137    if ( status == DW_DLV_OK )  {
2138        fixSymbolsInModule(dbg, moduleName, childDwarf); 
2139    }
2140
2141    /* Recurse to its sibling, if any. */
2142
2143    Dwarf_Die siblingDwarf;
2144    status = dwarf_siblingof( dbg, dieEntry, & siblingDwarf, NULL );
2145    assert( status != DW_DLV_ERROR );
2146
2147    if ( status == DW_DLV_OK ) 
2148    {
2149       dwarf_dealloc( dbg, dieEntry, DW_DLA_DIE );
2150
2151       /* Force tail-recursion to avoid stack overflows. */
2152       dieEntry = siblingDwarf;
2153       goto start;
2154    }
2155 } /* end fixSymbolsInModule */
2156
2157
2158 unsigned Object::fixSymbolsInModuleByRange(IntervalTree<Dwarf_Addr, std::string> &modules) 
2159 {
2160     if (modules.empty()) return 0;
2161
2162     unsigned nsyms_altered = 0;
2163     
2164     for (dyn_hash_map<Offset, std::vector<Symbol *> >::iterator iter = symsByOffset_.begin();
2165          iter != symsByOffset_.end();
2166          iter++) {
2167         Offset off = iter->first;
2168         std::vector<Symbol *> &syms = iter->second;       
2169
2170         std::string modname;
2171         if (modules.find((Dwarf_Addr) off, modname)) {
2172             for (unsigned i = 0; i < syms.size(); i++) {
2173                 symsToModules_[syms[i]] = modname;
2174                 nsyms_altered++;
2175             }
2176         }
2177     }
2178
2179    return nsyms_altered;
2180 }
2181
2182 bool Object::fix_global_symbol_modules_static_dwarf()
2183 {
2184    int status;
2185    /* Initialize libdwarf. */
2186    Dwarf_Debug *dbg_ptr = dwarf.dbg();
2187    if (!dbg_ptr)
2188       return false;
2189    Dwarf_Debug &dbg = *dbg_ptr;
2190
2191    Dwarf_Unsigned hdr;
2192
2193    IntervalTree<Dwarf_Addr, std::string> module_ranges;
2194
2195    /* Iterate over the CU headers. */
2196    while ( dwarf_next_cu_header( dbg, NULL, NULL, NULL, NULL, & hdr, NULL ) == DW_DLV_OK ) 
2197    {
2198
2199       /* Obtain the module DIE. */
2200       Dwarf_Die moduleDIE;
2201       status = dwarf_siblingof( dbg, NULL, & moduleDIE, NULL );
2202       assert( status == DW_DLV_OK );
2203
2204       /* Make sure we've got the right one. */
2205       Dwarf_Half moduleTag;
2206       status = dwarf_tag( moduleDIE, & moduleTag, NULL);
2207       assert( status == DW_DLV_OK );
2208       assert( moduleTag == DW_TAG_compile_unit );
2209
2210       /* Extract the name of this module. */
2211       char * dwarfModuleName = NULL;
2212       status = dwarf_diename( moduleDIE, & dwarfModuleName, NULL );
2213       assert( status != DW_DLV_ERROR );
2214
2215       string moduleName;
2216
2217       if ( status == DW_DLV_NO_ENTRY || dwarfModuleName == NULL ) 
2218       {
2219          moduleName = string( "{ANONYMOUS}" );
2220          //assert( moduleName != NULL );
2221       }
2222       else 
2223       {
2224          moduleName = extract_pathname_tail( string(dwarfModuleName) );
2225       }
2226
2227       Dwarf_Addr modLowPC = 0;
2228       Dwarf_Addr modHighPC = (Dwarf_Addr)(-1);
2229       Dwarf_Bool hasLowPC;
2230       Dwarf_Bool hasHighPC;
2231
2232       if ( (status = dwarf_hasattr(moduleDIE, DW_AT_low_pc, &hasLowPC, NULL)) == DW_DLV_OK &&
2233             hasLowPC &&
2234             (status = dwarf_hasattr(moduleDIE, DW_AT_high_pc, &hasHighPC, NULL)) == DW_DLV_OK && 
2235             hasHighPC ) 
2236       {
2237          // Get PC boundaries for the module, if present
2238          status = dwarf_lowpc(moduleDIE, &modLowPC, NULL);
2239          assert(status == DW_DLV_OK);
2240
2241          status = dwarf_highpc(moduleDIE, &modHighPC, NULL);
2242          assert(status == DW_DLV_OK);
2243
2244          if (modHighPC == 0) 
2245          {
2246             modHighPC = (Dwarf_Addr)(-1);
2247          }
2248
2249          // Set module names for all symbols that belong to the range
2250          module_ranges.insert(modLowPC, modHighPC, moduleName);
2251       }
2252       else 
2253       {
2254          /* Acquire declFileNoToName. */
2255          status = dwarf_srcfiles( moduleDIE, & declFileNoToName, & declFileNo, NULL );
2256          assert( status != DW_DLV_ERROR );
2257
2258          if ( status == DW_DLV_OK ) 
2259          {
2260             /* Walk the tree. */
2261
2262              //fprintf(stderr, "%s[%d]:  about to fixSymbolsInModule(%s,...)\n",
2263              //     FILE__, __LINE__, moduleName.c_str());
2264
2265              fixSymbolsInModule(dbg, moduleName, moduleDIE);
2266              
2267              /* Deallocate declFileNoToName. */
2268              
2269              for ( Dwarf_Signed i = 0; i < declFileNo; i++ ) {                
2270                  dwarf_dealloc( dbg, declFileNoToName[i], DW_DLA_STRING );
2271              }
2272
2273             dwarf_dealloc( dbg, declFileNoToName, DW_DLA_LIST );        
2274
2275          } /* end if the srcfile information was available */
2276       } /* end if code range information unavailable */
2277
2278    } /* end scan over CU headers. */
2279
2280    if (!module_ranges.empty()) {
2281        fixSymbolsInModuleByRange(module_ranges);
2282    }
2283
2284    return true;
2285 }
2286
2287 #else
2288
2289 // dummy definition for non-DWARF platforms
2290 bool Object::fix_global_symbol_modules_static_dwarf()
2291 { return false; }
2292
2293 #endif // USES_DWARF_DEBUG
2294
2295 /********************************************************
2296  *
2297  * For object files only....
2298  *  read the .stab section to find the module of global symbols
2299  *
2300  ********************************************************/
2301
2302 bool Object::fix_global_symbol_modules_static_stab(Elf_X_Shdr* stabscnp, Elf_X_Shdr* stabstrscnp) 
2303 {
2304    // Read the stab section to find the module of global symbols.
2305    // The symbols appear in the stab section by module. A module begins
2306    // with a symbol of type N_UNDF and ends with a symbol of type N_ENDM.
2307    // All the symbols in between those two symbols belong to the module.
2308
2309    if (!stabscnp || !stabstrscnp) return false;
2310
2311    Elf_X_Data stabdata = stabscnp->get_data();
2312    Elf_X_Data stabstrdata = stabstrscnp->get_data();
2313    stab_entry *stabptr = NULL;
2314
2315    if (!stabdata.isValid() || !stabstrdata.isValid()) return false;
2316
2317    switch (addressWidth_nbytes) 
2318    {
2319       case 4:
2320          stabptr = new stab_entry_32(stabdata.d_buf(),
2321                stabstrdata.get_string(),
2322                stabscnp->sh_size() / sizeof(stab32));
2323          break;
2324
2325       case 8:
2326          stabptr = new stab_entry_64(stabdata.d_buf(),
2327                stabstrdata.get_string(),
2328                stabscnp->sh_size() / sizeof(stab64));
2329          break;
2330    };
2331
2332    const char *next_stabstr = stabptr->getStringBase();
2333    string module = "DEFAULT_MODULE";
2334
2335    // the stabstr contains one string table for each module.
2336    // stabstr_offset gives the offset from the begining of stabstr of the
2337    // string table for the current module.
2338
2339    bool is_fortran = false;  // is the current module fortran code?
2340
2341    for (unsigned i = 0; i < stabptr->count(); i++) 
2342    {
2343       switch(stabptr->type(i)) 
2344       {
2345          case N_UNDF: /* start of object file */
2346             stabptr->setStringBase(next_stabstr);
2347             next_stabstr = stabptr->getStringBase() + stabptr->val(i);
2348             break;
2349
2350          case N_ENDM: /* end of object file */
2351             is_fortran = false;
2352             module = "DEFAULT_MODULE";
2353             break;
2354
2355          case N_SO: /* compilation source or file name */
2356             if ((stabptr->desc(i) == N_SO_FORTRAN) || (stabptr->desc(i) == N_SO_F90))
2357                is_fortran = true;
2358
2359             module = string(stabptr->name(i));
2360             break;
2361
2362          case N_ENTRY: /* fortran alternate subroutine entry point */
2363          case N_GSYM: /* global symbol */
2364             // the name string of a function or object appears in the stab 
2365             // string table as <symbol name>:<symbol descriptor><other stuff>
2366             // where <symbol descriptor> is a one char code.
2367             // we must extract the name and descriptor from the string
2368             {
2369                const char *p = stabptr->name(i);
2370                // bperr("got %d type, str = %s\n", stabptr->type(i), p);
2371                // if (stabptr->type(i) == N_FUN && strlen(p) == 0) {
2372
2373                if (strlen(p) == 0) 
2374                {
2375                   // GNU CC 2.8 and higher associate a null-named function
2376                   // entry with the end of a function.  Just skip it.
2377                   break;
2378                }
2379
2380                const char *q = strchr(p,':');
2381                unsigned len;
2382
2383                if (q) 
2384                {
2385                   len = q - p;
2386                } 
2387                else 
2388                {
2389                   len = strlen(p);
2390                }
2391
2392                if (len == 0)
2393                {
2394                   // symbol name is empty.Skip it.- 02/12/07 -Giri
2395                   break;
2396                }                
2397
2398                char *sname = new char[len+1];
2399                strncpy(sname, p, len);
2400                sname[len] = 0;
2401
2402                string SymName = string(sname);
2403
2404                // q points to the ':' in the name string, so 
2405                // q[1] is the symbol descriptor. We must check the symbol descriptor
2406                // here to skip things we are not interested in, such as prototypes.
2407
2408                bool res = (symbols_.find(SymName)!=symbols_.end());
2409
2410                if (!res && is_fortran) 
2411                {
2412                   // Fortran symbols usually appear with an '_' appended in .symtab,
2413                   // but not on .stab
2414                   SymName += "_";
2415                   res = (symbols_.find(SymName)!=symbols_.end());
2416                }
2417
2418                if (res && (q == 0 || q[1] != SD_PROTOTYPE)) 
2419                {
2420                   unsigned int count = 0;
2421                   std::vector< Symbol *> & syms = symbols_[SymName];
2422
2423                   /* If there's only one, apply regardless. */
2424                   if ( syms.size() == 1 ) 
2425                   { 
2426                      symbols_[SymName][0]->setModuleName(module); 
2427                   }
2428                   else 
2429                   {
2430                      for ( unsigned int i = 0; i < syms.size(); i++ ) 
2431                      {
2432                         if ( syms[i]->getLinkage() == Symbol::SL_GLOBAL ) 
2433                         {
2434                            symbols_[SymName][i]->setModuleName(module);
2435                            count++;
2436                         }
2437                      }
2438                   }
2439                }
2440                break;
2441             }
2442             case N_FUN: 
2443             /* function */ 
2444             {
2445                const char *p = stabptr->name(i);
2446
2447                if (strlen(p) == 0) 
2448                {
2449                   // Rumours are that GNU CC 2.8 and higher associate a
2450                   // null-named function entry with the end of a
2451                   // function. Just skip it.
2452                   break;
2453                }
2454
2455                const char *q = strchr(p,':');
2456
2457                if (q == 0) 
2458                {
2459                   // bperr( "Unrecognized stab format: %s\n", p);
2460                   // Happens with the Solaris native compiler (.xstabs entries?)
2461                   break;
2462                }
2463
2464                if (q[1] == SD_PROTOTYPE) 
2465                {
2466                   // We see a prototype, skip it
2467                   break;
2468                }
2469
2470                unsigned long entryAddr = stabptr->val(i);
2471
2472                if (entryAddr == 0) 
2473                {
2474                   // The function stab doesn't contain a function address
2475                   // (happens with the Solaris native compiler). We have to
2476                   // look up the symbol by its name. That's unfortunate, since
2477                   // names may not be unique and we may end up assigning a wrong
2478                   // module name to the symbol.
2479                   unsigned len = q - p;
2480                   if (len == 0)
2481                   {
2482                      // symbol name is empty.Skip it.- 02/12/07 -Giri
2483                      break;
2484                   }             
2485
2486                   char *sname = new char[len+1];
2487                   strncpy(sname, p, len);
2488                   sname[len] = 0;
2489                   string nameFromStab = string(sname);
2490                   delete[] sname;
2491
2492                   for (unsigned i = 0; i < symbols_[nameFromStab].size(); i++) {
2493                       symsToModules_[symbols_[nameFromStab][i]] = module;
2494                   }
2495                }
2496                else 
2497                {
2498                    if (symsByOffset_.find(entryAddr)==symsByOffset_.end()) {
2499                        //bperr( "fix_global_symbol_modules_static_stab "
2500                        //          "can't find address 0x%lx of STABS entry %s\n", entryAddr, p);
2501                        break;
2502                    }
2503                    for (unsigned i = 0; i < symsByOffset_[entryAddr].size(); i++) {
2504                        symsToModules_[symsByOffset_[entryAddr][i]] = module;
2505                    }
2506 #if !defined (os_solaris)
2507                      //  This is definitely triggered on mutatees compiled with
2508                      //  the solaris compilers -- the fix seems tricky and
2509                      //  possibly not worth the time and energy to restructure
2510                      //  and/or add sufficient further nuance to go back to the
2511                      //  symbol table to infer which nearly identical symbol belongs
2512                      //  to which modules
2513 #endif
2514                }
2515                break;
2516             }
2517
2518             default:
2519             /* ignore other entries */
2520             break;
2521             }
2522       }
2523
2524       delete stabptr;
2525
2526       return true;
2527    }
2528
2529
2530 // find_code_and_data(): populates the following members:
2531 //   code_ptr_, code_off_, code_len_
2532 //   data_ptr_, data_off_, data_len_
2533 void Object::find_code_and_data(Elf_X &elf,
2534       Offset txtaddr, 
2535       Offset dataddr) 
2536 {
2537    for (int i = 0; i < elf.e_phnum(); ++i) {
2538       Elf_X_Phdr phdr = elf.get_phdr(i);
2539
2540       char *file_ptr = (char *)mf->base_addr();
2541
2542       if(!isRegionPresent(phdr.p_paddr(), phdr.p_filesz(), phdr.p_flags()))
2543          regions_.push_back(new Region(i, "", phdr.p_paddr(), phdr.p_filesz(), phdr.p_vaddr(), phdr.p_memsz(), &file_ptr[phdr.p_offset()], getSegmentPerms(phdr.p_flags()), getSegmentType(phdr.p_type(), phdr.p_flags())));
2544
2545       // The code pointer, offset, & length should be set even if
2546       // txtaddr=0, so in this case we set these values by
2547       // identifying the segment that contains the entryAddress
2548       if (((phdr.p_vaddr() <= txtaddr) && 
2549                (phdr.p_vaddr() + phdr.p_filesz() >= txtaddr)) || 
2550             (!txtaddr && ((phdr.p_vaddr() <= entryAddress_) &&
2551                           (phdr.p_vaddr() + phdr.p_filesz() >= entryAddress_)))) {
2552
2553          if (code_ptr_ == 0 && code_off_ == 0 && code_len_ == 0) {
2554             code_ptr_ = (char *)(void*)&file_ptr[phdr.p_offset()];
2555             code_off_ = (Offset)phdr.p_vaddr();
2556             code_len_ = (unsigned)phdr.p_filesz();
2557          }
2558
2559       } else if (((phdr.p_vaddr() <= dataddr) && 
2560                (phdr.p_vaddr() + phdr.p_filesz() >= dataddr)) || 
2561             (!dataddr && (phdr.p_type() == PT_LOAD))) {
2562          if (data_ptr_ == 0 && data_off_ == 0 && data_len_ == 0) {
2563             data_ptr_ = (char *)(void *)&file_ptr[phdr.p_offset()];
2564             data_off_ = (Offset)phdr.p_vaddr();
2565             data_len_ = (unsigned)phdr.p_filesz();
2566          }
2567       }
2568    }
2569    //if (addressWidth_nbytes == 8) bperr( ">>> 64-bit find_code_and_data() successful\n");
2570 }
2571
2572 const char *Object::elf_vaddr_to_ptr(Offset vaddr) const
2573 {
2574    const char *ret = NULL;
2575    unsigned code_size_ = code_len_;
2576    unsigned data_size_ = data_len_;
2577
2578 #if defined(os_irix)
2579    vaddr -= base_addr;
2580 #endif
2581
2582    if (vaddr >= code_off_ && vaddr < code_off_ + code_size_) {
2583       ret = ((char *)code_ptr_) + (vaddr - code_off_);
2584    } else if (vaddr >= data_off_ && vaddr < data_off_ + data_size_) {
2585       ret = ((char *)data_ptr_) + (vaddr - data_off_);
2586    } 
2587
2588    return ret;
2589 }
2590
2591 stab_entry *Object::get_stab_info() const
2592 {
2593    char *file_ptr = (char *)mf->base_addr();
2594
2595    // check that file has .stab info
2596    if (stab_off_ && stab_size_ && stabstr_off_) {
2597       switch (addressWidth_nbytes) {
2598          case 4: // 32-bit object
2599             return new stab_entry_32(file_ptr + stab_off_,
2600                   file_ptr + stabstr_off_,
2601                   stab_size_ / sizeof(stab32));
2602             break;
2603          case 8: // 64-bit object
2604             return new stab_entry_64(file_ptr + stab_off_,
2605                   file_ptr + stabstr_off_,
2606                   stab_size_ / sizeof(stab64));
2607             break;
2608       };
2609    }
2610
2611    //fprintf(stderr, "%s[%d]:  WARNING:  FIXME, stab_off = %d, stab_size = %d, stabstr_off_ = %d\n", FILE__, __LINE__, stab_off_, stab_size_, stabstr_off_);
2612    return new stab_entry_64();
2613 }
2614
2615 Object::Object(MappedFile *mf_, MappedFile *mfd, void (*err_func)(const char *), 
2616       bool alloc_syms) :
2617    AObject(mf_, mfd, err_func), 
2618    dwarf(this),
2619    EEL(false),
2620    DbgSectionMapSorted(false)
2621 {
2622 #if defined(TIMED_PARSE)
2623    struct timeval starttime;
2624    gettimeofday(&starttime, NULL);
2625 #endif
2626 #if defined(os_solaris)
2627    loadNativeDemangler();
2628 #endif    
2629    is_aout_ = false;
2630    did_open = false;
2631    interpreter_name_ = NULL;
2632    isStripped = false;
2633    if(mf->getFD() != -1)
2634       elfHdr = Elf_X(mf->getFD(), ELF_C_READ);
2635    else
2636       elfHdr = Elf_X((char *)mf->base_addr(), mf->size());
2637
2638    mfForDebugInfo = findMappedFileForDebugInfo();
2639    // ELF header: sanity check
2640    //if (!elfHdr.isValid()|| !pdelf_check_ehdr(elfHdr)) 
2641    if (!elfHdr.isValid())  {
2642       log_elferror(err_func_, "ELF header");
2643       return;
2644    }
2645    else if (!pdelf_check_ehdr(elfHdr)) {
2646       log_elferror(err_func_, "ELF header failed integrity check");
2647    }
2648    if( elfHdr.e_type() == 3 )
2649       load_shared_object(alloc_syms);
2650    else if( elfHdr.e_type() == 1 || elfHdr.e_type() == 2 ) {
2651       is_aout_ = true;
2652       load_object(alloc_syms);
2653    }    
2654    else {
2655       log_perror(err_func_,"Invalid filetype in Elf header");
2656       return;
2657    }
2658 #ifdef BINEDIT_DEBUG
2659    print_symbol_map(&symbols_);
2660 #endif
2661 #if defined(TIMED_PARSE)
2662    struct timeval endtime;
2663    gettimeofday(&endtime, NULL);
2664    unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
2665    unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
2666    unsigned long difftime = lendtime - lstarttime;
2667    double dursecs = difftime/(1000 );
2668    cout << "obj parsing in Object-elf took "<<dursecs <<" msecs" << endl;
2669 #endif
2670 }
2671
2672 //Object constructor for archive members
2673 Object::Object(MappedFile *mf_, MappedFile *mfd, std::string &member_name, Offset offset,       
2674                void (*err_func)(const char *), void *base, bool alloc_syms) :
2675    AObject(mf_, mfd, err_func), 
2676    dwarf(this),
2677    EEL(false),
2678    DbgSectionMapSorted(false)
2679 {
2680 #if defined(TIMED_PARSE)
2681    struct timeval starttime;
2682    gettimeofday(&starttime, NULL);
2683 #endif
2684 #if defined(os_solaris)
2685    loadNativeDemangler();
2686 #endif    
2687    is_aout_ = false;
2688    did_open = false;
2689    interpreter_name_ = NULL;
2690    isStripped = false;
2691
2692    elfHdr = *(((Elf_X *)base)->e_rand(offset));
2693    Elf_Arhdr *archdr = elf_getarhdr(elfHdr.e_elfp());
2694    assert(member_name == string(archdr->ar_name));
2695
2696    // ELF header: sanity check
2697    //if (!elfHdr.isValid()|| !pdelf_check_ehdr(elfHdr)) 
2698    if (!elfHdr.isValid())  {
2699       log_elferror(err_func_, "ELF header");
2700       return;
2701    }
2702    assert(elfHdr.e_type() == ET_REL);
2703
2704    if( elfHdr.e_type() == 3 )
2705       load_shared_object(alloc_syms);
2706    else if( elfHdr.e_type() == 1 || elfHdr.e_type() == 2 ) {
2707       is_aout_ = true;
2708       load_object(alloc_syms);
2709    }    
2710    else {
2711       log_perror(err_func_,"Invalid filetype in Elf header");
2712       return;
2713    }
2714 #ifdef BINEDIT_DEBUG
2715    print_symbol_map(&symbols_);
2716 #endif
2717 #if defined(TIMED_PARSE)
2718    struct timeval endtime;
2719    gettimeofday(&endtime, NULL);
2720    unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
2721    unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
2722    unsigned long difftime = lendtime - lstarttime;
2723    double dursecs = difftime/(1000 );
2724    cout << "obj parsing in Object-elf took "<<dursecs <<" msecs" << endl;
2725 #endif
2726 }
2727
2728 Object::Object(const Object& obj)
2729    : AObject(obj), 
2730      dwarf(this),
2731      EEL(false)
2732 {
2733 #if defined(os_solaris)
2734    loadNativeDemangler();
2735 #endif    
2736    interpreter_name_ = obj.interpreter_name_;
2737    isStripped = obj.isStripped;
2738    loadAddress_ = obj.loadAddress_;
2739    entryAddress_ = obj.entryAddress_;
2740    relocation_table_ = obj.relocation_table_;
2741    fbt_ = obj.fbt_;
2742    elfHdr = obj.elfHdr;
2743    deps_ = obj.deps_;
2744    DbgSectionMapSorted = obj.DbgSectionMapSorted;
2745 }
2746
2747 #if 0
2748 const Object& Object::operator=(const Object& obj) 
2749 {
2750    (void) AObject::operator=(obj);
2751
2752    dynsym_addr_ = obj.dynsym_addr_;
2753    dynstr_addr_ = obj.dynstr_addr_;
2754    got_addr_ = obj.got_addr_;
2755    plt_addr_ = obj.plt_addr_;
2756    plt_size_ = obj.plt_size_;
2757    plt_entry_size_ = obj.plt_entry_size_;
2758    rel_plt_addr_ = obj.rel_plt_addr_;
2759    rel_plt_size_ = obj.rel_plt_size_;
2760    rel_plt_entry_size_ = obj.rel_plt_entry_size_;
2761    rel_size_ = obj.rel_size_;
2762    rel_entry_size_ = obj.rel_entry_size_;
2763    stab_off_ = obj.stab_off_;
2764    stab_size_ = obj.stab_size_;
2765    stabstr_off_ = obj.stabstr_off_;
2766    relocation_table_  = obj.relocation_table_;
2767    fbt_  = obj.fbt_;
2768    dwarvenDebugInfo = obj.dwarvenDebugInfo;
2769    versionMapping = obj.versionMapping;
2770    versionFileNameMapping = obj.versionFileNameMapping;
2771    deps_ = obj.deps_;
2772    elfHdr = obj.elfHdr; 
2773    DbgSectionMapSorted = obj.DbgSectionMapSorted;
2774    return *this;
2775 }
2776 #endif
2777
2778 Object::~Object()
2779 {
2780    //   if (fileName) free((void *)fileName);
2781    unsigned i;
2782    relocation_table_.clear();
2783    fbt_.clear();
2784    for(i=0; i<allRegionHdrs.size();i++)
2785       delete allRegionHdrs[i];
2786    allRegionHdrs.clear();
2787    versionMapping.clear();
2788    versionFileNameMapping.clear();
2789    deps_.clear();
2790 }
2791
2792 void Object::log_elferror(void (*err_func)(const char *), const char* msg) 
2793 {
2794    const char* err = elf_errmsg(elf_errno());
2795    err = err ? err: "(bad elf error)";
2796    string str = string(err)+string(msg);
2797    err_func(str.c_str());
2798 }
2799
2800 bool Object::get_func_binding_table(std::vector<relocationEntry> &fbt) const 
2801 {
2802    if(!plt_addr_ || (!fbt_.size())) return false;
2803    fbt = fbt_;
2804    return true;
2805 }
2806
2807 bool Object::get_func_binding_table_ptr(const std::vector<relocationEntry> *&fbt) const 
2808 {
2809    if(!plt_addr_ || (!fbt_.size())) return false;
2810    fbt = &fbt_;
2811    return true;
2812 }
2813
2814 void Object::getDependencies(std::vector<std::string> &deps){
2815    deps = deps_;
2816 }
2817
2818 bool Object::addRelocationEntry(relocationEntry &re)
2819 {
2820    relocation_table_.push_back(re);
2821    return true;
2822 }
2823
2824 #ifdef DEBUG
2825
2826 // stream-based debug output
2827 const ostream &Object::dump_state_info(ostream &s) 
2828 {
2829    s << "Debugging Information for Object (address) : " << this << endl;
2830
2831    s << " <<begin debugging info for base object>>" << endl;
2832    AObject::dump_state_info(s);
2833    s << " <<end debuggingo info for base object>>" << endl;
2834
2835    s << " dynsym_addr_ = " << dynsym_addr_ << endl;
2836    s << " dynstr_addr_ = " << dynstr_addr_ << endl;
2837    s << " got_addr_ = " << got_addr_ << endl;
2838    s << " plt_addr_ = " << plt_addr_ << endl;
2839    s << " plt_size_ = " << plt_size_ << endl;
2840    s << " plt_entry_size_ = " << plt_entry_size_ << endl;
2841    s << " rel_plt_addr_ = " << rel_plt_addr_ << endl; 
2842    s << " rel_plt_size_ = " << rel_plt_size_ << endl;
2843    s << " rel_plt_entry_size_ = " << rel_plt_entry_size_ << endl;
2844    s << " rel_size_ = " << rel_size_ << endl;
2845    s << " rel_entry_size_ = " << rel_entry_size_ << endl;
2846    s << " stab_off_ = " << stab_off_ << endl;
2847    s << " stab_size_ = " << stab_size_ << endl;
2848    s << " stabstr_off_ = " << stabstr_off_ << endl;
2849    s << " dwarvenDebugInfo = " << dwarvenDebugInfo << endl;
2850
2851    // and dump the relocation table....
2852    s << " fbt_ = (field seperator :: )" << endl;   
2853    for (unsigned i=0; i < fbt_.size(); i++) {
2854       s << fbt_[i] << " :: "; 
2855    }
2856    s << endl;
2857
2858    return s;
2859
2860
2861 #endif
2862
2863
2864 Offset Object::getPltSlot(string funcName) const
2865 {
2866    relocationEntry re;
2867    bool found= false;
2868    Offset offset=0;
2869
2870    for ( unsigned int i = 0; i < fbt_.size(); i++ ){
2871       if (funcName == fbt_[i].name() ){
2872          found = true;
2873          offset =  fbt_[i].rel_addr();
2874       }
2875    }
2876
2877    return offset;       
2878 }
2879
2880 //
2881 // get_valid_memory_areas - get ranges of code/data segments that have
2882 //                       sections mapped to them
2883 //
2884
2885 void Object::get_valid_memory_areas(Elf_X &elf)
2886 {
2887    for (unsigned i = 0; i < elf.e_shnum(); ++i) {
2888       Elf_X_Shdr shdr = elf.get_shdr(i);
2889       if ( !shdr.isValid()) { 
2890          break; 
2891       }
2892       if (shdr.sh_flags() & SHF_ALLOC) { // This section is in memory
2893          if (code_off_ <= shdr.sh_addr() &&
2894                shdr.sh_addr() <= code_off_ + code_len_) {
2895             if (shdr.sh_addr() < code_vldS_)
2896                code_vldS_ = shdr.sh_addr();
2897             if (shdr.sh_addr() + shdr.sh_size() > code_vldE_)
2898                code_vldE_ = shdr.sh_addr() + shdr.sh_size();
2899
2900          } else if (data_off_ <= shdr.sh_addr() &&
2901                shdr.sh_addr() <= data_off_ + data_len_) {
2902             if (shdr.sh_addr() < data_vldS_)
2903                data_vldS_ = shdr.sh_addr();
2904             if (shdr.sh_addr() + shdr.sh_size() > data_vldE_)
2905                data_vldE_ = shdr.sh_addr() + shdr.sh_size();
2906          }
2907       }
2908    }
2909 }
2910
2911 //
2912 // parseCompilerType - parse for compiler that was used to generate object
2913 //
2914 //
2915 //
2916 #if defined(os_linux)
2917 // Differentiating between g++ and pgCC by stabs info (as in the solaris/
2918 // aix case, below) will not work; the gcc-compiled object files that
2919 // get included at link time will fill in the N_OPT stabs line. Instead,
2920 // look for "pgCC_compiled." symbols.
2921 bool parseCompilerType(Object *objPtr)
2922 {
2923    dyn_hash_map<string, std::vector<Symbol *> >*syms = objPtr->getAllSymbols(); 
2924    if(syms->find("pgCC_compiled.") != syms->end())
2925       return true;
2926    return false;        
2927
2928 #else
2929 bool parseCompilerType(Object *objPtr) 
2930 {
2931    stab_entry *stabptr = objPtr->get_stab_info();
2932    const char *next_stabstr = stabptr->getStringBase();
2933
2934    for (unsigned int i=0; i < stabptr->count(); ++i) {
2935       // if (stabstrs) bperr("parsing #%d, %s\n", stabptr->type(i), stabptr->name(i));
2936       switch (stabptr->type(i)) {
2937
2938          case N_UNDF: /* start of object file */
2939             /* value contains offset of the next string table for next module */
2940             // assert(stabptr.nameIdx(i) == 1);
2941             stabptr->setStringBase(next_stabstr);
2942             next_stabstr = stabptr->getStringBase() + stabptr->val(i);
2943             break;
2944
2945          case N_OPT: /* Compiler options */
2946 #if defined(os_solaris) 
2947             if (strstr(stabptr->name(i), "Sun") != NULL ||
2948                   strstr(stabptr->name(i), "Forte") != NULL)
2949             {
2950                delete stabptr;
2951                return true;
2952             }
2953 #endif
2954             delete stabptr;
2955             return false;
2956       }
2957    }
2958    delete stabptr;
2959    return false; // Shouldn't happen - maybe N_OPT stripped
2960 }
2961 #endif
2962
2963
2964 #if defined(os_linux) && (defined(arch_x86) || defined(arch_x86_64))
2965
2966 static unsigned long read_uleb128(const unsigned char *data, unsigned *bytes_read)
2967 {
2968    unsigned long result = 0;
2969    unsigned shift = 0;
2970    *bytes_read = 0;
2971    while (1)
2972    {
2973       result |= (data[*bytes_read] & 0x7f) << shift;
2974       if ((data[(*bytes_read)++] & 0x80) == 0)
2975          break;
2976       shift += 7;
2977    }
2978    return result;
2979 }
2980
2981 static signed long read_sleb128(const unsigned char *data, unsigned *bytes_read)
2982 {
2983    unsigned long result = 0;
2984    unsigned shift = 0;
2985    *bytes_read = 0;
2986    while (1)
2987    {
2988       result |= (data[*bytes_read] & 0x7f) << shift;
2989       shift += 7;
2990       if ((data[*bytes_read] & 0x80) == 0)
2991          break;
2992       (*bytes_read)++;
2993    }
2994    if (shift < sizeof(int) && (data[*bytes_read] & 0x40))
2995       result |= -(1 << shift);
2996    (*bytes_read)++;
2997    return result;
2998 }
2999
3000 #define DW_EH_PE_absptr  0x00
3001 #define DW_EH_PE_uleb128 0x01
3002 #define DW_EH_PE_udata2  0x02
3003 #define DW_EH_PE_udata4  0x03
3004 #define DW_EH_PE_udata8  0x04
3005 #define DW_EH_PE_sleb128 0x09
3006 #define DW_EH_PE_sdata2  0x0A
3007 #define DW_EH_PE_sdata4  0x0B
3008 #define DW_EH_PE_sdata8  0x0C
3009 #define DW_EH_PE_pcrel   0x10
3010 #define DW_EH_PE_textrel 0x20
3011 #define DW_EH_PE_datarel 0x30
3012 #define DW_EH_PE_funcrel 0x40
3013 #define DW_EH_PE_aligned 0x50
3014 #define DW_EH_PE_omit    0xff
3015
3016 typedef struct {
3017    int word_size;
3018    unsigned long pc;
3019    unsigned long text;
3020    unsigned long data;
3021    unsigned long func;
3022 } mach_relative_info;
3023
3024 static int read_val_of_type(int type, unsigned long *value, const unsigned char *addr,
3025                            const mach_relative_info &mi)
3026 {
3027     unsigned size = 0;
3028    if (type == DW_EH_PE_omit)
3029       return 0;
3030
3031    unsigned long base = 0x0;
3032    /**
3033     * LSB Standard says that the upper four bits (0xf0) encode the base.
3034     * Except that none of these values should their upper bits set,
3035     * and I'm finding the upper bit seems to sometimes contain garbage.
3036     * gcc uses the 0x70 bits in its exception parsing, so that's what we'll do.
3037     **/
3038    switch (type & 0x70)
3039    {
3040       case DW_EH_PE_pcrel:
3041          base = mi.pc;
3042          break;
3043       case DW_EH_PE_textrel:
3044          base = mi.text;
3045          break;
3046       case DW_EH_PE_datarel:
3047          base = mi.data;
3048          break;
3049       case DW_EH_PE_funcrel:
3050          base = mi.func;
3051          break;
3052    }
3053
3054    switch (type & 0x0f)
3055    {
3056       case DW_EH_PE_absptr:
3057          if (mi.word_size == 4) {
3058             *value = (unsigned long) *((const uint32_t *) addr);
3059             size = 4;
3060          }
3061          else if (mi.word_size == 8) {
3062             *value = (unsigned long) *((const uint64_t *) addr);
3063             size = 8;
3064          }
3065          break;
3066       case DW_EH_PE_uleb128:
3067          *value = base + read_uleb128(addr, &size);
3068          break;
3069       case DW_EH_PE_sleb128:
3070          *value = base + read_sleb128(addr, &size);
3071          break;
3072       case DW_EH_PE_udata2:
3073          *value = base + *((const uint16_t *) addr);
3074          size = 2;
3075          break;
3076       case DW_EH_PE_sdata2:         
3077          *value = base + *((const int16_t *) addr);
3078          size = 2;
3079          break;
3080       case DW_EH_PE_udata4:
3081          *value = base + *((const uint32_t *) addr);
3082          size = 4;
3083          break;
3084       case DW_EH_PE_sdata4:
3085          *value = base + *((const int32_t *) addr);
3086          size = 4;
3087          break;
3088       case DW_EH_PE_udata8:
3089          *value = base + *((const uint64_t *) addr);
3090          size = 8;
3091          break;
3092       case DW_EH_PE_sdata8:
3093          *value = base + *((const int64_t *) addr);
3094          size = 8;
3095          break;
3096       default:
3097          return -1;
3098    }
3099
3100    if ((type & 0x70) == DW_EH_PE_aligned)
3101    {
3102       if (mi.word_size == 4) {
3103          *value &= ~(0x3l);
3104       }
3105       else if (mi.word_size == 8) {
3106          *value &= ~(0x7l);
3107       }
3108    }
3109
3110    return size;
3111 }
3112
3113 /**
3114  * On GCC 3.x/x86 we find catch blocks as follows:
3115  *   1. We start with a list of FDE entries in the .eh_frame
3116  *      table.  
3117  *   2. Each FDE entry has a pointer to a  CIE entry.  The CIE
3118  *      tells us whether the FDE has any 'Augmentations', and
3119  *      the types of those augmentations.  The FDE also
3120  *      contains a pointer to a function.
3121  *   3. If one of the FDE augmentations is a 'Language Specific Data Area' 
3122  *      then we have a pointer to one or more entires in the gcc_except_table.
3123  *   4. The gcc_except_table contains entries that point 
3124  *      to try and catch blocks, all encoded as offsets
3125  *      from the function start (it doesn't tell you which
3126  *      function, however). 
3127  *   5. We can add the function offsets from the gcc_except_table
3128  *      to the function pointer from the FDE to get all of
3129  *      the try/catch blocks.  
3130  **/ 
3131 #define SHORT_FDE_HLEN 4 
3132 #define LONG_FDE_HLEN 12
3133 static 
3134 int read_except_table_gcc3(Dwarf_Fde *fde_data, Dwarf_Signed fde_count,
3135                            mach_relative_info &mi,
3136                            Elf_X_Shdr *eh_frame, Elf_X_Shdr *except_scn,
3137                            std::vector<ExceptionBlock> &addresses)
3138 {
3139    Dwarf_Error err = (Dwarf_Error) NULL;
3140    Dwarf_Addr low_pc;
3141    Dwarf_Unsigned bytes_in_cie;
3142    Dwarf_Off fde_offset, cie_offset;
3143    Dwarf_Fde fde;
3144    Dwarf_Cie cie;
3145    int status, result, ptr_size;
3146    char *augmentor;
3147    unsigned char lpstart_format, ttype_format, table_format;
3148    unsigned long value, table_end, region_start, region_size;
3149    unsigned long catch_block, action, augmentor_len;
3150    Dwarf_Small *fde_augdata, *cie_augdata;
3151    Dwarf_Unsigned fde_augdata_len, cie_augdata_len;
3152    
3153    //For each FDE
3154    for (int i = 0; i < fde_count; i++) {
3155       unsigned int j;
3156       unsigned char lsda_encoding = 0xff, personality_encoding = 0xff;
3157       unsigned char *lsda_ptr = NULL, *personality_routine = NULL;
3158       unsigned char *cur_augdata;
3159       unsigned long except_off;
3160       unsigned long fde_addr, cie_addr;
3161       unsigned char *fde_bytes, *cie_bytes;
3162
3163       //Get the FDE
3164       status = dwarf_get_fde_n(fde_data, (Dwarf_Unsigned) i, &fde, &err);
3165       if (status != DW_DLV_OK) {
3166          pd_dwarf_handler(err, NULL);
3167          return false;
3168       }
3169
3170       //After this set of computations we should have:
3171       // low_pc = mi.func = the address of the function that contains this FDE
3172       // fde_bytes = the start of the FDE in our memory space
3173       // cie_bytes = the start of the CIE in our memory space
3174       status = dwarf_get_fde_range(fde, &low_pc, NULL, (void **) &fde_bytes,
3175                                    NULL, &cie_offset, NULL, 
3176                                    &fde_offset, &err);
3177       if (status != DW_DLV_OK) {
3178          pd_dwarf_handler(err, NULL);
3179          return false;
3180       }
3181       //The LSB strays from the DWARF here, when parsing the except_eh section
3182       // the cie_offset is relative to the FDE rather than the start of the
3183       // except_eh section.
3184       cie_offset = fde_offset - cie_offset +
3185          (*(uint32_t*)fde_bytes == 0xffffffff ? LONG_FDE_HLEN : SHORT_FDE_HLEN);
3186       cie_bytes = (unsigned char *)eh_frame->get_data().d_buf() + cie_offset;
3187
3188       //Get the CIE for the FDE
3189       status = dwarf_get_cie_of_fde(fde, &cie, &err);
3190       if (status != DW_DLV_OK) {
3191          pd_dwarf_handler(err, NULL);
3192          return false;
3193       }
3194
3195       //Get the Augmentation string for the CIE
3196       status = dwarf_get_cie_info(cie, &bytes_in_cie, NULL, &augmentor, 
3197                                   NULL, NULL, NULL, NULL, NULL, &err); 
3198       if (status != DW_DLV_OK) {
3199          pd_dwarf_handler(err, NULL);
3200          return false;
3201       }
3202       
3203       //Check that the string pointed to by augmentor has a 'L',
3204       // meaning we have a LSDA
3205       augmentor_len = (augmentor == NULL) ? 0 : strlen(augmentor);
3206       for (j = 0; j < augmentor_len; j++) {
3207          if (augmentor[j] == 'L') {
3208             break;
3209          }
3210       }
3211       if (j == augmentor_len)
3212          //If we don't have a language specific data area, then
3213          // we don't care about this FDE.
3214          continue;
3215
3216       //Some ptr encodings may be of type DW_EH_PE_pcrel, which means
3217       // that they're relative to their own location in the binary.  
3218       // We'll figure out where the FDE and CIE original load addresses
3219       // were and use those in pcrel computations.
3220       fde_addr = eh_frame->sh_addr() + fde_offset;
3221       cie_addr = eh_frame->sh_addr() + cie_offset;
3222       
3223       //Extract encoding information from the CIE.  
3224       // The CIE may have augmentation data, specified in the 
3225       // Linux Standard Base. The augmentation string tells us how
3226       // which augmentation data is present.  We only care about one 
3227       // field, a byte telling how the LSDA pointer is encoded.
3228       status = dwarf_get_cie_augmentation_data(cie, 
3229                                                &cie_augdata,
3230                                                &cie_augdata_len,
3231                                                &err);
3232       if (status != DW_DLV_OK) {
3233          pd_dwarf_handler(err, NULL);
3234          return false;
3235       }
3236
3237       cur_augdata = (unsigned char *) cie_augdata;
3238       lsda_encoding = DW_EH_PE_omit;
3239       for (j=0; j<augmentor_len; j++)
3240       {
3241          if (augmentor[j] == 'L')
3242          {
3243             lsda_encoding = *cur_augdata;
3244             cur_augdata++;
3245          }
3246          else if (augmentor[j] == 'P')
3247          {
3248             //We don't actually need the personality info, but we extract it 
3249             // anyways to make sure we properly extract the LSDA.
3250             personality_encoding = *cur_augdata;
3251             cur_augdata++;
3252             unsigned long personality_val;
3253             mi.pc = cie_addr + (unsigned long) (cur_augdata - cie_bytes);
3254             cur_augdata += read_val_of_type(personality_encoding, 
3255                                             &personality_val, cur_augdata, mi);
3256             personality_routine = (unsigned char *) personality_val;
3257          }
3258          else if (augmentor[j] == 'z' || augmentor[j] == 'R')
3259          {
3260             //Do nothing, these don't affect the CIE encoding.
3261          }
3262          else
3263          {
3264             //Fruit, Someone needs to check the Linux Standard Base, 
3265             // section 11.6 (as of v3.1), to see what new encodings 
3266             // exist and how we should decode them in the CIE.
3267             break;
3268          }
3269       }
3270       if (lsda_encoding == DW_EH_PE_omit)
3271          continue;
3272
3273
3274       //Read the LSDA pointer out of the FDE.
3275       // The FDE has an augmentation area, similar to the above one in the CIE.
3276       // Where-as the CIE augmentation tends to contain things like bytes describing 
3277       // pointer encodings, the FDE contains the actual pointers.
3278       status = dwarf_get_fde_augmentation_data(fde, 
3279                                                &fde_augdata,
3280                                                &fde_augdata_len,
3281                                                &err);
3282       if (status != DW_DLV_OK) {
3283          pd_dwarf_handler(err, NULL);
3284          return false;
3285       }
3286       cur_augdata = (unsigned char *) fde_augdata;
3287       for (j=0; j<augmentor_len; j++)
3288       {
3289          if (augmentor[j] == 'L')
3290          {
3291             unsigned long lsda_val;
3292             mi.pc = fde_addr + (unsigned long) (cur_augdata - fde_bytes);          
3293             ptr_size = read_val_of_type(lsda_encoding, &lsda_val, cur_augdata, mi);
3294             if (ptr_size == -1)
3295                break;
3296             lsda_ptr = (unsigned char *) lsda_val;
3297             cur_augdata += ptr_size;
3298          }
3299          else if (augmentor[j] == 'P' ||
3300                   augmentor[j] == 'z' ||
3301                   augmentor[j] == 'R')
3302          {
3303             //These don't affect the FDE augmentation data, do nothing
3304          }
3305          else
3306          {
3307             //See the comment for the 'else' case in the above CIE parsing
3308             break;
3309          }
3310       }
3311       if (!lsda_ptr)
3312          //Many FDE's have an LSDA area, but then have a NULL LSDA ptr.  
3313          // Just means there's no exception info here.
3314          continue;
3315
3316       // Get the exception data from the section.
3317       Elf_X_Data data = except_scn->get_data();
3318       if (!data.isValid()) {
3319          return false;
3320       }
3321
3322       const unsigned char *datap = (const unsigned char *) data.get_string();
3323       unsigned long int except_size = data.d_size();
3324
3325       except_off = (unsigned long) (lsda_ptr - except_scn->sh_addr());
3326       if (except_off >= except_size) {
3327          continue;
3328       }
3329
3330       // Read some variable length header info that we don't really
3331       // care about.
3332       lpstart_format = datap[except_off++];
3333       if (lpstart_format != DW_EH_PE_omit)
3334          except_off += read_val_of_type(DW_EH_PE_uleb128, &value, datap + except_off, mi);
3335       ttype_format = datap[except_off++];
3336       if (ttype_format != DW_EH_PE_omit)
3337          except_off += read_val_of_type(DW_EH_PE_uleb128, &value, datap + except_off, mi);
3338
3339       // This 'type' byte describes the data format of the entries in the 
3340       // table and the format of the table_size field.
3341       table_format = datap[except_off++];
3342       mi.pc = except_scn->sh_addr() + except_off;
3343       result = read_val_of_type(table_format, &table_end, datap + except_off, mi);
3344       if (result == -1) {
3345          continue;
3346       }
3347       except_off += result;
3348       table_end += except_off;
3349
3350       while (except_off < table_end && except_off < except_size) {
3351          //The entries in the gcc_except_table are the following format:
3352          //   <type>   region start
3353          //   <type>   region length
3354          //   <type>   landing pad
3355          //  uleb128   action
3356          //The 'region' is the try block, the 'landing pad' is the catch.
3357          mi.pc = except_scn->sh_addr() + except_off;
3358          except_off += read_val_of_type(table_format, &region_start, 
3359                                         datap + except_off, mi);
3360          mi.pc = except_scn->sh_addr() + except_off;
3361          except_off += read_val_of_type(table_format, &region_size, 
3362                                         datap + except_off, mi);
3363          mi.pc = except_scn->sh_addr() + except_off;
3364          except_off += read_val_of_type(table_format, &catch_block, 
3365                                         datap + except_off, mi);
3366          except_off += read_val_of_type(DW_EH_PE_uleb128, &action, 
3367                                         datap + except_off, mi);
3368
3369          if (catch_block == 0)
3370             continue;
3371          ExceptionBlock eb(region_start + low_pc, (unsigned) region_size, 
3372                            catch_block + low_pc);
3373          addresses.push_back(eb);
3374       }
3375    }
3376
3377    return true;
3378 }
3379
3380 /**
3381  * Things were much simpler in the old days.  On gcc 2.x
3382  * the gcc_except_table looks like:
3383  *   <long> try_start
3384  *   <long> try_end
3385  *   <long> catch_start
3386  * Where everything is an absolute address, even when compiled
3387  * with PIC.  All we got to do is read the catch_start entries
3388  * out of it.
3389  **/
3390 static bool read_except_table_gcc2(Elf_X_Shdr *except_table, 
3391                                    std::vector<ExceptionBlock> &addresses,
3392                                    const mach_relative_info &mi)
3393 {
3394    Offset try_start;
3395    Offset try_end;
3396    Offset catch_start;
3397
3398    Elf_X_Data data = except_table->get_data();
3399    const unsigned char *datap = (const unsigned char *)data.get_string();
3400    unsigned long except_size = data.d_size();
3401
3402    unsigned i = 0;
3403    while (i < except_size) {
3404       if (mi.word_size == 4) {
3405          i += read_val_of_type(DW_EH_PE_udata4, &try_start, datap + i, mi);
3406          i += read_val_of_type(DW_EH_PE_udata4, &try_end, datap + i, mi);
3407          i += read_val_of_type(DW_EH_PE_udata4, &catch_start, datap + i, mi);
3408       }
3409       else if (mi.word_size == 8) {
3410          i += read_val_of_type(DW_EH_PE_udata8, &try_start, datap + i, mi);
3411          i += read_val_of_type(DW_EH_PE_udata8, &try_end, datap + i, mi);
3412          i += read_val_of_type(DW_EH_PE_udata8, &catch_start, datap + i, mi);
3413       }
3414
3415       if (try_start != (Offset) -1 && try_end != (Offset) -1) {
3416          ExceptionBlock eb(try_start, (unsigned) (try_end - try_start), catch_start);
3417          addresses.push_back(eb);
3418       }
3419    }
3420    return true;
3421 }
3422
3423 struct  exception_compare: public binary_function<const ExceptionBlock &, const ExceptionBlock &, bool> 
3424 {
3425    bool operator()(const ExceptionBlock &e1, const ExceptionBlock &e2) {
3426       if (e1.tryStart() < e2.tryStart())
3427          return true;
3428       else if (e1.tryStart() > e2.tryStart())
3429          return false;
3430       else
3431          return true;
3432    }
3433 };
3434
3435 /**
3436  * Finds the addresses of catch blocks in a g++ generated elf file.
3437  *  'except_scn' should point to the .gcc_except_table section
3438  *  'eh_frame' should point to the .eh_frame section
3439  *  the addresses will be pushed into 'addresses'
3440  **/
3441 bool Object::find_catch_blocks(Elf_X_Shdr *eh_frame, 
3442                               Elf_X_Shdr *except_scn, 
3443                               Address txtaddr, Address dataaddr,
3444       std::vector<ExceptionBlock> &catch_addrs)
3445 {
3446    Dwarf_Cie *cie_data;
3447    Dwarf_Fde *fde_data;
3448    Dwarf_Signed cie_count, fde_count;
3449    Dwarf_Error err = (Dwarf_Error) NULL;
3450    Dwarf_Unsigned bytes_in_cie;
3451    Offset eh_frame_base, except_base;
3452    char *augmentor;
3453    int status, gcc_ver = 3;
3454    unsigned i;
3455    bool result = false;
3456
3457    if (except_scn == NULL) {
3458       //likely to happen if we're not using gcc
3459       return true;
3460    }
3461
3462    eh_frame_base = eh_frame->sh_addr();
3463    except_base = except_scn->sh_addr();
3464
3465    Dwarf_Debug *dbg_ptr = dwarf.dbg();
3466    if (!dbg_ptr) {
3467       pd_dwarf_handler(err, NULL);
3468       return false;
3469    }
3470    Dwarf_Debug &dbg = *dbg_ptr;
3471
3472    //Read the FDE and CIE information
3473    status = dwarf_get_fde_list_eh(dbg, &cie_data, &cie_count,
3474          &fde_data, &fde_count, &err);
3475    if (status != DW_DLV_OK) {
3476       //fprintf(stderr, "[%s:%u] - No fde data\n", __FILE__, __LINE__);
3477       //No actual stackwalk info in this object
3478       return false;
3479    }
3480    //fprintf(stderr, "[%s:%u] - Found %d fdes\n", __FILE__, __LINE__, fde_count);
3481
3482    mach_relative_info mi;
3483    mi.text = txtaddr;
3484    mi.data = dataaddr;
3485    mi.pc = 0x0;
3486    mi.func = 0x0;
3487    mi.word_size = eh_frame->wordSize();
3488
3489
3490    //GCC 2.x has "eh" as its augmentor string in the CIEs
3491    for (i = 0; i < cie_count; i++) {
3492       status = dwarf_get_cie_info(cie_data[i], &bytes_in_cie, NULL,
3493             &augmentor, NULL, NULL, NULL, NULL, NULL, &err);
3494       if (status != DW_DLV_OK) {
3495          pd_dwarf_handler(err, NULL);
3496          goto cleanup;
3497       }
3498       if (augmentor[0] == 'e' && augmentor[1] == 'h') {
3499          gcc_ver = 2;
3500       }