| author | |
| committer | |
| log | 72bb6bb1430f0b3b32f0cb5e52054293a59abca6 |
| tree | 2a9fd4c878ef85491f09ae5290d75e2fe76c2197 |
| parent | 3e59c1502556493b29171c2d22447dd70670ca02 |
3 files changed, 76 insertions(+), 31 deletions(-)
lib/std/start.zig+36-23| ... | ... | @@ -95,30 +95,43 @@ fn _start2() callconv(.Naked) noreturn { |
| 95 | 95 | } |
| 96 | 96 | |
| 97 | 97 | fn exit2(code: usize) noreturn { |
| 98 | switch (builtin.stage2_arch) { | |
| 99 | .x86_64 => { | |
| 100 | asm volatile ("syscall" | |
| 101 | : | |
| 102 | : [number] "{rax}" (231), | |
| 103 | [arg1] "{rdi}" (code) | |
| 104 | : "rcx", "r11", "memory" | |
| 105 | ); | |
| 106 | }, | |
| 107 | .arm => { | |
| 108 | asm volatile ("svc #0" | |
| 109 | : | |
| 110 | : [number] "{r7}" (1), | |
| 111 | [arg1] "{r0}" (code) | |
| 112 | : "memory" | |
| 113 | ); | |
| 98 | switch (builtin.stage2_os) { | |
| 99 | .linux => switch (builtin.stage2_arch) { | |
| 100 | .x86_64 => { | |
| 101 | asm volatile ("syscall" | |
| 102 | : | |
| 103 | : [number] "{rax}" (231), | |
| 104 | [arg1] "{rdi}" (code) | |
| 105 | : "rcx", "r11", "memory" | |
| 106 | ); | |
| 107 | }, | |
| 108 | .arm => { | |
| 109 | asm volatile ("svc #0" | |
| 110 | : | |
| 111 | : [number] "{r7}" (1), | |
| 112 | [arg1] "{r0}" (code) | |
| 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 => { | |
| 116 | asm volatile ("svc #0" | |
| 117 | : | |
| 118 | : [number] "{x8}" (93), | |
| 119 | [arg1] "{x0}" (code) | |
| 120 | : "memory", "cc" | |
| 121 | ); | |
| 126 | .plan9 => switch (builtin.stage2_arch) { | |
| 127 | .x86_64 => { | |
| 128 | asm volatile ("syscall" | |
| 129 | : | |
| 130 | : [number] "{rbp}" (8) | |
| 131 | : "rcx", "r11", "memory" | |
| 132 | ); | |
| 133 | }, | |
| 134 | else => @compileError("TODO"), | |
| 122 | 135 | }, |
| 123 | 136 | else => @compileError("TODO"), |
| 124 | 137 | } |
src/Compilation.zig+3| ... | ... | @@ -3556,6 +3556,8 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) Alloc |
| 3556 | 3556 | \\pub const zig_is_stage2 = {}; |
| 3557 | 3557 | \\/// Temporary until self-hosted supports the `cpu.arch` value. |
| 3558 | 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 | 3562 | \\pub const output_mode = std.builtin.OutputMode.{}; |
| 3561 | 3563 | \\pub const link_mode = std.builtin.LinkMode.{}; |
| ... | ... | @@ -3571,6 +3573,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) Alloc |
| 3571 | 3573 | build_options.version, |
| 3572 | 3574 | !use_stage1, |
| 3573 | 3575 | std.zig.fmtId(@tagName(target.cpu.arch)), |
| 3576 | std.zig.fmtId(@tagName(target.os.tag)), | |
| 3574 | 3577 | std.zig.fmtId(@tagName(comp.bin_file.options.output_mode)), |
| 3575 | 3578 | std.zig.fmtId(@tagName(comp.bin_file.options.link_mode)), |
| 3576 | 3579 | comp.bin_file.options.is_test, |
src/link/Plan9.zig+37-8| ... | ... | @@ -48,8 +48,8 @@ pub const DeclBlock = struct { |
| 48 | 48 | }; |
| 49 | 49 | }; |
| 50 | 50 | |
| 51 | // TODO change base addr based on target (right now it just works on amd64) | |
| 52 | const default_base_addr = 0x00200000; | |
| 51 | // TODO change base addr based on target (and section?) (right now it just works on amd64) | |
| 52 | const default_base_addr = 0x00200028; | |
| 53 | 53 | |
| 54 | 54 | pub const CallReloc = struct { |
| 55 | 55 | caller: *Module.Decl, |
| ... | ... | @@ -157,11 +157,13 @@ pub fn flushModule(self: *Plan9, comp: *Compilation) !void { |
| 157 | 157 | return; |
| 158 | 158 | }, |
| 159 | 159 | }; |
| 160 | if (is_fn) | |
| 161 | try self.text_buf.appendSlice(self.base.allocator, code) | |
| 162 | else | |
| 160 | if (is_fn) { | |
| 161 | try self.text_buf.appendSlice(self.base.allocator, code); | |
| 162 | try code_buffer.resize(0); | |
| 163 | } else { | |
| 163 | 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 | } |
| 167 | 169 | |
| ... | ... | @@ -176,7 +178,6 @@ pub fn flushModule(self: *Plan9, comp: *Compilation) !void { |
| 176 | 178 | const off = reloc.offset_in_caller + l.offset; |
| 177 | 179 | std.mem.writeInt(u32, self.text_buf.items[off - 4 ..][0..4], callee_offset, endian); |
| 178 | 180 | } else { |
| 179 | // what we are writing | |
| 180 | 181 | const callee_offset = reloc.callee.link.plan9.offset + default_base_addr; // TODO this is different if its data |
| 181 | 182 | const off = reloc.offset_in_caller + l.offset; |
| 182 | 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 | 185 | } |
| 185 | 186 | } |
| 186 | 187 | |
| 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 | 193 | var sym_buf = std.ArrayList(u8).init(self.base.allocator); |
| 188 | 194 | defer sym_buf.deinit(); |
| 189 | 195 | try self.writeSyms(&sym_buf); |
| ... | ... | @@ -202,10 +208,14 @@ pub fn flushModule(self: *Plan9, comp: *Compilation) !void { |
| 202 | 208 | |
| 203 | 209 | const file = self.base.file.?; |
| 204 | 210 | |
| 205 | const hdr_buf = self.hdr.toU8s(); | |
| 211 | var hdr_buf = self.hdr.toU8s(); | |
| 206 | 212 | const hdr_slice: []const u8 = &hdr_buf; |
| 207 | 213 | // account for the fat header |
| 208 | 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 | 219 | // write it all! |
| 210 | 220 | var vectors: [4]std.os.iovec_const = .{ |
| 211 | 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 | 300 | if (std.builtin.mode == .Debug or std.builtin.mode == .ReleaseSafe) |
| 291 | 301 | self.hdr.entry = 0x0; |
| 292 | 302 | |
| 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 | 322 | self.base.file = file; |
| 294 | 323 | return self; |
| 295 | 324 | } |