1
0
mirror of https://github.com/golang/go synced 2024-09-24 05:20:13 -06:00

cmd/asm: require NOSPLIT for ABIInternal asm functions

Change the assembler to enforce the requirement that ABIInternal
functions need to be NOSPLIT. At the moment all of the assembly
routines in the runtime that are defined as ABIInternal also
happen to be NOSPLIT, but this CL makes it mandatory.

Updates #40724.

Change-Id: Ief80d22de1782edb44b798fcde9aab8a93548722
Reviewed-on: https://go-review.googlesource.com/c/go/+/309789
Trust: Than McIntosh <thanm@google.com>
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
Than McIntosh 2021-04-13 13:46:52 -04:00
parent ef36e4fd0e
commit 25b25a9ed7
2 changed files with 43 additions and 12 deletions

View File

@ -134,6 +134,14 @@ func (p *Parser) asmText(operands [][]lex.Token) {
next++
}
// Issue an error if we see a function defined as ABIInternal
// without NOSPLIT. In ABIInternal, obj needs to know the function
// signature in order to construct the morestack path, so this
// currently isn't supported for asm functions.
if nameAddr.Sym.ABI() == obj.ABIInternal && flag&obj.NOSPLIT == 0 {
p.errorf("TEXT %q: ABIInternal requires NOSPLIT", name)
}
// Next operand is the frame and arg size.
// Bizarre syntax: $frameSize-argSize is two words, not subtraction.
// Both frameSize and argSize must be simple integers; only frameSize

View File

@ -25,11 +25,13 @@ func tokenize(s string) [][]lex.Token {
func TestErroneous(t *testing.T) {
tests := []struct {
type errtest struct {
pseudo string
operands string
expected string
}{
}
nonRuntimeTests := []errtest{
{"TEXT", "", "expect two or three operands for TEXT"},
{"TEXT", "%", "expect two or three operands for TEXT"},
{"TEXT", "1, 1", "TEXT symbol \"<erroneous symbol>\" must be a symbol(SB)"},
@ -58,23 +60,44 @@ func TestErroneous(t *testing.T) {
{"PCDATA", "1", "expect two operands for PCDATA"},
}
runtimeTests := []errtest{
{"TEXT", "foo<ABIInternal>(SB),0", "TEXT \"foo\": ABIInternal requires NOSPLIT"},
}
testcats := []struct {
compilingRuntime bool
tests []errtest
}{
{
compilingRuntime: false,
tests: nonRuntimeTests,
},
{
compilingRuntime: true,
tests: runtimeTests,
},
}
// Note these errors should be independent of the architecture.
// Just run the test with amd64.
parser := newParser("amd64")
var buf bytes.Buffer
parser.errorWriter = &buf
for _, test := range tests {
parser.errorCount = 0
parser.lineNum++
if !parser.pseudo(test.pseudo, tokenize(test.operands)) {
t.Fatalf("Wrong pseudo-instruction: %s", test.pseudo)
for _, cat := range testcats {
for _, test := range cat.tests {
parser.compilingRuntime = cat.compilingRuntime
parser.errorCount = 0
parser.lineNum++
if !parser.pseudo(test.pseudo, tokenize(test.operands)) {
t.Fatalf("Wrong pseudo-instruction: %s", test.pseudo)
}
errorLine := buf.String()
if test.expected != errorLine {
t.Errorf("Unexpected error %q; expected %q", errorLine, test.expected)
}
buf.Reset()
}
errorLine := buf.String()
if test.expected != errorLine {
t.Errorf("Unexpected error %q; expected %q", errorLine, test.expected)
}
buf.Reset()
}
}