mirror of
https://github.com/golang/go
synced 2024-10-03 23:31:22 -06:00
3f61184e1b
The object files begin with a header that is $GOARCH on a line by itself. This CL changes that header to go object $GOOS $GOARCH release.2011-01-01 4567+ where the final two fields are the most recent release tag and the current hg version number. All objects imported into a Go compilation or linked into an executable must have the same header line, and that header line must match the compiler and linker versions. The effect of this will be that if you update and run all.bash and then try to link in objects compiled with an earlier version of the compiler (or invoke the wrong version of the compiler), you will get an error showing the different headers instead of perhaps silent incompatibility. Normal usage with all.bash should be unaffected, because all.bash deletes all the object files in $GOROOT/pkg/$GOOS_$GOARCH and cleans all intermediate object files before starting. This change is intended to diagnose stale objects arising when users maintaining alternate installation directories forget to rebuild some of their files after updating. It should help make the adoption of $GOPATH (CL 3780043) less error-prone. R=ken2, r CC=golang-dev https://golang.org/cl/4023063
238 lines
4.4 KiB
C
238 lines
4.4 KiB
C
// 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
|
|
*/
|
|
|
|
static void outhist(Biobuf *b);
|
|
static void dumpglobls(void);
|
|
|
|
void
|
|
dumpobj(void)
|
|
{
|
|
bout = Bopen(outfile, OWRITE);
|
|
if(bout == nil) {
|
|
flusherrors();
|
|
print("can't create %s: %r\n", outfile);
|
|
errorexit();
|
|
}
|
|
|
|
Bprint(bout, "go object %s %s %s\n", getgoos(), thestring, getgoversion());
|
|
Bprint(bout, " exports automatically generated from\n");
|
|
Bprint(bout, " %s in package \"%s\"\n", curio.infile, localpkg->name);
|
|
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);
|
|
}
|
|
|
|
static 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->pkg != localpkg)
|
|
continue;
|
|
dowidth(n->type);
|
|
|
|
ggloblnod(n, n->type->width);
|
|
}
|
|
}
|
|
|
|
void
|
|
Bputname(Biobuf *b, Sym *s)
|
|
{
|
|
Bprint(b, "%s", s->pkg->prefix);
|
|
Bputc(b, '.');
|
|
Bwrite(b, s->name, strlen(s->name)+1);
|
|
}
|
|
|
|
static void
|
|
outzfile(Biobuf *b, char *p)
|
|
{
|
|
char *q, *q2;
|
|
|
|
while(p) {
|
|
q = utfrune(p, '/');
|
|
if(windows) {
|
|
q2 = utfrune(p, '\\');
|
|
if(q2 && (!q || q2 < q))
|
|
q = q2;
|
|
}
|
|
if(!q) {
|
|
zfile(b, p, strlen(p));
|
|
return;
|
|
}
|
|
if(q > p)
|
|
zfile(b, p, q-p);
|
|
p = q + 1;
|
|
}
|
|
}
|
|
|
|
#define isdelim(c) (c == '/' || c == '\\')
|
|
|
|
static void
|
|
outwinname(Biobuf *b, Hist *h, char *ds, char *p)
|
|
{
|
|
if(isdelim(p[0])) {
|
|
// full rooted name
|
|
zfile(b, ds, 3); // leading "c:/"
|
|
outzfile(b, p+1);
|
|
} else {
|
|
// relative name
|
|
if(h->offset == 0 && pathname && pathname[1] == ':') {
|
|
if(tolowerrune(ds[0]) == tolowerrune(pathname[0])) {
|
|
// using current drive
|
|
zfile(b, pathname, 3); // leading "c:/"
|
|
outzfile(b, pathname+3);
|
|
} else {
|
|
// using drive other then current,
|
|
// we don't have any simple way to
|
|
// determine current working directory
|
|
// there, therefore will output name as is
|
|
zfile(b, ds, 2); // leading "c:"
|
|
}
|
|
}
|
|
outzfile(b, p);
|
|
}
|
|
}
|
|
|
|
static void
|
|
outhist(Biobuf *b)
|
|
{
|
|
Hist *h;
|
|
char *p, ds[] = {'c', ':', '/', 0};
|
|
|
|
for(h = hist; h != H; h = h->link) {
|
|
p = h->name;
|
|
if(p) {
|
|
if(windows) {
|
|
// if windows variable is set, then, we know already,
|
|
// pathname is started with windows drive specifier
|
|
// and all '\' were replaced with '/' (see lex.c)
|
|
if(isdelim(p[0]) && isdelim(p[1])) {
|
|
// file name has network name in it,
|
|
// like \\server\share\dir\file.go
|
|
zfile(b, "//", 2); // leading "//"
|
|
outzfile(b, p+2);
|
|
} else if(p[1] == ':') {
|
|
// file name has drive letter in it
|
|
ds[0] = p[0];
|
|
outwinname(b, h, ds, p+2);
|
|
} else {
|
|
// no drive letter in file name
|
|
outwinname(b, h, pathname, p);
|
|
}
|
|
} else {
|
|
if(p[0] == '/') {
|
|
// full rooted name, like /home/rsc/dir/file.go
|
|
zfile(b, "/", 1); // leading "/"
|
|
outzfile(b, p+1);
|
|
} else {
|
|
// relative name, like dir/file.go
|
|
if(h->offset == 0 && pathname && pathname[0] == '/') {
|
|
zfile(b, "/", 1); // leading "/"
|
|
outzfile(b, pathname+1);
|
|
}
|
|
outzfile(b, p);
|
|
}
|
|
}
|
|
}
|
|
zhist(b, h->line, h->offset);
|
|
}
|
|
}
|
|
|
|
void
|
|
ieeedtod(uint64 *ieee, double native)
|
|
{
|
|
double fr, ho, f;
|
|
int exp;
|
|
uint32 h, l;
|
|
uint64 bits;
|
|
|
|
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;
|
|
f = 65536L;
|
|
fr = modf(fr*f, &ho);
|
|
l = ho;
|
|
l <<= 16;
|
|
l |= (int32)(fr*f);
|
|
bits = ((uint64)h<<32) | l;
|
|
if(exp < -1021) {
|
|
// gradual underflow
|
|
bits |= 1LL<<52;
|
|
bits >>= -1021 - exp;
|
|
exp = -1022;
|
|
}
|
|
bits |= (uint64)(exp+1022L) << 52;
|
|
*ieee = bits;
|
|
}
|
|
|
|
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);
|
|
}
|