mirror of
https://github.com/ziglang/zig.git
synced 2024-12-13 14:47:09 +00:00
plan9 linker: make runnable binaries
We can now run binaries! (they segfault, but still run!)
This commit is contained in:
parent
34c21affa2
commit
798162e509
@ -3517,7 +3517,7 @@ pub fn clearDecl(
|
||||
.coff => .{ .coff = link.File.Coff.TextBlock.empty },
|
||||
.elf => .{ .elf = link.File.Elf.TextBlock.empty },
|
||||
.macho => .{ .macho = link.File.MachO.TextBlock.empty },
|
||||
.plan9 => @panic("plan9 link"),
|
||||
.plan9 => .{ .plan9 = link.File.Plan9.DeclBlock.empty },
|
||||
.c => .{ .c = link.File.C.DeclBlock.empty },
|
||||
.wasm => .{ .wasm = link.File.Wasm.DeclBlock.empty },
|
||||
.spirv => .{ .spirv = {} },
|
||||
@ -3526,7 +3526,7 @@ pub fn clearDecl(
|
||||
.coff => .{ .coff = {} },
|
||||
.elf => .{ .elf = link.File.Elf.SrcFn.empty },
|
||||
.macho => .{ .macho = link.File.MachO.SrcFn.empty },
|
||||
.plan9 => @panic("plan9 fn_link"),
|
||||
.plan9 => .{ .plan9 = {} },
|
||||
.c => .{ .c = link.File.C.FnBlock.empty },
|
||||
.wasm => .{ .wasm = link.File.Wasm.FnData.empty },
|
||||
.spirv => .{ .spirv = .{} },
|
||||
@ -3694,7 +3694,7 @@ fn allocateNewDecl(mod: *Module, namespace: *Scope.Namespace, src_node: ast.Node
|
||||
.coff => .{ .coff = link.File.Coff.TextBlock.empty },
|
||||
.elf => .{ .elf = link.File.Elf.TextBlock.empty },
|
||||
.macho => .{ .macho = link.File.MachO.TextBlock.empty },
|
||||
.plan9 => @panic("PLan9 export"),
|
||||
.plan9 => .{ .plan9 = link.File.Plan9.DeclBlock.empty },
|
||||
.c => .{ .c = link.File.C.DeclBlock.empty },
|
||||
.wasm => .{ .wasm = link.File.Wasm.DeclBlock.empty },
|
||||
.spirv => .{ .spirv = {} },
|
||||
@ -3703,7 +3703,7 @@ fn allocateNewDecl(mod: *Module, namespace: *Scope.Namespace, src_node: ast.Node
|
||||
.coff => .{ .coff = {} },
|
||||
.elf => .{ .elf = link.File.Elf.SrcFn.empty },
|
||||
.macho => .{ .macho = link.File.MachO.SrcFn.empty },
|
||||
.plan9 => .{ .plan9 = link.File.Plan9.SrcFn.empty },
|
||||
.plan9 => .{ .plan9 = {} },
|
||||
.c => .{ .c = link.File.C.FnBlock.empty },
|
||||
.wasm => .{ .wasm = link.File.Wasm.FnData.empty },
|
||||
.spirv => .{ .spirv = .{} },
|
||||
@ -3773,7 +3773,7 @@ pub fn analyzeExport(
|
||||
.coff => .{ .coff = {} },
|
||||
.elf => .{ .elf = link.File.Elf.Export{} },
|
||||
.macho => .{ .macho = link.File.MachO.Export{} },
|
||||
.plan9 => @panic("plan9 link"),
|
||||
.plan9 => .{ .plan9 = null },
|
||||
.c => .{ .c = {} },
|
||||
.wasm => .{ .wasm = {} },
|
||||
.spirv => .{ .spirv = {} },
|
||||
|
@ -2556,9 +2556,19 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
|
||||
} else {
|
||||
return self.fail(inst.base.src, "TODO implement calling runtime known function pointer", .{});
|
||||
}
|
||||
} else {
|
||||
unreachable;
|
||||
}
|
||||
} else if (self.bin_file.cast(link.File.Plan9)) |p9| {
|
||||
if (inst.func.value()) |func_value| {
|
||||
if (func_value.castTag(.function)) |func_payload| {
|
||||
try p9.addCallReloc(self.code, .{
|
||||
.caller = p9.cur_decl,
|
||||
.callee = func_payload.data.owner_decl,
|
||||
.offset_in_caller = self.code.items.len,
|
||||
});
|
||||
} else return self.fail(inst.base.src, "TODO implement calling extern fn on plan9", .{});
|
||||
} else {
|
||||
return self.fail(inst.base.src, "TODO implement calling runtime known function pointer", .{});
|
||||
}
|
||||
} else unreachable;
|
||||
|
||||
switch (info.return_value) {
|
||||
.register => |reg| {
|
||||
|
@ -141,6 +141,7 @@ pub const File = struct {
|
||||
elf: Elf.TextBlock,
|
||||
coff: Coff.TextBlock,
|
||||
macho: MachO.TextBlock,
|
||||
plan9: Plan9.DeclBlock,
|
||||
c: C.DeclBlock,
|
||||
wasm: Wasm.DeclBlock,
|
||||
spirv: void,
|
||||
@ -150,7 +151,7 @@ pub const File = struct {
|
||||
elf: Elf.SrcFn,
|
||||
coff: Coff.SrcFn,
|
||||
macho: MachO.SrcFn,
|
||||
plan9: Plan9.SrcFn,
|
||||
plan9: void,
|
||||
c: C.FnBlock,
|
||||
wasm: Wasm.FnData,
|
||||
spirv: SpirV.FnData,
|
||||
@ -207,12 +208,12 @@ pub const File = struct {
|
||||
.coff, .pe => &(try Coff.createEmpty(allocator, options)).base,
|
||||
.elf => &(try Elf.createEmpty(allocator, options)).base,
|
||||
.macho => &(try MachO.createEmpty(allocator, options)).base,
|
||||
.plan9 => &(try Plan9.createEmpty(allocator, options)).base,
|
||||
.wasm => &(try Wasm.createEmpty(allocator, options)).base,
|
||||
.c => unreachable, // Reported error earlier.
|
||||
.spirv => &(try SpirV.createEmpty(allocator, options)).base,
|
||||
.hex => return error.HexObjectFormatUnimplemented,
|
||||
.raw => return error.RawObjectFormatUnimplemented,
|
||||
.plan9 => return error.Plan9ObjectFormatUnimplemented,
|
||||
};
|
||||
}
|
||||
// Open a temporary object file, not the final output file because we want to link with LLD.
|
||||
@ -224,12 +225,12 @@ pub const File = struct {
|
||||
.coff, .pe => &(try Coff.openPath(allocator, sub_path, options)).base,
|
||||
.elf => &(try Elf.openPath(allocator, sub_path, options)).base,
|
||||
.macho => &(try MachO.openPath(allocator, sub_path, options)).base,
|
||||
.plan9 => &(try Plan9.openPath(allocator, sub_path, options)).base,
|
||||
.wasm => &(try Wasm.openPath(allocator, sub_path, options)).base,
|
||||
.c => &(try C.openPath(allocator, sub_path, options)).base,
|
||||
.spirv => &(try SpirV.openPath(allocator, sub_path, options)).base,
|
||||
.hex => return error.HexObjectFormatUnimplemented,
|
||||
.raw => return error.RawObjectFormatUnimplemented,
|
||||
.plan9 => return error.Plan9ObjectFormatUnimplemented,
|
||||
};
|
||||
|
||||
if (use_lld) {
|
||||
@ -347,7 +348,7 @@ pub const File = struct {
|
||||
.macho => return @fieldParentPtr(MachO, "base", base).allocateDeclIndexes(decl),
|
||||
.c => return @fieldParentPtr(C, "base", base).allocateDeclIndexes(decl),
|
||||
.wasm => return @fieldParentPtr(Wasm, "base", base).allocateDeclIndexes(decl),
|
||||
.plan9 => return @fieldParentPtr(Plan9, "base", base).allocateDeclIndexes(decl),
|
||||
.plan9 => {},
|
||||
.spirv => {},
|
||||
}
|
||||
}
|
||||
|
@ -4,35 +4,66 @@ 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 codegen = @import("../codegen.zig");
|
||||
const trace = @import("../tracy.zig").trace;
|
||||
const mem = std.mem;
|
||||
const File = link.File;
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
const log = std.log.scoped(.link);
|
||||
const assert = std.debug.assert;
|
||||
|
||||
// TODO use incremental compilation
|
||||
|
||||
base: link.File,
|
||||
ptr_width: PtrWidth,
|
||||
error_flags: File.ErrorFlags = File.ErrorFlags{},
|
||||
|
||||
pub const SrcFn = struct {
|
||||
/// Offset from the beginning of the Debug Line Program header that contains this function.
|
||||
off: u32,
|
||||
/// Size of the line number program component belonging to this function, not
|
||||
/// including padding.
|
||||
len: u32,
|
||||
decl_table: std.AutoArrayHashMapUnmanaged(*Module.Decl, void) = .{},
|
||||
/// is just casted down when 32 bit
|
||||
syms: std.ArrayListUnmanaged(aout.Sym64) = .{},
|
||||
call_relocs: std.ArrayListUnmanaged(CallReloc) = .{},
|
||||
text_buf: std.ArrayListUnmanaged(u8) = .{},
|
||||
data_buf: std.ArrayListUnmanaged(u8) = .{},
|
||||
|
||||
/// Points to the previous and next neighbors, based on the offset from .debug_line.
|
||||
/// This can be used to find, for example, the capacity of this `SrcFn`.
|
||||
prev: ?*SrcFn,
|
||||
next: ?*SrcFn,
|
||||
cur_decl: *Module.Decl = undefined,
|
||||
hdr: aout.ExecHdr = undefined,
|
||||
|
||||
pub const empty: SrcFn = .{
|
||||
.off = 0,
|
||||
.len = 0,
|
||||
.prev = null,
|
||||
.next = null,
|
||||
fn headerSize(self: Plan9) u32 {
|
||||
// fat header (currently unused)
|
||||
const fat: u4 = if (self.ptr_width == .p64) 8 else 0;
|
||||
return aout.ExecHdr.size() + fat;
|
||||
}
|
||||
pub const DeclBlock = struct {
|
||||
type: enum { text, data },
|
||||
// offset in the text or data sects
|
||||
offset: u32,
|
||||
pub const empty = DeclBlock{
|
||||
.type = .text,
|
||||
.offset = 0,
|
||||
};
|
||||
};
|
||||
|
||||
// TODO change base addr based on target (right now it just works on amd64)
|
||||
const default_base_addr = 0x00200000;
|
||||
|
||||
pub const CallReloc = struct {
|
||||
caller: *Module.Decl,
|
||||
callee: *Module.Decl,
|
||||
offset_in_caller: usize,
|
||||
};
|
||||
|
||||
pub const PtrWidth = enum { p32, p64 };
|
||||
|
||||
pub fn createEmpty(gpa: *Allocator, options: link.Options) !*Plan9 {
|
||||
if (options.use_llvm)
|
||||
return error.LLVMBackendDoesNotSupportPlan9;
|
||||
const ptr_width: PtrWidth = switch (options.target.cpu.arch.ptrBitWidth()) {
|
||||
0...32 => .p32,
|
||||
33...64 => .p64,
|
||||
else => return error.UnsupportedELFArchitecture,
|
||||
};
|
||||
const self = try gpa.create(Plan9);
|
||||
self.* = .{
|
||||
.base = .{
|
||||
@ -41,25 +72,157 @@ pub fn createEmpty(gpa: *Allocator, options: link.Options) !*Plan9 {
|
||||
.allocator = gpa,
|
||||
.file = null,
|
||||
},
|
||||
.ptr_width = ptr_width,
|
||||
};
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn updateDecl(self: *Plan9, module: *Module, decl: *Module.Decl) !void {}
|
||||
pub fn updateDecl(self: *Plan9, module: *Module, decl: *Module.Decl) !void {
|
||||
_ = try self.decl_table.getOrPut(self.base.allocator, decl);
|
||||
}
|
||||
|
||||
pub fn allocateDeclIndexes(self: *Plan9, decl: *Module.Decl) !void {}
|
||||
pub fn flush(self: *Plan9, comp: *Compilation) !void {
|
||||
assert(!self.base.options.use_lld);
|
||||
|
||||
switch (self.base.options.effectiveOutputMode()) {
|
||||
.Exe => {},
|
||||
// plan9 object files are totally different
|
||||
.Obj => return error.TODOImplementPlan9Objs,
|
||||
.Lib => return error.TODOImplementWritingLibFiles,
|
||||
}
|
||||
return self.flushModule(comp);
|
||||
}
|
||||
pub fn flushModule(self: *Plan9, comp: *Compilation) !void {
|
||||
const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented;
|
||||
|
||||
// generate the header
|
||||
self.hdr.magic = try aout.magicFromArch(self.base.options.target.cpu.arch);
|
||||
const file = self.base.file.?;
|
||||
try file.seekTo(self.headerSize());
|
||||
|
||||
// temporary buffer
|
||||
var code_buffer = std.ArrayList(u8).init(self.base.allocator);
|
||||
defer code_buffer.deinit();
|
||||
{
|
||||
for (self.decl_table.keys()) |decl| {
|
||||
if (!decl.has_tv) continue;
|
||||
self.cur_decl = decl;
|
||||
const is_fn = (decl.ty.zigTypeTag() == .Fn);
|
||||
decl.link.plan9 = if (is_fn) .{
|
||||
.offset = @intCast(u32, self.text_buf.items.len),
|
||||
.type = .text,
|
||||
} else .{
|
||||
.offset = @intCast(u32, self.data_buf.items.len),
|
||||
.type = .data,
|
||||
};
|
||||
const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), .{
|
||||
.ty = decl.ty,
|
||||
.val = decl.val,
|
||||
}, &code_buffer, .{ .none = {} });
|
||||
const code = switch (res) {
|
||||
.externally_managed => |x| x,
|
||||
.appended => code_buffer.items,
|
||||
.fail => |em| {
|
||||
decl.analysis = .codegen_failure;
|
||||
try module.failed_decls.put(module.gpa, decl, em);
|
||||
// TODO try to do more decls
|
||||
return;
|
||||
},
|
||||
};
|
||||
if (is_fn)
|
||||
try self.text_buf.appendSlice(self.base.allocator, code)
|
||||
else
|
||||
try self.data_buf.appendSlice(self.base.allocator, code);
|
||||
code_buffer.items.len = 0;
|
||||
}
|
||||
}
|
||||
try file.writeAll(self.text_buf.items);
|
||||
try file.writeAll(self.data_buf.items);
|
||||
try file.seekTo(0);
|
||||
self.hdr.text = @intCast(u32, self.text_buf.items.len);
|
||||
self.hdr.data = @intCast(u32, self.data_buf.items.len);
|
||||
self.hdr.pcsz = 0;
|
||||
self.hdr.spsz = 0;
|
||||
inline for (std.meta.fields(aout.ExecHdr)) |f| {
|
||||
try file.writer().writeIntBig(f.field_type, @field(self.hdr, f.name));
|
||||
}
|
||||
}
|
||||
pub fn freeDecl(self: *Plan9, decl: *Module.Decl) void {
|
||||
assert(self.decl_table.swapRemove(decl));
|
||||
}
|
||||
|
||||
pub fn flush(self: *Plan9, comp: *Compilation) !void {}
|
||||
pub fn flushModule(self: *Plan9, comp: *Compilation) !void {}
|
||||
pub fn freeDecl(self: *Plan9, decl: *Module.Decl) void {}
|
||||
pub fn updateDeclExports(
|
||||
self: *Plan9,
|
||||
module: *Module,
|
||||
decl: *Module.Decl,
|
||||
exports: []const *Module.Export,
|
||||
) !void {}
|
||||
pub fn deinit(self: *Plan9) void {}
|
||||
) !void {
|
||||
for (exports) |exp| {
|
||||
if (exp.options.section) |section_name| {
|
||||
if (!mem.eql(u8, section_name, ".text")) {
|
||||
try module.failed_exports.ensureCapacity(module.gpa, module.failed_exports.count() + 1);
|
||||
module.failed_exports.putAssumeCapacityNoClobber(
|
||||
exp,
|
||||
try Module.ErrorMsg.create(self.base.allocator, decl.srcLoc(), "plan9 does not support extra sections", .{}),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (std.mem.eql(u8, exp.options.name, "_start")) {
|
||||
std.debug.assert(decl.link.plan9.type == .text); // we tried to link a non-function as _start
|
||||
self.hdr.entry = Plan9.default_base_addr + self.headerSize() + decl.link.plan9.offset;
|
||||
}
|
||||
if (exp.link.plan9) |i| {
|
||||
const sym = &self.syms.items[i];
|
||||
sym.* = .{
|
||||
.value = decl.link.plan9.offset,
|
||||
.type = switch (decl.link.plan9.type) {
|
||||
.text => .T,
|
||||
.data => .D,
|
||||
},
|
||||
.name = decl.name,
|
||||
};
|
||||
} else {
|
||||
try self.syms.append(self.base.allocator, .{
|
||||
.value = decl.link.plan9.offset,
|
||||
.type = switch (decl.link.plan9.type) {
|
||||
.text => .T,
|
||||
.data => .D,
|
||||
},
|
||||
.name = decl.name,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn deinit(self: *Plan9) void {
|
||||
self.decl_table.deinit(self.base.allocator);
|
||||
self.call_relocs.deinit(self.base.allocator);
|
||||
self.syms.deinit(self.base.allocator);
|
||||
self.text_buf.deinit(self.base.allocator);
|
||||
self.data_buf.deinit(self.base.allocator);
|
||||
}
|
||||
|
||||
pub const Export = struct {
|
||||
sym_index: ?u32 = null,
|
||||
};
|
||||
pub const Export = ?usize;
|
||||
pub const base_tag = .plan9;
|
||||
pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Options) !*Plan9 {
|
||||
if (options.use_llvm)
|
||||
return error.LLVMBackendDoesNotSupportPlan9;
|
||||
assert(options.object_format == .plan9);
|
||||
const file = try options.emit.?.directory.handle.createFile(sub_path, .{
|
||||
.truncate = false,
|
||||
.read = true,
|
||||
.mode = link.determineMode(options),
|
||||
});
|
||||
errdefer file.close();
|
||||
|
||||
const self = try createEmpty(allocator, options);
|
||||
errdefer self.base.destroy();
|
||||
|
||||
self.base.file = file;
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn addCallReloc(self: *Plan9, code: *std.ArrayList(u8), reloc: CallReloc) !void {
|
||||
try self.call_relocs.append(self.base.allocator, reloc);
|
||||
try code.writer().writeIntBig(u64, 0xdeadbeef);
|
||||
}
|
||||
|
122
src/link/plan9/a.out.zig
Normal file
122
src/link/plan9/a.out.zig
Normal file
@ -0,0 +1,122 @@
|
||||
// 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 = struct {
|
||||
magic: u32,
|
||||
text: u32,
|
||||
data: u32,
|
||||
bss: u32,
|
||||
syms: u32,
|
||||
entry: u32,
|
||||
spsz: u32,
|
||||
pcsz: u32,
|
||||
pub fn size() u8 {
|
||||
return 32;
|
||||
}
|
||||
};
|
||||
|
||||
// uchar value[4];
|
||||
// char type;
|
||||
// char name[n]; /* NUL-terminated */
|
||||
pub const Sym32 = struct {
|
||||
value: u32, // big endian in the file
|
||||
type: SymType,
|
||||
name: [*:0]const u8,
|
||||
};
|
||||
// uchar value[8];
|
||||
// char type;
|
||||
// char name[n]; /* NUL-terminated */
|
||||
pub const Sym64 = struct {
|
||||
value: u64, // big endian in the file
|
||||
type: SymType,
|
||||
name: [*:0]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 const HDR_MAGIC = @import("std").meta.promoteIntLiteral(c_int, 0x00008000, .hexadecimal);
|
||||
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(@as(c_int, 0), @as(c_int, 8)); // 68020
|
||||
pub const I_MAGIC = _MAGIC(@as(c_int, 0), @as(c_int, 11)); // intel 386
|
||||
pub const J_MAGIC = _MAGIC(@as(c_int, 0), @as(c_int, 12)); // intel 960 (retired)
|
||||
pub const K_MAGIC = _MAGIC(@as(c_int, 0), @as(c_int, 13)); // sparc
|
||||
pub const V_MAGIC = _MAGIC(@as(c_int, 0), @as(c_int, 16)); // mips 3000 BE
|
||||
pub const X_MAGIC = _MAGIC(@as(c_int, 0), @as(c_int, 17)); // att dsp 3210 (retired)
|
||||
pub const M_MAGIC = _MAGIC(@as(c_int, 0), @as(c_int, 18)); // mips 4000 BE
|
||||
pub const D_MAGIC = _MAGIC(@as(c_int, 0), @as(c_int, 19)); // amd 29000 (retired)
|
||||
pub const E_MAGIC = _MAGIC(@as(c_int, 0), @as(c_int, 20)); // arm
|
||||
pub const Q_MAGIC = _MAGIC(@as(c_int, 0), @as(c_int, 21)); // powerpc
|
||||
pub const N_MAGIC = _MAGIC(@as(c_int, 0), @as(c_int, 22)); // mips 4000 LE
|
||||
pub const L_MAGIC = _MAGIC(@as(c_int, 0), @as(c_int, 23)); // dec alpha (retired)
|
||||
pub const P_MAGIC = _MAGIC(@as(c_int, 0), @as(c_int, 24)); // mips 3000 LE
|
||||
pub const U_MAGIC = _MAGIC(@as(c_int, 0), @as(c_int, 25)); // sparc64
|
||||
pub const S_MAGIC = _MAGIC(HDR_MAGIC, @as(c_int, 26)); // amd64
|
||||
pub const T_MAGIC = _MAGIC(HDR_MAGIC, @as(c_int, 27)); // powerpc64
|
||||
pub const R_MAGIC = _MAGIC(HDR_MAGIC, @as(c_int, 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,
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user