| ... | ... | @@ -862,6 +862,11 @@ fn resolveRelocs(self: *Coff, atom: *Atom) !void { |
| 862 | 862 | fn freeAtom(self: *Coff, atom: *Atom) void { |
| 863 | 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 | 870 | const sym = atom.getSymbol(self); |
| 866 | 871 | const sect_id = @enumToInt(sym.section_number) - 1; |
| 867 | 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 | 960 | } |
| 956 | 961 | |
| 957 | 962 | pub 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; |
| 962 | 1024 | } |
| 963 | 1025 | |
| 964 | 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 | 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 | 1176 | pub fn freeDecl(self: *Coff, decl_index: Module.Decl.Index) void { |
| 1101 | 1177 | if (build_options.have_llvm) { |
| 1102 | 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 | 1186 | const kv = self.decls.fetchRemove(decl_index); |
| 1111 | 1187 | if (kv.?.value) |_| { |
| 1112 | 1188 | self.freeAtom(&decl.link.coff); |
| 1189 | self.freeUnnamedConsts(decl_index); |
| 1113 | 1190 | } |
| 1114 | 1191 | |
| 1115 | 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 | 1449 | decl_index: Module.Decl.Index, |
| 1373 | 1450 | reloc_info: link.File.RelocInfo, |
| 1374 | 1451 | ) !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; |
| 1379 | 1473 | } |
| 1380 | 1474 | |
| 1381 | 1475 | pub fn getGlobalSymbol(self: *Coff, name: []const u8) !u32 { |