scc

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

main.c (2579B)


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