| 367 | } |
| 368 | |
| 369 | int rmodule_collect_relocations(struct rmod_context *ctx, |
| 370 | struct reloc_filter *f) |
| 371 | { |
| 372 | Elf64_Xword nrelocs; |
| 373 | |
| 374 | /* |
| 375 | * The relocs array in the pelf should only contain relocations that |
| 376 | * apply to the program. Count the number relocations. Then collect |
| 377 | * them into the allocated buffer. |
| 378 | */ |
| 379 | if (for_each_reloc(ctx, f, 0)) |
| 380 | return -1; |
| 381 | |
| 382 | nrelocs = ctx->nrelocs; |
| 383 | INFO("%" PRIu64 " relocations to be emitted.\n", nrelocs); |
| 384 | if (!nrelocs) |
| 385 | return 0; |
| 386 | |
| 387 | /* Reset the counter for indexing into the array. */ |
| 388 | ctx->nrelocs = 0; |
| 389 | ctx->emitted_relocs = calloc(nrelocs, sizeof(Elf64_Addr)); |
| 390 | /* Write out the relocations into the emitted_relocs array. */ |
| 391 | if (for_each_reloc(ctx, f, 1)) |
| 392 | return -1; |
| 393 | |
| 394 | if (ctx->nrelocs != nrelocs) { |
| 395 | ERROR("Mismatch counted and emitted relocations: %zu vs %zu.\n", |
| 396 | (size_t)nrelocs, (size_t)ctx->nrelocs); |
| 397 | return -1; |
| 398 | } |
| 399 | |
| 400 | /* Sort the relocations by their address. */ |
| 401 | qsort(ctx->emitted_relocs, nrelocs, sizeof(Elf64_Addr), vaddr_cmp); |
| 402 | |
| 403 | return 0; |
| 404 | } |
| 405 | |
| 406 | static int |
| 407 | populate_sym(struct rmod_context *ctx, const char *sym_name, Elf64_Addr *addr, |
no test coverage detected