| ... | @@ -862,6 +862,11 @@ fn resolveRelocs(self: *Coff, atom: *Atom) !void { | ... | @@ -862,6 +862,11 @@ fn resolveRelocs(self: *Coff, atom: *Atom) !void { |
| 862 | fn freeAtom(self: *Coff, atom: *Atom) void { | 862 | fn freeAtom(self: *Coff, atom: *Atom) void { |
| 863 | log.debug("freeAtom {*}", .{atom}); | 863 | log.debug("freeAtom {*}", .{atom}); |
| 864 | | 864 | |
| | 865 | // TODO hashmap |
| | 866 | for (self.managed_atoms.items) |owned| { |
| | 867 | if (owned == atom) break; |
| | 868 | } else atom.deinit(self.base.allocator); |
| | 869 | |
| 865 | const sym = atom.getSymbol(self); | 870 | const sym = atom.getSymbol(self); |
| 866 | const sect_id = @enumToInt(sym.section_number) - 1; | 871 | const sect_id = @enumToInt(sym.section_number) - 1; |
| 867 | const free_list = &self.sections.items(.free_list)[sect_id]; | 872 | 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 | ... | @@ -955,10 +960,67 @@ pub fn updateFunc(self: *Coff, module: *Module, func: *Module.Fn, air: Air, live |
| 955 | } | 960 | } |
| 956 | | 961 | |
| 957 | pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.Index) !u32 { | 962 | pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.Index) !u32 { |
| 958 | _ = self; | 963 | const gpa = self.base.allocator; |
| 959 | _ = tv; | 964 | var code_buffer = std.ArrayList(u8).init(gpa); |
| 960 | _ = decl_index; | 965 | defer code_buffer.deinit(); |
| 961 | @panic("TODO lowerUnnamedConst"); | 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; |
| 962 | } | 1024 | } |
| 963 | | 1025 | |
| 964 | pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) !void { | 1026 | pub 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, | ... | @@ -1097,6 +1159,20 @@ fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []const u8, |
| 1097 | try self.writeAtom(atom, code); | 1159 | try self.writeAtom(atom, code); |
| 1098 | } | 1160 | } |
| 1099 | | 1161 | |
| | 1162 | fn 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 | |
| 1100 | pub fn freeDecl(self: *Coff, decl_index: Module.Decl.Index) void { | 1176 | pub fn freeDecl(self: *Coff, decl_index: Module.Decl.Index) void { |
| 1101 | if (build_options.have_llvm) { | 1177 | if (build_options.have_llvm) { |
| 1102 | if (self.llvm_object) |llvm_object| return llvm_object.freeDecl(decl_index); | 1178 | 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 { | ... | @@ -1110,6 +1186,7 @@ pub fn freeDecl(self: *Coff, decl_index: Module.Decl.Index) void { |
| 1110 | const kv = self.decls.fetchRemove(decl_index); | 1186 | const kv = self.decls.fetchRemove(decl_index); |
| 1111 | if (kv.?.value) |_| { | 1187 | if (kv.?.value) |_| { |
| 1112 | self.freeAtom(&decl.link.coff); | 1188 | self.freeAtom(&decl.link.coff); |
| | 1189 | self.freeUnnamedConsts(decl_index); |
| 1113 | } | 1190 | } |
| 1114 | | 1191 | |
| 1115 | // Appending to free lists is allowed to fail because the free lists are heuristics based anyway. | 1192 | // Appending to free lists is allowed to fail because the free lists are heuristics based anyway. |
| ... | @@ -1372,10 +1449,27 @@ pub fn getDeclVAddr( | ... | @@ -1372,10 +1449,27 @@ pub fn getDeclVAddr( |
| 1372 | decl_index: Module.Decl.Index, | 1449 | decl_index: Module.Decl.Index, |
| 1373 | reloc_info: link.File.RelocInfo, | 1450 | reloc_info: link.File.RelocInfo, |
| 1374 | ) !u64 { | 1451 | ) !u64 { |
| 1375 | _ = self; | 1452 | const mod = self.base.options.module.?; |
| 1376 | _ = decl_index; | 1453 | const decl = mod.declPtr(decl_index); |
| 1377 | _ = reloc_info; | 1454 | |
| 1378 | @panic("TODO getDeclVAddr"); | 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; |
| 1379 | } | 1473 | } |
| 1380 | | 1474 | |
| 1381 | pub fn getGlobalSymbol(self: *Coff, name: []const u8) !u32 { | 1475 | pub fn getGlobalSymbol(self: *Coff, name: []const u8) !u32 { |