github.com/eh-steve/goloader@v0.0.0-20240111193454-90ff3cfdae39/libc/libc_cgo/lookup_libc_cgo.go (about)

     1  //go:build cgo && !windows
     2  // +build cgo,!windows
     3  
     4  package libc_cgo
     5  
     6  /*
     7  #cgo linux LDFLAGS: -ldl
     8  #include <dlfcn.h>
     9  #include <limits.h>
    10  #include <stdlib.h>
    11  #include <stdint.h>
    12  
    13  #include <stdio.h>
    14  
    15  static uintptr_t selfOpen(char** err) {
    16  	void* h = dlopen(NULL, RTLD_NOW|RTLD_GLOBAL);
    17  	if (h == NULL) {
    18  		*err = (char*)dlerror();
    19  	}
    20  	return (uintptr_t)h;
    21  }
    22  
    23  static void* lookup(uintptr_t h, const char* name, char** err) {
    24  	void* r = dlsym((void*)h, name);
    25  	if (r == NULL) {
    26  		*err = (char*)dlerror();
    27  	}
    28  	return r;
    29  }
    30  */
    31  import "C"
    32  
    33  import (
    34  	"fmt"
    35  	"unsafe"
    36  )
    37  
    38  var selfDlHandle C.uintptr_t
    39  
    40  func init() {
    41  	var cErr *C.char
    42  	h := C.selfOpen(&cErr)
    43  	if h == 0 {
    44  		panic(C.GoString(cErr))
    45  	}
    46  	selfDlHandle = h
    47  }
    48  
    49  func LookupDynamicSymbol(symName string) (uintptr, error) {
    50  	cName := C.CString(symName)
    51  	defer C.free(unsafe.Pointer(cName))
    52  	var cErr *C.char
    53  	addr := C.lookup(selfDlHandle, cName, &cErr)
    54  	if addr == nil {
    55  		return 0, fmt.Errorf("failed to lookup symbol %s: %s", symName, string(C.GoString(cErr)))
    56  	}
    57  	return uintptr(addr), nil
    58  }