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