Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

process: unify load on NOMMU #611

Merged
merged 1 commit into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions hal/armv7m/arch/elf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* 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_ARMV7M_ELF_H_
#define _HAL_ARMV7M_ELF_H_


#define R_ARM_ABS32 2
agkaminski marked this conversation as resolved.
Show resolved Hide resolved
#define R_ARM_TARGET1 38


static inline int hal_isRelReloc(int relType)
{
return ((relType == R_ARM_ABS32) || (relType == R_ARM_TARGET1)) ? 1 : 0;
}

#endif
30 changes: 30 additions & 0 deletions hal/armv8m/arch/elf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* 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_ARMV8M_ELF_H_
#define _HAL_ARMV8M_ELF_H_


#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)) ? 1 : 0;
}

#endif
29 changes: 29 additions & 0 deletions hal/armv8r/arch/elf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* 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_ARMV8R_ELF_H_
#define _HAL_ARMV8R_ELF_H_


#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)) ? 1 : 0;
}

#endif
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) ? 1 : 0;
}
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
116 changes: 48 additions & 68 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,15 +743,12 @@ 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;
int i, j, relocsz = 0, badreloc = 0, err;
void *relptr;
char *snameTab;
ptr_t *got;
Expand Down Expand Up @@ -877,93 +875,75 @@ 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);

if (reltype == R_ARM_ABS32 || reltype == R_ARM_TARGET1) {
relptr = (void *)rel->r_offset;
if (hal_isRelReloc(ELF32_R_TYPE(rela.r_info)) == 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 is stored in the location. */
*(char **)relptr += symval;
}
else {
*(char **)relptr = (char *)(symval + rela.r_addend);
lukileczo marked this conversation as resolved.
Show resolved Hide resolved
}

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

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