2012-02-03 18:16:42 -05:00
|
|
|
// Copyright 2012 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 "a.h"
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Helpers for building pkg/runtime.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// mkzversion writes zversion.go:
|
|
|
|
|
//
|
|
|
|
|
// package runtime
|
|
|
|
|
// const defaultGoroot = <goroot>
|
|
|
|
|
// const theVersion = <version>
|
|
|
|
|
//
|
|
|
|
|
void
|
|
|
|
|
mkzversion(char *dir, char *file)
|
|
|
|
|
{
|
|
|
|
|
Buf b, out;
|
|
|
|
|
|
2012-05-01 22:32:46 -07:00
|
|
|
USED(dir);
|
|
|
|
|
|
2012-02-03 18:16:42 -05:00
|
|
|
binit(&b);
|
|
|
|
|
binit(&out);
|
|
|
|
|
|
|
|
|
|
bwritestr(&out, bprintf(&b,
|
|
|
|
|
"// auto generated by go tool dist\n"
|
|
|
|
|
"\n"
|
|
|
|
|
"package runtime\n"
|
|
|
|
|
"\n"
|
|
|
|
|
"const defaultGoroot = `%s`\n"
|
2012-02-09 20:47:12 -02:00
|
|
|
"const theVersion = `%s`\n", goroot_final, goversion));
|
2012-02-03 18:16:42 -05:00
|
|
|
|
2012-02-21 16:49:30 -05:00
|
|
|
writefile(&out, file, 0);
|
2012-02-03 18:16:42 -05:00
|
|
|
|
|
|
|
|
bfree(&b);
|
|
|
|
|
bfree(&out);
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-16 20:26:10 -04:00
|
|
|
// mkzexperiment writes zaexperiment.h (sic):
|
|
|
|
|
//
|
|
|
|
|
// #define GOEXPERIMENT "experiment string"
|
|
|
|
|
//
|
|
|
|
|
void
|
|
|
|
|
mkzexperiment(char *dir, char *file)
|
|
|
|
|
{
|
|
|
|
|
Buf b, out, exp;
|
|
|
|
|
|
|
|
|
|
USED(dir);
|
|
|
|
|
|
|
|
|
|
binit(&b);
|
|
|
|
|
binit(&out);
|
|
|
|
|
binit(&exp);
|
|
|
|
|
|
|
|
|
|
xgetenv(&exp, "GOEXPERIMENT");
|
|
|
|
|
bwritestr(&out, bprintf(&b,
|
|
|
|
|
"// auto generated by go tool dist\n"
|
|
|
|
|
"\n"
|
|
|
|
|
"#define GOEXPERIMENT \"%s\"\n", bstr(&exp)));
|
|
|
|
|
|
|
|
|
|
writefile(&out, file, 0);
|
|
|
|
|
|
|
|
|
|
bfree(&b);
|
|
|
|
|
bfree(&out);
|
|
|
|
|
bfree(&exp);
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-03 18:16:42 -05:00
|
|
|
// mkzgoarch writes zgoarch_$GOARCH.go:
|
|
|
|
|
//
|
|
|
|
|
// package runtime
|
|
|
|
|
// const theGoarch = <goarch>
|
|
|
|
|
//
|
|
|
|
|
void
|
|
|
|
|
mkzgoarch(char *dir, char *file)
|
|
|
|
|
{
|
|
|
|
|
Buf b, out;
|
2012-05-01 22:32:46 -07:00
|
|
|
|
|
|
|
|
USED(dir);
|
2012-02-03 18:16:42 -05:00
|
|
|
|
|
|
|
|
binit(&b);
|
|
|
|
|
binit(&out);
|
|
|
|
|
|
|
|
|
|
bwritestr(&out, bprintf(&b,
|
|
|
|
|
"// auto generated by go tool dist\n"
|
|
|
|
|
"\n"
|
|
|
|
|
"package runtime\n"
|
|
|
|
|
"\n"
|
|
|
|
|
"const theGoarch = `%s`\n", goarch));
|
|
|
|
|
|
2012-02-21 16:49:30 -05:00
|
|
|
writefile(&out, file, 0);
|
2012-02-03 18:16:42 -05:00
|
|
|
|
|
|
|
|
bfree(&b);
|
|
|
|
|
bfree(&out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// mkzgoos writes zgoos_$GOOS.go:
|
|
|
|
|
//
|
|
|
|
|
// package runtime
|
|
|
|
|
// const theGoos = <goos>
|
|
|
|
|
//
|
|
|
|
|
void
|
|
|
|
|
mkzgoos(char *dir, char *file)
|
|
|
|
|
{
|
|
|
|
|
Buf b, out;
|
2012-05-01 22:32:46 -07:00
|
|
|
|
|
|
|
|
USED(dir);
|
2012-02-03 18:16:42 -05:00
|
|
|
|
|
|
|
|
binit(&b);
|
|
|
|
|
binit(&out);
|
all: add GOOS=android
As android and linux have significant overlap, and
because build tags are a poor way to represent an
OS target, this CL introduces an exception into
go/build: linux is treated as a synonym for android
when matching files.
http://golang.org/s/go14android
https://groups.google.com/forum/#!topic/golang-dev/P1ATVp1mun0
LGTM=rsc, minux
R=golang-codereviews, mikioh.mikioh, dave, aram, minux, gobot, rsc, aram.h, elias.naur, iant
CC=golang-codereviews, rsc
https://golang.org/cl/105270043
2014-07-01 17:21:50 -04:00
|
|
|
|
|
|
|
|
bwritestr(&out, "// auto generated by go tool dist\n\n");
|
|
|
|
|
|
|
|
|
|
if (streq(goos, "linux")) {
|
|
|
|
|
bwritestr(&out, "// +build !android\n\n");
|
|
|
|
|
}
|
2012-02-03 18:16:42 -05:00
|
|
|
|
|
|
|
|
bwritestr(&out, bprintf(&b,
|
|
|
|
|
"package runtime\n"
|
|
|
|
|
"\n"
|
|
|
|
|
"const theGoos = `%s`\n", goos));
|
|
|
|
|
|
2012-02-21 16:49:30 -05:00
|
|
|
writefile(&out, file, 0);
|
2012-02-03 18:16:42 -05:00
|
|
|
|
|
|
|
|
bfree(&b);
|
|
|
|
|
bfree(&out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct {
|
|
|
|
|
char *goarch;
|
|
|
|
|
char *goos;
|
|
|
|
|
char *hdr;
|
|
|
|
|
} zasmhdr[] = {
|
|
|
|
|
{"386", "",
|
liblink: introduce TLS register on 386 and amd64
When I did the original 386 ports on Linux and OS X, I chose to
define GS-relative expressions like 4(GS) as relative to the actual
thread-local storage base, which was usually GS but might not be
(it might be FS, or it might be a different constant offset from GS or FS).
The original scope was limited but since then the rewrites have
gotten out of control. Sometimes GS is rewritten, sometimes FS.
Some ports do other rewrites to enable shared libraries and
other linking. At no point in the code is it clear whether you are
looking at the real GS/FS or some synthesized thing that will be
rewritten. The code manipulating all these is duplicated in many
places.
The first step to fixing issue 7719 is to make the code intelligible
again.
This CL adds an explicit TLS pseudo-register to the 386 and amd64.
As a register, TLS refers to the thread-local storage base, and it
can only be loaded into another register:
MOVQ TLS, AX
An offset from the thread-local storage base is written off(reg)(TLS*1).
Semantically it is off(reg), but the (TLS*1) annotation marks this as
indexing from the loaded TLS base. This emits a relocation so that
if the linker needs to adjust the offset, it can. For example:
MOVQ TLS, AX
MOVQ 8(AX)(TLS*1), CX // load m into CX
On systems that support direct access to the TLS memory, this
pair of instructions can be reduced to a direct TLS memory reference:
MOVQ 8(TLS), CX // load m into CX
The 2-instruction and 1-instruction forms correspond roughly to
ELF TLS initial exec mode and ELF TLS local exec mode, respectively.
Liblink applies this rewrite on systems that support the 1-instruction form.
The decision is made using only the operating system (and probably
the -shared flag, eventually), not the link mode. If some link modes
on a particular operating system require the 2-instruction form,
then all builds for that operating system will use the 2-instruction
form, so that the link mode decision can be delayed to link time.
Obviously it is late to be making changes like this, but I despair
of correcting issue 7719 and issue 7164 without it. To make sure
I am not changing existing behavior, I built a "hello world" program
for every GOOS/GOARCH combination we have and then worked
to make sure that the rewrite generates exactly the same binaries,
byte for byte. There are a handful of TODOs in the code marking
kludges to get the byte-for-byte property, but at least now I can
explain exactly how each binary is handled.
The targets I tested this way are:
darwin-386
darwin-amd64
dragonfly-386
dragonfly-amd64
freebsd-386
freebsd-amd64
freebsd-arm
linux-386
linux-amd64
linux-arm
nacl-386
nacl-amd64p32
netbsd-386
netbsd-amd64
openbsd-386
openbsd-amd64
plan9-386
plan9-amd64
solaris-amd64
windows-386
windows-amd64
There were four exceptions to the byte-for-byte goal:
windows-386 and windows-amd64 have a time stamp
at bytes 137 and 138 of the header.
darwin-386 and plan9-386 have five or six modified
bytes in the middle of the Go symbol table, caused by
editing comments in runtime/sys_{darwin,plan9}_386.s.
Fixes #7164.
LGTM=iant
R=iant, aram, minux.ma, dave
CC=golang-codereviews
https://golang.org/cl/87920043
2014-04-15 13:45:39 -04:00
|
|
|
"#define get_tls(r) MOVL TLS, r\n"
|
|
|
|
|
"#define g(r) 0(r)(TLS*1)\n"
|
2012-09-24 12:24:45 -04:00
|
|
|
},
|
liblink: introduce TLS register on 386 and amd64
When I did the original 386 ports on Linux and OS X, I chose to
define GS-relative expressions like 4(GS) as relative to the actual
thread-local storage base, which was usually GS but might not be
(it might be FS, or it might be a different constant offset from GS or FS).
The original scope was limited but since then the rewrites have
gotten out of control. Sometimes GS is rewritten, sometimes FS.
Some ports do other rewrites to enable shared libraries and
other linking. At no point in the code is it clear whether you are
looking at the real GS/FS or some synthesized thing that will be
rewritten. The code manipulating all these is duplicated in many
places.
The first step to fixing issue 7719 is to make the code intelligible
again.
This CL adds an explicit TLS pseudo-register to the 386 and amd64.
As a register, TLS refers to the thread-local storage base, and it
can only be loaded into another register:
MOVQ TLS, AX
An offset from the thread-local storage base is written off(reg)(TLS*1).
Semantically it is off(reg), but the (TLS*1) annotation marks this as
indexing from the loaded TLS base. This emits a relocation so that
if the linker needs to adjust the offset, it can. For example:
MOVQ TLS, AX
MOVQ 8(AX)(TLS*1), CX // load m into CX
On systems that support direct access to the TLS memory, this
pair of instructions can be reduced to a direct TLS memory reference:
MOVQ 8(TLS), CX // load m into CX
The 2-instruction and 1-instruction forms correspond roughly to
ELF TLS initial exec mode and ELF TLS local exec mode, respectively.
Liblink applies this rewrite on systems that support the 1-instruction form.
The decision is made using only the operating system (and probably
the -shared flag, eventually), not the link mode. If some link modes
on a particular operating system require the 2-instruction form,
then all builds for that operating system will use the 2-instruction
form, so that the link mode decision can be delayed to link time.
Obviously it is late to be making changes like this, but I despair
of correcting issue 7719 and issue 7164 without it. To make sure
I am not changing existing behavior, I built a "hello world" program
for every GOOS/GOARCH combination we have and then worked
to make sure that the rewrite generates exactly the same binaries,
byte for byte. There are a handful of TODOs in the code marking
kludges to get the byte-for-byte property, but at least now I can
explain exactly how each binary is handled.
The targets I tested this way are:
darwin-386
darwin-amd64
dragonfly-386
dragonfly-amd64
freebsd-386
freebsd-amd64
freebsd-arm
linux-386
linux-amd64
linux-arm
nacl-386
nacl-amd64p32
netbsd-386
netbsd-amd64
openbsd-386
openbsd-amd64
plan9-386
plan9-amd64
solaris-amd64
windows-386
windows-amd64
There were four exceptions to the byte-for-byte goal:
windows-386 and windows-amd64 have a time stamp
at bytes 137 and 138 of the header.
darwin-386 and plan9-386 have five or six modified
bytes in the middle of the Go symbol table, caused by
editing comments in runtime/sys_{darwin,plan9}_386.s.
Fixes #7164.
LGTM=iant
R=iant, aram, minux.ma, dave
CC=golang-codereviews
https://golang.org/cl/87920043
2014-04-15 13:45:39 -04:00
|
|
|
{"amd64p32", "",
|
|
|
|
|
"#define get_tls(r) MOVL TLS, r\n"
|
|
|
|
|
"#define g(r) 0(r)(TLS*1)\n"
|
2012-02-03 18:16:42 -05:00
|
|
|
},
|
2013-08-14 12:57:05 -04:00
|
|
|
{"amd64", "",
|
liblink: introduce TLS register on 386 and amd64
When I did the original 386 ports on Linux and OS X, I chose to
define GS-relative expressions like 4(GS) as relative to the actual
thread-local storage base, which was usually GS but might not be
(it might be FS, or it might be a different constant offset from GS or FS).
The original scope was limited but since then the rewrites have
gotten out of control. Sometimes GS is rewritten, sometimes FS.
Some ports do other rewrites to enable shared libraries and
other linking. At no point in the code is it clear whether you are
looking at the real GS/FS or some synthesized thing that will be
rewritten. The code manipulating all these is duplicated in many
places.
The first step to fixing issue 7719 is to make the code intelligible
again.
This CL adds an explicit TLS pseudo-register to the 386 and amd64.
As a register, TLS refers to the thread-local storage base, and it
can only be loaded into another register:
MOVQ TLS, AX
An offset from the thread-local storage base is written off(reg)(TLS*1).
Semantically it is off(reg), but the (TLS*1) annotation marks this as
indexing from the loaded TLS base. This emits a relocation so that
if the linker needs to adjust the offset, it can. For example:
MOVQ TLS, AX
MOVQ 8(AX)(TLS*1), CX // load m into CX
On systems that support direct access to the TLS memory, this
pair of instructions can be reduced to a direct TLS memory reference:
MOVQ 8(TLS), CX // load m into CX
The 2-instruction and 1-instruction forms correspond roughly to
ELF TLS initial exec mode and ELF TLS local exec mode, respectively.
Liblink applies this rewrite on systems that support the 1-instruction form.
The decision is made using only the operating system (and probably
the -shared flag, eventually), not the link mode. If some link modes
on a particular operating system require the 2-instruction form,
then all builds for that operating system will use the 2-instruction
form, so that the link mode decision can be delayed to link time.
Obviously it is late to be making changes like this, but I despair
of correcting issue 7719 and issue 7164 without it. To make sure
I am not changing existing behavior, I built a "hello world" program
for every GOOS/GOARCH combination we have and then worked
to make sure that the rewrite generates exactly the same binaries,
byte for byte. There are a handful of TODOs in the code marking
kludges to get the byte-for-byte property, but at least now I can
explain exactly how each binary is handled.
The targets I tested this way are:
darwin-386
darwin-amd64
dragonfly-386
dragonfly-amd64
freebsd-386
freebsd-amd64
freebsd-arm
linux-386
linux-amd64
linux-arm
nacl-386
nacl-amd64p32
netbsd-386
netbsd-amd64
openbsd-386
openbsd-amd64
plan9-386
plan9-amd64
solaris-amd64
windows-386
windows-amd64
There were four exceptions to the byte-for-byte goal:
windows-386 and windows-amd64 have a time stamp
at bytes 137 and 138 of the header.
darwin-386 and plan9-386 have five or six modified
bytes in the middle of the Go symbol table, caused by
editing comments in runtime/sys_{darwin,plan9}_386.s.
Fixes #7164.
LGTM=iant
R=iant, aram, minux.ma, dave
CC=golang-codereviews
https://golang.org/cl/87920043
2014-04-15 13:45:39 -04:00
|
|
|
"#define get_tls(r) MOVQ TLS, r\n"
|
|
|
|
|
"#define g(r) 0(r)(TLS*1)\n"
|
2013-08-14 12:57:05 -04:00
|
|
|
},
|
liblink: introduce TLS register on 386 and amd64
When I did the original 386 ports on Linux and OS X, I chose to
define GS-relative expressions like 4(GS) as relative to the actual
thread-local storage base, which was usually GS but might not be
(it might be FS, or it might be a different constant offset from GS or FS).
The original scope was limited but since then the rewrites have
gotten out of control. Sometimes GS is rewritten, sometimes FS.
Some ports do other rewrites to enable shared libraries and
other linking. At no point in the code is it clear whether you are
looking at the real GS/FS or some synthesized thing that will be
rewritten. The code manipulating all these is duplicated in many
places.
The first step to fixing issue 7719 is to make the code intelligible
again.
This CL adds an explicit TLS pseudo-register to the 386 and amd64.
As a register, TLS refers to the thread-local storage base, and it
can only be loaded into another register:
MOVQ TLS, AX
An offset from the thread-local storage base is written off(reg)(TLS*1).
Semantically it is off(reg), but the (TLS*1) annotation marks this as
indexing from the loaded TLS base. This emits a relocation so that
if the linker needs to adjust the offset, it can. For example:
MOVQ TLS, AX
MOVQ 8(AX)(TLS*1), CX // load m into CX
On systems that support direct access to the TLS memory, this
pair of instructions can be reduced to a direct TLS memory reference:
MOVQ 8(TLS), CX // load m into CX
The 2-instruction and 1-instruction forms correspond roughly to
ELF TLS initial exec mode and ELF TLS local exec mode, respectively.
Liblink applies this rewrite on systems that support the 1-instruction form.
The decision is made using only the operating system (and probably
the -shared flag, eventually), not the link mode. If some link modes
on a particular operating system require the 2-instruction form,
then all builds for that operating system will use the 2-instruction
form, so that the link mode decision can be delayed to link time.
Obviously it is late to be making changes like this, but I despair
of correcting issue 7719 and issue 7164 without it. To make sure
I am not changing existing behavior, I built a "hello world" program
for every GOOS/GOARCH combination we have and then worked
to make sure that the rewrite generates exactly the same binaries,
byte for byte. There are a handful of TODOs in the code marking
kludges to get the byte-for-byte property, but at least now I can
explain exactly how each binary is handled.
The targets I tested this way are:
darwin-386
darwin-amd64
dragonfly-386
dragonfly-amd64
freebsd-386
freebsd-amd64
freebsd-arm
linux-386
linux-amd64
linux-arm
nacl-386
nacl-amd64p32
netbsd-386
netbsd-amd64
openbsd-386
openbsd-amd64
plan9-386
plan9-amd64
solaris-amd64
windows-386
windows-amd64
There were four exceptions to the byte-for-byte goal:
windows-386 and windows-amd64 have a time stamp
at bytes 137 and 138 of the header.
darwin-386 and plan9-386 have five or six modified
bytes in the middle of the Go symbol table, caused by
editing comments in runtime/sys_{darwin,plan9}_386.s.
Fixes #7164.
LGTM=iant
R=iant, aram, minux.ma, dave
CC=golang-codereviews
https://golang.org/cl/87920043
2014-04-15 13:45:39 -04:00
|
|
|
|
2012-02-03 18:16:42 -05:00
|
|
|
{"arm", "",
|
|
|
|
|
"#define LR R14\n"
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
2013-06-24 17:17:45 +10:00
|
|
|
#define MAXWINCB 2000 /* maximum number of windows callbacks allowed */
|
|
|
|
|
|
2012-02-03 18:16:42 -05:00
|
|
|
// mkzasm writes zasm_$GOOS_$GOARCH.h,
|
|
|
|
|
// which contains struct offsets for use by
|
|
|
|
|
// assembly files. It also writes a copy to the work space
|
|
|
|
|
// under the name zasm_GOOS_GOARCH.h (no expansion).
|
|
|
|
|
//
|
|
|
|
|
void
|
|
|
|
|
mkzasm(char *dir, char *file)
|
|
|
|
|
{
|
|
|
|
|
int i, n;
|
|
|
|
|
char *aggr, *p;
|
2013-09-16 20:26:10 -04:00
|
|
|
Buf in, b, out, exp;
|
2012-02-03 18:16:42 -05:00
|
|
|
Vec argv, lines, fields;
|
|
|
|
|
|
|
|
|
|
binit(&in);
|
|
|
|
|
binit(&b);
|
|
|
|
|
binit(&out);
|
2013-09-16 20:26:10 -04:00
|
|
|
binit(&exp);
|
2012-02-03 18:16:42 -05:00
|
|
|
vinit(&argv);
|
|
|
|
|
vinit(&lines);
|
|
|
|
|
vinit(&fields);
|
|
|
|
|
|
|
|
|
|
bwritestr(&out, "// auto generated by go tool dist\n\n");
|
|
|
|
|
for(i=0; i<nelem(zasmhdr); i++) {
|
|
|
|
|
if(hasprefix(goarch, zasmhdr[i].goarch) && hasprefix(goos, zasmhdr[i].goos)) {
|
|
|
|
|
bwritestr(&out, zasmhdr[i].hdr);
|
|
|
|
|
goto ok;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
fatal("unknown $GOOS/$GOARCH in mkzasm");
|
|
|
|
|
ok:
|
|
|
|
|
|
2013-01-31 22:02:20 -08:00
|
|
|
// Run 6c -D GOOS_goos -D GOARCH_goarch -I workdir -a -n -o workdir/proc.acid proc.c
|
2014-02-28 21:45:12 +11:00
|
|
|
// to get acid [sic] output. Run once without the -a -o workdir/proc.acid in order to
|
|
|
|
|
// report compilation failures (the -o redirects all messages, unfortunately).
|
2012-02-03 18:16:42 -05:00
|
|
|
vreset(&argv);
|
2012-02-13 22:31:51 -05:00
|
|
|
vadd(&argv, bpathf(&b, "%s/%sc", tooldir, gochar));
|
2013-01-02 17:52:54 -05:00
|
|
|
vadd(&argv, "-D");
|
|
|
|
|
vadd(&argv, bprintf(&b, "GOOS_%s", goos));
|
|
|
|
|
vadd(&argv, "-D");
|
|
|
|
|
vadd(&argv, bprintf(&b, "GOARCH_%s", goarch));
|
|
|
|
|
vadd(&argv, "-I");
|
|
|
|
|
vadd(&argv, bprintf(&b, "%s", workdir));
|
2013-01-31 22:02:20 -08:00
|
|
|
vadd(&argv, "-n");
|
2014-02-28 21:45:12 +11:00
|
|
|
vadd(&argv, "-a");
|
2013-01-31 22:02:20 -08:00
|
|
|
vadd(&argv, "-o");
|
|
|
|
|
vadd(&argv, bpathf(&b, "%s/proc.acid", workdir));
|
2012-02-03 18:16:42 -05:00
|
|
|
vadd(&argv, "proc.c");
|
2013-01-31 22:02:20 -08:00
|
|
|
runv(nil, dir, CheckExit, &argv);
|
|
|
|
|
readfile(&in, bpathf(&b, "%s/proc.acid", workdir));
|
2012-02-03 18:16:42 -05:00
|
|
|
|
|
|
|
|
// Convert input like
|
|
|
|
|
// aggr G
|
|
|
|
|
// {
|
|
|
|
|
// Gobuf 24 sched;
|
|
|
|
|
// 'Y' 48 stack0;
|
|
|
|
|
// }
|
2013-07-12 12:24:57 -07:00
|
|
|
// StackMin = 128;
|
2012-02-03 18:16:42 -05:00
|
|
|
// into output like
|
|
|
|
|
// #define g_sched 24
|
|
|
|
|
// #define g_stack0 48
|
2013-07-12 12:24:57 -07:00
|
|
|
// #define const_StackMin 128
|
2012-02-03 18:16:42 -05:00
|
|
|
aggr = nil;
|
|
|
|
|
splitlines(&lines, bstr(&in));
|
|
|
|
|
for(i=0; i<lines.len; i++) {
|
|
|
|
|
splitfields(&fields, lines.p[i]);
|
|
|
|
|
if(fields.len == 2 && streq(fields.p[0], "aggr")) {
|
|
|
|
|
if(streq(fields.p[1], "G"))
|
|
|
|
|
aggr = "g";
|
|
|
|
|
else if(streq(fields.p[1], "M"))
|
|
|
|
|
aggr = "m";
|
2013-07-19 15:40:32 -04:00
|
|
|
else if(streq(fields.p[1], "P"))
|
|
|
|
|
aggr = "p";
|
2012-02-03 18:16:42 -05:00
|
|
|
else if(streq(fields.p[1], "Gobuf"))
|
|
|
|
|
aggr = "gobuf";
|
2014-01-17 17:58:10 +13:00
|
|
|
else if(streq(fields.p[1], "LibCall"))
|
|
|
|
|
aggr = "libcall";
|
2013-06-24 17:17:45 +10:00
|
|
|
else if(streq(fields.p[1], "WinCallbackContext"))
|
|
|
|
|
aggr = "cbctxt";
|
2012-05-30 15:10:54 +10:00
|
|
|
else if(streq(fields.p[1], "SEH"))
|
|
|
|
|
aggr = "seh";
|
2014-07-16 14:16:19 -07:00
|
|
|
else if(streq(fields.p[1], "Alg"))
|
|
|
|
|
aggr = "alg";
|
2012-02-03 18:16:42 -05:00
|
|
|
}
|
|
|
|
|
if(hasprefix(lines.p[i], "}"))
|
|
|
|
|
aggr = nil;
|
|
|
|
|
if(aggr && hasprefix(lines.p[i], "\t") && fields.len >= 2) {
|
|
|
|
|
n = fields.len;
|
|
|
|
|
p = fields.p[n-1];
|
|
|
|
|
if(p[xstrlen(p)-1] == ';')
|
|
|
|
|
p[xstrlen(p)-1] = '\0';
|
|
|
|
|
bwritestr(&out, bprintf(&b, "#define %s_%s %s\n", aggr, fields.p[n-1], fields.p[n-2]));
|
|
|
|
|
}
|
2013-07-12 12:24:57 -07:00
|
|
|
if(fields.len == 3 && streq(fields.p[1], "=")) { // generated from enumerated constants
|
|
|
|
|
p = fields.p[2];
|
|
|
|
|
if(p[xstrlen(p)-1] == ';')
|
|
|
|
|
p[xstrlen(p)-1] = '\0';
|
|
|
|
|
bwritestr(&out, bprintf(&b, "#define const_%s %s\n", fields.p[0], p));
|
|
|
|
|
}
|
2012-02-03 18:16:42 -05:00
|
|
|
}
|
2013-06-24 17:17:45 +10:00
|
|
|
|
|
|
|
|
// Some #defines that are used for .c files.
|
|
|
|
|
if(streq(goos, "windows")) {
|
|
|
|
|
bwritestr(&out, bprintf(&b, "#define cb_max %d\n", MAXWINCB));
|
|
|
|
|
}
|
2012-02-03 18:16:42 -05:00
|
|
|
|
2013-09-16 20:26:10 -04:00
|
|
|
xgetenv(&exp, "GOEXPERIMENT");
|
|
|
|
|
bwritestr(&out, bprintf(&b, "#define GOEXPERIMENT \"%s\"\n", bstr(&exp)));
|
|
|
|
|
|
2012-02-03 18:16:42 -05:00
|
|
|
// Write both to file and to workdir/zasm_GOOS_GOARCH.h.
|
2012-02-21 16:49:30 -05:00
|
|
|
writefile(&out, file, 0);
|
|
|
|
|
writefile(&out, bprintf(&b, "%s/zasm_GOOS_GOARCH.h", workdir), 0);
|
2012-02-03 18:16:42 -05:00
|
|
|
|
|
|
|
|
bfree(&in);
|
|
|
|
|
bfree(&b);
|
|
|
|
|
bfree(&out);
|
2013-09-16 20:26:10 -04:00
|
|
|
bfree(&exp);
|
2012-02-03 18:16:42 -05:00
|
|
|
vfree(&argv);
|
|
|
|
|
vfree(&lines);
|
|
|
|
|
vfree(&fields);
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-05 14:57:17 -05:00
|
|
|
// mkzsys writes zsys_$GOOS_$GOARCH.s,
|
2013-06-24 17:17:45 +10:00
|
|
|
// which contains arch or os specific asm code.
|
|
|
|
|
//
|
|
|
|
|
void
|
|
|
|
|
mkzsys(char *dir, char *file)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
Buf out;
|
|
|
|
|
|
|
|
|
|
USED(dir);
|
|
|
|
|
|
|
|
|
|
binit(&out);
|
|
|
|
|
|
|
|
|
|
bwritestr(&out, "// auto generated by go tool dist\n\n");
|
|
|
|
|
if(streq(goos, "windows")) {
|
|
|
|
|
bwritef(&out,
|
|
|
|
|
"// runtime·callbackasm is called by external code to\n"
|
|
|
|
|
"// execute Go implemented callback function. It is not\n"
|
|
|
|
|
"// called from the start, instead runtime·compilecallback\n"
|
|
|
|
|
"// always returns address into runtime·callbackasm offset\n"
|
|
|
|
|
"// appropriately so different callbacks start with different\n"
|
|
|
|
|
"// CALL instruction in runtime·callbackasm. This determines\n"
|
|
|
|
|
"// which Go callback function is executed later on.\n"
|
|
|
|
|
"TEXT runtime·callbackasm(SB),7,$0\n");
|
|
|
|
|
for(i=0; i<MAXWINCB; i++) {
|
|
|
|
|
bwritef(&out, "\tCALL\truntime·callbackasm1(SB)\n");
|
|
|
|
|
}
|
|
|
|
|
bwritef(&out, "\tRET\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
writefile(&out, file, 0);
|
|
|
|
|
|
|
|
|
|
bfree(&out);
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-03 18:16:42 -05:00
|
|
|
static char *runtimedefs[] = {
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 15:58:47 -05:00
|
|
|
"defs.c",
|
2012-02-03 18:16:42 -05:00
|
|
|
"proc.c",
|
2012-05-11 10:50:03 +04:00
|
|
|
"parfor.c",
|
2012-02-03 18:16:42 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// mkzruntimedefs writes zruntime_defs_$GOOS_$GOARCH.h,
|
|
|
|
|
// which contains Go struct definitions equivalent to the C ones.
|
|
|
|
|
// Mostly we just write the output of 6c -q to the file.
|
|
|
|
|
// However, we run it on multiple files, so we have to delete
|
|
|
|
|
// the duplicated definitions, and we don't care about the funcs
|
|
|
|
|
// and consts, so we delete those too.
|
|
|
|
|
//
|
|
|
|
|
void
|
|
|
|
|
mkzruntimedefs(char *dir, char *file)
|
|
|
|
|
{
|
|
|
|
|
int i, skip;
|
|
|
|
|
char *p;
|
2013-01-31 22:02:20 -08:00
|
|
|
Buf in, b, b1, out;
|
2012-02-03 18:16:42 -05:00
|
|
|
Vec argv, lines, fields, seen;
|
|
|
|
|
|
|
|
|
|
binit(&in);
|
|
|
|
|
binit(&b);
|
2013-01-31 22:02:20 -08:00
|
|
|
binit(&b1);
|
2012-02-03 18:16:42 -05:00
|
|
|
binit(&out);
|
|
|
|
|
vinit(&argv);
|
|
|
|
|
vinit(&lines);
|
|
|
|
|
vinit(&fields);
|
|
|
|
|
vinit(&seen);
|
|
|
|
|
|
|
|
|
|
bwritestr(&out, "// auto generated by go tool dist\n"
|
|
|
|
|
"\n"
|
|
|
|
|
"package runtime\n"
|
|
|
|
|
"import \"unsafe\"\n"
|
|
|
|
|
"var _ unsafe.Pointer\n"
|
|
|
|
|
"\n"
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
2013-01-31 22:02:20 -08:00
|
|
|
// Run 6c -D GOOS_goos -D GOARCH_goarch -I workdir -q -n -o workdir/runtimedefs
|
2012-02-03 18:16:42 -05:00
|
|
|
// on each of the runtimedefs C files.
|
2012-02-13 22:31:51 -05:00
|
|
|
vadd(&argv, bpathf(&b, "%s/%sc", tooldir, gochar));
|
2013-01-02 17:52:54 -05:00
|
|
|
vadd(&argv, "-D");
|
|
|
|
|
vadd(&argv, bprintf(&b, "GOOS_%s", goos));
|
|
|
|
|
vadd(&argv, "-D");
|
|
|
|
|
vadd(&argv, bprintf(&b, "GOARCH_%s", goarch));
|
|
|
|
|
vadd(&argv, "-I");
|
|
|
|
|
vadd(&argv, bprintf(&b, "%s", workdir));
|
2012-02-03 18:16:42 -05:00
|
|
|
vadd(&argv, "-q");
|
2013-01-31 22:02:20 -08:00
|
|
|
vadd(&argv, "-n");
|
|
|
|
|
vadd(&argv, "-o");
|
|
|
|
|
vadd(&argv, bpathf(&b, "%s/runtimedefs", workdir));
|
2012-02-03 18:16:42 -05:00
|
|
|
vadd(&argv, "");
|
|
|
|
|
p = argv.p[argv.len-1];
|
|
|
|
|
for(i=0; i<nelem(runtimedefs); i++) {
|
|
|
|
|
argv.p[argv.len-1] = runtimedefs[i];
|
2013-01-31 22:02:20 -08:00
|
|
|
runv(nil, dir, CheckExit, &argv);
|
|
|
|
|
readfile(&b, bpathf(&b1, "%s/runtimedefs", workdir));
|
2012-02-03 18:16:42 -05:00
|
|
|
bwriteb(&in, &b);
|
|
|
|
|
}
|
|
|
|
|
argv.p[argv.len-1] = p;
|
|
|
|
|
|
|
|
|
|
// Process the aggregate output.
|
|
|
|
|
skip = 0;
|
|
|
|
|
splitlines(&lines, bstr(&in));
|
|
|
|
|
for(i=0; i<lines.len; i++) {
|
|
|
|
|
p = lines.p[i];
|
|
|
|
|
// Drop comment, func, and const lines.
|
|
|
|
|
if(hasprefix(p, "//") || hasprefix(p, "const") || hasprefix(p, "func"))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
// Note beginning of type or var decl, which can be multiline.
|
|
|
|
|
// Remove duplicates. The linear check of seen here makes the
|
|
|
|
|
// whole processing quadratic in aggregate, but there are only
|
|
|
|
|
// about 100 declarations, so this is okay (and simple).
|
|
|
|
|
if(hasprefix(p, "type ") || hasprefix(p, "var ")) {
|
|
|
|
|
splitfields(&fields, p);
|
|
|
|
|
if(fields.len < 2)
|
|
|
|
|
continue;
|
|
|
|
|
if(find(fields.p[1], seen.p, seen.len) >= 0) {
|
|
|
|
|
if(streq(fields.p[fields.len-1], "{"))
|
|
|
|
|
skip = 1; // skip until }
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
vadd(&seen, fields.p[1]);
|
|
|
|
|
}
|
|
|
|
|
if(skip) {
|
|
|
|
|
if(hasprefix(p, "}"))
|
|
|
|
|
skip = 0;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bwritestr(&out, p);
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-21 16:49:30 -05:00
|
|
|
writefile(&out, file, 0);
|
2012-02-03 18:16:42 -05:00
|
|
|
|
|
|
|
|
bfree(&in);
|
|
|
|
|
bfree(&b);
|
2013-01-31 22:02:20 -08:00
|
|
|
bfree(&b1);
|
2012-02-03 18:16:42 -05:00
|
|
|
bfree(&out);
|
|
|
|
|
vfree(&argv);
|
|
|
|
|
vfree(&lines);
|
|
|
|
|
vfree(&fields);
|
|
|
|
|
vfree(&seen);
|
|
|
|
|
}
|