summaryrefslogtreecommitdiffstats
path: root/misc/cgo/test/issue4029.go
diff options
context:
space:
mode:
Diffstat (limited to 'misc/cgo/test/issue4029.go')
-rw-r--r--misc/cgo/test/issue4029.go80
1 files changed, 80 insertions, 0 deletions
diff --git a/misc/cgo/test/issue4029.go b/misc/cgo/test/issue4029.go
new file mode 100644
index 0000000..90ca08c
--- /dev/null
+++ b/misc/cgo/test/issue4029.go
@@ -0,0 +1,80 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !windows && !static && (!darwin || (!internal_pie && !arm64))
+// +build !windows
+// +build !static
+// +build !darwin !internal_pie,!arm64
+
+// Excluded in darwin internal linking PIE mode, as dynamic export is not
+// supported.
+// Excluded in internal linking mode on darwin/arm64, as it is always PIE.
+
+package cgotest
+
+/*
+#include <stdint.h>
+#include <dlfcn.h>
+#cgo linux LDFLAGS: -ldl
+
+extern uintptr_t dlopen4029(char*, int);
+extern uintptr_t dlsym4029(uintptr_t, char*);
+extern int dlclose4029(uintptr_t);
+
+extern void call4029(uintptr_t arg);
+*/
+import "C"
+
+import (
+ "testing"
+)
+
+var callbacks int
+
+//export IMPIsOpaque
+func IMPIsOpaque() {
+ callbacks++
+}
+
+//export IMPInitWithFrame
+func IMPInitWithFrame() {
+ callbacks++
+}
+
+//export IMPDrawRect
+func IMPDrawRect() {
+ callbacks++
+}
+
+//export IMPWindowResize
+func IMPWindowResize() {
+ callbacks++
+}
+
+func test4029(t *testing.T) {
+ loadThySelf(t, "IMPWindowResize")
+ loadThySelf(t, "IMPDrawRect")
+ loadThySelf(t, "IMPInitWithFrame")
+ loadThySelf(t, "IMPIsOpaque")
+ if callbacks != 4 {
+ t.Errorf("got %d callbacks, expected 4", callbacks)
+ }
+}
+
+func loadThySelf(t *testing.T, symbol string) {
+ this_process := C.dlopen4029(nil, C.RTLD_NOW)
+ if this_process == 0 {
+ t.Error("dlopen:", C.GoString(C.dlerror()))
+ return
+ }
+ defer C.dlclose4029(this_process)
+
+ symbol_address := C.dlsym4029(this_process, C.CString(symbol))
+ if symbol_address == 0 {
+ t.Error("dlsym:", C.GoString(C.dlerror()))
+ return
+ }
+ t.Log(symbol, symbol_address)
+ C.call4029(symbol_address)
+}