/************************************************************* * File: tools/cygnus.c * Purpose: compiler driver for pmcc command for GNU tools from * Cygnus (ECOFF format). * Author: Phil Bunce (pjb@carmel.com) * Revision History: * 970304 Added -driver and -ice * 970313 Added -ssyms option (separate symbols) * 970314 Removed $LSIPKG refs in crtn pathnames * 970417 Added check for nfiles==0 * 970902 Removed -ice */ #include #include #include #include "../include/defines.h" #include "misc.h" /* set various defaults */ int vflag = 0; /* verbose flag */ char *prom = ""; int fast = 1; int ssyms_flag; char *syms = "-s"; char *chksum = ""; char *ofile = "a"; char LIBM[100] = "/usr/lib/cmplrs/cc"; int driver; char tmp[400],tmp2[400]; char *ENDIAN,*Gnum,*LSIPMCC; char *COMP_HOST_ROOT; Str flags,cflags,asflags,ldflags,ppflags,rflags,llist,ilist,ofiles,LIBS; Str *strlst[] = {&flags,&cflags,&asflags,&ldflags,&ppflags,&rflags,&llist, &ilist,&ofiles,&LIBS,0}; char *LSIPKG,*CYGROOT; char LIBC[100]; char objfile[100]; char tstart[10]; char *dstart; char *files[100]; char *CC; int nfiles,msim; char stoppoint; char crt0[100]; char tmppath[200],cpppath[200]; char mname[32]; /* module object name */ char *ld_cmd_file1[] = { "OUTPUT_FORMAT(\"ecoff-bigmips\")", "OUTPUT_ARCH(mips)", "ENTRY(_start)", "SECTIONS", "{", 0}; /* .text 0xa0d80000 : */ char *ld_cmd_file2[] = { " {", " _ftext = .;", " *(.text)", " CREATE_OBJECT_SYMBOLS", " }", " .init . : { *(.init) } =0", " .fini . : { *(.fini) } =0", " .ctors . : { *(.ctors) }", " .dtors . : { *(.dtors) }", " _etext = .;", " etext = .;", " .reginfo . : { *(.reginfo) }", 0}; /* .data 0x00d88000 : */ char *ld_cmd_file3[] = { " {", " _fdata = .;", " *(.data)", " }", " .rdata . : { *(.rdata) }", " .rodata . : { *(.rodata) }", " .rodata1 . : { *(.rodata1) }", " .data1 . : { *(.data1) }", " __gp_start = .;", " .lit8 . : { *(.lit8) }", " .lit4 . : { *(.lit4) }", " .sdata . : { *(.sdata) }", " _edata = .;", " edata = .;", " .sbss . : {", " *(.sbss) *(.scommon) ", " }", " __gp_end = .;", " .bss . : {", " *(.bss) *(COMMON) ", " }", " _fbss = SIZEOF(.sbss) ? ADDR(.sbss) : ADDR(.bss);", " __bss_start = _fbss;", " _gp = __gp_start + ((__gp_end - __gp_start) / 2);", " _end = .;", " end = .;", "}", 0,}; /************************************************************* * main(argc,argv) */ main(argc,argv) int argc; char *argv[]; { int i,status,SZ,sz; char *e,*p,h[20],*vtmp; FILE *cfp,*sfp; char tmp2[100]; Str *f; SZ = 0; if (! (LSIPKG=getenv("LSIPKG"))) { fprintf(stderr,"pmcc: LSIPKG not set\n"); exit(1); } if (! (CYGROOT=getenv("CYGROOT"))) { fprintf(stderr,"pmcc: CYGROOT not set\n"); exit(1); } /* for backward compatability we set LSIPMCC */ if (! (LSIPMCC=getenv("LSIPMCC"))) LSIPMCC = ""; #ifdef SREC fast = 0; #endif #ifdef CLIENTPC sprintf(tmp,"%08x",CLIENTPC); strcpy(tstart,tmp); #else strcpy(tstart,"80020000"); #endif strcpy(tmppath,"/tmp/PMXXXXXX"); mktemp(&tmppath[5]); #ifdef LENDEF ENDIAN = "l"; #else ENDIAN = "b"; #endif Gnum = "o"; CC = "mips-idt-ecoff-gcc"; strcpy(cpppath,CPPPATH); Strcpy(&LIBS,""); sprintf(tmp,"-I%s/include",LSIPKG); Strcpy(&ilist,tmp); sprintf(tmp,"-L%s/lib/%%s%%s",LSIPKG); Strcpy(&llist,tmp); sprintf(tmp,"-DPMCC -DCYGNUS %s",LSIPMCC); Strcpy(&ppflags,tmp); Strcpy(&flags,""); #ifdef MSIM msim = 1; strcpy(crt0,"$LSIPKG/lib/bo/crt2.o"); strcpy(tstart,"9fc00000"); fast = 0; #endif /* # 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],"-fast")) fast = 1; else if (!strncmp(argv[i],"-mips",5)) addarg(&flags,argv[i]); else if (strequ(argv[i],"-msoft-float")) { addarg(&flags,argv[i]); } else if (strequ(argv[i],"-driver")) { driver = 1; syms = 0; sprintf(crt0,"%s/lib/%sg/crt3.o",LSIPKG,ENDIAN); } #if 0 /* 970902 */ else if (strequ(argv[i],"-ice")) { sprintf(crt0,"%s/lib/%so/crt4.o",LSIPKG,ENDIAN); } #endif else if (strequ(argv[i],"-prom")) { prom = "-p"; fast = 0; } else if (strequ(argv[i],"-msim")) { msim = 1; strcpy(crt0,"$LSIPKG/lib/bo/crt2.o"); strcpy(tstart,"9fc00000"); fast = 0; } else if (strequ(argv[i],"-crt0")) strcpy(crt0," "); else if (strequ(argv[i],"-T")) { i++; strcpy(tstart,argv[i]); } else if (strequ(argv[i],"-D")) { i++; dstart = argv[i]; } else if (!strncmp(argv[i],"-D",2)) addarg(&ppflags,argv[i]); else if (strequ(argv[i],"-target")) { /* just to keep Sun make happy */ i++; } else if (strequ(argv[i],"-L")) Strcpy(&llist,""); else if (!strncmp(argv[i],"-L",2)) addarg(&llist,argv[i]); else if (!strncmp(argv[i],"-l",2)) { sprintf(tmp,"-lx%s",&argv[i][2]); addarg(&LIBS,tmp); } else if (strequ(argv[i],"-G")) { i++; addarg(&flags,"-G"); addarg(&flags,argv[i]); if (strequ(argv[i],"0")) Gnum = "g"; else Gnum = "o"; } else if (strequ(argv[i],"-I")) Strcpy(&ilist,""); else if (!strncmp(argv[i],"-I",2)) addarg(&ppflags,argv[i]); else if (strequ(argv[i],"-g")) addarg(&flags,argv[i]); else if (strequ(argv[i],"-c")) { stoppoint = 'c'; addarg(&cflags,argv[i]); } else if (strequ(argv[i],"-S")) { stoppoint = 'S'; addarg(&cflags,argv[i]); } else if (strequ(argv[i],"-v")) { vflag = 1; addarg(&flags,argv[i]); } else if (strequ(argv[i],"-srec")) fast = 0; else if (strequ(argv[i],"-chksum")) chksum = "-c"; else if (strequ(argv[i],"-syms")) syms = ""; else if (strequ(argv[i],"-ssyms")) { syms = ""; ssyms_flag = 1; } else if (!strncmp(argv[i],"-O",2)) addarg(&cflags,argv[i]); else if (strequ(argv[i],"-float")) { addarg(&flags,argv[i]); addarg(&ppflags,"-DFLOAT"); SZ = 1; } else if (strequ(argv[i],"-double")) SZ = 1; else if (strequ(argv[i],"-EB")) ENDIAN = "b"; else if (strequ(argv[i],"-EL")) ENDIAN = "l"; else if (!strncmp(argv[i],"-W",2)) { for (p=argv[i];*p;p++) if (*p == ',') *p = ' '; switch (argv[i][2]) { case 'c' : f = &cflags; break; case 'a' : f = &asflags; break; case 'l' : f = &ldflags; break; } addarg(f,&argv[i][4]); } else if (strequ(argv[i],"-o")) { i++; ofile = argv[i]; } else if (strequ(argv[i],"-lm")) { fprintf(stderr,"-lm Not supported by this toolset\n"); Exit(1); } else if (argv[i][0] == '-') { fprintf(stderr,"%s: bad arg\n",argv[i]); Exit(1); } else files[nfiles++] = argv[i]; } if (strequ(ENDIAN,"b")) { addarg(&asflags,"-EB"); addarg(&cflags,"-EB"); addarg(&ppflags,"-DMIPSEB"); } else { addarg(&asflags,"-EL"); addarg(&cflags,"-EL"); addarg(&ppflags,"-DMIPSEL"); } 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(&ldflags,"-o"); addarg(&ldflags,objfile); } else if (nfiles == 1) { e = extent(files[0]); getHead(h,files[0]); if (strequ(e,"c")) { addarg(&cflags,"-o"); if (!strequ(ofile,"a")) addarg(&cflags,ofile); else { if (stoppoint == 'c') sprintf(tmp,"%s.o",h); else sprintf(tmp,"%s.s",h); addarg(&cflags,tmp); } } else if (strequ(e,"s")) { addarg(&asflags,"-o"); if (!strequ(ofile,"a")) addarg(&asflags,ofile); else { sprintf(tmp,"%s.o",h); addarg(&asflags,tmp); } } } 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 (nfiles == 0) { printf("Fatal error: no files specified.\n"); exit(1); } /* now invoke the compiler */ for (i=0;i %s.map", ofile,ldflags.str,crt0,ofiles.str,LIBS.str,ofile); fclose(sfp); if (status=System(tmp)) Exit(status); if (driver) { sprintf(tmp,"%s.rec",ofile); str2file(tmp,"SD"); sprintf(tmp,"gensrec %s >> %s.rec",objfile,ofile); if (status=System(tmp)) Exit(status); Exit(0); } /* now make the appropriate download records */ if (fast) sprintf(tmp,"genfrec %s %s %s > %s.rec",syms,chksum,objfile,ofile); else sprintf(tmp,"gensrec %s %s %s > %s.rec",prom,syms,objfile,ofile); if (status=System(tmp)) Exit(status); if (!ssyms_flag) Exit(0); if (fast) sprintf(tmp,"genfrec -e %s > %s.sym",objfile,ofile); else sprintf(tmp,"gensrec -e %s > %s.sym",objfile,ofile); if (status=System(tmp)) Exit(status); Exit(0); } /************************************************************* * wrfile(fp,msg) */ wrfile(fp,msg) FILE *fp; char *msg[]; { int i; for (i=0;msg[i];i++) fprintf(fp,"%s\n",msg[i]); } /************************************************************* * mksyms(f) */ mksyms(f) char *f; { FILE *mfp,*ofp; char buf[100],*field[10]; int nf,flag,csum,len; if (vflag) fprintf(stderr,"mksyms %s.map > %s.rec\n",f,f); flag = 0; sprintf(tmp,"%s.map",f); mfp = fopen(tmp,"r"); if (mfp == 0) { fprintf(stderr,"Can't open %s\n",tmp); Exit(1); } sprintf(tmp,"%s.rec",f); ofp = fopen(tmp,"w"); if (ofp == 0) { fprintf(stderr,"Can't open %s\n",tmp); Exit(1); } for (;;) { if (!fgets(buf,100,mfp)) break; buf[strlen(buf)-1] = 0; 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(mfp); 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.S",tmppath); if (fileExists(tmp)) unlink(tmp); sprintf(tmp,"%s.t1",tmppath); if (fileExists(tmp)) unlink(tmp); sprintf(tmp,"%s.t2",tmppath); if (fileExists(tmp)) unlink(tmp); exit(((x)>127)?1:(x)); } #endif