authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-07-21 23:38:20+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-07-21 23:38:20+02:00
logd0edd37f690c3e6cf3f8a7fc7a27016ba9b010ce
tree5345caa7297fd77d9c3d1f36fd205d4c0970cfbb
parente05b1e0e07708ca16c1a90e51a668faf51d883f4

macho: fix bug when freeing Decl

Take into account that an already freed Decl will no longer be available as `decl.link.macho` causing a potential "inactive union field" panic.

1 files changed, 8 insertions(+), 5 deletions(-)

src/link/MachO.zig+8-5
...@@ -197,11 +197,11 @@ managed_blocks: std.ArrayListUnmanaged(*TextBlock) = .{},...@@ -197,11 +197,11 @@ managed_blocks: std.ArrayListUnmanaged(*TextBlock) = .{},
197197
198blocks: std.AutoHashMapUnmanaged(MatchingSection, *TextBlock) = .{},198blocks: std.AutoHashMapUnmanaged(MatchingSection, *TextBlock) = .{},
199199
200/// List of Decls that are currently alive.200/// Table of Decls that are currently alive.
201/// We store them here so that we can properly dispose of any allocated201/// We store them here so that we can properly dispose of any allocated
202/// memory within the TextBlock in the incremental linker.202/// memory within the TextBlock in the incremental linker.
203/// TODO consolidate this.203/// TODO consolidate this.
204decls: std.ArrayListUnmanaged(*Module.Decl) = .{},204decls: std.AutoArrayHashMapUnmanaged(*Module.Decl, void) = .{},
205205
206/// Currently active Module.Decl.206/// Currently active Module.Decl.
207/// TODO this might not be necessary if we figure out how to pass Module.Decl instance207/// TODO this might not be necessary if we figure out how to pass Module.Decl instance
...@@ -3323,7 +3323,7 @@ pub fn deinit(self: *MachO) void {...@@ -3323,7 +3323,7 @@ pub fn deinit(self: *MachO) void {
3323 self.blocks.deinit(self.base.allocator);3323 self.blocks.deinit(self.base.allocator);
3324 self.text_block_free_list.deinit(self.base.allocator);3324 self.text_block_free_list.deinit(self.base.allocator);
33253325
3326 for (self.decls.items) |decl| {3326 for (self.decls.keys()) |decl| {
3327 decl.link.macho.deinit(self.base.allocator);3327 decl.link.macho.deinit(self.base.allocator);
3328 }3328 }
3329 self.decls.deinit(self.base.allocator);3329 self.decls.deinit(self.base.allocator);
...@@ -3427,9 +3427,8 @@ pub fn allocateDeclIndexes(self: *MachO, decl: *Module.Decl) !void {...@@ -3427,9 +3427,8 @@ pub fn allocateDeclIndexes(self: *MachO, decl: *Module.Decl) !void {
34273427
3428 try self.locals.ensureUnusedCapacity(self.base.allocator, 1);3428 try self.locals.ensureUnusedCapacity(self.base.allocator, 1);
3429 try self.got_entries.ensureUnusedCapacity(self.base.allocator, 1);3429 try self.got_entries.ensureUnusedCapacity(self.base.allocator, 1);
3430 try self.decls.ensureUnusedCapacity(self.base.allocator, 1);
34313430
3432 self.decls.appendAssumeCapacity(decl);3431 try self.decls.putNoClobber(self.base.allocator, decl, {});
34333432
3434 if (self.locals_free_list.popOrNull()) |i| {3433 if (self.locals_free_list.popOrNull()) |i| {
3435 log.debug("reusing symbol index {d} for {s}", .{ i, decl.name });3434 log.debug("reusing symbol index {d} for {s}", .{ i, decl.name });
...@@ -3598,6 +3597,9 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {...@@ -3598,6 +3597,9 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
35983597
3599 // Resolve relocations3598 // Resolve relocations
3600 try decl.link.macho.resolveRelocs(self);3599 try decl.link.macho.resolveRelocs(self);
3600 // TODO this requires further investigation: should we dispose of resolved relocs, or keep them
3601 // so that we can reapply them when moving/growing sections?
3602 decl.link.macho.relocs.clearRetainingCapacity();
36013603
3602 // Apply pending updates3604 // Apply pending updates
3603 while (self.pending_updates.popOrNull()) |update| {3605 while (self.pending_updates.popOrNull()) |update| {
...@@ -3746,6 +3748,7 @@ pub fn deleteExport(self: *MachO, exp: Export) void {...@@ -3746,6 +3748,7 @@ pub fn deleteExport(self: *MachO, exp: Export) void {
37463748
3747pub fn freeDecl(self: *MachO, decl: *Module.Decl) void {3749pub fn freeDecl(self: *MachO, decl: *Module.Decl) void {
3748 log.debug("freeDecl {*}", .{decl});3750 log.debug("freeDecl {*}", .{decl});
3751 _ = self.decls.swapRemove(decl);
3749 // Appending to free lists is allowed to fail because the free lists are heuristics based anyway.3752 // Appending to free lists is allowed to fail because the free lists are heuristics based anyway.
3750 self.freeTextBlock(&decl.link.macho);3753 self.freeTextBlock(&decl.link.macho);
3751 if (decl.link.macho.local_sym_index != 0) {3754 if (decl.link.macho.local_sym_index != 0) {