| 1644 | } |
| 1645 | |
| 1646 | static int |
| 1647 | link_elf_reloc_local(linker_file_t lf, bool ifuncs) |
| 1648 | { |
| 1649 | elf_file_t ef = (elf_file_t)lf; |
| 1650 | const Elf_Rel *rellim; |
| 1651 | const Elf_Rel *rel; |
| 1652 | const Elf_Rela *relalim; |
| 1653 | const Elf_Rela *rela; |
| 1654 | const Elf_Sym *sym; |
| 1655 | Elf_Addr base; |
| 1656 | int i; |
| 1657 | Elf_Size symidx; |
| 1658 | |
| 1659 | link_elf_fix_link_set(ef); |
| 1660 | |
| 1661 | /* Perform relocations without addend if there are any: */ |
| 1662 | for (i = 0; i < ef->nreltab; i++) { |
| 1663 | rel = ef->reltab[i].rel; |
| 1664 | if (rel == NULL) { |
| 1665 | link_elf_error(ef->lf.filename, "lost a reltab"); |
| 1666 | return (ENOEXEC); |
| 1667 | } |
| 1668 | rellim = rel + ef->reltab[i].nrel; |
| 1669 | base = findbase(ef, ef->reltab[i].sec); |
| 1670 | if (base == 0) { |
| 1671 | link_elf_error(ef->lf.filename, "lost base for reltab"); |
| 1672 | return (ENOEXEC); |
| 1673 | } |
| 1674 | for ( ; rel < rellim; rel++) { |
| 1675 | symidx = ELF_R_SYM(rel->r_info); |
| 1676 | if (symidx >= ef->ddbsymcnt) |
| 1677 | continue; |
| 1678 | sym = ef->ddbsymtab + symidx; |
| 1679 | /* Only do local relocs */ |
| 1680 | if (ELF_ST_BIND(sym->st_info) != STB_LOCAL) |
| 1681 | continue; |
| 1682 | if ((ELF_ST_TYPE(sym->st_info) == STT_GNU_IFUNC || |
| 1683 | elf_is_ifunc_reloc(rel->r_info)) != ifuncs) |
| 1684 | continue; |
| 1685 | if (elf_reloc_local(lf, base, rel, ELF_RELOC_REL, |
| 1686 | elf_obj_lookup) != 0) |
| 1687 | return (ENOEXEC); |
| 1688 | } |
| 1689 | } |
| 1690 | |
| 1691 | /* Perform relocations with addend if there are any: */ |
| 1692 | for (i = 0; i < ef->nrelatab; i++) { |
| 1693 | rela = ef->relatab[i].rela; |
| 1694 | if (rela == NULL) { |
| 1695 | link_elf_error(ef->lf.filename, "lost a relatab!"); |
| 1696 | return (ENOEXEC); |
| 1697 | } |
| 1698 | relalim = rela + ef->relatab[i].nrela; |
| 1699 | base = findbase(ef, ef->relatab[i].sec); |
| 1700 | if (base == 0) { |
| 1701 | link_elf_error(ef->lf.filename, "lost base for reltab"); |
| 1702 | return (ENOEXEC); |
| 1703 | } |
no test coverage detected