From 63419d9cc07c56234d0f61a80f32105b192aec8e Mon Sep 17 00:00:00 2001 From: "John Wilbert M. Villamor" Date: Thu, 18 Feb 2021 13:31:17 +0800 Subject: Lots of makefile corrections, improved build and toolchain instructions, added elf2cpe converter, fixed typo in plasma_tbl.h of n00bdemo example --- tools/util/elf.h | 45 +++++++++ tools/util/elf2cpe.c | 251 +++++++++++++++++++++++++++++++++++++++++++++++++++ tools/util/elf2x.c | 45 +-------- tools/util/makefile | 1 + 4 files changed, 300 insertions(+), 42 deletions(-) create mode 100644 tools/util/elf.h create mode 100644 tools/util/elf2cpe.c (limited to 'tools') diff --git a/tools/util/elf.h b/tools/util/elf.h new file mode 100644 index 0000000..9cb5cb3 --- /dev/null +++ b/tools/util/elf.h @@ -0,0 +1,45 @@ +#ifndef _ELF_H +#define _ELF_H + +#pragma pack(push, 1) + +typedef struct { + + unsigned int magic; // 0-3 + unsigned char word_size; // 4 + unsigned char endianness; // 5 + unsigned char elf_version; // 6 + unsigned char os_abi; // 7 + unsigned int unused[2]; // 8-15 + + unsigned short type; // 16-17 + unsigned short instr_set; // 18-19 + unsigned int elf_version2; // 20-23 + + unsigned int prg_entry_addr; // 24-27 + unsigned int prg_head_pos; // 28-31 + unsigned int sec_head_pos; // 32-35 + unsigned int flags; // 36-39 + unsigned short head_size; // 40-41 + unsigned short prg_entry_size; // 42-23 + unsigned short prg_entry_count; // 44-45 + unsigned short sec_entry_size; // 46-47 + unsigned short sec_entry_count; // 48-49 + unsigned short sec_names_index; // 50-51 + +} ELF_HEADER; + +typedef struct { + unsigned int seg_type; + unsigned int p_offset; + unsigned int p_vaddr; + unsigned int undefined; + unsigned int p_filesz; + unsigned int p_memsz; + unsigned int flags; + unsigned int alignment; +} PRG_HEADER; + +#pragma pack(pop) + +#endif /* _ELF_H */ \ No newline at end of file diff --git a/tools/util/elf2cpe.c b/tools/util/elf2cpe.c new file mode 100644 index 0000000..4379f4a --- /dev/null +++ b/tools/util/elf2cpe.c @@ -0,0 +1,251 @@ +#include +#include +#include +#include "elf.h" + +#define MAX_prg_entry_count 128 + +#ifndef false +#define false 0 +#endif + +#ifndef true +#define true 1 +#endif + +char *in_file = NULL; +char *out_file = NULL; + +int quiet; + +int copydata( FILE *in, FILE *out, int len ) +{ + char buff[8192]; + int i,readlen; + + while( len > 0 ) + { + readlen = len; + if( readlen > 8192 ) + { + readlen = 8192; + } + + i = fread( buff, 1, readlen, in ); + fwrite( buff, 1, i, out ); + + if( i < readlen ) + { + break; + } + len -= readlen; + } + + return( 0 ); + +} /* copydata */ + +int convertELF( void ) +{ + ELF_HEADER head; + PRG_HEADER prg_heads[MAX_prg_entry_count]; + + int i; + char *output_name; + + FILE *in_fp; + FILE *out_fp; + + /* Generate output filename if no output is specified */ + if( out_file ) + { + output_name = out_file; + } + else + { + char *ptr; + + output_name = strdup( in_file ); + + ptr = &output_name[strlen(output_name)]; + while (ptr != output_name) + { + if (*ptr == '.') + break; + else + ptr--; + } + + if( ptr != output_name ) + { + strcpy( ptr, ".cpe" ); + } + else + { + strcat( ptr, ".cpe" ); + } + } + + if( !out_file ) + { + free( output_name ); + } + + if( !( in_fp = fopen( in_file, "rb" ) ) ) + { + printf( "Cannot open input file.\n" ); + return( -1 ); + } + + /* read ELF header */ + fread( &head, 1, sizeof(head), in_fp ); + + /* test header to make sure it is valid */ + if( head.magic != 0x464c457f ) + { + printf( "File is not an ELF file.\n" ); + fclose( in_fp ); + return( -1 ); + } + + if( head.type != 2 ) + { + printf( "Only executable ELF files are supported.\n" ); + fclose( in_fp ); + return( -1 ); + } + + if( head.instr_set != 8 ) + { + printf( "ELF file is not a MIPS binary.\n" ); + fclose( in_fp ); + return( -1 ); + } + + if( head.word_size != 1 ) + { + printf( "Only 32-bit ELF files are supported.\n" ); + fclose( in_fp ); + return( -1 ); + } + + if( head.endianness != 1 ) + { + printf( "Only little endian ELF files are supported.\n" ); + fclose( in_fp ); + return( -1 ); + } + + /* read program headers */ + fseek( in_fp, head.prg_head_pos, SEEK_SET ); + fread( prg_heads, sizeof( PRG_HEADER ), head.prg_entry_count, in_fp ); + + if( !quiet ) + { + printf( "pc:%08x\n", head.prg_entry_addr ); + } + + /* create the CPE file */ + printf( "%s\n", output_name ); + if( !( out_fp = fopen( output_name, "wb" ) ) ) + { + printf( "Cannot create output file.\n" ); + return( -1 ); + } + + /* create file header */ + fputs( "CPE", out_fp ); + fputc( 0x01, out_fp ); + + /* select unit 0 */ + fputc( 0x08, out_fp ); /* chunk ID */ + fputc( 0x00, out_fp ); /* unit number */ + + /* set entrypoint */ + fputc( 0x03, out_fp ); /* chunk ID */ + fputc( 0x90, out_fp ); /* entry point type */ + fputc( 0x00, out_fp ); + fwrite( &head.prg_entry_addr, 1, 4, out_fp ); + + /* copy the program chunks */ + for( i=0; i [cpe_file]\n" ); + return( 0 ); + } + + if( !in_file ) + { + printf( "No input file specified.\n" ); + return( 0 ); + } + + return( convertELF() ); + +} /* main */ \ No newline at end of file diff --git a/tools/util/elf2x.c b/tools/util/elf2x.c index 612ca41..26ec9a3 100644 --- a/tools/util/elf2x.c +++ b/tools/util/elf2x.c @@ -4,52 +4,12 @@ #include #include #include +#include "elf.h" #define MAX_prg_entry_count 128 #define true (1) #define false (0) -#pragma pack(push, 1) - -typedef struct { - - unsigned int magic; // 0-3 - unsigned char word_size; // 4 - unsigned char endianness; // 5 - unsigned char elf_version; // 6 - unsigned char os_abi; // 7 - unsigned int unused[2]; // 8-15 - - unsigned short type; // 16-17 - unsigned short instr_set; // 18-19 - unsigned int elf_version2; // 20-23 - - unsigned int prg_entry_addr; // 24-27 - unsigned int prg_head_pos; // 28-31 - unsigned int sec_head_pos; // 32-35 - unsigned int flags; // 36-39 - unsigned short head_size; // 40-41 - unsigned short prg_entry_size; // 42-23 - unsigned short prg_entry_count; // 44-45 - unsigned short sec_entry_size; // 46-47 - unsigned short sec_entry_count; // 48-49 - unsigned short sec_names_index; // 50-51 - -} ELF_HEADER; - -typedef struct { - unsigned int seg_type; - unsigned int p_offset; - unsigned int p_vaddr; - unsigned int undefined; - unsigned int p_filesz; - unsigned int p_memsz; - unsigned int flags; - unsigned int alignment; -} PRG_HEADER; - -#pragma pack(pop) - typedef struct { unsigned int pc0; unsigned int gp0; @@ -112,7 +72,7 @@ int main(int argc, char** argv) { if( !quiet ) { printf( "PSn00bSDK elf2x - ELF to PS-EXE Converter\n" ); - printf( "2018-2019 Meido-Tek Productions\n\n" ); + printf( "2018-2021 Meido-Tek Productions\n\n" ); } if( argc == 1 ) { @@ -140,6 +100,7 @@ int main(int argc, char** argv) { // Check header if( head.magic != 0x464c457f ) { printf( "File is not an ELF file.\n" ); + fclose( fp ); return EXIT_FAILURE; } diff --git a/tools/util/makefile b/tools/util/makefile index c49a581..fe7aed5 100644 --- a/tools/util/makefile +++ b/tools/util/makefile @@ -10,6 +10,7 @@ endif all: $(CC) $(CFLAGS) elf2x.c -o elf2x$(EXE_SUFFIX) + $(CC) $(CFLAGS) elf2cpe.c -o elf2cpe$(EXE_SUFFIX) install: mkdir -p ../bin -- cgit v1.2.3