Add initial FreeBSD support (#1430)

Add initial FreeBSD support
This commit is contained in:
wilsonk
2024-09-11 14:38:53 -06:00
committed by GitHub
parent 2b0d2892af
commit 1b54a99f6a
11 changed files with 198 additions and 17 deletions

View File

@@ -146,6 +146,7 @@ const bool POSIX = LIBC && os_is_posix();
const bool OPENBSD = LIBC && OS_TYPE == OPENBSD;
const bool FREEBSD = LIBC && OS_TYPE == FREEBSD;
const bool NETBSD = LIBC && OS_TYPE == NETBSD;
const bool BSD_FAMILY = env::FREEBSD || env::OPENBSD || env::NETBSD;
const bool WASI = LIBC && OS_TYPE == WASI;
const bool WASM_NOLIBC @builtin = !LIBC && ARCH_TYPE == ArchType.WASM32 || ARCH_TYPE == ArchType.WASM64;
const bool ADDRESS_SANITIZER = $$ADDRESS_SANITIZER;

View File

@@ -1,11 +1,11 @@
module std::io::os;
import libc, std::os, std::io;
fn void! native_stat(Stat* stat, String path) @if(env::DARWIN || env::LINUX)
fn void! native_stat(Stat* stat, String path) @if(env::DARWIN || env::LINUX || env::BSD_FAMILY)
{
@pool()
{
$if env::DARWIN || env::LINUX:
$if env::DARWIN || env::LINUX || env::BSD_FAMILY:
int res = libc::stat(path.zstr_tcopy(), stat);
$else
unreachable("Stat unimplemented");
@@ -71,6 +71,9 @@ fn bool native_file_or_dir_exists(String path)
{
$switch
$case env::DARWIN:
$case env::FREEBSD:
$case env::NETBSD:
$case env::OPENBSD:
$case env::LINUX:
Stat stat;
return @ok(native_stat(&stat, path));
@@ -93,6 +96,9 @@ fn bool native_is_file(String path)
{
$switch
$case env::DARWIN:
$case env::FREEBSD:
$case env::NETBSD:
$case env::OPENBSD:
$case env::LINUX:
Stat stat;
return @ok(native_stat(&stat, path)) && libc_S_ISTYPE(stat.st_mode, libc::S_IFREG);
@@ -105,7 +111,7 @@ fn bool native_is_file(String path)
fn bool native_is_dir(String path)
{
$if env::DARWIN || env::LINUX:
$if env::DARWIN || env::LINUX || env::BSD_FAMILY:
Stat stat;
return @ok(native_stat(&stat, path)) && libc_S_ISTYPE(stat.st_mode, libc::S_IFDIR);
$else

View File

@@ -3,7 +3,6 @@
// a copy of which can be found in the LICENSE_STDLIB file.
module libc;
// Constants need to be per os/arch
const int EXIT_FAILURE = 1;
const int EXIT_SUCCESS = 0;
@@ -203,7 +202,7 @@ macro CFile stdin() => __stdin;
macro CFile stdout() => __stdout;
macro CFile stderr() => __stderr;
module libc @if(env::DARWIN);
module libc @if(env::DARWIN || env::BSD_FAMILY);
extern CFile __stdinp;
extern CFile __stdoutp;
extern CFile __stderrp;
@@ -219,7 +218,7 @@ macro CFile stdin() => __acrt_iob_func(STDIN_FD);
macro CFile stdout() => __acrt_iob_func(STDOUT_FD);
macro CFile stderr() => __acrt_iob_func(STDERR_FD);
module libc @if(env::LIBC && !env::WIN32 && !env::LINUX && !env::DARWIN);
module libc @if(env::LIBC && !env::WIN32 && !env::LINUX && !env::DARWIN && !env::BSD_FAMILY);
macro CFile stdin() { return (CFile*)(uptr)STDIN_FD; }
macro CFile stdout() { return (CFile*)(uptr)STDOUT_FD; }
macro CFile stderr() { return (CFile*)(uptr)STDERR_FD; }

View File

@@ -0,0 +1,62 @@
module libc @if(env::FREEBSD);
// Checked for x86_64, this is notoriously incorrect when comparing with Rust code etc
def Blksize_t = $typefrom(env::X86_64 ? long.typeid : CInt.typeid);
def Nlink_t = $typefrom(env::X86_64 ? ulong.typeid : CUInt.typeid);
def Blkcnt_t = long;
def Ino_t = ulong;
def Dev_t = ulong;
def Mode_t = uint;
def Ino64_t = ulong;
def Blkcnt64_t = long;
struct Stat @if(env::X86_64)
{
Dev_t st_dev;
Ino_t st_ino;
Nlink_t st_nlink;
Mode_t st_mode;
Uid_t st_uid;
Gid_t st_gid;
CInt __pad0;
Dev_t st_rdev;
Off_t st_size;
Blksize_t st_blksize;
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;
long[3] __unused;
}
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();

View File

@@ -7,15 +7,22 @@ distinct DIRPtr = void*;
struct Posix_dirent
{
Ino_t d_fileno;
Off_t d_off;
Off_t d_off @if(!env::NETBSD);
ushort d_reclen;
ushort d_namelen @if(env::DARWIN);
ushort d_namelen @if(env::DARWIN || env::NETBSD);
char d_type;
char d_namelen @if(env::FREEBSD || env::OPENBSD);
uint d_pad0 @if(env::FREEBSD);
char d_namelen @if(env::OPENBSD);
char[4] d_pad0 @if(env::OPENBSD);
char d_pad0 @if(env::FREEBSD);
ushort d_namelen @if(env::FREEBSD);
ushort d_pad1 @if(env::FREEBSD);
char[255+1] name @if(env::FREEBSD || env::OPENBSD);
char[511+1] name @if(env::NETBSD);
char[1024] name @if(env::DARWIN);
char[*] name @if(!env::DARWIN);
char[*] name @if(!env::DARWIN && !env::BSD_FAMILY);
}
extern fn int rmdir(ZString);
@@ -41,4 +48,3 @@ const DT_WHT = 14;
const USE_DARWIN_INODE64 = env::DARWIN && env::X86_64;
extern fn Posix_dirent* readdir(DIRPtr) @extern("readdir$INODE64") @if(USE_DARWIN_INODE64);

View File

@@ -0,0 +1,22 @@
fn int main()
{
String msg = "Hello, C3 World!\n";
$$syscall(4, 1, (uptr)msg.ptr, msg.len); // __NR_write, STDOUT
return 0;
}
fn void _start() @export("_start")
{
int ret = main();
$$syscall(1, ret); // __NR_exit
}
module std::core::builtin;
def PanicFn = fn void(String message, String file, String function, uint line);
PanicFn panic = &default_panic;
fn void default_panic(String message, String file, String function, uint line)
{
}

View File

@@ -0,0 +1,79 @@
{
// Language version of C3.
"langrev": "1",
// Warnings used for all targets.
"warnings": [ "no-unused" ],
// Directories where C3 library files may be found.
"dependency-search-paths": [ ],
// Libraries to use for all targets.
"dependencies": [ ],
// Authors, optionally with email.
"authors": [ "John Doe <john.doe@example.com>" ],
// Version using semantic versioning.
"version": "0.1.0",
// Sources compiled for all targets.
"sources": [ "./**" ],
// C sources if the project also compiles C sources
// relative to the project file.
// "c-sources": [ "csource/**" ],
// Output location, relative to project file.
"output": ".",
// Architecture and OS target.
// You can use 'c3c --list-targets' to list all valid targets.
"target": "freebsd-x64",
// Targets.
"targets": {
"hello_world": {
"type": "executable",
"debug-info": "none",
"link-libc": false,
"opt": "O0",
"safe": false,
"linker": "builtin",
"use-stdlib": false,
},
},
// Global settings.
// C compiler if the project also compiles C sources
// defaults to 'cc'.
"cc": "cc",
// CPU name, used for optimizations in the LLVM backend.
"cpu": "generic",
// Debug information, may be "none", "full" and "line-tables".
"debug-info": "full",
// FP math behaviour: "strict", "relaxed", "fast".
"fp-math": "strict",
// Link libc other default libraries.
"link-libc": true,
// Memory environment: "normal", "small", "tiny", "none".
"memory-env": "normal",
// Optimization: "O0", "O1", "O2", "O3", "O4", "O5", "Os", "Oz".
"opt": "O0",
// Code optimization level: "none", "less", "more", "max".
"optlevel": "none",
// Code size optimization: "none", "small", "tiny".
"optsize": "none",
// Relocation model: "none", "pic", "PIC", "pie", "PIE".
"reloc": "none",
// Trap on signed and unsigned integer wrapping for testing.
"trap-on-wrap": false,
// Turn safety (contracts, runtime bounds checking, null pointer checks etc).
"safe": true,
// Compile all modules together, enables more inlining.
"single-module": true,
// Use / don't use soft float, value is otherwise target default.
"soft-float": false,
// Strip unused code and globals from the output.
"strip-unused": true,
// The size of the symtab, which limits the amount
// of symbols that can be used. Should usually not be changed.
"symtab": 1048576,
// Select linker.
"linker": "cc",
// Include the standard library.
"use-stdlib": true,
// Set general level of x64 cpu: "baseline", "ssse3", "sse4", "avx1", "avx2-v1", "avx2-v2", "avx512", "native".
"x86cpu": "native",
// Set max type of vector use: "none", "mmx", "sse", "avx", "avx512", "native".
"x86vec": "sse",
}

View File

@@ -34,7 +34,7 @@ fn void testStruct()
foo = { 11, 12 };
// Named arguments
foo = createFoo(.b = 13, .a = 14);
foo = createFoo(a: 14, b: 13);
printf("Foo a:%d b:%d\n", foo.a, foo.b);
Bar bar = bitcast(foo, Bar);

View File

@@ -4,9 +4,11 @@ struct Overalign
double[<33>] x;
}
def Olist = List(<Overalign>);
fn void main()
{
List(<Overalign>) l;
Olist l;
Overalign y;
for (int i = 0; i < 1000; i++)
{

View File

@@ -402,7 +402,11 @@ static void linker_setup_linux(const char ***args_ref, Linker linker_type)
static void linker_setup_freebsd(const char ***args_ref, Linker linker_type)
{
if (linker_type == LINKER_CC) return;
if (linker_type == LINKER_CC) {
linking_add_link(&compiler.linking, "m");
linking_add_link(&compiler.linking, "pthread");
return;
}
if (is_no_pie(compiler.platform.reloc_model)) add_plain_arg("-no-pie");
if (is_pie(compiler.platform.reloc_model)) add_plain_arg("-pie");
if (compiler.platform.arch == ARCH_TYPE_X86_64) add_plain_arg("--eh-frame-hdr");

View File

@@ -8,7 +8,7 @@ int cpus(void)
GetSystemInfo(&sysinfo);
return sysinfo.dwNumberOfProcessors;
}
#elif __APPLE__ || defined(__linux__)
#elif __APPLE__ || defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
#include <unistd.h>
int cpus(void)
{
@@ -20,4 +20,4 @@ int cpus(void)
REMINDER("Implement processor count for OS");
return 1;
}
#endif
#endif