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