Skip to content

Commit 36113cf

Browse files
committed
overhaul elf csu (c-runtime startup) logic
- more support for linux, android, freebsd, netbsd, openbsd, dragonfly - centralize musl utils; musl logic is no longer intertwined with csu - fix musl compilation to build crti/crtn for full archs list - fix openbsd to support `zig build-lib -dynamic` - initial dragonfly linking success (with a warning) ancillary: - fix emutls (openbsd) tests to use `try`
1 parent e6881d4 commit 36113cf

File tree

11 files changed

+298
-82
lines changed

11 files changed

+298
-82
lines changed

lib/std/Thread.zig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,9 @@ pub fn getCurrentThreadId() u64 {
576576
assert(c.pthread_threadid_np(null, &thread_id) == 0);
577577
return thread_id;
578578
},
579+
.dragonfly => {
580+
return @bitCast(u32, c.lwp_gettid());
581+
},
579582
.netbsd => {
580583
return @bitCast(u32, c._lwp_self());
581584
},

lib/std/c/dragonfly.zig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int;
1818
pub const dl_iterate_phdr_callback = fn (info: *dl_phdr_info, size: usize, data: ?*c_void) callconv(.C) c_int;
1919
pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
2020

21+
pub extern "c" fn lwp_gettid() c_int;
22+
2123
pub extern "c" fn posix_memalign(memptr: *?*c_void, alignment: usize, size: usize) c_int;
2224

