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) = .{},
197197
198198blocks: std.AutoHashMapUnmanaged(MatchingSection, *TextBlock) = .{},
199199
200/// List of Decls that are currently alive.
200/// Table of Decls that are currently alive.
201201/// We store them here so that we can properly dispose of any allocated
202202/// memory within the TextBlock in the incremental linker.
203203/// TODO consolidate this.
204decls: std.ArrayListUnmanaged(*Module.Decl) = .{},
204decls: std.AutoArrayHashMapUnmanaged(*Module.Decl, void) = .{},
205205
206206/// Currently active Module.Decl.
207207/// 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 {
33233323 self.blocks.deinit(self.base.allocator);
33243324 self.text_block_free_list.deinit(self.base.allocator);
33253325
3326 for (self.decls.items) |decl| {
3326 for (self.decls.keys()) |decl| {
33273327 decl.link.macho.deinit(self.base.allocator);
33283328 }
33293329 self.decls.deinit(self.base.allocator);
......@@ -3427,9 +3427,8 @@ pub fn allocateDeclIndexes(self: *MachO, decl: *Module.Decl) !void {
34273427
34283428 try self.locals.ensureUnusedCapacity(self.base.allocator, 1);
34293429 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
34343433 if (self.locals_free_list.popOrNull()) |i| {
34353434 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 {
35983597
35993598 // Resolve relocations
36003599 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
36023604 // Apply pending updates
36033605 while (self.pending_updates.popOrNull()) |update| {
......@@ -3746,6 +3748,7 @@ pub fn deleteExport(self: *MachO, exp: Export) void {
37463748
37473749pub fn freeDecl(self: *MachO, decl: *Module.Decl) void {
37483750 log.debug("freeDecl {*}", .{decl});
3751 _ = self.decls.swapRemove(decl);
37493752 // Appending to free lists is allowed to fail because the free lists are heuristics based anyway.
37503753 self.freeTextBlock(&decl.link.macho);
37513754 if (decl.link.macho.local_sym_index != 0) {