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