| 706 | |
| 707 | #ifdef VIMAGE |
| 708 | static int |
| 709 | parse_vnet(elf_file_t ef) |
| 710 | { |
| 711 | int error, size; |
| 712 | #if defined(__i386__) |
| 713 | uint32_t pad; |
| 714 | #endif |
| 715 | |
| 716 | ef->vnet_start = 0; |
| 717 | ef->vnet_stop = 0; |
| 718 | error = link_elf_lookup_set(&ef->lf, "vnet", (void ***)&ef->vnet_start, |
| 719 | (void ***)&ef->vnet_stop, NULL); |
| 720 | /* Error just means there is no vnet data set to relocate. */ |
| 721 | if (error != 0) |
| 722 | return (0); |
| 723 | size = (uintptr_t)ef->vnet_stop - (uintptr_t)ef->vnet_start; |
| 724 | /* Empty set? */ |
| 725 | if (size < 1) |
| 726 | return (0); |
| 727 | #if defined(__i386__) |
| 728 | /* In case we do find __start/stop_set_ symbols double-check. */ |
| 729 | if (size < 4) { |
| 730 | uprintf("Kernel module '%s' must be recompiled with " |
| 731 | "linker script\n", ef->lf.pathname); |
| 732 | return (ENOEXEC); |
| 733 | } |
| 734 | |
| 735 | /* Padding from linker-script correct? */ |
| 736 | pad = *(uint32_t *)((uintptr_t)ef->vnet_stop - sizeof(pad)); |
| 737 | if (pad != LS_PADDING) { |
| 738 | uprintf("Kernel module '%s' must be recompiled with " |
| 739 | "linker script, invalid padding %#04x (%#04x)\n", |
| 740 | ef->lf.pathname, pad, LS_PADDING); |
| 741 | return (ENOEXEC); |
| 742 | } |
| 743 | /* If we only have valid padding, nothing to do. */ |
| 744 | if (size == 4) |
| 745 | return (0); |
| 746 | #endif |
| 747 | /* |
| 748 | * Allocate space in the primary vnet area. Copy in our |
| 749 | * initialization from the data section and then initialize |
| 750 | * all per-vnet storage from that. |
| 751 | */ |
| 752 | ef->vnet_base = (Elf_Addr)(uintptr_t)vnet_data_alloc(size); |
| 753 | if (ef->vnet_base == 0) { |
| 754 | printf("%s: vnet module space is out of space; " |
| 755 | "cannot allocate %d for %s\n", |
| 756 | __func__, size, ef->lf.pathname); |
| 757 | return (ENOSPC); |
| 758 | } |
| 759 | memcpy((void *)ef->vnet_base, (void *)ef->vnet_start, size); |
| 760 | vnet_data_copy((void *)ef->vnet_base, size); |
| 761 | elf_set_add(&set_vnet_list, ef->vnet_start, ef->vnet_stop, |
| 762 | ef->vnet_base); |
| 763 | |
| 764 | return (0); |
| 765 | } |
no test coverage detected