| author | |
| committer | |
| log | 74b14edea8b7d8ae7816feda2ee37a4ca016bc03 |
| tree | 2e5beb75cf5f179d947021a981ddc6210d0c9630 |
| parent | 70ac9fc7afe672d39cdcc2f1fa4df00d34f5a775 |
* Fix linker memory leaks found while running `zig build test-cases`.
* Add missing target to test manifest.5 files changed, 35 insertions(+), 14 deletions(-)
src/link.zig+4| ... | ... | @@ -223,7 +223,9 @@ pub const Options = struct { |
| 223 | 223 | |
| 224 | 224 | pub fn move(self: *Options) Options { |
| 225 | 225 | const copied_state = self.*; |
| 226 | self.frameworks = .{}; | |
| 226 | 227 | self.system_libs = .{}; |
| 228 | self.force_undefined_symbols = .{}; | |
| 227 | 229 | return copied_state; |
| 228 | 230 | } |
| 229 | 231 | }; |
| ... | ... | @@ -624,7 +626,9 @@ pub const File = struct { |
| 624 | 626 | base.releaseLock(); |
| 625 | 627 | if (base.file) |f| f.close(); |
| 626 | 628 | if (base.intermediary_basename) |sub_path| base.allocator.free(sub_path); |
| 629 | base.options.frameworks.deinit(base.allocator); | |
| 627 | 630 | base.options.system_libs.deinit(base.allocator); |
| 631 | base.options.force_undefined_symbols.deinit(base.allocator); | |
| 628 | 632 | switch (base.tag) { |
| 629 | 633 | .coff => { |
| 630 | 634 | if (build_options.only_c) unreachable; |
src/link/Coff.zig+6-4| ... | ... | @@ -289,6 +289,7 @@ pub fn deinit(self: *Coff) void { |
| 289 | 289 | |
| 290 | 290 | self.unresolved.deinit(gpa); |
| 291 | 291 | self.locals_free_list.deinit(gpa); |
| 292 | self.globals_free_list.deinit(gpa); | |
| 292 | 293 | self.strtab.deinit(gpa); |
| 293 | 294 | self.got_entries.deinit(gpa); |
| 294 | 295 | self.got_entries_free_list.deinit(gpa); |
| ... | ... | @@ -1150,8 +1151,10 @@ fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []const u8, |
| 1150 | 1151 | } |
| 1151 | 1152 | |
| 1152 | 1153 | fn freeRelocationsForAtom(self: *Coff, atom: *Atom) void { |
| 1153 | _ = self.relocs.remove(atom); | |
| 1154 | _ = self.base_relocs.remove(atom); | |
| 1154 | var removed_relocs = self.relocs.fetchRemove(atom); | |
| 1155 | if (removed_relocs) |*relocs| relocs.value.deinit(self.base.allocator); | |
| 1156 | var removed_base_relocs = self.base_relocs.fetchRemove(atom); | |
| 1157 | if (removed_base_relocs) |*base_relocs| base_relocs.value.deinit(self.base.allocator); | |
| 1155 | 1158 | } |
| 1156 | 1159 | |
| 1157 | 1160 | fn freeUnnamedConsts(self: *Coff, decl_index: Module.Decl.Index) void { |
| ... | ... | @@ -1489,9 +1492,8 @@ pub fn getGlobalSymbol(self: *Coff, name: []const u8) !u32 { |
| 1489 | 1492 | gop.value_ptr.* = sym_loc; |
| 1490 | 1493 | |
| 1491 | 1494 | const gpa = self.base.allocator; |
| 1492 | const sym_name = try gpa.dupe(u8, name); | |
| 1493 | 1495 | const sym = self.getSymbolPtr(sym_loc); |
| 1494 | try self.setSymbolName(sym, sym_name); | |
| 1496 | try self.setSymbolName(sym, name); | |
| 1495 | 1497 | sym.storage_class = .EXTERNAL; |
| 1496 | 1498 | |
| 1497 | 1499 | try self.unresolved.putNoClobber(gpa, global_index, true); |
src/link/MachO.zig+8-4| ... | ... | @@ -2576,10 +2576,14 @@ pub fn deleteExport(self: *MachO, exp: Export) void { |
| 2576 | 2576 | } |
| 2577 | 2577 | |
| 2578 | 2578 | fn freeRelocationsForAtom(self: *MachO, atom: *Atom) void { |
| 2579 | _ = self.relocs.remove(atom); | |
| 2580 | _ = self.rebases.remove(atom); | |
| 2581 | _ = self.bindings.remove(atom); | |
| 2582 | _ = self.lazy_bindings.remove(atom); | |
| 2579 | var removed_relocs = self.relocs.fetchRemove(atom); | |
| 2580 | if (removed_relocs) |*relocs| relocs.value.deinit(self.base.allocator); | |
| 2581 | var removed_rebases = self.rebases.fetchRemove(atom); | |
| 2582 | if (removed_rebases) |*rebases| rebases.value.deinit(self.base.allocator); | |
| 2583 | var removed_bindings = self.bindings.fetchRemove(atom); | |
| 2584 | if (removed_bindings) |*bindings| bindings.value.deinit(self.base.allocator); | |
| 2585 | var removed_lazy_bindings = self.lazy_bindings.fetchRemove(atom); | |
| 2586 | if (removed_lazy_bindings) |*lazy_bindings| lazy_bindings.value.deinit(self.base.allocator); | |
| 2583 | 2587 | } |
| 2584 | 2588 | |
| 2585 | 2589 | fn freeUnnamedConsts(self: *MachO, decl_index: Module.Decl.Index) void { |
src/link/Plan9.zig+16-6| ... | ... | @@ -201,7 +201,10 @@ fn putFn(self: *Plan9, decl_index: Module.Decl.Index, out: FnDeclOutput) !void { |
| 201 | 201 | const decl = mod.declPtr(decl_index); |
| 202 | 202 | const fn_map_res = try self.fn_decl_table.getOrPut(gpa, decl.getFileScope()); |
| 203 | 203 | if (fn_map_res.found_existing) { |
| 204 | try fn_map_res.value_ptr.functions.put(gpa, decl_index, out); | |
| 204 | if (try fn_map_res.value_ptr.functions.fetchPut(gpa, decl_index, out)) |old_entry| { | |
| 205 | gpa.free(old_entry.value.code); | |
| 206 | gpa.free(old_entry.value.lineinfo); | |
| 207 | } | |
| 205 | 208 | } else { |
| 206 | 209 | const file = decl.getFileScope(); |
| 207 | 210 | const arena = self.path_arena.allocator(); |
| ... | ... | @@ -408,9 +411,11 @@ pub fn updateDecl(self: *Plan9, module: *Module, decl_index: Module.Decl.Index) |
| 408 | 411 | return; |
| 409 | 412 | }, |
| 410 | 413 | }; |
| 411 | var duped_code = try self.base.allocator.dupe(u8, code); | |
| 412 | errdefer self.base.allocator.free(duped_code); | |
| 413 | try self.data_decl_table.put(self.base.allocator, decl_index, duped_code); | |
| 414 | try self.data_decl_table.ensureUnusedCapacity(self.base.allocator, 1); | |
| 415 | const duped_code = try self.base.allocator.dupe(u8, code); | |
| 416 | if (self.data_decl_table.fetchPutAssumeCapacity(decl_index, duped_code)) |old_entry| { | |
| 417 | self.base.allocator.free(old_entry.value); | |
| 418 | } | |
| 414 | 419 | return self.updateFinish(decl); |
| 415 | 420 | } |
| 416 | 421 | /// called at the end of update{Decl,Func} |
| ... | ... | @@ -743,14 +748,19 @@ pub fn freeDecl(self: *Plan9, decl_index: Module.Decl.Index) void { |
| 743 | 748 | if (is_fn) { |
| 744 | 749 | var symidx_and_submap = self.fn_decl_table.get(decl.getFileScope()).?; |
| 745 | 750 | var submap = symidx_and_submap.functions; |
| 746 | _ = submap.swapRemove(decl_index); | |
| 751 | if (submap.fetchSwapRemove(decl_index)) |removed_entry| { | |
| 752 | self.base.allocator.free(removed_entry.value.code); | |
| 753 | self.base.allocator.free(removed_entry.value.lineinfo); | |
| 754 | } | |
| 747 | 755 | if (submap.count() == 0) { |
| 748 | 756 | self.syms.items[symidx_and_submap.sym_index] = aout.Sym.undefined_symbol; |
| 749 | 757 | self.syms_index_free_list.append(self.base.allocator, symidx_and_submap.sym_index) catch {}; |
| 750 | 758 | submap.deinit(self.base.allocator); |
| 751 | 759 | } |
| 752 | 760 | } else { |
| 753 | _ = self.data_decl_table.swapRemove(decl_index); | |
| 761 | if (self.data_decl_table.fetchSwapRemove(decl_index)) |removed_entry| { | |
| 762 | self.base.allocator.free(removed_entry.value); | |
| 763 | } | |
| 754 | 764 | } |
| 755 | 765 | if (decl.link.plan9.got_index) |i| { |
| 756 | 766 | // TODO: if this catch {} is triggered, an assertion in flushModule will be triggered, because got_index_free_list will have the wrong length |
test/cases/plan9/hello_world_with_updates.1.zig+1| ... | ... | @@ -5,6 +5,7 @@ pub fn main() void { |
| 5 | 5 | } |
| 6 | 6 | |
| 7 | 7 | // run |
| 8 | // target=x86_64-plan9 | |
| 8 | 9 | // |
| 9 | 10 | // Hello World |
| 10 | 11 | // |