Line data Source code
1 1 : /*
2 : * Copyright (c) 2025 Arduino SA
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : #ifndef ZEPHYR_LLEXT_INSPECT_H
8 : #define ZEPHYR_LLEXT_INSPECT_H
9 :
10 : #ifdef __cplusplus
11 : extern "C" {
12 : #endif
13 :
14 : #include <stddef.h>
15 : #include <zephyr/llext/llext.h>
16 : #include <zephyr/llext/loader.h>
17 : #include <zephyr/llext/llext_internal.h>
18 :
19 : /**
20 : * @file
21 : * @brief LLEXT ELF inspection routines.
22 : *
23 : * This file contains routines to inspect the contents of an ELF file. It is
24 : * intended to be used by applications that need advanced access to the ELF
25 : * file structures of a loaded extension.
26 : *
27 : * @defgroup llext_inspect_apis ELF inspection APIs
28 : * @ingroup llext_apis
29 : * @{
30 : */
31 :
32 : /**
33 : * @brief Get information about a memory region for the specified extension.
34 : *
35 : * Retrieve information about a region (merged group of similar sections) in
36 : * the extension. Any output parameter can be NULL if that information is not
37 : * needed.
38 : *
39 : * @param[in] ldr Loader
40 : * @param[in] ext Extension
41 : * @param[in] region Region to get information about
42 : * @param[out] hdr Variable storing the pointer to the region header
43 : * @param[out] addr Variable storing the region load address
44 : * @param[out] size Variable storing the region size
45 : *
46 : * @return 0 on success, -EINVAL if the region is invalid
47 : */
48 1 : static inline int llext_get_region_info(const struct llext_loader *ldr,
49 : const struct llext *ext,
50 : enum llext_mem region,
51 : const elf_shdr_t **hdr,
52 : const void **addr, size_t *size)
53 : {
54 : if ((unsigned int)region >= LLEXT_MEM_COUNT) {
55 : return -EINVAL;
56 : }
57 :
58 : if (hdr) {
59 : *hdr = &ldr->sects[region];
60 : }
61 :
62 : /* address and size compensated for alignment prepad */
63 : if (addr) {
64 : *addr = (void *)((uintptr_t)ext->mem[region] + ldr->sects[region].sh_info);
65 : }
66 : if (size) {
67 : *size = ext->mem_size[region] - ldr->sects[region].sh_info;
68 : }
69 :
70 : return 0;
71 : }
72 :
73 : /**
74 : * @brief Get the index of a section with the specified name.
75 : *
76 : * Requires the @ref llext_load_param.keep_section_info flag to be set at
77 : * extension load time.
78 : *
79 : * @param[in] ldr Loader
80 : * @param[in] ext Extension
81 : * @param[in] section_name Name of the section to look for
82 : *
83 : * @return Section index on success, -ENOENT if the section was not found,
84 : * -ENOTSUP if section data is not available.
85 : */
86 1 : int llext_section_shndx(const struct llext_loader *ldr, const struct llext *ext,
87 : const char *section_name);
88 :
89 : /**
90 : * @brief Get information about a section for the specified extension.
91 : *
92 : * Retrieve information about an ELF sections in the extension. Any output
93 : * parameter can be @c NULL if that information is not needed.
94 : *
95 : * Requires the @ref llext_load_param.keep_section_info flag to be set at
96 : * extension load time.
97 : *
98 : * @param[in] ldr Loader
99 : * @param[in] ext Extension
100 : * @param[in] shndx Section index
101 : * @param[out] hdr Variable storing the pointer to the section header
102 : * @param[out] region Variable storing the region the section belongs to
103 : * @param[out] offset Variable storing the offset of the section in the region
104 : *
105 : * @return 0 on success, -EINVAL if the section index is invalid,
106 : * -ENOTSUP if section data is not available.
107 : */
108 1 : static inline int llext_get_section_info(const struct llext_loader *ldr,
109 : const struct llext *ext,
110 : unsigned int shndx,
111 : const elf_shdr_t **hdr,
112 : enum llext_mem *region,
113 : size_t *offset)
114 : {
115 : if (shndx < 0 || shndx >= ext->sect_cnt) {
116 : return -EINVAL;
117 : }
118 : if (!ldr->sect_map) {
119 : return -ENOTSUP;
120 : }
121 :
122 : enum llext_mem mem_idx = ldr->sect_map[shndx].mem_idx;
123 :
124 : if (hdr) {
125 : *hdr = &ext->sect_hdrs[shndx];
126 : }
127 : if (region) {
128 : *region = mem_idx;
129 : }
130 :
131 : /* offset compensated for alignment prepad */
132 : if (offset) {
133 : *offset = ldr->sect_map[shndx].offset - ldr->sects[mem_idx].sh_info;
134 : }
135 :
136 : return 0;
137 : }
138 :
139 : /**
140 : * @}
141 : */
142 :
143 : #ifdef __cplusplus
144 : }
145 : #endif
146 :
147 : #endif /* ZEPHYR_LLEXT_INSPECT_H */
|