initial support for haiku past stage0

This commit is contained in:
Al Hoang 2020-12-25 07:48:04 -06:00 committed by Andrew Kelley
parent 297eabd4ac
commit 025635c3f8
13 changed files with 1527 additions and 14 deletions

View File

@ -3,6 +3,32 @@
// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
// The MIT license requires this copyright notice to be included in all copies
// and substantial portions of the software.
//
const std = @import("../std.zig");
const builtin = std.builtin;
usingnamespace std.c;
extern "c" fn _errnop() *c_int;
pub const _errno = _errnop;
// not supported in haiku
pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;
pub const dl_iterate_phdr_callback = fn (info: *dl_phdr_info, size: usize, data: ?*c_void) callconv(.C) c_int;
//pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
//
pub const sem_t = extern struct {
_magic: u32,
_kern: extern struct {
_count: u32,
_flags: u32,
},
_padding: u32,
};
pub const pthread_mutex_t = extern struct {
flags: u32 = 0,
lock: i32 = 0,
@ -10,6 +36,7 @@ pub const pthread_mutex_t = extern struct {
owner: i32 = -1,
owner_count: i32 = 0,
};
pub const pthread_cond_t = extern struct {
flags: u32 = 0,
unused: i32 = -42,

View File

@ -1125,12 +1125,15 @@ pub const DebugInfo = struct {
}
pub fn getModuleForAddress(self: *DebugInfo, address: usize) !*ModuleDebugInfo {
if (comptime std.Target.current.isDarwin())
return self.lookupModuleDyld(address)
else if (builtin.os.tag == .windows)
return self.lookupModuleWin32(address)
else
if (comptime std.Target.current.isDarwin()) {
return self.lookupModuleDyld(address);
} else if (builtin.os.tag == .windows) {
return self.lookupModuleWin32(address);
} else if (builtin.os.tag == .haiku) {
return self.lookupModuleHaiku(address);
} else {
return self.lookupModuleDl(address);
}
}
fn lookupModuleDyld(self: *DebugInfo, address: usize) !*ModuleDebugInfo {
@ -1336,6 +1339,18 @@ pub const DebugInfo = struct {
return obj_di;
}
fn lookupModuleHaiku(self: *DebugInfo, address: usize) !*ModuleDebugInfo {
// TODO: implement me
var di = ModuleDebugInfo{
.base_address = undefined,
.dwarf = undefined,
.mapped_memory = undefined,
};
return &di;
}
};
const SymbolInfo = struct {
@ -1702,6 +1717,17 @@ pub const ModuleDebugInfo = switch (builtin.os.tag) {
unreachable;
}
},
.haiku => struct {
// Haiku should implement dl_iterat_phdr (https://dev.haiku-os.org/ticket/15743)
base_address: usize,
dwarf: DW.DwarfInfo,
mapped_memory: []const u8,
pub fn getSymbolAtAddress(self: *@This(), address: usize) !SymbolInfo {
// TODO: implement me
return SymbolInfo{};
}
},
else => DW.DwarfInfo,
};
@ -1720,7 +1746,7 @@ fn getDebugInfoAllocator() *mem.Allocator {
pub const have_segfault_handling_support = switch (builtin.os.tag) {
.linux, .netbsd => true,
.windows => true,
.freebsd, .openbsd => @hasDecl(os, "ucontext_t"),
.freebsd, .openbsd, .haiku => @hasDecl(os, "ucontext_t"),
else => false,
};
pub const enable_segfault_handler: bool = if (@hasDecl(root, "enable_segfault_handler"))

View File

@ -39,7 +39,7 @@ pub const Watch = @import("fs/watch.zig").Watch;
/// fit into a UTF-8 encoded array of this length.
/// The byte count includes room for a null sentinel byte.
pub const MAX_PATH_BYTES = switch (builtin.os.tag) {
.linux, .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd => os.PATH_MAX,
.linux, .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, .haiku => os.PATH_MAX,
// Each UTF-16LE character may be expanded to 3 UTF-8 bytes.
// If it would require 4 UTF-8 bytes, then there would be a surrogate
// pair in the UTF-16LE, and we (over)account 3 bytes for it that way.
@ -302,7 +302,7 @@ pub const Dir = struct {
const IteratorError = error{AccessDenied} || os.UnexpectedError;
pub const Iterator = switch (builtin.os.tag) {
.macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd => struct {
.macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, .haiku => struct {
dir: Dir,
seek: i64,
buf: [8192]u8, // TODO align(@alignOf(os.dirent)),
@ -319,6 +319,7 @@ pub const Dir = struct {
switch (builtin.os.tag) {
.macos, .ios => return self.nextDarwin(),
.freebsd, .netbsd, .dragonfly, .openbsd => return self.nextBsd(),
.haiku => return self.nextHaiku(),
else => @compileError("unimplemented"),
}
}
@ -426,6 +427,16 @@ pub const Dir = struct {
};
}
}
fn nextHaiku(self: *Self) !?Entry {
//const name = @ptrCast([*]u8, "placeholder-please-implement-me");
//const name = "placeholder-please-implement-me";
return Entry{
.name = base64_alphabet,
.kind = Entry.Kind.File,
};
}
},
.linux => struct {
dir: Dir,
@ -621,7 +632,7 @@ pub const Dir = struct {
pub fn iterate(self: Dir) Iterator {
switch (builtin.os.tag) {
.macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd => return Iterator{
.macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, .haiku => return Iterator{
.dir = self,
.seek = 0,
.index = 0,
@ -2339,7 +2350,7 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
// TODO could this slice from 0 to out_len instead?
return mem.spanZ(std.meta.assumeSentinel(out_buffer.ptr, 0));
},
.openbsd => {
.openbsd, .haiku => {
// OpenBSD doesn't support getting the path of a running process, so try to guess it
if (os.argv.len == 0)
return error.FileNotFound;

View File

@ -56,6 +56,13 @@ pub fn getAppDataDir(allocator: *mem.Allocator, appname: []const u8) GetAppDataD
};
return fs.path.join(allocator, &[_][]const u8{ home_dir, ".local", "share", appname });
},
.haiku => {
const home_dir = os.getenv("HOME") orelse {
// TODO look in /etc/passwd
return error.AppDataDirUnavailable;
};
return fs.path.join(allocator, &[_][]const u8{ home_dir, "config", "settings", appname });
},
else => @compileError("Unsupported OS"),
}
}

View File

@ -32,6 +32,7 @@ const MAX_PATH_BYTES = std.fs.MAX_PATH_BYTES;
pub const darwin = @import("os/darwin.zig");
pub const dragonfly = @import("os/dragonfly.zig");
pub const freebsd = @import("os/freebsd.zig");
pub const haiku = @import("os/haiku.zig");
pub const netbsd = @import("os/netbsd.zig");
pub const openbsd = @import("os/openbsd.zig");
pub const linux = @import("os/linux.zig");
@ -66,6 +67,7 @@ else if (builtin.link_libc)
else switch (builtin.os.tag) {
.macos, .ios, .watchos, .tvos => darwin,
.freebsd => freebsd,
.haiku => haiku,
.linux => linux,
.netbsd => netbsd,
.openbsd => openbsd,
@ -932,7 +934,7 @@ pub fn pwrite(fd: fd_t, bytes: []const u8, offset: u64) PWriteError!usize {
/// If `iov.len` is larger than will fit in a `u31`, a partial write will occur.
pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) PWriteError!usize {
const have_pwrite_but_not_pwritev = switch (std.Target.current.os.tag) {
.windows, .macos, .ios, .watchos, .tvos => true,
.windows, .macos, .ios, .watchos, .tvos, .haiku => true,
else => false,
};
@ -3889,6 +3891,21 @@ pub fn pipe2(flags: u32) PipeError![2]fd_t {
}
}
}
if (comptime std.Target.current.isHaiku()) {
var fds: [2]fd_t = try pipe();
if (flags == 0) return fds;
errdefer {
close(fds[0]);
close(fds[1]);
}
for (fds) |fd| switch (errno(system.fcntl(fd, F_SETFL, flags))) {
0 => {},
EINVAL => unreachable, // Invalid flags
EBADF => unreachable, // Always a race condition
else => |err| return unexpectedErrno(err),
};
return fds;
}
const new_flags = flags & ~@as(u32, O_CLOEXEC);
// Set every other flag affecting the file status using F_SETFL.

View File

@ -15,6 +15,7 @@ pub usingnamespace switch (std.Target.current.os.tag) {
.macos, .ios, .tvos, .watchos => @import("bits/darwin.zig"),
.dragonfly => @import("bits/dragonfly.zig"),
.freebsd => @import("bits/freebsd.zig"),
.haiku => @import("bits/haiku.zig"),
.linux => @import("bits/linux.zig"),
.netbsd => @import("bits/netbsd.zig"),
.openbsd => @import("bits/openbsd.zig"),

1394
lib/std/os/bits/haiku.zig Normal file

File diff suppressed because it is too large Load Diff

8
lib/std/os/haiku.zig Normal file
View File

@ -0,0 +1,8 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2015-2020 Zig Contributors
// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
// The MIT license requires this copyright notice to be included in all copies
// and substantial portions of the software.
const std = @import("../std.zig");
pub usingnamespace std.c;
pub usingnamespace @import("bits.zig");

View File

@ -609,7 +609,7 @@ pub const UserInfo = struct {
/// POSIX function which gets a uid from username.
pub fn getUserInfo(name: []const u8) !UserInfo {
return switch (builtin.os.tag) {
.linux, .macos, .watchos, .tvos, .ios, .freebsd, .netbsd, .openbsd => posixGetUserInfo(name),
.linux, .macos, .watchos, .tvos, .ios, .freebsd, .netbsd, .openbsd, .haiku => posixGetUserInfo(name),
else => @compileError("Unsupported OS"),
};
}
@ -777,6 +777,19 @@ pub fn getSelfExeSharedLibPaths(allocator: *Allocator) error{OutOfMemory}![][:0]
}
return paths.toOwnedSlice();
},
// Haiku should implement dl_iterat_phdr (https://dev.haiku-os.org/ticket/15743)
.haiku => {
var paths = List.init(allocator);
errdefer {
const slice = paths.toOwnedSlice();
for (slice) |item| {
allocator.free(item);
}
allocator.free(slice);
}
//TODO: fill out placeholder
return paths.toOwnedSlice();
},
else => @compileError("getSelfExeSharedLibPaths unimplemented for this target"),
}
}

View File

@ -1339,6 +1339,10 @@ pub const Target = struct {
return self.os.tag.isDarwin();
}
pub fn isHaiku(self: Target) bool {
return self.os.tag == .haiku;
}
pub fn isGnuLibC_os_tag_abi(os_tag: Os.Tag, abi: Abi) bool {
return os_tag == .linux and abi.isGnu();
}

View File

@ -61,7 +61,7 @@ typedef SSIZE_T ssize_t;
#endif
#if defined(ZIG_OS_LINUX) || defined(ZIG_OS_FREEBSD) || defined(ZIG_OS_NETBSD) || defined(ZIG_OS_DRAGONFLY) || defined(ZIG_OS_OPENBSD)
#if defined(ZIG_OS_LINUX) || defined(ZIG_OS_FREEBSD) || defined(ZIG_OS_NETBSD) || defined(ZIG_OS_DRAGONFLY) || defined(ZIG_OS_OPENBSD) || defined(ZIG_OS_HAIKU)
#include <link.h>
#endif

View File

@ -31,6 +31,8 @@
#define ZIG_OS_DRAGONFLY
#elif defined(__OpenBSD__)
#define ZIG_OS_OPENBSD
#elif defined(__HAIKU__)
#define ZIG_OS_HAIKU
#else
#define ZIG_OS_UNKNOWN
#endif

View File

@ -379,6 +379,9 @@ Error target_parse_os(Os *out_os, const char *os_ptr, size_t os_len) {
#elif defined(ZIG_OS_OPENBSD)
*out_os = OsOpenBSD;
return ErrorNone;
#elif defined(ZIG_OS_HAIKU)
*out_os = OsHaiku;
return ErrorNone;
#else
zig_panic("stage1 is unable to detect native target for this OS");
#endif
@ -645,6 +648,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
case OsDragonFly:
case OsOpenBSD:
case OsWASI:
case OsHaiku:
case OsEmscripten:
switch (id) {
case CIntTypeShort:
@ -703,7 +707,6 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
case OsKFreeBSD:
case OsLv2:
case OsSolaris:
case OsHaiku:
case OsMinix:
case OsRTEMS:
case OsNaCl: