Call C dlfcn functions directly on android (#263)
- commit
- 934083583908b08741591761d354cc1e4dc22f4a
- author
- TotallyGamerJet · · 2024-08-05 11:41 UTC
- committer
- GitHub · · 2024-08-05 11:41 UTC
- parent
- b9dbbd0
- signature
- GPG Unverified
B5690EEEBB952194The key is unknown
7 files · +83 -13
M dlfcn.go +1 -1
| @@ -1,7 +1,7 @@ | |||
| 1 | 1 | // SPDX-License-Identifier: Apache-2.0 | |
| 2 | 2 | // SPDX-FileCopyrightText: 2022 The Ebitengine Authors | |
| 3 | 3 | ||
| 4 | - | //go:build (darwin || freebsd || linux) && !faketime | |
| 4 | + | //go:build (darwin || freebsd || linux) && !android && !faketime | |
| 5 | 5 | ||
| 6 | 6 | package purego | |
| 7 | 7 | ||
| @@ -1,7 +1,7 @@ | |||||
| 1 | // SPDX-License-Identifier: Apache-2.0 | 1 | // SPDX-License-Identifier: Apache-2.0 | ||
| 2 | // SPDX-FileCopyrightText: 2022 The Ebitengine Authors | 2 | // SPDX-FileCopyrightText: 2022 The Ebitengine Authors | ||
| 3 | 3 | ||||
| 4 | - | //go:build (darwin || freebsd || linux) && !faketime | 4 | + | //go:build (darwin || freebsd || linux) && !android && !faketime |
| 5 | 5 | ||||
| 6 | package purego | 6 | package purego | ||
| 7 | 7 | ||||
A dlfcn_android.go +34 -0
| @@ -0,0 +1,34 @@ | |||
| 1 | + | // SPDX-License-Identifier: Apache-2.0 | |
| 2 | + | // SPDX-FileCopyrightText: 2024 The Ebitengine Authors | |
| 3 | + | ||
| 4 | + | package purego | |
| 5 | + | ||
| 6 | + | import "github.com/ebitengine/purego/internal/cgo" | |
| 7 | + | ||
| 8 | + | // Source for constants: https://android.googlesource.com/platform/bionic/+/refs/heads/main/libc/include/dlfcn.h | |
| 9 | + | ||
| 10 | + | const ( | |
| 11 | + | is64bit = 1 << (^uintptr(0) >> 63) / 2 | |
| 12 | + | is32bit = 1 - is64bit | |
| 13 | + | RTLD_DEFAULT = is32bit * 0xffffffff | |
| 14 | + | RTLD_LAZY = 0x00000001 | |
| 15 | + | RTLD_NOW = is64bit * 0x00000002 | |
| 16 | + | RTLD_LOCAL = 0x00000000 | |
| 17 | + | RTLD_GLOBAL = is64bit*0x00100 | is32bit*0x00000002 | |
| 18 | + | ) | |
| 19 | + | ||
| 20 | + | func Dlopen(path string, mode int) (uintptr, error) { | |
| 21 | + | return cgo.Dlopen(path, mode) | |
| 22 | + | } | |
| 23 | + | ||
| 24 | + | func Dlsym(handle uintptr, name string) (uintptr, error) { | |
| 25 | + | return cgo.Dlsym(handle, name) | |
| 26 | + | } | |
| 27 | + | ||
| 28 | + | func Dlclose(handle uintptr) error { | |
| 29 | + | return cgo.Dlclose(handle) | |
| 30 | + | } | |
| 31 | + | ||
| 32 | + | func loadSymbol(handle uintptr, name string) (uintptr, error) { | |
| 33 | + | return Dlsym(handle, name) | |
| 34 | + | } | |
| @@ -0,0 +1,34 @@ | |||||
| 1 | + | // SPDX-License-Identifier: Apache-2.0 | |||
| 2 | + | // SPDX-FileCopyrightText: 2024 The Ebitengine Authors | |||
| 3 | + | ||||
| 4 | + | package purego | |||
| 5 | + | ||||
| 6 | + | import "github.com/ebitengine/purego/internal/cgo" | |||
| 7 | + | ||||
| 8 | + | // Source for constants: https://android.googlesource.com/platform/bionic/+/refs/heads/main/libc/include/dlfcn.h | |||
| 9 | + | ||||
| 10 | + | const ( | |||
| 11 | + | is64bit = 1 << (^uintptr(0) >> 63) / 2 | |||
| 12 | + | is32bit = 1 - is64bit | |||
| 13 | + | RTLD_DEFAULT = is32bit * 0xffffffff | |||
| 14 | + | RTLD_LAZY = 0x00000001 | |||
| 15 | + | RTLD_NOW = is64bit * 0x00000002 | |||
| 16 | + | RTLD_LOCAL = 0x00000000 | |||
| 17 | + | RTLD_GLOBAL = is64bit*0x00100 | is32bit*0x00000002 | |||
| 18 | + | ) | |||
| 19 | + | ||||
| 20 | + | func Dlopen(path string, mode int) (uintptr, error) { | |||
| 21 | + | return cgo.Dlopen(path, mode) | |||
| 22 | + | } | |||
| 23 | + | ||||
| 24 | + | func Dlsym(handle uintptr, name string) (uintptr, error) { | |||
| 25 | + | return cgo.Dlsym(handle, name) | |||
| 26 | + | } | |||
| 27 | + | ||||
| 28 | + | func Dlclose(handle uintptr) error { | |||
| 29 | + | return cgo.Dlclose(handle) | |||
| 30 | + | } | |||
| 31 | + | ||||
| 32 | + | func loadSymbol(handle uintptr, name string) (uintptr, error) { | |||
| 33 | + | return Dlsym(handle, name) | |||
| 34 | + | } | |||
M dlfcn_darwin.go +5 -5
| @@ -6,11 +6,11 @@ package purego | |||
| 6 | 6 | // Source for constants: https://opensource.apple.com/source/dyld/dyld-360.14/include/dlfcn.h.auto.html | |
| 7 | 7 | ||
| 8 | 8 | const ( | |
| 9 | - | RTLD_DEFAULT = ^uintptr(0) - 1 // Pseudo-handle for dlsym so search for any loaded symbol | |
| 10 | - | RTLD_LAZY = 0x1 // Relocations are performed at an implementation-dependent time. | |
| 11 | - | RTLD_NOW = 0x2 // Relocations are performed when the object is loaded. | |
| 12 | - | RTLD_LOCAL = 0x4 // All symbols are not made available for relocation processing by other modules. | |
| 13 | - | RTLD_GLOBAL = 0x8 // All symbols are available for relocation processing of other modules. | |
| 9 | + | RTLD_DEFAULT = 1<<64 - 2 // Pseudo-handle for dlsym so search for any loaded symbol | |
| 10 | + | RTLD_LAZY = 0x1 // Relocations are performed at an implementation-dependent time. | |
| 11 | + | RTLD_NOW = 0x2 // Relocations are performed when the object is loaded. | |
| 12 | + | RTLD_LOCAL = 0x4 // All symbols are not made available for relocation processing by other modules. | |
| 13 | + | RTLD_GLOBAL = 0x8 // All symbols are available for relocation processing of other modules. | |
| 14 | 14 | ) | |
| 15 | 15 | ||
| 16 | 16 | //go:cgo_import_dynamic purego_dlopen dlopen "/usr/lib/libSystem.B.dylib" | |
| @@ -6,11 +6,11 @@ package purego | |||||
| 6 | // Source for constants: https://opensource.apple.com/source/dyld/dyld-360.14/include/dlfcn.h.auto.html | 6 | // Source for constants: https://opensource.apple.com/source/dyld/dyld-360.14/include/dlfcn.h.auto.html | ||
| 7 | 7 | ||||
| 8 | const ( | 8 | const ( | ||
| 9 | - | RTLD_DEFAULT = ^uintptr(0) - 1 // Pseudo-handle for dlsym so search for any loaded symbol | 9 | + | RTLD_DEFAULT = 1<<64 - 2 // Pseudo-handle for dlsym so search for any loaded symbol |
| 10 | - | RTLD_LAZY = 0x1 // Relocations are performed at an implementation-dependent time. | 10 | + | RTLD_LAZY = 0x1 // Relocations are performed at an implementation-dependent time. |
| 11 | - | RTLD_NOW = 0x2 // Relocations are performed when the object is loaded. | 11 | + | RTLD_NOW = 0x2 // Relocations are performed when the object is loaded. |
| 12 | - | RTLD_LOCAL = 0x4 // All symbols are not made available for relocation processing by other modules. | 12 | + | RTLD_LOCAL = 0x4 // All symbols are not made available for relocation processing by other modules. |
| 13 | - | RTLD_GLOBAL = 0x8 // All symbols are available for relocation processing of other modules. | 13 | + | RTLD_GLOBAL = 0x8 // All symbols are available for relocation processing of other modules. |
| 14 | ) | 14 | ) | ||
| 15 | 15 | ||||
| 16 | //go:cgo_import_dynamic purego_dlopen dlopen "/usr/lib/libSystem.B.dylib" | 16 | //go:cgo_import_dynamic purego_dlopen dlopen "/usr/lib/libSystem.B.dylib" | ||
M dlfcn_freebsd.go +6 -5
| @@ -5,9 +5,10 @@ package purego | |||
| 5 | 5 | ||
| 6 | 6 | // Constants as defined in https://github.com/freebsd/freebsd-src/blob/main/include/dlfcn.h | |
| 7 | 7 | const ( | |
| 8 | - | RTLD_DEFAULT = ^uintptr(0) - 2 // Pseudo-handle for dlsym so search for any loaded symbol | |
| 9 | - | RTLD_LAZY = 0x00001 // Relocations are performed at an implementation-dependent time. | |
| 10 | - | RTLD_NOW = 0x00002 // Relocations are performed when the object is loaded. | |
| 11 | - | RTLD_LOCAL = 0x00000 // All symbols are not made available for relocation processing by other modules. | |
| 12 | - | RTLD_GLOBAL = 0x00100 // All symbols are available for relocation processing of other modules. | |
| 8 | + | intSize = 32 << (^uint(0) >> 63) // 32 or 64 | |
| 9 | + | RTLD_DEFAULT = 1<<intSize - 2 // Pseudo-handle for dlsym so search for any loaded symbol | |
| 10 | + | RTLD_LAZY = 0x00000001 // Relocations are performed at an implementation-dependent time. | |
| 11 | + | RTLD_NOW = 0x00000002 // Relocations are performed when the object is loaded. | |
| 12 | + | RTLD_LOCAL = 0x00000000 // All symbols are not made available for relocation processing by other modules. | |
| 13 | + | RTLD_GLOBAL = 0x00000100 // All symbols are available for relocation processing of other modules. | |
| 13 | 14 | ) | |
| @@ -5,9 +5,10 @@ package purego | |||||
| 5 | 5 | ||||
| 6 | // Constants as defined in https://github.com/freebsd/freebsd-src/blob/main/include/dlfcn.h | 6 | // Constants as defined in https://github.com/freebsd/freebsd-src/blob/main/include/dlfcn.h | ||
| 7 | const ( | 7 | const ( | ||
| 8 | - | RTLD_DEFAULT = ^uintptr(0) - 2 // Pseudo-handle for dlsym so search for any loaded symbol | 8 | + | intSize = 32 << (^uint(0) >> 63) // 32 or 64 |
| 9 | - | RTLD_LAZY = 0x00001 // Relocations are performed at an implementation-dependent time. | 9 | + | RTLD_DEFAULT = 1<<intSize - 2 // Pseudo-handle for dlsym so search for any loaded symbol |
| 10 | - | RTLD_NOW = 0x00002 // Relocations are performed when the object is loaded. | 10 | + | RTLD_LAZY = 0x00000001 // Relocations are performed at an implementation-dependent time. |
| 11 | - | RTLD_LOCAL = 0x00000 // All symbols are not made available for relocation processing by other modules. | 11 | + | RTLD_NOW = 0x00000002 // Relocations are performed when the object is loaded. |
| 12 | - | RTLD_GLOBAL = 0x00100 // All symbols are available for relocation processing of other modules. | 12 | + | RTLD_LOCAL = 0x00000000 // All symbols are not made available for relocation processing by other modules. |
| 13 | + | RTLD_GLOBAL = 0x00000100 // All symbols are available for relocation processing of other modules. | |||
| 13 | ) | 14 | ) | ||
M dlfcn_linux.go +2 -0
| @@ -1,6 +1,8 @@ | |||
| 1 | 1 | // SPDX-License-Identifier: Apache-2.0 | |
| 2 | 2 | // SPDX-FileCopyrightText: 2022 The Ebitengine Authors | |
| 3 | 3 | ||
| 4 | + | //go:build !android | |
| 5 | + | ||
| 4 | 6 | package purego | |
| 5 | 7 | ||
| 6 | 8 | // Source for constants: https://codebrowser.dev/glibc/glibc/bits/dlfcn.h.html | |
| @@ -1,6 +1,8 @@ | |||||
| 1 | // SPDX-License-Identifier: Apache-2.0 | 1 | // SPDX-License-Identifier: Apache-2.0 | ||
| 2 | // SPDX-FileCopyrightText: 2022 The Ebitengine Authors | 2 | // SPDX-FileCopyrightText: 2022 The Ebitengine Authors | ||
| 3 | 3 | ||||
| 4 | + | //go:build !android | |||
| 5 | + | ||||
| 4 | package purego | 6 | package purego | ||
| 5 | 7 | ||||
| 6 | // Source for constants: https://codebrowser.dev/glibc/glibc/bits/dlfcn.h.html | 8 | // Source for constants: https://codebrowser.dev/glibc/glibc/bits/dlfcn.h.html | ||
M func.go +1 -2
| @@ -152,6 +152,7 @@ func RegisterFunc(fptr interface{}, cfn uintptr) { | |||
| 152 | 152 | stack++ | |
| 153 | 153 | } | |
| 154 | 154 | case reflect.Float32, reflect.Float64: | |
| 155 | + | const is32bit = unsafe.Sizeof(uintptr(0)) == 4 | |
| 155 | 156 | if is32bit { | |
| 156 | 157 | panic("purego: floats only supported on 64bit platforms") | |
| 157 | 158 | } | |
| @@ -417,8 +418,6 @@ func checkStructFieldsSupported(ty reflect.Type) { | |||
| 417 | 418 | } | |
| 418 | 419 | } | |
| 419 | 420 | ||
| 420 | - | const is32bit = unsafe.Sizeof(uintptr(0)) == 4 | |
| 421 | - | ||
| 422 | 421 | func roundUpTo8(val uintptr) uintptr { | |
| 423 | 422 | return (val + 7) &^ 7 | |
| 424 | 423 | } | |
| @@ -152,6 +152,7 @@ func RegisterFunc(fptr interface{}, cfn uintptr) { | |||||
| 152 | stack++ | 152 | stack++ | ||
| 153 | } | 153 | } | ||
| 154 | case reflect.Float32, reflect.Float64: | 154 | case reflect.Float32, reflect.Float64: | ||
| 155 | + | const is32bit = unsafe.Sizeof(uintptr(0)) == 4 | |||
| 155 | if is32bit { | 156 | if is32bit { | ||
| 156 | panic("purego: floats only supported on 64bit platforms") | 157 | panic("purego: floats only supported on 64bit platforms") | ||
| 157 | } | 158 | } | ||
| @@ -417,8 +418,6 @@ func checkStructFieldsSupported(ty reflect.Type) { | |||||
| 417 | } | 418 | } | ||
| 418 | } | 419 | } | ||
| 419 | 420 | ||||
| 420 | - | const is32bit = unsafe.Sizeof(uintptr(0)) == 4 | |||
| 421 | - | ||||
| 422 | func roundUpTo8(val uintptr) uintptr { | 421 | func roundUpTo8(val uintptr) uintptr { | ||
| 423 | return (val + 7) &^ 7 | 422 | return (val + 7) &^ 7 | ||
| 424 | } | 423 | } | ||
M internal/cgo/dlfcn_cgo_unix.go +34 -0
| @@ -9,9 +9,43 @@ package cgo | |||
| 9 | 9 | #cgo LDFLAGS: -ldl | |
| 10 | 10 | ||
| 11 | 11 | #include <dlfcn.h> | |
| 12 | + | #include <stdlib.h> | |
| 12 | 13 | */ | |
| 13 | 14 | import "C" | |
| 14 | 15 | ||
| 16 | + | import ( | |
| 17 | + | "errors" | |
| 18 | + | "unsafe" | |
| 19 | + | ) | |
| 20 | + | ||
| 21 | + | func Dlopen(filename string, flag int) (uintptr, error) { | |
| 22 | + | cfilename := C.CString(filename) | |
| 23 | + | defer C.free(unsafe.Pointer(cfilename)) | |
| 24 | + | handle := C.dlopen(cfilename, C.int(flag)) | |
| 25 | + | if handle == nil { | |
| 26 | + | return 0, errors.New(C.GoString(C.dlerror())) | |
| 27 | + | } | |
| 28 | + | return uintptr(handle), nil | |
| 29 | + | } | |
| 30 | + | ||
| 31 | + | func Dlsym(handle uintptr, symbol string) (uintptr, error) { | |
| 32 | + | csymbol := C.CString(symbol) | |
| 33 | + | defer C.free(unsafe.Pointer(csymbol)) | |
| 34 | + | symbolAddr := C.dlsym(*(*unsafe.Pointer)(unsafe.Pointer(&handle)), csymbol) | |
| 35 | + | if symbolAddr == nil { | |
| 36 | + | return 0, errors.New(C.GoString(C.dlerror())) | |
| 37 | + | } | |
| 38 | + | return uintptr(symbolAddr), nil | |
| 39 | + | } | |
| 40 | + | ||
| 41 | + | func Dlclose(handle uintptr) error { | |
| 42 | + | result := C.dlclose(*(*unsafe.Pointer)(unsafe.Pointer(&handle))) | |
| 43 | + | if result != 0 { | |
| 44 | + | return errors.New(C.GoString(C.dlerror())) | |
| 45 | + | } | |
| 46 | + | return nil | |
| 47 | + | } | |
| 48 | + | ||
| 15 | 49 | // all that is needed is to assign each dl function because then its | |
| 16 | 50 | // symbol will then be made available to the linker and linked to inside dlfcn.go | |
| 17 | 51 | var ( | |
| @@ -9,9 +9,43 @@ package cgo | |||||
| 9 | #cgo LDFLAGS: -ldl | 9 | #cgo LDFLAGS: -ldl | ||
| 10 | 10 | ||||
| 11 | #include <dlfcn.h> | 11 | #include <dlfcn.h> | ||
| 12 | + | #include <stdlib.h> | |||
| 12 | */ | 13 | */ | ||
| 13 | import "C" | 14 | import "C" | ||
| 14 | 15 | ||||
| 16 | + | import ( | |||
| 17 | + | "errors" | |||
| 18 | + | "unsafe" | |||
| 19 | + | ) | |||
| 20 | + | ||||
| 21 | + | func Dlopen(filename string, flag int) (uintptr, error) { | |||
| 22 | + | cfilename := C.CString(filename) | |||
| 23 | + | defer C.free(unsafe.Pointer(cfilename)) | |||
| 24 | + | handle := C.dlopen(cfilename, C.int(flag)) | |||
| 25 | + | if handle == nil { | |||
| 26 | + | return 0, errors.New(C.GoString(C.dlerror())) | |||
| 27 | + | } | |||
| 28 | + | return uintptr(handle), nil | |||
| 29 | + | } | |||
| 30 | + | ||||
| 31 | + | func Dlsym(handle uintptr, symbol string) (uintptr, error) { | |||
| 32 | + | csymbol := C.CString(symbol) | |||
| 33 | + | defer C.free(unsafe.Pointer(csymbol)) | |||
| 34 | + | symbolAddr := C.dlsym(*(*unsafe.Pointer)(unsafe.Pointer(&handle)), csymbol) | |||
| 35 | + | if symbolAddr == nil { | |||
| 36 | + | return 0, errors.New(C.GoString(C.dlerror())) | |||
| 37 | + | } | |||
| 38 | + | return uintptr(symbolAddr), nil | |||
| 39 | + | } | |||
| 40 | + | ||||
| 41 | + | func Dlclose(handle uintptr) error { | |||
| 42 | + | result := C.dlclose(*(*unsafe.Pointer)(unsafe.Pointer(&handle))) | |||
| 43 | + | if result != 0 { | |||
| 44 | + | return errors.New(C.GoString(C.dlerror())) | |||
| 45 | + | } | |||
| 46 | + | return nil | |||
| 47 | + | } | |||
| 48 | + | ||||
| 15 | // all that is needed is to assign each dl function because then its | 49 | // all that is needed is to assign each dl function because then its | ||
| 16 | // symbol will then be made available to the linker and linked to inside dlfcn.go | 50 | // symbol will then be made available to the linker and linked to inside dlfcn.go | ||
| 17 | var ( | 51 | var ( | ||