scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | README | LICENSE

main.c (2535B)


      1 #include <errno.h>
      2 #include <stdarg.h>
      3 #include <stdio.h>
      4 #include <stdlib.h>
      5 #include <string.h>
      6 
      7 #include <scc/syslibs.h>
      8 
      9 #include "ld.h"
     10 
     11 char *output = "a.out", *entry = "start";
     12 
     13 char *filename, *membname;
     14 unsigned long textsiz, datasiz, bsssiz;
     15 unsigned long textbase, database, bssbase;
     16 
     17 int sflag;        /* discard all the symbols */
     18 int xflag;        /* discard local symbols */
     19 int Xflag;        /* discard locals starting with 'L' */
     20 int rflag;        /* preserve relocation bits */
     21 int dflag;        /* define common even with rflag */
     22 int gflag;        /* preserve debug symbols */
     23 char *Dflag;      /* size of data */
     24 
     25 static int status;
     26 
     27 char *
     28 errstr(void)
     29 {
     30 	return strerror(errno);
     31 }
     32 
     33 void
     34 error(char *fmt, ...)
     35 {
     36 	va_list va;
     37 
     38 	va_start(va, fmt);
     39 	fprintf(stderr, "ld: %s: ", filename);
     40 	if (membname)
     41 		fprintf(stderr, "%s: ", membname);
     42 	vfprintf(stderr, fmt, va);
     43 	putc('\n', stderr);
     44 	va_end(va);
     45 
     46 	status = EXIT_FAILURE;
     47 }
     48 
     49 static void
     50 cleanup(void)
     51 {
     52 	if (status != EXIT_FAILURE)
     53 		remove(output);
     54 }
     55 
     56 static void
     57 usage(void)
     58 {
     59 	fputs("usage: ld [options] file ...\n", stderr);
     60 	exit(EXIT_FAILURE);
     61 }
     62 
     63 static void
     64 Lpath(char *path)
     65 {
     66 	char **bp, **end;
     67 
     68 	end = &syslibs[MAX_LIB_PATHS];
     69 	for (bp = syslibs; bp < end && *bp; ++bp)
     70 		;
     71 	if (bp == end) {
     72 		fputs("ld: too many -L options\n", stderr);
     73 		exit(1);
     74 	}
     75 	*bp = path;
     76 }
     77 
     78 int
     79 main(int argc, char *argv[])
     80 {
     81 	char *cp, **p;
     82 
     83 	for (--argc; *++argv; --argc) {
     84 		if (argv[0][0] != '-' || argv[0][1] == 'l')
     85 			break;
     86 		if (argv[0][1] == '-') {
     87 			--argc, ++argv;
     88 			break;
     89 		}
     90 		for (cp = &argv[0][1]; *cp; ++cp) {
     91 			switch (*cp) {
     92 			case 's':
     93 				sflag = 1;
     94 				break;
     95 			case 'x':
     96 				xflag = 1;
     97 				break;
     98 			case 'X':
     99 				Xflag = 1;
    100 				break;
    101 			case 'r':
    102 				rflag = 1;
    103 				break;
    104 			case 'd':
    105 				dflag = 1;
    106 				break;
    107 			case 'i':
    108 			case 'n':
    109 				/* TODO */
    110 				break;
    111 			case 'L':
    112 				if (argc == 0)
    113 					goto usage;
    114 				++argv, --argc;
    115 				Lpath(*argv);
    116 				break;
    117 			case 'u':
    118 				if (argc == 0)
    119 					goto usage;
    120 				++argv, --argc;
    121 				lookup(*argv, INSTALL);
    122 				break;
    123 			case 'o':
    124 				if (argc == 0)
    125 					goto usage;
    126 				++argv, --argc;
    127 				output = *argv;
    128 				break;
    129 			case 'e':
    130 				if (argc == 0)
    131 					goto usage;
    132 				++argv, --argc;
    133 				entry = *argv;
    134 				break;
    135 			case 'D':
    136 				if (argc == 0)
    137 					goto usage;
    138 				++argv, --argc;
    139 				Dflag = *argv;
    140 				break;
    141 			default:
    142 			usage:
    143 				usage();
    144 			}
    145 		}
    146 	}
    147 
    148 	if (argc == 0)
    149 		usage();
    150 
    151 	atexit(cleanup);
    152 
    153 	pass1(argc, argv);
    154 	pass2(argc, argv);
    155 	pass3(argc, argv);
    156 
    157 	return status;
    158 }