mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.typeparams] all: merge dev.regabi (23b0c1f) into dev.typeparams
Merge List: + 2021-02-0223b0c1f76e[dev.regabi] all: merge master (fca94ab) into dev.regabi + 2021-02-02fca94ab3abspec: improve the example in Type assertions section + 2021-02-0298f8454a73cmd/link: don't decode type symbol in shared library in deadcode + 2021-02-021426a571b7cmd/link: fix off-by-1 error in findShlibSection + 2021-02-0132e789f4fbtest: fix incorrectly laid out instructions in issue11656.go + 2021-02-01ca6999e27c[dev.regabi] test: add a test for inlining closures + 2021-02-010b6cfea634doc/go1.16: document that on OpenBSD syscalls are now made through libc + 2021-02-0126e29aa15acmd/link: disable TestPIESize if CGO isn't enabled + 2021-02-016ac91e460cdoc/go1.16: minor markup fixes + 2021-01-2944361140c0embed: update docs for proposal tweaks + 2021-01-2968058edc39runtime: document pointer write atomicity for memclrNoHeapPointers + 2021-01-28c8bd8010ffsyscall: generate readlen/writelen for openbsd libc + 2021-01-2841bb49b878cmd/go: revert TestScript/build_trimpath to use ioutil.ReadFile + 2021-01-28725a642c2druntime: correct syscall10/syscall10X on openbsd/amd64 + 2021-01-284b068cafb5doc/go1.16: document go/build/constraint package + 2021-01-28376518d77fruntime,syscall: convert syscall on openbsd/arm64 to libc + 2021-01-27aca22bddf2[dev.regabi] cmd/compile: remove nested functions from expands_calls.go + 2021-01-27667e08ba8c[dev.regabi] cmd/go: Use GOMAXPROCS to limit default build, compile parallelism + 2021-01-2700f2ff5c94api/go1.16: add go/build/constraint APIs + 2021-01-2735334caf18crypto/x509: remove leftover CertificateRequest field + 2021-01-27a5a5e2c968runtime: make sure to remove open-coded defer entries in all cases after a recover + 2021-01-278cfa01943aruntime: block console ctrlhandler when the signal is handled + 2021-01-27ff9e8364c6cmd/go: skip issue33139 when the 'cc' script command is unavailable + 2021-01-27cd176b3615runtime: switch runtime to libc for openbsd/arm64 + 2021-01-276c8fbfbdcfruntime: convert openbsd/arm64 locking to libc + 2021-01-275cdf0da1bfsyscall: clean up mkasm related changes + 2021-01-27210f70e298doc/go1.16: fix closing brace in .Export format + 2021-01-270f797f168dmath: fix typo in sqrt.go code comment + 2021-01-269b636feafe[dev.regabi] cmd/compile: missing last patch set for cl286013 + 2021-01-26f7dad5eae4[dev.regabi] cmd/compile: remove leftover code form late call lowering work + 2021-01-268634a234dfruntime,syscall: convert syscall on openbsd/amd64 to libc + 2021-01-261d5e14632eos: further document limitations around naked file descriptors + 2021-01-26cf263e9f77os: correct names in CreateTemp and MkdirTemp doc comments + 2021-01-26ce8b318624net/http/fcgi: remove locking added to prevent a test-only race Change-Id: Ibd38d559c8a5b0aa32dd0d3a8cdf6876368a3aeb
This commit is contained in:
commit
0d2d6c7464
84 changed files with 4499 additions and 2007 deletions
|
|
@ -232,6 +232,35 @@ pkg go/build, type Package struct, TestEmbedPatterns []string
|
|||
pkg go/build, type Package struct, TestEmbedPatternPos map[string][]token.Position
|
||||
pkg go/build, type Package struct, XTestEmbedPatterns []string
|
||||
pkg go/build, type Package struct, XTestEmbedPatternPos map[string][]token.Position
|
||||
pkg go/build/constraint, func IsGoBuild(string) bool
|
||||
pkg go/build/constraint, func IsPlusBuild(string) bool
|
||||
pkg go/build/constraint, func Parse(string) (Expr, error)
|
||||
pkg go/build/constraint, func PlusBuildLines(Expr) ([]string, error)
|
||||
pkg go/build/constraint, method (*AndExpr) Eval(func(string) bool) bool
|
||||
pkg go/build/constraint, method (*AndExpr) String() string
|
||||
pkg go/build/constraint, method (*NotExpr) Eval(func(string) bool) bool
|
||||
pkg go/build/constraint, method (*NotExpr) String() string
|
||||
pkg go/build/constraint, method (*OrExpr) Eval(func(string) bool) bool
|
||||
pkg go/build/constraint, method (*OrExpr) String() string
|
||||
pkg go/build/constraint, method (*SyntaxError) Error() string
|
||||
pkg go/build/constraint, method (*TagExpr) Eval(func(string) bool) bool
|
||||
pkg go/build/constraint, method (*TagExpr) String() string
|
||||
pkg go/build/constraint, type AndExpr struct
|
||||
pkg go/build/constraint, type AndExpr struct, X Expr
|
||||
pkg go/build/constraint, type AndExpr struct, Y Expr
|
||||
pkg go/build/constraint, type Expr interface, Eval(func(string) bool) bool
|
||||
pkg go/build/constraint, type Expr interface, String() string
|
||||
pkg go/build/constraint, type Expr interface, unexported methods
|
||||
pkg go/build/constraint, type NotExpr struct
|
||||
pkg go/build/constraint, type NotExpr struct, X Expr
|
||||
pkg go/build/constraint, type OrExpr struct
|
||||
pkg go/build/constraint, type OrExpr struct, X Expr
|
||||
pkg go/build/constraint, type OrExpr struct, Y Expr
|
||||
pkg go/build/constraint, type SyntaxError struct
|
||||
pkg go/build/constraint, type SyntaxError struct, Err string
|
||||
pkg go/build/constraint, type SyntaxError struct, Offset int
|
||||
pkg go/build/constraint, type TagExpr struct
|
||||
pkg go/build/constraint, type TagExpr struct, Tag string
|
||||
pkg html/template, func ParseFS(fs.FS, ...string) (*Template, error)
|
||||
pkg html/template, method (*Template) ParseFS(fs.FS, ...string) (*Template, error)
|
||||
pkg io, func NopCloser(Reader) ReadCloser
|
||||
|
|
|
|||
|
|
@ -80,6 +80,16 @@ Do not send CLs removing the interior tags from such phrases.
|
|||
support cgo.
|
||||
</p>
|
||||
|
||||
<p><!-- golang.org/issue/36435, many CLs -->
|
||||
On the 64-bit x86 and 64-bit ARM architectures on OpenBSD (the
|
||||
<code>openbsd/amd64</code> and <code>openbsd/arm64</code> ports), system
|
||||
calls are now made through <code>libc</code>, instead of directly using
|
||||
the <code>SYSCALL</code>/<code>SVC</code> instruction. This ensures
|
||||
forward-compatibility with future versions of OpenBSD. In particular,
|
||||
OpenBSD 6.9 onwards will require system calls to be made through
|
||||
<code>libc</code> for non-static Go binaries.
|
||||
</p>
|
||||
|
||||
<h3 id="386">386</h3>
|
||||
|
||||
<p><!-- golang.org/issue/40255, golang.org/issue/41848, CL 258957, and CL 260017 -->
|
||||
|
|
@ -146,7 +156,7 @@ Do not send CLs removing the interior tags from such phrases.
|
|||
<code>retract</code> directives may now be used in a <code>go.mod</code> file
|
||||
to indicate that certain published versions of the module should not be used
|
||||
by other modules. A module author may retract a version after a severe problem
|
||||
is discovered or if the version was published unintentionally.<br>
|
||||
is discovered or if the version was published unintentionally.
|
||||
</p>
|
||||
|
||||
<p><!-- golang.org/issue/26603 -->
|
||||
|
|
@ -275,7 +285,7 @@ Do not send CLs removing the interior tags from such phrases.
|
|||
When the <code>-export</code> flag is specified, the <code>BuildID</code>
|
||||
field is now set to the build ID of the compiled package. This is equivalent
|
||||
to running <code>go</code> <code>tool</code> <code>buildid</code> on
|
||||
<code>go</code> <code>list</code> <code>-exported</code> <code>-f</code> <code>{{.Export}</code>,
|
||||
<code>go</code> <code>list</code> <code>-exported</code> <code>-f</code> <code>{{.Export}}</code>,
|
||||
but without the extra step.
|
||||
</p>
|
||||
|
||||
|
|
@ -762,6 +772,25 @@ func TestFoo(t *testing.T) {
|
|||
</dd>
|
||||
</dl><!-- go/build -->
|
||||
|
||||
<dl id="go/build/constraint"><dt><a href="/pkg/go/build/constraint/">go/build/constraint</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 240604 -->
|
||||
The new
|
||||
<a href="/pkg/go/build/constraint/"><code>go/build/constraint</code></a>
|
||||
package parses build constraint lines, both the original
|
||||
<code>// +build</code> syntax and the <code>//go:build</code>
|
||||
syntax that will be introduced in Go 1.17.
|
||||
This package exists so that tools built with Go 1.16 will be able
|
||||
to process Go 1.17 source code.
|
||||
See <a href="https://golang.org/design/draft-gobuild">https://golang.org/design/draft-gobuild</a>
|
||||
for details about the build constraint syntaxes and the planned
|
||||
transition to the <code>//go:build</code> syntax.
|
||||
Note that <code>//go:build</code> lines are <b>not</b> supported
|
||||
in Go 1.16 and should not be introduced into Go programs yet.
|
||||
</p>
|
||||
</dd>
|
||||
</dl><!-- go/build/constraint -->
|
||||
|
||||
<dl id="html/template"><dt><a href="/pkg/html/template/">html/template</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 243938 -->
|
||||
|
|
@ -880,7 +909,7 @@ func TestFoo(t *testing.T) {
|
|||
</p>
|
||||
|
||||
<p><!-- CL 250039 -->
|
||||
The <a href="/pkg/net/http/#Client">Client</a> now sends
|
||||
The <a href="/pkg/net/http/#Client"><code>Client</code></a> now sends
|
||||
an explicit <code>Content-Length:</code> <code>0</code>
|
||||
header in <code>PATCH</code> requests with empty bodies,
|
||||
matching the existing behavior of <code>POST</code> and <code>PUT</code>.
|
||||
|
|
@ -927,7 +956,7 @@ func TestFoo(t *testing.T) {
|
|||
<dl id="net/smtp"><dt><a href="/pkg/net/smtp/">net/smtp</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 247257 -->
|
||||
The <a href="/pkg/net/smtp/#Client">Client</a>'s
|
||||
The <a href="/pkg/net/smtp/#Client"><code>Client</code></a>'s
|
||||
<a href="/pkg/net/smtp/#Client.Mail"><code>Mail</code></a>
|
||||
method now sends the <code>SMTPUTF8</code> directive to
|
||||
servers that support it, signaling that addresses are encoded in UTF-8.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<!--{
|
||||
"Title": "The Go Programming Language Specification",
|
||||
"Subtitle": "Version of Oct 7, 2020",
|
||||
"Subtitle": "Version of Feb 2, 2021",
|
||||
"Path": "/ref/spec"
|
||||
}-->
|
||||
|
||||
|
|
@ -3400,7 +3400,7 @@ A type assertion used in an <a href="#Assignments">assignment</a> or initializat
|
|||
v, ok = x.(T)
|
||||
v, ok := x.(T)
|
||||
var v, ok = x.(T)
|
||||
var v, ok T1 = x.(T)
|
||||
var v, ok interface{} = x.(T) // dynamic types of v and ok are T and bool
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
|
|
|
|||
|
|
@ -1063,3 +1063,11 @@ func TestGCData(t *testing.T) {
|
|||
goCmd(t, "build", "-linkshared", "./gcdata/main")
|
||||
runWithEnv(t, "running gcdata/main", []string{"GODEBUG=clobberfree=1"}, "./main")
|
||||
}
|
||||
|
||||
// Test that we don't decode type symbols from shared libraries (which has no data,
|
||||
// causing panic). See issue 44031.
|
||||
func TestIssue44031(t *testing.T) {
|
||||
goCmd(t, "install", "-buildmode=shared", "-linkshared", "./issue44031/a")
|
||||
goCmd(t, "install", "-buildmode=shared", "-linkshared", "./issue44031/b")
|
||||
goCmd(t, "run", "-linkshared", "./issue44031/main")
|
||||
}
|
||||
|
|
|
|||
9
misc/cgo/testshared/testdata/issue44031/a/a.go
vendored
Normal file
9
misc/cgo/testshared/testdata/issue44031/a/a.go
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
// Copyright 2021 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 a
|
||||
|
||||
type ATypeWithALoooooongName interface { // a long name, so the type descriptor symbol name is mangled
|
||||
M()
|
||||
}
|
||||
17
misc/cgo/testshared/testdata/issue44031/b/b.go
vendored
Normal file
17
misc/cgo/testshared/testdata/issue44031/b/b.go
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright 2021 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 b
|
||||
|
||||
import "testshared/issue44031/a"
|
||||
|
||||
type T int
|
||||
|
||||
func (T) M() {}
|
||||
|
||||
var i = a.ATypeWithALoooooongName(T(0))
|
||||
|
||||
func F() {
|
||||
i.M()
|
||||
}
|
||||
20
misc/cgo/testshared/testdata/issue44031/main/main.go
vendored
Normal file
20
misc/cgo/testshared/testdata/issue44031/main/main.go
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright 2021 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 main
|
||||
|
||||
import "testshared/issue44031/b"
|
||||
|
||||
type t int
|
||||
|
||||
func (t) m() {}
|
||||
|
||||
type i interface{ m() } // test that unexported method is correctly marked
|
||||
|
||||
var v interface{} = t(0)
|
||||
|
||||
func main() {
|
||||
b.F()
|
||||
v.(i).m()
|
||||
}
|
||||
|
|
@ -431,7 +431,6 @@ var passes = [...]pass{
|
|||
{name: "early copyelim", fn: copyelim},
|
||||
{name: "early deadcode", fn: deadcode}, // remove generated dead code to avoid doing pointless work during opt
|
||||
{name: "short circuit", fn: shortcircuit},
|
||||
{name: "decompose args", fn: decomposeArgs, required: !go116lateCallExpansion, disabled: go116lateCallExpansion}, // handled by late call lowering
|
||||
{name: "decompose user", fn: decomposeUser, required: true},
|
||||
{name: "pre-opt deadcode", fn: deadcode},
|
||||
{name: "opt", fn: opt, required: true}, // NB: some generic rules know the name of the opt pass. TODO: split required rules and optimizing rules
|
||||
|
|
|
|||
|
|
@ -179,14 +179,6 @@ type Frontend interface {
|
|||
MyImportPath() string
|
||||
}
|
||||
|
||||
const go116lateCallExpansion = true
|
||||
|
||||
// LateCallExpansionEnabledWithin returns true if late call expansion should be tested
|
||||
// within compilation of a function/method.
|
||||
func LateCallExpansionEnabledWithin(f *Func) bool {
|
||||
return go116lateCallExpansion
|
||||
}
|
||||
|
||||
// NewConfig returns a new configuration object for the given architecture.
|
||||
func NewConfig(arch string, types Types, ctxt *obj.Link, optimize bool) *Config {
|
||||
c := &Config{arch: arch, Types: types}
|
||||
|
|
|
|||
|
|
@ -219,10 +219,6 @@ func decomposeInterfacePhi(v *Value) {
|
|||
v.AddArg(data)
|
||||
}
|
||||
|
||||
func decomposeArgs(f *Func) {
|
||||
applyRewrite(f, rewriteBlockdecArgs, rewriteValuedecArgs, removeDeadValues)
|
||||
}
|
||||
|
||||
func decomposeUser(f *Func) {
|
||||
for _, b := range f.Blocks {
|
||||
for _, v := range b.Values {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -42,20 +42,20 @@
|
|||
(Store {hi.Type} dst hi mem))
|
||||
|
||||
// These are not enabled during decomposeBuiltin if late call expansion, but they are always enabled for softFloat
|
||||
(Arg {n} [off]) && is64BitInt(v.Type) && !config.BigEndian && v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin") =>
|
||||
(Arg {n} [off]) && is64BitInt(v.Type) && !config.BigEndian && v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin") =>
|
||||
(Int64Make
|
||||
(Arg <typ.Int32> {n} [off+4])
|
||||
(Arg <typ.UInt32> {n} [off]))
|
||||
(Arg {n} [off]) && is64BitInt(v.Type) && !config.BigEndian && !v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin") =>
|
||||
(Arg {n} [off]) && is64BitInt(v.Type) && !config.BigEndian && !v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin") =>
|
||||
(Int64Make
|
||||
(Arg <typ.UInt32> {n} [off+4])
|
||||
(Arg <typ.UInt32> {n} [off]))
|
||||
|
||||
(Arg {n} [off]) && is64BitInt(v.Type) && config.BigEndian && v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin") =>
|
||||
(Arg {n} [off]) && is64BitInt(v.Type) && config.BigEndian && v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin") =>
|
||||
(Int64Make
|
||||
(Arg <typ.Int32> {n} [off])
|
||||
(Arg <typ.UInt32> {n} [off+4]))
|
||||
(Arg {n} [off]) && is64BitInt(v.Type) && config.BigEndian && !v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin") =>
|
||||
(Arg {n} [off]) && is64BitInt(v.Type) && config.BigEndian && !v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin") =>
|
||||
(Int64Make
|
||||
(Arg <typ.UInt32> {n} [off])
|
||||
(Arg <typ.UInt32> {n} [off+4]))
|
||||
|
|
|
|||
|
|
@ -1,58 +0,0 @@
|
|||
// Copyright 2018 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.
|
||||
|
||||
// Decompose compound argument values
|
||||
// Do this early to simplify tracking names for debugging.
|
||||
|
||||
(Arg {n} [off]) && v.Type.IsString() =>
|
||||
(StringMake
|
||||
(Arg <typ.BytePtr> {n} [off])
|
||||
(Arg <typ.Int> {n} [off+int32(config.PtrSize)]))
|
||||
|
||||
(Arg {n} [off]) && v.Type.IsSlice() =>
|
||||
(SliceMake
|
||||
(Arg <v.Type.Elem().PtrTo()> {n} [off])
|
||||
(Arg <typ.Int> {n} [off+int32(config.PtrSize)])
|
||||
(Arg <typ.Int> {n} [off+2*int32(config.PtrSize)]))
|
||||
|
||||
(Arg {n} [off]) && v.Type.IsInterface() =>
|
||||
(IMake
|
||||
(Arg <typ.Uintptr> {n} [off])
|
||||
(Arg <typ.BytePtr> {n} [off+int32(config.PtrSize)]))
|
||||
|
||||
(Arg {n} [off]) && v.Type.IsComplex() && v.Type.Size() == 16 =>
|
||||
(ComplexMake
|
||||
(Arg <typ.Float64> {n} [off])
|
||||
(Arg <typ.Float64> {n} [off+8]))
|
||||
|
||||
(Arg {n} [off]) && v.Type.IsComplex() && v.Type.Size() == 8 =>
|
||||
(ComplexMake
|
||||
(Arg <typ.Float32> {n} [off])
|
||||
(Arg <typ.Float32> {n} [off+4]))
|
||||
|
||||
(Arg <t>) && t.IsStruct() && t.NumFields() == 0 && fe.CanSSA(t) =>
|
||||
(StructMake0)
|
||||
(Arg <t> {n} [off]) && t.IsStruct() && t.NumFields() == 1 && fe.CanSSA(t) =>
|
||||
(StructMake1
|
||||
(Arg <t.FieldType(0)> {n} [off+int32(t.FieldOff(0))]))
|
||||
(Arg <t> {n} [off]) && t.IsStruct() && t.NumFields() == 2 && fe.CanSSA(t) =>
|
||||
(StructMake2
|
||||
(Arg <t.FieldType(0)> {n} [off+int32(t.FieldOff(0))])
|
||||
(Arg <t.FieldType(1)> {n} [off+int32(t.FieldOff(1))]))
|
||||
(Arg <t> {n} [off]) && t.IsStruct() && t.NumFields() == 3 && fe.CanSSA(t) =>
|
||||
(StructMake3
|
||||
(Arg <t.FieldType(0)> {n} [off+int32(t.FieldOff(0))])
|
||||
(Arg <t.FieldType(1)> {n} [off+int32(t.FieldOff(1))])
|
||||
(Arg <t.FieldType(2)> {n} [off+int32(t.FieldOff(2))]))
|
||||
(Arg <t> {n} [off]) && t.IsStruct() && t.NumFields() == 4 && fe.CanSSA(t) =>
|
||||
(StructMake4
|
||||
(Arg <t.FieldType(0)> {n} [off+int32(t.FieldOff(0))])
|
||||
(Arg <t.FieldType(1)> {n} [off+int32(t.FieldOff(1))])
|
||||
(Arg <t.FieldType(2)> {n} [off+int32(t.FieldOff(2))])
|
||||
(Arg <t.FieldType(3)> {n} [off+int32(t.FieldOff(3))]))
|
||||
|
||||
(Arg <t>) && t.IsArray() && t.NumElem() == 0 =>
|
||||
(ArrayMake0)
|
||||
(Arg <t> {n} [off]) && t.IsArray() && t.NumElem() == 1 && fe.CanSSA(t) =>
|
||||
(ArrayMake1 (Arg <t.Elem()> {n} [off]))
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
// Copyright 2018 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.
|
||||
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
var decArgsOps = []opData{}
|
||||
|
||||
var decArgsBlocks = []blockData{}
|
||||
|
||||
func init() {
|
||||
archs = append(archs, arch{
|
||||
name: "decArgs",
|
||||
ops: decArgsOps,
|
||||
blocks: decArgsBlocks,
|
||||
generic: true,
|
||||
})
|
||||
}
|
||||
|
|
@ -184,12 +184,12 @@ func rewriteValuedec64_OpArg(v *Value) bool {
|
|||
config := b.Func.Config
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (Arg {n} [off])
|
||||
// cond: is64BitInt(v.Type) && !config.BigEndian && v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin")
|
||||
// cond: is64BitInt(v.Type) && !config.BigEndian && v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin")
|
||||
// result: (Int64Make (Arg <typ.Int32> {n} [off+4]) (Arg <typ.UInt32> {n} [off]))
|
||||
for {
|
||||
off := auxIntToInt32(v.AuxInt)
|
||||
n := auxToSym(v.Aux)
|
||||
if !(is64BitInt(v.Type) && !config.BigEndian && v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin")) {
|
||||
if !(is64BitInt(v.Type) && !config.BigEndian && v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin")) {
|
||||
break
|
||||
}
|
||||
v.reset(OpInt64Make)
|
||||
|
|
@ -203,12 +203,12 @@ func rewriteValuedec64_OpArg(v *Value) bool {
|
|||
return true
|
||||
}
|
||||
// match: (Arg {n} [off])
|
||||
// cond: is64BitInt(v.Type) && !config.BigEndian && !v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin")
|
||||
// cond: is64BitInt(v.Type) && !config.BigEndian && !v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin")
|
||||
// result: (Int64Make (Arg <typ.UInt32> {n} [off+4]) (Arg <typ.UInt32> {n} [off]))
|
||||
for {
|
||||
off := auxIntToInt32(v.AuxInt)
|
||||
n := auxToSym(v.Aux)
|
||||
if !(is64BitInt(v.Type) && !config.BigEndian && !v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin")) {
|
||||
if !(is64BitInt(v.Type) && !config.BigEndian && !v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin")) {
|
||||
break
|
||||
}
|
||||
v.reset(OpInt64Make)
|
||||
|
|
@ -222,12 +222,12 @@ func rewriteValuedec64_OpArg(v *Value) bool {
|
|||
return true
|
||||
}
|
||||
// match: (Arg {n} [off])
|
||||
// cond: is64BitInt(v.Type) && config.BigEndian && v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin")
|
||||
// cond: is64BitInt(v.Type) && config.BigEndian && v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin")
|
||||
// result: (Int64Make (Arg <typ.Int32> {n} [off]) (Arg <typ.UInt32> {n} [off+4]))
|
||||
for {
|
||||
off := auxIntToInt32(v.AuxInt)
|
||||
n := auxToSym(v.Aux)
|
||||
if !(is64BitInt(v.Type) && config.BigEndian && v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin")) {
|
||||
if !(is64BitInt(v.Type) && config.BigEndian && v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin")) {
|
||||
break
|
||||
}
|
||||
v.reset(OpInt64Make)
|
||||
|
|
@ -241,12 +241,12 @@ func rewriteValuedec64_OpArg(v *Value) bool {
|
|||
return true
|
||||
}
|
||||
// match: (Arg {n} [off])
|
||||
// cond: is64BitInt(v.Type) && config.BigEndian && !v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin")
|
||||
// cond: is64BitInt(v.Type) && config.BigEndian && !v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin")
|
||||
// result: (Int64Make (Arg <typ.UInt32> {n} [off]) (Arg <typ.UInt32> {n} [off+4]))
|
||||
for {
|
||||
off := auxIntToInt32(v.AuxInt)
|
||||
n := auxToSym(v.Aux)
|
||||
if !(is64BitInt(v.Type) && config.BigEndian && !v.Type.IsSigned() && !(go116lateCallExpansion && b.Func.pass.name == "decompose builtin")) {
|
||||
if !(is64BitInt(v.Type) && config.BigEndian && !v.Type.IsSigned() && !(b.Func.pass.name == "decompose builtin")) {
|
||||
break
|
||||
}
|
||||
v.reset(OpInt64Make)
|
||||
|
|
|
|||
|
|
@ -1,247 +0,0 @@
|
|||
// Code generated from gen/decArgs.rules; DO NOT EDIT.
|
||||
// generated with: cd gen; go run *.go
|
||||
|
||||
package ssa
|
||||
|
||||
func rewriteValuedecArgs(v *Value) bool {
|
||||
switch v.Op {
|
||||
case OpArg:
|
||||
return rewriteValuedecArgs_OpArg(v)
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuedecArgs_OpArg(v *Value) bool {
|
||||
b := v.Block
|
||||
config := b.Func.Config
|
||||
fe := b.Func.fe
|
||||
typ := &b.Func.Config.Types
|
||||
// match: (Arg {n} [off])
|
||||
// cond: v.Type.IsString()
|
||||
// result: (StringMake (Arg <typ.BytePtr> {n} [off]) (Arg <typ.Int> {n} [off+int32(config.PtrSize)]))
|
||||
for {
|
||||
off := auxIntToInt32(v.AuxInt)
|
||||
n := auxToSym(v.Aux)
|
||||
if !(v.Type.IsString()) {
|
||||
break
|
||||
}
|
||||
v.reset(OpStringMake)
|
||||
v0 := b.NewValue0(v.Pos, OpArg, typ.BytePtr)
|
||||
v0.AuxInt = int32ToAuxInt(off)
|
||||
v0.Aux = symToAux(n)
|
||||
v1 := b.NewValue0(v.Pos, OpArg, typ.Int)
|
||||
v1.AuxInt = int32ToAuxInt(off + int32(config.PtrSize))
|
||||
v1.Aux = symToAux(n)
|
||||
v.AddArg2(v0, v1)
|
||||
return true
|
||||
}
|
||||
// match: (Arg {n} [off])
|
||||
// cond: v.Type.IsSlice()
|
||||
// result: (SliceMake (Arg <v.Type.Elem().PtrTo()> {n} [off]) (Arg <typ.Int> {n} [off+int32(config.PtrSize)]) (Arg <typ.Int> {n} [off+2*int32(config.PtrSize)]))
|
||||
for {
|
||||
off := auxIntToInt32(v.AuxInt)
|
||||
n := auxToSym(v.Aux)
|
||||
if !(v.Type.IsSlice()) {
|
||||
break
|
||||
}
|
||||
v.reset(OpSliceMake)
|
||||
v0 := b.NewValue0(v.Pos, OpArg, v.Type.Elem().PtrTo())
|
||||
v0.AuxInt = int32ToAuxInt(off)
|
||||
v0.Aux = symToAux(n)
|
||||
v1 := b.NewValue0(v.Pos, OpArg, typ.Int)
|
||||
v1.AuxInt = int32ToAuxInt(off + int32(config.PtrSize))
|
||||
v1.Aux = symToAux(n)
|
||||
v2 := b.NewValue0(v.Pos, OpArg, typ.Int)
|
||||
v2.AuxInt = int32ToAuxInt(off + 2*int32(config.PtrSize))
|
||||
v2.Aux = symToAux(n)
|
||||
v.AddArg3(v0, v1, v2)
|
||||
return true
|
||||
}
|
||||
// match: (Arg {n} [off])
|
||||
// cond: v.Type.IsInterface()
|
||||
// result: (IMake (Arg <typ.Uintptr> {n} [off]) (Arg <typ.BytePtr> {n} [off+int32(config.PtrSize)]))
|
||||
for {
|
||||
off := auxIntToInt32(v.AuxInt)
|
||||
n := auxToSym(v.Aux)
|
||||
if !(v.Type.IsInterface()) {
|
||||
break
|
||||
}
|
||||
v.reset(OpIMake)
|
||||
v0 := b.NewValue0(v.Pos, OpArg, typ.Uintptr)
|
||||
v0.AuxInt = int32ToAuxInt(off)
|
||||
v0.Aux = symToAux(n)
|
||||
v1 := b.NewValue0(v.Pos, OpArg, typ.BytePtr)
|
||||
v1.AuxInt = int32ToAuxInt(off + int32(config.PtrSize))
|
||||
v1.Aux = symToAux(n)
|
||||
v.AddArg2(v0, v1)
|
||||
return true
|
||||
}
|
||||
// match: (Arg {n} [off])
|
||||
// cond: v.Type.IsComplex() && v.Type.Size() == 16
|
||||
// result: (ComplexMake (Arg <typ.Float64> {n} [off]) (Arg <typ.Float64> {n} [off+8]))
|
||||
for {
|
||||
off := auxIntToInt32(v.AuxInt)
|
||||
n := auxToSym(v.Aux)
|
||||
if !(v.Type.IsComplex() && v.Type.Size() == 16) {
|
||||
break
|
||||
}
|
||||
v.reset(OpComplexMake)
|
||||
v0 := b.NewValue0(v.Pos, OpArg, typ.Float64)
|
||||
v0.AuxInt = int32ToAuxInt(off)
|
||||
v0.Aux = symToAux(n)
|
||||
v1 := b.NewValue0(v.Pos, OpArg, typ.Float64)
|
||||
v1.AuxInt = int32ToAuxInt(off + 8)
|
||||
v1.Aux = symToAux(n)
|
||||
v.AddArg2(v0, v1)
|
||||
return true
|
||||
}
|
||||
// match: (Arg {n} [off])
|
||||
// cond: v.Type.IsComplex() && v.Type.Size() == 8
|
||||
// result: (ComplexMake (Arg <typ.Float32> {n} [off]) (Arg <typ.Float32> {n} [off+4]))
|
||||
for {
|
||||
off := auxIntToInt32(v.AuxInt)
|
||||
n := auxToSym(v.Aux)
|
||||
if !(v.Type.IsComplex() && v.Type.Size() == 8) {
|
||||
break
|
||||
}
|
||||
v.reset(OpComplexMake)
|
||||
v0 := b.NewValue0(v.Pos, OpArg, typ.Float32)
|
||||
v0.AuxInt = int32ToAuxInt(off)
|
||||
v0.Aux = symToAux(n)
|
||||
v1 := b.NewValue0(v.Pos, OpArg, typ.Float32)
|
||||
v1.AuxInt = int32ToAuxInt(off + 4)
|
||||
v1.Aux = symToAux(n)
|
||||
v.AddArg2(v0, v1)
|
||||
return true
|
||||
}
|
||||
// match: (Arg <t>)
|
||||
// cond: t.IsStruct() && t.NumFields() == 0 && fe.CanSSA(t)
|
||||
// result: (StructMake0)
|
||||
for {
|
||||
t := v.Type
|
||||
if !(t.IsStruct() && t.NumFields() == 0 && fe.CanSSA(t)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpStructMake0)
|
||||
return true
|
||||
}
|
||||
// match: (Arg <t> {n} [off])
|
||||
// cond: t.IsStruct() && t.NumFields() == 1 && fe.CanSSA(t)
|
||||
// result: (StructMake1 (Arg <t.FieldType(0)> {n} [off+int32(t.FieldOff(0))]))
|
||||
for {
|
||||
t := v.Type
|
||||
off := auxIntToInt32(v.AuxInt)
|
||||
n := auxToSym(v.Aux)
|
||||
if !(t.IsStruct() && t.NumFields() == 1 && fe.CanSSA(t)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpStructMake1)
|
||||
v0 := b.NewValue0(v.Pos, OpArg, t.FieldType(0))
|
||||
v0.AuxInt = int32ToAuxInt(off + int32(t.FieldOff(0)))
|
||||
v0.Aux = symToAux(n)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
// match: (Arg <t> {n} [off])
|
||||
// cond: t.IsStruct() && t.NumFields() == 2 && fe.CanSSA(t)
|
||||
// result: (StructMake2 (Arg <t.FieldType(0)> {n} [off+int32(t.FieldOff(0))]) (Arg <t.FieldType(1)> {n} [off+int32(t.FieldOff(1))]))
|
||||
for {
|
||||
t := v.Type
|
||||
off := auxIntToInt32(v.AuxInt)
|
||||
n := auxToSym(v.Aux)
|
||||
if !(t.IsStruct() && t.NumFields() == 2 && fe.CanSSA(t)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpStructMake2)
|
||||
v0 := b.NewValue0(v.Pos, OpArg, t.FieldType(0))
|
||||
v0.AuxInt = int32ToAuxInt(off + int32(t.FieldOff(0)))
|
||||
v0.Aux = symToAux(n)
|
||||
v1 := b.NewValue0(v.Pos, OpArg, t.FieldType(1))
|
||||
v1.AuxInt = int32ToAuxInt(off + int32(t.FieldOff(1)))
|
||||
v1.Aux = symToAux(n)
|
||||
v.AddArg2(v0, v1)
|
||||
return true
|
||||
}
|
||||
// match: (Arg <t> {n} [off])
|
||||
// cond: t.IsStruct() && t.NumFields() == 3 && fe.CanSSA(t)
|
||||
// result: (StructMake3 (Arg <t.FieldType(0)> {n} [off+int32(t.FieldOff(0))]) (Arg <t.FieldType(1)> {n} [off+int32(t.FieldOff(1))]) (Arg <t.FieldType(2)> {n} [off+int32(t.FieldOff(2))]))
|
||||
for {
|
||||
t := v.Type
|
||||
off := auxIntToInt32(v.AuxInt)
|
||||
n := auxToSym(v.Aux)
|
||||
if !(t.IsStruct() && t.NumFields() == 3 && fe.CanSSA(t)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpStructMake3)
|
||||
v0 := b.NewValue0(v.Pos, OpArg, t.FieldType(0))
|
||||
v0.AuxInt = int32ToAuxInt(off + int32(t.FieldOff(0)))
|
||||
v0.Aux = symToAux(n)
|
||||
v1 := b.NewValue0(v.Pos, OpArg, t.FieldType(1))
|
||||
v1.AuxInt = int32ToAuxInt(off + int32(t.FieldOff(1)))
|
||||
v1.Aux = symToAux(n)
|
||||
v2 := b.NewValue0(v.Pos, OpArg, t.FieldType(2))
|
||||
v2.AuxInt = int32ToAuxInt(off + int32(t.FieldOff(2)))
|
||||
v2.Aux = symToAux(n)
|
||||
v.AddArg3(v0, v1, v2)
|
||||
return true
|
||||
}
|
||||
// match: (Arg <t> {n} [off])
|
||||
// cond: t.IsStruct() && t.NumFields() == 4 && fe.CanSSA(t)
|
||||
// result: (StructMake4 (Arg <t.FieldType(0)> {n} [off+int32(t.FieldOff(0))]) (Arg <t.FieldType(1)> {n} [off+int32(t.FieldOff(1))]) (Arg <t.FieldType(2)> {n} [off+int32(t.FieldOff(2))]) (Arg <t.FieldType(3)> {n} [off+int32(t.FieldOff(3))]))
|
||||
for {
|
||||
t := v.Type
|
||||
off := auxIntToInt32(v.AuxInt)
|
||||
n := auxToSym(v.Aux)
|
||||
if !(t.IsStruct() && t.NumFields() == 4 && fe.CanSSA(t)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpStructMake4)
|
||||
v0 := b.NewValue0(v.Pos, OpArg, t.FieldType(0))
|
||||
v0.AuxInt = int32ToAuxInt(off + int32(t.FieldOff(0)))
|
||||
v0.Aux = symToAux(n)
|
||||
v1 := b.NewValue0(v.Pos, OpArg, t.FieldType(1))
|
||||
v1.AuxInt = int32ToAuxInt(off + int32(t.FieldOff(1)))
|
||||
v1.Aux = symToAux(n)
|
||||
v2 := b.NewValue0(v.Pos, OpArg, t.FieldType(2))
|
||||
v2.AuxInt = int32ToAuxInt(off + int32(t.FieldOff(2)))
|
||||
v2.Aux = symToAux(n)
|
||||
v3 := b.NewValue0(v.Pos, OpArg, t.FieldType(3))
|
||||
v3.AuxInt = int32ToAuxInt(off + int32(t.FieldOff(3)))
|
||||
v3.Aux = symToAux(n)
|
||||
v.AddArg4(v0, v1, v2, v3)
|
||||
return true
|
||||
}
|
||||
// match: (Arg <t>)
|
||||
// cond: t.IsArray() && t.NumElem() == 0
|
||||
// result: (ArrayMake0)
|
||||
for {
|
||||
t := v.Type
|
||||
if !(t.IsArray() && t.NumElem() == 0) {
|
||||
break
|
||||
}
|
||||
v.reset(OpArrayMake0)
|
||||
return true
|
||||
}
|
||||
// match: (Arg <t> {n} [off])
|
||||
// cond: t.IsArray() && t.NumElem() == 1 && fe.CanSSA(t)
|
||||
// result: (ArrayMake1 (Arg <t.Elem()> {n} [off]))
|
||||
for {
|
||||
t := v.Type
|
||||
off := auxIntToInt32(v.AuxInt)
|
||||
n := auxToSym(v.Aux)
|
||||
if !(t.IsArray() && t.NumElem() == 1 && fe.CanSSA(t)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpArrayMake1)
|
||||
v0 := b.NewValue0(v.Pos, OpArg, t.Elem())
|
||||
v0.AuxInt = int32ToAuxInt(off)
|
||||
v0.Aux = symToAux(n)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteBlockdecArgs(b *Block) bool {
|
||||
switch b.Kind {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
@ -1803,7 +1803,7 @@ const shareDeferExits = false
|
|||
// It returns a BlockRet block that ends the control flow. Its control value
|
||||
// will be set to the final memory state.
|
||||
func (s *state) exit() *ssa.Block {
|
||||
lateResultLowering := s.f.DebugTest && ssa.LateCallExpansionEnabledWithin(s.f)
|
||||
lateResultLowering := s.f.DebugTest
|
||||
if s.hasdefer {
|
||||
if s.hasOpenDefers {
|
||||
if shareDeferExits && s.lastDeferExit != nil && len(s.openDefers) == s.lastDeferCount {
|
||||
|
|
@ -4628,7 +4628,6 @@ func (s *state) openDeferExit() {
|
|||
s.lastDeferExit = deferExit
|
||||
s.lastDeferCount = len(s.openDefers)
|
||||
zeroval := s.constInt8(types.Types[types.TUINT8], 0)
|
||||
testLateExpansion := ssa.LateCallExpansionEnabledWithin(s.f)
|
||||
// Test for and run defers in reverse order
|
||||
for i := len(s.openDefers) - 1; i >= 0; i-- {
|
||||
r := s.openDefers[i]
|
||||
|
|
@ -4670,19 +4669,12 @@ func (s *state) openDeferExit() {
|
|||
if r.rcvr != nil {
|
||||
// rcvr in case of OCALLINTER
|
||||
v := s.load(r.rcvr.Type.Elem(), r.rcvr)
|
||||
addr := s.constOffPtrSP(s.f.Config.Types.UintptrPtr, argStart)
|
||||
ACArgs = append(ACArgs, ssa.Param{Type: types.Types[types.TUINTPTR], Offset: int32(argStart)})
|
||||
if testLateExpansion {
|
||||
callArgs = append(callArgs, v)
|
||||
} else {
|
||||
s.store(types.Types[types.TUINTPTR], addr, v)
|
||||
}
|
||||
}
|
||||
for j, argAddrVal := range r.argVals {
|
||||
f := getParam(r.n, j)
|
||||
pt := types.NewPtr(f.Type)
|
||||
ACArgs = append(ACArgs, ssa.Param{Type: f.Type, Offset: int32(argStart + f.Offset)})
|
||||
if testLateExpansion {
|
||||
var a *ssa.Value
|
||||
if !TypeOK(f.Type) {
|
||||
a = s.newValue2(ssa.OpDereference, f.Type, argAddrVal, s.mem())
|
||||
|
|
@ -4690,15 +4682,6 @@ func (s *state) openDeferExit() {
|
|||
a = s.load(f.Type, argAddrVal)
|
||||
}
|
||||
callArgs = append(callArgs, a)
|
||||
} else {
|
||||
addr := s.constOffPtrSP(pt, argStart+f.Offset)
|
||||
if !TypeOK(f.Type) {
|
||||
s.move(f.Type, addr, argAddrVal)
|
||||
} else {
|
||||
argVal := s.load(f.Type, argAddrVal)
|
||||
s.storeType(f.Type, addr, argVal, 0, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
var call *ssa.Value
|
||||
if r.closure != nil {
|
||||
|
|
@ -4706,30 +4689,15 @@ func (s *state) openDeferExit() {
|
|||
s.maybeNilCheckClosure(v, callDefer)
|
||||
codeptr := s.rawLoad(types.Types[types.TUINTPTR], v)
|
||||
aux := ssa.ClosureAuxCall(ACArgs, ACResults)
|
||||
if testLateExpansion {
|
||||
callArgs = append(callArgs, s.mem())
|
||||
call = s.newValue2A(ssa.OpClosureLECall, aux.LateExpansionResultType(), aux, codeptr, v)
|
||||
call.AddArgs(callArgs...)
|
||||
} else {
|
||||
call = s.newValue3A(ssa.OpClosureCall, types.TypeMem, aux, codeptr, v, s.mem())
|
||||
}
|
||||
} else {
|
||||
aux := ssa.StaticAuxCall(fn.(*ir.Name).Linksym(), ACArgs, ACResults)
|
||||
if testLateExpansion {
|
||||
callArgs = append(callArgs, s.mem())
|
||||
call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux)
|
||||
}
|
||||
callArgs = append(callArgs, s.mem())
|
||||
call.AddArgs(callArgs...)
|
||||
} else {
|
||||
// Do a static call if the original call was a static function or method
|
||||
call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, aux, s.mem())
|
||||
}
|
||||
}
|
||||
call.AuxInt = stksize
|
||||
if testLateExpansion {
|
||||
s.vars[memVar] = s.newValue1I(ssa.OpSelectN, types.TypeMem, int64(len(ACResults)), call)
|
||||
} else {
|
||||
s.vars[memVar] = call
|
||||
}
|
||||
// Make sure that the stack slots with pointers are kept live
|
||||
// through the call (which is a pre-emption point). Also, we will
|
||||
// use the first call of the last defer exit to compute liveness
|
||||
|
|
@ -4782,12 +4750,10 @@ func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool) *ssa.Val
|
|||
}
|
||||
}
|
||||
|
||||
testLateExpansion := false
|
||||
inRegisters := false
|
||||
|
||||
switch n.Op() {
|
||||
case ir.OCALLFUNC:
|
||||
testLateExpansion = k != callDeferStack && ssa.LateCallExpansionEnabledWithin(s.f)
|
||||
if k == callNormal && fn.Op() == ir.ONAME && fn.(*ir.Name).Class == ir.PFUNC {
|
||||
fn := fn.(*ir.Name)
|
||||
callee = fn
|
||||
|
|
@ -4813,7 +4779,6 @@ func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool) *ssa.Val
|
|||
s.Fatalf("OCALLINTER: n.Left not an ODOTINTER: %v", fn.Op())
|
||||
}
|
||||
fn := fn.(*ir.SelectorExpr)
|
||||
testLateExpansion = k != callDeferStack && ssa.LateCallExpansionEnabledWithin(s.f)
|
||||
var iclosure *ssa.Value
|
||||
iclosure, rcvr = s.getClosureAndRcvr(fn)
|
||||
if k == callNormal {
|
||||
|
|
@ -4827,7 +4792,6 @@ func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool) *ssa.Val
|
|||
|
||||
var call *ssa.Value
|
||||
if k == callDeferStack {
|
||||
testLateExpansion = ssa.LateCallExpansionEnabledWithin(s.f)
|
||||
// Make a defer struct d on the stack.
|
||||
t := deferstruct(stksize)
|
||||
d := typecheck.TempAt(n.Pos(), s.curfn, t)
|
||||
|
|
@ -4878,15 +4842,9 @@ func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool) *ssa.Val
|
|||
// Call runtime.deferprocStack with pointer to _defer record.
|
||||
ACArgs = append(ACArgs, ssa.Param{Type: types.Types[types.TUINTPTR], Offset: int32(base.Ctxt.FixedFrameSize())})
|
||||
aux := ssa.StaticAuxCall(ir.Syms.DeferprocStack, ACArgs, ACResults)
|
||||
if testLateExpansion {
|
||||
callArgs = append(callArgs, addr, s.mem())
|
||||
call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux)
|
||||
call.AddArgs(callArgs...)
|
||||
} else {
|
||||
arg0 := s.constOffPtrSP(types.Types[types.TUINTPTR], base.Ctxt.FixedFrameSize())
|
||||
s.store(types.Types[types.TUINTPTR], arg0, addr)
|
||||
call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, aux, s.mem())
|
||||
}
|
||||
if stksize < int64(types.PtrSize) {
|
||||
// We need room for both the call to deferprocStack and the call to
|
||||
// the deferred function.
|
||||
|
|
@ -4903,32 +4861,17 @@ func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool) *ssa.Val
|
|||
// Write argsize and closure (args to newproc/deferproc).
|
||||
argsize := s.constInt32(types.Types[types.TUINT32], int32(stksize))
|
||||
ACArgs = append(ACArgs, ssa.Param{Type: types.Types[types.TUINT32], Offset: int32(argStart)})
|
||||
if testLateExpansion {
|
||||
callArgs = append(callArgs, argsize)
|
||||
} else {
|
||||
addr := s.constOffPtrSP(s.f.Config.Types.UInt32Ptr, argStart)
|
||||
s.store(types.Types[types.TUINT32], addr, argsize)
|
||||
}
|
||||
ACArgs = append(ACArgs, ssa.Param{Type: types.Types[types.TUINTPTR], Offset: int32(argStart) + int32(types.PtrSize)})
|
||||
if testLateExpansion {
|
||||
callArgs = append(callArgs, closure)
|
||||
} else {
|
||||
addr := s.constOffPtrSP(s.f.Config.Types.UintptrPtr, argStart+int64(types.PtrSize))
|
||||
s.store(types.Types[types.TUINTPTR], addr, closure)
|
||||
}
|
||||
stksize += 2 * int64(types.PtrSize)
|
||||
argStart += 2 * int64(types.PtrSize)
|
||||
}
|
||||
|
||||
// Set receiver (for interface calls).
|
||||
if rcvr != nil {
|
||||
addr := s.constOffPtrSP(s.f.Config.Types.UintptrPtr, argStart)
|
||||
ACArgs = append(ACArgs, ssa.Param{Type: types.Types[types.TUINTPTR], Offset: int32(argStart)})
|
||||
if testLateExpansion {
|
||||
callArgs = append(callArgs, rcvr)
|
||||
} else {
|
||||
s.store(types.Types[types.TUINTPTR], addr, rcvr)
|
||||
}
|
||||
}
|
||||
|
||||
// Write args.
|
||||
|
|
@ -4939,7 +4882,7 @@ func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool) *ssa.Val
|
|||
}
|
||||
for i, n := range args {
|
||||
f := t.Params().Field(i)
|
||||
ACArg, arg := s.putArg(n, f.Type, argStart+f.Offset, testLateExpansion)
|
||||
ACArg, arg := s.putArg(n, f.Type, argStart+f.Offset)
|
||||
ACArgs = append(ACArgs, ACArg)
|
||||
callArgs = append(callArgs, arg)
|
||||
}
|
||||
|
|
@ -4950,20 +4893,10 @@ func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool) *ssa.Val
|
|||
switch {
|
||||
case k == callDefer:
|
||||
aux := ssa.StaticAuxCall(ir.Syms.Deferproc, ACArgs, ACResults)
|
||||
if testLateExpansion {
|
||||
call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux)
|
||||
call.AddArgs(callArgs...)
|
||||
} else {
|
||||
call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, aux, s.mem())
|
||||
}
|
||||
case k == callGo:
|
||||
aux := ssa.StaticAuxCall(ir.Syms.Newproc, ACArgs, ACResults)
|
||||
if testLateExpansion {
|
||||
call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux)
|
||||
call.AddArgs(callArgs...)
|
||||
} else {
|
||||
call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, aux, s.mem())
|
||||
}
|
||||
case closure != nil:
|
||||
// rawLoad because loading the code pointer from a
|
||||
// closure is always safe, but IsSanitizerSafeAddr
|
||||
|
|
@ -4971,40 +4904,22 @@ func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool) *ssa.Val
|
|||
// critical that we not clobber any arguments already
|
||||
// stored onto the stack.
|
||||
codeptr = s.rawLoad(types.Types[types.TUINTPTR], closure)
|
||||
if testLateExpansion {
|
||||
aux := ssa.ClosureAuxCall(ACArgs, ACResults)
|
||||
call = s.newValue2A(ssa.OpClosureLECall, aux.LateExpansionResultType(), aux, codeptr, closure)
|
||||
call.AddArgs(callArgs...)
|
||||
} else {
|
||||
call = s.newValue3A(ssa.OpClosureCall, types.TypeMem, ssa.ClosureAuxCall(ACArgs, ACResults), codeptr, closure, s.mem())
|
||||
}
|
||||
case codeptr != nil:
|
||||
if testLateExpansion {
|
||||
aux := ssa.InterfaceAuxCall(ACArgs, ACResults)
|
||||
call = s.newValue1A(ssa.OpInterLECall, aux.LateExpansionResultType(), aux, codeptr)
|
||||
call.AddArgs(callArgs...)
|
||||
} else {
|
||||
call = s.newValue2A(ssa.OpInterCall, types.TypeMem, ssa.InterfaceAuxCall(ACArgs, ACResults), codeptr, s.mem())
|
||||
}
|
||||
case callee != nil:
|
||||
if testLateExpansion {
|
||||
aux := ssa.StaticAuxCall(callTargetLSym(callee, s.curfn.LSym), ACArgs, ACResults)
|
||||
call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux)
|
||||
call.AddArgs(callArgs...)
|
||||
} else {
|
||||
call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, ssa.StaticAuxCall(callTargetLSym(callee, s.curfn.LSym), ACArgs, ACResults), s.mem())
|
||||
}
|
||||
default:
|
||||
s.Fatalf("bad call type %v %v", n.Op(), n)
|
||||
}
|
||||
call.AddArgs(callArgs...)
|
||||
call.AuxInt = stksize // Call operations carry the argsize of the callee along with them
|
||||
}
|
||||
if testLateExpansion {
|
||||
s.prevCall = call
|
||||
s.vars[memVar] = s.newValue1I(ssa.OpSelectN, types.TypeMem, int64(len(ACResults)), call)
|
||||
} else {
|
||||
s.vars[memVar] = call
|
||||
}
|
||||
// Insert OVARLIVE nodes
|
||||
for _, name := range n.KeepAlive {
|
||||
s.stmt(ir.NewUnaryExpr(n.Pos(), ir.OVARLIVE, name))
|
||||
|
|
@ -5033,17 +4948,11 @@ func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool) *ssa.Val
|
|||
fp := res.Field(0)
|
||||
if returnResultAddr {
|
||||
pt := types.NewPtr(fp.Type)
|
||||
if testLateExpansion {
|
||||
return s.newValue1I(ssa.OpSelectNAddr, pt, 0, call)
|
||||
}
|
||||
return s.constOffPtrSP(pt, fp.Offset+base.Ctxt.FixedFrameSize())
|
||||
}
|
||||
|
||||
if testLateExpansion {
|
||||
return s.newValue1I(ssa.OpSelectN, fp.Type, 0, call)
|
||||
}
|
||||
return s.load(n.Type(), s.constOffPtrSP(types.NewPtr(fp.Type), fp.Offset+base.Ctxt.FixedFrameSize()))
|
||||
}
|
||||
|
||||
// maybeNilCheckClosure checks if a nil check of a closure is needed in some
|
||||
// architecture-dependent situations and, if so, emits the nil check.
|
||||
|
|
@ -5458,7 +5367,6 @@ func (s *state) rtcall(fn *obj.LSym, returns bool, results []*types.Type, args .
|
|||
s.prevCall = nil
|
||||
// Write args to the stack
|
||||
off := base.Ctxt.FixedFrameSize()
|
||||
testLateExpansion := ssa.LateCallExpansionEnabledWithin(s.f)
|
||||
var ACArgs []ssa.Param
|
||||
var ACResults []ssa.Param
|
||||
var callArgs []*ssa.Value
|
||||
|
|
@ -5468,12 +5376,7 @@ func (s *state) rtcall(fn *obj.LSym, returns bool, results []*types.Type, args .
|
|||
off = types.Rnd(off, t.Alignment())
|
||||
size := t.Size()
|
||||
ACArgs = append(ACArgs, ssa.Param{Type: t, Offset: int32(off)})
|
||||
if testLateExpansion {
|
||||
callArgs = append(callArgs, arg)
|
||||
} else {
|
||||
ptr := s.constOffPtrSP(t.PtrTo(), off)
|
||||
s.store(t, ptr, arg)
|
||||
}
|
||||
off += size
|
||||
}
|
||||
off = types.Rnd(off, int64(types.RegSize))
|
||||
|
|
@ -5489,15 +5392,10 @@ func (s *state) rtcall(fn *obj.LSym, returns bool, results []*types.Type, args .
|
|||
// Issue call
|
||||
var call *ssa.Value
|
||||
aux := ssa.StaticAuxCall(fn, ACArgs, ACResults)
|
||||
if testLateExpansion {
|
||||
callArgs = append(callArgs, s.mem())
|
||||
call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux)
|
||||
call.AddArgs(callArgs...)
|
||||
s.vars[memVar] = s.newValue1I(ssa.OpSelectN, types.TypeMem, int64(len(ACResults)), call)
|
||||
} else {
|
||||
call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, aux, s.mem())
|
||||
s.vars[memVar] = call
|
||||
}
|
||||
|
||||
if !returns {
|
||||
// Finish block
|
||||
|
|
@ -5513,7 +5411,6 @@ func (s *state) rtcall(fn *obj.LSym, returns bool, results []*types.Type, args .
|
|||
|
||||
// Load results
|
||||
res := make([]*ssa.Value, len(results))
|
||||
if testLateExpansion {
|
||||
for i, t := range results {
|
||||
off = types.Rnd(off, t.Alignment())
|
||||
if TypeOK(t) {
|
||||
|
|
@ -5524,14 +5421,6 @@ func (s *state) rtcall(fn *obj.LSym, returns bool, results []*types.Type, args .
|
|||
}
|
||||
off += t.Size()
|
||||
}
|
||||
} else {
|
||||
for i, t := range results {
|
||||
off = types.Rnd(off, t.Alignment())
|
||||
ptr := s.constOffPtrSP(types.NewPtr(t), off)
|
||||
res[i] = s.load(t, ptr)
|
||||
off += t.Size()
|
||||
}
|
||||
}
|
||||
off = types.Rnd(off, int64(types.PtrSize))
|
||||
|
||||
// Remember how much callee stack space we needed.
|
||||
|
|
@ -5650,20 +5539,14 @@ func (s *state) storeTypePtrs(t *types.Type, left, right *ssa.Value) {
|
|||
}
|
||||
}
|
||||
|
||||
// putArg evaluates n for the purpose of passing it as an argument to a function and returns the corresponding Param for the call.
|
||||
// If forLateExpandedCall is true, it returns the argument value to pass to the call operation.
|
||||
// If forLateExpandedCall is false, then the value is stored at the specified stack offset, and the returned value is nil.
|
||||
func (s *state) putArg(n ir.Node, t *types.Type, off int64, forLateExpandedCall bool) (ssa.Param, *ssa.Value) {
|
||||
// putArg evaluates n for the purpose of passing it as an argument to a function and returns the corresponding Param and value for the call.
|
||||
func (s *state) putArg(n ir.Node, t *types.Type, off int64) (ssa.Param, *ssa.Value) {
|
||||
var a *ssa.Value
|
||||
if forLateExpandedCall {
|
||||
if !TypeOK(t) {
|
||||
a = s.newValue2(ssa.OpDereference, t, s.addr(n), s.mem())
|
||||
} else {
|
||||
a = s.expr(n)
|
||||
}
|
||||
} else {
|
||||
s.storeArgWithBase(n, t, s.sp, off)
|
||||
}
|
||||
return ssa.Param{Type: t, Offset: int32(off)}, a
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@
|
|||
// -p n
|
||||
// the number of programs, such as build commands or
|
||||
// test binaries, that can be run in parallel.
|
||||
// The default is the number of CPUs available.
|
||||
// The default is GOMAXPROCS, normally the number of CPUs available.
|
||||
// -race
|
||||
// enable data race detection.
|
||||
// Supported only on linux/amd64, freebsd/amd64, darwin/amd64, windows/amd64,
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ var (
|
|||
BuildMSan bool // -msan flag
|
||||
BuildN bool // -n flag
|
||||
BuildO string // -o flag
|
||||
BuildP = runtime.NumCPU() // -p flag
|
||||
BuildP = runtime.GOMAXPROCS(0) // -p flag
|
||||
BuildPkgdir string // -pkgdir flag
|
||||
BuildRace bool // -race flag
|
||||
BuildToolexec []string // -toolexec flag
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ and test commands:
|
|||
-p n
|
||||
the number of programs, such as build commands or
|
||||
test binaries, that can be run in parallel.
|
||||
The default is the number of CPUs available.
|
||||
The default is GOMAXPROCS, normally the number of CPUs available.
|
||||
-race
|
||||
enable data race detection.
|
||||
Supported only on linux/amd64, freebsd/amd64, darwin/amd64, windows/amd64,
|
||||
|
|
|
|||
|
|
@ -239,16 +239,19 @@ CheckFlags:
|
|||
// - it has no successor packages to compile (usually package main)
|
||||
// - all paths through the build graph pass through it
|
||||
// - critical path scheduling says it is high priority
|
||||
// and in such a case, set c to runtime.NumCPU.
|
||||
// and in such a case, set c to runtime.GOMAXPROCS(0).
|
||||
// By default this is the same as runtime.NumCPU.
|
||||
// We do this now when p==1.
|
||||
// To limit parallelism, set GOMAXPROCS below numCPU; this may be useful
|
||||
// on a low-memory builder, or if a deterministic build order is required.
|
||||
c := runtime.GOMAXPROCS(0)
|
||||
if cfg.BuildP == 1 {
|
||||
// No process parallelism. Max out c.
|
||||
return runtime.NumCPU()
|
||||
// No process parallelism, do not cap compiler parallelism.
|
||||
return c
|
||||
}
|
||||
// Some process parallelism. Set c to min(4, numcpu).
|
||||
c := 4
|
||||
if ncpu := runtime.NumCPU(); ncpu < c {
|
||||
c = ncpu
|
||||
// Some process parallelism. Set c to min(4, maxprocs).
|
||||
if c > 4 {
|
||||
c = 4
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ package main
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
|
@ -130,7 +131,7 @@ import (
|
|||
|
||||
func main() {
|
||||
exe := os.Args[1]
|
||||
data, err := os.ReadFile(exe)
|
||||
data, err := ioutil.ReadFile(exe)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# embedded in a package, that is referenced by a Go assembly function.
|
||||
# See issue 33139.
|
||||
[!gc] skip
|
||||
[!exec:cc] skip
|
||||
[!cgo] skip
|
||||
|
||||
# External linking is not supported on linux/ppc64.
|
||||
# See: https://github.com/golang/go/issues/8912
|
||||
|
|
|
|||
|
|
@ -226,6 +226,12 @@ func main() {
|
|||
|
||||
func TestPIESize(t *testing.T) {
|
||||
testenv.MustHaveGoBuild(t)
|
||||
|
||||
// We don't want to test -linkmode=external if cgo is not supported.
|
||||
// On some systems -buildmode=pie implies -linkmode=external, so just
|
||||
// always skip the test if cgo is not supported.
|
||||
testenv.MustHaveCGO(t)
|
||||
|
||||
if !sys.BuildModeSupported(runtime.Compiler, "pie", runtime.GOOS, runtime.GOARCH) {
|
||||
t.Skip("-buildmode=pie not supported")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -165,13 +165,17 @@ func (d *deadcodePass) flood() {
|
|||
// R_USEIFACEMETHOD is a marker relocation that marks an interface
|
||||
// method as used.
|
||||
rs := r.Sym()
|
||||
if d.ldr.SymType(rs) != sym.SDYNIMPORT { // don't decode DYNIMPORT symbol (we'll mark all exported methods anyway)
|
||||
if d.ctxt.linkShared && (d.ldr.SymType(rs) == sym.SDYNIMPORT || d.ldr.SymType(rs) == sym.Sxxx) {
|
||||
// Don't decode symbol from shared library (we'll mark all exported methods anyway).
|
||||
// We check for both SDYNIMPORT and Sxxx because name-mangled symbols haven't
|
||||
// been resolved at this point.
|
||||
continue
|
||||
}
|
||||
m := d.decodeIfaceMethod(d.ldr, d.ctxt.Arch, rs, r.Add())
|
||||
if d.ctxt.Debugvlog > 1 {
|
||||
d.ctxt.Logf("reached iface method: %v\n", m)
|
||||
}
|
||||
d.ifaceMethod[m] = true
|
||||
}
|
||||
continue
|
||||
}
|
||||
rs := r.Sym()
|
||||
|
|
|
|||
|
|
@ -279,7 +279,7 @@ func findShlibSection(ctxt *Link, path string, addr uint64) *elf.Section {
|
|||
for _, shlib := range ctxt.Shlibs {
|
||||
if shlib.Path == path {
|
||||
for _, sect := range shlib.File.Sections[1:] { // skip the NULL section
|
||||
if sect.Addr <= addr && addr <= sect.Addr+sect.Size {
|
||||
if sect.Addr <= addr && addr < sect.Addr+sect.Size {
|
||||
return sect
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1997,15 +1997,6 @@ func buildCSRExtensions(template *CertificateRequest) ([]pkix.Extension, error)
|
|||
})
|
||||
}
|
||||
|
||||
if template.KeyUsage != 0 &&
|
||||
!oidInExtensions(oidExtensionKeyUsage, template.ExtraExtensions) {
|
||||
ext, err := marshalKeyUsage(template.KeyUsage)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret = append(ret, ext)
|
||||
}
|
||||
|
||||
return append(ret, template.ExtraExtensions...), nil
|
||||
}
|
||||
|
||||
|
|
@ -2371,7 +2362,6 @@ type CertificateRequest struct {
|
|||
Version int
|
||||
Signature []byte
|
||||
SignatureAlgorithm SignatureAlgorithm
|
||||
KeyUsage KeyUsage
|
||||
|
||||
PublicKeyAlgorithm PublicKeyAlgorithm
|
||||
PublicKey interface{}
|
||||
|
|
@ -2501,15 +2491,6 @@ func parseCSRExtensions(rawAttributes []asn1.RawValue) ([]pkix.Extension, error)
|
|||
// - EmailAddresses
|
||||
// - IPAddresses
|
||||
// - URIs
|
||||
// - KeyUsage
|
||||
// - ExtKeyUsage
|
||||
// - UnknownExtKeyUsage
|
||||
// - BasicConstraintsValid
|
||||
// - IsCA
|
||||
// - MaxPathLen
|
||||
// - MaxPathLenZero
|
||||
// - SubjectKeyId
|
||||
// - PolicyIdentifiers
|
||||
// - ExtraExtensions
|
||||
// - Attributes (deprecated)
|
||||
//
|
||||
|
|
@ -2734,11 +2715,6 @@ func parseCertificateRequest(in *certificateRequest) (*CertificateRequest, error
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case extension.Id.Equal(oidExtensionKeyUsage):
|
||||
out.KeyUsage, err = parseKeyUsageExtension(extension.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2977,7 +2977,6 @@ func TestCertificateRequestRoundtripFields(t *testing.T) {
|
|||
EmailAddresses: []string{"a@example.com", "b@example.com"},
|
||||
IPAddresses: []net.IP{net.IPv4(192, 0, 2, 0), net.IPv6loopback},
|
||||
URIs: []*url.URL{urlA, urlB},
|
||||
KeyUsage: KeyUsageCertSign,
|
||||
}
|
||||
out := marshalAndParseCSR(t, in)
|
||||
|
||||
|
|
@ -2995,7 +2994,4 @@ func TestCertificateRequestRoundtripFields(t *testing.T) {
|
|||
if !reflect.DeepEqual(in.URIs, out.URIs) {
|
||||
t.Fatalf("Unexpected URIs: got %v, want %v", out.URIs, in.URIs)
|
||||
}
|
||||
if in.KeyUsage != out.KeyUsage {
|
||||
t.Fatalf("Unexpected KeyUsage: got %v, want %v", out.KeyUsage, in.KeyUsage)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,18 +9,28 @@
|
|||
// files read from the package directory or subdirectories at compile time.
|
||||
//
|
||||
// For example, here are three ways to embed a file named hello.txt
|
||||
// and then print its contents at run time:
|
||||
// and then print its contents at run time.
|
||||
//
|
||||
// import "embed"
|
||||
// Embedding one file into a string:
|
||||
//
|
||||
// import _ "embed"
|
||||
//
|
||||
// //go:embed hello.txt
|
||||
// var s string
|
||||
// print(s)
|
||||
//
|
||||
// Embedding one file into a slice of bytes:
|
||||
//
|
||||
// import _ "embed"
|
||||
//
|
||||
// //go:embed hello.txt
|
||||
// var b []byte
|
||||
// print(string(b))
|
||||
//
|
||||
// Embedded one or more files into a file system:
|
||||
//
|
||||
// import "embed"
|
||||
//
|
||||
// //go:embed hello.txt
|
||||
// var f embed.FS
|
||||
// data, _ := f.ReadFile("hello.txt")
|
||||
|
|
@ -34,8 +44,8 @@
|
|||
// The directive must immediately precede a line containing the declaration of a single variable.
|
||||
// Only blank lines and ‘//’ line comments are permitted between the directive and the declaration.
|
||||
//
|
||||
// The variable must be of type string, []byte, or FS exactly. Named types or type aliases
|
||||
// derived from those types are not allowed.
|
||||
// The type of the variable must be a string type, or a slice of a byte type,
|
||||
// or FS (or an alias of FS).
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
|
|
@ -70,8 +80,8 @@
|
|||
//
|
||||
// The //go:embed directive can be used with both exported and unexported variables,
|
||||
// depending on whether the package wants to make the data available to other packages.
|
||||
// Similarly, it can be used with both global and function-local variables,
|
||||
// depending on what is more convenient in context.
|
||||
// It can only be used with global variables at package scope,
|
||||
// not with local variables.
|
||||
//
|
||||
// Patterns must not match files outside the package's module, such as ‘.git/*’ or symbolic links.
|
||||
// Matches for empty directories are ignored. After that, each pattern in a //go:embed line
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ package math
|
|||
//
|
||||
// One may easily use induction to prove (4) and (5).
|
||||
// Note. Since the left hand side of (3) contain only i+2 bits,
|
||||
// it does not necessary to do a full (53-bit) comparison
|
||||
// it is not necessary to do a full (53-bit) comparison
|
||||
// in (3).
|
||||
// 3. Final rounding
|
||||
// After generating the 53 bits result, we compute one more bit.
|
||||
|
|
|
|||
|
|
@ -171,12 +171,9 @@ func (c *child) serve() {
|
|||
defer c.cleanUp()
|
||||
var rec record
|
||||
for {
|
||||
c.conn.mutex.Lock()
|
||||
if err := rec.read(c.conn.rwc); err != nil {
|
||||
c.conn.mutex.Unlock()
|
||||
return
|
||||
}
|
||||
c.conn.mutex.Unlock()
|
||||
if err := c.handleRecord(&rec); err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -221,7 +221,11 @@ var cleanUpTests = []struct {
|
|||
}
|
||||
|
||||
type nopWriteCloser struct {
|
||||
io.ReadWriter
|
||||
io.Reader
|
||||
}
|
||||
|
||||
func (nopWriteCloser) Write(buf []byte) (int, error) {
|
||||
return len(buf), nil
|
||||
}
|
||||
|
||||
func (nopWriteCloser) Close() error {
|
||||
|
|
@ -235,7 +239,7 @@ func TestChildServeCleansUp(t *testing.T) {
|
|||
for _, tt := range cleanUpTests {
|
||||
input := make([]byte, len(tt.input))
|
||||
copy(input, tt.input)
|
||||
rc := nopWriteCloser{bytes.NewBuffer(input)}
|
||||
rc := nopWriteCloser{bytes.NewReader(input)}
|
||||
done := make(chan bool)
|
||||
c := newChild(rc, http.HandlerFunc(func(
|
||||
w http.ResponseWriter,
|
||||
|
|
@ -325,7 +329,7 @@ func TestChildServeReadsEnvVars(t *testing.T) {
|
|||
for _, tt := range envVarTests {
|
||||
input := make([]byte, len(tt.input))
|
||||
copy(input, tt.input)
|
||||
rc := nopWriteCloser{bytes.NewBuffer(input)}
|
||||
rc := nopWriteCloser{bytes.NewReader(input)}
|
||||
done := make(chan bool)
|
||||
c := newChild(rc, http.HandlerFunc(func(
|
||||
w http.ResponseWriter,
|
||||
|
|
@ -375,7 +379,7 @@ func TestResponseWriterSniffsContentType(t *testing.T) {
|
|||
t.Run(tt.name, func(t *testing.T) {
|
||||
input := make([]byte, len(streamFullRequestStdin))
|
||||
copy(input, streamFullRequestStdin)
|
||||
rc := nopWriteCloser{bytes.NewBuffer(input)}
|
||||
rc := nopWriteCloser{bytes.NewReader(input)}
|
||||
done := make(chan bool)
|
||||
var resp *response
|
||||
c := newChild(rc, http.HandlerFunc(func(
|
||||
|
|
|
|||
|
|
@ -66,6 +66,10 @@ type file struct {
|
|||
// making it invalid; see runtime.SetFinalizer for more information on when
|
||||
// a finalizer might be run. On Unix systems this will cause the SetDeadline
|
||||
// methods to stop working.
|
||||
// Because file descriptors can be reused, the returned file descriptor may
|
||||
// only be closed through the Close method of f, or by its finalizer during
|
||||
// garbage collection. Otherwise, during garbage collection the finalizer
|
||||
// may close an unrelated file descriptor with the same (reused) number.
|
||||
//
|
||||
// As an alternative, see the f.SyscallConn method.
|
||||
func (f *File) Fd() uintptr {
|
||||
|
|
@ -90,6 +94,10 @@ func (f *File) Fd() uintptr {
|
|||
// descriptor. On Unix systems, if the file descriptor is in
|
||||
// non-blocking mode, NewFile will attempt to return a pollable File
|
||||
// (one for which the SetDeadline methods work).
|
||||
//
|
||||
// After passing it to NewFile, fd may become invalid under the same
|
||||
// conditions described in the comments of the Fd method, and the same
|
||||
// constraints apply.
|
||||
func NewFile(fd uintptr, name string) *File {
|
||||
kind := kindNewFile
|
||||
if nb, err := unix.IsNonblock(int(fd)); err == nil && nb {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ func nextRandom() string {
|
|||
// opens the file for reading and writing, and returns the resulting file.
|
||||
// The filename is generated by taking pattern and adding a random string to the end.
|
||||
// If pattern includes a "*", the random string replaces the last "*".
|
||||
// If dir is the empty string, TempFile uses the default directory for temporary files, as returned by TempDir.
|
||||
// If dir is the empty string, CreateTemp uses the default directory for temporary files, as returned by TempDir.
|
||||
// Multiple programs or goroutines calling CreateTemp simultaneously will not choose the same file.
|
||||
// The caller can use the file's Name method to find the pathname of the file.
|
||||
// It is the caller's responsibility to remove the file when it is no longer needed.
|
||||
|
|
@ -71,7 +71,7 @@ func prefixAndSuffix(pattern string) (prefix, suffix string, err error) {
|
|||
// and returns the pathname of the new directory.
|
||||
// The new directory's name is generated by adding a random string to the end of pattern.
|
||||
// If pattern includes a "*", the random string replaces the last "*" instead.
|
||||
// If dir is the empty string, TempFile uses the default directory for temporary files, as returned by TempDir.
|
||||
// If dir is the empty string, MkdirTemp uses the default directory for temporary files, as returned by TempDir.
|
||||
// Multiple programs or goroutines calling MkdirTemp simultaneously will not choose the same directory.
|
||||
// It is the caller's responsibility to remove the directory when it is no longer needed.
|
||||
func MkdirTemp(dir, pattern string) (string, error) {
|
||||
|
|
|
|||
|
|
@ -294,6 +294,18 @@ func TestRecursivePanic4(t *testing.T) {
|
|||
|
||||
}
|
||||
|
||||
func TestRecursivePanic5(t *testing.T) {
|
||||
output := runTestProg(t, "testprog", "RecursivePanic5")
|
||||
want := `first panic
|
||||
second panic
|
||||
panic: third panic
|
||||
`
|
||||
if !strings.HasPrefix(output, want) {
|
||||
t.Fatalf("output does not start with %q:\n%s", want, output)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestGoexitCrash(t *testing.T) {
|
||||
// External linking brings in cgo, causing deadlock detection not working.
|
||||
testenv.MustInternalLink(t)
|
||||
|
|
|
|||
|
|
@ -410,3 +410,31 @@ func rec1(max int) {
|
|||
rec1(max - 1)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIssue43921(t *testing.T) {
|
||||
defer func() {
|
||||
expect(t, 1, recover())
|
||||
}()
|
||||
func() {
|
||||
// Prevent open-coded defers
|
||||
for {
|
||||
defer func() {}()
|
||||
break
|
||||
}
|
||||
|
||||
defer func() {
|
||||
defer func() {
|
||||
expect(t, 4, recover())
|
||||
}()
|
||||
panic(4)
|
||||
}()
|
||||
panic(1)
|
||||
|
||||
}()
|
||||
}
|
||||
|
||||
func expect(t *testing.T, n int, err interface{}) {
|
||||
if n != err {
|
||||
t.Fatalf("have %v, want %v", err, n)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,11 @@ const (
|
|||
|
||||
_PTHREAD_CREATE_DETACHED = 0x1
|
||||
|
||||
_F_SETFD = 0x2
|
||||
_F_GETFL = 0x3
|
||||
_F_SETFL = 0x4
|
||||
_FD_CLOEXEC = 0x1
|
||||
|
||||
_SIGHUP = 0x1
|
||||
_SIGINT = 0x2
|
||||
_SIGQUIT = 0x3
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
// NOTE: Windows externalthreadhandler expects memclr to preserve DX.
|
||||
|
||||
// See memclrNoHeapPointers Go doc for important implementation constraints.
|
||||
|
||||
// func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
|
||||
TEXT runtime·memclrNoHeapPointers(SB), NOSPLIT, $0-8
|
||||
MOVL ptr+0(FP), DI
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
// NOTE: Windows externalthreadhandler expects memclr to preserve DX.
|
||||
|
||||
// See memclrNoHeapPointers Go doc for important implementation constraints.
|
||||
|
||||
// func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
|
||||
TEXT runtime·memclrNoHeapPointers(SB), NOSPLIT, $0-16
|
||||
MOVQ ptr+0(FP), DI
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@
|
|||
#define N R12
|
||||
#define TMP R12 /* N and TMP don't overlap */
|
||||
|
||||
// See memclrNoHeapPointers Go doc for important implementation constraints.
|
||||
|
||||
// func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
|
||||
TEXT runtime·memclrNoHeapPointers(SB),NOSPLIT,$0-8
|
||||
MOVW ptr+0(FP), TO
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#include "textflag.h"
|
||||
|
||||
// See memclrNoHeapPointers Go doc for important implementation constraints.
|
||||
|
||||
// func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
|
||||
TEXT runtime·memclrNoHeapPointers(SB),NOSPLIT,$0-16
|
||||
MOVD ptr+0(FP), R0
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@
|
|||
#include "go_asm.h"
|
||||
#include "textflag.h"
|
||||
|
||||
// See memclrNoHeapPointers Go doc for important implementation constraints.
|
||||
|
||||
// func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
|
||||
TEXT runtime·memclrNoHeapPointers(SB),NOSPLIT,$0-16
|
||||
MOVV ptr+0(FP), R1
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
#define MOVWLO MOVWL
|
||||
#endif
|
||||
|
||||
// See memclrNoHeapPointers Go doc for important implementation constraints.
|
||||
|
||||
// func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
|
||||
TEXT runtime·memclrNoHeapPointers(SB),NOSPLIT,$0-8
|
||||
MOVW n+4(FP), R2
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#include "textflag.h"
|
||||
|
||||
// See memclrNoHeapPointers Go doc for important implementation constraints.
|
||||
|
||||
// func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
|
||||
TEXT runtime·memclrNoHeapPointers(SB), NOSPLIT, $0-8
|
||||
MOVL ptr+0(FP), DI
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#include "textflag.h"
|
||||
|
||||
// See memclrNoHeapPointers Go doc for important implementation constraints.
|
||||
|
||||
// func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
|
||||
TEXT runtime·memclrNoHeapPointers(SB),NOSPLIT,$0-16
|
||||
MOVQ ptr+0(FP), DI
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include "textflag.h"
|
||||
|
||||
// See memclrNoHeapPointers Go doc for important implementation constraints.
|
||||
|
||||
// func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
|
||||
TEXT runtime·memclrNoHeapPointers(SB), NOSPLIT|NOFRAME, $0-16
|
||||
MOVD ptr+0(FP), R3
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#include "textflag.h"
|
||||
|
||||
// See memclrNoHeapPointers Go doc for important implementation constraints.
|
||||
|
||||
// void runtime·memclrNoHeapPointers(void*, uintptr)
|
||||
TEXT runtime·memclrNoHeapPointers(SB),NOSPLIT,$0-16
|
||||
MOV ptr+0(FP), T1
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#include "textflag.h"
|
||||
|
||||
// See memclrNoHeapPointers Go doc for important implementation constraints.
|
||||
|
||||
// func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
|
||||
TEXT runtime·memclrNoHeapPointers(SB),NOSPLIT|NOFRAME,$0-16
|
||||
MOVD ptr+0(FP), R4
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#include "textflag.h"
|
||||
|
||||
// See memclrNoHeapPointers Go doc for important implementation constraints.
|
||||
|
||||
// func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
|
||||
TEXT runtime·memclrNoHeapPointers(SB), NOSPLIT, $0-16
|
||||
MOVD ptr+0(FP), R0
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build openbsd,!amd64
|
||||
// +build openbsd,!amd64,!arm64
|
||||
|
||||
package runtime
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build openbsd,!amd64
|
||||
// +build openbsd,!amd64,!arm64
|
||||
|
||||
package runtime
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ const (
|
|||
//go:cgo_import_dynamic runtime._SetThreadPriority SetThreadPriority%2 "kernel32.dll"
|
||||
//go:cgo_import_dynamic runtime._SetUnhandledExceptionFilter SetUnhandledExceptionFilter%1 "kernel32.dll"
|
||||
//go:cgo_import_dynamic runtime._SetWaitableTimer SetWaitableTimer%6 "kernel32.dll"
|
||||
//go:cgo_import_dynamic runtime._Sleep Sleep%1 "kernel32.dll"
|
||||
//go:cgo_import_dynamic runtime._SuspendThread SuspendThread%1 "kernel32.dll"
|
||||
//go:cgo_import_dynamic runtime._SwitchToThread SwitchToThread%0 "kernel32.dll"
|
||||
//go:cgo_import_dynamic runtime._TlsAlloc TlsAlloc%0 "kernel32.dll"
|
||||
|
|
@ -97,6 +98,7 @@ var (
|
|||
_SetThreadPriority,
|
||||
_SetUnhandledExceptionFilter,
|
||||
_SetWaitableTimer,
|
||||
_Sleep,
|
||||
_SuspendThread,
|
||||
_SwitchToThread,
|
||||
_TlsAlloc,
|
||||
|
|
@ -1094,6 +1096,11 @@ func ctrlhandler1(_type uint32) uint32 {
|
|||
}
|
||||
|
||||
if sigsend(s) {
|
||||
if s == _SIGTERM {
|
||||
// Windows terminates the process after this handler returns.
|
||||
// Block indefinitely to give signal handlers a chance to clean up.
|
||||
stdcall1(_Sleep, uintptr(_INFINITE))
|
||||
}
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
|
|
|
|||
|
|
@ -1000,7 +1000,6 @@ func gopanic(e interface{}) {
|
|||
}
|
||||
atomic.Xadd(&runningPanicDefers, -1)
|
||||
|
||||
if done {
|
||||
// Remove any remaining non-started, open-coded
|
||||
// defer entries after a recover, since the
|
||||
// corresponding defers will be executed normally
|
||||
|
|
@ -1009,8 +1008,14 @@ func gopanic(e interface{}) {
|
|||
// the associated stack frame.
|
||||
d := gp._defer
|
||||
var prev *_defer
|
||||
if !done {
|
||||
// Skip our current frame, if not done. It is
|
||||
// needed to complete any remaining defers in
|
||||
// deferreturn()
|
||||
prev = d
|
||||
d = d.link
|
||||
}
|
||||
for d != nil {
|
||||
if d.openDefer {
|
||||
if d.started {
|
||||
// This defer is started but we
|
||||
// are in the middle of a
|
||||
|
|
@ -1019,6 +1024,7 @@ func gopanic(e interface{}) {
|
|||
// further defer entries
|
||||
break
|
||||
}
|
||||
if d.openDefer {
|
||||
if prev == nil {
|
||||
gp._defer = d.link
|
||||
} else {
|
||||
|
|
@ -1032,7 +1038,6 @@ func gopanic(e interface{}) {
|
|||
d = d.link
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gp._panic = p.link
|
||||
// Aborted panics are marked but remain on the g.panic list.
|
||||
|
|
|
|||
|
|
@ -1213,7 +1213,7 @@ func usesLibcall() bool {
|
|||
case "aix", "darwin", "illumos", "ios", "solaris", "windows":
|
||||
return true
|
||||
case "openbsd":
|
||||
return GOARCH == "amd64"
|
||||
return GOARCH == "amd64" || GOARCH == "arm64"
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import (
|
|||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"testing"
|
||||
|
|
@ -79,6 +80,69 @@ func sendCtrlBreak(pid int) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// TestCtrlHandler tests that Go can gracefully handle closing the console window.
|
||||
// See https://golang.org/issues/41884.
|
||||
func TestCtrlHandler(t *testing.T) {
|
||||
testenv.MustHaveGoBuild(t)
|
||||
t.Parallel()
|
||||
|
||||
// build go program
|
||||
exe := filepath.Join(t.TempDir(), "test.exe")
|
||||
cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", exe, "testdata/testwinsignal/main.go")
|
||||
out, err := testenv.CleanCmdEnv(cmd).CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("failed to build go exe: %v\n%s", err, out)
|
||||
}
|
||||
|
||||
// run test program
|
||||
cmd = exec.Command(exe)
|
||||
var stderr bytes.Buffer
|
||||
cmd.Stderr = &stderr
|
||||
outPipe, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create stdout pipe: %v", err)
|
||||
}
|
||||
outReader := bufio.NewReader(outPipe)
|
||||
|
||||
// in a new command window
|
||||
const _CREATE_NEW_CONSOLE = 0x00000010
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||
CreationFlags: _CREATE_NEW_CONSOLE,
|
||||
HideWindow: true,
|
||||
}
|
||||
if err := cmd.Start(); err != nil {
|
||||
t.Fatalf("Start failed: %v", err)
|
||||
}
|
||||
defer func() {
|
||||
cmd.Process.Kill()
|
||||
cmd.Wait()
|
||||
}()
|
||||
|
||||
// wait for child to be ready to receive signals
|
||||
if line, err := outReader.ReadString('\n'); err != nil {
|
||||
t.Fatalf("could not read stdout: %v", err)
|
||||
} else if strings.TrimSpace(line) != "ready" {
|
||||
t.Fatalf("unexpected message: %s", line)
|
||||
}
|
||||
|
||||
// gracefully kill pid, this closes the command window
|
||||
if err := exec.Command("taskkill.exe", "/pid", strconv.Itoa(cmd.Process.Pid)).Run(); err != nil {
|
||||
t.Fatalf("failed to kill: %v", err)
|
||||
}
|
||||
|
||||
// check child received, handled SIGTERM
|
||||
if line, err := outReader.ReadString('\n'); err != nil {
|
||||
t.Fatalf("could not read stdout: %v", err)
|
||||
} else if expected, got := syscall.SIGTERM.String(), strings.TrimSpace(line); expected != got {
|
||||
t.Fatalf("Expected '%s' got: %s", expected, got)
|
||||
}
|
||||
|
||||
// check child exited gracefully, did not timeout
|
||||
if err := cmd.Wait(); err != nil {
|
||||
t.Fatalf("Program exited with error: %v\n%s", err, &stderr)
|
||||
}
|
||||
}
|
||||
|
||||
// TestLibraryCtrlHandler tests that Go DLL allows calling program to handle console control events.
|
||||
// See https://golang.org/issues/35965.
|
||||
func TestLibraryCtrlHandler(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -73,7 +73,15 @@ func badsystemstack() {
|
|||
// *ptr is uninitialized memory (e.g., memory that's being reused
|
||||
// for a new allocation) and hence contains only "junk".
|
||||
//
|
||||
// memclrNoHeapPointers ensures that if ptr is pointer-aligned, and n
|
||||
// is a multiple of the pointer size, then any pointer-aligned,
|
||||
// pointer-sized portion is cleared atomically. Despite the function
|
||||
// name, this is necessary because this function is the underlying
|
||||
// implementation of typedmemclr and memclrHasPointers. See the doc of
|
||||
// memmove for more details.
|
||||
//
|
||||
// The (CPU-specific) implementations of this function are in memclr_*.s.
|
||||
//
|
||||
//go:noescape
|
||||
func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build openbsd,amd64
|
||||
// +build openbsd,amd64 openbsd,arm64
|
||||
|
||||
package runtime
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build openbsd,amd64
|
||||
// +build openbsd,amd64 openbsd,arm64
|
||||
|
||||
package runtime
|
||||
|
||||
|
|
|
|||
113
src/runtime/sys_openbsd3.go
Normal file
113
src/runtime/sys_openbsd3.go
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
// Copyright 2020 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.
|
||||
|
||||
// +build openbsd,amd64 openbsd,arm64
|
||||
|
||||
package runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// The X versions of syscall expect the libc call to return a 64-bit result.
|
||||
// Otherwise (the non-X version) expects a 32-bit result.
|
||||
// This distinction is required because an error is indicated by returning -1,
|
||||
// and we need to know whether to check 32 or 64 bits of the result.
|
||||
// (Some libc functions that return 32 bits put junk in the upper 32 bits of AX.)
|
||||
|
||||
//go:linkname syscall_syscall syscall.syscall
|
||||
//go:nosplit
|
||||
//go:cgo_unsafe_args
|
||||
func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
|
||||
entersyscall()
|
||||
libcCall(unsafe.Pointer(funcPC(syscall)), unsafe.Pointer(&fn))
|
||||
exitsyscall()
|
||||
return
|
||||
}
|
||||
func syscall()
|
||||
|
||||
//go:linkname syscall_syscallX syscall.syscallX
|
||||
//go:nosplit
|
||||
//go:cgo_unsafe_args
|
||||
func syscall_syscallX(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
|
||||
entersyscall()
|
||||
libcCall(unsafe.Pointer(funcPC(syscallX)), unsafe.Pointer(&fn))
|
||||
exitsyscall()
|
||||
return
|
||||
}
|
||||
func syscallX()
|
||||
|
||||
//go:linkname syscall_syscall6 syscall.syscall6
|
||||
//go:nosplit
|
||||
//go:cgo_unsafe_args
|
||||
func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
|
||||
entersyscall()
|
||||
libcCall(unsafe.Pointer(funcPC(syscall6)), unsafe.Pointer(&fn))
|
||||
exitsyscall()
|
||||
return
|
||||
}
|
||||
func syscall6()
|
||||
|
||||
//go:linkname syscall_syscall6X syscall.syscall6X
|
||||
//go:nosplit
|
||||
//go:cgo_unsafe_args
|
||||
func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
|
||||
entersyscall()
|
||||
libcCall(unsafe.Pointer(funcPC(syscall6X)), unsafe.Pointer(&fn))
|
||||
exitsyscall()
|
||||
return
|
||||
}
|
||||
func syscall6X()
|
||||
|
||||
//go:linkname syscall_syscall10 syscall.syscall10
|
||||
//go:nosplit
|
||||
//go:cgo_unsafe_args
|
||||
func syscall_syscall10(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 uintptr) (r1, r2, err uintptr) {
|
||||
entersyscall()
|
||||
libcCall(unsafe.Pointer(funcPC(syscall10)), unsafe.Pointer(&fn))
|
||||
exitsyscall()
|
||||
return
|
||||
}
|
||||
func syscall10()
|
||||
|
||||
//go:linkname syscall_syscall10X syscall.syscall10X
|
||||
//go:nosplit
|
||||
//go:cgo_unsafe_args
|
||||
func syscall_syscall10X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 uintptr) (r1, r2, err uintptr) {
|
||||
entersyscall()
|
||||
libcCall(unsafe.Pointer(funcPC(syscall10X)), unsafe.Pointer(&fn))
|
||||
exitsyscall()
|
||||
return
|
||||
}
|
||||
func syscall10X()
|
||||
|
||||
//go:linkname syscall_rawSyscall syscall.rawSyscall
|
||||
//go:nosplit
|
||||
//go:cgo_unsafe_args
|
||||
func syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
|
||||
libcCall(unsafe.Pointer(funcPC(syscall)), unsafe.Pointer(&fn))
|
||||
return
|
||||
}
|
||||
|
||||
//go:linkname syscall_rawSyscall6 syscall.rawSyscall6
|
||||
//go:nosplit
|
||||
//go:cgo_unsafe_args
|
||||
func syscall_rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
|
||||
libcCall(unsafe.Pointer(funcPC(syscall6)), unsafe.Pointer(&fn))
|
||||
return
|
||||
}
|
||||
|
||||
//go:linkname syscall_rawSyscall6X syscall.rawSyscall6X
|
||||
//go:nosplit
|
||||
//go:cgo_unsafe_args
|
||||
func syscall_rawSyscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
|
||||
libcCall(unsafe.Pointer(funcPC(syscall6X)), unsafe.Pointer(&fn))
|
||||
return
|
||||
}
|
||||
|
||||
//go:linkname syscall_rawSyscall10X syscall.rawSyscall10X
|
||||
//go:nosplit
|
||||
//go:cgo_unsafe_args
|
||||
func syscall_rawSyscall10X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 uintptr) (r1, r2, err uintptr) {
|
||||
libcCall(unsafe.Pointer(funcPC(syscall10X)), unsafe.Pointer(&fn))
|
||||
return
|
||||
}
|
||||
|
|
@ -445,3 +445,344 @@ TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0
|
|||
MOVL $0xf1, 0xf1 // crash
|
||||
POPQ BP
|
||||
RET
|
||||
|
||||
// syscall calls a function in libc on behalf of the syscall package.
|
||||
// syscall takes a pointer to a struct like:
|
||||
// struct {
|
||||
// fn uintptr
|
||||
// a1 uintptr
|
||||
// a2 uintptr
|
||||
// a3 uintptr
|
||||
// r1 uintptr
|
||||
// r2 uintptr
|
||||
// err uintptr
|
||||
// }
|
||||
// syscall must be called on the g0 stack with the
|
||||
// C calling convention (use libcCall).
|
||||
//
|
||||
// syscall expects a 32-bit result and tests for 32-bit -1
|
||||
// to decide there was an error.
|
||||
TEXT runtime·syscall(SB),NOSPLIT,$0
|
||||
PUSHQ BP
|
||||
MOVQ SP, BP
|
||||
SUBQ $16, SP
|
||||
MOVQ (0*8)(DI), CX // fn
|
||||
MOVQ (2*8)(DI), SI // a2
|
||||
MOVQ (3*8)(DI), DX // a3
|
||||
MOVQ DI, (SP)
|
||||
MOVQ (1*8)(DI), DI // a1
|
||||
XORL AX, AX // vararg: say "no float args"
|
||||
|
||||
CALL CX
|
||||
|
||||
MOVQ (SP), DI
|
||||
MOVQ AX, (4*8)(DI) // r1
|
||||
MOVQ DX, (5*8)(DI) // r2
|
||||
|
||||
// Standard libc functions return -1 on error
|
||||
// and set errno.
|
||||
CMPL AX, $-1 // Note: high 32 bits are junk
|
||||
JNE ok
|
||||
|
||||
// Get error code from libc.
|
||||
CALL libc_errno(SB)
|
||||
MOVLQSX (AX), AX
|
||||
MOVQ (SP), DI
|
||||
MOVQ AX, (6*8)(DI) // err
|
||||
|
||||
ok:
|
||||
XORL AX, AX // no error (it's ignored anyway)
|
||||
MOVQ BP, SP
|
||||
POPQ BP
|
||||
RET
|
||||
|
||||
// syscallX calls a function in libc on behalf of the syscall package.
|
||||
// syscallX takes a pointer to a struct like:
|
||||
// struct {
|
||||
// fn uintptr
|
||||
// a1 uintptr
|
||||
// a2 uintptr
|
||||
// a3 uintptr
|
||||
// r1 uintptr
|
||||
// r2 uintptr
|
||||
// err uintptr
|
||||
// }
|
||||
// syscallX must be called on the g0 stack with the
|
||||
// C calling convention (use libcCall).
|
||||
//
|
||||
// syscallX is like syscall but expects a 64-bit result
|
||||
// and tests for 64-bit -1 to decide there was an error.
|
||||
TEXT runtime·syscallX(SB),NOSPLIT,$0
|
||||
PUSHQ BP
|
||||
MOVQ SP, BP
|
||||
SUBQ $16, SP
|
||||
MOVQ (0*8)(DI), CX // fn
|
||||
MOVQ (2*8)(DI), SI // a2
|
||||
MOVQ (3*8)(DI), DX // a3
|
||||
MOVQ DI, (SP)
|
||||
MOVQ (1*8)(DI), DI // a1
|
||||
XORL AX, AX // vararg: say "no float args"
|
||||
|
||||
CALL CX
|
||||
|
||||
MOVQ (SP), DI
|
||||
MOVQ AX, (4*8)(DI) // r1
|
||||
MOVQ DX, (5*8)(DI) // r2
|
||||
|
||||
// Standard libc functions return -1 on error
|
||||
// and set errno.
|
||||
CMPQ AX, $-1
|
||||
JNE ok
|
||||
|
||||
// Get error code from libc.
|
||||
CALL libc_errno(SB)
|
||||
MOVLQSX (AX), AX
|
||||
MOVQ (SP), DI
|
||||
MOVQ AX, (6*8)(DI) // err
|
||||
|
||||
ok:
|
||||
XORL AX, AX // no error (it's ignored anyway)
|
||||
MOVQ BP, SP
|
||||
POPQ BP
|
||||
RET
|
||||
|
||||
// syscall6 calls a function in libc on behalf of the syscall package.
|
||||
// syscall6 takes a pointer to a struct like:
|
||||
// struct {
|
||||
// fn uintptr
|
||||
// a1 uintptr
|
||||
// a2 uintptr
|
||||
// a3 uintptr
|
||||
// a4 uintptr
|
||||
// a5 uintptr
|
||||
// a6 uintptr
|
||||
// r1 uintptr
|
||||
// r2 uintptr
|
||||
// err uintptr
|
||||
// }
|
||||
// syscall6 must be called on the g0 stack with the
|
||||
// C calling convention (use libcCall).
|
||||
//
|
||||
// syscall6 expects a 32-bit result and tests for 32-bit -1
|
||||
// to decide there was an error.
|
||||
TEXT runtime·syscall6(SB),NOSPLIT,$0
|
||||
PUSHQ BP
|
||||
MOVQ SP, BP
|
||||
SUBQ $16, SP
|
||||
MOVQ (0*8)(DI), R11// fn
|
||||
MOVQ (2*8)(DI), SI // a2
|
||||
MOVQ (3*8)(DI), DX // a3
|
||||
MOVQ (4*8)(DI), CX // a4
|
||||
MOVQ (5*8)(DI), R8 // a5
|
||||
MOVQ (6*8)(DI), R9 // a6
|
||||
MOVQ DI, (SP)
|
||||
MOVQ (1*8)(DI), DI // a1
|
||||
XORL AX, AX // vararg: say "no float args"
|
||||
|
||||
CALL R11
|
||||
|
||||
MOVQ (SP), DI
|
||||
MOVQ AX, (7*8)(DI) // r1
|
||||
MOVQ DX, (8*8)(DI) // r2
|
||||
|
||||
CMPL AX, $-1
|
||||
JNE ok
|
||||
|
||||
CALL libc_errno(SB)
|
||||
MOVLQSX (AX), AX
|
||||
MOVQ (SP), DI
|
||||
MOVQ AX, (9*8)(DI) // err
|
||||
|
||||
ok:
|
||||
XORL AX, AX // no error (it's ignored anyway)
|
||||
MOVQ BP, SP
|
||||
POPQ BP
|
||||
RET
|
||||
|
||||
// syscall6X calls a function in libc on behalf of the syscall package.
|
||||
// syscall6X takes a pointer to a struct like:
|
||||
// struct {
|
||||
// fn uintptr
|
||||
// a1 uintptr
|
||||
// a2 uintptr
|
||||
// a3 uintptr
|
||||
// a4 uintptr
|
||||
// a5 uintptr
|
||||
// a6 uintptr
|
||||
// r1 uintptr
|
||||
// r2 uintptr
|
||||
// err uintptr
|
||||
// }
|
||||
// syscall6X must be called on the g0 stack with the
|
||||
// C calling convention (use libcCall).
|
||||
//
|
||||
// syscall6X is like syscall6 but expects a 64-bit result
|
||||
// and tests for 64-bit -1 to decide there was an error.
|
||||
TEXT runtime·syscall6X(SB),NOSPLIT,$0
|
||||
PUSHQ BP
|
||||
MOVQ SP, BP
|
||||
SUBQ $16, SP
|
||||
MOVQ (0*8)(DI), R11// fn
|
||||
MOVQ (2*8)(DI), SI // a2
|
||||
MOVQ (3*8)(DI), DX // a3
|
||||
MOVQ (4*8)(DI), CX // a4
|
||||
MOVQ (5*8)(DI), R8 // a5
|
||||
MOVQ (6*8)(DI), R9 // a6
|
||||
MOVQ DI, (SP)
|
||||
MOVQ (1*8)(DI), DI // a1
|
||||
XORL AX, AX // vararg: say "no float args"
|
||||
|
||||
CALL R11
|
||||
|
||||
MOVQ (SP), DI
|
||||
MOVQ AX, (7*8)(DI) // r1
|
||||
MOVQ DX, (8*8)(DI) // r2
|
||||
|
||||
CMPQ AX, $-1
|
||||
JNE ok
|
||||
|
||||
CALL libc_errno(SB)
|
||||
MOVLQSX (AX), AX
|
||||
MOVQ (SP), DI
|
||||
MOVQ AX, (9*8)(DI) // err
|
||||
|
||||
ok:
|
||||
XORL AX, AX // no error (it's ignored anyway)
|
||||
MOVQ BP, SP
|
||||
POPQ BP
|
||||
RET
|
||||
|
||||
// syscall10 calls a function in libc on behalf of the syscall package.
|
||||
// syscall10 takes a pointer to a struct like:
|
||||
// struct {
|
||||
// fn uintptr
|
||||
// a1 uintptr
|
||||
// a2 uintptr
|
||||
// a3 uintptr
|
||||
// a4 uintptr
|
||||
// a5 uintptr
|
||||
// a6 uintptr
|
||||
// a7 uintptr
|
||||
// a8 uintptr
|
||||
// a9 uintptr
|
||||
// a10 uintptr
|
||||
// r1 uintptr
|
||||
// r2 uintptr
|
||||
// err uintptr
|
||||
// }
|
||||
// syscall10 must be called on the g0 stack with the
|
||||
// C calling convention (use libcCall).
|
||||
TEXT runtime·syscall10(SB),NOSPLIT,$0
|
||||
PUSHQ BP
|
||||
MOVQ SP, BP
|
||||
SUBQ $48, SP
|
||||
|
||||
// Arguments a1 to a6 get passed in registers, with a7 onwards being
|
||||
// passed via the stack per the x86-64 System V ABI
|
||||
// (https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf).
|
||||
MOVQ (7*8)(DI), R10 // a7
|
||||
MOVQ (8*8)(DI), R11 // a8
|
||||
MOVQ (9*8)(DI), R12 // a9
|
||||
MOVQ (10*8)(DI), R13 // a10
|
||||
MOVQ R10, (0*8)(SP) // a7
|
||||
MOVQ R11, (1*8)(SP) // a8
|
||||
MOVQ R12, (2*8)(SP) // a9
|
||||
MOVQ R13, (3*8)(SP) // a10
|
||||
MOVQ (0*8)(DI), R11 // fn
|
||||
MOVQ (2*8)(DI), SI // a2
|
||||
MOVQ (3*8)(DI), DX // a3
|
||||
MOVQ (4*8)(DI), CX // a4
|
||||
MOVQ (5*8)(DI), R8 // a5
|
||||
MOVQ (6*8)(DI), R9 // a6
|
||||
MOVQ DI, (4*8)(SP)
|
||||
MOVQ (1*8)(DI), DI // a1
|
||||
XORL AX, AX // vararg: say "no float args"
|
||||
|
||||
CALL R11
|
||||
|
||||
MOVQ (4*8)(SP), DI
|
||||
MOVQ AX, (11*8)(DI) // r1
|
||||
MOVQ DX, (12*8)(DI) // r2
|
||||
|
||||
CMPL AX, $-1
|
||||
JNE ok
|
||||
|
||||
CALL libc_errno(SB)
|
||||
MOVLQSX (AX), AX
|
||||
MOVQ (4*8)(SP), DI
|
||||
MOVQ AX, (13*8)(DI) // err
|
||||
|
||||
ok:
|
||||
XORL AX, AX // no error (it's ignored anyway)
|
||||
MOVQ BP, SP
|
||||
POPQ BP
|
||||
RET
|
||||
|
||||
// syscall10X calls a function in libc on behalf of the syscall package.
|
||||
// syscall10X takes a pointer to a struct like:
|
||||
// struct {
|
||||
// fn uintptr
|
||||
// a1 uintptr
|
||||
// a2 uintptr
|
||||
// a3 uintptr
|
||||
// a4 uintptr
|
||||
// a5 uintptr
|
||||
// a6 uintptr
|
||||
// a7 uintptr
|
||||
// a8 uintptr
|
||||
// a9 uintptr
|
||||
// a10 uintptr
|
||||
// r1 uintptr
|
||||
// r2 uintptr
|
||||
// err uintptr
|
||||
// }
|
||||
// syscall10X must be called on the g0 stack with the
|
||||
// C calling convention (use libcCall).
|
||||
//
|
||||
// syscall10X is like syscall10 but expects a 64-bit result
|
||||
// and tests for 64-bit -1 to decide there was an error.
|
||||
TEXT runtime·syscall10X(SB),NOSPLIT,$0
|
||||
PUSHQ BP
|
||||
MOVQ SP, BP
|
||||
SUBQ $48, SP
|
||||
|
||||
// Arguments a1 to a6 get passed in registers, with a7 onwards being
|
||||
// passed via the stack per the x86-64 System V ABI
|
||||
// (https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf).
|
||||
MOVQ (7*8)(DI), R10 // a7
|
||||
MOVQ (8*8)(DI), R11 // a8
|
||||
MOVQ (9*8)(DI), R12 // a9
|
||||
MOVQ (10*8)(DI), R13 // a10
|
||||
MOVQ R10, (0*8)(SP) // a7
|
||||
MOVQ R11, (1*8)(SP) // a8
|
||||
MOVQ R12, (2*8)(SP) // a9
|
||||
MOVQ R13, (3*8)(SP) // a10
|
||||
MOVQ (0*8)(DI), R11 // fn
|
||||
MOVQ (2*8)(DI), SI // a2
|
||||
MOVQ (3*8)(DI), DX // a3
|
||||
MOVQ (4*8)(DI), CX // a4
|
||||
MOVQ (5*8)(DI), R8 // a5
|
||||
MOVQ (6*8)(DI), R9 // a6
|
||||
MOVQ DI, (4*8)(SP)
|
||||
MOVQ (1*8)(DI), DI // a1
|
||||
XORL AX, AX // vararg: say "no float args"
|
||||
|
||||
CALL R11
|
||||
|
||||
MOVQ (4*8)(SP), DI
|
||||
MOVQ AX, (11*8)(DI) // r1
|
||||
MOVQ DX, (12*8)(DI) // r2
|
||||
|
||||
CMPQ AX, $-1
|
||||
JNE ok
|
||||
|
||||
CALL libc_errno(SB)
|
||||
MOVLQSX (AX), AX
|
||||
MOVQ (4*8)(SP), DI
|
||||
MOVQ AX, (13*8)(DI) // err
|
||||
|
||||
ok:
|
||||
XORL AX, AX // no error (it's ignored anyway)
|
||||
MOVQ BP, SP
|
||||
POPQ BP
|
||||
RET
|
||||
|
|
|
|||
|
|
@ -15,17 +15,6 @@
|
|||
#define CLOCK_REALTIME $0
|
||||
#define CLOCK_MONOTONIC $3
|
||||
|
||||
// With OpenBSD 6.7 onwards, an arm64 syscall returns two instructions
|
||||
// after the SVC instruction, to allow for a speculative execution
|
||||
// barrier to be placed after the SVC without impacting performance.
|
||||
// For now use hardware no-ops as this works with both older and newer
|
||||
// kernels. After OpenBSD 6.8 is released this should be changed to
|
||||
// speculation barriers.
|
||||
#define INVOKE_SYSCALL \
|
||||
SVC; \
|
||||
NOOP; \
|
||||
NOOP
|
||||
|
||||
// mstart_stub is the first function executed on a new thread started by pthread_create.
|
||||
// It just does some low-level setup and then calls mstart.
|
||||
// Note: called with the C calling convention.
|
||||
|
|
@ -188,322 +177,524 @@ TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0
|
|||
ADD $16, RSP
|
||||
RET
|
||||
|
||||
// Exit the entire program (like C exit)
|
||||
TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0
|
||||
MOVW code+0(FP), R0 // arg 1 - status
|
||||
MOVD $1, R8 // sys_exit
|
||||
INVOKE_SYSCALL
|
||||
BCC 3(PC)
|
||||
MOVD $0, R0 // crash on syscall failure
|
||||
TEXT runtime·thrkill_trampoline(SB),NOSPLIT,$0
|
||||
MOVW 8(R0), R1 // arg 2 - signal
|
||||
MOVD $0, R2 // arg 3 - tcb
|
||||
MOVW 0(R0), R0 // arg 1 - tid
|
||||
CALL libc_thrkill(SB)
|
||||
RET
|
||||
|
||||
TEXT runtime·thrsleep_trampoline(SB),NOSPLIT,$0
|
||||
MOVW 8(R0), R1 // arg 2 - clock_id
|
||||
MOVD 16(R0), R2 // arg 3 - abstime
|
||||
MOVD 24(R0), R3 // arg 4 - lock
|
||||
MOVD 32(R0), R4 // arg 5 - abort
|
||||
MOVD 0(R0), R0 // arg 1 - id
|
||||
CALL libc_thrsleep(SB)
|
||||
RET
|
||||
|
||||
TEXT runtime·thrwakeup_trampoline(SB),NOSPLIT,$0
|
||||
MOVW 8(R0), R1 // arg 2 - count
|
||||
MOVD 0(R0), R0 // arg 1 - id
|
||||
CALL libc_thrwakeup(SB)
|
||||
RET
|
||||
|
||||
TEXT runtime·exit_trampoline(SB),NOSPLIT,$0
|
||||
MOVW 0(R0), R0 // arg 1 - status
|
||||
CALL libc_exit(SB)
|
||||
MOVD $0, R0 // crash on failure
|
||||
MOVD R0, (R0)
|
||||
RET
|
||||
|
||||
// func exitThread(wait *uint32)
|
||||
TEXT runtime·exitThread(SB),NOSPLIT,$0
|
||||
MOVD wait+0(FP), R0 // arg 1 - notdead
|
||||
MOVD $302, R8 // sys___threxit
|
||||
INVOKE_SYSCALL
|
||||
MOVD $0, R0 // crash on syscall failure
|
||||
MOVD R0, (R0)
|
||||
JMP 0(PC)
|
||||
|
||||
TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0
|
||||
MOVD name+0(FP), R0 // arg 1 - path
|
||||
MOVW mode+8(FP), R1 // arg 2 - mode
|
||||
MOVW perm+12(FP), R2 // arg 3 - perm
|
||||
MOVD $5, R8 // sys_open
|
||||
INVOKE_SYSCALL
|
||||
BCC 2(PC)
|
||||
MOVW $-1, R0
|
||||
MOVW R0, ret+16(FP)
|
||||
TEXT runtime·getthrid_trampoline(SB),NOSPLIT,$0
|
||||
MOVD R0, R19 // pointer to args
|
||||
CALL libc_getthrid(SB)
|
||||
MOVW R0, 0(R19) // return value
|
||||
RET
|
||||
|
||||
TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0
|
||||
MOVW fd+0(FP), R0 // arg 1 - fd
|
||||
MOVD $6, R8 // sys_close
|
||||
INVOKE_SYSCALL
|
||||
BCC 2(PC)
|
||||
MOVW $-1, R0
|
||||
MOVW R0, ret+8(FP)
|
||||
TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0
|
||||
MOVD R0, R19 // pointer to args
|
||||
CALL libc_getpid(SB) // arg 1 - pid
|
||||
MOVW 0(R19), R1 // arg 2 - signal
|
||||
CALL libc_kill(SB)
|
||||
RET
|
||||
|
||||
TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0
|
||||
MOVW fd+0(FP), R0 // arg 1 - fd
|
||||
MOVD p+8(FP), R1 // arg 2 - buf
|
||||
MOVW n+16(FP), R2 // arg 3 - nbyte
|
||||
MOVD $3, R8 // sys_read
|
||||
INVOKE_SYSCALL
|
||||
BCC 2(PC)
|
||||
NEG R0, R0
|
||||
MOVW R0, ret+24(FP)
|
||||
TEXT runtime·sched_yield_trampoline(SB),NOSPLIT,$0
|
||||
CALL libc_sched_yield(SB)
|
||||
RET
|
||||
|
||||
// func pipe() (r, w int32, errno int32)
|
||||
TEXT runtime·pipe(SB),NOSPLIT|NOFRAME,$0-12
|
||||
MOVD $r+0(FP), R0
|
||||
MOVW $0, R1
|
||||
MOVD $101, R8 // sys_pipe2
|
||||
INVOKE_SYSCALL
|
||||
BCC 2(PC)
|
||||
NEG R0, R0
|
||||
MOVW R0, errno+8(FP)
|
||||
RET
|
||||
|
||||
// func pipe2(flags int32) (r, w int32, errno int32)
|
||||
TEXT runtime·pipe2(SB),NOSPLIT|NOFRAME,$0-20
|
||||
MOVD $r+8(FP), R0
|
||||
MOVW flags+0(FP), R1
|
||||
MOVD $101, R8 // sys_pipe2
|
||||
INVOKE_SYSCALL
|
||||
BCC 2(PC)
|
||||
NEG R0, R0
|
||||
MOVW R0, errno+16(FP)
|
||||
RET
|
||||
|
||||
TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0
|
||||
MOVD fd+0(FP), R0 // arg 1 - fd
|
||||
MOVD p+8(FP), R1 // arg 2 - buf
|
||||
MOVW n+16(FP), R2 // arg 3 - nbyte
|
||||
MOVD $4, R8 // sys_write
|
||||
INVOKE_SYSCALL
|
||||
BCC 2(PC)
|
||||
NEG R0, R0
|
||||
MOVW R0, ret+24(FP)
|
||||
RET
|
||||
|
||||
TEXT runtime·usleep(SB),NOSPLIT,$24-4
|
||||
MOVWU usec+0(FP), R3
|
||||
MOVD R3, R5
|
||||
MOVW $1000000, R4
|
||||
UDIV R4, R3
|
||||
MOVD R3, 8(RSP) // tv_sec
|
||||
MUL R3, R4
|
||||
SUB R4, R5
|
||||
MOVW $1000, R4
|
||||
MUL R4, R5
|
||||
MOVD R5, 16(RSP) // tv_nsec
|
||||
|
||||
ADD $8, RSP, R0 // arg 1 - rqtp
|
||||
MOVD $0, R1 // arg 2 - rmtp
|
||||
MOVD $91, R8 // sys_nanosleep
|
||||
INVOKE_SYSCALL
|
||||
RET
|
||||
|
||||
TEXT runtime·getthrid(SB),NOSPLIT,$0-4
|
||||
MOVD $299, R8 // sys_getthrid
|
||||
INVOKE_SYSCALL
|
||||
MOVW R0, ret+0(FP)
|
||||
RET
|
||||
|
||||
TEXT runtime·thrkill(SB),NOSPLIT,$0-16
|
||||
MOVW tid+0(FP), R0 // arg 1 - tid
|
||||
MOVD sig+8(FP), R1 // arg 2 - signum
|
||||
MOVW $0, R2 // arg 3 - tcb
|
||||
MOVD $119, R8 // sys_thrkill
|
||||
INVOKE_SYSCALL
|
||||
RET
|
||||
|
||||
TEXT runtime·raiseproc(SB),NOSPLIT,$0
|
||||
MOVD $20, R8 // sys_getpid
|
||||
INVOKE_SYSCALL
|
||||
// arg 1 - pid, already in R0
|
||||
MOVW sig+0(FP), R1 // arg 2 - signum
|
||||
MOVD $122, R8 // sys_kill
|
||||
INVOKE_SYSCALL
|
||||
RET
|
||||
|
||||
TEXT runtime·mmap(SB),NOSPLIT,$0
|
||||
MOVD addr+0(FP), R0 // arg 1 - addr
|
||||
MOVD n+8(FP), R1 // arg 2 - len
|
||||
MOVW prot+16(FP), R2 // arg 3 - prot
|
||||
MOVW flags+20(FP), R3 // arg 4 - flags
|
||||
MOVW fd+24(FP), R4 // arg 5 - fd
|
||||
MOVW $0, R5 // arg 6 - pad
|
||||
MOVW off+28(FP), R6 // arg 7 - offset
|
||||
MOVD $197, R8 // sys_mmap
|
||||
INVOKE_SYSCALL
|
||||
TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0
|
||||
MOVD R0, R19 // pointer to args
|
||||
MOVD 0(R19), R0 // arg 1 - addr
|
||||
MOVD 8(R19), R1 // arg 2 - len
|
||||
MOVW 16(R19), R2 // arg 3 - prot
|
||||
MOVW 20(R19), R3 // arg 4 - flags
|
||||
MOVW 24(R19), R4 // arg 5 - fid
|
||||
MOVW 28(R19), R5 // arg 6 - offset
|
||||
CALL libc_mmap(SB)
|
||||
MOVD $0, R1
|
||||
BCC 3(PC)
|
||||
MOVD R0, R1 // if error, move to R1
|
||||
CMP $-1, R0
|
||||
BNE noerr
|
||||
CALL libc_errno(SB)
|
||||
MOVW (R0), R1 // errno
|
||||
MOVD $0, R0
|
||||
MOVD R0, p+32(FP)
|
||||
MOVD R1, err+40(FP)
|
||||
noerr:
|
||||
MOVD R0, 32(R19)
|
||||
MOVD R1, 40(R19)
|
||||
RET
|
||||
|
||||
TEXT runtime·munmap(SB),NOSPLIT,$0
|
||||
MOVD addr+0(FP), R0 // arg 1 - addr
|
||||
MOVD n+8(FP), R1 // arg 2 - len
|
||||
MOVD $73, R8 // sys_munmap
|
||||
INVOKE_SYSCALL
|
||||
BCC 3(PC)
|
||||
TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0
|
||||
MOVD 8(R0), R1 // arg 2 - len
|
||||
MOVD 0(R0), R0 // arg 1 - addr
|
||||
CALL libc_munmap(SB)
|
||||
CMP $-1, R0
|
||||
BNE 3(PC)
|
||||
MOVD $0, R0 // crash on failure
|
||||
MOVD R0, (R0)
|
||||
RET
|
||||
|
||||
TEXT runtime·madvise_trampoline(SB), NOSPLIT, $0
|
||||
MOVD 8(R0), R1 // arg 2 - len
|
||||
MOVW 16(R0), R2 // arg 3 - advice
|
||||
MOVD 0(R0), R0 // arg 1 - addr
|
||||
CALL libc_madvise(SB)
|
||||
// ignore failure - maybe pages are locked
|
||||
RET
|
||||
|
||||
TEXT runtime·open_trampoline(SB),NOSPLIT,$0
|
||||
MOVW 8(R0), R1 // arg 2 - flags
|
||||
MOVW 12(R0), R2 // arg 3 - mode
|
||||
MOVD 0(R0), R0 // arg 1 - path
|
||||
MOVD $0, R3 // varargs
|
||||
CALL libc_open(SB)
|
||||
RET
|
||||
|
||||
TEXT runtime·close_trampoline(SB),NOSPLIT,$0
|
||||
MOVD 0(R0), R0 // arg 1 - fd
|
||||
CALL libc_close(SB)
|
||||
RET
|
||||
|
||||
TEXT runtime·read_trampoline(SB),NOSPLIT,$0
|
||||
MOVD 8(R0), R1 // arg 2 - buf
|
||||
MOVW 16(R0), R2 // arg 3 - count
|
||||
MOVW 0(R0), R0 // arg 1 - fd
|
||||
CALL libc_read(SB)
|
||||
CMP $-1, R0
|
||||
BNE noerr
|
||||
CALL libc_errno(SB)
|
||||
MOVW (R0), R0 // errno
|
||||
NEG R0, R0 // caller expects negative errno value
|
||||
noerr:
|
||||
RET
|
||||
|
||||
TEXT runtime·write_trampoline(SB),NOSPLIT,$0
|
||||
MOVD 8(R0), R1 // arg 2 - buf
|
||||
MOVW 16(R0), R2 // arg 3 - count
|
||||
MOVW 0(R0), R0 // arg 1 - fd
|
||||
CALL libc_write(SB)
|
||||
CMP $-1, R0
|
||||
BNE noerr
|
||||
CALL libc_errno(SB)
|
||||
MOVW (R0), R0 // errno
|
||||
NEG R0, R0 // caller expects negative errno value
|
||||
noerr:
|
||||
RET
|
||||
|
||||
TEXT runtime·pipe2_trampoline(SB),NOSPLIT,$0
|
||||
MOVW 8(R0), R1 // arg 2 - flags
|
||||
MOVD 0(R0), R0 // arg 1 - filedes
|
||||
CALL libc_pipe2(SB)
|
||||
CMP $-1, R0
|
||||
BNE noerr
|
||||
CALL libc_errno(SB)
|
||||
MOVW (R0), R0 // errno
|
||||
NEG R0, R0 // caller expects negative errno value
|
||||
noerr:
|
||||
RET
|
||||
|
||||
TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0
|
||||
MOVD 8(R0), R1 // arg 2 - new
|
||||
MOVD 16(R0), R2 // arg 3 - old
|
||||
MOVW 0(R0), R0 // arg 1 - which
|
||||
CALL libc_setitimer(SB)
|
||||
RET
|
||||
|
||||
TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
|
||||
MOVD 0(R0), R0 // arg 1 - usec
|
||||
CALL libc_usleep(SB)
|
||||
RET
|
||||
|
||||
TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0
|
||||
MOVW 8(R0), R1 // arg 2 - miblen
|
||||
MOVD 16(R0), R2 // arg 3 - out
|
||||
MOVD 24(R0), R3 // arg 4 - size
|
||||
MOVD 32(R0), R4 // arg 5 - dst
|
||||
MOVD 40(R0), R5 // arg 6 - ndst
|
||||
MOVD 0(R0), R0 // arg 1 - mib
|
||||
CALL libc_sysctl(SB)
|
||||
RET
|
||||
|
||||
TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
|
||||
CALL libc_kqueue(SB)
|
||||
RET
|
||||
|
||||
TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0
|
||||
MOVD 8(R0), R1 // arg 2 - keventt
|
||||
MOVW 16(R0), R2 // arg 3 - nch
|
||||
MOVD 24(R0), R3 // arg 4 - ev
|
||||
MOVW 32(R0), R4 // arg 5 - nev
|
||||
MOVD 40(R0), R5 // arg 6 - ts
|
||||
MOVW 0(R0), R0 // arg 1 - kq
|
||||
CALL libc_kevent(SB)
|
||||
CMP $-1, R0
|
||||
BNE noerr
|
||||
CALL libc_errno(SB)
|
||||
MOVW (R0), R0 // errno
|
||||
NEG R0, R0 // caller expects negative errno value
|
||||
noerr:
|
||||
RET
|
||||
|
||||
TEXT runtime·clock_gettime_trampoline(SB),NOSPLIT,$0
|
||||
MOVD 8(R0), R1 // arg 2 - tp
|
||||
MOVD 0(R0), R0 // arg 1 - clock_id
|
||||
CALL libc_clock_gettime(SB)
|
||||
CMP $-1, R0
|
||||
BNE 3(PC)
|
||||
MOVD $0, R0 // crash on failure
|
||||
MOVD R0, (R0)
|
||||
RET
|
||||
|
||||
TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
|
||||
MOVW 4(R0), R1 // arg 2 - cmd
|
||||
MOVW 8(R0), R2 // arg 3 - arg
|
||||
MOVW 0(R0), R0 // arg 1 - fd
|
||||
MOVD $0, R3 // vararg
|
||||
CALL libc_fcntl(SB)
|
||||
RET
|
||||
|
||||
TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0
|
||||
MOVD 8(R0), R1 // arg 2 - new
|
||||
MOVD 16(R0), R2 // arg 3 - old
|
||||
MOVW 0(R0), R0 // arg 1 - sig
|
||||
CALL libc_sigaction(SB)
|
||||
CMP $-1, R0
|
||||
BNE 3(PC)
|
||||
MOVD $0, R0 // crash on syscall failure
|
||||
MOVD R0, (R0)
|
||||
RET
|
||||
|
||||
TEXT runtime·madvise(SB),NOSPLIT,$0
|
||||
MOVD addr+0(FP), R0 // arg 1 - addr
|
||||
MOVD n+8(FP), R1 // arg 2 - len
|
||||
MOVW flags+16(FP), R2 // arg 2 - flags
|
||||
MOVD $75, R8 // sys_madvise
|
||||
INVOKE_SYSCALL
|
||||
BCC 2(PC)
|
||||
MOVW $-1, R0
|
||||
MOVW R0, ret+24(FP)
|
||||
RET
|
||||
|
||||
TEXT runtime·setitimer(SB),NOSPLIT,$0
|
||||
MOVW mode+0(FP), R0 // arg 1 - mode
|
||||
MOVD new+8(FP), R1 // arg 2 - new value
|
||||
MOVD old+16(FP), R2 // arg 3 - old value
|
||||
MOVD $69, R8 // sys_setitimer
|
||||
INVOKE_SYSCALL
|
||||
RET
|
||||
|
||||
// func walltime1() (sec int64, nsec int32)
|
||||
TEXT runtime·walltime1(SB), NOSPLIT, $32
|
||||
MOVW CLOCK_REALTIME, R0 // arg 1 - clock_id
|
||||
MOVD $8(RSP), R1 // arg 2 - tp
|
||||
MOVD $87, R8 // sys_clock_gettime
|
||||
INVOKE_SYSCALL
|
||||
|
||||
MOVD 8(RSP), R0 // sec
|
||||
MOVD 16(RSP), R1 // nsec
|
||||
MOVD R0, sec+0(FP)
|
||||
MOVW R1, nsec+8(FP)
|
||||
|
||||
RET
|
||||
|
||||
// int64 nanotime1(void) so really
|
||||
// void nanotime1(int64 *nsec)
|
||||
TEXT runtime·nanotime1(SB),NOSPLIT,$32
|
||||
MOVW CLOCK_MONOTONIC, R0 // arg 1 - clock_id
|
||||
MOVD $8(RSP), R1 // arg 2 - tp
|
||||
MOVD $87, R8 // sys_clock_gettime
|
||||
INVOKE_SYSCALL
|
||||
|
||||
MOVW 8(RSP), R3 // sec
|
||||
MOVW 16(RSP), R5 // nsec
|
||||
|
||||
MOVD $1000000000, R4
|
||||
MUL R4, R3
|
||||
ADD R5, R3
|
||||
MOVD R3, ret+0(FP)
|
||||
RET
|
||||
|
||||
TEXT runtime·sigaction(SB),NOSPLIT,$0
|
||||
MOVW sig+0(FP), R0 // arg 1 - signum
|
||||
MOVD new+8(FP), R1 // arg 2 - new sigaction
|
||||
MOVD old+16(FP), R2 // arg 3 - old sigaction
|
||||
MOVD $46, R8 // sys_sigaction
|
||||
INVOKE_SYSCALL
|
||||
BCC 3(PC)
|
||||
MOVD $3, R0 // crash on syscall failure
|
||||
TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0
|
||||
MOVD 8(R0), R1 // arg 2 - new
|
||||
MOVD 16(R0), R2 // arg 3 - old
|
||||
MOVW 0(R0), R0 // arg 1 - how
|
||||
CALL libc_pthread_sigmask(SB)
|
||||
CMP $-1, R0
|
||||
BNE 3(PC)
|
||||
MOVD $0, R0 // crash on syscall failure
|
||||
MOVD R0, (R0)
|
||||
RET
|
||||
|
||||
TEXT runtime·obsdsigprocmask(SB),NOSPLIT,$0
|
||||
MOVW how+0(FP), R0 // arg 1 - mode
|
||||
MOVW new+4(FP), R1 // arg 2 - new
|
||||
MOVD $48, R8 // sys_sigprocmask
|
||||
INVOKE_SYSCALL
|
||||
BCC 3(PC)
|
||||
MOVD $3, R8 // crash on syscall failure
|
||||
MOVD R8, (R8)
|
||||
MOVW R0, ret+8(FP)
|
||||
TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0
|
||||
MOVD 8(R0), R1 // arg 2 - old
|
||||
MOVD 0(R0), R0 // arg 1 - new
|
||||
CALL libc_sigaltstack(SB)
|
||||
CMP $-1, R0
|
||||
BNE 3(PC)
|
||||
MOVD $0, R0 // crash on syscall failure
|
||||
MOVD R0, (R0)
|
||||
RET
|
||||
|
||||
TEXT runtime·sigaltstack(SB),NOSPLIT,$0
|
||||
MOVD new+0(FP), R0 // arg 1 - new sigaltstack
|
||||
MOVD old+8(FP), R1 // arg 2 - old sigaltstack
|
||||
MOVD $288, R8 // sys_sigaltstack
|
||||
INVOKE_SYSCALL
|
||||
BCC 3(PC)
|
||||
MOVD $0, R8 // crash on syscall failure
|
||||
MOVD R8, (R8)
|
||||
// syscall calls a function in libc on behalf of the syscall package.
|
||||
// syscall takes a pointer to a struct like:
|
||||
// struct {
|
||||
// fn uintptr
|
||||
// a1 uintptr
|
||||
// a2 uintptr
|
||||
// a3 uintptr
|
||||
// r1 uintptr
|
||||
// r2 uintptr
|
||||
// err uintptr
|
||||
// }
|
||||
// syscall must be called on the g0 stack with the
|
||||
// C calling convention (use libcCall).
|
||||
//
|
||||
// syscall expects a 32-bit result and tests for 32-bit -1
|
||||
// to decide there was an error.
|
||||
TEXT runtime·syscall(SB),NOSPLIT,$0
|
||||
MOVD R0, R19 // pointer to args
|
||||
|
||||
MOVD (0*8)(R19), R11 // fn
|
||||
MOVD (1*8)(R19), R0 // a1
|
||||
MOVD (2*8)(R19), R1 // a2
|
||||
MOVD (3*8)(R19), R2 // a3
|
||||
MOVD $0, R3 // vararg
|
||||
|
||||
CALL R11
|
||||
|
||||
MOVD R0, (4*8)(R19) // r1
|
||||
MOVD R1, (5*8)(R19) // r2
|
||||
|
||||
// Standard libc functions return -1 on error
|
||||
// and set errno.
|
||||
CMPW $-1, R0
|
||||
BNE ok
|
||||
|
||||
// Get error code from libc.
|
||||
CALL libc_errno(SB)
|
||||
MOVW (R0), R0
|
||||
MOVD R0, (6*8)(R19) // err
|
||||
|
||||
ok:
|
||||
RET
|
||||
|
||||
TEXT runtime·osyield(SB),NOSPLIT,$0
|
||||
MOVD $298, R8 // sys_sched_yield
|
||||
INVOKE_SYSCALL
|
||||
// syscallX calls a function in libc on behalf of the syscall package.
|
||||
// syscallX takes a pointer to a struct like:
|
||||
// struct {
|
||||
// fn uintptr
|
||||
// a1 uintptr
|
||||
// a2 uintptr
|
||||
// a3 uintptr
|
||||
// r1 uintptr
|
||||
// r2 uintptr
|
||||
// err uintptr
|
||||
// }
|
||||
// syscallX must be called on the g0 stack with the
|
||||
// C calling convention (use libcCall).
|
||||
//
|
||||
// syscallX is like syscall but expects a 64-bit result
|
||||
// and tests for 64-bit -1 to decide there was an error.
|
||||
TEXT runtime·syscallX(SB),NOSPLIT,$0
|
||||
MOVD R0, R19 // pointer to args
|
||||
|
||||
MOVD (0*8)(R19), R11 // fn
|
||||
MOVD (1*8)(R19), R0 // a1
|
||||
MOVD (2*8)(R19), R1 // a2
|
||||
MOVD (3*8)(R19), R2 // a3
|
||||
MOVD $0, R3 // vararg
|
||||
|
||||
CALL R11
|
||||
|
||||
MOVD R0, (4*8)(R19) // r1
|
||||
MOVD R1, (5*8)(R19) // r2
|
||||
|
||||
// Standard libc functions return -1 on error
|
||||
// and set errno.
|
||||
CMP $-1, R0
|
||||
BNE ok
|
||||
|
||||
// Get error code from libc.
|
||||
CALL libc_errno(SB)
|
||||
MOVW (R0), R0
|
||||
MOVD R0, (6*8)(R19) // err
|
||||
|
||||
ok:
|
||||
RET
|
||||
|
||||
TEXT runtime·thrsleep(SB),NOSPLIT,$0
|
||||
MOVD ident+0(FP), R0 // arg 1 - ident
|
||||
MOVW clock_id+8(FP), R1 // arg 2 - clock_id
|
||||
MOVD tsp+16(FP), R2 // arg 3 - tsp
|
||||
MOVD lock+24(FP), R3 // arg 4 - lock
|
||||
MOVD abort+32(FP), R4 // arg 5 - abort
|
||||
MOVD $94, R8 // sys___thrsleep
|
||||
INVOKE_SYSCALL
|
||||
MOVW R0, ret+40(FP)
|
||||
// syscall6 calls a function in libc on behalf of the syscall package.
|
||||
// syscall6 takes a pointer to a struct like:
|
||||
// struct {
|
||||
// fn uintptr
|
||||
// a1 uintptr
|
||||
// a2 uintptr
|
||||
// a3 uintptr
|
||||
// a4 uintptr
|
||||
// a5 uintptr
|
||||
// a6 uintptr
|
||||
// r1 uintptr
|
||||
// r2 uintptr
|
||||
// err uintptr
|
||||
// }
|
||||
// syscall6 must be called on the g0 stack with the
|
||||
// C calling convention (use libcCall).
|
||||
//
|
||||
// syscall6 expects a 32-bit result and tests for 32-bit -1
|
||||
// to decide there was an error.
|
||||
TEXT runtime·syscall6(SB),NOSPLIT,$0
|
||||
MOVD R0, R19 // pointer to args
|
||||
|
||||
MOVD (0*8)(R19), R11 // fn
|
||||
MOVD (1*8)(R19), R0 // a1
|
||||
MOVD (2*8)(R19), R1 // a2
|
||||
MOVD (3*8)(R19), R2 // a3
|
||||
MOVD (4*8)(R19), R3 // a4
|
||||
MOVD (5*8)(R19), R4 // a5
|
||||
MOVD (6*8)(R19), R5 // a6
|
||||
MOVD $0, R6 // vararg
|
||||
|
||||
CALL R11
|
||||
|
||||
MOVD R0, (7*8)(R19) // r1
|
||||
MOVD R1, (8*8)(R19) // r2
|
||||
|
||||
// Standard libc functions return -1 on error
|
||||
// and set errno.
|
||||
CMPW $-1, R0
|
||||
BNE ok
|
||||
|
||||
// Get error code from libc.
|
||||
CALL libc_errno(SB)
|
||||
MOVW (R0), R0
|
||||
MOVD R0, (9*8)(R19) // err
|
||||
|
||||
ok:
|
||||
RET
|
||||
|
||||
TEXT runtime·thrwakeup(SB),NOSPLIT,$0
|
||||
MOVD ident+0(FP), R0 // arg 1 - ident
|
||||
MOVW n+8(FP), R1 // arg 2 - n
|
||||
MOVD $301, R8 // sys___thrwakeup
|
||||
INVOKE_SYSCALL
|
||||
MOVW R0, ret+16(FP)
|
||||
// syscall6X calls a function in libc on behalf of the syscall package.
|
||||
// syscall6X takes a pointer to a struct like:
|
||||
// struct {
|
||||
// fn uintptr
|
||||
// a1 uintptr
|
||||
// a2 uintptr
|
||||
// a3 uintptr
|
||||
// a4 uintptr
|
||||
// a5 uintptr
|
||||
// a6 uintptr
|
||||
// r1 uintptr
|
||||
// r2 uintptr
|
||||
// err uintptr
|
||||
// }
|
||||
// syscall6X must be called on the g0 stack with the
|
||||
// C calling convention (use libcCall).
|
||||
//
|
||||
// syscall6X is like syscall6 but expects a 64-bit result
|
||||
// and tests for 64-bit -1 to decide there was an error.
|
||||
TEXT runtime·syscall6X(SB),NOSPLIT,$0
|
||||
MOVD R0, R19 // pointer to args
|
||||
|
||||
MOVD (0*8)(R19), R11 // fn
|
||||
MOVD (1*8)(R19), R0 // a1
|
||||
MOVD (2*8)(R19), R1 // a2
|
||||
MOVD (3*8)(R19), R2 // a3
|
||||
MOVD (4*8)(R19), R3 // a4
|
||||
MOVD (5*8)(R19), R4 // a5
|
||||
MOVD (6*8)(R19), R5 // a6
|
||||
MOVD $0, R6 // vararg
|
||||
|
||||
CALL R11
|
||||
|
||||
MOVD R0, (7*8)(R19) // r1
|
||||
MOVD R1, (8*8)(R19) // r2
|
||||
|
||||
// Standard libc functions return -1 on error
|
||||
// and set errno.
|
||||
CMP $-1, R0
|
||||
BNE ok
|
||||
|
||||
// Get error code from libc.
|
||||
CALL libc_errno(SB)
|
||||
MOVW (R0), R0
|
||||
MOVD R0, (9*8)(R19) // err
|
||||
|
||||
ok:
|
||||
RET
|
||||
|
||||
TEXT runtime·sysctl(SB),NOSPLIT,$0
|
||||
MOVD mib+0(FP), R0 // arg 1 - mib
|
||||
MOVW miblen+8(FP), R1 // arg 2 - miblen
|
||||
MOVD out+16(FP), R2 // arg 3 - out
|
||||
MOVD size+24(FP), R3 // arg 4 - size
|
||||
MOVD dst+32(FP), R4 // arg 5 - dest
|
||||
MOVD ndst+40(FP), R5 // arg 6 - newlen
|
||||
MOVD $202, R8 // sys___sysctl
|
||||
INVOKE_SYSCALL
|
||||
BCC 2(PC)
|
||||
NEG R0, R0
|
||||
MOVW R0, ret+48(FP)
|
||||
// syscall10 calls a function in libc on behalf of the syscall package.
|
||||
// syscall10 takes a pointer to a struct like:
|
||||
// struct {
|
||||
// fn uintptr
|
||||
// a1 uintptr
|
||||
// a2 uintptr
|
||||
// a3 uintptr
|
||||
// a4 uintptr
|
||||
// a5 uintptr
|
||||
// a6 uintptr
|
||||
// a7 uintptr
|
||||
// a8 uintptr
|
||||
// a9 uintptr
|
||||
// a10 uintptr
|
||||
// r1 uintptr
|
||||
// r2 uintptr
|
||||
// err uintptr
|
||||
// }
|
||||
// syscall10 must be called on the g0 stack with the
|
||||
// C calling convention (use libcCall).
|
||||
TEXT runtime·syscall10(SB),NOSPLIT,$0
|
||||
MOVD R0, R19 // pointer to args
|
||||
|
||||
MOVD (0*8)(R19), R11 // fn
|
||||
MOVD (1*8)(R19), R0 // a1
|
||||
MOVD (2*8)(R19), R1 // a2
|
||||
MOVD (3*8)(R19), R2 // a3
|
||||
MOVD (4*8)(R19), R3 // a4
|
||||
MOVD (5*8)(R19), R4 // a5
|
||||
MOVD (6*8)(R19), R5 // a6
|
||||
MOVD (7*8)(R19), R6 // a7
|
||||
MOVD (8*8)(R19), R7 // a8
|
||||
MOVD (9*8)(R19), R8 // a9
|
||||
MOVD (10*8)(R19), R9 // a10
|
||||
MOVD $0, R10 // vararg
|
||||
|
||||
CALL R11
|
||||
|
||||
MOVD R0, (11*8)(R19) // r1
|
||||
MOVD R1, (12*8)(R19) // r2
|
||||
|
||||
// Standard libc functions return -1 on error
|
||||
// and set errno.
|
||||
CMPW $-1, R0
|
||||
BNE ok
|
||||
|
||||
// Get error code from libc.
|
||||
CALL libc_errno(SB)
|
||||
MOVW (R0), R0
|
||||
MOVD R0, (13*8)(R19) // err
|
||||
|
||||
ok:
|
||||
RET
|
||||
|
||||
// int32 runtime·kqueue(void);
|
||||
TEXT runtime·kqueue(SB),NOSPLIT,$0
|
||||
MOVD $269, R8 // sys_kqueue
|
||||
INVOKE_SYSCALL
|
||||
BCC 2(PC)
|
||||
NEG R0, R0
|
||||
MOVW R0, ret+0(FP)
|
||||
RET
|
||||
// syscall10X calls a function in libc on behalf of the syscall package.
|
||||
// syscall10X takes a pointer to a struct like:
|
||||
// struct {
|
||||
// fn uintptr
|
||||
// a1 uintptr
|
||||
// a2 uintptr
|
||||
// a3 uintptr
|
||||
// a4 uintptr
|
||||
// a5 uintptr
|
||||
// a6 uintptr
|
||||
// a7 uintptr
|
||||
// a8 uintptr
|
||||
// a9 uintptr
|
||||
// a10 uintptr
|
||||
// r1 uintptr
|
||||
// r2 uintptr
|
||||
// err uintptr
|
||||
// }
|
||||
// syscall10X must be called on the g0 stack with the
|
||||
// C calling convention (use libcCall).
|
||||
//
|
||||
// syscall10X is like syscall10 but expects a 64-bit result
|
||||
// and tests for 64-bit -1 to decide there was an error.
|
||||
TEXT runtime·syscall10X(SB),NOSPLIT,$0
|
||||
MOVD R0, R19 // pointer to args
|
||||
|
||||
// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
|
||||
TEXT runtime·kevent(SB),NOSPLIT,$0
|
||||
MOVW kq+0(FP), R0 // arg 1 - kq
|
||||
MOVD ch+8(FP), R1 // arg 2 - changelist
|
||||
MOVW nch+16(FP), R2 // arg 3 - nchanges
|
||||
MOVD ev+24(FP), R3 // arg 4 - eventlist
|
||||
MOVW nev+32(FP), R4 // arg 5 - nevents
|
||||
MOVD ts+40(FP), R5 // arg 6 - timeout
|
||||
MOVD $72, R8 // sys_kevent
|
||||
INVOKE_SYSCALL
|
||||
BCC 2(PC)
|
||||
NEG R0, R0
|
||||
MOVW R0, ret+48(FP)
|
||||
RET
|
||||
MOVD (0*8)(R19), R11 // fn
|
||||
MOVD (1*8)(R19), R0 // a1
|
||||
MOVD (2*8)(R19), R1 // a2
|
||||
MOVD (3*8)(R19), R2 // a3
|
||||
MOVD (4*8)(R19), R3 // a4
|
||||
MOVD (5*8)(R19), R4 // a5
|
||||
MOVD (6*8)(R19), R5 // a6
|
||||
MOVD (7*8)(R19), R6 // a7
|
||||
MOVD (8*8)(R19), R7 // a8
|
||||
MOVD (9*8)(R19), R8 // a9
|
||||
MOVD (10*8)(R19), R9 // a10
|
||||
MOVD $0, R10 // vararg
|
||||
|
||||
// func closeonexec(fd int32)
|
||||
TEXT runtime·closeonexec(SB),NOSPLIT,$0
|
||||
MOVW fd+0(FP), R0 // arg 1 - fd
|
||||
MOVD $2, R1 // arg 2 - cmd (F_SETFD)
|
||||
MOVD $1, R2 // arg 3 - arg (FD_CLOEXEC)
|
||||
MOVD $92, R8 // sys_fcntl
|
||||
INVOKE_SYSCALL
|
||||
RET
|
||||
CALL R11
|
||||
|
||||
// func runtime·setNonblock(int32 fd)
|
||||
TEXT runtime·setNonblock(SB),NOSPLIT|NOFRAME,$0-4
|
||||
MOVW fd+0(FP), R0 // arg 1 - fd
|
||||
MOVD $3, R1 // arg 2 - cmd (F_GETFL)
|
||||
MOVD $0, R2 // arg 3
|
||||
MOVD $92, R8 // sys_fcntl
|
||||
INVOKE_SYSCALL
|
||||
MOVD $4, R2 // O_NONBLOCK
|
||||
ORR R0, R2 // arg 3 - flags
|
||||
MOVW fd+0(FP), R0 // arg 1 - fd
|
||||
MOVD $4, R1 // arg 2 - cmd (F_SETFL)
|
||||
MOVD $92, R8 // sys_fcntl
|
||||
INVOKE_SYSCALL
|
||||
MOVD R0, (11*8)(R19) // r1
|
||||
MOVD R1, (12*8)(R19) // r2
|
||||
|
||||
// Standard libc functions return -1 on error
|
||||
// and set errno.
|
||||
CMP $-1, R0
|
||||
BNE ok
|
||||
|
||||
// Get error code from libc.
|
||||
CALL libc_errno(SB)
|
||||
MOVW (R0), R0
|
||||
MOVD R0, (13*8)(R19) // err
|
||||
|
||||
ok:
|
||||
RET
|
||||
|
|
|
|||
39
src/runtime/testdata/testprog/deadlock.go
vendored
39
src/runtime/testdata/testprog/deadlock.go
vendored
|
|
@ -25,6 +25,7 @@ func init() {
|
|||
register("RecursivePanic2", RecursivePanic2)
|
||||
register("RecursivePanic3", RecursivePanic3)
|
||||
register("RecursivePanic4", RecursivePanic4)
|
||||
register("RecursivePanic5", RecursivePanic5)
|
||||
register("GoexitExit", GoexitExit)
|
||||
register("GoNil", GoNil)
|
||||
register("MainGoroutineID", MainGoroutineID)
|
||||
|
|
@ -160,6 +161,44 @@ func RecursivePanic4() {
|
|||
panic("first panic")
|
||||
}
|
||||
|
||||
// Test case where we have an open-coded defer higher up the stack (in two), and
|
||||
// in the current function (three) we recover in a defer while we still have
|
||||
// another defer to be processed.
|
||||
func RecursivePanic5() {
|
||||
one()
|
||||
panic("third panic")
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func one() {
|
||||
two()
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func two() {
|
||||
defer func() {
|
||||
}()
|
||||
|
||||
three()
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func three() {
|
||||
defer func() {
|
||||
}()
|
||||
|
||||
defer func() {
|
||||
fmt.Println(recover())
|
||||
}()
|
||||
|
||||
defer func() {
|
||||
fmt.Println(recover())
|
||||
panic("second panic")
|
||||
}()
|
||||
|
||||
panic("first panic")
|
||||
}
|
||||
|
||||
func GoexitExit() {
|
||||
println("t1")
|
||||
go func() {
|
||||
|
|
|
|||
19
src/runtime/testdata/testwinsignal/main.go
vendored
Normal file
19
src/runtime/testdata/testwinsignal/main.go
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c)
|
||||
|
||||
fmt.Println("ready")
|
||||
sig := <-c
|
||||
|
||||
time.Sleep(time.Second)
|
||||
fmt.Println(sig)
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// +build netbsd openbsd
|
||||
// +build netbsd
|
||||
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
#include "funcdata.h"
|
||||
|
||||
//
|
||||
// Syscall9 support for AMD64, NetBSD and OpenBSD
|
||||
// Syscall9 support for AMD64, NetBSD
|
||||
//
|
||||
|
||||
// func Syscall9(trap int64, a1, a2, a3, a4, a5, a6, a7, a8, a9 int64) (r1, r2, err int64);
|
||||
|
|
|
|||
32
src/syscall/asm_openbsd_amd64.s
Normal file
32
src/syscall/asm_openbsd_amd64.s
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for AMD64, OpenBSD
|
||||
//
|
||||
|
||||
// Provide these function names via assembly so they are provided as ABI0,
|
||||
// rather than ABIInternal.
|
||||
|
||||
// func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
JMP ·syscallInternal(SB)
|
||||
|
||||
// func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
JMP ·syscall6Internal(SB)
|
||||
|
||||
// func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
JMP ·rawSyscallInternal(SB)
|
||||
|
||||
// func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
JMP ·rawSyscall6Internal(SB)
|
||||
|
||||
// func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||
JMP ·syscall9Internal(SB)
|
||||
|
|
@ -4,127 +4,29 @@
|
|||
|
||||
#include "textflag.h"
|
||||
|
||||
// See comment in runtime/sys_openbsd_arm64.s re this construction.
|
||||
#define INVOKE_SYSCALL \
|
||||
SVC; \
|
||||
NOOP; \
|
||||
NOOP
|
||||
//
|
||||
// System call support for ARM64, OpenBSD
|
||||
//
|
||||
|
||||
// func Syscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64);
|
||||
// Provide these function names via assembly so they are provided as ABI0,
|
||||
// rather than ABIInternal.
|
||||
|
||||
// func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
BL runtime·entersyscall(SB)
|
||||
MOVD a1+8(FP), R0
|
||||
MOVD a2+16(FP), R1
|
||||
MOVD a3+24(FP), R2
|
||||
MOVD $0, R3
|
||||
MOVD $0, R4
|
||||
MOVD $0, R5
|
||||
MOVD trap+0(FP), R8 // syscall number
|
||||
INVOKE_SYSCALL
|
||||
BCC ok
|
||||
MOVD $-1, R4
|
||||
MOVD R4, r1+32(FP) // r1
|
||||
MOVD ZR, r2+40(FP) // r2
|
||||
MOVD R0, err+48(FP) // errno
|
||||
BL runtime·exitsyscall(SB)
|
||||
RET
|
||||
ok:
|
||||
MOVD R0, r1+32(FP) // r1
|
||||
MOVD R1, r2+40(FP) // r2
|
||||
MOVD ZR, err+48(FP) // errno
|
||||
BL runtime·exitsyscall(SB)
|
||||
RET
|
||||
JMP ·syscallInternal(SB)
|
||||
|
||||
// func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
BL runtime·entersyscall(SB)
|
||||
MOVD a1+8(FP), R0
|
||||
MOVD a2+16(FP), R1
|
||||
MOVD a3+24(FP), R2
|
||||
MOVD a4+32(FP), R3
|
||||
MOVD a5+40(FP), R4
|
||||
MOVD a6+48(FP), R5
|
||||
MOVD trap+0(FP), R8 // syscall number
|
||||
INVOKE_SYSCALL
|
||||
BCC ok
|
||||
MOVD $-1, R4
|
||||
MOVD R4, r1+56(FP) // r1
|
||||
MOVD ZR, r2+64(FP) // r2
|
||||
MOVD R0, err+72(FP) // errno
|
||||
BL runtime·exitsyscall(SB)
|
||||
RET
|
||||
ok:
|
||||
MOVD R0, r1+56(FP) // r1
|
||||
MOVD R1, r2+64(FP) // r2
|
||||
MOVD ZR, err+72(FP) // errno
|
||||
BL runtime·exitsyscall(SB)
|
||||
RET
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||
BL runtime·entersyscall(SB)
|
||||
MOVD a1+8(FP), R0
|
||||
MOVD a2+16(FP), R1
|
||||
MOVD a3+24(FP), R2
|
||||
MOVD a4+32(FP), R3
|
||||
MOVD a5+40(FP), R4
|
||||
MOVD a6+48(FP), R5
|
||||
MOVD a7+56(FP), R6
|
||||
MOVD a8+64(FP), R7
|
||||
MOVD a9+72(FP), R8 // on stack
|
||||
MOVD R8, 8(RSP)
|
||||
MOVD num+0(FP), R8 // syscall number
|
||||
INVOKE_SYSCALL
|
||||
BCC ok
|
||||
MOVD $-1, R4
|
||||
MOVD R4, r1+80(FP) // r1
|
||||
MOVD ZR, r2+88(FP) // r2
|
||||
MOVD R0, err+96(FP) // errno
|
||||
BL runtime·exitsyscall(SB)
|
||||
RET
|
||||
ok:
|
||||
MOVD R0, r1+80(FP) // r1
|
||||
MOVD R1, r2+88(FP) // r2
|
||||
MOVD ZR, err+96(FP) // errno
|
||||
BL runtime·exitsyscall(SB)
|
||||
RET
|
||||
JMP ·syscall6Internal(SB)
|
||||
|
||||
// func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
MOVD a1+8(FP), R0
|
||||
MOVD a2+16(FP), R1
|
||||
MOVD a3+24(FP), R2
|
||||
MOVD $0, R3
|
||||
MOVD $0, R4
|
||||
MOVD $0, R5
|
||||
MOVD trap+0(FP), R8 // syscall number
|
||||
INVOKE_SYSCALL
|
||||
BCC ok
|
||||
MOVD $-1, R4
|
||||
MOVD R4, r1+32(FP) // r1
|
||||
MOVD ZR, r2+40(FP) // r2
|
||||
MOVD R0, err+48(FP) // errno
|
||||
RET
|
||||
ok:
|
||||
MOVD R0, r1+32(FP) // r1
|
||||
MOVD R1, r2+40(FP) // r2
|
||||
MOVD ZR, err+48(FP) // errno
|
||||
RET
|
||||
JMP ·rawSyscallInternal(SB)
|
||||
|
||||
// func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
MOVD a1+8(FP), R0
|
||||
MOVD a2+16(FP), R1
|
||||
MOVD a3+24(FP), R2
|
||||
MOVD a4+32(FP), R3
|
||||
MOVD a5+40(FP), R4
|
||||
MOVD a6+48(FP), R5
|
||||
MOVD trap+0(FP), R8 // syscall number
|
||||
INVOKE_SYSCALL
|
||||
BCC ok
|
||||
MOVD $-1, R4
|
||||
MOVD R4, r1+56(FP) // r1
|
||||
MOVD ZR, r2+64(FP) // r2
|
||||
MOVD R0, err+72(FP) // errno
|
||||
RET
|
||||
ok:
|
||||
MOVD R0, r1+56(FP) // r1
|
||||
MOVD R1, r2+64(FP) // r2
|
||||
MOVD ZR, err+72(FP) // errno
|
||||
RET
|
||||
JMP ·rawSyscall6Internal(SB)
|
||||
|
||||
// func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||
JMP ·syscall9Internal(SB)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// +build netbsd freebsd openbsd dragonfly
|
||||
// +build netbsd freebsd dragonfly
|
||||
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build dragonfly freebsd netbsd openbsd
|
||||
// +build dragonfly freebsd netbsd openbsd,!amd64,!arm64
|
||||
|
||||
package syscall
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build darwin openbsd,amd64 openbsd,arm64
|
||||
|
||||
package syscall
|
||||
|
||||
import (
|
||||
|
|
@ -272,6 +272,7 @@ func runtime_AfterExec()
|
|||
// avoids a build dependency for other platforms.
|
||||
var execveLibc func(path uintptr, argv uintptr, envp uintptr) Errno
|
||||
var execveDarwin func(path *byte, argv **byte, envp **byte) error
|
||||
var execveOpenBSD func(path *byte, argv **byte, envp **byte) error
|
||||
|
||||
// Exec invokes the execve(2) system call.
|
||||
func Exec(argv0 string, argv []string, envv []string) (err error) {
|
||||
|
|
@ -299,6 +300,9 @@ func Exec(argv0 string, argv []string, envv []string) (err error) {
|
|||
} else if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
|
||||
// Similarly on Darwin.
|
||||
err1 = execveDarwin(argv0p, &argvp[0], &envvp[0])
|
||||
} else if runtime.GOOS == "openbsd" && runtime.GOARCH == "amd64" {
|
||||
// Similarly on OpenBSD.
|
||||
err1 = execveOpenBSD(argv0p, &argvp[0], &envvp[0])
|
||||
} else {
|
||||
_, _, err1 = RawSyscall(SYS_EXECVE,
|
||||
uintptr(unsafe.Pointer(argv0p)),
|
||||
|
|
|
|||
|
|
@ -125,13 +125,13 @@ darwin_amd64)
|
|||
mkerrors="$mkerrors -m64"
|
||||
mksyscall="./mksyscall.pl -darwin"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
mkasm="go run mkasm_darwin.go"
|
||||
mkasm="go run mkasm.go"
|
||||
;;
|
||||
darwin_arm64)
|
||||
mkerrors="$mkerrors -m64"
|
||||
mksyscall="./mksyscall.pl -darwin"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
mkasm="go run mkasm_darwin.go"
|
||||
mkasm="go run mkasm.go"
|
||||
;;
|
||||
dragonfly_amd64)
|
||||
mkerrors="$mkerrors -m64"
|
||||
|
|
@ -283,6 +283,7 @@ netbsd_arm64)
|
|||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
;;
|
||||
openbsd_386)
|
||||
GOOSARCH_in="syscall_openbsd1.go syscall_openbsd_$GOARCH.go"
|
||||
mkerrors="$mkerrors -m32"
|
||||
mksyscall="./mksyscall.pl -l32 -openbsd"
|
||||
mksysctl="./mksysctl_openbsd.pl"
|
||||
|
|
@ -291,14 +292,17 @@ openbsd_386)
|
|||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
;;
|
||||
openbsd_amd64)
|
||||
GOOSARCH_in="syscall_openbsd_libc.go syscall_openbsd_$GOARCH.go"
|
||||
mkerrors="$mkerrors -m64"
|
||||
mksyscall="./mksyscall.pl -openbsd"
|
||||
mksyscall="./mksyscall.pl -openbsd -libc"
|
||||
mksysctl="./mksysctl_openbsd.pl"
|
||||
zsysctl="zsysctl_openbsd.go"
|
||||
mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
|
||||
mkasm="go run mkasm.go"
|
||||
;;
|
||||
openbsd_arm)
|
||||
GOOSARCH_in="syscall_openbsd1.go syscall_openbsd_$GOARCH.go"
|
||||
mkerrors="$mkerrors"
|
||||
mksyscall="./mksyscall.pl -l32 -openbsd -arm"
|
||||
mksysctl="./mksysctl_openbsd.pl"
|
||||
|
|
@ -309,16 +313,19 @@ openbsd_arm)
|
|||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
||||
;;
|
||||
openbsd_arm64)
|
||||
GOOSARCH_in="syscall_openbsd_libc.go syscall_openbsd_$GOARCH.go"
|
||||
mkerrors="$mkerrors -m64"
|
||||
mksyscall="./mksyscall.pl -openbsd"
|
||||
mksyscall="./mksyscall.pl -openbsd -libc"
|
||||
mksysctl="./mksysctl_openbsd.pl"
|
||||
zsysctl="zsysctl_openbsd.go"
|
||||
mksysnum="curl -s 'http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
|
||||
# Let the type of C char be signed to make the bare syscall
|
||||
# API consistent between platforms.
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
||||
mkasm="go run mkasm.go"
|
||||
;;
|
||||
openbsd_mips64)
|
||||
GOOSARCH_in="syscall_openbsd1.go syscall_openbsd_$GOARCH.go"
|
||||
mkerrors="$mkerrors -m64"
|
||||
mksyscall="./mksyscall.pl -openbsd"
|
||||
mksysctl="./mksysctl_openbsd.pl"
|
||||
|
|
@ -327,7 +334,6 @@ openbsd_mips64)
|
|||
# Let the type of C char be signed to make the bare syscall
|
||||
# API consistent between platforms.
|
||||
mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
|
||||
GOOSARCH_in=syscall_openbsd_mips64.go
|
||||
;;
|
||||
plan9_386)
|
||||
mkerrors=
|
||||
|
|
@ -367,5 +373,5 @@ esac
|
|||
# Therefore, "go run" tries to recompile syscall package but ztypes is empty and it fails.
|
||||
echo "$mktypes types_$GOOS.go |go run mkpost.go >ztypes_$GOOSARCH.go.NEW && mv ztypes_$GOOSARCH.go.NEW ztypes_$GOOSARCH.go";
|
||||
fi
|
||||
if [ -n "$mkasm" ]; then echo "$mkasm $GOARCH"; fi
|
||||
if [ -n "$mkasm" ]; then echo "$mkasm $GOOS $GOARCH"; fi
|
||||
) | $run
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
// +build ignore
|
||||
|
||||
// mkasm_darwin.go generates assembly trampolines to call libSystem routines from Go.
|
||||
// mkasm.go generates assembly trampolines to call library routines from Go.
|
||||
// This program must be run after mksyscall.pl.
|
||||
package main
|
||||
|
||||
|
|
@ -17,18 +17,25 @@ import (
|
|||
)
|
||||
|
||||
func main() {
|
||||
in1, err := os.ReadFile("syscall_darwin.go")
|
||||
if err != nil {
|
||||
log.Fatalf("can't open syscall_darwin.go: %s", err)
|
||||
if len(os.Args) != 3 {
|
||||
log.Fatalf("Usage: %s <goos> <arch>", os.Args[0])
|
||||
}
|
||||
arch := os.Args[1]
|
||||
in2, err := os.ReadFile(fmt.Sprintf("syscall_darwin_%s.go", arch))
|
||||
goos, arch := os.Args[1], os.Args[2]
|
||||
|
||||
syscallFilename := fmt.Sprintf("syscall_%s.go", goos)
|
||||
syscallArchFilename := fmt.Sprintf("syscall_%s_%s.go", goos, arch)
|
||||
|
||||
in1, err := os.ReadFile(syscallFilename)
|
||||
if err != nil {
|
||||
log.Fatalf("can't open syscall_darwin_%s.go: %s", arch, err)
|
||||
log.Fatalf("can't open syscall file: %s", err)
|
||||
}
|
||||
in3, err := os.ReadFile(fmt.Sprintf("zsyscall_darwin_%s.go", arch))
|
||||
in2, err := os.ReadFile(syscallArchFilename)
|
||||
if err != nil {
|
||||
log.Fatalf("can't open zsyscall_darwin_%s.go: %s", arch, err)
|
||||
log.Fatalf("can't open syscall file: %s", err)
|
||||
}
|
||||
in3, err := os.ReadFile("z" + syscallArchFilename)
|
||||
if err != nil {
|
||||
log.Fatalf("can't open syscall file: %s", err)
|
||||
}
|
||||
in := string(in1) + string(in2) + string(in3)
|
||||
|
||||
|
|
@ -36,7 +43,7 @@ func main() {
|
|||
|
||||
var out bytes.Buffer
|
||||
|
||||
fmt.Fprintf(&out, "// go run mkasm_darwin.go %s\n", strings.Join(os.Args[1:], " "))
|
||||
fmt.Fprintf(&out, "// go run mkasm.go %s\n", strings.Join(os.Args[1:], " "))
|
||||
fmt.Fprintf(&out, "// Code generated by the command above; DO NOT EDIT.\n")
|
||||
fmt.Fprintf(&out, "#include \"textflag.h\"\n")
|
||||
for _, line := range strings.Split(in, "\n") {
|
||||
|
|
@ -50,8 +57,8 @@ func main() {
|
|||
fmt.Fprintf(&out, "\tJMP\t%s(SB)\n", fn)
|
||||
}
|
||||
}
|
||||
err = os.WriteFile(fmt.Sprintf("zsyscall_darwin_%s.s", arch), out.Bytes(), 0644)
|
||||
err = os.WriteFile(fmt.Sprintf("zsyscall_%s_%s.s", goos, arch), out.Bytes(), 0644)
|
||||
if err != nil {
|
||||
log.Fatalf("can't write zsyscall_darwin_%s.s: %s", arch, err)
|
||||
log.Fatalf("can't write syscall file: %s", err)
|
||||
}
|
||||
}
|
||||
|
|
@ -30,6 +30,7 @@ my $openbsd = 0;
|
|||
my $netbsd = 0;
|
||||
my $dragonfly = 0;
|
||||
my $arm = 0; # 64-bit value should use (even, odd)-pair
|
||||
my $libc = 0;
|
||||
my $tags = ""; # build tags
|
||||
|
||||
if($ARGV[0] eq "-b32") {
|
||||
|
|
@ -45,6 +46,7 @@ if($ARGV[0] eq "-plan9") {
|
|||
}
|
||||
if($ARGV[0] eq "-darwin") {
|
||||
$darwin = 1;
|
||||
$libc = 1;
|
||||
shift;
|
||||
}
|
||||
if($ARGV[0] eq "-openbsd") {
|
||||
|
|
@ -63,6 +65,10 @@ if($ARGV[0] eq "-arm") {
|
|||
$arm = 1;
|
||||
shift;
|
||||
}
|
||||
if($ARGV[0] eq "-libc") {
|
||||
$libc = 1;
|
||||
shift;
|
||||
}
|
||||
if($ARGV[0] eq "-tags") {
|
||||
shift;
|
||||
$tags = $ARGV[0];
|
||||
|
|
@ -125,7 +131,7 @@ while(<>) {
|
|||
# without reading the header.
|
||||
$text .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n";
|
||||
|
||||
if ($darwin && $func eq "ptrace1") {
|
||||
if (($darwin || ($openbsd && $libc)) && $func eq "ptrace") {
|
||||
# The ptrace function is called from forkAndExecInChild where stack
|
||||
# growth is forbidden.
|
||||
$text .= "//go:nosplit\n"
|
||||
|
|
@ -176,7 +182,9 @@ while(<>) {
|
|||
push @args, "uintptr(_p$n)", "uintptr(len($name))";
|
||||
$n++;
|
||||
} elsif($type eq "int64" && ($openbsd || $netbsd)) {
|
||||
if (!$libc) {
|
||||
push @args, "0";
|
||||
}
|
||||
if($_32bit eq "big-endian") {
|
||||
push @args, "uintptr($name>>32)", "uintptr($name)";
|
||||
} elsif($_32bit eq "little-endian") {
|
||||
|
|
@ -220,7 +228,7 @@ while(<>) {
|
|||
$asm = "RawSyscall";
|
||||
}
|
||||
}
|
||||
if ($darwin) {
|
||||
if ($libc) {
|
||||
# Call unexported syscall functions (which take
|
||||
# libc functions instead of syscall numbers).
|
||||
$asm = lcfirst($asm);
|
||||
|
|
@ -243,7 +251,7 @@ while(<>) {
|
|||
print STDERR "$ARGV:$.: too many arguments to system call\n";
|
||||
}
|
||||
|
||||
if ($darwin) {
|
||||
if ($darwin || ($openbsd && $libc)) {
|
||||
# Use extended versions for calls that generate a 64-bit result.
|
||||
my ($name, $type) = parseparam($out[0]);
|
||||
if ($type eq "int64" || ($type eq "uintptr" && $_32bit eq "")) {
|
||||
|
|
@ -257,13 +265,13 @@ while(<>) {
|
|||
$sysname = "SYS_$func";
|
||||
$sysname =~ s/([a-z])([A-Z])/${1}_$2/g; # turn FooBar into Foo_Bar
|
||||
$sysname =~ y/a-z/A-Z/;
|
||||
if($darwin) {
|
||||
if($libc) {
|
||||
$sysname =~ y/A-Z/a-z/;
|
||||
$sysname = substr $sysname, 4;
|
||||
$funcname = "libc_$sysname";
|
||||
}
|
||||
}
|
||||
if($darwin) {
|
||||
if($libc) {
|
||||
if($funcname eq "") {
|
||||
$sysname = substr $sysname, 4;
|
||||
$funcname = "libc_$sysname";
|
||||
|
|
@ -338,14 +346,18 @@ while(<>) {
|
|||
}
|
||||
$text .= "\treturn\n";
|
||||
$text .= "}\n\n";
|
||||
if($darwin) {
|
||||
if($libc) {
|
||||
if (not exists $trampolines{$funcname}) {
|
||||
$trampolines{$funcname} = 1;
|
||||
# The assembly trampoline that jumps to the libc routine.
|
||||
$text .= "func ${funcname}_trampoline()\n";
|
||||
# Tell the linker that funcname can be found in libSystem using varname without the libc_ prefix.
|
||||
my $basename = substr $funcname, 5;
|
||||
$text .= "//go:cgo_import_dynamic $funcname $basename \"/usr/lib/libSystem.B.dylib\"\n\n";
|
||||
my $libc = "libc.so";
|
||||
if ($darwin) {
|
||||
$libc = "/usr/lib/libSystem.B.dylib";
|
||||
}
|
||||
$text .= "//go:cgo_import_dynamic $funcname $basename \"$libc\"\n\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -182,7 +182,6 @@ func setattrlistTimes(path string, times []Timespec) error {
|
|||
//sys Rename(from string, to string) (err error)
|
||||
//sys Revoke(path string) (err error)
|
||||
//sys Rmdir(path string) (err error)
|
||||
//sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK
|
||||
//sys Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error)
|
||||
//sysnb Setegid(egid int) (err error)
|
||||
//sysnb Seteuid(euid int) (err error)
|
||||
|
|
@ -207,8 +206,4 @@ func setattrlistTimes(path string, times []Timespec) error {
|
|||
//sys write(fd int, p []byte) (n int, err error)
|
||||
//sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
|
||||
//sys munmap(addr uintptr, length uintptr) (err error)
|
||||
//sys readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ
|
||||
//sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE
|
||||
//sys utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
|
||||
//sys getcwd(buf []byte) (n int, err error) = SYS___GETCWD
|
||||
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
|
||||
|
|
|
|||
13
src/syscall/syscall_openbsd1.go
Normal file
13
src/syscall/syscall_openbsd1.go
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright 2020 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.
|
||||
|
||||
// +build openbsd,!amd64,!arm64
|
||||
|
||||
package syscall
|
||||
|
||||
//sys readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ
|
||||
//sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE
|
||||
//sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK
|
||||
//sys getcwd(buf []byte) (n int, err error) = SYS___GETCWD
|
||||
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
|
||||
77
src/syscall/syscall_openbsd_libc.go
Normal file
77
src/syscall/syscall_openbsd_libc.go
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
// Copyright 2020 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.
|
||||
|
||||
// +build openbsd,amd64 openbsd,arm64
|
||||
|
||||
package syscall
|
||||
|
||||
import "unsafe"
|
||||
|
||||
func init() {
|
||||
execveOpenBSD = execve
|
||||
}
|
||||
|
||||
//sys directSyscall(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr) (ret uintptr, err error) = SYS_syscall
|
||||
|
||||
func syscallInternal(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
|
||||
return syscall6X(funcPC(libc_syscall_trampoline), trap, a1, a2, a3, 0, 0)
|
||||
}
|
||||
|
||||
func syscall6Internal(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
|
||||
return syscall10X(funcPC(libc_syscall_trampoline), trap, a1, a2, a3, a4, a5, a6, 0, 0, 0)
|
||||
}
|
||||
|
||||
func rawSyscallInternal(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
|
||||
return rawSyscall6X(funcPC(libc_syscall_trampoline), trap, a1, a2, a3, 0, 0)
|
||||
}
|
||||
|
||||
func rawSyscall6Internal(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
|
||||
return rawSyscall10X(funcPC(libc_syscall_trampoline), trap, a1, a2, a3, a4, a5, a6, 0, 0, 0)
|
||||
}
|
||||
|
||||
func syscall9Internal(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno) {
|
||||
return rawSyscall10X(funcPC(libc_syscall_trampoline), trap, a1, a2, a3, a4, a5, a6, a7, a8, a9)
|
||||
}
|
||||
|
||||
// Implemented in the runtime package (runtime/sys_openbsd3.go)
|
||||
func syscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
|
||||
func syscallX(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
|
||||
func syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
||||
func syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
||||
func syscall10(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 uintptr) (r1, r2 uintptr, err Errno)
|
||||
func syscall10X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 uintptr) (r1, r2 uintptr, err Errno)
|
||||
func rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
|
||||
func rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
||||
func rawSyscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
|
||||
func rawSyscall10X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 uintptr) (r1, r2 uintptr, err Errno)
|
||||
|
||||
func syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno) {
|
||||
return syscall10(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, 0)
|
||||
}
|
||||
func syscall9X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno) {
|
||||
return syscall10X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, 0)
|
||||
}
|
||||
|
||||
// Find the entry point for f. See comments in runtime/proc.go for the
|
||||
// function of the same name.
|
||||
//go:nosplit
|
||||
func funcPC(f func()) uintptr {
|
||||
return **(**uintptr)(unsafe.Pointer(&f))
|
||||
}
|
||||
|
||||
//sys readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_read
|
||||
//sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_write
|
||||
//sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_lseek
|
||||
//sys getcwd(buf []byte) (n int, err error)
|
||||
//sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error)
|
||||
//sysnb fork() (pid int, err error)
|
||||
//sysnb ioctl(fd int, req int, arg int) (err error)
|
||||
//sysnb execve(path *byte, argv **byte, envp **byte) (err error)
|
||||
//sysnb exit(res int) (err error)
|
||||
//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
|
||||
//sysnb getentropy(p []byte) (err error)
|
||||
//sys fstatat(fd int, path string, stat *Stat_t, flags int) (err error)
|
||||
//sys fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (val int, err error) = SYS_fcntl
|
||||
//sys unlinkat(fd int, path string, flags int) (err error)
|
||||
//sys openat(fd int, path string, flags int, perm uint32) (fdret int, err error)
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// go run mkasm_darwin.go amd64
|
||||
// go run mkasm.go darwin amd64
|
||||
// Code generated by the command above; DO NOT EDIT.
|
||||
#include "textflag.h"
|
||||
TEXT ·libc_getfsstat_trampoline(SB),NOSPLIT,$0-0
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// go run mkasm_darwin.go arm64
|
||||
// go run mkasm.go darwin arm64
|
||||
// Code generated by the command above; DO NOT EDIT.
|
||||
#include "textflag.h"
|
||||
TEXT ·libc_getfsstat_trampoline(SB),NOSPLIT,$0-0
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
233
src/syscall/zsyscall_openbsd_amd64.s
Normal file
233
src/syscall/zsyscall_openbsd_amd64.s
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
// go run mkasm.go openbsd amd64
|
||||
// Code generated by the command above; DO NOT EDIT.
|
||||
#include "textflag.h"
|
||||
TEXT ·libc_getgroups_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getgroups(SB)
|
||||
TEXT ·libc_setgroups_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_setgroups(SB)
|
||||
TEXT ·libc_wait4_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_wait4(SB)
|
||||
TEXT ·libc_accept_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_accept(SB)
|
||||
TEXT ·libc_bind_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_bind(SB)
|
||||
TEXT ·libc_connect_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_connect(SB)
|
||||
TEXT ·libc_socket_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_socket(SB)
|
||||
TEXT ·libc_getsockopt_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getsockopt(SB)
|
||||
TEXT ·libc_setsockopt_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_setsockopt(SB)
|
||||
TEXT ·libc_getpeername_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getpeername(SB)
|
||||
TEXT ·libc_getsockname_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getsockname(SB)
|
||||
TEXT ·libc_shutdown_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_shutdown(SB)
|
||||
TEXT ·libc_socketpair_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_socketpair(SB)
|
||||
TEXT ·libc_recvfrom_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_recvfrom(SB)
|
||||
TEXT ·libc_sendto_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_sendto(SB)
|
||||
TEXT ·libc_recvmsg_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_recvmsg(SB)
|
||||
TEXT ·libc_sendmsg_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_sendmsg(SB)
|
||||
TEXT ·libc_kevent_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_kevent(SB)
|
||||
TEXT ·libc_utimes_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_utimes(SB)
|
||||
TEXT ·libc_futimes_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_futimes(SB)
|
||||
TEXT ·libc_fcntl_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fcntl(SB)
|
||||
TEXT ·libc_pipe2_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_pipe2(SB)
|
||||
TEXT ·libc_accept4_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_accept4(SB)
|
||||
TEXT ·libc_getdents_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getdents(SB)
|
||||
TEXT ·libc_access_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_access(SB)
|
||||
TEXT ·libc_adjtime_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_adjtime(SB)
|
||||
TEXT ·libc_chdir_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_chdir(SB)
|
||||
TEXT ·libc_chflags_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_chflags(SB)
|
||||
TEXT ·libc_chmod_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_chmod(SB)
|
||||
TEXT ·libc_chown_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_chown(SB)
|
||||
TEXT ·libc_chroot_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_chroot(SB)
|
||||
TEXT ·libc_close_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_close(SB)
|
||||
TEXT ·libc_dup_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_dup(SB)
|
||||
TEXT ·libc_dup2_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_dup2(SB)
|
||||
TEXT ·libc_fchdir_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fchdir(SB)
|
||||
TEXT ·libc_fchflags_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fchflags(SB)
|
||||
TEXT ·libc_fchmod_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fchmod(SB)
|
||||
TEXT ·libc_fchown_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fchown(SB)
|
||||
TEXT ·libc_flock_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_flock(SB)
|
||||
TEXT ·libc_fpathconf_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fpathconf(SB)
|
||||
TEXT ·libc_fstat_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fstat(SB)
|
||||
TEXT ·libc_fstatfs_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fstatfs(SB)
|
||||
TEXT ·libc_fsync_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fsync(SB)
|
||||
TEXT ·libc_ftruncate_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_ftruncate(SB)
|
||||
TEXT ·libc_getegid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getegid(SB)
|
||||
TEXT ·libc_geteuid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_geteuid(SB)
|
||||
TEXT ·libc_getgid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getgid(SB)
|
||||
TEXT ·libc_getpgid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getpgid(SB)
|
||||
TEXT ·libc_getpgrp_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getpgrp(SB)
|
||||
TEXT ·libc_getpid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getpid(SB)
|
||||
TEXT ·libc_getppid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getppid(SB)
|
||||
TEXT ·libc_getpriority_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getpriority(SB)
|
||||
TEXT ·libc_getrlimit_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getrlimit(SB)
|
||||
TEXT ·libc_getrusage_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getrusage(SB)
|
||||
TEXT ·libc_getsid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getsid(SB)
|
||||
TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_gettimeofday(SB)
|
||||
TEXT ·libc_getuid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getuid(SB)
|
||||
TEXT ·libc_issetugid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_issetugid(SB)
|
||||
TEXT ·libc_kill_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_kill(SB)
|
||||
TEXT ·libc_kqueue_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_kqueue(SB)
|
||||
TEXT ·libc_lchown_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_lchown(SB)
|
||||
TEXT ·libc_link_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_link(SB)
|
||||
TEXT ·libc_listen_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_listen(SB)
|
||||
TEXT ·libc_lstat_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_lstat(SB)
|
||||
TEXT ·libc_mkdir_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_mkdir(SB)
|
||||
TEXT ·libc_mkfifo_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_mkfifo(SB)
|
||||
TEXT ·libc_mknod_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_mknod(SB)
|
||||
TEXT ·libc_nanosleep_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_nanosleep(SB)
|
||||
TEXT ·libc_open_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_open(SB)
|
||||
TEXT ·libc_pathconf_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_pathconf(SB)
|
||||
TEXT ·libc_pread_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_pread(SB)
|
||||
TEXT ·libc_pwrite_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_pwrite(SB)
|
||||
TEXT ·libc_read_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_read(SB)
|
||||
TEXT ·libc_readlink_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_readlink(SB)
|
||||
TEXT ·libc_rename_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_rename(SB)
|
||||
TEXT ·libc_revoke_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_revoke(SB)
|
||||
TEXT ·libc_rmdir_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_rmdir(SB)
|
||||
TEXT ·libc_select_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_select(SB)
|
||||
TEXT ·libc_setegid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_setegid(SB)
|
||||
TEXT ·libc_seteuid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_seteuid(SB)
|
||||
TEXT ·libc_setgid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_setgid(SB)
|
||||
TEXT ·libc_setlogin_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_setlogin(SB)
|
||||
TEXT ·libc_setpgid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_setpgid(SB)
|
||||
TEXT ·libc_setpriority_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_setpriority(SB)
|
||||
TEXT ·libc_setregid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_setregid(SB)
|
||||
TEXT ·libc_setreuid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_setreuid(SB)
|
||||
TEXT ·libc_setrlimit_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_setrlimit(SB)
|
||||
TEXT ·libc_setsid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_setsid(SB)
|
||||
TEXT ·libc_settimeofday_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_settimeofday(SB)
|
||||
TEXT ·libc_setuid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_setuid(SB)
|
||||
TEXT ·libc_stat_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_stat(SB)
|
||||
TEXT ·libc_statfs_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_statfs(SB)
|
||||
TEXT ·libc_symlink_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_symlink(SB)
|
||||
TEXT ·libc_sync_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_sync(SB)
|
||||
TEXT ·libc_truncate_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_truncate(SB)
|
||||
TEXT ·libc_umask_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_umask(SB)
|
||||
TEXT ·libc_unlink_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_unlink(SB)
|
||||
TEXT ·libc_unmount_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_unmount(SB)
|
||||
TEXT ·libc_write_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_write(SB)
|
||||
TEXT ·libc_mmap_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_mmap(SB)
|
||||
TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_munmap(SB)
|
||||
TEXT ·libc_utimensat_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_utimensat(SB)
|
||||
TEXT ·libc_syscall_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_syscall(SB)
|
||||
TEXT ·libc_lseek_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_lseek(SB)
|
||||
TEXT ·libc_getcwd_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getcwd(SB)
|
||||
TEXT ·libc_sysctl_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_sysctl(SB)
|
||||
TEXT ·libc_fork_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fork(SB)
|
||||
TEXT ·libc_ioctl_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_ioctl(SB)
|
||||
TEXT ·libc_execve_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_execve(SB)
|
||||
TEXT ·libc_exit_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_exit(SB)
|
||||
TEXT ·libc_ptrace_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_ptrace(SB)
|
||||
TEXT ·libc_getentropy_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getentropy(SB)
|
||||
TEXT ·libc_fstatat_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fstatat(SB)
|
||||
TEXT ·libc_unlinkat_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_unlinkat(SB)
|
||||
TEXT ·libc_openat_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_openat(SB)
|
||||
File diff suppressed because it is too large
Load diff
233
src/syscall/zsyscall_openbsd_arm64.s
Normal file
233
src/syscall/zsyscall_openbsd_arm64.s
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
// go run mkasm.go openbsd arm64
|
||||
// Code generated by the command above; DO NOT EDIT.
|
||||
#include "textflag.h"
|
||||
TEXT ·libc_getgroups_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getgroups(SB)
|
||||
TEXT ·libc_setgroups_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_setgroups(SB)
|
||||
TEXT ·libc_wait4_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_wait4(SB)
|
||||
TEXT ·libc_accept_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_accept(SB)
|
||||
TEXT ·libc_bind_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_bind(SB)
|
||||
TEXT ·libc_connect_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_connect(SB)
|
||||
TEXT ·libc_socket_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_socket(SB)
|
||||
TEXT ·libc_getsockopt_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getsockopt(SB)
|
||||
TEXT ·libc_setsockopt_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_setsockopt(SB)
|
||||
TEXT ·libc_getpeername_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getpeername(SB)
|
||||
TEXT ·libc_getsockname_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getsockname(SB)
|
||||
TEXT ·libc_shutdown_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_shutdown(SB)
|
||||
TEXT ·libc_socketpair_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_socketpair(SB)
|
||||
TEXT ·libc_recvfrom_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_recvfrom(SB)
|
||||
TEXT ·libc_sendto_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_sendto(SB)
|
||||
TEXT ·libc_recvmsg_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_recvmsg(SB)
|
||||
TEXT ·libc_sendmsg_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_sendmsg(SB)
|
||||
TEXT ·libc_kevent_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_kevent(SB)
|
||||
TEXT ·libc_utimes_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_utimes(SB)
|
||||
TEXT ·libc_futimes_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_futimes(SB)
|
||||
TEXT ·libc_fcntl_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fcntl(SB)
|
||||
TEXT ·libc_pipe2_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_pipe2(SB)
|
||||
TEXT ·libc_accept4_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_accept4(SB)
|
||||
TEXT ·libc_getdents_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getdents(SB)
|
||||
TEXT ·libc_access_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_access(SB)
|
||||
TEXT ·libc_adjtime_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_adjtime(SB)
|
||||
TEXT ·libc_chdir_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_chdir(SB)
|
||||
TEXT ·libc_chflags_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_chflags(SB)
|
||||
TEXT ·libc_chmod_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_chmod(SB)
|
||||
TEXT ·libc_chown_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_chown(SB)
|
||||
TEXT ·libc_chroot_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_chroot(SB)
|
||||
TEXT ·libc_close_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_close(SB)
|
||||
TEXT ·libc_dup_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_dup(SB)
|
||||
TEXT ·libc_dup2_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_dup2(SB)
|
||||
TEXT ·libc_fchdir_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fchdir(SB)
|
||||
TEXT ·libc_fchflags_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fchflags(SB)
|
||||
TEXT ·libc_fchmod_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fchmod(SB)
|
||||
TEXT ·libc_fchown_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fchown(SB)
|
||||
TEXT ·libc_flock_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_flock(SB)
|
||||
TEXT ·libc_fpathconf_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fpathconf(SB)
|
||||
TEXT ·libc_fstat_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fstat(SB)
|
||||
TEXT ·libc_fstatfs_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fstatfs(SB)
|
||||
TEXT ·libc_fsync_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fsync(SB)
|
||||
TEXT ·libc_ftruncate_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_ftruncate(SB)
|
||||
TEXT ·libc_getegid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getegid(SB)
|
||||
TEXT ·libc_geteuid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_geteuid(SB)
|
||||
TEXT ·libc_getgid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getgid(SB)
|
||||
TEXT ·libc_getpgid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getpgid(SB)
|
||||
TEXT ·libc_getpgrp_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getpgrp(SB)
|
||||
TEXT ·libc_getpid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getpid(SB)
|
||||
TEXT ·libc_getppid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getppid(SB)
|
||||
TEXT ·libc_getpriority_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getpriority(SB)
|
||||
TEXT ·libc_getrlimit_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getrlimit(SB)
|
||||
TEXT ·libc_getrusage_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getrusage(SB)
|
||||
TEXT ·libc_getsid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getsid(SB)
|
||||
TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_gettimeofday(SB)
|
||||
TEXT ·libc_getuid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getuid(SB)
|
||||
TEXT ·libc_issetugid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_issetugid(SB)
|
||||
TEXT ·libc_kill_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_kill(SB)
|
||||
TEXT ·libc_kqueue_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_kqueue(SB)
|
||||
TEXT ·libc_lchown_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_lchown(SB)
|
||||
TEXT ·libc_link_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_link(SB)
|
||||
TEXT ·libc_listen_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_listen(SB)
|
||||
TEXT ·libc_lstat_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_lstat(SB)
|
||||
TEXT ·libc_mkdir_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_mkdir(SB)
|
||||
TEXT ·libc_mkfifo_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_mkfifo(SB)
|
||||
TEXT ·libc_mknod_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_mknod(SB)
|
||||
TEXT ·libc_nanosleep_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_nanosleep(SB)
|
||||
TEXT ·libc_open_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_open(SB)
|
||||
TEXT ·libc_pathconf_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_pathconf(SB)
|
||||
TEXT ·libc_pread_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_pread(SB)
|
||||
TEXT ·libc_pwrite_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_pwrite(SB)
|
||||
TEXT ·libc_read_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_read(SB)
|
||||
TEXT ·libc_readlink_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_readlink(SB)
|
||||
TEXT ·libc_rename_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_rename(SB)
|
||||
TEXT ·libc_revoke_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_revoke(SB)
|
||||
TEXT ·libc_rmdir_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_rmdir(SB)
|
||||
TEXT ·libc_select_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_select(SB)
|
||||
TEXT ·libc_setegid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_setegid(SB)
|
||||
TEXT ·libc_seteuid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_seteuid(SB)
|
||||
TEXT ·libc_setgid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_setgid(SB)
|
||||
TEXT ·libc_setlogin_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_setlogin(SB)
|
||||
TEXT ·libc_setpgid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_setpgid(SB)
|
||||
TEXT ·libc_setpriority_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_setpriority(SB)
|
||||
TEXT ·libc_setregid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_setregid(SB)
|
||||
TEXT ·libc_setreuid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_setreuid(SB)
|
||||
TEXT ·libc_setrlimit_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_setrlimit(SB)
|
||||
TEXT ·libc_setsid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_setsid(SB)
|
||||
TEXT ·libc_settimeofday_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_settimeofday(SB)
|
||||
TEXT ·libc_setuid_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_setuid(SB)
|
||||
TEXT ·libc_stat_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_stat(SB)
|
||||
TEXT ·libc_statfs_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_statfs(SB)
|
||||
TEXT ·libc_symlink_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_symlink(SB)
|
||||
TEXT ·libc_sync_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_sync(SB)
|
||||
TEXT ·libc_truncate_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_truncate(SB)
|
||||
TEXT ·libc_umask_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_umask(SB)
|
||||
TEXT ·libc_unlink_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_unlink(SB)
|
||||
TEXT ·libc_unmount_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_unmount(SB)
|
||||
TEXT ·libc_write_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_write(SB)
|
||||
TEXT ·libc_mmap_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_mmap(SB)
|
||||
TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_munmap(SB)
|
||||
TEXT ·libc_utimensat_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_utimensat(SB)
|
||||
TEXT ·libc_syscall_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_syscall(SB)
|
||||
TEXT ·libc_lseek_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_lseek(SB)
|
||||
TEXT ·libc_getcwd_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getcwd(SB)
|
||||
TEXT ·libc_sysctl_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_sysctl(SB)
|
||||
TEXT ·libc_fork_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fork(SB)
|
||||
TEXT ·libc_ioctl_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_ioctl(SB)
|
||||
TEXT ·libc_execve_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_execve(SB)
|
||||
TEXT ·libc_exit_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_exit(SB)
|
||||
TEXT ·libc_ptrace_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_ptrace(SB)
|
||||
TEXT ·libc_getentropy_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getentropy(SB)
|
||||
TEXT ·libc_fstatat_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fstatat(SB)
|
||||
TEXT ·libc_unlinkat_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_unlinkat(SB)
|
||||
TEXT ·libc_openat_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_openat(SB)
|
||||
28
test/closure7.go
Normal file
28
test/closure7.go
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// run
|
||||
|
||||
// Copyright 2020 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 main
|
||||
|
||||
func g(f func()) {
|
||||
}
|
||||
|
||||
// Must have exportable name
|
||||
func F() {
|
||||
g(func() {
|
||||
ch := make(chan int)
|
||||
for {
|
||||
select {
|
||||
case <-ch:
|
||||
return
|
||||
default:
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func main() {
|
||||
F()
|
||||
}
|
||||
|
|
@ -59,10 +59,10 @@ func f(n int) {
|
|||
ill := make([]byte, 64)
|
||||
switch runtime.GOARCH {
|
||||
case "386", "amd64":
|
||||
ill = append(ill, 0x89, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00) // MOVL AX, 0
|
||||
ill = append(ill[:0], 0x89, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00) // MOVL AX, 0
|
||||
case "arm":
|
||||
binary.LittleEndian.PutUint32(ill, 0xe3a00000) // MOVW $0, R0
|
||||
binary.LittleEndian.PutUint32(ill, 0xe5800000) // MOVW R0, (R0)
|
||||
binary.LittleEndian.PutUint32(ill[0:4], 0xe3a00000) // MOVW $0, R0
|
||||
binary.LittleEndian.PutUint32(ill[4:8], 0xe5800000) // MOVW R0, (R0)
|
||||
case "arm64":
|
||||
binary.LittleEndian.PutUint32(ill, 0xf90003ff) // MOVD ZR, (ZR)
|
||||
case "ppc64":
|
||||
|
|
@ -74,7 +74,7 @@ func f(n int) {
|
|||
case "mipsle", "mips64le":
|
||||
binary.LittleEndian.PutUint32(ill, 0xfc000000) // MOVV R0, (R0)
|
||||
case "s390x":
|
||||
ill = append(ill, 0xa7, 0x09, 0x00, 0x00) // MOVD $0, R0
|
||||
ill = append(ill[:0], 0xa7, 0x09, 0x00, 0x00) // MOVD $0, R0
|
||||
ill = append(ill, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x24) // MOVD R0, (R0)
|
||||
case "riscv64":
|
||||
binary.LittleEndian.PutUint32(ill, 0x00003023) // MOV X0, (X0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue