| 495 | } |
| 496 | |
| 497 | static int |
| 498 | write_elf(const struct rmod_context *ctx, const struct buffer *in, |
| 499 | struct buffer *out) |
| 500 | { |
| 501 | int ret; |
| 502 | int bit64; |
| 503 | size_t loc; |
| 504 | size_t rmod_data_size; |
| 505 | struct elf_writer *ew; |
| 506 | struct buffer rmod_data; |
| 507 | struct buffer rmod_header; |
| 508 | struct buffer program; |
| 509 | struct buffer relocs; |
| 510 | Elf64_Xword total_size; |
| 511 | Elf64_Addr addr; |
| 512 | Elf64_Ehdr ehdr; |
| 513 | |
| 514 | if (ctx->nsegments != 1) { |
| 515 | ERROR("Multiple loadable segments is not supported.\n"); |
| 516 | return -1; |
| 517 | } |
| 518 | |
| 519 | bit64 = ctx->pelf.ehdr.e_ident[EI_CLASS] == ELFCLASS64; |
| 520 | |
| 521 | /* |
| 522 | * 3 sections will be added to the ELF file. |
| 523 | * +------------------+ |
| 524 | * | rmodule header | |
| 525 | * +------------------+ |
| 526 | * | program | |
| 527 | * +------------------+ |
| 528 | * | relocations | |
| 529 | * +------------------+ |
| 530 | */ |
| 531 | |
| 532 | /* Create buffer for header and relocations. */ |
| 533 | rmod_data_size = sizeof(struct rmodule_header); |
| 534 | if (bit64) |
| 535 | rmod_data_size += ctx->nrelocs * sizeof(Elf64_Addr); |
| 536 | else |
| 537 | rmod_data_size += ctx->nrelocs * sizeof(Elf32_Addr); |
| 538 | |
| 539 | if (buffer_create(&rmod_data, rmod_data_size, "rmod")) |
| 540 | return -1; |
| 541 | |
| 542 | buffer_splice(&rmod_header, &rmod_data, |
| 543 | 0, sizeof(struct rmodule_header)); |
| 544 | buffer_clone(&relocs, &rmod_data); |
| 545 | buffer_seek(&relocs, sizeof(struct rmodule_header)); |
| 546 | |
| 547 | /* Reset current location. */ |
| 548 | buffer_set_size(&rmod_header, 0); |
| 549 | buffer_set_size(&relocs, 0); |
| 550 | |
| 551 | /* Program contents. */ |
| 552 | buffer_splice(&program, in, ctx->phdr->p_offset, ctx->phdr->p_filesz); |
| 553 | |
| 554 | /* Create ELF writer. Set entry point to 0 to match section offsets. */ |
no test coverage detected