⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ghs.c

📁 mips架构的bootloader,99左右的版本 但源代码现在没人更新了
💻 C
字号:
/************************************************************* * File: tools/ghs.c * Purpose: The pmcc compiler driver for the Green Hills toolset * Author: Phil Bunce (pjb@carmel.com) * Revision History: *	971211	Created from cygelf.c *	971231	Changed order of section in lnk file *	971231	Added option for -nosda *	980102	Added -noS5 option to gsrec *	980102	Fixed prob w pmcc w/o -o *	980113	Changed -O to -OS. Big size reduction! *	980312	Changed winbootdir to windir. NT doesn't have winbootdir. *	981020	Removed x from -l option. Added -LCOMP_ROOT/mips_r3 & -larch. *	981027	Changed mips_r3 to mips_sf. *	981028	Fixed mips_r3 selector to use table. *	981028	Fixed -cpu=r4000 option. Was -mcpu=r4000. *	981028	Added -soft-float option. *	981028	Moved std opts to misc.c. *	981118	Incorporated "-larch last" fix. *	981215	Verified against GHS 1.8.9 *	981217	Fixed prob w wrong lib used when lendef. *	990119	Added -lind for _fmul etc. */#include <stdio.h>#include <malloc.h>#include <string.h>#include "../include/defines.h"#include "misc.h"#define DYNDEFS#ifdef MSDOS#define LINKER "lx"char cmdchar[] = "@";#endif/* 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 -larch -lind";int driver;char cmdfile[] = "cmdfile";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[100];char objfile[100];char tstart[10];char *dstart;char *CC;int nfiles,msim;char stoppoint;int SZ;char tmppath[200];char mname[32]; /* module object name */char *clientpc;char *getDef();char *ld_cmd_file1[] = {	"-sec",	"{",	0};/*	.text 		0x9fc00000 	: */char *ld_cmd_file2[] = {	".syscall 			:",	".secinfo 			:",	".fixaddr 			:",	".fixtype 			:",	".robase 	align(8)	:",	".rodata 			:",	".romdata	ROM(.data)	:",	".romsdata	ROM(.sdata)	:",	0};/*	.sdabase 	0x80000100	: */char *ld_cmd_file3[] = {	".data 				:",	".sdata 			:",	".sbss 				:",	".bss 				:",	".heap 	align(8) pad(0x100000) 	:",	".stack align(8) pad(0x80000) 	:",	"}",	0};extern int long_cmds_ok;/* the defines and table are how I figure out which library to link with */#define MODE_MSK 3#define MODE_4K  1#define MODE_16  2#define MODE_SF  4#define MODE_LE  8char *lib_mode[] = {	"mips_r3",	"mips_r4",	"mips_16",	0,	"mips_sf",	"mips_sf",	"mips_sf",	0,	"mipsl_r3",	"mipsl_r4",	"mipsl_16",	0,	"mipsl_sf",	"mipsl_sf",	"mipsl_sf",	0};/**************************************************************  main(argc,argv)*/main(argc,argv)int argc;char *argv[];{int i,status,SZ,sz;char *e,*p,h[20],*redir;char tmp2[100];char *vtmp,*fmt,*file;SZ = 0;if (! (LSIPKG=getenv("LSIPKG"))) {	fprintf(stderr,"pmcc: LSIPKG not set\n");	Exit(1);	}#ifdef MSDOSif (getenv("windir")) long_cmds_ok = 1;#elselong_cmds_ok = 1;#endifStrcpy(&LIBS,"");#ifdef DYNDEFSsprintf(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");if (getDef("LENDEF")) ENDIAN = "l";else ENDIAN = "b";#else#ifdef SRECfast = 0;#endif#ifdef CLIENTPCsprintf(tstart,"%08lx",CLIENTPC);#elsestrcpy(tstart,"80020000");#endif#endif#ifdef MSDOS#if 0if (! (TMPDIR=getenv("TMPDIR"))) {	fprintf(stderr,"pmcc: TMPDIR not set\n");	Exit(1);	}p = tmppath + sprintf(tmppath,"%s",TMPDIR);strcat(tmppath,"/PMXXXXXX");mktemp(p);#endif#endif/* for backward compatability we set LSIPMCC */if (! (LSIPMCC=getenv("LSIPMCC"))) LSIPMCC = "";/* Select default Endianess. */#ifdef LENDEFENDIAN = "l";#elseENDIAN = "b";#endifGnum = "o";CC = "ccmipe";stdcrt0 = "%s/lib/%s%s/crt0.o";sprintf(tmp,"-I%s/include",LSIPKG);Strcpy(&ilist,tmp);sprintf(tmp,"-L%s/lib/%%s%%s",LSIPKG);Strcpy(&llist,tmp);sprintf(tmp,"-DPMCC -DGHS %s",LSIPMCC);Strcpy(&flags,tmp);getargs(argc,argv);if (vflag) addarg(&flags,"-v");if (strequ(ENDIAN,"l")) CC = "ccmipel";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<nfiles;i++) {	file = getStrn(&files,i);	e = extent(file);	getHead(h,file);        if (nfiles == 1 && !strequ(ofile,"a") && stoppoint != 0)                strcpy(mname,ofile);        else sprintf(mname,"%s.o",h);	if (strequ(e,"s")) {		sprintf(tmp,"%s.mip",h);		fixasm(file,tmp);		fmt = "%s -c -DLANGUAGE_ASSEMBLY %s %s %s -o %s %s";		sz = strlen(CC)+strlen(flags.str)+strlen(ppflags.str)+			strlen(asflags.str)+strlen(mname)+strlen(tmp)+			strlen(fmt);		vtmp = malloc(sz);		sprintf(vtmp,fmt,CC,flags.str,ppflags.str, asflags.str,			mname,tmp);		if (status=System(vtmp)) Exit(status);		free(vtmp);		getHead(tmp,file);		strcat(tmp,".o");		addarg(&ofiles,tmp);		}	else if (strequ(e,"rec")) {		fmt = "rdsrec -A dat1 %s -o tmp.s";		sz = strlen(fmt)+strlen(file);		vtmp = malloc(sz);		sprintf(vtmp,fmt,file);		if (status=System(vtmp)) Exit(status);		free(vtmp);		fmt = "%s -c %s %s %s -o %s tmp.s";		sz = strlen(CC)+strlen(flags.str)+strlen(ppflags.str)+			strlen(asflags.str)+strlen(mname)+strlen(tmp)+			strlen(fmt);		vtmp = malloc(sz);		sprintf(vtmp,fmt,CC,flags.str,ppflags.str, asflags.str,			mname);		if (status=System(vtmp)) Exit(status);		free(vtmp);		getHead(tmp,file);		strcat(tmp,".o");		addarg(&ofiles,tmp);		}	else if (strequ(e,"c")) {		fmt = "%s -Z1250 -U__ghs_stdcall -Xt -unsignedchar %s %s -o %s %s";		sz = strlen(CC)+strlen(flags.str)+strlen(cflags.str)+		     strlen(mname)+strlen(file)+strlen(fmt);		vtmp = malloc(sz);		sprintf(vtmp,fmt,CC,flags.str,cflags.str,mname,file);		if (status=System(vtmp)) Exit(status);		free(vtmp);		getHead(tmp,file);		strcat(tmp,".o");		addarg(&ofiles,tmp);		}	else if (strequ(e,"o")) {		addarg(&ofiles,file);		}	else if (strequ(e,"a")) {		addarg(&ofiles,file);		}	else {		fprintf(stderr,"pmcc: %s: bad extent\n",e);		Exit(1);		}	free(file);	}if (stoppoint != 0) Exit(0);/* Select C library */sprintf(LIBC,"%s/lib/%s%s",LSIPKG,ENDIAN,Gnum);if (stdcrt0) addcrt0(stdcrt0,LSIPKG,ENDIAN,Gnum);if (crt0.str == 0) Strcpy(&crt0,"");if (dstart) {	mklnkfile(ofile);	fmt = "lx -map @%s.lnk %s %s %s %s %s";	sz = strlen(ofile)+strlen(ldflags.str)+Strlen(&crt0)+	strlen(ofiles.str)+strlen(initial_lc)+strlen(LIBS.str)+strlen(fmt);	vtmp = malloc(sz);	sprintf(vtmp,fmt,ofile,ldflags.str,crt0.str,ofiles.str,LIBS.str,		initial_lc);	}else {	fmt = "lx -map -T %s %s %s %s %s %s";	sz = strlen(tstart)+strlen(ldflags.str)+Strlen(&crt0)+	strlen(ofiles.str)+strlen(initial_lc)+strlen(LIBS.str)+strlen(fmt);	vtmp = malloc(sz);	sprintf(vtmp,fmt, tstart,ldflags.str,crt0.str,ofiles.str,LIBS.str,		initial_lc);	}if (status=System(vtmp)) Exit(status);free(vtmp);if (syms || driver) fmt = "gsrec -noS5 -o %s.tmp %s";else fmt = "gsrec -noS5 -o %s.rec %s";sz = strlen(fmt)+strlen(ofile)+strlen(objfile);vtmp = malloc(sz);#if 0sprintf(vtmp,fmt,objfile,ofile);#else /* 980102 */sprintf(vtmp,fmt,ofile,objfile);#endifif (status=System(vtmp)) Exit(status);free(vtmp);if (driver) {	sprintf(tmp2,"%s.rec",ofile);	str2file(tmp2,"SD");	sprintf(tmp,"%s.tmp",ofile);	appendFile(tmp2,tmp);	unlink(tmp);	Exit(0);	}if (syms) {	sprintf(tmp,"%s.map",ofile);	sprintf(tmp2,"%s.rec",ofile);	mksyms(tmp,tmp2);	sprintf(tmp,"%s.tmp",ofile);	appendFile(tmp2,tmp);	}if (fast) { /* build fastFormat records */	sprintf(tmp,"%s.tmp",ofile);	sprintf(tmp2,"%s.rec",ofile);	unlink(tmp); /* make sure that there's no .tmp file */	rename(tmp2,tmp); /* rename .rec file as .tmp */	/* convert the srecs in the .tmp file to fastrecs. put the	result in .rec file */	sprintf(tmp,"rdsrec -f %s.tmp -o %s.rec",ofile,ofile);	if (status=System(tmp)) Exit(status); /* execute & exit if error */	}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,mode;char buf[LNMAX];/*# 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*/if (getDef("LENDEF")) mode = MODE_LE;else mode = 0;for (i=1;i < argc;i++) {	if (strequ(argv[i],"-mips2")) {		mode &= ~MODE_MSK;		mode |= MODE_4K;		addarg(&cflags,argv[i]);		addarg(&cflags,"-cpu=r4000");		addarg(&asflags,argv[i]);		addarg(&asflags,"-cpu=r4000");		}	else if (strequ(argv[i],"-mips16")) {		mode &= ~MODE_MSK;		mode |= MODE_16;		addarg(&cflags,argv[i]);		addarg(&cflags,"-cpu=r4000");		addarg(&asflags,argv[i]);		addarg(&asflags,"-cpu=r4000");		}	else if (strequ(argv[i],"-G")) {		i++;		if (!strequ(argv[i],"0")) {			sprintf(tmp,"-sda=%s",argv[i]);			Gnum = "o";			}		else {			sprintf(tmp,"-nosda");			Gnum = "g";			}		addarg(&cflags,tmp);		addarg(&asflags,tmp);		}	else if (!strncmp(argv[i],"-O",2)) {		addarg(&cflags,"-OS");  /* 980113 */		}	else if (strequ(argv[i],"-soft-float")) { /* 981028 */		mode |= MODE_SF;		addarg(&cflags,"-fsoft");		addarg(&LIBS,"-lind");		}	else if (strequ(argv[i],"-float")) {		addarg(&flags,argv[i]);		addarg(&flags,"-DFLOAT");		SZ = 1; 		}	else if (strequ(argv[i],"-EB")) {		ENDIAN = "b";		mode &= ~MODE_LE;		}	else if (strequ(argv[i],"-EL")) {		ENDIAN = "l";		mode |= MODE_LE;		}	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++;		}	}sprintf(buf,"-L%s/%s",getDef("COMP_ROOT"),lib_mode[mode]);addarg(&llist,buf);}/**************************************************************  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(char *ifn,char *ofn)*/mksyms(ifn,ofn)char *ifn,*ofn;{FILE *ifp,*ofp;char buf[100],*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;	chomp(buf);	if (strlen(buf)==0) continue;	if (!strncmp(buf,"Global Symbols",14)) flag = 1;	if (!flag) continue;	nf = argvize(field,buf);	if (nf != 3) continue;	if (field[0][0] != '.') continue;	csum = 0;	len = strlen(field[2])+8+2;	fprintf(ofp,"S4%02X%s%s,%02x\n",len,field[1],field[2],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/**************************************************************  fixasm(ifn,ofn)*	This routine fixes all of the GHS assembly syntax differences.*	It does use a few shortcuts and so may not work for all cases.*	Output file must be named .mip.*/fixasm(ifn,ofn)char *ifn,*ofn;{FILE *ifp,*ofp;char buf1[200],buf2[200],*field[40],*p,*s,*e;int nf,flag,n;if (vflag) fprintf(stderr,"fixasm %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(buf1,200,ifp)) break;	chomp(buf1); /* delete the newline char(s) */	/* GHS doesn't like '#' comments in a .mip file */	/* delete all of the comments */	while ((s=strstr(buf1,"/*")) && (e=strstr(s,"*/"))) strcpy(s,e+2);	if (strlen(buf1) && (p=(char *)strchr(&buf1[1],'#'))) *p = 0;	strcpy(buf2,buf1);	nf = argvize(field,buf2); /* split the line into args */	/* now handle the directives that are different */	/* GHS align is # of bytes, MIPS align is 2^# bytes */	if (nf >= 2 && strequ(field[0],".align")) {		sscanf(field[1],"%d",&n);		fprintf(ofp,"\t.align %d\n",1<<n);		}	/* GHS .word does not accept repeat ':' option */	else if (nf == 2 && strequ(field[0],".word") && 		(p=strchr(field[1],':'))) {		*p = 0; p++;		fprintf(ofp,"	.rept %s\n",p);		fprintf(ofp,"	.word %s\n",field[1]);		fprintf(ofp,"	.endr\n");		}	/* GHS .extern does not accept the size option */	else if (nf >= 2 && strequ(field[0],".extern") && 		(p=strchr(field[1],','))) {		*p = 0; p++;		fprintf(ofp,"	.extern %s\n",field[1]);		}	else fprintf(ofp,"%s\n",buf1);	}fclose(ifp);fclose(ofp);}/**************************************************************  mklnkfile(basename)*/mklnkfile(basename)char *basename;{FILE *sfp;sprintf(tmp,"%s.lnk",basename);sfp = fopen(tmp,"w");if (!sfp) {	fprintf(stderr,"can't open %s\n",tmp);	exit(1);	}wrfile(sfp,ld_cmd_file1);fprintf(sfp,"\t.text\t\t0x%s\t:\n",tstart);wrfile(sfp,ld_cmd_file2);fprintf(sfp,"\t.sdabase\t0x%s\t:\n",dstart);wrfile(sfp,ld_cmd_file3);fclose(sfp);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -