summaryrefslogtreecommitdiffstats
path: root/mdk-stage1/dietlibc/diet.c
diff options
context:
space:
mode:
Diffstat (limited to 'mdk-stage1/dietlibc/diet.c')
-rw-r--r--mdk-stage1/dietlibc/diet.c317
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;
}