mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
plan9 linker: produce an object file that can actually work!!!
This commit is contained in:
parent
3e59c15025
commit
72bb6bb143
@ -95,30 +95,43 @@ fn _start2() callconv(.Naked) noreturn {
|
||||
}
|
||||
|
||||
fn exit2(code: usize) noreturn {
|
||||
switch (builtin.stage2_arch) {
|
||||
.x86_64 => {
|
||||
asm volatile ("syscall"
|
||||
:
|
||||
: [number] "{rax}" (231),
|
||||
[arg1] "{rdi}" (code)
|
||||
: "rcx", "r11", "memory"
|
||||
);
|
||||
switch (builtin.stage2_os) {
|
||||
.linux => switch (builtin.stage2_arch) {
|
||||
.x86_64 => {
|
||||
asm volatile ("syscall"
|
||||
:
|
||||
: [number] "{rax}" (231),
|
||||
[arg1] "{rdi}" (code)
|
||||
: "rcx", "r11", "memory"
|
||||
);
|
||||
},
|
||||
.arm => {
|
||||
asm volatile ("svc #0"
|
||||
:
|
||||
: [number] "{r7}" (1),
|
||||
[arg1] "{r0}" (code)
|
||||
: "memory"
|
||||
);
|
||||
},
|
||||
.aarch64 => {
|
||||
asm volatile ("svc #0"
|
||||
:
|
||||
: [number] "{x8}" (93),
|
||||
[arg1] "{x0}" (code)
|
||||
: "memory", "cc"
|
||||
);
|
||||
},
|
||||
else => @compileError("TODO"),
|
||||
},
|
||||
.arm => {
|
||||
asm volatile ("svc #0"
|
||||
:
|
||||
: [number] "{r7}" (1),
|
||||
[arg1] "{r0}" (code)
|
||||
: "memory"
|
||||
);
|
||||
},
|
||||
.aarch64 => {
|
||||
asm volatile ("svc #0"
|
||||
:
|
||||
: [number] "{x8}" (93),
|
||||
[arg1] "{x0}" (code)
|
||||
: "memory", "cc"
|
||||
);
|
||||
.plan9 => switch (builtin.stage2_arch) {
|
||||
.x86_64 => {
|
||||
asm volatile ("syscall"
|
||||
:
|
||||
: [number] "{rbp}" (8)
|
||||
: "rcx", "r11", "memory"
|
||||
);
|
||||
},
|
||||
else => @compileError("TODO"),
|
||||
},
|
||||
else => @compileError("TODO"),
|
||||
}
|
||||
|
||||
@ -3556,6 +3556,8 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) Alloc
|
||||
\\pub const zig_is_stage2 = {};
|
||||
\\/// Temporary until self-hosted supports the `cpu.arch` value.
|
||||
\\pub const stage2_arch: std.Target.Cpu.Arch = .{};
|
||||
\\/// Temporary until self-hosted supports the `os.tag` value.
|
||||
\\pub const stage2_os: std.Target.Os.Tag = .{};
|
||||
\\
|
||||
\\pub const output_mode = std.builtin.OutputMode.{};
|
||||
\\pub const link_mode = std.builtin.LinkMode.{};
|
||||
@ -3571,6 +3573,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) Alloc
|
||||
build_options.version,
|
||||
!use_stage1,
|
||||
std.zig.fmtId(@tagName(target.cpu.arch)),
|
||||
std.zig.fmtId(@tagName(target.os.tag)),
|
||||
std.zig.fmtId(@tagName(comp.bin_file.options.output_mode)),
|
||||
std.zig.fmtId(@tagName(comp.bin_file.options.link_mode)),
|
||||
comp.bin_file.options.is_test,
|
||||
|
||||
@ -48,8 +48,8 @@ pub const DeclBlock = struct {
|
||||
};
|
||||
};
|
||||
|
||||
// TODO change base addr based on target (right now it just works on amd64)
|
||||
const default_base_addr = 0x00200000;
|
||||
// TODO change base addr based on target (and section?) (right now it just works on amd64)
|
||||
const default_base_addr = 0x00200028;
|
||||
|
||||
pub const CallReloc = struct {
|
||||
caller: *Module.Decl,
|
||||
@ -157,11 +157,13 @@ pub fn flushModule(self: *Plan9, comp: *Compilation) !void {
|
||||
return;
|
||||
},
|
||||
};
|
||||
if (is_fn)
|
||||
try self.text_buf.appendSlice(self.base.allocator, code)
|
||||
else
|
||||
if (is_fn) {
|
||||
try self.text_buf.appendSlice(self.base.allocator, code);
|
||||
try code_buffer.resize(0);
|
||||
} else {
|
||||
try self.data_buf.appendSlice(self.base.allocator, code);
|
||||
code_buffer.items.len = 0;
|
||||
try code_buffer.resize(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -176,7 +178,6 @@ pub fn flushModule(self: *Plan9, comp: *Compilation) !void {
|
||||
const off = reloc.offset_in_caller + l.offset;
|
||||
std.mem.writeInt(u32, self.text_buf.items[off - 4 ..][0..4], callee_offset, endian);
|
||||
} else {
|
||||
// what we are writing
|
||||
const callee_offset = reloc.callee.link.plan9.offset + default_base_addr; // TODO this is different if its data
|
||||
const off = reloc.offset_in_caller + l.offset;
|
||||
std.mem.writeInt(u64, self.text_buf.items[off - 8 ..][0..8], callee_offset, endian);
|
||||
@ -184,6 +185,11 @@ pub fn flushModule(self: *Plan9, comp: *Compilation) !void {
|
||||
}
|
||||
}
|
||||
|
||||
// edata, end, etext
|
||||
self.syms.items[0].value = 0x200000; // TODO make this number other place, and what is it?
|
||||
self.syms.items[1].value = 0x200000; // TODO make this number other place, and what is it?
|
||||
self.syms.items[2].value = self.text_buf.items.len;
|
||||
|
||||
var sym_buf = std.ArrayList(u8).init(self.base.allocator);
|
||||
defer sym_buf.deinit();
|
||||
try self.writeSyms(&sym_buf);
|
||||
@ -202,10 +208,14 @@ pub fn flushModule(self: *Plan9, comp: *Compilation) !void {
|
||||
|
||||
const file = self.base.file.?;
|
||||
|
||||
const hdr_buf = self.hdr.toU8s();
|
||||
var hdr_buf = self.hdr.toU8s();
|
||||
const hdr_slice: []const u8 = &hdr_buf;
|
||||
// account for the fat header
|
||||
const hdr_size: u8 = if (self.ptr_width == .p32) 32 else 40;
|
||||
// write the fat header for debug info
|
||||
if (self.ptr_width == .p64) {
|
||||
mem.writeIntSliceBig(u64, hdr_buf[32..40], self.hdr.entry);
|
||||
}
|
||||
// write it all!
|
||||
var vectors: [4]std.os.iovec_const = .{
|
||||
.{ .iov_base = hdr_slice.ptr, .iov_len = hdr_size },
|
||||
@ -290,6 +300,25 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio
|
||||
if (std.builtin.mode == .Debug or std.builtin.mode == .ReleaseSafe)
|
||||
self.hdr.entry = 0x0;
|
||||
|
||||
// first 3 symbols in our table are edata, end, etext
|
||||
try self.syms.appendSlice(self.base.allocator, &.{
|
||||
.{
|
||||
.value = 0xcafebabe,
|
||||
.type = .B,
|
||||
.name = "edata",
|
||||
},
|
||||
.{
|
||||
.value = 0xcafebabe,
|
||||
.type = .B,
|
||||
.name = "end",
|
||||
},
|
||||
.{
|
||||
.value = 0xcafebabe,
|
||||
.type = .T,
|
||||
.name = "etext",
|
||||
},
|
||||
});
|
||||
|
||||
self.base.file = file;
|
||||
return self;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user