Lines Matching +full:has +full:- +full:magic +full:- +full:addr

5  * SPDX-License-Identifier: Apache-2.0
31 * - The input `struct llext` and fields in `struct loader` are zero-filled
34 * - If some function called by do_llext_load allocates memory, it does so by
36 * - do_llext_load() will clean up the memory allocated by the functions it
44 enum llext_mem mem_idx = ldr->sect_map[sh_ndx].mem_idx; in llext_loaded_sect_ptr()
50 return (const uint8_t *)ext->mem[mem_idx] + ldr->sect_map[sh_ndx].offset; in llext_loaded_sect_ptr()
69 ret = llext_read(ldr, &ldr->hdr, sizeof(ldr->hdr)); in llext_load_elf_data()
76 if (memcmp(ldr->hdr.e_ident, ELF_MAGIC, sizeof(ELF_MAGIC)) != 0) { in llext_load_elf_data()
77 LOG_HEXDUMP_ERR(ldr->hdr.e_ident, 16, "Invalid ELF, magic does not match"); in llext_load_elf_data()
78 return -ENOEXEC; in llext_load_elf_data()
81 switch (ldr->hdr.e_type) { in llext_load_elf_data()
91 LOG_ERR("Unsupported ELF file type %x", ldr->hdr.e_type); in llext_load_elf_data()
92 return -ENOEXEC; in llext_load_elf_data()
101 if (ldr->hdr.e_shentsize != sizeof(elf_shdr_t)) { in llext_load_elf_data()
102 LOG_ERR("Invalid section header size %d", ldr->hdr.e_shentsize); in llext_load_elf_data()
103 return -ENOEXEC; in llext_load_elf_data()
106 ext->sect_cnt = ldr->hdr.e_shnum; in llext_load_elf_data()
108 size_t sect_map_sz = ext->sect_cnt * sizeof(ldr->sect_map[0]); in llext_load_elf_data()
110 ldr->sect_map = llext_alloc(sect_map_sz); in llext_load_elf_data()
111 if (!ldr->sect_map) { in llext_load_elf_data()
113 return -ENOMEM; in llext_load_elf_data()
115 for (int i = 0; i < ext->sect_cnt; i++) { in llext_load_elf_data()
116 ldr->sect_map[i].mem_idx = LLEXT_MEM_COUNT; in llext_load_elf_data()
117 ldr->sect_map[i].offset = 0; in llext_load_elf_data()
120 ext->sect_hdrs = (elf_shdr_t *)llext_peek(ldr, ldr->hdr.e_shoff); in llext_load_elf_data()
121 if (ext->sect_hdrs) { in llext_load_elf_data()
122 ext->sect_hdrs_on_heap = false; in llext_load_elf_data()
124 size_t sect_hdrs_sz = ext->sect_cnt * sizeof(ext->sect_hdrs[0]); in llext_load_elf_data()
126 ext->sect_hdrs_on_heap = true; in llext_load_elf_data()
127 ext->sect_hdrs = llext_alloc(sect_hdrs_sz); in llext_load_elf_data()
128 if (!ext->sect_hdrs) { in llext_load_elf_data()
130 return -ENOMEM; in llext_load_elf_data()
133 ret = llext_seek(ldr, ldr->hdr.e_shoff); in llext_load_elf_data()
139 ret = llext_read(ldr, ext->sect_hdrs, sect_hdrs_sz); in llext_load_elf_data()
156 memset(ldr->sects, 0, sizeof(ldr->sects)); in llext_find_tables()
159 for (i = 0, table_cnt = 0; i < ext->sect_cnt && table_cnt < 3; ++i) { in llext_find_tables()
160 elf_shdr_t *shdr = ext->sect_hdrs + i; in llext_find_tables()
163 "addr 0x%zx, size %zd, link %d, info %d", in llext_find_tables()
165 (size_t)shdr->sh_offset, in llext_find_tables()
166 shdr->sh_name, in llext_find_tables()
167 shdr->sh_type, in llext_find_tables()
168 (size_t)shdr->sh_flags, in llext_find_tables()
169 (size_t)shdr->sh_addr, in llext_find_tables()
170 (size_t)shdr->sh_size, in llext_find_tables()
171 shdr->sh_link, in llext_find_tables()
172 shdr->sh_info); in llext_find_tables()
174 switch (shdr->sh_type) { in llext_find_tables()
178 ldr->sects[LLEXT_MEM_SYMTAB] = *shdr; in llext_find_tables()
179 ldr->sect_map[i].mem_idx = LLEXT_MEM_SYMTAB; in llext_find_tables()
183 if (ldr->hdr.e_shstrndx == i) { in llext_find_tables()
185 ldr->sects[LLEXT_MEM_SHSTRTAB] = *shdr; in llext_find_tables()
186 ldr->sect_map[i].mem_idx = LLEXT_MEM_SHSTRTAB; in llext_find_tables()
189 ldr->sects[LLEXT_MEM_STRTAB] = *shdr; in llext_find_tables()
190 ldr->sect_map[i].mem_idx = LLEXT_MEM_STRTAB; in llext_find_tables()
199 if (!ldr->sects[LLEXT_MEM_SHSTRTAB].sh_type || in llext_find_tables()
200 !ldr->sects[LLEXT_MEM_STRTAB].sh_type || in llext_find_tables()
201 !ldr->sects[LLEXT_MEM_SYMTAB].sh_type) { in llext_find_tables()
203 return -ENOEXEC; in llext_find_tables()
211 * calculating ldr->sects and ldr->sect_map.
219 for (i = 0; i < ext->sect_cnt; ++i) { in llext_map_sections()
220 elf_shdr_t *shdr = ext->sect_hdrs + i; in llext_map_sections()
222 name = llext_string(ldr, ext, LLEXT_MEM_SHSTRTAB, shdr->sh_name); in llext_map_sections()
224 if (ldr->sect_map[i].mem_idx != LLEXT_MEM_COUNT) { in llext_map_sections()
226 i, name, ldr->sect_map[i].mem_idx); in llext_map_sections()
233 switch (shdr->sh_type) { in llext_map_sections()
238 if (shdr->sh_flags & SHF_EXECINSTR) { in llext_map_sections()
240 } else if (shdr->sh_flags & SHF_WRITE) { in llext_map_sections()
266 !(shdr->sh_flags & SHF_ALLOC) || in llext_map_sections()
267 shdr->sh_size == 0) { in llext_map_sections()
276 if (shdr->sh_entsize != sizeof(void *) || in llext_map_sections()
277 shdr->sh_size % shdr->sh_entsize != 0) { in llext_map_sections()
279 return -ENOEXEC; in llext_map_sections()
287 ldr->sect_map[i].mem_idx = mem_idx; in llext_map_sections()
288 elf_shdr_t *region = ldr->sects + mem_idx; in llext_map_sections()
295 if (ldr_parm->section_detached && ldr_parm->section_detached(shdr)) { in llext_map_sections()
299 if (region->sh_type == SHT_NULL) { in llext_map_sections()
306 if ((shdr->sh_flags & SHF_BASIC_TYPE_MASK) != in llext_map_sections()
307 (region->sh_flags & SHF_BASIC_TYPE_MASK)) { in llext_map_sections()
309 (uint32_t)shdr->sh_flags, (uint32_t)region->sh_flags, in llext_map_sections()
311 return -ENOEXEC; in llext_map_sections()
323 return -ENOTSUP; in llext_map_sections()
331 return -ENOEXEC; in llext_map_sections()
336 if (ldr->hdr.e_type == ET_DYN) { in llext_map_sections()
342 if (shdr->sh_addr - region->sh_addr != in llext_map_sections()
343 shdr->sh_offset - region->sh_offset) { in llext_map_sections()
346 return -ENOEXEC; in llext_map_sections()
354 size_t address = MIN(region->sh_addr, shdr->sh_addr); in llext_map_sections()
355 size_t bot_ofs = MIN(region->sh_offset, shdr->sh_offset); in llext_map_sections()
356 size_t top_ofs = MAX(region->sh_offset + region->sh_size, in llext_map_sections()
357 shdr->sh_offset + shdr->sh_size); in llext_map_sections()
359 region->sh_addr = address; in llext_map_sections()
360 region->sh_offset = bot_ofs; in llext_map_sections()
361 region->sh_size = top_ofs - bot_ofs; in llext_map_sections()
371 elf_shdr_t *x = ldr->sects + i; in llext_map_sections()
372 elf_shdr_t *y = ldr->sects + j; in llext_map_sections()
374 if (x->sh_type == SHT_NULL || x->sh_size == 0 || in llext_map_sections()
375 y->sh_type == SHT_NULL || y->sh_size == 0) { in llext_map_sections()
398 if (ldr->hdr.e_type == ET_DYN) { in llext_map_sections()
402 if ((x->sh_addr <= y->sh_addr && in llext_map_sections()
403 x->sh_addr + x->sh_size > y->sh_addr) || in llext_map_sections()
404 (y->sh_addr <= x->sh_addr && in llext_map_sections()
405 y->sh_addr + y->sh_size > x->sh_addr)) { in llext_map_sections()
408 i, (size_t)x->sh_addr, (size_t)x->sh_size, in llext_map_sections()
409 j, (size_t)y->sh_addr, (size_t)y->sh_size); in llext_map_sections()
410 return -ENOEXEC; in llext_map_sections()
423 if ((x->sh_offset <= y->sh_offset && in llext_map_sections()
424 x->sh_offset + x->sh_size > y->sh_offset) || in llext_map_sections()
425 (y->sh_offset <= x->sh_offset && in llext_map_sections()
426 y->sh_offset + y->sh_size > x->sh_offset)) { in llext_map_sections()
429 i, (size_t)x->sh_offset, (size_t)x->sh_size, in llext_map_sections()
430 j, (size_t)y->sh_offset, (size_t)y->sh_size); in llext_map_sections()
431 return -ENOEXEC; in llext_map_sections()
440 for (i = 0; i < ext->sect_cnt; ++i) { in llext_map_sections()
441 elf_shdr_t *shdr = ext->sect_hdrs + i; in llext_map_sections()
442 enum llext_mem mem_idx = ldr->sect_map[i].mem_idx; in llext_map_sections()
445 ldr->sect_map[i].offset = shdr->sh_offset - ldr->sects[mem_idx].sh_offset; in llext_map_sections()
454 size_t ent_size = ldr->sects[LLEXT_MEM_SYMTAB].sh_entsize; in llext_count_export_syms()
455 size_t syms_size = ldr->sects[LLEXT_MEM_SYMTAB].sh_size; in llext_count_export_syms()
464 ext->sym_tab.sym_cnt = 0; in llext_count_export_syms()
465 for (i = 0, pos = ldr->sects[LLEXT_MEM_SYMTAB].sh_offset; in llext_count_export_syms()
492 ext->sym_tab.sym_cnt++; in llext_count_export_syms()
504 struct llext_symtable *sym_tab = &ext->sym_tab; in llext_allocate_symtab()
505 size_t syms_size = sym_tab->sym_cnt * sizeof(struct llext_symbol); in llext_allocate_symtab()
507 sym_tab->syms = llext_alloc(syms_size); in llext_allocate_symtab()
508 if (!sym_tab->syms) { in llext_allocate_symtab()
509 return -ENOMEM; in llext_allocate_symtab()
511 memset(sym_tab->syms, 0, syms_size); in llext_allocate_symtab()
512 ext->alloc_size += syms_size; in llext_allocate_symtab()
519 elf_shdr_t *shdr = ldr->sects + LLEXT_MEM_EXPORT; in llext_export_symbols()
523 if (shdr->sh_size < sizeof(struct llext_symbol)) { in llext_export_symbols()
528 struct llext_symtable *exp_tab = &ext->exp_tab; in llext_export_symbols()
530 exp_tab->sym_cnt = shdr->sh_size / sizeof(struct llext_symbol); in llext_export_symbols()
531 exp_tab->syms = llext_alloc(exp_tab->sym_cnt * sizeof(struct llext_symbol)); in llext_export_symbols()
532 if (!exp_tab->syms) { in llext_export_symbols()
533 return -ENOMEM; in llext_export_symbols()
536 for (i = 0, sym = ext->mem[LLEXT_MEM_EXPORT]; in llext_export_symbols()
537 i < exp_tab->sym_cnt; in llext_export_symbols()
539 exp_tab->syms[i].name = sym->name; in llext_export_symbols()
540 exp_tab->syms[i].addr = sym->addr; in llext_export_symbols()
541 LOG_DBG("sym %p name %s in %p", sym->addr, sym->name, exp_tab->syms + i); in llext_export_symbols()
550 size_t ent_size = ldr->sects[LLEXT_MEM_SYMTAB].sh_entsize; in llext_copy_symbols()
551 size_t syms_size = ldr->sects[LLEXT_MEM_SYMTAB].sh_size; in llext_copy_symbols()
553 struct llext_symtable *sym_tab = &ext->sym_tab; in llext_copy_symbols()
558 for (i = 0, pos = ldr->sects[LLEXT_MEM_SYMTAB].sh_offset, j = 0; in llext_copy_symbols()
584 __ASSERT(j <= sym_tab->sym_cnt, "Miscalculated symbol number %u\n", j); in llext_copy_symbols()
586 sym_tab->syms[j].name = name; in llext_copy_symbols()
588 elf_shdr_t *shdr = ext->sect_hdrs + shndx; in llext_copy_symbols()
589 uintptr_t section_addr = shdr->sh_addr; in llext_copy_symbols()
591 if (ldr_parm->pre_located && in llext_copy_symbols()
592 (!ldr_parm->section_detached || !ldr_parm->section_detached(shdr))) { in llext_copy_symbols()
593 sym_tab->syms[j].addr = (uint8_t *)sym.st_value + in llext_copy_symbols()
594 (ldr->hdr.e_type == ET_REL ? section_addr : 0); in llext_copy_symbols()
604 base = llext_peek(ldr, shdr->sh_offset); in llext_copy_symbols()
609 return -ENOTSUP; in llext_copy_symbols()
613 sym_tab->syms[j].addr = (uint8_t *)base + sym.st_value - in llext_copy_symbols()
614 (ldr->hdr.e_type == ET_REL ? 0 : section_addr); in llext_copy_symbols()
617 LOG_DBG("function symbol %d name %s addr %p", in llext_copy_symbols()
618 j, name, sym_tab->syms[j].addr); in llext_copy_symbols()
643 ldr->sect_map = NULL; in do_llext_load()
659 ret = k_mem_domain_init(&ext->mem_domain, 0, NULL); in do_llext_load()
715 if (ldr_parm->relocate_local) { in do_llext_load()
735 * the fact that freeing a NULL pointer has no effect. in do_llext_load()
738 llext_free(ldr->sect_map); in do_llext_load()
739 ldr->sect_map = NULL; in do_llext_load()
741 /* Until proper inter-llext linking is implemented, the symbol table is in do_llext_load()
746 llext_free(ext->sym_tab.syms); in do_llext_load()
747 ext->sym_tab.sym_cnt = 0; in do_llext_load()
748 ext->sym_tab.syms = NULL; in do_llext_load()
759 llext_free(ext->exp_tab.syms); in do_llext_load()
760 ext->exp_tab.sym_cnt = 0; in do_llext_load()
761 ext->exp_tab.syms = NULL; in do_llext_load()
763 LOG_DBG("loaded module, .text at %p, .rodata at %p", ext->mem[LLEXT_MEM_TEXT], in do_llext_load()
764 ext->mem[LLEXT_MEM_RODATA]); in do_llext_load()