1
0
mirror of https://github.com/golang/go synced 2024-09-30 17:28:32 -06:00
go/misc/cgo/test/issue4029.go

81 lines
1.7 KiB
Go
Raw Normal View History

// 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
cmd/cgo: put the real C function in the dynamic symbol table In the past, cgo generated Go code and C code. The C code was linked into a shared library. The Go code was built into an executable that dynamically linked against that shared library. C wrappers were exported from the shared library, and the Go code called them. It was all a long time ago, but in order to permit C code to call back into Go, somebody implemented #pragma dynexport (https://golang.org/cl/661043) to export a Go symbol into the dynamic symbol table. Then that same person added code to cgo to recognize //export comments (https://golang.org/cl/853042). The //export comments were implemented by generating C code, to be compiled by GCC, that would refer to C code, to be compiled by 6c, that would call the Go code. The GCC code would go into a shared library. The code compiled by 6c would be in the Go executable. The GCC code needed to refer to the 6c code, so the 6c function was marked with #pragma dynexport. The important point here is that #pragma dynexport was used to expose an internal detail of the implementation of an exported function, because at the time it was necessary. Moving forward to today, cgo no longer generates a shared library and 6c no longer exists. It's still true that we have a function compiled by GCC that refers to a wrapper function now written in Go. In the normal case today we are doing an external link, and we use a //go:cgo_export_static function to make the Go wrapper function visible to the C code under a known name. The #pragma dynexport statement has become a //go:cgo_export_dynamic comment on the Go code. That comment only takes effect when doing internal linking. The comment tells the linker to put the symbol in the dynamic symbol table. That still makes sense for the now unusual case of using internal linking with a shared library. However, all the changes to this code have carefully preserved the property that the //go:cgo_export_dynamic comment refers to an internal detail of the implementation of an exported function. That was necessary a long time ago, but no longer makes sense. This CL changes the code to put the actual C-callable function into the dynamic symbol table. I considered dropping the comment entirely, but it turns out that there is even a test for this, so I preserved it. Change-Id: I66a7958e366e5974363099bfaa6ba862ca327849 Reviewed-on: https://go-review.googlesource.com/17061 Run-TryBot: Ian Lance Taylor <iant@golang.org> Reviewed-by: Minux Ma <minux@golang.org>
2015-11-19 11:23:20 -07:00
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"
)
cmd/cgo: put the real C function in the dynamic symbol table In the past, cgo generated Go code and C code. The C code was linked into a shared library. The Go code was built into an executable that dynamically linked against that shared library. C wrappers were exported from the shared library, and the Go code called them. It was all a long time ago, but in order to permit C code to call back into Go, somebody implemented #pragma dynexport (https://golang.org/cl/661043) to export a Go symbol into the dynamic symbol table. Then that same person added code to cgo to recognize //export comments (https://golang.org/cl/853042). The //export comments were implemented by generating C code, to be compiled by GCC, that would refer to C code, to be compiled by 6c, that would call the Go code. The GCC code would go into a shared library. The code compiled by 6c would be in the Go executable. The GCC code needed to refer to the 6c code, so the 6c function was marked with #pragma dynexport. The important point here is that #pragma dynexport was used to expose an internal detail of the implementation of an exported function, because at the time it was necessary. Moving forward to today, cgo no longer generates a shared library and 6c no longer exists. It's still true that we have a function compiled by GCC that refers to a wrapper function now written in Go. In the normal case today we are doing an external link, and we use a //go:cgo_export_static function to make the Go wrapper function visible to the C code under a known name. The #pragma dynexport statement has become a //go:cgo_export_dynamic comment on the Go code. That comment only takes effect when doing internal linking. The comment tells the linker to put the symbol in the dynamic symbol table. That still makes sense for the now unusual case of using internal linking with a shared library. However, all the changes to this code have carefully preserved the property that the //go:cgo_export_dynamic comment refers to an internal detail of the implementation of an exported function. That was necessary a long time ago, but no longer makes sense. This CL changes the code to put the actual C-callable function into the dynamic symbol table. I considered dropping the comment entirely, but it turns out that there is even a test for this, so I preserved it. Change-Id: I66a7958e366e5974363099bfaa6ba862ca327849 Reviewed-on: https://go-review.googlesource.com/17061 Run-TryBot: Ian Lance Taylor <iant@golang.org> Reviewed-by: Minux Ma <minux@golang.org>
2015-11-19 11:23:20 -07:00
var callbacks int
//export IMPIsOpaque
func IMPIsOpaque() {
cmd/cgo: put the real C function in the dynamic symbol table In the past, cgo generated Go code and C code. The C code was linked into a shared library. The Go code was built into an executable that dynamically linked against that shared library. C wrappers were exported from the shared library, and the Go code called them. It was all a long time ago, but in order to permit C code to call back into Go, somebody implemented #pragma dynexport (https://golang.org/cl/661043) to export a Go symbol into the dynamic symbol table. Then that same person added code to cgo to recognize //export comments (https://golang.org/cl/853042). The //export comments were implemented by generating C code, to be compiled by GCC, that would refer to C code, to be compiled by 6c, that would call the Go code. The GCC code would go into a shared library. The code compiled by 6c would be in the Go executable. The GCC code needed to refer to the 6c code, so the 6c function was marked with #pragma dynexport. The important point here is that #pragma dynexport was used to expose an internal detail of the implementation of an exported function, because at the time it was necessary. Moving forward to today, cgo no longer generates a shared library and 6c no longer exists. It's still true that we have a function compiled by GCC that refers to a wrapper function now written in Go. In the normal case today we are doing an external link, and we use a //go:cgo_export_static function to make the Go wrapper function visible to the C code under a known name. The #pragma dynexport statement has become a //go:cgo_export_dynamic comment on the Go code. That comment only takes effect when doing internal linking. The comment tells the linker to put the symbol in the dynamic symbol table. That still makes sense for the now unusual case of using internal linking with a shared library. However, all the changes to this code have carefully preserved the property that the //go:cgo_export_dynamic comment refers to an internal detail of the implementation of an exported function. That was necessary a long time ago, but no longer makes sense. This CL changes the code to put the actual C-callable function into the dynamic symbol table. I considered dropping the comment entirely, but it turns out that there is even a test for this, so I preserved it. Change-Id: I66a7958e366e5974363099bfaa6ba862ca327849 Reviewed-on: https://go-review.googlesource.com/17061 Run-TryBot: Ian Lance Taylor <iant@golang.org> Reviewed-by: Minux Ma <minux@golang.org>
2015-11-19 11:23:20 -07:00
callbacks++
}
//export IMPInitWithFrame
func IMPInitWithFrame() {
cmd/cgo: put the real C function in the dynamic symbol table In the past, cgo generated Go code and C code. The C code was linked into a shared library. The Go code was built into an executable that dynamically linked against that shared library. C wrappers were exported from the shared library, and the Go code called them. It was all a long time ago, but in order to permit C code to call back into Go, somebody implemented #pragma dynexport (https://golang.org/cl/661043) to export a Go symbol into the dynamic symbol table. Then that same person added code to cgo to recognize //export comments (https://golang.org/cl/853042). The //export comments were implemented by generating C code, to be compiled by GCC, that would refer to C code, to be compiled by 6c, that would call the Go code. The GCC code would go into a shared library. The code compiled by 6c would be in the Go executable. The GCC code needed to refer to the 6c code, so the 6c function was marked with #pragma dynexport. The important point here is that #pragma dynexport was used to expose an internal detail of the implementation of an exported function, because at the time it was necessary. Moving forward to today, cgo no longer generates a shared library and 6c no longer exists. It's still true that we have a function compiled by GCC that refers to a wrapper function now written in Go. In the normal case today we are doing an external link, and we use a //go:cgo_export_static function to make the Go wrapper function visible to the C code under a known name. The #pragma dynexport statement has become a //go:cgo_export_dynamic comment on the Go code. That comment only takes effect when doing internal linking. The comment tells the linker to put the symbol in the dynamic symbol table. That still makes sense for the now unusual case of using internal linking with a shared library. However, all the changes to this code have carefully preserved the property that the //go:cgo_export_dynamic comment refers to an internal detail of the implementation of an exported function. That was necessary a long time ago, but no longer makes sense. This CL changes the code to put the actual C-callable function into the dynamic symbol table. I considered dropping the comment entirely, but it turns out that there is even a test for this, so I preserved it. Change-Id: I66a7958e366e5974363099bfaa6ba862ca327849 Reviewed-on: https://go-review.googlesource.com/17061 Run-TryBot: Ian Lance Taylor <iant@golang.org> Reviewed-by: Minux Ma <minux@golang.org>
2015-11-19 11:23:20 -07:00
callbacks++
}
//export IMPDrawRect
func IMPDrawRect() {
cmd/cgo: put the real C function in the dynamic symbol table In the past, cgo generated Go code and C code. The C code was linked into a shared library. The Go code was built into an executable that dynamically linked against that shared library. C wrappers were exported from the shared library, and the Go code called them. It was all a long time ago, but in order to permit C code to call back into Go, somebody implemented #pragma dynexport (https://golang.org/cl/661043) to export a Go symbol into the dynamic symbol table. Then that same person added code to cgo to recognize //export comments (https://golang.org/cl/853042). The //export comments were implemented by generating C code, to be compiled by GCC, that would refer to C code, to be compiled by 6c, that would call the Go code. The GCC code would go into a shared library. The code compiled by 6c would be in the Go executable. The GCC code needed to refer to the 6c code, so the 6c function was marked with #pragma dynexport. The important point here is that #pragma dynexport was used to expose an internal detail of the implementation of an exported function, because at the time it was necessary. Moving forward to today, cgo no longer generates a shared library and 6c no longer exists. It's still true that we have a function compiled by GCC that refers to a wrapper function now written in Go. In the normal case today we are doing an external link, and we use a //go:cgo_export_static function to make the Go wrapper function visible to the C code under a known name. The #pragma dynexport statement has become a //go:cgo_export_dynamic comment on the Go code. That comment only takes effect when doing internal linking. The comment tells the linker to put the symbol in the dynamic symbol table. That still makes sense for the now unusual case of using internal linking with a shared library. However, all the changes to this code have carefully preserved the property that the //go:cgo_export_dynamic comment refers to an internal detail of the implementation of an exported function. That was necessary a long time ago, but no longer makes sense. This CL changes the code to put the actual C-callable function into the dynamic symbol table. I considered dropping the comment entirely, but it turns out that there is even a test for this, so I preserved it. Change-Id: I66a7958e366e5974363099bfaa6ba862ca327849 Reviewed-on: https://go-review.googlesource.com/17061 Run-TryBot: Ian Lance Taylor <iant@golang.org> Reviewed-by: Minux Ma <minux@golang.org>
2015-11-19 11:23:20 -07:00
callbacks++
}
//export IMPWindowResize
func IMPWindowResize() {
cmd/cgo: put the real C function in the dynamic symbol table In the past, cgo generated Go code and C code. The C code was linked into a shared library. The Go code was built into an executable that dynamically linked against that shared library. C wrappers were exported from the shared library, and the Go code called them. It was all a long time ago, but in order to permit C code to call back into Go, somebody implemented #pragma dynexport (https://golang.org/cl/661043) to export a Go symbol into the dynamic symbol table. Then that same person added code to cgo to recognize //export comments (https://golang.org/cl/853042). The //export comments were implemented by generating C code, to be compiled by GCC, that would refer to C code, to be compiled by 6c, that would call the Go code. The GCC code would go into a shared library. The code compiled by 6c would be in the Go executable. The GCC code needed to refer to the 6c code, so the 6c function was marked with #pragma dynexport. The important point here is that #pragma dynexport was used to expose an internal detail of the implementation of an exported function, because at the time it was necessary. Moving forward to today, cgo no longer generates a shared library and 6c no longer exists. It's still true that we have a function compiled by GCC that refers to a wrapper function now written in Go. In the normal case today we are doing an external link, and we use a //go:cgo_export_static function to make the Go wrapper function visible to the C code under a known name. The #pragma dynexport statement has become a //go:cgo_export_dynamic comment on the Go code. That comment only takes effect when doing internal linking. The comment tells the linker to put the symbol in the dynamic symbol table. That still makes sense for the now unusual case of using internal linking with a shared library. However, all the changes to this code have carefully preserved the property that the //go:cgo_export_dynamic comment refers to an internal detail of the implementation of an exported function. That was necessary a long time ago, but no longer makes sense. This CL changes the code to put the actual C-callable function into the dynamic symbol table. I considered dropping the comment entirely, but it turns out that there is even a test for this, so I preserved it. Change-Id: I66a7958e366e5974363099bfaa6ba862ca327849 Reviewed-on: https://go-review.googlesource.com/17061 Run-TryBot: Ian Lance Taylor <iant@golang.org> Reviewed-by: Minux Ma <minux@golang.org>
2015-11-19 11:23:20 -07:00
callbacks++
}
func test4029(t *testing.T) {
loadThySelf(t, "IMPWindowResize")
loadThySelf(t, "IMPDrawRect")
loadThySelf(t, "IMPInitWithFrame")
loadThySelf(t, "IMPIsOpaque")
cmd/cgo: put the real C function in the dynamic symbol table In the past, cgo generated Go code and C code. The C code was linked into a shared library. The Go code was built into an executable that dynamically linked against that shared library. C wrappers were exported from the shared library, and the Go code called them. It was all a long time ago, but in order to permit C code to call back into Go, somebody implemented #pragma dynexport (https://golang.org/cl/661043) to export a Go symbol into the dynamic symbol table. Then that same person added code to cgo to recognize //export comments (https://golang.org/cl/853042). The //export comments were implemented by generating C code, to be compiled by GCC, that would refer to C code, to be compiled by 6c, that would call the Go code. The GCC code would go into a shared library. The code compiled by 6c would be in the Go executable. The GCC code needed to refer to the 6c code, so the 6c function was marked with #pragma dynexport. The important point here is that #pragma dynexport was used to expose an internal detail of the implementation of an exported function, because at the time it was necessary. Moving forward to today, cgo no longer generates a shared library and 6c no longer exists. It's still true that we have a function compiled by GCC that refers to a wrapper function now written in Go. In the normal case today we are doing an external link, and we use a //go:cgo_export_static function to make the Go wrapper function visible to the C code under a known name. The #pragma dynexport statement has become a //go:cgo_export_dynamic comment on the Go code. That comment only takes effect when doing internal linking. The comment tells the linker to put the symbol in the dynamic symbol table. That still makes sense for the now unusual case of using internal linking with a shared library. However, all the changes to this code have carefully preserved the property that the //go:cgo_export_dynamic comment refers to an internal detail of the implementation of an exported function. That was necessary a long time ago, but no longer makes sense. This CL changes the code to put the actual C-callable function into the dynamic symbol table. I considered dropping the comment entirely, but it turns out that there is even a test for this, so I preserved it. Change-Id: I66a7958e366e5974363099bfaa6ba862ca327849 Reviewed-on: https://go-review.googlesource.com/17061 Run-TryBot: Ian Lance Taylor <iant@golang.org> Reviewed-by: Minux Ma <minux@golang.org>
2015-11-19 11:23:20 -07:00
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)
cmd/cgo: put the real C function in the dynamic symbol table In the past, cgo generated Go code and C code. The C code was linked into a shared library. The Go code was built into an executable that dynamically linked against that shared library. C wrappers were exported from the shared library, and the Go code called them. It was all a long time ago, but in order to permit C code to call back into Go, somebody implemented #pragma dynexport (https://golang.org/cl/661043) to export a Go symbol into the dynamic symbol table. Then that same person added code to cgo to recognize //export comments (https://golang.org/cl/853042). The //export comments were implemented by generating C code, to be compiled by GCC, that would refer to C code, to be compiled by 6c, that would call the Go code. The GCC code would go into a shared library. The code compiled by 6c would be in the Go executable. The GCC code needed to refer to the 6c code, so the 6c function was marked with #pragma dynexport. The important point here is that #pragma dynexport was used to expose an internal detail of the implementation of an exported function, because at the time it was necessary. Moving forward to today, cgo no longer generates a shared library and 6c no longer exists. It's still true that we have a function compiled by GCC that refers to a wrapper function now written in Go. In the normal case today we are doing an external link, and we use a //go:cgo_export_static function to make the Go wrapper function visible to the C code under a known name. The #pragma dynexport statement has become a //go:cgo_export_dynamic comment on the Go code. That comment only takes effect when doing internal linking. The comment tells the linker to put the symbol in the dynamic symbol table. That still makes sense for the now unusual case of using internal linking with a shared library. However, all the changes to this code have carefully preserved the property that the //go:cgo_export_dynamic comment refers to an internal detail of the implementation of an exported function. That was necessary a long time ago, but no longer makes sense. This CL changes the code to put the actual C-callable function into the dynamic symbol table. I considered dropping the comment entirely, but it turns out that there is even a test for this, so I preserved it. Change-Id: I66a7958e366e5974363099bfaa6ba862ca327849 Reviewed-on: https://go-review.googlesource.com/17061 Run-TryBot: Ian Lance Taylor <iant@golang.org> Reviewed-by: Minux Ma <minux@golang.org>
2015-11-19 11:23:20 -07:00
C.call4029(symbol_address)
}