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