aboutsummaryrefslogtreecommitdiff
path: root/src/link
diff options
context:
space:
mode:
authorJacob G-W <jacoblevgw@gmail.com>2021-06-12 16:51:51 -0400
committerAndrew Kelley <andrew@ziglang.org>2021-07-08 14:10:49 -0700
commit72bb6bb1430f0b3b32f0cb5e52054293a59abca6 (patch)
tree2a9fd4c878ef85491f09ae5290d75e2fe76c2197 /src/link
parent3e59c1502556493b29171c2d22447dd70670ca02 (diff)
downloadzig-72bb6bb1430f0b3b32f0cb5e52054293a59abca6.tar.gz
zig-72bb6bb1430f0b3b32f0cb5e52054293a59abca6.zip
plan9 linker: produce an object file that can actually work!!!
Diffstat (limited to 'src/link')
-rw-r--r--src/link/Plan9.zig45
1 files changed, 37 insertions, 8 deletions
diff --git a/src/link/Plan9.zig b/src/link/Plan9.zig
index 5532e056fc..ffd88ddc77 100644
--- a/src/link/Plan9.zig
+++ b/src/link/Plan9.zig
@@ -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;
}