Skip to content

Commit

Permalink
process: unify load on NOMMU
Browse files Browse the repository at this point in the history
JIRA: RTOS-958
  • Loading branch information
badochov committed Oct 23, 2024
1 parent a6de825 commit e448443
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 73 deletions.
24 changes: 24 additions & 0 deletions hal/armv7m/arch/elf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Phoenix-RTOS
*
* Operating system kernel
*
* Hardware Abstraction Layer ELF support
*
* Copyright 2024 Phoenix Systems
* Author: Hubert Badocha
*
* This file is part of Phoenix-RTOS.
*
* %LICENSE%
*/


#define R_ARM_ABS32 2
#define R_ARM_TARGET1 38


static inline int hal_isRelReloc(int relType)
{
return (relType == R_ARM_ABS32) || (relType == R_ARM_TARGET1);
}
24 changes: 24 additions & 0 deletions hal/armv8m/arch/elf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Phoenix-RTOS
*
* Operating system kernel
*
* Hardware Abstraction Layer ELF support
*
* Copyright 2024 Phoenix Systems
* Author: Hubert Badocha
*
* This file is part of Phoenix-RTOS.
*
* %LICENSE%
*/


#define R_ARM_ABS32 2
#define R_ARM_TARGET1 38


static inline int hal_isRelReloc(int relType)
{
return (relType == R_ARM_ABS32) || (relType == R_ARM_TARGET1);
}
24 changes: 24 additions & 0 deletions hal/armv8r/arch/elf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Phoenix-RTOS
*
* Operating system kernel
*
* Hardware Abstraction Layer ELF support
*
* Copyright 2024 Phoenix Systems
* Author: Hubert Badocha
*
* This file is part of Phoenix-RTOS.
*
* %LICENSE%
*/


#define R_ARM_ABS32 2
#define R_ARM_TARGET1 38


static inline int hal_isRelReloc(int relType)
{
return (relType == R_ARM_ABS32) || (relType == R_ARM_TARGET1);
}
32 changes: 32 additions & 0 deletions hal/elf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Phoenix-RTOS
*
* Operating system kernel
*
* Hardware Abstraction Layer ELF support
*
* Copyright 2024 Phoenix Systems
* Author: Hubert Badocha
*
* This file is part of Phoenix-RTOS.
*
* %LICENSE%
*/

#ifndef _HAL_ELF_H_
#define _HAL_ELF_H_


#ifdef NOMMU


#include <arch/elf.h>


static int hal_isRelReloc(int relType);


#endif


#endif
22 changes: 22 additions & 0 deletions hal/sparcv8leon3/arch/elf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Phoenix-RTOS
*
* Operating system kernel
*
* Hardware Abstraction Layer ELF support
*
* Copyright 2024 Phoenix Systems
* Author: Hubert Badocha
*
* This file is part of Phoenix-RTOS.
*
* %LICENSE%
*/

#define R_SPARC_32 3


static inline int hal_isRelReloc(int relType)
{
return (relType == R_SPARC_32);
}
6 changes: 0 additions & 6 deletions proc/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,10 +180,4 @@ typedef struct {
#define ELF32_R_INFO(sym, type) (((sym)<<8)+(unsigned char)(type))


#define R_ARM_ABS32 2
#define R_ARM_GOT_BREL 26
#define R_ARM_TARGET1 38
#define R_SPARC_32 3


#endif
115 changes: 48 additions & 67 deletions proc/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

#include "hal/hal.h"
#include "hal/elf.h"
#include "include/errno.h"
#include "include/signal.h"
#include "vm/vm.h"
Expand Down Expand Up @@ -742,13 +743,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
Elf32_Rel *rel;
#endif
Elf32_Rela rela;
int isrela;
Elf32_Addr symval;
Elf32_Sym *symTab = NULL;
unsigned prot, flags, reloffs;
int i, j, relocsz = 0, reltype, badreloc = 0, err;
void *relptr;
Expand Down Expand Up @@ -877,93 +875,76 @@ 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 = (void *)((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) {
isrela = 1;
}
}
#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;
else if (hal_strncmp(&snameTab[shdr->sh_name], ".rel.", 5) == 0) {
isrela = 0;
}

if ((shdr->sh_size == 0) || (shdr->sh_entsize == 0)) {
else {
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);
for (j = 0; j < (shdr->sh_size / shdr->sh_entsize); ++j) {
/* Valid for both Elf32_Rela and Elf32_Rel, due to correct size being stored in shdr->sh_entsize. */
/* For .rel. section make sure not to access addend field! */
hal_memcpy(&rela, (Elf32_Rela *)((ptr_t)shdr->sh_offset + (ptr_t)ehdr + (j * shdr->sh_entsize)), shdr->sh_entsize);
reltype = ELF32_R_TYPE(rela.r_info);

if (reltype == R_ARM_ABS32 || reltype == R_ARM_TARGET1) {
relptr = (void *)rel->r_offset;
if (hal_isRelReloc(reltype) == 0) {
continue;
}

if (process_relocate(reloc, relocsz, (char **)&relptr) < 0) {
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;
}
/* 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) {
if (symTab == NULL) {
/* Accept files stripped from symtab if only SYM_UND is present, eg. files stripped with strip.py */
if (ELF32_R_SYM(rela.r_info) != 0) {
return -ENOEXEC;
}
symval = 0;
}
else {
symval = symTab[ELF32_R_SYM(rela.r_info)].st_value;
}

if (isrela == 0) {
/* If Rel is used addend stored is in the location. */
*(char **)relptr += symval;
}
else {
*(char **)relptr = (char *)(symval + rela.r_addend);
}

if (process_relocate(reloc, relocsz, relptr) < 0) {
return -ENOEXEC;
}
}
}
#endif

tlsNew.tls_base = NULL;
tlsNew.tdata_sz = 0;
Expand Down

0 comments on commit e448443

Please sign in to comment.