authorgravatar for jacoblevgw@gmail.comJacob G-W <jacoblevgw@gmail.com> 2023-07-16 21:34:13-04:00
committergravatar for jacoblevgw@gmail.comJacob G-W <jacoblevgw@gmail.com> 2023-08-02 18:19:07-04:00
logd0fbfd3c9f419ceb7112d06d4a3500e9c13f6044
treead6eeb111777476b7bf5a0411f98c38006131625
parent841b54f5e3447ee94d89007bf670b3924f78b0d2

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

2 files changed, 57 insertions(+), 33 deletions(-)

lib/std/os/plan9.zig+49-11
......@@ -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
22pub const ERRMAX = 128;
23var errstr_buf: [ERRMAX]u8 = undefined;
24/// Gets whatever the last errstr was
25pub 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}
29pub const Plink = anyopaque;
30pub 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
54pub var tos: *Tos = undefined; // set in start.zig
55pub fn getpid() u32 {
56 return tos.pid;
57}
2158pub const SIG = struct {
2259 /// hangup
2360 pub const HUP = 1;
......@@ -143,26 +180,27 @@ pub const SYS = enum(usize) {
143180};
144181
145182pub 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}
148pub 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);
185pub 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
152189pub 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}
155pub 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);
192pub 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
159pub fn open(path: [*:0]const u8, omode: mode_t) usize {
160 return syscall_bits.syscall2(.OPEN, @intFromPtr(path), @bitCast(@as(isize, omode)));
196pub fn open(path: [*:0]const u8, flags: u32) usize {
197 return syscall_bits.syscall2(.OPEN, @intFromPtr(path), @bitCast(@as(isize, flags)));
161198}
162199
163pub fn openat(dirfd: i32, path: [*:0]const u8, _: u32, omode: mode_t) usize {
200pub 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
180218pub fn fd2path(fd: i32, buf: [*]u8, nbuf: usize) usize {
lib/std/start.zig+8-22
......@@ -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
256235fn _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