proc/gdbserial: do not return floating point regs when not requested (#1497)

Fixes #1493
This commit is contained in:
Alessandro Arzilli
2019-02-26 17:53:45 +01:00
committed by Derek Parker
parent 0e1c742787
commit 14aeea2bd9
11 changed files with 47 additions and 18 deletions

View File

@ -284,7 +284,7 @@ func (a *AMD64) RegistersToDwarfRegisters(regs Registers, staticBase uint64) op.
} }
} }
for _, reg := range regs.Slice() { for _, reg := range regs.Slice(true) {
for dwarfReg, regName := range amd64DwarfToName { for dwarfReg, regName := range amd64DwarfToName {
if regName == reg.Name { if regName == reg.Name {
dregs[dwarfReg] = op.DwarfRegisterFromBytes(reg.Bytes) dregs[dwarfReg] = op.DwarfRegisterFromBytes(reg.Bytes)

View File

@ -242,7 +242,7 @@ func TestCore(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("Couldn't get current thread registers: %v", err) t.Fatalf("Couldn't get current thread registers: %v", err)
} }
regslice := regs.Slice() regslice := regs.Slice(true)
for _, reg := range regslice { for _, reg := range regslice {
t.Logf("%s = %s", reg.Name, reg.Value) t.Logf("%s = %s", reg.Name, reg.Value)
} }
@ -311,13 +311,13 @@ func TestCoreFpRegisters(t *testing.T) {
{"XMM8", "0x4059999a404ccccd4059999a404ccccd"}, {"XMM8", "0x4059999a404ccccd4059999a404ccccd"},
} }
for _, reg := range regs.Slice() { for _, reg := range regs.Slice(true) {
t.Logf("%s = %s", reg.Name, reg.Value) t.Logf("%s = %s", reg.Name, reg.Value)
} }
for _, regtest := range regtests { for _, regtest := range regtests {
found := false found := false
for _, reg := range regs.Slice() { for _, reg := range regs.Slice(true) {
if reg.Name == regtest.name { if reg.Name == regtest.name {
found = true found = true
if !strings.HasPrefix(reg.Value, regtest.value) { if !strings.HasPrefix(reg.Value, regtest.value) {

View File

@ -1826,9 +1826,12 @@ func (t *Thread) SetDX(dx uint64) error {
return t.p.conn.writeRegister(t.strID, reg.regnum, reg.value) return t.p.conn.writeRegister(t.strID, reg.regnum, reg.value)
} }
func (regs *gdbRegisters) Slice() []proc.Register { func (regs *gdbRegisters) Slice(floatingPoint bool) []proc.Register {
r := make([]proc.Register, 0, len(regs.regsInfo)) r := make([]proc.Register, 0, len(regs.regsInfo))
for _, reginfo := range regs.regsInfo { for _, reginfo := range regs.regsInfo {
if reginfo.Group == "float" && !floatingPoint {
continue
}
switch { switch {
case reginfo.Name == "eflags": case reginfo.Name == "eflags":
r = proc.AppendEflagReg(r, reginfo.Name, uint64(binary.LittleEndian.Uint32(regs.regs[reginfo.Name].value))) r = proc.AppendEflagReg(r, reginfo.Name, uint64(binary.LittleEndian.Uint32(regs.regs[reginfo.Name].value)))
@ -1841,6 +1844,9 @@ func (regs *gdbRegisters) Slice() []proc.Register {
case reginfo.Bitsize == 64: case reginfo.Bitsize == 64:
r = proc.AppendQwordReg(r, reginfo.Name, binary.LittleEndian.Uint64(regs.regs[reginfo.Name].value)) r = proc.AppendQwordReg(r, reginfo.Name, binary.LittleEndian.Uint64(regs.regs[reginfo.Name].value))
case reginfo.Bitsize == 80: case reginfo.Bitsize == 80:
if !floatingPoint {
continue
}
idx := 0 idx := 0
for _, stprefix := range []string{"stmm", "st"} { for _, stprefix := range []string{"stmm", "st"} {
if strings.HasPrefix(reginfo.Name, stprefix) { if strings.HasPrefix(reginfo.Name, stprefix) {
@ -1852,10 +1858,12 @@ func (regs *gdbRegisters) Slice() []proc.Register {
r = proc.AppendX87Reg(r, idx, binary.LittleEndian.Uint16(value[8:]), binary.LittleEndian.Uint64(value[:8])) r = proc.AppendX87Reg(r, idx, binary.LittleEndian.Uint16(value[8:]), binary.LittleEndian.Uint64(value[:8]))
case reginfo.Bitsize == 128: case reginfo.Bitsize == 128:
if floatingPoint {
r = proc.AppendSSEReg(r, strings.ToUpper(reginfo.Name), regs.regs[reginfo.Name].value) r = proc.AppendSSEReg(r, strings.ToUpper(reginfo.Name), regs.regs[reginfo.Name].value)
}
case reginfo.Bitsize == 256: case reginfo.Bitsize == 256:
if !strings.HasPrefix(strings.ToLower(reginfo.Name), "ymm") { if !strings.HasPrefix(strings.ToLower(reginfo.Name), "ymm") || !floatingPoint {
continue continue
} }

View File

@ -228,6 +228,7 @@ type gdbRegisterInfo struct {
Bitsize int `xml:"bitsize,attr"` Bitsize int `xml:"bitsize,attr"`
Offset int Offset int
Regnum int `xml:"regnum,attr"` Regnum int `xml:"regnum,attr"`
Group string `xml:"group,attr"`
} }
// readTargetXml reads target.xml file from stub using qXfer:features:read, // readTargetXml reads target.xml file from stub using qXfer:features:read,

View File

@ -51,7 +51,7 @@ type AMD64PtraceRegs struct {
} }
// Slice returns the registers as a list of (name, value) pairs. // Slice returns the registers as a list of (name, value) pairs.
func (r *AMD64Registers) Slice() []proc.Register { func (r *AMD64Registers) Slice(floatingPoint bool) []proc.Register {
var regs = []struct { var regs = []struct {
k string k string
v uint64 v uint64
@ -92,7 +92,9 @@ func (r *AMD64Registers) Slice() []proc.Register {
out = proc.AppendQwordReg(out, reg.k, reg.v) out = proc.AppendQwordReg(out, reg.k, reg.v)
} }
} }
if floatingPoint {
out = append(out, r.Fpregs...) out = append(out, r.Fpregs...)
}
return out return out
} }

View File

@ -42,7 +42,7 @@ type Regs struct {
fpregs []proc.Register fpregs []proc.Register
} }
func (r *Regs) Slice() []proc.Register { func (r *Regs) Slice(floatingPoint bool) []proc.Register {
var regs = []struct { var regs = []struct {
k string k string
v uint64 v uint64
@ -78,7 +78,9 @@ func (r *Regs) Slice() []proc.Register {
out = proc.AppendQwordReg(out, reg.k, reg.v) out = proc.AppendQwordReg(out, reg.k, reg.v)
} }
} }
if floatingPoint {
out = append(out, r.fpregs...) out = append(out, r.fpregs...)
}
return out return out
} }

View File

@ -23,7 +23,7 @@ type Registers interface {
// GAddr returns the address of the G variable if it is known, 0 and false otherwise // GAddr returns the address of the G variable if it is known, 0 and false otherwise
GAddr() (uint64, bool) GAddr() (uint64, bool)
Get(int) (uint64, error) Get(int) (uint64, error)
Slice() []Register Slice(floatingPoint bool) []Register
// Copy returns a copy of the registers that is guaranteed not to change // Copy returns a copy of the registers that is guaranteed not to change
// when the registers of the associated thread change. // when the registers of the associated thread change.
Copy() Registers Copy() Registers

View File

@ -79,7 +79,7 @@ func GetDwarfRegister(regs Registers, i int) []byte {
return buf.Bytes() return buf.Bytes()
} }
if regname, ok := dwarfToName[i]; ok { if regname, ok := dwarfToName[i]; ok {
regslice := regs.Slice() regslice := regs.Slice(true)
for _, reg := range regslice { for _, reg := range regslice {
if reg.Name == regname { if reg.Name == regname {
return reg.Bytes return reg.Bytes

View File

@ -74,7 +74,7 @@ func NewAMD64Registers(context *CONTEXT, TebBaseAddress uint64, floatingPoint bo
} }
// Slice returns the registers as a list of (name, value) pairs. // Slice returns the registers as a list of (name, value) pairs.
func (r *AMD64Registers) Slice() []proc.Register { func (r *AMD64Registers) Slice(floatingPoint bool) []proc.Register {
var regs = []struct { var regs = []struct {
k string k string
v uint64 v uint64
@ -103,7 +103,7 @@ func (r *AMD64Registers) Slice() []proc.Register {
{"TLS", r.tls}, {"TLS", r.tls},
} }
outlen := len(regs) outlen := len(regs)
if r.fltSave != nil { if r.fltSave != nil && floatingPoint {
outlen += 6 + 8 + 2 + 16 outlen += 6 + 8 + 2 + 16
} }
out := make([]proc.Register, 0, outlen) out := make([]proc.Register, 0, outlen)
@ -114,7 +114,7 @@ func (r *AMD64Registers) Slice() []proc.Register {
out = proc.AppendQwordReg(out, reg.k, reg.v) out = proc.AppendQwordReg(out, reg.k, reg.v)
} }
} }
if r.fltSave != nil { if r.fltSave != nil && floatingPoint {
out = proc.AppendWordReg(out, "CW", r.fltSave.ControlWord) out = proc.AppendWordReg(out, "CW", r.fltSave.ControlWord)
out = proc.AppendWordReg(out, "SW", r.fltSave.StatusWord) out = proc.AppendWordReg(out, "SW", r.fltSave.StatusWord)
out = proc.AppendWordReg(out, "TW", uint16(r.fltSave.TagWord)) out = proc.AppendWordReg(out, "TW", uint16(r.fltSave.TagWord))

View File

@ -847,3 +847,19 @@ func TestTruncateStacktrace(t *testing.T) {
} }
}) })
} }
func TestIssue1493(t *testing.T) {
// The 'regs' command without the '-a' option should only return
// general purpose registers.
withTestTerminal("continuetestprog", t, func(term *FakeTerminal) {
r := term.MustExec("regs")
nr := len(strings.Split(r, "\n"))
t.Logf("regs: %s", r)
ra := term.MustExec("regs -a")
nra := len(strings.Split(ra, "\n"))
t.Logf("regs -a: %s", ra)
if nr > nra/2 {
t.Fatalf("'regs' returned too many registers (%d) compared to 'regs -a' (%d)", nr, nra)
}
})
}

View File

@ -830,7 +830,7 @@ func (d *Debugger) Registers(threadID int, floatingPoint bool) (api.Registers, e
if err != nil { if err != nil {
return nil, err return nil, err
} }
return api.ConvertRegisters(regs.Slice()), err return api.ConvertRegisters(regs.Slice(floatingPoint)), err
} }
func convertVars(pv []*proc.Variable) []api.Variable { func convertVars(pv []*proc.Variable) []api.Variable {