| ... | ... | @@ -82,6 +82,8 @@ unnamed_const_atoms: UnnamedConstTable = .{}, |
| 82 | 82 | |
| 83 | 83 | lazy_syms: LazySymbolTable = .{}, |
| 84 | 84 | |
| 85 | anon_decls: std.AutoHashMapUnmanaged(InternPool.Index, Atom.Index) = .{}, |
| 86 | |
| 85 | 87 | relocs: std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Reloc)) = .{}, |
| 86 | 88 | hdr: aout.ExecHdr = undefined, |
| 87 | 89 | |
| ... | ... | @@ -166,6 +168,9 @@ pub const Atom = struct { |
| 166 | 168 | code_len: usize, |
| 167 | 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 | 174 | fn getCode(self: CodePtr, plan9: *const Plan9) []u8 { |
| 170 | 175 | const mod = plan9.base.options.module.?; |
| 171 | 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 | 613 | while (it_lazy.next()) |kv| { |
| 609 | 614 | lazy_atom_count += kv.value_ptr.numberOfAtoms(); |
| 610 | 615 | } |
| 616 | const anon_atom_count = self.anon_decls.count(); |
| 611 | 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 | 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 | 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 | 834 | // the lazy data symbols |
| 808 | 835 | var it_lazy = self.lazy_syms.iterator(); |
| 809 | 836 | while (it_lazy.next()) |kv| { |
| ... | ... | @@ -1196,6 +1223,11 @@ pub fn deinit(self: *Plan9) void { |
| 1196 | 1223 | while (itd.next()) |entry| { |
| 1197 | 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 | 1231 | self.data_decl_table.deinit(gpa); |
| 1200 | 1232 | self.syms.deinit(gpa); |
| 1201 | 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 | 1460 | // be used by more than one function, however, its address is being used so we need |
| 1429 | 1461 | // to put it in some location. |
| 1430 | 1462 | // ... |
| 1431 | | _ = self; |
| 1432 | | _ = decl_val; |
| 1433 | | _ = src_loc; |
| 1434 | | _ = @panic("TODO: link/Plan9 lowerAnonDecl"); |
| 1463 | const gpa = self.base.allocator; |
| 1464 | var gop = try self.anon_decls.getOrPut(gpa, decl_val); |
| 1465 | const mod = self.base.options.module.?; |
| 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 | 1500 | pub fn getAnonDeclVAddr(self: *Plan9, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 { |
| 1438 | | _ = self; |
| 1439 | | _ = decl_val; |
| 1440 | | _ = reloc_info; |
| 1441 | | _ = @panic("TODO: link/Plan9 getAnonDeclVAddr"); |
| 1501 | const atom_index = self.anon_decls.get(decl_val).?; |
| 1502 | try self.addReloc(reloc_info.parent_atom_index, .{ |
| 1503 | .target = atom_index, |
| 1504 | .offset = reloc_info.offset, |
| 1505 | .addend = reloc_info.addend, |
| 1506 | }); |
| 1507 | return undefined; |
| 1442 | 1508 | } |
| 1443 | 1509 | |
| 1444 | 1510 | pub fn addReloc(self: *Plan9, parent_index: Atom.Index, reloc: Reloc) !void { |