| 186 | */ |
| 187 | |
| 188 | static int for_each_reloc(struct rmod_context *ctx, struct reloc_filter *f, |
| 189 | int do_emit) |
| 190 | { |
| 191 | Elf64_Half i; |
| 192 | struct parsed_elf *pelf = &ctx->pelf; |
| 193 | |
| 194 | for (i = 0; i < pelf->ehdr.e_shnum; i++) { |
| 195 | Elf64_Shdr *shdr; |
| 196 | Elf64_Rela *relocs; |
| 197 | Elf64_Xword nrelocs; |
| 198 | Elf64_Xword j; |
| 199 | |
| 200 | relocs = pelf->relocs[i]; |
| 201 | |
| 202 | /* No relocations in this section. */ |
| 203 | if (relocs == NULL) |
| 204 | continue; |
| 205 | |
| 206 | shdr = &pelf->shdr[i]; |
| 207 | nrelocs = shdr->sh_size / shdr->sh_entsize; |
| 208 | |
| 209 | for (j = 0; j < nrelocs; j++) { |
| 210 | int filter_emit = 1; |
| 211 | Elf64_Rela *r = &relocs[j]; |
| 212 | |
| 213 | if (!ctx->ops->valid_type(r)) { |
| 214 | ERROR("Invalid reloc type: %u\n", |
| 215 | (unsigned int)ELF64_R_TYPE(r->r_info)); |
| 216 | if ((ctx->ops->arch == EM_X86_64) && |
| 217 | (ELF64_R_TYPE(r->r_info) == R_AMD64_32S)) |
| 218 | ERROR("Illegal use of 32bit sign extended addressing at offset 0x%x\n", |
| 219 | (unsigned int)r->r_offset); |
| 220 | return -1; |
| 221 | } |
| 222 | |
| 223 | if (relocation_for_absolute_symbol(ctx, r)) |
| 224 | continue; |
| 225 | |
| 226 | if (relocation_for_weak_extern_symbols(ctx, r)) |
| 227 | continue; |
| 228 | |
| 229 | if (relocation_for_undefined_symbol(ctx, r)) |
| 230 | continue; |
| 231 | |
| 232 | /* Allow the provided filter to have precedence. */ |
| 233 | if (f != NULL) { |
| 234 | filter_emit = f->filter(f, r); |
| 235 | |
| 236 | if (filter_emit < 0) |
| 237 | return filter_emit; |
| 238 | } |
| 239 | |
| 240 | if (filter_emit && ctx->ops->should_emit(r)) { |
| 241 | int n = ctx->nrelocs; |
| 242 | if (do_emit) |
| 243 | ctx->emitted_relocs[n] = r->r_offset; |
| 244 | ctx->nrelocs++; |
| 245 | } |
no test coverage detected