Skip to content

Commit

Permalink
Call C dlfcn functions directly on android (#263)
Browse files Browse the repository at this point in the history
  • Loading branch information
TotallyGamerJet authored Aug 5, 2024
1 parent b9dbbd0 commit 9340835
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 13 deletions.
2 changes: 1 addition & 1 deletion dlfcn.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors

//go:build (darwin || freebsd || linux) && !faketime
//go:build (darwin || freebsd || linux) && !android && !faketime

package purego

Expand Down
34 changes: 34 additions & 0 deletions dlfcn_android.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2024 The Ebitengine Authors

package purego

import "github.com/ebitengine/purego/internal/cgo"

// Source for constants: https://android.googlesource.com/platform/bionic/+/refs/heads/main/libc/include/dlfcn.h

const (
is64bit = 1 << (^uintptr(0) >> 63) / 2
is32bit = 1 - is64bit
RTLD_DEFAULT = is32bit * 0xffffffff
RTLD_LAZY = 0x00000001
RTLD_NOW = is64bit * 0x00000002
RTLD_LOCAL = 0x00000000
RTLD_GLOBAL = is64bit*0x00100 | is32bit*0x00000002
)

func Dlopen(path string, mode int) (uintptr, error) {
return cgo.Dlopen(path, mode)
}

func Dlsym(handle uintptr, name string) (uintptr, error) {
return cgo.Dlsym(handle, name)
}

func Dlclose(handle uintptr) error {
return cgo.Dlclose(handle)
}

func loadSymbol(handle uintptr, name string) (uintptr, error) {
return Dlsym(handle, name)
}
10 changes: 5 additions & 5 deletions dlfcn_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ package purego
// Source for constants: https://opensource.apple.com/source/dyld/dyld-360.14/include/dlfcn.h.auto.html

const (
RTLD_DEFAULT = ^uintptr(0) - 1 // Pseudo-handle for dlsym so search for any loaded symbol
RTLD_LAZY = 0x1 // Relocations are performed at an implementation-dependent time.
RTLD_NOW = 0x2 // Relocations are performed when the object is loaded.
RTLD_LOCAL = 0x4 // All symbols are not made available for relocation processing by other modules.
RTLD_GLOBAL = 0x8 // All symbols are available for relocation processing of other modules.
RTLD_DEFAULT = 1<<64 - 2 // Pseudo-handle for dlsym so search for any loaded symbol
RTLD_LAZY = 0x1 // Relocations are performed at an implementation-dependent time.
RTLD_NOW = 0x2 // Relocations are performed when the object is loaded.
RTLD_LOCAL = 0x4 // All symbols are not made available for relocation processing by other modules.
RTLD_GLOBAL = 0x8 // All symbols are available for relocation processing of other modules.
)

//go:cgo_import_dynamic purego_dlopen dlopen "/usr/lib/libSystem.B.dylib"
Expand Down
11 changes: 6 additions & 5 deletions dlfcn_freebsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ package purego

// Constants as defined in https://github.com/freebsd/freebsd-src/blob/main/include/dlfcn.h
const (
RTLD_DEFAULT = ^uintptr(0) - 2 // Pseudo-handle for dlsym so search for any loaded symbol
RTLD_LAZY = 0x00001 // Relocations are performed at an implementation-dependent time.
RTLD_NOW = 0x00002 // Relocations are performed when the object is loaded.
RTLD_LOCAL = 0x00000 // All symbols are not made available for relocation processing by other modules.
RTLD_GLOBAL = 0x00100 // All symbols are available for relocation processing of other modules.
intSize = 32 << (^uint(0) >> 63) // 32 or 64
RTLD_DEFAULT = 1<<intSize - 2 // Pseudo-handle for dlsym so search for any loaded symbol
RTLD_LAZY = 0x00000001 // Relocations are performed at an implementation-dependent time.
RTLD_NOW = 0x00000002 // Relocations are performed when the object is loaded.
RTLD_LOCAL = 0x00000000 // All symbols are not made available for relocation processing by other modules.
RTLD_GLOBAL = 0x00000100 // All symbols are available for relocation processing of other modules.
)
2 changes: 2 additions & 0 deletions dlfcn_linux.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors

//go:build !android

package purego

// Source for constants: https://codebrowser.dev/glibc/glibc/bits/dlfcn.h.html
Expand Down
3 changes: 1 addition & 2 deletions func.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ func RegisterFunc(fptr interface{}, cfn uintptr) {
stack++
}
case reflect.Float32, reflect.Float64:
const is32bit = unsafe.Sizeof(uintptr(0)) == 4
if is32bit {
panic("purego: floats only supported on 64bit platforms")
}
Expand Down Expand Up @@ -417,8 +418,6 @@ func checkStructFieldsSupported(ty reflect.Type) {
}
}

const is32bit = unsafe.Sizeof(uintptr(0)) == 4

func roundUpTo8(val uintptr) uintptr {
return (val + 7) &^ 7
}
Expand Down
34 changes: 34 additions & 0 deletions internal/cgo/dlfcn_cgo_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,43 @@ package cgo
#cgo LDFLAGS: -ldl
#include <dlfcn.h>
#include <stdlib.h>
*/
import "C"

import (
"errors"
"unsafe"
)

func Dlopen(filename string, flag int) (uintptr, error) {
cfilename := C.CString(filename)
defer C.free(unsafe.Pointer(cfilename))
handle := C.dlopen(cfilename, C.int(flag))
if handle == nil {
return 0, errors.New(C.GoString(C.dlerror()))
}
return uintptr(handle), nil
}

func Dlsym(handle uintptr, symbol string) (uintptr, error) {
csymbol := C.CString(symbol)
defer C.free(unsafe.Pointer(csymbol))
symbolAddr := C.dlsym(*(*unsafe.Pointer)(unsafe.Pointer(&handle)), csymbol)
if symbolAddr == nil {
return 0, errors.New(C.GoString(C.dlerror()))
}
return uintptr(symbolAddr), nil
}

func Dlclose(handle uintptr) error {
result := C.dlclose(*(*unsafe.Pointer)(unsafe.Pointer(&handle)))
if result != 0 {
return errors.New(C.GoString(C.dlerror()))
}
return nil
}

// all that is needed is to assign each dl function because then its
// symbol will then be made available to the linker and linked to inside dlfcn.go
var (
Expand Down

0 comments on commit 9340835

Please sign in to comment.