/* * Copyright (c) 2025 Arduino SA * * SPDX-License-Identifier: Apache-2.0 */ #ifndef ZEPHYR_LLEXT_INSPECT_H #define ZEPHYR_LLEXT_INSPECT_H #ifdef __cplusplus extern "C" { #endif #include #include #include #include /** * @file * @brief LLEXT ELF inspection routines. * * This file contains routines to inspect the contents of an ELF file. It is * intended to be used by applications that need advanced access to the ELF * file structures of a loaded extension. * * @defgroup llext_inspect_apis ELF inspection APIs * @ingroup llext_apis * @{ */ /** * @brief Get information about a memory region for the specified extension. * * Retrieve information about a region (merged group of similar sections) in * the extension. Any output parameter can be NULL if that information is not * needed. * * @param[in] ldr Loader * @param[in] ext Extension * @param[in] region Region to get information about * @param[out] hdr Variable storing the pointer to the region header * @param[out] addr Variable storing the region load address * @param[out] size Variable storing the region size * * @return 0 on success, -EINVAL if the region is invalid */ static inline int llext_get_region_info(const struct llext_loader *ldr, const struct llext *ext, enum llext_mem region, const elf_shdr_t **hdr, const void **addr, size_t *size) { if ((unsigned int)region >= LLEXT_MEM_COUNT) { return -EINVAL; } if (hdr) { *hdr = &ldr->sects[region]; } /* address and size compensated for alignment prepad */ if (addr) { *addr = (void *)((uintptr_t)ext->mem[region] + ldr->sects[region].sh_info); } if (size) { *size = ext->mem_size[region] - ldr->sects[region].sh_info; } return 0; } /** * @brief Get the index of a section with the specified name. * * Requires the @ref llext_load_param.keep_section_info flag to be set at * extension load time. * * @param[in] ldr Loader * @param[in] ext Extension * @param[in] section_name Name of the section to look for * * @return Section index on success, -ENOENT if the section was not found, * -ENOTSUP if section data is not available. */ int llext_section_shndx(const struct llext_loader *ldr, const struct llext *ext, const char *section_name); /** * @brief Get information about a section for the specified extension. * * Retrieve information about an ELF sections in the extension. Any output * parameter can be @c NULL if that information is not needed. * * Requires the @ref llext_load_param.keep_section_info flag to be set at * extension load time. * * @param[in] ldr Loader * @param[in] ext Extension * @param[in] shndx Section index * @param[out] hdr Variable storing the pointer to the section header * @param[out] region Variable storing the region the section belongs to * @param[out] offset Variable storing the offset of the section in the region * * @return 0 on success, -EINVAL if the section index is invalid, * -ENOTSUP if section data is not available. */ static inline int llext_get_section_info(const struct llext_loader *ldr, const struct llext *ext, unsigned int shndx, const elf_shdr_t **hdr, enum llext_mem *region, size_t *offset) { if (shndx < 0 || shndx >= ext->sect_cnt) { return -EINVAL; } if (!ldr->sect_map) { return -ENOTSUP; } enum llext_mem mem_idx = ldr->sect_map[shndx].mem_idx; if (hdr) { *hdr = &ext->sect_hdrs[shndx]; } if (region) { *region = mem_idx; } /* offset compensated for alignment prepad */ if (offset) { *offset = ldr->sect_map[shndx].offset - ldr->sects[mem_idx].sh_info; } return 0; } /** * @} */ #ifdef __cplusplus } #endif #endif /* ZEPHYR_LLEXT_INSPECT_H */