2 * See the dyninst/COPYRIGHT file for copyright information.
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.
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.
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.
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.
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
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 ************************************************************************/
44 #include "Aggregate.h"
49 #if defined(x86_64_unknown_linux2_4) || \
50 defined(ppc64_linux) || \
51 (defined(os_freebsd) && defined(arch_x86_64))
52 #include "emitElf-64.h"
55 #include "dwarfWalker.h"
57 using namespace Dyninst;
58 using namespace Dyninst::SymtabAPI;
61 #if !defined(_Object_elf_h_)
62 #error "Object-elf.h not #included"
69 #if defined(USES_DWARF_DEBUG)
74 //#include "symutil.h"
75 #include "common/h/pathName.h"
76 #include "Collections.h"
77 #if defined(TIMED_PARSE)
86 #include <boost/assign/list_of.hpp>
87 #include <boost/assign/std/set.hpp>
89 using namespace boost::assign;
93 // add some space to avoid looking for functions in data regions
96 bool Object::truncateLineFilenames = true;
98 string symt_current_func_name;
99 string symt_current_mangled_func_name;
100 Symbol *symt_current_func = NULL;
102 std::vector<Symbol *> opdsymbols_;
104 extern void print_symbols( std::vector< Symbol *>& allsymbols );
105 extern void print_symbol_map( dyn_hash_map< std::string, std::vector< Symbol *> > *symbols);
107 void (*dwarf_err_func)(const char *); // error callback for dwarf errors
109 static bool pdelf_check_ehdr(Elf_X &elf)
111 // Elf header integrity check
113 // This implies a valid header is a header for an executable, a shared object
114 // or a relocatable file (e.g .o) and it either has section headers or program headers
116 return ( (elf.e_type() == ET_EXEC || elf.e_type() == ET_DYN || elf.e_type() == ET_REL ) &&
117 ( ((elf.e_shoff() != 0) && (elf.e_shnum() != 0))
118 || ((elf.e_phoff() != 0) && (elf.e_phnum() != 0))
123 const char *pdelf_get_shnames(Elf_X &elf)
125 const char *result = NULL;
126 size_t shstrndx = elf.e_shstrndx();
128 Elf_X_Shdr shstrscn = elf.get_shdr(shstrndx);
129 if (shstrscn.isValid()) {
130 Elf_X_Data shstrdata = shstrscn.get_data();
131 if (shstrdata.isValid())
132 result = shstrdata.get_string();
138 // SectionHeaderSortFunction
140 // Compare function for use with the Vector<T> sort method.
142 struct SectionHeaderSortFunction: public binary_function<Elf_X_Shdr *, Elf_X_Shdr *, bool>
144 bool operator()(Elf_X_Shdr *hdr1, Elf_X_Shdr *hdr2) {
145 return (hdr1->sh_addr() < hdr2->sh_addr());
149 Region::perm_t getSegmentPerms(unsigned long flags){
151 return Region::RP_RWX;
153 return Region::RP_RW;
155 return Region::RP_RX;
160 Region::RegionType getSegmentType(unsigned long type, unsigned long flags)
162 if(type == PT_DYNAMIC)
163 return Region::RT_DYNAMIC;
165 return Region::RT_TEXTDATA;
167 return Region::RT_TEXT;
169 return Region::RT_DATA;
170 return Region::RT_OTHER;
173 /* binary search to find the section starting at a particular address */
174 Elf_X_Shdr *Object::getRegionHdrByAddr(Offset addr)
176 unsigned end = allRegionHdrs.size() - 1, start = 0;
179 mid = start + (end-start)/2;
180 if(allRegionHdrs[mid]->sh_addr() == addr)
181 return allRegionHdrs[mid];
182 else if(allRegionHdrs[mid]->sh_addr() < addr)
187 if(allRegionHdrs[start]->sh_addr() == addr)
188 return allRegionHdrs[start];
192 /* binary search to find the index into the RegionHdrs vector
193 of the section starting at a partidular address*/
194 int Object::getRegionHdrIndexByAddr(Offset addr)
196 int end = allRegionHdrs.size() - 1, start = 0;
199 mid = start + (end-start)/2;
200 if(allRegionHdrs[mid]->sh_addr() == addr)
202 else if(allRegionHdrs[mid]->sh_addr() < addr)
207 if(allRegionHdrs[start]->sh_addr() == addr)
212 Elf_X_Shdr *Object::getRegionHdrByIndex(unsigned index)
214 if (index >= allRegionHdrs.size())
216 return allRegionHdrs[index];
219 /* Check if there is a section which belongs to the segment and update permissions of that section.
220 * Return value indicates whether the segment has to be added to the list of regions*/
221 bool Object::isRegionPresent(Offset segmentStart, Offset segmentSize, unsigned segPerms){
222 bool present = false;
223 for(unsigned i = 0; i < regions_.size() ;i++){
224 if((regions_[i]->getDiskOffset() >= segmentStart) &&
225 ((regions_[i]->getDiskOffset()+regions_[i]->getDiskSize()) <= (segmentStart+segmentSize))){
227 regions_[i]->setRegionPermissions(getSegmentPerms(segPerms));
234 Region::perm_t getRegionPerms(unsigned long flags){
235 if((flags & SHF_WRITE) && !(flags & SHF_EXECINSTR))
236 return Region::RP_RW;
237 else if(!(flags & SHF_WRITE) && (flags & SHF_EXECINSTR))
238 return Region::RP_RX;
239 else if((flags & SHF_WRITE) && (flags & SHF_EXECINSTR))
240 return Region::RP_RWX;
245 Region::RegionType getRegionType(unsigned long type, unsigned long flags, const char *reg_name){
249 return Region::RT_SYMTAB;
251 return Region::RT_STRTAB;
253 return Region::RT_REL;
255 return Region::RT_RELA;
257 //Darn it, Linux/PPC has the PLT as a NOBITS. Can't just default
259 if (strcmp(reg_name, ".plt") == 0)
260 return Region::RT_OTHER;
262 return Region::RT_BSS;
264 if((flags & SHF_EXECINSTR) && (flags & SHF_WRITE))
265 return Region::RT_TEXTDATA;
266 else if(flags & SHF_EXECINSTR)
267 return Region::RT_TEXT;
269 return Region::RT_DATA;
271 return Region::RT_DYNAMIC;
273 return Region::RT_HASH;
275 return Region::RT_SYMVERSIONS;
277 return Region::RT_SYMVERDEF;
278 case SHT_GNU_verneed:
279 return Region::RT_SYMVERNEEDED;
281 return Region::RT_OTHER;
285 static Region::RegionType getRelTypeByElfMachine(Elf_X *localHdr) {
286 Region::RegionType ret;
287 switch(localHdr->e_machine()) {
295 ret = Region::RT_RELA;
298 ret = Region::RT_REL;
304 const char* EDITED_TEXT_NAME = ".edited.text";
305 // const char* INIT_NAME = ".init";
306 const char *INTERP_NAME = ".interp";
307 const char* FINI_NAME = ".fini";
308 const char* TEXT_NAME = ".text";
309 const char* BSS_NAME = ".bss";
310 const char* SYMTAB_NAME = ".symtab";
311 const char* STRTAB_NAME = ".strtab";
312 const char* STAB_NAME = ".stab";
313 const char* STABSTR_NAME = ".stabstr";
314 const char* STAB_INDX_NAME = ".stab.index";
315 const char* STABSTR_INDX_NAME= ".stab.indexstr";
316 const char* COMMENT_NAME= ".comment";
317 const char* OPD_NAME = ".opd"; // PPC64 Official Procedure Descriptors
318 // sections from dynamic executables and shared objects
319 const char* PLT_NAME = ".plt";
320 #if defined(os_vxworks)
321 const char* REL_PLT_NAME = ".rela.text";
323 const char* REL_PLT_NAME = ".rela.plt"; // sparc-solaris
325 const char* REL_PLT_NAME2 = ".rel.plt"; // x86-solaris
326 const char* GOT_NAME = ".got";
327 const char* DYNSYM_NAME = ".dynsym";
328 const char* DYNSTR_NAME = ".dynstr";
329 const char* DATA_NAME = ".data";
330 const char* RO_DATA_NAME = ".ro_data"; // mips
331 const char* DYNAMIC_NAME = ".dynamic";
332 const char* EH_FRAME_NAME = ".eh_frame";
333 const char* EXCEPT_NAME = ".gcc_except_table";
334 const char* EXCEPT_NAME_ALT = ".except_table";
336 set<string> debugInfoSections = list_of(string(SYMTAB_NAME))
337 (string(STRTAB_NAME));
339 // loaded_elf(): populate elf section pointers
340 // for EEL rewritten code, also populate "code_*_" members
341 bool Object::loaded_elf(Offset& txtaddr, Offset& dataddr,
342 Elf_X_Shdr* &bssscnp,
343 Elf_X_Shdr*& symscnp, Elf_X_Shdr*& strscnp,
344 Elf_X_Shdr*& stabscnp, Elf_X_Shdr*& stabstrscnp,
345 Elf_X_Shdr*& stabs_indxcnp, Elf_X_Shdr*& stabstrs_indxcnp,
346 Elf_X_Shdr*& rel_plt_scnp, Elf_X_Shdr*& plt_scnp,
347 Elf_X_Shdr*& got_scnp, Elf_X_Shdr*& dynsym_scnp,
348 Elf_X_Shdr*& dynstr_scnp, Elf_X_Shdr* &dynamic_scnp,
349 Elf_X_Shdr*& eh_frame, Elf_X_Shdr*& gcc_except,
350 Elf_X_Shdr *& interp_scnp, bool)
352 std::map<std::string, int> secnNameMap;
353 dwarf_err_func = err_func_;
354 entryAddress_ = elfHdr.e_entry();
356 no_of_sections_ = elfHdr.e_shnum();
358 // ".shstrtab" section: string table for section header names
359 const char *shnames = pdelf_get_shnames(elfHdr);
360 if (shnames == NULL) {
361 //fprintf(stderr, "[%s][%d]WARNING: .shstrtab section not found in ELF binary\n",__FILE__,__LINE__);
362 log_elferror(err_func_, ".shstrtab section");
366 // initialize Object members
368 text_addr_ = 0; //ccw 23 jan 2002
369 text_size_ = 0; //for determining if a mutation
370 //falls within the text section
371 //of a shared library
389 #if defined (ppc32_linux) || defined(ppc32_bgp)
391 rel_plt_entry_size_ = 8;
394 rel_plt_entry_size_ = 0;
406 stabstr_indx_off_ = 0;
408 MIPS_stubs_addr_ = 0;
410 MIPS_stubs_size_ = 0;
411 got_zero_index_ = -1;
412 dynsym_zero_index_ = -1;
414 dwarvenDebugInfo = false;
418 set<string> sectionsInOriginalBinary;
420 if(mfForDebugInfo->getFD() != -1)
421 elfHdrForDebugInfo = Elf_X(mfForDebugInfo->getFD(), ELF_C_READ);
423 elfHdrForDebugInfo = Elf_X((char *)mfForDebugInfo->base_addr(), mfForDebugInfo->size());
424 usesDebugFile = (mfForDebugInfo != mf);
426 if(!elfHdrForDebugInfo.isValid()) {
427 log_elferror(err_func_, "Elf header");
428 fprintf(stderr, "%s[%d]: failing to parse line info due to elf prob\n", FILE__, __LINE__);
430 else if(!pdelf_check_ehdr(elfHdrForDebugInfo)) {
431 fprintf(stderr, "%s[%d]: Warning: Elf ehdr failed integrity check\n", FILE__, __LINE__);
432 log_elferror(err_func_, "ELF header failed integrity check");
436 const char *shnamesForDebugInfo = pdelf_get_shnames(elfHdrForDebugInfo);
437 if (shnamesForDebugInfo == NULL) {
438 //fprintf(stderr, "[%s][%d]WARNING: .shstrtab section not found in ELF binary\n",__FILE__,__LINE__);
439 log_elferror(err_func_, ".shstrtab section");
443 #if defined(TIMED_PARSE)
444 struct timeval starttime;
445 gettimeofday(&starttime, NULL);
448 // Find pointer to dynamic section and interpreter section
449 bool foundInterp = false;
450 unsigned phdr_max_count = elfHdr.e_phnum();
452 for (unsigned i = 0; i < phdr_max_count; i++) {
453 Elf_X_Phdr elfPhdr = elfHdr.get_phdr(i);
454 if(elfPhdr.p_type() == PT_DYNAMIC){
455 dynamic_offset_ = elfPhdr.p_offset();
456 dynamic_size_ = elfPhdr.p_memsz();
457 } else if (elfPhdr.p_type() == PT_INTERP) {
462 if (elfHdr.e_type() == ET_DYN || foundInterp || elfHdr.e_type() == ET_REL) {
463 is_static_binary_ = false;
465 is_static_binary_ = true;
470 bool foundDynamicSection = false;
471 int dynamic_section_index = -1;
472 unsigned int dynamic_section_type = 0;
473 size_t dynamic_section_size = 0;
474 for (int i = 0; i < elfHdr.e_shnum();++i) {
475 scnp = new Elf_X_Shdr( elfHdr.get_shdr(i) );
476 if (! scnp->isValid()) { // section is malformed
480 if ((dynamic_offset_ !=0) && (scnp->sh_offset() == dynamic_offset_)) {
481 if (!foundDynamicSection) {
482 dynamic_section_index = i;
483 dynamic_section_size = scnp->sh_size();
484 dynamic_section_type = scnp->sh_type();
485 foundDynamicSection = true;
487 // If there are two or more sections with the same offset as the dynamic_offset,
488 // use other fields to chose which one the the dynamic section
489 if (dynamic_section_size == dynamic_size_ && dynamic_section_type == SHT_DYNAMIC) {
490 // We already have the right section
491 } else if ((scnp->sh_size() == dynamic_size_ && scnp->sh_type() == SHT_DYNAMIC) ||
492 (scnp->sh_size() == dynamic_size_)) {
493 // This section is a better match to be the dynamic section
494 // than the previous one!
495 dynamic_section_index = i;
496 dynamic_section_size = scnp->sh_size();
497 dynamic_section_type = scnp->sh_type();
504 if (dynamic_section_index != -1) {
505 scnp = new Elf_X_Shdr( elfHdr.get_shdr(dynamic_section_index) );
506 Elf_X_Data data = scnp->get_data();
507 Elf_X_Dyn dynsecData = data.get_dyn();
508 // Ubuntu 12.04 - we have debug files with NOBITS dynamic sections.
509 if (dynsecData.isValid()) {
510 for (unsigned j = 0; j < dynsecData.count(); ++j) {
511 switch (dynsecData.d_tag(j)) {
514 secAddrTagMapping[dynsecData.d_ptr(j)] = dynsecData.d_tag(j);
518 secAddrTagMapping[dynsecData.d_ptr(j)] = dynsecData.d_tag(j);
521 secAddrTagMapping[dynsecData.d_ptr(j)] = dynsecData.d_tag(j);
527 secAddrTagMapping[dynsecData.d_ptr(j)] = dynsecData.d_tag(j);
530 secAddrTagMapping[dynsecData.d_ptr(j)] = dynsecData.d_tag(j);
531 elf_hash_addr_ = dynsecData.d_ptr(j);
533 case 0x6ffffef5: //DT_GNU_HASH (not defined on all platforms)
534 secAddrTagMapping[dynsecData.d_ptr(j)] = dynsecData.d_tag(j);
535 gnu_hash_addr_ = dynsecData.d_ptr(j);
538 secAddrTagMapping[dynsecData.d_ptr(j)] = dynsecData.d_tag(j);
541 secTagSizeMapping[DT_REL] = dynsecData.d_val(j);
544 secTagSizeMapping[DT_RELA] = dynsecData.d_val(j);
547 secTagSizeMapping[DT_JMPREL] = dynsecData.d_val(j);
550 secTagSizeMapping[DT_STRTAB] = dynsecData.d_val(j);
553 if (dynsecData.d_val(j) == DT_REL)
555 else if (dynsecData.d_val(j) == DT_RELA)
562 dyn_hash_map<Offset, int>::iterator it = secAddrTagMapping.begin();
563 while (it != secAddrTagMapping.end()) {
564 int tag = it->second;
566 // Only sections with these tags are moved in the new rewritten binary
575 case 0x6ffffef5: // DT_GNU_HASH (not defined on all platforms)
577 if (secTagSizeMapping.find(tag) != secTagSizeMapping.end()) {
579 row.push_back(it->first);
580 row.push_back(it->first+ secTagSizeMapping[tag]);
581 moveSecAddrRange.push_back(row);
584 row.push_back(it->first);
585 row.push_back(it->first);
586 moveSecAddrRange.push_back(row);
595 isBlueGeneP_ = false;
596 isBlueGeneQ_ = false;
598 hasNoteSection_ = false;
600 for (int i = 0; i < elfHdr.e_shnum() + elfHdrForDebugInfo.e_shnum(); ++i) {
603 if(i < elfHdr.e_shnum()) {
604 scnp = new Elf_X_Shdr( elfHdr.get_shdr(i) );
605 if (! scnp->isValid()) { // section is malformed
609 name = &shnames[scnp->sh_name()];
610 sectionsInOriginalBinary.insert(string(name));
612 if(scnp->sh_flags() & SHF_ALLOC) {
613 DbgAddrConversion_t orig;
614 orig.name = std::string(name);
615 orig.orig_offset = scnp->sh_addr();
616 secnNameMap[orig.name] = DebugSectionMap.size();
617 DebugSectionMap.push_back(orig);
621 if(mfForDebugInfo == mf)
623 scnp = new Elf_X_Shdr(elfHdrForDebugInfo.get_shdr(i - elfHdr.e_shnum()));
624 if(! scnp->isValid()) {
628 name = &shnamesForDebugInfo[scnp->sh_name()];
630 std::string sname(name);
631 std::map<std::string, int>::iterator s = secnNameMap.find(sname);
632 if (s != secnNameMap.end()) {
634 DebugSectionMap[i].dbg_offset = scnp->sh_addr();
635 DebugSectionMap[i].dbg_size = scnp->sh_size();
637 scnp->setDebugFile(true);
639 if (scnp->sh_type() == SHT_NOBITS) {
645 if(scnp->sh_type() == SHT_NOTE) {
646 hasNoteSection_ = true;
650 //If the section appears in the memory image of a process address is given by
652 //otherwise this is zero and sh_offset() gives the offset to the first byte
654 if (!scnp->isFromDebugFile()) {
655 allRegionHdrs.push_back( scnp );
656 if(scnp->sh_flags() & SHF_ALLOC) {
657 // .bss, etc. have a disk size of 0
658 // unsigned long diskSize = (false) ? 0 : scnp->sh_size();
659 unsigned long diskSize = (scnp->sh_type() == SHT_NOBITS) ? 0 : scnp->sh_size();
660 Region *reg = new Region(i, name, scnp->sh_addr(), diskSize,
661 scnp->sh_addr(), scnp->sh_size(),
662 (mem_image()+scnp->sh_offset()),
663 getRegionPerms(scnp->sh_flags()),
664 getRegionType(scnp->sh_type(),
667 true, ((scnp->sh_flags() & SHF_TLS) != 0),
668 scnp->sh_addralign());
669 reg->setFileOffset(scnp->sh_offset());
670 regions_.push_back(reg);
673 Region *reg = new Region(i, name, scnp->sh_addr(), scnp->sh_size(), 0, 0,
674 (mem_image()+scnp->sh_offset()),
675 getRegionPerms(scnp->sh_flags()),
676 getRegionType(scnp->sh_type(),
679 false, ((scnp->sh_flags() & SHF_TLS) != 0),
680 scnp->sh_addralign());
682 reg->setFileOffset(scnp->sh_offset());
683 regions_.push_back(reg);
687 // section-specific processing
688 if (P_strcmp(name, EDITED_TEXT_NAME) == 0) {
689 // EEL rewritten executable
692 txtaddr = scnp->sh_addr();
693 char *file_ptr = (char *)mf->base_addr();
694 code_ptr_ = (char *)(void*)&file_ptr[scnp->sh_offset() - EXTRA_SPACE];
695 code_off_ = scnp->sh_addr() - EXTRA_SPACE;
696 code_len_ = scnp->sh_size() + EXTRA_SPACE;
699 if (strcmp(name, TEXT_NAME) == 0) {
700 text_addr_ = scnp->sh_addr();
701 text_size_ = scnp->sh_size();
704 txtaddr = scnp->sh_addr();
706 // .o's don't have program headers, so these members need
707 // to be populated here
708 if( !elfHdr.e_phnum() && !code_len_) {
709 // Populate code members
710 code_ptr_ = reinterpret_cast<char *>(scnp->get_data().d_buf());
711 code_off_ = scnp->sh_offset();
712 code_len_ = scnp->sh_size();
715 /* The following sections help us find the PH entry that
716 encompasses the data region. */
717 else if (strcmp(name, DATA_NAME) == 0) {
718 dataddr = scnp->sh_addr();
720 // .o's don't have program headers, so these members need
721 // to be populated here
722 if( !elfHdr.e_phnum() && !data_len_) {
723 // Populate data members
724 data_ptr_ = reinterpret_cast<char *>(scnp->get_data().d_buf());
725 data_off_ = scnp->sh_offset();
726 data_len_ = scnp->sh_size();
729 else if (strcmp(name, RO_DATA_NAME) == 0) {
730 if (!dataddr) dataddr = scnp->sh_addr();
732 else if (strcmp(name, GOT_NAME) == 0) {
734 got_addr_ = scnp->sh_addr();
735 got_size_ = scnp->sh_size();
736 if (!dataddr) dataddr = scnp->sh_addr();
738 else if (strcmp(name, BSS_NAME) == 0) {
740 if (!dataddr) dataddr = scnp->sh_addr();
742 /* End data region search */
743 /*else if (strcmp( name, FINI_NAME) == 0) {
744 fini_addr_ = scnp->sh_addr();
746 else if (strcmp(name, SYMTAB_NAME) == 0) {
749 symtab_addr_ = scnp->sh_addr();
752 else if (strcmp(name, STRTAB_NAME) == 0) {
755 strtab_addr_ = scnp->sh_addr();
757 } else if (strcmp(name, STAB_INDX_NAME) == 0) {
758 stabs_indxcnp = scnp;
759 stab_indx_off_ = scnp->sh_offset();
760 stab_indx_size_ = scnp->sh_size();
761 } else if (strcmp(name, STABSTR_INDX_NAME) == 0) {
762 stabstrs_indxcnp = scnp;
763 stabstr_indx_off_ = scnp->sh_offset();
764 } else if (strcmp(name, STAB_NAME) == 0) {
766 stab_off_ = scnp->sh_offset();
767 stab_size_ = scnp->sh_size();
768 } else if (strcmp(name, STABSTR_NAME) == 0) {
770 stabstr_off_ = scnp->sh_offset();
772 #if defined(os_vxworks)
773 else if ((strcmp(name, REL_PLT_NAME) == 0) ||
774 (strcmp(name, REL_PLT_NAME2) == 0)) {
776 rel_plt_addr_ = scnp->sh_addr();
777 rel_plt_size_ = scnp->sh_size();
778 rel_plt_entry_size_ = scnp->sh_entsize();
781 else if ((secAddrTagMapping.find(scnp->sh_addr()) != secAddrTagMapping.end() ) &&
782 secAddrTagMapping[scnp->sh_addr()] == DT_JMPREL ) {
784 rel_plt_addr_ = scnp->sh_addr();
785 rel_plt_size_ = scnp->sh_size();
786 rel_plt_entry_size_ = scnp->sh_entsize();
789 else if (strcmp(name, PLT_NAME) == 0) {
791 plt_addr_ = scnp->sh_addr();
792 plt_size_ = scnp->sh_size();
793 #if defined(arch_x86) || defined(arch_x86_64)
795 // On x86, the GNU linker purposefully sets the PLT
796 // table entry size to an incorrect value to be
797 // compatible with the UnixWare linker. (See the comment
798 // in the elf_i386_finish_dynamic_sections function of
799 // the BFD library.) The GNU linker sets this value to 4,
800 // when it should be 16.
802 // I see no good way to determine this value from the
803 // ELF section header information. We can either (a) hard-code
804 // the value that is used in the BFD library, or (b) compute
805 // it by dividing the size of the PLT by the number of entries
806 // we think should be in the PLT. I'm not certain, but I
807 // believe the PLT and the .rel.plt section should have the
808 // same number of "real" entries (the x86 PLT has one extra entry
809 // at the beginning).
811 // This code is applicable to any x86 system that uses the
812 // GNU linker. We currently only support Linux on x86 - if
813 // we start supporting some other x86 OS that uses the GNU
814 // linker in the future, it should be enabled for that platform as well.
815 // Note that this problem does not affect the non-x86 platforms
816 // that might use the GNU linker. For example, programs linked
817 // with gld on SPARC Solaris have the correct PLT entry size.
819 // Another potential headache in the future is if we support
820 // some other x86 platform that has both the GNU linker and
821 // some other linker. (Does BSD fall into this category?)
822 // If the two linkers set the entry size differently, we may
823 // need to re-evaluate this code.
825 //plt_entry_size_ = plt_size_ / ((rel_plt_size_ / rel_plt_entry_size_) + 1);
826 plt_entry_size_ = 16;
827 assert( plt_entry_size_ == 16 );
829 plt_entry_size_ = scnp->sh_entsize();
831 // X86-64: if we're on a 32-bit binary then set the PLT entry size to 16
833 #if defined(arch_x86_64)
834 if (addressWidth_nbytes == 4) {
835 plt_entry_size_ = 16;
836 assert( plt_entry_size_ == 16 );
839 assert(addressWidth_nbytes == 8);
844 #if defined (ppc32_linux) || defined(ppc32_bgp)
845 if (scnp->sh_flags() & SHF_EXECINSTR) {
846 // Old style executable PLT
847 if (!plt_entry_size_)
850 if (plt_entry_size_ != 8)
851 fprintf(stderr, "%s[%d]: weird plt_entry_size_ is %d, not 8\n",
852 FILE__, __LINE__, plt_entry_size_);
856 // New style secure PLT
857 plt_entry_size_ = 16;
861 } else if (strcmp(name, COMMENT_NAME) == 0) {
862 /* comment section is a sequence of NULL-terminated strings.
863 We want to concatenate them and search for BGP to determine
864 if the binary is built for BGP compute nodes */
866 Elf_X_Data data = scnp->get_data();
868 unsigned int index = 0;
869 size_t size = data.d_size();
870 char *buf = (char *) data.d_buf();
871 while (buf && (index < size))
873 string comment = buf+index;
874 size_t pos_p = comment.find("BGP");
875 size_t pos_q = comment.find("BGQ");
876 if (pos_p !=string::npos) {
879 } else if (pos_q !=string::npos) {
883 index += comment.size();
884 if (comment.size() == 0) { // Skip NULL characters in the comment section
890 else if ((secAddrTagMapping.find(scnp->sh_addr()) != secAddrTagMapping.end() ) &&
891 secAddrTagMapping[scnp->sh_addr()] == DT_SYMTAB ) {
894 dynsym_addr_ = scnp->sh_addr();
895 dynsym_size_ = scnp->sh_size()/scnp->sh_entsize();
897 else if ((secAddrTagMapping.find(scnp->sh_addr()) != secAddrTagMapping.end() ) &&
898 secAddrTagMapping[scnp->sh_addr()] == DT_STRTAB ) {
900 dynstr_addr_ = scnp->sh_addr();
902 else if (strcmp(name, ".debug_info") == 0) {
903 dwarvenDebugInfo = true;
905 else if (strcmp(name, EH_FRAME_NAME) == 0) {
908 else if ((strcmp(name, EXCEPT_NAME) == 0) ||
909 (strcmp(name, EXCEPT_NAME_ALT) == 0)) {
912 else if (strcmp(name, INTERP_NAME) == 0) {
915 else if (i == dynamic_section_index) {
917 dynamic_addr_ = scnp->sh_addr();
921 if(!symscnp || !strscnp) {
923 if(dynsym_scnp && dynstr_scnp){
924 symscnp = dynsym_scnp;
925 strscnp = dynstr_scnp;
930 #if defined(os_linux) || defined(os_freebsd)
932 * If the virtual address of the first PT_LOAD element in the
933 * program table is 0, Linux loads the shared object into any
934 * free spot into the address space. If the virtual address is
935 * non-zero, it gets loaded only at that address.
937 for (unsigned i = 0; i < elfHdr.e_phnum() && !loadAddress_; ++i) {
938 Elf_X_Phdr phdr = elfHdr.get_phdr(i);
940 if (phdr.p_type() == PT_LOAD) {
941 loadAddress_ = phdr.p_vaddr();
947 // save a copy of region headers, maintaining order in section header table
948 allRegionHdrsByShndx = allRegionHdrs;
950 // sort the section headers by base address
951 sort(allRegionHdrs.begin(), allRegionHdrs.end(), SectionHeaderSortFunction());
953 for (unsigned j = 0 ; j < regions_.size() ; j++) {
954 if (secAddrTagMapping.find(regions_[j]->getDiskOffset()) != secAddrTagMapping.end()) {
955 secTagRegionMapping[secAddrTagMapping[regions_[j]->getDiskOffset()]] = regions_[j];
959 #if defined(TIMED_PARSE)
960 struct timeval endtime;
961 gettimeofday(&endtime, NULL);
962 unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
963 unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
964 unsigned long difftime = lendtime - lstarttime;
965 double dursecs = difftime/(1000 );
966 cout << "main loop of loaded elf took "<<dursecs <<" msecs" << endl;
969 if (!dataddr || !symscnp || !strscnp) {
970 //log_elferror(err_func_, "no text/bss/symbol/string section");
972 //if (addressWidth_nbytes == 8) bperr( ">>> 64-bit loaded_elf() successful\n");
976 bool Object::is_offset_in_plt(Offset offset) const
978 return (offset > plt_addr_ && offset < plt_addr_ + plt_size_);
981 void Object::parseDynamic(Elf_X_Shdr *&dyn_scnp, Elf_X_Shdr *&dynsym_scnp,
982 Elf_X_Shdr *&dynstr_scnp)
984 Elf_X_Data data = dyn_scnp->get_data();
985 Elf_X_Dyn dyns = data.get_dyn();
986 int rel_scnp_index = -1;
988 for (unsigned i = 0; i < dyns.count(); ++i) {
989 switch(dyns.d_tag(i)) {
992 /*found Relocation section*/
993 rel_addr_ = (Offset) dyns.d_ptr(i);
994 rel_scnp_index = getRegionHdrIndexByAddr(dyns.d_ptr(i));
997 rel_plt_addr_ = (Offset) dyns.d_ptr(i);
1000 rel_plt_size_ = dyns.d_val(i) ;
1004 rel_size_ = dyns.d_val(i) ;
1008 rel_entry_size_ = dyns.d_val(i);
1010 //rel_plt_entry_size_ = dyns.d_val(i);
1013 init_addr_ = dyns.d_val(i);
1016 fini_addr_ = dyns.d_val(i);
1022 if (rel_scnp_index != -1)
1023 get_relocationDyn_entries(rel_scnp_index, dynsym_scnp, dynstr_scnp);
1026 /* parse relocations for the sections represented by DT_REL/DT_RELA in
1027 * the dynamic section. This section is the one we would want to emit
1029 bool Object::get_relocationDyn_entries( unsigned rel_scnp_index,
1030 Elf_X_Shdr *&dynsym_scnp,
1031 Elf_X_Shdr *&dynstr_scnp )
1033 Elf_X_Data symdata = dynsym_scnp->get_data();
1034 Elf_X_Data strdata = dynstr_scnp->get_data();
1035 Elf_X_Shdr* rel_scnp = NULL;
1036 if( !symdata.isValid() || !strdata.isValid())
1038 const char *strs = strdata.get_string();
1039 Elf_X_Sym sym = symdata.get_sym();
1041 unsigned num_rel_entries_found = 0;
1042 unsigned num_rel_entries = rel_size_/rel_entry_size_;
1044 if (rel_addr_ + rel_size_ > rel_plt_addr_){
1045 // REL/RELA section overlaps with REL PLT section
1046 num_rel_entries = (rel_plt_addr_-rel_addr_)/rel_entry_size_;
1048 while (num_rel_entries_found != num_rel_entries) {
1049 rel_scnp = getRegionHdrByIndex(rel_scnp_index++);
1050 Elf_X_Data reldata = rel_scnp->get_data();
1052 if( ! reldata.isValid()) return false;
1053 Elf_X_Rel rel = reldata.get_rel();
1054 Elf_X_Rela rela = reldata.get_rela();
1056 if (sym.isValid() && (rel.isValid() || rela.isValid()) && strs) {
1057 /* Iterate over the entries. */
1058 for( u_int i = 0; i < (reldata.d_size()/rel_entry_size_); ++i ) {
1059 num_rel_entries_found++;
1064 Region::RegionType rtype = Region::RT_REL;
1066 switch (reldata.d_type()) {
1068 offset = rel.r_offset(i);
1070 index = rel.R_SYM(i);
1071 type = rel.R_TYPE(i);
1075 offset = rela.r_offset(i);
1076 addend = rela.r_addend(i);
1077 index = rela.R_SYM(i);
1078 type = rela.R_TYPE(i);
1079 rtype = Region::RT_RELA;
1083 // We should never reach this case.
1086 // /* DEBUG */ fprintf( stderr, "%s: relocation information for target 0x%lx\n", __FUNCTION__, next_plt_entry_addr );
1087 relocationEntry re( offset, string( &strs[ sym.st_name(index) ] ), NULL, type );
1088 re.setAddend(addend);
1089 re.setRegionType(rtype);
1090 if(symbols_.find(&strs[ sym.st_name(index)]) != symbols_.end()){
1091 vector<Symbol *> &syms = symbols_[&strs[ sym.st_name(index)]];
1092 for (vector<Symbol *>::iterator i = syms.begin(); i != syms.end(); i++) {
1093 if (!(*i)->isInDynSymtab())
1100 relocation_table_.push_back(re);
1110 bool Object::get_relocation_entries( Elf_X_Shdr *&rel_plt_scnp,
1111 Elf_X_Shdr *&dynsym_scnp,
1112 Elf_X_Shdr *&dynstr_scnp )
1114 if (rel_plt_size_ && rel_plt_addr_) {
1115 Elf_X_Data reldata = rel_plt_scnp->get_data();
1116 Elf_X_Data symdata = dynsym_scnp->get_data();
1117 Elf_X_Data strdata = dynstr_scnp->get_data();
1119 if( reldata.isValid() && symdata.isValid() && strdata.isValid() ) {
1120 Offset next_plt_entry_addr = plt_addr_;
1122 #if defined(arch_x86) || defined(arch_x86_64)
1123 next_plt_entry_addr += plt_entry_size_; // 1st PLT entry is special
1125 #elif defined (ppc32_linux) || defined(ppc32_bgp)
1126 bool extraStubs = false;
1129 if (!plt_entry_size_) {
1130 fprintf(stderr, "%s[%d]: FIXME: plt_entry_size not established\n", FILE__, __LINE__);
1131 plt_entry_size_ = 8;
1134 if (plt_entry_size_ == 8) {
1135 // Old style executable PLT section
1136 next_plt_entry_addr += 9*plt_entry_size_; // 1st 9 PLT entries are special
1138 } else if (plt_entry_size_ == 16) {
1139 // New style secure PLT
1140 Region *plt = NULL, *relplt = NULL, *dynamic = NULL,
1141 *got = NULL, *glink = NULL;
1142 unsigned int glink_addr = 0;
1143 unsigned int stub_addr = 0;
1145 // Find the GLINK section. See ppc_elf_get_synthetic_symtab() in
1146 // bfd/elf32-ppc.c of GNU's binutils for more information.
1148 for (unsigned iter = 0; iter < regions_.size(); ++iter) {
1149 std::string name = regions_[iter]->getRegionName();
1150 if (name == PLT_NAME) plt = regions_[iter];
1151 else if (name == REL_PLT_NAME) relplt = regions_[iter];
1152 else if (name == DYNAMIC_NAME) dynamic = regions_[iter];
1153 else if (name == GOT_NAME) got = regions_[iter];
1156 // Rely on .dynamic section for prelinked binaries.
1157 if (dynamic != NULL) {
1158 Elf32_Dyn *dyn = (Elf32_Dyn *)dynamic->getPtrToRawData();
1159 unsigned int count = dynamic->getMemSize() / sizeof(Elf32_Dyn);
1161 for (unsigned int i = 0; i < count; ++i) {
1162 // Use DT_LOPROC instead of DT_PPC_GOT to circumvent problems
1163 // caused by early versions of libelf where DT_PPC_GOT has
1164 // yet to be defined.
1165 if (dyn[i].d_tag == DT_LOPROC) {
1166 unsigned int g_o_t = dyn[i].d_un.d_val;
1168 unsigned char *data =
1169 (unsigned char *)got->getPtrToRawData();
1170 glink_addr = *(unsigned int *)
1171 (data + (g_o_t - got->getMemOffset() + 4));
1178 // Otherwise, first entry in .plt section holds the glink address
1179 if (glink_addr == 0) {
1180 unsigned char *data = (unsigned char *)plt->getPtrToRawData();
1181 glink_addr = *(unsigned int *)(data);
1184 // Search for region that contains glink address
1185 for (unsigned iter = 0; iter < regions_.size(); ++iter) {
1186 unsigned int start = regions_[iter]->getMemOffset();
1187 unsigned int end = start + regions_[iter]->getMemSize();
1188 if (start <= glink_addr && glink_addr < end) {
1189 glink = regions_[iter];
1195 // fprintf(stderr, "*** Cound not find .glink section for '%s'.\n",
1196 // mf->pathname().c_str());
1197 // fprintf(stderr, "*** It may not be a ppc32 elf object.\n");
1201 // Find PLT function stubs. They preceed the glink section.
1202 stub_addr = glink_addr - (rel_plt_size_/rel_plt_entry_size_) * 16;
1204 const unsigned int LWZ_11_30 = 0x817e0000;
1205 const unsigned int ADDIS_11_30 = 0x3d7e0000;
1206 const unsigned int LWZ_11_11 = 0x816b0000;
1207 const unsigned int MTCTR_11 = 0x7d6903a6;
1208 const unsigned int BCTR = 0x4e800420;
1210 unsigned char *sec_data = (unsigned char *)glink->getPtrToRawData();
1211 unsigned int *insn = (unsigned int *)
1212 (sec_data + (stub_addr - glink->getMemOffset()));
1214 // Keep moving pointer back if more -fPIC stubs are found.
1215 while (sec_data < (unsigned char *)insn) {
1216 unsigned int *back = insn - 4;
1218 if (( (back[0] & 0xffff0000) == LWZ_11_30
1219 && back[1] == MTCTR_11
1222 || ( (back[0] & 0xffff0000) == ADDIS_11_30
1223 && (back[1] & 0xffff0000) == LWZ_11_11
1224 && back[2] == MTCTR_11
1225 && back[3] == BCTR))
1235 // Okay, this is where things get hairy. If we have a one to one
1236 // relationship between the glink stubs and plt entries (meaning
1237 // extraStubs == false), then we can generate our relocationEntry
1238 // objects normally below.
1240 // However, if we have extra glink stubs, then we must generate
1241 // relocations with unknown destinations for *all* stubs. Then,
1242 // we use the loop below to store additional information about
1243 // the data plt entry keyed by plt entry address.
1245 // Finally, if a symbol with any of the following forms:
1246 // [hex_addr].got2.plt_pic32.[sym_name]
1247 // [hex_addr].plt_pic32.[sym_name]
1249 // matches the glink stub address, then stub symbols exist and we
1250 // can rely on these tell us where the stub will eventually go.
1252 if (extraStubs == true) {
1256 while (stub_addr < glink_addr) {
1257 if (symsByOffset_.find(stub_addr) != symsByOffset_.end()) {
1258 name = (symsByOffset_[stub_addr])[0]->getMangledName();
1259 name = name.substr( name.rfind("plt_pic32.") + 10 );
1262 if (!name.empty()) {
1263 re = relocationEntry( stub_addr, 0, name, NULL, 0 );
1265 re = relocationEntry( stub_addr, 0, "@plt", NULL, 0 );
1271 // Now prepare to iterate over plt below.
1272 next_plt_entry_addr = plt_addr_;
1273 plt_entry_size_ = 4;
1276 next_plt_entry_addr = stub_addr;
1280 fprintf(stderr, "ERROR: Can't handle %d PLT entry size\n",
1285 //fprintf(stderr, "%s[%d]: skipping %d (6*%d) bytes initial plt\n",
1286 // FILE__, __LINE__, 9*plt_entry_size_, plt_entry_size_);
1287 // actually this is just fudged to make the offset value 72, which is what binutils uses
1288 // Note that binutils makes the distinction between PLT_SLOT_SIZE (8),
1289 // and PLT_ENTRY_SIZE (12). PLT_SLOT_SIZE seems to be what we want, even though we also
1290 // have PLT_INITIAL_ENTRY_SIZE (72)
1291 // see binutils/bfd/elf32-ppc.c/h if more info is needed
1292 //next_plt_entry_addr += 72; // 1st 6 PLT entries art special
1294 #elif defined(arch_power) && defined(arch_64bit) && defined(os_linux)
1295 // Unlike PPC32 Linux, we don't have a deterministic way of finding
1296 // PPC64 Linux linker stubs. So, we'll wait until the CFG is built
1297 // inside Dyninst, and code read at that point. To find them at this
1298 // point would require a scan of the entire .text section.
1300 // If we're lucky, symbols may exist for these linker stubs. They will
1301 // come in the following forms:
1302 // [hex_addr].plt_call.[sym_name]
1303 // [hex_addr].plt_branch.[sym_name]
1304 // [hex_addr].long_branch.[sym_name]
1305 // [hex_addr].plt_branch_r2off.[sym_name]
1306 // [hex_addr].long_branch_r2off.[sym_name]
1308 // Again unlike PPC32 above, we have no glink stub address to compare
1309 // against, so we must search through all symbols to find these names.
1312 // First, build a map of the .rela.plt symbol name -> .rela.plt offset:
1313 dyn_hash_map<std::string, Offset> plt_rel_map;
1315 // I'm not a fan of code duplication, but merging this into the
1316 // loop below would be ugly and difficult to maintain.
1317 Elf_X_Sym _sym = symdata.get_sym();
1318 Elf_X_Rel _rel = reldata.get_rel();
1319 Elf_X_Rela _rela = reldata.get_rela();
1320 const char *_strs = strdata.get_string();
1322 for( u_int i = 0; i < (rel_plt_size_/rel_plt_entry_size_); ++i ) {
1326 switch (reldata.d_type()) {
1328 _offset = _rel.r_offset(i);
1329 _index = _rel.R_SYM(i);
1333 _offset = _rela.r_offset(i);
1334 _index = _rela.R_SYM(i);
1338 // We should never reach this case.
1342 std::string _name = &_strs[ _sym.st_name(_index) ];
1343 // I'm interested to see if this assert will ever fail.
1344 assert(_name.length());
1346 plt_rel_map[_name] = _offset;
1348 // End code duplication.
1350 dyn_hash_map<std::string, std::vector<Symbol *> >::iterator iter;
1351 for (iter = symbols_.begin(); iter != symbols_.end(); ++iter) {
1352 std::string name = iter->first;
1353 if (name.length() > 8) {
1354 if (name.substr(8, 10) == ".plt_call.")
1355 name = name.substr(8 + 10);
1356 else if (name.substr(8, 12) == ".plt_branch.")
1357 name = name.substr(8 + 12);
1358 else if (name.substr(8, 13) == ".long_branch.")
1359 name = name.substr(8 + 13);
1360 else if (name.substr(8, 18) == ".plt_branch_r2off.")
1361 name = name.substr(8 + 18);
1362 else if (name.substr(8, 19) == ".long_branch_r2off.")
1363 name = name.substr(8 + 19);
1367 // Remove possible trailing addend value.
1368 std::string::size_type pos = name.rfind('+');
1369 if (pos != std::string::npos) name.erase(pos);
1371 // Remove possible version number.
1372 pos = name.find('@');
1373 if (pos != std::string::npos) name.erase(pos);
1375 // Find the dynamic symbol this linker stub branches to.
1376 Symbol *targ_sym = NULL;
1377 if (symbols_.find(name) != symbols_.end())
1378 for (unsigned i = 0; i < symbols_[name].size(); ++i)
1379 if ( (symbols_[name])[i]->isInDynSymtab())
1380 targ_sym = (symbols_[name])[i];
1382 // If a corresponding target symbol cannot be found for a
1383 // named linker stub, then ignore it. We'll find it during
1385 if (!targ_sym) continue;
1387 // I'm interested to see if these asserts will ever fail.
1388 assert(iter->second.size() == 1);
1389 assert(plt_rel_map.count(name) == 1);
1391 Symbol *stub_sym = iter->second[0];
1392 relocationEntry re(stub_sym->getOffset(),
1400 // 1st plt entry is special.
1401 next_plt_entry_addr += plt_entry_size_;
1404 next_plt_entry_addr += 4*(plt_entry_size_); //1st 4 entries are special
1407 Elf_X_Sym sym = symdata.get_sym();
1408 Elf_X_Rel rel = reldata.get_rel();
1409 Elf_X_Rela rela = reldata.get_rela();
1410 const char *strs = strdata.get_string();
1412 if (sym.isValid() && (rel.isValid() || rela.isValid()) && strs) {
1414 // Sometimes, PPC32 Linux may use this loop to update fbt entries.
1415 // Should stay -1 for all other platforms. See notes above.
1417 if (fbt_.size() > 0 && !fbt_[0].rel_addr() && fbt_[0].name() != "@plt")
1420 for( u_int i = 0; i < (rel_plt_size_/rel_plt_entry_size_); ++i ) {
1425 Region::RegionType rtype;
1427 switch (reldata.d_type()) {
1429 offset = rel.r_offset(i);
1431 index = rel.R_SYM(i);
1432 type = rel.R_TYPE(i);
1433 rtype = Region::RT_REL;
1437 offset = rela.r_offset(i);
1438 addend = rela.r_addend(i);
1439 index = rela.R_SYM(i);
1440 type = rela.R_TYPE(i);
1441 rtype = Region::RT_RELA;
1445 // We should never reach this case.
1449 std::string targ_name = &strs[ sym.st_name(index) ];
1450 vector<Symbol *> dynsym_list;
1451 if (symbols_.find(targ_name) != symbols_.end())
1453 vector<Symbol *> &syms = symbols_[&strs[ sym.st_name(index)]];
1454 for (vector<Symbol *>::iterator i = syms.begin(); i != syms.end(); i++) {
1455 if (!(*i)->isInDynSymtab())
1457 dynsym_list.push_back(*i);
1461 dynsym_list.clear();
1464 #if defined(os_vxworks)
1465 // VxWorks Kernel Images don't use PLT's, but we'll use the fbt to
1466 // note all function call relocations, and we'll fix these up later
1467 // in Symtab::fixup_RegionAddr()
1468 next_plt_entry_addr = sym.st_value(index);
1471 if (fbt_iter == -1) { // Create new relocation entry.
1472 relocationEntry re( next_plt_entry_addr, offset, targ_name,
1474 re.setAddend(addend);
1475 re.setRegionType(rtype);
1476 if (dynsym_list.size() > 0)
1477 re.addDynSym(dynsym_list[0]);
1480 } else { // Update existing relocation entry.
1481 while ((unsigned)fbt_iter < fbt_.size() &&
1482 fbt_[fbt_iter].name() == targ_name) {
1484 fbt_[fbt_iter].setRelAddr(offset);
1485 fbt_[fbt_iter].setAddend(addend);
1486 fbt_[fbt_iter].setRegionType(rtype);
1487 if (dynsym_list.size() > 0)
1488 fbt_[fbt_iter].addDynSym(dynsym_list[0]);
1494 #if defined(os_vxworks)
1495 // Nothing to increment here.
1497 next_plt_entry_addr += plt_entry_size_;
1507 void Object::load_object(bool alloc_syms)
1509 Elf_X_Shdr *bssscnp = 0;
1510 Elf_X_Shdr *symscnp = 0;
1511 Elf_X_Shdr *strscnp = 0;
1512 Elf_X_Shdr *stabscnp = 0;
1513 Elf_X_Shdr *stabstrscnp = 0;
1514 Elf_X_Shdr *stabs_indxcnp = 0;
1515 Elf_X_Shdr *stabstrs_indxcnp = 0;
1518 Elf_X_Shdr *rel_plt_scnp = 0;
1519 Elf_X_Shdr *plt_scnp = 0;
1520 Elf_X_Shdr *got_scnp = 0;
1521 Elf_X_Shdr *dynsym_scnp = 0;
1522 Elf_X_Shdr *dynstr_scnp = 0;
1523 Elf_X_Shdr *dynamic_scnp = 0;
1524 Elf_X_Shdr *eh_frame_scnp = 0;
1525 Elf_X_Shdr *gcc_except = 0;
1526 Elf_X_Shdr *interp_scnp = 0;
1528 { // binding contour (for "goto cleanup")
1530 // initialize object (for failure detection)
1538 // initialize "valid" regions of code and data segments
1539 code_vldS_ = (Offset) -1;
1541 data_vldS_ = (Offset) -1;
1544 // And attempt to parse the ELF data structures in the file....
1545 // EEL, added one more parameter
1547 if (!loaded_elf(txtaddr, dataddr, bssscnp, symscnp, strscnp,
1548 stabscnp, stabstrscnp, stabs_indxcnp, stabstrs_indxcnp,
1549 rel_plt_scnp, plt_scnp, got_scnp, dynsym_scnp, dynstr_scnp,
1550 dynamic_scnp, eh_frame_scnp,gcc_except, interp_scnp, true))
1555 addressWidth_nbytes = elfHdr.wordSize();
1557 // find code and data segments....
1558 find_code_and_data(elfHdr, txtaddr, dataddr);
1560 if (elfHdr.e_type() != ET_REL)
1562 if (!code_ptr_ || !code_len_)
1564 //bpfatal( "no text segment\n");
1568 if (!data_ptr_ || !data_len_)
1570 //bpfatal( "no data segment\n");
1574 get_valid_memory_areas(elfHdr);
1576 //fprintf(stderr, "[%s:%u] - Exe Name\n", __FILE__, __LINE__);
1578 #if (defined(os_linux) || defined(os_freebsd)) && (defined(arch_x86) || defined(arch_x86_64))
1579 if (eh_frame_scnp != 0 && gcc_except != 0)
1581 find_catch_blocks(eh_frame_scnp, gcc_except,
1582 txtaddr, dataddr, catch_addrs_);
1586 interpreter_name_ = (char *) interp_scnp->get_data().d_buf();
1588 // global symbols are put in global_symbols. Later we read the
1589 // stab section to find the module to where they belong.
1590 // Experiment : lets try to be a bit more intelligent about
1591 // how we initially size the global_symbols table.
1592 // dictionary_lite takes an initial # of bins (2nd param),
1593 // a max bin load (3rd param), and a grow factor (4th param).
1594 // Leaving aside the grow factor, lets allocate an initial #
1595 // of bins = nsyms / max bin load.
1597 #if defined(TIMED_PARSE)
1598 struct timeval starttime;
1599 gettimeofday(&starttime, NULL);
1603 // find symbol and string data
1604 #if defined(os_vxworks)
1605 // Avoid assigning symbols to DEFAULT_MODULE on VxWorks
1606 string module = mf->pathname();
1608 string module = "DEFAULT_MODULE";
1610 string name = "DEFAULT_NAME";
1611 Elf_X_Data symdata, strdata;
1613 if (symscnp && strscnp)
1615 symdata = symscnp->get_data();
1616 strdata = strscnp->get_data();
1617 parse_symbols(symdata, strdata, bssscnp, symscnp, false, module);
1620 no_of_symbols_ = nsymbols();
1622 // try to resolve the module names of global symbols
1623 // Sun compiler stab.index section
1624 fix_global_symbol_modules_static_stab(stabs_indxcnp, stabstrs_indxcnp);
1626 // STABS format (.stab section)
1627 fix_global_symbol_modules_static_stab(stabscnp, stabstrscnp);
1629 // DWARF format (.debug_info section)
1630 fix_global_symbol_modules_static_dwarf();
1632 if (dynamic_addr_ && dynsym_scnp && dynstr_scnp)
1634 symdata = dynsym_scnp->get_data();
1635 strdata = dynstr_scnp->get_data();
1636 parse_dynamicSymbols(dynamic_scnp, symdata, strdata, false, module);
1640 //Have a hash on the symbol table. Iterate over dynamic symbol table to check if it exists
1641 //If yes set dynamic for the symbol ( How to distinguish between symbols only in symtab,
1642 // symbols only in dynsymtab & symbols present in both).
1643 // Else add dynamic symbol to dictionary
1644 // (or) Have two sepearate dictionaries. Makes life easy!
1645 // Think about it today!!
1647 //allsymbols = merge(allsymbols, alldynSymbols);
1649 #if defined(TIMED_PARSE)
1650 struct timeval endtime;
1651 gettimeofday(&endtime, NULL);
1652 unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
1653 unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
1654 unsigned long difftime = lendtime - lstarttime;
1655 double dursecs = difftime/(1000);
1656 cout << "parsing/fixing/overriding elf took "<<dursecs <<" msecs" << endl;
1659 if (dynamic_addr_ && dynsym_scnp && dynstr_scnp)
1661 parseDynamic(dynamic_scnp, dynsym_scnp, dynstr_scnp);
1664 #if defined(os_vxworks)
1665 // Load relocations like they are PLT entries.
1666 // Use the non-dynamic symbol tables.
1667 if (rel_plt_scnp && symscnp && strscnp) {
1668 if (!get_relocation_entries(rel_plt_scnp, symscnp, strscnp))
1674 if (rel_plt_scnp && dynsym_scnp && dynstr_scnp)
1676 if (!get_relocation_entries(rel_plt_scnp,dynsym_scnp,dynstr_scnp))
1681 parse_all_relocations(elfHdr, dynsym_scnp, dynstr_scnp,
1684 handle_opd_relocations();
1688 int e_type = elfHdr.e_type();
1690 if (e_type == ET_DYN) {
1691 obj_type_ = obj_SharedLib;
1692 }else if (e_type == ET_EXEC) {
1693 obj_type_ = obj_Executable;
1694 }else if (e_type == ET_REL) {
1695 obj_type_ = obj_RelocatableFile;
1698 // Set rel type based on the ELF machine type
1699 relType_ = getRelTypeByElfMachine(&elfHdr);
1702 } // end binding contour (for "goto cleanup2")
1706 /* NOTE: The file should NOT be munmap()ed. The mapped file is
1707 used for function parsing (see dyninstAPI/src/symtab.C) */
1709 fprintf(stderr, "%s[%d]: failed to load elf object\n", FILE__, __LINE__);
1713 void Object::load_shared_object(bool alloc_syms)
1715 Elf_X_Shdr *bssscnp = 0;
1716 Elf_X_Shdr *symscnp = 0;
1717 Elf_X_Shdr *strscnp = 0;
1718 Elf_X_Shdr *stabscnp = 0;
1719 Elf_X_Shdr *stabstrscnp = 0;
1720 Elf_X_Shdr *stabs_indxcnp = 0;
1721 Elf_X_Shdr *stabstrs_indxcnp = 0;
1724 Elf_X_Shdr *rel_plt_scnp = 0;
1725 Elf_X_Shdr *plt_scnp = 0;
1726 Elf_X_Shdr *got_scnp = 0;
1727 Elf_X_Shdr *dynsym_scnp = 0;
1728 Elf_X_Shdr *dynstr_scnp = 0;
1729 Elf_X_Shdr *dynamic_scnp = 0;
1730 Elf_X_Shdr *eh_frame_scnp = 0;
1731 Elf_X_Shdr *gcc_except = 0;
1732 Elf_X_Shdr *interp_scnp = 0;
1734 { // binding contour (for "goto cleanup2")
1736 // initialize "valid" regions of code and data segments
1737 code_vldS_ = (Offset) -1;
1739 data_vldS_ = (Offset) -1;
1742 if (!loaded_elf(txtaddr, dataddr, bssscnp, symscnp, strscnp,
1743 stabscnp, stabstrscnp, stabs_indxcnp, stabstrs_indxcnp,
1744 rel_plt_scnp, plt_scnp, got_scnp, dynsym_scnp, dynstr_scnp,
1745 dynamic_scnp, eh_frame_scnp, gcc_except, interp_scnp))
1749 interpreter_name_ = (char *) interp_scnp->get_data().d_buf();
1751 addressWidth_nbytes = elfHdr.wordSize();
1753 // find code and data segments....
1754 find_code_and_data(elfHdr, txtaddr, dataddr);
1756 get_valid_memory_areas(elfHdr);
1758 #if (defined(os_linux) || defined(os_freebsd)) && (defined(arch_x86) || defined(arch_x86_64))
1759 //fprintf(stderr, "[%s:%u] - Mod Name is %s\n", __FILE__, __LINE__, name.c_str());
1760 if (eh_frame_scnp != 0 && gcc_except != 0) {
1761 find_catch_blocks(eh_frame_scnp, gcc_except,
1762 txtaddr, dataddr, catch_addrs_);
1765 #if defined(TIMED_PARSE)
1766 struct timeval starttime;
1767 gettimeofday(&starttime, NULL);
1771 // build symbol dictionary
1772 string module = mf->pathname();
1773 string name = "DEFAULT_NAME";
1775 Elf_X_Data symdata, strdata;
1776 if (symscnp && strscnp)
1778 symdata = symscnp->get_data();
1779 strdata = strscnp->get_data();
1780 if (!symdata.isValid() || !strdata.isValid()) {
1781 log_elferror(err_func_, "locating symbol/string data");
1784 bool result = parse_symbols(symdata, strdata, bssscnp, symscnp, false, module);
1786 log_elferror(err_func_, "locating symbol/string data");
1791 no_of_symbols_ = nsymbols();
1793 if (dynamic_addr_ && dynsym_scnp && dynstr_scnp)
1795 symdata = dynsym_scnp->get_data();
1796 strdata = dynstr_scnp->get_data();
1797 parse_dynamicSymbols(dynamic_scnp, symdata, strdata, false, module);
1800 #if defined(TIMED_PARSE)
1801 struct timeval endtime;
1802 gettimeofday(&endtime, NULL);
1803 unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
1804 unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
1805 unsigned long difftime = lendtime - lstarttime;
1806 double dursecs = difftime/(1000 * 1000);
1807 cout << "*INSERT SYMBOLS* elf took "<<dursecs <<" msecs" << endl;
1808 //cout << "parsing/fixing/overriding/insertion elf took "<<dursecs <<" msecs" << endl;
1810 if(dynamic_addr_ && dynsym_scnp && dynstr_scnp) {
1811 parseDynamic(dynamic_scnp, dynsym_scnp, dynstr_scnp);
1814 #if defined(os_vxworks)
1815 // Load relocations like they are PLT entries.
1816 // Use the non-dynamic symbol tables.
1817 if (rel_plt_scnp && symscnp && strscnp) {
1818 if (!get_relocation_entries(rel_plt_scnp, symscnp, strscnp))
1823 if (rel_plt_scnp && dynsym_scnp && dynstr_scnp) {
1824 if (!get_relocation_entries(rel_plt_scnp,dynsym_scnp,dynstr_scnp)) {
1829 parse_all_relocations(elfHdr, dynsym_scnp, dynstr_scnp,
1831 // Apply relocations to opd
1832 handle_opd_relocations();
1836 int e_type = elfHdr.e_type();
1837 if (e_type == ET_DYN) {
1838 obj_type_ = obj_SharedLib;
1840 else if (e_type == ET_EXEC) {
1841 obj_type_ = obj_Executable;
1842 }else if( e_type == ET_REL ) {
1843 obj_type_ = obj_RelocatableFile;
1846 // Set rel type based on the ELF machine type
1847 relType_ = getRelTypeByElfMachine(&elfHdr);
1849 } // end binding contour (for "goto cleanup2")
1856 static Symbol::SymbolType pdelf_type(int elf_type)
1859 case STT_FILE: return Symbol::ST_MODULE;
1860 case STT_SECTION:return Symbol::ST_SECTION;
1861 case STT_OBJECT: return Symbol::ST_OBJECT;
1862 case STT_TLS: return Symbol::ST_TLS;
1863 case STT_FUNC: return Symbol::ST_FUNCTION;
1864 case STT_NOTYPE: return Symbol::ST_NOTYPE;
1865 default: return Symbol::ST_UNKNOWN;
1869 static Symbol::SymbolLinkage pdelf_linkage(int elf_binding)
1871 switch (elf_binding) {
1872 case STB_LOCAL: return Symbol::SL_LOCAL;
1873 case STB_WEAK: return Symbol::SL_WEAK;
1874 case STB_GLOBAL: return Symbol::SL_GLOBAL;
1876 return Symbol::SL_UNKNOWN;
1879 static Symbol::SymbolVisibility pdelf_visibility(int elf_visibility)
1881 switch (elf_visibility) {
1882 case STV_DEFAULT: return Symbol::SV_DEFAULT;
1883 case STV_INTERNAL: return Symbol::SV_INTERNAL;
1884 case STV_HIDDEN: return Symbol::SV_HIDDEN;
1885 case STV_PROTECTED: return Symbol::SV_PROTECTED;
1887 return Symbol::SV_UNKNOWN;
1890 //============================================================================
1892 //#include "dyninstAPI/src/arch.h"
1893 //#include "dyninstAPI/src/inst.h"
1894 //#include "dyninstAPI/src/instPoint.h" // includes instPoint-x86.h
1895 //#include "dyninstAPI/src/instP.h" // class returnInstance
1896 //#include "dyninstAPI/src/rpcMgr.h"
1899 bool lookUpSymbol( std::vector< Symbol *>& allsymbols, Offset& addr )
1901 for( unsigned i = 0; i < allsymbols.size(); i++ )
1903 if( allsymbols[ i ]->getOffset() == addr )
1911 bool lookUpAddress( std::vector< Offset >& jumpTargets, Offset& addr )
1913 for( unsigned i = 0; i < jumpTargets.size(); i++ )
1915 if( jumpTargets[ i ] == addr )
1923 //utitility function to print std::vector of symbols
1924 void printSyms( std::vector< Symbol *>& allsymbols )
1926 for( unsigned i = 0; i < allsymbols.size(); i++ )
1928 if( allsymbols[ i ]->getType() != Symbol::ST_FUNCTION )
1932 cout << allsymbols[ i ] << endl;
1937 // Official Procedure Descriptor handler
1939 // Some platforms (PPC64 Linux libc v2.1) only produce function
1940 // symbols which point into the .opd section. Find the actual
1941 // function address in .text, and fix the symbol.
1943 // Additionally, large binaries may contain multiple TOC values.
1944 // Use the .opd section to determine the correct per-function TOC.
1945 // See binutils' bfd/elf64-ppc.c for all the gory details.
1947 // Symbol altering routines should be minimized to prevent problems
1948 // in the rewrite case. Instead, return a new symbol the encapsulates
1949 // the correct information.
1951 // In statically linked binaries, there are relocations against
1952 // .opd section. We need to apply the relocations before using
1955 void Object::handle_opd_relocations(){
1957 unsigned int i = 0, opdregion = 0;
1958 while (i < regions_.size()) {
1959 if(regions_[i]->getRegionName().compare(".opd") == 0){
1966 vector<relocationEntry> region_rels = (regions_[opdregion])->getRelocations();
1967 vector<relocationEntry>::iterator rel_it;
1968 vector<Symbol *>::iterator sym_it;
1969 for(sym_it = opdsymbols_.begin(); sym_it != opdsymbols_.end(); ++sym_it) {
1970 for(rel_it = region_rels.begin(); rel_it != region_rels.end(); ++rel_it) {
1971 if((*sym_it)->getPtrOffset() == (*rel_it).rel_addr()) {
1973 while (i < regions_.size()) {
1974 if(regions_[i]->getRegionName().compare((*rel_it).getDynSym()->getMangledName()) == 0){
1975 Region *targetRegion = regions_[i];
1976 Offset regionOffset = targetRegion->getDiskOffset()+(*rel_it).addend();
1977 (*sym_it)->setRegion(targetRegion);
1978 (*sym_it)->setOffset(regionOffset); // Store code address for the function.
1986 opdsymbols_.clear();
1989 Symbol *Object::handle_opd_symbol(Region *opd, Symbol *sym)
1991 if (!sym) return NULL;
1993 Offset soffset = sym->getOffset();
1994 Offset *opd_entry = (Offset *)(((char *)opd->getPtrToRawData()) +
1995 (soffset - opd->getDiskOffset()));
1996 assert(opd->isOffsetInRegion(soffset)); // Symbol must be in .opd section.
1998 Symbol *retval = new Symbol(*sym); // Copy the .opd symbol.
1999 retval->setOffset(opd_entry[0]); // Store code address for the function.
2000 retval->setLocalTOC(opd_entry[1]); // Store TOC address for this function.
2001 retval->setPtrOffset(soffset); // Original address is the ptr address.
2003 // Find the appropriate region for the new symbol.
2005 while (i < regions_.size()) {
2006 if (regions_[i]->isOffsetInRegion(opd_entry[0])) {
2007 retval->setRegion(regions_[i]);
2012 assert(i < regions_.size());
2013 retval->setSymbolType(Symbol::ST_FUNCTION);
2014 retval->tag_ = Symbol::TAG_INTERNAL; // Not sure if this is an appropriate
2015 // use of the tag field, but we need
2016 // to mark this symbol somehow as a
2019 ///* DEBUG */ fprintf(stderr, "addr:0x%lx ptr_addr:0x%lx toc:0x%lx section:%s\n", opd_entry[0], soffset, opd_entry[1], regions_[i]->getRegionName().c_str());
2023 // parse_symbols(): populate "allsymbols"
2024 bool Object::parse_symbols(Elf_X_Data &symdata, Elf_X_Data &strdata,
2025 Elf_X_Shdr* bssscnp,
2026 Elf_X_Shdr* symscnp,
2027 bool /*shared*/, string smodule)
2029 #if defined(TIMED_PARSE)
2030 struct timeval starttime;
2031 gettimeofday(&starttime, NULL);
2034 if (!symdata.isValid() || !strdata.isValid()) {
2038 Elf_X_Sym syms = symdata.get_sym();
2039 const char *strs = strdata.get_string();
2041 for (unsigned i = 0; i < syms.count(); i++) {
2042 //If it is not a dynamic executable then we need undefined symbols
2043 //in symtab section so that we can resolve symbol references. So
2044 //we parse & store undefined symbols only if there is no dynamic
2046 //1/09: not so anymore--we want to preserve all symbols,
2047 //regardless of file type
2049 int etype = syms.ST_TYPE(i);
2050 int ebinding = syms.ST_BIND(i);
2051 int evisibility = syms.ST_VISIBILITY(i);
2053 // resolve symbol elements
2054 string sname = &strs[ syms.st_name(i) ];
2055 Symbol::SymbolType stype = pdelf_type(etype);
2056 Symbol::SymbolLinkage slinkage = pdelf_linkage(ebinding);
2057 Symbol::SymbolVisibility svisibility = pdelf_visibility(evisibility);
2058 unsigned ssize = syms.st_size(i);
2059 unsigned secNumber = syms.st_shndx(i);
2062 if (symscnp->isFromDebugFile()) {
2063 Offset soffset_dbg = syms.st_value(i);
2064 soffset = soffset_dbg;
2066 bool result = convertDebugOffset(soffset_dbg, soffset);
2068 //Symbol does not match any section, can't convert
2074 soffset = syms.st_value(i);
2077 /* icc BUG: Variables in BSS are categorized as ST_NOTYPE instead of
2078 ST_OBJECT. To fix this, we check if the symbol is in BSS and has
2079 size > 0. If so, we can almost always say it is a variable and hence,
2080 change the type from ST_NOTYPE to ST_OBJECT.
2083 Offset bssStart = Offset(bssscnp->sh_addr());
2084 Offset bssEnd = Offset (bssStart + bssscnp->sh_size()) ;
2086 if(( bssStart <= soffset) && ( soffset < bssEnd ) && (ssize > 0) &&
2087 (stype == Symbol::ST_NOTYPE))
2089 stype = Symbol::ST_OBJECT;
2093 // discard "dummy" symbol at beginning of file
2094 if (i==0 && sname == "" && soffset == (Offset)0)
2099 if(secNumber >= 1 && secNumber < regions_.size()) {
2100 sec = regions_[secNumber];
2105 int strindex = syms.st_name(i);
2107 if(stype == Symbol::ST_SECTION && sec != NULL) {
2108 sname = sec->getRegionName();
2109 soffset = sec->getDiskOffset();
2112 if (stype == Symbol::ST_MODULE) {
2115 Symbol *newsym = new Symbol(sname,
2124 (secNumber == SHN_ABS),
2127 (secNumber == SHN_COMMON));
2129 if (stype == Symbol::ST_UNKNOWN)
2130 newsym->setInternalType(etype);
2132 if (sec && sec->getRegionName() == OPD_NAME && stype == Symbol::ST_FUNCTION ) {
2133 newsym = handle_opd_symbol(sec, newsym);
2135 opdsymbols_.push_back(newsym);
2136 symbols_[sname].push_back(newsym);
2137 symsByOffset_[newsym->getOffset()].push_back(newsym);
2138 symsToModules_[newsym] = smodule;
2140 symbols_[sname].push_back(newsym);
2141 symsByOffset_[newsym->getOffset()].push_back(newsym);
2142 symsToModules_[newsym] = smodule;
2147 #if defined(TIMED_PARSE)
2148 struct timeval endtime;
2149 gettimeofday(&endtime, NULL);
2150 unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
2151 unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
2152 unsigned long difftime = lendtime - lstarttime;
2153 double dursecs = difftime/(1000 * 1000);
2154 cout << "parsing elf took "<<dursecs <<" secs" << endl;
2159 // parse_symbols(): populate "allsymbols"
2160 // Lazy parsing of dynamic symbol & string tables
2161 // Parsing the dynamic symbols lazily would certainly
2162 // not increase the overhead of the entire parse
2163 void Object::parse_dynamicSymbols (Elf_X_Shdr *&
2165 , Elf_X_Data &symdata,
2166 Elf_X_Data &strdata,
2168 std::string smodule)
2170 #if defined(TIMED_PARSE)
2171 struct timeval starttime;
2172 gettimeofday(&starttime, NULL);
2175 Elf_X_Sym syms = symdata.get_sym();
2176 const char *strs = strdata.get_string();
2177 Elf_X_Shdr *versymSec = NULL, *verneedSec = NULL, *verdefSec = NULL;
2178 Elf_X_Data data = dyn_scnp->get_data();
2179 Elf_X_Dyn dyns = data.get_dyn();
2180 unsigned verneednum = 0, verdefnum = 0;
2181 Elf_X_Versym symVersions;
2182 Elf_X_Verdef *symVersionDefs = NULL;
2183 Elf_X_Verneed *symVersionNeeds = NULL;
2184 for (unsigned i = 0; i < dyns.count(); ++i) {
2185 switch(dyns.d_tag(i)) {
2187 deps_.push_back(&strs[dyns.d_ptr(i)]);
2190 versymSec = getRegionHdrByAddr(dyns.d_ptr(i));
2193 verneedSec = getRegionHdrByAddr(dyns.d_ptr(i));
2196 verdefSec = getRegionHdrByAddr(dyns.d_ptr(i));
2199 verneednum = dyns.d_ptr(i);
2202 verdefnum = dyns.d_ptr(i);
2209 symVersions = versymSec->get_data().get_versyms();
2211 symVersionDefs = verdefSec->get_data().get_verDefSym();
2213 symVersionNeeds = verneedSec->get_data().get_verNeedSym();
2215 for(unsigned i = 0; i < verdefnum ;i++) {
2216 Elf_X_Verdaux *aux = symVersionDefs->get_aux();
2217 for(unsigned j=0; j< symVersionDefs->vd_cnt(); j++){
2218 versionMapping[symVersionDefs->vd_ndx()].push_back(&strs[aux->vda_name()]);
2219 Elf_X_Verdaux *auxnext = aux->get_next();
2223 Elf_X_Verdef *symVersionDefsnext = symVersionDefs->get_next();
2224 delete symVersionDefs;
2225 symVersionDefs = symVersionDefsnext;
2228 for(unsigned i = 0; i < verneednum; i++){
2229 Elf_X_Vernaux *aux = symVersionNeeds->get_aux();
2230 for(unsigned j=0; j< symVersionNeeds->vn_cnt(); j++){
2231 versionMapping[aux->vna_other()].push_back(&strs[aux->vna_name()]);
2232 versionFileNameMapping[aux->vna_other()] = &strs[symVersionNeeds->vn_file()];
2233 Elf_X_Vernaux *auxnext = aux->get_next();
2237 Elf_X_Verneed *symVersionNeedsnext = symVersionNeeds->get_next();
2238 delete symVersionNeeds;
2239 symVersionNeeds = symVersionNeedsnext;
2242 if(syms.isValid()) {
2243 for (unsigned i = 0; i < syms.count(); i++) {
2244 int etype = syms.ST_TYPE(i);
2245 int ebinding = syms.ST_BIND(i);
2246 int evisibility = syms.ST_VISIBILITY(i);
2248 // resolve symbol elements
2249 string sname = &strs[ syms.st_name(i) ];
2250 Symbol::SymbolType stype = pdelf_type(etype);
2251 Symbol::SymbolLinkage slinkage = pdelf_linkage(ebinding);
2252 Symbol::SymbolVisibility svisibility = pdelf_visibility(evisibility);
2253 unsigned ssize = syms.st_size(i);
2254 Offset soffset = syms.st_value(i);
2255 unsigned secNumber = syms.st_shndx(i);
2257 // discard "dummy" symbol at beginning of file
2258 if (i==0 && sname == "" && soffset == (Offset)0)
2262 if(secNumber >= 1 && secNumber < regions_.size()) {
2263 sec = regions_[secNumber];
2269 int strindex = syms.st_name(i);
2271 if (stype == Symbol::ST_MODULE) {
2275 Symbol *newsym = new Symbol(sname,
2284 (secNumber == SHN_ABS),
2287 (secNumber == SHN_COMMON));
2289 if (stype == Symbol::ST_UNKNOWN)
2290 newsym->setInternalType(etype);
2293 unsigned short raw = symVersions.get(i);
2294 bool hidden = raw >> 15;
2295 int index = raw & 0x7fff;
2296 if(versionFileNameMapping.find(index) != versionFileNameMapping.end()) {
2297 //printf("version filename for %s: %s\n", sname.c_str(),
2298 //versionFileNameMapping[index].c_str());
2299 newsym->setVersionFileName(versionFileNameMapping[index]);
2301 if(versionMapping.find(index) != versionMapping.end()) {
2302 //printf("versions for %s: ", sname.c_str());
2303 //for (unsigned k=0; k < versionMapping[index].size(); k++)
2304 //printf(" %s", versionMapping[index][k].c_str());
2305 newsym->setVersions(versionMapping[index]);
2309 newsym->setVersionHidden();
2312 // register symbol in dictionary
2314 if (sec && sec->getRegionName() == OPD_NAME && stype == Symbol::ST_FUNCTION ) {
2315 newsym = handle_opd_symbol(sec, newsym);
2316 opdsymbols_.push_back(newsym);
2318 symbols_[sname].push_back(newsym);
2319 symsByOffset_[newsym->getOffset()].push_back(newsym);
2320 symsToModules_[newsym] = smodule;
2322 symbols_[sname].push_back(newsym);
2323 symsByOffset_[newsym->getOffset()].push_back(newsym);
2324 symsToModules_[newsym] = smodule;
2329 #if defined(TIMED_PARSE)
2330 struct timeval endtime;
2331 gettimeofday(&endtime, NULL);
2332 unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
2333 unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
2334 unsigned long difftime = lendtime - lstarttime;
2335 double dursecs = difftime/(1000 * 1000);
2336 cout << "parsing elf took "<<dursecs <<" secs" << endl;
2340 #if defined(USES_DWARF_DEBUG)
2342 string Object::find_symbol(string name)
2346 // pass #1: unmodified
2348 if (symbols_.find(name2)!=symbols_.end()) return name2;
2350 // pass #2: leading underscore (C)
2352 if (symbols_.find(name2)!=symbols_.end()) return name2;
2354 // pass #3: trailing underscore (Fortran)
2356 if (symbols_.find(name2)!=symbols_.end())
2365 /********************************************************
2367 * For object files only....
2368 * read the .debug_info section to find the module of global symbols
2370 * - "DWARF Debugging Information Format"
2371 * - "A Consumer Libary Interface to DWARF"
2373 ********************************************************/
2375 #if defined(USES_DWARF_DEBUG)
2377 void pd_dwarf_handler(Dwarf_Error error, Dwarf_Ptr /*userData*/)
2382 char *dwarf_msg = dwarf_errmsg(error);
2383 string str = string("DWARF Error: ")+ dwarf_msg;
2384 dwarf_err_func(str.c_str());
2386 //bperr( "DWARF error: %s\n", dwarf_msg);
2389 Dwarf_Signed declFileNo = 0;
2390 char ** declFileNoToName = NULL;
2392 bool Object::fixSymbolsInModule( Dwarf_Debug dbg, string & moduleName, Dwarf_Die dieEntry)
2397 string useModuleName;
2398 int status = dwarf_tag( dieEntry, & dieTag, NULL );
2399 if (status != DW_DLV_OK) goto error;
2401 useModuleName = moduleName;
2403 /* For debugging. */
2404 Dwarf_Off dieOffset;
2405 status = dwarf_die_CU_offset( dieEntry, & dieOffset, NULL );
2406 if (status != DW_DLV_OK) goto error;
2409 case DW_TAG_subprogram:
2410 case DW_TAG_entry_point:
2412 /* Let's try ignoring artificial entries, hmm-kay? */
2414 Dwarf_Bool isArtificial;
2415 status = dwarf_hasattr( dieEntry, DW_AT_artificial, & isArtificial, NULL );
2416 if (status != DW_DLV_OK) goto error;
2423 /* Only entries with a PC must be defining declarations. However,
2424 to avoid trying to decide in which module a DW_TAG_inlined_subroutine's
2425 DW_AT_abstract_origin belongs, we just insert the abstract origin itself. */
2427 Dwarf_Bool hasLowPC;
2428 status = dwarf_hasattr( dieEntry, DW_AT_low_pc, & hasLowPC, NULL );
2429 if (status != DW_DLV_OK) goto error;
2431 Dwarf_Bool isAbstractOrigin;
2432 status = dwarf_hasattr( dieEntry, DW_AT_inline, & isAbstractOrigin, NULL );
2433 if (status != DW_DLV_OK) goto error;
2435 if ( ! hasLowPC && ! isAbstractOrigin )
2440 bool isDeclaredNotInlined = false;
2442 /* Inline functions are "uninstrumentable", so leave them off the where axis. */
2444 if ( isAbstractOrigin )
2446 Dwarf_Attribute inlineAttribute;
2447 status = dwarf_attr( dieEntry, DW_AT_inline, & inlineAttribute, NULL );
2448 if (status != DW_DLV_OK) goto error;
2450 Dwarf_Unsigned inlineTag;
2451 status = dwarf_formudata( inlineAttribute, & inlineTag, NULL );
2452 if (status != DW_DLV_OK) goto error;
2454 if ( inlineTag == DW_INL_inlined || inlineTag == DW_INL_declared_inlined )
2459 if ( inlineTag == DW_INL_declared_not_inlined )
2461 isDeclaredNotInlined = true;
2464 dwarf_dealloc( dbg, inlineAttribute, DW_DLA_ATTR );
2467 /* If a DIE has a specification, the specification has its name
2468 and (optional) linkage name. */
2470 Dwarf_Attribute specificationAttribute;
2471 status = dwarf_attr(dieEntry, DW_AT_specification, &specificationAttribute, NULL);
2473 if (status == DW_DLV_ERROR) goto error;
2476 Dwarf_Die nameEntry = dieEntry;
2478 if ( status == DW_DLV_OK )
2480 Dwarf_Off specificationOffset;
2481 status = dwarf_global_formref(specificationAttribute, &specificationOffset, NULL);
2482 if (status != DW_DLV_OK) goto error;
2484 status = dwarf_offdie( dbg, specificationOffset, & nameEntry, NULL );
2485 if (status != DW_DLV_OK) goto error;
2487 dwarf_dealloc( dbg, specificationAttribute, DW_DLA_ATTR );
2488 } /* end if the DIE has a specification. */
2490 /* Ignore artificial entries. */
2492 status = dwarf_hasattr( nameEntry, DW_AT_artificial, & isArtificial, NULL );
2493 if (status != DW_DLV_OK) goto error;
2500 /* What's its name? */
2501 char * dieName = NULL;
2502 status = dwarf_diename( nameEntry, & dieName, NULL );
2503 if (status == DW_DLV_ERROR) goto error;
2505 /* Prefer the linkage (symbol table) name. */
2506 Dwarf_Attribute linkageNameAttribute;
2507 status = dwarf_attr(nameEntry, DW_AT_MIPS_linkage_name, &linkageNameAttribute, NULL);
2508 if (status == DW_DLV_ERROR) goto error;
2510 bool hasLinkageName = false;
2512 if ( status == DW_DLV_OK )
2514 dwarf_dealloc( dbg, dieName, DW_DLA_STRING );
2515 status = dwarf_formstring( linkageNameAttribute, & dieName, NULL );
2516 if (status != DW_DLV_OK) goto error;
2517 hasLinkageName = true;
2520 /* Anonymous functions are useless to us. */
2522 if ( dieName == NULL )
2527 /* Try to find the corresponding global symbol name. */
2529 Dwarf_Die declEntry = nameEntry;
2531 std::vector<Symbol *> foundSymbols;
2533 string globalSymbol = find_symbol(dieName);
2535 if (globalSymbol != "") {
2536 foundSymbols = symbols_[globalSymbol];
2538 else if ( globalSymbol == "" && ! hasLinkageName && isDeclaredNotInlined )
2540 /* Then scan forward for its concrete instance. */
2543 Dwarf_Die siblingDie = dieEntry;
2547 Dwarf_Die priorSibling = siblingDie;
2548 status = dwarf_siblingof( dbg, siblingDie, & siblingDie, NULL );
2549 if (status == DW_DLV_ERROR) goto error;
2553 dwarf_dealloc( dbg, priorSibling, DW_DLA_DIE );
2555 if ( status == DW_DLV_NO_ENTRY )
2560 Dwarf_Attribute abstractOriginAttr;
2561 status = dwarf_attr(siblingDie, DW_AT_abstract_origin, &abstractOriginAttr, NULL);
2563 if (status == DW_DLV_ERROR) goto error;
2565 /* Is its abstract origin the current dieEntry? */
2567 if ( status == DW_DLV_OK )
2569 Dwarf_Off abstractOriginOffset;
2570 status = dwarf_formref( abstractOriginAttr, & abstractOriginOffset, NULL );
2571 if (status != DW_DLV_OK) goto error;
2573 dwarf_dealloc( dbg, abstractOriginAttr, DW_DLA_ATTR );
2575 if ( abstractOriginOffset == dieOffset )
2578 status = dwarf_lowpc( siblingDie, & lowPC, NULL );
2579 if (status != DW_DLV_OK) goto error;
2581 // bperr( "Found function with pretty name '%s' inlined-not-declared at 0x%lx in module '%s'\n", dieName, (unsigned long)lowPC, useModuleName.c_str() );
2583 if ( symsByOffset_.find((Address)lowPC) !=
2584 symsByOffset_.end()) {
2585 foundSymbols = symsByOffset_[(Address)lowPC];
2588 dwarf_dealloc( dbg, siblingDie, DW_DLA_DIE );
2591 } /* end if we've found _the_ concrete instance */
2592 } /* end if we've found a concrete instance */
2596 } /* end iteration. */
2597 } /* end if we're trying to do a by-address look up. */
2599 if (foundSymbols.size()) {
2600 /* If it's not specified, is an inlined function in the same
2601 CU/namespace as its use. */
2603 if ( isDeclaredNotInlined && nameEntry != dieEntry ) {
2604 /* Then the function's definition is where it was
2605 declared, not wherever it happens to be referenced.
2607 Use the decl_file as the useModuleName, if available. */
2609 Dwarf_Attribute fileNoAttribute;
2610 status = dwarf_attr( declEntry, DW_AT_decl_file, & fileNoAttribute, NULL );
2611 if (status == DW_DLV_ERROR) goto error;
2614 if ( status == DW_DLV_OK ) {
2615 Dwarf_Unsigned fileNo;
2616 status = dwarf_formudata( fileNoAttribute, & fileNo, NULL );
2617 if (status != DW_DLV_OK) goto error;
2619 dwarf_dealloc( dbg, fileNoAttribute, DW_DLA_ATTR );
2621 useModuleName = declFileNoToName[ fileNo - 1 ];
2623 //create_printf("%s[%d]: Assuming declared-not-inlined function '%s' to be in module '%s'.\n", FILE__, __LINE__, dieName, useModuleName.c_str());
2625 } /* end if we have declaration file listed */
2627 /* This should never happen, but there's not much
2628 we can do if it does. */
2630 } /* end if isDeclaredNotInlined */
2632 if (foundSymbols.size() == 1) {
2633 symsToModules_[foundSymbols[0]] = useModuleName;
2636 for ( unsigned int i = 0; i < foundSymbols.size(); i++ ) {
2637 if ( foundSymbols[ i ]->getLinkage() == Symbol::SL_GLOBAL ) {
2638 symsToModules_[foundSymbols[i]] = useModuleName;
2642 } /* end if we found the name in the global symbols */
2643 else if ( !isAbstractOrigin &&
2644 (symbols_.find(dieName) != symbols_.end())) {
2645 std::vector< Symbol *> & syms = symbols_[ dieName ];
2647 /* If there's only one, apply regardless. */
2649 if ( syms.size() == 1 ) {
2650 symsToModules_[syms[0]] = useModuleName;
2653 for ( unsigned int i = 0; i < syms.size(); i++ ) {
2654 if ( syms[ i ]->getLinkage() == Symbol::SL_LOCAL ) {
2655 symsToModules_[syms[i]] = useModuleName;
2659 } /* end if we think it's a local symbol */
2660 dwarf_dealloc( dbg, dieName, DW_DLA_STRING );
2665 case DW_TAG_variable:
2666 case DW_TAG_constant:
2668 /* Is this a declaration? */
2670 Dwarf_Attribute declAttr;
2671 status = dwarf_attr( dieEntry, DW_AT_declaration, & declAttr, NULL );
2672 if (status == DW_DLV_ERROR) goto error;
2674 if ( status != DW_DLV_OK )
2679 dwarf_dealloc( dbg, declAttr, DW_DLA_ATTR );
2681 /* If a DIE has a specification, the specification has its name
2682 and (optional) linkage name. */
2684 Dwarf_Attribute specificationAttribute;
2685 status = dwarf_attr(dieEntry, DW_AT_specification, &specificationAttribute, NULL);
2686 if (status == DW_DLV_ERROR) goto error;
2688 Dwarf_Die nameEntry = dieEntry;
2690 if ( status == DW_DLV_OK )
2692 Dwarf_Off specificationOffset;
2693 status = dwarf_global_formref(specificationAttribute, &specificationOffset, NULL);
2694 if (status != DW_DLV_OK) goto error;
2696 dwarf_dealloc( dbg, specificationAttribute, DW_DLA_ATTR );
2698 status = dwarf_offdie( dbg, specificationOffset, & nameEntry, NULL );
2699 if (status != DW_DLV_OK) goto error;
2701 } /* end if the DIE has a specification. */
2703 /* What's its name? */
2705 char * dieName = NULL;
2706 status = dwarf_diename( nameEntry, & dieName, NULL );
2707 if (status == DW_DLV_ERROR) goto error;
2709 /* Prefer the linkage (symbol table) name. */
2711 Dwarf_Attribute linkageNameAttribute;
2712 status = dwarf_attr(nameEntry, DW_AT_MIPS_linkage_name, &linkageNameAttribute, NULL);
2713 if (status == DW_DLV_ERROR) goto error;
2715 if ( status == DW_DLV_OK )
2717 dwarf_dealloc( dbg, dieName, DW_DLA_STRING );
2718 status = dwarf_formstring( linkageNameAttribute, & dieName, NULL );
2719 if (status != DW_DLV_OK) goto error;
2722 /* Anonymous variables are useless to us. */
2723 if ( dieName == NULL )
2728 /* Update the module information. */
2730 string symName = find_symbol(dieName);
2732 if ( symName != "" )
2734 assert(symbols_.find(symName)!=symbols_.end());
2736 /* We're assuming global variables. */
2737 std::vector< Symbol *> & syms = symbols_[ symName ];
2739 /* If there's only one of symbol of that name, set it regardless. */
2740 if ( syms.size() == 1 ) {
2741 symsToModules_[syms[0]] = useModuleName;
2744 for ( unsigned int i = 0; i < syms.size(); i++ ) {
2745 if ( syms[ i ]->getLinkage() == Symbol::SL_GLOBAL ) {
2746 symsToModules_[syms[i]] = useModuleName;
2752 // /* DEBUG */ fprintf( stderr, "%s[%d]: DWARF-derived module %s for symbols of name '%s'\n", __FILE__, __LINE__, useModuleName.c_str(), symName.c_str() );
2754 dwarf_dealloc( dbg, dieName, DW_DLA_STRING );
2761 /* If it's not a function or a variable, ignore it. */
2763 } /* end tag switch */
2765 /* Recurse to its child, if any. */
2767 Dwarf_Die childDwarf;
2768 status = dwarf_child( dieEntry, & childDwarf, NULL );
2769 if (status == DW_DLV_ERROR) goto error;
2771 if ( status == DW_DLV_OK ) {
2772 fixSymbolsInModule(dbg, moduleName, childDwarf);
2775 /* Recurse to its sibling, if any. */
2777 Dwarf_Die siblingDwarf;
2778 status = dwarf_siblingof( dbg, dieEntry, & siblingDwarf, NULL );
2779 if (status == DW_DLV_ERROR) goto error;
2781 if ( status == DW_DLV_OK )
2783 dwarf_dealloc( dbg, dieEntry, DW_DLA_DIE );
2785 /* Force tail-recursion to avoid stack overflows. */
2786 dieEntry = siblingDwarf;
2791 dwarf_dealloc( dbg, dieEntry, DW_DLA_DIE );
2795 dwarf_dealloc( dbg, dieEntry, DW_DLA_DIE );
2797 } /* end fixSymbolsInModule */
2800 unsigned Object::fixSymbolsInModuleByRange(IntervalTree<Dwarf_Addr, std::string> &modules)
2802 if (modules.empty()) return 0;
2804 unsigned nsyms_altered = 0;
2806 for (dyn_hash_map<Offset, std::vector<Symbol *> >::iterator iter = symsByOffset_.begin();
2807 iter != symsByOffset_.end();
2809 Offset off = iter->first;
2810 std::vector<Symbol *> &syms = iter->second;
2812 std::string modname;
2813 if (modules.find((Dwarf_Addr) off, modname)) {
2814 for (unsigned i = 0; i < syms.size(); i++) {
2815 symsToModules_[syms[i]] = modname;
2821 return nsyms_altered;
2824 bool Object::fix_global_symbol_modules_static_dwarf()
2827 /* Initialize libdwarf. */
2828 Dwarf_Debug *dbg_ptr = dwarf.dbg();
2831 Dwarf_Debug &dbg = *dbg_ptr;
2835 IntervalTree<Dwarf_Addr, std::string> module_ranges;
2837 /* Iterate over the CU headers. */
2838 while ( dwarf_next_cu_header_c( dbg, 1,
2839 NULL, NULL, NULL, // len, stamp, abbrev
2840 NULL, NULL, NULL, // address, offset, extension
2841 NULL, NULL, // signature, typeoffset
2842 & hdr, NULL ) == DW_DLV_OK )
2844 /* Obtain the module DIE. */
2845 Dwarf_Die moduleDIE;
2846 status = dwarf_siblingof( dbg, NULL, & moduleDIE, NULL );
2847 if (status != DW_DLV_OK) goto error;
2849 /* Make sure we've got the right one. */
2850 Dwarf_Half moduleTag;
2851 status = dwarf_tag( moduleDIE, & moduleTag, NULL);
2852 if (status != DW_DLV_OK) goto error;
2853 if (moduleTag != DW_TAG_compile_unit) goto error;
2855 /* Extract the name of this module. */
2856 char * dwarfModuleName = NULL;
2857 status = dwarf_diename( moduleDIE, & dwarfModuleName, NULL );
2858 if (status == DW_DLV_ERROR) goto error;
2862 if ( status == DW_DLV_NO_ENTRY || dwarfModuleName == NULL )
2864 moduleName = string( "{ANONYMOUS}" );
2868 moduleName = extract_pathname_tail( string(dwarfModuleName) );
2871 Dwarf_Addr modLowPC = 0;
2872 Dwarf_Addr modHighPC = (Dwarf_Addr)(-1);
2873 Dwarf_Bool hasLowPC;
2874 Dwarf_Bool hasHighPC;
2876 if ( (status = dwarf_hasattr(moduleDIE, DW_AT_low_pc, &hasLowPC, NULL)) == DW_DLV_OK &&
2878 (status = dwarf_hasattr(moduleDIE, DW_AT_high_pc, &hasHighPC, NULL)) == DW_DLV_OK &&
2881 // Get PC boundaries for the module, if present
2882 status = dwarf_lowpc(moduleDIE, &modLowPC, NULL);
2883 if (status != DW_DLV_OK) goto error;
2885 status = dwarf_highpc(moduleDIE, &modHighPC, NULL);
2886 if (status != DW_DLV_OK) goto error;
2890 modHighPC = (Dwarf_Addr)(-1);
2893 // Set module names for all symbols that belong to the range
2894 module_ranges.insert(modLowPC, modHighPC, moduleName);
2898 /* Acquire declFileNoToName. */
2899 status = dwarf_srcfiles( moduleDIE, & declFileNoToName, & declFileNo, NULL );
2900 if (status == DW_DLV_ERROR) goto error;
2902 if ( status == DW_DLV_OK )
2904 /* Walk the tree. */
2906 //fprintf(stderr, "%s[%d]: about to fixSymbolsInModule(%s,...)\n",
2907 // FILE__, __LINE__, moduleName.c_str());
2909 bool result = fixSymbolsInModule(dbg, moduleName, moduleDIE);
2910 if (!result) goto error;
2912 /* Deallocate declFileNoToName. */
2914 for ( Dwarf_Signed i = 0; i < declFileNo; i++ ) {
2915 dwarf_dealloc( dbg, declFileNoToName[i], DW_DLA_STRING );
2918 dwarf_dealloc( dbg, declFileNoToName, DW_DLA_LIST );
2920 } /* end if the srcfile information was available */
2921 } /* end if code range information unavailable */
2923 modules_.push_back(std::pair<std::string, Offset>(moduleName, modLowPC));
2924 } /* end scan over CU headers. */
2926 if (!module_ranges.empty()) {
2927 fixSymbolsInModuleByRange(module_ranges);
2937 // dummy definition for non-DWARF platforms
2938 bool Object::fix_global_symbol_modules_static_dwarf()
2941 #endif // USES_DWARF_DEBUG
2943 /********************************************************
2945 * For object files only....
2946 * read the .stab section to find the module of global symbols
2948 ********************************************************/
2950 bool Object::fix_global_symbol_modules_static_stab(Elf_X_Shdr* stabscnp, Elf_X_Shdr* stabstrscnp)
2952 // Read the stab section to find the module of global symbols.
2953 // The symbols appear in the stab section by module. A module begins
2954 // with a symbol of type N_UNDF and ends with a symbol of type N_ENDM.
2955 // All the symbols in between those two symbols belong to the module.
2957 if (!stabscnp || !stabstrscnp) return false;
2959 Elf_X_Data stabdata = stabscnp->get_data();
2960 Elf_X_Data stabstrdata = stabstrscnp->get_data();
2961 stab_entry *stabptr = NULL;
2963 if (!stabdata.isValid() || !stabstrdata.isValid()) return false;
2965 switch (addressWidth_nbytes)
2968 stabptr = new stab_entry_32(stabdata.d_buf(),
2969 stabstrdata.get_string(),
2970 stabscnp->sh_size() / sizeof(stab32));
2974 stabptr = new stab_entry_64(stabdata.d_buf(),
2975 stabstrdata.get_string(),
2976 stabscnp->sh_size() / sizeof(stab64));
2980 const char *next_stabstr = stabptr->getStringBase();
2981 string module = "DEFAULT_MODULE";
2983 // the stabstr contains one string table for each module.
2984 // stabstr_offset gives the offset from the begining of stabstr of the
2985 // string table for the current module.
2987 bool is_fortran = false; // is the current module fortran code?
2989 for (unsigned i = 0; i < stabptr->count(); i++)
2991 switch(stabptr->type(i))
2993 case N_UNDF: /* start of object file */
2994 stabptr->setStringBase(next_stabstr);
2995 next_stabstr = stabptr->getStringBase() + stabptr->val(i);
2998 case N_ENDM: /* end of object file */
3000 module = "DEFAULT_MODULE";
3003 case N_SO: /* compilation source or file name */
3004 if ((stabptr->desc(i) == N_SO_FORTRAN) || (stabptr->desc(i) == N_SO_F90))
3007 module = string(stabptr->name(i));
3010 case N_ENTRY: /* fortran alternate subroutine entry point */
3011 case N_GSYM: /* global symbol */
3012 // the name string of a function or object appears in the stab
3013 // string table as <symbol name>:<symbol descriptor><other stuff>
3014 // where <symbol descriptor> is a one char code.
3015 // we must extract the name and descriptor from the string
3017 const char *p = stabptr->name(i);
3018 // bperr("got %d type, str = %s\n", stabptr->type(i), p);
3019 // if (stabptr->type(i) == N_FUN && strlen(p) == 0) {
3023 // GNU CC 2.8 and higher associate a null-named function
3024 // entry with the end of a function. Just skip it.
3028 const char *q = strchr(p,':');
3042 // symbol name is empty.Skip it.- 02/12/07 -Giri
3046 char *sname = new char[len+1];
3047 strncpy(sname, p, len);
3050 string SymName = string(sname);
3052 // q points to the ':' in the name string, so
3053 // q[1] is the symbol descriptor. We must check the symbol descriptor
3054 // here to skip things we are not interested in, such as prototypes.
3056 bool res = (symbols_.find(SymName)!=symbols_.end());
3058 if (!res && is_fortran)
3060 // Fortran symbols usually appear with an '_' appended in .symtab,
3063 res = (symbols_.find(SymName)!=symbols_.end());
3066 if (res && (q == 0 || q[1] != SD_PROTOTYPE))
3068 unsigned int count = 0;
3069 std::vector< Symbol *> & syms = symbols_[SymName];
3071 /* If there's only one, apply regardless. */
3072 if ( syms.size() == 1 )
3075 // symbols_[SymName][0]->setModuleName(module);
3079 for ( unsigned int i = 0; i < syms.size(); i++ )
3081 if ( syms[i]->getLinkage() == Symbol::SL_GLOBAL )
3084 // symbols_[SymName][i]->setModuleName(module);
3095 const char *p = stabptr->name(i);
3099 // Rumours are that GNU CC 2.8 and higher associate a
3100 // null-named function entry with the end of a
3101 // function. Just skip it.
3105 const char *q = strchr(p,':');
3109 // bperr( "Unrecognized stab format: %s\n", p);
3110 // Happens with the Solaris native compiler (.xstabs entries?)
3114 if (q[1] == SD_PROTOTYPE)
3116 // We see a prototype, skip it
3120 unsigned long entryAddr = stabptr->val(i);
3124 // The function stab doesn't contain a function address
3125 // (happens with the Solaris native compiler). We have to
3126 // look up the symbol by its name. That's unfortunate, since
3127 // names may not be unique and we may end up assigning a wrong
3128 // module name to the symbol.
3129 unsigned len = q - p;
3132 // symbol name is empty.Skip it.- 02/12/07 -Giri
3136 char *sname = new char[len+1];
3137 strncpy(sname, p, len);
3139 string nameFromStab = string(sname);
3142 for (unsigned i = 0; i < symbols_[nameFromStab].size(); i++) {
3143 symsToModules_[symbols_[nameFromStab][i]] = module;
3148 if (symsByOffset_.find(entryAddr)==symsByOffset_.end()) {
3149 //bperr( "fix_global_symbol_modules_static_stab "
3150 // "can't find address 0x%lx of STABS entry %s\n", entryAddr, p);
3153 for (unsigned i = 0; i < symsByOffset_[entryAddr].size(); i++) {
3154 symsToModules_[symsByOffset_[entryAddr][i]] = module;
3161 /* ignore other entries */
3172 // find_code_and_data(): populates the following members:
3173 // code_ptr_, code_off_, code_len_
3174 // data_ptr_, data_off_, data_len_
3175 void Object::find_code_and_data(Elf_X &elf,
3180 * .o's don't have program headers, so these fields are populated earlier
3181 * when the sections are processed -> see loaded_elf()
3184 for (int i = 0; i < elf.e_phnum(); ++i) {
3185 Elf_X_Phdr phdr = elf.get_phdr(i);
3187 char *file_ptr = (char *)mf->base_addr();
3189 if(!isRegionPresent(phdr.p_paddr(), phdr.p_filesz(), phdr.p_flags()))
3190 regions_.push_back(new Region(i, "", phdr.p_paddr(), phdr.p_filesz(), phdr.p_vaddr(), phdr.p_memsz(), &file_ptr[phdr.p_offset()], getSegmentPerms(phdr.p_flags()), getSegmentType(phdr.p_type(), phdr.p_flags())));
3192 // The code pointer, offset, & length should be set even if
3193 // txtaddr=0, so in this case we set these values by
3194 // identifying the segment that contains the entryAddress
3195 if (((phdr.p_vaddr() <= txtaddr) &&
3196 (phdr.p_vaddr() + phdr.p_filesz() >= txtaddr)) ||
3197 (!txtaddr && ((phdr.p_vaddr() <= entryAddress_) &&
3198 (phdr.p_vaddr() + phdr.p_filesz() >= entryAddress_)))) {
3200 if (code_ptr_ == 0 && code_off_ == 0 && code_len_ == 0) {
3201 code_ptr_ = (char *)(void*)&file_ptr[phdr.p_offset()];
3202 code_off_ = (Offset)phdr.p_vaddr();
3203 code_len_ = (unsigned)phdr.p_filesz();
3206 } else if (((phdr.p_vaddr() <= dataddr) &&
3207 (phdr.p_vaddr() + phdr.p_filesz() >= dataddr)) ||
3208 (!dataddr && (phdr.p_type() == PT_LOAD))) {
3209 if (data_ptr_ == 0 && data_off_ == 0 && data_len_ == 0) {
3210 data_ptr_ = (char *)(void *)&file_ptr[phdr.p_offset()];
3211 data_off_ = (Offset)phdr.p_vaddr();
3212 data_len_ = (unsigned)phdr.p_filesz();
3216 //if (addressWidth_nbytes == 8) bperr( ">>> 64-bit find_code_and_data() successful\n");
3219 const char *Object::elf_vaddr_to_ptr(Offset vaddr) const
3221 const char *ret = NULL;
3222 unsigned code_size_ = code_len_;
3223 unsigned data_size_ = data_len_;
3225 #if defined(os_irix)
3229 if (vaddr >= code_off_ && vaddr < code_off_ + code_size_) {
3230 ret = ((char *)code_ptr_) + (vaddr - code_off_);
3231 } else if (vaddr >= data_off_ && vaddr < data_off_ + data_size_) {
3232 ret = ((char *)data_ptr_) + (vaddr - data_off_);
3238 stab_entry *Object::get_stab_info() const
3240 char *file_ptr = (char *)mf->base_addr();
3242 // check that file has .stab info
3243 if (stab_off_ && stab_size_ && stabstr_off_) {
3244 switch (addressWidth_nbytes) {
3245 case 4: // 32-bit object
3246 return new stab_entry_32(file_ptr + stab_off_,
3247 file_ptr + stabstr_off_,
3248 stab_size_ / sizeof(stab32));
3250 case 8: // 64-bit object
3251 return new stab_entry_64(file_ptr + stab_off_,
3252 file_ptr + stabstr_off_,
3253 stab_size_ / sizeof(stab64));
3258 //fprintf(stderr, "%s[%d]: WARNING: FIXME, stab_off = %d, stab_size = %d, stabstr_off_ = %d\n", FILE__, __LINE__, stab_off_, stab_size_, stabstr_off_);
3259 return new stab_entry_64();
3262 Object::Object(MappedFile *mf_, MappedFile *mfd, bool, void (*err_func)(const char *),
3264 AObject(mf_, mfd, err_func),
3269 relType_(Region::RT_REL),
3272 DbgSectionMapSorted(false)
3275 #if defined(TIMED_PARSE)
3276 struct timeval starttime;
3277 gettimeofday(&starttime, NULL);
3281 interpreter_name_ = NULL;
3283 if(mf->getFD() != -1)
3284 elfHdr = Elf_X(mf->getFD(), ELF_C_READ);
3286 elfHdr = Elf_X((char *)mf->base_addr(), mf->size());
3288 // ELF header: sanity check
3289 //if (!elfHdr.isValid()|| !pdelf_check_ehdr(elfHdr))
3290 if (!elfHdr.isValid()) {
3291 log_elferror(err_func_, "ELF header");
3295 else if (!pdelf_check_ehdr(elfHdr)) {
3296 log_elferror(err_func_, "ELF header failed integrity check");
3300 mfForDebugInfo = findMappedFileForDebugInfo();
3302 if( elfHdr.e_type() == ET_DYN )
3303 load_shared_object(alloc_syms);
3304 else if( elfHdr.e_type() == ET_REL || elfHdr.e_type() == ET_EXEC ) {
3305 // Differentiate between an executable and an object file
3306 if( elfHdr.e_phnum() ) is_aout_ = true;
3307 else is_aout_ = false;
3309 load_object(alloc_syms);
3312 log_perror(err_func_,"Invalid filetype in Elf header");
3317 #ifdef BINEDIT_DEBUG
3318 print_symbol_map(&symbols_);
3320 #if defined(TIMED_PARSE)
3321 struct timeval endtime;
3322 gettimeofday(&endtime, NULL);
3323 unsigned long lstarttime = starttime.tv_sec * 1000 * 1000 + starttime.tv_usec;
3324 unsigned long lendtime = endtime.tv_sec * 1000 * 1000 + endtime.tv_usec;
3325 unsigned long difftime = lendtime - lstarttime;
3326 double dursecs = difftime/(1000 );
3327 cout << "obj parsing in Object-elf took "<<dursecs <<" msecs" << endl;
3331 Object::Object(const Object& obj)
3336 interpreter_name_ = obj.interpreter_name_;
3337 isStripped = obj.isStripped;
3338 loadAddress_ = obj.loadAddress_;
3339 entryAddress_ = obj.entryAddress_;
3340 relocation_table_ = obj.relocation_table_;
3342 elfHdr = obj.elfHdr;
3344 DbgSectionMapSorted = obj.DbgSectionMapSorted;
3345 relType_ = obj.relType_;
3351 relocation_table_.clear();
3353 for(i=0; i<allRegionHdrs.size();i++)
3354 delete allRegionHdrs[i];
3355 allRegionHdrs.clear();
3356 versionMapping.clear();
3357 versionFileNameMapping.clear();
3360 // This is necessary to free resources held internally by libelf
3362 elfHdrForDebugInfo.end();
3365 void Object::log_elferror(void (*err_func)(const char *), const char* msg)
3367 const char* err = elf_errmsg(elf_errno());
3368 err = err ? err: "(bad elf error)";
3369 string str = string(err)+string(msg);
3370 err_func(str.c_str());
3373 bool Object::get_func_binding_table(std::vector<relocationEntry> &fbt) const
3375 #if !defined(os_vxworks)
3376 if(!plt_addr_ || (!fbt_.size())) return false;
3382 bool Object::get_func_binding_table_ptr(const std::vector<relocationEntry> *&fbt) const
3384 if(!plt_addr_ || (!fbt_.size())) return false;
3389 void Object::getDependencies(std::vector<std::string> &deps){
3393 bool Object::addRelocationEntry(relocationEntry &re)
3395 relocation_table_.push_back(re);
3401 // stream-based debug output
3402 const ostream &Object::dump_state_info(ostream &s)
3404 s << "Debugging Information for Object (address) : " << this << endl;
3406 s << " <<begin debugging info for base object>>" << endl;
3407 AObject::dump_state_info(s);
3408 s << " <<end debuggingo info for base object>>" << endl;
3410 s << " dynsym_addr_ = " << dynsym_addr_ << endl;
3411 s << " dynstr_addr_ = " << dynstr_addr_ << endl;
3412 s << " got_addr_ = " << got_addr_ << endl;
3413 s << " plt_addr_ = " << plt_addr_ << endl;
3414 s << " plt_size_ = " << plt_size_ << endl;
3415 s << " plt_entry_size_ = " << plt_entry_size_ << endl;
3416 s << " rel_plt_addr_ = " << rel_plt_addr_ << endl;
3417 s << " rel_plt_size_ = " << rel_plt_size_ << endl;
3418 s << " rel_plt_entry_size_ = " << rel_plt_entry_size_ << endl;
3419 s << " rel_size_ = " << rel_size_ << endl;
3420 s << " rel_entry_size_ = " << rel_entry_size_ << endl;
3421 s << " stab_off_ = " << stab_off_ << endl;
3422 s << " stab_size_ = " << stab_size_ << endl;
3423 s << " stabstr_off_ = " << stabstr_off_ << endl;
3424 s << " dwarvenDebugInfo = " << dwarvenDebugInfo << endl;
3426 // and dump the relocation table....
3427 s << " fbt_ = (field seperator :: )" << endl;
3428 for (unsigned i=0; i < fbt_.size(); i++) {
3429 s << fbt_[i] << " :: ";
3439 Offset Object::getPltSlot(string funcName) const
3444 for ( unsigned int i = 0; i < fbt_.size(); i++ ){
3445 if (funcName == fbt_[i].name() ){
3446 offset = fbt_[i].rel_addr();
3454 // get_valid_memory_areas - get ranges of code/data segments that have
3455 // sections mapped to them
3458 void Object::get_valid_memory_areas(Elf_X &elf)
3460 for (unsigned i = 0; i < elf.e_shnum(); ++i) {
3461 Elf_X_Shdr shdr = elf.get_shdr(i);
3462 if ( !shdr.isValid()) {
3465 if (shdr.sh_flags() & SHF_ALLOC) { // This section is in memory
3466 if (code_off_ <= shdr.sh_addr() &&
3467 shdr.sh_addr() <= code_off_ + code_len_) {
3468 if (shdr.sh_addr() < code_vldS_)
3469 code_vldS_ = shdr.sh_addr();
3470 if (shdr.sh_addr() + shdr.sh_size() > code_vldE_)
3471 code_vldE_ = shdr.sh_addr() + shdr.sh_size();
3473 } else if (data_off_ <= shdr.sh_addr() &&
3474 shdr.sh_addr() <= data_off_ + data_len_) {
3475 if (shdr.sh_addr() < data_vldS_)
3476 data_vldS_ = shdr.sh_addr();
3477 if (shdr.sh_addr() + shdr.sh_size() > data_vldE_)
3478 data_vldE_ = shdr.sh_addr() + shdr.sh_size();
3485 // parseCompilerType - parse for compiler that was used to generate object
3489 #if defined(os_linux)
3490 // Differentiating between g++ and pgCC by stabs info (as in the solaris/
3491 // aix case, below) will not work; the gcc-compiled object files that
3492 // get included at link time will fill in the N_OPT stabs line. Instead,
3493 // look for "pgCC_compiled." symbols.
3494 bool parseCompilerType(Object *objPtr)
3496 dyn_hash_map<string, std::vector<Symbol *> >*syms = objPtr->getAllSymbols();
3497 if(syms->find("pgCC_compiled.") != syms->end())
3502 bool parseCompilerType(Object *objPtr)
3504 stab_entry *stabptr = objPtr->get_stab_info();
3505 const char *next_stabstr = stabptr->getStringBase();
3507 for (unsigned int i=0; i < stabptr->count(); ++i) {
3508 // if (stabstrs) bperr("parsing #%d, %s\n", stabptr->type(i), stabptr->name(i));
3509 switch (stabptr->type(i)) {
3511 case N_UNDF: /* start of object file */
3512 /* value contains offset of the next string table for next module */
3513 // assert(stabptr.nameIdx(i) == 1);
3514 stabptr->setStringBase(next_stabstr);
3515 next_stabstr = stabptr->getStringBase() + stabptr->val(i);
3518 case N_OPT: /* Compiler options */
3524 return false; // Shouldn't happen - maybe N_OPT stripped
3529 #if (defined(os_linux) || defined(os_freebsd)) && (defined(arch_x86) || defined(arch_x86_64))
3531 static unsigned long read_uleb128(const unsigned char *data, unsigned *bytes_read)
3533 unsigned long result = 0;
3538 result |= (data[*bytes_read] & 0x7f) << shift;
3539 if ((data[(*bytes_read)++] & 0x80) == 0)
3546 static signed long read_sleb128(const unsigned char *data, unsigned *bytes_read)