mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Improved OpenBSD support (#2317)
* add openbsd support, compiles and passses all tests * fix backtrace * gh actions should include openbsd artifacts
This commit is contained in:
@@ -143,7 +143,7 @@ const bool TRACK_MEMORY = DEBUG_SYMBOLS && (COMPILER_SAFE_MODE || TESTING);
|
||||
const bool X86_64 = ARCH_TYPE == X86_64;
|
||||
const bool X86 = ARCH_TYPE == X86;
|
||||
const bool AARCH64 = ARCH_TYPE == AARCH64;
|
||||
const bool NATIVE_STACKTRACE = LINUX || DARWIN || WIN32;
|
||||
const bool NATIVE_STACKTRACE = LINUX || DARWIN || OPENBSD || WIN32;
|
||||
const bool LINUX = LIBC && OS_TYPE == LINUX;
|
||||
const bool DARWIN = LIBC && os_is_darwin();
|
||||
const bool WIN32 = LIBC && OS_TYPE == WIN32;
|
||||
@@ -160,7 +160,7 @@ const bool MEMORY_SANITIZER = $$MEMORY_SANITIZER;
|
||||
const bool THREAD_SANITIZER = $$THREAD_SANITIZER;
|
||||
const bool ANY_SANITIZER = ADDRESS_SANITIZER || MEMORY_SANITIZER || THREAD_SANITIZER;
|
||||
const int LANGUAGE_DEV_VERSION = $$LANGUAGE_DEV_VERSION;
|
||||
const bool HAS_NATIVE_ERRNO = env::LINUX || env::ANDROID || env::DARWIN || env::WIN32;
|
||||
const bool HAS_NATIVE_ERRNO = env::LINUX || env::ANDROID || env::OPENBSD || env::DARWIN || env::WIN32;
|
||||
|
||||
macro bool os_is_darwin() @const
|
||||
{
|
||||
|
||||
@@ -11,6 +11,11 @@ extern fn int* __errno() @if(env::ANDROID);
|
||||
macro int errno() @if(env::ANDROID) => *__errno();
|
||||
macro void errno_set(int err) @if(env::ANDROID) => *(__errno()) = err;
|
||||
|
||||
// OpenBSD
|
||||
extern fn int* __errno() @if(env::OPENBSD);
|
||||
macro int errno() @if(env::OPENBSD) => *__errno();
|
||||
macro void errno_set(int err) @if(env::OPENBSD) => *(__errno()) = err;
|
||||
|
||||
// Darwin
|
||||
extern fn int* __error() @if(env::DARWIN);
|
||||
macro int errno() @if(env::DARWIN) => *__error();
|
||||
|
||||
60
lib/std/libc/os/openbsd.c3
Normal file
60
lib/std/libc/os/openbsd.c3
Normal file
@@ -0,0 +1,60 @@
|
||||
module libc @if(env::OPENBSD);
|
||||
|
||||
// Checked for x86_64
|
||||
|
||||
alias Blksize_t = int;
|
||||
alias Nlink_t = $typefrom(env::X86_64 ? uint.typeid : CUInt.typeid);
|
||||
alias Dev_t = int;
|
||||
alias Ino_t = ulong;
|
||||
alias Mode_t = uint;
|
||||
alias Blkcnt_t = long;
|
||||
alias Fflags_t = uint;
|
||||
|
||||
struct Stat @if(env::X86_64)
|
||||
{
|
||||
Mode_t st_mode;
|
||||
Dev_t st_dev;
|
||||
Ino_t st_ino;
|
||||
Nlink_t st_nlink;
|
||||
Uid_t st_uid;
|
||||
Gid_t st_gid;
|
||||
Dev_t st_rdev;
|
||||
TimeSpec st_atime;
|
||||
TimeSpec st_mtime;
|
||||
TimeSpec st_ctime;
|
||||
Off_t st_size;
|
||||
Blkcnt_t st_blocks;
|
||||
Blksize_t st_blksize;
|
||||
Fflags_t st_flags;
|
||||
uint st_gen;
|
||||
ulong[10] st_spare;
|
||||
}
|
||||
|
||||
// TODO: Investigate if this needs to be fixed
|
||||
struct Stat @if(!env::X86_64)
|
||||
{
|
||||
Dev_t st_dev;
|
||||
Ino_t st_ino;
|
||||
Mode_t st_mode;
|
||||
Nlink_t st_nlink;
|
||||
Uid_t st_uid;
|
||||
Gid_t st_gid;
|
||||
Dev_t st_rdev;
|
||||
CInt __pad1;
|
||||
Off_t st_size;
|
||||
Blksize_t st_blksize;
|
||||
CInt __pad2;
|
||||
Blkcnt_t st_blocks;
|
||||
Time_t st_atime;
|
||||
long st_atime_nsec;
|
||||
Time_t st_mtime;
|
||||
long st_mtime_nsec;
|
||||
Time_t st_ctime;
|
||||
long st_ctime_nsec;
|
||||
CInt[2] __unused;
|
||||
}
|
||||
|
||||
extern fn CInt stat(ZString path, Stat* stat);
|
||||
|
||||
extern fn CInt get_nprocs();
|
||||
extern fn CInt get_nprocs_conf();
|
||||
@@ -87,11 +87,12 @@ fn void*[] capture_current(void*[] buffer)
|
||||
|
||||
alias BacktraceList = List{Backtrace};
|
||||
|
||||
alias symbolize_backtrace @if(env::LINUX) = linux::symbolize_backtrace;
|
||||
alias symbolize_backtrace @if(env::WIN32) = win32::symbolize_backtrace;
|
||||
alias symbolize_backtrace @if(env::DARWIN) = darwin::symbolize_backtrace;
|
||||
alias symbolize_backtrace @if(env::LINUX) = linux::symbolize_backtrace;
|
||||
alias symbolize_backtrace @if(env::WIN32) = win32::symbolize_backtrace;
|
||||
alias symbolize_backtrace @if(env::DARWIN) = darwin::symbolize_backtrace;
|
||||
alias symbolize_backtrace @if(env::OPENBSD) = openbsd::symbolize_backtrace;
|
||||
|
||||
fn BacktraceList? symbolize_backtrace(Allocator allocator, void*[] backtrace) @if(!env::NATIVE_STACKTRACE)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +1,74 @@
|
||||
module std::os::openbsd @if(env::OPENBSD);
|
||||
import libc, std::os, std::collections::list;
|
||||
|
||||
extern fn ZString* backtrace_symbols_fmt(void **addrlist, usz len, ZString fmt);
|
||||
|
||||
fn Backtrace? backtrace_line_parse(Allocator allocator, String obj, String addr2line) @local
|
||||
{
|
||||
@stack_mem(256; Allocator mem)
|
||||
{
|
||||
String[] parts = addr2line.trim().split(mem, " at ");
|
||||
if (parts.len != 2) return NOT_FOUND?;
|
||||
|
||||
uint line = 0;
|
||||
String source = "";
|
||||
if (!parts[1].contains("?") && parts[1].contains(":"))
|
||||
{
|
||||
usz index = parts[1].rindex_of_char(':')!;
|
||||
source = parts[1][:index];
|
||||
line = parts[1][index + 1..].to_uint()!;
|
||||
}
|
||||
return {
|
||||
.function = parts[0].copy(allocator),
|
||||
.object_file = obj.copy(allocator),
|
||||
.file = source.copy(allocator),
|
||||
.line = line,
|
||||
.allocator = allocator,
|
||||
.is_inline = false,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
fn void? backtrace_add_addr2line(Allocator allocator, BacktraceList* list, String obj, String addr2line) @local
|
||||
{
|
||||
list.push(backtrace_line_parse(allocator, obj, addr2line)!);
|
||||
}
|
||||
|
||||
fn void? backtrace_add_from_exec(Allocator allocator, BacktraceList* list, String fun, String obj) @local
|
||||
{
|
||||
char[1024] buf @noinit;
|
||||
String addr2line = process::execute_stdout_to_buffer(&buf, {"llvm-addr2line", "-fpe", obj, fun})!;
|
||||
return backtrace_add_addr2line(allocator, list, obj, addr2line);
|
||||
}
|
||||
|
||||
fn void? backtrace_add_element(Allocator allocator, BacktraceList *list, String fun, String obj) @local
|
||||
{
|
||||
return backtrace_add_from_exec(allocator, list, fun, obj);
|
||||
}
|
||||
|
||||
fn BacktraceList? symbolize_backtrace(Allocator allocator, void*[] backtrace)
|
||||
{
|
||||
BacktraceList list;
|
||||
list.init(allocator, backtrace.len);
|
||||
defer catch
|
||||
{
|
||||
foreach (trace : list)
|
||||
{
|
||||
trace.free();
|
||||
}
|
||||
list.free();
|
||||
}
|
||||
|
||||
ZString *strings = backtrace_symbols_fmt(backtrace.ptr, backtrace.len, "%n%D %f");
|
||||
|
||||
for (int i = 0; i < backtrace.len; i++) {
|
||||
String full = strings[i].str_view();
|
||||
Splitter iter = full.tokenize(" ");
|
||||
String fun = iter.next()!;
|
||||
String obj = iter.next()!;
|
||||
backtrace_add_element(allocator, &list, fun, obj)!;
|
||||
}
|
||||
|
||||
free(strings);
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -58,7 +58,9 @@ const CInt WUNTRACES = 2;
|
||||
JmpBuf backtrace_jmpbuf @local;
|
||||
alias BacktraceFn = fn CInt(void** buffer, CInt size);
|
||||
|
||||
fn CInt backtrace(void** buffer, CInt size)
|
||||
extern fn CInt backtrace(void** buffer, CInt size) @if(env::OPENBSD);
|
||||
|
||||
fn CInt backtrace(void** buffer, CInt size) @if(!env::OPENBSD)
|
||||
{
|
||||
if (size < 1) return 0;
|
||||
void* handle = libc::dlopen("libc.so.6", libc::RTLD_LAZY|libc::RTLD_NODELETE);
|
||||
|
||||
Reference in New Issue
Block a user