authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-09-01 16:01:40+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-09-07 22:42:56+02:00
log49b1716064cb87b5e8ca13dcb1c9e4fc701737bc
tree63bb6c18bfde9f04552fb22a5fa24c095cc0fe58
parenta19e6adbf90771890ecdbb52d6dafab1943e4cc4

coff: implement lowering unnamed consts


2 files changed, 103 insertions(+), 9 deletions(-)

src/arch/x86_64/CodeGen.zig+1-1
......@@ -6959,7 +6959,7 @@ fn lowerUnnamedConst(self: *Self, tv: TypedValue) InnerError!MCValue {
69596959 } else if (self.bin_file.cast(link.File.MachO)) |_| {
69606960 return MCValue{ .direct_load = local_sym_index };
69616961 } else if (self.bin_file.cast(link.File.Coff)) |_| {
6962 return self.fail("TODO lower unnamed const in COFF", .{});
6962 return MCValue{ .direct_load = local_sym_index };
69636963 } else if (self.bin_file.cast(link.File.Plan9)) |_| {
69646964 return self.fail("TODO lower unnamed const in Plan9", .{});
69656965 } else {
src/link/Coff.zig+102-8
......@@ -862,6 +862,11 @@ fn resolveRelocs(self: *Coff, atom: *Atom) !void {
862862fn freeAtom(self: *Coff, atom: *Atom) void {
863863 log.debug("freeAtom {*}", .{atom});
864864
865 // TODO hashmap
866 for (self.managed_atoms.items) |owned| {
867 if (owned == atom) break;
868 } else atom.deinit(self.base.allocator);
869
865870 const sym = atom.getSymbol(self);
866871 const sect_id = @enumToInt(sym.section_number) - 1;
867872 const free_list = &self.sections.items(.free_list)[sect_id];
......@@ -955,10 +960,67 @@ pub fn updateFunc(self: *Coff, module: *Module, func: *Module.Fn, air: Air, live
955960}
956961
957962pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.Index) !u32 {
958 _ = self;
959 _ = tv;
960 _ = decl_index;
961 @panic("TODO lowerUnnamedConst");
963 const gpa = self.base.allocator;
964 var code_buffer = std.ArrayList(u8).init(gpa);
965 defer code_buffer.deinit();
966
967 const mod = self.base.options.module.?;
968 const decl = mod.declPtr(decl_index);
969
970 const gop = try self.unnamed_const_atoms.getOrPut(gpa, decl_index);
971 if (!gop.found_existing) {
972 gop.value_ptr.* = .{};
973 }
974 const unnamed_consts = gop.value_ptr;
975
976 const atom = try gpa.create(Atom);
977 errdefer gpa.destroy(atom);
978 atom.* = Atom.empty;
979
980 atom.sym_index = try self.allocateSymbol();
981 const sym = atom.getSymbolPtr(self);
982 const sym_name = blk: {
983 const decl_name = try decl.getFullyQualifiedName(mod);
984 defer gpa.free(decl_name);
985
986 const index = unnamed_consts.items.len;
987 break :blk try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });
988 };
989 defer gpa.free(sym_name);
990 try self.setSymbolName(sym, sym_name);
991 sym.section_number = @intToEnum(coff.SectionNumber, self.rdata_section_index.?);
992
993 try self.managed_atoms.append(gpa, atom);
994 try self.atom_by_index_table.putNoClobber(gpa, atom.sym_index, atom);
995
996 const res = try codegen.generateSymbol(&self.base, decl.srcLoc(), tv, &code_buffer, .none, .{
997 .parent_atom_index = atom.sym_index,
998 });
999 const code = switch (res) {
1000 .externally_managed => |x| x,
1001 .appended => code_buffer.items,
1002 .fail => |em| {
1003 decl.analysis = .codegen_failure;
1004 try mod.failed_decls.put(mod.gpa, decl_index, em);
1005 log.err("{s}", .{em.msg});
1006 return error.AnalysisFail;
1007 },
1008 };
1009
1010 const required_alignment = tv.ty.abiAlignment(self.base.options.target);
1011 atom.alignment = required_alignment;
1012 atom.size = @intCast(u32, code.len);
1013 sym.value = try self.allocateAtom(atom, atom.size, atom.alignment);
1014 errdefer self.freeAtom(atom);
1015
1016 try unnamed_consts.append(gpa, atom);
1017
1018 log.debug("allocated atom for {s} at 0x{x}", .{ sym_name, sym.value });
1019 log.debug(" (required alignment 0x{x})", .{required_alignment});
1020
1021 try self.writeAtom(atom, code);
1022
1023 return atom.sym_index;
9621024}
9631025
9641026pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) !void {
......@@ -1097,6 +1159,20 @@ fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []const u8,
10971159 try self.writeAtom(atom, code);
10981160}
10991161
1162fn freeUnnamedConsts(self: *Coff, decl_index: Module.Decl.Index) void {
1163 const gpa = self.base.allocator;
1164 const unnamed_consts = self.unnamed_const_atoms.getPtr(decl_index) orelse return;
1165 for (unnamed_consts.items) |atom| {
1166 self.freeAtom(atom);
1167 self.locals_free_list.append(gpa, atom.sym_index) catch {};
1168 self.locals.items[atom.sym_index].section_number = .UNDEFINED;
1169 _ = self.atom_by_index_table.remove(atom.sym_index);
1170 log.debug(" adding local symbol index {d} to free list", .{atom.sym_index});
1171 atom.sym_index = 0;
1172 }
1173 unnamed_consts.clearAndFree(gpa);
1174}
1175
11001176pub fn freeDecl(self: *Coff, decl_index: Module.Decl.Index) void {
11011177 if (build_options.have_llvm) {
11021178 if (self.llvm_object) |llvm_object| return llvm_object.freeDecl(decl_index);
......@@ -1110,6 +1186,7 @@ pub fn freeDecl(self: *Coff, decl_index: Module.Decl.Index) void {
11101186 const kv = self.decls.fetchRemove(decl_index);
11111187 if (kv.?.value) |_| {
11121188 self.freeAtom(&decl.link.coff);
1189 self.freeUnnamedConsts(decl_index);
11131190 }
11141191
11151192 // Appending to free lists is allowed to fail because the free lists are heuristics based anyway.
......@@ -1372,10 +1449,27 @@ pub fn getDeclVAddr(
13721449 decl_index: Module.Decl.Index,
13731450 reloc_info: link.File.RelocInfo,
13741451) !u64 {
1375 _ = self;
1376 _ = decl_index;
1377 _ = reloc_info;
1378 @panic("TODO getDeclVAddr");
1452 const mod = self.base.options.module.?;
1453 const decl = mod.declPtr(decl_index);
1454
1455 assert(self.llvm_object == null);
1456 assert(decl.link.coff.sym_index != 0);
1457
1458 const atom = self.atom_by_index_table.get(reloc_info.parent_atom_index).?;
1459 const target = SymbolWithLoc{ .sym_index = decl.link.coff.sym_index, .file = null };
1460 const target_sym = self.getSymbol(target);
1461 try atom.addRelocation(self, .{
1462 .@"type" = .direct,
1463 .target = target,
1464 .offset = @intCast(u32, reloc_info.offset),
1465 .addend = reloc_info.addend,
1466 .pcrel = false,
1467 .length = 3,
1468 .prev_vaddr = target_sym.value,
1469 });
1470 try atom.addBaseRelocation(self, @intCast(u32, reloc_info.offset));
1471
1472 return 0;
13791473}
13801474
13811475pub fn getGlobalSymbol(self: *Coff, name: []const u8) !u32 {