Files
wazero/internal/engine/wazevo/backend/isa/arm64/machine_relocation.go
2024-04-01 14:42:09 +09:00

35 lines
1.2 KiB
Go

package arm64
import (
"fmt"
"github.com/tetratelabs/wazero/internal/engine/wazevo/backend"
"github.com/tetratelabs/wazero/internal/engine/wazevo/ssa"
)
// ResolveRelocations implements backend.Machine ResolveRelocations.
//
// TODO: unit test!
func (m *machine) ResolveRelocations(refToBinaryOffset map[ssa.FuncRef]int, binary []byte, relocations []backend.RelocationInfo) {
for _, r := range relocations {
instrOffset := r.Offset
calleeFnOffset := refToBinaryOffset[r.FuncRef]
brInstr := binary[instrOffset : instrOffset+4]
diff := int64(calleeFnOffset) - (instrOffset)
// Check if the diff is within the range of the branch instruction.
if diff < -(1<<25)*4 || diff > ((1<<25)-1)*4 {
panic(fmt.Sprintf("TODO: too large binary where branch target is out of the supported range +/-128MB: %#x", diff))
}
// https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/BL--Branch-with-Link-
imm26 := diff / 4
brInstr[0] = byte(imm26)
brInstr[1] = byte(imm26 >> 8)
brInstr[2] = byte(imm26 >> 16)
if diff < 0 {
brInstr[3] = (byte(imm26 >> 24 & 0b000000_01)) | 0b100101_10 // Set sign bit.
} else {
brInstr[3] = (byte(imm26 >> 24 & 0b000000_01)) | 0b100101_00 // No sign bit.
}
}
}