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