From 14aeea2bd956f989690cc98f89f90dfe811d2090 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Tue, 26 Feb 2019 17:53:45 +0100 Subject: [PATCH] proc/gdbserial: do not return floating point regs when not requested (#1497) Fixes #1493 --- pkg/proc/arch.go | 2 +- pkg/proc/core/core_test.go | 6 +++--- pkg/proc/gdbserial/gdbserver.go | 14 +++++++++++--- pkg/proc/gdbserial/gdbserver_conn.go | 3 ++- pkg/proc/linutil/regs.go | 6 ++++-- pkg/proc/native/registers_darwin_amd64.go | 6 ++++-- pkg/proc/registers.go | 2 +- pkg/proc/registers_amd64.go | 2 +- pkg/proc/winutil/regs.go | 6 +++--- pkg/terminal/command_test.go | 16 ++++++++++++++++ service/debugger/debugger.go | 2 +- 11 files changed, 47 insertions(+), 18 deletions(-) diff --git a/pkg/proc/arch.go b/pkg/proc/arch.go index 0a460eb5..cdb20e70 100644 --- a/pkg/proc/arch.go +++ b/pkg/proc/arch.go @@ -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 { if regName == reg.Name { dregs[dwarfReg] = op.DwarfRegisterFromBytes(reg.Bytes) diff --git a/pkg/proc/core/core_test.go b/pkg/proc/core/core_test.go index d6f97d53..68eeb1c4 100644 --- a/pkg/proc/core/core_test.go +++ b/pkg/proc/core/core_test.go @@ -242,7 +242,7 @@ func TestCore(t *testing.T) { if err != nil { t.Fatalf("Couldn't get current thread registers: %v", err) } - regslice := regs.Slice() + regslice := regs.Slice(true) for _, reg := range regslice { t.Logf("%s = %s", reg.Name, reg.Value) } @@ -311,13 +311,13 @@ func TestCoreFpRegisters(t *testing.T) { {"XMM8", "0x4059999a404ccccd4059999a404ccccd"}, } - for _, reg := range regs.Slice() { + for _, reg := range regs.Slice(true) { t.Logf("%s = %s", reg.Name, reg.Value) } for _, regtest := range regtests { found := false - for _, reg := range regs.Slice() { + for _, reg := range regs.Slice(true) { if reg.Name == regtest.name { found = true if !strings.HasPrefix(reg.Value, regtest.value) { diff --git a/pkg/proc/gdbserial/gdbserver.go b/pkg/proc/gdbserial/gdbserver.go index a192ce93..e73f5c3b 100644 --- a/pkg/proc/gdbserial/gdbserver.go +++ b/pkg/proc/gdbserial/gdbserver.go @@ -1826,9 +1826,12 @@ func (t *Thread) SetDX(dx uint64) error { 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)) for _, reginfo := range regs.regsInfo { + if reginfo.Group == "float" && !floatingPoint { + continue + } switch { case reginfo.Name == "eflags": 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: r = proc.AppendQwordReg(r, reginfo.Name, binary.LittleEndian.Uint64(regs.regs[reginfo.Name].value)) case reginfo.Bitsize == 80: + if !floatingPoint { + continue + } idx := 0 for _, stprefix := range []string{"stmm", "st"} { 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])) case reginfo.Bitsize == 128: - r = proc.AppendSSEReg(r, strings.ToUpper(reginfo.Name), regs.regs[reginfo.Name].value) + if floatingPoint { + r = proc.AppendSSEReg(r, strings.ToUpper(reginfo.Name), regs.regs[reginfo.Name].value) + } case reginfo.Bitsize == 256: - if !strings.HasPrefix(strings.ToLower(reginfo.Name), "ymm") { + if !strings.HasPrefix(strings.ToLower(reginfo.Name), "ymm") || !floatingPoint { continue } diff --git a/pkg/proc/gdbserial/gdbserver_conn.go b/pkg/proc/gdbserial/gdbserver_conn.go index c5f14613..107f9d81 100644 --- a/pkg/proc/gdbserial/gdbserver_conn.go +++ b/pkg/proc/gdbserial/gdbserver_conn.go @@ -227,7 +227,8 @@ type gdbRegisterInfo struct { Name string `xml:"name,attr"` Bitsize int `xml:"bitsize,attr"` 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, diff --git a/pkg/proc/linutil/regs.go b/pkg/proc/linutil/regs.go index 5c63d4aa..d20a0103 100644 --- a/pkg/proc/linutil/regs.go +++ b/pkg/proc/linutil/regs.go @@ -51,7 +51,7 @@ type AMD64PtraceRegs struct { } // 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 { k string v uint64 @@ -92,7 +92,9 @@ func (r *AMD64Registers) Slice() []proc.Register { out = proc.AppendQwordReg(out, reg.k, reg.v) } } - out = append(out, r.Fpregs...) + if floatingPoint { + out = append(out, r.Fpregs...) + } return out } diff --git a/pkg/proc/native/registers_darwin_amd64.go b/pkg/proc/native/registers_darwin_amd64.go index ea873448..fec7066d 100644 --- a/pkg/proc/native/registers_darwin_amd64.go +++ b/pkg/proc/native/registers_darwin_amd64.go @@ -42,7 +42,7 @@ type Regs struct { fpregs []proc.Register } -func (r *Regs) Slice() []proc.Register { +func (r *Regs) Slice(floatingPoint bool) []proc.Register { var regs = []struct { k string v uint64 @@ -78,7 +78,9 @@ func (r *Regs) Slice() []proc.Register { out = proc.AppendQwordReg(out, reg.k, reg.v) } } - out = append(out, r.fpregs...) + if floatingPoint { + out = append(out, r.fpregs...) + } return out } diff --git a/pkg/proc/registers.go b/pkg/proc/registers.go index 17ee1323..77765239 100644 --- a/pkg/proc/registers.go +++ b/pkg/proc/registers.go @@ -23,7 +23,7 @@ type Registers interface { // GAddr returns the address of the G variable if it is known, 0 and false otherwise GAddr() (uint64, bool) Get(int) (uint64, error) - Slice() []Register + Slice(floatingPoint bool) []Register // Copy returns a copy of the registers that is guaranteed not to change // when the registers of the associated thread change. Copy() Registers diff --git a/pkg/proc/registers_amd64.go b/pkg/proc/registers_amd64.go index fac817a1..8ef4658a 100644 --- a/pkg/proc/registers_amd64.go +++ b/pkg/proc/registers_amd64.go @@ -79,7 +79,7 @@ func GetDwarfRegister(regs Registers, i int) []byte { return buf.Bytes() } if regname, ok := dwarfToName[i]; ok { - regslice := regs.Slice() + regslice := regs.Slice(true) for _, reg := range regslice { if reg.Name == regname { return reg.Bytes diff --git a/pkg/proc/winutil/regs.go b/pkg/proc/winutil/regs.go index c8a3619b..79c4fb3a 100644 --- a/pkg/proc/winutil/regs.go +++ b/pkg/proc/winutil/regs.go @@ -74,7 +74,7 @@ func NewAMD64Registers(context *CONTEXT, TebBaseAddress uint64, floatingPoint bo } // 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 { k string v uint64 @@ -103,7 +103,7 @@ func (r *AMD64Registers) Slice() []proc.Register { {"TLS", r.tls}, } outlen := len(regs) - if r.fltSave != nil { + if r.fltSave != nil && floatingPoint { outlen += 6 + 8 + 2 + 16 } out := make([]proc.Register, 0, outlen) @@ -114,7 +114,7 @@ func (r *AMD64Registers) Slice() []proc.Register { 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, "SW", r.fltSave.StatusWord) out = proc.AppendWordReg(out, "TW", uint16(r.fltSave.TagWord)) diff --git a/pkg/terminal/command_test.go b/pkg/terminal/command_test.go index 364ab1e3..e6ffbf6f 100644 --- a/pkg/terminal/command_test.go +++ b/pkg/terminal/command_test.go @@ -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) + } + }) +} diff --git a/service/debugger/debugger.go b/service/debugger/debugger.go index ce9acac1..059f556c 100644 --- a/service/debugger/debugger.go +++ b/service/debugger/debugger.go @@ -830,7 +830,7 @@ func (d *Debugger) Registers(threadID int, floatingPoint bool) (api.Registers, e if err != nil { return nil, err } - return api.ConvertRegisters(regs.Slice()), err + return api.ConvertRegisters(regs.Slice(floatingPoint)), err } func convertVars(pv []*proc.Variable) []api.Variable {