aboutsummaryrefslogtreecommitdiffstats
path: root/Godeps/_workspace/src/github.com/obscuren/qml/testing.go
diff options
context:
space:
mode:
authorTaylor Gerring <taylor.gerring@gmail.com>2015-02-16 21:28:33 +0800
committerTaylor Gerring <taylor.gerring@gmail.com>2015-02-16 21:28:33 +0800
commit702218008ee2b6d708d6b2821cdef80736bb3224 (patch)
treed55ff7ce88187082378e7d8e4c2f3aad14d23b4e /Godeps/_workspace/src/github.com/obscuren/qml/testing.go
parent202362d9258335c695eb75f55f4be74a50a1af33 (diff)
downloadgo-tangerine-702218008ee2b6d708d6b2821cdef80736bb3224.tar.gz
go-tangerine-702218008ee2b6d708d6b2821cdef80736bb3224.tar.zst
go-tangerine-702218008ee2b6d708d6b2821cdef80736bb3224.zip
Add versioned dependencies from godep
Diffstat (limited to 'Godeps/_workspace/src/github.com/obscuren/qml/testing.go')
-rw-r--r--Godeps/_workspace/src/github.com/obscuren/qml/testing.go69
1 files changed, 69 insertions, 0 deletions
diff --git a/Godeps/_workspace/src/github.com/obscuren/qml/testing.go b/Godeps/_workspace/src/github.com/obscuren/qml/testing.go
new file mode 100644
index 000000000..39a2a691d
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/obscuren/qml/testing.go
@@ -0,0 +1,69 @@
+package qml
+
+// #include <stdlib.h>
+// int mprotect(void *addr, size_t len, int prot);
+import "C"
+
+import (
+ "bytes"
+ "encoding/binary"
+ "gopkg.in/qml.v1/cdata"
+ "reflect"
+ "unsafe"
+)
+
+const pageSize = 4096
+
+func qmain() {
+ Run(func() error { tmain(); return nil })
+}
+
+func tmain() { tstub() }
+func tstub() { tstub() }
+
+func SetupTesting() {
+ ptr := func(f func()) uintptr { return reflect.ValueOf(f).Pointer() }
+ rmain, mmain := cdata.Addrs()
+ fset(rmain, mmain, ptr(qmain))
+ fset(ptr(tmain), ptr(tstub), mmain)
+}
+
+const (
+ protREAD = 1
+ protWRITE = 2
+ protEXEC = 4
+)
+
+func fset(target, old, new uintptr) {
+ pageOffset := target % pageSize
+ pageAddr := target - pageOffset
+
+ var mem []byte
+ memh := (*reflect.SliceHeader)(unsafe.Pointer(&mem))
+ memh.Data = pageAddr
+ memh.Len = pageSize * 2
+ memh.Cap = pageSize * 2
+
+ oldAddr := make([]byte, 8)
+ newAddr := make([]byte, 8)
+
+ binary.LittleEndian.PutUint64(oldAddr, uint64(old))
+ binary.LittleEndian.PutUint64(newAddr, uint64(new))
+
+ // BSD's syscall package misses Mprotect. Use cgo instead.
+ C.mprotect(unsafe.Pointer(pageAddr), C.size_t(len(mem)), protEXEC|protREAD|protWRITE)
+ defer C.mprotect(unsafe.Pointer(pageAddr), C.size_t(len(mem)), protEXEC|protREAD)
+
+ delta := make([]byte, 4)
+ for i, c := range mem[pageOffset:] {
+ if c == 0xe8 && int(pageOffset)+i+5 < len(mem) {
+ instrAddr := pageAddr + pageOffset + uintptr(i)
+ binary.LittleEndian.PutUint32(delta, uint32(old-instrAddr-5))
+ if bytes.Equal(mem[int(pageOffset)+i+1:int(pageOffset)+i+5], delta) {
+ binary.LittleEndian.PutUint32(mem[int(pageOffset)+i+1:], uint32(new-instrAddr-5))
+ return
+ }
+ }
+ }
+ panic("cannot setup qml package for testing")
+}