From: bogglez <bo...@us...> - 2017-03-09 23:50:41
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via c627b1798d8c845cd78a64314451a4daaa2c55dd (commit) via 626b4c782d3fcbbe0a02fb20f89c1408a0230278 (commit) via bfbe0a0bf4d61bd53304a6c82a175c7c70d8b7dc (commit) from 271c2a9383dbb811e5c753b14beac47fb18e3eb6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c627b1798d8c845cd78a64314451a4daaa2c55dd Author: bogglez <bo...@pr...> Date: Fri Mar 10 00:50:19 2017 +0100 man: remove empty SEE ALSO commit 626b4c782d3fcbbe0a02fb20f89c1408a0230278 Author: bogglez <bo...@pr...> Date: Fri Mar 10 00:49:38 2017 +0100 bincnv: add man page commit bfbe0a0bf4d61bd53304a6c82a175c7c70d8b7dc Author: bogglez <bo...@pr...> Date: Fri Mar 10 00:49:21 2017 +0100 bincnv: error checking, some refactoring ----------------------------------------------------------------------- Summary of changes: utils/bincnv/bincnv.8 | 28 +++++ utils/bincnv/bincnv.c | 248 +++++++++++++++++++++++++++----------------- utils/dcbumpgen/dcbumpgen.1 | 1 - utils/scramble/scramble.1 | 1 - utils/wav2adpcm/wav2adpcm.1 | 1 - 5 files changed, 183 insertions(+), 96 deletions(-) create mode 100644 utils/bincnv/bincnv.8 diff --git a/utils/bincnv/bincnv.8 b/utils/bincnv/bincnv.8 new file mode 100644 index 0000000..bbfcad1 --- /dev/null +++ b/utils/bincnv/bincnv.8 @@ -0,0 +1,28 @@ +.TH BINCNV 8 "Mar 2017" "Version 1.0" +.SH NAME +bincnv \- Test ELF to BIN converter +.SH SYNOPSIS +.B bincnv +[ +.B \-d +] +.IR from +.IR to + +.SH DESCRIPTION +.B bincnv +is used to test the ELF to BIN converter. +Loads to VMA 0x8c010000. This is an exact functional duplicate of the routine +in process/elf.c and is used for testing new changes first. +.SH EXAMPLES + +.EX +.B + bincnv from.elf to.bin +.EE + +.SH AUTHOR +This manual page was initially written by Stefan Galowicz <bo...@pr...>, +for the KOS project. +.TP +The program has been initially written by Dan Potter in 2000. diff --git a/utils/bincnv/bincnv.c b/utils/bincnv/bincnv.c index 08abee3..516bd56 100644 --- a/utils/bincnv/bincnv.c +++ b/utils/bincnv/bincnv.c @@ -11,6 +11,7 @@ #include <stdio.h> #include <stdlib.h> +#include <string.h> #define uint8 unsigned char #define uint16 unsigned short @@ -132,89 +133,152 @@ int find_sym(char *name, struct elf_sym_t* table, int tablelen) { return -1; } -/* There's a lot of shit in here that's not documented or very poorly - documented by Intel.. I hope that this works for future compilers. */ -void *elf_load(FILE *f, uint32 vma, int* outsz) { - char *img, *imgout; - int sz, i, j, sect; - struct elf_hdr_t *hdr; - struct elf_shdr_t *shdrs, *symtabhdr; - struct elf_sym_t *symtab; - int symtabsize; - struct elf_rela_t *reltab; - int reltabsize; - char *stringtab; - - /* Load the file */ +static int write_file_contents(char const * const filename, void * data, size_t size) { + FILE * f = fopen(filename, "wb"); + int ret = f && fwrite(data, size, 1, f) == 1; + fclose(f); + return ret; +} + +/** + * Helper function to load the raw texture data into an array. + * @param filename The filename of the texture. + * @param data A pointer to an array where the data should be stored. + * @param size A pointer to a variable where to size should be stored. + * @return 0 on success, non-zero on error. + */ +static int read_file_contents(char const * const filename, char **data, size_t *size) { + FILE *f = 0; + + f = fopen(filename, "rb"); + + // Read texture from file + if(!f) { + return 1; + } + fseek(f, 0, SEEK_END); - sz = ftell(f); - fseek(f, 0, SEEK_SET); - img = malloc(sz); - fread(img, sz, 1, f); + long imageSize = ftell(f); + rewind(f); + + *data = malloc(imageSize); + if(!*data) { + fclose(f); + return 2; + } + + if(fread(*data, imageSize, 1, f) != 1) { + free(*data); + fclose(f); + return 3; + } + fclose(f); - /* Header is at the front */ - hdr = (struct elf_hdr_t *)(img + 0); + *size = imageSize; + + return 0; +} + +static int build_memory_image(struct elf_shdr_t * shdrs, uint16 shnum) { + uint16 i; + size_t sz = 0; + for(i = 0; i < shnum; i++) { + if(shdrs[i].flags & SHF_ALLOC) { + shdrs[i].addr = sz; + sz += shdrs[i].size; + + if(shdrs[i].addralign && (shdrs[i].addr % shdrs[i].addralign)) { + shdrs[i].addr = (shdrs[i].addr + shdrs[i].addralign) + & ~(shdrs[i].addralign - 1); + } + } + } + + return sz; +} + +#define ERROR(...) { ret = 1; fprintf(stderr, __VA_ARGS__); goto cleanup; } + +/* There's a lot of shit in here that's not documented or very poorly + documented by Intel.. I hope that this works for future compilers. */ +static int elf_load(char ** out, size_t * outsz, char const * const filename, uint32 vma) { + int ret = 0; + char * img = 0; + char * imgout = 0; + size_t sz; + int i; + int j; + int sect; + struct elf_hdr_t * hdr; + struct elf_shdr_t * shdrs; + struct elf_shdr_t * symtabhdr; + struct elf_sym_t * symtab; + int symtabsize; + struct elf_rela_t * reltab; + int reltabsize; + char * stringtab; + + + if(read_file_contents(filename, &img, &sz)) { + ERROR("Cannot allocate memory.\n"); + } + + hdr = (struct elf_hdr_t*)img; - if(hdr->ident[0] != 0x7f || strncmp(hdr->ident + 1, "ELF", 3)) { - printf("File is not a valid ELF file\n"); - return NULL; + if(hdr->ident[0] != 0x7f || memcmp(hdr->ident + 1, "ELF", 3)) { + ERROR("File is not a valid ELF file\n"); } if(hdr->ident[4] != 1 || hdr->ident[5] != 1) { - printf("Invalid architecture flags in ELF file\n"); - return NULL; + ERROR("Invalid architecture flags in ELF file\n"); } if(hdr->machine != 0x2a) { - printf("Invalid architecture %02x in ELF file\n", hdr->machine); + ERROR("Invalid architecture %02x in ELF file\n", hdr->machine); } /* Print some debug info */ - printf("File size is %d bytes\n", sz); - printf(" entry point %08x\n", hdr->entry); - printf(" ph offset %08x\n", hdr->phoff); - printf(" sh offset %08x\n", hdr->shoff); - printf(" flags %08x\n", hdr->flags); - printf(" ehsize %08x\n", hdr->ehsize); - printf(" phentsize %08x\n", hdr->phentsize); - printf(" phnum %08x\n", hdr->phnum); - printf(" shentsize %08x\n", hdr->shentsize); - printf(" shnum %08x\n", hdr->shnum); - printf(" shstrndx %08x\n", hdr->shstrndx); + printf("File size is %zu bytes\n", sz); + printf(" entry point %08lx\n", hdr->entry); + printf(" ph offset %08lx\n", hdr->phoff); + printf(" sh offset %08lx\n", hdr->shoff); + printf(" flags %08lx\n", hdr->flags); + printf(" ehsize %08x\n", hdr->ehsize); + printf(" phentsize %08x\n", hdr->phentsize); + printf(" phnum %08x\n", hdr->phnum); + printf(" shentsize %08x\n", hdr->shentsize); + printf(" shnum %08x\n", hdr->shnum); + printf(" shstrndx %08x\n", hdr->shstrndx); /* Locate the string table; SH elf files ought to have two string tables, one for section names and one for object string names. We'll look for the latter. */ shdrs = (struct elf_shdr_t *)(img + hdr->shoff); - stringtab = NULL; + stringtab = 0; for(i = 0; i < hdr->shnum; i++) { - if(shdrs[i].type == SHT_STRTAB - && i != hdr->shstrndx) { + if(shdrs[i].type == SHT_STRTAB && i != hdr->shstrndx) { stringtab = (char*)(img + shdrs[i].offset); } } if(!stringtab) { - printf("ELF contains no object string table\n"); - return NULL; + ERROR("ELF contains no object string table\n"); } /* Locate the symbol table */ - symtabhdr = NULL; + symtabhdr = 0; for(i = 0; i < hdr->shnum; i++) { - if(shdrs[i].type == SHT_SYMTAB - || shdrs[i].type == SHT_DYNSYM) { + if(shdrs[i].type == SHT_SYMTAB || shdrs[i].type == SHT_DYNSYM) { symtabhdr = shdrs + i; break; } } if(!symtabhdr) { - printf("ELF contains no symbol table\n"); - return NULL; + ERROR("ELF contains no symbol table\n"); } symtab = (struct elf_sym_t *)(img + symtabhdr->offset); @@ -223,43 +287,33 @@ void *elf_load(FILE *f, uint32 vma, int* outsz) { /* Relocate symtab entries for quick access */ for(i = 0; i < symtabsize; i++) { symtab[i].name = (uint32)(stringtab + symtab[i].name); - printf("SYM: %s / %08x / %08x / %d\r\n", + printf("SYM: %s / %08lx / %08lx / %d\r\n", (char*)symtab[i].name, symtab[i].value, symtab[i].size, symtab[i].shndx); } for(i = 0; i < hdr->shnum; i++) { - printf(" Section %d: (%08x/%08x)\n", i, shdrs[i].name, shdrs[i].type); + printf(" Section %d: (%08lx/%08lx)\n", i, shdrs[i].name, shdrs[i].type); } /* Build the final memory image */ - sz = 0; - - for(i = 0; i < hdr->shnum; i++) { - if(shdrs[i].flags & SHF_ALLOC) { - shdrs[i].addr = sz; - sz += shdrs[i].size; - - if(shdrs[i].addralign && (shdrs[i].addr % shdrs[i].addralign)) { - shdrs[i].addr = - (shdrs[i].addr + shdrs[i].addralign) - & ~(shdrs[i].addralign - 1); - } - } - } - - printf("Final image is %d bytes\n", sz); + sz = build_memory_image(shdrs, hdr->shnum); + printf("Final image is %zu bytes\n", sz); imgout = malloc(sz); + if(!imgout) { + ERROR("Cannot allocate image.\n"); + goto cleanup; + } for(i = 0; i < hdr->shnum; i++) { if(shdrs[i].flags & SHF_ALLOC) { if(shdrs[i].type == SHT_NOBITS) { - printf("%d: setting %d bytes of zeros at %08x\n", + printf("%d: setting %ld bytes of zeros at %08lx\n", i, shdrs[i].size, shdrs[i].addr); memset(imgout + shdrs[i].addr, 0, shdrs[i].size); } else { - printf("%d: copying %d bytes from %08x to %08x\n", + printf("%d: copying %ld bytes from %08lx to %08lx\n", i, shdrs[i].size, shdrs[i].offset, shdrs[i].addr); memcpy(imgout + shdrs[i].addr, img + shdrs[i].offset, @@ -269,7 +323,7 @@ void *elf_load(FILE *f, uint32 vma, int* outsz) { } /* Find the RELA section; FIXME: More than one RELA section, REL sections */ - reltab = NULL; + reltab = 0; /*for (i=0; i<hdr->shnum; i++) { if (shdrs[i].type == SHT_RELA) { reltab = (struct elf_rela_t *)(img + shdrs[i].offset); @@ -278,7 +332,7 @@ void *elf_load(FILE *f, uint32 vma, int* outsz) { } if (!reltab) { printf("ELF contains no RELA section (did you use -r?)\n"); - return NULL; + return 0; } reltabsize = shdrs[i].size / sizeof(struct elf_rela_t); */ @@ -296,13 +350,12 @@ void *elf_load(FILE *f, uint32 vma, int* outsz) { int sym; if(ELF32_R_TYPE(reltab[j].info) != R_SH_DIR32) { - printf("ELF contains unknown RELA type %02x\r\n", + ERROR("ELF contains unknown RELA type %02x\r\n", ELF32_R_TYPE(reltab[j].info)); - return NULL; } sym = ELF32_R_SYM(reltab[j].info); - printf(" Writing REL %08x(%08x+%08x+%08x+%08x) -> %08x\r\n", + printf(" Writing REL %08lx(%08lx+%08lx+%08lx+%08lx) -> %08lx\r\n", vma + shdrs[symtab[sym].shndx].addr + symtab[sym].value + reltab[j].addend, vma, shdrs[symtab[sym].shndx].addr, symtab[sym].value, reltab[j].addend, vma + shdrs[sect].addr + reltab[j].offset); @@ -323,22 +376,19 @@ void *elf_load(FILE *f, uint32 vma, int* outsz) { mainsym = find_sym("_ko_main", symtab, symtabsize); if(mainsym < 0) { - printf("ELF contains no _ko_main\n"); - return NULL; + ERROR("ELF contains no _ko_main\n"); } getsvcsym = find_sym("_ko_get_svc", symtab, symtabsize); if(mainsym < 0) { - printf("ELF contains no _ko_get_svc\n"); - return NULL; + ERROR("ELF contains no _ko_get_svc\n"); } notifysym = find_sym("_ko_notify", symtab, symtabsize); if(notifysym < 0) { - printf("ELF contains no _ko_notify\n"); - return NULL; + ERROR("ELF contains no _ko_notify\n"); } /* Patch together getsvc and notify for now */ @@ -350,26 +400,38 @@ void *elf_load(FILE *f, uint32 vma, int* outsz) { + symtab[notifysym].value; } - free(img); - *outsz = sz; - return (void*)imgout; +cleanup: + if(!ret) { + *outsz = sz; + *out = imgout; + } + else if(imgout) { + free(imgout); + } + + if(img) free(img); + + return ret; } -void main(int argc, char **argv) { - FILE *f; - void *out; - int sz; +int main(int argc, char **argv) { + char * out; + size_t sz; - f = fopen(argv[1], "rb"); + if(argc != 3) { + puts("Usage: <infile> <outfile>"); + return 0; + } - if(!f) { - perror("Can't open input file"); - return; + if(elf_load(&out, &sz, argv[1], 0x8c010000)) { + fprintf(stderr, "Cannot load ELF file.\n"); + return 1; } - out = elf_load(f, 0x8c010000, &sz); + if(write_file_contents(argv[2], out, sz)) { + fprintf(stderr, "Cannot write image.\n"); + return 2; + } - f = fopen(argv[2], "wb"); - fwrite(out, sz, 1, f); - fclose(f); + return 0; } diff --git a/utils/dcbumpgen/dcbumpgen.1 b/utils/dcbumpgen/dcbumpgen.1 index 982ee26..4a1bd99 100644 --- a/utils/dcbumpgen/dcbumpgen.1 +++ b/utils/dcbumpgen/dcbumpgen.1 @@ -27,4 +27,3 @@ This manual page was initially written by Stefan Galowicz <bo...@pr... for the KOS project. .TP The program has been initially written by Frederik Ehnbom in 2005. -.SH SEE ALSO diff --git a/utils/scramble/scramble.1 b/utils/scramble/scramble.1 index a8adc66..2f96ca1 100644 --- a/utils/scramble/scramble.1 +++ b/utils/scramble/scramble.1 @@ -37,4 +37,3 @@ for the KOS project. .TP The program has been initially written by Marcus Comstedt and was obtained from his site (http://mc.pp.se/dc/). -.SH SEE ALSO diff --git a/utils/wav2adpcm/wav2adpcm.1 b/utils/wav2adpcm/wav2adpcm.1 index 3ea34f5..dc4bc7e 100644 --- a/utils/wav2adpcm/wav2adpcm.1 +++ b/utils/wav2adpcm/wav2adpcm.1 @@ -36,4 +36,3 @@ This manual page was initially written by Stefan Galowicz <bo...@pr... for the KOS project. .TP The program has been initially written by BERO <be...@ge...> and modified by Dan Potter. -.SH SEE ALSO hooks/post-receive -- A pseudo Operating System for the Dreamcast. |