| // Copyright 2009 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| #include "go.h" |
| |
| /* |
| * architecture-independent object file output |
| */ |
| |
| void |
| dumpobj(void) |
| { |
| bout = Bopen(outfile, OWRITE); |
| if(bout == nil) |
| fatal("cant open %s", outfile); |
| |
| Bprint(bout, "%s\n", thestring); |
| Bprint(bout, " exports automatically generated from\n"); |
| Bprint(bout, " %s in package \"%s\"\n", curio.infile, package); |
| dumpexport(); |
| Bprint(bout, "\n!\n"); |
| |
| outhist(bout); |
| |
| // add nil plist w AEND to catch |
| // auto-generated trampolines, data |
| newplist(); |
| |
| dumpglobls(); |
| dumptypestructs(); |
| dumpdata(); |
| dumpfuncs(); |
| |
| Bterm(bout); |
| } |
| |
| void |
| dumpglobls(void) |
| { |
| Node *n; |
| NodeList *l; |
| |
| // add globals |
| for(l=externdcl; l; l=l->next) { |
| n = l->n; |
| if(n->op != ONAME) |
| continue; |
| |
| if(n->type == T) |
| fatal("external %#N nil type\n", n); |
| if(n->class == PFUNC) |
| continue; |
| if(n->sym->package != package) |
| continue; |
| dowidth(n->type); |
| |
| // TODO(rsc): why is this not s/n->sym->def/n/ ? |
| ggloblnod(n->sym->def, n->type->width); |
| } |
| } |
| |
| void |
| Bputdot(Biobuf *b) |
| { |
| // put out middle dot ยท |
| Bputc(b, 0xc2); |
| Bputc(b, 0xb7); |
| } |
| |
| void |
| outhist(Biobuf *b) |
| { |
| Hist *h; |
| char *p, *q, *op; |
| int n; |
| |
| for(h = hist; h != H; h = h->link) { |
| p = h->name; |
| op = 0; |
| |
| if(p && p[0] != '/' && h->offset == 0 && pathname && pathname[0] == '/') { |
| op = p; |
| p = pathname; |
| } |
| |
| while(p) { |
| q = utfrune(p, '/'); |
| if(q) { |
| n = q-p; |
| if(n == 0) |
| n = 1; // leading "/" |
| q++; |
| } else { |
| n = strlen(p); |
| q = 0; |
| } |
| if(n) |
| zfile(b, p, n); |
| p = q; |
| if(p == 0 && op) { |
| p = op; |
| op = 0; |
| } |
| } |
| |
| zhist(b, h->line, h->offset); |
| } |
| } |
| |
| void |
| ieeedtod(uint64 *ieee, double native) |
| { |
| double fr, ho, f; |
| int exp; |
| uint32 h, l; |
| |
| if(native < 0) { |
| ieeedtod(ieee, -native); |
| *ieee |= 1ULL<<63; |
| return; |
| } |
| if(native == 0) { |
| *ieee = 0; |
| return; |
| } |
| fr = frexp(native, &exp); |
| f = 2097152L; /* shouldnt use fp constants here */ |
| fr = modf(fr*f, &ho); |
| h = ho; |
| h &= 0xfffffL; |
| h |= (exp+1022L) << 20; |
| f = 65536L; |
| fr = modf(fr*f, &ho); |
| l = ho; |
| l <<= 16; |
| l |= (int32)(fr*f); |
| *ieee = ((uint64)h << 32) | l; |
| } |
| |
| int |
| duint8(Sym *s, int off, uint8 v) |
| { |
| return duintxx(s, off, v, 1); |
| } |
| |
| int |
| duint16(Sym *s, int off, uint16 v) |
| { |
| return duintxx(s, off, v, 2); |
| } |
| |
| int |
| duint32(Sym *s, int off, uint32 v) |
| { |
| return duintxx(s, off, v, 4); |
| } |
| |
| int |
| duint64(Sym *s, int off, uint64 v) |
| { |
| return duintxx(s, off, v, 8); |
| } |
| |
| int |
| duintptr(Sym *s, int off, uint64 v) |
| { |
| return duintxx(s, off, v, widthptr); |
| } |