diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-07-08 14:24:16 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-07-08 14:24:16 -0700 |
| commit | 476faef97ab0f292159bb3eef42078f9b1e43dde (patch) | |
| tree | fdbe0ebed92520fa7920409cc65c9b51ca9dd288 /src/link | |
| parent | 4eb778fc3eeec62c5c45ccc0a21631ff757d8a23 (diff) | |
| download | zig-476faef97ab0f292159bb3eef42078f9b1e43dde.tar.gz zig-476faef97ab0f292159bb3eef42078f9b1e43dde.zip | |
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
Diffstat (limited to 'src/link')
| -rw-r--r-- | src/link/Plan9.zig | 13 | ||||
| -rw-r--r-- | src/link/Plan9/aout.zig | 114 | ||||
| -rw-r--r-- | src/link/plan9/a.out.zig | 134 |
3 files changed, 121 insertions, 140 deletions
diff --git a/src/link/Plan9.zig b/src/link/Plan9.zig index f12b8af6b5..f880b40d85 100644 --- a/src/link/Plan9.zig +++ b/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 diff --git a/src/link/Plan9/aout.zig b/src/link/Plan9/aout.zig new file mode 100644 index 0000000000..f6dff7437c --- /dev/null +++ b/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, + }; +} diff --git a/src/link/plan9/a.out.zig b/src/link/plan9/a.out.zig deleted file mode 100644 index 85be2d5c36..0000000000 --- a/src/link/plan9/a.out.zig +++ /dev/null @@ -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, - }; -} |
