From 58dceed66dace6f42abc64c56728201e5f2bde06 Mon Sep 17 00:00:00 2001 From: Hubert Badocha Date: Tue, 22 Oct 2024 13:06:07 +0200 Subject: [PATCH] process: unify load on NOMMU JIRA: RTOS-958 --- proc/process.c | 126 +++++++++++++++++++++---------------------------- 1 file changed, 55 insertions(+), 71 deletions(-) diff --git a/proc/process.c b/proc/process.c index 19314efa..d7d8ce29 100644 --- a/proc/process.c +++ b/proc/process.c @@ -742,13 +742,10 @@ int process_load(process_t *process, vm_object_t *o, off_t base, size_t size, vo Elf32_Ehdr *ehdr; Elf32_Phdr *phdr; Elf32_Shdr *shdr, *shstrshdr; -#ifdef __sparc__ Elf32_Rela *rela; Elf32_Sym *sym; - ptr_t symTab; -#else + ptr_t symTab = NULL; Elf32_Rel *rel; -#endif unsigned prot, flags, reloffs; int i, j, relocsz = 0, reltype, badreloc = 0, err; void *relptr; @@ -877,93 +874,80 @@ int process_load(process_t *process, vm_object_t *o, off_t base, size_t size, vo return -ENOEXEC; } -#ifdef __sparc__ /* find symtab */ for (i = 0, shdr = (void *)((char *)ehdr + ehdr->e_shoff); i < ehdr->e_shnum; i++, shdr++) { if (hal_strcmp(&snameTab[shdr->sh_name], ".symtab") == 0) { + symTab = (ptr_t)ehdr + (ptr_t)shdr->sh_offset; break; } } - if (i >= ehdr->e_shnum) { - return -ENOEXEC; - } - symTab = (ptr_t)ehdr + (ptr_t)shdr->sh_offset; - /* Perform data, init_array and fini_array relocation */ for (i = 0, shdr = (void *)((char *)ehdr + ehdr->e_shoff); i < ehdr->e_shnum; i++, shdr++) { - /* strncmp as there may be multiple .rela.* sections for different sections. */ - if (hal_strncmp(&snameTab[shdr->sh_name], ".rela", 5) != 0) { - continue; - } - if ((shdr->sh_size == 0) || (shdr->sh_entsize == 0)) { continue; } - for (j = 0; j < shdr->sh_size / shdr->sh_entsize; ++j) { - rela = (Elf32_Rela *)((ptr_t)shdr->sh_offset + (ptr_t)ehdr + (j * shdr->sh_entsize)); - reltype = ELF32_R_TYPE(rela->r_info); - - if (reltype == R_SPARC_32) { - relptr = (void *)rela->r_offset; - if (process_relocate(reloc, relocsz, (char **)&relptr) < 0) { - return -ENOEXEC; - } - - /* Don't modify ELF file! */ - if (((ptr_t)relptr >= (ptr_t)base) && ((ptr_t)relptr < ((ptr_t)base + size))) { - ++badreloc; - continue; - } - - sym = (Elf32_Sym *)(symTab + (ELF32_R_SYM(rela->r_info) * sizeof(Elf32_Sym))); - - /* Write addend to the address */ - *(char **)relptr = (char *)(sym->st_value + rela->r_addend); - - if (process_relocate(reloc, relocsz, relptr) < 0) { - return -ENOEXEC; + /* strncmp as there may be multiple .rela.* or .rel.* sections for different sections. */ + if (hal_strncmp(&snameTab[shdr->sh_name], ".rela.", 6) == 0) { + /* From currently supported NOMMU platforms only SPARC uses RELA */ + for (j = 0; j < shdr->sh_size / shdr->sh_entsize; ++j) { + rela = (Elf32_Rela *)((ptr_t)shdr->sh_offset + (ptr_t)ehdr + (j * shdr->sh_entsize)); + reltype = ELF32_R_TYPE(rela->r_info); + + if (reltype == R_SPARC_32) { + if (symTab == NULL) { + return -ENOEXEC; + } + + relptr = (void *)rela->r_offset; + if (process_relocate(reloc, relocsz, (char **)&relptr) < 0) { + return -ENOEXEC; + } + + /* Don't modify ELF file! */ + if (((ptr_t)relptr >= (ptr_t)base) && ((ptr_t)relptr < ((ptr_t)base + size))) { + ++badreloc; + continue; + } + + sym = (Elf32_Sym *)(symTab + (ELF32_R_SYM(rela->r_info) * sizeof(Elf32_Sym))); + + /* Write addend to the address */ + *(char **)relptr = (char *)(sym->st_value + rela->r_addend); + + if (process_relocate(reloc, relocsz, relptr) < 0) { + return -ENOEXEC; + } } } } - } -#else - /* Perform data, init_array and fini_array relocation */ - for (i = 0, shdr = (void *)((char *)ehdr + ehdr->e_shoff); i < ehdr->e_shnum; i++, shdr++) { - /* strncmp as there may be multiple .rel.* sections for different sections. */ - if (hal_strncmp(&snameTab[shdr->sh_name], ".rel", 4) != 0) { - continue; - } - - if ((shdr->sh_size == 0) || (shdr->sh_entsize == 0)) { - continue; - } - - for (j = 0; j < shdr->sh_size / shdr->sh_entsize; ++j) { - rel = (void *)((ptr_t)shdr->sh_offset + (ptr_t)ehdr + (j * shdr->sh_entsize)); - reltype = ELF32_R_TYPE(rel->r_info); - - if (reltype == R_ARM_ABS32 || reltype == R_ARM_TARGET1) { - relptr = (void *)rel->r_offset; - - if (process_relocate(reloc, relocsz, (char **)&relptr) < 0) { - return -ENOEXEC; - } - - /* Don't modify ELF file! */ - if (((ptr_t)relptr >= (ptr_t)base) && ((ptr_t)relptr < ((ptr_t)base + size))) { - ++badreloc; - continue; - } - - if (process_relocate(reloc, relocsz, relptr) < 0) { - return -ENOEXEC; + else if (hal_strncmp(&snameTab[shdr->sh_name], ".rel.", 5) == 0) { + /* From currently supported NOMMU platforms only ARM uses REL */ + for (j = 0; j < shdr->sh_size / shdr->sh_entsize; ++j) { + rel = (void *)((ptr_t)shdr->sh_offset + (ptr_t)ehdr + (j * shdr->sh_entsize)); + reltype = ELF32_R_TYPE(rel->r_info); + + if (reltype == R_ARM_ABS32 || reltype == R_ARM_TARGET1) { + relptr = (void *)rel->r_offset; + + if (process_relocate(reloc, relocsz, (char **)&relptr) < 0) { + return -ENOEXEC; + } + + /* Don't modify ELF file! */ + if (((ptr_t)relptr >= (ptr_t)base) && ((ptr_t)relptr < ((ptr_t)base + size))) { + ++badreloc; + continue; + } + + if (process_relocate(reloc, relocsz, relptr) < 0) { + return -ENOEXEC; + } } } } } -#endif tlsNew.tls_base = NULL; tlsNew.tdata_sz = 0;