/************************************************************* * File: tools/algo.c * Purpose: The pmcc compiler driver for the Algorithmics toolset * Author: Phil Bunce (pjb@carmel.com) * Revision History: * 970303 Added -ice and -driver options * 970313 Modified mksyms to work with algo's .map file * 970313 Added -ssyms option (separate symbols) * 970314 Removed $LSIPKG refs in crtn pathnames * 970417 Added check for nfiles==0 * 970902 Removed -ice option * 980402 Added support for sde3 * 980720 Added -mips16 * 981123 Fixed crt0 prob. */ #include #include #include #include "../include/defines.h" #include "misc.h" #define DYNDEFS /************************************************************* pmcc -- PMON compiler interface This program provides a standardized interface to the Algorithmics toolset. When linking it places the object file in OFILE, the downloadable records in OFILE.rec, and the link map in OFILE.map. This program assumes that the environment variable LSIPKG has been set. In addition to the usual cc options, this script supports: -fast - generate fast-format download records (default) -srec - generate S-record download records -syms - omit symbols from the download file -double - use LSI-supplied double-precision math library -chksum - don't generate chksum data in fast records -crt0 - don't include the standard crt0 -prom - append data to text for building proms Please checkout the pmcc man page for the latest information. *************************************************************/ #ifndef TOOLREV #define TOOLREV 10400 #endif #ifdef MSDOS #define LINKER "ld" char cmdchar[] = "@"; #else /* Unix */ #if TOOLREV >= 20000 #define LINKER "sde-ld" #else #define LINKER "ld-sde" #endif #endif #define MAXPATH 400 /* set various defaults */ int vflag = 0; /* verbose flag */ int fast = 1; int ssyms_flag; int syms = 1; char *chksum = ""; char *ofile = "a"; char *initial_lc = "-lc"; int driver; char cmdfile[] = "cmdfile"; char LIBM[MAXPATH] = "/usr/lib/cmplrs/cc"; char tmp[LNMAX],tmp2[LNMAX]; char *ENDIAN,*Gnum,*LSIPMCC; char *COMP_HOST_ROOT,*SDEROOT,*TMPDIR; Str flags,cflags,asflags,ldflags,ppflags,ofiles,llist,ilist,LIBS,files; Str *strlst[] = {&flags,&cflags,&asflags,&ldflags,&ppflags,&ofiles, &llist,&ilist,&LIBS,&files,0}; char *LSIPKG; char LIBC[MAXPATH]; char objfile[MAXPATH]; char tstart[MAXPATH]; char *dstart; char *CC; int nfiles; char stoppoint; int SZ; char tmppath[MAXPATH],cpppath[MAXPATH]; char mname[MAXPATH]; /* module object name */ char *clientpc; int toolrev; char *conv; extern int long_cmds_ok; char *getDef(); /************************************************************* * main(argc,argv) */ main(argc,argv) int argc; char *argv[]; { int i,status,SZ,sz; char *e,*p,h[MAXPATH],*redir; char tmp2[MAXPATH]; char *vtmp,*fmt,*file,*symsw,*promsw; SZ = 0; if (! (LSIPKG=getenv("LSIPKG"))) { fprintf(stderr,"pmcc: LSIPKG not set\n"); Exit(1); } Strcpy(&LIBS,""); #ifdef DYNDEFS sprintf(tmp,"%s/include/defines.h",LSIPKG); readDefs(tmp); if (getDef("SREC")) fast = 0; if (clientpc=getDef("CLIENTPC")) strcpy(tstart,&clientpc[2]); else strcpy(tstart,"80020000"); sscanf(getDef("TOOLREV"),"%d",&toolrev); /* only need this for really old tools */ if (toolrev < 20002) strcpy(cpppath,getDef("CPPPATH")); if (toolrev >= 30000) conv = "sde-conv"; else conv = "conv-sde"; #else #ifdef SREC fast = 0; #endif #ifdef CLIENTPC sprintf(tstart,"%08lx",CLIENTPC); #else strcpy(tstart,"80020000"); #endif strcpy(cpppath,CPPPATH); #endif /* !DYNDEFS */ #ifdef MSDOS if (! (TMPDIR=getenv("TMPDIR"))) { fprintf(stderr,"pmcc: TMPDIR not set\n"); Exit(1); } p = tmppath + sprintf(tmppath,"%s",TMPDIR); strcat(tmppath,"/PMXXXXXX"); mktemp(p); #else if (! (SDEROOT=getenv("SDEROOT"))) { fprintf(stderr,"pmcc: SDEROOT not set\n"); Exit(1); } strcpy(tmppath,"/tmp/PMXXXXXX"); mktemp(&tmppath[5]); #endif /* for backward compatability we set LSIPMCC */ if (! (LSIPMCC=getenv("LSIPMCC"))) LSIPMCC = ""; /* Select default Endianess. */ #ifdef LENDEF ENDIAN = "l"; #else ENDIAN = "b"; #endif Gnum = "o"; if (toolrev >= 30000) { CC = "sde-gcc"; long_cmds_ok = 1; } else CC = "gcc-sde"; sprintf(tmp,"-I%s/include",LSIPKG); Strcpy(&ilist,tmp); sprintf(tmp,"-L%s/lib/%%s%%s",LSIPKG); Strcpy(&llist,tmp); sprintf(tmp,"-DPMCC -DALGOR %s",LSIPMCC); Strcpy(&flags,tmp); getargs(argc,argv); if (vflag) addarg(&flags,"-v"); if (strequ(ENDIAN,"b")) { addarg(&asflags,"-EB"); addarg(&cflags,"-EB"); } else { #if TOOLREV >= 20000 addarg(&ldflags,"-oformat elf32-littlemips"); #else addarg(&ldflags,"-b elf-little"); #endif #if !defined(MSDOS) || TOOLREV >= 20000 addarg(&asflags,"-EL"); addarg(&cflags,"-EL"); #endif } strcpy(objfile,ofile); if (strequ(ofile,"a")) strcpy(objfile,"a.out"); if (stoppoint==0) { addarg(&cflags,"-c"); /* never want the cc driver to call ld */ addarg(&asflags,"-c"); /* never want the cc driver to call ld */ addarg(&ldflags,"-o"); addarg(&ldflags,objfile); } sprintf(tmp,llist.str,ENDIAN,Gnum,ENDIAN,Gnum); addarg(&ldflags,tmp); addarg(&cflags,ilist.str); addarg(&ppflags,ilist.str); addarg(&asflags,"-DLANGUAGE_ASSEMBLY"); addarg(&cflags,"-DLANGUAGE_C"); if (strequ(ENDIAN,"l")) { addarg(&cflags,"-DMIPSEL"); addarg(&ppflags,"-DMIPSEL"); } else { addarg(&cflags,"-DMIPSEB"); addarg(&ppflags,"-DMIPSEB"); } if (nfiles == 0) { printf("Fatal error: no files specified.\n"); exit(1); } /* now invoke the compiler */ for (i=0;i= 20000 redir = "-Map"; #else redir = ">"; #endif if (dstart) { fmt = "%s -N -M -e _start -Ttext %s -Tdata %s %s %s %s %s %s %s %s.map"; sz = strlen(LINKER)+strlen(tstart)+strlen(dstart)+strlen(ldflags.str)+ Strlen(&crt0)+strlen(ofiles.str)+strlen(initial_lc)+strlen(LIBS.str)+ strlen(redir)+strlen(ofile)+strlen(fmt); vtmp = malloc(sz); sprintf(vtmp,fmt,LINKER,tstart,dstart,ldflags.str,crt0.str,ofiles.str, initial_lc,LIBS.str,redir,ofile); } else { fmt = "%s -N -M -e _start -Ttext %s %s %s %s %s %s %s %s.map"; sz = strlen(LINKER)+strlen(tstart)+strlen(ldflags.str)+ Strlen(&crt0)+strlen(ofiles.str)+strlen(initial_lc)+strlen(LIBS.str)+ strlen(redir)+strlen(ofile)+strlen(fmt); vtmp = malloc(sz); sprintf(vtmp,fmt,LINKER,tstart,ldflags.str,crt0.str,ofiles.str, initial_lc,LIBS.str,redir,ofile); } if (status=System(vtmp)) Exit(status); free(vtmp); if (driver) { fmt = "%s -o %s.tmp %s"; sz = strlen(conv)+strlen(fmt)+strlen(ofile)+ strlen(objfile); vtmp = malloc(sz); sprintf(vtmp,fmt,conv,ofile,objfile); if (status=System(vtmp)) Exit(status); free(vtmp); sprintf(tmp,"%s.tmp",ofile); sprintf(tmp2,"%s.rec",ofile); str2file(tmp2,"SD"); /* write "SD" to ofile.rec */ appendFile(tmp2,tmp); Exit(0); } /* now make the appropriate download records */ if (fast) fmt = "%s -f lsi %s %s -o %s.rec %s"; else fmt = "%s %s %s -o %s.rec %s"; if (syms) symsw = "-y"; else symsw = ""; if (prom) promsw = "-p"; else promsw = ""; sz = strlen(fmt)+strlen(conv)+strlen(promsw)+strlen(symsw)+strlen(ofile)+ strlen(objfile); vtmp = malloc(sz); sprintf(vtmp,fmt,conv,promsw,symsw,ofile,objfile); if (status=System(vtmp)) Exit(status); free(vtmp); if (ssyms_flag) { sprintf(tmp,"%s.map",ofile); sprintf(tmp2,"%s.sym",ofile); mksyms(tmp,tmp2); } Exit(0); } /************************************************************* * getargs(argc,argv) */ getargs(argc,argv) int argc; char *argv[]; { int i; char *p; /* # This while loop does several jobs: # 1. strips off any pmcc defined options # 2. some options, if specified, must preceed path specs # so extract them from here, and add them to flags. # 3. find the output filename, if specified */ for (i=1;i < argc;i++) { if (strequ(argv[i],"-mips2")) { addarg(&cflags,argv[i]); addarg(&cflags,"-mcpu=r4000"); addarg(&asflags,argv[i]); addarg(&asflags,"-mcpu=r4000"); } else if (strequ(argv[i],"-mips16")) { addarg(&cflags,argv[i]); addarg(&asflags,argv[i]); mips16 = 1; } else if (strequ(argv[i],"-G")) { i++; addarg(&cflags,"-G"); addarg(&cflags,argv[i]); addarg(&asflags,"-G"); addarg(&asflags,argv[i]); if (strequ(argv[i],"0")) Gnum = "g"; else Gnum = "o"; } else if (!strncmp(argv[i],"-O",2)) { addarg(&cflags,argv[i]); } else if (strequ(argv[i],"-float")) { addarg(&flags,argv[i]); addarg(&flags,"-DFLOAT"); SZ = 1; } else if (getStdArgs(argc,argv,&i)) ; else if (argv[i][0] == '-') { fprintf(stderr,"%s: bad arg\n",argv[i]); exit(1); } else { addarg(&files,argv[i]); nfiles++; } } } /************************************************************* * mksyms(char *ifn,char *ofn) */ mksyms(ifn,ofn) char *ifn,*ofn; { FILE *ifp,*ofp; char buf[MAXPATH],*field[10]; int nf,flag,csum,len; if (vflag) fprintf(stderr,"mksyms %s > %s\n",ifn,ofn); flag = 0; ifp = fopen(ifn,"r"); if (ifp == 0) { fprintf(stderr,"Can't open %s\n",ifn); Exit(1); } ofp = fopen(ofn,"w"); if (ofp == 0) { fprintf(stderr,"Can't open %s\n",ofn); Exit(1); } for (;;) { if (!fgets(buf,100,ifp)) break; buf[strlen(buf)-1] = 0; if (!strcmp(buf,"**LINK EDITOR MEMORY MAP**")) flag = 1; if (!flag) continue; if (strlen(buf)==0) continue; if (buf[0] != ' ') continue; nf = argvize(field,buf); if (nf != 2) continue; if (strlen(field[0]) != 8) continue; csum = 0; len = strlen(field[1])+8+2; fprintf(ofp,"S4%02X%s%s,%02x\n",len,field[0],field[1],csum); } fclose(ifp); fclose(ofp); } #ifndef Exit /************************************************************* * Exit(x) */ Exit(x) int x; { int i; for (i=0;strlst[i];i++) { if (strlst[i]->str) free(strlst[i]->str); } sprintf(tmp,"%s.t1",tmppath); if (fileExists(tmp)) unlink(tmp); sprintf(tmp,"%s.t2",tmppath); if (fileExists(tmp)) unlink(tmp); sprintf(tmp,"%s.sx",tmppath); if (fileExists(tmp)) unlink(tmp); exit(((x)>127)?1:(x)); } #endif