Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1582)

Side by Side Diff: src/cmd/dist/buildruntime.c

Issue 5622058: code review 5622058: cmd/dist: generate files for package runtime (Closed)
Patch Set: diff -r 3300b1f1e809 https://go.googlecode.com/hg/ Created 13 years, 1 month ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/cmd/dist/build.c ('k') | src/cmd/dist/goc2c.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2012 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 #include "a.h"
6 #include <stdio.h>
7
8 /*
9 * Helpers for building pkg/runtime.
10 */
11
12 // mkzversion writes zversion.go:
13 //
14 // package runtime
15 // const defaultGoroot = <goroot>
16 // const theVersion = <version>
17 //
18 void
19 mkzversion(char *dir, char *file)
20 {
21 Buf b, out;
22 ········
23 binit(&b);
24 binit(&out);
25 ········
26 bwritestr(&out, bprintf(&b,
27 "// auto generated by go tool dist\n"
28 "\n"
29 "package runtime\n"
30 "\n"
31 "const defaultGoroot = `%s`\n"
32 "const theVersion = `%s`\n", goroot, goversion));
33
34 writefile(&out, file);
35 ········
36 bfree(&b);
37 bfree(&out);
38 }
39
40 // mkzgoarch writes zgoarch_$GOARCH.go:
41 //
42 // package runtime
43 // const theGoarch = <goarch>
44 //
45 void
46 mkzgoarch(char *dir, char *file)
47 {
48 Buf b, out;
49 ········
50 binit(&b);
51 binit(&out);
52 ········
53 bwritestr(&out, bprintf(&b,
54 "// auto generated by go tool dist\n"
55 "\n"
56 "package runtime\n"
57 "\n"
58 "const theGoarch = `%s`\n", goarch));
59
60 writefile(&out, file);
61 ········
62 bfree(&b);
63 bfree(&out);
64 }
65
66 // mkzgoos writes zgoos_$GOOS.go:
67 //
68 // package runtime
69 // const theGoos = <goos>
70 //
71 void
72 mkzgoos(char *dir, char *file)
73 {
74 Buf b, out;
75 ········
76 binit(&b);
77 binit(&out);
78 ········
79 bwritestr(&out, bprintf(&b,
80 "// auto generated by go tool dist\n"
81 "\n"
82 "package runtime\n"
83 "\n"
84 "const theGoos = `%s`\n", goos));
85
86 writefile(&out, file);
87 ········
88 bfree(&b);
89 bfree(&out);
90 }
91
92 static struct {
93 char *goarch;
94 char *goos;
95 char *hdr;
96 } zasmhdr[] = {
97 {"386", "windows",
98 "#define get_tls(r) MOVL 0x14(FS), r\n"
99 "#define g(r) 0(r)\n"
100 "#define m(r) 4(r)\n"
101 },
102 {"386", "plan9",
103 "#define get_tls(r) MOVL _tos(SB), r \n"
104 "#define g(r) -8(r)\n"
105 "#define m(r) -4(r)\n"
106 },
107 {"386", "linux",
108 "// On Linux systems, what we call 0(GS) and 4(GS) for g and m\n "
109 "// turn into %gs:-8 and %gs:-4 (using gcc syntax to denote\n"
110 "// what the machine sees as opposed to 8l input).\n"
111 "// 8l rewrites 0(GS) and 4(GS) into these.\n"
112 "//\n"
113 "// On Linux Xen, it is not allowed to use %gs:-8 and %gs:-4\n"
114 "// directly. Instead, we have to store %gs:0 into a temporary\ n"
115 "// register and then use -8(%reg) and -4(%reg). This kind\n"
116 "// of addressing is correct even when not running Xen.\n"
117 "//\n"
118 "// 8l can rewrite MOVL 0(GS), CX into the appropriate pair\n"
119 "// of mov instructions, using CX as the intermediate register\n "
120 "// (safe because CX is about to be written to anyway).\n"
121 "// But 8l cannot handle other instructions, like storing into 0 (GS),\n"
122 "// which is where these macros come into play.\n"
123 "// get_tls sets up the temporary and then g and r use it.\n"
124 "//\n"
125 "// The final wrinkle is that get_tls needs to read from %gs:0,\ n"
126 "// but in 8l input it's called 8(GS), because 8l is going to\n"
127 "// subtract 8 from all the offsets, as described above.\n"
128 "#define get_tls(r) MOVL 8(GS), r\n"
129 "#define g(r) -8(r)\n"
130 "#define m(r) -4(r)\n"
131 },
132 {"386", "",
133 "#define get_tls(r)\n"
134 "#define g(r) 0(GS)\n"
135 "#define m(r) 4(GS)\n"
136 },
137 ········
138 {"amd64", "windows",
139 "#define get_tls(r) MOVQ 0x28(GS), r\n"
140 "#define g(r) 0(r)\n"
141 "#define m(r) 8(r)\n"
142 },
143 {"amd64", "",
144 "// The offsets 0 and 8 are known to:\n"
145 "// ../../cmd/6l/pass.c:/D_GS\n"
146 "// cgo/gcc_linux_amd64.c:/^threadentry\n"
147 "// cgo/gcc_darwin_amd64.c:/^threadentry\n"
148 "//\n"
149 "#define get_tls(r)\n"
150 "#define g(r) 0(GS)\n"
151 "#define m(r) 8(GS)\n"
152 },
153 ········
154 {"arm", "",
155 "#define g R10\n"
156 "#define m R9\n"
157 "#define LR R14\n"
158 },
159 };
160
161 // mkzasm writes zasm_$GOOS_$GOARCH.h,
162 // which contains struct offsets for use by
163 // assembly files. It also writes a copy to the work space
164 // under the name zasm_GOOS_GOARCH.h (no expansion).
165 //·
166 void
167 mkzasm(char *dir, char *file)
168 {
169 int i, n;
170 char *aggr, *p;
171 Buf in, b, out;
172 Vec argv, lines, fields;
173
174 binit(&in);
175 binit(&b);
176 binit(&out);
177 vinit(&argv);
178 vinit(&lines);
179 vinit(&fields);
180 ········
181 bwritestr(&out, "// auto generated by go tool dist\n\n");
182 for(i=0; i<nelem(zasmhdr); i++) {
183 if(hasprefix(goarch, zasmhdr[i].goarch) && hasprefix(goos, zasmh dr[i].goos)) {
184 bwritestr(&out, zasmhdr[i].hdr);
185 goto ok;
186 }
187 }
188 fatal("unknown $GOOS/$GOARCH in mkzasm");
189 ok:
190
191 // Run 6c -DGOOS_goos -DGOARCH_goarch -Iworkdir -a proc.c
192 // to get acid [sic] output.
193 vreset(&argv);
194 vadd(&argv, bpathf(&b, "%s/bin/tool/%sc", goroot, gochar));
195 vadd(&argv, bprintf(&b, "-DGOOS_%s", goos));
196 vadd(&argv, bprintf(&b, "-DGOARCH_%s", goarch));
197 vadd(&argv, bprintf(&b, "-I%s", workdir));
198 vadd(&argv, "-a");
199 vadd(&argv, "proc.c");
200 runv(&in, dir, CheckExit, &argv);
201 ········
202 // Convert input like
203 // aggr G
204 // {
205 // Gobuf 24 sched;
206 // 'Y' 48 stack0;
207 // }
208 // into output like
209 // #define g_sched 24
210 // #define g_stack0 48
211 //
212 aggr = nil;
213 splitlines(&lines, bstr(&in));
214 for(i=0; i<lines.len; i++) {
215 splitfields(&fields, lines.p[i]);
216 if(fields.len == 2 && streq(fields.p[0], "aggr")) {
217 if(streq(fields.p[1], "G"))
218 aggr = "g";
219 else if(streq(fields.p[1], "M"))
220 aggr = "m";
221 else if(streq(fields.p[1], "Gobuf"))
222 aggr = "gobuf";
223 else if(streq(fields.p[1], "WinCall"))
224 aggr = "wincall";
225 }
226 if(hasprefix(lines.p[i], "}"))
227 aggr = nil;
228 if(aggr && hasprefix(lines.p[i], "\t") && fields.len >= 2) {
229 n = fields.len;
230 p = fields.p[n-1];
231 if(p[xstrlen(p)-1] == ';')
232 p[xstrlen(p)-1] = '\0';
233 bwritestr(&out, bprintf(&b, "#define %s_%s %s\n", aggr, fields.p[n-1], fields.p[n-2]));
234 }
235 }
236 ········
237 // Write both to file and to workdir/zasm_GOOS_GOARCH.h.
238 writefile(&out, file);
239 writefile(&out, bprintf(&b, "%s/zasm_GOOS_GOARCH.h", workdir));
240
241 bfree(&in);
242 bfree(&b);
243 bfree(&out);
244 vfree(&argv);
245 vfree(&lines);
246 vfree(&fields);
247 }
248
249 static char *runtimedefs[] = {
250 "proc.c",
251 "iface.c",
252 "hashmap.c",
253 "chan.c",
254 };
255
256 // mkzruntimedefs writes zruntime_defs_$GOOS_$GOARCH.h,
257 // which contains Go struct definitions equivalent to the C ones.
258 // Mostly we just write the output of 6c -q to the file.
259 // However, we run it on multiple files, so we have to delete
260 // the duplicated definitions, and we don't care about the funcs
261 // and consts, so we delete those too.
262 //·
263 void
264 mkzruntimedefs(char *dir, char *file)
265 {
266 int i, skip;
267 char *p;
268 Buf in, b, out;
269 Vec argv, lines, fields, seen;
270 ········
271 binit(&in);
272 binit(&b);
273 binit(&out);
274 vinit(&argv);
275 vinit(&lines);
276 vinit(&fields);
277 vinit(&seen);
278 ········
279 bwritestr(&out, "// auto generated by go tool dist\n"
280 "\n"
281 "package runtime\n"
282 "import \"unsafe\"\n"
283 "var _ unsafe.Pointer\n"
284 "\n"
285 );
286
287 ········
288 // Run 6c -DGOOS_goos -DGOARCH_goarch -Iworkdir -q
289 // on each of the runtimedefs C files.
290 vadd(&argv, bpathf(&b, "%s/bin/tool/%sc", goroot, gochar));
291 vadd(&argv, bprintf(&b, "-DGOOS_%s", goos));
292 vadd(&argv, bprintf(&b, "-DGOARCH_%s", goarch));
293 vadd(&argv, bprintf(&b, "-I%s", workdir));
294 vadd(&argv, "-q");
295 vadd(&argv, "");
296 p = argv.p[argv.len-1];
297 for(i=0; i<nelem(runtimedefs); i++) {
298 argv.p[argv.len-1] = runtimedefs[i];
299 runv(&b, dir, CheckExit, &argv);
300 bwriteb(&in, &b);
301 }
302 argv.p[argv.len-1] = p;
303 ················
304 // Process the aggregate output.
305 skip = 0;
306 splitlines(&lines, bstr(&in));
307 for(i=0; i<lines.len; i++) {
308 p = lines.p[i];
309 // Drop comment, func, and const lines.
310 if(hasprefix(p, "//") || hasprefix(p, "const") || hasprefix(p, " func"))
311 continue;
312 ················
313 // Note beginning of type or var decl, which can be multiline.
314 // Remove duplicates. The linear check of seen here makes the
315 // whole processing quadratic in aggregate, but there are only
316 // about 100 declarations, so this is okay (and simple).
317 if(hasprefix(p, "type ") || hasprefix(p, "var ")) {
318 splitfields(&fields, p);
319 if(fields.len < 2)
320 continue;
321 if(find(fields.p[1], seen.p, seen.len) >= 0) {
322 if(streq(fields.p[fields.len-1], "{"))
323 skip = 1; // skip until }
324 continue;
325 }
326 vadd(&seen, fields.p[1]);
327 }
328 if(skip) {
329 if(hasprefix(p, "}"))
330 skip = 0;
331 continue;
332 }
333 ················
334 bwritestr(&out, p);
335 }
336 ········
337 writefile(&out, file);
338
339 bfree(&in);
340 bfree(&b);
341 bfree(&out);
342 vfree(&argv);
343 vfree(&lines);
344 vfree(&fields);
345 vfree(&seen);
346 }
OLDNEW
« no previous file with comments | « src/cmd/dist/build.c ('k') | src/cmd/dist/goc2c.c » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b