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