| author | |
| committer | |
| log | 476faef97ab0f292159bb3eef42078f9b1e43dde |
| tree | fdbe0ebed92520fa7920409cc65c9b51ca9dd288 |
| parent | 4eb778fc3eeec62c5c45ccc0a21631ff757d8a23 |
* 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 anywhere7 files changed, 148 insertions(+), 167 deletions(-)
CMakeLists.txt+1-1| ... | @@ -574,7 +574,7 @@ set(ZIG_STAGE2_SOURCES | ... | @@ -574,7 +574,7 @@ set(ZIG_STAGE2_SOURCES |
| 574 | "${CMAKE_SOURCE_DIR}/src/link/Coff.zig" | 574 | "${CMAKE_SOURCE_DIR}/src/link/Coff.zig" |
| 575 | "${CMAKE_SOURCE_DIR}/src/link/Elf.zig" | 575 | "${CMAKE_SOURCE_DIR}/src/link/Elf.zig" |
| 576 | "${CMAKE_SOURCE_DIR}/src/link/Plan9.zig" | 576 | "${CMAKE_SOURCE_DIR}/src/link/Plan9.zig" |
| 577 | "${CMAKE_SOURCE_DIR}/src/link/plan9/a.out.zig" | 577 | "${CMAKE_SOURCE_DIR}/src/link/Plan9/aout.zig" |
| 578 | "${CMAKE_SOURCE_DIR}/src/link/MachO.zig" | 578 | "${CMAKE_SOURCE_DIR}/src/link/MachO.zig" |
| 579 | "${CMAKE_SOURCE_DIR}/src/link/MachO/Archive.zig" | 579 | "${CMAKE_SOURCE_DIR}/src/link/MachO/Archive.zig" |
| 580 | "${CMAKE_SOURCE_DIR}/src/link/MachO/CodeSignature.zig" | 580 | "${CMAKE_SOURCE_DIR}/src/link/MachO/CodeSignature.zig" |
lib/std/zig.zig+24-24| ... | @@ -181,32 +181,32 @@ pub fn binNameAlloc(allocator: *std.mem.Allocator, options: BinNameOptions) erro | ... | @@ -181,32 +181,32 @@ pub fn binNameAlloc(allocator: *std.mem.Allocator, options: BinNameOptions) erro |
| 181 | .spirv => return std.fmt.allocPrint(allocator, "{s}.spv", .{root_name}), | 181 | .spirv => return std.fmt.allocPrint(allocator, "{s}.spv", .{root_name}), |
| 182 | .hex => return std.fmt.allocPrint(allocator, "{s}.ihex", .{root_name}), | 182 | .hex => return std.fmt.allocPrint(allocator, "{s}.ihex", .{root_name}), |
| 183 | .raw => return std.fmt.allocPrint(allocator, "{s}.bin", .{root_name}), | 183 | .raw => return std.fmt.allocPrint(allocator, "{s}.bin", .{root_name}), |
| 184 | .plan9 => return std.fmt.allocPrint(allocator, "{s}.{c}", .{ root_name, archToPlan9Char(target.cpu.arch) }), | 184 | .plan9 => { |
| 185 | // copied from 2c(1) | ||
| 186 | // 0c spim little-endian MIPS 3000 family | ||
| 187 | // 1c 68000 Motorola MC68000 | ||
| 188 | // 2c 68020 Motorola MC68020 | ||
| 189 | // 5c arm little-endian ARM | ||
| 190 | // 6c amd64 AMD64 and compatibles (e.g., Intel EM64T) | ||
| 191 | // 7c arm64 ARM64 (ARMv8) | ||
| 192 | // 8c 386 Intel i386, i486, Pentium, etc. | ||
| 193 | // kc sparc Sun SPARC | ||
| 194 | // qc power Power PC | ||
| 195 | // vc mips big-endian MIPS 3000 family | ||
| 196 | const char: u8 = switch (target.cpu.arch) { | ||
| 197 | .arm => '5', | ||
| 198 | .x86_64 => '6', | ||
| 199 | .aarch64 => '7', | ||
| 200 | .i386 => '8', | ||
| 201 | .sparc => 'k', | ||
| 202 | .powerpc, .powerpcle => 'q', | ||
| 203 | .mips, .mipsel => 'v', | ||
| 204 | else => 'X', // this arch does not have a char or maybe was not ported to plan9 so we just use X | ||
| 205 | }; | ||
| 206 | return std.fmt.allocPrint(allocator, "{s}.{c}", .{ root_name, char }); | ||
| 207 | }, | ||
| 185 | } | 208 | } |
| 186 | } | 209 | } |
| 187 | fn archToPlan9Char(arch: std.Target.Cpu.Arch) ?u8 { | ||
| 188 | // copied from 2c(1) | ||
| 189 | // 0c spim little-endian MIPS 3000 family | ||
| 190 | // 1c 68000 Motorola MC68000 | ||
| 191 | // 2c 68020 Motorola MC68020 | ||
| 192 | // 5c arm little-endian ARM | ||
| 193 | // 6c amd64 AMD64 and compatibles (e.g., Intel EM64T) | ||
| 194 | // 7c arm64 ARM64 (ARMv8) | ||
| 195 | // 8c 386 Intel i386, i486, Pentium, etc. | ||
| 196 | // kc sparc Sun SPARC | ||
| 197 | // qc power Power PC | ||
| 198 | // vc mips big-endian MIPS 3000 family | ||
| 199 | return switch (arch) { | ||
| 200 | .arm => '5', | ||
| 201 | .x86_64 => '6', | ||
| 202 | .aarch64 => '7', | ||
| 203 | .i386 => '8', | ||
| 204 | .sparc => 'k', | ||
| 205 | .powerpc, .powerpcle => 'q', | ||
| 206 | .mips, .mipsel => 'v', | ||
| 207 | else => 'X', // this arch does not have a char or maybe was not ported to plan9 so we just use X | ||
| 208 | }; | ||
| 209 | } | ||
| 210 | 210 | ||
| 211 | pub const ParsedCharLiteral = union(enum) { | 211 | pub const ParsedCharLiteral = union(enum) { |
| 212 | success: u32, | 212 | success: u32, |
src/codegen.zig+1-1| ... | @@ -2556,7 +2556,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -2556,7 +2556,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 2556 | } else { | 2556 | } else { |
| 2557 | return self.fail(inst.base.src, "TODO implement calling runtime known function pointer", .{}); | 2557 | return self.fail(inst.base.src, "TODO implement calling runtime known function pointer", .{}); |
| 2558 | } | 2558 | } |
| 2559 | } else if (self.bin_file.cast(link.File.Plan9)) |_| { | 2559 | } else if (self.bin_file.cast(link.File.Plan9)) |p9| { |
| 2560 | switch (arch) { | 2560 | switch (arch) { |
| 2561 | .x86_64 => { | 2561 | .x86_64 => { |
| 2562 | for (info.args) |mc_arg, arg_i| { | 2562 | for (info.args) |mc_arg, arg_i| { |
src/link.zig+1-1| ... | @@ -333,7 +333,7 @@ pub const File = struct { | ... | @@ -333,7 +333,7 @@ pub const File = struct { |
| 333 | .elf => return @fieldParentPtr(Elf, "base", base).updateDeclLineNumber(module, decl), | 333 | .elf => return @fieldParentPtr(Elf, "base", base).updateDeclLineNumber(module, decl), |
| 334 | .macho => return @fieldParentPtr(MachO, "base", base).updateDeclLineNumber(module, decl), | 334 | .macho => return @fieldParentPtr(MachO, "base", base).updateDeclLineNumber(module, decl), |
| 335 | .c => return @fieldParentPtr(C, "base", base).updateDeclLineNumber(module, decl), | 335 | .c => return @fieldParentPtr(C, "base", base).updateDeclLineNumber(module, decl), |
| 336 | .plan9 => @panic("PLAN 9 DEBUG INFO"), | 336 | .plan9 => @panic("TODO: implement updateDeclLineNumber for plan9"), |
| 337 | .wasm, .spirv => {}, | 337 | .wasm, .spirv => {}, |
| 338 | } | 338 | } |
| 339 | } | 339 | } |
src/link/Plan9.zig+7-6| ... | @@ -1,10 +1,13 @@ | ... | @@ -1,10 +1,13 @@ |
| 1 | //! This implementation does all the linking work in flush(). A future improvement | ||
| 2 | //! would be to add incremental linking in a similar way as ELF does. | ||
| 3 | |||
| 1 | const Plan9 = @This(); | 4 | const Plan9 = @This(); |
| 2 | 5 | ||
| 3 | const std = @import("std"); | 6 | const std = @import("std"); |
| 4 | const link = @import("../link.zig"); | 7 | const link = @import("../link.zig"); |
| 5 | const Module = @import("../Module.zig"); | 8 | const Module = @import("../Module.zig"); |
| 6 | const Compilation = @import("../Compilation.zig"); | 9 | const Compilation = @import("../Compilation.zig"); |
| 7 | const aout = @import("plan9/a.out.zig"); | 10 | const aout = @import("Plan9/aout.zig"); |
| 8 | const codegen = @import("../codegen.zig"); | 11 | const codegen = @import("../codegen.zig"); |
| 9 | const trace = @import("../tracy.zig").trace; | 12 | const trace = @import("../tracy.zig").trace; |
| 10 | const mem = std.mem; | 13 | const mem = std.mem; |
| ... | @@ -14,8 +17,6 @@ const Allocator = std.mem.Allocator; | ... | @@ -14,8 +17,6 @@ const Allocator = std.mem.Allocator; |
| 14 | const log = std.log.scoped(.link); | 17 | const log = std.log.scoped(.link); |
| 15 | const assert = std.debug.assert; | 18 | const assert = std.debug.assert; |
| 16 | 19 | ||
| 17 | // TODO use incremental compilation | ||
| 18 | |||
| 19 | base: link.File, | 20 | base: link.File, |
| 20 | sixtyfour_bit: bool, | 21 | sixtyfour_bit: bool, |
| 21 | error_flags: File.ErrorFlags = File.ErrorFlags{}, | 22 | error_flags: File.ErrorFlags = File.ErrorFlags{}, |
| ... | @@ -38,7 +39,7 @@ const Bases = struct { | ... | @@ -38,7 +39,7 @@ const Bases = struct { |
| 38 | data: u64, | 39 | data: u64, |
| 39 | }; | 40 | }; |
| 40 | 41 | ||
| 41 | fn getAddr(self: Plan9, addr: u64, t: aout.SymType) u64 { | 42 | fn getAddr(self: Plan9, addr: u64, t: aout.Sym.Type) u64 { |
| 42 | return addr + switch (t) { | 43 | return addr + switch (t) { |
| 43 | .T, .t, .l, .L => self.bases.text, | 44 | .T, .t, .l, .L => self.bases.text, |
| 44 | .D, .d, .B, .b => self.bases.data, | 45 | .D, .d, .B, .b => self.bases.data, |
| ... | @@ -46,7 +47,7 @@ fn getAddr(self: Plan9, addr: u64, t: aout.SymType) u64 { | ... | @@ -46,7 +47,7 @@ fn getAddr(self: Plan9, addr: u64, t: aout.SymType) u64 { |
| 46 | }; | 47 | }; |
| 47 | } | 48 | } |
| 48 | /// opposite of getAddr | 49 | /// opposite of getAddr |
| 49 | fn takeAddr(self: Plan9, addr: u64, t: aout.SymType) u64 { | 50 | fn takeAddr(self: Plan9, addr: u64, t: aout.Sym.Type) u64 { |
| 50 | return addr - switch (t) { | 51 | return addr - switch (t) { |
| 51 | .T, .t, .l, .L => self.bases.text, | 52 | .T, .t, .l, .L => self.bases.text, |
| 52 | .D, .d, .B, .b => self.bases.data, | 53 | .D, .d, .B, .b => self.bases.data, |
| ... | @@ -59,7 +60,7 @@ fn getSymAddr(self: Plan9, s: aout.Sym) u64 { | ... | @@ -59,7 +60,7 @@ fn getSymAddr(self: Plan9, s: aout.Sym) u64 { |
| 59 | } | 60 | } |
| 60 | 61 | ||
| 61 | pub const DeclBlock = struct { | 62 | pub const DeclBlock = struct { |
| 62 | type: aout.SymType, | 63 | type: aout.Sym.Type, |
| 63 | /// offset in the text or data sects | 64 | /// offset in the text or data sects |
| 64 | offset: ?u64, | 65 | offset: ?u64, |
| 65 | /// offset into syms | 66 | /// offset into syms |
src/link/Plan9/aout.zig created+114| ... | @@ -0,0 +1,114 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const assert = std.debug.assert; | ||
| 3 | |||
| 4 | /// All integers are in big-endian format (needs a byteswap). | ||
| 5 | pub const ExecHdr = extern struct { | ||
| 6 | magic: u32, | ||
| 7 | text: u32, | ||
| 8 | data: u32, | ||
| 9 | bss: u32, | ||
| 10 | syms: u32, | ||
| 11 | /// You should truncate this to 32 bits on 64 bit systems, then but the actual 8 bytes | ||
| 12 | /// in the fat header. | ||
| 13 | entry: u32, | ||
| 14 | spsz: u32, | ||
| 15 | pcsz: u32, | ||
| 16 | comptime { | ||
| 17 | assert(@sizeOf(@This()) == 32); | ||
| 18 | } | ||
| 19 | /// It is up to the caller to disgard the last 8 bytes if the header is not fat. | ||
| 20 | pub fn toU8s(self: *@This()) [40]u8 { | ||
| 21 | var buf: [40]u8 = undefined; | ||
| 22 | var i: u8 = 0; | ||
| 23 | inline for (std.meta.fields(@This())) |f| { | ||
| 24 | std.mem.writeIntSliceBig(u32, buf[i .. i + 4], @field(self, f.name)); | ||
| 25 | i += 4; | ||
| 26 | } | ||
| 27 | return buf; | ||
| 28 | } | ||
| 29 | }; | ||
| 30 | |||
| 31 | pub const Sym = struct { | ||
| 32 | /// Big endian in the file | ||
| 33 | value: u64, | ||
| 34 | type: Type, | ||
| 35 | name: []const u8, | ||
| 36 | |||
| 37 | /// The type field is one of the following characters with the | ||
| 38 | /// high bit set: | ||
| 39 | /// T text segment symbol | ||
| 40 | /// t static text segment symbol | ||
| 41 | /// L leaf function text segment symbol | ||
| 42 | /// l static leaf function text segment symbol | ||
| 43 | /// D data segment symbol | ||
| 44 | /// d static data segment symbol | ||
| 45 | /// B bss segment symbol | ||
| 46 | /// b static bss segment symbol | ||
| 47 | /// a automatic (local) variable symbol | ||
| 48 | /// p function parameter symbol | ||
| 49 | /// f source file name components | ||
| 50 | /// z source file name | ||
| 51 | /// Z source file line offset | ||
| 52 | /// m for '.frame' | ||
| 53 | pub const Type = enum(u8) { | ||
| 54 | T = 0x80 | 'T', | ||
| 55 | t = 0x80 | 't', | ||
| 56 | L = 0x80 | 'L', | ||
| 57 | l = 0x80 | 'l', | ||
| 58 | D = 0x80 | 'D', | ||
| 59 | d = 0x80 | 'd', | ||
| 60 | B = 0x80 | 'B', | ||
| 61 | b = 0x80 | 'b', | ||
| 62 | a = 0x80 | 'a', | ||
| 63 | p = 0x80 | 'p', | ||
| 64 | f = 0x80 | 'f', | ||
| 65 | z = 0x80 | 'z', | ||
| 66 | Z = 0x80 | 'Z', | ||
| 67 | m = 0x80 | 'm', | ||
| 68 | |||
| 69 | pub fn toGlobal(self: Type) Type { | ||
| 70 | return switch (self) { | ||
| 71 | .t => .T, | ||
| 72 | .b => .B, | ||
| 73 | .d => .D, | ||
| 74 | else => unreachable, | ||
| 75 | }; | ||
| 76 | } | ||
| 77 | }; | ||
| 78 | }; | ||
| 79 | |||
| 80 | pub const HDR_MAGIC = 0x00008000; | ||
| 81 | pub inline fn _MAGIC(f: anytype, b: anytype) @TypeOf(f | ((((@as(c_int, 4) * b) + @as(c_int, 0)) * b) + @as(c_int, 7))) { | ||
| 82 | return f | ((((@as(c_int, 4) * b) + @as(c_int, 0)) * b) + @as(c_int, 7)); | ||
| 83 | } | ||
| 84 | pub const A_MAGIC = _MAGIC(0, 8); // 68020 | ||
| 85 | pub const I_MAGIC = _MAGIC(0, 11); // intel 386 | ||
| 86 | pub const J_MAGIC = _MAGIC(0, 12); // intel 960 (retired) | ||
| 87 | pub const K_MAGIC = _MAGIC(0, 13); // sparc | ||
| 88 | pub const V_MAGIC = _MAGIC(0, 16); // mips 3000 BE | ||
| 89 | pub const X_MAGIC = _MAGIC(0, 17); // att dsp 3210 (retired) | ||
| 90 | pub const M_MAGIC = _MAGIC(0, 18); // mips 4000 BE | ||
| 91 | pub const D_MAGIC = _MAGIC(0, 19); // amd 29000 (retired) | ||
| 92 | pub const E_MAGIC = _MAGIC(0, 20); // arm | ||
| 93 | pub const Q_MAGIC = _MAGIC(0, 21); // powerpc | ||
| 94 | pub const N_MAGIC = _MAGIC(0, 22); // mips 4000 LE | ||
| 95 | pub const L_MAGIC = _MAGIC(0, 23); // dec alpha (retired) | ||
| 96 | pub const P_MAGIC = _MAGIC(0, 24); // mips 3000 LE | ||
| 97 | pub const U_MAGIC = _MAGIC(0, 25); // sparc64 | ||
| 98 | pub const S_MAGIC = _MAGIC(HDR_MAGIC, 26); // amd64 | ||
| 99 | pub const T_MAGIC = _MAGIC(HDR_MAGIC, 27); // powerpc64 | ||
| 100 | pub const R_MAGIC = _MAGIC(HDR_MAGIC, 28); // arm64 | ||
| 101 | |||
| 102 | pub fn magicFromArch(arch: std.Target.Cpu.Arch) !u32 { | ||
| 103 | return switch (arch) { | ||
| 104 | .i386 => I_MAGIC, | ||
| 105 | .sparc => K_MAGIC, // TODO should sparcv9 and sparcel go here? | ||
| 106 | .mips => V_MAGIC, | ||
| 107 | .arm => E_MAGIC, | ||
| 108 | .aarch64 => R_MAGIC, | ||
| 109 | .powerpc => Q_MAGIC, | ||
| 110 | .powerpc64 => T_MAGIC, | ||
| 111 | .x86_64 => S_MAGIC, | ||
| 112 | else => error.ArchNotSupportedByPlan9, | ||
| 113 | }; | ||
| 114 | } | ||
src/link/plan9/a.out.zig deleted-134| ... | @@ -1,134 +0,0 @@ | ||
| 1 | // Copyright © 2021 Plan 9 Foundation | ||
| 2 | // Copyright © 20XX 9front authors | ||
| 3 | |||
| 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| 5 | // of this software and associated documentation files (the "Software"), to deal | ||
| 6 | // in the Software without restriction, including without limitation the rights | ||
| 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| 8 | // copies of the Software, and to permit persons to whom the Software is | ||
| 9 | // furnished to do so, subject to the following conditions: | ||
| 10 | |||
| 11 | // The above copyright notice and this permission notice shall be included in all | ||
| 12 | // copies or substantial portions of the Software. | ||
| 13 | |||
| 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| 20 | // SOFTWARE. | ||
| 21 | |||
| 22 | // Idomatic translation of 9front a.out.h | ||
| 23 | const std = @import("std"); | ||
| 24 | // all integers are in big-endian format (needs a byteswap) | ||
| 25 | pub const ExecHdr = extern struct { | ||
| 26 | magic: u32, | ||
| 27 | text: u32, | ||
| 28 | data: u32, | ||
| 29 | bss: u32, | ||
| 30 | syms: u32, | ||
| 31 | /// You should truncate this to 32 bits on 64 bit systems, then but the actual 8 bytes | ||
| 32 | /// in the fat header. | ||
| 33 | entry: u32, | ||
| 34 | spsz: u32, | ||
| 35 | pcsz: u32, | ||
| 36 | comptime { | ||
| 37 | std.debug.assert(@sizeOf(@This()) == 32); | ||
| 38 | } | ||
| 39 | /// it is up to the caller to disgard the last 8 bytes if the header is not fat | ||
| 40 | pub fn toU8s(self: *@This()) [40]u8 { | ||
| 41 | var buf: [40]u8 = undefined; | ||
| 42 | var i: u8 = 0; | ||
| 43 | inline for (std.meta.fields(@This())) |f| { | ||
| 44 | std.mem.writeIntSliceBig(u32, buf[i .. i + 4], @field(self, f.name)); | ||
| 45 | i += 4; | ||
| 46 | } | ||
| 47 | return buf; | ||
| 48 | } | ||
| 49 | }; | ||
| 50 | |||
| 51 | // uchar value[8]; | ||
| 52 | // char type; | ||
| 53 | // char name[n]; /* NUL-terminated */ | ||
| 54 | pub const Sym = struct { | ||
| 55 | value: u64, // big endian in the file | ||
| 56 | type: SymType, | ||
| 57 | name: []const u8, | ||
| 58 | }; | ||
| 59 | // The type field is one of the following characters with the | ||
| 60 | // high bit set: | ||
| 61 | // T text segment symbol | ||
| 62 | // t static text segment symbol | ||
| 63 | // L leaf function text segment symbol | ||
| 64 | // l static leaf function text segment symbol | ||
| 65 | // D data segment symbol | ||
| 66 | // d static data segment symbol | ||
| 67 | // B bss segment symbol | ||
| 68 | // b static bss segment symbol | ||
| 69 | // a automatic (local) variable symbol | ||
| 70 | // p function parameter symbol | ||
| 71 | // f source file name components | ||
| 72 | // z source file name | ||
| 73 | // Z source file line offset | ||
| 74 | // m for '.frame' | ||
| 75 | pub const SymType = enum(u8) { | ||
| 76 | T = 0x80 | 'T', | ||
| 77 | t = 0x80 | 't', | ||
| 78 | L = 0x80 | 'L', | ||
| 79 | l = 0x80 | 'l', | ||
| 80 | D = 0x80 | 'D', | ||
| 81 | d = 0x80 | 'd', | ||
| 82 | B = 0x80 | 'B', | ||
| 83 | b = 0x80 | 'b', | ||
| 84 | a = 0x80 | 'a', | ||
| 85 | p = 0x80 | 'p', | ||
| 86 | f = 0x80 | 'f', | ||
| 87 | z = 0x80 | 'z', | ||
| 88 | Z = 0x80 | 'Z', | ||
| 89 | m = 0x80 | 'm', | ||
| 90 | pub fn toGlobal(self: SymType) SymType { | ||
| 91 | return switch (self) { | ||
| 92 | .t => .T, | ||
| 93 | .b => .B, | ||
| 94 | .d => .D, | ||
| 95 | else => unreachable, | ||
| 96 | }; | ||
| 97 | } | ||
| 98 | }; | ||
| 99 | |||
| 100 | pub const HDR_MAGIC = 0x00008000; | ||
| 101 | pub inline fn _MAGIC(f: anytype, b: anytype) @TypeOf(f | ((((@as(c_int, 4) * b) + @as(c_int, 0)) * b) + @as(c_int, 7))) { | ||
| 102 | return f | ((((@as(c_int, 4) * b) + @as(c_int, 0)) * b) + @as(c_int, 7)); | ||
| 103 | } | ||
| 104 | pub const A_MAGIC = _MAGIC(0, 8); // 68020 | ||
| 105 | pub const I_MAGIC = _MAGIC(0, 11); // intel 386 | ||
| 106 | pub const J_MAGIC = _MAGIC(0, 12); // intel 960 (retired) | ||
| 107 | pub const K_MAGIC = _MAGIC(0, 13); // sparc | ||
| 108 | pub const V_MAGIC = _MAGIC(0, 16); // mips 3000 BE | ||
| 109 | pub const X_MAGIC = _MAGIC(0, 17); // att dsp 3210 (retired) | ||
| 110 | pub const M_MAGIC = _MAGIC(0, 18); // mips 4000 BE | ||
| 111 | pub const D_MAGIC = _MAGIC(0, 19); // amd 29000 (retired) | ||
| 112 | pub const E_MAGIC = _MAGIC(0, 20); // arm | ||
| 113 | pub const Q_MAGIC = _MAGIC(0, 21); // powerpc | ||
| 114 | pub const N_MAGIC = _MAGIC(0, 22); // mips 4000 LE | ||
| 115 | pub const L_MAGIC = _MAGIC(0, 23); // dec alpha (retired) | ||
| 116 | pub const P_MAGIC = _MAGIC(0, 24); // mips 3000 LE | ||
| 117 | pub const U_MAGIC = _MAGIC(0, 25); // sparc64 | ||
| 118 | pub const S_MAGIC = _MAGIC(HDR_MAGIC, 26); // amd64 | ||
| 119 | pub const T_MAGIC = _MAGIC(HDR_MAGIC, 27); // powerpc64 | ||
| 120 | pub const R_MAGIC = _MAGIC(HDR_MAGIC, 28); // arm64 | ||
| 121 | |||
| 122 | pub fn magicFromArch(arch: std.Target.Cpu.Arch) !u32 { | ||
| 123 | return switch (arch) { | ||
| 124 | .i386 => I_MAGIC, | ||
| 125 | .sparc => K_MAGIC, // TODO should sparcv9 and sparcel go here? | ||
| 126 | .mips => V_MAGIC, | ||
| 127 | .arm => E_MAGIC, | ||
| 128 | .aarch64 => R_MAGIC, | ||
| 129 | .powerpc => Q_MAGIC, | ||
| 130 | .powerpc64 => T_MAGIC, | ||
| 131 | .x86_64 => S_MAGIC, | ||
| 132 | else => error.ArchNotSupportedByPlan9, | ||
| 133 | }; | ||
| 134 | } | ||