Commit 476faef97a

Andrew Kelley <andrew@ziglang.org>
2021-07-08 23:24:16
plan9 cleanups
* rename files to adhere to conventions * remove unnecessary function / optionality * fix merge conflict * better panic message * remove unnecessary TODO comment * proper namespacing of declarations * clean up documentation comments * no copyright header needed for a brand new zig file that is not copied from anywhere
1 parent 4eb778f
Changed files (7)
lib/std/zig.zig
@@ -181,32 +181,32 @@ pub fn binNameAlloc(allocator: *std.mem.Allocator, options: BinNameOptions) erro
         .spirv => return std.fmt.allocPrint(allocator, "{s}.spv", .{root_name}),
         .hex => return std.fmt.allocPrint(allocator, "{s}.ihex", .{root_name}),
         .raw => return std.fmt.allocPrint(allocator, "{s}.bin", .{root_name}),
-        .plan9 => return std.fmt.allocPrint(allocator, "{s}.{c}", .{ root_name, archToPlan9Char(target.cpu.arch) }),
+        .plan9 => {
+            // copied from 2c(1)
+            // 0c spim    little-endian MIPS 3000 family
+            // 1c 68000   Motorola MC68000
+            // 2c 68020   Motorola MC68020
+            // 5c arm     little-endian ARM
+            // 6c amd64   AMD64 and compatibles (e.g., Intel EM64T)
+            // 7c arm64   ARM64 (ARMv8)
+            // 8c 386     Intel i386, i486, Pentium, etc.
+            // kc sparc   Sun SPARC
+            // qc power   Power PC
+            // vc mips    big-endian MIPS 3000 family
+            const char: u8 = switch (target.cpu.arch) {
+                .arm => '5',
+                .x86_64 => '6',
+                .aarch64 => '7',
+                .i386 => '8',
+                .sparc => 'k',
+                .powerpc, .powerpcle => 'q',
+                .mips, .mipsel => 'v',
+                else => 'X', // this arch does not have a char or maybe was not ported to plan9 so we just use X
+            };
+            return std.fmt.allocPrint(allocator, "{s}.{c}", .{ root_name, char });
+        },
     }
 }
