-
Notifications
You must be signed in to change notification settings - Fork 71
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for __dso_handle #114
Comments
Isn't it possible to just use Dlsym(lib, "__dso_handle")? Note that it returns a pointer to the value. |
That returns an error ( |
You are correct that it's unique to each dynamic object according to this StackOverflow post. I'm not sure how to reference it in Go. I am not familiar with this API either so more research needs to be done |
Something that would help here is the ability to lookup a given symbol/C-style global variable in the current process. But I don't know how feasible that is without full cgo. |
How would you do this with Cgo? |
|
So, cgo outputs Go code that links to the C symbol. // Code generated by cmd/cgo; DO NOT EDIT.
//line /Users/jarrettkuklis/Documents/GolandProjects/purego/test/main.go:1:1
package main
//#include <os/log.h>
import _ "unsafe"
import (
"fmt"
"unsafe"
)
func main() {
fmt.Printf("%x\n", unsafe.Pointer(&( /*line :11:37*/*_Cvar___dso_handle /*line :11:50*/)))
}
// --- _cgo_types.go ---
type _Ctype_struct_mach_header struct {
magic _Ctype_uint32_t
cputype _Ctype_int32_t
cpusubtype _Ctype_int32_t
filetype _Ctype_uint32_t
ncmds _Ctype_uint32_t
sizeofcmds _Ctype_uint32_t
flags _Ctype_uint32_t
}
//go:linkname __cgo___dso_handle __dso_handle
//go:cgo_import_static __dso_handle
var __cgo___dso_handle byte
var _Cvar___dso_handle *_Ctype_struct_mach_header = (*_Ctype_struct_mach_header)(unsafe.Pointer(&__cgo___dso_handle)) If you go ahead and copy this into a plan Go code you'll get something like this. package main
import (
"fmt"
"unsafe"
)
type mach_header struct {
magic uint32
cputype int32
cpusubtype int32
filetype uint32
ncmds uint32
sizeofcmds uint32
flags uint32
}
//go:linkname __cgo___dso_handle __dso_handle
//go:cgo_import_static __dso_handle
var __cgo___dso_handle byte
var _Cvar___dso_handle *mach_header = (*mach_header)(unsafe.Pointer(&__cgo___dso_handle))
func main() {
fmt.Printf("%x\n", unsafe.Pointer(_Cvar___dso_handle))
} Although this doesn't compile because the Now it finally compiles but points to some really low address (0x680000) when Cgo version points to a higher address (0x104280000). And when you try to dereference the go version it will SIGSEGV. I think this is an issue with how |
I have had some time to look into this. The reason trying to load it with purego doesn't work is because However, the data for this symbol is still able to be obtained since it is just the information about the currently running macho file. This information can be grabbed using just the stdlib: package main
import (
"debug/macho"
"fmt"
"log"
"os"
"structs"
)
// https://opensource.apple.com/source/xnu/xnu-2050.18.24/EXTERNAL_HEADERS/mach-o/loader.h
type Mach_header struct {
_ structs.HostLayout // ensures it matches system layout
Magic uint32
Cputype int32
Cpusubtype int32
Filetype uint32
Ncmds uint32
Sizeofcmds uint32
Flags uint32
_ uint32 // reserved
}
func main() {
dir, err := os.Executable()
if err != nil {
log.Fatal(err)
}
ex, err := macho.Open(dir) // or OpenFat if it is a fat macho
if err != nil {
log.Fatal(err)
}
header := Mach_header{
Magic: ex.FileHeader.Magic,
Cputype: int32(ex.FileHeader.Cpu),
Cpusubtype: int32(ex.FileHeader.SubCpu),
Filetype: uint32(ex.FileHeader.Type),
Ncmds: ex.FileHeader.Ncmd,
Sizeofcmds: ex.FileHeader.Cmdsz,
Flags: ex.FileHeader.Flags,
}
fmt.Println(header)
} I checked and this results in the exact same data as the |
@TotallyGamerJet I missed your update at first - thank you! I will try this and reply back here. |
Hello,
I thought I would try using purego to interface with macOS's unified logging framework. However I've hit a snag.
The unified logger uses a set of macros like
os_log_debug
that ultimately call_os_log_internal
. This is exported by libSystem.B.dylib - so far so good. However, the first argument to that function is&__dso_handle
, which is defined in C headers asI'm not sure how to resolve this symbol. It's not exported by libSystem.B.dylib, but rather it's specific to the running executable. I don't understand this fully, but I've read that it's actually dynamically generated by the linker.
Is there a way to reference this symbol with purego, or is this not possible?
The text was updated successfully, but these errors were encountered: