| 669 | } |
| 670 | |
| 671 | int rmodule_init(struct rmod_context *ctx, const struct buffer *elfin) |
| 672 | { |
| 673 | struct parsed_elf *pelf; |
| 674 | size_t i; |
| 675 | int ret; |
| 676 | |
| 677 | ret = -1; |
| 678 | memset(ctx, 0, sizeof(*ctx)); |
| 679 | pelf = &ctx->pelf; |
| 680 | |
| 681 | if (parse_elf(elfin, pelf, ELF_PARSE_ALL)) { |
| 682 | ERROR("Couldn't parse ELF!\n"); |
| 683 | return -1; |
| 684 | } |
| 685 | |
| 686 | /* Only allow executables to be turned into rmodules. */ |
| 687 | if (pelf->ehdr.e_type != ET_EXEC) { |
| 688 | ERROR("ELF is not an executable: %u.\n", pelf->ehdr.e_type); |
| 689 | goto out; |
| 690 | } |
| 691 | |
| 692 | /* Determine if architecture is supported. */ |
| 693 | for (i = 0; i < ARRAY_SIZE(reloc_ops); i++) { |
| 694 | if (reloc_ops[i].arch == pelf->ehdr.e_machine) { |
| 695 | ctx->ops = &reloc_ops[i]; |
| 696 | break; |
| 697 | } |
| 698 | } |
| 699 | |
| 700 | if (ctx->ops == NULL) { |
| 701 | ERROR("ELF is unsupported arch: %u.\n", pelf->ehdr.e_machine); |
| 702 | goto out; |
| 703 | } |
| 704 | |
| 705 | /* Set the endian ops. */ |
| 706 | if (ctx->pelf.ehdr.e_ident[EI_DATA] == ELFDATA2MSB) |
| 707 | ctx->xdr = &xdr_be; |
| 708 | else |
| 709 | ctx->xdr = &xdr_le; |
| 710 | |
| 711 | /* Obtain the string table. */ |
| 712 | for (i = 0; i < pelf->ehdr.e_shnum; i++) { |
| 713 | if (pelf->strtabs[i] == NULL) |
| 714 | continue; |
| 715 | /* Don't use the section headers' string table. */ |
| 716 | if (i == pelf->ehdr.e_shstrndx) |
| 717 | continue; |
| 718 | ctx->strtab = buffer_get(pelf->strtabs[i]); |
| 719 | break; |
| 720 | } |
| 721 | |
| 722 | if (ctx->strtab == NULL) { |
| 723 | ERROR("No string table found.\n"); |
| 724 | return -1; |
| 725 | } |
| 726 | |
| 727 | if (find_program_segment(ctx)) |
| 728 | goto out; |
no test coverage detected