home *** CD-ROM | disk | FTP | other *** search
- /*
- mwtodr.c
- a program to convert from MWC format executables to
- DRI format executables. Rearranges things and convert the the symbol table
- entries.
-
- All right reserved David DeGeorge September 5,1987.
- This program and it's source may be freely distributed on a not for profit
- basis only
- */
-
-
-
- #include <nout.h>
- #include <gemout.h>
- #include <stdio.h>
- #include <canon.h>
-
- /* usefuls */
- #define min(a,b) ( a > b ? b : a)
- #define READ 0
- #define WRITE 1
-
- /* defines for flag conversion */
- #define DEFINED 0x8000
- #define GLOBAL 0x2000
- #define DATABASED 0x400
- #define TEXTBASED 0x200
- #define BSSBASED 0x100
-
- char copyright[] = "Copyright 1987 David DeGeorge";
- char mwccopyr[] = "Portions of the program copyright 1984 Mark Williams Co.";
- /* some constants */
- #define BIGBUF 512*32 /* a biggish buffer make it bigger goes faster */
- #define NSYM 300 /* number of symbols to do at a wack */
- #define SMW sizeof(struct ldsym) /* 22 MWC symbols */
- #define SGM sizeof(struct gemsym) /* 14 DRI symbols */
- long _stksize=4000L; /* to be safe registers get saved on our stack */
-
- /* our globals */
- char * buffer;
- struct gemohdr gemhead;
- struct ldsym *cymbals;
- struct ldheader marky;
- struct gemsym *gsyms;
- long look40();
-
- main ( argc,argv)
- int argc;
- char ** argv;
- {
- int infd, /* file descriptors */
- outfd;
- long syms, /* counters */
- nsyms,
- nreloc = 4L;
- char msg[80]; /* for messages */
-
- /* check to see if enuff arguments and if there are ok */
- if ( argc != 3) usage();
- if(strcmp(argv[1],argv[2])== 0 )
- abort("Infile and outfile must be different\n\r");
-
- /* allocate space for the buffers */
- if ( ( buffer = malloc(BIGBUF) ) == (char *) 0 ){
- sprintf(msg,"Can't allocate %d bytes\n\r",BIGBUF);
- abort(msg);
- }
- if ( (cymbals = malloc(NSYM*SMW )) == (char *) 0 ){
- sprintf(msg,"Can't allocate for symbols");
- abort(msg);
- }
-
- if ( ( gsyms = malloc(NSYM*SGM )) == (char *) 0 ){
- sprintf(msg,"Can't allocate for symbols\n\r");
- abort(msg);
- }
-
- /* open the input file and check to see if executable and
- then if MWC format */
- if ( (infd = open(argv[1],READ)) < 0 ){
- sprintf(msg,"Can't open %s for reading\n\r",argv[1]);
- abort(msg);
- }
- read( infd,&gemhead,sizeof(gemhead));
- if ( gemhead.g_magic != GEMOMAGIC ) {
- sprintf(msg,"%s is the wrong format\n\r",argv[1]);
- abort(msg);
- }
-
- /* create the output file */
- creat(argv[2],1);
- if ( ( outfd = open(argv[2],WRITE)) < 0) {
- sprintf(msg,"Can't open %s for writing\n\r",argv[2]);
- abort(msg);
- }
- /* write out the header */
- write(outfd,&gemhead,sizeof(gemhead));
-
- /* calculate the amount of space used by the header,text and data segements
- and copy them to the new file */
- syms = gemhead.g_ssize[GO_TEXT] + gemhead.g_ssize[GO_DATA];
- xfer(outfd,infd,syms);
-
- /* calculate the number of relocation bytes..
- a long followed by bytes until the first 0 */
-
- read(infd,buffer,4);
- nreloc += look40(infd); /* look for the zero */
-
- /* seek to the MWC header and read it */
- lseek( infd,syms+sizeof(gemhead)+nreloc,0);
- read (infd,&marky,sizeof(marky));
- if ( _canw(marky.l_magic) != L_MAGIC) {
- sprintf(msg,"%s is not a MWC executable\n\r",argv[1]);
- unlink(argv[2]);
- abort(msg);
- }
-
- /* next do the symbols */
- nsyms = _canl(marky.l_ssize[L_SYM])/sizeof(struct ldsym);
- gemhead.g_ssize[GO_SYM] = nsyms * sizeof(struct gemsym);
- convrt(infd,outfd,nsyms);
-
- /* write out the relocation bytes */
- syms = sizeof(gemhead);
- syms += gemhead.g_ssize[GO_TEXT] + gemhead.g_ssize[GO_DATA];
- lseek(infd,syms,0);
- xfer(outfd,infd,nreloc);
-
- /* fix up the header to show the new sizeof the symbols */
- lseek(outfd,0L,0);
- write(outfd,&gemhead,sizeof(gemhead));
- }
-
- convrt(in,out,n)
- int in,out;
- long n;
-
-
- {
- long todo=n;
- int temp,
- flag,
- did,
- t1;
- char msg[80];
- register int i,
- j;
- register char *p,
- *q;
- register struct gemsym *g;
- register struct ldsym *l;
-
- while ( todo > 0) {
- t1 = min(todo,NSYM);
- if((did = read(in,cymbals,t1*SMW)) < 0)
- abort("Read error in convrt\r\n");
- t1=did/SMW;
- j=t1;
- l=cymbals;
- g=gsyms;
- while( j-- > 0 ){
- flag = _canw(l->ls_type);
- p = g->gs_name;
- q = l->ls_id;
- for ( i=0 ; i < 8 ; i++,p++,q++)*p=*q;
- g->gs_value = _canl(l->ls_addr);
- temp = DEFINED;
- if ( flag & 020 ) temp |= GLOBAL;
- switch( flag & 0xf ) {
- case L_SHRI:
- case L_PRVI:
- case L_BSSI:
- temp |= TEXTBASED;
- break;
- case L_SHRD:
- case L_PRVD:
- temp |= DATABASED;
- break;
- case L_BSSD:
- temp |= BSSBASED;
- break;
- default:
- sprintf(msg,
- "I don't recognize flag %d\r\n",
- flag & 0xF);
- write(2,msg,strlen(msg));
- break;
- }
- g -> gs_type = temp;
- l++;
- g++;
- }
- if( write(out,gsyms,t1*SGM) < 0){
- perror("");
- abort("Write error in cnvrt\r\c");
- }
- todo -= t1;
- }
-
- }
- xfer(out,in,n)
- int in,out;
- long n;
-
- {
- register int did;
- register long todo=n;
-
- while( todo > 0L ) {
- if((did = read(in,buffer,(int)min(todo,BIGBUF)))<0){
- perror("");
- abort("Read failure\r\n");
- }
- if (write(out,buffer,did) != did ){
- perror("");
- abort("Write failure\n\r");
- }
- todo -= did;
- }
- }
- usage()
- {
- char *msg="Usage mwcfile drifile\n\r";
- write(2,msg,strlen(msg));
- exit(1);
- }
-
- abort(msg)
- char * msg;
- {
- write(2,msg,strlen(msg));
- exit(1);
- }
-
-
- long look40(in) /* look for a zero
- will leave the file pointer in the wrong place */
- int in;
- { register long temp=0L;
- register char *p,*q;
- q = buffer + BIGBUF;
- while ( read(in,buffer,BIGBUF) > 0){
- p=buffer;
- for( p=buffer; p < q ; p++) {
- temp++;
- if( *p == '\0') goto end ;
- }
-
- }
- end:
-
- return(temp);
-
- }
-