Skip to content

Commit 93a4aba

Browse files
committed
llext: Keep RODATA sections without relocations in flash.
Keep RODATA sections that don't have any relocations in flash. Changes: - Add LLEXT_MEM_RODATA_NO_RELOC memory region type for relocation-free read-only data that stays in flash - Add pre-pass in llext_map_sections() that scans all REL/RELA sections and marks their target sections in a temporary array - Modify RODATA section classification to check relocation marks: sections with relocations go to LLEXT_MEM_RODATA (RAM), sections without go to LLEXT_MEM_RODATA_NO_RELOC (flash) since sections are interleaved Signed-off-by: Ibrahim Abdalkader <[email protected]>
1 parent 2c1c2c7 commit 93a4aba

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

include/zephyr/llext/llext.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ enum llext_mem {
4545
LLEXT_MEM_TEXT, /**< Executable code */
4646
LLEXT_MEM_DATA, /**< Initialized data */
4747
LLEXT_MEM_RODATA, /**< Read-only data */
48+
LLEXT_MEM_RODATA_NO_RELOC, /**< Large read-only constants kept in flash */
4849
LLEXT_MEM_BSS, /**< Uninitialized data */
4950
LLEXT_MEM_EXPORT, /**< Exported symbol table */
5051
LLEXT_MEM_SYMTAB, /**< Symbol table */

subsys/llext/llext_load.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,25 @@ static int llext_map_sections(struct llext_loader *ldr, struct llext *ext,
232232
{
233233
int i, j;
234234
const char *name;
235+
bool sect_has_relocs[ext->sect_cnt];
236+
237+
/*
238+
* Mark sections that have relocations targeting them. This allows us to separate
239+
* RODATA sections with/without relocations and place relocation-free sections in
240+
* RODATA_NO_RELOC region to save RAM.
241+
*/
242+
memset(sect_has_relocs, 0, sizeof(sect_has_relocs));
243+
244+
for (i = 0; i < ext->sect_cnt; ++i) {
245+
elf_shdr_t *shdr = ext->sect_hdrs + i;
246+
247+
if (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA) {
248+
/* Mark the target section as having relocations */
249+
if (shdr->sh_info < ext->sect_cnt) {
250+
sect_has_relocs[shdr->sh_info] = true;
251+
}
252+
}
253+
}
235254

236255
for (i = 0; i < ext->sect_cnt; ++i) {
237256
elf_shdr_t *shdr = ext->sect_hdrs + i;
@@ -256,8 +275,12 @@ static int llext_map_sections(struct llext_loader *ldr, struct llext *ext,
256275
mem_idx = LLEXT_MEM_TEXT;
257276
} else if (shdr->sh_flags & SHF_WRITE) {
258277
mem_idx = LLEXT_MEM_DATA;
259-
} else {
278+
} else if (sect_has_relocs[i]) {
279+
/* Has relocations - copy to RAM */
260280
mem_idx = LLEXT_MEM_RODATA;
281+
} else {
282+
/* No relocations - can stay in flash */
283+
mem_idx = LLEXT_MEM_RODATA_NO_RELOC;
261284
}
262285
break;
263286
case SHT_PREINIT_ARRAY:

0 commit comments

Comments
 (0)