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 Function to read (copy) from the loader
45 *
46 * Copies len bytes into buf from the current position of the
47 * loader.
48 *
49 * @param[in] ldr Loader
50 * @param[in] out Output location
51 * @param[in] len Length to copy into the output location
52 *
53 * @returns 0 on success, or a negative error code.
54 */
55 int (*read)(struct llext_loader *ldr, void *out, size_t len);
56
57 /**
58 * @brief Function to seek to a new absolute location in the stream.
59 *
60 * Changes the location of the loader position to a new absolute
61 * given position.
62 *
63 * @param[in] ldr Loader
64 * @param[in] pos Position in stream to move loader
65 *
66 * @returns 0 on success, or a negative error code.
67 */
68 int (*seek)(struct llext_loader *ldr, size_t pos);
69
70 /**
71 * @brief Optional function to peek at an absolute location in the ELF.
72 *
73 * Return a pointer to the buffer at specified offset.
74 *
75 * @param[in] ldr Loader
76 * @param[in] pos Position to obtain a pointer to
77 *
78 * @returns a pointer into the buffer or `NULL` if not supported
79 */
80 void *(*peek)(struct llext_loader *ldr, size_t pos);
81
82 /** @cond ignore */
83 elf_ehdr_t hdr;
84 elf_shdr_t sects[LLEXT_MEM_COUNT];
85 elf_shdr_t *sect_hdrs;
86 bool sect_hdrs_on_heap;
87 struct llext_elf_sect_map *sect_map;
88 uint32_t sect_cnt;
89 /** @endcond */
90 };
91
92 /** @cond ignore */
llext_read(struct llext_loader * l,void * buf,size_t len)93 static inline int llext_read(struct llext_loader *l, void *buf, size_t len)
94 {
95 return l->read(l, buf, len);
96 }
97
llext_seek(struct llext_loader * l,size_t pos)98 static inline int llext_seek(struct llext_loader *l, size_t pos)
99 {
100 return l->seek(l, pos);
101 }
102
llext_peek(struct llext_loader * l,size_t pos)103 static inline void *llext_peek(struct llext_loader *l, size_t pos)
104 {
105 if (l->peek) {
106 return l->peek(l, pos);
107 }
108
109 return NULL;
110 }
111 /* @endcond */
112
113 /**
114 * @}
115 */
116
117 #ifdef __cplusplus
118 }
119 #endif
120
121 #endif /* ZEPHYR_LLEXT_LOADER_H */
122