fuck submodules part 3
This commit is contained in:
parent
a1a94dec51
commit
88dee75f7d
26 changed files with 2962 additions and 0 deletions
160
libraries/back/back_darwin.odin
Normal file
160
libraries/back/back_darwin.odin
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
#+vet explicit-allocators
|
||||
#+private file
|
||||
package back
|
||||
|
||||
@require import "base:runtime"
|
||||
|
||||
@require import "core:strings"
|
||||
@require import "core:sys/posix"
|
||||
|
||||
when !USE_FALLBACK {
|
||||
|
||||
foreign import system "system:System.framework"
|
||||
|
||||
// NOTE: CoreSymbolication is a private framework, Apple is allowed to break it and doesn't provide
|
||||
// headers, although the API has as of my knowledge been the same in the past 10 years at least.
|
||||
@(extra_linker_flags="-iframework /System/Library/PrivateFrameworks")
|
||||
foreign import symbolication "system:CoreSymbolication.framework"
|
||||
|
||||
@(private="package")
|
||||
_Trace_Entry :: rawptr
|
||||
|
||||
@(private="package")
|
||||
_trace :: #force_no_inline proc(buf: Trace) -> (n: int) {
|
||||
ctx: unw_context_t
|
||||
cursor: unw_cursor_t
|
||||
|
||||
ret: i32
|
||||
ret = unw_getcontext(&ctx)
|
||||
assert(ret == 0)
|
||||
ret = unw_init_local(&cursor, &ctx)
|
||||
assert(ret == 0)
|
||||
|
||||
// Skip this function's frame and the caller.
|
||||
if unw_step(&cursor) <= 0 { return }
|
||||
|
||||
pc: uintptr
|
||||
for ; unw_step(&cursor) > 0 && n < len(buf); n += 1 {
|
||||
ret = unw_get_reg(&cursor, .IP, &pc)
|
||||
assert(ret == 0)
|
||||
buf[n] = rawptr(pc)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@(private="package")
|
||||
_lines_destroy :: proc(lines: []Line, allocator: runtime.Allocator) {
|
||||
for line in lines {
|
||||
delete(line.location, allocator)
|
||||
delete(line.symbol, allocator)
|
||||
}
|
||||
delete(lines, allocator)
|
||||
}
|
||||
|
||||
@(private="package")
|
||||
_lines :: proc(bt: Trace, allocator, _: runtime.Allocator) -> (out: []Line, err: Lines_Error) {
|
||||
out = make([]Line, len(bt), allocator)
|
||||
defer if err != nil { _lines_destroy(out, allocator) }
|
||||
|
||||
symbolicator := CSSymbolicatorCreateWithPid(posix.getpid())
|
||||
defer CSRelease(symbolicator)
|
||||
|
||||
for &msg, i in out {
|
||||
symbol := CSSymbolicatorGetSymbolWithAddressAtTime(symbolicator, uintptr(bt[i]), CSNow)
|
||||
info := CSSymbolicatorGetSourceInfoWithAddressAtTime(symbolicator, uintptr(bt[i]), CSNow)
|
||||
|
||||
msg.symbol = strings.clone_from(CSSymbolGetName(symbol), allocator)
|
||||
|
||||
// No debug info.
|
||||
if CSIsNull(info) {
|
||||
owner := CSSymbolGetSymbolOwner(symbol)
|
||||
msg.location = strings.clone_from(CSSymbolOwnerGetPath(owner), allocator)
|
||||
} else {
|
||||
path := string(CSSourceInfoGetPath(info))
|
||||
location := strings.builder_make(allocator)
|
||||
strings.write_string(&location, path)
|
||||
when ODIN_ERROR_POS_STYLE == .Default {
|
||||
strings.write_byte(&location, '(')
|
||||
strings.write_int (&location, int(CSSourceInfoGetLineNumber(info)))
|
||||
strings.write_byte(&location, ')')
|
||||
} else when ODIN_ERROR_POS_STYLE == .Unix {
|
||||
strings.write_byte(&location, ':')
|
||||
strings.write_int (&location, int(CSSourceInfoGetLineNumber(info)))
|
||||
} else {
|
||||
#panic("unhandled ODIN_ERROR_POS_STYLE")
|
||||
}
|
||||
msg.location = strings.to_string(location)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
CSTypeRef :: struct {
|
||||
csCppData: rawptr,
|
||||
csCppObj: rawptr,
|
||||
}
|
||||
|
||||
CSSymbolicatorRef :: distinct CSTypeRef
|
||||
CSSymbolRef :: distinct CSTypeRef
|
||||
CSSourceInfoRef :: distinct CSTypeRef
|
||||
CSSymbolOwnerRef :: distinct CSTypeRef
|
||||
|
||||
CSNow :: 0x80000000
|
||||
|
||||
foreign symbolication {
|
||||
@(link_name="CSIsNull")
|
||||
_CSIsNull :: proc(ref: CSTypeRef) -> bool ---
|
||||
@(link_name="CSRelease")
|
||||
_CSRelease :: proc(ref: CSTypeRef) ---
|
||||
|
||||
CSSymbolicatorCreateWithPid :: proc(pid: posix.pid_t) -> CSSymbolicatorRef ---
|
||||
|
||||
CSSymbolicatorGetSymbolWithAddressAtTime :: proc(symbolicator: CSSymbolicatorRef, addr: uintptr, time: u64) -> CSSymbolRef ---
|
||||
CSSymbolicatorGetSourceInfoWithAddressAtTime :: proc(symbolicator: CSSymbolicatorRef, adrr: uintptr, time: u64) -> CSSourceInfoRef ---
|
||||
|
||||
CSSymbolGetName :: proc(symbol: CSSymbolRef) -> cstring ---
|
||||
CSSymbolGetSymbolOwner :: proc(symbol: CSSymbolRef) -> CSSymbolOwnerRef ---
|
||||
|
||||
CSSourceInfoGetPath :: proc(info: CSSourceInfoRef) -> cstring ---
|
||||
CSSourceInfoGetLineNumber :: proc(info: CSSourceInfoRef) -> i32 ---
|
||||
CSSourceInfoGetSymbol :: proc(info: CSSourceInfoRef) -> CSSymbolRef ---
|
||||
|
||||
CSSymbolOwnerGetPath :: proc(owner: CSSymbolOwnerRef) -> cstring ---
|
||||
}
|
||||
|
||||
CSRelease :: #force_inline proc(ref: $T) {
|
||||
_CSRelease(CSTypeRef(ref))
|
||||
}
|
||||
|
||||
CSIsNull :: #force_inline proc(ref: $T) -> bool {
|
||||
return _CSIsNull(CSTypeRef(ref))
|
||||
}
|
||||
|
||||
// These could actually be smaller, but then we would have to define and check the size on each
|
||||
// architecture, the sizes here are the largest they can be.
|
||||
_LIBUNWIND_CONTEXT_SIZE :: 167
|
||||
_LIBUNWIND_CURSOR_SIZE :: 204
|
||||
|
||||
unw_context_t :: struct {
|
||||
data: [_LIBUNWIND_CONTEXT_SIZE]u64,
|
||||
}
|
||||
|
||||
unw_cursor_t :: struct {
|
||||
data: [_LIBUNWIND_CURSOR_SIZE]u64,
|
||||
}
|
||||
|
||||
// Cross-platform registers, each architecture has additional registers but these are enough for us.
|
||||
Register :: enum i32 {
|
||||
SP = -2,
|
||||
IP = -1,
|
||||
}
|
||||
|
||||
foreign system {
|
||||
unw_getcontext :: proc(ctx: ^unw_context_t) -> i32 ---
|
||||
unw_init_local :: proc(cursor: ^unw_cursor_t, ctx: ^unw_context_t) -> i32 ---
|
||||
unw_get_reg :: proc(cursor: ^unw_cursor_t, name: Register, reg: ^uintptr) -> i32 ---
|
||||
unw_step :: proc(cursor: ^unw_cursor_t) -> i32 ---
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue