Skip to content

Commit

Permalink
go: memory: fun with unsafe: read, write and call
Browse files Browse the repository at this point in the history
  • Loading branch information
StalkR committed Apr 19, 2015
1 parent b0cba7d commit ed32e25
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 0 deletions.
29 changes: 29 additions & 0 deletions go/memory/memory.go
@@ -0,0 +1,29 @@
// Package memory showcases some unsafe operations in Go: read, write and call.
package memory

import (
"reflect"
"unsafe"
)

func address(thing interface{}) int {
return int(reflect.ValueOf(thing).Pointer())
}

func read(addr int) int {
paddr := &addr
pv := reflect.NewAt(reflect.TypeOf(&paddr), unsafe.Pointer(&paddr))
return **pv.Elem().Interface().(**int)
}

func write(addr, value int) {
paddr := &addr
pv := reflect.NewAt(reflect.TypeOf(&paddr), unsafe.Pointer(&paddr))
**pv.Elem().Interface().(**int) = value
}

func call(addr int) {
f := func() {}
write(address(&f), address(&addr))
f()
}
56 changes: 56 additions & 0 deletions go/memory/memory_test.go
@@ -0,0 +1,56 @@
package memory

import (
"fmt"
"strconv"
"testing"
)

func addressViaFmt(t *testing.T, i interface{}) int {
addr, err := strconv.ParseUint(fmt.Sprintf("%p", i), 0, 0)
if err != nil {
t.Fatalf("could not parse address of %p", i)
}
return int(addr)
}

func TestAddress(t *testing.T) {
want := addressViaFmt(t, TestAddress)
got := address(TestAddress)
if got != want {
t.Errorf("wrong address for func: got %x, want %x", got, want)
}

x := 1
want = addressViaFmt(t, &x)
got = address(&x)
if got != want {
t.Errorf("wrong address for var: got %x, want %x", got, want)
}
}

func TestRead(t *testing.T) {
want := 0x41414141
got := read(address(&want))
if got != want {
t.Errorf("wrong read: got %x, want %x", got, want)
}
}

func TestWrite(t *testing.T) {
got := 0x41414141
want := 0x42424242
write(address(&got), want)
if got != want {
t.Errorf("wrong read: got %x, want %x", got, want)
}
}

var callWorked = false // Has to be a global otherwise cannot be set from inside call.

func TestCall(t *testing.T) {
call(address(func() { callWorked = true }))
if !callWorked {
t.Error("wrong call: got false, want true")
}
}

0 comments on commit ed32e25

Please sign in to comment.