2 * Copyright (c) 1996-2011 Barton P. Miller
4 * We provide the Paradyn Parallel Performance Tools (below
5 * described as "Paradyn") on an AS IS basis, and do not warrant its
6 * validity or performance. We reserve the right to update, modify,
7 * or discontinue this software at any time. We shall have no
8 * obligation to supply such updates or modifications or any other
9 * form of support to you.
11 * By your use of Paradyn, you understand and agree that we (or any
12 * other person or entity with proprietary rights in Paradyn) are
13 * under no obligation to provide either maintenance services,
14 * update services, notices of latent defects, or correction of
15 * defects for Paradyn.
17 * This library is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU Lesser General Public
19 * License as published by the Free Software Foundation; either
20 * version 2.1 of the License, or (at your option) any later version.
22 * This library is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 * Lesser General Public License for more details.
27 * You should have received a copy of the GNU Lesser General Public
28 * License along with this library; if not, write to the Free Software
29 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
32 #include "common/h/Elf_X.h"
35 #include <sys/types.h>
41 #include <boost/crc.hpp>
42 #include <boost/assign/list_of.hpp>
43 #include <boost/assign/std/set.hpp>
44 #include <boost/assign/std/vector.hpp>
47 using boost::crc_32_type;
48 using namespace boost::assign;
50 #define DEBUGLINK_NAME ".gnu_debuglink"
51 #define BUILD_ID_NAME ".note.gnu.build-id"
53 #if defined(INLINE_ELF_X)
54 #define INLINE_DEF inline
58 // ------------------------------------------------------------------------
59 // Class Elf_X simulates the Elf(32|64)_Ehdr structure.
60 // Also works for ELF archives.
61 INLINE_DEF Elf_X::Elf_X()
62 : elf(NULL), ehdr32(NULL), ehdr64(NULL), phdr32(NULL), phdr64(NULL),
63 filedes(-1), is64(false), isArchive(false)
66 INLINE_DEF Elf_X::Elf_X(int input, Elf_Cmd cmd, Elf_X *ref)
67 : ehdr32(NULL), ehdr64(NULL), phdr32(NULL), phdr64(NULL),
68 filedes(input), is64(false), isArchive(false)
70 if (elf_version(EV_CURRENT) != EV_NONE) {
71 elf_errno(); // Reset elf_errno to zero.
73 elf = elf_begin(input, cmd, ref->e_elfp());
75 elf = elf_begin(input, cmd, NULL);
77 if ((errnum = elf_errno()) != 0) {
78 //const char *msg = elf_errmsg(errnum);
79 //fprintf(stderr, "Elf error: %s\n", msg);
82 if (elf_kind(elf) == ELF_K_ELF) {
83 char *identp = elf_getident(elf, NULL);
84 is64 = (identp && identp[EI_CLASS] == ELFCLASS64);
86 else if(elf_kind(elf) == ELF_K_AR) {
87 char *identp = elf_getident(elf, NULL);
88 is64 = (identp && identp[EI_CLASS] == ELFCLASS64);
92 if (!is64) ehdr32 = elf32_getehdr(elf);
93 else ehdr64 = elf64_getehdr(elf);
95 if (!is64) phdr32 = elf32_getphdr(elf);
96 else phdr64 = elf64_getphdr(elf);
101 INLINE_DEF Elf_X::Elf_X(char *mem_image, size_t mem_size)
102 : ehdr32(NULL), ehdr64(NULL), phdr32(NULL), phdr64(NULL),
103 is64(false), isArchive(false)
105 if (elf_version(EV_CURRENT) != EV_NONE) {
106 elf_errno(); // Reset elf_errno to zero.
107 elf = elf_memory(mem_image, mem_size);
110 if ( (err = elf_errno()) != 0) {
111 //const char *msg = elf_errmsg(err);
115 if (elf_kind(elf) == ELF_K_ELF) {
116 char *identp = elf_getident(elf, NULL);
117 is64 = (identp && identp[EI_CLASS] == ELFCLASS64);
120 if (!is64) ehdr32 = elf32_getehdr(elf);
121 else ehdr64 = elf64_getehdr(elf);
123 if (!is64) phdr32 = elf32_getphdr(elf);
124 else phdr64 = elf64_getphdr(elf);
129 INLINE_DEF void Elf_X::end()
142 INLINE_DEF Elf *Elf_X::e_elfp() const
147 INLINE_DEF unsigned char *Elf_X::e_ident() const
150 static_cast<unsigned char*>(ehdr32->e_ident) :
151 static_cast<unsigned char*>(ehdr64->e_ident));
154 INLINE_DEF unsigned short Elf_X::e_type() const
157 static_cast<unsigned short>(ehdr32->e_type) :
158 static_cast<unsigned short>(ehdr64->e_type));
161 INLINE_DEF unsigned short Elf_X::e_machine() const
164 static_cast<unsigned short>(ehdr32->e_machine) :
165 static_cast<unsigned short>(ehdr64->e_machine));
168 INLINE_DEF unsigned long Elf_X::e_version() const
171 static_cast<unsigned long>(ehdr32->e_version) :
172 static_cast<unsigned long>(ehdr64->e_version));
175 INLINE_DEF unsigned long Elf_X::e_entry() const
178 static_cast<unsigned long>(ehdr32->e_entry) :
179 static_cast<unsigned long>(ehdr64->e_entry));
182 INLINE_DEF unsigned long Elf_X::e_phoff() const
185 static_cast<unsigned long>(ehdr32->e_phoff) :
186 static_cast<unsigned long>(ehdr64->e_phoff));
189 INLINE_DEF unsigned long Elf_X::e_shoff() const
192 static_cast<unsigned long>(ehdr32->e_shoff) :
193 static_cast<unsigned long>(ehdr64->e_shoff));
196 INLINE_DEF unsigned long Elf_X::e_flags() const
199 static_cast<unsigned long>(ehdr32->e_flags) :
200 static_cast<unsigned long>(ehdr64->e_flags));
203 INLINE_DEF unsigned short Elf_X::e_ehsize() const
206 static_cast<unsigned short>(ehdr32->e_ehsize) :
207 static_cast<unsigned short>(ehdr64->e_ehsize));
210 INLINE_DEF unsigned short Elf_X::e_phentsize() const {
212 static_cast<unsigned short>(ehdr32->e_phentsize) :
213 static_cast<unsigned short>(ehdr64->e_phentsize));
216 INLINE_DEF unsigned short Elf_X::e_phnum() const
219 static_cast<unsigned short>(ehdr32->e_phnum) :
220 static_cast<unsigned short>(ehdr64->e_phnum));
223 INLINE_DEF unsigned short Elf_X::e_shentsize() const
226 static_cast<unsigned short>(ehdr32->e_shentsize) :
227 static_cast<unsigned short>(ehdr64->e_shentsize));
230 INLINE_DEF unsigned short Elf_X::e_shnum() const
233 static_cast<unsigned short>(ehdr32->e_shnum) :
234 static_cast<unsigned short>(ehdr64->e_shnum));
237 INLINE_DEF unsigned short Elf_X::e_shstrndx() const
240 static_cast<unsigned short>(ehdr32->e_shstrndx) :
241 static_cast<unsigned short>(ehdr64->e_shstrndx));
244 INLINE_DEF const char *Elf_X::e_rawfile(size_t &nbytes) const
246 return elf_rawfile(elf, &nbytes);
249 INLINE_DEF Elf_X *Elf_X::e_next(Elf_X *ref)
253 Elf_Cmd cmd = elf_next(ref->e_elfp());
254 return new Elf_X(filedes, cmd, this);
257 INLINE_DEF Elf_X *Elf_X::e_rand(unsigned offset)
261 elf_rand(elf, offset);
262 return new Elf_X(filedes, ELF_C_READ, this);
266 INLINE_DEF void Elf_X::e_ident(unsigned char *input)
268 if (!is64) P_memcpy(ehdr32->e_ident, input, EI_NIDENT);
269 else P_memcpy(ehdr64->e_ident, input, EI_NIDENT);
272 INLINE_DEF void Elf_X::e_type(unsigned short input)
274 if (!is64) ehdr32->e_type = input;
275 else ehdr64->e_type = input;
278 INLINE_DEF void Elf_X::e_machine(unsigned short input)
280 if (!is64) ehdr32->e_machine = input;
281 else ehdr64->e_machine = input;
284 INLINE_DEF void Elf_X::e_version(unsigned long input)
286 if (!is64) ehdr32->e_version = input;
287 else ehdr64->e_version = input;
290 INLINE_DEF void Elf_X::e_entry(unsigned long input)
292 if (!is64) ehdr32->e_entry = input;
293 else ehdr64->e_entry = input;
296 INLINE_DEF void Elf_X::e_phoff(unsigned long input)
298 if (!is64) ehdr32->e_phoff = input;
299 else ehdr64->e_phoff = input;
302 INLINE_DEF void Elf_X::e_shoff(unsigned long input)
304 if (!is64) ehdr32->e_shoff = input;
305 else ehdr64->e_shoff = input;
308 INLINE_DEF void Elf_X::e_flags(unsigned long input)
310 if (!is64) ehdr32->e_flags = input;
311 else ehdr64->e_flags = input;
314 INLINE_DEF void Elf_X::e_ehsize(unsigned short input)
316 if (!is64) ehdr32->e_ehsize = input;
317 else ehdr64->e_ehsize = input;
320 INLINE_DEF void Elf_X::e_phentsize(unsigned short input)
322 if (!is64) ehdr32->e_phentsize = input;
323 else ehdr64->e_phentsize = input;
326 INLINE_DEF void Elf_X::e_phnum(unsigned short input)
328 if (!is64) ehdr32->e_phnum = input;
329 else ehdr64->e_phnum = input;
332 INLINE_DEF void Elf_X::e_shentsize(unsigned short input)
334 if (!is64) ehdr32->e_shentsize = input;
335 else ehdr64->e_shentsize = input;
338 INLINE_DEF void Elf_X::e_shnum(unsigned short input)
340 if (!is64) ehdr32->e_shnum = input;
341 else ehdr64->e_shnum = input;
344 INLINE_DEF void Elf_X::e_shstrndx(unsigned short input)
346 if (!is64) ehdr32->e_shstrndx = input;
347 else ehdr64->e_shstrndx = input;
351 INLINE_DEF bool Elf_X::isValid() const
353 return (ehdr32 || ehdr64);
356 INLINE_DEF int Elf_X::wordSize() const
358 return (!is64 ? 4 : 8);
361 INLINE_DEF Elf_X_Phdr Elf_X::get_phdr(unsigned int i) const
363 if (!is64) return Elf_X_Phdr(is64, phdr32 + i);
364 else return Elf_X_Phdr(is64, phdr64 + i);
367 INLINE_DEF Elf_X_Shdr Elf_X::get_shdr(unsigned int i) const
369 Elf_Scn *scn = elf_getscn(elf, i);
370 Elf_X_Shdr result(is64, scn);
375 // ------------------------------------------------------------------------
376 // Class Elf_X_Phdr simulates the Elf(32|64)_Phdr structure.
377 INLINE_DEF Elf_X_Phdr::Elf_X_Phdr()
378 : phdr32(NULL), phdr64(NULL), is64(false)
381 INLINE_DEF Elf_X_Phdr::Elf_X_Phdr(bool is64_, void *input)
382 : phdr32(NULL), phdr64(NULL), is64(is64_)
385 if (!is64) phdr32 = (Elf32_Phdr *)input;
386 else phdr64 = (Elf64_Phdr *)input;
391 INLINE_DEF unsigned long Elf_X_Phdr::p_type() const
394 static_cast<unsigned long>(phdr32->p_type) :
395 static_cast<unsigned long>(phdr64->p_type));
398 INLINE_DEF unsigned long Elf_X_Phdr::p_offset() const
401 static_cast<unsigned long>(phdr32->p_offset) :
402 static_cast<unsigned long>(phdr64->p_offset));
405 INLINE_DEF unsigned long Elf_X_Phdr::p_vaddr() const
408 static_cast<unsigned long>(phdr32->p_vaddr) :
409 static_cast<unsigned long>(phdr64->p_vaddr));
412 INLINE_DEF unsigned long Elf_X_Phdr::p_paddr() const
415 static_cast<unsigned long>(phdr32->p_paddr) :
416 static_cast<unsigned long>(phdr64->p_paddr));
419 INLINE_DEF unsigned long Elf_X_Phdr::p_filesz() const
422 static_cast<unsigned long>(phdr32->p_filesz) :
423 static_cast<unsigned long>(phdr64->p_filesz));
426 INLINE_DEF unsigned long Elf_X_Phdr::p_memsz() const
429 static_cast<unsigned long>(phdr32->p_memsz) :
430 static_cast<unsigned long>(phdr64->p_memsz));
433 INLINE_DEF unsigned long Elf_X_Phdr::p_flags() const
436 static_cast<unsigned long>(phdr32->p_flags) :
437 static_cast<unsigned long>(phdr64->p_flags));
440 INLINE_DEF unsigned long Elf_X_Phdr::p_align() const
443 static_cast<unsigned long>(phdr32->p_align) :
444 static_cast<unsigned long>(phdr64->p_align));
448 INLINE_DEF void Elf_X_Phdr::p_type(unsigned long input)
450 if (!is64) phdr32->p_type = input;
451 else phdr64->p_type = input;
454 INLINE_DEF void Elf_X_Phdr::p_offset(unsigned long input)
456 if (!is64) phdr32->p_offset = input;
457 else phdr64->p_offset = input;
460 INLINE_DEF void Elf_X_Phdr::p_vaddr(unsigned long input)
462 if (!is64) phdr32->p_vaddr = input;
463 else phdr64->p_vaddr = input;
466 INLINE_DEF void Elf_X_Phdr::p_paddr(unsigned long input)
468 if (!is64) phdr32->p_paddr = input;
469 else phdr64->p_paddr = input;
472 INLINE_DEF void Elf_X_Phdr::p_filesz(unsigned long input)
474 if (!is64) phdr32->p_filesz = input;
475 else phdr64->p_filesz = input;
478 INLINE_DEF void Elf_X_Phdr::p_memsz(unsigned long input)
480 if (!is64) phdr32->p_memsz = input;
481 else phdr64->p_memsz = input;
484 INLINE_DEF void Elf_X_Phdr::p_flags(unsigned long input)
486 if (!is64) phdr32->p_flags = input;
487 else phdr64->p_flags = input;
490 INLINE_DEF void Elf_X_Phdr::p_align(unsigned long input)
492 if (!is64) phdr32->p_align = input;
493 else phdr64->p_align = input;
496 INLINE_DEF bool Elf_X_Phdr::isValid() const
498 return (phdr32 || phdr64);
501 // ------------------------------------------------------------------------
502 // Class Elf_X_Shdr simulates the Elf(32|64)_Shdr structure.
503 INLINE_DEF Elf_X_Shdr::Elf_X_Shdr()
504 : scn(NULL), data(NULL), shdr32(NULL), shdr64(NULL), is64(false),
505 fromDebugFile(false), _elf(NULL)
508 INLINE_DEF Elf_X_Shdr::Elf_X_Shdr(bool is64_, Elf_Scn *input)
509 : scn(input), data(NULL), shdr32(NULL), shdr64(NULL), is64(is64_),
510 fromDebugFile(false), _elf(NULL)
514 if (!is64) shdr32 = elf32_getshdr(scn);
515 else shdr64 = elf64_getshdr(scn);
520 INLINE_DEF unsigned long Elf_X_Shdr::sh_name() const
523 static_cast<unsigned long>(shdr32->sh_name) :
524 static_cast<unsigned long>(shdr64->sh_name));
527 INLINE_DEF unsigned long Elf_X_Shdr::sh_type() const
530 static_cast<unsigned long>(shdr32->sh_type) :
531 static_cast<unsigned long>(shdr64->sh_type));
534 INLINE_DEF unsigned long Elf_X_Shdr::sh_flags() const
537 static_cast<unsigned long>(shdr32->sh_flags) :
538 static_cast<unsigned long>(shdr64->sh_flags));
541 INLINE_DEF unsigned long Elf_X_Shdr::sh_addr() const
543 #if defined(os_vxworks)
545 if (_elf->e_type() == ET_REL) {
546 // VxWorks relocatable object files (kernel modules) don't have
547 // the address filled out. Return the disk offset instead.
549 static_cast<unsigned long>(shdr32->sh_offset) :
550 static_cast<unsigned long>(shdr64->sh_offset));
555 static_cast<unsigned long>(shdr32->sh_addr) :
556 static_cast<unsigned long>(shdr64->sh_addr));
559 INLINE_DEF unsigned long Elf_X_Shdr::sh_offset() const
562 static_cast<unsigned long>(shdr32->sh_offset) :
563 static_cast<unsigned long>(shdr64->sh_offset));
566 INLINE_DEF unsigned long Elf_X_Shdr::sh_size() const
569 static_cast<unsigned long>(shdr32->sh_size) :
570 static_cast<unsigned long>(shdr64->sh_size));
573 INLINE_DEF unsigned long Elf_X_Shdr::sh_link() const
580 INLINE_DEF unsigned long Elf_X_Shdr::sh_info() const
583 static_cast<unsigned long>(shdr32->sh_info) :
584 static_cast<unsigned long>(shdr64->sh_info));
587 INLINE_DEF unsigned long Elf_X_Shdr::sh_addralign() const
590 static_cast<unsigned long>(shdr32->sh_addralign) :
591 static_cast<unsigned long>(shdr64->sh_addralign));
594 INLINE_DEF unsigned long Elf_X_Shdr::sh_entsize() const
597 static_cast<unsigned long>(shdr32->sh_entsize) :
598 static_cast<unsigned long>(shdr64->sh_entsize));
601 INLINE_DEF bool Elf_X_Shdr::isFromDebugFile() const
603 return fromDebugFile;
607 INLINE_DEF void Elf_X_Shdr::sh_name(unsigned long input)
609 if (!is64) shdr32->sh_name = input;
610 else shdr64->sh_name = input;
613 INLINE_DEF void Elf_X_Shdr::sh_type(unsigned long input)
615 if (!is64) shdr32->sh_type = input;
616 else shdr64->sh_type = input;
619 INLINE_DEF void Elf_X_Shdr::sh_flags(unsigned long input)
621 if (!is64) shdr32->sh_flags = input;
622 else shdr64->sh_flags = input;
625 INLINE_DEF void Elf_X_Shdr::sh_addr(unsigned long input)
627 if (!is64) shdr32->sh_flags = input;
628 else shdr64->sh_flags = input;
631 INLINE_DEF void Elf_X_Shdr::sh_offset(unsigned long input)
633 if (!is64) shdr32->sh_offset = input;
634 else shdr64->sh_offset = input;
637 INLINE_DEF void Elf_X_Shdr::sh_size(unsigned long input)
639 if (!is64) shdr32->sh_size = input;
640 else shdr64->sh_size = input;
643 INLINE_DEF void Elf_X_Shdr::sh_link(unsigned long input)
645 if (!is64) shdr32->sh_link = input;
646 else shdr64->sh_link = input;
649 INLINE_DEF void Elf_X_Shdr::sh_info(unsigned long input)
651 if (!is64) shdr32->sh_info = input;
652 else shdr64->sh_info = input;
655 INLINE_DEF void Elf_X_Shdr::sh_addralign(unsigned long input)
657 if (!is64) shdr32->sh_addralign = input;
658 else shdr64->sh_addralign = input;
661 INLINE_DEF void Elf_X_Shdr::sh_entsize(unsigned long input)
663 if (!is64) shdr32->sh_entsize = input;
664 else shdr64->sh_entsize = input;
667 INLINE_DEF void Elf_X_Shdr::setDebugFile(bool b)
672 // Section Data Interface
673 INLINE_DEF Elf_X_Data Elf_X_Shdr::get_data() const
675 return Elf_X_Data(is64, data);
678 // For Sections with Multiple Data Sections
679 INLINE_DEF void Elf_X_Shdr::first_data()
681 data = elf_getdata(scn, NULL);
684 INLINE_DEF bool Elf_X_Shdr::next_data()
686 Elf_Data *nextData = elf_getdata(scn, data);
687 if (nextData) data = nextData;
691 INLINE_DEF bool Elf_X_Shdr::isValid() const
693 return (shdr32 || shdr64);
696 INLINE_DEF unsigned Elf_X_Shdr::wordSize() const
701 INLINE_DEF Elf_Scn *Elf_X_Shdr::getScn() const
706 // ------------------------------------------------------------------------
707 // Class Elf_X_Data simulates the Elf_Data structure.
708 INLINE_DEF Elf_X_Data::Elf_X_Data()
709 : data(NULL), is64(false)
712 INLINE_DEF Elf_X_Data::Elf_X_Data(bool is64_, Elf_Data *input)
713 : data(input), is64(is64_)
717 INLINE_DEF void *Elf_X_Data::d_buf() const
722 INLINE_DEF Elf_Type Elf_X_Data::d_type() const
727 INLINE_DEF unsigned int Elf_X_Data::d_version() const
729 return data->d_version;
732 INLINE_DEF size_t Elf_X_Data::d_size() const
737 INLINE_DEF off_t Elf_X_Data::d_off() const
739 return (off_t) data->d_off;
742 INLINE_DEF size_t Elf_X_Data::d_align() const
744 return data->d_align;
748 INLINE_DEF void Elf_X_Data::d_buf(void *input)
753 INLINE_DEF void Elf_X_Data::d_type(Elf_Type input)
755 data->d_type = input;
758 INLINE_DEF void Elf_X_Data::d_version(unsigned int input)
760 data->d_version = input;
763 INLINE_DEF void Elf_X_Data::d_size(unsigned int input)
765 data->d_size = input;
768 INLINE_DEF void Elf_X_Data::d_off(signed int input)
773 INLINE_DEF void Elf_X_Data::d_align(unsigned int input)
775 data->d_align = input;
779 INLINE_DEF const char *Elf_X_Data::get_string() const
781 return (const char *)data->d_buf;
784 INLINE_DEF Elf_X_Dyn Elf_X_Data::get_dyn()
786 return Elf_X_Dyn(is64, data);
789 INLINE_DEF Elf_X_Versym Elf_X_Data::get_versyms()
791 return Elf_X_Versym(is64, data);
794 INLINE_DEF Elf_X_Verneed *Elf_X_Data::get_verNeedSym()
796 return new Elf_X_Verneed(is64, data->d_buf);
799 INLINE_DEF Elf_X_Verdef *Elf_X_Data::get_verDefSym()
801 return new Elf_X_Verdef(is64, data->d_buf);
804 INLINE_DEF Elf_X_Rel Elf_X_Data::get_rel()
806 return Elf_X_Rel(is64, data);
809 INLINE_DEF Elf_X_Rela Elf_X_Data::get_rela()
811 return Elf_X_Rela(is64, data);
814 INLINE_DEF Elf_X_Sym Elf_X_Data::get_sym()
816 return Elf_X_Sym(is64, data);
819 #if defined(arch_mips)
820 INLINE_DEF Elf_X_Options Elf_X_Data::get_options()
822 return Elf_X_Options(is64, data);
826 INLINE_DEF bool Elf_X_Data::isValid() const
831 // ------------------------------------------------------------------------
832 // Class Elf_X_Versym simulates the SHT_GNU_versym structure.
833 INLINE_DEF Elf_X_Versym::Elf_X_Versym()
834 : data(NULL), versym32(NULL), versym64(NULL), is64(false)
837 INLINE_DEF Elf_X_Versym::Elf_X_Versym(bool is64_, Elf_Data *input)
838 : data(input), versym32(NULL), versym64(NULL), is64(is64_)
841 if (!is64) versym32 = (Elf32_Half *)data->d_buf;
842 else versym64 = (Elf64_Half *)data->d_buf;
847 INLINE_DEF unsigned long Elf_X_Versym::get(int i) const
849 return (!is64 ? versym32[i]
853 // Meta-Info Interface
854 INLINE_DEF unsigned long Elf_X_Versym::count() const
856 return (data->d_size / (!is64 ? sizeof(Elf32_Half)
857 : sizeof(Elf64_Half) ));
860 INLINE_DEF bool Elf_X_Versym::isValid() const
862 return (versym32 || versym64);
865 // ------------------------------------------------------------------------
866 // Class Elf_X_Verdaux simulates the Elf(32|64)_Verdaux structure.
867 INLINE_DEF Elf_X_Verdaux::Elf_X_Verdaux()
868 : data(NULL), verdaux32(NULL), verdaux64(NULL), is64(false)
871 INLINE_DEF Elf_X_Verdaux::Elf_X_Verdaux(bool is64_, void *input)
872 : data(input), verdaux32(NULL), verdaux64(NULL), is64(is64_)
875 if (!is64) verdaux32 = (Elf32_Verdaux *)data;
876 else verdaux64 = (Elf64_Verdaux *)data;
881 INLINE_DEF unsigned long Elf_X_Verdaux::vda_name() const
883 return (!is64 ? verdaux32->vda_name
884 : verdaux64->vda_name);
887 INLINE_DEF unsigned long Elf_X_Verdaux::vda_next() const
889 return (!is64 ? verdaux32->vda_next
890 : verdaux64->vda_next);
893 INLINE_DEF Elf_X_Verdaux *Elf_X_Verdaux::get_next() const
897 return new Elf_X_Verdaux(is64, (char *)data+vda_next());
900 // Meta-Info Interface
901 INLINE_DEF bool Elf_X_Verdaux::isValid() const
903 return (verdaux32 || verdaux64);
906 // ------------------------------------------------------------------------
907 // Class Elf_X_Verdef simulates the Elf(32|64)_Verdef structure.
908 INLINE_DEF Elf_X_Verdef::Elf_X_Verdef()
909 : data(NULL), verdef32(NULL), verdef64(NULL), is64(false)
912 INLINE_DEF Elf_X_Verdef::Elf_X_Verdef(bool is64_, void *input)
913 : data(input), verdef32(NULL), verdef64(NULL), is64(is64_)
916 if (!is64) verdef32 = (Elf32_Verdef *)data;
917 else verdef64 = (Elf64_Verdef *)data;
922 INLINE_DEF unsigned long Elf_X_Verdef::vd_version() const
924 return (!is64 ? verdef32->vd_version
925 : verdef64->vd_version);
928 INLINE_DEF unsigned long Elf_X_Verdef::vd_flags() const
930 return (!is64 ? verdef32->vd_flags
931 : verdef64->vd_flags);
934 INLINE_DEF unsigned long Elf_X_Verdef::vd_ndx() const
936 return (!is64 ? verdef32->vd_ndx
940 INLINE_DEF unsigned long Elf_X_Verdef::vd_cnt() const
942 return (!is64 ? verdef32->vd_cnt
946 INLINE_DEF unsigned long Elf_X_Verdef::vd_hash() const
948 return (!is64 ? verdef32->vd_hash
949 : verdef64->vd_hash);
952 INLINE_DEF unsigned long Elf_X_Verdef::vd_aux() const
954 return (!is64 ? verdef32->vd_aux
958 INLINE_DEF unsigned long Elf_X_Verdef::vd_next() const
960 return (!is64 ? verdef32->vd_next
961 : verdef64->vd_next);
964 INLINE_DEF Elf_X_Verdaux *Elf_X_Verdef::get_aux() const
968 return new Elf_X_Verdaux(is64, (char *)data+vd_aux());
971 INLINE_DEF Elf_X_Verdef *Elf_X_Verdef::get_next() const
975 return new Elf_X_Verdef(is64, (char *)data+vd_next());
978 // Meta-Info Interface
979 INLINE_DEF bool Elf_X_Verdef::isValid() const
981 return (verdef32 || verdef64);
984 // ------------------------------------------------------------------------
985 // Class Elf_X_Vernaux simulates the Elf(32|64)_Vernaux structure.
986 INLINE_DEF Elf_X_Vernaux::Elf_X_Vernaux()
987 : data(NULL), vernaux32(NULL), vernaux64(NULL), is64(false)
990 INLINE_DEF Elf_X_Vernaux::Elf_X_Vernaux(bool is64_, void *input)
991 : data(input), vernaux32(NULL), vernaux64(NULL), is64(is64_)
994 if (!is64) vernaux32 = (Elf32_Vernaux *)data;
995 else vernaux64 = (Elf64_Vernaux *)data;
1000 INLINE_DEF unsigned long Elf_X_Vernaux::vna_hash() const
1002 return (!is64 ? vernaux32->vna_hash
1003 : vernaux64->vna_hash);
1006 INLINE_DEF unsigned long Elf_X_Vernaux::vna_flags() const
1008 return (!is64 ? vernaux32->vna_flags
1009 : vernaux64->vna_flags);
1012 INLINE_DEF unsigned long Elf_X_Vernaux::vna_other() const
1014 return (!is64 ? vernaux32->vna_other
1015 : vernaux64->vna_other);
1018 INLINE_DEF unsigned long Elf_X_Vernaux::vna_name() const
1020 return (!is64 ? vernaux32->vna_name
1021 : vernaux64->vna_name);
1024 INLINE_DEF unsigned long Elf_X_Vernaux::vna_next() const
1026 return (!is64 ? vernaux32->vna_next
1027 : vernaux64->vna_next);
1030 INLINE_DEF Elf_X_Vernaux *Elf_X_Vernaux::get_next() const
1032 if (vna_next() == 0)
1034 return new Elf_X_Vernaux(is64, (char *)data+vna_next());
1037 // Meta-Info Interface
1038 INLINE_DEF bool Elf_X_Vernaux::isValid() const
1040 return (vernaux32 || vernaux64);
1043 // ------------------------------------------------------------------------
1044 // Class Elf_X_Verneed simulates the Elf(32|64)_Verneed structure.
1045 INLINE_DEF Elf_X_Verneed::Elf_X_Verneed()
1046 : data(NULL), verneed32(NULL), verneed64(NULL), is64(false)
1049 INLINE_DEF Elf_X_Verneed::Elf_X_Verneed(bool is64_, void *input)
1050 : data(input), verneed32(NULL), verneed64(NULL), is64(is64_)
1053 if (!is64) verneed32 = (Elf32_Verneed *)data;
1054 else verneed64 = (Elf64_Verneed *)data;
1059 INLINE_DEF unsigned long Elf_X_Verneed::vn_version() const
1061 return (!is64 ? verneed32->vn_version
1062 : verneed64->vn_version);
1065 INLINE_DEF unsigned long Elf_X_Verneed::vn_cnt() const
1067 return (!is64 ? verneed32->vn_cnt
1068 : verneed64->vn_cnt);
1071 INLINE_DEF unsigned long Elf_X_Verneed::vn_file() const
1073 return (!is64 ? verneed32->vn_file
1074 : verneed64->vn_file);
1077 INLINE_DEF unsigned long Elf_X_Verneed::vn_aux() const
1079 return (!is64 ? verneed32->vn_aux
1080 : verneed64->vn_aux);
1083 INLINE_DEF unsigned long Elf_X_Verneed::vn_next() const
1085 return (!is64 ? verneed32->vn_next
1086 : verneed64->vn_next);
1089 INLINE_DEF Elf_X_Vernaux *Elf_X_Verneed::get_aux() const
1093 return new Elf_X_Vernaux(is64, (char *)data+vn_aux());
1096 INLINE_DEF Elf_X_Verneed *Elf_X_Verneed::get_next() const
1100 return new Elf_X_Verneed(is64, (char *)data+vn_next());
1103 // Meta-Info Interface
1104 INLINE_DEF bool Elf_X_Verneed::isValid() const
1106 return (verneed32 || verneed64);
1110 // ------------------------------------------------------------------------
1111 // Class Elf_X_Sym simulates the Elf(32|64)_Sym structure.
1112 INLINE_DEF Elf_X_Sym::Elf_X_Sym()
1113 : data(NULL), sym32(NULL), sym64(NULL), is64(false)
1116 INLINE_DEF Elf_X_Sym::Elf_X_Sym(bool is64_, Elf_Data *input)
1117 : data(input), sym32(NULL), sym64(NULL), is64(is64_)
1120 if (!is64) sym32 = (Elf32_Sym *)data->d_buf;
1121 else sym64 = (Elf64_Sym *)data->d_buf;
1126 INLINE_DEF unsigned long Elf_X_Sym::st_name(int i) const
1129 static_cast<unsigned long>(sym32[i].st_name) :
1130 static_cast<unsigned long>(sym64[i].st_name));
1133 INLINE_DEF unsigned long Elf_X_Sym::st_value(int i) const
1136 static_cast<unsigned long>(sym32[i].st_value) :
1137 static_cast<unsigned long>(sym64[i].st_value));
1140 INLINE_DEF unsigned long Elf_X_Sym::st_size(int i) const
1143 static_cast<unsigned long>(sym32[i].st_size) :
1144 static_cast<unsigned long>(sym64[i].st_size));
1147 INLINE_DEF unsigned char Elf_X_Sym::st_info(int i) const
1154 INLINE_DEF unsigned char Elf_X_Sym::st_other(int i) const
1161 INLINE_DEF unsigned short Elf_X_Sym::st_shndx(int i) const
1168 INLINE_DEF unsigned char Elf_X_Sym::ST_BIND(int i) const
1171 static_cast<unsigned char>(ELF32_ST_BIND(sym32[i].st_info)) :
1172 static_cast<unsigned char>(ELF64_ST_BIND(sym64[i].st_info)));
1175 INLINE_DEF unsigned char Elf_X_Sym::ST_TYPE(int i) const
1178 static_cast<unsigned char>(ELF32_ST_TYPE(sym32[i].st_info)) :
1179 static_cast<unsigned char>(ELF64_ST_TYPE(sym64[i].st_info)));
1182 INLINE_DEF unsigned char Elf_X_Sym::ST_VISIBILITY(int i) const
1185 static_cast<unsigned char>(ELF32_ST_VISIBILITY(sym32[i].st_other)) :
1186 static_cast<unsigned char>(ELF64_ST_VISIBILITY(sym64[i].st_other)));
1189 INLINE_DEF void *Elf_X_Sym::st_symptr(int i) const
1192 (void *)(sym32 + i) :
1193 (void *)(sym64 + i));
1196 INLINE_DEF unsigned Elf_X_Sym::st_entsize() const
1204 INLINE_DEF void Elf_X_Sym::st_name(int i, unsigned long input)
1206 if (!is64) sym32[i].st_name = input;
1207 else sym64[i].st_name = input;
1210 INLINE_DEF void Elf_X_Sym::st_value(int i, unsigned long input)
1212 if (!is64) sym32[i].st_value = input;
1213 else sym64[i].st_value = input;
1216 INLINE_DEF void Elf_X_Sym::st_size(int i, unsigned long input)
1218 if (!is64) sym32[i].st_size = input;
1219 else sym64[i].st_size = input;
1222 INLINE_DEF void Elf_X_Sym::st_info(int i, unsigned char input)
1224 if (!is64) sym32[i].st_info = input;
1225 else sym64[i].st_info = input;
1228 INLINE_DEF void Elf_X_Sym::st_other(int i, unsigned char input)
1230 if (!is64) sym32[i].st_other = input;
1231 else sym64[i].st_other = input;
1234 INLINE_DEF void Elf_X_Sym::st_shndx(int i, unsigned short input)
1236 if (!is64) sym32[i].st_shndx = input;
1237 else sym64[i].st_shndx = input;
1240 // Meta-Info Interface
1241 INLINE_DEF unsigned long Elf_X_Sym::count() const
1243 return (data->d_size / (!is64 ? sizeof(Elf32_Sym)
1244 : sizeof(Elf64_Sym)));
1247 INLINE_DEF bool Elf_X_Sym::isValid() const
1249 return sym32 || sym64;
1252 // ------------------------------------------------------------------------
1253 // Class Elf_X_Rel simulates the Elf(32|64)_Rel structure.
1254 INLINE_DEF Elf_X_Rel::Elf_X_Rel()
1255 : data(NULL), rel32(NULL), rel64(NULL), is64(false)
1258 INLINE_DEF Elf_X_Rel::Elf_X_Rel(bool is64_, Elf_Data *input)
1259 : data(input), rel32(NULL), rel64(NULL), is64(is64_)
1263 rel32 = (Elf32_Rel *)data->d_buf;
1265 rel64 = (Elf64_Rel *)data->d_buf;
1270 INLINE_DEF unsigned long Elf_X_Rel::r_offset(int i) const
1273 static_cast<unsigned long>(rel32[i].r_offset) :
1274 static_cast<unsigned long>(rel64[i].r_offset));
1277 INLINE_DEF unsigned long Elf_X_Rel::r_info(int i) const
1280 static_cast<unsigned long>(rel32[i].r_info) :
1281 static_cast<unsigned long>(rel64[i].r_info));
1284 INLINE_DEF unsigned long Elf_X_Rel::R_SYM(int i) const
1287 static_cast<unsigned long>(ELF32_R_SYM(rel32[i].r_info)) :
1288 static_cast<unsigned long>(ELF64_R_SYM(rel64[i].r_info)));
1291 INLINE_DEF unsigned long Elf_X_Rel::R_TYPE(int i) const
1294 static_cast<unsigned long>(ELF32_R_TYPE(rel32[i].r_info)) :
1295 static_cast<unsigned long>(ELF64_R_TYPE(rel64[i].r_info)));
1299 INLINE_DEF void Elf_X_Rel::r_offset(int i, unsigned long input)
1302 rel32[i].r_offset = input;
1304 rel64[i].r_offset = input;
1307 INLINE_DEF void Elf_X_Rel::r_info(int i, unsigned long input)
1310 rel32[i].r_info = input;
1312 rel64[i].r_info = input;
1315 // Meta-Info Interface
1316 INLINE_DEF unsigned long Elf_X_Rel::count() const
1318 return (data->d_size / (!is64 ? sizeof(Elf32_Rel)
1319 : sizeof(Elf64_Rel)) );
1322 INLINE_DEF bool Elf_X_Rel::isValid() const
1324 return (rel32 || rel64);
1327 // ------------------------------------------------------------------------
1328 // Class Elf_X_Rela simulates the Elf(32|64)_Rela structure.
1329 INLINE_DEF Elf_X_Rela::Elf_X_Rela()
1330 : data(NULL), rela32(NULL), rela64(NULL), is64(false)
1333 INLINE_DEF Elf_X_Rela::Elf_X_Rela(bool is64_, Elf_Data *input)
1334 : data(input), rela32(NULL), rela64(NULL), is64(is64_)
1338 rela32 = (Elf32_Rela *)data->d_buf;
1340 rela64 = (Elf64_Rela *)data->d_buf;
1345 INLINE_DEF unsigned long Elf_X_Rela::r_offset(int i) const
1348 static_cast<unsigned long>(rela32[i].r_offset) :
1349 static_cast<unsigned long>(rela64[i].r_offset));
1352 INLINE_DEF unsigned long Elf_X_Rela::r_info(int i) const
1355 static_cast<unsigned long>(rela32[i].r_info) :
1356 static_cast<unsigned long>(rela64[i].r_info));
1359 INLINE_DEF signed long Elf_X_Rela::r_addend(int i) const
1362 static_cast<signed long>(rela32[i].r_addend) :
1363 static_cast<signed long>(rela64[i].r_addend));
1366 INLINE_DEF unsigned long Elf_X_Rela::R_SYM(int i) const
1369 static_cast<unsigned long>(ELF32_R_SYM(rela32[i].r_info)) :
1370 static_cast<unsigned long>(ELF64_R_SYM(rela64[i].r_info)));
1373 INLINE_DEF unsigned long Elf_X_Rela::R_TYPE(int i) const
1376 static_cast<unsigned long>(ELF32_R_TYPE(rela32[i].r_info)) :
1377 static_cast<unsigned long>(ELF64_R_TYPE(rela64[i].r_info)));
1381 INLINE_DEF void Elf_X_Rela::r_offset(int i, unsigned long input)
1384 rela32[i].r_offset = input;
1386 rela64[i].r_offset = input;
1389 INLINE_DEF void Elf_X_Rela::r_info(int i, unsigned long input)
1392 rela32[i].r_info = input;
1394 rela64[i].r_info = input;
1397 INLINE_DEF void Elf_X_Rela::r_addend(int i, signed long input)
1400 rela32[i].r_addend = input;
1402 rela64[i].r_addend = input;
1405 // Meta-Info Interface
1406 INLINE_DEF unsigned long Elf_X_Rela::count() const
1408 return (data->d_size / (!is64 ? sizeof(Elf32_Rela)
1409 : sizeof(Elf64_Rela)));
1412 INLINE_DEF bool Elf_X_Rela::isValid() const
1414 return (rela32 || rela64);
1418 // ------------------------------------------------------------------------
1419 // Class Elf_X_Dyn simulates the Elf(32|64)_Dyn structure.
1420 INLINE_DEF Elf_X_Dyn::Elf_X_Dyn()
1421 : data(NULL), dyn32(NULL), dyn64(NULL), is64(false)
1424 INLINE_DEF Elf_X_Dyn::Elf_X_Dyn(bool is64_, Elf_Data *input)
1425 : data(input), dyn32(NULL), dyn64(NULL), is64(is64_)
1428 if (!is64) dyn32 = (Elf32_Dyn *)data->d_buf;
1429 else dyn64 = (Elf64_Dyn *)data->d_buf;
1434 INLINE_DEF signed long Elf_X_Dyn::d_tag(int i) const
1437 static_cast<signed long>(dyn32[i].d_tag) :
1438 static_cast<signed long>(dyn64[i].d_tag));
1441 INLINE_DEF unsigned long Elf_X_Dyn::d_val(int i) const
1444 static_cast<unsigned long>(dyn32[i].d_un.d_val) :
1445 static_cast<unsigned long>(dyn64[i].d_un.d_val));
1448 INLINE_DEF unsigned long Elf_X_Dyn::d_ptr(int i) const
1451 static_cast<unsigned long>(dyn32[i].d_un.d_ptr) :
1452 static_cast<unsigned long>(dyn64[i].d_un.d_ptr));
1456 INLINE_DEF void Elf_X_Dyn::d_tag(int i, signed long input)
1458 if (!is64) dyn32[i].d_tag = input;
1459 else dyn64[i].d_tag = input;
1462 INLINE_DEF void Elf_X_Dyn::d_val(int i, unsigned long input)
1464 if (!is64) dyn32[i].d_un.d_val = input;
1465 else dyn64[i].d_un.d_val = input;
1468 INLINE_DEF void Elf_X_Dyn::d_ptr(int i, unsigned long input)
1470 if (!is64) dyn32[i].d_un.d_ptr = input;
1471 else dyn64[i].d_un.d_ptr = input;
1474 // Meta-Info Interface
1475 INLINE_DEF unsigned long Elf_X_Dyn::count() const
1477 return (data->d_size / (!is64 ? sizeof(Elf32_Dyn)
1478 : sizeof(Elf64_Dyn) ));
1481 INLINE_DEF bool Elf_X_Dyn::isValid() const
1483 return (dyn32 || dyn64);
1486 static bool loadDebugFileFromDisk(string name, char* &output_buffer, unsigned long &output_buffer_size)
1488 struct stat fileStat;
1489 int result = stat(name.c_str(), &fileStat);
1492 int fd = open(name.c_str(), O_RDONLY);
1496 char *buffer = (char *) mmap(NULL, fileStat.st_size, PROT_READ, MAP_SHARED, fd, 0);
1501 output_buffer = buffer;
1502 output_buffer_size = fileStat.st_size;
1507 // The standard procedure to look for a separate debug information file
1509 // 1. Lookup build_id from .note.gnu.build-id section and debug-file-name and
1510 // crc from .gnu_debuglink section of the original binary.
1511 // 2. Look for the following files:
1512 // /usr/lib/debug/.build-id/<path-obtained-using-build-id>.debug
1513 // <debug-file-name> in <directory-of-executable>
1514 // <debug-file-name> in <directory-of-executable>/.debug
1515 // <debug-file-name> in /usr/lib/debug/<directory-of-executable>
1516 // Reference: http://sourceware.org/gdb/current/onlinedocs/gdb_16.html#SEC157
1517 INLINE_DEF bool Elf_X::findDebugFile(std::string origfilename, string &output_name, char* &output_buffer, unsigned long &output_buffer_size)
1519 uint16_t shnames_idx = e_shstrndx();
1520 Elf_X_Shdr shnames_hdr = get_shdr(shnames_idx);
1521 if (!shnames_hdr.isValid())
1523 const char *shnames = (const char *) shnames_hdr.get_data().d_buf();
1525 string debugFileFromDebugLink, debugFileFromBuildID;
1526 unsigned debugFileCrc = 0;
1528 for(int i = 0; i < e_shnum(); i++) {
1529 Elf_X_Shdr scn = get_shdr(i);
1530 if (!scn.isValid()) { // section is malformed
1534 const char *name = &shnames[scn.sh_name()];
1535 if(strcmp(name, DEBUGLINK_NAME) == 0) {
1536 Elf_X_Data data = scn.get_data();
1537 debugFileFromDebugLink = (char *) data.d_buf();
1538 void *crcLocation = ((char *) data.d_buf() + data.d_size() - 4);
1539 debugFileCrc = *(unsigned *) crcLocation;
1541 else if(strcmp(name, BUILD_ID_NAME) == 0) {
1542 char *buildId = (char *) scn.get_data().d_buf();
1543 string filename = string(buildId + 2) + ".debug";
1544 string subdir = string(buildId, 2);
1545 debugFileFromBuildID = "/usr/lib/debug/.build-id/" + subdir + "/" + filename;
1549 if (!debugFileFromBuildID.empty()) {
1550 bool result = loadDebugFileFromDisk(debugFileFromBuildID, output_buffer, output_buffer_size);
1552 output_name = debugFileFromBuildID;
1557 if (debugFileFromDebugLink.empty())
1560 char *mfPathNameCopy = strdup(origfilename.c_str());
1561 string objectFileDirName = dirname(mfPathNameCopy);
1563 vector<string> fnames = list_of
1564 (objectFileDirName + "/" + debugFileFromDebugLink)
1565 (objectFileDirName + "/.debug/" + debugFileFromDebugLink)
1566 ("/usr/lib/debug/" + objectFileDirName + "/" + debugFileFromDebugLink);
1568 free(mfPathNameCopy);
1570 for(unsigned i = 0; i < fnames.size(); i++) {
1571 bool result = loadDebugFileFromDisk(fnames[i], output_buffer, output_buffer_size);
1575 boost::crc_32_type crcComputer;
1576 crcComputer.process_bytes(output_buffer, output_buffer_size);
1577 if(crcComputer.checksum() != debugFileCrc) {
1578 munmap(output_buffer, output_buffer_size);
1582 output_name = fnames[i];