Skip to content

Commit 187d043

Browse files
committed
llext: add support for .bss directly adjacent to .data
Zephyr places .bss into a separate section element, still if it's immediately adjacent to writable data we can merge and allocate them together. Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
1 parent 858854e commit 187d043

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

src/library_manager/llext_manager.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,22 @@ static int llext_manager_load_module(uint32_t module_id, const struct sof_man_mo
137137

138138
/* Check, that .bss is within .data */
139139
if (bss_size &&
140-
((uintptr_t)bss_addr + bss_size < (uintptr_t)va_base_data ||
140+
((uintptr_t)bss_addr + bss_size <= (uintptr_t)va_base_data ||
141141
(uintptr_t)bss_addr >= (uintptr_t)va_base_data + data_size)) {
142-
tr_err(&lib_manager_tr, ".bss %#x @ %p isn't within writable data %#x @ %p!",
143-
bss_size, bss_addr, data_size, (void *)va_base_data);
144-
return -EPROTO;
142+
if ((uintptr_t)bss_addr + bss_size == (uintptr_t)va_base_data &&
143+
!((uintptr_t)bss_addr & (PAGE_SZ - 1))) {
144+
/* .bss directly in front of writable data and properly aligned, prepend */
145+
va_base_data = bss_addr;
146+
data_size += bss_size;
147+
} else if ((uintptr_t)bss_addr == (uintptr_t)va_base_data + data_size) {
148+
/* .bss directly behind writable data, append */
149+
data_size += bss_size;
150+
} else {
151+
tr_err(&lib_manager_tr, ".bss %#x @%p isn't within writable data %#x @%p!",
152+
bss_size, (__sparse_force void *)bss_addr,
153+
data_size, (__sparse_force void *)va_base_data);
154+
return -EPROTO;
155+
}
145156
}
146157

147158
/* Copy Code */
@@ -162,8 +173,7 @@ static int llext_manager_load_module(uint32_t module_id, const struct sof_man_mo
162173
if (ret < 0)
163174
goto e_rodata;
164175

165-
memset((__sparse_force void *)ctx->segment[LIB_MANAGER_BSS].addr, 0,
166-
ctx->segment[LIB_MANAGER_BSS].size);
176+
memset((__sparse_force void *)bss_addr, 0, bss_size);
167177

168178
return 0;
169179

0 commit comments

Comments
 (0)