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 Section text = {.type = 'T'};
24 Section rodata = {.type = 'R'};
25 Section data = {.type = 'D'};
26 Section bss = {.type = 'B'};
27 Section 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 }