proc/gdbserver: fix function call injection on rr (#3007)

Issue https://github.com/rr-debugger/rr/issues/3208 was fixed so finish
fixing call injection on rr and remove the test exception.
This commit is contained in:
Alessandro Arzilli 2022-05-17 18:19:34 +02:00 committed by GitHub
parent b53fcbe43a
commit 32bdd19f8f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 21 deletions

@ -1958,27 +1958,61 @@ func (t *gdbThread) SetReg(regNum uint64, reg *op.DwarfRegister) error {
if !ok && t.p.bi.Arch.Name == "arm64" && regName == "x30" {
gdbreg, ok = t.regs.regs["lr"]
}
if !ok && regName == "rflags" {
// rr has eflags instead of rflags
regName = "eflags"
gdbreg, ok = t.regs.regs[regName]
if ok {
reg.FillBytes()
reg.Bytes = reg.Bytes[:4]
}
}
if !ok {
return fmt.Errorf("could not set register %s: not found", regName)
}
reg.FillBytes()
if len(reg.Bytes) != len(gdbreg.value) {
return fmt.Errorf("could not set register %s: wrong size, expected %d got %d", regName, len(gdbreg.value), len(reg.Bytes))
wrongSizeErr := func(n int) error {
return fmt.Errorf("could not set register %s: wrong size, expected %d got %d", regName, n, len(reg.Bytes))
}
copy(gdbreg.value, reg.Bytes)
err := t.p.conn.writeRegister(t.strID, gdbreg.regnum, gdbreg.value)
if err != nil {
return err
}
if t.p.conn.workaroundReg != nil && len(gdbreg.value) > 16 {
// This is a workaround for a bug in debugserver where register writes (P
// packet) on AVX-2 and AVX-512 registers are ignored unless they are
// followed by a write to an AVX register.
// See:
// Issue #2767
// https://bugs.llvm.org/show_bug.cgi?id=52362
reg := t.regs.gdbRegisterNew(t.p.conn.workaroundReg)
return t.p.conn.writeRegister(t.strID, reg.regnum, reg.value)
if len(reg.Bytes) == len(gdbreg.value) {
copy(gdbreg.value, reg.Bytes)
err := t.p.conn.writeRegister(t.strID, gdbreg.regnum, gdbreg.value)
if err != nil {
return err
}
if t.p.conn.workaroundReg != nil && len(gdbreg.value) > 16 {
// This is a workaround for a bug in debugserver where register writes (P
// packet) on AVX-2 and AVX-512 registers are ignored unless they are
// followed by a write to an AVX register.
// See:
// Issue #2767
// https://bugs.llvm.org/show_bug.cgi?id=52362
reg := t.regs.gdbRegisterNew(t.p.conn.workaroundReg)
return t.p.conn.writeRegister(t.strID, reg.regnum, reg.value)
}
} else if len(reg.Bytes) == 2*len(gdbreg.value) && strings.HasPrefix(regName, "xmm") {
// rr uses xmmN for the low part of the register and ymmNh for the high part
gdbregh, ok := t.regs.regs["y"+regName[1:]+"h"]
if !ok {
return wrongSizeErr(len(gdbreg.value))
}
if len(reg.Bytes) != len(gdbreg.value)+len(gdbregh.value) {
return wrongSizeErr(len(gdbreg.value) + len(gdbregh.value))
}
copy(gdbreg.value, reg.Bytes[:len(gdbreg.value)])
copy(gdbregh.value, reg.Bytes[len(gdbreg.value):])
err := t.p.conn.writeRegister(t.strID, gdbreg.regnum, gdbreg.value)
if err != nil {
return err
}
err = t.p.conn.writeRegister(t.strID, gdbregh.regnum, gdbregh.value)
if err != nil {
return err
}
} else {
return wrongSizeErr(len(gdbreg.value))
}
return nil
}

@ -5860,6 +5860,7 @@ func TestCallInjectionFlagCorruption(t *testing.T) {
// time, after stepping out of debugCallV2.
// Fixes issue https://github.com/go-delve/delve/issues/2985
skipUnlessOn(t, "not relevant", "amd64")
protest.MustSupportFunctionCalls(t, testBackend)
withTestProcessArgs("badflags", t, ".", []string{"0"}, 0, func(p *proc.Target, fixture protest.Fixture) {
mainfn := p.BinInfo().LookupFunc["main.main"]

@ -1340,11 +1340,6 @@ func TestCallFunction(t *testing.T) {
if goversion.VersionAfterOrEqual(runtime.Version(), 1, 17) {
for _, tc := range testcases117 {
if strings.Contains(tc.expr, "floatsum") && testBackend == "rr" {
// Can not set floating point registers with RR.
// See: https://github.com/rr-debugger/rr/issues/3208
continue
}
testCallFunction(t, p, tc)
}
}