mirror of https://github.com/ceph/go-ceph
internal: add dlsym package for working with dynamically loaded symbols
The dlsym package provides LookupSymbol() which resolves a named symbol (like "rbd_clone4") and returns a unsafe.Pointer to it. The caller is expected to cast the symbol to function that can be called. Signed-off-by: Niels de Vos <ndevos@ibm.com>
This commit is contained in:
parent
9531dd692a
commit
0460442cba
|
@ -0,0 +1,41 @@
|
||||||
|
package dlsym
|
||||||
|
|
||||||
|
// #cgo LDFLAGS: -ldl
|
||||||
|
//
|
||||||
|
// #include <stdlib.h>
|
||||||
|
// #include <dlfcn.h>
|
||||||
|
//
|
||||||
|
// #ifndef RTLD_DEFAULT /* from dlfcn.h */
|
||||||
|
// #define RTLD_DEFAULT ((void *) 0)
|
||||||
|
// #endif
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ErrUndefinedSymbol is returned by LookupSymbol when the requested symbol
|
||||||
|
// could not be found.
|
||||||
|
var ErrUndefinedSymbol = errors.New("symbol not found")
|
||||||
|
|
||||||
|
// LookupSymbol resolves the named symbol from the already dynamically loaded
|
||||||
|
// libraries. If the symbol is found, a pointer to it is returned, in case of a
|
||||||
|
// failure, the message provided by dlerror() is included in the error message.
|
||||||
|
func LookupSymbol(symbol string) (unsafe.Pointer, error) {
|
||||||
|
cSymName := C.CString(symbol)
|
||||||
|
defer C.free(unsafe.Pointer(cSymName))
|
||||||
|
|
||||||
|
// clear dlerror before looking up the symbol
|
||||||
|
C.dlerror()
|
||||||
|
// resolve the address of the symbol
|
||||||
|
sym := C.dlsym(C.RTLD_DEFAULT, cSymName)
|
||||||
|
e := C.dlerror()
|
||||||
|
dlerr := C.GoString(e)
|
||||||
|
if dlerr != "" {
|
||||||
|
return nil, fmt.Errorf("%w: %s", ErrUndefinedSymbol, dlerr)
|
||||||
|
}
|
||||||
|
|
||||||
|
return sym, nil
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package dlsym
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestLookupSymbol(t *testing.T) {
|
||||||
|
t.Run("ValidSymbol", func(t *testing.T) {
|
||||||
|
sym, err := LookupSymbol("dlsym")
|
||||||
|
assert.NotNil(t, sym)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("InvalidSymbol", func(t *testing.T) {
|
||||||
|
sym, err := LookupSymbol("go_ceph_dlsym")
|
||||||
|
assert.Nil(t, sym)
|
||||||
|
assert.True(t, errors.Is(err, ErrUndefinedSymbol))
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in New Issue