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