cmd/internal/obj/wasm: use 64-bit instructions for indirect calls

Currently, on Wasm, an indirect call is compiled to

	// function index = PC>>16, PC is already on stack
	I32WrapI64
	I32Const $16
	ShrU
	// set PC_B to 0
	...
	// actual call
	CallIndirect

Specifically, the function index is extracted from bits 16-31 of
the "PC". When there are more than 65536 functions, this will
overflow and wrap around, causing wrong function being called.

This CL changes it to use 64-bit operations to extract the
function index from the "PC", so there are enough bits to for it.

For #64856.

Change-Id: I83c11db4b78cf66250e88ac02a82bd13730a8914
Reviewed-on: https://go-review.googlesource.com/c/go/+/567896
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
This commit is contained in:
Cherry Mui 2024-02-29 14:27:57 -05:00
parent b4309ece66
commit c876bf9346

View file

@ -465,9 +465,9 @@ func preprocess(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) {
case obj.TYPE_NONE:
// (target PC is on stack)
p = appendp(p, AI64Const, constAddr(16)) // only needs PC_F bits (16-63), PC_B bits (0-15) are zero
p = appendp(p, AI64ShrU)
p = appendp(p, AI32WrapI64)
p = appendp(p, AI32Const, constAddr(16)) // only needs PC_F bits (16-31), PC_B bits (0-15) are zero
p = appendp(p, AI32ShrU)
// Set PC_B parameter to function entry.
// We need to push this before pushing the target PC_F,
@ -521,9 +521,9 @@ func preprocess(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) {
case obj.TYPE_NONE:
// (target PC is on stack)
p = appendp(p, AI64Const, constAddr(16)) // only needs PC_F bits (16-63), PC_B bits (0-15) are zero
p = appendp(p, AI64ShrU)
p = appendp(p, AI32WrapI64)
p = appendp(p, AI32Const, constAddr(16)) // only needs PC_F bits (16-31), PC_B bits (0-15) are zero
p = appendp(p, AI32ShrU)
// Set PC_B parameter to function entry.
// We need to push this before pushing the target PC_F,