package sbf import ( "encoding/binary" "github.com/spaolacci/murmur3" ) const ( // EntrypointHash equals SymbolHash("entrypoint") EntrypointHash = uint32(0x71e3cf81) ) // SymbolHash returns the murmur3 32-bit hash of a symbol name. func SymbolHash(s string) uint32 { return murmur3.Sum32([]byte(s)) } // PCHash returns the murmur3 32-bit hash of a program counter. // // Used by VM for non-syscall functions func PCHash(addr uint64) uint32 { // TODO this is kinda pointless … var key [8]byte binary.LittleEndian.PutUint64(key[:], addr) return murmur3.Sum32(key[:]) } // Syscall are callback handles from VM to Go. (work in progress) type Syscall interface { Invoke(vm VM, r1, r2, r3, r4, r5 uint64, cuIn int) (r0 uint64, cuOut int, err error) } type SyscallRegistry map[uint32]Syscall func NewSyscallRegistry() SyscallRegistry { return make(SyscallRegistry) } func (s SyscallRegistry) Register(name string, syscall Syscall) (hash uint32, ok bool) { hash = SymbolHash(name) if _, exist := s[hash]; exist { return 0, false // collision or duplicate } s[hash] = syscall ok = true return } // Convenience Methods type SyscallFunc0 func(vm VM, cuIn int) (r0 uint64, cuOut int, err error) func (f SyscallFunc0) Invoke(vm VM, _, _, _, _, _ uint64, cuIn int) (r0 uint64, cuOut int, err error) { return f(vm, cuIn) } type SyscallFunc1 func(vm VM, r1 uint64, cuIn int) (r0 uint64, cuOut int, err error) func (f SyscallFunc1) Invoke(vm VM, r1, _, _, _, _ uint64, cuIn int) (r0 uint64, cuOut int, err error) { return f(vm, r1, cuIn) } type SyscallFunc2 func(vm VM, r1, r2 uint64, cuIn int) (r0 uint64, cuOut int, err error) func (f SyscallFunc2) Invoke(vm VM, r1, r2, _, _, _ uint64, cuIn int) (r0 uint64, cuOut int, err error) { return f(vm, r1, r2, cuIn) } type SyscallFunc3 func(vm VM, r1, r2, r3 uint64, cuIn int) (r0 uint64, cuOut int, err error) func (f SyscallFunc3) Invoke(vm VM, r1, r2, r3, _, _ uint64, cuIn int) (r0 uint64, cuOut int, err error) { return f(vm, r1, r2, r3, cuIn) } type SyscallFunc4 func(vm VM, r1, r2, r3, r4 uint64, cuIn int) (r0 uint64, cuOut int, err error) func (f SyscallFunc4) Invoke(vm VM, r1, r2, r3, r4, _ uint64, cuIn int) (r0 uint64, cuOut int, err error) { return f(vm, r1, r2, r3, r4, cuIn) } type SyscallFunc5 func(vm VM, r1, r2, r3, r4, r5 uint64, cuIn int) (r0 uint64, cuOut int, err error) func (f SyscallFunc5) Invoke(vm VM, r1, r2, r3, r4, r5 uint64, cuIn int) (r0 uint64, cuOut int, err error) { return f(vm, r1, r2, r3, r4, r5, cuIn) }