Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
derekparker committed Oct 28, 2022
1 parent 5548cef commit d972b85
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 22 deletions.
1 change: 1 addition & 0 deletions pkg/dwarf/regnum/ppc64le.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ var PPC64LENameToDwarf = func() map[string]int {

r["nip"] = PPC64LE_PC
r["sp"] = PPC64LE_SP
r["bp"] = PPC64LE_SP
r["link"] = PPC64LE_LR

// General Purpose Registers: from R0 to R31
Expand Down
3 changes: 2 additions & 1 deletion pkg/proc/linutil/regs_ppc64le_arch.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package linutil

import (
"fmt"

"github.com/go-delve/delve/pkg/proc"
)

Expand Down Expand Up @@ -85,7 +86,7 @@ func (r *PPC64LERegisters) LR() uint64 {
}

func (r *PPC64LERegisters) BP() uint64 {
return r.Regs.Gpr[30]
return r.Regs.Gpr[1]
}

// TLS returns the value of the thread pointer stored in Gpr[13]
Expand Down
32 changes: 18 additions & 14 deletions pkg/proc/ppc64le_arch.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ func ppc64leFixFrameUnwindContext(fctxt *frame.FrameContext, pc uint64, bi *Bina
a.sigreturnfn = bi.LookupFunc["runtime.sigreturn"]
}
if fctxt == nil || (a.sigreturnfn != nil && pc >= a.sigreturnfn.Entry && pc < a.sigreturnfn.End) {
fmt.Println("nil frame context")
return &frame.FrameContext{
RetAddrReg: regnum.PPC64LE_PC,
RetAddrReg: regnum.PPC64LE_LR,
Regs: map[uint64]frame.DWRule{
regnum.PPC64LE_PC: {
Rule: frame.RuleOffset,
Expand Down Expand Up @@ -77,7 +78,7 @@ func ppc64leFixFrameUnwindContext(fctxt *frame.FrameContext, pc uint64, bi *Bina

// Checks if we marked the function as a crosscall and if we are currently in it
if a.crosscall2fn != nil && pc >= a.crosscall2fn.Entry && pc < a.crosscall2fn.End {
fmt.Println("------------ Crosscall2")
fmt.Println("------------- crosscall2")
rule := fctxt.CFA
if rule.Offset == crosscall2SPOffsetBad {
// Linux support only
Expand All @@ -95,17 +96,14 @@ func ppc64leFixFrameUnwindContext(fctxt *frame.FrameContext, pc uint64, bi *Bina
return fctxt
}

const ppc64cgocallSPOffsetSaveSlot = 0x20
const ppc64prevG0schedSPOffsetSaveSlot = 0x18
const ppc64cgocallSPOffsetSaveSlot = 32
const ppc64prevG0schedSPOffsetSaveSlot = 40

// TODO(alexsaezm) Review this method
func ppc64leSwitchStack(it *stackIterator, callFrameRegs *op.DwarfRegisters) bool {
if it.frame.Current.Fn == nil {
if it.systemstack && it.g != nil && it.top {
it.switchToGoroutineStack()
return true
}
return false
if it.frame.Current.Fn == nil && it.systemstack && it.g != nil && it.top {
it.switchToGoroutineStack()
return true
}
if it.frame.Current.Fn != nil {
switch it.frame.Current.Fn.Name {
Expand All @@ -119,7 +117,9 @@ func ppc64leSwitchStack(it *stackIterator, callFrameRegs *op.DwarfRegisters) boo
//The offsets get from runtime/cgo/asm_ppc64x.s:10
newsp, _ := readUintRaw(it.mem, it.regs.SP()+8*24, int64(it.bi.Arch.PtrSize()))
newbp, _ := readUintRaw(it.mem, it.regs.SP()+8*14, int64(it.bi.Arch.PtrSize()))
newlr, _ := readUintRaw(it.mem, it.regs.SP()+8*16, int64(it.bi.Arch.PtrSize()))
newlr, _ := readUintRaw(it.mem, it.regs.SP()+16, int64(it.bi.Arch.PtrSize()))
panic("crosscall2")
fmt.Println("crosscall2", it.regs.SP(), newsp, newbp, newlr)
if it.regs.Reg(it.regs.BPRegNum) != nil {
it.regs.Reg(it.regs.BPRegNum).Uint64Val = newbp
} else {
Expand Down Expand Up @@ -150,6 +150,7 @@ func ppc64leSwitchStack(it *stackIterator, callFrameRegs *op.DwarfRegisters) boo
}
switch fn.Name {
case "runtime.asmcgocall":
fmt.Println("entering runtime.asmcgocall branch")
if !it.systemstack {
return false
}
Expand All @@ -158,11 +159,14 @@ func ppc64leSwitchStack(it *stackIterator, callFrameRegs *op.DwarfRegisters) boo
// switches from the goroutine stack to the system stack.
// Since we are unwinding the stack from callee to caller we have to switch
// from the system stack to the goroutine stack.
off, _ := readIntRaw(it.mem, callFrameRegs.SP()+ppc64cgocallSPOffsetSaveSlot, int64(it.bi.Arch.PtrSize()))
off, _ := readIntRaw(it.mem,
callFrameRegs.SP()+ppc64cgocallSPOffsetSaveSlot,
int64(it.bi.Arch.PtrSize()))
fmt.Printf("OFFSET: %x\n", off)
oldsp := callFrameRegs.SP()
newsp := uint64(int64(it.stackhi) - off)
fmt.Printf("oldsp %x newsp %x\n", oldsp, newsp)

fmt.Printf("asmcgocall %x %x\n", oldsp, newsp)
// runtime.asmcgocall can also be called from inside the system stack,
// in that case no stack switch actually happens
if newsp == oldsp {
Expand Down Expand Up @@ -214,7 +218,7 @@ func ppc64leRegSize(rn uint64) int {

func ppc64leRegistersToDwarfRegisters(staticBase uint64, regs Registers) *op.DwarfRegisters {
dregs := initDwarfRegistersFromSlice(int(regnum.PPC64LEMaxRegNum()), regs, regnum.PPC64LENameToDwarf)
dr := op.NewDwarfRegisters(staticBase, dregs, binary.LittleEndian, regnum.PPC64LE_PC, regnum.PPC64LE_SP, 0, regnum.PPC64LE_LR)
dr := op.NewDwarfRegisters(staticBase, dregs, binary.LittleEndian, regnum.PPC64LE_PC, regnum.PPC64LE_SP, regnum.PPC64LE_SP, regnum.PPC64LE_LR)
dr.SetLoadMoreCallback(loadMoreDwarfRegistersFromSliceFunc(dr, regs, regnum.PPC64LENameToDwarf))
return dr
}
Expand Down
7 changes: 6 additions & 1 deletion pkg/proc/proc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3321,7 +3321,11 @@ func logStacktrace(t *testing.T, p *proc.Target, frames []proc.Stackframe) {
name = fmt.Sprintf("%s inlined in %s", frames[j].Call.Fn.Name, frames[j].Current.Fn.Name)
}

t.Logf("\t%#x %#x %#x %s at %s:%d\n", frames[j].Call.PC, frames[j].FrameOffset(), frames[j].FramePointerOffset(), name, filepath.Base(frames[j].Call.File), frames[j].Call.Line)
t.Logf("\t%#x %#x %#x %s at %s:%d\n",
frames[j].Call.PC,
frames[j].FrameOffset(),
frames[j].FramePointerOffset(),
name, filepath.Base(frames[j].Call.File), frames[j].Call.Line)
if frames[j].TopmostDefer != nil {
_, _, fn := frames[j].TopmostDefer.DeferredFunc(p)
fnname := ""
Expand Down Expand Up @@ -3414,6 +3418,7 @@ func TestCgoStacktrace(t *testing.T) {

skipOn(t, "broken - cgo stacktraces", "386")
skipOn(t, "broken - cgo stacktraces", "linux", "arm64")
skipOn(t, "broken - cgo stacktraces", "linux", "ppc64le")
protest.MustHaveCgo(t)

// Tests that:
Expand Down
10 changes: 4 additions & 6 deletions pkg/proc/stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,15 +230,9 @@ func (it *stackIterator) Next() bool {
return false
}
it.frame = it.newStackframe(ret, retaddr)
fn := ""
if it.frame.Current.Fn != nil {
fn = it.frame.Current.Fn.Name
}
fmt.Printf("frame: %q %#v\n", fn, it.frame.Current)

if it.opts&StacktraceSimple == 0 {
if it.bi.Arch.switchStack(it, &callFrameRegs) {
fmt.Println("SWITCHED LE STACK")
return true
}
}
Expand Down Expand Up @@ -429,6 +423,9 @@ func (it *stackIterator) appendInlineCalls(frames []Stackframe, frame Stackframe
// it.regs.CFA; the caller has to eventually switch it.regs when the iterator
// advances to the next frame.
func (it *stackIterator) advanceRegs() (callFrameRegs op.DwarfRegisters, ret uint64, retaddr uint64) {
if it.frame.Current.Fn != nil {
fmt.Println("fname", it.frame.Current.Fn.Name)
}
fde, err := it.bi.frameEntries.FDEForPC(it.pc)
var framectx *frame.FrameContext
if _, nofde := err.(*frame.ErrNoFDEForPC); nofde {
Expand Down Expand Up @@ -491,6 +488,7 @@ func (it *stackIterator) advanceRegs() (callFrameRegs op.DwarfRegisters, ret uin
}

func (it *stackIterator) executeFrameRegRule(regnum uint64, rule frame.DWRule, cfa int64) (*op.DwarfRegister, error) {
// fmt.Printf("executeFrameRegRule: regnum=%d, rule=%v, cfa=%d\n", regnum, rule, cfa)
switch rule.Rule {
default:
fallthrough
Expand Down

0 comments on commit d972b85

Please sign in to comment.