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