Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Netbsd forever #4793

Merged
merged 11 commits into from Mar 25, 2020
Merged

Netbsd forever #4793

merged 11 commits into from Mar 25, 2020

Conversation

LemonBoy
Copy link
Contributor

Let me show some love for a really nice OS, NetBSD is the only BSD that manages to build Zig using LLVM from pkg!

What this patchset does:

Speaking of the event code, on NetBSD we have kqueue but without EVFILT_USER so cross-thread signaling has to be done like it's done for Linux using a pipe (or a socketpair) per-thread.

On NetBSD this caused the libuserland compilation to fail.

Closes ziglang#3719
* Use the correct versioned libc calls to avoid nasty surprises
* NetBSD is stricter than other OSs and doesn't allow mprotect to mark a
  non-accessible region as RW
* Fix mprotect call over the whole stack, oops
The guard page size shouldn't be taken into account, pthread is only
interested in the usable area.
On NetBSD this is needed to avoid crashes in pthread_join as the default
value for the guard page size is not ignored even though a custom stack
address is specified.
lib/std/os.zig Outdated
@@ -2542,6 +2542,17 @@ pub fn fstat(fd: fd_t) FStatError!Stat {
}
}

if (std.Target.current.os.tag == .netbsd) {
switch (errno(system.__fstat50(fd, &stat))) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets share the error code paths with the generic posix ones below?

switch (errno(switch(std.Target.current.os.tag) {
     .netbsd => system.__fstat50(fd, &stat),
     else => system.fstat(fd, &stat),
})) {
    ....
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking of something like this to avoid excessive nesting:

const fstat_symbol = switch (std.Target.current.os.tag) {
     .netbsd => "__fstat50",
     else => "fstat",
};
switch (errno(@field(system, fstat_symbol))) {
 ...
}

lib/std/os.zig Outdated Show resolved Hide resolved
@mikdusan
Copy link
Member

looking good so far!

netbsd 9.0: zig build test -Dskip-release -Dskip-non-native:

./lib/std/event/loop.zig:282:45: error: container 'os' has no member called 'EVFILT_USER'
                                .filter = os.EVFILT_USER,
                                            ^

@LemonBoy
Copy link
Contributor Author

Yeah that's expected, the event loop code expects evfilt_user to be available but that's not the case for NetBSD (nor OpenBSD afair).

But again, even on FreeBSD that test compiles and hangs, so it's safe to say that only Linux is well supported at the moment.

@andrewrk andrewrk merged commit 3869e80 into ziglang:master Mar 25, 2020

break :mem mmap_slice;
} else {
// NetBSD mprotect is very strict and doesn't allow to "upgrade"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason the NetBSD code path isn't used on every OS? Basically, you're dropping privileges instead of acquiring them later.

This should also be correct for grsec and similar hardened kernels, AFAIK.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Linux we can tell the kernel that the guard page is effectively empty and can avoid allocating memory for that. The savings are small but scale linearly with the number of threads we spawn.

This should also be correct for grsec and similar hardened kernels, AFAIK.

Hmm, that may be a problem...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

"error: FileNotFound, reached unreachable code" during libuserland install on NetBSD
5 participants