Mercurial > projects > ddmd
annotate dmd/backend/glue.d @ 14:2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
author | Robert Clipsham <robert@octarineparrot.com> |
---|---|
date | Sun, 04 Apr 2010 02:06:32 +0100 |
parents | 10317f0c89a5 |
children | 5c9b78899f5d |
rev | line source |
---|---|
0 | 1 module dmd.backend.glue; |
2 | |
3 import dmd.Array; | |
4 import dmd.Dsymbol; | |
5 import dmd.File; | |
6 import dmd.FileName; | |
7 import dmd.Library; | |
8 import dmd.OutBuffer; | |
9 import dmd.Module; | |
10 import dmd.Identifier; | |
11 import dmd.AssertExp; | |
12 import dmd.TOK; | |
13 import dmd.Global; | |
14 import dmd.Param; | |
15 import dmd.backend.Config; | |
16 import dmd.backend.Configv; | |
17 import dmd.backend.StringTab; | |
18 | |
19 import core.stdc.string; | |
20 | |
21 __gshared Array obj_symbols_towrite; | |
22 | |
14
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
23 extern (C++) /+extern+/ |
0 | 24 { |
25 __gshared Outbuffer objbuf; | |
26 int go_flag(char* cp); | |
27 void util_set64(); | |
28 void util_set386(); | |
29 } | |
30 | |
31 import std.contracts; | |
32 import std.string; | |
33 | |
34 string lastmname; | |
35 | |
36 struct Outbuffer | |
37 { | |
38 ubyte* buf; // the buffer itself | |
39 ubyte* pend; // pointer past the end of the buffer | |
40 ubyte* p; // current position in buffer | |
41 uint len; // size of buffer | |
42 uint inc; // default increment size | |
43 | |
44 this(uint inc) | |
45 { | |
46 assert(false); | |
47 } | |
48 | |
49 ~this() | |
50 { | |
51 assert(false); | |
52 } | |
53 | |
54 void reset() | |
55 { | |
56 assert(false); | |
57 } | |
58 | |
59 // Reserve nbytes in buffer | |
60 void reserve(uint nbytes) | |
61 { | |
62 assert(false); | |
63 } | |
64 | |
65 // Write n zeros; return pointer to start of zeros | |
66 void* writezeros(uint n) | |
67 { | |
68 assert(false); | |
69 } | |
70 | |
71 // Position buffer to accept the specified number of bytes at offset | |
72 int position(uint offset, uint nbytes); | |
73 | |
74 // Write an array to the buffer, no reserve check | |
75 void writen(const(void)* b, int len) | |
76 { | |
77 memcpy(p,b,len); | |
78 p += len; | |
79 } | |
80 | |
81 // Clear bytes, no reserve check | |
82 void clearn(int len) | |
83 { | |
84 int i; | |
85 for (i=0; i< len; i++) | |
86 *p++ = 0; | |
87 } | |
88 | |
89 // Write an array to the buffer. | |
90 void write(const void *b, int len) | |
91 { | |
92 assert(false); | |
93 } | |
94 | |
95 void write(Outbuffer* b) | |
96 { | |
97 write(b.buf, b.p - b.buf); | |
98 } | |
99 | |
100 /** | |
101 * Flushes the stream. This will write any buffered | |
102 * output bytes. | |
103 */ | |
104 void flush() { } | |
105 | |
106 /** | |
107 * Writes an 8 bit byte, no reserve check. | |
108 */ | |
109 void writeByten(char v) | |
110 { | |
111 *p++ = v; | |
112 } | |
113 | |
114 /** | |
115 * Writes an 8 bit byte. | |
116 */ | |
117 void writeByte(int v) | |
118 { | |
119 assert(false); | |
120 } | |
121 | |
122 /** | |
123 * Writes a 16 bit little-end short, no reserve check. | |
124 */ | |
125 void writeWordn(int v) | |
126 { | |
127 version (_WIN32) { | |
128 *cast(ushort*)p = cast(short)v; | |
129 } else { | |
14
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
130 assert(0, "Check this"); |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
131 p[0] = cast(ubyte)v; |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
132 p[1] = cast(ubyte)(v >> 8); |
0 | 133 } |
134 p += 2; | |
135 } | |
136 | |
137 /** | |
138 * Writes a 16 bit little-end short. | |
139 */ | |
140 void writeWord(int v) | |
141 { | |
142 reserve(2); | |
143 writeWordn(v); | |
144 } | |
145 | |
146 /** | |
147 * Writes a 16 bit big-end short. | |
148 */ | |
149 void writeShort(int v) | |
150 { | |
151 if (pend - p < 2) | |
152 reserve(2); | |
153 | |
154 static if (false) { | |
155 p[0] = (cast(ubyte*)&v)[1]; | |
156 p[1] = v; | |
157 } else { | |
158 ubyte* q = p; | |
159 q[0] = cast(ubyte)(v >> 8); | |
160 q[1] = cast(ubyte)v; | |
161 } | |
162 p += 2; | |
163 } | |
164 | |
165 /** | |
166 * Writes a 16 bit char. | |
167 */ | |
168 void writeChar(int v) | |
169 { | |
170 writeShort(v); | |
171 } | |
172 | |
173 /** | |
174 * Writes a 32 bit int. | |
175 */ | |
176 void write32(long v) | |
177 { | |
178 assert(false); | |
179 } | |
180 | |
181 /** | |
182 * Writes a 64 bit long. | |
183 */ | |
184 ///#if __INTSIZE == 4 | |
185 void write64(long v) | |
186 { | |
187 assert(false); | |
188 } | |
189 ///#endif | |
190 | |
191 /** | |
192 * Writes a 32 bit float. | |
193 */ | |
194 void writeFloat(float v) | |
195 { | |
196 assert(false); | |
197 } | |
198 | |
199 /** | |
200 * Writes a 64 bit double. | |
201 */ | |
202 void writeDouble(double v) | |
203 { | |
204 assert(false); | |
205 } | |
206 | |
207 void write(const(char)* s) | |
208 { | |
209 assert(false); | |
210 } | |
211 | |
212 void write(const(ubyte)* s) | |
213 { | |
214 assert(false); | |
215 } | |
216 | |
217 void writeString(const(char)* s) | |
218 { | |
219 assert(false); | |
220 } | |
221 | |
222 void prependBytes(const(char)* s) | |
223 { | |
224 assert(false); | |
225 } | |
226 | |
227 void bracket(char c1, char c2) | |
228 { | |
229 assert(false); | |
230 } | |
231 | |
232 /** | |
233 * Returns the number of bytes written. | |
234 */ | |
235 int size() | |
236 { | |
237 return p - buf; | |
238 } | |
239 | |
240 char* toString() | |
241 { | |
242 assert(false); | |
243 } | |
244 | |
245 void setsize(uint size) | |
246 { | |
247 assert(false); | |
248 } | |
249 | |
250 void writesLEB128(long value) | |
251 { | |
252 assert(false); | |
253 } | |
254 | |
255 void writeuLEB128(uint value) | |
256 { | |
257 assert(false); | |
258 } | |
259 } | |
260 | |
261 static this() | |
262 { | |
263 obj_symbols_towrite = new Array(); | |
264 } | |
265 | |
266 /************************************** | |
267 * Append s to list of object files to generate later. | |
268 */ | |
269 | |
270 void obj_append(Dsymbol s) | |
271 { | |
272 obj_symbols_towrite.push(cast(void*)s); | |
273 } | |
274 | |
14
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
275 version (Bug4059) |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
276 { |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
277 private extern (C) void _Z8obj_initP9OutbufferPKcS2_(Outbuffer* objbuf, const(char)* filename, const(char)* csegname); |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
278 void obj_init(Outbuffer* objbuf, const(char)* filename, const(char)* csegname) { return _Z8obj_initP9OutbufferPKcS2_(objbuf, filename, csegname); } |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
279 } |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
280 else |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
281 { |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
282 void obj_init(Outbuffer* objbuf, const(char)* filename, const(char)* csegname); |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
283 } |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
284 |
0 | 285 extern (C++) { |
286 void backend_init(); | |
287 void backend_term(); | |
288 void obj_term(); | |
289 void rtlsym_reset(); | |
290 void slist_reset(); | |
291 void el_reset(); | |
292 void cg87_reset(); | |
293 void out_reset(); | |
294 } | |
295 | |
296 void clearStringTab() | |
297 { | |
298 //printf("clearStringTab()\n"); | |
299 memset(stringTab.ptr, 0, stringTab.sizeof); | |
300 stidx = 0; | |
301 | |
302 assertexp_sfilename = null; | |
303 assertexp_name = null; | |
304 assertexp_mn = null; | |
305 } | |
306 | |
307 void obj_start(char *srcfile) | |
308 { | |
309 //printf("obj_start()\n"); | |
310 | |
311 out_config_init(); | |
312 | |
313 rtlsym_reset(); | |
314 slist_reset(); | |
315 clearStringTab(); | |
316 | |
317 obj_init(&objbuf, srcfile, null); | |
318 | |
319 el_reset(); | |
320 cg87_reset(); | |
321 out_reset(); | |
322 } | |
323 | |
324 void obj_end(Library library, File objfile) | |
325 { | |
326 obj_term(); | |
327 | |
328 if (library) | |
329 { | |
330 // Transfer image to library | |
331 library.addObject(objfile.name.toChars(), objbuf.buf, objbuf.p - objbuf.buf); | |
332 objbuf.buf = null; | |
333 } | |
334 else | |
335 { | |
336 // Transfer image to file | |
337 objfile.setbuffer(objbuf.buf, objbuf.p - objbuf.buf); | |
338 objbuf.buf = null; | |
339 | |
340 string p = FileName.path(objfile.name.toChars()); | |
341 FileName.ensurePathExists(p); | |
342 //mem.free(p); | |
343 | |
344 //printf("write obj %s\n", objfile.name.toChars()); | |
345 objfile.writev(); | |
346 } | |
347 | |
348 objbuf.pend = null; | |
349 objbuf.p = null; | |
350 objbuf.len = 0; | |
351 objbuf.inc = 0; | |
352 } | |
353 | |
354 void obj_write_deferred(Library library) | |
355 { | |
356 for (int i = 0; i < obj_symbols_towrite.dim; i++) | |
357 { | |
358 Dsymbol s = cast(Dsymbol)obj_symbols_towrite.data[i]; | |
359 Module m = s.getModule(); | |
360 | |
361 string mname; | |
362 if (m) | |
363 { | |
364 mname = m.srcfile.toChars(); | |
365 lastmname = mname; | |
366 } | |
367 else | |
368 { | |
369 //mname = s->ident->toChars(); | |
370 mname = lastmname; | |
371 assert(mname.length != 0); | |
372 } | |
373 | |
374 obj_start(cast(char*)toStringz(mname)); | |
375 | |
376 static int count; | |
377 count++; // sequence for generating names | |
378 | |
379 /* Create a module that's a doppelganger of m, with just | |
380 * enough to be able to create the moduleinfo. | |
381 */ | |
382 OutBuffer idbuf = new OutBuffer(); | |
383 idbuf.printf("%s.%d", m ? m.ident.toChars() : mname, count); | |
384 string idstr = idbuf.extractString(); | |
385 idbuf.data = null; | |
386 Identifier id = new Identifier(idstr, TOK.TOKidentifier); | |
387 | |
388 Module md = new Module(mname, id, 0, 0); | |
389 md.members = new Array(); | |
390 md.members.push(cast(void*)s); // its only 'member' is s | |
391 if (m) | |
392 { | |
393 md.doppelganger = 1; // identify this module as doppelganger | |
394 md.md = m.md; | |
395 md.aimports.push(cast(void*)m); // it only 'imports' m | |
396 md.massert = m.massert; | |
397 md.marray = m.marray; | |
398 } | |
399 | |
400 md.genobjfile(0); | |
401 | |
402 /* Set object file name to be source name with sequence number, | |
403 * as mangled symbol names get way too long. | |
404 */ | |
405 string fname = FileName.removeExt(mname); | |
406 | |
407 OutBuffer namebuf = new OutBuffer(); | |
408 uint hash = 0; | |
409 foreach (char c; s.toChars()) | |
410 hash += c; | |
411 | |
412 namebuf.printf("%s_%x_%x.%s", fname, count, hash, global.obj_ext); | |
413 fname = namebuf.extractString(); | |
414 | |
415 //printf("writing '%s'\n", fname); | |
416 File objfile = new File(fname); | |
417 obj_end(library, objfile); | |
418 } | |
419 | |
420 obj_symbols_towrite.dim = 0; | |
421 } | |
422 | |
423 /************************************** | |
424 * Initialize config variables. | |
425 */ | |
426 | |
427 void out_config_init() | |
428 { | |
429 Param* params = &global.params; | |
430 | |
431 if (!config.target_cpu) | |
432 { | |
433 config.target_cpu = TARGET_PentiumPro; | |
434 config.target_scheduler = config.target_cpu; | |
435 } | |
436 config.fulltypes = CVNONE; | |
437 config.inline8087 = 1; | |
438 config.memmodel = 0; | |
439 config.flags |= CFGuchar; // make sure TYchar is unsigned | |
440 version (TARGET_WINDOS) { | |
441 if (params.isX86_64) | |
442 config.exe = EX_WIN64; | |
443 else | |
444 config.exe = EX_NT; | |
445 | |
446 // Win32 eh | |
447 config.flags2 |= CFG2seh; | |
448 | |
449 if (params.run) | |
450 config.wflags |= WFexe; // EXE file only optimizations | |
451 else if (params.link && !global.params.deffile) | |
452 config.wflags |= WFexe; // EXE file only optimizations | |
453 else if (params.exefile) // if writing out EXE file | |
454 { | |
455 size_t len = params.exefile.length; | |
456 if (len >= 4 && icmp(params.exefile[len-3..len], "exe") == 0) | |
457 config.wflags |= WFexe; | |
458 } | |
459 config.flags4 |= CFG4underscore; | |
460 } | |
461 version (TARGET_LINUX) { | |
462 if (params.isX86_64) | |
463 config.exe = EX_LINUX64; | |
464 else | |
465 config.exe = EX_LINUX; | |
466 config.flags |= CFGnoebp; | |
467 config.flags |= CFGalwaysframe; | |
468 if (params.pic) | |
469 config.flags3 |= CFG3pic; | |
470 } | |
471 version (TARGET_OSX) { | |
472 if (params.isX86_64) | |
473 config.exe = EX_OSX64; | |
474 else | |
475 config.exe = EX_OSX; | |
476 config.flags |= CFGnoebp; | |
477 config.flags |= CFGalwaysframe; | |
478 if (params.pic) | |
479 config.flags3 |= CFG3pic; | |
480 } | |
481 version (TARGET_FREEBSD) { | |
482 if (params.isX86_64) | |
483 config.exe = EX_FREEBSD64; | |
484 else | |
485 config.exe = EX_FREEBSD; | |
486 config.flags |= CFGnoebp; | |
487 config.flags |= CFGalwaysframe; | |
488 if (params.pic) | |
489 config.flags3 |= CFG3pic; | |
490 } | |
491 version (TARGET_SOLARIS) { | |
492 if (params.isX86_64) | |
493 config.exe = EX_SOLARIS64; | |
494 else | |
495 config.exe = EX_SOLARIS; | |
496 config.flags |= CFGnoebp; | |
497 config.flags |= CFGalwaysframe; | |
498 if (params.pic) | |
499 config.flags3 |= CFG3pic; | |
500 } | |
501 config.flags2 |= CFG2nodeflib; // no default library | |
502 config.flags3 |= CFG3eseqds; | |
503 static if (false) { | |
504 if (env.getEEcontext().EEcompile != 2) | |
505 config.flags4 |= CFG4allcomdat; | |
506 if (env.nochecks()) | |
507 config.flags4 |= CFG4nochecks; // no runtime checking | |
508 } else version (TARGET_OSX) { | |
509 } else { | |
510 config.flags4 |= CFG4allcomdat; | |
511 } | |
512 if (params.trace) | |
513 config.flags |= CFGtrace; // turn on profiler | |
514 if (params.nofloat) | |
515 config.flags3 |= CFG3wkfloat; | |
516 | |
517 configv.verbose = params.verbose; | |
518 | |
519 if (params.optimize) | |
520 go_flag(cast(char*)"-o".ptr); | |
521 | |
522 if (params.symdebug) | |
523 { | |
524 version (ELFOBJ_OR_MACHOBJ) { | |
525 configv.addlinenumbers = 1; | |
526 config.fulltypes = (params.symdebug == 1) ? CVDWARF_D : CVDWARF_C; | |
527 } | |
528 version (OMFOBJ) { | |
529 configv.addlinenumbers = 1; | |
530 config.fulltypes = CV4; | |
531 } | |
532 if (!params.optimize) | |
533 config.flags |= CFGalwaysframe; | |
534 } | |
535 else | |
536 { | |
537 configv.addlinenumbers = 0; | |
538 config.fulltypes = CVNONE; | |
539 //config.flags &= ~CFGalwaysframe; | |
540 } | |
541 | |
542 if (params.isX86_64) | |
543 { | |
544 util_set64(); | |
545 cod3_set64(); | |
546 } | |
547 else | |
548 { | |
549 util_set386(); | |
550 cod3_set386(); | |
551 } | |
552 | |
553 debug { | |
554 debugb = params.debugb; | |
555 debugc = params.debugc; | |
556 debugf = params.debugf; | |
557 debugr = params.debugr; | |
558 debugw = params.debugw; | |
559 debugx = params.debugx; | |
560 debugy = params.debugy; | |
561 } | |
14
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
562 } |