elks-enhanced
public
Read
Owner: themaster
Branch: master
Commits: 6893
Updated: 2026-04-19 00:15
Git CLI clone URL
git clone https://www.xt-emporium.com/git/elks-enhanced.git
Fullscreen desktop URL
Code
Commits
History
Branches
Bug Reports
Discussions
Compare
Settings
elks-enhanced
/
elks
/
arch
/
i86
/
lib
/
unused
/
imgconv.c
File editor
/******************************************************************************* *** *** Filename : imgconv.c *** Purpose : converts a.out executables produced by bcc/as86/ld86 *** to the Psion .img format. This program is invoked when *** linking from bcc if the -img option is used. *** Author(s) : Matt J. Gumbley <matt@cs.keele.ac.uk> *** This program was pieced together from postings to the *** comp.sys.psion.programmer newsgroup, in particular, I'd *** like to thank the following for their efforts in *** discovering and publishing the format of the .img file: *** Dr. Olaf Flebbe *** <o.flebbe@science-computing.uni-tubingen.de> *** (for writing an initial version of this; his comments *** left intact) *** Alasdair Manson <ali-manson@psion.com> *** (for publishing the .img file structure) *** Andrew Lord <Andrew_Lord@tertio.co.uk> *** (for asking about the .img file and investigating *** bcc's suitability for developing Psion programs) *** Nic Wise <email address to be supplied later!> *** (for porting the toolset to DOS, pointing out *** incompatibilities.) *** Keith Walker <kdw@oasis.icl.co.uk> *** (CPOC author, with Dave Walker, for help with .img *** file format, magic statics, initialisation) *** Dr. Stephen Henson <shenson@bigfoot.com> *** (Corrections to the header structure, etc.) *** *** This program is placed under the GNU public license. *** *** Created : 19/01/97, probably *** Last updated : 11/03/97 *** ******************************************************************************** *** *** Modification Record *** 27/01/97 MJG Changed mmap() to standard IO calls, since DOS doesn't have *** mmap(). Added command line options, and tidied up. *** 05/03/97 SH Header corrections, casting. *** 09/03/97 MJG Now builds in the embedded file information, given a list in *** a .afl file with the same base name as the .img file. *** 11/03/97 SNH MS-DOS port *** *******************************************************************************/ /* Olaf's comments: ************************************************************ Hi, I wrote this little converter for the minix/linux ld86 linker. It converts the BSD a.out to Psion IMG. I was able to crash the Psion emulator with a simple image containing the `ret' instruction ;-) The IMG Format was reverse engeniered by me. So, please comment if anybody knows details....for instance what do the magic numbers mean? BTW: Is it true, that the Psion Img format knows no .bss segment? (.bss==uninitialzed data segment) The code compiles on Linux. The Header "bsd-a.out.h" is from the bin86-0.1 source code distribution by Bruce Evans changed by H.J.Lu. */ /* The format of the .img file is in img.h, as supplied by Alasdair, the magic has been demystified, yes, we have uninitialised data (.bss) and we're using the x86_aout.h definition now. *********************************************************** MJG *************/ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #ifndef __TSC__ #include <unistd.h> #endif #include <stdlib.h> #include <stdio.h> #include <ctype.h> #include "img.h" #include "a.out.h" /* A symbolic link to ../ld/x86_aout.h */ #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #ifndef O_BINARY #define O_BINARY 0 #endif struct embedded { unsigned short length; unsigned char *data; } embeddedFiles[MaxAddFiles]; short chksum(unsigned char *a, int len) { short sum = 0; for (; len > 0; len--) sum += *a++; return sum; } int main(int argc, char *argv[]) { int a_out_fd; struct stat statbuf; char *a_out; struct exec *header; /*short img_ar[12]; */ ImgHeader imgHeader; FILE *img_fd; /* Embedded file info */ char aflName[20]; /* Name of file containing list of added files */ char afName[20]; /* Name of embedded file from .afl file */ int af; /* general purpose integer for add files routines */ FILE *afl_fd; /* The .afl FILE */ int af_fd; /* Each embedded file */ struct stat afstatbuf; /* Each embedded file */ unsigned short embeddedTotalLength, embeddedOffset; int afLen, numEmbeddedFiles; /* Default values for the configurable options */ unsigned short HeapParas = 128; unsigned short StackParas = 64; /* Is this the default SIBO SDK uses? */ unsigned short InitialIP = 0; unsigned short Priority = 128; unsigned short CodeVersion = 8204; int verbose = FALSE; int i; if (argc < 3) goto usage; if ((a_out_fd = open(argv[1], O_RDONLY | O_BINARY)) < 0) { fprintf(stderr, "imgconv: Couldn't open input file %s\n", argv[1]); exit(1); } if (fstat(a_out_fd, &statbuf) < 0) { fprintf(stderr, "imgconv: Couldn't fstat input file %s: ", argv[1]); perror(""); exit(1); } if ((a_out = malloc(statbuf.st_size)) == NULL) { fprintf(stderr, "imgconv: Couldn't allocate %ld bytes to read input file %s\n", statbuf.st_size, argv[1]); exit(1); } if (statbuf.st_size != read(a_out_fd, a_out, statbuf.st_size)) { fprintf(stderr, "imgconv: Couldn't read %ld bytes of input file %s: ", statbuf.st_size, argv[1]); perror(""); exit(1); } #ifdef MSDOS if (NULL == (img_fd = fopen(argv[2], "wb"))) { #else if (NULL == (img_fd = fopen(argv[2], "w"))) { #endif fprintf(stderr, "imgconv: Couldn't open %s for writing\n", argv[1]); exit(1); } /* Handle any extra command line options */ for (i = 3; i < argc; i++) { if (argv[i][0] != '-') { fprintf(stderr, "imgconv: %s is not a - option\n", argv[i]); goto usage; } switch (tolower(argv[i][1])) { case 'c': /* Specify code version */ if (sscanf(&argv[i][2], "%hu", &CodeVersion) != 1) goto usage; break; case 'h': /* Specify heap paragraphs */ if (sscanf(&argv[i][2], "%hu", &HeapParas) != 1) goto usage; break; case 'i': /* Specify initial IP */ if (sscanf(&argv[i][2], "%hu", &InitialIP) != 1) goto usage; break; case 'p': /* Specify priority */ if (sscanf(&argv[i][2], "%hu", &Priority) != 1) goto usage; break; case 's': /* Specify stack paragraphs */ if (sscanf(&argv[i][2], "%hu", &StackParas) != 1) goto usage; break; case 'v': /* Verbose */ verbose = TRUE; break; default: fprintf(stderr, "imgconv: unknown option %s\n", argv[i]); goto usage; } } header = (struct exec *) a_out; if (BADMAG(*header)) { fprintf(stderr, "imgconv: Bad Magic in input file %s\n", argv[1]); exit(1); } if (verbose) printf("%s info:\nText 0x%04lx, Data 0x%04lx, BSS 0x%04lx\n", argv[1], header->a_text, header->a_data, header->a_bss); a_out += header->a_hdrlen; /* Do we have an add file list? (.afl file) Try the base name of the * .img file, replacing .img with .afl... */ strcpy(aflName, argv[2]); for (af = 0; af < 16 && aflName[af] != '.'; af++); strcpy(aflName + af, ".afl"); embeddedTotalLength = numEmbeddedFiles = 0; #ifdef MSDOS if (NULL != (afl_fd = fopen(aflName, "rb"))) { #else if (NULL != (afl_fd = fopen(aflName, "r"))) { #endif if (verbose) printf("Adding embedded files from list held in %s\n", aflName); for (af = 0; af < MaxAddFiles; af++) { embeddedFiles[af].length = 0; embeddedFiles[af].data = NULL; /* What is the name of this embedded file? */ if (fgets(afName, 20, afl_fd) == NULL) continue; afLen = strlen(afName); if (afLen < 2) continue; if (afName[afLen - 1] == '\n') afName[afLen - 1] = '\0'; if ((af_fd = open(afName, O_RDONLY | O_BINARY)) < 0) { fprintf(stderr, "imgconv: Couldn't open embedded file %s\n", afName); exit(1); } if (fstat(af_fd, &afstatbuf) < 0) { fprintf(stderr, "imgconv: Couldn't fstat embedded file %s: ", afName); perror(""); exit(1); } /* Embedded files can be zero length */ embeddedFiles[af].length = afstatbuf.st_size; if (embeddedFiles[af].length > 0) { /* Allocate storage space */ if ((embeddedFiles[af].data = malloc(embeddedFiles[af].length)) == NULL) { fprintf(stderr, "imgconv: Couldn't allocate %d bytes to read embedded file %s\n", embeddedFiles[af].length, afName); exit(1); } if (embeddedFiles[af].length != read(af_fd, embeddedFiles[af].data, embeddedFiles[af].length)) { fprintf(stderr, "imgconv: Couldn't read %d bytes of embedded file %s: ", embeddedFiles[af].length, afName); perror(""); exit(1); } } close(af_fd); numEmbeddedFiles++; embeddedTotalLength += embeddedFiles[af].length; if (verbose) printf("Read in %d bytes from %s\n", embeddedFiles[af].length, afName); } if (verbose) printf("Embedded files take up %d bytes\n", embeddedTotalLength); } /* Olaf's original .img header... * fwrite( "ImageFileType**", 16, 1, img_fd); * img_ar[ 0] = 8207; * img_ar[ 1] = 64; * img_ar[ 2] = header->a_text / 16; * img_ar[ 3] = 0; * img_ar[ 4] = 1000; ** Stack Size ** * img_ar[ 5] = header->a_data / 16; * img_ar[ 6] = 128; * img_ar[ 7] = header->a_data; * img_ar[ 8] = chksum( (short *) a_out, header->a_text); * img_ar[ 9] = chksum( (short *)(a_out+header->a_text), header->a_data); * img_ar[ 10] = 128; ** Start up Priority ** * img_ar[ 11] = 8204; ** Version ?? ** */ strcpy(imgHeader.Signature, "ImageFileType**"); imgHeader.ImageVersion = 0x200f; imgHeader.HeaderSizeBytes = sizeof(ImgHeader) + embeddedTotalLength; imgHeader.CodeParas = header->a_text / 16; imgHeader.InitialIP = InitialIP; imgHeader.StackParas = StackParas; imgHeader.DataParas = (header->a_data + header->a_bss + 15) / 16; imgHeader.HeapParas = HeapParas; imgHeader.InitialisedData = header->a_data; imgHeader.CodeCheckSum = chksum((unsigned char *) a_out, header->a_text); imgHeader.DataCheckSum = chksum((unsigned char *) (a_out + header->a_text), header->a_data); imgHeader.CodeVersion = CodeVersion; imgHeader.Priority = Priority; embeddedOffset = embeddedTotalLength > 0 ? sizeof(ImgHeader) : 0; for (i = 0; i < MaxAddFiles; i++) { imgHeader.Add[i].offset = i < numEmbeddedFiles ? embeddedOffset : 0; imgHeader.Add[i].length = i < numEmbeddedFiles ? embeddedFiles[i].length : 0; embeddedOffset += embeddedFiles[i].length; } imgHeader.DylCount = 0; imgHeader.DylTableOffsetLo = 0; imgHeader.DylTableOffsetHi = 0; imgHeader.Spare = 0; /* Olaf missed the DylTableOffset off this, methinks... * fwrite( img_ar, 12, 2, img_fd); * for (i=0 ; i < 12; i++) * img_ar[i] = 0; * fwrite( img_ar, 12, 2, img_fd);*/ /* Write out the header structure */ fwrite((char *) &imgHeader, sizeof(imgHeader), 1, img_fd); /* Write out the embedded files, if any */ for (i = 0; i < MaxAddFiles; i++) if (embeddedFiles[i].length > 0) { fwrite((char *) embeddedFiles[i].data, embeddedFiles[i].length, 1, img_fd); free(embeddedFiles[i].data); } /* Write out the code segment */ fwrite(a_out, header->a_text, 1, img_fd); /* Write out the initialised data segment */ fwrite(a_out + header->a_text, header->a_data, 1, img_fd); fclose(img_fd); close(a_out_fd); exit(0); usage: /* Vile, nasty hack: I love it :) */ fprintf(stderr, "usage: imgconv a.out-file .img-file [options]\n\n"); fprintf(stderr, "imgconv converts an executable file in a.out format (as produced\n"); fprintf(stderr, "by the bcc toolset) into a Psion-compatible .img file.\n\n"); fprintf(stderr, "These options can be passed to this program with the -Y\n"); fprintf(stderr, "option of bcc, e.g. bcc prog.c -o prog.img -Y-p50\n\n"); fprintf(stderr, "options: all <num>'s are in decimal, defaults in brackets\n"); fprintf(stderr, " -C<num> Specify code version number (8204)\n"); fprintf(stderr, " -H<num> Specify number of heap paragraphs (128)\n"); fprintf(stderr, " -I<num> Specify initial value for IP (0)\n"); fprintf(stderr, " -P<num> Specify priority (128)\n"); fprintf(stderr, " -S<num> Specify number of stack paragraphs (64)\n"); fprintf(stderr, " -V Verbose mode: display code stats (Don't)\n\n"); fprintf(stderr, "Up to four files may be embedded inside the resultant\n"); fprintf(stderr, ".img file by placing their filenames on separate lines\n"); fprintf(stderr, "in a .afl file. This .afl file must have the same base\n"); fprintf(stderr, "name as the .img file. e.g. Create a file fred.afl containing:\n"); fprintf(stderr, " fred.pic\n fred.rsc\n fred.shd\n"); fprintf(stderr, "To have these files added to the fred.img file.\n"); exit(1); } /* Dr. Olaf Flebbe Phone +49 (0)7071-9457-32 science + computing gmbh FAX +49 (0)7071-9457-27 Hagellocher Weg 71 D-72070 Tuebingen Email: o.flebbe@science-computing.uni-tuebingen.de */
Commit message
This repository is read-only for this account.
Repository snapshot
Current branch
master
Visibility
public
Your access
Read
Remote
Configured
File activity
View file history