| 418 | } |
| 419 | |
| 420 | int ElfView::getElfInfo(ElfInfo &info) const { |
| 421 | info.handle = static_cast<const uint8_t *>(mRva.address); |
| 422 | info.ehdr = info.handle; |
| 423 | if (mPointerSize == 4) { |
| 424 | info.shdr = (const void *) (info.handle + ((const Elf32_Ehdr *) info.ehdr)->e_shoff); |
| 425 | info.phdr = (const void *) (info.handle + ((const Elf32_Ehdr *) info.ehdr)->e_phoff); |
| 426 | info.shstr = nullptr; |
| 427 | Elf32_Phdr *dynamic = nullptr; |
| 428 | Elf32_Word size = 0; |
| 429 | if (!getSegmentInfoFromFileMemMap32(info, PT_DYNAMIC, |
| 430 | const_cast<const Elf32_Phdr **>(&dynamic), &size, &info.dyn)) { |
| 431 | return 0; |
| 432 | } |
| 433 | if (!dynamic) { |
| 434 | return 0; |
| 435 | } |
| 436 | info.dyn_size = size / sizeof(Elf32_Dyn); |
| 437 | const auto *dyn = static_cast<const Elf32_Dyn *>(info.dyn); |
| 438 | for (int i = 0; i < info.dyn_size; i++, dyn++) { |
| 439 | switch (dyn->d_tag) { |
| 440 | case DT_SYMTAB: |
| 441 | info.symtab = reinterpret_cast<const Elf32_Sym *>(info.handle + dyn->d_un.d_ptr); |
| 442 | break; |
| 443 | case DT_STRTAB: |
| 444 | info.symstr = reinterpret_cast<const char *>(info.handle + dyn->d_un.d_ptr); |
| 445 | break; |
| 446 | case DT_PLTREL: |
| 447 | info.use_rela = dyn->d_un.d_val == DT_RELA; |
| 448 | break; |
| 449 | case DT_REL: |
| 450 | case DT_RELA: |
| 451 | info.reldyn = reinterpret_cast<const Elf32_Rel *>(info.handle + dyn->d_un.d_ptr); |
| 452 | break; |
| 453 | case DT_RELSZ: |
| 454 | case DT_RELASZ: |
| 455 | info.reldyn_size = uint32_t(dyn->d_un.d_val / sizeof(Elf32_Rel)); |
| 456 | break; |
| 457 | case DT_JMPREL: |
| 458 | info.relplt = reinterpret_cast<const Elf32_Rel *>(info.handle + dyn->d_un.d_ptr); |
| 459 | break; |
| 460 | case DT_PLTRELSZ: |
| 461 | info.relplt_size = dyn->d_un.d_val / sizeof(Elf32_Rel); |
| 462 | break; |
| 463 | case DT_HASH: { |
| 464 | const auto *rawdata = reinterpret_cast<const uint32_t *>(info.handle + dyn->d_un.d_ptr); |
| 465 | info.nbucket = rawdata[0]; |
| 466 | info.nchain = rawdata[1]; |
| 467 | info.bucket = rawdata + 2; |
| 468 | info.chain = info.bucket + info.nbucket; |
| 469 | info.sym_size = info.nchain; |
| 470 | break; |
| 471 | } |
| 472 | case DT_GNU_HASH: { |
| 473 | info.gnu_hash = reinterpret_cast<const void *>(info.handle + dyn->d_un.d_ptr); |
| 474 | break; |
| 475 | } |
| 476 | default: |
| 477 | break; |
nothing calls this directly
no test coverage detected