From 86020cdd7a8204a0e900ebc14c8353f60159fdd0 Mon Sep 17 00:00:00 2001 From: Archana Ravindar Date: Thu, 14 Sep 2023 22:38:29 +0530 Subject: [PATCH] pkg/proc: Fix PIE tests on ppc64le port (#3498) * Fix PIE tests on ppc64le port * formatted ppc64le_disasm.go as part of fixing PIE tests for ppc64le port --- Documentation/backend_test_health.md | 2 -- pkg/proc/ppc64le_disasm.go | 10 ++++++++- pkg/proc/proc_test.go | 33 ++++++++++++++-------------- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/Documentation/backend_test_health.md b/Documentation/backend_test_health.md index e93bbce121..aa7cae7b46 100644 --- a/Documentation/backend_test_health.md +++ b/Documentation/backend_test_health.md @@ -20,8 +20,6 @@ Tests skipped by each supported backend: * 1 broken - cgo stacktraces * linux/ppc64le/native skipped = 1 * 1 broken in linux ppc64le -* linux/ppc64le/native/pie skipped = 11 - * 11 broken - pie mode * pie skipped = 2 * 2 upstream issue - https://github.com/golang/go/issues/29322 * ppc64le skipped = 11 diff --git a/pkg/proc/ppc64le_disasm.go b/pkg/proc/ppc64le_disasm.go index c3f9a72e3a..75b3add779 100644 --- a/pkg/proc/ppc64le_disasm.go +++ b/pkg/proc/ppc64le_disasm.go @@ -17,17 +17,25 @@ func init() { var tinyStacksplit = opcodeSeq{uint64(ppc64asm.ADDI), uint64(ppc64asm.CMPLD), uint64(ppc64asm.BC)} var smallStacksplit = opcodeSeq{uint64(ppc64asm.ADDI), uint64(ppc64asm.CMPLD), uint64(ppc64asm.BC)} var bigStacksplit = opcodeSeq{uint64(ppc64asm.ADDI), uint64(ppc64asm.CMPLD), uint64(ppc64asm.BC), uint64(ppc64asm.STD), uint64(ppc64asm.STD), uint64(ppc64asm.MFSPR)} + var adjustTOCPrologueOnPIE = opcodeSeq{uint64(ppc64asm.ADDIS), uint64(ppc64asm.ADDI)} var unixGetG = opcodeSeq{uint64(ppc64asm.LD)} + var prologue opcodeSeq prologuesPPC64LE = make([]opcodeSeq, 0, 3) + prologue = make(opcodeSeq, 0, 1) for _, getG := range []opcodeSeq{unixGetG} { for _, stacksplit := range []opcodeSeq{tinyStacksplit, smallStacksplit, bigStacksplit} { - prologue := make(opcodeSeq, 0, len(getG)+len(stacksplit)) prologue = append(prologue, getG...) prologue = append(prologue, stacksplit...) prologuesPPC64LE = append(prologuesPPC64LE, prologue) } } + // On PIE mode special prologue is generated two instructions before the function entry point that correlates to call target + // address, Teach delve to recognize this sequence to appropriately adjust PC address so that the breakpoint is actually hit + // while doing step + TOCprologue := make(opcodeSeq, 0, len(adjustTOCPrologueOnPIE)) + TOCprologue = append(TOCprologue, adjustTOCPrologueOnPIE...) + prologuesPPC64LE = append(prologuesPPC64LE, TOCprologue) } func ppc64leAsmDecode(asmInst *AsmInstruction, mem []byte, regs *op.DwarfRegisters, memrw MemoryReadWriter, bi *BinaryInfo) error { diff --git a/pkg/proc/proc_test.go b/pkg/proc/proc_test.go index 8e4010624e..6de1ba1b60 100644 --- a/pkg/proc/proc_test.go +++ b/pkg/proc/proc_test.go @@ -905,7 +905,6 @@ func (l1 *loc) match(l2 proc.Stackframe) bool { } func TestStacktrace(t *testing.T) { - skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") stacks := [][]loc{ {{4, "main.stacktraceme"}, {8, "main.func1"}, {16, "main.main"}}, {{4, "main.stacktraceme"}, {8, "main.func1"}, {12, "main.func2"}, {17, "main.main"}}, @@ -990,7 +989,6 @@ func stackMatch(stack []loc, locations []proc.Stackframe, skipRuntime bool) bool func TestStacktraceGoroutine(t *testing.T) { skipOn(t, "broken - cgo stacktraces", "darwin", "arm64") - skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") mainStack := []loc{{14, "main.stacktraceme"}, {29, "main.main"}} if goversion.VersionAfterOrEqual(runtime.Version(), 1, 11) { @@ -1315,7 +1313,6 @@ func TestVariableEvaluation(t *testing.T) { } func TestFrameEvaluation(t *testing.T) { - skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") protest.AllowRecording(t) lenient := false if runtime.GOOS == "windows" { @@ -2308,7 +2305,6 @@ func TestNextDeferReturnAndDirectCall(t *testing.T) { } func TestNextPanicAndDirectCall(t *testing.T) { - skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") // Next should not step into a deferred function if it is called // directly, only if it is called through a panic or a deferreturn. // Here we test the case where the function is called by a panic @@ -2326,7 +2322,6 @@ func TestStepCall(t *testing.T) { } func TestStepCallPtr(t *testing.T) { - skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") // Tests that Step works correctly when calling functions with a // function pointer. if goversion.VersionAfterOrEqual(runtime.Version(), 1, 11) && !protest.RegabiSupported() { @@ -2336,17 +2331,26 @@ func TestStepCallPtr(t *testing.T) { {6, 7}, {7, 11}}, "", t) } else { - testseq("teststepprog", contStep, []nextTest{ - {9, 10}, - {10, 5}, - {5, 6}, - {6, 7}, - {7, 11}}, "", t) + if runtime.GOOS == "linux" && runtime.GOARCH == "ppc64le" && buildMode == "pie" { + testseq("teststepprog", contStep, []nextTest{ + {9, 10}, + {10, 5}, + {5, 6}, + {6, 7}, + {7, 10}, + {10, 11}}, "", t) + } else { + testseq("teststepprog", contStep, []nextTest{ + {9, 10}, + {10, 5}, + {5, 6}, + {6, 7}, + {7, 11}}, "", t) + } } } func TestStepReturnAndPanic(t *testing.T) { - skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") // Tests that Step works correctly when returning from functions // and when a deferred function is called when panic'ing. testseq("defercall", contStep, []nextTest{ @@ -2358,7 +2362,6 @@ func TestStepReturnAndPanic(t *testing.T) { } func TestStepDeferReturn(t *testing.T) { - skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") // Tests that Step works correctly when a deferred function is // called during a return. testseq("defercall", contStep, []nextTest{ @@ -2373,7 +2376,6 @@ func TestStepDeferReturn(t *testing.T) { } func TestStepIgnorePrivateRuntime(t *testing.T) { - skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") // Tests that Step will ignore calls to private runtime functions // (such as runtime.convT2E in this case) switch { @@ -2752,7 +2754,6 @@ func TestIssue594(t *testing.T) { } func TestStepOutPanicAndDirectCall(t *testing.T) { - skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") // StepOut should not step into a deferred function if it is called // directly, only if it is called through a panic. // Here we test the case where the function is called by a panic @@ -5569,7 +5570,6 @@ func TestManualStopWhileStopped(t *testing.T) { } func TestDwrapStartLocation(t *testing.T) { - skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") // Tests that the start location of a goroutine is unwrapped in Go 1.17 and later. withTestProcess("goroutinestackprog", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { setFunctionBreakpoint(p, t, "main.stacktraceme") @@ -6071,7 +6071,6 @@ func TestEscapeCheckUnreadable(t *testing.T) { } func TestStepShadowConcurrentBreakpoint(t *testing.T) { - skipOn(t, "broken - pie mode", "linux", "ppc64le", "native", "pie") // Checks that a StepBreakpoint can not shadow a concurrently hit user breakpoint withTestProcess("stepshadow", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { break2 := setFunctionBreakpoint(p, t, "main.stacktraceme2")