authorgravatar for jacoblevgw@gmail.comJacob G-W <jacoblevgw@gmail.com> 2021-06-12 16:51:51-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-08 14:10:49-07:00
log72bb6bb1430f0b3b32f0cb5e52054293a59abca6
tree2a9fd4c878ef85491f09ae5290d75e2fe76c2197
parent3e59c1502556493b29171c2d22447dd70670ca02

plan9 linker: produce an object file that can actually work!!!


3 files changed, 76 insertions(+), 31 deletions(-)

lib/std/start.zig+36-23
...@@ -95,30 +95,43 @@ fn _start2() callconv(.Naked) noreturn {...@@ -95,30 +95,43 @@ fn _start2() callconv(.Naked) noreturn {
95}95}
9696
97fn exit2(code: usize) noreturn {97fn exit2(code: usize) noreturn {
98 switch (builtin.stage2_arch) {98 switch (builtin.stage2_os) {
99 .x86_64 => {99 .linux => switch (builtin.stage2_arch) {
100 asm volatile ("syscall"100 .x86_64 => {
101 :101 asm volatile ("syscall"
102 : [number] "{rax}" (231),102 :
103 [arg1] "{rdi}" (code)103 : [number] "{rax}" (231),
104 : "rcx", "r11", "memory"104 [arg1] "{rdi}" (code)
105 );105 : "rcx", "r11", "memory"
106 },106 );
107 .arm => {107 },
108 asm volatile ("svc #0"108 .arm => {
109 :109 asm volatile ("svc #0"
110 : [number] "{r7}" (1),110 :
111 [arg1] "{r0}" (code)111 : [number] "{r7}" (1),
112 : "memory"112 [arg1] "{r0}" (code)
113 );113 : "memory"
114 );
115 },
116 .aarch64 => {
117 asm volatile ("svc #0"
118 :
119 : [number] "{x8}" (93),
120 [arg1] "{x0}" (code)
121 : "memory", "cc"
122 );
123 },
124 else => @compileError("TODO"),
114 },125 },
115 .aarch64 => {126 .plan9 => switch (builtin.stage2_arch) {
116 asm volatile ("svc #0"127 .x86_64 => {
117 :128 asm volatile ("syscall"
118 : [number] "{x8}" (93),129 :
119 [arg1] "{x0}" (code)130 : [number] "{rbp}" (8)
120 : "memory", "cc"131 : "rcx", "r11", "memory"
121 );132 );
133 },
134 else => @compileError("TODO"),
122 },135 },
123 else => @compileError("TODO"),136 else => @compileError("TODO"),
124 }137 }
src/Compilation.zig+3
...@@ -3556,6 +3556,8 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) Alloc...@@ -3556,6 +3556,8 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) Alloc
3556 \\pub const zig_is_stage2 = {};3556 \\pub const zig_is_stage2 = {};
3557 \\/// Temporary until self-hosted supports the `cpu.arch` value.3557 \\/// Temporary until self-hosted supports the `cpu.arch` value.
3558 \\pub const stage2_arch: std.Target.Cpu.Arch = .{};3558 \\pub const stage2_arch: std.Target.Cpu.Arch = .{};
3559 \\/// Temporary until self-hosted supports the `os.tag` value.
3560 \\pub const stage2_os: std.Target.Os.Tag = .{};
3559 \\3561 \\
3560 \\pub const output_mode = std.builtin.OutputMode.{};3562 \\pub const output_mode = std.builtin.OutputMode.{};
3561 \\pub const link_mode = std.builtin.LinkMode.{};3563 \\pub const link_mode = std.builtin.LinkMode.{};
...@@ -3571,6 +3573,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) Alloc...@@ -3571,6 +3573,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) Alloc
3571 build_options.version,3573 build_options.version,
3572 !use_stage1,3574 !use_stage1,
3573 std.zig.fmtId(@tagName(target.cpu.arch)),3575 std.zig.fmtId(@tagName(target.cpu.arch)),
3576 std.zig.fmtId(@tagName(target.os.tag)),
3574 std.zig.fmtId(@tagName(comp.bin_file.options.output_mode)),3577 std.zig.fmtId(@tagName(comp.bin_file.options.output_mode)),
3575 std.zig.fmtId(@tagName(comp.bin_file.options.link_mode)),3578 std.zig.fmtId(@tagName(comp.bin_file.options.link_mode)),
3576 comp.bin_file.options.is_test,3579 comp.bin_file.options.is_test,
src/link/Plan9.zig+37-8
...@@ -48,8 +48,8 @@ pub const DeclBlock = struct {...@@ -48,8 +48,8 @@ pub const DeclBlock = struct {
48 };48 };
49};49};
5050
51// TODO change base addr based on target (right now it just works on amd64)51// TODO change base addr based on target (and section?) (right now it just works on amd64)
52const default_base_addr = 0x00200000;52const default_base_addr = 0x00200028;
5353
54pub const CallReloc = struct {54pub const CallReloc = struct {
55 caller: *Module.Decl,55 caller: *Module.Decl,
...@@ -157,11 +157,13 @@ pub fn flushModule(self: *Plan9, comp: *Compilation) !void {...@@ -157,11 +157,13 @@ pub fn flushModule(self: *Plan9, comp: *Compilation) !void {
157 return;157 return;
158 },158 },
159 };159 };
160 if (is_fn)160 if (is_fn) {
161 try self.text_buf.appendSlice(self.base.allocator, code)161 try self.text_buf.appendSlice(self.base.allocator, code);
162 else162 try code_buffer.resize(0);
163 } else {
163 try self.data_buf.appendSlice(self.base.allocator, code);164 try self.data_buf.appendSlice(self.base.allocator, code);
164 code_buffer.items.len = 0;165 try code_buffer.resize(0);
166 }
165 }167 }
166 }168 }
167169
...@@ -176,7 +178,6 @@ pub fn flushModule(self: *Plan9, comp: *Compilation) !void {...@@ -176,7 +178,6 @@ pub fn flushModule(self: *Plan9, comp: *Compilation) !void {
176 const off = reloc.offset_in_caller + l.offset;178 const off = reloc.offset_in_caller + l.offset;
177 std.mem.writeInt(u32, self.text_buf.items[off - 4 ..][0..4], callee_offset, endian);179 std.mem.writeInt(u32, self.text_buf.items[off - 4 ..][0..4], callee_offset, endian);
178 } else {180 } else {
179 // what we are writing
180 const callee_offset = reloc.callee.link.plan9.offset + default_base_addr; // TODO this is different if its data181 const callee_offset = reloc.callee.link.plan9.offset + default_base_addr; // TODO this is different if its data
181 const off = reloc.offset_in_caller + l.offset;182 const off = reloc.offset_in_caller + l.offset;
182 std.mem.writeInt(u64, self.text_buf.items[off - 8 ..][0..8], callee_offset, endian);183 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 {...@@ -184,6 +185,11 @@ pub fn flushModule(self: *Plan9, comp: *Compilation) !void {
184 }185 }
185 }186 }
186187
188 // edata, end, etext
189 self.syms.items[0].value = 0x200000; // TODO make this number other place, and what is it?
190 self.syms.items[1].value = 0x200000; // TODO make this number other place, and what is it?
191 self.syms.items[2].value = self.text_buf.items.len;
192
187 var sym_buf = std.ArrayList(u8).init(self.base.allocator);193 var sym_buf = std.ArrayList(u8).init(self.base.allocator);
188 defer sym_buf.deinit();194 defer sym_buf.deinit();
189 try self.writeSyms(&sym_buf);195 try self.writeSyms(&sym_buf);
...@@ -202,10 +208,14 @@ pub fn flushModule(self: *Plan9, comp: *Compilation) !void {...@@ -202,10 +208,14 @@ pub fn flushModule(self: *Plan9, comp: *Compilation) !void {
202208
203 const file = self.base.file.?;209 const file = self.base.file.?;
204210
205 const hdr_buf = self.hdr.toU8s();211 var hdr_buf = self.hdr.toU8s();
206 const hdr_slice: []const u8 = &hdr_buf;212 const hdr_slice: []const u8 = &hdr_buf;
207 // account for the fat header213 // account for the fat header
208 const hdr_size: u8 = if (self.ptr_width == .p32) 32 else 40;214 const hdr_size: u8 = if (self.ptr_width == .p32) 32 else 40;
215 // write the fat header for debug info
216 if (self.ptr_width == .p64) {
217 mem.writeIntSliceBig(u64, hdr_buf[32..40], self.hdr.entry);
218 }
209 // write it all!219 // write it all!
210 var vectors: [4]std.os.iovec_const = .{220 var vectors: [4]std.os.iovec_const = .{
211 .{ .iov_base = hdr_slice.ptr, .iov_len = hdr_size },221 .{ .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...@@ -290,6 +300,25 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio
290 if (std.builtin.mode == .Debug or std.builtin.mode == .ReleaseSafe)300 if (std.builtin.mode == .Debug or std.builtin.mode == .ReleaseSafe)
291 self.hdr.entry = 0x0;301 self.hdr.entry = 0x0;
292302
303 // first 3 symbols in our table are edata, end, etext
304 try self.syms.appendSlice(self.base.allocator, &.{
305 .{
306 .value = 0xcafebabe,
307 .type = .B,
308 .name = "edata",
309 },
310 .{
311 .value = 0xcafebabe,
312 .type = .B,
313 .name = "end",
314 },
315 .{
316 .value = 0xcafebabe,
317 .type = .T,
318 .name = "etext",
319 },
320 });
321
293 self.base.file = file;322 self.base.file = file;
294 return self;323 return self;
295}324}