| 552 | } |
| 553 | |
| 554 | static int |
| 555 | parse_dynamic(elf_file_t ef) |
| 556 | { |
| 557 | Elf_Dyn *dp; |
| 558 | int plttype = DT_REL; |
| 559 | |
| 560 | for (dp = ef->dynamic; dp->d_tag != DT_NULL; dp++) { |
| 561 | switch (dp->d_tag) { |
| 562 | case DT_HASH: |
| 563 | { |
| 564 | /* From src/libexec/rtld-elf/rtld.c */ |
| 565 | const Elf_Hashelt *hashtab = (const Elf_Hashelt *) |
| 566 | (ef->address + dp->d_un.d_ptr); |
| 567 | ef->nbuckets = hashtab[0]; |
| 568 | ef->nchains = hashtab[1]; |
| 569 | ef->buckets = hashtab + 2; |
| 570 | ef->chains = ef->buckets + ef->nbuckets; |
| 571 | break; |
| 572 | } |
| 573 | case DT_STRTAB: |
| 574 | ef->strtab = (caddr_t) (ef->address + dp->d_un.d_ptr); |
| 575 | break; |
| 576 | case DT_STRSZ: |
| 577 | ef->strsz = dp->d_un.d_val; |
| 578 | break; |
| 579 | case DT_SYMTAB: |
| 580 | ef->symtab = (Elf_Sym*) (ef->address + dp->d_un.d_ptr); |
| 581 | break; |
| 582 | case DT_SYMENT: |
| 583 | if (dp->d_un.d_val != sizeof(Elf_Sym)) |
| 584 | return (ENOEXEC); |
| 585 | break; |
| 586 | case DT_PLTGOT: |
| 587 | ef->got = (Elf_Addr *) (ef->address + dp->d_un.d_ptr); |
| 588 | break; |
| 589 | case DT_REL: |
| 590 | ef->rel = (const Elf_Rel *) (ef->address + dp->d_un.d_ptr); |
| 591 | break; |
| 592 | case DT_RELSZ: |
| 593 | ef->relsize = dp->d_un.d_val; |
| 594 | break; |
| 595 | case DT_RELENT: |
| 596 | if (dp->d_un.d_val != sizeof(Elf_Rel)) |
| 597 | return (ENOEXEC); |
| 598 | break; |
| 599 | case DT_JMPREL: |
| 600 | ef->pltrel = (const Elf_Rel *) (ef->address + dp->d_un.d_ptr); |
| 601 | break; |
| 602 | case DT_PLTRELSZ: |
| 603 | ef->pltrelsize = dp->d_un.d_val; |
| 604 | break; |
| 605 | case DT_RELA: |
| 606 | ef->rela = (const Elf_Rela *) (ef->address + dp->d_un.d_ptr); |
| 607 | break; |
| 608 | case DT_RELASZ: |
| 609 | ef->relasize = dp->d_un.d_val; |
| 610 | break; |
| 611 | case DT_RELAENT: |
no test coverage detected