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