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