main.c - scc - simple c99 compiler
 (HTM) git clone git://git.simple-cc.org/scc
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Submodules
 (DIR) README
 (DIR) LICENSE
       ---
       main.c (2862B)
       ---
            1 #include <errno.h>
            2 #include <stdarg.h>
            3 #include <stdio.h>
            4 #include <stdlib.h>
            5 #include <string.h>
            6 
            7 #include <scc/mach.h>
            8 
            9 #include "ld.h"
           10 
           11 #define MAX_LIB_PATHS 12
           12 
           13 int sflag;        /* discard all the symbols */
           14 int xflag;        /* discard local symbols */
           15 int Xflag;        /* discard locals starting with 'L' */
           16 int rflag;        /* preserve relocation bits */
           17 int dflag;        /* define common even with rflag */
           18 int gflag;        /* preserve debug symbols */
           19 int nmagic;       /* nmagic output */
           20 
           21 char *filename, *membname;
           22 
           23 Segment text = {.type = 'T'};
           24 Segment rodata = {.type = 'R'};
           25 Segment data = {.type = 'D'};
           26 Segment bss = {.type = 'B'};
           27 Segment debug = {.type = 'N'};
           28 
           29 char *libpaths[MAX_LIB_PATHS];
           30 
           31 char *output = "a.out", *entry = "start";
           32 static int status;
           33 
           34 void
           35 error(char *fmt, ...)
           36 {
           37         va_list va;
           38 
           39         va_start(va, fmt);
           40         fprintf(stderr, "ld: %s: ", filename);
           41         if (membname)
           42                 fprintf(stderr, "%s: ", membname);
           43         vfprintf(stderr, fmt, va);
           44         putc('\n', stderr);
           45         va_end(va);
           46 
           47         status = EXIT_FAILURE;
           48 }
           49 
           50 static void
           51 cleanup(void)
           52 {
           53         if (status != EXIT_FAILURE)
           54                 remove(output);
           55 }
           56 
           57 /*
           58  * pass1: Get the list of object files that are going to be linked.
           59  * pass2: Calculate the size of every segment.
           60  * pass3: Rebase all symbols in sections
           61  * pass4: Create the temporary files per section
           62  * pass5: Create the temporary files per segment
           63  */
           64 static void
           65 ld(int argc, char*argv[])
           66 {
           67         pass1(argc, argv);
           68         pass2(argc, argv);
           69 /*
           70         pass3(argc, argv);
           71         pass4(argc, argv);
           72         pass5(argc, argv);
           73 */
           74         debugsym();
           75         debugsec();
           76 }
           77 
           78 static void
           79 usage(void)
           80 {
           81         fputs("usage: ld [options] file ...\n", stderr);
           82         exit(EXIT_FAILURE);
           83 }
           84 
           85 static void
           86 Lpath(char *path)
           87 {
           88         char **bp, **end;
           89 
           90         end = &libpaths[MAX_LIB_PATHS];
           91         for (bp = libpaths; bp < end && *bp; ++bp)
           92                 ;
           93         if (bp == end) {
           94                 fputs("ld: too many -L options\n", stderr);
           95                 exit(1);
           96         }
           97         *bp = path;
           98 }
           99 
          100 char *
          101 nextarg(char **argp, char ***argv)
          102 {
          103         char *ap = *argp, **av = *argv;
          104 
          105         if (ap[1]) {
          106                 *argp += strlen(ap);
          107                 return ap+1;
          108         }
          109 
          110         if (av[1]) {
          111                 *argv = ++av;
          112                 return *av;
          113         }
          114 
          115         usage();
          116 }
          117 
          118 int
          119 main(int argc, char *argv[])
          120 {
          121         int files = 0;
          122         char *ap, **av;
          123 
          124         for (av = argv+1; *av; ++av) {
          125                 if (av[0][0] != '-') {
          126                         files = 1;
          127                         continue;
          128                 }
          129                 for (ap = &av[0][1]; *ap; ++ap) {
          130                         switch (*ap) {
          131                         case 's':
          132                                 sflag = 1;
          133                                 break;
          134                         case 'x':
          135                                 xflag = 1;
          136                                 break;
          137                         case 'X':
          138                                 Xflag = 1;
          139                                 break;
          140                         case 'i':
          141                         case 'r':
          142                                 rflag = 1;
          143                                 break;
          144                         case 'd':
          145                                 dflag = 1;
          146                                 break;
          147                         case 'n':
          148                                 nmagic = 1;
          149                                 break;
          150                         case 'l':
          151                         case 'u':
          152                                 nextarg(&ap, &av);
          153                                 break;
          154                         case 'L':
          155                                 Lpath(nextarg(&ap, &av));
          156                                 break;
          157                         case 'o':
          158                                 output = nextarg(&ap, &av);
          159                                 break;
          160                         case 'e':
          161                                 entry = nextarg(&ap, &av);
          162                                 break;
          163                         default:
          164                                 usage();
          165                         }
          166                 }
          167         }
          168 
          169         if (!files)
          170                 usage();
          171 
          172         atexit(cleanup);
          173         ld(argc, argv);
          174 
          175         return status;
          176 }