00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <sys/mman.h>
00032 #include <sys/types.h>
00033 #include <sys/stat.h>
00034 #include <fcntl.h>
00035 #include <unistd.h>
00036 #include <libgen.h>
00037
00038 #include <boost/crc.hpp>
00039 #include <boost/assign/list_of.hpp>
00040 #include <boost/assign/std/set.hpp>
00041 #include <boost/assign/std/vector.hpp>
00042
00043 #include "common/h/headers.h"
00044 #include "elf/h/Elf_X.h"
00045 #include <iostream>
00046 #include <iomanip>
00047 #include <sstream>
00048
00049 using namespace std;
00050 using boost::crc_32_type;
00051 using namespace boost::assign;
00052
00053 using namespace Dyninst;
00054
00055 #define DEBUGLINK_NAME ".gnu_debuglink"
00056 #define BUILD_ID_NAME ".note.gnu.build-id"
00057
00058 map<pair<string, int>, Elf_X *> Elf_X::elf_x_by_fd;
00059 map<pair<string, char *>, Elf_X *> Elf_X::elf_x_by_ptr;
00060
00061 #define APPEND(X) X ## 1
00062 #define APPEND2(X) APPEND(X)
00063 #define LIBELF_TEST APPEND2(_LIBELF_H)
00064 #if (LIBELF_TEST == 11)
00065 #define USES_ELFUTILS
00066 #endif
00067
00068 Elf_X *Elf_X::newElf_X(int input, Elf_Cmd cmd, Elf_X *ref, string name)
00069 {
00070 #if defined(USES_ELFUTILS)
00071
00072 if (cmd == ELF_C_READ) {
00073 cmd = ELF_C_READ_MMAP;
00074 }
00075 #endif
00076 if (name.empty()) {
00077 return new Elf_X(input, cmd, ref);
00078 }
00079 auto i = elf_x_by_fd.find(make_pair(name, input));
00080 if (i != elf_x_by_fd.end()) {
00081 Elf_X *ret = i->second;
00082 ret->ref_count++;
00083 return ret;
00084 }
00085 Elf_X *ret = new Elf_X(input, cmd, ref);
00086 ret->filename = name;
00087 elf_x_by_fd.insert(make_pair(make_pair(name, input), ret));
00088 return ret;
00089 }
00090
00091 Elf_X *Elf_X::newElf_X(char *mem_image, size_t mem_size, string name)
00092 {
00093 if (name.empty()) {
00094 return new Elf_X(mem_image, mem_size);
00095 }
00096 auto i = elf_x_by_ptr.find(make_pair(name, mem_image));
00097 if (i != elf_x_by_ptr.end()) {
00098 Elf_X *ret = i->second;
00099
00100 ret->ref_count++;
00101 return ret;
00102 }
00103 Elf_X *ret = new Elf_X(mem_image, mem_size);
00104 ret->filename = name;
00105 elf_x_by_ptr.insert(make_pair(make_pair(name, mem_image), ret));
00106 return ret;
00107 }
00108
00109
00110
00111
00112 Elf_X::Elf_X()
00113 : elf(NULL), ehdr32(NULL), ehdr64(NULL), phdr32(NULL), phdr64(NULL),
00114 filedes(-1), is64(false), isArchive(false), ref_count(1),
00115 cached_debug_buffer(NULL), cached_debug_size(0), cached_debug(false)
00116 { }
00117
00118 Elf_X::Elf_X(int input, Elf_Cmd cmd, Elf_X *ref)
00119 : ehdr32(NULL), ehdr64(NULL), phdr32(NULL), phdr64(NULL),
00120 filedes(input), is64(false), isArchive(false), ref_count(1),
00121 cached_debug_buffer(NULL), cached_debug_size(0), cached_debug(false)
00122 {
00123 if (elf_version(EV_CURRENT) == EV_NONE) {
00124 return;
00125 }
00126 elf_errno();
00127 if (ref)
00128 elf = elf_begin(input, cmd, ref->e_elfp());
00129 else {
00130 elf = elf_begin(input, cmd, NULL);
00131 }
00132 int errnum;
00133 if ((errnum = elf_errno()) != 0) {
00134 const char *msg = elf_errmsg(errnum);
00135 fprintf(stderr, "Elf error: %s\n", msg);
00136 }
00137 if (elf) {
00138 if (elf_kind(elf) == ELF_K_ELF) {
00139 char *identp = elf_getident(elf, NULL);
00140 is64 = (identp && identp[EI_CLASS] == ELFCLASS64);
00141 }
00142 else if(elf_kind(elf) == ELF_K_AR) {
00143 char *identp = elf_getident(elf, NULL);
00144 is64 = (identp && identp[EI_CLASS] == ELFCLASS64);
00145 isArchive = true;
00146 }
00147
00148 if (!is64) ehdr32 = elf32_getehdr(elf);
00149 else ehdr64 = elf64_getehdr(elf);
00150
00151 if (!is64) phdr32 = elf32_getphdr(elf);
00152 else phdr64 = elf64_getphdr(elf);
00153 }
00154
00155 if (elf_kind(elf) == ELF_K_ELF) {
00156 size_t phdrnum = e_phnum();
00157 size_t shdrnum = e_shnum();
00158 shdrs.resize(shdrnum);
00159 phdrs.resize(phdrnum);
00160 }
00161 }
00162
00163 Elf_X::Elf_X(char *mem_image, size_t mem_size)
00164 : ehdr32(NULL), ehdr64(NULL), phdr32(NULL), phdr64(NULL),
00165 is64(false), isArchive(false), ref_count(1),
00166 cached_debug_buffer(NULL), cached_debug_size(0), cached_debug(false)
00167 {
00168 if (elf_version(EV_CURRENT) == EV_NONE) {
00169 return;
00170 }
00171
00172 elf_errno();
00173 elf = elf_memory(mem_image, mem_size);
00174
00175 int err;
00176 if ( (err = elf_errno()) != 0) {
00177
00178 }
00179
00180 if (elf) {
00181 if (elf_kind(elf) == ELF_K_ELF) {
00182 char *identp = elf_getident(elf, NULL);
00183 is64 = (identp && identp[EI_CLASS] == ELFCLASS64);
00184 }
00185
00186 if (!is64) ehdr32 = elf32_getehdr(elf);
00187 else ehdr64 = elf64_getehdr(elf);
00188
00189 if (!is64) phdr32 = elf32_getphdr(elf);
00190 else phdr64 = elf64_getphdr(elf);
00191 }
00192
00193 if (elf_kind(elf) == ELF_K_ELF) {
00194 size_t phdrnum = e_phnum();
00195 size_t shdrnum = e_shnum();
00196 shdrs.resize(shdrnum);
00197 phdrs.resize(phdrnum);
00198 }
00199 }
00200
00201 void Elf_X::end()
00202 {
00203 if (ref_count > 1) {
00204 ref_count--;
00205 return;
00206 }
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 }
00219
00220 Elf_X::~Elf_X()
00221 {
00222
00223 for (auto iter = elf_x_by_fd.begin(); iter != elf_x_by_fd.end(); ++iter) {
00224 if (iter->second == this) {
00225 elf_x_by_fd.erase(iter);
00226 return;
00227 }
00228 }
00229
00230 for (auto iter = elf_x_by_ptr.begin(); iter != elf_x_by_ptr.end(); ++iter) {
00231 if (iter->second == this) {
00232 elf_x_by_ptr.erase(iter);
00233 }
00234 }
00235 }
00236
00237
00238 Elf *Elf_X::e_elfp() const
00239 {
00240 return elf;
00241 }
00242
00243 unsigned char *Elf_X::e_ident() const
00244 {
00245 return (!is64 ?
00246 static_cast<unsigned char*>(ehdr32->e_ident) :
00247 static_cast<unsigned char*>(ehdr64->e_ident));
00248 }
00249
00250 unsigned short Elf_X::e_type() const
00251 {
00252 return (!is64 ?
00253 static_cast<unsigned short>(ehdr32->e_type) :
00254 static_cast<unsigned short>(ehdr64->e_type));
00255 }
00256
00257 unsigned short Elf_X::e_machine() const
00258 {
00259 return (!is64 ?
00260 static_cast<unsigned short>(ehdr32->e_machine) :
00261 static_cast<unsigned short>(ehdr64->e_machine));
00262 }
00263
00264 unsigned long Elf_X::e_version() const
00265 {
00266 return (!is64 ?
00267 static_cast<unsigned long>(ehdr32->e_version) :
00268 static_cast<unsigned long>(ehdr64->e_version));
00269 }
00270
00271 unsigned long Elf_X::e_entry() const
00272 {
00273 return (!is64 ?
00274 static_cast<unsigned long>(ehdr32->e_entry) :
00275 static_cast<unsigned long>(ehdr64->e_entry));
00276 }
00277
00278 unsigned long Elf_X::e_phoff() const
00279 {
00280 return (!is64 ?
00281 static_cast<unsigned long>(ehdr32->e_phoff) :
00282 static_cast<unsigned long>(ehdr64->e_phoff));
00283 }
00284
00285 unsigned long Elf_X::e_shoff() const
00286 {
00287 return (!is64 ?
00288 static_cast<unsigned long>(ehdr32->e_shoff) :
00289 static_cast<unsigned long>(ehdr64->e_shoff));
00290 }
00291
00292 unsigned long Elf_X::e_flags() const
00293 {
00294 return (!is64 ?
00295 static_cast<unsigned long>(ehdr32->e_flags) :
00296 static_cast<unsigned long>(ehdr64->e_flags));
00297 }
00298
00299 unsigned short Elf_X::e_ehsize() const
00300 {
00301 return (!is64 ?
00302 static_cast<unsigned short>(ehdr32->e_ehsize) :
00303 static_cast<unsigned short>(ehdr64->e_ehsize));
00304 }
00305
00306 unsigned short Elf_X::e_phentsize() const {
00307 return (!is64 ?
00308 static_cast<unsigned short>(ehdr32->e_phentsize) :
00309 static_cast<unsigned short>(ehdr64->e_phentsize));
00310 }
00311
00312 unsigned short Elf_X::e_phnum() const
00313 {
00314 return (!is64 ?
00315 static_cast<unsigned short>(ehdr32->e_phnum) :
00316 static_cast<unsigned short>(ehdr64->e_phnum));
00317 }
00318
00319 unsigned short Elf_X::e_shentsize() const
00320 {
00321 return (!is64 ?
00322 static_cast<unsigned short>(ehdr32->e_shentsize) :
00323 static_cast<unsigned short>(ehdr64->e_shentsize));
00324 }
00325
00326 unsigned short Elf_X::e_shnum() const
00327 {
00328 return (!is64 ?
00329 static_cast<unsigned short>(ehdr32->e_shnum) :
00330 static_cast<unsigned short>(ehdr64->e_shnum));
00331 }
00332
00333 unsigned short Elf_X::e_shstrndx() const
00334 {
00335 return (!is64 ?
00336 static_cast<unsigned short>(ehdr32->e_shstrndx) :
00337 static_cast<unsigned short>(ehdr64->e_shstrndx));
00338 }
00339
00340 const char *Elf_X::e_rawfile(size_t &nbytes) const
00341 {
00342 return elf_rawfile(elf, &nbytes);
00343 }
00344
00345 Elf_X *Elf_X::e_next(Elf_X *ref)
00346 {
00347 if (!isArchive)
00348 return NULL;
00349 Elf_Cmd cmd = elf_next(ref->e_elfp());
00350 return Elf_X::newElf_X(filedes, cmd, this);
00351 }
00352
00353 Elf_X *Elf_X::e_rand(unsigned offset)
00354 {
00355 if (!isArchive)
00356 return NULL;
00357 elf_rand(elf, offset);
00358 return Elf_X::newElf_X(filedes, ELF_C_READ, this);
00359 }
00360
00361
00362 void Elf_X::e_ident(unsigned char *input)
00363 {
00364 if (!is64) P_memcpy(ehdr32->e_ident, input, EI_NIDENT);
00365 else P_memcpy(ehdr64->e_ident, input, EI_NIDENT);
00366 }
00367
00368 void Elf_X::e_type(unsigned short input)
00369 {
00370 if (!is64) ehdr32->e_type = input;
00371 else ehdr64->e_type = input;
00372 }
00373
00374 void Elf_X::e_machine(unsigned short input)
00375 {
00376 if (!is64) ehdr32->e_machine = input;
00377 else ehdr64->e_machine = input;
00378 }
00379
00380 void Elf_X::e_version(unsigned long input)
00381 {
00382 if (!is64) ehdr32->e_version = input;
00383 else ehdr64->e_version = input;
00384 }
00385
00386 void Elf_X::e_entry(unsigned long input)
00387 {
00388 if (!is64) ehdr32->e_entry = input;
00389 else ehdr64->e_entry = input;
00390 }
00391
00392 void Elf_X::e_phoff(unsigned long input)
00393 {
00394 if (!is64) ehdr32->e_phoff = input;
00395 else ehdr64->e_phoff = input;
00396 }
00397
00398 void Elf_X::e_shoff(unsigned long input)
00399 {
00400 if (!is64) ehdr32->e_shoff = input;
00401 else ehdr64->e_shoff = input;
00402 }
00403
00404 void Elf_X::e_flags(unsigned long input)
00405 {
00406 if (!is64) ehdr32->e_flags = input;
00407 else ehdr64->e_flags = input;
00408 }
00409
00410 void Elf_X::e_ehsize(unsigned short input)
00411 {
00412 if (!is64) ehdr32->e_ehsize = input;
00413 else ehdr64->e_ehsize = input;
00414 }
00415
00416 void Elf_X::e_phentsize(unsigned short input)
00417 {
00418 if (!is64) ehdr32->e_phentsize = input;
00419 else ehdr64->e_phentsize = input;
00420 }
00421
00422 void Elf_X::e_phnum(unsigned short input)
00423 {
00424 if (!is64) ehdr32->e_phnum = input;
00425 else ehdr64->e_phnum = input;
00426 }
00427
00428 void Elf_X::e_shentsize(unsigned short input)
00429 {
00430 if (!is64) ehdr32->e_shentsize = input;
00431 else ehdr64->e_shentsize = input;
00432 }
00433
00434 void Elf_X::e_shnum(unsigned short input)
00435 {
00436 if (!is64) ehdr32->e_shnum = input;
00437 else ehdr64->e_shnum = input;
00438 }
00439
00440 void Elf_X::e_shstrndx(unsigned short input)
00441 {
00442 if (!is64) ehdr32->e_shstrndx = input;
00443 else ehdr64->e_shstrndx = input;
00444 }
00445
00446
00447 bool Elf_X::isValid() const
00448 {
00449 return (ehdr32 || ehdr64);
00450 }
00451
00452 int Elf_X::wordSize() const
00453 {
00454 return (!is64 ? 4 : 8);
00455 }
00456
00457 Elf_X_Phdr &Elf_X::get_phdr(unsigned int i)
00458 {
00459 if (is64 && !phdrs[i].phdr64) {
00460 phdrs[i] = Elf_X_Phdr(is64, phdr64 + i);
00461 }
00462 else if (!is64 && !phdrs[i].phdr32) {
00463 phdrs[i] = Elf_X_Phdr(is64, phdr32 + i);
00464 }
00465 return phdrs[i];
00466 }
00467
00468 Elf_X_Shdr &Elf_X::get_shdr(unsigned int i)
00469 {
00470 if (!shdrs[i]._elf) {
00471 Elf_Scn *scn = elf_getscn(elf, i);
00472 shdrs[i] = Elf_X_Shdr(is64, scn);
00473 shdrs[i]._elf = this;
00474 }
00475 return shdrs[i];
00476 }
00477
00478
00479
00480 Elf_X_Phdr::Elf_X_Phdr()
00481 : phdr32(NULL), phdr64(NULL), is64(false)
00482 { }
00483
00484 Elf_X_Phdr::Elf_X_Phdr(bool is64_, void *input)
00485 : phdr32(NULL), phdr64(NULL), is64(is64_)
00486 {
00487 if (input) {
00488 if (!is64) phdr32 = (Elf32_Phdr *)input;
00489 else phdr64 = (Elf64_Phdr *)input;
00490 }
00491 }
00492
00493
00494 unsigned long Elf_X_Phdr::p_type() const
00495 {
00496 return (!is64 ?
00497 static_cast<unsigned long>(phdr32->p_type) :
00498 static_cast<unsigned long>(phdr64->p_type));
00499 }
00500
00501 unsigned long Elf_X_Phdr::p_offset() const
00502 {
00503 return (!is64 ?
00504 static_cast<unsigned long>(phdr32->p_offset) :
00505 static_cast<unsigned long>(phdr64->p_offset));
00506 }
00507
00508 unsigned long Elf_X_Phdr::p_vaddr() const
00509 {
00510 return (!is64 ?
00511 static_cast<unsigned long>(phdr32->p_vaddr) :
00512 static_cast<unsigned long>(phdr64->p_vaddr));
00513 }
00514
00515 unsigned long Elf_X_Phdr::p_paddr() const
00516 {
00517 return (!is64 ?
00518 static_cast<unsigned long>(phdr32->p_paddr) :
00519 static_cast<unsigned long>(phdr64->p_paddr));
00520 }
00521
00522 unsigned long Elf_X_Phdr::p_filesz() const
00523 {
00524 return (!is64 ?
00525 static_cast<unsigned long>(phdr32->p_filesz) :
00526 static_cast<unsigned long>(phdr64->p_filesz));
00527 }
00528
00529 unsigned long Elf_X_Phdr::p_memsz() const
00530 {
00531 return (!is64 ?
00532 static_cast<unsigned long>(phdr32->p_memsz) :
00533 static_cast<unsigned long>(phdr64->p_memsz));
00534 }
00535
00536 unsigned long Elf_X_Phdr::p_flags() const
00537 {
00538 return (!is64 ?
00539 static_cast<unsigned long>(phdr32->p_flags) :
00540 static_cast<unsigned long>(phdr64->p_flags));
00541 }
00542
00543 unsigned long Elf_X_Phdr::p_align() const
00544 {
00545 return (!is64 ?
00546 static_cast<unsigned long>(phdr32->p_align) :
00547 static_cast<unsigned long>(phdr64->p_align));
00548 }
00549
00550
00551 void Elf_X_Phdr::p_type(unsigned long input)
00552 {
00553 if (!is64) phdr32->p_type = input;
00554 else phdr64->p_type = input;
00555 }
00556
00557 void Elf_X_Phdr::p_offset(unsigned long input)
00558 {
00559 if (!is64) phdr32->p_offset = input;
00560 else phdr64->p_offset = input;
00561 }
00562
00563 void Elf_X_Phdr::p_vaddr(unsigned long input)
00564 {
00565 if (!is64) phdr32->p_vaddr = input;
00566 else phdr64->p_vaddr = input;
00567 }
00568
00569 void Elf_X_Phdr::p_paddr(unsigned long input)
00570 {
00571 if (!is64) phdr32->p_paddr = input;
00572 else phdr64->p_paddr = input;
00573 }
00574
00575 void Elf_X_Phdr::p_filesz(unsigned long input)
00576 {
00577 if (!is64) phdr32->p_filesz = input;
00578 else phdr64->p_filesz = input;
00579 }
00580
00581 void Elf_X_Phdr::p_memsz(unsigned long input)
00582 {
00583 if (!is64) phdr32->p_memsz = input;
00584 else phdr64->p_memsz = input;
00585 }
00586
00587 void Elf_X_Phdr::p_flags(unsigned long input)
00588 {
00589 if (!is64) phdr32->p_flags = input;
00590 else phdr64->p_flags = input;
00591 }
00592
00593 void Elf_X_Phdr::p_align(unsigned long input)
00594 {
00595 if (!is64) phdr32->p_align = input;
00596 else phdr64->p_align = input;
00597 }
00598
00599 bool Elf_X_Phdr::isValid() const
00600 {
00601 return (phdr32 || phdr64);
00602 }
00603
00604
00605
00606 Elf_X_Shdr::Elf_X_Shdr()
00607 : scn(NULL), data(NULL), shdr32(NULL), shdr64(NULL), is64(false),
00608 fromDebugFile(false), _elf(NULL)
00609 { }
00610
00611 Elf_X_Shdr::Elf_X_Shdr(bool is64_, Elf_Scn *input)
00612 : scn(input), data(NULL), shdr32(NULL), shdr64(NULL), is64(is64_),
00613 fromDebugFile(false), _elf(NULL)
00614 {
00615 if (input) {
00616 first_data();
00617 if (!is64) shdr32 = elf32_getshdr(scn);
00618 else shdr64 = elf64_getshdr(scn);
00619 }
00620 }
00621
00622
00623 unsigned long Elf_X_Shdr::sh_name() const
00624 {
00625 return (!is64 ?
00626 static_cast<unsigned long>(shdr32->sh_name) :
00627 static_cast<unsigned long>(shdr64->sh_name));
00628 }
00629
00630 unsigned long Elf_X_Shdr::sh_type() const
00631 {
00632 return (!is64 ?
00633 static_cast<unsigned long>(shdr32->sh_type) :
00634 static_cast<unsigned long>(shdr64->sh_type));
00635 }
00636
00637 unsigned long Elf_X_Shdr::sh_flags() const
00638 {
00639 return (!is64 ?
00640 static_cast<unsigned long>(shdr32->sh_flags) :
00641 static_cast<unsigned long>(shdr64->sh_flags));
00642 }
00643
00644 unsigned long Elf_X_Shdr::sh_addr() const
00645 {
00646 #if defined(os_vxworks)
00647 assert(_elf);
00648 if (_elf->e_type() == ET_REL) {
00649
00650
00651 return (!is64 ?
00652 static_cast<unsigned long>(shdr32->sh_offset) :
00653 static_cast<unsigned long>(shdr64->sh_offset));
00654 }
00655 #endif
00656
00657 return (!is64 ?
00658 static_cast<unsigned long>(shdr32->sh_addr) :
00659 static_cast<unsigned long>(shdr64->sh_addr));
00660 }
00661
00662 unsigned long Elf_X_Shdr::sh_offset() const
00663 {
00664 return (!is64 ?
00665 static_cast<unsigned long>(shdr32->sh_offset) :
00666 static_cast<unsigned long>(shdr64->sh_offset));
00667 }
00668
00669 unsigned long Elf_X_Shdr::sh_size() const
00670 {
00671 return (!is64 ?
00672 static_cast<unsigned long>(shdr32->sh_size) :
00673 static_cast<unsigned long>(shdr64->sh_size));
00674 }
00675
00676 unsigned long Elf_X_Shdr::sh_link() const
00677 {
00678 return (!is64 ?
00679 shdr32->sh_link :
00680 shdr64->sh_link);
00681 }
00682
00683 unsigned long Elf_X_Shdr::sh_info() const
00684 {
00685 return (!is64 ?
00686 static_cast<unsigned long>(shdr32->sh_info) :
00687 static_cast<unsigned long>(shdr64->sh_info));
00688 }
00689
00690 unsigned long Elf_X_Shdr::sh_addralign() const
00691 {
00692 return (!is64 ?
00693 static_cast<unsigned long>(shdr32->sh_addralign) :
00694 static_cast<unsigned long>(shdr64->sh_addralign));
00695 }
00696
00697 unsigned long Elf_X_Shdr::sh_entsize() const
00698 {
00699 return (!is64 ?
00700 static_cast<unsigned long>(shdr32->sh_entsize) :
00701 static_cast<unsigned long>(shdr64->sh_entsize));
00702 }
00703
00704 bool Elf_X_Shdr::isFromDebugFile() const
00705 {
00706 return fromDebugFile;
00707 }
00708
00709
00710 void Elf_X_Shdr::sh_name(unsigned long input)
00711 {
00712 if (!is64) shdr32->sh_name = input;
00713 else shdr64->sh_name = input;
00714 }
00715
00716 void Elf_X_Shdr::sh_type(unsigned long input)
00717 {
00718 if (!is64) shdr32->sh_type = input;
00719 else shdr64->sh_type = input;
00720 }
00721
00722 void Elf_X_Shdr::sh_flags(unsigned long input)
00723 {
00724 if (!is64) shdr32->sh_flags = input;
00725 else shdr64->sh_flags = input;
00726 }
00727
00728 void Elf_X_Shdr::sh_addr(unsigned long input)
00729 {
00730 if (!is64) shdr32->sh_flags = input;
00731 else shdr64->sh_flags = input;
00732 }
00733
00734 void Elf_X_Shdr::sh_offset(unsigned long input)
00735 {
00736 if (!is64) shdr32->sh_offset = input;
00737 else shdr64->sh_offset = input;
00738 }
00739
00740 void Elf_X_Shdr::sh_size(unsigned long input)
00741 {
00742 if (!is64) shdr32->sh_size = input;
00743 else shdr64->sh_size = input;
00744 }
00745
00746 void Elf_X_Shdr::sh_link(unsigned long input)
00747 {
00748 if (!is64) shdr32->sh_link = input;
00749 else shdr64->sh_link = input;
00750 }
00751
00752 void Elf_X_Shdr::sh_info(unsigned long input)
00753 {
00754 if (!is64) shdr32->sh_info = input;
00755 else shdr64->sh_info = input;
00756 }
00757
00758 void Elf_X_Shdr::sh_addralign(unsigned long input)
00759 {
00760 if (!is64) shdr32->sh_addralign = input;
00761 else shdr64->sh_addralign = input;
00762 }
00763
00764 void Elf_X_Shdr::sh_entsize(unsigned long input)
00765 {
00766 if (!is64) shdr32->sh_entsize = input;
00767 else shdr64->sh_entsize = input;
00768 }
00769
00770 void Elf_X_Shdr::setDebugFile(bool b)
00771 {
00772 fromDebugFile = b;
00773 }
00774
00775
00776 Elf_X_Data Elf_X_Shdr::get_data() const
00777 {
00778 return Elf_X_Data(is64, data);
00779 }
00780
00781
00782 void Elf_X_Shdr::first_data()
00783 {
00784 data = elf_getdata(scn, NULL);
00785 }
00786
00787 bool Elf_X_Shdr::next_data()
00788 {
00789 Elf_Data *nextData = elf_getdata(scn, data);
00790 if (nextData) data = nextData;
00791 return nextData;
00792 }
00793
00794 bool Elf_X_Shdr::isValid() const
00795 {
00796 return (shdr32 || shdr64);
00797 }
00798
00799 unsigned Elf_X_Shdr::wordSize() const
00800 {
00801 return is64 ? 8 : 4;
00802 }
00803
00804 Elf_Scn *Elf_X_Shdr::getScn() const
00805 {
00806 return scn;
00807 }
00808
00809 Elf_X_Nhdr Elf_X_Shdr::get_note() const
00810 {
00811 if (sh_type() != SHT_NOTE)
00812 return Elf_X_Nhdr();
00813 return Elf_X_Nhdr(data, 0);
00814 }
00815
00816
00817
00818 Elf_X_Data::Elf_X_Data()
00819 : data(NULL), is64(false)
00820 { }
00821
00822 Elf_X_Data::Elf_X_Data(bool is64_, Elf_Data *input)
00823 : data(input), is64(is64_)
00824 { }
00825
00826
00827 void *Elf_X_Data::d_buf() const
00828 {
00829 return data->d_buf;
00830 }
00831
00832 Elf_Type Elf_X_Data::d_type() const
00833 {
00834 return data->d_type;
00835 }
00836
00837 unsigned int Elf_X_Data::d_version() const
00838 {
00839 return data->d_version;
00840 }
00841
00842 size_t Elf_X_Data::d_size() const
00843 {
00844 return data->d_size;
00845 }
00846
00847 off_t Elf_X_Data::d_off() const
00848 {
00849 return (off_t) data->d_off;
00850 }
00851
00852 size_t Elf_X_Data::d_align() const
00853 {
00854 return data->d_align;
00855 }
00856
00857
00858 void Elf_X_Data::d_buf(void *input)
00859 {
00860 data->d_buf = input;
00861 }
00862
00863 void Elf_X_Data::d_type(Elf_Type input)
00864 {
00865 data->d_type = input;
00866 }
00867
00868 void Elf_X_Data::d_version(unsigned int input)
00869 {
00870 data->d_version = input;
00871 }
00872
00873 void Elf_X_Data::d_size(unsigned int input)
00874 {
00875 data->d_size = input;
00876 }
00877
00878 void Elf_X_Data::d_off(signed int input)
00879 {
00880 data->d_off = input;
00881 }
00882
00883 void Elf_X_Data::d_align(unsigned int input)
00884 {
00885 data->d_align = input;
00886 }
00887
00888
00889 const char *Elf_X_Data::get_string() const
00890 {
00891 return (const char *)data->d_buf;
00892 }
00893
00894 Elf_X_Dyn Elf_X_Data::get_dyn()
00895 {
00896 return Elf_X_Dyn(is64, data);
00897 }
00898
00899 Elf_X_Versym Elf_X_Data::get_versyms()
00900 {
00901 return Elf_X_Versym(is64, data);
00902 }
00903
00904 Elf_X_Verneed *Elf_X_Data::get_verNeedSym()
00905 {
00906 return new Elf_X_Verneed(is64, data->d_buf);
00907 }
00908
00909 Elf_X_Verdef *Elf_X_Data::get_verDefSym()
00910 {
00911 return new Elf_X_Verdef(is64, data->d_buf);
00912 }
00913
00914 Elf_X_Rel Elf_X_Data::get_rel()
00915 {
00916 return Elf_X_Rel(is64, data);
00917 }
00918
00919 Elf_X_Rela Elf_X_Data::get_rela()
00920 {
00921 return Elf_X_Rela(is64, data);
00922 }
00923
00924 Elf_X_Sym Elf_X_Data::get_sym()
00925 {
00926 return Elf_X_Sym(is64, data);
00927 }
00928
00929 #if defined(arch_mips)
00930 Elf_X_Options Elf_X_Data::get_options()
00931 {
00932 return Elf_X_Options(is64, data);
00933 }
00934 #endif
00935
00936 bool Elf_X_Data::isValid() const
00937 {
00938 return data;
00939 }
00940
00941
00942
00943 Elf_X_Versym::Elf_X_Versym()
00944 : data(NULL), versym32(NULL), versym64(NULL), is64(false)
00945 { }
00946
00947 Elf_X_Versym::Elf_X_Versym(bool is64_, Elf_Data *input)
00948 : data(input), versym32(NULL), versym64(NULL), is64(is64_)
00949 {
00950 if (input) {
00951 if (!is64) versym32 = (Elf32_Half *)data->d_buf;
00952 else versym64 = (Elf64_Half *)data->d_buf;
00953 }
00954 }
00955
00956
00957 unsigned long Elf_X_Versym::get(int i) const
00958 {
00959 return (!is64 ? versym32[i]
00960 : versym64[i]);
00961 }
00962
00963
00964 unsigned long Elf_X_Versym::count() const
00965 {
00966 return (data->d_size / (!is64 ? sizeof(Elf32_Half)
00967 : sizeof(Elf64_Half) ));
00968 }
00969
00970 bool Elf_X_Versym::isValid() const
00971 {
00972 return (versym32 || versym64);
00973 }
00974
00975
00976
00977 Elf_X_Verdaux::Elf_X_Verdaux()
00978 : data(NULL), verdaux32(NULL), verdaux64(NULL), is64(false)
00979 { }
00980
00981 Elf_X_Verdaux::Elf_X_Verdaux(bool is64_, void *input)
00982 : data(input), verdaux32(NULL), verdaux64(NULL), is64(is64_)
00983 {
00984 if (input) {
00985 if (!is64) verdaux32 = (Elf32_Verdaux *)data;
00986 else verdaux64 = (Elf64_Verdaux *)data;
00987 }
00988 }
00989
00990
00991 unsigned long Elf_X_Verdaux::vda_name() const
00992 {
00993 return (!is64 ? verdaux32->vda_name
00994 : verdaux64->vda_name);
00995 }
00996
00997 unsigned long Elf_X_Verdaux::vda_next() const
00998 {
00999 return (!is64 ? verdaux32->vda_next
01000 : verdaux64->vda_next);
01001 }
01002
01003 Elf_X_Verdaux *Elf_X_Verdaux::get_next() const
01004 {
01005 if (vda_next() == 0)
01006 return NULL;
01007 return new Elf_X_Verdaux(is64, (char *)data+vda_next());
01008 }
01009
01010
01011 bool Elf_X_Verdaux::isValid() const
01012 {
01013 return (verdaux32 || verdaux64);
01014 }
01015
01016
01017
01018 Elf_X_Verdef::Elf_X_Verdef()
01019 : data(NULL), verdef32(NULL), verdef64(NULL), is64(false)
01020 { }
01021
01022 Elf_X_Verdef::Elf_X_Verdef(bool is64_, void *input)
01023 : data(input), verdef32(NULL), verdef64(NULL), is64(is64_)
01024 {
01025 if (input) {
01026 if (!is64) verdef32 = (Elf32_Verdef *)data;
01027 else verdef64 = (Elf64_Verdef *)data;
01028 }
01029 }
01030
01031
01032 unsigned long Elf_X_Verdef::vd_version() const
01033 {
01034 return (!is64 ? verdef32->vd_version
01035 : verdef64->vd_version);
01036 }
01037
01038 unsigned long Elf_X_Verdef::vd_flags() const
01039 {
01040 return (!is64 ? verdef32->vd_flags
01041 : verdef64->vd_flags);
01042 }
01043
01044 unsigned long Elf_X_Verdef::vd_ndx() const
01045 {
01046 return (!is64 ? verdef32->vd_ndx
01047 : verdef64->vd_ndx);
01048 }
01049
01050 unsigned long Elf_X_Verdef::vd_cnt() const
01051 {
01052 return (!is64 ? verdef32->vd_cnt
01053 : verdef64->vd_cnt);
01054 }
01055
01056 unsigned long Elf_X_Verdef::vd_hash() const
01057 {
01058 return (!is64 ? verdef32->vd_hash
01059 : verdef64->vd_hash);
01060 }
01061
01062 unsigned long Elf_X_Verdef::vd_aux() const
01063 {
01064 return (!is64 ? verdef32->vd_aux
01065 : verdef64->vd_aux);
01066 }
01067
01068 unsigned long Elf_X_Verdef::vd_next() const
01069 {
01070 return (!is64 ? verdef32->vd_next
01071 : verdef64->vd_next);
01072 }
01073
01074 Elf_X_Verdaux *Elf_X_Verdef::get_aux() const
01075 {
01076 if (vd_cnt() == 0)
01077 return NULL;
01078 return new Elf_X_Verdaux(is64, (char *)data+vd_aux());
01079 }
01080
01081 Elf_X_Verdef *Elf_X_Verdef::get_next() const
01082 {
01083 if (vd_next() == 0)
01084 return NULL;
01085 return new Elf_X_Verdef(is64, (char *)data+vd_next());
01086 }
01087
01088
01089 bool Elf_X_Verdef::isValid() const
01090 {
01091 return (verdef32 || verdef64);
01092 }
01093
01094
01095
01096 Elf_X_Vernaux::Elf_X_Vernaux()
01097 : data(NULL), vernaux32(NULL), vernaux64(NULL), is64(false)
01098 { }
01099
01100 Elf_X_Vernaux::Elf_X_Vernaux(bool is64_, void *input)
01101 : data(input), vernaux32(NULL), vernaux64(NULL), is64(is64_)
01102 {
01103 if (input) {
01104 if (!is64) vernaux32 = (Elf32_Vernaux *)data;
01105 else vernaux64 = (Elf64_Vernaux *)data;
01106 }
01107 }
01108
01109
01110 unsigned long Elf_X_Vernaux::vna_hash() const
01111 {
01112 return (!is64 ? vernaux32->vna_hash
01113 : vernaux64->vna_hash);
01114 }
01115
01116 unsigned long Elf_X_Vernaux::vna_flags() const
01117 {
01118 return (!is64 ? vernaux32->vna_flags
01119 : vernaux64->vna_flags);
01120 }
01121
01122 unsigned long Elf_X_Vernaux::vna_other() const
01123 {
01124 return (!is64 ? vernaux32->vna_other
01125 : vernaux64->vna_other);
01126 }
01127
01128 unsigned long Elf_X_Vernaux::vna_name() const
01129 {
01130 return (!is64 ? vernaux32->vna_name
01131 : vernaux64->vna_name);
01132 }
01133
01134 unsigned long Elf_X_Vernaux::vna_next() const
01135 {
01136 return (!is64 ? vernaux32->vna_next
01137 : vernaux64->vna_next);
01138 }
01139
01140 Elf_X_Vernaux *Elf_X_Vernaux::get_next() const
01141 {
01142 if (vna_next() == 0)
01143 return NULL;
01144 return new Elf_X_Vernaux(is64, (char *)data+vna_next());
01145 }
01146
01147
01148 bool Elf_X_Vernaux::isValid() const
01149 {
01150 return (vernaux32 || vernaux64);
01151 }
01152
01153
01154
01155 Elf_X_Verneed::Elf_X_Verneed()
01156 : data(NULL), verneed32(NULL), verneed64(NULL), is64(false)
01157 { }
01158
01159 Elf_X_Verneed::Elf_X_Verneed(bool is64_, void *input)
01160 : data(input), verneed32(NULL), verneed64(NULL), is64(is64_)
01161 {
01162 if (input) {
01163 if (!is64) verneed32 = (Elf32_Verneed *)data;
01164 else verneed64 = (Elf64_Verneed *)data;
01165 }
01166 }
01167
01168
01169 unsigned long Elf_X_Verneed::vn_version() const
01170 {
01171 return (!is64 ? verneed32->vn_version
01172 : verneed64->vn_version);
01173 }
01174
01175 unsigned long Elf_X_Verneed::vn_cnt() const
01176 {
01177 return (!is64 ? verneed32->vn_cnt
01178 : verneed64->vn_cnt);
01179 }
01180
01181 unsigned long Elf_X_Verneed::vn_file() const
01182 {
01183 return (!is64 ? verneed32->vn_file
01184 : verneed64->vn_file);
01185 }
01186
01187 unsigned long Elf_X_Verneed::vn_aux() const
01188 {
01189 return (!is64 ? verneed32->vn_aux
01190 : verneed64->vn_aux);
01191 }
01192
01193 unsigned long Elf_X_Verneed::vn_next() const
01194 {
01195 return (!is64 ? verneed32->vn_next
01196 : verneed64->vn_next);
01197 }
01198
01199 Elf_X_Vernaux *Elf_X_Verneed::get_aux() const
01200 {
01201 if (vn_cnt() == 0)
01202 return NULL;
01203 return new Elf_X_Vernaux(is64, (char *)data+vn_aux());
01204 }
01205
01206 Elf_X_Verneed *Elf_X_Verneed::get_next() const
01207 {
01208 if (vn_next() == 0)
01209 return NULL;
01210 return new Elf_X_Verneed(is64, (char *)data+vn_next());
01211 }
01212
01213
01214 bool Elf_X_Verneed::isValid() const
01215 {
01216 return (verneed32 || verneed64);
01217 }
01218
01219
01220
01221
01222 Elf_X_Sym::Elf_X_Sym()
01223 : data(NULL), sym32(NULL), sym64(NULL), is64(false)
01224 { }
01225
01226 Elf_X_Sym::Elf_X_Sym(bool is64_, Elf_Data *input)
01227 : data(input), sym32(NULL), sym64(NULL), is64(is64_)
01228 {
01229 if (input) {
01230 if (!is64) sym32 = (Elf32_Sym *)data->d_buf;
01231 else sym64 = (Elf64_Sym *)data->d_buf;
01232 }
01233 }
01234
01235
01236 unsigned long Elf_X_Sym::st_name(int i) const
01237 {
01238 return (!is64 ?
01239 static_cast<unsigned long>(sym32[i].st_name) :
01240 static_cast<unsigned long>(sym64[i].st_name));
01241 }
01242
01243 unsigned long Elf_X_Sym::st_value(int i) const
01244 {
01245 return (!is64 ?
01246 static_cast<unsigned long>(sym32[i].st_value) :
01247 static_cast<unsigned long>(sym64[i].st_value));
01248 }
01249
01250 unsigned long Elf_X_Sym::st_size(int i) const
01251 {
01252 return (!is64 ?
01253 static_cast<unsigned long>(sym32[i].st_size) :
01254 static_cast<unsigned long>(sym64[i].st_size));
01255 }
01256
01257 unsigned char Elf_X_Sym::st_info(int i) const
01258 {
01259 return (!is64 ?
01260 sym32[i].st_info :
01261 sym64[i].st_info);
01262 }
01263
01264 unsigned char Elf_X_Sym::st_other(int i) const
01265 {
01266 return (!is64 ?
01267 sym32[i].st_other :
01268 sym64[i].st_other);
01269 }
01270
01271 unsigned short Elf_X_Sym::st_shndx(int i) const
01272 {
01273 return (!is64 ?
01274 sym32[i].st_shndx :
01275 sym64[i].st_shndx);
01276 }
01277
01278 unsigned char Elf_X_Sym::ST_BIND(int i) const
01279 {
01280 return (!is64 ?
01281 static_cast<unsigned char>(ELF32_ST_BIND(sym32[i].st_info)) :
01282 static_cast<unsigned char>(ELF64_ST_BIND(sym64[i].st_info)));
01283 }
01284
01285 unsigned char Elf_X_Sym::ST_TYPE(int i) const
01286 {
01287 return (!is64 ?
01288 static_cast<unsigned char>(ELF32_ST_TYPE(sym32[i].st_info)) :
01289 static_cast<unsigned char>(ELF64_ST_TYPE(sym64[i].st_info)));
01290 }
01291
01292 unsigned char Elf_X_Sym::ST_VISIBILITY(int i) const
01293 {
01294 return (!is64 ?
01295 static_cast<unsigned char>(ELF32_ST_VISIBILITY(sym32[i].st_other)) :
01296 static_cast<unsigned char>(ELF64_ST_VISIBILITY(sym64[i].st_other)));
01297 }
01298
01299 void *Elf_X_Sym::st_symptr(int i) const
01300 {
01301 return (!is64 ?
01302 (void *)(sym32 + i) :
01303 (void *)(sym64 + i));
01304 }
01305
01306 unsigned Elf_X_Sym::st_entsize() const
01307 {
01308 return (is64 ?
01309 sizeof(Elf64_Sym) :
01310 sizeof(Elf32_Sym));
01311 }
01312
01313
01314 void Elf_X_Sym::st_name(int i, unsigned long input)
01315 {
01316 if (!is64) sym32[i].st_name = input;
01317 else sym64[i].st_name = input;
01318 }
01319
01320 void Elf_X_Sym::st_value(int i, unsigned long input)
01321 {
01322 if (!is64) sym32[i].st_value = input;
01323 else sym64[i].st_value = input;
01324 }
01325
01326 void Elf_X_Sym::st_size(int i, unsigned long input)
01327 {
01328 if (!is64) sym32[i].st_size = input;
01329 else sym64[i].st_size = input;
01330 }
01331
01332 void Elf_X_Sym::st_info(int i, unsigned char input)
01333 {
01334 if (!is64) sym32[i].st_info = input;
01335 else sym64[i].st_info = input;
01336 }
01337
01338 void Elf_X_Sym::st_other(int i, unsigned char input)
01339 {
01340 if (!is64) sym32[i].st_other = input;
01341 else sym64[i].st_other = input;
01342 }
01343
01344 void Elf_X_Sym::st_shndx(int i, unsigned short input)
01345 {
01346 if (!is64) sym32[i].st_shndx = input;
01347 else sym64[i].st_shndx = input;
01348 }
01349
01350
01351 unsigned long Elf_X_Sym::count() const
01352 {
01353 return (data->d_size / (!is64 ? sizeof(Elf32_Sym)
01354 : sizeof(Elf64_Sym)));
01355 }
01356
01357 bool Elf_X_Sym::isValid() const
01358 {
01359 return sym32 || sym64;
01360 }
01361
01362
01363
01364 Elf_X_Rel::Elf_X_Rel()
01365 : data(NULL), rel32(NULL), rel64(NULL), is64(false)
01366 { }
01367
01368 Elf_X_Rel::Elf_X_Rel(bool is64_, Elf_Data *input)
01369 : data(input), rel32(NULL), rel64(NULL), is64(is64_)
01370 {
01371 if (input) {
01372 if (!is64)
01373 rel32 = (Elf32_Rel *)data->d_buf;
01374 else
01375 rel64 = (Elf64_Rel *)data->d_buf;
01376 }
01377 }
01378
01379
01380 unsigned long Elf_X_Rel::r_offset(int i) const
01381 {
01382 return (!is64 ?
01383 static_cast<unsigned long>(rel32[i].r_offset) :
01384 static_cast<unsigned long>(rel64[i].r_offset));
01385 }
01386
01387 unsigned long Elf_X_Rel::r_info(int i) const
01388 {
01389 return (!is64 ?
01390 static_cast<unsigned long>(rel32[i].r_info) :
01391 static_cast<unsigned long>(rel64[i].r_info));
01392 }
01393
01394 unsigned long Elf_X_Rel::R_SYM(int i) const
01395 {
01396 return (!is64 ?
01397 static_cast<unsigned long>(ELF32_R_SYM(rel32[i].r_info)) :
01398 static_cast<unsigned long>(ELF64_R_SYM(rel64[i].r_info)));
01399 }
01400
01401 unsigned long Elf_X_Rel::R_TYPE(int i) const
01402 {
01403 return (!is64 ?
01404 static_cast<unsigned long>(ELF32_R_TYPE(rel32[i].r_info)) :
01405 static_cast<unsigned long>(ELF64_R_TYPE(rel64[i].r_info)));
01406 };
01407
01408
01409 void Elf_X_Rel::r_offset(int i, unsigned long input)
01410 {
01411 if (!is64)
01412 rel32[i].r_offset = input;
01413 else
01414 rel64[i].r_offset = input;
01415 }
01416
01417 void Elf_X_Rel::r_info(int i, unsigned long input)
01418 {
01419 if (!is64)
01420 rel32[i].r_info = input;
01421 else
01422 rel64[i].r_info = input;
01423 }
01424
01425
01426 unsigned long Elf_X_Rel::count() const
01427 {
01428 return (data->d_size / (!is64 ? sizeof(Elf32_Rel)
01429 : sizeof(Elf64_Rel)) );
01430 }
01431
01432 bool Elf_X_Rel::isValid() const
01433 {
01434 return (rel32 || rel64);
01435 }
01436
01437
01438
01439 Elf_X_Rela::Elf_X_Rela()
01440 : data(NULL), rela32(NULL), rela64(NULL), is64(false)
01441 { }
01442
01443 Elf_X_Rela::Elf_X_Rela(bool is64_, Elf_Data *input)
01444 : data(input), rela32(NULL), rela64(NULL), is64(is64_)
01445 {
01446 if (input) {
01447 if (!is64)
01448 rela32 = (Elf32_Rela *)data->d_buf;
01449 else
01450 rela64 = (Elf64_Rela *)data->d_buf;
01451 }
01452 }
01453
01454
01455 unsigned long Elf_X_Rela::r_offset(int i) const
01456 {
01457 return (!is64 ?
01458 static_cast<unsigned long>(rela32[i].r_offset) :
01459 static_cast<unsigned long>(rela64[i].r_offset));
01460 }
01461
01462 unsigned long Elf_X_Rela::r_info(int i) const
01463 {
01464 return (!is64 ?
01465 static_cast<unsigned long>(rela32[i].r_info) :
01466 static_cast<unsigned long>(rela64[i].r_info));
01467 }
01468
01469 signed long Elf_X_Rela::r_addend(int i) const
01470 {
01471 return (!is64 ?
01472 static_cast<signed long>(rela32[i].r_addend) :
01473 static_cast<signed long>(rela64[i].r_addend));
01474 }
01475
01476 unsigned long Elf_X_Rela::R_SYM(int i) const
01477 {
01478 return (!is64 ?
01479 static_cast<unsigned long>(ELF32_R_SYM(rela32[i].r_info)) :
01480 static_cast<unsigned long>(ELF64_R_SYM(rela64[i].r_info)));
01481 }
01482
01483 unsigned long Elf_X_Rela::R_TYPE(int i) const
01484 {
01485 return (!is64 ?
01486 static_cast<unsigned long>(ELF32_R_TYPE(rela32[i].r_info)) :
01487 static_cast<unsigned long>(ELF64_R_TYPE(rela64[i].r_info)));
01488 }
01489
01490
01491 void Elf_X_Rela::r_offset(int i, unsigned long input)
01492 {
01493 if (!is64)
01494 rela32[i].r_offset = input;
01495 else
01496 rela64[i].r_offset = input;
01497 }
01498
01499 void Elf_X_Rela::r_info(int i, unsigned long input)
01500 {
01501 if (!is64)
01502 rela32[i].r_info = input;
01503 else
01504 rela64[i].r_info = input;
01505 }
01506
01507 void Elf_X_Rela::r_addend(int i, signed long input)
01508 {
01509 if (!is64)
01510 rela32[i].r_addend = input;
01511 else
01512 rela64[i].r_addend = input;
01513 }
01514
01515
01516 unsigned long Elf_X_Rela::count() const
01517 {
01518 return (data->d_size / (!is64 ? sizeof(Elf32_Rela)
01519 : sizeof(Elf64_Rela)));
01520 }
01521
01522 bool Elf_X_Rela::isValid() const
01523 {
01524 return (rela32 || rela64);
01525 }
01526
01527
01528
01529
01530 Elf_X_Dyn::Elf_X_Dyn()
01531 : data(NULL), dyn32(NULL), dyn64(NULL), is64(false)
01532 { }
01533
01534 Elf_X_Dyn::Elf_X_Dyn(bool is64_, Elf_Data *input)
01535 : data(input), dyn32(NULL), dyn64(NULL), is64(is64_)
01536 {
01537 if (input) {
01538 if (!is64) dyn32 = (Elf32_Dyn *)data->d_buf;
01539 else dyn64 = (Elf64_Dyn *)data->d_buf;
01540 }
01541 }
01542
01543
01544 signed long Elf_X_Dyn::d_tag(int i) const
01545 {
01546 return (!is64 ?
01547 static_cast<signed long>(dyn32[i].d_tag) :
01548 static_cast<signed long>(dyn64[i].d_tag));
01549 }
01550
01551 unsigned long Elf_X_Dyn::d_val(int i) const
01552 {
01553 return (!is64 ?
01554 static_cast<unsigned long>(dyn32[i].d_un.d_val) :
01555 static_cast<unsigned long>(dyn64[i].d_un.d_val));
01556 }
01557
01558 unsigned long Elf_X_Dyn::d_ptr(int i) const
01559 {
01560 return (!is64 ?
01561 static_cast<unsigned long>(dyn32[i].d_un.d_ptr) :
01562 static_cast<unsigned long>(dyn64[i].d_un.d_ptr));
01563 }
01564
01565
01566 void Elf_X_Dyn::d_tag(int i, signed long input)
01567 {
01568 if (!is64) dyn32[i].d_tag = input;
01569 else dyn64[i].d_tag = input;
01570 }
01571
01572 void Elf_X_Dyn::d_val(int i, unsigned long input)
01573 {
01574 if (!is64) dyn32[i].d_un.d_val = input;
01575 else dyn64[i].d_un.d_val = input;
01576 }
01577
01578 void Elf_X_Dyn::d_ptr(int i, unsigned long input)
01579 {
01580 if (!is64) dyn32[i].d_un.d_ptr = input;
01581 else dyn64[i].d_un.d_ptr = input;
01582 }
01583
01584
01585 unsigned long Elf_X_Dyn::count() const
01586 {
01587 return (data->d_size / (!is64 ? sizeof(Elf32_Dyn)
01588 : sizeof(Elf64_Dyn) ));
01589 }
01590
01591 bool Elf_X_Dyn::isValid() const
01592 {
01593 return (dyn32 || dyn64);
01594 }
01595
01596 static bool loadDebugFileFromDisk(string name, char* &output_buffer, unsigned long &output_buffer_size)
01597 {
01598 struct stat fileStat;
01599 int result = stat(name.c_str(), &fileStat);
01600 if (result == -1)
01601 return false;
01602 if (S_ISDIR(fileStat.st_mode))
01603 return false;
01604 int fd = open(name.c_str(), O_RDONLY);
01605 if (fd == -1)
01606 return false;
01607
01608 char *buffer = (char *) mmap(NULL, fileStat.st_size, PROT_READ, MAP_SHARED, fd, 0);
01609 close(fd);
01610 if (!buffer)
01611 return false;
01612
01613 output_buffer = buffer;
01614 output_buffer_size = fileStat.st_size;
01615
01616 return true;
01617 }
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629 bool Elf_X::findDebugFile(std::string origfilename, string &output_name, char* &output_buffer, unsigned long &output_buffer_size)
01630 {
01631 if (cached_debug) {
01632 output_buffer = cached_debug_buffer;
01633 output_buffer_size = cached_debug_size;
01634 output_name = cached_debug_name;
01635 return (output_buffer != NULL);
01636 }
01637 cached_debug = true;
01638
01639 uint16_t shnames_idx = e_shstrndx();
01640 Elf_X_Shdr shnames_hdr = get_shdr(shnames_idx);
01641 if (!shnames_hdr.isValid())
01642 return false;
01643 const char *shnames = (const char *) shnames_hdr.get_data().d_buf();
01644
01645 string debugFileFromDebugLink, debugFileFromBuildID;
01646 unsigned debugFileCrc = 0;
01647
01648 for(int i = 0; i < e_shnum(); i++) {
01649 Elf_X_Shdr scn = get_shdr(i);
01650 if (!scn.isValid()) {
01651 continue;
01652 }
01653
01654 const char *name = &shnames[scn.sh_name()];
01655 if(strcmp(name, DEBUGLINK_NAME) == 0) {
01656 Elf_X_Data data = scn.get_data();
01657 debugFileFromDebugLink = (char *) data.d_buf();
01658 void *crcLocation = ((char *) data.d_buf() + data.d_size() - 4);
01659 debugFileCrc = *(unsigned *) crcLocation;
01660 }
01661 else if (scn.sh_type() == SHT_NOTE) {
01662
01663
01664 for (Elf_X_Nhdr note = scn.get_note();
01665 note.isValid(); note = note.next()) {
01666 if (note.n_type() == 3
01667 && note.n_namesz() == sizeof("GNU")
01668 && strcmp(note.get_name(), "GNU") == 0
01669 && note.n_descsz() >= 2) {
01670
01671 const unsigned char *desc = (const unsigned char *)note.get_desc();
01672 stringstream buildid_path;
01673 buildid_path << "/usr/lib/debug/.build-id/"
01674 << hex << setfill('0') << setw(2) << (unsigned)desc[0] << '/';
01675 for (unsigned long j = 1; j < note.n_descsz(); ++j)
01676 buildid_path << (unsigned)desc[j];
01677 buildid_path << ".debug";
01678 debugFileFromBuildID = buildid_path.str();
01679 break;
01680 }
01681 }
01682 }
01683 }
01684
01685 if (!debugFileFromBuildID.empty()) {
01686 bool result = loadDebugFileFromDisk(debugFileFromBuildID, output_buffer, output_buffer_size);
01687 if (result) {
01688 output_name = debugFileFromBuildID;
01689 cached_debug_buffer = output_buffer;
01690 cached_debug_size = output_buffer_size;
01691 cached_debug_name = output_name;
01692 return true;
01693 }
01694 }
01695
01696 if (debugFileFromDebugLink.empty())
01697 return false;
01698
01699 char *mfPathNameCopy = strdup(origfilename.c_str());
01700 string objectFileDirName = dirname(mfPathNameCopy);
01701
01702 vector<string> fnames = list_of
01703 (objectFileDirName + "/" + debugFileFromDebugLink)
01704 (objectFileDirName + "/.debug/" + debugFileFromDebugLink)
01705 ("/usr/lib/debug/" + objectFileDirName + "/" + debugFileFromDebugLink);
01706
01707 free(mfPathNameCopy);
01708
01709 for(unsigned i = 0; i < fnames.size(); i++) {
01710 bool result = loadDebugFileFromDisk(fnames[i], output_buffer, output_buffer_size);
01711 if (!result)
01712 continue;
01713
01714 boost::crc_32_type crcComputer;
01715 crcComputer.process_bytes(output_buffer, output_buffer_size);
01716 if(crcComputer.checksum() != debugFileCrc) {
01717 munmap(output_buffer, output_buffer_size);
01718 continue;
01719 }
01720
01721 output_name = fnames[i];
01722 cached_debug_buffer = output_buffer;
01723 cached_debug_size = output_buffer_size;
01724 cached_debug_name = output_name;
01725 return true;
01726 }
01727
01728 return false;
01729 }
01730
01731
01732
01733 Elf_X_Nhdr::Elf_X_Nhdr()
01734 : data(NULL), nhdr(NULL)
01735 { }
01736
01737 Elf_X_Nhdr::Elf_X_Nhdr(Elf_Data *data_, size_t offset)
01738 : data(data_), nhdr(NULL)
01739 {
01740
01741 assert(sizeof(Elf32_Nhdr) == sizeof(Elf64_Nhdr));
01742
01743 if (data && offset < data->d_size) {
01744 size_t size = data->d_size - offset;
01745 if (sizeof(*nhdr) <= size) {
01746 size -= sizeof(*nhdr);
01747 nhdr = (Elf32_Nhdr *)((char *)data->d_buf + offset);
01748 if (n_namesz() > size || n_descsz() > size - n_namesz())
01749 nhdr = NULL;
01750 }
01751 }
01752 if (!nhdr)
01753 data = NULL;
01754 }
01755
01756
01757 unsigned long Elf_X_Nhdr::n_namesz() const
01758 {
01759 return isValid() ? nhdr->n_namesz : 0;
01760 }
01761
01762 unsigned long Elf_X_Nhdr::n_descsz() const
01763 {
01764 return isValid() ? nhdr->n_descsz : 0;
01765 }
01766
01767 unsigned long Elf_X_Nhdr::n_type() const
01768 {
01769 return isValid() ? nhdr->n_type : 0;
01770 }
01771
01772 bool Elf_X_Nhdr::isValid() const
01773 {
01774 return (data && nhdr);
01775 }
01776
01777 const char* Elf_X_Nhdr::get_name() const
01778 {
01779 return isValid() ? (char *)nhdr + sizeof(*nhdr) : NULL;
01780 }
01781
01782 const void* Elf_X_Nhdr::get_desc() const
01783 {
01784 return isValid() ? get_name() + n_namesz() : NULL;
01785 }
01786
01787 Elf_X_Nhdr Elf_X_Nhdr::next() const
01788 {
01789 if (!isValid())
01790 return Elf_X_Nhdr();
01791
01792 size_t offset = (char *)get_desc() + n_descsz() - (char *)data->d_buf;
01793 return Elf_X_Nhdr(data, offset);
01794 }