Merge branch 'semarie-openbsd-minimal'

master
Andrew Kelley 2020-10-17 17:53:47 -07:00
commit 71ac5b1515
22 changed files with 1181 additions and 41 deletions

View File

@ -249,7 +249,7 @@ pub extern "c" fn aligned_alloc(alignment: usize, size: usize) ?*c_void;
pub extern "c" fn malloc(usize) ?*c_void; pub extern "c" fn malloc(usize) ?*c_void;
pub usingnamespace switch (builtin.os.tag) { pub usingnamespace switch (builtin.os.tag) {
.linux, .freebsd, .kfreebsd, .netbsd, .openbsd => struct { .linux, .freebsd, .kfreebsd, .netbsd => struct {
pub extern "c" fn malloc_usable_size(?*const c_void) usize; pub extern "c" fn malloc_usable_size(?*const c_void) usize;
}, },
.macos, .ios, .watchos, .tvos => struct { .macos, .ios, .watchos, .tvos => struct {

View File

@ -3,9 +3,32 @@
// This file is part of [zig](https://ziglang.org/), which is MIT licensed. // 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 // The MIT license requires this copyright notice to be included in all copies
// and substantial portions of the software. // and substantial portions of the software.
const std = @import("../std.zig");
const builtin = std.builtin;
usingnamespace std.c;
extern "c" fn __errno() *c_int;
pub const _errno = __errno;
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 extern "c" fn arc4random_buf(buf: [*]u8, len: usize) void;
pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;
pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
pub const pthread_mutex_t = extern struct { pub const pthread_mutex_t = extern struct {
inner: ?*c_void = null, inner: ?*c_void = null,
}; };
pub const pthread_cond_t = extern struct { pub const pthread_cond_t = extern struct {
inner: ?*c_void = null, inner: ?*c_void = null,
}; };
pub const pthread_spinlock_t = extern struct {
inner: ?*c_void = null,
};
pub const pthread_attr_t = extern struct {
inner: ?*c_void = null,
};

View File

@ -654,6 +654,7 @@ pub fn openSelfDebugInfo(allocator: *mem.Allocator) anyerror!DebugInfo {
.freebsd, .freebsd,
.netbsd, .netbsd,
.dragonfly, .dragonfly,
.openbsd,
.macos, .macos,
.windows, .windows,
=> return DebugInfo.init(allocator), => return DebugInfo.init(allocator),
@ -1640,7 +1641,7 @@ pub const ModuleDebugInfo = switch (builtin.os.tag) {
}; };
} }
}, },
.linux, .netbsd, .freebsd, .dragonfly => struct { .linux, .netbsd, .freebsd, .dragonfly, .openbsd => struct {
base_address: usize, base_address: usize,
dwarf: DW.DwarfInfo, dwarf: DW.DwarfInfo,
mapped_memory: []const u8, mapped_memory: []const u8,

View File

@ -19,7 +19,7 @@ const max = std.math.max;
pub const DynLib = switch (builtin.os.tag) { pub const DynLib = switch (builtin.os.tag) {
.linux => if (builtin.link_libc) DlDynlib else ElfDynLib, .linux => if (builtin.link_libc) DlDynlib else ElfDynLib,
.windows => WindowsDynLib, .windows => WindowsDynLib,
.macos, .tvos, .watchos, .ios, .freebsd => DlDynlib, .macos, .tvos, .watchos, .ios, .freebsd, .openbsd => DlDynlib,
else => void, else => void,
}; };
@ -402,7 +402,7 @@ pub const DlDynlib = struct {
test "dynamic_library" { test "dynamic_library" {
const libname = switch (builtin.os.tag) { const libname = switch (builtin.os.tag) {
.linux, .freebsd => "invalid_so.so", .linux, .freebsd, .openbsd => "invalid_so.so",
.windows => "invalid_dll.dll", .windows => "invalid_dll.dll",
.macos, .tvos, .watchos, .ios => "invalid_dylib.dylib", .macos, .tvos, .watchos, .ios => "invalid_dylib.dylib",
else => return error.SkipZigTest, else => return error.SkipZigTest,

View File

@ -69,7 +69,7 @@ pub const Loop = struct {
}; };
pub const EventFd = switch (builtin.os.tag) { pub const EventFd = switch (builtin.os.tag) {
.macos, .freebsd, .netbsd, .dragonfly => KEventFd, .macos, .freebsd, .netbsd, .dragonfly, .openbsd => KEventFd,
.linux => struct { .linux => struct {
base: ResumeNode, base: ResumeNode,
epoll_op: u32, epoll_op: u32,
@ -88,7 +88,7 @@ pub const Loop = struct {
}; };
pub const Basic = switch (builtin.os.tag) { pub const Basic = switch (builtin.os.tag) {
.macos, .freebsd, .netbsd, .dragonfly => KEventBasic, .macos, .freebsd, .netbsd, .dragonfly, .openbsd => KEventBasic,
.linux => struct { .linux => struct {
base: ResumeNode, base: ResumeNode,
}, },
@ -266,7 +266,7 @@ pub const Loop = struct {
self.extra_threads[extra_thread_index] = try Thread.spawn(self, workerRun); self.extra_threads[extra_thread_index] = try Thread.spawn(self, workerRun);
} }
}, },
.macos, .freebsd, .netbsd, .dragonfly => { .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
self.os_data.kqfd = try os.kqueue(); self.os_data.kqfd = try os.kqueue();
errdefer os.close(self.os_data.kqfd); errdefer os.close(self.os_data.kqfd);
@ -391,7 +391,7 @@ pub const Loop = struct {
while (self.available_eventfd_resume_nodes.pop()) |node| os.close(node.data.eventfd); while (self.available_eventfd_resume_nodes.pop()) |node| os.close(node.data.eventfd);
os.close(self.os_data.epollfd); os.close(self.os_data.epollfd);
}, },
.macos, .freebsd, .netbsd, .dragonfly => { .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
os.close(self.os_data.kqfd); os.close(self.os_data.kqfd);
}, },
.windows => { .windows => {
@ -485,7 +485,7 @@ pub const Loop = struct {
.linux => { .linux => {
self.linuxWaitFd(fd, os.EPOLLET | os.EPOLLONESHOT | os.EPOLLIN); self.linuxWaitFd(fd, os.EPOLLET | os.EPOLLONESHOT | os.EPOLLIN);
}, },
.macos, .freebsd, .netbsd, .dragonfly => { .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_READ, os.EV_ONESHOT); self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_READ, os.EV_ONESHOT);
}, },
else => @compileError("Unsupported OS"), else => @compileError("Unsupported OS"),
@ -497,7 +497,7 @@ pub const Loop = struct {
.linux => { .linux => {
self.linuxWaitFd(fd, os.EPOLLET | os.EPOLLONESHOT | os.EPOLLOUT); self.linuxWaitFd(fd, os.EPOLLET | os.EPOLLONESHOT | os.EPOLLOUT);
}, },
.macos, .freebsd, .netbsd, .dragonfly => { .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_WRITE, os.EV_ONESHOT); self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_WRITE, os.EV_ONESHOT);
}, },
else => @compileError("Unsupported OS"), else => @compileError("Unsupported OS"),
@ -509,7 +509,7 @@ pub const Loop = struct {
.linux => { .linux => {
self.linuxWaitFd(fd, os.EPOLLET | os.EPOLLONESHOT | os.EPOLLOUT | os.EPOLLIN); self.linuxWaitFd(fd, os.EPOLLET | os.EPOLLONESHOT | os.EPOLLOUT | os.EPOLLIN);
}, },
.macos, .freebsd, .netbsd, .dragonfly => { .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_READ, os.EV_ONESHOT); self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_READ, os.EV_ONESHOT);
self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_WRITE, os.EV_ONESHOT); self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_WRITE, os.EV_ONESHOT);
}, },
@ -578,7 +578,7 @@ pub const Loop = struct {
const eventfd_node = &resume_stack_node.data; const eventfd_node = &resume_stack_node.data;
eventfd_node.base.handle = next_tick_node.data; eventfd_node.base.handle = next_tick_node.data;
switch (builtin.os.tag) { switch (builtin.os.tag) {
.macos, .freebsd, .netbsd, .dragonfly => { .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
const kevent_array = @as(*const [1]os.Kevent, &eventfd_node.kevent); const kevent_array = @as(*const [1]os.Kevent, &eventfd_node.kevent);
const empty_kevs = &[0]os.Kevent{}; const empty_kevs = &[0]os.Kevent{};
_ = os.kevent(self.os_data.kqfd, kevent_array, empty_kevs, null) catch { _ = os.kevent(self.os_data.kqfd, kevent_array, empty_kevs, null) catch {
@ -644,6 +644,7 @@ pub const Loop = struct {
.freebsd, .freebsd,
.netbsd, .netbsd,
.dragonfly, .dragonfly,
.openbsd,
=> self.fs_thread.wait(), => self.fs_thread.wait(),
else => {}, else => {},
} }
@ -736,7 +737,7 @@ pub const Loop = struct {
} }
return; return;
}, },
.macos, .freebsd, .netbsd, .dragonfly => { .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
const final_kevent = @as(*const [1]os.Kevent, &self.os_data.final_kevent); const final_kevent = @as(*const [1]os.Kevent, &self.os_data.final_kevent);
const empty_kevs = &[0]os.Kevent{}; const empty_kevs = &[0]os.Kevent{};
// cannot fail because we already added it and this just enables it // cannot fail because we already added it and this just enables it
@ -1351,7 +1352,7 @@ pub const Loop = struct {
} }
} }
}, },
.macos, .freebsd, .netbsd, .dragonfly => { .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
var eventlist: [1]os.Kevent = undefined; var eventlist: [1]os.Kevent = undefined;
const empty_kevs = &[0]os.Kevent{}; const empty_kevs = &[0]os.Kevent{};
const count = os.kevent(self.os_data.kqfd, empty_kevs, eventlist[0..], null) catch unreachable; const count = os.kevent(self.os_data.kqfd, empty_kevs, eventlist[0..], null) catch unreachable;
@ -1477,7 +1478,7 @@ pub const Loop = struct {
const OsData = switch (builtin.os.tag) { const OsData = switch (builtin.os.tag) {
.linux => LinuxOsData, .linux => LinuxOsData,
.macos, .freebsd, .netbsd, .dragonfly => KEventData, .macos, .freebsd, .netbsd, .dragonfly, .openbsd => KEventData,
.windows => struct { .windows => struct {
io_port: windows.HANDLE, io_port: windows.HANDLE,
extra_thread_count: usize, extra_thread_count: usize,

View File

@ -39,7 +39,7 @@ pub const Watch = @import("fs/watch.zig").Watch;
/// fit into a UTF-8 encoded array of this length. /// fit into a UTF-8 encoded array of this length.
/// The byte count includes room for a null sentinel byte. /// The byte count includes room for a null sentinel byte.
pub const MAX_PATH_BYTES = switch (builtin.os.tag) { pub const MAX_PATH_BYTES = switch (builtin.os.tag) {
.linux, .macos, .ios, .freebsd, .netbsd, .dragonfly => os.PATH_MAX, .linux, .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd => os.PATH_MAX,
// Each UTF-16LE character may be expanded to 3 UTF-8 bytes. // 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 // 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. // pair in the UTF-16LE, and we (over)account 3 bytes for it that way.
@ -303,7 +303,7 @@ pub const Dir = struct {
const IteratorError = error{AccessDenied} || os.UnexpectedError; const IteratorError = error{AccessDenied} || os.UnexpectedError;
pub const Iterator = switch (builtin.os.tag) { pub const Iterator = switch (builtin.os.tag) {
.macos, .ios, .freebsd, .netbsd, .dragonfly => struct { .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd => struct {
dir: Dir, dir: Dir,
seek: i64, seek: i64,
buf: [8192]u8, // TODO align(@alignOf(os.dirent)), buf: [8192]u8, // TODO align(@alignOf(os.dirent)),
@ -319,7 +319,7 @@ pub const Dir = struct {
pub fn next(self: *Self) Error!?Entry { pub fn next(self: *Self) Error!?Entry {
switch (builtin.os.tag) { switch (builtin.os.tag) {
.macos, .ios => return self.nextDarwin(), .macos, .ios => return self.nextDarwin(),
.freebsd, .netbsd, .dragonfly => return self.nextBsd(), .freebsd, .netbsd, .dragonfly, .openbsd => return self.nextBsd(),
else => @compileError("unimplemented"), else => @compileError("unimplemented"),
} }
} }
@ -615,7 +615,7 @@ pub const Dir = struct {
pub fn iterate(self: Dir) Iterator { pub fn iterate(self: Dir) Iterator {
switch (builtin.os.tag) { switch (builtin.os.tag) {
.macos, .ios, .freebsd, .netbsd, .dragonfly => return Iterator{ .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd => return Iterator{
.dir = self, .dir = self,
.seek = 0, .seek = 0,
.index = 0, .index = 0,
@ -1302,7 +1302,7 @@ pub const Dir = struct {
error.AccessDenied => |e| switch (builtin.os.tag) { error.AccessDenied => |e| switch (builtin.os.tag) {
// non-Linux POSIX systems return EPERM when trying to delete a directory, so // non-Linux POSIX systems return EPERM when trying to delete a directory, so
// we need to handle that case specifically and translate the error // we need to handle that case specifically and translate the error
.macos, .ios, .freebsd, .netbsd, .dragonfly => { .macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd => {
// Don't follow symlinks to match unlinkat (which acts on symlinks rather than follows them) // Don't follow symlinks to match unlinkat (which acts on symlinks rather than follows them)
const fstat = os.fstatatZ(self.fd, sub_path_c, os.AT_SYMLINK_NOFOLLOW) catch return e; const fstat = os.fstatatZ(self.fd, sub_path_c, os.AT_SYMLINK_NOFOLLOW) catch return e;
const is_dir = fstat.mode & os.S_IFMT == os.S_IFDIR; const is_dir = fstat.mode & os.S_IFMT == os.S_IFDIR;
@ -2232,6 +2232,43 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 {
// TODO could this slice from 0 to out_len instead? // TODO could this slice from 0 to out_len instead?
return mem.spanZ(@ptrCast([*:0]u8, out_buffer)); return mem.spanZ(@ptrCast([*:0]u8, out_buffer));
}, },
.openbsd => {
// OpenBSD doesn't support getting the path of a running process, so try to guess it
if (os.argv.len == 0)
return error.FileNotFound;
const argv0 = mem.span(os.argv[0]);
if (mem.indexOf(u8, argv0, "/") != null) {
// argv[0] is a path (relative or absolute): use realpath(3) directly
var real_path_buf: [MAX_PATH_BYTES]u8 = undefined;
const real_path = try os.realpathZ(os.argv[0], &real_path_buf);
if (real_path.len > out_buffer.len)
return error.NameTooLong;
mem.copy(u8, out_buffer, real_path);
return out_buffer[0..real_path.len];
} else if (argv0.len != 0) {
// argv[0] is not empty (and not a path): search it inside PATH
const PATH = std.os.getenvZ("PATH") orelse return error.FileNotFound;
var path_it = mem.tokenize(PATH, &[_]u8{path.delimiter});
while (path_it.next()) |a_path| {
var resolved_path_buf: [MAX_PATH_BYTES]u8 = undefined;
const resolved_path = std.fmt.bufPrintZ(&resolved_path_buf, "{s}/{s}", .{
a_path,
os.argv[0],
}) catch continue;
var real_path_buf: [MAX_PATH_BYTES]u8 = undefined;
if (os.realpathZ(&resolved_path_buf, &real_path_buf)) |real_path| {
// found a file, and hope it is the right file
if (real_path.len > out_buffer.len)
return error.NameTooLong;
mem.copy(u8, out_buffer, real_path);
return out_buffer[0..real_path.len];
} else |_| continue;
}
}
return error.FileNotFound;
},
.windows => { .windows => {
const utf16le_slice = selfExePathW(); const utf16le_slice = selfExePathW();
// Trust that Windows gives us valid UTF-16LE. // Trust that Windows gives us valid UTF-16LE.

View File

@ -49,7 +49,7 @@ pub fn getAppDataDir(allocator: *mem.Allocator, appname: []const u8) GetAppDataD
}; };
return fs.path.join(allocator, &[_][]const u8{ home_dir, "Library", "Application Support", appname }); return fs.path.join(allocator, &[_][]const u8{ home_dir, "Library", "Application Support", appname });
}, },
.linux, .freebsd, .netbsd, .dragonfly => { .linux, .freebsd, .netbsd, .dragonfly, .openbsd => {
const home_dir = os.getenv("HOME") orelse { const home_dir = os.getenv("HOME") orelse {
// TODO look in /etc/passwd // TODO look in /etc/passwd
return error.AppDataDirUnavailable; return error.AppDataDirUnavailable;

View File

@ -49,7 +49,7 @@ pub fn Watch(comptime V: type) type {
const OsData = switch (builtin.os.tag) { const OsData = switch (builtin.os.tag) {
// TODO https://github.com/ziglang/zig/issues/3778 // TODO https://github.com/ziglang/zig/issues/3778
.macos, .freebsd, .netbsd, .dragonfly => KqOsData, .macos, .freebsd, .netbsd, .dragonfly, .openbsd => KqOsData,
.linux => LinuxOsData, .linux => LinuxOsData,
.windows => WindowsOsData, .windows => WindowsOsData,
@ -160,7 +160,7 @@ pub fn Watch(comptime V: type) type {
return self; return self;
}, },
.macos, .freebsd, .netbsd, .dragonfly => { .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
self.* = Self{ self.* = Self{
.allocator = allocator, .allocator = allocator,
.channel = channel, .channel = channel,
@ -178,7 +178,7 @@ pub fn Watch(comptime V: type) type {
/// All addFile calls and removeFile calls must have completed. /// All addFile calls and removeFile calls must have completed.
pub fn deinit(self: *Self) void { pub fn deinit(self: *Self) void {
switch (builtin.os.tag) { switch (builtin.os.tag) {
.macos, .freebsd, .netbsd, .dragonfly => { .macos, .freebsd, .netbsd, .dragonfly, .openbsd => {
// TODO we need to cancel the frames before destroying the lock // TODO we need to cancel the frames before destroying the lock
self.os_data.table_lock.deinit(); self.os_data.table_lock.deinit();
var it = self.os_data.file_table.iterator(); var it = self.os_data.file_table.iterator();
@ -229,7 +229,7 @@ pub fn Watch(comptime V: type) type {
pub fn addFile(self: *Self, file_path: []const u8, value: V) !?V { pub fn addFile(self: *Self, file_path: []const u8, value: V) !?V {
switch (builtin.os.tag) { switch (builtin.os.tag) {
.macos, .freebsd, .netbsd, .dragonfly => return addFileKEvent(self, file_path, value), .macos, .freebsd, .netbsd, .dragonfly, .openbsd => return addFileKEvent(self, file_path, value),
.linux => return addFileLinux(self, file_path, value), .linux => return addFileLinux(self, file_path, value),
.windows => return addFileWindows(self, file_path, value), .windows => return addFileWindows(self, file_path, value),
else => @compileError("Unsupported OS"), else => @compileError("Unsupported OS"),

View File

@ -33,6 +33,7 @@ pub const darwin = @import("os/darwin.zig");
pub const dragonfly = @import("os/dragonfly.zig"); pub const dragonfly = @import("os/dragonfly.zig");
pub const freebsd = @import("os/freebsd.zig"); pub const freebsd = @import("os/freebsd.zig");
pub const netbsd = @import("os/netbsd.zig"); pub const netbsd = @import("os/netbsd.zig");
pub const openbsd = @import("os/openbsd.zig");
pub const linux = @import("os/linux.zig"); pub const linux = @import("os/linux.zig");
pub const uefi = @import("os/uefi.zig"); pub const uefi = @import("os/uefi.zig");
pub const wasi = @import("os/wasi.zig"); pub const wasi = @import("os/wasi.zig");
@ -47,6 +48,7 @@ test "" {
_ = freebsd; _ = freebsd;
_ = linux; _ = linux;
_ = netbsd; _ = netbsd;
_ = openbsd;
_ = uefi; _ = uefi;
_ = wasi; _ = wasi;
_ = windows; _ = windows;
@ -66,6 +68,7 @@ else switch (builtin.os.tag) {
.freebsd => freebsd, .freebsd => freebsd,
.linux => linux, .linux => linux,
.netbsd => netbsd, .netbsd => netbsd,
.openbsd => openbsd,
.dragonfly => dragonfly, .dragonfly => dragonfly,
.wasi => wasi, .wasi => wasi,
.windows => windows, .windows => windows,
@ -161,8 +164,8 @@ pub fn getrandom(buffer: []u8) GetRandomError!void {
} }
return; return;
} }
if (builtin.os.tag == .netbsd) { if (builtin.os.tag == .netbsd or builtin.os.tag == .openbsd) {
netbsd.arc4random_buf(buffer.ptr, buffer.len); system.arc4random_buf(buffer.ptr, buffer.len);
return; return;
} }
if (builtin.os.tag == .wasi) { if (builtin.os.tag == .wasi) {

View File

@ -17,6 +17,7 @@ pub usingnamespace switch (std.Target.current.os.tag) {
.freebsd => @import("bits/freebsd.zig"), .freebsd => @import("bits/freebsd.zig"),
.linux => @import("bits/linux.zig"), .linux => @import("bits/linux.zig"),
.netbsd => @import("bits/netbsd.zig"), .netbsd => @import("bits/netbsd.zig"),
.openbsd => @import("bits/openbsd.zig"),
.wasi => @import("bits/wasi.zig"), .wasi => @import("bits/wasi.zig"),
.windows => @import("bits/windows.zig"), .windows => @import("bits/windows.zig"),
else => struct {}, else => struct {},

1052
lib/std/os/bits/openbsd.zig Normal file

File diff suppressed because it is too large Load Diff

8
lib/std/os/openbsd.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

@ -618,7 +618,7 @@ test "PackedIntArray at end of available memory" {
if (we_are_testing_this_with_stage1_which_leaks_comptime_memory) return error.SkipZigTest; if (we_are_testing_this_with_stage1_which_leaks_comptime_memory) return error.SkipZigTest;
switch (builtin.os.tag) { switch (builtin.os.tag) {
.linux, .macos, .ios, .freebsd, .netbsd, .windows => {}, .linux, .macos, .ios, .freebsd, .netbsd, .openbsd, .windows => {},
else => return, else => return,
} }
const PackedArray = PackedIntArray(u3, 8); const PackedArray = PackedIntArray(u3, 8);
@ -639,7 +639,7 @@ test "PackedIntSlice at end of available memory" {
if (we_are_testing_this_with_stage1_which_leaks_comptime_memory) return error.SkipZigTest; if (we_are_testing_this_with_stage1_which_leaks_comptime_memory) return error.SkipZigTest;
switch (builtin.os.tag) { switch (builtin.os.tag) {
.linux, .macos, .ios, .freebsd, .netbsd, .windows => {}, .linux, .macos, .ios, .freebsd, .netbsd, .openbsd, .windows => {},
else => return, else => return,
} }
const PackedSlice = PackedIntSlice(u11); const PackedSlice = PackedIntSlice(u11);

View File

@ -585,7 +585,7 @@ pub const UserInfo = struct {
/// POSIX function which gets a uid from username. /// POSIX function which gets a uid from username.
pub fn getUserInfo(name: []const u8) !UserInfo { pub fn getUserInfo(name: []const u8) !UserInfo {
return switch (builtin.os.tag) { return switch (builtin.os.tag) {
.linux, .macos, .watchos, .tvos, .ios, .freebsd, .netbsd => posixGetUserInfo(name), .linux, .macos, .watchos, .tvos, .ios, .freebsd, .netbsd, .openbsd => posixGetUserInfo(name),
else => @compileError("Unsupported OS"), else => @compileError("Unsupported OS"),
}; };
} }
@ -712,6 +712,7 @@ pub fn getSelfExeSharedLibPaths(allocator: *Allocator) error{OutOfMemory}![][:0]
.freebsd, .freebsd,
.netbsd, .netbsd,
.dragonfly, .dragonfly,
.openbsd,
=> { => {
var paths = List.init(allocator); var paths = List.init(allocator);
errdefer { errdefer {

View File

@ -266,8 +266,8 @@ pub const Target = struct {
}, },
.openbsd => return .{ .openbsd => return .{
.semver = .{ .semver = .{
.min = .{ .major = 6, .minor = 6 }, .min = .{ .major = 6, .minor = 8 },
.max = .{ .major = 6, .minor = 6 }, .max = .{ .major = 6, .minor = 8 },
}, },
}, },
.dragonfly => return .{ .dragonfly => return .{
@ -1362,6 +1362,7 @@ pub const Target = struct {
switch (self.os.tag) { switch (self.os.tag) {
.freebsd => return copy(&result, "/libexec/ld-elf.so.1"), .freebsd => return copy(&result, "/libexec/ld-elf.so.1"),
.netbsd => return copy(&result, "/libexec/ld.elf_so"), .netbsd => return copy(&result, "/libexec/ld.elf_so"),
.openbsd => return copy(&result, "/libexec/ld.so"),
.dragonfly => return copy(&result, "/libexec/ld-elf.so.2"), .dragonfly => return copy(&result, "/libexec/ld-elf.so.2"),
.linux => switch (self.cpu.arch) { .linux => switch (self.cpu.arch) {
.i386, .i386,
@ -1471,7 +1472,6 @@ pub const Target = struct {
.fuchsia, .fuchsia,
.kfreebsd, .kfreebsd,
.lv2, .lv2,
.openbsd,
.solaris, .solaris,
.haiku, .haiku,
.minix, .minix,

View File

@ -449,6 +449,10 @@ pub const CrossTarget = struct {
return self.getOsTag() == .netbsd; return self.getOsTag() == .netbsd;
} }
pub fn isOpenBSD(self: CrossTarget) bool {
return self.getOsTag() == .openbsd;
}
pub fn isUefi(self: CrossTarget) bool { pub fn isUefi(self: CrossTarget) bool {
return self.getOsTag() == .uefi; return self.getOsTag() == .uefi;
} }

View File

@ -196,7 +196,7 @@ pub const LibCInstallation = struct {
errdefer batch.wait() catch {}; errdefer batch.wait() catch {};
batch.add(&async self.findNativeIncludeDirPosix(args)); batch.add(&async self.findNativeIncludeDirPosix(args));
switch (Target.current.os.tag) { switch (Target.current.os.tag) {
.freebsd, .netbsd => self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/usr/lib"), .freebsd, .netbsd, .openbsd => self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/usr/lib"),
.linux, .dragonfly => batch.add(&async self.findNativeCrtDirPosix(args)), .linux, .dragonfly => batch.add(&async self.findNativeCrtDirPosix(args)),
else => {}, else => {},
} }

View File

@ -1432,7 +1432,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
if (link_in_crt) { if (link_in_crt) {
const crt1o: []const u8 = o: { const crt1o: []const u8 = o: {
if (target.os.tag == .netbsd) { if (target.os.tag == .netbsd or target.os.tag == .openbsd) {
break :o "crt0.o"; break :o "crt0.o";
} else if (target.isAndroid()) { } else if (target.isAndroid()) {
if (self.base.options.link_mode == .Dynamic) { if (self.base.options.link_mode == .Dynamic) {
@ -1450,6 +1450,9 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
if (target_util.libc_needs_crti_crtn(target)) { if (target_util.libc_needs_crti_crtn(target)) {
try argv.append(try comp.get_libc_crt_file(arena, "crti.o")); try argv.append(try comp.get_libc_crt_file(arena, "crti.o"));
} }
if (target.os.tag == .openbsd) {
try argv.append(try comp.get_libc_crt_file(arena, "crtbegin.o"));
}
} }
// rpaths // rpaths
@ -1594,6 +1597,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void {
if (link_in_crt) { if (link_in_crt) {
if (target.isAndroid()) { if (target.isAndroid()) {
try argv.append(try comp.get_libc_crt_file(arena, "crtend_android.o")); try argv.append(try comp.get_libc_crt_file(arena, "crtend_android.o"));
} else if (target.os.tag == .openbsd) {
try argv.append(try comp.get_libc_crt_file(arena, "crtend.o"));
} else if (target_util.libc_needs_crti_crtn(target)) { } else if (target_util.libc_needs_crti_crtn(target)) {
try argv.append(try comp.get_libc_crt_file(arena, "crtn.o")); try argv.append(try comp.get_libc_crt_file(arena, "crtn.o"));
} }

View File

@ -25,7 +25,9 @@ comptime {
pub const log = stage2.log; pub const log = stage2.log;
pub const log_level = stage2.log_level; pub const log_level = stage2.log_level;
pub export fn main(argc: c_int, argv: [*]const [*:0]const u8) c_int { pub export fn main(argc: c_int, argv: [*][*:0]u8) c_int {
std.os.argv = argv[0..@intCast(usize, argc)];
std.debug.maybeEnableSegfaultHandler(); std.debug.maybeEnableSegfaultHandler();
zig_stage1_os_init(); zig_stage1_os_init();

View File

@ -59,7 +59,7 @@ typedef SSIZE_T ssize_t;
#endif #endif
#if defined(ZIG_OS_LINUX) || defined(ZIG_OS_FREEBSD) || defined(ZIG_OS_NETBSD) || defined(ZIG_OS_DRAGONFLY) #if defined(ZIG_OS_LINUX) || defined(ZIG_OS_FREEBSD) || defined(ZIG_OS_NETBSD) || defined(ZIG_OS_DRAGONFLY) || defined(ZIG_OS_OPENBSD)
#include <link.h> #include <link.h>
#endif #endif
@ -67,7 +67,7 @@ typedef SSIZE_T ssize_t;
#include <sys/auxv.h> #include <sys/auxv.h>
#endif #endif
#if defined(ZIG_OS_FREEBSD) || defined(ZIG_OS_NETBSD) || defined(ZIG_OS_DRAGONFLY) #if defined(ZIG_OS_FREEBSD) || defined(ZIG_OS_NETBSD) || defined(ZIG_OS_DRAGONFLY) || defined(ZIG_OS_OPENBSD)
#include <sys/sysctl.h> #include <sys/sysctl.h>
#endif #endif

View File

@ -29,6 +29,8 @@
#define ZIG_OS_NETBSD #define ZIG_OS_NETBSD
#elif defined(__DragonFly__) #elif defined(__DragonFly__)
#define ZIG_OS_DRAGONFLY #define ZIG_OS_DRAGONFLY
#elif defined(__OpenBSD__)
#define ZIG_OS_OPENBSD
#else #else
#define ZIG_OS_UNKNOWN #define ZIG_OS_UNKNOWN
#endif #endif

View File

@ -123,7 +123,7 @@ pub fn cannotDynamicLink(target: std.Target) bool {
/// since this is the stable syscall interface. /// since this is the stable syscall interface.
pub fn osRequiresLibC(target: std.Target) bool { pub fn osRequiresLibC(target: std.Target) bool {
return switch (target.os.tag) { return switch (target.os.tag) {
.freebsd, .netbsd, .dragonfly, .macos, .ios, .watchos, .tvos => true, .freebsd, .netbsd, .dragonfly, .openbsd, .macos, .ios, .watchos, .tvos => true,
else => false, else => false,
}; };
} }
@ -143,7 +143,7 @@ pub fn libcNeedsLibUnwind(target: std.Target) bool {
} }
pub fn requiresPIE(target: std.Target) bool { pub fn requiresPIE(target: std.Target) bool {
return target.isAndroid() or target.isDarwin(); return target.isAndroid() or target.isDarwin() or target.os.tag == .openbsd;
} }
/// This function returns whether non-pic code is completely invalid on the given target. /// This function returns whether non-pic code is completely invalid on the given target.
@ -161,7 +161,7 @@ pub fn supports_fpic(target: std.Target) bool {
} }
pub fn libc_needs_crti_crtn(target: std.Target) bool { pub fn libc_needs_crti_crtn(target: std.Target) bool {
return !(target.cpu.arch.isRISCV() or target.isAndroid()); return !(target.cpu.arch.isRISCV() or target.isAndroid() or target.os.tag == .openbsd);
} }
pub fn isSingleThreaded(target: std.Target) bool { pub fn isSingleThreaded(target: std.Target) bool {