Skip to content

Commit

Permalink
Merge pull request #33 from bytedance/fix/x10
Browse files Browse the repository at this point in the history
fix: use x19 register(arm64) for BR instruction
  • Loading branch information
Sychorius authored Aug 14, 2023
2 parents 784cc5e + 6b1e323 commit 3ffd172
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 2 deletions.
9 changes: 7 additions & 2 deletions internal/monkey/inst/inst_arm64.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,15 @@ func BranchTo(to uintptr) (res []byte) {
return
}

// create a branch into command
//
// Go supports passing function arguments from go 1.17 (see https://go.dev/doc/go1.17).
// We could not use x0~x18 register. As an alternative, we use R19 register (see https://go.googlesource.com/go/+/refs/heads/master/src/cmd/compile/abi-internal.md).
func BranchInto(to uintptr) (res []byte) {
// do not use x0~x18
res = append(res, x26MOV(to)...) // MOV x26, to // fake
res = append(res, []byte{0x4a, 0x03, 0x40, 0xf9}...) // LDR x10, [x26]
res = append(res, []byte{0x40, 0x01, 0x1f, 0xd6}...) // BR x10
res = append(res, []byte{0x53, 0x03, 0x40, 0xf9}...) // LDR x19, [x26]
res = append(res, []byte{0x60, 0x02, 0x1f, 0xd6}...) // BR x19
return
}

Expand Down
36 changes: 36 additions & 0 deletions mock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -385,3 +385,39 @@ func TestMockOrigin(t *testing.T) {
So((&foo{3}).Foo(), ShouldEqual, 4)
})
}

func TestMultiArgs(t *testing.T) {
PatchConvey("multi-arg-result", t, func() {
PatchConvey("multi-arg", func() {
// Go supports passing function arguments from go 1.17
//
// Mockey used to use X10 register to make BR instruction in
// arm64, which will cause arguments and results get a wrong value
//
// _0~_15 use x0~x15 register
fn := func(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20 int64) {
fmt.Println(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20)
}
ori := fn
Mock(fn).To(func(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20 int64) {
for _, _x := range []int64{_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20} {
So(_x, ShouldEqual, 0)
}
}).Origin(&ori).Build()
fn(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
})
PatchConvey("multi-result", func() {
fn := func() (_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20 int64) {
return 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}
ori := fn
Mock(fn).To(func() (_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20 int64) {
return ori()
}).Origin(&ori).Build()
_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20 := fn()
for _, _x := range []int64{_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20} {
So(_x, ShouldEqual, 0)
}
})
})
}

0 comments on commit 3ffd172

Please sign in to comment.