blob: 41e86e4d07ef9fd89ae4b8ad236174d7aad687e8 [file] [log] [blame]
# Verify PPC64 does not reuse a trampoline which is too far away.
# This tests an edge case where the direct call relocation addend should
# be ignored when computing the distance from the direct call to the
# already placed trampoline
[short] skip
[!GOARCH:ppc64] [!GOARCH:ppc64le] skip
[GOOS:aix] skip
# Note, this program does not run. Presumably, 'DWORD $0' is simpler to
# assembly 2^26 or so times.
#
# We build something which should be laid out as such:
#
# bar.Bar
# main.Func1
# bar.Bar+400-tramp0
# main.BigAsm
# main.Func2
# bar.Bar+400-tramp1
#
# bar.Bar needs to be placed far enough away to generate relocations
# from main package calls. and main.Func1 and main.Func2 are placed
# a bit more than the direct call limit apart, but not more than 0x400
# bytes beyond it (to verify the reloc calc).
go build
-- go.mod --
module foo
go 1.19
-- main.go --
package main
import "foo/bar"
func Func1()
func main() {
Func1()
bar.Bar2()
}
-- foo.s --
TEXT main·Func1(SB),0,$0-0
CALL bar·Bar+0x400(SB)
CALL main·BigAsm(SB)
// A trampoline will be placed here to bar.Bar
// This creates a gap sufficiently large to prevent trampoline reuse
#define NOP64 DWORD $0; DWORD $0; DWORD $0; DWORD $0; DWORD $0; DWORD $0; DWORD $0; DWORD $0;
#define NOP256 NOP64 NOP64 NOP64 NOP64
#define NOP2S10 NOP256 NOP256 NOP256 NOP256
#define NOP2S12 NOP2S10 NOP2S10 NOP2S10 NOP2S10
#define NOP2S14 NOP2S12 NOP2S12 NOP2S12 NOP2S12
#define NOP2S16 NOP2S14 NOP2S14 NOP2S14 NOP2S14
#define NOP2S18 NOP2S16 NOP2S16 NOP2S16 NOP2S16
#define NOP2S20 NOP2S18 NOP2S18 NOP2S18 NOP2S18
#define NOP2S22 NOP2S20 NOP2S20 NOP2S20 NOP2S20
#define NOP2S24 NOP2S22 NOP2S22 NOP2S22 NOP2S22
#define BIGNOP NOP2S24 NOP2S24
TEXT main·BigAsm(SB),0,$0-0
// Fill to the direct call limit so Func2 must generate a new trampoline.
// As the implicit trampoline above is just barely unreachable.
BIGNOP
MOVD $main·Func2(SB), R3
TEXT main·Func2(SB),0,$0-0
CALL bar·Bar+0x400(SB)
// Another trampoline should be placed here.
-- bar/bar.s --
#define NOP64 DWORD $0; DWORD $0; DWORD $0; DWORD $0; DWORD $0; DWORD $0; DWORD $0; DWORD $0;
#define NOP256 NOP64 NOP64 NOP64 NOP64
#define NOP2S10 NOP256 NOP256 NOP256 NOP256
#define NOP2S12 NOP2S10 NOP2S10 NOP2S10 NOP2S10
#define NOP2S14 NOP2S12 NOP2S12 NOP2S12 NOP2S12
#define NOP2S16 NOP2S14 NOP2S14 NOP2S14 NOP2S14
#define NOP2S18 NOP2S16 NOP2S16 NOP2S16 NOP2S16
#define NOP2S20 NOP2S18 NOP2S18 NOP2S18 NOP2S18
#define NOP2S22 NOP2S20 NOP2S20 NOP2S20 NOP2S20
#define NOP2S24 NOP2S22 NOP2S22 NOP2S22 NOP2S22
#define BIGNOP NOP2S24 NOP2S24 NOP2S10
// A very big not very interesting function.
TEXT bar·Bar(SB),0,$0-0
BIGNOP
-- bar/bar.go --
package bar
func Bar()
func Bar2() {
}