use RegisterFunc for dlfcn.go (#51)
RegisterFunc and RegisterLibFunc are a replacement for SyscallN
- commit
- d67702f873b12146375ddb25e53484f5ac8e6cc2
- author
- TotallyGamerJet · · 2022-10-23 17:43 UTC
- committer
- GitHub · · 2022-10-23 17:43 UTC
- parent
- ec7a70a
- signature
- GPG Unverified
4AEE18F83AFDEB23The key is unknown
1 file · +18 -15
M dlfcn.go +18 -15
| @@ -7,16 +7,27 @@ | |||
| 7 | 7 | package purego | |
| 8 | 8 | ||
| 9 | 9 | import ( | |
| 10 | - | "runtime" | |
| 11 | 10 | "unsafe" | |
| 12 | - | ||
| 13 | - | "github.com/ebitengine/purego/internal/strings" | |
| 14 | 11 | ) | |
| 15 | 12 | ||
| 16 | 13 | const RTLD_GLOBAL = 0x8 | |
| 17 | 14 | ||
| 18 | 15 | const RTLD_DEFAULT = ^uintptr(1) | |
| 19 | 16 | ||
| 17 | + | var ( | |
| 18 | + | fnDlopen func(path string, mode int) uintptr | |
| 19 | + | fnDlsym func(handle uintptr, name string) uintptr | |
| 20 | + | fnDlerror func() string | |
| 21 | + | fnDlclose func(handle uintptr) bool | |
| 22 | + | ) | |
| 23 | + | ||
| 24 | + | func init() { | |
| 25 | + | RegisterFunc(&fnDlopen, dlopenABI0) | |
| 26 | + | RegisterFunc(&fnDlsym, dlsymABI0) | |
| 27 | + | RegisterFunc(&fnDlerror, dlerrorABI0) | |
| 28 | + | RegisterFunc(&fnDlclose, dlcloseABI0) | |
| 29 | + | } | |
| 30 | + | ||
| 20 | 31 | // Dlopen examines the dynamic library or bundle file specified by path. If the file is compatible | |
| 21 | 32 | // with the current process and has not already been loaded into the | |
| 22 | 33 | // current process, it is loaded and linked. After being linked, if it contains | |
| @@ -26,10 +37,7 @@ const RTLD_DEFAULT = ^uintptr(1) | |||
| 26 | 37 | // reference count for the handle will be incremented. Therefore, all | |
| 27 | 38 | // Dlopen calls should be balanced with a Dlclose call. | |
| 28 | 39 | func Dlopen(path string, mode int) uintptr { | |
| 29 | - | bs := strings.CString(path) | |
| 30 | - | ret, _, _ := SyscallN(dlopenABI0, uintptr(unsafe.Pointer(bs)), uintptr(mode), 0) | |
| 31 | - | runtime.KeepAlive(bs) | |
| 32 | - | return ret | |
| 40 | + | return fnDlopen(path, mode) | |
| 33 | 41 | } | |
| 34 | 42 | ||
| 35 | 43 | // Dlsym takes a "handle" of a dynamic library returned by Dlopen and the symbol name. | |
| @@ -37,10 +45,7 @@ func Dlopen(path string, mode int) uintptr { | |||
| 37 | 45 | // in the specified library or any of the libraries that were automatically loaded by Dlopen | |
| 38 | 46 | // when that library was loaded, Dlsym returns zero. | |
| 39 | 47 | func Dlsym(handle uintptr, name string) uintptr { | |
| 40 | - | bs := strings.CString(name) | |
| 41 | - | ret, _, _ := SyscallN(dlsymABI0, handle, uintptr(unsafe.Pointer(bs)), 0) | |
| 42 | - | runtime.KeepAlive(bs) | |
| 43 | - | return ret | |
| 48 | + | return fnDlsym(handle, name) | |
| 44 | 49 | } | |
| 45 | 50 | ||
| 46 | 51 | // Dlerror returns a human-readable string describing the most recent error that | |
| @@ -50,8 +55,7 @@ func Dlsym(handle uintptr, name string) uintptr { | |||
| 50 | 55 | func Dlerror() string { | |
| 51 | 56 | // msg is only valid until the next call to Dlerror | |
| 52 | 57 | // which is why it gets copied into a Go string | |
| 53 | - | msg, _, _ := SyscallN(dlerrorABI0) | |
| 54 | - | return strings.GoString(msg) | |
| 58 | + | return fnDlerror() | |
| 55 | 59 | } | |
| 56 | 60 | ||
| 57 | 61 | // Dlclose decrements the reference count on the dynamic library handle. | |
| @@ -59,8 +63,7 @@ func Dlerror() string { | |||
| 59 | 63 | // use symbols in it, then the dynamic library is unloaded. | |
| 60 | 64 | // Dlclose returns false on success, and true on error. | |
| 61 | 65 | func Dlclose(handle uintptr) bool { | |
| 62 | - | ret, _, _ := SyscallN(dlcloseABI0, handle) | |
| 63 | - | return ret != 0 | |
| 66 | + | return fnDlclose(handle) | |
| 64 | 67 | } | |
| 65 | 68 | ||
| 66 | 69 | // these functions exist in dlfcn_stubs.s and are calling C functions linked to in dlfcn_GOOS.go | |
| @@ -7,16 +7,27 @@ | |||||
| 7 | package purego | 7 | package purego | ||
| 8 | 8 | ||||
| 9 | import ( | 9 | import ( | ||
| 10 | - | "runtime" | |||
| 11 | "unsafe" | 10 | "unsafe" | ||
| 12 | - | ||||
| 13 | - | "github.com/ebitengine/purego/internal/strings" | |||
| 14 | ) | 11 | ) | ||
| 15 | 12 | ||||
| 16 | const RTLD_GLOBAL = 0x8 | 13 | const RTLD_GLOBAL = 0x8 | ||
| 17 | 14 | ||||
| 18 | const RTLD_DEFAULT = ^uintptr(1) | 15 | const RTLD_DEFAULT = ^uintptr(1) | ||
| 19 | 16 | ||||
| 17 | + | var ( | |||
| 18 | + | fnDlopen func(path string, mode int) uintptr | |||
| 19 | + | fnDlsym func(handle uintptr, name string) uintptr | |||
| 20 | + | fnDlerror func() string | |||
| 21 | + | fnDlclose func(handle uintptr) bool | |||
| 22 | + | ) | |||
| 23 | + | ||||
| 24 | + | func init() { | |||
| 25 | + | RegisterFunc(&fnDlopen, dlopenABI0) | |||
| 26 | + | RegisterFunc(&fnDlsym, dlsymABI0) | |||
| 27 | + | RegisterFunc(&fnDlerror, dlerrorABI0) | |||
| 28 | + | RegisterFunc(&fnDlclose, dlcloseABI0) | |||
| 29 | + | } | |||
| 30 | + | ||||
| 20 | // Dlopen examines the dynamic library or bundle file specified by path. If the file is compatible | 31 | // Dlopen examines the dynamic library or bundle file specified by path. If the file is compatible | ||
| 21 | // with the current process and has not already been loaded into the | 32 | // with the current process and has not already been loaded into the | ||
| 22 | // current process, it is loaded and linked. After being linked, if it contains | 33 | // current process, it is loaded and linked. After being linked, if it contains | ||
| @@ -26,10 +37,7 @@ const RTLD_DEFAULT = ^uintptr(1) | |||||
| 26 | // reference count for the handle will be incremented. Therefore, all | 37 | // reference count for the handle will be incremented. Therefore, all | ||
| 27 | // Dlopen calls should be balanced with a Dlclose call. | 38 | // Dlopen calls should be balanced with a Dlclose call. | ||
| 28 | func Dlopen(path string, mode int) uintptr { | 39 | func Dlopen(path string, mode int) uintptr { | ||
| 29 | - | bs := strings.CString(path) | 40 | + | return fnDlopen(path, mode) |
| 30 | - | ret, _, _ := SyscallN(dlopenABI0, uintptr(unsafe.Pointer(bs)), uintptr(mode), 0) | |||
| 31 | - | runtime.KeepAlive(bs) | |||
| 32 | - | return ret | |||
| 33 | } | 41 | } | ||
| 34 | 42 | ||||
| 35 | // Dlsym takes a "handle" of a dynamic library returned by Dlopen and the symbol name. | 43 | // Dlsym takes a "handle" of a dynamic library returned by Dlopen and the symbol name. | ||
| @@ -37,10 +45,7 @@ func Dlopen(path string, mode int) uintptr { | |||||
| 37 | // in the specified library or any of the libraries that were automatically loaded by Dlopen | 45 | // in the specified library or any of the libraries that were automatically loaded by Dlopen | ||
| 38 | // when that library was loaded, Dlsym returns zero. | 46 | // when that library was loaded, Dlsym returns zero. | ||
| 39 | func Dlsym(handle uintptr, name string) uintptr { | 47 | func Dlsym(handle uintptr, name string) uintptr { | ||
| 40 | - | bs := strings.CString(name) | 48 | + | return fnDlsym(handle, name) |
| 41 | - | ret, _, _ := SyscallN(dlsymABI0, handle, uintptr(unsafe.Pointer(bs)), 0) | |||
| 42 | - | runtime.KeepAlive(bs) | |||
| 43 | - | return ret | |||
| 44 | } | 49 | } | ||
| 45 | 50 | ||||
| 46 | // Dlerror returns a human-readable string describing the most recent error that | 51 | // Dlerror returns a human-readable string describing the most recent error that | ||
| @@ -50,8 +55,7 @@ func Dlsym(handle uintptr, name string) uintptr { | |||||
| 50 | func Dlerror() string { | 55 | func Dlerror() string { | ||
| 51 | // msg is only valid until the next call to Dlerror | 56 | // msg is only valid until the next call to Dlerror | ||
| 52 | // which is why it gets copied into a Go string | 57 | // which is why it gets copied into a Go string | ||
| 53 | - | msg, _, _ := SyscallN(dlerrorABI0) | 58 | + | return fnDlerror() |
| 54 | - | return strings.GoString(msg) | |||
| 55 | } | 59 | } | ||
| 56 | 60 | ||||
| 57 | // Dlclose decrements the reference count on the dynamic library handle. | 61 | // Dlclose decrements the reference count on the dynamic library handle. | ||
| @@ -59,8 +63,7 @@ func Dlerror() string { | |||||
| 59 | // use symbols in it, then the dynamic library is unloaded. | 63 | // use symbols in it, then the dynamic library is unloaded. | ||
| 60 | // Dlclose returns false on success, and true on error. | 64 | // Dlclose returns false on success, and true on error. | ||
| 61 | func Dlclose(handle uintptr) bool { | 65 | func Dlclose(handle uintptr) bool { | ||
| 62 | - | ret, _, _ := SyscallN(dlcloseABI0, handle) | 66 | + | return fnDlclose(handle) |
| 63 | - | return ret != 0 | |||
| 64 | } | 67 | } | ||
| 65 | 68 | ||||
| 66 | // these functions exist in dlfcn_stubs.s and are calling C functions linked to in dlfcn_GOOS.go | 69 | // these functions exist in dlfcn_stubs.s and are calling C functions linked to in dlfcn_GOOS.go | ||