1 /*
2 * Copyright (c) 2023 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #ifndef ZEPHYR_LLEXT_LOADER_H
8 #define ZEPHYR_LLEXT_LOADER_H
9
10 #include <zephyr/llext/elf.h>
11 #include <stddef.h>
12
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16
17 /**
18 * @file
19 * @brief LLEXT ELF loader context types.
20 *
21 * The following types are used to define the context of the ELF loader
22 * used by the \ref llext subsystem.
23 *
24 * @defgroup llext_loader_apis ELF loader context
25 * @ingroup llext_apis
26 * @{
27 */
28
29 #include <zephyr/llext/llext.h>
30
31 /** @cond ignore */
32 struct llext_elf_sect_map; /* defined in llext_priv.h */
33 /** @endcond */
34
35 /**
36 * @brief Linkable loadable extension loader context
37 *
38 * This object is used to access the ELF file data and cache its contents
39 * while an extension is being loaded by the LLEXT subsystem. Once the
40 * extension is loaded, this object is no longer needed.
41 */
42 struct llext_loader {
43 /**
44 * @brief Optional function to prepare the loader for loading extension.
45 *
46 * @param[in] ldr Loader
47 *
48 * @returns 0 on success, or a negative error.
49 */
50 int (*prepare)(struct llext_loader *ldr);
51
52 /**
53 * @brief Function to read (copy) from the loader
54 *
55 * Copies len bytes into buf from the current position of the
56 * loader.
57 *
58 * @param[in] ldr Loader
59 * @param[in] out Output location
60 * @param[in] len Length to copy into the output location
61 *
62 * @returns 0 on success, or a negative error code.
63 */
64 int (*read)(struct llext_loader *ldr, void *out, size_t len);
65
66 /**
67 * @brief Function to seek to a new absolute location in the stream.
68 *
69 * Changes the location of the loader position to a new absolute
70 * given position.
71 *
72 * @param[in] ldr Loader
73 * @param[in] pos Position in stream to move loader
74 *
75 * @returns 0 on success, or a negative error code.
76 */
77 int (*seek)(struct llext_loader *ldr, size_t pos);
78
79 /**
80 * @brief Optional function to peek at an absolute location in the ELF.
81 *
82 * Return a pointer to the buffer at specified offset.
83 *
84 * @param[in] ldr Loader
85 * @param[in] pos Position to obtain a pointer to
86 *
87 * @returns a pointer into the buffer or `NULL` if not supported
88 */
89 void *(*peek)(struct llext_loader *ldr, size_t pos);
90
91 /**
92 * @brief Optional function to clean after the extension has been loaded or error occurred.
93 *
94 * @param[in] ldr Loader
95 */
96 void (*finalize)(struct llext_loader *ldr);
97
98 /** @cond ignore */
99 elf_ehdr_t hdr;
100 elf_shdr_t sects[LLEXT_MEM_COUNT];
101 struct llext_elf_sect_map *sect_map;
102 /** @endcond */
103 };
104
105 /** @cond ignore */
llext_prepare(struct llext_loader * l)106 static inline int llext_prepare(struct llext_loader *l)
107 {
108 if (l->prepare) {
109 return l->prepare(l);
110 }
111
112 return 0;
113 }
114
llext_read(struct llext_loader * l,void * buf,size_t len)115 static inline int llext_read(struct llext_loader *l, void *buf, size_t len)
116 {
117 return l->read(l, buf, len);
118 }
119
llext_seek(struct llext_loader * l,size_t pos)120 static inline int llext_seek(struct llext_loader *l, size_t pos)
121 {
122 return l->seek(l, pos);
123 }
124
llext_peek(struct llext_loader * l,size_t pos)125 static inline void *llext_peek(struct llext_loader *l, size_t pos)
126 {
127 if (l->peek) {
128 return l->peek(l, pos);
129 }
130
131 return NULL;
132 }
133
llext_finalize(struct llext_loader * l)134 static inline void llext_finalize(struct llext_loader *l)
135 {
136 if (l->finalize) {
137 l->finalize(l);
138 }
139 }
140 /* @endcond */
141
142 /**
143 * @}
144 */
145
146 #ifdef __cplusplus
147 }
148 #endif
149
150 #endif /* ZEPHYR_LLEXT_LOADER_H */
151