Commit f31305b7 authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder

cmd/asm: improve DATA size operand validation

Prior to this change, DATA instructions accepted
the values 1, 2, 4, and 8 as sizes.
The acceptable sizes were further restricted
to 4 and 8 for float constants.

This was both too restrictive and not restrictive enough:
string constants may reasonably have any length,
and address constants should really only accept pointer-length sizes.

Fixes #30269

Change-Id: I06e44ecdf5909eca7b19553861aec1fa39655c2b
Reviewed-on: https://go-review.googlesource.com/c/163747
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarKeith Randall <khr@golang.org>
parent 4a91d550
......@@ -7,6 +7,7 @@ package asm
import (
"bytes"
"fmt"
"strconv"
"text/scanner"
"cmd/asm/internal/arch"
......@@ -200,7 +201,11 @@ func (p *Parser) asmData(operands [][]lex.Token) {
p.errorf("expect /size for DATA argument")
return
}
scale := p.parseScale(op[n-1].String())
szop := op[n-1].String()
sz, err := strconv.Atoi(szop)
if err != nil {
p.errorf("bad size for DATA argument: %q", szop)
}
op = op[:n-2]
nameAddr := p.address(op)
if !p.validSymbol("DATA", &nameAddr, true) {
......@@ -223,24 +228,33 @@ func (p *Parser) asmData(operands [][]lex.Token) {
p.errorf("overlapping DATA entry for %s", name)
return
}
p.dataAddr[name] = nameAddr.Offset + int64(scale)
p.dataAddr[name] = nameAddr.Offset + int64(sz)
switch valueAddr.Type {
case obj.TYPE_CONST:
nameAddr.Sym.WriteInt(p.ctxt, nameAddr.Offset, int(scale), valueAddr.Offset)
switch sz {
case 1, 2, 4, 8:
nameAddr.Sym.WriteInt(p.ctxt, nameAddr.Offset, int(sz), valueAddr.Offset)
default:
p.errorf("bad int size for DATA argument: %d", sz)
}
case obj.TYPE_FCONST:
switch scale {
switch sz {
case 4:
nameAddr.Sym.WriteFloat32(p.ctxt, nameAddr.Offset, float32(valueAddr.Val.(float64)))
case 8:
nameAddr.Sym.WriteFloat64(p.ctxt, nameAddr.Offset, valueAddr.Val.(float64))
default:
panic("bad float scale")
p.errorf("bad float size for DATA argument: %d", sz)
}
case obj.TYPE_SCONST:
nameAddr.Sym.WriteString(p.ctxt, nameAddr.Offset, int(scale), valueAddr.Val.(string))
nameAddr.Sym.WriteString(p.ctxt, nameAddr.Offset, int(sz), valueAddr.Val.(string))
case obj.TYPE_ADDR:
nameAddr.Sym.WriteAddr(p.ctxt, nameAddr.Offset, int(scale), valueAddr.Sym, valueAddr.Offset)
if sz == p.arch.PtrSize {
nameAddr.Sym.WriteAddr(p.ctxt, nameAddr.Offset, int(sz), valueAddr.Sym, valueAddr.Offset)
} else {
p.errorf("bad addr size for DATA argument: %d", sz)
}
}
}
......
......@@ -43,6 +43,13 @@ func TestErroneous(t *testing.T) {
{"DATA", "0", "expect two operands for DATA"},
{"DATA", "(0), 1", "expect /size for DATA argument"},
{"DATA", "@B(SB)/4,0", "expected '(', found B"}, // Issue 23580.
{"DATA", "·A(SB)/4,0", "DATA value must be an immediate constant or address"},
{"DATA", "·B(SB)/4,$0", ""},
{"DATA", "·C(SB)/5,$0", "bad int size for DATA argument: 5"},
{"DATA", "·D(SB)/5,$0.0", "bad float size for DATA argument: 5"},
{"DATA", "·E(SB)/4,$·A(SB)", "bad addr size for DATA argument: 4"},
{"DATA", "·F(SB)/8,$·A(SB)", ""},
{"DATA", "·G(SB)/5,$\"abcde\"", ""},
{"GLOBL", "", "expect two or three operands for GLOBL"},
{"GLOBL", "0,1", "GLOBL symbol \"<erroneous symbol>\" must be a symbol(SB)"},
{"GLOBL", "@B(SB), 0", "expected '(', found B"}, // Issue 23580.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment