-
Notifications
You must be signed in to change notification settings - Fork 137
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #129 from fjtrujy/loadELF
Create a library to make easier the Loading of ELF files
- Loading branch information
Showing
9 changed files
with
372 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# _____ ___ ____ ___ ____ | ||
# ____| | ____| | | |____| | ||
# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. | ||
#----------------------------------------------------------------------- | ||
# (c) 2020 Francisco Javier Trujillo Mata <[email protected]> | ||
# Licenced under Academic Free License version 2.0 | ||
# Review ps2sdk README & LICENSE files for further details. | ||
|
||
EE_OBJS = elf.o loader.o | ||
|
||
all:: prepareLoader $(EE_LIB) | ||
|
||
clean:: cleanLoader | ||
|
||
prepareLoader: | ||
$(MAKE) -C src/loader | ||
$(PS2SDKSRC)/tools/bin2c/bin/bin2c src/loader/loader.elf src/loader.c loader_elf | ||
|
||
cleanLoader: | ||
$(MAKE) -C src/loader clean | ||
|
||
include $(PS2SDKSRC)/Defs.make | ||
include $(PS2SDKSRC)/ee/Rules.lib.make | ||
include $(PS2SDKSRC)/ee/Rules.make | ||
include $(PS2SDKSRC)/ee/Rules.release |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/* | ||
# _____ ___ ____ ___ ____ | ||
# ____| | ____| | | |____| | ||
# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. | ||
#----------------------------------------------------------------------- | ||
# (c) 2020 Francisco Javier Trujillo Mata <[email protected]> | ||
# Licenced under Academic Free License version 2.0 | ||
# Review ps2sdk README & LICENSE files for further details. | ||
*/ | ||
|
||
/** | ||
* @file | ||
* ELF Loader functions. | ||
*/ | ||
|
||
#ifndef __ELFLOADER_H__ | ||
#define __ELFLOADER_H__ | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
// Before call this method be sure that you have previously called sbv_patch_disable_prefix_check(); | ||
int LoadELFFromFile(const char *filename, int argc, char *argv[]); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* __ELFLOADER_H__ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# c representation of generated loader.elf | ||
loader.c |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
/* | ||
# _____ ___ ____ ___ ____ | ||
# ____| | ____| | | |____| | ||
# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. | ||
#----------------------------------------------------------------------- | ||
# (c) 2020 Francisco Javier Trujillo Mata <[email protected]> | ||
# Licenced under Academic Free License version 2.0 | ||
# Review ps2sdk README & LICENSE files for further details. | ||
*/ | ||
|
||
#include <string.h> | ||
#include <sifrpc.h> | ||
#include <kernel.h> | ||
#include <sys/stat.h> | ||
#include <stdbool.h> | ||
#include <malloc.h> | ||
|
||
#include "elf.h" | ||
|
||
// Loader ELF variables | ||
extern u8 loader_elf[]; | ||
extern int size_loader_elf; | ||
|
||
// ELF-loading stuff | ||
#define ELF_MAGIC 0x464c457f | ||
#define ELF_PT_LOAD 1 | ||
|
||
static bool file_exists(const char *filename) { | ||
struct stat buffer; | ||
return (stat (filename, &buffer) == 0); | ||
} | ||
|
||
int LoadELFFromFile(const char *filename, int argc, char *argv[]) | ||
{ | ||
u8 *boot_elf; | ||
elf_header_t *eh; | ||
elf_pheader_t *eph; | ||
void *pdata; | ||
int i; | ||
int new_argc = argc + 1; | ||
|
||
// We need to check that the ELF file before continue | ||
if (!file_exists(filename)) { | ||
return -1; // ELF file doesn't exists | ||
} | ||
// ELF Exists | ||
char *new_argv[new_argc]; | ||
|
||
new_argv[0] = (char *)filename; | ||
for (i = 0; i < argc; i++) { | ||
new_argv[i + 1] = argv[i]; | ||
} | ||
|
||
/* NB: LOADER.ELF is embedded */ | ||
boot_elf = (u8 *)loader_elf; | ||
eh = (elf_header_t *)boot_elf; | ||
if (_lw((u32)&eh->ident) != ELF_MAGIC) | ||
asm volatile("break\n"); | ||
|
||
eph = (elf_pheader_t *)(boot_elf + eh->phoff); | ||
|
||
/* Scan through the ELF's program headers and copy them into RAM, then zero out any non-loaded regions. */ | ||
for (i = 0; i < eh->phnum; i++) { | ||
if (eph[i].type != ELF_PT_LOAD) | ||
continue; | ||
|
||
pdata = (void *)(boot_elf + eph[i].offset); | ||
memcpy(eph[i].vaddr, pdata, eph[i].filesz); | ||
|
||
if (eph[i].memsz > eph[i].filesz) | ||
memset(eph[i].vaddr + eph[i].filesz, 0, eph[i].memsz - eph[i].filesz); | ||
} | ||
|
||
/* Let's go. */ | ||
SifExitRpc(); | ||
FlushCache(0); | ||
FlushCache(2); | ||
|
||
return ExecPS2((void *)eh->entry, NULL, new_argc, new_argv); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* | ||
# _____ ___ ____ ___ ____ | ||
# ____| | ____| | | |____| | ||
# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. | ||
#----------------------------------------------------------------------- | ||
# (c) 2020 Francisco Javier Trujillo Mata <[email protected]> | ||
# Licenced under Academic Free License version 2.0 | ||
# Review ps2sdk README & LICENSE files for further details. | ||
*/ | ||
|
||
#ifndef __ELF_H__ | ||
#define __ELF_H__ | ||
|
||
#include <tamtypes.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
typedef struct | ||
{ | ||
u8 ident[16]; // struct definition for ELF object header | ||
u16 type; | ||
u16 machine; | ||
u32 version; | ||
u32 entry; | ||
u32 phoff; | ||
u32 shoff; | ||
u32 flags; | ||
u16 ehsize; | ||
u16 phentsize; | ||
u16 phnum; | ||
u16 shentsize; | ||
u16 shnum; | ||
u16 shstrndx; | ||
} elf_header_t; | ||
|
||
typedef struct | ||
{ | ||
u32 type; // struct definition for ELF program section header | ||
u32 offset; | ||
void *vaddr; | ||
u32 paddr; | ||
u32 filesz; | ||
u32 memsz; | ||
u32 flags; | ||
u32 align; | ||
} elf_pheader_t; | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* __ELF_H__ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# _____ ___ ____ ___ ____ | ||
# ____| | ____| | | |____| | ||
# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. | ||
#----------------------------------------------------------------------- | ||
# (c) 2020 Francisco Javier Trujillo Mata <[email protected]> | ||
# Licenced under Academic Free License version 2.0 | ||
# Review ps2sdk README & LICENSE files for further details. | ||
|
||
### Adjust these three, for PS2Link compatibility tests | ||
### Old LaunchELF used LA=0x90000, SA=0xB0000, SS=0x08000 | ||
LOADADDR = 0x90000 | ||
STACKADDR = 0xA8000 | ||
STACKSIZE = 0x04000 | ||
|
||
ifeq ($(DEBUG),1) | ||
LOADADDR = 0x1700000 | ||
STACKADDR = 0x1720000 | ||
STACKSIZE = 0x08000 | ||
endif | ||
|
||
LDPARAMS := -Wl,--defsym -Wl,_stack_size=$(STACKSIZE) -Wl,--defsym -Wl,_stack=$(STACKADDR) | ||
|
||
EE_LDFLAGS += -Wl,-Ttext -Wl,$(LOADADDR) -s $(LDPARAMS) | ||
|
||
EE_BIN = loader.elf | ||
|
||
EE_OBJS = loader.o | ||
|
||
EE_LIBS = | ||
ifeq ($(DEBUG),1) | ||
EE_LIBS += -ldebug | ||
endif | ||
|
||
all: $(EE_BIN) | ||
|
||
clean: | ||
rm -f -r $(EE_OBJS) $(EE_BIN) | ||
|
||
include $(PS2SDKSRC)/Defs.make | ||
include Rules.make |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# _____ ___ ____ ___ ____ | ||
# ____| | ____| | | |____| | ||
# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. | ||
#----------------------------------------------------------------------- | ||
# Copyright 2001-2004, ps2dev - http://www.ps2dev.org | ||
# Licenced under Academic Free License version 2.0 | ||
# Review ps2sdk README & LICENSE files for further details. | ||
|
||
EE_CC_VERSION := $(shell $(EE_CC) -dumpversion) | ||
|
||
EE_SRC_DIR ?= src/ | ||
EE_INC_DIR ?= include/ | ||
|
||
# Include directories | ||
EE_INCS := $(EE_INCS) -I$(EE_SRC_DIR) -I$(EE_SRC_DIR)include -I$(EE_INC_DIR) -I$(PS2SDKSRC)/ee/kernel/include -I$(PS2SDKSRC)/common/include -I$(PS2SDKSRC)/ee/libc/include -I$(PS2SDKSRC)/ee/erl/include | ||
|
||
# C compiler flags | ||
EE_CFLAGS := -D_EE -O2 -G0 -Wall -Werror $(EE_CFLAGS) | ||
|
||
# C++ compiler flags | ||
EE_CXXFLAGS := -D_EE -O2 -G0 -Wall -Werror $(EE_CXXFLAGS) | ||
|
||
# Linker flags | ||
EE_LDFLAGS := -L$(PS2SDKSRC)/ee/kernel/lib -L$(PS2SDKSRC)/ee/libc/lib $(EE_LDFLAGS) | ||
|
||
# Assembler flags | ||
EE_ASFLAGS := -G0 $(EE_ASFLAGS) | ||
|
||
# Externally defined variables: EE_BIN, EE_OBJS, EE_LIB | ||
|
||
# _____ ___ ____ ___ ____ | ||
# ____| | ____| | | |____| | ||
# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. | ||
#----------------------------------------------------------------------- | ||
# (c) 2020 Francisco Javier Trujillo Mata <[email protected]> | ||
# Licenced under Academic Free License version 2.0 | ||
# Review ps2sdk README & LICENSE files for further details. | ||
|
||
# These macros can be used to simplify certain build rules. | ||
EE_C_COMPILE = $(EE_CC) $(EE_CFLAGS) $(EE_INCS) | ||
EE_CXX_COMPILE = $(EE_CXX) $(EE_CXXFLAGS) $(EE_INCS) | ||
|
||
%.o: %.c | ||
$(EE_CC) $(EE_CFLAGS) $(EE_INCS) -c $< -o $@ | ||
|
||
%.o: %.cc | ||
$(EE_CXX) $(EE_CXXFLAGS) $(EE_INCS) -c $< -o $@ | ||
|
||
%.o: %.cpp | ||
$(EE_CXX) $(EE_CXXFLAGS) $(EE_INCS) -c $< -o $@ | ||
|
||
%.o: %.S | ||
$(EE_CC) $(EE_CFLAGS) $(EE_INCS) -c $< -o $@ | ||
|
||
%.o: %.s | ||
$(EE_AS) $(EE_ASFLAGS) $< -o $@ | ||
|
||
$(EE_BIN): $(EE_OBJS) | ||
$(EE_CC) $(EE_CFLAGS) -o $(EE_BIN) $(EE_OBJS) $(EE_LDFLAGS) $(EE_LIBS) | ||
|
||
$(EE_ERL): $(EE_OBJS) | ||
$(EE_CC) -o $(EE_ERL) $(EE_OBJS) $(EE_CFLAGS) $(EE_LDFLAGS) -Wl,-r -Wl,-d | ||
$(EE_STRIP) --strip-unneeded -R .mdebug.eabi64 -R .reginfo -R .comment $(EE_ERL) | ||
|
||
$(EE_LIB): $(EE_OBJS) | ||
$(EE_AR) cru $(EE_LIB) $(EE_OBJS) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
/* | ||
# _____ ___ ____ ___ ____ | ||
# ____| | ____| | | |____| | ||
# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. | ||
#----------------------------------------------------------------------- | ||
# (c) 2020 Francisco Javier Trujillo Mata <[email protected]> | ||
# Licenced under Academic Free License version 2.0 | ||
# Review ps2sdk README & LICENSE files for further details. | ||
*/ | ||
|
||
#include <kernel.h> | ||
#include <loadfile.h> | ||
#include <sifrpc.h> | ||
#include <errno.h> | ||
|
||
//-------------------------------------------------------------- | ||
//Start of function code: | ||
//-------------------------------------------------------------- | ||
// Clear user memory | ||
// PS2Link (C) 2003 Tord Lindstrom ([email protected]) | ||
// (C) 2003 adresd ([email protected]) | ||
//-------------------------------------------------------------- | ||
static void wipeUserMem(void) | ||
{ | ||
int i; | ||
for (i = 0x100000; i < GetMemorySize(); i += 64) { | ||
asm volatile( | ||
"\tsq $0, 0(%0) \n" | ||
"\tsq $0, 16(%0) \n" | ||
"\tsq $0, 32(%0) \n" | ||
"\tsq $0, 48(%0) \n" ::"r"(i)); | ||
} | ||
} | ||
|
||
//-------------------------------------------------------------- | ||
//End of func: void wipeUserMem(void) | ||
//-------------------------------------------------------------- | ||
// *** MAIN *** | ||
//-------------------------------------------------------------- | ||
int main(int argc, char *argv[]) | ||
{ | ||
static t_ExecData elfdata; | ||
int ret; | ||
|
||
if (argc < 1) { // arg1=path to ELF | ||
return -EINVAL; | ||
} | ||
|
||
// Initialize | ||
SifInitRpc(0); | ||
wipeUserMem(); | ||
|
||
//Writeback data cache before loading ELF. | ||
FlushCache(0); | ||
ret = SifLoadElf(argv[0], &elfdata); | ||
if (ret == 0) { | ||
SifExitRpc(); | ||
FlushCache(0); | ||
FlushCache(2); | ||
|
||
// Following the standard the first parameter of a argv is the executable itself | ||
return ExecPS2((void *)elfdata.epc, (void *)elfdata.gp, argc, argv); | ||
} else { | ||
SifExitRpc(); | ||
return -ENOENT; | ||
} | ||
} | ||
|
||
//-------------------------------------------------------------- | ||
//End of func: int main(int argc, char *argv[]) | ||
//-------------------------------------------------------------- | ||
//End of file: loader.c | ||
//-------------------------------------------------------------- |