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