Skip to content

Commit d0fbfd3

Browse files
committed
Plan 9: add more features to std.os.plan9
* Replaces the exit assembly with the function from std. * Reads the top-of-stack struct at program startup that can get information like the pid. * Changes the read and write functions to use the Pread and Pwrite syscalls instead of the depreciated _READ and _WRITE * Changes the openat function to use flags instead of perms. Plan9 does not support perms when opening, just when creating. * Adds an errstr function to read the errstr buf created by the kernel
1 parent 841b54f commit d0fbfd3

File tree

2 files changed

+57
-33
lines changed

2 files changed

+57
-33
lines changed

lib/std/os/plan9.zig

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,43 @@ pub fn getErrno(r: usize) E {
1818
const int = if (signed_r > -4096 and signed_r < 0) -signed_r else 0;
1919
return @as(E, @enumFromInt(int));
2020
}
21+
// The max bytes that can be in the errstr buff
22+
pub const ERRMAX = 128;
23+
var errstr_buf: [ERRMAX]u8 = undefined;
24+
/// Gets whatever the last errstr was
25+
pub fn errstr() []const u8 {
26+
_ = syscall_bits.syscall2(.ERRSTR, @intFromPtr(&errstr_buf), ERRMAX);
27+
return std.mem.span(@as([*:0]u8, @ptrCast(&errstr_buf)));
28+
}
29+
pub const Plink = anyopaque;
30+
pub const Tos = extern struct {
31+
/// Per process profiling
32+
prof: extern struct {
33+
/// known to be 0(ptr)
34+
pp: *Plink,
35+
/// known to be 4(ptr)
36+
next: *Plink,
37+
last: *Plink,
38+
first: *Plink,
39+
pid: u32,
40+
what: u32,
41+
},
42+
/// cycle clock frequency if there is one, 0 otherwise
43+
cyclefreq: u64,
44+
/// cycles spent in kernel
45+
kcycles: i64,
46+
/// cycles spent in process (kernel + user)
47+
pcycles: i64,
48+
/// might as well put the pid here
49+
pid: u32,
50+
clock: u32,
51+
// top of stack is here
52+
};
53+
54+
pub var tos: *Tos = undefined; // set in start.zig
55+
pub fn getpid() u32 {
56+
return tos.pid;
57+
}
2158
pub const SIG = struct {
2259
/// hangup
2360
pub const HUP = 1;
@@ -143,26 +180,27 @@ pub const SYS = enum(usize) {
143180
};
144181

145182
pub fn write(fd: i32, buf: [*]const u8, count: usize) usize {
146-
return syscall_bits.syscall3(._WRITE, @bitCast(@as(isize, fd)), @intFromPtr(buf), count);
183+
return syscall_bits.syscall4(.PWRITE, @bitCast(@as(isize, fd)), @intFromPtr(buf), count, @bitCast(@as(isize, -1)));
147184
}
148-
pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: usize) usize {
149-
return syscall_bits.syscall4(.PWRITE, @bitCast(@as(isize, fd)), @intFromPtr(buf), count, offset);
185+
pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: isize) usize {
186+
return syscall_bits.syscall4(.PWRITE, @bitCast(@as(isize, fd)), @intFromPtr(buf), count, @bitCast(offset));
150187
}
151188

152189
pub fn read(fd: i32, buf: [*]const u8, count: usize) usize {
153-
return syscall_bits.syscall3(._READ, @bitCast(@as(isize, fd)), @intFromPtr(buf), count);
190+
return syscall_bits.syscall4(.PREAD, @bitCast(@as(isize, fd)), @intFromPtr(buf), count, @bitCast(@as(isize, -1)));
154191
}
155-
pub fn pread(fd: i32, buf: [*]const u8, count: usize, offset: usize) usize {
156-
return syscall_bits.syscall4(.PREAD, @bitCast(@as(isize, fd)), @intFromPtr(buf), count, offset);
192+
pub fn pread(fd: i32, buf: [*]const u8, count: usize, offset: isize) usize {
193+
return syscall_bits.syscall4(.PREAD, @bitCast(@as(isize, fd)), @intFromPtr(buf), count, @bitCast(offset));
157194
}
158195

159-
pub fn open(path: [*:0]const u8, omode: mode_t) usize {
160-
return syscall_bits.syscall2(.OPEN, @intFromPtr(path), @bitCast(@as(isize, omode)));
196+
pub fn open(path: [*:0]const u8, flags: u32) usize {
197+
return syscall_bits.syscall2(.OPEN, @intFromPtr(path), @bitCast(@as(isize, flags)));
161198
}
162199

163-
pub fn openat(dirfd: i32, path: [*:0]const u8, _: u32, omode: mode_t) usize {
200+
pub fn openat(dirfd: i32, path: [*:0]const u8, flags: u32, _: mode_t) usize {
201+
// we skip perms because only create supports perms
164202
if (dirfd == AT.FDCWD) { // openat(AT_FDCWD, ...) == open(...)
165-
return open(path, omode);
203+
return open(path, flags);
166204
}
167205
var dir_path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
168206
var total_path_buf: [std.fs.MAX_PATH_BYTES + 1]u8 = undefined;
@@ -174,7 +212,7 @@ pub fn openat(dirfd: i32, path: [*:0]const u8, _: u32, omode: mode_t) usize {
174212
const total_path = std.fs.path.join(alloc, &.{ dir_path, std.mem.span(path) }) catch unreachable; // the allocation shouldn't fail because it should not exceed MAX_PATH_BYTES
175213
fba.reset();
176214
const total_path_z = alloc.dupeZ(u8, total_path) catch unreachable; // should not exceed MAX_PATH_BYTES + 1
177-
return open(total_path_z.ptr, omode);
215+
return open(total_path_z.ptr, flags);
178216
}
179217

180218
pub fn fd2path(fd: i32, buf: [*]u8, nbuf: usize) usize {

lib/std/start.zig

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -166,28 +166,7 @@ fn exit2(code: usize) noreturn {
166166
else => @compileError("TODO"),
167167
},
168168
// exits(0)
169-
.plan9 => switch (builtin.cpu.arch) {
170-
.x86_64 => {
171-
asm volatile (
172-
\\push $0
173-
\\push $0
174-
\\syscall
175-
:
176-
: [syscall_number] "{rbp}" (8),
177-
: "rcx", "r11", "memory"
178-
);
179-
},
180-
// TODO once we get stack setting with assembly on
181-
// arm, exit with 0 instead of stack garbage
182-
.aarch64 => {
183-
asm volatile ("svc #0"
184-
:
185-
: [exit] "{x0}" (0x08),
186-
: "memory", "cc"
187-
);
188-
},
189-
else => @compileError("TODO"),
190-
},
169+
.plan9 => std.os.plan9.exits(null),
191170
.windows => {
192171
ExitProcess(@as(u32, @truncate(code)));
193172
},
@@ -254,6 +233,13 @@ fn EfiMain(handle: uefi.Handle, system_table: *uefi.tables.SystemTable) callconv
254233
}
255234

256235
fn _start() callconv(.Naked) noreturn {
236+
// TODO set Top of Stack on non x86_64-plan9
237+
if (native_os == .plan9 and native_arch == .x86_64) {
238+
// from /sys/src/libc/amd64/main9.s
239+
std.os.plan9.tos = asm volatile (""
240+
: [tos] "={rax}" (-> *std.os.plan9.Tos),
241+
);
242+
}
257243
asm volatile (switch (native_arch) {
258244
.x86_64 =>
259245
\\ xorl %%ebp, %%ebp

0 commit comments

Comments
 (0)