Determine the architecture of an ELF by looking at the file header instead of the...
[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.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::emitElf<ElfTypes32>;
326
327 extern template
328 class Dyninst::SymtabAPI::emitElf<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             Elf_X_Data data = scn.get_data();
625             if(strcmp(name, OPD_NAME) == 0)
626             {
627                 data.d_type(ELF_T_XWORD);
628                 data.xlatetom(elfHdr->e_endian() ? ELFDATA2MSB : ELFDATA2LSB);
629             }
630             if(scn.sh_flags() & SHF_ALLOC) {
631                 // .bss, etc. have a disk size of 0
632                 unsigned long diskSize  = (scn.sh_type() == SHT_NOBITS) ? 0 : scn.sh_size();
633
634                 Region *reg = new Region(i, name, scn.sh_addr(), diskSize,
635                                          scn.sh_addr(), scn.sh_size(),
636                                          ((char*)data.d_buf()),
637                                          getRegionPerms(scn.sh_flags()),
638                                          getRegionType(scn.sh_type(),
639                                                        scn.sh_flags(),
640                                                        name),
641                                          true, ((scn.sh_flags() & SHF_TLS) != 0),
642                                          scn.sh_addralign());
643                 reg->setFileOffset(scn.sh_offset());
644                 regions_.push_back(reg);
645             }
646             else {
647                 Region *reg = new Region(i, name, scn.sh_addr(), scn.sh_size(), 0, 0,
648                                          ((char*)data.d_buf()),
649                                          getRegionPerms(scn.sh_flags()),
650                                          getRegionType(scn.sh_type(),
651                                                        scn.sh_flags(),
652                                                        name),
653                                          false, ((scn.sh_flags() & SHF_TLS) != 0),
654                                          scn.sh_addralign());
655
656                 reg->setFileOffset(scn.sh_offset());
657                 regions_.push_back(reg);
658             }
659         }
660
661         // section-specific processing
662         if (P_strcmp(name, EDITED_TEXT_NAME) == 0) {
663             // EEL rewritten executable
664             EEL = true;
665             if (txtaddr == 0)
666                 txtaddr = scn.sh_addr();
667             char *file_ptr = (char *)mf->base_addr();
668             code_ptr_ = (char *)(void*)&file_ptr[scn.sh_offset() - EXTRA_SPACE];
669             code_off_ = scn.sh_addr() - EXTRA_SPACE;
670             code_len_ = scn.sh_size() + EXTRA_SPACE;
671         }
672
673         if (strcmp(name, TEXT_NAME) == 0) {
674             text_addr_ = scn.sh_addr();
675             text_size_ = scn.sh_size();
676
677             if (txtaddr == 0)
678                 txtaddr = scn.sh_addr();
679
680             // .o's don't have program headers, so these members need
681             // to be populated here
682             if( !elfHdr->e_phnum() && !code_len_) {
683                 // Populate code members
684                 code_ptr_ = reinterpret_cast<char *>(scn.get_data().d_buf());
685                 code_off_ = scn.sh_offset();
686                 code_len_ = scn.sh_size();
687             }
688         }
689             /* The following sections help us find the PH entry that
690        encompasses the data region. */
691         else if (strcmp(name, DATA_NAME) == 0) {
692             dataddr = scn.sh_addr();
693
694             // .o's don't have program headers, so these members need
695             // to be populated here
696             if( !elfHdr->e_phnum() && !data_len_) {
697                 // Populate data members
698                 data_ptr_ = reinterpret_cast<char *>(scn.get_data().d_buf());
699                 data_off_ = scn.sh_offset();
700                 data_len_ = scn.sh_size();
701             }
702         }
703         else if (strcmp(name, RO_DATA_NAME) == 0) {
704             if (!dataddr) dataddr = scn.sh_addr();
705         }
706         else if (strcmp(name, GOT_NAME) == 0) {
707             got_scnp = scnp;
708             got_addr_ = scn.sh_addr();
709             got_size_ = scn.sh_size();
710             if (!dataddr) dataddr = scn.sh_addr();
711         }
712         else if (strcmp(name, BSS_NAME) == 0) {
713             bssscnp = scnp;
714             if (!dataddr) dataddr = scn.sh_addr();
715         }
716             /* End data region search */
717             /*else if (strcmp( name, FINI_NAME) == 0) {
718       fini_addr_ = scn.sh_addr();
719       }*/
720         else if (strcmp(name, SYMTAB_NAME) == 0) {
721             if (!symscnp) {
722                 symscnp = scnp;
723                 symtab_addr_ = scn.sh_addr();
724             }
725         }
726         else if (strcmp(name, STRTAB_NAME) == 0) {
727             if (!strscnp) {
728                 strscnp = scnp;
729                 strtab_addr_ = scn.sh_addr();
730             }
731         } else if (strcmp(name, STAB_INDX_NAME) == 0) {
732             stabs_indxcnp = scnp;
733             stab_indx_off_ = scn.sh_offset();
734             stab_indx_size_ = scn.sh_size();
735         } else if (strcmp(name, STABSTR_INDX_NAME) == 0) {
736             stabstrs_indxcnp = scnp;
737             stabstr_indx_off_ = scn.sh_offset();
738         } else if (strcmp(name, STAB_NAME) == 0) {
739             stabscnp = scnp;
740             stab_off_ = scn.sh_offset();
741             stab_size_ = scn.sh_size();
742         } else if (strcmp(name, STABSTR_NAME) == 0) {
743             stabstrscnp = scnp;
744             stabstr_off_ = scn.sh_offset();
745         }
746 #if defined(os_vxworks)
747             else if ((strcmp(name, REL_PLT_NAME) == 0) ||
748              (strcmp(name, REL_PLT_NAME2) == 0)) {
749       rel_plt_scnp = scnp;
750       rel_plt_addr_ = scn.sh_addr();
751       rel_plt_size_ = scn.sh_size();
752       rel_plt_entry_size_ = scn.sh_entsize();
753     }
754 #else
755         else if ((secAddrTagMapping.find(scn.sh_addr()) != secAddrTagMapping.end() ) &&
756                  secAddrTagMapping[scn.sh_addr()] == DT_JMPREL ) {
757             rel_plt_scnp = scnp;
758             rel_plt_addr_ = scn.sh_addr();
759             rel_plt_size_ = scn.sh_size();
760             rel_plt_entry_size_ = scn.sh_entsize();
761         }
762 #endif
763         else if (strcmp(name, OPD_NAME) == 0) {
764             opd_scnp = scnp;
765             opd_addr_ = scn.sh_addr();
766             opd_size_ = scn.sh_size();
767         }
768         else if (strcmp(name, PLT_NAME) == 0) {
769             plt_scnp = scnp;
770             plt_addr_ = scn.sh_addr();
771             plt_size_ = scn.sh_size();
772             if(getArch() == Dyninst::Arch_x86 || getArch() == Dyninst::Arch_x86_64) {
773                 //
774                 // On x86, the GNU linker purposefully sets the PLT
775                 // table entry size to an incorrect value to be
776                 // compatible with the UnixWare linker.  (See the comment
777                 // in the elf_i386_finish_dynamic_sections function of
778                 // the BFD library.)  The GNU linker sets this value to 4,
779                 // when it should be 16.
780                 //
781                 // I see no good way to determine this value from the
782                 // ELF section header information.  We can either (a) hard-code
783                 // the value that is used in the BFD library, or (b) compute
784                 // it by dividing the size of the PLT by the number of entries
785                 // we think should be in the PLT.  I'm not certain, but I
786                 // believe the PLT and the .rel.plt section should have the
787                 // same number of "real" entries (the x86 PLT has one extra entry
788                 // at the beginning).
789                 //
790                 // This code is applicable to any x86 system that uses the
791                 // GNU linker.  We currently only support Linux on x86 - if
792                 // we start supporting some other x86 OS that uses the GNU
793                 // linker in the future, it should be enabled for that platform as well.
794                 // Note that this problem does not affect the non-x86 platforms
795                 // that might use the GNU linker.  For example, programs linked
796                 // with gld on SPARC Solaris have the correct PLT entry size.
797                 //
798                 // Another potential headache in the future is if we support
799                 // some other x86 platform that has both the GNU linker and
800                 // some other linker.  (Does BSD fall into this category?)
801                 // If the two linkers set the entry size differently, we may
802                 // need to re-evaluate this code.
803                 //
804                 //plt_entry_size_ = plt_size_ / ((rel_plt_size_ / rel_plt_entry_size_) + 1);
805                 plt_entry_size_ = 16;
806                 assert(plt_entry_size_ == 16);
807             }
808             else
809             {
810                 plt_entry_size_ = scn.sh_entsize();
811                 if(getArch() == Dyninst::Arch_ppc32)
812                 {
813                     if (scn.sh_flags() & SHF_EXECINSTR) {
814                         // Old style executable PLT
815                         if (!plt_entry_size_)
816                             plt_entry_size_ = 8;
817                         else {
818                             if (plt_entry_size_ != 8)
819                                 create_printf("%s[%d]:  weird plt_entry_size_ is %d, not 8\n",
820                                               FILE__, __LINE__, plt_entry_size_);
821                         }
822
823                     } else {
824                         // New style secure PLT
825                         plt_entry_size_ = 16;
826                     }
827                 }
828             }
829         } else if (strcmp(name, COMMENT_NAME) == 0) {
830             /* comment section is a sequence of NULL-terminated strings.
831          We want to concatenate them and search for BGP to determine
832          if the binary is built for BGP compute nodes */
833
834             Elf_X_Data data = scn.get_data();
835
836             unsigned int index = 0;
837             size_t size = data.d_size();
838             char *buf = (char *) data.d_buf();
839             while (buf && (index < size))
840             {
841                 string comment = buf+index;
842                 size_t pos_p = comment.find("BGP");
843                 size_t pos_q = comment.find("BGQ");
844                 if (pos_p !=string::npos) {
845                     isBlueGeneP_ = true;
846                     break;
847                 } else if (pos_q !=string::npos) {
848                     isBlueGeneQ_ = true;
849                     break;
850                 }
851                 index += comment.size();
852                 if (comment.size() == 0) { // Skip NULL characters in the comment section
853                     index ++;
854                 }
855             }
856         }
857
858         else if ((secAddrTagMapping.find(scn.sh_addr()) != secAddrTagMapping.end() ) &&
859                  secAddrTagMapping[scn.sh_addr()] == DT_SYMTAB ) {
860             is_dynamic_ = true;
861             dynsym_scnp = scnp;
862             dynsym_addr_ = scn.sh_addr();
863             dynsym_size_ = scn.sh_size()/scn.sh_entsize();
864         }
865         else if ((secAddrTagMapping.find(scn.sh_addr()) != secAddrTagMapping.end() ) &&
866                  secAddrTagMapping[scn.sh_addr()] == DT_STRTAB ) {
867             dynstr_scnp = scnp;
868             dynstr_addr_ = scn.sh_addr();
869         }
870         else if (strcmp(name, ".debug_info") == 0) {
871             dwarvenDebugInfo = true;
872         }
873         else if (strcmp(name, EH_FRAME_NAME) == 0) {
874             eh_frame = scnp;
875         }
876         else if ((strcmp(name, EXCEPT_NAME) == 0) ||
877                  (strcmp(name, EXCEPT_NAME_ALT) == 0)) {
878             gcc_except = scnp;
879         }
880         else if (strcmp(name, INTERP_NAME) == 0) {
881             interp_scnp = scnp;
882         }
883         else if ((int) i == dynamic_section_index) {
884             dynamic_scnp = scnp;
885             dynamic_addr_ = scn.sh_addr();
886         }
887     }
888
889     if(!symscnp || !strscnp) {
890         isStripped = true;
891         if(dynsym_scnp && dynstr_scnp){
892             symscnp = dynsym_scnp;
893             strscnp = dynstr_scnp;
894         }
895     }
896
897     loadAddress_ = 0x0;
898 #if defined(os_linux) || defined(os_freebsd)
899     /**
900    * If the virtual address of the first PT_LOAD element in the
901    * program table is 0, Linux loads the shared object into any
902    * free spot into the address space.  If the virtual address is
903    * non-zero, it gets loaded only at that address.
904    **/
905     for (unsigned i = 0; i < elfHdr->e_phnum() && !loadAddress_; ++i) {
906         Elf_X_Phdr &phdr = elfHdr->get_phdr(i);
907
908         if (phdr.p_type() == PT_LOAD) {
909             loadAddress_ = phdr.p_vaddr();
910             break;
911         }
912     }
913 #endif
914
915     // save a copy of region headers, maintaining order in section header table
916     allRegionHdrsByShndx = allRegionHdrs;
917
918     // sort the section headers by base address
919     sort(allRegionHdrs.begin(), allRegionHdrs.end(), SectionHeaderSortFunction());
920
921     for (unsigned j = 0 ; j < regions_.size() ; j++) {
922         if (secAddrTagMapping.find(regions_[j]->getDiskOffset()) != secAddrTagMapping.end()) {
923             secTagRegionMapping[secAddrTagMapping[regions_[j]->getDiskOffset()]] = regions_[j];
924         }
925     }
926
927 #if defined(TIMED_PARSE)
928     struct timeval endtime;
929   gettimeofday(&endtime, NULL);
930   unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
931   unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
932   unsigned long difftime = lendtime - lstarttime;
933   double dursecs = difftime/(1000 );
934   cout << "main loop of loaded elf took "<<dursecs <<" msecs" << endl;
935 #endif
936
937     if (!dataddr || !symscnp || !strscnp) {
938         //log_elferror(err_func_, "no text/bss/symbol/string section");
939     }
940     //if (addressWidth_nbytes == 8) bperr( ">>> 64-bit loaded_elf() successful\n");
941     return true;
942 }
943
944 bool Object::is_offset_in_plt(Offset offset) const
945 {
946     return (offset > plt_addr_ && offset < plt_addr_ + plt_size_);
947 }
948
949 void Object::parseDynamic(Elf_X_Shdr *&dyn_scnp, Elf_X_Shdr *&dynsym_scnp,
950                           Elf_X_Shdr *&dynstr_scnp)
951 {
952     Elf_X_Data data = dyn_scnp->get_data();
953     Elf_X_Dyn dyns = data.get_dyn();
954     int rel_scnp_index = -1;
955
956     for (unsigned i = 0; i < dyns.count(); ++i) {
957         switch(dyns.d_tag(i)) {
958             case DT_REL:
959             case DT_RELA:
960                 /*found Relocation section*/
961                 rel_addr_ = (Offset) dyns.d_ptr(i);
962                 rel_scnp_index = getRegionHdrIndexByAddr(dyns.d_ptr(i));
963                 break;
964             case DT_JMPREL:
965                 rel_plt_addr_ = (Offset) dyns.d_ptr(i);
966                 break;
967             case DT_PLTRELSZ:
968                 rel_plt_size_ = dyns.d_val(i) ;
969                 break;
970             case DT_RELSZ:
971             case DT_RELASZ:
972                 rel_size_ = dyns.d_val(i) ;
973                 break;
974             case DT_RELENT:
975             case DT_RELAENT:
976                 rel_entry_size_ = dyns.d_val(i);
977                 /* Maybe */
978                 //rel_plt_entry_size_ = dyns.d_val(i);
979                 break;
980             case DT_INIT:
981                 init_addr_ = dyns.d_val(i);
982                 break;
983             case DT_FINI:
984                 fini_addr_ = dyns.d_val(i);
985                 break;
986             default:
987                 break;
988         }
989     }
990     if (rel_scnp_index  != -1)
991         get_relocationDyn_entries(rel_scnp_index, dynsym_scnp, dynstr_scnp);
992 }
993
994 /* parse relocations for the sections represented by DT_REL/DT_RELA in
995  * the dynamic section. This section is the one we would want to emit
996  */
997 bool Object::get_relocationDyn_entries( unsigned rel_scnp_index,
998                                         Elf_X_Shdr *&dynsym_scnp,
999                                         Elf_X_Shdr *&dynstr_scnp )
1000 {
1001     Elf_X_Data symdata = dynsym_scnp->get_data();
1002     Elf_X_Data strdata = dynstr_scnp->get_data();
1003     Elf_X_Shdr* rel_scnp = NULL;
1004     if( !symdata.isValid() || !strdata.isValid())
1005         return false;
1006     const char *strs = strdata.get_string();
1007     Elf_X_Sym sym = symdata.get_sym();
1008
1009     unsigned num_rel_entries_found = 0;
1010     unsigned num_rel_entries = rel_size_/rel_entry_size_;
1011
1012     if (rel_addr_ + rel_size_ > rel_plt_addr_){
1013         // REL/RELA section overlaps with REL PLT section
1014         num_rel_entries = (rel_plt_addr_-rel_addr_)/rel_entry_size_;
1015     }
1016     while (num_rel_entries_found != num_rel_entries) {
1017         rel_scnp = getRegionHdrByIndex(rel_scnp_index++);
1018         Elf_X_Data reldata = rel_scnp->get_data();
1019
1020         if( ! reldata.isValid()) return false;
1021         Elf_X_Rel rel = reldata.get_rel();
1022         Elf_X_Rela rela = reldata.get_rela();
1023
1024         if (sym.isValid() && (rel.isValid() || rela.isValid()) && strs) {
1025             /* Iterate over the entries. */
1026             for( u_int i = 0; i < (reldata.d_size()/rel_entry_size_); ++i ) {
1027                 num_rel_entries_found++;
1028                 long offset;
1029                 long addend;
1030                 long index;
1031                 unsigned long type;
1032                 Region::RegionType rtype = Region::RT_REL;
1033
1034                 switch (reldata.d_type()) {
1035                     case ELF_T_REL:
1036                         offset = rel.r_offset(i);
1037                         addend = 0;
1038                         index = rel.R_SYM(i);
1039                         type = rel.R_TYPE(i);
1040                         break;
1041
1042                     case ELF_T_RELA:
1043                         offset = rela.r_offset(i);
1044                         addend = rela.r_addend(i);
1045                         index = rela.R_SYM(i);
1046                         type = rela.R_TYPE(i);
1047                         rtype = Region::RT_RELA;
1048                         break;
1049
1050                     default:
1051                         // We should never reach this case.
1052                         return false;
1053                 };
1054                 relocationEntry re( offset, string( &strs[ sym.st_name(index) ] ), NULL, type );
1055                 re.setAddend(addend);
1056                 re.setRegionType(rtype);
1057                 if(symbols_.find(&strs[ sym.st_name(index)]) != symbols_.end()){
1058                     vector<Symbol *> &syms = symbols_[&strs[ sym.st_name(index)]];
1059                     for (vector<Symbol *>::iterator i = syms.begin(); i != syms.end(); i++) {
1060                         if (!(*i)->isInDynSymtab())
1061                             continue;
1062                         re.addDynSym(*i);
1063                         break;
1064                     }
1065                 }
1066
1067                 relocation_table_.push_back(re);
1068             }
1069         } else {
1070             return false;
1071         }
1072
1073     }
1074     return true;
1075 }
1076
1077 bool Object::get_relocation_entries( Elf_X_Shdr *&rel_plt_scnp,
1078                                      Elf_X_Shdr *&dynsym_scnp,
1079                                      Elf_X_Shdr *&dynstr_scnp )
1080 {
1081     if (rel_plt_size_ && rel_plt_addr_) {
1082         Elf_X_Data reldata = rel_plt_scnp->get_data();
1083         Elf_X_Data symdata = dynsym_scnp->get_data();
1084         Elf_X_Data strdata = dynstr_scnp->get_data();
1085
1086         if( reldata.isValid() && symdata.isValid() && strdata.isValid() ) {
1087             Offset next_plt_entry_addr = plt_addr_;
1088         if(getArch() == Dyninst::Arch_x86 || getArch() == Dyninst::Arch_x86_64)
1089         {
1090             next_plt_entry_addr += plt_entry_size_;  // 1st PLT entry is special
1091         }
1092         else if(getArch()==Dyninst::Arch_ppc32)
1093         {
1094             bool extraStubs = false;
1095
1096             // Sanity check.
1097             if (!plt_entry_size_) {
1098                 create_printf("%s[%d]:  FIXME:  plt_entry_size not established\n", FILE__, __LINE__);
1099                 plt_entry_size_ = 8;
1100             }
1101
1102             if (plt_entry_size_ == 8) {
1103                 // Old style executable PLT section
1104                 next_plt_entry_addr += 9*plt_entry_size_;  // 1st 9 PLT entries are special
1105
1106             } else if (plt_entry_size_ == 16) {
1107                 // New style secure PLT
1108                 Region *plt = NULL, *dynamic = NULL,
1109                         *got = NULL, *glink = NULL;
1110                 // Region *relplt = NULL;
1111                 unsigned int glink_addr = 0;
1112                 unsigned int stub_addr = 0;
1113
1114                 // Find the GLINK section.  See ppc_elf_get_synthetic_symtab() in
1115                 // bfd/elf32-ppc.c of GNU's binutils for more information.
1116
1117                 for (unsigned iter = 0; iter < regions_.size(); ++iter) {
1118                     std::string name = regions_[iter]->getRegionName();
1119                     if (name == PLT_NAME) plt = regions_[iter];
1120                     // else if (name == REL_PLT_NAME) relplt = regions_[iter];
1121                     else if (name == DYNAMIC_NAME) dynamic = regions_[iter];
1122                     else if (name == GOT_NAME) got = regions_[iter];
1123                 }
1124
1125                 // Rely on .dynamic section for prelinked binaries.
1126                 if (dynamic != NULL) {
1127                     Elf32_Dyn *dyn = (Elf32_Dyn *)dynamic->getPtrToRawData();
1128                     unsigned int count = dynamic->getMemSize() / sizeof(Elf32_Dyn);
1129
1130                     for (unsigned int i = 0; i < count; ++i) {
1131                         // Use DT_LOPROC instead of DT_PPC_GOT to circumvent problems
1132                         // caused by early versions of libelf where DT_PPC_GOT has
1133                         // yet to be defined.
1134                         if (dyn[i].d_tag == DT_LOPROC) {
1135                             unsigned int g_o_t = dyn[i].d_un.d_val;
1136                             if (got != NULL) {
1137                                 unsigned char *data =
1138                                         (unsigned char *)got->getPtrToRawData();
1139                                 glink_addr = *(unsigned int *)
1140                                         (data + (g_o_t - got->getMemOffset() + 4));
1141                                 break;
1142                             }
1143                         }
1144                     }
1145                 }
1146
1147                 // Otherwise, first entry in .plt section holds the glink address
1148                 if (glink_addr == 0) {
1149                     unsigned char *data = (unsigned char *)plt->getPtrToRawData();
1150                     glink_addr = *(unsigned int *)(data);
1151                 }
1152
1153                 // Search for region that contains glink address
1154                 for (unsigned iter = 0; iter < regions_.size(); ++iter) {
1155                     unsigned int start = regions_[iter]->getMemOffset();
1156                     unsigned int end = start + regions_[iter]->getMemSize();
1157                     if (start <= glink_addr && glink_addr < end) {
1158                         glink = regions_[iter];
1159                         break;
1160                     }
1161                 }
1162
1163                 if (!glink) {
1164                     return false;
1165                 }
1166
1167                 // Find PLT function stubs.  They preceed the glink section.
1168                 stub_addr = glink_addr - (rel_plt_size_/rel_plt_entry_size_) * 16;
1169
1170                 const unsigned int LWZ_11_30   = 0x817e0000;
1171                 const unsigned int ADDIS_11_30 = 0x3d7e0000;
1172                 const unsigned int LWZ_11_11   = 0x816b0000;
1173                 const unsigned int MTCTR_11    = 0x7d6903a6;
1174                 const unsigned int BCTR        = 0x4e800420;
1175
1176                 unsigned char *sec_data = (unsigned char *)glink->getPtrToRawData();
1177                 unsigned int *insn = (unsigned int *)
1178                         (sec_data + (stub_addr - glink->getMemOffset()));
1179
1180                 // Keep moving pointer back if more -fPIC stubs are found.
1181                 while (sec_data < (unsigned char *)insn) {
1182                     unsigned int *back = insn - 4;
1183
1184                     if ((  (back[0] & 0xffff0000) == LWZ_11_30
1185                            && back[1] == MTCTR_11
1186                            && back[2] == BCTR)
1187
1188                         || (   (back[0] & 0xffff0000) == ADDIS_11_30
1189                                && (back[1] & 0xffff0000) == LWZ_11_11
1190                                &&  back[2] == MTCTR_11
1191                                &&  back[3] == BCTR))
1192                     {
1193                         extraStubs = true;
1194                         stub_addr -= 16;
1195                         insn = back;
1196                     } else {
1197                         break;
1198                     }
1199                 }
1200
1201                 // Okay, this is where things get hairy.  If we have a one to one
1202                 // relationship between the glink stubs and plt entries (meaning
1203                 // extraStubs == false), then we can generate our relocationEntry
1204                 // objects normally below.
1205
1206                 // However, if we have extra glink stubs, then we must generate
1207                 // relocations with unknown destinations for *all* stubs.  Then,
1208                 // we use the loop below to store additional information about
1209                 // the data plt entry keyed by plt entry address.
1210
1211                 // Finally, if a symbol with any of the following forms:
1212                 //     [hex_addr].got2.plt_pic32.[sym_name]
1213                 //     [hex_addr].plt_pic32.[sym_name]
1214                 //
1215                 // matches the glink stub address, then stub symbols exist and we
1216                 // can rely on these tell us where the stub will eventually go.
1217
1218                 if (extraStubs == true) {
1219                     std::string name;
1220                     relocationEntry re;
1221
1222                     while (stub_addr < glink_addr) {
1223                         if (symsByOffset_.find(stub_addr) != symsByOffset_.end()) {
1224                             name = (symsByOffset_[stub_addr])[0]->getMangledName();
1225                             name = name.substr( name.rfind("plt_pic32.") + 10 );
1226                         }
1227
1228                         if (!name.empty()) {
1229                             re = relocationEntry( stub_addr, 0, name, NULL, 0 );
1230                         } else {
1231                             re = relocationEntry( stub_addr, 0, "@plt", NULL, 0 );
1232                         }
1233                         fbt_.push_back(re);
1234                         stub_addr += 16;
1235                     }
1236
1237                     // Now prepare to iterate over plt below.
1238                     next_plt_entry_addr = plt_addr_;
1239                     plt_entry_size_ = 4;
1240
1241                 } else {
1242                     next_plt_entry_addr = stub_addr;
1243                 }
1244
1245             } else {
1246                 create_printf("ERROR: Can't handle %d PLT entry size\n",
1247                               plt_entry_size_);
1248                 return false;
1249             }
1250
1251             //  actually this is just fudged to make the offset value 72, which is what binutils uses
1252             //  Note that binutils makes the distinction between PLT_SLOT_SIZE (8),
1253             //  and PLT_ENTRY_SIZE (12).  PLT_SLOT_SIZE seems to be what we want, even though we also
1254             //  have PLT_INITIAL_ENTRY_SIZE (72)
1255             //  see binutils/bfd/elf32-ppc.c/h if more info is needed
1256             //next_plt_entry_addr += 72;  // 1st 6 PLT entries art special
1257
1258
1259         } else if(getArch() == Dyninst::Arch_ppc64)
1260         {
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 if (getArch() == Dyninst::Arch_aarch64)
1372         {
1373             next_plt_entry_addr += 2 * plt_entry_size_;
1374         } else {
1375             next_plt_entry_addr += 4*(plt_entry_size_); //1st 4 entries are special
1376         }
1377
1378
1379         Elf_X_Sym sym = symdata.get_sym();
1380         Elf_X_Rel rel = reldata.get_rel();
1381         Elf_X_Rela rela = reldata.get_rela();
1382         const char *strs = strdata.get_string();
1383
1384         if (sym.isValid() && (rel.isValid() || rela.isValid()) && strs) {
1385
1386             // Sometimes, PPC32 Linux may use this loop to update fbt entries.
1387             // Should stay -1 for all other platforms.  See notes above.
1388             int fbt_iter = -1;
1389             if (fbt_.size() > 0 && !fbt_[0].rel_addr() && fbt_[0].name() != "@plt")
1390                 fbt_iter = 0;
1391
1392             for( u_int i = 0; i < (rel_plt_size_/rel_plt_entry_size_); ++i ) {
1393                 long offset;
1394                 long addend;
1395                 long index;
1396                 unsigned long type;
1397                 Region::RegionType rtype;
1398
1399                 switch (reldata.d_type()) {
1400                     case ELF_T_REL:
1401                         offset = rel.r_offset(i);
1402                         addend = 0;
1403                         index = rel.R_SYM(i);
1404                         type = rel.R_TYPE(i);
1405                         rtype = Region::RT_REL;
1406                         break;
1407
1408                     case ELF_T_RELA:
1409                         offset = rela.r_offset(i);
1410                         addend = rela.r_addend(i);
1411                         index = rela.R_SYM(i);
1412                         type = rela.R_TYPE(i);
1413                         rtype = Region::RT_RELA;
1414                         break;
1415
1416                     default:
1417                         // We should never reach this case.
1418                         return false;
1419                 };
1420
1421                 std::string targ_name = &strs[ sym.st_name(index) ];
1422                 vector<Symbol *> dynsym_list;
1423                 if (symbols_.find(targ_name) != symbols_.end())
1424                 {
1425                     vector<Symbol *> &syms = symbols_[&strs[ sym.st_name(index)]];
1426                     for (vector<Symbol *>::iterator i = syms.begin(); i != syms.end(); i++) {
1427                         if (!(*i)->isInDynSymtab())
1428                             continue;
1429                         dynsym_list.push_back(*i);
1430                     }
1431                 }
1432                 else {
1433                     dynsym_list.clear();
1434                 }
1435
1436 #if defined(os_vxworks)
1437                     // VxWorks Kernel Images don't use PLT's, but we'll use the fbt to
1438           // note all function call relocations, and we'll fix these up later
1439           // in Symtab::fixup_RegionAddr()
1440           next_plt_entry_addr = sym.st_value(index);
1441 #endif
1442
1443                     if (fbt_iter == -1) { // Create new relocation entry.
1444                         relocationEntry re( next_plt_entry_addr, offset, targ_name,
1445                                             NULL, type );
1446                         re.setAddend(addend);
1447                         re.setRegionType(rtype);
1448                         if (dynsym_list.size() > 0)
1449                             re.addDynSym(dynsym_list[0]);
1450                         fbt_.push_back(re);
1451
1452                     } else { // Update existing relocation entry.
1453                         while ((unsigned)fbt_iter < fbt_.size() &&
1454                                fbt_[fbt_iter].name() == targ_name) {
1455
1456                             fbt_[fbt_iter].setRelAddr(offset);
1457                             fbt_[fbt_iter].setAddend(addend);
1458                             fbt_[fbt_iter].setRegionType(rtype);
1459                             if (dynsym_list.size() > 0)
1460                                 fbt_[fbt_iter].addDynSym(dynsym_list[0]);
1461
1462                             ++fbt_iter;
1463                         }
1464                     }
1465
1466 #if defined(os_vxworks)
1467                     // Nothing to increment here.
1468 #else
1469                     next_plt_entry_addr += plt_entry_size_;
1470 #endif
1471                 }
1472                 return true;
1473             }
1474         }
1475     }
1476     return false;
1477 }
1478
1479 void Object::load_object(bool alloc_syms)
1480 {
1481     Elf_X_Shdr *bssscnp = 0;
1482     Elf_X_Shdr *symscnp = 0;
1483     Elf_X_Shdr *strscnp = 0;
1484     Elf_X_Shdr *stabscnp = 0;
1485     Elf_X_Shdr *stabstrscnp = 0;
1486     Elf_X_Shdr *stabs_indxcnp = 0;
1487     Elf_X_Shdr *stabstrs_indxcnp = 0;
1488     Offset txtaddr = 0;
1489     Offset dataddr = 0;
1490     Elf_X_Shdr *rel_plt_scnp = 0;
1491     Elf_X_Shdr *plt_scnp = 0;
1492     Elf_X_Shdr *got_scnp = 0;
1493     Elf_X_Shdr *dynsym_scnp = 0;
1494     Elf_X_Shdr *dynstr_scnp = 0;
1495     Elf_X_Shdr *dynamic_scnp = 0;
1496     Elf_X_Shdr *eh_frame_scnp = 0;
1497     Elf_X_Shdr *gcc_except = 0;
1498     Elf_X_Shdr *interp_scnp = 0;
1499     Elf_X_Shdr *opd_scnp = NULL;
1500
1501     { // binding contour (for "goto cleanup")
1502
1503         // initialize object (for failure detection)
1504         code_ptr_ = 0;
1505         code_off_ = 0;
1506         code_len_ = 0;
1507         data_ptr_ = 0;
1508         data_off_ = 0;
1509         data_len_ = 0;
1510
1511         // initialize "valid" regions of code and data segments
1512         code_vldS_ = (Offset) -1;
1513         code_vldE_ = 0;
1514         data_vldS_ = (Offset) -1;
1515         data_vldE_ = 0;
1516
1517         // And attempt to parse the ELF data structures in the file....
1518         // EEL, added one more parameter
1519
1520         if (!loaded_elf(txtaddr, dataddr, bssscnp, symscnp, strscnp,
1521                         stabscnp, stabstrscnp, stabs_indxcnp, stabstrs_indxcnp,
1522                         rel_plt_scnp, plt_scnp, got_scnp, dynsym_scnp, dynstr_scnp,
1523                         dynamic_scnp, eh_frame_scnp,gcc_except, interp_scnp,
1524                         opd_scnp, true))
1525         {
1526             goto cleanup;
1527         }
1528
1529         addressWidth_nbytes = elfHdr->wordSize();
1530
1531         // find code and data segments....
1532         find_code_and_data(*elfHdr, txtaddr, dataddr);
1533
1534         if (elfHdr->e_type() != ET_REL)
1535         {
1536             if (!code_ptr_ || !code_len_)
1537             {
1538                 //bpfatal( "no text segment\n");
1539                 goto cleanup;
1540             }
1541         }
1542         get_valid_memory_areas(*elfHdr);
1543
1544 #if (defined(os_linux) || defined(os_freebsd))
1545         if(getArch() == Dyninst::Arch_x86 || getArch() == Dyninst::Arch_x86_64)
1546         {
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         }
1553 #endif
1554         if (interp_scnp) {
1555             interpreter_name_ = (char *) interp_scnp->get_data().d_buf();
1556         }
1557
1558         // global symbols are put in global_symbols. Later we read the
1559         // stab section to find the module to where they belong.
1560         // Experiment : lets try to be a bit more intelligent about
1561         // how we initially size the global_symbols table.
1562         // dictionary_lite takes an initial # of bins (2nd param),
1563         // a max bin load (3rd param), and a grow factor (4th param).
1564         // Leaving aside the grow factor, lets allocate an initial #
1565         // of bins = nsyms / max bin load.
1566
1567 #if defined(TIMED_PARSE)
1568         struct timeval starttime;
1569     gettimeofday(&starttime, NULL);
1570 #endif
1571         if (alloc_syms)
1572         {
1573             // find symbol and string data
1574 #if defined(os_vxworks)
1575             // Avoid assigning symbols to DEFAULT_MODULE on VxWorks
1576       string module = mf->pathname();
1577 #else
1578             string module = "DEFAULT_MODULE";
1579 #endif
1580             string name   = "DEFAULT_NAME";
1581             Elf_X_Data symdata, strdata;
1582
1583             if (symscnp && strscnp)
1584             {
1585                 symdata = symscnp->get_data();
1586                 strdata = strscnp->get_data();
1587                 parse_symbols(symdata, strdata, bssscnp, symscnp, false, module);
1588             }
1589
1590             no_of_symbols_ = nsymbols();
1591
1592             // try to resolve the module names of global symbols
1593             // Sun compiler stab.index section
1594             fix_global_symbol_modules_static_stab(stabs_indxcnp, stabstrs_indxcnp);
1595
1596             // STABS format (.stab section)
1597             fix_global_symbol_modules_static_stab(stabscnp, stabstrscnp);
1598
1599             // DWARF format (.debug_info section)
1600             fix_global_symbol_modules_static_dwarf();
1601
1602             if (dynamic_addr_ && dynsym_scnp && dynstr_scnp)
1603             {
1604                 symdata = dynsym_scnp->get_data();
1605                 strdata = dynstr_scnp->get_data();
1606                 parse_dynamicSymbols(dynamic_scnp, symdata, strdata, false, module);
1607             }
1608
1609             //TODO
1610             //Have a hash on the symbol table. Iterate over dynamic symbol table to check if it exists
1611             //If yes set dynamic for the symbol ( How to distinguish between symbols only in symtab,
1612             //         symbols only in dynsymtab & symbols present in both).
1613             // Else add dynamic symbol to dictionary
1614             // (or) Have two sepearate dictionaries. Makes life easy!
1615             // Think about it today!!
1616
1617             //allsymbols = merge(allsymbols, alldynSymbols);
1618
1619 #if defined(TIMED_PARSE)
1620             struct timeval endtime;
1621       gettimeofday(&endtime, NULL);
1622       unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
1623       unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
1624       unsigned long difftime = lendtime - lstarttime;
1625       double dursecs = difftime/(1000);
1626       cout << "parsing/fixing/overriding elf took "<<dursecs <<" msecs" << endl;
1627 #endif
1628
1629             if (dynamic_addr_ && dynsym_scnp && dynstr_scnp)
1630             {
1631                 parseDynamic(dynamic_scnp, dynsym_scnp, dynstr_scnp);
1632             }
1633
1634 #if defined(os_vxworks)
1635             // Load relocations like they are PLT entries.
1636       // Use the non-dynamic symbol tables.
1637       if (rel_plt_scnp && symscnp && strscnp) {
1638         if (!get_relocation_entries(rel_plt_scnp, symscnp, strscnp))
1639           goto cleanup;
1640       }
1641 #endif
1642
1643             // populate "fbt_"
1644             if (rel_plt_scnp && dynsym_scnp && dynstr_scnp)
1645             {
1646                 if (!get_relocation_entries(rel_plt_scnp,dynsym_scnp,dynstr_scnp))
1647                 {
1648                     goto cleanup;
1649                 }
1650             }
1651             parse_all_relocations(*elfHdr, dynsym_scnp, dynstr_scnp,
1652                                   symscnp, strscnp);
1653
1654             handle_opd_relocations();
1655         }
1656
1657         //Set object type
1658         int e_type = elfHdr->e_type();
1659
1660         if (e_type == ET_DYN) {
1661             obj_type_ = obj_SharedLib;
1662         }else if (e_type == ET_EXEC) {
1663             obj_type_ = obj_Executable;
1664         }else if (e_type == ET_REL) {
1665             obj_type_ = obj_RelocatableFile;
1666         }
1667
1668         // Set rel type based on the ELF machine type
1669         relType_ = getRelTypeByElfMachine(elfHdr);
1670
1671         if (opd_scnp) {
1672             parse_opd(opd_scnp);
1673         }
1674
1675         return;
1676     } // end binding contour (for "goto cleanup2")
1677
1678     cleanup:
1679     {
1680         /* NOTE: The file should NOT be munmap()ed.  The mapped file is
1681        used for function parsing (see dyninstAPI/src/symtab.C) */
1682
1683         create_printf("%s[%d]:  failed to load elf object\n", FILE__, __LINE__);
1684     }
1685 }
1686
1687 void Object::load_shared_object(bool alloc_syms)
1688 {
1689     Elf_X_Shdr *bssscnp = 0;
1690     Elf_X_Shdr *symscnp = 0;
1691     Elf_X_Shdr *strscnp = 0;
1692     Elf_X_Shdr *stabscnp = 0;
1693     Elf_X_Shdr *stabstrscnp = 0;
1694     Elf_X_Shdr *stabs_indxcnp = 0;
1695     Elf_X_Shdr *stabstrs_indxcnp = 0;
1696     Offset txtaddr = 0;
1697     Offset dataddr = 0;
1698     Elf_X_Shdr *rel_plt_scnp = 0;
1699     Elf_X_Shdr *plt_scnp = 0;
1700     Elf_X_Shdr *got_scnp = 0;
1701     Elf_X_Shdr *dynsym_scnp = 0;
1702     Elf_X_Shdr *dynstr_scnp = 0;
1703     Elf_X_Shdr *dynamic_scnp = 0;
1704     Elf_X_Shdr *eh_frame_scnp = 0;
1705     Elf_X_Shdr *gcc_except = 0;
1706     Elf_X_Shdr *interp_scnp = 0;
1707     Elf_X_Shdr *opd_scnp = NULL;
1708
1709     { // binding contour (for "goto cleanup2")
1710
1711         // initialize "valid" regions of code and data segments
1712         code_vldS_ = (Offset) -1;
1713         code_vldE_ = 0;
1714         data_vldS_ = (Offset) -1;
1715         data_vldE_ = 0;
1716
1717         if (!loaded_elf(txtaddr, dataddr, bssscnp, symscnp, strscnp,
1718                         stabscnp, stabstrscnp, stabs_indxcnp, stabstrs_indxcnp,
1719                         rel_plt_scnp, plt_scnp, got_scnp, dynsym_scnp, dynstr_scnp,
1720                         dynamic_scnp, eh_frame_scnp, gcc_except, interp_scnp, opd_scnp))
1721             goto cleanup2;
1722
1723         if (interp_scnp)
1724             interpreter_name_ = (char *) interp_scnp->get_data().d_buf();
1725
1726         addressWidth_nbytes = elfHdr->wordSize();
1727
1728         // find code and data segments....
1729         find_code_and_data(*elfHdr, txtaddr, dataddr);
1730
1731         get_valid_memory_areas(*elfHdr);
1732
1733 #if (defined(os_linux) || defined(os_freebsd))
1734         if(getArch() == Dyninst::Arch_x86 || getArch() == Dyninst::Arch_x86_64) {
1735             if (eh_frame_scnp != 0 && gcc_except != 0) {
1736                 find_catch_blocks(eh_frame_scnp, gcc_except,
1737                                   txtaddr, dataddr, catch_addrs_);
1738             }
1739         }
1740 #endif
1741
1742 #if defined(TIMED_PARSE)
1743         struct timeval starttime;
1744     gettimeofday(&starttime, NULL);
1745 #endif
1746
1747         if (alloc_syms) {
1748             // build symbol dictionary
1749             string module = mf->pathname();
1750             string name   = "DEFAULT_NAME";
1751
1752             Elf_X_Data symdata, strdata;
1753             if (symscnp && strscnp)
1754             {
1755                 symdata = symscnp->get_data();
1756                 strdata = strscnp->get_data();
1757                 if (!symdata.isValid() || !strdata.isValid()) {
1758                     log_elferror(err_func_, "locating symbol/string data");
1759                     goto cleanup2;
1760                 }
1761                 bool result = parse_symbols(symdata, strdata, bssscnp, symscnp, false, module);
1762                 if (!result) {
1763                     log_elferror(err_func_, "locating symbol/string data");
1764                     goto cleanup2;
1765                 }
1766             }
1767
1768             no_of_symbols_ = nsymbols();
1769             // try to resolve the module names of global symbols
1770             // Sun compiler stab.index section
1771             fix_global_symbol_modules_static_stab(stabs_indxcnp, stabstrs_indxcnp);
1772
1773             // STABS format (.stab section)
1774             fix_global_symbol_modules_static_stab(stabscnp, stabstrscnp);
1775
1776             // DWARF format (.debug_info section)
1777             fix_global_symbol_modules_static_dwarf();
1778
1779             if (dynamic_addr_ && dynsym_scnp && dynstr_scnp)
1780             {
1781                 symdata = dynsym_scnp->get_data();
1782                 strdata = dynstr_scnp->get_data();
1783                 parse_dynamicSymbols(dynamic_scnp, symdata, strdata, false, module);
1784             }
1785
1786 #if defined(TIMED_PARSE)
1787             struct timeval endtime;
1788       gettimeofday(&endtime, NULL);
1789       unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
1790       unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
1791       unsigned long difftime = lendtime - lstarttime;
1792       double dursecs = difftime/(1000 * 1000);
1793       cout << "*INSERT SYMBOLS* elf took "<<dursecs <<" msecs" << endl;
1794       //cout << "parsing/fixing/overriding/insertion elf took "<<dursecs <<" msecs" << endl;
1795 #endif
1796             if(dynamic_addr_ && dynsym_scnp && dynstr_scnp) {
1797                 parseDynamic(dynamic_scnp, dynsym_scnp, dynstr_scnp);
1798             }
1799
1800 #if defined(os_vxworks)
1801             // Load relocations like they are PLT entries.
1802       // Use the non-dynamic symbol tables.
1803       if (rel_plt_scnp && symscnp && strscnp) {
1804         if (!get_relocation_entries(rel_plt_scnp, symscnp, strscnp))
1805           goto cleanup2;
1806       }
1807 #endif
1808
1809             if (rel_plt_scnp && dynsym_scnp && dynstr_scnp) {
1810                 if (!get_relocation_entries(rel_plt_scnp,dynsym_scnp,dynstr_scnp)) {
1811                     goto cleanup2;
1812                 }
1813             }
1814
1815             parse_all_relocations(*elfHdr, dynsym_scnp, dynstr_scnp,
1816                                   symscnp, strscnp);
1817             // Apply relocations to opd
1818             handle_opd_relocations();
1819         }
1820
1821         //Set object type
1822         int e_type = elfHdr->e_type();
1823         if (e_type == ET_DYN) {
1824             obj_type_ = obj_SharedLib;
1825         }
1826         else if (e_type == ET_EXEC) {
1827             obj_type_ = obj_Executable;
1828         }else if( e_type == ET_REL ) {
1829             obj_type_ = obj_RelocatableFile;
1830         }
1831
1832
1833         if (opd_scnp) {
1834             parse_opd(opd_scnp);
1835         }
1836
1837         // Set rel type based on the ELF machine type
1838         relType_ = getRelTypeByElfMachine(elfHdr);
1839
1840     } // end binding contour (for "goto cleanup2")
1841
1842     cleanup2:
1843     {
1844     }
1845 }
1846
1847 static Symbol::SymbolType pdelf_type(int elf_type)
1848 {
1849     switch (elf_type) {
1850         case STT_FILE:   return Symbol::ST_MODULE;
1851         case STT_SECTION:return Symbol::ST_SECTION;
1852         case STT_OBJECT: return Symbol::ST_OBJECT;
1853         case STT_TLS:    return Symbol::ST_TLS;
1854         case STT_FUNC:   return Symbol::ST_FUNCTION;
1855         case STT_NOTYPE: return Symbol::ST_NOTYPE;
1856 #if defined(STT_GNU_IFUNC)
1857         case STT_GNU_IFUNC: return Symbol::ST_INDIRECT;
1858 #endif
1859         default: return Symbol::ST_UNKNOWN;
1860     }
1861 }
1862
1863 static Symbol::SymbolLinkage pdelf_linkage(int elf_binding)
1864 {
1865     switch (elf_binding) {
1866         case STB_LOCAL:  return Symbol::SL_LOCAL;
1867         case STB_WEAK:   return Symbol::SL_WEAK;
1868         case STB_GLOBAL: return Symbol::SL_GLOBAL;
1869 #if defined(STB_GNU_UNIQUE)        
1870         case STB_GNU_UNIQUE: return Symbol::SL_UNIQUE;
1871 #endif
1872     }
1873     return Symbol::SL_UNKNOWN;
1874 }
1875
1876 static Symbol::SymbolVisibility pdelf_visibility(int elf_visibility)
1877 {
1878     switch (elf_visibility) {
1879         case STV_DEFAULT:    return Symbol::SV_DEFAULT;
1880         case STV_INTERNAL:   return Symbol::SV_INTERNAL;
1881         case STV_HIDDEN:     return Symbol::SV_HIDDEN;
1882         case STV_PROTECTED:  return Symbol::SV_PROTECTED;
1883     }
1884     return Symbol::SV_UNKNOWN;
1885 }
1886
1887 //============================================================================
1888
1889 //#include "dyninstAPI/src/arch.h"
1890 //#include "dyninstAPI/src/inst.h"
1891 //#include "dyninstAPI/src/instPoint.h" // includes instPoint-x86.h
1892 //#include "dyninstAPI/src/instP.h" // class returnInstance
1893 //#include "dyninstAPI/src/rpcMgr.h"
1894
1895 //linear search
1896 bool lookUpSymbol( std::vector< Symbol *>& allsymbols, Offset& addr )
1897 {
1898     for( unsigned i = 0; i < allsymbols.size(); i++ )
1899     {
1900         if( allsymbols[ i ]->getOffset() == addr )
1901         {
1902             return true;
1903         }
1904     }
1905     return false;
1906 }
1907
1908 bool lookUpAddress( std::vector< Offset >& jumpTargets, Offset& addr )
1909 {
1910     for( unsigned i = 0; i < jumpTargets.size(); i++ )
1911     {
1912         if( jumpTargets[ i ] == addr )
1913         {
1914             return true;
1915         }
1916     }
1917     return false;
1918 }
1919
1920 //utitility function to print std::vector of symbols
1921 void printSyms( std::vector< Symbol *>& allsymbols )
1922 {
1923     for( unsigned i = 0; i < allsymbols.size(); i++ )
1924     {
1925         if( allsymbols[ i ]->getType() != Symbol::ST_FUNCTION )
1926         {
1927             continue;
1928         }
1929         cout << allsymbols[ i ] << endl;
1930     }
1931 }
1932
1933 // Official Procedure Descriptor handler
1934 //
1935 // Some platforms (PPC64 Linux libc v2.1) only produce function
1936 // symbols which point into the .opd section.  Find the actual
1937 // function address in .text, and fix the symbol.
1938 //
1939 // Additionally, large binaries may contain multiple TOC values.
1940 // Use the .opd section to determine the correct per-function TOC.
1941 // See binutils' bfd/elf64-ppc.c for all the gory details.
1942 //
1943 // Symbol altering routines should be minimized to prevent problems
1944 // in the rewrite case.  Instead, return a new symbol the encapsulates
1945 // the correct information.
1946
1947 // In statically linked binaries, there are relocations against
1948 // .opd section. We need to apply the relocations before using
1949 // opd symbols.
1950
1951 void Object::parse_opd(Elf_X_Shdr *opd_hdr) {
1952     // If the OPD is filled in, parse it and fill in our TOC table
1953     assert(opd_hdr);
1954
1955     Elf_X_Data data = opd_hdr->get_data();
1956     assert(data.isValid());
1957
1958     // Let's read this puppy
1959     unsigned long *buf = (unsigned long *)data.d_buf();
1960     // In some cases, the OPD is a set of 3-tuples: <func offset, TOC, environment ptr>.
1961     // In others, it's a set of 2-tuples. Since we can't tell the difference, we
1962     // instead look for function offsets.
1963     // Heck, it can even change within the opd!
1964
1965     // In almost all cases, the TOC is the same. So let's store it at the
1966     // special location 0 and only record differences.
1967     Offset baseTOC = buf[1];
1968     TOC_table_[0] = baseTOC;
1969
1970     // Note the lack of 32/64 here: okay because the only platform with an OPD
1971     // is 64-bit elf.
1972     unsigned i = 0;
1973     while (i < (data.d_size() / sizeof(unsigned long))) {
1974         Offset func = buf[i];
1975         Offset toc = buf[i+1];
1976
1977         if (func == 0 && i != 0) break;
1978
1979         if (symsByOffset_.find(func) == symsByOffset_.end()) {
1980             i++;
1981             continue;
1982         }
1983
1984         if (toc != baseTOC) {
1985             TOC_table_[func] = toc;
1986         }
1987         i += 2;
1988     }
1989 }
1990
1991 void Object::handle_opd_relocations(){
1992
1993     unsigned int i = 0, opdregion = 0;
1994     while (i < regions_.size()) {
1995         if(regions_[i]->getRegionName().compare(".opd") == 0){
1996             opdregion = i;
1997             break;
1998         }
1999         i++;
2000     }
2001
2002     vector<relocationEntry> region_rels = (regions_[opdregion])->getRelocations();
2003     vector<relocationEntry>::iterator rel_it;
2004     vector<Symbol *>::iterator sym_it;
2005     for(sym_it = opdsymbols_.begin(); sym_it != opdsymbols_.end(); ++sym_it) {
2006         for(rel_it = region_rels.begin(); rel_it != region_rels.end(); ++rel_it) {
2007             if((*sym_it)->getPtrOffset() == (*rel_it).rel_addr()) {
2008                 i = 0;
2009                 while (i < regions_.size()) {
2010                     if(regions_[i]->getRegionName().compare((*rel_it).getDynSym()->getMangledName()) == 0){
2011                         Region *targetRegion = regions_[i];
2012                         Offset regionOffset = targetRegion->getDiskOffset()+(*rel_it).addend();
2013                         (*sym_it)->setRegion(targetRegion);
2014                         (*sym_it)->setOffset(regionOffset);   // Store code address for the function.
2015                         break;
2016                     }
2017                     ++i;
2018                 }
2019             }
2020         }
2021     }
2022     opdsymbols_.clear();
2023 }
2024
2025 Symbol *Object::handle_opd_symbol(Region *opd, Symbol *sym)
2026 {
2027     if (!sym) return NULL;
2028
2029     Offset soffset = sym->getOffset();
2030     assert(opd->isOffsetInRegion(soffset));  // Symbol must be in .opd section.
2031
2032     Offset* opd_entry = (Offset*)opd->getPtrToRawData();
2033     opd_entry += (soffset - opd->getDiskOffset()) / sizeof(Offset); // table of offsets;
2034     Symbol *retval = new Symbol(*sym); // Copy the .opd symbol.
2035     retval->setOffset(opd_entry[0]);   // Store code address for the function.
2036     retval->setLocalTOC(opd_entry[1]); // Store TOC address for this function.
2037     retval->setPtrOffset(soffset);     // Original address is the ptr address.
2038
2039     // Find the appropriate region for the new symbol.
2040     unsigned int i = 0;
2041     while (i < regions_.size()) {
2042         if (regions_[i]->isOffsetInRegion(opd_entry[0])) {
2043             retval->setRegion(regions_[i]);
2044             break;
2045         }
2046         ++i;
2047     }
2048     assert(i < regions_.size());
2049     retval->setSymbolType(Symbol::ST_FUNCTION);
2050 #if 0
2051     retval->tag_ = Symbol::TAG_INTERNAL;  // Not sure if this is an appropriate
2052                                         // use of the tag field, but we need
2053                                         // to mark this symbol somehow as a
2054                                         // fake.
2055 #endif
2056     return retval;
2057 }
2058
2059 // parse_symbols(): populate "allsymbols"
2060 bool Object::parse_symbols(Elf_X_Data &symdata, Elf_X_Data &strdata,
2061                            Elf_X_Shdr* bssscnp,
2062                            Elf_X_Shdr* symscnp,
2063                            bool /*shared*/, string smodule)
2064 {
2065 #if defined(TIMED_PARSE)
2066     struct timeval starttime;
2067   gettimeofday(&starttime, NULL);
2068 #endif
2069
2070     if (!symdata.isValid() || !strdata.isValid()) {
2071         return false;
2072     }
2073
2074     Elf_X_Sym syms = symdata.get_sym();
2075     const char *strs = strdata.get_string();
2076     if(syms.isValid()){
2077         for (unsigned i = 0; i < syms.count(); i++) {
2078             //If it is not a dynamic executable then we need undefined symbols
2079             //in symtab section so that we can resolve symbol references. So
2080             //we parse & store undefined symbols only if there is no dynamic
2081             //symbol table
2082             //1/09: not so anymore--we want to preserve all symbols,
2083             //regardless of file type
2084
2085             int etype = syms.ST_TYPE(i);
2086             int ebinding = syms.ST_BIND(i);
2087             int evisibility = syms.ST_VISIBILITY(i);
2088
2089             // resolve symbol elements
2090             string sname = &strs[ syms.st_name(i) ];
2091             Symbol::SymbolType stype = pdelf_type(etype);
2092             Symbol::SymbolLinkage slinkage = pdelf_linkage(ebinding);
2093             Symbol::SymbolVisibility svisibility = pdelf_visibility(evisibility);
2094             unsigned ssize = syms.st_size(i);
2095             unsigned secNumber = syms.st_shndx(i);
2096
2097             Offset soffset;
2098             if (symscnp->isFromDebugFile()) {
2099                 Offset soffset_dbg = syms.st_value(i);
2100                 soffset = soffset_dbg;
2101                 if (soffset_dbg) {
2102                     bool result = convertDebugOffset(soffset_dbg, soffset);
2103                     if (!result) {
2104                         //Symbol does not match any section, can't convert
2105                         continue;
2106                     }
2107                 }
2108             }
2109             else {
2110                 soffset = syms.st_value(i);
2111             }
2112
2113             /* icc BUG: Variables in BSS are categorized as ST_NOTYPE instead of
2114          ST_OBJECT.  To fix this, we check if the symbol is in BSS and has
2115          size > 0. If so, we can almost always say it is a variable and hence,
2116          change the type from ST_NOTYPE to ST_OBJECT.
2117       */
2118             if (bssscnp) {
2119                 Offset bssStart = Offset(bssscnp->sh_addr());
2120                 Offset bssEnd = Offset (bssStart + bssscnp->sh_size()) ;
2121
2122                 if(( bssStart <= soffset) && ( soffset < bssEnd ) && (ssize > 0) &&
2123                    (stype == Symbol::ST_NOTYPE))
2124                 {
2125                     stype = Symbol::ST_OBJECT;
2126                 }
2127             }
2128
2129             // discard "dummy" symbol at beginning of file
2130             if (i==0 && sname == "" && soffset == (Offset)0)
2131                 continue;
2132
2133
2134             Region *sec;
2135             if(secNumber >= 1 && secNumber < regions_.size()) {
2136                 sec = regions_[secNumber];
2137             } else {
2138                 sec = NULL;
2139             }
2140             int ind = int (i);
2141             int strindex = syms.st_name(i);
2142
2143             if(stype == Symbol::ST_SECTION && sec != NULL) {
2144                 sname = sec->getRegionName();
2145                 soffset = sec->getDiskOffset();
2146             }
2147
2148             if (stype == Symbol::ST_MODULE) {
2149                 smodule = sname;
2150             }
2151             Symbol *newsym = new Symbol(sname,
2152                                         stype,
2153                                         slinkage,
2154                                         svisibility,
2155                                         soffset,
2156                                         NULL,
2157                                         sec,
2158                                         ssize,
2159                                         false,
2160                                         (secNumber == SHN_ABS),
2161                                         ind,
2162                                         strindex,
2163                                         (secNumber == SHN_COMMON));
2164
2165             if (stype == Symbol::ST_UNKNOWN)
2166                 newsym->setInternalType(etype);
2167
2168             if (sec && sec->getRegionName() == OPD_NAME && stype == Symbol::ST_FUNCTION ) {
2169                 newsym = handle_opd_symbol(sec, newsym);
2170
2171                 opdsymbols_.push_back(newsym);
2172                 symbols_[sname].push_back(newsym);
2173                 symsByOffset_[newsym->getOffset()].push_back(newsym);
2174                 symsToModules_[newsym] = smodule;
2175             } else {
2176                 symbols_[sname].push_back(newsym);
2177                 symsByOffset_[newsym->getOffset()].push_back(newsym);
2178                 symsToModules_[newsym] = smodule;
2179             }
2180
2181         }
2182     } // syms.isValid()
2183 #if defined(TIMED_PARSE)
2184     struct timeval endtime;
2185   gettimeofday(&endtime, NULL);
2186   unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
2187   unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
2188   unsigned long difftime = lendtime - lstarttime;
2189   double dursecs = difftime/(1000 * 1000);
2190   cout << "parsing elf took "<<dursecs <<" secs" << endl;
2191 #endif
2192     return true;
2193 }
2194
2195 // parse_symbols(): populate "allsymbols"
2196 // Lazy parsing of dynamic symbol  & string tables
2197 // Parsing the dynamic symbols lazily would certainly
2198 // not increase the overhead of the entire parse
2199 void Object::parse_dynamicSymbols (Elf_X_Shdr *&
2200 dyn_scnp
2201         , Elf_X_Data &symdata,
2202                                    Elf_X_Data &strdata,
2203                                    bool /*shared*/,
2204                                    std::string smodule)
2205 {
2206 #if defined(TIMED_PARSE)
2207     struct timeval starttime;
2208   gettimeofday(&starttime, NULL);
2209 #endif
2210
2211     Elf_X_Sym syms = symdata.get_sym();
2212     const char *strs = strdata.get_string();
2213     Elf_X_Shdr *versymSec = NULL, *verneedSec = NULL, *verdefSec = NULL;
2214     Elf_X_Data data = dyn_scnp->get_data();
2215     Elf_X_Dyn dyns = data.get_dyn();
2216     unsigned verneednum = 0, verdefnum = 0;
2217     Elf_X_Versym symVersions;
2218     Elf_X_Verdef *symVersionDefs = NULL;
2219     Elf_X_Verneed *symVersionNeeds = NULL;
2220     for (unsigned i = 0; i < dyns.count(); ++i) {
2221         switch(dyns.d_tag(i)) {
2222             case DT_NEEDED:
2223                 deps_.push_back(&strs[dyns.d_ptr(i)]);
2224                 break;
2225             case DT_VERSYM:
2226                 versymSec = getRegionHdrByAddr(dyns.d_ptr(i));
2227                 break;
2228             case DT_VERNEED:
2229                 verneedSec = getRegionHdrByAddr(dyns.d_ptr(i));
2230                 break;
2231             case DT_VERDEF:
2232                 verdefSec = getRegionHdrByAddr(dyns.d_ptr(i));
2233                 break;
2234             case DT_VERNEEDNUM:
2235                 verneednum = dyns.d_ptr(i);
2236                 break;
2237             case DT_VERDEFNUM:
2238                 verdefnum = dyns.d_ptr(i);
2239                 break;
2240             case DT_SONAME:
2241                 soname_ = &strs[dyns.d_ptr(i)];
2242             default:
2243                 break;
2244         }
2245     }
2246     if(versymSec)
2247         symVersions = versymSec->get_data().get_versyms();
2248     if(verdefSec)
2249         symVersionDefs = verdefSec->get_data().get_verDefSym();
2250     if(verneedSec)
2251         symVersionNeeds = verneedSec->get_data().get_verNeedSym();
2252
2253     for(unsigned i = 0; i < verdefnum ;i++) {
2254         Elf_X_Verdaux *aux = symVersionDefs->get_aux();
2255         for(unsigned j=0; j< symVersionDefs->vd_cnt(); j++){
2256             versionMapping[symVersionDefs->vd_ndx()].push_back(&strs[aux->vda_name()]);
2257             Elf_X_Verdaux *auxnext = aux->get_next();
2258             delete aux;
2259             aux = auxnext;
2260         }
2261         Elf_X_Verdef *symVersionDefsnext = symVersionDefs->get_next();
2262         delete symVersionDefs;
2263         symVersionDefs = symVersionDefsnext;
2264     }
2265
2266     for(unsigned i = 0; i < verneednum; i++){
2267         Elf_X_Vernaux *aux = symVersionNeeds->get_aux();
2268         for(unsigned j=0; j< symVersionNeeds->vn_cnt(); j++){
2269             versionMapping[aux->vna_other()].push_back(&strs[aux->vna_name()]);
2270             versionFileNameMapping[aux->vna_other()] = &strs[symVersionNeeds->vn_file()];
2271             Elf_X_Vernaux *auxnext = aux->get_next();
2272             delete aux;
2273             aux = auxnext;
2274         }
2275         Elf_X_Verneed *symVersionNeedsnext = symVersionNeeds->get_next();
2276         delete symVersionNeeds;
2277         symVersionNeeds = symVersionNeedsnext;
2278     }
2279
2280     if(syms.isValid()) {
2281         for (unsigned i = 0; i < syms.count(); i++) {
2282             int etype = syms.ST_TYPE(i);
2283             int ebinding = syms.ST_BIND(i);
2284             int evisibility = syms.ST_VISIBILITY(i);
2285
2286             // resolve symbol elements
2287             string sname = &strs[ syms.st_name(i) ];
2288             Symbol::SymbolType stype = pdelf_type(etype);
2289             Symbol::SymbolLinkage slinkage = pdelf_linkage(ebinding);
2290             Symbol::SymbolVisibility svisibility = pdelf_visibility(evisibility);
2291             unsigned ssize = syms.st_size(i);
2292             Offset soffset = syms.st_value(i);
2293             unsigned secNumber = syms.st_shndx(i);
2294
2295             // discard "dummy" symbol at beginning of file
2296             if (i==0 && sname == "" && soffset == 0)
2297                 continue;
2298
2299             Region *sec;
2300             if(secNumber >= 1 && secNumber < regions_.size()) {
2301                 sec = regions_[secNumber];
2302             } else {
2303                 sec = NULL;
2304             }
2305
2306             int ind = int (i);
2307             int strindex = syms.st_name(i);
2308
2309             if (stype == Symbol::ST_MODULE) {
2310                 smodule = sname;
2311             }
2312
2313             Symbol *newsym = new Symbol(sname,
2314                                         stype,
2315                                         slinkage,
2316                                         svisibility,
2317                                         soffset,
2318                                         NULL,
2319                                         sec,
2320                                         ssize,
2321                                         true,  // is dynamic
2322                                         (secNumber == SHN_ABS),
2323                                         ind,
2324                                         strindex,
2325                                         (secNumber == SHN_COMMON));
2326
2327             if (stype == Symbol::ST_UNKNOWN)
2328                 newsym->setInternalType(etype);
2329
2330             if(versymSec) {
2331                 unsigned short raw = symVersions.get(i);
2332                 bool hidden = raw >> 15;
2333                 int index = raw & 0x7fff;
2334                 if(versionFileNameMapping.find(index) != versionFileNameMapping.end()) {
2335                     //printf("version filename for %s: %s\n", sname.c_str(),
2336                     //versionFileNameMapping[index].c_str());
2337                     newsym->setVersionFileName(versionFileNameMapping[index]);
2338                 }
2339                 if(versionMapping.find(index) != versionMapping.end()) {
2340                     //printf("versions for %s: ", sname.c_str());
2341                     //for (unsigned k=0; k < versionMapping[index].size(); k++)
2342                     //printf(" %s", versionMapping[index][k].c_str());
2343                     newsym->setVersions(versionMapping[index]);
2344                     //printf("\n");
2345                 }
2346                 if (hidden) {
2347                     newsym->setVersionHidden();
2348                 }
2349             }
2350             // register symbol in dictionary
2351
2352             if (sec && sec->getRegionName() == OPD_NAME && stype == Symbol::ST_FUNCTION ) {
2353                 newsym = handle_opd_symbol(sec, newsym);
2354                 opdsymbols_.push_back(newsym);
2355
2356                 symbols_[sname].push_back(newsym);
2357                 symsByOffset_[newsym->getOffset()].push_back(newsym);
2358                 symsToModules_[newsym] = smodule;
2359             } else {
2360                 symbols_[sname].push_back(newsym);
2361                 symsByOffset_[newsym->getOffset()].push_back(newsym);
2362                 symsToModules_[newsym] = smodule;
2363             }
2364         }
2365     }
2366
2367 #if defined(TIMED_PARSE)
2368     struct timeval endtime;
2369   gettimeofday(&endtime, NULL);
2370   unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
2371   unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
2372   unsigned long difftime = lendtime - lstarttime;
2373   double dursecs = difftime/(1000 * 1000);
2374   cout << "parsing elf took "<<dursecs <<" secs" << endl;
2375 #endif
2376 }
2377
2378 #if defined(cap_dwarf)
2379
2380 string Object::find_symbol(string name)
2381 {
2382     string name2;
2383
2384     // pass #1: unmodified
2385     name2 = name;
2386     if (symbols_.find(name2)!=symbols_.end()) return name2;
2387
2388     // pass #2: leading underscore (C)
2389     name2 = "_" + name;
2390     if (symbols_.find(name2)!=symbols_.end()) return name2;
2391
2392     // pass #3: trailing underscore (Fortran)
2393     name2 = name + "_";
2394     if (symbols_.find(name2)!=symbols_.end())
2395         return name2;
2396
2397     return "";
2398 }
2399
2400 #endif
2401
2402
2403 /********************************************************
2404  *
2405  * For object files only....
2406  *   read the .debug_info section to find the module of global symbols
2407  *   see documents...
2408  *   - "DWARF Debugging Information Format"
2409  *   - "A Consumer Libary Interface to DWARF"
2410  *
2411  ********************************************************/
2412
2413 #if defined(cap_dwarf)
2414
2415 void pd_dwarf_handler(Dwarf_Error error, Dwarf_Ptr /*userData*/)
2416 {
2417     if (error == NULL)
2418         return;
2419
2420     char *dwarf_msg = dwarf_errmsg(error);
2421     string str = string("DWARF Error: ")+ dwarf_msg;
2422     dwarf_err_func(str.c_str());
2423
2424     //bperr( "DWARF error: %s\n", dwarf_msg);
2425 }
2426
2427 Dwarf_Signed declFileNo = 0;
2428 char ** declFileNoToName = NULL;
2429
2430 bool Object::dwarf_parse_aranges(Dwarf_Debug dbg, std::set<Dwarf_Off>& dies_seen)
2431 {
2432     Dwarf_Arange* ranges;
2433     Dwarf_Signed num_ranges;
2434     int status = dwarf_get_aranges(dbg, &ranges, &num_ranges, NULL);
2435     if(status != DW_DLV_OK) return false;
2436     Dwarf_Off cu_die_off;
2437     Dwarf_Die cu_die;
2438 //    cout << "Processing " << num_ranges << "DWARF ranges" << endl;
2439     for(int i = 0; i < num_ranges; i++)
2440     {
2441         Dwarf_Addr start;
2442         Dwarf_Unsigned len, segment, segment_size;
2443         // TODO: info_b has segment info from DWARF4
2444         status = dwarf_get_arange_info_b(ranges[i], &segment, &segment_size, &start, &len, &cu_die_off, NULL);
2445         assert(status == DW_DLV_OK);
2446         if(segment_size > 0)
2447         {
2448             cout << "WARNING: ignoring segment info" << endl;
2449         }
2450         if(dies_seen.find(cu_die_off) != dies_seen.end()) continue;
2451         if(len == 0) continue;
2452         status = dwarf_offdie_b(dbg, cu_die_off, Dwarf_Bool(true), &cu_die, NULL);
2453         assert(status == DW_DLV_OK);
2454         std::string modname;
2455         if(!DwarfWalker::findDieName(dbg, cu_die, modname))
2456         {
2457             modname = associated_symtab->file(); // default module
2458         }
2459         Offset actual_start, actual_end;
2460         convertDebugOffset(start, actual_start);
2461         convertDebugOffset(start + len, actual_end);
2462         Module* m = associated_symtab->getOrCreateModule(modname, actual_start);
2463         m->addRange(actual_start, actual_end);
2464         m->addDebugInfo(cu_die);
2465         DwarfWalker::buildSrcFiles(dbg, cu_die, m->getStrings());
2466         dies_seen.insert(cu_die_off);
2467         dwarf_dealloc(dbg, ranges[i], DW_DLA_ARANGE);
2468     }
2469     dwarf_dealloc(dbg, ranges, DW_DLA_LIST);
2470     return true;
2471 }
2472
2473 bool Object::fix_global_symbol_modules_static_dwarf()
2474 {
2475     /* Initialize libdwarf. */
2476     Dwarf_Debug *dbg_ptr = dwarf->type_dbg();
2477     if (!dbg_ptr)
2478         return false;
2479     Dwarf_Debug dbg = *dbg_ptr;
2480     std::set<Dwarf_Off> dies_seen;
2481     Dwarf_Off cu_die_off;
2482     Dwarf_Die cu_die;
2483     dwarf_parse_aranges(dbg, dies_seen);
2484     /* Iterate over the compilation-unit headers. */
2485     while (dwarf_next_cu_header_c(dbg, Dwarf_Bool(true),
2486                                   NULL,
2487                                   NULL,
2488                                   NULL,
2489                                   NULL,
2490                                   NULL,
2491                                   NULL,
2492                                   NULL,
2493                                   NULL,
2494                                   &cu_die_off, NULL) == DW_DLV_OK )
2495     {
2496         int status = dwarf_siblingof_b(dbg, NULL, Dwarf_Bool(true), &cu_die, NULL);
2497         assert(status == DW_DLV_OK);
2498         if(dies_seen.find(cu_die_off) != dies_seen.end()) continue;
2499         std::string modname;
2500         if(!DwarfWalker::findDieName(dbg, cu_die, modname))
2501         {
2502             modname = associated_symtab->file(); // default module
2503         }
2504 //        cout << "Processing CU DIE for " << modname << endl;
2505         Address tempModLow;
2506         Address modLow = 0;
2507         if (DwarfWalker::findConstant(DW_AT_low_pc, tempModLow, cu_die, dbg)) {
2508             convertDebugOffset(tempModLow, modLow);
2509         }
2510         std::vector<AddressRange> mod_ranges = DwarfWalker::getDieRanges(dbg, cu_die, modLow);
2511         Module* m = associated_symtab->getOrCreateModule(modname, modLow);
2512         for(auto r = mod_ranges.begin();
2513                 r != mod_ranges.end();
2514                 ++r)
2515         {
2516             m->addRange(r->first, r->second);
2517         }
2518         m->addDebugInfo(cu_die);
2519         DwarfWalker::buildSrcFiles(dbg, cu_die, m->getStrings());
2520         dies_seen.insert(cu_die_off);
2521
2522     }
2523
2524     return true;
2525 }
2526
2527 #else
2528
2529 // dummy definition for non-DWARF platforms
2530 bool Object::fix_global_symbol_modules_static_dwarf()
2531 { return false; }
2532
2533 #endif // cap_dwarf
2534
2535 /********************************************************
2536  *
2537  * For object files only....
2538  *  read the .stab section to find the module of global symbols
2539  *
2540  ********************************************************/
2541
2542 bool Object::fix_global_symbol_modules_static_stab(Elf_X_Shdr* stabscnp, Elf_X_Shdr* stabstrscnp)
2543 {
2544     // Read the stab section to find the module of global symbols.
2545     // The symbols appear in the stab section by module. A module begins
2546     // with a symbol of type N_UNDF and ends with a symbol of type N_ENDM.
2547     // All the symbols in between those two symbols belong to the module.
2548
2549     if (!stabscnp || !stabstrscnp) return false;
2550
2551     Elf_X_Data stabdata = stabscnp->get_data();
2552     Elf_X_Data stabstrdata = stabstrscnp->get_data();
2553     stab_entry *stabptr = NULL;
2554
2555     if (!stabdata.isValid() || !stabstrdata.isValid()) return false;
2556
2557     switch (addressWidth_nbytes)
2558     {
2559         case 4:
2560             stabptr = new stab_entry_32(stabdata.d_buf(),
2561                                         stabstrdata.get_string(),
2562                                         stabscnp->sh_size() / sizeof(stab32));
2563             break;
2564
2565         case 8:
2566             stabptr = new stab_entry_64(stabdata.d_buf(),
2567                                         stabstrdata.get_string(),
2568                                         stabscnp->sh_size() / sizeof(stab64));
2569             break;
2570     };
2571
2572     const char *next_stabstr = stabptr->getStringBase();
2573     string module = "DEFAULT_MODULE";
2574
2575     // the stabstr contains one string table for each module.
2576     // stabstr_offset gives the offset from the begining of stabstr of the
2577     // string table for the current module.
2578
2579     bool is_fortran = false;  // is the current module fortran code?
2580
2581     for (unsigned i = 0; i < stabptr->count(); i++)
2582     {
2583         switch(stabptr->type(i))
2584         {
2585             case N_UNDF: /* start of object file */
2586                 stabptr->setStringBase(next_stabstr);
2587                 next_stabstr = stabptr->getStringBase() + stabptr->val(i);
2588                 break;
2589
2590             case N_ENDM: /* end of object file */
2591                 is_fortran = false;
2592                 module = "DEFAULT_MODULE";
2593                 break;
2594
2595             case N_SO: /* compilation source or file name */
2596                 if ((stabptr->desc(i) == N_SO_FORTRAN) || (stabptr->desc(i) == N_SO_F90))
2597                     is_fortran = true;
2598
2599                 module = string(stabptr->name(i));
2600                 break;
2601
2602             case N_ENTRY: /* fortran alternate subroutine entry point */
2603             case N_GSYM: /* global symbol */
2604                 // the name string of a function or object appears in the stab
2605                 // string table as <symbol name>:<symbol descriptor><other stuff>
2606                 // where <symbol descriptor> is a one char code.
2607                 // we must extract the name and descriptor from the string
2608             {
2609                 const char *p = stabptr->name(i);
2610                 // bperr("got %d type, str = %s\n", stabptr->type(i), p);
2611                 // if (stabptr->type(i) == N_FUN && strlen(p) == 0) {
2612
2613                 if (strlen(p) == 0)
2614                 {
2615                     // GNU CC 2.8 and higher associate a null-named function
2616                     // entry with the end of a function.  Just skip it.
2617                     break;
2618                 }
2619
2620                 const char *q = strchr(p,':');
2621                 unsigned len;
2622
2623                 if (q)
2624                 {
2625                     len = q - p;
2626                 }
2627                 else
2628                 {
2629                     len = strlen(p);
2630                 }
2631
2632                 if (len == 0)
2633                 {
2634                     // symbol name is empty.Skip it.- 02/12/07 -Giri
2635                     break;
2636                 }
2637
2638                 char *sname = new char[len+1];
2639                 strncpy(sname, p, len);
2640                 sname[len] = 0;
2641
2642                 string SymName = string(sname);
2643
2644                 // q points to the ':' in the name string, so
2645                 // q[1] is the symbol descriptor. We must check the symbol descriptor
2646                 // here to skip things we are not interested in, such as prototypes.
2647
2648                 bool res = (symbols_.find(SymName)!=symbols_.end());
2649
2650                 if (!res && is_fortran)
2651                 {
2652                     // Fortran symbols usually appear with an '_' appended in .symtab,
2653                     // but not on .stab
2654                     SymName += "_";
2655                     res = (symbols_.find(SymName)!=symbols_.end());
2656                 }
2657
2658                 if (res && (q == 0 || q[1] != SD_PROTOTYPE))
2659                 {
2660                     unsigned int count = 0;
2661                     std::vector< Symbol *> & syms = symbols_[SymName];
2662
2663                     /* If there's only one, apply regardless. */
2664                     if ( syms.size() == 1 )
2665                     {
2666                         // TODO: set module
2667                         //                  symbols_[SymName][0]->setModuleName(module);
2668                     }
2669                     else
2670                     {
2671                         for ( unsigned int i = 0; i < syms.size(); i++ )
2672                         {
2673                             if ( syms[i]->getLinkage() == Symbol::SL_GLOBAL )
2674                             {
2675                                 // TODO: set module
2676                                 //                          symbols_[SymName][i]->setModuleName(module);
2677                                 count++;
2678                             }
2679                         }
2680                     }
2681                 }
2682                 break;
2683             }
2684             case N_FUN:
2685                 /* function */
2686             {
2687                 const char *p = stabptr->name(i);
2688
2689                 if (strlen(p) == 0)
2690                 {
2691                     // Rumours are that GNU CC 2.8 and higher associate a
2692                     // null-named function entry with the end of a
2693                     // function. Just skip it.
2694                     break;
2695                 }
2696
2697                 const char *q = strchr(p,':');
2698
2699                 if (q == 0)
2700                 {
2701                     // bperr( "Unrecognized stab format: %s\n", p);
2702                     // Happens with the Solaris native compiler (.xstabs entries?)
2703                     break;
2704                 }
2705
2706                 if (q[1] == SD_PROTOTYPE)
2707                 {
2708                     // We see a prototype, skip it
2709                     break;
2710                 }
2711
2712                 unsigned long entryAddr = stabptr->val(i);
2713
2714                 if (entryAddr == 0)
2715                 {
2716                     // The function stab doesn't contain a function address
2717                     // (happens with the Solaris native compiler). We have to
2718                     // look up the symbol by its name. That's unfortunate, since
2719                     // names may not be unique and we may end up assigning a wrong
2720                     // module name to the symbol.
2721                     unsigned len = q - p;
2722                     if (len == 0)
2723                     {
2724                         // symbol name is empty.Skip it.- 02/12/07 -Giri
2725                         break;
2726                     }
2727
2728                     char *sname = new char[len+1];
2729                     strncpy(sname, p, len);
2730                     sname[len] = 0;
2731                     string nameFromStab = string(sname);
2732                     delete[] sname;
2733
2734                     for (unsigned i = 0; i < symbols_[nameFromStab].size(); i++) {
2735                         symsToModules_[symbols_[nameFromStab][i]] = module;
2736                     }
2737                 }
2738                 else
2739                 {
2740                     if (symsByOffset_.find(entryAddr)==symsByOffset_.end()) {
2741                         //bperr( "fix_global_symbol_modules_static_stab "
2742                         //         "can't find address 0x%lx of STABS entry %s\n", entryAddr, p);
2743                         break;
2744                     }
2745                     for (unsigned i = 0; i < symsByOffset_[entryAddr].size(); i++) {
2746                         symsToModules_[symsByOffset_[entryAddr][i]] = module;
2747                     }
2748                 }
2749                 break;
2750             }
2751
2752             default:
2753                 /* ignore other entries */
2754                 break;
2755         }
2756     }
2757
2758     delete stabptr;
2759
2760     return true;
2761 }
2762
2763
2764 // find_code_and_data(): populates the following members:
2765 //   code_ptr_, code_off_, code_len_
2766 //   data_ptr_, data_off_, data_len_
2767 void Object::find_code_and_data(Elf_X &elf,
2768                                 Offset txtaddr,
2769                                 Offset dataddr)
2770 {
2771     /* Note:
2772    * .o's don't have program headers, so these fields are populated earlier
2773    * when the sections are processed -> see loaded_elf()
2774    */
2775
2776     for (int i = 0; i < elf.e_phnum(); ++i) {
2777         Elf_X_Phdr &phdr = elf.get_phdr(i);
2778
2779         char *file_ptr = (char *)mf->base_addr();
2780         /*
2781       if(!isRegionPresent(phdr.p_paddr(), phdr.p_filesz(), phdr.p_flags())) {
2782       Region *reg = new Region(i, "", phdr.p_paddr(), phdr.p_filesz(),
2783       phdr.p_vaddr(), phdr.p_memsz(),
2784       &file_ptr[phdr.p_offset()],
2785       getSegmentPerms(phdr.p_flags()),
2786       getSegmentType(phdr.p_type(), phdr.p_flags()));
2787       reg->setFileOffset(phdr.p_offset());
2788       regions_.push_back(reg);
2789       }
2790     */
2791         // The code pointer, offset, & length should be set even if
2792         // txtaddr=0, so in this case we set these values by
2793         // identifying the segment that contains the entryAddress
2794         if (((phdr.p_vaddr() <= txtaddr) &&
2795              (phdr.p_vaddr() + phdr.p_filesz() >= txtaddr)) ||
2796             (!txtaddr && ((phdr.p_vaddr() <= entryAddress_) &&
2797                           (phdr.p_vaddr() + phdr.p_filesz() >= entryAddress_)))) {
2798
2799             if (code_ptr_ == 0 && code_off_ == 0 && code_len_ == 0) {
2800                 code_ptr_ = (char *)(void*)&file_ptr[phdr.p_offset()];
2801                 code_off_ = (Offset)phdr.p_vaddr();
2802                 code_len_ = (unsigned)phdr.p_filesz();
2803             }
2804
2805         } else if (((phdr.p_vaddr() <= dataddr) &&
2806                     (phdr.p_vaddr() + phdr.p_filesz() >= dataddr)) ||
2807                    (!dataddr && (phdr.p_type() == PT_LOAD))) {
2808             if (data_ptr_ == 0 && data_off_ == 0 && data_len_ == 0) {
2809                 data_ptr_ = (char *)(void *)&file_ptr[phdr.p_offset()];
2810                 data_off_ = (Offset)phdr.p_vaddr();
2811                 data_len_ = (unsigned)phdr.p_filesz();
2812             }
2813         }
2814     }
2815     //if (addressWidth_nbytes == 8) bperr( ">>> 64-bit find_code_and_data() successful\n");
2816 }
2817
2818 const char *Object::elf_vaddr_to_ptr(Offset vaddr) const
2819 {
2820     const char *ret = NULL;
2821     unsigned code_size_ = code_len_;
2822     unsigned data_size_ = data_len_;
2823
2824     if (vaddr >= code_off_ && vaddr < code_off_ + code_size_) {
2825         ret = ((char *)code_ptr_) + (vaddr - code_off_);
2826     } else if (vaddr >= data_off_ && vaddr < data_off_ + data_size_) {
2827         ret = ((char *)data_ptr_) + (vaddr - data_off_);
2828     }
2829
2830     return ret;
2831 }
2832
2833 stab_entry *Object::get_stab_info() const
2834 {
2835     char *file_ptr = (char *)mf->base_addr();
2836
2837     // check that file has .stab info
2838     if (stab_off_ && stab_size_ && stabstr_off_) {
2839         switch (addressWidth_nbytes) {
2840             case 4: // 32-bit object
2841                 return new stab_entry_32(file_ptr + stab_off_,
2842                                          file_ptr + stabstr_off_,
2843                                          stab_size_ / sizeof(stab32));
2844                 break;
2845             case 8: // 64-bit object
2846                 return new stab_entry_64(file_ptr + stab_off_,
2847                                          file_ptr + stabstr_off_,
2848                                          stab_size_ / sizeof(stab64));
2849                 break;
2850         };
2851     }
2852
2853     return new stab_entry_64();
2854 }
2855
2856 Object::Object(MappedFile *mf_, bool, void (*err_func)(const char *),
2857                bool alloc_syms, Symtab* st) :
2858         AObject(mf_, err_func, st),
2859         elfHdr(NULL),
2860         hasReldyn_(false),
2861         hasReladyn_(false),
2862         hasRelplt_(false),
2863         hasRelaplt_(false),
2864         relType_(Region::RT_REL),
2865         isBlueGeneP_(false), isBlueGeneQ_(false),
2866         hasNoteSection_(false),
2867         elf_hash_addr_(0), gnu_hash_addr_(0),
2868         dynamic_offset_(0), dynamic_size_(0), dynsym_size_(0),
2869         init_addr_(0), fini_addr_(0),
2870         text_addr_(0), text_size_(0),
2871         symtab_addr_(0), strtab_addr_(0),
2872         dynamic_addr_(0), dynsym_addr_(0), dynstr_addr_(0),
2873         got_addr_(0), got_size_(0),
2874         plt_addr_(0), plt_size_(0), plt_entry_size_(0),
2875         rel_plt_addr_(0), rel_plt_size_(0), rel_plt_entry_size_(0),
2876         rel_addr_(0), rel_size_(0), rel_entry_size_(0),
2877         opd_addr_(0), opd_size_(0),
2878         stab_off_(0), stab_size_(0), stabstr_off_(0),
2879         stab_indx_off_(0), stab_indx_size_(0), stabstr_indx_off_(0),
2880         dwarvenDebugInfo(false),
2881         loadAddress_(0), entryAddress_(0),
2882         interpreter_name_(NULL),
2883         isStripped(false),
2884         dwarf(NULL),
2885         EEL(false), did_open(false),
2886         obj_type_(obj_Unknown),
2887         DbgSectionMapSorted(false),
2888         soname_(NULL)
2889 {
2890
2891 #if defined(TIMED_PARSE)
2892     struct timeval starttime;
2893   gettimeofday(&starttime, NULL);
2894 #endif
2895     is_aout_ = false;
2896
2897     if(mf->getFD() != -1) {
2898         elfHdr = Elf_X::newElf_X(mf->getFD(), ELF_C_READ, NULL, mf_->pathname());
2899     }
2900     else {
2901         elfHdr = Elf_X::newElf_X((char *)mf->base_addr(), mf->size(), mf_->pathname());
2902     }
2903
2904     // ELF header: sanity check
2905     //if (!elfHdr->isValid()|| !pdelf_check_ehdr(elfHdr))
2906     if (!elfHdr->isValid())  {
2907         log_elferror(err_func_, "ELF header");
2908         has_error = true;
2909         return;
2910     }
2911     else if (!pdelf_check_ehdr(*elfHdr)) {
2912         log_elferror(err_func_, "ELF header failed integrity check");
2913         has_error = true;
2914         return;
2915     }
2916
2917     dwarf = DwarfHandle::createDwarfHandle(mf_->pathname(), elfHdr);
2918     if( elfHdr->e_type() == ET_DYN ) {
2919 //        load_shared_object(alloc_syms);
2920             load_object(alloc_syms);
2921     }
2922     else if( elfHdr->e_type() == ET_REL || elfHdr->e_type() == ET_EXEC ) {
2923         // Differentiate between an executable and an object file
2924         if( elfHdr->e_phnum() ) is_aout_ = true;
2925         else is_aout_ = false;
2926
2927         load_object(alloc_syms);
2928     }
2929     else {
2930         log_perror(err_func_,"Invalid filetype in Elf header");
2931         has_error = true;
2932         return;
2933     }
2934
2935 #ifdef BINEDIT_DEBUG
2936     print_symbol_map(&symbols_);
2937 #endif
2938 #if defined(TIMED_PARSE)
2939     struct timeval endtime;
2940   gettimeofday(&endtime, NULL);
2941   unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
2942   unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
2943   unsigned long difftime = lendtime - lstarttime;
2944   double dursecs = difftime/(1000 );
2945   cout << "obj parsing in Object-elf took "<<dursecs <<" msecs" << endl;
2946 #endif
2947 }
2948
2949 Object::~Object()
2950 {
2951     relocation_table_.clear();
2952     fbt_.clear();
2953     allRegionHdrs.clear();
2954     versionMapping.clear();
2955     versionFileNameMapping.clear();
2956     deps_.clear();
2957 }
2958
2959 void Object::log_elferror(void (*err_func)(const char *), const char* msg)
2960 {
2961     const char* err = elf_errmsg(elf_errno());
2962     err = err ? err: "(bad elf error)";
2963     string str = string(err)+string(msg);
2964     err_func(str.c_str());
2965 }
2966
2967 bool Object::get_func_binding_table(std::vector<relocationEntry> &fbt) const
2968 {
2969 #if !defined(os_vxworks)
2970     if(!plt_addr_ || (!fbt_.size())) return false;
2971 #endif
2972     fbt = fbt_;
2973     return true;
2974 }
2975
2976 bool Object::get_func_binding_table_ptr(const std::vector<relocationEntry> *&fbt) const
2977 {
2978     if(!plt_addr_ || (!fbt_.size())) return false;
2979     fbt = &fbt_;
2980     return true;
2981 }
2982
2983 void Object::getDependencies(std::vector<std::string> &deps){
2984     deps = deps_;
2985 }
2986
2987 bool Object::addRelocationEntry(relocationEntry &re)
2988 {
2989     relocation_table_.push_back(re);
2990     return true;
2991 }
2992
2993 #ifdef DEBUG
2994
2995 // stream-based debug output
2996 const ostream &Object::dump_state_info(ostream &s)
2997 {
2998   s << "Debugging Information for Object (address) : " << this << endl;
2999
3000   s << " <<begin debugging info for base object>>" << endl;
3001   AObject::dump_state_info(s);
3002   s << " <<end debuggingo info for base object>>" << endl;
3003
3004   s << " dynsym_addr_ = " << dynsym_addr_ << endl;
3005   s << " dynstr_addr_ = " << dynstr_addr_ << endl;
3006   s << " got_addr_ = " << got_addr_ << endl;
3007   s << " plt_addr_ = " << plt_addr_ << endl;
3008   s << " plt_size_ = " << plt_size_ << endl;
3009   s << " plt_entry_size_ = " << plt_entry_size_ << endl;
3010   s << " rel_plt_addr_ = " << rel_plt_addr_ << endl;
3011   s << " rel_plt_size_ = " << rel_plt_size_ << endl;
3012   s << " rel_plt_entry_size_ = " << rel_plt_entry_size_ << endl;
3013   s << " rel_size_ = " << rel_size_ << endl;
3014   s << " rel_entry_size_ = " << rel_entry_size_ << endl;
3015   s << " stab_off_ = " << stab_off_ << endl;
3016   s << " stab_size_ = " << stab_size_ << endl;
3017   s << " stabstr_off_ = " << stabstr_off_ << endl;
3018   s << " dwarvenDebugInfo = " << dwarvenDebugInfo << endl;
3019
3020   // and dump the relocation table....
3021   s << " fbt_ = (field seperator :: )" << endl;
3022   for (unsigned i=0; i < fbt_.size(); i++) {
3023     s << fbt_[i] << " :: ";
3024   }
3025   s << endl;
3026
3027   return s;
3028 }
3029
3030 #endif
3031
3032
3033 Offset Object::getPltSlot(string funcName) const
3034 {
3035     relocationEntry re;
3036     Offset offset=0;
3037
3038     for ( unsigned int i = 0; i < fbt_.size(); i++ ){
3039         if (funcName == fbt_[i].name() ){
3040             offset =  fbt_[i].rel_addr();
3041         }
3042     }
3043
3044     return offset;
3045 }
3046
3047 //
3048 // get_valid_memory_areas - get ranges of code/data segments that have
3049 //                       sections mapped to them
3050 //
3051
3052 void Object::get_valid_memory_areas(Elf_X &elf)
3053 {
3054     for (unsigned i = 0; i < elf.e_shnum(); ++i) {
3055         Elf_X_Shdr &shdr = elf.get_shdr(i);
3056         if ( !shdr.isValid()) {
3057             break;
3058         }
3059         if (shdr.sh_flags() & SHF_ALLOC) { // This section is in memory
3060             if (code_off_ <= shdr.sh_addr() &&
3061                 shdr.sh_addr() <= code_off_ + code_len_) {
3062                 if (shdr.sh_addr() < code_vldS_)
3063                     code_vldS_ = shdr.sh_addr();
3064                 if (shdr.sh_addr() + shdr.sh_size() > code_vldE_)
3065                     code_vldE_ = shdr.sh_addr() + shdr.sh_size();
3066
3067             } else if (data_off_ <= shdr.sh_addr() &&
3068                        shdr.sh_addr() <= data_off_ + data_len_) {
3069                 if (shdr.sh_addr() < data_vldS_)
3070                     data_vldS_ = shdr.sh_addr();
3071                 if (shdr.sh_addr() + shdr.sh_size() > data_vldE_)
3072                     data_vldE_ = shdr.sh_addr() + shdr.sh_size();
3073             }
3074         }
3075     }
3076 }
3077
3078 //
3079 // parseCompilerType - parse for compiler that was used to generate object
3080 //
3081 //
3082 //
3083 #if defined(os_linux)
3084 // Differentiating between g++ and pgCC by stabs info (as in the solaris/
3085 // aix case, below) will not work; the gcc-compiled object files that
3086 // get included at link time will fill in the N_OPT stabs line. Instead,
3087 // look for "pgCC_compiled." symbols.
3088 bool parseCompilerType(Object *objPtr)
3089 {
3090     dyn_hash_map<string, std::vector<Symbol *> >*syms = objPtr->getAllSymbols();
3091     if(syms->find("pgCC_compiled.") != syms->end())
3092         return true;
3093     return false;
3094 }
3095 #else
3096 bool parseCompilerType(Object *objPtr)
3097 {
3098   stab_entry *stabptr = objPtr->get_stab_info();
3099   const char *next_stabstr = stabptr->getStringBase();
3100
3101   for (unsigned int i=0; i < stabptr->count(); ++i) {
3102     // if (stabstrs) bperr("parsing #%d, %s\n", stabptr->type(i), stabptr->name(i));
3103     switch (stabptr->type(i)) {
3104
3105     case N_UNDF: /* start of object file */
3106       /* value contains offset of the next string table for next module */
3107       // assert(stabptr.nameIdx(i) == 1);
3108       stabptr->setStringBase(next_stabstr);
3109       next_stabstr = stabptr->getStringBase() + stabptr->val(i);
3110       break;
3111
3112     case N_OPT: /* Compiler options */
3113       delete stabptr;
3114       return false;
3115     }
3116   }
3117   delete stabptr;
3118   return false; // Shouldn't happen - maybe N_OPT stripped
3119 }
3120 #endif
3121
3122
3123 #if (defined(os_linux) || defined(os_freebsd))
3124
3125 static unsigned long read_uleb128(const unsigned char *data, unsigned *bytes_read)
3126 {
3127     unsigned long result = 0;
3128     unsigned shift = 0;
3129     *bytes_read = 0;
3130     while (1)
3131     {
3132         result |= (data[*bytes_read] & 0x7f) << shift;
3133         if ((data[(*bytes_read)++] & 0x80) == 0)
3134             break;
3135         shift += 7;
3136     }
3137     return result;
3138 }
3139
3140 static signed long read_sleb128(const unsigned char *data, unsigned *bytes_read)
3141 {
3142     unsigned long result = 0;
3143     unsigned shift = 0;
3144     *bytes_read = 0;
3145     while (1)
3146     {
3147         result |= (data[*bytes_read] & 0x7f) << shift;
3148         shift += 7;
3149         if ((data[*bytes_read] & 0x80) == 0)
3150             break;
3151         (*bytes_read)++;
3152     }
3153     if (shift < sizeof(int) && (data[*bytes_read] & 0x40))
3154         result |= -(1 << shift);
3155     (*bytes_read)++;
3156
3157     return result;
3158 }
3159
3160 #define DW_EH_PE_absptr      0x00
3161 #define DW_EH_PE_uleb128     0x01
3162 #define DW_EH_PE_udata2      0x02
3163 #define DW_EH_PE_udata4      0x03
3164 #define DW_EH_PE_udata8      0x04
3165 #define DW_EH_PE_sleb128     0x09
3166 #define DW_EH_PE_sdata2      0x0A
3167 #define DW_EH_PE_sdata4      0x0B
3168 #define DW_EH_PE_sdata8      0x0C
3169 #define DW_EH_PE_pcrel       0x10
3170 #define DW_EH_PE_textrel     0x20
3171 #define DW_EH_PE_datarel     0x30
3172 #define DW_EH_PE_funcrel     0x40
3173 #define DW_EH_PE_aligned     0x50
3174 #define DW_EH_PE_indirect    0x80
3175 #define DW_EH_PE_omit        0xff
3176
3177 typedef struct {
3178     int word_size;
3179     unsigned long pc;
3180     unsigned long text;
3181     unsigned long data;
3182     unsigned long func;
3183 } mach_relative_info;
3184
3185 static int read_val_of_type(int type, unsigned long *value, const unsigned char *addr,
3186                             const mach_relative_info &mi)
3187 {
3188     unsigned size = 0;
3189     if (type == DW_EH_PE_omit)
3190         return 0;
3191
3192     unsigned long base = 0x0;
3193     /**
3194    * LSB Standard says that the upper four bits (0xf0) encode the base.
3195    * Except that none of these values should their upper bits set,
3196    * and I'm finding the upper bit seems to sometimes contain garbage.
3197    * gcc uses the 0x70 bits in its exception parsing, so that's what we'll do.
3198    **/
3199     switch (type & 0x70)
3200     {
3201         case DW_EH_PE_pcrel:
3202             base = mi.pc;
3203             break;
3204         case DW_EH_PE_textrel:
3205             base = mi.text;
3206             break;
3207         case DW_EH_PE_datarel:
3208             base = mi.data;
3209             break;
3210         case DW_EH_PE_funcrel:
3211             base = mi.func;
3212             break;
3213     }
3214
3215     if ((type & 0x70) == DW_EH_PE_aligned)
3216     {
3217         if (mi.word_size == 4) {
3218             addr = (const unsigned char*)(((unsigned long)addr + 3) & (~0x3l));
3219         }
3220         else if (mi.word_size == 8) {
3221             addr = (const unsigned char*)(((unsigned long)addr + 7) & (~0x7l));
3222         }
3223     }
3224
3225
3226     switch (type & 0x0f)
3227     {
3228         case DW_EH_PE_absptr:
3229             if (mi.word_size == 4) {
3230                 *value = (unsigned long) *((const uint32_t *) addr);
3231                 size = 4;
3232             }
3233             else if (mi.word_size == 8) {
3234                 *value = (unsigned long) *((const uint64_t *) addr);
3235                 size = 8;
3236             }
3237             break;
3238         case DW_EH_PE_uleb128:
3239             *value = read_uleb128(addr, &size);
3240             break;
3241         case DW_EH_PE_sleb128:
3242             *value = read_sleb128(addr, &size);
3243             break;
3244         case DW_EH_PE_udata2:
3245             *value = *((const uint16_t *) addr);
3246             size = 2;
3247             break;
3248         case DW_EH_PE_sdata2:
3249             *value = *((const int16_t *) addr);
3250             size = 2;
3251             break;
3252         case DW_EH_PE_udata4:
3253             *value = *((const uint32_t *) addr);
3254             size = 4;
3255             break;
3256         case DW_EH_PE_sdata4:
3257             *value = *((const int32_t *) addr);
3258             size = 4;
3259             break;
3260         case DW_EH_PE_udata8:
3261             *value = *((const uint64_t *) addr);
3262             size = 8;
3263             break;
3264         case DW_EH_PE_sdata8:
3265             *value = *((const int64_t *) addr);
3266             size = 8;
3267             break;
3268         default:
3269             fprintf(stderr, "Unhandled type %d\n", type & 0x0f);
3270             return -1;
3271     }
3272
3273     if (*value) {
3274         *value += base;
3275         if (type & DW_EH_PE_indirect) {
3276             // When there is a indirect catch block,
3277             // it is often the case that the indirect pointer would point
3278             // to a dynamic section, not resolvable at static time.
3279             // We currently ignore this dynamic catch block.
3280             *value = 0;
3281         }
3282     }
3283     return size;
3284 }
3285
3286 /**
3287  * On GCC 3.x/x86 we find catch blocks as follows:
3288  *   1. We start with a list of FDE entries in the .eh_frame
3289  *      table.
3290  *   2. Each FDE entry has a pointer to a  CIE entry.  The CIE
3291  *      tells us whether the FDE has any 'Augmentations', and
3292  *      the types of those augmentations.  The FDE also
3293  *      contains a pointer to a function.
3294  *   3. If one of the FDE augmentations is a 'Language Specific Data Area'
3295  *      then we have a pointer to one or more entires in the gcc_except_table.
3296  *   4. The gcc_except_table contains entries that point
3297  *      to try and catch blocks, all encoded as offsets
3298  *      from the function start (it doesn't tell you which
3299  *      function, however).
3300  *   5. We can add the function offsets from the gcc_except_table
3301  *      to the function pointer from the FDE to get all of
3302  *      the try/catch blocks.
3303  **/
3304 #define SHORT_FDE_HLEN 4
3305 #define LONG_FDE_HLEN 12
3306 static
3307 int read_except_table_gcc3(Dwarf_Fde *fde_data, Dwarf_Signed fde_count,
3308                            mach_relative_info &mi,
3309                            Elf_X_Shdr *eh_frame, Elf_X_Shdr *except_scn,
3310                            std::vector<ExceptionBlock> &addresses)
3311 {
3312     Dwarf_Error err = (Dwarf_Error) NULL;
3313     Dwarf_Addr low_pc;
3314     Dwarf_Unsigned bytes_in_cie;
3315     Dwarf_Off fde_offset, cie_offset;
3316     Dwarf_Fde fde;
3317     Dwarf_Cie cie;
3318     int status, result, ptr_size;
3319     char *augmentor;
3320     unsigned char lpstart_format, ttype_format, table_format;
3321     unsigned long value, table_end, region_start, region_size, landingpad_base;
3322     unsigned long catch_block, action, augmentor_len;
3323     Dwarf_Small *fde_augdata, *cie_augdata;
3324     Dwarf_Unsigned fde_augdata_len, cie_augdata_len;
3325
3326     //For each FDE
3327     for (int i = 0; i < fde_count; i++) {
3328         unsigned int j;
3329         unsigned char lsda_encoding = 0xff, personality_encoding = 0xff;
3330         unsigned char *lsda_ptr = NULL;
3331         unsigned char *cur_augdata;
3332         unsigned long except_off;
3333         unsigned long fde_addr, cie_addr;
3334         unsigned char *fde_bytes, *cie_bytes;
3335
3336         //Get the FDE
3337         status = dwarf_get_fde_n(fde_data, (Dwarf_Unsigned) i, &fde, &err);
3338         if (status != DW_DLV_OK) {
3339             pd_dwarf_handler(err, NULL);
3340             return false;
3341         }
3342
3343         //After this set of computations we should have:
3344         // low_pc = mi.func = the address of the function that contains this FDE
3345         // fde_bytes = the start of the FDE in our memory space
3346         // cie_bytes = the start of the CIE in our memory space
3347         status = dwarf_get_fde_range(fde, &low_pc, NULL, (void **) &fde_bytes,
3348                                      NULL, &cie_offset, NULL,
3349                                      &fde_offset, &err);
3350         if (status != DW_DLV_OK) {
3351             pd_dwarf_handler(err, NULL);
3352             return false;
3353         }
3354         //The LSB strays from the DWARF here, when parsing the except_eh section
3355         // the cie_offset is relative to the FDE rather than the start of the
3356         // except_eh section.
3357         cie_offset = fde_offset - cie_offset +
3358                      (*(uint32_t*)fde_bytes == 0xffffffff ? LONG_FDE_HLEN : SHORT_FDE_HLEN);
3359         cie_bytes = (unsigned char *)eh_frame->get_data().d_buf() + cie_offset;
3360
3361         //Get the CIE for the FDE
3362         status = dwarf_get_cie_of_fde(fde, &cie, &err);
3363         if (status != DW_DLV_OK) {
3364             pd_dwarf_handler(err, NULL);
3365             return false;
3366   &nb