diff options
Diffstat (limited to 'mdk-stage1/dietlibc/diet.c')
-rw-r--r-- | mdk-stage1/dietlibc/diet.c | 317 |
1 files changed, 286 insertions, 31 deletions
diff --git a/mdk-stage1/dietlibc/diet.c b/mdk-stage1/dietlibc/diet.c index 1de6befc8..c3a053ac8 100644 --- a/mdk-stage1/dietlibc/diet.c +++ b/mdk-stage1/dietlibc/diet.c @@ -1,7 +1,11 @@ #include <string.h> #include <unistd.h> +#include <fcntl.h> #include <stdio.h> #include <stdlib.h> +#include <write12.h> + +#include "dietfeatures.h" /* goal: * when invoked as @@ -15,90 +19,341 @@ * "sparc-linux-gcc -nostdlib -static -o t t.o /path/to/dietlibc/bin-sparc/start.o /path/to/dietlibc/bin-sparc/dietlibc.a" */ -void error(const char *message) { - write(2,message,strlen(message)); +static void error(const char *message) { + __write2(message); exit(1); } +static const char* Os[] = { + "i386","-Os","-mpreferred-stack-boundary=2", + "-malign-functions=0","-malign-jumps=0", + "-malign-loops=0","-fomit-frame-pointer",0, + "x86_64","-Os","-fno-omit-frame-pointer",0, + "sparc","-Os","-mcpu=supersparc",0, + "sparc64","-Os","-m64",0, + "alpha","-Os","-fomit-frame-pointer",0, + "arm","-Os","-fomit-frame-pointer",0, + "mips","-Os","-fomit-frame-pointer","-mno-abicalls","-G","8","-fno-pic",0, + "ppc","-Os","-fomit-frame-pointer","-mpowerpc-gpopt","-mpowerpc-gfxopt",0, + "s390","-Os","-fomit-frame-pointer",0, + "sh","-Os","-fomit-frame-pointer",0, + "ia64","-Os","-fno-omit-frame-pointer",0, + "x86_64","-Os","-fstrict-aliasing","-momit-leaf-frame-pointer","-mfance-math-387",0, + 0}; + int main(int argc,char *argv[]) { - int link=0; + int _link=0; int compile=0; + int preprocess=0; + int verbose=0; + int profile=0; char diethome[]=DIETHOME; - char platform[1000]=DIETHOME "/bin-"; - char *nostdlib="-nostdlib"; - char *libgcc="-lgcc"; - char dashL[1000]="-L"; + char platform[1000]; +#ifdef __DYN_LIB + int shared=0; +#endif + char* shortplatform=0; +#ifdef WANT_SAFEGUARD + char safeguard1[]="-include"; + char safeguard2[]=DIETHOME "/include/dietref.h"; +#endif + const char *nostdlib="-nostdlib"; + const char *libgcc="-lgcc"; + char dashL[1000]; + char dashstatic[]="-static"; int i; + int mangleopts=0; + char manglebuf[1024]; + +#ifdef INSTALLVERSION + strcpy(platform,DIETHOME "/lib-"); +#else +#ifndef __DYN_LIB + strcpy(platform,DIETHOME "/bin-"); +#else + strcpy(platform,DIETHOME "/pic-"); +#endif +#endif + strcpy(dashL,"-L"); if (argc<2) { - error("usage: diet [gcc command line]\n" - "e.g. diet gcc -c t.c\n" +usage: + if (verbose) { + __write2( +#ifdef __DYN_LIB + "dyn-" +#endif + "diet version " VERSION +#ifndef INSTALLVERSION + " (non-install version in source tree)" +#endif + "\n\n"); + } + error("usage: diet [-v] [-Os] gcc command line\n" + "e.g. diet -Os gcc -c t.c\n" "or diet sparc-linux-gcc -o foo foo.c bar.o\n"); } + if (!strcmp(argv[1],"-v")) { + ++argv; --argc; + verbose=1; + } + if (argv[1] && !strcmp(argv[1],"-Os")) { + ++argv; --argc; + mangleopts=1; + } + if (!argv[1]) goto usage; { char *tmp=strchr(argv[1],0)-2; - char *tmp2; + char *tmp2,*tmp3; char *cc=argv[1]; if (tmp<cc) goto donttouch; - if ((tmp2=strchr(cc,'-'))) { /* cross compiling? */ + if ((tmp2=strstr(cc,"linux-"))) { /* cross compiling? */ int len=strlen(platform); + --tmp2; + tmp3=strchr(cc,'-'); + if (tmp3<tmp2) tmp2=tmp3; if (tmp2-cc>90) error("platform name too long!\n"); - memmove(platform+len,argv[1],tmp2-cc); + shortplatform=platform+len; + memmove(shortplatform,argv[1],(size_t)(tmp2-cc)); platform[tmp2-cc+len]=0; -/* printf("found platform %s\n",platform); */ + if (shortplatform[0]=='i' && shortplatform[2]=='8' && shortplatform[3]=='6') shortplatform[1]='3'; } else { #ifdef __sparc__ - strcat(platform,"sparc"); +#ifdef __arch64__ + shortplatform="sparc64"; +#else + shortplatform="sparc"; #endif -#ifdef __ppc__ - strcat(platform,"ppc"); +#endif +#ifdef __powerpc__ + shortplatform="ppc"; #endif #ifdef __i386__ - strcat(platform,"i386"); + shortplatform="i386"; #endif #ifdef __alpha__ - strcat(platform,"alpha"); + shortplatform="alpha"; #endif #ifdef __arm__ - strcat(platform,"arm"); + shortplatform="arm"; #endif #ifdef __mips__ - strcat(platform,"mips"); + shortplatform="mips"; +#endif +#ifdef __s390__ + shortplatform="s390"; +#endif +#ifdef __sh__ + shortplatform="sh"; +#endif +#ifdef __hppa__ + shortplatform="parisc"; +#endif +#ifdef __x86_64__ + shortplatform="x86_64"; +#endif +#ifdef __ia64__ + shortplatform="ia64"; #endif + { + char *tmp=platform+strlen(platform); + strcpy(tmp,shortplatform); + shortplatform=tmp; + } + } + /* MIPS needs special handling. If argv contains -EL, change + * platform name to mipsel */ + if (!strcmp(shortplatform,"mips")) { + int i; + for (i=1; i<argc; ++i) + if (!strcmp(argv[i],"-EL")) + strcpy(shortplatform,"mipsel"); } strcat(dashL,platform); if (!strcmp(tmp,"cc")) { char **newargv; char **dest; char *a,*b,*c; +#ifdef WANT_DYNAMIC + char *d,*e,*f; +#endif /* we need to add -I... if the command line contains -c, -S or -E */ - for (i=2; i<argc; ++i) - if (!strcmp(argv[i],"-c") || !strcmp(argv[i],"-S") || !strcmp(argv[i],"-E")) + for (i=2; i<argc; ++i) { + if (argv[i][0]=='-' && argv[i][1]=='M') + goto pp; + if (!strcmp(argv[i],"-pg")) + profile=1; + if (!strcmp(argv[i],"-c") || !strcmp(argv[i],"-S")) compile=1; + if (!strcmp(argv[i],"-E")) +pp: + preprocess=compile=1; + } /* we need to add -nostdlib if we are not compiling*/ - link=!compile; + _link=!compile; +#ifdef __DYN_LIB + if (_link) { + for (i=2; i<argc; ++i) + if (!strcmp(argv[i],"-shared")) { + shared=1; + _link=0; + } + } +#endif #if 0 for (i=2; i<argc; ++i) if (!strcmp(argv[i],"-o")) - if (!compile) link=1; + if (!compile) _link=1; #endif - newargv=alloca(sizeof(char*)*(argc+6)); + newargv=alloca(sizeof(char*)*(argc+100)); a=alloca(strlen(diethome)+20); b=alloca(strlen(platform)+20); c=alloca(strlen(platform)+20); strcpy(a,"-I"); strcat(a,diethome); strcat(a,"/include"); - strcpy(b,platform); strcat(b,"/start.o"); +#ifndef __DYN_LIB + strcpy(b,platform); + if (profile) strcat(b,"/pstart.o"); else strcat(b,"/start.o"); +#ifdef INSTALLVERSION + strcpy(c,platform); strcat(c,"/libc.a"); +#else strcpy(c,platform); strcat(c,"/dietlibc.a"); +#endif +#else + strcpy(b,platform); strcat(b,"/dstart.o"); + strcpy(c,"-lc"); +#endif + +#ifdef WANT_DYNAMIC + d=alloca(strlen(platform)+20); + e=alloca(strlen(platform)+20); +#ifdef __DYN_LIB + strcpy(d,platform); + strcpy(e,platform); + if (shared) + strcat(d,"/dyn_so_start.o"); +#ifdef INSTALLVERSION + else + strcat(d,"/dyn_dstart.o"); + strcat(e,"/dyn_dstop.o"); +#else + else + strcat(d,"/dyn_start.o"); + strcat(e,"/dyn_stop.o"); +#endif +#else + strcpy(d,platform); strcat(d,"/dyn_start.o"); + strcpy(e,platform); strcat(e,"/dyn_stop.o"); +#endif +#endif dest=newargv; *dest++=argv[1]; - if (link) { *dest++=nostdlib; *dest++=dashL; } - if (compile || link) *dest++=a; - for (i=2; i<argc; ++i) +#ifndef __DYN_LIB + if (_link) { *dest++=(char*)nostdlib; *dest++=dashstatic; *dest++=dashL; } +#else + /* avoid R_*_COPY relocations */ + *dest++="-fPIC"; + if (_link || shared) { *dest++=(char*)nostdlib; *dest++=dashL; } +#endif +#ifdef WANT_SAFEGUARD + if (compile && !preprocess) { + *dest++=safeguard1; + *dest++=safeguard2; + } +#endif + if (_link) { *dest++=b; } +#ifdef WANT_DYNAMIC + if (_link) { *dest++=d; } +#endif + for (i=2; i<argc; ++i) { + if (mangleopts) + if (argv[i][0]=='-' && (argv[i][1]=='O' || argv[i][1]=='f' || argv[i][1]=='m')) { + if (strcmp(argv[i],"-fpic") && strcmp(argv[i],"-fno-pic")) + continue; + } *dest++=argv[i]; - if (link) { *dest++=b; *dest++=c; *dest++=libgcc; } + } +#ifndef __DYN_LIB + if (compile || _link) *dest++=a; +#else + if (compile || _link || shared) *dest++=a; +#endif + *dest++="-D__dietlibc__"; + if (mangleopts) { + const char **o=Os; + + { + int fd; + char* tmp=getenv("HOME"); + if (tmp) { + if (strlen(tmp)+strlen(cc)<900) { + strcpy(manglebuf,tmp); + strcat(manglebuf,"/.diet/"); + strcat(manglebuf,cc); + if ((fd=open(manglebuf,O_RDONLY))>=0) { + int len=read(fd,manglebuf,1023); + if (len>0) { + int i; + manglebuf[len]=0; + *dest++=manglebuf; + for (i=1; i<len; ++i) { + if (manglebuf[i]==' ' || manglebuf[i]=='\n') { + manglebuf[i]=0; + if (i+1<len) + *dest++=manglebuf+i+1; + } + } + goto incorporated; + } + } + } + } + } + for (o=Os;*o;++o) { + if (!strcmp(*o,shortplatform)) { + ++o; + while (*o) { + *dest++=(char*)*o; + ++o; + } + break; + } else + while (*o) ++o; + } + } +incorporated: + if (_link) { + if (profile) *dest++="-lgmon"; + if (!strcmp(shortplatform,"sparc") || !strcmp(shortplatform,"sparc64")) { + *dest++=(char*)libgcc; *dest++=c; + } else { + *dest++=c; *dest++=(char*)libgcc; + } + } +#ifdef WANT_DYNAMIC + if (_link) { *dest++=e; } +#endif +#ifdef __DYN_LIB + if (shared){ *dest++=c; } + f=alloca(strlen(platform)+100); + if (_link) { + strcpy(f,"-Wl,-dynamic-linker="); + strcat(f,platform); +// strcat(f,"/diet-linux.so"); + strcat(f,"/libdl.so"); + *dest++=f; + } +#endif *dest=0; + if (verbose) { + int i; + for (i=0; newargv[i]; i++) { + __write2(newargv[i]); + __write2(" "); + } + __write2("\n"); + } execvp(newargv[0],newargv); goto error; } else if (!strcmp(tmp,"ld")) { @@ -107,6 +362,6 @@ int main(int argc,char *argv[]) { donttouch: execvp(argv[1],argv+1); error: - error("execvp failed!\n"); + error("execvp() failed!\n"); return 1; } |