| ... | @@ -82,6 +82,8 @@ unnamed_const_atoms: UnnamedConstTable = .{}, | ... | @@ -82,6 +82,8 @@ unnamed_const_atoms: UnnamedConstTable = .{}, |
| 82 | | 82 | |
| 83 | lazy_syms: LazySymbolTable = .{}, | 83 | lazy_syms: LazySymbolTable = .{}, |
| 84 | | 84 | |
| | 85 | anon_decls: std.AutoHashMapUnmanaged(InternPool.Index, Atom.Index) = .{}, |
| | 86 | |
| 85 | relocs: std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Reloc)) = .{}, | 87 | relocs: std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Reloc)) = .{}, |
| 86 | hdr: aout.ExecHdr = undefined, | 88 | hdr: aout.ExecHdr = undefined, |
| 87 | | 89 | |
| ... | @@ -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 | } |
| 614 | | 620 | |
| 615 | pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void { | 621 | pub 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 symbols | 834 | // 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 need | 1460 | // 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 | } |
| 1436 | | 1499 | |
| 1437 | pub fn getAnonDeclVAddr(self: *Plan9, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 { | 1500 | pub 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 | } |
| 1443 | | 1509 | |
| 1444 | pub fn addReloc(self: *Plan9, parent_index: Atom.Index, reloc: Reloc) !void { | 1510 | pub fn addReloc(self: *Plan9, parent_index: Atom.Index, reloc: Reloc) !void { |