mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.ssa] Merge remote-tracking branch 'origin/master' into mergebranch
Semi-regular merge from tip to dev.ssa. Two fixes: 1) Mark selectgo as not returning. This caused problems because there are no VARKILL ops on the selectgo path, causing things to be marked live that shouldn't be. 2) Tell the amd64 assembler that addressing modes like name(SP)(AX*4) are ok. Change-Id: I9ca81c76391b1a65cc47edc8610c70ff1a621913
This commit is contained in:
commit
eb0cff9a76
206 changed files with 14731 additions and 1404 deletions
|
|
@ -12,7 +12,7 @@ The document is not comprehensive.
|
|||
|
||||
<p>
|
||||
The assembler is based on the input style of the Plan 9 assemblers, which is documented in detail
|
||||
<a href="http://plan9.bell-labs.com/sys/doc/asm.html">elsewhere</a>.
|
||||
<a href="https://9p.io/sys/doc/asm.html">elsewhere</a>.
|
||||
If you plan to write assembly language, you should read that document although much of it is Plan 9-specific.
|
||||
The current document provides a summary of the syntax and the differences with
|
||||
what is explained in that document, and
|
||||
|
|
@ -23,7 +23,7 @@ describes the peculiarities that apply when writing assembly code to interact wi
|
|||
The most important thing to know about Go's assembler is that it is not a direct representation of the underlying machine.
|
||||
Some of the details map precisely to the machine, but some do not.
|
||||
This is because the compiler suite (see
|
||||
<a href="http://plan9.bell-labs.com/sys/doc/compiler.html">this description</a>)
|
||||
<a href="https://9p.io/sys/doc/compiler.html">this description</a>)
|
||||
needs no assembler pass in the usual pipeline.
|
||||
Instead, the compiler operates on a kind of semi-abstract instruction set,
|
||||
and instruction selection occurs partly after code generation.
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@
|
|||
|
||||
The full address syntax is summarized in this table
|
||||
(an excerpt of Table II from
|
||||
<a href="http://plan9.bell-labs.com/sys/doc/sam/sam.html">The text editor <code>sam</code></a>):
|
||||
<a href="https://9p.io/sys/doc/sam/sam.html">The text editor <code>sam</code></a>):
|
||||
<br/><br/>
|
||||
|
||||
<table>
|
||||
|
|
|
|||
|
|
@ -118,10 +118,10 @@ instead of generated from <a href="/cmd/yacc/">yacc</a>.
|
|||
</p>
|
||||
|
||||
<p>
|
||||
The compiler, linker, and <code>go</code> command have new flag <code>-msan</code>,
|
||||
The compiler, linker, and <code>go</code> command have a new flag <code>-msan</code>,
|
||||
analogous to <code>-race</code> and only available on linux/amd64,
|
||||
that enables interoperation with the <a href="http://clang.llvm.org/docs/MemorySanitizer.html">Clang MemorySanitizer</a>.
|
||||
Such interoperation useful mainly for testing a program containing suspect C or C++ code.
|
||||
Such interoperation is useful mainly for testing a program containing suspect C or C++ code.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
@ -341,6 +341,19 @@ and changing the global timer resolution caused problems on some systems,
|
|||
so the call has been removed.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
When using <code>-buildmode=c-archive</code> or
|
||||
<code>-buildmode=c-shared</code> to build an archive or a shared
|
||||
library, the handling of signals has changed.
|
||||
In Go 1.5 the archive or shared library would install a signal handler
|
||||
for most signals.
|
||||
In Go 1.6 it will only install a signal handler for the
|
||||
synchronous signals needed to handle run-time panics in Go code:
|
||||
SIGBUS, SIGFPE, SIGSEGV.
|
||||
See the <a href="/pkg/os/signal">os/signal</a> package for more
|
||||
details.
|
||||
</p>
|
||||
|
||||
<h3 id="reflect">Reflect</h3>
|
||||
|
||||
<p>
|
||||
|
|
@ -451,20 +464,8 @@ Second, the new <a href="/pkg/text/template/#hdr-Actions"><code>{{"{{"}}block}}<
|
|||
combined with allowing redefinition of named templates,
|
||||
provides a simple way to define pieces of a template that
|
||||
can be replaced in different instantiations.
|
||||
For example, the template
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
<title>{{"{{"}}block "title"}}Page Title{{"{{"}}end}}</title>
|
||||
<body>
|
||||
<h1>{{"{{"}}template "title"}}</h1>
|
||||
{{"{{"}}block "page"}}Main text{{"{{"}}end}}
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
defines the basic formatting of a web page. A program can then
|
||||
overlay that template with new definitions for the <code>"title"</code>
|
||||
and <code>"page"</code> blocks to reuse the formatting for another page.
|
||||
There is <a href="/pkg/text/template/#example_Template_block">an example</a>
|
||||
in the <code>text/template</code> package that demonstrates this new feature.
|
||||
</p>
|
||||
|
||||
<h3 id="minor_library_changes">Minor changes to the library</h3>
|
||||
|
|
@ -588,7 +589,7 @@ Also in the <a href="/pkg/encoding/asn1/"><code>encoding/asn1</code></a> package
|
|||
The <a href="/pkg/encoding/base64"><code>encoding/base64</code></a> package's
|
||||
<a href="/pkg/encoding/base64/#Decoder"><code>Decoder</code></a> has been fixed
|
||||
to process the final bytes of its input. Previously it processed as many four-byte tokens as
|
||||
possible but ignore the remainder, up to three bytes.
|
||||
possible but ignored the remainder, up to three bytes.
|
||||
The <code>Decoder</code> therefore now handles inputs in unpadded encodings (like
|
||||
<a href="/pkg/encoding/base64/#RawURLEncoding">RawURLEncoding</a>) correctly,
|
||||
but it also rejects inputs in padded encodings that are truncated or end with invalid bytes,
|
||||
|
|
@ -631,17 +632,17 @@ In previous releases, the argument to <code>*</code> was required to have type <
|
|||
Also in the <a href="/pkg/fmt/"><code>fmt</code></a> package,
|
||||
<a href="/pkg/fmt/#Scanf"><code>Scanf</code></a> can now scan hexadecimal strings using %X, as an alias for %x.
|
||||
Both formats accept any mix of upper- and lower-case hexadecimal.
|
||||
<a href="golang.org/x/13585">TODO: Keep?</a>
|
||||
<a href="https://golang.org/issues/13585">TODO: Keep?</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
The <a href="/pkg/image/"><code>image</code></a>
|
||||
and
|
||||
The <a href="/pkg/image/color/"><code>image/color</code></a> packages
|
||||
<a href="/pkg/image/color/"><code>image/color</code></a> packages
|
||||
add
|
||||
<a href="/pkg/image/#NYCbCrA"><code>NYCbCrA</code></a>
|
||||
and
|
||||
<a href="/pkg/color/#NYCbCrA"><code>NYCbCrA</code></a>
|
||||
<a href="/pkg/image/color/#NYCbCrA"><code>NYCbCrA</code></a>
|
||||
types, to support Y'CbCr images with non-premultiplied alpha.
|
||||
</li>
|
||||
|
||||
|
|
@ -725,22 +726,31 @@ This is arguably a mistake but is not yet fixed. See https://golang.org/issue/13
|
|||
The <a href="/pkg/net/http/"><code>net/http</code></a> package has
|
||||
a number of minor additions beyond the HTTP/2 support already discussed.
|
||||
First, the
|
||||
<a href="/pkg/http/#FileServer"><code>FileServer</code></a> now sorts its generated directory listings by file name.
|
||||
<a href="/pkg/net/http/#FileServer"><code>FileServer</code></a> now sorts its generated directory listings by file name.
|
||||
Second, the
|
||||
<a href="/pkg/http/#Client"><code>Client</code></a> now allows user code to set the
|
||||
<a href="/pkg/net/http/#ServeFile"><code>ServeFile</code></a> function now refuses to serve a result
|
||||
if the request's URL path contains “..” (dot-dot) as a path element.
|
||||
Programs should typically use <code>FileServer</code> and
|
||||
<a href="/pkg/net/http/#Dir"><code>Dir</code></a>
|
||||
instead of calling <code>ServeFile</code> directly.
|
||||
Programs that need to serve file content in response to requests for URLs containing dot-dot can
|
||||
still call <a href="/pkg/net/http/#ServeContent"><code>ServeContent</code></a>.
|
||||
Third, the
|
||||
<a href="/pkg/net/http/#Client"><code>Client</code></a> now allows user code to set the
|
||||
<code>Expect:</code> <code>100-continue</code> header (see
|
||||
<a href="/pkg/http/#Transport"><code>Transport.ExpectContinueTimeout</code></a>).
|
||||
Third, there are
|
||||
<a href="/pkg/net/http/#pkg-constants">four new error codes</a> from RFC 6585:
|
||||
<a href="/pkg/net/http/#Transport"><code>Transport.ExpectContinueTimeout</code></a>).
|
||||
Fourth, there are
|
||||
<a href="/pkg/net/http/#pkg-constants">five new error codes</a>:
|
||||
<code>StatusPreconditionRequired</code> (428),
|
||||
<code>StatusTooManyRequests</code> (429),
|
||||
<code>StatusRequestHeaderFieldsTooLarge</code> (431),
|
||||
and
|
||||
<code>StatusNetworkAuthenticationRequired</code> (511).
|
||||
Fourth, the implementation and documentation of
|
||||
<a href="/pkg/http/#CloseNotifier"><code>CloseNotifier</code></a>
|
||||
<code>StatusRequestHeaderFieldsTooLarge</code> (431), and
|
||||
<code>StatusNetworkAuthenticationRequired</code> (511) from RFC 6585,
|
||||
as well as the recently-approved
|
||||
<code>StatusUnavailableForLegalReasons</code> (451).
|
||||
Fifth, the implementation and documentation of
|
||||
<a href="/pkg/net/http/#CloseNotifier"><code>CloseNotifier</code></a>
|
||||
has been substantially changed.
|
||||
The <a href="/pkg/http/#Hijacker"><code>Hijacker</code></a>
|
||||
The <a href="/pkg/net/http/#Hijacker"><code>Hijacker</code></a>
|
||||
interface now works correctly on connections that have previously
|
||||
been used with <code>CloseNotifier</code>.
|
||||
The documentation now describes when <code>CloseNotifier</code>
|
||||
|
|
@ -750,17 +760,17 @@ is expected to work.
|
|||
<li>
|
||||
Also in the <a href="/pkg/net/http/"><code>net/http</code></a> package,
|
||||
there are a few changes related to the handling of a
|
||||
<a href="/pkg/http/#Request"><code>Request</code></a> data structure with its <code>Method</code> field set to the empty string.
|
||||
<a href="/pkg/net/http/#Request"><code>Request</code></a> data structure with its <code>Method</code> field set to the empty string.
|
||||
An empty <code>Method</code> field has always been documented as an alias for <code>"GET"</code>
|
||||
and it remains so.
|
||||
However, Go 1.6 fixes a few routines that did not treat an empty
|
||||
<code>Method</code> the same as an explicit <code>"GET"</code>.
|
||||
Most notably, in previous releases
|
||||
<a href="/pkg/http/#Client"><code>Client</code></a> followed redirects only with
|
||||
<a href="/pkg/net/http/#Client"><code>Client</code></a> followed redirects only with
|
||||
<code>Method</code> set explicitly to <code>"GET"</code>;
|
||||
in Go 1.6 <code>Client</code> also follows redirects for the empty <code>Method</code>.
|
||||
Finally,
|
||||
<a href="/pkg/http/#NewRequest"><code>NewRequest</code></a> accepts a <code>method</code> argument that has not been
|
||||
<a href="/pkg/net/http/#NewRequest"><code>NewRequest</code></a> accepts a <code>method</code> argument that has not been
|
||||
documented as allowed to be empty.
|
||||
In past releases, passing an empty <code>method</code> argument resulted
|
||||
in a <code>Request</code> with an empty <code>Method</code> field.
|
||||
|
|
@ -825,7 +835,7 @@ In the <a href="/pkg/os/exec/"><code>os/exec</code></a> package,
|
|||
<a href="/pkg/os/exec/#Cmd.Output"><code>Output</code></a> method continues to return an
|
||||
<a href="/pkg/os/exec/#ExitError"><code>ExitError</code></a> when a command exits with an unsuccessful status.
|
||||
If standard error would otherwise have been discarded,
|
||||
the returned <code>ExitError</code> now holds a prefix
|
||||
the returned <code>ExitError</code> now holds a prefix and suffix
|
||||
(currently 32 kB) of the failed command's standard error output,
|
||||
for debugging or for inclusion in error messages.
|
||||
The <code>ExitError</code>'s
|
||||
|
|
@ -865,16 +875,18 @@ should only be used when contention has been observed.
|
|||
<li>
|
||||
The <a href="/pkg/strconv/"><code>strconv</code></a> package adds
|
||||
<a href="/pkg/strconv/#IsGraphic"><code>IsGraphic</code></a>,
|
||||
similar to <a href="/pkg/strconv/#IsPrint"><code>IsPrint</code></a>.
|
||||
It also adds
|
||||
<a href="/pkg/strconv/#QuoteToGraphic"><code>QuoteToGraphic</code></a>,
|
||||
<a href="/pkg/strconv/#QuoteRuneToGraphic"><code>QuoteRuneToGraphic</code></a>,
|
||||
<a href="/pkg/strconv/#AppendQuoteToGraphic"><code>AppendQuoteToGraphic</code></a>,
|
||||
and
|
||||
<a href="/pkg/strconv/#AppendQuoteRuneToGraphic"><code>AppendQuoteRuneToGraphic</code></a>,
|
||||
analogous to
|
||||
<a href="/pkg/strconv/#IsPrint"><code>IsPrint</code></a>,
|
||||
<a href="/pkg/strconv/#QuoteToPrint"><code>QuoteToPrint</code></a>,
|
||||
<a href="/pkg/strconv/#QuoteToASCII"><code>QuoteToASCII</code></a>,
|
||||
<a href="/pkg/strconv/#QuoteRuneToASCII"><code>QuoteRuneToASCII</code></a>,
|
||||
and so on.
|
||||
The <code>Print</code> family escapes all space characters except ASCII space (U+0020).
|
||||
The <code>ASCII</code> family escapes all space characters except ASCII space (U+0020).
|
||||
In contrast, the <code>Graphic</code> family does not escape any Unicode space characters (category Zs).
|
||||
</li>
|
||||
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ What's the origin of the mascot?</h3>
|
|||
<p>
|
||||
The mascot and logo were designed by
|
||||
<a href="http://reneefrench.blogspot.com">Renée French</a>, who also designed
|
||||
<a href="http://plan9.bell-labs.com/plan9/glenda.html">Glenda</a>,
|
||||
<a href="https://9p.io/plan9/glenda.html">Glenda</a>,
|
||||
the Plan 9 bunny.
|
||||
The <a href="https://blog.golang.org/gopher">gopher</a>
|
||||
is derived from one she used for an <a href="http://wfmu.org/">WFMU</a>
|
||||
|
|
|
|||
|
|
@ -173,6 +173,21 @@ follow the instructions on the
|
|||
<a href="http://git-scm.com/downloads">Git downloads</a> page.
|
||||
</p>
|
||||
|
||||
<h2 id="ccompiler">(Optional) Install a C compiler</h2>
|
||||
|
||||
<p>
|
||||
To build a Go installation
|
||||
with <code><a href="/cmd/cgo">cgo</a></code> support, which permits Go
|
||||
programs to import C libraries, a C compiler such as <code>gcc</code>
|
||||
or <code>clang</code> must be installed first. Do this using whatever
|
||||
installation method is standard on the system.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To build without <code>cgo</code>, set the environment variable
|
||||
<code>CGO_ENABLED=0</code> before running <code>all.bash</code> or
|
||||
<code>make.bash</code>.
|
||||
</p>
|
||||
|
||||
<h2 id="fetch">Fetch the repository</h2>
|
||||
|
||||
|
|
@ -184,7 +199,7 @@ Then clone the repository and check out the latest release tag:</p>
|
|||
<pre>
|
||||
$ git clone https://go.googlesource.com/go
|
||||
$ cd go
|
||||
$ git checkout go1.5.2
|
||||
$ git checkout go1.5.3
|
||||
</pre>
|
||||
|
||||
<h2 id="head">(Optional) Switch to the master branch</h2>
|
||||
|
|
@ -363,7 +378,7 @@ New releases are announced on the
|
|||
<a href="//groups.google.com/group/golang-announce">golang-announce</a>
|
||||
mailing list.
|
||||
Each announcement mentions the latest release tag, for instance,
|
||||
<code>go1.5.2</code>.
|
||||
<code>go1.5.3</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
|
|
|||
|
|
@ -5,10 +5,11 @@
|
|||
|
||||
# This script rebuilds the time zone files using files
|
||||
# downloaded from the ICANN/IANA distribution.
|
||||
# Consult http://www.iana.org/time-zones for the latest versions.
|
||||
|
||||
# Versions to use.
|
||||
CODE=2015e
|
||||
DATA=2015e
|
||||
CODE=2016a
|
||||
DATA=2016a
|
||||
|
||||
set -e
|
||||
rm -rf work
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -27,10 +27,16 @@ type ptrTest struct {
|
|||
imports []string // a list of imports
|
||||
support string // supporting functions
|
||||
body string // the body of the main function
|
||||
extra []extra // extra files
|
||||
fail bool // whether the test should fail
|
||||
expensive bool // whether the test requires the expensive check
|
||||
}
|
||||
|
||||
type extra struct {
|
||||
name string
|
||||
contents string
|
||||
}
|
||||
|
||||
var ptrTests = []ptrTest{
|
||||
{
|
||||
// Passing a pointer to a struct that contains a Go pointer.
|
||||
|
|
@ -237,6 +243,43 @@ var ptrTests = []ptrTest{
|
|||
func GoFn() *byte { return (*byte)(C.malloc(1)) }`,
|
||||
body: `C.GoFn()`,
|
||||
},
|
||||
{
|
||||
// Passing a Go string is fine.
|
||||
name: "pass-string",
|
||||
c: `#include <stddef.h>
|
||||
typedef struct { const char *p; ptrdiff_t n; } gostring;
|
||||
gostring f(gostring s) { return s; }`,
|
||||
imports: []string{"unsafe"},
|
||||
body: `s := "a"; r := C.f(*(*C.gostring)(unsafe.Pointer(&s))); if *(*string)(unsafe.Pointer(&r)) != s { panic(r) }`,
|
||||
},
|
||||
{
|
||||
// Passing a slice of Go strings fails.
|
||||
name: "pass-string-slice",
|
||||
c: `void f(void *p) {}`,
|
||||
imports: []string{"strings", "unsafe"},
|
||||
support: `type S struct { a [1]string }`,
|
||||
body: `s := S{a:[1]string{strings.Repeat("a", 2)}}; C.f(unsafe.Pointer(&s.a[0]))`,
|
||||
fail: true,
|
||||
},
|
||||
{
|
||||
// Exported functions may not return strings.
|
||||
name: "ret-string",
|
||||
c: `extern void f();`,
|
||||
imports: []string{"strings"},
|
||||
support: `//export GoStr
|
||||
func GoStr() string { return strings.Repeat("a", 2) }`,
|
||||
body: `C.f()`,
|
||||
extra: []extra{
|
||||
{
|
||||
"call.c",
|
||||
`#include <stddef.h>
|
||||
typedef struct { const char *p; ptrdiff_t n; } gostring;
|
||||
extern gostring GoStr();
|
||||
void f() { GoStr(); }`,
|
||||
},
|
||||
},
|
||||
fail: true,
|
||||
},
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
|
@ -244,12 +287,17 @@ func main() {
|
|||
}
|
||||
|
||||
func doTests() int {
|
||||
dir, err := ioutil.TempDir("", "cgoerrors")
|
||||
gopath, err := ioutil.TempDir("", "cgoerrors")
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
return 2
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
defer os.RemoveAll(gopath)
|
||||
|
||||
if err := os.MkdirAll(filepath.Join(gopath, "src"), 0777); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
return 2
|
||||
}
|
||||
|
||||
workers := runtime.NumCPU() + 1
|
||||
|
||||
|
|
@ -259,7 +307,7 @@ func doTests() int {
|
|||
for i := 0; i < workers; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
worker(dir, c, errs)
|
||||
worker(gopath, c, errs)
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
|
|
@ -281,10 +329,10 @@ func doTests() int {
|
|||
return tot
|
||||
}
|
||||
|
||||
func worker(dir string, c, errs chan int) {
|
||||
func worker(gopath string, c, errs chan int) {
|
||||
e := 0
|
||||
for i := range c {
|
||||
if !doOne(dir, i) {
|
||||
if !doOne(gopath, i) {
|
||||
e++
|
||||
}
|
||||
}
|
||||
|
|
@ -293,9 +341,15 @@ func worker(dir string, c, errs chan int) {
|
|||
}
|
||||
}
|
||||
|
||||
func doOne(dir string, i int) bool {
|
||||
func doOne(gopath string, i int) bool {
|
||||
t := &ptrTests[i]
|
||||
|
||||
dir := filepath.Join(gopath, "src", fmt.Sprintf("dir%d", i))
|
||||
if err := os.Mkdir(dir, 0777); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
return false
|
||||
}
|
||||
|
||||
name := filepath.Join(dir, fmt.Sprintf("t%d.go", i))
|
||||
f, err := os.Create(name)
|
||||
if err != nil {
|
||||
|
|
@ -330,13 +384,30 @@ func doOne(dir string, i int) bool {
|
|||
return false
|
||||
}
|
||||
if err := f.Close(); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "closing %s: %v\n", name, err)
|
||||
fmt.Fprintf(os.Stderr, "closing %s: %v\n", name, err)
|
||||
return false
|
||||
}
|
||||
|
||||
for _, e := range t.extra {
|
||||
if err := ioutil.WriteFile(filepath.Join(dir, e.name), []byte(e.contents), 0644); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "writing %s: %v\n", e.name, err)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
ok := true
|
||||
|
||||
cmd := exec.Command("go", "run", name)
|
||||
cmd := exec.Command("go", "build")
|
||||
cmd.Dir = dir
|
||||
cmd.Env = addEnv("GOPATH", gopath)
|
||||
buf, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "test %s failed to build: %v\n%s", t.name, err, buf)
|
||||
return false
|
||||
}
|
||||
|
||||
exe := filepath.Join(dir, filepath.Base(dir))
|
||||
cmd = exec.Command(exe)
|
||||
cmd.Dir = dir
|
||||
|
||||
if t.expensive {
|
||||
|
|
@ -354,7 +425,7 @@ func doOne(dir string, i int) bool {
|
|||
ok = false
|
||||
}
|
||||
|
||||
cmd = exec.Command("go", "run", name)
|
||||
cmd = exec.Command(exe)
|
||||
cmd.Dir = dir
|
||||
}
|
||||
|
||||
|
|
@ -362,7 +433,7 @@ func doOne(dir string, i int) bool {
|
|||
cmd.Env = cgocheckEnv("2")
|
||||
}
|
||||
|
||||
buf, err := cmd.CombinedOutput()
|
||||
buf, err = cmd.CombinedOutput()
|
||||
|
||||
if t.fail {
|
||||
if err == nil {
|
||||
|
|
@ -389,7 +460,7 @@ func doOne(dir string, i int) bool {
|
|||
|
||||
if !t.expensive && ok {
|
||||
// Make sure it passes with the expensive checks.
|
||||
cmd := exec.Command("go", "run", name)
|
||||
cmd := exec.Command(exe)
|
||||
cmd.Dir = dir
|
||||
cmd.Env = cgocheckEnv("2")
|
||||
buf, err := cmd.CombinedOutput()
|
||||
|
|
@ -404,7 +475,7 @@ func doOne(dir string, i int) bool {
|
|||
}
|
||||
|
||||
if t.fail && ok {
|
||||
cmd = exec.Command("go", "run", name)
|
||||
cmd = exec.Command(exe)
|
||||
cmd.Dir = dir
|
||||
cmd.Env = cgocheckEnv("0")
|
||||
buf, err := cmd.CombinedOutput()
|
||||
|
|
@ -427,9 +498,14 @@ func reportTestOutput(w io.Writer, name string, buf []byte) {
|
|||
}
|
||||
|
||||
func cgocheckEnv(val string) []string {
|
||||
env := []string{"GODEBUG=cgocheck=" + val}
|
||||
return addEnv("GODEBUG", "cgocheck="+val)
|
||||
}
|
||||
|
||||
func addEnv(key, val string) []string {
|
||||
env := []string{key + "=" + val}
|
||||
look := key + "="
|
||||
for _, e := range os.Environ() {
|
||||
if !strings.HasPrefix(e, "GODEBUG=") {
|
||||
if !strings.HasPrefix(e, look) {
|
||||
env = append(env, e)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ static void changeSignalStack() {
|
|||
}
|
||||
|
||||
static void restoreSignalStack() {
|
||||
#if defined(__x86_64__) && defined(__APPLE__)
|
||||
#if (defined(__x86_64__) || defined(__i386__)) && defined(__APPLE__)
|
||||
// The Darwin C library enforces a minimum that the kernel does not.
|
||||
// This is OK since we allocated this much space in mpreinit,
|
||||
// it was just removed from the buffer by stackalloc.
|
||||
|
|
@ -57,6 +57,8 @@ func testSigaltstack(t *testing.T) {
|
|||
switch {
|
||||
case runtime.GOOS == "solaris", runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64"):
|
||||
t.Skipf("switching signal stack not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
|
||||
case runtime.GOOS == "darwin" && runtime.GOARCH == "386":
|
||||
t.Skipf("sigaltstack fails on darwin/386")
|
||||
}
|
||||
|
||||
C.changeSignalStack()
|
||||
|
|
|
|||
|
|
@ -85,4 +85,22 @@ if ! $bin; then
|
|||
fi
|
||||
rm -rf libgo4.a libgo4.h testp pkg
|
||||
|
||||
rm -f testar
|
||||
cat >testar <<EOF
|
||||
#!/usr/bin/env bash
|
||||
while expr \$1 : '[-]' >/dev/null; do
|
||||
shift
|
||||
done
|
||||
echo "testar" > \$1
|
||||
echo "testar" > $(pwd)/testar.ran
|
||||
EOF
|
||||
chmod +x testar
|
||||
rm -f testar.ran
|
||||
GOPATH=$(pwd) go build -buildmode=c-archive -ldflags=-extar=$(pwd)/testar -o libgo4.a libgo4
|
||||
if ! test -f testar.ran; then
|
||||
echo "FAIL test5"
|
||||
status=1
|
||||
fi
|
||||
rm -rf libgo4.a libgo4.h testar testar.ran pkg
|
||||
|
||||
exit $status
|
||||
|
|
|
|||
|
|
@ -749,3 +749,15 @@ func TestABIChecking(t *testing.T) {
|
|||
goCmd(t, "install", "-buildmode=shared", "-linkshared", "dep")
|
||||
run(t, "after non-ABI breaking change", "./bin/exe")
|
||||
}
|
||||
|
||||
// If a package 'explicit' imports a package 'implicit', building
|
||||
// 'explicit' into a shared library implicitly includes implicit in
|
||||
// the shared library. Building an executable that imports both
|
||||
// explicit and implicit builds the code from implicit into the
|
||||
// executable rather than fetching it from the shared library. The
|
||||
// link still succeeds and the executable still runs though.
|
||||
func TestImplicitInclusion(t *testing.T) {
|
||||
goCmd(t, "install", "-buildmode=shared", "-linkshared", "explicit")
|
||||
goCmd(t, "install", "-linkshared", "implicitcmd")
|
||||
run(t, "running executable linked against library that contains same package as it", "./bin/implicitcmd")
|
||||
}
|
||||
|
|
|
|||
9
misc/cgo/testshared/src/explicit/explicit.go
Normal file
9
misc/cgo/testshared/src/explicit/explicit.go
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
package explicit
|
||||
|
||||
import (
|
||||
"implicit"
|
||||
)
|
||||
|
||||
func E() int {
|
||||
return implicit.I()
|
||||
}
|
||||
5
misc/cgo/testshared/src/implicit/implicit.go
Normal file
5
misc/cgo/testshared/src/implicit/implicit.go
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
package implicit
|
||||
|
||||
func I() int {
|
||||
return 42
|
||||
}
|
||||
10
misc/cgo/testshared/src/implicitcmd/implicitcmd.go
Normal file
10
misc/cgo/testshared/src/implicitcmd/implicitcmd.go
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"explicit"
|
||||
"implicit"
|
||||
)
|
||||
|
||||
func main() {
|
||||
println(implicit.I() + explicit.E())
|
||||
}
|
||||
|
|
@ -76,8 +76,7 @@ func ExampleReader() {
|
|||
}
|
||||
|
||||
func ExampleWriter_RegisterCompressor() {
|
||||
// Override the default Deflate compressor with a higher compression
|
||||
// level.
|
||||
// Override the default Deflate compressor with a higher compression level.
|
||||
|
||||
// Create a buffer to write our archive to.
|
||||
buf := new(bytes.Buffer)
|
||||
|
|
@ -85,19 +84,9 @@ func ExampleWriter_RegisterCompressor() {
|
|||
// Create a new zip archive.
|
||||
w := zip.NewWriter(buf)
|
||||
|
||||
var fw *flate.Writer
|
||||
|
||||
// Register the deflator.
|
||||
// Register a custom Deflate compressor.
|
||||
w.RegisterCompressor(zip.Deflate, func(out io.Writer) (io.WriteCloser, error) {
|
||||
var err error
|
||||
if fw == nil {
|
||||
// Creating a flate compressor for every file is
|
||||
// expensive, create one and reuse it.
|
||||
fw, err = flate.NewWriter(out, flate.BestCompression)
|
||||
} else {
|
||||
fw.Reset(out)
|
||||
}
|
||||
return fw, err
|
||||
return flate.NewWriter(out, flate.BestCompression)
|
||||
})
|
||||
|
||||
// Proceed to add files to w.
|
||||
|
|
|
|||
|
|
@ -118,8 +118,6 @@ func (z *Reader) init(r io.ReaderAt, size int64) error {
|
|||
// RegisterDecompressor registers or overrides a custom decompressor for a
|
||||
// specific method ID. If a decompressor for a given method is not found,
|
||||
// Reader will default to looking up the decompressor at the package level.
|
||||
//
|
||||
// Must not be called concurrently with Open on any Files in the Reader.
|
||||
func (z *Reader) RegisterDecompressor(method uint16, dcomp Decompressor) {
|
||||
if z.decompressors == nil {
|
||||
z.decompressors = make(map[uint16]Decompressor)
|
||||
|
|
@ -332,7 +330,17 @@ func readDirectoryHeader(f *File, r io.Reader) error {
|
|||
}
|
||||
}
|
||||
|
||||
if needUSize || needCSize || needHeaderOffset {
|
||||
// Assume that uncompressed size 2³²-1 could plausibly happen in
|
||||
// an old zip32 file that was sharding inputs into the largest chunks
|
||||
// possible (or is just malicious; search the web for 42.zip).
|
||||
// If needUSize is true still, it means we didn't see a zip64 extension.
|
||||
// As long as the compressed size is not also 2³²-1 (implausible)
|
||||
// and the header is not also 2³²-1 (equally implausible),
|
||||
// accept the uncompressed size 2³²-1 as valid.
|
||||
// If nothing else, this keeps archive/zip working with 42.zip.
|
||||
_ = needUSize
|
||||
|
||||
if needCSize || needHeaderOffset {
|
||||
return ErrFormat
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,12 +27,24 @@ type ZipTest struct {
|
|||
}
|
||||
|
||||
type ZipTestFile struct {
|
||||
Name string
|
||||
Content []byte // if blank, will attempt to compare against File
|
||||
Name string
|
||||
Mode os.FileMode
|
||||
Mtime string // optional, modified time in format "mm-dd-yy hh:mm:ss"
|
||||
|
||||
// Information describing expected zip file content.
|
||||
// First, reading the entire content should produce the error ContentErr.
|
||||
// Second, if ContentErr==nil, the content should match Content.
|
||||
// If content is large, an alternative to setting Content is to set File,
|
||||
// which names a file in the testdata/ directory containing the
|
||||
// uncompressed expected content.
|
||||
// If content is very large, an alternative to setting Content or File
|
||||
// is to set Size, which will then be checked against the header-reported size
|
||||
// but will bypass the decompressing of the actual data.
|
||||
// This last option is used for testing very large (multi-GB) compressed files.
|
||||
ContentErr error
|
||||
File string // name of file to compare to (relative to testdata/)
|
||||
Mtime string // modified time in format "mm-dd-yy hh:mm:ss"
|
||||
Mode os.FileMode
|
||||
Content []byte
|
||||
File string
|
||||
Size uint64
|
||||
}
|
||||
|
||||
// Caution: The Mtime values found for the test files should correspond to
|
||||
|
|
@ -248,6 +260,19 @@ var tests = []ZipTest{
|
|||
},
|
||||
},
|
||||
},
|
||||
// Largest possible non-zip64 file, with no zip64 header.
|
||||
{
|
||||
Name: "big.zip",
|
||||
Source: returnBigZipBytes,
|
||||
File: []ZipTestFile{
|
||||
{
|
||||
Name: "big.file",
|
||||
Content: nil,
|
||||
Size: 1<<32 - 1,
|
||||
Mode: 0666,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var crossPlatform = []ZipTestFile{
|
||||
|
|
@ -356,13 +381,31 @@ func readTestFile(t *testing.T, zt ZipTest, ft ZipTestFile, f *File) {
|
|||
|
||||
testFileMode(t, zt.Name, f, ft.Mode)
|
||||
|
||||
var b bytes.Buffer
|
||||
size := uint64(f.UncompressedSize)
|
||||
if size == uint32max {
|
||||
size = f.UncompressedSize64
|
||||
} else if size != f.UncompressedSize64 {
|
||||
t.Errorf("%v: UncompressedSize=%#x does not match UncompressedSize64=%#x", f.Name, size, f.UncompressedSize64)
|
||||
}
|
||||
|
||||
r, err := f.Open()
|
||||
if err != nil {
|
||||
t.Errorf("%s: %v", zt.Name, err)
|
||||
return
|
||||
}
|
||||
|
||||
// For very large files, just check that the size is correct.
|
||||
// The content is expected to be all zeros.
|
||||
// Don't bother uncompressing: too big.
|
||||
if ft.Content == nil && ft.File == "" && ft.Size > 0 {
|
||||
if size != ft.Size {
|
||||
t.Errorf("%v: uncompressed size %#x, want %#x", size, ft.Size)
|
||||
}
|
||||
r.Close()
|
||||
return
|
||||
}
|
||||
|
||||
var b bytes.Buffer
|
||||
_, err = io.Copy(&b, r)
|
||||
if err != ft.ContentErr {
|
||||
t.Errorf("%s: copying contents: %v (want %v)", zt.Name, err, ft.ContentErr)
|
||||
|
|
@ -372,10 +415,6 @@ func readTestFile(t *testing.T, zt ZipTest, ft ZipTestFile, f *File) {
|
|||
}
|
||||
r.Close()
|
||||
|
||||
size := uint64(f.UncompressedSize)
|
||||
if size == uint32max {
|
||||
size = f.UncompressedSize64
|
||||
}
|
||||
if g := uint64(b.Len()); g != size {
|
||||
t.Errorf("%v: read %v bytes but f.UncompressedSize == %v", f.Name, g, size)
|
||||
}
|
||||
|
|
@ -510,6 +549,182 @@ func returnRecursiveZip() (r io.ReaderAt, size int64) {
|
|||
return bytes.NewReader(b), int64(len(b))
|
||||
}
|
||||
|
||||
// biggestZipBytes returns the bytes of a zip file biggest.zip
|
||||
// that contains a zip file bigger.zip that contains a zip file
|
||||
// big.zip that contains big.file, which contains 2³²-1 zeros.
|
||||
// The big.zip file is interesting because it has no zip64 header,
|
||||
// much like the innermost zip files in the well-known 42.zip.
|
||||
//
|
||||
// biggest.zip was generated by changing isZip64 to use > uint32max
|
||||
// instead of >= uint32max and then running this program:
|
||||
//
|
||||
// package main
|
||||
//
|
||||
// import (
|
||||
// "archive/zip"
|
||||
// "bytes"
|
||||
// "io"
|
||||
// "io/ioutil"
|
||||
// "log"
|
||||
// )
|
||||
//
|
||||
// type zeros struct{}
|
||||
//
|
||||
// func (zeros) Read(b []byte) (int, error) {
|
||||
// for i := range b {
|
||||
// b[i] = 0
|
||||
// }
|
||||
// return len(b), nil
|
||||
// }
|
||||
//
|
||||
// func main() {
|
||||
// bigZip := makeZip("big.file", io.LimitReader(zeros{}, 1<<32-1))
|
||||
// if err := ioutil.WriteFile("/tmp/big.zip", bigZip, 0666); err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
//
|
||||
// biggerZip := makeZip("big.zip", bytes.NewReader(bigZip))
|
||||
// if err := ioutil.WriteFile("/tmp/bigger.zip", biggerZip, 0666); err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
//
|
||||
// biggestZip := makeZip("bigger.zip", bytes.NewReader(biggerZip))
|
||||
// if err := ioutil.WriteFile("/tmp/biggest.zip", biggestZip, 0666); err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// func makeZip(name string, r io.Reader) []byte {
|
||||
// var buf bytes.Buffer
|
||||
// w := zip.NewWriter(&buf)
|
||||
// wf, err := w.Create(name)
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
// if _, err = io.Copy(wf, r); err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
// if err := w.Close(); err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
// return buf.Bytes()
|
||||
// }
|
||||
//
|
||||
// The 4 GB of zeros compresses to 4 MB, which compresses to 20 kB,
|
||||
// which compresses to 1252 bytes (in the hex dump below).
|
||||
//
|
||||
// It's here in hex for the same reason as rZipBytes above: to avoid
|
||||
// problems with on-disk virus scanners or other zip processors.
|
||||
//
|
||||
func biggestZipBytes() []byte {
|
||||
s := `
|
||||
0000000 50 4b 03 04 14 00 08 00 08 00 00 00 00 00 00 00
|
||||
0000010 00 00 00 00 00 00 00 00 00 00 0a 00 00 00 62 69
|
||||
0000020 67 67 65 72 2e 7a 69 70 ec dc 6b 4c 53 67 18 07
|
||||
0000030 f0 16 c5 ca 65 2e cb b8 94 20 61 1f 44 33 c7 cd
|
||||
0000040 c0 86 4a b5 c0 62 8a 61 05 c6 cd 91 b2 54 8c 1b
|
||||
0000050 63 8b 03 9c 1b 95 52 5a e3 a0 19 6c b2 05 59 44
|
||||
0000060 64 9d 73 83 71 11 46 61 14 b9 1d 14 09 4a c3 60
|
||||
0000070 2e 4c 6e a5 60 45 02 62 81 95 b6 94 9e 9e 77 e7
|
||||
0000080 d0 43 b6 f8 71 df 96 3c e7 a4 69 ce bf cf e9 79
|
||||
0000090 ce ef 79 3f bf f1 31 db b6 bb 31 76 92 e7 f3 07
|
||||
00000a0 8b fc 9c ca cc 08 cc cb cc 5e d2 1c 88 d9 7e bb
|
||||
00000b0 4f bb 3a 3f 75 f1 5d 7f 8f c2 68 67 77 8f 25 ff
|
||||
00000c0 84 e2 93 2d ef a4 95 3d 71 4e 2c b9 b0 87 c3 be
|
||||
00000d0 3d f8 a7 60 24 61 c5 ef ae 9e c8 6c 6d 4e 69 c8
|
||||
00000e0 67 65 34 f8 37 76 2d 76 5c 54 f3 95 65 49 c7 0f
|
||||
00000f0 18 71 4b 7e 5b 6a d1 79 47 61 41 b0 4e 2a 74 45
|
||||
0000100 43 58 12 b2 5a a5 c6 7d 68 55 88 d4 98 75 18 6d
|
||||
0000110 08 d1 1f 8f 5a 9e 96 ee 45 cf a4 84 4e 4b e8 50
|
||||
0000120 a7 13 d9 06 de 52 81 97 36 b2 d7 b8 fc 2b 5f 55
|
||||
0000130 23 1f 32 59 cf 30 27 fb e2 8a b9 de 45 dd 63 9c
|
||||
0000140 4b b5 8b 96 4c 7a 62 62 cc a1 a7 cf fa f1 fe dd
|
||||
0000150 54 62 11 bf 36 78 b3 c7 b1 b5 f2 61 4d 4e dd 66
|
||||
0000160 32 2e e6 70 34 5f f4 c9 e6 6c 43 6f da 6b c6 c3
|
||||
0000170 09 2c ce 09 57 7f d2 7e b4 23 ba 7c 1b 99 bc 22
|
||||
0000180 3e f1 de 91 2f e3 9c 1b 82 cc c2 84 39 aa e6 de
|
||||
0000190 b4 69 fc cc cb 72 a6 61 45 f0 d3 1d 26 19 7c 8d
|
||||
00001a0 29 c8 66 02 be 77 6a f9 3d 34 79 17 19 c8 96 24
|
||||
00001b0 a3 ac e4 dd 3b 1a 8e c6 fe 96 38 6b bf 67 5a 23
|
||||
00001c0 f4 16 f4 e6 8a b4 fc c2 cd bf 95 66 1d bb 35 aa
|
||||
00001d0 92 7d 66 d8 08 8d a5 1f 54 2a af 09 cf 61 ff d2
|
||||
00001e0 85 9d 8f b6 d7 88 07 4a 86 03 db 64 f3 d9 92 73
|
||||
00001f0 df ec a7 fc 23 4c 8d 83 79 63 2a d9 fd 8d b3 c8
|
||||
0000200 8f 7e d4 19 85 e6 8d 1c 76 f0 8b 58 32 fd 9a d6
|
||||
0000210 85 e2 48 ad c3 d5 60 6f 7e 22 dd ef 09 49 7c 7f
|
||||
0000220 3a 45 c3 71 b7 df f3 4c 63 fb b5 d9 31 5f 6e d6
|
||||
0000230 24 1d a4 4a fe 32 a7 5c 16 48 5c 3e 08 6b 8a d3
|
||||
0000240 25 1d a2 12 a5 59 24 ea 20 5f 52 6d ad 94 db 6b
|
||||
0000250 94 b9 5d eb 4b a7 5c 44 bb 1e f2 3c 6b cf 52 c9
|
||||
0000260 e9 e5 ba 06 b9 c4 e5 0a d0 00 0d d0 00 0d d0 00
|
||||
0000270 0d d0 00 0d d0 00 0d d0 00 0d d0 00 0d d0 00 0d
|
||||
0000280 d0 00 0d d0 00 0d d0 00 0d d0 00 0d d0 00 0d d0
|
||||
0000290 00 0d d0 00 0d d0 00 0d d0 00 0d d0 00 0d d0 00
|
||||
00002a0 0d d0 00 cd ff 9e 46 86 fa a7 7d 3a 43 d7 8e 10
|
||||
00002b0 52 e9 be e6 6e cf eb 9e 85 4d 65 ce cc 30 c1 44
|
||||
00002c0 c0 4e af bc 9c 6c 4b a0 d7 54 ff 1d d5 5c 89 fb
|
||||
00002d0 b5 34 7e c4 c2 9e f5 a0 f6 5b 7e 6e ca 73 c7 ef
|
||||
00002e0 5d be de f9 e8 81 eb a5 0a a5 63 54 2c d7 1c d1
|
||||
00002f0 89 17 85 f8 16 94 f2 8a b2 a3 f5 b6 6d df 75 cd
|
||||
0000300 90 dd 64 bd 5d 55 4e f2 55 19 1b b7 cc ef 1b ea
|
||||
0000310 2e 05 9c f4 aa 1e a8 cd a6 82 c7 59 0f 5e 9d e0
|
||||
0000320 bb fc 6c d6 99 23 eb 36 ad c6 c5 e1 d8 e1 e2 3e
|
||||
0000330 d9 90 5a f7 91 5d 6f bc 33 6d 98 47 d2 7c 2e 2f
|
||||
0000340 99 a4 25 72 85 49 2c be 0b 5b af 8f e5 6e 81 a6
|
||||
0000350 a3 5a 6f 39 53 3a ab 7a 8b 1e 26 f7 46 6c 7d 26
|
||||
0000360 53 b3 22 31 94 d3 83 f2 18 4d f5 92 33 27 53 97
|
||||
0000370 0f d3 e6 55 9c a6 c5 31 87 6f d3 f3 ae 39 6f 56
|
||||
0000380 10 7b ab 7e d0 b4 ca f2 b8 05 be 3f 0e 6e 5a 75
|
||||
0000390 ab 0c f5 37 0e ba 8e 75 71 7a aa ed 7a dd 6a 63
|
||||
00003a0 be 9b a0 97 27 6a 6f e7 d3 8b c4 7c ec d3 91 56
|
||||
00003b0 d9 ac 5e bf 16 42 2f 00 1f 93 a2 23 87 bd e2 59
|
||||
00003c0 a0 de 1a 66 c8 62 eb 55 8f 91 17 b4 61 42 7a 50
|
||||
00003d0 40 03 34 40 03 34 40 03 34 40 03 34 40 03 34 40
|
||||
00003e0 03 34 40 03 34 40 03 34 40 03 34 40 03 34 40 03
|
||||
00003f0 34 40 03 34 40 03 34 ff 85 86 90 8b ea 67 90 0d
|
||||
0000400 e1 42 1b d2 61 d6 79 ec fd 3e 44 28 a4 51 6c 5c
|
||||
0000410 fc d2 72 ca ba 82 18 46 16 61 cd 93 a9 0f d1 24
|
||||
0000420 17 99 e2 2c 71 16 84 0c c8 7a 13 0f 9a 5e c5 f0
|
||||
0000430 79 64 e2 12 4d c8 82 a1 81 19 2d aa 44 6d 87 54
|
||||
0000440 84 71 c1 f6 d4 ca 25 8c 77 b9 08 c7 c8 5e 10 8a
|
||||
0000450 8f 61 ed 8c ba 30 1f 79 9a c7 60 34 2b b9 8c f8
|
||||
0000460 18 a6 83 1b e3 9f ad 79 fe fd 1b 8b f1 fc 41 6f
|
||||
0000470 d4 13 1f e3 b8 83 ba 64 92 e7 eb e4 77 05 8f ba
|
||||
0000480 fa 3b 00 00 ff ff 50 4b 07 08 a6 18 b1 91 5e 04
|
||||
0000490 00 00 e4 47 00 00 50 4b 01 02 14 00 14 00 08 00
|
||||
00004a0 08 00 00 00 00 00 a6 18 b1 91 5e 04 00 00 e4 47
|
||||
00004b0 00 00 0a 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
00004c0 00 00 00 00 62 69 67 67 65 72 2e 7a 69 70 50 4b
|
||||
00004d0 05 06 00 00 00 00 01 00 01 00 38 00 00 00 96 04
|
||||
00004e0 00 00 00 00`
|
||||
s = regexp.MustCompile(`[0-9a-f]{7}`).ReplaceAllString(s, "")
|
||||
s = regexp.MustCompile(`\s+`).ReplaceAllString(s, "")
|
||||
b, err := hex.DecodeString(s)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func returnBigZipBytes() (r io.ReaderAt, size int64) {
|
||||
b := biggestZipBytes()
|
||||
for i := 0; i < 2; i++ {
|
||||
r, err := NewReader(bytes.NewReader(b), int64(len(b)))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
f, err := r.File[0].Open()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
b, err = ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
return bytes.NewReader(b), int64(len(b))
|
||||
}
|
||||
|
||||
func TestIssue8186(t *testing.T) {
|
||||
// Directory headers & data found in the TOC of a JAR file.
|
||||
dirEnts := []string{
|
||||
|
|
|
|||
|
|
@ -12,15 +12,19 @@ import (
|
|||
"sync"
|
||||
)
|
||||
|
||||
// A Compressor returns a compressing writer, writing to the
|
||||
// provided writer. On Close, any pending data should be flushed.
|
||||
type Compressor func(io.Writer) (io.WriteCloser, error)
|
||||
// A Compressor returns a new compressing writer, writing to w.
|
||||
// The WriteCloser's Close method must be used to flush pending data to w.
|
||||
// The Compressor itself must be safe to invoke from multiple goroutines
|
||||
// simultaneously, but each returned writer will be used only by
|
||||
// one goroutine at a time.
|
||||
type Compressor func(w io.Writer) (io.WriteCloser, error)
|
||||
|
||||
// Decompressor is a function that wraps a Reader with a decompressing Reader.
|
||||
// The decompressed ReadCloser is returned to callers who open files from
|
||||
// within the archive. These callers are responsible for closing this reader
|
||||
// when they're finished reading.
|
||||
type Decompressor func(io.Reader) io.ReadCloser
|
||||
// A Decompressor returns a new decompressing reader, reading from r.
|
||||
// The ReadCloser's Close method must be used to release associated resources.
|
||||
// The Decompressor itself must be safe to invoke from multiple goroutines
|
||||
// simultaneously, but each returned reader will be used only by
|
||||
// one goroutine at a time.
|
||||
type Decompressor func(r io.Reader) io.ReadCloser
|
||||
|
||||
var flateWriterPool sync.Pool
|
||||
|
||||
|
|
@ -75,14 +79,15 @@ var (
|
|||
)
|
||||
|
||||
// RegisterDecompressor allows custom decompressors for a specified method ID.
|
||||
func RegisterDecompressor(method uint16, d Decompressor) {
|
||||
// The common methods Store and Deflate are built in.
|
||||
func RegisterDecompressor(method uint16, dcomp Decompressor) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
if _, ok := decompressors[method]; ok {
|
||||
panic("decompressor already registered")
|
||||
}
|
||||
decompressors[method] = d
|
||||
decompressors[method] = dcomp
|
||||
}
|
||||
|
||||
// RegisterCompressor registers custom compressors for a specified method ID.
|
||||
|
|
|
|||
|
|
@ -162,11 +162,11 @@ func archX86(linkArch *obj.LinkArch) *Arch {
|
|||
instructions["MOVDQ2Q"] = x86.AMOVQ
|
||||
instructions["MOVNTDQ"] = x86.AMOVNTO
|
||||
instructions["MOVOA"] = x86.AMOVO
|
||||
instructions["MOVOA"] = x86.AMOVO
|
||||
instructions["PF2ID"] = x86.APF2IL
|
||||
instructions["PI2FD"] = x86.API2FL
|
||||
instructions["PSLLDQ"] = x86.APSLLO
|
||||
instructions["PSRLDQ"] = x86.APSRLO
|
||||
instructions["PADDD"] = x86.APADDL
|
||||
|
||||
return &Arch{
|
||||
LinkArch: linkArch,
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ var armSCOND = map[string]uint8{
|
|||
var armJump = map[string]bool{
|
||||
"B": true,
|
||||
"BL": true,
|
||||
"BX": true,
|
||||
"BEQ": true,
|
||||
"BNE": true,
|
||||
"BCS": true,
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ func (p *Parser) append(prog *obj.Prog, cond string, doLabel bool) {
|
|||
fmt.Println(p.histLineNum, prog)
|
||||
}
|
||||
if testOut != nil {
|
||||
fmt.Fprintln(testOut, p.histLineNum, prog)
|
||||
fmt.Fprintln(testOut, prog)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,9 +8,11 @@ import (
|
|||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
|
|
@ -22,74 +24,368 @@ import (
|
|||
// Output is generated by, in effect, turning on -S and comparing the
|
||||
// result against a golden file.
|
||||
|
||||
func testEndToEnd(t *testing.T, goarch string) {
|
||||
func testEndToEnd(t *testing.T, goarch, file string) {
|
||||
lex.InitHist()
|
||||
input := filepath.Join("testdata", goarch+".s")
|
||||
output := filepath.Join("testdata", goarch+".out")
|
||||
input := filepath.Join("testdata", file+".s")
|
||||
architecture, ctxt := setArch(goarch)
|
||||
lexer := lex.NewLexer(input, ctxt)
|
||||
parser := NewParser(ctxt, architecture, lexer)
|
||||
pList := obj.Linknewplist(ctxt)
|
||||
var ok bool
|
||||
testOut = new(bytes.Buffer) // The assembler writes -S output to this buffer.
|
||||
testOut = new(bytes.Buffer) // The assembler writes test output to this buffer.
|
||||
ctxt.Bso = obj.Binitw(os.Stdout)
|
||||
defer ctxt.Bso.Flush()
|
||||
ctxt.Diag = log.Fatalf
|
||||
obj.Binitw(ioutil.Discard)
|
||||
failed := false
|
||||
ctxt.DiagFunc = func(format string, args ...interface{}) {
|
||||
failed = true
|
||||
t.Errorf(format, args...)
|
||||
}
|
||||
pList.Firstpc, ok = parser.Parse()
|
||||
if !ok {
|
||||
t.Fatalf("asm: %s assembly failed", goarch)
|
||||
if !ok || failed {
|
||||
t.Errorf("asm: %s assembly failed", goarch)
|
||||
return
|
||||
}
|
||||
result := string(testOut.Bytes())
|
||||
expect, err := ioutil.ReadFile(output)
|
||||
// For Windows.
|
||||
result = strings.Replace(result, `testdata\`, `testdata/`, -1)
|
||||
output := strings.Split(testOut.String(), "\n")
|
||||
|
||||
// Reconstruct expected output by independently "parsing" the input.
|
||||
data, err := ioutil.ReadFile(input)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
if result != string(expect) {
|
||||
if false { // Enable to capture output.
|
||||
fmt.Printf("%s", result)
|
||||
os.Exit(1)
|
||||
lineno := 0
|
||||
seq := 0
|
||||
hexByLine := map[string]string{}
|
||||
lines := strings.SplitAfter(string(data), "\n")
|
||||
Diff:
|
||||
for _, line := range lines {
|
||||
lineno++
|
||||
|
||||
// The general form of a test input line is:
|
||||
// // comment
|
||||
// INST args [// printed form] [// hex encoding]
|
||||
parts := strings.Split(line, "//")
|
||||
printed := strings.TrimSpace(parts[0])
|
||||
if printed == "" || strings.HasSuffix(printed, ":") { // empty or label
|
||||
continue
|
||||
}
|
||||
t.Errorf("%s failed: output differs", goarch)
|
||||
r := strings.Split(result, "\n")
|
||||
e := strings.Split(string(expect), "\n")
|
||||
if len(r) != len(e) {
|
||||
t.Errorf("%s: expected %d lines, got %d", goarch, len(e), len(r))
|
||||
}
|
||||
n := len(e)
|
||||
if n > len(r) {
|
||||
n = len(r)
|
||||
}
|
||||
for i := 0; i < n; i++ {
|
||||
if r[i] != e[i] {
|
||||
t.Errorf("%s:%d:\nexpected\n\t%s\ngot\n\t%s", output, i, e[i], r[i])
|
||||
seq++
|
||||
|
||||
var hexes string
|
||||
switch len(parts) {
|
||||
default:
|
||||
t.Errorf("%s:%d: unable to understand comments: %s", input, lineno, line)
|
||||
case 1:
|
||||
// no comment
|
||||
case 2:
|
||||
// might be printed form or hex
|
||||
note := strings.TrimSpace(parts[1])
|
||||
if isHexes(note) {
|
||||
hexes = note
|
||||
} else {
|
||||
printed = note
|
||||
}
|
||||
case 3:
|
||||
// printed form, then hex
|
||||
printed = strings.TrimSpace(parts[1])
|
||||
hexes = strings.TrimSpace(parts[2])
|
||||
if !isHexes(hexes) {
|
||||
t.Errorf("%s:%d: malformed hex instruction encoding: %s", input, lineno, line)
|
||||
}
|
||||
}
|
||||
|
||||
if hexes != "" {
|
||||
hexByLine[fmt.Sprintf("%s:%d", input, lineno)] = hexes
|
||||
}
|
||||
|
||||
// Canonicalize spacing in printed form.
|
||||
// First field is opcode, then tab, then arguments separated by spaces.
|
||||
// Canonicalize spaces after commas first.
|
||||
// Comma to separate argument gets a space; comma within does not.
|
||||
var buf []byte
|
||||
nest := 0
|
||||
for i := 0; i < len(printed); i++ {
|
||||
c := printed[i]
|
||||
switch c {
|
||||
case '{', '[':
|
||||
nest++
|
||||
case '}', ']':
|
||||
nest--
|
||||
case ',':
|
||||
buf = append(buf, ',')
|
||||
if nest == 0 {
|
||||
buf = append(buf, ' ')
|
||||
}
|
||||
for i+1 < len(printed) && (printed[i+1] == ' ' || printed[i+1] == '\t') {
|
||||
i++
|
||||
}
|
||||
continue
|
||||
}
|
||||
buf = append(buf, c)
|
||||
}
|
||||
|
||||
f := strings.Fields(string(buf))
|
||||
|
||||
// Turn relative (PC) into absolute (PC) automatically,
|
||||
// so that most branch instructions don't need comments
|
||||
// giving the absolute form.
|
||||
if len(f) > 0 && strings.HasSuffix(printed, "(PC)") {
|
||||
last := f[len(f)-1]
|
||||
n, err := strconv.Atoi(last[:len(last)-len("(PC)")])
|
||||
if err == nil {
|
||||
f[len(f)-1] = fmt.Sprintf("%d(PC)", seq+n)
|
||||
}
|
||||
}
|
||||
|
||||
if len(f) == 1 {
|
||||
printed = f[0]
|
||||
} else {
|
||||
printed = f[0] + "\t" + strings.Join(f[1:], " ")
|
||||
}
|
||||
|
||||
want := fmt.Sprintf("%05d (%s:%d)\t%s", seq, input, lineno, printed)
|
||||
for len(output) > 0 && (output[0] < want || output[0] != want && len(output[0]) >= 5 && output[0][:5] == want[:5]) {
|
||||
if len(output[0]) >= 5 && output[0][:5] == want[:5] {
|
||||
t.Errorf("mismatched output:\nhave %s\nwant %s", output[0], want)
|
||||
output = output[1:]
|
||||
continue Diff
|
||||
}
|
||||
t.Errorf("unexpected output: %q", output[0])
|
||||
output = output[1:]
|
||||
}
|
||||
if len(output) > 0 && output[0] == want {
|
||||
output = output[1:]
|
||||
} else {
|
||||
t.Errorf("missing output: %q", want)
|
||||
}
|
||||
}
|
||||
for len(output) > 0 {
|
||||
if output[0] == "" {
|
||||
// spurious blank caused by Split on "\n"
|
||||
output = output[1:]
|
||||
continue
|
||||
}
|
||||
t.Errorf("unexpected output: %q", output[0])
|
||||
output = output[1:]
|
||||
}
|
||||
|
||||
// Checked printing.
|
||||
// Now check machine code layout.
|
||||
|
||||
top := pList.Firstpc
|
||||
var text *obj.LSym
|
||||
ok = true
|
||||
ctxt.DiagFunc = func(format string, args ...interface{}) {
|
||||
t.Errorf(format, args...)
|
||||
ok = false
|
||||
}
|
||||
obj.Flushplist(ctxt)
|
||||
|
||||
for p := top; p != nil; p = p.Link {
|
||||
if p.As == obj.ATEXT {
|
||||
text = p.From.Sym
|
||||
}
|
||||
hexes := hexByLine[p.Line()]
|
||||
if hexes == "" {
|
||||
continue
|
||||
}
|
||||
delete(hexByLine, p.Line())
|
||||
if text == nil {
|
||||
t.Errorf("%s: instruction outside TEXT", p)
|
||||
}
|
||||
size := int64(len(text.P)) - p.Pc
|
||||
if p.Link != nil {
|
||||
size = p.Link.Pc - p.Pc
|
||||
} else if p.Isize != 0 {
|
||||
size = int64(p.Isize)
|
||||
}
|
||||
var code []byte
|
||||
if p.Pc < int64(len(text.P)) {
|
||||
code = text.P[p.Pc:]
|
||||
if size < int64(len(code)) {
|
||||
code = code[:size]
|
||||
}
|
||||
}
|
||||
codeHex := fmt.Sprintf("%x", code)
|
||||
if codeHex == "" {
|
||||
codeHex = "empty"
|
||||
}
|
||||
ok := false
|
||||
for _, hex := range strings.Split(hexes, " or ") {
|
||||
if codeHex == hex {
|
||||
ok = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
t.Errorf("%s: have encoding %s, want %s", p, codeHex, hexes)
|
||||
}
|
||||
}
|
||||
|
||||
if len(hexByLine) > 0 {
|
||||
var missing []string
|
||||
for key := range hexByLine {
|
||||
missing = append(missing, key)
|
||||
}
|
||||
sort.Strings(missing)
|
||||
for _, line := range missing {
|
||||
t.Errorf("%s: did not find instruction encoding", line)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestPPC64EndToEnd(t *testing.T) {
|
||||
testEndToEnd(t, "ppc64")
|
||||
func isHexes(s string) bool {
|
||||
if s == "" {
|
||||
return false
|
||||
}
|
||||
if s == "empty" {
|
||||
return true
|
||||
}
|
||||
for _, f := range strings.Split(s, " or ") {
|
||||
if f == "" || len(f)%2 != 0 || strings.TrimLeft(f, "0123456789abcdef") != "" {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func TestARMEndToEnd(t *testing.T) {
|
||||
testEndToEnd(t, "arm")
|
||||
}
|
||||
// It would be nice if the error messages began with
|
||||
// the standard file:line: prefix,
|
||||
// but that's not where we are today.
|
||||
// It might be at the beginning but it might be in the middle of the printed instruction.
|
||||
var fileLineRE = regexp.MustCompile(`(?:^|\()(testdata[/\\][0-9a-z]+\.s:[0-9]+)(?:$|\))`)
|
||||
|
||||
func TestARM64EndToEnd(t *testing.T) {
|
||||
testEndToEnd(t, "arm64")
|
||||
}
|
||||
// Same as in test/run.go
|
||||
var (
|
||||
errRE = regexp.MustCompile(`// ERROR ?(.*)`)
|
||||
errQuotesRE = regexp.MustCompile(`"([^"]*)"`)
|
||||
)
|
||||
|
||||
func TestAMD64EndToEnd(t *testing.T) {
|
||||
testEndToEnd(t, "amd64")
|
||||
func testErrors(t *testing.T, goarch, file string) {
|
||||
lex.InitHist()
|
||||
input := filepath.Join("testdata", file+".s")
|
||||
architecture, ctxt := setArch(goarch)
|
||||
lexer := lex.NewLexer(input, ctxt)
|
||||
parser := NewParser(ctxt, architecture, lexer)
|
||||
pList := obj.Linknewplist(ctxt)
|
||||
var ok bool
|
||||
testOut = new(bytes.Buffer) // The assembler writes test output to this buffer.
|
||||
ctxt.Bso = obj.Binitw(os.Stdout)
|
||||
defer ctxt.Bso.Flush()
|
||||
failed := false
|
||||
var errBuf bytes.Buffer
|
||||
ctxt.DiagFunc = func(format string, args ...interface{}) {
|
||||
failed = true
|
||||
s := fmt.Sprintf(format, args...)
|
||||
if !strings.HasSuffix(s, "\n") {
|
||||
s += "\n"
|
||||
}
|
||||
errBuf.WriteString(s)
|
||||
}
|
||||
pList.Firstpc, ok = parser.Parse()
|
||||
obj.Flushplist(ctxt)
|
||||
if ok && !failed {
|
||||
t.Errorf("asm: %s had no errors", goarch)
|
||||
}
|
||||
|
||||
errors := map[string]string{}
|
||||
for _, line := range strings.Split(errBuf.String(), "\n") {
|
||||
if line == "" || strings.HasPrefix(line, "\t") {
|
||||
continue
|
||||
}
|
||||
m := fileLineRE.FindStringSubmatch(line)
|
||||
if m == nil {
|
||||
t.Errorf("unexpected error: %v", line)
|
||||
continue
|
||||
}
|
||||
fileline := m[1]
|
||||
if errors[fileline] != "" {
|
||||
t.Errorf("multiple errors on %s:\n\t%s\n\t%s", fileline, errors[fileline], line)
|
||||
continue
|
||||
}
|
||||
errors[fileline] = line
|
||||
}
|
||||
|
||||
// Reconstruct expected errors by independently "parsing" the input.
|
||||
data, err := ioutil.ReadFile(input)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
lineno := 0
|
||||
lines := strings.Split(string(data), "\n")
|
||||
for _, line := range lines {
|
||||
lineno++
|
||||
|
||||
fileline := fmt.Sprintf("%s:%d", input, lineno)
|
||||
if m := errRE.FindStringSubmatch(line); m != nil {
|
||||
all := m[1]
|
||||
mm := errQuotesRE.FindAllStringSubmatch(all, -1)
|
||||
if len(mm) != 1 {
|
||||
t.Errorf("%s: invalid errorcheck line:\n%s", fileline, line)
|
||||
} else if err := errors[fileline]; err == "" {
|
||||
t.Errorf("%s: missing error, want %s", fileline, all)
|
||||
} else if !strings.Contains(err, mm[0][1]) {
|
||||
t.Errorf("%s: wrong error for %s:\n%s", fileline, all, err)
|
||||
}
|
||||
} else {
|
||||
if errors[fileline] != "" {
|
||||
t.Errorf("unexpected error on %s: %v", fileline, errors[fileline])
|
||||
}
|
||||
}
|
||||
delete(errors, fileline)
|
||||
}
|
||||
var extra []string
|
||||
for key := range errors {
|
||||
extra = append(extra, key)
|
||||
}
|
||||
sort.Strings(extra)
|
||||
for _, fileline := range extra {
|
||||
t.Errorf("unexpected error on %s: %v", fileline, errors[fileline])
|
||||
}
|
||||
}
|
||||
|
||||
func Test386EndToEnd(t *testing.T) {
|
||||
testEndToEnd(t, "386")
|
||||
defer os.Setenv("GO386", os.Getenv("GO386"))
|
||||
|
||||
for _, go386 := range []string{"387", "sse"} {
|
||||
os.Setenv("GO386", go386)
|
||||
t.Logf("GO386=%v", os.Getenv("GO386"))
|
||||
testEndToEnd(t, "386", "386")
|
||||
}
|
||||
}
|
||||
|
||||
func TestARMEndToEnd(t *testing.T) {
|
||||
defer os.Setenv("GOARM", os.Getenv("GOARM"))
|
||||
|
||||
for _, goarm := range []string{"5", "6", "7"} {
|
||||
os.Setenv("GOARM", goarm)
|
||||
t.Logf("GOARM=%v", os.Getenv("GOARM"))
|
||||
testEndToEnd(t, "arm", "arm")
|
||||
}
|
||||
}
|
||||
|
||||
func TestARM64EndToEnd(t *testing.T) {
|
||||
testEndToEnd(t, "arm64", "arm64")
|
||||
}
|
||||
|
||||
func TestAMD64EndToEnd(t *testing.T) {
|
||||
testEndToEnd(t, "amd64", "amd64")
|
||||
}
|
||||
|
||||
func TestAMD64Encoder(t *testing.T) {
|
||||
testEndToEnd(t, "amd64", "amd64enc")
|
||||
}
|
||||
|
||||
func TestAMD64Errors(t *testing.T) {
|
||||
testErrors(t, "amd64", "amd64error")
|
||||
}
|
||||
|
||||
func TestMIPS64EndToEnd(t *testing.T) {
|
||||
testEndToEnd(t, "mips64")
|
||||
testEndToEnd(t, "mips64", "mips64")
|
||||
}
|
||||
|
||||
func TestPPC64EndToEnd(t *testing.T) {
|
||||
testEndToEnd(t, "ppc64", "ppc64")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,6 +127,9 @@ var amd64OperandTests = []operandTest{
|
|||
{"(SI)(BX*1)", "(SI)(BX*1)"},
|
||||
{"(SI)(DX*1)", "(SI)(DX*1)"},
|
||||
{"(SP)", "(SP)"},
|
||||
{"(SP)(AX*4)", "(SP)(AX*4)"},
|
||||
{"32(SP)(BX*2)", "32(SP)(BX*2)"},
|
||||
{"32323(SP)(R8*4)", "32323(SP)(R8*4)"},
|
||||
{"+3(PC)", "3(PC)"},
|
||||
{"-1(DI)(BX*1)", "-1(DI)(BX*1)"},
|
||||
{"-3(PC)", "-3(PC)"},
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import (
|
|||
"unicode/utf8"
|
||||
|
||||
"cmd/asm/internal/arch"
|
||||
"cmd/asm/internal/flags"
|
||||
"cmd/asm/internal/lex"
|
||||
"cmd/internal/obj"
|
||||
)
|
||||
|
|
@ -78,7 +79,7 @@ func (p *Parser) errorf(format string, args ...interface{}) {
|
|||
}
|
||||
fmt.Fprintf(p.errorWriter, format, args...)
|
||||
p.errorCount++
|
||||
if p.errorCount > 10 {
|
||||
if p.errorCount > 10 && !*flags.AllErrors {
|
||||
log.Fatal("too many errors")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
49
src/cmd/asm/internal/asm/testdata/386.out
vendored
49
src/cmd/asm/internal/asm/testdata/386.out
vendored
|
|
@ -1,49 +0,0 @@
|
|||
5 00001 (testdata/386.s:5) TEXT foo(SB), 0, $0
|
||||
8 00002 (testdata/386.s:8) SETCC AX
|
||||
9 00003 (testdata/386.s:9) SETCC foo+4(SB)
|
||||
12 00004 (testdata/386.s:12) DIVB AX
|
||||
13 00005 (testdata/386.s:13) DIVB foo+4(SB)
|
||||
14 00006 (testdata/386.s:14) PUSHL $foo+4(SB)
|
||||
15 00007 (testdata/386.s:15) POPL AX
|
||||
18 00008 (testdata/386.s:18) SUBB $1, AX
|
||||
19 00009 (testdata/386.s:19) SUBB $1, foo+4(SB)
|
||||
20 00010 (testdata/386.s:20) SUBB BX, AX
|
||||
21 00011 (testdata/386.s:21) SUBB BX, foo+4(SB)
|
||||
24 00012 (testdata/386.s:24) CMPB AX, $1
|
||||
25 00013 (testdata/386.s:25) CMPB foo+4(SB), $4
|
||||
26 00014 (testdata/386.s:26) CMPB BX, AX
|
||||
27 00015 (testdata/386.s:27) CMPB foo+4(SB), BX
|
||||
31 00016 (testdata/386.s:31) JCS
|
||||
32 00017 (testdata/386.s:32) JCS 16(PC)
|
||||
35 00018 (testdata/386.s:35) CALL AX
|
||||
36 00019 (testdata/386.s:36) JMP AX
|
||||
37 00020 (testdata/386.s:37) CALL *foo(SB)
|
||||
38 00021 (testdata/386.s:38) JMP $4
|
||||
39 00022 (testdata/386.s:39) JMP 16
|
||||
40 00023 (testdata/386.s:40) CALL foo(SB)
|
||||
42 00024 (testdata/386.s:42) CALL foo+4(SB)(AX*4)
|
||||
43 00025 (testdata/386.s:43) CALL 4(SP)
|
||||
44 00026 (testdata/386.s:44) CALL (AX)
|
||||
45 00027 (testdata/386.s:45) CALL (SP)
|
||||
47 00028 (testdata/386.s:47) CALL (AX)(AX*4)
|
||||
48 00029 (testdata/386.s:48) CALL 4(SP)
|
||||
49 00030 (testdata/386.s:49) CALL (AX)
|
||||
50 00031 (testdata/386.s:50) CALL (SP)
|
||||
52 00032 (testdata/386.s:52) JMP (AX)(AX*4)
|
||||
55 00033 (testdata/386.s:55) NOP
|
||||
56 00034 (testdata/386.s:56) NOP AX
|
||||
57 00035 (testdata/386.s:57) NOP foo+4(SB)
|
||||
60 00036 (testdata/386.s:60) SHLL $4, BX
|
||||
61 00037 (testdata/386.s:61) SHLL $4, foo+4(SB)
|
||||
62 00038 (testdata/386.s:62) SHLL $4, AX, foo+4(SB)
|
||||
65 00039 (testdata/386.s:65) MOVL AX, BX
|
||||
66 00040 (testdata/386.s:66) MOVL $4, BX
|
||||
69 00041 (testdata/386.s:69) IMULL AX
|
||||
70 00042 (testdata/386.s:70) IMULL $4, CX
|
||||
71 00043 (testdata/386.s:71) IMULL AX, BX
|
||||
74 00044 (testdata/386.s:74) CMPPD X0, X1, 4
|
||||
75 00045 (testdata/386.s:75) CMPPD X0, foo+4(SB), 4
|
||||
78 00046 (testdata/386.s:78) PINSRD $1, (AX), X0
|
||||
79 00047 (testdata/386.s:79) PINSRD $2, foo+4(FP), X0
|
||||
83 00048 (testdata/386.s:83) LOOP
|
||||
86 00049 (testdata/386.s:86) RET
|
||||
37
src/cmd/asm/internal/asm/testdata/386.s
vendored
37
src/cmd/asm/internal/asm/testdata/386.s
vendored
|
|
@ -2,7 +2,7 @@
|
|||
// the old assembler's (8a's) grammar and hand-writing complete
|
||||
// instructions for each rule, to guarantee we cover the same space.
|
||||
|
||||
TEXT foo(SB), 0, $0
|
||||
TEXT foo(SB), 7, $0
|
||||
|
||||
// LTYPE1 nonrem { outcode(int($1), &$2); }
|
||||
SETCC AX
|
||||
|
|
@ -12,7 +12,7 @@ TEXT foo(SB), 0, $0
|
|||
DIVB AX
|
||||
DIVB foo+4(SB)
|
||||
PUSHL $foo+4(SB)
|
||||
POPL AX // balance PUSHL
|
||||
POPL AX
|
||||
|
||||
// LTYPE3 rimrem { outcode(int($1), &$2); }
|
||||
SUBB $1, AX
|
||||
|
|
@ -28,27 +28,31 @@ TEXT foo(SB), 0, $0
|
|||
|
||||
// LTYPER nonrel { outcode(int($1), &$2); }
|
||||
label:
|
||||
JC label
|
||||
JC -1(PC)
|
||||
JC label // JCS
|
||||
JC -1(PC) // JCS -1(PC)
|
||||
|
||||
// LTYPEC spec3 { outcode(int($1), &$2); }
|
||||
CALL AX
|
||||
JMP *AX
|
||||
JCS 2(PC)
|
||||
JMP *AX // JMP AX
|
||||
CALL *foo(SB)
|
||||
JCS 2(PC)
|
||||
JMP $4
|
||||
JMP label
|
||||
JCS 2(PC)
|
||||
JMP label // JMP 16
|
||||
CALL foo(SB)
|
||||
CALL (AX*4)
|
||||
// CALL (AX*4) // TODO: This line is silently dropped on the floor!
|
||||
CALL foo+4(SB)(AX*4)
|
||||
CALL *4(SP)
|
||||
CALL *(AX)
|
||||
CALL *(SP)
|
||||
CALL *(AX*4)
|
||||
CALL *(AX)(AX*4)
|
||||
CALL *4(SP) // CALL 4(SP)
|
||||
CALL *(AX) // CALL (AX)
|
||||
CALL *(SP) // CALL (SP)
|
||||
// CALL *(AX*4) // TODO: This line is silently dropped on the floor!
|
||||
CALL *(AX)(AX*4) // CALL (AX)(AX*4)
|
||||
CALL 4(SP)
|
||||
CALL (AX)
|
||||
CALL (SP)
|
||||
CALL (AX*4)
|
||||
// CALL (AX*4) // TODO: This line is silently dropped on the floor!
|
||||
JCS 2(PC)
|
||||
JMP (AX)(AX*4)
|
||||
|
||||
// LTYPEN spec4 { outcode(int($1), &$2); }
|
||||
|
|
@ -59,7 +63,7 @@ label:
|
|||
// LTYPES spec5 { outcode(int($1), &$2); }
|
||||
SHLL $4, BX
|
||||
SHLL $4, foo+4(SB)
|
||||
SHLL $4, foo+4(SB):AX
|
||||
SHLL $4, foo+4(SB):AX // SHLL $4, AX, foo+4(SB)
|
||||
|
||||
// LTYPEM spec6 { outcode(int($1), &$2); }
|
||||
MOVL AX, BX
|
||||
|
|
@ -72,15 +76,16 @@ label:
|
|||
|
||||
// LTYPEXC spec9 { outcode(int($1), &$2); }
|
||||
CMPPD X0, X1, 4
|
||||
CMPPD X0, foo+4(SB), 4
|
||||
CMPPD foo+4(SB), X1, 4
|
||||
|
||||
// LTYPEX spec10 { outcode(int($1), &$2); }
|
||||
PINSRD $1, (AX), X0
|
||||
PINSRD $2, foo+4(FP), X0
|
||||
|
||||
// Was bug: LOOP is a branch instruction.
|
||||
JCS 2(PC)
|
||||
loop:
|
||||
LOOP loop
|
||||
LOOP loop // LOOP
|
||||
|
||||
// LTYPE0 nonnon { outcode(int($1), &$2); }
|
||||
RET
|
||||
|
|
|
|||
57
src/cmd/asm/internal/asm/testdata/amd64.out
vendored
57
src/cmd/asm/internal/asm/testdata/amd64.out
vendored
|
|
@ -1,57 +0,0 @@
|
|||
9 00001 (testdata/amd64.s:9) TEXT foo(SB), 0, $0
|
||||
12 00002 (testdata/amd64.s:12) NEGQ R11
|
||||
13 00003 (testdata/amd64.s:13) NEGQ 4(R11)
|
||||
14 00004 (testdata/amd64.s:14) NEGQ foo+4(SB)
|
||||
17 00005 (testdata/amd64.s:17) INT $4
|
||||
18 00006 (testdata/amd64.s:18) DIVB R11
|
||||
19 00007 (testdata/amd64.s:19) DIVB 4(R11)
|
||||
20 00008 (testdata/amd64.s:20) DIVB foo+4(SB)
|
||||
23 00009 (testdata/amd64.s:23) SUBQ $4, DI
|
||||
24 00010 (testdata/amd64.s:24) SUBQ R11, DI
|
||||
25 00011 (testdata/amd64.s:25) SUBQ 4(R11), DI
|
||||
26 00012 (testdata/amd64.s:26) SUBQ foo+4(SB), DI
|
||||
27 00013 (testdata/amd64.s:27) SUBQ $4, 8(R12)
|
||||
28 00014 (testdata/amd64.s:28) SUBQ R11, 8(R12)
|
||||
29 00015 (testdata/amd64.s:29) SUBQ R11, foo+4(SB)
|
||||
32 00016 (testdata/amd64.s:32) CMPB CX, $4
|
||||
36 00017 (testdata/amd64.s:36) JCS 13(PC)
|
||||
37 00018 (testdata/amd64.s:37) JCS 17
|
||||
40 00019 (testdata/amd64.s:40) JMP 15(PC)
|
||||
41 00020 (testdata/amd64.s:41) JMP 17
|
||||
42 00021 (testdata/amd64.s:42) JMP foo+4(SB)
|
||||
43 00022 (testdata/amd64.s:43) JMP bar<>+4(SB)
|
||||
44 00023 (testdata/amd64.s:44) JMP bar<>+4(SB)(R11*4)
|
||||
45 00024 (testdata/amd64.s:45) JMP 4(SP)
|
||||
46 00025 (testdata/amd64.s:46) JMP (R12)
|
||||
48 00026 (testdata/amd64.s:48) JMP (R12)(R13*4)
|
||||
49 00027 (testdata/amd64.s:49) JMP (AX)
|
||||
50 00028 (testdata/amd64.s:50) JMP (SP)
|
||||
52 00029 (testdata/amd64.s:52) JMP (AX)(AX*4)
|
||||
53 00030 (testdata/amd64.s:53) JMP 4(SP)
|
||||
54 00031 (testdata/amd64.s:54) JMP (R12)
|
||||
56 00032 (testdata/amd64.s:56) JMP (R12)(R13*4)
|
||||
57 00033 (testdata/amd64.s:57) JMP (AX)
|
||||
58 00034 (testdata/amd64.s:58) JMP (SP)
|
||||
60 00035 (testdata/amd64.s:60) JMP (AX)(AX*4)
|
||||
61 00036 (testdata/amd64.s:61) JMP R13
|
||||
64 00037 (testdata/amd64.s:64) NOP
|
||||
65 00038 (testdata/amd64.s:65) NOP AX
|
||||
66 00039 (testdata/amd64.s:66) NOP foo+4(SB)
|
||||
69 00040 (testdata/amd64.s:69) SHLL R11, R12
|
||||
70 00041 (testdata/amd64.s:70) SHLL R11, foo+4(SB)
|
||||
71 00042 (testdata/amd64.s:71) SHLL R11, AX, R11
|
||||
74 00043 (testdata/amd64.s:74) MOVL AX, R11
|
||||
75 00044 (testdata/amd64.s:75) MOVL $4, R11
|
||||
76 00045 (testdata/amd64.s:76) MOVL AX, CS, AX
|
||||
79 00046 (testdata/amd64.s:79) IMULB $4
|
||||
80 00047 (testdata/amd64.s:80) IMULB R11
|
||||
81 00048 (testdata/amd64.s:81) IMULB $4, R11
|
||||
82 00049 (testdata/amd64.s:82) IMULB R11, R12
|
||||
83 00050 (testdata/amd64.s:83) IMULB R11, foo+4(SB)
|
||||
86 00051 (testdata/amd64.s:86) CMPPD R11, R12, 4
|
||||
87 00052 (testdata/amd64.s:87) CMPPD R11, foo+4(SB), 4
|
||||
90 00053 (testdata/amd64.s:90) PINSRW $4, R11, AX
|
||||
91 00054 (testdata/amd64.s:91) PINSRW $4, foo+4(SB), AX
|
||||
94 00055 (testdata/amd64.s:94) RETFL $4
|
||||
98 00056 (testdata/amd64.s:98) LOOP
|
||||
101 00057 (testdata/amd64.s:101) RET
|
||||
102
src/cmd/asm/internal/asm/testdata/amd64.s
vendored
102
src/cmd/asm/internal/asm/testdata/amd64.s
vendored
|
|
@ -6,7 +6,7 @@
|
|||
// the old assembler's (6a's) grammar and hand-writing complete
|
||||
// instructions for each rule, to guarantee we cover the same space.
|
||||
|
||||
TEXT foo(SB), 0, $0
|
||||
TEXT foo(SB), 7, $0
|
||||
|
||||
// LTYPE1 nonrem { outcode($1, &$2); }
|
||||
NEGQ R11
|
||||
|
|
@ -33,31 +33,53 @@ TEXT foo(SB), 0, $0
|
|||
|
||||
// LTYPER nonrel { outcode($1, &$2); }
|
||||
label:
|
||||
JB -4(PC)
|
||||
JB label
|
||||
JB -4(PC) // JCS -4(PC)
|
||||
JB label // JCS 17
|
||||
|
||||
// LTYPEC spec3 { outcode($1, &$2); }
|
||||
JCS 2(PC)
|
||||
JMP -4(PC)
|
||||
JMP label
|
||||
JCS 2(PC)
|
||||
JMP label // JMP 17
|
||||
JCS 2(PC)
|
||||
JMP foo+4(SB)
|
||||
JCS 2(PC)
|
||||
JMP bar<>+4(SB)
|
||||
JCS 2(PC)
|
||||
JMP bar<>+4(SB)(R11*4)
|
||||
JMP *4(SP)
|
||||
JMP *(R12)
|
||||
JMP *(R12*4)
|
||||
JMP *(R12)(R13*4)
|
||||
JMP *(AX)
|
||||
JMP *(SP)
|
||||
JMP *(AX*4)
|
||||
JMP *(AX)(AX*4)
|
||||
JCS 2(PC)
|
||||
JMP *4(SP) // JMP 4(SP)
|
||||
JCS 2(PC)
|
||||
JMP *(R12) // JMP (R12)
|
||||
JCS 2(PC)
|
||||
// JMP *(R12*4) // TODO: This line is silently dropped on the floor!
|
||||
JCS 2(PC)
|
||||
JMP *(R12)(R13*4) // JMP (R12)(R13*4)
|
||||
JCS 2(PC)
|
||||
JMP *(AX) // JMP (AX)
|
||||
JCS 2(PC)
|
||||
JMP *(SP) // JMP (SP)
|
||||
JCS 2(PC)
|
||||
// JMP *(AX*4) // TODO: This line is silently dropped on the floor!
|
||||
JCS 2(PC)
|
||||
JMP *(AX)(AX*4) // JMP (AX)(AX*4)
|
||||
JCS 2(PC)
|
||||
JMP 4(SP)
|
||||
JCS 2(PC)
|
||||
JMP (R12)
|
||||
JMP (R12*4)
|
||||
JCS 2(PC)
|
||||
// JMP (R12*4) // TODO: This line is silently dropped on the floor!
|
||||
JCS 2(PC)
|
||||
JMP (R12)(R13*4)
|
||||
JCS 2(PC)
|
||||
JMP (AX)
|
||||
JCS 2(PC)
|
||||
JMP (SP)
|
||||
JMP (AX*4)
|
||||
JCS 2(PC)
|
||||
// JMP (AX*4) // TODO: This line is silently dropped on the floor!
|
||||
JCS 2(PC)
|
||||
JMP (AX)(AX*4)
|
||||
JCS 2(PC)
|
||||
JMP R13
|
||||
|
||||
// LTYPEN spec4 { outcode($1, &$2); }
|
||||
|
|
@ -66,36 +88,58 @@ label:
|
|||
NOP foo+4(SB)
|
||||
|
||||
// LTYPES spec5 { outcode($1, &$2); }
|
||||
SHLL R11, R12
|
||||
SHLL R11, foo+4(SB)
|
||||
SHLL R11, R11:AX // Old syntax, still accepted.
|
||||
SHLL CX, R12
|
||||
SHLL CX, foo+4(SB)
|
||||
// Old syntax, still accepted:
|
||||
SHLL CX, R11:AX // SHLL CX, AX, R11
|
||||
|
||||
// LTYPEM spec6 { outcode($1, &$2); }
|
||||
MOVL AX, R11
|
||||
MOVL $4, R11
|
||||
MOVL AX, AX:CS
|
||||
// MOVL AX, 0(AX):DS // no longer works - did it ever?
|
||||
|
||||
// LTYPEI spec7 { outcode($1, &$2); }
|
||||
IMULB $4
|
||||
IMULB R11
|
||||
IMULB $4, R11
|
||||
IMULB R11, R12
|
||||
IMULB R11, foo+4(SB)
|
||||
IMULB DX
|
||||
IMULW DX, BX
|
||||
IMULL R11, R12
|
||||
IMULQ foo+4(SB), R11
|
||||
|
||||
// LTYPEXC spec8 { outcode($1, &$2); }
|
||||
CMPPD R11, R12, 4
|
||||
CMPPD R11, foo+4(SB), 4
|
||||
CMPPD X1, X2, 4
|
||||
CMPPD foo+4(SB), X2, 4
|
||||
|
||||
// LTYPEX spec9 { outcode($1, &$2); }
|
||||
PINSRW $4, R11, AX
|
||||
PINSRW $4, foo+4(SB), AX
|
||||
PINSRW $4, AX, X2
|
||||
PINSRW $4, foo+4(SB), X2
|
||||
|
||||
// LTYPERT spec10 { outcode($1, &$2); }
|
||||
JCS 2(PC)
|
||||
RETFL $4
|
||||
|
||||
// Was bug: LOOP is a branch instruction.
|
||||
JCS 2(PC)
|
||||
loop:
|
||||
LOOP loop
|
||||
LOOP loop // LOOP
|
||||
|
||||
// Intel pseudonyms for our own renamings.
|
||||
PADDD M2, M1 // PADDL M2, M1
|
||||
MOVDQ2Q X1, M1 // MOVQ X1, M1
|
||||
MOVNTDQ X1, (AX) // MOVNTO X1, (AX)
|
||||
MOVOA (AX), X1 // MOVO (AX), X1
|
||||
|
||||
// Tests for SP indexed addresses.
|
||||
MOVQ foo(SP)(AX*1), BX // 488b1c04
|
||||
MOVQ foo+32(SP)(CX*2), DX // 488b544c20
|
||||
MOVQ foo+32323(SP)(R8*4), R9 // 4e8b8c84437e0000
|
||||
MOVL foo(SP)(SI*8), DI // 8b3cf4
|
||||
MOVL foo+32(SP)(R10*1), R11 // 468b5c1420
|
||||
MOVL foo+32323(SP)(R12*2), R13 // 468bac64437e0000
|
||||
MOVW foo(SP)(AX*4), R8 // 66448b0484
|
||||
MOVW foo+32(SP)(R9*8), CX // 66428b4ccc20
|
||||
MOVW foo+32323(SP)(AX*1), DX // 668b9404437e0000
|
||||
MOVB foo(SP)(AX*2), AL // 8a0444
|
||||
MOVB foo+32(SP)(CX*4), AH // 8a648c20
|
||||
MOVB foo+32323(SP)(CX*8), R9 // 448a8ccc437e0000
|
||||
|
||||
// LTYPE0 nonnon { outcode($1, &$2); }
|
||||
RET
|
||||
RET // c3
|
||||
|
|
|
|||
10682
src/cmd/asm/internal/asm/testdata/amd64enc.s
vendored
Normal file
10682
src/cmd/asm/internal/asm/testdata/amd64enc.s
vendored
Normal file
File diff suppressed because it is too large
Load diff
8
src/cmd/asm/internal/asm/testdata/amd64error.s
vendored
Normal file
8
src/cmd/asm/internal/asm/testdata/amd64error.s
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
// Copyright 2016 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.
|
||||
|
||||
TEXT errors(SB),$0
|
||||
MOVL foo<>(SB)(AX), AX // ERROR "invalid instruction"
|
||||
MOVL (AX)(SP*1), AX // ERROR "invalid instruction"
|
||||
RET
|
||||
60
src/cmd/asm/internal/asm/testdata/arm.out
vendored
60
src/cmd/asm/internal/asm/testdata/arm.out
vendored
|
|
@ -1,60 +0,0 @@
|
|||
9 00001 (testdata/arm.s:9) TEXT foo(SB), 0, $0
|
||||
18 00002 (testdata/arm.s:18) ADD $1, R2, R3
|
||||
19 00003 (testdata/arm.s:19) ADD R1<<R2, R3, R4
|
||||
20 00004 (testdata/arm.s:20) ADD R1>>R2, R3, R4
|
||||
21 00005 (testdata/arm.s:21) ADD R1@>R2, R3, R4
|
||||
22 00006 (testdata/arm.s:22) ADD R1->R2, R3, R4
|
||||
23 00007 (testdata/arm.s:23) ADD R1, R2, R3
|
||||
24 00008 (testdata/arm.s:24) ADD R1<<R2, R3, R4
|
||||
34 00009 (testdata/arm.s:34) ADD $1, R2
|
||||
35 00010 (testdata/arm.s:35) ADD R1<<R2, R3
|
||||
36 00011 (testdata/arm.s:36) ADD R1>>R2, R3
|
||||
37 00012 (testdata/arm.s:37) ADD R1@>R2, R3
|
||||
38 00013 (testdata/arm.s:38) ADD R1->R2, R3
|
||||
39 00014 (testdata/arm.s:39) ADD R1, R2
|
||||
48 00015 (testdata/arm.s:48) CLZ.S R1, R2
|
||||
57 00016 (testdata/arm.s:57) MOVW.S R1, R2
|
||||
58 00017 (testdata/arm.s:58) MOVW.S $1, R2
|
||||
59 00018 (testdata/arm.s:59) MOVW.S R1<<R2, R3
|
||||
68 00019 (testdata/arm.s:68) JMP.S 20(PC)
|
||||
74 00020 (testdata/arm.s:74) JMP.S (R2)
|
||||
75 00021 (testdata/arm.s:75) JMP.S foo(SB)
|
||||
76 00022 (testdata/arm.s:76) JMP.S bar<>(SB)
|
||||
85 00023 (testdata/arm.s:85) BX (R2)
|
||||
94 00024 (testdata/arm.s:94) BEQ 25(PC)
|
||||
103 00025 (testdata/arm.s:103) SWI.S R1
|
||||
104 00026 (testdata/arm.s:104) SWI.S (R1)
|
||||
105 00027 (testdata/arm.s:105) SWI.S foo(SB)
|
||||
114 00028 (testdata/arm.s:114) CMP.S $1, R2
|
||||
115 00029 (testdata/arm.s:115) CMP.S R1<<R2, R3
|
||||
116 00030 (testdata/arm.s:116) CMP.S R1, R2
|
||||
130 00031 (testdata/arm.s:130) MOVM (R1), [R2,R5,R8,g]
|
||||
131 00032 (testdata/arm.s:131) MOVM (R1), [R2,R3,R4,R5]
|
||||
132 00033 (testdata/arm.s:132) MOVM.S (R1), [R2]
|
||||
143 00034 (testdata/arm.s:143) MOVM [R2,R5,R8,g], (R1)
|
||||
144 00035 (testdata/arm.s:144) MOVM [R2,R3,R4,R5], (R1)
|
||||
145 00036 (testdata/arm.s:145) MOVM.S [R2], (R1)
|
||||
154 00037 (testdata/arm.s:154) STREX.S (R2), R1, R3
|
||||
160 00038 (testdata/arm.s:160) STREX.S (R2), R1, R1
|
||||
166 00039 (testdata/arm.s:166) STREX.S (R2), R3, R3
|
||||
175 00040 (testdata/arm.s:175) WORD $1234
|
||||
184 00041 (testdata/arm.s:184) ABSF.S F1, F2
|
||||
190 00042 (testdata/arm.s:190) ADDD.S F1, F2
|
||||
191 00043 (testdata/arm.s:191) ADDD.S $(0.5), F2
|
||||
197 00044 (testdata/arm.s:197) ADDD.S F1, F2, F3
|
||||
198 00045 (testdata/arm.s:198) ADDD.S $(0.5), F2, F3
|
||||
204 00046 (testdata/arm.s:204) CMPD.S F1, F2
|
||||
228 00047 (testdata/arm.s:228) MRC $8301712627
|
||||
229 00048 (testdata/arm.s:229) MRC $8300664051
|
||||
238 00049 (testdata/arm.s:238) MULL R1, R2, (R3, R4)
|
||||
250 00050 (testdata/arm.s:250) MULAWT R1, R2, R3, R4
|
||||
258 00051 (testdata/arm.s:258) PLD (R1)
|
||||
259 00052 (testdata/arm.s:259) PLD 4(R1)
|
||||
268 00053 (testdata/arm.s:268) RET
|
||||
272 00054 (testdata/arm.s:272) JMP foo(SB)
|
||||
273 00055 (testdata/arm.s:273) CALL foo(SB)
|
||||
274 00056 (testdata/arm.s:274) JMP foo(SB)
|
||||
275 00057 (testdata/arm.s:275) CALL foo(SB)
|
||||
278 00058 (testdata/arm.s:278) CMPF F1, F2
|
||||
279 00059 (testdata/arm.s:279) CMPD F1, F2
|
||||
288 00060 (testdata/arm.s:288) END
|
||||
47
src/cmd/asm/internal/asm/testdata/arm.s
vendored
47
src/cmd/asm/internal/asm/testdata/arm.s
vendored
|
|
@ -6,7 +6,7 @@
|
|||
// the old assembler's (5a's) grammar and hand-writing complete
|
||||
// instructions for each rule, to guarantee we cover the same space.
|
||||
|
||||
TEXT foo(SB), 0, $0
|
||||
TEXT foo(SB), 7, $0
|
||||
|
||||
// ADD
|
||||
//
|
||||
|
|
@ -21,7 +21,7 @@ TEXT foo(SB), 0, $0
|
|||
ADD R1@>R2, R3, R4
|
||||
ADD R1->R2, R3, R4
|
||||
ADD R1, R2, R3
|
||||
ADD R(1)<<R(2), R(3), R(4)
|
||||
ADD R(1)<<R(2), R(3), R(4) // ADD R1<<R2, R3, R4
|
||||
|
||||
// LTYPE1 cond imsr ',' spreg ',' // asm doesn't support trailing comma.
|
||||
// {
|
||||
|
|
@ -65,15 +65,16 @@ TEXT foo(SB), 0, $0
|
|||
// {
|
||||
// outcode($1, $2, &nullgen, 0, &$4);
|
||||
// }
|
||||
B.S 1(PC)
|
||||
B.EQ 1(PC) // BEQ 1(PC)
|
||||
|
||||
// LTYPE4 cond comma nireg
|
||||
// {
|
||||
// outcode($1, $2, &nullgen, 0, &$4);
|
||||
// }
|
||||
B.S (R2)
|
||||
B.S foo(SB)
|
||||
B.S bar<>(SB)
|
||||
BEQ 2(PC)
|
||||
B foo(SB) // JMP foo(SB)
|
||||
BEQ 2(PC)
|
||||
B bar<>(SB) // JMP bar<>(SB)
|
||||
|
||||
//
|
||||
// BX
|
||||
|
|
@ -82,7 +83,7 @@ TEXT foo(SB), 0, $0
|
|||
// {
|
||||
// outcode($1, Always, &nullgen, 0, &$3);
|
||||
// }
|
||||
BX (R2)
|
||||
BX (R0)
|
||||
|
||||
//
|
||||
// BEQ
|
||||
|
|
@ -100,9 +101,9 @@ TEXT foo(SB), 0, $0
|
|||
// {
|
||||
// outcode($1, $2, &nullgen, 0, &$4);
|
||||
// }
|
||||
SWI.S R1
|
||||
SWI.S $2
|
||||
SWI.S (R1)
|
||||
SWI.S foo(SB)
|
||||
// SWI.S foo(SB) - TODO: classifying foo(SB) as C_TLS_LE
|
||||
|
||||
//
|
||||
// CMP
|
||||
|
|
@ -127,8 +128,8 @@ TEXT foo(SB), 0, $0
|
|||
// g.Offset = int64($6);
|
||||
// outcode($1, $2, &$3, 0, &g);
|
||||
// }
|
||||
MOVM 0(R1), [R2,R5,R8,g]
|
||||
MOVM 0(R1), [R2-R5]
|
||||
MOVM 0(R1), [R2,R5,R8,g] // MOVM (R1), [R2,R5,R8,g]
|
||||
MOVM (R1), [R2-R5] // MOVM (R1), [R2,R3,R4,R5]
|
||||
MOVM.S (R1), [R2]
|
||||
|
||||
// LTYPE8 cond '[' reglist ']' ',' ioreg
|
||||
|
|
@ -140,8 +141,8 @@ TEXT foo(SB), 0, $0
|
|||
// g.Offset = int64($4);
|
||||
// outcode($1, $2, &g, 0, &$7);
|
||||
// }
|
||||
MOVM [R2,R5,R8,g], 0(R1)
|
||||
MOVM [R2-R5], 0(R1)
|
||||
MOVM [R2,R5,R8,g], 0(R1) // MOVM [R2,R5,R8,g], (R1)
|
||||
MOVM [R2-R5], (R1) // MOVM [R2,R3,R4,R5], (R1)
|
||||
MOVM.S [R2], (R1)
|
||||
|
||||
//
|
||||
|
|
@ -151,19 +152,19 @@ TEXT foo(SB), 0, $0
|
|||
// {
|
||||
// outcode($1, $2, &$5, int32($3.Reg), &$7);
|
||||
// }
|
||||
STREX.S R1, (R2), R3
|
||||
STREX.S R1, (R2), R3 // STREX.S (R2), R1, R3
|
||||
|
||||
// LTYPE9 cond reg ',' ireg
|
||||
// {
|
||||
// outcode($1, $2, &$5, int32($3.Reg), &$3);
|
||||
// }
|
||||
STREX.S R1, (R2)
|
||||
STREX.S R1, (R2) // STREX.S (R2), R1, R1
|
||||
|
||||
// LTYPE9 cond comma ireg ',' reg
|
||||
// {
|
||||
// outcode($1, $2, &$4, int32($6.Reg), &$6);
|
||||
// }
|
||||
STREX.S (R2), R3
|
||||
STREX.S (R2), R3 // STREX.S (R2), R3, R3
|
||||
|
||||
//
|
||||
// word
|
||||
|
|
@ -188,14 +189,13 @@ TEXT foo(SB), 0, $0
|
|||
// outcode($1, $2, &$3, 0, &$5);
|
||||
// }
|
||||
ADDD.S F1, F2
|
||||
ADDD.S $0.5, F2
|
||||
MOVF $0.5, F2 // MOVF $(0.5), F2
|
||||
|
||||
// LTYPEK cond frcon ',' LFREG ',' freg
|
||||
// {
|
||||
// outcode($1, $2, &$3, $5, &$7);
|
||||
// }
|
||||
ADDD.S F1, F2, F3
|
||||
ADDD.S $0.5, F2, F3
|
||||
|
||||
// LTYPEL cond freg ',' freg
|
||||
// {
|
||||
|
|
@ -225,8 +225,8 @@ TEXT foo(SB), 0, $0
|
|||
// (1<<4)); /* must be set */
|
||||
// outcode(AMRC, Always, &nullgen, 0, &g);
|
||||
// }
|
||||
MRC.S 4, 6, R1, C2, C3, 7
|
||||
MCR.S 4, 6, R1, C2, C3, 7
|
||||
MRC.S 4, 6, R1, C2, C3, 7 // MRC $8301712627
|
||||
MCR.S 4, 6, R1, C2, C3, 7 // MRC $8300664051
|
||||
|
||||
//
|
||||
// MULL r1,r2,(hi,lo)
|
||||
|
|
@ -265,12 +265,15 @@ TEXT foo(SB), 0, $0
|
|||
// {
|
||||
// outcode($1, $2, &nullgen, 0, &nullgen);
|
||||
// }
|
||||
BEQ 2(PC)
|
||||
RET
|
||||
|
||||
// More B/BL cases, and canonical names JMP, CALL.
|
||||
|
||||
B foo(SB)
|
||||
BL foo(SB)
|
||||
BEQ 2(PC)
|
||||
B foo(SB) // JMP foo(SB)
|
||||
BL foo(SB) // CALL foo(SB)
|
||||
BEQ 2(PC)
|
||||
JMP foo(SB)
|
||||
CALL foo(SB)
|
||||
|
||||
|
|
|
|||
55
src/cmd/asm/internal/asm/testdata/arm64.out
vendored
55
src/cmd/asm/internal/asm/testdata/arm64.out
vendored
|
|
@ -1,55 +0,0 @@
|
|||
9 00001 (testdata/arm64.s:9) TEXT foo(SB), 7, $-8
|
||||
20 00002 (testdata/arm64.s:20) ADDW $1, R2, R3
|
||||
21 00003 (testdata/arm64.s:21) ADDW R1, R2, R3
|
||||
22 00004 (testdata/arm64.s:22) ADDW R1, ZR, R3
|
||||
23 00005 (testdata/arm64.s:23) ADD $1, R2, R3
|
||||
24 00006 (testdata/arm64.s:24) ADD R1, R2, R3
|
||||
25 00007 (testdata/arm64.s:25) ADD R1, ZR, R3
|
||||
26 00008 (testdata/arm64.s:26) ADD $1, R2, R3
|
||||
36 00009 (testdata/arm64.s:36) ADDW $1, R2
|
||||
37 00010 (testdata/arm64.s:37) ADDW R1, R2
|
||||
38 00011 (testdata/arm64.s:38) ADD $1, R2
|
||||
39 00012 (testdata/arm64.s:39) ADD R1, R2
|
||||
48 00013 (testdata/arm64.s:48) CLSW R1, R2
|
||||
49 00014 (testdata/arm64.s:49) CLS R1, R2
|
||||
58 00015 (testdata/arm64.s:58) MOVW R1, R2
|
||||
59 00016 (testdata/arm64.s:59) MOVW ZR, R1
|
||||
60 00017 (testdata/arm64.s:60) MOVW R1, ZR
|
||||
61 00018 (testdata/arm64.s:61) MOVW $1, ZR
|
||||
62 00019 (testdata/arm64.s:62) MOVW $1, R1
|
||||
63 00020 (testdata/arm64.s:63) MOVW ZR, (R1)
|
||||
64 00021 (testdata/arm64.s:64) MOVD R1, R2
|
||||
65 00022 (testdata/arm64.s:65) MOVD ZR, R1
|
||||
66 00023 (testdata/arm64.s:66) MOVD $1, ZR
|
||||
67 00024 (testdata/arm64.s:67) MOVD $1, R1
|
||||
68 00025 (testdata/arm64.s:68) MOVD ZR, (R1)
|
||||
77 00026 (testdata/arm64.s:77) MOVK $1, R1
|
||||
86 00027 (testdata/arm64.s:86) CALL 28(PC)
|
||||
92 00028 (testdata/arm64.s:92) CALL (R2)
|
||||
93 00029 (testdata/arm64.s:93) CALL foo(SB)
|
||||
94 00030 (testdata/arm64.s:94) CALL bar<>(SB)
|
||||
102 00031 (testdata/arm64.s:102) BEQ 32(PC)
|
||||
110 00032 (testdata/arm64.s:110) SVC
|
||||
119 00033 (testdata/arm64.s:119) CMP $3, R2
|
||||
120 00034 (testdata/arm64.s:120) CMP R1, R2
|
||||
130 00035 (testdata/arm64.s:130) CBZ R1
|
||||
139 00036 (testdata/arm64.s:139) CSET GT, R1
|
||||
147 00037 (testdata/arm64.s:147) CSEL LT, R1, R2, ZR
|
||||
148 00038 (testdata/arm64.s:148) CSINC GT, R1, ZR, R3
|
||||
149 00039 (testdata/arm64.s:149) CSNEG MI, R1, R2, R3
|
||||
150 00040 (testdata/arm64.s:150) CSINV HS, R1, R2, R3
|
||||
156 00041 (testdata/arm64.s:156) CSEL LT, R1, R2
|
||||
164 00042 (testdata/arm64.s:164) CCMN MI, ZR, R1, $4
|
||||
173 00043 (testdata/arm64.s:173) FADDD $(0.5), F1
|
||||
174 00044 (testdata/arm64.s:174) FADDD F1, F2
|
||||
180 00045 (testdata/arm64.s:180) FADDD $(0.69999999999999996), F1, F2
|
||||
181 00046 (testdata/arm64.s:181) FADDD F1, F2, F3
|
||||
233 00047 (testdata/arm64.s:233) DMB $1
|
||||
242 00048 (testdata/arm64.s:242) LDAXRW (R0), R2
|
||||
243 00049 (testdata/arm64.s:243) STLXRW R1, (R0), R3
|
||||
251 00050 (testdata/arm64.s:251) RET
|
||||
255 00051 (testdata/arm64.s:255) JMP foo(SB)
|
||||
256 00052 (testdata/arm64.s:256) CALL foo(SB)
|
||||
257 00053 (testdata/arm64.s:257) JMP foo(SB)
|
||||
258 00054 (testdata/arm64.s:258) CALL foo(SB)
|
||||
266 00055 (testdata/arm64.s:266) END
|
||||
23
src/cmd/asm/internal/asm/testdata/arm64.s
vendored
23
src/cmd/asm/internal/asm/testdata/arm64.s
vendored
|
|
@ -83,15 +83,15 @@ TEXT foo(SB), 7, $-8
|
|||
// {
|
||||
// outcode($1, &nullgen, NREG, &$3);
|
||||
// }
|
||||
BL 1(PC)
|
||||
BL 1(PC) // CALL 1(PC)
|
||||
|
||||
// LTYPE4 comma nireg
|
||||
// {
|
||||
// outcode($1, &nullgen, NREG, &$3);
|
||||
// }
|
||||
BL (R2)
|
||||
BL foo(SB)
|
||||
BL bar<>(SB)
|
||||
BL (R2) // CALL (R2)
|
||||
BL foo(SB) // CALL foo(SB)
|
||||
BL bar<>(SB) // CALL bar<>(SB)
|
||||
//
|
||||
// BEQ
|
||||
//
|
||||
|
|
@ -127,7 +127,7 @@ TEXT foo(SB), 7, $-8
|
|||
// outcode($1, &$2, NREG, &$4);
|
||||
// }
|
||||
again:
|
||||
CBZ R1, again
|
||||
CBZ R1, again // CBZ R1
|
||||
|
||||
//
|
||||
// CSET
|
||||
|
|
@ -147,7 +147,7 @@ again:
|
|||
CSEL LT, R1, R2, ZR
|
||||
CSINC GT, R1, ZR, R3
|
||||
CSNEG MI, R1, R2, R3
|
||||
CSINV CS, R1, R2, R3
|
||||
CSINV CS, R1, R2, R3 // CSINV HS, R1, R2, R3
|
||||
|
||||
// LTYPES cond ',' reg ',' reg
|
||||
// {
|
||||
|
|
@ -170,14 +170,14 @@ again:
|
|||
// {
|
||||
// outcode($1, &$2, NREG, &$4);
|
||||
// }
|
||||
FADDD $0.5, F1
|
||||
FADDD $0.5, F1 // FADDD $(0.5), F1
|
||||
FADDD F1, F2
|
||||
|
||||
// LTYPEK frcon ',' freg ',' freg
|
||||
// {
|
||||
// outcode($1, &$2, $4.reg, &$6);
|
||||
// }
|
||||
FADDD $0.7, F1, F2
|
||||
FADDD $0.7, F1, F2 // FADDD $(0.69999999999999996), F1, F2
|
||||
FADDD F1, F2, F3
|
||||
|
||||
//
|
||||
|
|
@ -248,12 +248,15 @@ again:
|
|||
// {
|
||||
// outcode($1, &nullgen, NREG, &nullgen);
|
||||
// }
|
||||
BEQ 2(PC)
|
||||
RET
|
||||
|
||||
// More B/BL cases, and canonical names JMP, CALL.
|
||||
|
||||
B foo(SB)
|
||||
BL foo(SB)
|
||||
BEQ 2(PC)
|
||||
B foo(SB) // JMP foo(SB)
|
||||
BL foo(SB) // CALL foo(SB)
|
||||
BEQ 2(PC)
|
||||
JMP foo(SB)
|
||||
CALL foo(SB)
|
||||
|
||||
|
|
|
|||
99
src/cmd/asm/internal/asm/testdata/mips64.out
vendored
99
src/cmd/asm/internal/asm/testdata/mips64.out
vendored
|
|
@ -1,99 +0,0 @@
|
|||
8 00001 (testdata/mips64.s:8) TEXT foo(SB), 0, $0
|
||||
18 00002 (testdata/mips64.s:18) MOVW R1, R2
|
||||
19 00003 (testdata/mips64.s:19) MOVW LO, R1
|
||||
20 00004 (testdata/mips64.s:20) MOVW HI, R1
|
||||
21 00005 (testdata/mips64.s:21) MOVW R1, LO
|
||||
22 00006 (testdata/mips64.s:22) MOVW R1, HI
|
||||
23 00007 (testdata/mips64.s:23) MOVV R1, R2
|
||||
24 00008 (testdata/mips64.s:24) MOVV LO, R1
|
||||
25 00009 (testdata/mips64.s:25) MOVV HI, R1
|
||||
26 00010 (testdata/mips64.s:26) MOVV R1, LO
|
||||
27 00011 (testdata/mips64.s:27) MOVV R1, HI
|
||||
33 00012 (testdata/mips64.s:33) MOVW foo<>+3(SB), R2
|
||||
34 00013 (testdata/mips64.s:34) MOVW 16(R1), R2
|
||||
35 00014 (testdata/mips64.s:35) MOVW (R1), R2
|
||||
36 00015 (testdata/mips64.s:36) MOVV foo<>+3(SB), R2
|
||||
37 00016 (testdata/mips64.s:37) MOVV 16(R1), R2
|
||||
38 00017 (testdata/mips64.s:38) MOVV (R1), R2
|
||||
44 00018 (testdata/mips64.s:44) MOVB R1, R2
|
||||
50 00019 (testdata/mips64.s:50) MOVB foo<>+3(SB), R2
|
||||
51 00020 (testdata/mips64.s:51) MOVB 16(R1), R2
|
||||
52 00021 (testdata/mips64.s:52) MOVB (R1), R2
|
||||
61 00022 (testdata/mips64.s:61) MOVD foo<>+3(SB), F2
|
||||
62 00023 (testdata/mips64.s:62) MOVD 16(R1), F2
|
||||
63 00024 (testdata/mips64.s:63) MOVD (R1), F2
|
||||
69 00025 (testdata/mips64.s:69) MOVD $(0.10000000000000001), F2
|
||||
75 00026 (testdata/mips64.s:75) MOVD F1, F2
|
||||
81 00027 (testdata/mips64.s:81) MOVD F2, foo<>+3(SB)
|
||||
82 00028 (testdata/mips64.s:82) MOVD F2, 16(R1)
|
||||
83 00029 (testdata/mips64.s:83) MOVD F2, (R1)
|
||||
92 00030 (testdata/mips64.s:92) MOVW R1, foo<>+3(SB)
|
||||
93 00031 (testdata/mips64.s:93) MOVW R1, 16(R2)
|
||||
94 00032 (testdata/mips64.s:94) MOVW R1, (R2)
|
||||
95 00033 (testdata/mips64.s:95) MOVV R1, foo<>+3(SB)
|
||||
96 00034 (testdata/mips64.s:96) MOVV R1, 16(R2)
|
||||
97 00035 (testdata/mips64.s:97) MOVV R1, (R2)
|
||||
103 00036 (testdata/mips64.s:103) MOVB R1, foo<>+3(SB)
|
||||
104 00037 (testdata/mips64.s:104) MOVB R1, 16(R2)
|
||||
105 00038 (testdata/mips64.s:105) MOVB R1, (R2)
|
||||
114 00039 (testdata/mips64.s:114) MOVD F1, foo<>+3(SB)
|
||||
115 00040 (testdata/mips64.s:115) MOVD F1, 16(R2)
|
||||
116 00041 (testdata/mips64.s:116) MOVD F1, (R2)
|
||||
125 00042 (testdata/mips64.s:125) MOVW FCR0, R1
|
||||
131 00043 (testdata/mips64.s:131) MOVW R1, FCR0
|
||||
137 00044 (testdata/mips64.s:137) MOVW R1, M1
|
||||
138 00045 (testdata/mips64.s:138) MOVV R1, M1
|
||||
144 00046 (testdata/mips64.s:144) MOVW M1, R1
|
||||
145 00047 (testdata/mips64.s:145) MOVV M1, R1
|
||||
158 00048 (testdata/mips64.s:158) ADD R1, R2, R3
|
||||
164 00049 (testdata/mips64.s:164) ADD $1, R2, R3
|
||||
170 00050 (testdata/mips64.s:170) ADD R1, R2
|
||||
176 00051 (testdata/mips64.s:176) ADD $4, R1
|
||||
182 00052 (testdata/mips64.s:182) MUL R1, R2
|
||||
188 00053 (testdata/mips64.s:188) SLL R1, R2, R3
|
||||
194 00054 (testdata/mips64.s:194) SLL R1, R2
|
||||
200 00055 (testdata/mips64.s:200) SLL $4, R1, R2
|
||||
206 00056 (testdata/mips64.s:206) SLL $4, R1
|
||||
215 00057 (testdata/mips64.s:215) MOVW $1, R1
|
||||
216 00058 (testdata/mips64.s:216) MOVV $1, R1
|
||||
222 00059 (testdata/mips64.s:222) MOVW $1, R1
|
||||
223 00060 (testdata/mips64.s:223) MOVW $foo(SB), R1
|
||||
224 00061 (testdata/mips64.s:224) MOVV $1, R1
|
||||
225 00062 (testdata/mips64.s:225) MOVV $foo(SB), R1
|
||||
236 00063 (testdata/mips64.s:236) JMP 64(PC)
|
||||
237 00064 (testdata/mips64.s:237) JMP 63
|
||||
238 00065 (testdata/mips64.s:238) CALL 66(PC)
|
||||
239 00066 (testdata/mips64.s:239) CALL 63
|
||||
245 00067 (testdata/mips64.s:245) JMP 4(R1)
|
||||
246 00068 (testdata/mips64.s:246) JMP foo(SB)
|
||||
247 00069 (testdata/mips64.s:247) CALL 4(R1)
|
||||
248 00070 (testdata/mips64.s:248) CALL foo(SB)
|
||||
258 00071 (testdata/mips64.s:258) BEQ R1, 72(PC)
|
||||
259 00072 (testdata/mips64.s:259) BEQ R1, 71
|
||||
266 00073 (testdata/mips64.s:266) BEQ R1, R2, 74(PC)
|
||||
267 00074 (testdata/mips64.s:267) BEQ R1, R2, 73
|
||||
277 00075 (testdata/mips64.s:277) BLTZ R1, 76(PC)
|
||||
278 00076 (testdata/mips64.s:278) BLTZ R1, 75
|
||||
285 00077 (testdata/mips64.s:285) BFPT 78(PC)
|
||||
286 00078 (testdata/mips64.s:286) BFPT 77
|
||||
296 00079 (testdata/mips64.s:296) ABSD F1, F2
|
||||
302 00080 (testdata/mips64.s:302) ADDD F1, F2
|
||||
308 00081 (testdata/mips64.s:308) ADDD F1, F2, F3
|
||||
314 00082 (testdata/mips64.s:314) CMPEQD F1, F2
|
||||
320 00083 (testdata/mips64.s:320) WORD $1
|
||||
321 00084 (testdata/mips64.s:321) WORD $foo(SB)
|
||||
330 00085 (testdata/mips64.s:330) NOP
|
||||
336 00086 (testdata/mips64.s:336) NOP R2
|
||||
342 00087 (testdata/mips64.s:342) NOP F2
|
||||
348 00088 (testdata/mips64.s:348) NOP R2
|
||||
354 00089 (testdata/mips64.s:354) NOP F2
|
||||
360 00090 (testdata/mips64.s:360) NOP $4
|
||||
365 00091 (testdata/mips64.s:365) SYSCALL
|
||||
366 00092 (testdata/mips64.s:366) BREAK
|
||||
367 00093 (testdata/mips64.s:367) BREAK $1, (R1)
|
||||
376 00094 (testdata/mips64.s:376) SYSCALL
|
||||
377 00095 (testdata/mips64.s:377) RET
|
||||
382 00096 (testdata/mips64.s:382) CALL foo(SB)
|
||||
383 00097 (testdata/mips64.s:383) JMP foo(SB)
|
||||
384 00098 (testdata/mips64.s:384) CALL foo(SB)
|
||||
392 00099 (testdata/mips64.s:392) END
|
||||
41
src/cmd/asm/internal/asm/testdata/mips64.s
vendored
41
src/cmd/asm/internal/asm/testdata/mips64.s
vendored
|
|
@ -5,7 +5,7 @@
|
|||
// This input was created by taking the ppc64 testcase and modified
|
||||
// by hand.
|
||||
|
||||
TEXT foo(SB),0,$0
|
||||
TEXT foo(SB),7,$0
|
||||
|
||||
//inst:
|
||||
//
|
||||
|
|
@ -66,7 +66,7 @@ TEXT foo(SB),0,$0
|
|||
// {
|
||||
// outcode(int($1), &$2, 0, &$4);
|
||||
// }
|
||||
MOVD $0.1, F2
|
||||
MOVD $0.1, F2 // MOVD $(0.10000000000000001), F2
|
||||
|
||||
// LFMOV freg ',' freg
|
||||
// {
|
||||
|
|
@ -232,20 +232,28 @@ TEXT foo(SB),0,$0
|
|||
// {
|
||||
// outcode(int($1), &nullgen, 0, &$2);
|
||||
// }
|
||||
BEQ R1, 2(PC)
|
||||
label0:
|
||||
JMP 1(PC)
|
||||
JMP label0+0
|
||||
JAL 1(PC)
|
||||
JAL label0+0
|
||||
BEQ R1, 2(PC)
|
||||
JMP label0+0 // JMP 64
|
||||
BEQ R1, 2(PC)
|
||||
JAL 1(PC) // CALL 1(PC)
|
||||
BEQ R1, 2(PC)
|
||||
JAL label0+0 // CALL 64
|
||||
|
||||
// LBRA addr
|
||||
// {
|
||||
// outcode(int($1), &nullgen, 0, &$2);
|
||||
// }
|
||||
JMP 4(R1)
|
||||
JMP foo+0(SB)
|
||||
JAL 4(R1)
|
||||
JAL foo+0(SB)
|
||||
BEQ R1, 2(PC)
|
||||
JMP 0(R1) // JMP (R1)
|
||||
BEQ R1, 2(PC)
|
||||
JMP foo+0(SB) // JMP foo(SB)
|
||||
BEQ R1, 2(PC)
|
||||
JAL 0(R1) // CALL (R1)
|
||||
BEQ R1, 2(PC)
|
||||
JAL foo+0(SB) // CALL foo(SB)
|
||||
|
||||
//
|
||||
// BEQ/BNE
|
||||
|
|
@ -256,7 +264,7 @@ label0:
|
|||
// }
|
||||
label1:
|
||||
BEQ R1, 1(PC)
|
||||
BEQ R1, label1
|
||||
BEQ R1, label1 // BEQ R1, 79
|
||||
|
||||
// LBRA rreg ',' sreg ',' rel
|
||||
// {
|
||||
|
|
@ -264,7 +272,7 @@ label1:
|
|||
// }
|
||||
label2:
|
||||
BEQ R1, R2, 1(PC)
|
||||
BEQ R1, R2, label2
|
||||
BEQ R1, R2, label2 // BEQ R1, R2, 81
|
||||
|
||||
//
|
||||
// other integer conditional branch
|
||||
|
|
@ -275,7 +283,7 @@ label2:
|
|||
// }
|
||||
label3:
|
||||
BLTZ R1, 1(PC)
|
||||
BLTZ R1, label3
|
||||
BLTZ R1, label3 // BLTZ R1, 83
|
||||
|
||||
//
|
||||
// floating point conditional branch
|
||||
|
|
@ -283,7 +291,7 @@ label3:
|
|||
// LBRA rel
|
||||
label4:
|
||||
BFPT 1(PC)
|
||||
BFPT label4
|
||||
BFPT label4 // BFPT 85
|
||||
|
||||
|
||||
//
|
||||
|
|
@ -364,7 +372,8 @@ label4:
|
|||
//
|
||||
SYSCALL
|
||||
BREAK
|
||||
BREAK $1, (R1) // overloaded CACHE opcode
|
||||
// overloaded cache opcode:
|
||||
BREAK R1, (R1)
|
||||
|
||||
//
|
||||
// RET
|
||||
|
|
@ -374,12 +383,14 @@ label4:
|
|||
// outcode(int($1), &nullgen, 0, &nullgen);
|
||||
// }
|
||||
SYSCALL
|
||||
BEQ R1, 2(PC)
|
||||
RET
|
||||
|
||||
|
||||
// More JMP/JAL cases, and canonical names JMP, CALL.
|
||||
|
||||
JAL foo(SB)
|
||||
JAL foo(SB) // CALL foo(SB)
|
||||
BEQ R1, 2(PC)
|
||||
JMP foo(SB)
|
||||
CALL foo(SB)
|
||||
|
||||
|
|
|
|||
114
src/cmd/asm/internal/asm/testdata/ppc64.out
vendored
114
src/cmd/asm/internal/asm/testdata/ppc64.out
vendored
|
|
@ -1,114 +0,0 @@
|
|||
9 00001 (testdata/ppc64.s:9) TEXT foo(SB), 0, $0
|
||||
19 00002 (testdata/ppc64.s:19) MOVW R1, R2
|
||||
25 00003 (testdata/ppc64.s:25) MOVW foo<>+3(SB), R2
|
||||
26 00004 (testdata/ppc64.s:26) MOVW 16(R1), R2
|
||||
32 00005 (testdata/ppc64.s:32) MOVW (R1), R2
|
||||
33 00006 (testdata/ppc64.s:33) MOVW (R1)(R2*1), R3
|
||||
39 00007 (testdata/ppc64.s:39) MOVW R1, R2
|
||||
45 00008 (testdata/ppc64.s:45) MOVB foo<>+3(SB), R2
|
||||
46 00009 (testdata/ppc64.s:46) MOVB 16(R1), R2
|
||||
52 00010 (testdata/ppc64.s:52) MOVB (R1), R2
|
||||
53 00011 (testdata/ppc64.s:53) MOVB (R1)(R2*1), R3
|
||||
62 00012 (testdata/ppc64.s:62) FMOVD foo<>+3(SB), F2
|
||||
63 00013 (testdata/ppc64.s:63) FMOVD 16(R1), F2
|
||||
69 00014 (testdata/ppc64.s:69) FMOVD (R1), F2
|
||||
75 00015 (testdata/ppc64.s:75) FMOVD $(0.10000000000000001), F2
|
||||
81 00016 (testdata/ppc64.s:81) FMOVD F1, F2
|
||||
87 00017 (testdata/ppc64.s:87) FMOVD F2, foo<>+3(SB)
|
||||
88 00018 (testdata/ppc64.s:88) FMOVD F2, 16(R1)
|
||||
94 00019 (testdata/ppc64.s:94) FMOVD F2, (R1)
|
||||
103 00020 (testdata/ppc64.s:103) MOVW R1, foo<>+3(SB)
|
||||
104 00021 (testdata/ppc64.s:104) MOVW R1, 16(R2)
|
||||
110 00022 (testdata/ppc64.s:110) MOVW R1, (R1)
|
||||
111 00023 (testdata/ppc64.s:111) MOVW R1, (R2)(R3*1)
|
||||
117 00024 (testdata/ppc64.s:117) MOVB R1, foo<>+3(SB)
|
||||
118 00025 (testdata/ppc64.s:118) MOVB R1, 16(R2)
|
||||
124 00026 (testdata/ppc64.s:124) MOVB R1, (R1)
|
||||
125 00027 (testdata/ppc64.s:125) MOVB R1, (R2)(R3*1)
|
||||
133 00028 (testdata/ppc64.s:133) FMOVD F1, foo<>+3(SB)
|
||||
134 00029 (testdata/ppc64.s:134) FMOVD F1, 16(R2)
|
||||
140 00030 (testdata/ppc64.s:140) FMOVD F1, (R1)
|
||||
149 00031 (testdata/ppc64.s:149) MOVFL FPSCR, F1
|
||||
155 00032 (testdata/ppc64.s:155) MOVFL F1, FPSCR
|
||||
161 00033 (testdata/ppc64.s:161) MOVFL F1, $4, FPSCR
|
||||
167 00034 (testdata/ppc64.s:167) MOVFL FPSCR, CR0
|
||||
188 00035 (testdata/ppc64.s:188) MOVW R1, CR1
|
||||
194 00036 (testdata/ppc64.s:194) MOVW R1, CR
|
||||
206 00037 (testdata/ppc64.s:206) ADD R1, R2, R3
|
||||
212 00038 (testdata/ppc64.s:212) ADD $1, R2, R3
|
||||
224 00039 (testdata/ppc64.s:224) ADD R1, R2
|
||||
230 00040 (testdata/ppc64.s:230) ADD $4, R1
|
||||
236 00041 (testdata/ppc64.s:236) ADDE R1, R2, R3
|
||||
242 00042 (testdata/ppc64.s:242) ADDE R1, R2
|
||||
248 00043 (testdata/ppc64.s:248) SLW R1, R2, R3
|
||||
254 00044 (testdata/ppc64.s:254) SLW R1, R2
|
||||
260 00045 (testdata/ppc64.s:260) SLW $4, R1, R2
|
||||
266 00046 (testdata/ppc64.s:266) SLW $4, R1
|
||||
272 00047 (testdata/ppc64.s:272) SLW $4, R1
|
||||
278 00048 (testdata/ppc64.s:278) SUBME R1, R1
|
||||
296 00049 (testdata/ppc64.s:296) MOVW $1, R1
|
||||
302 00050 (testdata/ppc64.s:302) MOVW $1, R1
|
||||
303 00051 (testdata/ppc64.s:303) MOVW $foo(SB), R1
|
||||
327 00052 (testdata/ppc64.s:327) MOVFL CR0, CR1
|
||||
339 00053 (testdata/ppc64.s:339) MOVW CR, R1
|
||||
345 00054 (testdata/ppc64.s:345) MOVW SPR(0), R1
|
||||
346 00055 (testdata/ppc64.s:346) MOVW SPR(7), R1
|
||||
352 00056 (testdata/ppc64.s:352) MOVW LR, R1
|
||||
353 00057 (testdata/ppc64.s:353) MOVW CTR, R1
|
||||
359 00058 (testdata/ppc64.s:359) MOVW R1, LR
|
||||
360 00059 (testdata/ppc64.s:360) MOVW R1, CTR
|
||||
372 00060 (testdata/ppc64.s:372) MOVW R1, SPR(7)
|
||||
384 00061 (testdata/ppc64.s:384) JMP 62(PC)
|
||||
385 00062 (testdata/ppc64.s:385) JMP 61
|
||||
391 00063 (testdata/ppc64.s:391) JMP 4(R1)
|
||||
392 00064 (testdata/ppc64.s:392) JMP foo(SB)
|
||||
398 00065 (testdata/ppc64.s:398) JMP CTR
|
||||
417 00066 (testdata/ppc64.s:417) BEQ CR1, 67(PC)
|
||||
418 00067 (testdata/ppc64.s:418) BEQ CR1, 66
|
||||
444 00068 (testdata/ppc64.s:444) BC 4, CTR
|
||||
454 00069 (testdata/ppc64.s:454) BC $3, R4, 66
|
||||
474 00070 (testdata/ppc64.s:474) BC $3, R3, LR
|
||||
504 00071 (testdata/ppc64.s:504) FABS F1, F2
|
||||
510 00072 (testdata/ppc64.s:510) FADD F1, F2
|
||||
516 00073 (testdata/ppc64.s:516) FADD F1, F2, F3
|
||||
522 00074 (testdata/ppc64.s:522) FMADD F1, F2, F3, F4
|
||||
528 00075 (testdata/ppc64.s:528) FCMPU F1, F2
|
||||
534 00076 (testdata/ppc64.s:534) FCMPU F1, F2, CR0
|
||||
543 00077 (testdata/ppc64.s:543) CMP R1, R2
|
||||
549 00078 (testdata/ppc64.s:549) CMP R1, $4
|
||||
555 00079 (testdata/ppc64.s:555) CMP R1, CR0, R2
|
||||
561 00080 (testdata/ppc64.s:561) CMP R1, CR0, $4
|
||||
570 00081 (testdata/ppc64.s:570) RLDC $4, R1, $5, R2
|
||||
576 00082 (testdata/ppc64.s:576) RLDC $26, R1, $201326592, R2
|
||||
582 00083 (testdata/ppc64.s:582) RLDC R1, R2, $4, R3
|
||||
588 00084 (testdata/ppc64.s:588) RLWMI R1, R2, $201326592, R3
|
||||
597 00085 (testdata/ppc64.s:597) MOVMW foo(SB), R2
|
||||
598 00086 (testdata/ppc64.s:598) MOVMW 4(R1), R2
|
||||
604 00087 (testdata/ppc64.s:604) MOVMW R1, foo(SB)
|
||||
605 00088 (testdata/ppc64.s:605) MOVMW R1, 4(R2)
|
||||
615 00089 (testdata/ppc64.s:615) LSW (R1), R2
|
||||
616 00090 (testdata/ppc64.s:616) LSW (R1)(R2*1), R3
|
||||
622 00091 (testdata/ppc64.s:622) LSW (R1), $1, R2
|
||||
623 00092 (testdata/ppc64.s:623) LSW (R1)(R2*1), $1, R3
|
||||
629 00093 (testdata/ppc64.s:629) STSW R1, (R2)
|
||||
630 00094 (testdata/ppc64.s:630) STSW R1, (R2)(R3*1)
|
||||
636 00095 (testdata/ppc64.s:636) STSW R1, $1, (R2)
|
||||
637 00096 (testdata/ppc64.s:637) STSW R1, $1, (R2)(R3*1)
|
||||
643 00097 (testdata/ppc64.s:643) MOVHBR (R1), R2
|
||||
644 00098 (testdata/ppc64.s:644) MOVHBR (R1)(R2*1), R3
|
||||
650 00099 (testdata/ppc64.s:650) MOVHBR R1, (R2)
|
||||
651 00100 (testdata/ppc64.s:651) MOVHBR R1, (R2)(R3*1)
|
||||
657 00101 (testdata/ppc64.s:657) DCBF (R1)
|
||||
658 00102 (testdata/ppc64.s:658) DCBF (R1)(R2*1)
|
||||
667 00103 (testdata/ppc64.s:667) NOP
|
||||
673 00104 (testdata/ppc64.s:673) NOP R2
|
||||
679 00105 (testdata/ppc64.s:679) NOP F2
|
||||
685 00106 (testdata/ppc64.s:685) NOP R2
|
||||
691 00107 (testdata/ppc64.s:691) NOP F2
|
||||
697 00108 (testdata/ppc64.s:697) NOP $4
|
||||
705 00109 (testdata/ppc64.s:705) RET
|
||||
709 00110 (testdata/ppc64.s:709) JMP foo(SB)
|
||||
710 00111 (testdata/ppc64.s:710) CALL foo(SB)
|
||||
711 00112 (testdata/ppc64.s:711) JMP foo(SB)
|
||||
712 00113 (testdata/ppc64.s:712) CALL foo(SB)
|
||||
720 00114 (testdata/ppc64.s:720) END
|
||||
78
src/cmd/asm/internal/asm/testdata/ppc64.s
vendored
78
src/cmd/asm/internal/asm/testdata/ppc64.s
vendored
|
|
@ -6,7 +6,7 @@
|
|||
// the old assembler's (9a's) grammar and hand-writing complete
|
||||
// instructions for each rule, to guarantee we cover the same space.
|
||||
|
||||
TEXT foo(SB),0,$0
|
||||
TEXT foo(SB),7,$0
|
||||
|
||||
//inst:
|
||||
//
|
||||
|
|
@ -30,7 +30,7 @@ TEXT foo(SB),0,$0
|
|||
// outcode(int($1), &$2, 0, &$4);
|
||||
// }
|
||||
MOVW (R1), R2
|
||||
MOVW (R1+R2), R3
|
||||
MOVW (R1+R2), R3 // MOVW (R1)(R2*1), R3
|
||||
|
||||
// LMOVB rreg ',' rreg
|
||||
// {
|
||||
|
|
@ -50,7 +50,7 @@ TEXT foo(SB),0,$0
|
|||
// outcode(int($1), &$2, 0, &$4);
|
||||
// }
|
||||
MOVB (R1), R2
|
||||
MOVB (R1+R2), R3
|
||||
MOVB (R1+R2), R3 // MOVB (R1)(R2*1), R3
|
||||
|
||||
//
|
||||
// load floats
|
||||
|
|
@ -72,7 +72,7 @@ TEXT foo(SB),0,$0
|
|||
// {
|
||||
// outcode(int($1), &$2, 0, &$4);
|
||||
// }
|
||||
FMOVD $0.1, F2
|
||||
FMOVD $0.1, F2 // FMOVD $(0.10000000000000001), F2
|
||||
|
||||
// LFMOV freg ',' freg
|
||||
// {
|
||||
|
|
@ -108,7 +108,7 @@ TEXT foo(SB),0,$0
|
|||
// outcode(int($1), &$2, 0, &$4);
|
||||
// }
|
||||
MOVW R1, (R1)
|
||||
MOVW R1, (R2+R3)
|
||||
MOVW R1, (R2+R3) // MOVW R1, (R2)(R3*1)
|
||||
|
||||
// LMOVB rreg ',' addr
|
||||
// {
|
||||
|
|
@ -122,7 +122,7 @@ TEXT foo(SB),0,$0
|
|||
// outcode(int($1), &$2, 0, &$4);
|
||||
// }
|
||||
MOVB R1, (R1)
|
||||
MOVB R1, (R2+R3)
|
||||
MOVB R1, (R2+R3) // MOVB R1, (R2)(R3*1)
|
||||
//
|
||||
// store floats
|
||||
//
|
||||
|
|
@ -275,7 +275,7 @@ TEXT foo(SB),0,$0
|
|||
// {
|
||||
// outcode(int($1), &$2, 0, &$2);
|
||||
// }
|
||||
SUBME R1
|
||||
SUBME R1 // SUBME R1, R1
|
||||
|
||||
//
|
||||
// multiply-accumulate
|
||||
|
|
@ -380,22 +380,29 @@ TEXT foo(SB),0,$0
|
|||
// {
|
||||
// outcode(int($1), &nullgen, 0, &$2);
|
||||
// }
|
||||
BEQ CR1, 2(PC)
|
||||
label0:
|
||||
BR 1(PC)
|
||||
BR label0+0
|
||||
BR 1(PC) // JMP 1(PC)
|
||||
BEQ CR1, 2(PC)
|
||||
BR label0+0 // JMP 62
|
||||
|
||||
// LBRA addr
|
||||
// {
|
||||
// outcode(int($1), &nullgen, 0, &$2);
|
||||
// }
|
||||
BR 4(R1)
|
||||
BR foo+0(SB)
|
||||
BEQ CR1, 2(PC)
|
||||
BR LR // JMP LR
|
||||
BEQ CR1, 2(PC)
|
||||
// BR 0(R1) // TODO should work
|
||||
BEQ CR1, 2(PC)
|
||||
BR foo+0(SB) // JMP foo(SB)
|
||||
|
||||
// LBRA '(' xlreg ')'
|
||||
// {
|
||||
// outcode(int($1), &nullgen, 0, &$3);
|
||||
// }
|
||||
BR (CTR)
|
||||
BEQ CR1, 2(PC)
|
||||
BR (CTR) // JMP CTR
|
||||
|
||||
// LBRA ',' rel // asm doesn't support the leading comma
|
||||
// {
|
||||
|
|
@ -415,7 +422,7 @@ label0:
|
|||
// }
|
||||
label1:
|
||||
BEQ CR1, 1(PC)
|
||||
BEQ CR1, label1
|
||||
BEQ CR1, label1 // BEQ CR1, 72
|
||||
|
||||
// LBRA creg ',' addr // TODO DOES NOT WORK in 9a
|
||||
// {
|
||||
|
|
@ -441,7 +448,7 @@ label1:
|
|||
// {
|
||||
// outcode(int($1), &nullgen, int($2), &$5);
|
||||
// }
|
||||
BC 4, (CTR)
|
||||
// BC 4, (CTR) // TODO - should work
|
||||
|
||||
// LBRA con ',' con ',' rel
|
||||
// {
|
||||
|
|
@ -451,7 +458,7 @@ label1:
|
|||
// g.Offset = $2;
|
||||
// outcode(int($1), &g, int(REG_R0+$4), &$6);
|
||||
// }
|
||||
BC 3, 4, label1
|
||||
// BC 3, 4, label1 // TODO - should work
|
||||
|
||||
// LBRA con ',' con ',' addr // TODO mystery
|
||||
// {
|
||||
|
|
@ -471,7 +478,7 @@ label1:
|
|||
// g.Offset = $2;
|
||||
// outcode(int($1), &g, int(REG_R0+$4), &$7);
|
||||
// }
|
||||
BC 3, 3, (LR)
|
||||
BC 3, 3, (LR) // BC $3, R3, LR
|
||||
|
||||
//
|
||||
// conditional trap // TODO NOT DEFINED
|
||||
|
|
@ -531,7 +538,7 @@ label1:
|
|||
// {
|
||||
// outcode(int($1), &$2, int($6.Reg), &$4);
|
||||
// }
|
||||
FCMPU F1, F2, CR0
|
||||
// FCMPU F1, F2, CR0
|
||||
|
||||
//
|
||||
// CMP
|
||||
|
|
@ -552,13 +559,13 @@ label1:
|
|||
// {
|
||||
// outcode(int($1), &$2, int($6.Reg), &$4);
|
||||
// }
|
||||
CMP R1, R2, CR0
|
||||
CMP R1, R2, CR0 // CMP R1, CR0, R2
|
||||
|
||||
// LCMP rreg ',' imm ',' creg
|
||||
// {
|
||||
// outcode(int($1), &$2, int($6.Reg), &$4);
|
||||
// }
|
||||
CMP R1, $4, CR0
|
||||
CMP R1, $4, CR0 // CMP R1, CR0, $4
|
||||
|
||||
//
|
||||
// rotate and mask
|
||||
|
|
@ -567,25 +574,25 @@ label1:
|
|||
// {
|
||||
// outgcode(int($1), &$2, int($4.Reg), &$6, &$8);
|
||||
// }
|
||||
RLDC $4, R1, $5, R2
|
||||
RLDC $4, R1, $16, R2
|
||||
|
||||
// LRLWM imm ',' rreg ',' mask ',' rreg
|
||||
// {
|
||||
// outgcode(int($1), &$2, int($4.Reg), &$6, &$8);
|
||||
// }
|
||||
RLDC $26, R1, 4, 5, R2
|
||||
RLDC $26, R1, 4, 5, R2 // RLDC $26, R1, $201326592, R2
|
||||
|
||||
// LRLWM rreg ',' rreg ',' imm ',' rreg
|
||||
// {
|
||||
// outgcode(int($1), &$2, int($4.Reg), &$6, &$8);
|
||||
// }
|
||||
RLDC R1, R2, $4, R3
|
||||
RLDCL R1, R2, $7, R3
|
||||
|
||||
// LRLWM rreg ',' rreg ',' mask ',' rreg
|
||||
// {
|
||||
// outgcode(int($1), &$2, int($4.Reg), &$6, &$8);
|
||||
// }
|
||||
RLWMI R1, R2, 4, 5, R3
|
||||
RLWMI R1, R2, 4, 5, R3 // RLWMI R1, R2, $201326592, R3
|
||||
|
||||
//
|
||||
// load/store multiple
|
||||
|
|
@ -594,14 +601,14 @@ label1:
|
|||
// {
|
||||
// outcode(int($1), &$2, 0, &$4);
|
||||
// }
|
||||
MOVMW foo+0(SB), R2
|
||||
// MOVMW foo+0(SB), R2 // TODO TLS broke this!
|
||||
MOVMW 4(R1), R2
|
||||
|
||||
// LMOVMW rreg ',' addr
|
||||
// {
|
||||
// outcode(int($1), &$2, 0, &$4);
|
||||
// }
|
||||
MOVMW R1, foo+0(SB)
|
||||
// MOVMW R1, foo+0(SB) // TODO TLS broke this!
|
||||
MOVMW R1, 4(R2)
|
||||
|
||||
//
|
||||
|
|
@ -613,49 +620,49 @@ label1:
|
|||
// outcode(int($1), &$2, 0, &$4);
|
||||
// }
|
||||
LSW (R1), R2
|
||||
LSW (R1+R2), R3
|
||||
LSW (R1+R2), R3 // LSW (R1)(R2*1), R3
|
||||
|
||||
// LXLD regaddr ',' imm ',' rreg
|
||||
// {
|
||||
// outgcode(int($1), &$2, 0, &$4, &$6);
|
||||
// }
|
||||
LSW (R1), $1, R2
|
||||
LSW (R1+R2), $1, R3
|
||||
LSW (R1+R2), $1, R3 // LSW (R1)(R2*1), $1, R3
|
||||
|
||||
// LXST rreg ',' regaddr
|
||||
// {
|
||||
// outcode(int($1), &$2, 0, &$4);
|
||||
// }
|
||||
STSW R1, (R2)
|
||||
STSW R1, (R2+R3)
|
||||
STSW R1, (R2+R3) // STSW R1, (R2)(R3*1)
|
||||
|
||||
// LXST rreg ',' imm ',' regaddr
|
||||
// {
|
||||
// outgcode(int($1), &$2, 0, &$4, &$6);
|
||||
// }
|
||||
STSW R1, $1, (R2)
|
||||
STSW R1, $1, (R2+R3)
|
||||
STSW R1, $1, (R2+R3) // STSW R1, $1, (R2)(R3*1)
|
||||
|
||||
// LXMV regaddr ',' rreg
|
||||
// {
|
||||
// outcode(int($1), &$2, 0, &$4);
|
||||
// }
|
||||
MOVHBR (R1), R2
|
||||
MOVHBR (R1+R2), R3
|
||||
MOVHBR (R1+R2), R3 // MOVHBR (R1)(R2*1), R3
|
||||
|
||||
// LXMV rreg ',' regaddr
|
||||
// {
|
||||
// outcode(int($1), &$2, 0, &$4);
|
||||
// }
|
||||
MOVHBR R1, (R2)
|
||||
MOVHBR R1, (R2+R3)
|
||||
MOVHBR R1, (R2+R3) // MOVHBR R1, (R2)(R3*1)
|
||||
|
||||
// LXOP regaddr
|
||||
// {
|
||||
// outcode(int($1), &$2, 0, &nullgen);
|
||||
// }
|
||||
DCBF (R1)
|
||||
DCBF (R1+R2)
|
||||
DCBF (R1+R2) // DCBF (R1)(R2*1)
|
||||
|
||||
//
|
||||
// NOP
|
||||
|
|
@ -702,12 +709,15 @@ label1:
|
|||
// {
|
||||
// outcode(int($1), &nullgen, 0, &nullgen);
|
||||
// }
|
||||
BEQ 2(PC)
|
||||
RET
|
||||
|
||||
// More BR/BL cases, and canonical names JMP, CALL.
|
||||
|
||||
BR foo(SB)
|
||||
BL foo(SB)
|
||||
BEQ 2(PC)
|
||||
BR foo(SB) // JMP foo(SB)
|
||||
BL foo(SB) // CALL foo(SB)
|
||||
BEQ 2(PC)
|
||||
JMP foo(SB)
|
||||
CALL foo(SB)
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ var (
|
|||
TrimPath = flag.String("trimpath", "", "remove prefix from recorded source file paths")
|
||||
Shared = flag.Bool("shared", false, "generate code that can be linked into a shared library")
|
||||
Dynlink = flag.Bool("dynlink", false, "support references to Go symbols defined in other shared libraries")
|
||||
AllErrors = flag.Bool("e", false, "no limit on number of errors reported")
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
|||
|
|
@ -47,21 +47,28 @@ func main() {
|
|||
}
|
||||
ctxt.Bso = obj.Binitw(os.Stdout)
|
||||
defer ctxt.Bso.Flush()
|
||||
ctxt.Diag = log.Fatalf
|
||||
output := obj.Binitw(fd)
|
||||
fmt.Fprintf(output, "go object %s %s %s\n", obj.Getgoos(), obj.Getgoarch(), obj.Getgoversion())
|
||||
fmt.Fprintf(output, "!\n")
|
||||
|
||||
lexer := lex.NewLexer(flag.Arg(0), ctxt)
|
||||
parser := asm.NewParser(ctxt, architecture, lexer)
|
||||
diag := false
|
||||
ctxt.DiagFunc = func(format string, args ...interface{}) {
|
||||
diag = true
|
||||
log.Printf(format, args...)
|
||||
}
|
||||
pList := obj.Linknewplist(ctxt)
|
||||
var ok bool
|
||||
pList.Firstpc, ok = parser.Parse()
|
||||
if !ok {
|
||||
if ok {
|
||||
// reports errors to parser.Errorf
|
||||
obj.Writeobjdirect(ctxt, output)
|
||||
}
|
||||
if !ok || diag {
|
||||
log.Printf("asm: assembly of %s failed", flag.Arg(0))
|
||||
os.Remove(*flags.OutputFile)
|
||||
os.Exit(1)
|
||||
}
|
||||
obj.Writeobjdirect(ctxt, output)
|
||||
output.Flush()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -273,7 +273,7 @@ func (z *Int) Mod(x, y *Int) *Int {
|
|||
// DivMod implements Euclidean division and modulus (unlike Go):
|
||||
//
|
||||
// q = x div y such that
|
||||
// m = x - y*q with 0 <= m < |q|
|
||||
// m = x - y*q with 0 <= m < |y|
|
||||
//
|
||||
// (See Raymond T. Boute, ``The Euclidean definition of the functions
|
||||
// div and mod''. ACM Transactions on Programming Languages and
|
||||
|
|
|
|||
|
|
@ -544,6 +544,9 @@ var expTests = []struct {
|
|||
{"0x8000000000000000", "1000", "6719", "1603"},
|
||||
{"0x8000000000000000", "1000000", "6719", "3199"},
|
||||
{"0x8000000000000000", "-1000000", "6719", "1"},
|
||||
|
||||
{"0xffffffffffffffffffffffffffffffff", "0x12345678123456781234567812345678123456789", "0x01112222333344445555666677778889", "0x36168FA1DB3AAE6C8CE647E137F97A"},
|
||||
|
||||
{
|
||||
"2938462938472983472983659726349017249287491026512746239764525612965293865296239471239874193284792387498274256129746192347",
|
||||
"298472983472983471903246121093472394872319615612417471234712061",
|
||||
|
|
@ -551,12 +554,24 @@ var expTests = []struct {
|
|||
"23537740700184054162508175125554701713153216681790245129157191391322321508055833908509185839069455749219131480588829346291",
|
||||
},
|
||||
// test case for issue 8822
|
||||
{
|
||||
"11001289118363089646017359372117963499250546375269047542777928006103246876688756735760905680604646624353196869572752623285140408755420374049317646428185270079555372763503115646054602867593662923894140940837479507194934267532831694565516466765025434902348314525627418515646588160955862839022051353653052947073136084780742729727874803457643848197499548297570026926927502505634297079527299004267769780768565695459945235586892627059178884998772989397505061206395455591503771677500931269477503508150175717121828518985901959919560700853226255420793148986854391552859459511723547532575574664944815966793196961286234040892865",
|
||||
"0xB08FFB20760FFED58FADA86DFEF71AD72AA0FA763219618FE022C197E54708BB1191C66470250FCE8879487507CEE41381CA4D932F81C2B3F1AB20B539D50DCD",
|
||||
"0xAC6BDB41324A9A9BF166DE5E1389582FAF72B6651987EE07FC3192943DB56050A37329CBB4A099ED8193E0757767A13DD52312AB4B03310DCD7F48A9DA04FD50E8083969EDB767B0CF6095179A163AB3661A05FBD5FAAAE82918A9962F0B93B855F97993EC975EEAA80D740ADBF4FF747359D041D5C33EA71D281E446B14773BCA97B43A23FB801676BD207A436C6481F1D2B9078717461A5B9D32E688F87748544523B524B0D57D5EA77A2775D2ECFA032CFBDBF52FB3786160279004E57AE6AF874E7303CE53299CCC041C7BC308D82A5698F3A8D0C38271AE35F8E9DBFBB694B5C803D89F7AE435DE236D525F54759B65E372FCD68EF20FA7111F9E4AFF73",
|
||||
"21484252197776302499639938883777710321993113097987201050501182909581359357618579566746556372589385361683610524730509041328855066514963385522570894839035884713051640171474186548713546686476761306436434146475140156284389181808675016576845833340494848283681088886584219750554408060556769486628029028720727393293111678826356480455433909233520504112074401376133077150471237549474149190242010469539006449596611576612573955754349042329130631128234637924786466585703488460540228477440853493392086251021228087076124706778899179648655221663765993962724699135217212118535057766739392069738618682722216712319320435674779146070442",
|
||||
},
|
||||
{
|
||||
"-0x1BCE04427D8032319A89E5C4136456671AC620883F2C4139E57F91307C485AD2D6204F4F87A58262652DB5DBBAC72B0613E51B835E7153BEC6068F5C8D696B74DBD18FEC316AEF73985CF0475663208EB46B4F17DD9DA55367B03323E5491A70997B90C059FB34809E6EE55BCFBD5F2F52233BFE62E6AA9E4E26A1D4C2439883D14F2633D55D8AA66A1ACD5595E778AC3A280517F1157989E70C1A437B849F1877B779CC3CDDEDE2DAA6594A6C66D181A00A5F777EE60596D8773998F6E988DEAE4CCA60E4DDCF9590543C89F74F603259FCAD71660D30294FBBE6490300F78A9D63FA660DC9417B8B9DDA28BEB3977B621B988E23D4D954F322C3540541BC649ABD504C50FADFD9F0987D58A2BF689313A285E773FF02899A6EF887D1D4A0D2",
|
||||
"0xB08FFB20760FFED58FADA86DFEF71AD72AA0FA763219618FE022C197E54708BB1191C66470250FCE8879487507CEE41381CA4D932F81C2B3F1AB20B539D50DCD",
|
||||
"0xAC6BDB41324A9A9BF166DE5E1389582FAF72B6651987EE07FC3192943DB56050A37329CBB4A099ED8193E0757767A13DD52312AB4B03310DCD7F48A9DA04FD50E8083969EDB767B0CF6095179A163AB3661A05FBD5FAAAE82918A9962F0B93B855F97993EC975EEAA80D740ADBF4FF747359D041D5C33EA71D281E446B14773BCA97B43A23FB801676BD207A436C6481F1D2B9078717461A5B9D32E688F87748544523B524B0D57D5EA77A2775D2ECFA032CFBDBF52FB3786160279004E57AE6AF874E7303CE53299CCC041C7BC308D82A5698F3A8D0C38271AE35F8E9DBFBB694B5C803D89F7AE435DE236D525F54759B65E372FCD68EF20FA7111F9E4AFF73",
|
||||
"21484252197776302499639938883777710321993113097987201050501182909581359357618579566746556372589385361683610524730509041328855066514963385522570894839035884713051640171474186548713546686476761306436434146475140156284389181808675016576845833340494848283681088886584219750554408060556769486628029028720727393293111678826356480455433909233520504112074401376133077150471237549474149190242010469539006449596611576612573955754349042329130631128234637924786466585703488460540228477440853493392086251021228087076124706778899179648655221663765993962724699135217212118535057766739392069738618682722216712319320435674779146070442",
|
||||
},
|
||||
|
||||
// test cases for issue 13907
|
||||
{"0xffffffff00000001", "0xffffffff00000001", "0xffffffff00000001", "0"},
|
||||
{"0xffffffffffffffff00000001", "0xffffffffffffffff00000001", "0xffffffffffffffff00000001", "0"},
|
||||
{"0xffffffffffffffffffffffff00000001", "0xffffffffffffffffffffffff00000001", "0xffffffffffffffffffffffff00000001", "0"},
|
||||
{"0xffffffffffffffffffffffffffffffff00000001", "0xffffffffffffffffffffffffffffffff00000001", "0xffffffffffffffffffffffffffffffff00000001", "0"},
|
||||
}
|
||||
|
||||
func TestExp(t *testing.T) {
|
||||
|
|
@ -584,7 +599,7 @@ func TestExp(t *testing.T) {
|
|||
t.Errorf("#%d: %v is not normalized", i, *z1)
|
||||
}
|
||||
if z1.Cmp(out) != 0 {
|
||||
t.Errorf("#%d: got %s want %s", i, z1, out)
|
||||
t.Errorf("#%d: got %x want %x", i, z1, out)
|
||||
}
|
||||
|
||||
if m == nil {
|
||||
|
|
@ -593,7 +608,7 @@ func TestExp(t *testing.T) {
|
|||
m = &Int{abs: nat{}} // m != nil && len(m.abs) == 0
|
||||
z2 := new(Int).Exp(x, y, m)
|
||||
if z2.Cmp(z1) != 0 {
|
||||
t.Errorf("#%d: got %s want %s", i, z2, z1)
|
||||
t.Errorf("#%d: got %x want %x", i, z2, z1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1369,6 +1384,14 @@ func TestModSqrt(t *testing.T) {
|
|||
t.Errorf("#%d: failed (sqrt(e) = %s)", i, &sqrt)
|
||||
}
|
||||
}
|
||||
|
||||
if testing.Short() && i > 2 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if testing.Short() {
|
||||
return
|
||||
}
|
||||
|
||||
// exhaustive test for small values
|
||||
|
|
|
|||
|
|
@ -213,25 +213,25 @@ func (z nat) montgomery(x, y, m nat, k Word, n int) nat {
|
|||
if len(x) != n || len(y) != n || len(m) != n {
|
||||
panic("math/big: mismatched montgomery number lengths")
|
||||
}
|
||||
var c1, c2, c3 Word
|
||||
z = z.make(n)
|
||||
z.clear()
|
||||
var c Word
|
||||
for i := 0; i < n; i++ {
|
||||
d := y[i]
|
||||
c2 = addMulVVW(z, x, d)
|
||||
c2 := addMulVVW(z, x, d)
|
||||
t := z[0] * k
|
||||
c3 = addMulVVW(z, m, t)
|
||||
c3 := addMulVVW(z, m, t)
|
||||
copy(z, z[1:])
|
||||
cx := c1 + c2
|
||||
cx := c + c2
|
||||
cy := cx + c3
|
||||
z[n-1] = cy
|
||||
if cx < c2 || cy < c3 {
|
||||
c1 = 1
|
||||
c = 1
|
||||
} else {
|
||||
c1 = 0
|
||||
c = 0
|
||||
}
|
||||
}
|
||||
if c1 != 0 {
|
||||
if c != 0 {
|
||||
subVV(z, z, m)
|
||||
}
|
||||
return z
|
||||
|
|
@ -1056,23 +1056,19 @@ func (z nat) expNNWindowed(x, y, m nat) nat {
|
|||
// expNNMontgomery calculates x**y mod m using a fixed, 4-bit window.
|
||||
// Uses Montgomery representation.
|
||||
func (z nat) expNNMontgomery(x, y, m nat) nat {
|
||||
var zz, one, rr, RR nat
|
||||
|
||||
numWords := len(m)
|
||||
|
||||
// We want the lengths of x and m to be equal.
|
||||
// It is OK if x >= m as long as len(x) == len(m).
|
||||
if len(x) > numWords {
|
||||
_, rr = rr.div(rr, x, m)
|
||||
} else if len(x) < numWords {
|
||||
rr = rr.make(numWords)
|
||||
rr.clear()
|
||||
for i := range x {
|
||||
rr[i] = x[i]
|
||||
}
|
||||
} else {
|
||||
rr = x
|
||||
_, x = nat(nil).div(nil, x, m)
|
||||
// Note: now len(x) <= numWords, not guaranteed ==.
|
||||
}
|
||||
if len(x) < numWords {
|
||||
rr := make(nat, numWords)
|
||||
copy(rr, x)
|
||||
x = rr
|
||||
}
|
||||
x = rr
|
||||
|
||||
// Ideally the precomputations would be performed outside, and reused
|
||||
// k0 = -m**-1 mod 2**_W. Algorithm from: Dumas, J.G. "On Newton–Raphson
|
||||
|
|
@ -1086,8 +1082,8 @@ func (z nat) expNNMontgomery(x, y, m nat) nat {
|
|||
k0 = -k0
|
||||
|
||||
// RR = 2**(2*_W*len(m)) mod m
|
||||
RR = RR.setWord(1)
|
||||
zz = zz.shl(RR, uint(2*numWords*_W))
|
||||
RR := nat(nil).setWord(1)
|
||||
zz := nat(nil).shl(RR, uint(2*numWords*_W))
|
||||
_, RR = RR.div(RR, zz, m)
|
||||
if len(RR) < numWords {
|
||||
zz = zz.make(numWords)
|
||||
|
|
@ -1095,8 +1091,7 @@ func (z nat) expNNMontgomery(x, y, m nat) nat {
|
|||
RR = zz
|
||||
}
|
||||
// one = 1, with equal length to that of m
|
||||
one = one.make(numWords)
|
||||
one.clear()
|
||||
one := make(nat, numWords)
|
||||
one[0] = 1
|
||||
|
||||
const n = 4
|
||||
|
|
@ -1131,6 +1126,23 @@ func (z nat) expNNMontgomery(x, y, m nat) nat {
|
|||
}
|
||||
// convert to regular number
|
||||
zz = zz.montgomery(z, one, m, k0, numWords)
|
||||
|
||||
// One last reduction, just in case.
|
||||
// See golang.org/issue/13907.
|
||||
if zz.cmp(m) >= 0 {
|
||||
// Common case is m has high bit set; in that case,
|
||||
// since zz is the same length as m, there can be just
|
||||
// one multiple of m to remove. Just subtract.
|
||||
// We think that the subtract should be sufficient in general,
|
||||
// so do that unconditionally, but double-check,
|
||||
// in case our beliefs are wrong.
|
||||
// The div is not expected to be reached.
|
||||
zz = zz.sub(zz, m)
|
||||
if zz.cmp(m) >= 0 {
|
||||
_, zz = nat(nil).div(nil, zz, m)
|
||||
}
|
||||
}
|
||||
|
||||
return zz.norm()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -483,6 +483,12 @@ var expNNTests = []struct {
|
|||
"29834729834729834729347290846729561262544958723956495615629569234729836259263598127342374289365912465901365498236492183464",
|
||||
"23537740700184054162508175125554701713153216681790245129157191391322321508055833908509185839069455749219131480588829346291",
|
||||
},
|
||||
{
|
||||
"11521922904531591643048817447554701904414021819823889996244743037378330903763518501116638828335352811871131385129455853417360623007349090150042001944696604737499160174391019030572483602867266711107136838523916077674888297896995042968746762200926853379",
|
||||
"426343618817810911523",
|
||||
"444747819283133684179",
|
||||
"42",
|
||||
},
|
||||
}
|
||||
|
||||
func TestExpNN(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -420,7 +420,7 @@ func symfmt(s *Sym, flag int) string {
|
|||
if s.Pkg != nil && flag&obj.FmtShort == 0 {
|
||||
switch fmtmode {
|
||||
case FErr: // This is for the user
|
||||
if s.Pkg == localpkg {
|
||||
if s.Pkg == builtinpkg || s.Pkg == localpkg {
|
||||
return s.Name
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -607,9 +607,6 @@ func Tempname(nn *Node, t *Type) {
|
|||
n.Esc = EscNever
|
||||
n.Name.Curfn = Curfn
|
||||
Curfn.Func.Dcl = list(Curfn.Func.Dcl, n)
|
||||
if Debug['h'] != 0 {
|
||||
println("H", n, n.Orig, funcSym(Curfn).Name)
|
||||
}
|
||||
|
||||
dowidth(t)
|
||||
n.Xoffset = 0
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ func Main() {
|
|||
|
||||
Thearch.Linkarchinit()
|
||||
Ctxt = obj.Linknew(Thearch.Thelinkarch)
|
||||
Ctxt.Diag = Yyerror
|
||||
Ctxt.DiagFunc = Yyerror
|
||||
Ctxt.Bso = &bstdout
|
||||
bstdout = *obj.Binitw(os.Stdout)
|
||||
|
||||
|
|
@ -845,6 +845,13 @@ func importfile(f *Val, line int) {
|
|||
}
|
||||
p := fmt.Sprintf("package %s %s\n$$\n", importpkg.Name, tag)
|
||||
cannedimports(file, p)
|
||||
// Reset incannedimport flag (we are not truly in a
|
||||
// canned import) - this will cause importpkg.Direct to
|
||||
// be set via parser.import_package (was issue #13977).
|
||||
//
|
||||
// TODO(gri) Remove this global variable and convoluted
|
||||
// code in the process of streamlining the import code.
|
||||
incannedimport = 0
|
||||
|
||||
default:
|
||||
Yyerror("no import in %q", f.U.(string))
|
||||
|
|
@ -927,13 +934,9 @@ func isfrog(c int) bool {
|
|||
}
|
||||
|
||||
type yySymType struct {
|
||||
yys int
|
||||
node *Node
|
||||
list *NodeList
|
||||
typ *Type
|
||||
sym *Sym
|
||||
val Val
|
||||
op Op
|
||||
sym *Sym
|
||||
val Val
|
||||
op Op
|
||||
}
|
||||
|
||||
const (
|
||||
|
|
|
|||
|
|
@ -149,6 +149,7 @@ var opnames = []string{
|
|||
OCFUNC: "CFUNC",
|
||||
OCHECKNIL: "CHECKNIL",
|
||||
OVARKILL: "VARKILL",
|
||||
OVARLIVE: "VARLIVE",
|
||||
OREGISTER: "REGISTER",
|
||||
OINDREG: "INDREG",
|
||||
OCMP: "CMP",
|
||||
|
|
|
|||
|
|
@ -668,9 +668,14 @@ func (p *parser) simple_stmt(labelOk, rangeOk bool) *Node {
|
|||
if labelOk {
|
||||
// If we have a labelname, it was parsed by operand
|
||||
// (calling p.name()) and given an ONAME, ONONAME, OTYPE, OPACK, or OLITERAL node.
|
||||
// We only have a labelname if there is a symbol (was issue 14006).
|
||||
switch lhs.Op {
|
||||
case ONAME, ONONAME, OTYPE, OPACK, OLITERAL:
|
||||
lhs = newname(lhs.Sym)
|
||||
if lhs.Sym != nil {
|
||||
lhs = newname(lhs.Sym)
|
||||
break
|
||||
}
|
||||
fallthrough
|
||||
default:
|
||||
p.syntax_error("expecting semicolon or newline or }")
|
||||
// we already progressed, no need to advance
|
||||
|
|
@ -2496,6 +2501,24 @@ func (p *parser) interfacedcl() *Node {
|
|||
ifacedcl(meth)
|
||||
return meth
|
||||
|
||||
case '@', '?':
|
||||
// newname indcl
|
||||
// We arrive here when parsing an interface type declared inside
|
||||
// an exported and inlineable function and the interface declares
|
||||
// unexported methods (which are then package-qualified).
|
||||
//
|
||||
// Since the compiler always flattens embedded interfaces, we
|
||||
// will never see an embedded package-qualified interface in export
|
||||
// data; i.e., when we reach here we know it must be a method.
|
||||
//
|
||||
// See also issue 14164.
|
||||
mname := newname(p.sym())
|
||||
sig := p.indcl()
|
||||
|
||||
meth := Nod(ODCLFIELD, mname, sig)
|
||||
ifacedcl(meth)
|
||||
return meth
|
||||
|
||||
case '(':
|
||||
p.next()
|
||||
pname := p.packname(nil)
|
||||
|
|
|
|||
|
|
@ -544,7 +544,8 @@ func (s *state) stmt(n *Node) {
|
|||
// Expression statements
|
||||
case OCALLFUNC, OCALLMETH, OCALLINTER:
|
||||
s.call(n, callNormal)
|
||||
if n.Op == OCALLFUNC && n.Left.Op == ONAME && n.Left.Class == PFUNC && n.Left.Sym.Pkg == Runtimepkg && n.Left.Sym.Name == "gopanic" {
|
||||
if n.Op == OCALLFUNC && n.Left.Op == ONAME && n.Left.Class == PFUNC && n.Left.Sym.Pkg == Runtimepkg &&
|
||||
(n.Left.Sym.Name == "gopanic" || n.Left.Sym.Name == "selectgo") {
|
||||
m := s.mem()
|
||||
b := s.endBlock()
|
||||
b.Kind = ssa.BlockExit
|
||||
|
|
@ -873,6 +874,10 @@ func (s *state) stmt(n *Node) {
|
|||
lab.breakTarget = nil
|
||||
}
|
||||
|
||||
// OSWITCH never falls through (s.curBlock == nil here).
|
||||
// OSELECT does not fall through if we're calling selectgo.
|
||||
// OSELECT does fall through if we're calling selectnb{send,recv}[2].
|
||||
// In those latter cases, go to the code after the select.
|
||||
if b := s.endBlock(); b != nil {
|
||||
b.AddEdgeTo(bEnd)
|
||||
}
|
||||
|
|
|
|||
6
src/cmd/dist/test.go
vendored
6
src/cmd/dist/test.go
vendored
|
|
@ -336,7 +336,11 @@ func (t *tester) registerTests() {
|
|||
} else {
|
||||
// Use a format string to only list packages and commands that have tests.
|
||||
const format = "{{if (or .TestGoFiles .XTestGoFiles)}}{{.ImportPath}}{{end}}"
|
||||
cmd := exec.Command("go", "list", "-f", format, "std")
|
||||
cmd := exec.Command("go", "list", "-f", format)
|
||||
if t.race {
|
||||
cmd.Args = append(cmd.Args, "-tags", "race")
|
||||
}
|
||||
cmd.Args = append(cmd.Args, "std")
|
||||
if !t.race {
|
||||
cmd.Args = append(cmd.Args, "cmd")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,7 +93,8 @@ and test commands:
|
|||
Supported only on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64.
|
||||
-msan
|
||||
enable interoperation with memory sanitizer.
|
||||
Supported only on linux/amd64.
|
||||
Supported only on linux/amd64,
|
||||
and only with Clang/LLVM as the host C compiler.
|
||||
-v
|
||||
print the names of packages as they are compiled.
|
||||
-work
|
||||
|
|
@ -603,6 +604,14 @@ syntax of package template. The default output is equivalent to -f
|
|||
XTestImports []string // imports from XTestGoFiles
|
||||
}
|
||||
|
||||
The error information, if any, is
|
||||
|
||||
type PackageError struct {
|
||||
ImportStack []string // shortest path from package named on command line to this one
|
||||
Pos string // position of error (if present, file:line:col)
|
||||
Err string // the error itself
|
||||
}
|
||||
|
||||
The template function "join" calls strings.Join.
|
||||
|
||||
The template function "context" returns the build context, defined as:
|
||||
|
|
|
|||
|
|
@ -72,7 +72,8 @@ and test commands:
|
|||
Supported only on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64.
|
||||
-msan
|
||||
enable interoperation with memory sanitizer.
|
||||
Supported only on linux/amd64.
|
||||
Supported only on linux/amd64,
|
||||
and only with Clang/LLVM as the host C compiler.
|
||||
-v
|
||||
print the names of packages as they are compiled.
|
||||
-work
|
||||
|
|
@ -1835,6 +1836,7 @@ var objectMagic = [][]byte{
|
|||
{0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00}, // PE (Windows) as generated by 6l/8l and gcc
|
||||
{0x00, 0x00, 0x01, 0xEB}, // Plan 9 i386
|
||||
{0x00, 0x00, 0x8a, 0x97}, // Plan 9 amd64
|
||||
{0x00, 0x00, 0x06, 0x47}, // Plan 9 arm
|
||||
}
|
||||
|
||||
func isObject(s string) bool {
|
||||
|
|
@ -2568,11 +2570,11 @@ func (tools gccgoToolchain) asm(b *builder, p *Package, obj, ofile, sfile string
|
|||
sfile = mkAbs(p.Dir, sfile)
|
||||
defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch}
|
||||
if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
|
||||
defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
|
||||
defs = append(defs, `-D`, `GOPKGPATH=`+pkgpath)
|
||||
}
|
||||
defs = tools.maybePIC(defs)
|
||||
defs = append(defs, b.gccArchArgs()...)
|
||||
return b.run(p.Dir, p.ImportPath, nil, tools.compiler(), "-I", obj, "-o", ofile, defs, sfile)
|
||||
return b.run(p.Dir, p.ImportPath, nil, tools.compiler(), "-xassembler-with-cpp", "-I", obj, "-c", "-o", ofile, defs, sfile)
|
||||
}
|
||||
|
||||
func (gccgoToolchain) pkgpath(basedir string, p *Package) string {
|
||||
|
|
|
|||
|
|
@ -657,6 +657,9 @@ func TestGoBuildDashAInDevBranch(t *testing.T) {
|
|||
tg.setenv("TESTGO_IS_GO_RELEASE", "0")
|
||||
tg.run("build", "-v", "-a", "math")
|
||||
tg.grepStderr("runtime", "testgo build -a math in dev branch DID NOT build runtime, but should have")
|
||||
|
||||
// Everything is out of date. Rebuild to leave things in a better state.
|
||||
tg.run("install", "std")
|
||||
}
|
||||
|
||||
func TestGoBuildDashAInReleaseBranch(t *testing.T) {
|
||||
|
|
@ -666,10 +669,110 @@ func TestGoBuildDashAInReleaseBranch(t *testing.T) {
|
|||
|
||||
tg := testgo(t)
|
||||
defer tg.cleanup()
|
||||
tg.run("install", "math") // should be up to date already but just in case
|
||||
tg.run("install", "math", "net/http") // should be up to date already but just in case
|
||||
tg.setenv("TESTGO_IS_GO_RELEASE", "1")
|
||||
tg.run("build", "-v", "-a", "math")
|
||||
tg.grepStderr("runtime", "testgo build -a math in dev branch did not build runtime, but should have")
|
||||
tg.run("install", "-v", "-a", "math")
|
||||
tg.grepStderr("runtime", "testgo build -a math in release branch DID NOT build runtime, but should have")
|
||||
|
||||
// Now runtime.a is updated (newer mtime), so everything would look stale if not for being a release.
|
||||
tg.run("build", "-v", "net/http")
|
||||
tg.grepStderrNot("strconv", "testgo build -v net/http in release branch with newer runtime.a DID build strconv but should not have")
|
||||
tg.grepStderrNot("golang.org/x/net/http2/hpack", "testgo build -v net/http in release branch with newer runtime.a DID build .../golang.org/x/net/http2/hpack but should not have")
|
||||
tg.grepStderrNot("net/http", "testgo build -v net/http in release branch with newer runtime.a DID build net/http but should not have")
|
||||
|
||||
// Everything is out of date. Rebuild to leave things in a better state.
|
||||
tg.run("install", "std")
|
||||
}
|
||||
|
||||
func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("don't rebuild the standard library in short mode")
|
||||
}
|
||||
|
||||
tg := testgo(t)
|
||||
defer tg.cleanup()
|
||||
|
||||
addNL := func(name string) (restore func()) {
|
||||
data, err := ioutil.ReadFile(name)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
old := data
|
||||
data = append(data, '\n')
|
||||
if err := ioutil.WriteFile(name, append(data, '\n'), 0666); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tg.sleep()
|
||||
return func() {
|
||||
if err := ioutil.WriteFile(name, old, 0666); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tg.setenv("TESTGO_IS_GO_RELEASE", "1")
|
||||
|
||||
tg.tempFile("d1/src/p1/p1.go", `package p1`)
|
||||
tg.setenv("GOPATH", tg.path("d1"))
|
||||
tg.run("install", "-a", "p1")
|
||||
tg.wantNotStale("p1", "./testgo list claims p1 is stale, incorrectly")
|
||||
tg.sleep()
|
||||
|
||||
// Changing mtime and content of runtime/internal/sys/sys.go
|
||||
// should have no effect: we're in a release, which doesn't rebuild
|
||||
// for general mtime or content changes.
|
||||
sys := runtime.GOROOT() + "/src/runtime/internal/sys/sys.go"
|
||||
restore := addNL(sys)
|
||||
defer restore()
|
||||
tg.wantNotStale("p1", "./testgo list claims p1 is stale, incorrectly, after updating runtime/internal/sys/sys.go")
|
||||
restore()
|
||||
tg.wantNotStale("p1", "./testgo list claims p1 is stale, incorrectly, after restoring runtime/internal/sys/sys.go")
|
||||
|
||||
// But changing runtime/internal/sys/zversion.go should have an effect:
|
||||
// that's how we tell when we flip from one release to another.
|
||||
zversion := runtime.GOROOT() + "/src/runtime/internal/sys/zversion.go"
|
||||
restore = addNL(zversion)
|
||||
defer restore()
|
||||
tg.wantStale("p1", "./testgo list claims p1 is NOT stale, incorrectly, after changing to new release")
|
||||
restore()
|
||||
tg.wantNotStale("p1", "./testgo list claims p1 is stale, incorrectly, after changing back to old release")
|
||||
addNL(zversion)
|
||||
tg.wantStale("p1", "./testgo list claims p1 is NOT stale, incorrectly, after changing again to new release")
|
||||
tg.run("install", "p1")
|
||||
tg.wantNotStale("p1", "./testgo list claims p1 is stale after building with new release")
|
||||
|
||||
// Restore to "old" release.
|
||||
restore()
|
||||
tg.wantStale("p1", "./testgo list claims p1 is NOT stale, incorrectly, after changing to old release after new build")
|
||||
tg.run("install", "p1")
|
||||
tg.wantNotStale("p1", "./testgo list claims p1 is stale after building with old release")
|
||||
|
||||
// Everything is out of date. Rebuild to leave things in a better state.
|
||||
tg.run("install", "std")
|
||||
}
|
||||
|
||||
func TestGoListStandard(t *testing.T) {
|
||||
tg := testgo(t)
|
||||
defer tg.cleanup()
|
||||
tg.cd(runtime.GOROOT() + "/src")
|
||||
tg.run("list", "-f", "{{if not .Standard}}{{.ImportPath}}{{end}}", "./...")
|
||||
stdout := tg.getStdout()
|
||||
for _, line := range strings.Split(stdout, "\n") {
|
||||
if strings.HasPrefix(line, "_/") && strings.HasSuffix(line, "/src") {
|
||||
// $GOROOT/src shows up if there are any .go files there.
|
||||
// We don't care.
|
||||
continue
|
||||
}
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
t.Errorf("package in GOROOT not listed as standard: %v", line)
|
||||
}
|
||||
|
||||
// Similarly, expanding std should include some of our vendored code.
|
||||
tg.run("list", "std", "cmd")
|
||||
tg.grepStdout("golang.org/x/net/http2/hpack", "list std cmd did not mention vendored hpack")
|
||||
tg.grepStdout("golang.org/x/arch/x86/x86asm", "list std cmd did not mention vendored x86asm")
|
||||
}
|
||||
|
||||
func TestGoInstallCleansUpAfterGoBuild(t *testing.T) {
|
||||
|
|
@ -725,8 +828,8 @@ func TestGoInstallRebuildsStalePackagesInOtherGOPATH(t *testing.T) {
|
|||
sep := string(filepath.ListSeparator)
|
||||
tg.setenv("GOPATH", tg.path("d1")+sep+tg.path("d2"))
|
||||
tg.run("install", "p1")
|
||||
tg.wantNotStale("p1", "./testgo list mypkg claims p1 is stale, incorrectly")
|
||||
tg.wantNotStale("p2", "./testgo list mypkg claims p2 is stale, incorrectly")
|
||||
tg.wantNotStale("p1", "./testgo list claims p1 is stale, incorrectly")
|
||||
tg.wantNotStale("p2", "./testgo list claims p2 is stale, incorrectly")
|
||||
tg.sleep()
|
||||
if f, err := os.OpenFile(tg.path("d2/src/p2/p2.go"), os.O_WRONLY|os.O_APPEND, 0); err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
@ -735,12 +838,12 @@ func TestGoInstallRebuildsStalePackagesInOtherGOPATH(t *testing.T) {
|
|||
} else {
|
||||
tg.must(f.Close())
|
||||
}
|
||||
tg.wantStale("p2", "./testgo list mypkg claims p2 is NOT stale, incorrectly")
|
||||
tg.wantStale("p1", "./testgo list mypkg claims p1 is NOT stale, incorrectly")
|
||||
tg.wantStale("p2", "./testgo list claims p2 is NOT stale, incorrectly")
|
||||
tg.wantStale("p1", "./testgo list claims p1 is NOT stale, incorrectly")
|
||||
|
||||
tg.run("install", "p1")
|
||||
tg.wantNotStale("p2", "./testgo list mypkg claims p2 is stale after reinstall, incorrectly")
|
||||
tg.wantNotStale("p1", "./testgo list mypkg claims p1 is stale after reinstall, incorrectly")
|
||||
tg.wantNotStale("p2", "./testgo list claims p2 is stale after reinstall, incorrectly")
|
||||
tg.wantNotStale("p1", "./testgo list claims p1 is stale after reinstall, incorrectly")
|
||||
}
|
||||
|
||||
func TestGoInstallDetectsRemovedFiles(t *testing.T) {
|
||||
|
|
@ -1590,7 +1693,7 @@ func TestGoTestDashOWritesBinary(t *testing.T) {
|
|||
}
|
||||
|
||||
// Issue 4568.
|
||||
func TestSymlinksDoNotConfuseGoList(t *testing.T) {
|
||||
func TestSymlinksList(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "plan9", "windows":
|
||||
t.Skipf("skipping symlink test on %s", runtime.GOOS)
|
||||
|
|
@ -1609,6 +1712,58 @@ func TestSymlinksDoNotConfuseGoList(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// Issue 14054.
|
||||
func TestSymlinksVendor(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "plan9", "windows":
|
||||
t.Skipf("skipping symlink test on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
tg := testgo(t)
|
||||
defer tg.cleanup()
|
||||
tg.setenv("GO15VENDOREXPERIMENT", "1")
|
||||
tg.tempDir("gopath/src/dir1/vendor/v")
|
||||
tg.tempFile("gopath/src/dir1/p.go", "package main\nimport _ `v`\nfunc main(){}")
|
||||
tg.tempFile("gopath/src/dir1/vendor/v/v.go", "package v")
|
||||
tg.must(os.Symlink(tg.path("gopath/src/dir1"), tg.path("symdir1")))
|
||||
tg.setenv("GOPATH", tg.path("gopath"))
|
||||
tg.cd(tg.path("symdir1"))
|
||||
tg.run("list", "-f", "{{.Root}}", ".")
|
||||
if strings.TrimSpace(tg.getStdout()) != tg.path("gopath") {
|
||||
t.Error("list confused by symlinks")
|
||||
}
|
||||
|
||||
// All of these should succeed, not die in vendor-handling code.
|
||||
tg.run("run", "p.go")
|
||||
tg.run("build")
|
||||
tg.run("install")
|
||||
}
|
||||
|
||||
func TestSymlinksInternal(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "plan9", "windows":
|
||||
t.Skipf("skipping symlink test on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
tg := testgo(t)
|
||||
defer tg.cleanup()
|
||||
tg.tempDir("gopath/src/dir1/internal/v")
|
||||
tg.tempFile("gopath/src/dir1/p.go", "package main\nimport _ `dir1/internal/v`\nfunc main(){}")
|
||||
tg.tempFile("gopath/src/dir1/internal/v/v.go", "package v")
|
||||
tg.must(os.Symlink(tg.path("gopath/src/dir1"), tg.path("symdir1")))
|
||||
tg.setenv("GOPATH", tg.path("gopath"))
|
||||
tg.cd(tg.path("symdir1"))
|
||||
tg.run("list", "-f", "{{.Root}}", ".")
|
||||
if strings.TrimSpace(tg.getStdout()) != tg.path("gopath") {
|
||||
t.Error("list confused by symlinks")
|
||||
}
|
||||
|
||||
// All of these should succeed, not die in internal-handling code.
|
||||
tg.run("run", "p.go")
|
||||
tg.run("build")
|
||||
tg.run("install")
|
||||
}
|
||||
|
||||
// Issue 4515.
|
||||
func TestInstallWithTags(t *testing.T) {
|
||||
tg := testgo(t)
|
||||
|
|
@ -2255,6 +2410,7 @@ func TestGoGetInsecureCustomDomain(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestIssue10193(t *testing.T) {
|
||||
t.Skip("depends on code.google.com")
|
||||
testenv.MustHaveExternalNetwork(t)
|
||||
if _, err := exec.LookPath("hg"); err != nil {
|
||||
t.Skip("skipping because hg binary not found")
|
||||
|
|
|
|||
|
|
@ -78,6 +78,14 @@ syntax of package template. The default output is equivalent to -f
|
|||
XTestImports []string // imports from XTestGoFiles
|
||||
}
|
||||
|
||||
The error information, if any, is
|
||||
|
||||
type PackageError struct {
|
||||
ImportStack []string // shortest path from package named on command line to this one
|
||||
Pos string // position of error (if present, file:line:col)
|
||||
Err string // the error itself
|
||||
}
|
||||
|
||||
The template function "join" calls strings.Join.
|
||||
|
||||
The template function "context" returns the build context, defined as:
|
||||
|
|
|
|||
|
|
@ -524,6 +524,15 @@ func hasFilePathPrefix(s, prefix string) bool {
|
|||
}
|
||||
}
|
||||
|
||||
// expandPath returns the symlink-expanded form of path.
|
||||
func expandPath(p string) string {
|
||||
x, err := filepath.EvalSymlinks(p)
|
||||
if err == nil {
|
||||
return x
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// treeCanMatchPattern(pattern)(name) reports whether
|
||||
// name or children of name can possibly match pattern.
|
||||
// Pattern is the same limited glob accepted by matchPattern.
|
||||
|
|
@ -588,10 +597,9 @@ func matchPackages(pattern string) []string {
|
|||
}
|
||||
|
||||
name := filepath.ToSlash(path[len(src):])
|
||||
if pattern == "std" && (strings.Contains(name, ".") || name == "cmd") {
|
||||
if pattern == "std" && (!isStandardImportPath(name) || name == "cmd") {
|
||||
// The name "std" is only the standard library.
|
||||
// If the name has a dot, assume it's a domain name for go get,
|
||||
// and if the name is cmd, it's the root of the command tree.
|
||||
// If the name is cmd, it's the root of the command tree.
|
||||
return filepath.SkipDir
|
||||
}
|
||||
if !treeCanMatch(name) {
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ func (p *Package) copyBuild(pp *build.Package) {
|
|||
p.ConflictDir = pp.ConflictDir
|
||||
// TODO? Target
|
||||
p.Goroot = pp.Goroot
|
||||
p.Standard = p.Goroot && p.ImportPath != "" && !strings.Contains(p.ImportPath, ".")
|
||||
p.Standard = p.Goroot && p.ImportPath != "" && isStandardImportPath(p.ImportPath)
|
||||
p.GoFiles = pp.GoFiles
|
||||
p.CgoFiles = pp.CgoFiles
|
||||
p.IgnoredGoFiles = pp.IgnoredGoFiles
|
||||
|
|
@ -177,6 +177,19 @@ func (p *Package) copyBuild(pp *build.Package) {
|
|||
p.XTestImports = pp.XTestImports
|
||||
}
|
||||
|
||||
// isStandardImportPath reports whether $GOROOT/src/path should be considered
|
||||
// part of the standard distribution. For historical reasons we allow people to add
|
||||
// their own code to $GOROOT instead of using $GOPATH, but we assume that
|
||||
// code will start with a domain name (dot in the first element).
|
||||
func isStandardImportPath(path string) bool {
|
||||
i := strings.Index(path, "/")
|
||||
if i < 0 {
|
||||
i = len(path)
|
||||
}
|
||||
elem := path[:i]
|
||||
return !strings.Contains(elem, ".")
|
||||
}
|
||||
|
||||
// A PackageError describes an error loading information about a package.
|
||||
type PackageError struct {
|
||||
ImportStack []string // shortest path from package named on command line to this one
|
||||
|
|
@ -362,7 +375,7 @@ func loadImport(path, srcDir string, parent *Package, stk *importStack, importPo
|
|||
err = fmt.Errorf("code in directory %s expects import %q", bp.Dir, bp.ImportComment)
|
||||
}
|
||||
p.load(stk, bp, err)
|
||||
if p.Error != nil && len(importPos) > 0 {
|
||||
if p.Error != nil && p.Error.Pos == "" && len(importPos) > 0 {
|
||||
pos := importPos[0]
|
||||
pos.Filename = shortPath(pos.Filename)
|
||||
p.Error.Pos = pos.String()
|
||||
|
|
@ -402,11 +415,18 @@ func vendoredImportPath(parent *Package, path string) (found string) {
|
|||
if parent == nil || parent.Root == "" || !go15VendorExperiment {
|
||||
return path
|
||||
}
|
||||
|
||||
dir := filepath.Clean(parent.Dir)
|
||||
root := filepath.Join(parent.Root, "src")
|
||||
if !hasFilePathPrefix(dir, root) {
|
||||
// Look for symlinks before reporting error.
|
||||
dir = expandPath(dir)
|
||||
root = expandPath(root)
|
||||
}
|
||||
if !hasFilePathPrefix(dir, root) || len(dir) <= len(root) || dir[len(root)] != filepath.Separator {
|
||||
fatalf("invalid vendoredImportPath: dir=%q root=%q separator=%q", dir, root, string(filepath.Separator))
|
||||
}
|
||||
|
||||
vpath := "vendor/" + path
|
||||
for i := len(dir); i >= len(root); i-- {
|
||||
if i < len(dir) && dir[i] != filepath.Separator {
|
||||
|
|
@ -520,6 +540,13 @@ func disallowInternal(srcDir string, p *Package, stk *importStack) *Package {
|
|||
return p
|
||||
}
|
||||
|
||||
// Look for symlinks before reporting error.
|
||||
srcDir = expandPath(srcDir)
|
||||
parent = expandPath(parent)
|
||||
if hasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
|
||||
return p
|
||||
}
|
||||
|
||||
// Internal is present, and srcDir is outside parent's tree. Not allowed.
|
||||
perr := *p
|
||||
perr.Error = &PackageError{
|
||||
|
|
@ -617,6 +644,13 @@ func disallowVendorVisibility(srcDir string, p *Package, stk *importStack) *Pack
|
|||
return p
|
||||
}
|
||||
|
||||
// Look for symlinks before reporting error.
|
||||
srcDir = expandPath(srcDir)
|
||||
parent = expandPath(parent)
|
||||
if hasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
|
||||
return p
|
||||
}
|
||||
|
||||
// Vendor is present, and srcDir is outside parent's tree. Not allowed.
|
||||
perr := *p
|
||||
perr.Error = &PackageError{
|
||||
|
|
@ -933,6 +967,17 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
|
|||
}
|
||||
}
|
||||
}
|
||||
if p.Standard && !p1.Standard && p.Error == nil {
|
||||
p.Error = &PackageError{
|
||||
ImportStack: stk.copy(),
|
||||
Err: fmt.Sprintf("non-standard import %q in standard package %q", path, p.ImportPath),
|
||||
}
|
||||
pos := p.build.ImportPos[path]
|
||||
if len(pos) > 0 {
|
||||
p.Error.Pos = pos[0].String()
|
||||
}
|
||||
}
|
||||
|
||||
path = p1.ImportPath
|
||||
importPaths[i] = path
|
||||
if i < len(p.Imports) {
|
||||
|
|
@ -1497,11 +1542,14 @@ func computeBuildID(p *Package) {
|
|||
fmt.Fprintf(h, "file %s\n", file)
|
||||
}
|
||||
|
||||
// Include the content of runtime/zversion.go in the hash
|
||||
// Include the content of runtime/internal/sys/zversion.go in the hash
|
||||
// for package runtime. This will give package runtime a
|
||||
// different build ID in each Go release.
|
||||
if p.Standard && p.ImportPath == "runtime" {
|
||||
data, _ := ioutil.ReadFile(filepath.Join(p.Dir, "zversion.go"))
|
||||
if p.Standard && p.ImportPath == "runtime/internal/sys" {
|
||||
data, err := ioutil.ReadFile(filepath.Join(p.Dir, "zversion.go"))
|
||||
if err != nil {
|
||||
fatalf("go: %s", err)
|
||||
}
|
||||
fmt.Fprintf(h, "zversion %q\n", string(data))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -89,8 +89,18 @@ func runRun(cmd *Command, args []string) {
|
|||
fatalf("%s", p.Error)
|
||||
}
|
||||
p.omitDWARF = true
|
||||
for _, err := range p.DepsErrors {
|
||||
errorf("%s", err)
|
||||
if len(p.DepsErrors) > 0 {
|
||||
// Since these are errors in dependencies,
|
||||
// the same error might show up multiple times,
|
||||
// once in each package that depends on it.
|
||||
// Only print each once.
|
||||
printed := map[*PackageError]bool{}
|
||||
for _, err := range p.DepsErrors {
|
||||
if !printed[err] {
|
||||
printed[err] = true
|
||||
errorf("%s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
exitIfErrors()
|
||||
if p.Name != "main" {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,6 @@ import (
|
|||
|
||||
func TestMsgInternal(t *testing.T) {
|
||||
if strings.Msg != "hello, world" {
|
||||
t.Fatal("unexpected msg: %v", strings.Msg)
|
||||
t.Fatalf("unexpected msg: %v", strings.Msg)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,6 @@ import (
|
|||
|
||||
func TestMsgExternal(t *testing.T) {
|
||||
if strings.Msg != "hello, world" {
|
||||
t.Fatal("unexpected msg: %v", strings.Msg)
|
||||
t.Fatalf("unexpected msg: %v", strings.Msg)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ var vcsGit = &vcsCmd{
|
|||
name: "Git",
|
||||
cmd: "git",
|
||||
|
||||
createCmd: []string{"clone {repo} {dir}", "-C {dir} submodule update --init --recursive"},
|
||||
createCmd: []string{"clone {repo} {dir}", "-go-internal-cd {dir} submodule update --init --recursive"},
|
||||
downloadCmd: []string{"pull --ff-only", "submodule update --init --recursive"},
|
||||
|
||||
tagCmd: []tagCmd{
|
||||
|
|
@ -335,6 +335,15 @@ func (v *vcsCmd) run1(dir string, cmdline string, keyval []string, verbose bool)
|
|||
args[i] = expand(m, arg)
|
||||
}
|
||||
|
||||
if len(args) >= 2 && args[0] == "-go-internal-cd" {
|
||||
if filepath.IsAbs(args[1]) {
|
||||
dir = args[1]
|
||||
} else {
|
||||
dir = filepath.Join(dir, args[1])
|
||||
}
|
||||
args = args[2:]
|
||||
}
|
||||
|
||||
_, err := exec.LookPath(v.cmd)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr,
|
||||
|
|
|
|||
|
|
@ -18,14 +18,14 @@ func TestRepoRootForImportPath(t *testing.T) {
|
|||
path string
|
||||
want *repoRoot
|
||||
}{
|
||||
{
|
||||
/*{
|
||||
"code.google.com/p/go",
|
||||
&repoRoot{
|
||||
vcs: vcsHg,
|
||||
repo: "https://code.google.com/p/go",
|
||||
},
|
||||
},
|
||||
/*{
|
||||
{
|
||||
"code.google.com/r/go",
|
||||
&repoRoot{
|
||||
vcs: vcsHg,
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ var cnames5 = []string{
|
|||
"REG",
|
||||
"REGREG",
|
||||
"REGREG2",
|
||||
"REGLIST",
|
||||
"SHIFT",
|
||||
"FREG",
|
||||
"PSR",
|
||||
|
|
|
|||
|
|
@ -1561,7 +1561,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
|
|||
o1 |= (uint32(p.To.Reg) & 15) << 12
|
||||
|
||||
case 5: /* bra s */
|
||||
o1 = opbra(ctxt, int(p.As), int(p.Scond))
|
||||
o1 = opbra(ctxt, p, int(p.As), int(p.Scond))
|
||||
|
||||
v := int32(-8)
|
||||
if p.To.Sym != nil {
|
||||
|
|
@ -2594,9 +2594,9 @@ func oprrr(ctxt *obj.Link, a int, sc int) uint32 {
|
|||
return 0
|
||||
}
|
||||
|
||||
func opbra(ctxt *obj.Link, a int, sc int) uint32 {
|
||||
func opbra(ctxt *obj.Link, p *obj.Prog, a int, sc int) uint32 {
|
||||
if sc&(C_SBIT|C_PBIT|C_WBIT) != 0 {
|
||||
ctxt.Diag(".nil/.nil/.W on bra instruction")
|
||||
ctxt.Diag("%v: .nil/.nil/.W on bra instruction", p)
|
||||
}
|
||||
sc &= C_SCOND
|
||||
sc ^= C_SCOND_XOR
|
||||
|
|
@ -2604,7 +2604,7 @@ func opbra(ctxt *obj.Link, a int, sc int) uint32 {
|
|||
return uint32(sc)<<28 | 0x5<<25 | 0x1<<24
|
||||
}
|
||||
if sc != 0xe {
|
||||
ctxt.Diag(".COND on bcond instruction")
|
||||
ctxt.Diag("%v: .COND on bcond instruction", p)
|
||||
}
|
||||
switch a {
|
||||
case ABEQ:
|
||||
|
|
@ -2737,7 +2737,7 @@ func olhrr(ctxt *obj.Link, i int, b int, r int, sc int) uint32 {
|
|||
|
||||
func ofsr(ctxt *obj.Link, a int, r int, v int32, b int, sc int, p *obj.Prog) uint32 {
|
||||
if sc&C_SBIT != 0 {
|
||||
ctxt.Diag(".nil on FLDR/FSTR instruction")
|
||||
ctxt.Diag(".nil on FLDR/FSTR instruction: %v", p)
|
||||
}
|
||||
o := ((uint32(sc) & C_SCOND) ^ C_SCOND_XOR) << 28
|
||||
if sc&C_PBIT == 0 {
|
||||
|
|
|
|||
|
|
@ -655,15 +655,8 @@ const (
|
|||
AUCVTFS
|
||||
AUCVTFWD
|
||||
AUCVTFWS
|
||||
AHISTORY
|
||||
ANAME
|
||||
AWORD
|
||||
ADYNT
|
||||
AINIT
|
||||
ADWORD
|
||||
ASIGNAME
|
||||
AGOK
|
||||
AEND
|
||||
AFCSELS
|
||||
AFCSELD
|
||||
AFMAXS
|
||||
|
|
|
|||
|
|
@ -312,15 +312,8 @@ var Anames = []string{
|
|||
"UCVTFS",
|
||||
"UCVTFWD",
|
||||
"UCVTFWS",
|
||||
"HISTORY",
|
||||
"NAME",
|
||||
"WORD",
|
||||
"DYNT",
|
||||
"INIT",
|
||||
"DWORD",
|
||||
"SIGNAME",
|
||||
"GOK",
|
||||
"END",
|
||||
"FCSELS",
|
||||
"FCSELD",
|
||||
"FMAXS",
|
||||
|
|
|
|||
|
|
@ -693,7 +693,7 @@ func flushpool(ctxt *obj.Link, p *obj.Prog, skip int) {
|
|||
q.Link = ctxt.Blitrl
|
||||
q.Lineno = p.Lineno
|
||||
ctxt.Blitrl = q
|
||||
} else if p.Pc+int64(pool.size)-int64(pool.start) < 1024*1024 {
|
||||
} else if p.Pc+int64(pool.size)-int64(pool.start) < maxPCDisp {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -826,9 +826,15 @@ func regoff(ctxt *obj.Link, a *obj.Addr) uint32 {
|
|||
return uint32(ctxt.Instoffset)
|
||||
}
|
||||
|
||||
// Maximum PC-relative displacement.
|
||||
// The actual limit is ±2²⁰, but we are conservative
|
||||
// to avoid needing to recompute the literal pool flush points
|
||||
// as span-dependent jumps are enlarged.
|
||||
const maxPCDisp = 512 * 1024
|
||||
|
||||
// ispcdisp reports whether v is a valid PC-relative displacement.
|
||||
func ispcdisp(v int32) bool {
|
||||
/* pc-relative addressing will reach? */
|
||||
return v >= -0xfffff && v <= 0xfffff && (v&3) == 0
|
||||
return -maxPCDisp < v && v < maxPCDisp && v&3 == 0
|
||||
}
|
||||
|
||||
func isaddcon(v int64) bool {
|
||||
|
|
@ -3654,7 +3660,8 @@ func brdist(ctxt *obj.Link, p *obj.Prog, preshift int, flen int, shift int) int6
|
|||
v >>= uint(shift)
|
||||
t = int64(1) << uint(flen-1)
|
||||
if v < -t || v >= t {
|
||||
ctxt.Diag("branch too far\n%v", p)
|
||||
ctxt.Diag("branch too far %#x vs %#x [%p]\n%v\n%v", v, t, ctxt.Blitrl, p, p.Pcond)
|
||||
panic("branch too far")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -604,12 +604,13 @@ type Link struct {
|
|||
Autosize int32
|
||||
Armsize int32
|
||||
Pc int64
|
||||
Diag func(string, ...interface{})
|
||||
DiagFunc func(string, ...interface{})
|
||||
Mode int
|
||||
Cursym *LSym
|
||||
Version int
|
||||
Textp *LSym
|
||||
Etextp *LSym
|
||||
Errors int
|
||||
|
||||
// state for writing objects
|
||||
Text *LSym
|
||||
|
|
@ -618,6 +619,11 @@ type Link struct {
|
|||
Edata *LSym
|
||||
}
|
||||
|
||||
func (ctxt *Link) Diag(format string, args ...interface{}) {
|
||||
ctxt.Errors++
|
||||
ctxt.DiagFunc(format, args...)
|
||||
}
|
||||
|
||||
// The smallest possible offset from the hardware stack pointer to a local
|
||||
// variable on the stack. Architectures that use a link register save its value
|
||||
// on the stack in the function prologue and so always have a pointer between
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ const (
|
|||
REG_LO
|
||||
|
||||
// co-processor 0 control registers
|
||||
REG_M0 = obj.RBaseMIPS64 + 1024 + iota
|
||||
REG_M0
|
||||
REG_M1
|
||||
REG_M2
|
||||
REG_M3
|
||||
|
|
@ -148,7 +148,7 @@ const (
|
|||
REG_M31
|
||||
|
||||
// FPU control registers
|
||||
REG_FCR0 = obj.RBaseMIPS64 + 2048 + iota
|
||||
REG_FCR0
|
||||
REG_FCR1
|
||||
REG_FCR2
|
||||
REG_FCR3
|
||||
|
|
@ -181,6 +181,8 @@ const (
|
|||
REG_FCR30
|
||||
REG_FCR31
|
||||
|
||||
REG_LAST = REG_FCR31 // the last defined register
|
||||
|
||||
REG_SPECIAL = REG_M0
|
||||
|
||||
REGZERO = REG_R0 /* set to zero */
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ import (
|
|||
)
|
||||
|
||||
func init() {
|
||||
obj.RegisterRegister(obj.RBaseMIPS64, REG_FCR0+1024, Rconv)
|
||||
obj.RegisterRegister(obj.RBaseMIPS64, REG_LAST&^1023+1024, Rconv)
|
||||
obj.RegisterOpcode(obj.ABaseMIPS64, Anames)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -532,7 +532,7 @@ const (
|
|||
RBaseARM = 3 * 1024
|
||||
RBasePPC64 = 4 * 1024 // range [4k, 8k)
|
||||
RBaseARM64 = 8 * 1024 // range [8k, 13k)
|
||||
RBaseMIPS64 = 13 * 1024 // range [13k, 16k)
|
||||
RBaseMIPS64 = 13 * 1024 // range [13k, 14k)
|
||||
)
|
||||
|
||||
// RegisterRegister binds a pretty-printer (Rconv) for register
|
||||
|
|
|
|||
|
|
@ -95,7 +95,11 @@ const (
|
|||
ADIVL
|
||||
ADIVW
|
||||
AENTER
|
||||
AHADDPD
|
||||
AHADDPS
|
||||
AHLT
|
||||
AHSUBPD
|
||||
AHSUBPS
|
||||
AIDIVB
|
||||
AIDIVL
|
||||
AIDIVW
|
||||
|
|
@ -187,7 +191,9 @@ const (
|
|||
APAUSE
|
||||
APOPAL
|
||||
APOPAW
|
||||
APOPCNT
|
||||
APOPCNTW
|
||||
APOPCNTL
|
||||
APOPCNTQ
|
||||
APOPFL
|
||||
APOPFW
|
||||
APOPL
|
||||
|
|
@ -514,10 +520,22 @@ const (
|
|||
AADDPS
|
||||
AADDSD
|
||||
AADDSS
|
||||
AANDNL
|
||||
AANDNQ
|
||||
AANDNPD
|
||||
AANDNPS
|
||||
AANDPD
|
||||
AANDPS
|
||||
ABEXTRL
|
||||
ABEXTRQ
|
||||
ABLSIL
|
||||
ABLSIQ
|
||||
ABLSMSKL
|
||||
ABLSMSKQ
|
||||
ABLSRL
|
||||
ABLSRQ
|
||||
ABZHIL
|
||||
ABZHIQ
|
||||
ACMPPD
|
||||
ACMPPS
|
||||
ACMPSD
|
||||
|
|
@ -555,6 +573,7 @@ const (
|
|||
AFXRSTOR64
|
||||
AFXSAVE
|
||||
AFXSAVE64
|
||||
ALDDQU
|
||||
ALDMXCSR
|
||||
AMASKMOVOU
|
||||
AMASKMOVQ
|
||||
|
|
@ -591,6 +610,8 @@ const (
|
|||
AMULPS
|
||||
AMULSD
|
||||
AMULSS
|
||||
AMULXL
|
||||
AMULXQ
|
||||
AORPD
|
||||
AORPS
|
||||
APACKSSLW
|
||||
|
|
@ -604,15 +625,15 @@ const (
|
|||
APADDUSB
|
||||
APADDUSW
|
||||
APADDW
|
||||
APAND
|
||||
APANDB
|
||||
APANDL
|
||||
APANDN
|
||||
APANDSB
|
||||
APANDSW
|
||||
APANDUSB
|
||||
APANDUSW
|
||||
APANDW
|
||||
APAND
|
||||
APANDN
|
||||
APAVGB
|
||||
APAVGW
|
||||
APCMPEQB
|
||||
|
|
@ -621,10 +642,14 @@ const (
|
|||
APCMPGTB
|
||||
APCMPGTL
|
||||
APCMPGTW
|
||||
APEXTRW
|
||||
APDEPL
|
||||
APDEPQ
|
||||
APEXTL
|
||||
APEXTQ
|
||||
APEXTRB
|
||||
APEXTRD
|
||||
APEXTRQ
|
||||
APEXTRW
|
||||
APFACC
|
||||
APFADD
|
||||
APFCMPEQ
|
||||
|
|
@ -636,42 +661,63 @@ const (
|
|||
APFNACC
|
||||
APFPNACC
|
||||
APFRCP
|
||||
APFRCPIT1
|
||||
APFRCPI2T
|
||||
APFRCPIT1
|
||||
APFRSQIT1
|
||||
APFRSQRT
|
||||
APFSUB
|
||||
APFSUBR
|
||||
APINSRW
|
||||
APHADDD
|
||||
APHADDSW
|
||||
APHADDW
|
||||
APHMINPOSUW
|
||||
APHSUBD
|
||||
APHSUBSW
|
||||
APHSUBW
|
||||
APINSRB
|
||||
APINSRD
|
||||
APINSRQ
|
||||
APINSRW
|
||||
APMADDWL
|
||||
APMAXSW
|
||||
APMAXUB
|
||||
APMINSW
|
||||
APMINUB
|
||||
APMOVMSKB
|
||||
APMOVSXBD
|
||||
APMOVSXBQ
|
||||
APMOVSXBW
|
||||
APMOVSXDQ
|
||||
APMOVSXWD
|
||||
APMOVSXWQ
|
||||
APMOVZXBD
|
||||
APMOVZXBQ
|
||||
APMOVZXBW
|
||||
APMOVZXDQ
|
||||
APMOVZXWD
|
||||
APMOVZXWQ
|
||||
APMULDQ
|
||||
APMULHRW
|
||||
APMULHUW
|
||||
APMULHW
|
||||
APMULLD
|
||||
APMULLW
|
||||
APMULULQ
|
||||
APOR
|
||||
APSADBW
|
||||
APSHUFB
|
||||
APSHUFHW
|
||||
APSHUFL
|
||||
APSHUFLW
|
||||
APSHUFW
|
||||
APSHUFB
|
||||
APSLLO
|
||||
APSLLL
|
||||
APSLLO
|
||||
APSLLQ
|
||||
APSLLW
|
||||
APSRAL
|
||||
APSRAW
|
||||
APSRLO
|
||||
APSRLL
|
||||
APSRLO
|
||||
APSRLQ
|
||||
APSRLW
|
||||
APSUBB
|
||||
|
|
@ -696,6 +742,12 @@ const (
|
|||
ARCPSS
|
||||
ARSQRTPS
|
||||
ARSQRTSS
|
||||
ASARXL
|
||||
ASARXQ
|
||||
ASHLXL
|
||||
ASHLXQ
|
||||
ASHRXL
|
||||
ASHRXQ
|
||||
ASHUFPD
|
||||
ASHUFPS
|
||||
ASQRTPD
|
||||
|
|
@ -755,9 +807,9 @@ const (
|
|||
APCLMULQDQ
|
||||
|
||||
AVZEROUPPER
|
||||
AMOVHDU
|
||||
AMOVNTHD
|
||||
AMOVHDA
|
||||
AVMOVDQU
|
||||
AVMOVNTDQ
|
||||
AVMOVDQA
|
||||
AVPCMPEQB
|
||||
AVPXOR
|
||||
AVPMOVMSKB
|
||||
|
|
@ -870,6 +922,23 @@ const (
|
|||
REG_X14
|
||||
REG_X15
|
||||
|
||||
REG_Y0
|
||||
REG_Y1
|
||||
REG_Y2
|
||||
REG_Y3
|
||||
REG_Y4
|
||||
REG_Y5
|
||||
REG_Y6
|
||||
REG_Y7
|
||||
REG_Y8
|
||||
REG_Y9
|
||||
REG_Y10
|
||||
REG_Y11
|
||||
REG_Y12
|
||||
REG_Y13
|
||||
REG_Y14
|
||||
REG_Y15
|
||||
|
||||
REG_CS
|
||||
REG_SS
|
||||
REG_DS
|
||||
|
|
|
|||
|
|
@ -57,7 +57,11 @@ var Anames = []string{
|
|||
"DIVL",
|
||||
"DIVW",
|
||||
"ENTER",
|
||||
"HADDPD",
|
||||
"HADDPS",
|
||||
"HLT",
|
||||
"HSUBPD",
|
||||
"HSUBPS",
|
||||
"IDIVB",
|
||||
"IDIVL",
|
||||
"IDIVW",
|
||||
|
|
@ -149,7 +153,9 @@ var Anames = []string{
|
|||
"PAUSE",
|
||||
"POPAL",
|
||||
"POPAW",
|
||||
"POPCNT",
|
||||
"POPCNTW",
|
||||
"POPCNTL",
|
||||
"POPCNTQ",
|
||||
"POPFL",
|
||||
"POPFW",
|
||||
"POPL",
|
||||
|
|
@ -457,10 +463,22 @@ var Anames = []string{
|
|||
"ADDPS",
|
||||
"ADDSD",
|
||||
"ADDSS",
|
||||
"ANDNL",
|
||||
"ANDNQ",
|
||||
"ANDNPD",
|
||||
"ANDNPS",
|
||||
"ANDPD",
|
||||
"ANDPS",
|
||||
"BEXTRL",
|
||||
"BEXTRQ",
|
||||
"BLSIL",
|
||||
"BLSIQ",
|
||||
"BLSMSKL",
|
||||
"BLSMSKQ",
|
||||
"BLSRL",
|
||||
"BLSRQ",
|
||||
"BZHIL",
|
||||
"BZHIQ",
|
||||
"CMPPD",
|
||||
"CMPPS",
|
||||
"CMPSD",
|
||||
|
|
@ -498,6 +516,7 @@ var Anames = []string{
|
|||
"FXRSTOR64",
|
||||
"FXSAVE",
|
||||
"FXSAVE64",
|
||||
"LDDQU",
|
||||
"LDMXCSR",
|
||||
"MASKMOVOU",
|
||||
"MASKMOVQ",
|
||||
|
|
@ -534,6 +553,8 @@ var Anames = []string{
|
|||
"MULPS",
|
||||
"MULSD",
|
||||
"MULSS",
|
||||
"MULXL",
|
||||
"MULXQ",
|
||||
"ORPD",
|
||||
"ORPS",
|
||||
"PACKSSLW",
|
||||
|
|
@ -547,15 +568,15 @@ var Anames = []string{
|
|||
"PADDUSB",
|
||||
"PADDUSW",
|
||||
"PADDW",
|
||||
"PAND",
|
||||
"PANDB",
|
||||
"PANDL",
|
||||
"PANDN",
|
||||
"PANDSB",
|
||||
"PANDSW",
|
||||
"PANDUSB",
|
||||
"PANDUSW",
|
||||
"PANDW",
|
||||
"PAND",
|
||||
"PANDN",
|
||||
"PAVGB",
|
||||
"PAVGW",
|
||||
"PCMPEQB",
|
||||
|
|
@ -564,10 +585,14 @@ var Anames = []string{
|
|||
"PCMPGTB",
|
||||
"PCMPGTL",
|
||||
"PCMPGTW",
|
||||
"PEXTRW",
|
||||
"PDEPL",
|
||||
"PDEPQ",
|
||||
"PEXTL",
|
||||
"PEXTQ",
|
||||
"PEXTRB",
|
||||
"PEXTRD",
|
||||
"PEXTRQ",
|
||||
"PEXTRW",
|
||||
"PFACC",
|
||||
"PFADD",
|
||||
"PFCMPEQ",
|
||||
|
|
@ -579,42 +604,63 @@ var Anames = []string{
|
|||
"PFNACC",
|
||||
"PFPNACC",
|
||||
"PFRCP",
|
||||
"PFRCPIT1",
|
||||
"PFRCPI2T",
|
||||
"PFRCPIT1",
|
||||
"PFRSQIT1",
|
||||
"PFRSQRT",
|
||||
"PFSUB",
|
||||
"PFSUBR",
|
||||
"PINSRW",
|
||||
"PHADDD",
|
||||
"PHADDSW",
|
||||
"PHADDW",
|
||||
"PHMINPOSUW",
|
||||
"PHSUBD",
|
||||
"PHSUBSW",
|
||||
"PHSUBW",
|
||||
"PINSRB",
|
||||
"PINSRD",
|
||||
"PINSRQ",
|
||||
"PINSRW",
|
||||
"PMADDWL",
|
||||
"PMAXSW",
|
||||
"PMAXUB",
|
||||
"PMINSW",
|
||||
"PMINUB",
|
||||
"PMOVMSKB",
|
||||
"PMOVSXBD",
|
||||
"PMOVSXBQ",
|
||||
"PMOVSXBW",
|
||||
"PMOVSXDQ",
|
||||
"PMOVSXWD",
|
||||
"PMOVSXWQ",
|
||||
"PMOVZXBD",
|
||||
"PMOVZXBQ",
|
||||
"PMOVZXBW",
|
||||
"PMOVZXDQ",
|
||||
"PMOVZXWD",
|
||||
"PMOVZXWQ",
|
||||
"PMULDQ",
|
||||
"PMULHRW",
|
||||
"PMULHUW",
|
||||
"PMULHW",
|
||||
"PMULLD",
|
||||
"PMULLW",
|
||||
"PMULULQ",
|
||||
"POR",
|
||||
"PSADBW",
|
||||
"PSHUFB",
|
||||
"PSHUFHW",
|
||||
"PSHUFL",
|
||||
"PSHUFLW",
|
||||
"PSHUFW",
|
||||
"PSHUFB",
|
||||
"PSLLO",
|
||||
"PSLLL",
|
||||
"PSLLO",
|
||||
"PSLLQ",
|
||||
"PSLLW",
|
||||
"PSRAL",
|
||||
"PSRAW",
|
||||
"PSRLO",
|
||||
"PSRLL",
|
||||
"PSRLO",
|
||||
"PSRLQ",
|
||||
"PSRLW",
|
||||
"PSUBB",
|
||||
|
|
@ -639,6 +685,12 @@ var Anames = []string{
|
|||
"RCPSS",
|
||||
"RSQRTPS",
|
||||
"RSQRTSS",
|
||||
"SARXL",
|
||||
"SARXQ",
|
||||
"SHLXL",
|
||||
"SHLXQ",
|
||||
"SHRXL",
|
||||
"SHRXQ",
|
||||
"SHUFPD",
|
||||
"SHUFPS",
|
||||
"SQRTPD",
|
||||
|
|
@ -690,9 +742,9 @@ var Anames = []string{
|
|||
"PSHUFD",
|
||||
"PCLMULQDQ",
|
||||
"VZEROUPPER",
|
||||
"MOVHDU",
|
||||
"MOVNTHD",
|
||||
"MOVHDA",
|
||||
"VMOVDQU",
|
||||
"VMOVNTDQ",
|
||||
"VMOVDQA",
|
||||
"VPCMPEQB",
|
||||
"VPXOR",
|
||||
"VPMOVMSKB",
|
||||
|
|
|
|||
|
|
@ -148,6 +148,8 @@ const (
|
|||
Ymm
|
||||
Yxr
|
||||
Yxm
|
||||
Yyr
|
||||
Yym
|
||||
Ytls
|
||||
Ytextsize
|
||||
Yindir
|
||||
|
|
@ -181,7 +183,6 @@ const (
|
|||
Zm_r
|
||||
Zm2_r
|
||||
Zm_r_xm
|
||||
Zm_r_xm_vex
|
||||
Zm_r_i_xm
|
||||
Zm_r_3d
|
||||
Zm_r_xm_nr
|
||||
|
|
@ -195,8 +196,6 @@ const (
|
|||
Zpseudo
|
||||
Zr_m
|
||||
Zr_m_xm
|
||||
Zr_m_xm_vex
|
||||
Zr_r_r_vex
|
||||
Zrp_
|
||||
Z_ib
|
||||
Z_il
|
||||
|
|
@ -206,29 +205,32 @@ const (
|
|||
Zil_rr
|
||||
Zclr
|
||||
Zbyte
|
||||
Zvex_rm_v_r
|
||||
Zvex_r_v_rm
|
||||
Zvex_v_rm_r
|
||||
Zmax
|
||||
)
|
||||
|
||||
const (
|
||||
Px = 0
|
||||
Px1 = 1 // symbolic; exact value doesn't matter
|
||||
P32 = 0x32 /* 32-bit only */
|
||||
Pe = 0x66 /* operand escape */
|
||||
Pm = 0x0f /* 2byte opcode escape */
|
||||
Pq = 0xff /* both escapes: 66 0f */
|
||||
Pb = 0xfe /* byte operands */
|
||||
Pf2 = 0xf2 /* xmm escape 1: f2 0f */
|
||||
Pf3 = 0xf3 /* xmm escape 2: f3 0f */
|
||||
Pq3 = 0x67 /* xmm escape 3: 66 48 0f */
|
||||
Pfw = 0xf4 /* Pf3 with Rex.w: f3 48 0f */
|
||||
Pvex1 = 0xc5 /* 66.0f escape, vex encoding */
|
||||
Pvex2 = 0xc6 /* f3.0f escape, vex encoding */
|
||||
Pvex3 = 0xc7 /* 66.0f38 escape, vex encoding */
|
||||
Pw = 0x48 /* Rex.w */
|
||||
Pw8 = 0x90 // symbolic; exact value doesn't matter
|
||||
Py = 0x80 /* defaults to 64-bit mode */
|
||||
Py1 = 0x81 // symbolic; exact value doesn't matter
|
||||
Py3 = 0x83 // symbolic; exact value doesn't matter
|
||||
Px = 0
|
||||
Px1 = 1 // symbolic; exact value doesn't matter
|
||||
P32 = 0x32 /* 32-bit only */
|
||||
Pe = 0x66 /* operand escape */
|
||||
Pm = 0x0f /* 2byte opcode escape */
|
||||
Pq = 0xff /* both escapes: 66 0f */
|
||||
Pb = 0xfe /* byte operands */
|
||||
Pf2 = 0xf2 /* xmm escape 1: f2 0f */
|
||||
Pf3 = 0xf3 /* xmm escape 2: f3 0f */
|
||||
Pef3 = 0xf5 /* xmm escape 2 with 16-bit prefix: 66 f3 0f */
|
||||
Pq3 = 0x67 /* xmm escape 3: 66 48 0f */
|
||||
Pq4 = 0x68 /* xmm escape 4: 66 0F 38 */
|
||||
Pfw = 0xf4 /* Pf3 with Rex.w: f3 48 0f */
|
||||
Pw = 0x48 /* Rex.w */
|
||||
Pw8 = 0x90 // symbolic; exact value doesn't matter
|
||||
Py = 0x80 /* defaults to 64-bit mode */
|
||||
Py1 = 0x81 // symbolic; exact value doesn't matter
|
||||
Py3 = 0x83 // symbolic; exact value doesn't matter
|
||||
Pvex = 0x84 // symbolic: exact value doesn't matter
|
||||
|
||||
Rxw = 1 << 3 /* =1, 64-bit operand size */
|
||||
Rxr = 1 << 2 /* extend modrm reg */
|
||||
|
|
@ -236,6 +238,75 @@ const (
|
|||
Rxb = 1 << 0 /* extend modrm r/m, sib base, or opcode reg */
|
||||
)
|
||||
|
||||
const (
|
||||
// Encoding for VEX prefix in tables.
|
||||
// The P, L, and W fields are chosen to match
|
||||
// their eventual locations in the VEX prefix bytes.
|
||||
|
||||
// P field - 2 bits
|
||||
vex66 = 1 << 0
|
||||
vexF3 = 2 << 0
|
||||
vexF2 = 3 << 0
|
||||
// L field - 1 bit
|
||||
vexLZ = 0 << 2
|
||||
vexLIG = 0 << 2
|
||||
vex128 = 0 << 2
|
||||
vex256 = 1 << 2
|
||||
// W field - 1 bit
|
||||
vexWIG = 0 << 7
|
||||
vexW0 = 0 << 7
|
||||
vexW1 = 1 << 7
|
||||
// M field - 5 bits, but mostly reserved; we can store up to 4
|
||||
vex0F = 1 << 3
|
||||
vex0F38 = 2 << 3
|
||||
vex0F3A = 3 << 3
|
||||
|
||||
// Combinations used in the manual.
|
||||
VEX_128_0F_WIG = vex128 | vex0F | vexWIG
|
||||
VEX_128_66_0F_W0 = vex128 | vex66 | vex0F | vexW0
|
||||
VEX_128_66_0F_W1 = vex128 | vex66 | vex0F | vexW1
|
||||
VEX_128_66_0F_WIG = vex128 | vex66 | vex0F | vexWIG
|
||||
VEX_128_66_0F38_W0 = vex128 | vex66 | vex0F38 | vexW0
|
||||
VEX_128_66_0F38_W1 = vex128 | vex66 | vex0F38 | vexW1
|
||||
VEX_128_66_0F38_WIG = vex128 | vex66 | vex0F38 | vexWIG
|
||||
VEX_128_66_0F3A_W0 = vex128 | vex66 | vex0F3A | vexW0
|
||||
VEX_128_66_0F3A_W1 = vex128 | vex66 | vex0F3A | vexW1
|
||||
VEX_128_66_0F3A_WIG = vex128 | vex66 | vex0F3A | vexWIG
|
||||
VEX_128_F2_0F_WIG = vex128 | vexF2 | vex0F | vexWIG
|
||||
VEX_128_F3_0F_WIG = vex128 | vexF3 | vex0F | vexWIG
|
||||
VEX_256_66_0F_WIG = vex256 | vex66 | vex0F | vexWIG
|
||||
VEX_256_66_0F38_W0 = vex256 | vex66 | vex0F38 | vexW0
|
||||
VEX_256_66_0F38_W1 = vex256 | vex66 | vex0F38 | vexW1
|
||||
VEX_256_66_0F38_WIG = vex256 | vex66 | vex0F38 | vexWIG
|
||||
VEX_256_66_0F3A_W0 = vex256 | vex66 | vex0F3A | vexW0
|
||||
VEX_256_66_0F3A_W1 = vex256 | vex66 | vex0F3A | vexW1
|
||||
VEX_256_66_0F3A_WIG = vex256 | vex66 | vex0F3A | vexWIG
|
||||
VEX_256_F2_0F_WIG = vex256 | vexF2 | vex0F | vexWIG
|
||||
VEX_256_F3_0F_WIG = vex256 | vexF3 | vex0F | vexWIG
|
||||
VEX_LIG_0F_WIG = vexLIG | vex0F | vexWIG
|
||||
VEX_LIG_66_0F_WIG = vexLIG | vex66 | vex0F | vexWIG
|
||||
VEX_LIG_66_0F38_W0 = vexLIG | vex66 | vex0F38 | vexW0
|
||||
VEX_LIG_66_0F38_W1 = vexLIG | vex66 | vex0F38 | vexW1
|
||||
VEX_LIG_66_0F3A_WIG = vexLIG | vex66 | vex0F3A | vexWIG
|
||||
VEX_LIG_F2_0F_W0 = vexLIG | vexF2 | vex0F | vexW0
|
||||
VEX_LIG_F2_0F_W1 = vexLIG | vexF2 | vex0F | vexW1
|
||||
VEX_LIG_F2_0F_WIG = vexLIG | vexF2 | vex0F | vexWIG
|
||||
VEX_LIG_F3_0F_W0 = vexLIG | vexF3 | vex0F | vexW0
|
||||
VEX_LIG_F3_0F_W1 = vexLIG | vexF3 | vex0F | vexW1
|
||||
VEX_LIG_F3_0F_WIG = vexLIG | vexF3 | vex0F | vexWIG
|
||||
VEX_LZ_0F_WIG = vexLZ | vex0F | vexWIG
|
||||
VEX_LZ_0F38_W0 = vexLZ | vex0F38 | vexW0
|
||||
VEX_LZ_0F38_W1 = vexLZ | vex0F38 | vexW1
|
||||
VEX_LZ_66_0F38_W0 = vexLZ | vex66 | vex0F38 | vexW0
|
||||
VEX_LZ_66_0F38_W1 = vexLZ | vex66 | vex0F38 | vexW1
|
||||
VEX_LZ_F2_0F38_W0 = vexLZ | vexF2 | vex0F38 | vexW0
|
||||
VEX_LZ_F2_0F38_W1 = vexLZ | vexF2 | vex0F38 | vexW1
|
||||
VEX_LZ_F2_0F3A_W0 = vexLZ | vexF2 | vex0F3A | vexW0
|
||||
VEX_LZ_F2_0F3A_W1 = vexLZ | vexF2 | vex0F3A | vexW1
|
||||
VEX_LZ_F3_0F38_W0 = vexLZ | vexF3 | vex0F38 | vexW0
|
||||
VEX_LZ_F3_0F38_W1 = vexLZ | vexF3 | vex0F38 | vexW1
|
||||
)
|
||||
|
||||
var ycover [Ymax * Ymax]uint8
|
||||
|
||||
var reg [MAXREG]int
|
||||
|
|
@ -606,6 +677,10 @@ var yxm = []ytab{
|
|||
{Yxm, Ynone, Yxr, Zm_r_xm, 1},
|
||||
}
|
||||
|
||||
var yxm_q4 = []ytab{
|
||||
{Yxm, Ynone, Yxr, Zm_r, 1},
|
||||
}
|
||||
|
||||
var yxcvm1 = []ytab{
|
||||
{Yxm, Ynone, Yxr, Zm_r_xm, 2},
|
||||
{Yxm, Ynone, Ymr, Zm_r_xm, 2},
|
||||
|
|
@ -630,20 +705,6 @@ var yxr_ml = []ytab{
|
|||
{Yxr, Ynone, Yml, Zr_m_xm, 1},
|
||||
}
|
||||
|
||||
var yxr_ml_vex = []ytab{
|
||||
{Yxr, Ynone, Yml, Zr_m_xm_vex, 1},
|
||||
}
|
||||
|
||||
var yml_xr_vex = []ytab{
|
||||
{Yml, Ynone, Yxr, Zm_r_xm_vex, 1},
|
||||
{Yxr, Ynone, Yxr, Zm_r_xm_vex, 1},
|
||||
}
|
||||
|
||||
var yxm_xm_xm = []ytab{
|
||||
{Yxr, Yxr, Yxr, Zr_r_r_vex, 1},
|
||||
{Yxm, Yxr, Yxr, Zr_r_r_vex, 1},
|
||||
}
|
||||
|
||||
var ymr = []ytab{
|
||||
{Ymr, Ynone, Ymr, Zm_r, 1},
|
||||
}
|
||||
|
|
@ -660,11 +721,6 @@ var yxcmpi = []ytab{
|
|||
{Yxm, Yxr, Yi8, Zm_r_i_xm, 2},
|
||||
}
|
||||
|
||||
var yxmov_vex = []ytab{
|
||||
{Yxm, Ynone, Yxr, Zm_r_xm_vex, 1},
|
||||
{Yxr, Ynone, Yxm, Zr_m_xm_vex, 1},
|
||||
}
|
||||
|
||||
var yxmov = []ytab{
|
||||
{Yxm, Ynone, Yxr, Zm_r_xm, 1},
|
||||
{Yxr, Ynone, Yxm, Zr_m_xm, 1},
|
||||
|
|
@ -743,10 +799,6 @@ var ymskb = []ytab{
|
|||
{Ymr, Ynone, Yrl, Zm_r_xm, 1},
|
||||
}
|
||||
|
||||
var ymskb_vex = []ytab{
|
||||
{Yxr, Ynone, Yrl, Zm_r_xm_vex, 2},
|
||||
}
|
||||
|
||||
var ycrc32l = []ytab{
|
||||
{Yml, Ynone, Yrl, Zlitm_r, 0},
|
||||
}
|
||||
|
|
@ -771,6 +823,81 @@ var yxabort = []ytab{
|
|||
{Yu8, Ynone, Ynone, Zib_, 1},
|
||||
}
|
||||
|
||||
var ylddqu = []ytab{
|
||||
{Ym, Ynone, Yxr, Zm_r, 1},
|
||||
}
|
||||
|
||||
// VEX instructions that come in two forms:
|
||||
// VTHING xmm2/m128, xmmV, xmm1
|
||||
// VTHING ymm2/m256, ymmV, ymm1
|
||||
// The opcode array in the corresponding Optab entry
|
||||
// should contain the (VEX prefixes, opcode byte) pair
|
||||
// for each of the two forms.
|
||||
// For example, the entries for VPXOR are:
|
||||
//
|
||||
// VPXOR xmm2/m128, xmmV, xmm1
|
||||
// VEX.NDS.128.66.0F.WIG EF /r
|
||||
//
|
||||
// VPXOR ymm2/m256, ymmV, ymm1
|
||||
// VEX.NDS.256.66.0F.WIG EF /r
|
||||
//
|
||||
// The NDS/NDD/DDS part can be dropped, producing this
|
||||
// Optab entry:
|
||||
//
|
||||
// {AVPXOR, yvex_xy3, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0xEF, VEX_256_66_0F_WIG, 0xEF}}
|
||||
//
|
||||
var yvex_xy3 = []ytab{
|
||||
{Yxm, Yxr, Yxr, Zvex_rm_v_r, 2},
|
||||
{Yym, Yyr, Yyr, Zvex_rm_v_r, 2},
|
||||
}
|
||||
|
||||
var yvex_r3 = []ytab{
|
||||
{Yml, Yrl, Yrl, Zvex_rm_v_r, 2},
|
||||
{Yml, Yrl, Yrl, Zvex_rm_v_r, 2},
|
||||
}
|
||||
|
||||
var yvex_vmr3 = []ytab{
|
||||
{Yrl, Yml, Yrl, Zvex_v_rm_r, 2},
|
||||
{Yrl, Yml, Yrl, Zvex_v_rm_r, 2},
|
||||
}
|
||||
|
||||
var yvex_xy2 = []ytab{
|
||||
{Yxm, Ynone, Yxr, Zvex_rm_v_r, 2},
|
||||
{Yym, Ynone, Yyr, Zvex_rm_v_r, 2},
|
||||
}
|
||||
|
||||
var yvex_xyr2 = []ytab{
|
||||
{Yxr, Ynone, Yrl, Zvex_rm_v_r, 2},
|
||||
{Yyr, Ynone, Yrl, Zvex_rm_v_r, 2},
|
||||
}
|
||||
|
||||
var yvex_vmovdqa = []ytab{
|
||||
{Yxm, Ynone, Yxr, Zvex_rm_v_r, 2},
|
||||
{Yxr, Ynone, Yxm, Zvex_r_v_rm, 2},
|
||||
{Yym, Ynone, Yyr, Zvex_rm_v_r, 2},
|
||||
{Yyr, Ynone, Yym, Zvex_r_v_rm, 2},
|
||||
}
|
||||
|
||||
var yvex_vmovntdq = []ytab{
|
||||
{Yxr, Ynone, Ym, Zvex_r_v_rm, 2},
|
||||
{Yyr, Ynone, Ym, Zvex_r_v_rm, 2},
|
||||
}
|
||||
|
||||
var yvex_vpbroadcast = []ytab{
|
||||
{Yxm, Ynone, Yxr, Zvex_rm_v_r, 2},
|
||||
{Yxm, Ynone, Yyr, Zvex_rm_v_r, 2},
|
||||
}
|
||||
|
||||
var yvex_xxmyxm = []ytab{
|
||||
{Yxr, Ynone, Yxm, Zvex_r_v_rm, 2},
|
||||
{Yyr, Ynone, Yxm, Zvex_r_v_rm, 2},
|
||||
}
|
||||
|
||||
var ymmxmm0f38 = []ytab{
|
||||
{Ymm, Ynone, Ymr, Zlitm_r, 3},
|
||||
{Yxm, Ynone, Yxr, Zlitm_r, 5},
|
||||
}
|
||||
|
||||
/*
|
||||
* You are doasm, holding in your hand a Prog* with p->as set to, say, ACRC32,
|
||||
* and p->from and p->to as operands (Addr*). The linker scans optab to find
|
||||
|
|
@ -1044,9 +1171,14 @@ var optab =
|
|||
{AJPC, yjcond, Px, [23]uint8{0x7b, 0x8b}},
|
||||
{AJPL, yjcond, Px, [23]uint8{0x79, 0x89}},
|
||||
{AJPS, yjcond, Px, [23]uint8{0x7a, 0x8a}},
|
||||
{AHADDPD, yxm, Pq, [23]uint8{0x7c}},
|
||||
{AHADDPS, yxm, Pf2, [23]uint8{0x7c}},
|
||||
{AHSUBPD, yxm, Pq, [23]uint8{0x7d}},
|
||||
{AHSUBPS, yxm, Pf2, [23]uint8{0x7d}},
|
||||
{ALAHF, ynone, Px, [23]uint8{0x9f}},
|
||||
{ALARL, yml_rl, Pm, [23]uint8{0x02}},
|
||||
{ALARW, yml_rl, Pq, [23]uint8{0x02}},
|
||||
{ALDDQU, ylddqu, Pf2, [23]uint8{0xf0}},
|
||||
{ALDMXCSR, ysvrs, Pm, [23]uint8{0xae, 02, 0xae, 02}},
|
||||
{ALEAL, ym_rl, Px, [23]uint8{0x8d}},
|
||||
{ALEAQ, ym_rl, Pw, [23]uint8{0x8d}},
|
||||
|
|
@ -1191,6 +1323,13 @@ var optab =
|
|||
{APFRSQRT, ymfp, Px, [23]uint8{0x97}},
|
||||
{APFSUB, ymfp, Px, [23]uint8{0x9a}},
|
||||
{APFSUBR, ymfp, Px, [23]uint8{0xaa}},
|
||||
{APHADDD, ymmxmm0f38, Px, [23]uint8{0x0F, 0x38, 0x02, 0, 0x66, 0x0F, 0x38, 0x02, 0}},
|
||||
{APHADDSW, yxm_q4, Pq4, [23]uint8{0x03}},
|
||||
{APHADDW, yxm_q4, Pq4, [23]uint8{0x01}},
|
||||
{APHMINPOSUW, yxm_q4, Pq4, [23]uint8{0x41}},
|
||||
{APHSUBD, yxm_q4, Pq4, [23]uint8{0x06}},
|
||||
{APHSUBSW, yxm_q4, Pq4, [23]uint8{0x07}},
|
||||
{APHSUBW, yxm_q4, Pq4, [23]uint8{0x05}},
|
||||
{APINSRW, yinsrw, Pq, [23]uint8{0xc4, 00}},
|
||||
{APINSRB, yinsr, Pq, [23]uint8{0x3a, 0x20, 00}},
|
||||
{APINSRD, yinsr, Pq, [23]uint8{0x3a, 0x22, 00}},
|
||||
|
|
@ -1201,14 +1340,30 @@ var optab =
|
|||
{APMINSW, yxm, Pe, [23]uint8{0xea}},
|
||||
{APMINUB, yxm, Pe, [23]uint8{0xda}},
|
||||
{APMOVMSKB, ymskb, Px, [23]uint8{Pe, 0xd7, 0xd7}},
|
||||
{APMOVSXBD, yxm_q4, Pq4, [23]uint8{0x21}},
|
||||
{APMOVSXBQ, yxm_q4, Pq4, [23]uint8{0x22}},
|
||||
{APMOVSXBW, yxm_q4, Pq4, [23]uint8{0x20}},
|
||||
{APMOVSXDQ, yxm_q4, Pq4, [23]uint8{0x25}},
|
||||
{APMOVSXWD, yxm_q4, Pq4, [23]uint8{0x23}},
|
||||
{APMOVSXWQ, yxm_q4, Pq4, [23]uint8{0x24}},
|
||||
{APMOVZXBD, yxm_q4, Pq4, [23]uint8{0x31}},
|
||||
{APMOVZXBQ, yxm_q4, Pq4, [23]uint8{0x32}},
|
||||
{APMOVZXBW, yxm_q4, Pq4, [23]uint8{0x30}},
|
||||
{APMOVZXDQ, yxm_q4, Pq4, [23]uint8{0x35}},
|
||||
{APMOVZXWD, yxm_q4, Pq4, [23]uint8{0x33}},
|
||||
{APMOVZXWQ, yxm_q4, Pq4, [23]uint8{0x34}},
|
||||
{APMULDQ, yxm_q4, Pq4, [23]uint8{0x28}},
|
||||
{APMULHRW, ymfp, Px, [23]uint8{0xb7}},
|
||||
{APMULHUW, ymm, Py1, [23]uint8{0xe4, Pe, 0xe4}},
|
||||
{APMULHW, ymm, Py1, [23]uint8{0xe5, Pe, 0xe5}},
|
||||
{APMULLD, yxm_q4, Pq4, [23]uint8{0x40}},
|
||||
{APMULLW, ymm, Py1, [23]uint8{0xd5, Pe, 0xd5}},
|
||||
{APMULULQ, ymm, Py1, [23]uint8{0xf4, Pe, 0xf4}},
|
||||
{APOPAL, ynone, P32, [23]uint8{0x61}},
|
||||
{APOPAW, ynone, Pe, [23]uint8{0x61}},
|
||||
{APOPCNT, yml_rl, Pfw, [23]uint8{0xb8}},
|
||||
{APOPCNTW, yml_rl, Pef3, [23]uint8{0xb8}},
|
||||
{APOPCNTL, yml_rl, Pf3, [23]uint8{0xb8}},
|
||||
{APOPCNTQ, yml_rl, Pfw, [23]uint8{0xb8}},
|
||||
{APOPFL, ynone, P32, [23]uint8{0x9d}},
|
||||
{APOPFQ, ynone, Py, [23]uint8{0x9d}},
|
||||
{APOPFW, ynone, Pe, [23]uint8{0x9d}},
|
||||
|
|
@ -1528,16 +1683,37 @@ var optab =
|
|||
{AROUNDSS, yaes2, Pq, [23]uint8{0x3a, 0x0a, 0}},
|
||||
{APSHUFD, yxshuf, Pq, [23]uint8{0x70, 0}},
|
||||
{APCLMULQDQ, yxshuf, Pq, [23]uint8{0x3a, 0x44, 0}},
|
||||
|
||||
{AANDNL, yvex_r3, Pvex, [23]uint8{VEX_LZ_0F38_W0, 0xF2}},
|
||||
{AANDNQ, yvex_r3, Pvex, [23]uint8{VEX_LZ_0F38_W1, 0xF2}},
|
||||
{ABEXTRL, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_0F38_W0, 0xF7}},
|
||||
{ABEXTRQ, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_0F38_W1, 0xF7}},
|
||||
{ABZHIL, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_0F38_W0, 0xF5}},
|
||||
{ABZHIQ, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_0F38_W1, 0xF5}},
|
||||
{AMULXL, yvex_r3, Pvex, [23]uint8{VEX_LZ_F2_0F38_W0, 0xF6}},
|
||||
{AMULXQ, yvex_r3, Pvex, [23]uint8{VEX_LZ_F2_0F38_W1, 0xF6}},
|
||||
{APDEPL, yvex_r3, Pvex, [23]uint8{VEX_LZ_F2_0F38_W0, 0xF5}},
|
||||
{APDEPQ, yvex_r3, Pvex, [23]uint8{VEX_LZ_F2_0F38_W1, 0xF5}},
|
||||
{APEXTL, yvex_r3, Pvex, [23]uint8{VEX_LZ_F3_0F38_W0, 0xF5}},
|
||||
{APEXTQ, yvex_r3, Pvex, [23]uint8{VEX_LZ_F3_0F38_W1, 0xF5}},
|
||||
{ASARXL, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_F3_0F38_W0, 0xF7}},
|
||||
{ASARXQ, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_F3_0F38_W1, 0xF7}},
|
||||
{ASHLXL, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_66_0F38_W0, 0xF7}},
|
||||
{ASHLXQ, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_66_0F38_W1, 0xF7}},
|
||||
{ASHRXL, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_F2_0F38_W0, 0xF7}},
|
||||
{ASHRXQ, yvex_vmr3, Pvex, [23]uint8{VEX_LZ_F2_0F38_W1, 0xF7}},
|
||||
|
||||
{AVZEROUPPER, ynone, Px, [23]uint8{0xc5, 0xf8, 0x77}},
|
||||
{AMOVHDU, yxmov_vex, Pvex2, [23]uint8{0x6f, 0x7f}},
|
||||
{AMOVNTHD, yxr_ml_vex, Pvex1, [23]uint8{0xe7}},
|
||||
{AMOVHDA, yxmov_vex, Pvex1, [23]uint8{0x6f, 0x7f}},
|
||||
{AVPCMPEQB, yxm_xm_xm, Pvex1, [23]uint8{0x74, 0x74}},
|
||||
{AVPXOR, yxm_xm_xm, Pvex1, [23]uint8{0xef, 0xef}},
|
||||
{AVPMOVMSKB, ymskb_vex, Pvex1, [23]uint8{0xd7}},
|
||||
{AVPAND, yxm_xm_xm, Pvex1, [23]uint8{0xdb, 0xdb}},
|
||||
{AVPBROADCASTB, yml_xr_vex, Pvex3, [23]uint8{0x78, 0x78}},
|
||||
{AVPTEST, yml_xr_vex, Pvex3, [23]uint8{0x17, 0x17}},
|
||||
{AVMOVDQU, yvex_vmovdqa, Pvex, [23]uint8{VEX_128_F3_0F_WIG, 0x6F, VEX_128_F3_0F_WIG, 0x7F, VEX_256_F3_0F_WIG, 0x6F, VEX_256_F3_0F_WIG, 0x7F}},
|
||||
{AVMOVDQA, yvex_vmovdqa, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0x6F, VEX_128_66_0F_WIG, 0x7F, VEX_256_66_0F_WIG, 0x6F, VEX_256_66_0F_WIG, 0x7F}},
|
||||
{AVMOVNTDQ, yvex_vmovntdq, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0xE7, VEX_256_66_0F_WIG, 0xE7}},
|
||||
{AVPCMPEQB, yvex_xy3, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0x74, VEX_256_66_0F_WIG, 0x74}},
|
||||
{AVPXOR, yvex_xy3, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0xEF, VEX_256_66_0F_WIG, 0xEF}},
|
||||
{AVPMOVMSKB, yvex_xyr2, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0xD7, VEX_256_66_0F_WIG, 0xD7}},
|
||||
{AVPAND, yvex_xy3, Pvex, [23]uint8{VEX_128_66_0F_WIG, 0xDB, VEX_256_66_0F_WIG, 0xDB}},
|
||||
{AVPBROADCASTB, yvex_vpbroadcast, Pvex, [23]uint8{VEX_128_66_0F38_W0, 0x78, VEX_256_66_0F38_W0, 0x78}},
|
||||
{AVPTEST, yvex_xy2, Pvex, [23]uint8{VEX_128_66_0F38_WIG, 0x17, VEX_256_66_0F38_WIG, 0x17}},
|
||||
|
||||
{AXACQUIRE, ynone, Px, [23]uint8{0xf2}},
|
||||
{AXRELEASE, ynone, Px, [23]uint8{0xf3}},
|
||||
{AXBEGIN, yxbegin, Px, [23]uint8{0xc7, 0xf8}},
|
||||
|
|
@ -1684,6 +1860,7 @@ func span6(ctxt *obj.Link, s *obj.LSym) {
|
|||
var loop int32
|
||||
var m int
|
||||
var p *obj.Prog
|
||||
errors := ctxt.Errors
|
||||
for {
|
||||
loop = 0
|
||||
for i = 0; i < len(s.R); i++ {
|
||||
|
|
@ -1795,6 +1972,9 @@ func span6(ctxt *obj.Link, s *obj.LSym) {
|
|||
if loop == 0 {
|
||||
break
|
||||
}
|
||||
if ctxt.Errors > errors {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if ctxt.Headtype == obj.Hnacl {
|
||||
|
|
@ -1927,6 +2107,9 @@ func instinit() {
|
|||
ycover[Ym*Ymax+Yxm] = 1
|
||||
ycover[Yxr*Ymax+Yxm] = 1
|
||||
|
||||
ycover[Ym*Ymax+Yym] = 1
|
||||
ycover[Yyr*Ymax+Yym] = 1
|
||||
|
||||
for i := 0; i < MAXREG; i++ {
|
||||
reg[i] = -1
|
||||
if i >= REG_AL && i <= REG_R15B {
|
||||
|
|
@ -1961,6 +2144,12 @@ func instinit() {
|
|||
regrex[i] = Rxr | Rxx | Rxb
|
||||
}
|
||||
}
|
||||
if i >= REG_Y0 && i <= REG_Y0+15 {
|
||||
reg[i] = (i - REG_Y0) & 7
|
||||
if i >= REG_Y0+8 {
|
||||
regrex[i] = Rxr | Rxx | Rxb
|
||||
}
|
||||
}
|
||||
|
||||
if i >= REG_CR+8 && i <= REG_CR+15 {
|
||||
regrex[i] = Rxr
|
||||
|
|
@ -2112,6 +2301,31 @@ func oclass(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) int {
|
|||
return Yxxx
|
||||
|
||||
case obj.TYPE_MEM:
|
||||
if a.Index == REG_SP {
|
||||
// Can't use SP as the index register
|
||||
return Yxxx
|
||||
}
|
||||
if ctxt.Asmode == 64 {
|
||||
switch a.Name {
|
||||
case obj.NAME_EXTERN, obj.NAME_STATIC, obj.NAME_GOTREF:
|
||||
// Global variables can't use index registers and their
|
||||
// base register is %rip (%rip is encoded as REG_NONE).
|
||||
if a.Reg != REG_NONE || a.Index != REG_NONE || a.Scale != 0 {
|
||||
return Yxxx
|
||||
}
|
||||
case obj.NAME_AUTO, obj.NAME_PARAM:
|
||||
// These names must have a base of SP. The old compiler
|
||||
// uses 0 for the base register. SSA uses REG_SP.
|
||||
if a.Reg != REG_SP && a.Reg != 0 {
|
||||
return Yxxx
|
||||
}
|
||||
case obj.NAME_NONE:
|
||||
// everything is ok
|
||||
default:
|
||||
// unknown name
|
||||
return Yxxx
|
||||
}
|
||||
}
|
||||
return Ym
|
||||
|
||||
case obj.TYPE_ADDR:
|
||||
|
|
@ -2297,6 +2511,24 @@ func oclass(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) int {
|
|||
REG_X0 + 15:
|
||||
return Yxr
|
||||
|
||||
case REG_Y0 + 0,
|
||||
REG_Y0 + 1,
|
||||
REG_Y0 + 2,
|
||||
REG_Y0 + 3,
|
||||
REG_Y0 + 4,
|
||||
REG_Y0 + 5,
|
||||
REG_Y0 + 6,
|
||||
REG_Y0 + 7,
|
||||
REG_Y0 + 8,
|
||||
REG_Y0 + 9,
|
||||
REG_Y0 + 10,
|
||||
REG_Y0 + 11,
|
||||
REG_Y0 + 12,
|
||||
REG_Y0 + 13,
|
||||
REG_Y0 + 14,
|
||||
REG_Y0 + 15:
|
||||
return Yyr
|
||||
|
||||
case REG_CS:
|
||||
return Ycs
|
||||
case REG_SS:
|
||||
|
|
@ -2597,7 +2829,7 @@ func asmandsz(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, r int, rex int, m64 int)
|
|||
goto bad
|
||||
|
||||
case obj.TYPE_REG:
|
||||
if a.Reg < REG_AL || REG_X0+15 < a.Reg {
|
||||
if a.Reg < REG_AL || REG_Y0+15 < a.Reg {
|
||||
goto bad
|
||||
}
|
||||
if v != 0 {
|
||||
|
|
@ -3025,77 +3257,40 @@ var bpduff2 = []byte{
|
|||
0x48, 0x8b, 0x6d, 0x00, // MOVQ 0(BP), BP
|
||||
}
|
||||
|
||||
// Assemble vex prefix, from 3 operands and prefix.
|
||||
// Emit VEX prefix and opcode byte.
|
||||
// The three addresses are the r/m, vvvv, and reg fields.
|
||||
// The reg and rm arguments appear in the same order as the
|
||||
// arguments to asmand, which typically follows the call to asmvex.
|
||||
// The final two arguments are the VEX prefix (see encoding above)
|
||||
// and the opcode byte.
|
||||
// For details about vex prefix see:
|
||||
// https://en.wikipedia.org/wiki/VEX_prefix#Technical_description
|
||||
func vexprefix(ctxt *obj.Link, to *obj.Addr, from *obj.Addr, from3 *obj.Addr, pref uint8) {
|
||||
rexR := regrex[to.Reg]
|
||||
rexB := regrex[from.Reg]
|
||||
rexX := regrex[from.Index]
|
||||
var prefBit uint8
|
||||
// This will go into VEX.PP field.
|
||||
if pref == Pvex1 || pref == Pvex3 {
|
||||
prefBit = 1
|
||||
} else if pref == Pvex2 {
|
||||
prefBit = 2
|
||||
} // TODO add Pvex0
|
||||
|
||||
if rexX == 0 && rexB == 0 && pref != Pvex3 { // 2-byte vex prefix
|
||||
// In 2-byte case, first byte is always C5
|
||||
ctxt.Andptr[0] = 0xc5
|
||||
ctxt.Andptr = ctxt.Andptr[1:]
|
||||
|
||||
if from3 == nil {
|
||||
// If this is a 2-operand instruction fill VEX.VVVV with 1111
|
||||
// We are also interested only in 256-bit version, so VEX.L=1
|
||||
ctxt.Andptr[0] = 0x7c
|
||||
} else {
|
||||
// VEX.L=1
|
||||
ctxt.Andptr[0] = 0x4
|
||||
// VEX.VVVV (bits 3:6) is a inversed register number
|
||||
ctxt.Andptr[0] |= byte((^(from3.Reg - REG_X0))<<3) & 0x78
|
||||
}
|
||||
|
||||
// VEX encodes REX.R as inversed upper bit
|
||||
if rexR == 0 {
|
||||
ctxt.Andptr[0] |= 0x80
|
||||
}
|
||||
ctxt.Andptr[0] |= prefBit
|
||||
ctxt.Andptr = ctxt.Andptr[1:]
|
||||
} else { // 3-byte case
|
||||
// First byte is always C$
|
||||
ctxt.Andptr[0] = 0xc4
|
||||
ctxt.Andptr = ctxt.Andptr[1:]
|
||||
|
||||
// Encode VEX.mmmmm with prefix value, assume 0F,
|
||||
// which encodes as 1, unless 0F38 was specified with pvex3.
|
||||
ctxt.Andptr[0] = 0x1 // TODO handle 0F3A
|
||||
if pref == Pvex3 {
|
||||
ctxt.Andptr[0] = 0x2
|
||||
}
|
||||
|
||||
// REX.[RXB] are inverted and encoded in 3 upper bits
|
||||
if rexR == 0 {
|
||||
ctxt.Andptr[0] |= 0x80
|
||||
}
|
||||
if rexX == 0 {
|
||||
ctxt.Andptr[0] |= 0x40
|
||||
}
|
||||
if rexB == 0 {
|
||||
ctxt.Andptr[0] |= 0x20
|
||||
}
|
||||
ctxt.Andptr = ctxt.Andptr[1:]
|
||||
|
||||
// Fill VEX.VVVV, same as 2-operand VEX instruction.
|
||||
if from3 == nil {
|
||||
ctxt.Andptr[0] = 0x7c
|
||||
} else {
|
||||
ctxt.Andptr[0] = 0x4
|
||||
ctxt.Andptr[0] |= byte((^(from3.Reg - REG_X0))<<3) & 0x78
|
||||
}
|
||||
ctxt.Andptr[0] |= prefBit
|
||||
ctxt.Andptr = ctxt.Andptr[1:]
|
||||
func asmvex(ctxt *obj.Link, rm, v, r *obj.Addr, vex, opcode uint8) {
|
||||
ctxt.Vexflag = 1
|
||||
rexR := regrex[r.Reg] & Rxr
|
||||
rexB := regrex[rm.Reg] & Rxb
|
||||
rexX := regrex[rm.Index] & Rxx
|
||||
vexM := (vex >> 3) & 0xF
|
||||
vexWLP := vex & 0x87
|
||||
vexV := byte(0)
|
||||
if v != nil {
|
||||
vexV = byte(reg[v.Reg]|(regrex[v.Reg]&Rxr)<<1) & 0xF
|
||||
}
|
||||
vexV ^= 0xF
|
||||
if vexM == 1 && (rexX|rexB) == 0 && vex&vexW1 == 0 {
|
||||
// Can use 2-byte encoding.
|
||||
ctxt.Andptr[0] = 0xc5
|
||||
ctxt.Andptr[1] = byte(rexR<<5) ^ 0x80 | vexV<<3 | vexWLP
|
||||
ctxt.Andptr = ctxt.Andptr[2:]
|
||||
} else {
|
||||
// Must use 3-byte encoding.
|
||||
ctxt.Andptr[0] = 0xc4
|
||||
ctxt.Andptr[1] = (byte(rexR|rexX|rexB) << 5) ^ 0xE0 | vexM
|
||||
ctxt.Andptr[2] = vexV<<3 | vexWLP
|
||||
ctxt.Andptr = ctxt.Andptr[3:]
|
||||
}
|
||||
ctxt.Andptr[0] = opcode
|
||||
ctxt.Andptr = ctxt.Andptr[1:]
|
||||
}
|
||||
|
||||
func doasm(ctxt *obj.Link, p *obj.Prog) {
|
||||
|
|
@ -3192,15 +3387,19 @@ func doasm(ctxt *obj.Link, p *obj.Prog) {
|
|||
ctxt.Andptr[0] = Pm
|
||||
ctxt.Andptr = ctxt.Andptr[1:]
|
||||
|
||||
case Pq3: /* 16 bit escape, Rex.w, and opcode escape */
|
||||
case Pq3: /* 16 bit escape and opcode escape + REX.W */
|
||||
ctxt.Rexflag |= Pw
|
||||
ctxt.Andptr[0] = Pe
|
||||
ctxt.Andptr = ctxt.Andptr[1:]
|
||||
|
||||
ctxt.Andptr[0] = Pw
|
||||
ctxt.Andptr = ctxt.Andptr[1:]
|
||||
ctxt.Andptr[0] = Pm
|
||||
ctxt.Andptr = ctxt.Andptr[1:]
|
||||
|
||||
case Pq4: /* 66 0F 38 */
|
||||
ctxt.Andptr[0] = 0x66
|
||||
ctxt.Andptr[1] = 0x0F
|
||||
ctxt.Andptr[2] = 0x38
|
||||
ctxt.Andptr = ctxt.Andptr[3:]
|
||||
|
||||
case Pf2, /* xmm opcode escape */
|
||||
Pf3:
|
||||
ctxt.Andptr[0] = byte(o.prefix)
|
||||
|
|
@ -3209,11 +3408,17 @@ func doasm(ctxt *obj.Link, p *obj.Prog) {
|
|||
ctxt.Andptr[0] = Pm
|
||||
ctxt.Andptr = ctxt.Andptr[1:]
|
||||
|
||||
case Pfw: /* first escape, Rex.w, and second escape */
|
||||
case Pef3:
|
||||
ctxt.Andptr[0] = Pe
|
||||
ctxt.Andptr = ctxt.Andptr[1:]
|
||||
ctxt.Andptr[0] = Pf3
|
||||
ctxt.Andptr = ctxt.Andptr[1:]
|
||||
ctxt.Andptr[0] = Pm
|
||||
ctxt.Andptr = ctxt.Andptr[1:]
|
||||
|
||||
ctxt.Andptr[0] = Pw
|
||||
case Pfw: /* xmm opcode escape + REX.W */
|
||||
ctxt.Rexflag |= Pw
|
||||
ctxt.Andptr[0] = Pf3
|
||||
ctxt.Andptr = ctxt.Andptr[1:]
|
||||
ctxt.Andptr[0] = Pm
|
||||
ctxt.Andptr = ctxt.Andptr[1:]
|
||||
|
|
@ -3340,13 +3545,6 @@ func doasm(ctxt *obj.Link, p *obj.Prog) {
|
|||
mediaop(ctxt, o, op, int(yt.zoffset), z)
|
||||
asmand(ctxt, p, &p.From, &p.To)
|
||||
|
||||
case Zm_r_xm_vex:
|
||||
ctxt.Vexflag = 1
|
||||
vexprefix(ctxt, &p.To, &p.From, nil, o.prefix)
|
||||
ctxt.Andptr[0] = byte(op)
|
||||
ctxt.Andptr = ctxt.Andptr[1:]
|
||||
asmand(ctxt, p, &p.From, &p.To)
|
||||
|
||||
case Zm_r_xm_nr:
|
||||
ctxt.Rexflag = 0
|
||||
mediaop(ctxt, o, op, int(yt.zoffset), z)
|
||||
|
|
@ -3406,20 +3604,18 @@ func doasm(ctxt *obj.Link, p *obj.Prog) {
|
|||
ctxt.Andptr = ctxt.Andptr[1:]
|
||||
asmand(ctxt, p, &p.To, &p.From)
|
||||
|
||||
case Zr_m_xm_vex:
|
||||
ctxt.Vexflag = 1
|
||||
vexprefix(ctxt, &p.From, &p.To, nil, o.prefix)
|
||||
ctxt.Andptr[0] = byte(op)
|
||||
ctxt.Andptr = ctxt.Andptr[1:]
|
||||
asmand(ctxt, p, &p.To, &p.From)
|
||||
|
||||
case Zr_r_r_vex:
|
||||
ctxt.Vexflag = 1
|
||||
vexprefix(ctxt, &p.To, &p.From, p.From3, o.prefix)
|
||||
ctxt.Andptr[0] = byte(op)
|
||||
ctxt.Andptr = ctxt.Andptr[1:]
|
||||
case Zvex_rm_v_r:
|
||||
asmvex(ctxt, &p.From, p.From3, &p.To, o.op[z], o.op[z+1])
|
||||
asmand(ctxt, p, &p.From, &p.To)
|
||||
|
||||
case Zvex_v_rm_r:
|
||||
asmvex(ctxt, p.From3, &p.From, &p.To, o.op[z], o.op[z+1])
|
||||
asmand(ctxt, p, p.From3, &p.To)
|
||||
|
||||
case Zvex_r_v_rm:
|
||||
asmvex(ctxt, &p.To, p.From3, &p.From, o.op[z], o.op[z+1])
|
||||
asmand(ctxt, p, &p.To, &p.From)
|
||||
|
||||
case Zr_m_xm:
|
||||
mediaop(ctxt, o, op, int(yt.zoffset), z)
|
||||
asmand(ctxt, p, &p.To, &p.From)
|
||||
|
|
@ -4277,7 +4473,8 @@ bad:
|
|||
}
|
||||
}
|
||||
|
||||
ctxt.Diag("doasm: notfound ft=%d tt=%d %v %d %d", p.Ft, p.Tt, p, oclass(ctxt, p, &p.From), oclass(ctxt, p, &p.To))
|
||||
ctxt.Diag("invalid instruction: %v", p)
|
||||
// ctxt.Diag("doasm: notfound ft=%d tt=%d %v %d %d", p.Ft, p.Tt, p, oclass(ctxt, p, &p.From), oclass(ctxt, p, &p.To))
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -104,6 +104,22 @@ var Register = []string{
|
|||
"X13",
|
||||
"X14",
|
||||
"X15",
|
||||
"Y0",
|
||||
"Y1",
|
||||
"Y2",
|
||||
"Y3",
|
||||
"Y4",
|
||||
"Y5",
|
||||
"Y6",
|
||||
"Y7",
|
||||
"Y8",
|
||||
"Y9",
|
||||
"Y10",
|
||||
"Y11",
|
||||
"Y12",
|
||||
"Y13",
|
||||
"Y14",
|
||||
"Y15",
|
||||
"CS", /* [D_CS] */
|
||||
"SS",
|
||||
"DS",
|
||||
|
|
|
|||
|
|
@ -150,6 +150,13 @@ func parseOutput(t *testing.T, td *ParsedTestData, asmout []byte) {
|
|||
func TestDynlink(t *testing.T) {
|
||||
testenv.MustHaveGoBuild(t)
|
||||
|
||||
if os.Getenv("GOHOSTARCH") != "" {
|
||||
// TODO: make this work? It was failing due to the
|
||||
// GOARCH= filtering above and skipping is easiest for
|
||||
// now.
|
||||
t.Skip("skipping when GOHOSTARCH is set")
|
||||
}
|
||||
|
||||
testdata := parseTestData(t)
|
||||
asmout := asmOutput(t, testdata.input)
|
||||
parseOutput(t, testdata, asmout)
|
||||
|
|
|
|||
|
|
@ -52,6 +52,9 @@ Flags:
|
|||
The dynamic header is on by default, even without any
|
||||
references to dynamic libraries, because many common
|
||||
system tools now assume the presence of the header.
|
||||
-extar ar
|
||||
Set the external archive program (default "ar").
|
||||
Used only for -buildmode=c-archive.
|
||||
-extld linker
|
||||
Set the external linker (default "clang" or "gcc").
|
||||
-extldflags flags
|
||||
|
|
|
|||
|
|
@ -689,14 +689,14 @@ func asmb() {
|
|||
switch ld.HEADTYPE {
|
||||
default:
|
||||
case obj.Hplan9: /* plan 9 */
|
||||
ld.Thearch.Lput(0x647) /* magic */
|
||||
ld.Thearch.Lput(uint32(ld.Segtext.Filelen)) /* sizes */
|
||||
ld.Thearch.Lput(uint32(ld.Segdata.Filelen))
|
||||
ld.Thearch.Lput(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
|
||||
ld.Thearch.Lput(uint32(ld.Symsize)) /* nsyms */
|
||||
ld.Thearch.Lput(uint32(ld.Entryvalue())) /* va of entry */
|
||||
ld.Thearch.Lput(0)
|
||||
ld.Thearch.Lput(uint32(ld.Lcsize))
|
||||
ld.Lputb(0x647) /* magic */
|
||||
ld.Lputb(uint32(ld.Segtext.Filelen)) /* sizes */
|
||||
ld.Lputb(uint32(ld.Segdata.Filelen))
|
||||
ld.Lputb(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
|
||||
ld.Lputb(uint32(ld.Symsize)) /* nsyms */
|
||||
ld.Lputb(uint32(ld.Entryvalue())) /* va of entry */
|
||||
ld.Lputb(0)
|
||||
ld.Lputb(uint32(ld.Lcsize))
|
||||
|
||||
case obj.Hlinux,
|
||||
obj.Hfreebsd,
|
||||
|
|
|
|||
|
|
@ -850,7 +850,26 @@ func Elfinit() {
|
|||
}
|
||||
}
|
||||
|
||||
// Make sure PT_LOAD is aligned properly and
|
||||
// that there is no gap,
|
||||
// correct ELF loaders will do this implicitly,
|
||||
// but buggy ELF loaders like the one in some
|
||||
// versions of QEMU and UPX won't.
|
||||
func fixElfPhdr(e *ElfPhdr) {
|
||||
frag := int(e.vaddr & (e.align - 1))
|
||||
|
||||
e.off -= uint64(frag)
|
||||
e.vaddr -= uint64(frag)
|
||||
e.paddr -= uint64(frag)
|
||||
e.filesz += uint64(frag)
|
||||
e.memsz += uint64(frag)
|
||||
}
|
||||
|
||||
func elf64phdr(e *ElfPhdr) {
|
||||
if e.type_ == PT_LOAD {
|
||||
fixElfPhdr(e)
|
||||
}
|
||||
|
||||
Thearch.Lput(e.type_)
|
||||
Thearch.Lput(e.flags)
|
||||
Thearch.Vput(e.off)
|
||||
|
|
@ -863,16 +882,7 @@ func elf64phdr(e *ElfPhdr) {
|
|||
|
||||
func elf32phdr(e *ElfPhdr) {
|
||||
if e.type_ == PT_LOAD {
|
||||
// Correct ELF loaders will do this implicitly,
|
||||
// but buggy ELF loaders like the one in some
|
||||
// versions of QEMU won't.
|
||||
frag := int(e.vaddr & (e.align - 1))
|
||||
|
||||
e.off -= uint64(frag)
|
||||
e.vaddr -= uint64(frag)
|
||||
e.paddr -= uint64(frag)
|
||||
e.filesz += uint64(frag)
|
||||
e.memsz += uint64(frag)
|
||||
fixElfPhdr(e)
|
||||
}
|
||||
|
||||
Thearch.Lput(e.type_)
|
||||
|
|
|
|||
|
|
@ -207,6 +207,7 @@ var (
|
|||
tmpdir string
|
||||
extld string
|
||||
extldflags string
|
||||
extar string
|
||||
libgccfile string
|
||||
debug_s int // backup old value of debug['s']
|
||||
Ctxt *Link
|
||||
|
|
@ -504,17 +505,24 @@ func loadlib() {
|
|||
|
||||
var i int
|
||||
for i = 0; i < len(Ctxt.Library); i++ {
|
||||
if Debug['v'] > 1 {
|
||||
fmt.Fprintf(&Bso, "%5.2f autolib: %s (from %s)\n", obj.Cputime(), Ctxt.Library[i].File, Ctxt.Library[i].Objref)
|
||||
}
|
||||
iscgo = iscgo || Ctxt.Library[i].Pkg == "runtime/cgo"
|
||||
if Ctxt.Library[i].Shlib != "" {
|
||||
ldshlibsyms(Ctxt.Library[i].Shlib)
|
||||
} else {
|
||||
if Ctxt.Library[i].Shlib == "" {
|
||||
if Debug['v'] > 1 {
|
||||
fmt.Fprintf(&Bso, "%5.2f autolib: %s (from %s)\n", obj.Cputime(), Ctxt.Library[i].File, Ctxt.Library[i].Objref)
|
||||
}
|
||||
objfile(Ctxt.Library[i])
|
||||
}
|
||||
}
|
||||
|
||||
for i = 0; i < len(Ctxt.Library); i++ {
|
||||
if Ctxt.Library[i].Shlib != "" {
|
||||
if Debug['v'] > 1 {
|
||||
fmt.Fprintf(&Bso, "%5.2f autolib: %s (from %s)\n", obj.Cputime(), Ctxt.Library[i].Shlib, Ctxt.Library[i].Objref)
|
||||
}
|
||||
ldshlibsyms(Ctxt.Library[i].Shlib)
|
||||
}
|
||||
}
|
||||
|
||||
if Linkmode == LinkAuto {
|
||||
if iscgo && externalobj {
|
||||
Linkmode = LinkExternal
|
||||
|
|
@ -1008,8 +1016,12 @@ func archive() {
|
|||
return
|
||||
}
|
||||
|
||||
if extar == "" {
|
||||
extar = "ar"
|
||||
}
|
||||
|
||||
mayberemoveoutfile()
|
||||
argv := []string{"ar", "-q", "-c", "-s", outfile}
|
||||
argv := []string{extar, "-q", "-c", "-s", outfile}
|
||||
argv = append(argv, fmt.Sprintf("%s/go.o", tmpdir))
|
||||
argv = append(argv, hostobjCopy()...)
|
||||
|
||||
|
|
@ -1458,18 +1470,11 @@ func ldshlibsyms(shlib string) {
|
|||
continue
|
||||
}
|
||||
lsym := Linklookup(Ctxt, elfsym.Name, 0)
|
||||
if lsym.Type != 0 && lsym.Type != obj.SDYNIMPORT && lsym.Dupok == 0 {
|
||||
if (lsym.Type != obj.SBSS && lsym.Type != obj.SNOPTRBSS) || len(lsym.R) != 0 || len(lsym.P) != 0 || f.Sections[elfsym.Section].Type != elf.SHT_NOBITS {
|
||||
Diag("Found duplicate symbol %s reading from %s, first found in %s", elfsym.Name, shlib, lsym.File)
|
||||
}
|
||||
if lsym.Size > int64(elfsym.Size) {
|
||||
// If the existing symbol is a BSS value that is
|
||||
// larger than the one read from the shared library,
|
||||
// keep references to that. Conversely, if the
|
||||
// version from the shared libray is larger, we want
|
||||
// to make all references be to that.
|
||||
continue
|
||||
}
|
||||
// Because loadlib above loads all .a files before loading any shared
|
||||
// libraries, any symbols we find that duplicate symbols already
|
||||
// loaded should be ignored (the symbols from the .a files "win").
|
||||
if lsym.Type != 0 {
|
||||
continue
|
||||
}
|
||||
lsym.Type = obj.SDYNIMPORT
|
||||
lsym.ElfType = elf.ST_TYPE(elfsym.Info)
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ func Ldmain() {
|
|||
flag.Var(&Buildmode, "buildmode", "set build `mode`")
|
||||
obj.Flagcount("c", "dump call graph", &Debug['c'])
|
||||
obj.Flagcount("d", "disable dynamic executable", &Debug['d'])
|
||||
obj.Flagstr("extar", "archive program for buildmode=c-archive", &extar)
|
||||
obj.Flagstr("extld", "use `linker` when linking in external mode", &extld)
|
||||
obj.Flagstr("extldflags", "pass `flags` to external linker", &extldflags)
|
||||
obj.Flagcount("f", "ignore version mismatch", &Debug['f'])
|
||||
|
|
|
|||
|
|
@ -72,6 +72,9 @@ func cgoBaseType(f *File, arg ast.Expr) types.Type {
|
|||
}
|
||||
// Here arg is *f(v).
|
||||
t := f.pkg.types[call.Fun].Type
|
||||
if t == nil {
|
||||
break
|
||||
}
|
||||
ptr, ok := t.Underlying().(*types.Pointer)
|
||||
if !ok {
|
||||
break
|
||||
|
|
|
|||
|
|
@ -445,12 +445,12 @@ func (f *File) okPrintfArg(call *ast.CallExpr, state *formatState) (ok bool) {
|
|||
return false
|
||||
}
|
||||
arg := call.Args[argNum]
|
||||
if f.isFunctionValue(arg) && state.verb != 'p' && state.verb != 'T' {
|
||||
f.Badf(call.Pos(), "arg %s in printf call is a function value, not a function call", f.gofmt(arg))
|
||||
return false
|
||||
}
|
||||
if !f.matchArgType(v.typ, nil, arg) {
|
||||
typeString := ""
|
||||
if f.isFunctionValue(arg) {
|
||||
f.Badf(call.Pos(), "arg %s in printf call is a function value, not a function call", f.gofmt(arg))
|
||||
return false
|
||||
}
|
||||
if typ := f.pkg.types[arg].Type; typ != nil {
|
||||
typeString = typ.String()
|
||||
}
|
||||
|
|
|
|||
9
src/cmd/vet/testdata/cgo2.go
vendored
Normal file
9
src/cmd/vet/testdata/cgo2.go
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
// Copyright 2016 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.
|
||||
|
||||
// Test the cgo checker on a file that doesn't use cgo.
|
||||
|
||||
package testdata
|
||||
|
||||
var _ = C.f(*p(**p))
|
||||
3
src/cmd/vet/testdata/print.go
vendored
3
src/cmd/vet/testdata/print.go
vendored
|
|
@ -197,7 +197,10 @@ func PrintfTests() {
|
|||
et5.error() // ok, not an error method.
|
||||
// Can't print a function.
|
||||
Printf("%d", someFunction) // ERROR "arg someFunction in printf call is a function value, not a function call"
|
||||
Printf("%v", someFunction) // ERROR "arg someFunction in printf call is a function value, not a function call"
|
||||
Println(someFunction) // ERROR "arg someFunction in Println call is a function value, not a function call"
|
||||
Printf("%p", someFunction) // ok: maybe someone wants to see the pointer
|
||||
Printf("%T", someFunction) // ok: maybe someone wants to see the type
|
||||
// Bug: used to recur forever.
|
||||
Printf("%p %x", recursiveStructV, recursiveStructV.next)
|
||||
Printf("%p %x", recursiveStruct1V, recursiveStruct1V.next)
|
||||
|
|
|
|||
|
|
@ -14,6 +14,58 @@ import (
|
|||
"os"
|
||||
)
|
||||
|
||||
func ExampleNewGCMEncrypter() {
|
||||
// The key argument should be the AES key, either 16 or 32 bytes
|
||||
// to select AES-128 or AES-256.
|
||||
key := []byte("AES256Key-32Characters1234567890")
|
||||
plaintext := []byte("exampleplaintext")
|
||||
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
// Never use more than 2^32 random nonces with a given key because of the risk of a repeat.
|
||||
nonce := make([]byte, 12)
|
||||
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
aesgcm, err := cipher.NewGCM(block)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
ciphertext := aesgcm.Seal(nil, nonce, plaintext, nil)
|
||||
fmt.Printf("%x\n", ciphertext)
|
||||
}
|
||||
|
||||
func ExampleNewGCMDecrypter() {
|
||||
// The key argument should be the AES key, either 16 or 32 bytes
|
||||
// to select AES-128 or AES-256.
|
||||
key := []byte("AES256Key-32Characters1234567890")
|
||||
ciphertext, _ := hex.DecodeString("f90fbef747e7212ad7410d0eee2d965de7e890471695cddd2a5bc0ef5da1d04ad8147b62141ad6e4914aee8c512f64fba9037603d41de0d50b718bd665f019cdcd")
|
||||
|
||||
nonce, _ := hex.DecodeString("bb8ef84243d2ee95a41c6c57")
|
||||
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
aesgcm, err := cipher.NewGCM(block)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
plaintext, err := aesgcm.Open(nil, nonce, ciphertext, nil)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
fmt.Printf("%s\n", string(plaintext))
|
||||
}
|
||||
|
||||
func ExampleNewCBCDecrypter() {
|
||||
key := []byte("example key 1234")
|
||||
ciphertext, _ := hex.DecodeString("f363f3ccdcb12bb883abf484ba77d9cd7d32b5baecb3d4b1b3e0e4beffdb3ded")
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ type Signer interface {
|
|||
// private key.
|
||||
Public() PublicKey
|
||||
|
||||
// Sign signs msg with the private key, possibly using entropy from
|
||||
// Sign signs digest with the private key, possibly using entropy from
|
||||
// rand. For an RSA key, the resulting signature should be either a
|
||||
// PKCS#1 v1.5 or PSS signature (as indicated by opts). For an (EC)DSA
|
||||
// key, it should be a DER-serialised, ASN.1 signature structure.
|
||||
|
|
@ -118,7 +118,11 @@ type Signer interface {
|
|||
// simply pass in the hash function used as opts. Sign may also attempt
|
||||
// to type assert opts to other types in order to obtain algorithm
|
||||
// specific values. See the documentation in each package for details.
|
||||
Sign(rand io.Reader, msg []byte, opts SignerOpts) (signature []byte, err error)
|
||||
//
|
||||
// Note that when a signature of a hash of a larger message is needed,
|
||||
// the caller is responsible for hashing the larger message and passing
|
||||
// the hash (as digest) and the hash function (as opts) to Sign.
|
||||
Sign(rand io.Reader, digest []byte, opts SignerOpts) (signature []byte, err error)
|
||||
}
|
||||
|
||||
// SignerOpts contains options for signing with a Signer.
|
||||
|
|
|
|||
169
src/crypto/rsa/example_test.go
Normal file
169
src/crypto/rsa/example_test.go
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
// Copyright 2016 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.
|
||||
|
||||
package rsa
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
// RSA is able to encrypt only a very limited amount of data. In order
|
||||
// to encrypt reasonable amounts of data a hybrid scheme is commonly
|
||||
// used: RSA is used to encrypt a key for a symmetric primitive like
|
||||
// AES-GCM.
|
||||
//
|
||||
// Before encrypting, data is “padded” by embedding it in a known
|
||||
// structure. This is done for a number of reasons, but the most
|
||||
// obvious is to ensure that the value is large enough that the
|
||||
// exponentiation is larger than the modulus. (Otherwise it could be
|
||||
// decrypted with a square-root.)
|
||||
//
|
||||
// In these designs, when using PKCS#1 v1.5, it's vitally important to
|
||||
// avoid disclosing whether the received RSA message was well-formed
|
||||
// (that is, whether the result of decrypting is a correctly padded
|
||||
// message) because this leaks secret information.
|
||||
// DecryptPKCS1v15SessionKey is designed for this situation and copies
|
||||
// the decrypted, symmetric key (if well-formed) in constant-time over
|
||||
// a buffer that contains a random key. Thus, if the RSA result isn't
|
||||
// well-formed, the implementation uses a random key in constant time.
|
||||
func ExampleDecryptPKCS1v15SessionKey() {
|
||||
// crypto/rand.Reader is a good source of entropy for blinding the RSA
|
||||
// operation.
|
||||
rng := rand.Reader
|
||||
|
||||
// The hybrid scheme should use at least a 16-byte symmetric key. Here
|
||||
// we read the random key that will be used if the RSA decryption isn't
|
||||
// well-formed.
|
||||
key := make([]byte, 32)
|
||||
if _, err := io.ReadFull(rng, key); err != nil {
|
||||
panic("RNG failure")
|
||||
}
|
||||
|
||||
rsaCiphertext, _ := hex.DecodeString("aabbccddeeff")
|
||||
|
||||
if err := DecryptPKCS1v15SessionKey(rng, rsaPrivateKey, rsaCiphertext, key); err != nil {
|
||||
// Any errors that result will be “public” – meaning that they
|
||||
// can be determined without any secret information. (For
|
||||
// instance, if the length of key is impossible given the RSA
|
||||
// public key.)
|
||||
fmt.Fprintf(os.Stderr, "Error from RSA decryption: %s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Given the resulting key, a symmetric scheme can be used to decrypt a
|
||||
// larger ciphertext.
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
panic("aes.NewCipher failed: " + err.Error())
|
||||
}
|
||||
|
||||
// Since the key is random, using a fixed nonce is acceptable as the
|
||||
// (key, nonce) pair will still be unique, as required.
|
||||
var zeroNonce [12]byte
|
||||
aead, err := cipher.NewGCM(block)
|
||||
if err != nil {
|
||||
panic("cipher.NewGCM failed: " + err.Error())
|
||||
}
|
||||
ciphertext, _ := hex.DecodeString("00112233445566")
|
||||
plaintext, err := aead.Open(nil, zeroNonce[:], ciphertext, nil)
|
||||
if err != nil {
|
||||
// The RSA ciphertext was badly formed; the decryption will
|
||||
// fail here because the AES-GCM key will be incorrect.
|
||||
fmt.Fprintf(os.Stderr, "Error decrypting: %s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("Plaintext: %s\n", string(plaintext))
|
||||
}
|
||||
|
||||
func ExampleSignPKCS1v15() {
|
||||
// crypto/rand.Reader is a good source of entropy for blinding the RSA
|
||||
// operation.
|
||||
rng := rand.Reader
|
||||
|
||||
message := []byte("message to be signed")
|
||||
|
||||
// Only small messages can be signed directly; thus the hash of a
|
||||
// message, rather than the message itself, is signed. This requires
|
||||
// that the hash function be collision resistant. SHA-256 is the
|
||||
// least-strong hash function that should be used for this at the time
|
||||
// of writing (2016).
|
||||
hashed := sha256.Sum256(message)
|
||||
|
||||
signature, err := SignPKCS1v15(rng, rsaPrivateKey, crypto.SHA256, hashed[:])
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error from signing: %s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("Signature: %x\n", signature)
|
||||
}
|
||||
|
||||
func ExampleVerifyPKCS1v15() {
|
||||
message := []byte("message to be signed")
|
||||
signature, _ := hex.DecodeString("ad2766728615cc7a746cc553916380ca7bfa4f8983b990913bc69eb0556539a350ff0f8fe65ddfd3ebe91fe1c299c2fac135bc8c61e26be44ee259f2f80c1530")
|
||||
|
||||
// Only small messages can be signed directly; thus the hash of a
|
||||
// message, rather than the message itself, is signed. This requires
|
||||
// that the hash function be collision resistant. SHA-256 is the
|
||||
// least-strong hash function that should be used for this at the time
|
||||
// of writing (2016).
|
||||
hashed := sha256.Sum256(message)
|
||||
|
||||
err := VerifyPKCS1v15(&rsaPrivateKey.PublicKey, crypto.SHA256, hashed[:], signature)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error from verification: %s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
// signature is a valid signature of message from the public key.
|
||||
}
|
||||
|
||||
func ExampleEncryptOAEP() {
|
||||
secretMessage := []byte("send reinforcements, we're going to advance")
|
||||
label := []byte("orders")
|
||||
|
||||
// crypto/rand.Reader is a good source of entropy for randomizing the
|
||||
// encryption function.
|
||||
rng := rand.Reader
|
||||
|
||||
ciphertext, err := EncryptOAEP(sha256.New(), rng, &test2048Key.PublicKey, secretMessage, label)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error from encryption: %s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Since encryption is a randomized function, ciphertext will be
|
||||
// different each time.
|
||||
fmt.Printf("Ciphertext: %x\n", ciphertext)
|
||||
}
|
||||
|
||||
func ExampleDecryptOAEP() {
|
||||
ciphertext, _ := hex.DecodeString("4d1ee10e8f286390258c51a5e80802844c3e6358ad6690b7285218a7c7ed7fc3a4c7b950fbd04d4b0239cc060dcc7065ca6f84c1756deb71ca5685cadbb82be025e16449b905c568a19c088a1abfad54bf7ecc67a7df39943ec511091a34c0f2348d04e058fcff4d55644de3cd1d580791d4524b92f3e91695582e6e340a1c50b6c6d78e80b4e42c5b4d45e479b492de42bbd39cc642ebb80226bb5200020d501b24a37bcc2ec7f34e596b4fd6b063de4858dbf5a4e3dd18e262eda0ec2d19dbd8e890d672b63d368768360b20c0b6b8592a438fa275e5fa7f60bef0dd39673fd3989cc54d2cb80c08fcd19dacbc265ee1c6014616b0e04ea0328c2a04e73460")
|
||||
label := []byte("orders")
|
||||
|
||||
// crypto/rand.Reader is a good source of entropy for blinding the RSA
|
||||
// operation.
|
||||
rng := rand.Reader
|
||||
|
||||
plaintext, err := DecryptOAEP(sha256.New(), rng, test2048Key, ciphertext, label)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error from decryption: %s\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("Plaintext: %s\n", string(plaintext))
|
||||
|
||||
// Remember that encryption only provides confidentiality. The
|
||||
// ciphertext should be signed before authenticity is assumed and, even
|
||||
// then, consider that messages might be reordered.
|
||||
}
|
||||
|
|
@ -26,6 +26,10 @@ type PKCS1v15DecryptOptions struct {
|
|||
|
||||
// EncryptPKCS1v15 encrypts the given message with RSA and the padding scheme from PKCS#1 v1.5.
|
||||
// The message must be no longer than the length of the public modulus minus 11 bytes.
|
||||
//
|
||||
// The rand parameter is used as a source of entropy to ensure that encrypting
|
||||
// the same message twice doesn't result in the same ciphertext.
|
||||
//
|
||||
// WARNING: use of this function to encrypt plaintexts other than session keys
|
||||
// is dangerous. Use RSA OAEP in new protocols.
|
||||
func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) (out []byte, err error) {
|
||||
|
|
@ -59,6 +63,12 @@ func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) (out []byte, er
|
|||
|
||||
// DecryptPKCS1v15 decrypts a plaintext using RSA and the padding scheme from PKCS#1 v1.5.
|
||||
// If rand != nil, it uses RSA blinding to avoid timing side-channel attacks.
|
||||
//
|
||||
// Note that whether this function returns an error or not discloses secret
|
||||
// information. If an attacker can cause this function to run repeatedly and
|
||||
// learn whether each instance returned an error then they can decrypt and
|
||||
// forge signatures as if they had the private key. See
|
||||
// DecryptPKCS1v15SessionKey for a way of solving this problem.
|
||||
func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (out []byte, err error) {
|
||||
if err := checkPub(&priv.PublicKey); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -87,6 +97,12 @@ func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (out [
|
|||
// See ``Chosen Ciphertext Attacks Against Protocols Based on the RSA
|
||||
// Encryption Standard PKCS #1'', Daniel Bleichenbacher, Advances in Cryptology
|
||||
// (Crypto '98).
|
||||
//
|
||||
// Note that if the session key is too small then it may be possible for an
|
||||
// attacker to brute-force it. If they can do that then they can learn whether
|
||||
// a random value was used (because it'll be different for the same ciphertext)
|
||||
// and thus whether the padding was correct. This defeats the point of this
|
||||
// function. Using at least a 16-byte key will protect against this attack.
|
||||
func DecryptPKCS1v15SessionKey(rand io.Reader, priv *PrivateKey, ciphertext []byte, key []byte) (err error) {
|
||||
if err := checkPub(&priv.PublicKey); err != nil {
|
||||
return err
|
||||
|
|
@ -201,6 +217,13 @@ var hashPrefixes = map[crypto.Hash][]byte{
|
|||
// Note that hashed must be the result of hashing the input message using the
|
||||
// given hash function. If hash is zero, hashed is signed directly. This isn't
|
||||
// advisable except for interoperability.
|
||||
//
|
||||
// If rand is not nil then RSA blinding will be used to avoid timing side-channel attacks.
|
||||
//
|
||||
// This function is deterministic. Thus, if the set of possible messages is
|
||||
// small, an attacker may be able to build a map from messages to signatures
|
||||
// and identify the signed messages. As ever, signatures provide authenticity,
|
||||
// not confidentiality.
|
||||
func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte) (s []byte, err error) {
|
||||
hashLen, prefix, err := pkcs1v15HashInfo(hash, len(hashed))
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,21 @@
|
|||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package rsa implements RSA encryption as specified in PKCS#1.
|
||||
//
|
||||
// RSA is a single, fundamental operation that is used in this package to
|
||||
// implement either public-key encryption or public-key signatures.
|
||||
//
|
||||
// The original specification for encryption and signatures with RSA is PKCS#1
|
||||
// and the terms "RSA encryption" and "RSA signatures" by default refer to
|
||||
// PKCS#1 version 1.5. However, that specification has flaws and new designs
|
||||
// should use version two, usually called by just OAEP and PSS, where
|
||||
// possible.
|
||||
//
|
||||
// Two sets of interfaces are included in this package. When a more abstract
|
||||
// interface isn't neccessary, there are functions for encrypting/decrypting
|
||||
// with v1.5/OAEP and signing/verifying with v1.5/PSS. If one needs to abstract
|
||||
// over the public-key primitive, the PrivateKey struct implements the
|
||||
// Decrypter and Signer interfaces from the crypto package.
|
||||
package rsa
|
||||
|
||||
import (
|
||||
|
|
@ -317,6 +332,20 @@ func encrypt(c *big.Int, pub *PublicKey, m *big.Int) *big.Int {
|
|||
}
|
||||
|
||||
// EncryptOAEP encrypts the given message with RSA-OAEP.
|
||||
//
|
||||
// OAEP is parameterised by a hash function that is used as a random oracle.
|
||||
// Encryption and decryption of a given message must use the same hash function
|
||||
// and sha256.New() is a reasonable choice.
|
||||
//
|
||||
// The random parameter is used as a source of entropy to ensure that
|
||||
// encrypting the same message twice doesn't result in the same ciphertext.
|
||||
//
|
||||
// The label parameter may contain arbitrary data that will not be encrypted,
|
||||
// but which gives important context to the message. For example, if a given
|
||||
// public key is used to decrypt two types of messages then distinct label
|
||||
// values could be used to ensure that a ciphertext for one purpose cannot be
|
||||
// used for another by an attacker. If not required it can be empty.
|
||||
//
|
||||
// The message must be no longer than the length of the public modulus less
|
||||
// twice the hash length plus 2.
|
||||
func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, label []byte) (out []byte, err error) {
|
||||
|
|
@ -522,7 +551,17 @@ func decryptAndCheck(random io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int
|
|||
}
|
||||
|
||||
// DecryptOAEP decrypts ciphertext using RSA-OAEP.
|
||||
// If random != nil, DecryptOAEP uses RSA blinding to avoid timing side-channel attacks.
|
||||
|
||||
// OAEP is parameterised by a hash function that is used as a random oracle.
|
||||
// Encryption and decryption of a given message must use the same hash function
|
||||
// and sha256.New() is a reasonable choice.
|
||||
//
|
||||
// The random parameter, if not nil, is used to blind the private-key operation
|
||||
// and avoid timing side-channel attacks. Blinding is purely internal to this
|
||||
// function – the random data need not match that used when encrypting.
|
||||
//
|
||||
// The label parameter must match the value given when encrypting. See
|
||||
// EncryptOAEP for details.
|
||||
func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext []byte, label []byte) (msg []byte, err error) {
|
||||
if err := checkPub(&priv.PublicKey); err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
|
|
@ -172,7 +172,9 @@ func Dial(network, addr string, config *Config) (*Conn, error) {
|
|||
}
|
||||
|
||||
// LoadX509KeyPair reads and parses a public/private key pair from a pair of
|
||||
// files. The files must contain PEM encoded data.
|
||||
// files. The files must contain PEM encoded data. On successful return,
|
||||
// Certificate.Leaf will be nil because the parsed form of the certificate is
|
||||
// not retained.
|
||||
func LoadX509KeyPair(certFile, keyFile string) (Certificate, error) {
|
||||
certPEMBlock, err := ioutil.ReadFile(certFile)
|
||||
if err != nil {
|
||||
|
|
@ -186,7 +188,8 @@ func LoadX509KeyPair(certFile, keyFile string) (Certificate, error) {
|
|||
}
|
||||
|
||||
// X509KeyPair parses a public/private key pair from a pair of
|
||||
// PEM encoded data.
|
||||
// PEM encoded data. On successful return, Certificate.Leaf will be nil because
|
||||
// the parsed form of the certificate is not retained.
|
||||
func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (Certificate, error) {
|
||||
fail := func(err error) (Certificate, error) { return Certificate{}, err }
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import (
|
|||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
var errNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error
|
||||
|
|
@ -127,6 +128,18 @@ func convertAssign(dest, src interface{}) error {
|
|||
*d = s
|
||||
return nil
|
||||
}
|
||||
case time.Time:
|
||||
switch d := dest.(type) {
|
||||
case *string:
|
||||
*d = s.Format(time.RFC3339Nano)
|
||||
return nil
|
||||
case *[]byte:
|
||||
if d == nil {
|
||||
return errNilPtr
|
||||
}
|
||||
*d = []byte(s.Format(time.RFC3339Nano))
|
||||
return nil
|
||||
}
|
||||
case nil:
|
||||
switch d := dest.(type) {
|
||||
case *interface{}:
|
||||
|
|
@ -226,7 +239,8 @@ func convertAssign(dest, src interface{}) error {
|
|||
s := asString(src)
|
||||
i64, err := strconv.ParseInt(s, 10, dv.Type().Bits())
|
||||
if err != nil {
|
||||
return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err)
|
||||
err = strconvErr(err)
|
||||
return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
|
||||
}
|
||||
dv.SetInt(i64)
|
||||
return nil
|
||||
|
|
@ -234,7 +248,8 @@ func convertAssign(dest, src interface{}) error {
|
|||
s := asString(src)
|
||||
u64, err := strconv.ParseUint(s, 10, dv.Type().Bits())
|
||||
if err != nil {
|
||||
return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err)
|
||||
err = strconvErr(err)
|
||||
return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
|
||||
}
|
||||
dv.SetUint(u64)
|
||||
return nil
|
||||
|
|
@ -242,13 +257,21 @@ func convertAssign(dest, src interface{}) error {
|
|||
s := asString(src)
|
||||
f64, err := strconv.ParseFloat(s, dv.Type().Bits())
|
||||
if err != nil {
|
||||
return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err)
|
||||
err = strconvErr(err)
|
||||
return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
|
||||
}
|
||||
dv.SetFloat(f64)
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("unsupported driver -> Scan pair: %T -> %T", src, dest)
|
||||
return fmt.Errorf("unsupported Scan, storing driver.Value type %T into type %T", src, dest)
|
||||
}
|
||||
|
||||
func strconvErr(err error) error {
|
||||
if ne, ok := err.(*strconv.NumError); ok {
|
||||
return ne.Err
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func cloneBytes(b []byte) []byte {
|
||||
|
|
|
|||
|
|
@ -77,6 +77,14 @@ var conversionTests = []conversionTest{
|
|||
{s: uint64(123), d: &scanstr, wantstr: "123"},
|
||||
{s: 1.5, d: &scanstr, wantstr: "1.5"},
|
||||
|
||||
// From time.Time:
|
||||
{s: time.Unix(1, 0).UTC(), d: &scanstr, wantstr: "1970-01-01T00:00:01Z"},
|
||||
{s: time.Unix(1453874597, 0).In(time.FixedZone("here", -3600*8)), d: &scanstr, wantstr: "2016-01-26T22:03:17-08:00"},
|
||||
{s: time.Unix(1, 2).UTC(), d: &scanstr, wantstr: "1970-01-01T00:00:01.000000002Z"},
|
||||
{s: time.Time{}, d: &scanstr, wantstr: "0001-01-01T00:00:00Z"},
|
||||
{s: time.Unix(1, 2).UTC(), d: &scanbytes, wantbytes: []byte("1970-01-01T00:00:01.000000002Z")},
|
||||
{s: time.Unix(1, 2).UTC(), d: &scaniface, wantiface: time.Unix(1, 2).UTC()},
|
||||
|
||||
// To []byte
|
||||
{s: nil, d: &scanbytes, wantbytes: nil},
|
||||
{s: "string", d: &scanbytes, wantbytes: []byte("string")},
|
||||
|
|
@ -104,10 +112,16 @@ var conversionTests = []conversionTest{
|
|||
|
||||
// Strings to integers
|
||||
{s: "255", d: &scanuint8, wantuint: 255},
|
||||
{s: "256", d: &scanuint8, wanterr: `converting string "256" to a uint8: strconv.ParseUint: parsing "256": value out of range`},
|
||||
{s: "256", d: &scanuint8, wanterr: "converting driver.Value type string (\"256\") to a uint8: value out of range"},
|
||||
{s: "256", d: &scanuint16, wantuint: 256},
|
||||
{s: "-1", d: &scanint, wantint: -1},
|
||||
{s: "foo", d: &scanint, wanterr: `converting string "foo" to a int: strconv.ParseInt: parsing "foo": invalid syntax`},
|
||||
{s: "foo", d: &scanint, wanterr: "converting driver.Value type string (\"foo\") to a int: invalid syntax"},
|
||||
|
||||
// int64 to smaller integers
|
||||
{s: int64(5), d: &scanuint8, wantuint: 5},
|
||||
{s: int64(256), d: &scanuint8, wanterr: "converting driver.Value type int64 (\"256\") to a uint8: value out of range"},
|
||||
{s: int64(256), d: &scanuint16, wantuint: 256},
|
||||
{s: int64(65536), d: &scanuint16, wanterr: "converting driver.Value type int64 (\"65536\") to a uint16: value out of range"},
|
||||
|
||||
// True bools
|
||||
{s: true, d: &scanbool, wantbool: true},
|
||||
|
|
@ -155,7 +169,10 @@ var conversionTests = []conversionTest{
|
|||
{s: 1.5, d: new(userDefined), wantusrdef: 1.5},
|
||||
{s: int64(123), d: new(userDefined), wantusrdef: 123},
|
||||
{s: "1.5", d: new(userDefined), wantusrdef: 1.5},
|
||||
{s: []byte{1, 2, 3}, d: new(userDefinedSlice), wanterr: `unsupported driver -> Scan pair: []uint8 -> *sql.userDefinedSlice`},
|
||||
{s: []byte{1, 2, 3}, d: new(userDefinedSlice), wanterr: `unsupported Scan, storing driver.Value type []uint8 into type *sql.userDefinedSlice`},
|
||||
|
||||
// Other errors
|
||||
{s: complex(1, 2), d: &scanstr, wanterr: `unsupported Scan, storing driver.Value type complex128 into type *string`},
|
||||
}
|
||||
|
||||
func intPtrValue(intptr interface{}) interface{} {
|
||||
|
|
|
|||
|
|
@ -189,8 +189,7 @@ func (n NullBool) Value() (driver.Value, error) {
|
|||
type Scanner interface {
|
||||
// Scan assigns a value from a database driver.
|
||||
//
|
||||
// The src value will be of one of the following restricted
|
||||
// set of types:
|
||||
// The src value will be of one of the following types:
|
||||
//
|
||||
// int64
|
||||
// float64
|
||||
|
|
@ -1786,17 +1785,56 @@ func (rs *Rows) Columns() ([]string, error) {
|
|||
}
|
||||
|
||||
// Scan copies the columns in the current row into the values pointed
|
||||
// at by dest.
|
||||
// at by dest. The number of values in dest must be the same as the
|
||||
// number of columns in Rows.
|
||||
//
|
||||
// If an argument has type *[]byte, Scan saves in that argument a copy
|
||||
// of the corresponding data. The copy is owned by the caller and can
|
||||
// be modified and held indefinitely. The copy can be avoided by using
|
||||
// an argument of type *RawBytes instead; see the documentation for
|
||||
// RawBytes for restrictions on its use.
|
||||
// Scan converts columns read from the database into the following
|
||||
// common Go types and special types provided by the sql package:
|
||||
//
|
||||
// *string
|
||||
// *[]byte
|
||||
// *int, *int8, *int16, *int32, *int64
|
||||
// *uint, *uint8, *uint16, *uint32, *uint64
|
||||
// *bool
|
||||
// *float32, *float64
|
||||
// *interface{}
|
||||
// *RawBytes
|
||||
// any type implementing Scanner (see Scanner docs)
|
||||
//
|
||||
// In the most simple case, if the type of the value from the source
|
||||
// column is an integer, bool or string type T and dest is of type *T,
|
||||
// Scan simply assigns the value through the pointer.
|
||||
//
|
||||
// Scan also converts between string and numeric types, as long as no
|
||||
// information would be lost. While Scan stringifies all numbers
|
||||
// scanned from numeric database columns into *string, scans into
|
||||
// numeric types are checked for overflow. For example, a float64 with
|
||||
// value 300 or a string with value "300" can scan into a uint16, but
|
||||
// not into a uint8, though float64(255) or "255" can scan into a
|
||||
// uint8. One exception is that scans of some float64 numbers to
|
||||
// strings may lose information when stringifying. In general, scan
|
||||
// floating point columns into *float64.
|
||||
//
|
||||
// If a dest argument has type *[]byte, Scan saves in that argument a
|
||||
// copy of the corresponding data. The copy is owned by the caller and
|
||||
// can be modified and held indefinitely. The copy can be avoided by
|
||||
// using an argument of type *RawBytes instead; see the documentation
|
||||
// for RawBytes for restrictions on its use.
|
||||
//
|
||||
// If an argument has type *interface{}, Scan copies the value
|
||||
// provided by the underlying driver without conversion. If the value
|
||||
// is of type []byte, a copy is made and the caller owns the result.
|
||||
// provided by the underlying driver without conversion. When scanning
|
||||
// from a source value of type []byte to *interface{}, a copy of the
|
||||
// slice is made and the caller owns the result.
|
||||
//
|
||||
// Source values of type time.Time may be scanned into values of type
|
||||
// *time.Time, *interface{}, *string, or *[]byte. When converting to
|
||||
// the latter two, time.Format3339Nano is used.
|
||||
//
|
||||
// Source values of type bool may be scanned into types *bool,
|
||||
// *interface{}, *string, *[]byte, or *RawBytes.
|
||||
//
|
||||
// For scanning into *bool, the source may be true, false, 1, 0, or
|
||||
// string inputs parseable by strconv.ParseBool.
|
||||
func (rs *Rows) Scan(dest ...interface{}) error {
|
||||
if rs.closed {
|
||||
return errors.New("sql: Rows are closed")
|
||||
|
|
@ -1845,8 +1883,9 @@ type Row struct {
|
|||
}
|
||||
|
||||
// Scan copies the columns from the matched row into the values
|
||||
// pointed at by dest. If more than one row matches the query,
|
||||
// Scan uses the first row and discards the rest. If no row matches
|
||||
// pointed at by dest. See the documentation on Rows.Scan for details.
|
||||
// If more than one row matches the query,
|
||||
// Scan uses the first row and discards the rest. If no row matches
|
||||
// the query, Scan returns ErrNoRows.
|
||||
func (r *Row) Scan(dest ...interface{}) error {
|
||||
if r.err != nil {
|
||||
|
|
|
|||
|
|
@ -227,7 +227,8 @@ func NewDecoder(r io.Reader) *Decoder {
|
|||
//
|
||||
// Token guarantees that the StartElement and EndElement
|
||||
// tokens it returns are properly nested and matched:
|
||||
// if Token encounters an unexpected end element,
|
||||
// if Token encounters an unexpected end element
|
||||
// or EOF before all expected end elements,
|
||||
// it will return an error.
|
||||
//
|
||||
// Token implements XML name spaces as described by
|
||||
|
|
|
|||
|
|
@ -300,6 +300,7 @@ func TestShellSafety(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestImportVendor(t *testing.T) {
|
||||
t.Skip("skipping; hpack has moved to internal for now; golang.org/issue/14047")
|
||||
testenv.MustHaveGoBuild(t) // really must just have source
|
||||
ctxt := Default
|
||||
ctxt.GOPATH = ""
|
||||
|
|
|
|||
|
|
@ -358,7 +358,7 @@ var pkgDeps = map[string][]string{
|
|||
"L4", "NET", "OS",
|
||||
"compress/gzip", "crypto/tls", "mime/multipart", "runtime/debug",
|
||||
"net/http/internal",
|
||||
"golang.org/x/net/http2/hpack",
|
||||
"internal/golang.org/x/net/http2/hpack",
|
||||
},
|
||||
"net/http/internal": {"L4"},
|
||||
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ func (x stringVal) String() string {
|
|||
// only the first maxLen-3 runes; then add "...".
|
||||
i := 0
|
||||
for n := 0; n < maxLen-3; n++ {
|
||||
_, size := utf8.DecodeRuneInString(s)
|
||||
_, size := utf8.DecodeRuneInString(s[i:])
|
||||
i += size
|
||||
}
|
||||
s = s[:i] + "..."
|
||||
|
|
|
|||
|
|
@ -204,6 +204,7 @@ func eql(x, y Value) bool {
|
|||
// String tests
|
||||
|
||||
var xxx = strings.Repeat("x", 68)
|
||||
var issue14262 = `"بموجب الشروط التالية نسب المصنف — يجب عليك أن تنسب العمل بالطريقة التي تحددها المؤلف أو المرخص (ولكن ليس بأي حال من الأحوال أن توحي وتقترح بتحول أو استخدامك للعمل). المشاركة على قدم المساواة — إذا كنت يعدل ، والتغيير ، أو الاستفادة من هذا العمل ، قد ينتج عن توزيع العمل إلا في ظل تشابه او تطابق فى واحد لهذا الترخيص."`
|
||||
|
||||
var stringTests = []struct {
|
||||
input, short, exact string
|
||||
|
|
@ -225,6 +226,7 @@ var stringTests = []struct {
|
|||
{`"` + xxx + `xx"`, `"` + xxx + `xx"`, `"` + xxx + `xx"`},
|
||||
{`"` + xxx + `xxx"`, `"` + xxx + `...`, `"` + xxx + `xxx"`},
|
||||
{`"` + xxx + xxx + `xxx"`, `"` + xxx + `...`, `"` + xxx + xxx + `xxx"`},
|
||||
{issue14262, `"بموجب الشروط التالية نسب المصنف — يجب عليك أن تنسب العمل بالطريقة ال...`, issue14262},
|
||||
|
||||
// Int
|
||||
{"0", "0", "0"},
|
||||
|
|
|
|||
|
|
@ -184,7 +184,8 @@ func roundFloat64(x constant.Value) constant.Value {
|
|||
// provided (only needed for int/uint sizes).
|
||||
//
|
||||
// If rounded != nil, *rounded is set to the rounded value of x for
|
||||
// representable floating-point values; it is left alone otherwise.
|
||||
// representable floating-point and complex values, and to an Int
|
||||
// value for integer values; it is left alone otherwise.
|
||||
// It is ok to provide the addressof the first argument for rounded.
|
||||
func representableConst(x constant.Value, conf *Config, typ *Basic, rounded *constant.Value) bool {
|
||||
if x.Kind() == constant.Unknown {
|
||||
|
|
@ -197,6 +198,9 @@ func representableConst(x constant.Value, conf *Config, typ *Basic, rounded *con
|
|||
if x.Kind() != constant.Int {
|
||||
return false
|
||||
}
|
||||
if rounded != nil {
|
||||
*rounded = x
|
||||
}
|
||||
if x, ok := constant.Int64Val(x); ok {
|
||||
switch typ.kind {
|
||||
case Int:
|
||||
|
|
@ -808,8 +812,6 @@ func (check *Checker) binary(x *operand, e *ast.BinaryExpr, lhs, rhs ast.Expr, o
|
|||
typ := x.typ.Underlying().(*Basic)
|
||||
// force integer division of integer operands
|
||||
if op == token.QUO && isInteger(typ) {
|
||||
xval = constant.ToInt(xval)
|
||||
yval = constant.ToInt(yval)
|
||||
op = token.QUO_ASSIGN
|
||||
}
|
||||
x.val = constant.BinaryOp(xval, op, yval)
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue