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