* helper function, find executable section by name. */
| 132 | * helper function, find executable section by name. |
| 133 | */ |
| 134 | static int |
| 135 | find_elf_code(Elf *elf, const char *section, Elf_Data **psd, size_t *pidx) |
| 136 | { |
| 137 | Elf_Scn *sc; |
| 138 | const Elf64_Ehdr *eh; |
| 139 | const Elf64_Shdr *sh; |
| 140 | Elf_Data *sd; |
| 141 | const char *sn; |
| 142 | int32_t rc; |
| 143 | |
| 144 | eh = elf64_getehdr(elf); |
| 145 | if (eh == NULL) { |
| 146 | rc = elf_errno(); |
| 147 | RTE_BPF_LOG(ERR, "%s(%p, %s) error code: %d(%s)\n", |
| 148 | __func__, elf, section, rc, elf_errmsg(rc)); |
| 149 | return -EINVAL; |
| 150 | } |
| 151 | |
| 152 | if (check_elf_header(eh) != 0) |
| 153 | return -EINVAL; |
| 154 | |
| 155 | /* find given section by name */ |
| 156 | for (sc = elf_nextscn(elf, NULL); sc != NULL; |
| 157 | sc = elf_nextscn(elf, sc)) { |
| 158 | sh = elf64_getshdr(sc); |
| 159 | sn = elf_strptr(elf, eh->e_shstrndx, sh->sh_name); |
| 160 | if (sn != NULL && strcmp(section, sn) == 0 && |
| 161 | sh->sh_type == SHT_PROGBITS && |
| 162 | sh->sh_flags == (SHF_ALLOC | SHF_EXECINSTR)) |
| 163 | break; |
| 164 | } |
| 165 | |
| 166 | sd = elf_getdata(sc, NULL); |
| 167 | if (sd == NULL || sd->d_size == 0 || |
| 168 | sd->d_size % sizeof(struct ebpf_insn) != 0) { |
| 169 | rc = elf_errno(); |
| 170 | RTE_BPF_LOG(ERR, "%s(%p, %s) error code: %d(%s)\n", |
| 171 | __func__, elf, section, rc, elf_errmsg(rc)); |
| 172 | return -EINVAL; |
| 173 | } |
| 174 | |
| 175 | *psd = sd; |
| 176 | *pidx = elf_ndxscn(sc); |
| 177 | return 0; |
| 178 | } |
| 179 | |
| 180 | /* |
| 181 | * helper function to process data from relocation table. |
no test coverage detected