| /* |
| * Copyright 2017, Data61 |
| * Commonwealth Scientific and Industrial Research Organisation (CSIRO) |
| * ABN 41 687 119 230. |
| * |
| * This software may be distributed and modified according to the terms of |
| * the BSD 2-Clause license. Note that NO WARRANTY is provided. |
| * See "LICENSE_BSD2.txt" for details. |
| * |
| * @TAG(DATA61_BSD) |
| */ |
| #pragma once |
| |
| #include <autoconf.h> |
| #include <sel4utils/gen_config.h> |
| |
| #include <vka/vka.h> |
| |
| #include <vspace/vspace.h> |
| #include <elf/elf.h> |
| |
| #if CONFIG_WORD_SIZE == 64 |
| #define Elf_Phdr Elf64_Phdr |
| #elif CONFIG_WORD_SIZE == 32 |
| #define Elf_Phdr Elf32_Phdr |
| #else |
| #error "Word size unsupported" |
| #endif /* CONFIG_WORD_SIZE */ |
| |
| |
| typedef struct sel4utils_elf_region { |
| seL4_CapRights_t rights; |
| /* These two vstarts may differ if the elf was not mapped 1to1. Such an elf is not |
| * runnable, but allows it to be loaded into a vspace where it is not intended to be run. |
| * This is also as reported by the elf file. */ |
| void *elf_vstart; |
| /* Start of the reservation. This will be 4k aligned */ |
| void *reservation_vstart; |
| /* Size of the elf segment as reported by elf file */ |
| uint32_t size; |
| /* Size of the reservation. This will be a multple of 4k */ |
| size_t reservation_size; |
| reservation_t reservation; |
| int cacheable; |
| /* Index of this elf segment in the section header */ |
| int segment_index; |
| } sel4utils_elf_region_t; |
| |
| /** |
| * Load an elf file into a vspace. |
| * |
| * The loader vspace and vka allocation will be preserved (no extra cslots or objects or vaddrs |
| * will leak from this function), even in the case of an error. |
| * |
| * The loadee vspace and vka will alter: cslots will be allocated for each frame to be |
| * mapped into the address space and frames will be allocated. In case of failure the entire |
| * virtual address space is left in the state where it failed. |
| * |
| * @param loadee the vspace to load the elf file into |
| * @param loader the vspace we are loading from |
| * @param loadee_vka allocator to use for allocation in the loadee vspace |
| * @param loader_vka allocator to use for loader vspace. Can be the same as loadee_vka. |
| * @param image_name name of the image in the cpio archive to load. |
| * @param regions Optional array for list of regions to be placed. Assumed to be the correct |
| size as reported by a call to sel4utils_elf_num_regions |
| * @param mapanywhere If true allows the elf to be loaded anywhere in the vspace. Regions will |
| still be contiguous |
| * |
| * @return The entry point of the new process, NULL on error |
| */ |
| void * |
| sel4utils_elf_load_record_regions(vspace_t *loadee, vspace_t *loader, vka_t *loadee_vka, |
| vka_t *loader_vka, elf_t *elf, sel4utils_elf_region_t *regions, int mapanywhere); |
| |
| /** |
| * Wrapper for sel4utils_elf_load_record_regions. Does not record/perform reservations and |
| * maps into the correct virtual addresses |
| * |
| * @param loadee the vspace to load the elf file into |
| * @param loader the vspace we are loading from |
| * @param loadee_vka allocator to use for allocation in the loadee vspace |
| * @param loader_vka allocator to use for loader vspace. Can be the same as loadee_vka. |
| * @param image_name name of the image in the cpio archive to load. |
| * |
| * @return The entry point of the new process, NULL on error |
| */ |
| void * |
| sel4utils_elf_load(vspace_t *loadee, vspace_t *loader, vka_t *loadee_vka, |
| vka_t *loader_vka, elf_t *elf); |
| |
| /** |
| * Parses an elf file but does not actually load it. Merely reserves the regions in the vspace |
| * for where the elf segments would go. This is used for lazy loading / copy on write |
| |
| * @param loadee the vspace to reserve the elf regions in |
| * @param image_name name of the image in the cpio archive to parse. |
| * @param regions Array for list of regions to be placed. Assumed to be the correct |
| size as reported by a call to sel4utils_elf_num_regions |
| * |
| * @return The entry point of the elf, NULL on error |
| */ |
| void * |
| sel4utils_elf_reserve(vspace_t *loadee, elf_t *elf, sel4utils_elf_region_t *regions); |
| |
| /** |
| * Parses an elf file and returns the number of loadable regions. The result of this |
| * is used to calculate the number of regions to pass to sel4utils_elf_reserve and |
| * sel4utils_elf_load_record_regions |
| * |
| * @param image_name name of the image in the cpio archive to inspect |
| * @return Number of loadable regions in the elf |
| */ |
| int |
| sel4utils_elf_num_regions(elf_t *elf); |
| |
| /** |
| * Looks for the __vsyscall section in an elf file and returns the value. This |
| * is used to set the __sysinfo value when launching the elf |
| * |
| * @param image_name name of the image in the cpio archive to inspect |
| * |
| * @return Address of vsyscall function or 0 if not found |
| */ |
| uintptr_t sel4utils_elf_get_vsyscall(elf_t *elf); |
| |
| /** |
| * Finds the section_name section in an elf file and returns the address. |
| * |
| * @param image_name name of the image in the cpio archive to inspect |
| * |
| * @param section_name name of the section to find |
| * |
| * @param section_size optional pointer to uint64_t to return the section size |
| * |
| * @return Address of section or 0 if not found |
| */ |
| uintptr_t sel4utils_elf_get_section(elf_t *elf, const char *section_name, uint64_t *section_size); |
| |
| /** |
| * Parses an elf file and returns the number of phdrs. The result of this |
| * can be used prior to a call to sel4utils_elf_read_phdrs |
| * |
| * @param image_name name of the image in the cpio archive to inspect |
| * @return Number of phdrs in the elf |
| */ |
| uint32_t sel4utils_elf_num_phdrs(elf_t *elf); |
| |
| /** |
| * Parse an elf file and retrieve all the phdrs |
| * |
| * @param image_name name of the image in the cpio archive to inspect |
| * @param max_phdrs Maximum number of phdrs to retrieve |
| * @param phdrs Array to store the loaded phdrs into |
| * |
| * @return Number of phdrs retrieved |
| */ |
| void sel4utils_elf_read_phdrs(elf_t *elf, size_t max_phdrs, Elf_Phdr *phdrs); |
| |