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