-fn archToPlan9Char(arch: std.Target.Cpu.Arch) ?u8 {
-    // copied from 2c(1)
-    // 0c spim    little-endian MIPS 3000 family
-    // 1c 68000   Motorola MC68000
-    // 2c 68020   Motorola MC68020
-    // 5c arm     little-endian ARM
-    // 6c amd64   AMD64 and compatibles (e.g., Intel EM64T)
-    // 7c arm64   ARM64 (ARMv8)
-    // 8c 386     Intel i386, i486, Pentium, etc.
-    // kc sparc   Sun SPARC
-    // qc power   Power PC
-    // vc mips    big-endian MIPS 3000 family
-    return switch (arch) {
-        .arm => '5',
-        .x86_64 => '6',
-        .aarch64 => '7',
-        .i386 => '8',
-        .sparc => 'k',
-        .powerpc, .powerpcle => 'q',
-        .mips, .mipsel => 'v',
-        else => 'X', // this arch does not have a char or maybe was not ported to plan9 so we just use X
-    };
-}
 
 pub const ParsedCharLiteral = union(enum) {
     success: u32,
src/link/Plan9/aout.zig
@@ -0,0 +1,114 @@
+const std = @import("std");
+const assert = std.debug.assert;
+
+/// All integers are in big-endian format (needs a byteswap).
+pub const ExecHdr = extern struct {
+    magic: u32,
+    text: u32,
+    data: u32,
+    bss: u32,
+    syms: u32,
+    /// You should truncate this to 32 bits on 64 bit systems, then but the actual 8 bytes
+    /// in the fat header.
+    entry: u32,
+    spsz: u32,
+    pcsz: u32,
+    comptime {
+        assert(@sizeOf(@This()) == 32);
+    }
+    /// It is up to the caller to disgard the last 8 bytes if the header is not fat.
+    pub fn toU8s(self: *@This()) [40]u8 {
+        var buf: [40]u8 = undefined;
+        var i: u8 = 0;
+        inline for (std.meta.fields(@This())) |f| {
+            std.mem.writeIntSliceBig(u32, buf[i .. i + 4], @field(self, f.name));
+            i += 4;
+        }
+        return buf;
+    }
+};
+
+pub const Sym = struct {
+    /// Big endian in the file
+    value: u64,
+    type: Type,
+    name: []const u8,
+
+    /// The type field is one of the following characters with the
+    /// high bit set:
+    /// T    text segment symbol
+    /// t    static text segment symbol
+    /// L    leaf function text segment symbol
+    /// l    static leaf function text segment symbol
+    /// D    data segment symbol
+    /// d    static data segment symbol
+    /// B    bss segment symbol
+    /// b    static bss segment symbol
+    /// a    automatic (local) variable symbol
+    /// p    function parameter symbol
+    /// f    source file name components
+    /// z    source file name
+    /// Z    source file line offset
+    /// m for '.frame'
+    pub const Type = enum(u8) {
+        T = 0x80 | 'T',
+        t = 0x80 | 't',
+        L = 0x80 | 'L',
+        l = 0x80 | 'l',
+        D = 0x80 | 'D',
+        d = 0x80 | 'd',
+        B = 0x80 | 'B',
+        b = 0x80 | 'b',
+        a = 0x80 | 'a',
+        p = 0x80 | 'p',
+        f = 0x80 | 'f',
+        z = 0x80 | 'z',
+        Z = 0x80 | 'Z',
+        m = 0x80 | 'm',
+
+        pub fn toGlobal(self: Type) Type {
+            return switch (self) {
+                .t => .T,
+                .b => .B,
+                .d => .D,
+                else => unreachable,
+            };
+        }
+    };
+};
+
+pub const HDR_MAGIC = 0x00008000;
+pub inline fn _MAGIC(f: anytype, b: anytype) @TypeOf(f | ((((@as(c_int, 4) * b) + @as(c_int, 0)) * b) + @as(c_int, 7))) {
+    return f | ((((@as(c_int, 4) * b) + @as(c_int, 0)) * b) + @as(c_int, 7));
+}
+pub const A_MAGIC = _MAGIC(0, 8); // 68020
+pub const I_MAGIC = _MAGIC(0, 11); // intel 386
+pub const J_MAGIC = _MAGIC(0, 12); // intel 960 (retired)
+pub const K_MAGIC = _MAGIC(0, 13); // sparc
+pub const V_MAGIC = _MAGIC(0, 16); // mips 3000 BE
+pub const X_MAGIC = _MAGIC(0, 17); // att dsp 3210 (retired)
+pub const M_MAGIC = _MAGIC(0, 18); // mips 4000 BE
+pub const D_MAGIC = _MAGIC(0, 19); // amd 29000 (retired)
+pub const E_MAGIC = _MAGIC(0, 20); // arm
+pub const Q_MAGIC = _MAGIC(0, 21); // powerpc
+pub const N_MAGIC = _MAGIC(0, 22); // mips 4000 LE
+pub const L_MAGIC = _MAGIC(0, 23); // dec alpha (retired)
+pub const P_MAGIC = _MAGIC(0, 24); // mips 3000 LE
+pub const U_MAGIC = _MAGIC(0, 25); // sparc64
+pub const S_MAGIC = _MAGIC(HDR_MAGIC, 26); // amd64
+pub const T_MAGIC = _MAGIC(HDR_MAGIC, 27); // powerpc64
+pub const R_MAGIC = _MAGIC(HDR_MAGIC, 28); // arm64
+
+pub fn magicFromArch(arch: std.Target.Cpu.Arch) !u32 {
+    return switch (arch) {
+        .i386 => I_MAGIC,
+        .sparc => K_MAGIC, // TODO should sparcv9 and sparcel go here?
+        .mips => V_MAGIC,
+        .arm => E_MAGIC,
+        .aarch64 => R_MAGIC,
+        .powerpc => Q_MAGIC,
+        .powerpc64 => T_MAGIC,
+        .x86_64 => S_MAGIC,
+        else => error.ArchNotSupportedByPlan9,
+    };
+}
src/link/plan9/a.out.zig
@@ -1,134 +0,0 @@
-// Copyright © 2021 Plan 9 Foundation
-// Copyright © 20XX 9front authors
-
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-// Idomatic translation of 9front a.out.h
-const std = @import("std");
-// all integers are in big-endian format (needs a byteswap)
-pub const ExecHdr = extern struct {
-    magic: u32,
-    text: u32,
-    data: u32,
-    bss: u32,
-    syms: u32,
-    /// You should truncate this to 32 bits on 64 bit systems, then but the actual 8 bytes
-    /// in the fat header.
-    entry: u32,
-    spsz: u32,
-    pcsz: u32,
-    comptime {
-        std.debug.assert(@sizeOf(@This()) == 32);
-    }
-    /// it is up to the caller to disgard the last 8 bytes if the header is not fat
-    pub fn toU8s(self: *@This()) [40]u8 {
-        var buf: [40]u8 = undefined;
-        var i: u8 = 0;
-        inline for (std.meta.fields(@This())) |f| {
-            std.mem.writeIntSliceBig(u32, buf[i .. i + 4], @field(self, f.name));
-            i += 4;
-        }
-        return buf;
-    }
-};
-
-// uchar value[8];
-// char  type;
-// char  name[n];   /* NUL-terminated */
-pub const Sym = struct {
-    value: u64, // big endian in the file
-    type: SymType,
-    name: []const u8,
-};
-// The type field is one of the following characters with the
-// high bit set:
-// T    text segment symbol
-// t    static text segment symbol
-// L    leaf function text segment symbol
-// l    static leaf function text segment symbol
-// D    data segment symbol
-// d    static data segment symbol
-// B    bss segment symbol
-// b    static bss segment symbol
-// a    automatic (local) variable symbol
-// p    function parameter symbol
-// f    source file name components
-// z    source file name
-// Z    source file line offset
-// m for '.frame'
-pub const SymType = enum(u8) {
-    T = 0x80 | 'T',
-    t = 0x80 | 't',
-    L = 0x80 | 'L',
-    l = 0x80 | 'l',
-    D = 0x80 | 'D',
-    d = 0x80 | 'd',
-    B = 0x80 | 'B',
-    b = 0x80 | 'b',
-    a = 0x80 | 'a',
-    p = 0x80 | 'p',
-    f = 0x80 | 'f',
-    z = 0x80 | 'z',
-    Z = 0x80 | 'Z',
-    m = 0x80 | 'm',
-    pub fn toGlobal(self: SymType) SymType {
-        return switch (self) {
-            .t => .T,
-            .b => .B,
-            .d => .D,
-            else => unreachable,
-        };
-    }
-};
-
-pub const HDR_MAGIC = 0x00008000;
-pub inline fn _MAGIC(f: anytype, b: anytype) @TypeOf(f | ((((@as(c_int, 4) * b) + @as(c_int, 0)) * b) + @as(c_int, 7))) {
-    return f | ((((@as(c_int, 4) * b) + @as(c_int, 0)) * b) + @as(c_int, 7));
-}
-pub const A_MAGIC = _MAGIC(0, 8); // 68020
-pub const I_MAGIC = _MAGIC(0, 11); // intel 386
-pub const J_MAGIC = _MAGIC(0, 12); // intel 960 (retired)
-pub const K_MAGIC = _MAGIC(0, 13); // sparc
-pub const V_MAGIC = _MAGIC(0, 16); // mips 3000 BE
-pub const X_MAGIC = _MAGIC(0, 17); // att dsp 3210 (retired)
-pub const M_MAGIC = _MAGIC(0, 18); // mips 4000 BE
-pub const D_MAGIC = _MAGIC(0, 19); // amd 29000 (retired)
-pub const E_MAGIC = _MAGIC(0, 20); // arm
-pub const Q_MAGIC = _MAGIC(0, 21); // powerpc
-pub const N_MAGIC = _MAGIC(0, 22); // mips 4000 LE
-pub const L_MAGIC = _MAGIC(0, 23); // dec alpha (retired)
-pub const P_MAGIC = _MAGIC(0, 24); // mips 3000 LE
-pub const U_MAGIC = _MAGIC(0, 25); // sparc64
-pub const S_MAGIC = _MAGIC(HDR_MAGIC, 26); // amd64
-pub const T_MAGIC = _MAGIC(HDR_MAGIC, 27); // powerpc64
-pub const R_MAGIC = _MAGIC(HDR_MAGIC, 28); // arm64
-
-pub fn magicFromArch(arch: std.Target.Cpu.Arch) !u32 {
-    return switch (arch) {
-        .i386 => I_MAGIC,
-        .sparc => K_MAGIC, // TODO should sparcv9 and sparcel go here?
-        .mips => V_MAGIC,
-        .arm => E_MAGIC,
-        .aarch64 => R_MAGIC,
-        .powerpc => Q_MAGIC,
-        .powerpc64 => T_MAGIC,
-        .x86_64 => S_MAGIC,
-        else => error.ArchNotSupportedByPlan9,
-    };
-}
src/link/Plan9.zig
@@ -1,10 +1,13 @@
+//! This implementation does all the linking work in flush(). A future improvement
+//! would be to add incremental linking in a similar way as ELF does.
+
 const Plan9 = @This();
 
 const std = @import("std");
 const link = @import("../link.zig");
 const Module = @import("../Module.zig");
 const Compilation = @import("../Compilation.zig");
-const aout = @import("plan9/a.out.zig");
+const aout = @import("Plan9/aout.zig");
 const codegen = @import("../codegen.zig");
 const trace = @import("../tracy.zig").trace;
 const mem = std.mem;
@@ -14,8 +17,6 @@ const Allocator = std.mem.Allocator;
 const log = std.log.scoped(.link);
 const assert = std.debug.assert;
 
-// TODO use incremental compilation
-
 base: link.File,
 sixtyfour_bit: bool,
 error_flags: File.ErrorFlags = File.ErrorFlags{},
@@ -38,7 +39,7 @@ const Bases = struct {
     data: u64,
 };
 
-fn getAddr(self: Plan9, addr: u64, t: aout.SymType) u64 {
+fn getAddr(self: Plan9, addr: u64, t: aout.Sym.Type) u64 {
     return addr + switch (t) {
         .T, .t, .l, .L => self.bases.text,
         .D, .d, .B, .b => self.bases.data,
@@ -46,7 +47,7 @@ fn getAddr(self: Plan9, addr: u64, t: aout.SymType) u64 {
     };
 }
 /// opposite of getAddr
-fn takeAddr(self: Plan9, addr: u64, t: aout.SymType) u64 {
+fn takeAddr(self: Plan9, addr: u64, t: aout.Sym.Type) u64 {
     return addr - switch (t) {
         .T, .t, .l, .L => self.bases.text,
         .D, .d, .B, .b => self.bases.data,
@@ -59,7 +60,7 @@ fn getSymAddr(self: Plan9, s: aout.Sym) u64 {
 }
 
 pub const DeclBlock = struct {
-    type: aout.SymType,
+    type: aout.Sym.Type,
     /// offset in the text or data sects
     offset: ?u64,
     /// offset into syms
src/codegen.zig
@@ -2556,7 +2556,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
                 } else {
                     return self.fail(inst.base.src, "TODO implement calling runtime known function pointer", .{});
                 }
-            } else if (self.bin_file.cast(link.File.Plan9)) |_| {
+            } else if (self.bin_file.cast(link.File.Plan9)) |p9| {
                 switch (arch) {
                     .x86_64 => {
                         for (info.args) |mc_arg, arg_i| {
src/link.zig
@@ -333,7 +333,7 @@ pub const File = struct {
             .elf => return @fieldParentPtr(Elf, "base", base).updateDeclLineNumber(module, decl),
             .macho => return @fieldParentPtr(MachO, "base", base).updateDeclLineNumber(module, decl),
             .c => return @fieldParentPtr(C, "base", base).updateDeclLineNumber(module, decl),
-            .plan9 => @panic("PLAN 9 DEBUG INFO"),
+            .plan9 => @panic("TODO: implement updateDeclLineNumber for plan9"),
             .wasm, .spirv => {},
         }
     }
CMakeLists.txt
@@ -574,7 +574,7 @@ set(ZIG_STAGE2_SOURCES
     "${CMAKE_SOURCE_DIR}/src/link/Coff.zig"
     "${CMAKE_SOURCE_DIR}/src/link/Elf.zig"
     "${CMAKE_SOURCE_DIR}/src/link/Plan9.zig"
-    "${CMAKE_SOURCE_DIR}/src/link/plan9/a.out.zig"
+    "${CMAKE_SOURCE_DIR}/src/link/Plan9/aout.zig"
     "${CMAKE_SOURCE_DIR}/src/link/MachO.zig"
     "${CMAKE_SOURCE_DIR}/src/link/MachO/Archive.zig"
     "${CMAKE_SOURCE_DIR}/src/link/MachO/CodeSignature.zig"