authorgravatar for jacoblevgw@gmail.comJacob G-W <jacoblevgw@gmail.com> 2023-10-03 15:00:33-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-10-03 12:49:45-07:00
logd634e02d33e682c8db9d137175c01d1318e6ab80
treefd3c32b9bf86cba1fe1f9db06d35bc25ad911130
parentde78caf9c404e8c93beb67fcb0daf42cb40cb1f9

plan9: implement linking anon decls


1 files changed, 75 insertions(+), 9 deletions(-)

src/link/Plan9.zig+75-9
...@@ -82,6 +82,8 @@ unnamed_const_atoms: UnnamedConstTable = .{},...@@ -82,6 +82,8 @@ unnamed_const_atoms: UnnamedConstTable = .{},
8282
83lazy_syms: LazySymbolTable = .{},83lazy_syms: LazySymbolTable = .{},
8484
85anon_decls: std.AutoHashMapUnmanaged(InternPool.Index, Atom.Index) = .{},
86
85relocs: std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Reloc)) = .{},87relocs: std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Reloc)) = .{},
86hdr: aout.ExecHdr = undefined,88hdr: aout.ExecHdr = undefined,
8789
...@@ -166,6 +168,9 @@ pub const Atom = struct {...@@ -166,6 +168,9 @@ pub const Atom = struct {
166 code_len: usize,168 code_len: usize,
167 decl_index: Module.Decl.Index,169 decl_index: Module.Decl.Index,
168 },170 },
171 fn fromSlice(slice: []u8) CodePtr {
172 return .{ .code_ptr = slice.ptr, .other = .{ .code_len = slice.len } };
173 }
169 fn getCode(self: CodePtr, plan9: *const Plan9) []u8 {174 fn getCode(self: CodePtr, plan9: *const Plan9) []u8 {
170 const mod = plan9.base.options.module.?;175 const mod = plan9.base.options.module.?;
171 return if (self.code_ptr) |p| p[0..self.other.code_len] else blk: {176 return if (self.code_ptr) |p| p[0..self.other.code_len] else blk: {
...@@ -608,8 +613,9 @@ fn atomCount(self: *Plan9) usize {...@@ -608,8 +613,9 @@ fn atomCount(self: *Plan9) usize {
608 while (it_lazy.next()) |kv| {613 while (it_lazy.next()) |kv| {
609 lazy_atom_count += kv.value_ptr.numberOfAtoms();614 lazy_atom_count += kv.value_ptr.numberOfAtoms();
610 }615 }
616 const anon_atom_count = self.anon_decls.count();
611 const extern_atom_count = self.externCount();617 const extern_atom_count = self.externCount();
612 return data_decl_count + fn_decl_count + unnamed_const_count + lazy_atom_count + extern_atom_count;618 return data_decl_count + fn_decl_count + unnamed_const_count + lazy_atom_count + extern_atom_count + anon_atom_count;
613}619}
614620
615pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {621pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
...@@ -804,6 +810,27 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No...@@ -804,6 +810,27 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
804 self.syms.items[atom.sym_index.?].value = off;810 self.syms.items[atom.sym_index.?].value = off;
805 }811 }
806 }812 }
813 // the anon decls
814 {
815 var it_anon = self.anon_decls.iterator();
816 while (it_anon.next()) |kv| {
817 const atom = self.getAtomPtr(kv.value_ptr.*);
818 const code = atom.code.getOwnedCode().?;
819 log.debug("write anon decl: {s}", .{self.syms.items[atom.sym_index.?].name});
820 foff += code.len;
821 iovecs[iovecs_i] = .{ .iov_base = code.ptr, .iov_len = code.len };
822 iovecs_i += 1;
823 const off = self.getAddr(data_i, .d);
824 data_i += code.len;
825 atom.offset = off;
826 if (!self.sixtyfour_bit) {
827 mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), self.base.options.target.cpu.arch.endian());
828 } else {
829 mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian());
830 }
831 self.syms.items[atom.sym_index.?].value = off;
832 }
833 }
807 // the lazy data symbols834 // the lazy data symbols
808 var it_lazy = self.lazy_syms.iterator();835 var it_lazy = self.lazy_syms.iterator();
809 while (it_lazy.next()) |kv| {836 while (it_lazy.next()) |kv| {
...@@ -1196,6 +1223,11 @@ pub fn deinit(self: *Plan9) void {...@@ -1196,6 +1223,11 @@ pub fn deinit(self: *Plan9) void {
1196 while (itd.next()) |entry| {1223 while (itd.next()) |entry| {
1197 gpa.free(entry.value_ptr.*);1224 gpa.free(entry.value_ptr.*);
1198 }1225 }
1226 var it_anon = self.anon_decls.iterator();
1227 while (it_anon.next()) |entry| {
1228 const sym_index = self.getAtom(entry.value_ptr.*).sym_index.?;
1229 gpa.free(self.syms.items[sym_index].name);
1230 }
1199 self.data_decl_table.deinit(gpa);1231 self.data_decl_table.deinit(gpa);
1200 self.syms.deinit(gpa);1232 self.syms.deinit(gpa);
1201 self.got_index_free_list.deinit(gpa);1233 self.got_index_free_list.deinit(gpa);
...@@ -1428,17 +1460,51 @@ pub fn lowerAnonDecl(self: *Plan9, decl_val: InternPool.Index, src_loc: Module.S...@@ -1428,17 +1460,51 @@ pub fn lowerAnonDecl(self: *Plan9, decl_val: InternPool.Index, src_loc: Module.S
1428 // be used by more than one function, however, its address is being used so we need1460 // be used by more than one function, however, its address is being used so we need
1429 // to put it in some location.1461 // to put it in some location.
1430 // ...1462 // ...
1431 _ = self;1463 const gpa = self.base.allocator;
1432 _ = decl_val;1464 var gop = try self.anon_decls.getOrPut(gpa, decl_val);
1433 _ = src_loc;1465 const mod = self.base.options.module.?;
1434 _ = @panic("TODO: link/Plan9 lowerAnonDecl");1466 if (!gop.found_existing) {
1467 const ty = mod.intern_pool.typeOf(decl_val).toType();
1468 const val = decl_val.toValue();
1469 const tv = TypedValue{ .ty = ty, .val = val };
1470 const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)});
1471
1472 const index = try self.createAtom();
1473 const got_index = self.allocateGotIndex();
1474 gop.value_ptr.* = index;
1475 // we need to free name latex
1476 var code_buffer = std.ArrayList(u8).init(gpa);
1477 const res = try codegen.generateSymbol(&self.base, src_loc, tv, &code_buffer, .{ .none = {} }, .{ .parent_atom_index = index });
1478 const code = switch (res) {
1479 .ok => code_buffer.items,
1480 .fail => |em| return .{ .fail = em },
1481 };
1482 const atom_ptr = self.getAtomPtr(index);
1483 atom_ptr.* = .{
1484 .type = .d,
1485 .offset = undefined,
1486 .sym_index = null,
1487 .got_index = got_index,
1488 .code = Atom.CodePtr.fromSlice(code),
1489 };
1490 _ = try atom_ptr.getOrCreateSymbolTableEntry(self);
1491 self.syms.items[atom_ptr.sym_index.?] = .{
1492 .type = .d,
1493 .value = undefined,
1494 .name = name,
1495 };
1496 }
1497 return .ok;
1435}1498}
14361499
1437pub fn getAnonDeclVAddr(self: *Plan9, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {1500pub fn getAnonDeclVAddr(self: *Plan9, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
1438 _ = self;1501 const atom_index = self.anon_decls.get(decl_val).?;
1439 _ = decl_val;1502 try self.addReloc(reloc_info.parent_atom_index, .{
1440 _ = reloc_info;1503 .target = atom_index,
1441 _ = @panic("TODO: link/Plan9 getAnonDeclVAddr");1504 .offset = reloc_info.offset,
1505 .addend = reloc_info.addend,
1506 });
1507 return undefined;
1442}1508}
14431509
1444pub fn addReloc(self: *Plan9, parent_index: Atom.Index, reloc: Reloc) !void {1510pub fn addReloc(self: *Plan9, parent_index: Atom.Index, reloc: Reloc) !void {