about summary refs log tree commit diff
path: root/vendor/github.com/radareorg/r2pipe-go/native.go
diff options
context:
space:
mode:
authorEmile <git@emile.space>2024-08-16 19:50:26 +0200
committerEmile <git@emile.space>2024-08-16 19:50:26 +0200
commit1a57267a17c2fc17fb6e104846fabc3e363c326c (patch)
tree1e574e3a80622086dc3c81ff9cba65ef7049b1a9 /vendor/github.com/radareorg/r2pipe-go/native.go
initial commit
Diffstat (limited to 'vendor/github.com/radareorg/r2pipe-go/native.go')
-rw-r--r--vendor/github.com/radareorg/r2pipe-go/native.go161
1 files changed, 161 insertions, 0 deletions
diff --git a/vendor/github.com/radareorg/r2pipe-go/native.go b/vendor/github.com/radareorg/r2pipe-go/native.go
new file mode 100644
index 0000000..2283717
--- /dev/null
+++ b/vendor/github.com/radareorg/r2pipe-go/native.go
@@ -0,0 +1,161 @@
+// radare - LGPL - Copyright 2017 - pancake
+
+package r2pipe
+
+//#cgo linux LDFLAGS: -ldl
+//#include <stdio.h>
+//#include <dlfcn.h>
+// #include <stdlib.h>
+// void *gor_core_new(void *f) {
+// 	void *(*rcn)();
+// 	rcn = (void *(*)())f;
+// 	return rcn();
+// }
+//
+// void gor_core_free(void *f, void *arg) {
+// 	void (*fr)(void *);
+// 	fr = (void (*)(void *))f;
+// 	fr(arg);
+// }
+//
+// char *gor_core_cmd_str(void *f, void *arg, char *arg2) {
+// 	char *(*cmdstr)(void *, char *);
+// 	cmdstr = (char *(*)(void *, char *))f;
+// 	return cmdstr(arg, arg2);
+// }
+import "C"
+
+import (
+	"errors"
+	"fmt"
+	"os"
+	"runtime"
+	"unsafe"
+)
+
+type Ptr = unsafe.Pointer
+
+// *struct{}
+
+var (
+	lib            Ptr = nil
+	r_core_new     func() Ptr
+	r_core_free    func(Ptr)
+	r_core_cmd_str func(Ptr, string) string
+)
+
+type DL struct {
+	handle unsafe.Pointer
+	name   string
+}
+
+func libpath(libname string) string {
+	paths := []string{"/usr/local/lib", "/usr/lib", "/lib"}
+	for _, path := range paths {
+		if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) {
+			// path/to/whatever does not exist
+		} else {
+			// file exists
+			return path + "/" + libname
+		}
+	}
+	return libname
+}
+
+func dlOpen(path string) (*DL, error) {
+	var ret DL
+	switch runtime.GOOS {
+	case "darwin":
+		path = path + ".dylib"
+	case "windows":
+		path = path + ".dll"
+	default:
+		path = path + ".so" //linux/bsds
+	}
+	path = libpath(path)
+	cpath := C.CString(path)
+	if cpath == nil {
+		return nil, errors.New("Failed to get cpath")
+	}
+	//r2pioe only uses flag 0
+	ret.handle = C.dlopen(cpath, 0)
+	ret.name = path
+	C.free(unsafe.Pointer(cpath))
+	if ret.handle == nil {
+		return nil, errors.New(fmt.Sprintf("Failed to open %s", path))
+	}
+	return &ret, nil
+}
+
+func dlSym(dl *DL, name string) (unsafe.Pointer, error) {
+	cname := C.CString(name)
+	if cname == nil {
+		return nil, errors.New("Fail")
+	}
+	handle := C.dlsym(dl.handle, cname)
+	C.free(unsafe.Pointer(cname))
+	if handle == nil {
+		return nil, errors.New("Fail")
+	}
+	return handle, nil
+}
+
+func NativeLoad() error {
+	if lib != nil {
+		return nil
+	}
+	lib, err := dlOpen("libr_core")
+	_ = lib
+	if err != nil {
+		return err
+	}
+	handle1, _ := dlSym(lib, "r_core_new")
+	r_core_new = func() Ptr {
+		a := (Ptr)(C.gor_core_new(handle1))
+		return a
+	}
+	handle2, _ := dlSym(lib, "r_core_free")
+	r_core_free = func(p Ptr) {
+		C.gor_core_free(handle2, unsafe.Pointer(p))
+	}
+	handle3, _ := dlSym(lib, "r_core_cmd_str")
+	r_core_cmd_str = func(p Ptr, s string) string {
+		a := C.CString(s)
+		b := C.gor_core_cmd_str(handle3, unsafe.Pointer(p), a)
+		C.free(unsafe.Pointer(a))
+		return C.GoString(b)
+	}
+	return nil
+}
+
+func (r2p *Pipe) NativeCmd(cmd string) (string, error) {
+	res := r_core_cmd_str(r2p.Core, cmd)
+	return res, nil
+}
+
+func (r2p *Pipe) NativeClose() error {
+	r_core_free(r2p.Core)
+	r2p.Core = nil
+	return nil
+}
+
+func NewNativePipe(file string) (*Pipe, error) {
+	if err := NativeLoad(); err != nil {
+		return nil, err
+	}
+	r2 := r_core_new()
+	r2p := &Pipe{
+		File: file,
+		Core: r2,
+		cmd: func(r2p *Pipe, cmd string) (string, error) {
+			return r2p.NativeCmd(cmd)
+		},
+		close: func(r2p *Pipe) error {
+			return r2p.NativeClose()
+		},
+	}
+	if file != "" {
+		r2p.NativeCmd("o " + file)
+	}
+	return r2p, nil
+}