2325
pub const pthread_mutex_t = extern struct {
@@ -31,3 +33,5 @@ pub const pthread_attr_t = extern struct { // copied from freebsd
3133
__size: [56]u8,
3234
__align: c_long,
3335
};
36+
37+
pub const sem_t = ?*opaque {};

lib/std/child_process.zig

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,10 @@ pub const ChildProcess = struct {
203203
// of space an ArrayList will allocate grows exponentially.
204204
const bump_amt = 512;
205205

206+
// TODO https://github.com/ziglang/zig/issues/8724
207+
// parent process does not receive POLLHUP events
208+
const dragonfly_workaround = builtin.os.tag == .dragonfly;
209+
206210
while (dead_fds < poll_fds.len) {
207211
const events = try os.poll(&poll_fds, std.math.maxInt(i32));
208212
if (events == 0) continue;
@@ -215,15 +219,23 @@ pub const ChildProcess = struct {
215219
try stdout.ensureCapacity(new_capacity);
216220
const buf = stdout.unusedCapacitySlice();
217221
if (buf.len == 0) return error.StdoutStreamTooLong;
218-
stdout.items.len += try os.read(poll_fds[0].fd, buf);
222+
const nread = try os.read(poll_fds[0].fd, buf);
223+
stdout.items.len += nread;
224+
225+
// insert POLLHUP event because dragonfly fails to do so
226+
if (dragonfly_workaround and nread == 0) poll_fds[0].revents |= os.POLLHUP;
219227
}
220228
if (poll_fds[1].revents & os.POLLIN != 0) {
221229
// stderr is ready.
222230
const new_capacity = std.math.min(stderr.items.len + bump_amt, max_output_bytes);
223231
try stderr.ensureCapacity(new_capacity);
224232
const buf = stderr.unusedCapacitySlice();
225233
if (buf.len == 0) return error.StderrStreamTooLong;
226-
stderr.items.len += try os.read(poll_fds[1].fd, buf);
234+
const nread = try os.read(poll_fds[1].fd, buf);
235+
stderr.items.len += nread;
236+
237+
// insert POLLHUP event because dragonfly fails to do so
238+
if (dragonfly_workaround and nread == 0) poll_fds[1].revents |= os.POLLHUP;
227239
}
228240

229241
// Exclude the fds that signaled an error.

lib/std/os/bits/dragonfly.zig

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -774,3 +774,29 @@ pub const rlimit = extern struct {
774774
/// Hard limit
775775
max: rlim_t,
776776
};
777+
778+
pub const SHUT_RD = 0;
779+
pub const SHUT_WR = 1;
780+
pub const SHUT_RDWR = 2;
781+
782+
pub const nfds_t = u32;
783+
784+
pub const pollfd = extern struct {
785+
fd: fd_t,
786+
events: i16,
787+
revents: i16,
788+
};
789+
790+
/// Requestable events.
791+
pub const POLLIN = 0x0001;
792+
pub const POLLPRI = 0x0002;
793+
pub const POLLOUT = 0x0004;
794+
pub const POLLRDNORM = 0x0040;
795+
pub const POLLWRNORM = POLLOUT;
796+
pub const POLLRDBAND = 0x0080;
797+
pub const POLLWRBAND = 0x0100;
798+
799+
/// These events are set if they occur regardless of whether they were requested.
800+
pub const POLLERR = 0x0008;
801+
pub const POLLHUP = 0x0010;
802+
pub const POLLNVAL = 0x0020;

lib/std/special/compiler_rt/emutls.zig

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -376,19 +376,19 @@ test "__emutls_get_address with default_value" {
376376

377377
test "test default_value with differents sizes" {
378378
const testType = struct {
379-
fn _testType(comptime T: type, value: T) void {
379+
fn _testType(comptime T: type, value: T) !void {
380380
var def: T = value;
381381
var ctl = emutls_control.init(T, &def);
382382
var x = ctl.get_typed_pointer(T);
383383
try expect(x.* == value);
384384
}
385385
}._testType;
386386

387-
testType(usize, 1234);
388-
testType(u32, 1234);
389-
testType(i16, -12);
390-
testType(f64, -12.0);
391-
testType(
387+
try testType(usize, 1234);
388+
try testType(u32, 1234);
389+
try testType(i16, -12);
390+
try testType(f64, -12.0);
391+
try testType(
392392
@TypeOf("012345678901234567890123456789"),
393393
"012345678901234567890123456789",
394394
);

src/Compilation.zig

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,7 +1285,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
12851285
}
12861286
if (comp.wantBuildMuslFromSource()) {
12871287
try comp.work_queue.ensureUnusedCapacity(6);
1288-
if (target_util.libc_needs_crti_crtn(comp.getTarget())) {
1288+
if (musl.libc_needs_crti_crtn(comp.getTarget())) {
12891289
comp.work_queue.writeAssumeCapacity(&[_]Job{
12901290
.{ .musl_crt_file = .crti_o },
12911291
.{ .musl_crt_file = .crtn_o },
@@ -2904,7 +2904,7 @@ fn detectLibCIncludeDirs(
29042904
const generic_name = target_util.libCGenericName(target);
29052905
// Some architectures are handled by the same set of headers.
29062906
const arch_name = if (target.abi.isMusl())
2907-
target_util.archMuslName(target.cpu.arch)
2907+
musl.archMuslName(target.cpu.arch)
29082908
else if (target.cpu.arch.isThumb())
29092909
// ARM headers are valid for Thumb too.
29102910
switch (target.cpu.arch) {
@@ -3009,7 +3009,7 @@ fn addBuildingGLibCJobs(comp: *Compilation) !void {
30093009
});
30103010
}
30113011

3012-
fn wantBuildLibCFromSource(comp: Compilation) bool {
3012+
pub fn wantBuildLibCFromSource(comp: Compilation) bool {
30133013
const is_exe_or_dyn_lib = switch (comp.bin_file.options.output_mode) {
30143014
.Obj => false,
30153015
.Lib => comp.bin_file.options.link_mode == .Dynamic,
@@ -3019,16 +3019,16 @@ fn wantBuildLibCFromSource(comp: Compilation) bool {
30193019
comp.bin_file.options.libc_installation == null;
30203020
}
30213021

3022-
fn wantBuildGLibCFromSource(comp: Compilation) bool {
3022+
pub fn wantBuildGLibCFromSource(comp: Compilation) bool {
30233023
return comp.wantBuildLibCFromSource() and comp.getTarget().isGnuLibC();
30243024
}
30253025

3026-
fn wantBuildMuslFromSource(comp: Compilation) bool {
3026+
pub fn wantBuildMuslFromSource(comp: Compilation) bool {
30273027
return comp.wantBuildLibCFromSource() and comp.getTarget().isMusl() and
30283028
!comp.getTarget().isWasm();
30293029
}
30303030

3031-
fn wantBuildMinGWFromSource(comp: Compilation) bool {
3031+
pub fn wantBuildMinGWFromSource(comp: Compilation) bool {
30323032
return comp.wantBuildLibCFromSource() and comp.getTarget().isMinGW();
30333033
}
30343034

src/libc_installation.zig

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,8 @@ pub const LibCInstallation = struct {
195195
errdefer batch.wait() catch {};
196196
batch.add(&async self.findNativeIncludeDirPosix(args));
197197
switch (Target.current.os.tag) {
198-
.freebsd, .netbsd, .openbsd => self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/usr/lib"),
199-
.linux, .dragonfly => batch.add(&async self.findNativeCrtDirPosix(args)),
198+
.freebsd, .netbsd, .openbsd, .dragonfly => self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/usr/lib"),
199+
.linux => batch.add(&async self.findNativeCrtDirPosix(args)),
200200
.haiku => self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/system/develop/lib"),
201201
else => {},
202202
}
@@ -524,7 +524,7 @@ pub const CCPrintFileNameOptions = struct {
524524
};
525525

526526
/// caller owns returned memory
527-
fn ccPrintFileName(args: CCPrintFileNameOptions) ![:0]u8 {
527+
pub fn ccPrintFileName(args: CCPrintFileNameOptions) ![:0]u8 {
528528
const allocator = args.allocator;
529529

530530
const cc_exe = std.os.getenvZ("CC") orelse default_cc_exe;

0 commit comments

Comments
 (0)